Virtual Hard Disk
2026-02-25 18:40Я добавил в симулятор PC i86 поддержку образов жёсткого диска в формате VHD. Это когда пустые сектора не хранятся, а файл постепенно увеличивается по мере наполнения диска содержимым. Получилось совместимо с QEMU, что очень удобно: можно пользоваться утилитой qemu-img чтобы создавать и конвертировать образы. Формат VHD когда-то придумала фирма Connectix (позже доставшаяся Микрософту), и теперь это открытый стандарт. Кроме QEMU его поддерживают Hyper-V, VirtualBox, Virtual PC и другие.
Для примера, 100-мегабайтный диск C: с установленным MS-DOS 3.3 и Volkov Commander имеет размер всего 2 мегабайта. Никакого сжатия, чисто пропуск пустых секторов. Можно смело создавать диски большого размера, не боясь забить файловую систему ерундой.
Для проверки симулятора пробую запускать разные исторические приложения. Турбо Паскаль фунциклирует замечательно.

Турбо Си тоже прекрасно.

QuickC запускается, но не реагирует на клавиатуру. Неужели пытается опрашивать клавиши мимо биоса? Надо выяснять.

В целом уже понятно, что эксперимент с симуляцией биоса удался. Теперь задача перетащить всё хозяйство на микроконтроллер, с видео выходом HDMI, клавиатурой USB и диском на SD карточке.
Для примера, 100-мегабайтный диск C: с установленным MS-DOS 3.3 и Volkov Commander имеет размер всего 2 мегабайта. Никакого сжатия, чисто пропуск пустых секторов. Можно смело создавать диски большого размера, не боясь забить файловую систему ерундой.
Для проверки симулятора пробую запускать разные исторические приложения. Турбо Паскаль фунциклирует замечательно.

Турбо Си тоже прекрасно.

QuickC запускается, но не реагирует на клавиатуру. Неужели пытается опрашивать клавиши мимо биоса? Надо выяснять.

В целом уже понятно, что эксперимент с симуляцией биоса удался. Теперь задача перетащить всё хозяйство на микроконтроллер, с видео выходом HDMI, клавиатурой USB и диском на SD карточке.

no subject
Date: 2026-02-26 05:04 (UTC)no subject
Date: 2026-02-26 05:37 (UTC)no subject
Date: 2026-02-26 06:27 (UTC)https://vak.dreamwidth.org/1108108.html
Но поверх биоса он не ставится. Для него нужно симулировать само железо.
no subject
Date: 2026-02-26 06:29 (UTC)no subject
Date: 2026-02-26 07:02 (UTC)no subject
Date: 2026-02-26 08:20 (UTC)Иначе я б тебя беспокоить не стал.
[Вторая попытка. Почему-то с первого раза комментарий не оставился.]
no subject
Date: 2026-02-26 09:26 (UTC)HandleBreak proc far
push es ds ax bx cx dx di si bp
mov ax, cs
mov ds, ax
mov ax, 40h
mov es, ax
in al, 60h
mov ah, es:byte ptr 17h
and ah,0ch
pushf
call dword ptr Save09Vec
cmp ax,0c11h ;Alt-Ctrl-W pressed
jne pop2
cmp cs:ActivFlag,True
je pop2
mov cs:ActivFlag,True
call Snipp
mov cs:ActivFlag,False
pop2: pop bp si di dx cx bx ax ds es
iret
HandleBreak endp
Сейчас еще посмотрел, там внутри основной программы используется очень популярная в те времена среди паскалеров либа Turbo Professional
;******************************************************
; OPENHKBD.ASM 1.10
; Enhanced keyboard routines
; Copyright (c) TurboPower Software 1987, 1989.
; All rights reserved.
;******************************************************
А в ней еще сложней.
NewInt09 PROC FAR
STI ;Interrupts on
PUSH AX ;Save registers we use
PUSH BX
PUSH CX
PUSH DS
MOV AX,SEG DATA
MOV DS,AX ;Point to Turbo data area
CMP EnableEnhanced,0 ;Enhanced functions enabled?
JZ Int09Orig ;No, get out
MOV AX,0040h
MOV DS,AX ;Point to BIOS data area
MOV AL,DS:BiosShiftFlags ;Shift status in AL
TEST AL,00001111b ;Any shift bits set? !!.03
JNZ SkipReleased ;Skip released check if so !!.03
MOV ShiftReleased,1 ;All shift keys released !!.03
SkipReleased: ; !!.03
CMP ShiftReleased,1 ;Have all shifts been released? !!.03
JNZ Int09Orig ;Get out if not !!.03
MOV CL,AL ;Save shift state in CL
TEST AL,00001100b ;Either Control or Alt depressed?
JZ TestPad5 ;No, check special case of Pad-5
AND AL,00001100b ;Just Ctrl-Alt bits
CMP AL,00001100b ;Both Ctrl and Alt depressed?
JNZ NotCtrlAlt ;Jump if not !!.10
IN AL,60h ;Read scan code !!.10
CMP AL,53h ;Look for Ctrl-Alt-Del !!.10
JE Int09Orig ;Let BIOS handle reboot !!.10
NotCtrlAlt: ; !!.10
MOV AL,CL ;Restore shift state
AND AL,00001111b ;All shift bits
CMP AL,00001010b ;Just Alt-LeftShift?
JE Int09Orig ;Get out so Alt-Keypad works
IN AL,60h ;Read scan code
CMP AL,0E0h ;Code for enh kbd extended key? !!.03
JZ NewInt09Done ;Eat the key if so !!.03
CMP AL,53h ;Is it in range 0..53h?
JA Int09Orig ;If not, pass on to BIOS int 09 handler
MOV BX,offset IndexTable ;Point to index table
XLAT BYTE PTR CS:[0] ;Get index
CMP AL,0FFh ;AL = FFh?
JNZ MatchedScan ;Special case if AL <> FFh
Int09Orig: ;Let BIOS int 09 handler take care of it
POP DS ;Restore registers
POP CX
POP BX
POP AX
JMP PrevInt09 ;Transfer to previous interrupt 09
TestPad5:
IN AL,60h ;Read scan code
CMP AL,0E0h ;Code for enh kbd extended key? !!.03
JZ NewInt09Done ;Eat the key if so !!.03
CMP AL,4Ch ;Pad-5 key?
JNZ Int09Orig ;No, get out
MOV AX,4C00h ;Set up scan code to return
TEST CL,00100000b ;Is NumLock set?
JZ NoNumLock ;No, it's not
NumLockSet:
TEST CL,00000011b ;Is a shift key depressed?
JNZ StoreScanWord ;Yes, we want to store 4C00 in buffer
JMP SHORT Int09Orig ;No, let original int 9 do it
NoNumLock:
TEST CL,00000011b ;Is a shift key depressed?
JZ StoreScanWord ;No, store scan word
JMP SHORT Int09Orig ;Yes, let original int 9 do it
MatchedScan:
SHL AX,1 ;Multiply scan index by 2
SHL AX,1 ;Multiply by 2 again
MOV BX,AX ;BX = Index * 4
TEST CL,00001000b ;Alt depressed?
JZ NoAltKey ;No, use first column of table
ADD BX,2 ;Yes, use second column of table
NoAltKey:
MOV AX,CS:WordTable[BX] ;Get the scan word
CMP AX,0FFFFh ;Case handled by BIOS?
JZ Int09Orig ;Yes, get out of here
StoreScanWord: ;!!.03 rearranged to reuse EatKey code
MOV CX,AX ;Save scan word in CX
CLI ;Stop CPU interrupts
MOV BX,DS:BufferTail ;Point to end of keyboard buffer
MOV AX,BX ;Transfer to AX
ADD AX,0002 ;Advance to next position
CMP AX,DS:BufferEnd ;Wrap around if needed
JNE CheckFull ;No need to wrap
MOV AX,DS:BufferStart ;Else to beginning of buffer
CheckFull:
CMP AX,DS:BufferHead ;Bumping into start?
JE NewInt09Done ;Exit if full
MOV [BX],CX ;Store keystroke
MOV DS:BufferTail,AX ;Advance tail
NewInt09Done:
IN AL,61h ;Read control port value
MOV AH,AL ;Save in AH
OR AL,80h ;Set high bit
OUT 61h,AL ;Reset keyboard
MOV AL,AH ;Retrieve original value
OUT 61h,AL ;Enable keyboard
CLI ;Assure ints off before signaling EOI
MOV AL,20h ;End of interrupt
OUT 20h,AL ;To the interrupt controller
POP DS ;Restore registers
POP CX
POP BX
POP AX
IRET ;Return to caller
NewInt09 ENDP
В общем, я думаю, что для полноценной симуляции без этих портов не обойтись. Куча вполне нормативных ДОСовских программ лезут в клавиатурные порты как к себе в холодильник, так как оно более-менее на всех PC одинаковое и тогда не было никаких причин этого не делать. Ну и таймера это тоже касается. В его порты тоже каждая вторая программа зачем-нибудь лезла.