keyboard interrupt (untested)
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 12 Oct 2019 11:08:31 +0000 (14:08 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 12 Oct 2019 11:08:31 +0000 (14:08 +0300)
src/intr.inc
src/kbregs.inc [new file with mode: 0644]
src/keyb.asm
src/keyb.inc [new file with mode: 0644]

index 55a1c9d..ac57934 100644 (file)
@@ -1,9 +1,14 @@
 ; vi:filetype=nasm ts=8 sts=8 sw=8:
 
-%define IRQ_OFFSET     32
+PIC1_CMD       equ 020h
+PIC2_CMD       equ 0a0h
+OCW2_EOI       equ 020h
+OCW3_ISR       equ 00bh
+IRQ_OFFSET     equ 32
 %define IRQ_TO_INTR(x) ((x) + IRQ_OFFSET)
 %define INTR_TO_IRQ(x) ((x) - IRQ_OFFSET)
 
+
 %macro set_irq_vector 2
        push dword IRQ_TO_INTR(%1)
        push dword %2
@@ -45,3 +50,7 @@
 %endmacro
 
        extern idt
+
+%ifndef INTR_ASM_
+       extern set_intr
+%endif
diff --git a/src/kbregs.inc b/src/kbregs.inc
new file mode 100644 (file)
index 0000000..8b58ced
--- /dev/null
@@ -0,0 +1,26 @@
+; vi:filetype=nasm ts=8 sts=8 sw=8:
+
+KB_IRQ                 equ 1
+KB_DATA_PORT           equ 60h
+KB_CMD_PORT            equ 64h
+KB_STATUS_PORT         equ 64h
+
+KB_ACK                 equ 00fah
+KB_NACK                        equ 00feh
+KB_TEST_PASS           equ 0055h
+KB_TEST_FAIL           equ 00fch
+
+KB_STAT_OUTBUF_FULL    equ 01h
+KB_STAT_INBUF_FULL     equ 02h
+KB_STAT_SYSFLAG                equ 04h
+KB_STAT_CMD            equ 08h
+KB_STAT_ACTIVE         equ 10h
+KB_STAT_AUX            equ 20h
+KB_STAT_TIMEOUT                equ 40h
+KB_STAT_PAR_ERROR      equ 80h
+
+KB_CMD_GET_CMDBYTE     equ 20h
+KB_CMD_SET_CMDBYTE     equ 60h
+
+KB_CCB_KB_INTREN       equ 01h
+KB_CCB_KB_XLAT         equ 40h
index 5200f2a..0f1d498 100644 (file)
@@ -1,5 +1,107 @@
 ; vi:filetype=nasm ts=8 sts=8 sw=8:
+%include "intr.inc"
+%include "kbregs.inc"
 
        global kb_init
 kb_init:
-       
+       push kbintr
+       push dword IRQ_TO_INTR(KB_IRQ)
+       call set_intr
+       add esp, 8
+
+       ; 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:
+       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
diff --git a/src/keyb.inc b/src/keyb.inc
new file mode 100644 (file)
index 0000000..0a6b9a7
--- /dev/null
@@ -0,0 +1,3 @@
+; vi:filetype=nasm:
+
+       extern keystate