jwt27 / djgpp-cvs

git mirror of cvs.delorie.com:/cvs/djgpp
http://www.delorie.com/djgpp/cvs.html
GNU General Public License v2.0
10 stars 7 forks source link

Fix faulty keyboard handler #12

Open kjliew opened 3 months ago

kjliew commented 3 months ago

https://www.vogons.org/viewtopic.php?p=818225#p818225 Patch

--- orig/src/libc/go32/exceptn.S        2002-12-21 21:08:39.000000000 -0800
+++ ./exceptn.S 2020-01-18 18:37:27.397176800 -0800
@@ -337,6 +337,15 @@
        je      6f
        orb     $2,%ah  /* If RShift is set, set LShift as well */
 6:
+        movb    %ah,%al
+       andb    %cs:___djgpp_sigint_mask, %ah   /* Mask off irrelevant bits */
+       cmpb    %cs:___djgpp_sigint_key+1, %ah  /* Test for SIGINT */
+        je      60f
+        movb    %al,%ah
+       andb    %cs:___djgpp_sigquit_mask, %ah  /* Mask off irrelevant bits */
+       cmpb    %cs:___djgpp_sigquit_key+1, %ah /* Test for SIGQUIT*/
+       jne     Lkbd_chain
+60:
        inb     $0x60,%al                       /* Read the scan code */
 99:
        movb    %ah,%bh                         /* Save KB status */

Fix toolchain without recompiling by replacing the object file within libc

$ i686-pc-msdosdjgpp-gcc -c -o exceptn.o exceptn.S
$ i686-pc-msdosdjgpp-ar ru /opt/djgpp/i686-pc-msdosdjgpp/lib/libc.a exceptn.o

Affected DJGPP apps (for eg. Vim) can then be rebuilt to replace the faulty keyboard handler.

jwt27 commented 3 months ago

Hi!

I did see your post on Vogons a while back, but never tried the patch as I didn't notice the problem myself. IMO, this is a QEMU bug, as port 0x60 should return the same scan code for at least ~600 µs after the IRQ. This is limited by the keyboard clock speed, and QEMU does not emulate this exactly.

For reference, see Dosbox-X code where this delay is properly implemented: https://github.com/joncampbell123/dosbox-x/blob/85eec1f6160575246dd1cb43f4b0c9a30749cc88/src/hardware/keyboard.cpp#L381

That said, having this workaround in djgpp is probably a good idea. But I do try to keep this repo only a mirror of upstream CVS - please send your patch to the mailing list first: djgpp@delorie.com (you may need to subscribe in order to post). It's not completely dead, as evidenced by some recent commit activity. But if there is no interest there I can merge it on the jwt27 branch.

kjliew commented 3 months ago

In real hardware, I reproduced the problem on Acer Aspire One laptop with DOS32 VIM. I presume some KBCs just don't model the delay anymore. It has not been something that spec out explicitly for PC compatibles.

I am not interested in dealing with the mailing list. It is OK to keep it here to achieve the purpose of archiving outside of VOGONS. Anyone is free to post it on the mailing list and drive it to closure. Thanks.

jwt27 commented 3 months ago

I was reading the qemu code and found this commit: https://github.com/qemu/qemu/commit/d1e45668d2128b064e2cd8080ca662f9b0f33bd6

Looks like a fix is available in recent versions (since v6.1.0), but this is not enabled by default, and requires a flag: -global i8042.kbd-throttle=on

I also checked the VirtualBox code but it doesn't seem to have such delay, so the problem may occur there too with multi-byte scan codes (arrow keys, etc).

In real hardware, I reproduced the problem on Acer Aspire One laptop with DOS32 VIM. I presume some KBCs just don't model the delay anymore. It has not been something that spec out explicitly for PC compatibles.

I forget some people run DOS on more recent hardware :)

On a real 8042 it is fairly well specified, the output buffer is a separate register that is updated atomically with the "output buffer full" flag. It never contains any intermediate value, and the observed delay is just a consequence of the slow serial interface. I expect there will be some TSRs out there that also rely on this.

I found this disassembly of the original IBM KBC firmware, it's an interesting read: https://github.com/Halicery/8042/blob/main/8042_PS2_INTERN.TEXT

Of course none of this necessarily applies to clone controllers, USB emulation, etc.

Ringdingcoder commented 2 weeks ago

FWIW, VirtualBox used to have the problem, but it disappeared a long time ago (and I no longer run modern versions of it, so I cannot attest to the quality of the last decade’s worth of VirtualBox releases).

https://www.virtualbox.org/ticket/58 The qemu thread referenced there was this: http://lists.gnu.org/archive/html/qemu-devel/2009-08/msg01182.html