Question

From the OSDev page on the A20 line, the code for enabling A20 is given as:

enable_A20:
    cli

    call    a20wait
    mov     al,0xAD
    out     0x64,al

    call    a20wait
    mov     al,0xD0
    out     0x64,al

    call    a20wait2
    in      al,0x60
    push    eax

    call    a20wait
    mov     al,0xD1
    out     0x64,al

    call    a20wait
    pop     eax
    or      al,2
    out     0x60,al

    call    a20wait
    mov     al,0xAE
    out     0x64,al

    call    a20wait
    sti
    ret

a20wait:
    in      al,0x64
    test    al,2
    jnz     a20wait
    ret


a20wait2:
    in      al,0x64
    test    al,1
    jz      a20wait2
    ret

a20wait waits on the input buffer and a20wait2 on the output buffer.

From what I understood, writing to/reading from 0x64 access the command/status register and not the buffer registers.

Then why are there are so many waits on the input/output buffers ? Shouldn't there be one on the output buffer before reading the status register, and one on the input buffer after writing the new command byte ?

I tried disabling all other wait calls except the two I mentioned in the previous paragraph and it worked fine. But I'm curious as to why they are there. Is there some other reason ?

Was it helpful?

Solution

The A20 gate control signal is provided by another processor. Traditionally an 8042 micro-controller, one of its output port pins drives the signal. That micro-controller was intended to handle the keyboard interface, it had a unused output pin so the IBM engineers that designed the AT decided to cut hardware cost and control the A20 gate signal with it.

The interface between the main processor and that microcontroller is a very simplistic one, just two 8-bit ports. I/O address 0x60 is the data port, 0x64 is the command/status port.

The 8042 executes its own program, completely independent from the main processor. So some care is required to talk to it, the handshaking has to be done in software. You can only write something after you made sure that the 8042 obtained the previous command and executed it. And only read something after you made sure that the 8042 wrote to the data port. Spinning on the input and output buffer status bits is thus required to let the 8042 catch up.

Removing that spinning may work in an emulator. Pretty unlikely to work correctly on real hardware, you could get lucky. There's completely no point in risking it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top