Ignore:
Timestamp:
Apr 25, 2018, 10:20:25 AM (7 years ago)
Author:
chronos
Message:
  • Added: Used condition compilation to allow to enable/disable CPU extensions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu3/UMachine.pas

    r157 r158  
    11unit UMachine;
     2
     3
     4{$DEFINE EXT_IO}
     5{$DEFINE EXT_ADDRESSING_MODES}
     6{$DEFINE EXT_ARITHMETIC}
     7{$DEFINE EXT_LOGICAL}
     8{$DEFINE EXT_STACK}
     9{$DEFINE EXT_SUBROUTINE}
     10{$DEFINE EXT_SHIFT}
     11{$DEFINE EXT_BLOCK}
     12{$DEFINE EXT_GENERAL}
     13{$DEFINE EXT_BIT}
     14
     15// Extension dependencies
     16{$IFDEF EXT_SUBROUTINE}
     17{$DEFINE EXT_STACK}
     18{$ENDIF}
    219
    320{$mode objfpc}{$H+}
     
    1128  TOpcode = (opNop, opHalt, opLD, opLDC, opLDM, opSTM, opInc, opDec, opJP, opJr,
    1229    opPush, opPop, opCall, opRet, opAdd, opSub, opMul, opDiv, opShr, opShl,
    13     opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc, opTstZ, opTstNZ,
    14     opLDMD, opSTMD);
     30    opIn, opOut, opXchg, opXor, opOr, opAnd, opJpc, opJrc,
     31    opTstZ, opTstNZ, opTstC, opTstNC, opLDMD, opSTMD, opLdir, opLddr,
     32    opBitSet, opBitRes, opBitGet, opBitPut);
    1533
    1634  TOpcodeHandler = procedure of object;
     35
     36  // Goals: Simple to implement, fast execution
     37  // Address and data have same bit width
     38  // Memory access with lower bit width?
     39  // Related instructions grouped as extensions
    1740
    1841  { TCPU }
     
    4063    FOnOutput: TOutputEvent;
    4164    Condition: Boolean;
    42     procedure OpcodeAddition;
    43     procedure OpcodeAnd;
    44     procedure OpcodeCall;
    45     procedure OpcodeDecrement;
    46     procedure OpcodeDivision;
    47     procedure OpcodeExchange;
     65    procedure OpcodeNoOperation;
    4866    procedure OpcodeHalt;
    4967    procedure OpcodeIncrement;
    50     procedure OpcodeInput;
     68    procedure OpcodeDecrement;
    5169    procedure OpcodeJump;
    5270    procedure OpcodeJumpConditional;
     
    5674    procedure OpcodeLoadConst;
    5775    procedure OpcodeLoadMemory;
     76    procedure OpcodeStoreMemory;
     77    procedure OpcodeTestNotZero;
     78    procedure OpcodeTestZero;
     79    procedure OpcodeTestNotCarry;
     80    procedure OpcodeTestCarry;
     81    {$IFDEF EXT_GENERAL}
     82    procedure OpcodeExchange;
     83    {$ENDIF}
     84    {$IFDEF EXT_IO}
     85    procedure OpcodeInput;
     86    procedure OpcodeOutput;
     87    {$ENDIF}
     88    {$IFDEF EXT_ADDRESSING_MODES}
    5889    procedure OpcodeLoadMemoryDisplacement;
     90    procedure OpcodeStoreMemoryDisplacement;
     91    {$ENDIF}
     92    {$IFDEF EXT_ARITHMETIC}
     93    procedure OpcodeAddition;
     94    procedure OpcodeSubtraction;
     95    procedure OpcodeDivision;
    5996    procedure OpcodeMultiplication;
    60     procedure OpcodeNoOperation;
     97    {$ENDIF}
     98    {$IFDEF EXT_LOGICAL}
     99    procedure OpcodeAnd;
    61100    procedure OpcodeOr;
    62     procedure OpcodeOutput;
     101    procedure OpcodeXor;
     102    {$ENDIF}
     103    {$IFDEF EXT_STACK}
    63104    procedure OpcodePop;
    64105    procedure OpcodePush;
     106    {$ENDIF}
     107    {$IFDEF EXT_SUBROUTINE}
     108    procedure OpcodeCall;
    65109    procedure OpcodeReturn;
     110    {$ENDIF}
     111    {$IFDEF EXT_SHIFT}
    66112    procedure OpcodeShiftLeft;
    67113    procedure OpcodeShiftRight;
    68     procedure OpcodeStoreMemory;
    69     procedure OpcodeStoreMemoryDisplacement;
    70     procedure OpcodeSubtraction;
    71     procedure OpcodeTestNotZero;
    72     procedure OpcodeTestZero;
    73     procedure OpcodeXor;
     114    {$ENDIF}
     115    {$IFDEF EXT_BLOCK}
     116    procedure OpcodeLdir;
     117    procedure OpcodeLddr;
     118    {$ENDIF}
     119    {$IFDEF EXT_BIT}
     120    procedure OpcodeBitSet;
     121    procedure OpcodeBitReset;
     122    procedure OpcodeBitGet;
     123    procedure OpcodeBitPut;
     124    {$ENDIF}
    74125  public
    75126    Registers: array of T;
    76127    Memory: array of Byte;
    77128    IP: T;
     129    {$IFDEF EXT_STACK}
    78130    SP: T;
     131    {$ENDIF}
    79132    procedure Run;
    80133    constructor Create;
     
    109162begin
    110163  IP := 0;
     164  {$IFDEF EXT_STACK}
    111165  SP := Length(Memory);
     166  {$ENDIF}
    112167  Terminated := False;
    113168  while not Terminated do
     
    166221end;
    167222
     223{$IFDEF EXT_ADDRESSING_MODES}
    168224procedure TCPU.OpcodeLoadMemoryDisplacement;
    169225var
     
    185241  PT(@Memory[Registers[Dest] + Registers[Disp]])^ := Registers[Src];
    186242end;
     243{$ENDIF}
    187244
    188245procedure TCPU.OpcodeIncrement;
     
    202259end;
    203260
     261{$IFDEF EXT_ARITHMETIC}
    204262procedure TCPU.OpcodeAddition;
    205263var
     
    237295  Registers[Dest] := Registers[Dest] div Registers[Src];
    238296end;
    239 
     297{$ENDIF}
     298
     299{$IFDEF EXT_SHIFT}
    240300procedure TCPU.OpcodeShiftLeft;
    241301var
     
    255315  Registers[Dest] := Registers[Dest] shr Registers[Src];
    256316end;
    257 
     317{$ENDIF}
     318
     319{$IFDEF EXT_LOGICAL}
    258320procedure TCPU.OpcodeAnd;
    259321var
     
    282344  Registers[Dest] := Registers[Dest] xor Registers[Src];
    283345end;
     346{$ENDIF}
    284347
    285348procedure TCPU.OpcodeJump;
     
    317380end;
    318381
     382{$IFDEF EXT_STACK}
    319383procedure TCPU.OpcodePush;
    320384var
     
    334398  SP := SP + SizeOf(T);
    335399end;
    336 
     400{$ENDIF}
     401
     402{$IFDEF EXT_SUBROUTINE}
    337403procedure TCPU.OpcodeCall;
    338404var
     
    350416  SP := SP + SizeOf(T);
    351417end;
    352 
     418{$ENDIF}
     419
     420{$IFDEF EXT_IO}
    353421procedure TCPU.OpcodeInput;
    354422var
     
    370438    FOnOutput(Registers[Dest], Registers[Src]);
    371439end;
     440{$ENDIF}
    372441
    373442procedure TCPU.OpcodeTestZero;
     
    379448end;
    380449
     450procedure TCPU.OpcodeTestNotCarry;
     451var
     452  Reg1: TRegIndex;
     453  Reg2: TRegIndex;
     454begin
     455  Reg1 := ReadReg;
     456  Reg2 := ReadReg;
     457  Condition := Registers[Reg2] <= Registers[Reg1];
     458end;
     459
     460procedure TCPU.OpcodeTestCarry;
     461var
     462  Reg1: TRegIndex;
     463  Reg2: TRegIndex;
     464begin
     465  Reg1 := ReadReg;
     466  Reg2 := ReadReg;
     467  Condition := Registers[Reg2] > Registers[Reg1];
     468end;
     469
    381470procedure TCPU.OpcodeTestNotZero;
    382471var
     
    387476end;
    388477
     478{$IFDEF EXT_GENERAL}
    389479procedure TCPU.OpcodeExchange;
    390480var
     
    398488  Registers[Src] := Temp;
    399489end;
    400 
     490{$ENDIF}
     491
     492{$IFDEF EXT_BLOCK}
     493procedure TCPU.OpcodeLdir;
     494var
     495  Dest, Src, Count: TRegIndex;
     496begin
     497  Dest := ReadReg;
     498  Src := ReadReg;
     499  Count := ReadReg;
     500  while Count > 0 do begin
     501    Memory[Registers[Dest]] := Memory[Registers[Src]];
     502    Inc(Registers[Dest]);
     503    Inc(Registers[Src]);
     504    Dec(Registers[Count]);
     505  end;
     506end;
     507
     508procedure TCPU.OpcodeLddr;
     509var
     510  Dest, Src, Count: TRegIndex;
     511begin
     512  Dest := ReadReg;
     513  Src := ReadReg;
     514  Count := ReadReg;
     515  while Count > 0 do begin
     516    Memory[Registers[Dest]] := Memory[Registers[Src]];
     517    Dec(Registers[Dest]);
     518    Dec(Registers[Src]);
     519    Dec(Registers[Count]);
     520  end;
     521end;
     522
     523{$IFDEF EXT_BIT}
     524procedure TCPU.OpcodeBitSet;
     525var
     526  Reg: TRegIndex;
     527  Bit: TRegIndex;
     528begin
     529  Reg := ReadReg;
     530  Bit := ReadReg;
     531  Registers[Reg] := Registers[Reg] or (1 shl Registers[Bit]);
     532end;
     533
     534procedure TCPU.OpcodeBitReset;
     535var
     536  Reg: TRegIndex;
     537  Bit: TRegIndex;
     538begin
     539  Reg := ReadReg;
     540  Bit := ReadReg;
     541  Registers[Reg] := Registers[Reg] and ((1 shl Registers[Bit]) xor -1);
     542end;
     543
     544procedure TCPU.OpcodeBitGet;
     545var
     546  Reg: TRegIndex;
     547  Bit: TRegIndex;
     548begin
     549  Reg := ReadReg;
     550  Bit := ReadReg;
     551  Condition := ((Registers[Reg] shr Registers[Bit]) and 1) = 1;
     552end;
     553
     554procedure TCPU.OpcodeBitPut;
     555var
     556  Reg: TRegIndex;
     557  Bit: TRegIndex;
     558begin
     559  Reg := ReadReg;
     560  Bit := ReadReg;
     561  if Condition then
     562    Registers[Reg] := Registers[Reg] or (1 shl Registers[Bit]);
     563end;
     564{$ENDIF}
     565
     566{$ENDIF}
    401567
    402568procedure TCPU.Step;
     
    422588  AddOpcode(opNop, @OpcodeNoOperation);
    423589  AddOpcode(opHalt, @OpcodeHalt);
    424   AddOpcode(opAnd, @OpcodeAnd);
    425   AddOpcode(opOr, @OpcodeOr);
    426   AddOpcode(opXor, @OpcodeXor);
    427590  AddOpcode(opLD, @OpcodeLoad);
    428591  AddOpcode(opLDC, @OpcodeLoadConst);
    429592  AddOpcode(opLDM, @OpcodeLoadMemory);
    430593  AddOpcode(opSTM, @OpcodeStoreMemory);
    431   AddOpcode(opLDMD, @OpcodeLoadMemoryDisplacement);
    432   AddOpcode(opSTMD, @OpcodeStoreMemoryDisplacement);
    433   AddOpcode(opCall, @OpcodeCall);
    434   AddOpcode(opRet, @OpcodeReturn);
    435   AddOpcode(opPush, @OpcodePush);
    436   AddOpcode(opPop, @OpcodePop);
     594  AddOpcode(opInc, @OpcodeIncrement);
     595  AddOpcode(opDec, @OpcodeDecrement);
     596  AddOpcode(opTstNZ, @OpcodeTestNotZero);
     597  AddOpcode(opTstZ, @OpcodeTestZero);
     598  AddOpcode(opTstNC, @OpcodeTestNotCarry);
     599  AddOpcode(opTstC, @OpcodeTestCarry);
    437600  AddOpcode(opJP, @OpcodeJump);
    438601  AddOpcode(opJpc, @OpcodeJumpConditional);
    439602  AddOpcode(opJR, @OpcodeJumpRelative);
    440603  AddOpcode(opJRC, @OpcodeJumpRelativeConditional);
     604  {$IFDEF EXT_BIT}
     605  AddOpcode(opBitSet, @OpcodeBitSet);
     606  AddOpcode(opBitRes, @OpcodeBitReset);
     607  AddOpcode(opBitPut, @OpcodeBitPut);
     608  AddOpcode(opBitGet, @OpcodeBitGet);
     609  {$ENDIF}
     610  {$IFDEF EXT_LOGICAL}
     611  AddOpcode(opAnd, @OpcodeAnd);
     612  AddOpcode(opOr, @OpcodeOr);
     613  AddOpcode(opXor, @OpcodeXor);
     614  {$ENDIF}
     615  {$IFDEF EXT_ADDRESSING_MODES}
     616  AddOpcode(opLDMD, @OpcodeLoadMemoryDisplacement);
     617  AddOpcode(opSTMD, @OpcodeStoreMemoryDisplacement);
     618  {$ENDIF}
     619  {$IFDEF EXT_SUBROUTINE}
     620  AddOpcode(opCall, @OpcodeCall);
     621  AddOpcode(opRet, @OpcodeReturn);
     622  {$ENDIF}
     623  {$IFDEF EXT_STACK}
     624  AddOpcode(opPush, @OpcodePush);
     625  AddOpcode(opPop, @OpcodePop);
     626  {$ENDIF}
     627  {$IFDEF EXT_ARITHMETIC}
    441628  AddOpcode(opAdd, @OpcodeAddition);
    442629  AddOpcode(opSub, @OpcodeSubtraction);
    443630  AddOpcode(opMul, @OpcodeMultiplication);
    444631  AddOpcode(opDiv, @OpcodeDivision);
     632  {$ENDIF}
     633  {$IFDEF EXT_GENERAL}
    445634  AddOpcode(opXchg, @OpcodeExchange);
     635  {$ENDIF}
     636  {$IFDEF EXT_SHIFT}
    446637  AddOpcode(opShl, @OpcodeShiftLeft);
    447638  AddOpcode(opShr, @OpcodeShiftRight);
     639  {$ENDIF}
     640  {$IFDEF EXT_IO}
    448641  AddOpcode(opIn, @OpcodeInput);
    449642  AddOpcode(opOut, @OpcodeOutput);
    450   AddOpcode(opInc, @OpcodeIncrement);
    451   AddOpcode(opDec, @OpcodeDecrement);
    452   AddOpcode(opTstNZ, @OpcodeTestNotZero);
    453   AddOpcode(opTstZ, @OpcodeTestZero);
     643  {$ENDIF}
     644  {$IFDEF EXT_BLOCK}
     645  AddOpcode(opLdir, @OpcodeLdir);
     646  AddOpcode(opLddr, @OpcodeLddr);
     647  {$ENDIF}
    454648end;
    455649
Note: See TracChangeset for help on using the changeset viewer.