I can't take credit for this algorithm; I don't remember where I saw it first.Antti wrote:Oh no, I'm not that tough. If there is a way to significantly improve this, I'm all ears.
- Multiply the number of heads by the sectors per track. This is the sectors per cylinder.
- Check to see if the high 16 bits of the LBA are smaller than the sectors per cylinder. If the high 16 bits are greater than or equal to the sectors per cylinder, division will overflow.
- Divide the LBA by the sectors per cylinder. The quotient is the cylinder. The remainder is the sector number relative to the start of the cylinder instead of the start of the disk.
- Divide that remainder by the sectors per track. The quotient is the head. The remainder is one less than the sector. There is no overflow check for this division, since both of these results are guaranteed to fit in 8 bits. (You can use 8-bit DIV instead of 16-bit DIV here.)
- At some point, you still have to make sure the cylinder fits in 10 bits.
If you don't mind reading my painfully optimized version, it starts around line 272 of this file. (Speaking of which, I think I just spotted another optimization...)
There was a discussion, and no one provided any evidence that these forms of opcode 83 were invalid. Intel's documentation doesn't count because Intel likes to lie about which opcodes are invalid. Discussions elsewhere conclude that they must work on 8086/8088/80286 CPUs because DOS uses them, and DOS certainly works on those CPUs. (Also, the IBM PC demoscene would have noticed by now if NASM didn't work properly. Personally, I'm inclined to trust the guys who spend their free time writing code to run on IBM PC hardware.)Antti wrote:Are you referring to "and cx, strict word 0x003F"? There was a discussion...