Analysis of the problem
The cause is an incompatibility with many pieces in it. It is centered around what the bit 4 of 40:96
in the BIOS data area actually means. This bit is documented to mean that a "101/102 key keyboard" is connected to the computer. This is the case in my XT system. The keyboard I use has a switch (8088/80286) to choose the protocol, and in XT mode, it uses the XT keyboard protocol, but it still sends E0
prefixes like in AT mode when extended keys (like the separate cursor keys) are pressed.
The BIOS on this computer does not know about 101/102-key keyboards, and also does not use 40:96
at all, so it is zeroed out on boot. The KEYB
command included with MS-DOS 5.0 overrides the BIOS implementation of the keyboard IRQ handler (INT 09
) with a variant that does handle extended keys. If the MS-DOS 5.0 keyboard driver recognizes E0
or E1
scan codes (no matter on what machine), it automatically sets the bit indicating the presence of an "extended keyboard". This makes sense.
On the other hand, the keyboard abstraction layer in QBASIC
(and EDIT
on DOS 5 is implemented by running QBASIC
with a special command line switch) attaches more meaning to that bit. If it sees this bit set, QBASIC
implies that the keyboard BIOS is AT-like, and thus INT 16
supports the extended BIOS services 10h
, 11h
and 12h
that IBM introduced in the AT. These services are needed to make best use of the 101/102-key keyboard, as they allow (e.g.) to differentiate between the numpad cursor keys with numlock off and the separate cursor keys.
You likely can see where this is heading: As the DOS keyboard driver replaces only INT 09
, the hardware IRQ driver is now 101/102-key aware, and the awareness is indicated in the BIOS data area after the first extended key has been pressed. The BIOS API at INT 16
is still the PC-class service that only supports subfunctions 0 to 2. As QBASIC
now tries to interface to the keyboard using the unsupported subfunctionss 10h and 11h, it reads garbage inputs and seems to not draw the file to the screen while some keys (possibly scrolling keys) are pressed.
A way to fix the problem
Actually, the QBASIC keyboard abstraction layer has an internal flag to disable AT keyboard BIOS support. It does not seem to be set anywhere in QBASIC though. The configuration flags for the driver are in QBASIC.EXE
in the data segment, but as QBASIC
is compressed by Microsoft's linker (/EXEPACK
), the flag byte can not be patched. What can be patched is the instruction that checks the 101-key flag.
26 F6 06 96 04 10 test es:keybd_flags_3, 10h ; 101 key keyboard?
74 16 jz NoATSupport
8B 1D mov bx, [di+KbdState.Environment]
83 7F 18 00 cmp [bx+KbdEnvironment.InhibitATSupport], 0
75 0E jnz NoATSupport
[...]
NoATSupport:
The byte sequence 26 F6 06 96 04 10
has only one hit in QBASIC.EXE
. Patch the last byte to 00
to make sure the zero flag is always set after this instruction.