Indrekis
Indrekis

Categories

  • retrocomputing
  • ibm_pc_compat

Tags

  • retrocomputing
  • IBM PC та сумісні
  • 86-DOS

Знайдені нові старі версії 86-DOS – 0.11 та 0.34, спричинили цілу хвилю публікацій. Десь на десятку побачених, вирішив і я спробувати їх.

Про значимість контексту. В коді і в документації на ранні 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.
  • 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.
  • За зміщенням 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 1005, не дало очікуваного результату, тому адреси доводиться рахувати вручну:

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 цієї версії створювати файли без імені вже не вміє, то трішки зламав диск вручну:

  1. Створив файл, але ім’я замінив пробілами.
  2. Створив зайвий ланцюжок в 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.

Посилання

Виноски

  1. Підозрюю, можна використати й інші емулятори, але особливо не досліджував. 

  2. В мене Ubuntu під WSL, з великим набором інструментів розробки – не довелося нічого доінстальовувати. 

  3. SCP – це Seattle Computer Products

  4. Цікаво, що в документації DEBUG.COM називають Resident debugger. 

  5. Звичне з пізніших DOS – там DEBUG,якщо не вказано іншого, виводить відносно вмісту DS.