ROMOS + int21 for usb .sys driver
ROMOS + int21 for usb .sys driver
The following is some thing interesting works about ROMOS + int21h. The goal is to load .sys driver privier to booting the os up. Thus I can use this environment hopefully to load USB .sys driver and boot from it.
[size=-1]Progress:
1. The ROMOS is working in qemu
2. DFDOS have simple implementation of int21h
3 I combine all int21h from DFDOS to ROMOS
4 I also tested some int21h function, mostly int21,9
TODO:
1. add .sys loading mechanism
2. load the .sys file automatically
3 extensily test this idea.
File:[url=]rom15.asm[/url]
Reference:
ROMOS
http://rayer.ic.cz/romos/romose.htm
DFDOS
http://www.dftech.cwc.net/osdev/
V0.2
http://www.dftech.cwc.net/osdev/DFDOS002.zip
NETBOOT idea
http://netboot.sourceforge.net/english/index.shtml
steps:
1: download ROMOS, DFDOS v0.2
2: put all DFDOS kernel source file into the romos dir
3: use the provided rom15.asm instead of orginal romos.asm
4: compile the rom15.asm into romos.bin
5: test the romos.bin in qemu v0.9 by'-option-rom romos.bin' switch
[size=-1]Progress:
1. The ROMOS is working in qemu
2. DFDOS have simple implementation of int21h
3 I combine all int21h from DFDOS to ROMOS
4 I also tested some int21h function, mostly int21,9
TODO:
1. add .sys loading mechanism
2. load the .sys file automatically
3 extensily test this idea.
File:[url=]rom15.asm[/url]
Reference:
ROMOS
http://rayer.ic.cz/romos/romose.htm
DFDOS
http://www.dftech.cwc.net/osdev/
V0.2
http://www.dftech.cwc.net/osdev/DFDOS002.zip
NETBOOT idea
http://netboot.sourceforge.net/english/index.shtml
steps:
1: download ROMOS, DFDOS v0.2
2: put all DFDOS kernel source file into the romos dir
3: use the provided rom15.asm instead of orginal romos.asm
4: compile the rom15.asm into romos.bin
5: test the romos.bin in qemu v0.9 by'-option-rom romos.bin' switch
;*****************************************************************************
;* .-= The ROMOS Project =-. *
;* ROM Operating System 1.02 by Martin 瀍h爇 (C) 2001-2006; rayer@seznam.cz *
;* Started: 27.3.2001 *
;* Last updated: 18.3.2006 *
;* Tested on: Award BIOS 4.51PG (Octek Rhino II ZX), 6.00PG (Abit BX133-Raid)*
;* Compile with NASM (286 code), recommended segment to load: D000h *
;* Now able to boot FreeDOS from virtual ROMDISK image, see incbin at EOF *
;*****************************************************************************
;%define MAKE_DEBUG_COM ;compile as executable *.COM file / zkompiluje spustitelny *.COM soubor
%define MAKE_PCI_MODULE ;create PCI ROM module instead ISA ROM module (needed for new BIOSes) / vytvori ROM jako PCI modul misto ISA modulu (nektere nove BIOSy uz nepodporuji ISA)
ROM_IMAGE_SIZE EQU 64 ;size of ROM image in kB / velikost ROM image v kB
ROMDISK_DRIVE EQU 1 ;0=A: 1=B: 80h=C:
emulated drive / emulovana jednotka
ROMDISK_CYLS EQU 7 ;number of cylinders of emulated drive [1-255] / pocet cylindru emulovane jednotky
ROMDISK_HEADS EQU 1 ;number of heads of emulated drive [1-255] / pocet hlav emulovane jednotky
ROMDISK_SECPT EQU 18 ;sectors per track of emulated drive [1-63] / pocet sektoru na stopu emulovane jednotky
BS_DRIVE_OFFSET EQU 24h ;offset in bootsector where boot dive number is stored / pozice v bootsektoru, kde je cislo jednotky
BS_SEGMENT EQU 0 ;address to load bootsector / adresa spousteni bootsectoru
BS_OFFSET EQU 7C00h
ROMOS_MSG_DELAY EQU 30 ;delay of MSG1 show in 55ms ticks / doba zobrazeni MSG1 v 55ms ticich
ROMOS_HOTKEY EQU 00010000b ;mask for ScrollLock key / maska pro klavesu ScrollLock
;ROMOS_HOTKEY EQU 00100000b ;mask for NumLock key / maska pro klavesu NumLock
NEW_SS EQU 04000h ;address of new stack (4000:xxxx should be free for Award BIOS)
NEW_SP EQU 0FFFFh ;adresa noveho zasobniku (oblast 4000:xxxx by mela byt v Award BIOSu volna)
INT19H EQU 19h*4 ;address in IVT for store INT 19h vector / misto v IVT pro ulozeni vektoru INT 19h
OLD_INT13H EQU 85h*4 ;address for permanent store of old INT 13h vector - INT 85h / misto pro trvale ulozeni puvodniho vektrou INT 13h
;INT 84h a 85h shuld be free, change it if collide / INT 84h a 85h by melo byt volne, v pripade kolize zmenit
%ifdef MAKE_DEBUG_COM
ORG 100h ;use if compiling .COM file / pouzij pri kompilaci .COM souboru
%else
ORG 0h ;use if compiling ROM image / pouzij pri kompilaci ROM image
DW 0AA55h ;ROM header signature / ROM hlavicka
DB ROM_IMAGE_SIZE*2;ROM size in 512B blocks, minimum 8 blocks / velikost ROM v 512B blocich, minimum 8 bloku
%endif
JMP BEGIN ;jump to begin of code / skok na zacatek kodu
DB 'CHKSUM=',0 ;reserved Byte for checksum / rezerva na korekci checksumu
%ifdef MAKE_PCI_MODULE ;need to insert additional PCI headers / je potreba vlozit pridavne hlavicky PCI
TIMES 18h-($-$$) DB 0 ;padding zeros to offset 18h / zarovnani nulami na offset 18h
DW PCIHDR ;pointer to PCI Header / ukazatel na hlavicku PCI (musi byt na offsetu 18h)
DW PNPHDR ;pointer to PnP Expansion Header / ukazatel na hlavicku PnP (musi byt na offsetu 20h)
PCIHDR: DB 'PCIR' ;PCI data structure signature / hlavicka PCI data structury
DW 10ECh ;vendor ID (must match real PCI device) / ID vyrobce (musi odpovidat existujicimu PCI zarizeni)
DW 8029h ;device ID (must match real PCI device) / ID zarizeni (musi odpovidat existujicimu PCI zarizeni)
DW 0 ;pointer to vital product data (0=none) / ukazatel na vital product data (0=nic)
DW 24 ;PCI data structure length [B] / velikost PCI data structury [B]
DB 0 ;PCI data structure revision (0=PCI 2.1)/ revize PCI data structury (0=PCI 2.1)
DB 2,0,0 ;PCI device class code (2=notwork ctrl., 0=eth.) / trida PCI zarizeni (musi odpovidat existujicimu PCI zarizeni)
DW ROM_IMAGE_SIZE*2;ROM size in 512B blocks / velikost ROM v 512B blocich
DW 0 ;revision level of code / revize kodu
DB 0 ;code type (0=x86 PC-AT) / typ kodu (0=x86 PC-AT kompatabilni)
DB 80h ;last image indicator/indikuje posledni image v ROM
DW 0 ;reserved
PNPHDR: DB '$PnP' ;PnP data structure signature / hlavicka PnP data structury (PnP BIOS spec. 1.0a str. 17)
DB 1 ;PnP structure revision / revize PnP struktury
DB 2 ;PnP structure length (in 16B blocks) / velikost PnP struktury v 16B blocich
DW 0 ;offset to next header (0-none) / offset na dalsi hlavicku
DB 0 ;reserved
DB 33h ;PnP structure checksum / kontrolni soucet PnP struktury
DD 0 ;device identifier / identifikator zarizeni
DW 0 ;pointer to manufacturer string / ukazatel na retezec vyrobce
DW 0 ;pointer to productname string / ukazatel na retezec zarizeni
DB 2,0,0 ;device class code (2=notwork ctrl., 0=eth.) / trida PCI zarizeni (musi odpovidat existujicimu PCI zarizeni)
DB 64h ;device indicators (64h - shadowable,cacheable,not only for boot,IPL device)
DW 0 ;boot connection vector (0-none)
DW 0 ;disconnect vector (0-none)
DW 0 ;bootstrap entry vector (0-none)
DW 0 ;reserved
DW 0 ;static resource info vector (0-none)
%endif
;************** Constants / Konstanty *****************************************
MSG1 DB 'Press [ScrollLock] to boot ROMOS !',0
%ifdef MAKE_PCI_MODULE
MSG2 DB 'Welcome to ROMOS ver. 1.02 PCI by Martin Rehak',0
%else
MSG2 DB 'Welcome to ROMOS ver. 1.02 by Martin Rehak (C) 2001-2006; rayer@seznam.cz',0
%endif
MSG3 DB 'ROMOS has installed virtual ROM DISK drive.',0
MSG4 DB 'Bootsector loaded at ',0
MSG5 DB 'Booting!',0
;************** Subroutines / Procedury ***************************************
DELAY: ;pause, put number of 55ms idle ticks in AH / pauza, do AH vloz pocet 55ms idle tiku
STI ;enable interrupts otherwise timer will not be updated / povol preruseni, jinak se neaktualizuje casovac
PUSH AX ;store / uloz AX
PUSH ES ;store / uloz ES
PUSHF
PUSH BYTE 0 ;segment of timer / segment casovace 0000 (opcode 6A 00 misto 68 00 00)
POP ES ;ikdyz jsme pushli jen Byte, popne se cely Word (vyssi Byte je vzdy 0)
ADD AH,[ES:046Ch] ;add ticks to required delay / k pozadovane pauze pricti aktualni pocet tiku z adresy casovace 046C
@DLY1: CMP AH,[ES:046Ch] ;compare current and required value / rovnaji se pozadovane a aktualni ?
JNE @DLY1 ;if not then repeat / kdyz ne, opakuj
POPF
POP ES ;restore ES / obnov ES
POP AX ;restore AX / obnov AX
RET ;return / navrat
;*****************************************************************************
GOTOXY: PUSH AX ;set cursor [x,y] position given in [DL,DH] / nastavi kurzor na pozici [x,y] danou [DL,DH]
PUSH BX ;[0,0] is top-left corner / [0,0] je levy horni roh
MOV AH,2 ;function number 2 / funkce cislo 2
MOV BH,0 ;videopage / videostranka
INT 10h ;execute / proved
POP BX
POP AX
RET ;return / navrat
;*****************************************************************************
WHEREXY:
PUSH AX ;get cursor [x,y] position into [DL,DH] / precte pozici kurzoru [x,y] do [DL,DH]
PUSH BX
PUSH CX
MOV AH,3 ;function number 3 / funkce cislo 3
MOV BH,0 ;videopage / videostranka
INT 10h ;execute / proved
POP CX ;waste information about cursor size / zahod informaci o velikosti kurzoru
POP BX
POP AX
RET ;return / navrat
;*****************************************************************************
WRITE: PUSHA ;write zero-terminated string from CS:IP pointer / vypis 0-ukoncene vety z CS:SI atributem v BL
PUSHF ;with every character repeated BH-times (low 7bit) / a opakovanim jednotlivych znaku BH-krat
PUSH BX ;and write CRLF if MSB of BH is 1 / a odradkuj pokud MSB BH je 1
CALL WHEREXY ;read cursor position to [DL,DH] / precti pozici kurzoru [DL,DH]
MOV AH,9 ;function write char 9h (BH=scr_num, AL=char, CX=repeat, BL=attrib) / funkce na vypis znaku 9h
XOR CX,CX ;set CH=0, CL=0
XCHG CL,BH ;repeat char. BH-times CH=0, CL=BH, BH=0 / opakovani znaku BH-krat
AND CL,7Fh ;set MSB=0, accept only 7-bit value / snuluj MSB, akceptujeme pouze 7-bit hodnotu
@WRI1: MOV AL,[CS:SI] ;load char. from zero-terminated string / nacti znak z retezce ukonceneho 0
CMP AL,0 ;if it is 0 / je-li konec - 0
JE @WRI2 ;then end / tak konec
INT 10h ;execute / proved
INC SI ;increment string index / inkrementuj index znaku ve vete
INC DL ;increment X-cursor position / inkrementuj X-ovou pozizi kurzoru
CALL GOTOXY ;set cursor to [DL,DH] (need to do myself) / nastav kurzor na [DL,DH] (musim to delat rucne)
JMP SHORT @WRI1 ;repeat / opakuj
@WRI2: POP BX ;restore BX / obnov BX
CMP BH,80h ;if BH<80h (MSB=0) skip / pokud je BH<80h (MSB=0)
JS @WRI3 ;jump to end / preskoc na konec
POPF ;else write newline / jinak odradkuj
POPA ;restore regs because WCRLF store them again / obnov registry protoze WCRLF je opet uklada
WCRLF: PUSHA ;write CRLF = newline / vypis CRLF = novy radek
PUSHF ;this subfunc. can be called out of WRITE func. / tato podfunkce muze byt volana i mimo fci WRITE
MOV AX,0E0Dh ;function 0E - write char as TTY, CR / funkce 0E - pis TTY znak, znak CR
XOR BL,BL ;paper color=0 / barva papiru=0
INT 10h ;execute / proved
MOV AL,0Ah ;char LF / znak LF
INT 10h ;execute / proved
@WRI3: POPF ;restore flags (2B) / obnov flagy
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B)
RET ;return / navrat
;*****************************************************************************
WHEXPTR:PUSH AX ;write hexa pointer DX:CX / vypis hexa pointer DX:CX
PUSH BX ;store AX,BX / uloz AX,BX
CALL WHEXW ;write segment from DX / vypis segment z DX
XCHG DX,CX ;swap CX-DX / prohod CX-DX
XOR BL,BL ;paper color=0 / barva papiru=0
MOV AX,0E3Ah ;write char : / vypis znak :
INT 10h ;via BIOS / pres BIOS
CALL WHEXW ;write offset from DX / vypis offset z DX
XCHG DX,CX ;swap back CX-DX / prohod CX-DX tak jak byly puvodne
POP BX ;restore BX,AX / obnov BX,AX
POP AX
RET ;return / navrat
;*****************************************************************************
WHEXW: XCHG DH,DL ;write hexa word from DX / vypis hexa word z DX
CALL WHEXB ;call WHEXB to write upper Byte / zavolej WHEXB na vypis horniho Byte
XCHG DH,DL ;swap DH,DL / prohod DH,DL
CALL WHEXB ;call WHEXB to write lower Byte / zavolej WHEXB na vypis dolniho Byte
RET ;return / navrat
;*****************************************************************************
WHEXB: PUSH AX ;write hexa Byte from DL / vypis hexa Byte z DL
PUSH DX
PUSHF
MOV DH,DL
AND DL,00Fh ;mask lower digit / vymaskuj dolni cislici
AND DH,0F0h ;mask upper digit / vymaskuj horni cislici
ROR DH,4 ;shift upper digit 4bits right / posun horni cislici o 4 bity vpravo
CALL @WHB1 ;write upper digit / vytiskni horni cislici
MOV DH,DL
CALL @WHB1 ;write lower digit / vytiskni dolni cislici
POPF
POP DX
POP AX
RET
@WHB1: CMP DH,0Ah ;compare if the digit is lower than 10 / porovnej, je-li cislo mensi nez 10 (0Ah)
JC @WHB2 ;if not then skip / neni-li preskoc dal
ADD DH,7 ;if yes then add 7 to get proper ASCII code / je-li, pricti 7 (rozdil ASCII kodu 'A' a '9'+1)
@WHB2: ADD DH,'0' ;add ASCII code of '0' / pricti ASCII kod '0'
MOV AH,0Eh ;write char / vypis znak
MOV AL,DH ;from AL / z AL
INT 10h ;via BIOS / pres BIOS
RET ;return / navrat
;*****************************************************************************
WREGS: PUSHA ;write register dump line and CRLF / vypis na radku registry a odradkuj
PUSH DS ;prepare all regs to stack / priprav vsechny registry do zasobniku
PUSH ES ;AX,CX,DX,BX,SP,BP,SI,DI, DS,ES,SS,CS, F
PUSH SS
PUSH CS
PUSHF
MOV CX,9 ;loop counter-9x repeat / pocitadlo smycky-9x oparuj
MOV SI,REGSTR ;prepare reg name / priprav jmeno registru
MOV BP,SP ;set BP=SP for indexing stored regs / priprav BP=SP pro indexaci ulozenych registru
@WREGS1:MOV BX,0107h ;seda barva, opakovani 1x
CALL WRITE ;write reg name / vypis jmeno registru
MOV AX,0E3Dh ;write char function, char '=' / funkce vypisu znaku, znak '='
XOR BL,BL ;paper color=0 / barva papiru=0
INT 10h ;write '=' via BIOS / vypis '=' pres BIOS
MOV DX,[SS:BP] ;load reg from stack to DX / nacti registr ze zasobniku do DX
CALL WHEXW ;write DX hexa value / vypis hexa hodnotu DX
MOV AL,' ' ;write char ' ' / vypis znak ' '
INT 10h ;via BIOS / pres BIOS
INC BP ;go up through the stack data / jdi v zasobniku na dalsi registr
INC BP
INC SI ;reg name pointer+=3 / nastav pointer na dalsi jmeno registru (+3)
INC SI
INC SI
LOOP @WREGS1 ;repeat until CX is nonzero / opakuj dokud je CX nenulove
CALL WCRLF ;newline / odradkuj
POPF ;restore regs and flag / obnov registry a flag
POP DS ;POP DS instead CS because it crashed under BOCHS
POP SS ;anyway CS was not changed during this routine
POP ES
POP DS
POPA
RET ;return / navrat
REGSTR DB 'F',0,0 ;strings with regs names / retezce s nazvy registru
DB 'CS',0
DB 'SS',0
DB 'ES',0
DB 'DS',0
DB 'DI',0
DB 'SI',0
DB 'BP',0
DB 'SP',0
;************** New INT 13h handler emulating virtual ROM disk, now supports functions 2,3,8
;************** Nova obsluha INT 13h emulujici virtualni ROM disk, nyni podporuje sluzby 2,3,8
NEW_INT13H: ;INT XX do CLI, PUSH F,CS,IP (6B) / INT XX provadi CLI, PUSH F,CS,IP (6B)
PUSHF ;store flags (2B) / uloz flagy (2B)
CMP DL,ROMDISK_DRIVE;related to our disk ? / tyka se to naseho disku?
JE @NEW_INT13H_HUB ;if yes continue below else / pokud ano, pokracuj nize, jinak
POPF ;restore flags (2B) and / obnov flagy (2B) a
JMP 0:OLD_INT13H-1 ;jump to old INT 13h handler using FAR JMP / skoc na puvodni preruseni INT 13h pomoci FAR JMP
@NEW_INT13H_HUB: ;subfunction hub / rozcestnik podfunkci
PUSHA ;store regs AX,CX,DX,BX,SP,BP,SI,DI (16B) / uloz registry![](https://www.cnblogs.com/Images/dot.gif)
PUSH DS ;store DS (2B) / uloz DS (2B)
CMP AH,02h ;function ?= 2h - read sectors / sluzba ?= 2h - cti sektory
JE @NEW_INT13H_02H
CMP AH,03h ;function ?= 3h - write sectors / sluzba ?= 3h - pis sektory
JE @NEW_INT13H_03H
CMP AH,08h ;function ?= 8h - get drive params / sluzba ?= 8h - vrat parametry disku
JE @NEW_INT13H_08H
CMP AH,15h ;function ?= 15h - get disk type / sluzba ?= 15h - vrat typ disku
JE @NEW_INT13H_15H
ADD AH,'A' ;infoflag of unhandled function (cislo 0=A, 1=B,
) / priznak neobslouzeni funkce
JMP @NEW_INT13HEND1 ;other? jump to end and let me know / jina? preskoc na konec a dej o tom vedet
@NEW_INT13H_02H: ;INT 13h: AH=func, DL=drive, DH=H, CH=C, CL=S,
PUSH AX ; AL=S-CNT, ES:BX=buffer of calling program
MOV DI,BX ;prepare destination address ES:BX->ES:DI / priprav cilovou adresu![](https://www.cnblogs.com/Images/dot.gif)
XOR SI,SI ;we prepare linear address to SI step by step / do SI si postupne pripravime linearni adresu
AND CL,03Fh ;number of sector is only 6-bit / cislo sektoru je jen 6-bitove (cyl<=80 u FD)
DEC CL ;BIOS numbers the sectors from starting 1, we need from 0 / BIOS cisluje sektory o 1, my potebujem od 0
MOV AX,ROMDISK_SECPT;SI=LINSEC=NH*NS*C + NS*H + (S-1)
MUL DH ;AX*DH->AX (NS*H)
ADD SI,AX ;add to SI (SI=NS*H) / pricti do SI
MOV AX,ROMDISK_HEADS;there's no check of CHS validity / neprovadi se zadna kontrola parametru CHS
MOV BL,ROMDISK_SECPT;so when CHS overflow it returns invalid data from memory / takze pri prekroceni adr. rozs. vraci nesmyslna data
MUL BL ;AX*BL->AX (NH*NS)
MUL CH ;AX*CH->AX (NH*NS*C)
ADD SI,AX ;add to SI (SI=NS*H + NH*NS*C) / pricti do SI
XOR CH,CH ;prepare S to CX / priprav S v CX
ADD SI,CX ;add to SI (SI=NH*NS*C + NS*H + (S-1)) / pricti do SI
SHL SI,9 ;recalc from sectors to Bytes (SI*512) / prepocti SI ze sektoru na Byty
ADD SI,IMG_BEGIN ;prepare source offset (and add offset to image) / priprav zdrojovy offset (jeste pricti offset na image)
PUSH CS ;prepare source segment / priprav zdrojovy segment
POP DS ;set DS=CS (ROM segment with disk image / segment ROM s image disku)
POP CX ;restore number of required sectors to CX / vyber pocet ctenych sektoru do CX
SHL CX,9 ;recalc number of sectors to number of Bytes (S-CNT*512) / prepocitej pocet sektoru na Byty
REP MOVSB ;copy until CX is nonzero / kopiruj dokud CX neni nulove
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13H_03H: ;ROM disk is read-only so return errorcode AH=3 / ROM disk je read-only, takze vrat chybu AH=3
MOV BP,SP ;set BP=SP / nastav BP=SP
MOV AX,[SS:BP+24] ;precti ze zasobniku FLAG (adr=2+16+2+2+2 objem dat v zasob. nad F)
OR AX,1 ;nahod bit CARRY (SP->DS,ALL,F,IP,CS ^)
MOV [SS:BP+24],AX ;zapis ho zpet
MOV [SS:BP+17],BYTE 3 ;nastav AH v zasobniku na kod chyby 3 (adr=16+2-1=DS+ALL)
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13H_08H: ;return CHS info about ROM disk geometry / vrat informace CHS o geometrii ROM disku
MOV BP,SP ;set BP=SP / nastav BP=SP
MOV CH,ROMDISK_CYLS ;set CH to number of cylinders / nastav CH na pocet cylindru
MOV CL,ROMDISK_SECPT;set CL to number of sectors per track / nastav CL na pocet sektoru/stopu
MOV [SS:BP+13],BYTE ROMDISK_HEADS ;nastav DH v zasob. - hlavy (adr=2+16-2-2-1=DS+ALL-AX-CX-DL)
MOV [SS:BP+14],CX ;nastav CX v zasobniku (adr=2+16-2-2=DS+ALL-AX-CX)
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13H_15H: ;ROM disk is like nonchangeable diskette drive / ROM disk je jako nevymenna disketova jednotka
MOV BP,SP ;set BP=SP / nastav BP=SP
MOV [SS:BP+17],BYTE 1 ;nastav AH v zasobniku na kod chyby 0 (adr=16+2-1=DS+ALL)
MOV [SS:BP+14],WORD 0 ;set CX=0 (total drive sectors high word to 0) / nastav vyssi slovo poctu sektoru na 0
MOV [SS:BP+12],WORD ROMDISK_CYLS*ROMDISK_HEADS*ROMDISK_SECPT ;set DX=total drive sectors / nastav DX=celkovy pocet sektoru
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13HEND: ;INT 13h watcher (work in textmode only / funguje jen v textovem modu)
MOV AH,'*' ;flag of hanled function / priznak obslouzeni funkce
@NEW_INT13HEND1:
PUSH WORD 0B800h
POP DS ;set DS=B800h (segment of textmode VRAM on VGA / segment textove VRAM u VGA)
MOV [DS:79*2],AH ;write flag character to top-right corner from AH / do praveho horniho rohu obrazovky vykresli znak z AH
POP DS ;restore DS (2B) / obnov DS (2B)
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B) / obnov registry![](https://www.cnblogs.com/Images/dot.gif)
POPF ;restore flags (2B) / obnov flagy (2B)
IRET ;return from an interrupt do POP IP,CS,F (6B) / navrat z preruseni provadi![](https://www.cnblogs.com/Images/dot.gif)
;*****************************************************************************
INSTALL_NEW_INT13H: ;install new INT 13h handler / nainstaluj novou obsluhu INT 13h
PUSHA ;and write message about vector change + CRLF / a vypise hlaseni o zmene vektoru a odradkuje
PUSH ES ;store ES / uloz ES
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0) / vynuluj ES
MOV SI,13h*4 ;set SI at INT 13h IVT position / nastav SI na pozici vektoru INT 13h v IVT
MOV DI,OLD_INT13H ;set DI at free INT 85h IVT position / nastav DI na volnou pozici vektoru INT 85h v IVT
MOV CX,[ES:SI] ;load original offset of INT 13h handler from IVT to CX / nacti do CX offset puvodni obsluhy INT 13h z IVT
MOV [ES:DI],CX ;store it to other safe place in IVT / uloz ho na jine bezpecne misto v IVT
MOV DX,[ES:SI+2] ;load original segment of INT 13h handler from IVT to DX / nacti do DX segment puvodni obsluhy INT 13h z IVT
MOV [ES:DI+2],DX ;store it to other safe place in IVT / uloz ho na jine bezpecne misto v IVT
MOV [ES:DI-1],BYTE 0EAh ;opcode FAR JMP (dynamically modified instruction / dynamicky menena instrukce)
MOV [ES:SI],WORD NEW_INT13H ;set offset of new INT 13h handler / nastav offset nove obsluhy INT 13h
MOV [ES:SI+2],CS ;set segment of new INT 13h handler (current-ROM) / nastav segment nove obsluhy INT 13h (aktualni-ROM)
MOV SI,IINTSTR ;write hook INT 13h vector message / vypis zpravu o zmene vektoru INT 13h
MOV BX,0107h ;grey color, 1-times / seda barva, opakovani 1x
CALL WRITE
CALL WHEXPTR ;write original vector DX:CX / vypis puvodni vektor DX:CX
MOV SI,AROWSTR
CALL WRITE ;write / vypis ' -> '
MOV DX,CS
MOV CX,WORD NEW_INT13H
CALL WHEXPTR ;write new vector DX:CX (CS:NEW_INT13H) / vypis novy vektor DX:CX
CALL WCRLF ;newline / odradkuj
POP ES
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B) / obnov registry![](https://www.cnblogs.com/Images/dot.gif)
RET ;return / navrat
IINTSTR DB 'INT13h vector has been hooked ',0
AROWSTR DB ' -> ',0
;************** Initial code - modify carefully! / Pocatecni kod, upravujte s max. opatrnosti!
BEGIN: PUSHF ;store flags (2B) / uloz flagy (2B)
PUSHA ;store regs AX,CX,DX,BX,SP,BP,SI,DI (16B) / uloz registry![](https://www.cnblogs.com/Images/dot.gif)
PUSH ES ;store ES / uloz ES
PUSH DS ;store DS / uloz DS
MOV AX,SS ;set AX=original SS / nastav AX=puvodni SS
PUSH NEW_SS ;set new bigger stack (BIOS use default SS=0 SP=0Dxx - small) / nastav novy vetsi zasobnik![](https://www.cnblogs.com/Images/dot.gif)
POP SS ;segment
MOV BX,NEW_SP ;offset
XCHG BX,SP ;set BX=original SP / nastav BX=puvodni SP
PUSH AX ;store configuration of original stack - SS / uloz konfiguraci stareho zasobniku - SS
PUSH BX ;store configuration of original stack - SP / uloz konfiguraci stareho zasobniku - SP
;TEST FOR 1ST RUN-ROMSCAN/2ND RUN-INT19H CALL
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0, segment of IVT) / nastav ES=0, segment IVT
CMP [ES:INT19H],WORD BEGIN ;compare if offset match the BEGIN label / porovnej, shoduje-li se offset s labelem BEGIN
JNE RUN1ST ;if not it means that's 1st run-ROMSCAN / pokud ne, znamena to, ze bezime poprve-ROMSCAN
MOV AX,CS ;set AX=CS (cannot compare CS directly / CS nelze primo porovnavat)
CMP [ES:INT19H+2],AX;compare if segment match the current CS segment / porovnej, shoduje-li se segment s aktualnim CS
JNE RUN1ST ;if not it means that's 1st run-ROMSCAN / pokud ne, znamena to, ze bezime poprve-ROMSCAN
JMP BOOT ;else continue next phase at BOOT label / jinak pokracuj v dalsi fazi na labelu BOOT
;ASK FOR BOOT ROMOS
RUN1ST: CALL WCRLF ;newline / odradkuj
MOV SI,MSG1 ;prompt to press HotKey / vyzva ke stisku HotKey
MOV BX,810Fh ;white color, 1-times + CRLF / bila barva, opakovani 1x a odradkuj
CALL WRITE ;write message / vypis hlasku
MOV AH,ROMOS_MSG_DELAY ;wait / pockej
CALL DELAY
;TEST FOR SCROLLOCK ;test if HotKey was pressed / otestuj, jestli je stisknuty HotKey
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0, segment of keyboard flags / segment flagu klavesnice)
MOV AL,[ES:0417h] ;offset of keyboard flags / offset flagu klavesnice 0417h
MOV AH,AL ;store loaded value to AH / schovej si nactenou hodnotu do AH
AND AL,ROMOS_HOTKEY ;mask the HotKey / vymaskuj HotKey
CMP AL,ROMOS_HOTKEY ;if it is turned on then / je-li zaply,
JE EXIT_AND_HOOK_INT19H ;end and hook INT 19h else / skonci a hookni INT 19h, jinak
MOV [CS:0],ES ;erase 55AAxx (ES=0) ROM header, then BIOS will free this area for UMB / smaz hlavicku ROM 55AAxx (ES=0)![](https://www.cnblogs.com/Images/dot.gif)
JMP EXIT ;end without hook of INT 19h / skonci bez hooknuti INT 19h
;************** Terminating and restoring, returning controll back to BIOS ***
;************** Ukonceni, obnoveni stavu a predani rizeni zpet BIOSu *********
EXIT_AND_HOOK_INT19H:
;here you can place a code which should be executed on 1st run-during ROMSCAN
;zde je jeste mozno pridat kod, ktery se ma provest pri prvnim spusteni-ROMSCAN
; Initalise software interrupts
cli
call Initalise_int
sti
console:
MOV AL,ROMOS_HOTKEY ;load HotKey bit mask / nacti bitovou masku HotKey
NOT AL ;negate HotKey bit mask / zneguj bitovou masku HotKey
AND AH,AL ;turn off the HotKey / zhasni HotKey
MOV [ES:0417h],AH ;write keyboard flag (ES=0, see above) / zapis flag klavesnice
;HOOK INT 19h
MOV [ES:INT19H],WORD BEGIN ;put ROM module address here ,/ vlozime tam adresu ROM modulu,
MOV [ES:INT19H+2],CS;offset first, then segment / napred offset a pak segment
EXIT:
POP BX ;get BX=original SP / nacti BX=puvodni SP
POP SS ;restore SS=original SS / obnov SS=puvodni SS
MOV SP,BX ;restore SP=original SP / obnov SP=puvodni SP
POP DS ;restore DS (2B) / obnov DS (2B)
POP ES ;restore ES (2B) / obnov ES (2B)
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B) / obnov registry![](https://www.cnblogs.com/Images/dot.gif)
POPF ;restore flags (2B) / obnov flagy (2B)
%ifdef MAKE_DEBUG_COM
INT 20h ;use if compiling *.COM file / pouzij pri kompilaci .COM souboru
%else
RETF ;CBh - FAR RET
%endif
;************** Here you can place your code without risks - it can be skipped when booting
;************** Zde uz je mozno psat kod bez obav, lze ho pri bootu preskocit
BOOT: ;this code is executed after POST is finished / tento kod se uz provadi po ukonceni POST
;when INT 19h is invoked ROM area is write protected / pri volani INT19h, ROM pamet je zamcena pro zapis
jmp CODE_2;
TEXT_1 DB 'TEST INT 21H $',0
CODE_2:
push DS;
push DX;
push ax;
mov ax,TEXT_1;
mov dx,ax;
mov ax,cs;
mov ds,ax;
mov ah, 0x9;
int 21h;
pop ax
pop dx
pop ds
CALL WCRLF ;newline / odradkuj
MOV SI,MSG2
MOV BX,810Eh ;yellow color, 1-times + CRLF / zluta barva, opakovani 1x a odradkuj
CALL WRITE ;write welcome message / vypis welcome
MOV AH,20 ;20*55ms delay / pauza
CALL DELAY
CALL INSTALL_NEW_INT13H ;install new INT 13h handler / nainstaluj novou obsluhu INT 13h
CALL DELAY ;for accessing virtual ROM disk / pro pristup k virtual ROM disku
MOV SI,MSG3
MOV BX,8107h ;grey color, 1-times + CRLF / seda barva, opakovani 1x a odradkuj
CALL WRITE ;write isntall ROMDISK message / vypis isntall ROMDISK
CALL DELAY
CALL WCRLF ;newline / odradkuj
CALL WREGS ;write registers dump / vypis registry
CALL DELAY
MOV SI,MSG4
MOV BX,0107h ;grey color, 1-times / seda barva, opakovani 1x
CALL WRITE ;write Bootsector loaded at message / vypis Bootsector loaded at
MOV DX,BS_SEGMENT ;prepare segment to DX / priprav segment do DX
MOV CX,BS_OFFSET ;prepare offset to CX / priprav offset do CX
CALL WHEXPTR ;write pointer / vypis pointer
CALL WCRLF ;newline / odradkuj
MOV SI,MSG5
MOV BX,810Fh ;white color, 1-times + CRLF / bila barva, opakovani 1x a odradkuj
CALL WRITE ;write Booting! message / vypis Booting!
MOV AH,10 ;10*55ms delay / pauza
CALL DELAY
;************** Copy bootsector from virtual ROM disk at starting address ****
;************** Prekopiruje bootsector z virtual ROM disku na spousteci adresu
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0, segment BIOS data)
MOV SI,0410h ;prepare address of equipment Byte (INT11h) / priprav adresu Bytu vybaveni (INT11h)
MOV AL,[ES:SI] ;two top bits means number of drives-1 / horni dva bity udavaji pocet mechanik-1
MOV AH,BYTE ROMDISK_DRIVE ;so: any=00, A:=00, A:+B:=01 / tedy: zadna=00, A:=00, A:+B:=01
CMP AH,1 ;if we have to emulate B: drive / pokud mame emulovat jednotku B:
JNE SKIP_DRVNUPD ;else leave / jinak nech bejt
OR AL,01000000b ;number of drives is needed to be increased / je potreba zvysit pocet mechanik
MOV [ES:SI],AL ;write updated equipment Byte / zapis aktualizovany Byte vybaveni
SKIP_DRVNUPD:
PUSH WORD BS_SEGMENT ;prepare destination segment for bootsector / priprav cilovy segment pro nahrani bootsectoru
POP ES ;set ES=BS_SEGMENT / nastav ES=BS_SEGMENT
MOV DI,BS_OFFSET ;prepare destination offset for bootsector / priprav cilovy offset pro nahrani bootsectoru
PUSH CS ;prepare source segment / priprav zdrojovy segment
POP DS ;set DS=CS / nastav DS=CS
MOV SI,IMG_BEGIN ;prepare source offset - beginning of the ROMDISK image / priprav zdrojovy offset-zacatek ROMDISK image
MOV CX,512 ;1 sector=512B
REP MOVSB ;copy until CX is nonzero / kopiruj dokud CX neni nulove
MOV [ES:BS_OFFSET+BS_DRIVE_OFFSET], BYTE ROMDISK_DRIVE ;patch bootsector by drive number / patch bootsectoru podle c. drive
MOV DL,BYTE ROMDISK_DRIVE ;set bootdrive for bootsector / nastav bootdrive pro bootsector
JMP BS_SEGMENT:BS_OFFSET ;jump to beginning of bootsector copy / skoc na zacatek kopie bootsectoru
;************** Include VIRTUAL ROMDISK image / Vloz VIRTUAL ROMDISK image
IMG_BEGIN ;append binary file of romdisk image at the end / nakonec pripoj binarni soubor image disku
; incbin "romdisk.img" ;FAT12 (1x), C:7, H:1, S:18, S/CL:1, ROOTE:16
; incbin "romdusb.img" ;FAT12 (1x), C:7, H:1, S:18, S/CL:1, ROOTE:16
incbin "romd15kb.img" ;FAT12 (1x), C:7, H:1, S:18, S/CL:1, ROOTE:16
; incbin "test.img"
IMG_END
%include "txtio.inc" ;<- Print/Scan style commands
%include "console.inc" ;<- UI stuff
%include "commands.inc" ;<- Commands possible
%include "data.inc" ;<- Data (Messages variables etc)
%include "intrupt.inc" ;<- Interrupts Initalising section
%include "IntFuncs.inc" ;<- Common Interrupt functions/procedures
%include "convers.inc" ;<- Common conversion procedures.
%include "HWtests.inc" ;<- Hard ware checks/test procedures.
; Include the interrupt functions:
%include "int20.inc" ; Include the int 20 functions
%include "int21.inc" ; Include the int 21 functions
%include "int22.inc" ; Include the int 22 functions
%include "int23.inc" ; Include the int 23 functions
%include "int24.inc" ; Include the int 24 functions
%include "int25.inc" ; Include the int 25 functions
%include "int26.inc" ; Include the int 26 functions
%include "int27.inc" ; Include the int 27 functions
%include "int28.inc" ; Include the int 28 functions
%include "int29.inc" ; Include the int 29 functions
%include "int2e.inc" ; Include the int 2e functions
%include "int2f.inc" ; Include the int 2f functions
TIMES ROM_IMAGE_SIZE*1024-($-$$) db 0 ;zero padding to required length / zarovnani nulami na danou velikost
END
;************** Block diagram ************************************************
; (BEGIN)
; ___________|____________
; |store regs, old stack
|
; ~~~~~~~~~~~|~~~~~~~~~~~~
; _________|_________
; ___________________/' running 1st? `\
; | go to BOOT Y `\ (called by ROMSCAN) /'
; | ~~~~~~~~N~|~~~~~~~~~~
; | | RUN1ST:
; | __________|___________
; | |display HotKey message|
; | ~~~~~~~~~~|~~~~~~~~~~~
; | _____|_____
; | /' was HotKey`\_________________________________
; | `\ pressed? /' Y go to EXIT_AND_HOOK_INT19H |
; | ~~~~~~|~N~~~~ |
; | __________|___________ |
; | |delete 55AA ROM header| |
; | ~~~~~~~~~~|~~~~~~~~~~~ |
; | | ,----------------------'
; | | | EXIT_AND_HOOK_INT19H:
; | | ___________|____________
; | | | disable hotkey |
; | | |(exec some 1st-run code)|
; | | | hook INT 19h to ROM |
; | | ~~~~~~~~~~~|~~~~~~~~~~~~
; | `-----------------| EXIT:
; | ____________|_____________
; | |restore regs, old stack
|
; | | and RETF to BIOS |
; | ~~~~~~~~~~~~~~~~~~~~~~~~~~
; `------------->----------------,
; | BOOT: (note: this is right place for user code)
; ________________|_________________
; | display some messages |
; | install new INT13h handler |
; | look for number of FDDs |
; |copy bootsector from image to RAM |
; |patch bootdrive Byte in bootsector|
; |jump to bootsector (never return) |
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;* .-= The ROMOS Project =-. *
;* ROM Operating System 1.02 by Martin 瀍h爇 (C) 2001-2006; rayer@seznam.cz *
;* Started: 27.3.2001 *
;* Last updated: 18.3.2006 *
;* Tested on: Award BIOS 4.51PG (Octek Rhino II ZX), 6.00PG (Abit BX133-Raid)*
;* Compile with NASM (286 code), recommended segment to load: D000h *
;* Now able to boot FreeDOS from virtual ROMDISK image, see incbin at EOF *
;*****************************************************************************
;%define MAKE_DEBUG_COM ;compile as executable *.COM file / zkompiluje spustitelny *.COM soubor
%define MAKE_PCI_MODULE ;create PCI ROM module instead ISA ROM module (needed for new BIOSes) / vytvori ROM jako PCI modul misto ISA modulu (nektere nove BIOSy uz nepodporuji ISA)
ROM_IMAGE_SIZE EQU 64 ;size of ROM image in kB / velikost ROM image v kB
ROMDISK_DRIVE EQU 1 ;0=A: 1=B: 80h=C:
![](https://www.cnblogs.com/Images/dot.gif)
ROMDISK_CYLS EQU 7 ;number of cylinders of emulated drive [1-255] / pocet cylindru emulovane jednotky
ROMDISK_HEADS EQU 1 ;number of heads of emulated drive [1-255] / pocet hlav emulovane jednotky
ROMDISK_SECPT EQU 18 ;sectors per track of emulated drive [1-63] / pocet sektoru na stopu emulovane jednotky
BS_DRIVE_OFFSET EQU 24h ;offset in bootsector where boot dive number is stored / pozice v bootsektoru, kde je cislo jednotky
BS_SEGMENT EQU 0 ;address to load bootsector / adresa spousteni bootsectoru
BS_OFFSET EQU 7C00h
ROMOS_MSG_DELAY EQU 30 ;delay of MSG1 show in 55ms ticks / doba zobrazeni MSG1 v 55ms ticich
ROMOS_HOTKEY EQU 00010000b ;mask for ScrollLock key / maska pro klavesu ScrollLock
;ROMOS_HOTKEY EQU 00100000b ;mask for NumLock key / maska pro klavesu NumLock
NEW_SS EQU 04000h ;address of new stack (4000:xxxx should be free for Award BIOS)
NEW_SP EQU 0FFFFh ;adresa noveho zasobniku (oblast 4000:xxxx by mela byt v Award BIOSu volna)
INT19H EQU 19h*4 ;address in IVT for store INT 19h vector / misto v IVT pro ulozeni vektoru INT 19h
OLD_INT13H EQU 85h*4 ;address for permanent store of old INT 13h vector - INT 85h / misto pro trvale ulozeni puvodniho vektrou INT 13h
;INT 84h a 85h shuld be free, change it if collide / INT 84h a 85h by melo byt volne, v pripade kolize zmenit
%ifdef MAKE_DEBUG_COM
ORG 100h ;use if compiling .COM file / pouzij pri kompilaci .COM souboru
%else
ORG 0h ;use if compiling ROM image / pouzij pri kompilaci ROM image
DW 0AA55h ;ROM header signature / ROM hlavicka
DB ROM_IMAGE_SIZE*2;ROM size in 512B blocks, minimum 8 blocks / velikost ROM v 512B blocich, minimum 8 bloku
%endif
JMP BEGIN ;jump to begin of code / skok na zacatek kodu
DB 'CHKSUM=',0 ;reserved Byte for checksum / rezerva na korekci checksumu
%ifdef MAKE_PCI_MODULE ;need to insert additional PCI headers / je potreba vlozit pridavne hlavicky PCI
TIMES 18h-($-$$) DB 0 ;padding zeros to offset 18h / zarovnani nulami na offset 18h
DW PCIHDR ;pointer to PCI Header / ukazatel na hlavicku PCI (musi byt na offsetu 18h)
DW PNPHDR ;pointer to PnP Expansion Header / ukazatel na hlavicku PnP (musi byt na offsetu 20h)
PCIHDR: DB 'PCIR' ;PCI data structure signature / hlavicka PCI data structury
DW 10ECh ;vendor ID (must match real PCI device) / ID vyrobce (musi odpovidat existujicimu PCI zarizeni)
DW 8029h ;device ID (must match real PCI device) / ID zarizeni (musi odpovidat existujicimu PCI zarizeni)
DW 0 ;pointer to vital product data (0=none) / ukazatel na vital product data (0=nic)
DW 24 ;PCI data structure length [B] / velikost PCI data structury [B]
DB 0 ;PCI data structure revision (0=PCI 2.1)/ revize PCI data structury (0=PCI 2.1)
DB 2,0,0 ;PCI device class code (2=notwork ctrl., 0=eth.) / trida PCI zarizeni (musi odpovidat existujicimu PCI zarizeni)
DW ROM_IMAGE_SIZE*2;ROM size in 512B blocks / velikost ROM v 512B blocich
DW 0 ;revision level of code / revize kodu
DB 0 ;code type (0=x86 PC-AT) / typ kodu (0=x86 PC-AT kompatabilni)
DB 80h ;last image indicator/indikuje posledni image v ROM
DW 0 ;reserved
PNPHDR: DB '$PnP' ;PnP data structure signature / hlavicka PnP data structury (PnP BIOS spec. 1.0a str. 17)
DB 1 ;PnP structure revision / revize PnP struktury
DB 2 ;PnP structure length (in 16B blocks) / velikost PnP struktury v 16B blocich
DW 0 ;offset to next header (0-none) / offset na dalsi hlavicku
DB 0 ;reserved
DB 33h ;PnP structure checksum / kontrolni soucet PnP struktury
DD 0 ;device identifier / identifikator zarizeni
DW 0 ;pointer to manufacturer string / ukazatel na retezec vyrobce
DW 0 ;pointer to productname string / ukazatel na retezec zarizeni
DB 2,0,0 ;device class code (2=notwork ctrl., 0=eth.) / trida PCI zarizeni (musi odpovidat existujicimu PCI zarizeni)
DB 64h ;device indicators (64h - shadowable,cacheable,not only for boot,IPL device)
DW 0 ;boot connection vector (0-none)
DW 0 ;disconnect vector (0-none)
DW 0 ;bootstrap entry vector (0-none)
DW 0 ;reserved
DW 0 ;static resource info vector (0-none)
%endif
;************** Constants / Konstanty *****************************************
MSG1 DB 'Press [ScrollLock] to boot ROMOS !',0
%ifdef MAKE_PCI_MODULE
MSG2 DB 'Welcome to ROMOS ver. 1.02 PCI by Martin Rehak',0
%else
MSG2 DB 'Welcome to ROMOS ver. 1.02 by Martin Rehak (C) 2001-2006; rayer@seznam.cz',0
%endif
MSG3 DB 'ROMOS has installed virtual ROM DISK drive.',0
MSG4 DB 'Bootsector loaded at ',0
MSG5 DB 'Booting!',0
;************** Subroutines / Procedury ***************************************
DELAY: ;pause, put number of 55ms idle ticks in AH / pauza, do AH vloz pocet 55ms idle tiku
STI ;enable interrupts otherwise timer will not be updated / povol preruseni, jinak se neaktualizuje casovac
PUSH AX ;store / uloz AX
PUSH ES ;store / uloz ES
PUSHF
PUSH BYTE 0 ;segment of timer / segment casovace 0000 (opcode 6A 00 misto 68 00 00)
POP ES ;ikdyz jsme pushli jen Byte, popne se cely Word (vyssi Byte je vzdy 0)
ADD AH,[ES:046Ch] ;add ticks to required delay / k pozadovane pauze pricti aktualni pocet tiku z adresy casovace 046C
@DLY1: CMP AH,[ES:046Ch] ;compare current and required value / rovnaji se pozadovane a aktualni ?
JNE @DLY1 ;if not then repeat / kdyz ne, opakuj
POPF
POP ES ;restore ES / obnov ES
POP AX ;restore AX / obnov AX
RET ;return / navrat
;*****************************************************************************
GOTOXY: PUSH AX ;set cursor [x,y] position given in [DL,DH] / nastavi kurzor na pozici [x,y] danou [DL,DH]
PUSH BX ;[0,0] is top-left corner / [0,0] je levy horni roh
MOV AH,2 ;function number 2 / funkce cislo 2
MOV BH,0 ;videopage / videostranka
INT 10h ;execute / proved
POP BX
POP AX
RET ;return / navrat
;*****************************************************************************
WHEREXY:
PUSH AX ;get cursor [x,y] position into [DL,DH] / precte pozici kurzoru [x,y] do [DL,DH]
PUSH BX
PUSH CX
MOV AH,3 ;function number 3 / funkce cislo 3
MOV BH,0 ;videopage / videostranka
INT 10h ;execute / proved
POP CX ;waste information about cursor size / zahod informaci o velikosti kurzoru
POP BX
POP AX
RET ;return / navrat
;*****************************************************************************
WRITE: PUSHA ;write zero-terminated string from CS:IP pointer / vypis 0-ukoncene vety z CS:SI atributem v BL
PUSHF ;with every character repeated BH-times (low 7bit) / a opakovanim jednotlivych znaku BH-krat
PUSH BX ;and write CRLF if MSB of BH is 1 / a odradkuj pokud MSB BH je 1
CALL WHEREXY ;read cursor position to [DL,DH] / precti pozici kurzoru [DL,DH]
MOV AH,9 ;function write char 9h (BH=scr_num, AL=char, CX=repeat, BL=attrib) / funkce na vypis znaku 9h
XOR CX,CX ;set CH=0, CL=0
XCHG CL,BH ;repeat char. BH-times CH=0, CL=BH, BH=0 / opakovani znaku BH-krat
AND CL,7Fh ;set MSB=0, accept only 7-bit value / snuluj MSB, akceptujeme pouze 7-bit hodnotu
@WRI1: MOV AL,[CS:SI] ;load char. from zero-terminated string / nacti znak z retezce ukonceneho 0
CMP AL,0 ;if it is 0 / je-li konec - 0
JE @WRI2 ;then end / tak konec
INT 10h ;execute / proved
INC SI ;increment string index / inkrementuj index znaku ve vete
INC DL ;increment X-cursor position / inkrementuj X-ovou pozizi kurzoru
CALL GOTOXY ;set cursor to [DL,DH] (need to do myself) / nastav kurzor na [DL,DH] (musim to delat rucne)
JMP SHORT @WRI1 ;repeat / opakuj
@WRI2: POP BX ;restore BX / obnov BX
CMP BH,80h ;if BH<80h (MSB=0) skip / pokud je BH<80h (MSB=0)
JS @WRI3 ;jump to end / preskoc na konec
POPF ;else write newline / jinak odradkuj
POPA ;restore regs because WCRLF store them again / obnov registry protoze WCRLF je opet uklada
WCRLF: PUSHA ;write CRLF = newline / vypis CRLF = novy radek
PUSHF ;this subfunc. can be called out of WRITE func. / tato podfunkce muze byt volana i mimo fci WRITE
MOV AX,0E0Dh ;function 0E - write char as TTY, CR / funkce 0E - pis TTY znak, znak CR
XOR BL,BL ;paper color=0 / barva papiru=0
INT 10h ;execute / proved
MOV AL,0Ah ;char LF / znak LF
INT 10h ;execute / proved
@WRI3: POPF ;restore flags (2B) / obnov flagy
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B)
RET ;return / navrat
;*****************************************************************************
WHEXPTR:PUSH AX ;write hexa pointer DX:CX / vypis hexa pointer DX:CX
PUSH BX ;store AX,BX / uloz AX,BX
CALL WHEXW ;write segment from DX / vypis segment z DX
XCHG DX,CX ;swap CX-DX / prohod CX-DX
XOR BL,BL ;paper color=0 / barva papiru=0
MOV AX,0E3Ah ;write char : / vypis znak :
INT 10h ;via BIOS / pres BIOS
CALL WHEXW ;write offset from DX / vypis offset z DX
XCHG DX,CX ;swap back CX-DX / prohod CX-DX tak jak byly puvodne
POP BX ;restore BX,AX / obnov BX,AX
POP AX
RET ;return / navrat
;*****************************************************************************
WHEXW: XCHG DH,DL ;write hexa word from DX / vypis hexa word z DX
CALL WHEXB ;call WHEXB to write upper Byte / zavolej WHEXB na vypis horniho Byte
XCHG DH,DL ;swap DH,DL / prohod DH,DL
CALL WHEXB ;call WHEXB to write lower Byte / zavolej WHEXB na vypis dolniho Byte
RET ;return / navrat
;*****************************************************************************
WHEXB: PUSH AX ;write hexa Byte from DL / vypis hexa Byte z DL
PUSH DX
PUSHF
MOV DH,DL
AND DL,00Fh ;mask lower digit / vymaskuj dolni cislici
AND DH,0F0h ;mask upper digit / vymaskuj horni cislici
ROR DH,4 ;shift upper digit 4bits right / posun horni cislici o 4 bity vpravo
CALL @WHB1 ;write upper digit / vytiskni horni cislici
MOV DH,DL
CALL @WHB1 ;write lower digit / vytiskni dolni cislici
POPF
POP DX
POP AX
RET
@WHB1: CMP DH,0Ah ;compare if the digit is lower than 10 / porovnej, je-li cislo mensi nez 10 (0Ah)
JC @WHB2 ;if not then skip / neni-li preskoc dal
ADD DH,7 ;if yes then add 7 to get proper ASCII code / je-li, pricti 7 (rozdil ASCII kodu 'A' a '9'+1)
@WHB2: ADD DH,'0' ;add ASCII code of '0' / pricti ASCII kod '0'
MOV AH,0Eh ;write char / vypis znak
MOV AL,DH ;from AL / z AL
INT 10h ;via BIOS / pres BIOS
RET ;return / navrat
;*****************************************************************************
WREGS: PUSHA ;write register dump line and CRLF / vypis na radku registry a odradkuj
PUSH DS ;prepare all regs to stack / priprav vsechny registry do zasobniku
PUSH ES ;AX,CX,DX,BX,SP,BP,SI,DI, DS,ES,SS,CS, F
PUSH SS
PUSH CS
PUSHF
MOV CX,9 ;loop counter-9x repeat / pocitadlo smycky-9x oparuj
MOV SI,REGSTR ;prepare reg name / priprav jmeno registru
MOV BP,SP ;set BP=SP for indexing stored regs / priprav BP=SP pro indexaci ulozenych registru
@WREGS1:MOV BX,0107h ;seda barva, opakovani 1x
CALL WRITE ;write reg name / vypis jmeno registru
MOV AX,0E3Dh ;write char function, char '=' / funkce vypisu znaku, znak '='
XOR BL,BL ;paper color=0 / barva papiru=0
INT 10h ;write '=' via BIOS / vypis '=' pres BIOS
MOV DX,[SS:BP] ;load reg from stack to DX / nacti registr ze zasobniku do DX
CALL WHEXW ;write DX hexa value / vypis hexa hodnotu DX
MOV AL,' ' ;write char ' ' / vypis znak ' '
INT 10h ;via BIOS / pres BIOS
INC BP ;go up through the stack data / jdi v zasobniku na dalsi registr
INC BP
INC SI ;reg name pointer+=3 / nastav pointer na dalsi jmeno registru (+3)
INC SI
INC SI
LOOP @WREGS1 ;repeat until CX is nonzero / opakuj dokud je CX nenulove
CALL WCRLF ;newline / odradkuj
POPF ;restore regs and flag / obnov registry a flag
POP DS ;POP DS instead CS because it crashed under BOCHS
POP SS ;anyway CS was not changed during this routine
POP ES
POP DS
POPA
RET ;return / navrat
REGSTR DB 'F',0,0 ;strings with regs names / retezce s nazvy registru
DB 'CS',0
DB 'SS',0
DB 'ES',0
DB 'DS',0
DB 'DI',0
DB 'SI',0
DB 'BP',0
DB 'SP',0
;************** New INT 13h handler emulating virtual ROM disk, now supports functions 2,3,8
;************** Nova obsluha INT 13h emulujici virtualni ROM disk, nyni podporuje sluzby 2,3,8
NEW_INT13H: ;INT XX do CLI, PUSH F,CS,IP (6B) / INT XX provadi CLI, PUSH F,CS,IP (6B)
PUSHF ;store flags (2B) / uloz flagy (2B)
CMP DL,ROMDISK_DRIVE;related to our disk ? / tyka se to naseho disku?
JE @NEW_INT13H_HUB ;if yes continue below else / pokud ano, pokracuj nize, jinak
POPF ;restore flags (2B) and / obnov flagy (2B) a
JMP 0:OLD_INT13H-1 ;jump to old INT 13h handler using FAR JMP / skoc na puvodni preruseni INT 13h pomoci FAR JMP
@NEW_INT13H_HUB: ;subfunction hub / rozcestnik podfunkci
PUSHA ;store regs AX,CX,DX,BX,SP,BP,SI,DI (16B) / uloz registry
![](https://www.cnblogs.com/Images/dot.gif)
PUSH DS ;store DS (2B) / uloz DS (2B)
CMP AH,02h ;function ?= 2h - read sectors / sluzba ?= 2h - cti sektory
JE @NEW_INT13H_02H
CMP AH,03h ;function ?= 3h - write sectors / sluzba ?= 3h - pis sektory
JE @NEW_INT13H_03H
CMP AH,08h ;function ?= 8h - get drive params / sluzba ?= 8h - vrat parametry disku
JE @NEW_INT13H_08H
CMP AH,15h ;function ?= 15h - get disk type / sluzba ?= 15h - vrat typ disku
JE @NEW_INT13H_15H
ADD AH,'A' ;infoflag of unhandled function (cislo 0=A, 1=B,
![](https://www.cnblogs.com/Images/dot.gif)
JMP @NEW_INT13HEND1 ;other? jump to end and let me know / jina? preskoc na konec a dej o tom vedet
@NEW_INT13H_02H: ;INT 13h: AH=func, DL=drive, DH=H, CH=C, CL=S,
PUSH AX ; AL=S-CNT, ES:BX=buffer of calling program
MOV DI,BX ;prepare destination address ES:BX->ES:DI / priprav cilovou adresu
![](https://www.cnblogs.com/Images/dot.gif)
XOR SI,SI ;we prepare linear address to SI step by step / do SI si postupne pripravime linearni adresu
AND CL,03Fh ;number of sector is only 6-bit / cislo sektoru je jen 6-bitove (cyl<=80 u FD)
DEC CL ;BIOS numbers the sectors from starting 1, we need from 0 / BIOS cisluje sektory o 1, my potebujem od 0
MOV AX,ROMDISK_SECPT;SI=LINSEC=NH*NS*C + NS*H + (S-1)
MUL DH ;AX*DH->AX (NS*H)
ADD SI,AX ;add to SI (SI=NS*H) / pricti do SI
MOV AX,ROMDISK_HEADS;there's no check of CHS validity / neprovadi se zadna kontrola parametru CHS
MOV BL,ROMDISK_SECPT;so when CHS overflow it returns invalid data from memory / takze pri prekroceni adr. rozs. vraci nesmyslna data
MUL BL ;AX*BL->AX (NH*NS)
MUL CH ;AX*CH->AX (NH*NS*C)
ADD SI,AX ;add to SI (SI=NS*H + NH*NS*C) / pricti do SI
XOR CH,CH ;prepare S to CX / priprav S v CX
ADD SI,CX ;add to SI (SI=NH*NS*C + NS*H + (S-1)) / pricti do SI
SHL SI,9 ;recalc from sectors to Bytes (SI*512) / prepocti SI ze sektoru na Byty
ADD SI,IMG_BEGIN ;prepare source offset (and add offset to image) / priprav zdrojovy offset (jeste pricti offset na image)
PUSH CS ;prepare source segment / priprav zdrojovy segment
POP DS ;set DS=CS (ROM segment with disk image / segment ROM s image disku)
POP CX ;restore number of required sectors to CX / vyber pocet ctenych sektoru do CX
SHL CX,9 ;recalc number of sectors to number of Bytes (S-CNT*512) / prepocitej pocet sektoru na Byty
REP MOVSB ;copy until CX is nonzero / kopiruj dokud CX neni nulove
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13H_03H: ;ROM disk is read-only so return errorcode AH=3 / ROM disk je read-only, takze vrat chybu AH=3
MOV BP,SP ;set BP=SP / nastav BP=SP
MOV AX,[SS:BP+24] ;precti ze zasobniku FLAG (adr=2+16+2+2+2 objem dat v zasob. nad F)
OR AX,1 ;nahod bit CARRY (SP->DS,ALL,F,IP,CS ^)
MOV [SS:BP+24],AX ;zapis ho zpet
MOV [SS:BP+17],BYTE 3 ;nastav AH v zasobniku na kod chyby 3 (adr=16+2-1=DS+ALL)
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13H_08H: ;return CHS info about ROM disk geometry / vrat informace CHS o geometrii ROM disku
MOV BP,SP ;set BP=SP / nastav BP=SP
MOV CH,ROMDISK_CYLS ;set CH to number of cylinders / nastav CH na pocet cylindru
MOV CL,ROMDISK_SECPT;set CL to number of sectors per track / nastav CL na pocet sektoru/stopu
MOV [SS:BP+13],BYTE ROMDISK_HEADS ;nastav DH v zasob. - hlavy (adr=2+16-2-2-1=DS+ALL-AX-CX-DL)
MOV [SS:BP+14],CX ;nastav CX v zasobniku (adr=2+16-2-2=DS+ALL-AX-CX)
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13H_15H: ;ROM disk is like nonchangeable diskette drive / ROM disk je jako nevymenna disketova jednotka
MOV BP,SP ;set BP=SP / nastav BP=SP
MOV [SS:BP+17],BYTE 1 ;nastav AH v zasobniku na kod chyby 0 (adr=16+2-1=DS+ALL)
MOV [SS:BP+14],WORD 0 ;set CX=0 (total drive sectors high word to 0) / nastav vyssi slovo poctu sektoru na 0
MOV [SS:BP+12],WORD ROMDISK_CYLS*ROMDISK_HEADS*ROMDISK_SECPT ;set DX=total drive sectors / nastav DX=celkovy pocet sektoru
JMP @NEW_INT13HEND ;end without calling original INT 13h handler / konec bez volani puvodni obsluhy INT 13h
@NEW_INT13HEND: ;INT 13h watcher (work in textmode only / funguje jen v textovem modu)
MOV AH,'*' ;flag of hanled function / priznak obslouzeni funkce
@NEW_INT13HEND1:
PUSH WORD 0B800h
POP DS ;set DS=B800h (segment of textmode VRAM on VGA / segment textove VRAM u VGA)
MOV [DS:79*2],AH ;write flag character to top-right corner from AH / do praveho horniho rohu obrazovky vykresli znak z AH
POP DS ;restore DS (2B) / obnov DS (2B)
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B) / obnov registry
![](https://www.cnblogs.com/Images/dot.gif)
POPF ;restore flags (2B) / obnov flagy (2B)
IRET ;return from an interrupt do POP IP,CS,F (6B) / navrat z preruseni provadi
![](https://www.cnblogs.com/Images/dot.gif)
;*****************************************************************************
INSTALL_NEW_INT13H: ;install new INT 13h handler / nainstaluj novou obsluhu INT 13h
PUSHA ;and write message about vector change + CRLF / a vypise hlaseni o zmene vektoru a odradkuje
PUSH ES ;store ES / uloz ES
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0) / vynuluj ES
MOV SI,13h*4 ;set SI at INT 13h IVT position / nastav SI na pozici vektoru INT 13h v IVT
MOV DI,OLD_INT13H ;set DI at free INT 85h IVT position / nastav DI na volnou pozici vektoru INT 85h v IVT
MOV CX,[ES:SI] ;load original offset of INT 13h handler from IVT to CX / nacti do CX offset puvodni obsluhy INT 13h z IVT
MOV [ES:DI],CX ;store it to other safe place in IVT / uloz ho na jine bezpecne misto v IVT
MOV DX,[ES:SI+2] ;load original segment of INT 13h handler from IVT to DX / nacti do DX segment puvodni obsluhy INT 13h z IVT
MOV [ES:DI+2],DX ;store it to other safe place in IVT / uloz ho na jine bezpecne misto v IVT
MOV [ES:DI-1],BYTE 0EAh ;opcode FAR JMP (dynamically modified instruction / dynamicky menena instrukce)
MOV [ES:SI],WORD NEW_INT13H ;set offset of new INT 13h handler / nastav offset nove obsluhy INT 13h
MOV [ES:SI+2],CS ;set segment of new INT 13h handler (current-ROM) / nastav segment nove obsluhy INT 13h (aktualni-ROM)
MOV SI,IINTSTR ;write hook INT 13h vector message / vypis zpravu o zmene vektoru INT 13h
MOV BX,0107h ;grey color, 1-times / seda barva, opakovani 1x
CALL WRITE
CALL WHEXPTR ;write original vector DX:CX / vypis puvodni vektor DX:CX
MOV SI,AROWSTR
CALL WRITE ;write / vypis ' -> '
MOV DX,CS
MOV CX,WORD NEW_INT13H
CALL WHEXPTR ;write new vector DX:CX (CS:NEW_INT13H) / vypis novy vektor DX:CX
CALL WCRLF ;newline / odradkuj
POP ES
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B) / obnov registry
![](https://www.cnblogs.com/Images/dot.gif)
RET ;return / navrat
IINTSTR DB 'INT13h vector has been hooked ',0
AROWSTR DB ' -> ',0
;************** Initial code - modify carefully! / Pocatecni kod, upravujte s max. opatrnosti!
BEGIN: PUSHF ;store flags (2B) / uloz flagy (2B)
PUSHA ;store regs AX,CX,DX,BX,SP,BP,SI,DI (16B) / uloz registry
![](https://www.cnblogs.com/Images/dot.gif)
PUSH ES ;store ES / uloz ES
PUSH DS ;store DS / uloz DS
MOV AX,SS ;set AX=original SS / nastav AX=puvodni SS
PUSH NEW_SS ;set new bigger stack (BIOS use default SS=0 SP=0Dxx - small) / nastav novy vetsi zasobnik
![](https://www.cnblogs.com/Images/dot.gif)
POP SS ;segment
MOV BX,NEW_SP ;offset
XCHG BX,SP ;set BX=original SP / nastav BX=puvodni SP
PUSH AX ;store configuration of original stack - SS / uloz konfiguraci stareho zasobniku - SS
PUSH BX ;store configuration of original stack - SP / uloz konfiguraci stareho zasobniku - SP
;TEST FOR 1ST RUN-ROMSCAN/2ND RUN-INT19H CALL
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0, segment of IVT) / nastav ES=0, segment IVT
CMP [ES:INT19H],WORD BEGIN ;compare if offset match the BEGIN label / porovnej, shoduje-li se offset s labelem BEGIN
JNE RUN1ST ;if not it means that's 1st run-ROMSCAN / pokud ne, znamena to, ze bezime poprve-ROMSCAN
MOV AX,CS ;set AX=CS (cannot compare CS directly / CS nelze primo porovnavat)
CMP [ES:INT19H+2],AX;compare if segment match the current CS segment / porovnej, shoduje-li se segment s aktualnim CS
JNE RUN1ST ;if not it means that's 1st run-ROMSCAN / pokud ne, znamena to, ze bezime poprve-ROMSCAN
JMP BOOT ;else continue next phase at BOOT label / jinak pokracuj v dalsi fazi na labelu BOOT
;ASK FOR BOOT ROMOS
RUN1ST: CALL WCRLF ;newline / odradkuj
MOV SI,MSG1 ;prompt to press HotKey / vyzva ke stisku HotKey
MOV BX,810Fh ;white color, 1-times + CRLF / bila barva, opakovani 1x a odradkuj
CALL WRITE ;write message / vypis hlasku
MOV AH,ROMOS_MSG_DELAY ;wait / pockej
CALL DELAY
;TEST FOR SCROLLOCK ;test if HotKey was pressed / otestuj, jestli je stisknuty HotKey
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0, segment of keyboard flags / segment flagu klavesnice)
MOV AL,[ES:0417h] ;offset of keyboard flags / offset flagu klavesnice 0417h
MOV AH,AL ;store loaded value to AH / schovej si nactenou hodnotu do AH
AND AL,ROMOS_HOTKEY ;mask the HotKey / vymaskuj HotKey
CMP AL,ROMOS_HOTKEY ;if it is turned on then / je-li zaply,
JE EXIT_AND_HOOK_INT19H ;end and hook INT 19h else / skonci a hookni INT 19h, jinak
MOV [CS:0],ES ;erase 55AAxx (ES=0) ROM header, then BIOS will free this area for UMB / smaz hlavicku ROM 55AAxx (ES=0)
![](https://www.cnblogs.com/Images/dot.gif)
JMP EXIT ;end without hook of INT 19h / skonci bez hooknuti INT 19h
;************** Terminating and restoring, returning controll back to BIOS ***
;************** Ukonceni, obnoveni stavu a predani rizeni zpet BIOSu *********
EXIT_AND_HOOK_INT19H:
;here you can place a code which should be executed on 1st run-during ROMSCAN
;zde je jeste mozno pridat kod, ktery se ma provest pri prvnim spusteni-ROMSCAN
; Initalise software interrupts
cli
call Initalise_int
sti
console:
MOV AL,ROMOS_HOTKEY ;load HotKey bit mask / nacti bitovou masku HotKey
NOT AL ;negate HotKey bit mask / zneguj bitovou masku HotKey
AND AH,AL ;turn off the HotKey / zhasni HotKey
MOV [ES:0417h],AH ;write keyboard flag (ES=0, see above) / zapis flag klavesnice
;HOOK INT 19h
MOV [ES:INT19H],WORD BEGIN ;put ROM module address here ,/ vlozime tam adresu ROM modulu,
MOV [ES:INT19H+2],CS;offset first, then segment / napred offset a pak segment
EXIT:
POP BX ;get BX=original SP / nacti BX=puvodni SP
POP SS ;restore SS=original SS / obnov SS=puvodni SS
MOV SP,BX ;restore SP=original SP / obnov SP=puvodni SP
POP DS ;restore DS (2B) / obnov DS (2B)
POP ES ;restore ES (2B) / obnov ES (2B)
POPA ;restore regs DI,SI,BP,SP,BX,DX,CX,AX (16B) / obnov registry
![](https://www.cnblogs.com/Images/dot.gif)
POPF ;restore flags (2B) / obnov flagy (2B)
%ifdef MAKE_DEBUG_COM
INT 20h ;use if compiling *.COM file / pouzij pri kompilaci .COM souboru
%else
RETF ;CBh - FAR RET
%endif
;************** Here you can place your code without risks - it can be skipped when booting
;************** Zde uz je mozno psat kod bez obav, lze ho pri bootu preskocit
BOOT: ;this code is executed after POST is finished / tento kod se uz provadi po ukonceni POST
;when INT 19h is invoked ROM area is write protected / pri volani INT19h, ROM pamet je zamcena pro zapis
jmp CODE_2;
TEXT_1 DB 'TEST INT 21H $',0
CODE_2:
push DS;
push DX;
push ax;
mov ax,TEXT_1;
mov dx,ax;
mov ax,cs;
mov ds,ax;
mov ah, 0x9;
int 21h;
pop ax
pop dx
pop ds
CALL WCRLF ;newline / odradkuj
MOV SI,MSG2
MOV BX,810Eh ;yellow color, 1-times + CRLF / zluta barva, opakovani 1x a odradkuj
CALL WRITE ;write welcome message / vypis welcome
MOV AH,20 ;20*55ms delay / pauza
CALL DELAY
CALL INSTALL_NEW_INT13H ;install new INT 13h handler / nainstaluj novou obsluhu INT 13h
CALL DELAY ;for accessing virtual ROM disk / pro pristup k virtual ROM disku
MOV SI,MSG3
MOV BX,8107h ;grey color, 1-times + CRLF / seda barva, opakovani 1x a odradkuj
CALL WRITE ;write isntall ROMDISK message / vypis isntall ROMDISK
CALL DELAY
CALL WCRLF ;newline / odradkuj
CALL WREGS ;write registers dump / vypis registry
CALL DELAY
MOV SI,MSG4
MOV BX,0107h ;grey color, 1-times / seda barva, opakovani 1x
CALL WRITE ;write Bootsector loaded at message / vypis Bootsector loaded at
MOV DX,BS_SEGMENT ;prepare segment to DX / priprav segment do DX
MOV CX,BS_OFFSET ;prepare offset to CX / priprav offset do CX
CALL WHEXPTR ;write pointer / vypis pointer
CALL WCRLF ;newline / odradkuj
MOV SI,MSG5
MOV BX,810Fh ;white color, 1-times + CRLF / bila barva, opakovani 1x a odradkuj
CALL WRITE ;write Booting! message / vypis Booting!
MOV AH,10 ;10*55ms delay / pauza
CALL DELAY
;************** Copy bootsector from virtual ROM disk at starting address ****
;************** Prekopiruje bootsector z virtual ROM disku na spousteci adresu
PUSH BYTE 0 ;push 00
POP ES ;pop 0000 (ES=0, segment BIOS data)
MOV SI,0410h ;prepare address of equipment Byte (INT11h) / priprav adresu Bytu vybaveni (INT11h)
MOV AL,[ES:SI] ;two top bits means number of drives-1 / horni dva bity udavaji pocet mechanik-1
MOV AH,BYTE ROMDISK_DRIVE ;so: any=00, A:=00, A:+B:=01 / tedy: zadna=00, A:=00, A:+B:=01
CMP AH,1 ;if we have to emulate B: drive / pokud mame emulovat jednotku B:
JNE SKIP_DRVNUPD ;else leave / jinak nech bejt
OR AL,01000000b ;number of drives is needed to be increased / je potreba zvysit pocet mechanik
MOV [ES:SI],AL ;write updated equipment Byte / zapis aktualizovany Byte vybaveni
SKIP_DRVNUPD:
PUSH WORD BS_SEGMENT ;prepare destination segment for bootsector / priprav cilovy segment pro nahrani bootsectoru
POP ES ;set ES=BS_SEGMENT / nastav ES=BS_SEGMENT
MOV DI,BS_OFFSET ;prepare destination offset for bootsector / priprav cilovy offset pro nahrani bootsectoru
PUSH CS ;prepare source segment / priprav zdrojovy segment
POP DS ;set DS=CS / nastav DS=CS
MOV SI,IMG_BEGIN ;prepare source offset - beginning of the ROMDISK image / priprav zdrojovy offset-zacatek ROMDISK image
MOV CX,512 ;1 sector=512B
REP MOVSB ;copy until CX is nonzero / kopiruj dokud CX neni nulove
MOV [ES:BS_OFFSET+BS_DRIVE_OFFSET], BYTE ROMDISK_DRIVE ;patch bootsector by drive number / patch bootsectoru podle c. drive
MOV DL,BYTE ROMDISK_DRIVE ;set bootdrive for bootsector / nastav bootdrive pro bootsector
JMP BS_SEGMENT:BS_OFFSET ;jump to beginning of bootsector copy / skoc na zacatek kopie bootsectoru
;************** Include VIRTUAL ROMDISK image / Vloz VIRTUAL ROMDISK image
IMG_BEGIN ;append binary file of romdisk image at the end / nakonec pripoj binarni soubor image disku
; incbin "romdisk.img" ;FAT12 (1x), C:7, H:1, S:18, S/CL:1, ROOTE:16
; incbin "romdusb.img" ;FAT12 (1x), C:7, H:1, S:18, S/CL:1, ROOTE:16
incbin "romd15kb.img" ;FAT12 (1x), C:7, H:1, S:18, S/CL:1, ROOTE:16
; incbin "test.img"
IMG_END
%include "txtio.inc" ;<- Print/Scan style commands
%include "console.inc" ;<- UI stuff
%include "commands.inc" ;<- Commands possible
%include "data.inc" ;<- Data (Messages variables etc)
%include "intrupt.inc" ;<- Interrupts Initalising section
%include "IntFuncs.inc" ;<- Common Interrupt functions/procedures
%include "convers.inc" ;<- Common conversion procedures.
%include "HWtests.inc" ;<- Hard ware checks/test procedures.
; Include the interrupt functions:
%include "int20.inc" ; Include the int 20 functions
%include "int21.inc" ; Include the int 21 functions
%include "int22.inc" ; Include the int 22 functions
%include "int23.inc" ; Include the int 23 functions
%include "int24.inc" ; Include the int 24 functions
%include "int25.inc" ; Include the int 25 functions
%include "int26.inc" ; Include the int 26 functions
%include "int27.inc" ; Include the int 27 functions
%include "int28.inc" ; Include the int 28 functions
%include "int29.inc" ; Include the int 29 functions
%include "int2e.inc" ; Include the int 2e functions
%include "int2f.inc" ; Include the int 2f functions
TIMES ROM_IMAGE_SIZE*1024-($-$$) db 0 ;zero padding to required length / zarovnani nulami na danou velikost
END
;************** Block diagram ************************************************
; (BEGIN)
; ___________|____________
; |store regs, old stack
![](https://www.cnblogs.com/Images/dot.gif)
; ~~~~~~~~~~~|~~~~~~~~~~~~
; _________|_________
; ___________________/' running 1st? `\
; | go to BOOT Y `\ (called by ROMSCAN) /'
; | ~~~~~~~~N~|~~~~~~~~~~
; | | RUN1ST:
; | __________|___________
; | |display HotKey message|
; | ~~~~~~~~~~|~~~~~~~~~~~
; | _____|_____
; | /' was HotKey`\_________________________________
; | `\ pressed? /' Y go to EXIT_AND_HOOK_INT19H |
; | ~~~~~~|~N~~~~ |
; | __________|___________ |
; | |delete 55AA ROM header| |
; | ~~~~~~~~~~|~~~~~~~~~~~ |
; | | ,----------------------'
; | | | EXIT_AND_HOOK_INT19H:
; | | ___________|____________
; | | | disable hotkey |
; | | |(exec some 1st-run code)|
; | | | hook INT 19h to ROM |
; | | ~~~~~~~~~~~|~~~~~~~~~~~~
; | `-----------------| EXIT:
; | ____________|_____________
; | |restore regs, old stack
![](https://www.cnblogs.com/Images/dot.gif)
; | | and RETF to BIOS |
; | ~~~~~~~~~~~~~~~~~~~~~~~~~~
; `------------->----------------,
; | BOOT: (note: this is right place for user code)
; ________________|_________________
; | display some messages |
; | install new INT13h handler |
; | look for number of FDDs |
; |copy bootsector from image to RAM |
; |patch bootdrive Byte in bootsector|
; |jump to bootsector (never return) |
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~