📄 romos.asm
字号:
;*****************************************************************************
;* .-= The ROMOS Project =-. *
;* ROM Operating System 1.03 by Martin 瀍h爇 (C) 2001-2007; rayer@seznam.cz *
;* Started: 27.3.2001 *
;* Last updated: 15.7.2007 *
;* Tested on: Award BIOS 4.51PG (Octek Rhino II ZX-AT, 64kB ROM image) *
;* Award BIOS 6.00PG (Abit BX133-Raid, 15kB and 64kB ROM image) *
;* AMI PnP BIOS 2.53 (ASUS P5LD2, 55kB and 64kB ROM image) *
;* Compile with NASM (186 code), recommended segment to load: D000h *
;* Now able to boot FreeDOS from virtual ROMDISK image, see incbin at EOF *
;*****************************************************************************
CPU 186 ;code compatability
;%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)
%define HOOK_INT19H ;hook INT19h firts, finish POST and then boot or if commented boot directly without hooking INT19h / ma-li se napred hooknout INT19h, dokoncit POST a pak az bootovat
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
;************** ROM header ***************************************************
%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
;************** PCI ROM header ***********************************************
%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 11ABh ;vendor ID-Marvell (must match real PCI device) / ID vyrobce (musi odpovidat existujicimu PCI zarizeni)
DW 4362h ;device ID-Yukon 1Gbit eth. (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
%ifdef HOOK_INT19H
MSG2 DB 'Welcome to ROMOS ver. 1.03 PCI by Martin Rehak',0
%else
MSG2 DB 'Welcome to ROMOS ver. 1.03 PCI by Martin Rehak (C) 2001-2007; rayer@seznam.cz',0
%endif
%else
MSG2 DB 'Welcome to ROMOS ver. 1.03 by Martin Rehak (C) 2001-2007; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -