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

📄 simx86p.pas

📁 汇编编程艺术
💻 PAS
📖 第 1 页 / 共 4 页
字号:
	Operand:word;
begin

	Result := IntToHex(CodeAdrs,4) + ': ' +
        	  IntToHex(ReadMem(CodeAdrs),2) + ' ';

        Size := InstrSz(ReadMem(CodeAdrs));
        Opcode := ReadMem(CodeAdrs);
        if Size = 1 then
        begin

        	Result := Result + '      ';
                inc(CodeAdrs);

        end
        else begin

        	Result := Result +
        	       IntToHex(ReadMem(CodeAdrs+1),2) + ' ' +
                       IntToHex(ReadMem(CodeAdrs+2),2) + ' ';
                Operand := ReadMem(CodeAdrs+1) + (ReadMem(CodeAdrs+2) shl 8);
                CodeAdrs := CodeAdrs + 3;

        end;
        Result := Result + Instr(opcode) + ' ';
        case (opcode shr 5) of
        1,2,3,4,5,6:begin

        	case ((opcode shr 3) and $3) of
                0: Result := Result + 'ax, ';
                1: Result := Result + 'bx, ';
                2: Result := Result + 'cx, ';
                3: Result := Result + 'dx, ';
                end;
                Result := Result + AdrsMode(Opcode, Operand);
            end;

        7:begin

        	Result := Result + AdrsMode(Opcode, Operand) + ', ';
                case ((opcode shr 3) and $3) of
                0: Result := Result + 'ax';
                1: Result := Result + 'bx';
                2: Result := Result + 'cx';
                3: Result := Result + 'dx';
                end;
           end;

        0: begin

        	case (opcode shr 3) and $3 of
                1: Result := Result + IntToHex(Operand,4);
                2: Result := Result + AdrsMode(Opcode,Operand);
                end;

           end;

        end;

end;



function Disassemble(CodeAdrs:word):string;
begin

	Result := Disassemble2(CodeAdrs);

end;



{ The following event method handles switching between pages on the form. }

procedure TSIMx86Form.Simx86PagesChange(Sender: TObject;
					NewTab: Integer;
  					var AllowChange: Boolean);
var DisAdrs:word;
    i:integer;
begin

	{ Don't allow a change if a program is running. }

	if (Running and (NewTab = 0)) then
        begin

        	AllowChange := false;

        end

        { If the user switches to the memory page, redraw all the cells. }

	else if (NewTab = 1) then
        	AdrsEntryChange(AdrsEntry)

        { If the user switches to the execute page, disassemble some	}
        { code for the disassembly list box.				}

        else if (NewTab = 2) then
        begin

            DisAdrs := HexToWord(DisAsmAdrs.Text);
            DisAsm.Clear;
            for i := 1 to 15 do
            	DisAsm.Items.Add(Disassemble2(DisAdrs));
            Instruction.Caption := Disassemble(IP);

        end;

end;



{ If the user changes the address in the TEdit box at the bottom of the	}
{ disassembly list box, the following procedure converts this to a word	}
{ and disassembles 15 instructions starting at this new address.	}

procedure TSIMx86Form.DisAsmAdrsChange(Sender: TObject);
var i:integer;
    DisAdrs:word;
begin

    DisAdrs := HexToWord(DisAsmAdrs.Text);
    DisAsm.Clear;
    for i := 1 to 15 do
        DisAsm.Items.Add(Disassemble2(DisAdrs));

end;


{ If the user presses on the down portion of the spinner at the bottom	}
{ of the disassembly list box, this method increments the disassembly	}
{ address and updates the disassembly list box.				}

procedure TSIMx86Form.SpinButtonDownClick(Sender: TObject);
var value:word;
begin

    Value := HexToWord(DisAsmAdrs.Text);
    inc(Value);
    DisAsmAdrs.Text := IntToHex(Value,4);

end;

{ If they press on the up arrow portion of the spinner, this code will	}
{ decrement the starting disassembly address and update the list box.	}

procedure TSIMx86Form.SpinButtonUpClick(Sender: TObject);
var value:word;
begin

    Value := HexToWord(DisAsmAdrs.Text);
    dec(Value);
    DisAsmAdrs.Text := IntToHex(Value,4);

end;








procedure OneInstr;


    procedure Store(mode:byte; index:word; value: word);
    begin

	case mode of

        0: AX := value;
        1: BX := value;
        2: CX := value;
        3: DX := value;
        4: begin

        	WriteMem(bx, value and $FF);
                WriteMem(bx+1, value shr 8);

           end;

        5: begin

        	WriteMem(bx+index, value and $FF);
                WriteMem(bx+index+1, value shr 8);

           end;

        6: begin

        	WriteMem(index, value and $FF);
                WriteMem(index+1, value shr 8);

           end;

        end;

    end;


begin

	with  SIMx86Form do begin

                if (PendingInt) and (not InInt) then
                   if (IntAdrs <> $FFFF) then
                   begin

                   	InInt := true;
                        SaveAX := AX;
                        SaveBX := BX;
                        SaveCX := CX;
                        SaveDX := DX;
                        SaveIP := IP;
                        SaveLess := LessThanFlag.Checked;
                        SaveEqual:= EqualFlag.Checked;
                        PendingInt := false;

                        IP := IntAdrs;

                   end;

                { Okay, do the instruction here.	}

                Opcode := ReadMem(IP);
                Operation := Opcode shr 5;
                Reg := (Opcode shr 3) and $3;
                RegMem := Opcode and $7;
                InstrSize := 1;

                case Reg of
                  0: Op1 := @AX;
                  1: Op1 := @BX;
                  2: Op1 := @CX;
                  3: Op1 := @DX;
                end;


                case RegMem of
                  0: Op2v := AX;
                  1: Op2v := BX;
                  2: Op2v := CX;
                  3: Op2v := DX;

                  4: Op2v := ReadMem(BX) + (ReadMem(BX+1) shl 8);

                  5: begin {[1000+bx]}

                  	offset := BX + ReadMem(IP+1) + ReadMem(IP+2) shl 8;
                  	Op2v := ReadMem(offset) + ReadMem(offset+1) shl 8;
                        InstrSize := 3;

                     end;

                  6: begin {[1000]}

                  	offset := ReadMem(IP+1) + ReadMem(IP+2) shl 8;
                  	Op2v := ReadMem(offset) + ReadMem(offset+1) shl 8;
                        InstrSize := 3;

                     end;

                  7: begin {1000}

                  	Op2v := ReadMem(IP+1) + ReadMem(IP+2) shl 8;
                        InstrSize := 3;

                     end;

                end;

                case Operation of

                  1: Op1^ := Op1^ or Op2v;
		  2: Op1^ := Op1^ and Op2v;

                  3: begin

                  	LessThanFlag.Checked := Op1^ < Op2v;
                        EqualFlag.Checked := Op1^ = Op2v;

                     end;

		  4: Op1^ := Op1^ - Op2v;
		  5: Op1^ := Op1^ + Op2v;
                  6: Op1^ := Op2v;
                  7: Store(regmem, ReadMem(IP+1) + ReadMem(IP+2) shl 8, Op1^);

                  0: case Reg of

                  	2: Store(regmem,
                        	 ReadMem(IP+1) + ReadMem(IP+2) shl 8,
                                 not Op2v);

                        1: begin {jumps}

                        	InstrSize := 0;
                        	case RegMem of

                        	0: if EqualFlag.Checked then
                                	IP := ReadMem(IP+1) +
                                        	ReadMem(IP+2) shl 8
                                   else InstrSize := 3;

                        	1: if not EqualFlag.Checked then
                                	IP := ReadMem(IP+1) +
                                        	ReadMem(IP+2) shl 8
                                   else InstrSize := 3;

                        	2: if LessThanFlag.Checked then
                                	IP := ReadMem(IP+1) +
                                        	ReadMem(IP+2) shl 8
                                   else InstrSize := 3;

                        	3: if LessThanFlag.Checked or
                                      EqualFlag.Checked then
                                	IP := ReadMem(IP+1) +
                                        	ReadMem(IP+2) shl 8
                                   else InstrSize := 3;

                        	4: if not (LessThanFlag.Checked or
                                           EqualFlag.Checked) then
                                	IP := ReadMem(IP+1) +
                                        	ReadMem(IP+2) shl 8
                                   else InstrSize := 3;

                        	5: if not LessThanFlag.Checked then
                                	IP := ReadMem(IP+1) +
                                        	ReadMem(IP+2) shl 8
                                   else InstrSize := 3;

                        	6: IP := ReadMem(IP+1) + ReadMem(IP+2) shl 8;

                                7: begin

                                	ErrorMsg('Illegal instruction',
                                        	 IntToHex(IP,4));

                                        Halted := true;

                                   end;

                                end;
                           end;

                        3: begin

                        	ErrorMsg('Illegal instruction',IntToHex(IP,4));
				Halted := true;

                           end;

                        0: case (RegMem) of
                           0,1,2:begin

                        	ErrorMsg('Illegal instruction',IntToHex(IP,4));
				Halted := true;
                                InstrSize := 0;

                              end;

                           3: begin

                        	ErrorMsg('BRK encountered',IntToHex(IP,4));
				Halted := true;
                                InstrSize := 1;

                              end;

                           4: if (not InInt) then
                              begin

                        	ErrorMsg('IRET encountered outside interrupt',
                                	 IntToHex(IP,4));
				Halted := true;
                                InstrSize := 0;

                              end
                              else begin

                              	AX := SaveAX;
                              	BX := SaveBX;
                              	CX := SaveCX;
                              	DX := SaveDX;
                              	IP := SaveIP;
                                LessThanFlag.Checked := SaveLess;
                                EqualFlag.Checked := SaveEqual;
                                InstrSize := 0;
                                InInt := false;

                              end;

                           5: begin

                        	ErrorMsg('Halt encountered',IntToHex(IP,4));
				Halted := true;
                                InstrSize := 0;

                              end;

                           6: begin

                           	InputForm.ShowModal;
                           	AX := InputValue;
                                InstrSize := 1;

                              end;

                           7: begin

                           	Output.Items.Add(IntToHex(AX,4));
                                InstrSize := 1;

                              end;

                        end;
                  end;
                end;
                IP := IP + InstrSize;

        end;

end;


procedure StopPgm;
begin

    with SIMx86Form do begin

	IPValue.Enabled := true;
	DisAsmAdrs.Enabled := true;
	SpinButton.Enabled := true;
	RunBtn.Enabled := true;
	StepBtn.Enabled := true;
	AXValue.Enabled := true;
	BXValue.Enabled := true;
	CXValue.Enabled := true;
	DXValue.Enabled := true;
	LessThanFlag.Enabled := true;
	EqualFlag.Enabled := true;
	HaltBtn.Enabled := false;
        RunningLite.Color := clGray;
        MainMenu.Items[0].Enabled := true;
        MainMenu.Items[1].Enabled := true;
        PendingInt := false;
        Instruction.Caption := Disassemble(IP);

    end;

end;

{ If the users presses the "RUN" button, the following code kicks in	}
{ the emulator.								}

procedure TSIMx86Form.RunBtnClick(Sender: TObject);


begin

	IPValue.Enabled := false;
	DisAsmAdrs.Enabled := false;
	SpinButton.Enabled := false;
	RunBtn.Enabled := false;
	StepBtn.Enabled := false;
	AXValue.Enabled := false;
	BXValue.Enabled := false;
	CXValue.Enabled := false;
	DXValue.Enabled := false;
	LessThanFlag.Enabled := false;
	EqualFlag.Enabled := false;
	HaltBtn.Enabled := true;
        RunningLite.Color := clRed;
        PendingInt := false;

        MainMenu.Items[0].Enabled := false;
        MainMenu.Items[1].Enabled := false;

        Halted := false;
        Running := true;
        InInt := false;



        while not Halted do begin

        	Application.ProcessMessages;
                OneInstr;

        end;
        Running := false;
        RunningLite.Color := clGray;
        StopPgm;

        IPValue.Text := IntToHex(IP,4);
        AXValue.Text := IntToHex(AX,4);
        BXValue.Text := IntToHex(BX,4);
        CXValue.Text := IntToHex(CX,4);
        DXValue.Text := IntToHex(DX,4);

end;

procedure TSIMx86Form.HaltBtnClick(Sender: TObject);
begin

	StopPgm;
        Halted := true;

end;


{ If the user presses the reset button, the following method resets	}
{ the machine.								}

procedure TSIMx86Form.ResetBtnClick(Sender: TObject);
begin

	AX := 0;
        BX := 0;
        CX := 0;
        DX := 0;
        AXValue.Text := '0000';
        BXValue.Text := '0000';
        CXValue.Text := '0000';
        DXValue.Text := '0000';
        if (ResetVect.Color <> clRed) then
        begin

        	IP := HexToWord(ResetVect.Text);
	        IPValue.Text := ResetVect.Text;

        end
        else begin

        	IP := 0;
                IPValue.Text := '0000';

        end;
        LessThanFlag.Checked := false;
        EqualFlag.Checked := false;
        PendingInt := false;
        StopPgm;
        Halted := true;
        Output.Items.Clear;
        Input.Items.Clear;
        Instruction.Caption := Disassemble(IP);


end;




procedure TSIMx86Form.InterruptBtnClick(Sender: TObject);
begin

	PendingInt := true;

end;



procedure TSIMx86Form.IntVectChange(Sender: TObject);
begin

	CheckHex(IntVect);
        if (IntVect.Color <> clRed) then
        begin

        	IntAdrs := HexToWord(IntVect.Text);

        end;
end;

procedure TSIMx86Form.IPValueChange(Sender: TObject);
begin

	CheckHex(IPValue);
        if IPValue.Color <> clRed then
        begin

        	IP := HexToWord(IPValue.Text);

        end;
        Instruction.Caption := Disassemble(IP);

end;

procedure TSIMx86Form.StepBtnClick(Sender: TObject);
begin

	OneInstr;
        IPValue.Text := IntToHex(IP,4);
        AXValue.Text := IntToHex(AX,4);
        BXValue.Text := IntToHex(BX,4);
        CXValue.Text := IntToHex(CX,4);
        DXValue.Text := IntToHex(DX,4);
        Instruction.Caption := Disassemble(IP);

end;


end.

⌨️ 快捷键说明

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