How to handle keyboard in real mode through BIOS interrupts?
If you want to use high-level BIOS keyboard services, rather than handling the keyboard interrupts yourself, then INT 16h
is what you want.
INT 16h
with AH=00h
or 10h
will block waiting for a keypress (returns ASCII result in AL
); use AH=01h
or 11h
to query whether a keypress is available first if you want to avoid blocking (returns immediately with ZF
clear if a key is available, or set if not). See e.g. here, or here (or Google "INT 16h" for more).
You can handle IRQ 1 (mapped to interrupt 9 by the x86 controller) and read the keys from port 60h
.
See http://inglorion.net/documents/tutorials/x86ostut/keyboard/.
Minimal GAS boot sector BIOS example
When you enter a character, it gets printed to the screen.
main.S
.code16
.global _start
_start:
cli
/* Set SS and SP as they may get used by BIOS calls. */
xor %ax, %ax
mov %ax, %ss
mov $0x0000, %sp
/* Get input to %al */
mov $0x00, %ah
int $0x16
/* Print the input from %al */
mov $0x0E, %ah
int $0x10
hlt
.org 510
.word 0xaa55
Compile and run:
as -o main.o main.S
ld --oformat binary -o main.img -Ttext 0x7C00 main.o
qemu-system-i386 -hda main.img
GitHub upstream.
Tested on Ubuntu 14.04 AMD64, Binutils 2.24, QEMU 2.0.0 and on real hardware Lenovo Thinkpad T400.