Why does my BIOS app stop responding after a single keyboard interrupt?

0

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:

enter image description here

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

enter image description here

x86
nasm
interrupt
bootloader
bios
asked on Stack Overflow Aug 17, 2017 by Dmitry • edited Aug 17, 2017 by Cody Gray

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0