# Adding keyboard support

Writing an OS is great fun, but instead of only printing stuff to the screen, it would be better if we could interact with the user, right?

In the next chapters we will see how to interact with keyboard, and get the user input.

The topics we are going to cover are:

* [Handling the keyboard interrupt](10_Keyboard_Interrupt_Handling.md) The first thing to do is to properly handle the keyboard generated by the IRQ, and understand when, they are generated, how to understand the event type.
* [Writing a driver](11_Keyboard_Driver_Implementation.md) How to translate a scancode to a character, and print it on the screen/logs

## Keyboard Overview

Before proceeding further let's have a quick high level overview of a keyboard.

We'll be dealing with the PS/2 keyboard in this chapter, which communicates with us via the PS/2 controller in our system. Other keyboard running over more complex protocols (like USB) can be used to emulate a PS/2 keyboard, but this requires support from the device and motherboard. The good news for laptop developers is that most laptop keyboards (and trackpads) are actually still using PS/2 internally.

Keyboards can accept several commands and generate interrupts, placing a byte on the communication port.

Whenever a key is pressed or released the keyboard sends some data to us via the communication port, this data is called a *scancode*, and is composed of one or more bytes.

There are three different sets of scancodes available (1, 2 and 3). Sets 1 and 2 are the most widely supported, set 3 was a later addition and is rare to see in the wild. Set 1 was the first, and a lot of software at the time was hardcoded to support it. This prevented an interesting problem when set 2 was introduced later on, and then standardized as being the default set for a keyboard. The solution was to keep set 2 as the default, but the ps/2 controller will translate set 2 scancodes into set 1 scancodes. To ensure compatability with older software, and confuse future os developers, this feature is enabled by default.

The scancode that is generated when a key is pressed is called the **make** code, while the scancode generated by a key release is callee the **break** code.

In order to develop our keyboard driver we'll need to do the following:

* First identify the scancode set used by our keyboard, this is important because it is going to influence our mapping.
* Enable the Keyboard IRQ, how to do this depends on whether we are using the PIC or the IOAPIC, but in both cases we need to set up a handler and unmask the relevant entry into an IRQ table.
* Read the scancode byte.
* Once we have the full scancode, store it in a buffer along with any extra info we might need (any currently pressed modifiers).

Translating the scancode to a printable character is not in the list above, we'll touch on how to do this briefly, although it's not really related to the keyboard driver.
