Changeset 187


Ignore:
Timestamp:
May 7, 2019, 5:58:20 PM (5 years ago)
Author:
chronos
Message:
  • Added: More instruction implemented for pascal code generator.
Location:
branches/virtualcpu4
Files:
4 edited

Legend:

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

    r186 r187  
    11object FormMain: TFormMain
    22  Left = 686
    3   Height = 318
     3  Height = 265
    44  Top = 444
    5   Width = 806
     5  Width = 672
    66  Caption = 'VirtCpu4'
    7   ClientHeight = 318
    8   ClientWidth = 806
    9   DesignTimePPI = 144
     7  ClientHeight = 265
     8  ClientWidth = 672
     9  DesignTimePPI = 120
    1010  OnCreate = FormCreate
    1111  OnDestroy = FormDestroy
    1212  OnShow = FormShow
    13   LCLVersion = '2.0.0.4'
     13  LCLVersion = '2.0.2.0'
    1414  object ButtonStart: TButton
    15     Left = 229
    16     Height = 37
    17     Top = 17
    18     Width = 113
     15    Left = 191
     16    Height = 31
     17    Top = 14
     18    Width = 94
    1919    Caption = 'Start'
    2020    OnClick = ButtonStartClick
     
    2323  end
    2424  object ButtonStop: TButton
    25     Left = 229
    26     Height = 37
    27     Top = 65
    28     Width = 113
     25    Left = 191
     26    Height = 31
     27    Top = 54
     28    Width = 94
    2929    Caption = 'Stop'
    3030    OnClick = ButtonStopClick
     
    3333  end
    3434  object ButtonDisassembler: TButton
    35     Left = 371
    36     Height = 38
    37     Top = 17
    38     Width = 185
     35    Left = 309
     36    Height = 32
     37    Top = 14
     38    Width = 154
    3939    Caption = 'Disassembler'
    4040    OnClick = ButtonDisassemblerClick
     
    4343  end
    4444  object ButtonMemory: TButton
    45     Left = 24
    46     Height = 38
    47     Top = 112
    48     Width = 185
     45    Left = 20
     46    Height = 32
     47    Top = 93
     48    Width = 154
    4949    Caption = 'Memory'
    5050    OnClick = ButtonMemoryClick
     
    5353  end
    5454  object ButtonCpuState: TButton
    55     Left = 24
    56     Height = 38
    57     Top = 160
    58     Width = 185
     55    Left = 20
     56    Height = 32
     57    Top = 133
     58    Width = 154
    5959    Caption = 'CPU state'
    6060    OnClick = ButtonCpuStateClick
     
    6363  end
    6464  object ButtonScreen: TButton
    65     Left = 24
    66     Height = 38
    67     Top = 16
    68     Width = 185
     65    Left = 20
     66    Height = 32
     67    Top = 13
     68    Width = 154
    6969    Caption = 'Screen'
    7070    OnClick = ButtonScreenClick
     
    7373  end
    7474  object ButtonConsole: TButton
    75     Left = 24
    76     Height = 38
    77     Top = 64
    78     Width = 185
     75    Left = 20
     76    Height = 32
     77    Top = 53
     78    Width = 154
    7979    Caption = 'Console'
    8080    OnClick = ButtonConsoleClick
     
    8383  end
    8484  object ButtonAssembler: TButton
    85     Left = 371
    86     Height = 38
    87     Top = 56
    88     Width = 185
     85    Left = 309
     86    Height = 32
     87    Top = 47
     88    Width = 154
    8989    Caption = 'Assembler'
    9090    OnClick = ButtonAssemblerClick
     
    9393  end
    9494  object ButtonClearMemory: TButton
    95     Left = 24
    96     Height = 38
    97     Top = 208
    98     Width = 185
     95    Left = 20
     96    Height = 32
     97    Top = 173
     98    Width = 154
    9999    Caption = 'Clear memory'
    100100    OnClick = ButtonClearMemoryClick
     
    103103  end
    104104  object ButtonCompilerPascal: TButton
    105     Left = 371
    106     Height = 38
    107     Top = 200
    108     Width = 185
     105    Left = 309
     106    Height = 32
     107    Top = 167
     108    Width = 154
    109109    Caption = 'Pascal compiler'
    110110    OnClick = ButtonCompilerPascalClick
  • branches/virtualcpu4/Forms/UFormMain.pas

    r186 r187  
    183183  LabelText2 := IP;
    184184    WriteString('Good day!');
     185    Write8(0);
     186    Write8(0);
     187    Write8(0);
     188    Write8(0);
    185189
    186190  LabelPrint := IP;
  • branches/virtualcpu4/UCompilerPascal.pas

    r186 r187  
    66
    77uses
    8   Classes, SysUtils, UInstructionReader, UOpcode, UCpu;
     8  Classes, SysUtils, UInstructionReader, UOpcode, UCpu, strutils;
    99
    1010type
     
    1616    OpcodeDefs: TOpcodeDefs;
    1717    Instructions: array[TOpcode] of TInstructionEvent;
     18    Indent: Integer;
     19    Labels: TStringList;
    1820    procedure InstConvert;
    1921    procedure InstNop;
     
    9193begin
    9294  R := Reader.Read8;
    93   AddLine(GetRegister(R, Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize));
     95  AddLine(GetRegister(R, Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize) + ';');
    9496end;
    9597
     
    100102procedure TCompilerPascal.InstHalt;
    101103begin
    102   AddLine('Exit');
     104  AddLine('Exit;');
    103105end;
    104106
     
    109111  R1 := Reader.Read8;
    110112  R2 := Reader.Read8;
    111   AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize));
     113  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize) + ';');
    112114end;
    113115
     
    117119begin
    118120  R := Reader.Read8;
    119   AddLine(GetRegister(R, Reader.DataSize) + ' := ' + IntToStr(Reader.ReadData));
     121  AddLine(GetRegister(R, Reader.DataSize) + ' := ' + IntToHexEx(Reader.ReadData, -1, '$') + ';');
    120122end;
    121123
    122124procedure TCompilerPascal.InstJump;
    123125begin
    124   Reader.ReadAddress;
    125   // TODO
     126  AddLine('GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');');
    126127end;
    127128
    128129procedure TCompilerPascal.InstJumpZero;
    129130begin
    130   Reader.ReadAddress;
    131   // TODO
     131  AddLine('if Zero then GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');');
    132132end;
    133133
    134134procedure TCompilerPascal.InstJumpNotZero;
    135135begin
    136   Reader.ReadAddress;
    137   // TODO
     136  AddLine('if not Zero then GotoAddr(@L' + IntToStr(Reader.ReadAddress) + ');');
    138137end;
    139138
    140139procedure TCompilerPascal.InstJumpRel;
    141 begin
    142   Reader.ReadAddressSigned;
    143   // TODO
     140var
     141  Addr: TAddressSigned;
     142begin
     143  Addr := Reader.ReadAddressSigned;
     144  AddLine('GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');');
    144145end;
    145146
    146147procedure TCompilerPascal.InstJumpRelZero;
    147 begin
    148   Reader.ReadAddressSigned;
    149   // TODO
     148var
     149  Addr: TAddressSigned;
     150begin
     151  Addr := Reader.ReadAddressSigned;
     152  AddLine('if Zero then GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');');
    150153end;
    151154
    152155procedure TCompilerPascal.InstJumpRelNotZero;
    153 begin
    154   Reader.ReadAddressSigned;
    155   // TODO
     156var
     157  Addr: TAddressSigned;
     158begin
     159  Addr := Reader.ReadAddressSigned;
     160  AddLine('if not Zero then GotoAddr(@L' + IntToStr(Reader.IP + Addr) + ');');
    156161end;
    157162
     
    161166begin
    162167  R := Reader.Read8;
    163   AddLine('Z := ' + GetRegister(R, Reader.DataSize) + ' = 0');
     168  AddLine('Zero := ' + GetRegister(R, Reader.DataSize) + ' = 0;');
    164169end;
    165170
     
    169174begin
    170175  R := Reader.Read8;
    171   AddLine(GetRegister(R, Reader.DataSize) + ' := -' + GetRegister(R, Reader.DataSize));
     176  AddLine(GetRegister(R, Reader.DataSize) + ' := -' + GetRegister(R, Reader.DataSize) + ';');
    172177end;
    173178
     
    177182begin
    178183  R := Reader.Read8;
    179   AddLine(GetRegister(R, Reader.DataSize) + ' := 0');
     184  AddLine(GetRegister(R, Reader.DataSize) + ' := 0;');
    180185end;
    181186
     
    187192  R2 := Reader.Read8;
    188193  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' +
    189     GetMemory(GetRegister(R2, Reader.AddrSize), Reader.AddrSize));
     194    GetMemory(GetRegister(R2, Reader.AddrSize), Reader.AddrSize) + ';');
    190195end;
    191196
     
    197202  R2 := Reader.Read8;
    198203  AddLine(GetMemory(GetRegister(R1, Reader.AddrSize), Reader.AddrSize) + ' := ' +
    199     GetRegister(R2, Reader.DataSize));
     204    GetRegister(R2, Reader.DataSize) + ';');
    200205end;
    201206
     
    206211  R1 := Reader.Read8;
    207212  R2 := Reader.Read8;
    208   // TODO
     213  AddLine('Temp := ' + GetRegister(R1, Reader.DataSize) + ';');
     214  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R2, Reader.DataSize) + ';');
     215  AddLine(GetRegister(R2, Reader.DataSize) + ' := Temp;');
    209216end;
    210217
     
    214221begin
    215222  R := Reader.Read8;
    216   AddLine('Dec(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');' + LineEnding +
    217     GetMemory('SP', Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize));
     223  AddLine('Dec(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');');
     224  AddLine(GetMemory('SP', Reader.AddrSize) + ' := ' + GetRegister(R, Reader.DataSize) + ';');
    218225end;
    219226
     
    223230begin
    224231  R := Reader.Read8;
    225   AddLine(GetRegister(R, Reader.DataSize) + ' := ' + GetMemory('SP', Reader.AddrSize) + LineEnding +
    226     'Inc(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');');
     232  AddLine(GetRegister(R, Reader.DataSize) + ' := ' + GetMemory('SP', Reader.AddrSize) + ';');
     233  AddLine('Inc(SP, ' + IntToStr(BitWidthBytes[Reader.DataSize]) + ');');
    227234end;
    228235
    229236procedure TCompilerPascal.InstCall;
    230 begin
    231   Reader.ReadAddress;
    232   // TODO
     237var
     238  Addr: QWord;
     239begin
     240  Addr := Reader.ReadAddress;
     241  AddLine('Dec(SP, ' + IntToStr(BitWidthBytes[Reader.AddrSize]) + ');');
     242  AddLine(GetMemory('SP', Reader.AddrSize) + ' := ' + IntToStr(Reader.IP) + ';');
     243  AddLine('GotoAddr(@L' + IntToStr(Addr) + ');');
    233244end;
    234245
    235246procedure TCompilerPascal.InstRet;
    236247begin
    237   // TODO
     248  AddLine('TempAddr := Pointer(' + GetMemory('SP', Reader.AddrSize) + ');');
     249  AddLine('Inc(SP, ' + IntToStr(BitWidthBytes[Reader.AddrSize]) + ');');
     250  AddLine('GotoAddr(TempAddr);');
    238251end;
    239252
     
    277290
    278291procedure TCompilerPascal.InstMul;
    279 begin
    280 
     292var
     293  R1, R2: Byte;
     294begin
     295  R1 := Reader.Read8;
     296  R2 := Reader.Read8;
     297  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) +
     298    ' * ' + GetRegister(R2, Reader.DataSize));
    281299end;
    282300
    283301procedure TCompilerPascal.InstDiv;
    284 begin
    285 
     302var
     303  R1, R2: Byte;
     304begin
     305  R1 := Reader.Read8;
     306  R2 := Reader.Read8;
     307  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) +
     308    ' div ' + GetRegister(R2, Reader.DataSize));
    286309end;
    287310
    288311procedure TCompilerPascal.InstMod;
    289 begin
    290 
     312var
     313  R1, R2: Byte;
     314begin
     315  R1 := Reader.Read8;
     316  R2 := Reader.Read8;
     317  AddLine(GetRegister(R1, Reader.DataSize) + ' := ' + GetRegister(R1, Reader.DataSize) +
     318    ' mod ' + GetRegister(R2, Reader.DataSize));
    291319end;
    292320
     
    296324begin
    297325  R := Reader.Read8;
    298   AddLine('Inc(' + GetRegister(R, Reader.DataSize) + ')');
     326  AddLine('Inc(' + GetRegister(R, Reader.DataSize) + ');');
    299327end;
    300328
     
    304332begin
    305333  R := Reader.Read8;
    306   AddLine('Dec(' + GetRegister(R, Reader.DataSize) + ')');
     334  AddLine('Dec(' + GetRegister(R, Reader.DataSize) + ');');
    307335end;
    308336
     
    377405procedure TCompilerPascal.InstLddr;
    378406begin
    379 
     407  // TODO
    380408end;
    381409
    382410procedure TCompilerPascal.InstLdir;
    383411begin
    384 
     412  // TODO
    385413end;
    386414
     
    410438
    411439procedure TCompilerPascal.InstDataSize;
    412 begin
    413   Reader.DataSizeBase := TBitWidth(Reader.Read8);
    414   Reader.DataSize := Reader.DataSizeBase;
     440var
     441  BitWidth: Byte;
     442begin
     443  BitWidth := Reader.Read8;
     444  if (BitWidth <> 0) and (BitWidth <= Byte(High(TBitWidth))) then begin
     445    Reader.DataSizeBase := TBitWidth(BitWidth);
     446    Reader.DataSize := Reader.DataSizeBase;
     447  end;
    415448end;
    416449
     
    440473
    441474procedure TCompilerPascal.InstAddrSize;
    442 begin
    443   Reader.AddrSizeBase := TBitWidth(Reader.Read8);
    444   Reader.AddrSize := Reader.AddrSizeBase;
     475var
     476  BitWidth: Byte;
     477begin
     478  BitWidth := Reader.Read8;
     479  if (BitWidth <> 0) and (BitWidth <= Byte(High(TBitWidth))) then begin
     480    Reader.AddrSizeBase := TBitWidth(BitWidth);
     481    Reader.AddrSize := Reader.AddrSizeBase;
     482  end; // TODO error reporting
    445483end;
    446484
     
    500538procedure TCompilerPascal.AddLine(Text: string);
    501539begin
    502   Output := Output + '  ' + Text + ';' + LineEnding;
     540  Output := Output + DupeString('  ', Indent) + Text + LineEnding;
    503541end;
    504542
    505543function TCompilerPascal.GetRegister(Index: Byte; BitWidth: TBitWidth): string;
    506544begin
    507   Result := 'Registers[' + IntToStr(Index) + ']' + BitWidthSuffix[BitWidth];
     545  Result := 'R' + IntToStr(Index) + BitWidthSuffix[BitWidth];
    508546end;
    509547
     
    517555  Opcode: Byte;
    518556  MemorySize: QWord;
     557  OutputBody: string;
     558  LabelsText: string;
     559  LabelAddr: QWord;
     560  I: Integer;
    519561begin
    520562  Reader.Init;
    521563  MemorySize := MemSize(Reader.Cpu.Memory);
    522   Output :=
    523     'type' + LineEnding +
    524     '  TBitWidth = (bwNone, bw8, bw16, bw32, bw64);' + LineEnding +
    525     '  TRegister = record' + LineEnding +
    526     '  case TBitWidth of' + LineEnding +
    527     '    bw8: (B: Byte);' + LineEnding +
    528     '    bw16: (W: Word);' + LineEnding +
    529     '    bw32: (D: DWord);' + LineEnding +
    530     '    bw64: (Q: QWord);' + LineEnding +
    531     '  end;' + LineEnding +
    532     'var' + LineEnding +
    533     '  Memory: Pointer;' + LineEnding +
    534     '  Registers: array[0..' + IntToStr(High(Reader.Cpu.Registers)) + '] of TRegister;' + LineEnding +
    535     '  SP: QWord;' + LineEnding +
    536     '  Zero: Boolean;' + LineEnding +
    537     'begin' + LineEnding +
    538     '  Memory := GetMem(' + IntToStr(MemorySize) + ');' + LineEnding;
     564  AddLine('begin');
     565  AddLine('  SP := ' + IntToStr(MemorySize) + ';');
     566  AddLine('  Memory := GetMem(' + IntToStr(MemorySize) + ');');
     567  Inc(Indent);
    539568  while Reader.IP < MemorySize do begin
    540569    Reader.Prefix := False;
     570    LabelAddr := Reader.IP;
    541571    Opcode := Reader.Read8;
    542572    if Opcode <= Integer(High(TOpcode)) then begin
     573      AddLine('L' + IntToStr(LabelAddr) + ':');
     574      Labels.Add('L' + IntToStr(LabelAddr));
    543575      if Opcode < Length(Instructions) then begin
    544576      if Assigned(Instructions[TOpcode(Opcode)]) then Instructions[TOpcode(Opcode)]
     
    552584    end;
    553585  end;
    554   Output := Output + 'end.' + LineEnding;
     586  Dec(Indent);
     587  AddLine('end.');
     588  OutputBody := Output;
     589
     590  Output := '';
     591  AddLine('type');
     592  AddLine('  TBitWidth = (bwNone, bw8, bw16, bw32, bw64);');
     593  AddLine('  TRegister = record');
     594  AddLine('  case TBitWidth of');
     595  AddLine('    bw8: (B: Byte);');
     596  AddLine('    bw16: (W: Word);');
     597  AddLine('    bw32: (D: DWord);');
     598  AddLine('    bw64: (Q: QWord);');
     599  AddLine('  end;');
     600  AddLine('var');
     601  AddLine('  Memory: Pointer;');
     602  for I := 0 to High(Reader.Cpu.Registers) do
     603    AddLine('  R' + IntToStr(I) + ': TRegister;');
     604  AddLine('  SP: QWord;');
     605  AddLine('  Zero: Boolean;');
     606  AddLine('  Temp: QWord;');
     607  AddLine('  TempAddr: Pointer;');
     608  AddLine('');
     609  AddLine('procedure GotoAddr(P: Pointer); inline; assembler;');
     610  AddLine('asm');
     611  AddLine('  jmp P;');
     612  AddLine('end;');
     613  AddLine('');
     614  LabelsText := '';
     615  for I := 0 to Labels.Count - 1 do begin
     616    if I > 0 then LabelsText := LabelsText + ', ';
     617    LabelsText := LabelsText + Labels[I];
     618  end;
     619  AddLine('label ' + LabelsText + ';');
     620  Output := Output + OutputBody;
    555621end;
    556622
     
    559625  OpcodeDefs := TOpcodeDefs.Create;
    560626  Reader := TInstructionReader.Create;
     627  Labels := TStringList.Create;
    561628  InitInstructions;
    562629end;
     
    566633  FreeAndNil(Reader);
    567634  FreeAndNil(OpcodeDefs);
     635  FreeAndNil(Labels);
    568636  inherited Destroy;
    569637end;
  • branches/virtualcpu4/UOpcode.pas

    r185 r187  
    2929  end;
    3030
    31   function IntToHexEx(Value: Int64; Digits: ShortInt; Prefix: string = ''): string; overload;
    32   function IntToHexEx(Value: QWord; Digits: ShortInt; Prefix: string = ''): string; overload;
     31  function IntToHexEx(Value: Int64; Digits: ShortInt = -1; Prefix: string = ''): string; overload;
     32  function IntToHexEx(Value: QWord; Digits: ShortInt = -1; Prefix: string = ''): string; overload;
    3333
    3434
     
    3838  HexChars: array[0..15] of Char = '0123456789ABCDEF';
    3939
    40 function IntToHexEx(Value: Int64; Digits: ShortInt; Prefix: string = ''): string;
     40function IntToHexEx(Value: Int64; Digits: ShortInt = -1; Prefix: string = ''): string;
    4141var
    4242  I: Integer;
     
    6363end;
    6464
    65 function IntToHexEx(Value: QWord; Digits: ShortInt; Prefix: string = ''): string;
     65function IntToHexEx(Value: QWord; Digits: ShortInt = -1; Prefix: string = ''): string;
    6666var
    6767  I: Integer;
Note: See TracChangeset for help on using the changeset viewer.