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

 

;*****************************************************************************
;
*               .-= 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
    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
    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
    POPF            ;restore flags (2B) / obnov flagy (2B)
    IRET            ;return from an interrupt do POP IP,CS,F (6B) / navrat z preruseni provadi

;*****************************************************************************
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
    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
    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
    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)
    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
    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) |
;
           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
posted @ 2008-10-02 01:03  BinSys  阅读(943)  评论(0编辑  收藏  举报