mirror of
https://github.com/vishapoberon/compiler.git
synced 2026-04-05 23:22:25 +00:00
improved risc crosscompiler, added example and readme.
This commit is contained in:
parent
1acddf0fb9
commit
c2b91243e9
12 changed files with 298 additions and 13 deletions
|
|
@ -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
251
src/voc07R/ORTool.Mod
Normal 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.
|
||||
|
|
@ -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
BIN
src/voc07R/Oberon10.Scn.Fnt
Normal file
Binary file not shown.
29
src/voc07R/README.md
Normal file
29
src/voc07R/README.md
Normal 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.
|
||||
|
||||
|
|
@ -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
BIN
src/voc07R/test/Oberon.rsc
Normal file
Binary file not shown.
BIN
src/voc07R/test/Oberon.smb
Normal file
BIN
src/voc07R/test/Oberon.smb
Normal file
Binary file not shown.
BIN
src/voc07R/test/Test.Mod
Normal file
BIN
src/voc07R/test/Test.Mod
Normal file
Binary file not shown.
BIN
src/voc07R/test/Texts.rsc
Normal file
BIN
src/voc07R/test/Texts.rsc
Normal file
Binary file not shown.
BIN
src/voc07R/test/Texts.smb
Normal file
BIN
src/voc07R/test/Texts.smb
Normal file
Binary file not shown.
3
src/voc07R/test/readme
Normal file
3
src/voc07R/test/readme
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
put ORP binary here and run
|
||||
|
||||
> ./ORP Test.Mod
|
||||
Loading…
Add table
Add a link
Reference in a new issue