changeset 5503:003e84b91d21

Initial revision
author Richard M. Stallman <rms@gnu.org>
date Sat, 08 Jan 1994 09:22:50 +0000
parents 2b48fd9bc80e
children 6d6d042b3df6
files src/dosfns.c src/dosfns.h src/m/=dos386.h src/msdos.c src/msdos.h src/s/msdos.h
diffstat 6 files changed, 1681 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dosfns.c	Sat Jan 08 09:22:50 1994 +0000
@@ -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, &regs, &regs);
+  regs.x.ax = 0x1101;
+  regs.h.bl = 0;
+  int86 (0x10, &regs, &regs);
+  regs.x.ax = 0x1200;
+  regs.h.bl = 32;
+  int86 (0x10, &regs, &regs);
+  regs.x.ax = 3;
+  int86 (0x10, &regs, &regs);
+  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, &regs, &regs);
+  regs.x.ax = 0x1112;
+  regs.h.bl = 0;
+  int86 (0x10, &regs, &regs);
+  regs.x.ax = 0x1200;
+  regs.h.bl = 32;
+  int86 (0x10, &regs, &regs);
+  regs.x.ax = 0x0100;
+  regs.x.cx = 7;
+  int86 (0x10, &regs, &regs);
+  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 (&regs, &regs);
+  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 (&regs, &regs);
+  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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/dosfns.h	Sat Jan 08 09:22:50 1994 +0000
@@ -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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/m/=dos386.h	Sat Jan 08 09:22:50 1994 +0000
@@ -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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/msdos.c	Sat Jan 08 09:22:50 1994 +0000
@@ -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, &regs, &regs);
+  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, &regs, &regs);
+      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 (&regs, &regs);
+  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, &regs, &regs);
+
+  regs.x.ax = 0x0008;
+  regs.x.cx = 0;
+  regs.x.dx = 8 * (ScreenRows () - 1);
+  int86 (0x33, &regs, &regs);
+
+  mouse_moveto (ScreenCols () - 1, ScreenRows () - 1);
+  mouse_on ();
+}
+
+void
+mouse_on ()
+{
+  union REGS regs;
+
+  regs.x.ax = 0x0001;
+  int86 (0x33, &regs, &regs);
+}
+
+void
+mouse_off ()
+{
+  union REGS regs;
+
+  regs.x.ax = 0x0002;
+  int86 (0x33, &regs, &regs);
+}
+
+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, &regs, &regs);
+}
+
+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, &regs, &regs);
+  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, &regs, &regs);
+  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, &regs, &regs);
+  *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, &regs, &regs);
+  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, &regs, &regs);
+  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 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/msdos.h	Sat Jan 08 09:22:50 1994 +0000
@@ -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 *);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/s/msdos.h	Sat Jan 08 09:22:50 1994 +0000
@@ -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