Changeset 34


Ignore:
Timestamp:
Jul 12, 2022, 11:51:47 PM (2 years ago)
Author:
chronos
Message:
  • Modified: Execute instructions as array of instruction handlers.
  • Modified: Optimized some methods call with inline directive.
Location:
branches/UltimatOS
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • branches/UltimatOS/Forms/UFormMain.lfm

    r32 r34  
    11object FormMain: TFormMain
    22  Left = 227
    3   Height = 707
     3  Height = 814
    44  Top = 205
    5   Width = 998
     5  Width = 1150
    66  Caption = 'UltimatOS'
    7   ClientHeight = 707
    8   ClientWidth = 998
    9   DesignTimePPI = 125
     7  ClientHeight = 814
     8  ClientWidth = 1150
     9  DesignTimePPI = 144
    1010  OnCreate = FormCreate
    1111  OnDestroy = FormDestroy
    1212  OnKeyUp = FormKeyUp
    1313  OnShow = FormShow
    14   LCLVersion = '2.2.0.4'
     14  LCLVersion = '2.2.2.0'
    1515  object PaintBox1: TPaintBox
    16     Left = 8
    17     Height = 480
    18     Top = 8
    19     Width = 640
     16    Left = 9
     17    Height = 553
     18    Top = 9
     19    Width = 737
    2020    OnMouseMove = PaintBox1MouseMove
    2121    OnPaint = PaintBox1Paint
    2222  end
    2323  object ButtonStart: TButton
    24     Left = 8
    25     Height = 33
    26     Top = 496
    27     Width = 98
     24    Left = 9
     25    Height = 38
     26    Top = 571
     27    Width = 113
    2828    Caption = 'Start'
    2929    OnClick = ButtonStartClick
     
    3131  end
    3232  object MemoCode: TMemo
    33     Left = 656
    34     Height = 477
    35     Top = 9
    36     Width = 328
     33    Left = 756
     34    Height = 550
     35    Top = 10
     36    Width = 378
    3737    ScrollBars = ssAutoBoth
    3838    TabOrder = 1
    3939  end
    4040  object Label1: TLabel
    41     Left = 662
    42     Height = 22
    43     Top = 500
    44     Width = 68
     41    Left = 763
     42    Height = 26
     43    Top = 576
     44    Width = 79
    4545    Caption = 'Instrukcí:'
     46    ParentColor = False
    4647  end
    4748  object ButtonMemory: TButton
    48     Left = 550
    49     Height = 33
    50     Top = 496
    51     Width = 98
     49    Left = 634
     50    Height = 38
     51    Top = 571
     52    Width = 113
    5253    Caption = 'Memory'
    5354    OnClick = ButtonMemoryClick
     
    5556  end
    5657  object ButtonStop: TButton
    57     Left = 112
    58     Height = 33
    59     Top = 496
    60     Width = 98
     58    Left = 129
     59    Height = 38
     60    Top = 571
     61    Width = 113
    6162    Caption = 'Stop'
    6263    OnClick = ButtonStopClick
     
    6465  end
    6566  object ButtonRestart: TButton
    66     Left = 216
    67     Height = 33
    68     Top = 496
    69     Width = 98
     67    Left = 249
     68    Height = 38
     69    Top = 571
     70    Width = 113
    7071    Caption = 'Restart'
    7172    OnClick = ButtonRestartClick
     
    7374  end
    7475  object ButtonCompile: TButton
    75     Left = 8
    76     Height = 33
    77     Top = 536
    78     Width = 98
     76    Left = 9
     77    Height = 38
     78    Top = 617
     79    Width = 113
    7980    Caption = 'Compile'
    8081    OnClick = ButtonCompileClick
    8182    TabOrder = 5
    8283  end
     84  object Label2: TLabel
     85    Left = 763
     86    Height = 26
     87    Top = 632
     88    Width = 55
     89    Caption = 'Label2'
     90    ParentColor = False
     91  end
    8392  object Timer1: TTimer
    8493    Interval = 20
    8594    OnTimer = Timer1Timer
    86     Left = 190
    87     Top = 542
     95    Left = 219
     96    Top = 624
     97  end
     98  object Timer2: TTimer
     99    OnTimer = Timer2Timer
     100    Left = 768
     101    Top = 664
    88102  end
    89103end
  • branches/UltimatOS/Forms/UFormMain.pas

    r32 r34  
    1818    ButtonRestart: TButton;
    1919    Label1: TLabel;
     20    Label2: TLabel;
    2021    MemoCode: TMemo;
    2122    PaintBox1: TPaintBox;
    2223    Timer1: TTimer;
     24    Timer2: TTimer;
    2325    procedure ButtonCompileClick(Sender: TObject);
    2426    procedure ButtonMemoryClick(Sender: TObject);
     
    3436    procedure PaintBox1Paint(Sender: TObject);
    3537    procedure Timer1Timer(Sender: TObject);
     38    procedure Timer2Timer(Sender: TObject);
    3639  private
     40    LastTicks: Integer;
    3741    procedure InitProgram;
    3842    procedure UpdateInterface;
     
    143147end;
    144148
     149procedure TFormMain.Timer2Timer(Sender: TObject);
     150begin
     151  Label2.Caption := 'Ticks/s: ' + IntToStr(Machine.Cpu.ExecutedCount - LastTicks);
     152  LastTicks := Machine.Cpu.ExecutedCount;
     153end;
     154
    145155procedure TFormMain.InitProgram;
    146156begin
  • branches/UltimatOS/UCpu.pas

    r32 r34  
    2121
    2222  TCpu = class;
     23  TInstructionHandler = procedure of object;
    2324
    2425  { TCpuThread }
     
    4041    InterruptVector: Integer;
    4142    InterruptEnabled: Boolean;
     43    FInstructionHandlers: array[TInstruction] of TInstructionHandler;
    4244    function GetRunning: Boolean;
    43     function ReadByte: Byte;
    44     function ReadAddress: TAddress;
    45     function ReadData: TData;
    46     procedure Push(Value: Integer);
    47     function Pop: Integer;
     45    function ReadByte: Byte; inline;
     46    function ReadAddress: TAddress; inline;
     47    function ReadData: TData; inline;
     48    procedure Push(Value: Integer); inline;
     49    function Pop: Integer; inline;
    4850    procedure SetRunning(AValue: Boolean);
     51    procedure InitInstructions;
     52    procedure InstructionNop;
     53    procedure InstructionHalt;
     54    procedure InstructionSet;
     55    procedure InstructionInput;
     56    procedure InstructionOutput;
     57    procedure InstructionInc;
     58    procedure InstructionDec;
     59    procedure InstructionJp;
     60    procedure InstructionJpnz;
     61    procedure InstructionJpz;
     62    procedure InstructionAdd;
     63    procedure InstructionSub;
     64    procedure InstructionCall;
     65    procedure InstructionRet;
     66    procedure InstructionPush;
     67    procedure InstructionPop;
     68    procedure InstructionCopy;
     69    procedure InstructionShl;
     70    procedure InstructionShr;
     71    procedure InstructionLoad;
     72    procedure InstructionLoadi;
     73    procedure InstructionStore;
     74    procedure InstructionMul;
     75    procedure InstructionAnd;
     76    procedure InstructionAndi;
     77    procedure InstructionOr;
     78    procedure InstructionXor;
     79    procedure InstructionInt;
     80    procedure InstructionReti;
     81    procedure InstructionEnableInt;
     82    procedure InstructionDisableInt;
    4983  public
    5084    ExecutedCount: Integer;
     
    135169end;
    136170
     171procedure TCpu.InitInstructions;
     172begin
     173  FInstructionHandlers[inNop] := InstructionNop;
     174  FInstructionHandlers[inHalt] := InstructionHalt;
     175  FInstructionHandlers[inSet] := InstructionSet;
     176  FInstructionHandlers[inInput] := InstructionInput;
     177  FInstructionHandlers[inOutput] := InstructionOutput;
     178  FInstructionHandlers[inInc] := InstructionInc;
     179  FInstructionHandlers[inDec] := InstructionDec;
     180  FInstructionHandlers[inJp] := InstructionJp;
     181  FInstructionHandlers[inJpz] := InstructionJpz;
     182  FInstructionHandlers[inJpnz] := InstructionJpnz;
     183  FInstructionHandlers[inAdd] := InstructionAdd;
     184  FInstructionHandlers[inSub] := InstructionSub;
     185  FInstructionHandlers[inCall] := InstructionCall;
     186  FInstructionHandlers[inRet] := InstructionRet;
     187  FInstructionHandlers[inPush] := InstructionPush;
     188  FInstructionHandlers[inPop] := InstructionPop;
     189  FInstructionHandlers[inCopy] := InstructionCopy;
     190  FInstructionHandlers[inShl] := InstructionShl;
     191  FInstructionHandlers[inShr] := InstructionShr;
     192  FInstructionHandlers[inLoad] := InstructionLoad;
     193  FInstructionHandlers[inLoadi] := InstructionLoadi;
     194  FInstructionHandlers[inStore] := InstructionStore;
     195  FInstructionHandlers[inMul] := InstructionMul;
     196  FInstructionHandlers[inAnd] := InstructionAnd;
     197  FInstructionHandlers[inAndi] := InstructionAndi;
     198  FInstructionHandlers[inOr] := InstructionOr;
     199  FInstructionHandlers[inXor] := InstructionXor;
     200  FInstructionHandlers[inInt] := InstructionInt;
     201  FInstructionHandlers[inReti] := InstructionReti;
     202  FInstructionHandlers[inEnableInt] := InstructionEnableInt;
     203  FInstructionHandlers[inDisableInt] := InstructionDisableInt;
     204end;
     205
     206procedure TCpu.InstructionNop;
     207begin
     208  // No operation
     209end;
     210
     211procedure TCpu.InstructionHalt;
     212begin
     213  Terminated := True;
     214end;
     215
     216procedure TCpu.InstructionSet;
     217var
     218  RegIndex: Byte;
     219begin
     220  RegIndex := ReadByte;
     221  R[RegIndex] := ReadData;
     222end;
     223
     224procedure TCpu.InstructionInput;
     225var
     226  RegIndex: Byte;
     227  Address: TAddress;
     228begin
     229  RegIndex := ReadByte;
     230  Address := ReadAddress;
     231  if Assigned(FOnInput) then R[RegIndex] := FOnInput(Address)
     232    else R[RegIndex] := 0;
     233end;
     234
     235procedure TCpu.InstructionOutput;
     236var
     237  RegIndex: Byte;
     238  Address: TAddress;
     239begin
     240  Address := ReadAddress;
     241  RegIndex := ReadByte;
     242  if Assigned(FOnOutput) then FOnOutput(Address, R[RegIndex]);
     243end;
     244
     245procedure TCpu.InstructionInc;
     246var
     247  RegIndex: Byte;
     248begin
     249  RegIndex := ReadByte;
     250  R[RegIndex] := R[RegIndex] + 1;
     251end;
     252
     253procedure TCpu.InstructionDec;
     254var
     255  RegIndex: Byte;
     256begin
     257  RegIndex := ReadByte;
     258  R[RegIndex] := R[RegIndex] - 1;
     259end;
     260
     261procedure TCpu.InstructionJp;
     262begin
     263  IP := ReadAddress;
     264end;
     265
     266procedure TCpu.InstructionJpnz;
     267var
     268  RegIndex: Byte;
     269  Address: TAddress;
     270begin
     271  RegIndex := ReadByte;
     272  Address := ReadAddress;
     273  if R[RegIndex] <> 0 then IP := Address;
     274end;
     275
     276procedure TCpu.InstructionJpz;
     277var
     278  RegIndex: Byte;
     279  Address: TAddress;
     280begin
     281  RegIndex := ReadByte;
     282  Address := ReadAddress;
     283  if R[RegIndex] = 0 then IP := Address;
     284end;
     285
     286procedure TCpu.InstructionAdd;
     287var
     288  RegIndex: Byte;
     289  RegIndex2: Byte;
     290begin
     291  RegIndex := ReadByte;
     292  RegIndex2 := ReadByte;
     293  R[RegIndex] := R[RegIndex] + R[RegIndex2];
     294end;
     295
     296procedure TCpu.InstructionSub;
     297var
     298  RegIndex: Byte;
     299  RegIndex2: Byte;
     300begin
     301  RegIndex := ReadByte;
     302  RegIndex2 := ReadByte;
     303  R[RegIndex] := R[RegIndex] - R[RegIndex2];
     304end;
     305
     306procedure TCpu.InstructionCall;
     307var
     308  Address: TAddress;
     309begin
     310  Address := ReadAddress;
     311  Push(IP);
     312  IP := Address;
     313end;
     314
     315procedure TCpu.InstructionRet;
     316begin
     317  IP := Pop;
     318end;
     319
     320procedure TCpu.InstructionPush;
     321begin
     322  Push(R[ReadByte]);
     323end;
     324
     325procedure TCpu.InstructionPop;
     326begin
     327  R[ReadByte] := Pop;
     328end;
     329
     330procedure TCpu.InstructionCopy;
     331var
     332  RegIndex: Byte;
     333  RegIndex2: Byte;
     334begin
     335  RegIndex := ReadByte;
     336  RegIndex2 := ReadByte;
     337  R[RegIndex] := R[RegIndex2];
     338end;
     339
     340procedure TCpu.InstructionShl;
     341var
     342  RegIndex: Byte;
     343  Num: Byte;
     344begin
     345  RegIndex := ReadByte;
     346  Num := ReadByte;
     347  R[RegIndex] := R[RegIndex] shl Num;
     348end;
     349
     350procedure TCpu.InstructionShr;
     351var
     352  RegIndex: Byte;
     353  Num: Byte;
     354begin
     355  RegIndex := ReadByte;
     356  Num := ReadByte;
     357  R[RegIndex] := R[RegIndex] shr Num;
     358end;
     359
     360procedure TCpu.InstructionLoad;
     361var
     362  RegIndex: Byte;
     363  RegIndex2: Byte;
     364begin
     365  RegIndex := ReadByte;
     366  RegIndex2 := ReadByte;
     367  R[RegIndex] := PData(@Memory.Data[R[RegIndex2]])^;
     368end;
     369
     370procedure TCpu.InstructionLoadi;
     371var
     372  RegIndex: Byte;
     373  Address: TAddress;
     374begin
     375  RegIndex := ReadByte;
     376  Address := ReadAddress;
     377  R[RegIndex] := PData(@Memory.Data[Address])^;
     378end;
     379
     380procedure TCpu.InstructionStore;
     381var
     382  RegIndex: Byte;
     383  RegIndex2: Byte;
     384begin
     385  RegIndex := ReadByte;
     386  RegIndex2 := ReadByte;
     387  PData(@Memory.Data[R[RegIndex2]])^ := R[RegIndex];
     388end;
     389
     390procedure TCpu.InstructionMul;
     391var
     392  RegIndex: Byte;
     393  RegIndex2: Byte;
     394begin
     395  RegIndex := ReadByte;
     396  RegIndex2 := ReadByte;
     397  R[RegIndex] := R[RegIndex] * R[RegIndex2];
     398end;
     399
     400procedure TCpu.InstructionAnd;
     401var
     402  RegIndex: Byte;
     403  RegIndex2: Byte;
     404begin
     405  RegIndex := ReadByte;
     406  RegIndex2 := ReadByte;
     407  R[RegIndex] := R[RegIndex] and R[RegIndex2];
     408end;
     409
     410procedure TCpu.InstructionAndi;
     411var
     412  RegIndex: Byte;
     413begin
     414  RegIndex := ReadByte;
     415  R[RegIndex] := R[RegIndex] and ReadData;
     416end;
     417
     418procedure TCpu.InstructionOr;
     419var
     420  RegIndex: Byte;
     421  RegIndex2: Byte;
     422begin
     423  RegIndex := ReadByte;
     424  RegIndex2 := ReadByte;
     425  R[RegIndex] := R[RegIndex] or R[RegIndex2];
     426end;
     427
     428procedure TCpu.InstructionXor;
     429var
     430  RegIndex: Byte;
     431  RegIndex2: Byte;
     432begin
     433  RegIndex := ReadByte;
     434  RegIndex2 := ReadByte;
     435  R[RegIndex] := R[RegIndex] xor R[RegIndex2];
     436end;
     437
     438procedure TCpu.InstructionInt;
     439begin
     440  Interrupt(ReadByte);
     441end;
     442
     443procedure TCpu.InstructionReti;
     444begin
     445  IP := Pop;
     446  InterruptEnabled := True;
     447end;
     448
     449procedure TCpu.InstructionEnableInt;
     450begin
     451  InterruptEnabled := True;
     452end;
     453
     454procedure TCpu.InstructionDisableInt;
     455begin
     456  InterruptEnabled := False;
     457end;
     458
    137459procedure TCpu.Run;
    138460begin
     
    161483var
    162484  Instruction: TInstruction;
    163   Address: Integer;
    164   RegIndex: Byte;
    165   RegIndex2: Byte;
    166   Num: Byte;
    167485begin
    168486  Instruction := TInstruction(ReadByte);
     487  if Assigned(FInstructionHandlers[Instruction]) then
     488    FInstructionHandlers[Instruction]
     489    else raise Exception.Create('Missing handler for instruction ' + IntToStr(Integer(Instruction)));
    169490  Inc(ExecutedCount);
    170   case Instruction of
    171     inNop: ;
    172     inHalt: Terminated := True;
    173     inSet: begin
    174       RegIndex := ReadByte;
    175       R[RegIndex] := ReadData;
    176     end;
    177     inLoad: begin
    178       RegIndex := ReadByte;
    179       RegIndex2 := ReadByte;
    180       R[RegIndex] := PData(@Memory.Data[R[RegIndex2]])^;
    181     end;
    182     inLoadi: begin
    183       RegIndex := ReadByte;
    184       Address := ReadAddress;
    185       R[RegIndex] := PData(@Memory.Data[Address])^;
    186     end;
    187     inStore: begin
    188       RegIndex := ReadByte;
    189       RegIndex2 := ReadByte;
    190       PData(@Memory.Data[R[RegIndex2]])^ := R[RegIndex];
    191     end;
    192     inInput: begin
    193       RegIndex := ReadByte;
    194       Address := ReadAddress;
    195       if Assigned(FOnInput) then R[RegIndex] := FOnInput(Address)
    196         else R[RegIndex] := 0;
    197     end;
    198     inOutput: begin
    199       Address := ReadAddress;
    200       RegIndex := ReadByte;
    201       if Assigned(FOnOutput) then FOnOutput(Address, R[RegIndex]);
    202     end;
    203     inInc: begin
    204       RegIndex := ReadByte;
    205       R[RegIndex] := R[RegIndex] + 1;
    206     end;
    207     inDec: begin
    208       RegIndex := ReadByte;
    209       R[RegIndex] := R[RegIndex] - 1;
    210     end;
    211     inJp: begin
    212       IP := ReadAddress;
    213     end;
    214     inJpz: begin
    215       RegIndex := ReadByte;
    216       Address := ReadAddress;
    217       if R[RegIndex] = 0 then IP := Address;
    218     end;
    219     inJpnz: begin
    220       RegIndex := ReadByte;
    221       Address := ReadAddress;
    222       if R[RegIndex] <> 0 then IP := Address;
    223     end;
    224     inAdd: begin
    225       RegIndex := ReadByte;
    226       RegIndex2 := ReadByte;
    227       R[RegIndex] := R[RegIndex] + R[RegIndex2];
    228     end;
    229     inSub: begin
    230       RegIndex := ReadByte;
    231       RegIndex2 := ReadByte;
    232       R[RegIndex] := R[RegIndex] - R[RegIndex2];
    233     end;
    234     inPush: begin
    235       RegIndex := ReadByte;
    236       Push(R[RegIndex]);
    237     end;
    238     inPop: begin
    239       RegIndex := ReadByte;
    240       R[RegIndex] := Pop;
    241     end;
    242     inCall: begin
    243       Address := ReadAddress;
    244       Push(IP);
    245       IP := Address;
    246     end;
    247     inRet: begin
    248       IP := Pop;
    249     end;
    250     inCopy: begin
    251       RegIndex := ReadByte;
    252       RegIndex2 := ReadByte;
    253       R[RegIndex] := R[RegIndex2];
    254     end;
    255     inShl: begin
    256       RegIndex := ReadByte;
    257       Num := ReadByte;
    258       R[RegIndex] := R[RegIndex] shl Num;
    259     end;
    260     inShr: begin
    261       RegIndex := ReadByte;
    262       Num := ReadByte;
    263       R[RegIndex] := R[RegIndex] shr Num;
    264     end;
    265     inMul: begin
    266       RegIndex := ReadByte;
    267       RegIndex2 := ReadByte;
    268       R[RegIndex] := R[RegIndex] * R[RegIndex2];
    269     end;
    270     inAnd: begin
    271       RegIndex := ReadByte;
    272       RegIndex2 := ReadByte;
    273       R[RegIndex] := R[RegIndex] and R[RegIndex2];
    274     end;
    275     inAndi: begin
    276       RegIndex := ReadByte;
    277       R[RegIndex] := R[RegIndex] and ReadData;
    278     end;
    279     inOr: begin
    280       RegIndex := ReadByte;
    281       RegIndex2 := ReadByte;
    282       R[RegIndex] := R[RegIndex] or R[RegIndex2];
    283     end;
    284     inXor: begin
    285       RegIndex := ReadByte;
    286       RegIndex2 := ReadByte;
    287       R[RegIndex] := R[RegIndex] xor R[RegIndex2];
    288     end;
    289     inInt: begin
    290       Interrupt(ReadByte);
    291     end;
    292     inReti: begin
    293       IP := Pop;
    294       InterruptEnabled := True;
    295     end;
    296     inEnableInt: InterruptEnabled := True;
    297     inDisableInt: InterruptEnabled := False;
    298   end;
    299491end;
    300492
     
    319511constructor TCpu.Create;
    320512begin
     513  InitInstructions;
    321514end;
    322515
  • branches/UltimatOS/UMachine.pas

    r32 r34  
    1414    Machine: TMachine;
    1515    procedure Reset; virtual;
     16    procedure OutputHandler(Port: TAddress; Data: TData); virtual; abstract;
     17    function InputHandler(Port: TAddress): TData;  virtual; abstract;
    1618  end;
    1719
     
    8789  end;
    8890
     91  { TStorage }
     92
     93  TStorage = class(TDevice)
     94  public
     95    F: TFileStream;
     96    FileName: string;
     97    constructor Create;
     98    procedure OutputHandler(Port: TAddress; Data: TData); override;
     99    function InputHandler(Port: TAddress): TData; override;
     100  end;
     101
    89102  { TMachine }
    90103
     
    110123
    111124implementation
     125
     126{ TStorage }
     127
     128constructor TStorage.Create;
     129begin
     130
     131end;
     132
     133procedure TStorage.OutputHandler(Port: TAddress; Data: TData);
     134begin
     135
     136end;
     137
     138function TStorage.InputHandler(Port: TAddress): TData;
     139begin
     140
     141end;
    112142
    113143{ TMouse }
  • branches/UltimatOS/UMemory.pas

    r29 r34  
    1111  TMemory = class
    1212  private
     13    FSize: Integer;
    1314    function GetSize: Integer;
    1415    procedure SetSize(AValue: Integer);
    1516  public
    1617    Data: PByte;
    17     property Size: Integer read GetSize write SetSize;
     18    property Size: Integer read FSize write SetSize;
    1819    constructor Create;
    1920    destructor Destroy; override;
     
    3233procedure TMemory.SetSize(AValue: Integer);
    3334begin
     35  if FSize = AValue then Exit;
     36  FSize := AValue;
    3437  Data := ReAllocMem(Data, AValue);
    3538end;
Note: See TracChangeset for help on using the changeset viewer.