From: Guillermo J. Rozas Date: Sun, 6 Sep 1992 16:24:26 +0000 (+0000) Subject: Make caps-lock work correctly by adding a third translation table. X-Git-Tag: 20090517-FFI~8997 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=a8a1a48841ec6831752218565926614f987635e6;p=mit-scheme.git Make caps-lock work correctly by adding a third translation table. --- diff --git a/v7/src/microcode/dosconio.c b/v7/src/microcode/dosconio.c index 66d75d266..63b505227 100644 --- a/v7/src/microcode/dosconio.c +++ b/v7/src/microcode/dosconio.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: dosconio.c,v 1.3 1992/09/03 07:40:47 jinx Exp $ +$Id: dosconio.c,v 1.4 1992/09/06 16:24:18 jinx Exp $ Copyright (c) 1992 Massachusetts Institute of Technology @@ -83,42 +83,16 @@ typedef struct typeahead_buffer_struct static conio_buffer_t line_buffer, key_buffer; static typeahead_buffer_t typeahead_buffer; -static int max_scancode_conversion_length = 0; +static int max_scancode_conversion_length = 1; static unsigned char * keyboard_scancode_table[] = DEFAULT_SCANCODE_CONVERSIONS; -/* This is a kludge to save 200 bytes or so of memory; sigh! */ -#ifndef ULONG_BIT -#define ULONG_BIT (sizeof(unsigned long)*CHAR_BIT) -#endif -#define MALLOCED_TABLE_SIZE \ - ((KEYBOARD_SCANCODE_TABLE_SIZE+(ULONG_BIT-1))/ULONG_BIT) - -static unsigned long scancode_malloced_table[MALLOCED_TABLE_SIZE] = {0,}; - -#define Scancode_To_Malloced_Table_Word(s) ((s)/ULONG_BIT) -#define Scancode_To_Malloced_Table_Word_Bit(s) ((s)%ULONG_BIT) - -#define Scancode_Malloced_p(s) \ - (scancode_malloced_table[Scancode_To_Malloced_Table_Word(s)] & \ - (1 << Scancode_To_Malloced_Table_Word_Bit(s))) +#define IMAX(a, b) (((a) > (b)) ? (a) : (b)) -#define Scancode_Malloced(s) \ - (scancode_malloced_table[Scancode_To_Malloced_Table_Word(s)] |= \ - (1 << Scancode_To_Malloced_Table_Word_Bit(s))) - -#define Scancode_Malloced_Not(s) \ - (scancode_malloced_table[Scancode_To_Malloced_Table_Word(s)] &= \ - (~(1 << Scancode_To_Malloced_Table_Word_Bit(s)))) - -/* End of Kludge */ - -#define Max(a, b) (((a) > (b)) ? (a) : (b)) - -#define Typeahead_Buffer_Remaining() \ +#define TYPEAHEAD_BUFFER_REMAINING() \ (TYPEAHEAD_BUFFER_SIZE - typeahead_buffer.length) -#define Typeahead_Buffer_Available_p() \ - (Typeahead_Buffer_Remaining() >= max_scancode_conversion_length) +#define TYPEAHEAD_BUFFER_AVAILABLE_P() \ + ((TYPEAHEAD_BUFFER_REMAINING ()) >= max_scancode_conversion_length) static void DEFUN (map_keyboard_scancode, (scancode), unsigned char scancode) @@ -144,7 +118,7 @@ DEFUN (map_keyboard_scancode, (scancode), unsigned char scancode) len = ((conversion == CTRL_AT) ? 1 : (strlen (conversion))); - if (len <= (Typeahead_Buffer_Remaining ())) + if (len <= (TYPEAHEAD_BUFFER_REMAINING ())) { /* Copy conversion string into typeahead buffer, worrying about interrupt characters along the way. @@ -158,12 +132,12 @@ DEFUN (map_keyboard_scancode, (scancode), unsigned char scancode) } return; } - + static void DEFUN_VOID (recompute_max_scancode_conversion_length) { int i, length; - max_scancode_conversion_length = 0; + max_scancode_conversion_length = 1; for (i = 0; i < KEYBOARD_SCANCODE_TABLE_SIZE; i++) { @@ -174,106 +148,19 @@ DEFUN_VOID (recompute_max_scancode_conversion_length) length = 1; else length = (strlen (conversion)); - max_scancode_conversion_length - = Max (length, max_scancode_conversion_length); + max_scancode_conversion_length = (IMAX (length, + max_scancode_conversion_length)); } return; } -static void -DEFUN_VOID (initialize_scancode_table) -{ - recompute_max_scancode_conversion_length (); -} - -DEFINE_PRIMITIVE ("KEYBOARD-GET-CONVERSION", Prim_keyboard_get_conversion, - 1, 1, 0) -{ - PRIMITIVE_HEADER (1); - { - long scancode = arg_integer(1); - - if ((scancode < 0) || (scancode >= KEYBOARD_SCANCODE_TABLE_SIZE)) - error_bad_range_arg(1); - else - { - unsigned char * conversion = keyboard_scancode_table[scancode]; - if (conversion == NO_CONVERSION) - PRIMITIVE_RETURN (SHARP_F); - else if (conversion == CTRL_AT) - PRIMITIVE_RETURN (memory_to_string (1, "\0")); - else - PRIMITIVE_RETURN (char_pointer_to_string (conversion)); - } - } -} - -DEFINE_PRIMITIVE ("KEYBOARD-SET-CONVERSION!", Prim_keyboard_set_conversion, - 2, 2, 0) -{ - PRIMITIVE_HEADER (2); - { - int scancode = (arg_integer (1)); - SCHEME_OBJECT scheme_conversion = (ARG_REF (2)); - - if ((scancode < 0) || (scancode >= KEYBOARD_SCANCODE_TABLE_SIZE)) - error_bad_range_arg(1); - else - { - int len; - if ((scheme_conversion != SHARP_F) - && (!STRING_P (scheme_conversion))) - error_wrong_type_arg (2); - if ((scheme_conversion == SHARP_F) - || ((len = (STRING_LENGTH (scheme_conversion))) - == 0)) - { - if (Scancode_Malloced_p (scancode)) - DOS_free (keyboard_scancode_table[scancode]); - keyboard_scancode_table[scancode] = NO_CONVERSION; - Scancode_Malloced_Not (scancode); - } - else if ((len == 1) - && ((STRING_REF (scheme_conversion, 0)) == '\0')) - { - if (Scancode_Malloced_p (scancode)) - DOS_free (keyboard_scancode_table[scancode]); - keyboard_scancode_table[scancode] = CTRL_AT; - Scancode_Malloced_Not (scancode); - } - else - { - int i; - unsigned char * old_conversion - = keyboard_scancode_table[scancode]; - unsigned char * conversion, * scheme; - - conversion = (DOS_malloc (len + 1)); - if (conversion == 0) - error_system_call (ENOMEM, syscall_malloc); - if (Scancode_Malloced_p (scancode)) - DOS_free (old_conversion); - keyboard_scancode_table[scancode] = conversion; - Scancode_Malloced (scancode); - for (i = 0, scheme = (STRING_LOC (scheme_conversion, 0)); - i <= len; - i ++) - *conversion++ = *scheme++; - *conversion = '\0'; - } - recompute_max_scancode_conversion_length (); - PRIMITIVE_RETURN (UNSPECIFIC); - } - } -} - static void DEFUN_VOID (consume_typeahead) { extern int signal_keyboard_character_interrupt (int); unsigned char character; - while ((Typeahead_Buffer_Available_p ()) && + while ((TYPEAHEAD_BUFFER_AVAILABLE_P ()) && (dos_poll_keyboard_character (&character))) { if (character == '\0') /* Extended scancode */ @@ -313,18 +200,6 @@ DEFUN_VOID (get_typeahead_character) return (result); } } - -DEFINE_PRIMITIVE ("DOS-HIGH-PRIORITY-TIMER-INTERRUPT", Prim_dos_high_priority_timer, 2, 2, - "High-priority timer interrupt handler.") -{ - extern void EXFUN (dos_process_timer_interrupt, (void)); - PRIMITIVE_HEADER (2); - - consume_typeahead (); - dos_process_timer_interrupt (); - CLEAR_INTERRUPT (INT_Global_GC); - PRIMITIVE_RETURN (UNSPECIFIC); -} static void DEFUN (key_buffer_insert_self, (c), unsigned char c) @@ -356,7 +231,7 @@ DEFUN_VOID (key_buffer_erase_character) } static void -DEFUN_VOID(key_buffer_to_line_buffer) +DEFUN_VOID (key_buffer_to_line_buffer) { register size_t i = 0; register size_t j = 0; @@ -383,6 +258,7 @@ void DEFUN_VOID (DOS_initialize_conio) { void initialize_keyboard_interrupt_table (void); + void initialize_scancode_table (void); flush_conio_buffers (); initialize_keyboard_interrupt_table (); @@ -401,7 +277,18 @@ DEFUN (DOS_initialize_fov, (fov), SCHEME_OBJECT fov) prim = (make_primitive ("DOS-HIGH-PRIORITY-TIMER-INTERRUPT")); iv = (FAST_VECTOR_REF (fov, System_Interrupt_Vector)); VECTOR_SET (iv, Global_GC_Level, prim); + return; +} +static void +DEFUN (non_buffered_key_command, (c), unsigned char c) +{ + if (line_buffer.length == CONIO_BUFFER_SIZE) return; + + if ((!DOS_keyboard_intercepted_p) + && (c == BACKSPACE)) + c = DELETE; + line_buffer.buffer[line_buffer.length++] = c; return; } @@ -441,22 +328,9 @@ DEFUN (buffered_key_command, (c), unsigned char c) return; } -static void -DEFUN (non_buffered_key_command, (c), unsigned char c) -{ - if (line_buffer.length == CONIO_BUFFER_SIZE) return; - - if ((!DOS_keyboard_intercepted_p) - && (c == BACKSPACE)) - c = DELETE; - - line_buffer.buffer[line_buffer.length++] = c; - return; -} - long -DEFUN(console_read, (buffer, nbytes, buffered_p, blocking_p), - char * buffer AND unsigned nbytes AND int buffered_p AND int blocking_p) +DEFUN (console_read, (buffer, nbytes, buffered_p, blocking_p), + char * buffer AND unsigned nbytes AND int buffered_p AND int blocking_p) { System_Error_Reset(); do @@ -493,3 +367,134 @@ DEFUN (console_write_string, (string), void * string) text_write ((fileno(stdout)), string, strlen((char *) string)); return; } + +DEFINE_PRIMITIVE ("DOS-HIGH-PRIORITY-TIMER-INTERRUPT", Prim_dos_high_priority_timer, 2, 2, + "DOS High-priority timer interrupt handler.") +{ + extern void EXFUN (dos_process_timer_interrupt, (void)); + PRIMITIVE_HEADER (2); + + consume_typeahead (); + dos_process_timer_interrupt (); + CLEAR_INTERRUPT (INT_Global_GC); + PRIMITIVE_RETURN (UNSPECIFIC); +} + +DEFINE_PRIMITIVE ("KEYBOARD-GET-CONVERSION", Prim_keyboard_get_conversion, 1, 1, + "Translate a keyboard scan code into a string.") +{ + PRIMITIVE_HEADER (1); + { + long scancode = arg_integer(1); + + if ((scancode < 0) || (scancode >= KEYBOARD_SCANCODE_TABLE_SIZE)) + error_bad_range_arg(1); + else + { + unsigned char * conversion = keyboard_scancode_table[scancode]; + if (conversion == NO_CONVERSION) + PRIMITIVE_RETURN (SHARP_F); + else if (conversion == CTRL_AT) + PRIMITIVE_RETURN (memory_to_string (1, "\0")); + else + PRIMITIVE_RETURN (char_pointer_to_string (conversion)); + } + } +} + +#ifndef ULONG_BIT +# define ULONG_BIT ((sizeof (unsigned long)) * CHAR_BIT) +#endif + +#define MALLOCED_TABLE_SIZE \ + ((KEYBOARD_SCANCODE_TABLE_SIZE + (ULONG_BIT - 1)) / ULONG_BIT) + +static unsigned long scancode_malloced_table[MALLOCED_TABLE_SIZE] = {0,}; + +#define SCANCODE_TO_MALLOCED_TABLE_WORD(s) ((s) / ULONG_BIT) +#define SCANCODE_TO_MALLOCED_TABLE_BIT(s) ((s) % ULONG_BIT) + +#define SCANCODE_MALLOCED_P(s) \ + ((scancode_malloced_table[SCANCODE_TO_MALLOCED_TABLE_WORD (s)] & \ + (1 << SCANCODE_TO_MALLOCED_TABLE_BIT (s))) \ + != 0) + +#define SCANCODE_MALLOCED(s) \ + (scancode_malloced_table[SCANCODE_TO_MALLOCED_TABLE_WORD (s)] |= \ + (1 << SCANCODE_TO_MALLOCED_TABLE_BIT (s))) + +#define SCANCODE_MALLOCED_NOT(s) \ + (scancode_malloced_table[SCANCODE_TO_MALLOCED_TABLE_WORD (s)] &= \ + (~(1 << SCANCODE_TO_MALLOCED_TABLE_BIT (s)))) + +static void +DEFUN_VOID (initialize_scancode_table) +{ + int i; + + for (i = 0; i < MALLOCED_TABLE_SIZE; i++) + scancode_malloced_table[i] = ((unsigned long) 0); + recompute_max_scancode_conversion_length (); + return; +} + +DEFINE_PRIMITIVE ("KEYBOARD-SET-CONVERSION!", Prim_keyboard_set_conversion, 2, 2, + "Set the translation for a keyboard scan code.") +{ + PRIMITIVE_HEADER (2); + { + int scancode = (arg_integer (1)); + SCHEME_OBJECT scheme_conversion = (ARG_REF (2)); + + if ((scancode < 0) || (scancode >= KEYBOARD_SCANCODE_TABLE_SIZE)) + error_bad_range_arg(1); + else + { + int len; + unsigned char * old_conversion = keyboard_scancode_table[scancode]; + int old_malloced_p = (SCANCODE_MALLOCED_P (scancode)); + + if ((scheme_conversion != SHARP_F) && (!STRING_P (scheme_conversion))) + error_wrong_type_arg (2); + + len = ((scheme_conversion == SHARP_F) + ? 0 + : (STRING_LENGTH (scheme_conversion))); + if (len == 0) + { + keyboard_scancode_table[scancode] = NO_CONVERSION; + SCANCODE_MALLOCED_NOT (scancode); + if (old_malloced_p) + DOS_free (old_conversion); + } + else if ((len == 1) + && ((STRING_REF (scheme_conversion, 0)) == '\0')) + { + keyboard_scancode_table[scancode] = CTRL_AT; + SCANCODE_MALLOCED_NOT (scancode); + if (old_malloced_p) + DOS_free (old_conversion); + } + else + { + int i; + unsigned char * conversion, * ptr, * scheme; + + conversion = (DOS_malloc (len + 1)); + if (conversion == 0) + error_system_call (ENOMEM, syscall_malloc); + ptr = conversion; + scheme = (STRING_LOC (scheme_conversion, 0)); + for (i = 0; i <= len; i ++) + *ptr++ = *scheme++; + *ptr = '\0'; + keyboard_scancode_table[scancode] = conversion; + SCANCODE_MALLOCED (scancode); + if (old_malloced_p) + DOS_free (old_conversion); + } + recompute_max_scancode_conversion_length (); + PRIMITIVE_RETURN (UNSPECIFIC); + } + } +} diff --git a/v7/src/microcode/doskbd.c b/v7/src/microcode/doskbd.c index 2f026bd68..3e3eb56ee 100644 --- a/v7/src/microcode/doskbd.c +++ b/v7/src/microcode/doskbd.c @@ -1,5 +1,5 @@ /* -*-C-*- -$Id: doskbd.c,v 1.8 1992/09/03 07:30:46 jinx Exp $ +$Id: doskbd.c,v 1.9 1992/09/06 16:24:03 jinx Exp $ Copyright (c) 1992 Massachusetts Institute of Technology @@ -31,6 +31,14 @@ Technology nor of any adaptation thereof in any advertising, promotional, or sales literature without prior written consent from MIT in each case. */ +#include +#include +#include +#include +#include +#include +#include "msdos.h" + /* These flags determine how the code will behave. */ #define DOSX_USE_INT_INTERCEPT @@ -40,14 +48,6 @@ MIT in each case. */ #define DPMI_RM_HANDLER_REAL #define DPMI_PM_HANDLER_UNTOUCHED -#include -#include -#include -#include -#include -#include -#include "msdos.h" - #ifdef getDS #undef getDS #endif @@ -72,7 +72,7 @@ MIT in each case. */ extern unsigned char scan_code_tables_start[]; extern unsigned char scan_code_tables_end[]; - + /* Tables mapping scan codes to ASCII characters. Entries with NULL (\0) should not be mapped by the Scheme keyboard ISR. Let the default handler map them. @@ -81,9 +81,74 @@ extern unsigned char scan_code_tables_end[]; unsigned char scan_code_tables_start[] = "foo"; +static unsigned char modifier_mask = 0x4f; + +static unsigned char +unshifted_scan_code_to_ascii[] = +{ + '\0', /* 0 */ + '\033', /* 1 */ + '1', /* 2 */ + '2', /* 3 */ + '3', /* 4 */ + '4', /* 5 */ + '5', /* 6 */ + '6', /* 7 */ + '7', /* 8 */ + '8', /* 9 */ + '9', /* 10 */ + '0', /* 11 */ + '-', /* 12 */ + '=', /* 13 */ + '\177', /* 14 */ + '\t', /* 15 */ + 'q', /* 16 */ + 'w', /* 17 */ + 'e', /* 18 */ + 'r', /* 19 */ + 't', /* 20 */ + 'y', /* 21 */ + 'u', /* 22 */ + 'i', /* 23 */ + 'o', /* 24 */ + 'p', /* 25 */ + '[', /* 26 */ + ']', /* 27 */ + '\r', /* 28 */ + '\0', /* 29 */ + 'a', /* 30 */ + 's', /* 31 */ + 'd', /* 32 */ + 'f', /* 33 */ + 'g', /* 34 */ + 'h', /* 35 */ + 'j', /* 36 */ + 'k', /* 37 */ + 'l', /* 38 */ + ';', /* 39 */ + '\'', /* 40 */ + '`', /* 41 */ + '\0', /* 42 */ + '\\', /* 43 */ + 'z', /* 44 */ + 'x', /* 45 */ + 'c', /* 46 */ + 'v', /* 47 */ + 'b', /* 48 */ + 'n', /* 49 */ + 'm', /* 50 */ + ',', /* 51 */ + '.', /* 52 */ + '/', /* 53 */ + '\0', /* 54 */ + '\0', /* 55 */ + '\0', /* 56 */ + ' ' /* 57 */ + }; + static unsigned char shifted_scan_code_to_ascii[] = -{ +{ '\0', /* 0 */ '\033', /* 1 */ '!', /* 2 */ @@ -145,7 +210,7 @@ shifted_scan_code_to_ascii[] = }; static unsigned char -unshifted_scan_code_to_ascii[] = +caps_scan_code_to_ascii[] = { '\0', /* 0 */ '\033', /* 1 */ @@ -163,41 +228,41 @@ unshifted_scan_code_to_ascii[] = '=', /* 13 */ '\177', /* 14 */ '\t', /* 15 */ - 'q', /* 16 */ - 'w', /* 17 */ - 'e', /* 18 */ - 'r', /* 19 */ - 't', /* 20 */ - 'y', /* 21 */ - 'u', /* 22 */ - 'i', /* 23 */ - 'o', /* 24 */ - 'p', /* 25 */ + 'Q', /* 16 */ + 'W', /* 17 */ + 'E', /* 18 */ + 'R', /* 19 */ + 'T', /* 20 */ + 'Y', /* 21 */ + 'U', /* 22 */ + 'I', /* 23 */ + 'O', /* 24 */ + 'P', /* 25 */ '[', /* 26 */ ']', /* 27 */ '\r', /* 28 */ '\0', /* 29 */ - 'a', /* 30 */ - 's', /* 31 */ - 'd', /* 32 */ - 'f', /* 33 */ - 'g', /* 34 */ - 'h', /* 35 */ - 'j', /* 36 */ - 'k', /* 37 */ - 'l', /* 38 */ + 'A', /* 30 */ + 'S', /* 31 */ + 'D', /* 32 */ + 'F', /* 33 */ + 'G', /* 34 */ + 'H', /* 35 */ + 'J', /* 36 */ + 'K', /* 37 */ + 'L', /* 38 */ ';', /* 39 */ '\'', /* 40 */ '`', /* 41 */ '\0', /* 42 */ '\\', /* 43 */ - 'z', /* 44 */ - 'x', /* 45 */ - 'c', /* 46 */ - 'v', /* 47 */ - 'b', /* 48 */ - 'n', /* 49 */ - 'm', /* 50 */ + 'Z', /* 44 */ + 'X', /* 45 */ + 'C', /* 46 */ + 'V', /* 47 */ + 'B', /* 48 */ + 'N', /* 49 */ + 'M', /* 50 */ ',', /* 51 */ '.', /* 52 */ '/', /* 53 */ @@ -207,8 +272,6 @@ unshifted_scan_code_to_ascii[] = ' ' /* 57 */ }; -static unsigned char modifier_mask = 0x4f; - unsigned char scan_code_tables_end[] = "bar"; @@ -300,26 +363,33 @@ install_kbd_hook_p (char * var_name) #define DOS_HOOK_TRANSLATE_KEYSTROKE 0x4f #define DOS_KBD_FUNC_RECORD_KEYSTROKE 0x5 - + int -bios_keyboard_handler (struct INT_DATA *pd) +bios_keyboard_handler (struct INT_DATA * pd) { - unsigned char scan_code, chord, ascii; + unsigned char scan_code, chord, ascii, * table; union REGS regs; if (pd->regs.h.ah != DOS_HOOK_TRANSLATE_KEYSTROKE) return (INTERRUPT_CHAIN_NEXT); scan_code = (pd->regs.h.al); + + /* All the tables are assumed to be the same length. */ + if (scan_code >= (sizeof (shifted_scan_code_to_ascii))) return (INTERRUPT_CHAIN_NEXT); chord = ((bioskey (_KEYBRD_SHIFTSTATUS)) & modifier_mask); - if ((chord == 0) || (chord == PC_KBD_ALT_MASK)) - ascii = ((int) unshifted_scan_code_to_ascii[scan_code]); + if ((chord & (PC_KBD_CTRL_MASK | PC_KBD_SHIFT_MASK)) != 0) + table = &shifted_scan_code_to_ascii[0]; + else if ((chord & PC_KBD_CAPSL_MASK) != 0) + table = &caps_scan_code_to_ascii[0]; else - ascii = ((int) shifted_scan_code_to_ascii[scan_code]); + table = &unshifted_scan_code_to_ascii[0]; + + ascii = table[scan_code]; if (ascii == 0) return (INTERRUPT_CHAIN_NEXT); @@ -670,18 +740,19 @@ make_PM_trampoline (void (* hook) (void)) void * trampoline; INSN_DECLS (); - trampoline = (malloc (TRAMP_SIZE (6))); + trampoline = (malloc (TRAMP_SIZE (7))); if (trampoline != ((void *) NULL)) { INIT_INSNS (trampoline); PUSH_INSN (old_PM_vector_cs); PUSH_INSN (old_PM_vector_eip); - PUSH_INSN (& modifier_mask); - PUSH_INSN (unshifted_scan_code_to_ascii); + PUSH_INSH (caps_scan_code_to_ascii); PUSH_INSN (shifted_scan_code_to_ascii); + PUSH_INSN (unshifted_scan_code_to_ascii); + PUSH_INSN (& modifier_mask); PUSH_INSN (getDS ()); JMP_INSN (hook); - HLT_INSNS (6); + HLT_INSNS (7); } return (trampoline); } @@ -694,18 +765,19 @@ make_RM_trampoline (void (* hook) (void)) void * trampoline; INSN_DECLS (); - trampoline = (malloc (TRAMP_SIZE (6))); + trampoline = (malloc (TRAMP_SIZE (7))); if (trampoline != ((void *) NULL)) { INIT_INSNS (trampoline); PUSH_INSN (old_RM_vector.x.seg); PUSH_INSN (old_RM_vector.x.off); - PUSH_INSN (& modifier_mask); - PUSH_INSN (unshifted_scan_code_to_ascii); + PUSH_INSH (caps_scan_code_to_ascii); PUSH_INSN (shifted_scan_code_to_ascii); + PUSH_INSN (unshifted_scan_code_to_ascii); + PUSH_INSN (& modifier_mask); PUSH_INSN (getDS ()); JMP_INSN (hook); - HLT_INSNS (6); + HLT_INSNS (7); } return (trampoline); } @@ -787,14 +859,14 @@ DPMI_restore_kbd_hook (void) #if defined(DPMI_RM_HANDLER_REAL) || defined(DOSX_RM_HANDLER_REAL) -static unsigned shifted_table_offset = 0; -static unsigned unshifted_table_offset = 0; +static unsigned tables_offset = 0; #define PATTERN_MODIFIER_OFFSET 0 -#define PATTERN_SHIFTED_PTR_OFFSET 2 -#define PATTERN_UNSHIFTED_PTR_OFFSET 4 -#define PATTERN_CHAIN_OFFSET 8 -#define PATTERN_START_OFFSET 12 +#define PATTERN_UNSHIFTED_PTR_OFFSET 2 +#define PATTERN_SHIFTED_PTR_OFFSET 4 +#define PATTERN_CAPS_PTR_OFFSET 6 +#define PATTERN_CHAIN_OFFSET 10 +#define PATTERN_START_OFFSET 14 #define RM_ISR_MASK_OFFSET PATTERN_MODIFIER_OFFSET @@ -816,8 +888,9 @@ make_RM_handler (unsigned * size, unsigned * offset, unsigned * delta) pattern_size = (((unsigned long) RM_keyboard_pattern_end) - start_offset); total_size = (pattern_size + + (sizeof (unshifted_scan_code_to_ascii)) + (sizeof (shifted_scan_code_to_ascii)) - + (sizeof (unshifted_scan_code_to_ascii))); + + (sizeof (caps_scan_code_to_ascii))); copy = ((unsigned char *) (malloc (total_size))); if (copy == ((unsigned char *) NULL)) @@ -839,18 +912,27 @@ make_RM_handler (unsigned * size, unsigned * offset, unsigned * delta) } memcpy ((copy + pattern_size), + unshifted_scan_code_to_ascii, + (sizeof (unshifted_scan_code_to_ascii))); + + memcpy ((copy + (pattern_size + (sizeof (unshifted_scan_code_to_ascii)))), shifted_scan_code_to_ascii, (sizeof (shifted_scan_code_to_ascii))); - memcpy ((copy + (pattern_size + (sizeof (shifted_scan_code_to_ascii)))), - unshifted_scan_code_to_ascii, - (sizeof (unshifted_scan_code_to_ascii))); + memcpy ((copy + (pattern_size + ((sizeof (unshifted_scan_code_to_ascii)) + + (sizeof (shifted_scan_code_to_ascii))))), + caps_scan_code_to_ascii, + (sizeof (caps_scan_code_to_ascii))); copy[PATTERN_MODIFIER_OFFSET] = modifier_mask; - wordptr = ((unsigned short *) (copy + PATTERN_SHIFTED_PTR_OFFSET)); - * wordptr = (pattern_size + start_offset); wordptr = ((unsigned short *) (copy + PATTERN_UNSHIFTED_PTR_OFFSET)); - * wordptr = ((pattern_size + (sizeof (shifted_scan_code_to_ascii))) + * wordptr = (pattern_size + start_offset); + wordptr = ((unsigned short *) (copy + PATTERN_SHIFTED_PTR_OFFSET)); + * wordptr = ((pattern_size + (sizeof (unshifted_scan_code_to_ascii))) + + start_offset); + wordptr = ((unsigned short *) (copy + PATTERN_CAPS_PTR_OFFSET)); + * wordptr = ((pattern_size + ((sizeof (unshifted_scan_code_to_ascii)) + + (sizeof (shifted_scan_code_to_ascii)))) + start_offset); wordptr = ((unsigned short *) (copy + PATTERN_CHAIN_OFFSET)); * wordptr++ = old_RM_vector.x.off; @@ -859,8 +941,7 @@ make_RM_handler (unsigned * size, unsigned * offset, unsigned * delta) * delta = start_offset; * size = total_size; * offset = PATTERN_START_OFFSET; - shifted_table_offset = pattern_size; - unshifted_table_offset = (pattern_size + (sizeof (shifted_scan_code_to_ascii))); + tables_offset = pattern_size; return ((void *) copy); } @@ -1034,16 +1115,28 @@ DPMI_set_modifier_mask (unsigned char new_mask) } static void -DPMI_set_kbd_translation (unsigned shift_p, +DPMI_set_kbd_translation (unsigned table, unsigned scan_code, unsigned char new) { #ifdef DPMI_RM_HANDLER_REAL + int offset = tables_offset; + + switch (table) + { + case 2: + offset += (sizeof (shifted_scan_code_to_ascii)); + + case 1: + offset += (sizeof (unshifted_scan_code_to_ascii)); + + default: + break; + } + if (DPMI_RM_selector != 0) - farcpy ((scan_code + ((shift_p != 0) - ? shifted_table_offset - : unshifted_table_offset)), + farcpy ((scan_code + tables_offset), DPMI_RM_selector, ((unsigned) (& new)), (getDS ()), @@ -1274,18 +1367,29 @@ DOSX_set_modifier_mask (unsigned char new_mask) } static void -DOSX_set_kbd_translation (unsigned shift_p, +DOSX_set_kbd_translation (unsigned table, unsigned scan_code, unsigned char new) { #ifdef DOSX_RM_HANDLER_REAL + int offset = tables_offset; + + switch (table) + { + case 2: + offset += (sizeof (shifted_scan_code_to_ascii)); + + case 1: + offset += (sizeof (unshifted_scan_code_to_ascii)); + + default: + break; + } + if (DOSX_RM_segment != 0) (* ((unsigned char *) - ((((unsigned long) DOSX_RM_segment) << 4) - + (scan_code + ((shift_p != 0) - ? shifted_table_offset - : unshifted_table_offset))))) + ((((unsigned long) DOSX_RM_segment) << 4) + (scan_code + offset)))) = new; #endif /* DOSX_RM_HANDLER_REAL */ @@ -1315,6 +1419,7 @@ X32_install_kbd_hook (void) X32_kbd_interrupt_pointers[0] = ((PTR) &modifier_mask); X32_kbd_interrupt_pointers[1] = ((PTR) &unshifted_scan_code_to_ascii[0]); X32_kbd_interrupt_pointers[2] = ((PTR) &shifted_scan_code_to_ascii[0]); + X32_kbd_interrupt_pointers[3] = ((PTR) &caps_scan_code_to_ascii[0]); if ((X32_int_intercept (DOS_INTVECT_SYSTEM_SERVICES, X32_keyboard_interrupt, @@ -1341,7 +1446,7 @@ X32_set_modifier_mask (unsigned char new_mask) } static void -X32_set_kbd_translation (unsigned shift_p, +X32_set_kbd_translation (unsigned table, unsigned scan_code, unsigned char new) { @@ -1437,7 +1542,7 @@ extern int EXFUN (dos_set_kbd_translation, (unsigned, unsigned, unsigned char)); int -dos_set_kbd_translation (unsigned shift_p, +dos_set_kbd_translation (unsigned which_table, unsigned scan_code, unsigned char new) { @@ -1447,16 +1552,28 @@ dos_set_kbd_translation (unsigned shift_p, if (scan_code >= (sizeof (shifted_scan_code_to_ascii))) return (-1); - if (shift_p != 0) - table = &shifted_scan_code_to_ascii[0]; - else - table = &unshifted_scan_code_to_ascii[0]; + switch (which_table) + { + case 0: + default: + table = &unshifted_scan_code_to_ascii[0]; + break; + + case 1: + table = &shifted_scan_code_to_ascii[0]; + break; + + case 2: + table = &caps_scan_code_to_ascii[0]; + break; + } old = table[scan_code]; table[scan_code] = new; if (installed_keyboard_method != ((struct keyboard_method_s *) NULL)) - (* (installed_keyboard_method->set_kbd_translation)) (shift_p, scan_code, new); + (* (installed_keyboard_method->set_kbd_translation)) + (which_table, scan_code, new); return ((int) old); } diff --git a/v7/src/microcode/doskbutl.asm b/v7/src/microcode/doskbutl.asm index 57de4b2e8..5c066a96f 100644 --- a/v7/src/microcode/doskbutl.asm +++ b/v7/src/microcode/doskbutl.asm @@ -1,6 +1,6 @@ ;;; -*-Midas-*- ;;; -;;; $Id: doskbutl.asm,v 1.4 1992/09/03 07:30:20 jinx Exp $ +;;; $Id: doskbutl.asm,v 1.5 1992/09/06 16:24:10 jinx Exp $ ;;; ;;; Copyright (c) 1992 Massachusetts Institute of Technology ;;; @@ -43,14 +43,15 @@ ;; Stack on entry to _DOSX_scheme_system_isr ;; -;;32 IRETD EFLAGS -;;28 IRETD CS -;;24 IRETD EIP -;;20 CS for next handler in chain -;;16 EIP for next handler in chain -;;12 address of modifier mask -;;8 offset for unshifted table -;;4 offset for shifted table +;;36 IRETD EFLAGS +;;32 IRETD CS +;;28 IRETD EIP +;;24 CS for next handler in chain +;;20 EIP for next handler in chain +;;16 offset of caps table +;;12 offset of shifted table +;;8 offset of unshifted table +;;4 offset of modifier mask ;;0 DS for scan_code to ascii tables extrn scheme_system_isr:near @@ -65,7 +66,7 @@ _DPMI_PM_scheme_system_isr: ;; Chain to next handler (flags unmodified) popfd - lea esp,16[esp] + lea esp,20[esp] ; ret far db 0cbh @@ -74,19 +75,20 @@ _DPMI_PM_scheme_system_isr: DOSX_scheme_system_dismiss: push eax mov eax,4[esp] ;updated flags - mov 40[esp],eax ;flags to restore + mov 44[esp],eax ;flags to restore pop eax popfd - lea esp,24[esp] + lea esp,28[esp] iretd ;; Stack on entry to _DPMI_scheme_system_isr ;; -;;20 CS for next (real mode) handler in chain -;;16 IP for next (real mode) handler in chain -;;12 address of modifier mask +;;24 CS for next (real mode) handler in chain +;;20 IP for next (real mode) handler in chain +;;16 offset for caps table +;;12 offset for shifted table ;;8 offset for unshifted table -;;4 offset for shifted table +;;4 offset of modifier mask ;;0 DS for scan_code to ascii tables public _DPMI_RM_scheme_system_isr @@ -100,11 +102,11 @@ _DPMI_RM_scheme_system_isr: ;; Chain to next real mode handler (flags unmodified) lea esp,4[esp] ; drop flags - mov eax,16[esp] ; real mode IP (padded to dword) + mov eax,20[esp] ; real mode IP (padded to dword) mov es:42[edi],ax - mov eax,20[esp] ; real mode CS (padded to dword) + mov eax,24[esp] ; real mode CS (padded to dword) mov es:44[edi],ax - lea esp,24[esp] ; pop args + lea esp,28[esp] ; pop args iret ; tell DPMI we're done ;; Dismiss/finish interrupt in real mode (update flags, simulate RM iret) @@ -117,7 +119,7 @@ DPMI_scheme_system_dismiss: mov ax,ds:2[esi] ; real mode IRET cs mov es:44[edi],ax add word ptr es:46[edi],6 ; bump real mode sp - lea esp,24[esp] ; pop args + lea esp,28[esp] ; pop args iret ; tell DPMI we're done ;; These macros taken from x32's mac32.asm @@ -139,9 +141,11 @@ _RM_keyboard_pattern_start: modifier_mask: db 2 dup (0) +unshifted_table_offset: + db 2 dup (0) shifted_table_offset: db 2 dup (0) -unshifted_table_offset: +caps_table_offset: db 2 dup (0) chain: @@ -163,21 +167,33 @@ kbd_isr: pop bx ; Get scan code push bx and bx,3fh ; Drop fncn - cmp al,8h ; Only meta bit set? - je do_unshifted - cmp al,0 ; No modifier bits set? - je do_unshifted + + test al,7h ; Ctrl or shift set? + jne do_shifted + test al,40h ; CAPS set? + jne do_caps + +do_unshifted: + push si + mov si,word ptr cs:unshifted_table_offset + mov bl,byte ptr cs:[bx+si] + pop si + jmp merge + do_shifted: push si mov si,word ptr cs:shifted_table_offset mov bl,byte ptr cs:[bx+si] pop si jmp merge -do_unshifted: + +do_caps: push si - mov si,word ptr cs:unshifted_table_offset + mov si,word ptr cs:caps_table_offset mov bl,byte ptr cs:[bx+si] pop si +; jmp merge + merge: cmp bl,0 ; No translation? je abort_translation diff --git a/v7/src/microcode/dosscan.h b/v7/src/microcode/dosscan.h index 92b9b06d1..664309833 100644 --- a/v7/src/microcode/dosscan.h +++ b/v7/src/microcode/dosscan.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: dosscan.h,v 1.3 1992/09/05 10:58:38 jinx Exp $ +$Id: dosscan.h,v 1.4 1992/09/06 16:24:26 jinx Exp $ Copyright (c) 1992 Massachusetts Institute of Technology @@ -37,65 +37,65 @@ MIT in each case. */ #ifndef SCM_DOSSCAN_INCLUDE #define SCM_DOSSCAN_INCLUDE -#define Metafy(c) ((unsigned char) (((unsigned char) (c))+128)) +#define METAFY(c) ((unsigned char) (((unsigned char) (c)) + 128)) /* This had better get uppercase characters */ -#define Controlify(c) ((unsigned char) (((unsigned char) (c))-64)) +#define CONTROLIFY(c) ((unsigned char) (((unsigned char) (c)) - 64)) #define NO_CONVERSION ((unsigned char *) ((void *) 0)) unsigned char CTRL_AT[] = { '\0' }; -unsigned char HARD_ATTN[] = "This is hard attention"; -unsigned char SOFT_ATTN[] = "This is soft attention"; -unsigned char META_a[] = {Metafy('a'), '\0'}; -unsigned char META_b[] = {Metafy('b'), '\0'}; -unsigned char META_c[] = {Metafy('c'), '\0'}; -unsigned char META_d[] = {Metafy('d'), '\0'}; -unsigned char META_e[] = {Metafy('e'), '\0'}; -unsigned char META_f[] = {Metafy('f'), '\0'}; -unsigned char META_g[] = {Metafy('g'), '\0'}; -unsigned char META_h[] = {Metafy('h'), '\0'}; -unsigned char META_i[] = {Metafy('i'), '\0'}; -unsigned char META_j[] = {Metafy('j'), '\0'}; -unsigned char META_k[] = {Metafy('k'), '\0'}; -unsigned char META_l[] = {Metafy('l'), '\0'}; -unsigned char META_m[] = {Metafy('m'), '\0'}; -unsigned char META_n[] = {Metafy('n'), '\0'}; -unsigned char META_o[] = {Metafy('o'), '\0'}; -unsigned char META_p[] = {Metafy('p'), '\0'}; -unsigned char META_q[] = {Metafy('q'), '\0'}; -unsigned char META_r[] = {Metafy('r'), '\0'}; -unsigned char META_s[] = {Metafy('s'), '\0'}; -unsigned char META_t[] = {Metafy('t'), '\0'}; -unsigned char META_u[] = {Metafy('u'), '\0'}; -unsigned char META_v[] = {Metafy('v'), '\0'}; -unsigned char META_w[] = {Metafy('w'), '\0'}; -unsigned char META_x[] = {Metafy('x'), '\0'}; -unsigned char META_y[] = {Metafy('y'), '\0'}; -unsigned char META_z[] = {Metafy('z'), '\0'}; -unsigned char META_1[] = {Metafy('1'), '\0'}; -unsigned char META_2[] = {Metafy('2'), '\0'}; -unsigned char META_3[] = {Metafy('3'), '\0'}; -unsigned char META_4[] = {Metafy('4'), '\0'}; -unsigned char META_5[] = {Metafy('5'), '\0'}; -unsigned char META_6[] = {Metafy('6'), '\0'}; -unsigned char META_7[] = {Metafy('7'), '\0'}; -unsigned char META_8[] = {Metafy('8'), '\0'}; -unsigned char META_9[] = {Metafy('9'), '\0'}; -unsigned char META_0[] = {Metafy('0'), '\0'}; -unsigned char META_DASH[] = {Metafy('-'), '\0'}; -unsigned char META_EQUAL[] = {Metafy('='), '\0'}; -unsigned char META_RET[] = {Metafy('\r'), '\0'}; -unsigned char META_TAB[] = {Metafy('\t'), '\0'}; -unsigned char META_LBROK[] = {Metafy('['), '\0'}; -unsigned char META_RBROK[] = {Metafy(']'), '\0'}; -unsigned char META_BACK[] = {Metafy('\\'), '\0'}; -unsigned char META_SEMI[] = {Metafy(';'), '\0'}; -unsigned char META_RQUOTE[] = {Metafy('\''), '\0'}; -unsigned char META_COMMA[] = {Metafy(','), '\0'}; -unsigned char META_DOT[] = {Metafy('.'), '\0'}; -unsigned char META_SLASH[] = {Metafy('/'), '\0'}; -unsigned char META_LQUOTE[] = {Metafy('`'), '\0'}; -unsigned char META_PLUS[] = {Metafy('+'), '\0'}; +unsigned char HARD_ATTN[] = "HA"; +unsigned char SOFT_ATTN[] = "SA"; +unsigned char META_a[] = {METAFY('a'), '\0'}; +unsigned char META_b[] = {METAFY('b'), '\0'}; +unsigned char META_c[] = {METAFY('c'), '\0'}; +unsigned char META_d[] = {METAFY('d'), '\0'}; +unsigned char META_e[] = {METAFY('e'), '\0'}; +unsigned char META_f[] = {METAFY('f'), '\0'}; +unsigned char META_g[] = {METAFY('g'), '\0'}; +unsigned char META_h[] = {METAFY('h'), '\0'}; +unsigned char META_i[] = {METAFY('i'), '\0'}; +unsigned char META_j[] = {METAFY('j'), '\0'}; +unsigned char META_k[] = {METAFY('k'), '\0'}; +unsigned char META_l[] = {METAFY('l'), '\0'}; +unsigned char META_m[] = {METAFY('m'), '\0'}; +unsigned char META_n[] = {METAFY('n'), '\0'}; +unsigned char META_o[] = {METAFY('o'), '\0'}; +unsigned char META_p[] = {METAFY('p'), '\0'}; +unsigned char META_q[] = {METAFY('q'), '\0'}; +unsigned char META_r[] = {METAFY('r'), '\0'}; +unsigned char META_s[] = {METAFY('s'), '\0'}; +unsigned char META_t[] = {METAFY('t'), '\0'}; +unsigned char META_u[] = {METAFY('u'), '\0'}; +unsigned char META_v[] = {METAFY('v'), '\0'}; +unsigned char META_w[] = {METAFY('w'), '\0'}; +unsigned char META_x[] = {METAFY('x'), '\0'}; +unsigned char META_y[] = {METAFY('y'), '\0'}; +unsigned char META_z[] = {METAFY('z'), '\0'}; +unsigned char META_1[] = {METAFY('1'), '\0'}; +unsigned char META_2[] = {METAFY('2'), '\0'}; +unsigned char META_3[] = {METAFY('3'), '\0'}; +unsigned char META_4[] = {METAFY('4'), '\0'}; +unsigned char META_5[] = {METAFY('5'), '\0'}; +unsigned char META_6[] = {METAFY('6'), '\0'}; +unsigned char META_7[] = {METAFY('7'), '\0'}; +unsigned char META_8[] = {METAFY('8'), '\0'}; +unsigned char META_9[] = {METAFY('9'), '\0'}; +unsigned char META_0[] = {METAFY('0'), '\0'}; +unsigned char META_DASH[] = {METAFY('-'), '\0'}; +unsigned char META_EQUAL[] = {METAFY('='), '\0'}; +unsigned char META_RET[] = {METAFY('\r'), '\0'}; +unsigned char META_TAB[] = {METAFY('\t'), '\0'}; +unsigned char META_LBROK[] = {METAFY('['), '\0'}; +unsigned char META_RBROK[] = {METAFY(']'), '\0'}; +unsigned char META_BACK[] = {METAFY('\\'), '\0'}; +unsigned char META_SEMI[] = {METAFY(';'), '\0'}; +unsigned char META_RQUOTE[] = {METAFY('\''), '\0'}; +unsigned char META_COMMA[] = {METAFY(','), '\0'}; +unsigned char META_DOT[] = {METAFY('.'), '\0'}; +unsigned char META_SLASH[] = {METAFY('/'), '\0'}; +unsigned char META_LQUOTE[] = {METAFY('`'), '\0'}; +unsigned char META_PLUS[] = {METAFY('+'), '\0'}; #define DEFAULT_SCANCODE_CONVERSIONS \ { \ diff --git a/v7/src/microcode/dosxcutl.asm b/v7/src/microcode/dosxcutl.asm index 684b6c380..590ed05d7 100644 --- a/v7/src/microcode/dosxcutl.asm +++ b/v7/src/microcode/dosxcutl.asm @@ -1,6 +1,6 @@ ;;; -*-Midas-*- ;;; -;;; $Id: dosxcutl.asm,v 1.3 1992/09/03 07:30:06 jinx Exp $ +;;; $Id: dosxcutl.asm,v 1.4 1992/09/06 16:23:57 jinx Exp $ ;;; ;;; Copyright (c) 1992 Massachusetts Institute of Technology ;;; @@ -400,9 +400,10 @@ _X32_kbd_interrupt_previous dd 0 dd 0 public _X32_kbd_interrupt_pointers -_X32_kbd_interrupt_pointers dd 0 - dd 0 - dd 0 +_X32_kbd_interrupt_pointers dd 0 ; mask + dd 0 ; unshifted table + dd 0 ; shifted table + dd 0 ; caps table public _IntCode ; These are usually declared in C, _IntCode dd 0 ; but they need to be locked since @@ -592,40 +593,42 @@ x32_timer_return: public _X32_keyboard_interrupt _X32_keyboard_interrupt: - push dword ptr cs:_X32_kbd_interrupt_pointers[0] - push dword ptr cs:_X32_kbd_interrupt_pointers[4] + push dword ptr cs:_X32_kbd_interrupt_pointers[12] push dword ptr cs:_X32_kbd_interrupt_pointers[8] + push dword ptr cs:_X32_kbd_interrupt_pointers[4] + push dword ptr cs:_X32_kbd_interrupt_pointers[0] push dword ptr cs:_X32_ds_val[0] pushfd call scheme_system_isr jnc x32_keyboard_interrupt_dismiss popfd ; original flags - lea esp,16[esp] + lea esp,20[esp] ; pop args jmp fword ptr cs:_X32_kbd_interrupt_previous x32_keyboard_interrupt_dismiss: push ebx ; preserve ebx push ecx ; preserve ecx mov ebx,8[esp] ; updated flags - mov 36[esp],ebx ; store eflags to location 1 - mov ecx,40[esp] ; pointer to interrupt structure + mov 40[esp],ebx ; store eflags to location 1 + mov ecx,44[esp] ; pointer to interrupt structure mov ss:[ecx],eax ; store new eax mov ss:24[ecx],ebx ; store eflags to location 2 pop ecx pop ebx popfd ; updated flags - lea esp,16[esp] ; pop args + lea esp,20[esp] ; pop args iretd ;; Stack on entry to scheme_system_isr ;; -;;24 address of modifier mask -;;20 offset for unshifted table -;;16 offset for shifted table +;;28 offset of caps table +;;24 offset of shifted table +;;20 offset of unshifted table +;;16 offset of modifier mask ;;12 DS for scan_code to ascii tables ;;8 Flags to restore/modify -;;4 EIP for low-level hook (DPMI or DOSX) +;;4 EIP for low-level hook (DPMI/X32/DOSX) ;;0 Old ebp [pushed on entry] ;; ;; Arguments: @@ -665,17 +668,30 @@ scheme_system_isr: push edx pop es - mov edx,24[ebp] ; Modifier mask address + mov edx,16[ebp] ; Modifier mask address and al,es:[edx] ; Ignore modifiers push eax ; Save result mov ecx,-4[ebp] ; Scan code + function number and ecx,3fh ; Only scan code - mov edx,20[ebp] ; Unshifted table offset and eax,47h ; Shift, ctrl, and CAPS-LOCK mask - cmp al,0 - je index_into_table - mov edx,16[ebp] ; Shifted table offset + + test al,7h + jne use_shifted + test al,40h + jne use_caps + +use_unshifted: + mov edx,20[ebp] ; Unshifted table offset + jmp index_into_table + +use_shifted: + mov edx,24[ebp] ; Shifted table offset + jmp index_into_table + +use_caps: + mov edx,28[ebp] ; Caps-locked table offset +; jmp index_into_table index_into_table: mov al,es:[edx] [ecx] ; Get ASCII value