Change DOS timer interrupt behavior:
authorGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Thu, 3 Sep 1992 07:30:46 +0000 (07:30 +0000)
committerGuillermo J. Rozas <edu/mit/csail/zurich/gjr>
Thu, 3 Sep 1992 07:30:46 +0000 (07:30 +0000)
- Low level timer interrupt sets the "Global GC" interrupt but.

- The Global GC interrupt handler (a primitive) tracks user timer
requests and sets the timer interrupt bit when appropriate.  It also
invokes consume_typeahead to look for keyboard interrupt characters.

Keyboard interrupt behavior changes:

- The interactive handler is invoked from the consume_typeahead
routine, not when Scheme is trying to map the interrupt character.
In this way, its range of actions is greater.

- Add reset option and hard attention keys.

Keyboard interrupt handler:

- Implement X32 version (does not work under DPMI).

- Rewrite DPMI handler to use masm-assembled code instead of
hand-assembled code.  This makes it considerably easier to modify.

v7/src/microcode/dosconio.c
v7/src/microcode/doskbd.c
v7/src/microcode/doskbutl.asm
v7/src/microcode/dosscan.h
v7/src/microcode/dossig.c
v7/src/microcode/dosx32.c
v7/src/microcode/dosxcutl.asm

index 73a98effe611f8849272197a8228d8f16d8b7998..80689172953c3ba5a29da364c1794de37f8d7b6b 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/dosconio.c,v 1.1 1992/05/05 06:55:13 jinx Exp $
+$Id: dosconio.c,v 1.2 1992/09/03 07:29:51 jinx Exp $
 
 Copyright (c) 1992 Massachusetts Institute of Technology
 
@@ -41,7 +41,7 @@ MIT in each case. */
 #include "dosscan.h"
 #include "dossys.h"
 #include "intrpt.h"
-
+\f
 /* This is really not set up to include Scheme level headers, so we
    fake them here. */
 extern long
@@ -52,7 +52,6 @@ extern long
 #define fileno(fp)     ((fp)->_file)
 #endif
 
-\f
 #define CONIO_BUFFER_SIZE      (1024)
 #define TYPEAHEAD_BUFFER_SIZE  (1024)
 
@@ -83,7 +82,6 @@ typedef struct typeahead_buffer_struct
 
 static conio_buffer_t line_buffer, key_buffer;
 static typeahead_buffer_t typeahead_buffer;
-
 \f
 static int max_scancode_conversion_length = 0;
 static unsigned char * keyboard_scancode_table[] = DEFAULT_SCANCODE_CONVERSIONS;
@@ -124,7 +122,8 @@ static unsigned long scancode_malloced_table[MALLOCED_TABLE_SIZE] = {0,};
 
 static void
 DEFUN (map_keyboard_scancode, (scancode), unsigned char scancode)
-{ extern int signal_keyboard_character_interrupt(unsigned char);
+{
+  extern int signal_keyboard_character_interrupt (int);
 
   if (scancode < KEYBOARD_SCANCODE_TABLE_SIZE)
   {
@@ -132,15 +131,27 @@ DEFUN (map_keyboard_scancode, (scancode), unsigned char scancode)
     unsigned char * conversion = keyboard_scancode_table[scancode];
     if (conversion == NO_CONVERSION)
       return;
+    else if (conversion == SOFT_ATTN)
+    {
+      signal_keyboard_character_interrupt (-1);
+      return;
+    }
+    else if (conversion == HARD_ATTN)
+    {
+      signal_keyboard_character_interrupt (-2);
+      return;
+    }
 
-    len = ((conversion == CTRL_AT) ? 1 : strlen (conversion));
+    len = ((conversion == CTRL_AT) ? 1 : (strlen (conversion)));
     
     if (len <= (Typeahead_Buffer_Remaining ()))
-    { /* Copy conversion string into typeahead buffer, worrying about
-        interrupt characters along the way. */
+    {
+      /* Copy conversion string into typeahead buffer, worrying about
+        interrupt characters along the way.
+       */
       while (--len >= 0)
       {
-       if ((signal_keyboard_character_interrupt (*conversion)) == 0)
+       if ((signal_keyboard_character_interrupt ((int) (*conversion))) == 0)
          typeahead_buffer.buffer[typeahead_buffer.length++] = *conversion++;
       }
     }
@@ -162,7 +173,7 @@ DEFUN_VOID (recompute_max_scancode_conversion_length)
     else if (conversion == CTRL_AT)
       length = 1;
     else
-      length = strlen (conversion);
+      length = (strlen (conversion));
     max_scancode_conversion_length 
       = Max (length, max_scancode_conversion_length);
   }
@@ -202,8 +213,8 @@ DEFINE_PRIMITIVE ("KEYBOARD-SET-CONVERSION!", Prim_keyboard_set_conversion,
 {
   PRIMITIVE_HEADER (2);
   {
-    int scancode = arg_integer (1);
-    SCHEME_OBJECT scheme_conversion = ARG_REF (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);
@@ -259,18 +270,18 @@ DEFINE_PRIMITIVE ("KEYBOARD-SET-CONVERSION!", Prim_keyboard_set_conversion,
 static void
 DEFUN_VOID (consume_typeahead)
 {
-  extern int signal_keyboard_character_interrupt(unsigned char);
+  extern int signal_keyboard_character_interrupt (int);
   unsigned char character;
 
-  while ( (Typeahead_Buffer_Available_p()) &&
-         (dos_poll_keyboard_character(&character)) )
+  while ((Typeahead_Buffer_Available_p ()) &&
+        (dos_poll_keyboard_character (&character)))
   { 
     if (character == '\0') /* Extended scancode */
     { 
-      dos_poll_keyboard_character(&character);
-      map_keyboard_scancode(character);
+      dos_poll_keyboard_character (&character);
+      map_keyboard_scancode (character);
     }
-    else if (signal_keyboard_character_interrupt(character) == 0)
+    else if ((signal_keyboard_character_interrupt ((int) character)) == 0)
       typeahead_buffer.buffer[typeahead_buffer.length++] = character;
     else
       break;
@@ -281,35 +292,47 @@ DEFUN_VOID (consume_typeahead)
 static int
 DEFUN_VOID (typeahead_available_p)
 {
-  consume_typeahead();
-  return !(typeahead_buffer.length == 0);
+  consume_typeahead ();
+  return (!(typeahead_buffer.length == 0));
 }
 
 static unsigned char
 DEFUN_VOID (get_typeahead_character)
-{ unsigned char result;
-  
+{
   if (typeahead_buffer.length == 0)
     return '\0';
   else
-  { int i;
+  {
+    int i;
+    unsigned char result;
+
     result = typeahead_buffer.buffer[0];
     for (i = 1; i < typeahead_buffer.length; i++)
       typeahead_buffer.buffer[i - 1] = typeahead_buffer.buffer[i];
     typeahead_buffer.length--;
-    return result;
+    return (result);
   }
 }
 
 DEFINE_PRIMITIVE ("CONSUME-TYPEAHEAD", Prim_consume_typeahead, 0, 0,
-  "Suck up DOS typeahead.")
+                 "Suck up DOS typeahead.")
 {
-
+  /* Obsolete -- done by microcode directly. */
   PRIMITIVE_HEADER(0);
-  consume_typeahead();
   PRIMITIVE_RETURN (UNSPECIFIC);
 }
 
+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);
+}
 \f
 static void
 DEFUN (key_buffer_insert_self, (c), unsigned char c)
@@ -319,12 +342,13 @@ DEFUN (key_buffer_insert_self, (c), unsigned char c)
   if (key_buffer.length != CONIO_BUFFER_SIZE)
   {
     key_buffer.buffer[key_buffer.length++] = c;
-    ( (c == LINEFEED)
-      ? dos_console_write(crlf, sizeof(crlf))
-      : dos_console_write(&c, 1) );
+    if (c == LINEFEED)
+      dos_console_write (crlf, (sizeof (crlf)));
+    else
+      dos_console_write (&c, 1);
   }
   return;
-}  
+}
 
 static void
 DEFUN_VOID (key_buffer_erase_character)
@@ -334,27 +358,26 @@ DEFUN_VOID (key_buffer_erase_character)
   if (key_buffer.length != 0)
   {
     key_buffer.length -= 1;
-    dos_console_write(erase, sizeof(erase));
+    dos_console_write (erase, (sizeof (erase)));
   }
   return;
 }
 
 static void
 DEFUN_VOID(key_buffer_to_line_buffer)
-{ register size_t i = 0;
+{
+  register size_t i = 0;
   register size_t j = 0;
 
-  while ((i < key_buffer.length)&&(line_buffer.length != CONIO_BUFFER_SIZE))
+  while ((i < key_buffer.length)
+        && (line_buffer.length != CONIO_BUFFER_SIZE))
     line_buffer.buffer[line_buffer.length++] = key_buffer.buffer[i++];
   while (i < key_buffer.length)
     key_buffer.buffer[j++] = key_buffer.buffer[i++];
   key_buffer.length = j;
-
   return;
 }
-
 \f
-
 void
 DEFUN_VOID (flush_conio_buffers)
 {
@@ -366,19 +389,34 @@ DEFUN_VOID (flush_conio_buffers)
 
 void
 DEFUN_VOID (DOS_initialize_conio)
-{ void initialize_keyboard_interrupt_table(void);
-
-  flush_conio_buffers();
-  initialize_keyboard_interrupt_table();
-  initialize_scancode_table();
+{
+  void initialize_keyboard_interrupt_table (void);
 
+  flush_conio_buffers ();
+  initialize_keyboard_interrupt_table ();
+  initialize_scancode_table ();
   return;
 }
 
+extern void EXFUN (DOS_initialize_fov, (SCHEME_OBJECT));
+
+void
+DEFUN (DOS_initialize_fov, (fov), SCHEME_OBJECT fov)
+{
+  extern SCHEME_OBJECT EXFUN (make_primitive, (unsigned char *));
+  SCHEME_OBJECT iv, prim;
+
+  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 int
-DEFUN(empty_line_buffer, (buffer, nbytes), char * buffer AND size_t nbytes)
-{ register size_t i, j;
+DEFUN (empty_line_buffer, (buffer, nbytes), char * buffer AND size_t nbytes)
+{
+  register size_t i, j;
   
   for (i = 0; ((i < line_buffer.length)&&(i < nbytes)); i++)
     *buffer++ = line_buffer.buffer[i];
@@ -386,9 +424,8 @@ DEFUN(empty_line_buffer, (buffer, nbytes), char * buffer AND size_t nbytes)
   for (j = 0; i < line_buffer.length; i++, j++)
     line_buffer.buffer[j] = line_buffer.buffer[i];
   line_buffer.length -= nbytes;
-  return nbytes;
+  return (nbytes);
 }
-
 \f
 static void
 DEFUN (buffered_key_command, (c), unsigned char c)
@@ -432,34 +469,35 @@ DEFUN(console_read, (buffer, nbytes, buffered_p, blocking_p),
   System_Error_Reset();
   do
   { /* Get all pending characters into the buffer */
-    while (typeahead_available_p())
+    while (typeahead_available_p ())
     { 
       if (buffered_p)
-       buffered_key_command(get_typeahead_character());
-      else /* Non buffered channel, in CScheme, also no echo. */
-       non_buffered_key_command(get_typeahead_character());
+       buffered_key_command (get_typeahead_character ());
+      else
+       /* Non buffered channel, in CScheme, also no echo. */
+       non_buffered_key_command (get_typeahead_character ());
     } /* End WHILE */
     /* Test for pending interrupts here: */
-    if (pending_interrupts_p())
-    { if (INTERRUPT_QUEUED_P(INT_Character))
-       flush_conio_buffers();
-      System_Error_Return(EINTR);
+    if (pending_interrupts_p ())
+    {
+      if (INTERRUPT_QUEUED_P (INT_Character))
+       flush_conio_buffers ();
+      System_Error_Return (EINTR);
     }
     /* Return if we buffered up a line, or channel is not buffered */
     if (line_buffer.length != 0)
-      return empty_line_buffer(buffer, nbytes);
+      return (empty_line_buffer (buffer, nbytes));
   } while (blocking_p);        /* Keep reading for blocking channel. */
   /* This means there is nothing available, don't block */
-  System_Error_Return(ERRNO_NONBLOCK);
+  System_Error_Return (ERRNO_NONBLOCK);
 }
-       
-\f
+
 extern int EXFUN
  (text_write, (int fd AND CONST unsigned char * buffer AND size_t nbytes));
 
 void
 DEFUN (console_write_string, (string), void * string)
 {
-  text_write(fileno(stdout), string, strlen((char *) string));
+  text_write ((fileno(stdout)), string, strlen((char *) string));
   return;
 }
index 8b27860120b012acb1354e579aac7bf932117b94..2f026bd688fa397db23825ed7ed4de50c7fe7830 100644 (file)
@@ -1,6 +1,5 @@
 /* -*-C-*-
-
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/doskbd.c,v 1.7 1992/06/04 12:40:40 jinx Exp $
+$Id: doskbd.c,v 1.8 1992/09/03 07:30:46 jinx Exp $
 
 Copyright (c) 1992 Massachusetts Institute of Technology
 
@@ -53,6 +52,10 @@ MIT in each case. */
 #undef getDS
 #endif
 
+#ifdef getCS
+#undef getCS
+#endif
+
 #include "dossys.h"
 #include "dosinsn.h"
 #include "doskbd.h"
@@ -64,12 +67,20 @@ MIT in each case. */
 #ifndef EFAULT
 #  define EFAULT 2001
 #endif
+
+/* These depend on the C compiler (Zortech) allocating them contiguosly. */
+
+extern unsigned char scan_code_tables_start[];
+extern unsigned char scan_code_tables_end[];
 \f
 /* 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.
  */
 
+unsigned char
+scan_code_tables_start[] = "foo";
+
 static unsigned char
 shifted_scan_code_to_ascii[] =
 { 
@@ -132,7 +143,7 @@ shifted_scan_code_to_ascii[] =
        '\0',           /* 56 */
        ' '             /* 57 */
   };
-\f    
+\f
 static unsigned char
 unshifted_scan_code_to_ascii[] =
 {
@@ -197,6 +208,9 @@ unshifted_scan_code_to_ascii[] =
   };
 
 static unsigned char modifier_mask = 0x4f;
+
+unsigned char
+scan_code_tables_end[] = "bar";
 \f
 union RM_address
 {
@@ -229,16 +243,6 @@ under_QEMM_386_p (void)
   return (dos_false);
 }
 
-dos_boolean
-under_DPMI_p (void)
-{
-  union REGS regs;
-  
-  regs.e.eax = 0x1686;
-  int86 (0x2f, &regs, &regs);
-  return (regs.x.ax == 0);
-}
-
 static void
 normalize_RM_address (union RM_address * addr)
 {
@@ -298,7 +302,7 @@ install_kbd_hook_p (char * var_name)
 #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;
   union REGS regs;
@@ -783,129 +787,80 @@ DPMI_restore_kbd_hook (void)
 \f
 #if defined(DPMI_RM_HANDLER_REAL) || defined(DOSX_RM_HANDLER_REAL)
 
-unsigned char RM_handler_pattern[] =
-{
-                       /*  chain:                                      */
-0x9d,                  /* 0    popf                                    */
-0xea,0,0,0,0,          /* 1    jmpf    next_in_chain                   */
-                       /*  kbd_isr:                                    */
-0x9c,                  /* 6    pushf                                   */
-0x80,0xfc,0x4f,                /* 7    cmp     ah,4fh                          */
-0x75,0xf4,             /* a    jne     chain                           */
-0x3c,0x39,             /* c    cmp     al,39h                          */
-0x77,0xf0,             /* e    ja      chain                           */
-0x53,                  /* 10   push    bx      ; Preserve bx           */
-0x50,                  /* 11   push    ax      ; Preserve scan code    */
-0xb4,2,                        /* 12   mov     ah,2h                           */
-0xcd,0x16,             /* 14   int     16h     ; Get modifier bits     */
-0x2e,0x22,6,0xf4,0,    /* 16   and     al,cs:modifier mask             */
-0x5b,                  /* 1b   pop     bx      ; Get scan code         */
-0x53,                  /* 1c   push    bx                              */
-0x81,0xe3,0x3f,0,      /* 1d   and     bx,3fh  ; Drop fncn             */
-0x3c,8,                        /* 21   cmp     al,8h   ; Only meta bit set?    */
-0x74,0xb,              /* 23   je      do_unshifted                    */
-0x3c,0,                        /* 25   cmp     al,0    ; No modifier bits set? */
-0x74,7,                        /* 27   je      do_unshifted                    */
-                       /*  do_shifted:                                 */
-0x2e,0x8a,0x9f,0x80,0, /* 29   mov     bl,cs:shifted_table[bx]         */
-0xeb,5,                        /* 2e   jmp     merge                           */
-                       /*  do_unshifted:                               */
-0x2e,0x8a,0x9f,0xba,0, /* 30   mov     bl,cs:unshifted_table[bx]       */
-                       /*  merge:                                      */
-0x80,0xfb,0,           /* 35   cmp     bl,0    ; No translation?       */
-0x74,0x37,             /* 38   je      abort_translation               */
-0x0f,0xba,0xe0,2,      /* 3a   bt      al,2h   ; Control set?          */
-0x73,3,                        /* 3e   jnc     after_ctrl                      */
-0x80,0xe3,0x9f,                /* 40   and     bl,09fh ; controlify            */
-                       /*  after_ctrl:                                 */
-0x0f,0xba,0xe0,3,      /* 43   bt      al,3h   ; Alt set?              */
-0x73,3,                        /* 47   jnc     after_meta                      */
-0x80,0xcb,0x80,                /* 49   or      bl,080h ; metify                */
-                       /*  after_meta:                                 */
-0x80,0xfb,0xf0,                /* 4c   cmp     bl,0f0h ; M-p ?                 */
-0x74,0x20,             /* 4f   je      abort_translation               */
-0x58,                  /* 51   pop     ax                              */
-0x51,                  /* 52   push    cx      ; Preserve cx           */
-0x50,                  /* 53   push    ax                              */
-0x8a,0xe8,             /* 54   mov     ch,al   ; Scan code             */
-0x80,0xfb,0,           /* 56   cmp     bl,0    ; C-Space?              */
-0x75,2,                        /* 59   jne     after_ctrl_space                */
-0xb5,3,                        /* 5b   mov     ch,3    ; Fudge scan code       */
-                       /*  after_ctrl_space:                           */
-0x8a,0xcb,             /* 5d   mov     cl,bl   ; ASCII value           */
-0xb4,5,                        /* 5f   mov     ah,05h  ; fcn. number           */
-0xcd,0x16,             /* 61   int     16h     ; Record keystroke      */
-0x58,                  /* 63   pop     ax      ; Restore registers     */
-0x59,                  /* 64   pop     cx                              */
-0x5b,                  /* 65   pop     bx                              */
-0x55,                  /* 66   push    bp                              */
-0x8b,0xec,             /* 67   mov     bp,sp                           */
-0x80,0x66,8,0xfe,      /* 69   and     8[bp],0feh  ; clc iret's flags  */
-0x5d,                  /* 6d   pop     bp                              */
-0x9d,                  /* 6e   popf                                    */
-0xf8,                  /* 6f   clc                                     */
-0xcf,                  /* 70   iret                                    */
-                       /*  abort_translation:                          */
-0x58,                  /* 71   pop     ax                              */
-0x5b,                  /* 72   pop     bx                              */
-0xeb,0x8b              /* 73   jmp     chain                           */
-                       /* 75   PAD                                     */
-};
-\f
-#define PATTERN_SIZE           0x75
-#define PADDED_PATTERN_SIZE    0x80
-#define PATTERN_CHAIN_OFFSET   2
-#define PATTERN_START_OFFSET   6
-#define RM_ISR_TABLE_SIZE      0x3a
-#define RM_ISR_TOTAL_SIZE                                      \
-  (PADDED_PATTERN_SIZE + (2 * RM_ISR_TABLE_SIZE) + 1)
-#define RM_ISR_MASK_OFFSET     (RM_ISR_TOTAL_SIZE - 1)
+static unsigned shifted_table_offset = 0;
+static unsigned unshifted_table_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 RM_ISR_MASK_OFFSET             PATTERN_MODIFIER_OFFSET
+                                                                       
 static void *
-make_RM_handler (void)
+make_RM_handler (unsigned * size, unsigned * offset, unsigned * delta)
 {
-  unsigned char * copy;
+  extern void RM_keyboard_pattern_start (void);
+  extern void RM_keyboard_pattern_end (void);
+  unsigned long pattern_start, start_offset;
+  unsigned long pattern_size, total_size;
   unsigned short * wordptr;
+  unsigned char * copy;
+  union REGS regs;
 
-  if (((sizeof (RM_handler_pattern)) != PATTERN_SIZE)
-      || ((sizeof (shifted_scan_code_to_ascii)) != RM_ISR_TABLE_SIZE)
-      || ((sizeof (unshifted_scan_code_to_ascii)) != RM_ISR_TABLE_SIZE)
-      || (RM_ISR_MASK_OFFSET != 0xf4))
-  {
-    fprintf (stderr, "make_RM_handler: Inconsistent sizes!\n");
-    fprintf (stderr, "    PATTERN_SIZE = %d\n", PATTERN_SIZE);
-    fprintf (stderr, "and (sizeof (RM_handler_pattern)) = %d\n",
-            (sizeof (RM_handler_pattern)));
-    fprintf (stderr, "    RM_ISR_TABLE_SIZE = %d\n",
-            RM_ISR_TABLE_SIZE);
-
-    fprintf (stderr, "and (sizeof (shifted_scan_code_to_ascii)) = %d\n",
-            (sizeof (shifted_scan_code_to_ascii)));
-    fprintf (stderr, "and (sizeof (unshifted_scan_code_to_ascii)) = %d\n",
-            (sizeof (unshifted_scan_code_to_ascii)));
-    fprintf (stderr, "    RM_ISR_MASK_OFFSET  = 0x%x <> 0xf4",
-            RM_ISR_MASK_OFFSET);
-    errno = EFAULT;
-    return ((void *) NULL);
-  }
+  regs.x.ax = 0x2509;
+  int86 (0x21, &regs, &regs);
+  start_offset = ((unsigned long) RM_keyboard_pattern_start);
+  pattern_start = ((((unsigned long) regs.x.bx) << 4) + start_offset);
 
-  copy = ((unsigned char *) (malloc (RM_ISR_TOTAL_SIZE)));
+  pattern_size = (((unsigned long) RM_keyboard_pattern_end) - start_offset);
+  total_size = (pattern_size
+               + (sizeof (shifted_scan_code_to_ascii))
+               + (sizeof (unshifted_scan_code_to_ascii)));
+
+  copy = ((unsigned char *) (malloc (total_size)));
   if (copy == ((unsigned char *) NULL))
     return ((void *) NULL);
 
-  memcpy (copy, RM_handler_pattern, (sizeof (RM_handler_pattern)));
-  memcpy ((copy + PADDED_PATTERN_SIZE),
+  farcpy (((unsigned) copy), (getDS ()),
+         ((unsigned) pattern_start), (regs.e.edx >> 16),
+         pattern_size);
+
+  if (copy[PATTERN_START_OFFSET] != ((unsigned char) 0x9c))
+  {
+    fprintf (stderr, "make_RM_handler: Bad pattern!\n");
+    fprintf (stderr, "\tpattern_start = 0x%lx, pattern_size = %d.\n",
+            pattern_start, pattern_size);
+    fprintf (stderr, "\tselector = 0x%x; segment = 0x%x; start_offset = 0x%x.\n",
+            (regs.e.edx >> 16), regs.x.bx, start_offset);
+    free (copy);
+    return ((void *) NULL);
+  }
+
+  memcpy ((copy + pattern_size),
          shifted_scan_code_to_ascii,
-         RM_ISR_TABLE_SIZE);
-  memcpy ((copy + PADDED_PATTERN_SIZE + RM_ISR_TABLE_SIZE),
-         unshifted_scan_code_to_ascii,
-         RM_ISR_TABLE_SIZE);
+         (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)));
+
+  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)))
+              + start_offset);
   wordptr = ((unsigned short *) (copy + PATTERN_CHAIN_OFFSET));
   * wordptr++ = old_RM_vector.x.off;
   * wordptr = old_RM_vector.x.seg;
-  * (copy + RM_ISR_MASK_OFFSET) = modifier_mask;
 
+  * 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)));
   return ((void *) copy);
 }
 
@@ -1011,10 +966,12 @@ DPMI_install_kbd_hook (void)
 \f
   {
     void * RM_handler;
-    unsigned short real_mode_segment;
+    unsigned handler_size, entry_offset, relocation;
     unsigned short prot_mode_selector;
+    unsigned short real_mode_segment;
+    unsigned long base_addr;
 
-    RM_handler = (make_RM_handler ());
+    RM_handler = (make_RM_handler (& handler_size, & entry_offset, & relocation));
     if (RM_handler == ((void *) NULL))
     {
       int saved_errno = errno;
@@ -1024,7 +981,7 @@ DPMI_install_kbd_hook (void)
       return (DOS_FAILURE);
     }
 
-    if ((DPMI_allocate_DOS_block (RM_ISR_TOTAL_SIZE,
+    if ((DPMI_allocate_DOS_block (handler_size,
                                  & real_mode_segment,
                                  & prot_mode_selector))
        != DOS_SUCCESS)
@@ -1037,11 +994,13 @@ DPMI_install_kbd_hook (void)
 
     farcpy (0, prot_mode_selector,
            ((unsigned) RM_handler), (getDS ()),
-           RM_ISR_TOTAL_SIZE);
+           handler_size);
+
+    base_addr = ((((unsigned long) real_mode_segment) << 4) - relocation);
 
     if ((DPMI_RM_setvector (DOS_INTVECT_SYSTEM_SERVICES,
-                           PATTERN_START_OFFSET,
-                           real_mode_segment))
+                           (entry_offset + relocation),
+                           (base_addr >> 4)))
        != DOS_SUCCESS)
     {
       DPMI_free_DOS_block (prot_mode_selector);
@@ -1060,6 +1019,51 @@ DPMI_install_kbd_hook (void)
   return (DOS_SUCCESS);
 }
 \f
+static void
+DPMI_set_modifier_mask (unsigned char new_mask)
+{
+#ifdef DPMI_RM_HANDLER_REAL
+
+  if (DPMI_RM_selector != 0)
+    farcpy (RM_ISR_MASK_OFFSET, DPMI_RM_selector, 
+           ((unsigned) (& new_mask)), (getDS ()),
+           1);
+
+#endif /* DPMI_RM_HANDLER_REAL */
+  return;
+}
+
+static void
+DPMI_set_kbd_translation (unsigned shift_p,
+                         unsigned scan_code,
+                         unsigned char new)
+{
+#ifdef DPMI_RM_HANDLER_REAL
+
+  if (DPMI_RM_selector != 0)
+    farcpy ((scan_code + ((shift_p != 0)
+                         ? shifted_table_offset
+                         : unshifted_table_offset)),
+           DPMI_RM_selector,
+           ((unsigned) (& new)),
+           (getDS ()),
+           1);
+
+#endif /* DPMI_RM_HANDLER_REAL */
+
+  return;
+}
+
+dos_boolean
+under_DPMI_p (void)
+{
+  union REGS regs;
+  
+  regs.e.eax = 0x1686;
+  int86 (0x2f, &regs, &regs);
+  return (regs.x.ax == 0);
+}
+\f
 #ifdef DOSX_RM_HANDLER_REAL
   static unsigned short DOSX_RM_segment = 0;
 #endif /* DOSX_RM_HANDLER_REAL */
@@ -1111,18 +1115,20 @@ DOSX_install_kbd_hook (void)
   {
     void * RM_handler;
     union RM_address new_handler;
+    unsigned handler_size, entry_offset, relocation;
+    unsigned long base_addr;
 
     DOSX_RM_getvector (DOS_INTVECT_SYSTEM_SERVICES,
                       ((unsigned *) & old_RM_vector));
 
-    RM_handler = (make_RM_handler ());
+    RM_handler = (make_RM_handler (& handler_size, & entry_offset, & relocation));
     if (RM_handler == ((void *) NULL))
       return (DOS_FAILURE);
 
 #if 0
 
     if ((DOSX_convert_PM_to_RM_address ((getDS ()), ((unsigned) RM_handler),
-                                       RM_ISR_TOTAL_SIZE,
+                                       handler_size,
                                        ((unsigned *) & new_handler)))
        != DOS_SUCCESS)
     {
@@ -1142,7 +1148,11 @@ DOSX_install_kbd_hook (void)
       return (DOS_FAILURE);
     }
 
-    normalize_RM_address (& new_handler);
+    base_addr = (((new_handler.x.seg << 4) + (new_handler.x.off))
+                - relocation);
+    new_handler.x.seg = (base_addr >> 4);
+    new_handler.x.off = (base_addr & 0xf);
+    new_handler.x.off += (relocation + entry_offset);
 
     if ((DOSX_RM_setvector (DOS_INTVECT_SYSTEM_SERVICES,
                            ((unsigned) new_handler)))
@@ -1156,7 +1166,7 @@ DOSX_install_kbd_hook (void)
 
 #else /* not 0 */
     
-    if ((DOSX_allocate_DOS_block (RM_ISR_TOTAL_SIZE, &new_handler.x.seg))
+    if ((DOSX_allocate_DOS_block (handler_size, &new_handler.x.seg))
        != DOS_SUCCESS)
     {
       int saved_errno = errno;
@@ -1165,7 +1175,6 @@ DOSX_install_kbd_hook (void)
       errno = saved_errno;
       return (DOS_FAILURE);
     }
-    new_handler.x.off = 0;
 
     /* This assumes that the bottom 1 Mb of memory is mapped to the DOS
        memory, so it can be accessed directly.
@@ -1173,18 +1182,25 @@ DOSX_install_kbd_hook (void)
 
     memcpy (((void *) ((unsigned long) new_handler.x.seg << 4)),
            RM_handler,
-           RM_ISR_TOTAL_SIZE);
+           handler_size);
+
+    DOSX_RM_segment = new_handler.x.seg;
+
+    base_addr = ((new_handler.x.seg << 4) - relocation)
+    new_handler.x.seg = (base_addr >> 4);
+    new_handler.x.off = (base_addr & 0xf);
+    new_handler.x.off += (relocation + entry_offset);
 
     if ((DOSX_RM_setvector (DOS_INTVECT_SYSTEM_SERVICES, new_handler.fp))
        != DOS_SUCCESS)
     {
-      DOSX_free_DOS_block (new_handler.x.seg);
+      DOSX_free_DOS_block (DOSX_RM_segment);
+      DOSX_RM_segment = 0;
       fflush (stdout);
       free (RM_handler);
       errno = EFAULT;
       return (DOS_FAILURE);
     }
-    DOSX_RM_segment = new_handler.x.seg;
 
 #endif /* 0 */
 
@@ -1243,45 +1259,165 @@ DOSX_restore_kbd_hook (void)
   return (DOS_SUCCESS);
 }
 \f
-int
-dos_install_kbd_hook (void)
+static void
+DOSX_set_modifier_mask (unsigned char new_mask)
 {
-  if (scheme_PM_vector != ((void *) NULL))
-  {
-    errno = ELOOP;
+#ifdef DOSX_RM_HANDLER_REAL
+
+  if (DOSX_RM_segment != 0)
+    (* ((unsigned char *)
+       ((((unsigned long) DOSX_RM_segment) << 4) + RM_ISR_MASK_OFFSET)))
+      = new_mask;
+
+#endif /* DOSX_RM_HANDLER_REAL */
+  return;
+}
+
+static void
+DOSX_set_kbd_translation (unsigned shift_p,
+                         unsigned scan_code,
+                         unsigned char new)
+{
+#ifdef DOSX_RM_HANDLER_REAL
+
+  if (DOSX_RM_segment != 0)
+    (* ((unsigned char *)
+       ((((unsigned long) DOSX_RM_segment) << 4)
+        + (scan_code + ((shift_p != 0)
+                        ? shifted_table_offset
+                        : unshifted_table_offset)))))
+      = new;
+
+#endif /* DOSX_RM_HANDLER_REAL */
+  return;
+}
+
+static dos_boolean
+under_DOSX_p (void)
+{
+  return (dos_true);
+}
+\f
+/* Zortech's int_intercept does not work consistently with X32.
+   Here is alternative lower-level code.
+ */
+
+extern dos_boolean EXFUN (under_X32_p, (void));
+
+static int
+X32_install_kbd_hook (void)
+{
+  extern int EXFUN (X32_int_intercept, (unsigned, void (*) (void), PTR));
+  extern void EXFUN (X32_keyboard_interrupt, (void));
+  extern PTR X32_kbd_interrupt_pointers[];
+  extern int X32_kbd_interrupt_previous;
+
+  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]);
+
+  if ((X32_int_intercept (DOS_INTVECT_SYSTEM_SERVICES,
+                         X32_keyboard_interrupt,
+                         ((PTR) &X32_kbd_interrupt_previous)))
+      != 0)
     return (DOS_FAILURE);
-  }
-  if (under_DPMI_p ())
-    return (DPMI_install_kbd_hook ());
-  else
-    return (DOSX_install_kbd_hook ());
+  return (DOS_SUCCESS);
 }
 
-int
-dos_restore_kbd_hook (void)
+static int
+X32_restore_kbd_hook (void)
 {
-  if ((scheme_PM_vector == ((void *) NULL))
-      && (scheme_RM_vector == ((void *) NULL)))
-    return (DOS_SUCCESS);
-  else if (!under_DPMI_p ())
-  {
-    if ((DOSX_restore_kbd_hook ()) != DOS_SUCCESS)
-      return (DOS_FAILURE);
-  }
-  else if ((DPMI_restore_kbd_hook ()) != DOS_SUCCESS)
+  extern int EXFUN (X32_interrupt_restore, (unsigned));
+
+  if ((X32_interrupt_restore (DOS_INTVECT_SYSTEM_SERVICES)) != 0)
     return (DOS_FAILURE);
+  return (DOS_SUCCESS);
+}
 
-  if (scheme_PM_vector != ((void *) NULL))
+static void
+X32_set_modifier_mask (unsigned char new_mask)
+{
+  return;
+}
+
+static void
+X32_set_kbd_translation (unsigned shift_p,
+                        unsigned scan_code,
+                        unsigned char new)
+{
+  return;
+}
+\f
+struct keyboard_method_s
+{
+  dos_boolean (* present) (void);
+  int (* install) (void);
+  int (* restore) (void);
+  void (* set_modifier_mask) (unsigned char);
+  void (* set_kbd_translation) (unsigned, unsigned, unsigned char);
+};
+
+static struct keyboard_method_s keyboard_methods[] =
+{
   {
-    free (scheme_PM_vector);
-    scheme_PM_vector = ((void *) NULL);
+    under_DPMI_p,
+    DPMI_install_kbd_hook,
+    DPMI_restore_kbd_hook,
+    DPMI_set_modifier_mask,
+    DPMI_set_kbd_translation
+  },
+  {
+    under_X32_p,
+    X32_install_kbd_hook,
+    X32_restore_kbd_hook,
+    X32_set_modifier_mask,
+    X32_set_kbd_translation
+  },
+  {
+    under_DOSX_p,
+    DOSX_install_kbd_hook,
+    DOSX_restore_kbd_hook,
+    DOSX_set_modifier_mask,
+    DOSX_set_kbd_translation    
   }
-  if (scheme_RM_vector != ((void *) NULL))
+};
+
+struct keyboard_method_s *
+  installed_keyboard_method = ((struct keyboard_method_s *) NULL);
+
+#define N_KEYBOARD_METHODS                                             \
+  ((sizeof (keyboard_methods)) / (sizeof (struct keyboard_method_s)))
+
+int
+dos_install_kbd_hook (void)
+{
+  int i, result;
+
+  for (i = 0; i < N_KEYBOARD_METHODS; i++)
   {
-    free (scheme_RM_vector);
-    scheme_RM_vector = ((void *) NULL);
+    if ((* (keyboard_methods[i].present)) ())
+    {
+      result = ((* (keyboard_methods[i].install)) ());
+      if (result == DOS_SUCCESS)
+       installed_keyboard_method = &keyboard_methods[i];
+      return (result);
+    }
   }
-  return (DOS_SUCCESS);
+  return (DOS_FAILURE);
+}
+\f
+int
+dos_restore_kbd_hook (void)
+{
+  int result;
+
+  if (installed_keyboard_method == ((struct keyboard_method_s *) NULL))
+    return (DOS_SUCCESS);
+  
+  result = (* (installed_keyboard_method->restore)) ();
+  if (result == DOS_SUCCESS)
+    installed_keyboard_method = ((struct keyboard_method_s *) NULL);
+  return (result);
 }
 
 unsigned char
@@ -1291,38 +1427,15 @@ dos_set_kbd_modifier_mask (unsigned char new_mask)
 
   modifier_mask = new_mask;
 
-#ifdef DPMI_RM_HANDLER_REAL
-
-  if (DPMI_RM_selector != 0)
-    farcpy (RM_ISR_MASK_OFFSET, DPMI_RM_selector, 
-           ((unsigned) (& modifier_mask)), (getDS ()),
-           1);
-
-#endif /* DPMI_RM_HANDLER_REAL */
-
-#ifdef DOSX_RM_HANDLER_REAL
-
-  if (DOSX_RM_segment != 0)
-    (* ((unsigned char *)
-       ((((unsigned long) DOSX_RM_segment) << 4) + RM_ISR_MASK_OFFSET)))
-      = modifier_mask;
-
-#endif /* DOSX_RM_HANDLER_REAL */
+  if (installed_keyboard_method != ((struct keyboard_method_s *) NULL))
+    (* (installed_keyboard_method->set_modifier_mask)) (modifier_mask);
 
   return (old_mask);
 }
-\f
+
 extern int EXFUN (dos_set_kbd_translation,
                  (unsigned, unsigned, unsigned char));
 
-#ifndef PADDED_PATTERN_SIZE
-#  define PADDED_PATTERN_SIZE 0
-#endif
-
-#ifndef RM_ISR_TABLE_SIZE
-#  define RM_ISR_TABLE_SIZE 0
-#endif
-
 int
 dos_set_kbd_translation (unsigned shift_p,
                         unsigned scan_code,
@@ -1330,44 +1443,20 @@ dos_set_kbd_translation (unsigned shift_p,
 {
   unsigned char old;
   unsigned char * table;
-  unsigned offset;
 
   if (scan_code >= (sizeof (shifted_scan_code_to_ascii)))
     return (-1);
 
   if (shift_p != 0)
-  {
     table = &shifted_scan_code_to_ascii[0];
-    offset = PADDED_PATTERN_SIZE;
-  }
   else
-  {
     table = &unshifted_scan_code_to_ascii[0];
-    offset = (PADDED_PATTERN_SIZE + RM_ISR_TABLE_SIZE);
-  }
+
   old = table[scan_code];
   table[scan_code] = new;
-                              
 
-#ifdef DPMI_RM_HANDLER_REAL
-
-  if (DPMI_RM_selector != 0)
-    farcpy ((offset + scan_code),
-           DPMI_RM_selector,
-           ((unsigned) (& table[scan_code])),
-           (getDS ()),
-           1);
-
-#endif /* DPMI_RM_HANDLER_REAL */
-
-#ifdef DOSX_RM_HANDLER_REAL
-
-  if (DOSX_RM_segment != 0)
-    (* ((unsigned char *)
-       ((((unsigned long) DOSX_RM_segment) << 4) + offset)))
-      = new;
-
-#endif /* DOSX_RM_HANDLER_REAL */
+  if (installed_keyboard_method != ((struct keyboard_method_s *) NULL))
+    (* (installed_keyboard_method->set_kbd_translation)) (shift_p, scan_code, new);
 
-  return (old);
+  return ((int) old);
 }
index 2147b9daf996f86586aa61775c59db93382d6fa6..57de4b2e8a4ab68b5a7c44733bf297306aca65c7 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Midas-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/doskbutl.asm,v 1.3 1992/07/28 14:30:04 jinx Exp $
+;;;    $Id: doskbutl.asm,v 1.4 1992/09/03 07:30:20 jinx Exp $
 ;;;
 ;;;    Copyright (c) 1992 Massachusetts Institute of Technology
 ;;;
@@ -53,8 +53,9 @@
 ;;4    offset for shifted table
 ;;0    DS for scan_code to ascii tables
 
-       public _DOSX_scheme_system_isr
-       public _DPMI_PM_scheme_system_isr
+       extrn   scheme_system_isr:near
+       public  _DOSX_scheme_system_isr
+       public  _DPMI_PM_scheme_system_isr
 
 _DOSX_scheme_system_isr:
 _DPMI_PM_scheme_system_isr:
@@ -119,111 +120,110 @@ DPMI_scheme_system_dismiss:
        lea     esp,24[esp]             ; pop args
        iret                            ; tell DPMI we're done  
 \f
-;;     Stack on entry to scheme_system_isr
-;;
-;;24    address of modifier mask
-;;20   offset for unshifted table
-;;16   offset for shifted table
-;;12   DS for scan_code to ascii tables
-;;8    Flags to restore/modify
-;;4    EIP for low-level hook (DPMI or DOSX)
-;;0    Old ebp [pushed on entry]
-;;
-;;     Arguments:
-;; AL = scan code
-;; AH = 4fh
-;; CF set
-;;
-;;     Return:
-;; AL = scan code
-;; CF clear if scan code should be ignored (interrupt dismissed).
-
-chain_to_next_handler:
-       stc                             ; set the carry flag
-       ret
-
-scheme_system_isr:
+;; These macros taken from x32's mac32.asm
+
+;Macro for start of a real mode code segment
+start16code     macro
+__X386_CODESEG_16       segment para use16 public 'CODE'
+assume cs:__X386_CODESEG_16,ds:nothing,es:nothing,fs:nothing,gs:nothing,ss:nothing
+endm
+
+;Macro for end of real mode code segment
+end16code       macro
+__X386_CODESEG_16       ends
+endm
+
+start16code
+       public  _RM_keyboard_pattern_start
+_RM_keyboard_pattern_start:
+
+modifier_mask:
+       db 2 dup (0)
+shifted_table_offset:
+       db 2 dup (0)
+unshifted_table_offset:
+       db 2 dup (0)
+
+chain:
+       popf
+       db      0eah                    ; jmpf  next_in_chain
+       db 4 dup (0)
+                       
+kbd_isr:
+       pushf
        cmp     ah,4fh
-       jne     chain_to_next_handler
+       jne     chain
        cmp     al,39h
-        ja      chain_to_next_handler
-
-;; process a keystroke
-
-       push    ebp
-       mov     ebp,esp
-        push    eax             ; Preserve accross interrupt
-
-        mov     ah,2h           ; Get shift bits
-        int     16h             ; Return in AL
-        
-        push    ecx
-        push    edx             ; Preserve regs
-        push    es
-
-        mov     edx,12[ebp]      ; Segment selector
-        push    edx
-        pop     es
-       
-        mov     edx,24[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
-\f
-index_into_table:
-        mov     al,es:[edx] [ecx]  ; Get ASCII value
-        pop     edx             ; Masked modifier bits
-        cmp     al,0            ; Null entries mean chain
-        je      abort_translation
-
-        bt      edx,2           ; Control set?
-        jnc     after_control
-        and     al,09fh         ; Clear bits 6 and 5
-
-after_control:
-        bt      edx,3           ; Alt set?
-        jnc     after_meta
-        or      al,080h         ; Set bit 8
-
+       ja      chain
+       push    bx                      ; Preserve bx
+       push    ax                      ; Preserve scan code
+       mov     ah,2h
+       int     16h                     ; Get modifier bits
+       and     al,byte ptr cs:modifier_mask
+       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
+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:
+       push    si
+       mov     si,word ptr cs:unshifted_table_offset
+       mov     bl,byte ptr cs:[bx+si]
+       pop     si
+merge:
+       cmp     bl,0                    ; No translation?
+       je      abort_translation
+       ; bt    al,2h                   ; Control set?
+       db      0fh,0bah,0e0h,2         ; bt    al,2h
+       jnc     after_ctrl
+       and     bl,09fh                 ; controlify
+after_ctrl:
+       ; bt    al,3h                   ; Alt set?
+       db      0fh,0bah,0e0h,3
+       jnc     after_meta
+       or      bl,080h                 ; metify
 after_meta:
-       cmp     al,0f0h         ; M-p ?
+       cmp     bl,0f0h                 ; M-p ?
        je      abort_translation
-        mov     ecx,-4[ebp]     ; Get scan code
-
-       cmp     al,0            ; C-Space ?
+       pop     ax
+       push    cx                      ; Preserve cx
+       push    ax
+       mov     ch,al                   ; Scan code
+       cmp     bl,0                    ; C-Space?
        jne     after_ctrl_space
-       mov     cl,3            ; Fudge scan code
-
+       mov     ch,3                    ; Fudge scan code
 after_ctrl_space:
-       mov     ch,cl
-        mov     cl,al           ; Transfer ASCII value
-        
-        mov     ah,5h           ; Insert keystroke
-        int     16h             ; CH = scan code, CL = ASCII
-                                ; returns AL = 0h if win, 1h if buffer full
-
-       and     byte ptr 8[ebp],0feh    ; clear interrupt carry flag
-        pop     es
-        pop     edx
-        pop     ecx
-       pop     eax
-       pop     ebp
-       clc                             ; clear our carry flag
-       ret
+       mov     cl,bl                   ; ASCII value
+       mov     ah,05h                  ; fcn. number
+       int     16h                     ; Record keystroke
+       pop     ax                      ; Restore registers
+       pop     cx
+       pop     bx
+       push    bp
+       mov     bp,sp
+       and     8[bp],0feh              ; clc iret's flags
+       pop     bp
+       popf
+       clc
+       iret
 
 abort_translation:
-        pop     es
-        pop     edx
-        pop     ecx
-       pop     eax
-       pop     ebp
-       stc                             ; set carry flag
-       ret
+       pop     ax
+       pop     bx
+       jmp     chain
+       
+       public  _RM_keyboard_pattern_end
+_RM_keyboard_pattern_end:
+       nop
+
+end16code
+
 end
index 0332640db903678eb868631678bf2c1282b70bb4..b71f62c97767465235af7aa3ad0f9c08ed6d0b5f 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/dosscan.h,v 1.1 1992/05/05 06:55:13 jinx Exp $
+$Id: dosscan.h,v 1.2 1992/09/03 07:29:58 jinx Exp $
 
 Copyright (c) 1992 Massachusetts Institute of Technology
 
@@ -44,6 +44,8 @@ MIT in each case. */
 #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'};
@@ -235,9 +237,9 @@ unsigned char META_PLUS[] = {Metafy('+'), '\0'};
 /* 135 */      NO_CONVERSION,                                  \
 /* 136 */      NO_CONVERSION,                                  \
 /* 137 */      NO_CONVERSION,                                  \
-/* 138 */      NO_CONVERSION,                                  \
+/* 138 */      HARD_ATTN,              /* Ctrl-F12 */          \
 /* 139 */      NO_CONVERSION,                                  \
-/* 140 */      NO_CONVERSION,                                  \
+/* 140 */      SOFT_ATTN,              /* Alt-F12 */           \
 /* 141 */      NO_CONVERSION,                                  \
 /* 142 */      NO_CONVERSION,                                  \
 /* 143 */      NO_CONVERSION,                                  \
index 2e5e5fe8df62e6dfc590d4fb0e7d688fc0a270d5..2d57858d83305ed758c3b226f0757366fa13ecd0 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/dossig.c,v 1.4 1992/07/28 14:40:43 jinx Exp $
+$Id: dossig.c,v 1.5 1992/09/03 07:29:39 jinx Exp $
 
 Copyright (c) 1992 Massachusetts Institute of Technology
 
@@ -44,6 +44,8 @@ MIT in each case. */
 #include "dossys.h"
 #include "dosexcp.h"
 #include "doskbd.h"
+
+cc_t EXFUN (DOS_interactive_interrupt_handler, (void));
 \f
 /* Signal Manipulation */
 
@@ -232,12 +234,13 @@ DEFUN (ta_abort_handler, (ap), PTR ap)
                 (((struct handler_record *) ap) -> handler));
 }
 \f
-#define CONTROL_B_INTERRUPT_CHAR 'B'
-#define CONTROL_G_INTERRUPT_CHAR 'G'
-#define CONTROL_U_INTERRUPT_CHAR 'U'
-#define CONTROL_X_INTERRUPT_CHAR 'X'
-#define GENERAL_INTERRUPT_CHAR  '!'
-#define NO_INTERRUPT_CHAR       '0'
+#define CONTROL_B_INTERRUPT_CHAR       'B'
+#define CONTROL_G_INTERRUPT_CHAR       'G'
+#define CONTROL_U_INTERRUPT_CHAR       'U'
+#define CONTROL_X_INTERRUPT_CHAR       'X'
+#define INTERACTIVE_INTERRUPT_CHAR     '!'
+#define TERMINATE_INTERRUPT_CHAR       '@'
+#define NO_INTERRUPT_CHAR              '0'
 
 static void
 DEFUN (echo_keyboard_interrupt, (c, dc), cc_t c AND cc_t dc)
@@ -264,12 +267,17 @@ DEFUN_STD_HANDLER (sighnd_control_g,
     
 DEFUN_STD_HANDLER (sighnd_control_c,
   { 
-    tty_set_next_interrupt_char (GENERAL_INTERRUPT_CHAR);
+    cc_t int_char;
+
+    int_char = (DOS_interactive_interrupt_handler ());
+    if (int_char != ((cc_t) 0))
+      tty_set_next_interrupt_char (int_char);
   })
 
 /* Keyboard interrupt */
 #define KB_INT_TABLE_SIZE              ((256) + 1)
 
+#define CONTROL_BREAK                  '\0'            /* A lie. */
 #define CONTROL_B                      '\002'
 #define CONTROL_C                      '\003'
 #define CONTROL_G                      '\007'
@@ -280,7 +288,8 @@ DEFUN_STD_HANDLER (sighnd_control_c,
 #define CONTROL_G_ENABLE               (0x2)
 #define CONTROL_U_ENABLE               (0x4)
 #define CONTROL_X_ENABLE               (0x8)
-#define GENERAL_INTERRUPT_ENABLE       (0x10)
+#define INTERACTIVE_INTERRUPT_ENABLE   (0x10)
+#define TERMINATE_INTERRUPT_ENABLE     (0x20)
 
 /* This is a table and also a null terminated string. */
 unsigned char keyboard_interrupt_table[KB_INT_TABLE_SIZE];
@@ -289,20 +298,22 @@ static unsigned char keyboard_interrupt_enables;
 void
 DEFUN (OS_ctty_get_interrupt_enables, (mask), Tinterrupt_enables * mask)
 {
-  *mask = (Tinterrupt_enables) keyboard_interrupt_enables;
+  *mask = ((Tinterrupt_enables) keyboard_interrupt_enables);
   return;
 }
 
 void 
 DEFUN (OS_ctty_set_interrupt_enables, (mask), Tinterrupt_enables * mask)
 {
-  keyboard_interrupt_enables = *mask;
+  /* Kludge: ctl-break always enabled. */
+  keyboard_interrupt_enables = (((unsigned char) (*mask))
+                               | TERMINATE_INTERRUPT_ENABLE);
   return;
 }
 \f
 /* This is a temporary kludge. */
 
-#define NUM_INT_CHANNELS 5
+#define NUM_INT_CHANNELS 6
 static cc_t int_chars[NUM_INT_CHANNELS];
 static cc_t int_handlers[NUM_INT_CHANNELS];
 
@@ -337,7 +348,11 @@ DEFUN_VOID (update_interrupt_characters)
        break;
 
       case interrupt_handler_interactive:
-        handler = GENERAL_INTERRUPT_CHAR;
+        handler = INTERACTIVE_INTERRUPT_CHAR;
+       break;
+
+      case interrupt_handler_terminate:
+       handler = TERMINATE_INTERRUPT_CHAR;
        break;
 
       default:
@@ -404,71 +419,138 @@ DEFUN_VOID (initialize_keyboard_interrupt_table)
   int_handlers[3] = ((unsigned char) interrupt_handler_control_x);
   int_chars[4] = CONTROL_C;
   int_handlers[4] = ((unsigned char) interrupt_handler_interactive);
+  int_chars[5] = CONTROL_BREAK;
+  int_handlers[5] = ((unsigned char) interrupt_handler_terminate);
   update_interrupt_characters ();
   keyboard_interrupt_enables =
-    (CONTROL_B_ENABLE | CONTROL_G_ENABLE | CONTROL_U_ENABLE |
-     CONTROL_X_ENABLE | GENERAL_INTERRUPT_ENABLE);
+    (CONTROL_B_ENABLE | CONTROL_G_ENABLE
+     | CONTROL_U_ENABLE | CONTROL_X_ENABLE
+     | INTERACTIVE_INTERRUPT_ENABLE
+     | TERMINATE_INTERRUPT_ENABLE);
+  return;
+}
+  
+static int hard_attn_limit = 2;
+static int hard_attn_counter = 0;
+
+cc_t
+DEFUN (OS_tty_map_interrupt_char, (int_char), cc_t int_char)
+{
+  /* Scheme got a keyboard interrupt, reset the hard attention counter. */
+  hard_attn_counter = 0;
+  return (int_char);
+}
+
+static void
+DEFUN_VOID (print_interrupt_help)
+{ 
+  console_write_string ("\nInterrupt Choices are:\n");
+  console_write_string ("C-G interrupt:    G, g, ^G (abort to top level)\n");
+  console_write_string ("C-X interrupt:    X, x, ^x (abort)\n");
+  console_write_string ("C-B interrupt:    B, b, ^B (break)\n");
+  console_write_string ("C-U interrupt:    U, u, ^U (up)\n");
+  console_write_string ("Ignore interrupt: I, i     (dismiss)\n");
+  console_write_string ("Reset scheme:     R, r     (hard reset)\n");
+  console_write_string ("Quit scheme:      Q, q     (exit)\n");
+  console_write_string ("Print help:       ?");
   return;
 }
 
+#define REQUEST_INTERRUPT_IF_ENABLED(mask) do                          \
+{                                                                      \
+  if (keyboard_interrupt_enables & (mask))                             \
+  {                                                                    \
+    tty_set_next_interrupt_char (interrupt_char);                      \
+    interrupt_p = 1;                                                   \
+  }                                                                    \
+  else                                                                 \
+    interrupt_p = 0;                                                   \
+} while (0)
+\f    
+int EXFUN (signal_keyboard_character_interrupt, (int));
+
 int
-DEFUN (signal_keyboard_character_interrupt, (c), unsigned char c)
+DEFUN (signal_keyboard_character_interrupt, (c), int c)
 {
-  if ((c >= 0) && (c < KB_INT_TABLE_SIZE))
-  { int interrupt_char = keyboard_interrupt_table[c];
-    int interrupt_p;
+  if (c == -1)
+  {
+    if (keyboard_interrupt_enables & TERMINATE_INTERRUPT_ENABLE)
+      goto interactive_interrupt;
+    else
+      return (0);
+  }
+  if (c == -2)
+  {
+    /* Special kludge for hard attn. */
+    if (keyboard_interrupt_enables & TERMINATE_INTERRUPT_ENABLE)
+    {
+      hard_attn_counter += 1;
+      if (hard_attn_counter >= hard_attn_limit)
+      {
+       console_write_string ("\nTerminating scheme!");
+       termination_normal (0);
+      }
+      goto interactive_interrupt;
+    }
+    return (0);
+  }
+  else if ((c >= 0) && (c < KB_INT_TABLE_SIZE))
+  {
+    int interrupt_p, interrupt_char;
+
+    interrupt_char = keyboard_interrupt_table[c];
 
-#define Request_Interrupt_If_Enabled(mask)                     \
-  ( interrupt_p =                                              \
-      ( (keyboard_interrupt_enables&(mask))                    \
-       ? tty_set_next_interrupt_char (interrupt_char), 1 : 0 ))
-    
     switch (interrupt_char)
     { 
       case CONTROL_B_INTERRUPT_CHAR:
-       Request_Interrupt_If_Enabled(CONTROL_B_ENABLE); break;
+       REQUEST_INTERRUPT_IF_ENABLED (CONTROL_B_ENABLE);
+       break;
+
       case CONTROL_G_INTERRUPT_CHAR:
-       Request_Interrupt_If_Enabled(CONTROL_G_ENABLE); break;
+       REQUEST_INTERRUPT_IF_ENABLED (CONTROL_G_ENABLE);
+       break;
+
       case CONTROL_U_INTERRUPT_CHAR:
-       Request_Interrupt_If_Enabled(CONTROL_U_ENABLE); break;
+       REQUEST_INTERRUPT_IF_ENABLED (CONTROL_U_ENABLE);
+       break;
+
       case CONTROL_X_INTERRUPT_CHAR:
-       Request_Interrupt_If_Enabled(CONTROL_X_ENABLE); break;
-      case GENERAL_INTERRUPT_CHAR:
-       Request_Interrupt_If_Enabled(GENERAL_INTERRUPT_ENABLE); break;
+       REQUEST_INTERRUPT_IF_ENABLED (CONTROL_X_ENABLE);
+       break;
+
+      case INTERACTIVE_INTERRUPT_CHAR:
+       if (! (keyboard_interrupt_enables & INTERACTIVE_INTERRUPT_ENABLE))
+       {
+         interrupt_p = 0;
+         break;
+       }
+interactive_interrupt:
+       {
+         cc_t int_char;
+
+         int_char = (DOS_interactive_interrupt_handler ());
+         if (int_char != ((cc_t) 0))
+         {
+           tty_set_next_interrupt_char ((int) int_char);
+           interrupt_p = 1;
+         }
+       }
+       break;
+
       default:
        interrupt_p = 0;
     }
-    return interrupt_p;
+    return (interrupt_p);
   }
-  return 0;
-}      
-
-\f
-static void
-DEFUN_VOID (print_interrupt_help)
-{ 
-  console_write_string("\nInterrupt Choices are:\n");
-  console_write_string("C-G interrupt: G, g, ^G (abort to top level)\n");
-  console_write_string("C-X interrupt: X, x, ^x (abort)\n");
-  console_write_string("C-B interrupt: B, b, ^B (break)\n");
-  console_write_string("C-U interrupt: U, u, ^U (up)\n");
-  console_write_string("Quit scheme:   Q, q\n");
-  console_write_string("Print help:    ?");
-
-  return;
+  return (0);
 }
-  
+\f
 cc_t
-DEFUN (OS_tty_map_interrupt_char, (int_char), cc_t int_char)
-{
-  if ((int_char == CONTROL_B_INTERRUPT_CHAR) ||
-      (int_char == CONTROL_G_INTERRUPT_CHAR) ||
-      (int_char == CONTROL_X_INTERRUPT_CHAR) ||
-      (int_char == CONTROL_U_INTERRUPT_CHAR) )
-    return int_char;
-  
+DEFUN_VOID (DOS_interactive_interrupt_handler)
+{  
   while (1)
-  { unsigned char response;
+  {
+    unsigned char response;
 
     console_write_string
       ("\nKeyboard interrupt, type character (? for help): ");
@@ -488,6 +570,18 @@ DEFUN (OS_tty_map_interrupt_char, (int_char), cc_t int_char)
       case CONTROL_G:
        return CONTROL_G_INTERRUPT_CHAR;
 
+      case 'i':
+      case 'I':
+       return ((cc_t) 0);      
+
+      case 'R':
+      case 'r':
+      {
+       extern void EXFUN (soft_reset, (void));
+       soft_reset ();
+       /*NOTREACHED*/
+      }
+
       case 'q':
       case 'Q':
       {
@@ -526,8 +620,8 @@ DEFUN (OS_tty_map_interrupt_char, (int_char), cc_t int_char)
        print_interrupt_help ();
        break;
       }
-    } /* End CASE */
- }    /* End WHILE */
+    }
+ }
 }
 \f  
 void
@@ -548,7 +642,6 @@ DEFUN_VOID (OS_restartable_exit)
   stop_signal_default (SIGTSTP);
 }
 
-
 #ifdef HAVE_ITIMER
 
 DEFUN_STD_HANDLER (sighnd_timer,
@@ -625,6 +718,7 @@ DEFUN_STD_HANDLER (sighnd_dead_subprocess,
 \f
 /* PC specific low-level interrupt hooks */
 /* Control-Break Interrupt */
+
 int
 DEFUN (control_break_handler, (pd), struct INT_DATA *pd)
 {
@@ -635,23 +729,45 @@ DEFUN (control_break_handler, (pd), struct INT_DATA *pd)
 /* Interval timer */
 
 /* Scheme timer emulation; DOS does not have an ITIMER like unix. */
-/* Zero means timer is not set. */
+/* Zero means timer is not set or has expired. */
 
-extern volatile unsigned long scm_itimer_counter;
-extern volatile unsigned long scm_itimer_reload;
-extern int EXFUN (bios_timer_handler, (struct INT_DATA *));
+extern unsigned long scm_itimer_counter;
+extern unsigned long scm_itimer_reload;
 
-int 
-DEFUN (bios_timer_handler, (pd), struct INT_DATA *pd)
+unsigned long scm_itimer_counter = 0;
+unsigned long scm_itimer_reload = 0;
+
+extern void EXFUN (dos_process_timer_interrupt, (void));
+
+void
+DEFUN_VOID (dos_process_timer_interrupt)
 {
-  if (scm_itimer_reload != 0)
+  if (scm_itimer_counter != 0)
   {
     if (--scm_itimer_counter == 0)
     { 
       scm_itimer_counter = scm_itimer_reload;
-      request_timer_interrupt();
+      request_timer_interrupt ();
     }
   }
+  return;
+}
+
+extern int EXFUN (bios_timer_handler, (struct INT_DATA *));
+
+int 
+DEFUN (bios_timer_handler, (pd), struct INT_DATA *pd)
+{
+#if 0
+  dos_process_timer_interrupt ();
+#else
+  /* This is a kludge for DOS.
+     Reuse INT_Global_GC as a high-priority interrupt from
+     which the keyboard interrupt and real timer interrupt are
+     derived.
+   */
+  REQUEST_INTERRUPT (INT_Global_GC);
+#endif
   return (INTERRUPT_CHAIN_NEXT);
 }
 \f
@@ -867,12 +983,13 @@ DEFUN_VOID (DOS_install_interrupts)
     extern int X32_timer_interrupt_previous;
 
     X32_asm_initialize ();
+
     if ((X32_lock_scheme_microcode ()) != 0)
     {
       fprintf (stderr,
               "\n;; DOS_install_interrupts (X32): Unable to lock memory.");
       fprintf (stderr,
-              "\n;; Timer interrupt not available!\n");
+              "\n;; Interrupt and exceptions handlers not available!\n");
       fflush (stderr);
       return;
     }
@@ -887,43 +1004,39 @@ DEFUN_VOID (DOS_install_interrupts)
       fprintf (stderr,
               "\n;; Timer interrupt not available!\n");
       fflush (stderr);
-      return;
     }
     else
       dos_record_interrupt_interception (DOS_INTVECT_USER_TIMER_TICK,
                                         X32_interrupt_restore);
-    if ((dos_install_kbd_hook ()) == DOS_SUCCESS)
-    {
-      dos_record_interrupt_interception (DOS_INTVECT_SYSTEM_SERVICES,
-                                        DOS_restore_keyboard);
-      DOS_keyboard_intercepted_p = true;    
-    }
+
     install_exception_handlers (X32_get_exception_vector,
                                X32_set_exception_handler,
                                X32_restore_handler);
   }
+\f
   else
   {
     scm_int_intercept (DOS_INTVECT_USER_TIMER_TICK, 
                       bios_timer_handler, 
                       256);
 
-    if ((dos_install_kbd_hook ()) == DOS_SUCCESS)
-    {
-      dos_record_interrupt_interception (DOS_INTVECT_SYSTEM_SERVICES,
-                                        DOS_restore_keyboard);
-      DOS_keyboard_intercepted_p = true;    
-    }
-
     if (!under_DPMI_p ())
       scm_int_intercept (DOS_INTVECT_KB_CTRL_BREAK,
                         control_break_handler,
                         256);
+
     else if (enable_DPMI_exceptions_p ())
       install_exception_handlers (DPMI_get_exception_vector,
                                  DPMI_set_exception_handler,
                                  DPMI_restore_handler);
   }
+
+  if ((dos_install_kbd_hook ()) == DOS_SUCCESS)
+  {
+    dos_record_interrupt_interception (DOS_INTVECT_SYSTEM_SERVICES,
+                                      DOS_restore_keyboard);
+    DOS_keyboard_intercepted_p = true;    
+  }
   return;
 }
 
index f9cdd0ccdccc848822cfed82299767904d737dff..5c42ce2b1c6c85db64ac67e2b425e9e5a9006edb 100644 (file)
@@ -1,6 +1,6 @@
 /* -*-C-*-
 
-$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/dosx32.c,v 1.1 1992/07/28 17:55:42 jinx Exp $
+$Id: dosx32.c,v 1.2 1992/09/03 07:30:13 jinx Exp $
 
 Copyright (c) 1992 Massachusetts Institute of Technology
 
@@ -42,31 +42,25 @@ extern int EXFUN (X32_lock_scheme_microcode, (void));
 
 extern int EXFUN (under_X32_p, (void));
 
-#ifdef USE_LOCKED_INT_INTERCEPT
-
-extern int EXFUN (locked_int_intercept,
-                 (unsigned,
-                  int (_cdecl * funcptr) (struct INT_DATA *),
-                  unsigned));
-
-extern void EXFUN (locked_int_restore, (unsigned));
-
-/* Imports */
-
-extern void EXFUN (int_service, (void));
-
-#else /* not USE_LOCKED_INT_INTERCEPT */
-
 extern int EXFUN (X32_interrupt_restore, (unsigned));
 
 extern int EXFUN (X32_int_intercept, (unsigned, void (*) (void), PTR));
 
-#endif /* USE_LOCKED_INT_INTERCEPT */
-
 extern unsigned short EXFUN (getCS, (void));
 
 extern unsigned short EXFUN (getDS, (void));
 
+int
+DEFUN_VOID (under_X32_p)
+{
+  union REGS regs;
+  
+  regs.x.bx = (getDS ());
+  regs.x.ax = 0x3504;
+  int86 (0x21, &regs, &regs);
+  return ((regs.e.flags & 1) == 0);
+}
+
 #define I486_PAGE_SIZE 4096
 
 #define OPERATION_LOCK         0
@@ -105,7 +99,7 @@ DEFUN (lock_unlock, (operation, segment, offset, size),
   return (((regs.e.flags & 1) != 0) ? -1 : 0);
 }
 \f
-int
+static int
 DEFUN (lock_region, (segment, offset, size),
        unsigned short segment
        AND PTR offset
@@ -114,7 +108,7 @@ DEFUN (lock_region, (segment, offset, size),
   return (lock_unlock (OPERATION_LOCK, segment, offset, size));
 }
 
-int
+static int
 DEFUN (unlock_region, (segment, offset, size),
        unsigned short segment
        AND PTR offset
@@ -122,263 +116,79 @@ DEFUN (unlock_region, (segment, offset, size),
 {
   return (lock_unlock (OPERATION_UNLOCK, segment, offset, size));
 }
-
-#ifdef USE_LOCKED_INT_INTERCEPT
-
-extern PTR EXFUN (malloc, (unsigned long));
-extern int EXFUN (free, (PTR));
-
-PTR
-DEFUN (locked_malloc, (size), unsigned long size)
-{
-  PTR block;
-
-  block = (malloc (size));
-  if (block == ((PTR) NULL))
-    return (block);
-  if ((lock_region ((getDS ()), block, size)) != 0)
-  {
-    free (block);
-    return ((PTR) NULL);
-  }
-  return (block);
-}
-
-void
-DEFUN (locked_free, (block, size),
-       PTR block AND unsigned long size)
-{
-  if ((unlock_region ((getDS ()), block, size)) != 0)
-    return;
-  free (block);
-  return;
-}
 \f
-#pragma ZTC align 1                    /* no alignment for DOS structs */
+#define ES     0
+#define CS     1
+#define SS     2
+#define DS     3
 
-struct trampoline
+struct wired_area_s
 {
-  unsigned char callf;         /* CALLF opcode */
-  PTR off;                     /* CALLF offset */
-  unsigned short seg;          /* CALLF segment */
-  struct INT_DATA closure;
-  unsigned short datasel;
+  int seg;
+  PTR start;
+  PTR end;
 };
-
-#pragma ZTC align
-
-
-#define MIN_STACK_SIZE 128
-
-
-void
-DEFUN (locked_int_restore, (vectornumber),
-       unsigned vectornumber)
-{
-  union REGS regs;
-  struct SREGS sregs;
-  struct trampoline * tramp;
-  struct INT_DATA * clos;
   
-  /* Get protected mode interrupt vector. */
-
-  {
-    regs.x.ax = 0x2502;
-    regs.h.cl = vectornumber;
-    segread (&sregs);
-    int86x (0x21, &regs, &regs, &sregs);
-    if ((regs.e.flags & 1) != 0)
-      return;
-    tramp = ((struct trampoline *) regs.e.ebx);
-  }
-
-  clos = &tramp->closure;
-
-  /* Restore previous vectors */
-  {
-    regs.x.ax = 0x2507;
-    regs.h.cl = vectornumber;
-    segread (&sregs);
-    sregs.ds = clos->prevvec_seg;
-    regs.e.edx = clos->prevvec_off;
-    regs.e.ebx = (* ((unsigned long *) &clos->prevvecr_off));
-    int86x (0x21, &regs, &regs, &sregs);
-    if ((regs.e.flags & 1) != 0)
-      return;
-  }
-
-  if (clos->stacksize != 0)
-    locked_free (((PTR) (((char *) clos->newstack_off) - clos->stacksize)),
-                clos->stacksize);
-
-  locked_free (((PTR) tramp), (sizeof (struct trampoline)));
-  return;
-}
-\f
-int
-DEFUN (locked_int_intercept, (vectornumber, handler, stacksize),
-       unsigned vectornumber
-       AND int EXFUN ((_cdecl * handler), (struct INT_DATA *))
-       AND unsigned stacksize)
+extern unsigned X32_locked_data_start;
+extern unsigned X32_locked_data_end;
+extern void EXFUN (X32_locked_code_start, (void));
+extern void EXFUN (X32_locked_code_end, (void));
+extern unsigned char scan_code_tables_start[];
+extern unsigned char scan_code_tables_end[];
+
+static struct wired_area_s wired_areas[] =
 {
-  extern void EXFUN (int_setvector, (unsigned, unsigned, unsigned));
-  union REGS regs;
-  struct SREGS sregs;
-  struct trampoline * tramp;
-  struct INT_DATA * clos;
-  
-  tramp = ((struct trampoline *)
-          (locked_malloc (sizeof (struct trampoline))));
-  if (tramp == ((struct trampoline *) NULL))
-    return (-1);
-  
-  tramp->callf = 0x9a;
-  tramp->off = ((PTR) int_service);
-  tramp->seg = (getCS ());
-  
-  clos = &tramp->closure;
-
-  if (stacksize == 0)
   {
-    clos->stacksize = 0;
-    clos->newstack_off = 0;
-    clos->newstack_seg = 0;
-  }
-  else
+    DS,
+    ((PTR) &X32_locked_data_start),
+    ((PTR) &X32_locked_data_end)
+  },
   {
-    PTR stack;
-
-    if (stacksize < MIN_STACK_SIZE)
-      stacksize = MIN_STACK_SIZE;
-    
-    stack = (locked_malloc (stacksize));
-    if (stack == ((PTR) NULL))
-    {
-      locked_free (((PTR) tramp), (sizeof (struct trampoline)));
-      return (-1);
-    }
-
-    clos->stacksize = stacksize;
-    clos->newstack_off = ((unsigned) (((char *) stack) + stacksize));
-    clos->newstack_seg = (getDS ());
-  }
-  clos->funcptr = handler;
-  
-  /* Preserve previous real mode interrupt handler */
-
+    CS,
+    ((PTR) X32_locked_code_start),
+    ((PTR) X32_locked_code_end)
+  },
   {
-    regs.x.ax = 0x2503;
-    regs.h.cl = vectornumber;
-    int86 (0x21, &regs, &regs);
-    if ((regs.e.flags & 1) != 0)
-    {
-error_getting_old_handlers:
-      if (clos->stacksize != 0)
-       locked_free (((PTR) (((char *) clos->newstack_off) - clos->stacksize)),
-                    clos->stacksize);
-      locked_free (((PTR) tramp), (sizeof (struct trampoline)));
-      return (-1);
-    }
-    * ((unsigned *) &clos->prevvecr_off) = regs.e.ebx;
+    DS,
+    ((PTR) &scan_code_tables_start[0]),
+    ((PTR) &scan_code_tables_end[0])
   }
+};
 
-  /* Preserve previous protected mode interrupt handler. */
-  
-  {
-    regs.x.ax = 0x2502;
-    regs.h.cl = vectornumber;
-    segread (&sregs);
-    int86x (0x21, &regs, &regs, &sregs);
-    if ((regs.e.flags & 1) != 0)
-      goto error_getting_old_handlers;
-
-    clos->prevvec_off = regs.e.ebx;
-    clos->prevvec_seg = sregs.es;
-  }
-  tramp->datasel = (getDS ());
+#define N_WIRED_AREAS ((sizeof (wired_areas)) / (sizeof (struct wired_area_s)))
 
-  int_setvector (vectornumber, ((unsigned) tramp), (getCS ()));
-  return (0);
-}
-#endif /* USE_LOCKED_INT_INTERCEPT */
-\f
 int
 DEFUN_VOID (X32_lock_scheme_microcode)
 {
-  extern unsigned X32_locked_data_start;
-  extern unsigned X32_locked_data_end;
-#ifdef USE_LOCKED_INT_INTERCEPT
-  extern int EXFUN (bios_timer_handler, (struct INT_DATA *));
-  extern void EXFUN (bios_timer_handler_end, (void));
-#else
-  extern void EXFUN (X32_locked_code_start, (void));
-  extern void EXFUN (X32_locked_code_end, (void));
-#endif
-  unsigned short cs, ds;
+  int i, j;
+  unsigned short cs, ds, sel;
 
   ds = (getDS ());
   cs = (getCS ());
 
-  if ((lock_region (ds, ((PTR) &X32_locked_data_start),
-                   (((unsigned long) &X32_locked_data_end)
-                    - ((unsigned long) &X32_locked_data_start))))
-      != 0)
-    return (-1);
-
-#ifdef USE_LOCKED_INT_INTERCEPT
-  if ((lock_region (cs, ((PTR) bios_timer_handler),
-                   (((unsigned long) bios_timer_handler_end)
-                    - ((unsigned long) bios_timer_handler))))
-      != 0)
-  {
-    unlock_region (ds, ((PTR) &X32_locked_data_start),
-                  (((unsigned long) &X32_locked_data_end)
-                   - ((unsigned long) &X32_locked_data_start)));
-    return (-1);
-  }
-  if ((lock_region (cs, ((PTR) int_service),
-                   (((unsigned long) int_intercept)
-                    - ((unsigned long) int_service))))
-      != 0)
-  {
-    unlock_region (ds, ((PTR) &X32_locked_data_start),
-                  (((unsigned long) &X32_locked_data_end)
-                   - ((unsigned long) &X32_locked_data_start)));
-    unlock_region (cs, ((PTR) bios_timer_handler),
-                  (((unsigned long) bios_timer_handler_end)
-                   - ((unsigned long) bios_timer_handler)));
-    return (-1);
-  }
-#else /* not USE_LOCKED_INT_INTERCEPT */
-
-  if ((lock_region (cs, ((PTR) X32_locked_code_start),
-                   (((unsigned long) X32_locked_code_end)
-                    - ((unsigned long) X32_locked_code_start))))
-      != 0)
+  for (i = 0; i < N_WIRED_AREAS; i++)
   {
-    unlock_region (ds, ((PTR) &X32_locked_data_start),
-                  (((unsigned long) &X32_locked_data_end)
-                   - ((unsigned long) &X32_locked_data_start)));
-    return (-1);
+    sel = ((wired_areas[i].seg == CS) ? cs : ds);
+    if ((lock_region (sel,
+                     wired_areas[i].start,
+                     (((unsigned long) wired_areas[i].end)
+                      - ((unsigned long) wired_areas[i].start))))
+       != 0)
+    {
+      while (--i >= 0)
+      {
+       sel = ((wired_areas[i].seg == CS) ? cs : ds);
+       (void) unlock_region (sel,
+                             wired_areas[i].start,
+                             (((unsigned long) wired_areas[i].end)
+                              - ((unsigned long) wired_areas[i].start)));
+      }
+      return (-1);
+    }
   }
-
-#endif /* USE_LOCKED_INT_INTERCEPT */
   return (0);
 }
-
-int
-DEFUN_VOID (under_X32_p)
-{
-  union REGS regs;
-  
-  regs.x.bx = (getDS ());
-  regs.x.ax = 0x3504;
-  int86 (0x21, &regs, &regs);
-  return ((regs.e.flags & 1) == 0);
-}
 \f
-#ifndef USE_LOCKED_INT_INTERCEPT
-
 struct save_area
 {
   unsigned protected_offset;
@@ -436,7 +246,7 @@ DEFUN (X32_interrupt_restore, (iv), unsigned iv)
   }
   return (-1);
 }
-
+\f
 int
 DEFUN (X32_remember_interrupt, (iv, area),
        unsigned iv
@@ -508,5 +318,3 @@ DEFUN (X32_int_intercept, (iv, handler, ptr),
   }
   return (0);
 }
-
-#endif /* USE_LOCKED_INT_INTERCEPT */
index 368384c775c3c3df95dbc7537f7533ffe999bd83..684b6c3803194899a036902b210d690b1b44ba1c 100644 (file)
@@ -1,6 +1,6 @@
 ;;; -*-Midas-*-
 ;;;
-;;;    $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/Attic/dosxcutl.asm,v 1.2 1992/07/28 14:26:03 jinx Exp $
+;;;    $Id: dosxcutl.asm,v 1.3 1992/09/03 07:30:06 jinx Exp $
 ;;;
 ;;;    Copyright (c) 1992 Massachusetts Institute of Technology
 ;;;
@@ -378,24 +378,31 @@ common_different_stacks:
 ;;     it cannot process a page fault.
 
        .data
+
        public _X32_locked_data_start
-_X32_locked_data_start dd 0
+_X32_locked_data_start                         dd 0
 
-X32_excp_buffer                        db 64 dup(0)
+X32_excp_buffer                                db 64 dup(0)
        public  _X32_excp_handlers
-_X32_excp_handlers             db 32*20 dup (0)
+_X32_excp_handlers                     db 32*20 dup (0)
 
        public _X32_ds_val
-_X32_ds_val    dd 06765h
+_X32_ds_val                            dd 06765h
+
        public _X32_timer_interrupt_previous
-_X32_timer_interrupt_previous  dd 0
-                               dd 0
-                               dd 0
+_X32_timer_interrupt_previous          dd 0
+                                       dd 0
+                                       dd 0
 
-       public _scm_itimer_counter
-_scm_itimer_counter dd 0
-       public _scm_itimer_reload
-_scm_itimer_reload dd 0
+       public _X32_kbd_interrupt_previous
+_X32_kbd_interrupt_previous            dd 0
+                                       dd 0
+                                       dd 0
+
+       public _X32_kbd_interrupt_pointers
+_X32_kbd_interrupt_pointers            dd 0
+                                       dd 0
+                                       dd 0
 
        public _IntCode                 ; These are usually declared in C,
 _IntCode dd 0                          ; but they need to be locked since
@@ -548,23 +555,22 @@ X32_set_up_trap_sp_merge:
 ;;     executing as a normal program again), so it should be able to
 ;;     page it in if necessary.
 \f
-;;     X32 timer interrupt.
-;;     Must be locked in memory (and all the data it accesses.
+;;;;   X32 interrupt handlers:
+;;     Must be locked in memory (and all the data they access).
+
+;;     X32 timer interrupt handler.
+;;     This signals Scheme's "global GC interrupt", a high-priority
+;;     timer interrupt from which the keyboard and real timer
+;;     interrupts are derived.
 
-INT_Timer equ 64                       ; This must agree with intrpt.h
+INT_Timer equ 2                                ; This must agree with intrpt.h
+;;     INT_Timer equ 64
 
        public  _X32_timer_interrupt
 _X32_timer_interrupt:
        push    ds
        mov     ds,cs:_X32_ds_val
-       cmp     dword ptr _scm_itimer_reload,0
-       je      x32_timer_return
-       dec     dword ptr _scm_itimer_counter
-       cmp     dword ptr _scm_itimer_counter,0
-       jne     x32_timer_return
        push    eax
-       mov     eax,dword ptr _scm_itimer_reload
-       mov     dword ptr _scm_itimer_counter,eax
        or      _IntCode,INT_Timer
        mov     eax,_IntCode
        and     eax,_IntEnb
@@ -579,10 +585,151 @@ x32_timer_return:
        pop     ds
        jmp     fword ptr cs:_X32_timer_interrupt_previous
 
+;;     X32 keyboard interrupt handler
+;;     This performs scan-code to ASCII translation in order
+;;     not to drop the bucky bits.
+;;
+
+       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[8]
+       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]
+       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     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
+       iretd
+\f
+;;     Stack on entry to scheme_system_isr
+;;
+;;24    address of modifier mask
+;;20   offset for unshifted table
+;;16   offset for shifted table
+;;12   DS for scan_code to ascii tables
+;;8    Flags to restore/modify
+;;4    EIP for low-level hook (DPMI or DOSX)
+;;0    Old ebp [pushed on entry]
+;;
+;;     Arguments:
+;; AL = scan code
+;; AH = 4fh
+;; CF set
+;;
+;;     Return:
+;; AL = scan code
+;; CF clear if scan code should be ignored (interrupt dismissed).
+
+chain_to_next_handler:
+       stc                             ; set the carry flag
+       ret
+
+       public  scheme_system_isr
+scheme_system_isr:
+       cmp     ah,4fh
+       jne     chain_to_next_handler
+       cmp     al,39h
+        ja      chain_to_next_handler
+
+;; process a keystroke
+
+       push    ebp
+       mov     ebp,esp
+        push    eax             ; Preserve accross interrupt
+
+        mov     ah,2h           ; Get shift bits
+        int     16h             ; Return in AL
+        
+        push    ecx
+        push    edx             ; Preserve regs
+        push    es
+
+        mov     edx,12[ebp]      ; Segment selector
+        push    edx
+        pop     es
+       
+        mov     edx,24[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
+\f
+index_into_table:
+        mov     al,es:[edx] [ecx]  ; Get ASCII value
+        pop     edx             ; Masked modifier bits
+        cmp     al,0            ; Null entries mean chain
+        je      abort_translation
+
+        bt      edx,2           ; Control set?
+        jnc     after_control
+        and     al,09fh         ; Clear bits 6 and 5
+
+after_control:
+        bt      edx,3           ; Alt set?
+        jnc     after_meta
+        or      al,080h         ; Set bit 8
+
+after_meta:
+       cmp     al,0f0h         ; M-p ?
+       je      abort_translation
+        mov     ecx,-4[ebp]     ; Get scan code
+
+       cmp     al,0            ; C-Space ?
+       jne     after_ctrl_space
+       mov     cl,3            ; Fudge scan code
+
+after_ctrl_space:
+       mov     ch,cl
+        mov     cl,al           ; Transfer ASCII value
+        
+        mov     ah,5h           ; Insert keystroke
+        int     16h             ; CH = scan code, CL = ASCII
+                                ; returns AL = 0h if win, 1h if buffer full
+
+       and     byte ptr 8[ebp],0feh    ; clear interrupt carry flag
+        pop     es
+        pop     edx
+        pop     ecx
+       pop     eax
+       pop     ebp
+       clc                             ; clear our carry flag
+       ret
+
+abort_translation:
+        pop     es
+        pop     edx
+        pop     ecx
+       pop     eax
+       pop     ebp
+       stc                             ; set carry flag
+       ret
+\f
        public  _X32_locked_code_end
 _X32_locked_code_end:
 
-
 X32_set_up_trap_stack:
        push    4[edx]                  ; Trapped SS
        push    0[edx]                  ; Trapped ESP