Вихідний код оброблений https://chat.qwen.ai EnotVM32, Turbo Pascal 4.0, Version=1 ( Тема на форумі http://enotvm.frmbb.ru/viewtopic.php?id=31) uTpDt.pas: {Обробка вихідного коду від https://chat.qwen.ai} unit uTpDt; { Модуль типів та даних } interface type { Базові цілочисельні типи } Int8 = Shortint; { -128..127, signed 8-bit } Int16 = Integer; { Smallint -32768..32767, signed 16-bit } Int32 = Longint; { -2147483648..2147483647, signed 32-bit } { Типи, які будуть оптимізуватися } OptByte = Word; OptWord = Word; OptInt8 = Int16; OptInt16= Int16; OptInt32= Int32; ShortString = string[255]; const { 232-239: EXTR вхідні дані } idYA = 232; idYB = 233; idYC = 234; idYD = 235; idYE = 236; idYF = 237; idYG = 238; idYH = 239; { 240-247: EXTR вихідні дані } idZA = 240; idZB = 241; idZC = 242; idZD = 243; idZE = 244; idZF = 245; idZG = 246; idZH = 247; { 248-255: Резерв } idCMP1 = 254; idCMP2 = 255; const { Середовище компіляції EnotVM } { 1 = Turbo Pascal Version 4.0 Copyright (c) 1987 Borland International } cEnotVMItIsCompiled = 1; const cVersionEnotVM = 1; { EXTR 5 } cTypeOfAmbience = 1; { повертає ZA = 1 - 16бит; ZA = 2 - 32бит. EXTR 11 } cSizeOfRAMstack = 255; { EXTR 13 } cSizeOfRAM = 49151; { EXTR 14. 48 КБ = 49152 байт, індекси від 0 до 49151 } var RAM: array[0..cSizeOfRAM] of Byte; RAMc: array[0..cSizeOfRAMstack] of Int32; RgESP: Int32; RegsDW: array[0..255] of Int32; RgEIPMain: OptInt16; const cSizeOfRAMext = 49151; { EXTR 15. 48 КБ = 49152 байт, індекси від 0 до 49151 } cMaxPagesOfRAMext= 10; { EXTR 16. Кількість сторінок, від 0 до ... } type { Одна сторінка розширеної пам'яті } TExtPage = array[0..cSizeOfRAMext] of Byte; PExtPage = ^TExtPage; var { Розширена пам'ять — масив покажчиків } ExtRAMPages: array[0..cMaxPagesOfRAMext] of PExtPage; pSTOPEngine: OptByte; { 1 = EndProgram, 2 = ErrorOpCode, 3 = APM. EXTR 12 = APM } implementation end. uString.pas: {Обробка вихідного коду від https://chat.qwen.ai} unit uString; { Модуль, в якому обробляються рядки, а також ввід та вивід на екран (write/writeln, Read/Readln) } interface uses uTpDt; procedure pWriteStr; procedure pWritelnStr; implementation procedure CheckTypeFormat(Addr: OptWord; var TypeF: OptByte; var FullSize: OptWord; var CurSize: OptWord; var BeginAddrDate: OptWord; var EndAddrDate: OptWord); { 16bit } begin TypeF := RAM[Addr]; case TypeF of 1: begin FullSize := RAM[Addr+1]; CurSize := RAM[Addr+2]; BeginAddrDate := Addr+3; end; 2: begin FullSize := (RAM[Addr+1] + (RAM[Addr+2] shl 8)); CurSize := (RAM[Addr+3] + (RAM[Addr+4] shl 8)); BeginAddrDate := Addr+5; end; 3: begin FullSize := (RAM[Addr+1] + (RAM[Addr+2] shl 8)); CurSize := (RAM[Addr+4] + (RAM[Addr+5] shl 8)); BeginAddrDate := Addr+7; end; 4: begin FullSize := (RAM[Addr+1] + (RAM[Addr+2] shl 8)); CurSize := (RAM[Addr+5] + (RAM[Addr+6] shl 8)); BeginAddrDate := Addr+9; end; end; EndAddrDate := BeginAddrDate + CurSize - 1; end; procedure CheckTypeFormat2(Addr: OptWord; var BeginAddrDate: OptWord; var EndAddrDate: OptWord); { 16bit } var TypeF: OptByte; FullSize: OptWord; CurSize: OptWord; begin TypeF := RAM[Addr]; case TypeF of 1: begin FullSize := RAM[Addr+1]; CurSize := RAM[Addr+2]; BeginAddrDate := Addr+3; end; 2: begin FullSize := (RAM[Addr+1] + (RAM[Addr+2] shl 8)); CurSize := (RAM[Addr+3] + (RAM[Addr+4] shl 8)); BeginAddrDate := Addr+5; end; 3: begin FullSize := (RAM[Addr+1] + (RAM[Addr+2] shl 8)); CurSize := (RAM[Addr+4] + (RAM[Addr+5] shl 8)); BeginAddrDate := Addr+7; end; 4: begin FullSize := (RAM[Addr+1] + (RAM[Addr+2] shl 8)); CurSize := (RAM[Addr+5] + (RAM[Addr+6] shl 8)); BeginAddrDate := Addr+9; end; end; EndAddrDate := BeginAddrDate + CurSize - 1; end; procedure pWriteStr; { EXTR 257 } var Strb1: string; SizeStrb1: OptWord; BeginAddrDate: OptWord; EndAddrDate: OptWord; begin Strb1 := ''; SizeStrb1 := 0; CheckTypeFormat2(RegsDW[idYA], BeginAddrDate, EndAddrDate); while BeginAddrDate <= EndAddrDate do begin if SizeStrb1 < 255 then begin Strb1 := Strb1 + chr(RAM[BeginAddrDate]); inc(SizeStrb1); inc(BeginAddrDate); end else begin Write(Strb1); Strb1 := ''; SizeStrb1 := 0; end; end; if SizeStrb1 <> 0 then Write(Strb1); end; procedure pWritelnStr; { EXTR 256 } var Strb1: string; SizeStrb1: OptWord; BeginAddrDate: OptWord; EndAddrDate: OptWord; begin Strb1 := ''; SizeStrb1 := 0; CheckTypeFormat2(RegsDW[idYA], BeginAddrDate, EndAddrDate); while BeginAddrDate <= EndAddrDate do begin if SizeStrb1 < 255 then begin Strb1 := Strb1 + chr(RAM[BeginAddrDate]); inc(SizeStrb1); inc(BeginAddrDate); end else begin Write(Strb1); Strb1 := ''; SizeStrb1 := 0; end; end; if SizeStrb1 <> 0 then Writeln(Strb1) else Writeln; end; end. uEmul0.pas: {Обробка вихідного коду від https://chat.qwen.ai} unit uEmul0; interface uses Dos, uTpDt; procedure LoadBIN(FileName: ShortString); procedure InitCPU; function IntToStr(N: Int32): ShortString; function IntToHEX(N: Int32; Digits: OptByte): ShortString; procedure pWriteln_GetTimeStr; { EXTR 3 } procedure pCONT; { EXTR 7 } procedure pWritelnYA; { EXTR 8 } procedure pWait00secTime_and_Writeln_GetTimeStr; { EXTR 9 } procedure pEndProgram; { EXTR 10 } { Extr RAM } procedure InitExtRAM; procedure CopyMainToExt(MainBeginAddr: OptWord; Count: OptWord; PageNum, ExtBeginAddr: OptWord); procedure CopyExtToMain(PageNum, ExtBeginAddr: OptWord; Count: OptWord; MainBeginAddr: OptWord); procedure CopyExtToExt(PageNum1, Ext1BeginAddr: OptWord; Count: OptWord; PageNum2, Ext2BeginAddr: OptWord); procedure CopyMainToMain(MainSrcAddr: OptWord; Count: OptWord; MainDstAddr: OptWord); implementation procedure LoadBIN(FileName: ShortString); var f: file; size: OptInt32; begin Assign(f, FileName); Reset(f, 1); size := FileSize(f); if size > SizeOf(RAM) then size := SizeOf(RAM); BlockRead(f, RAM, size); Close(f); end; procedure InitCPU; begin RgESP := cSizeOfRAMstack; RgEIPMain := 0; end; function IntToStr(N: Int32): ShortString; 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: OptByte): ShortString; 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 pWriteln_GetTimeStr; { EXTR 3 } var Hour, Minute, Second, Sec100: Word; begin GetTime(Hour, Minute, Second, Sec100); Writeln(Hour, ':', Minute, ':', Second, '.', Sec100); end; procedure pCONT; { EXTR 7 } var wrems: string; begin Repeat Writeln('Will Enter ', #39, 'cont', #39, ' or ', #39, 'CONT', #39, ' for continue'); Readln(wrems); until (wrems = 'cont') or (wrems = 'CONT'); end; procedure pWritelnYA; { EXTR 8 } begin Writeln(IntToStr(RegsDW[idYA]) + ' ($' + IntToHEX(RegsDW[idYA], 8) + ')'); end; procedure pWait00secTime_and_Writeln_GetTimeStr; { EXTR 9 } var Hour, Minute, Second, Sec100: Word; begin Writeln('Wait Time 00 Sec'); Repeat GetTime(Hour, Minute, Second, Sec100); until Second = 0; Writeln(Hour, ':', Minute, ':', Second, '.', Sec100); end; procedure pEndProgram; { EXTR 10 } begin pSTOPEngine := 1; { pEndProgram } end; { Extr RAM } procedure InitExtRAM; var i: OptInt16; begin for i := 0 to cMaxPagesOfRAMext do begin New(ExtRAMPages[i]); FillChar(ExtRAMPages[i]^, SizeOf(TExtPage), 0); end; end; procedure CopyMainToExt(MainBeginAddr: OptWord; Count: OptWord; PageNum, ExtBeginAddr: OptWord); begin Move(RAM[MainBeginAddr], ExtRAMPages[PageNum]^[ExtBeginAddr], Count); end; procedure CopyExtToMain(PageNum, ExtBeginAddr: OptWord; Count: OptWord; MainBeginAddr: OptWord); begin Move(ExtRAMPages[PageNum]^[ExtBeginAddr], RAM[MainBeginAddr], Count); end; procedure CopyExtToExt(PageNum1, Ext1BeginAddr: OptWord; Count: OptWord; PageNum2, Ext2BeginAddr: OptWord); begin Move(ExtRAMPages[PageNum1]^[Ext1BeginAddr], ExtRAMPages[PageNum2]^[Ext2BeginAddr], Count); end; procedure CopyMainToMain(MainSrcAddr: OptWord; Count: OptWord; MainDstAddr: OptWord); begin Move(RAM[MainSrcAddr], RAM[MainDstAddr], Count); end; end. uEmul.pas: {Обробка вихідного коду від https://chat.qwen.ai} unit uEmul; interface uses Dos, uEmul0, uString, uTpDt; procedure StartEngine; implementation procedure Engine16bitB4; var RgEIP: OptInt16; tmp1, tmp2: OptByte; Adr1, Adr2: OptInt16; V1: OptInt32; begin pSTOPEngine := 0; RgEIP := RgEIPMain; repeat tmp1 := RAM[RgEIP]; case tmp1 of $00: { NOP } begin Inc(RgEIP); end; $01: { MOVrv: mov Rg32, V } begin Adr1 := RgEIP + 2; RegsDW[RAM[(RgEIP+1)]] := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8) or (OptInt32(RAM[Adr1+2]) shl 16) or (OptInt32(RAM[Adr1+3]) shl 24); Inc(RgEIP, 6); end; $02: { MOVrr: mov Rg32, Rg32 } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $03: { MOVrm: mov Rg32, [DWA1] } begin Adr1 := RgEIP + 2; Adr2 := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8); RegsDW[RAM[RgEIP+1]] := OptInt32(RAM[Adr2]) or (OptInt32(RAM[Adr2+1]) shl 8) or (OptInt32(RAM[Adr2+2]) shl 16) or (OptInt32(RAM[Adr2+3]) shl 24); Inc(RgEIP, 6); end; $04: { MOVrmr: mov Rg32, [Rg32] } begin Adr1 := RegsDW[RAM[(RgEIP+2)]]; RegsDW[RAM[(RgEIP+1)]] := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8) or (OptInt32(RAM[Adr1+2]) shl 16) or (OptInt32(RAM[Adr1+3]) shl 24); Inc(RgEIP, 3); end; $05: { MOVmr: mov [DWA1], Rg32 } begin Adr1 := RgEIP + 1; Adr2 := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8); V1 := RegsDW[RAM[RgEIP+5]]; RAM[Adr2] := Byte(V1); RAM[Adr2+1] := Byte(V1 shr 8); RAM[Adr2+2] := Byte(V1 shr 16); RAM[Adr2+3] := Byte(V1 shr 24); Inc(RgEIP, 6); end; $06: { MOVmrr: mov [Rg32], Rg32 } begin Adr1 := RegsDW[RAM[(RgEIP+1)]]; V1 := RegsDW[RAM[(RgEIP+2)]]; RAM[Adr1] := Byte(V1); RAM[Adr1+1] := Byte(V1 shr 8); RAM[Adr1+2] := Byte(V1 shr 16); RAM[Adr1+3] := Byte(V1 shr 24); Inc(RgEIP, 3); end; $07: { MOV2rm: mov Rg32, word [DWA1] } begin Adr1 := RgEIP + 2; RegsDW[RAM[RgEIP+1]] := RAM[Adr1] or (RAM[Adr1+1] shl 8); Inc(RgEIP, 6); end; $08: { MOV2mr: mov [DWA1], word Rg32 } begin Adr1 := RgEIP + 1; Adr2 := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8); V1 := RegsDW[RAM[RgEIP+5]]; RAM[Adr2] := Byte(V1); RAM[Adr2+1] := Byte(V1 shr 8); Inc(RgEIP, 6); end; $09: { MOV1rm: mov Rg32, byte [DWA1] } begin Adr1 := RgEIP + 2; Adr2 := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8); RegsDW[RAM[RgEIP+1]] := RAM[Adr2]; Inc(RgEIP, 6); end; $0A: { MOV1mr: mov [DWA1], byte Rg32 } begin Adr1 := RgEIP + 1; Adr2 := OptInt32(RAM[Adr1]) or (OptInt32(RAM[Adr1+1]) shl 8); RAM[Adr2] := RegsDW[RAM[RgEIP+5]]; Inc(RgEIP, 6); end; $0B: { CALLa DWA1 } begin Dec(RgESP); RAMc[RgESP] := (RgEIP + 5); RgEIP := OptInt32(RAM[(RgEIP+1)]) or (OptInt32(RAM[(RgEIP+2)]) shl 8); end; $0C: { CALLr Rg32 } begin Dec(RgESP); RAMc[RgESP] := (RgEIP + 2); RgEIP := RegsDW[RAM[(RgEIP+1)]]; end; $0D: { RET } begin RgEIP := RAMc[RgESP]; inc(RgESP); end; $0E: { GOTOa } begin RgEIP := OptInt32(RAM[(RgEIP+1)]) or (OptInt32(RAM[(RgEIP+2)]) shl 8); end; $0F: { GOTOr } begin RgEIP := RegsDW[RAM[RgEIP+1]]; end; $10: { GOTOsaIs } begin if RegsDW[idCMP1] = RegsDW[idCMP2] then RgEIP := OptInt32(RAM[(RgEIP+1)]) or (OptInt32(RAM[(RgEIP+2)]) shl 8) else Inc(RgEIP, 5); end; $11: { GOTOsaNotIs } begin if RegsDW[idCMP1] <> RegsDW[idCMP2] then RgEIP := OptInt32(RAM[(RgEIP+1)]) or (OptInt32(RAM[(RgEIP+2)]) shl 8) else Inc(RgEIP, 5); end; $12: { GOTOsaMoreIs } begin if RegsDW[idCMP1] >= RegsDW[idCMP2] then RgEIP := OptInt32(RAM[(RgEIP+1)]) or (OptInt32(RAM[(RgEIP+2)]) shl 8) else Inc(RgEIP, 5); end; $13: { GOTOsaLess } begin if RegsDW[idCMP1] < RegsDW[idCMP2] then RgEIP := OptInt32(RAM[(RgEIP+1)]) or (OptInt32(RAM[(RgEIP+2)]) shl 8) else Inc(RgEIP, 5); end; $14: { GOTOsrIs } begin if RegsDW[idCMP1] = RegsDW[idCMP2] then RgEIP := RegsDW[RAM[(RgEIP+1)]] else Inc(RgEIP, 2); end; $15: { GOTOsrNotIs } begin if RegsDW[idCMP1] <> RegsDW[idCMP2] then RgEIP := RegsDW[RAM[(RgEIP+1)]] else Inc(RgEIP, 2); end; $16: { GOTOsrMoreIs } begin if RegsDW[idCMP1] >= RegsDW[idCMP2] then RgEIP := RegsDW[RAM[(RgEIP+1)]] else Inc(RgEIP, 2); end; $17: { GOTOsrLess } begin if RegsDW[idCMP1] < RegsDW[idCMP2] then RgEIP := RegsDW[RAM[(RgEIP+1)]] else Inc(RgEIP, 2); end; $18: { PUSHr } begin Dec(RgESP); RAMc[RgESP] := RegsDW[RAM[(RgEIP+1)]]; Inc(RgEIP, 2); end; $19: { POPr } begin RegsDW[RAM[(RgEIP+1)]] := RAMc[RgESP]; inc(RgESP); Inc(RgEIP, 2); end; $1A: { PUSHrsvr (кілька регістрів) } begin Adr1 := RAM[RgEIP+1]; tmp2 := RAM[RgEIP+2] - Adr1; Dec(RgESP, tmp2 + 1); for tmp1 := 0 to tmp2 do RAMc[RgESP+tmp1] := RegsDW[Adr1+tmp1]; Inc(RgEIP, 3); end; $1B: { POPrsvr (кілька регістрів) } begin Adr1 := RAM[RgEIP+1]; tmp2 := RAM[RgEIP+2] - Adr1; for tmp1 := 0 to tmp2 do RegsDW[Adr1+tmp1] := RAMc[RgESP+tmp1]; inc(RgESP, tmp2 + 1); Inc(RgEIP, 3); end; $1C: { ADDrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] + RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $1D: { SUBrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] - RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $1E: { MULrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] * RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $1F: { DIVrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] div RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $20: { MODrr } begin RegsDW[RAM[RgEIP+1]] := (RegsDW[RAM[RgEIP+1]] mod RegsDW[RAM[RgEIP+2]]); Inc(RgEIP, 3); end; $21: { INCr } begin Inc(RegsDW[RAM[RgEIP+1]]); Inc(RgEIP, 2); end; $22: { DECr } begin Dec(RegsDW[RAM[RgEIP+1]]); Inc(RgEIP, 2); end; $23: { ANDrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] and RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $24: { ORrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] or RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $25: { XORrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] xor RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $26: { NOTr } begin RegsDW[RAM[RgEIP+1]] := not RegsDW[RAM[RgEIP+1]]; Inc(RgEIP, 2); end; $27: { SHLrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] shl RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $28: { SHRrr } begin RegsDW[RAM[RgEIP+1]] := RegsDW[RAM[RgEIP+1]] shr RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; $29: { CMPrr } begin RegsDW[idCMP1] := RegsDW[RAM[RgEIP+1]]; RegsDW[idCMP2] := RegsDW[RAM[RgEIP+2]]; Inc(RgEIP, 3); end; { $2A: OpEXTR; Початок } $2A: begin { 232-239: EXTR вхідні дані } { idYA=232; idYB=233; idYC=234; idYD=235; idYE=236; idYF=237; idYG=238; idYH=239; } { EXTR вихідні дані: idZA=240; idZB=241; idZC=242; idZD=243; idZE=244; idZF=245; idZG=246; idZH=247 } Adr1 := RAM[RgEIP+1]; Adr2 := RAM[RgEIP+2]; Inc(RgEIP, 3); case Adr2 of 0: { 0-255: Процедури для тестів емулятору та інше } case Adr1 of 0: { EXTR_NOP } begin end; 1: { CheckEXTR } begin RegsDW[idZA] := 0; case RegsDW[idYA] of 0..16, 256..257, 512..515, 768..771: RegsDW[idZA] := 1; end; end; 2: { HALT_ } HALT(RegsDW[idYA]); 3: { Writeln_GetTimeStr } pWriteln_GetTimeStr; 4: { Readln0 } Readln; 5: { VersionEnotVM } RegsDW[idZA] := cVersionEnotVM; 6: { Writeln0 } Writeln; 7: { CONT } pCONT; 8: { WritelnYA } pWritelnYA; 9: { Wait00secTime_and_Writeln_GetTimeStr } pWait00secTime_and_Writeln_GetTimeStr; 10: { EndProgram } pEndProgram; 11: { TypeOfAmbience } RegsDW[idZA] := cTypeOfAmbience; 12: { APM } pSTOPEngine := 3; 13: { SizeOfRAMstack } RegsDW[idZA] := cSizeOfRAMstack; 14: { SizeOfRAM } RegsDW[idZA] := cSizeOfRAM; 15: { SizeOfRAMext } RegsDW[idZA] := cSizeOfRAMext; 16: { MaxPagesOfRAMext } RegsDW[idZA] := cMaxPagesOfRAMext; 17: RegsDW[idZA] := cEnotVMItIsCompiled; end; 1: { 256-511: STRING } case Adr1 of 0: { 256: WritelnStr } pWritelnStr; 1: { 257: WriteStr } pWriteStr; end; 2: { 512-767: ExtrRAM } case Adr1 of 0: { 512: CopyMainToMain } Move(RAM[RegsDW[idYC]], RAM[RegsDW[idYE]], RegsDW[idYB]); 1: { 513: CopyMainToExt } Move(RAM[RegsDW[idYC]], ExtRAMPages[RegsDW[idYF]]^[RegsDW[idYE]], RegsDW[idYB]); 2: { 514: CopyExtToMain } Move(ExtRAMPages[RegsDW[idYD]]^[RegsDW[idYC]], RAM[RegsDW[idYE]], RegsDW[idYB]); 3: { 515: CopyExtToExt } Move(ExtRAMPages[RegsDW[idYD]]^[RegsDW[idYC]], ExtRAMPages[RegsDW[idYF]]^[RegsDW[idYE]], RegsDW[idYB]); end; 3: { 768-1023: GOTOu... } case Adr1 of 0: { 768: GOTOuaMoreIs } begin if (Word(RegsDW[idCMP1] shr 16) > Word(RegsDW[idCMP2] shr 16)) or ((Word(RegsDW[idCMP1] shr 16) = Word(RegsDW[idCMP2] shr 16)) and (Word(RegsDW[idCMP1] and $FFFF) >= Word(RegsDW[idCMP2] and $FFFF))) then RgEIP := OptInt32(RAM[(RgEIP)]) or (OptInt32(RAM[(RgEIP+1)]) shl 8) else Inc(RgEIP, 4); end; 1: { 769: GOTOuaLess } begin if (Word(RegsDW[idCMP1] shr 16) < Word(RegsDW[idCMP2] shr 16)) or ((Word(RegsDW[idCMP1] shr 16) = Word(RegsDW[idCMP2] shr 16)) and (Word(RegsDW[idCMP1] and $FFFF) < Word(RegsDW[idCMP2] and $FFFF))) then RgEIP := OptInt32(RAM[(RgEIP)]) or (OptInt32(RAM[(RgEIP+1)]) shl 8) else Inc(RgEIP, 4); end; 2: { 770: GOTOurMoreIs } begin if (Word(RegsDW[idCMP1] shr 16) > Word(RegsDW[idCMP2] shr 16)) or ((Word(RegsDW[idCMP1] shr 16) = Word(RegsDW[idCMP2] shr 16)) and (Word(RegsDW[idCMP1] and $FFFF) >= Word(RegsDW[idCMP2] and $FFFF))) then RgEIP := RegsDW[RAM[(RgEIP)]] else Inc(RgEIP, 1); end; 3: { 771: GOTOurLess } begin if (Word(RegsDW[idCMP1] shr 16) < Word(RegsDW[idCMP2] shr 16)) or ((Word(RegsDW[idCMP1] shr 16) = Word(RegsDW[idCMP2] shr 16)) and (Word(RegsDW[idCMP1] and $FFFF) < Word(RegsDW[idCMP2] and $FFFF))) then RgEIP := RegsDW[RAM[(RgEIP)]] else Inc(RgEIP, 1); end; end; end; end; { OpEXTR; Кінець } $2B: { MOV2rmr: mov Rg32, word [Rg32] } begin Adr1 := RegsDW[RAM[(RgEIP+2)]]; RegsDW[RAM[(RgEIP+1)]] := (RAM[Adr1] or (RAM[Adr1+1] shl 8)); Inc(RgEIP, 3); end; $2C: { MOV2mrr: mov [Rg32], word Rg32 } begin Adr1 := RegsDW[RAM[(RgEIP+1)]]; V1 := RegsDW[RAM[(RgEIP+2)]]; RAM[Adr1] := Byte(V1); RAM[Adr1+1] := Byte(V1 shr 8); Inc(RgEIP, 3); end; $2D: { MOV1rmr: mov Rg32, byte [Rg32] } begin RegsDW[RAM[(RgEIP+1)]] := RAM[(RegsDW[RAM[(RgEIP+2)]])]; Inc(RgEIP, 3); end; $2E: { MOV1mrr: mov [Rg32], byte Rg32 } begin RAM[RegsDW[RAM[(RgEIP+1)]]] := RegsDW[RAM[(RgEIP+2)]]; Inc(RgEIP, 3); end; else pSTOPEngine := 2; { ErrorOpCode } end; until pSTOPEngine <> 0; { 1=EndProgram, 2=ErrorOpCode, 3=APM } RgEIPMain := RgEIP; end; procedure StartEngine; begin LoadBIN('BOOT.bin'); InitCPU; Engine16bitB4; end; end. uMain.pas: {Обробка вихідного коду від https://chat.qwen.ai} unit uMain; interface uses uEmul, uEmul0; procedure InitProgram; procedure StartProgram; procedure FinalProgram; implementation procedure InitProgram; begin InitExtRAM; end; procedure FinalProgram; begin end; procedure StartProgram; begin StartEngine; end; end. ENOTVM32.pas: {Обробка вихідного коду від https://chat.qwen.ai} Program ENOTVM32; uses Crt, uMain; begin InitProgram; StartProgram; FinalProgram; end.