Ignore:
Timestamp:
Nov 25, 2023, 11:47:52 PM (5 months ago)
Author:
chronos
Message:
  • Fixed: Assembler and disassembler to work correctly with supported instructions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/ByteArray/Disassembler.pas

    r55 r59  
    44
    55uses
    6   Classes, SysUtils, Cpu, Instructions, StrUtils, Memory;
     6  Classes, SysUtils, Cpu, Instructions, StrUtils, Memory, BigInt;
    77
    88type
     
    1212  TDisassembler = class
    1313  private
    14     function RegToStr(RegIndex: Byte): string;
     14    InstText: string;
     15    InstBytes: string;
     16    InstDataWidth: TBigIntSize;
     17    InstAddressWidth: TBigIntSize;
     18    procedure DisassembleData;
     19    procedure DisassembleAddress;
     20    procedure DisassembleRegister;
     21    procedure DisassembleRegisterIndirect;
     22    procedure DisassembleRegisterIndirectIndex;
     23    procedure DisassembleDataWidth;
     24    procedure DisassembleAddressWidth;
    1525  public
    16     InstructionSet: TInstructionSet;
     26    InstructionSet: TInstructionInfos;
    1727    Memory: TMemory;
     28    DataWidth: TBigIntSize;
     29    AddressWidth: TBigIntSize;
    1830    procedure Disassemble(Lines: TStrings);
    1931    procedure SaveToFile(FileName: string);
     
    2537implementation
    2638
    27 uses
    28   BigInt;
     39procedure TDisassembler.DisassembleData;
     40var
     41  Text: string;
     42begin
     43  Text := IntToHex(Memory.ReadPos(InstDataWidth));
     44  if not (Copy(Text, 1, 1)[1] in ['0'..'9']) then Text := '0' + Text;
     45  InstText := InstText + Text + 'h';
     46end;
    2947
    30 function TDisassembler.RegToStr(RegIndex: Byte): string;
     48procedure TDisassembler.DisassembleAddress;
     49var
     50  Text: string;
    3151begin
    32   Result := Chr(Ord('A') + RegIndex);
     52  Text := IntToHex(Memory.ReadPos(InstAddressWidth));
     53  if not (Copy(Text, 1, 1)[1] in ['0'..'9']) then Text := '0' + Text;
     54  InstText := InstText + Text + 'h';
     55end;
     56
     57procedure TDisassembler.DisassembleRegister;
     58begin
     59  InstText := InstText + 'R' + IntToStr(Byte(Memory.ReadPos(1)));
     60end;
     61
     62procedure TDisassembler.DisassembleRegisterIndirect;
     63begin
     64  InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) + ')';
     65end;
     66
     67procedure TDisassembler.DisassembleRegisterIndirectIndex;
     68begin
     69  InstText := InstText + '(R' + IntToStr(Byte(Memory.ReadPos(1))) +
     70    ' + ';
     71  DisassembleAddress;
     72  InstText := InstText + ')';
     73end;
     74
     75procedure TDisassembler.DisassembleDataWidth;
     76begin
     77  InstDataWidth := Memory.ReadPos(1);
     78  InstText := InstText + 'D' + IntToStr(InstDataWidth);
     79end;
     80
     81procedure TDisassembler.DisassembleAddressWidth;
     82begin
     83  InstAddressWidth := Memory.ReadPos(1);
     84  InstText := InstText + 'A' + IntToStr(InstAddressWidth);
    3385end;
    3486
    3587procedure TDisassembler.Disassemble(Lines: TStrings);
    3688var
    37   I: Integer;
    3889  J: Integer;
    3990  Value: TBigInt;
     
    4192  InstructionInfo: TInstructionInfo;
    4293  Line: string;
    43   InstText: string;
    44   InstBytes: string;
     94  MemoryPos: Integer;
     95  InstructionByteSize: Integer;
     96  I: Integer;
    4597begin
    4698  Memory.Position := 0;
    4799  while Memory.Position < Memory.Size do begin
    48100    Line := IntToHex(Memory.Position, 8) + ' ';
     101    MemoryPos := Memory.Position;
    49102    Value := Memory.ReadPos(1);
    50103    InstBytes := IntToHex(Value, 2) + ' ';
    51104    InstText := '';
     105    InstAddressWidth := AddressWidth;
     106    InstDataWidth := DataWidth;
    52107    if (Value >= 0) and (Value <= Integer(High(TInstruction))) then begin
    53108      Instruction := TInstruction(Int64(Value));
     
    56111        InstText := InstructionInfo.Name;
    57112        for J := 0 to Length(InstructionInfo.Params) - 1 do begin
    58           Value := Memory.ReadPos(1);
    59           InstBytes := InstBytes + IntToHex(Value, 2) + ' ';
    60113          if J > 0 then
    61114            InstText := InstText + ', ' else
    62115            InstText := InstText + ' ';
    63           if InstructionInfo.Params[J] = ptNumber then begin
    64             InstText := InstText + IntToHex(Value) + 'h';
    65           end else
    66           if InstructionInfo.Params[J] = ptReg then begin
    67             InstText := InstText + RegToStr(Value);
    68           end else
    69           if InstructionInfo.Params[J] = ptRegIndirect then begin
    70             InstText := InstText + '(' + RegToStr(Value) + ')';
    71           end else
    72           if InstructionInfo.Params[J] = ptRegIndirectIndex then begin
    73             InstText := InstText + '(' + RegToStr(Value);
    74             Value := Memory.ReadPos(1);
    75             InstBytes := InstBytes + IntToHex(Value, 2) + ' ';
    76             InstText := InstText + ' + ' + IntToStr(Value) + ')';
     116          case InstructionInfo.Params[J] of
     117            ptData: DisassembleData;
     118            ptAddress: DisassembleAddress;
     119            ptReg: DisassembleRegister;
     120            ptRegIndirect: DisassembleRegisterIndirect;
     121            ptRegIndirectIndex: DisassembleRegisterIndirectIndex;
     122            ptDataWidth: DisassembleDataWidth;
     123            ptAddressWidth: DisassembleAddressWidth;
    77124          end;
    78125        end;
    79         InstBytes := InstBytes + DupeString(' ', 13 - Length(InstBytes));
    80126      end;
    81127    end;
     128
     129    // Instruction bytes to hex string
     130    InstructionByteSize := Memory.Position - MemoryPos;
     131    Memory.Position := MemoryPos;
     132    InstBytes := '';
     133    for I := 0 to InstructionByteSize - 1 do
     134      InstBytes := InstBytes + IntToHex(Memory.ReadPos(1), 2) + ' ';
     135    InstBytes := InstBytes + DupeString(' ', 13 - Length(InstBytes));
     136
    82137    Line := Line + InstBytes + InstText;
    83138    Lines.Add(Line);
     
    97152constructor TDisassembler.Create;
    98153begin
    99   InstructionSet := TInstructionSet.Create;
     154  InstructionSet := TInstructionInfos.Create;
     155  InstructionSet.Init;
     156  DataWidth := 1;
     157  AddressWidth := 1;
    100158end;
    101159
Note: See TracChangeset for help on using the changeset viewer.