Changeset 215
- Timestamp:
- Aug 19, 2020, 11:54:20 PM (4 years ago)
- Location:
- branches/virtcpu fixed int
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtcpu fixed int/UFormMain.lfm
r168 r215 1 1 object Form1: TForm1 2 2 Left = 385 3 Height = 7623 Height = 914 4 4 Top = 208 5 Width = 1 2865 Width = 1543 6 6 Caption = 'Form1' 7 ClientHeight = 7628 ClientWidth = 1 2869 DesignTimePPI = 1 207 ClientHeight = 914 8 ClientWidth = 1543 9 DesignTimePPI = 144 10 10 OnCreate = FormCreate 11 11 OnDestroy = FormDestroy 12 12 OnKeyPress = FormKeyPress 13 13 OnShow = FormShow 14 LCLVersion = ' 1.8.2.0'14 LCLVersion = '2.0.10.0' 15 15 object ListViewMemory: TListView 16 Left = 51517 Height = 68718 Top = 4 019 Width = 73316 Left = 618 17 Height = 824 18 Top = 48 19 Width = 880 20 20 Columns = < 21 21 item 22 22 Caption = 'Address' 23 Width = 1 0023 Width = 120 24 24 end 25 25 item 26 Width = 50026 Width = 745 27 27 end> 28 28 Font.Name = 'Liberation Mono' … … 34 34 end 35 35 object ListViewRegisters: TListView 36 Left = 3 1237 Height = 68738 Top = 4 139 Width = 19236 Left = 374 37 Height = 824 38 Top = 49 39 Width = 230 40 40 Columns = < 41 41 item 42 42 Caption = 'Register' 43 Width = 8043 Width = 96 44 44 end 45 45 item 46 Width = 1 0046 Width = 120 47 47 end> 48 48 Font.Name = 'Liberation Mono' … … 54 54 end 55 55 object Memo1: TMemo 56 Left = 1 657 Height = 53158 Top = 2 459 Width = 28456 Left = 19 57 Height = 637 58 Top = 29 59 Width = 341 60 60 OnKeyPress = Memo1KeyPress 61 ParentFont = False 61 62 ReadOnly = True 62 63 TabOrder = 2 63 64 end 64 object Button 1: TButton65 Left = 2 0666 Height = 3 167 Top = 56868 Width = 9465 object ButtonStart: TButton 66 Left = 248 67 Height = 37 68 Top = 682 69 Width = 113 69 70 Caption = 'Start' 70 OnClick = Button1Click 71 OnClick = ButtonStartClick 72 ParentFont = False 71 73 TabOrder = 3 72 74 end 73 object Button 2: TButton74 Left = 8875 Height = 3 176 Top = 56877 Width = 9475 object ButtonStop: TButton 76 Left = 106 77 Height = 37 78 Top = 682 79 Width = 113 78 80 Caption = 'Stop' 79 OnClick = Button2Click 81 OnClick = ButtonStopClick 82 ParentFont = False 80 83 TabOrder = 4 81 84 end 82 85 object LabelTicks: TLabel 83 Left = 1 684 Height = 2 085 Top = 61286 Width = 3586 Left = 19 87 Height = 24 88 Top = 734 89 Width = 48 87 90 Caption = 'Ticks:' 88 91 ParentColor = False 92 ParentFont = False 89 93 end 90 94 object Timer1: TTimer 91 95 Interval = 500 92 96 OnTimer = Timer1Timer 93 left = 22694 top = 67597 Left = 271 98 Top = 810 95 99 end 96 100 end -
branches/virtcpu fixed int/UFormMain.pas
r168 r215 7 7 uses 8 8 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls, 9 StdCtrls, ExtCtrls, U Machine, UInstructionWriter;9 StdCtrls, ExtCtrls, UCpu, UInstructionWriter, UMachine; 10 10 11 11 type … … 14 14 15 15 TForm1 = class(TForm) 16 Button 1: TButton;17 Button 2: TButton;16 ButtonStart: TButton; 17 ButtonStop: TButton; 18 18 LabelTicks: TLabel; 19 19 ListViewMemory: TListView; … … 21 21 Memo1: TMemo; 22 22 Timer1: TTimer; 23 procedure Button 1Click(Sender: TObject);24 procedure Button 2Click(Sender: TObject);23 procedure ButtonStartClick(Sender: TObject); 24 procedure ButtonStopClick(Sender: TObject); 25 25 procedure FormCreate(Sender: TObject); 26 26 procedure FormDestroy(Sender: TObject); … … 32 32 procedure Timer1Timer(Sender: TObject); 33 33 private 34 KeyInputBuffer: array of Char;35 34 procedure ReloadMemoryDump; 36 35 procedure ReloadRegisterDump; 37 function CpuInput(Port: T): T; 38 procedure CpuOutput(Port, Value: T); 36 procedure SerialOutputExecute(Sender: TObject); 39 37 public 40 Cpu: TCPU;38 Machine: TMachine; 41 39 InstructionWriter: TInstructionWriter; 42 40 end; … … 87 85 Output(0, R1); 88 86 Subtract(R1, R4); 89 JumpZero(R1, LabelPrint); 87 TestZero(R1); 88 JumpCond(LabelPrint); 90 89 LabelPrintBack := IP; 91 90 Increment(R2); … … 101 100 procedure TForm1.FormDestroy(Sender: TObject); 102 101 begin 103 InstructionWriter.Free;104 Cpu.Free;102 FreeAndNil(InstructionWriter); 103 FreeAndNil(Machine); 105 104 end; 106 105 … … 111 110 procedure TForm1.FormCreate(Sender: TObject); 112 111 begin 113 Cpu := TCPU.Create(nil); 114 Cpu.OnInput := CpuInput; 115 Cpu.OnOutput := CpuOutput; 112 Machine := TMachine.Create(nil); 113 Machine.OnSerialOutput := SerialOutputExecute; 116 114 InstructionWriter := TInstructionWriter.Create; 117 InstructionWriter.Cpu := Cpu;115 InstructionWriter.Cpu := Machine.Cpu; 118 116 end; 119 117 120 procedure TForm1.Button 1Click(Sender: TObject);118 procedure TForm1.ButtonStartClick(Sender: TObject); 121 119 begin 122 Cpu.Start;120 Machine.Cpu.Start; 123 121 end; 124 122 125 procedure TForm1.Button 2Click(Sender: TObject);123 procedure TForm1.ButtonStopClick(Sender: TObject); 126 124 begin 127 Cpu.Stop;125 Machine.Cpu.Stop; 128 126 end; 129 127 … … 133 131 I: Integer; 134 132 begin 135 if Item.Index < Length( Cpu.Memory) div ItemsPerLine then begin133 if Item.Index < Length(Machine.Cpu.Memory) div ItemsPerLine then begin 136 134 Line := ''; 137 135 for I := 0 to ItemsPerLine - 1 do 138 Line := Line + IntToHex( Cpu.Memory[Item.Index * ItemsPerLine + I], 2) + ' ';136 Line := Line + IntToHex(Machine.Cpu.Memory[Item.Index * ItemsPerLine + I], 2) + ' '; 139 137 Item.Caption := IntToHex(Item.Index * ItemsPerLine, 8); 140 138 Item.SubItems.Add(Line); … … 144 142 procedure TForm1.ListViewRegistersData(Sender: TObject; Item: TListItem); 145 143 begin 146 if Item.Index < Length( Cpu.Registers) + 1 then begin144 if Item.Index < Length(Machine.Cpu.Registers) + 1 then begin 147 145 if Item.Index = 0 then begin 148 146 Item.Caption := 'IP'; 149 Item.SubItems.Add(IntToHex( Cpu.IP, 8));147 Item.SubItems.Add(IntToHex(Machine.Cpu.IP, 8)); 150 148 end else begin 151 149 Item.Caption := 'R' + IntToStr(Item.Index - 1); 152 Item.SubItems.Add(IntToHex( Cpu.Registers[Item.Index - 1], 8));150 Item.SubItems.Add(IntToHex(Machine.Cpu.Registers[Item.Index - 1], 8)); 153 151 end; 154 152 end; … … 157 155 procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: char); 158 156 begin 159 SetLength(KeyInputBuffer, Length(KeyInputBuffer) + 1); 160 KeyInputBuffer[High(KeyInputBuffer)] := Key; 157 Machine.SerialInput(Key); 161 158 end; 162 159 … … 165 162 ReloadMemoryDump; 166 163 ReloadRegisterDump; 167 LabelTicks.Caption := 'Ticks: ' + IntToStr( Cpu.Ticks);164 LabelTicks.Caption := 'Ticks: ' + IntToStr(Machine.Cpu.Ticks); 168 165 end; 169 166 170 167 procedure TForm1.ReloadMemoryDump; 171 168 begin 172 ListViewMemory.Items.Count := Length( Cpu.Memory) div ItemsPerLine;169 ListViewMemory.Items.Count := Length(Machine.Cpu.Memory) div ItemsPerLine; 173 170 ListViewMemory.Refresh; 174 171 end; … … 176 173 procedure TForm1.ReloadRegisterDump; 177 174 begin 178 ListViewRegisters.Items.Count := Length( Cpu.Registers);175 ListViewRegisters.Items.Count := Length(Machine.Cpu.Registers); 179 176 ListViewRegisters.Refresh; 180 177 end; 181 178 182 function TForm1.CpuInput(Port: T): T; 179 procedure TForm1.SerialOutputExecute(Sender: TObject); 180 var 181 Buffer: string; 183 182 begin 184 Result := 0; 185 case Port of 186 0: begin 187 while (Length(KeyInputBuffer) = 0) and not Cpu.Terminated do begin 188 Sleep(100); 189 Application.ProcessMessages; 190 end; 191 if Length(KeyInputBuffer) > 0 then begin 192 Result := Ord(KeyInputBuffer[0]); 193 if Length(KeyInputBuffer) > 1 then 194 Move(KeyInputBuffer[1], KeyInputBuffer[0], Length(KeyInputBuffer) - 1); 195 SetLength(KeyInputBuffer, Length(KeyInputBuffer) - 1); 196 end else Result := 0; 183 Machine.SerialBufferLock.Acquire; 184 try 185 if Length(Machine.SerialBufferOutput) > 0 then begin 186 SetLength(Buffer, Length(Machine.SerialBufferOutput)); 187 Move(Machine.SerialBufferOutput[0], Buffer[1], Length(Machine.SerialBufferOutput)); 188 Memo1.Lines.Text := Memo1.Lines.Text + Buffer; 189 SetLength(Machine.SerialBufferOutput, 0); 197 190 end; 198 end; 199 end; 200 201 procedure TForm1.CpuOutput(Port, Value: T); 202 begin 203 case Port of 204 0: Memo1.Lines.Text := Memo1.Lines.Text + Char(Value); 191 finally 192 Machine.SerialBufferLock.Release; 205 193 end; 206 194 end; -
branches/virtcpu fixed int/UInstructionWriter.pas
r168 r215 6 6 7 7 uses 8 Classes, SysUtils, U Machine;8 Classes, SysUtils, UCpu; 9 9 10 10 type … … 28 28 procedure Subtract(R1, R2: Integer); 29 29 procedure Jump(Addr: Integer); 30 procedure Jump NotZero(R1: Integer;Addr: Integer);31 procedure JumpZero(R1: Integer; Addr: Integer);30 procedure JumpCond(Addr: Integer); 31 procedure TestZero(R: Integer); 32 32 {$IFDEF EXT_REL_JUMP}procedure JumpRelative(Addr: Integer);{$ENDIF} 33 procedure SysCall; 33 34 procedure Increment(R: Integer); 34 35 procedure Decrement(R: Integer); … … 112 113 end; 113 114 114 procedure TInstructionWriter.Jump NotZero(R1: Integer;Addr: Integer);115 procedure TInstructionWriter.JumpCond(Addr: Integer); 115 116 begin 116 Write(T(opJumpNotZero)); 117 Write(R1); 117 Write(T(opJumpCond)); 118 118 Write(Addr); 119 119 end; 120 120 121 procedure TInstructionWriter. JumpZero(R1: Integer; Addr: Integer);121 procedure TInstructionWriter.TestZero(R: Integer); 122 122 begin 123 Write(T(opJumpZero)); 124 Write(R1); 125 Write(Addr); 123 Write(T(opTestZero)); 124 Write(R); 125 end; 126 127 procedure TInstructionWriter.SysCall; 128 begin 129 Write(T(opSysCall)); 126 130 end; 127 131 -
branches/virtcpu fixed int/UMachine.pas
r168 r215 1 1 unit UMachine; 2 2 3 {$DEFINE EXT_MEMORY} 4 {$DEFINE EXT_IO} 5 {$DEFINE EXT_ARITHMETIC} 6 {$DEFINE EXT_CONDITIONAL} 7 {$DEFINE EXT_LOGICAL} 8 {$DEFINE EXT_STACK} 9 {$DEFINE EXT_SUBROUTINE} 10 {$DEFINE EXT_ROTATION} 11 {$DEFINE EXT_MULTIPLICATION} 12 {$DEFINE EXT_SHIFT} 13 {$DEFINE EXT_BLOCK} 14 {$DEFINE EXT_GENERAL} 15 {$DEFINE EXT_BIT} 16 {$DEFINE EXT_REL_JUMP} 17 18 // Extension dependencies 19 {$IFDEF EXT_SUBROUTINE} 20 {$DEFINE EXT_STACK} 21 {$ENDIF} 22 {$IFDEF EXT_MULTIPLICATION} 23 {$DEFINE EXT_ARITHMETIC} 24 {$ENDIF} 25 26 27 {$mode delphi}{$H+} 3 {$mode delphi} 28 4 29 5 interface 30 6 31 7 uses 32 Classes, SysUtils ;8 Classes, SysUtils, UCpu, syncobjs; 33 9 34 10 type 35 T = Integer;11 { TMachine } 36 12 37 TOpcode = (opNop, opLoad, opLoadConst, opNeg, 38 opJump, {$IFDEF EXT_REL_JUMP}opJumpRel,{$ENDIF} 39 opInc, opDec, 40 {$IFDEF EXT_MEMORY}opLoadMem, opStoreMem,{$ENDIF} 41 {$IFDEF EXT_ARITHMETIC}opAdd, opSub,{$ENDIF} 42 {$IFDEF EXT_IO}opInput, opOutput,{$ENDIF} 43 {$IFDEF EXT_SUBROUTINE}opCall, 44 {$IFDEF EXT_REL_JUMP}opCallRel,{$ENDIF} 45 opRet,{$ENDIF} 46 {$IFDEF EXT_GENERAL}opExchg,{$ENDIF} 47 {$IFDEF EXT_LOGICAL}opAnd, opOr, opXor,{$ENDIF} 48 {$IFDEF EXT_SHIFT}opShl, opShr,{$ENDIF} 49 {$IFDEF EXT_ROTATION}opRor, opRol,{$ENDIF} 50 {$IFDEF EXT_STACK}opPush, opPop,{$ENDIF} 51 {$IFDEF EXT_CONDITIONAL} 52 {$IFDEF EXT_REL_JUMP}opJumpRelZero, opJumpRelNotZero,{$ENDIF} 53 opJumpZero, opJumpNotZero, opTestEqual, opTestNotEqual, opTestLess, 54 opTestLessEqual, opTestGreater, opTestGreaterEqual, 55 {$ENDIF} 56 {$IFDEF EXT_MULTIPLICATION} 57 opMul, opDiv, 58 {$ENDIF} 59 opHalt 60 ); 61 62 TOpcodeHandler = procedure of object; 63 TInputEvent = function (Port: T): T of object; 64 TOutputEvent = procedure (Port, Value: T) of object; 65 66 { TCPU } 67 68 TCPU = class(TComponent) 13 TMachine = class(TComponent) 69 14 private 70 FOnInput: TInputEvent; 71 FOnOutput: TOutputEvent; 72 OpcodeHandlers: array[TOpcode] of TOpcodeHandler; 73 function ReadNext: T; inline; 74 procedure OpcodeNop; 75 procedure OpcodeHalt; 76 procedure OpcodeLoad; 77 procedure OpcodeLoadConst; 78 procedure OpcodeJump; 79 {$IFDEF EXT_REL_JUMP} 80 procedure OpcodeJumpRel; 81 {$ENDIF} 82 procedure OpcodeNeg; 83 procedure OpcodeInc; 84 procedure OpcodeDec; 85 {$IFDEF EXT_MEMORY} 86 procedure OpcodeLoadMem; 87 procedure OpcodeStoreMem; 88 {$ENDIF} 89 {$IFDEF EXT_GENERAL} 90 procedure OpcodeExchange; 91 {$ENDIF} 92 {$IFDEF EXT_CONDITIONAL} 93 procedure OpcodeTestEqual; 94 procedure OpcodeTestNotEqual; 95 procedure OpcodeTestGreatEqual; 96 procedure OpcodeTestGreat; 97 procedure OpcodeTestLessEqual; 98 procedure OpcodeTestLess; 99 procedure OpcodeJumpCondNotZero; 100 procedure OpcodeJumpCondZero; 101 {$IFDEF EXT_REL_JUMP} 102 procedure OpcodeJumpRelCondNotZero; 103 procedure OpcodeJumpRelCondZero; 104 {$ENDIF} 105 {$ENDIF} 106 {$IFDEF EXT_SHIFT} 107 procedure OpcodeShl; 108 procedure OpcodeShr; 109 {$ENDIF} 110 {$IFDEF EXT_ROTATION} 111 procedure OpcodeRor; 112 procedure OpcodeRol; 113 {$ENDIF} 114 {$IFDEF EXT_LOGICAL} 115 procedure OpcodeAnd; 116 procedure OpcodeOr; 117 procedure OpcodeXor; 118 {$ENDIF} 119 {$IFDEF EXT_STACK} 120 procedure OpcodePush; 121 procedure OpcodePop; 122 {$ENDIF} 123 {$IFDEF EXT_SUBROUTINE} 124 procedure OpcodeCall; 125 procedure OpcodeReturn; 126 {$IFDEF EXT_REL_JUMP} 127 procedure OpcodeCallRel; 128 {$ENDIF} 129 {$ENDIF} 130 {$IFDEF EXT_IO} 131 procedure OpcodeOutput; 132 procedure OpcodeInput; 133 {$ENDIF} 134 {$IFDEF EXT_ARITHMETIC} 135 procedure OpcodeAdd; 136 procedure OpcodeSub; 137 {$ENDIF} 138 {$IFDEF EXT_MULTIPLICATION} 139 procedure OpcodeMul; 140 procedure OpcodeDiv; 141 {$ENDIF} 15 FOnSerialOutput: TNotifyEvent; 16 function CpuInput(Port: T): T; 17 procedure CpuOutput(Port, Value: T); 18 procedure DoSerialOutput; 142 19 public 143 Registers: array of T;144 IP: T;145 {$IFDEF EXT_STACK}146 SP: T;147 {$ENDIF}148 20 Memory: array of T; 149 Terminated: Boolean; 150 Ticks: Integer; 151 procedure Start; 152 procedure Stop; 21 Cpu: TCpu; 22 VideoBase: T; 23 VideoWidth: T; 24 VideoHeight: T; 25 SerialBufferInput: array of Char; 26 SerialBufferOutput: array of Char; 27 SerialBufferLock: TCriticalSection; 153 28 constructor Create(AOwner: TComponent); override; 154 published155 pro perty OnInput: TInputEvent read FOnInput write FOnInput;156 property On Output: TOutputEvent read FOnOutput write FOnOutput;29 destructor Destroy; override; 30 procedure SerialInput(C: Char); 31 property OnSerialOutput: TNotifyEvent read FOnSerialOutput write FOnSerialOutput; 157 32 end; 158 159 33 160 34 implementation 161 35 162 { T CPU}36 { TMachine } 163 37 164 function TCPU.ReadNext: T;38 constructor TMachine.Create(AOwner: TComponent); 165 39 begin 166 Result := Memory[IP]; 167 Inc(IP); 40 inherited; 41 SerialBufferLock := TCriticalSection.Create; 42 Cpu := TCpu.Create(nil); 43 Cpu.OnInput := CpuInput; 44 Cpu.OnOutput := CpuOutput; 168 45 end; 169 46 170 procedure TCPU.OpcodeHalt;47 destructor TMachine.Destroy; 171 48 begin 172 Terminated := True; 49 Cpu.Stop; 50 FreeAndNil(Cpu); 51 FreeAndNil(SerialBufferLock); 52 inherited; 173 53 end; 174 54 175 procedure T CPU.OpcodeNop;55 procedure TMachine.SerialInput(C: Char); 176 56 begin 177 // Do nothing 178 end; 179 180 procedure TCPU.OpcodeLoad; 181 var 182 P1: T; 183 P2: T; 184 begin 185 P1 := ReadNext; 186 P2 := ReadNext; 187 Registers[P1] := Registers[P2]; 188 end; 189 190 procedure TCPU.OpcodeLoadConst; 191 var 192 P1: T; 193 P2: T; 194 begin 195 P1 := ReadNext; 196 P2 := ReadNext; 197 Registers[P1] := P2; 198 end; 199 200 {$IFDEF EXT_MEMORY} 201 procedure TCPU.OpcodeLoadMem; 202 var 203 P1: T; 204 P2: T; 205 begin 206 P1 := ReadNext; 207 P2 := ReadNext; 208 Registers[P1] := Memory[Registers[P2]]; 209 end; 210 211 procedure TCPU.OpcodeStoreMem; 212 var 213 P1: T; 214 P2: T; 215 begin 216 P1 := ReadNext; 217 P2 := ReadNext; 218 Memory[Registers[P1]] := Registers[P2]; 219 end; 220 {$ENDIF} 221 222 procedure TCPU.OpcodeNeg; 223 var 224 P1: T; 225 begin 226 P1 := ReadNext; 227 Registers[P1] := -Registers[P1]; 228 end; 229 230 {$IFDEF EXT_GENERAL} 231 procedure TCPU.OpcodeExchange; 232 var 233 P1, P2, Temp: T; 234 begin 235 P1 := ReadNext; 236 P2 := ReadNext; 237 Temp := Registers[P1]; 238 Registers[P1] := Registers[P2]; 239 Registers[P2] := Temp; 240 end; 241 {$ENDIF} 242 243 procedure TCPU.OpcodeJump; 244 begin 245 IP := ReadNext; 246 end; 247 248 {$IFDEF EXT_REL_JUMP} 249 procedure TCPU.OpcodeJumpRel; 250 begin 251 IP := IP + ReadNext; 252 end; 253 {$ENDIF} 254 255 {$IFDEF EXT_CONDITIONAL} 256 procedure TCPU.OpcodeTestEqual; 257 var 258 P1, P2: T; 259 begin 260 P1 := ReadNext; 261 P2 := ReadNext; 262 if Registers[P1] = Registers[P2] then Registers[P1] := 1 263 else Registers[P1] := 0; 264 end; 265 266 procedure TCPU.OpcodeTestNotEqual; 267 var 268 P1, P2: T; 269 begin 270 P1 := ReadNext; 271 P2 := ReadNext; 272 if Registers[P1] <> Registers[P2] then Registers[P1] := 1 273 else Registers[P1] := 0; 274 end; 275 276 procedure TCPU.OpcodeTestGreatEqual; 277 var 278 P1, P2: T; 279 begin 280 P1 := ReadNext; 281 P2 := ReadNext; 282 if Registers[P1] >= Registers[P2] then Registers[P1] := 1 283 else Registers[P1] := 0; 284 end; 285 286 procedure TCPU.OpcodeTestGreat; 287 var 288 P1, P2: T; 289 begin 290 P1 := ReadNext; 291 P2 := ReadNext; 292 if Registers[P1] > Registers[P2] then Registers[P1] := 1 293 else Registers[P1] := 0; 294 end; 295 296 procedure TCPU.OpcodeTestLessEqual; 297 var 298 P1, P2: T; 299 begin 300 P1 := ReadNext; 301 P2 := ReadNext; 302 if Registers[P1] <= Registers[P2] then Registers[P1] := 1 303 else Registers[P1] := 0; 304 end; 305 306 procedure TCPU.OpcodeTestLess; 307 var 308 P1, P2: T; 309 begin 310 P1 := ReadNext; 311 P2 := ReadNext; 312 if Registers[P1] < Registers[P2] then Registers[P1] := 1 313 else Registers[P1] := 0; 314 end; 315 316 procedure TCPU.OpcodeJumpCondNotZero; 317 var 318 P1, P2: T; 319 begin 320 P1 := ReadNext; 321 P2 := ReadNext; 322 if Registers[P1] <> 0 then IP := P2; 323 end; 324 325 procedure TCPU.OpcodeJumpCondZero; 326 var 327 P1, P2: T; 328 begin 329 P1 := ReadNext; 330 P2 := ReadNext; 331 if Registers[P1] = 0 then IP := P2; 332 end; 333 334 {$IFDEF EXT_REL_JUMP} 335 procedure TCPU.OpcodeJumpRelCondZero; 336 var 337 P1, P2: T; 338 begin 339 P1 := ReadNext; 340 P2 := ReadNext; 341 if P1 = 0 then IP := IP + P2; 342 end; 343 344 procedure TCPU.OpcodeJumpRelCondNotZero; 345 var 346 P1, P2: T; 347 begin 348 P1 := ReadNext; 349 P2 := ReadNext; 350 if P1 <> 0 then IP := IP + P2; 351 end; 352 {$ENDIF} 353 {$ENDIF} 354 355 {$IFDEF EXT_ROTATION} 356 procedure TCPU.OpcodeRor; 357 var 358 P1, P2: T; 359 begin 360 P1 := ReadNext; 361 P2 := ReadNext; 362 Registers[P1] := (Registers[P1] shr Registers[P2]) or 363 ((Registers[P1] and ((1 shl Registers[P2]) - 1)) shl (SizeOf(T) * 8 - Registers[P2])); 364 end; 365 366 procedure TCPU.OpcodeRol; 367 var 368 P1, P2: T; 369 begin 370 P1 := ReadNext; 371 P2 := ReadNext; 372 Registers[P1] := (Registers[P1] shl Registers[P2]) or 373 ((Registers[P1] shr (SizeOf(T) * 8 - Registers[P2])) and ((1 shl Registers[P2]) - 1)); 374 end; 375 {$ENDIF} 376 377 {$IFDEF EXT_SHIFT} 378 procedure TCPU.OpcodeShl; 379 var 380 P1, P2: T; 381 begin 382 P1 := ReadNext; 383 P2 := ReadNext; 384 Registers[P1] := Registers[P1] shl Registers[P2]; 385 end; 386 387 procedure TCPU.OpcodeShr; 388 var 389 P1, P2: T; 390 begin 391 P1 := ReadNext; 392 P2 := ReadNext; 393 Registers[P1] := Registers[P1] shr Registers[P2]; 394 end; 395 {$ENDIF} 396 397 {$IFDEF EXT_LOGICAL} 398 procedure TCPU.OpcodeAnd; 399 var 400 P1, P2: T; 401 begin 402 P1 := ReadNext; 403 P2 := ReadNext; 404 Registers[P1] := Registers[P1] and Registers[P2]; 405 end; 406 407 procedure TCPU.OpcodeOr; 408 var 409 P1, P2: T; 410 begin 411 P1 := ReadNext; 412 P2 := ReadNext; 413 Registers[P1] := Registers[P1] or Registers[P2]; 414 end; 415 416 procedure TCPU.OpcodeXor; 417 var 418 P1, P2: T; 419 begin 420 P1 := ReadNext; 421 P2 := ReadNext; 422 Registers[P1] := Registers[P1] xor Registers[P2]; 423 end; 424 {$ENDIF} 425 426 {$IFDEF EXT_STACK} 427 procedure TCPU.OpcodePush; 428 begin 429 Memory[SP] := Registers[ReadNext]; 430 Dec(SP); 431 end; 432 433 procedure TCPU.OpcodePop; 434 begin 435 Inc(SP); 436 Registers[ReadNext] := Memory[SP]; 437 end; 438 {$ENDIF} 439 440 {$IFDEF EXT_SUBROUTINE} 441 procedure TCPU.OpcodeCall; 442 var 443 Addr: T; 444 begin 445 Addr := ReadNext; 446 Memory[SP] := IP; 447 Dec(SP); 448 IP := Addr; 449 end; 450 451 {$IFDEF EXT_REL_JUMP} 452 procedure TCPU.OpcodeCallRel; 453 var 454 Addr: T; 455 begin 456 Addr := ReadNext; 457 Memory[SP] := IP; 458 Dec(SP); 459 IP := IP + Addr; 460 end; 461 {$ENDIF} 462 463 procedure TCPU.OpcodeReturn; 464 begin 465 Inc(SP); 466 IP := Memory[SP]; 467 end; 468 {$ENDIF} 469 470 {$IFDEF EXT_IO} 471 procedure TCPU.OpcodeOutput; 472 var 473 R1: T; 474 R2: T; 475 begin 476 R1 := ReadNext; 477 R2 := ReadNext; 478 if Assigned(FOnOutput) then 479 FOnOutput(Registers[R1], Registers[R2]); 480 end; 481 482 procedure TCPU.OpcodeInput; 483 var 484 R1: T; 485 R2: T; 486 begin 487 R1 := ReadNext; 488 R2 := ReadNext; 489 if Assigned(FOnInput) then 490 Registers[R1] := FOnInput(Registers[R2]); 491 end; 492 {$ENDIF} 493 494 procedure TCPU.OpcodeInc; 495 var 496 R: T; 497 begin 498 R := ReadNext; 499 Registers[R] := Registers[R] + 1; 500 end; 501 502 procedure TCPU.OpcodeDec; 503 var 504 R: T; 505 begin 506 R := ReadNext; 507 Registers[R] := Registers[R] - 1; 508 end; 509 510 {$IFDEF EXT_ARITHMETIC} 511 procedure TCPU.OpcodeAdd; 512 var 513 R1: T; 514 R2: T; 515 begin 516 R1 := ReadNext; 517 R2 := ReadNext; 518 Registers[R1] := Registers[R1] + Registers[R2]; 519 end; 520 521 procedure TCPU.OpcodeSub; 522 var 523 R1: T; 524 R2: T; 525 begin 526 R1 := ReadNext; 527 R2 := ReadNext; 528 Registers[R1] := Registers[R1] - Registers[R2]; 529 end; 530 {$ENDIF} 531 532 {$IFDEF EXT_MULTIPLICATION} 533 procedure TCPU.OpcodeMul; 534 var 535 R1: T; 536 R2: T; 537 begin 538 R1 := ReadNext; 539 R2 := ReadNext; 540 Registers[R1] := Registers[R1] * Registers[R2]; 541 end; 542 543 procedure TCPU.OpcodeDiv; 544 var 545 R1: T; 546 R2: T; 547 begin 548 R1 := ReadNext; 549 R2 := ReadNext; 550 Registers[R1] := Registers[R1] div Registers[R2]; 551 end; 552 {$ENDIF} 553 554 procedure TCPU.Start; 555 var 556 Opcode: T; 557 begin 558 Terminated := False; 559 IP := 0; 560 Ticks := 0; 561 {$IFDEF EXT_STACK} 562 SP := Length(Memory); 563 {$ENDIF} 564 while not Terminated do begin 565 Opcode := ReadNext; 566 if (Opcode >= 0) and (Opcode <= T(High(TOpcode))) then 567 OpcodeHandlers[TOpcode(Opcode)] 568 else raise Exception.Create(Format('Unsupported instruction %d', [Opcode])); 569 Inc(Ticks); 57 SerialBufferLock.Acquire; 58 try 59 SetLength(SerialBufferInput, Length(SerialBufferInput) + 1); 60 SerialBufferInput[High(SerialBufferInput)] := C; 61 finally 62 SerialBufferLock.Release; 570 63 end; 571 64 end; 572 65 573 procedure TCPU.Stop;66 function TMachine.CpuInput(Port: T): T; 574 67 begin 575 Terminated := True; 68 Result := 0; 69 case Port of 70 0: begin 71 SerialBufferLock.Acquire; 72 try 73 while (Length(SerialBufferInput) = 0) and not Cpu.Terminated do begin 74 try 75 SerialBufferLock.Release; 76 Sleep(10); 77 finally 78 SerialBufferLock.Acquire; 79 end; 80 end; 81 if Length(SerialBufferInput) > 0 then begin 82 Result := Ord(SerialBufferInput[0]); 83 if Length(SerialBufferInput) > 1 then 84 Move(SerialBufferInput[1], SerialBufferInput[0], Length(SerialBufferInput) - 1); 85 SetLength(SerialBufferInput, Length(SerialBufferInput) - 1); 86 end else Result := 0; 87 finally 88 SerialBufferLock.Release; 89 end; 90 end; 91 1: begin 92 Result := Length(SerialBufferInput); 93 end; 94 end; 576 95 end; 577 96 578 constructor TCPU.Create(AOwner: TComponent);97 procedure TMachine.CpuOutput(Port, Value: T); 579 98 begin 580 inherited; 581 SetLength(Registers, 16); 582 SetLength(Memory, 1024); 583 OpcodeHandlers[opNop] := OpcodeNop; 584 OpcodeHandlers[opLoad] := OpcodeLoad; 585 OpcodeHandlers[opHalt] := OpcodeHalt; 586 OpcodeHandlers[opLoadConst] := OpcodeLoadConst; 587 OpcodeHandlers[opNeg] := OpcodeNeg; 588 OpcodeHandlers[opJump] := OpcodeJump; 589 OpcodeHandlers[opInc] := OpcodeInc; 590 OpcodeHandlers[opDec] := OpcodeDec; 591 {$IFDEF EXT_REL_JUMP} 592 OpcodeHandlers[opJumpRel] := OpcodeJumpRel; 593 {$ENDIF} 594 {$IFDEF EXT_MEMORY} 595 OpcodeHandlers[opLoadMem] := OpcodeLoadMem; 596 OpcodeHandlers[opStoreMem] := OpcodeStoreMem; 597 {$ENDIF} 598 {$IFDEF EXT_GENERAL} 599 OpcodeHandlers[opExchg] := OpcodeExchange; 600 {$ENDIF} 601 {$IFDEF EXT_LOGICAL} 602 OpcodeHandlers[opAnd] := OpcodeAnd; 603 OpcodeHandlers[opOr] := OpcodeOr; 604 OpcodeHandlers[opXor] := OpcodeXor; 605 {$ENDIF} 606 {$IFDEF EXT_SHIFT} 607 OpcodeHandlers[opShl] := OpcodeShl; 608 OpcodeHandlers[opShr] := OpcodeShr; 609 {$ENDIF} 610 {$IFDEF EXT_STACK} 611 OpcodeHandlers[opPush] := OpcodePush; 612 OpcodeHandlers[opPop] := OpcodePop; 613 {$ENDIF} 614 {$IFDEF EXT_SUBROUTINE} 615 OpcodeHandlers[opCall] := OpcodeCall; 616 {$IFDEF EXT_REL_JUMP} 617 OpcodeHandlers[opCallRel] := OpcodeCallRel; 618 {$ENDIF} 619 OpcodeHandlers[opRet] := OpcodeReturn; 620 {$ENDIF} 621 {$IFDEF EXT_ROTATION} 622 OpcodeHandlers[opRor] := OpcodeRor; 623 OpcodeHandlers[opRol] := OpcodeRol; 624 {$ENDIF} 625 {$IFDEF EXT_IO} 626 OpcodeHandlers[opInput] := OpcodeInput; 627 OpcodeHandlers[opOutput] := OpcodeOutput; 628 {$ENDIF} 629 {$IFDEF EXT_ARITHMETIC} 630 OpcodeHandlers[opAdd] := OpcodeAdd; 631 OpcodeHandlers[opSub] := OpcodeSub; 632 {$ENDIF} 633 {$IFDEF EXT_CONDITIONAL} 634 OpcodeHandlers[opJumpZero] := OpcodeJumpCondZero; 635 OpcodeHandlers[opJumpNotZero] := OpcodeJumpCondNotZero; 636 {$IFDEF EXT_REL_JUMP} 637 OpcodeHandlers[opJumpRelZero] := OpcodeJumpRelCondZero; 638 OpcodeHandlers[opJumpRelNotZero] := OpcodeJumpRelCondNotZero; 639 {$ENDIF} 640 OpcodeHandlers[opTestEqual] := OpcodeTestEqual; 641 OpcodeHandlers[opTestNotEqual] := OpcodeTestNotEqual; 642 OpcodeHandlers[opTestLess] := OpcodeTestLess; 643 OpcodeHandlers[opTestLessEqual] := OpcodeTestLessEqual; 644 OpcodeHandlers[opTestGreater] := OpcodeTestGreat; 645 OpcodeHandlers[opTestGreaterEqual] := OpcodeTestGreatEqual; 646 {$ENDIF} 647 {$IFDEF EXT_MULTIPLICATION} 648 OpcodeHandlers[opMul] := OpcodeMul; 649 OpcodeHandlers[opDiv] := OpcodeDiv; 650 {$ENDIF} 99 case Port of 100 0: begin 101 SerialBufferLock.Acquire; 102 try 103 SetLength(SerialBufferOutput, Length(SerialBufferOutput) + 1); 104 SerialBufferOutput[High(SerialBufferOutput)] := Chr(Value); 105 finally 106 SerialBufferLock.Release; 107 end; 108 TThread.Synchronize(Cpu.Thread, DoSerialOutput); 109 end; 110 end; 111 end; 112 113 procedure TMachine.DoSerialOutput; 114 begin 115 if Assigned(FOnSerialOutput) then 116 FOnSerialOutput(Self); 651 117 end; 652 118 -
branches/virtcpu fixed int/virtcpu.lpi
r166 r215 2 2 <CONFIG> 3 3 <ProjectOptions> 4 <Version Value="1 0"/>4 <Version Value="11"/> 5 5 <PathDelim Value="\"/> 6 6 <General> … … 47 47 </Options> 48 48 </Linking> 49 <Other> 50 <CustomOptions Value="-dUseCThreads"/> 51 </Other> 49 52 </CompilerOptions> 50 53 </Item2> … … 54 57 </PublishOptions> 55 58 <RunParams> 56 <local> 57 <FormatVersion Value="1"/> 58 </local> 59 <FormatVersion Value="2"/> 60 <Modes Count="1"> 61 <Mode0 Name="default"/> 62 </Modes> 59 63 </RunParams> 60 64 <RequiredPackages Count="1"> … … 63 67 </Item1> 64 68 </RequiredPackages> 65 <Units Count=" 4">69 <Units Count="5"> 66 70 <Unit0> 67 71 <Filename Value="virtcpu.lpr"/> … … 76 80 </Unit1> 77 81 <Unit2> 78 <Filename Value="U Machine.pas"/>82 <Filename Value="UCpu.pas"/> 79 83 <IsPartOfProject Value="True"/> 80 84 </Unit2> … … 83 87 <IsPartOfProject Value="True"/> 84 88 </Unit3> 89 <Unit4> 90 <Filename Value="UMachine.pas"/> 91 <IsPartOfProject Value="True"/> 92 </Unit4> 85 93 </Units> 86 94 </ProjectOptions> … … 125 133 </Options> 126 134 </Linking> 135 <Other> 136 <CustomOptions Value="-dUseCThreads"/> 137 </Other> 127 138 </CompilerOptions> 128 139 <Debugging> -
branches/virtcpu fixed int/virtcpu.lpr
r163 r215 8 8 {$ENDIF}{$ENDIF} 9 9 Interfaces, // this includes the LCL widgetset 10 Forms, UFormMain, U Machine, UInstructionWriter10 Forms, UFormMain, UCpu, UInstructionWriter, UMachine 11 11 { you can add units after this }; 12 12
Note:
See TracChangeset
for help on using the changeset viewer.