Знайдені нові старі версії 86-DOS – 0.11 та 0.34, спричинили цілу хвилю публікацій. Десь на десятку побачених, вирішив і я спробувати їх.
- Емуляція
- Формат диску – FAT12, з 16-байтовими записами каталогу
- Вміст дисків та експерименти
- Посилання
- Виноски
Про значимість контексту. В коді і в документації на ранні 86-DOS є фрази “Hard disk error”. Але все вказує, що мова не про HDD error, збій жорсткого диску, а про “серйозна помилка диску”, “disk hard error”…
Емуляція
Попрацювати з нею безпосередньо можна за допомогою open-simh. Потрібно скористатися1 машиною altairz80 – z80 у назві, не зважаючи на те, що 86-DOS потребує 8088/86, не повинна відлякувати – наявність плати-розширення з відповідним процесором вказується у конфігурації.
Моя, безперечно, не єдина, послідовність дій була наступною:
- Скомпілював open-simh/altairz80 з-під Linux2.
- Виконавчий файл,
altairz80
буде в піддиректорії BIN. - Він є незалежним від дерева компіляції, його можна копіювати куди завгодно.
- Виконавчий файл,
git clone https://github.com/open-simh/simh.git
cd simh/
make altairz80
cd BIN
- Копіюємо у директорію з цим файлом образи дисків, (.imd та .img розуміє), scp86mon.rom3 та файл конфігурації, умовно, scp86mon.txt:
; SIMH/AltairZ80 Configuration File for SCP 8086MON v1.5
; Copyright (c) 2008 Howard M. Harte
; www.86dos.org
;
; Press <return> to get into the Monitor, and then type
; 'B' to boot 86-DOS.
;
set cpu 8086
; load SCP Monitor
load scp86mon.rom 0
load scp86mon.rom ff800
; Set serial port for SCP
set sio port=f6/0/0/0/0/F/0/T
set sio port=f7/0/2/0/1/F/0/F
set sio ansi
set cromfdc en
set wd179x en
d cromfdc fdctype 4
; Образ диску:
att cromfdc0 86-DOS-v_0.11.img
; Start monitor, press enter to get '>' prompt.
go ffff0
- Запуск виглядатиме так:
- Двічі тиснемо Enter, тоді з’явиться запрошення.
- Важливо, щоб літера B – BOOT була великою. Нагадало DEBUG.COM власне з 86-DOS.
- Ctrl-E повертає до консолі симулятора, q (а ось тут регістр літери не важливий) – завершити його.
- Зауважте, DIR з 0.11 не виводить розмір файлів. У версії 0.34 – вже виводить.
./altairz80 scp86mon.txt
Altair 8800 (Z80) simulator Open SIMH V4.1-0 Current git commit id: c077c22d
2047 bytes [8 pages] loaded at 0.
2047 bytes [8 pages] loaded at ff800.
<Потрібно двічі натиснути Enter>
SCP 8086 Monitor 1.5
>B
? <=Тут символ з кодом 1
86-DOS version 0.11
Copyright 1980 Seattle Computer Products, Inc.
A:dir
COMMAND COM
RDCPM COM
HEX2BIN COM
ASM COM
TRANS COM
SYS COM
EDLIN COM
CHESS COM
CHESS DOC
A: <= Натиснув Ctrl-E
Simulation stopped, PCX: 004CF (and al,0x2)
sim> q
Goodbye
Завантажити образи, з якими експериментую, разом з конфігурацією, можна тут. Достатньо скопіювати ці файли у директорію з емулятором та вибрати потрібний образ в scp86mon.txt.
Формат диску – FAT12, з 16-байтовими записами каталогу
Фізичний формат
Диски для древніх дисководів, тому фізичний формат незвичний:
- сектор – 128 байт,
- на доріжці 26 секторів,
- 77 доріжок,
- одна голівка/односторонній диск,
- розмір – 256 256 байт.
На жаль, диски у форматі
.imd
з bitsavers виглядають пошкодженими – емулятор відмовляється їх вантажити, вони компресовані, якщо розархівувати IMDU – всі сектори образу виглядають порожніми, але інформація про диск ніби вірна. Не вдалося перетворити його і dsktrans з libdsk. Детальніше не розбирався, хоча щось у них ніби є…
Логічний формат
- Перших дві доріжки – 52 сектори, зарезервовані для операційної системи, в традиції CP/M.
- Коли я писав “Аналіз SYS.COM з попередника, 86-DOS”, ще не знав про цю особливість CP/M, тому дуже дивувався.
- Тобто, власне FAT починається, в файлі образу, зі зміщення 0x1A00.
- FAT займає шість секторів (по 128 байт) – 768 байт.
- Записи 12-бітові, це FAT12.
- Перший байт – 0xFF, видається (див. Addendum), це значення використовувалося ранніми версіями 86/MS/PC-DOS, щоб розпізнати дискету, де каталог з 16-байтовими записами – інші media ID в FAT були завжди меншими.
- Є дві копії FAT, друга – за зміщенням 0x1D00.
- Кластер – 4 сектори, тобто 512 байт (0x200).
- Далі каталог – кореневий і єдиний. Зміщення 0x2000, 8 секторів.
- Формат запису, згідно “86-DOS Revisited”:
- 8 байт імені, доповнені пробілами.
- 3 байти розширення, доповнені пробілами.
- 2 байти номеру першого кластера файлу, little endian формат – молодший байт перший.
- 3 байти розміру файлу, little endian.
- На дисках з 0.11 і 0.34, розмір зберігався лиш кратним 128 байт, хоча технічно була можливою байтова роздільна здатність, тому молодший байт або 0x00 або 0x80.
- Цікаво, які проблеми будуть з розміром, не кратним 128?
- Оскільки місце під атрибути відсутнє, думаю, каталоги в такому FAT неможливі.
- Хоча, теоретично, можна було використати 4 зайвих біти номера кластеру. Треба буде колись глянути в код, за натяками, чи цю можливість розглядали – наприклад, зануляли відповідні біти, перш ніж звертатися до таблиці FAT… Але це так, фантазії, під впливом способу збереження бітів атрибутів в CP/M.
- Формат запису, згідно “86-DOS Revisited”:
- За зміщенням 0x2400 починається область даних.
- Перший кластер має номер 2.
Таким чином, щоб знайти зміщення початку файлу в образі: взяти номер першого кластеру з каталогу, відняти від нього 2, помножити на 4*0x80 = 0x200 (розмір кластера) і додати 0x2400 – зміщення початку області даних. Наприклад, для SYS.COM:
(0x1C-2)*0x200 + 0x2400 = 0x5800
. Розрахунок номеру сектора ще простіший. :-)
Вперше зіткнувся з “живим” диском з 16-байтовими записами каталогу. Опис вище – нотатки, на випадок, якщо колись зберуся написати підтримку цього формату – окремою утилітою, чи додавши до плагіна Total Commander-а.
Вміст каталогу диску з 86-DOS 0.11. Вертикальними лініями відділено різні поля. Підкреслено молодші байти розміру, які тут мають лише два різних значення, стрілочка – в якому порядку читати байти (little endian): розмір HEX2BIN.COM – 0x000180, або, в десятковій – 384 байти. |
Кумедно, що перші шість файлів на дисках 0.11 і 0.34 збігаються настільки, що й записи в FAT для них тотожні – хіба що розмір трохи більший в COMMAND.COM i RDCPM.COM
Див. також 86-DOS: Supported disk formats на Wiki.
Якщо вміст окремих файлів комусь цікавий – пишіть, добуду, але поки лінь – мені простіше безпосередньо з образу взяти необхідне для експериментів.
Вміст дисків та експерименти
Далі про файли на дисках, але також проглянув їх сирий вміст – ніби, крім умовно цікавих залишків тексту у секторах, зайнятих SYS.COM, більше нічого не знайшов. Можливо, на диску 0.34 є фрагменти стертих асемблерних файлів – щоб перевірити, потрібно побудувати карту зайнятих кластерів, це довго. Але на 0.11 стертих файлів немає, на 0.34 – ?OVE.$$$, якийсь тимчасовий файл для присутнього MOVE.ASM, ймовірно.
86-DOS 0.11
У роботі, після досвіду (новіших версій) DOS, ця – достатньо звична, хіба що обмеженіша.
Наприклад, DIR не міє у wildcard-и…
A:dir
COMMAND COM <== Тут зрозуміло.
RDCPM COM <== Копіювання файлів з дисків CP/M в оцей підтримуваний FAT.
HEX2BIN COM <== Утиліти розробки -- конвертування текстового HEX в бінарний,
ASM COM <== асемблер SCP,
TRANS COM <== транслятор з асемблера Z80 в 8086.
SYS COM <== Створення bootable дискети.
EDLIN COM <== Той самий жахливий редактор, наголос в слові "самий" на ваш розсуд,
<== хоча, після редакторів OpenVMS, особливо по "сирому" UART-у,
<== краще його розумію...
CHESS COM <== Текстова шахова гра,
CHESS DOC <== та її документація.
Шахи доволі цікаві, хоча інтерфейс текстовий. Кажуть, запускається і під MS-DOS і доволі потужна. До неї є документація:
A:type chess.doc
This chess game uses algebraic chess notation. The files are lettered
"a" to "h" and the ranks are numbered 1 to 8. The lower left-hand corner
(from White's viewpoint) is a1.
Moves are entered as ff-tt (f=from, t=to), so to play the white king's
pawn up two squares you would enter E2-E4. You must enter your file
letters in upper case, while the computer will always use lower case.
To castle, enter only the king's move. The computer castles the same way.
To capture En Passant, enter your pawn's actual move.
Ply depth is the number of half-turns the computer looks ahead. For
example, with a ply depth of 3, the computer will consider
1. All of his possible moves
2. All of your responses to those moves.
3. All of his possible replies to your responses.
Start at ply depth 2 to get the feel for it.
A move of "R" will restart the game.
Приклад запуску шахової програми. |
Асемблер
Повторюся, благословенні часи, коли асемблер йшов у комплекті ОС. Навіть документація до них іде в User Manual – не в Developer. Не зміг стриматися і спробував.
Не те щоб я раніше ніколи не працював з EDLIN – кілька раз доводилося, але тут виконав у ньому багато більше операцій, ніж за все попереднє життя разом.
Команда Q не підтримується, а так – сюрпризів майже не було.
А ще, викликавши EDLIN без імені файлу, мені вдалося створити файл без імені… Як його стерти, не редагуючи каталог – не знаю. |
Асемблювання очевидне:
- Нехай є файл HW.ASM.
ASM HW
викликає асемблер. Розширення вказувати не можна.- Створює файли HW.HEX – з об’єктним кодом, записаним в шістнадцятковій системі та HW.PRN – лістинг.
HEX2BIN HW
з HW.HEX створює звичайний HW.COM, який можна запустити.
Приклад:
HW.ASM
:
PUT 0100H
ORG 0100H
MOV AH, 9
MOV DX, STR
INT 021H
INT 020H
STR: DM "Hello!$"
FB: DB '$'
HW.PRN
0000 PUT 0100H
0000 ORG 0100H
0100 B4 09 MOV AH, 9
0102 BA 09 01 MOV DX, STR
0105 CD 21 INT 021H
0107 CD 20 INT 020H
0109 48 65 6C 6C 6F 21 STR: DM "Hello!$"
A4
0110 24 FB: DB '$'
0111
Error Count = 0
HW.HEX
:11010000B409BA0901CD21CD2048656C6C6F21A424B5
:0000000000
Зверніть увагу, що славнозвісний $ у стрічці (яка задається DM – define message), транслюється у символ з кодом 0xA4 і виводиться цією системою як, власне, символ долара. Щоб додати символ кінця стрічки для функції AH=9, слід задати його як байт – але можна і ‘$’, і кодом 36.
Я дуже здивувався, коли доданий долар не допоміг завершити стрічку, як і нульовий символ… На початку – вивід вмісту файлу за допомогою EDLIN. |
За помилок асемблер, традиційно для того часу, лаконічний – і хіба в лістингу щось підказує (навіщо йому стільки порожніх рядків під копірайтом?!):
A:ASM HW
Seattle Computer Products 8086 Assembler Version 2.00
Copyright 1979 by Seattle Computer Products, Inc.
Error Count = 1
A:type HW.PRN
0000 PUT 0100H
0000 ORG 0100H
0100 B4 09 MOV AH, 9
0102 MOV DS, STR
***** ERROR no. 16H
0102 BA 00 00 MOV DX, 0
0105 CD 21 INT 021H
0107 CD 20 INT 020H
0109 48 65 6C 6C 6F 21 STR: DM "Hello!$"
A4
0110
Error Count = 1
Образ диску з цими експериментами долучаю – 86-DOS-v_0.11_test.img в архіві.
86-DOS 0.34
Тут вже DIR wildcard-и розуміє. Файлів там більше:
A:dir
COMMAND COM 1536
RDCPM COM 1024
HEX2BIN COM 384
ASM COM 6656
TRANS COM 3200
SYS COM 256
EDIT COM 1920 <== EDLIN version 0.21
CHKDSK COM 1152 <== Треба буде колись подивитися, що він вміє,
<== в порівнянні з http://indrekis2.blogspot.com/2013/08/chkdskcom-pc-dos-100.html
DEBUG COM 2432 <== Дизасемблювати поки не вміє -- лістинги будуть корисними.
MAKRDCPM COM 384 <== Своєрідний конфігуратор для RDCPM.
INITSMAL COM 512 <== Форматувати малі (5.25")
INITLARG COM 512 <== та великі (8") дискети комп'ютерів CROMEMCO,
<== https://en.wikipedia.org/wiki/Cromemco#From_boards_to_systems
BOOT ASM 2688 <== Дуже цікаві файли! Бутлоадер,
CPMTAB ASM 1152 <== таблиці дисків для RDCOM,
MON ASM 35584 <== "firmware monitor", аналог BIOS,
<== те що, скомпільованим, як scp86mon.rom, згодовуємо емулятору
INIT ASM 4992 <== Функція низькорівневого форматування для 1771/1791 контролерів:
<== https://en.wikipedia.org/wiki/Western_Digital_FD1771 ,
<== каже, трансльована з Z80, кажуть 12-19-80.
DOSIO ASM 11008 <== "I/O System for 86-DOS", вбудовані драйвери,
<== аналог IO.SYS з MS DOS.
<== Все разом -- значна частина коду 86-DOS, хай і лише
<== низькорівнева, аналог OEM Adaption Kit від MS.
NEWS DOC 1280 <== Власне, вони, новини -- зацитую далі.
MOVE ASM 512 <== Решту файлів -- прості асемблерні приклади, наведу один далі.
MOVE HEX 256
DAMN COM 128
SHIT COM 128
DAMN! COM 128
SHIT! COM 128
DAMN ASM 384
MOVE COM 128
SHIT! ASM 384
AARGH ASM 384
SPEEDCHK ASM 128
SHIT ASM 384
AARGH COM 128
SPEEDCHK HEX 256
AARGH! ASM 384
SPEEDCHK PRN 384
AARGH! COM 128
SPEEDCHK COM 128
Новини з 1981 року – десь приблизно тоді я народився:
A:type news.doc
UPDATED INFO NOT IN OUR MANUALS:
The file CPMTAB.ASM is the source file for the tables used by RDCPM and
is provided as an example of how new tables may be prepared. These
tables allow reading 8" or 5" single-density CP/M disks. If new tables
are desired for reading disks of a different CP/M 2 format, follow
these steps:
1. Prepare a source file of the new tables (see MAKRDCPM in
manual).
2. Assemble the new tables.
3. Convert the new tables to binary with HEX2BIN.
4. Run MAKRDCPM.
The files INIT.ASM and INIT.COM are the source and object code for a
disk initialization routine. Any raw or blown disk may be formatted
by this routine to an empty disk with the soft-sector information
necessary for your controller. Note that CLEAR must be run after
formatting to use the disk with 86-DOS. The program prints a warning
message and asks which drive to format before initializing begins.
NOTE TO CROMEMCO USERS: You have two programs, INITLARG and INITSMAL.
Each may only be used with 8" and 5" drives, respectively.
If you have BASIC, you will find INP, OUT, and RND have all been fixed.
Microsoft's version number does not reflect these changes, but the
creation date can be used to distinguish improved releases.
DEBUG.COM
Візьмемо цей файл за основу для експериментів з DEBUG.COM4:
A:type DAMN.ASM
; A PROGRAM TO EXPRESS HOW I FEEL.
PUT 0100H
ORG 0100H
MOV CX,CHARCOUNT
MOV SI,OUTBUFF
UP
LOOP: LODB
MOV DL,AL
MOV AH,2
INT 21H
LOOP LOOP
INT 20H
; BUFFERS AND CONSTANTS
OUTBUFF: DM "SOMEONE STEAL YOUR SNEAKERS?"
CHARCOUNT: EQU 28
; END OF *DAMN*
Його лістинг:
A:type damn.prn
0000 ; A PROGRAM TO EXPRESS HOW I FEEL.
0000 PUT 0100H
0000 ORG 0100H
0100 B9 1C 00 MOV CX,CHARCOUNT
0103 BE 12 01 MOV SI,OUTBUFF
0106 FC UP
0107 AC LOOP: LODB
0108 8A D0 MOV DL,AL
010A B4 02 MOV AH,2
010C CD 21 INT 21H
010E E2 F7 LOOP LOOP
0110 CD 20 INT 20H
0112 ; BUFFERS AND CONSTANTS
0112 53 4F 4D 45 4F 4E OUTBUFF: DM "SOMEONE STEAL YOUR SNEAKERS?"
45 20 53 54 45 41
4C 20 59 4F 55 52
20 53 4E 45 41 4B
45 52 53 BF
012E CHARCOUNT: EQU 28
012E ; END OF *DAMN*
012E
Error Count = 0
Команди – лише великими літерами. Також, дебагер сегменти не розуміє, D 100
5, не дало очікуваного результату, тому адреси доводиться рахувати вручну:
A:debug damn.com
DEBUG-86 version 0.2
>R
AX=0000 BX=0000 CX=0001 DX=0000 SP=003E BP=0000 SI=0000 DI=0000
DS=031A ES=031A SS=031A CS=031A IP=0100 NV UP DI PL NZ NA PO NC
>D 32A0
032A0 B9 1C 00 BE 12 01 FC AC-8A D0 B4 02 CD 21 E2 F7 9..>..|,.P4.M!bw
032B0 CD 20 53 4F 4D 45 4F 4E-45 20 53 54 45 41 4C 20 M SOMEONE STEAL
032C0 59 4F 55 52 20 53 4E 45-41 4B 45 52 53 BF 20 20 YOUR SNEAKERS?
032D0 20 20 20 20 20 20 20 20-20 20 20 20 20 20 43 48 CH
032E0 41 52 43 4F 55 4E 54 3A-09 45 51 55 09 32 38 0D ARCOUNT:.EQU.28.
032F0 0A 30 31 32 45 20 20 20-20 20 20 20 20 20 20 20 .012E
03300 20 20 20 20 20 20 20 20-20 3B 09 09 45 4E 44 20 ;..END
03310 4F 46 20 2A 44 41 4D 4E-2A 0D 0A 30 31 32 45 20 OF *DAMN*..012E
>
Бачимо, що CS = 031A, множимо на 0x10, додаємо 0x100, отримуємо 0x32A0 – і там видно наш виконавчий файл – вміст відповідає лістингу.
На жаль, T
, трасування по команді, виконує програму до завершення, не зупиняючись, і не виводячи вмісту регістрів, як обіцяли. Ймовірно, причина в емуляторі, який не реалізовує апаратне покрокове виконання з викликом INT 1. Або баг саме в цій версії – поки не можу перевірити.
Команда G
працює, але дуже вже незручна:
>G 32A3
AX=0000 BX=0000 CX=001C DX=0000 SP=003E BP=0000 SI=0000 DI=0000
DS=031A ES=031A SS=031A CS=031A IP=0103 NV UP DI PL NZ NA PO NC
>G 32A6
AX=0000 BX=0000 CX=0001 DX=0000 SP=003E BP=0000 SI=0112 DI=0000
DS=031A ES=031A SS=031A CS=031A IP=0106 NV UP DI PL NZ NA PO NC
CHKDSK.COM
EDLIN цієї версії створювати файли без імені вже не вміє, то трішки зламав диск вручну:
- Створив файл, але ім’я замінив пробілами.
- Створив зайвий ланцюжок в FAT з двох кластерів, лише в першій копії FAT.
Результат такий:
<skipped>
SPEEDCHK PRN 384
AARGH! COM 128
SPEEDCHK COM 128
896
A:chkdsk a:
1024 bytes unallocated disk space freed
38 disk files
246784 bytes total disk space
156160 bytes remain available
49152 bytes total system RAM
39136 bytes free
Файл з порожнім іменем не зачепило, про розбіжність копій FAT не сказало, але виправляє обидві.
Колись може спробую дизасемблювати, порівняти з його версією з DOS 1.00.
Посилання
- “86 DOS Version 0.11 found!”
- Seattle Computer Products 86-DOS v0.11, serial # 11, 1980-??-?? на archive.org
- Seattle Computer Products 86-DOS v0.34, serial # 221, 1980-02-20 на archive.org
- “86-DOS Revisited”
- “Обнаружены шахматы для DOS… 1980 года” – опис шахової програми.
- 86-DOS 0.3 Programmers Manual, 1980
- 86-DOS 0.3 Users Manual, 1980
- Category:86-DOS versions – з детальним описом.
- 86-DOS на WinWorldPC – гарні архіви, деякі з емуляторами, плюс – добуті з образів файли.
- Tarbell to Cromemco – модифікація образу версії 86-DOS 1.14, який потребує не підтримуваних SIMH дисководів, щоб він працював з підтримуваним – шляхом редагування BOOT.ASM та DOSIO.ASM та асемблювання – все необхідне вже є, просто не підтримується.
Виноски
-
Підозрюю, можна використати й інші емулятори, але особливо не досліджував. ↩
-
В мене Ubuntu під WSL, з великим набором інструментів розробки – не довелося нічого доінстальовувати. ↩
-
SCP – це Seattle Computer Products. ↩
-
Цікаво, що в документації DEBUG.COM називають Resident debugger. ↩
-
Звичне з пізніших DOS – там DEBUG,якщо не вказано іншого, виводить відносно вмісту DS. ↩