Initial revision
[bpt/emacs.git] / src / dosfns.c
CommitLineData
1b94449f
RS
1/* MS-DOS specific Lisp utilities. Coded by Manabu Higashida, 1991.
2 Major changes May-July 1993 Morten Welinder (only 10% original code left)
3 Copyright (C) 1991, 1993 Free Software Foundation, Inc.
4
5This file is part of GNU Emacs.
6
7GNU Emacs is free software; you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published by
9the Free Software Foundation; either version 1, or (at your option)
10any later version.
11
12GNU Emacs is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15GNU General Public License for more details.
16
17You should have received a copy of the GNU General Public License
18along with GNU Emacs; see the file COPYING. If not, write to
19the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
20
21
48984716 22#include <config.h>
1b94449f
RS
23
24#ifdef MSDOS
25/* The entire file is within this conditional */
26
27#include <stdio.h>
28#include <dos.h>
29#include "lisp.h"
30#include "buffer.h"
31#include "termchar.h"
32#include "termhooks.h"
33#include "frame.h"
34#include "dosfns.h"
35#include "msdos.h"
36
24ba360b
RS
37DEFUN ("mode25", Fmode25, Smode25, 0, 0, "", "\
38Changes the number of rows to 25.")
1b94449f
RS
39 ()
40{
41 union REGS regs;
42
24ba360b
RS
43#ifdef HAVE_X_WINDOWS
44 if (!inhibit_window_system)
45 return Qnil;
46#endif
47 if (have_mouse) mouse_off ();
1b94449f
RS
48 regs.x.ax = 3;
49 int86 (0x10, &regs, &regs);
50 regs.x.ax = 0x1101;
51 regs.h.bl = 0;
52 int86 (0x10, &regs, &regs);
53 regs.x.ax = 0x1200;
54 regs.h.bl = 32;
55 int86 (0x10, &regs, &regs);
56 regs.x.ax = 3;
57 int86 (0x10, &regs, &regs);
24ba360b 58 Fset_frame_size (Fselected_frame (), ScreenCols (), ScreenRows ());
1b94449f
RS
59 Frecenter (Qnil);
60 Fredraw_display ();
24ba360b
RS
61 if (have_mouse) mouse_init ();
62 return Qnil;
1b94449f
RS
63}
64
24ba360b
RS
65DEFUN ("mode4350", Fmode4350, Smode4350, 0, 0, "", "\
66Changes the number of rows to 43 (EGA) or 50 (VGA).")
1b94449f
RS
67 ()
68{
69 union REGS regs;
70
24ba360b
RS
71#ifdef HAVE_X_WINDOWS
72 if (!inhibit_window_system)
73 return Qnil;
74#endif
75 if (have_mouse) mouse_off ();
1b94449f
RS
76 regs.x.ax = 3;
77 int86 (0x10, &regs, &regs);
78 regs.x.ax = 0x1112;
79 regs.h.bl = 0;
80 int86 (0x10, &regs, &regs);
81 regs.x.ax = 0x1200;
82 regs.h.bl = 32;
83 int86 (0x10, &regs, &regs);
84 regs.x.ax = 0x0100;
85 regs.x.cx = 7;
86 int86 (0x10, &regs, &regs);
24ba360b 87 Fset_frame_size (Fselected_frame (), ScreenCols (), ScreenRows ());
1b94449f
RS
88 Frecenter (Qnil);
89 Fredraw_display ();
24ba360b
RS
90 if (have_mouse) mouse_init ();
91 return Qnil;
1b94449f
RS
92}
93
94DEFUN ("int86", Fint86, Sint86, 2, 2, 0,
95 "Call specific MSDOS interrupt number INTERRUPT with REGISTERS.\n\
96Return the updated REGISTER vector.\n\
97\n\
98INTERRUPT should be an integer in the range 0 to 255.\n\
99REGISTERS should be a vector produced by `make-register' and\n\
100`set-register-value'.")
101 (intno, regs)
102 Lisp_Object intno, regs;
103{
104 register int i;
105 int no;
106 union REGS inregs, outregs;
107 Lisp_Object val;
108
109 CHECK_NUMBER (intno, 0);
110 no = (unsigned long) XINT (intno);
111 CHECK_VECTOR (regs, 1);
112 if (no < 0 || no > 0xff || XVECTOR (regs)-> size != 8)
113 return Qnil;
114 for (i = 0; i < 8; i++)
115 CHECK_NUMBER (XVECTOR (regs)->contents[i], 1);
116
117 inregs.x.ax = (unsigned long) XFASTINT (XVECTOR (regs)->contents[0]);
118 inregs.x.bx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[1]);
119 inregs.x.cx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[2]);
120 inregs.x.dx = (unsigned long) XFASTINT (XVECTOR (regs)->contents[3]);
121 inregs.x.si = (unsigned long) XFASTINT (XVECTOR (regs)->contents[4]);
122 inregs.x.di = (unsigned long) XFASTINT (XVECTOR (regs)->contents[5]);
123 inregs.x.cflag = (unsigned long) XFASTINT (XVECTOR (regs)->contents[6]);
124 inregs.x.flags = (unsigned long) XFASTINT (XVECTOR (regs)->contents[7]);
125
126 int86 (no, &inregs, &outregs);
127
128 XVECTOR (regs)->contents[0] = make_number (outregs.x.ax);
129 XVECTOR (regs)->contents[1] = make_number (outregs.x.bx);
130 XVECTOR (regs)->contents[2] = make_number (outregs.x.cx);
131 XVECTOR (regs)->contents[3] = make_number (outregs.x.dx);
132 XVECTOR (regs)->contents[4] = make_number (outregs.x.si);
133 XVECTOR (regs)->contents[5] = make_number (outregs.x.di);
134 XVECTOR (regs)->contents[6] = make_number (outregs.x.cflag);
135 XVECTOR (regs)->contents[7] = make_number (outregs.x.flags);
136
137 return regs;
138}
139
140int dos_country_code;
141int dos_codepage;
142Lisp_Object Vdos_version;
143
144void
145init_dosfns ()
146{
147 union REGS regs;
148 _go32_dpmi_seginfo info;
149 _go32_dpmi_registers dpmiregs;
150
151 get_lim_data (); /* why the hell isn't this called elsewhere? */
152
153 regs.x.ax = 0x3000;
154 intdos (&regs, &regs);
155 Vdos_version = Fcons (make_number (regs.h.al), make_number (regs.h.ah));
156
157 /* Obtain the country code by calling Dos via Dpmi. Don't rely on GO32. */
158 info.size = (34 + 15) / 16;
159 if (_go32_dpmi_allocate_dos_memory (&info))
160 dos_country_code = 1;
161 else
162 {
163 dpmiregs.x.ax = 0x3800;
164 dpmiregs.x.ds = info.rm_segment;
165 dpmiregs.x.dx = 0;
166 dpmiregs.x.ss = dpmiregs.x.sp = 0;
167 _go32_dpmi_simulate_int (0x21, &dpmiregs);
168 dos_country_code = dpmiregs.x.bx;
169 _go32_dpmi_free_dos_memory (&info);
170 }
171
172 regs.x.ax = 0x6601;
173 intdos (&regs, &regs);
174 if (regs.x.cflag)
175 /* Estimate code page from country code */
176 switch (dos_country_code)
177 {
178 case 45: /* Denmark */
179 case 47: /* Norway */
180 dos_codepage = 865;
181 break;
182 default:
183 /* US */
184 dos_codepage = 437;
185 }
186 else
187 dos_codepage = regs.x.bx & 0xffff;
188}
189\f
190/*
191 * Define everything
192 */
193syms_of_dosfns ()
194{
195 defsubr (&Smode25);
196 defsubr (&Smode4350);
197 defsubr (&Sint86);
198
199 DEFVAR_INT ("dos-country-code", &dos_country_code,
200 "The country code returned by Dos when Emacs was started.\n\
201Usually this is the international telephone prefix.");
202
203 DEFVAR_INT ("dos-codepage", &dos_codepage,
204 "The codepage active when Emacs was started.\n\
24ba360b
RS
205The following are known:\n\
206 437 United States\n\
207 850 Multilingual (Latin I)\n\
208 852 Slavic (Latin II)\n\
209 857 Turkish\n\
210 860 Portugal\n\
211 861 Iceland\n\
212 863 Canada (French)\n\
1b94449f
RS
213 865 Norway/Denmark");
214
215 DEFVAR_LISP ("dos-version", &Vdos_version,
216 "The (MAJOR . MINOR) Dos version (subject to modification with setver).");
217}
218#endif /* MSDOS */