Changeset 156
- Timestamp:
- Apr 24, 2018, 9:54:30 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu3/UMachine.pas
r155 r156 11 11 TOpcode = (opNop, opHalt, opLD, opLDC, opLDM, opSTM, opInc, opDec, opJP, opJr, 12 12 opPush, opPop, opCall, opRet, opAdd, opSub, opMul, opDiv, opShr, opShl, 13 opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc, opTstZ, opTstNZ); 13 opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc, opTstZ, opTstNZ, 14 opLDMD, opSTMD); 15 16 TOpcodeHandler = procedure of object; 14 17 15 18 { TCPU } … … 21 24 var 22 25 Terminated: Boolean; 26 OpcodeHandlers: array[TOpcode] of TOpcodeHandler; 23 27 function ReadNext: T; 24 28 procedure Step; 29 procedure AddOpcode(Opcode: TOpcode; Handler: TOpcodeHandler); 30 procedure InitOpcodes; 25 31 private 26 32 FOnInput: TInputEvent; 27 33 FOnOutput: TOutputEvent; 28 34 Condition: Boolean; 35 procedure OpcodeAddition; 36 procedure OpcodeAnd; 37 procedure OpcodeCall; 38 procedure OpcodeDecrement; 39 procedure OpcodeDivision; 40 procedure OpcodeExchange; 41 procedure OpcodeHalt; 42 procedure OpcodeIncrement; 43 procedure OpcodeInput; 44 procedure OpcodeJump; 45 procedure OpcodeJumpConditional; 46 procedure OpcodeJumpRelative; 47 procedure OpcodeJumpRelativeConditional; 48 procedure OpcodeLoad; 49 procedure OpcodeLoadConst; 50 procedure OpcodeLoadMemory; 51 procedure OpcodeLoadMemoryDisplacement; 52 procedure OpcodeMultiplication; 53 procedure OpcodeNop; 54 procedure OpcodeOr; 55 procedure OpcodeOutput; 56 procedure OpcodePop; 57 procedure OpcodePush; 58 procedure OpcodeReturn; 59 procedure OpcodeShiftLeft; 60 procedure OpcodeShiftRight; 61 procedure OpcodeStoreMemory; 62 procedure OpcodeStoreMemoryDisplacement; 63 procedure OpcodeSubtraction; 64 procedure OpcodeTestNotZero; 65 procedure OpcodeTestZero; 66 procedure OpcodeXor; 29 67 public 30 68 Registers: array of T; … … 62 100 SetLength(Registers, 32); 63 101 SetLength(Memory, 1000); 64 end; 102 InitOpcodes; 103 end; 104 105 procedure TCPU.OpcodeNop; 106 begin 107 end; 108 109 procedure TCPU.OpcodeHalt; 110 begin 111 Terminated := True; 112 end; 113 114 procedure TCPU.OpcodeLoad; 115 var 116 Src, Dest: T; 117 begin 118 Dest := ReadNext; 119 Src := ReadNext; 120 Registers[Dest] := Registers[Src]; 121 end; 122 123 procedure TCPU.OpcodeLoadConst; 124 var 125 Reg: T; 126 begin 127 Reg := ReadNext; 128 Registers[Reg] := ReadNext; 129 end; 130 131 procedure TCPU.OpcodeLoadMemory; 132 var 133 Src, Dest: T; 134 begin 135 Dest := ReadNext; 136 Src := ReadNext; 137 Registers[Dest] := Memory[Registers[Src]]; 138 end; 139 140 procedure TCPU.OpcodeStoreMemory; 141 var 142 Src, Dest: T; 143 begin 144 Dest := ReadNext; 145 Src := ReadNext; 146 Memory[Registers[Dest]] := Registers[Src]; 147 end; 148 149 procedure TCPU.OpcodeLoadMemoryDisplacement; 150 var 151 Reg, Src, Dest: T; 152 begin 153 Dest := ReadNext; 154 Src := ReadNext; 155 Reg := ReadNext; 156 Registers[Dest] := Memory[Registers[Src] + Registers[Reg]]; 157 end; 158 159 procedure TCPU.OpcodeStoreMemoryDisplacement; 160 var 161 Reg, Src, Dest: T; 162 begin 163 Dest := ReadNext; 164 Reg := ReadNext; 165 Src := ReadNext; 166 Memory[Registers[Dest] + Registers[Reg]] := Registers[Src]; 167 end; 168 169 procedure TCPU.OpcodeIncrement; 170 var 171 Reg: T; 172 begin 173 Reg := ReadNext; 174 Registers[Reg] := Registers[Reg] + 1; 175 end; 176 177 procedure TCPU.OpcodeDecrement; 178 var 179 Reg: T; 180 begin 181 Reg := ReadNext; 182 Registers[Reg] := Registers[Reg] - 1; 183 end; 184 185 procedure TCPU.OpcodeAddition; 186 var 187 Dest, Src: T; 188 begin 189 Dest := ReadNext; 190 Src := ReadNext; 191 Registers[Dest] := Registers[Dest] + Registers[Src]; 192 end; 193 194 procedure TCPU.OpcodeSubtraction; 195 var 196 Dest, Src: T; 197 begin 198 Dest := ReadNext; 199 Src := ReadNext; 200 Registers[Dest] := Registers[Dest] - Registers[Src]; 201 end; 202 203 procedure TCPU.OpcodeMultiplication; 204 var 205 Dest, Src: T; 206 begin 207 Dest := ReadNext; 208 Src := ReadNext; 209 Registers[Dest] := Registers[Dest] * Registers[Src]; 210 end; 211 212 procedure TCPU.OpcodeDivision; 213 var 214 Dest, Src: T; 215 begin 216 Dest := ReadNext; 217 Src := ReadNext; 218 Registers[Dest] := Registers[Dest] div Registers[Src]; 219 end; 220 221 procedure TCPU.OpcodeShiftLeft; 222 var 223 Dest, Src: T; 224 begin 225 Dest := ReadNext; 226 Src := ReadNext; 227 Registers[Dest] := Registers[Dest] shl Registers[Src]; 228 end; 229 230 procedure TCPU.OpcodeShiftRight; 231 var 232 Src, Dest: T; 233 begin 234 Dest := ReadNext; 235 Src := ReadNext; 236 Registers[Dest] := Registers[Dest] shr Registers[Src]; 237 end; 238 239 procedure TCPU.OpcodeAnd; 240 var 241 Src, Dest: T; 242 begin 243 Dest := ReadNext; 244 Src := ReadNext; 245 Registers[Dest] := Registers[Dest] and Registers[Src]; 246 end; 247 248 procedure TCPU.OpcodeOr; 249 var 250 Src, Dest: T; 251 begin 252 Dest := ReadNext; 253 Src := ReadNext; 254 Registers[Dest] := Registers[Dest] or Registers[Src]; 255 end; 256 257 procedure TCPU.OpcodeXor; 258 var 259 Src, Dest: T; 260 begin 261 Dest := ReadNext; 262 Src := ReadNext; 263 Registers[Dest] := Registers[Dest] xor Registers[Src]; 264 end; 265 266 procedure TCPU.OpcodeJump; 267 var 268 Reg: T; 269 begin 270 Reg := ReadNext; 271 IP := Registers[Reg]; 272 end; 273 274 procedure TCPU.OpcodeJumpConditional; 275 var 276 Reg: T; 277 begin 278 Reg := ReadNext; 279 if Condition then 280 IP := Registers[Reg]; 281 end; 282 283 procedure TCPU.OpcodeJumpRelative; 284 var 285 Reg: T; 286 begin 287 Reg := ReadNext; 288 IP := IP + Registers[Reg]; 289 end; 290 291 procedure TCPU.OpcodeJumpRelativeConditional; 292 var 293 Reg: T; 294 begin 295 Reg := ReadNext; 296 if Condition then 297 IP := IP + Registers[Reg]; 298 end; 299 300 procedure TCPU.OpcodePush; 301 var 302 Reg: T; 303 begin 304 SP := SP - 1; 305 Reg := ReadNext; 306 Memory[SP] := Registers[Reg]; 307 end; 308 309 procedure TCPU.OpcodePop; 310 var 311 Reg: T; 312 begin 313 Reg := ReadNext; 314 Registers[Reg] := Memory[SP]; 315 SP := SP + 1; 316 end; 317 318 procedure TCPU.OpcodeCall; 319 var 320 Reg: T; 321 begin 322 SP := SP - 1; 323 Reg := ReadNext; 324 Memory[SP] := IP; 325 IP := Registers[Reg]; 326 end; 327 328 procedure TCPU.OpcodeReturn; 329 begin 330 IP := Memory[SP]; 331 SP := SP + 1; 332 end; 333 334 procedure TCPU.OpcodeInput; 335 var 336 Src, Dest: T; 337 begin 338 Dest := ReadNext; 339 Src := ReadNext; 340 if Assigned(FOnInput) then 341 Registers[Dest] := FOnInput(Registers[Src]); 342 end; 343 344 procedure TCPU.OpcodeOutput; 345 var 346 Dest, Src: T; 347 begin 348 Dest := ReadNext; 349 Src := ReadNext; 350 if Assigned(FOnOutput) then 351 FOnOutput(Registers[Dest], Registers[Src]); 352 end; 353 354 procedure TCPU.OpcodeTestZero; 355 var 356 Reg: T; 357 begin 358 Reg := ReadNext; 359 Condition := Registers[Reg] = 0; 360 end; 361 362 procedure TCPU.OpcodeTestNotZero; 363 var 364 Reg: T; 365 begin 366 Reg := ReadNext; 367 Condition := Registers[Reg] <> 0; 368 end; 369 370 procedure TCPU.OpcodeExchange; 371 var 372 Dest, Src, Temp: T; 373 begin 374 Dest := ReadNext; 375 Src := ReadNext; 376 Temp := Registers[Dest]; 377 Registers[Dest] := Registers[Src]; 378 Registers[Src] := Temp; 379 end; 380 65 381 66 382 procedure TCPU.Step; 67 383 var 68 384 Opcode: TOpcode; 69 Reg: T; 70 Src: T; 71 Dest: T; 72 Temp: T; 385 Handler: TOpcodeHandler; 73 386 begin 74 387 Opcode := TOpcode(ReadNext); 75 case Opcode of 76 opNop: ; 77 opHalt: Terminated := True; 78 opLD: begin 79 Dest := ReadNext; 80 Src := ReadNext; 81 Registers[Dest] := Registers[Src]; 82 end; 83 opLDC: begin 84 Reg := ReadNext; 85 Registers[Reg] := ReadNext; 86 end; 87 opLDM: begin 88 Dest := ReadNext; 89 Src := ReadNext; 90 Registers[Dest] := Memory[Registers[Src]]; 91 end; 92 opSTM: begin 93 Dest := ReadNext; 94 Src := ReadNext; 95 Memory[Registers[Dest]] := Registers[Src]; 96 end; 97 opLDMD: begin 98 Dest := ReadNext; 99 Src := ReadNext; 100 Reg := ReadNext; 101 Registers[Dest] := Memory[Registers[Src] + Registers[Reg]]; 102 end; 103 opSTMD: begin 104 Dest := ReadNext; 105 Reg := ReadNext; 106 Src := ReadNext; 107 Memory[Registers[Dest] + Registers[Reg]] := Registers[Src]; 108 end; 109 opInc: begin 110 Reg := ReadNext; 111 Registers[Reg] := Registers[Reg] + 1; 112 end; 113 opDec: begin 114 Reg := ReadNext; 115 Registers[Reg] := Registers[Reg] - 1; 116 end; 117 opAdd: begin 118 Dest := ReadNext; 119 Src := ReadNext; 120 Registers[Dest] := Registers[Dest] + Registers[Src]; 121 end; 122 opSub: begin 123 Dest := ReadNext; 124 Src := ReadNext; 125 Registers[Dest] := Registers[Dest] - Registers[Src]; 126 end; 127 opMul: begin 128 Dest := ReadNext; 129 Src := ReadNext; 130 Registers[Dest] := Registers[Dest] * Registers[Src]; 131 end; 132 opDiv: begin 133 Dest := ReadNext; 134 Src := ReadNext; 135 Registers[Dest] := Registers[Dest] div Registers[Src]; 136 end; 137 opShl: begin 138 Dest := ReadNext; 139 Src := ReadNext; 140 Registers[Dest] := Registers[Dest] shl Registers[Src]; 141 end; 142 opShr: begin 143 Dest := ReadNext; 144 Src := ReadNext; 145 Registers[Dest] := Registers[Dest] shr Registers[Src]; 146 end; 147 opAnd: begin 148 Dest := ReadNext; 149 Src := ReadNext; 150 Registers[Dest] := Registers[Dest] and Registers[Src]; 151 end; 152 opOr: begin 153 Dest := ReadNext; 154 Src := ReadNext; 155 Registers[Dest] := Registers[Dest] or Registers[Src]; 156 end; 157 opXor: begin 158 Dest := ReadNext; 159 Src := ReadNext; 160 Registers[Dest] := Registers[Dest] xor Registers[Src]; 161 end; 162 opJp: begin 163 Reg := ReadNext; 164 IP := Registers[Reg]; 165 end; 166 opJpc: begin 167 Reg := ReadNext; 168 if Condition then 169 IP := Registers[Reg]; 170 end; 171 opJr: begin 172 Reg := ReadNext; 173 IP := IP + Registers[Reg]; 174 end; 175 opJrc: begin 176 Reg := ReadNext; 177 if Condition then 178 IP := IP + Registers[Reg]; 179 end; 180 opPush: begin 181 SP := SP - 1; 182 Reg := ReadNext; 183 Memory[SP] := Registers[Reg]; 184 end; 185 opPop: begin 186 Reg := ReadNext; 187 Registers[Reg] := Memory[SP]; 188 SP := SP + 1; 189 end; 190 opCall: begin 191 SP := SP - 1; 192 Reg := ReadNext; 193 Memory[SP] := IP; 194 IP := Registers[Reg]; 195 end; 196 opRet: begin 197 Reg := ReadNext; 198 IP := Memory[SP]; 199 SP := SP + 1; 200 end; 201 opIn: begin 202 Dest := ReadNext; 203 Src := ReadNext; 204 if Assigned(FOnInput) then 205 Registers[Dest] := FOnInput(Registers[Src]); 206 end; 207 opOut: begin 208 Dest := ReadNext; 209 Src := ReadNext; 210 if Assigned(FOnOutput) then 211 FOnOutput(Registers[Dest], Registers[Src]); 212 end; 213 opTstZ: begin 214 Reg := ReadNext; 215 Condition := Registers[Reg] = 0; 216 end; 217 opTstNZ: begin 218 Reg := ReadNext; 219 Condition := Registers[Reg] <> 0; 220 end; 221 opXchg: begin 222 Dest := ReadNext; 223 Src := ReadNext; 224 Temp := Registers[Dest]; 225 Registers[Dest] := Registers[Src]; 226 Registers[Src] := Temp; 227 end; 228 else raise Exception.Create('Unknown opcode: ' + IntToStr(Integer(Opcode))); 229 end; 388 if Opcode <= High(TOpcode) then begin 389 Handler := OpcodeHandlers[Opcode]; 390 if Assigned(Handler) then Handler 391 else raise Exception.Create('Missing handler for opcode + ' + IntToStr(Integer(Opcode))); 392 end else raise Exception.Create('Unknown opcode: ' + IntToStr(Integer(Opcode))); 393 end; 394 395 procedure TCPU.AddOpcode(Opcode: TOpcode; Handler: TOpcodeHandler); 396 begin 397 OpcodeHandlers[Opcode] := Handler; 398 end; 399 400 procedure TCPU.InitOpcodes; 401 begin 402 AddOpcode(opNop, @OpcodeNop); 403 AddOpcode(opHalt, @OpcodeHalt); 404 AddOpcode(opAnd, @OpcodeAnd); 405 AddOpcode(opOr, @OpcodeOr); 406 AddOpcode(opXor, @OpcodeXor); 407 AddOpcode(opLD, @OpcodeLoad); 408 AddOpcode(opLDC, @OpcodeLoadConst); 409 AddOpcode(opLDM, @OpcodeLoadMemory); 410 AddOpcode(opSTM, @OpcodeStoreMemory); 411 AddOpcode(opLDMD, @OpcodeLoadMemoryDisplacement); 412 AddOpcode(opSTMD, @OpcodeStoreMemoryDisplacement); 413 AddOpcode(opCall, @OpcodeCall); 414 AddOpcode(opRet, @OpcodeReturn); 415 AddOpcode(opPush, @OpcodePush); 416 AddOpcode(opPop, @OpcodePop); 417 AddOpcode(opJP, @OpcodeJump); 418 AddOpcode(opJpc, @OpcodeJumpConditional); 419 AddOpcode(opJR, @OpcodeJumpRelative); 420 AddOpcode(opJRC, @OpcodeJumpRelativeConditional); 421 AddOpcode(opAdd, @OpcodeAddition); 422 AddOpcode(opSub, @OpcodeSubtraction); 423 AddOpcode(opMul, @OpcodeMultiplication); 424 AddOpcode(opDiv, @OpcodeDivision); 425 AddOpcode(opXchg, @OpcodeExchange); 426 AddOpcode(opShl, @OpcodeShiftLeft); 427 AddOpcode(opShr, @OpcodeShiftRight); 428 AddOpcode(opIn, @OpcodeInput); 429 AddOpcode(opOut, @OpcodeOutput); 430 AddOpcode(opInc, @OpcodeIncrement); 431 AddOpcode(opDec, @OpcodeDecrement); 432 AddOpcode(opTstNZ, @OpcodeTestNotZero); 433 AddOpcode(opTstZ, @OpcodeTestZero); 230 434 end; 231 435
Note:
See TracChangeset
for help on using the changeset viewer.