| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668 |
- (*
- BSD 2-Clause License
- Copyright (c) 2020-2021, Anton Krotov
- All rights reserved.
- *)
- (*
- RVMxI executor and disassembler
- Usage:
- RVMxI.exe <program file> -run [program parameters]
- RVMxI.exe <program file> -dis <output file>
- *)
- MODULE RVMxI;
- IMPORT SYSTEM, File, Args, Out, API, HOST;
- CONST
- szWORD = HOST.bit_depth DIV 8;
- opSTOP = 0; opRET = 1; opENTER = 2; opNEG = 3; opNOT = 4; opNOP = 5;
- opXCHG = 6; opLDB = 7; opLDH = 8; opLDW = 9; opPUSH = 10; opPUSHC = 11;
- opPOP = 12; opLABEL = 13; opLEA = 14; opLLA = 15;
- opLDD = 16; (* 17, 18 *)
- opJMP = 19; opCALL = 20; opCALLI = 21;
- opMOV = 22; opMUL = 24; opADD = 26; opSUB = 28; opDIV = 30; opMOD = 32;
- opSTB = 34; opSTH = 36; opSTW = 38; opSTD = 40; (* 42, 44 *)
- opAND = 46; opOR = 48; opXOR = 50; opASR = 52; opLSR = 54;
- opLSL = 56; opROR = 58; (* 60, 62 *) opCMP = 64;
- opMOVC = 23; opMULC = 25; opADDC = 27; opSUBC = 29; opDIVC = 31; opMODC = 33;
- opSTBC = 35; opSTHC = 37; opSTWC = 39; opSTDC = 41; (* 43, 45 *)
- opANDC = 47; opORC = 49; opXORC = 51; opASRC = 53; opLSRC = 55;
- opLSLC = 57; opRORC = 59; (* 61, 63 *) opCMPC = 65;
- opBIT = 66; opSYSCALL = 67; opJBT = 68; opADDRC = 69;
- opJEQ = 70; opJNE = 71; opJLT = 72; opJGE = 73; opJGT = 74; opJLE = 75;
- opSEQ = 76; opSNE = 77; opSLT = 78; opSGE = 79; opSGT = 80; opSLE = 81;
- nREG = 16;
- ACC = 0; BP = 3; SP = 4;
- Types = 0;
- Strings = 1;
- Global = 2;
- Heap = 3;
- Stack = 4;
- TYPE
- COMMAND = POINTER TO RECORD
- op, param1, param2: INTEGER;
- next, prev: COMMAND
- END;
- LABELS = ARRAY 30000 OF COMMAND;
- SECTIONS = ARRAY 5 OF INTEGER;
- VAR
- Sections: SECTIONS;
- first, last: COMMAND;
- Labels: LABELS;
- F: INTEGER; buf: ARRAY 65536 OF BYTE; cnt: INTEGER;
- PROCEDURE syscall (ptr: INTEGER);
- VAR
- fn, r, n: INTEGER;
- proc2: PROCEDURE (a, b: INTEGER): INTEGER;
- proc3: PROCEDURE (a, b, c: INTEGER): INTEGER;
- proc4: PROCEDURE (a, b, c, d: INTEGER): INTEGER;
- r1, r2: REAL;
- PROCEDURE GetInt (ptr, n: INTEGER): INTEGER;
- BEGIN
- SYSTEM.GET(ptr + SYSTEM.SIZE(INTEGER) * n, n)
- RETURN n
- END GetInt;
- PROCEDURE GetReal (ptr, n: INTEGER): REAL;
- VAR
- r: REAL;
- BEGIN
- SYSTEM.GET(ptr + SYSTEM.SIZE(INTEGER) * n, r)
- RETURN r
- END GetReal;
- BEGIN
- fn := GetInt(ptr, 0);
- CASE fn OF
- | 0:
- HOST.ExitProcess(GetInt(ptr, 1))
- | 1:
- SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.GetCurrentDirectory));
- r := proc2(GetInt(ptr, 1), GetInt(ptr, 2))
- | 2:
- n := GetInt(ptr, 1);
- SYSTEM.PUT(SYSTEM.ADR(proc3), SYSTEM.ADR(HOST.GetArg));
- r := proc3(n - ORD(n = 0) + 2, GetInt(ptr, 2), GetInt(ptr, 3))
- | 3:
- SYSTEM.PUT(SYSTEM.ADR(proc4), SYSTEM.ADR(HOST.FileRead));
- SYSTEM.PUT(ptr, proc4(GetInt(ptr, 1), GetInt(ptr, 2), GetInt(ptr, 3), GetInt(ptr, 4)))
- | 4:
- SYSTEM.PUT(SYSTEM.ADR(proc4), SYSTEM.ADR(HOST.FileWrite));
- SYSTEM.PUT(ptr, proc4(GetInt(ptr, 1), GetInt(ptr, 2), GetInt(ptr, 3), GetInt(ptr, 4)))
- | 5:
- SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.FileCreate));
- SYSTEM.PUT(ptr, proc2(GetInt(ptr, 1), GetInt(ptr, 2)))
- | 6:
- HOST.FileClose(GetInt(ptr, 1))
- | 7:
- SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.FileOpen));
- SYSTEM.PUT(ptr, proc2(GetInt(ptr, 1), GetInt(ptr, 2)))
- | 8:
- HOST.OutChar(CHR(GetInt(ptr, 1)))
- | 9:
- SYSTEM.PUT(ptr, HOST.GetTickCount())
- |10:
- SYSTEM.PUT(ptr, HOST.UnixTime())
- |11:
- SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.isRelative));
- SYSTEM.PUT(ptr, proc2(GetInt(ptr, 1), GetInt(ptr, 2)))
- |12:
- SYSTEM.PUT(SYSTEM.ADR(proc2), SYSTEM.ADR(HOST.chmod));
- r := proc2(GetInt(ptr, 1), GetInt(ptr, 2))
- |100..103:
- r1 := GetReal(ptr, 1);
- r2 := GetReal(ptr, 2);
- CASE fn OF
- |100: SYSTEM.PUT(ptr, r2 * r1)
- |101: SYSTEM.PUT(ptr, r2 / r1)
- |102: SYSTEM.PUT(ptr, r2 + r1)
- |103: SYSTEM.PUT(ptr, r2 - r1)
- END
- |104:
- r1 := GetReal(ptr, 2);
- r2 := GetReal(ptr, 3);
- CASE GetInt(ptr, 1) OF
- |0: SYSTEM.PUT(ptr, ORD(r2 = r1))
- |1: SYSTEM.PUT(ptr, ORD(r2 # r1))
- |2: SYSTEM.PUT(ptr, ORD(r2 < r1))
- |3: SYSTEM.PUT(ptr, ORD(r2 <= r1))
- |4: SYSTEM.PUT(ptr, ORD(r2 > r1))
- |5: SYSTEM.PUT(ptr, ORD(r2 >= r1))
- END
- |105:
- SYSTEM.PUT(ptr, FLOOR(GetReal(ptr, 1)))
- |106:
- SYSTEM.PUT(ptr, FLT(GetInt(ptr, 1)))
- END
- END syscall;
- PROCEDURE exec (VAR Labels: LABELS; first, last: COMMAND; Sections: SECTIONS);
- VAR
- cmd: COMMAND;
- param1, param2, i: INTEGER;
- R: ARRAY nREG OF INTEGER;
- fe, fl, fb: BOOLEAN;
- BEGIN
- FOR i := 0 TO LEN(Labels) - 1 DO
- cmd := Labels[i];
- IF cmd # NIL THEN
- REPEAT
- cmd := cmd.next
- UNTIL cmd.op # opLABEL;
- Labels[i] := cmd
- END
- END;
- cmd := first;
- WHILE cmd # NIL DO
- IF cmd.op = opLABEL THEN
- cmd.prev.next := cmd.next;
- cmd.next.prev := cmd.prev
- END;
- cmd := cmd.next
- END;
- FOR i := 0 TO LEN(Labels) - 1 DO
- IF Labels[i] # NIL THEN
- Labels[i] := Labels[i].prev
- END
- END;
- cmd := first;
- WHILE cmd # NIL DO
- param1 := cmd.param1;
- param2 := cmd.param2;
- CASE cmd.op OF
- |opSTOP: cmd := last
- |opRET: SYSTEM.GET(R[SP], cmd); INC(R[SP], szWORD)
- |opENTER: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], R[BP]); R[BP] := R[SP];
- WHILE param1 > 0 DO DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], 0); DEC(param1) END
- |opPOP: SYSTEM.GET(R[SP], R[param1]); INC(R[SP], szWORD)
- |opPUSH: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], R[param1])
- |opPUSHC: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], param1)
- |opCALL: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], cmd); cmd := Labels[param1]
- |opCALLI: DEC(R[SP], szWORD); SYSTEM.PUT(R[SP], cmd); SYSTEM.GET(SYSTEM.ADR(R[param1]), cmd)
- |opNEG: R[param1] := -R[param1]
- |opNOT: R[param1] := ORD(-BITS(R[param1]))
- |opNOP:
- |opXCHG: i := R[param1]; R[param1] := R[param2]; R[param2] := i
- |opLDB: i := param1 MOD 256; SYSTEM.GET8(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 256
- |opLDH: i := param1 MOD 256; SYSTEM.GET16(R[param1 DIV 256] + param2, R[i]); R[i] := R[i] MOD 65536
- |opLDW: SYSTEM.GET32(R[param1 DIV 256] + param2, R[param1 MOD 256]);
- $IF (CPU_X8664)
- R[param1 MOD 256] := R[param1 MOD 256] MOD 100000000H
- $END
- |opLDD: SYSTEM.GET(R[param1 DIV 256] + param2, R[param1 MOD 256])
- |opLLA: SYSTEM.GET(SYSTEM.ADR(Labels[param2]), R[param1])
- |opJMP: cmd := Labels[param1]
- |opMOV: R[param1] := R[param2]
- |opMOVC: R[param1] := param2
- |opMUL: R[param1] := R[param1] * R[param2]
- |opMULC: R[param1] := R[param1] * param2
- |opADD: INC(R[param1], R[param2])
- |opADDC: INC(R[param1], param2)
- |opSUB: DEC(R[param1], R[param2])
- |opSUBC: DEC(R[param1], param2)
- |opDIV: R[param1] := R[param1] DIV R[param2]
- |opDIVC: R[param1] := R[param1] DIV param2
- |opMOD: R[param1] := R[param1] MOD R[param2]
- |opMODC: R[param1] := R[param1] MOD param2
- |opSTB: SYSTEM.PUT8(R[param1 DIV 256] + param2, R[param1 MOD 256])
- |opSTH: SYSTEM.PUT16(R[param1 DIV 256] + param2, R[param1 MOD 256])
- |opSTW: SYSTEM.PUT32(R[param1 DIV 256] + param2, R[param1 MOD 256])
- |opSTD: SYSTEM.PUT(R[param1 DIV 256] + param2, R[param1 MOD 256])
- |opSTBC: SYSTEM.PUT8(R[param1], param2)
- |opSTHC: SYSTEM.PUT16(R[param1], param2)
- |opSTWC: SYSTEM.PUT32(R[param1], param2)
- |opSTDC: SYSTEM.PUT(R[param1], param2)
- |opAND: R[param1] := ORD(BITS(R[param1]) * BITS(R[param2]))
- |opANDC: R[param1] := ORD(BITS(R[param1]) * BITS(param2))
- |opOR: R[param1] := ORD(BITS(R[param1]) + BITS(R[param2]))
- |opORC: R[param1] := ORD(BITS(R[param1]) + BITS(param2))
- |opXOR: R[param1] := ORD(BITS(R[param1]) / BITS(R[param2]))
- |opXORC: R[param1] := ORD(BITS(R[param1]) / BITS(param2))
- |opASR: R[param1] := ASR(R[param1], R[param2])
- |opASRC: R[param1] := ASR(R[param1], param2)
- |opLSR: R[param1] := LSR(R[param1], R[param2])
- |opLSRC: R[param1] := LSR(R[param1], param2)
- |opLSL: R[param1] := LSL(R[param1], R[param2])
- |opLSLC: R[param1] := LSL(R[param1], param2)
- |opROR: R[param1] := ROR(R[param1], R[param2])
- |opRORC: R[param1] := ROR(R[param1], param2)
- |opLEA: R[param1 MOD 256] := Sections[param1 DIV 256] + param2
- (*|opLABEL:*)
- |opSYSCALL: syscall(R[param1])
- |opADDRC: R[param1 MOD 256] := R[param1 DIV 256] + param2
- |opCMP: fl := R[param1] < R[param2]; fe := R[param1] = R[param2]; fb := fl & (R[param1] >= 0)
- |opCMPC: fl := R[param1] < param2; fe := R[param1] = param2; fb := fl & (R[param1] >= 0)
- |opJEQ: IF fe THEN cmd := Labels[param1] END
- |opJNE: IF ~fe THEN cmd := Labels[param1] END
- |opJLT: IF fl THEN cmd := Labels[param1] END
- |opJLE: IF fl OR fe THEN cmd := Labels[param1] END
- |opJGT: IF ~fl & ~fe THEN cmd := Labels[param1] END
- |opJGE: IF ~fl THEN cmd := Labels[param1] END
- |opSEQ: R[param1] := ORD(fe)
- |opSNE: R[param1] := ORD(~fe)
- |opSLT: R[param1] := ORD(fl)
- |opSLE: R[param1] := ORD(fl OR fe)
- |opSGT: R[param1] := ORD(~fl & ~fe)
- |opSGE: R[param1] := ORD(~fl)
- |opJBT: IF fb THEN cmd := Labels[param1] END
- |opBIT: R[param1] := ORD({R[param2]})
- END;
- cmd := cmd.next
- END
- END exec;
- PROCEDURE disasm (name: ARRAY OF CHAR; t_count, c_count, glob, heap: INTEGER);
- VAR
- cmd: COMMAND;
- param1, param2, i, t, ptr: INTEGER;
- b: BYTE;
- Names: ARRAY 5, 16 OF CHAR;
- PROCEDURE String (s: ARRAY OF CHAR);
- VAR
- n: INTEGER;
- BEGIN
- n := LENGTH(s);
- IF n > LEN(buf) - cnt THEN
- ASSERT(File.Write(F, SYSTEM.ADR(buf[0]), cnt) = cnt);
- cnt := 0
- END;
- SYSTEM.MOVE(SYSTEM.ADR(s[0]), SYSTEM.ADR(buf[0]) + cnt, n);
- INC(cnt, n)
- END String;
- PROCEDURE Ln;
- BEGIN
- String(0DX + 0AX)
- END Ln;
- PROCEDURE hexdgt (n: INTEGER): CHAR;
- BEGIN
- IF n < 10 THEN
- INC(n, ORD("0"))
- ELSE
- INC(n, ORD("A") - 10)
- END
- RETURN CHR(n)
- END hexdgt;
- PROCEDURE Hex (x: INTEGER);
- VAR
- str: ARRAY 19 OF CHAR;
- n: INTEGER;
- BEGIN
- n := szWORD * 2 + 2;
- str[n] := 0X;
- WHILE n > 2 DO
- str[n - 1] := hexdgt(x MOD 16);
- x := x DIV 16;
- DEC(n)
- END;
- str[1] := "x";
- str[0] := "0";
- String(str)
- END Hex;
- PROCEDURE Byte (x: BYTE);
- VAR
- str: ARRAY 5 OF CHAR;
- BEGIN
- str[4] := 0X;
- str[3] := hexdgt(x MOD 16);
- str[2] := hexdgt(x DIV 16);
- str[1] := "x";
- str[0] := "0";
- String(str)
- END Byte;
- PROCEDURE Reg (n: INTEGER);
- VAR
- s: ARRAY 2 OF CHAR;
- BEGIN
- IF n = BP THEN
- String("BP")
- ELSIF n = SP THEN
- String("SP")
- ELSE
- String("R");
- s[1] := 0X;
- IF n >= 10 THEN
- s[0] := CHR(n DIV 10 + ORD("0"));
- String(s)
- END;
- s[0] := CHR(n MOD 10 + ORD("0"));
- String(s)
- END
- END Reg;
- PROCEDURE Reg2 (r1, r2: INTEGER);
- BEGIN
- Reg(r1); String(", "); Reg(r2)
- END Reg2;
- PROCEDURE RegC (r, c: INTEGER);
- BEGIN
- Reg(r); String(", "); Hex(c)
- END RegC;
- PROCEDURE RegL (r, label: INTEGER);
- BEGIN
- Reg(r); String(", L"); Hex(label)
- END RegL;
- BEGIN
- Names[Types] := "TYPES";
- Names[Strings] := "STRINGS";
- Names[Global] := "GLOBAL";
- Names[Heap] := "HEAP";
- Names[Stack] := "STACK";
- F := File.Create(name);
- ASSERT(F > 0);
- cnt := 0;
- String("CODE:"); Ln;
- cmd := first;
- WHILE cmd # NIL DO
- param1 := cmd.param1;
- param2 := cmd.param2;
- CASE cmd.op OF
- |opSTOP: String("STOP")
- |opRET: String("RET")
- |opENTER: String("ENTER "); Hex(param1)
- |opPOP: String("POP "); Reg(param1)
- |opNEG: String("NEG "); Reg(param1)
- |opNOT: String("NOT "); Reg(param1)
- |opNOP: String("NOP")
- |opXCHG: String("XCHG "); Reg2(param1, param2)
- |opLDB: String("LDB "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
- |opLDH: String("LDH "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
- |opLDW: String("LDW "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
- |opLDD: String("LDD "); Reg(param1 MOD 256); String(", ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("]")
- |opPUSH: String("PUSH "); Reg(param1)
- |opPUSHC: String("PUSH "); Hex(param1)
- |opLLA: String("LLA "); RegL(param1, param2)
- |opJMP: String("JMP L"); Hex(param1)
- |opCALL: String("CALL L"); Hex(param1)
- |opCALLI: String("CALL "); Reg(param1)
- |opMOV: String("MOV "); Reg2(param1, param2)
- |opMOVC: String("MOV "); RegC(param1, param2)
- |opMUL: String("MUL "); Reg2(param1, param2)
- |opMULC: String("MUL "); RegC(param1, param2)
- |opADD: String("ADD "); Reg2(param1, param2)
- |opADDC: String("ADD "); RegC(param1, param2)
- |opSUB: String("SUB "); Reg2(param1, param2)
- |opSUBC: String("SUB "); RegC(param1, param2)
- |opDIV: String("DIV "); Reg2(param1, param2)
- |opDIVC: String("DIV "); RegC(param1, param2)
- |opMOD: String("MOD "); Reg2(param1, param2)
- |opMODC: String("MOD "); RegC(param1, param2)
- |opSTB: String("STB ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
- |opSTH: String("STH ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
- |opSTW: String("STW ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
- |opSTD: String("STD ["); Reg(param1 DIV 256); String(" + "); Hex(param2); String("], "); Reg(param1 MOD 256)
- |opSTBC: String("STB ["); Reg(param1); String("], "); Hex(param2)
- |opSTHC: String("STH ["); Reg(param1); String("], "); Hex(param2)
- |opSTWC: String("STW ["); Reg(param1); String("], "); Hex(param2)
- |opSTDC: String("STD ["); Reg(param1); String("], "); Hex(param2)
- |opAND: String("AND "); Reg2(param1, param2)
- |opANDC: String("AND "); RegC(param1, param2)
- |opOR: String("OR "); Reg2(param1, param2)
- |opORC: String("OR "); RegC(param1, param2)
- |opXOR: String("XOR "); Reg2(param1, param2)
- |opXORC: String("XOR "); RegC(param1, param2)
- |opASR: String("ASR "); Reg2(param1, param2)
- |opASRC: String("ASR "); RegC(param1, param2)
- |opLSR: String("LSR "); Reg2(param1, param2)
- |opLSRC: String("LSR "); RegC(param1, param2)
- |opLSL: String("LSL "); Reg2(param1, param2)
- |opLSLC: String("LSL "); RegC(param1, param2)
- |opROR: String("ROR "); Reg2(param1, param2)
- |opRORC: String("ROR "); RegC(param1, param2)
- |opLEA: String("LEA "); Reg(param1 MOD 256); String(", "); String(Names[param1 DIV 256]); String(" + "); Hex(param2)
- |opADDRC: String("ADD "); Reg(param1 MOD 256); String(", "); Reg(param1 DIV 256); String(", "); Hex(param2)
- |opLABEL: String("L"); Hex(param1); String(":")
- |opSYSCALL: String("SYSCALL "); Reg(param1)
- |opCMP: String("CMP "); Reg2(param1, param2)
- |opCMPC: String("CMP "); RegC(param1, param2)
- |opJEQ: String("JEQ L"); Hex(param1)
- |opJNE: String("JNE L"); Hex(param1)
- |opJLT: String("JLT L"); Hex(param1)
- |opJLE: String("JLE L"); Hex(param1)
- |opJGT: String("JGT L"); Hex(param1)
- |opJGE: String("JGE L"); Hex(param1)
- |opSEQ: String("SEQ "); Reg(param1)
- |opSNE: String("SNE "); Reg(param1)
- |opSLT: String("SLT "); Reg(param1)
- |opSLE: String("SLE "); Reg(param1)
- |opSGT: String("SGT "); Reg(param1)
- |opSGE: String("SGE "); Reg(param1)
- |opJBT: String("JBT L"); Hex(param1)
- |opBIT: String("BIT "); Reg2(param1, param2)
- END;
- Ln;
- cmd := cmd.next
- END;
- String("TYPES:");
- ptr := Sections[Types];
- FOR i := 0 TO t_count - 1 DO
- IF i MOD 4 = 0 THEN
- Ln; String("WORD ")
- ELSE
- String(", ")
- END;
- SYSTEM.GET(ptr, t); INC(ptr, szWORD);
- Hex(t)
- END;
- Ln;
- String("STRINGS:");
- ptr := Sections[Strings];
- FOR i := 0 TO c_count - 1 DO
- IF i MOD 8 = 0 THEN
- Ln; String("BYTE ")
- ELSE
- String(", ")
- END;
- SYSTEM.GET8(ptr, b); INC(ptr);
- Byte(b)
- END;
- Ln;
- String("GLOBAL:"); Ln;
- String("WORDS "); Hex(glob); Ln;
- String("HEAP:"); Ln;
- String("WORDS "); Hex(heap); Ln;
- String("STACK:"); Ln;
- String("WORDS 8"); Ln;
- ASSERT(File.Write(F, SYSTEM.ADR(buf[0]), cnt) = cnt);
- File.Close(F)
- END disasm;
- PROCEDURE GetCommand (adr: INTEGER): COMMAND;
- VAR
- op, param1, param2: INTEGER;
- res: COMMAND;
- BEGIN
- op := 0; param1 := 0; param2 := 0;
- SYSTEM.GET(adr, op);
- SYSTEM.GET(adr + szWORD, param1);
- SYSTEM.GET(adr + szWORD * 2, param2);
- NEW(res);
- res.op := op;
- res.param1 := param1;
- res.param2 := param2;
- res.next := NIL
- RETURN res
- END GetCommand;
- PROCEDURE main;
- VAR
- name, param: ARRAY 1024 OF CHAR;
- cmd: COMMAND;
- file, fsize, n: INTEGER;
- descr: ARRAY 12 OF INTEGER;
- offTypes, offStrings, GlobalSize, HeapStackSize, DescrSize: INTEGER;
- BEGIN
- Out.Open;
- Args.GetArg(1, name);
- F := File.Open(name, File.OPEN_R);
- IF F > 0 THEN
- DescrSize := LEN(descr) * SYSTEM.SIZE(INTEGER);
- fsize := File.Seek(F, 0, File.SEEK_END);
- ASSERT(fsize > DescrSize);
- file := API._NEW(fsize);
- ASSERT(file # 0);
- n := File.Seek(F, 0, File.SEEK_BEG);
- ASSERT(fsize = File.Read(F, file, fsize));
- File.Close(F);
- SYSTEM.MOVE(file + fsize - DescrSize, SYSTEM.ADR(descr[0]), DescrSize);
- offTypes := descr[0];
- ASSERT(offTypes < fsize - DescrSize);
- ASSERT(offTypes > 0);
- ASSERT(offTypes MOD (3 * szWORD) = 0);
- offStrings := descr[1];
- ASSERT(offStrings < fsize - DescrSize);
- ASSERT(offStrings > 0);
- ASSERT(offStrings MOD szWORD = 0);
- ASSERT(offStrings > offTypes);
- GlobalSize := descr[2];
- ASSERT(GlobalSize > 0);
- HeapStackSize := descr[3];
- ASSERT(HeapStackSize > 0);
- Sections[Types] := API._NEW(offStrings - offTypes);
- ASSERT(Sections[Types] # 0);
- SYSTEM.MOVE(file + offTypes, Sections[Types], offStrings - offTypes);
- Sections[Strings] := API._NEW(fsize - offStrings - DescrSize);
- ASSERT(Sections[Strings] # 0);
- SYSTEM.MOVE(file + offStrings, Sections[Strings], fsize - offStrings - DescrSize);
- Sections[Global] := API._NEW(GlobalSize * szWORD);
- ASSERT(Sections[Global] # 0);
- Sections[Heap] := API._NEW(HeapStackSize * szWORD);
- ASSERT(Sections[Heap] # 0);
- Sections[Stack] := Sections[Heap] + HeapStackSize * szWORD - szWORD*8;
- n := offTypes DIV (3 * szWORD);
- first := GetCommand(file + offTypes - n * (3 * szWORD));
- first.prev := NIL;
- last := first;
- DEC(n);
- WHILE n > 0 DO
- cmd := GetCommand(file + offTypes - n * (3 * szWORD));
- IF cmd.op = opLABEL THEN
- Labels[cmd.param1] := cmd
- END;
- last.next := cmd;
- cmd.prev := last;
- last := cmd;
- DEC(n)
- END;
- file := API._DISPOSE(file);
- Args.GetArg(2, param);
- IF param = "-dis" THEN
- Args.GetArg(3, name);
- IF name # "" THEN
- disasm(name, (offStrings - offTypes) DIV szWORD, fsize - offStrings - DescrSize, GlobalSize, HeapStackSize)
- END
- ELSIF param = "-run" THEN
- exec(Labels, first, last, Sections)
- END
- ELSE
- Out.String("file not found"); Out.Ln
- END
- END main;
- BEGIN
- main
- END RVMxI.
|