-
Notifications
You must be signed in to change notification settings - Fork 1
/
RISC.Mod
80 lines (76 loc) · 3.23 KB
/
RISC.Mod
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
MODULE RISC; (*NW 22.9.07 / 1.11.2013*)
IMPORT SYSTEM, Texts, Oberon;
CONST
MOV = 0; LSL = 1; ASR = 2; ROR = 3; AND = 4; ANN = 5; IOR = 6; XOR = 7;
ADD = 8; SUB = 9; MUL = 10; Div = 11;
VAR IR: LONGINT; (*instruction register*)
PC: LONGINT; (*program counter*)
N, Z: BOOLEAN; (*condition flags*)
R: ARRAY 16 OF LONGINT;
H: LONGINT; (*aux register for division*)
PROCEDURE Execute*(VAR M: ARRAY OF LONGINT; pc: LONGINT;
VAR S: Texts.Scanner; VAR W: Texts.Writer);
VAR a, b, op, im: LONGINT; (*instruction fields*)
adr, A, B, C, n: LONGINT;
MemSize: LONGINT;
BEGIN PC := 0; R[13] := pc * 4; R[14] := LEN(M)*4; n := 0;
REPEAT (*interpretation cycle*)
IR := M[PC]; INC(PC); INC(n);
a := IR DIV 1000000H MOD 10H;
b := IR DIV 100000H MOD 10H;
op := IR DIV 10000H MOD 10H;
im := IR MOD 10000H;
IF ~ODD(IR DIV 80000000H) THEN (*~p: register instruction*)
B := R[b];
IF ~ODD(IR DIV 40000000H) THEN (*~q*) C := R[IR MOD 10H]
ELSIF ~ODD(IR DIV 10000000H) THEN (*q&~v*) C := im
ELSE (*q&v*) C := im + 0FFFF0000H
END ;
CASE op OF
MOV: IF ~ODD(IR DIV 20000000H) THEN A := C ELSE A := H END |
LSL: A := SYSTEM.LSH(B, C) |
ASR: A := ASH(B, -C) |
ROR: A := SYSTEM.ROT(B, -C) |
AND: A := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, B) * SYSTEM.VAL(SET, C)) |
ANN: A := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, B) - SYSTEM.VAL(SET, C)) |
IOR: A := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, B) + SYSTEM.VAL(SET, C)) |
XOR: A := SYSTEM.VAL(LONGINT, SYSTEM.VAL(SET, B) / SYSTEM.VAL(SET, C)) |
ADD: A := B + C |
SUB: A := B - C |
MUL: A := B * C |
Div: A := B DIV C; H := B MOD C
END ;
R[a] := A; N := A < 0; Z := A = 0
ELSIF ~ODD(IR DIV 40000000H) THEN (*p & ~q: memory instruction*)
adr := (R[b] + IR MOD 100000H) DIV 4;
IF ~ODD(IR DIV 20000000H) THEN
IF adr >= 0 THEN (*load*) R[a] := M[adr]; N := A < 0; Z := A = 0
ELSE (*input*)
IF adr = -1 THEN (*ReadInt*) Texts.Scan(S); R[a] := S.i;
ELSIF adr = -2 THEN (*eot*) Z := S.class # Texts.Int
END
END
ELSE
IF adr >= 0 THEN (*store*) M[adr] := R[a];
ELSE (*output*)
IF adr = -1 THEN Texts.WriteInt(W, R[a], 4)
ELSIF adr = -2 THEN Texts.Write(W, CHR(R[a] MOD 80H))
ELSIF adr = -3 THEN Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
END
END
END
ELSE (* p & q: branch instruction*)
IF (a = 0) & N OR (a = 1) & Z OR (a = 5) & N OR (a = 6) & (N OR Z) OR (a = 7) OR
(a = 8) & ~N OR (a = 9) & ~Z OR (a = 13) & ~N OR (a = 14) & ~(N OR Z) THEN
IF ODD(IR DIV 10000000H) THEN R[15] := PC * 4 END ;
IF ODD(IR DIV 20000000H) THEN PC := (PC + (IR MOD 1000000H)) MOD 40000H
ELSE PC := R[IR MOD 10H] DIV 4
END
END
END
UNTIL (PC = 0) OR (n = 100000);
Texts.WriteInt(W, n, 8);
IF n = 100000 THEN Texts.WriteString(W, " aborted") END ;
Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf)
END Execute;
END RISC.