diff --git a/src/ada_chip.adb b/src/ada_chip.adb index abb1089..da48b7b 100644 --- a/src/ada_chip.adb +++ b/src/ada_chip.adb @@ -50,11 +50,10 @@ procedure Ada_Chip is case ins.Value is when ISA.Clear_Screen => Video.Clear_Screen; when ISA.Ret => CPU.Ret (State); - when others => begin + when others => Ada.Text_IO.Put_Line ("Machine code calls are unsupported!"); delay 1.0; Video.Finish; - end; end case; end Run_Flow; @@ -90,14 +89,13 @@ procedure Ada_Chip is State.Address_Register + Address (State.Registers (X)); when Get_Font => State.Address_Register := Address (State.Registers (X) mod 16) * 5; - when Get_BCD => begin + when Get_BCD => State.Memory (State.Address_Register) := State.Registers (X) / 100; State.Memory (State.Address_Register + 1) := State.Registers (X) / 10 mod 10; State.Memory (State.Address_Register + 2) := State.Registers (X) mod 10; - end; end case; end Run_Misc; diff --git a/src/cpu.adb b/src/cpu.adb index 809e039..6ea3f5d 100644 --- a/src/cpu.adb +++ b/src/cpu.adb @@ -1,5 +1,4 @@ with Ada.Sequential_IO; -with Ada.Text_IO; with Bit_Ops; package body CPU is @@ -52,47 +51,32 @@ package body CPU is end Skip; procedure Math (Inst : in out Instance; VX, VY : Register_Index; N : Byte) - is begin - case N is - when 0 => - Inst.Registers (VX) := Inst.Registers (VY); - when 1 => - Inst.Registers (VX) := Bit_Ops.Bitwise_Or - (Inst.Registers (VX), Inst.Registers (VY)); - when 2 => - Inst.Registers (VX) := Bit_Ops.Bitwise_And - (Inst.Registers (VX), Inst.Registers (VY)); - when 3 => - Inst.Registers (VX) := Bit_Ops.Bitwise_Xor - (Inst.Registers (VX), Inst.Registers (VY)); - when 4 => - declare - X : constant Byte := Inst.Registers (VX); - Y : constant Byte := Inst.Registers (VY); - begin - Inst.Registers (VX) := X + Y; - Inst.Registers (15) := - (if Integer (X) + Integer (Y) > Integer (X + Y) - then 1 else 0); - end; - when 5 => - declare - X : constant Byte := Inst.Registers (VX); - Y : constant Byte := Inst.Registers (VY); - begin - Inst.Registers (VX) := X - Y; - Inst.Registers (15) := (if X >= Y then 1 else 0); - end; - when 6 => - Inst.Registers (15) := Inst.Registers (VX) mod 2; - Inst.Registers (VX) := Inst.Registers (VX) / 2; - when 14 => - Inst.Registers (15) := Inst.Registers (VX) / (2 ** 7); - Inst.Registers (VX) := Inst.Registers (VX) * 2; - when others => begin - Ada.Text_IO.Put_Line ("Uh oh!"); - Ada.Text_IO.Put_Line (Byte'Image (N)); - end; + is + X : constant Byte := Inst.Registers (VX); + Y : constant Byte := Inst.Registers (VY); + begin + case Math_Class'Enum_Val (N) is + when Assign => Inst.Registers (VX) := Y; + when Bit_Or => Inst.Registers (VX) := Bit_Ops.Bitwise_Or (X, Y); + when Bit_And => Inst.Registers (VX) := Bit_Ops.Bitwise_And (X, Y); + when Bit_Xor => Inst.Registers (VX) := Bit_Ops.Bitwise_Xor (X, Y); + when Add => + Inst.Registers (VX) := X + Y; + Inst.Registers (15) := + (if Integer (X) + Integer (Y) > Integer (X + Y) + then 1 else 0); + when Sub_Y => + Inst.Registers (VX) := X - Y; + Inst.Registers (15) := (if X >= Y then 1 else 0); + when Shift_Right => + Inst.Registers (15) := X mod 2; + Inst.Registers (VX) := X / 2; + when Sub_X => + Inst.Registers (VX) := Y - X; + Inst.Registers (15) := (if Y >= X then 1 else 0); + when Shift_Left => + Inst.Registers (15) := X / (2 ** 7); + Inst.Registers (VX) := X * 2; end case; end Math; diff --git a/src/isa.ads b/src/isa.ads index 98d3d3e..ffc0593 100644 --- a/src/isa.ads +++ b/src/isa.ads @@ -46,6 +46,23 @@ package ISA is Clear_Screen : constant Opcode_Value := 16#E0#; Ret : constant Opcode_Value := 16#EE#; + type Math_Class is ( + Assign, Bit_Or, Bit_And, Bit_Xor, Add, Sub_Y, Shift_Right, Sub_X, + Shift_Left + ); + + for Math_Class use ( + Assign => 0, + Bit_Or => 1, + Bit_And => 2, + Bit_Xor => 3, + Add => 4, + Sub_Y => 5, + Shift_Right => 6, + Sub_X => 7, + Shift_Left => 14 + ); + type Input_Class is (Key_Down, Key_Up); for Input_Class use (