Changeset 175 for branches/virtualcpu4
- Timestamp:
- Apr 12, 2019, 1:34:47 AM (6 years ago)
- Location:
- branches/virtualcpu4
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCpu.pas
r174 r175 153 153 154 154 procedure TCpu.InstLoadImmediate; 155 begin 156 case DataSize of 157 bw8: Registers[Read8].B := Read8; 158 bw16: Registers[Read8].W := Read16; 159 bw32: Registers[Read8].D := Read32; 160 bw64: Registers[Read8].Q := Read64; 155 var 156 R: TRegIndex; 157 begin 158 R := Read8; 159 case DataSize of 160 bw8: Registers[R].B := Read8; 161 bw16: Registers[R].W := Read16; 162 bw32: Registers[R].D := Read32; 163 bw64: Registers[R].Q := Read64; 161 164 end; 162 165 end; … … 219 222 220 223 procedure TCpu.InstLoadMem; 221 begin 222 case DataSize of 223 bw8: Registers[Read8].B := PByte(Memory + PAddress(@Registers[Read8])^)^; 224 bw16: Registers[Read8].W := PWord(Memory + PAddress(@Registers[Read8])^)^; 225 bw32: Registers[Read8].D := PDWord(Memory + PAddress(@Registers[Read8])^)^; 226 bw64: Registers[Read8].Q := PQWord(Memory + PAddress(@Registers[Read8])^)^; 224 var 225 R1, R2: TRegIndex; 226 begin 227 R1 := Read8; 228 R2 := Read8; 229 case AddressSize of 230 bw8: case DataSize of 231 bw8: Registers[R1].B := PByte(Memory + PByte(@Registers[R2])^)^; 232 bw16: Registers[R1].W := PWord(Memory + PByte(@Registers[R2])^)^; 233 bw32: Registers[R1].D := PDWord(Memory + PByte(@Registers[R2])^)^; 234 bw64: Registers[R1].Q := PQWord(Memory + PByte(@Registers[R2])^)^; 235 end; 236 bw16: case DataSize of 237 bw8: Registers[R1].B := PByte(Memory + PWord(@Registers[R2])^)^; 238 bw16: Registers[R1].W := PWord(Memory + PWord(@Registers[R2])^)^; 239 bw32: Registers[R1].D := PDWord(Memory + PWord(@Registers[R2])^)^; 240 bw64: Registers[R1].Q := PQWord(Memory + PWord(@Registers[R2])^)^; 241 end; 242 bw32: case DataSize of 243 bw8: Registers[R1].B := PByte(Memory + PDWord(@Registers[R2])^)^; 244 bw16: Registers[R1].W := PWord(Memory + PDWord(@Registers[R2])^)^; 245 bw32: Registers[R1].D := PDWord(Memory + PDWord(@Registers[R2])^)^; 246 bw64: Registers[R1].Q := PQWord(Memory + PDWord(@Registers[R2])^)^; 247 end; 248 bw64: case DataSize of 249 bw8: Registers[R1].B := PByte(Memory + PQWord(@Registers[R2])^)^; 250 bw16: Registers[R1].W := PWord(Memory + PQWord(@Registers[R2])^)^; 251 bw32: Registers[R1].D := PDWord(Memory + PQWord(@Registers[R2])^)^; 252 bw64: Registers[R1].Q := PQWord(Memory + PQWord(@Registers[R2])^)^; 253 end; 227 254 end; 228 255 end; 229 256 230 257 procedure TCpu.InstStoreMem; 231 begin 232 case DataSize of 233 bw8: PByte(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].B; 234 bw16: PWord(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].W; 235 bw32: PDWord(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].D; 236 bw64: PQWord(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].Q; 258 var 259 R1, R2: TRegIndex; 260 begin 261 R1 := Read8; 262 R2 := Read8; 263 case AddressSize of 264 bw8: case DataSize of 265 bw8: PByte(Memory + PByte(@Registers[R1])^)^ := Registers[R2].B; 266 bw16: PWord(Memory + PByte(@Registers[R1])^)^ := Registers[R2].W; 267 bw32: PDWord(Memory + PByte(@Registers[R1])^)^ := Registers[R2].D; 268 bw64: PQWord(Memory + PByte(@Registers[R1])^)^ := Registers[R2].Q; 269 end; 270 bw16: case DataSize of 271 bw8: PByte(Memory + PWord(@Registers[R1])^)^ := Registers[R2].B; 272 bw16: PWord(Memory + PWord(@Registers[R1])^)^ := Registers[R2].W; 273 bw32: PDWord(Memory + PWord(@Registers[R1])^)^ := Registers[R2].D; 274 bw64: PQWord(Memory + PWord(@Registers[R1])^)^ := Registers[R2].Q; 275 end; 276 bw32: case DataSize of 277 bw8: PByte(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].B; 278 bw16: PWord(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].W; 279 bw32: PDWord(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].D; 280 bw64: PQWord(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].Q; 281 end; 282 bw64: case DataSize of 283 bw8: PByte(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].B; 284 bw16: PWord(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].W; 285 bw32: PDWord(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].D; 286 bw64: PQWord(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].Q; 287 end; 237 288 end; 238 289 end; … … 436 487 procedure TCpu.InstDec; 437 488 var 438 R 1: TRegIndex;439 begin 440 R 1:= Read8;441 case DataSize of 442 bw8: Registers[R 1].B := Registers[R1].B - 1;443 bw16: Registers[R 1].W := Registers[R1].W - 1;444 bw32: Registers[R 1].D := Registers[R1].D - 1;445 bw64: Registers[R 1].Q := Registers[R1].Q - 1;489 R: TRegIndex; 490 begin 491 R := Read8; 492 case DataSize of 493 bw8: Registers[R].B := Registers[R].B - 1; 494 bw16: Registers[R].W := Registers[R].W - 1; 495 bw32: Registers[R].D := Registers[R].D - 1; 496 bw64: Registers[R].Q := Registers[R].Q - 1; 446 497 end; 447 498 end; … … 450 501 begin 451 502 case AddressSize of 452 bw8: if Z then IP := Read8 ;453 bw16: if Z then IP := Read16 ;454 bw32: if Z then IP := Read32 ;455 bw64: if Z then IP := Read64 ;503 bw8: if Z then IP := Read8 else Read8; 504 bw16: if Z then IP := Read16 else Read16; 505 bw32: if Z then IP := Read32 else Read32; 506 bw64: if Z then IP := Read64 else Read64; 456 507 end; 457 508 end; … … 460 511 begin 461 512 case AddressSize of 462 bw8: if not Z then IP := Read8 ;463 bw16: if not Z then IP := Read16 ;464 bw32: if not Z then IP := Read32 ;465 bw64: if not Z then IP := Read64 ;513 bw8: if not Z then IP := Read8 else Read8; 514 bw16: if not Z then IP := Read16 else Read16; 515 bw32: if not Z then IP := Read32 else Read32; 516 bw64: if not Z then IP := Read64 else Read64; 466 517 end; 467 518 end; … … 913 964 if Assigned(Instructions[TOpcode(Opcode)]) then Instructions[TOpcode(Opcode)] 914 965 else raise Exception.Create('Missing instruction handler for opcode '+ IntToStr(Opcode)); 915 end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP , 8) + '.');966 end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP - 1, 8) + '.'); 916 967 if DataSizeLast <> bwNone then begin 917 968 DataSize := DataSizeLast; -
branches/virtualcpu4/UFormMain.lfm
r173 r175 87 87 object Memo1: TMemo 88 88 Left = 1181 89 Height = 74389 Height = 344 90 90 Top = 192 91 91 Width = 518 … … 104 104 ParentFont = False 105 105 end 106 object PaintBox1: TPaintBox 107 Left = 1181 108 Height = 374 109 Top = 552 110 Width = 518 111 OnPaint = PaintBox1Paint 112 OnResize = PaintBox1Resize 113 end 106 114 object Timer1: TTimer 107 115 Interval = 100 … … 110 118 top = 173 111 119 end 120 object TimerDraw: TTimer 121 OnTimer = TimerDrawTimer 122 left = 104 123 top = 304 124 end 112 125 end -
branches/virtualcpu4/UFormMain.pas
r174 r175 21 21 ListViewRegisters: TListView; 22 22 Memo1: TMemo; 23 PaintBox1: TPaintBox; 23 24 Timer1: TTimer; 25 TimerDraw: TTimer; 24 26 procedure ButtonStartClick(Sender: TObject); 25 27 procedure ButtonStopClick(Sender: TObject); … … 30 32 procedure ListViewRegistersData(Sender: TObject; Item: TListItem); 31 33 procedure Memo1KeyPress(Sender: TObject; var Key: char); 34 procedure PaintBox1Paint(Sender: TObject); 35 procedure PaintBox1Resize(Sender: TObject); 32 36 procedure Timer1Timer(Sender: TObject); 37 procedure TimerDrawTimer(Sender: TObject); 33 38 private 34 39 procedure ReloadMemoryDump; … … 85 90 I: Integer; 86 91 begin 87 if Item.Index < Length(Machine.Memory)div ItemsPerLine then begin92 if Item.Index < Machine.MemorySize div ItemsPerLine then begin 88 93 Line := ''; 89 94 for I := 0 to ItemsPerLine - 1 do 90 Line := Line + IntToHex( Machine.Memory[Item.Index * ItemsPerLine + I], 2) + ' ';95 Line := Line + IntToHex(PByte(Machine.Memory + Item.Index * ItemsPerLine + I)^, 2) + ' '; 91 96 Item.Caption := IntToHex(Item.Index * ItemsPerLine, 8); 92 97 Item.SubItems.Add(Line); … … 118 123 end; 119 124 125 procedure TFormMain.PaintBox1Paint(Sender: TObject); 126 var 127 X, Y: Integer; 128 B: Byte; 129 MemorySizeTmp: Integer; 130 Addr: Integer; 131 begin 132 MemorySizeTmp := Machine.MemorySize; 133 with Machine, Screen do 134 for Y := 0 to Size.Y - 1 do 135 for X := 0 to Size.X - 1 do begin 136 Addr := MemoryBase + Y * Size.X + X; 137 if Addr < MemorySizeTmp then begin 138 B := PByte(Memory + Addr)^; 139 PaintBox1.Canvas.Pixels[X, Y] := B * $010101; 140 end; 141 end; 142 end; 143 144 procedure TFormMain.PaintBox1Resize(Sender: TObject); 145 begin 146 Machine.Screen.Size := Point(PaintBox1.Width, PaintBox1.Height); 147 end; 148 120 149 procedure TFormMain.Timer1Timer(Sender: TObject); 121 150 begin … … 129 158 end; 130 159 160 procedure TFormMain.TimerDrawTimer(Sender: TObject); 161 begin 162 PaintBox1.Repaint; 163 end; 164 131 165 procedure TFormMain.ReloadMemoryDump; 132 166 begin 133 ListViewMemory.Items.Count := Length(Machine.Memory)div ItemsPerLine;167 ListViewMemory.Items.Count := Machine.MemorySize div ItemsPerLine; 134 168 ListViewMemory.Refresh; 135 169 end; … … 146 180 R2: Byte; 147 181 R3: Byte; 182 R4: Byte; 148 183 LabelStart: Integer; 149 184 LabelText: Integer; 150 185 LabelPrint: Integer; 186 LabelClearScreen: Integer; 151 187 begin 152 188 R1 := 1; 153 189 R2 := 2; 154 190 R3 := 3; 191 R4 := 4; 155 192 with InstructionWriter do begin 193 // Print Hello world text 156 194 LabelText := 200; 157 195 Loadi(R1, LabelText); 158 196 Loadi(R2, 12); 159 197 LabelPrint := IP; 160 DataPrefix8; LoadMem(R3, R1);198 DataPrefix8; LoadMem(R3, R1); 161 199 DataPrefix8; Output(0, R3); 162 200 Increment(R1); … … 165 203 JumpNotZero(LabelPrint); 166 204 205 // Draw to video memory 206 Loadi(R1, Machine.Screen.MemoryBase); 207 Loadi(R2, $10000); 208 Loadi(R3, $7f); 209 LabelClearScreen := IP; 210 DataPrefix8; StoreMem(R1, R3); 211 Increment(R1); 212 Decrement(R2); 213 Test(R2); 214 JumpNotZero(LabelClearScreen); 215 216 // Read keyboard and print to console 167 217 Loadi(R1, 100); 168 218 LabelStart := IP; 169 219 Increment(R1); 170 Loadi(R2, 100);220 Loadi(R2, $100); 171 221 DataPrefix8; StoreMem(R2, R1); 172 222 DataPrefix8; Input(R2, 0); -
branches/virtualcpu4/UMachine.pas
r174 r175 11 11 TScreen = class 12 12 Size: TPoint; 13 MemoryBase: Integer; 13 14 end; 14 15 … … 19 20 function CpuInput(Port: TAddress): TRegister; 20 21 procedure CpuOutput(Port: TAddress; Value: TRegister); 22 function GetMemorySize: Integer; 23 procedure SetMemorySize(AValue: Integer); 21 24 public 22 Memory: array of Byte;25 Memory: Pointer; 23 26 Cpu: TCpu; 24 27 Screen: TScreen; … … 27 30 LockInput: TCriticalSection; 28 31 LockOutput: TCriticalSection; 32 property MemorySize: Integer read GetMemorySize write SetMemorySize; 29 33 constructor Create; 30 34 destructor Destroy; override; … … 42 46 Cpu.OnInput := CpuInput; 43 47 Cpu.OnOutput := CpuOutput; 44 Cpu.DataSize := bw 16;45 Cpu.AddressSize := bw 16;48 Cpu.DataSize := bw32; 49 Cpu.AddressSize := bw32; 46 50 Screen := TScreen.Create; 47 51 Screen.Size := Point(320, 240); 48 SetLength(Memory, 1000); 52 Screen.MemoryBase := $100; 53 MemorySize := $1000000; 49 54 Cpu.Memory := Memory; 50 55 end; … … 76 81 LockInput.Release; 77 82 end; 83 1: case Cpu.DataSize of 84 bw8: Result.B := Screen.Size.X; 85 bw16: Result.W := Screen.Size.X; 86 bw32: Result.D := Screen.Size.X; 87 bw64: Result.Q := Screen.Size.X; 88 end; 89 2: case Cpu.DataSize of 90 bw8: Result.B := Screen.Size.Y; 91 bw16: Result.W := Screen.Size.Y; 92 bw32: Result.D := Screen.Size.Y; 93 bw64: Result.Q := Screen.Size.Y; 94 end; 95 3: case Cpu.DataSize of 96 bw8: Result.B := Screen.MemoryBase; 97 bw16: Result.W := Screen.MemoryBase; 98 bw32: Result.D := Screen.MemoryBase; 99 bw64: Result.Q := Screen.MemoryBase; 100 end; 78 101 end; 79 102 end; … … 87 110 LockOutput.Release; 88 111 end; 112 1: case Cpu.DataSize of 113 bw8: Screen.Size.X := Value.B; 114 bw16: Screen.Size.X := Value.W; 115 bw32: Screen.Size.X := Value.D; 116 bw64: Screen.Size.X := Value.Q; 117 end; 118 2: case Cpu.DataSize of 119 bw8: Screen.Size.Y := Value.B; 120 bw16: Screen.Size.Y := Value.W; 121 bw32: Screen.Size.Y := Value.D; 122 bw64: Screen.Size.Y := Value.Q; 123 end; 124 3: case Cpu.DataSize of 125 bw8: Screen.MemoryBase := Value.B; 126 bw16: Screen.MemoryBase := Value.W; 127 bw32: Screen.MemoryBase := Value.D; 128 bw64: Screen.MemoryBase := Value.Q; 129 end; 89 130 end; 131 end; 132 133 function TMachine.GetMemorySize: Integer; 134 begin 135 Result := MemSize(Memory); 136 end; 137 138 procedure TMachine.SetMemorySize(AValue: Integer); 139 begin 140 Memory := ReAllocMem(Memory, AValue); 90 141 end; 91 142
Note:
See TracChangeset
for help on using the changeset viewer.