1 /* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
2 /* */
3 /* This library is free software; you can redistribute it and/or */
4 /* modify it without any restrictions. This library is distributed */
5 /* in the hope that it will be useful, but without any warranty. */
6
7 /* Multi-chipset support Copyright (C) 1993 Harm Hanemaayer */
8 /* partially copyrighted (C) 1993 by Hartmut Schirmer */
9 /* Changes by Michael Weller. */
10 /* Modified by Don Secrest to include Tseng ET6000 handling */
11 /* Changes around the config things by 101 (Attila Lendvai) */
12
13 /* The code is a bit of a mess; also note that the drawing functions */
14 /* are not speed optimized (the gl functions are much faster). */
15 #define _GNU_SOURCE
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <fcntl.h>
19 #include <signal.h>
20 #include <termios.h>
21 #include <string.h>
22 #include <unistd.h>
23 #include <stdarg.h>
24 #include <sys/mman.h>
25 #include <sys/kbio.h>
26 #include <sys/ioctl.h>
27 #include <sys/stat.h>
28 #include <sys/consio.h>
29 #include <sys/wait.h>
30 #include <errno.h>
31 #include <ctype.h>
32 #include "vga.h"
33 #include "libvga.h"
34 #include "driver.h"
35 #include "vgapci.h"
36 #include "mouse/vgamouse.h"
37 #include "keyboard/vgakeyboard.h"
38 #include "vgaregs.h"
39 #include "vgaversion.h"
40
41 int permfd = -1;
ioperm(unsigned long from,unsigned long num,int on)42 int ioperm(unsigned long from, unsigned long num, int on)
43 {
44 if (permfd == -1)
45 permfd = open("/dev/io", O_RDONLY);
46 if (permfd != -1)
47 return 0;
48 else
49 return 1;
50 }
51
iopl(int level)52 int iopl(int level)
53 {
54 return ioperm(0, 0, 0);
55 }
56
57 #ifdef BACKGROUND
58 #include "vgabg.h"
59
60 /* ugly check to prevent usage on kernel versions < 2.0.36 and < 2.1.123
61 * should this also be runtime checked?
62 *
63 * Why not earlier kernels?
64 * The following sequence of mmap() calls is deadly in these versions
65 * due to a kernel bug:
66 * #define MAP_ADDR 0xfd000000 // high mem area, eg. framebuf
67 * #define MAP_SIZE 0x200000
68 * map_a=mmap(0,MAP_SIZE,PROT_READ|PROT_WRITE,
69 * MAP_PRIVATE|MAP_ANONYMOUS,-1,0);
70 * map_b=mmap(0,MAP_SIZE,PROT_READ | PROT_WRITE,
71 * MAP_SHARED,dev_mem_fd,MAP_ADDR);
72 * map_c=mmap(map_a,MAP_SIZE,PROT_READ | PROT_WRITE,
73 * MAP_SHARED | MAP_FIXED,proc_self_mem_fd,
74 * map_b);
75 * The map_c mmapping will destroy random kernel data. A similar
76 * mmap sequence is done when calling __svgalib_map_virtual_screen()
77 * to map the linear framebuffer virtual address to the final
78 * virtual address (which then can mapped to backing storage on VC switch,
79 * transparently for the application).
80 */
81 #include <linux/version.h>
82 #define LNX_MAJ_VER ((LINUX_VERSION_CODE >> 16) & 255)
83 #define LNX_MED_VER ((LINUX_VERSION_CODE >> 8) & 255)
84 #define LNX_MIN_VER (LINUX_VERSION_CODE & 255)
85 #if (LNX_MAJ_VER < 2) || \
86 ( (LNX_MAJ_VER == 2) && (LNX_MED_VER == 0) && (LNX_MIN_VER < 36) ) || \
87 ( (LNX_MAJ_VER == 2) && (LNX_MED_VER == 1) && (LNX_MIN_VER < 123) ) || \
88 ( (LNX_MAJ_VER == 2) && (LNX_MED_VER == 3) && (LNX_MIN_VER > 26) )
89 #warning BACKGROUND *not* supported on kernel versions < 2.0.36 or < 2.1.123,
90 #warning or version>2.3.26. Compile without BACKGROUND.
91 #endif
92 #endif /* #ifdef BACKGROUND */
93
94 /* Delay in microseconds after a mode is set (screen is blanked during this */
95 /* time), allows video signals to stabilize */
96 #define MODESWITCHDELAY 150000
97
98 /* Define this to disable video output during mode switches, in addition to */
99 /* 'turning off the screen', which is always done. */
100 /* Doesn't look very nice on my Cirrus. */
101 /* #define DISABLE_VIDEO_OUTPUT */
102
103 /* #define DONT_WAIT_VC_ACTIVE */
104
105 /* Use /dev/tty instead of /dev/tty0 (the previous behaviour may have been
106 * silly). */
107 #define USE_DEVTTY
108
109 #define SETSIG(sa, sig, fun) {\
110 sa.sa_handler = fun; \
111 sa.sa_flags = SA_RESTART; \
112 zero_sa_mask(&(sa.sa_mask)); \
113 sigaction(sig, &sa, NULL); \
114 }
115
116 #ifdef INCLUDE_VESA_DRIVER
117 extern int __svgalib_lrmi_cpu_type;
118 #endif
119
120 /* variables used to shift between monchrome and color emulation */
121
122 int __svgalib_CRT_I; /* current CRT index register address */
123 int __svgalib_CRT_D; /* current CRT data register address */
124 int __svgalib_IS1_R; /* current input status register address */
125 static int color_text; /* true if color text emulation */
126
127 unsigned char * BANKED_MEM_POINTER=NULL, * LINEAR_MEM_POINTER, *MMIO_POINTER;
128 unsigned char * B8000_MEM_POINTER=NULL;
129 unsigned long int __svgalib_banked_mem_base, __svgalib_banked_mem_size;
130 unsigned long int __svgalib_mmio_base, __svgalib_mmio_size=0;
131 unsigned long int __svgalib_linear_mem_base=0, __svgalib_linear_mem_size=0;
132
133 /* If == 0 then nothing is defined by the user... */
134 int __svgalib_default_mode = 0;
135
136 struct info infotable[] =
137 {
138 {80, 25, 16, 160, 0}, /* VGAlib VGA modes */
139 {320, 200, 16, 40, 0},
140 {640, 200, 16, 80, 0},
141 {640, 350, 16, 80, 0},
142 {640, 480, 16, 80, 0},
143 {320, 200, 256, 320, 1},
144 {320, 240, 256, 80, 0},
145 {320, 400, 256, 80, 0},
146 {360, 480, 256, 90, 0},
147 {640, 480, 2, 80, 0},
148
149 {640, 480, 256, 640, 1}, /* VGAlib SVGA modes */
150 {800, 600, 256, 800, 1},
151 {1024, 768, 256, 1024, 1},
152 {1280, 1024, 256, 1280, 1},
153
154 {320, 200, 1 << 15, 640, 2}, /* Hicolor/truecolor modes */
155 {320, 200, 1 << 16, 640, 2},
156 {320, 200, 1 << 24, 320 * 3, 3},
157 {640, 480, 1 << 15, 640 * 2, 2},
158 {640, 480, 1 << 16, 640 * 2, 2},
159 {640, 480, 1 << 24, 640 * 3, 3},
160 {800, 600, 1 << 15, 800 * 2, 2},
161 {800, 600, 1 << 16, 800 * 2, 2},
162 {800, 600, 1 << 24, 800 * 3, 3},
163 {1024, 768, 1 << 15, 1024 * 2, 2},
164 {1024, 768, 1 << 16, 1024 * 2, 2},
165 {1024, 768, 1 << 24, 1024 * 3, 3},
166 {1280, 1024, 1 << 15, 1280 * 2, 2},
167 {1280, 1024, 1 << 16, 1280 * 2, 2},
168 {1280, 1024, 1 << 24, 1280 * 3, 3},
169
170 {800, 600, 16, 100, 0}, /* SVGA 16-color modes */
171 {1024, 768, 16, 128, 0},
172 {1280, 1024, 16, 160, 0},
173
174 {720, 348, 2, 90, 0}, /* Hercules emulation mode */
175
176 {320, 200, 1 << 24, 320 * 4, 4},
177 {640, 480, 1 << 24, 640 * 4, 4},
178 {800, 600, 1 << 24, 800 * 4, 4},
179 {1024, 768, 1 << 24, 1024 * 4, 4},
180 {1280, 1024, 1 << 24, 1280 * 4, 4},
181
182 {1152, 864, 16, 144, 0},
183 {1152, 864, 256, 1152, 1},
184 {1152, 864, 1 << 15, 1152 * 2, 2},
185 {1152, 864, 1 << 16, 1152 * 2, 2},
186 {1152, 864, 1 << 24, 1152 * 3, 3},
187 {1152, 864, 1 << 24, 1152 * 4, 4},
188
189 {1600, 1200, 16, 200, 0},
190 {1600, 1200, 256, 1600, 1},
191 {1600, 1200, 1 << 15, 1600 * 2, 2},
192 {1600, 1200, 1 << 16, 1600 * 2, 2},
193 {1600, 1200, 1 << 24, 1600 * 3, 3},
194 {1600, 1200, 1 << 24, 1600 * 4, 4},
195
196 {320, 240, 256, 320, 1},
197 {320, 240, 1<<15, 320*2, 2},
198 {320, 240, 1<<16, 320*2, 2},
199 {320, 240, 1<<24, 320*3, 3},
200 {320, 240, 1<<24, 320*4, 4},
201
202 {400, 300, 256, 400, 1},
203 {400, 300, 1<<15, 400*2, 2},
204 {400, 300, 1<<16, 400*2, 2},
205 {400, 300, 1<<24, 400*3, 3},
206 {400, 300, 1<<24, 400*4, 4},
207
208 {512, 384, 256, 512, 1},
209 {512, 384, 1<<15, 512*2, 2},
210 {512, 384, 1<<16, 512*2, 2},
211 {512, 384, 1<<24, 512*3, 3},
212 {512, 384, 1<<24, 512*4, 4},
213
214 {960, 720, 256, 960, 1},
215 {960, 720, 1<<15, 960*2, 2},
216 {960, 720, 1<<16, 960*2, 2},
217 {960, 720, 1<<24, 960*3, 3},
218 {960, 720, 1<<24, 960*4, 4},
219
220 {1920, 1440, 256, 1920, 1},
221 {1920, 1440, 1<<15, 1920*2, 2},
222 {1920, 1440, 1<<16, 1920*2, 2},
223 {1920, 1440, 1<<24, 1920*3, 3},
224 {1920, 1440, 1<<24, 1920*4, 4},
225
226 {320, 400, 1<<8, 320, 1},
227 {320, 400, 1<<15, 320*2, 2},
228 {320, 400, 1<<16, 320*2, 2},
229 {320, 400, 1<<24, 320*3, 3},
230 {320, 400, 1<<24, 320*4, 4},
231
232 {640, 400, 256, 640, 1},
233 {640, 400, 1<<15, 640*2, 2},
234 {640, 400, 1<<16, 640*2, 2},
235 {640, 400, 1<<24, 640*3, 3},
236 {640, 400, 1<<24, 640*4, 4},
237
238 {320, 480, 256, 320, 1},
239 {320, 480, 1<<15, 320*2, 2},
240 {320, 480, 1<<16, 320*2, 2},
241 {320, 480, 1<<24, 320*3, 3},
242 {320, 480, 1<<24, 320*4, 4},
243
244 {720, 540, 256, 720, 1},
245 {720, 540, 1<<15, 720*2, 2},
246 {720, 540, 1<<16, 720*2, 2},
247 {720, 540, 1<<24, 720*3, 3},
248 {720, 540, 1<<24, 720*4, 4},
249
250 {848, 480, 256, 848, 1},
251 {848, 480, 1<<15, 848*2, 2},
252 {848, 480, 1<<16, 848*2, 2},
253 {848, 480, 1<<24, 848*3, 3},
254 {848, 480, 1<<24, 848*4, 4},
255
256 {1072, 600, 256, 1072, 1},
257 {1072, 600, 1<<15, 1072*2, 2},
258 {1072, 600, 1<<16, 1072*2, 2},
259 {1072, 600, 1<<24, 1072*3, 3},
260 {1072, 600, 1<<24, 1072*4, 4},
261
262 {1280, 720, 256, 1280, 1},
263 {1280, 720, 1<<15, 1280*2, 2},
264 {1280, 720, 1<<16, 1280*2, 2},
265 {1280, 720, 1<<24, 1280*3, 3},
266 {1280, 720, 1<<24, 1280*4, 4},
267
268 {1360, 768, 256, 1360, 1},
269 {1360, 768, 1<<15, 1360*2, 2},
270 {1360, 768, 1<<16, 1360*2, 2},
271 {1360, 768, 1<<24, 1360*3, 3},
272 {1360, 768, 1<<24, 1360*4, 4},
273
274 {1800, 1012, 256, 1800, 1},
275 {1800, 1012, 1<<15, 1800*2, 2},
276 {1800, 1012, 1<<16, 1800*2, 2},
277 {1800, 1012, 1<<24, 1800*3, 3},
278 {1800, 1012, 1<<24, 1800*4, 4},
279
280 {1920, 1080, 256, 1920, 1},
281 {1920, 1080, 1<<15, 1920*2, 2},
282 {1920, 1080, 1<<16, 1920*2, 2},
283 {1920, 1080, 1<<24, 1920*3, 3},
284 {1920, 1080, 1<<24, 1920*4, 4},
285
286 {2048, 1152, 256, 2048, 1},
287 {2048, 1152, 1<<15, 2048*2, 2},
288 {2048, 1152, 1<<16, 2048*2, 2},
289 {2048, 1152, 1<<24, 2048*3, 3},
290 {2048, 1152, 1<<24, 2048*4, 4},
291
292 {2048, 1536, 256, 2048, 1},
293 {2048, 1536, 1<<15, 2048*2, 2},
294 {2048, 1536, 1<<16, 2048*2, 2},
295 {2048, 1536, 1<<24, 2048*3, 3},
296 {2048, 1536, 1<<24, 2048*4, 4},
297
298 {512, 480, 256, 512, 1},
299 {512, 480, 1<<15, 512*2, 2},
300 {512, 480, 1<<16, 512*2, 2},
301 {512, 480, 1<<24, 512*3, 3},
302 {512, 480, 1<<24, 512*4, 4},
303
304 {400, 600, 256, 400, 1},
305 {400, 600, 1<<15, 400*2, 2},
306 {400, 600, 1<<16, 400*2, 2},
307 {400, 600, 1<<24, 400*3, 3},
308 {400, 600, 1<<24, 400*4, 4},
309
310 {0, 0, 0, 0, 0},
311 {0, 0, 0, 0, 0},
312 {0, 0, 0, 0, 0},
313 {0, 0, 0, 0, 0},
314 {0, 0, 0, 0, 0},
315 {0, 0, 0, 0, 0},
316 {0, 0, 0, 0, 0},
317 {0, 0, 0, 0, 0},
318 {0, 0, 0, 0, 0},
319 {0, 0, 0, 0, 0},
320 {0, 0, 0, 0, 0},
321 {0, 0, 0, 0, 0},
322 {0, 0, 0, 0, 0},
323 {0, 0, 0, 0, 0},
324 {0, 0, 0, 0, 0},
325 {0, 0, 0, 0, 0},
326 {0, 0, 0, 0, 0}
327 };
328
329 #define MAX_MODES (sizeof(infotable) / sizeof(struct info))
330
331 #ifndef BACKGROUND
332 void (*__svgalib_go_to_background) (void) = 0;
333 void (*__svgalib_come_from_background) (void) = 0;
334 static int release_acquire=0;
335 #endif /* BACKGROUND */
336
337 unsigned long __svgalib_graph_base = GRAPH_BASE;
338
339 unsigned char __svgalib_novga = 0; /* Does not have VGA circuitry on board */
340 unsigned char __svgalib_vesatext = 0;
341 unsigned char __svgalib_textprog = 0; /* run a program when returning to text mode */
342 unsigned char __svgalib_secondary = 0; /* this is not the main card with VC'S (not yet supported) */
343 unsigned char __svgalib_novccontrol = 0; /* this is not the main card with VC'S (not yet supported) */
344 unsigned char __svgalib_simple = 0;
345 unsigned char __svgalib_ragedoubleclock = 0;
346
347 /* default palette values */
348 static const unsigned char default_red[256]
349 =
350 {0, 0, 0, 0, 42, 42, 42, 42, 21, 21, 21, 21, 63, 63, 63, 63,
351 0, 5, 8, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 56, 63,
352 0, 16, 31, 47, 63, 63, 63, 63, 63, 63, 63, 63, 63, 47, 31, 16,
353 0, 0, 0, 0, 0, 0, 0, 0, 31, 39, 47, 55, 63, 63, 63, 63,
354 63, 63, 63, 63, 63, 55, 47, 39, 31, 31, 31, 31, 31, 31, 31, 31,
355 45, 49, 54, 58, 63, 63, 63, 63, 63, 63, 63, 63, 63, 58, 54, 49,
356 45, 45, 45, 45, 45, 45, 45, 45, 0, 7, 14, 21, 28, 28, 28, 28,
357 28, 28, 28, 28, 28, 21, 14, 7, 0, 0, 0, 0, 0, 0, 0, 0,
358 14, 17, 21, 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 24, 21, 17,
359 14, 14, 14, 14, 14, 14, 14, 14, 20, 22, 24, 26, 28, 28, 28, 28,
360 28, 28, 28, 28, 28, 26, 24, 22, 20, 20, 20, 20, 20, 20, 20, 20,
361 0, 4, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 12, 8, 4,
362 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 14, 16, 16, 16, 16,
363 16, 16, 16, 16, 16, 14, 12, 10, 8, 8, 8, 8, 8, 8, 8, 8,
364 11, 12, 13, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 15, 13, 12,
365 11, 11, 11, 11, 11, 11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0};
366 static const unsigned char default_green[256]
367 =
368 {0, 0, 42, 42, 0, 0, 21, 42, 21, 21, 63, 63, 21, 21, 63, 63,
369 0, 5, 8, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 56, 63,
370 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 31, 47, 63, 63, 63, 63,
371 63, 63, 63, 63, 63, 47, 31, 16, 31, 31, 31, 31, 31, 31, 31, 31,
372 31, 39, 47, 55, 63, 63, 63, 63, 63, 63, 63, 63, 63, 55, 47, 39,
373 45, 45, 45, 45, 45, 45, 45, 45, 45, 49, 54, 58, 63, 63, 63, 63,
374 63, 63, 63, 63, 63, 58, 54, 49, 0, 0, 0, 0, 0, 0, 0, 0,
375 0, 7, 14, 21, 29, 28, 28, 28, 28, 28, 28, 28, 28, 21, 14, 7,
376 14, 14, 14, 14, 14, 14, 14, 14, 14, 17, 21, 24, 28, 28, 28, 28,
377 28, 28, 28, 28, 28, 24, 21, 17, 20, 20, 20, 20, 20, 20, 20, 20,
378 20, 22, 24, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 24, 22,
379 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 12, 16, 16, 16, 16,
380 16, 16, 16, 16, 16, 12, 8, 4, 8, 8, 8, 8, 8, 8, 8, 8,
381 8, 10, 12, 14, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 12, 10,
382 11, 11, 11, 11, 11, 11, 11, 11, 11, 12, 13, 15, 16, 16, 16, 16,
383 16, 16, 16, 16, 16, 15, 13, 12, 0, 0, 0, 0, 0, 0, 0, 0};
384 static const unsigned char default_blue[256]
385 =
386 {0, 42, 0, 42, 0, 42, 0, 42, 21, 63, 21, 63, 21, 63, 21, 63,
387 0, 5, 8, 11, 14, 17, 20, 24, 28, 32, 36, 40, 45, 50, 56, 63,
388 63, 63, 63, 63, 63, 47, 31, 16, 0, 0, 0, 0, 0, 0, 0, 0,
389 0, 16, 31, 47, 63, 63, 63, 63, 63, 63, 63, 63, 63, 55, 47, 39,
390 31, 31, 31, 31, 31, 31, 31, 31, 31, 39, 47, 55, 63, 63, 63, 63,
391 63, 63, 63, 63, 63, 58, 54, 49, 45, 45, 45, 45, 45, 45, 45, 45,
392 45, 49, 54, 58, 63, 63, 63, 63, 28, 28, 28, 28, 28, 21, 14, 7,
393 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 14, 21, 28, 28, 28, 28,
394 28, 28, 28, 28, 28, 24, 21, 17, 14, 14, 14, 14, 14, 14, 14, 14,
395 14, 17, 21, 24, 28, 28, 28, 28, 28, 28, 28, 28, 28, 26, 24, 22,
396 20, 20, 20, 20, 20, 20, 20, 20, 20, 22, 24, 26, 28, 28, 28, 28,
397 16, 16, 16, 16, 16, 12, 8, 4, 0, 0, 0, 0, 0, 0, 0, 0,
398 0, 4, 8, 12, 16, 16, 16, 16, 16, 16, 16, 16, 16, 14, 12, 10,
399 8, 8, 8, 8, 8, 8, 8, 8, 8, 10, 12, 14, 16, 16, 16, 16,
400 16, 16, 16, 16, 16, 15, 13, 12, 11, 11, 11, 11, 11, 11, 11, 11,
401 11, 12, 13, 15, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0};
402
403
404 static unsigned char text_regs[MAX_REGS]; /* VGA registers for saved text mode */
405 static unsigned char graph_regs[MAX_REGS]; /* VGA registers for svgalib mode */
406
407 char *__svgalib_TextProg_argv[16]; /* should be enough */
408 char *__svgalib_TextProg;
409
410 /* saved text mode palette values */
411 static unsigned char text_red[256];
412 static unsigned char text_green[256];
413 static unsigned char text_blue[256];
414
415 /* saved graphics mode palette values */
416 static unsigned char graph_red[256];
417 static unsigned char graph_green[256];
418 static unsigned char graph_blue[256];
419
420 static int prv_mode = TEXT; /* previous video mode */
421 static int flip_mode = TEXT; /* flipped video mode */
422
423 int CM = TEXT; /* current video mode */
424 struct info CI; /* current video parameters */
425 int COL; /* current color */
426
427
428 static int initialized = 0; /* flag: initialize() called ? */
429 static int flip = 0; /* flag: executing vga_flip() ? */
430
431 /* svgalib additions: */
432
433 int __svgalib_chipset = UNDEFINED;
434 int __svgalib_driver_report = 1;
435 /* report driver used after chipset detection */
436 int __svgalib_videomemoryused = -1;
437 int __svgalib_modeX = 0; /* true after vga_setmodeX() */
438 int __svgalib_modeflags = 0; /* copy of flags for current mode */
439 int __svgalib_critical = 0; /* indicates blitter is busy */
440 int __svgalib_screenon = 1; /* screen visible if != 0 */
441 RefreshRange __svgalib_horizsync =
442 {31500U, 0U}; /* horz. refresh (Hz) min, max */
443 RefreshRange __svgalib_vertrefresh =
444 {50U, 70U}; /* vert. refresh (Hz) min, max */
445 int __svgalib_bandwidth=50000; /* monitor maximum bandwidth (kHz) */
446 int __svgalib_grayscale = 0; /* grayscale vs. color mode */
447 int __svgalib_modeinfo_linearset = 0; /* IS_LINEAR handled via extended vga_modeinfo */
448 const int __svgalib_max_modes = MAX_MODES; /* Needed for dynamical allocated tables in mach32.c */
449
450 static unsigned __svgalib_maxhsync[] =
451 {
452 31500, 35100, 35500, 37900, 48300, 56000, 60000
453 };
454
455 static int lastmodenumber = __GLASTMODE; /* Last defined mode */
456 static int my_pid = 0; /* process PID, used with atexit() */
457 #ifndef BACKGROUND
458 static int __svgalib_currentpage;
459 #endif
460 static int vga_page_offset; /* offset to add to all vga_set*page() calls */
461 static int currentlogicalwidth;
462 static int currentdisplaystart;
463 static int mouse_support = 0;
464 int mouse_open = 0;
465 static int mouse_mode = 0;
466 static int mouse_type = -1;
467 static int mouse_modem_ctl = 0;
468 static char *mouse_device = "/dev/mouse";
469 #ifndef BACKGROUND
470 static int __svgalib_oktowrite = 1;
471 #endif
472 static int modeinfo_mask = ~0;
473
474 int __svgalib_mem_fd = -1; /* /dev/mem file descriptor */
475 int __svgalib_tty_fd = -1; /* /dev/tty file descriptor */
476 int __svgalib_nosigint = 0; /* Don't generate SIGINT in graphics mode */
477 int __svgalib_runinbackground = 0;
478 static int svgalib_vc = -1, startup_vc = -1;
479 static int __svgalib_security_revokeallprivs = 1;
480 static unsigned fontbufsize = 8192; /* compatibility */
481
482 /* Dummy buffer for mmapping grahics memory; points to 64K VGA framebuffer. */
483 unsigned char *__svgalib_graph_mem;
484 /* Exported variable (read-only) is shadowed from internal variable, for */
485 /* better shared library performance. */
486 unsigned char *graph_mem;
487
488 /* static unsigned char saved_text[32768]; */
489
490 /* Some new organisation for backgrund running. */
491 /* Alpha do not have ability to run in background (yet). */
492 /* Bg runnin has two different methods 1 and (2). */
493
494
495 #ifdef BACKGROUND
496
497 static unsigned char *__svgalib_graph_mem_orginal;
498 static unsigned char *__svgalib_graph_mem_check;
499 unsigned char *__svgalib_graph_mem_linear_orginal;
500 unsigned char *__svgalib_graph_mem_linear_check;
501 static int __svgalib_linear_is_background=0;
502 int __svgalib_oktowrite=1;
503
504 /* __svgalib_oktowrite tells if it is safe to write registers. */
505
506 int __svgalib_currentpage;
507 int __svgalib_virtual_mem_fd=-1;
508 static int __svgalib_processnumber=-1;
509 static unsigned char *graph_buf2 = NULL; /* saves linear graphics data during flip */
510
511 #endif
512
513 void *__svgalib_physaddr;
514 int __svgalib_linear_memory_size;
515
516
517 #ifdef __alpha__
518
519 /* same as graph mem, but mapped through sparse memory: */
520 unsigned char *__svgalib_sparse_mem;
521
522 #endif
523
524 static unsigned char *graph_buf = NULL; /* saves graphics data during flip */
525
526 static unsigned char *font_buf1; /* saved font data - plane 2 */
527 static unsigned char *font_buf2; /* saved font data - plane 3 */
528 static unsigned char *text_buf1; /* saved text data - plane 0 */
529 static unsigned char *text_buf2; /* saved text data - plane 1 */
530
531 static struct termios text_termio; /* text mode termio parameters */
532 static struct termios graph_termio; /* graphics mode termio parameters */
533
534 int __svgalib_flipchar = '\x1b'; /* flip character - initially ESCAPE */
535
536 /* Chipset specific functions */
537
538 DriverSpecs *__svgalib_driverspecs = &__svgalib_vga_driverspecs;
539
540 #ifndef BACKGROUND
541 static void (*__svgalib_setpage) (int); /* gives little faster vga_setpage() */
542 static void (*__svgalib_setrdpage) (int);
543 static void (*__svgalib_setwrpage) (int);
544 #endif
545 #ifdef BACKGROUND
546 void (*__svgalib_setpage) (int);
547 void (*__svgalib_setrdpage) (int);
548 void (*__svgalib_setwrpage) (int);
549 #endif
550
551 static void readconfigfile(void);
552
553 DriverSpecs *__svgalib_driverspecslist[] =
554 {
555 NULL, /* chipset undefined */
556 &__svgalib_vga_driverspecs,
557 #ifdef INCLUDE_ET4000_DRIVER
558 &__svgalib_et4000_driverspecs,
559 #else
560 NULL,
561 #endif
562 #ifdef INCLUDE_CIRRUS_DRIVER
563 &__svgalib_cirrus_driverspecs,
564 #else
565 NULL,
566 #endif
567 #ifdef INCLUDE_TVGA_DRIVER
568 &__svgalib_tvga8900_driverspecs,
569 #else
570 NULL,
571 #endif
572 #ifdef INCLUDE_OAK_DRIVER
573 &__svgalib_oak_driverspecs,
574 #else
575 NULL,
576 #endif
577 #ifdef INCLUDE_EGA_DRIVER
578 &__svgalib_ega_driverspecs,
579 #else
580 NULL,
581 #endif
582 #ifdef INCLUDE_S3_DRIVER
583 &__svgalib_s3_driverspecs,
584 #else
585 NULL,
586 #endif
587 #ifdef INCLUDE_ET3000_DRIVER
588 &__svgalib_et3000_driverspecs,
589 #else
590 NULL,
591 #endif
592 #ifdef INCLUDE_MACH32_DRIVER
593 &__svgalib_mach32_driverspecs,
594 #else
595 NULL,
596 #endif
597 #ifdef INCLUDE_GVGA6400_DRIVER
598 &__svgalib_gvga6400_driverspecs,
599 #else
600 NULL,
601 #endif
602 #ifdef INCLUDE_ARK_DRIVER
603 &__svgalib_ark_driverspecs,
604 #else
605 NULL,
606 #endif
607 #ifdef INCLUDE_ATI_DRIVER
608 &__svgalib_ati_driverspecs,
609 #else
610 NULL,
611 #endif
612 #ifdef INCLUDE_ALI_DRIVER
613 &__svgalib_ali_driverspecs,
614 #else
615 NULL,
616 #endif
617 #ifdef INCLUDE_MACH64_DRIVER
618 &__svgalib_mach64_driverspecs,
619 #else
620 NULL,
621 #endif
622 #ifdef INCLUDE_CHIPS_DRIVER
623 &__svgalib_chips_driverspecs,
624 #else
625 NULL,
626 #endif
627 #ifdef INCLUDE_APM_DRIVER
628 &__svgalib_apm_driverspecs,
629 #else
630 NULL,
631 #endif
632 #ifdef INCLUDE_NV3_DRIVER
633 &__svgalib_nv3_driverspecs,
634 #else
635 NULL,
636 #endif
637 #ifdef INCLUDE_ET6000_DRIVER
638 &__svgalib_et6000_driverspecs,
639 #else
640 NULL,
641 #endif
642 #ifdef INCLUDE_VESA_DRIVER
643 &__svgalib_vesa_driverspecs,
644 #else
645 NULL,
646 #endif
647 #ifdef INCLUDE_MX_DRIVER
648 &__svgalib_mx_driverspecs,
649 #else
650 NULL,
651 #endif
652 #ifdef INCLUDE_PARADISE_DRIVER
653 &__svgalib_paradise_driverspecs,
654 #else
655 NULL,
656 #endif
657 #ifdef INCLUDE_RAGE_DRIVER
658 &__svgalib_rage_driverspecs,
659 #else
660 NULL,
661 #endif
662 #ifdef INCLUDE_BANSHEE_DRIVER
663 &__svgalib_banshee_driverspecs,
664 #else
665 NULL,
666 #endif
667 #ifdef INCLUDE_SIS_DRIVER
668 &__svgalib_sis_driverspecs,
669 #else
670 NULL,
671 #endif
672 #ifdef INCLUDE_I740_DRIVER
673 &__svgalib_i740_driverspecs,
674 #else
675 NULL,
676 #endif
677 #ifdef INCLUDE_NEO_DRIVER
678 &__svgalib_neo_driverspecs,
679 #else
680 NULL,
681 #endif
682 #ifdef INCLUDE_LAGUNA_DRIVER
683 &__svgalib_laguna_driverspecs,
684 #else
685 NULL,
686 #endif
687 #ifdef INCLUDE_FBDEV_DRIVER
688 &__svgalib_fbdev_driverspecs,
689 #else
690 NULL,
691 #endif
692 #ifdef INCLUDE_G400_DRIVER
693 &__svgalib_g400_driverspecs,
694 #else
695 NULL,
696 #endif
697 #ifdef INCLUDE_R128_DRIVER
698 &__svgalib_r128_driverspecs,
699 #else
700 NULL,
701 #endif
702 #ifdef INCLUDE_SAVAGE_DRIVER
703 &__svgalib_savage_driverspecs,
704 #else
705 NULL,
706 #endif
707 };
708
709 static char *driver_names[] =
710 {
711 "",
712 "VGA",
713 "ET4000",
714 "Cirrus",
715 "TVGA",
716 "Oak",
717 "EGA",
718 "S3",
719 "ET3000",
720 "Mach32",
721 "GVGA6400",
722 "ARK",
723 "ATI",
724 "ALI",
725 "Mach64",
726 "C&T",
727 "APM",
728 "NV3",
729 "ET6000",
730 "VESA",
731 "MX",
732 "PARADISE",
733 "RAGE",
734 "BANSHEE",
735 "SIS",
736 "I740",
737 "NEOMAGIC",
738 "LAGUNA",
739 "FBDev",
740 "G400",
741 "R128",
742 "Savage",
743 NULL};
744
745 /* Chipset drivers */
746
747 /* vgadrv Standard VGA (also used by drivers below) */
748 /* et4000 Tseng ET4000 (from original vgalib) */
749 /* cirrus Cirrus Logic GD542x */
750 /* tvga8900 Trident TVGA 8900/9000 (derived from tvgalib) */
751 /* oak Oak Technologies 037/067/077 */
752 /* egadrv IBM EGA (subset of VGA) */
753 /* s3 S3 911 */
754 /* mach32 ATI MACH32 */
755 /* ark ARK Logic */
756 /* gvga6400 Genoa 6400 (old SVGA) */
757 /* ati ATI */
758 /* ali ALI2301 */
759 /* mach64 ATI MACH64 */
760 /* chips chips & technologies*/
761 /* et6000 Tseng ET6000 */ /* DS */
762
763 /*#define DEBUG */
764
765 /* Debug config file parsing.. */
766 /*#define DEBUG_CONF */
767
768 #ifdef DEBUG
_DEBUG(int dnr)769 static void _DEBUG(int dnr)
770 {
771 static int first = 1;
772 FILE *dfile;
773
774 dfile = fopen("svgalib.debug", (first ? "w" : "a"));
775 first = 0;
776 if (dfile == NULL)
777 exit(1);
778 fprintf(dfile, "debug #%d\n", dnr);
779 fclose(dfile);
780 sync();
781 }
782 #else
783 #define _DEBUG(d)
784 #endif
785
set_graphtermio(void)786 static void set_graphtermio(void)
787 {
788 /* Leave keyboard alone when rawkeyboard is enabled! */
789 if (__svgalib_kbd_fd < 0) {
790 /* set graphics mode termio parameters */
791 ioctl(0, TIOCSETAW, &graph_termio);
792 }
793 }
794
795
set_texttermio(void)796 static void set_texttermio(void)
797 {
798 /* Leave keyboard alone when rawkeyboard is enabled! */
799 if (__svgalib_kbd_fd < 0) {
800 /* restore text mode termio parameters */
801 ioctl(0, TIOCSETAW, &text_termio);
802 }
803 }
804
805
disable_interrupt(void)806 static void disable_interrupt(void)
807 {
808 struct termios cur_termio;
809
810 /* Well, one could argue that sigint is not enabled at all when in __svgalib_nosigint
811 but sometimes they *still* are enabled b4 graph_termio is set.. */
812 ioctl(0, TIOCGETA, &cur_termio);
813 cur_termio.c_lflag &= ~ISIG;
814 ioctl(0, TIOCSETAW, &cur_termio);
815 }
816
817
enable_interrupt(void)818 static void enable_interrupt(void)
819 {
820 struct termios cur_termio;
821
822 if (__svgalib_nosigint) /* do not reenable, they are often reenabled by text_termio */
823 return;
824 ioctl(0, TIOCGETA, &cur_termio);
825 cur_termio.c_lflag |= ISIG;
826 ioctl(0, TIOCSETAW, &cur_termio);
827 }
828
829 /* The following is rather messy and inelegant. The only solution I can */
830 /* see is getting a extra free VT for graphics like XFree86 does. */
831
__svgalib_waitvtactive(void)832 void __svgalib_waitvtactive(void)
833 {
834 if (__svgalib_tty_fd < 0)
835 return; /* Not yet initialized */
836
837 while (ioctl(__svgalib_tty_fd, VT_WAITACTIVE, svgalib_vc) < 0) {
838 if ((errno != EAGAIN) && (errno != EINTR)) {
839 perror("ioctl(VT_WAITACTIVE)");
840 exit(1);
841 }
842 usleep(150000);
843 }
844 }
845
846
847 /* open /dev/mem */
open_mem(void)848 static void open_mem(void)
849 {
850 #ifdef BACKGROUND
851 #if BACKGROUND == 1
852 char tmp[40];
853 #endif
854 #endif
855
856 if (CHIPSET == FBDEV)
857 return;
858
859 /* Ensure that the open will get a file descriptor greater
860 * than 2, else problems can occur with stdio functions
861 * under certain strange conditions: */
862 if (fcntl(0,F_GETFD) < 0) open("/dev/null", O_RDONLY);
863 if (fcntl(1,F_GETFD) < 0) open("/dev/null", O_WRONLY);
864 if (fcntl(2,F_GETFD) < 0) open("/dev/null", O_WRONLY);
865
866 if (__svgalib_mem_fd < 0)
867 if ((__svgalib_mem_fd = open("/dev/mem", O_RDWR)) < 0) {
868 printf("svgalib: Cannot open /dev/mem.\n");
869 exit(1);
870 }
871 #ifdef BACKGROUND
872 #if BACKGROUND == 1
873
874 /* Needs proc-fs. */
875 /* printf("procc\n"); */
876 /* char tmp[40];*/
877 if (__svgalib_virtual_mem_fd<0)
878 {
879 __svgalib_processnumber=getpid();
880 sprintf(tmp,"/proc/%d/mem",__svgalib_processnumber);
881 if ((__svgalib_virtual_mem_fd = open(tmp,O_RDWR)) < 0)
882 {
883 printf("svgalib: Cannot open /proc/%d/mem.\n",
884 __svgalib_processnumber);
885 exit(-1);
886 }
887 }
888 #endif
889 #endif
890 }
891
check_owner(int vc)892 static int check_owner(int vc)
893 {
894 struct stat sbuf;
895 char fname[30];
896
897 #ifdef ROOT_VC_SHORTCUT
898 if (!getuid())
899 return 1; /* root can do it always */
900 #endif
901 sprintf(fname, "/dev/ttyv%x", vc - 1);
902 if ((stat(fname, &sbuf) >= 0) && (getuid() == sbuf.st_uid)) {
903 return 1;
904 }
905 printf("You must be the owner of the current console to use svgalib.\n");
906 return 0;
907 }
908
__svgalib_open_devconsole(void)909 void __svgalib_open_devconsole(void)
910 {
911 struct vt_mode vtm;
912 int vts;
913 struct stat sbuf;
914 char fname[30];
915
916 if(__svgalib_novccontrol)return;
917
918 if (__svgalib_tty_fd >= 0)
919 return;
920
921 /* The code below assumes file descriptors 0, 1, and 2
922 * are already open; make sure that's true. */
923 if (fcntl(0,F_GETFD) < 0) open("/dev/null", O_RDONLY);
924 if (fcntl(1,F_GETFD) < 0) open("/dev/null", O_WRONLY);
925 if (fcntl(2,F_GETFD) < 0) open("/dev/null", O_WRONLY);
926
927 /*
928 * Now, it would be great if we could use /dev/tty and see what it is connected to.
929 * Alas, we cannot find out reliably what VC /dev/tty is bound to. Thus we parse
930 * stdin through stderr for a reliable VC
931 */
932 for (__svgalib_tty_fd = 0; __svgalib_tty_fd < 3; __svgalib_tty_fd++) {
933 if (fstat(__svgalib_tty_fd, &sbuf) < 0)
934 continue;
935 if (ioctl(__svgalib_tty_fd, VT_GETMODE, &vtm) < 0)
936 continue;
937 if ((sbuf.st_rdev & 0xff00) != 0x400)
938 continue;
939 if (!(sbuf.st_rdev & 0xff))
940 continue;
941 svgalib_vc = sbuf.st_rdev & 0xff;
942 return; /* perfect */
943 }
944
945 if ((__svgalib_tty_fd = open("/dev/console", O_RDWR)) < 0) {
946 printf("svgalib: can't open /dev/console \n");
947 exit(1);
948 }
949 if (ioctl(__svgalib_tty_fd, VT_OPENQRY, &svgalib_vc) < 0)
950 goto error;
951 if (svgalib_vc <= 0)
952 goto error;
953 sprintf(fname, "/dev/ttyv%x", svgalib_vc - 1);
954 close(__svgalib_tty_fd);
955 /* change our control terminal: */
956 setpgid(0,getppid());
957 setsid();
958 /* We must use RDWR to allow for output... */
959 if (((__svgalib_tty_fd = open(fname, O_RDWR)) >= 0) &&
960 (ioctl(__svgalib_tty_fd, VT_GETACTIVE, &vts) >= 0)) {
961 if (!check_owner(vts))
962 goto error;
963 /* success, redirect all stdios */
964 if (DREP)
965 printf("[svgalib: allocated virtual console #%d]\n", svgalib_vc);
966 fflush(stdin);
967 fflush(stdout);
968 fflush(stderr);
969 close(0);
970 close(1);
971 close(2);
972 dup(__svgalib_tty_fd);
973 dup(__svgalib_tty_fd);
974 dup(__svgalib_tty_fd);
975 /* clear screen and switch to it */
976 fwrite("\e[H\e[J", 6, 1, stderr);
977 fflush(stderr);
978 if (svgalib_vc != vts) {
979 startup_vc = vts;
980 ioctl(__svgalib_tty_fd, VT_ACTIVATE, svgalib_vc);
981 __svgalib_waitvtactive();
982 }
983 } else {
984 error:
985 if (__svgalib_tty_fd > 2)
986 close(__svgalib_tty_fd);
987 __svgalib_tty_fd = - 1;
988 printf("Not running in a graphics capable console,\n"
989 "and unable to find one.\n");
990 }
991 }
992
__svgalib_get_perm(void)993 void __svgalib_get_perm(void)
994 {
995 static int done = 0;
996
997 /* Only do this once. */
998 if (done)
999 return;
1000 done = 1;
1001
1002 /* Get I/O permissions for VGA registers. */
1003 /* If IOPERM is set, assume permissions have already been obtained */
1004 /* by a calling (exec-ing) process, e.g. ioperm(1). */
1005
1006 if (CHIPSET != FBDEV && getenv("IOPERM") == NULL)
1007 #ifdef __alpha__
1008 if (ioperm(0x0000, 0x10000, 1)) {
1009 printf("svgalib: Cannot get I/O permissions.\n");
1010 exit(1);
1011 }
1012 #else
1013 if (ioperm(0x3b4, 0x3df - 0x3b4 + 1, 1)) {
1014 printf("svgalib: Cannot get I/O permissions.\n");
1015 exit(1);
1016 }
1017 #endif
1018
1019 /* Open /dev/mem (also needs supervisor rights; ioperm(1) can be */
1020 /* used together with a special group that has r/w access on */
1021 /* /dev/mem to facilitate this). */
1022 open_mem();
1023
1024 __svgalib_open_devconsole();
1025
1026 /* color or monochrome text emulation? */
1027 if (CHIPSET != EGA && CHIPSET != FBDEV && !__svgalib_novga)
1028 color_text = port_in(MIS_R) & 0x01;
1029 else
1030 color_text = 1; /* EGA is assumed color */
1031
1032 /* chose registers for color/monochrome emulation */
1033 if (color_text) {
1034 __svgalib_CRT_I = CRT_IC;
1035 __svgalib_CRT_D = CRT_DC;
1036 __svgalib_IS1_R = IS1_RC;
1037 } else {
1038 __svgalib_CRT_I = CRT_IM;
1039 __svgalib_CRT_D = CRT_DM;
1040 __svgalib_IS1_R = IS1_RM;
1041 }
1042 }
1043
1044
__svgalib_delay(void)1045 void __svgalib_delay(void)
1046 {
1047 int i;
1048 for (i = 0; i < 10; i++);
1049 }
1050
1051 /* The Xfree server uses a slow copy, may help us too ... */
1052 #if defined(CONFIG_ALPHA_JENSEN)
1053 extern unsigned long vga_readl(unsigned long base, unsigned long off);
1054 extern void vga_writel(unsigned long b, unsigned long base, unsigned long off);
slowcpy_from_sm(unsigned char * dest,unsigned char * src,unsigned bytes)1055 static void slowcpy_from_sm(unsigned char *dest, unsigned char *src, unsigned bytes)
1056 {
1057 long i;
1058 if (((long) dest & 7) || ((long) src & 7) || bytes & 7) {
1059 printf("svgalib: unaligned slowcpy()!\n");
1060 exit(1);
1061 }
1062 for (i = 0; i < bytes; i++) {
1063 *(dest + i) = (*(unsigned long *) (src + (i << 7)) >> ((i & 0x03) * 8))
1064 & 0xffUL;
1065 }
1066 }
slowcpy_to_sm(unsigned char * dest,unsigned char * src,unsigned bytes)1067 static void slowcpy_to_sm(unsigned char *dest, unsigned char *src, unsigned bytes)
1068 {
1069 long i;
1070 if (((long) dest & 7) || ((long) src & 7) || bytes & 7) {
1071 printf("svgalib: unaligned slowcpy()!\n");
1072 exit(1);
1073 }
1074 for (i = 0; i < bytes; i++) {
1075 *(unsigned long *) (dest + (i << 7)) =
1076 (*(unsigned char *) (src + i)) * 0x01010101UL;
1077 }
1078 }
1079
1080 #else
slowcpy(unsigned char * dest,unsigned char * src,unsigned bytes)1081 static void slowcpy(unsigned char *dest, unsigned char *src, unsigned bytes)
1082 {
1083 #ifdef __alpha__
1084 if (((long) dest & 7) || ((long) src & 7) || bytes & 7) {
1085 printf("svgalib: unaligned slowcpy()!\n");
1086 exit(1);
1087 }
1088 while (bytes > 0) {
1089 *(long *) dest = *(long *) src;
1090 dest += 8;
1091 src += 8;
1092 bytes -= 8;
1093 }
1094 #else
1095 while (bytes-- > 0)
1096 *(dest++) = *(src++);
1097 #endif
1098 }
1099 #endif
1100
1101 #define TEXT_SIZE 65536
1102
restore_text(void)1103 static void restore_text(void)
1104 {
1105
1106 __svgalib_outseq(0x02,0x01);
1107
1108 #ifdef __alpha__
1109 port_out(0x06, GRA_I);
1110 port_out(0x00, GRA_D);
1111 #endif
1112
1113 #ifdef BACKGROUND
1114 if (-1 == mprotect(text_buf1,TEXT_SIZE*2,PROT_READ|PROT_WRITE))
1115 {
1116 printf("svgalib: Memory protect error\n");
1117 exit(-1);
1118 }
1119 #endif
1120
1121 #if defined(CONFIG_ALPHA_JENSEN)
1122 slowcpy_to_sm(SM, text_buf1, TEXT_SIZE);
1123 #else
1124 slowcpy(GM, text_buf1, TEXT_SIZE);
1125 #endif
1126
1127 __svgalib_outseq(0x02,0x02);
1128 #if defined(CONFIG_ALPHA_JENSEN)
1129 slowcpy_to_sm(SM, text_buf2, TEXT_SIZE);
1130 #else
1131 slowcpy(GM, text_buf2, TEXT_SIZE);
1132 #endif
1133 #ifdef BACKGROUND
1134 if (-1 == mprotect(text_buf1,TEXT_SIZE*2,PROT_READ))
1135 {
1136 printf("svgalib: Memory protect error\n");
1137 exit(1);
1138 }
1139 #endif
1140 };
1141
save_text(void)1142 static void save_text(void)
1143 {
1144
1145 #ifndef BACKGROUND
1146 text_buf1 = malloc(TEXT_SIZE * 2);
1147 #endif
1148 #ifdef BACKGROUND
1149 text_buf1 = valloc(TEXT_SIZE * 2);
1150 #endif
1151 text_buf2 = text_buf1 + TEXT_SIZE;
1152
1153 port_out(0x04, GRA_I);
1154 port_out(0x00, GRA_D);
1155 #ifdef __alpha__
1156 port_out(0x06, GRA_I);
1157 port_out(0x00, GRA_D);
1158 #endif
1159 #if defined(CONFIG_ALPHA_JENSEN)
1160 slowcpy_from_sm(text_buf1, SM, TEXT_SIZE);
1161 #else
1162 slowcpy(text_buf1, GM, TEXT_SIZE);
1163 #endif
1164
1165 /* save font data in plane 3 */
1166 port_out(0x04, GRA_I);
1167 port_out(0x01, GRA_D);
1168 #if defined(CONFIG_ALPHA_JENSEN)
1169 slowcpy_from_sm(text_buf2, SM, TEXT_SIZE);
1170 #else
1171 slowcpy(text_buf2, GM, TEXT_SIZE);
1172 #endif
1173
1174 #ifdef BACKGROUND
1175 /* Let's protect font. */
1176 /* Read only */
1177 if (-1 == mprotect(text_buf1,TEXT_SIZE*2,PROT_READ))
1178 {
1179 printf("svgalib: Memory protect error\n");
1180 exit(-1);
1181 }
1182 #endif
1183
1184 };
1185
__svgalib_saveregs(unsigned char * regs)1186 int __svgalib_saveregs(unsigned char *regs)
1187 {
1188 int i;
1189
1190 if (__svgalib_chipset == EGA || __svgalib_novga) {
1191 /* Special case: Don't save standard VGA registers. */
1192 return chipset_saveregs(regs);
1193 }
1194 /* save VGA registers */
1195 for (i = 0; i < CRT_C; i++) {
1196 regs[CRT + i] = __svgalib_incrtc(i);
1197 }
1198 for (i = 0; i < ATT_C; i++) {
1199 port_in(__svgalib_IS1_R);
1200 __svgalib_delay();
1201 port_out(i, ATT_IW);
1202 __svgalib_delay();
1203 regs[ATT + i] = port_in(ATT_R);
1204 __svgalib_delay();
1205 }
1206 for (i = 0; i < GRA_C; i++) {
1207 port_out(i, GRA_I);
1208 regs[GRA + i] = port_in(GRA_D);
1209 }
1210 for (i = 0; i < SEQ_C; i++) {
1211 port_out(i, SEQ_I);
1212 regs[SEQ + i] = port_in(SEQ_D);
1213 }
1214 regs[MIS] = __svgalib_inmisc();
1215
1216 i = chipset_saveregs(regs); /* save chipset-specific registers */
1217 /* i : additional registers */
1218 if (!SCREENON) { /* We turned off the screen */
1219 port_in(__svgalib_IS1_R);
1220 __svgalib_delay();
1221 port_out(0x20, ATT_IW);
1222 }
1223 return CRT_C + ATT_C + GRA_C + SEQ_C + 1 + i;
1224 }
1225
1226
__svgalib_setregs(const unsigned char * regs)1227 int __svgalib_setregs(const unsigned char *regs)
1228 {
1229 int i;
1230
1231 if(__svgalib_novga) return 1;
1232
1233 if (__svgalib_chipset == EGA) {
1234 /* Enable graphics register modification */
1235 port_out(0x00, GRA_E0);
1236 port_out(0x01, GRA_E1);
1237 }
1238 /* update misc output register */
1239 __svgalib_outmisc(regs[MIS]);
1240
1241 /* synchronous reset on */
1242 __svgalib_outseq(0x00,0x01);
1243
1244 /* write sequencer registers */
1245 __svgalib_outseq(0x01,regs[SEQ + 1] | 0x20);
1246 port_out(1, SEQ_I);
1247 port_out(regs[SEQ + 1] | 0x20, SEQ_D);
1248 for (i = 2; i < SEQ_C; i++) {
1249 __svgalib_outseq(i,regs[SEQ + i]);
1250 }
1251
1252 /* synchronous reset off */
1253 __svgalib_outseq(0x00,0x03);
1254
1255 if (__svgalib_chipset != EGA) {
1256 /* deprotect CRT registers 0-7 */
1257 __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);
1258 }
1259 /* write CRT registers */
1260 for (i = 0; i < CRT_C; i++) {
1261 __svgalib_outcrtc(i,regs[CRT + i]);
1262 }
1263
1264 /* write graphics controller registers */
1265 for (i = 0; i < GRA_C; i++) {
1266 port_out(i, GRA_I);
1267 port_out(regs[GRA + i], GRA_D);
1268 }
1269
1270 /* write attribute controller registers */
1271 for (i = 0; i < ATT_C; i++) {
1272 port_in(__svgalib_IS1_R); /* reset flip-flop */
1273 __svgalib_delay();
1274 port_out(i, ATT_IW);
1275 __svgalib_delay();
1276 port_out(regs[ATT + i], ATT_IW);
1277 __svgalib_delay();
1278 }
1279
1280 return 0;
1281 }
1282
1283 /* We invoke the old interrupt handler after setting text mode */
1284 /* We catch all signals that cause an exit by default (aka almost all) */
1285 static char sig2catch[] =
1286 {SIGHUP, SIGINT, SIGQUIT, SIGILL,
1287 SIGTRAP, SIGIOT, SIGBUS, SIGFPE,
1288 SIGSEGV, SIGPIPE, SIGALRM, SIGTERM,
1289 SIGXCPU, SIGXFSZ, SIGVTALRM,
1290 /* SIGPROF ,*/ SIGUSR1};
1291 static struct sigaction old_signal_handler[sizeof(sig2catch)];
1292
1293 struct vt_mode __svgalib_oldvtmode;
1294
restoretextmode(void)1295 static void restoretextmode(void)
1296 {
1297 /* handle unexpected interrupts - restore text mode and exit */
1298 keyboard_close();
1299 /* Restore a setting screwed by keyboard_close (if opened in graphicsmode) */
1300 set_texttermio();
1301 if (CM != TEXT)
1302 vga_setmode(TEXT);
1303 if (!__svgalib_screenon)
1304 vga_screenon();
1305 if (__svgalib_tty_fd >= 0) {
1306 if (!__svgalib_secondary) {
1307 ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT);
1308 ioctl(__svgalib_tty_fd, VT_SETMODE, &__svgalib_oldvtmode);
1309 }
1310 }
1311 if((__svgalib_textprog&3)==3){
1312 pid_t child;
1313 if((child=fork())==0){
1314 execv(__svgalib_TextProg,__svgalib_TextProg_argv);
1315 } else {
1316 waitpid(child,NULL,0);
1317 };
1318 };
1319 }
1320
idle_accel(void)1321 static void idle_accel(void) {
1322 /* wait for the accel to finish, we assume one of the both interfaces suffices */
1323 if (vga_ext_set(VGA_EXT_AVAILABLE, VGA_AVAIL_ACCEL) & ACCELFLAG_SYNC)
1324 vga_accel(ACCEL_SYNC);
1325 else if (vga_getmodeinfo(CM)->haveblit & HAVE_BLITWAIT)
1326 vga_blitwait();
1327 }
1328
signal_handler(int v)1329 static void signal_handler(int v)
1330 {
1331 int i;
1332
1333 /* If we have accelerated functions, possibly wait for the
1334 * blitter to finish. I hope the PutBitmap functions disable
1335 * interrupts while writing data to the screen, otherwise
1336 * this will cause an infinite loop.
1337 */
1338 idle_accel();
1339
1340 restoretextmode();
1341 printf("svgalib: Signal %d: %s received%s.\n", v, strsignal(v),
1342 (v == SIGINT) ? " (ctrl-c pressed)" : "");
1343
1344 for (i = 0; i < sizeof(sig2catch); i++)
1345 if (sig2catch[i] == v) {
1346 sigaction(v, old_signal_handler + i, NULL);
1347 raise(v);
1348 break;
1349 }
1350 if (i >= sizeof(sig2catch)) {
1351 printf("svgalib: Aieeee! Illegal call to signal_handler, raising segfault.\n");
1352 raise(SIGSEGV);
1353 }
1354 }
1355
__svgalib_getchipset(void)1356 int __svgalib_getchipset(void)
1357 {
1358 readconfigfile(); /* Make sure the config file is read. */
1359
1360 /* Unlike the others, the FBDev test needs to be before __svgalib_get_perm() */
1361
1362 #ifdef INCLUDE_FBDEV_DRIVER_TEST
1363 if (CHIPSET == UNDEFINED && __svgalib_fbdev_driverspecs.test())
1364 {
1365 CHIPSET = FBDEV;
1366 __svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1367 __svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1368 __svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1369 }
1370 #endif
1371 __svgalib_get_perm();
1372 if (CHIPSET == UNDEFINED) {
1373 CHIPSET = VGA; /* Protect against recursion */
1374 #ifdef INCLUDE_NV3_DRIVER_TEST
1375 if (__svgalib_nv3_driverspecs.test())
1376 CHIPSET = NV3;
1377 else
1378 #endif
1379 #ifdef INCLUDE_G400_DRIVER_TEST
1380 if (__svgalib_g400_driverspecs.test())
1381 CHIPSET = G400;
1382 else
1383 #endif
1384 #ifdef INCLUDE_R128_DRIVER_TEST
1385 if (__svgalib_r128_driverspecs.test())
1386 CHIPSET = R128;
1387 else
1388 #endif
1389 #ifdef INCLUDE_BANSHEE_DRIVER_TEST
1390 if (__svgalib_banshee_driverspecs.test())
1391 CHIPSET = BANSHEE;
1392 else
1393 #endif
1394 #ifdef INCLUDE_SIS_DRIVER_TEST
1395 if (__svgalib_sis_driverspecs.test())
1396 CHIPSET = SIS;
1397 else
1398 #endif
1399 #ifdef INCLUDE_I740_DRIVER_TEST
1400 if (__svgalib_i740_driverspecs.test())
1401 CHIPSET = I740;
1402 else
1403 #endif
1404 #ifdef INCLUDE_LAGUNA_DRIVER_TEST
1405 if (__svgalib_laguna_driverspecs.test())
1406 CHIPSET = LAGUNA;
1407 else
1408 #endif
1409 #ifdef INCLUDE_RAGE_DRIVER_TEST
1410 if (__svgalib_rage_driverspecs.test())
1411 CHIPSET = RAGE;
1412 else
1413 #endif
1414 #ifdef INCLUDE_MX_DRIVER_TEST
1415 if (__svgalib_mx_driverspecs.test())
1416 CHIPSET = MX;
1417 else
1418 #endif
1419 #ifdef INCLUDE_SAVAGE_DRIVER_TEST
1420 if (__svgalib_savage_driverspecs.test())
1421 CHIPSET = SAVAGE;
1422 else
1423 #endif
1424 #ifdef INCLUDE_NEO_DRIVER_TEST
1425 if (__svgalib_neo_driverspecs.test())
1426 CHIPSET = NEOMAGIC;
1427 else
1428 #endif
1429 #ifdef INCLUDE_CHIPS_DRIVER_TEST
1430 if (__svgalib_chips_driverspecs.test())
1431 CHIPSET = CHIPS;
1432 else
1433 #endif
1434 #ifdef INCLUDE_MACH64_DRIVER_TEST
1435 if (__svgalib_mach64_driverspecs.test())
1436 CHIPSET = MACH64;
1437 else
1438 #endif
1439 #ifdef INCLUDE_MACH32_DRIVER_TEST
1440 if (__svgalib_mach32_driverspecs.test())
1441 CHIPSET = MACH32;
1442 else
1443 #endif
1444 #ifdef INCLUDE_EGA_DRIVER_TEST
1445 if (__svgalib_ega_driverspecs.test())
1446 CHIPSET = EGA;
1447 else
1448 #endif
1449 #ifdef INCLUDE_ET6000_DRIVER_TEST /* DS */
1450 if (__svgalib_et6000_driverspecs.test()) /* This must be before */
1451 CHIPSET = ET6000; /* ET4000 or the card */
1452 else /* will be called et4k */
1453 #endif
1454 #ifdef INCLUDE_ET4000_DRIVER_TEST
1455 if (__svgalib_et4000_driverspecs.test())
1456 CHIPSET = ET4000;
1457 else
1458 #endif
1459 #ifdef INCLUDE_TVGA_DRIVER_TEST
1460 if (__svgalib_tvga8900_driverspecs.test())
1461 CHIPSET = TVGA8900;
1462 else
1463 #endif
1464 #ifdef INCLUDE_CIRRUS_DRIVER_TEST
1465 /* The Cirrus detection is not very clean. */
1466 if (__svgalib_cirrus_driverspecs.test())
1467 CHIPSET = CIRRUS;
1468 else
1469 #endif
1470 #ifdef INCLUDE_OAK_DRIVER_TEST
1471 if (__svgalib_oak_driverspecs.test())
1472 CHIPSET = OAK;
1473 else
1474 #endif
1475 #ifdef INCLUDE_PARADISE_DRIVER_TEST
1476 if (__svgalib_paradise_driverspecs.test())
1477 CHIPSET = PARADISE;
1478 else
1479 #endif
1480 #ifdef INCLUDE_S3_DRIVER_TEST
1481 if (__svgalib_s3_driverspecs.test())
1482 CHIPSET = S3;
1483 else
1484 #endif
1485 #ifdef INCLUDE_ET3000_DRIVER_TEST
1486 if (__svgalib_et3000_driverspecs.test())
1487 CHIPSET = ET3000;
1488 else
1489 #endif
1490 #ifdef INCLUDE_ARK_DRIVER_TEST
1491 if (__svgalib_ark_driverspecs.test())
1492 CHIPSET = ARK;
1493 else
1494 #endif
1495 #ifdef INCLUDE_GVGA6400_DRIVER_TEST
1496 if (__svgalib_gvga6400_driverspecs.test())
1497 CHIPSET = GVGA6400;
1498 else
1499 #endif
1500 #ifdef INCLUDE_ATI_DRIVER_TEST
1501 if (__svgalib_ati_driverspecs.test())
1502 CHIPSET = ATI;
1503 else
1504 #endif
1505 #ifdef INCLUDE_ALI_DRIVER_TEST
1506 if (__svgalib_ali_driverspecs.test())
1507 CHIPSET = ALI;
1508 else
1509 #endif
1510 #ifdef INCLUDE_APM_DRIVER_TEST
1511 /* Note: On certain cards this may toggle the video signal on/off which
1512 is ugly. Hence we test this last. */
1513 if (__svgalib_apm_driverspecs.test())
1514 CHIPSET = APM;
1515 else
1516 #endif
1517 #ifdef INCLUDE_VESA_DRIVER_TEST
1518 if (__svgalib_vesa_driverspecs.test())
1519 CHIPSET = VESA;
1520 else
1521 #endif
1522
1523 if (__svgalib_vga_driverspecs.test())
1524 CHIPSET = VGA;
1525 else
1526 /* else */
1527 {
1528 fprintf(stderr, "svgalib: Cannot find EGA or VGA graphics device.\n");
1529 exit(1);
1530 }
1531 __svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1532 __svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1533 __svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1534 }
1535 return CHIPSET;
1536 }
1537
vga_setchipset(int c)1538 void vga_setchipset(int c)
1539 {
1540 CHIPSET = c;
1541 #ifdef DEBUG
1542 printf("Setting chipset\n");
1543 #endif
1544 if (c == UNDEFINED)
1545 return;
1546 if (__svgalib_driverspecslist[c] == NULL) {
1547 printf("svgalib: Invalid chipset. The driver may not be compiled in.\n");
1548 CHIPSET = UNDEFINED;
1549 return;
1550 }
1551 __svgalib_get_perm();
1552 __svgalib_driverspecslist[c]->init(0, 0, 0);
1553 __svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1554 __svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1555 __svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1556 }
1557
vga_setchipsetandfeatures(int c,int par1,int par2)1558 void vga_setchipsetandfeatures(int c, int par1, int par2)
1559 {
1560 CHIPSET = c;
1561 #ifdef DEBUG
1562 printf("Forcing chipset and features\n");
1563 #endif
1564 __svgalib_get_perm();
1565 __svgalib_driverspecslist[c]->init(1, par1, par2);
1566 #ifdef DEBUG
1567 printf("Finished forcing chipset and features\n");
1568 #endif
1569 __svgalib_setpage = __svgalib_driverspecs->__svgalib_setpage;
1570 __svgalib_setrdpage = __svgalib_driverspecs->__svgalib_setrdpage;
1571 __svgalib_setwrpage = __svgalib_driverspecs->__svgalib_setwrpage;
1572 }
1573
1574
savepalette(unsigned char * red,unsigned char * green,unsigned char * blue)1575 static void savepalette(unsigned char *red, unsigned char *green,
1576 unsigned char *blue)
1577 {
1578 int i;
1579
1580 if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->savepalette)
1581 return (__svgalib_driverspecs->emul->savepalette(red, green, blue));
1582
1583 if (CHIPSET == EGA || __svgalib_novga)
1584 return;
1585
1586 /* save graphics mode palette - first select palette index 0 */
1587 port_out(0, PEL_IR);
1588
1589 /* read RGB components - index is autoincremented */
1590 for (i = 0; i < 256; i++) {
1591 __svgalib_delay();
1592 *(red++) = port_in(PEL_D);
1593 __svgalib_delay();
1594 *(green++) = port_in(PEL_D);
1595 __svgalib_delay();
1596 *(blue++) = port_in(PEL_D);
1597 }
1598 }
1599
restorepalette(const unsigned char * red,const unsigned char * green,const unsigned char * blue)1600 static void restorepalette(const unsigned char *red,
1601 const unsigned char *green, const unsigned char *blue)
1602 {
1603 int i;
1604
1605 if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->restorepalette)
1606 return (__svgalib_driverspecs->emul->restorepalette(red, green, blue));
1607
1608 if (CHIPSET == EGA || __svgalib_novga)
1609 return;
1610
1611 /* restore saved palette */
1612 port_out(0, PEL_IW);
1613
1614 /* read RGB components - index is autoincremented */
1615 for (i = 0; i < 256; i++) {
1616 __svgalib_delay();
1617 port_out(*(red++), PEL_D);
1618 __svgalib_delay();
1619 port_out(*(green++), PEL_D);
1620 __svgalib_delay();
1621 port_out(*(blue++), PEL_D);
1622 }
1623 }
1624
1625 #ifndef BACKGROUND
1626
1627 /* Virtual console switching */
1628
1629 static int forbidvtrelease = 0;
1630 static int forbidvtacquire = 0;
1631 static int lock_count = 0;
1632 static int release_flag = 0;
1633
1634 static void __svgalib_takevtcontrol(void);
1635
1636 void __svgalib_flipaway(void);
1637 static void __svgalib_flipback(void);
1638
__svgalib_releasevt_signal(int n)1639 static void __svgalib_releasevt_signal(int n)
1640 {
1641 if (lock_count) {
1642 release_flag = 1;
1643 return;
1644 }
1645 #ifdef DEBUG
1646 printf("Release request.\n");
1647 #endif
1648 forbidvtacquire = 1;
1649 if (forbidvtrelease) {
1650 forbidvtacquire = 0;
1651 ioctl(__svgalib_tty_fd, VT_RELDISP, 0);
1652 return;
1653 }
1654 if (__svgalib_go_to_background)
1655 (__svgalib_go_to_background) ();
1656 __svgalib_flipaway();
1657 if((__svgalib_textprog&3)==3){
1658 pid_t child;
1659 if((child=fork())==0){
1660 execv(__svgalib_TextProg,__svgalib_TextProg_argv);
1661 } else {
1662 waitpid(child,NULL,0);
1663 };
1664 };
1665 ioctl(__svgalib_tty_fd, VT_RELDISP, 1);
1666 #ifdef DEBUG
1667 printf("Finished release.\n");
1668 #endif
1669 forbidvtacquire = 0;
1670
1671 /* Suspend program until switched to again. */
1672 #ifdef DEBUG
1673 printf("Suspended.\n");
1674 #endif
1675
1676 __svgalib_oktowrite = 0;
1677 if (!__svgalib_runinbackground)
1678 __svgalib_waitvtactive();
1679 #ifdef DEBUG
1680 printf("Waked.\n");
1681 #endif
1682 }
1683
__svgalib_acquirevt_signal(int n)1684 static void __svgalib_acquirevt_signal(int n)
1685 {
1686 #ifdef DEBUG
1687 printf("Acquisition request.\n");
1688 #endif
1689 forbidvtrelease = 1;
1690 if (forbidvtacquire) {
1691 forbidvtrelease = 0;
1692 return;
1693 }
1694 __svgalib_flipback();
1695 ioctl(__svgalib_tty_fd, VT_RELDISP, VT_ACKACQ);
1696 #ifdef DEBUG
1697 printf("Finished acquisition.\n");
1698 #endif
1699 forbidvtrelease = 0;
1700 if (__svgalib_come_from_background)
1701 (__svgalib_come_from_background) ();
1702 __svgalib_oktowrite = 1;
1703 }
1704
1705 #endif
1706
1707 #ifndef BACKGROUND
1708
__svgalib_takevtcontrol(void)1709 void __svgalib_takevtcontrol(void)
1710 {
1711 struct sigaction siga;
1712 struct vt_mode newvtmode;
1713
1714 ioctl(__svgalib_tty_fd, VT_GETMODE, &__svgalib_oldvtmode);
1715 newvtmode = __svgalib_oldvtmode;
1716 newvtmode.mode = VT_PROCESS; /* handle VT changes */
1717 newvtmode.relsig = SVGALIB_RELEASE_SIG; /* I didn't find SIGUSR1/2 anywhere */
1718 newvtmode.acqsig = SVGALIB_ACQUIRE_SIG; /* in the kernel sources, so I guess */
1719 /* they are free */
1720 SETSIG(siga, SVGALIB_RELEASE_SIG, __svgalib_releasevt_signal);
1721 SETSIG(siga, SVGALIB_ACQUIRE_SIG, __svgalib_acquirevt_signal);
1722 ioctl(__svgalib_tty_fd, VT_SETMODE, &newvtmode);
1723 }
1724
1725 #endif
1726
1727 #ifdef LINEAR_DEBUG
dump_mem(unsigned char * name)1728 void dump_mem(unsigned char *name)
1729 {
1730 unsigned char bu[128];
1731 sprintf(bu,"cat /proc/%d/maps > /tmp/%s",getpid(),name);
1732 system(bu);
1733 }
1734 #endif
1735
1736 #ifdef BACKGROUND
1737 #if BACKGROUND == 1
__svgalib_map_virtual_screen(int page)1738 void __svgalib_map_virtual_screen(int page)
1739 {
1740 if (page==1000000)
1741 {
1742 __svgalib_graph_mem =
1743 (unsigned char *) mmap((caddr_t) GM, GRAPH_SIZE,
1744 PROT_READ | PROT_WRITE,
1745 MAP_SHARED | MAP_FIXED,
1746 __svgalib_virtual_mem_fd,
1747 (int)__svgalib_graph_mem_orginal);
1748 if (__svgalib_graph_mem!=__svgalib_graph_mem_check)
1749 {
1750 printf("svgalib: mmap error in paged screen memory.\n");
1751 exit(-1);
1752 }
1753 if (__svgalib_modeinfo_linearset&IS_LINEAR)
1754 {
1755 __svgalib_linearframebuffer =
1756 (unsigned char *) mmap((caddr_t) __svgalib_linearframebuffer,
1757 __svgalib_linear_memory_size,
1758 PROT_READ | PROT_WRITE,
1759 MAP_SHARED | MAP_FIXED,
1760 __svgalib_virtual_mem_fd,
1761 (int)__svgalib_graph_mem_linear_orginal);
1762 if (__svgalib_linearframebuffer!=__svgalib_graph_mem_linear_check)
1763 {
1764 printf("svgalib: mmap error in linear screen memory.\n");
1765 exit(-1);
1766 }
1767 __svgalib_linear_is_background=0;
1768 }
1769 }
1770 else
1771 {
1772 /* Program is now in the background. */
1773 __svgalib_graph_mem =
1774 (unsigned char *) mmap((caddr_t) GM, GRAPH_SIZE,
1775 PROT_READ | PROT_WRITE,
1776 MAP_SHARED | MAP_FIXED,
1777 __svgalib_virtual_mem_fd,
1778 (int)(graph_buf+(GRAPH_SIZE*page)));
1779 if (__svgalib_graph_mem!=__svgalib_graph_mem_check)
1780 {
1781 printf("svgalib: mmap error in paged background memory.\n");
1782 exit(-1);
1783 }
1784 if (!__svgalib_linear_is_background &&
1785 __svgalib_modeinfo_linearset&IS_LINEAR)
1786 {
1787 #ifdef LINEAR_DEBUG
1788 dump_mem("testmaps-before");
1789 printf("svgalib: trying to map regular mem at %p, size=0x%08x from %p\n",
1790 __svgalib_linearframebuffer,__svgalib_linear_memory_size,graph_buf2);
1791 #endif
1792 munmap(__svgalib_linearframebuffer,__svgalib_linear_memory_size);
1793 #ifdef LINEAR_DEBUG
1794 dump_mem("testmaps-after");
1795 #endif
1796 __svgalib_linearframebuffer =
1797 (unsigned char *) mmap((caddr_t) __svgalib_linearframebuffer,
1798 __svgalib_linear_memory_size,
1799 PROT_READ | PROT_WRITE,
1800 MAP_SHARED | MAP_FIXED,
1801 __svgalib_virtual_mem_fd,
1802 (int)(graph_buf2));
1803 if (__svgalib_linearframebuffer!=__svgalib_graph_mem_linear_check)
1804 {
1805 printf("svgalib: mmap error in linear background memory.\n");
1806 exit(-1);
1807 }
1808 __svgalib_linear_is_background=1;
1809 }
1810 }
1811 return;
1812 }
1813
1814 #endif
1815 #if BACKGROUND == 2
1816
1817 #endif
1818 #endif
1819
1820
__vga_mmap(void)1821 static void __vga_mmap(void)
1822 {
1823 #ifdef LINEAR_DEBUG
1824 printf("__vga_mmap() called, __svgalib_graph_base=0x%08lx\n",__svgalib_graph_base);
1825 #endif
1826 /* This assumes pl10+. */
1827 /* Still seems to waste 64K, so don't bother. */
1828 #ifndef BACKGROUND
1829 GM = (unsigned char *) BANKED_MEM_POINTER;
1830 #endif
1831 #ifdef BACKGROUND
1832 #if BACKGROUND == 1
1833 if ((__svgalib_graph_mem = valloc(GRAPH_SIZE)) == NULL) {
1834 printf("svgalib: allocation error \n");
1835 exit(-1);
1836 }
1837 __svgalib_graph_mem_check=__svgalib_graph_mem;
1838 __svgalib_graph_mem_orginal = (unsigned char *) BANKED_MEM_POINTER;
1839 __svgalib_map_virtual_screen(1000000); /* Video page */
1840 #endif
1841 #if BACKGROUND == 2
1842 GM = (unsigned char *) BANKED_MEM_POINTER;
1843 __svgalib_graph_mem_orginal=GM;
1844 #endif
1845 #endif
1846
1847 #ifdef __alpha__
1848 SM = (unsigned char *) mmap(
1849 (caddr_t) 0,
1850 GRAPH_SIZE << MEM_SHIFT,
1851 PROT_READ | PROT_WRITE,
1852 MAP_SHARED,
1853 __svgalib_mem_fd,
1854 SPARSE_GRAPH_BASE
1855 );
1856 #endif
1857 graph_mem = __svgalib_graph_mem; /* Exported variable. */
1858 }
1859
__vga_atexit(void)1860 static void __vga_atexit(void)
1861 {
1862 if (getpid() == my_pid) /* protect against forked processes */
1863 restoretextmode();
1864 if (__svgalib_tty_fd >= 0 && startup_vc > 0)
1865 ioctl(__svgalib_tty_fd, VT_ACTIVATE, startup_vc);
1866 }
1867
setcoloremulation(void)1868 static void setcoloremulation(void)
1869 {
1870 /* shift to color emulation */
1871 __svgalib_CRT_I = CRT_IC;
1872 __svgalib_CRT_D = CRT_DC;
1873 __svgalib_IS1_R = IS1_RC;
1874 if (CHIPSET != EGA && !__svgalib_novga)
1875 port_out(port_in(MIS_R) | 0x01, MIS_W);
1876 }
1877
initialize(void)1878 static void initialize(void)
1879 {
1880 int i;
1881 struct sigaction siga;
1882
1883 __svgalib_open_devconsole();
1884 if (__svgalib_tty_fd < 0) {
1885 exit(1);
1886 }
1887
1888 /* Make sure that textmode is restored at exit(). */
1889 if (my_pid == 0)
1890 my_pid = getpid();
1891 atexit(__vga_atexit);
1892
1893 #ifndef DONT_WAIT_VC_ACTIVE
1894 __svgalib_waitvtactive();
1895 #endif
1896
1897 /* save text mode termio parameters */
1898 ioctl(0, TIOCGETA, &text_termio);
1899
1900 graph_termio = text_termio;
1901
1902 /* change termio parameters to allow our own I/O processing */
1903 graph_termio.c_iflag &= ~(BRKINT | PARMRK | INPCK | IXON | IXOFF);
1904 graph_termio.c_iflag |= (IGNBRK | IGNPAR);
1905
1906 /* graph_termio.c_oflag &= ~(ONOCR);*/
1907
1908 graph_termio.c_lflag &= ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | NOFLSH);
1909 if (__svgalib_nosigint)
1910 graph_termio.c_lflag &= ~ISIG; /* disable interrupt */
1911 else
1912 graph_termio.c_lflag |= ISIG; /* enable interrupt */
1913
1914 graph_termio.c_cc[VMIN] = 1;
1915 graph_termio.c_cc[VTIME] = 0;
1916 graph_termio.c_cc[VSUSP] = 0; /* disable suspend */
1917
1918 disable_interrupt(); /* Is reenabled later by set_texttermio */
1919
1920 __svgalib_getchipset(); /* make sure a chipset has been selected */
1921 chipset_unlock();
1922
1923 /* disable text output to console */
1924 if (!__svgalib_secondary)
1925 ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS);
1926
1927 __svgalib_takevtcontrol(); /* HH: Take control over VT */
1928
1929 /* open /dev/mem */
1930 open_mem();
1931
1932 /* mmap graphics memory */
1933 if(B8000_MEM_POINTER==NULL){
1934 if(__svgalib_banked_mem_base==0)__svgalib_banked_mem_base=0xa0000;
1935 if(__svgalib_banked_mem_size==0)__svgalib_banked_mem_size=0x10000;
1936 BANKED_MEM_POINTER=mmap((caddr_t) 0,
1937 __svgalib_banked_mem_size,
1938 PROT_READ | PROT_WRITE,
1939 MAP_SHARED,
1940 __svgalib_mem_fd,
1941 __svgalib_banked_mem_base
1942
1943 );
1944 if(__svgalib_linear_mem_size) {
1945 LINEAR_MEM_POINTER=mmap((caddr_t) 0,
1946 __svgalib_linear_mem_size,
1947 PROT_READ | PROT_WRITE,
1948 MAP_SHARED,
1949 __svgalib_mem_fd,
1950 (off_t) __svgalib_linear_mem_base
1951 );
1952 };/* else LINEAR_MEM_POINTER=NULL;*/
1953
1954 if(__svgalib_mmio_size)
1955 MMIO_POINTER=mmap((caddr_t) 0,
1956 __svgalib_mmio_size,
1957 PROT_READ | PROT_WRITE,
1958 MAP_SHARED,
1959 __svgalib_mem_fd,
1960 (off_t) __svgalib_mmio_base
1961 ); else MMIO_POINTER=NULL;
1962
1963 B8000_MEM_POINTER=mmap((caddr_t) 0,
1964 32768,
1965 PROT_READ | PROT_WRITE,
1966 MAP_SHARED,
1967 __svgalib_mem_fd,
1968 (off_t) 0xb8000);
1969 };
1970 __vga_mmap();
1971
1972 if ((long) GM < 0) {
1973 printf("svgalib: mmap error rrr\n");
1974 exit(1);
1975 }
1976 /* disable video */
1977 vga_screenoff();
1978
1979 /* Sanity check: (from painful experience) */
1980
1981 i = __svgalib_saveregs(text_regs);
1982 if (i > MAX_REGS) {
1983 puts("svgalib: FATAL internal error:");
1984 printf("Set MAX_REGS at least to %d in src/driver.h and recompile everything.\n",
1985 i);
1986 exit(1);
1987 }
1988 /* This appears to fix the Trident 8900 rebooting problem. */
1989 if (__svgalib_chipset == TVGA8900) {
1990 port_out(0x0c, SEQ_I); /* reg 12 */
1991 text_regs[EXT + 11] = port_in(SEQ_D);
1992 port_out(0x1f, __svgalib_CRT_I);
1993 text_regs[EXT + 12] = port_in(__svgalib_CRT_D);
1994 }
1995 /* save text mode palette - first select palette index 0 */
1996 if(!__svgalib_novga)
1997 port_out(0, PEL_IR);
1998
1999 /* read RGB components - index is autoincremented */
2000 savepalette(text_red, text_green, text_blue);
2001
2002 /* shift to color emulation */
2003 setcoloremulation();
2004
2005 /* save font data - first select a 16 color graphics mode */
2006 if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->savefont) {
2007 __svgalib_driverspecs->emul->savefont();
2008 } else if(!__svgalib_novga) {
2009 __svgalib_driverspecs->setmode(GPLANE16, prv_mode);
2010 save_text();
2011
2012 /* Allocate space for textmode font. */
2013 #ifndef BACKGROUND
2014 font_buf1 = malloc(FONT_SIZE * 2);
2015 #endif
2016 #ifdef BACKGROUND
2017 font_buf1 = valloc(FONT_SIZE * 2);
2018 #endif
2019 font_buf2 = font_buf1 + FONT_SIZE;
2020
2021 /* save font data in plane 2 */
2022 port_out(0x04, GRA_I);
2023 port_out(0x02, GRA_D);
2024 #ifdef __alpha__
2025 port_out(0x06, GRA_I);
2026 port_out(0x00, GRA_D);
2027 #endif
2028 #if defined(CONFIG_ALPHA_JENSEN)
2029 slowcpy_from_sm(font_buf1, SM, FONT_SIZE);
2030 #else
2031 slowcpy(font_buf1, GM, FONT_SIZE);
2032 #endif
2033
2034 /* save font data in plane 3 */
2035 port_out(0x04, GRA_I);
2036 port_out(0x03, GRA_D);
2037 #if defined(CONFIG_ALPHA_JENSEN)
2038 slowcpy_from_sm(font_buf2, SM, FONT_SIZE);
2039 #else
2040 slowcpy(font_buf2, GM, FONT_SIZE);
2041 #endif
2042
2043 #ifdef BACKGROUND
2044 /* Let's protect font. */
2045 /* Read only */
2046 if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ))
2047 {
2048 printf("svgalib: Memory protect error\n");
2049 exit(-1);
2050 }
2051 #endif
2052 }
2053 initialized = 1;
2054
2055 /* do our own interrupt handling */
2056 for (i = 0; i < sizeof(sig2catch); i++) {
2057 siga.sa_handler = signal_handler;
2058 siga.sa_flags = 0;
2059 zero_sa_mask(&(siga.sa_mask));
2060 sigaction((int) sig2catch[i], &siga, old_signal_handler + i);
2061 }
2062
2063 /* vga_unlockvc(); */
2064 }
2065
2066 #ifndef BACKGROUND
2067
vga_setpage(int p)2068 inline void vga_setpage(int p)
2069 {
2070 p += vga_page_offset;
2071 if (p == __svgalib_currentpage && !__svgalib_simple)
2072 return;
2073 (*__svgalib_setpage) (p);
2074 __svgalib_currentpage = p;
2075 }
2076
2077
vga_setreadpage(int p)2078 void vga_setreadpage(int p)
2079 {
2080 p += vga_page_offset;
2081 if (p == __svgalib_currentpage)
2082 return;
2083 (*__svgalib_setrdpage) (p);
2084 __svgalib_currentpage = -1;
2085 }
2086
2087
vga_setwritepage(int p)2088 void vga_setwritepage(int p)
2089 {
2090 p += vga_page_offset;
2091 if (p == __svgalib_currentpage)
2092 return;
2093 (*__svgalib_setwrpage) (p);
2094 __svgalib_currentpage = -1;
2095 }
2096
2097 #endif
2098
vga_safety_fork(void (* shutdown_routine)(void))2099 void vga_safety_fork(void (*shutdown_routine) (void))
2100 {
2101 pid_t childpid;
2102 int child_status, oldkbmode;
2103
2104 if (initialized) {
2105 printf("svgalib: warning: vga_safety_fork() called when already initialized\n");
2106 goto no_fork;
2107 }
2108 initialize();
2109
2110 /*
2111 * get current keyboard mode:
2112 * If this didn't suffice we claim we are on an old system and just don't
2113 * need to restore it.
2114 */
2115 ioctl(__svgalib_tty_fd, KDGKBMODE, &oldkbmode);
2116
2117 childpid = fork();
2118 if (childpid < 0) {
2119 no_fork:
2120 printf("svgalib: warning: can't fork to enhance reliability; proceeding anyway");
2121 return;
2122 }
2123 if (childpid) {
2124 ioctl(__svgalib_tty_fd, (int) TIOCNOTTY, (char *)0);
2125 for (;;) {
2126 while (waitpid(childpid, &child_status, WUNTRACED) != childpid);
2127
2128 if (shutdown_routine)
2129 shutdown_routine();
2130
2131 vga_setmode(TEXT); /* resets termios as well */
2132 ioctl(__svgalib_tty_fd, KDSKBMODE, oldkbmode);
2133
2134 if (WIFEXITED(child_status))
2135 exit(WEXITSTATUS(child_status));
2136
2137 if (WCOREDUMP(child_status))
2138 puts("svgalib:vga_safety_fork: Core dumped!");
2139
2140 if (WIFSIGNALED(child_status)) {
2141 printf("svgalib:vga_safety_fork: Killed by signal %d, %s.\n",
2142 WTERMSIG(child_status),
2143 strsignal(WTERMSIG(child_status)));
2144 exit(1);
2145 }
2146 if (WIFSTOPPED(child_status)) {
2147 printf("svgalib:vga_safety_fork: Stopped by signal %d, %s.\n",
2148 WSTOPSIG(child_status),
2149 strsignal(WSTOPSIG(child_status)));
2150 puts("\aWARNING! Continue stopped svgalib application at own risk. You are better\n"
2151 "off killing it NOW!");
2152 continue;
2153 }
2154 }
2155 }
2156 /* These need to be done again because the child doesn't inherit them. */
2157 __svgalib_get_perm();
2158
2159 #ifdef BACKGROUND
2160 if (__svgalib_virtual_mem_fd>0)close(__svgalib_virtual_mem_fd);
2161 {
2162 char tmp[50];
2163 __svgalib_processnumber=getpid();
2164 sprintf(tmp,"/proc/%d/mem",__svgalib_processnumber);
2165 if ((__svgalib_virtual_mem_fd = open(tmp,O_RDWR)) < 0)
2166 {
2167 printf("svgalib: Cannot open /proc/%d/mem.\n",
2168 __svgalib_processnumber);
2169 exit(-1);
2170 }
2171 };
2172 #endif
2173 /*
2174 * But alas. That doesn't suffice. We raise the iopl here what merely makes
2175 * the previous call pointless.
2176 *
2177 * If IOPERM is set, assume permissions have already been set by Olaf Titz'
2178 * ioperm(1).
2179 */
2180
2181 if (CHIPSET != FBDEV && getenv("IOPERM") == NULL) {
2182 if (iopl(3) < 0) {
2183 printf("svgalib(vga_safety_fork): Cannot get I/O permissions.\n");
2184 exit(1);
2185 }
2186 }
2187 /*
2188 * Actually the mmap's are inherited anyway (and not all are remade here),
2189 * but it does not really harm.
2190 */
2191 #ifdef BACKGROUND
2192 /*
2193 * __vga_mmap() call is now really dangerous. You can only call
2194 * mmap once. Once virtual screen has been allocated its better
2195 * stay in one place. At least for now. Anyway this works now.
2196 */
2197 #else
2198 __vga_mmap();
2199 #endif
2200
2201
2202 /*
2203 * We might still want to do vc switches.
2204 */
2205
2206 __svgalib_takevtcontrol();
2207 }
2208
prepareforfontloading(void)2209 static void prepareforfontloading(void)
2210 {
2211 if (__svgalib_chipset == CIRRUS) {
2212 outb(SEQ_I, 0x0f);
2213 /* Disable CRT FIFO Fast-Page mode. */
2214 outb(SEQ_D, inb(SEQ_D) | 0x40);
2215 }
2216 }
2217
fontloadingcomplete(void)2218 static void fontloadingcomplete(void)
2219 {
2220 if (__svgalib_chipset == CIRRUS) {
2221 outb(SEQ_I, 0x0f);
2222 /* Re-enable CRT FIFO Fast-Page mode. */
2223 outb(SEQ_D, inb(SEQ_D) & 0xbf);
2224 }
2225 }
2226
2227
vga_setmode(int mode)2228 int vga_setmode(int mode)
2229 {
2230 int modeflags=mode&0xfffff000;
2231
2232 if(mode==-1)return vga_version;
2233
2234 mode&=0xfff;
2235 #ifdef BACKGROUND
2236 __svgalib_dont_switch_vt_yet();
2237 /* Can't initialize if screen is flipped. */
2238 if (__svgalib_oktowrite)
2239 #endif
2240 if (!initialized)
2241 initialize();
2242
2243 if (mode != TEXT && !chipset_modeavailable(mode))
2244 {
2245 #ifdef BACKGROUND
2246 __svgalib_is_vt_switching_needed();
2247 #endif
2248 return -1;
2249 }
2250
2251 #ifdef BACKGROUND
2252 if (!__svgalib_oktowrite)
2253 {
2254 prv_mode=CM;
2255 CM=mode;
2256 vga_setpage(0);
2257 __svgalib_is_vt_switching_needed();
2258 return(0);
2259 /* propably this was enough. */
2260 /* hmm.. there... virtual screen... */
2261 }
2262 #endif
2263
2264 /* if (!flip)
2265 vga_lockvc(); */
2266 disable_interrupt();
2267
2268 prv_mode = CM;
2269 CM = mode;
2270
2271 /* disable video */
2272 vga_screenoff();
2273
2274 if(!__svgalib_novga) {
2275 /* Should be more robust (eg. grabbed X modes) */
2276 if (__svgalib_getchipset() == ET4000
2277 && prv_mode != G640x480x256
2278 && SVGAMODE(prv_mode))
2279 chipset_setmode(G640x480x256, prv_mode);
2280
2281 /* This is a hack to get around the fact that some C&T chips
2282 * are programmed to ignore syncronous resets. So if we are
2283 * a C&T wait for retrace start
2284 */
2285 if (__svgalib_getchipset() == CHIPS) {
2286 while (((port_in(__svgalib_IS1_R)) & 0x08) == 0x08 );/* wait VSync off */
2287 while (((port_in(__svgalib_IS1_R)) & 0x08) == 0 ); /* wait VSync on */
2288 port_outw(0x07,SEQ_I); /* reset hsync - just in case... */
2289 }
2290 }
2291
2292 if (mode == TEXT) {
2293 /* Returning to textmode. */
2294
2295 if (SVGAMODE(prv_mode))
2296 vga_setpage(0);
2297
2298 /* The extended registers are restored either by the */
2299 /* chipset setregs function, or the chipset setmode function. */
2300
2301 /* restore font data - first select a 16 color graphics mode */
2302 /* Note: this should restore the old extended registers if */
2303 /* setregs is not defined for the chipset. */
2304 if(__svgalib_novga) __svgalib_driverspecs->setmode(TEXT, prv_mode);
2305 if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->restorefont) {
2306 __svgalib_driverspecs->emul->restorefont();
2307 chipset_setregs(text_regs, mode);
2308 } else if(!__svgalib_novga) {
2309 __svgalib_driverspecs->setmode(GPLANE16, prv_mode);
2310
2311 if (CHIPSET != EGA)
2312 /* restore old extended regs */
2313 chipset_setregs(text_regs, mode);
2314
2315 /* disable Set/Reset Register */
2316 port_out(0x01, GRA_I);
2317 port_out(0x00, GRA_D);
2318
2319 prepareforfontloading();
2320 restore_text();
2321
2322 /* restore font data in plane 2 - necessary for all VGA's */
2323 port_out(0x02, SEQ_I);
2324 port_out(0x04, SEQ_D);
2325 #ifdef __alpha__
2326 port_out(0x06, GRA_I);
2327 port_out(0x00, GRA_D);
2328 #endif
2329
2330 #ifdef BACKGROUND
2331 if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ|PROT_WRITE))
2332 {
2333 printf("svgalib: Memory protect error\n");
2334 exit(-1);
2335 }
2336 #endif
2337
2338 #if defined(CONFIG_ALPHA_JENSEN)
2339 slowcpy_to_sm(SM, font_buf1, FONT_SIZE);
2340 #else
2341 slowcpy(GM, font_buf1, FONT_SIZE);
2342 #endif
2343
2344 /* restore font data in plane 3 - necessary for Trident VGA's */
2345 port_out(0x02, SEQ_I);
2346 port_out(0x08, SEQ_D);
2347 #if defined(CONFIG_ALPHA_JENSEN)
2348 slowcpy_to_sm(SM, font_buf2, FONT_SIZE);
2349 #else
2350 slowcpy(GM, font_buf2, FONT_SIZE);
2351 #endif
2352 #ifdef BACKGROUND
2353 if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ))
2354 {
2355 printf("svgalib: Memory protect error\n");
2356 exit(1);
2357 }
2358 #endif
2359 fontloadingcomplete();
2360
2361 /* change register adresses if monochrome text mode */
2362 /* EGA is assumed to use color emulation. */
2363 if (!color_text) {
2364 __svgalib_CRT_I = CRT_IM;
2365 __svgalib_CRT_D = CRT_DM;
2366 __svgalib_IS1_R = IS1_RM;
2367 port_out(port_in(MIS_R) & 0xFE, MIS_W);
2368 }
2369 } else chipset_setregs(text_regs, mode);
2370 /* restore saved palette */
2371 restorepalette(text_red, text_green, text_blue);
2372
2373 /* restore text mode VGA registers */
2374 __svgalib_setregs(text_regs);
2375
2376 /* Set VMEM to some minimum value .. probably pointless.. */
2377 {
2378 vga_claimvideomemory(12);
2379 }
2380
2381 /* if (!flip) */
2382 /* enable text output - restores the screen contents */
2383 if (!__svgalib_secondary)
2384 ioctl(__svgalib_tty_fd, KDSETMODE, KD_TEXT);
2385
2386 /* now wait for signal to stabilize, but don't do it on C&T chips. */
2387 /* This is needed to restore correct text mode stretching. */
2388 if (__svgalib_chipset != CHIPS)
2389 usleep(MODESWITCHDELAY);
2390
2391 /* enable video */
2392 vga_screenon();
2393
2394 if (!flip)
2395 /* restore text mode termio */
2396 set_texttermio();
2397 } else {
2398 /* Setting a graphics mode. */
2399
2400 /* disable text output */
2401 if (!__svgalib_secondary)
2402 ioctl(__svgalib_tty_fd, KDSETMODE, KD_GRAPHICS);
2403
2404 if (SVGAMODE(prv_mode)) {
2405 /* The current mode is an SVGA mode, and we now want to */
2406 /* set a standard VGA mode. Make sure the extended regs */
2407 /* are restored. */
2408 /* Also used when setting another SVGA mode to hopefully */
2409 /* eliminate lock-ups. */
2410 vga_setpage(0);
2411 chipset_setregs(text_regs, mode);
2412 /* restore old extended regs */
2413 }
2414 /* shift to color emulation */
2415 setcoloremulation();
2416
2417 CI.xdim = infotable[mode].xdim;
2418 CI.ydim = infotable[mode].ydim;
2419 CI.colors = infotable[mode].colors;
2420 CI.xbytes = infotable[mode].xbytes;
2421 CI.bytesperpixel = infotable[mode].bytesperpixel;
2422
2423 chipset_setmode(mode, prv_mode);
2424 MODEX = 0;
2425
2426 /* Set default claimed memory (moved here from initialize - Michael.) */
2427 if (mode == G320x200x256)
2428 VMEM = 65536;
2429 else if (STDVGAMODE(mode))
2430 VMEM = 256 * 1024; /* Why always 256K ??? - Michael */
2431 else {
2432 vga_modeinfo *modeinfo;
2433
2434 modeinfo = vga_getmodeinfo(mode);
2435 VMEM = modeinfo->linewidth * modeinfo->height;
2436 CI.xbytes = modeinfo->linewidth;
2437 }
2438
2439 if (!flip) {
2440 /* set default palette */
2441 if (CI.colors <= 256)
2442 restorepalette(default_red, default_green, default_blue);
2443
2444 /* clear screen (sets current color to 15) */
2445 __svgalib_currentpage = -1;
2446 if(!(modeflags&0x8000))vga_clear();
2447
2448 if (SVGAMODE(__svgalib_cur_mode))
2449 vga_setpage(0);
2450 }
2451 __svgalib_currentpage = -1;
2452 currentlogicalwidth = CI.xbytes;
2453 currentdisplaystart = 0;
2454
2455 usleep(MODESWITCHDELAY); /* wait for signal to stabilize */
2456
2457 /* enable video */
2458 if (!flip)
2459 vga_screenon();
2460
2461 if (mouse_support && mouse_open) {
2462 /* vga_lockvc(); */
2463 mouse_setxrange(0, CI.xdim - 1);
2464 mouse_setyrange(0, CI.ydim - 1);
2465 mouse_setwrap(MOUSE_NOWRAP);
2466 mouse_mode = mode;
2467 } {
2468 vga_modeinfo *modeinfo;
2469 modeinfo = vga_getmodeinfo(mode);
2470 MODEX = ((MODEFLAGS = modeinfo->flags) & IS_MODEX);
2471 }
2472
2473 if (!flip)
2474 /* set graphics mode termio */
2475 set_graphtermio();
2476 else if (__svgalib_kbd_fd < 0)
2477 enable_interrupt();
2478 }
2479
2480 /* if (!flip)
2481 vga_unlockvc(); */
2482 #ifdef BACKGROUND
2483 __svgalib_is_vt_switching_needed();
2484 #endif
2485 return 0;
2486 }
2487
vga_gettextfont(void * font)2488 void vga_gettextfont(void *font)
2489 {
2490 unsigned int getsize;
2491
2492 getsize = fontbufsize;
2493 if (getsize > FONT_SIZE)
2494 getsize = FONT_SIZE;
2495 memcpy(font, font_buf1, getsize);
2496 if (fontbufsize > getsize)
2497 memset(((char *)font) + getsize, 0, (size_t)(fontbufsize - getsize));
2498 }
2499
vga_puttextfont(void * font)2500 void vga_puttextfont(void *font)
2501 {
2502 unsigned int putsize;
2503
2504 #ifdef BACKGROUND
2505 if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ|PROT_WRITE))
2506 {
2507 printf("svgalib: Memory protect error\n");
2508 exit(-1);
2509 }
2510 #endif
2511
2512 putsize = fontbufsize;
2513 if (putsize > FONT_SIZE)
2514 putsize = FONT_SIZE;
2515 memcpy(font_buf1, font, putsize);
2516 memcpy(font_buf2, font, putsize);
2517 if (putsize < FONT_SIZE) {
2518 memset(font_buf1 + putsize, 0, (size_t)(FONT_SIZE - putsize));
2519 memset(font_buf2 + putsize, 0, (size_t)(FONT_SIZE - putsize));
2520 }
2521
2522 #ifdef BACKGROUND
2523 if (-1 == mprotect(font_buf1,FONT_SIZE*2,PROT_READ))
2524 {
2525 printf("svgalib: Memory protect error\n");
2526 exit(-1);
2527 }
2528 #endif
2529 }
2530
vga_gettextmoderegs(void * regs)2531 void vga_gettextmoderegs(void *regs)
2532 {
2533 memcpy(regs, text_regs, MAX_REGS);
2534 }
2535
vga_settextmoderegs(void * regs)2536 void vga_settextmoderegs(void *regs)
2537 {
2538 memcpy(text_regs, regs, MAX_REGS);
2539 }
2540
vga_getcurrentmode(void)2541 int vga_getcurrentmode(void)
2542 {
2543 return CM;
2544 }
2545
vga_getcurrentchipset(void)2546 int vga_getcurrentchipset(void)
2547 {
2548 return __svgalib_getchipset();
2549 }
2550
vga_disabledriverreport(void)2551 void vga_disabledriverreport(void)
2552 {
2553 DREP = 0;
2554 }
2555
vga_getmodeinfo(int mode)2556 vga_modeinfo *vga_getmodeinfo(int mode)
2557 {
2558 static vga_modeinfo modeinfo;
2559 int is_modeX = (CM == mode) && MODEX;
2560
2561 modeinfo.linewidth = infotable[mode].xbytes;
2562 __svgalib_getchipset();
2563 if (mode > vga_lastmodenumber())
2564 return NULL;
2565 modeinfo.width = infotable[mode].xdim;
2566 modeinfo.height = infotable[mode].ydim;
2567 modeinfo.bytesperpixel = infotable[mode].bytesperpixel;
2568 modeinfo.colors = infotable[mode].colors;
2569 if (is_modeX) {
2570 modeinfo.linewidth = modeinfo.width / 4;
2571 modeinfo.bytesperpixel = 0;
2572 }
2573 if (mode == TEXT) {
2574 modeinfo.flags = HAVE_EXT_SET;
2575 return &modeinfo;
2576 }
2577 modeinfo.flags = 0;
2578 if ((STDVGAMODE(mode) && mode != G320x200x256) || is_modeX)
2579 __svgalib_vga_driverspecs.getmodeinfo(mode, &modeinfo);
2580 else
2581 /* Get chipset specific info for SVGA modes and */
2582 /* 320x200x256 (chipsets may support more pages) */
2583 chipset_getmodeinfo(mode, &modeinfo);
2584
2585 if (modeinfo.colors == 256 && modeinfo.bytesperpixel == 0)
2586 modeinfo.flags |= IS_MODEX;
2587 if (mode > __GLASTMODE)
2588 modeinfo.flags |= IS_DYNAMICMODE;
2589
2590 /* Maskout CAPABLE_LINEAR if requested by config file */
2591 modeinfo.flags &= modeinfo_mask;
2592
2593 /* Many cards have problems with linear 320x200x256 mode */
2594 if(mode==G320x200x256)modeinfo.flags &= (~CAPABLE_LINEAR) & (~IS_LINEAR) ;
2595
2596 /* If all needed info is here, signal if linear support has been enabled */
2597 if ((modeinfo.flags & (CAPABLE_LINEAR | EXT_INFO_AVAILABLE)) ==
2598 (CAPABLE_LINEAR | EXT_INFO_AVAILABLE)) {
2599 modeinfo.flags |= __svgalib_modeinfo_linearset;
2600 }
2601
2602 #ifdef BACKGROUND
2603 #if 0 /* vga_set[rw]page() don't work if compile for background, even when in foreground. */
2604 if (__svgalib_runinbackground) /* these cannot be provided if we are really in background */
2605 #endif
2606 modeinfo.flags &= ~HAVE_RWPAGE;
2607 #endif
2608
2609 return &modeinfo;
2610 }
2611
vga_hasmode(int mode)2612 int vga_hasmode(int mode)
2613 {
2614 __svgalib_getchipset(); /* Make sure the chipset is known. */
2615 if (mode == TEXT)
2616 return 1;
2617 if (mode < 0 || mode > lastmodenumber)
2618 return 0;
2619 return (chipset_modeavailable(mode) != 0);
2620 }
2621
2622
vga_lastmodenumber(void)2623 int vga_lastmodenumber(void)
2624 {
2625 __svgalib_getchipset();
2626 return lastmodenumber;
2627 }
2628
2629
__svgalib_addmode(int xdim,int ydim,int cols,int xbytes,int bytespp)2630 int __svgalib_addmode(int xdim, int ydim, int cols, int xbytes, int bytespp)
2631 {
2632 int i;
2633
2634 for (i = 0; i <= lastmodenumber; ++i)
2635 if (infotable[i].xdim == xdim &&
2636 infotable[i].ydim == ydim &&
2637 infotable[i].colors == cols &&
2638 infotable[i].bytesperpixel == bytespp &&
2639 infotable[i].xbytes == xbytes)
2640 return i;
2641 if (lastmodenumber >= MAX_MODES - 1)
2642 return -1; /* no more space available */
2643 ++lastmodenumber;
2644 infotable[lastmodenumber].xdim = xdim;
2645 infotable[lastmodenumber].ydim = ydim;
2646 infotable[lastmodenumber].colors = cols;
2647 infotable[lastmodenumber].xbytes = xbytes;
2648 infotable[lastmodenumber].bytesperpixel = bytespp;
2649
2650 return lastmodenumber;
2651 }
2652
vga_getcrtcregs(unsigned char * regs)2653 int vga_getcrtcregs(unsigned char *regs) {
2654 int i;
2655
2656 for (i = 0; i < CRT_C; i++) {
2657 regs[i] = __svgalib_incrtc(i);
2658 }
2659 return 0;
2660 }
2661
vga_setcrtcregs(unsigned char * regs)2662 int vga_setcrtcregs(unsigned char *regs) {
2663 int i;
2664
2665 if(CM>9) return -1;
2666
2667 __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);
2668 for (i = 0; i < CRT_C; i++) {
2669 __svgalib_outcrtc(i,regs[i]);
2670 }
2671
2672 return 0;
2673 }
2674
vga_setcolor(int color)2675 int vga_setcolor(int color)
2676 {
2677 switch (CI.colors) {
2678 case 2:
2679 if (color != 0)
2680 color = 15;
2681 case 16: /* update set/reset register */
2682 #ifdef BACKGROUND
2683 __svgalib_dont_switch_vt_yet();
2684 if (!__svgalib_oktowrite)
2685 {
2686 color=color & 15;
2687 COL = color;
2688 }
2689 else
2690 {
2691 #endif
2692 port_out(0x00, GRA_I);
2693 port_out((color & 15), GRA_D);
2694 #ifdef BACKGROUND
2695 }
2696 __svgalib_is_vt_switching_needed();
2697 #endif
2698 break;
2699 default:
2700 COL = color;
2701 break;
2702 }
2703 return 0;
2704 }
2705
2706
vga_screenoff(void)2707 int vga_screenoff(void)
2708 {
2709 int tmp = 0;
2710
2711 SCREENON = 0;
2712
2713 if(__svgalib_novga) return 0;
2714 #ifdef BACKGROUND
2715 __svgalib_dont_switch_vt_yet();
2716 if (!__svgalib_oktowrite) {
2717 __svgalib_is_vt_switching_needed();
2718 return(0);
2719 }
2720 #endif
2721
2722 if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->screenoff) {
2723 tmp = __svgalib_driverspecs->emul->screenoff();
2724 } else {
2725 /* turn off screen for faster VGA memory acces */
2726 if (CHIPSET != EGA) {
2727 port_out(0x01, SEQ_I);
2728 port_out(port_in(SEQ_D) | 0x20, SEQ_D);
2729 }
2730 /* Disable video output */
2731 #ifdef DISABLE_VIDEO_OUTPUT
2732 port_in(__svgalib_IS1_R);
2733 __svgalib_delay();
2734 port_out(0x00, ATT_IW);
2735 #endif
2736 }
2737
2738 #ifdef BACKGROUND
2739 __svgalib_is_vt_switching_needed();
2740 #endif
2741 return tmp;
2742 }
2743
2744
vga_screenon(void)2745 int vga_screenon(void)
2746 {
2747 int tmp = 0;
2748
2749 SCREENON = 1;
2750 if(__svgalib_novga) return 0;
2751 #ifdef BACKGROUND
2752 __svgalib_dont_switch_vt_yet();
2753 if (!__svgalib_oktowrite) {
2754 __svgalib_is_vt_switching_needed();
2755 return(0);
2756 }
2757 #endif
2758 if (__svgalib_driverspecs->emul && __svgalib_driverspecs->emul->screenon) {
2759 tmp = __svgalib_driverspecs->emul->screenon();
2760 } else {
2761 /* turn screen back on */
2762 if (CHIPSET != EGA) {
2763 port_out(0x01, SEQ_I);
2764 port_out(port_in(SEQ_D) & 0xDF, SEQ_D);
2765 }
2766 /* #ifdef DISABLE_VIDEO_OUTPUT */
2767 /* enable video output */
2768 port_in(__svgalib_IS1_R);
2769 __svgalib_delay();
2770 port_out(0x20, ATT_IW);
2771 /* #endif */
2772 }
2773
2774 #ifdef BACKGROUND
2775 __svgalib_is_vt_switching_needed();
2776 #endif
2777 return 0;
2778 }
2779
2780
vga_getxdim(void)2781 int vga_getxdim(void)
2782 {
2783 return CI.xdim;
2784 }
2785
2786
vga_getydim(void)2787 int vga_getydim(void)
2788 {
2789 return CI.ydim;
2790 }
2791
2792
vga_getcolors(void)2793 int vga_getcolors(void)
2794 {
2795 return CI.colors;
2796 }
2797
vga_white(void)2798 int vga_white(void)
2799 {
2800 switch (CI.colors) {
2801 case 2:
2802 case 16:
2803 case 256:
2804 return 15;
2805 case 1 << 15:
2806 return 32767;
2807 case 1 << 16:
2808 return 65535;
2809 case 1 << 24:
2810 return (1 << 24) - 1;
2811 }
2812 return CI.colors - 1;
2813 }
2814
vga_claimvideomemory(int m)2815 int vga_claimvideomemory(int m)
2816 {
2817 vga_modeinfo *modeinfo;
2818 int cardmemory;
2819
2820 modeinfo = vga_getmodeinfo(CM);
2821 if (m < VMEM)
2822 return 0;
2823 if (modeinfo->colors == 16)
2824 cardmemory = modeinfo->maxpixels / 2;
2825 else
2826 cardmemory = (modeinfo->maxpixels * modeinfo->bytesperpixel
2827 + 2) & 0xffff0000;
2828 /* maxpixels * bytesperpixel can be 2 less than video memory in */
2829 /* 3 byte-per-pixel modes; assume memory is multiple of 64K */
2830 if (m > cardmemory)
2831 return -1;
2832 VMEM = m;
2833 return 0;
2834 }
2835
vga_setmodeX(void)2836 int vga_setmodeX(void)
2837 {
2838 switch (CM) {
2839 case TEXT:
2840 /* case G320x200x256: */
2841 case G320x240x256:
2842 case G320x400x256:
2843 case G360x480x256:
2844 return 0;
2845 }
2846 if (CI.colors == 256 && VMEM < 256 * 1024) {
2847 port_out(4, SEQ_I); /* switch from linear to plane memory */
2848 port_out((port_in(SEQ_D) & 0xF7) | 0x04, SEQ_D);
2849 port_out(0x14, __svgalib_CRT_I); /* switch double word mode off */
2850 port_out((port_in(__svgalib_CRT_D) & 0xBF), __svgalib_CRT_D);
2851 port_out(0x17, __svgalib_CRT_I);
2852 port_out((port_in(__svgalib_CRT_D) | 0x40), __svgalib_CRT_D);
2853 CI.xbytes = CI.xdim / 4;
2854 vga_setpage(0);
2855 MODEX = 1;
2856 return 1;
2857 }
2858 return 0;
2859 }
2860
2861
2862 static int saved_page;
2863 static int saved_logicalwidth;
2864 static int saved_displaystart;
2865 static int saved_modeX;
2866 #ifdef BACKGROUND
2867 static int saved_linearset;
2868 #endif
2869
savestate(void)2870 static void savestate(void)
2871 {
2872 int i;
2873
2874 vga_screenoff();
2875
2876 savepalette(graph_red, graph_green, graph_blue);
2877
2878 saved_page = __svgalib_currentpage;
2879 saved_logicalwidth = currentlogicalwidth;
2880 saved_displaystart = currentdisplaystart;
2881 saved_modeX = MODEX;
2882 #ifdef BACKGROUND
2883 saved_linearset = __svgalib_modeinfo_linearset;
2884 #endif
2885
2886 if (CM == G320x200x256 && VMEM <= 65536) {
2887 #ifndef BACKGROUND
2888 /* 320x200x256 is a special case; only 64K is addressable */
2889 /* (unless more has been claimed, in which case we assume */
2890 /* SVGA bank-switching) */
2891 if ((graph_buf = malloc(GRAPH_SIZE)) == NULL) {
2892 #endif
2893 #ifdef BACKGROUND
2894 #if BACKGROUND == 1
2895 if ((graph_buf = valloc(GRAPH_SIZE)) == NULL)
2896 {
2897 #endif
2898 #if BACKGROUND == 2
2899 if ((graph_buf = malloc(GRAPH_SIZE)) == NULL) {
2900 #endif
2901 #endif
2902 printf("Cannot allocate memory for VGA state\n");
2903 vga_setmode(TEXT);
2904 exit(1);
2905 }
2906 memcpy(graph_buf, GM, GRAPH_SIZE);
2907 } else if (MODEX || CM == G800x600x16 || (STDVGAMODE(CM) && CM != G320x200x256)) {
2908 /* for planar VGA modes, save the full 256K */
2909 __svgalib_vga_driverspecs.setmode(GPLANE16, prv_mode);
2910 #ifndef BACKGROUND
2911 if ((graph_buf = malloc(4 * GRAPH_SIZE)) == NULL) {
2912 #endif
2913 #ifdef BACKGROUND
2914 #if BACKGROUND == 1
2915 if ((graph_buf = valloc(4 * GRAPH_SIZE)) == NULL)
2916 {
2917 #endif
2918 #if BACKGROUND == 2
2919 if ((graph_buf = malloc(4 * GRAPH_SIZE)) == NULL) {
2920 #endif
2921 #endif
2922 printf("Cannot allocate memory for VGA state\n");
2923 vga_setmode(TEXT);
2924 exit(1);
2925 }
2926 for (i = 0; i < 4; i++) {
2927 /* save plane i */
2928 port_out(0x04, GRA_I);
2929 port_out(i, GRA_D);
2930 memcpy(graph_buf + i * GRAPH_SIZE, GM, GRAPH_SIZE);
2931 }
2932 } else if (CI.colors == 16) {
2933 int page, size, sbytes;
2934 unsigned char *sp;
2935
2936 size = VMEM;
2937 #ifndef BACKGROUND
2938 if ((graph_buf = malloc(4 * size)) == NULL) {
2939 #endif
2940 #ifdef BACKGROUND
2941 #if BACKGROUND == 1
2942 if ((graph_buf = valloc(4 * size)) == NULL) {
2943 #endif
2944 #if BACKGROUND == 2
2945 if ((graph_buf = malloc(4 * size)) == NULL) {
2946 #endif
2947 #endif
2948 printf("Cannot allocate memory for VGA state\n");
2949 vga_setmode(TEXT);
2950 exit(1);
2951 }
2952 sp = graph_buf;
2953 for (page = 0; size > 0; ++page) {
2954 vga_setpage(page);
2955 sbytes = (size > GRAPH_SIZE) ? GRAPH_SIZE : size;
2956 for (i = 0; i < 4; i++) {
2957 /* save plane i */
2958 port_out(0x04, GRA_I);
2959 port_out(i, GRA_D);
2960 memcpy(sp, GM, sbytes);
2961 sp += sbytes;
2962 }
2963 size -= sbytes;
2964 }
2965 #ifdef BACKGROUND
2966 } else if (__svgalib_modeinfo_linearset & IS_LINEAR) { /* linear modes */
2967 if (! graph_buf2) { /* graph_buf2 only gets allocated _once_, and then reused */
2968 int page_size=getpagesize();
2969 if (! (graph_buf2=malloc(__svgalib_linear_memory_size+page_size-1))) {
2970 printf("Cannot allocate memory for linear state.\n");
2971 vga_setmode(TEXT);
2972 exit(1);
2973 }
2974 #ifdef LINEAR_DEBUG
2975 printf("Allocated %d bytes for background screen storage\n",
2976 __svgalib_linear_memory_size);
2977 #endif
2978 graph_buf2 = (unsigned char *) /* make graph_buf2 page aligned */
2979 (((unsigned long)graph_buf2 + page_size - 1) & ~(page_size-1));
2980 }
2981
2982 if (! (graph_buf=malloc(GRAPH_SIZE/*__svgalib_linear_memory_size*/))) {
2983 printf("Cannot allocate memory for planar state.\n");
2984 vga_setmode(TEXT);
2985 exit(1);
2986 }
2987 memcpy(graph_buf2,__svgalib_linearframebuffer,__svgalib_linear_memory_size);
2988 /* cpg: the following memcpy is needed, else the mmap() call in */
2989 /* __svgalib_map_virtual_screen() bombs out with "invalid argument" */
2990 /* (kernel 2.1.125) */
2991 memcpy(graph_buf,__svgalib_linearframebuffer,GRAPH_SIZE/*__svgalib_linear_memory_size*/);
2992 #endif
2993 } else { /* SVGA, and SVGA 320x200x256 if videomemoryused > 65536 */
2994 int size;
2995 int page;
2996
2997 size = VMEM;
2998
2999 #ifdef DEBUG
3000 printf("Saving %dK of video memory.\n", (size + 2) / 1024);
3001 #endif
3002 #ifndef BACKGROUND
3003 if ((graph_buf = malloc(size)) == NULL) {
3004 #endif
3005 #ifdef BACKGROUND
3006 #if BACKGROUND == 1
3007 /* Must allocate hole videopage. */
3008 if ((graph_buf = valloc((size/GRAPH_SIZE+1)*GRAPH_SIZE)) == NULL) {
3009 #endif
3010 #if BACKGROUND == 2
3011 if ((graph_buf = malloc(size)) == NULL) {
3012 #endif
3013 #endif
3014 printf("Cannot allocate memory for SVGA state.\n");
3015 vga_setmode(TEXT);
3016 exit(1);
3017 }
3018 page = 0;
3019 while (size >= 65536) {
3020 vga_setpage(page);
3021 memcpy(graph_buf + page * 65536, GM, 65536);
3022 page++;
3023 size -= 65536;
3024 }
3025 #ifdef BACKGROUND
3026 #if BACKGROUND == 1
3027 /* Whole page must be written for mmap(). */
3028 if (size > 0) {
3029 vga_setpage(page);
3030 memcpy(graph_buf + page * 65536, GM, GRAPH_SIZE);
3031 }
3032 #endif
3033 #if BACKGROUND == 2
3034 if (size > 0) {
3035 vga_setpage(page);
3036 memcpy(graph_buf + page * 65536, GM, size);
3037 }
3038 #endif
3039 #endif
3040 #ifndef BACKGROUND
3041 if (size > 0) {
3042 vga_setpage(page);
3043 memcpy(graph_buf + page * 65536, GM, size);
3044 }
3045 #endif
3046 }
3047 }
3048
3049 static void restorestate(void)
3050 {
3051 int i;
3052
3053 vga_screenoff();
3054
3055 if (saved_modeX)
3056 vga_setmodeX();
3057
3058 restorepalette(graph_red, graph_green, graph_blue);
3059
3060 if (CM == G320x200x256 && VMEM <= 65536) {
3061 memcpy(GM, graph_buf, 65536);
3062 } else if (MODEX || CM == G800x600x16 || (STDVGAMODE(CM) && CM != G320x200x256)) {
3063 int setresetreg, planereg;
3064 /* disable Set/Reset Register */
3065 port_out(0x01, GRA_I);
3066 setresetreg = inb(GRA_D);
3067 port_out(0x00, GRA_D);
3068 outb(SEQ_I, 0x02);
3069 planereg = inb(SEQ_D);
3070
3071 for (i = 0; i < 4; i++) {
3072 /* restore plane i */
3073 port_out(0x02, SEQ_I);
3074 port_out(1 << i, SEQ_D);
3075 memcpy(GM, graph_buf + i * GRAPH_SIZE, GRAPH_SIZE);
3076 }
3077 outb(GRA_I, 0x01);
3078 outb(GRA_D, setresetreg);
3079 outb(SEQ_I, 0x02);
3080 outb(SEQ_D, planereg);
3081 } else if (CI.colors == 16) {
3082 int page, size, rbytes;
3083 unsigned char *rp;
3084 int setresetreg, planereg;
3085
3086 /* disable Set/Reset Register */
3087 port_out(0x01, GRA_I);
3088 if (CHIPSET == EGA)
3089 setresetreg = 0;
3090 else
3091 setresetreg = inb(GRA_D);
3092 port_out(0x00, GRA_D);
3093 port_out(0x02, SEQ_I);
3094 if (CHIPSET == EGA)
3095 planereg = 0;
3096 else
3097 planereg = inb(SEQ_D);
3098
3099 size = VMEM;
3100 rp = graph_buf;
3101 for (page = 0; size > 0; ++page) {
3102 vga_setpage(page);
3103 rbytes = (size > GRAPH_SIZE) ? GRAPH_SIZE : size;
3104 for (i = 0; i < 4; i++) {
3105 /* save plane i */
3106 port_out(0x02, SEQ_I);
3107 port_out(1 << i, SEQ_D);
3108 memcpy(GM, rp, rbytes);
3109 rp += rbytes;
3110 }
3111 size -= rbytes;
3112 }
3113
3114 outb(GRA_I, 0x01);
3115 outb(GRA_D, setresetreg);
3116 outb(SEQ_I, 0x02);
3117 outb(SEQ_D, planereg);
3118 #ifdef BACKGROUND
3119 } else if (saved_linearset & IS_LINEAR) {
3120 memcpy(__svgalib_linearframebuffer,graph_buf2,__svgalib_linear_memory_size);
3121 #ifdef LINEAR_DEBUG
3122 dump_mem("restore-lin");
3123 #endif
3124 #endif
3125 } else {
3126 /* vga_modeinfo *modeinfo; */
3127 int size;
3128 int page;
3129 size = VMEM;
3130
3131 #ifdef DEBUG
3132 printf("Restoring %dK of video memory.\n", (size + 2) / 1024);
3133 #endif
3134 page = 0;
3135 while (size >= 65536) {
3136 vga_setpage(page);
3137 memcpy(GM, graph_buf + page * 65536, 65536);
3138 size -= 65536;
3139 page++;
3140 }
3141 if (size > 0) {
3142 vga_setpage(page);
3143 memcpy(GM, graph_buf + page * 65536, size);
3144 }
3145 }
3146
3147 if (saved_logicalwidth != CI.xbytes)
3148 vga_setlogicalwidth(saved_logicalwidth);
3149 if (saved_page != 0)
3150 vga_setpage(saved_page);
3151 if (saved_displaystart != 0)
3152 vga_setdisplaystart(saved_displaystart);
3153
3154 vga_screenon();
3155
3156 free(graph_buf);
3157 }
3158
3159
3160 int vga_getch(void)
3161 {
3162 char c;
3163
3164 if (CM == TEXT)
3165 return -1;
3166
3167 while ((read(__svgalib_tty_fd, &c, 1) < 0) && (errno == EINTR));
3168
3169 return c;
3170 }
3171
3172 #ifdef BACKGROUND
3173 int __svgalib_flip_status(void)
3174
3175 {
3176 return(flip);
3177 }
3178 #endif
3179
3180 /* I have kept the slightly funny 'flip' terminology. */
3181
3182 void __svgalib_flipaway(void)
3183 {
3184 /* Leaving console. */
3185 flip_mode = CM;
3186 #ifndef SVGA_AOUT
3187 __joystick_flip_vc(0);
3188 #endif
3189 if (CM != TEXT) {
3190 /* wait for any blitter operation to finish */
3191 idle_accel();
3192 /* Save state and go to textmode. */
3193 __svgalib_saveregs(graph_regs);
3194 savestate();
3195 flip = 1;
3196 if(!__svgalib_secondary)vga_setmode(TEXT);
3197 flip = 0;
3198
3199 if(!__svgalib_secondary){
3200 #ifdef BACKGROUND
3201 /* Let's put bg screen to right place */
3202
3203 #if BACKGROUND == 1
3204 if (__svgalib_currentpage<0) __svgalib_currentpage=0;
3205 __svgalib_map_virtual_screen(__svgalib_currentpage);
3206 #endif
3207 #if BACKGROUND == 2
3208 __svgalib_graph_mem=graph_buf+(GRAPH_SIZE*__svgalib_currentpage);
3209 #endif
3210 __svgalib_oktowrite=0; /* screen is fliped, not __svgalib_oktowrite. */
3211 #endif
3212 }
3213 }
3214 }
3215
3216 #ifndef BACKGROUND
3217 static void __svgalib_flipback(void)
3218 #endif
3219 #ifdef BACKGROUND
3220 void __svgalib_flipback(void)
3221 #endif
3222 {
3223 #ifdef BACKGROUND
3224 int tmp_page=__svgalib_currentpage;
3225 #endif
3226 /* Entering console. */
3227 /* Hmmm... and how about unlocking anything someone else locked? */
3228 #ifndef SVGA_AOUT
3229 __joystick_flip_vc(1);
3230 #endif
3231 chipset_unlock();
3232 if (flip_mode != TEXT) {
3233 /* Restore graphics mode and state. */
3234 if(!__svgalib_secondary){
3235 #ifdef BACKGROUND
3236 __svgalib_oktowrite=1;
3237 #endif
3238 flip = 1;
3239 vga_setmode(flip_mode);
3240 flip = 0;
3241 #ifdef BACKGROUND
3242 #if BACKGROUND == 1
3243 __svgalib_map_virtual_screen(1000000);
3244 #endif
3245 #if BACKGROUND == 2
3246 __svgalib_graph_mem=__svgalib_graph_mem_orginal;
3247 #endif
3248 /* do we need to explicitly enable linear? */
3249 if ((saved_linearset & IS_LINEAR) && /* if old mode was linear */
3250 __svgalib_driverspecs->linear) { /* and linear function present */
3251 __svgalib_driverspecs->linear(LINEAR_ENABLE, (long)__svgalib_physaddr);
3252 }
3253 #endif
3254 __svgalib_setregs(graph_regs);
3255 restorestate();
3256 #ifdef BACKGROUND
3257 /* Has to make sure right page is on. */
3258 vga_setpage(tmp_page);
3259 vga_setcolor(COL);
3260 #endif
3261 }
3262 }
3263 }
3264
3265 int vga_flip(void)
3266 {
3267 #ifdef BACKGROUND
3268 int tmp_page=__svgalib_currentpage;
3269 #endif
3270 if (CM != TEXT) { /* save state and go to textmode */
3271 savestate();
3272 flip_mode = CM;
3273 flip = 1;
3274 vga_setmode(TEXT);
3275 flip = 0;
3276 #ifdef BACKGROUND
3277 /* Lets put bg screen to right place */
3278
3279 #if BACKGROUND == 1
3280 if (__svgalib_currentpage<0) __svgalib_currentpage=0;
3281 __svgalib_map_virtual_screen(__svgalib_currentpage);
3282 #endif
3283 #if BACKGROUND == 2
3284 __svgalib_graph_mem=graph_buf+(GRAPH_SIZE*__svgalib_currentpage);;
3285 #endif
3286 __svgalib_oktowrite=0; /* screen is fliped, not __svgalib_oktowrite. */
3287 #endif
3288 } else { /* restore graphics mode and state */
3289 #ifdef BACKGROUND
3290 __svgalib_oktowrite=1;
3291 /* Probably here too ... */
3292 chipset_unlock();
3293 #endif
3294 flip = 1;
3295 vga_setmode(flip_mode);
3296 flip = 0;
3297 #ifdef BACKGROUND
3298 #if BACKGROUND == 1
3299 __svgalib_map_virtual_screen(1000000);
3300 #endif
3301 #if BACKGROUND == 2
3302 __svgalib_graph_mem=__svgalib_graph_mem_orginal;
3303 #endif
3304 if (__svgalib_modeinfo_linearset & IS_LINEAR) {
3305 int (*lfn) (int op, int param) = __svgalib_driverspecs->linear;
3306 if (lfn) (*lfn) (LINEAR_ENABLE, (long)__svgalib_physaddr);
3307 }
3308 #endif
3309 restorestate();
3310 #ifdef BACKGROUND
3311 /* Has to make sure right page is on. */
3312 vga_setpage(tmp_page);
3313 vga_setcolor(COL);
3314 #endif
3315 }
3316 return 0;
3317 }
3318
3319
3320 int vga_setflipchar(int c)
3321 /* This function is obsolete. Retained for VGAlib compatibility. */
3322 {
3323 __svgalib_flipchar = c;
3324
3325 return 0;
3326 }
3327
3328 void vga_setlogicalwidth(int w)
3329 {
3330 __svgalib_driverspecs->setlogicalwidth(w);
3331 currentlogicalwidth = w;
3332 }
3333
3334 void vga_setdisplaystart(int a)
3335 {
3336 currentdisplaystart = a;
3337 if (CHIPSET != VGA && CHIPSET != EGA)
3338 if (MODEX || CI.colors == 16) {
3339 /* We are currently using a Mode X-like mode on a */
3340 /* SVGA card, use the standard VGA function */
3341 /* that works properly for Mode X. */
3342 /* Same goes for 16 color modes. */
3343 __svgalib_vga_driverspecs.setdisplaystart(a);
3344 return;
3345 }
3346 /* Call the regular display start function for the chipset */
3347 __svgalib_driverspecs->setdisplaystart(a);
3348 }
3349
3350 void vga_bitblt(int srcaddr, int destaddr, int w, int h, int pitch)
3351 {
3352 __svgalib_driverspecs->bitblt(srcaddr, destaddr, w, h, pitch);
3353 }
3354
3355 void vga_imageblt(void *srcaddr, int destaddr, int w, int h, int pitch)
3356 {
3357 __svgalib_driverspecs->imageblt(srcaddr, destaddr, w, h, pitch);
3358 }
3359
3360 void vga_fillblt(int destaddr, int w, int h, int pitch, int c)
3361 {
3362 __svgalib_driverspecs->fillblt(destaddr, w, h, pitch, c);
3363 }
3364
3365 void vga_hlinelistblt(int ymin, int n, int *xmin, int *xmax, int pitch,
3366 int c)
3367 {
3368 __svgalib_driverspecs->hlinelistblt(ymin, n, xmin, xmax, pitch, c);
3369 }
3370
3371 void vga_blitwait(void)
3372 {
3373 __svgalib_driverspecs->bltwait();
3374 }
3375
3376 int vga_ext_set(unsigned what,...)
3377 {
3378 va_list params;
3379 register int retval = 0;
3380
3381 switch(what) {
3382 case VGA_EXT_AVAILABLE:
3383 /* Does this use of the arglist corrupt non-AVAIL_ACCEL ext_set? */
3384 va_start(params, what);
3385 switch (va_arg(params, int)) {
3386 case VGA_AVAIL_ACCEL:
3387 if (__svgalib_driverspecs->accelspecs != NULL)
3388 retval = __svgalib_driverspecs->accelspecs->operations;
3389 break;
3390 case VGA_AVAIL_ROP:
3391 if (__svgalib_driverspecs->accelspecs != NULL)
3392 retval = __svgalib_driverspecs->accelspecs->ropOperations;
3393 break;
3394 case VGA_AVAIL_TRANSPARENCY:
3395 if (__svgalib_driverspecs->accelspecs != NULL)
3396 retval = __svgalib_driverspecs->accelspecs->transparencyOperations;
3397 break;
3398 case VGA_AVAIL_ROPMODES:
3399 if (__svgalib_driverspecs->accelspecs != NULL)
3400 retval = __svgalib_driverspecs->accelspecs->ropModes;
3401 break;
3402 case VGA_AVAIL_TRANSMODES:
3403 if (__svgalib_driverspecs->accelspecs != NULL)
3404 retval = __svgalib_driverspecs->accelspecs->transparencyModes;
3405 break;
3406 case VGA_AVAIL_SET:
3407 retval = (1 << VGA_EXT_PAGE_OFFSET) |
3408 (1 << VGA_EXT_FONT_SIZE); /* These are handled by us */
3409 break;
3410 }
3411 va_end(params);
3412 break;
3413 case VGA_EXT_PAGE_OFFSET:
3414 /* Does this use of the arglist corrupt it? */
3415 va_start(params, what);
3416 retval = vga_page_offset;
3417 vga_page_offset = va_arg(params, int);
3418 va_end(params);
3419 return retval;
3420 case VGA_EXT_FONT_SIZE:
3421 va_start(params, what);
3422 what = va_arg(params, unsigned int);
3423 va_end(params);
3424 if (!what)
3425 return FONT_SIZE;
3426 retval = fontbufsize;
3427 fontbufsize = what;
3428 return retval;
3429 }
3430 if ((CM != TEXT) && (MODEFLAGS & HAVE_EXT_SET)) {
3431 va_start(params, what);
3432 retval |= __svgalib_driverspecs->ext_set(what, params);
3433 va_end(params);
3434 }
3435 return retval;
3436 }
3437
3438 /* Parse a string for options.. str is \0-terminated source,
3439 commands is an array of char ptrs (last one is NULL) containing commands
3440 to parse for. (if first char is ! case sensitive),
3441 func is called with ind the index of the detected command.
3442 func has to return the ptr to the next unhandled token returned by strtok(NULL," ").
3443 Use strtok(NULL," ") to get the next token from the file..
3444 mode is 1 when reading from conffile and 0 when parsing the env-vars. This is to
3445 allow disabling of dangerous (hardware damaging) options when reading the ENV-Vars
3446 of Joe user.
3447 Note: We use strtok, that is str is destroyed! */
3448 static void parse_string(char *str, char **commands, char *(*func) (int ind, int mode), int mode)
3449 {
3450 int index;
3451 register char *ptr, **curr;
3452
3453 /*Pass one, delete comments,ensure only whitespace is ' ' */
3454 for (ptr = str; *ptr; ptr++) {
3455 if (*ptr == '#') {
3456 while (*ptr && (*ptr != '\n')) {
3457 *ptr++ = ' ';
3458 }
3459 if (*ptr)
3460 *ptr = ' ';
3461 } else if (isspace(*ptr)) {
3462 *ptr = ' ';
3463 }
3464 }
3465 /*Pass two, parse commands */
3466 ptr = strtok(str, " ");
3467 while (ptr) {
3468 #ifdef DEBUG_CONF
3469 printf("Parsing: %s\n", ptr);
3470 #endif
3471 for (curr = commands, index = 0; *curr; curr++, index++) {
3472 #ifdef DEBUG_CONF
3473 printf("Checking: %s\n", *curr);
3474 #endif
3475 if (**curr == '!') {
3476 if (!strcmp(*curr + 1, ptr)) {
3477 ptr = (*func) (index, mode);
3478 break;
3479 }
3480 } else {
3481 if (!strcasecmp(*curr, ptr)) {
3482 ptr = (*func) (index, mode);
3483 break;
3484 }
3485 }
3486 }
3487 if (!*curr) /*unknow command */
3488 ptr = strtok(NULL, " "); /* skip silently til' next command */
3489 }
3490 }
3491
3492 static int allowoverride = 0; /* Allow dangerous options in ENV-Var or in */
3493 /* the $HOME/.svgalibrc */
3494
3495 static void process_config_file(FILE *file, int mode, char **commands,
3496 char *(*func)(int ind, int mode)) {
3497 struct stat st;
3498 char *buf, *ptr;
3499 int i;
3500
3501 fstat(fileno(file), &st); /* Some error analysis may be fine here.. */
3502 if ( (buf = alloca(st.st_size + 1)) == 0) { /* + a final \0 */
3503 puts("svgalib: out of mem while parsing config file !");
3504 return;
3505 }
3506 fread(buf, 1, st.st_size, file);
3507 for (i = 0, ptr = buf; i < st.st_size; i++, ptr++) {
3508 if (!*ptr)
3509 *ptr = ' '; /* Erase any maybe embedded \0 */
3510 }
3511 *ptr = 0; /* Trailing \0 */
3512 parse_string(buf, commands, func, mode); /* parse config file */
3513 }
3514
3515 /* This is a service function for drivers. Commands and func are as above.
3516 The following config files are parsed in this order:
3517 - /etc/vga/libvga.conf (#define SVGALIB_CONFIG_FILE)
3518 - ~/.svgalibrc
3519 - the file where env variavle SVGALIB_CONFIG_FILE points
3520 - the env variable SVGALIB_CONFIG (for compatibility, but I would remove
3521 it, we should be more flexible... Opinions ?)
3522 - MW: I'd rather keep it, doesn't do too much harm and is sometimes nice
3523 to have.
3524 */
3525 void __svgalib_read_options(char **commands, char *(*func) (int ind, int mode)) {
3526 FILE *file;
3527 char *buf = NULL, *ptr;
3528 int i;
3529
3530 if ( (file = fopen(SVGALIB_CONFIG_FILE, "r")) != 0) {
3531 #ifdef DEBUG_CONF
3532 printf("Processing config file \'%s\'\n", SVGALIB_CONFIG_FILE);
3533 #endif
3534 process_config_file(file, 1, commands, func);
3535 fclose(file);
3536 } else {
3537 fprintf(stderr, "svgalib: Configuration file \'%s\' not found.\n", SVGALIB_CONFIG_FILE);
3538 }
3539
3540 if ( (ptr = getenv("HOME")) != 0) {
3541 char *filename;
3542
3543 filename = alloca(strlen(ptr) + 20);
3544 if (!filename) {
3545 puts("svgalib: out of mem while parsing SVGALIB_CONFIG_FILE !");
3546 } else {
3547 strcpy(filename, ptr);
3548 strcat(filename, "/.svgalibrc");
3549 if ( (file = fopen(filename, "r")) != 0) {
3550 #ifdef DEBUG_CONF
3551 printf("Processing config file \'%s\'\n", filename);
3552 #endif
3553 process_config_file(file, allowoverride, commands, func);
3554 fclose(file);
3555 }
3556 }
3557 }
3558
3559 if ( (ptr = getenv("SVGALIB_CONFIG_FILE")) != 0) {
3560 if ( (file = fopen(ptr, "r")) != 0) {
3561 #ifdef DEBUG_CONF
3562 printf("Processing config file \'%s\'\n", ptr);
3563 #endif
3564 process_config_file(file, allowoverride, commands, func);
3565 fclose(file);
3566 } else {
3567 fprintf(stderr, "svgalib: warning: config file \'%s\', pointed to by SVGALIB_CONFIG_FILE, not found !\n", ptr);
3568 }
3569 }
3570
3571 if ( (ptr = getenv("SVGALIB_CONFIG")) != 0 && (i = strlen(ptr)) != 0) {
3572 buf = alloca(i + 1);
3573 if (!buf) {
3574 puts("svgalib: out of mem while parsing SVGALIB_CONFIG !");
3575 } else {
3576 strcpy(buf, ptr); /* Copy for safety and strtok!! */
3577 #ifdef DEBUG_CONF
3578 puts("Parsing env variable \'SVGALIB_CONFIG\'");
3579 #endif
3580 parse_string(buf, commands, func, allowoverride);
3581 }
3582 }
3583 }
3584
3585 /* Configuration file, mouse interface, initialization. */
3586
3587 static int configfileread = 0; /* Boolean. */
3588
3589 /* What are these m0 m1 m... things ? Shouldn't they be removed ? */
3590 static char *vga_conf_commands[] = {
3591 "mouse", "monitor", "!m", "!M", "chipset", "overrideenable", "!m0", "!m1", "!m2", "!m3",
3592 "!m4", "!m9", "!M0", "!M1", "!M2", "!M3", "!M4", "!M5", "!M6", "nolinear",
3593 "linear", "!C0", "!C1", "!C2", "!C3", "!C4", "!C5", "!C6", "!C7", "!C8", "!C9",
3594 "!c0", "!c1", "monotext", "colortext", "!m5",
3595 "leavedtr", "cleardtr", "setdtr", "leaverts", "clearrts",
3596 "setrts", "grayscale", "horizsync", "vertrefresh", "modeline",
3597 "security","mdev", "default_mode", "nosigint", "sigint",
3598 "joystick0", "joystick1", "joystick2", "joystick3",
3599 "textprog", "vesatext", "vesasave", "secondary", "bandwidth",
3600 "novccontrol", "newmode", "noprocpci", "vesatextmode", "pcistart",
3601 "ragedoubleclock", "vesacputype",
3602 NULL};
3603
3604 static char *conf_mousenames[] =
3605 {
3606 "Microsoft", "MouseSystems", "MMSeries", "Logitech", "Busmouse", "PS2",
3607 "MouseMan", "gpm", "Spaceball", "none", "IntelliMouse", "IMPS2", "pnp",
3608 "WacomGraphire", "DRMOUSE4DS", NULL};
3609
3610 static int check_digit(char *ptr, char *digits)
3611 {
3612 if (ptr == NULL)
3613 return 0;
3614 return strlen(ptr) == strspn(ptr, digits);
3615 }
3616
3617 static char *process_option(int command, int mode)
3618 {
3619 static char digits[] = ".0123456789";
3620 char *ptr, **tabptr, *ptb;
3621 int i, j;
3622 float f;
3623
3624 #ifdef DEBUG_CONF
3625 printf("command %d detected.\n", command);
3626 #endif
3627 switch (command) {
3628 case 5:
3629 #ifdef DEBUG_CONF
3630 puts("Allow override");
3631 #endif
3632 if (mode)
3633 allowoverride = 1;
3634 else
3635 puts("Overrideenable denied. (Gee.. Do you think I'm that silly?)");
3636 break;
3637 case 0: /* mouse */
3638 case 2: /* m */
3639 ptr = strtok(NULL, " ");
3640 if (ptr == NULL)
3641 goto inv_mouse;
3642 if (check_digit(ptr, digits + 1)) { /* It is a number.. */
3643 i = atoi(ptr);
3644 if ((i < 0) || (i > 9))
3645 goto inv_mouse;
3646 mouse_type = i;
3647 } else { /* parse for symbolic name.. */
3648 for (i = 0, tabptr = conf_mousenames; *tabptr; tabptr++, i++) {
3649 if (!strcasecmp(ptr, *tabptr)) {
3650 mouse_type = i;
3651 #ifdef DEBUG_DRMOUSE4DS
3652 fprintf(stderr, "mouse type: %d: %s \n", i, conf_mousenames[i]);
3653 #endif
3654 goto leave;
3655 }
3656 }
3657 inv_mouse:
3658 printf("svgalib: Illegal mouse setting: {mouse|m} %s\n"
3659 "Correct usage: {mouse|m} mousetype\n"
3660 "where mousetype is one of 0, 1, 2, 3, 4, 5, 6, 7, 9,\n",
3661 (ptr != NULL) ? ptr : "");
3662 for (tabptr = conf_mousenames, i = 0; *tabptr; tabptr++, i++) {
3663 if (i == MOUSE_NONE)
3664 continue;
3665 printf("%s, ", *tabptr);
3666 }
3667 puts("or none.");
3668 return ptr; /* Allow a second parse of str */
3669 }
3670 break;
3671 case 1: /* monitor */
3672 case 3: /* M */
3673 ptr = strtok(NULL, " ");
3674 if (check_digit(ptr, digits + 1)) { /* It is an int.. */
3675 i = atoi(ptr);
3676 if (i < 7) {
3677 command = i + 12;
3678 goto monnum;
3679 } else {
3680 f = i;
3681 goto monkhz;
3682 }
3683 } else if (check_digit(ptr, digits)) { /* It is a float.. */
3684 f = atof(ptr);
3685 monkhz:
3686 if (!mode)
3687 goto mon_deny;
3688 __svgalib_horizsync.max = f * 1000.0f;
3689 } else {
3690 printf("svgalib: Illegal monitor setting: {monitor|M} %s\n"
3691 "Correct usage: {monitor|M} monitortype\n"
3692 "where monitortype is one of 0, 1, 2, 3, 4, 5, 6, or\n"
3693 "maximal horz. scan frequency in khz.\n"
3694 "Example: monitor 36.5\n",
3695 (ptr != NULL) ? ptr : "");
3696 return ptr; /* Allow a second parse of str */
3697 }
3698 break;
3699 case 4: /* chipset */
3700 ptr = strtok(NULL, " ");
3701 if (ptr == NULL) {
3702 puts("svgalib: Illegal chipset setting: no chipset given");
3703 goto chip_us;
3704 }
3705 /*First param is chipset */
3706 for (i = 0, tabptr = driver_names; *tabptr; tabptr++, i++) {
3707 if (!strcasecmp(ptr, *tabptr)) {
3708 if (!__svgalib_driverspecslist[i]) {
3709 printf("svgalib: Illegal chipset setting: Driver for %s is NOT compiled in.\n",
3710 ptr);
3711 continue; /* The for above will loop a few more times and fail */
3712 }
3713 ptr = strtok(NULL, " ");
3714 if (check_digit(ptr, digits + 1)) {
3715 j = atoi(ptr);
3716 ptr = strtok(NULL, " ");
3717 if (check_digit(ptr, digits + 1)) {
3718 if (mode)
3719 vga_setchipsetandfeatures(i, j, atoi(ptr));
3720 else {
3721 chipdeny:
3722 puts("chipset override from environment denied.");
3723 }
3724 return strtok(NULL, " ");
3725 } else {
3726 puts("svgalib: Illegal chipset setting: memory is not a number");
3727 goto chip_us;
3728 }
3729 }
3730 if (mode)
3731 vga_setchipset(i);
3732 else
3733 puts("chipset override from environment denied.");
3734 return ptr;
3735 }
3736 }
3737 printf("svgalib: Illegal chipset setting: chipset %s\n", ptr);
3738 chip_us:
3739 puts("Correct usage: chipset driver [par1 par2]\n"
3740 "where driver is one of:");
3741 ptb = "%s";
3742 for (i = 0, tabptr = driver_names; *tabptr; tabptr++, i++) {
3743 if (__svgalib_driverspecslist[i] != NULL) {
3744 printf(ptb, *tabptr);
3745 ptb = ", %s";
3746 }
3747 }
3748 puts("\npar1 and par2 are river dependant integers.\n"
3749 "Example: Chipset VGA or\n"
3750 "Chipset VGA 0 512");
3751 return ptr;
3752 case 6: /* oldstyle config: m0-m4 */
3753 case 7:
3754 case 8:
3755 case 9:
3756 case 10:
3757 mouse_type = command - 6;
3758 break;
3759 case 11: /* m9 */
3760 mouse_type = MOUSE_NONE;
3761 break;
3762 case 12: /* oldstyle config: M0-M6 */
3763 case 13:
3764 case 14:
3765 case 15:
3766 case 16:
3767 case 17:
3768 case 18:
3769 monnum:
3770 if (!mode) {
3771 mon_deny:
3772 puts("Monitor setting from environment denied.");
3773 break;
3774 } else {
3775 __svgalib_horizsync.max = __svgalib_maxhsync[command - 12];
3776 }
3777 break;
3778 case 19: /*nolinear */
3779 modeinfo_mask &= ~CAPABLE_LINEAR;
3780 break;
3781 case 20: /*linear */
3782 modeinfo_mask |= CAPABLE_LINEAR;
3783 break;
3784 case 21: /* oldstyle chipset C0 - C9 */
3785 case 22:
3786 case 23:
3787 case 24:
3788 case 25:
3789 case 26:
3790 case 27:
3791 case 28:
3792 case 29:
3793 case 30:
3794 if (!mode)
3795 goto chipdeny;
3796 vga_setchipset(command - 21);
3797 break;
3798 case 31: /* c0-c1 color-text selection */
3799 if (!mode) {
3800 coltexdeny:
3801 puts("Color/mono text selection from environment denied.");
3802 break;
3803 }
3804 color_text = 0;
3805 break;
3806 case 32:
3807 if (!mode) {
3808 puts("Color/mono text selection from environment denied.");
3809 break;
3810 }
3811 color_text = 1;
3812 break;
3813 case 33:
3814 case 34:
3815 if (!mode)
3816 goto coltexdeny;
3817 color_text = command - 32;
3818 break;
3819 case 35: /* Mouse type 5 - "PS2". */
3820 mouse_type = 5;
3821 break;
3822 case 36:
3823 mouse_modem_ctl &= ~(MOUSE_CHG_DTR | MOUSE_DTR_HIGH);
3824 break;
3825 case 37:
3826 mouse_modem_ctl &= ~MOUSE_DTR_HIGH;
3827 mouse_modem_ctl |= MOUSE_CHG_DTR;
3828 break;
3829 case 38:
3830 mouse_modem_ctl |= (MOUSE_CHG_RTS | MOUSE_RTS_HIGH);
3831 break;
3832 case 39:
3833 mouse_modem_ctl &= ~(MOUSE_CHG_RTS | MOUSE_RTS_HIGH);
3834 break;
3835 case 40:
3836 mouse_modem_ctl &= ~MOUSE_RTS_HIGH;
3837 mouse_modem_ctl |= MOUSE_CHG_RTS;
3838 break;
3839 case 41:
3840 mouse_modem_ctl |= (MOUSE_CHG_RTS | MOUSE_RTS_HIGH);
3841 break;
3842 case 42: /* grayscale */
3843 __svgalib_grayscale = 1;
3844 break;
3845 case 43: /* horizsync */
3846 ptr = strtok(NULL, " ");
3847 if (check_digit(ptr, digits)) { /* It is a float.. */
3848 f = atof(ptr);
3849 if (!mode)
3850 goto mon_deny;
3851 __svgalib_horizsync.min = f * 1000;
3852 } else
3853 goto hs_bad;
3854
3855 ptr = strtok(NULL, " ");
3856 if (check_digit(ptr, digits)) { /* It is a float.. */
3857 f = atof(ptr);
3858 if (!mode)
3859 goto mon_deny;
3860 __svgalib_horizsync.max = f * 1000;
3861 } else {
3862 hs_bad:
3863 printf("svgalib: Illegal HorizSync setting.\n"
3864 "Correct usage: HorizSync min_kHz max_kHz\n"
3865 "Example: HorizSync 31.5 36.5\n");
3866 }
3867 break;
3868 case 44: /* vertrefresh */
3869 ptr = strtok(NULL, " ");
3870 if (check_digit(ptr, digits)) { /* It is a float.. */
3871 f = atof(ptr);
3872 if (!mode)
3873 goto mon_deny;
3874 __svgalib_vertrefresh.min = f;
3875 } else
3876 goto vr_bad;
3877
3878 ptr = strtok(NULL, " ");
3879 if (check_digit(ptr, digits)) { /* It is a float.. */
3880 f = atof(ptr);
3881 if (!mode)
3882 goto mon_deny;
3883 __svgalib_vertrefresh.max = f;
3884 } else {
3885 vr_bad:
3886 printf("svgalib: Illegal VertRefresh setting.\n"
3887 "Correct usage: VertRefresh min_Hz max_Hz\n"
3888 "Example: VertRefresh 50 70\n");
3889 }
3890 break;
3891 case 45:{ /* modeline */
3892 MonitorModeTiming mmt;
3893 const struct {
3894 char *name;
3895 int val;
3896 } options[] = {
3897 {
3898 "-hsync", NHSYNC
3899 },
3900 {
3901 "+hsync", PHSYNC
3902 },
3903 {
3904 "-vsync", NVSYNC
3905 },
3906 {
3907 "+vsync", PVSYNC
3908 },
3909 {
3910 "interlace", INTERLACED
3911 },
3912 {
3913 "interlaced", INTERLACED
3914 },
3915 {
3916 "doublescan", DOUBLESCAN
3917 }
3918 };
3919 #define ML_NR_OPTS (sizeof(options)/sizeof(*options))
3920
3921 /* Skip the name of the mode */
3922 ptr = strtok(NULL, " ");
3923 if (!ptr)
3924 break;
3925
3926 ptr = strtok(NULL, " ");
3927 if (!ptr)
3928 break;
3929 mmt.pixelClock = atof(ptr) * 1000;
3930
3931 #define ML_GETINT(x) \
3932 ptr = strtok(NULL, " "); if(!ptr) break; \
3933 mmt.x = atoi(ptr);
3934
3935 ML_GETINT(HDisplay);
3936 ML_GETINT(HSyncStart);
3937 ML_GETINT(HSyncEnd);
3938 ML_GETINT(HTotal);
3939 ML_GETINT(VDisplay);
3940 ML_GETINT(VSyncStart);
3941 ML_GETINT(VSyncEnd);
3942 ML_GETINT(VTotal);
3943 mmt.flags = 0;
3944 while ((ptr = strtok(NULL, " "))) {
3945 for (i = 0; i < ML_NR_OPTS; i++)
3946 if (!strcasecmp(ptr, options[i].name))
3947 {
3948 mmt.flags |= options[i].val;
3949 break;
3950 }
3951 if (i == ML_NR_OPTS)
3952 break;
3953 }
3954 #undef ML_GETINT
3955 #undef ML_NR_OPTS
3956
3957 __svgalib_addusertiming(&mmt);
3958 return ptr;
3959
3960 }
3961 case 46:
3962 if (!mode) {
3963 puts("Security setting from environment denied.");
3964 break;
3965 }
3966 if ( (ptr = strtok( NULL, " ")) ) {
3967 if (!strcasecmp("revoke-all-privs", ptr)) {
3968 __svgalib_security_revokeallprivs = 1;
3969 break;
3970 } else if (!strcasecmp("compat", ptr)) {
3971 __svgalib_security_revokeallprivs = 0;
3972 break;
3973 }
3974 }
3975 puts("svgalib: Unknown security options\n");
3976 break;
3977 case 47:
3978 ptr = strtok(NULL," ");
3979 if (ptr) {
3980 mouse_device = strdup(ptr);
3981 if (mouse_device == NULL) {
3982 nomem:
3983 puts("svgalib: Fatal error: out of memory.");
3984 exit(1);
3985 }
3986 } else
3987 goto param_needed;
3988 break;
3989 case 48: /* default_mode */
3990 if ( (ptr = strtok(NULL, " ")) != 0) {
3991 int mode = vga_getmodenumber(ptr);
3992 if (mode != -1) {
3993 __svgalib_default_mode = mode;
3994 } else {
3995 printf("svgalib: config: illegal mode \'%s\' for \'%s\'\n",
3996 ptr, vga_conf_commands[command]);
3997 }
3998 } else {
3999 param_needed:
4000 printf("svgalib: config: \'%s\' requires parameter(s)",
4001 vga_conf_commands[command]);
4002 break;
4003 }
4004 break;
4005 case 49: /* nosigint */
4006 __svgalib_nosigint = 1;
4007 break;
4008 case 50: /* sigint */
4009 __svgalib_nosigint = 0;
4010 break;
4011 case 51: /* joystick0 */
4012 case 52: /* joystick1 */
4013 case 53: /* joystick2 */
4014 case 54: /* joystick3 */
4015 if (! (ptr = strtok(NULL, " ")) )
4016 goto param_needed;
4017 #ifndef SVGA_AOUT
4018 if (__joystick_devicenames[command - 51])
4019 free(__joystick_devicenames[command - 51]);
4020 __joystick_devicenames[command - 51] = strdup(ptr);
4021 if (!__joystick_devicenames[command - 51])
4022 goto nomem;
4023 #else
4024 printf("svgalib: No joystick support in a.out version.\n");
4025 #endif
4026 break;
4027 case 55: /* TextProg */
4028 ptr = strtok(NULL," ");
4029 if(ptr==NULL)break;
4030 __svgalib_textprog|=2;
4031 __svgalib_TextProg = strdup(ptr);
4032 if (!__svgalib_TextProg)
4033 goto nomem;
4034 i=1;
4035 while(((ptr=strtok(NULL," "))!=NULL) &&
4036 (i< ((sizeof(__svgalib_TextProg_argv) / sizeof(char *)) + 1)) &&
4037 strcmp(ptr,"END")){
4038 __svgalib_TextProg_argv[i]=strdup(ptr);
4039 if (!__svgalib_TextProg_argv[i])
4040 goto nomem;
4041 i++;
4042 };
4043 __svgalib_TextProg_argv[i]=NULL;
4044 ptb=strrchr(__svgalib_TextProg,'/');
4045 __svgalib_TextProg_argv[0]=ptb?ptb + 1:__svgalib_TextProg;
4046 break;
4047 case 56:
4048 #ifdef INCLUDE_VESA_DRIVER
4049 __svgalib_vesatext=1;
4050 break;
4051 #else
4052 printf("svgalib: Warning: VESA support not enabled!\n");
4053 #endif
4054 case 57: /* Vesa save bitmap */
4055 #ifdef INCLUDE_VESA_DRIVER
4056 ptr = strtok(NULL, " ");
4057 if(ptr!=NULL){
4058 j = atoi(ptr);
4059 __svgalib_VESA_savebitmap=j;
4060 };
4061 #else
4062 printf("svgalib: Warning: VESA support not enabled!\n");
4063 #endif
4064 break;
4065 case 58:
4066 __svgalib_secondary=1;
4067 break;
4068 case 59: /* max bandwidth */
4069 if ( (ptr = strtok(NULL, " ")) != 0) {
4070 if (check_digit(ptr, digits)) {
4071 int f = atoi(ptr);
4072 if (f<31000)f=31000;
4073 __svgalib_bandwidth = f;
4074 }
4075 } else {
4076 printf("svgalib: config: \'%s\' requires parameter(s)",
4077 vga_conf_commands[command]);
4078 break;
4079 }
4080 break;
4081 case 60:
4082 __svgalib_novccontrol=1;
4083 break;
4084 case 61: {
4085 int x,y,c,p,b;
4086
4087 ptr = strtok(NULL, " ");
4088 if(!ptr) break;
4089 x = atoi(ptr);
4090 ptr = strtok(NULL, " ");
4091 if(!ptr) break;
4092 y = atoi(ptr);
4093 ptr = strtok(NULL, " ");
4094 if(!ptr) break;
4095 c = atoi(ptr);
4096 ptr = strtok(NULL, " ");
4097 if(!ptr) break;
4098 p = atoi(ptr);
4099 ptr = strtok(NULL, " ");
4100 if(!ptr) break;
4101 b = atoi(ptr);
4102
4103 vga_addmode(x,y,c,p,b);
4104 };
4105 break;
4106 case 62:
4107 __svgalib_use_procpci=0;
4108 break;
4109 case 63: /* Vesa text mode number */
4110 #ifdef INCLUDE_VESA_DRIVER
4111 ptr = strtok(NULL, " ");
4112 if(ptr!=NULL){
4113 j = atoi(ptr);
4114 __svgalib_VESA_textmode=j;
4115 };
4116 #else
4117 printf("svgalib: Warning: VESA support not enabled!\n");
4118 #endif
4119 break;
4120 case 64: /* pci initial values */
4121 ptr = strtok(NULL, " ");
4122 if (check_digit(ptr, digits)) {
4123 j = atoi(ptr);
4124 if((j<16)&&(j>=0))__svgalib_pci_ibus = j;
4125 } else
4126 goto ps_bad;
4127
4128 ptr = strtok(NULL, " ");
4129 if (check_digit(ptr, digits)) {
4130 j = atoi(ptr);
4131 if((j<256)&&(j>=0))__svgalib_pci_idev = j;
4132 } else {
4133 ps_bad:
4134 printf("svgalib: Illegal PCI initial values setting.\n"
4135 "Correct usage: PCIStart initial_bus initial_dev"
4136 "Example: PCIStart 1 0\n");
4137 }
4138 break;
4139 case 65:
4140 __svgalib_ragedoubleclock=1;
4141 break;
4142 case 66: /* cpu type */
4143 ptr = strtok(NULL, " ");
4144 #ifdef INCLUDE_VESA_DRIVER
4145 if(ptr!=NULL){
4146 j = atoi(ptr);
4147 __svgalib_lrmi_cpu_type=j;
4148 };
4149 #endif
4150 break;
4151 }
4152 leave:
4153 return strtok(NULL, " ");
4154 }
4155
4156 static void readconfigfile(void)
4157 {
4158 if (configfileread)
4159 return;
4160 configfileread = 1;
4161 mouse_type = -1;
4162
4163 {
4164 struct stat buf;
4165
4166 if(!stat("/proc/bus/pci",&buf))__svgalib_use_procpci=1;
4167 else __svgalib_use_procpci=0;
4168 }
4169
4170 __svgalib_read_options(vga_conf_commands, process_option);
4171 if (mouse_type == -1) {
4172 mouse_type = MOUSE_MICROSOFT; /* Default. */
4173 puts("svgalib: Assuming Microsoft mouse.");
4174 }
4175 if (__svgalib_horizsync.max == 0U) {
4176 /* Default monitor is low end SVGA/8514. */
4177 __svgalib_horizsync.min = 31500U;
4178 __svgalib_horizsync.max = 35500U;
4179 puts("svgalib: Assuming low end SVGA/8514 monitor (35.5 KHz).");
4180 }
4181 #ifdef DEBUG_CONF
4182 printf("Mouse is: %d Monitor is: H(%5.1f, %5.1f) V(%u,%u)\n", mouse_type,
4183 __svgalib_horizsync.min / 1000.0, __svgalib_horizsync.max / 1000.0,
4184 __svgalib_vertrefresh.min, __svgalib_vertrefresh.max);
4185 printf("Mouse device is: %s",mouse_device);
4186 #endif
4187 }
4188
4189 int vga_getmousetype(void)
4190 {
4191 readconfigfile();
4192 return mouse_type | mouse_modem_ctl;
4193 }
4194
4195 int vga_getmonitortype(void)
4196 { /* obsolete */
4197 int i;
4198 readconfigfile();
4199 for (i = 1; i <= MON1024_72; i++)
4200 if (__svgalib_horizsync.max < __svgalib_maxhsync[i])
4201 return i - 1;
4202
4203 return MON1024_72;
4204 }
4205
4206 void vga_setmousesupport(int s)
4207 {
4208 mouse_support = s;
4209 }
4210
4211 #ifndef BACKGROUND
4212
4213 void vga_lockvc(void)
4214 {
4215 lock_count++;
4216 if (flip)
4217 __svgalib_waitvtactive();
4218 }
4219
4220 void vga_unlockvc(void)
4221 {
4222 if (--lock_count <= 0) {
4223 lock_count = 0;
4224 if (release_flag) {
4225 release_flag = 0;
4226 __svgalib_releasevt_signal(SVGALIB_RELEASE_SIG);
4227 }
4228 }
4229 }
4230
4231 void vga_runinbackground(int stat, ...)
4232 {
4233 va_list params;
4234
4235 va_start(params,stat);
4236
4237 switch (stat) {
4238 case VGA_GOTOBACK:
4239 __svgalib_go_to_background = va_arg(params, void *);
4240 break;
4241 case VGA_COMEFROMBACK:
4242 __svgalib_come_from_background = va_arg(params, void *);
4243 break;
4244 default:
4245 __svgalib_runinbackground = stat;
4246 break;
4247 };
4248 }
4249
4250 #endif
4251
4252 int vga_runinbackground_version(void)
4253
4254 /* Program can check, if it is safe to in background. */
4255
4256 {
4257 int version=0;
4258
4259 #ifdef BACKGROUND
4260 #if BACKGROUND == 1
4261 version=1;
4262 #endif
4263 #if BACKGROUND == 2
4264 version=2;
4265 #endif
4266 #endif
4267 return(version);
4268 }
4269
4270 #ifdef BACKGROUND
4271
4272 unsigned char *__svgalib_give_graph_red(void)
4273
4274 {
4275 return(graph_red);
4276 }
4277
4278 unsigned char *__svgalib_give_graph_green(void)
4279
4280 {
4281 return(graph_green);
4282 }
4283
4284 unsigned char *__svgalib_give_graph_blue(void)
4285
4286 {
4287 return(graph_blue);
4288 }
4289
4290 #endif
4291
4292 int vga_oktowrite(void)
4293 {
4294 if(__svgalib_secondary)return 1;
4295 return __svgalib_oktowrite;
4296 }
4297
4298 void vga_chipset_setregs(unsigned char regs[])
4299 {
4300 chipset_setregs(regs, TEXT); /* Why TEXT? Can't think of smthg else*/
4301 }
4302
4303 void vga_chipset_saveregs(unsigned char regs[])
4304 {
4305 chipset_saveregs(regs);
4306 }
4307
4308 int vga_simple_init(void)
4309 {
4310 __svgalib_simple = 1;
4311 __svgalib_novccontrol = 1;
4312 __svgalib_driver_report = 0;
4313 readconfigfile();
4314 vga_hasmode(TEXT);
4315 if(__svgalib_mmio_size)
4316 MMIO_POINTER=mmap((caddr_t) 0,
4317 __svgalib_mmio_size,
4318 PROT_READ | PROT_WRITE,
4319 MAP_SHARED,
4320 __svgalib_mem_fd,
4321 (off_t) __svgalib_mmio_base
4322 ); else MMIO_POINTER=NULL;
4323 close(__svgalib_mem_fd);
4324 return 0;
4325 }
4326
4327 int vga_initf(int flags) {
4328 if(flags&1)
4329 __svgalib_novccontrol=2;
4330 if(flags&2)
4331 __svgalib_secondary=2;
4332 return vga_init();
4333 }
4334
4335
4336 int vga_init(void)
4337 {
4338 int retval = 0;
4339
4340 #if 0
4341 __svgalib_open_devconsole();
4342 if (__svgalib_tty_fd < 0) {
4343 /* Return with error code. */
4344 /* Since the configuration file hasnt been read yet, security will
4345 only be set to 1 if it has been compiled into the program */
4346 retval = -1;
4347 } else {
4348 readconfigfile();
4349 vga_hasmode(TEXT); /* Force driver message and initialization. */
4350 }
4351 #else
4352 readconfigfile();
4353 vga_hasmode(TEXT);
4354 if(__svgalib_driver_report) {
4355 printf("svgalib %s\n", versionstr);
4356 }
4357 if(!__svgalib_novccontrol)__svgalib_open_devconsole();
4358 #endif
4359
4360 if(B8000_MEM_POINTER==NULL){
4361 if(__svgalib_banked_mem_base==0)__svgalib_banked_mem_base=0xa0000;
4362 if(__svgalib_banked_mem_size==0)__svgalib_banked_mem_size=0x10000;
4363 BANKED_MEM_POINTER=mmap((caddr_t) 0,
4364 __svgalib_banked_mem_size,
4365 PROT_READ | PROT_WRITE,
4366 MAP_SHARED,
4367 __svgalib_mem_fd,
4368 __svgalib_banked_mem_base
4369
4370 );
4371 if(__svgalib_linear_mem_size) {
4372 LINEAR_MEM_POINTER=mmap((caddr_t) 0,
4373 __svgalib_linear_mem_size,
4374 PROT_READ | PROT_WRITE,
4375 MAP_SHARED,
4376 __svgalib_mem_fd,
4377 (off_t) __svgalib_linear_mem_base
4378 );
4379 };/* else LINEAR_MEM_POINTER=NULL;*/
4380
4381 if(__svgalib_mmio_size)
4382 MMIO_POINTER=mmap((caddr_t) 0,
4383 __svgalib_mmio_size,
4384 PROT_READ | PROT_WRITE,
4385 MAP_SHARED,
4386 __svgalib_mem_fd,
4387 (off_t) __svgalib_mmio_base
4388 ); else MMIO_POINTER=NULL;
4389
4390 B8000_MEM_POINTER=mmap((caddr_t) 0,
4391 32768,
4392 PROT_READ | PROT_WRITE,
4393 MAP_SHARED,
4394 __svgalib_mem_fd,
4395 (off_t) 0xb8000);
4396 };
4397
4398 close(__svgalib_mem_fd);
4399
4400 #ifdef DEBUG
4401 printf("svgalib: Opening mouse (type = %x).\n", mouse_type | mouse_modem_ctl);
4402 #endif
4403 if (mouse_init(mouse_device, mouse_type | mouse_modem_ctl, MOUSE_DEFAULTSAMPLERATE))
4404 printf("svgalib: Failed to initialize mouse.\n");
4405 else
4406 mouse_open = 1;
4407
4408 /* Michael: I assume this is a misunderstanding, when svgalib was developed,
4409 there were no saved uids, thus setting effective uid sufficed... */
4410 if ( __svgalib_security_revokeallprivs == 1 ) {
4411 setuid(getuid());
4412 setgid(getgid());
4413 }
4414 seteuid(getuid());
4415 setegid(getgid());
4416 return retval;
4417 }
4418
4419 int vga_addtiming( int pixelClock,
4420 int HDisplay,
4421 int HSyncStart,
4422 int HSyncEnd,
4423 int HTotal,
4424 int VDisplay,
4425 int VSyncStart,
4426 int VSyncEnd,
4427 int VTotal,
4428 int flags) {
4429
4430 MonitorModeTiming mmt;
4431
4432 mmt.pixelClock=pixelClock;
4433 mmt.HDisplay=HDisplay;
4434 mmt.HSyncStart=HSyncStart;
4435 mmt.HSyncEnd=HSyncEnd;
4436 mmt.HTotal=HTotal;
4437 mmt.VDisplay=VDisplay;
4438 mmt.VSyncStart=VSyncStart;
4439 mmt.VSyncEnd=VSyncEnd;
4440 mmt.VTotal=VTotal;
4441 mmt.flags=flags;
4442
4443 __svgalib_addusertiming(&mmt);
4444
4445 return 1;
4446
4447 };
4448
4449 int vga_addmode(int xdim, int ydim, int cols,
4450 int xbytes, int bytespp)
4451 {
4452 int i;
4453
4454 i=__svgalib_addmode(xdim, ydim, cols, xbytes, bytespp);
4455
4456 return i;
4457 };
4458
4459
4460 #ifdef __alpha__
4461
4462 #define vuip volatile unsigned int *
4463
4464 extern void sethae(unsigned long hae);
4465
4466 static struct hae hae;
4467
4468 int iopl(int level)
4469 {
4470 return 0;
4471 }
4472
4473 unsigned long vga_readb(unsigned long base, unsigned long off)
4474 {
4475 unsigned long result, shift;
4476 #if !defined(CONFIG_ALPHA_JENSEN)
4477 unsigned long msb;
4478 #endif
4479
4480 shift = (off & 0x3) * 8;
4481 #if !defined(CONFIG_ALPHA_JENSEN)
4482 if (off >= (1UL << 24)) {
4483 msb = off & 0xf8000000;
4484 off -= msb;
4485 if (msb && msb != hae.cache) {
4486 sethae(msb);
4487 }
4488 }
4489 #endif
4490 result = *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_BYTE);
4491 result >>= shift;
4492 return 0xffUL & result;
4493 }
4494
4495 unsigned long vga_readw(unsigned long base, unsigned long off)
4496 {
4497 unsigned long result, shift;
4498 #if !defined(CONFIG_ALPHA_JENSEN)
4499 unsigned long msb;
4500 #endif
4501
4502 shift = (off & 0x3) * 8;
4503 #if !defined(CONFIG_ALPHA_JENSEN)
4504 if (off >= (1UL << 24)) {
4505 msb = off & 0xf8000000;
4506 off -= msb;
4507 if (msb && msb != hae.cache) {
4508 sethae(msb);
4509 }
4510 }
4511 #endif
4512 result = *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_WORD);
4513 result >>= shift;
4514 return 0xffffUL & result;
4515 }
4516
4517 #if defined(CONFIG_ALPHA_JENSEN)
4518 unsigned long vga_readl(unsigned long base, unsigned long off)
4519 {
4520 unsigned long result;
4521 result = *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_LONG);
4522 return 0xffffffffUL & result;
4523 }
4524 #endif
4525
4526 void vga_writeb(unsigned char b, unsigned long base, unsigned long off)
4527 {
4528 #if !defined(CONFIG_ALPHA_JENSEN)
4529 unsigned long msb;
4530 unsigned int w;
4531
4532 if (off >= (1UL << 24)) {
4533 msb = off & 0xf8000000;
4534 off -= msb;
4535 if (msb && msb != hae.cache) {
4536 sethae(msb);
4537 }
4538 }
4539 asm("insbl %2,%1,%0": "r="(w):"ri"(off & 0x3), "r"(b));
4540 *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_BYTE) = w;
4541 #else
4542 *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_BYTE) = b * 0x01010101;
4543 #endif
4544 }
4545
4546 void vga_writew(unsigned short b, unsigned long base, unsigned long off)
4547 {
4548 #if !defined(CONFIG_ALPHA_JENSEN)
4549 unsigned long msb;
4550 unsigned int w;
4551
4552 if (off >= (1UL << 24)) {
4553 msb = off & 0xf8000000;
4554 off -= msb;
4555 if (msb && msb != hae.cache) {
4556 sethae(msb);
4557 }
4558 }
4559 asm("inswl %2,%1,%0": "r="(w):"ri"(off & 0x3), "r"(b));
4560 *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_WORD) = w;
4561 #else
4562 *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_WORD) = b * 0x00010001;
4563 #endif
4564 }
4565
4566 #if defined(CONFIG_ALPHA_JENSEN)
4567 void vga_writel(unsigned long b, unsigned long base, unsigned long off)
4568 {
4569 *(vuip) ((off << MEM_SHIFT) + base + MEM_TYPE_LONG) = b;
4570 }
4571
4572 #endif
4573
4574 #endif
4575