Last month, I published 3 blog posts on how computers work on a low level from a hardware perspective. Such a low level, that we created an entire computer on breadboards. Now, you may be wondering how do we interact with a computer? Well, you already know how computers execute instructions to process values in memory and you’ve probably used a keyboard and mouse before… But, how does a computer accept and process inputs from keyboards and mice?
Not All Input Devices are Equal
Two Ways of Input
Since the dawn of modern computing (as far back as the 1950s), we have had generally two methods of handling user input. Interrupts and device polling. Both of these methods can be used to receive user inputs, even though they are very different from a hardware and software perspective.
Interrupts
Interrupts (or at least hardware ones) are a way for devices to tell the CPU that they have something for it which it needs to process. A device that uses interrupts basically says to the CPU: “Hey! Stop what you’re doing. I have data for you” and the CPU pauses whatever it is doing, processes the input, and then continues execution right where it stopped. How rude of the device…
The CPU doesn’t have to waste any time to check if there is any new data. It is just interrupted whenever something is ready for it to process. And when it is interrupted, it executes an interrupt handler. After that, it returns to whatever it was doing.
A pseudo-implementation in which the CPU processes data from an interrupt-based device may be something like this:
//Interrupt Handler
handleInput()
{
//Load the data and process it
}
//Define handleInput() as an interrupt handler.This is specific to AVRs. But, you get the idea.
#pragma interrupt_handler handleInput
int main()
{
doStuff(); //The CPU doesn't care about anything as long as it isn't interrupted
}
Well, now you may be wondering: How would a device interrupt the CPU? The answer is simple: through a hardware interrupt.
Hardware Interrupts
A hardware interrupt is an electrical signal sent to the CPU via a specific pin or connection. Let’s simplify things a bit and look at the original Intel 8086 CPU’s pin-outs.
We can see pin 18 labelled as INTR
which is short for interrupt (sometimes also labelled as INT
). The input device would send a HIGH
signal to pin 18 to interrupt the CPU. Depending on the application, the developer would have already implemented the handler for the device and that handler would be executed.
The NMI
pin also exists, which stands for Non-maskable Interrupt. But, let’s just not get into that today, ok?
Polling
Devices that use polling, on the other hand, are a bit more polite. They wait for the CPU to check whatever the device has for it. The CPU in this case would keep asking the device: “Do you have something for me? Huh? Pls reply” and the device would then send whatever data it has. This data could be a result of the user typing something on a keyboard, moving the mouse, etc…
This whole process is rather wasteful for the CPU as it keeps wasting time to check if the device has anything for it to process. However, it is much cheaper to implement.
A pseudo-implementation where the CPU is polling a device, would be kind of like this:
int main()
{
doStuff();
/*
The CPU would waste some cycles here to check on the device
even if the device has nothing useful going on
*/
if (somethingToProcess)
{
//Load the data and process it
}
doMoreStuff();
}
Common Connectors
USB
USB is a very commonly-used example of a protocol which uses polling. Devices which are connected via USB are polled regularly to check if the device has anything to send over.
We are ignoring the software side of things here. Things are a bit different when it comes to software, and sometimes USB events are labelled as “interrupts” due to how software treats them. Even though, physically, USB connections are always polled.
Almost every peripheral you buy these days will probably be using USB. Especially, after the introduction of the type C connector. And why not? It is convenient, easy to plug in and out, cheap to implement, and hot-pluggable, which means you can plug/unplug your USB device anytime.
The only downside of USB is that it uses polling instead of interrupts. In theory, that makes it slower compared to other interrupt-based connectors. How slow though? Does it even matter? In short, not really. For the long(er) answer, continue reading!
You can watch the following video to understand on a low level how USB works.
PS/2
PS/2 on the other hand, although not as popular nowadays due to the use of USB being more prevalent, still exists and was very popular up until USB took over in the late 1990s/early 2000s.
It uses interrupts to communicate with the system and requires virtually no special drivers whatsoever. Pretty much almost any PS/2 keyboard or mouse you will connect to your computer will just work out of the box. That is, if you have a PS/2 port.
If that’s the case, why don’t we all use PS/2? Well, if you’ve ever used them, you’ll probably know why. The connector isn’t really easy to plug/unplug, and is also very bulky compared to modern USB. They also aren’t hot-pluggable.
PS/2 Ports?
Image Credit: Wikimedia Commons by Jud McCranie
Well, they are still being used by some people as they argue that they are “better” and faster than USB. For example, some professional gamers still use PS/2 keyboards as they are relatively faster compared to USB. Another reason is mostly how PS/2 ports are very simple and work as soon as the computer starts. They can help greatly in debugging systems that are failing to start. As sometimes, USB wouldn’t work in those cases.
Even as of 2022 and 2023, some top of the line motherboard manufacturers still include dedicated PS/2 ports.
You can watch the following video to understand on a low level how PS/2 works.
Which is better?
None. You can use either. Both connectors have their pros and cons, use whatever suits your use case.
The summary is that PS/2 is in theory slightly faster than USB. On the other hand, USB is much more convenient to use with features like being hot-pluggable and being able to use USB ports for any device (not just keyboards and mice). However, CPUs these days are way faster than you can imagine. An interrupt from a keyboard or polling a USB keyboard really shouldn’t be much of a concern at all.
If you have issues with your computer, especially with USB drivers or controllers, then using a PS/2 keyboard may just be your thing. Or at least temporarily, until you have things figured out. Also, I read somewhere that some people still use PS/2 for security purposes and disable USB completely since PS/2 is strictly used for keyboard and mouse input and can’t be used for any other purposes.
This could be a good idea? I’m really not sure about how effective this is. But, it may make sense if all you need for a specific machine is a keyboard and mouse. Using PS/2 allows you to disable USB, which in turn disabled USB drives and bad USB devices or “Rubber Duckies”. And please, don’t get me started on creating a “Rubber Ducky” using PS/2 because PS/2 isn’t even hot pluggable so you’d have to restart the whole system and then… yeah… just forget it.
Most people just use USB for convenience, even professional gamers that care about the tiniest of delays. I definitely am using USB, at least. I really wouldn’t want to use PS/2 again. It’s one of the old technologies that I never really miss.
One time as a child, I bent the pins on my favourite PS/2 keyboard and since then I haven’t been fond of connectors with exposed pins. (Yes, I am looking at you, VGA)
Thanks for reading! I hope you enjoyed reading this blog post. If you did, please share it with your friends who enjoy interrupting their CPUs.