d a v i d j w a l l i n g . c o m

Custom Operating System Series

Part Five : Enabling Keyboard Input

This article is part five in a series introducing system software concepts for Intel x86 or compatible processors in protected mode. In this series we are developing a simple protected mode operating system in assembly language. We are using the Netwide Assembler (NASM) to assemble our code and VMware Player as our test platform.

In our first four articles, we configured VMware Player to launch a virtual machine that loaded a boot sector from a floppy disk image file, called our boot sector code which searched the disk image file for an operating system program, loaded that program into memory and called it, which configured a 32-bit operating system kernel, entered protected mode and transfered control to a task.

In this article, we will extend our interrupt-handling logic to accept keyboard input. The code we add will translate keyboard scan codes that arrive on the keyboard interrupt. The scan code values and translated ASCII codes will be displayed in an operator information area at the bottom of the screen. Later articles in this series will extend this keyboard input handling by providing an API to get keyboard events for the current task.




1. Additional Equates

Just as in our last article, this article also introduces several new symbolic constants that define ASCII encodings used by the program. EASCIICASE and EASCIICASEMASK are used to help distinguish between ASCII capital and lower-case alphabetic characters. Some keyboard scan codes are also specifically defined because their values will be tested in the keyboard interrupt handler. Finally, a set of keyboard flags are defined to track the state of certain keys (ctrl, alt, shift, etc.). Also, we define ECONOIAROW as the row where the operator information area appears.










2. Update to Structures

In our last article, we introduced a very simple structure to define operating system variables. This article adds several new fields to this structure to capture the keyboard status and scan code stream.






3. Keyboard Interrupt Handler

Our keyboard interrupt handler in the last article was simply a placeholder. Now we introduce code to respond to the keyboard hardware interrupt, capture and translate keyboard scan codes.










4. New Kernel Functions

This article adds the kernel functions SetKeyboardLamps, WaitForKeyInBuffer, WaitForKeyOutBuffer, PutConsoleOIAShift, PutConsoleOIAChar, and PutConsoleHexByte.












Now with these functions and the new keyboard interrupt handler, the program updates the operator information area at the bottom of the screen withe keyboard scan code values shown as hexadecimal values in the lower left corner and the corresponding ASCII value of the key in the center. In addition, indicators show in the operator information area the status of shift, control and alt keys.






Conclusion

In this article we have introduced code that handles the keyboard interrupt, translates keyboard scan codes into their ASCII equivalents, updates internal keyboard status fields and displays to the console, in an operator information area, the most recent scan code, ASCII code and the status of shift, control, alt and lock keys. In our next article, we will expand on this code, adding a message queue to collect keyboard and other events for the current task. We will also demonstrate how the console task can retrieve events for the task from this queue.




Program Notes

Here is a link to the entire listing of the code and data from this lab.

Program Listing

Revised 10 October 2014