Here's the function (real mode):
Code: Select all
;; Read specified 16-bit LBA to ES:BX
;; ax = LBA
;; bx = offset
;; cl = numSectors
;; es = segment
readDisk:
;; save the sector count
push cx
;; LBA -> CHS
xor dx, dx
div word [BPB_SecPerTrk]
inc dx
mov cl, dl
xor dx, dx
div word [BPB_NumHeads]
mov ch, al
mov dh, dl
sal ah, 6
or ah, cl
mov cl, ah
;; retrieve sector count
pop ax
;; zero error counter
xor ah, ah
.tryLoop:
;; save error counter
;; This seems to be the problematic push
push ax
;; set BIOS parameters
mov ah, 0x02
mov dl, [BPB_DriveNumber]
;; and do the call
int 13h
;; retrieve error counter
pop ax
;; if(error)
jc .readError
;; else
ret
.readError:
;; increment error counter
inc ah
;; check if we've reached 4 tries
and ah, 0x04
;; if not
jz .tryLoop
;; else
returnC:
;; set error flag and return
stc
ret
Code: Select all
ax: 0001
bx: 0000
cx: 0011
dx: 0101
si: 7BEE
di: 0003
sp: 7BF8
Stack:
[7BF8] 7DB5 <-- return Addr
Code: Select all
ax: 0046
bx: 0000
cx: 0011
dx: 0100
si: 7BEE
di: 0003
sp: 7BF6
Stack:
[7BF6] 0001 <-- Shouldn't be here!
[7BF8] 7DB5 <-- return Addr
Edit:
Note to self: Load destination segment before trying to write there.
I think I was overwriting the IVT, and since I didn't disable interrupts it screwed something up. My OS still crashes, but it finishes the function under the same conditions as before so I'm pretty sure it's something else I screwed up.
Edit 2.0: Turns out said screw up was caused by the program I was calling, not the OS itself. I just have one last feature to implement and my 512-byte OS will be done!