@@ -16,6 +16,8 @@ static bool alt_state = false;
1616static struct key_state key_states [256 ] = {0 };
1717static uint8_t key_was_extended [256 ] = {0 };
1818
19+ static debugkey_handler_t debugkeys [256 ];
20+
1921/* UK mappings of scan codes to characters, based in part off http://www.ee.bgu.ac.il/~microlab/MicroLab/Labs/ScanCodes.htm
2022 * These are DEFAULTS. They can be replaced by the KEYMAP BASIC keyword.
2123 */
@@ -106,7 +108,7 @@ static char parse_token(const char **p)
106108 }
107109 buf [len ] = 0 ;
108110 c = (char )atoll (buf , 16 );
109- } else { /* bare character literal */
111+ } else { /* bare character literal */
110112 c = * s ++ ;
111113 }
112114
@@ -309,13 +311,21 @@ void keyboard_repeat_tick() {
309311 }
310312}
311313
314+ static void debugkey_dprintf_dump (void ) {
315+ const char * log = dprintf_buffer_snapshot ();
316+ kprintf ("\n%s\n" , log );
317+ kfree_null (& log );
318+ return ;
319+ }
320+
312321void init_keyboard () {
313322 char devname [16 ];
314323 buffer_write_ptr = 0 ;
315324 buffer_read_ptr = 0 ;
316325 make_unique_device_name ("kb" , devname , sizeof (devname ));
317326 register_interrupt_handler (IRQ1 , keyboard_handler , dev_zero , NULL );
318327 proc_register_idle (keyboard_repeat_tick , IDLE_BACKGROUND , 1 );
328+ debugkey_register ('D' , true, false, true, debugkey_dprintf_dump );
319329}
320330
321331// Map a keyboard scan code to a keymap value
@@ -389,27 +399,57 @@ bool caps_lock_on() {
389399 return caps_lock ;
390400}
391401
402+ static size_t debugkey_index (char key , bool ctrl , bool alt , bool shift ) {
403+ if (key < 'A' || key > 'Z' ) {
404+ return DEBUGKEY_INVALID ;
405+ }
406+
407+ size_t mods =
408+ (ctrl ? 0x20 : 0 ) |
409+ (alt ? 0x40 : 0 ) |
410+ (shift ? 0x80 : 0 );
411+
412+ return mods | (key - 'A' );
413+ }
414+
415+ bool debugkey_register (char key , bool ctrl , bool alt , bool shift , debugkey_handler_t handler ) {
416+ size_t idx = debugkey_index (key , ctrl , alt , shift );
417+
418+ if (idx == DEBUGKEY_INVALID || !handler ) {
419+ return false;
420+ }
421+
422+ debugkeys [idx ] = handler ;
423+ return true;
424+ }
425+
426+ void debugkey_unregister (char key , bool ctrl , bool alt , bool shift ) {
427+ size_t idx = debugkey_index (key , ctrl , alt , shift );
428+
429+ if (idx != DEBUGKEY_INVALID ) {
430+ debugkeys [idx ] = NULL ;
431+ }
432+ }
433+
434+ static bool debugkey_dispatch (char key ) {
435+ size_t idx = debugkey_index (key , ctrl_held (), alt_held (), shift_held ());
436+
437+ if (idx == DEBUGKEY_INVALID ) {
438+ return false;
439+ }
440+
441+ debugkey_handler_t handler = debugkeys [idx ];
442+
443+ if (!handler ) {
444+ return false;
445+ }
446+
447+ handler ();
448+ return true;
449+ }
450+
392451static void push_to_buffer (char x ) {
393- #ifdef PROFILE_KERNEL
394- if (ctrl_held () && alt_held () && shift_held () && x == 'P' ) {
395- kprintf ("\nDumping callgrind.out to serial port...\n" );
396- rr_flip ();
397- profile_dump ();
398- kprintf ("Profile written.\n" );
399- rr_flip ();
400- return ;
401- }
402- #endif
403- #ifdef MEMORY_TRACE
404- if (ctrl_held () && alt_held () && shift_held () && x == 'M' ) {
405- memory_trace_dump_leaks (memory_trace_owner_buddy , NULL );
406- memory_trace_dump_leaks (memory_trace_owner_kmalloc , NULL );
407- }
408- #endif
409- if (ctrl_held () && shift_held () && x == 'D' ) {
410- const char * log = dprintf_buffer_snapshot ();
411- kprintf ("\n%s\n" , log );
412- kfree_null (& log );
452+ if (debugkey_dispatch (x )) {
413453 return ;
414454 }
415455
@@ -439,7 +479,7 @@ void keyboard_process_scancode_input(uint8_t sc) {
439479 }
440480
441481 uint8_t was_escaped = escaped ; /* one-shot */
442- escaped = false; /* consume E0 regardless of outcome */
482+ escaped = false; /* consume E0 regardless of outcome */
443483
444484 switch (sc ) {
445485 case 0x2A :
0 commit comments