diff options
Diffstat (limited to 'src/dosfns.c')
-rw-r--r-- | src/dosfns.c | 215 |
1 files changed, 215 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 */ |