⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 romos.asm

📁 bios嵌入DOS操作系统,可以先编译romos.asm制作成BIN文件,加载至BIOS的ISA模块.另外还有制作工具
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	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...
	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
	PUSH	ES		;store ES / uloz ES
	PUSH	DS		;store DS / uloz DS
;TEST FOR 1ST RUN-ROMSCAN/2ND RUN-INT19H CALL
%ifdef HOOK_INT19H		;only if we want to hook INT 19h otherwise skip this / jen pokud chceme hooknout INT 19h
	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
%endif
;ASK FOR BOOT ROMOS

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -