improved risc crosscompiler, added example and readme.

This commit is contained in:
Norayr Chilingarian 2014-09-15 22:14:08 +04:00
parent 1acddf0fb9
commit c2b91243e9
12 changed files with 298 additions and 13 deletions

View file

@ -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);*)

251
src/voc07R/ORTool.Mod Normal file
View file

@ -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.

View file

@ -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;

BIN
src/voc07R/Oberon10.Scn.Fnt Normal file

Binary file not shown.

29
src/voc07R/README.md Normal file
View file

@ -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.

View file

@ -1,10 +0,0 @@
MODULE test;
VAR b : BOOLEAN;
i : INTEGER;
BEGIN
b := FALSE;
i := ORD(b);
END test.

BIN
src/voc07R/test/Oberon.rsc Normal file

Binary file not shown.

BIN
src/voc07R/test/Oberon.smb Normal file

Binary file not shown.

BIN
src/voc07R/test/Test.Mod Normal file

Binary file not shown.

BIN
src/voc07R/test/Texts.rsc Normal file

Binary file not shown.

BIN
src/voc07R/test/Texts.smb Normal file

Binary file not shown.

3
src/voc07R/test/readme Normal file
View file

@ -0,0 +1,3 @@
put ORP binary here and run
> ./ORP Test.Mod