From: Guillermo J. Rozas Date: Fri, 25 Sep 1992 21:46:01 +0000 (+0000) Subject: Add critical-error handling outside of DPMI (Windows). X-Git-Tag: 20090517-FFI~8903 X-Git-Url: https://birchwood-abbey.net/git?a=commitdiff_plain;h=40d6c498aea39aace3b306af4ccf3ef66655432b;p=mit-scheme.git Add critical-error handling outside of DPMI (Windows). --- diff --git a/v7/src/microcode/dossig.c b/v7/src/microcode/dossig.c index 04e15ad54..16cba1bec 100644 --- a/v7/src/microcode/dossig.c +++ b/v7/src/microcode/dossig.c @@ -1,6 +1,6 @@ /* -*-C-*- -$Id: dossig.c,v 1.8 1992/09/25 01:23:24 jinx Exp $ +$Id: dossig.c,v 1.9 1992/09/25 21:42:38 jinx Exp $ Copyright (c) 1992 Massachusetts Institute of Technology @@ -44,6 +44,9 @@ MIT in each case. */ #include "dossys.h" #include "dosexcp.h" #include "doskbd.h" +#ifdef USE_ZORTECH_CERROR +#include +#endif cc_t EXFUN (DOS_interactive_interrupt_handler, (void)); @@ -716,16 +719,67 @@ DEFUN_STD_HANDLER (sighnd_dead_subprocess, { }) -/* PC specific low-level interrupt hooks */ -/* Control-Break Interrupt */ +/* PC specific low-level interrupt hooks. */ +/* Control-Break Interrupt. */ int -DEFUN (control_break_handler, (pd), struct INT_DATA *pd) +DEFUN (control_break_handler, (pd), struct INT_DATA * pd) { tty_set_next_interrupt_char (CONTROL_G_INTERRUPT_CHAR); - return INTERRUPT_RETURN; + return (INTERRUPT_RETURN); +} + +/* Critical-Error (abort, retry, ignore, fail) handler */ + +#define CE_CAN_ERROR_BIT 0x1000 +#define CE_CAN_RETRY_BIT 0x0800 +#define CE_CAN_IGNORE_BIT 0x0400 + +#define CE_IGNORE 0 +#define CE_RETRY 1 +#define CE_KILL 2 +#define CE_ERROR 3 + +int +ce_handler (int * ax, int * di) +{ + if (((* ax) & CE_CAN_ERROR_BIT) != 0) + * ax = (((* ax) & 0xff00) | CE_ERROR); + + else if (((* ax) & CE_CAN_IGNORE_BIT) != 0) + * ax = (((* ax) & 0xff00) | CE_IGNORE); + + else if (((* ax) & CE_CAN_RETRY_BIT) != 0) + * ax = (((* ax) & 0xff00) | CE_RETRY); + + else + /* We should really kill Scheme, + but there may be no way to do this from here. + */ + * ax = (((* ax) & 0xff00) | CE_KILL); + + return (1); +} + +#ifdef USE_ZORTECH_CERROR + +int _far _cdecl +critical_error_handler (int * ax, int * di) +{ + return (ce_handler (ax, di)); } +#else /* not USE_ZORTECH_CERROR */ + +int +DEFUN (critical_error_handler, (pd), struct INT_DATA * pd) +{ + int value = (ce_handler (&pd->regs.e.eax, &pd->regs.e.edi)); + return ((value == 1) ? INTERRUPT_RETURN : INTERRUPT_CHAIN_NEXT); +} + +#endif /* USE_ZORTECH_CERROR */ + /* Interval timer */ /* Scheme timer emulation; DOS does not have an ITIMER like unix. */ @@ -813,6 +867,10 @@ DEFUN_VOID (DOS_initialize_interrupts) { int iv; +#ifdef USE_ZORTECH_CERROR + _cerror_handler = ((int _far _cdecl (*) (int *, int *)) NULL); +#endif + ctrl_c_check_flag = (dos_set_ctrl_c_check_flag (0)); for (iv = (NUM_DOS_HANDLERS - 1); iv >= 0; iv--) @@ -1025,7 +1083,7 @@ DEFUN_VOID (enable_DPMI_exceptions_p) else return (dos_false); } - + static void DEFUN_VOID (DOS_install_interrupts) { @@ -1040,7 +1098,9 @@ DEFUN_VOID (DOS_install_interrupts) extern int EXFUN (X32_interrupt_restore, (unsigned)); extern int EXFUN (X32_int_intercept, (unsigned, void (*) (), PTR)); extern void EXFUN (X32_timer_interrupt, (void)); + extern void EXFUN (X32_critical_error, (void)); extern int X32_timer_interrupt_previous; + extern int X32_critical_error_previous; X32_asm_initialize (); @@ -1068,6 +1128,22 @@ DEFUN_VOID (DOS_install_interrupts) else dos_record_interrupt_interception (DOS_INTVECT_USER_TIMER_TICK, X32_interrupt_restore); + + if (!dpmi_p) + { +#ifdef USE_ZORTECH_CERROR + _cerror_handler = critical_error_handler; + cerror_open (); +#else /* not USE_ZORTECH_CERROR */ + if ((X32_int_intercept (DOS_INTVECT_CRITICAL_ERROR, + X32_critical_error, + ((PTR) &X32_critical_error_previous))) + == 0) + dos_record_interrupt_interception (DOS_INTVECT_CRITICAL_ERROR, + X32_interrupt_restore); + +#endif /* USE_ZORTECH_CERROR */ + } } else @@ -1077,10 +1153,20 @@ DEFUN_VOID (DOS_install_interrupts) 256); if (!dpmi_p) + { scm_int_intercept (DOS_INTVECT_KB_CTRL_BREAK, control_break_handler, 256); +#ifdef USE_ZORTECH_CERROR + _cerror_handler = critical_error_handler; + cerror_open (); +#else /* not USE_ZORTECH_CERROR */ + scm_int_intercept (DOS_INTVECT_CRITICAL_ERROR, + critical_error_handler, + 256); +#endif /* USE_ZORTECH_CERROR */ + } } if ((dos_install_kbd_hook ()) == DOS_SUCCESS) @@ -1115,6 +1201,15 @@ DEFUN_VOID (DOS_restore_interrupts) (void) ((dos_interrupt_restoration[iv]) (iv)); dos_interrupt_restoration[iv] = ((int (*) (unsigned)) NULL); } + +#ifdef USE_ZORTECH_CERROR + if (_cerror_handler == critical_error_handler) + { + cerror_close (); + _cerror_handler = ((int _far _cdecl (*) (int *, int *)) NULL); + } +#endif /* USE_ZORTECH_CERROR */ + dos_interrupts_initialized_p = false; } dos_set_ctrl_c_check_flag (ctrl_c_check_flag); diff --git a/v7/src/microcode/dosxcutl.asm b/v7/src/microcode/dosxcutl.asm index fa865e4cc..d8813bac6 100644 --- a/v7/src/microcode/dosxcutl.asm +++ b/v7/src/microcode/dosxcutl.asm @@ -1,6 +1,6 @@ ;;; -*-Midas-*- ;;; -;;; $Id: dosxcutl.asm,v 1.6 1992/09/25 01:21:28 jinx Exp $ +;;; $Id: dosxcutl.asm,v 1.7 1992/09/25 21:46:01 jinx Exp $ ;;; ;;; Copyright (c) 1992 Massachusetts Institute of Technology ;;; @@ -389,6 +389,11 @@ _X32_excp_handlers db 32*20 dup (0) public _X32_ds_val _X32_ds_val dd 06765h + public _X32_critical_error_previous +_X32_critical_error_previous dd 0 + dd 0 + dd 0 + public _X32_timer_interrupt_previous _X32_timer_interrupt_previous dd 0 dd 0 @@ -586,6 +591,42 @@ x32_timer_return: pop ds jmp fword ptr cs:_X32_timer_interrupt_previous +;; X32 critical error interrupt handler. +;; This gets invoked primarily when accessing removable media +;; that is not present. +;; Very few DOS functions can be invoked from here. + + public _X32_critical_error +_X32_critical_error: + pushfd + test ah,10h ; can error ? + je x32_critical_error_ignore + mov al,03h ; error + jmp x32_critical_error_return + +x32_critical_error_ignore: + test ah,04h ; can ignore ? + je x32_critical_error_retry + mov al,00h ; ignore + jmp x32_critical_error_return + +x32_critical_error_retry: + test ah,08h ; can retry ? + je x32_critical_error_kill + mov al,01h ; ignore + jmp x32_critical_error_return + +x32_critical_error_kill: + ;; For now, invoke the previous handler. + ;; Eventually we should abort cleanly, + ;; but it is not clear it can be done. + popfd + jmp fword ptr cs:_X32_critical_error_previous + +x32_critical_error_return: + popfd + iretd + ;; X32 keyboard interrupt handler ;; This performs scan-code to ASCII translation in order ;; not to drop the bucky bits.