From 99dd5a3c08ba8ebd77535f9b9c185f065c96fe98 Mon Sep 17 00:00:00 2001 From: Stephen Adams Date: Wed, 10 Feb 1993 22:39:46 +0000 Subject: [PATCH] Initial revision --- v7/src/microcode/nt.h | 547 ++++++++++++++ v7/src/microcode/ntasutl.asm | 104 +++ v7/src/microcode/ntenv.c | 227 ++++++ v7/src/microcode/ntfile.c | 199 +++++ v7/src/microcode/ntfs.c | 294 ++++++++ v7/src/microcode/ntio.c | 539 ++++++++++++++ v7/src/microcode/ntio.h | 89 +++ v7/src/microcode/ntsig.c | 1344 ++++++++++++++++++++++++++++++++++ v7/src/microcode/ntsys.c | 447 +++++++++++ v7/src/microcode/ntsys.h | 178 +++++ v7/src/microcode/ntterm.h | 41 ++ v7/src/microcode/nttop.c | 222 ++++++ v7/src/microcode/nttop.h | 41 ++ v7/src/microcode/nttrap.c | 893 ++++++++++++++++++++++ v7/src/microcode/nttrap.h | 96 +++ v7/src/microcode/nttterm.c | 104 +++ v7/src/microcode/nttty.c | 209 ++++++ 17 files changed, 5574 insertions(+) create mode 100644 v7/src/microcode/nt.h create mode 100644 v7/src/microcode/ntasutl.asm create mode 100644 v7/src/microcode/ntenv.c create mode 100644 v7/src/microcode/ntfile.c create mode 100644 v7/src/microcode/ntfs.c create mode 100644 v7/src/microcode/ntio.c create mode 100644 v7/src/microcode/ntio.h create mode 100644 v7/src/microcode/ntsig.c create mode 100644 v7/src/microcode/ntsys.c create mode 100644 v7/src/microcode/ntsys.h create mode 100644 v7/src/microcode/ntterm.h create mode 100644 v7/src/microcode/nttop.c create mode 100644 v7/src/microcode/nttop.h create mode 100644 v7/src/microcode/nttrap.c create mode 100644 v7/src/microcode/nttrap.h create mode 100644 v7/src/microcode/nttterm.c create mode 100644 v7/src/microcode/nttty.c diff --git a/v7/src/microcode/nt.h b/v7/src/microcode/nt.h new file mode 100644 index 000000000..bd4893a3b --- /dev/null +++ b/v7/src/microcode/nt.h @@ -0,0 +1,547 @@ +/* -*-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 + +#define SYSTEM_NAME "NT" +#define SYSTEM_VARIANT "Windows-NT" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include /*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" + +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 +}; + +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 +#include +#include + +#define HAVE_MKDIR +#define HAVE_RMDIR +#define HAVE_GETCWD + +/* #define HAVE_DUP2 */ +/* #define HAVE_FCNTL */ +#define VOID_SIGNAL_HANDLERS + +#include + +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 */ + +/* 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 + +/* 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 + +#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 + +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)); \ +} + +#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 */ + diff --git a/v7/src/microcode/ntasutl.asm b/v7/src/microcode/ntasutl.asm new file mode 100644 index 000000000..22dba48d2 --- /dev/null +++ b/v7/src/microcode/ntasutl.asm @@ -0,0 +1,104 @@ +;;; -*-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 + + 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 diff --git a/v7/src/microcode/ntenv.c b/v7/src/microcode/ntenv.c new file mode 100644 index 000000000..b7fa1efbf --- /dev/null +++ b/v7/src/microcode/ntenv.c @@ -0,0 +1,227 @@ +/* -*-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 + +#ifdef WINNT +#include +#endif + +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))); +} + +/* 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; +} + +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; + } + } +} diff --git a/v7/src/microcode/ntfile.c b/v7/src/microcode/ntfile.c new file mode 100644 index 000000000..61cfb786d --- /dev/null +++ b/v7/src/microcode/ntfile.c @@ -0,0 +1,199 @@ +/* -*-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)); + +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 + +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 (); +} diff --git a/v7/src/microcode/ntfs.c b/v7/src/microcode/ntfs.c new file mode 100644 index 000000000..20240dfcb --- /dev/null +++ b/v7/src/microcode/ntfs.c @@ -0,0 +1,294 @@ +/* -*-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 + +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 (); +} + +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))); +} + + +/* 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)); +} + +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); +} + + diff --git a/v7/src/microcode/ntio.c b/v7/src/microcode/ntio.c new file mode 100644 index 000000000..922d8ff5e --- /dev/null +++ b/v7/src/microcode/ntio.c @@ -0,0 +1,539 @@ +/* -*-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 + +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; + } +} + +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)); +} + +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); + } + } +} + +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; + } +} + +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; +} + +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; +} + +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); +} + +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); + } +} diff --git a/v7/src/microcode/ntio.h b/v7/src/microcode/ntio.h new file mode 100644 index 000000000..96a9928e8 --- /dev/null +++ b/v7/src/microcode/ntio.h @@ -0,0 +1,89 @@ +/* -*-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 */ + \ No newline at end of file diff --git a/v7/src/microcode/ntsig.c b/v7/src/microcode/ntsig.c new file mode 100644 index 000000000..2184a2ee3 --- /dev/null +++ b/v7/src/microcode/ntsig.c @@ -0,0 +1,1344 @@ +/* -*-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 +/*#include SRA*/ +#include "ossig.h" +#include "osctty.h" +#include "ostty.h" +#include "critsec.h" +/*#include SRA*/ +#include "ntsys.h" +#include "ntexcp.h" +#include "ntkbd.h" +#ifdef USE_ZORTECH_CERROR +#include +#endif + +#ifndef fileno +#define fileno(fp) ((fp)->_file) +#endif + +cc_t EXFUN (DOS_interactive_interrupt_handler, (void)); + +/* Signal Manipulation */ + +#ifdef UNUSED + +static Tsignal_handler +DEFUN (current_handler, (signo), int signo) +{ + Tsignal_handler result = (DOS_signal (signo, SIG_IGN)); + if (result != SIG_IGN) + DOS_signal (signo, result); + return (result); +} + +#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; +} + +#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); +} + +#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 (); +} + +/* 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 */ + +#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; +} + +/* 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; +} + +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); +} + +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) + +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); +} + +cc_t +DEFUN_VOID (DOS_interactive_interrupt_handler) +{ + while (1) + { + unsigned char response; + + console_write_string + ("\nKeyboard interrupt, type character (? for help): "); + + response = (console_read_character ()); + console_write_character (response); + + switch (response) + { + case 'b': + case 'B': + case CONTROL_B: + return CONTROL_B_INTERRUPT_CHAR; + + case 'g': + case 'G': + case CONTROL_G: + return CONTROL_G_INTERRUPT_CHAR; + + case 'i': + case 'I': + return ((cc_t) 0); + + case 'R': + case 'r': + { + extern void EXFUN (soft_reset, (void)); + soft_reset (); + /*NOTREACHED*/ + } + + case 'q': + case 'Q': + { + console_write_string ("\nTerminate scheme (y or n)? "); + response = (console_read_character ()); + console_write_character (response); + if ((response == 'y') || (response == 'Y')) + { + console_write_string ("\n"); + termination_normal (0); + } + print_interrupt_help (); + break; + } + + case 'u': + case 'U': + case CONTROL_U: + return CONTROL_U_INTERRUPT_CHAR; + + case 'x': + case 'X': + case CONTROL_X: + return CONTROL_X_INTERRUPT_CHAR; + + case '?': + print_interrupt_help (); + break; + + default: + { + unsigned char temp[128]; + + sprintf (temp, "\nIllegal interrupt character: [%c]", response); + console_write_string (temp); + print_interrupt_help (); + break; + } + } + } +} + +void +DEFUN_VOID (OS_restartable_exit) +{ + 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 */ + +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 */ + +/* 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 */ + +/* 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); +} + +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; +} + +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)); +} + +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); + + 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; +} + +/* 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")); +} + +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*/ + +#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; +} + +/* 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; +} diff --git a/v7/src/microcode/ntsys.c b/v7/src/microcode/ntsys.c new file mode 100644 index 000000000..2ce63cb13 --- /dev/null +++ b/v7/src/microcode/ntsys.c @@ -0,0 +1,447 @@ +/* -*-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 */ +#include +#include "nt.h" +#include "ntsys.h" + +#ifdef UNUSED +int +dos_keyboard_input_available_p (void) +{ + union REGS regs; + + regs.h.ah = 0x0B; + intdos (®s, ®s); + return (regs.h.al != 0); +} + +unsigned char +dos_get_keyboard_character (void) +{ + union REGS regs; + + regs.h.ah = 0x07; + intdos (®s, ®s); + return ((unsigned char) (regs.h.al)); +} +#endif /* UNUSED */ + +int +dos_poll_keyboard_character (unsigned char * result) +{ +/*SRA + union REGS regs; + + regs.h.ah = 0x06; + regs.h.dl = 0xFF; + intdos (®s, ®s); + *result = ((unsigned char) (regs.h.al)); + return ((regs.x.flags & 0x40) == 0); +*/ + char c; + read(0,&c,1); + *result = c; + return c; +} + +void +dos_console_write_character (unsigned char character) +{ + putchar(character); +} + +int +dos_console_write (void * vbuffer, size_t nsize) +{ + unsigned char * buffer = vbuffer; + int i; + + for (i = 0; i < nsize; i++) + { + putchar(buffer[i]); + } + return (nsize); +} + +/* 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 */ + +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 */ + +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); +} */ + +/* The following code should work at least under X32, Zortech's DOSX, + and Phar Lap 386/DOSX. +*/ + + /*SRA remove the following: */ +#if 0 +extern int DOS_canonicalize_filename (char *, char *); +extern unsigned long RealModeBufferParagraph; +extern char *pRealModeBuffer; + +#pragma ZTC align 1 + +struct rm_interrupt +{ + unsigned short intno; + unsigned short ds; + unsigned short es; + unsigned short fs; + unsigned short gs; + unsigned long eax; + unsigned long edx; +}; + +#pragma ZTC align + +#define RETURN_BUFFER_SIZE 128 + +int +DOS_canonicalize_filename (char * aliased, char * direct) +{ + struct rm_interrupt intrpt; + struct SREGS sregs; + union REGS regs; + + if (pRealModeBuffer == NULL) + return (-1); + strcpy ((pRealModeBuffer + RETURN_BUFFER_SIZE), aliased); + segread (&sregs); + /* Int 21h, ah = 60h: Canonicalize filename or path. */ + intrpt.intno = 0x21; + intrpt.eax = 0x6000; + intrpt.ds = (RealModeBufferParagraph + (RETURN_BUFFER_SIZE >> 4)); + intrpt.es = RealModeBufferParagraph; + regs.e.esi = 0; + regs.e.edi = 0; + regs.e.edx = ((unsigned) &intrpt); + /* Int 21h, ax = 2511h: Issue real mode interrupt. */ + regs.x.ax = 0x2511; + intdosx (®s, ®s, &sregs); + if (regs.e.cflag != 0) + return (-1); + strncpy (direct, pRealModeBuffer, RETURN_BUFFER_SIZE); + return (0); +} +#endif + +#if 0 +extern void DOS_initialize_real_mode (void); +unsigned long RealModeBufferParagraph = 0; +char *pRealModeBuffer = NULL; + +void +DOS_initialize_real_mode (void) +{ + union REGS regs; + + regs.h.ah = 0x48; + regs.x.bx = 256; + intdos (®s, ®s); + if (regs.e.cflag == 0) + { + pRealModeBuffer = ((char *) regs.e.ebx); + RealModeBufferParagraph = regs.x.ax; + } + return; +} +#endif diff --git a/v7/src/microcode/ntsys.h b/v7/src/microcode/ntsys.h new file mode 100644 index 000000000..22414814e --- /dev/null +++ b/v7/src/microcode/ntsys.h @@ -0,0 +1,178 @@ +/* -*-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 + +#define DOS_SUCCESS (0) +#define DOS_FAILURE (-1) +#define dos_boolean int +#define dos_true (1) +#define dos_false (0) + +typedef struct version_struct +{ + unsigned char major; + unsigned char minor; +} version_t; + + # +/* Console Character I/O */ +#ifdef UNUSED +extern int dos_keyboard_input_available_p (void); +extern unsigned char dos_get_keyboard_character (void); +#endif /* UNUSED */ +extern int dos_poll_keyboard_character (unsigned char *result); +extern void dos_console_write_character (unsigned char character); +extern int dos_console_write (void * vbuffer, size_t nsize); + +/* Handle I/O */ +#ifdef UNUSED +typedef int handle_t; + +extern handle_t dos_open_file_with_handle (unsigned char * name, int mode); +extern int dos_close_file_with_handle (handle_t handle); +extern int dos_read_file_with_handle + (handle_t handle, void * buffer, size_t nbytes); +extern int dos_write_file_with_handle + (handle_t handle, void * buffer, size_t nbytes); +extern int dos_get_device_status_with_handle (handle_t handle); +extern int dos_set_device_status_with_handle (handle_t handle, int mode); +#endif /* UNUSED */ + +/* Misc */ +extern void dos_get_version (version_t * version_number); +#ifdef UNUSED +extern void dos_reset_drive (void); +extern int dos_set_verify_flag (int verify_p); +#endif /* UNUSED */ +extern int dos_set_ctrl_c_check_flag (int check_p); +extern int dos_rename_file (const char *old, const char *new); +#ifdef UNUSED +extern int dos_get_machine_name (char *name); +#endif /* UNUSED */ +extern int dos_drive_letter_to_number (char letter); +#ifdef UNUSED +extern char dos_drive_number_to_letter (int number); +extern int dos_get_default_drive (int drive_number); +#endif /* UNUSED */ +extern int dos_set_default_drive (int drive_number); +extern int dos_pathname_as_filename (char * name, char * buffer); +extern int dos_split_filename (char * name, char * device, char * filename); + +/* Keyboard control */ + +extern dos_boolean DOS_keyboard_intercepted_p; +extern int dos_restore_kbd_hook (void); +extern int dos_install_kbd_hook (void); +extern unsigned char dos_set_kbd_modifier_mask (unsigned char); + +/* DOS Interrupt Vectors */ +#define DOS_INTVECT_DIVIDE_BY_0 (0x00) +#define DOS_INTVECT_SINGLE_STEP (0x01) +#define DOS_INTVECT_NMI (0x02) +#define DOS_INTVECT_BREAKPOINT (0x03) +#define DOS_INTVECT_OVERFLOW (0x04) +#define DOS_INTVECT_PRINT_SCREEN (0x05) +#define DOS_INTVECT_INVALID_OPCODE (0x06) +#define DOS_INTVECT_RESERVED_1 (0x07) +#define DOS_INTVECT_SYSTEM_TIMER (0x08) +#define DOS_INTVECT_KEYBOARD_EVENT (0x09) +#define DOS_INTVECT_IRQ2 (0x0A) +#define DOS_INTVECT_IRQ3 (0x0B) +#define DOS_INTVECT_IRQ4 (0x0C) +#define DOS_INTVECT_IRQ5 (0x0D) +#define DOS_INTVECT_DISKETTE_EVENT (0x0E) +#define DOS_INTVECT_IRQ7 (0x0F) +#define DOS_INTVECT_VIDEO (0x10) +#define DOS_INTVECT_EQUIPMENT (0x11) +#define DOS_INTVECT_MEMORY_SIZE (0x12) +#define DOS_INTVECT_DISK_REQUEST (0x13) +#define DOS_INTVECT_COMMUNICATIONS (0x14) +#define DOS_INTVECT_SYSTEM_SERVICES (0x15) +#define DOS_INTVECT_KEYBOARD_REQUEST (0x16) +#define DOS_INTVECT_PRINTER_REQUEST (0x17) +#define DOS_INTVECT_IBM_BASIC (0x18) +#define DOS_INTVECT_BOOTSTRAP (0x19) +#define DOS_INTVECT_SYSTEM_TIMER_2 (0x1A) +#define DOS_INTVECT_KB_CTRL_BREAK (0x1B) +#define DOS_INTVECT_USER_TIMER_TICK (0x1C) +#define DOS_INTVECT_VIDEO_PARAMETERS (0x1D) +#define DOS_INTVECT_DISKETTE_PARAMETERS (0x1E) +#define DOS_INTVECT_GRAPHICS_CHARACTERS (0x1F) +#define DOS_INTVECT_PROGRAM_TERMINATE (0x20) +#define DOS_INTVECT_DOS_REQUEST (0x21) +#define DOS_INTVECT_TERMINATE_ADDRESS (0x22) +#define DOS_INTVECT_DOS_CTRL_BREAK (0x23) +#define DOS_INTVECT_CRITICAL_ERROR (0x24) +#define DOS_INTVECT_ABS_DISK_READ (0x25) +#define DOS_INTVECT_ABS_DISK_WRITE (0x26) +#define DOS_INTVECT_TSR (0x27) +#define DOS_INTVECT_DOS_IDLE (0x28) +#define DOS_INTVECT_DOS_TTY (0x29) +#define DOS_INTVECT_MS_NET (0x2A) +#define DOS_INTVECT_DOS_INTERNAL_1 (0x2B) +#define DOS_INTVECT_DOS_INTERNAL_2 (0x2C) +#define DOS_INTVECT_DOS_INTERNAL_3 (0x2D) +#define DOS_INTVECT_BATCH_EXEC (0x2E) +#define DOS_INTVECT_MULTIPLEX (0x2F) +#define DOS_INTVECT_CPM_JUMP_1 (0x30) +#define DOS_INTVECT_CPM_JUMP_2 (0x31) +#define DOS_INTVECT_RESERVED_2 (0x32) +#define DOS_INTVECT_MS_MOUSE (0x33) +/* Non consecutive */ +#define DOS_INTVECT_DISKETTE_REQUEST (0x40) +#define DOS_INTVECT_FIXED_DISK_1_PARAM (0x41) +#define DOS_INTVECT_EGA_GRAPHICS_CHARS (0x43) +#define DOS_INTVECT_FIXED_DISK_2_PARAM (0x46) +#define DOS_INTVECT_USER_ALARM (0x4A) +#define DOS_INTVECT_PROGRAM_USE_1 (0x60) +#define DOS_INTVECT_PROGRAM_USE_2 (0x61) +#define DOS_INTVECT_PROGRAM_USE_3 (0x62) +#define DOS_INTVECT_PROGRAM_USE_4 (0x63) +#define DOS_INTVECT_PROGRAM_USE_5 (0x64) +#define DOS_INTVECT_PROGRAM_USE_6 (0x65) +#define DOS_INTVECT_PROGRAM_USE_7 (0x66) +#define DOS_INTVECT_EMS_REQUEST (0x67) +#define DOS_INTVECT_REAL_TIME_CLOCK (0x70) +#define DOS_INTVECT_IRQ2_REDIRECT (0x72) +#define DOS_INTVECT_IRQ11 (0x73) +#define DOS_INTVECT_IBM_MOUSE_EVENT (0x74) +#define DOS_INTVECT_COPROCESSOR_ERROR (0x75) +#define DOS_INTVECT_HARD_DISK_EVENT (0x76) +#define DOS_INTVECT_IRQ15 (0x77) + +#define MAX_DOS_INTVECT (0xFF) + +#endif /* SCM_DOSSYS_H */ diff --git a/v7/src/microcode/ntterm.h b/v7/src/microcode/ntterm.h new file mode 100644 index 000000000..28b39a01c --- /dev/null +++ b/v7/src/microcode/ntterm.h @@ -0,0 +1,41 @@ +/* -*-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 */ + \ No newline at end of file diff --git a/v7/src/microcode/nttop.c b/v7/src/microcode/nttop.c new file mode 100644 index 000000000..9b8c1ea0b --- /dev/null +++ b/v7/src/microcode/nttop.c @@ -0,0 +1,222 @@ +/* -*-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; + +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 (); +} + +#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; +} diff --git a/v7/src/microcode/nttop.h b/v7/src/microcode/nttop.h new file mode 100644 index 000000000..12900fa9e --- /dev/null +++ b/v7/src/microcode/nttop.h @@ -0,0 +1,41 @@ +/* -*-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 */ + \ No newline at end of file diff --git a/v7/src/microcode/nttrap.c b/v7/src/microcode/nttrap.c new file mode 100644 index 000000000..831218aa5 --- /dev/null +++ b/v7/src/microcode/nttrap.c @@ -0,0 +1,893 @@ +/* -*-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; + +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); +} + +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 (); + } + } +} + +#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))))); +} + +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); +} + +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); +} + +/* 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 */ + +/* 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); +} + +/* 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)); +} + +/* + 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 */ + diff --git a/v7/src/microcode/nttrap.h b/v7/src/microcode/nttrap.h new file mode 100644 index 000000000..8b2f61fec --- /dev/null +++ b/v7/src/microcode/nttrap.h @@ -0,0 +1,96 @@ +/* -*-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 + +#ifndef SIGINFO_T +#define SIGINFO_T unsigned +#define SIGINFO_VALID_P(info) (1) +#define SIGINFO_CODE(info) (info) +#endif + +/* EIP not included here, not a "register", except on the Vax. + 8 General registers. + 6 Segment registers. + 1 Flags register. + */ + +#define HAVE_SIGCONTEXT +#define HAVE_FULL_SIGCONTEXT +#define PROCESSOR_NREGS (8 + 6 + 1) +#define FULL_SIGCONTEXT_NREGS PROCESSOR_NREGS + +#define SIGCONTEXT sigcontext +#define SIGCONTEXT_SP(scp) ((scp)->sc_esp) +#define SIGCONTEXT_PC(scp) ((scp)->sc_eip) + +#define FULL_SIGCONTEXT SIGCONTEXT +#define FULL_SIGCONTEXT_SP SIGCONTEXT_SP +#define FULL_SIGCONTEXT_PC SIGCONTEXT_PC +#define FULL_SIGCONTEXT_RFREE(scp) ((scp)->sc_edi) +#define FULL_SIGCONTEXT_FIRST_REG(scp) (& (scp->sc_eax)) +#define FULL_SIGCONTEXT_SCHSP FULL_SIGCONTEXT_SP + +#define DECLARE_FULL_SIGCONTEXT(name) \ + struct FULL_SIGCONTEXT * name + +#define INITIALIZE_FULL_SIGCONTEXT(partial, full) \ + ((full) = ((struct FULL_SIGCONTEXT *) (partial))) + +#define INVALID_TRAP -1 + +enum trap_state +{ + trap_state_trapped, + 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 */ + \ No newline at end of file diff --git a/v7/src/microcode/nttterm.c b/v7/src/microcode/nttterm.c new file mode 100644 index 000000000..5b509caaa --- /dev/null +++ b/v7/src/microcode/nttterm.c @@ -0,0 +1,104 @@ +/* -*-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; +} + +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))); +} diff --git a/v7/src/microcode/nttty.c b/v7/src/microcode/nttty.c new file mode 100644 index 000000000..b803c929e --- /dev/null +++ b/v7/src/microcode/nttty.c @@ -0,0 +1,209 @@ +/* -*-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" + +/* 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); +} + +#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; +} + +/* 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); +} -- 2.25.1