Skip to content

Instantly share code, notes, and snippets.

@tangentstorm
Created April 9, 2013 14:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tangentstorm/5346279 to your computer and use it in GitHub Desktop.
Save tangentstorm/5346279 to your computer and use it in GitHub Desktop.
RISC virtual machine by Niklaus Wirth from his book, Compiler Construction. (This is actually oberon, not pascal, but github doesn't highlight oberon)
MODULE RISC; (* NW 22.9.07 / 28.3.11 *)
IMPORT SYSTEM, Texts, Oberon;
CONST
MemSize = 1024; (* in words *)
MOV = 0; AND = 1; IOR = 2; XOR = 3; LSL = 4; ASR = 5;
ADD = 8; SUB = 9; MUL = 10; Div = 11; CMP = 12;
VAR
IR : LONGINT; (* instruction register *)
PC : LONGINT; (* program counter *)
N, Z : BOOLEAN; (* condition regosters *)
R : ARRAY 16 OF LONGINT;
PROCEDURE Execute*( VAR M: ARRAY OF LONGINT; VAR S: Texts.Scanner; VAR W: Texts.Writer );
VAR pq, a, b, op, im : LONGINT; (* instruction fields *)
VAR adr, A, B, C : LONGINT;
BEGIN
PC := 0;
REPEAT (* interpretation cycle *)
IR := M[ PC ];
INC( PC );
pq := IR DIV 40000000H MOD 4; (* insr. class *)
a := IR DIV 1000000H MOD 10H;
b := IR DIV 100000H MOD 10H;
op := IR DIV 10000H MOD 10H;
im := IR MOD 10000H;
CASE pq OF
0, 1 : (* register instructions *)
B := R[ b ];
IF pq = 0 THEN
C := R[ IR MOD 10H ]
ELSIF ODD( IR DIV 10000000H ) THEN
C := im + 0FFFF0000H
ELSE
C := im
END ;
CASE op OF
MOV : A := C
| AND : 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 ))
| LSL : A := SYSTEM.LSH( B, C )
| ASR : IF ODD( IR DIV 20000000H ) THEN A := SYSTEM.ROT( B, -C ) ELSE A := ASH( B, -C ) END
| ADD : A := B + C
| SUB, CMP : A := B - C
| MUL : A := B * C
| Div : A := B DIV C
END ;
IF op # CMP THEN
R[ a ] := A
END ;
N := A < 0;
Z := A = 0
| 2 : (* memory instructions *)
adr := ( R[ b ] + IR ) MOD 100000H DIV 4;
IF adr < MemSize THEN
IF ODD( IR DIV 20000000H ) THEN
M[ adr ] := R[ a ]
ELSE
R[ a ] := M[ adr ]
END
ELSE (* I/O *)
IF ODD( IR DIV 20000000H ) THEN
IF adr = 3FFF2H THEN
Texts.WriteInt( W, R[ a ], 8 )
ELSIF adr = 3FFF3H THEN
Texts.WriteLn( W );
Texts.Append( Oberon.Log, W.buf )
END
ELSE
IF adr = 3FFF2H THEN
Texts.Scan( S );
R[ a ] := S.i
ELSIF adr = 3FFF3H THEN
IF S.class # Texts.Int THEN
R[ a ] := 1
ELSE
R[ a ] := 0
END
END
END
END ;
| 3 : (* branch instructions *)
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 ;
Texts.Append( Oberon.Log, W.buf )
UNTIL PC = 0
END Execute;
END RISC.
@NanaYaw1
Copy link

Please anyone with codes of c++,since the one here is pascal....Please help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment