⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jdevdisassemblydialog.pas

📁 一个不出名的GBA模拟器
💻 PAS
字号:
//////////////////////////////////////////////////////////////////////
//                                                                  //
// jdevDisassemblyDialog.pas: Scripted disassembly dialog           //
//   This provides an interface for the user to save a disasm of    //
//   multiple sections of memory in different modes.                //
//                                                                  //
// The contents of this file are subject to the Bottled Light       //
// Public License Version 1.0 (the "License"); you may not use this //
// file except in compliance with the License. You may obtain a     //
// copy of the License at http://www.bottledlight.com/BLPL/         //
//                                                                  //
// Software distributed under the License is distributed on an      //
// "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or   //
// implied. See the License for the specific language governing     //
// rights and limitations under the License.                        //
//                                                                  //
// The Original Code is the Mappy VM User Interface, released       //
// April 1st, 2003. The Initial Developer of the Original Code is   //
// Bottled Light, Inc. Portions created by Bottled Light, Inc. are  //
// Copyright (C) 2001-2003 Bottled Light, Inc. All Rights Reserved. //
//                                                                  //
// Author(s):                                                       //
//   Michael Noland (joat), michael@bottledlight.com                //
//                                                                  //
// Changelog:                                                       //
//   1.0: First public release (April 1st, 2003)                    //
//                                                                  //
// Notes:                                                           //
//   Needs rewriting to make the output directly recompile in GAS.  //
//                                                                  //
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
unit jdevDisassemblyDialog; //////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////
interface ////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StdCtrls, console, Menus, arm_disass, nexus,
  AddressSpace;

//////////////////////////////////////////////////////////////////////

type
  TOnDDialogClose = procedure (executed: boolean) of object;

  TjdevDisasmDialog = class(TForm)
    eDestFile: TEdit;
    browseButton: TButton;
    lDestination: TLabel;
    saveDialog: TSaveDialog;
    tasks: TListView;
    lCommands: TLabel;
    okButton: TButton;
    cancelButton: TButton;
    rTargetARM: TRadioButton;
    rTargetGAS: TRadioButton;
    lTargetASM: TLabel;
    addButton: TButton;
    removeButton: TButton;
    eLabel: TEdit;
    eMode: TComboBox;
    eSize: TEdit;
    eAddress: TEdit;
    mainMenu: TMainMenu;
    mFile: TMenuItem;
    mLoadScript: TMenuItem;
    mSaveScript: TMenuItem;
    openDialog: TOpenDialog;
    procedure addButtonClick(Sender: TObject);
    procedure removeButtonClick(Sender: TObject);
    procedure browseButtonClick(Sender: TObject);
    procedure okButtonClick(Sender: TObject);
    procedure cancelButtonClick(Sender: TObject);
    procedure tasksCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);
    procedure FormCreate(Sender: TObject);
    procedure LoadScript(Sender: TObject);
    procedure SaveScript(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure AddEntry(title, address, size, mode: string);
  end;

//////////////////////////////////////////////////////////////////////

var
  jdevDisasmDialog: TjdevDisasmDialog;

//////////////////////////////////////////////////////////////////////
implementation ///////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////

{$R *.DFM}

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.AddEntry(title, address, size, mode: string);
var
  item: TListItem;
  st: string;
  base, count: uint32;
begin
  // Get the address
  st := Trim(address);
  if Length(st) < 1 then begin
    Beep;
    Exit;
  end;
  if st[1] <> '$' then st := '$' + st;
  base := StrToInt(st);

  // Get the size
  st := Trim(size);
  if Length(st) < 1 then begin
    Beep;
    Exit;
  end;
  count := StrToInt(st);

  // Add the item
  item := tasks.Items.Add;
  item.Caption := title;
  item.SubItems.Add('$'+IntToHex(base and not 1, 8));
  item.SubItems.Add(IntToStr(count));

  // Get the mode
  if Uppercase(mode) = 'ARM' then
    item.SubItems.Add('ARM')
  else if Uppercase(mode) = 'THUMB' then
    item.SubItems.Add('Thumb')
  else
    item.SubItems.Add('Data');

  // Sort the list
  tasks.CustomSort(nil, 0);
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.addButtonClick(Sender: TObject);
begin
  AddEntry(eLabel.Text, eAddress.Text, eSize.Text, eMode.Text)
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.removeButtonClick(Sender: TObject);
begin
  if Assigned(tasks.Selected) then tasks.Selected.Delete;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.browseButtonClick(Sender: TObject);
begin
  saveDialog.DefaultExt := 'asm';
  saveDialog.Filter := 'Assembler File|*.asm;*.s|All Files|*.*';
  if saveDialog.Execute then
    eDestFile.Text := saveDialog.FileName;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.okButtonClick(Sender: TObject);
var
  item: TListItem;
  i, k: uint32;
  text: TStringList;
  count, base: uint32;
  st: string;
begin
  if eDestFile.Text = '' then begin
    Beep;
    Exit;
  end;

  disassembler.showJunk := false;
  disassembler.useTabs := true;

  // Create the disasm file and write a prologue
  text := TStringList.Create;
  text.Add('Disassembly produced by Mappy VM');
  text.Add('Created on ' + DateTimeToStr(Now));

  // Add the labels to the disassembler first
  for i := 0 to tasks.Items.Count - 1 do begin
    item := tasks.Items.Item[i];
    base := StrToIntDef(item.SubItems.Strings[0], 0);
    disassembler.AddMapping(base, item.Caption);
  end;

  // Disassemble all the tasks in the list
  for i := 0 to tasks.Items.Count - 1 do begin
    // Get a new task
    item := tasks.Items.Item[i];

    // Parse the label, base address, length, and CPU mode of the entry
    base := StrToIntDef(item.SubItems.Strings[0], 0);
    count := StrToIntDef(item.SubItems.Strings[1], 0);
    disassembler.thumbMode := Uppercase(item.SubItems.Strings[2]) = 'THUMB';

    // Disassemble this task
    if count > 0 then begin
      text.Add('');
      if Uppercase(item.SubItems.Strings[2]) = 'DATA' then begin
        k := 0;
        st := item.Caption + '  ';
        while k < count do begin
          if k and 7 = 0 then begin
            Delete(st, Length(st)-1, 2);
            text.Add(st);
            st := IntToHex(base, 8) + #9'DCD'#9;
          end;
          st := st + '$' + IntToHex(vmReadWord(base), 8) + ', ';
          Inc(base, 4);
          Inc(k);
        end;

        if count and 7 <> 0 then begin
          Delete(st, Length(st)-1, 2);
          text.Add(st);
        end;
      end else begin
//        text.Add(item.Caption + #9);
        disassembler.Emulate(base, count, text);
      end;
    end;
  end;

  // Save the disassembly to a file
  text.SaveToFile(eDestFile.Text);
  text.Free;

  // Clear the task list
//  tasks.Items.Clear;

  disassembler.showJunk := true;
  disassembler.useTabs := false;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.cancelButtonClick(Sender: TObject);
begin
  Close;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.tasksCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer);
begin
  if (Item2.SubItems.Count > 0) and (Item2.SubItems.Count > 0) then begin
    Compare := StrComp(PChar(Item1.SubItems.Strings[0]), PChar(Item2.SubItems.Strings[0]));
    if Compare = 0 then Compare := StrComp(PChar(Item1.Caption), PChar(Item2.Caption));
  end else
    Compare := 0;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.FormCreate(Sender: TObject);
begin
  HelpContext := LinkHelp('disassembler_script.html');
  eDestFile.Text := '';
  eMode.ItemIndex := 0;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.LoadScript(Sender: TObject);

function HaxorLeft(var st: string): string;
var
  i: integer;
begin
  i := Pos(#9, st);
  if i = 0 then i := Length(st)+1;
  Result := Copy(st, 1, i-1);
  Delete(st, 1, i);
end;

var
  index: integer;
  items: TStringList;
  line, a, b, c, d: string;
begin
  openDialog.DefaultExt := 'asr';
  openDialog.Filter := 'Assembly Script Resource|*.asr;*.s|All Files|*.*';
  if openDialog.Execute then begin
    // Load the file
    items := TStringList.Create;
    items.LoadFromFile(openDialog.FileName);

    // A touch of da crude error checking
    if (items.Count = 0) or (Copy(Uppercase(items.Strings[0]), 1, 4) <> 'ASR1') then begin
      Beep;
      Exit;
    end;

    // Add the entries to the task list
    index := 1;
    tasks.Items.Clear;
    while index < items.Count do begin
      line := items.Strings[index];
      a := HaxorLeft(line);
      b := HaxorLeft(line);
      c := HaxorLeft(line);
      d := HaxorLeft(line);
      AddEntry(a, b, c, d);
      Inc(index);
    end;

    // Close the file
    items.Free;
  end;
end;

//////////////////////////////////////////////////////////////////////

procedure TjdevDisasmDialog.SaveScript(Sender: TObject);
var
  index: integer;
  items: TStringList;
  item: TListItem;
begin
  saveDialog.DefaultExt := 'asr';
  saveDialog.Filter := 'Assembly Script Resource|*.asr;*.s|All Files|*.*';
  if saveDialog.Execute then begin
    // Create a string file
    items := TStringList.Create;
    items.Add('ASR1 - Generated by Mappy VM');

    // Copy the task list to the file
    for index := 0 to tasks.Items.Count-1 do begin
      item := tasks.Items.Item[index];
      items.Add(Format('%s'#9'%s'#9'%s'#9'%s', [item.Caption, item.SubItems.Strings[0], item.SubItems.Strings[1], item.SubItems.Strings[2]]));
    end;

    // Save and close it
    items.SaveToFile(saveDialog.FileName);
    items.Free;
  end;
end;

//////////////////////////////////////////////////////////////////////

end.

//////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -