--- /dev/null
+/* -*-C-*-
+
+$Id: nt.h,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992-1993 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/* DOS system include file */
+
+#ifndef SCM_MSDOS_H
+#define SCM_MSDOS_H
+\f
+#define SYSTEM_NAME "NT"
+#define SYSTEM_VARIANT "Windows-NT"
+
+#include <windows.h>
+#include <sys/types.h>
+#include <sys/times.h>
+#include <dos.h>
+#include <io.h>
+#include <conio.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <direct.h>
+#include <signal.h>
+#include <errno.h>
+
+#include <fcntl.h> /*SRA*/
+
+/* We fake these for console I/O in DOS */
+#ifndef ESTALE
+#define ESTALE 1997
+#endif
+#ifndef ERRNO_NONBLOCK
+#define ERRNO_NONBLOCK 1998
+#endif
+#ifndef EINTR
+#define EINTR 1999
+#endif
+
+#include "oscond.h"
+#include "ansidecl.h"
+#include "posixtyp.h"
+
+#include "intext.h"
+#include "dstack.h"
+#include "osscheme.h"
+#include "ntsys.h"
+\f
+enum syscall_names
+{
+ syscall_accept,
+ syscall_bind,
+ syscall_chdir,
+ syscall_chmod,
+ syscall_close,
+ syscall_connect,
+ syscall_fcntl_GETFL,
+ syscall_fcntl_SETFL,
+ syscall_fork,
+ syscall_fstat,
+ syscall_ftruncate,
+ syscall_getcwd,
+ syscall_gethostname,
+ syscall_gettimeofday,
+ syscall_ioctl_TIOCGPGRP,
+ syscall_ioctl_TIOCSIGSEND,
+ syscall_kill,
+ syscall_link,
+ syscall_listen,
+ syscall_localtime,
+ syscall_lseek,
+ syscall_malloc,
+ syscall_mkdir,
+ syscall_open,
+ syscall_opendir,
+ syscall_pause,
+ syscall_pipe,
+ syscall_read,
+ syscall_readlink,
+ syscall_realloc,
+ syscall_rename,
+ syscall_rmdir,
+ syscall_select,
+ syscall_setitimer,
+ syscall_setpgid,
+ syscall_sighold,
+ syscall_sigprocmask,
+ syscall_sigsuspend,
+ syscall_sleep,
+ syscall_socket,
+ syscall_symlink,
+ syscall_tcdrain,
+ syscall_tcflush,
+ syscall_tcgetpgrp,
+ syscall_tcsetpgrp,
+ syscall_terminal_get_state,
+ syscall_terminal_set_state,
+ syscall_time,
+ syscall_times,
+ syscall_unlink,
+ syscall_utime,
+ syscall_vfork,
+ syscall_write,
+ syscall_stat,
+ syscall_lstat,
+ syscall_mktime
+};
+\f
+enum syserr_names
+{
+ syserr_unknown,
+ syserr_arg_list_too_long,
+ syserr_bad_address,
+ syserr_bad_file_descriptor,
+ syserr_broken_pipe,
+ syserr_directory_not_empty,
+ syserr_domain_error,
+ syserr_exec_format_error,
+ syserr_file_exists,
+ syserr_file_too_large,
+ syserr_filename_too_long,
+ syserr_function_not_implemented,
+ syserr_improper_link,
+ syserr_inappropriate_io_control_operation,
+ syserr_interrupted_function_call,
+ syserr_invalid_argument,
+ syserr_invalid_seek,
+ syserr_io_error,
+ syserr_is_a_directory,
+ syserr_no_child_processes,
+ syserr_no_locks_available,
+ syserr_no_space_left_on_device,
+ syserr_no_such_device,
+ syserr_no_such_device_or_address,
+ syserr_no_such_file_or_directory,
+ syserr_no_such_process,
+ syserr_not_a_directory,
+ syserr_not_enough_space,
+ syserr_operation_not_permitted,
+ syserr_permission_denied,
+ syserr_read_only_file_system,
+ syserr_resource_busy,
+ syserr_resource_deadlock_avoided,
+ syserr_resource_temporarily_unavailable,
+ syserr_result_too_large,
+ syserr_too_many_links,
+ syserr_too_many_open_files,
+ syserr_too_many_open_files_in_system
+};
+
+extern void EXFUN (error_system_call, (int code, enum syscall_names name));
+
+#include <limits.h>
+#include <time.h>
+#include <termio.h>
+
+#define HAVE_MKDIR
+#define HAVE_RMDIR
+#define HAVE_GETCWD
+
+/* #define HAVE_DUP2 */
+/* #define HAVE_FCNTL */
+#define VOID_SIGNAL_HANDLERS
+
+#include <sys/dir.h>
+\f
+typedef void Tsignal_handler_result;
+#define SIGNAL_HANDLER_RETURN() return
+
+typedef Tsignal_handler_result (*Tsignal_handler) ();
+
+#ifndef SIG_ERR
+#define SIG_ERR ((Tsignal_handler) (-1))
+#endif
+
+#if !defined(SIGCHLD) && defined(SIGCLD)
+#define SIGCHLD SIGCLD
+#endif
+#if !defined(SIGABRT) && defined(SIGIOT)
+#define SIGABRT SIGIOT
+#endif
+
+/* Crufty, but it will work here. */
+#ifndef ENOSYS
+#define ENOSYS 0
+#endif
+
+#ifdef UNION_WAIT_STATUS
+
+typedef union wait wait_status_t;
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(_X) ((_X) . w_retcode)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(_X) ((_X) . w_termsig)
+#endif
+
+#ifndef WSTOPSIG
+#define WSTOPSIG(_X) ((_X) . w_stopsig)
+#endif
+
+#else /* not UNION_WAIT_STATUS */
+
+typedef int wait_status_t;
+
+#ifndef WIFEXITED
+#define WIFEXITED(_X) (((_X) & 0377) == 0)
+#endif
+
+#ifndef WIFSTOPPED
+#define WIFSTOPPED(_X) (((_X) & 0377) == 0177)
+#endif
+
+#ifndef WIFSIGNALED
+#define WIFSIGNALED(_X) ((((_X) & 0377) != 0) && (((_X) & 0377) != 0177))
+#endif
+
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(_X) (((_X) >> 8) & 0377)
+#endif
+
+#ifndef WTERMSIG
+#define WTERMSIG(_X) ((_X) & 0177)
+#endif
+
+#ifndef WSTOPSIG
+#define WSTOPSIG(_X) (((_X) >> 8) & 0377)
+#endif
+
+#endif /* UNION_WAIT_STATUS */
+\f
+/* Provide null defaults for all the signals we're likely to use so we
+ aren't continually testing to see if they're defined. */
+
+#ifndef SIGLOST
+#define SIGLOST 0
+#endif
+#ifndef SIGWINCH
+#define SIGWINCH 0
+#endif
+#ifndef SIGURG
+#define SIGURG 0
+#endif
+#ifndef SIGIO
+#define SIGIO 0
+#endif
+#ifndef SIGUSR1
+#define SIGUSR1 0
+#endif
+#ifndef SIGUSR2
+#define SIGUSR2 0
+#endif
+#ifndef SIGVTALRM
+#define SIGVTALRM 0
+#endif
+#ifndef SIGABRT
+#define SIGABRT 0
+#endif
+#ifndef SIGPWR
+#define SIGPWR 0
+#endif
+#ifndef SIGPROF
+#define SIGPROF 0
+#endif
+#ifndef SIGSTOP
+#define SIGSTOP 0
+#endif
+#ifndef SIGTSTP
+#define SIGTSTP 0
+#endif
+#ifndef SIGCONT
+#define SIGCONT 0
+#endif
+#ifndef SIGCHLD
+#define SIGCHLD 0
+#endif
+#ifndef SIGTTIN
+#define SIGTTIN 0
+#endif
+#ifndef SIGTTOU
+#define SIGTTOU 0
+#endif
+\f
+/* constants for access() */
+#ifndef R_OK
+#define R_OK 4
+#define W_OK 2
+#define X_OK 1
+#define F_OK 0
+#endif
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 128
+#endif
+
+#ifdef __STDC__
+#define ALERT_CHAR '\a'
+#define ALERT_STRING "\a"
+#else
+#define ALERT_CHAR '\007'
+#define ALERT_STRING "\007"
+#endif
+
+#ifndef STDIN_FILENO
+#define STDIN_FILENO 0
+#define STDOUT_FILENO 1
+#define STDERR_FILENO 2
+#endif
+
+/* constants for open() and fcntl() */
+#ifndef O_RDONLY
+#define O_RDONLY 0
+#define O_WRONLY 1
+#define O_RDWR 2
+#endif
+
+/* mode bit definitions for open(), creat(), and chmod() */
+#ifndef S_IRWXU
+#define S_IRWXU 0700
+#define S_IRWXG 0070
+#define S_IRWXO 0007
+#endif
+
+#ifndef S_IRUSR
+#define S_IRUSR 0400
+#define S_IWUSR 0200
+#define S_IXUSR 0100
+#define S_IRGRP 0040
+#define S_IWGRP 0020
+#define S_IXGRP 0010
+#define S_IROTH 0004
+#define S_IWOTH 0002
+#define S_IXOTH 0001
+#endif
+
+#define MODE_REG (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)
+#define MODE_DIR (MODE_REG | S_IXUSR | S_IXGRP | S_IXOTH)
+
+/* constants for lseek() */
+#ifndef SEEK_SET
+#define SEEK_SET 0
+#define SEEK_CUR 1
+#define SEEK_END 2
+#endif
+\f
+#ifndef DECL_GETLOGIN
+extern char * EXFUN (getlogin, (void));
+#endif
+
+#define DOS_abort abort
+#define DOS_access access
+#define DOS_alarm alarm
+#define DOS_chdir chdir
+#define DOS_chmod chmod
+#define DOS_close close
+#define DOS_ctime ctime
+#define DOS_dup dup
+#define DOS_free free
+#define DOS_fstat fstat
+#define DOS_getcwd getcwd
+#define DOS_getenv getenv
+#define DOS_getegid getegid
+#define DOS_geteuid geteuid
+#define DOS_getgrgid getgrgid
+#define DOS_gethostname gethostname
+#define DOS_getlogin getlogin
+#define DOS_getpid getpid
+#define DOS_getpwnam getpwnam
+#define DOS_getpwuid getpwuid
+#define DOS_ioctl ioctl
+#define DOS_link link
+#define DOS_localtime localtime
+#define DOS_lseek lseek
+#define DOS_malloc malloc
+#define DOS_mknod mknod
+#define DOS_mktime mktime
+#define DOS_pause pause
+#define DOS_pipe pipe
+#define DOS_read read
+#define DOS_realloc realloc
+#define DOS_signal signal
+#define DOS_sleep sleep
+#define DOS_stat stat
+#define DOS_system system
+#define DOS_time time
+#define DOS_unlink unlink
+#define DOS_write write
+#define DOS_wait wait
+
+#ifndef WINNT
+extern PTR EXFUN (malloc, (unsigned int size));
+extern PTR EXFUN (realloc, (PTR ptr, unsigned int size));
+#endif
+extern int EXFUN (gethostname, (char * name, unsigned int size));
+
+#ifdef HAVE_FCNTL
+#define DOS_fcntl fcntl
+#endif
+
+#ifdef HAVE_TRUNCATE
+#define DOS_ftruncate ftruncate
+#define DOS_truncate truncate
+#endif
+
+#ifdef HAVE_VFORK
+#define DOS_vfork vfork
+#else
+#define DOS_vfork fork
+#endif
+
+#ifdef HAVE_SYMBOLIC_LINKS
+#define DOS_lstat lstat
+#define DOS_readlink readlink
+#define DOS_symlink symlink
+#else
+#define DOS_lstat stat
+#endif
+\f
+extern void EXFUN (DOS_prim_check_errno, (enum syscall_names name));
+
+#define STD_VOID_SYSTEM_CALL(name, expression) \
+{ \
+ while ((expression) < 0) \
+ error_system_call (errno, (name)); \
+}
+
+#define STD_UINT_SYSTEM_CALL(name, result, expression) \
+{ \
+ while (((result) = (expression)) < 0) \
+ error_system_call (errno, (name)); \
+}
+
+#define STD_PTR_SYSTEM_CALL(name, result, expression) \
+{ \
+ while (((result) = (expression)) == 0) \
+ error_system_call (errno, (name)); \
+}
+\f
+#ifdef HAVE_GETTIMEOFDAY
+#define DOS_gettimeofday gettimeofday
+#endif
+#ifdef HAVE_ITIMER
+#define DOS_setitimer setitimer
+#endif
+#ifdef HAVE_RMDIR
+#define DOS_rmdir rmdir
+#endif
+#ifdef HAVE_TIMES
+#define DOS_times times
+#endif
+
+#ifdef HAVE_DUMB_OPEN
+extern int EXFUN (DOS_open, (CONST char * name, int oflag, mode_t mode));
+#else
+#define DOS_open open
+#endif
+
+#ifdef HAVE_GETCWD
+#define DOS_getcwd getcwd
+#else
+#define EMULATE_GETCWD
+#define HAVE_GETCWD
+extern char * EXFUN (DOS_getcwd, (char * buffer, size_t length));
+#endif
+
+#ifdef HAVE_MKDIR
+#define DOS_mkdir mkdir
+#else
+#define EMULATE_MKDIR
+#define HAVE_MKDIR
+extern int EXFUN (DOS_mkdir, (CONST char * name, mode_t mode));
+#endif
+
+#ifdef HAVE_RENAME
+#define DOS_rename rename
+#else
+#define DOS_rename dos_rename_file
+#endif
+
+#ifdef HAVE_WAITPID
+#define DOS_waitpid waitpid
+#else /* not HAVE_WAITPID */
+#ifdef HAVE_WAIT3
+#define EMULATE_WAITPID
+#define HAVE_WAITPID
+extern int EXFUN
+ (DOS_waitpid, (pid_t pid, wait_status_t * stat_loc, int options));
+#endif /* HAVE_WAIT3 */
+#endif /* HAVE_WAITPID */
+
+#ifndef WUNTRACED
+#define WUNTRACED 0
+#endif
+
+#ifdef HAVE_SELECT
+#define DOS_select select
+#endif /* HAVE_SELECT */
+
+#ifdef _NFILE
+#define DOS_SC_OPEN_MAX() _NFILE
+#else
+#define DOS_SC_OPEN_MAX() 16
+#endif
+
+/* Interrupts */
+
+#define int10h(in,out) int86 (0x10, in, out)
+#define intDPMI(in,out) int86 (0x31, in, out)
+#define intDPMIx(in,out,seg) int86x (0x31, in, out, seg)
+
+/* Doesn't really go anywhere */
+#define INTERRUPT_CHAIN_NEXT 0
+#define INTERRUPT_RETURN 1
+
+#endif /* SCM_MSDOS_H */
+
--- /dev/null
+;;; -*-Midas-*-
+;;;
+;;; $Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/ntasutl.asm,v 1.1 1993/02/10 22:39:46 adams Exp $
+;;;
+;;; Copyright (c) 1992 Massachusetts Institute of Technology
+;;;
+;;; This material was developed by the Scheme project at the
+;;; Massachusetts Institute of Technology, Department of
+;;; Electrical Engineering and Computer Science. Permission to
+;;; copy this software, to redistribute it, and to use it for any
+;;; purpose is granted, subject to the following restrictions and
+;;; understandings.
+;;;
+;;; 1. Any copy made of this software must include this copyright
+;;; notice in full.
+;;;
+;;; 2. Users of this software agree to make their best efforts (a)
+;;; to return to the MIT Scheme project any improvements or
+;;; extensions that they make, so that these may be included in
+;;; future releases; and (b) to inform MIT of noteworthy uses of
+;;; this software.
+;;;
+;;; 3. All materials developed as a consequence of the use of this
+;;; software shall duly acknowledge such use, in accordance with
+;;; the usual standards of acknowledging credit in academic
+;;; research.
+;;;
+;;; 4. MIT has made no warrantee or representation that the
+;;; operation of this software will be error-free, and MIT is
+;;; under no obligation to provide any services, by way of
+;;; maintenance, update, or otherwise.
+;;;
+;;; 5. In conjunction with products arising from the use of this
+;;; material, there shall be no use of the name of the
+;;; Massachusetts Institute of Technology nor of any adaptation
+;;; thereof in any advertising, promotional, or sales literature
+;;; without prior written consent from MIT in each case.
+;;;
+
+.386
+.model tiny
+ .code
+\f
+ public _getCS
+_getCS:
+ xor eax,eax ; clear eax
+ mov ax,cs ; copy code segment descriptor
+ ret
+
+;; getDS added by SRA
+;_getDS:
+; xor eax,eax ; clear eax
+; mov ax,ds ; copy code segment descriptor
+; ret
+
+ public _getSS
+_getSS:
+ xor eax,eax ; clear eax
+ mov ax,ss ; copy code segment descriptor
+ ret
+
+;; Frame on entry to farcpy
+
+;;24 size
+;;20 src_sel
+;;16 src_off
+;;12 dst_sel
+;;8 dst_off
+;;4 ret add
+;;0 previous ebp
+
+ public _farcpy
+_farcpy:
+ push ebp
+ mov ebp,esp
+ push ebx
+ push ds
+ push es
+
+ mov eax,12[ebp]
+ mov ds,ax ; dst sel
+ mov eax,20[ebp]
+ mov es,ax ; src sel
+ mov edx,8[ebp] ; dst off
+ mov ecx,16[ebp] ; src off
+ mov eax,24[ebp] ; count
+ jmp enter_loop
+
+farcpy_loop:
+ mov bl,es:[ecx]
+ mov ds:[edx],bl
+ inc ecx
+ inc edx
+
+enter_loop:
+ dec eax
+ jge farcpy_loop
+
+ pop es
+ pop ds
+ pop ebx
+ pop ebp
+ ret
+end
--- /dev/null
+/* -*-C-*-
+
+$Id: ntenv.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992-1993 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "nt.h"
+#include "osenv.h"
+#include <stdlib.h>
+
+#ifdef WINNT
+#include <string.h>
+#endif
+\f
+time_t
+DEFUN_VOID (OS_encoded_time)
+{
+ time_t t;
+ STD_UINT_SYSTEM_CALL (syscall_time, t, (DOS_time (0)));
+ return (t);
+}
+
+void
+DEFUN (OS_decode_time, (t, buffer), time_t t AND struct time_structure * buffer)
+{
+ struct tm * ts;
+ STD_PTR_SYSTEM_CALL (syscall_localtime, ts, (DOS_localtime (&t)));
+ (buffer -> year) = ((ts -> tm_year) + 1900);
+ (buffer -> month) = ((ts -> tm_mon) + 1);
+ (buffer -> day) = (ts -> tm_mday);
+ (buffer -> hour) = (ts -> tm_hour);
+ (buffer -> minute) = (ts -> tm_min);
+ (buffer -> second) = (ts -> tm_sec);
+ {
+ /* In localtime() encoding, 0 is Sunday; in ours, it's Monday. */
+ int wday = (ts -> tm_wday);
+ (buffer -> day_of_week) = ((wday == 0) ? 6 : (wday - 1));
+ }
+}
+
+time_t
+DEFUN (OS_encode_time ,(buffer), struct time_structure * buffer)
+{
+ time_t t;
+ struct tm ts_s, * ts;
+ ts = &ts_s;
+ (ts -> tm_year) = ((buffer -> year) - 1900);
+ (ts -> tm_mon) = ((buffer -> month) - 1);
+ (ts -> tm_mday) = (buffer -> day);
+ (ts -> tm_hour) = (buffer -> hour);
+ (ts -> tm_min) = (buffer -> minute);
+ (ts -> tm_sec) = (buffer -> second);
+ {
+ /* In localtime() encoding, 0 is Sunday; in ours, it's Monday. */
+ int wday = (buffer -> day_of_week);
+ (ts -> tm_wday) = ((wday == 6) ? 0 : (wday + 1));
+ }
+ STD_UINT_SYSTEM_CALL (syscall_mktime, t, (DOS_mktime (ts)));
+ return (t);
+}
+
+clock_t
+DEFUN_VOID (OS_process_clock)
+{
+ /* This must not signal an error in normal use. */
+ /* Return answer in milliseconds, was in 1/100th seconds */
+ return (clock()*((clock_t) (1000/CLOCKS_PER_SEC)));
+}
+
+clock_t
+DEFUN_VOID (OS_real_time_clock)
+{
+ return (clock()*((clock_t) (1000/CLOCKS_PER_SEC)));
+}
+\f
+/* Timer adjustments */
+#define PC_TIMER_TICKS_PER_SECOND (18.2)
+/* This should work out to about 55 */
+#define PC_MILLISECONDS_PER_TIMER_TICK \
+ ((long) ((1000.0/PC_TIMER_TICKS_PER_SECOND)+0.5))
+
+static unsigned long
+DEFUN (ms_to_ticks, (clocks), clock_t clocks)
+{ ldiv_t ticks;
+ unsigned long result;
+
+ ticks = ldiv((long) clocks, PC_MILLISECONDS_PER_TIMER_TICK);
+
+ result = ((ticks.rem >= (PC_MILLISECONDS_PER_TIMER_TICK/2)) ?
+ (ticks.quot + 1) : (ticks.quot));
+ return (result == 0) ? 1 : result;
+}
+
+
+extern volatile unsigned long scm_itimer_counter, scm_itimer_reload;
+
+void
+DEFUN (OS_process_timer_set, (first, interval),
+ clock_t first AND
+ clock_t interval)
+{ /* Convert granularity to 1/18.2 seconds */
+
+ scm_itimer_counter = ms_to_ticks(first);
+ scm_itimer_reload = ms_to_ticks(interval);
+
+ return;
+}
+
+void
+DEFUN_VOID (OS_process_timer_clear)
+{
+ scm_itimer_reload = scm_itimer_counter = 0;
+ return;
+}
+
+void
+DEFUN (OS_real_timer_set, (first, interval),
+ clock_t first AND
+ clock_t interval)
+{
+ OS_process_timer_set (first, interval);
+}
+
+void
+DEFUN_VOID (OS_real_timer_clear)
+{
+ OS_process_timer_clear();
+ return;
+}
+
+void
+DEFUN_VOID (DOS_initialize_environment)
+{
+ return;
+}
+\f
+static size_t current_dir_path_size = 0;
+static char * current_dir_path = 0;
+
+CONST char *
+DEFUN_VOID (OS_working_dir_pathname)
+{
+ if (current_dir_path) {
+ return (current_dir_path);
+ }
+ if (current_dir_path_size == 0)
+ {
+ current_dir_path = (DOS_malloc (1024));
+ if (current_dir_path == 0)
+ error_system_call (ENOMEM, syscall_malloc);
+ current_dir_path_size = 1024;
+ }
+ while (1)
+ {
+ if ((DOS_getcwd (current_dir_path, current_dir_path_size)) != 0)
+ { strlwr(current_dir_path);
+ return (current_dir_path);
+ }
+#ifdef ERANGE
+ if (errno != ERANGE)
+ error_system_call (errno, syscall_getcwd);
+#endif
+ current_dir_path_size *= 2;
+ {
+ char * new_current_dir_path =
+ (DOS_realloc (current_dir_path, current_dir_path_size));
+ if (new_current_dir_path == 0)
+ /* ANSI C requires `path' to be unchanged -- we may have to
+ discard it for systems that don't behave thus. */
+ error_system_call (ENOMEM, syscall_realloc);
+ current_dir_path = new_current_dir_path;
+ }
+ }
+}
+
+void
+DEFUN (OS_set_working_dir_pathname, (name), char * name)
+{
+ /*SRA*/
+ size_t name_size = strlen(name);
+ char *filename = name;
+
+ STD_VOID_SYSTEM_CALL (syscall_chdir, (SetCurrentDirectory (filename)));
+
+ while (1) {
+ if (name_size < current_dir_path_size) {
+ strcpy(current_dir_path, name);
+ return;
+ }
+ current_dir_path_size *= 2;
+ {
+ char * new_current_dir_path =
+ (DOS_realloc (current_dir_path, current_dir_path_size));
+ if (new_current_dir_path == 0)
+ error_system_call (ENOMEM, syscall_realloc);
+ current_dir_path = new_current_dir_path;
+ }
+ }
+}
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/ntfile.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "nt.h"
+#include "osfile.h"
+#include "ntio.h"
+
+extern void EXFUN (terminal_open, (Tchannel channel));
+\f
+static enum channel_type
+DEFUN (fd_channel_type, (fd), int fd)
+{
+ static int first_time = 1;
+ if (first_time) {
+ printf("\n;; fd_channel_type(fd) is broken.\n");
+ first_time = 0;
+ }
+ return channel_type_file;
+/* SRA:stat is fried on the NT Oct Beta
+ struct stat stat_buf;
+ if ((DOS_fstat (fd, (&stat_buf))) < 0){
+ return (channel_type_unknown);
+ {
+ mode_t type = ((stat_buf . st_mode) & S_IFMT);
+ return
+ ((type == S_IFREG) ? channel_type_file
+ : (type == S_IFCHR)
+ ? ((isatty (fd))
+ ? channel_type_terminal
+ : channel_type_character_device)
+#ifdef S_IFIFO
+ : (type == S_IFIFO) ? channel_type_fifo
+#endif
+#ifdef S_IFBLK
+ : (type == S_IFBLK) ? channel_type_block_device
+#endif
+ : (type == S_IFDIR) ? channel_type_directory
+ : channel_type_unknown);
+ }
+ */
+}
+
+Tchannel
+DEFUN (OS_open_fd, (fd), int fd)
+{
+ enum channel_type type = (fd_channel_type (fd));
+ Tchannel channel;
+ MAKE_CHANNEL (fd, type, channel =);
+
+ /* Like Unix, all terminals initialize to cooked mode. */
+ if (type == channel_type_terminal) CHANNEL_COOKED(channel) = 1;
+
+ return (channel);
+}
+
+static Tchannel
+DEFUN (open_file, (filename, oflag), CONST char * filename AND int oflag)
+{
+ int fd;
+ STD_UINT_SYSTEM_CALL
+ (syscall_open, fd, (DOS_open (filename, oflag, MODE_REG)));
+ return (OS_open_fd (fd));
+}
+
+#define DEFUN_OPEN_FILE(name, oflag) \
+Tchannel \
+DEFUN (name, (filename), CONST char * filename) \
+{ \
+ return (open_file)(filename, oflag); \
+}
+
+DEFUN_OPEN_FILE (OS_open_input_file, O_RDONLY | _O_BINARY)
+DEFUN_OPEN_FILE (OS_open_output_file, (O_WRONLY | O_CREAT | O_TRUNC | _O_BINARY))
+DEFUN_OPEN_FILE (OS_open_io_file, (O_RDWR | O_CREAT))
+
+#ifdef HAVE_APPEND
+
+DEFUN_OPEN_FILE (OS_open_append_file, (O_WRONLY | O_CREAT | O_APPEND | _O_BINARY))
+
+#else
+
+Tchannel
+DEFUN (OS_open_append_file, (filename), CONST char * filename)
+{
+ error_unimplemented_primitive ();
+ return (0);
+}
+
+#endif
+\f
+static Tchannel
+DEFUN (make_load_channel, (fd), int fd)
+{
+ enum channel_type type = (fd_channel_type (fd));
+/*SRA: fd_channel_type doesnt work properly
+ if ((type == channel_type_terminal)
+ || (type == channel_type_directory)
+ || (type == channel_type_unknown))
+ return (NO_CHANNEL);
+*/
+ if ((type == channel_type_terminal)
+ || (type == channel_type_directory)
+ )
+ return (NO_CHANNEL);
+ MAKE_CHANNEL (fd, type, return);
+}
+
+Tchannel
+DEFUN (OS_open_load_file, (filename), CONST char * filename)
+{
+ while (1)
+ {
+ /*SRA:*/
+ int fd = (DOS_open (filename, O_RDONLY|_O_BINARY, MODE_REG));
+ if (fd >= 0)
+ return (make_load_channel (fd));
+ if (errno != EINTR)
+ return (NO_CHANNEL);
+ }
+}
+
+Tchannel
+DEFUN (OS_open_dump_file, (filename), CONST char * filename)
+{
+ while (1)
+ {
+ /*SRA: +binary*/
+ int fd = (DOS_open (filename, (_O_BINARY | O_WRONLY | O_CREAT | O_TRUNC), MODE_REG));
+ if (fd >= 0)
+ return (make_load_channel (fd));
+ if (errno != EINTR)
+ return (NO_CHANNEL);
+ }
+}
+
+off_t
+DEFUN (OS_file_length, (channel), Tchannel channel)
+{
+ struct stat stat_buf;
+ STD_VOID_SYSTEM_CALL
+ (syscall_fstat, (DOS_fstat ((CHANNEL_DESCRIPTOR (channel)), (&stat_buf))));
+ return (stat_buf . st_size);
+}
+
+off_t
+DEFUN (OS_file_position, (channel), Tchannel channel)
+{
+ off_t result;
+ STD_UINT_SYSTEM_CALL
+ (syscall_lseek,
+ result,
+ (DOS_lseek ((CHANNEL_DESCRIPTOR (channel)), 0L, SEEK_CUR)));
+ return (result);
+}
+
+void
+DEFUN (OS_file_set_position, (channel, position),
+ Tchannel channel AND
+ off_t position)
+{
+ off_t result;
+ STD_UINT_SYSTEM_CALL
+ (syscall_lseek,
+ result,
+ (DOS_lseek ((CHANNEL_DESCRIPTOR (channel)), position, SEEK_SET)));
+ if (result != position)
+ error_external_return ();
+}
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/ntfs.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "nt.h"
+#include "osfs.h"
+#include <string.h>
+\f
+int
+DEFUN (DOS_read_file_status, (name, s),
+ CONST char * name AND
+ struct stat * s)
+{ char filename[128];
+
+ dos_pathname_as_filename(name, filename);
+
+ while ((stat (filename, s)) < 0)
+ {
+ if (errno == EINTR)
+ continue;
+ if ((errno == ENOENT) || (errno == ENOTDIR))
+ return (0);
+ error_system_call (errno, syscall_lstat);
+ }
+ return (1);
+}
+
+enum file_existence
+DEFUN (OS_file_existence_test, (name), char * name)
+{
+ struct stat s;
+ char filename[128];
+
+ dos_pathname_as_filename(name, filename);
+
+ return
+ (((DOS_stat (filename, (&s))) < 0)
+ ? file_doesnt_exist : file_does_exist);
+}
+
+int
+DEFUN (OS_file_access, (name, mode), CONST char * name AND unsigned int mode)
+{
+ char filename[128];
+
+ dos_pathname_as_filename(name, filename);
+ return ((DOS_access (filename, mode)) == 0);
+}
+
+int
+DEFUN (OS_file_directory_p, (name), char * name)
+{
+ struct stat s;
+ char filename[128];
+
+ dos_pathname_as_filename(name, filename);
+ return (((DOS_stat (filename, (&s))) == 0) &&
+ (((s . st_mode) & S_IFMT) == S_IFDIR));
+}
+
+CONST char *
+DEFUN (OS_file_soft_link_p, (name), CONST char * name)
+{
+ return (0);
+}
+
+void
+DEFUN (OS_file_remove, (name), CONST char * name)
+{
+ STD_VOID_SYSTEM_CALL (syscall_unlink, (DOS_unlink (name)));
+}
+
+void
+DEFUN (OS_file_remove_link, (name), CONST char * name)
+{
+ struct stat s;
+ if ( (DOS_stat (name, (&s)) == 0) &&
+ (((s . st_mode) & S_IFMT) == S_IFREG) )
+ DOS_unlink (name);
+ return;
+}
+
+void
+DEFUN (OS_file_link_hard, (from_name, to_name),
+ CONST char * from_name AND
+ CONST char * to_name)
+{
+ error_unimplemented_primitive ();
+}
+
+void
+DEFUN (OS_file_link_soft, (from_name, to_name),
+ CONST char * from_name AND
+ CONST char * to_name)
+{
+ error_unimplemented_primitive ();
+}
+\f
+void
+DEFUN (OS_file_rename, (from_name, to_name),
+ CONST char * from_name AND
+ CONST char * to_name)
+{
+ if ((rename (from_name, to_name)) != 0)
+ error_system_call (errno, syscall_rename);
+}
+
+void
+DEFUN (OS_directory_make, (name), CONST char * name)
+{
+ STD_VOID_SYSTEM_CALL (syscall_mkdir, (DOS_mkdir (name)));
+}
+
+void
+DEFUN (OS_directory_delete, (name), CONST char * name)
+{
+ STD_VOID_SYSTEM_CALL (syscall_mkdir, (RemoveDirectory(name)));
+}
+
+\f
+/* This is such that directory open does not return the first file */
+#define DIR_UNALLOCATED (-1L)
+typedef struct DIR_struct
+{ struct _finddata_t entry;
+ long handle; /* may be DIR_UNALLOCATED */
+ char pathname[256];
+} DIR;
+
+#define Get_Directory_Entry_Name(entry, pathname) \
+ (strcpy(pathname, (entry).name), strlwr(pathname))
+
+int OS_directory_index;
+
+static DIR ** directory_pointers;
+static unsigned int n_directory_pointers;
+
+void
+DEFUN_VOID (DOS_initialize_directory_reader)
+{
+ directory_pointers = 0;
+ n_directory_pointers = 0;
+ OS_directory_index = (-1);
+}
+
+static unsigned int
+DEFUN (allocate_directory_pointer, (pointer), DIR * pointer)
+{
+ if (n_directory_pointers == 0)
+ {
+ DIR ** pointers = ((DIR **) (DOS_malloc ((sizeof (DIR *)) * 4)));
+ if (pointers == 0)
+ error_system_call (ENOMEM, syscall_malloc);
+ directory_pointers = pointers;
+ n_directory_pointers = 4;
+ {
+ DIR ** scan = directory_pointers;
+ DIR ** end = (scan + n_directory_pointers);
+ (*scan++) = pointer;
+ while (scan < end)
+ (*scan++) = 0;
+ }
+ return (0);
+ }
+ {
+ DIR ** scan = directory_pointers;
+ DIR ** end = (scan + n_directory_pointers);
+ while (scan < end)
+ if ((*scan++) == 0)
+ {
+ (*--scan) = pointer;
+ return (scan - directory_pointers);
+ }
+ }
+ {
+ unsigned int result = n_directory_pointers;
+ unsigned int n_pointers = (2 * n_directory_pointers);
+ DIR ** pointers =
+ ((DIR **)
+ (DOS_realloc (((PTR) directory_pointers),
+ ((sizeof (DIR *)) * n_pointers))));
+ if (pointers == 0)
+ error_system_call (ENOMEM, syscall_realloc);
+ {
+ DIR ** scan = (pointers + result);
+ DIR ** end = (pointers + n_pointers);
+ (*scan++) = pointer;
+ while (scan < end)
+ (*scan++) = 0;
+ }
+ directory_pointers = pointers;
+ n_directory_pointers = n_pointers;
+ return (result);
+ }
+}
+
+#define REFERENCE_DIRECTORY(index) (directory_pointers[(index)])
+#define DEALLOCATE_DIRECTORY(index) ((directory_pointers[(index)]) = 0)
+
+int
+DEFUN (OS_directory_valid_p, (index), long index)
+{
+ return
+ ((0 <= index)
+ && (index < n_directory_pointers)
+ && ((REFERENCE_DIRECTORY (index)) != 0));
+}
+\f
+unsigned int
+DEFUN (OS_directory_open, (name), CONST char * name)
+{
+ char filename[128], searchname[128];
+ DIR * dir = malloc(sizeof(DIR));
+
+ if (dir == 0)
+ error_system_call (ENOMEM, syscall_malloc);
+
+ if (dos_pathname_as_filename(name, filename))
+ sprintf(searchname, "%s*.*", filename);
+ else
+ sprintf(searchname, "%s\\*.*", filename);
+
+ dir->handle = _findfirst(searchname, &(dir->entry));
+ if (dir->handle == DIR_UNALLOCATED || (dir->entry.attrib & _A_SUBDIR)== 0)
+ error_system_call (errno, syscall_opendir);
+
+ return (allocate_directory_pointer (dir));
+}
+
+CONST char *
+DEFUN (OS_directory_read, (index), unsigned int index)
+{ DIR * dir = REFERENCE_DIRECTORY (index);
+
+ if (dir == 0 || dir->handle==DIR_UNALLOCATED)
+ return 0;
+
+ Get_Directory_Entry_Name(dir->entry, dir->pathname);
+ if ( _findnext(dir->handle, &(dir->entry))) {
+ dir->handle = DIR_UNALLOCATED;
+ }
+ return (dir -> pathname);
+}
+
+CONST char *
+DEFUN (OS_directory_read_matching, (index, prefix),
+ unsigned int index AND
+ CONST char * prefix)
+{
+ error_unimplemented_primitive ();
+ return (0);
+}
+
+void
+DEFUN (OS_directory_close, (index), unsigned int index)
+{ DIR * dir = REFERENCE_DIRECTORY (index);
+
+ if (dir) {
+ if (dir->handle != DIR_UNALLOCATED)
+ _findclose(dir->handle);
+ free(dir);
+ }
+ DEALLOCATE_DIRECTORY (index);
+}
+
+
--- /dev/null
+/* -*-C-*-
+
+$Id: ntio.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "nt.h"
+#include "ntio.h"
+#include "osterm.h"
+
+#ifndef fileno
+#define fileno(fp) ((fp)->_file)
+#endif
+\f
+size_t OS_channel_table_size;
+struct channel * channel_table;
+
+unsigned int OS_channels_registered;
+
+static void
+DEFUN_VOID (DOS_channel_close_all)
+{
+ Tchannel channel;
+ for (channel = 0; (channel < OS_channel_table_size); channel += 1)
+ if (CHANNEL_OPEN_P (channel))
+ OS_channel_close_noerror (channel);
+ return;
+}
+
+void
+DEFUN_VOID (DOS_initialize_channels)
+{
+ printf(">> DOS_initialize_channels\n");
+ OS_channel_table_size = (DOS_SC_OPEN_MAX ());
+ channel_table =
+ (DOS_malloc (OS_channel_table_size * (sizeof (struct channel))));
+ if (channel_table == 0)
+ {
+ fprintf (stderr, "\nUnable to allocate channel table.\n");
+ fflush (stderr);
+ termination_init_error ();
+ }
+ {
+ Tchannel channel;
+ for (channel = 0; (channel < OS_channel_table_size); channel += 1)
+ MARK_CHANNEL_CLOSED (channel);
+ }
+ add_reload_cleanup (DOS_channel_close_all);
+ OS_channels_registered = 0;
+ return;
+}
+
+void
+DEFUN_VOID (DOS_reset_channels)
+{
+ DOS_free (channel_table);
+ channel_table = 0;
+ OS_channel_table_size = 0;
+ return;
+}
+
+Tchannel
+DEFUN_VOID (channel_allocate)
+{
+ Tchannel channel = 0;
+ while (1)
+ {
+ if (channel == OS_channel_table_size)
+ error_out_of_channels ();
+ if (CHANNEL_CLOSED_P (channel))
+ return (channel);
+ channel += 1;
+ }
+}
+\f
+int
+DEFUN (OS_channel_open_p, (channel), Tchannel channel)
+{
+ return (CHANNEL_OPEN_P (channel));
+}
+
+void
+DEFUN (OS_channel_close, (channel), Tchannel channel)
+{
+ if (! (CHANNEL_INTERNAL (channel)))
+ {
+ if (CHANNEL_REGISTERED (channel))
+ OS_channel_unregister (channel);
+ STD_VOID_SYSTEM_CALL
+ (syscall_close, (DOS_close (CHANNEL_DESCRIPTOR (channel))));
+ MARK_CHANNEL_CLOSED (channel);
+ }
+ return;
+}
+
+void
+DEFUN (OS_channel_close_noerror, (channel), Tchannel channel)
+{
+ if (! (CHANNEL_INTERNAL (channel)))
+ {
+ if (CHANNEL_REGISTERED (channel))
+ OS_channel_unregister (channel);
+ DOS_close (CHANNEL_DESCRIPTOR (channel));
+ MARK_CHANNEL_CLOSED (channel);
+ }
+ return;
+}
+
+static void
+DEFUN (channel_close_on_abort_1, (cp), PTR cp)
+{
+ OS_channel_close (* ((Tchannel *) cp));
+ return;
+}
+
+void
+DEFUN (OS_channel_close_on_abort, (channel), Tchannel channel)
+{
+ Tchannel * cp = (dstack_alloc (sizeof (Tchannel)));
+ (*cp) = (channel);
+ transaction_record_action (tat_abort, channel_close_on_abort_1, cp);
+ return;
+}
+
+enum channel_type
+DEFUN (OS_channel_type, (channel), Tchannel channel)
+{
+ return (CHANNEL_TYPE (channel));
+}
+\f
+void
+DEFUN (OS_terminal_flush_input, (channel), Tchannel channel)
+{ extern void EXFUN (flush_conio_buffers, (void));
+
+ if ((CHANNEL_DESCRIPTOR (channel)) == (fileno (stdin)))
+ flush_conio_buffers();
+ return;
+}
+
+void
+DEFUN (OS_terminal_flush_output, (channel), Tchannel channel)
+{
+ return;
+}
+
+void
+DEFUN (OS_terminal_drain_output, (channel), Tchannel channel)
+{
+ return;
+}
+
+extern int EXFUN (dos_read, (int, PTR, size_t, int, int, int));
+
+int
+DEFUN (dos_read, (fd, buffer, nbytes, buffered_p, blocking_p, intrpt_p),
+ int fd AND PTR buffer AND size_t nbytes
+ AND int buffered_p AND int blocking_p AND int intrpt_p)
+{
+ if (nbytes == 0)
+ return (0);
+ else if (fd == (fileno (stdin)))
+ return (console_read (buffer, nbytes, buffered_p, blocking_p, intrpt_p));
+ else
+ return (DOS_read (fd, buffer, nbytes));
+}
+
+int
+DEFUN (dos_channel_read, (channel, buffer, nbytes),
+ Tchannel channel AND PTR buffer AND size_t nbytes)
+{
+ if (nbytes == 0)
+ return 0;
+ else if ((CHANNEL_DESCRIPTOR (channel)) == (fileno (stdin))) {
+ /* fake the console being a nonblocking channel that has nothing after
+ each read */
+ static int nonblock = 1;
+ nonblock = !nonblock;
+ if (nonblock) {
+ errno = ERRNO_NONBLOCK;
+ return -1;
+ }
+ return (DOS_read ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes));
+ /*return (console_read (buffer, nbytes,
+ (CHANNEL_BUFFERED (channel)),
+ (CHANNEL_BLOCKING_P (channel)),
+ 1));*/
+ }
+ else
+ return (DOS_read ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes));
+}
+
+long
+DEFUN (OS_channel_read, (channel, buffer, nbytes),
+ Tchannel channel AND PTR buffer AND size_t nbytes)
+{
+ while (1)
+ {
+ long scr = (dos_channel_read (channel, buffer, nbytes));
+ if (scr < 0)
+ {
+ if (errno == ERRNO_NONBLOCK)
+ return -1;
+ DOS_prim_check_errno (syscall_read);
+ continue;
+ }
+ else if (scr > nbytes)
+ error_external_return ();
+ else {
+ return (scr);
+ }
+ }
+}
+\f
+static int
+DEFUN (dos_write, (fd, buffer, nbytes),
+ int fd AND CONST unsigned char * buffer AND size_t nbytes)
+{
+ return ((fd == (fileno (stdout)))
+ ? (dos_console_write (buffer, nbytes))
+
+ : (DOS_write (fd, buffer, nbytes)));
+}
+
+#define Syscall_Write(fd, buffer, size, so_far) \
+do \
+{ size_t _size = (size); \
+ int _written; \
+ _written = dos_write ((fd), (buffer), (_size)); \
+ if (_size != _written) \
+ return ((_written < 0) ? -1 : (so_far) + _written); \
+} while (0)
+
+long
+DEFUN (text_write, (fd, buffer, nbytes),
+ int fd AND CONST unsigned char * buffer AND size_t nbytes)
+{ /* Map LF to CR/LF */
+ static CONST unsigned char crlf[] = {CARRIAGE_RETURN, LINEFEED};
+ CONST unsigned char *start;
+ size_t i;
+
+ for (i = 0, start = buffer; i < nbytes; start = &buffer[i])
+ { size_t len;
+
+ while ((i < nbytes) && (buffer[i] != LINEFEED)) i++;
+ len = (&buffer[i] - start);
+
+ Syscall_Write (fd, start, len, (i - len));
+
+ if ((i < nbytes) && (buffer[i] == LINEFEED))
+ { /* We are sitting on a linefeed. Write out CRLF */
+ /* This backs out incorrectly if only CR is written out */
+ Syscall_Write (fd, crlf, (sizeof (crlf)), i);
+ i = i + 1; /* Skip over special character */
+ }
+ }
+ return nbytes;
+}
+
+#undef Syscall_Write
+
+long
+DEFUN (OS_channel_write, (channel, buffer, nbytes),
+ Tchannel channel AND CONST PTR buffer AND size_t nbytes)
+{
+ if (nbytes == 0)
+ return (0);
+
+ while (1)
+ {
+ int fd, scr;
+
+ fd = CHANNEL_DESCRIPTOR(channel);
+ scr = ((CHANNEL_COOKED (channel))
+ ? (text_write (fd, buffer, nbytes))
+ : (dos_write (fd, buffer, nbytes)));
+
+ if (scr < 0)
+ {
+ DOS_prim_check_errno (syscall_write);
+ continue;
+ }
+
+ if (scr > nbytes)
+ error_external_return ();
+ return scr;
+ }
+}
+\f
+size_t
+DEFUN (OS_channel_read_load_file, (channel, buffer, nbytes),
+ Tchannel channel AND PTR buffer AND size_t nbytes)
+{
+ int scr;
+ scr = (DOS_read ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes));
+
+ return ((scr < 0) ? 0 : scr);
+}
+
+size_t
+DEFUN (OS_channel_write_dump_file, (channel, buffer, nbytes),
+ Tchannel channel AND CONST PTR buffer AND size_t nbytes)
+{
+ int scr = (DOS_write ((CHANNEL_DESCRIPTOR (channel)), buffer, nbytes));
+ return ((scr < 0) ? 0 : scr);
+}
+
+void
+DEFUN (OS_channel_write_string, (channel, string),
+ Tchannel channel AND
+ CONST char * string)
+{
+ unsigned long length = (strlen (string));
+ if ((OS_channel_write (channel, string, length)) != length)
+ error_external_return ();
+}
+
+void
+DEFUN (OS_make_pipe, (readerp, writerp),
+ Tchannel * readerp AND
+ Tchannel * writerp)
+{
+ return;
+}
+\f
+int
+DEFUN (OS_channel_nonblocking_p, (channel), Tchannel channel)
+{
+ return (CHANNEL_NONBLOCKING (channel));
+}
+
+void
+DEFUN (OS_channel_nonblocking, (channel), Tchannel channel)
+{
+ (CHANNEL_NONBLOCKING (channel)) = 1;
+ return;
+}
+
+void
+DEFUN (OS_channel_blocking, (channel), Tchannel channel)
+{
+ (CHANNEL_NONBLOCKING (channel)) = 0;
+}
+
+int
+DEFUN (OS_terminal_buffered_p, (channel), Tchannel channel)
+{
+ return (CHANNEL_BUFFERED(channel));
+}
+
+void
+DEFUN (OS_terminal_buffered, (channel), Tchannel channel)
+{
+ CHANNEL_BUFFERED(channel) = 1;
+}
+
+void
+DEFUN (OS_terminal_nonbuffered, (channel), Tchannel channel)
+{
+ CHANNEL_BUFFERED(channel) = 0;
+}
+
+int
+DEFUN (OS_terminal_cooked_output_p, (channel), Tchannel channel)
+{
+ return (CHANNEL_COOKED(channel));
+}
+
+void
+DEFUN (OS_terminal_cooked_output, (channel), Tchannel channel)
+{
+ CHANNEL_COOKED(channel) = 1;
+}
+
+void
+DEFUN (OS_terminal_raw_output, (channel), Tchannel channel)
+{
+ CHANNEL_COOKED(channel) = 0;
+}
+\f
+unsigned int
+DEFUN (arg_baud_index, (argument), unsigned int argument)
+{
+ return (arg_index_integer (argument, 1));
+}
+
+unsigned long
+DEFUN (OS_terminal_get_ispeed, (channel), Tchannel channel)
+{
+ return (0);
+}
+
+unsigned long
+DEFUN (OS_terminal_get_ospeed, (channel), Tchannel channel)
+{
+ return (0);
+}
+
+unsigned int
+DEFUN (OS_baud_index_to_rate, (index), unsigned int index)
+{
+ return (9600);
+}
+
+int
+DEFUN (OS_baud_rate_to_index, (rate), unsigned int rate)
+{
+ return ((rate == 9600) ? 0 : -1);
+}
+
+unsigned int
+DEFUN_VOID (OS_terminal_state_size)
+{
+ return (3);
+}
+
+void
+DEFUN (OS_terminal_get_state, (channel, state_ptr),
+ Tchannel channel AND PTR state_ptr)
+{
+ unsigned char *statep = (unsigned char *) state_ptr;
+
+ *statep++ = CHANNEL_NONBLOCKING(channel);
+ *statep++ = CHANNEL_BUFFERED(channel);
+ *statep = CHANNEL_COOKED(channel);
+
+ return;
+}
+
+void
+DEFUN (OS_terminal_set_state, (channel, state_ptr),
+ Tchannel channel AND PTR state_ptr)
+{
+ unsigned char *statep = (unsigned char *) state_ptr;
+
+ CHANNEL_NONBLOCKING(channel) = *statep++;
+ CHANNEL_BUFFERED(channel) = *statep++;
+ CHANNEL_COOKED(channel) = *statep;
+
+ return;
+}
+
+#ifndef FALSE
+# define FALSE 0
+#endif
+
+int
+DEFUN_VOID (OS_job_control_p)
+{
+ return (FALSE);
+}
+
+int
+DEFUN_VOID (OS_have_ptys_p)
+{
+ return (FALSE);
+}
+\f
+int
+DEFUN (OS_channel_registered_p, (channel), Tchannel channel)
+{
+ return (CHANNEL_REGISTERED (channel));
+}
+
+void
+DEFUN (OS_channel_register, (channel), Tchannel channel)
+{
+ error_unimplemented_primitive ();
+}
+
+void
+DEFUN (OS_channel_unregister, (channel), Tchannel channel)
+{
+ if (CHANNEL_REGISTERED (channel))
+ {
+ OS_channels_registered -= 1;
+ (CHANNEL_REGISTERED (channel)) = 0;
+ }
+}
+
+
+/* No SELECT in DOS */
+long
+DEFUN (OS_channel_select_then_read, (channel, buffer, nbytes),
+ Tchannel channel AND
+ PTR buffer AND
+ size_t nbytes)
+{ /* We can't really select amongst channels in DOS, but still need
+ to keep track of whether the read was interrupted.
+ */
+ while (1)
+ {
+ long scr = (dos_channel_read (channel, buffer, nbytes));
+
+ if (scr < 0)
+ {
+ if (errno == ERRNO_NONBLOCK)
+ return -1;
+ else if (errno == EINTR)
+ return -4;
+ else
+ {
+ DOS_prim_check_errno (syscall_read);
+ continue;
+ }
+ }
+ else if (scr > nbytes)
+ error_external_return ();
+ else
+ return (scr);
+ }
+}
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/ntio.h,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_UXIO_H
+#define SCM_UXIO_H
+
+#include "osio.h"
+
+struct channel
+{
+ int descriptor;
+ enum channel_type type;
+ unsigned int internal : 1;
+ unsigned int nonblocking : 1;
+ unsigned int registered : 1;
+ unsigned int buffered : 1;
+ unsigned int cooked : 1;
+};
+
+#define MARK_CHANNEL_CLOSED(channel) ((CHANNEL_DESCRIPTOR (channel)) = (-1))
+#define CHANNEL_CLOSED_P(channel) ((CHANNEL_DESCRIPTOR (channel)) < 0)
+#define CHANNEL_OPEN_P(channel) ((CHANNEL_DESCRIPTOR (channel)) >= 0)
+#define CHANNEL_DESCRIPTOR(channel) ((channel_table [(channel)]) . descriptor)
+#define CHANNEL_TYPE(channel) ((channel_table [(channel)]) . type)
+#define CHANNEL_INTERNAL(channel) ((channel_table [(channel)]) . internal)
+#define CHANNEL_NONBLOCKING(channel) \
+ ((channel_table [(channel)]) . nonblocking)
+#define CHANNEL_BLOCKING_P(channel) \
+ (!CHANNEL_NONBLOCKING(channel))
+#define CHANNEL_REGISTERED(channel) ((channel_table [(channel)]) . registered)
+#define CHANNEL_BUFFERED(channel) ((channel_table [(channel)]) . buffered)
+#define CHANNEL_COOKED(channel) ((channel_table [(channel)]) . cooked)
+
+#define MAKE_CHANNEL(descriptor, type, receiver) \
+{ \
+ Tchannel MAKE_CHANNEL_temp = (channel_allocate ()); \
+ (CHANNEL_DESCRIPTOR (MAKE_CHANNEL_temp)) = (descriptor); \
+ (CHANNEL_TYPE (MAKE_CHANNEL_temp)) = (type); \
+ (CHANNEL_INTERNAL (MAKE_CHANNEL_temp)) = 0; \
+ (CHANNEL_NONBLOCKING (MAKE_CHANNEL_temp)) = 0; \
+ (CHANNEL_REGISTERED (MAKE_CHANNEL_temp)) = 0; \
+ (CHANNEL_BUFFERED (MAKE_CHANNEL_temp)) = 1; \
+ (CHANNEL_COOKED (MAKE_CHANNEL_temp)) = 0; \
+ receiver (MAKE_CHANNEL_temp); \
+}
+
+extern struct channel * channel_table;
+extern Tchannel EXFUN (channel_allocate, (void));
+
+#define BACKSPACE '\b'
+#define SPACE ' '
+#define CARRIAGE_RETURN '\r'
+#define LINEFEED '\n'
+#define CNTRL_Z '\032'
+#define DELETE '\177'
+
+#endif /* SCM_UXIO_H */
+\1a
\ No newline at end of file
--- /dev/null
+/* -*-C-*-
+
+$Id: ntsig.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "scheme.h"
+#include "nt.h"
+#include <signal.h>
+/*#include <int.h> SRA*/
+#include "ossig.h"
+#include "osctty.h"
+#include "ostty.h"
+#include "critsec.h"
+/*#include <bios.h> SRA*/
+#include "ntsys.h"
+#include "ntexcp.h"
+#include "ntkbd.h"
+#ifdef USE_ZORTECH_CERROR
+#include <cerror.h>
+#endif
+
+#ifndef fileno
+#define fileno(fp) ((fp)->_file)
+#endif
+
+cc_t EXFUN (DOS_interactive_interrupt_handler, (void));
+\f
+/* 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);
+}
+
+#define INSTALL_HANDLER DOS_signal
+#define NEED_HANDLER_TRANSACTION
+
+#define ENTER_HANDLER(signo)
+#define ABORT_HANDLER DOS_signal
+#define EXIT_HANDLER DOS_signal
+
+#endif /* UNUSED */
+
+/* These could be implemented, at least under DPMI by examining
+ and setting the virtual interrupt state.
+ */
+
+void
+DEFUN_VOID (preserve_signal_mask)
+{
+ return;
+}
+
+void
+DEFUN_VOID (block_signals)
+{
+ return;
+}
+
+void
+DEFUN_VOID (unblock_signals)
+{
+ return;
+}
+\f
+#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)
+ {
+ fprintf (stderr, "\nUnable to grow signal definitions table.\n");
+ fflush (stderr);
+ 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);
+}
+\f
+#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)
+ {
+ fprintf (stderr, "\nUnable to allocate signal definitions table.\n");
+ fflush (stderr);
+ 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 ();
+}
+\f
+/* 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));
+}
+#endif /* UNUSED */
+\f
+#define CONTROL_B_INTERRUPT_CHAR 'B'
+#define CONTROL_G_INTERRUPT_CHAR 'G'
+#define CONTROL_U_INTERRUPT_CHAR 'U'
+#define CONTROL_X_INTERRUPT_CHAR 'X'
+#define INTERACTIVE_INTERRUPT_CHAR '!'
+#define TERMINATE_INTERRUPT_CHAR '@'
+#define NO_INTERRUPT_CHAR '0'
+
+#ifdef UNUSED
+static void
+DEFUN (echo_keyboard_interrupt, (c, dc), cc_t c AND cc_t dc)
+{
+ c &= 0177;
+ if (c == ALERT_CHAR)
+ putc (c, stdout);
+ else if (c < '\040')
+ {
+ putc ('^', stdout);
+ putc ((c + '@'), stdout);
+ }
+ else if (c == '\177')
+ fputs ("^?", stdout);
+ else
+ putc (c, stdout);
+ fflush (stdout);
+}
+
+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);
+ })
+
+#endif /* UNUSED */
+
+/* Keyboard interrupt */
+
+#define KB_INT_TABLE_SIZE ((256) + 1)
+
+#define CONTROL_BREAK '\0' /* A lie. */
+#define CONTROL_B '\002'
+#define CONTROL_C '\003'
+#define CONTROL_G '\007'
+#define CONTROL_U '\025'
+#define CONTROL_X '\030'
+
+#define CONTROL_B_ENABLE (0x1)
+#define CONTROL_G_ENABLE (0x2)
+#define CONTROL_U_ENABLE (0x4)
+#define CONTROL_X_ENABLE (0x8)
+#define INTERACTIVE_INTERRUPT_ENABLE (0x10)
+#define TERMINATE_INTERRUPT_ENABLE (0x20)
+
+/* This is a table and also a null terminated string. */
+unsigned char keyboard_interrupt_table[KB_INT_TABLE_SIZE];
+static unsigned char keyboard_interrupt_enables;
+
+void
+DEFUN (OS_ctty_get_interrupt_enables, (mask), Tinterrupt_enables * mask)
+{
+ *mask = ((Tinterrupt_enables) keyboard_interrupt_enables);
+ return;
+}
+
+void
+DEFUN (OS_ctty_set_interrupt_enables, (mask), Tinterrupt_enables * mask)
+{
+ /* Kludge: ctl-break always enabled. */
+ keyboard_interrupt_enables = (((unsigned char) (*mask))
+ | TERMINATE_INTERRUPT_ENABLE);
+ return;
+}
+\f
+/* This is a temporary kludge. */
+
+#define NUM_INT_CHANNELS 6
+static cc_t int_chars[NUM_INT_CHANNELS];
+static cc_t int_handlers[NUM_INT_CHANNELS];
+
+static void
+DEFUN_VOID (update_interrupt_characters)
+{
+ int i;
+
+ for (i = 0; i < KB_INT_TABLE_SIZE; i++)
+ keyboard_interrupt_table[i] = NO_INTERRUPT_CHAR;
+
+ for (i = 0; i < NUM_INT_CHANNELS; i++)
+ {
+ unsigned char handler;
+
+ switch (int_handlers[i])
+ {
+ case interrupt_handler_control_b:
+ handler = CONTROL_B_INTERRUPT_CHAR;
+ break;
+
+ case interrupt_handler_control_g:
+ handler = CONTROL_G_INTERRUPT_CHAR;
+ break;
+
+ case interrupt_handler_control_u:
+ handler = CONTROL_U_INTERRUPT_CHAR;
+ break;
+
+ case interrupt_handler_control_x:
+ handler = CONTROL_X_INTERRUPT_CHAR;
+ break;
+
+ case interrupt_handler_interactive:
+ handler = INTERACTIVE_INTERRUPT_CHAR;
+ break;
+
+ case interrupt_handler_terminate:
+ handler = TERMINATE_INTERRUPT_CHAR;
+ break;
+
+ default:
+ handler = NO_INTERRUPT_CHAR;
+ break;
+ }
+ keyboard_interrupt_table[(int) (int_chars[i])] = handler;
+ }
+ return;
+}
+\f
+unsigned int
+DEFUN_VOID (OS_ctty_num_int_chars)
+{
+ return (NUM_INT_CHANNELS);
+}
+
+cc_t *
+DEFUN_VOID (OS_ctty_get_int_chars)
+{
+ return (&int_chars[0]);
+}
+
+void
+DEFUN (OS_ctty_set_int_chars, (new_int_chars), cc_t * new_int_chars)
+{
+ int i;
+
+ for (i = 0; i < NUM_INT_CHANNELS; i++)
+ int_chars[i] = new_int_chars[i];
+ update_interrupt_characters ();
+ return;
+}
+
+cc_t *
+DEFUN_VOID (OS_ctty_get_int_char_handlers)
+{
+ return (&int_handlers[0]);
+}
+
+void
+DEFUN (OS_ctty_set_int_char_handlers, (new_int_handlers),
+ cc_t * new_int_handlers)
+{
+ int i;
+
+ for (i = 0; i < NUM_INT_CHANNELS; i++)
+ int_handlers[i] = new_int_handlers[i];
+ update_interrupt_characters ();
+ return;
+}
+
+extern long EXFUN (text_write, (int, CONST unsigned char *, size_t));
+
+static void
+DEFUN (console_write_string, (string), unsigned char * string)
+{
+ (void) text_write ((fileno (stdout)), string, (strlen (string)));
+ return;
+}
+
+static void
+DEFUN (console_write_character, (c), unsigned char c)
+{
+ (void) text_write ((fileno (stdout)), &c, 1);
+ return;
+}
+
+static unsigned char
+DEFUN_VOID (console_read_character)
+{
+ unsigned char c;
+ extern int EXFUN (dos_read, (int, PTR, size_t, int, int, int));
+
+ /* non-buffered, blocking, non-interrupting read. */
+ (void) dos_read ((fileno (stdin)), &c, 1, 0, 1, 0);
+ return (c);
+}
+\f
+void
+DEFUN_VOID (initialize_keyboard_interrupt_table)
+{
+ /* Set up default interrupt characters */
+ int_chars[0] = CONTROL_B;
+ int_handlers[0] = ((unsigned char) interrupt_handler_control_b);
+ int_chars[1] = CONTROL_G;
+ int_handlers[1] = ((unsigned char) interrupt_handler_control_g);
+ int_chars[2] = CONTROL_U;
+ int_handlers[2] = ((unsigned char) interrupt_handler_control_u);
+ int_chars[3] = CONTROL_X;
+ int_handlers[3] = ((unsigned char) interrupt_handler_control_x);
+ int_chars[4] = CONTROL_C;
+ int_handlers[4] = ((unsigned char) interrupt_handler_interactive);
+ int_chars[5] = CONTROL_BREAK;
+ int_handlers[5] = ((unsigned char) interrupt_handler_terminate);
+ update_interrupt_characters ();
+ keyboard_interrupt_enables =
+ (CONTROL_B_ENABLE | CONTROL_G_ENABLE
+ | CONTROL_U_ENABLE | CONTROL_X_ENABLE
+ | INTERACTIVE_INTERRUPT_ENABLE
+ | TERMINATE_INTERRUPT_ENABLE);
+ return;
+}
+
+static int hard_attn_limit = 2;
+static int hard_attn_counter = 0;
+
+cc_t
+DEFUN (OS_tty_map_interrupt_char, (int_char), cc_t int_char)
+{
+ /* Scheme got a keyboard interrupt, reset the hard attention counter. */
+ hard_attn_counter = 0;
+ return (int_char);
+}
+
+static void
+DEFUN_VOID (print_interrupt_help)
+{
+ console_write_string ("\nInterrupt Choices are:\n");
+ console_write_string ("C-G interrupt: G, g, ^G (abort to top level)\n");
+ console_write_string ("C-X interrupt: X, x, ^x (abort)\n");
+ console_write_string ("C-B interrupt: B, b, ^B (break)\n");
+ console_write_string ("C-U interrupt: U, u, ^U (up)\n");
+ console_write_string ("Ignore interrupt: I, i (dismiss)\n");
+ console_write_string ("Reset scheme: R, r (hard reset)\n");
+ console_write_string ("Quit scheme: Q, q (exit)\n");
+ console_write_string ("Print help: ?");
+ return;
+}
+
+#define REQUEST_INTERRUPT_IF_ENABLED(mask) do \
+{ \
+ if (keyboard_interrupt_enables & (mask)) \
+ { \
+ tty_set_next_interrupt_char (interrupt_char); \
+ interrupt_p = 1; \
+ } \
+ else \
+ interrupt_p = 0; \
+} while (0)
+\f
+int EXFUN (signal_keyboard_character_interrupt, (int));
+
+int
+DEFUN (signal_keyboard_character_interrupt, (c), int c)
+{
+ if (c == -1)
+ {
+ if (keyboard_interrupt_enables & TERMINATE_INTERRUPT_ENABLE)
+ goto interactive_interrupt;
+ else
+ return (0);
+ }
+ if (c == -2)
+ {
+ /* Special kludge for hard attn. */
+ if (keyboard_interrupt_enables & TERMINATE_INTERRUPT_ENABLE)
+ {
+ hard_attn_counter += 1;
+ if (hard_attn_counter >= hard_attn_limit)
+ {
+ console_write_string ("\nTerminating scheme!");
+ termination_normal (0);
+ }
+ goto interactive_interrupt;
+ }
+ return (0);
+ }
+ else if ((c >= 0) && (c < KB_INT_TABLE_SIZE))
+ {
+ int interrupt_p, interrupt_char;
+
+ interrupt_char = keyboard_interrupt_table[c];
+
+ switch (interrupt_char)
+ {
+ case CONTROL_B_INTERRUPT_CHAR:
+ REQUEST_INTERRUPT_IF_ENABLED (CONTROL_B_ENABLE);
+ break;
+
+ case CONTROL_G_INTERRUPT_CHAR:
+ REQUEST_INTERRUPT_IF_ENABLED (CONTROL_G_ENABLE);
+ break;
+
+ case CONTROL_U_INTERRUPT_CHAR:
+ REQUEST_INTERRUPT_IF_ENABLED (CONTROL_U_ENABLE);
+ break;
+
+ case CONTROL_X_INTERRUPT_CHAR:
+ REQUEST_INTERRUPT_IF_ENABLED (CONTROL_X_ENABLE);
+ break;
+
+ case INTERACTIVE_INTERRUPT_CHAR:
+ if (! (keyboard_interrupt_enables & INTERACTIVE_INTERRUPT_ENABLE))
+ {
+ interrupt_p = 0;
+ break;
+ }
+interactive_interrupt:
+ {
+ cc_t int_char;
+
+ int_char = (DOS_interactive_interrupt_handler ());
+ if (int_char == ((cc_t) 0))
+ hard_attn_counter = 0;
+ else
+ {
+ tty_set_next_interrupt_char ((int) int_char);
+ interrupt_p = 1;
+ }
+ }
+ break;
+
+ default:
+ interrupt_p = 0;
+ }
+ return (interrupt_p);
+ }
+ return (0);
+}
+\f
+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;
+ }
+ }
+ }
+}
+\f
+void
+DEFUN_VOID (OS_restartable_exit)
+{
+ return;
+}
+
+#ifdef UNUSED
+
+#define IF_POSIX_SIGNALS(code) do {} while (0)
+
+DEFUN_STD_HANDLER (sighnd_stop, {})
+
+#ifdef HAVE_ITIMER
+
+DEFUN_STD_HANDLER (sighnd_timer,
+ {
+ request_timer_interrupt ();
+ })
+
+#else /* not HAVE_ITIMER */
+
+extern void EXFUN (reschedule_alarm, (void));
+
+DEFUN_STD_HANDLER (sighnd_timer,
+ {
+ /* reschedule_alarm ();
+ request_timer_interrupt ();
+ */
+ })
+
+#endif /* HAVE_ITIMER */
+\f
+DEFUN_STD_HANDLER (sighnd_save_then_terminate,
+ (request_suspend_interrupt ()))
+
+#ifndef SIGNUP
+#define SIGHUP 999
+#endif
+
+DEFUN_STD_HANDLER (sighnd_terminate,
+ (termination_signal
+ ((! (option_emacs_subprocess && (signo == SIGHUP)))
+ ? (find_signal_name (signo))
+ : 0)))
+
+#define VOID ((struct sigcontext *) 0)
+
+DEFUN_STD_HANDLER (sighnd_fpe,
+ {
+ if (executing_scheme_primitive_p ())
+ error_floating_point_exception ();
+ trap_handler ("floating-point exception signal", signo, VOID, VOID);
+ })
+
+DEFUN_STD_HANDLER (sighnd_hardware_trap,
+ (trap_handler ("hardware fault signal", signo, VOID, VOID)))
+
+DEFUN_STD_HANDLER (sighnd_software_trap,
+ (trap_handler ("system software fault signal", signo, VOID, VOID)))
+
+
+/* When a child process terminates, it becomes a zombie until its
+ parent process calls one of the wait() routines to obtain the
+ child's termination status. The SIGCHLD handler must always call
+ wait() or waitpid() to permit the child process's resources to be
+ freed. */
+
+/* On systems with waitpid() (i.e. those that support WNOHANG) we must
+ loop until there are no more processes, because some of those
+ systems may deliver only one SIGCHLD when more than one child
+ terminates. Systems without waitpid() (e.g. _SYSV) typically
+ provide queuing of SIGCHLD such that one SIGCHLD is delivered for
+ every child that terminates. Systems that provide neither
+ waitpid() nor queuing are so losing that we can't win, in which
+ case we just hope that child terminations don't happen too close to
+ one another to cause problems. */
+
+DEFUN_STD_HANDLER (sighnd_dead_subprocess,
+ {
+ })
+#endif /* UNUSED */
+\f
+/* PC specific low-level interrupt hooks. */
+/* Control-Break Interrupt. */
+
+int
+DEFUN (control_break_handler, (pd), struct INT_DATA * pd)
+{
+ tty_set_next_interrupt_char (CONTROL_G_INTERRUPT_CHAR);
+ 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)
+{
+/* SRA HACK
+ int value = (ce_handler (&pd->regs.e.eax, &pd->regs.e.edi));
+ return ((value == 1) ? INTERRUPT_RETURN : INTERRUPT_CHAIN_NEXT);
+*/
+ return INTERRUPT_CHAIN_NEXT;
+}
+
+#endif /* USE_ZORTECH_CERROR */
+\f
+/* Interval timer */
+
+/* Scheme timer emulation; DOS does not have an ITIMER like unix. */
+/* Zero means timer is not set or has expired. */
+
+extern unsigned long scm_itimer_counter;
+extern unsigned long scm_itimer_reload;
+
+unsigned long scm_itimer_counter = 0;
+unsigned long scm_itimer_reload = 0;
+
+extern void EXFUN (dos_process_timer_interrupt, (void));
+
+void
+DEFUN_VOID (dos_process_timer_interrupt)
+{
+ if (scm_itimer_counter != 0)
+ {
+ if (--scm_itimer_counter == 0)
+ {
+ scm_itimer_counter = scm_itimer_reload;
+ request_timer_interrupt ();
+ }
+ }
+ return;
+}
+
+extern int EXFUN (bios_timer_handler, (struct INT_DATA *));
+
+int
+DEFUN (bios_timer_handler, (pd), struct INT_DATA *pd)
+{
+#if 0
+ dos_process_timer_interrupt ();
+#else
+ /* This is a kludge for DOS.
+ Reuse INT_Global_GC as a high-priority interrupt from
+ which the keyboard interrupt and real timer interrupt are
+ derived.
+ */
+ REQUEST_INTERRUPT (INT_Global_GC);
+#endif
+ return (INTERRUPT_CHAIN_NEXT);
+}
+\f
+static Boolean
+ dos_interrupts_initialized_p = false,
+ ctrl_c_check_flag = true;
+
+dos_boolean DOS_keyboard_intercepted_p = false;
+
+#define NUM_DOS_INTVECT (MAX_DOS_INTVECT + 1)
+#define NUM_DOS_HANDLERS (NUM_DOS_INTVECT + NUM_DOS_EXCP)
+static int EXFUN ((* (dos_interrupt_restoration[NUM_DOS_HANDLERS])),
+ (unsigned));
+
+static void
+DEFUN (dos_record_interrupt_interception, (intno, restorer),
+ unsigned intno AND int ((*restorer) (unsigned)))
+{
+ dos_interrupt_restoration[intno] = restorer;
+ return;
+}
+
+static int
+DEFUN (scm_int_restore, (iv), unsigned iv)
+{
+/*SRA
+ int_restore (iv);
+*/
+ return (DOS_SUCCESS); /* A big lie. */
+}
+
+static int
+DEFUN (scm_int_intercept, (iv, proc, stack),
+ unsigned iv AND int (*proc)(struct INT_DATA *) AND unsigned stack)
+{
+ if ((int_intercept (iv, proc, stack)) != 0)
+ return (DOS_FAILURE);
+
+ dos_record_interrupt_interception (iv, scm_int_restore);
+ return (DOS_SUCCESS);
+}
+
+static void
+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--)
+ dos_interrupt_restoration[iv] = ((int (*) (unsigned)) NULL);
+
+ dos_interrupts_initialized_p = true;
+ return;
+}
+\f
+extern int EXFUN (DPMI_free_scheme_stack, (unsigned short));
+extern int EXFUN (DPMI_alloc_scheme_stack,
+ (unsigned short *, unsigned short *, unsigned long));
+
+extern unsigned short Scheme_Stack_Segment_Selector;
+extern unsigned short scheme_ss, scheme_ds;
+unsigned short scheme_ds = 0;
+unsigned short scheme_ss = 0;
+
+static char i386_exceptions_to_handle[] =
+{
+ DOS_EXCP_Stack_exception, /* Must be first */
+ DOS_EXCP_Integer_divide_by_zero,
+ DOS_EXCP_Debug_exception,
+ DOS_EXCP_Breakpoint,
+ DOS_EXCP_Integer_overflow,
+ DOS_EXCP_Bounds_check,
+ DOS_EXCP_Invalid_opcode,
+ DOS_EXCP_Numeric_co_processor_not_available,
+ DOS_EXCP_Numeric_co_processor_segment_overrun,
+ DOS_EXCP_Invalid_TSS,
+ DOS_EXCP_Segment_not_present,
+ DOS_EXCP_General_protection,
+ DOS_EXCP_Page_Fault,
+ DOS_EXCP_Floating_point_exception,
+ DOS_EXCP_Alignment_check,
+ DOS_INVALID_TRAP
+};
+
+static short old_excp_handler_cs[NUM_DOS_EXCP];
+static unsigned old_excp_handler_eip[NUM_DOS_EXCP];
+static void * stack_exception_fault_stack = ((void *) NULL);
+
+#define STACK_EXCEPTION_STACK_SIZE 2048
+
+static int
+DEFUN (restore_exception_handler, (iv, restore),
+ unsigned iv
+ AND int EXFUN ((* restore), (unsigned, unsigned short, unsigned)))
+{
+ unsigned excp = (iv - NUM_DOS_INTVECT);
+
+ if (((* restore) (excp,
+ old_excp_handler_cs[excp],
+ old_excp_handler_eip[excp]))
+ != DOS_SUCCESS)
+ return (DOS_FAILURE);
+ if (excp == DOS_EXCP_Stack_exception)
+ {
+ if (scheme_ss != 0)
+ {
+ Scheme_Stack_Segment_Selector = scheme_ds;
+ /* SRA
+ DPMI_free_scheme_stack (scheme_ss);
+ */
+ }
+ free (stack_exception_fault_stack);
+ stack_exception_fault_stack = ((void *) NULL);
+ }
+ return (DOS_SUCCESS);
+}
+
+/* The following two procedures would not be here if C had lambda */
+
+static int
+DEFUN (DPMI_restore_handler, (iv), unsigned iv)
+{
+ return (restore_exception_handler (iv, DPMI_restore_exception_handler));
+}
+
+static int
+DEFUN (X32_restore_handler, (iv), unsigned iv)
+{
+ return (restore_exception_handler (iv, X32_restore_exception_handler));
+}
+\f
+static void
+DEFUN (exception_handler, (trapno, trapcode, scp),
+ unsigned trapno AND unsigned trapcode AND struct sigcontext * scp)
+{
+ trap_handler ("hardware exception", ((int) trapno), trapcode, scp);
+ /*NOTREACHED*/
+}
+
+static void
+DEFUN (DPMI_stack_fault_handler, (trapno, trapcode, scp),
+ unsigned trapno AND unsigned trapcode AND struct sigcontext * scp)
+{
+ Scheme_Stack_Segment_Selector = scheme_ds;
+ if (((scp->sc_ss & 0xffff) == scheme_ss)
+ && (scp->sc_esp < (((unsigned long) Stack_Guard) + 0x1000)))
+ {
+ scp->sc_ss = scheme_ds;
+ REQUEST_INTERRUPT (INT_Stack_Overflow);
+ return;
+ }
+ trap_handler ("hardware exception", ((int) trapno), trapcode, scp);
+ /*NOTREACHED*/
+}
+
+extern void EXFUN (dos386_stack_reset, (void));
+
+void
+DEFUN_VOID (dos386_stack_reset)
+{
+ if (scheme_ss != 0)
+ Scheme_Stack_Segment_Selector = scheme_ss;
+ return;
+}
+
+static void
+DEFUN (install_exception_handlers, (get_vector, set_handler, restore),
+ int EXFUN ((* get_vector),
+ (unsigned, unsigned short *, unsigned *))
+ AND int EXFUN ((* set_handler),
+ (unsigned,
+ void EXFUN ((*),
+ (unsigned,
+ unsigned,
+ struct sigcontext *)),
+ void *))
+ AND int EXFUN ((* restore), (unsigned)))
+{
+ int i;
+ char * normal_stack = ((char *) NULL);
+\f
+ for (i = 0; dos_true ; i++)
+ {
+ int excp = ((int) i386_exceptions_to_handle[i]);
+
+ if (excp == DOS_INVALID_TRAP)
+ break;
+ if (((* get_vector) (((unsigned) excp),
+ & old_excp_handler_cs[excp],
+ & old_excp_handler_eip[excp]))
+ != DOS_SUCCESS)
+ continue;
+ if (excp == DOS_EXCP_Stack_exception)
+ {
+ void EXFUN ((* handler), (unsigned, unsigned, struct sigcontext *));
+ char * stack;
+
+ stack = ((char *) (malloc (2 * STACK_EXCEPTION_STACK_SIZE)));
+ if (stack == ((char *) NULL))
+ continue;
+ handler = exception_handler;
+/*SRA
+ if ((under_DPMI_p ())
+ && (enable_DPMI_exceptions_p ())
+ && ((DPMI_alloc_scheme_stack (&scheme_ds, &scheme_ss,
+ ((unsigned long) Stack_Guard)))
+ == DOS_SUCCESS))
+ {
+ Scheme_Stack_Segment_Selector = scheme_ss;
+ handler = DPMI_stack_fault_handler;
+ normal_stack = (stack + STACK_EXCEPTION_STACK_SIZE);
+ }
+*/
+ if (((* set_handler) (((unsigned) excp),
+ handler,
+ ((void *) (stack + STACK_EXCEPTION_STACK_SIZE))))
+ != DOS_SUCCESS)
+ {
+ normal_stack = ((char *) NULL);
+ free (stack);
+ if (handler != exception_handler)
+ {
+ Scheme_Stack_Segment_Selector = scheme_ds;
+ /*SRA
+ DPMI_free_scheme_stack (scheme_ss);
+ */
+ scheme_ss = 0;
+ }
+ continue;
+ }
+ stack_exception_fault_stack = ((void *) stack);
+ }
+ else if (((* set_handler) (((unsigned) excp),
+ exception_handler,
+ ((void *) normal_stack)))
+ != DOS_SUCCESS)
+ continue;
+ dos_record_interrupt_interception ((excp + NUM_DOS_INTVECT), restore);
+ }
+ return;
+}
+\f
+/* No lambda! foo. */
+
+/*SRA
+static int
+DEFUN (DOS_restore_keyboard, (intno), unsigned intno)
+{
+ if ((dos_restore_kbd_hook ()) != DOS_SUCCESS)
+ return (DOS_FAILURE);
+ DOS_keyboard_intercepted_p = false;
+ return (DOS_SUCCESS);
+}*/
+
+/* This defaults to true. */
+
+static dos_boolean
+DEFUN (feature_enabled_p, (symbol), char * symbol)
+{
+ extern int strcmp_ci (char *, char *);
+ char * envvar = (DOS_getenv (symbol));
+
+ if ((envvar == NULL)
+ || ((strcmp_ci (envvar, "true")) == 0)
+ || ((strcmp_ci (envvar, "yes")) == 0))
+ return (dos_true);
+ else
+ return (dos_false);
+}
+
+
+static dos_boolean
+DEFUN_VOID (enable_DPMI_exceptions_p)
+{
+ return (feature_enabled_p ("MITSCHEME_DPMI_EXCEPTIONS"));
+}
+
+static dos_boolean
+DEFUN_VOID (enable_X32_exceptions_p)
+{
+ return (feature_enabled_p ("MITSCHEME_X32_EXCEPTIONS"));
+}
+\f
+static void
+DEFUN_VOID (DOS_install_interrupts)
+{
+/*
+ extern dos_boolean EXFUN (under_X32_p, (void));
+ dos_boolean x32_p = (under_X32_p ());
+ dos_boolean dpmi_p = (under_DPMI_p ());
+*/
+
+#if 0
+ if (x32_p && (feature_enabled_p ("MITSCHEME_X32_INTERRUPTS")))
+ {
+ extern void EXFUN (X32_asm_initialize, (void));
+ extern int EXFUN (X32_lock_scheme_microcode, (void));
+ 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 ();
+
+ if ((X32_lock_scheme_microcode ()) != 0)
+ {
+ fprintf (stderr,
+ "\n;; DOS_install_interrupts (X32): Unable to lock memory.");
+ fprintf (stderr,
+ "\n;; Interrupt and exceptions handlers not available!\n");
+ fflush (stderr);
+ return;
+ }
+
+ if ((X32_int_intercept (DOS_INTVECT_USER_TIMER_TICK,
+ X32_timer_interrupt,
+ ((PTR) &X32_timer_interrupt_previous)))
+ != 0)
+ {
+ fprintf (stderr,
+ "\n;; DOS_install_interrupts (X32): Unable to intercept.");
+ fprintf (stderr,
+ "\n;; Timer interrupt not available!\n");
+ fflush (stderr);
+ }
+ 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 */
+ }
+ }
+#endif /* 0 to comment out SRA*/
+\f
+#if 0
+ else if (feature_enabled_p ("MITSCHEME_DOSX_INTERRUPTS"))
+ {
+ scm_int_intercept (DOS_INTVECT_USER_TIMER_TICK,
+ bios_timer_handler,
+ 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)
+ {
+ dos_record_interrupt_interception (DOS_INTVECT_SYSTEM_SERVICES,
+ DOS_restore_keyboard);
+ DOS_keyboard_intercepted_p = true;
+ }
+#endif /*0*/
+/*SRA
+ if (dpmi_p && (enable_DPMI_exceptions_p ()))
+ install_exception_handlers (DPMI_get_exception_vector,
+ DPMI_set_exception_handler,
+ DPMI_restore_handler);
+ else if (x32_p && (enable_X32_exceptions_p ()))
+ install_exception_handlers (X32_get_exception_vector,
+ X32_set_exception_handler,
+ X32_restore_handler);
+*/
+ return;
+}
+
+void
+DEFUN_VOID (DOS_restore_interrupts)
+{
+ int iv;
+
+ if (dos_interrupts_initialized_p)
+ {
+ for (iv = (NUM_DOS_HANDLERS - 1); iv >= 0; iv--)
+ if ((dos_interrupt_restoration[iv]) != ((int (*) (unsigned)) NULL))
+ {
+ (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);
+ return;
+}
+\f
+/* Signal Bindings */
+
+#ifdef UNUSED
+
+static void
+DEFUN (bind_handler, (signo, handler),
+ int signo AND
+ Tsignal_handler handler)
+{
+ if ((signo != 0)
+ && ((handler != ((Tsignal_handler) sighnd_stop)))
+ && ((current_handler (signo)) == SIG_DFL))
+ INSTALL_HANDLER (signo, handler);
+ return;
+}
+
+#endif /* UNUSED */
+
+void
+DEFUN_VOID (DOS_initialize_signals)
+{
+#ifdef UNUSED
+ initialize_signal_descriptors ();
+ bind_handler (SIGINT, sighnd_control_c);
+ bind_handler (SIGTERM, sighnd_control_g);
+ bind_handler (SIGFPE, sighnd_fpe);
+ if ((isatty (STDIN_FILENO)) || option_emacs_subprocess)
+ {
+ bind_handler (SIGILL, sighnd_hardware_trap);
+ bind_handler (SIGSEGV, sighnd_hardware_trap);
+ bind_handler (SIGABRT, sighnd_software_trap);
+ }
+ {
+ struct signal_descriptor * scan = signal_descriptors;
+ struct signal_descriptor * end = (scan + signal_descriptors_length);
+ while (scan < end)
+ {
+ if (((scan -> flags) & NOCATCH) == 0)
+ switch (scan -> action)
+ {
+ case dfl_terminate:
+ bind_handler ((scan -> signo), sighnd_terminate);
+ break;
+ case dfl_stop:
+ bind_handler ((scan -> signo), sighnd_stop);
+ break;
+ }
+ scan += 1;
+ }
+ }
+#else /* UNUSED */
+ DOS_initialize_interrupts ();
+ DOS_install_interrupts ();
+#endif /* UNUSED */
+ return;
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: ntsys.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/*#include <dos.h>*/
+#include <stdio.h>
+#include "nt.h"
+#include "ntsys.h"
+\f
+#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)
+{
+ unsigned char * buffer = vbuffer;
+ int i;
+
+ for (i = 0; i < nsize; i++)
+ {
+ putchar(buffer[i]);
+ }
+ return (nsize);
+}
+\f
+/* DOS I/O functions using handles */
+
+#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 */
+\f
+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;
+}
+
+
+#ifdef UNUSED
+void
+dos_reset_drive (void)
+{
+ union REGS regs;
+
+ regs.h.al = 0x0d;
+ intdos (®s, ®s);
+ 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 */
+\f
+dos_boolean
+dos_pathname_as_filename (char * name, char * buffer)
+{ /* Returns whether directory encountered is top level */
+ unsigned int end_index = ((strlen (name)) - 1);
+
+ /* The runtime system comes down with a name that has a back slash
+ at the end. This will choke DOS.
+ */
+ strcpy (buffer, name);
+ 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);
+ else
+ {
+ if (buffer[end_index-1] == ':') /* Preceded by drive letter, top */
+ return (dos_true);
+ else
+ {
+ buffer[end_index] = '\0';
+ return (dos_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);
+} */
+\f
+/* 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
+\f
+#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;
+}
+#endif
--- /dev/null
+/* -*-C-*-
+
+$Id: ntsys.h,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_DOSSYS_H
+#define SCM_DOSSYS_H
+\f
+#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);
+\f
+/* 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)
+
+#endif /* SCM_DOSSYS_H */
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/ntterm.h,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_UXTERM_H
+#define SCM_UXTERM_H
+
+#include "osterm.h"
+
+#endif /* SCM_UXTERM_H */
+\1a
\ No newline at end of file
--- /dev/null
+/* -*-C-*-
+
+$Id: nttop.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "nt.h"
+#include "nttop.h"
+#include "osctty.h"
+#include "ntutil.h"
+#include "errors.h"
+#include "option.h"
+
+extern void EXFUN (DOS_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_signals, (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 (DOS_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));
+
+/* reset_interruptable_extent */
+
+extern CONST char * OS_Name;
+extern CONST char * OS_Variant;
+\f
+static int interactive;
+
+int
+DEFUN_VOID (OS_under_emacs_p)
+{
+ return (option_emacs_subprocess);
+}
+
+void
+DEFUN_VOID (OS_initialize)
+{
+ dstack_initialize ();
+ transaction_initialize ();
+ interactive = 1;
+
+ DOS_initialize_channels ();
+ DOS_initialize_environment ();
+ DOS_initialize_tty ();
+ /*DOS_initialize_trap_recovery ();*/
+ DOS_initialize_signals ();
+ DOS_initialize_directory_reader ();
+ DOS_initialize_conio();
+ /*DOS_initialize_real_mode (); SRA*/
+ OS_Name = SYSTEM_NAME;
+ OS_Variant = SYSTEM_VARIANT;
+
+ { version_t version_number;
+
+ dos_get_version(&version_number);
+ fprintf (stdout, "MIT Scheme running under %s %d.%d 386/486\n",
+ OS_Variant,
+ (int) version_number.major, (int) version_number.minor);
+ /* To make our compiler vendors happy. */
+ fprintf(stdout,
+ "Copyright (c) 1992 Massachusetts Institute of Technology\n");
+ }
+
+ fputs ("", stdout);
+ fflush (stdout);
+}
+
+void
+DEFUN_VOID (OS_reset)
+{
+ /*
+ There should really be a reset for each initialize above,
+ but the rest seem innocuous.
+ */
+
+ DOS_reset_channels ();
+ execute_reload_cleanups ();
+}
+
+void
+DEFUN (OS_quit, (code, abnormal_p), int code AND int abnormal_p)
+{
+ fflush (stdout);
+ fputs ("\nScheme has terminated abnormally!\n", stdout);
+ OS_restore_external_state ();
+}
+\f
+#ifndef EAGAIN
+#define EAGAIN ERRNO_NONBLOCK
+#endif
+
+static enum syserr_names
+DEFUN (error_code_to_syserr, (code), int code)
+{
+ switch (code)
+ {
+ case E2BIG: return (syserr_arg_list_too_long);
+ case EACCES: return (syserr_permission_denied);
+ case EAGAIN: return (syserr_resource_temporarily_unavailable);
+ case EBADF: return (syserr_bad_file_descriptor);
+ case EDEADLOCK: return (syserr_resource_deadlock_avoided);
+ case EDOM: return (syserr_domain_error);
+ case EEXIST: return (syserr_file_exists);
+ case EINTR: return (syserr_interrupted_function_call);
+ case EINVAL: return (syserr_invalid_argument);
+ case EMFILE: return (syserr_too_many_open_files);
+ case ENOENT: return (syserr_no_such_file_or_directory);
+ case ENOEXEC: return (syserr_exec_format_error);
+ case ENOMEM: return (syserr_not_enough_space);
+ case ENOTDIR: return (syserr_not_a_directory);
+ case ERANGE: return (syserr_result_too_large);
+ default: return (syserr_unknown);
+ }
+}
+
+static int
+DEFUN (syserr_to_error_code, (syserr), enum syserr_names syserr)
+{
+ switch (syserr)
+ {
+ case syserr_arg_list_too_long: return (E2BIG);
+ case syserr_bad_file_descriptor: return (EBADF);
+ case syserr_domain_error: return (EDOM);
+ case syserr_exec_format_error: return (ENOEXEC);
+ case syserr_file_exists: return (EEXIST);
+ case syserr_interrupted_function_call: return (EINTR);
+ case syserr_invalid_argument: return (EINVAL);
+ case syserr_no_such_file_or_directory: return (ENOENT);
+ case syserr_not_a_directory: return (ENOTDIR);
+ case syserr_not_enough_space: return (ENOMEM);
+ case syserr_permission_denied: return (EACCES);
+ case syserr_resource_deadlock_avoided: return (EDEADLOCK);
+ case syserr_resource_temporarily_unavailable: return (EAGAIN);
+ case syserr_result_too_large: return (ERANGE);
+ case syserr_too_many_open_files: return (EMFILE);
+ default: return (0);
+ }
+}
+
+void
+DEFUN (error_system_call, (code, name), int code AND enum syscall_names name)
+{
+ extern unsigned int syscall_error_code;
+ extern unsigned int syscall_error_name;
+ syscall_error_code = ((unsigned int) (error_code_to_syserr (code)));
+ syscall_error_name = ((unsigned int) name);
+ signal_error_from_primitive (ERR_IN_SYSTEM_CALL);
+}
+
+CONST char *
+DEFUN (OS_error_code_to_message, (syserr), unsigned int syserr)
+{
+ extern char * sys_errlist [];
+ extern int sys_nerr;
+ int code = (syserr_to_error_code ((enum syserr_names) syserr));
+ return (((code > 0) && (code <= sys_nerr)) ? (sys_errlist [code]) : 0);
+}
+
+void
+DEFUN (DOS_prim_check_errno, (name), enum syscall_names name)
+{
+ if (errno != EINTR)
+ error_system_call (errno, name);
+ deliver_pending_interrupts();
+}
+
+void OS_restore_external_state (void)
+{ extern void DOS_restore_interrupts(void);
+
+ DOS_restore_interrupts();
+ return;
+}
+
+void bcopy (const char *s1, char *s2, int n)
+{
+ while (n-- > 0)
+ *s2++ = *s1++;
+ return;
+}
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/nttop.h,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_DOSTOP_H
+#define SCM_DOSTOP_H
+
+#include "ostop.h"
+
+#endif /* SCM_DOSTOP_H */
+\1a
\ No newline at end of file
--- /dev/null
+/* -*-C-*-
+
+$Id: nttrap.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "scheme.h"
+#include "os.h"
+#include "nt.h"
+#include "nttrap.h"
+#include "ntexcp.h"
+#include "ntinsn.h"
+
+
+extern void EXFUN (DOS_initialize_trap_recovery, (void));
+CONST char * EXFUN (find_trap_name, (int trapno));
+extern PTR initial_C_stack_pointer;
+\f
+static enum trap_state trap_state;
+static enum trap_state user_trap_state;
+
+static enum trap_state saved_trap_state;
+static int saved_trapno;
+static SIGINFO_T saved_info;
+static struct FULL_SIGCONTEXT * saved_scp;
+
+static unsigned short
+ initial_C_ss = 0,
+ initial_C_ds = 0,
+ initial_C_cs = 0;
+
+static void EXFUN (initialize_dos_trap_codes, (void));
+static void EXFUN
+ (continue_from_trap,
+ (int trapno, SIGINFO_T info, struct FULL_SIGCONTEXT * scp));
+
+/*SRA
+void
+DEFUN_VOID (DOS_initialize_trap_recovery)
+{
+ extern unsigned short getSS (void);
+
+ 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 ();
+} */
+
+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 void
+DEFUN_VOID (trap_normal_termination)
+{
+ trap_state = trap_state_exitting_soft;
+ termination_trap ();
+}
+
+static void
+DEFUN_VOID (trap_immediate_termination)
+{
+ trap_state = trap_state_exitting_hard;
+ OS_restore_external_state ();
+ exit (1);
+}
+
+static void
+DEFUN_VOID (trap_recover)
+{
+ if (WITHIN_CRITICAL_SECTION_P ())
+ {
+ CLEAR_CRITICAL_SECTION_HOOK ();
+ EXIT_CRITICAL_SECTION ({});
+ }
+ reset_interruptable_extent ();
+ continue_from_trap (saved_trapno, saved_info, saved_scp);
+}
+\f
+void
+DEFUN (trap_handler, (message, trapno, info, scp),
+ CONST char * message AND
+ int trapno AND
+ SIGINFO_T info AND
+ struct FULL_SIGCONTEXT * scp)
+{
+ 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;
+
+ 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);
+
+ 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 ();
+ }
+
+ fflush (stdout);
+ saved_trap_state = old_trap_state;
+ saved_trapno = trapno;
+ saved_info = info;
+ saved_scp = scp;
+
+ 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 ();
+ }
+ }
+}
+\f
+#define STATE_UNKNOWN (LONG_TO_UNSIGNED_FIXNUM (0))
+#define STATE_PRIMITIVE (LONG_TO_UNSIGNED_FIXNUM (1))
+#define STATE_COMPILED_CODE (LONG_TO_UNSIGNED_FIXNUM (2))
+#define STATE_PROBABLY_COMPILED (LONG_TO_UNSIGNED_FIXNUM (3))
+
+struct trap_recovery_info
+{
+ SCHEME_OBJECT state;
+ SCHEME_OBJECT pc_info_1;
+ SCHEME_OBJECT pc_info_2;
+ SCHEME_OBJECT extra_trap_info;
+};
+
+static struct trap_recovery_info dummy_recovery_info =
+{
+ STATE_UNKNOWN,
+ SHARP_F,
+ SHARP_F,
+ SHARP_F
+};
+
+struct dos_trap_code_desc
+{
+ int trapno;
+ unsigned long code_mask;
+ unsigned long code_value;
+ char *name;
+};
+
+static struct dos_trap_code_desc dos_trap_codes [64];
+
+#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; \
+}
+
+static SCHEME_OBJECT
+DEFUN (find_trap_code_name, (trapno, info, scp),
+ int trapno AND
+ SIGINFO_T info AND
+ struct FULL_SIGCONTEXT * scp)
+{
+ 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)))));
+}
+\f
+static void
+DEFUN_VOID (initialize_dos_trap_codes)
+{
+ 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));
+ return;
+}
+
+static CONST char *
+trap_names[NUM_DOS_EXCP] =
+{
+ "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"
+};
+
+CONST char *
+DEFUN (find_trap_name, (trapno), int trapno)
+{
+ static char buffer [64], * name;
+ if ((trapno >= 0) &&
+ (trapno < ((sizeof (trap_names)) / (sizeof (char *)))))
+ {
+ name = trap_names[trapno];
+ if ((name != ((char *) NULL))
+ && (name[0] != '\0'))
+ return ((CONST char *) name);
+ }
+ sprintf (buffer, "unknown exception %d", trapno);
+ return ((CONST char *) buffer);
+}
+\f
+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)
+{
+ SCHEME_OBJECT handler;
+ SCHEME_OBJECT trap_name, trap_code;
+ 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))
+ {
+ fprintf (stderr, "There is no trap handler for recovery!\n");
+ fprintf (stderr, "Trap = %s.\n", (find_trap_name (trapno)));
+ fprintf (stderr, "pc = %04x:%08lx; sp = %04x:%08lx.\n",
+ scp->sc_cs, scp->sc_eip, scp->sc_ss, scp->sc_esp);
+ fflush (stderr);
+ 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)
+ {
+ Initialize_Stack ();
+ Will_Push (CONTINUATION_SIZE);
+ Store_Return (RC_END_OF_COMPUTATION);
+ Store_Expression (SHARP_F);
+ Save_Cont ();
+ Pushed ();
+ }
+ else
+ Stack_Pointer = new_stack_pointer;
+ Will_Push (7 + CONTINUATION_SIZE);
+ STACK_PUSH (trinfo -> extra_trap_info);
+ STACK_PUSH (trinfo -> pc_info_2);
+ STACK_PUSH (trinfo -> pc_info_1);
+ STACK_PUSH (trinfo -> state);
+ STACK_PUSH (BOOLEAN_TO_OBJECT (stack_recovered_p));
+ STACK_PUSH (trap_code);
+ STACK_PUSH (trap_name);
+ Store_Return (RC_HARDWARE_TRAP);
+ Store_Expression (long_to_integer (trapno));
+ Save_Cont ();
+ Pushed ();
+ if (stack_recovered_p
+ /* This may want to do it in other cases, but this may be enough. */
+ && (trinfo->state == STATE_COMPILED_CODE))
+ Stop_History ();
+
+ History = (Make_Dummy_History ());
+ Will_Push (STACK_ENV_EXTRA_SLOTS + 2);
+ STACK_PUSH (trap_name);
+ STACK_PUSH (handler);
+ STACK_PUSH (STACK_FRAME_HEADER + 1);
+ Pushed ();
+ SET_INTERRUPT_MASK (saved_mask);
+ abort_to_interpreter (PRIM_APPLY);
+}
+\f
+/* 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);
+}
+
+#else /* HAVE_SIGCONTEXT and HAS_COMPILER_SUPPORT and not USE_STACKLETS */
+\f
+/* 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;
+ 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"
+
+#define SCHEME_ALIGNMENT_MASK ((sizeof (long)) - 1)
+#define STACK_ALIGNMENT_MASK SCHEME_ALIGNMENT_MASK
+#define FREE_PARANOIA_MARGIN 0x100
+
+/* PCs must be aligned according to this. */
+
+#define PC_ALIGNMENT_MASK ((1 << PC_ZERO_BITS) - 1)
+
+/* But they may have bits that can be masked by this. */
+
+#ifndef PC_VALUE_MASK
+#define PC_VALUE_MASK (~0)
+#endif
+
+#define C_STACK_SIZE 0x01000000
+
+#ifdef HAS_COMPILER_SUPPORT
+#define ALLOW_ONLY_C 0
+#else
+#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
+/* For now */
+#define get_etext() (Heap_Bottom)
+#endif
+
+static void
+DEFUN (continue_from_trap, (trapno, info, scp),
+ int trapno AND
+ SIGINFO_T info AND
+ struct FULL_SIGCONTEXT * scp)
+{
+ extern unsigned short scheme_ss;
+ int pc_in_C;
+ int pc_in_heap;
+ int pc_in_constant_space;
+ int pc_in_scheme;
+ int pc_in_hyper_space;
+ 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;
+
+ if (scp == ((struct FULL_SIGCONTEXT *) NULL))
+ {
+ if (Free < MemTop)
+ Free = MemTop;
+ setup_trap_frame (trapno, info, scp, (&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 FALSE
+ fprintf (stderr, "\ncontinue_from_trap:");
+ fprintf (stderr, "\tpc = 0x%08lx\n", the_pc);
+ fprintf (stderr, "\tCsp = 0x%08lx\n", C_sp);
+ fprintf (stderr, "\tssp = 0x%08lx\n", scheme_sp);
+ fprintf (stderr, "\tesp = 0x%08lx\n", Ext_Stack_Pointer);
+#endif
+
+ if (((the_pc & PC_ALIGNMENT_MASK) != 0)
+ || (scp->sc_cs != initial_C_cs))
+ {
+ pc_in_C = 0;
+ pc_in_heap = 0;
+ pc_in_constant_space = 0;
+ pc_in_scheme = 0;
+ pc_in_hyper_space = 1;
+ }
+ else
+ {
+ pc_in_C = (the_pc <= ((long) (get_etext ())));
+ 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_hyper_space = ((!pc_in_C) && (!pc_in_scheme));
+ }
+
+ scheme_sp_valid =
+ (pc_in_scheme
+ && (((scp->sc_ss & 0xffff) == (scp->sc_ds & 0xffff))
+ || ((scheme_ss != 0)
+ && ((scp->sc_ss & 0xffff) == scheme_ss)))
+ && ((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)));
+
+ 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)));
+
+ if (pc_in_hyper_space || (pc_in_scheme && ALLOW_ONLY_C))
+ {
+ /* In hyper space. */
+ (trinfo . state) = STATE_UNKNOWN;
+ (trinfo . pc_info_1) = SHARP_F;
+ (trinfo . pc_info_2) = SHARP_F;
+ new_stack_pointer = 0;
+ if ((Free < MemTop) ||
+ (Free >= Heap_Top) ||
+ ((((unsigned long) Free) & SCHEME_ALIGNMENT_MASK) != 0))
+ Free = MemTop;
+ }
+ else if (pc_in_scheme)
+ {
+ /* In compiled code. */
+ 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)
+ {
+ (trinfo . state) = STATE_PROBABLY_COMPILED;
+ (trinfo . pc_info_1) = (LONG_TO_UNSIGNED_FIXNUM (the_pc));
+ (trinfo . pc_info_2) = SHARP_F;
+ if ((Free < MemTop) ||
+ (Free >= Heap_Top) ||
+ ((((unsigned long) Free) & SCHEME_ALIGNMENT_MASK) != 0))
+ Free = MemTop;
+ }
+ 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)));
+ 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
+ {
+ /* In the interpreter, a primitive, or a compiled code utility. */
+
+ SCHEME_OBJECT primitive = (Regs[REGBLOCK_PRIMITIVE]);
+
+ if ((OBJECT_TYPE (primitive)) != TC_PRIMITIVE)
+ {
+ (trinfo . state) = STATE_UNKNOWN;
+ (trinfo . pc_info_1) = SHARP_F;
+ (trinfo . pc_info_2) = SHARP_F;
+ new_stack_pointer = 0;
+ }
+ else
+ {
+ long primitive_address =
+ ((long) (Primitive_Procedure_Table[OBJECT_DATUM (primitive)]));
+ (trinfo . state) = STATE_PRIMITIVE;
+ (trinfo . pc_info_1) = primitive;
+ (trinfo . pc_info_2) =
+ (LONG_TO_UNSIGNED_FIXNUM (Regs[REGBLOCK_LEXPR_ACTUALS]));
+ }
+ if ((new_stack_pointer == 0)
+ || ((((unsigned long) Free) & SCHEME_ALIGNMENT_MASK) != 0)
+ || ((Free < Heap_Bottom) || (Free >= Heap_Top))
+ || ((Free < MemTop) && ((Free + FREE_PARANOIA_MARGIN) >= MemTop)))
+ Free = MemTop;
+ 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);
+ {
+ 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++) = ((SCHEME_OBJECT) the_pc);
+ setup_trap_frame (trapno, info, scp, (&trinfo), new_stack_pointer);
+}
+\f
+/* Find the compiled code block in area which contains `pc_value'.
+ This attempts to be more efficient than `find_block_address_in_area'.
+ If the pointer is in the heap, it can actually do twice as
+ much work, but it is expected to pay off on the average. */
+
+static SCHEME_OBJECT * EXFUN
+ (find_block_address_in_area, (char * pc_value, SCHEME_OBJECT * area_start));
+
+#define MINIMUM_SCAN_RANGE 2048
+
+static SCHEME_OBJECT *
+DEFUN (find_block_address, (pc_value, area_start),
+ char * pc_value AND
+ SCHEME_OBJECT * area_start)
+{
+ if (area_start == Constant_Space)
+ {
+ extern SCHEME_OBJECT * EXFUN
+ (find_constant_space_block, (SCHEME_OBJECT *));
+ SCHEME_OBJECT * constant_block =
+ (find_constant_space_block
+ ((SCHEME_OBJECT *)
+ (((unsigned long) pc_value) &~ SCHEME_ALIGNMENT_MASK)));
+ return
+ ((constant_block == 0)
+ ? 0
+ : (find_block_address_in_area (pc_value, constant_block)));
+ }
+ {
+ SCHEME_OBJECT * nearest_word =
+ ((SCHEME_OBJECT *)
+ (((unsigned long) pc_value) &~ SCHEME_ALIGNMENT_MASK));
+ long maximum_distance = (nearest_word - area_start);
+ long distance = maximum_distance;
+ while ((distance / 2) > MINIMUM_SCAN_RANGE)
+ distance = (distance / 2);
+ while ((distance * 2) < maximum_distance)
+ {
+ SCHEME_OBJECT * block =
+ (find_block_address_in_area (pc_value, (nearest_word - distance)));
+ if (block != 0)
+ return (block);
+ distance *= 2;
+ }
+ }
+ return (find_block_address_in_area (pc_value, area_start));
+}
+\f
+/*
+ Find the compiled code block in area which contains `pc_value',
+ by scanning sequentially the complete area.
+ For the time being, skip over manifest closures and linkage sections. */
+
+static SCHEME_OBJECT *
+DEFUN (find_block_address_in_area, (pc_value, area_start),
+ char * pc_value AND
+ SCHEME_OBJECT * area_start)
+{
+ SCHEME_OBJECT * first_valid = area_start;
+ SCHEME_OBJECT * area = area_start;
+ while (((char *) area) < pc_value)
+ {
+ SCHEME_OBJECT object = (*area);
+ switch (OBJECT_TYPE (object))
+ {
+ case TC_LINKAGE_SECTION:
+ {
+ switch (READ_LINKAGE_KIND (object))
+ {
+ case OPERATOR_LINKAGE_KIND:
+ case GLOBAL_OPERATOR_LINKAGE_KIND:
+ {
+ long count = (READ_OPERATOR_LINKAGE_COUNT (object));
+ area = ((END_OPERATOR_LINKAGE_AREA (area, count)) + 1);
+ break;
+ }
+
+ default:
+#if FALSE
+ {
+ gc_death (TERM_EXIT,
+ "find_block_address: Unknown compiler linkage kind.",
+ area, NULL);
+ /*NOTREACHED*/
+ }
+#else
+ /* Fall through, no reason to crash here. */
+#endif
+ case REFERENCE_LINKAGE_KIND:
+ case ASSIGNMENT_LINKAGE_KIND:
+ area += ((READ_CACHE_LINKAGE_COUNT (object)) + 1);
+ break;
+
+ }
+ break;
+ }
+ case TC_MANIFEST_CLOSURE:
+ {
+ area += 1;
+ {
+ long count = (MANIFEST_CLOSURE_COUNT (area));
+ area = ((MANIFEST_CLOSURE_END (area, count)) + 1);
+ }
+ break;
+ }
+ case TC_MANIFEST_NM_VECTOR:
+ {
+ long count = (OBJECT_DATUM (object));
+ if (((char *) (area + (count + 1))) < pc_value)
+ {
+ area += (count + 1);
+ first_valid = area;
+ break;
+ }
+ {
+ 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))))
+ ? 0
+ : block);
+ }
+ }
+ default:
+ {
+ area += 1;
+ break;
+ }
+ }
+ }
+ return (0);
+}
+
+#endif /* HAVE_SIGCONTEXT and HAS_COMPILER_SUPPORT and not USE_STACKLETS */
+
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/nttrap.h,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#ifndef SCM_DOSTRAP_H
+#define SCM_DOSTRAP_H
+\f
+#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
+\f
+enum trap_state
+{
+ trap_state_trapped,
+ trap_state_exit,
+ trap_state_suspend,
+ trap_state_query,
+ trap_state_recover,
+ trap_state_exitting_soft,
+ trap_state_exitting_hard
+};
+
+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_DOSTRAP_H */
+\1a
\ No newline at end of file
--- /dev/null
+/* -*-C-*-
+
+$Header: /Users/cph/tmp/foo/mit-scheme/mit-scheme/v7/src/microcode/nttterm.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+/* termcap(3) interface for Scheme -- Only a subset needed for DOS. */
+
+#include "scheme.h"
+#include "prims.h"
+#include "osterm.h"
+
+extern char * EXFUN (tparam, (char *, char*, int, int, ...));
+extern char * EXFUN (tgoto, (char *, int, int));
+extern int EXFUN (tputs, (char *, int, void (*) (int)));
+extern char * BC;
+extern char * UP;
+extern char PC;
+extern short ospeed;
+
+#ifndef TERMCAP_BUFFER_SIZE
+#define TERMCAP_BUFFER_SIZE 2048
+#endif
+
+static char tputs_output [TERMCAP_BUFFER_SIZE];
+static char * tputs_output_scan;
+
+static void
+DEFUN (tputs_write_char, (c), int c)
+{
+ (*tputs_output_scan++) = c;
+ return;
+}
+\f
+DEFINE_PRIMITIVE ("TERMCAP-PARAM-STRING", Prim_termcap_param_string, 5, 5, 0)
+{
+ PRIMITIVE_HEADER (5);
+ {
+ char * s =
+ (tparam ((STRING_ARG (1)), 0, 0,
+ (arg_nonnegative_integer (2)),
+ (arg_nonnegative_integer (3)),
+ (arg_nonnegative_integer (4)),
+ (arg_nonnegative_integer (5))));
+ SCHEME_OBJECT result = (char_pointer_to_string ((unsigned char *) s));
+ free (s);
+ PRIMITIVE_RETURN (result);
+ }
+}
+
+DEFINE_PRIMITIVE ("TERMCAP-GOTO-STRING", Prim_termcap_goto_string, 5, 5, 0)
+{
+ PRIMITIVE_HEADER (5);
+ {
+ BC = (((ARG_REF (4)) == SHARP_F) ? 0 : (STRING_ARG (4)));
+ UP = (((ARG_REF (5)) == SHARP_F) ? 0 : (STRING_ARG (5)));
+ PRIMITIVE_RETURN
+ (char_pointer_to_string
+ ((unsigned char *)
+ (tgoto ((STRING_ARG (1)),
+ (arg_nonnegative_integer (2)),
+ (arg_nonnegative_integer (3))))));
+ }
+}
+
+DEFINE_PRIMITIVE ("TERMCAP-PAD-STRING", Prim_termcap_pad_string, 4, 4, 0)
+{
+ PRIMITIVE_HEADER (4);
+ ospeed = (arg_baud_index (3));
+ PC = (((ARG_REF (4)) == SHARP_F) ? '\0' : ((STRING_ARG (4)) [0]));
+ tputs_output_scan = tputs_output;
+ tputs ((STRING_ARG (1)), (arg_nonnegative_integer (2)), tputs_write_char);
+ PRIMITIVE_RETURN
+ (memory_to_string ((tputs_output_scan - tputs_output),
+ ((unsigned char *) tputs_output)));
+}
--- /dev/null
+/* -*-C-*-
+
+$Id: nttty.c,v 1.1 1993/02/10 22:39:46 adams Exp $
+
+Copyright (c) 1992 Massachusetts Institute of Technology
+
+This material was developed by the Scheme project at the Massachusetts
+Institute of Technology, Department of Electrical Engineering and
+Computer Science. Permission to copy this software, to redistribute
+it, and to use it for any purpose is granted, subject to the following
+restrictions and understandings.
+
+1. Any copy made of this software must include this copyright notice
+in full.
+
+2. Users of this software agree to make their best efforts (a) to
+return to the MIT Scheme project any improvements or extensions that
+they make, so that these may be included in future releases; and (b)
+to inform MIT of noteworthy uses of this software.
+
+3. All materials developed as a consequence of the use of this
+software shall duly acknowledge such use, in accordance with the usual
+standards of acknowledging credit in academic research.
+
+4. MIT has made no warrantee or representation that the operation of
+this software will be error-free, and MIT is under no obligation to
+provide any services, by way of maintenance, update, or otherwise.
+
+5. In conjunction with products arising from the use of this material,
+there shall be no use of the name of the Massachusetts Institute of
+Technology nor of any adaptation thereof in any advertising,
+promotional, or sales literature without prior written consent from
+MIT in each case. */
+
+#include "nt.h"
+#include "ostty.h"
+#include "osenv.h"
+#include "ntio.h"
+#include "ntterm.h"
+\f
+/* Standard Input and Output */
+
+static Tchannel input_channel;
+static Tchannel output_channel;
+int tty_x_size;
+int tty_y_size;
+ /* 1-based values */
+static char * tty_command_beep;
+static char * tty_command_clear;
+
+Tchannel
+DEFUN_VOID (OS_tty_input_channel)
+{
+ return (input_channel);
+}
+
+Tchannel
+DEFUN_VOID (OS_tty_output_channel)
+{
+ return (output_channel);
+}
+
+unsigned int
+DEFUN_VOID (OS_tty_x_size)
+{
+ return (tty_x_size);
+}
+
+unsigned int
+DEFUN_VOID (OS_tty_y_size)
+{
+ return (tty_y_size);
+}
+
+CONST char *
+DEFUN_VOID (OS_tty_command_beep)
+{
+ return (tty_command_beep);
+}
+
+CONST char *
+DEFUN_VOID (OS_tty_command_clear)
+{
+ return (tty_command_clear);
+}
+\f
+#ifndef TERMCAP_BUFFER_SIZE
+#define TERMCAP_BUFFER_SIZE 0
+#endif
+
+#ifndef DEFAULT_TTY_X_SIZE
+#define DEFAULT_TTY_X_SIZE 80
+#endif
+
+#ifndef DEFAULT_TTY_Y_SIZE
+#define DEFAULT_TTY_Y_SIZE 25
+#endif
+
+void
+pc_gestalt_screen_x_size (void)
+{
+ tty_x_size = DEFAULT_TTY_X_SIZE;
+
+/*SRA
+ char *psTemp;
+
+ psTemp = (getenv ("MITSCHEME_COLUMNS"));
+ if (psTemp == NULL)
+ {
+ union REGS regs;
+
+ regs.h.ah = 0x0F;
+ regs.h.al = 0x00;
+ int10h (®s, ®s);
+ tty_x_size = regs.h.ah;
+ }
+ else
+ {
+ tty_x_size = (atoi (psTemp));
+ if (tty_x_size == 0)
+ tty_x_size = DEFAULT_TTY_X_SIZE; /* atoi failed, use default */ /*
+ }
+*/
+ return;
+}
+
+void
+pc_gestalt_screen_y_size (void)
+{
+ tty_y_size = DEFAULT_TTY_Y_SIZE;
+/*SRA
+ char *psTemp;
+
+ psTemp = (getenv ("MITSCHEME_LINES"));
+ if (psTemp == NULL)
+ {
+ union REGS regs;
+
+ regs.x.ax = 0x1130;
+ regs.h.bh = 0x00;
+ regs.h.dl = DEFAULT_TTY_Y_SIZE-1;
+ int10h (®s, ®s);
+ tty_y_size = regs.h.dl + 1;
+ }
+ else
+ {
+ tty_y_size = (atoi (psTemp));
+ if (tty_y_size == 0)
+ tty_y_size = DEFAULT_TTY_Y_SIZE; /* atoi failed, use default */ /*
+ }
+*/
+ return;
+}
+
+void
+DEFUN_VOID (DOS_initialize_tty)
+{
+ extern Tchannel EXFUN (OS_open_fd, (int fd));
+ input_channel = (OS_open_fd (STDIN_FILENO));
+ (CHANNEL_INTERNAL (input_channel)) = 1;
+ output_channel = (OS_open_fd (STDOUT_FILENO));
+ (CHANNEL_INTERNAL (output_channel)) = 1;
+ tty_x_size = (-1);
+ tty_y_size = (-1);
+ tty_command_beep = ALERT_STRING;
+ tty_command_clear = "\033[2J";
+
+ /* Figure out the size of the terminal. Tries environment variables.
+ If that fails, use default values. */
+
+ pc_gestalt_screen_x_size ();
+ pc_gestalt_screen_y_size ();
+ return;
+}
+\f
+/* Fake TERMCAP capability */
+short ospeed;
+char PC;
+
+int
+tputs (string, nlines, outfun)
+ register char * string;
+ int nlines;
+ register int (*outfun) ();
+{
+ register int padcount = 0;
+
+ if (string == (char *) 0)
+ return;
+ while (*string >= '0' && *string <= '9')
+ {
+ padcount += *string++ - '0';
+ padcount *= 10;
+ }
+ if (*string == '.')
+ {
+ string++;
+ padcount += *string++ - '0';
+ }
+ if (*string == '*')
+ {
+ string++;
+ padcount *= nlines;
+ }
+ while (*string)
+ (*outfun) (*string++);
+
+ return (0);
+}