blob: 809e03999fe2c66e9565c0cdd7d97f8b236a459c (
plain)
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
with Ada.Sequential_IO;
with Ada.Text_IO;
with Bit_Ops;
package body CPU is
function Get_Opcode (Inst : in out Instance) return Opcode is
Op : aliased Opcode_Raw;
Op_Record : Opcode with Address => Op'Address;
begin
Op := Opcode_Raw (Inst.Memory (Inst.Program_Counter)) * 2 ** 8;
Op := Op + Opcode_Raw (Inst.Memory (Inst.Program_Counter + 1));
Inst.Program_Counter := Inst.Program_Counter + 2;
return Op_Record;
end Get_Opcode;
procedure Reg_Store (Inst : in out Instance; VX : Register_Index) is
begin
for I in 0 .. VX loop
Inst.Memory (Inst.Address_Register + Address (I)) :=
Inst.Registers (I);
end loop;
end Reg_Store;
procedure Reg_Load (Inst : in out Instance; VX : Register_Index) is
begin
for I in 0 .. VX loop
Inst.Registers (I) := Inst.Memory
(Inst.Address_Register + Address (I));
end loop;
end Reg_Load;
procedure Ret (Inst : in out Instance) is
begin
Jump (Inst, Inst.Stack.Last_Element);
Inst.Stack.Delete_Last;
end Ret;
procedure Call (Inst : in out Instance; A : Address) is
begin
Inst.Stack.Append (Inst.Program_Counter);
Jump (Inst, A);
end Call;
procedure Jump (Inst : in out Instance; A : Address) is
begin
Inst.Program_Counter := A;
end Jump;
procedure Skip (Inst : in out Instance) is
begin
Inst.Program_Counter := Inst.Program_Counter + 2;
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;
end case;
end Math;
procedure Load_File (Inst : in out Instance; File_Name : String) is
package Byte_IO is new Ada.Sequential_IO (Byte);
I : Address := Start_Address;
File_Handle : Byte_IO.File_Type;
begin
Byte_IO.Open (File_Handle, Byte_IO.In_File, File_Name);
while not Byte_IO.End_Of_File (File_Handle) loop
Byte_IO.Read (File_Handle, Inst.Memory (I));
I := I + 1;
end loop;
Byte_IO.Close (File_Handle);
end Load_File;
end CPU;
|