Changeset 171 for branches/virtualcpu4/UCpu.pas
- Timestamp:
- Apr 10, 2019, 4:00:46 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCpu.pas
r170 r171 13 13 opCall, opRet, opAdd, opAddc, opSub, opSubc, opInc, opDec, opIn, opOut, opShl, 14 14 opShr, opDataPrefix8, opDataPrefix16, opDataPrefix32, opDataPrefix64, 15 opDataSize, opAddrSize );15 opDataSize, opAddrSize, opTest); 16 16 TAddress = QWord; 17 17 PAddress = ^TAddress; … … 53 53 procedure InstJumpNotZero; 54 54 procedure InstJumpRel; 55 procedure InstTest; 55 56 procedure InstNeg; 56 57 procedure InstClear; … … 77 78 procedure InstDataSize; 78 79 procedure InstAddrSize; 80 procedure InitInstructions; 79 81 public 80 82 Memory: array of Byte; … … 93 95 function Read32: DWord; inline; 94 96 function Read64: QWord; inline; 97 function ReadAddress: TAddress; inline; 95 98 constructor Create; 96 99 property Ticks: Integer read FTicks; … … 167 170 end; 168 171 172 procedure TCpu.InstTest; 173 var 174 Reg: Byte; 175 begin 176 Reg := Read8; 177 case DataSize of 178 bw8: Z := Registers[Reg].B = 0; 179 bw16: Z := Registers[Reg].W = 0; 180 bw32: Z := Registers[Reg].D = 0; 181 bw64: Z := Registers[Reg].Q = 0; 182 end; 183 end; 184 169 185 procedure TCpu.InstNeg; 170 186 var 171 Reg: Integer;187 Reg: Byte; 172 188 begin 173 189 Reg := Read8; … … 428 444 procedure TCpu.InstIn; 429 445 var 430 R: Integer;431 Port: Integer;446 R: Byte; 447 Port: TAddress; 432 448 begin 433 449 R := Read8; 434 Port := Read 8;450 Port := ReadAddress; 435 451 case DataSize of 436 452 bw8: begin … … 455 471 procedure TCpu.InstOut; 456 472 var 457 R: Integer;473 R: Byte; 458 474 Port: TAddress; 459 475 Value: TRegister; 460 476 begin 477 Port := ReadAddress; 461 478 R := Read8; 462 Port := Read8;463 479 case DataSize of 464 480 bw8: begin … … 541 557 end; 542 558 543 procedure TCpu.Run; 544 begin 545 Terminated := False; 546 FTicks := 0; 547 DataSizeLast := bwNone; 548 IP := 0; 549 SP := Length(Memory); 550 while not Terminated do 551 Step; 552 end; 553 554 procedure TCpu.Step; 555 var 556 Opcode: Byte; 557 begin 558 if DataSizePrefix <> bwNone then begin 559 DataSizeLast := DataSize; 560 DataSize := DataSizePrefix; 561 DataSizePrefix := bwNone; 562 end; 563 Opcode := Read8; 564 if Opcode < Length(Instructions) then Instructions[TOpcode(Opcode)] 565 else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP, 8) + '.'); 566 if DataSizeLast <> bwNone then begin 567 DataSize := DataSizeLast; 568 DataSizeLast := bwNone; 569 end; 570 IP := IP mod Length(Memory); 571 Inc(FTicks); 572 end; 573 574 procedure TCpu.Start; 575 begin 576 if not Running then begin 577 Terminated := False; 578 Thread := TCpuThread.Create(True); 579 Thread.Cpu := Self; 580 Thread.Start; 581 FRunning := True; 582 end; 583 end; 584 585 procedure TCpu.Stop; 586 begin 587 if Running then begin 588 Terminated := True; 589 Thread.Terminate; 590 Thread.WaitFor; 591 FreeAndNil(Thread); 592 FRunning := False; 593 end; 594 end; 595 596 function TCpu.Read8: Byte; 597 begin 598 Result := Memory[IP]; 599 Inc(IP); 600 end; 601 602 function TCpu.Read16: Word; 603 begin 604 Result := PWord(@Memory[IP])^; 605 Inc(IP, SizeOf(Word)); 606 end; 607 608 function TCpu.Read32: DWord; 609 begin 610 Result := PDWord(@Memory[IP])^; 611 Inc(IP, SizeOf(DWord)); 612 end; 613 614 function TCpu.Read64: QWord; 615 begin 616 Result := PQWord(@Memory[IP])^; 617 Inc(IP, SizeOf(QWord)); 618 end; 619 620 constructor TCpu.Create; 621 begin 622 DataSize := bw16; 623 AddressSize := bw16; 624 SetLength(Memory, 1000); 625 SetLength(Registers, 32); 559 procedure TCpu.InitInstructions; 560 begin 626 561 Instructions[opNop] := InstNop; 627 562 Instructions[opHalt] := InstHalt; … … 629 564 Instructions[opLoadConst] := InstLoadConst; 630 565 Instructions[opJump] := InstJump; 566 Instructions[opJumpNotZero] := InstJumpNotZero; 567 Instructions[opJumpZero] := InstJumpZero; 631 568 Instructions[opJumpRel] := InstJumpRel; 632 569 Instructions[opLoadMem] := InstLoadMem; … … 654 591 Instructions[opDataPrefix32] := InstDataPrefix64; 655 592 Instructions[opAddrSize] := InstAddrSize; 593 Instructions[opTest] := InstTest; 594 end; 595 596 procedure TCpu.Run; 597 begin 598 Terminated := False; 599 FTicks := 0; 600 DataSizeLast := bwNone; 601 IP := 0; 602 SP := Length(Memory); 603 while not Terminated do 604 Step; 605 end; 606 607 procedure TCpu.Step; 608 var 609 Opcode: Byte; 610 begin 611 if DataSizePrefix <> bwNone then begin 612 DataSizeLast := DataSize; 613 DataSize := DataSizePrefix; 614 DataSizePrefix := bwNone; 615 end; 616 Opcode := Read8; 617 if Opcode < Length(Instructions) then begin 618 if Assigned(Instructions[TOpcode(Opcode)]) then Instructions[TOpcode(Opcode)] 619 else raise Exception.Create('Missing instruction handler for opcode '+ IntToStr(Opcode)); 620 end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP, 8) + '.'); 621 if DataSizeLast <> bwNone then begin 622 DataSize := DataSizeLast; 623 DataSizeLast := bwNone; 624 end; 625 IP := IP mod Length(Memory); 626 Inc(FTicks); 627 end; 628 629 procedure TCpu.Start; 630 begin 631 if not Running then begin 632 Terminated := False; 633 Thread := TCpuThread.Create(True); 634 Thread.Cpu := Self; 635 Thread.Start; 636 FRunning := True; 637 end; 638 end; 639 640 procedure TCpu.Stop; 641 begin 642 if Running then begin 643 Terminated := True; 644 Thread.Terminate; 645 Thread.WaitFor; 646 FreeAndNil(Thread); 647 FRunning := False; 648 end; 649 end; 650 651 function TCpu.Read8: Byte; 652 begin 653 Result := Memory[IP]; 654 Inc(IP); 655 end; 656 657 function TCpu.Read16: Word; 658 begin 659 Result := PWord(@Memory[IP])^; 660 Inc(IP, SizeOf(Word)); 661 end; 662 663 function TCpu.Read32: DWord; 664 begin 665 Result := PDWord(@Memory[IP])^; 666 Inc(IP, SizeOf(DWord)); 667 end; 668 669 function TCpu.Read64: QWord; 670 begin 671 Result := PQWord(@Memory[IP])^; 672 Inc(IP, SizeOf(QWord)); 673 end; 674 675 function TCpu.ReadAddress: TAddress; 676 begin 677 case AddressSize of 678 bw8: Result := Read8; 679 bw16: Result := Read16; 680 bw32: Result := Read32; 681 bw64: Result := Read64; 682 end; 683 end; 684 685 constructor TCpu.Create; 686 begin 687 DataSize := bw16; 688 AddressSize := bw16; 689 SetLength(Memory, 1000); 690 SetLength(Registers, 32); 691 InitInstructions; 656 692 end; 657 693
Note:
See TracChangeset
for help on using the changeset viewer.