Changeset 34 for branches/UltimatOS/UCpu.pas
- Timestamp:
- Jul 12, 2022, 11:51:47 PM (22 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/UltimatOS/UCpu.pas
r32 r34 21 21 22 22 TCpu = class; 23 TInstructionHandler = procedure of object; 23 24 24 25 { TCpuThread } … … 40 41 InterruptVector: Integer; 41 42 InterruptEnabled: Boolean; 43 FInstructionHandlers: array[TInstruction] of TInstructionHandler; 42 44 function GetRunning: Boolean; 43 function ReadByte: Byte; 44 function ReadAddress: TAddress; 45 function ReadData: TData; 46 procedure Push(Value: Integer); 47 function Pop: Integer; 45 function ReadByte: Byte; inline; 46 function ReadAddress: TAddress; inline; 47 function ReadData: TData; inline; 48 procedure Push(Value: Integer); inline; 49 function Pop: Integer; inline; 48 50 procedure SetRunning(AValue: Boolean); 51 procedure InitInstructions; 52 procedure InstructionNop; 53 procedure InstructionHalt; 54 procedure InstructionSet; 55 procedure InstructionInput; 56 procedure InstructionOutput; 57 procedure InstructionInc; 58 procedure InstructionDec; 59 procedure InstructionJp; 60 procedure InstructionJpnz; 61 procedure InstructionJpz; 62 procedure InstructionAdd; 63 procedure InstructionSub; 64 procedure InstructionCall; 65 procedure InstructionRet; 66 procedure InstructionPush; 67 procedure InstructionPop; 68 procedure InstructionCopy; 69 procedure InstructionShl; 70 procedure InstructionShr; 71 procedure InstructionLoad; 72 procedure InstructionLoadi; 73 procedure InstructionStore; 74 procedure InstructionMul; 75 procedure InstructionAnd; 76 procedure InstructionAndi; 77 procedure InstructionOr; 78 procedure InstructionXor; 79 procedure InstructionInt; 80 procedure InstructionReti; 81 procedure InstructionEnableInt; 82 procedure InstructionDisableInt; 49 83 public 50 84 ExecutedCount: Integer; … … 135 169 end; 136 170 171 procedure TCpu.InitInstructions; 172 begin 173 FInstructionHandlers[inNop] := InstructionNop; 174 FInstructionHandlers[inHalt] := InstructionHalt; 175 FInstructionHandlers[inSet] := InstructionSet; 176 FInstructionHandlers[inInput] := InstructionInput; 177 FInstructionHandlers[inOutput] := InstructionOutput; 178 FInstructionHandlers[inInc] := InstructionInc; 179 FInstructionHandlers[inDec] := InstructionDec; 180 FInstructionHandlers[inJp] := InstructionJp; 181 FInstructionHandlers[inJpz] := InstructionJpz; 182 FInstructionHandlers[inJpnz] := InstructionJpnz; 183 FInstructionHandlers[inAdd] := InstructionAdd; 184 FInstructionHandlers[inSub] := InstructionSub; 185 FInstructionHandlers[inCall] := InstructionCall; 186 FInstructionHandlers[inRet] := InstructionRet; 187 FInstructionHandlers[inPush] := InstructionPush; 188 FInstructionHandlers[inPop] := InstructionPop; 189 FInstructionHandlers[inCopy] := InstructionCopy; 190 FInstructionHandlers[inShl] := InstructionShl; 191 FInstructionHandlers[inShr] := InstructionShr; 192 FInstructionHandlers[inLoad] := InstructionLoad; 193 FInstructionHandlers[inLoadi] := InstructionLoadi; 194 FInstructionHandlers[inStore] := InstructionStore; 195 FInstructionHandlers[inMul] := InstructionMul; 196 FInstructionHandlers[inAnd] := InstructionAnd; 197 FInstructionHandlers[inAndi] := InstructionAndi; 198 FInstructionHandlers[inOr] := InstructionOr; 199 FInstructionHandlers[inXor] := InstructionXor; 200 FInstructionHandlers[inInt] := InstructionInt; 201 FInstructionHandlers[inReti] := InstructionReti; 202 FInstructionHandlers[inEnableInt] := InstructionEnableInt; 203 FInstructionHandlers[inDisableInt] := InstructionDisableInt; 204 end; 205 206 procedure TCpu.InstructionNop; 207 begin 208 // No operation 209 end; 210 211 procedure TCpu.InstructionHalt; 212 begin 213 Terminated := True; 214 end; 215 216 procedure TCpu.InstructionSet; 217 var 218 RegIndex: Byte; 219 begin 220 RegIndex := ReadByte; 221 R[RegIndex] := ReadData; 222 end; 223 224 procedure TCpu.InstructionInput; 225 var 226 RegIndex: Byte; 227 Address: TAddress; 228 begin 229 RegIndex := ReadByte; 230 Address := ReadAddress; 231 if Assigned(FOnInput) then R[RegIndex] := FOnInput(Address) 232 else R[RegIndex] := 0; 233 end; 234 235 procedure TCpu.InstructionOutput; 236 var 237 RegIndex: Byte; 238 Address: TAddress; 239 begin 240 Address := ReadAddress; 241 RegIndex := ReadByte; 242 if Assigned(FOnOutput) then FOnOutput(Address, R[RegIndex]); 243 end; 244 245 procedure TCpu.InstructionInc; 246 var 247 RegIndex: Byte; 248 begin 249 RegIndex := ReadByte; 250 R[RegIndex] := R[RegIndex] + 1; 251 end; 252 253 procedure TCpu.InstructionDec; 254 var 255 RegIndex: Byte; 256 begin 257 RegIndex := ReadByte; 258 R[RegIndex] := R[RegIndex] - 1; 259 end; 260 261 procedure TCpu.InstructionJp; 262 begin 263 IP := ReadAddress; 264 end; 265 266 procedure TCpu.InstructionJpnz; 267 var 268 RegIndex: Byte; 269 Address: TAddress; 270 begin 271 RegIndex := ReadByte; 272 Address := ReadAddress; 273 if R[RegIndex] <> 0 then IP := Address; 274 end; 275 276 procedure TCpu.InstructionJpz; 277 var 278 RegIndex: Byte; 279 Address: TAddress; 280 begin 281 RegIndex := ReadByte; 282 Address := ReadAddress; 283 if R[RegIndex] = 0 then IP := Address; 284 end; 285 286 procedure TCpu.InstructionAdd; 287 var 288 RegIndex: Byte; 289 RegIndex2: Byte; 290 begin 291 RegIndex := ReadByte; 292 RegIndex2 := ReadByte; 293 R[RegIndex] := R[RegIndex] + R[RegIndex2]; 294 end; 295 296 procedure TCpu.InstructionSub; 297 var 298 RegIndex: Byte; 299 RegIndex2: Byte; 300 begin 301 RegIndex := ReadByte; 302 RegIndex2 := ReadByte; 303 R[RegIndex] := R[RegIndex] - R[RegIndex2]; 304 end; 305 306 procedure TCpu.InstructionCall; 307 var 308 Address: TAddress; 309 begin 310 Address := ReadAddress; 311 Push(IP); 312 IP := Address; 313 end; 314 315 procedure TCpu.InstructionRet; 316 begin 317 IP := Pop; 318 end; 319 320 procedure TCpu.InstructionPush; 321 begin 322 Push(R[ReadByte]); 323 end; 324 325 procedure TCpu.InstructionPop; 326 begin 327 R[ReadByte] := Pop; 328 end; 329 330 procedure TCpu.InstructionCopy; 331 var 332 RegIndex: Byte; 333 RegIndex2: Byte; 334 begin 335 RegIndex := ReadByte; 336 RegIndex2 := ReadByte; 337 R[RegIndex] := R[RegIndex2]; 338 end; 339 340 procedure TCpu.InstructionShl; 341 var 342 RegIndex: Byte; 343 Num: Byte; 344 begin 345 RegIndex := ReadByte; 346 Num := ReadByte; 347 R[RegIndex] := R[RegIndex] shl Num; 348 end; 349 350 procedure TCpu.InstructionShr; 351 var 352 RegIndex: Byte; 353 Num: Byte; 354 begin 355 RegIndex := ReadByte; 356 Num := ReadByte; 357 R[RegIndex] := R[RegIndex] shr Num; 358 end; 359 360 procedure TCpu.InstructionLoad; 361 var 362 RegIndex: Byte; 363 RegIndex2: Byte; 364 begin 365 RegIndex := ReadByte; 366 RegIndex2 := ReadByte; 367 R[RegIndex] := PData(@Memory.Data[R[RegIndex2]])^; 368 end; 369 370 procedure TCpu.InstructionLoadi; 371 var 372 RegIndex: Byte; 373 Address: TAddress; 374 begin 375 RegIndex := ReadByte; 376 Address := ReadAddress; 377 R[RegIndex] := PData(@Memory.Data[Address])^; 378 end; 379 380 procedure TCpu.InstructionStore; 381 var 382 RegIndex: Byte; 383 RegIndex2: Byte; 384 begin 385 RegIndex := ReadByte; 386 RegIndex2 := ReadByte; 387 PData(@Memory.Data[R[RegIndex2]])^ := R[RegIndex]; 388 end; 389 390 procedure TCpu.InstructionMul; 391 var 392 RegIndex: Byte; 393 RegIndex2: Byte; 394 begin 395 RegIndex := ReadByte; 396 RegIndex2 := ReadByte; 397 R[RegIndex] := R[RegIndex] * R[RegIndex2]; 398 end; 399 400 procedure TCpu.InstructionAnd; 401 var 402 RegIndex: Byte; 403 RegIndex2: Byte; 404 begin 405 RegIndex := ReadByte; 406 RegIndex2 := ReadByte; 407 R[RegIndex] := R[RegIndex] and R[RegIndex2]; 408 end; 409 410 procedure TCpu.InstructionAndi; 411 var 412 RegIndex: Byte; 413 begin 414 RegIndex := ReadByte; 415 R[RegIndex] := R[RegIndex] and ReadData; 416 end; 417 418 procedure TCpu.InstructionOr; 419 var 420 RegIndex: Byte; 421 RegIndex2: Byte; 422 begin 423 RegIndex := ReadByte; 424 RegIndex2 := ReadByte; 425 R[RegIndex] := R[RegIndex] or R[RegIndex2]; 426 end; 427 428 procedure TCpu.InstructionXor; 429 var 430 RegIndex: Byte; 431 RegIndex2: Byte; 432 begin 433 RegIndex := ReadByte; 434 RegIndex2 := ReadByte; 435 R[RegIndex] := R[RegIndex] xor R[RegIndex2]; 436 end; 437 438 procedure TCpu.InstructionInt; 439 begin 440 Interrupt(ReadByte); 441 end; 442 443 procedure TCpu.InstructionReti; 444 begin 445 IP := Pop; 446 InterruptEnabled := True; 447 end; 448 449 procedure TCpu.InstructionEnableInt; 450 begin 451 InterruptEnabled := True; 452 end; 453 454 procedure TCpu.InstructionDisableInt; 455 begin 456 InterruptEnabled := False; 457 end; 458 137 459 procedure TCpu.Run; 138 460 begin … … 161 483 var 162 484 Instruction: TInstruction; 163 Address: Integer;164 RegIndex: Byte;165 RegIndex2: Byte;166 Num: Byte;167 485 begin 168 486 Instruction := TInstruction(ReadByte); 487 if Assigned(FInstructionHandlers[Instruction]) then 488 FInstructionHandlers[Instruction] 489 else raise Exception.Create('Missing handler for instruction ' + IntToStr(Integer(Instruction))); 169 490 Inc(ExecutedCount); 170 case Instruction of171 inNop: ;172 inHalt: Terminated := True;173 inSet: begin174 RegIndex := ReadByte;175 R[RegIndex] := ReadData;176 end;177 inLoad: begin178 RegIndex := ReadByte;179 RegIndex2 := ReadByte;180 R[RegIndex] := PData(@Memory.Data[R[RegIndex2]])^;181 end;182 inLoadi: begin183 RegIndex := ReadByte;184 Address := ReadAddress;185 R[RegIndex] := PData(@Memory.Data[Address])^;186 end;187 inStore: begin188 RegIndex := ReadByte;189 RegIndex2 := ReadByte;190 PData(@Memory.Data[R[RegIndex2]])^ := R[RegIndex];191 end;192 inInput: begin193 RegIndex := ReadByte;194 Address := ReadAddress;195 if Assigned(FOnInput) then R[RegIndex] := FOnInput(Address)196 else R[RegIndex] := 0;197 end;198 inOutput: begin199 Address := ReadAddress;200 RegIndex := ReadByte;201 if Assigned(FOnOutput) then FOnOutput(Address, R[RegIndex]);202 end;203 inInc: begin204 RegIndex := ReadByte;205 R[RegIndex] := R[RegIndex] + 1;206 end;207 inDec: begin208 RegIndex := ReadByte;209 R[RegIndex] := R[RegIndex] - 1;210 end;211 inJp: begin212 IP := ReadAddress;213 end;214 inJpz: begin215 RegIndex := ReadByte;216 Address := ReadAddress;217 if R[RegIndex] = 0 then IP := Address;218 end;219 inJpnz: begin220 RegIndex := ReadByte;221 Address := ReadAddress;222 if R[RegIndex] <> 0 then IP := Address;223 end;224 inAdd: begin225 RegIndex := ReadByte;226 RegIndex2 := ReadByte;227 R[RegIndex] := R[RegIndex] + R[RegIndex2];228 end;229 inSub: begin230 RegIndex := ReadByte;231 RegIndex2 := ReadByte;232 R[RegIndex] := R[RegIndex] - R[RegIndex2];233 end;234 inPush: begin235 RegIndex := ReadByte;236 Push(R[RegIndex]);237 end;238 inPop: begin239 RegIndex := ReadByte;240 R[RegIndex] := Pop;241 end;242 inCall: begin243 Address := ReadAddress;244 Push(IP);245 IP := Address;246 end;247 inRet: begin248 IP := Pop;249 end;250 inCopy: begin251 RegIndex := ReadByte;252 RegIndex2 := ReadByte;253 R[RegIndex] := R[RegIndex2];254 end;255 inShl: begin256 RegIndex := ReadByte;257 Num := ReadByte;258 R[RegIndex] := R[RegIndex] shl Num;259 end;260 inShr: begin261 RegIndex := ReadByte;262 Num := ReadByte;263 R[RegIndex] := R[RegIndex] shr Num;264 end;265 inMul: begin266 RegIndex := ReadByte;267 RegIndex2 := ReadByte;268 R[RegIndex] := R[RegIndex] * R[RegIndex2];269 end;270 inAnd: begin271 RegIndex := ReadByte;272 RegIndex2 := ReadByte;273 R[RegIndex] := R[RegIndex] and R[RegIndex2];274 end;275 inAndi: begin276 RegIndex := ReadByte;277 R[RegIndex] := R[RegIndex] and ReadData;278 end;279 inOr: begin280 RegIndex := ReadByte;281 RegIndex2 := ReadByte;282 R[RegIndex] := R[RegIndex] or R[RegIndex2];283 end;284 inXor: begin285 RegIndex := ReadByte;286 RegIndex2 := ReadByte;287 R[RegIndex] := R[RegIndex] xor R[RegIndex2];288 end;289 inInt: begin290 Interrupt(ReadByte);291 end;292 inReti: begin293 IP := Pop;294 InterruptEnabled := True;295 end;296 inEnableInt: InterruptEnabled := True;297 inDisableInt: InterruptEnabled := False;298 end;299 491 end; 300 492 … … 319 511 constructor TCpu.Create; 320 512 begin 513 InitInstructions; 321 514 end; 322 515
Note:
See TracChangeset
for help on using the changeset viewer.