VOGONS


First post, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

I don't remember if I have shared this information somewhere. Since this place has folks interested in DJGPP DOS32 programming, let archive the info here.

At some point in time when DJGPP improved its libc for being more POSIX compliant by adding programmable keys for SIGQUIT and SIGINT, it broke the keyboard handling by reading the scancode every time regardless if the STATUS byte matched the keys. The old keyboard handler only read the scancode when the STATUS byte matched the key. So then every DJGPP compiled codes would potentially exhibit erroneous keyboard behavior such as the bug below.
https://bugs.launchpad.net/qemu/+bug/1574246

For eg. VIM editor DOS32 version is unusable after version 5.8 because of this issue. Key strokes were frequently dropped or recorded twice.

The patch fixes the issue and restores the behavior of old keyboard handler.

--- 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 */

The toolchain can be fixed easily by replacing the object file in libc with GNU ar.

$ 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

There is no need the rebuild the toolchain. Once the toolchain is fixed, DJGPP application can be recompiled to replace the faulty keyboard handler.

Reply 1 of 6, by kpedersen

User metadata
Rank Newbie
Rank
Newbie

I just made an account to say thanks for this! (I promise I am not a bot 😉)

I have been wondering what was causing this infuriating issue with Qemu. Since nothing had been fixed for ~10+ years I assumed it wasn't going to. I didn't know whether to blame SeaBios, Qemu or the DPMI systems.

I applied your patch, compiled it (using DJGPP's gcc 9.3 on DOS itself), added it to the libc archive and built vim (7.3) as normal. I am actually amazed vim built so smoothly. I chose 7.3 because I knew a binary existed for that so the makefile hasn't yet rotted. But I am tempted to look into getting some later ones to compile for the sheer "thrill" of it.

Some additional things: I notice that a number of existing software has this issue which unfortunately cannot be rebuilt (closed source, terrible build systems, etc). One of particular note is Quarterdeck's DESQview. Does this mean that was originally built using the faulty DJGPP or was your patch indeed a workaround for something still broken in qemu?

If DJGPP is really at fault, I wonder if it would be possible to create a patch utility to inject the fix into the binary itself? What are your views on this? Especially now I can build Vim with and without the fix, I could probably isolate the binary diff quite easily.

I notice DJGPP is still under active development. (The compiler is getting heavier and slower every day!). It is now on GCC 9.x which is very new. Have you considered contacting them with your fix so it can go upstream?

Either way, thanks again. I am off to fiddle with a perfectly working Vim on Qemu after... 4 years on and off looking for a solution 😉

Reply 2 of 6, by kpedersen

User metadata
Rank Newbie
Rank
Newbie

(my second post is a double post. Still definitely not a bot!)

Because it is a slight faff to compile, I thought it might be useful for others (all those millions of DOS/Vim users out there!) for me to upload compiled binaries with this fix.

In the .zip you will find two versions of Vim.

One simply compiled (via make -f make_djg.mak) requiring csdpmi*b or other DPMI server to run as with the original.
And another in the pmode folder using pmode/dj embedded in requiring no DPMI server. So like an "all in one" bundle.

Prepared via:

exe2coff origvim.exe vim.bin
copy /b pmodstub.exe+vim.bin vim.exe

Attachments

  • Filename
    vim-7.3-dosfix.zip
    File size
    2.01 MiB
    Downloads
    83 downloads
    File license
    Public domain

Reply 3 of 6, by kjliew

User metadata
Rank Oldbie
Rank
Oldbie

Very cool 😉

I am a VIM user and use VIM on QEMU DOS VM, too. Used to be a VIM hater in my younger life, but slowly grew to love it eventually for being a text warrior in the world of WYSIWYG glamour.

I do not find it easy to upstream the fix as it touches the low-level libc core of the toolchain which hasn't been updated since 2008 and no maintainers. I believe DJGPP is only active to keep up with the GNU software. Feel free to take it if you wish.

When nobody complained about faulty keyboard behavior, then it just indicates that DOS software is dying.... It happens on real hardware, too, but not all. Perhaps some old hardware KBCs are more tolerant than newer firmware-based re-implementation of 8042.

Reply 4 of 6, by latalante

User metadata
Rank Newbie
Rank
Newbie

This trivial SeaBIOS patch is effective.

--- a/src/hw/ps2port.c
+++ b/src/hw/ps2port.c
@@ -401,6 +401,7 @@ handle_09(void)
dprintf(1, "ps2 keyboard irq but found mouse data?!\n");
goto done;
}
+ i8042_command(I8042_CMD_KBD_DISABLE, NULL);
v = inb(PORT_PS2_DATA);

if (!(GET_LOW(Ps2ctr) & I8042_CTR_KBDINT))

Qemu with the new bios can be run like this.

qemu-system-x86_64 -bios ../seabios/out/bios.bin

Reply 5 of 6, by darry

User metadata
Rank l33t++
Rank
l33t++
latalante wrote on 2021-02-18, 15:46:
This trivial SeaBIOS patch is effective. […]
Show full quote

This trivial SeaBIOS patch is effective.

--- a/src/hw/ps2port.c
+++ b/src/hw/ps2port.c
@@ -401,6 +401,7 @@ handle_09(void)
dprintf(1, "ps2 keyboard irq but found mouse data?!\n");
goto done;
}
+ i8042_command(I8042_CMD_KBD_DISABLE, NULL);
v = inb(PORT_PS2_DATA);

if (!(GET_LOW(Ps2ctr) & I8042_CTR_KBDINT))

Qemu with the new bios can be run like this.

qemu-system-x86_64 -bios ../seabios/out/bios.bin

Just to be clear, this patch for Seabios is meant as a workaround for the keyboard handler issues experienced in DOS software compiled with "buggy" recent DJGPP versions when running said DOS software in hypervisor that uses Seabios as it BIOS (among which Qemu), correct ?

Reply 6 of 6, by latalante

User metadata
Rank Newbie
Rank
Newbie
darry wrote on 2021-02-18, 17:38:

Just to be clear, this patch for Seabios is meant as a workaround for the keyboard handler issues experienced in DOS software compiled with "buggy" recent DJGPP versions when running said DOS software in hypervisor that uses Seabios as it BIOS (among which Qemu), correct ?

It's not even that good. I can only confirm its effectiveness when using Qemu 2.8.1 with Seabios 1.10.2 or 1.14.0. For Qemu 5.2, this patch for SeaBIOS doesn't change anything.