The PC Keyboard Controller

A standard AT-architecture machine will include on the motherboard the functionality of a bidirectional keyboard controller based on an Intel 8042.

Starting with the PS/2 range the mouse or pointing device was also attached to the same controller. Although it now supports the mouse as well as the keyboard the designation of keyboard controller remains. It should not be confused with any controller embedded in the [[keyboard]] which generates the scan codes.

This document refers to the keyboard controller which is part of the motherboard and which is directly accessible to the CPU via ports 0x60 and 0x64.

keyboard controller graphic

Reading and writing the controller

Before reading or writing the motherboard keyboard controller you can find out if it is ready by examining bits in the status register.

The details are below but as an aide-memoire remember that the requirements are in a sense crossed over in that bit 1 must be 0 (zero) and bit 0 must be 1 (one) before carrying out the access. Also, the bit relevant to writing two ports (both ports) is in the more significant position than the bit relevant to reading one port (just the data port).

The status register at port 0x64 can be read at any time.

Writing a byte

Before writing to either port 0x60 or port 0x64

  • check that the status register bit 1 is 0 (zero) indicating that the controller's input buffer is vacant.

Bit 1 controls writes to both ports as, architecturally, both writes end up in the same buffer in the keyboard controller. For example, if you write a byte to port 0x60 then, until the keyboard controller accepts the byte, status register bit 1 will be set to 1 (one) and both ports will effectively be blocked.

Given that there is a single input buffer how does the keyboard controller know which port the byte came from? The answer is that it sets or clears bit 3 in its status register.

Reading a byte

Before reading from port 0x60

  • check that the status register bit 0 is 1 (one) indicating that the output buffer is occupied, i.e. has a byte waiting to be read,
  • on a PS/2 Type 1 controller wait at least seven microseconds after the bit changes to 1 (one).

Then you can read the byte. Once you have read the byte the output buffer will automatically be marked as vacant.

Sending a Command

Before sending a command byte or a byte of data you must wait until the controller indicates it is ready to receive another byte.

To send a command to the keyboard controller write the first byte, i.e. the command code, to port 0x64 and any subsequent bytes of data to port 0x60. Once all bytes have been transferred the controller will execute the command.


In addition to the data and command ports which face the computer's CPU the keyboard controller has ports which face the peripherals it controls. The input port reads the serial data from the keyboard and mouse. The output port sends data to the devices and has controls for the A20 gate and the system reset line.

Common Uses

Before you read or write each byte make sure the controller is ready as described above.

Reading keyboard or mouse

If no controller command is in progress then data from the keyboard - or, on a PS/2, from the mouse - will be readable from port 0x60.

On the PS/2 check the status register bit 5 to determine whether the byte waiting to be read is from the mouse or the keyboard. If the byte is from the keyboard bit 5 will be 0 (zero). If the byte is from the pointing device the bit will be 1 (one). The AT does not support a mouse via the keyboard controller and uses that bit to indicate a transmission error.

Writing to the keyboard

If no controller command is in progress you can write a byte to the keyboard by sending it to port 0x60. No command to the motherboard keyboard controller is needed or possible in this case.

Writing to the mouse

To write a byte to the mouse send the motherboard keyboard controller the command 0xD4 and then send the byte intended for the mouse to port 0x60.


For the commands that can be sent to the controller see kbc-commands.

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License