source: branches/simple/Cpu.pas

Last change on this file was 42, checked in by chronos, 9 months ago
  • Modified: Improved simple virtual machine.
File size: 7.1 KB
Line 
1unit Cpu;
2
3interface
4
5uses
6 Classes, SysUtils, Channel;
7
8type
9 TInstruction = (inLoadImmediate, inLoadImmediate8, inLoadImmediate16,
10 inLoad, inLoad8, inLoad16, inLoad32, inLoad64,
11 inStore, inStore8, inStore16, inStore32, inStore64,
12 inInput, inInput8, inInput16, inInput32, inInput64,
13 inOutput, inOutput8, inOutput16, inOutput32, inOutput64,
14 inNop, inHalt, inJump);
15
16 { TCpu8 }
17
18 TCpu8 = class
19 private
20 public
21 IO: TAddressableChannel8;
22 Memory: TAddressableChannel8;
23 Terminated: Boolean;
24 A: Byte;
25 PC: Byte;
26 function ReadProg8: Byte;
27 procedure Reset;
28 procedure Run;
29 procedure Step;
30 constructor Create;
31 destructor Destroy; override;
32 end;
33
34 { TCpu16 }
35
36 TCpu16 = class
37 private
38 public
39 IO: TAddressableChannel16;
40 Memory: TAddressableChannel16;
41 Terminated: Boolean;
42 A: Word;
43 PC: Word;
44 function ReadProg8: Byte;
45 function ReadProg16: Word;
46 procedure Reset;
47 procedure Run;
48 procedure Step;
49 constructor Create;
50 destructor Destroy; override;
51 end;
52
53 TCpu = class
54 BitWidth: TBitWidth;
55 Cpu8: TCpu8;
56 Cpu16: TCpu16;
57 end;
58
59 TRegMulti = record
60 case Byte of
61 0: (ValueByte: Byte);
62 1: (ValueWord: Word);
63 end;
64
65 { TCpuMulti }
66
67 TCpuMulti = class
68 private
69 public
70 IO: TAddressableChannelMulti;
71 Memory: TAddressableChannelMulti;
72 Terminated: Boolean;
73 A: TRegMulti;
74 PC: TRegMulti;
75 BitWidth: TBitWidth;
76 function ReadProg8: Byte;
77 function ReadProg16: Word;
78 procedure Reset;
79 procedure Run;
80 procedure Step;
81 constructor Create;
82 destructor Destroy; override;
83 end;
84
85
86implementation
87
88{ TCpuMulti }
89
90function TCpuMulti.ReadProg8: Byte;
91begin
92 case BitWidth of
93 bw8: begin
94 Result := Memory.ReadA8D8(PC.ValueByte);
95 Inc(PC.ValueByte);
96 end;
97 bw16: begin
98 Result := Memory.ReadA16D8(PC.ValueWord);
99 Inc(PC.ValueWord);
100 end;
101 end;
102end;
103
104function TCpuMulti.ReadProg16: Word;
105begin
106 case BitWidth of
107 //bw8: begin
108 // Result := Memory.ReadA8D16(PC.ValueByte);
109 // Inc(PC.ValueByte);
110 //end;
111 bw16: begin
112 Result := Memory.ReadA16D16(PC.ValueWord);
113 Inc(PC.ValueWord);
114 end;
115 end;
116end;
117
118procedure TCpuMulti.Reset;
119begin
120 Terminated := False;
121 PC.ValueWord := 0;
122end;
123
124procedure TCpuMulti.Run;
125begin
126 while not Terminated do
127 Step;
128end;
129
130procedure TCpuMulti.Step;
131var
132 Instruction: TInstruction;
133begin
134 Instruction := TInstruction(ReadProg8);
135 case Instruction of
136 inNop: ;
137 inHalt: Terminated := True;
138 inLoadImmediate8: A.ValueByte := ReadProg8;
139 inLoadImmediate16: A.ValueWord := ReadProg16;
140 inLoadImmediate: case BitWidth of
141 bw8: A.ValueByte := ReadProg8;
142 bw16: A.ValueWord := ReadProg16;
143 end;
144 inLoad8: case BitWidth of
145 bw8: A.ValueByte := Memory.ReadA8D8(ReadProg8);
146 bw16: A.ValueByte := Memory.ReadA16D8(ReadProg16);
147 end;
148 inLoad16: case BitWidth of
149 //bw8: A.ValueWord := Memory.ReadA8D16(ReadProg8);
150 bw16: A.ValueWord := Memory.ReadA16D16(ReadProg16);
151 end;
152 inLoad: case BitWidth of
153 bw8: A.ValueByte := Memory.ReadA8D8(ReadProg8);
154 bw16: A.ValueWord := Memory.ReadA16D16(ReadProg16);
155 end;
156 inStore8: case BitWidth of
157 bw8: Memory.WriteA8D8(ReadProg8, A.ValueByte);
158 bw16: Memory.WriteA16D8(ReadProg16, A.ValueByte);
159 end;
160 inStore16: case BitWidth of
161 //bw8: Memory.WriteA8D16(ReadProg8, A.ValueWord);
162 bw16: Memory.WriteA16D16(ReadProg16, A.ValueWord);
163 end;
164 inStore: case BitWidth of
165 bw8: Memory.WriteA8D8(ReadProg8, A.ValueByte);
166 bw16: Memory.WriteA16D16(ReadProg16, A.ValueWord);
167 end;
168 inInput8: case BitWidth of
169 bw8: A.ValueByte := IO.ReadA8D8(ReadProg8);
170 bw16: A.ValueByte := IO.ReadA16D8(ReadProg16);
171 end;
172 inInput16: case BitWidth of
173 //bw8: A.ValueWord := IO.ReadA8D16(ReadProg8);
174 bw16: A.ValueWord := IO.ReadA16D16(ReadProg16);
175 end;
176 inInput: case BitWidth of
177 bw8: A.ValueByte := IO.ReadA8D8(ReadProg8);
178 bw16: A.ValueWord := IO.ReadA16D16(ReadProg16);
179 end;
180 inOutput8: case BitWidth of
181 bw8: IO.WriteA8D8(ReadProg8, A.ValueByte);
182 bw16: IO.WriteA16D8(ReadProg16, A.ValueWord);
183 end;
184 inOutput16: case BitWidth of
185 //bw8: IO.WriteA8D16(ReadProg8, A.ValueWord);
186 bw16: IO.WriteA16D16(ReadProg16, A.ValueWord);
187 end;
188 inOutput: case BitWidth of
189 bw8: IO.WriteA8D8(ReadProg8, A.ValueByte);
190 bw16: IO.WriteA16D16(ReadProg16, A.ValueWord);
191 end;
192 inJump: case BitWidth of
193 bw8: PC.ValueByte := ReadProg8;
194 bw16: PC.ValueWord := ReadProg16;
195 end;
196 end;
197end;
198
199constructor TCpuMulti.Create;
200begin
201 IO := TAddressableChannelMulti.Create;
202 Memory := TAddressableChannelMulti.Create;
203end;
204
205destructor TCpuMulti.Destroy;
206begin
207 FreeAndNil(IO);
208 FreeAndNil(Memory);
209 inherited;
210end;
211
212{ TCpu16 }
213
214function TCpu16.ReadProg8: Byte;
215begin
216 Result := Memory.Read8(PC);
217 Inc(PC);
218end;
219
220function TCpu16.ReadProg16: Word;
221begin
222 Result := Memory.Read16(PC);
223 Inc(PC, SizeOf(Word));
224end;
225
226procedure TCpu16.Reset;
227begin
228 Terminated := False;
229 PC := 0;
230end;
231
232procedure TCpu16.Run;
233begin
234 while not Terminated do
235 Step;
236end;
237
238procedure TCpu16.Step;
239var
240 Instruction: TInstruction;
241begin
242 Instruction := TInstruction(ReadProg8);
243 case Instruction of
244 inNop: ;
245 inHalt: Terminated := True;
246 inLoadImmediate8: A := (A and $ff00) or ReadProg8;
247 inLoadImmediate16: A := ReadProg16;
248 inLoadImmediate: A := ReadProg16;
249 inLoad8: A := (A and $ff00) or Memory.Read8(ReadProg16);
250 inLoad16: A := Memory.Read16(ReadProg16);
251 inLoad: A := Memory.Read16(ReadProg16);
252 inStore8: Memory.Write8(ReadProg16, A);
253 inStore16: Memory.Write16(ReadProg16, A);
254 inStore: Memory.Write16(ReadProg16, A);
255 inInput8: A := (A and $ff00) or IO.Read8(ReadProg16);
256 inInput16: A := IO.Read16(ReadProg16);
257 inInput: A := IO.Read16(ReadProg16);
258 inOutput8: IO.Write8(ReadProg16, A);
259 inOutput16: IO.Write16(ReadProg16, A);
260 inOutput: IO.Write16(ReadProg16, A);
261 inJump: PC := ReadProg16;
262 end;
263end;
264
265constructor TCpu16.Create;
266begin
267 IO := TAddressableChannel16.Create;
268 Memory := TAddressableChannel16.Create;
269end;
270
271destructor TCpu16.Destroy;
272begin
273 FreeAndNil(IO);
274 FreeAndNil(Memory);
275 inherited;
276end;
277
278{ TCpu8 }
279
280function TCpu8.ReadProg8: Byte;
281begin
282 Result := Memory.Read8(PC);
283 Inc(PC);
284end;
285
286procedure TCpu8.Reset;
287begin
288 Terminated := False;
289 PC := 0;
290end;
291
292procedure TCpu8.Run;
293begin
294 while not Terminated do
295 Step;
296end;
297
298procedure TCpu8.Step;
299var
300 Instruction: TInstruction;
301begin
302 Instruction := TInstruction(ReadProg8);
303 case Instruction of
304 inNop: ;
305 inLoadImmediate, inLoadImmediate8: A := ReadProg8;
306 inLoad, inLoad8: A := Memory.Read8(ReadProg8);
307 inStore, inStore8: Memory.Write8(ReadProg8, A);
308 inInput, inInput8: A := IO.Read8(ReadProg8);
309 inOutput, inOutput8: IO.Write8(ReadProg8, A);
310 inHalt: Terminated := True;
311 inJump: PC := ReadProg8;
312 end;
313end;
314
315constructor TCpu8.Create;
316begin
317 IO := TAddressableChannel8.Create;
318 Memory := TAddressableChannel8.Create;
319end;
320
321destructor TCpu8.Destroy;
322begin
323 FreeAndNil(IO);
324 FreeAndNil(Memory);
325 inherited;
326end;
327
328end.
329
Note: See TracBrowser for help on using the repository browser.