Changeset 158 for branches/virtualcpu3/UMachine.pas
- Timestamp:
- Apr 25, 2018, 10:20:25 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu3/UMachine.pas
r157 r158 1 1 unit UMachine; 2 3 4 {$DEFINE EXT_IO} 5 {$DEFINE EXT_ADDRESSING_MODES} 6 {$DEFINE EXT_ARITHMETIC} 7 {$DEFINE EXT_LOGICAL} 8 {$DEFINE EXT_STACK} 9 {$DEFINE EXT_SUBROUTINE} 10 {$DEFINE EXT_SHIFT} 11 {$DEFINE EXT_BLOCK} 12 {$DEFINE EXT_GENERAL} 13 {$DEFINE EXT_BIT} 14 15 // Extension dependencies 16 {$IFDEF EXT_SUBROUTINE} 17 {$DEFINE EXT_STACK} 18 {$ENDIF} 2 19 3 20 {$mode objfpc}{$H+} … … 11 28 TOpcode = (opNop, opHalt, opLD, opLDC, opLDM, opSTM, opInc, opDec, opJP, opJr, 12 29 opPush, opPop, opCall, opRet, opAdd, opSub, opMul, opDiv, opShr, opShl, 13 opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc, opTstZ, opTstNZ, 14 opLDMD, opSTMD); 30 opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc, 31 opTstZ, opTstNZ, opTstC, opTstNC, opLDMD, opSTMD, opLdir, opLddr, 32 opBitSet, opBitRes, opBitGet, opBitPut); 15 33 16 34 TOpcodeHandler = procedure of object; 35 36 // Goals: Simple to implement, fast execution 37 // Address and data have same bit width 38 // Memory access with lower bit width? 39 // Related instructions grouped as extensions 17 40 18 41 { TCPU } … … 40 63 FOnOutput: TOutputEvent; 41 64 Condition: Boolean; 42 procedure OpcodeAddition; 43 procedure OpcodeAnd; 44 procedure OpcodeCall; 45 procedure OpcodeDecrement; 46 procedure OpcodeDivision; 47 procedure OpcodeExchange; 65 procedure OpcodeNoOperation; 48 66 procedure OpcodeHalt; 49 67 procedure OpcodeIncrement; 50 procedure Opcode Input;68 procedure OpcodeDecrement; 51 69 procedure OpcodeJump; 52 70 procedure OpcodeJumpConditional; … … 56 74 procedure OpcodeLoadConst; 57 75 procedure OpcodeLoadMemory; 76 procedure OpcodeStoreMemory; 77 procedure OpcodeTestNotZero; 78 procedure OpcodeTestZero; 79 procedure OpcodeTestNotCarry; 80 procedure OpcodeTestCarry; 81 {$IFDEF EXT_GENERAL} 82 procedure OpcodeExchange; 83 {$ENDIF} 84 {$IFDEF EXT_IO} 85 procedure OpcodeInput; 86 procedure OpcodeOutput; 87 {$ENDIF} 88 {$IFDEF EXT_ADDRESSING_MODES} 58 89 procedure OpcodeLoadMemoryDisplacement; 90 procedure OpcodeStoreMemoryDisplacement; 91 {$ENDIF} 92 {$IFDEF EXT_ARITHMETIC} 93 procedure OpcodeAddition; 94 procedure OpcodeSubtraction; 95 procedure OpcodeDivision; 59 96 procedure OpcodeMultiplication; 60 procedure OpcodeNoOperation; 97 {$ENDIF} 98 {$IFDEF EXT_LOGICAL} 99 procedure OpcodeAnd; 61 100 procedure OpcodeOr; 62 procedure OpcodeOutput; 101 procedure OpcodeXor; 102 {$ENDIF} 103 {$IFDEF EXT_STACK} 63 104 procedure OpcodePop; 64 105 procedure OpcodePush; 106 {$ENDIF} 107 {$IFDEF EXT_SUBROUTINE} 108 procedure OpcodeCall; 65 109 procedure OpcodeReturn; 110 {$ENDIF} 111 {$IFDEF EXT_SHIFT} 66 112 procedure OpcodeShiftLeft; 67 113 procedure OpcodeShiftRight; 68 procedure OpcodeStoreMemory; 69 procedure OpcodeStoreMemoryDisplacement; 70 procedure OpcodeSubtraction; 71 procedure OpcodeTestNotZero; 72 procedure OpcodeTestZero; 73 procedure OpcodeXor; 114 {$ENDIF} 115 {$IFDEF EXT_BLOCK} 116 procedure OpcodeLdir; 117 procedure OpcodeLddr; 118 {$ENDIF} 119 {$IFDEF EXT_BIT} 120 procedure OpcodeBitSet; 121 procedure OpcodeBitReset; 122 procedure OpcodeBitGet; 123 procedure OpcodeBitPut; 124 {$ENDIF} 74 125 public 75 126 Registers: array of T; 76 127 Memory: array of Byte; 77 128 IP: T; 129 {$IFDEF EXT_STACK} 78 130 SP: T; 131 {$ENDIF} 79 132 procedure Run; 80 133 constructor Create; … … 109 162 begin 110 163 IP := 0; 164 {$IFDEF EXT_STACK} 111 165 SP := Length(Memory); 166 {$ENDIF} 112 167 Terminated := False; 113 168 while not Terminated do … … 166 221 end; 167 222 223 {$IFDEF EXT_ADDRESSING_MODES} 168 224 procedure TCPU.OpcodeLoadMemoryDisplacement; 169 225 var … … 185 241 PT(@Memory[Registers[Dest] + Registers[Disp]])^ := Registers[Src]; 186 242 end; 243 {$ENDIF} 187 244 188 245 procedure TCPU.OpcodeIncrement; … … 202 259 end; 203 260 261 {$IFDEF EXT_ARITHMETIC} 204 262 procedure TCPU.OpcodeAddition; 205 263 var … … 237 295 Registers[Dest] := Registers[Dest] div Registers[Src]; 238 296 end; 239 297 {$ENDIF} 298 299 {$IFDEF EXT_SHIFT} 240 300 procedure TCPU.OpcodeShiftLeft; 241 301 var … … 255 315 Registers[Dest] := Registers[Dest] shr Registers[Src]; 256 316 end; 257 317 {$ENDIF} 318 319 {$IFDEF EXT_LOGICAL} 258 320 procedure TCPU.OpcodeAnd; 259 321 var … … 282 344 Registers[Dest] := Registers[Dest] xor Registers[Src]; 283 345 end; 346 {$ENDIF} 284 347 285 348 procedure TCPU.OpcodeJump; … … 317 380 end; 318 381 382 {$IFDEF EXT_STACK} 319 383 procedure TCPU.OpcodePush; 320 384 var … … 334 398 SP := SP + SizeOf(T); 335 399 end; 336 400 {$ENDIF} 401 402 {$IFDEF EXT_SUBROUTINE} 337 403 procedure TCPU.OpcodeCall; 338 404 var … … 350 416 SP := SP + SizeOf(T); 351 417 end; 352 418 {$ENDIF} 419 420 {$IFDEF EXT_IO} 353 421 procedure TCPU.OpcodeInput; 354 422 var … … 370 438 FOnOutput(Registers[Dest], Registers[Src]); 371 439 end; 440 {$ENDIF} 372 441 373 442 procedure TCPU.OpcodeTestZero; … … 379 448 end; 380 449 450 procedure TCPU.OpcodeTestNotCarry; 451 var 452 Reg1: TRegIndex; 453 Reg2: TRegIndex; 454 begin 455 Reg1 := ReadReg; 456 Reg2 := ReadReg; 457 Condition := Registers[Reg2] <= Registers[Reg1]; 458 end; 459 460 procedure TCPU.OpcodeTestCarry; 461 var 462 Reg1: TRegIndex; 463 Reg2: TRegIndex; 464 begin 465 Reg1 := ReadReg; 466 Reg2 := ReadReg; 467 Condition := Registers[Reg2] > Registers[Reg1]; 468 end; 469 381 470 procedure TCPU.OpcodeTestNotZero; 382 471 var … … 387 476 end; 388 477 478 {$IFDEF EXT_GENERAL} 389 479 procedure TCPU.OpcodeExchange; 390 480 var … … 398 488 Registers[Src] := Temp; 399 489 end; 400 490 {$ENDIF} 491 492 {$IFDEF EXT_BLOCK} 493 procedure TCPU.OpcodeLdir; 494 var 495 Dest, Src, Count: TRegIndex; 496 begin 497 Dest := ReadReg; 498 Src := ReadReg; 499 Count := ReadReg; 500 while Count > 0 do begin 501 Memory[Registers[Dest]] := Memory[Registers[Src]]; 502 Inc(Registers[Dest]); 503 Inc(Registers[Src]); 504 Dec(Registers[Count]); 505 end; 506 end; 507 508 procedure TCPU.OpcodeLddr; 509 var 510 Dest, Src, Count: TRegIndex; 511 begin 512 Dest := ReadReg; 513 Src := ReadReg; 514 Count := ReadReg; 515 while Count > 0 do begin 516 Memory[Registers[Dest]] := Memory[Registers[Src]]; 517 Dec(Registers[Dest]); 518 Dec(Registers[Src]); 519 Dec(Registers[Count]); 520 end; 521 end; 522 523 {$IFDEF EXT_BIT} 524 procedure TCPU.OpcodeBitSet; 525 var 526 Reg: TRegIndex; 527 Bit: TRegIndex; 528 begin 529 Reg := ReadReg; 530 Bit := ReadReg; 531 Registers[Reg] := Registers[Reg] or (1 shl Registers[Bit]); 532 end; 533 534 procedure TCPU.OpcodeBitReset; 535 var 536 Reg: TRegIndex; 537 Bit: TRegIndex; 538 begin 539 Reg := ReadReg; 540 Bit := ReadReg; 541 Registers[Reg] := Registers[Reg] and ((1 shl Registers[Bit]) xor -1); 542 end; 543 544 procedure TCPU.OpcodeBitGet; 545 var 546 Reg: TRegIndex; 547 Bit: TRegIndex; 548 begin 549 Reg := ReadReg; 550 Bit := ReadReg; 551 Condition := ((Registers[Reg] shr Registers[Bit]) and 1) = 1; 552 end; 553 554 procedure TCPU.OpcodeBitPut; 555 var 556 Reg: TRegIndex; 557 Bit: TRegIndex; 558 begin 559 Reg := ReadReg; 560 Bit := ReadReg; 561 if Condition then 562 Registers[Reg] := Registers[Reg] or (1 shl Registers[Bit]); 563 end; 564 {$ENDIF} 565 566 {$ENDIF} 401 567 402 568 procedure TCPU.Step; … … 422 588 AddOpcode(opNop, @OpcodeNoOperation); 423 589 AddOpcode(opHalt, @OpcodeHalt); 424 AddOpcode(opAnd, @OpcodeAnd);425 AddOpcode(opOr, @OpcodeOr);426 AddOpcode(opXor, @OpcodeXor);427 590 AddOpcode(opLD, @OpcodeLoad); 428 591 AddOpcode(opLDC, @OpcodeLoadConst); 429 592 AddOpcode(opLDM, @OpcodeLoadMemory); 430 593 AddOpcode(opSTM, @OpcodeStoreMemory); 431 AddOpcode(op LDMD, @OpcodeLoadMemoryDisplacement);432 AddOpcode(op STMD, @OpcodeStoreMemoryDisplacement);433 AddOpcode(op Call, @OpcodeCall);434 AddOpcode(op Ret, @OpcodeReturn);435 AddOpcode(op Push, @OpcodePush);436 AddOpcode(op Pop, @OpcodePop);594 AddOpcode(opInc, @OpcodeIncrement); 595 AddOpcode(opDec, @OpcodeDecrement); 596 AddOpcode(opTstNZ, @OpcodeTestNotZero); 597 AddOpcode(opTstZ, @OpcodeTestZero); 598 AddOpcode(opTstNC, @OpcodeTestNotCarry); 599 AddOpcode(opTstC, @OpcodeTestCarry); 437 600 AddOpcode(opJP, @OpcodeJump); 438 601 AddOpcode(opJpc, @OpcodeJumpConditional); 439 602 AddOpcode(opJR, @OpcodeJumpRelative); 440 603 AddOpcode(opJRC, @OpcodeJumpRelativeConditional); 604 {$IFDEF EXT_BIT} 605 AddOpcode(opBitSet, @OpcodeBitSet); 606 AddOpcode(opBitRes, @OpcodeBitReset); 607 AddOpcode(opBitPut, @OpcodeBitPut); 608 AddOpcode(opBitGet, @OpcodeBitGet); 609 {$ENDIF} 610 {$IFDEF EXT_LOGICAL} 611 AddOpcode(opAnd, @OpcodeAnd); 612 AddOpcode(opOr, @OpcodeOr); 613 AddOpcode(opXor, @OpcodeXor); 614 {$ENDIF} 615 {$IFDEF EXT_ADDRESSING_MODES} 616 AddOpcode(opLDMD, @OpcodeLoadMemoryDisplacement); 617 AddOpcode(opSTMD, @OpcodeStoreMemoryDisplacement); 618 {$ENDIF} 619 {$IFDEF EXT_SUBROUTINE} 620 AddOpcode(opCall, @OpcodeCall); 621 AddOpcode(opRet, @OpcodeReturn); 622 {$ENDIF} 623 {$IFDEF EXT_STACK} 624 AddOpcode(opPush, @OpcodePush); 625 AddOpcode(opPop, @OpcodePop); 626 {$ENDIF} 627 {$IFDEF EXT_ARITHMETIC} 441 628 AddOpcode(opAdd, @OpcodeAddition); 442 629 AddOpcode(opSub, @OpcodeSubtraction); 443 630 AddOpcode(opMul, @OpcodeMultiplication); 444 631 AddOpcode(opDiv, @OpcodeDivision); 632 {$ENDIF} 633 {$IFDEF EXT_GENERAL} 445 634 AddOpcode(opXchg, @OpcodeExchange); 635 {$ENDIF} 636 {$IFDEF EXT_SHIFT} 446 637 AddOpcode(opShl, @OpcodeShiftLeft); 447 638 AddOpcode(opShr, @OpcodeShiftRight); 639 {$ENDIF} 640 {$IFDEF EXT_IO} 448 641 AddOpcode(opIn, @OpcodeInput); 449 642 AddOpcode(opOut, @OpcodeOutput); 450 AddOpcode(opInc, @OpcodeIncrement); 451 AddOpcode(opDec, @OpcodeDecrement); 452 AddOpcode(opTstNZ, @OpcodeTestNotZero); 453 AddOpcode(opTstZ, @OpcodeTestZero); 643 {$ENDIF} 644 {$IFDEF EXT_BLOCK} 645 AddOpcode(opLdir, @OpcodeLdir); 646 AddOpcode(opLddr, @OpcodeLddr); 647 {$ENDIF} 454 648 end; 455 649
Note:
See TracChangeset
for help on using the changeset viewer.