It was thus said that the Great Michael B. Brutman once stated:
On the PCjr, if I touch the keyboard the machine screeches. And not its
normal polite 'Go away I'm busy beep' either. The keyboard on this
machine is wired to NMI instead of IRQ1, so it has higher priority than
timer 0. The NMI interrupt is used to read the keyboard serial data
stream and it uses timer 1 of the 8253 to record when the first bit is
received. Timer 1 isn't used elsewhere, so that is fine. If there is
an error in the serial data it sounds the system beeper, so timer 2 can
get altered at any time making timer 2 unusable.
Any keypress causes the screeching. First, I can't figure out why the
NMI handler is having a problem deserializing the keyboard even if timer
0 is running fast. All interrupts are disabled, so this should be
business as usual. Yet any keypress causes it to go nuts. Any ideas?
(As a side effect the timings reported by ping start to look bad - the
NMI is definitely taking up precious time.)
Second, the machine becomes unstable. I don't care about getting bad
timings because of keypresses, but this is far worse ..
If I disable the NMI interrupt everything is perfect - but then you
can't hit Ctrl-Break to stop pinging. (Yes, I have Ctrl-Break captured,
and it works if I don't mess with timer 0 at all.) I don't want to have
to shut off the keyboard entirely if there is a possibility of figuring
out why the NMI is causing problems with a fast timer 0.
Ideas?
If you have the IBM PCjr tech ref handy, it does contain the BIOS listing,
but if you don't, the NMI routine itself reads the timer (see below for the
sequence) to time the bit stream coming from the keyboard (no hardware
assist here, so it's the CPU reading the bits directly). Further more, for
each code received from the keyboard, the NMI routine calls INT $48 (about
five and a half pages of code) to translate the code to an IBM PC keyboard
compatable code, stuffs that value (or values if a multi-byte sequence is
needed) into port $60, then directly calls INT $09.
And if there's an error during any of this, a sound routine called, which
manipulates port $61 to toggle the speaker directly (using software loops to
control pitch and duration).
The code sequence to read the timers goes
mov al,40h
out 43h,al ; translated from symbolic constant
nop
nop
in al,41h
mov ah,al
in al,41h
xchg al,ah
I hope this helps some.
-spc (The PCjr was my second computer ... )