📄 simx86p.pas
字号:
unit Simx86p;
interface
uses
SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls,
Forms, Dialogs, Patterns, Menus, StdCtrls, TabNotBk, ExtCtrls, VBXCtrl,
Switch, Spin, GetInput, Printers;
type
TMem = array [0..$ffef] of byte;
TMemPtr = ^TMem;
TSIMx86Form = class(TForm)
Simx86Pages: TTabbedNotebook;
SourceCode: TMemo;
MainMenu: TMainMenu;
File1: TMenuItem;
Edit: TMenuItem;
New: TMenuItem;
Open: TMenuItem;
Save: TMenuItem;
SaveAs: TMenuItem;
Cut: TMenuItem;
Copy: TMenuItem;
Paste: TMenuItem;
Delete: TMenuItem;
EditBreak: TMenuItem;
BeforeQuit: TMenuItem;
PrintMenuItem: TMenuItem;
SelectAll: TMenuItem;
OpenDialog: TOpenDialog;
SaveDialog: TSaveDialog;
StartAdrs: TEdit;
StartAdrsLbl: TLabel;
ASMbtn: TButton;
Mem01: TEdit;
Mem02: TEdit;
Mem03: TEdit;
Mem04: TEdit;
Mem05: TEdit;
Mem00: TEdit;
Mem06: TEdit;
Mem07: TEdit;
AdrsEntry: TEdit;
Label0: TLabel;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
Label6: TLabel;
Label7: TLabel;
Lbl8: TLabel;
Lbl10: TLabel;
Lbl18: TLabel;
Lbl20: TLabel;
Lbl28: TLabel;
Lbl30: TLabel;
Lbl38: TLabel;
Mem10: TEdit;
Mem11: TEdit;
Mem12: TEdit;
Mem13: TEdit;
Mem14: TEdit;
Mem15: TEdit;
Mem16: TEdit;
Mem17: TEdit;
Mem27: TEdit;
Mem26: TEdit;
Mem25: TEdit;
Mem24: TEdit;
Mem23: TEdit;
Mem22: TEdit;
Mem21: TEdit;
Mem20: TEdit;
Mem30: TEdit;
Mem31: TEdit;
Mem32: TEdit;
Mem33: TEdit;
Mem34: TEdit;
Mem35: TEdit;
Mem36: TEdit;
Mem37: TEdit;
Mem47: TEdit;
Mem46: TEdit;
Mem45: TEdit;
Mem44: TEdit;
Mem43: TEdit;
Mem42: TEdit;
Mem41: TEdit;
Mem40: TEdit;
Mem50: TEdit;
Mem51: TEdit;
Mem52: TEdit;
Mem53: TEdit;
Mem54: TEdit;
Mem55: TEdit;
Mem56: TEdit;
Mem57: TEdit;
Mem67: TEdit;
Mem66: TEdit;
Mem65: TEdit;
Mem64: TEdit;
Mem63: TEdit;
Mem62: TEdit;
Mem61: TEdit;
Mem60: TEdit;
Mem70: TEdit;
Mem71: TEdit;
Mem72: TEdit;
Mem73: TEdit;
Mem74: TEdit;
Mem75: TEdit;
Mem76: TEdit;
Mem77: TEdit;
IntVect: TEdit;
IntVectLbl: TLabel;
ResetVectLbl: TLabel;
ResetVect: TEdit;
Label8: TLabel;
DisAsm: TListBox;
Output: TListBox;
InPort0: TBiSwitch;
InPort2: TBiSwitch;
InPort4: TBiSwitch;
InPort6: TBiSwitch;
OutPort8: TShape;
OutPortA: TShape;
OutPortC: TShape;
OutPortE: TShape;
FFF8Lbl: TLabel;
FFFALbl: TLabel;
FFFCLbl: TLabel;
FFFELbl: TLabel;
RunBtn: TButton;
StepBtn: TButton;
HaltBtn: TButton;
InterruptBtn: TButton;
OutputLbl: TLabel;
RunningLite: TPanel;
AXValue: TEdit;
AXLbl: TLabel;
BXValue: TEdit;
DXValue: TEdit;
CXValue: TEdit;
IPValue: TEdit;
BXLbl: TLabel;
CXLbl: TLabel;
DXLbl: TLabel;
IPLbl: TLabel;
Instruction: TLabel;
DisAsmAdrs: TEdit;
EqualFlag: TCheckBox;
LessThanFlag: TCheckBox;
ResetBtn: TButton;
Input: TListBox;
InputLbl: TLabel;
SpinButton: TSpinButton;
ClrMemBtn: TButton;
PrintDialog: TPrintDialog;
N1: TMenuItem;
Quit: TMenuItem;
procedure QuitClick(Sender: TObject);
procedure CutClick(Sender: TObject);
procedure CopyClick(Sender: TObject);
procedure PasteClick(Sender: TObject);
procedure DeleteClick(Sender: TObject);
procedure SelectAllClick(Sender: TObject);
procedure NewClick(Sender: TObject);
procedure OpenClick(Sender: TObject);
procedure SaveAsClick(Sender: TObject);
procedure HexChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure AdrsEntryChange(Sender: TObject);
procedure StartAdrsChange(Sender: TObject);
procedure ASMbtnClick(Sender: TObject);
procedure Simx86PagesChange(Sender: TObject; NewTab: Integer;
var AllowChange: Boolean);
procedure ClrMemBtnClick(Sender: TObject);
procedure DisAsmAdrsChange(Sender: TObject);
procedure SpinButtonDownClick(Sender: TObject);
procedure SpinButtonUpClick(Sender: TObject);
procedure ResetBtnClick(Sender: TObject);
procedure RunBtnClick(Sender: TObject);
procedure HaltBtnClick(Sender: TObject);
procedure InterruptBtnClick(Sender: TObject);
procedure IntVectChange(Sender: TObject);
procedure IPValueChange(Sender: TObject);
procedure StepBtnClick(Sender: TObject);
procedure PrintMenuItemClick(Sender: TObject);
procedure SaveClick(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
SIMx86Form: TSIMx86Form;
MemEntry: array[0..7,0..7] of TEdit;
implementation
type
TSymPtr = ^TSym;
TSym = record
value:word;
defined:boolean;
end;
const
MaxCodeAdrs = 4095;
var
HasOpcode:Boolean;
Opcode:word;
HasReg:Boolean;
RegCode:word;
HasOperand:Boolean;
OperandCode:word;
HasValue:Boolean;
OperandValue:word;
StoreMem:boolean;
Halted:boolean;
Running:boolean;
PendingInt:boolean;
InInt:boolean;
IntAdrs:word;
Val:byte;
AX: word;
BX: word;
CX: word;
DX: word;
IP: word;
LineNum:integer;
Adrs:word;
MemAdrs:word;
MemWS:integer;
AbortAsm:Boolean;
NoError:Boolean;
Memory: TMemPtr;
SymTbl: array ['A'..'Z'] of TSym;
SaveAX:word;
SaveBX:word;
SaveCX:word;
SaveDX:word;
SaveIP:word;
SaveEqual:boolean;
SaveLess:boolean;
Reg:byte;
RegMem:byte;
Operation:byte;
InstrSize:word;
Op1:^word;
Op2v:word;
offset:word;
Filename:string;
{$F+}
function ProcessLbl(Pat:TPatPtr):boolean; forward;
function GetLbl(Pat:TPatPtr):boolean; forward;
function ConvertHex(Pat:TPatPtr):boolean; forward;
procedure SetJmp(Pat:TPatPtr); forward;
procedure SetJa(Pat:TPatPtr); forward;
procedure SetJae(Pat:TPatPtr); forward;
procedure SetJb(Pat:TPatPtr); forward;
procedure SetJbe(Pat:TPatPtr); forward;
procedure SetJe(Pat:TPatPtr); forward;
procedure SetJne(Pat:TPatPtr); forward;
procedure SetNot(Pat:TPatPtr); forward;
procedure SetAnd(Pat:TPatPtr); forward;
procedure SetOr(Pat:TPatPtr); forward;
procedure SetCmp(Pat:TPatPtr); forward;
procedure SetSub(Pat:TPatPtr); forward;
procedure SetAdd(Pat:TPatPtr); forward;
procedure SetMovReg(Pat:TPatPtr); forward;
procedure SetMovMem(Pat:TPatPtr); forward;
procedure SetIret(Pat:TPatPtr); forward;
procedure SetHalt(Pat:TPatPtr); forward;
procedure SetBrk(Pat:TPatPtr); forward;
procedure SetPut(Pat:TPatPtr); forward;
procedure SetGet(Pat:TPatPtr); forward;
procedure SetAX(Pat:TPatPtr); forward;
procedure SetBX(Pat:TPatPtr); forward;
procedure SetCX(Pat:TPatPtr); forward;
procedure SetDX(Pat:TPatPtr); forward;
procedure SetAX2(Pat:TPatPtr); forward;
procedure SetBX2(Pat:TPatPtr); forward;
procedure SetCX2(Pat:TPatPtr); forward;
procedure SetDX2(Pat:TPatPtr); forward;
procedure SetBXInd(Pat:TPatPtr); forward;
procedure SetBXIndx(Pat:TPatPtr); forward;
procedure SetABS(Pat:TPatPtr); forward;
procedure SetImm(Pat:TPatPtr); forward;
{$F-}
const
{ WS1- Matches a string containing one or more white- }
{ space characters. }
WS1:TPattern = (mf:OneOrMoreCset; m:(cset:[' ',#9]);
Next:NIL; Alt:NIL; Success:NIL);
{ WS0- Matches a string containing zero or more white- }
{ space characters. }
WS0:TPattern=(mf:SpanCset; m:(cset:[' ',#9]);
Next:NIL; Alt:NIL; Success:NIL);
{ A Pattern that matches whitespace at the end of a line }
SkipToEOS:TPattern=(mf:EOS; m:(ch:' ');
Next:NIL; Alt:NIL; Success:NIL);
WSeoln:TPattern=(mf:SpanCset; m:(cset:[' ',#9]);
Next:@SkipToEOS; Alt:NIL; Success:NIL);
{ Match an x86 register mode here. }
TryDX:Tpattern=(mf:Matchistr; m:(str:'DX');
Next:NIL; Alt:NIL; Success:SetDX);
TryCX:Tpattern=(mf:Matchistr; m:(str:'CX');
Next:NIL; Alt:@TryDX; Success:SetCX);
TryBX:Tpattern=(mf:Matchistr; m:(str:'BX');
Next:NIL; Alt:@TryCX; Success:SetBX);
TryReg:Tpattern=(mf:Matchistr; m:(str:'AX');
Next:NIL; Alt:@TryBX; Success:SetAX);
{ Match an x86 addressing mode here }
TryImm:TPattern=( mf:ConvertHex; m:(ch:' ');
Next:@WSEoln; Alt:NIL; Success:SetImm);
TryDX2:Tpattern=(mf:Matchistr; m:(str:'DX');
Next:@WSeoln; Alt:@TryImm; Success:SetDX2);
TryCX2:Tpattern=(mf:Matchistr; m:(str:'CX');
Next:@WSeoln; Alt:@TryDX2; Success:SetCX2);
TryBX2:Tpattern=(mf:Matchistr; m:(str:'BX');
Next:@WSeoln; Alt:@TryCX2; Success:SetBX2);
TryReg2:Tpattern=(mf:Matchistr; m:(str:'AX');
Next:@WSeoln; Alt:@TryBX2; Success:SetAX2);
BXBrack:TPattern=( mf:MatchChar; m:(ch:']');
Next:NIL; Alt:NIL; Success:NIL);
BXBrackWS:TPattern=( mf:SpanCset; m:(cset:[' ',#9]);
Next:@BXBrack; Alt:NIL; Success:NIL);
BXEnd:TPattern=( mf:MatchiStr; m:(str:'BX');
Next:@BXBrackWS; Alt:NIL; Success:NIL);
TryABS:TPattern=( mf:Succeed; m:(ch:' ');
Next:@BXBrackWS; Alt:NIL; Success:SetABS);
BXPlus:TPattern=( mf:MatchChar; m:(ch:'+');
Next:@BXEnd; Alt:@TryABS; Success:SetBXIndx);
BXPlusWS:TPattern=( mf:SpanCset; m:(cset:[' ',#9]);
Next:@BXPlus; Alt:NIL; Success:NIL);
BXIndex:TPattern=( mf:ConvertHex; m:(ch:' ');
Next:@BXPlusWS; Alt:@BXEnd; Success:NIL);
BXBracket:TPattern=( mf:MatchiStr; m:(str:'BX');
Next:@BXBrackWS; Alt:@BXIndex; Success:SetBXInd);
BXIndWS:TPattern=(mf:SpanCset; m:(cset:[' ',#9]);
Next:@BXBracket; Alt:NIL; Success:NIL);
DoMem:TPattern=( mf:MatchChar; m:(ch:'[');
Next:@BXIndWS; Alt:@TryReg2; Success:NIL);
{ Generic Two-operand instructions }
TryOr:TPattern=(mf:MatchiStr; m:(str:'OR');
Next:NIL; Alt:NIL; Success:SetOr);
TryAnd:TPattern=(mf:MatchiStr; m:(str:'AND');
Next:NIL; Alt:@TryOr; Success:SetAnd);
TryCmp:TPattern=(mf:MatchiStr; m:(str:'CMP');
Next:NIL; Alt:@TryAnd; Success:SetCmp);
TrySub:TPattern=(mf:MatchiStr; m:(str:'SUB');
Next:NIL; Alt:@TryCmp; Success:SetSub);
TryAdd:TPattern=( mf:MatchiStr; m:(str:'ADD');
Next:NIL; Alt:@TrySub; Success:SetAdd);
{ Handle label definitions at the beginning of the line }
Lbl:TPattern=(mf:ProcessLbl; m:(ch:' ');
Next:NIL; Alt:NIL; Success:NIL);
{ A statement may be one of the following: }
{ }
{ 1: A Blank Line. }
{ 2: An optional label in column 1 followed by an }
{ instruction. }
{ 3: Whitespace followed by an instruction. }
{ 4: An instruction starting in column 1. }
{ }
{ The following patterns match one of the above. }
{ Zero-Operand Instructions here: }
TryBrk:TPattern=( mf:MatchiStr; m:(str:'BRK');
Next:@WSeoln; Alt:NIL; Success:SetBrk);
TryIRet:TPattern=( mf:MatchiStr; m:(str:'IRET');
Next:@WSeoln; Alt:@TryBrk; Success:SetIret);
TryHalt:TPattern=( mf:MatchiStr; m:(str:'HALT');
Next:@WSeoln; Alt:@TryIRet; Success:SetHalt);
TryPut:TPattern=( mf:MatchiStr; m:(str:'PUT');
Next:@WSeoln; Alt:@TryHalt; Success:SetPut);
TryGet:TPattern=( mf:MatchiStr; m:(str:'GET');
Next:@WSeoln; Alt:@TryPut; Success:SetGet);
{ Jump Instructions here: }
JmpLbl2:TPattern=(mf:GetLbl; m:(ch:' ');
Next:NIL; Alt:NIL; Success:NIL);
JmpLbl:TPattern=(mf:OneOrMoreCset; m:(cset:[' ',#9]);
Next:@JmpLbl2; Alt:NIL; Success:NIL);
TryJne:TPattern=(mf:MatchiStr; m:(str:'JNE');
Next:@JmpLbl; Alt:@TryGet; Success:SetJne);
TryJe:TPattern=(mf:MatchiStr; m:(str:'JE');
Next:@JmpLbl; Alt:@TryJne; Success:SetJe);
TryJb:TPattern=(mf:MatchiStr; m:(str:'JB');
Next:@JmpLbl; Alt:@TryJe; Success:SetJb);
TryJbe:TPattern=(mf:MatchiStr; m:(str:'JBE');
Next:@JmpLbl; Alt:@TryJb; Success:SetJbe);
TryJa:TPattern=(mf:MatchiStr; m:(str:'JA');
Next:@JmpLbl; Alt:@TryJbe; Success:SetJa);
TryJae:TPattern=(mf:MatchiStr; m:(str:'JAE');
Next:@JmpLbl; Alt:@TryJa; Success:SetJae);
TryJmp:TPattern=(mf:MatchiStr; m:(str:'JMP');
Next:@JmpLbl; Alt:@TryJae; Success:SetJmp);
{ not reg/mem here: }
GenMemMode:TPattern=( mf:MatchSub; m:(Pat:@DoMem);
Next:@WSeoln; Alt:NIL; Success:NIL);
NotWS:TPattern=(mf:SpanCset; m:(cset:[' ',#9]);
Next:@GenMemMode; Alt:NIL; Success:NIL);
TryNotInstr:TPattern=( mf:MatchiStr; m:(str:'NOT');
Next:@NotWS; Alt:@TryJmp; Success:SetNot);
{ instr reg, mem here: }
WSComma2:TPattern=( mf:SpanCset; m:(cset:[' ',',',#9]);
Next:@GenMemMode; Alt:NIL; Success:NIL);
GenRegMem:TPattern=(mf:MatchSub; m:(Pat:@TryReg);
Next:@WSComma2; Alt:NIL; Success:NIL);
InstrWS:TPattern=(mf:SpanCset; m:(cset:[' ',#9]);
Next:@GenRegMem; Alt:NIL; Success:NIL);
TryGeneric:TPattern=( mf:MatchSub; m:(Pat:@TryAdd);
Next:@InstrWS; Alt:@TryNotInstr; Success:NIL);
{ mov mem, reg here: }
MovReg:TPattern=(mf:MatchSub; m:(Pat:@TryReg);
Next:@WSeoln; Alt:NIL; Success:SetMovMem);
WSComma3:TPattern=( mf:SpanCset; m:(cset:[' ',',',#9]);
Next:@MovReg; Alt:NIL; Success:NIL);
MemReg:TPattern=( mf:MatchSub; m:(Pat:@DoMem);
Next:@WSComma3; Alt:NIL; Success:NIL);
{ mov reg, mem here: }
MemMode:TPattern=( mf:MatchSub; m:(Pat:@DoMem);
Next:@WSeoln; Alt:NIL; Success:SetMovReg);
WSComma:TPattern=( mf:SpanCset; m:(cset:[' ',',',#9]);
Next:@MemMode; Alt:NIL; Success:NIL);
RgMem:TPattern=(mf:MatchSub; m:(Pat:@TryReg);
Next:@WSComma; Alt:@MemReg; Success:NIL);
{ Generic mov here: }
MovWS:TPattern=(mf:SpanCset; m:(cset:[' ',#9]);
Next:@RgMem; Alt:NIL; Success:NIL);
TryMnemonic:TPattern=(mf:MatchiStr; m:(str:'MOV');
Next:@MovWS; Alt:@TryGeneric; Success:NIL);
TryEOS:TPattern=(mf:EOS; m:(ch:' ');
Next:NIL; Alt:@TryMnemonic; Success:NIL);
TryWS:TPattern =(mf:SpanCset; m:(cset:[' ',#9]);
Next:@TryEOS; Alt:NIL; Success:NIL);
stmt:TPattern = (mf:MatchSub; m:(Pat:@Lbl);
Next:@TryMnemonic; Alt:@TryWS; Success:NIL);
{ System initialization }
procedure TSIMx86Form.FormCreate(Sender: TObject);
var i: word;
ch: char;
begin
{ Allocate Storage for the x86 memory space }
system.new(Memory);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -