Ignore:
Timestamp:
Apr 13, 2019, 1:32:32 PM (6 years ago)
Author:
chronos
Message:
  • Fixed: Allow to use multiple prefix instructions in row.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu4/UCpu.pas

    r181 r182  
    4141  TCpu = class
    4242  private
     43    FAddrSizeBase: TBitWidth;
     44    FDataSizeBase: TBitWidth;
    4345    FOnInput: TInputEvent;
    4446    FOnOutput: TOutputEvent;
     
    4648    FTicks: Integer;
    4749    Instructions: array[TOpcode] of TInstructionEvent;
    48     DataSizeLast: TBitWidth;
    49     DataSizePrefix: TBitWidth;
    50     AddrSizeLast: TBitWidth;
    51     AddrSizePrefix: TBitWidth;
     50    Prefix: Boolean;
    5251    Z: Boolean;
    5352    Thread: TCpuThread;
     
    101100    procedure InstAddrSize;
    102101    procedure InitInstructions;
     102    procedure SetAddrSizeBase(AValue: TBitWidth);
     103    procedure SetDataSizeBase(AValue: TBitWidth);
    103104  public
    104105    Memory: Pointer;
     
    107108    IP: TAddress;
    108109    SP: TAddress;
     110    DataSize: TBitWidth;
    109111    AddrSize: TBitWidth;
    110     DataSize: TBitWidth;
    111112    procedure Run;
    112113    procedure Step; inline;
     
    121122    constructor Create;
    122123    destructor Destroy; override;
     124    property DataSizeBase: TBitWidth read FDataSizeBase write SetDataSizeBase;
     125    property AddrSizeBase: TBitWidth read FAddrSizeBase write SetAddrSizeBase;
    123126    property Ticks: Integer read FTicks;
    124127    property Running: Boolean read FRunning;
     
    140143    Param2: TOpcodeParam;
    141144    Param3: TOpcodeParam;
     145    Prefix: Boolean;
    142146  end;
    143147
     
    146150  BitWidthText: array[TBitWidth] of string = ('None', '8-bit', '16-bit', '32-bit', '64-bit');
    147151  OpcodeDef: array[TOpcode] of TOpcodeDef = (
    148     (Name: 'NOP'; Param1: prNone; Param2: prNone; Param3: prNone),
    149     (Name: 'HALT'; Param1: prNone; Param2: prNone; Param3: prNone),
    150     (Name: 'LD'; Param1: prReg; Param2: prReg; Param3: prNone),
    151     (Name: 'LDI'; Param1: prReg; Param2: prData; Param3: prNone),
    152     (Name: 'JP'; Param1: prAddr; Param2: prNone; Param3: prNone),
    153     (Name: 'JPZ'; Param1: prAddr; Param2: prNone; Param3: prNone),
    154     (Name: 'JPNZ'; Param1: prAddr; Param2: prNone; Param3: prNone),
    155     (Name: 'JR'; Param1: prAddrRel; Param2: prNone; Param3: prNone),
    156     (Name: 'JRZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone),
    157     (Name: 'JRNZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone),
    158     (Name: 'NEG'; Param1: prReg; Param2: prNone; Param3: prNone),
    159     (Name: 'CLR'; Param1: prReg; Param2: prNone; Param3: prNone),
    160     (Name: 'LDM'; Param1: prReg; Param2: prReg; Param3: prNone),
    161     (Name: 'STM'; Param1: prReg; Param2: prReg; Param3: prNone),
    162     (Name: 'EX'; Param1: prReg; Param2: prReg; Param3: prNone),
    163     (Name: 'PUSH'; Param1: prReg; Param2: prNone; Param3: prNone),
    164     (Name: 'POP'; Param1: prReg; Param2: prNone; Param3: prNone),
    165     (Name: 'CALL'; Param1: prAddr; Param2: prNone; Param3: prNone),
    166     (Name: 'RET'; Param1: prNone; Param2: prNone; Param3: prNone),
    167     (Name: 'ADD'; Param1: prReg; Param2: prReg; Param3: prNone),
    168     (Name: 'ADDI'; Param1: prReg; Param2: prData; Param3: prNone),
    169     (Name: 'SUB'; Param1: prReg; Param2: prReg; Param3: prNone),
    170     (Name: 'SUBI'; Param1: prReg; Param2: prData; Param3: prNone),
    171     (Name: 'INC'; Param1: prReg; Param2: prNone; Param3: prNone),
    172     (Name: 'DEC'; Param1: prReg; Param2: prNone; Param3: prNone),
    173     (Name: 'IN'; Param1: prReg; Param2: prAddr; Param3: prNone),
    174     (Name: 'OUT'; Param1: prAddr; Param2: prReg; Param3: prNone),
    175     (Name: 'SHL'; Param1: prReg; Param2: prReg; Param3: prNone),
    176     (Name: 'SHR'; Param1: prReg; Param2: prReg; Param3: prNone),
    177     (Name: 'DP8'; Param1: prNone; Param2: prNone; Param3: prNone),
    178     (Name: 'DP16'; Param1: prNone; Param2: prNone; Param3: prNone),
    179     (Name: 'DP32'; Param1: prNone; Param2: prNone; Param3: prNone),
    180     (Name: 'DP64'; Param1: prNone; Param2: prNone; Param3: prNone),
    181     (Name: 'DS'; Param1: prNone; Param2: prNone; Param3: prNone),
    182     (Name: 'AS'; Param1: prNone; Param2: prNone; Param3: prNone),
    183     (Name: 'TEST'; Param1: prReg; Param2: prNone; Param3: prNone),
    184     (Name: 'AND'; Param1: prReg; Param2: prReg; Param3: prNone),
    185     (Name: 'OR'; Param1: prReg; Param2: prReg; Param3: prNone),
    186     (Name: 'XOR'; Param1: prReg; Param2: prReg; Param3: prNone),
    187     (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg),
    188     (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg),
    189     (Name: 'MUL'; Param1: prReg; Param2: prReg; Param3: prNone),
    190     (Name: 'DIV'; Param1: prReg; Param2: prReg; Param3: prNone),
    191     (Name: 'MOD'; Param1: prReg; Param2: prReg; Param3: prNone),
    192     (Name: 'AP8'; Param1: prNone; Param2: prNone; Param3: prNone),
    193     (Name: 'AP16'; Param1: prNone; Param2: prNone; Param3: prNone),
    194     (Name: 'AP32'; Param1: prNone; Param2: prNone; Param3: prNone),
    195     (Name: 'AP64'; Param1: prNone; Param2: prNone; Param3: prNone)
     152    (Name: 'NOP'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False),
     153    (Name: 'HALT'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False),
     154    (Name: 'LD'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     155    (Name: 'LDI'; Param1: prReg; Param2: prData; Param3: prNone; Prefix: False),
     156    (Name: 'JP'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False),
     157    (Name: 'JPZ'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False),
     158    (Name: 'JPNZ'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False),
     159    (Name: 'JR'; Param1: prAddrRel; Param2: prNone; Param3: prNone; Prefix: False),
     160    (Name: 'JRZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone; Prefix: False),
     161    (Name: 'JRNZ'; Param1: prAddrRel; Param2: prNone; Param3: prNone; Prefix: False),
     162    (Name: 'NEG'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     163    (Name: 'CLR'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     164    (Name: 'LDM'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     165    (Name: 'STM'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     166    (Name: 'EX'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     167    (Name: 'PUSH'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     168    (Name: 'POP'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     169    (Name: 'CALL'; Param1: prAddr; Param2: prNone; Param3: prNone; Prefix: False),
     170    (Name: 'RET'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False),
     171    (Name: 'ADD'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     172    (Name: 'ADDI'; Param1: prReg; Param2: prData; Param3: prNone; Prefix: False),
     173    (Name: 'SUB'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     174    (Name: 'SUBI'; Param1: prReg; Param2: prData; Param3: prNone; Prefix: False),
     175    (Name: 'INC'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     176    (Name: 'DEC'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     177    (Name: 'IN'; Param1: prReg; Param2: prAddr; Param3: prNone; Prefix: False),
     178    (Name: 'OUT'; Param1: prAddr; Param2: prReg; Param3: prNone; Prefix: False),
     179    (Name: 'SHL'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     180    (Name: 'SHR'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     181    (Name: 'DP8'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True),
     182    (Name: 'DP16'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False),
     183    (Name: 'DP32'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True),
     184    (Name: 'DP64'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True),
     185    (Name: 'DS'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False),
     186    (Name: 'AS'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: False),
     187    (Name: 'TEST'; Param1: prReg; Param2: prNone; Param3: prNone; Prefix: False),
     188    (Name: 'AND'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     189    (Name: 'OR'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     190    (Name: 'XOR'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     191    (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg; Prefix: False),
     192    (Name: 'LDDR'; Param1: prReg; Param2: prReg; Param3: prReg; Prefix: False),
     193    (Name: 'MUL'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     194    (Name: 'DIV'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     195    (Name: 'MOD'; Param1: prReg; Param2: prReg; Param3: prNone; Prefix: False),
     196    (Name: 'AP8'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True),
     197    (Name: 'AP16'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True),
     198    (Name: 'AP32'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True),
     199    (Name: 'AP64'; Param1: prNone; Param2: prNone; Param3: prNone; Prefix: True)
    196200  );
    197201
     
    991995procedure TCpu.InstDataPrefix8;
    992996begin
    993   DataSizePrefix := bw8;
     997  DataSize := bw8;
     998  Prefix := True;
    994999end;
    9951000
    9961001procedure TCpu.InstDataPrefix16;
    9971002begin
    998   DataSizePrefix := bw16;
     1003  DataSize := bw16;
     1004  Prefix := True;
    9991005end;
    10001006
    10011007procedure TCpu.InstDataPrefix32;
    10021008begin
    1003   DataSizePrefix := bw32;
     1009  DataSize := bw32;
     1010  Prefix := True;
    10041011end;
    10051012
    10061013procedure TCpu.InstDataPrefix64;
    10071014begin
    1008   DataSizePrefix := bw64;
     1015  DataSize := bw64;
     1016  Prefix := True;
    10091017end;
    10101018
    10111019procedure TCpu.InstDataSize;
    10121020begin
    1013   DataSize := TBitWidth(Read8);
     1021  DataSizeBase := TBitWidth(Read8);
     1022  DataSize := DataSizeBase;
    10141023end;
    10151024
    10161025procedure TCpu.InstAddrPrefix8;
    10171026begin
    1018   AddrSizePrefix := bw8;
     1027  AddrSize := bw8;
     1028  Prefix := True;
    10191029end;
    10201030
    10211031procedure TCpu.InstAddrPrefix16;
    10221032begin
    1023   AddrSizePrefix := bw16;
     1033  AddrSize := bw16;
     1034  Prefix := True;
    10241035end;
    10251036
    10261037procedure TCpu.InstAddrPrefix32;
    10271038begin
    1028   AddrSizePrefix := bw32;
     1039  AddrSize := bw32;
     1040  Prefix := True;
    10291041end;
    10301042
    10311043procedure TCpu.InstAddrPrefix64;
    10321044begin
    1033   AddrSizePrefix := bw64;
     1045  AddrSize := bw64;
     1046  Prefix := True;
    10341047end;
    10351048
    10361049procedure TCpu.InstAddrSize;
    10371050begin
    1038   AddrSize := TBitWidth(Read8);
     1051  AddrSizeBase := TBitWidth(Read8);
     1052  AddrSize := AddrSizeBase;
    10391053end;
    10401054
     
    10911105end;
    10921106
     1107procedure TCpu.SetAddrSizeBase(AValue: TBitWidth);
     1108begin
     1109  if FAddrSizeBase = AValue then Exit;
     1110  FAddrSizeBase := AValue;
     1111  AddrSize := AValue;
     1112end;
     1113
     1114procedure TCpu.SetDataSizeBase(AValue: TBitWidth);
     1115begin
     1116  if FDataSizeBase = AValue then Exit;
     1117  FDataSizeBase := AValue;
     1118  DataSize := AValue;
     1119end;
     1120
    10931121procedure TCpu.Run;
    10941122begin
     1123  DataSize := DataSizeBase;
     1124  AddrSize := AddrSizeBase;
    10951125  Terminated := False;
    10961126  FTicks := 0;
    1097   DataSizeLast := bwNone;
    10981127  IP := 0;
    10991128  SP := MemSize(Memory);
     
    11061135  Opcode: Byte;
    11071136begin
    1108   if DataSizePrefix <> bwNone then begin
    1109     DataSizeLast := DataSize;
    1110     DataSize := DataSizePrefix;
    1111     DataSizePrefix := bwNone;
    1112   end;
    1113   if AddrSizePrefix <> bwNone then begin
    1114     AddrSizeLast := AddrSize;
    1115     AddrSize := AddrSizePrefix;
    1116     AddrSizePrefix := bwNone;
    1117   end;
     1137  Prefix := False;
    11181138  Opcode := Read8;
    11191139  if Opcode < Length(Instructions) then begin
     
    11211141      else raise Exception.Create('Missing instruction handler for opcode '+ IntToStr(Opcode));
    11221142  end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP - 1, 8) + '.');
    1123   if DataSizeLast <> bwNone then begin
    1124     DataSize := DataSizeLast;
    1125     DataSizeLast := bwNone;
    1126   end;
    1127   if AddrSizeLast <> bwNone then begin
    1128     AddrSize := AddrSizeLast;
    1129     AddrSizeLast := bwNone;
     1143  if not Prefix then begin
     1144    DataSize := DataSizeBase;
     1145    AddrSize := AddrSizeBase;
    11301146  end;
    11311147  IP := IP mod MemSize(Memory);
     
    12011217constructor TCpu.Create;
    12021218begin
    1203   DataSize := bw16;
    1204   AddrSize := bw16;
     1219  DataSizeBase := bw16;
     1220  AddrSizeBase := bw16;
    12051221  SetLength(Registers, 32);
    12061222  InitInstructions;
Note: See TracChangeset for help on using the changeset viewer.