Документація та опис від автору EnotVM32 "01 Загальний опис EnotVM32.txt": Загальний опис EnotVM32. Емулятор EnotVM32, задумувався, враховуючи ряд факторів, які я може й не всі й пригадаю. :-) Але основні все таки спробую. Це: * Мінімальний набір команд процесору EnotVM32, який може бути легко перенесений на інші платформи та середовища розробки. * Щоб була схожість команд EnotVM32 на АСМ32, також для можливого відносно легкого перенесення коду з АСМ32 на EnotVM32, та навпаки. * Вихідний код емулятору доступний. * Використовувати можливості FASM, його макросів, для розробки програм для EnotVM32. Можливо й використовувати інші асемблери, окрім FASM. Тощо. Для написання програм для EnotVM32, використовуйте FASM та файл макросів Macros.asm, який описує ідентифікатори регістрів та макроси команд EnotVM32. Програма стартує з нульової адреси, при необхідності, це можна змінити в вихідному коді EnotVM32, але краще не треба. :-) Розмір оперативної пам'яті регулюється константою cSizeOfRAM. Розмір масиву стеку константою cSizeOfRAMstack. Що примітно, що розмір стеку вказується в 32 бітних даних, а не в байтах. І стек має окремий масив. Ну думаю, для загального опису цього достатньою. Тонкощі читайте в інших файлах документації по "EnotVM32". Особливу увагу зверніть на ось це: EnotVM32 є 32-бітним емулятором, але в 16-бітних середовищах, де немає сенсу для для 32-бітних переходів,EnotVM32 використовує лише частину адреси переходів, тобто 16-бітні переходи, для збереження швидкості емулятора. "02 Команди EnotVM32.txt": Опис, особливості та документація по командам віртуального процесору "EnotVM32". Регістрів 256. Назви регістрів дві літери від "AA" до "JV". Це так звані довгі назви регістрів. Ті назви регістрів, які не можуть бути використані, з-за того, що є зарезервовані FASM або іншим яким середовищем, до них додається "_" в кінці назви. В FASM наприклад, це AH_,AL_,AS_,AT_ і.д. дивіться в файлі Macros.asm. Існує також короткі назви регістрів для зручності. Від "A" до "Z", що відповідає довгій назві від "AA" до "AZ". Також існують регістри зарезервовані під інше. YA,YB,YC,YD,YE,YF,YG,YH, - зарезервовані для передачі даних при виклику EXTR (Системна інструкція для виклику розширень). ZA,ZB,ZC,ZD,ZE,ZF,ZG,ZH - Зарезервовані для повернення даних після виклику EXTR. CMP1,CMP2 - для використання їх в командах порівняння та переходів процесору "EnotVM32", таких як, GOTOsaIs, GOTOsaNotIs, GOTOsaMoreIs, GOTOsaLess, GOTOsrIs, GOTOsrNotIs, GOTOsrMoreIs, GOTOsrLess і т.д. Регістри зберігаються у вигляді масиву RegsDW:array[0..255] of Int32; (окрім RgESP та RgEIP) і тому у кожного регістра є цифровий ідентифікатор. Ідентифікатори регістрів, дивіться в Macros.asm. Також дивіться мнемоніку написання кожної команди, у вигляді макросів. Коротко A=0 до Z=25,CMP1=254,CMP2=255. В вихідних файлах ідентифікатори регістрів з додаванням "id" до регістру. В основному команди емулятору побудовані так, щоб усі операції, що тільки можливо, виконувались через 32-бітні регістри. Арифметичні операції виконуються як знакові (Int32) (Int32=Longint PAS|DELPHI). Логічні операції працюють на рівні бітів. Емулятор стартує з адреси 0, тобто при загрузці файлу, - RgEIP:=0. І програма починає робити. Довжина пам'яті налаштовується cSizeOfRAM. Для стеку є окремий масив RAMc:array[0..cSizeOfRAMstack] of Int32; його довжина налаштовується окремо cSizeOfRAMstack. При початку загрузки встановлюється RgESP:=cSizeOfRAMstack. Стек адресує елементи типу Int32 (4 байти). RgESP індексує елементи, а не байти. Регістри RgESP,RgEIP:Int32, недоступні, як звичайні регістри, тобто через команди типа MOV.Доступні вони будуть, через ($2A; EXTR). Опис команд самого процесору. Значення в опису команд. Rg1,Rg2 - ід-регістру відповідно "EnotVM32", (значення 0.255) V - числове 32 бітне значення -2147483648..2147483647 Rg32 - регістр аналог 32 бітного асемблеру (eax,ebx,ecx...) DWA - (DWord Adress), 32 бітна адреса Код десятичний; код шістнадцятирічний; Назва макросу (формат)в модулі Macros.asm який для FASM; довжина команди в байтах; аналог команди в FASM (можливо приблизний); опис команди. 00; $00; nop_; 1; nop; Пуста команда не виконує ніяких дій. ----------- команди MOV для 32 бітних регістрів. На відміну від асемблеру де робота з 32,16 та 8 бітними даними робиться, через одну команду MOV. В "EnotVM32", це робиться. окремими командами MOV..., MOV2..., MOV1 відповідно. 01; $01; MOVrv Rg1,V ; 6 ; mov Rg32,V ; Присвоює регістру Rg1 значення V. 02; $02; MOVrr Rg1,Rg2 ; 3 ; mov Rg32,Rg32 ; Присвоює регістру Rg1 значення регістру Rg2. 03; $03; MOVrm Rg1,DWA1 ; 6 ; mov Rg32,[DWA1] ; Присвоює регістру Rg1, значення, яке знаходиться по адресі DWA1. 04; $04; MOVrmr Rg1,Rg2 ; 3 ; mov Rg32,[Rg32] ; Присвоює регістру Rg1, значення, яке знаходиться по адресі регістру Rg2. 05; $05; MOVmr DWA1,Rg1 ; 6 ; mov [DWA1],Rg32 ; Присвоює пам'яті з адресою DWA1 значення, регістру Rg1. 06; $06; MOVmrr Rg1,Rg2 ; 3 ; mov [Rg32],Rg32 ; Присвоює пам'яті, з адресою в Rg1, значення, регістру Rg2. ----------- команди MOV для 16 бітних регістрів. 07; $07; MOV2rm Rg1,DWA1 ; 6 ; mov Rg32, word [DWA1]; Присвоює регістру Rg1, значення, яке знаходиться по адресі DWA1. 08; $08; MOV2mr DWA1,Rg1 ; 6 ; mov [DWA1], word Rg32; Присвоює пам'яті з адресою DWA1 значення, регістру Rg1. ----------- команди MOV для 8 бітних регістрів. 09; $09; MOV1rm Rg1,DWA1 ; 6 ; mov Rg32, byte [DWA1] ; Присвоює регістру Rg1, значення, яке знаходиться по адресі DWA1. 10; $0A; MOV1mr DWA1,Rg1 ; 6 ; mov [DWA1],byte Rg32 ; Присвоює пам'яті з адресою DWA1 значення, регістру Rg1. ----------- Команди викликів підпрограм та переходи. 11; $0B; CALLa DWA1 ; 5 ; CALL DWA1 ; Викликає підпрограму по адресі DWA1. 12; $0C; CALLr Rg1 ; 2 ; CALL Rg32 ; Викликає підпрограму по адресі, яка знаходиться в регістрі Rg1. 13; $0D; RET ; 1 ; RET ; Повертає з підпрограми. 14; $0E; GOTOa DWA1 ; 5 ; JMP DWA1 ; Безумовний перехід по адресі DWA1. 15; $0F; GOTOr Rg1 ; 2 ; JMP Rg1 ; Безумовний перехід по адресі, значення, якої в регістрі Rg1. ----------- Умовні переходи.ЗНАКОВІ. Умовні переходи порівнюють лише регістр CMP1 з регістром CMP2. Завантажувати дані регістри можна командами присвоєння регістрі MOV ($01 - $06) або однієї командою CMPrr {$29} можна завантажити відразу CMP1 та CMP2. Не забувайте данні порівняння знакові. Умовні переходи які роблять порівняння CMP1 та CMP2 та перехід. 16; $10; GOTOsaIs DWA1 ; 5 ;if ... then jump; Якщо CMP1=CMP2 то перехід, на адресу DWA1 17; $11; GOTOsaNotIs DWA1 ; 5 ; (дивись вище) ; Якщо CMP1<>CMP2 то перехід, на адресу DWA1 18; $12; GOTOsaMoreIs DWA1; 5 ; (дивись вище) ; Якщо CMP1>=CMP2 то перехід, на адресу DWA1 19; $13; GOTOsaLess DWA1 ; 5 ; (дивись вище) ; Якщо CMP1CMP2 то перехід, на адресу, яка вказана в Rg1 22; $16; GOTOsrMoreIs Rg1 ; 2 ; (дивись вище) ; Якщо CMP1>=CMP2 то перехід, на адресу, яка вказана в Rg1 23; $17; GOTOsrLess Rg1 ; 2 ; (дивись вище) ; Якщо CMP1 CMP2 then jump addr 12h if CMP1 >= CMP2 then jump addr 13h if CMP1 < CMP2 then jump addr 14h–17h — ті ж самі, але адреса в регістрі Стек. 18h PUSHr Rg1 push(Rg1) 19h POPr Rg1 Rg1 = pop() 1Ah PUSHrsvr Rg1,Rg2 push(Rg1..Rg2) 1Bh POPrsvr Rg1,Rg2 pop(Rg1..Rg2) Арифметика та логіка. Формат: Rg1 = (Rg1 op Rg2) | Opcode | Операція | | ------ | -------- | | 1C | ADD | | 1D | SUB | | 1E | MUL | | 1F | DIV | | 20 | MOD | | 21 | INC | | 22 | DEC | | 23 | AND | | 24 | OR | | 25 | XOR | | 26 | NOT | | 27 | SHL | | 28 | SHR | | ------ | -------- | CMP. 29h CMPrr Rg1, Rg2 CMP1 = Rg1; CMP2 = Rg2 Розширення. 2Ah EXTR Системна команда для виклику: * внутрішніх процедур * API емулятора * розширень (аналог BIOS / interrupt-подібного механізму) Особливості архітектури. * 256 регістрів * відсутність FLAGS (замість цього CMP1/CMP2) * явні розміри доступу до пам’яті (byte/word/dword) * стек працює з Int32 елементами * простий декодер команд (opcode + аргументи) Висновок. **EnotVM32** — це: * проста * швидка * добре контрольована VM-архітектура з елементами: * RISC (чіткі інструкції) * x86 (гнучкість доступу до пам’яті) "04 Документація по командам MOV від ChatGPT.txt": Документація по командам MOV від ChatGPT ( https://chatgpt.com/ ) Регістр < значення | Opcode | Формат | Опис | | ------ | ----------------- | ---------------------- | | 01 | `mov Rg32, imm32` | Завантаження константи | | 02 | `mov Rg32, Rg32` | Регістр < регістр | Регістр < пам’ять (за адресою) | Opcode | Формат | Опис | | ------ | ------------------------ | -------------------------- | | 03 | `mov Rg32, [imm32]` | Читання DWORD | | 07 | `mov Rg32, word [imm32]` | Читання WORD (zero-extend) | | 09 | `mov Rg32, byte [imm32]` | Читання BYTE (zero-extend) | Регістр < пам’ять (через регістр) | Opcode | Формат | Опис | | ------ | ----------------------- | ------------------ | | 04 | `mov Rg32, [Rg32]` | DWORD | | 2B | `mov Rg32, word [Rg32]` | WORD (zero-extend) | | 2D | `mov Rg32, byte [Rg32]` | BYTE (zero-extend) | Пам’ять < регістр (за адресою) | Opcode | Формат | Опис | | ------ | ------------------------ | ----------- | | 05 | `mov [imm32], Rg32` | Запис DWORD | | 08 | `mov [imm32], word Rg32` | Запис WORD | | 0A | `mov [imm32], byte Rg32` | Запис BYTE | Пам’ять < регістр (через регістр) | Opcode | Формат | Опис | | ------ | ----------------------- | ----- | | 06 | `mov [Rg32], Rg32` | DWORD | | 2C | `mov [Rg32], word Rg32` | WORD | | 2E | `mov [Rg32], byte Rg32` | BYTE | "05 Встановлення, використання та написання програм для EnotVM32.txt": Встановлення, використання та написання програм для EnotVM32. Встановлення. Опис для диску "C:\". Розпакуйте архів EnotVM32 на диск "C" повинно вийти ось так: C:\EnotVM32\BP4_001\ ATT.BGI CGA.BGI EGAVGA.BGI HERC.BGI PC3270.BGI EnotVM32.EXE Descript.ion Папка "BP4_001", BP4 - означає, що він компільований Turbo Pascal Version 4.0 Copyright (c) 1987 Borland International цифри це версія EnotVM32 Виберіть будь-який приклад з C:\EnotVM32\BP4_001\Examples\ файл "BOOT.bin" та скопіююйте його в папку C:\EnotVM32\BP4_001\ тепер можна запускати EnotVM32.EXE і він буде виконувати програму BOOT.bin Розробка програм. Розробка програм буде описуватись для flat assembler version 1.73.25 (FASM). Встановіть FASM цієї версії або будь якої іншої з офіційного сайту https://flatassembler.net/ https://flatassembler.net/download.php - посилання для скачування останньої версії. https://flatassembler.net/fasm17335.zip - flat assembler 1.73.35 for DOS ( fasm17335.7z - http://forumstatic.ru/files/001c/77/27/72607.7z ) або https://flatassembler.net/fasmw17335.zip - flat assembler 1.73.35 for Windows ( fasmw17335.7z - http://forumstatic.ru/files/001c/77/27/91859.7z ) створіть папку C:\FASMdos\ та розпакуйте fasm17335.zip або створіть папку C:\FASMwin\ та розпакуйте fasmw17335.zip Перевірьте, щоб був обов'язково файл макросів Macros.asm та BOOT.asm, - файл для написання програми для EnotVM32. Створимо... EditDos.Bat, який дозволяє редагувати BOOT.asm в режимі ДОС. EditWin.Bat, який дозволяє редагувати BOOT.asm в режимі Windows. Або ж ви можете використовувати будь який інший текстовий редактор який вам до вподоби. Якщо ви використовували один з цих редакторів та компілювали (Ctrl+F9) програму з'явиться (оновиться) файл BOOT.bin і після цього можна запустити EnotVM32.EXE для роботи BOOT.bin Якщо ж ви використовували будь який інших редактор, то програму треба компілювати. Для цього створені ComplDos.Bat та ComplWin.Bat відповідно для компіляції DOS-компілятором або Windows-компілятором і після цього можна запустити EnotVM32.EXE для роботи BOOT.bin Примітка. Якщо для компіляції ви використовуєте ComplDos.Bat або ComplWin.Bat, то зверніть увагу, на те, що перед компіляцією вони видаляють BOOT.bin, згідно строки "del BOOT.bin" в цих файлах. Якщо таке не потрібно, то, закоментуйте цю строку вставивши на її початок "REM ", тобто повинно буди "REM del BOOT.bin", або просто видаліть її повністю. Звісно при бажання можна створити Bat-файл і зробити, що відразу компілювала та запускала EnotVM32. Результат всього створеного буде в архіві EnotVM32. "99 Вдячність.txt": Автор EnotVM32 вдячний за допомогу в розробці та описам EnotVM32 штучним інтелектам На початку розоробки, двигун - ChatGPT ( https://chatgpt.com/ ) Декілька моментів в допомозі було від gemini.google ( https://gemini.google.com/ ) https://chat.qwen.ai за Вихідний код оброблений та документацію. https://chat.deepseek.com/ за Вихідний код оброблений та документацію. Надалі користуюсь https://chat.deepseek.com/