Changeset 173 for branches/virtualcpu4/UCpu.pas
- Timestamp:
- Apr 11, 2019, 11:43:06 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCpu.pas
r171 r173 9 9 10 10 type 11 TOpcode = (opNop, opHalt, op Copy, opLoadConst, opJump, opJumpZero, opJumpNotZero,11 TOpcode = (opNop, opHalt, opLoad, opLoadi, opJump, opJumpZero, opJumpNotZero, 12 12 opJumpRel, opNeg, opClear, opLoadMem, opStoreMem, opExchg, opPush, opPop, 13 opCall, opRet, opAdd, opAdd c, opSub, opSubc, opInc, opDec, opIn, opOut, opShl,13 opCall, opRet, opAdd, opAddi, opSub, opSubi, opInc, opDec, opIn, opOut, opShl, 14 14 opShr, opDataPrefix8, opDataPrefix16, opDataPrefix32, opDataPrefix64, 15 opDataSize, opAddrSize, opTest );15 opDataSize, opAddrSize, opTest, opAnd, opOr, opXor, opLddr, opLdir); 16 16 TAddress = QWord; 17 17 PAddress = ^TAddress; 18 18 TRegIndex = Byte; 19 20 TBitWidth = (bwNone, bw8, bw16, bw32, bw64); 19 21 TRegister = record 20 case Integer of 21 0: (B: Byte); 22 1: (W: Word); 23 2: (D: DWord); 24 3: (Q: QWord); 25 end; 26 27 TBitWidth = (bwNone, bw8, bw16, bw32, bw64); 22 case TBitWidth of 23 bw8: (B: Byte); 24 bw16: (W: Word); 25 bw32: (D: DWord); 26 bw64: (Q: QWord); 27 end; 28 28 29 TInstructionEvent = procedure of object; 29 30 TInputEvent = function (Port: TAddress): TRegister of object; … … 47 48 procedure InstNop; 48 49 procedure InstHalt; 49 procedure Inst Copy;50 procedure InstLoad Const;50 procedure InstLoad; 51 procedure InstLoadImmediate; 51 52 procedure InstJump; 52 53 procedure InstJumpZero; … … 64 65 procedure InstRet; 65 66 procedure InstAdd; 66 procedure InstAdd c;67 procedure InstAddi; 67 68 procedure InstSub; 69 procedure InstSubi; 68 70 procedure InstInc; 69 71 procedure InstDec; … … 72 74 procedure InstShr; 73 75 procedure InstShl; 76 procedure InstAnd; 77 procedure InstOr; 78 procedure InstXor; 79 procedure InstLddr; 80 procedure InstLdir; 74 81 procedure InstDataPrefix8; 75 82 procedure InstDataPrefix16; … … 97 104 function ReadAddress: TAddress; inline; 98 105 constructor Create; 106 destructor Destroy; override; 99 107 property Ticks: Integer read FTicks; 100 108 property Running: Boolean read FRunning; … … 130 138 end; 131 139 132 procedure TCpu.InstCopy; 133 begin 134 case DataSize of 135 bw8: Registers[Read8].B := Registers[Read8].B; 136 bw16: Registers[Read8].W := Registers[Read8].W; 137 bw32: Registers[Read8].D := Registers[Read8].D; 138 bw64: Registers[Read8].Q := Registers[Read8].Q; 139 end; 140 end; 141 142 procedure TCpu.InstLoadConst; 140 procedure TCpu.InstLoad; 141 var 142 R1, R2: TRegIndex; 143 begin 144 R1 := Read8; 145 R2 := Read8; 146 case DataSize of 147 bw8: Registers[R1].B := Registers[R2].B; 148 bw16: Registers[R1].W := Registers[R2].W; 149 bw32: Registers[R1].D := Registers[R2].D; 150 bw64: Registers[R1].Q := Registers[R2].Q; 151 end; 152 end; 153 154 procedure TCpu.InstLoadImmediate; 143 155 begin 144 156 case DataSize of … … 172 184 procedure TCpu.InstTest; 173 185 var 174 Reg: Byte;186 Reg: TRegIndex; 175 187 begin 176 188 Reg := Read8; … … 185 197 procedure TCpu.InstNeg; 186 198 var 187 Reg: Byte;199 Reg: TRegIndex; 188 200 begin 189 201 Reg := Read8; … … 229 241 var 230 242 Temp: TRegister; 231 R1, R2: Byte;243 R1, R2: TRegIndex; 232 244 begin 233 245 R1 := Read8; … … 357 369 procedure TCpu.InstAdd; 358 370 var 359 R1, R2: Integer;371 R1, R2: TRegIndex; 360 372 begin 361 373 R1 := Read8; … … 369 381 end; 370 382 371 procedure TCpu.InstAdd c;372 var 373 R 1: Integer;374 begin 375 R 1:= Read8;376 case DataSize of 377 bw8: Registers[R 1].B := Registers[R1].B + Read8;378 bw16: Registers[R 1].W := Registers[R1].W + Read16;379 bw32: Registers[R 1].D := Registers[R1].D + Read32;380 bw64: Registers[R 1].Q := Registers[R1].Q + Read64;383 procedure TCpu.InstAddi; 384 var 385 R: TRegIndex; 386 begin 387 R := Read8; 388 case DataSize of 389 bw8: Registers[R].B := Registers[R].B + Read8; 390 bw16: Registers[R].W := Registers[R].W + Read16; 391 bw32: Registers[R].D := Registers[R].D + Read32; 392 bw64: Registers[R].Q := Registers[R].Q + Read64; 381 393 end; 382 394 end; … … 384 396 procedure TCpu.InstSub; 385 397 var 386 R1, R2: Integer;398 R1, R2: TRegIndex; 387 399 begin 388 400 R1 := Read8; … … 396 408 end; 397 409 410 procedure TCpu.InstSubi; 411 var 412 R: TRegIndex; 413 begin 414 R := Read8; 415 case DataSize of 416 bw8: Registers[R].B := Registers[R].B - Read8; 417 bw16: Registers[R].W := Registers[R].W - Read16; 418 bw32: Registers[R].D := Registers[R].D - Read32; 419 bw64: Registers[R].Q := Registers[R].Q - Read64; 420 end; 421 end; 422 398 423 procedure TCpu.InstInc; 399 424 var 400 R1: Integer;425 R1: TRegIndex; 401 426 begin 402 427 R1 := Read8; … … 411 436 procedure TCpu.InstDec; 412 437 var 413 R1: Integer;438 R1: TRegIndex; 414 439 begin 415 440 R1 := Read8; … … 444 469 procedure TCpu.InstIn; 445 470 var 446 R: Byte;471 R: TRegIndex; 447 472 Port: TAddress; 448 473 begin … … 471 496 procedure TCpu.InstOut; 472 497 var 473 R: Byte;498 R: TRegIndex; 474 499 Port: TAddress; 475 500 Value: TRegister; … … 503 528 procedure TCpu.InstShr; 504 529 var 505 R: Integer;530 R: TRegIndex; 506 531 begin 507 532 R := Read8; … … 516 541 procedure TCpu.InstShl; 517 542 var 518 R: Integer;543 R: TRegIndex; 519 544 begin 520 545 R := Read8; … … 527 552 end; 528 553 554 procedure TCpu.InstAnd; 555 var 556 R1, R2: TRegIndex; 557 begin 558 R1 := Read8; 559 R2 := Read8; 560 case DataSize of 561 bw8: Registers[R1].B := Registers[R1].B and Registers[R2].B; 562 bw16: Registers[R1].W := Registers[R1].W and Registers[R2].W; 563 bw32: Registers[R1].D := Registers[R1].D and Registers[R2].D; 564 bw64: Registers[R1].Q := Registers[R1].Q and Registers[R2].Q; 565 end; 566 end; 567 568 procedure TCpu.InstOr; 569 var 570 R1, R2: TRegIndex; 571 begin 572 R1 := Read8; 573 R2 := Read8; 574 case DataSize of 575 bw8: Registers[R1].B := Registers[R1].B or Registers[R2].B; 576 bw16: Registers[R1].W := Registers[R1].W or Registers[R2].W; 577 bw32: Registers[R1].D := Registers[R1].D or Registers[R2].D; 578 bw64: Registers[R1].Q := Registers[R1].Q or Registers[R2].Q; 579 end; 580 end; 581 582 procedure TCpu.InstXor; 583 var 584 R1, R2: TRegIndex; 585 begin 586 R1 := Read8; 587 R2 := Read8; 588 case DataSize of 589 bw8: Registers[R1].B := Registers[R1].B xor Registers[R2].B; 590 bw16: Registers[R1].W := Registers[R1].W xor Registers[R2].W; 591 bw32: Registers[R1].D := Registers[R1].D xor Registers[R2].D; 592 bw64: Registers[R1].Q := Registers[R1].Q xor Registers[R2].Q; 593 end; 594 end; 595 596 procedure TCpu.InstLddr; 597 var 598 Source, Dest, Count: TRegIndex; 599 begin 600 Source := Read8; 601 Dest := Read8; 602 Count := Read8; 603 case AddressSize of 604 bw8: while Registers[Count].B > 0 do begin 605 case DataSize of 606 bw8: begin 607 PByte(@Memory[Registers[Dest].B])^ := PByte(@Memory[Registers[Source].B])^; 608 Dec(Registers[Dest].B, SizeOf(Byte)); 609 Dec(Registers[Source].B, SizeOf(Byte)); 610 end; 611 bw16: begin 612 PWord(@Memory[Registers[Dest].B])^ := PWord(@Memory[Registers[Source].B])^; 613 Dec(Registers[Dest].B, SizeOf(Word)); 614 Dec(Registers[Source].B, SizeOf(Word)); 615 end; 616 bw32: begin 617 PDWord(@Memory[Registers[Dest].B])^ := PDWord(@Memory[Registers[Source].B])^; 618 Dec(Registers[Dest].B, SizeOf(DWord)); 619 Dec(Registers[Source].B, SizeOf(DWord)); 620 end; 621 bw64: begin 622 PQWord(@Memory[Registers[Dest].B])^ := PQWord(@Memory[Registers[Source].B])^; 623 Dec(Registers[Dest].B, SizeOf(QWord)); 624 Dec(Registers[Source].B, SizeOf(QWord)); 625 end; 626 end; 627 Dec(Registers[Count].B); 628 end; 629 bw16: while Registers[Count].W > 0 do begin 630 case DataSize of 631 bw8: begin 632 PByte(@Memory[Registers[Dest].W])^ := PByte(@Memory[Registers[Source].W])^; 633 Dec(Registers[Dest].W, SizeOf(Byte)); 634 Dec(Registers[Source].W, SizeOf(Byte)); 635 end; 636 bw16: begin 637 PWord(@Memory[Registers[Dest].W])^ := PWord(@Memory[Registers[Source].W])^; 638 Dec(Registers[Dest].W, SizeOf(Word)); 639 Dec(Registers[Source].W, SizeOf(Word)); 640 end; 641 bw32: begin 642 PDWord(@Memory[Registers[Dest].W])^ := PDWord(@Memory[Registers[Source].W])^; 643 Dec(Registers[Dest].W, SizeOf(DWord)); 644 Dec(Registers[Source].W, SizeOf(DWord)); 645 end; 646 bw64: begin 647 PQWord(@Memory[Registers[Dest].W])^ := PQWord(@Memory[Registers[Source].W])^; 648 Dec(Registers[Dest].W, SizeOf(QWord)); 649 Dec(Registers[Source].W, SizeOf(QWord)); 650 end; 651 end; 652 Dec(Registers[Count].W); 653 end; 654 bw32: while Registers[Count].D > 0 do begin 655 case DataSize of 656 bw8: begin 657 PByte(@Memory[Registers[Dest].D])^ := PByte(@Memory[Registers[Source].D])^; 658 Dec(Registers[Dest].D, SizeOf(Byte)); 659 Dec(Registers[Source].D, SizeOf(Byte)); 660 end; 661 bw16: begin 662 PWord(@Memory[Registers[Dest].D])^ := PWord(@Memory[Registers[Source].D])^; 663 Dec(Registers[Dest].D, SizeOf(Word)); 664 Dec(Registers[Source].D, SizeOf(Word)); 665 end; 666 bw32: begin 667 PDWord(@Memory[Registers[Dest].W])^ := PDWord(@Memory[Registers[Source].D])^; 668 Dec(Registers[Dest].D, SizeOf(DWord)); 669 Dec(Registers[Source].D, SizeOf(DWord)); 670 end; 671 bw64: begin 672 PQWord(@Memory[Registers[Dest].D])^ := PQWord(@Memory[Registers[Source].D])^; 673 Dec(Registers[Dest].D, SizeOf(QWord)); 674 Dec(Registers[Source].D, SizeOf(QWord)); 675 end; 676 end; 677 Dec(Registers[Count].D); 678 end; 679 bw64: while Registers[Count].Q > 0 do begin 680 case DataSize of 681 bw8: begin 682 PByte(@Memory[Registers[Dest].Q])^ := PByte(@Memory[Registers[Source].Q])^; 683 Dec(Registers[Dest].Q, SizeOf(Byte)); 684 Dec(Registers[Source].Q, SizeOf(Byte)); 685 end; 686 bw16: begin 687 PWord(@Memory[Registers[Dest].Q])^ := PWord(@Memory[Registers[Source].Q])^; 688 Dec(Registers[Dest].Q, SizeOf(Word)); 689 Dec(Registers[Source].Q, SizeOf(Word)); 690 end; 691 bw32: begin 692 PDWord(@Memory[Registers[Dest].Q])^ := PDWord(@Memory[Registers[Source].Q])^; 693 Dec(Registers[Dest].Q, SizeOf(DWord)); 694 Dec(Registers[Source].Q, SizeOf(DWord)); 695 end; 696 bw64: begin 697 PQWord(@Memory[Registers[Dest].Q])^ := PQWord(@Memory[Registers[Source].Q])^; 698 Dec(Registers[Dest].Q, SizeOf(QWord)); 699 Dec(Registers[Source].Q, SizeOf(QWord)); 700 end; 701 end; 702 Dec(Registers[Count].W); 703 end; 704 end; 705 end; 706 707 procedure TCpu.InstLdir; 708 var 709 Source, Dest, Count: TRegIndex; 710 begin 711 Source := Read8; 712 Dest := Read8; 713 Count := Read8; 714 case AddressSize of 715 bw8: while Registers[Count].B > 0 do begin 716 case DataSize of 717 bw8: begin 718 PByte(@Memory[Registers[Dest].B])^ := PByte(@Memory[Registers[Source].B])^; 719 Inc(Registers[Dest].B, SizeOf(Byte)); 720 Inc(Registers[Source].B, SizeOf(Byte)); 721 end; 722 bw16: begin 723 PWord(@Memory[Registers[Dest].B])^ := PWord(@Memory[Registers[Source].B])^; 724 Inc(Registers[Dest].B, SizeOf(Word)); 725 Inc(Registers[Source].B, SizeOf(Word)); 726 end; 727 bw32: begin 728 PDWord(@Memory[Registers[Dest].B])^ := PDWord(@Memory[Registers[Source].B])^; 729 Inc(Registers[Dest].B, SizeOf(DWord)); 730 Inc(Registers[Source].B, SizeOf(DWord)); 731 end; 732 bw64: begin 733 PQWord(@Memory[Registers[Dest].B])^ := PQWord(@Memory[Registers[Source].B])^; 734 Inc(Registers[Dest].B, SizeOf(QWord)); 735 Inc(Registers[Source].B, SizeOf(QWord)); 736 end; 737 end; 738 Dec(Registers[Count].B); 739 end; 740 bw16: while Registers[Count].W > 0 do begin 741 case DataSize of 742 bw8: begin 743 PByte(@Memory[Registers[Dest].W])^ := PByte(@Memory[Registers[Source].W])^; 744 Inc(Registers[Dest].W, SizeOf(Byte)); 745 Inc(Registers[Source].W, SizeOf(Byte)); 746 end; 747 bw16: begin 748 PWord(@Memory[Registers[Dest].W])^ := PWord(@Memory[Registers[Source].W])^; 749 Inc(Registers[Dest].W, SizeOf(Word)); 750 Inc(Registers[Source].W, SizeOf(Word)); 751 end; 752 bw32: begin 753 PDWord(@Memory[Registers[Dest].W])^ := PDWord(@Memory[Registers[Source].W])^; 754 Inc(Registers[Dest].W, SizeOf(DWord)); 755 Inc(Registers[Source].W, SizeOf(DWord)); 756 end; 757 bw64: begin 758 PQWord(@Memory[Registers[Dest].W])^ := PQWord(@Memory[Registers[Source].W])^; 759 Inc(Registers[Dest].W, SizeOf(QWord)); 760 Inc(Registers[Source].W, SizeOf(QWord)); 761 end; 762 end; 763 Dec(Registers[Count].W); 764 end; 765 bw32: while Registers[Count].D > 0 do begin 766 case DataSize of 767 bw8: begin 768 PByte(@Memory[Registers[Dest].D])^ := PByte(@Memory[Registers[Source].D])^; 769 Inc(Registers[Dest].D, SizeOf(Byte)); 770 Inc(Registers[Source].D, SizeOf(Byte)); 771 end; 772 bw16: begin 773 PWord(@Memory[Registers[Dest].D])^ := PWord(@Memory[Registers[Source].D])^; 774 Inc(Registers[Dest].D, SizeOf(Word)); 775 Inc(Registers[Source].D, SizeOf(Word)); 776 end; 777 bw32: begin 778 PDWord(@Memory[Registers[Dest].W])^ := PDWord(@Memory[Registers[Source].D])^; 779 Inc(Registers[Dest].D, SizeOf(DWord)); 780 Inc(Registers[Source].D, SizeOf(DWord)); 781 end; 782 bw64: begin 783 PQWord(@Memory[Registers[Dest].D])^ := PQWord(@Memory[Registers[Source].D])^; 784 Inc(Registers[Dest].D, SizeOf(QWord)); 785 Inc(Registers[Source].D, SizeOf(QWord)); 786 end; 787 end; 788 Dec(Registers[Count].D); 789 end; 790 bw64: while Registers[Count].Q > 0 do begin 791 case DataSize of 792 bw8: begin 793 PByte(@Memory[Registers[Dest].Q])^ := PByte(@Memory[Registers[Source].Q])^; 794 Inc(Registers[Dest].Q, SizeOf(Byte)); 795 Inc(Registers[Source].Q, SizeOf(Byte)); 796 end; 797 bw16: begin 798 PWord(@Memory[Registers[Dest].Q])^ := PWord(@Memory[Registers[Source].Q])^; 799 Inc(Registers[Dest].Q, SizeOf(Word)); 800 Inc(Registers[Source].Q, SizeOf(Word)); 801 end; 802 bw32: begin 803 PDWord(@Memory[Registers[Dest].Q])^ := PDWord(@Memory[Registers[Source].Q])^; 804 Inc(Registers[Dest].Q, SizeOf(DWord)); 805 Inc(Registers[Source].Q, SizeOf(DWord)); 806 end; 807 bw64: begin 808 PQWord(@Memory[Registers[Dest].Q])^ := PQWord(@Memory[Registers[Source].Q])^; 809 Inc(Registers[Dest].Q, SizeOf(QWord)); 810 Inc(Registers[Source].Q, SizeOf(QWord)); 811 end; 812 end; 813 Dec(Registers[Count].W); 814 end; 815 end; 816 end; 817 529 818 procedure TCpu.InstDataPrefix8; 530 819 begin … … 561 850 Instructions[opNop] := InstNop; 562 851 Instructions[opHalt] := InstHalt; 563 Instructions[op Copy] := InstCopy;564 Instructions[opLoad Const] := InstLoadConst;852 Instructions[opLoad] := InstLoad; 853 Instructions[opLoadi] := InstLoadImmediate; 565 854 Instructions[opJump] := InstJump; 566 855 Instructions[opJumpNotZero] := InstJumpNotZero; … … 577 866 Instructions[opRet] := InstRet; 578 867 Instructions[opAdd] := InstAdd; 579 Instructions[opAdd c] := InstAddc;868 Instructions[opAddi] := InstAddi; 580 869 Instructions[opSub] := InstSub; 870 Instructions[opSubi] := InstSubi; 581 871 Instructions[opInc] := InstInc; 582 872 Instructions[opDec] := InstDec; … … 592 882 Instructions[opAddrSize] := InstAddrSize; 593 883 Instructions[opTest] := InstTest; 884 Instructions[opAnd] := InstAnd; 885 Instructions[opOr] := InstOr; 886 Instructions[opXor] := InstXor; 887 Instructions[opLdir] := InstLdir; 888 Instructions[opLddr] := InstLddr; 594 889 end; 595 890 … … 692 987 end; 693 988 989 destructor TCpu.Destroy; 990 begin 991 Stop; 992 inherited Destroy; 993 end; 994 694 995 end. 695 996
Note:
See TracChangeset
for help on using the changeset viewer.