Changeset 177 for branches/virtualcpu4/UCpu.pas
- Timestamp:
- Apr 12, 2019, 2:03:51 PM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/virtualcpu4/UCpu.pas
r175 r177 10 10 type 11 11 TOpcode = (opNop, opHalt, opLoad, opLoadi, opJump, opJumpZero, opJumpNotZero, 12 opJumpRel, opNeg, opClear, opLoadMem, opStoreMem, opExchg, opPush, opPop, 13 opCall, opRet, opAdd, opAddi, opSub, opSubi, opInc, opDec, opIn, opOut, opShl, 14 opShr, opDataPrefix8, opDataPrefix16, opDataPrefix32, opDataPrefix64, 15 opDataSize, opAddrSize, opTest, opAnd, opOr, opXor, opLddr, opLdir); 12 opJumpRel, opJumpRelZero, opJumpRelNotZero, opNeg, opClear, opLoadMem, 13 opStoreMem, opExchg, opPush, opPop, opCall, opRet, opAdd, opAddi, opSub, 14 opSubi, opInc, opDec, opIn, opOut, opShl, opShr, opDataPrefix8, opDataPrefix16, 15 opDataPrefix32, opDataPrefix64, opDataSize, opAddrSize, opTest, opAnd, opOr, 16 opXor, opLddr, opLdir, opMul, opDiv, opMod, opAddrPrefix8, opAddrPrefix16, 17 opAddrPrefix32, opAddrPrefix64); 18 19 TAddressSigned = Int64; 16 20 TAddress = QWord; 17 21 PAddress = ^TAddress; … … 44 48 DataSizeLast: TBitWidth; 45 49 DataSizePrefix: TBitWidth; 50 AddrSizeLast: TBitWidth; 51 AddrSizePrefix: TBitWidth; 46 52 Z: Boolean; 47 53 Thread: TCpuThread; … … 54 60 procedure InstJumpNotZero; 55 61 procedure InstJumpRel; 62 procedure InstJumpRelZero; 63 procedure InstJumpRelNotZero; 56 64 procedure InstTest; 57 65 procedure InstNeg; … … 68 76 procedure InstSub; 69 77 procedure InstSubi; 78 procedure InstMul; 79 procedure InstDiv; 80 procedure InstMod; 70 81 procedure InstInc; 71 82 procedure InstDec; … … 84 95 procedure InstDataPrefix64; 85 96 procedure InstDataSize; 97 procedure InstAddrPrefix8; 98 procedure InstAddrPrefix16; 99 procedure InstAddrPrefix32; 100 procedure InstAddrPrefix64; 86 101 procedure InstAddrSize; 87 102 procedure InitInstructions; … … 92 107 IP: TAddress; 93 108 SP: TAddress; 94 Addr essSize: TBitWidth;109 AddrSize: TBitWidth; 95 110 DataSize: TBitWidth; 96 111 procedure Run; … … 103 118 function Read64: QWord; inline; 104 119 function ReadAddress: TAddress; inline; 120 function ReadAddressSigned: TAddressSigned; inline; 105 121 constructor Create; 106 122 destructor Destroy; override; … … 118 134 end; 119 135 136 const 137 BitWidthBytes: array[TBitWidth] of Byte = (0, 1, 2, 4, 8); 138 120 139 implementation 121 140 … … 167 186 procedure TCpu.InstJump; 168 187 begin 169 case AddressSize of 170 bw8: IP := Read8; 171 bw16: IP := Read16; 172 bw32: IP := Read32; 173 bw64: IP := Read64; 174 end; 188 IP := ReadAddress; 189 end; 190 191 procedure TCpu.InstJumpZero; 192 var 193 Addr: TAddress; 194 begin 195 Addr := ReadAddress; 196 if Z then IP := Addr; 197 end; 198 199 procedure TCpu.InstJumpNotZero; 200 var 201 Addr: TAddress; 202 begin 203 Addr := ReadAddress; 204 if not Z then IP := Addr; 175 205 end; 176 206 177 207 procedure TCpu.InstJumpRel; 178 208 begin 179 case AddressSize of 180 bw8: PByte(@IP)^ := Byte(IP) + Read8; 181 bw16: PWord(@IP)^ := Word(IP) + Read16; 182 bw32: PDWord(@IP)^ := DWord(IP) + Read32; 183 bw64: PQWord(@IP)^ := QWord(IP) + Read64; 184 end; 209 IP := IP + ReadAddressSigned; 210 end; 211 212 procedure TCpu.InstJumpRelZero; 213 var 214 Addr: TAddressSigned; 215 begin 216 Addr := ReadAddressSigned; 217 if Z then IP := IP + Addr; 218 end; 219 220 procedure TCpu.InstJumpRelNotZero; 221 var 222 Addr: TAddressSigned; 223 begin 224 Addr := ReadAddressSigned; 225 if not Z then IP := IP + Addr; 185 226 end; 186 227 … … 227 268 R1 := Read8; 228 269 R2 := Read8; 229 case Addr essSize of270 case AddrSize of 230 271 bw8: case DataSize of 231 272 bw8: Registers[R1].B := PByte(Memory + PByte(@Registers[R2])^)^; … … 261 302 R1 := Read8; 262 303 R2 := Read8; 263 case Addr essSize of304 case AddrSize of 264 305 bw8: case DataSize of 265 306 bw8: PByte(Memory + PByte(@Registers[R1])^)^ := Registers[R2].B; … … 368 409 Dest: TRegister; 369 410 begin 370 case Addr essSize of411 case AddrSize of 371 412 bw8: begin 372 413 Dest.B := Read8; … … 398 439 procedure TCpu.InstRet; 399 440 begin 400 case Addr essSize of441 case AddrSize of 401 442 bw8: begin 402 443 IP := PByte(Memory + SP)^; … … 472 513 end; 473 514 515 procedure TCpu.InstMul; 516 var 517 R1, R2: TRegIndex; 518 begin 519 R1 := Read8; 520 R2 := Read8; 521 case DataSize of 522 bw8: Registers[R1].B := Registers[R1].B * Registers[R2].B; 523 bw16: Registers[R1].W := Registers[R1].W * Registers[R2].W; 524 bw32: Registers[R1].D := Registers[R1].D * Registers[R2].D; 525 bw64: Registers[R1].Q := Registers[R1].Q * Registers[R2].Q; 526 end; 527 end; 528 529 procedure TCpu.InstDiv; 530 var 531 R1, R2: TRegIndex; 532 begin 533 R1 := Read8; 534 R2 := Read8; 535 case DataSize of 536 bw8: Registers[R1].B := Registers[R1].B div Registers[R2].B; 537 bw16: Registers[R1].W := Registers[R1].W div Registers[R2].W; 538 bw32: Registers[R1].D := Registers[R1].D div Registers[R2].D; 539 bw64: Registers[R1].Q := Registers[R1].Q div Registers[R2].Q; 540 end; 541 end; 542 543 procedure TCpu.InstMod; 544 var 545 R1, R2: TRegIndex; 546 begin 547 R1 := Read8; 548 R2 := Read8; 549 case DataSize of 550 bw8: Registers[R1].B := Registers[R1].B mod Registers[R2].B; 551 bw16: Registers[R1].W := Registers[R1].W mod Registers[R2].W; 552 bw32: Registers[R1].D := Registers[R1].D mod Registers[R2].D; 553 bw64: Registers[R1].Q := Registers[R1].Q mod Registers[R2].Q; 554 end; 555 end; 556 474 557 procedure TCpu.InstInc; 475 558 var … … 498 581 end; 499 582 500 procedure TCpu.InstJumpZero;501 begin502 case AddressSize of503 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;507 end;508 end;509 510 procedure TCpu.InstJumpNotZero;511 begin512 case AddressSize of513 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;517 end;518 end;519 520 583 procedure TCpu.InstIn; 521 584 var … … 652 715 Dest := Read8; 653 716 Count := Read8; 654 case Addr essSize of717 case AddrSize of 655 718 bw8: while Registers[Count].B > 0 do begin 656 719 case DataSize of … … 763 826 Dest := Read8; 764 827 Count := Read8; 765 case Addr essSize of828 case AddrSize of 766 829 bw8: while Registers[Count].B > 0 do begin 767 830 case DataSize of … … 892 955 end; 893 956 957 procedure TCpu.InstAddrPrefix8; 958 begin 959 AddrSizePrefix := bw8; 960 end; 961 962 procedure TCpu.InstAddrPrefix16; 963 begin 964 AddrSizePrefix := bw16; 965 end; 966 967 procedure TCpu.InstAddrPrefix32; 968 begin 969 AddrSizePrefix := bw32; 970 end; 971 972 procedure TCpu.InstAddrPrefix64; 973 begin 974 AddrSizePrefix := bw64; 975 end; 976 894 977 procedure TCpu.InstAddrSize; 895 978 begin 896 Addr essSize := TBitWidth(Read8);979 AddrSize := TBitWidth(Read8); 897 980 end; 898 981 … … 907 990 Instructions[opJumpZero] := InstJumpZero; 908 991 Instructions[opJumpRel] := InstJumpRel; 992 Instructions[opJumpRelNotZero] := InstJumpRelNotZero; 993 Instructions[opJumpRelZero] := InstJumpRelZero; 909 994 Instructions[opLoadMem] := InstLoadMem; 910 995 Instructions[opStoreMem] := InstStoreMem; … … 932 1017 Instructions[opDataPrefix32] := InstDataPrefix64; 933 1018 Instructions[opAddrSize] := InstAddrSize; 1019 Instructions[opAddrPrefix8] := InstAddrPrefix8; 1020 Instructions[opAddrPrefix16] := InstAddrPrefix16; 1021 Instructions[opAddrPrefix32] := InstAddrPrefix32; 1022 Instructions[opAddrPrefix32] := InstAddrPrefix64; 934 1023 Instructions[opTest] := InstTest; 935 1024 Instructions[opAnd] := InstAnd; … … 938 1027 Instructions[opLdir] := InstLdir; 939 1028 Instructions[opLddr] := InstLddr; 1029 Instructions[opMul] := InstMul; 1030 Instructions[opDiv] := InstDiv; 1031 Instructions[opMod] := InstMod; 940 1032 end; 941 1033 … … 959 1051 DataSize := DataSizePrefix; 960 1052 DataSizePrefix := bwNone; 1053 end; 1054 if AddrSizePrefix <> bwNone then begin 1055 AddrSizeLast := AddrSize; 1056 AddrSize := AddrSizePrefix; 1057 AddrSizePrefix := bwNone; 961 1058 end; 962 1059 Opcode := Read8; … … 969 1066 DataSizeLast := bwNone; 970 1067 end; 1068 if AddrSizeLast <> bwNone then begin 1069 AddrSize := AddrSizeLast; 1070 AddrSizeLast := bwNone; 1071 end; 971 1072 IP := IP mod MemSize(Memory); 972 1073 Inc(FTicks); … … 1021 1122 function TCpu.ReadAddress: TAddress; 1022 1123 begin 1023 case Addr essSize of1124 case AddrSize of 1024 1125 bw8: Result := Read8; 1025 1126 bw16: Result := Read16; … … 1029 1130 end; 1030 1131 1132 function TCpu.ReadAddressSigned: TAddressSigned; 1133 begin 1134 case AddrSize of 1135 bw8: Result := ShortInt(Read8); 1136 bw16: Result := SmallInt(Read16); 1137 bw32: Result := Integer(Read32); 1138 bw64: Result := Int64(Read64); 1139 end; 1140 end; 1141 1031 1142 constructor TCpu.Create; 1032 1143 begin 1033 1144 DataSize := bw16; 1034 Addr essSize := bw16;1145 AddrSize := bw16; 1035 1146 SetLength(Registers, 32); 1036 1147 InitInstructions;
Note:
See TracChangeset
for help on using the changeset viewer.