c41a2b6316a44afa59ebc798725d8fd7e7d59806
[ld45_start_nothing] / src / keyb.asm
1 ; vi:filetype=nasm ts=8 sts=8 sw=8:
2 %include "intr.inc"
3 %include "kbregs.inc"
4
5         global kb_init
6 kb_init:
7         set_irq_vector KB_IRQ, kbintr
8
9         ; enable keyboard interrupt
10         mov eax, KB_CMD_GET_CMDBYTE
11         call send_cmd
12         call read_data
13         or eax, KB_CCB_KB_INTREN        ; set the INTREN flag
14         push eax
15         mov eax, KB_CMD_SET_CMDBYTE
16         call send_cmd
17         pop eax
18         call send_data
19
20         ; flush the read buffer
21         call wait_read
22         jz .skipread
23         call read_data
24 .skipread:
25
26         unmask_irq KB_IRQ
27         ret
28
29         ; keyboard interrupt handler
30 kbintr:
31         pusha
32         in al, KB_DATA_PORT
33         cmp al, 0e0h
34         jnz .noext
35         mov byte [key_ext], 1
36         jmp .eoi
37 .noext:
38         ; keystate[keycode] address in ebx
39         xor ebx, ebx
40         mov bl, al
41         add ebx, keystate
42
43         ; determine if it's a press or release
44         test al, 80h
45         jz .press
46         ; key release
47         mov byte [ebx], 0
48         jmp .eoi
49 .press: ; key press
50         mov byte [ebx], 1
51
52 .eoi:
53         cli
54         end_of_irq KB_IRQ
55
56         popa
57         iret
58
59 %macro iodelay 0
60         xor al, al
61         times 7 out 80h, al
62 %endmacro
63
64 wait_write:
65         push eax
66         push ecx
67         mov ecx, 32768
68 .loop:  in al, KB_STATUS_PORT
69         test al, KB_STAT_INBUF_FULL
70         jz .break
71         iodelay
72         dec ecx
73         jnz .loop
74 .break: pop ecx
75         pop eax
76         ret
77
78 wait_read:
79         push eax
80         push ecx
81         mov ecx, 32768
82 .loop:  in al, KB_STATUS_PORT
83         test al, KB_STAT_OUTBUF_FULL
84         jnz .break
85         iodelay
86         dec ecx
87         jnz .loop
88 .break: pop ecx
89         pop eax
90         ret
91
92         ; expects command in al
93 send_cmd:
94         call wait_write
95         out KB_CMD_PORT, al
96         ret
97
98 read_data:
99 send_data:
100
101         section .data
102         align 4
103 key_ext: db 0
104
105         global keystate
106 keystate: times 256 db 0