Hi,
Just a couple little things...
It's probably a good idea to count the number of times the BIOS returns an error for "floppy_reset:", just like you do for "floppy_read:".
In "LBAtoCHS:" you can divide by a value in memory (which prevents messing with BX). This makes it easier to change the boot sector code for other disk formats.
For the floppy read code you are updating the destination address with "add bx, WORD [BytesPerSector]", which works for now but when you need to load more than 64 KB it will overflow. Rather than changing the offset you could change the ES segment register - that way you could load until you run out of memory. The instruction "call $" is a bug (infinite recursion causing stack overflow), and there's nothing after "endread:" - not sure if this is correct or if there should be be a "ret" after it. You don't set CX to the number of sectors to load, so I'm assuming that this is done by the calling code. There's also no need to use the "loop" instruction and "dec cx; jz endread" - you'd only load half the sectors as CX is decreased twice. AX (the LBA address) isn't set either, but is used for setting ES so you'll accidentally start loading at sector number 0 (I assume you'd prefer to start with sector number 1, the sector after this boot code).
IMHO it's a good idea to tell the user something went wrong rather than using "jmp $" (I left the code to display an error message up to you). Also, by putting all of the values that specify the disk format together at a known offset these values can be changed by other software (for e.g. the "format" command could set them). That way the same boot code can be used for any floppy disk formats (e.g. 1.2 MB disks) and for booting from hard drive (as long as the LBA address and absoluteTrack don't overflow) - this is similar to what DOS does (the "BIOS Parameter Block", which doesn't actually have anything to do with the BIOS).
Combining all of this results in the following:
Code: Select all
sectorsPerTrack dw 18
headsPerDisk dw 2
ParagraphsPerSector dw 512/16
absoluteTrack db 0
absoluteSector db 0
absoluteHead db 0
BootDrv db 0
floppy_reset:
mov di,3
retryReset:
mov ah, 0
int 13h
or ah, ah
jz floppy_read
sub di,1
jnz retryReset
jmp displayError
LBAtoCHS:
push dx
xor dx,dx
div word [sectorsPerTrack]
inc dx
mov [absoluteSector], dx
xor dx,dx
div word [headsPerDisk]
mov [absoluteTrack], dx
mov [absoluteHead], ax
pop dx
ret
;Read Sectors
;
;Input
; ax = starting sector number (LBA)
; cx = number of sectors to read
floppy_read:
mov bx, 0x0100
mov es, bx
main:
mov di, 5
sectorloop:
push ax
push cx
call LBAtoCHS
mov ah, 02
mov al, 01
mov ch, BYTE [absoluteTrack]
mov cl, BYTE [absoluteSector]
mov dh, BYTE [absoluteHead]
mov dl, BYTE [BootDrv]
xor bx,bx
int 0x13
pop cx
pop ax
jnc success
sub di,1
jnz sectorloop
jmp displayError
success:
mov bx,es
add bx, WORD [ParagraphsPerSector]
mov es,bx
inc ax
loop main
ret???
There might still be bugs in this, but I think I got them all (and hopefully haven't introduced many more)..
Cheers,
Brendan