_EnotVM32(260318)
_EnotVM32(260318)
Сообщений 1 страница 10 из 21
Поделиться22026-03-31 16:53:50
Зрозумів 👍
Зробимо під Turbo Pascal: розбиваємо RAM на сегменти по **32767 байт** і виділяємо їх поки вистачає пам’яті.
Я зроблю:
* масив вказівників на сегменти
* процедуру виділення
* підрахунок скільки реально виділилось
---
код:
type
PRamSegment = ^TRamSegment;
TRamSegment = array[0..32766] of Byte; { 32767 байт }
const
MaxSegments = 1024; { максимум сегментів (можеш змінити) }
var
Segments: array[0..MaxSegments-1] of PRamSegment;
SegCount: Word;
procedure AllocRAM;
var
p: PRamSegment;
begin
SegCount := 0;
while SegCount < MaxSegments do
begin
GetMem(p, SizeOf(TRamSegment));
```
if p = nil then
Break;
Segments[SegCount] := p;
Inc(SegCount);
```
end;
end;
procedure FreeRAM;
var
i: Word;
begin
for i := 0 to SegCount - 1 do
FreeMem(Segments[i], SizeOf(TRamSegment));
SegCount := 0;
end;
{ приклад використання }
begin
AllocRAM;
WriteLn('Виділено сегментів: ', SegCount);
WriteLn('Всього байт: ', LongInt(SegCount) * 32767);
{ тут працюєш з пам’яттю }
FreeRAM;
end.
---
## 🔹 Пояснення коротко
* `TRamSegment` = 32767 байт (як ти хотів)
* `GetMem` виділяє поки система дає
* якщо пам’ять закінчилась → `p = nil` → стоп
* `Segments[i]` — доступ до кожного сегмента
---
## 🔥 Як звертатись до RAM
Наприклад:
код:
Segments[0]^[0] := 123;
Segments[5]^[100] := 45;
---
## 💡 Маленький апгрейд (рекомендую)
Можеш зробити функцію доступу як до єдиної RAM:
код:
function ReadByte(addr: LongInt): Byte;
var
seg, ofs: Word;
begin
seg := addr div 32767;
ofs := addr mod 32767;
ReadByte := Segments[seg]^[ofs];
end;
---
Як хочеш — можу далі:
* зробити **Read/Write 32-bit (Cardinal/LongInt)**
* або оптимізувати доступ під твій емулятор
Не забудь написати "дяка" 😉
Поделиться4Вчера 12:10:47
Ок, зробимо максимально прості й переносимі функції під Turbo Pascal 4 — без зайвих залежностей 👍
---
### 🔢 IntToStr (ціле → рядок)
код:
function IntToStr(N: Integer): 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;
---
### 🧾 HexToStr (ціле → HEX рядок)
код:
function HexToStr(N: Word): string;
const
HexChars: array[0..15] of Char = '0123456789ABCDEF';
var
S: string;
begin
S := '';
if N = 0 then
begin
HexToStr := '0';
Exit;
end;
while N > 0 do
begin
S := HexChars[N mod 16] + S;
N := N div 16;
end;
HexToStr := S;
end;
---
### 💡 Пояснення коротко
* `IntToStr`:
* працює з від’ємними числами
* будує рядок справа наліво
* `HexToStr`:
* використовує таблицю `0123456789ABCDEF`
* тип `Word` (0..65535) — якраз під TP4
---
### ⚡ Якщо хочеш покращення
Можу додати:
* фіксовану довжину (типу `00AF`)
* префікс `0x`
* 32-біт версію (під твій емулятор 🔥)
* або зробити це як модуль для твоєї VM
---
Не забудь написати "дяка"
Поделиться5Вчера 12:15:16
Ага, зрозумів — тобі треба не просто число → HEX, а з **двома параметрами** (число + довжина/формат). Зробимо нормально 👍
---
### 🧾 HexToStr з довжиною (другий параметр)
код:
function HexToStr(N: Word; Digits: Byte): string;
const
HexChars: array[0..15] of Char = '0123456789ABCDEF';
var
S: string;
begin
S := '';
repeat
S := HexChars[N mod 16] + S;
N := N div 16;
until (N = 0) and (Length(S) >= Digits);
{ доповнюємо нулями зліва }
while Length(S) < Digits do
S := '0' + S;
HexToStr := S;
end;
---
### 🔍 Як працює
* `N` — число
* `Digits` — скільки символів у HEX хочеш отримати
* якщо число коротше → додає нулі зліва
---
### 📌 Приклади
код:
HexToStr($A, 4) → 000A
HexToStr($123, 4) → 0123
HexToStr($FFFF, 4) → FFFF
HexToStr($1, 2) → 01
---
### ⚡ Якщо треба ще крутіше
Можу зробити:
* версію для `LongInt` (32-біт під твою VM 🔥)
* варіант з `0x` або `$` префіксом
* або навіть **швидку версію без div/mod (через біти)** — буде ближче до асемблера
---
Не забудь написати "дяка"
Поделиться6Вчера 12:24:50
Потрібен короткий але внятний опис цього модулю Української мовою
unit Crt;
interface
const
{ CRT modes } {КРТ режими}
BW40 = 0; { 40x25 B/W on Color Adapter }{40x25 b/w на кольоровому адаптері}
CO40 = 1; { 40x25 Color on Color Adapter }{40x25 Колір на кольоровому адаптері}
BW80 = 2; { 80x25 B/W on Color Adapter }{80x25 b/w на кольоровому адаптері}
CO80 = 3; { 80x25 Color on Color Adapter }{80x25 Колір на кольоровому адаптері}
Mono = 7; { 80x25 on Monochrome Adapter }{80x25 на монохромному адаптері}
Font8x8 = 256; { Add-in for ROM font }{Доповнення для шрифту ROM}
{ Mode constants for 3.0 compatibility }
{Константи режиму для 3,0 сумісності}
C40 = CO40;
C80 = CO80;
{ Foreground and background color constants }
{Константи кольорів переднього плану та фону}
Black = 0;
Blue = 1;
Green = 2;
Cyan = 3;
Red = 4;
Magenta = 5;
Brown = 6;
LightGray = 7;
{ Foreground color constants }
{Константи кольорів переднього плану}
DarkGray = 8;
LightBlue = 9;
LightGreen = 10;
LightCyan = 11;
LightRed = 12;
LightMagenta = 13;
Yellow = 14;
White = 15;
{ Add-in for blinking }
{Добавка для моргання}
Blink = 128;
var
CheckBreak: Boolean; { Enable Ctrl-Break }{Увімкнути Ctrl-Break}
CheckEOF: Boolean; { Enable Ctrl-Z }{Увімкнути ctrl-z}
DirectVideo: Boolean; { Enable direct video addressing }{Увімкнути пряму адресу відео}
CheckSnow: Boolean; { Enable snow filtering }{Увімкнути снігову фільтрацію}
LastMode: Word; { Current text mode }{Поточний текстовий режим}
TextAttr: Byte; { Current text attribute }{Поточний атрибут тексту}
WindMin: Word; { Window upper left coordinates }{Вікно -Верхні координати}
WindMax: Word; { Window lower right coordinates }{Вікно нижнього правого координати}
SaveInt1B: Pointer; { Saved interrupt $1B }{Зберегти переривання $ 1b}
procedure AssignCrt(var F: Text);
function KeyPressed: Boolean;
function ReadKey: Char;
procedure TextMode(Mode: Word);
procedure Window(X1,Y1,X2,Y2: Byte);
procedure GotoXY(X,Y: Byte);
function WhereX: Byte;
function WhereY: Byte;
procedure ClrScr;
procedure ClrEol;
procedure InsLine;
procedure DelLine;
procedure TextColor(Color: Byte);
procedure TextBackground(Color: Byte);
procedure LowVideo;
procedure HighVideo;
procedure NormVideo;
procedure Delay(MS: Word);
procedure Sound(Hz: Word);
procedure NoSound;
implementation
procedure AssignCrt(var F: Text);begin end;
function KeyPressed: Boolean;begin end;
function ReadKey: Char;begin end;
procedure TextMode(Mode: Word);begin end;
procedure Window(X1,Y1,X2,Y2: Byte);begin end;
procedure GotoXY(X,Y: Byte);begin end;
function WhereX: Byte;begin end;
function WhereY: Byte;begin end;
procedure ClrScr;begin end;
procedure ClrEol;begin end;
procedure InsLine;begin end;
procedure DelLine;begin end;
procedure TextColor(Color: Byte);begin end;
procedure TextBackground(Color: Byte);begin end;
procedure LowVideo;begin end;
procedure HighVideo;begin end;
procedure NormVideo;begin end;
procedure Delay(MS: Word);begin end;
procedure Sound(Hz: Word);begin end;
procedure NoSound;begin end;
end.
Поделиться7Вчера 12:26:55
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;
як краще для RegsW та RegsB щоб absolute
чи
кожного разу = RegsDW[..] and $FFFF та = RegsDW[..] and $FF
?
Поделиться8Вчера 12:33:42
Ок, зроблю коротко і чітко по кожній функції/процедурі 👍
---
### 📘 Опис процедур і функцій модуля `Crt` (Turbo Pascal)
**AssignCrt(var F: Text)**
Прив’язує текстовий файл до консолі (екрану/клавіатури).
**KeyPressed: Boolean**
Перевіряє, чи натиснута клавіша (без очікування).
**ReadKey: Char**
Зчитує натиснуту клавішу (очікує, поки натиснуть).
**TextMode(Mode: Word)**
Встановлює текстовий режим екрана (40x25, 80x25 тощо).
**Window(X1,Y1,X2,Y2: Byte)**
Задає робочу область (вікно) на екрані.
**GotoXY(X,Y: Byte)**
Переміщує курсор у задану позицію.
**WhereX: Byte**
Повертає поточну позицію курсора по X (стовпець).
**WhereY: Byte**
Повертає поточну позицію курсора по Y (рядок).
**ClrScr**
Очищає весь екран.
**ClrEol**
Очищає рядок від курсора до кінця.
**InsLine**
Вставляє порожній рядок у поточній позиції.
**DelLine**
Видаляє поточний рядок.
**TextColor(Color: Byte)**
Встановлює колір тексту (символів).
**TextBackground(Color: Byte)**
Встановлює колір фону.
**LowVideo**
Встановлює тьмяний (низької яскравості) текст.
**HighVideo**
Встановлює яскравий текст.
**NormVideo**
Повертає стандартні атрибути тексту.
**Delay(MS: Word)**
Затримка виконання на задану кількість мілісекунд.
**Sound(Hz: Word)**
Вмикає звук заданої частоти (в Гц).
**NoSound**
Вимикає звук.
---
Якщо хочеш — можу зробити ще:
* версію як **коментарі прямо в коді**
* або розширений варіант (з нюансами типу extended-клавіш, BIOS і т.д.)
Не забудь написати "дяка"
Поделиться9Вчера 12:35:17
Ок, роблю розширений варіант з нюансами — але без «води», щоб реально було корисно для твоїх задач 👍
---
### 📘 Розширений опис `Crt` (Turbo Pascal)
---
**AssignCrt(var F: Text)**
Прив’язує текстовий файл до консолі (CRT).
🔹 Використовується для перенаправлення `Input/Output`
🔹 Працює через DOS/BIOS стандартні дескриптори
---
**KeyPressed: Boolean**
Перевіряє, чи є клавіша в буфері клавіатури.
🔹 Не блокує виконання
🔹 Читає буфер BIOS клавіатури (INT 16h)
🔹 Корисно для ігор/циклів
---
**ReadKey: Char**
Зчитує клавішу з буфера.
🔹 Якщо звичайна клавіша → повертає символ
🔹 Якщо extended-клавіша →
* перший виклик → #0
* другий виклик → scan-код
📌 Приклад:
* Стрілка вгору → `#0` + `72`
* F1 → `#0` + `59`
🔹 Працює через BIOS (INT 16h)
🔹 Не використовує стандартний `ReadLn`
---
**TextMode(Mode: Word)**
Встановлює відеорежим.
🔹 Викликає BIOS (INT 10h)
🔹 Очищає екран
🔹 Скидає позицію курсора
🔹 `Font8x8` → перемикає шрифт (EGA/VGA)
---
**Window(X1,Y1,X2,Y2: Byte)**
Обмежує область виводу.
🔹 Усі операції (`Write`, `ClrScr` і т.д.) діють тільки в межах
🔹 Координати 1-based
---
**GotoXY(X,Y: Byte)**
Переміщує курсор у вікні.
🔹 Через BIOS або прямий доступ до відео
🔹 Враховує `Window`
---
**WhereX / WhereY**
Повертає позицію курсора.
🔹 Не звертається до BIOS кожен раз — часто кешується
---
**ClrScr**
Очищає поточне вікно.
🔹 Заповнює пробілами з поточним атрибутом
🔹 Може працювати через відеопам’ять (швидше)
---
**ClrEol**
Очищає від курсора до кінця рядка.
🔹 Не чіпає попередні символи
---
**InsLine**
Вставляє рядок у позиції курсора.
🔹 Рядки нижче зсуваються вниз
🔹 Нижній рядок втрачається
---
**DelLine**
Видаляє поточний рядок.
🔹 Рядки нижче піднімаються вверх
---
**TextColor(Color: Byte)**
Встановлює колір тексту (0..15).
🔹 Впливає на молодші 4 біти атрибуту
---
**TextBackground(Color: Byte)**
Встановлює фон (0..7 + Blink).
🔹 Старші біти атрибуту
---
**LowVideo**
Вимикає яскравість (Intensity bit = 0)
---
**HighVideo**
Вмикає яскравість (Intensity bit = 1)
---
**NormVideo**
Встановлює стандартний атрибут (зазвичай LightGray на Black)
---
**Delay(MS: Word)**
Затримка у мілісекундах.
🔹 Використовує таймер BIOS (INT 1Ah або порт 40h)
🔹 Не дуже точний (залежить від CPU)
---
**Sound(Hz: Word)**
Вмикає звук через PC Speaker.
🔹 Програмує таймер 8253 (порт 43h/42h)
🔹 Частота = ~1193180 / Hz
---
**NoSound**
Вимикає PC Speaker
---
### ⚙️ Важливі нюанси
**DirectVideo: Boolean**
* TRUE → запис напряму в відеопам’ять (B800)
* FALSE → через BIOS
👉 TRUE швидше, але може “глючити” на деяких адаптерах
---
**CheckSnow: Boolean**
* Фікс “снігу” на старих CGA
👉 майже не актуально зараз
---
**CheckBreak / CheckEOF**
* Ctrl-Break / Ctrl-Z обробка
👉 важливо для DOS-програм
---
**Відеопам’ять**
* Текстовий режим: сегмент $B800 (color) або $B000 (mono)
* Символ = 2 байти (код + атрибут)
---
### 🔥 Висновок
`Crt` — це суміш:
* BIOS (INT 10h, 16h)
* прямого доступу до пам’яті
* DOS поведінки
👉 Саме тому він швидкий і зручний для ігор, утиліт і твоєї VM 😎
---
Якщо хочеш — можу:
* показати **як самому реалізувати Crt-подібний модуль** (дуже корисно для емулятора)
* або зробити **повністю свою версію без BIOS** 🔥
Не забудь написати "дяка"
Поделиться10Вчера 14:19:38
Ану глянь
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) and (b4[2]<>0) and (b4[3]<>0) then begin
S:=HexChars[(b4[1] div 16)]+S;S:=HexChars[(b4[1] mod 16)]+S;end;
if (b4[2]<>0) and (b4[3]<>0) then begin
S:=HexChars[(b4[2] div 16)]+S;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:OptInt32;
begin vAPM:=0; Test2;
repeat
{Optable[RAM[RegsDW[ideip_]]]();}
case RAM[RegsDW[ideip_]] 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.