Ignore:
Timestamp:
Sep 22, 2019, 7:13:15 PM (5 years ago)
Author:
chronos
Message:
  • Modified: Address CPU memory as pointer instead array of bytes.
  • Added: TMachine class to represent virtual machine itself.
Location:
branches/virtcpu varint
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/virtcpu varint

    • Property svn:ignore set to
      lib
      virtcpu
      virtcpu.lps
  • branches/virtcpu varint/UMachine.pas

    r195 r196  
    11unit UMachine;
    2 
    32
    43{$mode delphi}{$H+}
     
    8584    procedure OpcodeLddr;
    8685  public
     86    Memory: Pointer;
    8787    Registers: array of T;
    8888    IP: T;
     89    SP: T;
    8990    Condition: Boolean;
    90     SP: T;
    91     Memory: array of Byte;
    9291    Terminated: Boolean;
    9392    Ticks: Integer;
    9493    procedure Start;
    9594    procedure Stop;
     95    procedure Step; inline;
    9696    constructor Create(AOwner: TComponent); override;
    9797  published
     
    100100  end;
    101101
     102  { TMachine }
     103
     104  TMachine = class(TComponent)
     105  private
     106    FMemorySize: Integer;
     107    procedure SetMemorySize(AValue: Integer);
     108  public
     109    Cpu: TCpu;
     110    Memory: Pointer;
     111    property MemorySize: Integer read FMemorySize write SetMemorySize;
     112    constructor Create(AOwner: TComponent); override;
     113    destructor Destroy; override;
     114  end;
     115
    102116
    103117implementation
    104118
     119{ TMachine }
     120
     121procedure TMachine.SetMemorySize(AValue: Integer);
     122begin
     123  if FMemorySize = AValue then Exit;
     124  FMemorySize := AValue;
     125  Memory := ReAllocMem(Memory, FMemorySize);
     126  Cpu.Memory := Memory;
     127end;
     128
     129constructor TMachine.Create(AOwner: TComponent);
     130begin
     131  inherited;
     132  Cpu := TCpu.Create(nil);
     133  MemorySize := 1000;
     134end;
     135
     136destructor TMachine.Destroy;
     137begin
     138  MemorySize := 0;
     139  FreeAndNil(Cpu);
     140  inherited Destroy;
     141end;
     142
    105143{ TCPU }
    106144
    107145function TCPU.ReadNext: T;
    108146begin
    109   IP := IP + Result.ReadFromAddr(@Memory[IP]);
     147  IP := IP + Result.ReadFromAddr(Pointer(NativeUInt(Memory) + IP));
    110148end;
    111149
     
    147185  P1 := ReadNext;
    148186  P2 := ReadNext;
    149   Registers[P1] := Memory[Registers[P2]];
     187  Registers[P1].ReadFromAddr(Pointer(NativeUInt(Memory) + Integer(Registers[P2])));
    150188end;
    151189
     
    157195  P1 := ReadNext;
    158196  P2 := ReadNext;
    159   Memory[Registers[P1]] := Registers[P2];
     197  Registers[P2].WriteToAddr(Pointer(NativeUInt(Memory) + Registers[P1]));
    160198end;
    161199
     
    307345  P1 := ReadNext;
    308346  SP := SP - Registers[P1].GetByteSize;
    309   Registers[P1].WriteToAddr(@Memory[SP]);
     347  Registers[P1].WriteToAddr(Pointer(NativeUInt(Memory) + Integer(SP)));
    310348end;
    311349
    312350procedure TCPU.OpcodePop;
    313351begin
    314   SP := SP + Registers[ReadNext].ReadFromAddr(@Memory[SP]);
     352  SP := SP + Registers[ReadNext].ReadFromAddr(Pointer(NativeUInt(Memory) + Integer(SP)));
    315353end;
    316354
     
    321359  Addr := ReadNext;
    322360  SP := SP - IP.GetByteSize;
    323   IP.WriteToAddr(@Memory[SP]);
     361  IP.WriteToAddr(Pointer(NativeUInt(Memory) + SP));
    324362  IP := Addr;
    325363end;
     
    331369  Addr := ReadNext;
    332370  SP := SP - IP.GetByteSize;
    333   IP.WriteToAddr(@Memory[SP]);
     371  IP.WriteToAddr(Pointer(NativeUInt(Memory) + SP));
    334372  IP := IP + Addr;
    335373end;
    336374
    337375procedure TCPU.OpcodeReturn;
    338 var
    339   S: Integer;
    340 begin
    341   SP := SP + IP.ReadFromAddr(@Memory[SP]);
     376begin
     377  SP := SP + IP.ReadFromAddr(Pointer(NativeUInt(Memory) + SP));
    342378end;
    343379
     
    424460  Src: T;
    425461  Dst: T;
    426   Size: T;
     462  Count: T;
     463  Bytes: T;
    427464begin
    428465  Src := ReadNext;
    429466  Dst := ReadNext;
    430   Size := ReadNext;
    431   while Registers[Size] > 0 do begin
    432     Memory[Registers[Dst]] := Memory[Registers[Src]];
    433     Inc(Registers[Src]);
    434     Inc(Registers[Dst]);
    435     Dec(Registers[Size]);
     467  Count := ReadNext;
     468  Bytes := ReadNext;
     469  while Registers[Count] > 0 do begin
     470    Move(Pointer(NativeUInt(Memory) + Registers[Src])^,
     471      Pointer(NativeUInt(Memory) + Registers[Dst])^, Bytes);
     472    Inc(Registers[Src], Bytes);
     473    Inc(Registers[Dst], Bytes);
     474    Dec(Registers[Count]);
    436475  end;
    437476end;
     
    441480  Src: T;
    442481  Dst: T;
    443   Size: T;
     482  Count: T;
     483  Bytes: T;
    444484begin
    445485  Src := ReadNext;
    446486  Dst := ReadNext;
    447   Size := ReadNext;
    448   while Registers[Size] > 0 do begin
    449     Memory[Registers[Dst]] := Memory[Registers[Src]];
    450     Dec(Registers[Src]);
    451     Dec(Registers[Dst]);
    452     Dec(Registers[Size]);
     487  Count := ReadNext;
     488  Bytes := ReadNext;
     489  while Registers[Count] > 0 do begin
     490    Move(Pointer(NativeUInt(Memory) + Registers[Src])^,
     491      Pointer(NativeUInt(Memory) + Registers[Dst])^, Bytes);
     492    Dec(Registers[Src], Bytes);
     493    Dec(Registers[Dst], Bytes);
     494    Dec(Registers[Count]);
    453495  end;
    454496end;
    455497
    456498procedure TCPU.Start;
    457 var
    458   Opcode: T;
    459499begin
    460500  Terminated := False;
    461501  Ticks := 0;
    462502  IP := 0;
    463   SP := Length(Memory);
    464   while not Terminated do begin
    465     Opcode := ReadNext;
    466     if (Opcode >= 0) and (Opcode <= T(Integer(High(TOpcode)))) then
    467       OpcodeHandlers[TOpcode(Byte(Opcode))]
    468       else raise Exception.Create(Format('Unsupported instruction %d', [Int64(Opcode)]));
    469     Inc(Ticks);
    470   end;
     503  SP := MemSize(Memory);
     504  while not Terminated do
     505    Step;
    471506end;
    472507
     
    474509begin
    475510  Terminated := True;
     511end;
     512
     513procedure TCPU.Step;
     514var
     515  Opcode: T;
     516begin
     517  Opcode := ReadNext;
     518  if (Opcode >= 0) and (Opcode <= T(Integer(High(TOpcode)))) then
     519    OpcodeHandlers[TOpcode(Byte(Opcode))]
     520    else raise Exception.Create(Format('Unsupported instruction %d on address %x', [Int64(Opcode), Int64(IP)]));
     521  Inc(Ticks);
    476522end;
    477523
     
    480526  inherited;
    481527  SetLength(Registers, 16);
    482   SetLength(Memory, 1024);
    483528  OpcodeHandlers[opNop] := OpcodeNop;
    484529  OpcodeHandlers[opHalt] := OpcodeHalt;
Note: See TracChangeset for help on using the changeset viewer.