Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
LBAToCHS:
div [SectorsPerTrack]
mov cl, dl
inc cl
div [NumberOfHeads]
mov ch, al
mov dh, dl
mov dl, [DriveNumber]
ret
Something weird happened the second (the first time it worked fine) time the procedure was called. Before executing div [NumberOfHeads], CS:IP was 0000:7d74. After executing it, CS:IP was f000:ff53, pointing to an iret instruction. This is not a one-time fluke. I spent hours trying to track this down. Why does this happen? It makes no sense to me.
I didn't capture register information (Bochs debugger freezes if untouched for too long), but [NumberOfHeads] is 2 (it is a word) and ax SHOULD be 33 (decimal) but MIGHT be 31 or maybe some other number. I will see if I can grab some register info.
Actually, it is the third time it is called, but that shouldn't matter too much. I have some register information now and I was wrong about one thing. ax should not be 0, but 1. I forgot about the previous div operation. According to the debugger, ax is 1, and the registers don't change when the div is executed (it just jumps to f000:ff53). It seems like the div is failing in some way. Why would it do this?
I think you have division overflow. It's popular mistake in such routine. At least for first division you should use "double division" operation (to know why look at my post here). You can use divide routine from my boot loaders.
I don't really understand. What exactly is "division overflow"? And how would double division help?
I did see somewhere that zeroing dx beforehand would fix it. Is that true?