; 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
%endmacro
extern idt
+
+%ifndef INTR_ASM_
+ extern set_intr
+%endif
--- /dev/null
+; 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
; 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