; vi:filetype=nasm ts=8 sts=8 sw=8: %include "intr.inc" %include "kbregs.inc" global kb_init kb_init: set_irq_vector KB_IRQ, kbintr ; enable keyboard interrupt mov eax, KB_CMD_GET_CMDBYTE call send_cmd call read_data or eax, KB_CCB_KB_INTREN ; set the INTREN flag push eax mov eax, KB_CMD_SET_CMDBYTE call send_cmd pop eax call send_data ; flush the read buffer call wait_read jz .skipread call read_data .skipread: unmask_irq KB_IRQ ret ; keyboard interrupt handler kbintr: pusha in al, KB_DATA_PORT cmp al, 0e0h jnz .noext mov byte [key_ext], 1 jmp .eoi .noext: ; keystate[keycode] address in ebx xor ebx, ebx mov bl, al add ebx, keystate ; determine if it's a press or release test al, 80h jz .press ; key release mov byte [ebx], 0 jmp .eoi .press: ; key press mov byte [ebx], 1 .eoi: cli end_of_irq KB_IRQ popa iret %macro iodelay 0 xor al, al times 7 out 80h, al %endmacro wait_write: push eax push ecx mov ecx, 32768 .loop: in al, KB_STATUS_PORT test al, KB_STAT_INBUF_FULL jz .break iodelay dec ecx jnz .loop .break: pop ecx pop eax ret wait_read: push eax push ecx mov ecx, 32768 .loop: in al, KB_STATUS_PORT test al, KB_STAT_OUTBUF_FULL jnz .break iodelay dec ecx jnz .loop .break: pop ecx pop eax ret ; expects command in al send_cmd: call wait_write out KB_CMD_PORT, al ret read_data: send_data: section .data align 4 key_ext: db 0 global keystate keystate: times 256 db 0