Rev 1842 | Rev 1848 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1842 | Rev 1843 | ||
---|---|---|---|
Line 40... | Line 40... | ||
40 | * and z8530-irrelevant constants, code and comments. |
40 | * and z8530-irrelevant constants, code and comments. |
41 | * Still it miraculously works. |
41 | * Still it miraculously works. |
42 | */ |
42 | */ |
43 | 43 | ||
44 | #include <genarch/kbd/z8530.h> |
44 | #include <genarch/kbd/z8530.h> |
- | 45 | #include <genarch/kbd/key.h> |
|
45 | #include <genarch/kbd/scanc.h> |
46 | #include <genarch/kbd/scanc.h> |
46 | #include <genarch/kbd/scanc_sun.h> |
47 | #include <genarch/kbd/scanc_sun.h> |
47 | #include <arch/drivers/z8530.h> |
48 | #include <arch/drivers/z8530.h> |
48 | #include <arch/interrupt.h> |
49 | #include <arch/interrupt.h> |
49 | #include <cpu.h> |
50 | #include <cpu.h> |
50 | #include <arch/asm.h> |
51 | #include <arch/asm.h> |
51 | #include <arch.h> |
52 | #include <arch.h> |
52 | #include <synch/spinlock.h> |
- | |
53 | #include <typedefs.h> |
53 | #include <typedefs.h> |
54 | #include <console/chardev.h> |
54 | #include <console/chardev.h> |
55 | #include <console/console.h> |
55 | #include <console/console.h> |
56 | #include <macros.h> |
- | |
57 | #include <interrupt.h> |
56 | #include <interrupt.h> |
58 | 57 | ||
59 | /* Keyboard commands. */ |
58 | /* Keyboard commands. */ |
60 | #define KBD_ENABLE 0xf4 |
59 | #define KBD_ENABLE 0xf4 |
61 | #define KBD_DISABLE 0xf5 |
60 | #define KBD_DISABLE 0xf5 |
Line 81... | Line 80... | ||
81 | 80 | ||
82 | #define z8530_BUFFER_FULL_MASK 0x01 |
81 | #define z8530_BUFFER_FULL_MASK 0x01 |
83 | #define z8530_WAIT_MASK 0x02 |
82 | #define z8530_WAIT_MASK 0x02 |
84 | #define z8530_MOUSE_DATA 0x20 |
83 | #define z8530_MOUSE_DATA 0x20 |
85 | 84 | ||
86 | #define KEY_RELEASE 0x80 |
- | |
87 | - | ||
88 | /* |
85 | /* |
89 | * These codes read from z8530 data register are silently ignored. |
86 | * These codes read from z8530 data register are silently ignored. |
90 | */ |
87 | */ |
91 | #define IGNORE_CODE 0x7f /* all keys up */ |
88 | #define IGNORE_CODE 0x7f /* all keys up */ |
92 | 89 | ||
93 | static void key_released(uint8_t sc); |
- | |
94 | static void key_pressed(uint8_t sc); |
- | |
95 | static char key_read(chardev_t *d); |
- | |
96 | - | ||
97 | #define PRESSED_SHIFT (1<<0) |
- | |
98 | #define PRESSED_CAPSLOCK (1<<1) |
- | |
99 | #define LOCKED_CAPSLOCK (1<<0) |
- | |
100 | - | ||
101 | #define ACTIVE_READ_BUFF_SIZE 16 /* Must be power of 2 */ |
- | |
102 | - | ||
103 | static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE]; |
- | |
104 | - | ||
105 | SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
- | |
106 | static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
- | |
107 | static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
- | |
108 | - | ||
109 | static void z8530_suspend(chardev_t *); |
90 | static void z8530_suspend(chardev_t *); |
110 | static void z8530_resume(chardev_t *); |
91 | static void z8530_resume(chardev_t *); |
111 | 92 | ||
112 | static chardev_t kbrd; |
93 | chardev_t kbrd; |
113 | static chardev_operations_t ops = { |
94 | static chardev_operations_t ops = { |
114 | .suspend = z8530_suspend, |
95 | .suspend = z8530_suspend, |
115 | .resume = z8530_resume, |
96 | .resume = z8530_resume, |
116 | .read = key_read |
97 | .read = key_read |
117 | }; |
98 | }; |
Line 190... | Line 171... | ||
190 | while (z8530_status_read() & z8530_WAIT_MASK) { |
171 | while (z8530_status_read() & z8530_WAIT_MASK) { |
191 | /* wait */ |
172 | /* wait */ |
192 | } |
173 | } |
193 | } |
174 | } |
194 | 175 | ||
195 | /** Process release of key. |
- | |
196 | * |
- | |
197 | * @param sc Scancode of the key being released. |
- | |
198 | */ |
- | |
199 | void key_released(uint8_t sc) |
- | |
200 | { |
- | |
201 | spinlock_lock(&keylock); |
- | |
202 | switch (sc) { |
- | |
203 | case SC_LSHIFT: |
- | |
204 | case SC_RSHIFT: |
- | |
205 | keyflags &= ~PRESSED_SHIFT; |
- | |
206 | break; |
- | |
207 | case SC_CAPSLOCK: |
- | |
208 | keyflags &= ~PRESSED_CAPSLOCK; |
- | |
209 | if (lockflags & LOCKED_CAPSLOCK) |
- | |
210 | lockflags &= ~LOCKED_CAPSLOCK; |
- | |
211 | else |
- | |
212 | lockflags |= LOCKED_CAPSLOCK; |
- | |
213 | break; |
- | |
214 | default: |
- | |
215 | break; |
- | |
216 | } |
- | |
217 | spinlock_unlock(&keylock); |
- | |
218 | } |
- | |
219 | - | ||
220 | /** Process keypress. |
- | |
221 | * |
- | |
222 | * @param sc Scancode of the key being pressed. |
- | |
223 | */ |
- | |
224 | void key_pressed(uint8_t sc) |
- | |
225 | { |
- | |
226 | char *map = sc_primary_map; |
- | |
227 | char ascii = sc_primary_map[sc]; |
- | |
228 | bool shift, capslock; |
- | |
229 | bool letter = false; |
- | |
230 | - | ||
231 | spinlock_lock(&keylock); |
- | |
232 | switch (sc) { |
- | |
233 | case SC_LSHIFT: |
- | |
234 | case SC_RSHIFT: |
- | |
235 | keyflags |= PRESSED_SHIFT; |
- | |
236 | break; |
- | |
237 | case SC_CAPSLOCK: |
- | |
238 | keyflags |= PRESSED_CAPSLOCK; |
- | |
239 | break; |
- | |
240 | case SC_SPEC_ESCAPE: |
- | |
241 | break; |
- | |
242 | case SC_LEFTARR: |
- | |
243 | chardev_push_character(&kbrd, 0x1b); |
- | |
244 | chardev_push_character(&kbrd, 0x5b); |
- | |
245 | chardev_push_character(&kbrd, 0x44); |
- | |
246 | break; |
- | |
247 | case SC_RIGHTARR: |
- | |
248 | chardev_push_character(&kbrd, 0x1b); |
- | |
249 | chardev_push_character(&kbrd, 0x5b); |
- | |
250 | chardev_push_character(&kbrd, 0x43); |
- | |
251 | break; |
- | |
252 | case SC_UPARR: |
- | |
253 | chardev_push_character(&kbrd, 0x1b); |
- | |
254 | chardev_push_character(&kbrd, 0x5b); |
- | |
255 | chardev_push_character(&kbrd, 0x41); |
- | |
256 | break; |
- | |
257 | case SC_DOWNARR: |
- | |
258 | chardev_push_character(&kbrd, 0x1b); |
- | |
259 | chardev_push_character(&kbrd, 0x5b); |
- | |
260 | chardev_push_character(&kbrd, 0x42); |
- | |
261 | break; |
- | |
262 | case SC_HOME: |
- | |
263 | chardev_push_character(&kbrd, 0x1b); |
- | |
264 | chardev_push_character(&kbrd, 0x4f); |
- | |
265 | chardev_push_character(&kbrd, 0x48); |
- | |
266 | break; |
- | |
267 | case SC_END: |
- | |
268 | chardev_push_character(&kbrd, 0x1b); |
- | |
269 | chardev_push_character(&kbrd, 0x4f); |
- | |
270 | chardev_push_character(&kbrd, 0x46); |
- | |
271 | break; |
- | |
272 | case SC_DELETE: |
- | |
273 | chardev_push_character(&kbrd, 0x1b); |
- | |
274 | chardev_push_character(&kbrd, 0x5b); |
- | |
275 | chardev_push_character(&kbrd, 0x33); |
- | |
276 | chardev_push_character(&kbrd, 0x7e); |
- | |
277 | break; |
- | |
278 | default: |
- | |
279 | letter = is_lower(ascii); |
- | |
280 | capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
- | |
281 | shift = keyflags & PRESSED_SHIFT; |
- | |
282 | if (letter && capslock) |
- | |
283 | shift = !shift; |
- | |
284 | if (shift) |
- | |
285 | map = sc_secondary_map; |
- | |
286 | chardev_push_character(&kbrd, map[sc]); |
- | |
287 | break; |
- | |
288 | } |
- | |
289 | spinlock_unlock(&keylock); |
- | |
290 | } |
- | |
291 | - | ||
292 | /* Called from getc(). */ |
176 | /* Called from getc(). */ |
293 | void z8530_resume(chardev_t *d) |
177 | void z8530_resume(chardev_t *d) |
294 | { |
178 | { |
295 | } |
179 | } |
296 | 180 | ||
297 | /* Called from getc(). */ |
181 | /* Called from getc(). */ |
298 | void z8530_suspend(chardev_t *d) |
182 | void z8530_suspend(chardev_t *d) |
299 | { |
183 | { |
300 | } |
184 | } |
301 | 185 | ||
302 | static uint8_t active_read_buff_read(void) |
- | |
303 | { |
- | |
304 | static int i=0; |
- | |
305 | i &= (ACTIVE_READ_BUFF_SIZE-1); |
- | |
306 | if(!active_read_buff[i]) { |
- | |
307 | return 0; |
- | |
308 | } |
- | |
309 | return active_read_buff[i++]; |
- | |
310 | } |
- | |
311 | - | ||
312 | static void active_read_buff_write(uint8_t ch) |
- | |
313 | { |
- | |
314 | static int i=0; |
- | |
315 | active_read_buff[i] = ch; |
- | |
316 | i++; |
- | |
317 | i &= (ACTIVE_READ_BUFF_SIZE-1); |
- | |
318 | active_read_buff[i]=0; |
- | |
319 | } |
- | |
320 | - | ||
321 | - | ||
322 | static void active_read_key_pressed(uint8_t sc) |
- | |
323 | { |
- | |
324 | char *map = sc_primary_map; |
- | |
325 | char ascii = sc_primary_map[sc]; |
- | |
326 | bool shift, capslock; |
- | |
327 | bool letter = false; |
- | |
328 | - | ||
329 | /*spinlock_lock(&keylock);*/ |
- | |
330 | switch (sc) { |
- | |
331 | case SC_LSHIFT: |
- | |
332 | case SC_RSHIFT: |
- | |
333 | keyflags |= PRESSED_SHIFT; |
- | |
334 | break; |
- | |
335 | case SC_CAPSLOCK: |
- | |
336 | keyflags |= PRESSED_CAPSLOCK; |
- | |
337 | break; |
- | |
338 | case SC_SPEC_ESCAPE: |
- | |
339 | break; |
- | |
340 | case SC_LEFTARR: |
- | |
341 | active_read_buff_write(0x1b); |
- | |
342 | active_read_buff_write(0x5b); |
- | |
343 | active_read_buff_write(0x44); |
- | |
344 | break; |
- | |
345 | case SC_RIGHTARR: |
- | |
346 | active_read_buff_write(0x1b); |
- | |
347 | active_read_buff_write(0x5b); |
- | |
348 | active_read_buff_write(0x43); |
- | |
349 | break; |
- | |
350 | case SC_UPARR: |
- | |
351 | active_read_buff_write(0x1b); |
- | |
352 | active_read_buff_write(0x5b); |
- | |
353 | active_read_buff_write(0x41); |
- | |
354 | break; |
- | |
355 | case SC_DOWNARR: |
- | |
356 | active_read_buff_write(0x1b); |
- | |
357 | active_read_buff_write(0x5b); |
- | |
358 | active_read_buff_write(0x42); |
- | |
359 | break; |
- | |
360 | case SC_HOME: |
- | |
361 | active_read_buff_write(0x1b); |
- | |
362 | active_read_buff_write(0x4f); |
- | |
363 | active_read_buff_write(0x48); |
- | |
364 | break; |
- | |
365 | case SC_END: |
- | |
366 | active_read_buff_write(0x1b); |
- | |
367 | active_read_buff_write(0x4f); |
- | |
368 | active_read_buff_write(0x46); |
- | |
369 | break; |
- | |
370 | case SC_DELETE: |
- | |
371 | active_read_buff_write(0x1b); |
- | |
372 | active_read_buff_write(0x5b); |
- | |
373 | active_read_buff_write(0x33); |
- | |
374 | active_read_buff_write(0x7e); |
- | |
375 | break; |
- | |
376 | default: |
- | |
377 | letter = is_lower(ascii); |
- | |
378 | capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
- | |
379 | shift = keyflags & PRESSED_SHIFT; |
- | |
380 | if (letter && capslock) |
- | |
381 | shift = !shift; |
- | |
382 | if (shift) |
- | |
383 | map = sc_secondary_map; |
- | |
384 | active_read_buff_write(map[sc]); |
- | |
385 | break; |
- | |
386 | } |
- | |
387 | /*spinlock_unlock(&keylock);*/ |
- | |
388 | - | ||
389 | } |
- | |
390 | - | ||
391 | static char key_read(chardev_t *d) |
186 | char key_read(chardev_t *d) |
392 | { |
187 | { |
393 | char ch; |
188 | char ch; |
394 | 189 | ||
395 | while(!(ch = active_read_buff_read())) { |
190 | while(!(ch = active_read_buff_read())) { |
396 | uint8_t x; |
191 | uint8_t x; |