On Fri, Mar 12, 2010 at 11:24:27PM +0000, Jamie Lokier wrote:
The DOS coding method brought up in this thread, resulting in two reads of port 0x60, is quite common. It works on all real PCs, and correct emulation must handle it.
I'm not sure if reading port 0x60 is supposed to clear the status bit immediately or not. The problem might be QEMU's hardware emulation clearing the 8042 status bit too quickly, or it might be SeaBIOS should not check the status bit - in which case it probably fails on _real_ hardware too, when running these old DOS TSRs and similar programs.
It would be good if someone can check the behaviour of real hardware.
On my epia-cn, a read of port 0x60 immiediately clears the OBF flag of the status register.
The GHOST program which drops/corrupts keys on qemu seems to work fine on my epia-cn.
[...]
In other words, 8042 emulation _should_ permit port 0x60 to be read multiple times, but if sufficient time elapses without the irq being acknowledged, it should drop the byte and deliver the next one.
The ps2 port can use up to a 16.6Khz clock, and it takes 11 clock cycles to read a byte. The next keyboard byte only starts being transmitted after the first byte is dequeued, so a second read of the data port shouldn't return a new byte in less than 660us.
However, I don't see anything that would prevent a mouse data byte being read on the second read. So, this still seems very sloppy to me.
Unfortunately, in QEMU _guaranteeing_ that the guest has had some guest time to process the irq before the timeout is a bit tricky, if QEMU is delayed by host scheduling.
As a hack, I suppose qemu could check the time each inb(0x60) and return old data if a new irq hasn't been observed and 660us hasn't elapsed since the first read.
-Kevin