diff options
-rw-r--r-- | src/dosfns.c | 215 | ||||
-rw-r--r-- | src/dosfns.h | 23 | ||||
-rw-r--r-- | src/m/=dos386.h | 112 | ||||
-rw-r--r-- | src/msdos.c | 1067 | ||||
-rw-r--r-- | src/msdos.h | 45 | ||||
-rw-r--r-- | src/s/msdos.h | 219 |
6 files changed, 1681 insertions, 0 deletions
diff --git a/src/dosfns.c b/src/dosfns.c new file mode 100644 index 00000000000..82af5adb9c2 --- /dev/null +++ b/src/dosfns.c @@ -0,0 +1,215 @@ +/* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991. + Major changes May-July 1993 Morten Welinder (only 10% original code left) + Copyright (C) 1991, 1993 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + + +#include "config.h" + +#ifdef MSDOS +/* The entire file is within this conditional */ + +#include <stdio.h> +#include <dos.h> +#include "lisp.h" +#include "buffer.h" +#include "termchar.h" +#include "termhooks.h" +#include "frame.h" +#include "dosfns.h" +#include "msdos.h" + +static void +mode_resetsize () +{ + Fset_screen_width (ScreenCols (), Qnil); + Fset_screen_height (ScreenRows (), Qnil); +} + +DEFUN ("mode25", Fmode25, Smode25, 0, 0, "", + "Set the number of rows to 25.") + () +{ + union REGS regs; + + if (have_mouse) Mouse_off (); + regs.x.ax = 3; + int86 (0x10, ®s, ®s); + regs.x.ax = 0x1101; + regs.h.bl = 0; + int86 (0x10, ®s, ®s); + regs.x.ax = 0x1200; + regs.h.bl = 32; + int86 (0x10, ®s, ®s); + regs.x.ax = 3; + int86 (0x10, ®s, ®s); + mode_resetsize (); + Frecenter (Qnil); + Fredraw_display (); + if (have_mouse) Mouse_init (); +} + +DEFUN ("mode4350", Fmode4350, Smode4350, 0, 0, "", + "Set the number of rows to 43 (EGA) or 50 (VGA).") + () +{ + union REGS regs; + + if (have_mouse) Mouse_off (); + regs.x.ax = 3; + int86 (0x10, ®s, ®s); + regs.x.ax = 0x1112; + regs.h.bl = 0; + int86 (0x10, ®s, ®s); + regs.x.ax = 0x1200; + regs.h.bl = 32; + int86 (0x10, ®s, ®s); + regs.x.ax = 0x0100; + regs.x.cx = 7; + int86 (0x10, ®s, ®s); + mode_resetsize (); + Frecenter (Qnil); + Fredraw_display (); + if (have_mouse) Mouse_init (); +} + +DEFUN ("int86", Fint86, Sint86, 2, 2, 0, + "Call specific MSDOS interrupt number INTERRUPT with REGISTERS.\n\ +Return the updated REGISTER vector.\n\ +\n\ +INTERRUPT should be an integer in the range 0 to 255.\n\ +REGISTERS should be a vector produced by `make-register' and\n\ +`set-register-value'.") + (intno, regs) + Lisp_Object intno, regs; +{ + register int i; + int no; + union REGS inregs, outregs; + Lisp_Object val; + + CHECK_NUMBER (intno, 0); + no = (unsigned long) XINT (intno); + CHECK_VECTOR (regs, 1); + if (no < 0 || no > 0xff || XVECTOR (regs)-> size != 8) + return Qnil; + for (i = 0; i < 8; i++) + CHECK_NUMBER (XVECTOR (regs)->contents[i], 1); + + inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (regs)->contents[0]); + inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[1]); + inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[2]); + inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[3]); + inregs.x.si = (unsigned long) XFASTINT (XVECTOR (regs)->contents[4]); + inregs.x.di = (unsigned long) XFASTINT (XVECTOR (regs)->contents[5]); + inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (regs)->contents[6]); + inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (regs)->contents[7]); + + int86 (no, &inregs, &outregs); + + XVECTOR (regs)->contents[0] = make_number (outregs.x.ax); + XVECTOR (regs)->contents[1] = make_number (outregs.x.bx); + XVECTOR (regs)->contents[2] = make_number (outregs.x.cx); + XVECTOR (regs)->contents[3] = make_number (outregs.x.dx); + XVECTOR (regs)->contents[4] = make_number (outregs.x.si); + XVECTOR (regs)->contents[5] = make_number (outregs.x.di); + XVECTOR (regs)->contents[6] = make_number (outregs.x.cflag); + XVECTOR (regs)->contents[7] = make_number (outregs.x.flags); + + return regs; +} + +int dos_country_code; +int dos_codepage; +Lisp_Object Vdos_version; + +void +init_dosfns () +{ + union REGS regs; + _go32_dpmi_seginfo info; + _go32_dpmi_registers dpmiregs; + + get_lim_data (); /* why the hell isn't this called elsewhere? */ + + regs.x.ax = 0x3000; + intdos (®s, ®s); + Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah)); + + /* Obtain the country code by calling Dos via Dpmi. Don't rely on GO32. */ + info.size = (34 + 15) / 16; + if (_go32_dpmi_allocate_dos_memory (&info)) + dos_country_code = 1; + else + { + dpmiregs.x.ax = 0x3800; + dpmiregs.x.ds = info.rm_segment; + dpmiregs.x.dx = 0; + dpmiregs.x.ss = dpmiregs.x.sp = 0; + _go32_dpmi_simulate_int (0x21, &dpmiregs); + dos_country_code = dpmiregs.x.bx; + _go32_dpmi_free_dos_memory (&info); + } + + regs.x.ax = 0x6601; + intdos (®s, ®s); + if (regs.x.cflag) + /* Estimate code page from country code */ + switch (dos_country_code) + { + case 45: /* Denmark */ + case 47: /* Norway */ + dos_codepage = 865; + break; + default: + /* US */ + dos_codepage = 437; + } + else + dos_codepage = regs.x.bx & 0xffff; +} + +/* + * Define everything + */ +syms_of_dosfns () +{ + defsubr (&Smode25); + defsubr (&Smode4350); + defsubr (&Sint86); + + DEFVAR_INT ("dos-country-code", &dos_country_code, + "The country code returned by Dos when Emacs was started.\n\ +Usually this is the international telephone prefix."); + + DEFVAR_INT ("dos-codepage", &dos_codepage, + "The codepage active when Emacs was started.\n\ +The following are known: + 437 US + 850 Multilingual + 852 Slavic/Latin II + 857 Turkish + 860 Portugal + 861 Iceland + 863 Canada (French) + 865 Norway/Denmark"); + + DEFVAR_LISP ("dos-version", &Vdos_version, + "The (MAJOR . MINOR) Dos version (subject to modification with setver)."); +} +#endif /* MSDOS */ diff --git a/src/dosfns.h b/src/dosfns.h new file mode 100644 index 00000000000..f27b344bb5c --- /dev/null +++ b/src/dosfns.h @@ -0,0 +1,23 @@ +/* MS-DOS specific Lisp utilities interface. + Coded by Manabu Higashida, 1991. + Copyright (C) 1991 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +extern int dos_country_code; +extern int dos_codepage; +extern Lisp_Object Vdos_version; diff --git a/src/m/=dos386.h b/src/m/=dos386.h new file mode 100644 index 00000000000..defd8f1036e --- /dev/null +++ b/src/m/=dos386.h @@ -0,0 +1,112 @@ +/* Machine description file for MS-DOS + + Copyright (C) 1993 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Note: lots of stuff here was taken from m-dos386.h in demacs. */ + + +/* The following three symbols give information on + the size of various data types. */ + +#define SHORTBITS 16 /* Number of bits in a short */ +#define INTBITS 32 /* Number of bits in an int */ +#define LONGBITS 32 /* Number of bits in a long */ + +/* Define BIG_ENDIAN iff lowest-numbered byte in a word + is the most significant byte. */ + +/* #define BIG_ENDIAN */ + +/* Define NO_ARG_ARRAY if you cannot take the address of the first of a + * group of arguments and treat it as an array of the arguments. */ + +/* #define NO_ARG_ARRAY */ + +/* Define WORD_MACHINE if addresses and such have + * to be corrected before they can be used as byte counts. */ + +/* #define WORD_MACHINE */ + +/* Define how to take a char and sign-extend into an int. + On machines where char is signed, this is a no-op. */ + +#define SIGN_EXTEND_CHAR(c) (c) + +/* Now define a symbol for the cpu type, if your compiler + does not define it automatically: + Ones defined so far include vax, m68000, ns16000, pyramid, + orion, tahoe, APOLLO and many others */ + +#define INTEL386 + +/* Use type int rather than a union, to represent Lisp_Object */ +/* This is desirable for most machines. */ + +#define NO_UNION_TYPE + +/* Define EXPLICIT_SIGN_EXTEND if XINT must explicitly sign-extend + the 24-bit bit field into an int. In other words, if bit fields + are always unsigned. + + If you use NO_UNION_TYPE, this flag does not matter. */ + +#define EXPLICIT_SIGN_EXTEND + +/* Data type of load average, as read out of kmem. */ + +/* #define LOAD_AVE_TYPE long */ + +/* Convert that into an integer that is 100 for a load average of 1.0 */ + +/* #define LOAD_AVE_CVT(x) (int) (((double) (x)) * 100.0 / FSCALE) */ + +/* Define CANNOT_DUMP on machines where unexec does not work. + Then the function dump-emacs will not be defined + and temacs will do (load "loadup") automatically unless told otherwise. */ + +/* #define CANNOT_DUMP */ + +/* Define VIRT_ADDR_VARIES if the virtual addresses of + pure and impure space as loaded can vary, and even their + relative order cannot be relied on. + + Otherwise Emacs assumes that text space precedes data space, + numerically. */ + +/* #define VIRT_ADDR_VARIES */ + +/* Define C_ALLOCA if this machine does not support a true alloca + and the one written in C should be used instead. + Define HAVE_ALLOCA to say that the system provides a properly + working alloca function and it should be used. + Define neither one if an assembler-language alloca + in the file alloca.s should be used. */ + +#define HAVE_ALLOCA +#define alloca(x) __builtin_alloca(x) + +/* Define NO_REMAP if memory segmentation makes it not work well + to change the boundary between the text section and data section + when Emacs is dumped. If you define this, the preloaded Lisp + code will not be sharable; but that's better than failing completely. */ + +#define NO_REMAP + +/* We need a little extra space, see ../../lisp/loadup.el */ +#define PURESIZE 210000 diff --git a/src/msdos.c b/src/msdos.c new file mode 100644 index 00000000000..d0937cf763b --- /dev/null +++ b/src/msdos.c @@ -0,0 +1,1067 @@ +/* MS-DOS specific C utilities. Coded by Morten Welinder 1993 + Copyright (C) 1993 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Note: some of the stuff here was taken from end of sysdep.c in demacs. */ + +#include "config.h" + +#ifdef MSDOS +#include "lisp.h" +#include <stdio.h> +#include <stdlib.h> +#include <sys/param.h> +#include <sys/time.h> +#include <dos.h> +#include "dosfns.h" +#include "msdos.h" +#include "systime.h" +#include "termhooks.h" +#include "frame.h" +#include <go32.h> +#include <pc.h> +#include <ctype.h> +/* #include <process.h> */ +/* Damn that local process.h! Instead we can define P_WAIT ourselves. */ +#define P_WAIT 1 + +static int break_stat; /* BREAK check mode status. */ +static int stdin_stat; /* stdin IOCTL status. */ +static int extended_kbd; /* 101 (102) keyboard present. */ + +int have_mouse; /* Mouse present? */ +static int mouse_last_x; +static int mouse_last_y; + +/* Turn off Dos' Ctrl-C checking and inhibit interpretation of control chars + by Dos. Determine the keyboard type. */ +int +dos_ttraw () +{ + union REGS inregs, outregs; + + inregs.h.ah = 0xc0; + int86 (0x15, &inregs, &outregs); + extended_kbd = (!outregs.x.cflag) && (outregs.h.ah == 0); + + break_stat = getcbrk (); + setcbrk (0); + install_ctrl_break_check (); + have_mouse = Mouse_init1 (); + + inregs.x.ax = 0x4400; /* Get IOCTL status. */ + inregs.x.bx = 0x00; /* 0 = stdin. */ + intdos (&inregs, &outregs); + stdin_stat = outregs.h.dl; + + inregs.x.dx = (outregs.x.dx | 0x0020) & 0x0027; /* raw mode */ + inregs.h.al = 0x01; + intdos (&inregs, &outregs); + return !outregs.x.cflag; +} + +/* Restore status of standard input and Ctrl-C checking. */ +int +dos_ttcooked () +{ + union REGS inregs, outregs; + + setcbrk (break_stat); + if (have_mouse) Mouse_off (); + + inregs.x.ax = 0x4401; /* Set IOCTL status. */ + inregs.x.bx = 0x00; /* 0 = stdin. */ + inregs.x.dx = stdin_stat; + intdos (&inregs, &outregs); + return !outregs.x.cflag; +} + +static unsigned short +ibmpc_translate_map[] = +{ + /* --------------- 00 to 0f --------------- */ + 0, /* Ctrl Break */ + 0xff1b, /* Escape */ + 0xffb1, /* Keypad 1 */ + 0xffb2, /* Keypad 2 */ + 0xffb3, /* Keypad 3 */ + 0xffb4, /* Keypad 4 */ + 0xffb5, /* Keypad 5 */ + 0xffb6, /* Keypad 6 */ + 0xffb7, /* Keypad 7 */ + 0xffb8, /* Keypad 8 */ + 0xffb9, /* Keypad 9 */ + 0xffb0, /* Keypad 0 */ + '-', '=', + 0xff08, /* Backspace */ + 0xff74, /* (Shift) Tab [Tab doesn't use this table] */ + + /* --------------- 10 to 1f --------------- */ + 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', + 0xff8d, /* Keypad Enter */ + 0, /* Ctrl */ + 'a', 's', + + /* --------------- 20 to 2f --------------- */ + 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', + 0, /* Left shift */ + '\\', 'z', 'x', 'c', 'v', + + /* --------------- 30 to 3f --------------- */ + 'b', 'n', 'm', ',', '.', + 0xffaf, /* Grey / */ + 0, /* Right shift */ + 0xffaa, /* Grey * */ + 0, /* Alt */ + ' ', + 0, /* Caps Lock */ + 0xffbe, /* F1 */ + 0xffbf, /* F2 */ + 0xffc0, /* F3 */ + 0xffc1, /* F4 */ + 0xffc2, /* F5 */ + + /* --------------- 40 to 4f --------------- */ + 0xffc3, /* F6 */ + 0xffc4, /* F7 */ + 0xffc5, /* F8 */ + 0xffc6, /* F9 */ + 0xffc7, /* F10 */ + 0, /* Num Lock */ + 0, /* Scroll Lock */ + 0xff50, /* Home */ + 0xff52, /* Up */ + 0xff55, /* Page Up */ + 0xffad, /* Grey - */ + 0xff51, /* Left */ + 0xffb5, /* Keypad 5 */ + 0xff53, /* Right */ + 0xffab, /* Grey + */ + 0xff57, /* End */ + + /* --------------- 50 to 5f --------------- */ + 0xff54, /* Down */ + 0xff56, /* Page Down */ + 0xff63, /* Insert */ + 0xffff, /* Delete */ + 0xffbe, /* (Shift) F1 */ + 0xffbf, /* (Shift) F2 */ + 0xffc0, /* (Shift) F3 */ + 0xffc1, /* (Shift) F4 */ + 0xffc2, /* (Shift) F5 */ + 0xffc3, /* (Shift) F6 */ + 0xffc4, /* (Shift) F7 */ + 0xffc5, /* (Shift) F8 */ + 0xffc6, /* (Shift) F9 */ + 0xffc7, /* (Shift) F10 */ + 0xffbe, /* (Ctrl) F1 */ + 0xffbf, /* (Ctrl) F2 */ + + /* --------------- 60 to 6f --------------- */ + 0xffc0, /* (Ctrl) F3 */ + 0xffc1, /* (Ctrl) F4 */ + 0xffc2, /* (Ctrl) F5 */ + 0xffc3, /* (Ctrl) F6 */ + 0xffc4, /* (Ctrl) F7 */ + 0xffc5, /* (Ctrl) F8 */ + 0xffc6, /* (Ctrl) F9 */ + 0xffc7, /* (Ctrl) F10 */ + 0xffbe, /* (Alt) F1 */ + 0xffbf, /* (Alt) F2 */ + 0xffc0, /* (Alt) F3 */ + 0xffc1, /* (Alt) F4 */ + 0xffc2, /* (Alt) F5 */ + 0xffc3, /* (Alt) F6 */ + 0xffc4, /* (Alt) F7 */ + 0xffc5, /* (Alt) F8 */ + + /* --------------- 70 to 7f --------------- */ + 0xffc6, /* (Alt) F9 */ + 0xffc7, /* (Alt) F10 */ + 0xff6d, /* (Ctrl) Sys Rq */ + 0xff51, /* (Ctrl) Left */ + 0xff53, /* (Ctrl) Right */ + 0xff57, /* (Ctrl) End */ + 0xff56, /* (Ctrl) Page Down */ + 0xff50, /* (Ctrl) Home */ + '1', '2', '3', '4', '5', '6', '7', '8', /* (Alt) */ + + /* --------------- 80 to 8f --------------- */ + '9', '0', '-', '=', /* (Alt) */ + 0xff55, /* (Ctrl) Page Up */ + 0xffc8, /* F11 */ + 0xffc9, /* F12 */ + 0xffc8, /* (Shift) F11 */ + 0xffc9, /* (Shift) F12 */ + 0xffc8, /* (Ctrl) F11 */ + 0xffc9, /* (Ctrl) F12 */ + 0xffc8, /* (Alt) F11 */ + 0xffc9, /* (Alt) F12 */ + 0xff52, /* (Ctrl) Up */ + 0xffae, /* (Ctrl) Grey - */ + 0xffb5, /* (Ctrl) Keypad 5 */ + + /* --------------- 90 to 9f --------------- */ + 0xffab, /* (Ctrl) Grey + */ + 0xff54, /* (Ctrl) Down */ + 0xff63, /* (Ctrl) Insert */ + 0xffff, /* (Ctrl) Delete */ + 0xff09, /* (Ctrl) Tab */ + 0xffaf, /* (Ctrl) Grey / */ + 0xffaa, /* (Ctrl) Grey * */ + 0xff50, /* (Alt) Home */ + 0xff52, /* (Alt) Up */ + 0xff55, /* (Alt) Page Up */ + 0, /* NO KEY */ + 0xff51, /* (Alt) Left */ + 0, /* NO KEY */ + 0xff53, /* (Alt) Right */ + 0, /* NO KEY */ + 0xff57, /* (Alt) End */ + + /* --------------- a0 to af --------------- */ + 0xff54, /* (Alt) Down */ + 0xff56, /* (Alt) Page Down */ + 0xff63, /* (Alt) Insert */ + 0xffff, /* (Alt) Delete */ + 0xffaf, /* (Alt) Grey / */ + 0xff09, /* (Alt) Tab */ + 0xff0d /* (Alt) Enter */ +}; + +/* Get a char from keyboard. Function keys are put into the event queue. */ +static int +dos_rawgetc () +{ + struct input_event event; + struct timeval tv; + union REGS regs; + int ctrl_p, alt_p, shift_p; + + /* Calculate modifier bits */ + regs.h.ah = extended_kbd ? 0x12 : 0x02; + int86 (0x16, ®s, ®s); + ctrl_p = ((regs.h.al & 4) != 0); + shift_p = ((regs.h.al & 3) != 0); + alt_p = ((extended_kbd ? (regs.h.ah & 2) : (regs.h.al & 8)) != 0); + + while (kbhit ()) + { + union REGS regs; + register unsigned char c; + int sc, code; + + regs.h.ah = extended_kbd ? 0x10 : 0x00; + int86 (0x16, ®s, ®s); + c = regs.h.al; + sc = regs.h.ah; + + /* Determine from the scan code if a keypad key was pressed. */ + if (c >= '0' && c <= '9' && sc > 0xb) + sc = (c == '0') ? 0xb : (c - '0' + 1), c = 0; + else if (sc == 0xe0) + { + switch (c) + { + case 10: /* Ctrl Enter */ + case 13: + sc = 0x1c; + break; + case '.': /* Decimal point or decimal comma */ + case ',': + sc = 0x53; + break; + case '/': + sc = 0x35; + break; + default: + sc = 0; + }; + c = 0; + } + + if (c == 0 + || c == ' ' + || alt_p + || (ctrl_p && shift_p) + || (c == 0xe0 && sc != 0) /* Pseudo-key */ + || sc == 0x37 /* Grey * */ + || sc == 0x4a /* Grey - */ + || sc == 0x4e /* Grey + */ + || sc == 0x0e) /* Back space *key*, not Ctrl-h */ + { + if (sc >= (sizeof (ibmpc_translate_map) / sizeof (short))) + code = 0; + else + code = ibmpc_translate_map[sc]; + if (code != 0) + { + if (code >= 0x100) + { + event.kind = non_ascii_keystroke; + event.code = code & 0xff; + } + else + { + /* Don't return S- if we don't have to. */ + if (code >= 'a' && code <= 'z') + { + c = shift_p ? toupper (code) : code; + shift_p = 0; + } + else + if (c == 0) c = code; + event.kind = ascii_keystroke; + event.code = c; + } + event.modifiers + = (shift_p ? shift_modifier : 0) + + (ctrl_p ? ctrl_modifier : 0) + + (alt_p ? meta_modifier : 0); + /* EMACS == Enter Meta Alt Control Shift */ + event.frame_or_window = selected_frame; + gettimeofday (&tv, NULL); + event.timestamp = tv.tv_usec; + kbd_buffer_store_event (&event); + } + } else + return c; + } + + if (have_mouse) + { + int but, press, x, y, ok; + + /* Check for mouse movement *before* buttons. */ + Mouse_check_moved (); + + for (but = 0; but < NUM_MOUSE_BUTTONS; but++) + for (press = 0; press < 2; press++) + { + if (press) + ok = Mouse_pressed (but, &x, &y); + else + ok = Mouse_released (but, &x, &y); + if (ok) + { + event.kind = mouse_click; + event.code = but; + event.modifiers + = (shift_p ? shift_modifier : 0) + + (ctrl_p ? ctrl_modifier : 0) + + (alt_p ? meta_modifier : 0) + + (press ? down_modifier : up_modifier); + event.x = x; + event.y = y; + event.frame_or_window = selected_frame; + gettimeofday (&tv, NULL); + event.timestamp = tv.tv_usec; + kbd_buffer_store_event (&event); + } + } + } + + return -1; +} + +static int prev_get_char = -1; + +/* Return 1 if a key is ready to be read without suspending execution. */ +dos_keysns () +{ + if (prev_get_char != -1) + return 1; + else + return ((prev_get_char = dos_rawgetc ()) != -1); +} + +/* Read a key. Return -1 if no key is ready. */ +dos_keyread () +{ + if (prev_get_char != -1) + { + int c = prev_get_char; + prev_get_char = -1; + return c; + } + else + return dos_rawgetc (); +} + +/* Hostnames for a pc are not really funny, but they are used in change log + so we emulate the best we can. */ +gethostname (p, size) + char *p; + int size; +{ + char *q = egetenv ("HOSTNAME"); + + if (!q) q = "pc"; + strcpy (p, q); + return 0; +} + +/* Destructively turn backslashes into slashes. */ +void +dostounix_filename (p) + register char *p; +{ + while (*p) + { + if (*p == '\\') + *p = '/'; + p++; + } +} + +/* Destructively turn slashes into backslashes. */ +void +unixtodos_filename (p) + register char *p; +{ + while (*p) + { + if (*p == '/') + *p = '\\'; + p++; + } +} + +/* Get the default directory for a given drive. 0=def, 1=A, 2=B, ... */ +int +getdefdir (drive, dst) + int drive; + char *dst; +{ + union REGS regs; + + *dst++ = '/'; + regs.h.dl = drive; + regs.x.si = (int) dst; + regs.h.ah = 0x47; + intdos (®s, ®s); + return !regs.x.cflag; +} + +/* Remove all CR's that are followed by a LF. */ +int +crlf_to_lf (n, buf) + register int n; + register unsigned char *buf; +{ + unsigned char *np = buf; + unsigned char *startp = buf; + unsigned char *endp = buf + n; + unsigned char c; + + if (n == 0) + return n; + while (buf < endp) + { + if (*buf == 0x0d) + { + if (*(++buf) != 0x0a) + *np++ = 0x0d; + } + else + *np++ = *buf++; + } + return np - startp; +} + + +/* Run command as specified by ARGV in directory DIR. + The command is run with input from TEMPIN and output to file TEMPOUT. */ +int +run_msdos_command (argv, dir, tempin, tempout) + unsigned char **argv; + Lisp_Object dir; + int tempin, tempout; +{ + char *saveargv1, *saveargv2, **envv; + char oldwd[MAXPATHLEN + 1]; /* Fixed size is safe on MSDOS. */ + int msshell, result = -1; + int in, out, inbak, outbak, errbak; + Lisp_Object cmd; + + /* Get current directory as MSDOS cwd is not per-process. */ + getwd (oldwd); + + cmd = Ffile_name_nondirectory (build_string (argv[0])); + msshell = !NILP (Fmember (cmd, Fsymbol_value (intern ("msdos-shells")))) + && !strcmp ("-c", argv[1]); + if (msshell) + { + saveargv1 = argv[1]; + argv[1] = "/c"; + if (argv[2]) + { + saveargv2 = argv[2]; + unixtodos_filename (argv[2] = strdup (argv[2])); + } + } + + /* Build the environment array. */ + { + extern Lisp_Object Vprocess_environment; + Lisp_Object tmp, lst = Vprocess_environment; + int i, len = XFASTINT (Flength (lst)); + + envv = alloca ((len + 1) * sizeof (char *)); + for (i = 0; i < len; i++) + { + tmp = Fcar (lst); + lst = Fcdr (lst); + CHECK_STRING (tmp, 0); + envv[i] = alloca (XSTRING (tmp)->size + 1); + strcpy (envv[i], XSTRING (tmp)->data); + } + envv[len] = (char *) 0; + } + + if (XTYPE (dir) == Lisp_String) + chdir (XSTRING (dir)->data); + inbak = dup (0); + outbak = dup (1); + errbak = dup (2); + if (inbak < 0 || outbak < 0 || errbak < 0) + goto done; /* Allocation might fail due to lack of descriptors. */ + dup2 (tempin, 0); + dup2 (tempout, 1); + dup2 (tempout, 2); + dos_ttcooked (); + result = spawnve (P_WAIT, argv[0], argv, envv); + dos_ttraw (); + dup2 (inbak, 0); + dup2 (outbak, 1); + dup2 (errbak, 2); + + done: + chdir (oldwd); + if (msshell) + { + argv[1] = saveargv1; + if (argv[2]) + { + free (argv[2]); + argv[2] = saveargv2; + } + } + return result; +} + + +croak (badfunc) + char *badfunc; +{ + fprintf (stderr, "%s not yet implemented\r\n", badfunc); + reset_sys_modes (); + exit (1); +} + +/* A list of unimplemented functions that we silently ignore. */ +unsigned alarm (s) unsigned s; {} +fork () { return 0; } +int kill (x, y) int x, y; { return -1; } +nice (p) int p; {} +void volatile pause () {} +request_sigio () {} +setpgrp () {return 0; } +setpriority (x,y,z) int x,y,z; { return 0; } +sigsetmask (x) int x; { return 0; } +unrequest_sigio () {} + +#ifdef chdir +#undef chdir +#endif + +int +sys_chdir (path) + const char* path; +{ + int len = strlen (path); + char *tmp = (char *) alloca (len + 1); + /* Gotta do this extern here due to the corresponding #define: */ + extern int chdir (); + + if (*path && path[1] == ':' && (getdisk () != tolower (path[0]) - 'a')) + setdisk (tolower (path[0]) - 'a'); + + strcpy (tmp, path); + if (strcmp (path, "/") && strcmp (path + 1, ":/") && (path[len - 1] == '/')) + tmp[len - 1] = 0; + return chdir (tmp); +} + +/* Sleep SECS. If KBDOK also return immediately if a key is pressed. */ +void +sleep_or_kbd_hit (secs, kbdok) + int secs, kbdok; +{ + long clnow, clthen; + struct timeval t; + + gettimeofday (&t, NULL); + clnow = t.tv_sec * 100 + t.tv_usec / 10000; + clthen = clnow + (100 * secs); + + do + { + gettimeofday (&t, NULL); + clnow = t.tv_sec * 100 + t.tv_usec / 10000; + if (kbdok && detect_input_pending ()) + return; + } + while (clnow < clthen); +} + +/* Define a lot of environment variables if not already defined. Don't + remove anything unless you know what you're doing -- lots of code will + break if one or more of these are missing. */ +void +init_environment (argc, argv, skip_args) + int argc; + char **argv; + int skip_args; +{ + char *s, *t; + + /* We default HOME to the directory from which Emacs was started, but with + a "/bin" suffix removed. */ + s = argv[0]; + t = alloca (strlen (s) + 1); + strcpy (t, s); + s = t + strlen (t); + while (s != t && *s != '/' && *s != ':') s--; + if (s == t) + t = "c:/emacs"; /* When run under debug32. */ + else + { + if (*s == ':') s++; + *s = 0; + if (s - 4 >= t && strcmp (s - 4, "/bin") == 0) + s[strlen (s) - 4] = 0; + } + setenv ("HOME", t, 0); + + /* We set EMACSPATH to ~/bin (expanded) */ + s = getenv ("HOME"); + t = strcpy (alloca (strlen (s) + 6), s); + if (s[strlen (s) - 1] != '/') strcat (t, "/"); + strcat (t, "bin"); + setenv ("EMACSPATH", t, 0); + + /* I don't expect anybody to ever use other terminals so the internal + terminal is the default. */ + setenv ("TERM", "internal", 0); + + /* SHELL is a bit tricky -- COMSPEC is the closest we come, but we must + downcase it and mirror the backslashes. */ + s = getenv ("COMSPEC"); + if (!s) s = "c:/command.com"; + t = alloca (strlen (s) + 1); + strcpy (t, s); + strlwr (t); + dostounix_filename (t); + setenv ("SHELL", t, 0); + + /* PATH is also downcased and backslashes mirrored. */ + s = getenv ("PATH"); + if (!s) s = ""; + t = alloca (strlen (s) + 3); + /* Current directory is always considered part of MsDos's path but it is + not normally mentioned. Now it is. */ + strcat (strcpy (t, ".;"), s); + strlwr (t); + dostounix_filename (t); /* Not a single file name, but this should work. */ + setenv ("PATH", t, 1); + + /* In some sense all dos users have root privileges, so... */ + setenv ("USER", "root", 0); + setenv ("NAME", getenv ("USER"), 0); + + /* Time zone determined from country code. To make this possible, the + country code may not span more than one time zone. In other words, + in the USA, you lose. */ + switch (dos_country_code) + { + case 31: /* Belgium */ + case 32: /* The Netherlands */ + case 33: /* France */ + case 34: /* Spain */ + case 36: /* Hungary */ + case 38: /* Yugoslavia (or what's left of it?) */ + case 39: /* Italy */ + case 41: /* Switzerland */ + case 42: /* Tjekia */ + case 45: /* Denmark */ + case 46: /* Sweden */ + case 47: /* Norway */ + case 48: /* Poland */ + case 49: /* Germany */ + /* Daylight saving from last Sunday in March to last Sunday in + September, both at 2AM. */ + setenv ("TZ", "MET-01METDST-02,M3.5.0/02:00,M9.5.0/02:00", 0); + break; + case 44: /* United Kingdom */ + case 351: /* Portugal */ + case 354: /* Iceland */ + setenv ("TZ", "GMT+00", 0); + break; + case 81: /* Japan */ + case 82: /* Korea */ + setenv ("TZ", "???-09", 0); + break; + case 90: /* Turkey */ + case 358: /* Finland */ + case 972: /* Israel */ + setenv ("TZ", "EET-02", 0); + break; + } + tzset (); +} + +/* Flash the screen as a substitute for BEEPs. */ + +static unsigned char _xorattr; + +void +visible_bell (xorattr) + unsigned char xorattr; +{ + _xorattr = xorattr; + asm (" pushl %eax + pushl %ebx + pushl %ecx + pushl %edx + movl $1,%edx +visible_bell_0: + movl _ScreenPrimary,%eax + call dosmemsetup + movl %eax,%ebx + call _ScreenRows + movl %eax,%ecx + call _ScreenCols + imull %eax,%ecx + movb (__xorattr),%al + incl %ebx +visible_bell_1: + xorb %al,%gs:(%ebx) + addl $2,%ebx + decl %ecx + jne visible_bell_1 + decl %edx + jne visible_bell_3 +visible_bell_2: + movzwl %ax,%eax + movzwl %ax,%eax + movzwl %ax,%eax + movzwl %ax,%eax + decw %cx + jne visible_bell_2 + jmp visible_bell_0 +visible_bell_3: + popl %edx + popl %ecx + popl %ebx + popl %eax"); +} + +static int internal_terminal = 0; +#undef fflush + +int +internal_flush (f) + FILE *f; +{ + static int x; + static int y; + char c, *cp; + int count, i; + + if (internal_terminal && f == stdout) + { + if (have_mouse) Mouse_off (); + cp = stdout->_base; + count = stdout->_ptr - stdout->_base; + while (count > 0) + { + switch (c = *cp++) + { + case 27: + switch (*cp++) + { + case '@': + y = *cp++; + x = *cp++; + count -= 4; + break; + case 'A': + ScreenAttrib = *cp++; + count -= 3; + break; + case 'B': + visible_bell (*cp++); + count -= 3; + break; + case 'C': + ScreenClear (); + x = y = 0; + count -= 2; + break; + case 'E': + for (i = ScreenCols () - 1; i >= x; i--) + ScreenPutChar (' ', ScreenAttrib, i, y); + count -= 2; + break; + case 'R': + x++; + count -= 2; + break; + case 'U': + y--; + count -= 2; + break; + case 'X': + ScreenAttrib ^= *cp++; + count -= 3; + break; + default: + count -= 2; + } + break; + case 8: + x--; + count--; + break; + case 13: + x = 0; + count--; + break; + case 10: + y++; + count--; + break; + default: + ScreenPutChar (c, ScreenAttrib, x++, y); + count--; + } + } + fpurge (stdout); + ScreenSetCursor (y, x); + if (have_mouse) Mouse_on (); + } + else + /* This is a call to the original fflush. */ + fflush (f); +} + +/* Do we need the internal terminal? */ +void +internal_terminal_init () +{ + char *term = getenv ("TERM"); + + internal_terminal + = (!noninteractive) && term && !strcmp (term, "internal"); +} + +/* These must be global. */ +static _go32_dpmi_seginfo ctrl_break_vector; +static _go32_dpmi_registers ctrl_break_regs; +static int ctrlbreakinstalled = 0; + +/* Interrupt level detection of Ctrl-Break. Don't do anything fancy here! */ +void +ctrl_break_func (regs) + _go32_dpmi_registers *regs; +{ + Vquit_flag = Qt; +} + +void +install_ctrl_break_check () +{ + if (!ctrlbreakinstalled) + { + /* Don't press Ctrl-Break if you don't have either DPMI or Emacs + was compiler with Djgpp 1.11 maintenance level 2 or later! */ + ctrlbreakinstalled = 1; + ctrl_break_vector.pm_offset = (int) ctrl_break_func; + _go32_dpmi_allocate_real_mode_callback_iret (&ctrl_break_vector, + &ctrl_break_regs); + _go32_dpmi_set_real_mode_interrupt_vector (0x1b, &ctrl_break_vector); + } +} + + +/* Mouse routines under devellopment follow. Coordinates are in screen + positions and zero based. Mouse buttons are numbered from left to + right and also zero based. */ + +static int mouse_button_translate[NUM_MOUSE_BUTTONS]; +static int mouse_button_count; + +void +mouse_init () +{ + union REGS regs; + + regs.x.ax = 0x0007; + regs.x.cx = 0; + regs.x.dx = 8 * (ScreenCols () - 1); + int86 (0x33, ®s, ®s); + + regs.x.ax = 0x0008; + regs.x.cx = 0; + regs.x.dx = 8 * (ScreenRows () - 1); + int86 (0x33, ®s, ®s); + + mouse_moveto (ScreenCols () - 1, ScreenRows () - 1); + mouse_on (); +} + +void +mouse_on () +{ + union REGS regs; + + regs.x.ax = 0x0001; + int86 (0x33, ®s, ®s); +} + +void +mouse_off () +{ + union REGS regs; + + regs.x.ax = 0x0002; + int86 (0x33, ®s, ®s); +} + +void +mouse_moveto (x, y) + int x, y; +{ + union REGS regs; + + regs.x.ax = 0x0004; + mouse_last_x = regs.x.cx = x * 8; + mouse_last_y = regs.x.dx = y * 8; + int86 (0x33, ®s, ®s); +} + +int +mouse_pressed (b, xp, yp) + int b, *xp, *yp; +{ + union REGS regs; + + if (b >= mouse_button_count) + return 0; + regs.x.ax = 0x0005; + regs.x.bx = mouse_button_translate[b]; + int86 (0x33, ®s, ®s); + if (regs.x.bx) + *xp = regs.x.cx / 8, *yp = regs.x.dx /8; + return (regs.x.bx != 0); +} + +int +mouse_released (b, xp, yp) + int b, *xp, *yp; +{ + union REGS regs; + + if (b >= mouse_button_count) + return 0; + regs.x.ax = 0x0006; + regs.x.bx = mouse_button_translate[b]; + int86 (0x33, ®s, ®s); + if (regs.x.bx) + *xp = regs.x.cx / 8, *yp = regs.x.dx / 8; + return (regs.x.bx != 0); +} + +void +mouse_get_pos (f, bar_window, part, x, y, time) + FRAME_PTR *f; + Lisp_Object *bar_window, *x, *y; + enum scroll_bar_part *part; + unsigned long *time; +{ + union REGS regs; + struct timeval tv; + + regs.x.ax = 0x0003; + int86 (0x33, ®s, ®s); + *f = selected_frame; + *bar_window = Qnil; + gettimeofday (&tv, NULL); + *x = make_number (regs.x.cx / 8); + *y = make_number (regs.x.dx / 8); + *time = tv.tv_usec; + mouse_moved = 0; +} + +void +mouse_check_moved () +{ + union REGS regs; + + regs.x.ax = 0x0003; + int86 (0x33, ®s, ®s); + if (regs.x.cx != mouse_last_x || regs.x.dx != mouse_last_y) + { + mouse_moved = 1; + mouse_last_x = regs.x.cx; + mouse_last_y = regs.x.dx; + } +} + +int +mouse_init1 () +{ + union REGS regs; + int present; + + regs.x.ax = 0x0021; + int86 (0x33, ®s, ®s); + present = internal_terminal && (regs.x.ax & 0xffff) == 0xffff; + if (present) + { + if (regs.x.bx == 3) + { + mouse_button_count = 3; + mouse_button_translate[0] = 0; /* Left */ + mouse_button_translate[1] = 2; /* Middle */ + mouse_button_translate[2] = 1; /* Right */ + } + else + { + mouse_button_count = 2; + mouse_button_translate[0] = 0; + mouse_button_translate[1] = 1; + } + mouse_position_hook = &mouse_get_pos; + mouse_init (); + } + return present; +} + +#endif /* MSDOS */ diff --git a/src/msdos.h b/src/msdos.h new file mode 100644 index 00000000000..bf3030c00df --- /dev/null +++ b/src/msdos.h @@ -0,0 +1,45 @@ +/* MS-DOS specific C utilities, interface. + Copyright (C) 1993 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include <time.h> +#include <dpmi.h> + +int dos_ttraw (); +int dos_ttcooked (); +int getdefdir (int, char*); +void unixtodos_filename (char *); +void dostounix_filename (char *); +void sleep_or_kbd_hit (int, int); +void init_environment (); +void internal_terminal_init (); +#ifndef _stdio_h_ +int internal_flush (FILE *); +#endif +void ctrl_break_func (_go32_dpmi_registers *); +void install_ctrl_break_check (); + +extern int have_mouse; +int mouse_init1 (); +void mouse_init (); +void mouse_on (); +void mouse_off (); +void mouse_moveto (int, int); +void mouse_check_moved (); +int mouse_pressed (int, int *, int *); +int mouse_released (int, int *, int *); diff --git a/src/s/msdos.h b/src/s/msdos.h new file mode 100644 index 00000000000..10c15ee682e --- /dev/null +++ b/src/s/msdos.h @@ -0,0 +1,219 @@ +/* System description file for MS-DOS + + Copyright (C) 1993 Free Software Foundation, Inc. + +This file is part of GNU Emacs. + +GNU Emacs is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Emacs is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Emacs; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* Note: lots of stuff here was taken from s-msdos.h in demacs. */ + + +/* + * Define symbols to identify the version of Unix this is. + * Define all the symbols that apply correctly. + */ + +/* #define UNIPLUS */ +/* #define USG5 */ +/* #define USG */ +/* #define HPUX */ +/* #define UMAX */ +/* #define BSD4_1 */ +/* #define BSD4_2 */ +/* #define BSD4_3 */ +/* #define BSD */ +/* #define VMS */ +#ifndef MSDOS +#define MSDOS +#endif +#undef BSD +#undef VMS + +/* SYSTEM_TYPE should indicate the kind of system you are using. + It sets the Lisp variable system-type. */ + +#define SYSTEM_TYPE "ms-dos" + +#define SYMS_SYSTEM syms_of_dosfns() + +/* NOMULTIPLEJOBS should be defined if your system's shell + does not have "job control" (the ability to stop a program, + run some other program, then continue the first one). */ + +#define NOMULTIPLEJOBS + +/* Emacs can read input using SIGIO and buffering characters itself, + or using CBREAK mode and making C-g cause SIGINT. + The choice is controlled by the variable interrupt_input. + Define INTERRUPT_INPUT to make interrupt_input = 1 the default (use SIGIO) + + SIGIO can be used only on systems that implement it (4.2 and 4.3). + CBREAK mode has two disadvatages + 1) At least in 4.2, it is impossible to handle the Meta key properly. + I hear that in system V this problem does not exist. + 2) Control-G causes output to be discarded. + I do not know whether this can be fixed in system V. + + Another method of doing input is planned but not implemented. + It would have Emacs fork off a separate process + to read the input and send it to the true Emacs process + through a pipe. +*/ + +/* #define INTERRUPT_INPUT */ + +/* Letter to use in finding device name of first pty, + if system supports pty's. 'a' means it is /dev/ptya0 */ + +/* #define FIRST_PTY_LETTER 'a' */ + +/* + * Define HAVE_TIMEVAL if the system supports the BSD style clock values. + * Look in <sys/time.h> for a timeval structure. + */ + +#define HAVE_TIMEVAL + +/* + * Define HAVE_SELECT if the system supports the `select' system call. + */ + +/* #define HAVE_SELECT */ + +/* + * Define HAVE_PTYS if the system supports pty devices. + */ + +/* #define HAVE_PTYS */ + +/* + * Define NONSYSTEM_DIR_LIBRARY to make Emacs emulate + * The 4.2 opendir, etc., library functions. + */ + +/* #define NONSYSTEM_DIR_LIBRARY */ + +#define SYSV_SYSTEM_DIR + +/* Define this symbol if your system has the functions bcopy, etc. */ + +#define BSTRING + +/* subprocesses should be defined if you want to + have code for asynchronous subprocesses + (as used in M-x compile and M-x shell). + This is generally OS dependent, and not supported + under most USG systems. */ + +#undef subprocesses + +/* If your system uses COFF (Common Object File Format) then define the + preprocessor symbol "COFF". */ + +#define COFF + +/* define MAIL_USE_FLOCK if the mailer uses flock + to interlock access to /usr/spool/mail/$USER. + The alternative is that a lock file named + /usr/spool/mail/$USER.lock. */ + +/* #define MAIL_USE_FLOCK */ + +/* Define CLASH_DETECTION if you want lock files to be written + so that Emacs can tell instantly when you try to modify + a file that someone else has modified in his Emacs. */ + +/* #define CLASH_DETECTION */ + +/* Here, on a separate page, add any special hacks needed + to make Emacs work on this system. For example, + you might define certain system call names that don't + exist on your system, or that do different things on + your system and must be used only through an encapsulation + (Which you should place, by convention, in sysdep.c). */ + +/* Some compilers tend to put everything declared static + into the initialized data area, which becomes pure after dumping Emacs. + On these systems, you must #define static as nothing to foil this. + Note that emacs carefully avoids static vars inside functions. */ + +/* #define static */ + +/* we use djgcc's malloc */ +/* #define SYSTEM_MALLOC */ +/* setjmp and longjmp can safely replace _setjmp and _longjmp, + but they will run slower. */ + +#define _setjmp setjmp +#define _longjmp longjmp + +#define NO_MODE_T + +/* we can use dj's getpagesize() */ +#define HAVE_GETPAGESIZE + +/* New chdir () routine. */ +#ifdef chdir +#undef chdir +#endif +#define chdir sys_chdir + +#define LIBS_SYSTEM -lpc + +/* This somehow needs to be defined even though we use COFF. */ +#define TEXT_START -1 + +#define ORDINARY_LINK + +/* command.com does not under stand `...` so we define this. */ +#define LIB_GCC -Lgcc +#define DONT_NEED_ENVIRON +#define SEPCHAR ';' + +#define NULL_DEVICE "nul" +#define EXEC_SUFFIXES ".exe:.com:.bat:" + +#define O_RDONLY 0x0001 +#define O_WRONLY 0x0002 +#define O_RDWR 0x0004 +#define O_CREAT 0x0100 +#define O_TRUNC 0x0200 +#define O_EXCL 0x0400 +#define O_APPEND 0x0800 +#define O_TEXT 0x4000 +#define O_BINARY 0x8000 + +#define HAVE_INVERSE_HYPERBOLIC +#define FLOAT_CHECK_DOMAIN + +/* When $TERM is "internal" then this is substituted: */ +#define INTERNAL_TERMINAL "pc|bios|IBM PC with colour display:\ +:co#80:li#25:km:\ +:cm=\E@%.%.:\ +:do=^J:le=^H:up=\EU:ri=\ER:\ +:ti=\EA\027:te=\EA\007\EE:\ +:so=\EA\077:se=\EA\027:\ +:ms:mb=\EX\200:md=\EX\010:mk=\EA\161:me=\EA\027:\ +:cl=\EC:ce=\EE:\ +:vb=\EB\140:bl=:" +#define fflush internal_flush + +/* Define this to a function (Fdowncase, Fupcase) if your file system + likes that */ +#define FILE_SYSTEM_CASE Fdowncase + +/* MSDOS doesn't really have this function. */ +#define getppid() 1 |