Unfortunately I cant seem to get BIOS int 13h to work, I have tried many implementations including AH=02h but they always seem to fail.
Obviously I must be doing something seriously wrong. At first after switching to int 13h extensions, I wasnt checking if they were available, but I have added a check now and it always seems to say that the extensions are not available (Bochs, Qemu and Virtual Box).
I have spent many hours on this and I am hoping someone here could shed some light on the problem.
I also note that wikipedia states that the default DL value for a HDD is 0x80, but on Qemu and Bochs DL is 0x00 at boot. I have tried manually setting dl to 0x80 but still no luck.
Code: Select all
bits 16 ; We are still in 16 bit Real Mode
org 0x7c00 ; We are loaded by BIOS at 0x7C00
start:
jmp entry
BPBOEM_ID db "GRAVITY "
BPBBytesPerSector dw 0x0200
BPBSectorsPerCluster db 0x08
BPBReservedSectors dw 0x0020
BPBTotalFATs db 0x02
BPBMaxRootEntries dw 0x0000
BPBNumberOfSectors dw 0x0000
BPBMediaDescriptor db 0xF8
BPBSectorsPerFAT dw 0x0000
BPBSectorsPerTrack dw 0x0000
BPBSectorsPerHead dw 0x0000
BPBHiddenSectors dd 0x00000000
BPBTotalSectors dd 0x00000000
BPBBigSectorsPerFAT dd 0x00000000
BPBFlags dw 0x0000
BPBFSVersion dw 0x0000
BPBRootDirectoryStart dd 0x00000002
BPBFSInfoSector dw 0x0001
BPBBackupBootSector dw 0x0006
times 13 db 0 ; jmp next offset
BPBDriveNumber db 0x00
BPBSignature db 0x29
BPBVolumeID dd 0xFFFFFFFF
BPBVolumeLabel db "Gravity Vol"
BPBSystemID db "FAT32 "
entry:
cli ; clear interrupts
xor ax, ax ; null segments
mov ds, ax
mov es, ax
mov ax, 0x0 ; stack begins at 0x9000-0xffff
mov ss, ax
mov sp, 0xFFFF
sti ; enable interrupts
mov dl, 0x80
mov al, dl
call printb
; Print Entry Message
mov si, msg_init
call PrintString
; Check Int 13H Extensions Available
mov ah,0x41 ;INT 13h AH=41h: Check Extensions Present
mov bx,0xAA55 ;Must be AA55
int 0x13 ;Check extensions
jc BootNoExt ;Carry flag set, No extensions
cmp bx,0x55AA ;Is BX 55AA
jnz BootNoExt ;Nope, No extensions
; Load one sector starting at 0x01 to 0x8000
mov eax, 0x0001
mov di, 0x8000
mov cx, 0x01
call Fat32_Read_Disk
jc BootError
; Print Exit Message
mov si, msg_exit
call PrintString
jmp halt
;
; Subroutines
;
;Read_Disk - Reads sectors form disk
;In : EDX:EAX = QWORD LBA on disk to read from
; ES:DI => Location in memory to read to
; CX = Number of sectors to read
;Out: Carry on error
Fat32_Read_Disk:
pushad ;Save registers
mov DWORD [DAP_LBA_MSD],edx ;EDX = MSD of LBA
mov DWORD [DAP_LBA_LSD],eax ;EAX = LSD of LBA
mov WORD [DAP_Segment],es ;ES = Segment
mov WORD [DAP_Offset],di ;DI = Offset
mov WORD [DAP_Sectors],cx ;CX = Sectors
mov cx,0x05 ;Attempt to read disk 5 times
Fat32_Read:
mov ax,0x4200 ;INT 13h AH=42h: Extended Read Sectors From Drive
mov dl,BYTE [BPBDriveNumber] ;DL = Drive Number
lea si,[DAP_Size] ;SI = Offset if DAP
int 0x13 ;Read disk
jnc Fat32_Read_Success ;Carry clear? Return
dec cx ;Read_count--
or cx,cx ;Read_count=0?
jz Fat32_Read_Error ;Return w/ carry
xor ah,ah ;INT 13h AH=00h: Reset Disk Drive
int 0x13 ;Reset Disk
jc Fat32_Read_Error ;Carry Flag? error
jmp Fat32_Read ;Attempt to read disk again
Fat32_Read_Error:
stc ;Set the carry flag to indicate failure
Fat32_Read_Success:
popad ;Get Registers back
ret ;Return
BootError:
mov si, msg_error
call PrintString
BootNoExt:
mov si, msg_noext
call PrintString
halt:
cli ; Clear all Interrupts
hlt ; halt the system
;
; Includes
;
;%include 'asm/printstring.asm'
;%include 'asm/printhex.asm'
;Including file source for post
;*************************
; Print Functions
;*************************
PrintString:
lodsb
or al, al ; Al=cur char
jz PrintDone ; If null..bail
mov ah, 0x0E ; Next char
int 0x10 ; Print
jmp PrintString ; Loop
PrintDone:
mov ax, 0E0Dh
xor bx, bx
int 10h
mov al, 0Ah
int 10h
ret
;
; Variables
;
DAP_Size db 0x10 ;Size of packet, always 16 BYTES
DAP_Reserved db 0x00 ;Reserved
DAP_Sectors dw 0x0000 ;Number of sectors to read
DAP_Offset dw 0x0000 ;Offset to read data to
DAP_Segment dw 0x0000 ;Segment to read data to
DAP_LBA_LSD dd 0x00000000 ;QWORD with LBA of where to start reading from
DAP_LBA_MSD dd 0x00000000
;
; String Messages
;
msg_init db "[VBR] Init", 0
msg_exit db "[VBR] Exit", 0
msg_error db "[VBR] Boot Error!", 0
msg_noext db "[VBR] Not Ext int 13h!", 0
times 510 - ($-$$) db 0
dw 0xAA55
Many thanks,
Andrew