- Timestamp:
- Apr 10, 2019, 3:26:36 PM (6 years ago)
- Location:
- branches/virtualcpu4
- Files:
-
- 1 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCpu.pas
r169 r170 9 9 10 10 type 11 TAddress = DWord; 11 TOpcode = (opNop, opHalt, opCopy, opLoadConst, opJump, opJumpZero, opJumpNotZero, 12 opJumpRel, opNeg, opClear, opLoadMem, opStoreMem, opExchg, opPush, opPop, 13 opCall, opRet, opAdd, opAddc, opSub, opSubc, opInc, opDec, opIn, opOut, opShl, 14 opShr, opDataPrefix8, opDataPrefix16, opDataPrefix32, opDataPrefix64, 15 opDataSize, opAddrSize); 16 TAddress = QWord; 12 17 PAddress = ^TAddress; 13 18 … … 25 30 TOutputEvent = procedure (Port: TAddress; Value: TRegister) of object; 26 31 32 TCpuThread = class; 33 27 34 { TCpu } 28 35 … … 31 38 FOnInput: TInputEvent; 32 39 FOnOutput: TOutputEvent; 33 Instructions: array of TInstructionEvent;34 AddressSize: TBitWidth;35 DataSize: TBitWidth;40 FRunning: Boolean; 41 FTicks: Integer; 42 Instructions: array[TOpcode] of TInstructionEvent; 36 43 DataSizeLast: TBitWidth; 44 DataSizePrefix: TBitWidth; 37 45 Z: Boolean; 46 Thread: TCpuThread; 38 47 procedure InstNop; 39 48 procedure InstHalt; … … 61 70 procedure InstOut; 62 71 procedure InstShr; 72 procedure InstShl; 63 73 procedure InstDataPrefix8; 64 74 procedure InstDataPrefix16; … … 73 83 IP: TAddress; 74 84 SP: TAddress; 85 AddressSize: TBitWidth; 86 DataSize: TBitWidth; 75 87 procedure Run; 76 procedure Step; 77 function Read8: Byte; 78 function Read16: Word; 79 function Read32: DWord; 80 function Read64: QWord; 88 procedure Step; inline; 89 procedure Start; 90 procedure Stop; 91 function Read8: Byte; inline; 92 function Read16: Word; inline; 93 function Read32: DWord; inline; 94 function Read64: QWord; inline; 81 95 constructor Create; 96 property Ticks: Integer read FTicks; 97 property Running: Boolean read FRunning; 82 98 property OnInput: TInputEvent read FOnInput write FOnInput; 83 99 property OnOutput: TOutputEvent read FOnOutput write FOnOutput; 84 100 end; 85 101 102 { TCpuThread } 103 104 TCpuThread = class(TThread) 105 Cpu: TCpu; 106 procedure Execute; override; 107 end; 108 86 109 implementation 110 111 { TCpuThread } 112 113 procedure TCpuThread.Execute; 114 begin 115 Cpu.Run; 116 end; 87 117 88 118 { TCpu } … … 468 498 end; 469 499 500 procedure TCpu.InstShl; 501 var 502 R: Integer; 503 begin 504 R := Read8; 505 case DataSize of 506 bw8: Registers[R].B := Registers[R].B shl Read8; 507 bw16: Registers[R].W := Registers[R].W shl Read16; 508 bw32: Registers[R].D := Registers[R].D shl Read32; 509 bw64: Registers[R].Q := Registers[R].Q shl Read64; 510 end; 511 end; 512 470 513 procedure TCpu.InstDataPrefix8; 471 514 begin 472 DataSizeLast := DataSize; 473 DataSize := bw8; 515 DataSizePrefix := bw8; 474 516 end; 475 517 476 518 procedure TCpu.InstDataPrefix16; 477 519 begin 478 DataSizeLast := DataSize; 479 DataSize := bw16; 520 DataSizePrefix := bw16; 480 521 end; 481 522 482 523 procedure TCpu.InstDataPrefix32; 483 524 begin 484 DataSizeLast := DataSize; 485 DataSize := bw32; 525 DataSizePrefix := bw32; 486 526 end; 487 527 488 528 procedure TCpu.InstDataPrefix64; 489 529 begin 490 DataSizeLast := DataSize; 491 DataSize := bw64; 530 DataSizePrefix := bw64; 492 531 end; 493 532 … … 505 544 begin 506 545 Terminated := False; 546 FTicks := 0; 507 547 DataSizeLast := bwNone; 508 DataSize := bw16;509 AddressSize := bw16;510 548 IP := 0; 549 SP := Length(Memory); 511 550 while not Terminated do 512 551 Step; … … 517 556 Opcode: Byte; 518 557 begin 558 if DataSizePrefix <> bwNone then begin 559 DataSizeLast := DataSize; 560 DataSize := DataSizePrefix; 561 DataSizePrefix := bwNone; 562 end; 519 563 Opcode := Read8; 520 if Opcode < Length(Instructions) then Instructions[ Opcode]564 if Opcode < Length(Instructions) then Instructions[TOpcode(Opcode)] 521 565 else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP, 8) + '.'); 522 566 if DataSizeLast <> bwNone then begin … … 525 569 end; 526 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; 527 594 end; 528 595 … … 553 620 constructor TCpu.Create; 554 621 begin 622 DataSize := bw16; 623 AddressSize := bw16; 555 624 SetLength(Memory, 1000); 556 625 SetLength(Registers, 32); 557 SetLength(Instructions, 29);558 Instructions[ 0] := InstNop;559 Instructions[ 1] := InstHalt;560 Instructions[ 2] := InstCopy;561 Instructions[ 3] := InstLoadConst;562 Instructions[ 4] := InstJump;563 Instructions[ 5] := InstJumpRel;564 Instructions[ 6] := InstLoadMem;565 Instructions[ 7] := InstStoreMem;566 Instructions[ 8] := InstClear;567 Instructions[ 9] := InstNeg;568 Instructions[ 10] := InstExchg;569 Instructions[ 11] := InstPop;570 Instructions[ 12] := InstPush;571 Instructions[ 13] := InstCall;572 Instructions[ 14] := InstRet;573 Instructions[ 15] := InstAdd;574 Instructions[ 16] := InstInc;575 Instructions[ 17] := InstDec;576 Instructions[ 18] := InstIn;577 Instructions[ 19] := InstOut;578 Instructions[ 20] := InstSub;579 Instructions[ 21] := InstShr;580 Instructions[ 22] := InstAddc;581 Instructions[ 23] := InstDataSize;582 Instructions[ 24] := InstDataPrefix8;583 Instructions[ 25] := InstDataPrefix16;584 Instructions[ 26] := InstDataPrefix32;585 Instructions[ 27] := InstDataPrefix64;586 Instructions[ 28] := InstAddrSize;626 Instructions[opNop] := InstNop; 627 Instructions[opHalt] := InstHalt; 628 Instructions[opCopy] := InstCopy; 629 Instructions[opLoadConst] := InstLoadConst; 630 Instructions[opJump] := InstJump; 631 Instructions[opJumpRel] := InstJumpRel; 632 Instructions[opLoadMem] := InstLoadMem; 633 Instructions[opStoreMem] := InstStoreMem; 634 Instructions[opClear] := InstClear; 635 Instructions[opNeg] := InstNeg; 636 Instructions[opExchg] := InstExchg; 637 Instructions[opPop] := InstPop; 638 Instructions[opPush] := InstPush; 639 Instructions[opCall] := InstCall; 640 Instructions[opRet] := InstRet; 641 Instructions[opAdd] := InstAdd; 642 Instructions[opAddc] := InstAddc; 643 Instructions[opSub] := InstSub; 644 Instructions[opInc] := InstInc; 645 Instructions[opDec] := InstDec; 646 Instructions[opIn] := InstIn; 647 Instructions[opOut] := InstOut; 648 Instructions[opShr] := InstShr; 649 Instructions[opShl] := InstShl; 650 Instructions[opDataSize] := InstDataSize; 651 Instructions[opDataPrefix8] := InstDataPrefix8; 652 Instructions[opDataPrefix16] := InstDataPrefix16; 653 Instructions[opDataPrefix32] := InstDataPrefix32; 654 Instructions[opDataPrefix32] := InstDataPrefix64; 655 Instructions[opAddrSize] := InstAddrSize; 587 656 end; 588 657 -
branches/virtualcpu4/UFormMain.lfm
r169 r170 1 object Form 1: TForm12 Left = 4643 Height = 3004 Top = 3025 Width = 4006 Caption = ' Form1'7 ClientHeight = 3008 ClientWidth = 4001 object FormMain: TFormMain 2 Left = 384 3 Height = 613 4 Top = 219 5 Width = 1178 6 Caption = 'VirtCpu4' 7 ClientHeight = 613 8 ClientWidth = 1178 9 9 DesignTimePPI = 120 10 10 OnCreate = FormCreate 11 11 OnDestroy = FormDestroy 12 OnShow = FormShow 12 13 LCLVersion = '2.0.0.4' 13 object Button Run: TButton14 Left = 7214 object ButtonStart: TButton 15 Left = 984 15 16 Height = 31 16 Top = 7917 Top = 8 17 18 Width = 94 18 Caption = ' Run'19 OnClick = Button RunClick19 Caption = 'Start' 20 OnClick = ButtonStartClick 20 21 TabOrder = 0 21 22 end 23 object ButtonStop: TButton 24 Left = 984 25 Height = 31 26 Top = 48 27 Width = 94 28 Caption = 'Stop' 29 OnClick = ButtonStopClick 30 TabOrder = 1 31 end 32 object Label1: TLabel 33 Left = 984 34 Height = 20 35 Top = 96 36 Width = 35 37 Caption = 'Ticks:' 38 ParentColor = False 39 end 40 object ListViewRegisters: TListView 41 Left = 8 42 Height = 592 43 Top = 8 44 Width = 312 45 Anchors = [akTop, akLeft, akBottom] 46 Columns = < 47 item 48 Caption = 'Register' 49 Width = 100 50 end 51 item 52 Width = 180 53 end> 54 Font.Height = -17 55 Font.Name = 'Liberation Mono' 56 OwnerData = True 57 ParentFont = False 58 TabOrder = 2 59 ViewStyle = vsReport 60 OnData = ListViewRegistersData 61 end 62 object ListViewMemory: TListView 63 Left = 328 64 Height = 592 65 Top = 8 66 Width = 648 67 Anchors = [akTop, akLeft, akBottom] 68 Columns = < 69 item 70 Caption = 'Address' 71 Width = 100 72 end 73 item 74 Width = 500 75 end> 76 Font.Height = -17 77 Font.Name = 'Liberation Mono' 78 OwnerData = True 79 ParentFont = False 80 TabOrder = 3 81 ViewStyle = vsReport 82 OnData = ListViewMemoryData 83 end 84 object Timer1: TTimer 85 Interval = 200 86 OnTimer = Timer1Timer 87 left = 96 88 top = 144 89 end 22 90 end -
branches/virtualcpu4/UFormMain.pas
r169 r170 6 6 7 7 uses 8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, UCpu; 8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, ExtCtrls, 9 ComCtrls, UCpu, UInstructionWriter; 9 10 10 11 type 11 12 12 { TForm 1}13 { TFormMain } 13 14 14 TForm1 = class(TForm) 15 ButtonRun: TButton; 16 procedure ButtonRunClick(Sender: TObject); 15 TFormMain = class(TForm) 16 ButtonStart: TButton; 17 ButtonStop: TButton; 18 Label1: TLabel; 19 ListViewMemory: TListView; 20 ListViewRegisters: TListView; 21 Timer1: TTimer; 22 procedure ButtonStartClick(Sender: TObject); 23 procedure ButtonStopClick(Sender: TObject); 17 24 procedure FormCreate(Sender: TObject); 18 25 procedure FormDestroy(Sender: TObject); 26 procedure FormShow(Sender: TObject); 27 procedure ListViewMemoryData(Sender: TObject; Item: TListItem); 28 procedure ListViewRegistersData(Sender: TObject; Item: TListItem); 29 procedure Timer1Timer(Sender: TObject); 19 30 private 20 31 procedure ReloadMemoryDump; 32 procedure ReloadRegisterDump; 33 procedure LoadProgram; 21 34 public 22 35 Cpu: TCpu; 36 InstructionWriter: TInstructionWriter; 23 37 end; 24 38 25 39 var 26 Form 1: TForm1;40 FormMain: TFormMain; 27 41 28 42 implementation … … 30 44 {$R *.lfm} 31 45 32 { TForm1 } 46 const 47 ItemsPerLine = 16; 33 48 34 procedure TForm1.ButtonRunClick(Sender: TObject); 49 { TFormMain } 50 51 procedure TFormMain.ButtonStartClick(Sender: TObject); 35 52 begin 36 Cpu. Run;53 Cpu.Start; 37 54 end; 38 55 39 procedure TForm1.FormCreate(Sender: TObject); 56 procedure TFormMain.ButtonStopClick(Sender: TObject); 57 begin 58 Cpu.Stop; 59 end; 60 61 procedure TFormMain.FormCreate(Sender: TObject); 40 62 begin 41 63 Cpu := TCpu.Create; 64 Cpu.DataSize := bw16; 65 Cpu.AddressSize := bw16; 66 InstructionWriter := TInstructionWriter.Create; 67 InstructionWriter.Cpu := Cpu; 42 68 end; 43 69 44 procedure TForm 1.FormDestroy(Sender: TObject);70 procedure TFormMain.FormDestroy(Sender: TObject); 45 71 begin 72 InstructionWriter.Free; 46 73 Cpu.Free; 47 74 end; 48 75 76 procedure TFormMain.FormShow(Sender: TObject); 77 begin 78 LoadProgram; 79 end; 80 81 procedure TFormMain.ListViewMemoryData(Sender: TObject; Item: TListItem); 82 var 83 Line: string; 84 I: Integer; 85 begin 86 if Item.Index < Length(Cpu.Memory) div ItemsPerLine then begin 87 Line := ''; 88 for I := 0 to ItemsPerLine - 1 do 89 Line := Line + IntToHex(Cpu.Memory[Item.Index * ItemsPerLine + I], 2) + ' '; 90 Item.Caption := IntToHex(Item.Index * ItemsPerLine, 8); 91 Item.SubItems.Add(Line); 92 end; 93 end; 94 95 procedure TFormMain.ListViewRegistersData(Sender: TObject; Item: TListItem); 96 begin 97 if Item.Index < Length(Cpu.Registers) + 2 then begin 98 if Item.Index = 0 then begin 99 Item.Caption := 'IP'; 100 Item.SubItems.Add(IntToHex(Cpu.IP, 16)); 101 end else 102 if Item.Index = 1 then begin 103 Item.Caption := 'SP'; 104 Item.SubItems.Add(IntToHex(Cpu.SP, 16)); 105 end else begin 106 Item.Caption := 'R' + IntToStr(Item.Index - 2); 107 Item.SubItems.Add(IntToHex(Cpu.Registers[Item.Index - 2].D, 16)); 108 end; 109 end; 110 end; 111 112 procedure TFormMain.Timer1Timer(Sender: TObject); 113 begin 114 Label1.Caption := 'Ticks: ' + IntToStr(Cpu.Ticks); 115 ReloadMemoryDump; 116 ReloadRegisterDump; 117 end; 118 119 procedure TFormMain.ReloadMemoryDump; 120 begin 121 ListViewMemory.Items.Count := Length(Cpu.Memory) div ItemsPerLine; 122 ListViewMemory.Refresh; 123 end; 124 125 procedure TFormMain.ReloadRegisterDump; 126 begin 127 ListViewRegisters.Items.Count := Length(Cpu.Registers); 128 ListViewRegisters.Refresh; 129 end; 130 131 procedure TFormMain.LoadProgram; 132 var 133 R1: Byte; 134 R2: Byte; 135 LabelStart: Integer; 136 begin 137 R1 := 1; 138 R2 := 2; 139 with InstructionWriter do begin 140 LoadConst(R1, 100); 141 LoadConst(R2, 100); 142 LabelStart := IP; 143 Increment(R1); 144 DataPrefix8; StoreMem(R2, R1); 145 Jump(LabelStart); 146 Halt; 147 end; 148 end; 149 150 49 151 end. 50 152 -
branches/virtualcpu4/virtucpu4.lpi
r169 r170 32 32 </Item1> 33 33 </RequiredPackages> 34 <Units Count=" 3">34 <Units Count="4"> 35 35 <Unit0> 36 36 <Filename Value="virtucpu4.lpr"/> … … 40 40 <Filename Value="UFormMain.pas"/> 41 41 <IsPartOfProject Value="True"/> 42 <ComponentName Value="Form1"/> 42 <ComponentName Value="FormMain"/> 43 <HasResources Value="True"/> 43 44 <ResourceBaseClass Value="Form"/> 44 45 </Unit1> … … 47 48 <IsPartOfProject Value="True"/> 48 49 </Unit2> 50 <Unit3> 51 <Filename Value="UInstructionWriter.pas"/> 52 <IsPartOfProject Value="True"/> 53 </Unit3> 49 54 </Units> 50 55 </ProjectOptions> -
branches/virtualcpu4/virtucpu4.lpr
r169 r170 17 17 Application.Scaled:=True; 18 18 Application.Initialize; 19 Application.CreateForm(TForm 1, Form1);19 Application.CreateForm(TFormMain, FormMain); 20 20 Application.Run; 21 21 end.
Note:
See TracChangeset
for help on using the changeset viewer.