diff --git a/src/voc07R/CompatTexts.Mod b/src/voc07R/CompatTexts.Mod index f94b3151..62b9073a 100644 --- a/src/voc07R/CompatTexts.Mod +++ b/src/voc07R/CompatTexts.Mod @@ -167,12 +167,16 @@ MODULE CompatTexts; (*JG 21.11.90 / NW 11.7.90 / 24.12.95 / 22.11.10 / 26.3.2014 rlen := rlen + q.len; q := q.next END; (*Dict[N] := p.fnt.name;*) - COPY(p.fnt.name, Dict[N]); (* voc adaptation by noch *) + IF p.fnt # NIL THEN COPY(p.fnt.name, Dict[N]) END; (* voc adaptation by noch *) n := 1; - WHILE Dict[n] # p.fnt.name DO INC(n) END; + IF p.fnt # NIL THEN (* voc adaptation by noch *) + WHILE Dict[n] # p.fnt.name DO INC(n) END; + END; (*Files.WriteByte(W, n);*) Files.WriteByte(W, SHORT(SHORT(n))); (* voc adaptation by noch *) - IF n = N THEN Files.WriteString(W, p.fnt.name); INC(N) END; + IF p.fnt # NIL THEN (* voc adaptation by noch *) + IF n = N THEN Files.WriteString(W, p.fnt.name); INC(N) END; + END; (*Files.WriteByte(W, p.col);*) Files.WriteByte(W, SHORT(SHORT(p.col))); (* voc adaptation by noch *) (*Files.WriteByte(W, p.voff);*) diff --git a/src/voc07R/ORTool.Mod b/src/voc07R/ORTool.Mod new file mode 100644 index 00000000..3c3f9411 --- /dev/null +++ b/src/voc07R/ORTool.Mod @@ -0,0 +1,251 @@ +MODULE ORTool; (*NW 18.2.2013*) + IMPORT SYSTEM, Files, Texts, Oberon, ORB; + VAR W: Texts.Writer; + Form: INTEGER; (*result of ReadType*) + mnemo0, mnemo1: ARRAY 16, 4 OF CHAR; (*mnemonics*) + + PROCEDURE Read(VAR R: Files.Rider; VAR n: INTEGER); + VAR b: BYTE; + BEGIN Files.ReadByte(R, b); + IF b < 80H THEN n := b ELSE n := b - 100H END + END Read; + + PROCEDURE ReadType(VAR R: Files.Rider); + VAR key, len, lev, size, off: INTEGER; + ref, mno, class, form, readonly: INTEGER; + name, modname: ARRAY 32 OF CHAR; + BEGIN Read(R, ref); Texts.Write(W, " "); Texts.Write(W, "["); + IF ref < 0 THEN Texts.Write(W, "^"); Texts.WriteInt(W, -ref, 1) + ELSE Texts.WriteInt(W, ref, 1); + Read(R, form); Texts.WriteString(W, " form = "); Texts.WriteInt(W, form, 1); + IF form = ORB.Pointer THEN ReadType(R) + ELSIF form = ORB.Array THEN + ReadType(R); Files.ReadNum(R, len); Files.ReadNum(R, size); + Texts.WriteString(W, " len = "); Texts.WriteInt(W, len, 1); + Texts.WriteString(W, " size = "); Texts.WriteInt(W, size, 1) + ELSIF form = ORB.Record THEN + ReadType(R); (*base type*) + Files.ReadNum(R, off); Texts.WriteString(W, " exno = "); Texts.WriteInt(W, off, 1); + Files.ReadNum(R, off); Texts.WriteString(W, " extlev = "); Texts.WriteInt(W, off, 1); + Files.ReadNum(R, size); Texts.WriteString(W, " size = "); Texts.WriteInt(W, size, 1); + Texts.Write(W, " "); Texts.Write(W, "{"); Read(R, class); + WHILE class # 0 DO (*fields*) + Files.ReadString(R, name); + IF name[0] # 0X THEN Texts.Write(W, " "); Texts.WriteString(W, name); ReadType(R) + ELSE Texts.WriteString(W, " --") + END ; + Files.ReadNum(R, off); Texts.WriteInt(W, off, 4); Read(R, class) + END ; + Texts.Write(W, "}") + ELSIF form = ORB.Proc THEN + ReadType(R); Texts.Write(W, "("); Read(R, class); + WHILE class # 0 DO + Texts.WriteString(W, " class = "); Texts.WriteInt(W, class, 1); Read(R, readonly); + IF readonly = 1 THEN Texts.Write(W, "#") END ; + ReadType(R); Read(R, class) + END ; + Texts.Write(W, ")") + END ; + Files.ReadString(R, modname); + IF modname[0] # 0X THEN + Files.ReadInt(R, key); Files.ReadString(R, name); + Texts.Write(W, " "); Texts.WriteString(W, modname); Texts.Write(W, "."); Texts.WriteString(W, name); + Texts.WriteHex(W, key) + END + END ; + Form := form; Texts.Write(W, "]") + END ReadType; + + PROCEDURE DecSym*; (*decode symbol file*) + VAR class, typno, k: INTEGER; + name: ARRAY 32 OF CHAR; + F: Files.File; R: Files.Rider; + S: Texts.Scanner; + BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); + IF S.class = Texts.Name THEN + Texts.WriteString(W, "OR-decode "); Texts.WriteString(W, S.s); + Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); + F := Files.Old(S.s); + IF F # NIL THEN + Files.Set(R, F, 0); Files.ReadInt(R, k); Files.ReadInt(R, k); + Files.ReadString(R, name); Texts.WriteString(W, name); Texts.WriteHex(W, k); + Read(R, class); Texts.WriteInt(W, class, 3); (*sym file version*) + IF class = ORB.versionkey THEN + Texts.WriteLn(W); Read(R, class); + WHILE class # 0 DO + Texts.WriteInt(W, class, 4); Files.ReadString(R, name); Texts.Write(W, " "); Texts.WriteString(W, name); + ReadType(R); + IF class = ORB.Typ THEN + Texts.Write(W, "("); Read(R, class); + WHILE class # 0 DO (*pointer base fixup*) + Texts.WriteString(W, " ->"); Texts.WriteInt(W, class, 4); Read(R, class) + END ; + Texts.Write(W, ")") + ELSIF (class = ORB.Const) OR (class = ORB.Var) THEN + Files.ReadNum(R, k); Texts.WriteInt(W, k, 5); (*Reals, Strings!*) + END ; + Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); + Read(R, class) + END + ELSE Texts.WriteString(W, " bad symfile version") + END + ELSE Texts.WriteString(W, " not found") + END ; + Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf) + END + END DecSym; + +(* ---------------------------------------------------*) + + PROCEDURE WriteReg(r: LONGINT); + BEGIN Texts.Write(W, " "); + IF r < 12 THEN Texts.WriteString(W, " R"); Texts.WriteInt(W, r MOD 10H, 1) + ELSIF r = 12 THEN Texts.WriteString(W, "MT") + ELSIF r = 13 THEN Texts.WriteString(W, "SB") + ELSIF r = 14 THEN Texts.WriteString(W, "SP") + ELSE Texts.WriteString(W, "LNK") + END + END WriteReg; + + PROCEDURE opcode(w: LONGINT); + VAR k, op, u, a, b, c: LONGINT; + BEGIN + k := w DIV 40000000H MOD 4; + a := w DIV 1000000H MOD 10H; + b := w DIV 100000H MOD 10H; + op := w DIV 10000H MOD 10H; + u := w DIV 20000000H MOD 2; + IF k = 0 THEN + Texts.WriteString(W, mnemo0[op]); + IF u = 1 THEN Texts.Write(W, "'") END ; + WriteReg(a); WriteReg(b); WriteReg(w MOD 10H) + ELSIF k = 1 THEN + Texts.WriteString(W, mnemo0[op]); + IF u = 1 THEN Texts.Write(W, "'") END ; + WriteReg(a); WriteReg(b); w := w MOD 10000H; + IF w >= 8000H THEN w := w - 10000H END ; + Texts.WriteInt(W, w, 7) + ELSIF k = 2 THEN (*LDR/STR*) + IF u = 1 THEN Texts.WriteString(W, "STR ") ELSE Texts.WriteString(W, "LDR") END ; + WriteReg(a); WriteReg(b); w := w MOD 100000H; + IF w >= 80000H THEN w := w - 100000H END ; + Texts.WriteInt(W, w, 8) + ELSIF k = 3 THEN (*Branch instr*) + Texts.Write(W, "B"); + IF ODD(w DIV 10000000H) THEN Texts.Write(W, "L") END ; + Texts.WriteString(W, mnemo1[a]); + IF u = 0 THEN WriteReg(w MOD 10H) ELSE + w := w MOD 100000H; + IF w >= 80000H THEN w := w - 100000H END ; + Texts.WriteInt(W, w, 8) + END + END + END opcode; + + PROCEDURE Sync(VAR R: Files.Rider); + VAR ch: CHAR; + BEGIN Files.Read(R, ch); Texts.WriteString(W, "Sync "); Texts.Write(W, ch); Texts.WriteLn(W) + END Sync; + + PROCEDURE Write(VAR R: Files.Rider; x: INTEGER); + BEGIN Files.WriteByte(R, x) (* -128 <= x < 128 *) + END Write; + + PROCEDURE DecObj*; (*decode object file*) + VAR class, i, n, key, size, fix, adr, data, len: INTEGER; + ch: CHAR; + name: ARRAY 32 OF CHAR; + F: Files.File; R: Files.Rider; + S: Texts.Scanner; + BEGIN Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S); + IF S.class = Texts.Name THEN + Texts.WriteString(W, "decode "); Texts.WriteString(W, S.s); F := Files.Old(S.s); + IF F # NIL THEN + Files.Set(R, F, 0); Files.ReadString(R, name); Texts.WriteLn(W); Texts.WriteString(W, name); + Files.ReadInt(R, key); Texts.WriteHex(W, key); Read(R, class); Texts.WriteInt(W, class, 4); (*version*) + Files.ReadInt(R, size); Texts.WriteInt(W, size, 6); Texts.WriteLn(W); + Texts.WriteString(W, "imports:"); Texts.WriteLn(W); Files.ReadString(R, name); + WHILE name[0] # 0X DO + Texts.Write(W, 9X); Texts.WriteString(W, name); + Files.ReadInt(R, key); Texts.WriteHex(W, key); Texts.WriteLn(W); + Files.ReadString(R, name) + END ; + (* Sync(R); *) + Texts.WriteString(W, "type descriptors"); Texts.WriteLn(W); + Files.ReadInt(R, n); n := n DIV 4; i := 0; + WHILE i < n DO Files.ReadInt(R, data); Texts.WriteHex(W, data); INC(i) END ; + Texts.WriteLn(W); + Texts.WriteString(W, "data"); Files.ReadInt(R, data); Texts.WriteInt(W, data, 6); Texts.WriteLn(W); + Texts.WriteString(W, "strings"); Texts.WriteLn(W); + Files.ReadInt(R, n); i := 0; + WHILE i < n DO Files.Read(R, ch); Texts.Write(W, ch); INC(i) END ; + Texts.WriteLn(W); + Texts.WriteString(W, "code"); Texts.WriteLn(W); + Files.ReadInt(R, n); i := 0; + WHILE i < n DO + Files.ReadInt(R, data); Texts.WriteInt(W, i, 4); Texts.Write(W, 9X); Texts.WriteHex(W, data); + Texts.Write(W, 9X); opcode(data); Texts.WriteLn(W); INC(i) + END ; + (* Sync(R); *) + Texts.WriteString(W, "commands:"); Texts.WriteLn(W); + Files.ReadString(R, name); + WHILE name[0] # 0X DO + Texts.Write(W, 9X); Texts.WriteString(W, name); + Files.ReadInt(R, adr); Texts.WriteInt(W, adr, 5); Texts.WriteLn(W); + Files.ReadString(R, name) + END ; + (* Sync(R); *) + Texts.WriteString(W, "entries"); Texts.WriteLn(W); + Files.ReadInt(R, n); i := 0; + WHILE i < n DO + Files.ReadInt(R, adr); Texts.WriteInt(W, adr, 6); INC(i) + END ; + Texts.WriteLn(W); + (* Sync(R); *) + Texts.WriteString(W, "pointer refs"); Texts.WriteLn(W); Files.ReadInt(R, adr); + WHILE adr # -1 DO Texts.WriteInt(W, adr, 6); Files.ReadInt(R, adr) END ; + Texts.WriteLn(W); + (* Sync(R); *) + Files.ReadInt(R, data); Texts.WriteString(W, "fixP = "); Texts.WriteInt(W, data, 8); Texts.WriteLn(W); + Files.ReadInt(R, data); Texts.WriteString(W, "fixD = "); Texts.WriteInt(W, data, 8); Texts.WriteLn(W); + Files.ReadInt(R, data); Texts.WriteString(W, "fixT = "); Texts.WriteInt(W, data, 8); Texts.WriteLn(W); + Files.ReadInt(R, data); Texts.WriteString(W, "entry = "); Texts.WriteInt(W, data, 8); Texts.WriteLn(W); + Files.Read(R, ch); + IF ch # "O" THEN Texts.WriteString(W, "format eror"); Texts.WriteLn(W) END + (* Sync(R); *) + ELSE Texts.WriteString(W, " not found"); Texts.WriteLn(W) + END ; + Texts.Append(Oberon.Log, W.buf) + END + END DecObj; + +BEGIN Texts.OpenWriter(W); Texts.WriteString(W, "ORTool 18.2.2013"); + Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf); + mnemo0[0] := "MOV"; + mnemo0[1] := "LSL"; + mnemo0[2] := "ASR"; + mnemo0[3] := "ROR"; + mnemo0[4] := "AND"; + mnemo0[5] := "ANN"; + mnemo0[6] := "IOR"; + mnemo0[7] := "XOR"; + mnemo0[8] := "ADD"; + mnemo0[9] := "SUB"; + mnemo0[10] := "MUL"; + mnemo0[11] := "DIV"; + mnemo0[12] := "FAD"; + mnemo0[13] := "FSB"; + mnemo0[14] := "FML"; + mnemo0[15] := "FDV"; + mnemo1[0] := "MI "; + mnemo1[8] := "PL"; + mnemo1[1] := "EQ "; + mnemo1[9] := "NE "; + mnemo1[2] := "LS "; + mnemo1[10] := "HI "; + mnemo1[5] := "LT "; + mnemo1[13] := "GE "; + mnemo1[6] := "LE "; + mnemo1[14] := "GT "; + mnemo1[15] := "NO "; +END ORTool. diff --git a/src/voc07R/Oberon.Mod b/src/voc07R/Oberon.Mod index 736d664c..b2da7dee 100644 --- a/src/voc07R/Oberon.Mod +++ b/src/voc07R/Oberon.Mod @@ -1,5 +1,12 @@ MODULE Oberon; +(* this module emulates Oberon.Log and Oberon.Par in order to pass agruments to Oberon programs, as it's in Oberon environment; + it creates Oberon.Par from command line arguments; + procedure Dump dumps Oberon.Log to standard output. + + -- noch *) + +(* Files are commented out, because it's not necessary for work, but can be very useful for debug. See WriteTextToFile procedure; -- noch *) IMPORT Args, Strings, Texts := CompatTexts, (*Files := CompatFiles,*) Out := Console; VAR Log*: Texts.Text; @@ -34,6 +41,7 @@ BEGIN WHILE i < Args.argc DO Args.Get(i, opt); Strings.Append(opt, opts);(* Strings.Append (" ", opts);*) + (* ORP calls Texts.Scan, which returns filename, and nextCh would be set to " " if we append here " ". However after that ORP will check nextCh, and if it finds that nextCh is not "/" it's not gonna parse options. That's why Strings.Append is commented out; -- noch *) INC(i) END; diff --git a/src/voc07R/Oberon10.Scn.Fnt b/src/voc07R/Oberon10.Scn.Fnt new file mode 100644 index 00000000..15f99921 Binary files /dev/null and b/src/voc07R/Oberon10.Scn.Fnt differ diff --git a/src/voc07R/README.md b/src/voc07R/README.md new file mode 100644 index 00000000..6b4cf474 --- /dev/null +++ b/src/voc07R/README.md @@ -0,0 +1,29 @@ + +RISC crosscompiler +================== + +This is a version of re re revised Oberon compiler for Wirth's RISC machine which can be compiled and run with VOC (Vishap Oberon Compiler) on supported platforms. + +Files generated can be transferred to RISC machine or emulator and be run there. + +Compile +======= + +If you have vishap oberon compiler installed, just type +>make + +Run +=== + +>./ORP test.Mod /s + +like that. + +you may need symbol (.smb) files from RISC Oberon system in order to write programs that import some modules. + +some answers +============ + +- why Oberon10.Scn.Fnt ? +- it's actually not really necessary. because Texts are patched (test for NIL) to not crash if this file does not exist. however, unless I remove dependency from Fonts.Mod I have decided to keep this file here, and thus my added test for NIL is not necessary, and generated output file is completely correct Oberon Text file. Otherwise it would not contain the font name, for instance. + diff --git a/src/voc07R/test.Mod b/src/voc07R/test.Mod deleted file mode 100644 index d97a7e52..00000000 --- a/src/voc07R/test.Mod +++ /dev/null @@ -1,10 +0,0 @@ -MODULE test; -VAR b : BOOLEAN; -i : INTEGER; -BEGIN -b := FALSE; -i := ORD(b); - -END test. - - diff --git a/src/voc07R/test/Oberon.rsc b/src/voc07R/test/Oberon.rsc new file mode 100644 index 00000000..d0e49fa8 Binary files /dev/null and b/src/voc07R/test/Oberon.rsc differ diff --git a/src/voc07R/test/Oberon.smb b/src/voc07R/test/Oberon.smb new file mode 100644 index 00000000..148bd414 Binary files /dev/null and b/src/voc07R/test/Oberon.smb differ diff --git a/src/voc07R/test/Test.Mod b/src/voc07R/test/Test.Mod new file mode 100644 index 00000000..34c85704 Binary files /dev/null and b/src/voc07R/test/Test.Mod differ diff --git a/src/voc07R/test/Texts.rsc b/src/voc07R/test/Texts.rsc new file mode 100644 index 00000000..a1d32e38 Binary files /dev/null and b/src/voc07R/test/Texts.rsc differ diff --git a/src/voc07R/test/Texts.smb b/src/voc07R/test/Texts.smb new file mode 100644 index 00000000..9c97e0d9 Binary files /dev/null and b/src/voc07R/test/Texts.smb differ diff --git a/src/voc07R/test/readme b/src/voc07R/test/readme new file mode 100644 index 00000000..9108c517 --- /dev/null +++ b/src/voc07R/test/readme @@ -0,0 +1,3 @@ +put ORP binary here and run + +> ./ORP Test.Mod