Вихід за межі не перевіряй
IntToHEX виправив
unit uEmulato;
interface
uses uTypes;
const cSizeOfRAM=50000;
cSizeOfRAMstak=1000;
var RAM:array[0..cSizeOfRAM] of Byte;
var RAMc:array[0..cSizeOfRAMstak] of Int32; ESP_:Int32;
var RegsDW:array[0..255] of Int32;
var RegsW:array[0..511] of Word absolute RegsDW;
var RegsB:array[0..1023] of Byte absolute RegsDW;
vAPM:OptByte;
procedure StartEngine;
const
idA=00;idB=01;idC=02;idD=03;idE=04;idF=05;idG=06;idH=07;
idI=08;idJ=09;idK=10;idL=11;idM=12;idN=13;idO=14;idP=15;
idQ=16;idR=17;idS=18;idT=19;idU=20;idV=21;idW=22;idX=23;idY=24;idZ=25;
{//;для INT вход дан YA=232;YB=233;YC=234;YD=235; YE=236;YF=237;YG=238;YH=239;}
{//;для INT виход дан ZA=240;ZB=241;ZC=242;ZD=243; ZE=244;ZF=245;ZG=246;ZH=247;}
{239}
{//TMP1=248;TMP2=249;TMP3=250;TMP4=251;}
idCMP1=252;idCMP2=253;{idESP_=254;}idEIP_=255;
implementation
procedure LoadBIN(FileName:ShortString);
var f:file; size,i:OptInt32;
begin
Assign(f,FileName); Reset(f,1); size := FileSize(f);
if size > cSizeOfRAM then size:=cSizeOfRAM;
BlockRead(f,RAM,size);Close(f);
end;
{================ MEMORY =================}
function ReadByte(a:OptByte):OptByte; begin ReadByte := RAM[a];end;
procedure WriteByte(a,v:OptByte); begin RAM[a] := v;end;
function ReadWord(a:OptWord):OptWord; begin ReadWord := RAM[a] or (RAM[a+1] shl 8);end;
procedure WriteWord(a,v:OptWord);begin RAM[a] := Byte(v); RAM[a+1] := Byte(v shr 8);end;
function ReadDWord(a:OptInt32):OptInt32; begin ReadDWord:= OptInt32(RAM[a]) or
(OptInt32(RAM[a+1]) shl 8) or (OptInt32(RAM[a+2]) shl 16) or (OptInt32(RAM[a+3])
shl 24);end;
procedure WriteDWord (a,v:OptInt32);begin RAM[a] := Byte(v);RAM[a+1] := Byte(v shr 8);
RAM[a+2] := Byte(v shr 16);RAM[a+3] := Byte(v shr 24);end;
var Wrem1,Wrem2:OptInt16;
{*}{00}Procedure OpNOP;begin Inc(RegsDW[idEIP_]); end;
{*}{01}Procedure OpMOVrv;begin RegsDW[RAM[(RegsDW[idEIP_]+1)]]:=ReadDWord(RegsDW[idEIP_]+2);Inc(RegsDW[idEIP_],6); end;
{*}{02}Procedure OpMOVrr;begin RegsDW[RAM[RegsDW[idEIP_]+1]]:=RegsDW[RAM[RegsDW[idEIP_]+2]];Inc(RegsDW[idEIP_],3);end;
{*}{03}Procedure OpMOVrm;begin RegsDW[RAM[RegsDW[idEIP_]+1]]:=ReadDWord((ReadDWord(RegsDW[idEIP_]+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{04}Procedure OpMOVrmr; begin RegsDW[RAM[(RegsDW[idEIP_]+1)]]:=ReadDWord(RegsDW[RAM[(RegsDW[idEIP_]+2)]]);
Inc(RegsDW[idEIP_],2);end;
{*}{05}Procedure OpMOVmr; begin WriteDWord((ReadDWord(RegsDW[idEIP_]+1)),RegsDW[RAM[RegsDW[idEIP_]+5]]);
Inc(RegsDW[idEIP_],6);end;
{*}{06}Procedure OpMOVmrr;begin WriteDWord(ReadDWord(RegsDW[RAM[(RegsDW[idEIP_]+1)]]),RegsDW[RAM[(RegsDW[idEIP_]+2)]]);
Inc(RegsDW[idEIP_],2);end;
{*}{07}Procedure OpMOV2rm;begin RegsDW[RAM[RegsDW[idEIP_]+1]]:=ReadWord((ReadDWord(RegsDW[idEIP_]+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{08}Procedure OpMOV2mr; begin WriteWord((ReadDWord(RegsDW[idEIP_]+1)),RegsDW[RAM[RegsDW[idEIP_]+5]]);
Inc(RegsDW[idEIP_],6);end;
{*}{09}Procedure OpMOV1rm;begin RegsDW[RAM[RegsDW[idEIP_]+1]]:=ReadByte((ReadDWord(RegsDW[idEIP_]+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{0A}Procedure OpMOV1mr; begin WriteByte((ReadDWord(RegsDW[idEIP_]+1)),RegsDW[RAM[RegsDW[idEIP_]+5]]);
Inc(RegsDW[idEIP_],6);end;
{*}{0B}Procedure OpCALLadr;begin Dec(ESP_);RAMc[ESP_]:=(RegsDW[idEIP_]+5);RegsDW[idEIP_]:=
ReadDWord(RegsDW[idEIP_]+1);end;
{*}{0C}Procedure OpCALLreg;begin Dec(ESP_);RAMc[ESP_]:=(RegsDW[idEIP_]+2);RegsDW[idEIP_]:=
RegsDW[RAM[(RegsDW[idEIP_]+1)]];end;
{*}{0D}Procedure OpRET;begin RegsDW[idEIP_]:=RAMc[ESP_];inc(ESP_);end;
{*}{0E}Procedure OpGOTOadr;begin RegsDW[idEIP_]:=ReadDWord(RegsDW[idEIP_]+1);end;
{*}{0F}Procedure OpGOTOreg;begin RegsDW[idEIP_]:=RegsDW[RAM[(RegsDW[idEIP_]+1)]];end;
{10}Procedure OpGOTOadrIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RegsDW[idEIP_]+1)
else Inc(RegsDW[idEIP_],5);end;
{11}Procedure OpGOTOadrNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RegsDW[idEIP_]+1)
else Inc(RegsDW[idEIP_],5);end;
{12}Procedure OpGOTOadrMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RegsDW[idEIP_]+1)
else Inc(RegsDW[idEIP_],5);end;
{13}Procedure OpGOTOadrLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RegsDW[idEIP_]+1)
else Inc(RegsDW[idEIP_],5);end;
{14}Procedure OpGOTOregIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RegsDW[idEIP_]+1)]]
else Inc(RegsDW[idEIP_],2);end;
{15}Procedure OpGOTOregNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RegsDW[idEIP_]+1)]]
else Inc(RegsDW[idEIP_],2);end;
{16}Procedure OpGOTOregMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RegsDW[idEIP_]+1)]]
else Inc(RegsDW[idEIP_],2);end;
{17}Procedure OpGOTOregLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RegsDW[idEIP_]+1)]]
else Inc(RegsDW[idEIP_],2);end;
{18}Procedure OpPUSHreg;begin Dec(ESP_); RAMc[ESP_]:=RegsDW[RAM[(RegsDW[idEIP_]+1)]];
Inc(RegsDW[idEIP_],2);end;
{19}Procedure OpPOPreg;begin RegsDW[RAM[(RegsDW[idEIP_]+1)]]:=RAMc[ESP_];inc(ESP_);
Inc(RegsDW[idEIP_],2);end;
procedure InitCPU; var i:Integer; begin
ESP_:=cSizeOfRAMstak;
RegsDW[ideip_]:=0;
end;
Procedure ErrorOpCodeFound1;
var r:ShortString;
begin
Writeln('ErrorOpCodeFound1');
Writeln('eip_=',RegsDW[ideip_],' ','esp_=',esp_);
Readln(r); If r='q' then halt;
end;
function IntToStr(N: Int32): string;
var S: string; Neg: Boolean;
begin S := ''; Neg := N < 0; if N = 0 then begin IntToStr := '0'; Exit; end;
if Neg then N := -N; while N > 0 do begin S := Chr(Ord('0') + (N mod 10)) + S;
N := N div 10;end; if Neg then S := '-' + S; IntToStr := S; end;
function IntToHEX(N: int32; Digits: Byte): string;
var b4:array[0..3] of Byte absolute N;
const HexChars: array[0..15] of Char = '0123456789ABCDEF';
var S: string; begin S := '';
S:=HexChars[(b4[0] div 16)]+S;S:=HexChars[(b4[0] mod 16)]+S;
if (b4[1]<>0) or (b4[2]<>0) or (b4[3]<>0) then begin
S:=HexChars[(b4[1] div 16)]+S;S:=HexChars[(b4[1] mod 16)]+S;end;
if (b4[2]<>0) or (b4[3]<>0) then begin
S:=HexChars[(b4[2] div 16)]+S;S:=HexChars[(b4[2] mod 16)]+S;end;
if (b4[3]<>0) then begin
S:=HexChars[(b4[3] div 16)]+S;S:=HexChars[(b4[3] mod 16)]+S;end;
{ доповнюємо нулями зліва }while Length(S) < Digits do S := '0' + S;IntToHEX := S;end;
procedure Test1;
var s,s1:string;
begin
case RAM[RegsDW[ideip_]] of
00:s:='NOP'; 01:s:='OpMOVrv'; 02:s:='OpMOVrr'; 03:s:='OpMOVrm';04:s:='OpMOVrmr';
05:s:='OpMOVmr';06:s:='OpMOVmrr';
07:s:='OpMOV2rm';08:s:='OpMOV2mr';
09:s:='OpMOV1rm';$0A:s:='OpMOV1mr';
$0B:s:='OpCALLadr';$0C:s:='OpCALLreg';$0D:s:='OpRET';
$0E:s:='OpGOTOadr';$0F:s:='OpGOTOreg';
$10:s:='OpGOTOadrIs';$11:s:='OpGOTOadrNotIs';$12:s:='OpGOTOadrMoreIs';
$13:s:='OpGOTOadrLess';$14:s:='OpGOTOregIs';$15:s:='OpGOTOregNotIs';
$16:s:='OpGOTOregMoreIs';$17:s:='OpGOTOregLess';
$18:s:='OpPUSHreg';$19:s:='OpPOPreg';
else s:='-----';
end;
s1:=
'eip_='+IntToStr(RegsDW[ideip_])+
'| esp_='+IntToStr(ESP_)+
'| RAMc[esp_]='+IntToStr(RAMc[ESP_])+
'| RAM[eip_]=$'+IntToHEX(RAM[RegsDW[ideip_]],2)+' |'+s+
'| A='+IntToStr(RegsDW[idA])+
'| B='+IntToStr(RegsDW[idB]);
Writeln(s1);
end;
procedure Test2;var r:ShortString; begin Test1;
Readln(r); If r='q' then halt;
end;
procedure Engine; var tmp1:OptInt16;
begin vAPM:=0; Test2;
repeat
tmp1:=RAM[RegsDW[ideip_]];
case tmp1 of
$00:OpNOP;
$01:OpMOVrv;$02:OpMOVrr;$03:OpMOVrm;$04:OpMOVrmr;
$05:OpMOVmr;$06:OpMOVmrr;
$07:OpMOV2rm;$08:OpMOV2mr;
$09:OpMOV1rm;$0A:OpMOV1mr;
$0B:OpCALLadr;$0C:OpCALLreg;$0D:OpRET;
$0E:OpGOTOadr;$0F:OpGOTOreg;
$10:OpGOTOadrIs;$11:OpGOTOadrNotIs;$12:OpGOTOadrMoreIs;
$13:OpGOTOadrLess;$14:OpGOTOregIs;$15:OpGOTOregNotIs;
$16:OpGOTOregMoreIs;$17:OpGOTOregLess;
$18:OpPUSHreg;$19:OpPOPreg;
else ErrorOpCodeFound1;end;
Test2; until vAPM<>0; end;
procedure StartEngine;
begin
LoadBIN('BOOT.bin');
InitCPU;
{RegsDW[eip_]:=0;}
{ESP_:= SizeOf(RAMc);} {стек}
Engine;
end;
end.