]> wirehaze git hosting - BOS.git/blob - kernel/kbd/keyboard.asm

wirehaze git hosting

Update shell.asm
[BOS.git] / kernel / kbd / keyboard.asm
1 ;----------------------------------------------------------;
2 ; BOS 0.04 Christoffer Bubach, 2004-2005. ;
3 ;----------------------------------------------------------;
4 ; ;
5 ; Keyboard functions. IRQ, INT's and more. ;
6 ; ;
7 ;----------------------------------------------------------;
8
9
10 ;--------------;
11 ; Variabels ;
12 ;--------------;
13
14 ;--------------------------------------------------------------------------------;
15 ; _______________________ Keyboard buffer system ;
16 ; | | | | | | | | | | | | ;
17 ; +---------------------+ ;
18 ; | +----------> kbd_head, here is where we put new scan-codes. ;
19 ; +--------------------> kbd_tail, where we last read a key. this means ;
20 ; that we have 4 new scan-codes to read before we catch up. ;
21 ;--------------------------------------------------------------------------------;
22 kbd_buffer db ' A 64-byte '
23 db ' keyboard buffer '
24 kbd_head db 1 ; head must be +1 from tail
25 kbd_tail db 0
26
27 ;-------------------------------------------------------------------------;
28 ; _________________ Flag byte: ;
29 ; |1|1|0|0|0|1|1|1| ;
30 ; +---------------+ 1 = True 0 = False ;
31 ; | | | | | | | +---> shift key ;
32 ; | | | | | | +-----> ctrl key ;
33 ; | | | | | +-------> alt key ;
34 ; | | | | +---------> reserved bit ;
35 ; | | | +-----------> reserved bit ;
36 ; | | +-------------> reserved bit ;
37 ; | +---------------> ctrl + alt + del ;
38 ; +-----------------> key released ;
39 ;-------------------------------------------------------------------------;
40 kbd_flags db 0 ; flag byte
41
42 ;-------------------------------------------------------------------------;
43 ; _________________ LED status byte: ;
44 ; |0|0|0|0|0|1|1|1| ;
45 ; +---------------+ 1 = True 0 = False ;
46 ; | | +---> scroll lock ;
47 ; | +-----> num lock ;
48 ; +-------> caps lock ;
49 ;-------------------------------------------------------------------------;
50 kbd_status db 0 ; LED statusbyte
51
52
53 ;----------------------;
54 ; Keyboard IRQ ;
55 ;----------------------;
56 keyboard_isr:
57 push eax
58
59 ;-------------------------;
60 ; get the scancode ;
61 ;-------------------------;
62 xor eax, eax
63 in al, 0x60
64
65 ;------------------------------;
66 ; check if key was released ;
67 ;------------------------------;
68 test al, 0x80
69 jz .key_down
70 and byte [kbd_flags], 01111111b ; key up..
71
72 cmp al, 42+128 ; left shift up?
73 je .shift_up
74 cmp al, 54+128 ; right shift up?
75 je .shift_up
76
77 cmp al, 29+128 ; ctrl up?
78 je .ctrl_up
79
80 cmp al, 83+128 ; del up?
81 je .del_up
82
83 cmp al, 56+128 ; alt up?
84 je .alt_up
85 jmp .end
86
87 ;--------------------;
88 ; it was released ;
89 ;--------------------;
90 .shift_up:
91 and byte [kbd_flags], 11111110b
92 jmp .end
93
94 .del_up:
95 jmp .CAD_off
96
97 .ctrl_up:
98 and byte [kbd_flags], 11111101b ; ctrl off.
99 jmp .CAD_off
100
101 .alt_up:
102 and byte [kbd_flags], 11111011b ; alt off.
103 jmp .CAD_off
104
105 .CAD_off:
106 test byte [kbd_flags], 01000000b
107 jz .CAD_is_off
108 and byte [kbd_flags], 10111111b ; ctrl+alt+del bit off.
109 .CAD_is_off:
110 jmp .end
111
112 ;----------------------------------------------;
113 ; a key was pressed, check for special keys ;
114 ;----------------------------------------------;
115 .key_down:
116 or byte [kbd_flags], 10000000b
117
118 .shift:
119 cmp al, 42
120 jnz .check_rshift
121 or byte [kbd_flags], 00000001b
122 jmp .end
123
124 .check_rshift:
125 cmp al, 54
126 jnz .check_ctrl
127 or byte [kbd_flags], 00000001b
128 jmp .end
129
130 .check_ctrl:
131 cmp al, 29
132 jnz .check_alt
133 or byte [kbd_flags], 00000010b
134 jmp .end
135
136 .check_alt:
137 cmp al, 56
138 jnz .ctrl_alt_del
139 or byte [kbd_flags], 00000100b
140 jmp .end
141
142 .ctrl_alt_del:
143 test byte [kbd_flags], 00000110b ; check for ctrl+alt
144 jz .check_caps
145 cmp al, 83 ; check for delete
146 jne .check_caps
147 or byte [kbd_flags], 01000000b ; ctrl+alt+del bit on.
148
149 ;-------------------------------------;
150 ; toggle caps, num and scroll lock ;
151 ;-------------------------------------;
152 .check_caps:
153 cmp al, 58
154 jnz .check_num
155 xor byte [kbd_status], 4
156 call update_leds
157 jmp .end
158
159 .check_num:
160 cmp al, 69
161 jnz .check_scroll
162 xor byte [kbd_status], 2
163 call update_leds
164 jmp .end
165
166 .check_scroll:
167 cmp al, 70
168 jnz .end
169 xor byte [kbd_status], 1
170 call update_leds
171 jmp .end
172
173 ;-----------------------------------;
174 ; put the scancode in the buffer ;
175 ;-----------------------------------;
176 .end:
177 push eax
178 mov edi, kbd_buffer
179 xor eax, eax
180 mov al, [kbd_head]
181 add edi, eax
182 pop eax
183 stosb
184 cmp [kbd_head], 63 ; if we reach the buffer
185 jne .cont1 ; end, go back to 0.
186 cmp [kbd_tail], 0
187 je .error
188 mov [kbd_head], 0
189 jmp .quit
190 .cont1:
191 mov ah, [kbd_tail]
192 mov al, [kbd_head]
193 add al, 1
194 cmp ah, al
195 je .error
196 inc [kbd_head]
197 jmp .quit
198 .error:
199 call beep ; pc_speaker.inc
200 mov [kbd_head], 1 ; fix it as good
201 mov [kbd_tail], 0 ; as possible.. :S
202 .quit:
203 mov al, 0x20
204 out 0x20, al
205 pop eax
206 ret
207
208
209
210 ;------------------------------;
211 ; Update the keyboard LED's ;
212 ;------------------------------;
213 update_leds:
214 push ax
215
216 call kbd_wait
217 mov al, 0xED
218 out 0x60, al
219 call kbd_wait
220 mov al, [kbd_status]
221 out 0x60, al
222 call kbd_wait
223
224 pop ax
225 ret
226
227
228
229 ;------------------;
230 ; keyboard wait ;
231 ;------------------;
232 kbd_wait:
233 jmp $+2
234 in al, 0x64
235 test al, 1
236 jz .ok
237 jmp $+2
238 in al, 0x60
239 jmp kbd_wait
240 .ok:
241 test al, 2
242 jnz kbd_wait
243 ret
244
245
246
247 ;-------------------------------------------------------;
248 ; BOS INT to get a char. ;
249 ; out: ah = scan code, al = ascii ;
250 ; bh = flag-byte, bl = led-byte ;
251 ;-------------------------------------------------------;
252 getc:
253 push esi
254
255 .no_new:
256 mov al, [kbd_head]
257 mov ah, [kbd_tail]
258 cmp ah, 63
259 jne .check2
260 cmp al, 0
261 je .no_new
262 mov [kbd_tail], 0
263 jmp .done_check
264 .check2:
265 mov bl, ah
266 inc bl
267 cmp bl, al
268 je .no_new
269 inc [kbd_tail]
270 .done_check:
271
272 mov esi, kbd_buffer
273 movzx eax, [kbd_tail]
274 add esi, eax
275 mov ah, byte [esi] ; ah = scancode
276 movzx esi, byte [esi] ; esi = scancode
277
278 ;------------------;
279 ; some checks.. ;
280 ;------------------;
281 cmp ah, 0xFA
282 je .no_new
283 cmp ah, 0xE0
284 je .no_new
285 cmp ah, 0xE1
286 je .no_new
287 test ah, 0x80
288 jnz .no_new
289
290 ;--------------------------------;
291 ; check for caps, shift & alt ;
292 ;--------------------------------;
293 test [kbd_status], 00000100b
294 jnz .caps
295 test [kbd_flags], 00000001b
296 jnz .shift
297
298 ;------------------;
299 ; normal keymap ;
300 ;------------------;
301 mov al, [esi+keymap] ; scancode + keymap = ascii
302 jmp .end
303
304 ;--------------------;
305 ; capslock keymap ;
306 ;--------------------;
307 .caps:
308 test [kbd_flags], 00000001b
309 jnz .caps_and_shift
310
311 mov al, [esi+keymap_caps]
312 jmp .end
313
314 ;--------------------------;
315 ; caps and shift keymap ;
316 ;--------------------------;
317 .caps_and_shift:
318 mov al, [esi+keymap_caps_shift]
319 jmp .end
320
321 ;-----------------;
322 ; shift keymap ;
323 ;-----------------;
324 .shift:
325 mov al, [esi+keymap_shift]
326 jmp .end
327
328 ;---------------------------;
329 ; set registers and exit ;
330 ;---------------------------;
331 .end:
332 mov bl, [kbd_status]
333 mov bh, [kbd_flags]
334
335 pop esi
336 ret
337
338
339 ;------------------------------;
340 ; "press any key to..." ;
341 ;------------------------------;
342 wait_key:
343 push eax
344 push ebx
345 push esi
346
347 .no_new:
348 mov al, [kbd_head]
349 mov ah, [kbd_tail]
350 cmp ah, 63
351 jne .check2
352 cmp al, 0
353 je .no_new
354 mov [kbd_tail], 0
355 jmp .done_check
356 .check2:
357 mov bl, ah
358 inc bl
359 cmp bl, al
360 je .no_new
361 inc [kbd_tail]
362 .done_check:
363
364 mov esi, kbd_buffer
365 movzx eax, [kbd_tail]
366 add esi, eax
367 mov ah, byte [esi] ; ah = scancode
368 cmp ah, 0xFA ; check for some stuff..
369 je .no_new
370 cmp ah, 0xE0
371 je .no_new
372 cmp ah, 0xE1
373 je .no_new
374 test ah, 0x80
375 jnz .no_new
376
377 pop esi
378 pop ebx
379 pop eax
380 ret