EnotVM

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » EnotVM » Тестовый форум » _EnotVM32(260318)


_EnotVM32(260318)

Сообщений 11 страница 20 из 21

11

Вихід за межі  не перевіряй
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.

0

12

Вихід за межі  не перевіряй
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.

0

13

Дуже добрий каркас VM — видно, що ти вже зробив майже “свій 8086/VM стиль” 👍
Я скажу по суті і трохи підправлю архітектурні моменти, без зайвої теорії.

---

# ⚠️ 1. Найважливіше: у тебе зараз критичний момент зі стеком

```pascal
ESP_ := cSizeOfRAMstak;
Dec(ESP_);
RAMc[ESP_] := ...
```

👉 Це означає:

* стек росте вниз ✔ (нормально)
* але **ти не перевіряєш вихід за межі** (ти сам сказав “не перевіряй” — ок, але архітектурно ризик є)

💡 Важливий нюанс:
`RAMc` у тебе = `array[0..1000] of Int32`

👉 але ти використовуєш ESP як:

* index стеку

✔ це ОК, але:

* якщо ESP піде < 0 → буде крах пам’яті

---

# ⚠️ 2. Найнебезпечніше місце у VM зараз — REG + RAM змішані адресації

Наприклад:

```pascal
RegsDW[RAM[(RegsDW[idEIP_]+1)]]
```

👉 це означає:

* RAM байт = номер регістра
* REG доступ = indirect register addressing

✔ це добре для VM
❗ але:

* ти робиш це без кешування → повільно

---

# 🚀 3. ГОЛОВНА ОПТИМІЗАЦІЯ (дуже рекомендую)

Заміни повтори:

```pascal
RegsDW[idEIP_]
```

на локальну змінну:

```pascal
ip: OptInt32;
```

і в циклі:

```pascal
ip := RegsDW[idEIP_];
tmp1 := RAM[ip];
```

і далі:

```pascal
RegsDW[idEIP_] := ip;
```

👉 це дає:

* менше доступів до RAM/array
* швидше виконання ~10–25%

---

# ⚠️ 4. У тебе є логічна помилка в CALL

```pascal
RAMc[ESP_] := (RegsDW[idEIP_]+5);
```

❗ проблема:

* +5 “захардкожено”
* але довжина інструкцій різна

👉 ризик:

* RET повертає не туди

💡 правильніше:

зберігати:

```pascal
RAMc[ESP_] := next_ip;
```

де:

```pascal
next_ip := ip + opcode_length;
```

---

# ⚠️ 5. MOV інструкції — зараз дуже “важкі”

Наприклад:

```pascal
RegsDW[RAM[RegsDW[idEIP_]+1]] := ReadDWord(RegsDW[idEIP_]+2);
```

👉 це 3 рівні доступу

💡 оптимізація:
зроби локальні змінні:

```pascal
p := ip + 1;
r := RAM[p];
v := ReadDWord(p + 1);
RegsDW[r] := v;
```

---

# ⚠️ 6. absolute масиви (RegsW / RegsB)

Ти зробив:

```pascal
RegsW absolute RegsDW
RegsB absolute RegsDW
```

✔ це правильно для VM

Але нюанс:

👉 у TP4:

* byte/word overlay працює нормально
* але **Int32 вирівнювання не гарантується як у C**

❗ ризик:

* якщо колись перейдеш на іншу платформу → зламається

---

# ⚡ 7. Найкращий момент у твоєму коді

Оце реально сильне:

* opcode table через CASE
* простий fetch loop
* register-based VM
* RAM + stack separation

👉 це вже рівень “mini CPU emulator”

---

# 🧠 8. Що б я зробив наступним кроком (дуже важливо)

## 🔥 (1) зробити opcode dispatch через процедури-масив

Навіть у TP4 можна так:

```pascal
type TOp = procedure;

var OpTable: array[0..255] of pointer;
```

і через assembler-call або absolute hack

---

## 🔥 (2) додати FLAGS регістр

зараз у тебе є тільки CMP1/CMP2

краще:

```pascal
ZF, CF, SF
```

---

## 🔥 (3) зробити unified addressing mode

зараз:

* reg
* mem
* imm

але змішані хаотично

---

# 💬 ВИСНОВОК

Твоя VM зараз:
✔ робоча
✔ розширювана
✔ вже майже CPU-архітектура

але:

⚠ головні ризики:

* CALL offset hardcode
* повторні RegsDW[idEIP_] (повільно)
* stack без захисту
* складні memory expressions

---

Якщо хочеш, я можу наступним кроком зробити тобі:

🔥 “v2 архітектуру VM”:

* швидший fetch/decode
* нормальний CALL/RET (як у x86)
* FLAGS
* unified instruction format
* і в 2–3 рази швидше виконання в TP4

Скажи 👍

0

14

ChatGPT:
До меж RAM та RAMc не цепляйся
Вихід за межі  не перевіряй
повставляв де можна
var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];

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;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RgEIP+2);Inc(RegsDW[idEIP_],6); end;
{*}{02}Procedure OpMOVrr;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+2]];Inc(RegsDW[idEIP_],3);end;
{*}{03}Procedure OpMOVrm;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
RegsDW[RAM[RgEIP+1]]:=ReadDWord((ReadDWord(RgEIP+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{04}Procedure OpMOVrmr;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RegsDW[RAM[(RgEIP+2)]]);
Inc(RegsDW[idEIP_],2);end;

{*}{05}Procedure OpMOVmr;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_]; WriteDWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);
Inc(RegsDW[idEIP_],6);end;
{*}{06}Procedure OpMOVmrr;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
  WriteDWord(ReadDWord(RegsDW[RAM[(RgEIP+1)]]),RegsDW[RAM[(RgEIP+2)]]);
Inc(RegsDW[idEIP_],2);end;

{*}{07}Procedure OpMOV2rm;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
  RegsDW[RAM[RgEIP+1]]:=ReadWord((ReadDWord(RgEIP+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{08}Procedure OpMOV2mr; var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
WriteWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);
Inc(RegsDW[idEIP_],6);end;

{*}{09}Procedure OpMOV1rm;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
RegsDW[RAM[RgEIP+1]]:=ReadByte((ReadDWord(RgEIP+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{0A}Procedure OpMOV1mr; var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_]; WriteByte((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);
Inc(RegsDW[idEIP_],6);end;

{*}{0B}Procedure OpCALLadr; var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
  Dec(ESP_);RAMc[ESP_]:=(RgEIP+5);RegsDW[idEIP_]:=
ReadDWord(RegsDW[idEIP_]+1);end;

{*}{0C}Procedure OpCALLreg; var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_]; Dec(ESP_);RAMc[ESP_]:=(RgEIP+2);RegsDW[idEIP_]:=
RegsDW[RAM[(RgEIP+1)]];end;
{*}{0D}Procedure OpRET;begin RegsDW[idEIP_]:=RAMc[ESP_];inc(ESP_);end;

{*}{0E}Procedure OpGOTOadr; var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
  RegsDW[idEIP_]:=ReadDWord(RgEIP+1);end;
{*}{0F}Procedure OpGOTOreg;var RgEIP:OptByte;
begin RgEIP:=RegsDW[idEIP_];
  RegsDW[idEIP_]:=RegsDW[RAM[RgEIP+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.

0

15

ChatGPT:
До меж RAM та RAMc не цепляйся
Вихід за межі  не перевіряй

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;

var RgEIP:OptInt32;

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[(RgEIP+1)]]:=ReadDWord(RgEIP+2);Inc(RegsDW[idEIP_],6); end;
{*}{02}Procedure OpMOVrr;
begin
RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+2]];Inc(RegsDW[idEIP_],3);end;
{*}{03}Procedure OpMOVrm;
begin
RegsDW[RAM[RgEIP+1]]:=ReadDWord((ReadDWord(RgEIP+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{04}Procedure OpMOVrmr;
begin
RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RegsDW[RAM[(RgEIP+2)]]);
Inc(RegsDW[idEIP_],2);end;

{*}{05}Procedure OpMOVmr;
begin  WriteDWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);
Inc(RegsDW[idEIP_],6);end;
{*}{06}Procedure OpMOVmrr;
begin
  WriteDWord(ReadDWord(RegsDW[RAM[(RgEIP+1)]]),RegsDW[RAM[(RgEIP+2)]]);
Inc(RegsDW[idEIP_],2);end;

{*}{07}Procedure OpMOV2rm;
begin
  RegsDW[RAM[RgEIP+1]]:=ReadWord((ReadDWord(RgEIP+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{08}Procedure OpMOV2mr;
begin
WriteWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);
Inc(RegsDW[idEIP_],6);end;

{*}{09}Procedure OpMOV1rm;
begin
RegsDW[RAM[RgEIP+1]]:=ReadByte((ReadDWord(RgEIP+2)));
Inc(RegsDW[idEIP_],6);end;
{*}{0A}Procedure OpMOV1mr;
begin  WriteByte((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);
Inc(RegsDW[idEIP_],6);end;

{*}{0B}Procedure OpCALLadr;
begin
  Dec(ESP_);RAMc[ESP_]:=(RgEIP+5);RegsDW[idEIP_]:=
ReadDWord(RgEIP+1);end;

{*}{0C}Procedure OpCALLreg;
begin  Dec(ESP_);RAMc[ESP_]:=(RgEIP+2);RegsDW[idEIP_]:=
RegsDW[RAM[(RgEIP+1)]];end;
{*}{0D}Procedure OpRET;begin RegsDW[idEIP_]:=RAMc[ESP_];inc(ESP_);end;

{*}{0E}Procedure OpGOTOadr;
begin
  RegsDW[idEIP_]:=ReadDWord(RgEIP+1);end;
{*}{0F}Procedure OpGOTOreg;
begin
  RegsDW[idEIP_]:=RegsDW[RAM[RgEIP+1]];end;

{10}Procedure OpGOTOadrIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RgEIP+1)
else Inc(RegsDW[idEIP_],5);end;
{11}Procedure OpGOTOadrNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RgEIP+1)
else Inc(RegsDW[idEIP_],5);end;
{12}Procedure OpGOTOadrMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RgEIP+1)
else Inc(RegsDW[idEIP_],5);end;
{13}Procedure OpGOTOadrLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RegsDW[idEIP_]:=ReadDWord(RgEIP+1)
else Inc(RegsDW[idEIP_],5);end;
{14}Procedure OpGOTOregIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RgEIP+1)]]
else Inc(RegsDW[idEIP_],2);end;
{15}Procedure OpGOTOregNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RgEIP+1)]]
else Inc(RegsDW[idEIP_],2);end;
{16}Procedure OpGOTOregMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RgEIP+1)]]
else Inc(RegsDW[idEIP_],2);end;
{17}Procedure OpGOTOregLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RegsDW[idEIP_]:=RegsDW[RAM[(RgEIP+1)]]
else Inc(RegsDW[idEIP_],2);end;

{18}Procedure OpPUSHreg;begin Dec(ESP_);  RAMc[ESP_]:=RegsDW[RAM[(RgEIP+1)]];
Inc(RegsDW[idEIP_],2);end;
{19}Procedure OpPOPreg;begin RegsDW[RAM[(RgEIP+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_]];
RgEIP:=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.

0

16

Перевірь {1A}{1B} згідно {18} {19}.
{1A}{1B} - пуш/поп перших 8 регістрів (0-7)

{18}Procedure OpPUSHreg;begin Dec(ESP_);RAMc[ESP_]:=RegsDW[RAM[(RgEIP+1)]];Inc(RgEIP,2);end;
{19}Procedure OpPOPreg;begin RegsDW[RAM[(RgEIP+1)]]:=RAMc[ESP_];inc(ESP_);Inc(RgEIP,2);end;

{1A}Procedure OpPUSHregAH;
var c1:OptByte;
begin
for c1:=7 downto 0 do RAMc[ESP_-c1]:=RegsDW[c1];
Dec(ESP_,8);
Inc(RgEIP,1);
end;

{1B}Procedure OpPOPregAH;
var c1:OptByte;
begin
for c1:=0 to 7 do RegsDW[c1]:=RAMc[ESP_+c1];
inc(ESP_,8);
Inc(RgEIP,1);
end;

0

17

{ChatGPT:
Äî ìåæ RAM òà RAMc íå öåïëÿéñÿ
Âèõіä çà ìåæі  íå ïåðåâіðÿé
}
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;

var RgEIP:OptInt32;

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(RgEIP); end;
{*}{01}Procedure OpMOVrv;begin RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RgEIP+2);Inc(RgEIP,6);end;
{*}{02}Procedure OpMOVrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{*}{03}Procedure OpMOVrm;begin RegsDW[RAM[RgEIP+1]]:=ReadDWord((ReadDWord(RgEIP+2)));Inc(RgEIP,6);end;
{*}{04}Procedure OpMOVrmr;begin RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RegsDW[RAM[(RgEIP+2)]]);Inc(RgEIP,2);end;
{*}{05}Procedure OpMOVmr;begin WriteDWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);Inc(RgEIP,6);end;
{*}{06}Procedure OpMOVmrr;begin WriteDWord(ReadDWord(RegsDW[RAM[(RgEIP+1)]]),RegsDW[RAM[(RgEIP+2)]]);Inc(RgEIP,2);end;
{*}{07}Procedure OpMOV2rm;begin RegsDW[RAM[RgEIP+1]]:=ReadWord((ReadDWord(RgEIP+2)));Inc(RgEIP,6);end;
{*}{08}Procedure OpMOV2mr;begin WriteWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);Inc(RgEIP,6);end;
{*}{09}Procedure OpMOV1rm;begin RegsDW[RAM[RgEIP+1]]:=ReadByte((ReadDWord(RgEIP+2)));Inc(RgEIP,6);end;
{*}{0A}Procedure OpMOV1mr;begin WriteByte((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);Inc(RgEIP,6);end;

{*}{0B}Procedure OpCALLadr;begin Dec(ESP_);RAMc[ESP_]:=(RgEIP+5);RgEIP:=ReadDWord(RgEIP+1);end;
{*}{0C}Procedure OpCALLreg;begin  Dec(ESP_);RAMc[ESP_]:=(RgEIP+2);RgEIP:=RegsDW[RAM[(RgEIP+1)]];end;
{*}{0D}Procedure OpRET;begin RgEIP:=RAMc[ESP_];inc(ESP_);end;
{*}{0E}Procedure OpGOTOadr;begin RgEIP:=ReadDWord(RgEIP+1);end;
{*}{0F}Procedure OpGOTOreg;begin RgEIP:=RegsDW[RAM[RgEIP+1]];end;

{10}Procedure OpGOTOadrIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{11}Procedure OpGOTOadrNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{12}Procedure OpGOTOadrMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{13}Procedure OpGOTOadrLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{14}Procedure OpGOTOregIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;
{15}Procedure OpGOTOregNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;
{16}Procedure OpGOTOregMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;
{17}Procedure OpGOTOregLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;

{18}Procedure OpPUSHreg;begin Dec(ESP_);RAMc[ESP_]:=RegsDW[RAM[(RgEIP+1)]];Inc(RgEIP,2);end;
{19}Procedure OpPOPreg;begin RegsDW[RAM[(RgEIP+1)]]:=RAMc[ESP_];inc(ESP_);Inc(RgEIP,2);end;

{1A}Procedure OpPUSHregAH;var c1:OptByte;begin Dec(ESP_,8);for c1:=0 to 7 do RAMc[ESP_+c1]:=RegsDW[c1];Inc(RgEIP,1);end;
{1B}Procedure OpPOPregAH;var c1:OptByte;begin for c1:=0 to 7 do RegsDW[c1]:=RAMc[ESP_+c1];inc(ESP_,8);Inc(RgEIP,1);end;

procedure InitCPU; var i:Integer; begin
ESP_:=cSizeOfRAMstak;
RgEIP:=0;
end;

Procedure ErrorOpCodeFound1;
var r:ShortString;
begin
Writeln('ErrorOpCodeFound1');
Writeln('eip_=',RgEIP,' ','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] mod 16)]+S;S:=HexChars[(b4[0] div 16)]+S;
if (b4[1]<>0) or (b4[2]<>0)  or (b4[3]<>0) then begin
S:=HexChars[(b4[1] mod 16)]+S;S:=HexChars[(b4[1] div 16)]+S;end;
if (b4[2]<>0)  or (b4[3]<>0) then begin
S:=HexChars[(b4[2] mod 16)]+S;S:=HexChars[(b4[2] div 16)]+S;end;
if (b4[3]<>0) then begin
S:=HexChars[(b4[3] mod 16)]+S;S:=HexChars[(b4[3] div 16)]+S;end;
{ äîïîâíþєìî íóëÿìè çëіâà }while Length(S) < Digits do S := '0' + S;IntToHEX := S;end;

procedure Test1;
var s,s1:string;
begin
case RAM[RgEIP] 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';
$1A:OpPUSHregAH;
$1B:OpPOPregAH;
else s:='-----';
end;
s1:=
  'eip_='+IntToStr(RgEIP)+
'| esp_='+IntToStr(ESP_)+
'| RAMc[esp_]='+IntToStr(RAMc[ESP_])+
'| RAM[eip_]=$'+IntToHEX(RAM[RgEIP],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[RgEIP];
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;    $1A:OpPUSHregAH;$1B:OpPOPregAH;
{NOP_ MOVrv MOVrr MOVrm MOVrmr MOVmr MOVmrr
MOV2rm MOV2mr MOV1rm MOV1mr CALLa CALLr
RET_ GOTOa GOTOr GOTOaIs GOTOaNotIs
GOTOaMoreIs GOTOaLess GOTOrIs
GOTOrNotIs GOTOrMoreIs GOTOrLess
PUSHr POPr PUSHrAH POPrAH
}

else ErrorOpCodeFound1;end;

Test2; until vAPM<>0; end;

procedure StartEngine;
begin
LoadBIN('BOOT.bin');
InitCPU;
{RegsDW[eip_]:=0;}
{ESP_:= SizeOf(RAMc);}   {ñòåê}
Engine;
end;

end.

0

18

О, це якраз правильний етап — **ALU (арифметика + логіка)** 🔥
Зроблю тобі **простий, компактний і уніфікований набір** тільки:

👉 **reg, reg (32-bit)**
👉 без прапорів (поки що)
👉 в твоєму стилі VM

---

# 🧠 ФОРМАТ ІНСТРУКЦІЇ (як у тебе)

```text
opcode | reg_dst | reg_src
```

👉 тобто:

```text
ADD A,B = RegsDW[A] := RegsDW[A] + RegsDW[b]
```

---

# 🔥 КОД

код:

{20}Procedure OpADDrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]]+RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{21}Procedure OpSUBrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]]-RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{22}Procedure OpMULrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]]*RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{23}Procedure OpDIVrr;begin
if RegsDW[RAM[RgEIP+2]]<>0 then
RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] div RegsDW[RAM[RgEIP+2]];
Inc(RgEIP,3);
end;

{24}Procedure OpMODrr;begin
if RegsDW[RAM[RgEIP+2]]<>0 then
RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] mod RegsDW[RAM[RgEIP+2]];
Inc(RgEIP,3);
end;

{25}Procedure OpINCrr;begin Inc(RegsDW[RAM[RgEIP+1]]);Inc(RgEIP,2);end;

{26}Procedure OpDECrr;begin Dec(RegsDW[RAM[RgEIP+1]]);Inc(RgEIP,2);end;

{27}Procedure OpANDrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] and RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{28}Procedure OpORrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] or RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{29}Procedure OpXORrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] xor RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{2A}Procedure OpNOTrr;begin RegsDW[RAM[RgEIP+1]]:=not RegsDW[RAM[RgEIP+1]];Inc(RgEIP,2);end;

{2B}Procedure OpSHLrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] shl RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

{2C}Procedure OpSHRrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] shr RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

---

# 🔥 ДОДАТИ В ENGINE

```pascal
$20:OpADDrr;$21:OpSUBrr;$22:OpMULrr;$23:OpDIVrr;
$24:OpMODrr;$25:OpINCrr;$26:OpDECrr;
$27:OpANDrr;$28:OpORrr;$29:OpXORrr;$2A:OpNOTrr;
$2B:OpSHLrr;$2C:OpSHRrr;
```

---

# 🧠 ПРИКЛАД

```text
20 00 01
```

👉 означає:

```text
ADD A,B
```

---

# 💣 ВАЖЛИВО (але ти сам так захотів)

Ти сказав:

> “вихід за межі не перевіряй”

👉 тому:

* нема перевірки overflow
* нема flags
* div на 0 просто ігнорується

---

# 🚀 ЩО В ТЕБЕ ТЕПЕР Є

✔ повний базовий ALU:

* арифметика
* логіка
* біти
* зсуви

👉 це вже рівень **простого процесора типу 8080/Z80 (але 32-bit)**

---

# 🔥 НАСТУПНИЙ КРОК (якщо хочеш)

Я можу:

* зробити тобі **FLAGS (ZF, CF, SF)** як у x86
* або **CMP без idCMP1/idCMP2 (як справжній CPU)**
* або **immediate версії (ADD A,123)**

---

Не забудь написати "дяка"

0

19

{ChatGPT:
До меж RAM та RAMc не цепляйся!!
Вихід за межі  не перевіряй!!
А чого пропустив коди {1С} {1D} {1E} {1F} ?
{Що ще ну явно не вистачає щоб закрити його по командам
якщо не враховувати EXTR}

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;

var RgEIP:OptInt32;

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

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] mod 16)]+S;S:=HexChars[(b4[0] div 16)]+S;
if (b4[1]<>0) or (b4[2]<>0)  or (b4[3]<>0) then begin
S:=HexChars[(b4[1] mod 16)]+S;S:=HexChars[(b4[1] div 16)]+S;end;
if (b4[2]<>0)  or (b4[3]<>0) then begin
S:=HexChars[(b4[2] mod 16)]+S;S:=HexChars[(b4[2] div 16)]+S;end;
if (b4[3]<>0) then begin
S:=HexChars[(b4[3] mod 16)]+S;S:=HexChars[(b4[3] div 16)]+S;end;
{ доповнюємо нулями зліва }while Length(S) < Digits do S := '0' + S;IntToHEX := S;end;

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(RgEIP); end;
{*}{01}Procedure OpMOVrv;begin RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RgEIP+2);Inc(RgEIP,6);end;
{*}{02}Procedure OpMOVrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{*}{03}Procedure OpMOVrm;begin RegsDW[RAM[RgEIP+1]]:=ReadDWord((ReadDWord(RgEIP+2)));Inc(RgEIP,6);end;
{*}{04}Procedure OpMOVrmr;begin RegsDW[RAM[(RgEIP+1)]]:=ReadDWord(RegsDW[RAM[(RgEIP+2)]]);Inc(RgEIP,2);end;
{*}{05}Procedure OpMOVmr;begin WriteDWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);Inc(RgEIP,6);end;
{*}{06}Procedure OpMOVmrr;begin WriteDWord(ReadDWord(RegsDW[RAM[(RgEIP+1)]]),RegsDW[RAM[(RgEIP+2)]]);Inc(RgEIP,2);end;
{*}{07}Procedure OpMOV2rm;begin RegsDW[RAM[RgEIP+1]]:=ReadWord((ReadDWord(RgEIP+2)));Inc(RgEIP,6);end;
{*}{08}Procedure OpMOV2mr;begin WriteWord((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);Inc(RgEIP,6);end;
{*}{09}Procedure OpMOV1rm;begin RegsDW[RAM[RgEIP+1]]:=ReadByte((ReadDWord(RgEIP+2)));Inc(RgEIP,6);end;
{*}{0A}Procedure OpMOV1mr;begin WriteByte((ReadDWord(RgEIP+1)),RegsDW[RAM[RgEIP+5]]);Inc(RgEIP,6);end;

{*}{0B}Procedure OpCALLadr;begin Dec(ESP_);RAMc[ESP_]:=(RgEIP+5);RgEIP:=ReadDWord(RgEIP+1);end;
{*}{0C}Procedure OpCALLreg;begin  Dec(ESP_);RAMc[ESP_]:=(RgEIP+2);RgEIP:=RegsDW[RAM[(RgEIP+1)]];end;
{*}{0D}Procedure OpRET;begin RgEIP:=RAMc[ESP_];inc(ESP_);end;
{*}{0E}Procedure OpGOTOadr;begin RgEIP:=ReadDWord(RgEIP+1);end;
{*}{0F}Procedure OpGOTOreg;begin RgEIP:=RegsDW[RAM[RgEIP+1]];end;

{10}Procedure OpGOTOadrIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{11}Procedure OpGOTOadrNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{12}Procedure OpGOTOadrMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{13}Procedure OpGOTOadrLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RgEIP:=ReadDWord(RgEIP+1)else Inc(RgEIP,5);end;
{14}Procedure OpGOTOregIs;begin If RegsDW[idCMP1]=RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;
{15}Procedure OpGOTOregNotIs;begin If RegsDW[idCMP1]<>RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;
{16}Procedure OpGOTOregMoreIs;begin If RegsDW[idCMP1]>=RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;
{17}Procedure OpGOTOregLess;begin If RegsDW[idCMP1]<RegsDW[idCMP2] then RgEIP:=RegsDW[RAM[(RgEIP+1)]]else Inc(RgEIP,2);end;

{18}Procedure OpPUSHreg;begin Dec(ESP_);RAMc[ESP_]:=RegsDW[RAM[(RgEIP+1)]];Inc(RgEIP,2);end;
{19}Procedure OpPOPreg;begin RegsDW[RAM[(RgEIP+1)]]:=RAMc[ESP_];inc(ESP_);Inc(RgEIP,2);end;

{1A}Procedure OpPUSHregAH;var c1:OptByte;begin Dec(ESP_,8);for c1:=0 to 7 do RAMc[ESP_+c1]:=RegsDW[c1];Inc(RgEIP,1);end;
{1B}Procedure OpPOPregAH;var c1:OptByte;begin for c1:=0 to 7 do RegsDW[c1]:=RAMc[ESP_+c1];inc(ESP_,8);Inc(RgEIP,1);end;
{1С}
{1D}
{1E}
{1F}
{20}Procedure OpADDrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]]+RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{21}Procedure OpSUBrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]]-RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{22}Procedure OpMULrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]]*RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{23}Procedure OpDIVrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] div RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{24}Procedure OpMODrr;begin if RegsDW[RAM[RgEIP+2]]<>0 then RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] mod
RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{25}Procedure OpINCrr;begin Inc(RegsDW[RAM[RgEIP+1]]);Inc(RgEIP,2);end;
{26}Procedure OpDECrr;begin Dec(RegsDW[RAM[RgEIP+1]]);Inc(RgEIP,2);end;
{27}Procedure OpANDrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] and RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{28}Procedure OpORrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] or RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{29}Procedure OpXORrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] xor RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{2A}Procedure OpNOTrr;begin RegsDW[RAM[RgEIP+1]]:=not RegsDW[RAM[RgEIP+1]];Inc(RgEIP,2);end;
{2B}Procedure OpSHLrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] shl RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;
{2C}Procedure OpSHRrr;begin RegsDW[RAM[RgEIP+1]]:=RegsDW[RAM[RgEIP+1]] shr RegsDW[RAM[RgEIP+2]];Inc(RgEIP,3);end;

procedure InitCPU; var i:Integer; begin
ESP_:=cSizeOfRAMstak;
RgEIP:=0;
end;

Procedure ErrorOpCodeFound1;
var r:ShortString;
begin
Writeln('ErrorOpCodeFound1');
Writeln('eip_=',RgEIP,' ','esp_=',esp_);
Readln(r);   If r='q' then halt;
end;

procedure Test1;
var s,s1:string;
begin
case RAM[RgEIP] 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';
$1A:s:='OpPUSHregAH'; $1B:s:='OpPOPregAH';

$20:s:='OpADDrr';$21:s:='OpSUBrr';$22:s:='OpMULrr';$23:s:='OpDIVrr';
$24:s:='OpMODrr';$25:s:='OpINCrr';$26:s:='OpDECrr';$27:s:='OpANDrr';
$28:s:='OpORrr';$29:s:='OpXORrr';$2A:s:='OpNOTrr';$2B:s:='OpSHLrr';
$2C:s:='OpSHRrr';

else s:='-----';
end;
s1:=
  'eip_='+IntToStr(RgEIP)+
'| esp_='+IntToStr(ESP_)+
'| RAMc[esp_]='+IntToStr(RAMc[ESP_])+
'| RAM[eip_]=$'+IntToHEX(RAM[RgEIP],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[RgEIP];
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;    $1A:OpPUSHregAH;$1B:OpPOPregAH;

$20:OpADDrr;$21:OpSUBrr;$22:OpMULrr;$23:OpDIVrr;
$24:OpMODrr;$25:OpINCrr;$26:OpDECrr;
$27:OpANDrr;$28:OpORrr;$29:OpXORrr;$2A:OpNOTrr;
$2B:OpSHLrr;$2C:OpSHRrr;

{NOP_ MOVrv MOVrr MOVrm MOVrmr MOVmr MOVmrr
MOV2rm MOV2mr MOV1rm MOV1mr CALLa CALLr
RET_ GOTOa GOTOr GOTOaIs GOTOaNotIs
GOTOaMoreIs GOTOaLess GOTOrIs
GOTOrNotIs GOTOrMoreIs GOTOrLess
PUSHr POPr PUSHrAH POPrAH
}

else ErrorOpCodeFound1;end;

Test2; until vAPM<>0; end;

procedure StartEngine;
begin
LoadBIN('BOOT.bin');
InitCPU;
{RegsDW[eip_]:=0;}
{ESP_:= SizeOf(RAMc);}   {стек}
Engine;
end;

end.

0

20

О, це вже прям ядро + runtime система 🔥
Зроблю тобі готовий набір EXT-функцій, максимально простий і в твоєму стилі.

👉 все через:

A = номер функції
B,C,D = аргументи
A = результат
🔥 OPCODE
{2D}Procedure OpEXT;
begin
  case RegsDW[idA] of
    0: ; // NOP
    1: ExtPrintInt;
    2: ExtPrintChar;
    3: ExtRandom;
    4: ExtMemRead;
    5: ExtMemWrite;
    6: ExtAbs;
    7: ExtPow2;
    8: ExtMin;
    9: ExtMax;
  end;
  Inc(RgEIP,1);
end;
🧠 PRINT

код:

Procedure ExtPrintInt;
begin
Writeln(RegsDW[idB]);
end;

Procedure ExtPrintChar;
begin
Write(Chr(RegsDW[idB] and $FF));
end;

🎲 RANDOM

код:

Procedure ExtRandom;
begin
RegsDW[idA] := Random(RegsDW[idB]);
end;

👉 перед цим бажано один раз:

Randomize;
🧠 MEMORY

код:

Procedure ExtMemRead;
begin
RegsDW[idA] := ReadDWord(RegsDW[idB]);
end;

Procedure ExtMemWrite;
begin
WriteDWord(RegsDW[idB], RegsDW[idC]);
end;

🧮 MATH

код:

Procedure ExtAbs;
begin
if RegsDW[idB] < 0 then
RegsDW[idA] := -RegsDW[idB]
else
RegsDW[idA] := RegsDW[idB];
end;

Procedure ExtPow2;
begin
RegsDW[idA] := RegsDW[idB] * RegsDW[idB];
end;

Procedure ExtMin;
begin
if RegsDW[idB] < RegsDW[idC] then
RegsDW[idA] := RegsDW[idB]
else
RegsDW[idA] := RegsDW[idC];
end;

Procedure ExtMax;
begin
if RegsDW[idB] > RegsDW[idC] then
RegsDW[idA] := RegsDW[idB]
else
RegsDW[idA] := RegsDW[idC];
end;

🚀 ПРИКЛАДИ ВИКОРИСТАННЯ
🔹 print число
MOV A,1
MOV B,123
EXT
🔹 random 0..99
MOV A,3
MOV B,100
EXT
🔹 читання пам’яті
MOV A,4
MOV B,1000
EXT

👉 результат в A

🔹 запис пам’яті
MOV A,5
MOV B,1000
MOV C,777
EXT
🔹 max
MOV A,9
MOV B,10
MOV C,20
EXT

👉 A = 20

💣 ПЛЮСИ ТВОЄЇ СХЕМИ

✔ мінімум opcode
✔ вся складність винесена в EXT
✔ легко розширюється
✔ можна додати хоч 100 функцій без зміни CPU

🔥 МОЖНА ДОБАВИТИ ДАЛІ

Якщо хочеш — я наступним кроком зроблю:

🔸 EXT_STRING (рядки)
🔸 EXT_FILE (файли)
🔸 EXT_TIME (час, таймер)
🔸 EXT_CONSOLE (позиція курсора, колір)

Ти зараз реально бу

0

Быстрый ответ

Напишите ваше сообщение и нажмите «Отправить»



Вы здесь » EnotVM » Тестовый форум » _EnotVM32(260318)