[Oberon] [EXT] Re: Emulating interrupts in oberon-risc-emu as in the RISC5 specification
joerg.straube at iaeth.ch
Wed Mar 31 08:28:16 CEST 2021
Identifiers of a module are not part of the language description per se.
So you don‘t find Out.Ln or TCP.Read in the language description, as Ln is implemented in Out.Mod and Read is implemented in TCP.Mod
These identifiers are part of the API of the module.
Now, the module SYSTEM is a little special in that respect as there is no direct source file SYSTEM.Mod. Think of it as a “virtual“ source file implemented by the compiler.
When NW added interrupts to the RISC CPU, he added the * marking to the language and extended the API of SYSTEM.
LDPSR means „load processor status register“
If there is a need to find out in SW whether the CPU can handle interrupts, there is an undocumented feature to read CPU version.
> Am 31.03.2021 um 05:52 schrieb Skulski, Wojciech <skulski at pas.rochester.edu>:
> what is SYSTEM.LDPSR? It does not seem to be present in the language report dated Revision 1.10.2013 / 3.5.2016, which I just downloaded from Paul's website.
> From: Oberon [oberon-bounces at lists.inf.ethz.ch] on behalf of Jörg [joerg.straube at iaeth.ch]
> Sent: Tuesday, March 30, 2021 8:45 PM
> To: ETH Oberon and related systems
> Subject: [EXT] Re: [Oberon] Emulating interrupts in oberon-risc-emu as in the RISC5 specification
> Although TestInt is low-level, it should use Kernel.Install (SYSTEM.ADR(Int), 4) to make it a little bit less low-level😀
> This little wrapper makes interrupts a little bit better consumable:
> MODULE Interrupts; (* jr/31mar21 *)
> IMPORT S := SYSTEM, Kernel;
> PROCEDURE Install*(handler: PROCEDURE);
> BEGIN Kernel.Install(S.ADR(handler), 4) END Install;
> PROCEDURE Set*(on: BOOLEAN);
> BEGIN S.LDPSR(ORD(on)) END Set;
> END Interrupts.
> With it TestInt.Mod gets
> MODULE TestInt;
> IMPORT Interrupts;
> VAR led, cnt: INTEGER;
> PROCEDURE* MyInterrupt;
> INC(cnt); IF cnt = 500 THEN led := 3-led; LED(led); cnt := 0 END
> END MyInterrupt;
> PROCEDURE On*; BEGIN Interrupts.Set(TRUE) END On;
> PROCEDURE Off*; BEGIN Interrupts.Set(FALSE) END Off;
> led := 1; cnt := 0; Interrupts.Install(MyInterrupt)
> Interrupts.Mod could be enhanced servicing multiple interrupt handlers. Comparable to the background tasks in Oberon.Mod. This enhancement would install its own interrupt handler doing the scheduling, and the user‘s „interrupt handlers“ are normal procedures without * marking of the procedure. You would then install your handler like this
> PROCEDURE MyTask; BEGIN led := 3 - led; LED(led) END MyTask;
> BEGIN led := 1; Interrupts.Install(MyTask, 500) END TestInt.
> br, Jörg
> Oberon at lists.inf.ethz.ch mailing list for ETH Oberon and related systems
More information about the Oberon