I am playing with BIOS on virtualbox, and I'm trying to get it to respond to keyboard events.
I want to write a BIOS app that prints '#' symbol whenever any key is pressed.
i managed to set the interrupt, but it only responds to the first time a key is hit.
I made it write '^' while it is in the event loop(where I use hlt to avoid wasting cycles).
This is what it looks like:
I managed to get it to not respond until a key is hit, but after a single response('#' is printed), it doesn't respond to any keys from then on.
Can somebody take a look and let me know what I'm doing wrong?
I am also curious what's interrupting the program so often(causing '^' to be printed at regular intervals, but very slowly).
The program below is compiled with nasm; put on MagicISO by "load boot image", then the .iso is put into a default virtualbox machine that is suggested for the system "bootloader".
bits 16
org 0x7c00
cli ; clear interrupts
; set the 4 bytes (starting at 0x00000024) to our -
; handler's segment, offset.
mov word [cs:0x24], keyboardCallback
mov word [cs:0x26], cs
sti ; enable interrupts
; event loop
nextStep:
hlt ; wait for an interrupt
call printCaretSign ; so we know if anything is happening
jmp nextStep
; intended to print # whenever a key is hit.
keyboardCallback:
call printNumberSign
iret
; prints # sign
printNumberSign:
mov al, '#'
mov ah, 0xe
mov bh, 0
int 0x10
ret
; prints ^ sign
printCaretSign:
mov al, '^'
mov ah, 0xe
mov bh, 0
int 0x10
ret
; padding and bios signature
times (510 - ($ - $$)) db 0
dw 0xaa55
altered version that no longer works;
changes:
(1) cs is set to 0 at start (2) ax, bx are pushed at start of interrupt and popped at the end.
bits 16
org 0x7c00
; set cs to 0
xor ax, ax
mov cs, ax
; clear interrupts
cli
; set the 4 byte long pointer at 0x00000024 to our callback.
mov word [cs:0x24], keyboardCallback
mov word [cs:0x26], cs
sti ; enable interrupts
; event loop
nextStep:
hlt
call printCaretSign ; so we know if anything is happening
jmp nextStep
; intended to print # whenever a key is hit.
keyboardCallback:
push bx
push ax
call printNumberSign
pop ax
pop bx
iret
; prints # sign
printNumberSign:
mov al, '#'
mov ah, 0xe
mov bh, 0
int 0x10
ret
; prints ^ sign
printCaretSign:
mov al, '^'
mov ah, 0xe
mov bh, 0
int 0x10
ret
times (510 - ($ - $$)) db 0
dw 0xaa55
version 3, works again(apparently setting cs the way above doesn't work, but same issue as v1):
bits 16
org 0x7c00
; make sure we are where we want to be.
jmp 0x0:start
start:
call printCaretSign ; are we alive?
; disable interrupts while we're setting our callback
cli
; set the 4 byte long pointer at 0x00000024 to our callback.
mov word [cs:0x24], keyboardCallback
mov word [cs:0x26], cs
; enable interrupts
sti
; event loop
nextStep:
hlt
call printCaretSign ; so we know if anything is happening
jmp nextStep
; intended to print # whenever a key is hit.
keyboardCallback:
push bx
push ax
call printNumberSign
; end of interrupt here? whatever it is?
pop ax
pop bx
iret
; prints # sign
printNumberSign:
mov al, '#'
mov ah, 0xe
mov bh, 0
int 0x10
sti
ret
; prints ^ sign
printCaretSign:
mov al, '^'
mov ah, 0xe
mov bh, 0
int 0x10
ret
times (510 - ($ - $$)) db 0
dw 0xaa55
version 4, seems to be working as expected:
bits 16
org 0x7c00
jmp 0x0:start
start:
call printCaretSign ; are we alive?
; disable interrupts while we're setting our callback
cli
; set the 4 byte long pointer at 0x00000024 to our callback.
mov word [cs:0x24], keyboardCallback
mov word [cs:0x26], cs
; enable interrupts
sti
; event loop
nextStep:
hlt
call printCaretSign ; so we know if anything is happening
jmp nextStep
; intended to print # whenever a key is hit.
keyboardCallback:
push bx
push ax
call printNumberSign
; we must read at least one byte.
in al, 0x60
; 2 magic out calls that i'm not yet
; familiar with.
mov al, 0x20
out 0x20, al
mov al, 0x20
pop ax
pop bx
iret
; prints # sign
printNumberSign:
mov al, '#'
mov ah, 0xe
mov bh, 0
int 0x10
sti
ret
; prints ^ sign
printCaretSign:
mov al, '^'
mov ah, 0xe
mov bh, 0
int 0x10
ret
times (510 - ($ - $$)) db 0
dw 0xaa55
final version
bits 16
org 0x7c00
jmp 0x0:start
start:
call printCaretSign ; are we alive?
; disable interrupts while we're setting our callback
cli
; set the 4 byte long pointer at 0x00000024 to our callback.
mov word [cs:0x24], keyboardCallback
mov word [cs:0x26], cs
; enable interrupts
sti
; event loop
nextStep:
hlt
call printCaretSign ; so we know if anything is happening
jmp nextStep
; intended to print # whenever a key is hit.
keyboardCallback:
push bx
push ax
call printNumberSign
; we must read at least one byte.
in al, 0x60
; respond to peripheral interface controller.
mov al, 0x20
out 0x20, al
pop ax
pop bx
iret
; prints # sign
printNumberSign:
mov al, '#'
mov ah, 0xe
mov bh, 0
int 0x10
sti
ret
; prints ^ sign
printCaretSign:
mov al, '^'
mov ah, 0xe
mov bh, 0
int 0x10
ret
times (510 - ($ - $$)) db 0
dw 0xaa55
User contributions licensed under CC BY-SA 3.0