sortof bounds-check while moving
[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         and bl, 07fh
42         add ebx, keystate
43
44         ; determine if it's a press or release (high bit set on release)
45         rol al, 1
46         and al, 1
47         xor al, 1
48         mov byte [ebx], al
49 .eoi:
50         cli
51         end_of_irq KB_IRQ
52
53         popa
54         iret
55
56 %macro iodelay 0
57         xor al, al
58         times 7 out 80h, al
59 %endmacro
60
61 wait_write:
62         push eax
63         push ecx
64         mov ecx, 32768
65 .loop:  in al, KB_STATUS_PORT
66         test al, KB_STAT_INBUF_FULL
67         jz .break
68         iodelay
69         dec ecx
70         jnz .loop
71 .break: pop ecx
72         pop eax
73         ret
74
75 wait_read:
76         push eax
77         push ecx
78         mov ecx, 32768
79 .loop:  in al, KB_STATUS_PORT
80         test al, KB_STAT_OUTBUF_FULL
81         jnz .break
82         iodelay
83         dec ecx
84         jnz .loop
85 .break: pop ecx
86         pop eax
87         ret
88
89         ; expects command in al
90 send_cmd:
91         call wait_write
92         out KB_CMD_PORT, al
93         ret
94
95 read_data:
96 send_data:
97
98         section .data
99         align 4
100 key_ext: db 0
101
102         global keystate
103 keystate: times 256 db 0