source: branches/bigint/Cpu.pas

Last change on this file was 12, checked in by chronos, 3 months ago
  • Added: More CPU instructions.
  • Added: Mouse device.
File size: 9.6 KB
Line 
1unit Cpu;
2
3interface
4
5uses
6 Classes, SysUtils, Int;
7
8type
9 TInstructionEvent = procedure of object;
10
11 TInstruction = (inNop, inHalt, inLoad, inLoadConst, inInput, inOutput,
12 inJump, inJumpZero, inJumpNotZero, inIncrement, inDecrement, inLoadIndex,
13 inPush, inPop, inCall, inReturn, inLoadMem, inStoreMem, inAdd, inSubtract,
14 inAnd, inOr, inXor, inShiftLeft, inShiftRight, inJumpRel, inJumpRelZero,
15 inJumpRelNotZero, inBitSet, inBitReset, inBitTest, inGetMaxInt, inGetMinInt);
16
17 { TCpu }
18
19 TCpu = class
20 private
21 FOnReadIo: TReadAddrEvent;
22 FOnReadMem: TReadAddrEvent;
23 FOnWriteIo: TWriteAddrEvent;
24 FOnWriteMem: TWriteAddrEvent;
25 Instructions: array[TInstruction] of TInstructionEvent;
26 procedure InstructionNop;
27 procedure InstructionHalt;
28 procedure InstructionLoad;
29 procedure InstructionLoadConst;
30 procedure InstructionLoadIndex;
31 procedure InstructionLoadMem;
32 procedure InstructionStoreMem;
33 procedure InstructionInput;
34 procedure InstructionOutput;
35 procedure InstructionInc;
36 procedure InstructionDec;
37 procedure InstructionJump;
38 procedure InstructionJumpZero;
39 procedure InstructionJumpNotZero;
40 procedure InstructionJumpRel;
41 procedure InstructionJumpRelZero;
42 procedure InstructionJumpRelNotZero;
43 procedure InstructionPush;
44 procedure InstructionPop;
45 procedure InstructionCall;
46 procedure InstructionRet;
47 procedure InstructionAdd;
48 procedure InstructionSub;
49 procedure InstructionAnd;
50 procedure InstructionOr;
51 procedure InstructionXor;
52 procedure InstructionShl;
53 procedure InstructionShr;
54 procedure InstructionBitSet;
55 procedure InstructionBitReset;
56 procedure InstructionBitTest;
57 procedure InstructionGetMaxInt;
58 procedure InstructionGetMinInt;
59 procedure WriteMem(Address, Data: TInt);
60 function ReadMem(Address: TInt): TInt;
61 function ReadMemPc: TInt;
62 procedure WriteIo(Address, Data: TInt);
63 function ReadIo(Address: TInt): TInt;
64 procedure Push(Data: TInt);
65 function Pop: TInt;
66 public
67 Halted: Boolean;
68 PC: TInt;
69 SP: TInt;
70 procedure Reset;
71 procedure Run;
72 procedure Step;
73 constructor Create;
74 property OnReadMem: TReadAddrEvent read FOnReadMem write FOnReadMem;
75 property OnWriteMem: TWriteAddrEvent read FOnWriteMem write FOnWriteMem;
76 property OnReadIo: TReadAddrEvent read FOnReadIo write FOnReadIo;
77 property OnWriteIo: TWriteAddrEvent read FOnWriteIo write FOnWriteIo;
78 end;
79
80implementation
81
82{ TCpu }
83
84procedure TCpu.InstructionNop;
85begin
86 // No operation
87end;
88
89procedure TCpu.InstructionHalt;
90begin
91 Halted := True;
92end;
93
94procedure TCpu.InstructionLoad;
95var
96 Dst, Src: TInt;
97begin
98 Dst := ReadMemPc;
99 Src := ReadMemPc;
100 WriteMem(Dst, ReadMem(Src));
101end;
102
103procedure TCpu.InstructionLoadConst;
104var
105 Dst, Data: TInt;
106begin
107 Dst := ReadMemPc;
108 Data := ReadMemPc;
109 WriteMem(Dst, Data);
110end;
111
112procedure TCpu.InstructionLoadIndex;
113var
114 Dst, Src, Index: TInt;
115begin
116 Dst := ReadMemPc;
117 Src := ReadMemPc;
118 Index := ReadMemPc;
119 WriteMem(Dst, ReadMem(Src + Index));
120end;
121
122procedure TCpu.InstructionLoadMem;
123var
124 Dst, Src: TInt;
125begin
126 Dst := ReadMemPc;
127 Src := ReadMemPc;
128 WriteMem(Dst, ReadMem(ReadMem(Src)));
129end;
130
131procedure TCpu.InstructionStoreMem;
132var
133 Dst, Src: TInt;
134begin
135 Dst := ReadMemPc;
136 Src := ReadMemPc;
137 WriteMem(ReadMem(Dst), ReadMem(Src));
138end;
139
140procedure TCpu.InstructionInput;
141var
142 Dst, Src: TInt;
143begin
144 Dst := ReadMemPc;
145 Src := ReadMemPc;
146 WriteMem(Dst, ReadIo(Src));
147end;
148
149procedure TCpu.InstructionOutput;
150var
151 Dst, Src: TInt;
152begin
153 Dst := ReadMemPc;
154 Src := ReadMemPc;
155 WriteIo(Dst, ReadMem(Src));
156end;
157
158procedure TCpu.InstructionInc;
159var
160 Addr: TInt;
161begin
162 Addr := ReadMemPc;
163 WriteMem(Addr, ReadMem(Addr) + 1);
164end;
165
166procedure TCpu.InstructionDec;
167var
168 Addr: TInt;
169begin
170 Addr := ReadMemPc;
171 WriteMem(Addr, ReadMem(Addr) - 1);
172end;
173
174procedure TCpu.InstructionJump;
175begin
176 PC := ReadMemPc;
177end;
178
179procedure TCpu.InstructionJumpZero;
180var
181 Condition: TInt;
182 Addr: TInt;
183begin
184 Condition := ReadMemPc;
185 Addr := ReadMemPc;
186 if ReadMem(Condition) = 0 then PC := Addr;
187end;
188
189procedure TCpu.InstructionJumpNotZero;
190var
191 Condition: TInt;
192 Addr: TInt;
193begin
194 Condition := ReadMemPc;
195 Addr := ReadMemPc;
196 if ReadMem(Condition) <> 0 then PC := Addr;
197end;
198
199procedure TCpu.InstructionJumpRel;
200var
201 Addr: TInt;
202begin
203 Addr := ReadMemPc;
204 PC := PC + Addr;
205end;
206
207procedure TCpu.InstructionJumpRelZero;
208var
209 Condition: TInt;
210 Addr: TInt;
211begin
212 Condition := ReadMemPc;
213 Addr := ReadMemPc;
214 if ReadMem(Condition) = 0 then PC := PC + Addr;
215end;
216
217procedure TCpu.InstructionJumpRelNotZero;
218var
219 Condition: TInt;
220 Addr: TInt;
221begin
222 Condition := ReadMemPc;
223 Addr := ReadMemPc;
224 if ReadMem(Condition) <> 0 then PC := PC + Addr;
225end;
226
227procedure TCpu.InstructionPush;
228begin
229 Push(ReadMem(ReadMemPc));
230end;
231
232procedure TCpu.InstructionPop;
233begin
234 WriteMem(ReadMemPc, Pop);
235end;
236
237procedure TCpu.InstructionCall;
238var
239 Addr: TInt;
240begin
241 Addr := ReadMemPc;
242 Push(PC);
243 PC := Addr;
244end;
245
246procedure TCpu.InstructionRet;
247begin
248 PC := Pop;
249end;
250
251procedure TCpu.InstructionAdd;
252var
253 Dst, Src1, Src2: TInt;
254begin
255 Dst := ReadMemPc;
256 Src1 := ReadMemPc;
257 Src2 := ReadMemPc;
258 WriteMem(Dst, ReadMem(Src1) + ReadMem(Src2));
259end;
260
261procedure TCpu.InstructionSub;
262var
263 Dst, Src1, Src2: TInt;
264begin
265 Dst := ReadMemPc;
266 Src1 := ReadMemPc;
267 Src2 := ReadMemPc;
268 WriteMem(Dst, ReadMem(Src1) - ReadMem(Src2));
269end;
270
271procedure TCpu.InstructionAnd;
272var
273 Dst, Src1, Src2: TInt;
274begin
275 Dst := ReadMemPc;
276 Src1 := ReadMemPc;
277 Src2 := ReadMemPc;
278 WriteMem(Dst, ReadMem(Src1) and ReadMem(Src2));
279end;
280
281procedure TCpu.InstructionOr;
282var
283 Dst, Src1, Src2: TInt;
284begin
285 Dst := ReadMemPc;
286 Src1 := ReadMemPc;
287 Src2 := ReadMemPc;
288 WriteMem(Dst, ReadMem(Src1) or ReadMem(Src2));
289end;
290
291procedure TCpu.InstructionXor;
292var
293 Dst, Src1, Src2: TInt;
294begin
295 Dst := ReadMemPc;
296 Src1 := ReadMemPc;
297 Src2 := ReadMemPc;
298 WriteMem(Dst, ReadMem(Src1) xor ReadMem(Src2));
299end;
300
301procedure TCpu.InstructionShl;
302var
303 Dst, Src, Shift: TInt;
304begin
305 Dst := ReadMemPc;
306 Src := ReadMemPc;
307 Shift := ReadMemPc;
308 WriteMem(Dst, ReadMem(Src) shl ReadMem(Shift));
309end;
310
311procedure TCpu.InstructionShr;
312var
313 Dst, Src, Shift: TInt;
314begin
315 Dst := ReadMemPc;
316 Src := ReadMemPc;
317 Shift := ReadMemPc;
318 WriteMem(Dst, ReadMem(Src) shr ReadMem(Shift));
319end;
320
321procedure TCpu.InstructionBitSet;
322var
323 Dst, Src, Bit: TInt;
324begin
325 Dst := ReadMemPc;
326 Src := ReadMemPc;
327 Bit := ReadMemPc;
328 WriteMem(Dst, ReadMem(Src) or (1 << ReadMem(Bit)));
329end;
330
331procedure TCpu.InstructionBitReset;
332var
333 Dst, Src, Bit: TInt;
334begin
335 Dst := ReadMemPc;
336 Src := ReadMemPc;
337 Bit := ReadMemPc;
338 WriteMem(Dst, ReadMem(Src) and (-1 xor (1 << ReadMem(Bit))));
339end;
340
341procedure TCpu.InstructionBitTest;
342var
343 Dst, Src, Bit: TInt;
344begin
345 Dst := ReadMemPc;
346 Src := ReadMemPc;
347 Bit := ReadMemPc;
348 WriteMem(Dst, (ReadMem(Src) >> ReadMem(Bit)) and 1);
349end;
350
351procedure TCpu.InstructionGetMaxInt;
352var
353 Dst: TInt;
354begin
355 Dst := ReadMemPc;
356 WriteMem(Dst, SizeOf(TInt) * 8);
357end;
358
359procedure TCpu.InstructionGetMinInt;
360var
361 Dst: TInt;
362begin
363 Dst := ReadMemPc;
364// WriteMem(Dst, SizeOf(TInt) * 8);
365end;
366
367procedure TCpu.WriteMem(Address, Data: TInt);
368begin
369 if Assigned(FOnWriteMem) then FOnWriteMem(Address, Data);
370end;
371
372function TCpu.ReadMem(Address: TInt): TInt;
373begin
374 if Assigned(FOnReadMem) then Result := FOnReadMem(Address)
375 else Result := 0;
376end;
377
378function TCpu.ReadMemPc: TInt;
379begin
380 Result := ReadMem(PC);
381 Inc(PC);
382end;
383
384procedure TCpu.WriteIo(Address, Data: TInt);
385begin
386 if Assigned(FOnWriteIo) then FOnWriteIo(Address, Data);
387end;
388
389function TCpu.ReadIo(Address: TInt): TInt;
390begin
391 if Assigned(FOnReadIo) then Result := FOnReadIo(Address)
392 else Result := 0;
393end;
394
395procedure TCpu.Push(Data: TInt);
396begin
397 Dec(SP);
398 WriteMem(SP, Data);
399end;
400
401function TCpu.Pop: TInt;
402begin
403 Result := ReadMem(SP);
404 Inc(SP);
405end;
406
407procedure TCpu.Reset;
408begin
409 PC := 0;
410 SP := 1000;
411 Halted := False;
412end;
413
414procedure TCpu.Run;
415begin
416 Reset;
417 while not Halted do
418 Step;
419end;
420
421procedure TCpu.Step;
422var
423 Opcode: TInstruction;
424begin
425 Opcode := TInstruction(FOnReadMem(PC));
426 Inc(PC);
427 Instructions[Opcode];
428end;
429
430constructor TCpu.Create;
431begin
432 Instructions[inNop] := InstructionNop;
433 Instructions[inHalt] := InstructionHalt;
434 Instructions[inLoad] := InstructionLoad;
435 Instructions[inLoadIndex] := InstructionLoadIndex;
436 Instructions[inLoadConst] := InstructionLoadConst;
437 Instructions[inLoadMem] := InstructionLoadMem;
438 Instructions[inStoreMem] := InstructionStoreMem;
439 Instructions[inInput] := InstructionInput;
440 Instructions[inOutput] := InstructionOutput;
441 Instructions[inJump] := InstructionJump;
442 Instructions[inJumpZero] := InstructionJumpZero;
443 Instructions[inJumpNotZero] := InstructionJumpNotZero;
444 Instructions[inJumpRel] := InstructionJumpRel;
445 Instructions[inJumpRelZero] := InstructionJumpRelZero;
446 Instructions[inJumpRelNotZero] := InstructionJumpRelNotZero;
447 Instructions[inIncrement] := InstructionInc;
448 Instructions[inDecrement] := InstructionDec;
449 Instructions[inPush] := InstructionPush;
450 Instructions[inPop] := InstructionPop;
451 Instructions[inCall] := InstructionCall;
452 Instructions[inReturn] := InstructionRet;
453 Instructions[inAdd] := InstructionAdd;
454 Instructions[inSubtract] := InstructionSub;
455 Instructions[inAnd] := InstructionAnd;
456 Instructions[inOr] := InstructionOr;
457 Instructions[inXor] := InstructionXor;
458 Instructions[inShiftLeft] := InstructionShl;
459 Instructions[inShiftRight] := InstructionShr;
460 Instructions[inBitSet] := InstructionBitSet;
461 Instructions[inBitReset] := InstructionBitReset;
462 Instructions[inBitTest] := InstructionBitTest;
463 Instructions[inGetMaxInt] := InstructionGetMaxInt;
464 Instructions[inGetMinInt] := InstructionGetMinInt;
465end;
466
467end.
468
Note: See TracBrowser for help on using the repository browser.