source: branches/multi-width/Cpu.pas

Last change on this file was 54, checked in by chronos, 6 months ago
  • Added: Experimental multi-width CPU.
File size: 4.9 KB
Line 
1unit Cpu;
2
3interface
4
5uses
6 Classes, SysUtils, Channel;
7
8type
9 TOpcode = (opNop, opHalt, opLoad, opLoadMem, opStoreMem,
10 opInput, opOutput, opJump,
11 opWidth8, opWidth16, opWidth24, opWidth32, opWidth64, opWidth128,
12 opLoadSys, opStoreSys);
13
14 { TCpu }
15
16 TCpu = class
17 private
18 FDataWidth: TBitWidth;
19 FAddressWidth: TBitWidth;
20 FPrefixDataWidth: TBitWidth;
21 public
22 Memory: TChannel;
23 IO: TChannel;
24 Terminated: Boolean;
25 PC: QWord;
26 A: QWord;
27 procedure ReadData(var Data: QWord); overload;
28 procedure ReadData(Address: QWord; var Data: QWord); overload;
29 procedure ReadAddress(var Address: QWord);
30 function Read8: Byte;
31 function Read16: Word;
32 function Read24: DWord;
33 function Read32: DWord;
34 function Read64: QWord;
35 function ReadOpcode: TOpcode;
36 procedure WriteData(Data: QWord); overload;
37 procedure WriteData(Address: QWord; Data: QWord); overload;
38 procedure WriteAddress(Address: QWord);
39 procedure Write8(Data: Byte);
40 procedure Write16(Data: Word);
41 procedure Write24(Data: DWord);
42 procedure Write32(Data: DWord);
43 procedure Write64(Data: QWord);
44 procedure WriteOpcode(Opcode: TOpcode);
45 procedure Reset;
46 procedure Run;
47 procedure Step;
48 constructor Create;
49 destructor Destroy; override;
50 property AddressWidth: TBitWidth read FAddressWidth write FAddressWidth;
51 end;
52
53
54implementation
55
56{ TCpu }
57
58function TCpu.Read8: Byte;
59begin
60 Result := Memory.Read8(PC);
61 Inc(PC);
62end;
63
64function TCpu.Read16: Word;
65begin
66 Result := Memory.Read16(PC);
67 Inc(PC, SizeOf(Word));
68end;
69
70function TCpu.Read24: DWord;
71begin
72 Result := Memory.Read24(PC);
73 Inc(PC, 3);
74end;
75
76function TCpu.Read32: DWord;
77begin
78 Result := Memory.Read32(PC);
79 Inc(PC, SizeOf(DWord));
80end;
81
82function TCpu.Read64: QWord;
83begin
84 Result := Memory.Read64(PC);
85 Inc(PC, SizeOf(QWord));
86end;
87
88procedure TCpu.ReadData(var Data: QWord);
89begin
90 ReadData(PC, Data);
91 Inc(PC, Integer(FDataWidth));
92end;
93
94procedure TCpu.ReadData(Address: QWord; var Data: QWord);
95begin
96 Memory.Read(FDataWidth, Address, Data);
97end;
98
99procedure TCpu.ReadAddress(var Address: QWord);
100begin
101 Memory.Read(FAddressWidth, PC, Address);
102 Inc(PC, Integer(FAddressWidth));
103end;
104
105function TCpu.ReadOpcode: TOpcode;
106begin
107 Result := TOpcode(Memory.Read8(PC));
108 Inc(PC);
109end;
110
111procedure TCpu.WriteData(Data: QWord);
112begin
113 WriteData(PC, Data);
114 Inc(PC, Integer(FDataWidth));
115end;
116
117procedure TCpu.WriteData(Address: QWord; Data: QWord);
118begin
119 Memory.Write(FDataWidth, Address, Data);
120end;
121
122procedure TCpu.WriteAddress(Address: QWord);
123begin
124 Memory.Write(FAddressWidth, PC, Address);
125 Inc(PC, Integer(FAddressWidth));
126end;
127
128procedure TCpu.Write8(Data: Byte);
129begin
130 Memory.Write8(PC, Data);
131 Inc(PC);
132end;
133
134procedure TCpu.Write16(Data: Word);
135begin
136 Memory.Write16(PC, Data);
137 Inc(PC, SizeOf(Word));
138end;
139
140procedure TCpu.Write24(Data: DWord);
141begin
142 Memory.Write24(PC, Data);
143 Inc(PC, 3);
144end;
145
146procedure TCpu.Write32(Data: DWord);
147begin
148 Memory.Write32(PC, Data);
149 Inc(PC, SizeOf(DWord));
150end;
151
152procedure TCpu.Write64(Data: QWord);
153begin
154 Memory.Write64(PC, Data);
155 Inc(PC, SizeOf(QWord));
156end;
157
158procedure TCpu.WriteOpcode(Opcode: TOpcode);
159begin
160 Memory.Write8(PC, Byte(Opcode));
161 Inc(PC);
162end;
163
164procedure TCpu.Reset;
165begin
166 Terminated := False;
167 PC := 0;
168 FPrefixDataWidth := bwNone;
169 FDataWidth := FAddressWidth;
170end;
171
172procedure TCpu.Run;
173begin
174 Reset;
175 while not Terminated do
176 Step;
177end;
178
179procedure TCpu.Step;
180var
181 Opcode: TOpcode;
182 Address: QWord;
183begin
184 if FPrefixDataWidth <> bwNone then begin
185 FDataWidth := FPrefixDataWidth;
186 FPrefixDataWidth := bwNone;
187 end;
188 Opcode := TOpcode(Read8);
189 case Opcode of
190 opNop: ;
191 opHalt: Terminated := True;
192 opLoad: ReadData(A);
193 opLoadMem: begin
194 Address := 0;
195 ReadAddress(Address);
196 ReadData(Address, A);
197 end;
198 opStoreMem: begin
199 Address := 0;
200 ReadAddress(Address);
201 WriteData(Address, A);
202 end;
203 opInput: begin
204 Address := 0;
205 ReadAddress(Address);
206 IO.Read(FDataWidth, Address, A);
207 end;
208 opOutput: begin
209 Address := 0;
210 ReadAddress(Address);
211 IO.Write(FDataWidth, Address, A);
212 end;
213 opJump: begin
214 PC := 0;
215 ReadData(PC);
216 end;
217 opWidth8: if FAddressWidth <= bw8 then FPrefixDataWidth := bw8;
218 opWidth16: if FAddressWidth <= bw16 then FPrefixDataWidth := bw16;
219 opWidth24: if FAddressWidth <= bw24 then FPrefixDataWidth := bw24;
220 opWidth32: if FAddressWidth <= bw32 then FPrefixDataWidth := bw32;
221 opWidth64: if FAddressWidth <= bw64 then FPrefixDataWidth := bw64;
222 opWidth128: if FAddressWidth <= bw128 then FPrefixDataWidth := bw128;
223 end;
224 FDataWidth := FAddressWidth;
225end;
226
227constructor TCpu.Create;
228begin
229 Memory := TChannel.Create;
230 IO := TChannel.Create;
231 FAddressWidth := bw8;
232 Reset;
233end;
234
235destructor TCpu.Destroy;
236begin
237 FreeAndNil(Memory);
238 FreeAndNil(IO);
239 inherited;
240end;
241
242end.
243
Note: See TracBrowser for help on using the repository browser.