source: branches/bigint/Cpu.pas

Last change on this file was 7, checked in by chronos, 3 months ago
  • Added: More instructions implemented.
File size: 5.7 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, inInc, inDec, inLoadIndex, inPush, inPop,
13 inCall, inRet, inLoadMem, inStoreMem);
14
15 { TCpu }
16
17 TCpu = class
18 private
19 FOnReadIo: TReadAddrEvent;
20 FOnReadMem: TReadAddrEvent;
21 FOnWriteIo: TWriteAddrEvent;
22 FOnWriteMem: TWriteAddrEvent;
23 Instructions: array[TInstruction] of TInstructionEvent;
24 procedure InstructionNop;
25 procedure InstructionHalt;
26 procedure InstructionLoad;
27 procedure InstructionLoadConst;
28 procedure InstructionLoadIndex;
29 procedure InstructionLoadMem;
30 procedure InstructionStoreMem;
31 procedure InstructionInput;
32 procedure InstructionOutput;
33 procedure InstructionInc;
34 procedure InstructionDec;
35 procedure InstructionJump;
36 procedure InstructionJumpZero;
37 procedure InstructionJumpNotZero;
38 procedure InstructionPush;
39 procedure InstructionPop;
40 procedure InstructionCall;
41 procedure InstructionRet;
42 procedure WriteMem(Address, Data: TInt);
43 function ReadMem(Address: TInt): TInt;
44 function ReadMemPc: TInt;
45 procedure WriteIo(Address, Data: TInt);
46 function ReadIo(Address: TInt): TInt;
47 procedure Push(Data: TInt);
48 function Pop: TInt;
49 public
50 Halted: Boolean;
51 PC: TInt;
52 SP: TInt;
53 procedure Reset;
54 procedure Run;
55 procedure Step;
56 constructor Create;
57 property OnReadMem: TReadAddrEvent read FOnReadMem write FOnReadMem;
58 property OnWriteMem: TWriteAddrEvent read FOnWriteMem write FOnWriteMem;
59 property OnReadIo: TReadAddrEvent read FOnReadIo write FOnReadIo;
60 property OnWriteIo: TWriteAddrEvent read FOnWriteIo write FOnWriteIo;
61 end;
62
63implementation
64
65{ TCpu }
66
67procedure TCpu.InstructionNop;
68begin
69 // No operation
70end;
71
72procedure TCpu.InstructionHalt;
73begin
74 Halted := True;
75end;
76
77procedure TCpu.InstructionLoad;
78var
79 Dst, Src: TInt;
80begin
81 Dst := ReadMemPc;
82 Src := ReadMemPc;
83 WriteMem(Dst, ReadMem(Src));
84end;
85
86procedure TCpu.InstructionLoadConst;
87var
88 Dst, Data: TInt;
89begin
90 Dst := ReadMemPc;
91 Data := ReadMemPc;
92 WriteMem(Dst, Data);
93end;
94
95procedure TCpu.InstructionLoadIndex;
96var
97 Dst, Src, Index: TInt;
98begin
99 Dst := ReadMemPc;
100 Src := ReadMemPc;
101 Index := ReadMemPc;
102 WriteMem(Dst, ReadMem(Src + Index));
103end;
104
105procedure TCpu.InstructionLoadMem;
106var
107 Dst, Src: TInt;
108begin
109 Dst := ReadMemPc;
110 Src := ReadMemPc;
111 WriteMem(Dst, ReadMem(ReadMem(Src)));
112end;
113
114procedure TCpu.InstructionStoreMem;
115var
116 Dst, Src: TInt;
117begin
118 Dst := ReadMemPc;
119 Src := ReadMemPc;
120 WriteMem(ReadMem(Dst), ReadMem(Src));
121end;
122
123procedure TCpu.InstructionInput;
124var
125 Dst, Src: TInt;
126begin
127 Dst := ReadMemPc;
128 Src := ReadMemPc;
129 WriteMem(Dst, ReadIo(Src));
130end;
131
132procedure TCpu.InstructionOutput;
133var
134 Dst, Src: TInt;
135begin
136 Dst := ReadMemPc;
137 Src := ReadMemPc;
138 WriteIo(Dst, ReadMem(Src));
139end;
140
141procedure TCpu.InstructionInc;
142var
143 Addr: TInt;
144begin
145 Addr := ReadMemPc;
146 WriteMem(Addr, ReadMem(Addr) + 1);
147end;
148
149procedure TCpu.InstructionDec;
150var
151 Addr: TInt;
152begin
153 Addr := ReadMemPc;
154 WriteMem(Addr, ReadMem(Addr) - 1);
155end;
156
157procedure TCpu.InstructionJump;
158begin
159 PC := ReadMemPc;
160end;
161
162procedure TCpu.InstructionJumpZero;
163var
164 Condition: TInt;
165 Addr: TInt;
166begin
167 Condition := ReadMemPc;
168 Addr := ReadMemPc;
169 if ReadMem(Condition) = 0 then PC := Addr;
170end;
171
172procedure TCpu.InstructionJumpNotZero;
173var
174 Condition: TInt;
175 Addr: TInt;
176begin
177 Condition := ReadMemPc;
178 Addr := ReadMemPc;
179 if ReadMem(Condition) <> 0 then PC := Addr;
180end;
181
182procedure TCpu.InstructionPush;
183begin
184 Push(ReadMem(ReadMemPc));
185end;
186
187procedure TCpu.InstructionPop;
188begin
189 WriteMem(ReadMemPc, Pop);
190end;
191
192procedure TCpu.InstructionCall;
193var
194 Addr: TInt;
195begin
196 Addr := ReadMemPc;
197 Push(PC);
198 PC := Addr;
199end;
200
201procedure TCpu.InstructionRet;
202begin
203 PC := Pop;
204end;
205
206procedure TCpu.WriteMem(Address, Data: TInt);
207begin
208 if Assigned(FOnWriteMem) then FOnWriteMem(Address, Data);
209end;
210
211function TCpu.ReadMem(Address: TInt): TInt;
212begin
213 if Assigned(FOnReadMem) then Result := FOnReadMem(Address)
214 else Result := 0;
215end;
216
217function TCpu.ReadMemPc: TInt;
218begin
219 Result := ReadMem(PC);
220 Inc(PC);
221end;
222
223procedure TCpu.WriteIo(Address, Data: TInt);
224begin
225 if Assigned(FOnWriteIo) then FOnWriteIo(Address, Data);
226end;
227
228function TCpu.ReadIo(Address: TInt): TInt;
229begin
230 if Assigned(FOnReadIo) then Result := FOnReadIo(Address)
231 else Result := 0;
232end;
233
234procedure TCpu.Push(Data: TInt);
235begin
236 Dec(SP);
237 WriteMem(SP, Data);
238end;
239
240function TCpu.Pop: TInt;
241begin
242 Result := ReadMem(SP);
243 Inc(SP);
244end;
245
246procedure TCpu.Reset;
247begin
248 PC := 0;
249 SP := 1000;
250 Halted := False;
251end;
252
253procedure TCpu.Run;
254begin
255 Reset;
256 while not Halted do
257 Step;
258end;
259
260procedure TCpu.Step;
261var
262 Opcode: TInstruction;
263begin
264 Opcode := TInstruction(FOnReadMem(PC));
265 Inc(PC);
266 Instructions[Opcode];
267end;
268
269constructor TCpu.Create;
270begin
271 Instructions[inNop] := InstructionNop;
272 Instructions[inHalt] := InstructionHalt;
273 Instructions[inLoad] := InstructionLoad;
274 Instructions[inLoadIndex] := InstructionLoadIndex;
275 Instructions[inLoadConst] := InstructionLoadConst;
276 Instructions[inLoadMem] := InstructionLoadMem;
277 Instructions[inStoreMem] := InstructionStoreMem;
278 Instructions[inInput] := InstructionInput;
279 Instructions[inOutput] := InstructionOutput;
280 Instructions[inJump] := InstructionJump;
281 Instructions[inJumpZero] := InstructionJumpZero;
282 Instructions[inJumpNotZero] := InstructionJumpNotZero;
283 Instructions[inInc] := InstructionInc;
284 Instructions[inDec] := InstructionDec;
285 Instructions[inPush] := InstructionPush;
286 Instructions[inPop] := InstructionPop;
287 Instructions[inCall] := InstructionCall;
288 Instructions[inRet] := InstructionRet;
289end;
290
291end.
292
Note: See TracBrowser for help on using the repository browser.