diff --git a/src/shardware.adb b/src/shardware.adb index 3ee9ffa..2a69a10 100644 --- a/src/shardware.adb +++ b/src/shardware.adb @@ -232,4 +232,40 @@ package body Shardware is end if; end DivF; + function CmpU (Register : Unsigned_32; Value : Unsigned_32) return Boolean is + begin + if Register = Value then + return True; + else + return False; + end if; + end CmpU; + + function CmpI (Register : Integer; Value : Integer) return Boolean is + begin + if Register = Value then + return True; + else + return False; + end if; + end CmpI; + + function CmpF (Register : Float; Value : Float) return Boolean is + begin + if Register = Value then + return True; + else + return False; + end if; + end CmpF; + + function Jump (Address : Unsigned_32) return Unsigned_32 is + begin + if Address mod 2 = 0 then + return Address; + else + raise Constraint_Error with "Can only jump to start of the line"; + end if; + end Jump; + end Shardware; diff --git a/src/shardware.ads b/src/shardware.ads index 23c7fa1..99e4295 100644 --- a/src/shardware.ads +++ b/src/shardware.ads @@ -46,4 +46,10 @@ package Shardware is procedure DivI (Register : in out Integer; Value : Integer); procedure DivF (Register : in out Float; Value : Float); + function CmpU (Register : Unsigned_32; Value : Unsigned_32) return Boolean; + function CmpI (Register : Integer; Value : Integer) return Boolean; + function CmpF (Register : Float; Value : Float) return Boolean; + + function Jump (Address : Unsigned_32) return Unsigned_32; + end Shardware; diff --git a/src/sillymachine.adb b/src/sillymachine.adb index c29d362..326848f 100644 --- a/src/sillymachine.adb +++ b/src/sillymachine.adb @@ -19,13 +19,15 @@ procedure sillymachine is ExecSize : Integer := 0; MemorySize : Integer := 0; - PC : Integer := 0; -- Program Counter + PC : Unsigned_32 := 0; -- Program Counter Instruction : ByteArr (0 .. 15); RegisterU : RegArrU (0 .. 27); RegisterI : RegArrI (0 .. 27); RegisterF : RegArrF (0 .. 27); + ZeroFlag : Boolean := False; + begin @@ -106,7 +108,7 @@ begin PC := 64; -- initialise program counter to entry point while True loop for i in 0 .. 15 loop -- load the instruction - Instruction (i) := MemoryArr (PC + i); + Instruction (i) := MemoryArr (Integer(PC) + i); end loop; case MyShiftU(Instruction (0), 8) + Unsigned_32(Instruction (1)) is -- execute the instruction @@ -175,6 +177,30 @@ begin BytesToF(TempBytes(Instruction))); when 34 => DivF(RegisterF(Integer(Instruction(2))), -- Divide Register by Register (Float) RegisterF(Integer(Instruction (3)))); + when 35 => ZeroFlag := CmpU(RegisterU(Integer(Instruction(2))), + BytesToU(TempBytes(Instruction))); + when 36 => ZeroFlag := CmpU(RegisterU(Integer(Instruction(2))), + RegisterU(Integer(Instruction (3)))); + when 37 => ZeroFlag := CmpI(RegisterI(Integer(Instruction(2))), + BytesToI(TempBytes(Instruction))); + when 38 => ZeroFlag := CmpI(RegisterI(Integer(Instruction(2))), + RegisterI(Integer(Instruction (3)))); + when 39 => ZeroFlag := CmpF(RegisterF(Integer(Instruction(2))), + BytesToF(TempBytes(Instruction))); + when 40 => ZeroFlag := CmpF(RegisterF(Integer(Instruction(2))), + RegisterF(Integer(Instruction (3)))); + when 41 => + if ZeroFlag then + PC := Jump(BytesToU(TempBytes(Instruction))); + else + null; + end if; + when 42 => + if ZeroFlag then + null; + else + PC := Jump(BytesToU(TempBytes(Instruction))); + end if; when 65535 => goto THE_END; -- exit opcode when others => null; end case;