1 | {$IFDEF INTERFACE}
|
---|
2 | TGCpu = class
|
---|
3 | public
|
---|
4 | PC: TGCpuData;
|
---|
5 | A: TGCpuData;
|
---|
6 | Memory: TGCpuAddrChannel;
|
---|
7 | IO: TGCpuAddrChannel;
|
---|
8 | Terminated: Boolean;
|
---|
9 | function Read: TGCpuData;
|
---|
10 | procedure Write(Data: TGCpuData);
|
---|
11 | procedure WriteOpcode(Opcode: TOpcode);
|
---|
12 | procedure Output(Address: TGCpuData; Data: TGCpuData);
|
---|
13 | {$IF TGCpuWidth>=8}
|
---|
14 | function Read8: Byte;
|
---|
15 | procedure Write8(Data: Byte);
|
---|
16 | procedure Output8(Address: TGCpuData; Data: Byte);
|
---|
17 | {$ENDIF}
|
---|
18 | {$IF TGCpuWidth>=16}
|
---|
19 | function Read16: Word;
|
---|
20 | procedure Write16(Data: Word);
|
---|
21 | procedure Output16(Address: TGCpuData; Data: Word);
|
---|
22 | {$ENDIF}
|
---|
23 | {$IF TGCpuWidth>=32}
|
---|
24 | function Read32: DWord;
|
---|
25 | procedure Write32(Data: DWord);
|
---|
26 | procedure Output32(Address: TGCpuData; Data: DWord);
|
---|
27 | {$ENDIF}
|
---|
28 | {$IF TGCpuWidth>=64}
|
---|
29 | function Read64: QWord;
|
---|
30 | procedure Write64(Data: QWord);
|
---|
31 | procedure Output64(Address: TGCpuData; Data: QWord);
|
---|
32 | {$ENDIF}
|
---|
33 | procedure Run;
|
---|
34 | procedure Step;
|
---|
35 | procedure Reset;
|
---|
36 | constructor Create;
|
---|
37 | destructor Destroy; override;
|
---|
38 | end;
|
---|
39 |
|
---|
40 | {$UNDEF INTERFACE}
|
---|
41 | {$ENDIF}
|
---|
42 |
|
---|
43 | {$IFDEF IMPLEMENTATION}
|
---|
44 |
|
---|
45 | constructor TGCpu.Create;
|
---|
46 | begin
|
---|
47 | Memory := TGCpuAddrChannel.Create;
|
---|
48 | IO := TGCpuAddrChannel.Create;
|
---|
49 | end;
|
---|
50 |
|
---|
51 | destructor TGCpu.Destroy;
|
---|
52 | begin
|
---|
53 | FreeAndNil(IO);
|
---|
54 | FreeAndNil(Memory);
|
---|
55 | inherited;
|
---|
56 | end;
|
---|
57 |
|
---|
58 | procedure TGCpu.Reset;
|
---|
59 | begin
|
---|
60 | A := 0;
|
---|
61 | PC := 0;
|
---|
62 | Terminated := False;
|
---|
63 | end;
|
---|
64 |
|
---|
65 | procedure TGCpu.Run;
|
---|
66 | begin
|
---|
67 | Reset;
|
---|
68 | while not Terminated do
|
---|
69 | Step;
|
---|
70 | end;
|
---|
71 |
|
---|
72 | procedure TGCpu.Step;
|
---|
73 | var
|
---|
74 | Opcode: TOpcode;
|
---|
75 | begin
|
---|
76 | Opcode := TOpcode(Read8);
|
---|
77 | case Opcode of
|
---|
78 | opNop: ;
|
---|
79 | opHalt: Terminated := True;
|
---|
80 | opLoadImmediate: A := Read;
|
---|
81 | {$IF TGCpuWidth>=8}opLoadImmediate8: PByte(@A)^ := Read8;{$ENDIF}
|
---|
82 | {$IF TGCpuWidth>=16}opLoadImmediate16: PWord(@A)^ := Read16;{$ENDIF}
|
---|
83 | {$IF TGCpuWidth>=32}opLoadImmediate32: PDWord(@A)^ := Read32;{$ENDIF}
|
---|
84 | {$IF TGCpuWidth>=64}opLoadImmediate64: PQWord(@A)^ := Read64;{$ENDIF}
|
---|
85 | opOutput: Output(Read, A);
|
---|
86 | {$IF TGCpuWidth>=8}opOutput8: Output8(Read, A);{$ENDIF}
|
---|
87 | {$IF TGCpuWidth>=16}opOutput16: Output16(Read, A);{$ENDIF}
|
---|
88 | {$IF TGCpuWidth>=32}opOutput32: Output32(Read, A);{$ENDIF}
|
---|
89 | {$IF TGCpuWidth>=64}opOutput64: Output64(Read, A);{$ENDIF}
|
---|
90 | opInc: A := A + 1;
|
---|
91 | {$IF TGCpuWidth>=8}opInc8: PByte(@A)^ := PByte(@A)^ + 1;{$ENDIF}
|
---|
92 | {$IF TGCpuWidth>=16}opInc16: PWord(@A)^ := PWord(@A)^ + 1;{$ENDIF}
|
---|
93 | {$IF TGCpuWidth>=32}opInc32: PDWord(@A)^ := PDWord(@A)^ + 1;{$ENDIF}
|
---|
94 | {$IF TGCpuWidth>=64}opInc64: PQWord(@A)^ := PQWord(@A)^ + 1;{$ENDIF}
|
---|
95 | end;
|
---|
96 | end;
|
---|
97 |
|
---|
98 | function TGCpu.Read: TGCpuData;
|
---|
99 | begin
|
---|
100 | {$IF TGCpuWidth=8}Result := Memory.Read8(PC);{$ENDIF}
|
---|
101 | {$IF TGCpuWidth=16}Result := Memory.Read16(PC);{$ENDIF}
|
---|
102 | {$IF TGCpuWidth=32}Result := Memory.Read32(PC);{$ENDIF}
|
---|
103 | {$IF TGCpuWidth=64}Result := Memory.Read64(PC);{$ENDIF}
|
---|
104 | Inc(PC, SizeOf(TGCpuData));
|
---|
105 | end;
|
---|
106 |
|
---|
107 | procedure TGCpu.Write(Data: TGCpuData);
|
---|
108 | begin
|
---|
109 | {$IF TGCpuWidth=8}Memory.Write8(PC, Data);{$ENDIF}
|
---|
110 | {$IF TGCpuWidth=16}Memory.Write16(PC, Data);{$ENDIF}
|
---|
111 | {$IF TGCpuWidth=32}Memory.Write32(PC, Data);{$ENDIF}
|
---|
112 | {$IF TGCpuWidth=64}Memory.Write64(PC, Data);{$ENDIF}
|
---|
113 | Inc(PC, SizeOf(TGCpuData));
|
---|
114 | end;
|
---|
115 |
|
---|
116 | procedure TGCpu.Output(Address: TGCpuData; Data: TGCpuData);
|
---|
117 | begin
|
---|
118 | {$IF TGCpuWidth=8}IO.Write8(Address, Data);{$ENDIF}
|
---|
119 | {$IF TGCpuWidth=16}IO.Write16(Address, Data);{$ENDIF}
|
---|
120 | {$IF TGCpuWidth=32}IO.Write32(Address, Data);{$ENDIF}
|
---|
121 | {$IF TGCpuWidth=64}IO.Write64(Address, Data);{$ENDIF}
|
---|
122 | end;
|
---|
123 |
|
---|
124 | procedure TGCpu.WriteOpcode(Opcode: TOpcode);
|
---|
125 | begin
|
---|
126 | Write8(Byte(Opcode));
|
---|
127 | end;
|
---|
128 |
|
---|
129 | {$IF TGCpuWidth>=8}
|
---|
130 | function TGCpu.Read8: Byte;
|
---|
131 | begin
|
---|
132 | Result := Memory.Read8(PC);
|
---|
133 | Inc(PC);
|
---|
134 | end;
|
---|
135 |
|
---|
136 | procedure TGCpu.Write8(Data: Byte);
|
---|
137 | begin
|
---|
138 | Memory.Write8(PC, Data);
|
---|
139 | Inc(PC);
|
---|
140 | end;
|
---|
141 |
|
---|
142 | procedure TGCpu.Output8(Address: TGCpuData; Data: Byte);
|
---|
143 | begin
|
---|
144 | IO.Write8(Address, Data);
|
---|
145 | end;
|
---|
146 | {$ENDIF}
|
---|
147 |
|
---|
148 | {$IF TGCpuWidth>=16}
|
---|
149 | function TGCpu.Read16: Word;
|
---|
150 | begin
|
---|
151 | Result := Memory.Read16(PC);
|
---|
152 | Inc(PC, SizeOf(Word));
|
---|
153 | end;
|
---|
154 |
|
---|
155 | procedure TGCpu.Write16(Data: Word);
|
---|
156 | begin
|
---|
157 | Memory.Write16(PC, Data);
|
---|
158 | Inc(PC, SizeOf(Word));
|
---|
159 | end;
|
---|
160 |
|
---|
161 | procedure TGCpu.Output16(Address: TGCpuData; Data: Word);
|
---|
162 | begin
|
---|
163 | IO.Write16(Address, Data);
|
---|
164 | end;
|
---|
165 | {$ENDIF}
|
---|
166 |
|
---|
167 | {$IF TGCpuWidth>=32}
|
---|
168 | function TGCpu.Read32: DWord;
|
---|
169 | begin
|
---|
170 | Result := Memory.Read32(PC);
|
---|
171 | Inc(PC, SizeOf(DWord));
|
---|
172 | end;
|
---|
173 |
|
---|
174 | procedure TGCpu.Write32(Data: DWord);
|
---|
175 | begin
|
---|
176 | Memory.Write32(PC, Data);
|
---|
177 | Inc(PC, SizeOf(DWord));
|
---|
178 | end;
|
---|
179 |
|
---|
180 | procedure TGCpu.Output32(Address: TGCpuData; Data: DWord);
|
---|
181 | begin
|
---|
182 | IO.Write32(Address, Data);
|
---|
183 | end;
|
---|
184 | {$ENDIF}
|
---|
185 |
|
---|
186 | {$IF TGCpuWidth>=64}
|
---|
187 | function TGCpu.Read64: QWord;
|
---|
188 | begin
|
---|
189 | Result := Memory.Read64(PC);
|
---|
190 | Inc(PC, SizeOf(QWord));
|
---|
191 | end;
|
---|
192 |
|
---|
193 | procedure TGCpu.Write64(Data: QWord);
|
---|
194 | begin
|
---|
195 | Memory.Write64(PC, Data);
|
---|
196 | Inc(PC, SizeOf(QWord));
|
---|
197 | end;
|
---|
198 |
|
---|
199 | procedure TGCpu.Output64(Address: TGCpuData; Data: QWord);
|
---|
200 | begin
|
---|
201 | IO.Write64(Address, Data);
|
---|
202 | end;
|
---|
203 | {$ENDIF}
|
---|
204 |
|
---|
205 | {$UNDEF IMPLEMENTATION}
|
---|
206 | {$ENDIF}
|
---|