From: Guillermo J. Rozas Date: Sat, 21 Aug 1993 03:54:51 +0000 (+0000) Subject: - Handle address relocation to allow the NT version of Scheme to run X-Git-Tag: 20090517-FFI~8031 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=9d80dd54799cfd552fdaf2cfc54cf30945cc222c;p=mit-scheme.git - Handle address relocation to allow the NT version of Scheme to run under Windows 3.1. - Cleanup of the NT sources. Remove DOS fossils. --- diff --git a/v7/src/microcode/ntsig.c b/v7/src/microcode/ntsig.c index b35e603f9..4ec8e4ac0 100644 --- a/v7/src/microcode/ntsig.c +++ b/v7/src/microcode/ntsig.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: ntsig.c,v 1.6 1993/07/27 21:00:54 gjr Exp $ +$Id: ntsig.c,v 1.7 1993/08/21 03:45:54 gjr Exp $ Copyright (c) 1992-1993 Massachusetts Institute of Technology @@ -40,54 +40,21 @@ MIT in each case. */ #include "scheme.h" #include "nt.h" #include -/*#include SRA*/ #include "ossig.h" #include "osctty.h" #include "ostty.h" #include "critsec.h" -/*#include SRA*/ #include "ntsys.h" #include "ntio.h" -#include "ntexcp.h" -#include "ntkbd.h" -#ifdef USE_ZORTECH_CERROR -#include -#endif #include "extern.h" #include "ntutil.h" #include "ntscreen.h" #include "ntscmlib.h" - -#ifndef fileno -#define fileno(fp) ((fp)->_file) -#endif - -cc_t EXFUN (DOS_interactive_interrupt_handler, (void)); -/* Signal Manipulation */ - -#ifdef UNUSED - -static Tsignal_handler -DEFUN (current_handler, (signo), int signo) -{ - Tsignal_handler result = (DOS_signal (signo, SIG_IGN)); - if (result != SIG_IGN) - DOS_signal (signo, result); - return (result); -} -#endif /* UNUSED */ - -#define INSTALL_HANDLER DOS_signal -#define NEED_HANDLER_TRANSACTION - -#define ENTER_HANDLER(signo) -#define ABORT_HANDLER DOS_signal -#define EXIT_HANDLER DOS_signal +/* Signal mask manipulation */ - -/* These could be implemented, at least under DPMI by examining - and setting the virtual interrupt state. +/* These could be implemented, at least under Win32s/DPMI + by examining and setting the virtual interrupt state. */ void @@ -108,159 +75,6 @@ DEFUN_VOID (unblock_signals) return; } -#ifdef UNUSED -/* Signal Descriptors */ - -enum dfl_action { dfl_terminate, dfl_ignore, dfl_stop }; - -struct signal_descriptor -{ - int signo; - CONST char * name; - enum dfl_action action; - int flags; -}; - -/* `flags' bits */ -#define NOIGNORE 1 -#define NOBLOCK 2 -#define NOCATCH 4 -#define CORE_DUMP 8 - -static struct signal_descriptor * signal_descriptors; -static unsigned int signal_descriptors_length; -static unsigned int signal_descriptors_limit; - -static void -DEFUN (defsignal, (signo, name, action, flags), - int signo AND - CONST char * name AND - enum dfl_action action AND - int flags) -{ - if (signo == 0) - return; - if (signal_descriptors_length == signal_descriptors_limit) - { - signal_descriptors_limit += 8; - signal_descriptors = - (DOS_realloc (signal_descriptors, - (signal_descriptors_limit * - (sizeof (struct signal_descriptor))))); - if (signal_descriptors == 0) - { - outf_fatal ("\nUnable to grow signal definitions table.\n"); - termination_init_error (); - } - } - { - struct signal_descriptor * sd = - (signal_descriptors + (signal_descriptors_length++)); - (sd -> signo) = signo; - (sd -> name) = name; - (sd -> action) = action; - (sd -> flags) = flags; - } -} - -static struct signal_descriptor * -DEFUN (find_signal_descriptor, (signo), int signo) -{ - struct signal_descriptor * scan = signal_descriptors; - struct signal_descriptor * end = (scan + signal_descriptors_length); - for (; (scan < end); scan += 1) - if ((scan -> signo) == signo) - return (scan); - return (0); -} - -CONST char * -DEFUN (find_signal_name, (signo), int signo) -{ - static char buffer [32]; - struct signal_descriptor * descriptor = (find_signal_descriptor (signo)); - if (descriptor != 0) - return (descriptor -> name); - sprintf (buffer, "unknown signal %d", signo); - return ((CONST char *) buffer); -} - -#define OS_SPECIFIC_SIGNALS() - -#if (SIGABRT == SIGIOT) -#undef SIGABRT -#define SIGABRT 0 -#endif - -static void -DEFUN_VOID (initialize_signal_descriptors) -{ - signal_descriptors_length = 0; - signal_descriptors_limit = 32; - signal_descriptors = - (DOS_malloc (signal_descriptors_limit * - (sizeof (struct signal_descriptor)))); - if (signal_descriptors == 0) - { - outf_error ("\nUnable to allocate signal definitions table.\n"); - termination_init_error (); - } - - defsignal (SIGINT, "SIGINT", dfl_terminate, 0); - defsignal (SIGILL, "SIGILL", dfl_terminate, CORE_DUMP); - defsignal (SIGFPE, "SIGFPE", dfl_terminate, CORE_DUMP); - defsignal (SIGSEGV, "SIGSEGV", dfl_terminate, CORE_DUMP); - defsignal (SIGTERM, "SIGTERM", dfl_terminate, 0); - defsignal (SIGABRT, "SIGABRT", dfl_terminate, CORE_DUMP); - - OS_SPECIFIC_SIGNALS (); -} -#endif - -/* Signal Handlers */ - -struct handler_record -{ - int signo; - Tsignal_handler handler; -}; - -#define DEFUN_STD_HANDLER(name, statement) \ -static Tsignal_handler_result \ -DEFUN (name, (signo), int signo) \ -{ \ - int STD_HANDLER_abortp; \ - ENTER_HANDLER (signo); \ - STD_HANDLER_abortp = (enter_interruption_extent ()); \ - transaction_begin (); \ - { \ - struct handler_record * record = \ - (dstack_alloc (sizeof (struct handler_record))); \ - (record -> signo) = signo; \ - (record -> handler) = 0; \ - transaction_record_action (tat_abort, ta_abort_handler, record); \ - } \ - statement; \ - if (STD_HANDLER_abortp) \ - { \ - transaction_abort (); \ - exit_interruption_extent (); \ - } \ - transaction_commit (); \ - EXIT_HANDLER (signo, name); \ - SIGNAL_HANDLER_RETURN (); \ -} - - -static void -DEFUN (ta_abort_handler, (ap), PTR ap) -{ - ABORT_HANDLER ((((struct handler_record *) ap) -> signo), - (((struct handler_record *) ap) -> handler)); -} -#ifdef UNUSED -#endif /* UNUSED */ - #define CONTROL_B_INTERRUPT_CHAR 'B' #define CONTROL_G_INTERRUPT_CHAR 'G' #define CONTROL_U_INTERRUPT_CHAR 'U' @@ -269,7 +83,6 @@ DEFUN (ta_abort_handler, (ap), PTR ap) #define TERMINATE_INTERRUPT_CHAR '@' #define NO_INTERRUPT_CHAR '0' - static void DEFUN (echo_keyboard_interrupt, (c, dc), cc_t c AND cc_t dc) { @@ -282,24 +95,9 @@ DEFUN (echo_keyboard_interrupt, (c, dc), cc_t c AND cc_t dc) outf_console ("^?"); else outf_console ("%c", c); - outf_flush_console(); + outf_flush_console (); } -DEFUN_STD_HANDLER (sighnd_control_g, - { - tty_set_next_interrupt_char (CONTROL_G_INTERRUPT_CHAR); - }) - -DEFUN_STD_HANDLER (sighnd_control_c, - { - 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) @@ -333,7 +131,7 @@ void DEFUN (OS_ctty_set_interrupt_enables, (mask), Tinterrupt_enables * mask) { /* Kludge: ctl-break always enabled. */ - keyboard_interrupt_enables = (((unsigned char) (*mask)) + keyboard_interrupt_enables = (((unsigned char) (* mask)) | TERMINATE_INTERRUPT_ENABLE); return; } @@ -341,15 +139,19 @@ DEFUN (OS_ctty_set_interrupt_enables, (mask), Tinterrupt_enables * mask) /* This is a temporary kludge. */ #define NUM_INT_CHANNELS 6 + static cc_t int_chars[NUM_INT_CHANNELS]; static cc_t int_handlers[NUM_INT_CHANNELS]; #define SCREEN_COMMAND_INTERRUPT_FIRST (SCREEN_COMMAND_CLOSE+10) -LRESULT master_tty_interrupt (HWND tty, WORD command) +int EXFUN (signal_keyboard_character_interrupt, (int)); + +LRESULT +master_tty_interrupt (HWND tty, WORD command) { - int ch = int_chars[command - SCREEN_COMMAND_INTERRUPT_FIRST]; - return (signal_keyboard_character_interrupt (ch)); + int ch = int_chars[command - SCREEN_COMMAND_INTERRUPT_FIRST]; + return (signal_keyboard_character_interrupt (ch)); } static void @@ -358,7 +160,8 @@ DEFUN_VOID (update_interrupt_characters) extern HANDLE master_tty_window; int i; - for (i = 0; i < KB_INT_TABLE_SIZE; i++) { + for (i = 0; i < KB_INT_TABLE_SIZE; i++) + { keyboard_interrupt_table[i] = NO_INTERRUPT_CHAR; SendMessage (master_tty_window, SCREEN_SETBINDING, i, 0); } @@ -398,11 +201,16 @@ DEFUN_VOID (update_interrupt_characters) break; } keyboard_interrupt_table[(int) (int_chars[i])] = handler; - SendMessage (master_tty_window, SCREEN_SETCOMMAND, - SCREEN_COMMAND_INTERRUPT_FIRST+i, + + SendMessage (master_tty_window, + SCREEN_SETCOMMAND, + (SCREEN_COMMAND_INTERRUPT_FIRST + i), (LPARAM) master_tty_interrupt); - SendMessage (master_tty_window, SCREEN_SETBINDING, - int_chars[i], SCREEN_COMMAND_INTERRUPT_FIRST+i); + + SendMessage (master_tty_window, + SCREEN_SETBINDING, + int_chars[i], + (SCREEN_COMMAND_INTERRUPT_FIRST + i)); } return; } @@ -448,31 +256,15 @@ DEFUN (OS_ctty_set_int_char_handlers, (new_int_handlers), return; } -extern long EXFUN (text_write, (int, CONST unsigned char *, size_t)); - static void DEFUN (console_write_string, (string), unsigned char * string) { outf_console ("%s", string); - outf_flush_console(); + outf_flush_console (); return; } - -static void -DEFUN (console_write_character, (c), unsigned char c) -{ - outf_console ("%c", c); - outf_flush_console(); - return; -} - -static unsigned char -DEFUN_VOID (console_read_character) -{ - return userio_read_char(); -} -void +static void DEFUN_VOID (initialize_keyboard_interrupt_table) { /* Set up default interrupt characters */ @@ -520,20 +312,11 @@ DEFUN_VOID (print_interrupt_help) "(exit) to exit Scheme\r\n" ); -/* - 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; } +extern void EXFUN (tty_set_next_interrupt_char, (cc_t)); + #define REQUEST_INTERRUPT_IF_ENABLED(mask) do \ { \ if (keyboard_interrupt_enables & (mask)) \ @@ -545,8 +328,6 @@ DEFUN_VOID (print_interrupt_help) interrupt_p = 0; \ } while (0) -int EXFUN (signal_keyboard_character_interrupt, (int)); - int DEFUN (signal_keyboard_character_interrupt, (c), int c) { @@ -572,6 +353,7 @@ DEFUN (signal_keyboard_character_interrupt, (c), int c) } return (0); } + else if ((c >= 0) && (c < KB_INT_TABLE_SIZE)) { int interrupt_p, interrupt_char; @@ -603,21 +385,8 @@ DEFUN (signal_keyboard_character_interrupt, (c), int c) break; } interactive_interrupt: - { - cc_t int_char; - - /*int_char = (DOS_interactive_interrupt_handler ());*/ - print_interrupt_help(); - int_char = 0; - - if (int_char == ((cc_t) 0)) - hard_attn_counter = 0; - else - { - tty_set_next_interrupt_char ((int) int_char); - interrupt_p = 1; - } - } + print_interrupt_help (); + interrupt_p = 0; break; default: @@ -627,85 +396,6 @@ interactive_interrupt: } return (0); } - -cc_t -DEFUN_VOID (DOS_interactive_interrupt_handler) -{ - while (1) - { - unsigned char response; - - console_write_string - ("\nKeyboard interrupt, type character (? for help): "); - - response = (console_read_character ()); - console_write_character (response); - - switch (response) - { - case 'b': - case 'B': - case CONTROL_B: - return CONTROL_B_INTERRUPT_CHAR; - - case 'g': - case 'G': - 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': - { - console_write_string ("\nTerminate scheme (y or n)? "); - response = (console_read_character ()); - console_write_character (response); - if ((response == 'y') || (response == 'Y')) - { - console_write_string ("\n"); - termination_normal (0); - } - print_interrupt_help (); - break; - } - - case 'u': - case 'U': - case CONTROL_U: - return CONTROL_U_INTERRUPT_CHAR; - - case 'x': - case 'X': - case CONTROL_X: - return CONTROL_X_INTERRUPT_CHAR; - - case '?': - print_interrupt_help (); - break; - - default: - { - unsigned char temp[128]; - - sprintf (temp, "\nIllegal interrupt character: [%c]", response); - console_write_string (temp); - print_interrupt_help (); - break; - } - } - } -} void DEFUN_VOID (OS_restartable_exit) @@ -725,11 +415,13 @@ DEFUN_VOID (OS_restartable_exit) static void * timer_state = ((void *) NULL); +static char * DEFUN_VOID (install_timer) { - switch (win32_install_async_timer (&Registers[REGBLOCK_INT_CODE], - &Registers[REGBLOCK_INT_MASK], - &Registers[REGBLOCK_MEMTOP], + switch (win32_install_async_timer (&Registers[0], + REGBLOCK_MEMTOP, + REGBLOCK_INT_CODE, + REGBLOCK_INT_MASK, (INT_Global_1 | INT_Timer), &timer_state)) { @@ -751,6 +443,9 @@ DEFUN_VOID (install_timer) case WIN32_ASYNC_TIMER_NOMEM: return ("Not enough memory to install the timer interrupt handler"); + case WIN32_ASYNC_TIMER_NOLDT: + return ("Not enough selectors to fix the timer interrupt handler"); + default: return ("Unknown asynchronous timer return code"); } @@ -771,7 +466,7 @@ void DEFUN (NT_initialize_fov, (fov), SCHEME_OBJECT fov) { int ctr, in; - SCHEME_OBJECT iv, imv, prim, mask; + SCHEME_OBJECT iv, imv, prim; extern SCHEME_OBJECT EXFUN (make_primitive, (char *)); static int interrupt_numbers[2] = { @@ -800,8 +495,10 @@ DEFUN (NT_initialize_fov, (fov), SCHEME_OBJECT fov) void DEFUN_VOID (NT_initialize_signals) { - char * timer_error = (install_timer ()); + char * timer_error; + initialize_keyboard_interrupt_table (); + timer_error = (install_timer ()); if (timer_error) { outf_fatal ("install_timer: %s", timer_error); diff --git a/v7/src/microcode/ntsys.c b/v7/src/microcode/ntsys.c index 5e8311cd7..e44527e2f 100644 --- a/v7/src/microcode/ntsys.c +++ b/v7/src/microcode/ntsys.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: ntsys.c,v 1.2 1993/06/24 02:08:47 gjr Exp $ +$Id: ntsys.c,v 1.3 1993/08/21 03:46:27 gjr Exp $ Copyright (c) 1992-1993 Massachusetts Institute of Technology @@ -32,293 +32,37 @@ Technology nor of any adaptation thereof in any advertising, promotional, or sales literature without prior written consent from MIT in each case. */ -/*#include */ #include #include "nt.h" #include "ntsys.h" -#ifdef UNUSED int -dos_keyboard_input_available_p (void) -{ - union REGS regs; - - regs.h.ah = 0x0B; - intdos (®s, ®s); - return (regs.h.al != 0); -} - -unsigned char -dos_get_keyboard_character (void) -{ - union REGS regs; - - regs.h.ah = 0x07; - intdos (®s, ®s); - return ((unsigned char) (regs.h.al)); -} -#endif /* UNUSED */ - -int -dos_poll_keyboard_character (unsigned char * result) -{ -/*SRA - union REGS regs; - - regs.h.ah = 0x06; - regs.h.dl = 0xFF; - intdos (®s, ®s); - *result = ((unsigned char) (regs.h.al)); - return ((regs.x.flags & 0x40) == 0); -*/ - char c; - read(0,&c,1); - *result = c; - return c; -} - -void -dos_console_write_character (unsigned char character) -{ - putchar(character); -} - -int -dos_console_write (void * vbuffer, size_t nsize) +nt_console_write (void * vbuffer, size_t nsize) { unsigned char * buffer = vbuffer; int i; for (i = 0; i < nsize; i++) - { - putchar(buffer[i]); - } - return (nsize); -} - -/* DOS I/O functions using handles */ + putchar (buffer[i]); -#ifdef UNUSED -handle_t -dos_open_file_with_handle (unsigned char * name, int mode) -{ - union REGS regs; - struct SREGS segregs; - - regs.e.edx = ((unsigned long) name); - segread (&segregs); - regs.h.ah = 0x3D; - regs.h.al = mode; - intdosx (®s, ®s, &segregs); - return ((regs.x.cflag) ? DOS_FAILURE : ((unsigned int) regs.x.ax)); -} - -int -dos_close_file_with_handle (handle_t handle) -{ - union REGS regs; - - regs.x.bx = handle; - regs.h.al = 0x3E; - intdos (®s, ®s); - return ((regs.x.cflag) ? DOS_FAILURE : DOS_SUCCESS); -} - -int -dos_read_file_with_handle (handle_t handle, void * buffer, size_t nbytes) -{ - union REGS regs; - struct SREGS segregs; - - regs.x.bx = handle; - regs.e.edx = ((unsigned long) buffer); - regs.e.ecx = nbytes; - segread (&segregs); - regs.h.ah = 0x3F; - intdosx (®s, ®s, &segregs); - return ((regs.x.cflag) ? DOS_FAILURE : regs.e.eax); -} - -int -dos_write_file_with_handle (handle_t handle, void * buffer, size_t nbytes) -{ - union REGS regs; - struct SREGS segregs; - - regs.x.bx = handle; - regs.e.edx = (unsigned long) buffer; - regs.e.ecx = nbytes; - segread (&segregs); - regs.h.ah = 0x40; - intdosx (®s, ®s, &segregs); - return ((regs.x.cflag) ? DOS_FAILURE : regs.e.eax); -} - -int -dos_get_device_status_with_handle (handle_t handle) -{ - union REGS regs; - - regs.x.bx = handle; - regs.x.ax = 0x4400; - intdos (®s, ®s); - return ((regs.x.cflag) ? DOS_FAILURE : ((unsigned int) regs.x.dx)); -} - -int -dos_set_device_status_with_handle (handle_t handle, int mode) -{ - int original_mode; - union REGS regs; - - original_mode = dos_get_device_status_with_handle(handle); - if (original_mode == DOS_FAILURE) - return (DOS_FAILURE); - regs.x.dx = mode; - regs.x.bx = handle; - regs.x.ax = 0x4401; - intdos (®s, ®s); - return ((regs.x.cflag) ? DOS_FAILURE : original_mode); -} -#endif /* UNUSED */ - -void dos_get_version(version_t *version_number) -{ - DWORD ver; - ver = GetVersion(); - version_number->major = HIBYTE(HIWORD(ver)); - version_number->minor = LOBYTE(HIWORD(ver)); - /* windows version major = LOBYTE(HIWORD(ver)); - windows version minor = HIBYTE(LOWORD(ver)); */ - return; + return (nsize); } - -#ifdef UNUSED void -dos_reset_drive (void) +nt_get_version (version_t * version_number) { - union REGS regs; - - regs.h.al = 0x0d; - intdos (®s, ®s); + DWORD ver; + ver = (GetVersion ()); + version_number->major = (HIBYTE (HIWORD (ver))); + version_number->minor = (LOBYTE (HIWORD (ver))); + /* windows version major = (LOBYTE (LOWORD (ver))); + windows version minor = (HIBYTE (LOWORD (ver))); + */ return; } -int -dos_set_verify_flag (int verify_p) -{ - union REGS regs; - int old_flag; - - regs.h.ah = 0x54; - intdos (®s, ®s); - old_flag = regs.h.al; - regs.h.al = ((verify_p) ? 1 : 0); - regs.h.ah = 0x2E; - intdos (®s, ®s); - return (old_flag); -} -#endif /* UNUSED */ - -int -dos_set_ctrl_c_check_flag (int check_p) -{ /*SRA*/ - (check_p); - return 0; -} - - /*SRA:dont want to do this -int -dos_rename_file (const char * old, const char * new) -{ - union REGS regs; - struct SREGS segregs; - - regs.e.edx = ((unsigned long) old); - regs.e.edi = ((unsigned long) new); - segread (&segregs); - segregs.es = segregs.ds; - regs.h.ah = 0x56; - intdosx (®s, ®s, &segregs); - if (regs.x.cflag) - return (DOS_FAILURE); - else - return (DOS_SUCCESS); -} */ - -#ifdef UNUSED -int -dos_get_machine_name (char * name) -{ - union REGS regs; - struct SREGS segregs; - - regs.e.edx = ((unsigned long) name); - segread (&segregs); - regs.x.ax = 0x5E00; - intdosx (®s, ®s, &segregs); - if ((regs.x.cflag) || (regs.h.ch == 0)) - return (DOS_FAILURE); - else - return (regs.h.cl); -} -#endif /* UNUSED */ - -/* SRA: should not need this in NT -int -dos_drive_letter_to_number (char letter) -{ - if (letter == '\0') - return 0; - else if ((letter >= 'a') && (letter <= 'z')) - return ((letter - 'a') + 1); - else if ((letter >= 'A') && (letter <= 'Z')) - return ((letter - 'A') + 1); - else - return (-1); -} */ - -#ifdef UNUSED -char -dos_drive_number_to_letter (int number) -{ - if ((number >= 1) && (number <= 26)) - return ('A' + (number - 1)); - else - return ('\0'); -} -#endif /* UNUSED */ - -/* SRA: should not need these -int -dos_set_default_drive (int drive_number) -{ - union REGS regs; - - if (drive_number > 0) - { - regs.h.dl = (drive_number - 1); - regs.h.ah = 0x0E; - intdos (®s, ®s); - } - return (DOS_SUCCESS); -} */ - -#ifdef UNUSED -int -dos_get_default_drive (int drive_number) -{ - union REGS regs; - - regs.h.ah = 0x19; - intdos (®s, ®s); - return ((regs.h.al) + 1); -} -#endif /* UNUSED */ - -dos_boolean -dos_pathname_as_filename (char * name, char * buffer) +BOOL +nt_pathname_as_filename (char * name, char * buffer) { /* Returns whether directory encountered is top level */ unsigned int end_index = ((strlen (name)) - 1); @@ -329,119 +73,17 @@ dos_pathname_as_filename (char * name, char * buffer) if ((end_index >= 0) && (buffer[end_index] == '\\')) { /* Name is indeed a directory */ if (end_index == 0) /* if only one char, name is top */ - return (dos_true); + return (TRUE); else { if (buffer[end_index-1] == ':') /* Preceded by drive letter, top */ - return (dos_true); + return (TRUE); else { buffer[end_index] = '\0'; - return (dos_false); + return (FALSE); } } } - else - return (dos_false); -} - -/* SRA should not need to do this in NT -int -dos_split_filename (char * name, char * device, char * filename) -{ - unsigned start; - int drive_number; - - if ((strlen(name) >= 2) && (name[1] == ':')) - { - device[0] = name[0], device[1] = name[1], device[2] = '\0'; - drive_number = dos_drive_letter_to_number(name[0]); - start = 2; - } - else - { - device[0] = '\0'; - drive_number = 0; - start = 0; - } - dos_pathname_as_filename (&name[start], filename); - return (drive_number); -} */ - -/* The following code should work at least under X32, Zortech's DOSX, - and Phar Lap 386/DOSX. -*/ - - /*SRA remove the following: */ -#if 0 -extern int DOS_canonicalize_filename (char *, char *); -extern unsigned long RealModeBufferParagraph; -extern char *pRealModeBuffer; - -#pragma ZTC align 1 - -struct rm_interrupt -{ - unsigned short intno; - unsigned short ds; - unsigned short es; - unsigned short fs; - unsigned short gs; - unsigned long eax; - unsigned long edx; -}; - -#pragma ZTC align - -#define RETURN_BUFFER_SIZE 128 - -int -DOS_canonicalize_filename (char * aliased, char * direct) -{ - struct rm_interrupt intrpt; - struct SREGS sregs; - union REGS regs; - - if (pRealModeBuffer == NULL) - return (-1); - strcpy ((pRealModeBuffer + RETURN_BUFFER_SIZE), aliased); - segread (&sregs); - /* Int 21h, ah = 60h: Canonicalize filename or path. */ - intrpt.intno = 0x21; - intrpt.eax = 0x6000; - intrpt.ds = (RealModeBufferParagraph + (RETURN_BUFFER_SIZE >> 4)); - intrpt.es = RealModeBufferParagraph; - regs.e.esi = 0; - regs.e.edi = 0; - regs.e.edx = ((unsigned) &intrpt); - /* Int 21h, ax = 2511h: Issue real mode interrupt. */ - regs.x.ax = 0x2511; - intdosx (®s, ®s, &sregs); - if (regs.e.cflag != 0) - return (-1); - strncpy (direct, pRealModeBuffer, RETURN_BUFFER_SIZE); - return (0); -} -#endif - -#if 0 -extern void DOS_initialize_real_mode (void); -unsigned long RealModeBufferParagraph = 0; -char *pRealModeBuffer = NULL; - -void -DOS_initialize_real_mode (void) -{ - union REGS regs; - - regs.h.ah = 0x48; - regs.x.bx = 256; - intdos (®s, ®s); - if (regs.e.cflag == 0) - { - pRealModeBuffer = ((char *) regs.e.ebx); - RealModeBufferParagraph = regs.x.ax; - } - return; + return (FALSE); } -#endif diff --git a/v7/src/microcode/ntsys.h b/v7/src/microcode/ntsys.h index ff12956d9..4f6b2b281 100644 --- a/v7/src/microcode/ntsys.h +++ b/v7/src/microcode/ntsys.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: ntsys.h,v 1.2 1993/06/24 02:09:18 gjr Exp $ +$Id: ntsys.h,v 1.3 1993/08/21 03:47:20 gjr Exp $ Copyright (c) 1992-1993 Massachusetts Institute of Technology @@ -35,144 +35,16 @@ MIT in each case. */ #ifndef SCM_NTSYS_H #define SCM_NTSYS_H -#define DOS_SUCCESS (0) -#define DOS_FAILURE (-1) -#define dos_boolean int -#define dos_true (1) -#define dos_false (0) - typedef struct version_struct { unsigned char major; unsigned char minor; } version_t; - # -/* Console Character I/O */ -#ifdef UNUSED -extern int dos_keyboard_input_available_p (void); -extern unsigned char dos_get_keyboard_character (void); -#endif /* UNUSED */ -extern int dos_poll_keyboard_character (unsigned char *result); -extern void dos_console_write_character (unsigned char character); -extern int dos_console_write (void * vbuffer, size_t nsize); - -/* Handle I/O */ -#ifdef UNUSED -typedef int handle_t; - -extern handle_t dos_open_file_with_handle (unsigned char * name, int mode); -extern int dos_close_file_with_handle (handle_t handle); -extern int dos_read_file_with_handle - (handle_t handle, void * buffer, size_t nbytes); -extern int dos_write_file_with_handle - (handle_t handle, void * buffer, size_t nbytes); -extern int dos_get_device_status_with_handle (handle_t handle); -extern int dos_set_device_status_with_handle (handle_t handle, int mode); -#endif /* UNUSED */ - /* Misc */ -extern void dos_get_version (version_t * version_number); -#ifdef UNUSED -extern void dos_reset_drive (void); -extern int dos_set_verify_flag (int verify_p); -#endif /* UNUSED */ -extern int dos_set_ctrl_c_check_flag (int check_p); -extern int dos_rename_file (const char *old, const char *new); -#ifdef UNUSED -extern int dos_get_machine_name (char *name); -#endif /* UNUSED */ -extern int dos_drive_letter_to_number (char letter); -#ifdef UNUSED -extern char dos_drive_number_to_letter (int number); -extern int dos_get_default_drive (int drive_number); -#endif /* UNUSED */ -extern int dos_set_default_drive (int drive_number); -extern int dos_pathname_as_filename (char * name, char * buffer); -extern int dos_split_filename (char * name, char * device, char * filename); - -/* Keyboard control */ - -extern dos_boolean DOS_keyboard_intercepted_p; -extern int dos_restore_kbd_hook (void); -extern int dos_install_kbd_hook (void); -extern unsigned char dos_set_kbd_modifier_mask (unsigned char); - -/* DOS Interrupt Vectors */ -#define DOS_INTVECT_DIVIDE_BY_0 (0x00) -#define DOS_INTVECT_SINGLE_STEP (0x01) -#define DOS_INTVECT_NMI (0x02) -#define DOS_INTVECT_BREAKPOINT (0x03) -#define DOS_INTVECT_OVERFLOW (0x04) -#define DOS_INTVECT_PRINT_SCREEN (0x05) -#define DOS_INTVECT_INVALID_OPCODE (0x06) -#define DOS_INTVECT_RESERVED_1 (0x07) -#define DOS_INTVECT_SYSTEM_TIMER (0x08) -#define DOS_INTVECT_KEYBOARD_EVENT (0x09) -#define DOS_INTVECT_IRQ2 (0x0A) -#define DOS_INTVECT_IRQ3 (0x0B) -#define DOS_INTVECT_IRQ4 (0x0C) -#define DOS_INTVECT_IRQ5 (0x0D) -#define DOS_INTVECT_DISKETTE_EVENT (0x0E) -#define DOS_INTVECT_IRQ7 (0x0F) -#define DOS_INTVECT_VIDEO (0x10) -#define DOS_INTVECT_EQUIPMENT (0x11) -#define DOS_INTVECT_MEMORY_SIZE (0x12) -#define DOS_INTVECT_DISK_REQUEST (0x13) -#define DOS_INTVECT_COMMUNICATIONS (0x14) -#define DOS_INTVECT_SYSTEM_SERVICES (0x15) -#define DOS_INTVECT_KEYBOARD_REQUEST (0x16) -#define DOS_INTVECT_PRINTER_REQUEST (0x17) -#define DOS_INTVECT_IBM_BASIC (0x18) -#define DOS_INTVECT_BOOTSTRAP (0x19) -#define DOS_INTVECT_SYSTEM_TIMER_2 (0x1A) -#define DOS_INTVECT_KB_CTRL_BREAK (0x1B) -#define DOS_INTVECT_USER_TIMER_TICK (0x1C) -#define DOS_INTVECT_VIDEO_PARAMETERS (0x1D) -#define DOS_INTVECT_DISKETTE_PARAMETERS (0x1E) -#define DOS_INTVECT_GRAPHICS_CHARACTERS (0x1F) -#define DOS_INTVECT_PROGRAM_TERMINATE (0x20) -#define DOS_INTVECT_DOS_REQUEST (0x21) -#define DOS_INTVECT_TERMINATE_ADDRESS (0x22) -#define DOS_INTVECT_DOS_CTRL_BREAK (0x23) -#define DOS_INTVECT_CRITICAL_ERROR (0x24) -#define DOS_INTVECT_ABS_DISK_READ (0x25) -#define DOS_INTVECT_ABS_DISK_WRITE (0x26) -#define DOS_INTVECT_TSR (0x27) -#define DOS_INTVECT_DOS_IDLE (0x28) -#define DOS_INTVECT_DOS_TTY (0x29) -#define DOS_INTVECT_MS_NET (0x2A) -#define DOS_INTVECT_DOS_INTERNAL_1 (0x2B) -#define DOS_INTVECT_DOS_INTERNAL_2 (0x2C) -#define DOS_INTVECT_DOS_INTERNAL_3 (0x2D) -#define DOS_INTVECT_BATCH_EXEC (0x2E) -#define DOS_INTVECT_MULTIPLEX (0x2F) -#define DOS_INTVECT_CPM_JUMP_1 (0x30) -#define DOS_INTVECT_CPM_JUMP_2 (0x31) -#define DOS_INTVECT_RESERVED_2 (0x32) -#define DOS_INTVECT_MS_MOUSE (0x33) -/* Non consecutive */ -#define DOS_INTVECT_DISKETTE_REQUEST (0x40) -#define DOS_INTVECT_FIXED_DISK_1_PARAM (0x41) -#define DOS_INTVECT_EGA_GRAPHICS_CHARS (0x43) -#define DOS_INTVECT_FIXED_DISK_2_PARAM (0x46) -#define DOS_INTVECT_USER_ALARM (0x4A) -#define DOS_INTVECT_PROGRAM_USE_1 (0x60) -#define DOS_INTVECT_PROGRAM_USE_2 (0x61) -#define DOS_INTVECT_PROGRAM_USE_3 (0x62) -#define DOS_INTVECT_PROGRAM_USE_4 (0x63) -#define DOS_INTVECT_PROGRAM_USE_5 (0x64) -#define DOS_INTVECT_PROGRAM_USE_6 (0x65) -#define DOS_INTVECT_PROGRAM_USE_7 (0x66) -#define DOS_INTVECT_EMS_REQUEST (0x67) -#define DOS_INTVECT_REAL_TIME_CLOCK (0x70) -#define DOS_INTVECT_IRQ2_REDIRECT (0x72) -#define DOS_INTVECT_IRQ11 (0x73) -#define DOS_INTVECT_IBM_MOUSE_EVENT (0x74) -#define DOS_INTVECT_COPROCESSOR_ERROR (0x75) -#define DOS_INTVECT_HARD_DISK_EVENT (0x76) -#define DOS_INTVECT_IRQ15 (0x77) -#define MAX_DOS_INTVECT (0xFF) +extern int nt_console_write (void * vbuffer, size_t nsize); +extern void nt_get_version (version_t * version_number); +extern BOOL nt_pathname_as_filename (char * name, char * buffer); #endif /* SCM_NTSYS_H */ diff --git a/v7/src/microcode/nttop.c b/v7/src/microcode/nttop.c index 0ec7f2d38..b149f4d5a 100644 --- a/v7/src/microcode/nttop.c +++ b/v7/src/microcode/nttop.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: nttop.c,v 1.6 1993/08/03 08:29:55 gjr Exp $ +$Id: nttop.c,v 1.7 1993/08/21 03:48:26 gjr Exp $ Copyright (c) 1993 Massachusetts Institute of Technology @@ -42,30 +42,18 @@ MIT in each case. */ #include "option.h" #include "outf.h" -extern void EXFUN (NT_initialize_channels, (void)); -extern void EXFUN (DOS_initialize_ctty, (int interactive)); -extern void EXFUN (DOS_initialize_directory_reader, (void)); -extern void EXFUN (DOS_initialize_environment, (void)); -extern void EXFUN (DOS_initialize_processes, (void)); -extern void EXFUN (DOS_initialize_terminals, (void)); -/*extern void EXFUN (DOS_initialize_trap_recovery, (void));*/ -extern void EXFUN (DOS_initialize_conio, (void)); -extern void EXFUN (DOS_initialize_tty, (void)); -extern void EXFUN (NT_initialize_userio, (void)); -extern void EXFUN (DOS_initialize_real_mode, (void)); - -extern void EXFUN (DOS_reset_channels, (void)); -extern void EXFUN (DOS_reset_processes, (void)); -extern void EXFUN (DOS_reset_terminals, (void)); extern void EXFUN (execute_reload_cleanups, (void)); -extern void EXFUN (DOS_ctty_save_external_state, (void)); -extern void EXFUN (DOS_ctty_save_internal_state, (void)); -extern void EXFUN (DOS_ctty_restore_internal_state, (void)); -extern void EXFUN (DOS_ctty_restore_external_state, (void)); - +extern void EXFUN (NT_initialize_channels, (void)); +extern void EXFUN (NT_initialize_directory_reader, (void)); extern void EXFUN (NT_initialize_signals, (void)); +extern void EXFUN (NT_initialize_traps, (void)); +extern void EXFUN (NT_initialize_tty, (void)); + +extern void EXFUN (NT_reset_channels, (void)); + extern void EXFUN (NT_restore_signals, (void)); +extern void EXFUN (NT_restore_traps, (void)); /* reset_interruptable_extent */ @@ -89,29 +77,30 @@ DEFUN_VOID (OS_initialize) NT_gui_init (); NT_initialize_channels (); - DOS_initialize_environment (); - DOS_initialize_tty (); - /*DOS_initialize_trap_recovery ();*/ + NT_initialize_tty (); NT_initialize_signals (); - DOS_initialize_directory_reader (); - DOS_initialize_conio(); - /*DOS_initialize_real_mode (); SRA*/ + NT_initialize_traps (); + NT_initialize_directory_reader (); + OS_Name = SYSTEM_NAME; OS_Variant = SYSTEM_VARIANT; - { version_t version_number; + { + version_t version_number; - dos_get_version(&version_number); + nt_get_version (&version_number); outf_console ("MIT Scheme running under %s %d.%d 386/486\r\n", - OS_Variant, - (int) version_number.major, (int) version_number.minor); + OS_Variant, + ((int) version_number.major), + ((int) version_number.minor)); /* To make our compiler vendors happy. */ - outf_console( - "Copyright (c) 1993 Massachusetts Institute of Technology\r\n"); + outf_console + ("Copyright (c) 1993 Massachusetts Institute of Technology\r\n"); } outf_console ("\r\n"); outf_flush_console (); + return; } void @@ -122,8 +111,9 @@ DEFUN_VOID (OS_reset) but the rest seem innocuous. */ - DOS_reset_channels (); + NT_reset_channels (); execute_reload_cleanups (); + return; } void @@ -131,6 +121,7 @@ DEFUN (OS_quit, (code, abnormal_p), int code AND int abnormal_p) { outf_console ("\nScheme has terminated abnormally!\n"); OS_restore_external_state (); + return; } #ifndef EAGAIN @@ -195,7 +186,7 @@ DEFUN (OS_error_code_to_message, (syserr), unsigned int syserr) } void -DEFUN (DOS_prim_check_errno, (name), enum syscall_names name) +DEFUN (NT_prim_check_errno, (name), enum syscall_names name) { if (errno != EINTR) error_system_call (errno, name); @@ -206,12 +197,13 @@ DEFUN (DOS_prim_check_errno, (name), enum syscall_names name) void OS_restore_external_state (void) { + NT_restore_traps (); NT_restore_signals (); return; } -void bcopy -(const char * s1, char * s2, int n) +void +bcopy (const char * s1, char * s2, int n) { while (n-- > 0) *s2++ = *s1++; diff --git a/v7/src/microcode/nttrap.c b/v7/src/microcode/nttrap.c index 640199286..e2b9c2a1d 100644 --- a/v7/src/microcode/nttrap.c +++ b/v7/src/microcode/nttrap.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: nttrap.c,v 1.4 1993/07/27 21:27:06 gjr Exp $ +$Id: nttrap.c,v 1.5 1993/08/21 03:48:49 gjr Exp $ Copyright (c) 1992-1993 Massachusetts Institute of Technology @@ -32,203 +32,252 @@ Technology nor of any adaptation thereof in any advertising, promotional, or sales literature without prior written consent from MIT in each case. */ +#include #include "scheme.h" #include "os.h" #include "nt.h" #include "nttrap.h" -#include "ntexcp.h" -#include "ntinsn.h" -#include "extern.h" - -extern void EXFUN (DOS_initialize_trap_recovery, (void)); -CONST char * EXFUN (find_trap_name, (int trapno)); -extern PTR initial_C_stack_pointer; +#include "gccode.h" +#include "ntscmlib.h" +#include + +#ifdef W32_TRAP_DEBUG +extern char * AskUser (char *, int); +extern int EXFUN (TellUser, (char *, ...)); +extern int EXFUN (TellUserEx, (int, char *, ...)); +#endif /* W32_TRAP_DEBUG */ + +extern void EXFUN (NT_initialize_traps, (void)); +extern void EXFUN (NT_restore_traps, (void)); + +extern unsigned short + Scheme_Code_Segment_Selector, + Scheme_Data_Segment_Selector, + Scheme_Stack_Segment_Selector, + C_Code_Segment_Selector, + C_Data_Segment_Selector, + C_Extra_Segment_Selector, + C_Stack_Segment_Selector; + +extern DWORD + C_Stack_Pointer, + C_Frame_Pointer; -static enum trap_state trap_state; -static enum trap_state user_trap_state; +#ifdef W32_TRAP_DEBUG -static enum trap_state saved_trap_state; -static int saved_trapno; -static SIGINFO_T saved_info; -static struct FULL_SIGCONTEXT * saved_scp; +static BOOL trap_verbose_p = FALSE; -static unsigned short - initial_C_ss = 0, - initial_C_ds = 0, - initial_C_cs = 0; +#define IFVERBOSE(command) do \ +{ \ + if (trap_verbose_p) \ + { \ + int result = command; \ + if (result == IDCANCEL) \ + trap_verbose_p = FALSE; \ + } \ +} while (0) -static void EXFUN (initialize_dos_trap_codes, (void)); -static void EXFUN - (continue_from_trap, - (int trapno, SIGINFO_T info, struct FULL_SIGCONTEXT * scp)); +#else /* not W32_TRAP_DEBUG */ -/*SRA -void -DEFUN_VOID (DOS_initialize_trap_recovery) -{ - extern unsigned short getSS (void); +#define IFVERBOSE(command) do { } while (0) - initial_C_ss = (getSS ()); - initial_C_ds = (getDS ()); - initial_C_cs = (getCS ()); - trap_state = trap_state_recover; - user_trap_state = trap_state_recover; - initialize_dos_trap_codes (); -} */ +#endif /* W32_TRAP_DEBUG */ -enum trap_state -DEFUN (OS_set_trap_state, (state), enum trap_state state) +static char * trap_output = ((char *) NULL); +static char * trap_output_pointer = ((char *) NULL); + +static void +DEFUN_VOID (trap_noise_start) { - enum trap_state old_trap_state = user_trap_state; - user_trap_state = state; - trap_state = state; - return (old_trap_state); + trap_output = ((char *) NULL); + trap_output_pointer = ((char *) NULL); + return; } static void -DEFUN_VOID (trap_normal_termination) +DEFUN (trap_noise, (format), char * format DOTS) { - trap_state = trap_state_exitting_soft; - termination_trap (); + va_list arg_ptr; + unsigned long size; + char * temp; + + size = (trap_output_pointer - trap_output); + temp = ((trap_output == ((char *) NULL)) + ? ((char *) (malloc (256))) + : ((char *) (realloc (trap_output, (256 + size))))); + if (temp == ((char *) NULL)) + return; + + trap_output = temp; + trap_output_pointer = (temp + size); + va_start (arg_ptr, format); + size = (wvsprintf (trap_output_pointer, format, arg_ptr)); + trap_output_pointer += size; + va_end (arg_ptr); + return; } -static void -DEFUN_VOID (trap_immediate_termination) +static int +DEFUN (trap_noise_end, (style), UINT style) { - trap_state = trap_state_exitting_hard; - OS_restore_external_state (); - exit (1); + int value; + + if (trap_output == ((char *) NULL)) + return (IDYES); + + value = (MessageBox (NULL, + trap_output, + "MIT Scheme Exception Information", + style)); + free (trap_output); + trap_output = ((char *) NULL); + trap_output_pointer = ((char *) NULL); + return (value); } -static void -DEFUN_VOID (trap_recover) +static BOOL +DEFUN (isvowel, (c), char c) { - if (WITHIN_CRITICAL_SECTION_P ()) - { - CLEAR_CRITICAL_SECTION_HOOK (); - EXIT_CRITICAL_SECTION ({}); - } - reset_interruptable_extent (); - continue_from_trap (saved_trapno, saved_info, saved_scp); + switch (c) + { + case 'a': + case 'e': + case 'i': + case 'o': + case 'u': + case 'A': + case 'E': + case 'I': + case 'O': + case 'U': + return (TRUE); + + default: + return (FALSE); + } } -void -DEFUN (trap_handler, (message, trapno, info, scp), - CONST char * message AND - int trapno AND - SIGINFO_T info AND - struct FULL_SIGCONTEXT * scp) +struct exception_name_s { - int code = ((SIGINFO_VALID_P (info)) ? (SIGINFO_CODE (info)) : 0); - Boolean constant_space_broken = (!(CONSTANT_SPACE_SEALED ())); - enum trap_state old_trap_state = trap_state; + DWORD code; + char * name; +}; - if (old_trap_state == trap_state_exitting_hard) - { - _exit (1); - } - else if (old_trap_state == trap_state_exitting_soft) - { - trap_immediate_termination (); - } - trap_state = trap_state_trapped; - if (WITHIN_CRITICAL_SECTION_P ()) - { - fprintf (stdout, - "\n>> A %s has occurred within critical section \"%s\".\n", - message, (CRITICAL_SECTION_NAME ())); - fprintf (stdout, ">> [exception %d (%s), code %d = 0x%x]\n", - trapno, (find_trap_name (trapno)), code, code); - } - else if (constant_space_broken || (old_trap_state != trap_state_recover)) - { - fprintf (stdout, "\n>> A %s (%d) has occurred.\n", message, trapno); - fprintf (stdout, ">> [exception %d (%s), code %d = 0x%x]\n", - trapno, (find_trap_name (trapno)), code, code); - } - if (constant_space_broken) - { - fputs (">> Constant space has been overwritten.\n", stdout); - fputs (">> Probably a runaway recursion has overflowed the stack.\n", - stdout); - } - fflush (stdout); +static struct exception_name_s exception_names[] = +{ + { + EXCEPTION_ACCESS_VIOLATION, + "ACCESS_VIOLATION", + }, + { + EXCEPTION_DATATYPE_MISALIGNMENT, + "DATATYPE_MISALIGNMENT", + }, + { + EXCEPTION_BREAKPOINT, + "BREAKPOINT", + }, + { + EXCEPTION_SINGLE_STEP, + "SINGLE_STEP", + }, + { + EXCEPTION_ARRAY_BOUNDS_EXCEEDED, + "ARRAY_BOUNDS_EXCEEDED", + }, + { + EXCEPTION_FLT_DENORMAL_OPERAND, + "FLT_DENORMAL_OPERAND", + }, + { + EXCEPTION_FLT_DIVIDE_BY_ZERO, + "FLT_DIVIDE_BY_ZERO", + }, + { + EXCEPTION_FLT_INEXACT_RESULT, + "FLT_INEXACT_RESULT", + }, + { + EXCEPTION_FLT_INVALID_OPERATION, + "FLT_INVALID_OPERATION", + }, + { + EXCEPTION_FLT_OVERFLOW, + "FLT_OVERFLOW", + }, + { + EXCEPTION_FLT_STACK_CHECK, + "FLT_STACK_CHECK", + }, + { + EXCEPTION_FLT_UNDERFLOW, + "FLT_UNDERFLOW", + }, + { + EXCEPTION_INT_DIVIDE_BY_ZERO, + "INT_DIVIDE_BY_ZERO", + }, + { + EXCEPTION_INT_OVERFLOW, + "INT_OVERFLOW", + }, + + { + EXCEPTION_PRIV_INSTRUCTION, + "PRIV_INSTRUCTION", + }, + { + EXCEPTION_IN_PAGE_ERROR, + "IN_PAGE_ERROR", + }, + { + EXCEPTION_ILLEGAL_INSTRUCTION, + "ILLEGAL_INSTRUCTION", + }, + { + EXCEPTION_NONCONTINUABLE_EXCEPTION, + "NONCONTINUABLE_EXCEPTION", + }, + { + EXCEPTION_STACK_OVERFLOW, + "STACK_OVERFLOW", + }, + { + EXCEPTION_INVALID_DISPOSITION, + "INVALID_DISPOSITION", + }, +}; - switch (old_trap_state) - { - case trap_state_trapped: - if ((saved_trap_state == trap_state_recover) || - (saved_trap_state == trap_state_query)) - { - fputs (">> The trap occurred while processing an earlier trap.\n", - stdout); - fprintf (stdout, - ">> [The earlier trap raised exception %d (%s), code %d.]\n", - saved_trapno, - (find_trap_name (saved_trapno)), - ((SIGINFO_VALID_P (saved_info)) - ? (SIGINFO_CODE (saved_info)) - : 0)); - fputs (((WITHIN_CRITICAL_SECTION_P ()) - ? ">> Successful recovery is extremely unlikely.\n" - : ">> Successful recovery is unlikely.\n"), - stdout); - break; - } - else - trap_immediate_termination (); - case trap_state_recover: - if ((WITHIN_CRITICAL_SECTION_P ()) || constant_space_broken) - { - fputs (">> Successful recovery is unlikely.\n", stdout); - break; - } - else - { - saved_trap_state = old_trap_state; - saved_trapno = trapno; - saved_info = info; - saved_scp = scp; - trap_recover (); - } - case trap_state_exit: - termination_trap (); - } +const int excp_name_limit = ((sizeof (exception_names)) + / (sizeof (struct exception_name_s))); - fflush (stdout); - saved_trap_state = old_trap_state; - saved_trapno = trapno; - saved_info = info; - saved_scp = scp; +static char * +find_exception_name (DWORD code) +{ + int i; - while (1) - { - char option; - static CONST char * trap_query_choices[] = - { - "I = terminate immediately", - "N = terminate normally", - "R = attempt recovery", - "Q = terminate normally", - 0 - }; - option = (userio_choose_option - ("Choose one of the following actions:", - "Action -> ", - trap_query_choices)); - switch (option) - { - case 'I': - trap_immediate_termination (); - case '\0': - /* Error in IO. Assume everything scrod. */ - case 'N': - case 'Q': - trap_normal_termination (); - case 'R': - trap_recover (); - } - } + for (i = 0; i < excp_name_limit; i++) + if (exception_names[i].code == code) + return (exception_names[i].name); + return ((char *) NULL); +} + +static void +DEFUN (describe_trap, (noise, code), + char * noise AND DWORD code) +{ + char * name; + + name = (find_exception_name (code)); + if (name == ((char *) NULL)) + trap_noise (">> The %s an unknown trap [code = %d].\n", + noise, code); + else + trap_noise (">> The %s a%s %s trap.\n", + noise, + ((isvowel (name[0])) ? "n" : ""), + name); + return; } #define STATE_UNKNOWN (LONG_TO_UNSIGNED_FIXNUM (0)) @@ -252,195 +301,258 @@ static struct trap_recovery_info dummy_recovery_info = SHARP_F }; -struct dos_trap_code_desc +struct nt_trap_code_desc { int trapno; unsigned long code_mask; unsigned long code_value; char *name; }; + +static enum trap_state trap_state; +static enum trap_state user_trap_state; -static struct dos_trap_code_desc dos_trap_codes [64]; +static enum trap_state saved_trap_state; +static DWORD saved_trap_code; -#define DECLARE_DOS_TRAP_CODE(s, m, v, n) \ -{ \ - ((dos_trap_codes [i]) . trapno) = (s); \ - ((dos_trap_codes [i]) . code_mask) = (m); \ - ((dos_trap_codes [i]) . code_value) = (v); \ - ((dos_trap_codes [i]) . name) = (n); \ - i += 1; \ +enum trap_state +DEFUN (OS_set_trap_state, (state), enum trap_state state) +{ + enum trap_state old_trap_state = user_trap_state; + + user_trap_state = state; + trap_state = state; + return (old_trap_state); } -static SCHEME_OBJECT -DEFUN (find_trap_code_name, (trapno, info, scp), - int trapno AND - SIGINFO_T info AND - struct FULL_SIGCONTEXT * scp) +static void +DEFUN_VOID (trap_normal_termination) { - unsigned long code = 0; - char * name = 0; - if (SIGINFO_VALID_P (info)) - { - code = (SIGINFO_CODE (info)); - { - struct dos_trap_code_desc * entry = (& (dos_trap_codes [0])); - while ((entry -> trapno) != DOS_INVALID_TRAP) - if (((entry -> trapno) == trapno) - && (((entry -> code_mask) & code) == (entry -> code_value))) - { - name = (entry -> name); - break; - } - else - entry += 1; - } - } - return (cons ((long_to_integer ((long) code)), - ((name == 0) ? SHARP_F - : (char_pointer_to_string ((unsigned char *) name))))); + trap_state = trap_state_exitting_soft; + termination_trap (); } - + static void -DEFUN_VOID (initialize_dos_trap_codes) +DEFUN_VOID (trap_immediate_termination) { - unsigned int i = 0; - - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Integer_divide_by_zero, - 0, 0, - "Integer divide by zero"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Debug_exception, - 0, 0, - "Debug exception"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Non_maskable_interrupt, - 0, 0, - "Non-maskable interrupt"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Breakpoint, - 0, 0, - "Breakpoint"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Integer_overflow, - 0, 0, - "Integer overflow"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Bounds_check, - 0, 0, - "Bounds check"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Invalid_opcode, - 0, 0, - "Invalid opcode"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Numeric_co_processor_not_available, - 0, 0, - "Numeric co-processor not available"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Double_fault, - 0, 0, - "Double fault"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Numeric_co_processor_segment_overrun, - 0, 0, - "Numeric co-processor segment overrun"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Invalid_TSS, - 0, 0, - "Invalid TSS"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Segment_not_present, - 0, 0, - "Segment not present"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Stack_exception, - 0, 0, - "Stack exception"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_General_protection, - 0, 0, - "General protection"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Page_Fault, - 0, 0, - "Page Fault"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Floating_point_exception, - 0, 0, - "Floating-point exception"); - DECLARE_DOS_TRAP_CODE (DOS_EXCP_Alignment_check, - 0, 0, - "Alignment check"); - DECLARE_DOS_TRAP_CODE (DOS_INVALID_TRAP, 0, 0, ((char *) 0)); + extern void EXFUN (OS_restore_external_state, (void)); + + trap_state = trap_state_exitting_hard; + OS_restore_external_state (); + exit (1); +} + +void +DEFUN_VOID (NT_initialize_traps) +{ + trap_state = trap_state_recover; + user_trap_state = trap_state_recover; return; } -static CONST char * -trap_names[NUM_DOS_EXCP] = +void +DEFUN_VOID (NT_restore_traps) { - "Integer divide by zero", - "Debugging trap", - "NMI interrupt", - "Breakpoint exception", - "INTO -- integer overflow", - "BOUND -- range exceeded", - "UD -- invalid opcode", - "NM -- 387 not available", - "DF -- double fault", - "387 segment overrun", - "TS -- invalid TSS", - "NP -- segment not present", - "SS -- stack fault", - "GP -- general protection", - "PF -- page fault", - ((CONST char *) NULL), - "MF -- floating-point error", - "AC -- alignment check" -}; + return; +} + +static int +DEFUN (display_exception_information, (info, context, flags), + PEXCEPTION_RECORD info AND PCONTEXT context AND int flags) +{ + int value; + char msgbuf[4096]; + char * flag, * name, * bufptr; + + bufptr = &msgbuf[0]; + name = (find_exception_name (info->ExceptionCode)); + flag = ((info->ExceptionFlags == 0) ? "Continuable" : "Non-continuable"); + if (name == ((char *) NULL)) + bufptr += (sprintf (bufptr, "%s Unknown Exception %d Raised at address 0x%lx", + flag, info->ExceptionCode, info->ExceptionAddress)); + else + bufptr += (sprintf (bufptr, "%s %s Exception Raised at address 0x%lx", + flag, name, info->ExceptionAddress)); + +#ifdef W32_TRAP_DEBUG + if (context == ((PCONTEXT) NULL)) + bufptr += (sprintf (bufptr, "\nContext is NULL.")); + else + { + if ((context->ContextFlags & CONTEXT_CONTROL) != 0) + bufptr += (sprintf (bufptr, + "\nContext contains CONTROL information.")); + if ((context->ContextFlags & CONTEXT_INTEGER) != 0) + bufptr += (sprintf (bufptr, + "\nContext contains INTEGER registers.")); + if ((context->ContextFlags & CONTEXT_SEGMENTS) != 0) + bufptr += (sprintf (bufptr, + "\nContext contains SEGMENT registers.")); + if ((context->ContextFlags & CONTEXT_FLOATING_POINT) != 0) + bufptr += (sprintf (bufptr, + "\nContext contains floating-point registers.")); + bufptr += (sprintf (bufptr, "\ncontext->Eip = 0x%lx.", context->Eip)); + bufptr += (sprintf (bufptr, "\ncontext->Esp = 0x%lx.", context->Esp)); + bufptr += (sprintf (bufptr, "\nStack_Pointer = 0x%lx.", Stack_Pointer)); + bufptr += (sprintf (bufptr, "\nwinnt_address_delta = 0x%lx.", winnt_address_delta)); + bufptr += (sprintf (bufptr, "\nadj (Stack_Pointer) = 0x%lx.", + (ADDR_TO_SCHEME_ADDR (Stack_Pointer)))); + bufptr += (sprintf (bufptr, "\nCS = 0x%04x;\tC CS = 0x%04x;\tS CS = 0x%04x.", + context->SegCs, + C_Code_Segment_Selector, + Scheme_Code_Segment_Selector)); + + bufptr += (sprintf (bufptr, "\nDS = 0x%04x;\tC DS = 0x%04x;\tS DS = 0x%04x.", + context->SegDs, + C_Data_Segment_Selector, + Scheme_Data_Segment_Selector)); + + bufptr += (sprintf (bufptr, "\nES = 0x%04x;\tC ES = 0x%04x;\tS ES = 0x%04x.", + context->SegEs, + C_Extra_Segment_Selector, + C_Data_Segment_Selector)); + + bufptr += (sprintf (bufptr, "\nSS = 0x%04x;\tC SS = 0x%04x;\tS SS = 0x%04x.", + context->SegSs, + C_Stack_Segment_Selector, + Scheme_Stack_Segment_Selector)); + } +#endif /* W32_TRAP_DEBUG */ + + info = info->ExceptionRecord; + if (info != ((PEXCEPTION_RECORD) NULL)) + bufptr += (sprintf (bufptr, + "\nTrap occurred within an earlier trap.")); + +#ifdef W32_TRAP_DEBUG + if (flags == MB_YESNO) + bufptr += (sprintf (bufptr, "\n\nDisplay More Information?")); +#else /* not W32_TRAP_DEBUG */ + flags = MB_OK; + bufptr += + (sprintf (bufptr, + "\n\nScheme cannot find the state necessary to continue.")); +#endif /* W32_TRAP_DEBUG */ + + value = (MessageBox (NULL, &msgbuf[0], + "MIT Scheme Exception Info", + (flags | MB_ICONSTOP))); + return (value); +} + +#define TEMP_STACK_LEN 2048 /* objects */ + +static BOOL + return_by_aborting, + clear_real_stack; -CONST char * -DEFUN (find_trap_name, (trapno), int trapno) +static SCHEME_OBJECT + temp_stack_buffer[TEMP_STACK_LEN], + * temp_stack = &temp_stack_buffer[0], + * temp_stack_end = &temp_stack_buffer[TEMP_STACK_LEN], + * temp_stack_limit, + * real_stack_guard, + * real_stack_pointer; + +extern int EXFUN (WinntExceptionTransferHook, (void)); +extern void EXFUN (callWinntExceptionTransferHook, (void)); + +int +DEFUN_VOID (WinntExceptionTransferHook) { - static char buffer [64], * name; - if ((trapno >= 0) && - (trapno < ((sizeof (trap_names)) / (sizeof (char *))))) + /* These must be static because the memcpy below may + be overwriting this procedure's locals! + */ + + static int size; + static SCHEME_OBJECT * temp_stack_ptr, * new_sp; + + temp_stack_ptr = Stack_Pointer; + size = (temp_stack_limit - temp_stack_ptr); + IFVERBOSE (TellUserEx (MB_OKCANCEL, "WinntExceptionTransferHook.")); + + if (clear_real_stack) + Initialize_Stack (); + else { - name = trap_names[trapno]; - if ((name != ((char *) NULL)) - && (name[0] != '\0')) - return ((CONST char *) name); + Stack_Pointer = real_stack_pointer; + Stack_Guard = real_stack_guard; } - sprintf (buffer, "unknown exception %d", trapno); - return ((CONST char *) buffer); + + new_sp = (real_stack_pointer - size); + if (new_sp != temp_stack_ptr) + memcpy (new_sp, temp_stack_ptr, (size * (sizeof (SCHEME_OBJECT)))); + Stack_Pointer = new_sp; + SET_INTERRUPT_MASK ((FETCH_INTERRUPT_MASK ())); + if (return_by_aborting) + abort_to_interpreter (PRIM_APPLY); + return (PRIM_APPLY); } + +extern unsigned short EXFUN (getCS, (void)); +extern unsigned short EXFUN (getDS, (void)); +extern unsigned short EXFUN (getSS, (void)); +/* Needed because Stack_Check checks for <= instead of < when pushing */ + +#define MAGIC_BUFFER_SIZE 1 + static void -DEFUN (setup_trap_frame, (trapno, info, scp, trinfo, new_stack_pointer), - int trapno AND - SIGINFO_T info AND - struct FULL_SIGCONTEXT * scp AND - struct trap_recovery_info * trinfo AND - SCHEME_OBJECT * new_stack_pointer) +DEFUN (setup_trap_frame, (code, context, trinfo, new_stack_pointer), + DWORD code + AND PCONTEXT context + AND struct trap_recovery_info * trinfo + AND SCHEME_OBJECT * new_stack_pointer) { - SCHEME_OBJECT handler; SCHEME_OBJECT trap_name, trap_code; + SCHEME_OBJECT handler; int stack_recovered_p = (new_stack_pointer != 0); long saved_mask = (FETCH_INTERRUPT_MASK ()); SET_INTERRUPT_MASK (0); /* To prevent GC for now. */ - if ((! (Valid_Fixed_Obj_Vector ())) || - ((handler = (Get_Fixed_Obj_Slot (Trap_Handler))) == SHARP_F)) + + IFVERBOSE (TellUserEx (MB_OKCANCEL, + "setup_trap_frame (%s, 0x%lx, %s, 0x%lx, 0x%lx).", + (find_exception_name (code)), + context, + trinfo, + new_stack_pointer)); + + if ((! (Valid_Fixed_Obj_Vector ())) + || ((handler = (Get_Fixed_Obj_Slot (Trap_Handler))) == SHARP_F)) { - outf_fatal ("There is no trap handler for recovery!\n"); - outf_fatal ("Trap = %s.\n", (find_trap_name (trapno))); - outf_fatal ("pc = %04x:%08lx; sp = %04x:%08lx.\n", - scp->sc_cs, scp->sc_eip, scp->sc_ss, scp->sc_esp); + trap_noise_start (); + trap_noise ("There is no trap handler for recovery!\n"); + describe_trap ("trap is", code); + (void) trap_noise_end (MB_OK | MB_ICONSTOP); termination_trap (); } if (Free > MemTop) Request_GC (0); - trap_name = - ((trapno <= 0) - ? SHARP_F - : (char_pointer_to_string - ((unsigned char *) (find_trap_name (trapno))))); - trap_code = (find_trap_code_name (trapno, info, scp)); - if (!stack_recovered_p) - { + trap_name = ((context == ((PCONTEXT) NULL)) + ? SHARP_F + : (char_pointer_to_string (find_exception_name (code)))); + trap_code = (long_to_integer (0)); + + if (win32_under_win32s_p ()) + { + if (! stack_recovered_p) Initialize_Stack (); - Will_Push (CONTINUATION_SIZE); - Store_Return (RC_END_OF_COMPUTATION); - Store_Expression (SHARP_F); - Save_Cont (); - Pushed (); - } + clear_real_stack = FALSE; + real_stack_pointer = Stack_Pointer; + real_stack_guard = Stack_Guard; + temp_stack_limit = Stack_Pointer; + } else - Stack_Pointer = new_stack_pointer; + { + clear_real_stack = (!stack_recovered_p); + real_stack_pointer = new_stack_pointer; + real_stack_guard = Stack_Guard; + temp_stack_limit = temp_stack_end; + Stack_Pointer = temp_stack_end; + Stack_Guard = temp_stack; + } + Will_Push (7 + CONTINUATION_SIZE); STACK_PUSH (trinfo -> extra_trap_info); STACK_PUSH (trinfo -> pc_info_2); @@ -450,11 +562,11 @@ DEFUN (setup_trap_frame, (trapno, info, scp, trinfo, new_stack_pointer), STACK_PUSH (trap_code); STACK_PUSH (trap_name); Store_Return (RC_HARDWARE_TRAP); - Store_Expression (long_to_integer (trapno)); + Store_Expression (long_to_integer (code)); Save_Cont (); Pushed (); if (stack_recovered_p - /* This may want to do it in other cases, but this may be enough. */ + /* This may want to be done in other cases, but this may be enough. */ && (trinfo->state == STATE_COMPILED_CODE)) Stop_History (); @@ -465,75 +577,23 @@ DEFUN (setup_trap_frame, (trapno, info, scp, trinfo, new_stack_pointer), STACK_PUSH (STACK_FRAME_HEADER + 1); Pushed (); SET_INTERRUPT_MASK (saved_mask); - abort_to_interpreter (PRIM_APPLY); -} - -/* DOS_INVALID_TRAP is an invalid trap, it means a user requested reset. */ - -void -DEFUN (hard_reset, (scp), struct FULL_SIGCONTEXT * scp) -{ - continue_from_trap (DOS_INVALID_TRAP, 0, scp); -} -/* Called synchronously. */ - -void -DEFUN_VOID (soft_reset) -{ - struct trap_recovery_info trinfo; - SCHEME_OBJECT * new_stack_pointer = - (((Stack_Pointer <= Stack_Top) && (Stack_Pointer > Stack_Guard)) - ? Stack_Pointer - : 0); - if ((Regs[REGBLOCK_PRIMITIVE]) != SHARP_F) - { - (trinfo . state) = STATE_PRIMITIVE; - (trinfo . pc_info_1) = (Regs[REGBLOCK_PRIMITIVE]); - (trinfo . pc_info_2) = - (LONG_TO_UNSIGNED_FIXNUM (Regs[REGBLOCK_LEXPR_ACTUALS])); - (trinfo . extra_trap_info) = SHARP_F; - } - else - { - (trinfo . state) = STATE_UNKNOWN; - (trinfo . pc_info_1) = SHARP_F; - (trinfo . pc_info_2) = SHARP_F; - (trinfo . extra_trap_info) = SHARP_F; - } - if ((Free >= Heap_Top) || (Free < Heap_Bottom)) - /* Let's hope this works. */ - Free = MemTop; - setup_trap_frame (DOS_INVALID_TRAP, 0, 0, (&trinfo), new_stack_pointer); -} - -#if !defined(HAVE_SIGCONTEXT) || !defined(HAS_COMPILER_SUPPORT) || defined(USE_STACKLETS) - -static void -DEFUN (continue_from_trap, (trapno, info, scp), - int trapno AND - SIGINFO_T info AND - struct FULL_SIGCONTEXT * scp) -{ - if (Free < MemTop) - Free = MemTop; - setup_trap_frame (trapno, info, scp, (&dummy_recovery_info), 0); + IFVERBOSE (TellUserEx (MB_OKCANCEL, "setup_trap_frame done.")); + return; } - -#else /* HAVE_SIGCONTEXT and HAS_COMPILER_SUPPORT and not USE_STACKLETS */ /* Heuristic recovery from processor traps/exceptions. continue_from_trap attempts to: 1) validate the trap information (pc and sp); - 2) determine whether compiled code was executing, a primitive was - executing, or execution was in the interpreter; + 2) determine whether compiled code was executing, + a primitive was executing, + or execution was in the interpreter; 3) guess what C global state is still valid; and 4) set up a recovery frame for the interpreter so that debuggers can - display more information. */ - -#include "gccode.h" + display more information. +*/ #define SCHEME_ALIGNMENT_MASK ((sizeof (long)) - 1) #define STACK_ALIGNMENT_MASK SCHEME_ALIGNMENT_MASK @@ -546,70 +606,103 @@ DEFUN (continue_from_trap, (trapno, info, scp), /* But they may have bits that can be masked by this. */ #ifndef PC_VALUE_MASK -#define PC_VALUE_MASK (~0) +# define PC_VALUE_MASK (~0) #endif #define C_STACK_SIZE 0x01000000 #ifdef HAS_COMPILER_SUPPORT -#define ALLOW_ONLY_C 0 +# define ALLOW_ONLY_C 0 #else -#define ALLOW_ONLY_C 1 -#define PLAUSIBLE_CC_BLOCK_P(block) 0 +# define ALLOW_ONLY_C 1 +# define PLAUSIBLE_CC_BLOCK_P(block) 0 #endif static SCHEME_OBJECT * EXFUN (find_block_address, (char * pc_value, SCHEME_OBJECT * area_start)); -#if 0 -#define get_etext() (&etext) -#else +#define I386_NREGS 12 + /* For now */ -#define get_etext() (Heap_Bottom) -#endif +#define GET_ETEXT() (Heap_Bottom) static void -DEFUN (continue_from_trap, (trapno, info, scp), - int trapno AND - SIGINFO_T info AND - struct FULL_SIGCONTEXT * scp) +DEFUN (continue_from_trap, (code, context), + DWORD code AND PCONTEXT context) { + int pc_in_builtin; + int builtin_index; int pc_in_C; int pc_in_heap; int pc_in_constant_space; int pc_in_scheme; int pc_in_hyper_space; + int pc_in_utility; + int utility_index; int scheme_sp_valid; - long C_sp; long scheme_sp; long the_pc; SCHEME_OBJECT * new_stack_pointer; SCHEME_OBJECT * xtra_info; struct trap_recovery_info trinfo; + extern int EXFUN (pc_to_utility_index, (unsigned long)); + extern int EXFUN (pc_to_builtin_index, (unsigned long)); - if (scp == ((struct FULL_SIGCONTEXT *) NULL)) + IFVERBOSE (TellUserEx (MB_OKCANCEL, + "continue_from_trap (%s, 0x%lx).", + (find_exception_name (code)), context)); + + if (context == ((PCONTEXT) NULL)) { if (Free < MemTop) Free = MemTop; - setup_trap_frame (trapno, info, scp, (&dummy_recovery_info), 0); + setup_trap_frame (code, context, (&dummy_recovery_info), 0); /*NOTREACHED*/ } - C_sp = (FULL_SIGCONTEXT_SP (scp)); - scheme_sp = (FULL_SIGCONTEXT_SCHSP (scp)); - the_pc = ((FULL_SIGCONTEXT_PC (scp)) & PC_VALUE_MASK); + if (context->SegSs == (getDS ())) + { + IFVERBOSE + (TellUserEx + (MB_OKCANCEL, + "continue_from_trap: SS = C DS; Stack_Pointer = 0x%lx; Esp = 0x%lx.", + Stack_Pointer, context->Esp)); + scheme_sp = (context->Esp); + } + else if (context->SegSs == Scheme_Stack_Segment_Selector) + { + IFVERBOSE (TellUserEx (MB_OKCANCEL, + "continue_from_trap: SS = Scheme SS.")); + scheme_sp = ((long) (SCHEME_ADDR_TO_ADDR (context->Esp))); + } + else + { + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap: SS unknown!")); + scheme_sp = 0; + } -#if FALSE - outf_error ("\ncontinue_from_trap:"); - outf_error ("\tpc = 0x%08lx\n", the_pc); - outf_error ("\tCsp = 0x%08lx\n", C_sp); - outf_error ("\tssp = 0x%08lx\n", scheme_sp); - outf_error ("\tesp = 0x%08lx\n", Ext_Stack_Pointer); -#endif + if (context->SegCs == (getCS ())) + { + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap: CS = C CS.")); + the_pc = (context->Eip & PC_VALUE_MASK); + } + else if (context->SegCs == Scheme_Code_Segment_Selector) + { + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap: CS = Scheme CS")); + /* Assume in Scheme. Of course, it could be in a builtin. */ + the_pc = ((long) (SCHEME_ADDR_TO_ADDR (context->Eip & PC_VALUE_MASK))); + } + else + { + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap: CS unknown")); + goto pc_in_hyperspace; + } - if (((the_pc & PC_ALIGNMENT_MASK) != 0) - || (scp->sc_cs != initial_C_cs)) + if ((the_pc & PC_ALIGNMENT_MASK) != 0) { +pc_in_hyperspace: + pc_in_builtin = 0; + pc_in_utility = 0; pc_in_C = 0; pc_in_heap = 0; pc_in_constant_space = 0; @@ -618,33 +711,40 @@ DEFUN (continue_from_trap, (trapno, info, scp), } else { - pc_in_C = (the_pc <= ((long) (get_etext ()))); + builtin_index = (pc_to_builtin_index (the_pc)); + pc_in_builtin = (builtin_index != -1); + utility_index = (pc_to_utility_index (the_pc)); + pc_in_utility = (utility_index != -1); + pc_in_C = ((the_pc <= ((long) (GET_ETEXT ()))) && (! pc_in_builtin)); pc_in_heap = ((the_pc < ((long) Heap_Top)) && (the_pc >= ((long) Heap_Bottom))); pc_in_constant_space = ((the_pc < ((long) Constant_Top)) && (the_pc >= ((long) Constant_Space))); - pc_in_scheme = (pc_in_heap || pc_in_constant_space); + pc_in_scheme = (pc_in_heap || pc_in_constant_space || pc_in_builtin); pc_in_hyper_space = ((!pc_in_C) && (!pc_in_scheme)); } + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 1")); + scheme_sp_valid = (pc_in_scheme - && ((scp->sc_ss & 0xffff) == (scp->sc_ds & 0xffff)) - && ((scp->sc_ds & 0xffff) == (initial_C_ds & 0xffff)) && ((scheme_sp < ((long) Stack_Top)) && (scheme_sp >= ((long) Absolute_Stack_Base)) && ((scheme_sp & STACK_ALIGNMENT_MASK) == 0))); + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 2")); + new_stack_pointer = (scheme_sp_valid ? ((SCHEME_OBJECT *) scheme_sp) : ((pc_in_C - && ((scp->sc_ss & 0xffff) == (initial_C_ss & 0xffff)) && (Stack_Pointer < Stack_Top) && (Stack_Pointer > Absolute_Stack_Base)) ? Stack_Pointer : ((SCHEME_OBJECT *) 0))); + + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 3")); if (pc_in_hyper_space || (pc_in_scheme && ALLOW_ONLY_C)) { @@ -664,13 +764,34 @@ DEFUN (continue_from_trap, (trapno, info, scp), SCHEME_OBJECT * block_addr; SCHEME_OBJECT * maybe_free; block_addr = - (find_block_address (((PTR) the_pc), - (pc_in_heap ? Heap_Bottom : Constant_Space))); - if (block_addr == 0) + (pc_in_builtin + ? ((SCHEME_OBJECT *) NULL) + : (find_block_address (((PTR) the_pc), + (pc_in_heap ? Heap_Bottom : Constant_Space)))); + + if (block_addr != ((SCHEME_OBJECT *) NULL)) + { + (trinfo . state) = STATE_COMPILED_CODE; + (trinfo . pc_info_1) = + (MAKE_POINTER_OBJECT (TC_COMPILED_CODE_BLOCK, block_addr)); + (trinfo . pc_info_2) = + (LONG_TO_UNSIGNED_FIXNUM (the_pc - ((long) block_addr))); + } + else if (pc_in_builtin) + { + (trinfo . state) = STATE_PROBABLY_COMPILED; + (trinfo . pc_info_1) = (LONG_TO_UNSIGNED_FIXNUM (builtin_index)); + (trinfo . pc_info_2) = SHARP_T; + } + else { (trinfo . state) = STATE_PROBABLY_COMPILED; (trinfo . pc_info_1) = (LONG_TO_UNSIGNED_FIXNUM (the_pc)); (trinfo . pc_info_2) = SHARP_F; + } + + if ((block_addr == ((SCHEME_OBJECT *) NULL)) && (! pc_in_builtin)) + { if ((Free < MemTop) || (Free >= Heap_Top) || ((((unsigned long) Free) & SCHEME_ALIGNMENT_MASK) != 0)) @@ -678,32 +799,30 @@ DEFUN (continue_from_trap, (trapno, info, scp), } else { - (trinfo . state) = STATE_COMPILED_CODE; - (trinfo . pc_info_1) = - (MAKE_POINTER_OBJECT (TC_COMPILED_CODE_BLOCK, block_addr)); - (trinfo . pc_info_2) = - (LONG_TO_UNSIGNED_FIXNUM (the_pc - ((long) block_addr))); -#ifdef HAVE_FULL_SIGCONTEXT - maybe_free = ((SCHEME_OBJECT *) (FULL_SIGCONTEXT_RFREE (scp))); + maybe_free = ((SCHEME_OBJECT *) context->Edi); if (((((unsigned long) maybe_free) & SCHEME_ALIGNMENT_MASK) == 0) && (maybe_free >= Heap_Bottom) && (maybe_free < Heap_Top)) Free = (maybe_free + FREE_PARANOIA_MARGIN); else -#endif - { if ((Free < MemTop) || (Free >= Heap_Top) || ((((unsigned long) Free) & SCHEME_ALIGNMENT_MASK) != 0)) Free = MemTop; - } } } - else + + else /* pc_in_C */ { /* In the interpreter, a primitive, or a compiled code utility. */ SCHEME_OBJECT primitive = (Regs[REGBLOCK_PRIMITIVE]); - if ((OBJECT_TYPE (primitive)) != TC_PRIMITIVE) + if (pc_in_utility) + { + (trinfo . state) = STATE_PROBABLY_COMPILED; + (trinfo . pc_info_1) = (LONG_TO_UNSIGNED_FIXNUM (utility_index)); + (trinfo . pc_info_2) = UNSPECIFIC; + } + else if ((OBJECT_TYPE (primitive)) != TC_PRIMITIVE) { (trinfo . state) = STATE_UNKNOWN; (trinfo . pc_info_1) = SHARP_F; @@ -727,27 +846,55 @@ DEFUN (continue_from_trap, (trapno, info, scp), else if ((Free + FREE_PARANOIA_MARGIN) < MemTop) Free += FREE_PARANOIA_MARGIN; } - xtra_info = Free; - Free += (1 + 2 + PROCESSOR_NREGS); - (trinfo . extra_trap_info) = - (MAKE_POINTER_OBJECT (TC_NON_MARKED_VECTOR, xtra_info)); - (*xtra_info++) = - (MAKE_OBJECT (TC_MANIFEST_NM_VECTOR, (2 + PROCESSOR_NREGS))); - (*xtra_info++) = ((SCHEME_OBJECT) the_pc); - (*xtra_info++) = ((SCHEME_OBJECT) C_sp); + + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 4")); + + if (win32_under_win32s_p ()) + (trinfo . extra_trap_info) = SHARP_F; + else { - int counter = FULL_SIGCONTEXT_NREGS; - int * regs = (FULL_SIGCONTEXT_FIRST_REG (scp)); - while ((counter--) > 0) - (*xtra_info++) = ((SCHEME_OBJECT) (*regs++)); - } - /* We assume that regs,sp,pc is the order in the processor. - Scheme can always fix this. */ - if ((PROCESSOR_NREGS - FULL_SIGCONTEXT_NREGS) > 0) - (*xtra_info++) = ((SCHEME_OBJECT) C_sp); - if ((PROCESSOR_NREGS - FULL_SIGCONTEXT_NREGS) > 1) + xtra_info = Free; + Free += (1 + (I386_NREGS + 2)); + (trinfo . extra_trap_info) = + (MAKE_POINTER_OBJECT (TC_NON_MARKED_VECTOR, xtra_info)); + (*xtra_info++) = (MAKE_OBJECT (TC_MANIFEST_NM_VECTOR, (I386_NREGS + 2))); (*xtra_info++) = ((SCHEME_OBJECT) the_pc); - setup_trap_frame (trapno, info, scp, (&trinfo), new_stack_pointer); + (*xtra_info++) = ((SCHEME_OBJECT) scheme_sp); + { + int counter = I386_NREGS; + int * regs = ((int *) context->Edi); + while ((counter--) > 0) + (*xtra_info++) = ((SCHEME_OBJECT) (*regs++)); + } + } + + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 5")); + + /* Handshake with try+except. */ + + context->Eip = ((DWORD) callWinntExceptionTransferHook); + context->SegCs = (getCS ()); + return_by_aborting = TRUE; + + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 6")); + + if (pc_in_scheme && (! (win32_under_win32s_p ()))) + { + context->SegCs = C_Code_Segment_Selector; + context->SegDs = C_Data_Segment_Selector; + context->SegEs = C_Extra_Segment_Selector; + context->SegSs = C_Stack_Segment_Selector; + context->Esp = C_Stack_Pointer; + context->Ebp = C_Frame_Pointer; + if (pc_in_scheme) + return_by_aborting = FALSE; + } + + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 7")); + + setup_trap_frame (code, context, (&trinfo), new_stack_pointer); + + IFVERBOSE (TellUserEx (MB_OKCANCEL, "continue_from_trap 8")); } /* Find the compiled code block in area which contains `pc_value'. @@ -867,10 +1014,10 @@ DEFUN (find_block_address_in_area, (pc_value, area_start), { SCHEME_OBJECT * block = (area - 1); return - (((area == first_valid) || - ((OBJECT_TYPE (*block)) != TC_MANIFEST_VECTOR) || - ((OBJECT_DATUM (*block)) < (count + 1)) || - (! (PLAUSIBLE_CC_BLOCK_P (block)))) + (((area == first_valid) + || ((OBJECT_TYPE (* block)) != TC_MANIFEST_VECTOR) + || ((OBJECT_DATUM (* block)) < ((unsigned long) (count + 1))) + || (! (PLAUSIBLE_CC_BLOCK_P (block)))) ? 0 : block); } @@ -884,6 +1031,240 @@ DEFUN (find_block_address_in_area, (pc_value, area_start), } return (0); } + +static void +DEFUN (trap_recover, (code, context), + DWORD code AND PCONTEXT context) +{ + IFVERBOSE (TellUserEx (MB_OKCANCEL, + "trap_recover (%s, 0x%lx).", + (find_exception_name (code)), context)); + + if (WITHIN_CRITICAL_SECTION_P ()) + { + CLEAR_CRITICAL_SECTION_HOOK (); + EXIT_CRITICAL_SECTION ({}); + } + reset_interruptable_extent (); + continue_from_trap (code, context); +} + +static void +DEFUN (nt_trap_handler, (code, context), + DWORD code AND PCONTEXT context) +{ + Boolean constant_space_broken = (! (CONSTANT_SPACE_SEALED ())); + enum trap_state old_trap_state = trap_state; + int flags; + + IFVERBOSE (TellUserEx (MB_OKCANCEL, + "nt_trap_handler (%s, 0x%lx).", + (find_exception_name (code)), context)); + + if (old_trap_state == trap_state_exitting_hard) + _exit (1); + else if (old_trap_state == trap_state_exitting_soft) + trap_immediate_termination (); + + trap_state = trap_state_trapped; + + trap_noise_start (); + if (WITHIN_CRITICAL_SECTION_P ()) + { + trap_noise (">> The system has trapped within critical section \"%s\".\n", + (CRITICAL_SECTION_NAME ())); + describe_trap ("trap is", code); + } + else if (constant_space_broken || (old_trap_state != trap_state_recover)) + { + trap_noise (">> The system has trapped.\n"); + describe_trap ("trap is", code); + } + if (constant_space_broken) + { + trap_noise (">> Constant space has been overwritten.\n"); + trap_noise (">> Probably a runaway recursion has overflowed the stack.\n"); + } + + switch (old_trap_state) + { + case trap_state_trapped: + if ((saved_trap_state == trap_state_recover) + || (saved_trap_state == trap_state_query)) + { + trap_noise (">> The trap occurred while processing an earlier trap.\n"); + describe_trap ("earlier trap was", saved_trap_code); + trap_noise ((WITHIN_CRITICAL_SECTION_P ()) + ? ">> Successful recovery is extremely unlikely.\n" + : ">> Successful recovery is unlikely.\n"); + break; + } + else + { + (void) trap_noise_end (MB_OK | MB_ICONSTOP); + trap_immediate_termination (); + } + + case trap_state_recover: + if ((WITHIN_CRITICAL_SECTION_P ()) || constant_space_broken) + { + trap_noise (">> Successful recovery is unlikely.\n"); + break; + } + else + { + saved_trap_state = old_trap_state; + saved_trap_code = code; + (void) trap_noise_end (MB_OK | MB_ICONSTOP); + trap_recover (code, context); + return; + } + case trap_state_exit: + (void) trap_noise_end (MB_OK | MB_ICONSTOP); + termination_trap (); + } + + trap_noise ("\n"); + saved_trap_state = old_trap_state; + saved_trap_code = code; + flags = MB_ICONSTOP; + + while (1) + { + trap_noise ("Attempt recovery?"); + if ((trap_noise_end (MB_YESNO | flags)) == IDYES) + { + trap_recover (code, context); + return; + } + flags = 0; + + trap_noise ("Terminate Scheme normally?"); + switch (trap_noise_end (MB_YESNOCANCEL)) + { + case IDYES: + trap_normal_termination (); + + case IDNO: + trap_immediate_termination (); + _exit (1); + + default: + break; + } + } +} + +#ifdef W32_TRAP_DEBUG + +static void +DEFUN (parse_response, (buf, addr, len), + char * buf AND unsigned long * addr AND int * len) +{ + const char * separators = " ,\t;"; + char * token; + + token = (strtok (buf, separators)); + if (token == ((char *) NULL)) + return; + * addr = (strtoul (token, ((char **) NULL), 0)); + token = (strtok (((char *) NULL), separators)); + if (token == ((char *) NULL)) + return; + * len = ((int) (strtoul (token, ((char **) NULL), 0))); + return; +} + +static void +DEFUN (tinyexcpdebug, (code, info), + DWORD code AND LPEXCEPTION_POINTERS info) +{ + int count, len; + char * message; + unsigned long * addr; + char responsebuf[256], * response; + + if ((MessageBox (NULL, "Debug?", "MIT Scheme Exception Debugger", MB_YESNO)) + != IDYES) + return; + + message = "&info ="; + addr = ((unsigned long *) (& info)); + len = 1; + + while (1) + { + trap_noise_start (); + trap_noise ("%s 0x%lx.\n", message, ((unsigned long) addr)); + for (count = 0; count < len; count++) + trap_noise ("\n*0x%08x\t= 0x%08x\t= %d.", + (addr + count), + addr[count], + addr[count]); + trap_noise ("\n\nMore?"); + if ((trap_noise_end (MB_YESNO)) != IDYES) + break; + response = (AskUser (&responsebuf[0], (sizeof (responsebuf)))); + if (response == ((char *) NULL)) + continue; + message = "Contents of"; + parse_response (&responsebuf[0], &addr, &len); + } + return; +} +#endif /* W32_TRAP_DEBUG */ + +static int +DEFUN (WinntException, (code, info), + DWORD code AND LPEXCEPTION_POINTERS info) +{ + PCONTEXT context; + + context = info->ContextRecord; + if ((info->ExceptionRecord->ExceptionFlags != 0) + || (context == ((PCONTEXT) NULL)) + || ((context->ContextFlags & CONTEXT_CONTROL) == 0) + || ((context->ContextFlags & CONTEXT_INTEGER) == 0) + || ((context->ContextFlags & CONTEXT_SEGMENTS) == 0)) + { + (void) + display_exception_information (info->ExceptionRecord, + info->ContextRecord, + MB_OK); + trap_immediate_termination (); + } + else + { +#ifdef W32_TRAP_DEBUG + trap_verbose_p = ((display_exception_information + (info->ExceptionRecord, + info->ContextRecord, + MB_YESNO)) + == IDYES); + tinyexcpdebug (code, info); +#endif /* W32_TRAP_DEBUG */ + nt_trap_handler (code, context); + return (EXCEPTION_CONTINUE_EXECUTION); + } +} -#endif /* HAVE_SIGCONTEXT and HAS_COMPILER_SUPPORT and not USE_STACKLETS */ +extern void EXFUN (WinntEnterHook, (void (*) (void))); +void +DEFUN (WinntEnterHook, (enter_interpreter), + void EXFUN ((* enter_interpreter), (void))) +{ + do + { + try + { + (* enter_interpreter) (); + } + except (WinntException ((GetExceptionCode ()), + (GetExceptionInformation ()))) + { + outf_fatal ("Exception!\n"); + termination_trap (); + } + } while (1); +} diff --git a/v7/src/microcode/nttrap.h b/v7/src/microcode/nttrap.h index 49df1f195..7550acd6e 100644 --- a/v7/src/microcode/nttrap.h +++ b/v7/src/microcode/nttrap.h @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: nttrap.h,v 1.3 1993/06/24 02:11:23 gjr Exp $ +$Id: nttrap.h,v 1.4 1993/08/21 03:50:40 gjr Exp $ Copyright (c) 1992-1993 Massachusetts Institute of Technology @@ -35,42 +35,6 @@ MIT in each case. */ #ifndef SCM_NTTRAP_H #define SCM_NTTRAP_H -#ifndef SIGINFO_T -#define SIGINFO_T unsigned -#define SIGINFO_VALID_P(info) (1) -#define SIGINFO_CODE(info) (info) -#endif - -/* EIP not included here, not a "register", except on the Vax. - 8 General registers. - 6 Segment registers. - 1 Flags register. - */ - -#define HAVE_SIGCONTEXT -#define HAVE_FULL_SIGCONTEXT -#define PROCESSOR_NREGS (8 + 6 + 1) -#define FULL_SIGCONTEXT_NREGS PROCESSOR_NREGS - -#define SIGCONTEXT sigcontext -#define SIGCONTEXT_SP(scp) ((scp)->sc_esp) -#define SIGCONTEXT_PC(scp) ((scp)->sc_eip) - -#define FULL_SIGCONTEXT SIGCONTEXT -#define FULL_SIGCONTEXT_SP SIGCONTEXT_SP -#define FULL_SIGCONTEXT_PC SIGCONTEXT_PC -#define FULL_SIGCONTEXT_RFREE(scp) ((scp)->sc_edi) -#define FULL_SIGCONTEXT_FIRST_REG(scp) (& (scp->sc_eax)) -#define FULL_SIGCONTEXT_SCHSP FULL_SIGCONTEXT_SP - -#define DECLARE_FULL_SIGCONTEXT(name) \ - struct FULL_SIGCONTEXT * name - -#define INITIALIZE_FULL_SIGCONTEXT(partial, full) \ - ((full) = ((struct FULL_SIGCONTEXT *) (partial))) - -#define INVALID_TRAP -1 - enum trap_state { trap_state_trapped, @@ -83,13 +47,5 @@ enum trap_state }; extern enum trap_state EXFUN (OS_set_trap_state, (enum trap_state state)); -extern void EXFUN - (trap_handler, - (CONST char * message, - int signo, - SIGINFO_T info, - struct FULL_SIGCONTEXT * scp)); -extern void EXFUN (hard_reset, (struct FULL_SIGCONTEXT * scp)); -extern void EXFUN (soft_reset, (void)); #endif /* SCM_NTTRAP_H */ diff --git a/v7/src/microcode/nttty.c b/v7/src/microcode/nttty.c index c5678bdec..b93b745bf 100644 --- a/v7/src/microcode/nttty.c +++ b/v7/src/microcode/nttty.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: nttty.c,v 1.3 1993/06/24 02:12:04 gjr Exp $ +$Id: nttty.c,v 1.4 1993/08/21 03:51:19 gjr Exp $ Copyright (c) 1992-1993 Massachusetts Institute of Technology @@ -102,18 +102,13 @@ DEFUN_VOID (OS_tty_command_clear) #define DEFAULT_TTY_Y_SIZE 25 #endif - - void -DEFUN_VOID (DOS_initialize_tty) +DEFUN_VOID (NT_initialize_tty) { extern Tchannel EXFUN (OS_open_handle, (int fd)); -// master_tty_window = Screen_Create (NULL, "MIT Scheme", SW_SHOWNORMAL); - input_channel = OS_open_handle (master_tty_window); -// input_channel = OS_open_handle (STDIN_HANDLE); + input_channel = (OS_open_handle (master_tty_window)); (CHANNEL_INTERNAL (input_channel)) = 1; output_channel = input_channel; -// output_channel = OS_open_handle (STDOUT_HANDLE); (CHANNEL_INTERNAL (output_channel)) = 1; Screen_GetSize (master_tty_window, &tty_y_size, &tty_x_size); diff --git a/v7/src/microcode/ntutl/scheme16.c b/v7/src/microcode/ntutl/scheme16.c index fd2021ca4..0d072cc5d 100644 --- a/v7/src/microcode/ntutl/scheme16.c +++ b/v7/src/microcode/ntutl/scheme16.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: scheme16.c,v 1.1 1993/07/27 20:53:27 gjr Exp $ +$Id: scheme16.c,v 1.2 1993/08/21 03:51:47 gjr Exp $ Copyright (c) 1993 Massachusetts Institute of Technology @@ -36,123 +36,436 @@ MIT in each case. */ Win16 side of the Win32s version. */ +#define _WINDLL #define W32SUT_16 -#include -#include -#include -#include "ntw32lib.h" +#include "ntscmlib.h" +#include -#ifndef STD_MSGBOX_STYLE -# define STD_MSGBOX_STYLE MB_OK -#endif +struct seg_desc_s +{ + unsigned long low; + unsigned long high; +}; -static void -TellUser (char * format, unsigned long value) -{ - char buffer[128]; - - wsprintf (&buffer[0], - ((LPCSTR) format), - value); - - MessageBox (NULL, - ((LPCSTR) &buffer[0]), - ((LPCSTR) "MIT Scheme Win16 Notification"), - STD_MSGBOX_STYLE); - return; +static BOOL +DPMI_get_descriptor (UINT selector, struct seg_desc_s far * desc) +{ + UINT saved_es; + + _asm + { + _emit 066h + push di + _emit 066h + push bx + _emit 066h + xor di,di + mov ax,es + mov word ptr [bp-2],ax + les di, dword ptr 6[bp] + mov bx, word ptr 4[bp] + mov ax, 000bh + int 31h + jc fail + mov ax, word ptr [bp-2] + mov es,ax + _emit 066h + pop bx + _emit 066h + pop di + mov ax,0 + leave + ret + fail: + mov ax, word ptr [bp-2] + mov es,ax + _emit 066h + pop bx + _emit 066h + pop di + mov ax,1 + leave + ret + } } + +static BOOL +DPMI_set_descriptor (UINT selector, struct seg_desc_s far * desc) +{ + UINT saved_es; + _asm + { + _emit 066h + push di + _emit 066h + push bx + _emit 066h + xor di,di + mov ax,es + mov word ptr [bp-2],ax + les di, dword ptr 6[bp] + mov bx, word ptr 4[bp] + mov ax, 000ch + int 31h + jc fail + mov ax, word ptr [bp-2] + mov es,ax + _emit 066h + pop bx + _emit 066h + pop di + mov ax,0 + leave + ret + fail: + mov ax, word ptr [bp-2] + mov es,ax + _emit 066h + pop bx + _emit 066h + pop di + mov ax,1 + leave + ret + } +} + static DWORD -win16_allocate_heap (struct ntw32lib_malloc_s FAR * buf) +win16_alloc_scheme_selectors (struct ntw32lib_selalloc_s FAR * buf) { - DWORD linear_address = 0L; - DWORD handle = 0L; - UINT lose = 0; - UINT code = 0; - + UINT cs_sel, ds_sel; + struct seg_desc_s desc; + unsigned long nbase, nlimit; + + ds_sel = (AllocSelector (0)); + if (ds_sel == 0) + return (0L); + nbase = (GetSelectorBase (buf->ds32)); + + nbase = (nbase + buf->base); + (void) DPMI_get_descriptor (buf->ds32, & desc); + + desc.low &= 0xffffUL; + desc.low |= (nbase << 16); + desc.high &= 0x00ffff00UL; + desc.high |= (nbase & 0xff000000UL); + desc.high |= ((nbase >> 16) & 0xff); + (void) DPMI_set_descriptor (ds_sel, & desc); + + cs_sel = (AllocDStoCSAlias (ds_sel)); + if (cs_sel == 0) + { #if 0 - union _REGS regs; + FreeSelector (ds_sel); +#endif + return (0L); + } + buf->cs = cs_sel; + buf->ds = ds_sel; + buf->ss = ds_sel; - regs.x.ax = 0x0501; - regs.x.bx = (HIWORD (buf->size)); - regs.x.cx = (LOWORD (buf->size)); - (void) _int86 (0x31, ®s, ®s); + nbase = (GetSelectorBase (cs_sel)); + nlimit = (GetSelectorLimit (cs_sel)); - if (regs.x.cflag) + if ((nbase != 0) && (nlimit != 0)) + return (1L); + else { - TellUser ("DPMI failed.", 0L); +#if 0 + FreeSelector (cs_sel); + FreeSelector (ds_sel); +#endif return (0L); } - linear_address = (MAKELONG (regs.x.cx, regs.x.bx)); +} -#elif 0 - TellUser ("Trying to allocate %ld bytes.", buf->size); - - _asm les bx,DWORD PTR [bp+4] - _asm mov bx,WORD PTR es:[bx+2] - _asm mov cx,WORD PTR es:[bx] - _asm mov ax,0501H - _asm int 031h +static DWORD +win16_release_scheme_selectors (struct ntw32lib_selfree_s FAR * buf) +{ +#if 0 + if ((buf->ds != 0) && (buf->ds != buf->ds32)) + FreeSelector (buf->ds); + if ((buf->cs != 0) && (buf->cs != buf->cs32)) + FreeSelector (buf->cs); +#endif + return (1L); +} + +static BOOL +DPMI_lock_unlock (UINT fun, unsigned long lin, unsigned long nbytes) +{ + _asm + { + push si + push di + push bx + + mov ax, 4[bp] + mov cx, 6[bp] + mov bx, 8[bp] + mov di, 10[bp] + mov si, 12[bp] + + int 31h + jc fail + mov ax,1 + jmp join + + fail: + xor ax,ax + join: + pop bx + pop di + pop si + leave + ret + } +} - _asm jnc dpmi_wins - _asm mov WORD PTR [bp-10],1 - _asm jmp dpmi_merge +static BOOL +pagelockunlock (unsigned int dpmi_fun, void FAR * low, unsigned long nbytes) +{ + unsigned int seg, off; + unsigned long base, lin; - _asm dpmi_wins: - _asm mov WORD PTR [bp-4],cx - _asm mov WORD PTR [bp-2],bx - _asm dpmi_merge: + seg = (FP_SEG (low)); + off = (FP_OFF (low)); + base = (GetSelectorBase (seg)); + lin = (base + ((unsigned long) off)); -#else + return (DPMI_lock_unlock (dpmi_fun, lin, nbytes)); +} - TellUser ("Trying to allocate %ld bytes.", buf->size); - - _asm les bx,DWORD PTR [bp+4] - _asm mov ecx,DWORD PTR es:[bx] - _asm mov ebx,00200000H - _asm mov edx,1 - _asm mov ax,0504H - _asm int 031H - - _asm jnc dpmi_wins - _asm mov WORD PTR [bp-10],1 - _asm mov WORD PTR [bp-12],ax - _asm jmp dpmi_merge - - _asm dpmi_wins: - _asm mov DWORD PTR [bp-4],ebx - _asm mov DWORD PTR [bp-8],esi - _asm dpmi_merge: +static BOOL +pagelock (void FAR * low, unsigned long nbytes) +{ + return (pagelockunlock (0x0600, low, nbytes)); +} -#endif +static BOOL +pageunlock (void FAR * low, unsigned long nbytes) +{ + return (pagelockunlock (0x0601, low, nbytes)); +} + +static DWORD +win16_lock_area (struct ntw32lib_vlock_s FAR * buf) +{ + return ((DWORD) (pagelock (buf->area, buf->size))); +} - if (lose) +static DWORD +win16_unlock_area (struct ntw32lib_vulock_s FAR * buf) +{ + return ((DWORD) (pageunlock (buf->area, buf->size))); +} + +#ifndef MK_FP +static void FAR * +MK_FP (unsigned short seg, unsigned short off) +{ + union { - TellUser ("DPMI call failed 0x%x", ((unsigned long) code)); - return (0L); + struct + { + unsigned short off; + unsigned short seg; + } split; + void FAR * result; + } views; + + views.split.seg = seg; + views.split.off = off; + return (views.result); +} +#endif /* MK_FP */ + +static WORD htimer = 0; +static unsigned long timer_index = 0; + +static WORD (FAR PASCAL * KillSystemTimer) (WORD htimer); + +static struct ntw16lib_itimer_s +{ + struct ntw16lib_itimer_s FAR * next; + unsigned long FAR * base; + unsigned long memtop_off; + unsigned long int_code_off; + unsigned long int_mask_off; + unsigned long bit_mask; + unsigned long index; + UINT selector; + HGLOBAL ghan; +} FAR * async_timers = ((struct ntw16lib_itimer_s FAR *) NULL); + +void FAR _export +scheme_asynctimer (void) +{ + struct ntw16lib_itimer_s FAR * scm_timer = async_timers; + + while (scm_timer != ((struct ntw16lib_itimer_s FAR *) NULL)) + { + scm_timer->base[scm_timer->int_code_off] |= scm_timer->bit_mask; + if ((scm_timer->base[scm_timer->int_mask_off] + & scm_timer->bit_mask) + != 0) + scm_timer->base[scm_timer->memtop_off] = ((unsigned long) -1L); + scm_timer = scm_timer->next; } - - TellUser ("Linear address = 0x%lx.", linear_address); - TellUser ("Handle = 0x%lx.", handle); - buf->area = linear_address; - buf->handle = handle; - return (linear_address); + return; } -static DWORD -win16_release_heap (struct ntw32lib_malloc_s FAR * buf) +static void +scheme_asynctimer_end (void) { - TellUser ("Freeing arena with handle 0x%lx", buf->handle); + return; +} + +static void +possibly_uninstall_async_handler (void) +{ + if (async_timers != ((struct ntw16lib_itimer_s FAR *) NULL)) + return; + if (htimer != 0) + { + KillSystemTimer (htimer); + htimer = 0; + } + pageunlock (&async_timers, + (sizeof (struct ntw16lib_itimer_s FAR *))); + pageunlock (((void FAR *) scheme_asynctimer), + ((unsigned long) scheme_asynctimer_end) + - ((unsigned long) scheme_asynctimer)); + return; +} - _asm les bx,DWORD PTR [bp+4] - _asm mov si,WORD PTR es:[bx+6] - _asm mov di,WORD PTR es:[bx+4] - _asm mov ax,0502H - _asm int 031H +static DWORD +win16_flush_timer (struct ntw32lib_ftimer_s FAR * buf) +{ + unsigned long index = buf->handle; + struct ntw16lib_itimer_s FAR * FAR * ptr = & async_timers; + while ((* ptr) != ((struct ntw16lib_itimer_s FAR *) NULL)) + { + if (((* ptr) -> index) == index) + { + struct ntw16lib_itimer_s FAR * current = (* ptr); + + (* ptr) = current->next; + if (index == (timer_index - 1)) + timer_index = index; + FreeSelector (current->selector); + GlobalPageUnlock (current->ghan); + GlobalUnlock (current->ghan); + GlobalFree (current->ghan); + possibly_uninstall_async_handler (); + return (1L); + } + ptr = & ((* ptr) -> next); + } return (0L); } +static DWORD +do_install_async_handler (void) +{ + WORD (FAR PASCAL * CreateSystemTimer) (WORD rate, FARPROC callback); + HINSTANCE hsystem; + + if (! (pagelock (((void FAR *) scheme_asynctimer), + ((unsigned long) scheme_asynctimer_end) + - ((unsigned long) scheme_asynctimer)))) + return (WIN32_ASYNC_TIMER_NOLOCK); + else if (! (pagelock (&async_timers, + (sizeof (struct ntw16lib_itimer_s FAR *))))) + { + pageunlock (((void FAR *) scheme_asynctimer), + ((unsigned long) scheme_asynctimer_end) + - ((unsigned long) scheme_asynctimer)); + return (WIN32_ASYNC_TIMER_NOLOCK); + } + + hsystem = (GetModuleHandle ("SYSTEM")); + CreateSystemTimer = (GetProcAddress (hsystem, "CREATESYSTEMTIMER")); + KillSystemTimer = (GetProcAddress (hsystem, "KILLSYSTEMTIMER")); + + if ((CreateSystemTimer == ((WORD (FAR PASCAL *) (WORD, FARPROC)) NULL)) + || (KillSystemTimer == ((WORD (FAR PASCAL *) (WORD)) NULL))) + { + possibly_uninstall_async_handler (); + return (WIN32_ASYNC_TIMER_NONE); + } + + htimer = (CreateSystemTimer (55, ((FARPROC) scheme_asynctimer))); + if (htimer == 0) + { + possibly_uninstall_async_handler (); + return (WIN32_ASYNC_TIMER_EXHAUSTED); + } + return (WIN32_ASYNC_TIMER_OK); +} + +static DWORD +win16_install_timer (struct ntw32lib_itimer_s FAR * buf) +{ + struct ntw16lib_itimer_s FAR * scm_timer; + DWORD result; + HGLOBAL ghan; + + if (htimer == 0) + { + result = (do_install_async_handler ()); + if (result != WIN32_ASYNC_TIMER_OK) + return (result); + } + + ghan = (GlobalAlloc (GMEM_FIXED, (sizeof (struct ntw16lib_itimer_s)))); + if (ghan == ((HGLOBAL) NULL)) + { + possibly_uninstall_async_handler (); + return (WIN32_ASYNC_TIMER_NOMEM); + } + scm_timer = ((struct ntw16lib_itimer_s FAR *) (GlobalLock (ghan))); + if (scm_timer == ((struct ntw16lib_itimer_s FAR *) NULL)) + { + GlobalFree (ghan); + possibly_uninstall_async_handler (); + return (WIN32_ASYNC_TIMER_NOLOCK); + } + if ((GlobalPageLock (ghan)) == 0) + { + GlobalUnlock (ghan); + GlobalFree (ghan); + possibly_uninstall_async_handler (); + return (WIN32_ASYNC_TIMER_NOLOCK); + } + + scm_timer->selector = (AllocSelector (FP_SEG (buf->base))); + if (scm_timer->selector == 0) + { + GlobalPageUnlock (ghan); + GlobalUnlock (ghan); + GlobalFree (ghan); + possibly_uninstall_async_handler (); + return (WIN32_ASYNC_TIMER_NOLDT); + } + + scm_timer->ghan = ghan; + scm_timer->base = (MK_FP (scm_timer->selector, (FP_OFF (buf->base)))); + scm_timer->memtop_off = buf->memtop_off; + scm_timer->int_code_off = buf->int_code_off; + scm_timer->int_mask_off = buf->int_mask_off; + scm_timer->bit_mask = buf->bit_mask; + scm_timer->index = timer_index++; + scm_timer->next = async_timers; + + buf->handle = scm_timer->index; + async_timers = scm_timer; + + return (WIN32_ASYNC_TIMER_OK); +} + /* The 32-bit call-back thunk is not really needed right now, but ... */ static UT16CBPROC call_32_bit_code = NULL; @@ -176,16 +489,22 @@ ntw16lib_handler (LPVOID buf, DWORD func) return (win16_release_heap (buf)); case NTW32LIB_VIRTUAL_LOCK: - return (1L); + return (win16_lock_area (buf)); case NTW32LIB_VIRTUAL_UNLOCK: - return (1L); + return (win16_unlock_area (buf)); case NTW32LIB_INSTALL_TIMER: - return (0L); + return (win16_install_timer (buf)); case NTW32LIB_FLUSH_TIMER: - return (0L); + return (win16_flush_timer (buf)); + + case NTW32LIB_ALLOC_SELECTORS: + return (win16_alloc_scheme_selectors (buf)); + + case NTW32LIB_FREE_SELECTORS: + return (win16_release_scheme_selectors (buf)); default: return (0L); diff --git a/v7/src/microcode/ntutl/scheme16.def b/v7/src/microcode/ntutl/scheme16.def index 016ba66aa..a54aa0733 100644 --- a/v7/src/microcode/ntutl/scheme16.def +++ b/v7/src/microcode/ntutl/scheme16.def @@ -5,8 +5,8 @@ EXETYPE WINDOWS STUB "WINSTUB.EXE" -CODE PRELOAD MOVEABLE DISCARDABLE -DATA PRELOAD MOVEABLE SINGLE +CODE PRELOAD +DATA PRELOAD HEAPSIZE 1024 diff --git a/v7/src/microcode/ntutl/scheme16.mak b/v7/src/microcode/ntutl/scheme16.mak index dfe8fd204..6cfb93687 100644 --- a/v7/src/microcode/ntutl/scheme16.mak +++ b/v7/src/microcode/ntutl/scheme16.mak @@ -1,6 +1,6 @@ ### -*- Fundamental -*- ### -### $Id: scheme16.mak,v 1.1 1993/07/27 20:53:38 gjr Exp $ +### $Id: scheme16.mak,v 1.2 1993/08/21 03:54:51 gjr Exp $ ### ### Copyright (c) 1993 Massachusetts Institute of Technology ### @@ -45,15 +45,9 @@ all: ntw16lib.dll # with the Win16 SDK! ntw16lib.obj: ntw16lib.c ntw32lib.h - cl /c /ASw /Fa /G2 /Gsw /Ow /W2 /Zp1 ntw16lib.c - -# ntw16lib.dll: ntw16lib.obj ntw16lib.def -# link ntw16lib.obj libentry.obj, ntw16lib.dll,ntw16lib.map /map, \ -# w32sut16.lib mdllcew.lib libw.lib/noe/nod,ntw16lib.def + cl /c /ASw /G2 /Gsw /Ow /W2 /Zp1 ntw16lib.c ntw16lib.dll: ntw16lib.obj ntw16lib.def link ntw16lib.obj, ntw16lib.dll,ntw16lib.map /map, \ w32sut16.lib mdllcew.lib libw.lib/noe/nod,ntw16lib.def - -