Changeset 175 for branches


Ignore:
Timestamp:
Apr 12, 2019, 1:34:47 AM (6 years ago)
Author:
chronos
Message:
  • Added: Drawing to video memory.
Location:
branches/virtualcpu4
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/virtualcpu4/UCpu.pas

    r174 r175  
    153153
    154154procedure TCpu.InstLoadImmediate;
    155 begin
    156   case DataSize of
    157     bw8: Registers[Read8].B := Read8;
    158     bw16: Registers[Read8].W := Read16;
    159     bw32: Registers[Read8].D := Read32;
    160     bw64: Registers[Read8].Q := Read64;
     155var
     156  R: TRegIndex;
     157begin
     158  R := Read8;
     159  case DataSize of
     160    bw8: Registers[R].B := Read8;
     161    bw16: Registers[R].W := Read16;
     162    bw32: Registers[R].D := Read32;
     163    bw64: Registers[R].Q := Read64;
    161164  end;
    162165end;
     
    219222
    220223procedure TCpu.InstLoadMem;
    221 begin
    222   case DataSize of
    223     bw8: Registers[Read8].B := PByte(Memory + PAddress(@Registers[Read8])^)^;
    224     bw16: Registers[Read8].W := PWord(Memory + PAddress(@Registers[Read8])^)^;
    225     bw32: Registers[Read8].D := PDWord(Memory + PAddress(@Registers[Read8])^)^;
    226     bw64: Registers[Read8].Q := PQWord(Memory + PAddress(@Registers[Read8])^)^;
     224var
     225  R1, R2: TRegIndex;
     226begin
     227  R1 := Read8;
     228  R2 := Read8;
     229  case AddressSize of
     230    bw8: case DataSize of
     231      bw8: Registers[R1].B := PByte(Memory + PByte(@Registers[R2])^)^;
     232      bw16: Registers[R1].W := PWord(Memory + PByte(@Registers[R2])^)^;
     233      bw32: Registers[R1].D := PDWord(Memory + PByte(@Registers[R2])^)^;
     234      bw64: Registers[R1].Q := PQWord(Memory + PByte(@Registers[R2])^)^;
     235    end;
     236    bw16: case DataSize of
     237      bw8: Registers[R1].B := PByte(Memory + PWord(@Registers[R2])^)^;
     238      bw16: Registers[R1].W := PWord(Memory + PWord(@Registers[R2])^)^;
     239      bw32: Registers[R1].D := PDWord(Memory + PWord(@Registers[R2])^)^;
     240      bw64: Registers[R1].Q := PQWord(Memory + PWord(@Registers[R2])^)^;
     241    end;
     242    bw32: case DataSize of
     243      bw8: Registers[R1].B := PByte(Memory + PDWord(@Registers[R2])^)^;
     244      bw16: Registers[R1].W := PWord(Memory + PDWord(@Registers[R2])^)^;
     245      bw32: Registers[R1].D := PDWord(Memory + PDWord(@Registers[R2])^)^;
     246      bw64: Registers[R1].Q := PQWord(Memory + PDWord(@Registers[R2])^)^;
     247    end;
     248    bw64: case DataSize of
     249      bw8: Registers[R1].B := PByte(Memory + PQWord(@Registers[R2])^)^;
     250      bw16: Registers[R1].W := PWord(Memory + PQWord(@Registers[R2])^)^;
     251      bw32: Registers[R1].D := PDWord(Memory + PQWord(@Registers[R2])^)^;
     252      bw64: Registers[R1].Q := PQWord(Memory + PQWord(@Registers[R2])^)^;
     253    end;
    227254  end;
    228255end;
    229256
    230257procedure TCpu.InstStoreMem;
    231 begin
    232   case DataSize of
    233     bw8: PByte(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].B;
    234     bw16: PWord(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].W;
    235     bw32: PDWord(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].D;
    236     bw64: PQWord(Memory + PAddress(@Registers[Read8])^)^ := Registers[Read8].Q;
     258var
     259  R1, R2: TRegIndex;
     260begin
     261  R1 := Read8;
     262  R2 := Read8;
     263  case AddressSize of
     264    bw8: case DataSize of
     265      bw8: PByte(Memory + PByte(@Registers[R1])^)^ := Registers[R2].B;
     266      bw16: PWord(Memory + PByte(@Registers[R1])^)^ := Registers[R2].W;
     267      bw32: PDWord(Memory + PByte(@Registers[R1])^)^ := Registers[R2].D;
     268      bw64: PQWord(Memory + PByte(@Registers[R1])^)^ := Registers[R2].Q;
     269    end;
     270    bw16: case DataSize of
     271      bw8: PByte(Memory + PWord(@Registers[R1])^)^ := Registers[R2].B;
     272      bw16: PWord(Memory + PWord(@Registers[R1])^)^ := Registers[R2].W;
     273      bw32: PDWord(Memory + PWord(@Registers[R1])^)^ := Registers[R2].D;
     274      bw64: PQWord(Memory + PWord(@Registers[R1])^)^ := Registers[R2].Q;
     275    end;
     276    bw32: case DataSize of
     277      bw8: PByte(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].B;
     278      bw16: PWord(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].W;
     279      bw32: PDWord(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].D;
     280      bw64: PQWord(Memory + PDWord(@Registers[R1])^)^ := Registers[R2].Q;
     281    end;
     282    bw64: case DataSize of
     283      bw8: PByte(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].B;
     284      bw16: PWord(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].W;
     285      bw32: PDWord(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].D;
     286      bw64: PQWord(Memory + PQWord(@Registers[R1])^)^ := Registers[R2].Q;
     287    end;
    237288  end;
    238289end;
     
    436487procedure TCpu.InstDec;
    437488var
    438   R1: TRegIndex;
    439 begin
    440   R1 := Read8;
    441   case DataSize of
    442     bw8: Registers[R1].B := Registers[R1].B - 1;
    443     bw16: Registers[R1].W := Registers[R1].W - 1;
    444     bw32: Registers[R1].D := Registers[R1].D - 1;
    445     bw64: Registers[R1].Q := Registers[R1].Q - 1;
     489  R: TRegIndex;
     490begin
     491  R := Read8;
     492  case DataSize of
     493    bw8: Registers[R].B := Registers[R].B - 1;
     494    bw16: Registers[R].W := Registers[R].W - 1;
     495    bw32: Registers[R].D := Registers[R].D - 1;
     496    bw64: Registers[R].Q := Registers[R].Q - 1;
    446497  end;
    447498end;
     
    450501begin
    451502  case AddressSize of
    452     bw8: if Z then IP := Read8;
    453     bw16: if Z then IP := Read16;
    454     bw32: if Z then IP := Read32;
    455     bw64: if Z then IP := Read64;
     503    bw8: if Z then IP := Read8 else Read8;
     504    bw16: if Z then IP := Read16 else Read16;
     505    bw32: if Z then IP := Read32 else Read32;
     506    bw64: if Z then IP := Read64 else Read64;
    456507  end;
    457508end;
     
    460511begin
    461512  case AddressSize of
    462     bw8: if not Z then IP := Read8;
    463     bw16: if not Z then IP := Read16;
    464     bw32: if not Z then IP := Read32;
    465     bw64: if not Z then IP := Read64;
     513    bw8: if not Z then IP := Read8 else Read8;
     514    bw16: if not Z then IP := Read16 else Read16;
     515    bw32: if not Z then IP := Read32 else Read32;
     516    bw64: if not Z then IP := Read64 else Read64;
    466517  end;
    467518end;
     
    913964    if Assigned(Instructions[TOpcode(Opcode)]) then Instructions[TOpcode(Opcode)]
    914965      else raise Exception.Create('Missing instruction handler for opcode '+ IntToStr(Opcode));
    915   end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP, 8) + '.');
     966  end else raise Exception.Create('Unsupported opcode ' + IntToStr(Opcode) + ' at address ' + IntToHex(IP - 1, 8) + '.');
    916967  if DataSizeLast <> bwNone then begin
    917968    DataSize := DataSizeLast;
  • branches/virtualcpu4/UFormMain.lfm

    r173 r175  
    8787  object Memo1: TMemo
    8888    Left = 1181
    89     Height = 743
     89    Height = 344
    9090    Top = 192
    9191    Width = 518
     
    104104    ParentFont = False
    105105  end
     106  object PaintBox1: TPaintBox
     107    Left = 1181
     108    Height = 374
     109    Top = 552
     110    Width = 518
     111    OnPaint = PaintBox1Paint
     112    OnResize = PaintBox1Resize
     113  end
    106114  object Timer1: TTimer
    107115    Interval = 100
     
    110118    top = 173
    111119  end
     120  object TimerDraw: TTimer
     121    OnTimer = TimerDrawTimer
     122    left = 104
     123    top = 304
     124  end
    112125end
  • branches/virtualcpu4/UFormMain.pas

    r174 r175  
    2121    ListViewRegisters: TListView;
    2222    Memo1: TMemo;
     23    PaintBox1: TPaintBox;
    2324    Timer1: TTimer;
     25    TimerDraw: TTimer;
    2426    procedure ButtonStartClick(Sender: TObject);
    2527    procedure ButtonStopClick(Sender: TObject);
     
    3032    procedure ListViewRegistersData(Sender: TObject; Item: TListItem);
    3133    procedure Memo1KeyPress(Sender: TObject; var Key: char);
     34    procedure PaintBox1Paint(Sender: TObject);
     35    procedure PaintBox1Resize(Sender: TObject);
    3236    procedure Timer1Timer(Sender: TObject);
     37    procedure TimerDrawTimer(Sender: TObject);
    3338  private
    3439    procedure ReloadMemoryDump;
     
    8590  I: Integer;
    8691begin
    87   if Item.Index < Length(Machine.Memory) div ItemsPerLine then begin
     92  if Item.Index < Machine.MemorySize div ItemsPerLine then begin
    8893    Line := '';
    8994    for I := 0 to ItemsPerLine - 1 do
    90       Line := Line + IntToHex(Machine.Memory[Item.Index * ItemsPerLine + I], 2) + ' ';
     95      Line := Line + IntToHex(PByte(Machine.Memory + Item.Index * ItemsPerLine + I)^, 2) + ' ';
    9196    Item.Caption := IntToHex(Item.Index * ItemsPerLine, 8);
    9297    Item.SubItems.Add(Line);
     
    118123end;
    119124
     125procedure TFormMain.PaintBox1Paint(Sender: TObject);
     126var
     127  X, Y: Integer;
     128  B: Byte;
     129  MemorySizeTmp: Integer;
     130  Addr: Integer;
     131begin
     132  MemorySizeTmp := Machine.MemorySize;
     133  with Machine, Screen do
     134  for Y := 0 to Size.Y - 1 do
     135  for X := 0 to Size.X - 1 do begin
     136    Addr := MemoryBase + Y * Size.X + X;
     137    if Addr < MemorySizeTmp then begin
     138      B := PByte(Memory + Addr)^;
     139      PaintBox1.Canvas.Pixels[X, Y] := B * $010101;
     140    end;
     141  end;
     142end;
     143
     144procedure TFormMain.PaintBox1Resize(Sender: TObject);
     145begin
     146  Machine.Screen.Size := Point(PaintBox1.Width, PaintBox1.Height);
     147end;
     148
    120149procedure TFormMain.Timer1Timer(Sender: TObject);
    121150begin
     
    129158end;
    130159
     160procedure TFormMain.TimerDrawTimer(Sender: TObject);
     161begin
     162  PaintBox1.Repaint;
     163end;
     164
    131165procedure TFormMain.ReloadMemoryDump;
    132166begin
    133   ListViewMemory.Items.Count := Length(Machine.Memory) div ItemsPerLine;
     167  ListViewMemory.Items.Count := Machine.MemorySize div ItemsPerLine;
    134168  ListViewMemory.Refresh;
    135169end;
     
    146180  R2: Byte;
    147181  R3: Byte;
     182  R4: Byte;
    148183  LabelStart: Integer;
    149184  LabelText: Integer;
    150185  LabelPrint: Integer;
     186  LabelClearScreen: Integer;
    151187begin
    152188  R1 := 1;
    153189  R2 := 2;
    154190  R3 := 3;
     191  R4 := 4;
    155192  with InstructionWriter do begin
     193    // Print Hello world text
    156194    LabelText := 200;
    157195    Loadi(R1, LabelText);
    158196    Loadi(R2, 12);
    159197  LabelPrint := IP;
    160     DataPrefix8; LoadMem(R3, R1);
     198      DataPrefix8; LoadMem(R3, R1);
    161199    DataPrefix8; Output(0, R3);
    162200    Increment(R1);
     
    165203    JumpNotZero(LabelPrint);
    166204
     205    // Draw to video memory
     206    Loadi(R1, Machine.Screen.MemoryBase);
     207    Loadi(R2, $10000);
     208    Loadi(R3, $7f);
     209  LabelClearScreen := IP;
     210    DataPrefix8; StoreMem(R1, R3);
     211    Increment(R1);
     212    Decrement(R2);
     213    Test(R2);
     214    JumpNotZero(LabelClearScreen);
     215
     216    // Read keyboard and print to console
    167217    Loadi(R1, 100);
    168218  LabelStart := IP;
    169219    Increment(R1);
    170     Loadi(R2, 100);
     220    Loadi(R2, $100);
    171221    DataPrefix8; StoreMem(R2, R1);
    172222    DataPrefix8; Input(R2, 0);
  • branches/virtualcpu4/UMachine.pas

    r174 r175  
    1111  TScreen = class
    1212    Size: TPoint;
     13    MemoryBase: Integer;
    1314  end;
    1415
     
    1920    function CpuInput(Port: TAddress): TRegister;
    2021    procedure CpuOutput(Port: TAddress; Value: TRegister);
     22    function GetMemorySize: Integer;
     23    procedure SetMemorySize(AValue: Integer);
    2124  public
    22     Memory: array of Byte;
     25    Memory: Pointer;
    2326    Cpu: TCpu;
    2427    Screen: TScreen;
     
    2730    LockInput: TCriticalSection;
    2831    LockOutput: TCriticalSection;
     32    property MemorySize: Integer read GetMemorySize write SetMemorySize;
    2933    constructor Create;
    3034    destructor Destroy; override;
     
    4246  Cpu.OnInput := CpuInput;
    4347  Cpu.OnOutput := CpuOutput;
    44   Cpu.DataSize := bw16;
    45   Cpu.AddressSize := bw16;
     48  Cpu.DataSize := bw32;
     49  Cpu.AddressSize := bw32;
    4650  Screen := TScreen.Create;
    4751  Screen.Size := Point(320, 240);
    48   SetLength(Memory, 1000);
     52  Screen.MemoryBase := $100;
     53  MemorySize := $1000000;
    4954  Cpu.Memory := Memory;
    5055end;
     
    7681      LockInput.Release;
    7782    end;
     83    1: case Cpu.DataSize of
     84      bw8: Result.B := Screen.Size.X;
     85      bw16: Result.W := Screen.Size.X;
     86      bw32: Result.D := Screen.Size.X;
     87      bw64: Result.Q := Screen.Size.X;
     88    end;
     89    2: case Cpu.DataSize of
     90      bw8: Result.B := Screen.Size.Y;
     91      bw16: Result.W := Screen.Size.Y;
     92      bw32: Result.D := Screen.Size.Y;
     93      bw64: Result.Q := Screen.Size.Y;
     94    end;
     95    3: case Cpu.DataSize of
     96      bw8: Result.B := Screen.MemoryBase;
     97      bw16: Result.W := Screen.MemoryBase;
     98      bw32: Result.D := Screen.MemoryBase;
     99      bw64: Result.Q := Screen.MemoryBase;
     100    end;
    78101  end;
    79102end;
     
    87110      LockOutput.Release;
    88111    end;
     112    1: case Cpu.DataSize of
     113      bw8: Screen.Size.X := Value.B;
     114      bw16: Screen.Size.X := Value.W;
     115      bw32: Screen.Size.X := Value.D;
     116      bw64: Screen.Size.X := Value.Q;
     117    end;
     118    2: case Cpu.DataSize of
     119      bw8: Screen.Size.Y := Value.B;
     120      bw16: Screen.Size.Y := Value.W;
     121      bw32: Screen.Size.Y := Value.D;
     122      bw64: Screen.Size.Y := Value.Q;
     123    end;
     124    3: case Cpu.DataSize of
     125      bw8: Screen.MemoryBase := Value.B;
     126      bw16: Screen.MemoryBase := Value.W;
     127      bw32: Screen.MemoryBase := Value.D;
     128      bw64: Screen.MemoryBase := Value.Q;
     129    end;
    89130  end;
     131end;
     132
     133function TMachine.GetMemorySize: Integer;
     134begin
     135  Result := MemSize(Memory);
     136end;
     137
     138procedure TMachine.SetMemorySize(AValue: Integer);
     139begin
     140  Memory := ReAllocMem(Memory, AValue);
    90141end;
    91142
Note: See TracChangeset for help on using the changeset viewer.