Ignore:
Timestamp:
Aug 19, 2020, 11:54:20 PM (4 years ago)
Author:
chronos
Message:
  • Added: TMachine class which contains CPU and peripherals.
  • Added: Execute TCpu inside background thread.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/virtcpu fixed int/UFormMain.pas

    r168 r215  
    77uses
    88  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ComCtrls,
    9   StdCtrls, ExtCtrls, UMachine, UInstructionWriter;
     9  StdCtrls, ExtCtrls, UCpu, UInstructionWriter, UMachine;
    1010
    1111type
     
    1414
    1515  TForm1 = class(TForm)
    16     Button1: TButton;
    17     Button2: TButton;
     16    ButtonStart: TButton;
     17    ButtonStop: TButton;
    1818    LabelTicks: TLabel;
    1919    ListViewMemory: TListView;
     
    2121    Memo1: TMemo;
    2222    Timer1: TTimer;
    23     procedure Button1Click(Sender: TObject);
    24     procedure Button2Click(Sender: TObject);
     23    procedure ButtonStartClick(Sender: TObject);
     24    procedure ButtonStopClick(Sender: TObject);
    2525    procedure FormCreate(Sender: TObject);
    2626    procedure FormDestroy(Sender: TObject);
     
    3232    procedure Timer1Timer(Sender: TObject);
    3333  private
    34     KeyInputBuffer: array of Char;
    3534    procedure ReloadMemoryDump;
    3635    procedure ReloadRegisterDump;
    37     function CpuInput(Port: T): T;
    38     procedure CpuOutput(Port, Value: T);
     36    procedure SerialOutputExecute(Sender: TObject);
    3937  public
    40     Cpu: TCPU;
     38    Machine: TMachine;
    4139    InstructionWriter: TInstructionWriter;
    4240  end;
     
    8785    Output(0, R1);
    8886    Subtract(R1, R4);
    89     JumpZero(R1, LabelPrint);
     87    TestZero(R1);
     88    JumpCond(LabelPrint);
    9089  LabelPrintBack := IP;
    9190    Increment(R2);
     
    101100procedure TForm1.FormDestroy(Sender: TObject);
    102101begin
    103   InstructionWriter.Free;
    104   Cpu.Free;
     102  FreeAndNil(InstructionWriter);
     103  FreeAndNil(Machine);
    105104end;
    106105
     
    111110procedure TForm1.FormCreate(Sender: TObject);
    112111begin
    113   Cpu := TCPU.Create(nil);
    114   Cpu.OnInput := CpuInput;
    115   Cpu.OnOutput := CpuOutput;
     112  Machine := TMachine.Create(nil);
     113  Machine.OnSerialOutput := SerialOutputExecute;
    116114  InstructionWriter := TInstructionWriter.Create;
    117   InstructionWriter.Cpu := Cpu;
     115  InstructionWriter.Cpu := Machine.Cpu;
    118116end;
    119117
    120 procedure TForm1.Button1Click(Sender: TObject);
     118procedure TForm1.ButtonStartClick(Sender: TObject);
    121119begin
    122   Cpu.Start;
     120  Machine.Cpu.Start;
    123121end;
    124122
    125 procedure TForm1.Button2Click(Sender: TObject);
     123procedure TForm1.ButtonStopClick(Sender: TObject);
    126124begin
    127   Cpu.Stop;
     125  Machine.Cpu.Stop;
    128126end;
    129127
     
    133131  I: Integer;
    134132begin
    135   if Item.Index < Length(Cpu.Memory) div ItemsPerLine then begin
     133  if Item.Index < Length(Machine.Cpu.Memory) div ItemsPerLine then begin
    136134    Line := '';
    137135    for I := 0 to ItemsPerLine - 1 do
    138       Line := Line + IntToHex(Cpu.Memory[Item.Index * ItemsPerLine + I], 2) + ' ';
     136      Line := Line + IntToHex(Machine.Cpu.Memory[Item.Index * ItemsPerLine + I], 2) + ' ';
    139137    Item.Caption := IntToHex(Item.Index * ItemsPerLine, 8);
    140138    Item.SubItems.Add(Line);
     
    144142procedure TForm1.ListViewRegistersData(Sender: TObject; Item: TListItem);
    145143begin
    146   if Item.Index < Length(Cpu.Registers) + 1 then begin
     144  if Item.Index < Length(Machine.Cpu.Registers) + 1 then begin
    147145    if Item.Index = 0 then begin
    148146      Item.Caption := 'IP';
    149       Item.SubItems.Add(IntToHex(Cpu.IP, 8));
     147      Item.SubItems.Add(IntToHex(Machine.Cpu.IP, 8));
    150148    end else begin
    151149      Item.Caption := 'R' + IntToStr(Item.Index - 1);
    152       Item.SubItems.Add(IntToHex(Cpu.Registers[Item.Index - 1], 8));
     150      Item.SubItems.Add(IntToHex(Machine.Cpu.Registers[Item.Index - 1], 8));
    153151    end;
    154152  end;
     
    157155procedure TForm1.Memo1KeyPress(Sender: TObject; var Key: char);
    158156begin
    159   SetLength(KeyInputBuffer, Length(KeyInputBuffer) + 1);
    160   KeyInputBuffer[High(KeyInputBuffer)] := Key;
     157  Machine.SerialInput(Key);
    161158end;
    162159
     
    165162  ReloadMemoryDump;
    166163  ReloadRegisterDump;
    167   LabelTicks.Caption := 'Ticks: ' + IntToStr(Cpu.Ticks);
     164  LabelTicks.Caption := 'Ticks: ' + IntToStr(Machine.Cpu.Ticks);
    168165end;
    169166
    170167procedure TForm1.ReloadMemoryDump;
    171168begin
    172   ListViewMemory.Items.Count := Length(Cpu.Memory) div ItemsPerLine;
     169  ListViewMemory.Items.Count := Length(Machine.Cpu.Memory) div ItemsPerLine;
    173170  ListViewMemory.Refresh;
    174171end;
     
    176173procedure TForm1.ReloadRegisterDump;
    177174begin
    178   ListViewRegisters.Items.Count := Length(Cpu.Registers);
     175  ListViewRegisters.Items.Count := Length(Machine.Cpu.Registers);
    179176  ListViewRegisters.Refresh;
    180177end;
    181178
    182 function TForm1.CpuInput(Port: T): T;
     179procedure TForm1.SerialOutputExecute(Sender: TObject);
     180var
     181  Buffer: string;
    183182begin
    184   Result := 0;
    185   case Port of
    186     0: begin
    187       while (Length(KeyInputBuffer) = 0) and not Cpu.Terminated do begin
    188         Sleep(100);
    189         Application.ProcessMessages;
    190       end;
    191       if Length(KeyInputBuffer) > 0 then begin
    192         Result := Ord(KeyInputBuffer[0]);
    193         if Length(KeyInputBuffer) > 1 then
    194           Move(KeyInputBuffer[1], KeyInputBuffer[0], Length(KeyInputBuffer) - 1);
    195         SetLength(KeyInputBuffer, Length(KeyInputBuffer) - 1);
    196       end else Result := 0;
     183  Machine.SerialBufferLock.Acquire;
     184  try
     185    if Length(Machine.SerialBufferOutput) > 0 then begin
     186      SetLength(Buffer, Length(Machine.SerialBufferOutput));
     187      Move(Machine.SerialBufferOutput[0], Buffer[1], Length(Machine.SerialBufferOutput));
     188      Memo1.Lines.Text := Memo1.Lines.Text + Buffer;
     189      SetLength(Machine.SerialBufferOutput, 0);
    197190    end;
    198   end;
    199 end;
    200 
    201 procedure TForm1.CpuOutput(Port, Value: T);
    202 begin
    203   case Port of
    204     0: Memo1.Lines.Text := Memo1.Lines.Text + Char(Value);
     191  finally
     192    Machine.SerialBufferLock.Release;
    205193  end;
    206194end;
Note: See TracChangeset for help on using the changeset viewer.