INT 13h AH=41h: Check Extensions Present
参数:
寄存器:
AH 41h = function number for extensions check
DL drive index (e.g. 1st HDD = 80h)
BX 55AAh
返回值:
CF Set On Not Present, Clear If Present
AH Error Code or Major Version Number
BX AA55h
CX Interface support bitmask:
1 - Device Access using the packet structure
2 - Drive Locking and Ejecting
4 - Enhanced Disk Drive Support (EDD)
INT 13h AH=42h: Extended Read Sectors From Drive
参数:
寄存器:
AH 42h = function number for extended read
DL drive index (e.g. 1st HDD = 80h)
DS:SI segment:offset pointer to the DAP, see below
DAP : Disk Address Packet
offset range size description
00h 1 byte size of DAP (set this to 10h)DAP大小:16字节。
01h 1 byte unused, should be zero,未使用,固定值0.
02h..03h 2 bytes number of sectors to be read, (some Phoenix BIOSes are limited to a maximum of 127 sectors)要读取的扇区数量。
04h..07h 4 bytes segment:offset pointer to the memory buffer to which sectors will be transferred (note that x86 is little-endian: if declaring the segment and offset separately, the offset must be declared before the segment)存储读取内容的段地址和偏移地址。
08h..0Fh 8 bytes absolute number of the start of the sectors to be read (1st sector of drive has number 0)读取扇区的绝对开始扇区号。
返回值:
CF Set On Error, Clear If No Error
AH Return Code
INT 13h AH=43h: Extended Write Sectors to Drive
参数:
寄存器:
AH 43h = function number for extended write
AL bit 0 = 0: close write check,
bit 0 = 1: open write check,
bit 1-7:reserved, set to 0
DL drive index (e.g. 1st HDD = 80h)
DS:SI segment:offset pointer to the DAP
返回值:
CF Set On Error, Clear If No Error
AH Return Code
INT 13h AH=48h: Extended Read Drive Parameters
参数:
寄存器:
AH 48h = function number for extended_read_drive_ Parameters
DL drive index (e.g. 1st HDD = 80h)
DS:SI segment:offset pointer to Result Buffer, see below
Result Buffer
offset range size description
00h..01h 2 bytes size of Result Buffer (set this to 1Eh)
02h..03h 2 bytes information flags
04h..07h 4 bytes physical number of cylinders = last index + 1 (because index starts with 0)
08h..0Bh 4 bytes physical number of heads = last index + 1 (because index starts with 0)
0Ch..0Fh 4 bytes physical number of sectors per track = last index (because index starts with 1)
10h..17h 8 bytes absolute number of sectors = last index + 1 (because index starts with 0)
18h..19h 2 bytes bytes per sector
1Ah..1Dh 4 bytes optional pointer to Enhanced Disk Drive (EDD) configuration Parameters
which may be used for subsequent interrupt 13h Extension calls (if supported)
返回值:
CF Set On Error, Clear If No Error
AH Return Code
Remark: Physical CHS values of function 48h may/should differ from logical values of function 08h.
小例子:
ORG 7C00H
JMP SHORT VBR_START ; 跳过数BPB
NOP
bsOEM_NAME DB 'RDLBA1.0' ; 8 bytes
bsBYTES_PER_SECTOR DW 00h ; 2
bsSECTORS_PER_CLUSTER DB 00h ; 1
bsRESERVED_SECTORS DW 00h ; 2
bsFAT_COPIES DB 00h ; 1
bsROOT_DIR_ENTRIES DW 00h ; 2
bsTOTAL_DISK_SECTORS DW 00h ; 2
bsMEDIA_DESCRIPTOR DB 00h ; 1
bsSECTORS_PER_FAT DW 00h ; 2
bsSECTORS_PER_TRACK DW 00h ; 2
bsSIDES DW 00h ; 2
bsHIDDEN_SECTORS_HIGH DW 00h ; 2
bsHIDDEN_SECTORS_LOW DW 00h ; 2
bsTOTAL_NUM_SECTORS DD 00h ; 4
bsPHYS_DRIVE_NUMBER_1 DB 00h ; 1
bsPHYS_DRIVE_NUMBER_2 DB 00h ; 1
bsBOOT_RECORD_SIG DB 29h ; 1
bsVOL_SERIAL_NUM DD 1F61A800h ; 4
bsVOLUME_LABEL DB 'NO NAME ' ; 11 bytes
bsFILE_SYSTEM_ID DB 'FAT16 ' ; 8 bytes
TIMES 2 DB 00
DISK_ADDRESS_PACKET:
dapSIZE DB 10H ; 1
dapUNUSED DB 00H ; 1
dapSECTORS_READ DW 0000H ; 2
dapOFFSET DW 0000H ; 2
dapSEGMENT DW 0000H ; 2
dapLLLBA DW 0000H ; 2
dapLHLBA DW 0000H ; 2
dapHLLBA DW 0000H ; 2
dapHHLBA DW 0000H ; 2
;[========================================================================]
; Disk Parameter Block
;
; The DPB is located in the ROM BIOS at the address pointed to by 0078h.
; The 11 bytes starting from START are overwritten at COPY_DPB with the
; DPB (7C3E-7C48). This is what the area looks like *after* the copy
; at COPY_DPB:
;[========================================================================]
;dpbCONTROL_TIMERS DW 00h ; 2
;dpbMOTOR_OFF_DELAY DB 00h ; 1
;dpbBYTES_PER_SECTOR DB 00h ; 1
;dpbSECTORS_PER_TRACK DB 00h ; 1
;dpbGAP_LENGTH DB 00h ; 1
;dpbDATA_LENGTH DB 00h ; 1
;dpbFORMAT_GAP_LENGTH DB 00h ; 1
;dpbFORMAT_FILLER_BYTE DB 00h ; 1
;dpbHEAD_SETTLE_TIME DB 00h ; 1
;dpbMOTOR_START_TIME DB 00h ; 1
;[========================================================================]
; Following the copy of the DPB, more information is copied over
; previously existing code:
;[========================================================================]
;cpbsHIDDEN_SECTORS_HIGH DW 00h
;cpbsHIDDEN_SECTORS_LOW DW 00h
;
; DB 00h
; DB 00h
; DB 00h
;
;cpbsHIDDEN_SECTORS_HIGH DW 00h
;cpbsHIDDEN_SECTORS_LOW DW 00h
;[========================================================================]
; Here is the start of the boot sector code. Note that the first 11
; bytes will be destroyed later on as described above.
;[========================================================================]
VBR_START:
CLI ; Disable interrupts
XOR AX,AX ; AX=0000
MOV SS,AX ; SS=0000
MOV SP,7C00H ; 初始化堆栈; SP grows in decrements
PUSH SS
POP ES ; ES=0000
MOV BX,0078H ; 1EH 号中断向量的地址为0000:0078H;指向磁盘驱动器参数表指针
; The address of the ROM BIOS disk table is 78h. (INT 18h). ROM routine copies this address during cold boot initialization.
LDS SI,[SS:BX] ; 0000:0078H SI points to ROMBIOS table The source for the copy
PUSH DS
PUSH SI
PUSH SS
PUSH BX
MOV DI,0600H ;VBR_START ; VBR_START ; Address of destination
MOV CX,000BH ; 11字节 ; Size of area to copy (Disk parameters) Set direction flag to inc Move 11 bytes from the disk parameter area to overlap with the start of the code at 7D3E (save space?)
CLD
REP MOVSB ; DS:SI-11->ES:DI(0000:7C3E)
PUSH ES
POP DS ; DS=ES ; DS=0000
MOV BYTE [DI-02H],0FH ; At this point, DI points to 7C49, one byte after the last thing copied. Destination operand is dpbHEAD_SETTLE_TIME.
; 7C47 = 0F
MOV CX, [bsSECTORS_PER_TRACK]
MOV [DI-07H],CL ; Destination operand is dpbSECTORS_PER_TRACK.
MOV [BX+02H],AX ; (AX)=0000H,修改1EH号中断向量(段址) ; Destination operand is dpbMOTOR_OFF_DELAY.
MOV WORD [BX],0600H ; VBR_START ; 修改1EH号中断向量(偏移),这样1EH号中断向量的内容为0000:7C3EH,指向新的磁盘参数表
; The code at 7C6B installs the new Int 1E into the interrupt table at 0000:0078. At 7C68, AX is 0. START is the offset for the new INT 1E.
STI
;功能00H 功能描述: 磁盘系统复位
;AH=00H DL=驱动器,00H~7FH:软盘;80H~0FFH:硬盘
;CF=0——操作成功,AH=00H,否则,AH=状态代码,参见功能号01H中的说明
INT 13H ; 用新的磁盘参数表来复位磁盘; Reset drives (AX=0000)
JC DSP_MSG ; 出错则转出错处理
;------------------------------------------------------;----------------
XOR AX,AX
CMP [bsTOTAL_DISK_SECTORS],AX ; BPB_ToSec16FAT32必须等于0,FAT12/FAT16为扇区总数。
JZ LBL00000084
MOV CX,[bsTOTAL_DISK_SECTORS]
MOV [bsTOTAL_NUM_SECTORS],CX ; BPB_ToSec32
LBL00000084:
MOV AL, [bsFAT_COPIES] ; FAT表个数 2
MUL WORD [bsSECTORS_PER_FAT] ; * FAT 表所占的扇区数 40
ADD AX, [bsHIDDEN_SECTORS_HIGH] ; + 隐藏的扇区数H
ADC DX, [bsHIDDEN_SECTORS_LOW] ; + 隐藏的扇区数L 63
ADD AX, [bsRESERVED_SECTORS] ; + 保留扇区数L 1
ADC DX, BYTE +00H ; + 保留扇区数H
MOV [0612H],AX ; ROOT扇区NOL
MOV [0614H],DX ; ROOT扇区NOH
MOV [060BH],AX
MOV [060DH],DX
MOV AX, 20H ; 32字节
MUL WORD [bsROOT_DIR_ENTRIES] ; 根目录中目录的个数
MOV BX, [bsBYTES_PER_SECTOR] ; 每扇区字节数
ADD AX, BX ;
DEC AX ; ( 32 * n + 511 ) / 512
DIV BX ; 根目录所占扇区数
ADD [060BH],AX ; FILE扇区NOL
ADC WORD [060DH],BYTE + 00H ; FILE扇区NOH
;------------------------------------------------------;----------------
MOV DX, [0614H]
MOV AX, [0612H]
MOV WORD [dapOFFSET], 0800H ; 0000:0800 ROOTDIR
MOV [dapLHLBA], DX
MOV [dapLLLBA], AX
MOV WORD [dapSECTORS_READ], 01H
CALL WORD READ_SECTOR ; ES:BX0000:0800 = ROOTDIR
MOV BX, 01H
JC DSP_MSG ; Error? Print message and reboot.
;------------------------------------------------------;----------------
MOV DI,0800H
MOV CX,000BH ; 11 characters in DOS filename.
MOV SI,7DE6H ; 1E6:DUBENJU SYS
REPE CMPSB
MOV BX, 02H
JNZ DSP_MSG ; First file in root dir is not IO.SYS? Print error.
LEA DI,[0820H] ; NEXT:MSDOS SYS
MOV CX,0BH ; 11 characters in DOS filename.
REPE CMPSB ; Is second file in root MSDOS.SYS?
JZ RD_DBJ_SYS ; Yes? Then continue on.
MOV BX, 03H
DSP_MSG:
MOV SI,MSG1 ; MSG
CALL WORD WRITE_STR
XOR AX,AX
INT 16H
POP SI
POP DS
POP WORD [SI]
POP WORD [SI+02H]
INT 19H
SHW_ERR_MSG:
POP AX
POP AX
POP AX
JMP SHORT DSP_MSG
RD_DBJ_SYS:
MOV AX,[081AH]
DEC AX
DEC AX
MOV BL,[bsSECTORS_PER_CLUSTER] ; bsSECTORS_PER_CLUSTER
XOR BH,BH
MUL BX
ADD AX,[060BH]
ADC DX,[060DH]
MOV WORD [dapOFFSET], 7F00H ; DOS loading buffer
MOV [dapLHLBA], DX
MOV [dapLLLBA], AX
MOV WORD [dapSECTORS_READ], 00FFH
CALL WORD READ_SECTOR
MOV BX, 04H
JC DSP_MSG
; MOV CH,[7C15H] ; bsMEDIA_DESCRIPTOR
; MOV DL,[7C24H] ; bsPHYS_DRIVE_NUMBER_1
; MOV BX,[060BH]
; MOV AX,[060DH]
; JMP FIN
JMP WORD 07F0H:0000H ; Transfer to ROM BIOS
;[========================================================================]
; Procedure WRITE_STRING
;[========================================================================]
; Parameters:
; SI: Address of string to write
WRITE_STR:
LODSB
OR AL,AL
JZ RETURN_PRC
MOV AH,0EH
MOV BX,07H
INT 10H
JMP SHORT WRITE_STR
READ_SECTOR:
MOV AX, 00H
MOV DS, AX
MOV AH, 42H
MOV DL,[7C24H] ;(DL)=驱动器号
MOV SI, DISK_ADDRESS_PACKET
INT 13H
RETURN_PRC:
RET
MSG1 DB 0DH,0AH,'Non-System disk or disk error'
DB 0DH,0AH,'Replace and press any key when ready'
DB 0DH,0AH,00H
FIN:
JMP FIN
times 486 - ( $ - $$) DB 0
FILE1 DB 'DUBENJU SYSMSDOS SYS'
times 2 DB 0
DB 55H
DB 0AAH
(完蛋)