Changeset 42 for branches/simple/Cpu.pas


Ignore:
Timestamp:
Sep 8, 2023, 11:20:27 PM (9 months ago)
Author:
chronos
Message:
  • Modified: Improved simple virtual machine.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/simple/Cpu.pas

    r41 r42  
    44
    55uses
    6   Classes, SysUtils, DataBus;
     6  Classes, SysUtils, Channel;
    77
    88type
    9   TInstruction = (inLoadImmediate8, inLoadImmediate16, inLoad8, inLoad16,
    10     inStore8, inStore16, inInput8, inInput16, inOutput8, inOutput16,
    11     inHalt, inJump);
     9  TInstruction = (inLoadImmediate, inLoadImmediate8, inLoadImmediate16,
     10    inLoad, inLoad8, inLoad16, inLoad32, inLoad64,
     11    inStore, inStore8, inStore16, inStore32, inStore64,
     12    inInput, inInput8, inInput16, inInput32, inInput64,
     13    inOutput, inOutput8, inOutput16, inOutput32, inOutput64,
     14    inNop, inHalt, inJump);
    1215
    1316  { TCpu8 }
     
    1619  private
    1720  public
    18     IO: TDataBus8;
    19     Memory: TDataBus8;
     21    IO: TAddressableChannel8;
     22    Memory: TAddressableChannel8;
    2023    Terminated: Boolean;
    2124    A: Byte;
     
    2528    procedure Run;
    2629    procedure Step;
     30    constructor Create;
     31    destructor Destroy; override;
    2732  end;
    2833
     
    3237  private
    3338  public
    34     IO: TDataBus16;
    35     Memory: TDataBus16;
     39    IO: TAddressableChannel16;
     40    Memory: TAddressableChannel16;
    3641    Terminated: Boolean;
    3742    A: Word;
     
    4247    procedure Run;
    4348    procedure Step;
     49    constructor Create;
     50    destructor Destroy; override;
     51  end;
     52
     53  TCpu = class
     54    BitWidth: TBitWidth;
     55    Cpu8: TCpu8;
     56    Cpu16: TCpu16;
     57  end;
     58
     59  TRegMulti = record
     60    case Byte of
     61      0: (ValueByte: Byte);
     62      1: (ValueWord: Word);
     63  end;
     64
     65  { TCpuMulti }
     66
     67  TCpuMulti = class
     68  private
     69  public
     70    IO: TAddressableChannelMulti;
     71    Memory: TAddressableChannelMulti;
     72    Terminated: Boolean;
     73    A: TRegMulti;
     74    PC: TRegMulti;
     75    BitWidth: TBitWidth;
     76    function ReadProg8: Byte;
     77    function ReadProg16: Word;
     78    procedure Reset;
     79    procedure Run;
     80    procedure Step;
     81    constructor Create;
     82    destructor Destroy; override;
    4483  end;
    4584
    4685
    4786implementation
     87
     88{ TCpuMulti }
     89
     90function TCpuMulti.ReadProg8: Byte;
     91begin
     92  case BitWidth of
     93    bw8: begin
     94      Result := Memory.ReadA8D8(PC.ValueByte);
     95      Inc(PC.ValueByte);
     96    end;
     97    bw16: begin
     98      Result := Memory.ReadA16D8(PC.ValueWord);
     99      Inc(PC.ValueWord);
     100    end;
     101  end;
     102end;
     103
     104function TCpuMulti.ReadProg16: Word;
     105begin
     106  case BitWidth of
     107    //bw8: begin
     108    //  Result := Memory.ReadA8D16(PC.ValueByte);
     109    //  Inc(PC.ValueByte);
     110    //end;
     111    bw16: begin
     112      Result := Memory.ReadA16D16(PC.ValueWord);
     113      Inc(PC.ValueWord);
     114    end;
     115  end;
     116end;
     117
     118procedure TCpuMulti.Reset;
     119begin
     120  Terminated := False;
     121  PC.ValueWord := 0;
     122end;
     123
     124procedure TCpuMulti.Run;
     125begin
     126  while not Terminated do
     127    Step;
     128end;
     129
     130procedure TCpuMulti.Step;
     131var
     132  Instruction: TInstruction;
     133begin
     134  Instruction := TInstruction(ReadProg8);
     135  case Instruction of
     136    inNop: ;
     137    inHalt: Terminated := True;
     138    inLoadImmediate8: A.ValueByte := ReadProg8;
     139    inLoadImmediate16: A.ValueWord := ReadProg16;
     140    inLoadImmediate: case BitWidth of
     141      bw8: A.ValueByte := ReadProg8;
     142      bw16: A.ValueWord := ReadProg16;
     143    end;
     144    inLoad8: case BitWidth of
     145      bw8: A.ValueByte := Memory.ReadA8D8(ReadProg8);
     146      bw16: A.ValueByte := Memory.ReadA16D8(ReadProg16);
     147    end;
     148    inLoad16: case BitWidth of
     149      //bw8: A.ValueWord := Memory.ReadA8D16(ReadProg8);
     150      bw16: A.ValueWord := Memory.ReadA16D16(ReadProg16);
     151    end;
     152    inLoad: case BitWidth of
     153      bw8: A.ValueByte := Memory.ReadA8D8(ReadProg8);
     154      bw16: A.ValueWord := Memory.ReadA16D16(ReadProg16);
     155    end;
     156    inStore8: case BitWidth of
     157      bw8: Memory.WriteA8D8(ReadProg8, A.ValueByte);
     158      bw16: Memory.WriteA16D8(ReadProg16, A.ValueByte);
     159    end;
     160    inStore16: case BitWidth of
     161      //bw8: Memory.WriteA8D16(ReadProg8, A.ValueWord);
     162      bw16: Memory.WriteA16D16(ReadProg16, A.ValueWord);
     163    end;
     164    inStore: case BitWidth of
     165      bw8: Memory.WriteA8D8(ReadProg8, A.ValueByte);
     166      bw16: Memory.WriteA16D16(ReadProg16, A.ValueWord);
     167    end;
     168    inInput8: case BitWidth of
     169      bw8: A.ValueByte := IO.ReadA8D8(ReadProg8);
     170      bw16: A.ValueByte := IO.ReadA16D8(ReadProg16);
     171    end;
     172    inInput16: case BitWidth of
     173      //bw8: A.ValueWord := IO.ReadA8D16(ReadProg8);
     174      bw16: A.ValueWord := IO.ReadA16D16(ReadProg16);
     175    end;
     176    inInput: case BitWidth of
     177      bw8: A.ValueByte := IO.ReadA8D8(ReadProg8);
     178      bw16: A.ValueWord := IO.ReadA16D16(ReadProg16);
     179    end;
     180    inOutput8: case BitWidth of
     181      bw8: IO.WriteA8D8(ReadProg8, A.ValueByte);
     182      bw16: IO.WriteA16D8(ReadProg16, A.ValueWord);
     183    end;
     184    inOutput16: case BitWidth of
     185      //bw8: IO.WriteA8D16(ReadProg8, A.ValueWord);
     186      bw16: IO.WriteA16D16(ReadProg16, A.ValueWord);
     187    end;
     188    inOutput: case BitWidth of
     189      bw8: IO.WriteA8D8(ReadProg8, A.ValueByte);
     190      bw16: IO.WriteA16D16(ReadProg16, A.ValueWord);
     191    end;
     192    inJump: case BitWidth of
     193      bw8: PC.ValueByte := ReadProg8;
     194      bw16: PC.ValueWord := ReadProg16;
     195    end;
     196  end;
     197end;
     198
     199constructor TCpuMulti.Create;
     200begin
     201  IO := TAddressableChannelMulti.Create;
     202  Memory := TAddressableChannelMulti.Create;
     203end;
     204
     205destructor TCpuMulti.Destroy;
     206begin
     207  FreeAndNil(IO);
     208  FreeAndNil(Memory);
     209  inherited;
     210end;
    48211
    49212{ TCpu16 }
     
    58221begin
    59222  Result := Memory.Read16(PC);
    60   Inc(PC, 2);
     223  Inc(PC, SizeOf(Word));
    61224end;
    62225
     
    79242  Instruction := TInstruction(ReadProg8);
    80243  case Instruction of
     244    inNop: ;
    81245    inHalt: Terminated := True;
    82     inLoadImmediate8: A := ReadProg8;
     246    inLoadImmediate8: A := (A and $ff00) or ReadProg8;
    83247    inLoadImmediate16: A := ReadProg16;
    84     inLoad8: A := Memory.Read8(ReadProg16);
     248    inLoadImmediate: A := ReadProg16;
     249    inLoad8: A := (A and $ff00) or Memory.Read8(ReadProg16);
    85250    inLoad16: A := Memory.Read16(ReadProg16);
     251    inLoad: A := Memory.Read16(ReadProg16);
    86252    inStore8: Memory.Write8(ReadProg16, A);
    87253    inStore16: Memory.Write16(ReadProg16, A);
    88     inInput8: A := IO.Read8(ReadProg16);
     254    inStore: Memory.Write16(ReadProg16, A);
     255    inInput8: A := (A and $ff00) or IO.Read8(ReadProg16);
    89256    inInput16: A := IO.Read16(ReadProg16);
     257    inInput: A := IO.Read16(ReadProg16);
    90258    inOutput8: IO.Write8(ReadProg16, A);
    91259    inOutput16: IO.Write16(ReadProg16, A);
     260    inOutput: IO.Write16(ReadProg16, A);
    92261    inJump: PC := ReadProg16;
    93262  end;
     263end;
     264
     265constructor TCpu16.Create;
     266begin
     267  IO := TAddressableChannel16.Create;
     268  Memory := TAddressableChannel16.Create;
     269end;
     270
     271destructor TCpu16.Destroy;
     272begin
     273  FreeAndNil(IO);
     274  FreeAndNil(Memory);
     275  inherited;
    94276end;
    95277
     
    120302  Instruction := TInstruction(ReadProg8);
    121303  case Instruction of
    122     inLoadImmediate8: A := ReadProg8;
    123     inLoad8: A := Memory.Read8(ReadProg8);
    124     inStore8: Memory.Write8(ReadProg8, A);
    125     inInput8: A := IO.Read8(ReadProg8);
    126     inOutput8: IO.Write8(ReadProg8, A);
     304    inNop: ;
     305    inLoadImmediate, inLoadImmediate8: A := ReadProg8;
     306    inLoad, inLoad8: A := Memory.Read8(ReadProg8);
     307    inStore, inStore8: Memory.Write8(ReadProg8, A);
     308    inInput, inInput8: A := IO.Read8(ReadProg8);
     309    inOutput, inOutput8: IO.Write8(ReadProg8, A);
    127310    inHalt: Terminated := True;
    128311    inJump: PC := ReadProg8;
     
    130313end;
    131314
     315constructor TCpu8.Create;
     316begin
     317  IO := TAddressableChannel8.Create;
     318  Memory := TAddressableChannel8.Create;
     319end;
     320
     321destructor TCpu8.Destroy;
     322begin
     323  FreeAndNil(IO);
     324  FreeAndNil(Memory);
     325  inherited;
     326end;
     327
    132328end.
    133329
Note: See TracChangeset for help on using the changeset viewer.