diff --git a/config/ada_chip_config.gpr b/config/ada_chip_config.gpr index 58d9276..ff2b579 100644 --- a/config/ada_chip_config.gpr +++ b/config/ada_chip_config.gpr @@ -12,7 +12,7 @@ abstract project Ada_Chip_Config is Ada_Compiler_Switches := External_As_List ("ADAFLAGS", " "); Ada_Compiler_Switches := Ada_Compiler_Switches & ( - "-Og" -- Optimize for debug + "-O2" ,"-ffunction-sections" -- Separate ELF section for each function ,"-fdata-sections" -- Separate ELF section for each variable ,"-g" -- Generate debug info diff --git a/src/ada_chip.adb b/src/ada_chip.adb index 1a86a32..abb1089 100644 --- a/src/ada_chip.adb +++ b/src/ada_chip.adb @@ -13,45 +13,36 @@ with Video; procedure Ada_Chip is package Random_Byte is new Ada.Numerics.Discrete_Random (ISA.Byte); - Steps_Per_Frame : constant := 8; - - State : CPU.Instance; Random_Generator : Random_Byte.Generator; + State : CPU.Instance; Delay_Timer : Natural := 0; Sound_Timer : Natural := 0; - Beep_Sound_Buffer : constant Sf.Audio.sfSoundBuffer_Ptr := - Sf.Audio.SoundBuffer.createFromFile ("beep.ogg"); - Beep_Sound : constant Sf.Audio.sfSound_Ptr := Sf.Audio.Sound.create; - procedure Draw_Sprite (VX, VY : ISA.Register_Index; N : ISA.Byte) is - use Sf; use ISA; - X, Y : sfUint32; + X : constant Byte := State.Registers (VX); + Y : constant Byte := State.Registers (VY); Row : aliased Byte; Row_Pixels : Pixel with Address => Row'Address; - VF : Boolean := False; + VF : Byte := 0; begin - X := sfUint32 (State.Registers (VX)); - Y := sfUint32 (State.Registers (VY)); - for I in 0 .. N - 1 loop Row := State.Memory (State.Address_Register + Address (I)); for J in 0 .. 7 loop if Row_Pixels (7 - J) then if Video.Toggle_Pixel - ((X + sfUint32 (J)) mod Video.Width, - (Y + sfUint32 (I)) mod Video.Height) + (Sf.sfUint32 ((X + Byte (J)) mod Video.Width), + Sf.sfUint32 ((Y + I) mod Video.Height)) then - VF := True; + VF := 1; end if; end if; end loop; end loop; - State.Registers (15) := (if VF then 1 else 0); + State.Registers (15) := VF; end Draw_Sprite; procedure Run_Flow (ins : ISA.Opcode) is @@ -72,7 +63,7 @@ procedure Ada_Chip is Key : constant Video.Key := Video.Key (State.Registers (X_Register (ins)) mod 16); begin - case Input_Class'Enum_Val (ins.Value mod 256) is + case Input_Class'Enum_Val (To_Byte (ins)) is when Key_Down => if Video.Key_Down (Key) then CPU.Skip (State); @@ -88,7 +79,7 @@ procedure Ada_Chip is use ISA; X : constant Register_Index := X_Register (ins); begin - case Misc_Class'Enum_Val (ins.Value mod 256) is + case Misc_Class'Enum_Val (To_Byte (ins)) is when Get_Delay => State.Registers (X) := Byte (Delay_Timer); when Get_Key => State.Registers (X) := Byte (Video.Next_Key); when Set_Delay => Delay_Timer := Natural (State.Registers (X)); @@ -112,59 +103,52 @@ procedure Ada_Chip is procedure Run_Step is use ISA; - ins : Opcode; + ins : constant Opcode := CPU.Get_Opcode (State); + XI : constant Register_Index := X_Register (ins); + YI : constant Register_Index := Y_Register (ins); + X : constant Byte := State.Registers (XI); + Y : constant Byte := State.Registers (YI); begin - ins := CPU.Get_Opcode (State); case ins.Class is when Flow => Run_Flow (ins); when Jump => CPU.Jump (State, Address (ins.Value)); when Call => CPU.Call (State, Address (ins.Value)); + when Set_Register => State.Registers (XI) := To_Byte (ins); + when Add => State.Registers (XI) := X + To_Byte (ins); + when Math => CPU.Math (State, XI, YI, To_Byte (ins) mod 16); + when Set_Address => State.Address_Register := Address (ins.Value); + when Draw_Sprite => Draw_Sprite (XI, YI, To_Byte (ins) mod 16); + when Input => Run_Input (ins); + when Misc => Run_Misc (ins); + when Jump_Relative => + CPU.Jump (State, + Address (State.Registers (0)) + Address (ins.Value)); when Equal => - if State.Registers (X_Register (ins)) = To_Byte (ins) then + if X = To_Byte (ins) then CPU.Skip (State); end if; when Not_Equal => - if State.Registers (X_Register (ins)) /= To_Byte (ins) then + if X /= To_Byte (ins) then CPU.Skip (State); end if; when Compare => - if State.Registers (X_Register (ins)) = - State.Registers (Y_Register (ins)) - then + if X = Y then CPU.Skip (State); end if; - when Set_Register => - State.Registers (X_Register (ins)) := To_Byte (ins); - when Add => - State.Registers (X_Register (ins)) := - State.Registers (X_Register (ins)) + To_Byte (ins); - when Math => - CPU.Math (State, X_Register (ins), Y_Register (ins), - To_Byte (ins) mod 16); when Not_Compare => - if State.Registers (X_Register (ins)) /= - State.Registers (Y_Register (ins)) - then + if X /= Y then CPU.Skip (State); end if; - when Set_Address => - State.Address_Register := Address (ins.Value); when Random => - State.Registers (X_Register (ins)) := + State.Registers (XI) := Random_Byte.Random (Random_Generator) mod To_Byte (ins); - when Draw_Sprite => - Draw_Sprite (X_Register (ins), Y_Register (ins), - To_Byte (ins) mod 16); - when Input => Run_Input (ins); - when Misc => Run_Misc (ins); - when others => begin - Ada.Text_IO.Put_Line ("Unknown instruction class!"); - Ada.Text_IO.Put_Line (Opcode_Class'Image (ins.Class)); - delay 1.0; - Video.Finish; - end; end case; end Run_Step; + + Steps_Per_Frame : constant := 8; + Beep_Sound : constant Sf.Audio.sfSound_Ptr := Sf.Audio.Sound.create; + Beep_Sound_Buffer : constant Sf.Audio.sfSoundBuffer_Ptr := + Sf.Audio.SoundBuffer.createFromFile ("beep.ogg"); begin if Ada.Command_Line.Argument_Count /= 1 then Ada.Text_IO.Put_Line ("usage: adachip <.c8 file>");