- 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.
/* -*-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
#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
#define fileno(fp) ((fp)->_file)
#endif
-\f
#define CONIO_BUFFER_SIZE (1024)
#define TYPEAHEAD_BUFFER_SIZE (1024)
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;
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)
{
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++;
}
}
else if (conversion == CTRL_AT)
length = 1;
else
- length = strlen (conversion);
+ length = (strlen (conversion));
max_scancode_conversion_length
= Max (length, max_scancode_conversion_length);
}
{
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);
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;
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)
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)
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)
{
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];
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)
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;
}
/* -*-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
#undef getDS
#endif
+#ifdef getCS
+#undef getCS
+#endif
+
#include "dossys.h"
#include "dosinsn.h"
#include "doskbd.h"
#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[] =
{
'\0', /* 56 */
' ' /* 57 */
};
-\f
+\f
static unsigned char
unshifted_scan_code_to_ascii[] =
{
};
static unsigned char modifier_mask = 0x4f;
+
+unsigned char
+scan_code_tables_end[] = "bar";
\f
union RM_address
{
return (dos_false);
}
-dos_boolean
-under_DPMI_p (void)
-{
- union REGS regs;
-
- regs.e.eax = 0x1686;
- int86 (0x2f, ®s, ®s);
- return (regs.x.ax == 0);
-}
-
static void
normalize_RM_address (union RM_address * addr)
{
#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;
\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, ®s, ®s);
+ 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);
}
\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;
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)
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);
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, ®s, ®s);
+ return (regs.x.ax == 0);
+}
+\f
#ifdef DOSX_RM_HANDLER_REAL
static unsigned short DOSX_RM_segment = 0;
#endif /* DOSX_RM_HANDLER_REAL */
{
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)
{
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)))
#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;
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.
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 */
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
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,
{
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);
}
;;; -*-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
;;;
;;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:
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
/* -*-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
#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'};
/* 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, \
/* -*-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
#include "dossys.h"
#include "dosexcp.h"
#include "doskbd.h"
+
+cc_t EXFUN (DOS_interactive_interrupt_handler, (void));
\f
/* Signal Manipulation */
(((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)
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'
#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];
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];
break;
case interrupt_handler_interactive:
- handler = GENERAL_INTERRUPT_CHAR;
+ handler = INTERACTIVE_INTERRUPT_CHAR;
+ break;
+
+ case interrupt_handler_terminate:
+ handler = TERMINATE_INTERRUPT_CHAR;
break;
default:
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): ");
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':
{
print_interrupt_help ();
break;
}
- } /* End CASE */
- } /* End WHILE */
+ }
+ }
}
\f
void
stop_signal_default (SIGTSTP);
}
-
#ifdef HAVE_ITIMER
DEFUN_STD_HANDLER (sighnd_timer,
\f
/* PC specific low-level interrupt hooks */
/* Control-Break Interrupt */
+
int
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
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;
}
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;
}
/* -*-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
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, ®s, ®s);
+ return ((regs.e.flags & 1) == 0);
+}
+
#define I486_PAGE_SIZE 4096
#define OPERATION_LOCK 0
return (((regs.e.flags & 1) != 0) ? -1 : 0);
}
\f
-int
+static int
DEFUN (lock_region, (segment, offset, size),
unsigned short segment
AND PTR offset
return (lock_unlock (OPERATION_LOCK, segment, offset, size));
}
-int
+static int
DEFUN (unlock_region, (segment, offset, size),
unsigned short segment
AND PTR offset
{
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, ®s, ®s, &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, ®s, ®s, &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, ®s, ®s);
- 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, ®s, ®s, &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, ®s, ®s);
- return ((regs.e.flags & 1) == 0);
-}
\f
-#ifndef USE_LOCKED_INT_INTERCEPT
-
struct save_area
{
unsigned protected_offset;
}
return (-1);
}
-
+\f
int
DEFUN (X32_remember_interrupt, (iv, area),
unsigned iv
}
return (0);
}
-
-#endif /* USE_LOCKED_INT_INTERCEPT */
;;; -*-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
;;;
;; 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
;; 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
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