Ignore:
Timestamp:
Apr 12, 2019, 2:03:51 PM (6 years ago)
Author:
chronos
Message:
  • Modified: Better use data and address prefix opcodes.
  • Added: More instructions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu4/UCpu.pas

    r175 r177  
    1010type
    1111  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;
    1620  TAddress = QWord;
    1721  PAddress = ^TAddress;
     
    4448    DataSizeLast: TBitWidth;
    4549    DataSizePrefix: TBitWidth;
     50    AddrSizeLast: TBitWidth;
     51    AddrSizePrefix: TBitWidth;
    4652    Z: Boolean;
    4753    Thread: TCpuThread;
     
    5460    procedure InstJumpNotZero;
    5561    procedure InstJumpRel;
     62    procedure InstJumpRelZero;
     63    procedure InstJumpRelNotZero;
    5664    procedure InstTest;
    5765    procedure InstNeg;
     
    6876    procedure InstSub;
    6977    procedure InstSubi;
     78    procedure InstMul;
     79    procedure InstDiv;
     80    procedure InstMod;
    7081    procedure InstInc;
    7182    procedure InstDec;
     
    8495    procedure InstDataPrefix64;
    8596    procedure InstDataSize;
     97    procedure InstAddrPrefix8;
     98    procedure InstAddrPrefix16;
     99    procedure InstAddrPrefix32;
     100    procedure InstAddrPrefix64;
    86101    procedure InstAddrSize;
    87102    procedure InitInstructions;
     
    92107    IP: TAddress;
    93108    SP: TAddress;
    94     AddressSize: TBitWidth;
     109    AddrSize: TBitWidth;
    95110    DataSize: TBitWidth;
    96111    procedure Run;
     
    103118    function Read64: QWord; inline;
    104119    function ReadAddress: TAddress; inline;
     120    function ReadAddressSigned: TAddressSigned; inline;
    105121    constructor Create;
    106122    destructor Destroy; override;
     
    118134  end;
    119135
     136const
     137  BitWidthBytes: array[TBitWidth] of Byte = (0, 1, 2, 4, 8);
     138
    120139implementation
    121140
     
    167186procedure TCpu.InstJump;
    168187begin
    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;
     189end;
     190
     191procedure TCpu.InstJumpZero;
     192var
     193  Addr: TAddress;
     194begin
     195  Addr := ReadAddress;
     196  if Z then IP := Addr;
     197end;
     198
     199procedure TCpu.InstJumpNotZero;
     200var
     201  Addr: TAddress;
     202begin
     203  Addr := ReadAddress;
     204  if not Z then IP := Addr;
    175205end;
    176206
    177207procedure TCpu.InstJumpRel;
    178208begin
    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;
     210end;
     211
     212procedure TCpu.InstJumpRelZero;
     213var
     214  Addr: TAddressSigned;
     215begin
     216  Addr := ReadAddressSigned;
     217  if Z then IP := IP + Addr;
     218end;
     219
     220procedure TCpu.InstJumpRelNotZero;
     221var
     222  Addr: TAddressSigned;
     223begin
     224  Addr := ReadAddressSigned;
     225  if not Z then IP := IP + Addr;
    185226end;
    186227
     
    227268  R1 := Read8;
    228269  R2 := Read8;
    229   case AddressSize of
     270  case AddrSize of
    230271    bw8: case DataSize of
    231272      bw8: Registers[R1].B := PByte(Memory + PByte(@Registers[R2])^)^;
     
    261302  R1 := Read8;
    262303  R2 := Read8;
    263   case AddressSize of
     304  case AddrSize of
    264305    bw8: case DataSize of
    265306      bw8: PByte(Memory + PByte(@Registers[R1])^)^ := Registers[R2].B;
     
    368409  Dest: TRegister;
    369410begin
    370   case AddressSize of
     411  case AddrSize of
    371412    bw8: begin
    372413      Dest.B := Read8;
     
    398439procedure TCpu.InstRet;
    399440begin
    400   case AddressSize of
     441  case AddrSize of
    401442    bw8: begin
    402443      IP := PByte(Memory + SP)^;
     
    472513end;
    473514
     515procedure TCpu.InstMul;
     516var
     517  R1, R2: TRegIndex;
     518begin
     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;
     527end;
     528
     529procedure TCpu.InstDiv;
     530var
     531  R1, R2: TRegIndex;
     532begin
     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;
     541end;
     542
     543procedure TCpu.InstMod;
     544var
     545  R1, R2: TRegIndex;
     546begin
     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;
     555end;
     556
    474557procedure TCpu.InstInc;
    475558var
     
    498581end;
    499582
    500 procedure TCpu.InstJumpZero;
    501 begin
    502   case AddressSize of
    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;
    507   end;
    508 end;
    509 
    510 procedure TCpu.InstJumpNotZero;
    511 begin
    512   case AddressSize of
    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;
    517   end;
    518 end;
    519 
    520583procedure TCpu.InstIn;
    521584var
     
    652715  Dest := Read8;
    653716  Count := Read8;
    654   case AddressSize of
     717  case AddrSize of
    655718    bw8: while Registers[Count].B > 0 do begin
    656719      case DataSize of
     
    763826  Dest := Read8;
    764827  Count := Read8;
    765   case AddressSize of
     828  case AddrSize of
    766829    bw8: while Registers[Count].B > 0 do begin
    767830      case DataSize of
     
    892955end;
    893956
     957procedure TCpu.InstAddrPrefix8;
     958begin
     959  AddrSizePrefix := bw8;
     960end;
     961
     962procedure TCpu.InstAddrPrefix16;
     963begin
     964  AddrSizePrefix := bw16;
     965end;
     966
     967procedure TCpu.InstAddrPrefix32;
     968begin
     969  AddrSizePrefix := bw32;
     970end;
     971
     972procedure TCpu.InstAddrPrefix64;
     973begin
     974  AddrSizePrefix := bw64;
     975end;
     976
    894977procedure TCpu.InstAddrSize;
    895978begin
    896   AddressSize := TBitWidth(Read8);
     979  AddrSize := TBitWidth(Read8);
    897980end;
    898981
     
    907990  Instructions[opJumpZero] := InstJumpZero;
    908991  Instructions[opJumpRel] := InstJumpRel;
     992  Instructions[opJumpRelNotZero] := InstJumpRelNotZero;
     993  Instructions[opJumpRelZero] := InstJumpRelZero;
    909994  Instructions[opLoadMem] := InstLoadMem;
    910995  Instructions[opStoreMem] := InstStoreMem;
     
    9321017  Instructions[opDataPrefix32] := InstDataPrefix64;
    9331018  Instructions[opAddrSize] := InstAddrSize;
     1019  Instructions[opAddrPrefix8] := InstAddrPrefix8;
     1020  Instructions[opAddrPrefix16] := InstAddrPrefix16;
     1021  Instructions[opAddrPrefix32] := InstAddrPrefix32;
     1022  Instructions[opAddrPrefix32] := InstAddrPrefix64;
    9341023  Instructions[opTest] := InstTest;
    9351024  Instructions[opAnd] := InstAnd;
     
    9381027  Instructions[opLdir] := InstLdir;
    9391028  Instructions[opLddr] := InstLddr;
     1029  Instructions[opMul] := InstMul;
     1030  Instructions[opDiv] := InstDiv;
     1031  Instructions[opMod] := InstMod;
    9401032end;
    9411033
     
    9591051    DataSize := DataSizePrefix;
    9601052    DataSizePrefix := bwNone;
     1053  end;
     1054  if AddrSizePrefix <> bwNone then begin
     1055    AddrSizeLast := AddrSize;
     1056    AddrSize := AddrSizePrefix;
     1057    AddrSizePrefix := bwNone;
    9611058  end;
    9621059  Opcode := Read8;
     
    9691066    DataSizeLast := bwNone;
    9701067  end;
     1068  if AddrSizeLast <> bwNone then begin
     1069    AddrSize := AddrSizeLast;
     1070    AddrSizeLast := bwNone;
     1071  end;
    9711072  IP := IP mod MemSize(Memory);
    9721073  Inc(FTicks);
     
    10211122function TCpu.ReadAddress: TAddress;
    10221123begin
    1023   case AddressSize of
     1124  case AddrSize of
    10241125    bw8: Result := Read8;
    10251126    bw16: Result := Read16;
     
    10291130end;
    10301131
     1132function TCpu.ReadAddressSigned: TAddressSigned;
     1133begin
     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;
     1140end;
     1141
    10311142constructor TCpu.Create;
    10321143begin
    10331144  DataSize := bw16;
    1034   AddressSize := bw16;
     1145  AddrSize := bw16;
    10351146  SetLength(Registers, 32);
    10361147  InitInstructions;
Note: See TracChangeset for help on using the changeset viewer.