Thanks to John Elliott, a ROM dump of the PS/2 Model 50 keyboard controller (an 8742 chip) is now available. The IBM PC/AT keyboard controller (KBC) ROM has been analyzed earlier.
So what exactly changed between the PC/AT and the first generation PS/2 systems? The obvious difference is the addition of auxiliary device (typically mouse) support. However, since the PS/2 architecture is noticeably different from the PC/AT, how many other changes are there in the keyboard controller? The answer is “fewer than one might think”.
A word of warning: The following is based on an early analysis of the ROM; there may be errors and/or omissions. It is a work in progress.
The biggest non-difference between the PC/AT and PS/2 Model 50 keyboard controller is the controller chip itself. It’s still the same Intel 8042 (8742) microcontroller. It is obvious that IBM integrated the controller into the system in a very similar way, and reused significant chunks of the ROM. But there certainly were changes.
In the PC/AT, host interrupts are handled via the automatic 8042 mechanism; the
EN FLAGS instruction is used to generate an interrupt via pin P24 when the output buffer (OBB) is written. Enabling and disabling interrupts is handled by toggling the P24 bit. Very simple and convenient.
In the PS/2, that is no longer adequate because two different interrupts are used. Therefore,
EN FLAGS is not used at all and interrupts are triggered manually. When the OBB is written, the KBC must know whether it’s keyboard or auxiliary data. It checks the appropriate interrupt enable bit in the KBC command register, updates the status register (to indicate that the OBB is full and whether it contains auxiliary or keyboard data), and writes the OBB. If the relevant interrupt is enabled, the KBC sets the corresponding bit in output port P2, executes a
NOP instruction to insert a small delay, and then clears both interrupt bits in P2.
It’s not obvious whether updating the status register before writing the OBB is a bug or a feature. It is likely responsible for a warning in the PS/2 Technical Reference: “wait 7 microseconds from the buffer-full indication [...] before reading the output buffer.”
Just like in the PC/AT, pin P24 is used for the keyboard interrupt (IRQ 1). Pin P25 is newly used for the auxiliary interrupt (IRQ 12). Perhaps unexpectedly, edge triggered interrupts are still generated by the KBC, even though the PS/2 uses level triggered interrupts. To this end, the PS/2 motheboard must implement a latch for IRQ 1 and IRQ 12 in order to emulate level-triggered interrupts. The latch is cleared by a read from port 60h, which means that typical keyboard interrupt handlers run unmodified.
This also raises the question whether the PS/2 KBC was deliberately designed to be upwardly compatible with the PC/AT KBC (the real difference being the ROM!). It might be possible to use a PC/AT with the PS/2 KBC ROM and vice versa.
The KBC RAM locations 50h-7Eh are used to store a password, if one is installed. If the byte at location 50h is zero, the password is disabled.
The Model 50 KBC command set is upwardly compatible with the PC/AT, as long as one considers only documented commands. The undocumented diagnostic dump command (ACh) is gone, likely due to ROM space constraints.
New commands were added to handle keyboard password locks. This functionality was meant to be used by the system BIOS (since the KBC had no non-volatile storage for the password).
And obviously new commands were also added to handle auxiliary devices. To a large extent these mirror the keyboard control command. Much of the code to handle auxiliary devices is a modified copy of the keyboard code. That makes sense since auxiliary devices use the same protocol, only communicate over different KBC pins.
At offset 1A8h there are a few bytes of apparently unreachable code. This code performs a variable timeout controlled by RAM location 35h.
To be continued…