Subject: mbr_bootsel timer code incorrect.
To: None <port-i386@netbsd.org>
From: David Laight <David.Laight@btinternet.com>
List: port-i386
Date: 11/27/2001 00:07:17
I've found a bug in the sbin/fdisk/mbr_bootsel/mbr_bootsel.S timeout code.

If you specify a timeout of 1801 or larger (in fdisk) then the timer
expires immediately.

I'm fairly sure that the problem is either that the:
    movw_mem_ax(timeout)
instruction will sign extend the 16bit value to 32 bits
or that the:
    cmpl    %rax,%edx
instruction is only doing a 16 bit compare and is followed by
a signed jump.

The code can also be simplified - saving some vital bytes!
If the sums are correctly done modulo 2^16 the high part of the
counter can be ignored.

I haven't test this - anyone who has done it before or feels brave?
(I suppose you can boot from CD to put the MBR back...)
But I think the following is right - assuming I've not mistyped it.

    xorb    %ah,%ah
    int     $0x1a
    movl    %edx,%edi
3:
    movb    $1,%ah
    int     $0x16
    jnz     4f
    xor     %ah,%ah
    int     $0x1a
    subl    %edi,%edx
    movw_mem_ax(timeout)
    cmpl    %eax,%edx
    jb      3b

Hard to count how many bytes this saves...

I don't have a system that can reference the CVS tree.....
Anyone fancy the dirty work?

    David