<!DOCTYPE html><html><head><title></title><style type="text/css">#qt p.qt-MsoNormal{margin-top:0cm;margin-right:0cm;margin-bottom:0cm;margin-left:0cm;font-size:11pt;font-family:Calibri, sans-serif;}
#qt a:link{color:blue;text-decoration:underline;}
#qt pre{margin-top:0cm;margin-right:0cm;margin-left:0cm;margin-bottom:0.0001pt;font-size:10pt;font-family:"Courier New";}

p.MsoNormal,p.MsoNoSpacing{margin:0}</style></head><body><div>Adding to Jörg's post, below, I have a simple eight channel interrupt controller in the FPGA hardware as "front end" to the single interrupt of the RISC5 CPU, including the corresponding Oberon driver of course. It adds one clock cycle of latency, IIRC. Let me know if you're interested. It requires some minor changes to the RISC5 CPU, though.<br></div><div><br></div><div>-- gray<br></div><div><br></div><div>On Thu, 6 May 2021, at 19:53, Joerg wrote:<br></div><blockquote type="cite" id="qt" style="word-wrap:break-word;"><div class="qt-WordSection1"><p class="qt-MsoNormal"><span style="">Hi Jeff</span><br></p><p class="qt-MsoNormal"><span style=""> </span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="">The interrupt signal is handed over by the HW to the RISC5 CPU in RISC5Top.v.</span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="">The interrupt signal in the CPU is called .irq, and the current RISC5Top.v hands over periodic interrupts with the Verilog code below</span><br></p><pre><span lang="EN-US">RISC5 riscx(.clk(clk), .rst(rst), <b><span style="color:red;">.irq(limit),</span></b></span><br></pre><p class="qt-MsoNormal"><span lang="EN-US" style=""><span class="font" style="font-family:"Courier New";"><span class="size" style="font-size:10pt;">   .rd(rd), .wr(wr), .ben(ben), .stallX(vidreq),</span></span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style=""><span class="font" style="font-family:"Courier New";"><span class="size" style="font-size:10pt;">   </span></span></span><span style=""><span class="font" style="font-family:"Courier New";"><span class="size" style="font-size:10pt;">.adr(adr), .codebus(codebus), .inbus(inbus),</span></span></span><br></p><p class="qt-MsoNormal"><span style=""><span class="font" style="font-family:"Courier New";"><span class="size" style="font-size:10pt;">        .outbus(outbus));</span></span></span><br></p><pre> <br></pre><pre>assign limit = (cnt0 == 24999);<br></pre><p class="qt-MsoNormal"><span lang="EN-US" style=""> </span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="">But you are totally free to set the CPU’s .irq signal on other HW conditions, e.g. a packet on the Ethernet board arrived or the temperature sensor says the meat is tender.</span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style=""> </span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="">Below I attached an older mail on an “simple” API to facilitate programming with interrupts. Instead of Kernel.Install you would call Interrupt.Install to install the interrupt handler.</span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style=""> </span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="">br</span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="">Jörg</span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style=""> </span><br></p><div style="border-right-width:initial;border-bottom-width:initial;border-left-width:initial;border-right-style:none;border-bottom-style:none;border-left-style:none;border-right-color:initial;border-bottom-color:initial;border-left-color:initial;border-image-source:initial;border-image-slice:initial;border-image-width:initial;border-image-outset:initial;border-image-repeat:initial;border-top-width:1pt;border-top-style:solid;border-top-color:rgb(181, 196, 223);padding-top:3pt;padding-right:0cm;padding-bottom:0cm;padding-left:0cm;"><p class="qt-MsoNormal"><b><span style="color:black;"><span class="size" style="font-size:12pt;">Von: </span></span></b><span style="color:black;"><span class="size" style="font-size:12pt;">Oberon <oberon-bounces@lists.inf.ethz.ch> im Auftrag von Jeff Maggio <jmaggio14@gmail.com><br><b>Antworten an: </b>ETH Oberon and related systems <oberon@lists.inf.ethz.ch><br><b>Datum: </b>Donnerstag, 6. Mai 2021 um 13:44<br><b>An: </b><oberon@lists.inf.ethz.ch><br><b>Betreff: </b>[Oberon] Stimulus driven interrupts?</span></span></p></div><div><p class="qt-MsoNormal"> <br></p></div><div><div><p class="qt-MsoNormal">Hi all,<br></p></div><div><p class="qt-MsoNormal"> <br></p></div><div><p class="qt-MsoNormal">I'm using Oberon on an embedded RISC5 system, and am able to modify both firmware and software. <br></p></div><div><p class="qt-MsoNormal"> <br></p></div><p class="qt-MsoNormal">In this Oberon-1 paper (<b><a href="http://norayr.am/papers/WirthTasksVersusThreads.pdf">http://norayr.am/papers/WirthTasksVersusThreads.pdf</a></b>) from 1996, Wirth discusses a method of "real-time tasks". <b>(Page 10)</b>. In which I believe interrupt handlers installed with <b>Kernel.Install(Handler, N)</b> are triggered when a device or buffer is updated? The details are unclear in the paper. <br></p><div><p class="qt-MsoNormal"></p><div><br></div><div>I see that <b>Kernel.Install</b> still exists in the RISC5 source. Can this method still be used for "real-time tasks" in which a procedure is run when an external stimulus changes? So far all the interrupt examples I've seen make use of interrupts triggered periodically by the millisecond timer.<br></div><p></p></div><div><p class="qt-MsoNormal"></p><div><br></div><div>My end goal is to trigger an interrupt (from firmware or otherwise) in reaction to stimulus without having to wait for the millisecond timer<br></div><p></p></div><div><p class="qt-MsoNormal"> <br></p></div><div><p class="qt-MsoNormal">best,<br></p></div><div><p class="qt-MsoNormal">Jeff<br></p></div></div><p class="qt-MsoNormal">-- Oberon@lists.inf.ethz.ch mailing list for ETH Oberon and related systems https://lists.inf.ethz.ch/mailman/listinfo/oberon<br></p><p class="qt-MsoNormal"> <br></p><p class="qt-MsoNormal">. . . . . .<br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><span class="size" style="font-size:13.5pt;">Hi</span></span></span><span lang="EN-US"></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">A remark on interrupts in ProjectOberon:</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">The current implementation of interrupts looks to me a little bit like a quick and dirty hack or proof of concept. I don‘t find it user-friendly a programmer has to import SYSTEM and has to know the „magic“ address 4. Let me explain.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Offering interrupts to the programmer needs three parts:</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">- CPU support: instructions to enable/disable interrupts and return from interrupts.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">   DONE.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">- Compiler support: PROCEDURE* is parsed and correct instructions are generated.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">   DONE.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">- OS support: an easy to use API to use the interrupt in a program.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">   MISSING.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Of course I can provide an API myself. Eg:</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">MODULE Interrupt; (* jr/31dec19 *)</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">  IMPORT SYSTEM, Kernel;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">  PROCEDURE* Empty; END Empty;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">  PROCEDURE Install*(handler: PROCEDURE); (* handler=NIL: deactivate interrupts *)</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">    VAR instr: INTEGER;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">    BEGIN</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">      SYSTEM.LDPSR(0);</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">      Kernel.Install(SYSTEM.ADR(Empty), 4);</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">      SYSTEM.GET(SYSTEM.VAL, INTEGER, handler)+4, instr);</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">      IF instr = 0A0E00000H THEN (* valid interrupt handler *)</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">        </span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Kernel.Install(SYSTEM.VAL(INTEGER, handler), 4);</span></span><br></p><p class="qt-MsoNormal"><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">        </span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">SYSTEM.LDPSR(1)</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">      END</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">    END Install;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">BEGIN Install(NIL) END Interrupt.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">For me something like the above should be part of the inner core (e.g. Kernel.Mod) or at least a module of the outer core to be provided with the standard distribution.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">With the above API, interrupts are easily consumable (no import of SYSTEM, all the nitty gritty details hidden in Interrupt.Mod)</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">MODULE TestInt;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">IMPORT Interrupt;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">VAR led, cnt: INTEGER;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">PROCEDURE* Int; (*interrupt handler called every millisecond*)</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">  BEGIN</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">    INC(cnt); IF cnt = 500 THEN led := 3 - led; LED(led); cnt := 0 END</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">  END Int;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">PROCEDURE On*;  BEGIN Interrupt.Install(Int) END On;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">PROCEDURE Off*;  BEGIN Interrupt.Install(NIL) END Off;</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">BEGIN</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">  led := 1; cnt := 0</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">END TestInt.</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">br</span></span><br></p><p class="qt-MsoNormal"><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Jörg</span></span><br></p><p class="qt-MsoNormal"><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><br></span></span></p><p class="qt-MsoNormal" style="margin-bottom:12pt;"><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Am 30.12.2019 um 16:12 schrieb Charles Perkins <<a href="mailto:chuck@kuracali.com">chuck@kuracali.com</a>>:</span></span><br></p><p class="qt-MsoNormal"><span style="color:black;"></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"></span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Hi Paul and Jörg,</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Sometimes I am too clever for my own good. I thought I saw a way out of the name confusion. I'll make it clear that RISC5 is the correct name for the architecture. Also, I missed the CPU version bits in the emulator -- I will have to make sure the SYSTEM.H code works too... after I correct DIV for negative operands and finish floating point!  </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Of course this is just another emulator and the Oberon community already has plenty of those but I wanted to work with just one emulation platform across several porting efforts, and QEMU is to me the obvious choice. And as a side benefit it seems quite fast, comparatively. </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Cheers,</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Chuck</span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> </span></span><br></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">On Mon, Dec 30, 2019 at 1:43 AM Jörg <</span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="mailto:joerg.straube@iaeth.ch"><span lang="EN-US">joerg.straube@iaeth.ch</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">> wrote:</span></span><br></p><p class="qt-MsoNormal" style="margin-left:40.8pt;"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Hi<br><br>You can ask the RISC processor to reveal its version with this code<br><br>   cpu := SYSTEM.H(2019) MOD 80H;<br>   IF cpu = 53H THEN       (* RISC5: with interrupts + floating-point, 31.8.2018 *)<br>   ELSIF cpu = 54H THEN (* RISC5a: no interrupts, no floating-point, 1.9.2018*)<br>   ELSIF cpu = A0H THEN (* RISC0, 26.12.2013 *)<br>   END;<br><br>br<br>Jörg<br><br></span></span><span style="color:black;"></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">Am 30.12.19, 09:56 schrieb "Oberon im Auftrag von Paul Reed" <</span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="mailto:oberon-bounces@lists.inf.ethz.ch" target="_blank"><span lang="EN-US">oberon-bounces@lists.inf.ethz.ch</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> im Auftrag von </span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="mailto:paulreed@paddedcell.com" target="_blank"><span lang="EN-US">paulreed@paddedcell.com</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">>:<br><br>    Hi Chuck,<br><br>    > ...the target is named risc6<br>    > to avoid confusion with the already existing riscv target in qemu and<br>    > because in one communication (An Update of the RISC5 Implementation<br>    > [1]) Professor Wirth defines module RISC6 to introduce interrupts into<br>    > the architecture.<br><br>    Sorry I think that's a mis-print since it's the only occurrence, I'm <br>    pretty sure the intention was to keep it as RISC5.  Apologies for any <br>    confusion.<br><br>    As it happens most of the stuff for interrupts was there originally <br>    anyway before the update, especially in the compiler.  The RISC5 source <br>    on Prof. Wirth's site definitely contains the interrupt code now.  <br>    There's also a RISC5a version, without interrupts and without <br>    floating-point.<br><br>    Cheers,<br>    Paul<br>    --<br>    </span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="mailto:Oberon@lists.inf.ethz.ch" target="_blank"><span lang="EN-US">Oberon@lists.inf.ethz.ch</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> mailing list for ETH Oberon and related systems<br>    </span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" target="_blank"><span lang="EN-US">https://lists.inf.ethz.ch/mailman/listinfo/oberon</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><br><br><br><br>--<br></span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="mailto:Oberon@lists.inf.ethz.ch" target="_blank"><span lang="EN-US">Oberon@lists.inf.ethz.ch</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> mailing list for ETH Oberon and related systems<br></span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon" target="_blank"><span lang="EN-US">https://lists.inf.ethz.ch/mailman/listinfo/oberon</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"></span></span></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;">--<br></span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="mailto:Oberon@lists.inf.ethz.ch"><span lang="EN-US">Oberon@lists.inf.ethz.ch</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"> mailing list for ETH Oberon and related systems<br></span></span><span style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon"><span lang="EN-US">https://lists.inf.ethz.ch/mailman/listinfo/oberon</span></a></span></span><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"></span></span></p><p class="qt-MsoNormal"><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><span class="size" style="font-size:13.5pt;">-- </span></span></span><a href="mailto:Oberon@lists.inf.ethz.ch"><span lang="EN-US" style=""><span class="font" style="font-family:-webkit-standard, serif;">Oberon@lists.inf.ethz.ch</span></span></a><span lang="EN-US" style="color:black;"><span class="font" style="font-family:-webkit-standard, serif;"><span class="size" style="font-size:13.5pt;"> mailing list for ETH Oberon and related systems </span></span></span><a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon"><span lang="EN-US" style=""><span class="font" style="font-family:-webkit-standard, serif;">https://lists.inf.ethz.ch/mailman/listinfo/oberon</span></span></a><span lang="EN-US"></span><br></p><p class="qt-MsoNormal"><span lang="EN-US"> </span><br></p></div><div>--<br></div><div><a href="mailto:Oberon%40lists.inf.ethz.ch">Oberon@lists.inf.ethz.ch</a> mailing list for ETH Oberon and related systems<br></div><div><a href="https://lists.inf.ethz.ch/mailman/listinfo/oberon">https://lists.inf.ethz.ch/mailman/listinfo/oberon</a><br></div><div><br></div></blockquote><div><br></div></body></html>