Browse Source

synchronized with original

Alexander Shiryaev 5 years ago
parent
commit
48b490dc74

+ 22 - 18
BlackBox/Po/Files/ORB.Mod.txt

@@ -1,4 +1,4 @@
-MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
+MODULE ORB;   (*NW 25.6.2014  / 1.3.2019  in Oberon-07*)
   IMPORT Files, ORS;
   (*Definition of data types Object and Type, which together form the data structure
     called "symbol table". Contains procedures for creation of Objects, and for search:
@@ -133,13 +133,7 @@ MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
     VAR mod: Module; obj, obj1: Object;
   BEGIN obj1 := topScope; obj := obj1.next;  (*search for module*)
     WHILE (obj # NIL) & (obj.name # name) DO obj1 := obj; obj := obj1.next END ;
-    IF obj = NIL THEN 
-      obj1 := topScope; obj := obj1.next;
-      WHILE (obj # NIL) & (obj IS Module) & (obj(Module).orgname # orgname) DO
-        obj1 := obj; obj := obj1.next
-      END
-    END ;
-    IF obj = NIL THEN (*insert new module*)
+    IF obj = NIL THEN  (*insert new module*)
       NEW(mod); mod.class := Mod; mod.rdo := FALSE;
       mod.name := name; mod.orgname := orgname; mod.val := key;
       mod.lev := nofmod; INC(nofmod); mod.type := noType; mod.dsc := NIL; mod.next := NIL;
@@ -211,7 +205,8 @@ MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
   
   PROCEDURE Import*(VAR modid, modid1: ORS.Ident);
     VAR key: LONGINT; class, k: INTEGER;
-      obj, thismod: Object;
+      obj: Object;  t: Type;
+      thismod: Object;
       modname, fname: ORS.Ident;
       F: Files.File; R: Files.Rider;
   BEGIN
@@ -228,10 +223,14 @@ MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
         WHILE class # 0 DO
           NEW(obj); obj.class := class; Files.ReadString(R, obj.name);
           InType(R, thismod, obj.type); obj.lev := -thismod.lev;
-          IF class = Typ THEN obj.type.typobj := obj; Read(R, k)
-          ELSIF class = Const THEN
+          IF class = Typ THEN
+            t := obj.type; t.typobj := obj; Read(R, k);  (*fixup bases of previously declared pointer types*)
+            WHILE k # 0 DO typtab[k].base := t; Read(R, k) END
+          ELSE
+            IF class = Const THEN
               IF obj.type.form = Real THEN Files.ReadInt(R, obj.val) ELSE Files.ReadNum(R, obj.val) END
-          ELSIF class = Var THEN Files.ReadNum(R, obj.val); obj.rdo := TRUE
+            ELSIF class = Var THEN Files.ReadNum(R, obj.val); obj.rdo := TRUE
+            END
           END ;
           obj.next := thismod.dsc; thismod.dsc := obj; Read(R, class)
         END ;
@@ -280,10 +279,7 @@ MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
       ELSIF t.form = Array THEN OutType(R, t.base); Files.WriteNum(R, t.len); Files.WriteNum(R, t.size)
       ELSIF t.form = Record THEN
         IF t.base # NIL THEN OutType(R, t.base); bot := t.base.dsc ELSE OutType(R, noType); bot := NIL END ;
-        IF obj # NIL THEN
-           IF t.mno > 0 THEN Files.WriteNum(R, t.len) ELSE Files.WriteNum(R, obj.exno) END
-        ELSE Write(R, 0)
-        END ;
+        IF obj # NIL THEN Files.WriteNum(R, obj.exno) ELSE Write(R, 0) END ;
         Files.WriteNum(R, t.nofpar); Files.WriteNum(R, t.size);
         fld := t.dsc;
         WHILE fld # bot DO  (*fields*)
@@ -309,7 +305,7 @@ MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
 
   PROCEDURE Export*(VAR modid: ORS.Ident; VAR newSF: BOOLEAN; VAR key: LONGINT);
     VAR x, sum, oldkey: LONGINT;
-      obj: Object;
+      obj, obj0: Object;
       filename: ORS.Ident;
       F, F1: Files.File; R, R1: Files.Rider;
   BEGIN Ref := Record + 1; MakeFileName(filename, modid, ".smb");
@@ -322,7 +318,15 @@ MODULE ORB;   (*NW 25.6.2014  / 26.1.2020   in Oberon-07*)
       IF obj.expo THEN
         Write(R, obj.class); Files.WriteString(R, obj.name);
         OutType(R, obj.type);
-        IF obj.class = Typ THEN Write(R, 0)
+        IF obj.class = Typ THEN
+          IF obj.type.form = Record THEN
+            obj0 := topScope.next;  (*check whether this is base of previously declared pointer types*)
+            WHILE obj0 # obj DO
+              IF (obj0.type.form = Pointer) & (obj0.type.base = obj.type) & (obj0.type.ref > 0) THEN Write(R, obj0.type.ref) END ;
+              obj0 := obj0.next
+            END
+          END ;
+          Write(R, 0)
         ELSIF obj.class = Const THEN
           IF obj.type.form = Proc THEN Files.WriteNum(R, obj.exno)
           ELSIF obj.type.form = Real THEN Files.WriteInt(R, obj.val)

+ 23 - 19
BlackBox/Po/Files/ORP.Mod.txt

@@ -1,4 +1,4 @@
-MODULE ORP; (*N. Wirth 1.7.97 / 31.5.2019  Oberon compiler for RISC in Oberon-07*)
+MODULE ORP; (*N. Wirth 1.7.97 / 8.2.2020  Oberon compiler for RISC in Oberon-07*)
   IMPORT Texts, Oberon, ORS, ORB, ORG;
   (*Author: Niklaus Wirth, 2014.
     Parser of Oberon-RISC compiler. Uses Scanner ORS to obtain symbols (tokens),
@@ -889,12 +889,29 @@ MODULE ORP; (*N. Wirth 1.7.97 / 31.5.2019  Oberon compiler for RISC in Oberon-07
         ORS.Get(sym)
       ELSE ORS.Mark("no proc id")
       END
+    ELSE ORS.Mark("proc id expected")
     END
   END ProcedureDecl;
 
+  PROCEDURE Import;
+    VAR impid, impid1: ORS.Ident;
+  BEGIN
+    IF sym = ORS.ident THEN
+      ORS.CopyId(impid); ORS.Get(sym);
+      IF sym = ORS.becomes THEN
+        ORS.Get(sym);
+        IF sym = ORS.ident THEN ORS.CopyId(impid1); ORS.Get(sym)
+        ELSE ORS.Mark("id expected"); impid1 := impid
+        END
+      ELSE impid1 := impid
+      END ;
+      ORB.Import(impid, impid1)
+    ELSE ORS.Mark("id expected")
+    END
+  END Import;
+
   PROCEDURE Module;
     VAR key: LONGINT;
-      impid, impid1: ORS.Ident;
   BEGIN Texts.WriteString(W, "  compiling "); ORS.Get(sym);
     IF sym = ORS.module THEN
       ORS.Get(sym);
@@ -907,22 +924,9 @@ MODULE ORP; (*N. Wirth 1.7.97 / 31.5.2019  Oberon compiler for RISC in Oberon-07
       END ;
       Check(ORS.semicolon, "no ;"); level := 0; exno := 1; key := 0;
       IF sym = ORS.import THEN
-        ORS.Get(sym);
-        WHILE sym = ORS.ident DO
-          ORS.CopyId(impid); ORS.Get(sym);
-          IF sym = ORS.becomes THEN
-            ORS.Get(sym);
-            IF sym = ORS.ident THEN ORS.CopyId(impid1); ORS.Get(sym)
-            ELSE ORS.Mark("id expected")
-            END
-          ELSE impid1 := impid
-          END ;
-          ORB.Import(impid, impid1);
-          IF sym = ORS.comma THEN ORS.Get(sym)
-          ELSIF sym = ORS.ident THEN ORS.Mark("comma missing")
-          END
-        END ;
-        Check(ORS.semicolon, "no ;")
+        ORS.Get(sym); Import;
+        WHILE sym = ORS.comma DO ORS.Get(sym); Import END ;
+        Check(ORS.semicolon, "; missing")
       END ;
       ORG.Open(version); Declarations(dc); ORG.SetDataSize((dc + 3) DIV 4 * 4);
       WHILE sym = ORS.procedure DO ProcedureDecl; Check(ORS.semicolon, "no ;") END ;
@@ -990,7 +994,7 @@ MODULE ORP; (*N. Wirth 1.7.97 / 31.5.2019  Oberon compiler for RISC in Oberon-07
     Oberon.Collect(0)
   END Compile;
 
-BEGIN Texts.OpenWriter(W); Texts.WriteString(W, "OR Compiler  31.5.2019");
+BEGIN Texts.OpenWriter(W); Texts.WriteString(W, "OR Compiler  8.2.2020");
   Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf);
   NEW(dummy); dummy.class := ORB.Var; dummy.type := ORB.intType;
   expression := expression0; Type := Type0; FormalType := FormalType0

+ 184 - 183
BlackBox/Po/Files/RISC5.v

@@ -1,183 +1,184 @@
-`timescale 1ns / 1ps  // 9.11.2016
-
-module RISC5(
-input clk, rst, stallX,
-input [31:0] inbus, codebus,
-output [23:0] adr,
-output rd, wr, ben,
-output [31:0] outbus);
-
-localparam StartAdr = 22'h3FF800;
-
-reg [21:0] PC;
-reg [31:0] IR;  // instruction register
-reg N, Z, C, OV;  // condition flags 
-reg [31:0] R [0:15];  // array of 16 registers
-reg [31:0] H;  // aux register
-reg stall1, PMsel;
-
-wire [31:0] ins, pmout;
-wire [21:0] pcmux, nxpc;
-wire cond, S;
-wire sa, sb, sc;
-
-wire p, q, u, v;  // instruction fields
-wire [3:0] op, ira, ira0, irb, irc;
-wire [2:0] cc;
-wire [15:0] imm;
-wire [19:0] off;
-wire [21:0] disp;
-
-wire regwr;
-wire stall, stallL, stallM, stallD, stallFA, stallFM, stallFD;
-wire a0, a1, a2, a3;
-wire [7:0] inbusL, outbusB0, outbusB1, outbusB2, outbusB3;
-wire [23:0] inbusH;
-
-wire [31:0] A, B, C0, C1, aluRes, regmux;
-wire [31:0] lshout, rshout;
-wire [31:0] quotient, remainder;
-wire [63:0] product;
-wire [31:0] fsum, fprod, fquot;
-
-wire ADD, SUB, MUL, DIV;
-wire FAD, FSB, FML, FDV;
-wire LDR, STR, BR;
-
-PROM PM (.adr(pcmux[8:0]), .data(pmout), .clk(clk));
-
-Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
-   .u(~u), .x(B), .y(C1), .z(product));
-
-Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
-   .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
-
-LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
-
-RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(ins[16]));
-
-FPAdder fpaddx (.clk(clk), .run(FAD|FSB), .u(u), .v(v), .stall(stallFA),
-   .x(B), .y({FSB^C0[31], C0[30:0]}), .z(fsum));
-
-FPMultiplier fpmulx (.clk(clk), .run(FML), .stall(stallFM),
-   .x(B), .y(C0), .z(fprod));
-
-FPDivider fpdivx (.clk(clk), .run(FDV), .stall(stallFD),
-   .x(B), .y(C0), .z(fquot));
-
-assign ins = PMsel ? pmout : IR;  // decoding
-assign p = ins[31];
-assign q = ins[30];
-assign u = ins[29];
-assign v = ins[28];
-assign cc  = ins[26:24];
-assign ira = ins[27:24];
-assign irb = ins[23:20];
-assign op  = ins[19:16];
-assign irc = ins[3:0];
-assign imm = ins[15:0];   // reg instr.
-assign off = ins[19:0];   // mem instr.
-assign disp = ins[21:0];  // branch instr.
-
-assign ADD = ~p & (op == 8);
-assign SUB = ~p & (op == 9);
-assign MUL = ~p & (op == 10);
-assign DIV = ~p & (op == 11);
-assign FAD = ~p & (op == 12);
-assign FSB = ~p & (op == 13);
-assign FML = ~p & (op == 14);
-assign FDV = ~p & (op == 15);
-
-assign LDR = p & ~q & ~u;
-assign STR = p & ~q & u;
-assign BR = p & q;
-
-assign A = R[ira0];  // register data signals
-assign B = R[irb];
-assign C0 = R[irc];
-
-// Arithmetic-logical unit (ALU)
-assign ira0 = BR ? 15 : ira;
-assign C1 = q ? {{16{v}}, imm} : C0;
-assign adr = stallL ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
-assign rd = LDR & ~stallX & ~stall1;
-assign wr = STR & ~stallX & ~stall1;
-assign ben = p & ~q & v & ~stallX & ~stall1;  // byte enable
-
-assign aluRes =  // 21.71 ns
-  ~op[3] ?
-    (~op[2] ?
-      (~op[1] ?
-        (~op[0] ? 
-          (q ?  // MOV
-            (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
-            (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h50}))) :
-          lshout) :  //  LSL
-        rshout) : //  ASR, ROR
-      (~op[1] ?
-        (~op[0] ? B & C1 : B & ~C1) :  // AND, ANN
-        (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
-    (~op[2] ?
-       (~op[1] ?
-          (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) :   // ADD, SUB
-           (~op[0] ? product[31:0] : quotient)) :  // MUL, DIV
-         (~op[1] ?    // flt.pt.
-          fsum :
-          (~op[0] ? fprod : fquot)));
-
-assign regwr = ~p & ~stall | (LDR & ~stallX & ~stall1) | (BR & cond & v & ~stallX);
-assign a0 = ~adr[1] & ~adr[0];
-assign a1 = ~adr[1] & adr[0];
-assign a2 = adr[1] & ~adr[0];
-assign a3 = adr[1] & adr[0];
-assign inbusL = (~ben | a0) ? inbus[7:0] :
-  a1 ? inbus[15:8] : a2 ? inbus[23:16] : inbus[31:24];
-assign inbusH = ~ben ? inbus[31:8] : 24'b0;
-assign regmux = LDR ? {inbusH, inbusL} : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
-
-assign outbusB0 = A[7:0];
-assign outbusB1 = ben & a1 ? A[7:0] : A[15:8];
-assign outbusB2 = ben & a2 ? A[7:0] : A[23:16];
-assign outbusB3 = ben & a3 ? A[7:0] : A[31:24];
-assign outbus = {outbusB3, outbusB2, outbusB1, outbusB0};
-
-// Control unit CU
-assign S = N ^ OV;
-assign nxpc = PC + 1;
-assign cond = ins[27] ^
-  ((cc == 0) & N | // MI, PL
-   (cc == 1) & Z | // EQ, NE
-   (cc == 2) & C | // CS, CC
-   (cc == 3) & OV | // VS, VC
-   (cc == 4) & (C|Z) | // LS, HI
-   (cc == 5) & S | // LT, GE
-   (cc == 6) & (S|Z) | // LE, GT
-   (cc == 7)); // T, F
-
-assign pcmux = ~rst ? StartAdr :
-  stall ? PC :
-  (BR & cond & u) ? nxpc + disp :
-  (BR & cond & ~u) ? C0[23:2] : nxpc;
-  
-assign sa = aluRes[31];
-assign sb = B[31];
-assign sc = C1[31];
-
-assign stall = stallL | stallM | stallD | stallX | stallFA | stallFM | stallFD;
-assign stallL = (LDR|STR) & ~stall1;
-
-always @ (posedge clk) begin
-  PC <= pcmux;
-  PMsel <= ~rst | (pcmux[21:12] == 10'h3FF);
-  IR <= stall ? IR : codebus;
-  stall1 <= stallX ? stall1 : stallL;
-  R[ira0] <= regwr ? regmux : A;
-  N <= regwr ? regmux[31] : N;
-  Z <= regwr ? (regmux == 0) : Z;
-  C <= ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
-	 SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
-  OV <= ADD ? (sa&~sb&~sc) | (~sa&sb&sc): 
-	 SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
-  H <= MUL ? product[63:32] : DIV ? remainder : H;
-end 
-endmodule 
+`timescale 1ns / 1ps  // 31.8.2018
+//with interrupt and floating-point
+
+module RISC5(
+input clk, rst, irq, stallX,
+input [31:0] inbus, codebus,
+output [23:0] adr,
+output rd, wr, ben,
+output [31:0] outbus);
+
+localparam StartAdr = 22'h3FF800;
+
+reg [21:0] PC;
+reg [31:0] IR;  // instruction register
+reg N, Z, C, OV;  // condition flags 
+reg [31:0] H;  // aux register
+reg stallL1;
+
+wire [21:0] pcmux, pcmux0, nxpc;
+wire cond, S;
+wire sa, sb, sc;
+
+wire p, q, u, v;  // instruction fields
+wire [3:0] op, ira, ira0, irb, irc;
+wire [2:0] cc;
+wire [15:0] imm;
+wire [19:0] off;
+wire [21:0] disp;
+
+wire regwr;
+wire stall, stallL0, stallM, stallD, stallFA, stallFM, stallFD;
+wire nn, zz, cx, vv;
+
+reg irq1, intEnb, intPnd, intMd;
+reg [25:0] SPC; // saved PC on interrupt
+wire intAck;
+
+wire [31:0] A, B, C0, C1, aluRes, regmux, inbus1;
+wire [31:0] lshout, rshout;
+wire [31:0] quotient, remainder;
+wire [63:0] product;
+wire [31:0] fsum, fprod, fquot;
+
+wire ADD, SUB, MUL, DIV;
+wire FAD, FSB, FML, FDV;
+wire LDR, STR, BR, RTI;
+
+Registers regs (.clk(clk), .wr(regwr), .rno0(ira0), .rno1(irb),
+   .rno2(irc), .din(regmux), .dout0(A), .dout1(B), .dout2(C0));
+
+Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
+   .u(~u), .x(B), .y(C1), .z(product));
+
+Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
+   .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
+
+LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
+
+RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(IR[16]));
+
+FPAdder fpaddx (.clk(clk), .run(FAD|FSB), .u(u), .v(v), .stall(stallFA),
+   .x(B), .y({FSB^C0[31], C0[30:0]}), .z(fsum));
+
+FPMultiplier fpmulx (.clk(clk), .run(FML), .stall(stallFM),
+   .x(B), .y(C0), .z(fprod));
+
+FPDivider fpdivx (.clk(clk), .run(FDV), .stall(stallFD),
+   .x(B), .y(C0), .z(fquot));
+
+assign p = IR[31];
+assign q = IR[30];
+assign u = IR[29];
+assign v = IR[28];
+assign cc  = IR[26:24];
+assign ira = IR[27:24];
+assign irb = IR[23:20];
+assign op  = IR[19:16];
+assign irc = IR[3:0];
+assign imm = IR[15:0];   // reg instr.
+assign off = IR[19:0];   // mem instr.
+assign disp = IR[21:0];  // branch instr.
+
+assign ADD = ~p & (op == 8);
+assign SUB = ~p & (op == 9);
+assign MUL = ~p & (op == 10);
+assign DIV = ~p & (op == 11);
+
+assign FAD = ~p & (op == 12);
+assign FSB = ~p & (op == 13);
+assign FML = ~p & (op == 14);
+assign FDV = ~p & (op == 15);
+
+assign LDR = p & ~q & ~u;
+assign STR = p & ~q & u;
+assign BR = p & q;
+assign RTI = BR & ~u & ~v & IR[4];
+
+// Arithmetic-logical unit (ALU)
+assign ira0 = BR ? 15 : ira;
+assign C1 = q ? {{16{v}}, imm} : C0;
+assign adr = stallL0 ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
+assign rd = LDR & ~stallX & ~stallL1;
+assign wr = STR & ~stallX & ~stallL1;
+assign ben = p & ~q & v & ~stallX & ~stallL1;  // byte enable
+
+assign aluRes =
+  ~op[3] ?
+    (~op[2] ?
+      (~op[1] ?
+        (~op[0] ? 
+          (q ?  // MOV
+            (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
+            (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h53}))) :
+          lshout) :  //  LSL
+        rshout) : //  ASR, ROR
+      (~op[1] ?
+        (~op[0] ? B & C1 : B & ~C1) :  // AND, ANN
+        (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
+    (~op[2] ?
+       (~op[1] ?
+          (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) :   // ADD, SUB
+           (~op[0] ? product[31:0] : quotient)) :  // MUL, DIV
+       (~op[1] ?    // flt.pt.
+          fsum :
+          (~op[0] ? fprod : fquot)));
+
+assign regwr = ~p & ~stall | (LDR & ~stallX & ~stallL1) | (BR & cond & v & ~stallX);
+assign inbus1 = ~ben ? inbus :
+  {24'b0, (adr[1] ? (adr[0] ? inbus[31:24] : inbus[23:16]) :
+          (adr[0] ? inbus[15:8] : inbus[7:0]))};
+assign regmux = LDR ? inbus1 : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
+assign outbus = ~ben ? A :
+  adr[1] ? (adr[0] ? {A[7:0], 24'b0} : {8'b0, A[7:0], 16'b0}) :
+           (adr[0] ? {16'b0, A[7:0], 8'b0} : {24'b0, A[7:0]});
+
+// Control unit CU
+assign S = N ^ OV;
+assign nxpc = PC + 1;
+assign cond = IR[27] ^
+  ((cc == 0) & N | // MI, PL
+   (cc == 1) & Z | // EQ, NE
+   (cc == 2) & C | // CS, CC
+   (cc == 3) & OV | // VS, VC
+   (cc == 4) & (C|Z) | // LS, HI
+   (cc == 5) & S | // LT, GE
+   (cc == 6) & (S|Z) | // LE, GT
+   (cc == 7)); // T, F
+
+assign intAck = intPnd & intEnb & ~intMd & ~stall;
+assign pcmux = ~rst | stall | intAck | RTI ? 
+   (~rst | stall ? (~rst ? StartAdr : PC) :
+   (intAck ? 1 : SPC)) : pcmux0;
+assign pcmux0 = (BR & cond) ? (u? nxpc + disp : C0[23:2]) : nxpc;
+  
+assign sa = aluRes[31];
+assign sb = B[31];
+assign sc = C1[31];
+
+assign nn = RTI ? SPC[25] : regwr ? regmux[31] : N;
+assign zz = RTI ? SPC[24] : regwr ? (regmux == 0) : Z;
+assign cx = RTI ? SPC[23] :
+    ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
+	 SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
+assign vv = RTI ? SPC[22] :
+    ADD ? (sa&~sb&~sc) | (~sa&sb&sc): 
+	 SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
+	 
+assign stallL0 = (LDR|STR) & ~stallL1;
+assign stall = stallL0 | stallM | stallD | stallX | stallFA | stallFM | stallFD;
+
+always @ (posedge clk) begin
+  PC <= pcmux;
+  IR <= stall ? IR : codebus;
+  stallL1 <= stallX ? stallL1 : stallL0;
+  N <= nn; Z <= zz; C <= cx; OV <= vv;
+  H <= MUL ? product[63:32] : DIV ? remainder : H;
+
+  irq1 <= irq;  // edge detector
+  intPnd <= rst & ~intAck & ((~irq1 & irq) | intPnd);
+  intMd <= rst & ~RTI & (intAck | intMd);
+  intEnb <= ~rst ? 0 : (BR & ~u & ~v & IR[5]) ? IR[0] : intEnb;
+  SPC <= (intAck) ? {nn, zz, cx, vv, pcmux0} : SPC;
+  end 
+endmodule 

+ 36 - 28
BlackBox/Po/Files/RISC5Top.v

@@ -1,5 +1,5 @@
-`timescale 1ns / 1ps  // 22.9.2015
-// with SRAM, byte access, flt.-pt., and gpio
+`timescale 1ns / 1ps  // 14.6.2018
+// with SRAM, and gpio
 // PS/2 mouse and network 7.1.2014 PDR
 
 module RISC5Top(
@@ -24,23 +24,25 @@ module RISC5Top(
   inout [7:0] gpio);
 
 // IO addresses for input / output
-// 0  milliseconds / --
-// 1  switches / LEDs
-// 2  RS-232 data / RS-232 data (start)
-// 3  RS-232 status / RS-232 control
-// 4  SPI data / SPI data (start)
-// 5  SPI status / SPI control
-// 6  PS2 keyboard / --
-// 7  mouse / --
-// 8  general-purpose I/O data
-// 9  general-purpose I/O tri-state control
+// 0  -64  FFFFC0  milliseconds / --
+// 1  -60  FFFFC4  switches / LEDs
+// 2  -56  FFFFC8  RS-232 data / RS-232 data (start)
+// 3  -52  FFFFCC  RS-232 status / RS-232 control
+// 4  -48  FFFFD0  SPI data / SPI data (start)
+// 5  -44  FFFFD4  SPI status / SPI control
+// 6  -40  FFFFD8  PS2 mouse data, keyboard status / --
+// 7  -36  FFFFDC  keyboard data / --
+// 8  -32  FFFFE0  general-purpose I/O data
+// 9  -28  FFFFE4  general-purpose I/O tri-state control
 
 reg rst, clk;
 wire[23:0] adr;
 wire [3:0] iowadr; // word address
 wire [31:0] inbus, inbus0;  // data to RISC core
 wire [31:0] outbus;  // data from RISC core
-wire rd, wr, ben, ioenb, dspreq;
+wire [31:0] romout, codebus;  // code to RISC core
+wire SRbe0, SRbe1;
+wire rd, wr, ben, ioenb, vidreq;
 
 wire [7:0] dataTx, dataRx, dataKbd;
 wire rdyRx, doneRx, startTx, rdyTx, rdyKbd, doneKbd;
@@ -59,21 +61,27 @@ wire [17:0] vidadr;
 reg [7:0] gpout, gpoc;
 wire [7:0] gpin;
 
-RISC5 riscx(.clk(clk), .rst(rst), .rd(rd), .wr(wr), .ben(ben), .stallX(dspreq),
-   .adr(adr), .codebus(inbus0), .inbus(inbus), .outbus(outbus));
-RS232R receiver(.clk(clk), .rst(rst), .RxD(RxD), .fsel(bitrate), .done(doneRx),
-   .data(dataRx), .rdy(rdyRx));
-RS232T transmitter(.clk(clk), .rst(rst), .start(startTx), .fsel(bitrate),
-   .data(dataTx), .TxD(TxD), .rdy(rdyTx));
+RISC5 riscx(.clk(clk), .rst(rst), .irq(limit),
+   .rd(rd), .wr(wr), .ben(ben), .stallX(vidreq),
+   .adr(adr), .codebus(codebus), .inbus(inbus),
+	.outbus(outbus));
+PROM PM (.adr(adr[10:2]), .data(romout), .clk(~clk));
+RS232R receiver(.clk(clk), .rst(rst), .RxD(RxD), .fsel(bitrate),
+   .done(doneRx), .data(dataRx), .rdy(rdyRx));
+RS232T transmitter(.clk(clk), .rst(rst), .start(startTx),
+   .fsel(bitrate), .data(dataTx), .TxD(TxD), .rdy(rdyTx));
 SPI spi(.clk(clk), .rst(rst), .start(spiStart), .dataTx(outbus),
    .fast(spiCtrl[2]), .dataRx(spiRx), .rdy(spiRdy),
  	.SCLK(SCLK[0]), .MOSI(MOSI[0]), .MISO(MISO[0] & MISO[1]));
-VID vid(.clk(clk), .req(dspreq), .inv(swi[7]),
-   .vidadr(vidadr), .viddata(inbus0), .RGB(RGB), .hsync(hsync), .vsync(vsync));
+VID vid(.clk(clk), .req(vidreq), .inv(swi[7]),
+   .vidadr(vidadr), .viddata(inbus0), .RGB(RGB),
+	.hsync(hsync), .vsync(vsync));
 PS2 kbd(.clk(clk), .rst(rst), .done(doneKbd), .rdy(rdyKbd), .shift(),
    .data(dataKbd), .PS2C(PS2C), .PS2D(PS2D));
-MouseP Ms(.clk(clk), .rst(rst), .msclk(msclk), .msdat(msdat), .out(dataMs));
+MouseP Ms(.clk(clk), .rst(rst), .msclk(msclk),
+   .msdat(msdat), .out(dataMs));
 
+assign codebus = (adr[23:14] == 10'h3FF) ? romout : inbus0;
 assign iowadr = adr[5:2];
 assign ioenb = (adr[23:6] == 18'h3FFFF);
 assign inbus = ~ioenb ? inbus0 :
@@ -88,14 +96,14 @@ assign inbus = ~ioenb ? inbus0 :
     (iowadr == 8) ? {24'b0, gpin} :
     (iowadr == 9) ? {24'b0, gpoc} : 0);
 	 
-assign SRce0 = ben & adr[1];
-assign SRce1 = ben & ~adr[1];
-assign SRbe0 = ben & adr[0];
-assign SRbe1 = ben & ~adr[0];
+assign SRce0 = ~(~ben | ~adr[1]);
+assign SRce1 = ~(~ben | adr[1]);
+assign SRbe0 = ~(~ben | ~adr[0]);
+assign SRbe1 = ~(~ben | adr[0]);
 assign SRwe = ~wr | clk;
 assign SRoe = wr;
 assign SRbe = {SRbe1, SRbe0, SRbe1, SRbe0};
-assign SRadr = dspreq ? vidadr : adr[19:2];
+assign SRadr = vidreq ? vidadr : adr[19:2];
 
 genvar i;
 generate // tri-state buffer for SRAM
@@ -135,4 +143,4 @@ begin
 end
 
 always @ (posedge CLK50M) clk <= ~clk;
-endmodule
+endmodule

+ 147 - 0
BlackBox/Po/Files/RISC5a.v

@@ -0,0 +1,147 @@
+`timescale 1ns / 1ps  // 1.9.2018
+//no interrupt, no floating-point
+
+module RISC5(
+input clk, rst, irq, stallX,
+input [31:0] inbus, codebus,
+output [23:0] adr,
+output rd, wr, ben,
+output [31:0] outbus);
+
+localparam StartAdr = 22'h3FF800;
+
+reg [21:0] PC;
+reg [31:0] IR;  // instruction register
+reg N, Z, C, OV;  // condition flags 
+reg [31:0] H;  // aux register
+reg stallL1;
+
+wire [21:0] pcmux, nxpc;
+wire cond, S;
+wire sa, sb, sc;
+
+wire p, q, u, v;  // instruction fields
+wire [3:0] op, ira, ira0, irb, irc;
+wire [2:0] cc;
+wire [15:0] imm;
+wire [19:0] off;
+wire [21:0] disp;
+
+wire regwr;
+wire stall, stallL0, stallM, stallD;
+wire [31:0] A, B, C0, C1, aluRes, regmux, inbus1;
+wire [31:0] lshout, rshout;
+wire [31:0] quotient, remainder;
+wire [63:0] product;
+
+wire ADD, SUB, MUL, DIV;
+wire LDR, STR, BR;
+
+Registers regs (.clk(clk), .wr(regwr), .rno0(ira0), .rno1(irb),
+   .rno2(irc), .din(regmux), .dout0(A), .dout1(B), .dout2(C0));
+
+Multiplier mulUnit (.clk(clk), .run(MUL), .stall(stallM),
+   .u(~u), .x(B), .y(C1), .z(product));
+
+Divider divUnit (.clk(clk), .run(DIV), .stall(stallD),
+   .u(~u), .x(B), .y(C1), .quot(quotient), .rem(remainder));
+
+LeftShifter LSUnit (.x(B), .y(lshout), .sc(C1[4:0]));
+
+RightShifter RSUnit(.x(B), .y(rshout), .sc(C1[4:0]), .md(IR[16]));
+
+assign p = IR[31];
+assign q = IR[30];
+assign u = IR[29];
+assign v = IR[28];
+assign cc  = IR[26:24];
+assign ira = IR[27:24];
+assign irb = IR[23:20];
+assign op  = IR[19:16];
+assign irc = IR[3:0];
+assign imm = IR[15:0];   // reg instr.
+assign off = IR[19:0];   // mem instr.
+assign disp = IR[21:0];  // branch instr.
+
+assign ADD = ~p & (op == 8);
+assign SUB = ~p & (op == 9);
+assign MUL = ~p & (op == 10);
+assign DIV = ~p & (op == 11);
+
+assign LDR = p & ~q & ~u;
+assign STR = p & ~q & u;
+assign BR = p & q;
+
+// Arithmetic-logical unit (ALU)
+assign ira0 = BR ? 15 : ira;
+assign C1 = q ? {{16{v}}, imm} : C0;
+assign adr = stallL0 ? B[23:0] + {{4{off[19]}}, off} : {pcmux, 2'b00};
+assign rd = LDR & ~stallX & stallL0;
+assign wr = STR & ~stallX & stallL0;
+assign ben = p & ~q & v & ~stallX & stallL0; // byte enable
+
+assign aluRes =
+  ~op[3] ?
+    (~op[2] ?
+      (~op[1] ?
+        (~op[0] ? 
+          (q ?  // MOV
+            (~u ? {{16{v}}, imm} : {imm, 16'b0}) :
+            (~u ? C0 : (~v ? H : {N, Z, C, OV, 20'b0, 8'h54}))) :
+          lshout) :  //  LSL
+        rshout) : //  ASR, ROR
+      (~op[1] ?
+        (~op[0] ? B & C1 : B & ~C1) :  // AND, ANN
+        (~op[0] ? B | C1 : B ^ C1))) : // IOR. XOR
+    (~op[2] ?
+       (~op[1] ?
+          (~op[0] ? B + C1 + (u&C) : B - C1 - (u&C)) : // ADD, SUB
+           (~op[0] ? product[31:0] : quotient)) :  // MUL, DIV
+        0);
+
+assign regwr = ~p & ~stall | (LDR & ~stallX & ~stallL1) | (BR & cond & v & ~stallX);
+assign inbus1 = ~ben ? inbus :
+  {24'b0, (adr[1] ? (adr[0] ? inbus[31:24] : inbus[23:16]) :
+          (adr[0] ? inbus[15:8] : inbus[7:0]))};
+assign regmux = LDR ? inbus1 : (BR & v) ? {8'b0, nxpc, 2'b0} : aluRes;
+assign outbus = ~ben ? A :
+  adr[1] ? (adr[0] ? {A[7:0], 24'b0} : {8'b0, A[7:0], 16'b0}) :
+           (adr[0] ? {16'b0, A[7:0], 8'b0} : {24'b0, A[7:0]});
+
+// Control unit CU
+assign S = N ^ OV;
+assign nxpc = PC + 1;
+assign cond = IR[27] ^
+  ((cc == 0) & N | // MI, PL
+   (cc == 1) & Z | // EQ, NE
+   (cc == 2) & C | // CS, CC
+   (cc == 3) & OV | // VS, VC
+   (cc == 4) & (C|Z) | // LS, HI
+   (cc == 5) & S | // LT, GE
+   (cc == 6) & (S|Z) | // LE, GT
+   (cc == 7)); // T, F
+
+assign pcmux = ~rst | stall ?
+  (~rst ? StartAdr : PC) :
+  (BR & cond) ? (u ? nxpc + disp : C0[23:2]) : nxpc;
+
+assign sa = aluRes[31];
+assign sb = B[31];
+assign sc = C1[31];
+
+assign stall = stallL0 | stallM | stallD | stallX;
+assign stallL0 = (LDR|STR) & ~stallL1;
+
+always @ (posedge clk) begin
+  PC <= pcmux;
+  IR <= stall ? IR : codebus;
+  stallL1 <= stallX ? stallL1 : stallL0;
+  N <= regwr ? regmux[31] : N;
+  Z <= regwr ? (regmux == 0) : Z;
+  C <= ADD ? (~sb&sc&~sa) | (sb&sc&sa) | (sb&~sa) :
+	 SUB ? (~sb&sc&~sa) | (sb&sc&sa) | (~sb&sa) : C;
+  OV <= ADD ? (sa&~sb&~sc) | (~sa&sb&sc): 
+	 SUB ? (sa&~sb&sc) | (~sa&sb&~sc) : OV;
+  H <= MUL ? product[63:32] : DIV ? remainder : H;
+end 
+endmodule 

+ 46 - 0
BlackBox/Po/Files/Registers.v

@@ -0,0 +1,46 @@
+`timescale 1ns / 1ps  // 1.2.2018
+// register file, triple-port
+
+module Registers(
+  input clk,wr,
+  input [3:0] rno0, rno1, rno2,
+  input [31:0] din,
+  output [31:0] dout0, dout1, dout2);
+genvar i;
+generate    //triple port register file, duplicated LUT array
+	for (i = 0; i < 32; i = i+1)
+	begin: rf32
+	RAM16X1D # (.INIT(16'h0000))
+	rfb(
+	.DPO(dout1[i]), // data out
+	.SPO(dout0[i]),
+	.A0(rno0[0]),   // R/W address, controls D and SPO
+	.A1(rno0[1]),
+	.A2(rno0[2]),
+	.A3(rno0[3]),
+	.D(din[i]),  // data in
+	.DPRA0(rno1[0]), // read-only adr, controls DPO
+	.DPRA1(rno1[1]),
+	.DPRA2(rno1[2]),
+	.DPRA3(rno1[3]),
+	.WCLK(clk),
+	.WE(wr));
+
+	RAM16X1D # (.INIT(16'h0000))
+	rfc(
+	.DPO(dout2[i]), // data out
+	.SPO(),
+	.A0(rno0[0]),   // R/W address, controls D and SPO
+	.A1(rno0[1]),
+	.A2(rno0[2]),
+	.A3(rno0[3]),
+	.D(din[i]),  // data in
+	.DPRA0(rno2[0]), // read-only adr, controls DPO
+	.DPRA1(rno2[1]),
+	.DPRA2(rno2[2]),
+	.DPRA3(rno2[3]),
+	.WCLK(clk),
+	.WE(wr));
+	end
+endgenerate
+endmodule

+ 1 - 1
BlackBox/Po/Files/Texts.Mod.txt

@@ -468,7 +468,7 @@ MODULE Texts; (*JG 21.11.90 / NW 11.7.90 / 24.12.95 / 22.11.10 / 18.11.2014 / 10
   END WriteHex;
 
  PROCEDURE WriteReal* (VAR W: Writer; x: REAL; n: INTEGER);
-    VAR e, i, m: INTEGER;
+    VAR e, i, k, m: INTEGER;
       d: ARRAY 16 OF CHAR;
   BEGIN e := ASR(ORD(x), 23) MOD 100H;  (*binary exponent*)
     IF e = 0 THEN

BIN
BlackBox/Po/Mod/ORB.odc


BIN
BlackBox/Po/Mod/ORB3.odc


BIN
BlackBox/Po/Mod/ORP.odc


BIN
BlackBox/Po/Mod/ORP3.odc


BIN
BlackBox/Po/Mod/Texts.odc


BIN
BlackBox/Po/Mod/Texts2.odc