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