OSD Home

- # - Assembly-language keyboard functions using the BIOS
- # - C-language keyboard functions using the BIOS
- # - Keyboard input without the BIOS
- # - 8042 and 8048 registers and command bytes
- # - Keycaps and scancodes for different keyboard types
- # - Code snippets
- # - Links
- REPORT BUGS OR ERRORS IN THIS DOCUMENT

## Assembly-language keyboard functions using the BIOS

For information on using BIOS keyboard functions, see INT 16h in Ralf Brown's interrupt list: http://www.cs.cmu.edu/afs/cs/user/ralf/pub/WWW/files.html

## C-language keyboard functions using the BIOS

Both DJGPP and Turbo C `getch()` and `kbhit()` call DOS (not BIOS) interrupts. They will not work for OS code. With both compilers, you may use `int86()` to access BIOS INT 16h. As with text output, 32-bit code requires a V86 mode monitor (VMM) to call 16-bit BIOS routines.

## Keyboard input without the BIOS

The keyboard itself contains an 8048 microprocessor. There is a second microprocessor (an 8042) on the motherboard. The keyboard produces one or more bytes (the make code) when a key is pressed, and zero, one, or more bytes (the break code) when a key is released. An IRQ 1 interrupt is generated for each byte. The keyboard interrupt handler must read the make or break code (collectively called the scan code) from I/O port 60h. Additional IRQ 1 interrupts are inhibited (masked) until you read port 60h.

You may also use polling to read from the keyboard without using interrupts (see code snippets below).

Make and break codes for each key depend on the scancode set:

- Scancode set 1: IBM PC XT
- Scancode set 2: IBM PC AT
- Scancode set 3: IBM PS/2

For exact scancode values, # - see below.

Only scancode set 2 is widely supported and relatively free of bugs. However, the 8042 can be (and usually is) programmed to convert set 2 scancodes from the keyboard to set 1. The 8042 also handles some non-keyboard functions, such as resetting the CPU, controlling the A20 gate, and communicating with a PS/2 mouse.

## 8042 and 8048 registers and command bytes

## Keycaps and scancodes for different keyboard types

104-key US keyboard | Set 1 scancodes | Set 2 scancodes | Set 3 scancodes
105-key British keyboard (from Tim Robinson and Beth Stone) | Set 1 scancodes | Set 2 scancodes | Set 3 scancodes
104-key German keyboard (this is guesswork) | Set 1 scancodes | Set 2 scancodes | Set 3 scancodes

## Keyboard code snippets

Keyboard driver code (DOS; DJGPP or Turbo C or Watcom C)

Polled keyboard input routine (does not use interrupts):

    read_kbd:
            in al,64h       ; read status byte
    	and al,01h      ; wait for OBF==1
            jz read_kbd
            in al,60h       ; read scancode byte
            ret

Enable A20 gate and verify it's on: see bootstrap code snippets

Turn on all three keyboard LEDs:

                    call kbd
    		mov al,0EDh     ; 8048 command byte to set LEDs
    		out 60h,al
    		call kbd
    	; b0 is ScrollLock, b1 is NumLock, b2 is CapsLock
    		mov al,07h
    		out 60h,al

    	    ...

    	kbd0:   jmp short $+2
    		in al,60h
    	kbd:    jmp short $+2
    		in al,64h
    		test al,1
    		jnz kbd0
    		test al,2
    		jnz kbd
    		ret

Reset the PC:

    	; Warning: this function may not work unless A20 is enabled
            ; See http://my.execpc.com/~geezer/osd/gotchas/index.htm#a20_reboot
    	;
    	; set the POST reset word at 0040h:0072h
    	; 0000h for cold boot, 1234h to bypass memory test (warm boot)
    		mov ax,40h
    		mov es,ax
    		mov ax,0
    		mov [es:72h],ax

            ; bit b0 of the 8042 'Output Port' drives the CPU reset line
    	; pulse it low to reset the system
    		call kbd	; kbd routine above
    		mov al,0FEh	; 8042 command byte to pulse Output Port pin
    		out 64h,al

## Links

http://homepages.cwi.nl/~aeb/linux/kbd/scancodes.html
http://panda.cs.ndsu.nodak.edu/~achapwes/PICmicro/keyboard/atkeyboard.html
http://www.nondot.org/sabre/os/articles/HumanInterfaceDevices/

## TO DO

    - converting scan codes to ASCII, Unicode, UTF, etc.

## REPORT BUGS OR ERRORS IN THIS DOCUMENT