summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2008-11-05 11:39:46 -0500
committerAdam Jackson <ajax@redhat.com>2008-11-05 11:39:46 -0500
commit6d21fbf00648307208146aca0837ec63ea490659 (patch)
tree2da42c3df69b98c47ab2a684076c83df307597b2
parent9a874a71a791c6110fd57b8a5c083f777a446d0f (diff)
kdrive: Bye bye Xvesa
-rw-r--r--configure.ac2
-rw-r--r--hw/kdrive/Makefile.am7
-rw-r--r--hw/kdrive/vesa/Makefile.am33
-rw-r--r--hw/kdrive/vesa/Xvesa.man105
-rw-r--r--hw/kdrive/vesa/vbe.c706
-rw-r--r--hw/kdrive/vesa/vbe.h165
-rw-r--r--hw/kdrive/vesa/vesa.c1819
-rw-r--r--hw/kdrive/vesa/vesa.h295
-rw-r--r--hw/kdrive/vesa/vesainit.c92
-rw-r--r--hw/kdrive/vesa/vga.c242
-rw-r--r--hw/kdrive/vesa/vga.h59
-rw-r--r--hw/kdrive/vesa/vm86.c764
-rw-r--r--hw/kdrive/vesa/vm86.h173
13 files changed, 1 insertions, 4461 deletions
diff --git a/configure.ac b/configure.ac
index e75e6d3ee..90cacd761 100644
--- a/configure.ac
+++ b/configure.ac
@@ -554,7 +554,6 @@ AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdriv
554AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto]) 554AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto])
555AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto]) 555AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto])
556AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto]) 556AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
557AC_ARG_ENABLE(kdrive-vesa, AS_HELP_STRING([--enable-kdrive-vesa], [Build the kdrive VESA-based servers (default: auto)]), [KDRIVEVESA=$enableval], [KDRIVEVESA=auto])
558 557
559 558
560dnl chown/chmod to be setuid root as part of build 559dnl chown/chmod to be setuid root as part of build
@@ -1875,6 +1874,5 @@ hw/kdrive/fbdev/Makefile
1875hw/kdrive/linux/Makefile 1874hw/kdrive/linux/Makefile
1876hw/kdrive/sdl/Makefile 1875hw/kdrive/sdl/Makefile
1877hw/kdrive/src/Makefile 1876hw/kdrive/src/Makefile
1878hw/kdrive/vesa/Makefile
1879xorg-server.pc 1877xorg-server.pc
1880]) 1878])
diff --git a/hw/kdrive/Makefile.am b/hw/kdrive/Makefile.am
index c30a157c7..e20d4d6d2 100644
--- a/hw/kdrive/Makefile.am
+++ b/hw/kdrive/Makefile.am
@@ -1,7 +1,3 @@
1if KDRIVEVESA
2VESA_SUBDIRS = vesa
3endif
4
5if BUILD_KDRIVEFBDEVLIB 1if BUILD_KDRIVEFBDEVLIB
6FBDEV_SUBDIRS = fbdev 2FBDEV_SUBDIRS = fbdev
7endif 3endif
@@ -25,7 +21,6 @@ endif
25SERVER_SUBDIRS = \ 21SERVER_SUBDIRS = \
26 $(XSDL_SUBDIRS) \ 22 $(XSDL_SUBDIRS) \
27 $(FBDEV_SUBDIRS) \ 23 $(FBDEV_SUBDIRS) \
28 $(VESA_SUBDIRS) \
29 $(XEPHYR_SUBDIRS) \ 24 $(XEPHYR_SUBDIRS) \
30 $(XFAKE_SUBDIRS) 25 $(XFAKE_SUBDIRS)
31 26
@@ -34,7 +29,7 @@ SUBDIRS = \
34 $(LINUX_SUBDIRS) \ 29 $(LINUX_SUBDIRS) \
35 $(SERVER_SUBDIRS) 30 $(SERVER_SUBDIRS)
36 31
37DIST_SUBDIRS = vesa fbdev sdl ephyr src linux fake 32DIST_SUBDIRS = fbdev sdl ephyr src linux fake
38 33
39relink: 34relink:
40 @for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done 35 @for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done
diff --git a/hw/kdrive/vesa/Makefile.am b/hw/kdrive/vesa/Makefile.am
deleted file mode 100644
index 4225dcfbc..000000000
--- a/hw/kdrive/vesa/Makefile.am
+++ /dev/null
@@ -1,33 +0,0 @@
1INCLUDES = \
2 @KDRIVE_INCS@ \
3 @KDRIVE_CFLAGS@
4
5noinst_LIBRARIES = libvesa.a
6
7bin_PROGRAMS = Xvesa
8
9libvesa_a_SOURCES = \
10 vesa.c \
11 vesa.h \
12 vbe.c \
13 vbe.h \
14 vga.c \
15 vga.h \
16 vm86.c \
17 vm86.h
18
19Xvesa_SOURCES = \
20 vesainit.c
21
22Xvesa_LDADD = \
23 libvesa.a \
24 @KDRIVE_LIBS@
25
26Xvesa_DEPENDENCIES = \
27 libvesa.a \
28 @KDRIVE_LOCAL_LIBS@
29
30Xvesa_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
31
32relink:
33 rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
diff --git a/hw/kdrive/vesa/Xvesa.man b/hw/kdrive/vesa/Xvesa.man
deleted file mode 100644
index 137531c1b..000000000
--- a/hw/kdrive/vesa/Xvesa.man
+++ /dev/null
@@ -1,105 +0,0 @@
1.\" $RCSId: xc/programs/Xserver/hw/kdrive/vesa/Xvesa.man,v 1.5 2001/01/24 00:06:10 dawes Exp $
2.TH Xvesa 1 __vendorversion__
3.SH NAME
4Xvesa \- VESA Bios Extensions tiny X server
5.SH SYNOPSIS
6.B Xvesa
7.RI [ :display ]
8.RI [ option ...]
9.SH DESCRIPTION
10.B Xvesa
11is a generic X server for Linux on the x86 platform.
12.B Xvesa
13doesn't know about any particular hardware, and sets the video mode by
14running the video BIOS in VM86 mode.
15.B Xvesa
16can use both standard VGA BIOS modes and any modes advertised by a
17VESA BIOS if available.
18
19.B Xvesa
20runs untrusted code with full privileges, and is therefore a fairly
21insecure X server.
22.B Run at your own risk.
23.SH OPTIONS
24In addition to the normal KDrive server's options (see Xkdrive(1)),
25.B Xvesa
26accepts the following command line switches:
27.TP 8
28.B -mode \fIn\fB
29specifies the VESA video mode to use. If mode
30.I n
31is not supported by your BIOS and hardware,
32.B Xvesa
33will fail, hang your system, damage your hardware, or cause a global
34thermonuclear war; you are on your own. This option overrides any
35.B -screen
36options.
37.TP 8
38.B -listmodes
39list all supported video modes. If
40.B -force
41was specified before
42.BR -listmodes ,
43lists all the modes that your BIOS claims to support, even those that
44the
45.B Xvesa
46server won't be able to use.
47.TP 8
48.B -force
49disable some sanity checks and use the specified mode even if the
50BIOS claims not to support it.
51.TP 8
52.B -shadow
53use a shadow framebuffer even if it is not strictly necessary. This
54may dramatically improve performance on some hardware.
55.TP 8
56.B -nolinear
57don't use a linear framebuffer even if one is available. You don't
58want to use this option.
59.TP 8
60.B -swaprgb
61pass RGB values in the order that works on broken BIOSes. Use this if
62the colours are wrong in PseudoColor and 16 colour modes.
63.TP 8
64.B -map-holes
65use a contiguous (hole-less) memory map. This fixes a segmentation
66violation with some rare BIOSes that violate the VESA specification,
67but may cause slightly higher memory usage on systems that overcommit
68memory.
69.TP 8
70.B -force-text
71ignore saved video mode and switch back to regular 25x80 text mode
72on server exit or VT switch.
73.TP 8
74.B -verbose
75emit diagnostic messages during BIOS initialization and teardown.
76.SH KEYBOARD
77Multiple key presses recognized directly by
78.B Xvesa
79are:
80.TP 8
81.B Ctrl+Alt+Backspace
82Immediately kill the server.
83.TP 8
84.B Ctrl+Alt+F1...F12
85Switch to virtual console 1 through 12.
86.SH BUGS
87.B Xvesa
88opens all IO ports and runs your VESA BIOS, which may be assumed to be
89buggy. Allowing your users to run
90.B Xvesa
91is probably a security hole.
92
93.B Xvesa
94records the current BIOS mode when it starts and restores that mode on
95termination; if the video card has been reprogrammed by another application,
96the display will almost certainly be trashed. The alternative of saving and
97restoring the complete video card state has proven unreliable on most video
98cards.
99.SH SEE ALSO
100X(__miscmansuffix__), Xserver(1), Xkdrive(1), xdm(1), xinit(1).
101.SH AUTHORS
102The VESA driver was written by Juliusz Chroboczek who didn't realise
103what he was doing until it was too late. Keith Packard then added
104support for standard VGA BIOS modes and is especially proud of 320x200
10516 colour mode.
diff --git a/hw/kdrive/vesa/vbe.c b/hw/kdrive/vesa/vbe.c
deleted file mode 100644
index cedefe9fc..000000000
--- a/hw/kdrive/vesa/vbe.c
+++ /dev/null
@@ -1,706 +0,0 @@
1/*
2Copyright (c) 2000 by Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#ifdef HAVE_CONFIG_H
24#include <kdrive-config.h>
25#endif
26#include "vesa.h"
27
28int
29VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib)
30{
31 int code;
32 int mark;
33 int vib_base;
34 VbeInfoBlock *vib_low;
35
36 mark = Vm86MarkMemory (vi);
37 vib_base = Vm86AllocateMemory (vi, sizeof (VbeInfoBlock));
38 vib_low = (VbeInfoBlock*)&(LM(vi, vib_base));
39 vi->vms.regs.eax = 0x4F00;
40 vi->vms.regs.es = POINTER_SEGMENT(vib_base);
41 vi->vms.regs.edi = POINTER_OFFSET(vib_base);
42 memcpy(vib_low->VbeSignature, "VBE2", 4);
43 code = VbeDoInterrupt10(vi);
44 if(code >= 0)
45 {
46 if(memcmp(vib_low->VbeSignature, "VESA", 4) == 0)
47 *vib = *vib_low;
48 else
49 code = -1;
50 }
51 Vm86ReleaseMemory (vi, mark);
52 return code;
53}
54
55int
56VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib)
57{
58 int code;
59 int mark;
60 int vmib_base;
61 VbeModeInfoBlock *vmib_low;
62
63 mark = Vm86MarkMemory (vi);
64
65 vmib_base = Vm86AllocateMemory (vi, sizeof (VbeModeInfoBlock));
66 vmib_low = (VbeModeInfoBlock*)&(LM(vi, vmib_base));
67
68 vi->vms.regs.eax = 0x4F01;
69 vi->vms.regs.ecx = mode&0xFFFF;
70 vi->vms.regs.es = POINTER_SEGMENT(vmib_base);
71 vi->vms.regs.edi = POINTER_OFFSET(vmib_base);
72 code = VbeDoInterrupt10(vi);
73
74 if(code >= 0)
75 *vmib = *vmib_low;
76 Vm86ReleaseMemory (vi, mark);
77 return code;
78}
79
80static int
81VbeReportVib(Vm86InfoPtr vi, VbeInfoBlock *vib)
82{
83 U32 i, p;
84 unsigned char c;
85 int error = 0;
86
87 ErrorF("VBE version %c.%c (",
88 ((vib->VbeVersion >> 8) & 0xFF) + '0',
89 (vib->VbeVersion & 0xFF)+'0');
90 p = vib->OemStringPtr;
91 for(i = 0; 1; i++) {
92 c = Vm86Memory(vi, MAKE_POINTER_1(p+i));
93 if(!c) break;
94 if (c >= ' ')
95 ErrorF("%c", c);
96 if (i > 32000) {
97 error = 1;
98 break;
99 }
100 }
101 ErrorF(")\n");
102 ErrorF("DAC is %s, controller is %sVGA compatible%s\n",
103 (vib->Capabilities[0]&1)?"switchable":"fixed",
104 (vib->Capabilities[0]&2)?"not ":"",
105 (vib->Capabilities[0]&3)?", RAMDAC causes snow":"");
106 ErrorF("Total memory: %lu kilobytes\n", 64L*vib->TotalMemory);
107 if(error)
108 return -1;
109 return 0;
110}
111
112#if 0
113static int
114VbeReportModeInfo(Vm86InfoPtr vi, U16 mode, VbeModeInfoBlock *vmib)
115{
116 int supported = (vmib->ModeAttributes&0x1)?1:0;
117 int colour = (vmib->ModeAttributes&0x8)?1:0;
118 int graphics = (vmib->ModeAttributes&0x10)?1:0;
119 int vga_compatible = !((vmib->ModeAttributes&0x20)?1:0);
120 int linear_fb = (vmib->ModeAttributes&0x80)?1:0;
121
122 ErrorF("0x%04X: %dx%dx%d%s",
123 (unsigned)mode,
124 (int)vmib->XResolution, (int)vmib->YResolution,
125 (int)vmib->BitsPerPixel,
126 colour?"":" (monochrome)",
127 graphics?"":" (graphics)",
128 vga_compatible?"":" (vga compatible)",
129 linear_fb?"":" (linear frame buffer)");
130 switch(vmib->MemoryModel) {
131 case 0:
132 ErrorF(" text mode (%dx%d)",
133 (int)vmib->XCharSize, (int)vmib->YCharSize);
134 break;
135 case 1:
136 ErrorF(" CGA graphics");
137 break;
138 case 2:
139 ErrorF(" Hercules graphics");
140 break;
141 case 3:
142 ErrorF(" Planar (%d planes)", vmib->NumberOfPlanes);
143 break;
144 case 4:
145 ErrorF(" PseudoColor");
146 break;
147 case 5:
148 ErrorF(" Non-chain 4, 256 colour");
149 break;
150 case 6:
151 if(vmib->DirectColorModeInfo & 1)
152 ErrorF(" DirectColor");
153 else
154 ErrorF(" TrueColor");
155 ErrorF(" [%d:%d:%d:%d]",
156 vmib->RedMaskSize, vmib->GreenMaskSize, vmib->BlueMaskSize,
157 vmib->RsvdMaskSize);
158 if(vmib->DirectColorModeInfo & 2)
159 ErrorF(" (reserved bits are reserved)");
160 break;
161 case 7: ErrorF("YUV");
162 break;
163 default:
164 ErrorF("unknown MemoryModel 0x%X ", vmib->MemoryModel);
165 }
166 if(!supported)
167 ErrorF(" (unsupported)");
168 else if(!linear_fb)
169 ErrorF(" (no linear framebuffer)");
170 ErrorF("\n");
171 return 0;
172}
173#endif
174
175void
176VbeReportInfo (Vm86InfoPtr vi)
177{
178 VbeInfoBlock vib;
179 int code;
180
181 code = VbeGetVib (vi, &vib);
182 if (code >= 0)
183 VbeReportVib(vi, &vib);
184}
185
186int
187VbeGetNmode (Vm86InfoPtr vi)
188{
189 VbeInfoBlock vib;
190 int code;
191 unsigned int p;
192 int n;
193 int mode;
194
195 code = VbeGetVib (vi, &vib);
196 if (code >= 0)
197 {
198 p = MAKE_POINTER_1(vib.VideoModePtr);
199 for (n = 0; ; n++)
200 {
201 mode = Vm86MemoryW(vi, p);
202 if (mode == 0xffff)
203 break;
204 p += 2;
205 }
206 code = n;
207 }
208 return code;
209}
210
211int
212VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode)
213{
214 VbeInfoBlock vib;
215 int code;
216 unsigned int p;
217 int n;
218 int mode;
219 VbeModeInfoBlock vmib;
220
221 code = VbeGetVib (vi, &vib);
222 if (code < 0)
223 return code;
224
225 memset (modes, '\0', nmode * sizeof (VesaModeRec));
226
227 p = MAKE_POINTER_1(vib.VideoModePtr);
228 for (n = 0; n < nmode; n++)
229 {
230 mode = Vm86MemoryW(vi, p);
231 if (mode == 0xffff)
232 break;
233 modes[n].mode = mode;
234 modes[n].vbe = 1;
235 p += 2;
236 }
237
238 nmode = n;
239
240 for (n = 0; n < nmode; n++)
241 {
242 code = VbeGetVmib (vi, modes[n].mode, &vmib);
243 if (code >= 0)
244 {
245 modes[n].ModeAttributes = vmib.ModeAttributes;
246 modes[n].NumberOfPlanes = vmib.NumberOfPlanes;
247 modes[n].BitsPerPixel = vmib.BitsPerPixel;
248 modes[n].MemoryModel = vmib.MemoryModel;
249 modes[n].RedMaskSize = vmib.RedMaskSize;
250 modes[n].RedFieldPosition = vmib.RedFieldPosition;
251 modes[n].GreenMaskSize = vmib.GreenMaskSize;
252 modes[n].GreenFieldPosition = vmib.GreenFieldPosition;
253 modes[n].BlueMaskSize = vmib.BlueMaskSize;
254 modes[n].BlueFieldPosition = vmib.BlueFieldPosition;
255 modes[n].RsvdMaskSize = vmib.RsvdMaskSize;
256 modes[n].RsvdFieldPosition = vmib.RsvdFieldPosition;
257 modes[n].DirectColorModeInfo = vmib.DirectColorModeInfo;
258 modes[n].XResolution = vmib.XResolution;
259 modes[n].YResolution = vmib.YResolution;
260 modes[n].BytesPerScanLine = vmib.BytesPerScanLine;
261 }
262 }
263
264 return nmode;
265}
266
267VbeInfoPtr
268VbeInit (Vm86InfoPtr vi)
269{
270 VbeInfoPtr vbe;
271 int code;
272 VbeInfoBlock vib;
273
274 code = VbeGetVib (vi, &vib);
275 if (code < 0)
276 return 0;
277
278 vbe = xalloc (sizeof (VbeInfoRec));
279 if (!vbe)
280 return 0;
281 vbe->palette_format = 6;
282 vbe->palette_wait = TRUE;
283 return vbe;
284}
285
286void
287VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe)
288{
289 xfree (vbe);
290}
291
292int
293VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct)
294{
295 int code;
296 VbeInfoBlock vib;
297 int palette_wait = 0, palette_hi = 0;
298
299 code = VbeGetVib (vi, &vib);
300 if (code < 0)
301 return -1;
302
303 code = VbeGetVmib (vi, mode, &vbe->vmib);
304 if (code < 0)
305 return -1;
306
307 mode = (mode & 0xffff) &~ 0x8000;
308 if (linear)
309 mode |= 0x4000;
310
311 vi->vms.regs.eax = 0x4F02;
312 vi->vms.regs.ebx = mode;
313 code = VbeDoInterrupt10(vi);
314 if(code < 0)
315 return -1;
316
317 vbe->windowA_offset = vbe->windowB_offset = -1;
318 vbe->last_window = 1;
319
320 if (!direct)
321 {
322 if(vib.Capabilities[0] & 1)
323 palette_hi = 1;
324 if(vib.Capabilities[0] & 4)
325 palette_wait = 1;
326
327 if(palette_hi || palette_wait)
328 VbeSetPaletteOptions(vi, vbe, palette_hi?8:6, palette_wait);
329 }
330
331 return 0;
332}
333
334int
335VbeGetMode(Vm86InfoPtr vi, int *mode)
336{
337 int code;
338
339 vi->vms.regs.eax = 0x4F03;
340 code = VbeDoInterrupt10(vi);
341 if(code < 0)
342 return - 1;
343 *mode = vi->vms.regs.ebx & 0xFFFF;
344 return 0;
345}
346
347void *
348VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size, CARD32 *ret_phys)
349{
350 U8 *fb;
351 VbeInfoBlock vib;
352 VbeModeInfoBlock vmib;
353 int size;
354 int pagesize = getpagesize();
355 int before, after;
356
357 if (VbeGetVib (vi, &vib) < 0)
358 return 0;
359
360 if (VbeGetVmib (vi, mode, &vmib) < 0)
361 return 0;
362
363 size = 1024 * 64L * vib.TotalMemory;
364
365 *ret_size = size;
366 *ret_phys = vmib.PhysBasePtr;
367
368 before = vmib.PhysBasePtr % pagesize;
369 after = pagesize - ((vmib.PhysBasePtr + size) % pagesize);
370 if(after == pagesize)
371 after = 0;
372
373 fb = KdMapDevice (vmib.PhysBasePtr - before, before + size + after);
374
375 if(fb == 0)
376 {
377 ErrorF("Failed to map framebuffer\n");
378 return NULL;
379 }
380
381 KdSetMappedMode (vmib.PhysBasePtr - before, before + size + after,
382 KD_MAPPED_MODE_FRAMEBUFFER);
383
384 return fb + before;
385}
386
387void
388VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb)
389{
390 VbeInfoBlock vib;
391 VbeModeInfoBlock vmib;
392 int size;
393 int pagesize = getpagesize();
394 int before, after;
395
396 if (VbeGetVib (vi, &vib) < 0)
397 return;
398
399 if (VbeGetVmib (vi, mode, &vmib) < 0)
400 return;
401
402 size = 1024 * 64L * vib.TotalMemory;
403
404 before = vmib.PhysBasePtr % pagesize;
405 after = pagesize - ((vmib.PhysBasePtr + size) % pagesize);
406 if(after == pagesize)
407 after = 0;
408
409 fb = (void *) ((char *) fb - before);
410
411 KdUnmapDevice (fb, before + size + after);
412 KdResetMappedMode (vmib.PhysBasePtr - before, before + size + after,
413 KD_MAPPED_MODE_FRAMEBUFFER);
414}
415
416int
417VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries)
418{
419 U8 *palette_scratch;
420 int mark;
421 int palette_base;
422 int i, code;
423
424 if(number == 0)
425 return 0;
426
427 if(first < 0 || number < 0 || first + number > 256) {
428 ErrorF("Cannot set %d, %d palette entries\n", first, number);
429 return -1;
430 }
431 if(vbe->palette_format < 6 || vbe->palette_format > 8) {
432 ErrorF("Impossible palette format %d\n", vbe->palette_format);
433 return -1;
434 }
435
436 mark = Vm86MarkMemory (vi);
437 palette_base = Vm86AllocateMemory (vi, 4 * 256);
438
439 palette_scratch = &LM(vi, palette_base);
440
441 for(i=0; i<number*4; i++)
442 palette_scratch[i] = entries[i] >> (8 - vbe->palette_format);
443
444 vi->vms.regs.eax = 0x4F09;
445 if(vbe->palette_wait)
446 vi->vms.regs.ebx = 0x80;
447 else
448 vi->vms.regs.ebx = 0x00;
449 vi->vms.regs.ecx = number;
450 vi->vms.regs.edx = first;
451 vi->vms.regs.es = POINTER_SEGMENT(palette_base);
452 vi->vms.regs.edi = POINTER_OFFSET(palette_base);
453 code = VbeDoInterrupt10(vi);
454 Vm86ReleaseMemory (vi, mark);
455
456 if(code < 0)
457 return -1;
458 return 0;
459}
460
461int
462VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries)
463{
464 U8 *palette_scratch;
465 int mark;
466 int palette_base;
467 int i, code;
468
469 if(number == 0)
470 return 0;
471
472 if(first < 0 || number < 0 || first + number > 256) {
473 ErrorF("Cannot get %d, %d palette entries\n", first, number);
474 return -1;
475 }
476 if(vbe->palette_format < 6 || vbe->palette_format > 8) {
477 ErrorF("Impossible palette format %d\n", vbe->palette_format);
478 return -1;
479 }
480
481 mark = Vm86MarkMemory (vi);
482 palette_base = Vm86AllocateMemory (vi, 4 * 256);
483
484 palette_scratch = &LM(vi, palette_base);
485
486 vi->vms.regs.eax = 0x4F09;
487 vi->vms.regs.ebx = 0x01;
488 vi->vms.regs.ecx = number;
489 vi->vms.regs.edx = first;
490 vi->vms.regs.es = POINTER_SEGMENT(palette_base);
491 vi->vms.regs.edi = POINTER_OFFSET(palette_base);
492 code = VbeDoInterrupt10(vi);
493 if(code >= 0)
494 {
495 for(i=0; i<number*4; i++)
496 entries[i] = palette_scratch[i] << (8-vbe->palette_format);
497 }
498 Vm86ReleaseMemory (vi, mark);
499
500 return 0;
501}
502
503int
504VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait)
505{
506 int code;
507
508 if(bits < 6 || bits > 8) {
509 ErrorF("Impossible palette format %d\n", bits);
510 return -1;
511 }
512 if(bits != vbe->palette_format)
513 {
514 vbe->palette_format = 0;
515 vi->vms.regs.eax = 0x4F08;
516 vi->vms.regs.ebx = bits << 8;
517 code = VbeDoInterrupt10(vi);
518 if(code < 0)
519 return -1;
520 vbe->palette_format = bits;
521 }
522 vbe->palette_wait = wait;
523 return 0;
524}
525
526static int
527VbeReallySetWindow(Vm86InfoPtr vi, U8 window, U16 winnum)
528{
529 int code;
530 vi->vms.regs.eax = 0x4F05;
531 vi->vms.regs.ebx = window;
532 vi->vms.regs.edx = winnum;
533 code = VbeDoInterrupt10(vi);
534 if(code < 0)
535 return -1;
536 return 0;
537}
538
539void *
540VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return)
541{
542 int window_size = vbe->vmib.WinSize * 1024;
543 int code;
544 int winnum;
545
546 if(vbe->windowA_offset >= 0)
547 if(vbe->windowA_offset <= offset && vbe->windowA_offset + window_size > offset)
548 if(vbe->vmib.WinAAttributes & purpose)
549 goto windowA;
550
551 if(vbe->windowB_offset >= 0)
552 if(vbe->windowB_offset <= offset && vbe->windowB_offset + window_size > offset)
553 if(vbe->vmib.WinBAttributes & purpose)
554 goto windowB;
555
556 if(!(vbe->vmib.WinBAttributes & purpose) ||
557 !(vbe->vmib.WinBAttributes & VBE_WINDOW_RELOCATE))
558 goto set_windowA;
559
560 if(!(vbe->vmib.WinAAttributes & purpose) ||
561 !(vbe->vmib.WinAAttributes & VBE_WINDOW_RELOCATE))
562 goto set_windowB;
563
564 if(vbe->last_window)
565 goto set_windowA;
566 else
567 goto set_windowB;
568
569set_windowA:
570 winnum = offset / (vbe->vmib.WinGranularity * 1024);
571 code = VbeReallySetWindow(vi, 0, winnum);
572 if(code < 0) {
573 ErrorF("Couldn't set window A to %d*%d\n",
574 (int)winnum, (int)vbe->vmib.WinGranularity);
575 return NULL;
576 }
577 vbe->windowA_offset = winnum * vbe->vmib.WinGranularity * 1024;
578windowA:
579 vbe->last_window = 0;
580 *size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowA_offset);
581 return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinASegment, 0)))) + offset - vbe->windowA_offset;
582
583set_windowB:
584 winnum = offset / (vbe->vmib.WinGranularity * 1024);
585 code = VbeReallySetWindow(vi, 1, winnum);
586 if(code < 0) {
587 ErrorF("Couldn't set window B to %d*%d\n",
588 (int)winnum, (int)vbe->vmib.WinGranularity);
589 return NULL;
590 }
591 vbe->windowB_offset = winnum * vbe->vmib.WinGranularity * 1024;
592windowB:
593 vbe->last_window = 1;
594 *size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowB_offset);
595 return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinBSegment, 0)))) + offset - vbe->windowB_offset;
596}
597
598static const int VbeDPMSModes[4] = {
599 0x00, /* KD_DPMS_NORMAL */
600 0x01, /* KD_DPMS_STANDBY */
601 0x02, /* KD_DPMS_SUSPEND */
602 0x04, /* KD_DPMS_POWERDOWN */
603};
604
605Bool
606VbeDPMS(Vm86InfoPtr vi, int mode)
607{
608 int code;
609
610 /*
611 * Check which modes are supported
612 */
613 vi->vms.regs.eax = 0x4f10;
614 vi->vms.regs.ebx = 0x0000;
615 vi->vms.regs.es = 0;
616 vi->vms.regs.edi = 0;
617 code = VbeDoInterrupt10 (vi);
618 if (code < 0)
619 {
620 ErrorF ("No DPMS Support %d\n", code);
621 return FALSE;
622 }
623 /* Skip this stage if it's not supported */
624 if (((vi->vms.regs.ebx >> 4) & VbeDPMSModes[mode]) != VbeDPMSModes[mode])
625 return FALSE;
626
627 /* Select this mode */
628 vi->vms.regs.eax = 0x4f10;
629 vi->vms.regs.ebx = (VbeDPMSModes[mode] << 8) | 0x01;
630 code = VbeDoInterrupt10 (vi);
631 if (code < 0)
632 {
633 ErrorF ("DPMS failed %d\n", code);
634 return FALSE;
635 }
636
637 return TRUE;
638}
639
640Bool
641VbeBoot(Vm86InfoPtr vi)
642{
643 int code;
644 int bus = 1;
645 int device = 0;
646 int function = 0;
647
648 vi->vms.regs.eax = (bus << 8) | (device << 3) | (function & 0x7);
649 code = VbeDoInterruptE6 (vi);
650 ErrorF ("Boot: %d\n", code);
651 return TRUE;
652}
653
654int
655VbeDoInterrupt10(Vm86InfoPtr vi)
656{
657 int code;
658 int oldax;
659
660 oldax = vi->vms.regs.eax & 0xFFFF;
661
662 code = Vm86DoInterrupt(vi, 0x10);
663 if(code < 0)
664 return -1;
665
666 if((vi->vms.regs.eax & 0xFFFF) != 0x4F && (oldax & 0xFF00) == 0x4F00) {
667 ErrorF("Int 10h (0x%04X) failed: 0x%04X",
668 oldax, vi->vms.regs.eax & 0xFFFF);
669 if((oldax & 0xFF00) == 0x4F00) {
670 switch((vi->vms.regs.eax & 0xFF00)>>8) {
671 case 0:
672 ErrorF(" (success)\n");
673 return 0;
674 case 1:
675 ErrorF(" (function call failed)\n");
676 break;
677 case 2:
678 ErrorF(" (function not supported on this hardware)\n");
679 break;
680 case 3:
681 ErrorF(" (function call invalid in this video mode)\n");
682 break;
683 default:
684 ErrorF(" (unknown error)\n");
685 break;
686 } return -1;
687 } else {
688 ErrorF("\n");
689 }
690 }
691 return code;
692}
693
694int
695VbeDoInterruptE6(Vm86InfoPtr vi)
696{
697 int code;
698 int oldax;
699
700 oldax = vi->vms.regs.eax & 0xffff;
701
702 code = Vm86DoPOST (vi);
703 ErrorF("POST (0x%04X): 0x%04X\n",
704 oldax, vi->vms.regs.eax & 0xffff);
705 return code;
706}
diff --git a/hw/kdrive/vesa/vbe.h b/hw/kdrive/vesa/vbe.h
deleted file mode 100644
index f67fbbe42..000000000
--- a/hw/kdrive/vesa/vbe.h
+++ /dev/null
@@ -1,165 +0,0 @@
1/*
2Copyright (c) 2000 by Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#ifndef _VBE_H
24#define _VBE_H
25
26#define VBE_WINDOW_RELOCATE 1
27#define VBE_WINDOW_READ 2
28#define VBE_WINDOW_WRITE 4
29
30typedef struct _VbeInfoBlock {
31 U8 VbeSignature[4]; /* VBE Signature */
32 U16 VbeVersion; /* VBE Version */
33 U32 OemStringPtr; /* Pointer to OEM String */
34 U8 Capabilities[4]; /* Capabilities of graphics controller */
35 U32 VideoModePtr; /* Pointer to VideoModeList */
36 U16 TotalMemory; /* Number of 64kb memory blocks */
37/* Added for VBE 2.0 */
38 U16 OemSoftwareRev; /* VBE implementation Software revision */
39 U32 OemVendorNamePtr; /* Pointer to Vendor Name String */
40 U32 OemProductNamePtr; /* Pointer to Product Name String */
41 U32 OemProductRevPtr; /* Pointer to Product Revision String */
42 U8 Reserved[222]; /* Reserved for VBE implementation */
43 U8 OemData[256]; /* Data Area for OEM Strings*/
44} __attribute__((packed)) VbeInfoBlock;
45
46typedef struct _VbeModeInfoBlock {
47/* Mandatory information for all VBE revisions */
48 U16 ModeAttributes; /* mode attributes */
49 U8 WinAAttributes; /* window A attributes */
50 U8 WinBAttributes; /* window B attributes */
51 U16 WinGranularity; /* window granularity */
52 U16 WinSize; /* window size */
53 U16 WinASegment; /* window A start segment */
54 U16 WinBSegment; /* window B start segment */
55 U32 WinFuncPtr; /* pointer to window function */
56 U16 BytesPerScanLine; /* bytes per scan line */
57/* Mandatory information for VBE 1.2 and above */
58 U16 XResolution; /* horizontal resolution */
59 U16 YResolution; /* vertical resolution */
60 U8 XCharSize; /* character cell width in pixels */
61 U8 YCharSize; /* character cell height in pixels */
62 U8 NumberOfPlanes; /* number of memory planes */
63 U8 BitsPerPixel; /* bits per pixel */
64 U8 NumberOfBanks; /* number of banks */
65 U8 MemoryModel; /* memory model type */
66 U8 BankSize; /* bank size in KB */
67 U8 NumberOfImagePages; /* number of images */
68 U8 Reserved; /* reserved for page function */
69/* Direct Color fields (required for direct/6 and YUV/7 memory models) */
70 U8 RedMaskSize; /* size of direct color red mask in bits */
71 U8 RedFieldPosition; /* bit position of lsb of red mask */
72 U8 GreenMaskSize; /* size of direct color green mask in bits */
73 U8 GreenFieldPosition; /* bit position of lsb of green mask */
74 U8 BlueMaskSize; /* size of direct color blue mask in bits */
75 U8 BlueFieldPosition; /* bit position of lsb of blue mask */
76 U8 RsvdMaskSize; /* size of direct color reserved mask bits*/
77 U8 RsvdFieldPosition; /* bit position of lsb of reserved mask */
78 U8 DirectColorModeInfo; /* direct color mode attributes */
79/* Mandatory information for VBE 2.0 and above */
80 U32 PhysBasePtr; /* physical address for flat memory fb */
81 U32 OffScreenMemOffset; /* pointer to start of off screen memory */
82 U16 OffScreenMemSize; /* amount of off screen memory in 1k units */
83 U8 Reserved2[206]; /* remainder of ModeInfoBlock */
84} __attribute__((packed)) VbeModeInfoBlock;
85
86typedef struct _VbeInfoRec {
87 U8 palette_format;
88 int palette_wait;
89 int windowA_offset;
90 int windowB_offset;
91 int window_size;
92 int last_window;
93 VbeModeInfoBlock vmib;
94} VbeInfoRec, *VbeInfoPtr;
95
96typedef struct _SupVbeInfoBlock {
97 U8 SupVbeSignature[7]; /* Supplemental VBE Signature */
98 U16 SupVbeVersion; /* Supplemental VBE Version*/
99 U8 SupVbeSubFunc[8]; /* Bitfield of supported subfunctions */
100 U16 OemSoftwareRev; /* OEM Software revision */
101 U32 OemVendorNamePtr; /* Pointer to Vendor Name String */
102 U32 OemProductNamePtr; /* Pointer to Product Name String */
103 U32 OemProductRevPtr; /* Pointer to Product Revision String */
104 U32 OemStringPtr; /* Pointer to OEM String */
105 U8 Reserved[221]; /* Reserved */
106} __attribute__((packed)) SupVbeInfoBlock;
107
108int
109VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib);
110
111int
112VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib);
113
114void
115VbeReportInfo (Vm86InfoPtr vi);
116
117int
118VbeGetNmode (Vm86InfoPtr vi);
119
120int
121VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode);
122
123VbeInfoPtr
124VbeInit (Vm86InfoPtr vi);
125
126void
127VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe);
128
129int
130VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct);
131
132int
133VbeGetMode(Vm86InfoPtr vi, int *mode);
134
135void *
136VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size, CARD32 *ret_phys);
137
138void
139VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb);
140
141int
142VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries);
143
144int
145VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries);
146
147int
148VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait);
149
150void *
151VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return);
152
153Bool
154VbeDPMS(Vm86InfoPtr vi, int mode);
155
156int
157VbeDoInterrupt10(Vm86InfoPtr vi);
158
159Bool
160VbeBoot(Vm86InfoPtr vi);
161
162int
163VbeDoInterruptE6(Vm86InfoPtr vi);
164
165#endif
diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c
deleted file mode 100644
index b7cc8f1e9..000000000
--- a/hw/kdrive/vesa/vesa.c
+++ /dev/null
@@ -1,1819 +0,0 @@
1/*
2Copyright (c) 2000 by Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#ifdef HAVE_CONFIG_H
24#include <kdrive-config.h>
25#endif
26#include "vesa.h"
27#include "vga.h"
28#include "vbe.h"
29#ifdef RANDR
30#include <randrstr.h>
31#endif
32
33int vesa_video_mode = 0;
34Bool vesa_force_mode = FALSE;
35Bool vesa_swap_rgb = FALSE;
36Bool vesa_shadow = FALSE;
37Bool vesa_linear_fb = TRUE;
38Bool vesa_restore = FALSE;
39Bool vesa_verbose = FALSE;
40Bool vesa_force_text = FALSE;
41Bool vesa_restore_font = TRUE;
42Bool vesa_map_holes = TRUE;
43Bool vesa_boot = FALSE;
44
45#define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver)
46
47#define vesaWidth(scr,vmib) ((vmib)->XResolution)
48#define vesaHeight(scr,vmib) ((vmib)->YResolution)
49
50static Bool
51vesaComputeFramebufferMapping (KdScreenInfo *screen);
52
53static Bool
54vesaMapFramebuffer (KdScreenInfo *screen);
55
56static Bool
57vesaModeSupportable (VesaModePtr mode, Bool complain)
58{
59 if((mode->ModeAttributes & 0x10) == 0) {
60 if(complain)
61 ErrorF("Text mode specified.\n");
62 return FALSE;
63 }
64 if(mode->MemoryModel != 0x06 && mode->MemoryModel != 0x04 && mode->MemoryModel != 0x03) {
65 if(complain)
66 ErrorF("Unsupported memory model 0x%X\n", mode->MemoryModel);
67 return FALSE;
68 }
69 if((mode->ModeAttributes & 0x80) == 0) {
70 if ((mode->ModeAttributes & 0x40) != 0) {
71 if(complain)
72 ErrorF("Neither linear nor windowed framebuffer available in this mode\n");
73 return FALSE;
74 }
75 }
76 if(!(mode->ModeAttributes & 1)) {
77 if(complain)
78 ErrorF("Mode not supported on this hardware\n");
79 return FALSE;
80 }
81 return TRUE;
82}
83
84static Bool
85vesaModeSupported (VesaCardPrivPtr priv, VesaModePtr mode, Bool complain)
86{
87 if (!priv->vbeInfo && mode->vbe) {
88 if (complain)
89 ErrorF("VBE bios mode not usable.\n");
90 return FALSE;
91 }
92 return vesaModeSupportable (mode, complain);
93}
94
95void
96vesaReportMode (VesaModePtr mode)
97{
98 int supported = (mode->ModeAttributes&MODE_SUPPORTED)?1:0;
99 int colour = (mode->ModeAttributes&MODE_COLOUR)?1:0;
100 int graphics = (mode->ModeAttributes&MODE_GRAPHICS)?1:0;
101 int vga_compatible = !((mode->ModeAttributes&MODE_VGA)?1:0);
102 int linear_fb = (mode->ModeAttributes&MODE_LINEAR)?1:0;
103
104 ErrorF("0x%04X: %dx%dx%d%s%s",
105 (unsigned)mode->mode,
106 (int)mode->XResolution, (int)mode->YResolution,
107 vesaDepth (mode),
108 colour?"":" (monochrome)",
109 graphics?"":" (graphics)",
110 vga_compatible?"":" (vga compatible)",
111 linear_fb?"":" (linear frame buffer)");
112 switch(mode->MemoryModel) {
113 case MEMORY_TEXT:
114 ErrorF(" text mode");
115 break;
116 case MEMORY_CGA:
117 ErrorF(" CGA graphics");
118 break;
119 case MEMORY_HERCULES:
120 ErrorF(" Hercules graphics");
121 break;
122 case MEMORY_PLANAR:
123 ErrorF(" Planar (%d planes)", mode->NumberOfPlanes);
124 break;
125 case MEMORY_PSEUDO:
126 ErrorF(" PseudoColor");
127 break;
128 case MEMORY_NONCHAIN:
129 ErrorF(" Non-chain 4, 256 colour");
130 break;
131 case MEMORY_DIRECT:
132 if(mode->DirectColorModeInfo & MODE_DIRECT)
133 ErrorF(" DirectColor");
134 else
135 ErrorF(" TrueColor");
136 ErrorF(" [%d:%d:%d:%d]",
137 mode->RedMaskSize, mode->GreenMaskSize, mode->BlueMaskSize,
138 mode->RsvdMaskSize);
139 if(mode->DirectColorModeInfo & 2)
140 ErrorF(" (reserved bits are reserved)");
141 break;
142 case MEMORY_YUV:
143 ErrorF("YUV");
144 break;
145 default:
146 ErrorF("unknown MemoryModel 0x%X ", mode->MemoryModel);
147 }
148 if(!supported)
149 ErrorF(" (unsupported)");
150 else if(!linear_fb)
151 ErrorF(" (no linear framebuffer)");
152 ErrorF("\n");
153}
154
155VesaModePtr
156vesaGetModes (Vm86InfoPtr vi, int *ret_nmode)
157{
158 VesaModePtr modes;
159 int nmode, nmodeVbe, nmodeVga;
160 int code;
161
162 code = VgaGetNmode (vi);
163 if (code <= 0)
164 nmodeVga = 0;
165 else
166 nmodeVga = code;
167
168 code = VbeGetNmode (vi);
169 if (code <= 0)
170 nmodeVbe = 0;
171 else
172 nmodeVbe = code;
173
174 nmode = nmodeVga + nmodeVbe;
175 if (nmode <= 0)
176 return 0;
177
178 modes = xcalloc (nmode, sizeof (VesaModeRec));
179
180 if (nmodeVga)
181 {
182 code = VgaGetModes (vi, modes, nmodeVga);
183 if (code <= 0)
184 nmodeVga = 0;
185 else
186 nmodeVga = code;
187 }
188
189 if (nmodeVbe)
190 {
191 code = VbeGetModes (vi, modes + nmodeVga, nmodeVbe);
192 if (code <= 0)
193 nmodeVbe = 0;
194 else
195 nmodeVbe = code;
196 }
197
198 nmode = nmodeVga + nmodeVbe;
199
200 if (nmode == 0)
201 {
202 xfree (modes);
203 modes = 0;
204 return 0;
205 }
206 *ret_nmode = nmode;
207 return modes;
208}
209
210Bool
211vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv)
212{
213 priv->vi = Vm86Setup(vesa_map_holes);
214 if(!priv->vi)
215 goto fail;
216
217 if (vesa_boot)
218 VbeBoot (priv->vi);
219
220 priv->modes = vesaGetModes (priv->vi, &priv->nmode);
221
222 if (!priv->modes)
223 goto fail;
224
225 priv->vbeInfo = VbeInit (priv->vi);
226
227 card->driver = priv;
228
229 return TRUE;
230
231fail:
232 if(priv->vi)
233 Vm86Cleanup(priv->vi);
234 return FALSE;
235}
236
237void
238vesaListModes (void)
239{
240 Vm86InfoPtr vi;
241 VesaModePtr modes;
242 int nmode;
243 int n;
244
245 vi = Vm86Setup (vesa_map_holes);
246 if (!vi)
247 {
248 ErrorF ("Can't setup vm86\n");
249 }
250 else
251 {
252 modes = vesaGetModes (vi, &nmode);
253 if (!modes)
254 {
255 ErrorF ("No modes available\n");
256 }
257 else
258 {
259 VbeReportInfo (vi);
260 for (n = 0; n < nmode; n++)
261 {
262 if (vesa_force_mode || vesaModeSupportable (modes+n, 0))
263 vesaReportMode (modes+n);
264 }
265 xfree (modes);
266 }
267 Vm86Cleanup (vi);
268 }
269}
270
271void
272vesaTestMode (void)
273{
274 Vm86InfoPtr vi;
275 VesaModePtr modes;
276 VesaModePtr mode;
277 VbeInfoPtr vbeInfo;
278 int nmode;
279 int n;
280
281 vi = Vm86Setup (vesa_map_holes);
282 if (!vi)
283 {
284 ErrorF ("Can't setup vm86\n");
285 return;
286 }
287 modes = vesaGetModes (vi, &nmode);
288 if (!modes)
289 {
290 ErrorF ("No modes available\n");
291 return;
292 }
293 VbeReportInfo (vi);
294 vbeInfo = VbeInit (vi);
295 for (n = 0; n < nmode; n++)
296 {
297 if (modes[n].mode == vesa_video_mode)
298 break;
299 }
300 if (n == nmode)
301 {
302 ErrorF ("no mode specified\n");
303 return;
304 }
305 mode = &modes[n];
306 if (mode->vbe)
307 {
308 ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
309 VbeSetMode(vi, vbeInfo, mode->mode, FALSE, FALSE);
310 }
311 else
312 {
313 ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
314 VgaSetMode (vi, mode->mode);
315 }
316 sleep (2);
317 ErrorF ("Restore BIOS mode 0x%x\n", 3);
318 VgaSetMode (vi, 3);
319 xfree (modes);
320 Vm86Cleanup (vi);
321}
322
323Bool
324vesaCardInit(KdCardInfo *card)
325{
326 VesaCardPrivPtr priv;
327
328 priv = xalloc(sizeof(VesaCardPrivRec));
329 if(!priv)
330 return FALSE;
331
332 if (!vesaInitialize (card, priv))
333 {
334 xfree(priv);
335 return FALSE;
336 }
337
338 return TRUE;
339}
340
341int
342vesaDepth (VesaModePtr mode)
343{
344 if (mode->MemoryModel == MEMORY_DIRECT)
345 return (mode->RedMaskSize +
346 mode->GreenMaskSize +
347 mode->BlueMaskSize);
348 else
349 return mode->BitsPerPixel;
350}
351
352Bool
353vesaModeGood (KdScreenInfo *screen,
354 VesaModePtr a)
355{
356 if (vesaWidth(screen,a) <= screen->width &&
357 vesaHeight(screen,a) <= screen->height &&
358 vesaDepth (a) >= screen->fb[0].depth)
359 {
360 return TRUE;
361 }
362 return FALSE;
363}
364
365#define vabs(a) ((a) >= 0 ? (a) : -(a))
366
367int
368vesaSizeError (KdScreenInfo *screen,
369 VesaModePtr a)
370{
371 int xdist, ydist;
372 xdist = vabs (screen->width - vesaWidth(screen,a));
373 ydist = vabs (screen->height - vesaHeight(screen,a));
374 return xdist * xdist + ydist * ydist;
375}
376
377Bool
378vesaModeBetter (KdScreenInfo *screen,
379 VesaModePtr a,
380 VesaModePtr b)
381{
382 int aerr, berr;
383
384 if (vesaModeGood (screen, a))
385 {
386 if (!vesaModeGood (screen, b))
387 return TRUE;
388 }
389 else
390 {
391 if (vesaModeGood (screen, b))
392 return FALSE;
393 }
394 aerr = vesaSizeError (screen, a);
395 berr = vesaSizeError (screen, b);
396 if (aerr < berr)
397 return TRUE;
398 if (berr < aerr)
399 return FALSE;
400 if (vabs (screen->fb[0].depth - vesaDepth (a)) <
401 vabs (screen->fb[0].depth - vesaDepth (b)))
402 return TRUE;
403 if (a->BitsPerPixel == 32 && b->BitsPerPixel == 24)
404 return TRUE;
405 return FALSE;
406}
407
408VesaModePtr
409vesaSelectMode (KdScreenInfo *screen)
410{
411 VesaCardPrivPtr priv = screen->card->driver;
412 int i, best;
413
414 if (vesa_video_mode)
415 {
416 for (best = 0; best < priv->nmode; best++)
417 if (priv->modes[best].mode == vesa_video_mode &&
418 (vesaModeSupported (priv, &priv->modes[best], FALSE) ||
419 vesa_force_mode))
420 return &priv->modes[best];
421 }
422 for (best = 0; best < priv->nmode; best++)
423 {
424 if (vesaModeSupported (priv, &priv->modes[best], FALSE))
425 break;
426 }
427 if (best == priv->nmode)
428 return 0;
429 for (i = best + 1; i < priv->nmode; i++)
430 if (vesaModeSupported (priv, &priv->modes[i], FALSE) &&
431 vesaModeBetter (screen, &priv->modes[i],
432 &priv->modes[best]))
433 best = i;
434 return &priv->modes[best];
435}
436
437Bool
438vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
439{
440 VesaModePtr mode;
441
442 screen->driver = pscr;
443
444 if (!screen->width || !screen->height)
445 {
446 screen->width = 640;
447 screen->height = 480;
448 }
449 if (!screen->fb[0].depth)
450 screen->fb[0].depth = 4;
451
452 if (vesa_verbose)
453 ErrorF ("Mode requested %dx%dx%d\n",
454 screen->width, screen->height, screen->fb[0].depth);
455
456 mode = vesaSelectMode (screen);
457
458 if (!mode)
459 {
460 if (vesa_verbose)
461 ErrorF ("No selectable mode\n");
462 return FALSE;
463 }
464 pscr->mode = *mode;
465
466 if (vesa_verbose)
467 {
468 ErrorF ("\t");
469 vesaReportMode (&pscr->mode);
470 }
471
472 pscr->randr = screen->randr;
473 pscr->shadow = vesa_shadow;
474 pscr->origDepth = screen->fb[0].depth;
475 /*
476 * Compute visual support for the selected depth
477 */
478
479 switch (pscr->mode.MemoryModel) {
480 case MEMORY_DIRECT:
481 /* TrueColor or DirectColor */
482 screen->fb[0].visuals = (1 << TrueColor);
483 screen->fb[0].redMask =
484 FbStipMask(pscr->mode.RedFieldPosition, pscr->mode.RedMaskSize);
485 screen->fb[0].greenMask =
486 FbStipMask(pscr->mode.GreenFieldPosition, pscr->mode.GreenMaskSize);
487 screen->fb[0].blueMask =
488 FbStipMask(pscr->mode.BlueFieldPosition, pscr->mode.BlueMaskSize);
489 break;
490 case MEMORY_PSEUDO:
491 /* PseudoColor */
492 screen->fb[0].visuals = ((1 << StaticGray) |
493 (1 << GrayScale) |
494 (1 << StaticColor) |
495 (1 << PseudoColor) |
496 (1 << TrueColor) |
497 (1 << DirectColor));
498 screen->fb[0].blueMask = 0x00;
499 screen->fb[0].greenMask = 0x00;
500 screen->fb[0].redMask = 0x00;
501 break;
502 case MEMORY_PLANAR:
503 /* 4 plane planar */
504 if (pscr->mode.ModeAttributes & MODE_COLOUR)
505 screen->fb[0].visuals = (1 << StaticColor);
506 else
507 screen->fb[0].visuals = (1 << StaticGray);
508 screen->fb[0].blueMask = 0x00;
509 screen->fb[0].greenMask = 0x00;
510 screen->fb[0].redMask = 0x00;
511 break;
512 default:
513 ErrorF("Unsupported VESA MemoryModel 0x%02X\n",
514 pscr->mode.MemoryModel);
515 return FALSE;
516 }
517 screen->rate = 72;
518
519 if (!vesaComputeFramebufferMapping (screen))
520 return FALSE;
521 if (!vesaMapFramebuffer (screen))
522 return FALSE;
523 return TRUE;
524}
525
526Bool
527vesaScreenInit(KdScreenInfo *screen)
528{
529 VesaScreenPrivPtr pscr;
530
531 pscr = xcalloc (1, sizeof (VesaScreenPrivRec));
532 if (!pscr)
533 return FALSE;
534 if (!vesaScreenInitialize (screen, pscr))
535 return FALSE;
536 return TRUE;
537}
538
539void *
540vesaSetWindowPlanar(ScreenPtr pScreen,
541 CARD32 row,
542 CARD32 offset,
543 int mode,
544 CARD32 *size)
545{
546 KdScreenPriv(pScreen);
547 VesaCardPrivPtr priv = pScreenPriv->card->driver;
548 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
549 static int plane;
550 int winSize;
551 void *base;
552
553 plane = offset & 3;
554 VgaSetWritePlaneMask (priv->vi, (1 << plane));
555 offset = offset >> 2;
556 if (pscr->mode.vbe)
557 {
558 base = VbeSetWindow (priv->vi,
559 priv->vbeInfo,
560 pscr->mode.BytesPerScanLine * row + offset,
561 mode,
562 &winSize);
563 }
564 else
565 {
566 base = VgaSetWindow (priv->vi,
567 pscr->mode.mode,
568 pscr->mode.BytesPerScanLine * row + offset,
569 mode,
570 &winSize);
571 }
572 *size = (CARD32) winSize;
573 return base;
574}
575
576void *
577vesaSetWindowLinear (ScreenPtr pScreen,
578 CARD32 row,
579 CARD32 offset,
580 int mode,
581 CARD32 *size)
582{
583 KdScreenPriv(pScreen);
584 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
585
586 *size = pscr->mode.BytesPerScanLine;
587 return (CARD8 *) pscr->fb + row * pscr->mode.BytesPerScanLine + offset;
588}
589
590void *
591vesaSetWindowWindowed (ScreenPtr pScreen,
592 CARD32 row,
593 CARD32 offset,
594 int mode,
595 CARD32 *size)
596{
597 KdScreenPriv(pScreen);
598 VesaCardPrivPtr priv = pScreenPriv->card->driver;
599 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
600 int winSize;
601 void *base;
602
603 if (pscr->mode.vbe)
604 {
605 base = VbeSetWindow (priv->vi,
606 priv->vbeInfo,
607 pscr->mode.BytesPerScanLine * row + offset,
608 mode,
609 &winSize);
610 }
611 else
612 {
613 base = VgaSetWindow (priv->vi,
614 pscr->mode.mode,
615 pscr->mode.BytesPerScanLine * row + offset,
616 mode,
617 &winSize);
618 }
619 *size = (CARD32) winSize;
620 return base;
621}
622
623void *
624vesaWindowPlanar (ScreenPtr pScreen,
625 CARD32 row,
626 CARD32 offset,
627 int mode,
628 CARD32 *size,
629 void *closure)
630{
631 KdScreenPriv(pScreen);
632
633 if (!pScreenPriv->enabled)
634 return 0;
635 return vesaSetWindowPlanar (pScreen, row, offset, mode, size);
636}
637
638void *
639vesaWindowLinear (ScreenPtr pScreen,
640 CARD32 row,
641 CARD32 offset,
642 int mode,
643 CARD32 *size,
644 void *closure)
645{
646 KdScreenPriv(pScreen);
647
648 if (!pScreenPriv->enabled)
649 return 0;
650 return vesaSetWindowLinear (pScreen, row, offset, mode, size);
651}
652
653void *
654vesaWindowWindowed (ScreenPtr pScreen,
655 CARD32 row,
656 CARD32 offset,
657 int mode,
658 CARD32 *size,
659 void *closure)
660{
661 KdScreenPriv(pScreen);
662
663 if (!pScreenPriv->enabled)
664 return 0;
665 return vesaSetWindowWindowed (pScreen, row, offset, mode, size);
666}
667
668#define vesaInvertBits32(v) { \
669 v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
670 v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
671 v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
672}
673
674void *
675vesaWindowCga (ScreenPtr pScreen,
676 CARD32 row,
677 CARD32 offset,
678 int mode,
679 CARD32 *size,
680 void *closure)
681{
682 KdScreenPriv(pScreen);
683 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
684 int line;
685
686 if (!pScreenPriv->enabled)
687 return 0;
688 *size = pscr->mode.BytesPerScanLine;
689 line = ((row & 1) << 13) + (row >> 1) * pscr->mode.BytesPerScanLine;
690 return (CARD8 *) pscr->fb + line + offset;
691}
692
693void
694vesaUpdateMono (ScreenPtr pScreen,
695 shadowBufPtr pBuf)
696{
697 RegionPtr damage = shadowDamage(pBuf);
698 PixmapPtr pShadow = pBuf->pPixmap;
699 int nbox = REGION_NUM_RECTS (damage);
700 BoxPtr pbox = REGION_RECTS (damage);
701 FbBits *shaBase, *shaLine, *sha;
702 FbStride shaStride;
703 int scrBase, scrLine, scr;
704 int shaBpp;
705 int shaXoff, shaYoff; /* XXX assumed to be zero */
706 int x, y, w, h, width;
707 int i;
708 FbBits *winBase = 0, *win;
709 CARD32 winSize;
710 FbBits bits;
711
712 fbGetDrawable (&pShadow->drawable, shaBase, shaStride, shaBpp, shaXoff, shaYoff);
713 while (nbox--)
714 {
715 x = pbox->x1 * shaBpp;
716 y = pbox->y1;
717 w = (pbox->x2 - pbox->x1) * shaBpp;
718 h = pbox->y2 - pbox->y1;
719
720 scrLine = (x >> FB_SHIFT);
721 shaLine = shaBase + y * shaStride + (x >> FB_SHIFT);
722
723 x &= FB_MASK;
724 w = (w + x + FB_MASK) >> FB_SHIFT;
725
726 while (h--)
727 {
728 winSize = 0;
729 scrBase = 0;
730 width = w;
731 scr = scrLine;
732 sha = shaLine;
733 while (width) {
734 /* how much remains in this window */
735 i = scrBase + winSize - scr;
736 if (i <= 0 || scr < scrBase)
737 {
738 winBase = (FbBits *) (*pBuf->window) (pScreen,
739 y,
740 scr * sizeof (FbBits),
741 SHADOW_WINDOW_WRITE,
742 &winSize,
743 pBuf->closure);
744 if(!winBase)
745 return;
746 scrBase = scr;
747 winSize /= sizeof (FbBits);
748 i = winSize;
749 }
750 win = winBase + (scr - scrBase);
751 if (i > width)
752 i = width;
753 width -= i;
754 scr += i;
755 while (i--)
756 {
757 bits = *sha++;
758 vesaInvertBits32(bits);
759 *win++ = bits;
760 }
761 }
762 shaLine += shaStride;
763 y++;
764 }
765 pbox++;
766 }
767}
768
769static const CARD16 vga16Colors[16][3] = {
770 { 0, 0, 0, }, /* 0 */
771 { 0, 0, 0xAA,}, /* 1 */
772 { 0, 0xAA,0, }, /* 2 */
773 { 0, 0xAA,0xAA,}, /* 3 */
774 { 0xAA,0, 0, }, /* 4 */
775 { 0xAA,0, 0xAA,}, /* 5 */
776 { 0xAA,0x55,0, }, /* 6 */
777 { 0xAA,0xAA,0xAA,}, /* 7 */
778 { 0x55,0x55,0x55,}, /* 8 */
779 { 0x55,0x55,0xFF,}, /* 9 */
780 { 0x55,0xFF,0x55,}, /* 10 */
781 { 0x55,0xFF,0xFF,}, /* 11 */
782 { 0xFF,0x55,0x55,}, /* 12 */
783 { 0xFF,0x55,0xFF,}, /* 13 */
784 { 0xFF,0xFF,0x55,}, /* 14 */
785 { 0xFF,0xFF,0xFF,}, /* 15 */
786};
787
788Bool
789vesaCreateColormap16 (ColormapPtr pmap)
790{
791 int i, j;
792
793 if (pmap->pVisual->ColormapEntries == 16)
794 for (i = 0; i < pmap->pVisual->ColormapEntries; i++)
795 {
796 j = i & 0xf;
797 pmap->red[i].co.local.red = (vga16Colors[j][0]<<8)|vga16Colors[j][0];
798 pmap->red[i].co.local.green = (vga16Colors[j][1]<<8)|vga16Colors[j][1];
799 pmap->red[i].co.local.blue = (vga16Colors[j][2]<<8)|vga16Colors[j][2];
800 }
801 return TRUE;
802}
803
804void
805vesaSetScreenSizes (ScreenPtr pScreen)
806{
807 KdScreenPriv(pScreen);
808 KdScreenInfo *screen = pScreenPriv->screen;
809 VesaScreenPrivPtr pscr = screen->driver;
810
811 if (pscr->randr & (RR_Rotate_0|RR_Rotate_180))
812 {
813 pScreen->width = pscr->mode.XResolution;
814 pScreen->height = pscr->mode.YResolution;
815 pScreen->mmWidth = screen->width_mm;
816 pScreen->mmHeight = screen->height_mm;
817 }
818 else
819 {
820 pScreen->width = pscr->mode.YResolution;
821 pScreen->height = pscr->mode.XResolution;
822 pScreen->mmWidth = screen->height_mm;
823 pScreen->mmHeight = screen->width_mm;
824 }
825}
826
827Bool
828vesaSetShadow (ScreenPtr pScreen)
829{
830 KdScreenPriv(pScreen);
831 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
832 ShadowUpdateProc update;
833 ShadowWindowProc window = 0;
834
835 if (pscr->randr != RR_Rotate_0)
836 update = shadowUpdateRotatePacked;
837 else
838 update = shadowUpdatePacked;
839 switch (pscr->mapping) {
840 case VESA_LINEAR:
841 window = vesaWindowLinear;
842 break;
843 case VESA_WINDOWED:
844 window = vesaWindowWindowed;
845 break;
846 case VESA_PLANAR:
847 if (pScreenPriv->screen->fb[0].bitsPerPixel == 8)
848 update = shadowUpdatePlanar4x8;
849 else
850 update = shadowUpdatePlanar4;
851 window = vesaWindowPlanar;
852 break;
853 case VESA_MONO:
854 update = vesaUpdateMono;
855 if (pscr->mode.mode < 8)
856 window = vesaWindowCga;
857 else
858 window = vesaWindowLinear;
859 break;
860 }
861
862 return KdShadowSet (pScreen, pscr->randr, update, window);
863}
864
865static Bool
866vesaComputeFramebufferMapping (KdScreenInfo *screen)
867{
868 VesaScreenPrivPtr pscr = screen->driver;
869 int depth, bpp, fbbpp;
870 Pixel allbits;
871 KdPointerMatrix m;
872
873 if (vesa_linear_fb)
874 {
875 pscr->mapping = VESA_LINEAR;
876 pscr->shadow = FALSE;
877 }
878 else
879 {
880 pscr->mapping = VESA_WINDOWED;
881 pscr->shadow = TRUE;
882 }
883
884 depth = vesaDepth (&pscr->mode);
885 bpp = pscr->mode.BitsPerPixel;
886
887 if (bpp > 24)
888 bpp = 32;
889 else if (bpp > 16)
890 bpp = 24;
891 else if (bpp > 8)
892 bpp = 16;
893 else if (bpp > 4)
894 bpp = 8;
895 else if (bpp > 1)
896 bpp = 4;
897 else
898 bpp = 1;
899 fbbpp = bpp;
900
901 switch (pscr->mode.MemoryModel) {
902 case MEMORY_DIRECT:
903 allbits = (screen->fb[0].redMask |
904 screen->fb[0].greenMask |
905 screen->fb[0].blueMask);
906 depth = 32;
907 while (depth && !(allbits & (1 << (depth - 1))))
908 depth--;
909 if (vesa_verbose)
910 ErrorF ("\tTrue Color %d/%d red 0x%x green 0x%x blue 0x%x\n",
911 bpp, depth,
912 screen->fb[0].redMask,
913 screen->fb[0].greenMask,
914 screen->fb[0].blueMask);
915 break;
916 case MEMORY_PSEUDO:
917 if (vesa_verbose)
918 ErrorF ("\tPseudo Color bpp %d depth %d\n",
919 bpp, depth);
920 break;
921 case MEMORY_PLANAR:
922 if (bpp == 4)
923 {
924 bpp = screen->fb[0].bitsPerPixel;
925 if (bpp != 8)
926 bpp = 4;
927 depth = bpp;
928 }
929 if (bpp == 1)
930 {
931 pscr->mapping = VESA_MONO;
932 if (vesa_verbose)
933 ErrorF ("\tMonochrome\n");
934 }
935 else
936 {
937 pscr->mapping = VESA_PLANAR;
938 if (vesa_verbose)
939 ErrorF ("\tStatic color bpp %d depth %d\n",
940 bpp, depth);
941 }
942 pscr->randr = RR_Rotate_0;
943 pscr->shadow = TRUE;
944 break;
945 default:
946 return FALSE;
947 }
948
949 switch (fbbpp) {
950 case 8:
951 case 16:
952 case 32:
953 break;
954 default:
955 pscr->randr = RR_Rotate_0;
956 break;
957 }
958
959 if (pscr->randr != RR_Rotate_0)
960 pscr->shadow = TRUE;
961
962 if (vesa_shadow)
963 pscr->shadow = vesa_shadow;
964
965 if (pscr->mapping == VESA_LINEAR && !(pscr->mode.ModeAttributes & MODE_LINEAR))
966 {
967 pscr->mapping = VESA_WINDOWED;
968 pscr->shadow = TRUE;
969 }
970 KdComputePointerMatrix (&m, pscr->randr,
971 pscr->mode.XResolution, pscr->mode.YResolution);
972
973 KdSetPointerMatrix (&m);
974
975 screen->width = pscr->mode.XResolution;
976 screen->height = pscr->mode.YResolution;
977 screen->fb[0].depth = depth;
978 screen->fb[0].bitsPerPixel = bpp;
979
980 return TRUE;
981}
982
983static Bool
984vesaMapFramebuffer (KdScreenInfo *screen)
985{
986 VesaCardPrivPtr priv = screen->card->driver;
987 VesaScreenPrivPtr pscr = screen->driver;
988
989 if (pscr->mapped)
990 return TRUE;
991 switch (pscr->mapping) {
992 case VESA_MONO:
993 case VESA_LINEAR:
994 if (pscr->mode.vbe)
995 pscr->fb = VbeMapFramebuffer(priv->vi, priv->vbeInfo,
996 pscr->mode.mode,
997 &pscr->fb_size,
998 &pscr->fb_phys);
999 else
1000 pscr->fb = VgaMapFramebuffer (priv->vi,
1001 pscr->mode.mode,
1002 &pscr->fb_size,
1003 &pscr->fb_phys);
1004 if (!pscr->fb)
1005 return FALSE;
1006 break;
1007 case VESA_WINDOWED:
1008 pscr->fb = NULL;
1009 break;
1010 case VESA_PLANAR:
1011 pscr->fb = NULL;
1012 break;
1013 }
1014
1015 screen->memory_base = pscr->fb;
1016 screen->memory_size = pscr->fb_size;
1017
1018 if (pscr->shadow)
1019 {
1020 if (!KdShadowFbAlloc (screen, 0,
1021 pscr->randr & (RR_Rotate_90|RR_Rotate_270)))
1022 return FALSE;
1023 screen->off_screen_base = screen->memory_size;
1024 }
1025 else
1026 {
1027 screen->fb[0].frameBuffer = (CARD8 *) (pscr->fb);
1028 screen->fb[0].byteStride = pscr->mode.BytesPerScanLine;
1029 screen->fb[0].pixelStride = ((pscr->mode.BytesPerScanLine * 8) /
1030 screen->fb[0].bitsPerPixel);
1031 screen->off_screen_base = screen->fb[0].byteStride * screen->height;
1032 }
1033 pscr->mapped = TRUE;
1034
1035 return TRUE;
1036}
1037
1038static void
1039vesaUnmapFramebuffer (KdScreenInfo *screen)
1040{
1041 VesaCardPrivPtr priv = screen->card->driver;
1042 VesaScreenPrivPtr pscr = screen->driver;
1043
1044 if (!pscr->mapped)
1045 return;
1046
1047 pscr->mapped = FALSE;
1048 KdShadowFbFree (screen, 0);
1049 if (pscr->fb)
1050 {
1051 if (pscr->mode.vbe)
1052 VbeUnmapFramebuffer(priv->vi, priv->vbeInfo, pscr->mode.mode, pscr->fb);
1053 else
1054 VgaUnmapFramebuffer (priv->vi);
1055 pscr->fb = 0;
1056 }
1057}
1058
1059#ifdef RANDR
1060Bool
1061vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
1062{
1063 KdScreenPriv(pScreen);
1064 VesaModePtr modes, mode;
1065 KdScreenInfo *screen = pScreenPriv->screen;
1066 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1067 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1068 int nmode;
1069 int n;
1070 RRScreenSizePtr pSize;
1071
1072 *rotations = (RR_Rotate_0|RR_Rotate_90|RR_Rotate_180|RR_Rotate_270|
1073 RR_Reflect_X|RR_Reflect_Y);
1074 /*
1075 * Get mode information from BIOS -- every time in case
1076 * something changes, like an external monitor is plugged in
1077 */
1078 modes = vesaGetModes (priv->vi, &nmode);
1079 if (!modes)
1080 return FALSE;
1081 if (priv->modes)
1082 xfree (priv->modes);
1083 priv->modes = modes;
1084 priv->nmode = nmode;
1085 for (n = 0; n < nmode; n++)
1086 {
1087 mode = &priv->modes[n];
1088 if (vesaModeSupported (priv, mode, FALSE))
1089 {
1090 /*
1091 * XXX limit reported modes to those matching the current
1092 * format
1093 */
1094 if (mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
1095 mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
1096 mode->MemoryModel == pscr->mode.MemoryModel &&
1097 mode->RedMaskSize == pscr->mode.RedMaskSize &&
1098 mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
1099 mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
1100 mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
1101 mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
1102 mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
1103 {
1104 int width, height, width_mm, height_mm;
1105 if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
1106 {
1107 width = mode->XResolution;
1108 height = mode->YResolution;
1109 width_mm = screen->width_mm;
1110 height_mm = screen->height_mm;
1111 }
1112 else
1113 {
1114 width = mode->YResolution;
1115 height = mode->XResolution;
1116 width_mm = screen->height_mm;
1117 height_mm = screen->width_mm;
1118 }
1119 pSize = RRRegisterSize (pScreen,
1120 width, height,
1121 width_mm, height_mm);
1122 if (mode->XResolution == screen->width &&
1123 mode->YResolution == screen->height)
1124 {
1125 int randr = KdSubRotation (pscr->randr, screen->randr);
1126 RRSetCurrentConfig (pScreen, randr, 0, pSize);
1127 }
1128 }
1129 }
1130 }
1131 return TRUE;
1132}
1133
1134Bool
1135vesaRandRSetConfig (ScreenPtr pScreen,
1136 Rotation randr,
1137 int rate,
1138 RRScreenSizePtr pSize)
1139{
1140 KdScreenPriv(pScreen);
1141 VesaModePtr mode = 0;
1142 KdScreenInfo *screen = pScreenPriv->screen;
1143 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1144 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1145 int n;
1146 Bool wasEnabled = pScreenPriv->enabled;
1147 Bool ret = FALSE;
1148 VesaScreenPrivRec oldscr;
1149 int oldwidth;
1150 int oldheight;
1151 int oldmmwidth;
1152 int oldmmheight;
1153 int newwidth, newheight;
1154
1155 if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
1156 {
1157 newwidth = pSize->width;
1158 newheight = pSize->height;
1159 }
1160 else
1161 {
1162 newwidth = pSize->height;
1163 newheight = pSize->width;
1164 }
1165 for (n = 0; n < priv->nmode; n++)
1166 {
1167 mode = &priv->modes[n];
1168 if (vesaModeSupported (priv, mode, FALSE))
1169 {
1170 /*
1171 * XXX all we have to match is the size
1172 */
1173 if (mode->XResolution == newwidth &&
1174 mode->YResolution == newheight &&
1175 mode->NumberOfPlanes == pscr->mode.NumberOfPlanes &&
1176 mode->BitsPerPixel == pscr->mode.BitsPerPixel &&
1177 mode->RedMaskSize == pscr->mode.RedMaskSize &&
1178 mode->RedFieldPosition == pscr->mode.RedFieldPosition &&
1179 mode->GreenMaskSize == pscr->mode.GreenMaskSize &&
1180 mode->GreenFieldPosition == pscr->mode.GreenFieldPosition &&
1181 mode->BlueMaskSize == pscr->mode.BlueMaskSize &&
1182 mode->BlueFieldPosition == pscr->mode.BlueFieldPosition)
1183 break;
1184 }
1185 }
1186 if (n == priv->nmode)
1187 goto bail0;
1188
1189 if (wasEnabled)
1190 KdDisableScreen (pScreen);
1191
1192 if (mode->mode != pscr->mode.mode)
1193 {
1194 ret = vesaSetMode (pScreen, mode);
1195 if (!ret)
1196 goto bail1;
1197 }
1198
1199 oldscr = *pscr;
1200
1201 oldwidth = screen->width;
1202 oldheight = screen->height;
1203 oldmmwidth = pScreen->mmWidth;
1204 oldmmheight = pScreen->mmHeight;
1205
1206 /*
1207 * Set new configuration
1208 */
1209
1210 pscr->mode = *mode;
1211 pscr->randr = KdAddRotation (screen->randr, randr);
1212
1213 /*
1214 * Can't rotate some formats
1215 */
1216 switch (screen->fb[0].bitsPerPixel) {
1217 case 8:
1218 case 16:
1219 case 32:
1220 break;
1221 default:
1222 if (pscr->randr)
1223 goto bail2;
1224 break;
1225 }
1226
1227 vesaUnmapFramebuffer (screen);
1228
1229 if (!vesaComputeFramebufferMapping (screen))
1230 goto bail3;
1231
1232 if (!vesaMapFramebuffer (screen))
1233 goto bail3;
1234
1235 vesaSetScreenSizes (screen->pScreen);
1236
1237 if (!vesaSetShadow (screen->pScreen))
1238 goto bail4;
1239
1240 /*
1241 * Set frame buffer mapping
1242 */
1243 (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
1244 pScreen->width,
1245 pScreen->height,
1246 screen->fb[0].depth,
1247 screen->fb[0].bitsPerPixel,
1248 screen->fb[0].byteStride,
1249 screen->fb[0].frameBuffer);
1250
1251 /* set the subpixel order */
1252 KdSetSubpixelOrder (pScreen, pscr->randr);
1253
1254 if (wasEnabled)
1255 KdEnableScreen (pScreen);
1256
1257 return TRUE;
1258
1259bail4:
1260 vesaUnmapFramebuffer (screen);
1261 *pscr = oldscr;
1262 (void) vesaComputeFramebufferMapping (screen);
1263 (void) vesaMapFramebuffer (screen);
1264
1265bail3:
1266 pScreen->width = oldwidth;
1267 pScreen->height = oldheight;
1268 pScreen->mmWidth = oldmmwidth;
1269 pScreen->mmHeight = oldmmheight;
1270
1271bail2:
1272 *pscr = oldscr;
1273
1274 (void) vesaSetMode (pScreen, &pscr->mode);
1275bail1:
1276 if (wasEnabled)
1277 KdEnableScreen (pScreen);
1278bail0:
1279
1280 return FALSE;
1281}
1282
1283Bool
1284vesaRandRInit (ScreenPtr pScreen)
1285{
1286 rrScrPrivPtr pScrPriv;
1287
1288 if (!RRScreenInit (pScreen))
1289 return FALSE;
1290
1291 pScrPriv = rrGetScrPriv(pScreen);
1292 pScrPriv->rrGetInfo = vesaRandRGetInfo;
1293 pScrPriv->rrSetConfig = vesaRandRSetConfig;
1294 return TRUE;
1295}
1296#endif
1297
1298Bool
1299vesaInitScreen(ScreenPtr pScreen)
1300{
1301 KdScreenPriv(pScreen);
1302 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1303 switch (pscr->mapping) {
1304 case VESA_PLANAR:
1305 pScreen->CreateColormap = vesaCreateColormap16;
1306 break;
1307 }
1308 return TRUE;
1309}
1310
1311Bool
1312vesaFinishInitScreen (ScreenPtr pScreen)
1313{
1314 if (!shadowSetup (pScreen))
1315 return FALSE;
1316
1317#ifdef RANDR
1318 if (!vesaRandRInit (pScreen))
1319 return FALSE;
1320#endif
1321
1322 return TRUE;
1323}
1324
1325Bool
1326vesaCreateResources (ScreenPtr pScreen)
1327{
1328 return vesaSetShadow (pScreen);
1329}
1330
1331Bool
1332vesaSetMode (ScreenPtr pScreen,
1333 VesaModePtr mode)
1334{
1335 KdScreenPriv(pScreen);
1336 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1337 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1338 int code;
1339
1340 if (mode->vbe)
1341 {
1342 if (vesa_verbose)
1343 ErrorF ("Enable VBE mode 0x%x\n", mode->mode);
1344 code = VbeSetMode(priv->vi, priv->vbeInfo, mode->mode,
1345 pscr->mapping == VESA_LINEAR,
1346 mode->MemoryModel == MEMORY_DIRECT);
1347 }
1348 else
1349 {
1350 if (vesa_verbose)
1351 ErrorF ("Enable BIOS mode 0x%x\n", mode->mode);
1352 code = VgaSetMode (priv->vi, mode->mode);
1353 }
1354
1355 if(code < 0)
1356 return FALSE;
1357
1358 return TRUE;
1359}
1360
1361Bool
1362vesaEnable(ScreenPtr pScreen)
1363{
1364 KdScreenPriv(pScreen);
1365 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1366 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1367 KdScreenInfo *screen = pScreenPriv->screen;
1368 int i;
1369 CARD32 size;
1370 char *p;
1371 Bool was_mapped = pscr->mapped;
1372
1373 if (!vesaMapFramebuffer (screen))
1374 return FALSE;
1375
1376 if (!vesaSetMode (pScreen, &pscr->mode))
1377 return FALSE;
1378
1379 switch (pscr->mapping) {
1380 case VESA_MONO:
1381 VgaSetWritePlaneMask (priv->vi, 0x1);
1382 case VESA_LINEAR:
1383 if (vesa_restore_font)
1384 memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
1385 break;
1386 case VESA_WINDOWED:
1387 if (vesa_restore_font)
1388 {
1389 for (i = 0; i < VESA_TEXT_SAVE;)
1390 {
1391 p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_READ, &size);
1392 if(!p) {
1393 ErrorF("Couldn't set window for saving VGA font\n");
1394 break;
1395 }
1396 if(i + size > VESA_TEXT_SAVE)
1397 size = VESA_TEXT_SAVE - i;
1398 memcpy(((char*)priv->text) + i, p, size);
1399 i += size;
1400 }
1401 }
1402 break;
1403 case VESA_PLANAR:
1404 if (vesa_restore_font)
1405 {
1406 for (i = 0; i < 4; i++)
1407 {
1408 p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_READ, &size);
1409 memcpy (((char *)priv->text) + i * (VESA_TEXT_SAVE/4), p,
1410 (VESA_TEXT_SAVE/4));
1411 }
1412 }
1413 break;
1414 }
1415 if (!was_mapped)
1416 {
1417 (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
1418 pScreen->width,
1419 pScreen->height,
1420 screen->fb[0].depth,
1421 screen->fb[0].bitsPerPixel,
1422 screen->fb[0].byteStride,
1423 screen->fb[0].frameBuffer);
1424 }
1425 return TRUE;
1426}
1427
1428#ifndef TOSHIBA_SMM
1429
1430# ifdef linux
1431# define TOSHIBA_SMM 1
1432# endif
1433
1434# ifndef TOSHIBA_SMM
1435# define TOSHIBA_SMM 0
1436# endif
1437
1438#endif
1439
1440#if TOSHIBA_SMM
1441/*
1442 * Toshiba laptops use a special interface to operate the backlight
1443 */
1444#include <sys/ioctl.h>
1445#define TOSH_PROC "/proc/toshiba"
1446#define TOSH_DEVICE "/dev/toshiba"
1447#define TOSH_SMM _IOWR('t', 0x90, SMMRegisters)
1448
1449typedef struct {
1450 unsigned int eax;
1451 unsigned int ebx __attribute__ ((packed));
1452 unsigned int ecx __attribute__ ((packed));
1453 unsigned int edx __attribute__ ((packed));
1454 unsigned int esi __attribute__ ((packed));
1455 unsigned int edi __attribute__ ((packed));
1456} SMMRegisters;
1457
1458#define HCI_BACKLIGHT 0x0002
1459#define HCI_DISABLE 0x0000
1460#define HCI_ENABLE 0x0001
1461#define HCI_GET 0xfe00,
1462#define HCI_SET 0xff00
1463
1464Bool
1465toshibaDPMS (ScreenPtr pScreen, int mode)
1466{
1467 SMMRegisters regs;
1468 static int fd;
1469
1470 if (!fd)
1471 fd = open (TOSH_DEVICE, 2);
1472 if (fd < 0)
1473 return FALSE;
1474 regs.eax = HCI_SET;
1475 regs.ebx = HCI_BACKLIGHT;
1476 regs.ecx = mode ? HCI_DISABLE : HCI_ENABLE;
1477 if (ioctl (fd, TOSH_SMM, &regs) < 0)
1478 return FALSE;
1479 return TRUE;
1480}
1481#endif /* TOSHIBA_SMM */
1482
1483Bool
1484vesaDPMS (ScreenPtr pScreen, int mode)
1485{
1486 KdScreenPriv(pScreen);
1487 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1488 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1489
1490#if TOSHIBA_SMM
1491 if (toshibaDPMS (pScreen, mode))
1492 return TRUE;
1493#endif
1494 if (pscr->mode.vbe)
1495 return VbeDPMS (priv->vi, mode);
1496 return FALSE;
1497}
1498
1499void
1500vesaDisable(ScreenPtr pScreen)
1501{
1502 KdScreenPriv(pScreen);
1503 KdScreenInfo *screen = pScreenPriv->screen;
1504 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1505 VesaScreenPrivPtr pscr = screen->driver;
1506 int i=0;
1507 CARD32 size;
1508 char *p;
1509
1510 if (vesa_restore_font) {
1511 switch (pscr->mapping) {
1512 case VESA_LINEAR:
1513 case VESA_MONO:
1514 memcpy(pscr->fb, priv->text, VESA_TEXT_SAVE);
1515 break;
1516 case VESA_WINDOWED:
1517 while(i < VESA_TEXT_SAVE) {
1518 p = vesaSetWindowWindowed (pScreen, 0, i, VBE_WINDOW_WRITE, &size);
1519 if(!p) {
1520 ErrorF("Couldn't set window for restoring VGA font\n");
1521 break;
1522 }
1523 if(i + size > VESA_TEXT_SAVE)
1524 size = VESA_TEXT_SAVE - i;
1525 memcpy(p, ((char*)priv->text) + i, size);
1526 i += size;
1527 }
1528 break;
1529 case VESA_PLANAR:
1530 for (i = 0; i < 4; i++)
1531 {
1532 p = vesaSetWindowPlanar (pScreen, 0, i, VBE_WINDOW_WRITE, &size);
1533 memcpy (p,
1534 ((char *)priv->text) + i * (VESA_TEXT_SAVE/4),
1535 (VESA_TEXT_SAVE/4));
1536 }
1537 break;
1538 }
1539 }
1540 vesaUnmapFramebuffer (screen);
1541}
1542
1543void
1544vesaPreserve(KdCardInfo *card)
1545{
1546 VesaCardPrivPtr priv = card->driver;
1547
1548 /* The framebuffer might not be valid at this point, so we cannot
1549 save the VGA fonts now; we do it in vesaEnable. */
1550
1551 if (VbeGetMode (priv->vi, &priv->old_vbe_mode) < 0)
1552 priv->old_vbe_mode = -1;
1553
1554 if (VgaGetMode (priv->vi, &priv->old_vga_mode) < 0)
1555 priv->old_vga_mode = -1;
1556
1557 if (vesa_verbose)
1558 ErrorF ("Previous modes: VBE 0x%x BIOS 0x%x\n",
1559 priv->old_vbe_mode, priv->old_vga_mode);
1560}
1561
1562void
1563vesaRestore(KdCardInfo *card)
1564{
1565 VesaCardPrivPtr priv = card->driver;
1566 int n;
1567
1568 if (vesa_force_text)
1569 {
1570 if (vesa_verbose)
1571 ErrorF ("Forcing switch back to mode 3 text\n");
1572 priv->old_vbe_mode = -1;
1573 priv->old_vga_mode = 3;
1574 }
1575 for (n = 0; n < priv->nmode; n++)
1576 if (priv->modes[n].vbe && priv->modes[n].mode == (priv->old_vbe_mode&0x3fff))
1577 break;
1578
1579 if (n < priv->nmode)
1580 {
1581 if (vesa_verbose)
1582 ErrorF ("Restore VBE mode 0x%x\n", priv->old_vbe_mode);
1583 VbeSetMode (priv->vi, priv->vbeInfo, priv->old_vbe_mode, 0, 0);
1584 }
1585 else
1586 {
1587 if (vesa_verbose)
1588 ErrorF ("Restore BIOS mode 0x%x\n", priv->old_vga_mode);
1589 VgaSetMode (priv->vi, priv->old_vga_mode);
1590 }
1591}
1592
1593void
1594vesaCardFini(KdCardInfo *card)
1595{
1596 VesaCardPrivPtr priv = card->driver;
1597
1598 if (priv->vbeInfo)
1599 VbeCleanup (priv->vi, priv->vbeInfo);
1600 if (priv->modes)
1601 xfree (priv->modes);
1602 Vm86Cleanup(priv->vi);
1603}
1604
1605void
1606vesaScreenFini(KdScreenInfo *screen)
1607{
1608 VesaScreenPrivPtr pscr = screen->driver;
1609
1610 KdShadowFbFree (screen, 0);
1611 vesaUnmapFramebuffer (screen);
1612 screen->fb[0].depth = pscr->origDepth;
1613}
1614
1615int
1616vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries)
1617{
1618 if (priv->vga_palette)
1619 return VgaSetPalette (priv->vi, first, number, entries);
1620 else
1621 return VbeSetPalette (priv->vi, priv->vbeInfo, first, number, entries);
1622}
1623
1624
1625int
1626vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries)
1627{
1628 int code;
1629
1630 if (priv->vga_palette)
1631 code = VgaGetPalette (priv->vi, first, number, entries);
1632 else
1633 {
1634 code = VbeGetPalette (priv->vi, priv->vbeInfo, first, number, entries);
1635 if (code < 0)
1636 {
1637 priv->vga_palette = 1;
1638 code = VgaGetPalette (priv->vi, first, number, entries);
1639 }
1640 }
1641 return code;
1642}
1643
1644void
1645vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
1646{
1647 KdScreenPriv(pScreen);
1648 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1649 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1650 int p;
1651 CARD8 *scratch;
1652 int red, green, blue;
1653 int min, max;
1654
1655 if (vesa_swap_rgb)
1656 {
1657 red = 2;
1658 green = 1;
1659 blue = 0;
1660 }
1661 else
1662 {
1663 red = 0;
1664 green = 1;
1665 blue = 2;
1666 }
1667
1668 min = 256;
1669 max = 0;
1670 while (n--)
1671 {
1672 p = pdefs->pixel;
1673 if (p < min)
1674 min = p;
1675 if (p > max)
1676 max = p;
1677 scratch = priv->cmap + (p * 4);
1678 scratch[red] = pdefs->red >> 8;
1679 scratch[green] = pdefs->green >> 8;
1680 scratch[blue] = pdefs->blue >> 8;
1681 scratch[3] = 0;
1682 pdefs++;
1683 if (pscr->mapping == VESA_PLANAR)
1684 {
1685 /*
1686 * VGA modes are strange; this code covers all
1687 * possible modes by duplicating the color information
1688 * however the attribute registers might be set
1689 */
1690 if (p < 16)
1691 {
1692 vesaSetPalette (priv, p, 1, scratch);
1693 if (p >= 8)
1694 vesaSetPalette (priv, p+0x30, 1, scratch);
1695 else if (p == 6)
1696 vesaSetPalette (priv, 0x14, 1, scratch);
1697 }
1698 }
1699 }
1700 if (pscr->mapping != VESA_PLANAR)
1701 vesaSetPalette (priv, min, max-min+1, priv->cmap + min * 4);
1702}
1703
1704void
1705vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
1706{
1707 KdScreenPriv(pScreen);
1708 VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
1709 VesaCardPrivPtr priv = pScreenPriv->card->driver;
1710 int i;
1711 int red, green, blue;
1712 int min, max;
1713 int p;
1714 CARD8 *scratch;
1715
1716 if (vesa_swap_rgb)
1717 {
1718 red = 2;
1719 green = 1;
1720 blue = 0;
1721 }
1722 else
1723 {
1724 red = 0;
1725 green = 1;
1726 blue = 2;
1727 }
1728
1729 min = 256;
1730 max = 0;
1731 for(i = 0; i < n; i++)
1732 {
1733 p = pdefs[i].pixel;
1734 if (p < min)
1735 min = p;
1736 if (p > max)
1737 max = p;
1738 if (pscr->mapping == VESA_PLANAR)
1739 vesaGetPalette (priv, p, 1, priv->cmap + p * 4);
1740 }
1741 if (pscr->mapping != VESA_PLANAR)
1742 vesaGetPalette (priv, min, max - min + 1, priv->cmap + min * 4);
1743 for (i = 0; i < n; i++)
1744 {
1745 p = pdefs[i].pixel;
1746 scratch = priv->cmap + p * 4;
1747 pdefs[i].red = scratch[red]<<8;
1748 pdefs[i].green = scratch[green]<<8;
1749 pdefs[i].blue = scratch[blue]<<8;
1750 }
1751}
1752
1753void
1754vesaUseMsg (void)
1755{
1756 ErrorF("\nTinyX VESA Usage:\n");
1757 ErrorF("-mode VESA video mode to use (Be careful!)\n");
1758 ErrorF("-listmodes List supported video modes\n");
1759 ErrorF("-force Attempt even unsupported modes\n");
1760 ErrorF("-shadow Always use shadow framebuffer (May increase performance)\n");
1761 ErrorF("-nolinear Never use linear framebuffer (Not useful)\n");
1762 ErrorF("-swaprgb Use if colors are wrong in PseudoColor and 16 color modes\n");
1763 ErrorF("-map-holes Use contiguous memory map (For seg fault with rare BIOS)\n");
1764 ErrorF("-verbose Emit diagnostic messages during BIOS initialization\n");
1765 ErrorF("-force-text Always use standard 25x80 text mode on server exit or VT switch\n");
1766 ErrorF("-boot Soft boot video card\n");
1767 /* XXX: usage for -vesatest, -no-map-holes (don't need?),
1768 * XXX: and -trash-font. Also in man page. */
1769}
1770
1771int
1772vesaProcessArgument (int argc, char **argv, int i)
1773{
1774 if(!strcmp(argv[i], "-mode")) {
1775 if(i+1 < argc) {
1776 vesa_video_mode = strtol(argv[i+1], NULL, 0);
1777 } else
1778 UseMsg();
1779 return 2;
1780 } else if(!strcmp(argv[i], "-force")) {
1781 vesa_force_mode = TRUE;
1782 return 1;
1783 } else if(!strcmp(argv[i], "-listmodes")) {
1784 vesaListModes();
1785 exit(0);
1786 } else if(!strcmp(argv[i], "-vesatest")) {
1787 vesaTestMode();
1788 exit (0);
1789 } else if(!strcmp(argv[i], "-swaprgb")) {
1790 vesa_swap_rgb = TRUE;
1791 return 1;
1792 } else if(!strcmp(argv[i], "-shadow")) {
1793 vesa_shadow = TRUE;
1794 return 1;
1795 } else if(!strcmp(argv[i], "-nolinear")) {
1796 vesa_linear_fb = FALSE;
1797 return 1;
1798 } else if(!strcmp(argv[i], "-verbose")) {
1799 vesa_verbose = TRUE;
1800 return 1;
1801 } else if(!strcmp(argv[i], "-force-text")) {
1802 vesa_force_text = TRUE;
1803 return 1;
1804 } else if(!strcmp(argv[i], "-map-holes")) {
1805 vesa_map_holes = TRUE;
1806 return 1;
1807 } else if(!strcmp(argv[i], "-no-map-holes")) {
1808 vesa_map_holes = FALSE;
1809 return 1;
1810 } else if(!strcmp(argv[i], "-trash-font")) {
1811 vesa_restore_font = FALSE;
1812 return 1;
1813 } else if(!strcmp(argv[i], "-boot")) {
1814 vesa_boot = TRUE;
1815 return 1;
1816 }
1817
1818 return 0;
1819}
diff --git a/hw/kdrive/vesa/vesa.h b/hw/kdrive/vesa/vesa.h
deleted file mode 100644
index f6b21e9f5..000000000
--- a/hw/kdrive/vesa/vesa.h
+++ /dev/null
@@ -1,295 +0,0 @@
1/*
2Copyright (c) 2000 by Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#ifndef _VESA_H_
24#define _VESA_H_
25
26#include "kdrive.h"
27#include "shadow.h"
28#include "vm86.h"
29#ifdef RANDR
30#include "randrstr.h"
31#endif
32
33#define VESA_TEXT_SAVE (64*1024)
34
35#define MODE_SUPPORTED 0x01
36#define MODE_COLOUR 0x08
37#define MODE_GRAPHICS 0x10
38#define MODE_VGA 0x20
39#define MODE_LINEAR 0x80
40
41#define MODE_DIRECT 0x1
42
43#define MEMORY_TEXT 0
44#define MEMORY_CGA 1
45#define MEMORY_HERCULES 2
46#define MEMORY_PLANAR 3
47#define MEMORY_PSEUDO 4
48#define MEMORY_NONCHAIN 5
49#define MEMORY_DIRECT 6
50#define MEMORY_YUV 7
51
52typedef struct _VesaMode {
53 int mode; /* mode number */
54 int vbe; /* a VBE mode */
55 int ModeAttributes; /* mode attributes */
56 int NumberOfPlanes; /* number of memory planes */
57 int BitsPerPixel; /* bits per pixel */
58 int MemoryModel; /* memory model type */
59 int RedMaskSize; /* size of direct color red mask in bits */
60 int RedFieldPosition; /* bit position of lsb of red mask */
61 int GreenMaskSize; /* size of direct color green mask in bits */
62 int GreenFieldPosition; /* bit position of lsb of green mask */
63 int BlueMaskSize; /* size of direct color blue mask in bits */
64 int BlueFieldPosition; /* bit position of lsb of blue mask */
65 int RsvdMaskSize; /* size of direct color reserved mask bits*/
66 int RsvdFieldPosition; /* bit position of lsb of reserved mask */
67 int DirectColorModeInfo; /* direct color mode attributes */
68 int XResolution; /* horizontal resolution */
69 int YResolution; /* vertical resolution */
70 int BytesPerScanLine; /* bytes per scan line */
71} VesaModeRec, *VesaModePtr;
72
73#include "vbe.h"
74#include "vga.h"
75
76typedef struct _VesaCardPriv {
77 int vbe;
78 VesaModePtr modes;
79 int nmode;
80 Vm86InfoPtr vi;
81 int vga_palette;
82 int old_vbe_mode;
83 int old_vga_mode;
84 VbeInfoPtr vbeInfo;
85 char text[VESA_TEXT_SAVE];
86 CARD8 cmap[256*4];
87} VesaCardPrivRec, *VesaCardPrivPtr;
88
89#define VESA_LINEAR 0
90#define VESA_WINDOWED 1
91#define VESA_PLANAR 2
92#define VESA_MONO 3
93
94typedef struct _VesaScreenPriv {
95 VesaModeRec mode;
96 Bool shadow;
97 Rotation randr;
98 int mapping;
99 int origDepth;
100 void *fb;
101 int fb_size;
102 CARD32 fb_phys;
103 PixmapPtr pShadow;
104 Bool mapped;
105} VesaScreenPrivRec, *VesaScreenPrivPtr;
106
107extern int vesa_video_mode;
108extern Bool vesa_force_mode;
109
110void
111vesaReportMode (VesaModePtr mode);
112
113VesaModePtr
114vesaGetModes (Vm86InfoPtr vi, int *ret_nmode);
115
116void
117vesaTestMode (void);
118
119void *
120vesaSetWindowPlanar(ScreenPtr pScreen,
121 CARD32 row,
122 CARD32 offset,
123 int mode,
124 CARD32 *size);
125
126void *
127vesaSetWindowLinear (ScreenPtr pScreen,
128 CARD32 row,
129 CARD32 offset,
130 int mode,
131 CARD32 *size);
132
133void *
134vesaSetWindowWindowed (ScreenPtr pScreen,
135 CARD32 row,
136 CARD32 offset,
137 int mode,
138 CARD32 *size);
139
140void *
141vesaWindowPlanar (ScreenPtr pScreen,
142 CARD32 row,
143 CARD32 offset,
144 int mode,
145 CARD32 *size,
146 void *closure);
147
148void *
149vesaWindowLinear (ScreenPtr pScreen,
150 CARD32 row,
151 CARD32 offset,
152 int mode,
153 CARD32 *size,
154 void *closure);
155
156void *
157vesaWindowWindowed (ScreenPtr pScreen,
158 CARD32 row,
159 CARD32 offset,
160 int mode,
161 CARD32 *size,
162 void *closure);
163
164void *
165vesaWindowCga (ScreenPtr pScreen,
166 CARD32 row,
167 CARD32 offset,
168 int mode,
169 CARD32 *size,
170 void *closure);
171
172void
173vesaUpdateMono (ScreenPtr pScreen,
174 shadowBufPtr pBuf);
175
176Bool
177vesaCreateColormap16 (ColormapPtr pmap);
178
179void
180vesaSetScreenSizes (ScreenPtr pScreen);
181
182Bool
183vesaSetShadow (ScreenPtr pScreen);
184
185
186void
187vesaListModes(void);
188
189Bool
190vesaInitialize(KdCardInfo *card, VesaCardPrivPtr priv);
191
192Bool
193vesaCardInit(KdCardInfo *card);
194
195int
196vesaDepth (VesaModePtr mode);
197
198Bool
199vesaModeGood (KdScreenInfo *screen,
200 VesaModePtr a);
201
202int
203vesaSizeError (KdScreenInfo *screen,
204 VesaModePtr a);
205
206Bool
207vesaModeBetter (KdScreenInfo *screen,
208 VesaModePtr a,
209 VesaModePtr b);
210
211VesaModePtr
212vesaSelectMode (KdScreenInfo *screen);
213
214Bool
215vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv);
216
217Bool
218vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr);
219
220Bool
221vesaScreenInit(KdScreenInfo *screen);
222
223PixmapPtr
224vesaGetPixmap (ScreenPtr pScreen);
225
226Bool
227vesaInitScreen(ScreenPtr pScreen);
228
229Bool
230vesaFinishInitScreen(ScreenPtr pScreen);
231
232Bool
233vesaCreateResources (ScreenPtr pScreen);
234
235Bool
236vesaSetMode (ScreenPtr pScreen,
237 VesaModePtr mode);
238
239Bool
240vesaEnable(ScreenPtr pScreen);
241
242Bool
243vesaDPMS (ScreenPtr pScreen, int mode);
244
245void
246vesaDisable(ScreenPtr pScreen);
247
248void
249vesaPreserve(KdCardInfo *card);
250
251void
252vesaRestore(KdCardInfo *card);
253
254void
255vesaCardFini(KdCardInfo *card);
256
257void
258vesaScreenFini(KdScreenInfo *screen);
259
260int
261vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries);
262
263int
264vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries);
265
266void
267vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
268
269void
270vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
271
272void
273vesaUseMsg (void);
274
275int
276vesaProcessArgument (int argc, char **argv, int i);
277
278#ifdef RANDR
279Bool
280vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations);
281
282Bool
283vesaRandRSetConfig (ScreenPtr pScreen,
284 Rotation randr,
285 int rate,
286 RRScreenSizePtr pSize);
287Bool
288vesaRandRInit (ScreenPtr pScreen);
289
290#endif
291
292Bool
293toshibaDPMS (ScreenPtr pScreen, int mode);
294
295#endif /* _VESA_H_ */
diff --git a/hw/kdrive/vesa/vesainit.c b/hw/kdrive/vesa/vesainit.c
deleted file mode 100644
index a5e216cfd..000000000
--- a/hw/kdrive/vesa/vesainit.c
+++ /dev/null
@@ -1,92 +0,0 @@
1/*
2Copyright (c) 2000 by Juliusz Chroboczek
3
4Permission is hereby granted, free of charge, to any person obtaining a copy
5of this software and associated documentation files (the "Software"), to deal
6in the Software without restriction, including without limitation the rights
7to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8copies of the Software, and to permit persons to whom the Software is
9furnished to do so, subject to the following conditions:
10
11The above copyright notice and this permission notice shall be included in
12all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20THE SOFTWARE.
21*/
22
23#ifdef HAVE_CONFIG_H
24#include <kdrive-config.h>
25#endif
26#include "vesa.h"
27
28const KdCardFuncs vesaFuncs = {
29 vesaCardInit, /* cardinit */
30 vesaScreenInit, /* scrinit */
31 vesaInitScreen, /* initScreen */
32 vesaFinishInitScreen, /* finishInitScreen */
33 vesaCreateResources, /* createRes */
34 vesaPreserve, /* preserve */
35 vesaEnable, /* enable */
36 vesaDPMS, /* dpms */
37 vesaDisable, /* disable */
38 vesaRestore, /* restore */
39 vesaScreenFini, /* scrfini */
40 vesaCardFini, /* cardfini */
41
42 0, /* initCursor */
43 0, /* enableCursor */
44 0, /* disableCursor */
45 0, /* finiCursor */
46 0, /* recolorCursor */
47
48 0, /* initAccel */
49 0, /* enableAccel */
50 0, /* disableAccel */
51 0, /* finiAccel */
52
53 vesaGetColors, /* getColors */
54 vesaPutColors, /* putColors */
55};
56
57void
58InitCard(char *name)
59{
60 KdCardAttr attr;
61 KdCardInfoAdd((KdCardFuncs *) &vesaFuncs, &attr, 0);
62}
63
64void
65InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
66{
67 KdInitOutput (pScreenInfo, argc, argv);
68}
69
70void
71InitInput (int argc, char **argv)
72{
73 KdOsAddInputDrivers();
74 KdInitInput();
75}
76
77void
78ddxUseMsg (void)
79{
80 KdUseMsg();
81 vesaUseMsg();
82}
83
84int
85ddxProcessArgument (int argc, char **argv, int i)
86{
87 int ret;
88
89 if (!(ret = vesaProcessArgument (argc, argv, i)))
90 ret = KdProcessArgument(argc, argv, i);
91 return ret;
92}
diff --git a/hw/kdrive/vesa/vga.c b/hw/kdrive/vesa/vga.c
deleted file mode 100644
index 0367a5f06..000000000
--- a/hw/kdrive/vesa/vga.c
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 * Copyright © 2000 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include <kdrive-config.h>
25#endif
26#include "vesa.h"
27
28static const VesaModeRec vgaModes[] = {
29 {
30 6, 0,
31 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
32 1, 1, MEMORY_PLANAR,
33 0, 0, 0, 0, 0, 0, 0, 0, 0,
34 640, 200, 80,
35 },
36 {
37 0xd, 0,
38 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
39 4, 4, MEMORY_PLANAR,
40 0, 0, 0, 0, 0, 0, 0, 0, 0,
41 320, 200, 40,
42 },
43 {
44 0xe, 0,
45 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
46 4, 4, MEMORY_PLANAR,
47 0, 0, 0, 0, 0, 0, 0, 0, 0,
48 640, 200, 80,
49 },
50 {
51 0x10, 0,
52 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
53 4, 4, MEMORY_PLANAR,
54 0, 0, 0, 0, 0, 0, 0, 0, 0,
55 640, 350, 80,
56 },
57 {
58 0x11, 0,
59 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
60 1, 1, MEMORY_PLANAR,
61 0, 0, 0, 0, 0, 0, 0, 0, 0,
62 640, 480, 80,
63 },
64 {
65 0x12, 0,
66 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
67 4, 4, MEMORY_PLANAR,
68 0, 0, 0, 0, 0, 0, 0, 0, 0,
69 640, 480, 80,
70 },
71 {
72 0x13, 0,
73 MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR | MODE_LINEAR,
74 8, 8, MEMORY_PSEUDO,
75 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 320, 200, 320,
77 },
78};
79
80#define NUM_VGA_MODE (sizeof vgaModes / sizeof vgaModes[0])
81
82int
83VgaGetNmode (Vm86InfoPtr vi)
84{
85 return NUM_VGA_MODE;
86}
87
88int
89VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode)
90{
91 if (nmode > NUM_VGA_MODE)
92 nmode = NUM_VGA_MODE;
93 memcpy (mode, vgaModes, nmode * sizeof (VesaModeRec));
94 return nmode;
95}
96
97int
98VgaSetMode(Vm86InfoPtr vi, int mode)
99{
100 int code;
101
102 vi->vms.regs.eax = mode & 0x7f;
103 code = Vm86DoInterrupt (vi, 0x10);
104 if(code < 0)
105 return -1;
106 return 0;
107}
108
109int
110VgaGetMode (Vm86InfoPtr vi, int *mode)
111{
112 *mode = Vm86Memory (vi, 0x449);
113 return 0;
114}
115
116void
117VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask)
118{
119 asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4));
120 asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5));
121}
122
123void
124VgaSetReadPlaneMap(Vm86InfoPtr vi, int map)
125{
126 asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce));
127 asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf));
128}
129
130int
131VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries)
132{
133 U8 *palette_scratch;
134 int mark;
135 int palette_base;
136 int i, j, code;
137
138 if(number == 0)
139 return 0;
140
141 if(first < 0 || number < 0 || first + number > 256) {
142 ErrorF("Cannot set %d, %d palette entries\n", first, number);
143 return -1;
144 }
145
146 mark = Vm86MarkMemory (vi);
147 palette_base = Vm86AllocateMemory (vi, 3 * 256);
148
149 palette_scratch = &LM(vi, palette_base);
150
151 vi->vms.regs.eax = 0x1012;
152 vi->vms.regs.ebx = first;
153 vi->vms.regs.ecx = number;
154 vi->vms.regs.es = POINTER_SEGMENT(palette_base);
155 vi->vms.regs.edx = POINTER_OFFSET(palette_base);
156 j = 0;
157 i = 0;
158 while (number--)
159 {
160 palette_scratch[j++] = entries[i++] >> 2;
161 palette_scratch[j++] = entries[i++] >> 2;
162 palette_scratch[j++] = entries[i++] >> 2;
163 i++;
164 }
165 code = Vm86DoInterrupt(vi, 0x10);
166 Vm86ReleaseMemory (vi, mark);
167
168 if(code < 0)
169 return -1;
170 return 0;
171}
172
173int
174VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries)
175{
176 U8 *palette_scratch;
177 int mark;
178 int palette_base;
179 int i, j, code;
180
181 if(number == 0)
182 return 0;
183
184 if(first < 0 || number < 0 || first + number > 256) {
185 ErrorF("Cannot get %d, %d palette entries\n", first, number);
186 return -1;
187 }
188
189 mark = Vm86MarkMemory (vi);
190 palette_base = Vm86AllocateMemory (vi, 3 * 256);
191
192 palette_scratch = &LM(vi, palette_base);
193
194 vi->vms.regs.eax = 0x1017;
195 vi->vms.regs.ebx = first;
196 vi->vms.regs.ecx = number;
197 vi->vms.regs.es = POINTER_SEGMENT(palette_base);
198 vi->vms.regs.edx = POINTER_OFFSET(palette_base);
199
200 code = VbeDoInterrupt10(vi);
201 if(code < 0)
202 return -1;
203
204 j = 0;
205 i = 0;
206 while (number--)
207 {
208 entries[i++] = palette_scratch[j++] << 2;
209 entries[i++] = palette_scratch[j++] << 2;
210 entries[i++] = palette_scratch[j++] << 2;
211 entries[i++] = 0;
212 }
213
214 Vm86ReleaseMemory (vi, mark);
215
216 return 0;
217}
218
219#define VGA_FB(vm) ((vm) < 8 ? 0xb8000 : 0xa0000)
220
221void *
222VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size)
223{
224 *size = 0x10000 - bytes;
225 return &LM(vi,VGA_FB(vmode) + bytes);
226}
227
228void *
229VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *ret_phys)
230{
231 if (VGA_FB(vmode) == 0xa0000)
232 *size = 0x10000;
233 else
234 *size = 0x4000;
235 *ret_phys = VGA_FB(vmode);
236 return &LM(vi,VGA_FB(vmode));
237}
238
239void
240VgaUnmapFramebuffer (Vm86InfoPtr vi)
241{
242}
diff --git a/hw/kdrive/vesa/vga.h b/hw/kdrive/vesa/vga.h
deleted file mode 100644
index 9a368cef7..000000000
--- a/hw/kdrive/vesa/vga.h
+++ /dev/null
@@ -1,59 +0,0 @@
1/*
2 * Copyright © 2000 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22
23#ifndef _VGA_H_
24#define _VGA_H_
25
26int
27VgaGetNmode (Vm86InfoPtr vi);
28
29int
30VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode);
31
32int
33VgaSetMode(Vm86InfoPtr vi, int mode);
34
35int
36VgaGetMode (Vm86InfoPtr vi, int *mode);
37
38void
39VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask);
40
41void
42VgaSetReadPlaneMap(Vm86InfoPtr vi, int map);
43
44int
45VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries);
46
47int
48VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries);
49
50void *
51VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size);
52
53void *
54VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *phys);
55
56void
57VgaUnmapFramebuffer (Vm86InfoPtr vi);
58
59#endif /* _VGA_H_ */
diff --git a/hw/kdrive/vesa/vm86.c b/hw/kdrive/vesa/vm86.c
deleted file mode 100644
index 0f7bb2262..000000000
--- a/hw/kdrive/vesa/vm86.c
+++ /dev/null
@@ -1,764 +0,0 @@
1/*
2 * Copyright © 2000 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22/*
23Copyright (c) 2000 by Juliusz Chroboczek
24
25Permission is hereby granted, free of charge, to any person obtaining a copy
26of this software and associated documentation files (the "Software"), to deal
27in the Software without restriction, including without limitation the rights
28to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29copies of the Software, and to permit persons to whom the Software is
30furnished to do so, subject to the following conditions:
31
32The above copyright notice and this permission notice shall be included in
33all copies or substantial portions of the Software.
34
35THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41THE SOFTWARE.
42*/
43
44#ifdef HAVE_CONFIG_H
45#include <kdrive-config.h>
46#endif
47#include "vm86.h"
48
49#define PUSHW(vi, i) \
50{ vi->vms.regs.esp -= 2;\
51 LMW(vi,MAKE_POINTER(vi->vms.regs.ss, vi->vms.regs.esp)) = i;}
52
53static int vm86old(struct vm86_struct *vms);
54static int vm86_loop(Vm86InfoPtr vi);
55
56static const U8 rev_ints[32] =
57{ 0, 0, 0, 0, 0, 0, 0, 0,
58 0, 0, 0, 0, 0, 0, 0, 0,
59 0, 0, 0, 0, 0, 0, 0, 0,
60 0, 0, 0, 0, 0, 0, 0, 0x80,
61};
62
63static const U8 retcode_data[2] =
64{ 0xCD, 0xFF };
65
66Vm86InfoPtr
67Vm86Setup(int mapHoles)
68{
69 int devmem = -1, devzero = -1;
70 void *magicMem, *loMem, *hiMem;
71 void *hole1, *hole2;
72 U32 stack_base, ret_code;
73 Vm86InfoPtr vi = NULL;
74
75 devmem = open("/dev/mem", O_RDWR);
76 if(devmem < 0) {
77 perror("open /dev/mem");
78 goto fail;
79 }
80
81 devzero = open("/dev/zero", O_RDWR);
82 if(devzero < 0) {
83 perror("open /dev/zero");
84 goto fail;
85 }
86
87 magicMem = MAP_FAILED;
88 loMem = MAP_FAILED;
89 hiMem = MAP_FAILED;
90 hole1 = MAP_FAILED;
91 hole2 = MAP_FAILED;
92
93
94 magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE,
95 PROT_READ | PROT_WRITE | PROT_EXEC,
96 MAP_PRIVATE | MAP_FIXED, devmem, MAGICMEM_BASE);
97
98 if(magicMem == MAP_FAILED) {
99 ErrorF("Couldn't map magic memory\n");
100 goto unmapfail;
101 }
102
103 if(mapHoles) {
104 hole1 = mmap((void*)HOLE1_BASE, HOLE1_SIZE,
105 PROT_READ | PROT_WRITE | PROT_EXEC,
106 MAP_PRIVATE | MAP_FIXED, devzero, HOLE1_BASE);
107
108 if(hole1 == MAP_FAILED) {
109 ErrorF("Couldn't map first hole\n");
110 goto unmapfail;
111 }
112 }
113
114 loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE,
115 PROT_READ | PROT_WRITE | PROT_EXEC,
116 MAP_PRIVATE | MAP_FIXED, devzero, LOMEM_BASE);
117 if(loMem == MAP_FAILED) {
118 ErrorF("Couldn't map low memory\n");
119 munmap(magicMem, MAGICMEM_SIZE);
120 goto unmapfail;
121 }
122
123 if(mapHoles) {
124 hole2 = mmap((void*)HOLE2_BASE, HOLE2_SIZE,
125 PROT_READ | PROT_WRITE | PROT_EXEC,
126 MAP_PRIVATE | MAP_FIXED, devzero, HOLE2_BASE);
127
128 if(hole2 == MAP_FAILED) {
129 ErrorF("Couldn't map first hole\n");
130 goto unmapfail;
131 }
132 }
133
134 hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE,
135 PROT_READ | PROT_WRITE | PROT_EXEC,
136 MAP_SHARED | MAP_FIXED,
137 devmem, HIMEM_BASE);
138 if(hiMem == MAP_FAILED) {
139 ErrorF("Couldn't map high memory\n");
140 goto unmapfail;
141 }
142
143 vi = xalloc(sizeof(Vm86InfoRec));
144 if (!vi)
145 goto unmapfail;
146
147 vi->magicMem = magicMem;
148 vi->hole1 = hole1;
149 vi->loMem = loMem;
150 vi->hole2 = hole2;
151 vi->hiMem = hiMem;
152 vi->brk = LOMEM_BASE;
153
154 stack_base = Vm86AllocateMemory(vi, STACK_SIZE);
155 if(stack_base == ALLOC_FAIL)
156 goto unmapfail;
157 ret_code = Vm86AllocateMemory(vi, sizeof(retcode_data));
158 if(ret_code == ALLOC_FAIL)
159 goto unmapfail;
160
161 vi->stack_base = stack_base;
162 vi->ret_code = ret_code;
163
164 memset(&vi->vms, 0, sizeof(struct vm86_struct));
165 vi->vms.flags = 0;
166 vi->vms.screen_bitmap = 0;
167 vi->vms.cpu_type = CPU_586;
168 memcpy(&vi->vms.int_revectored, rev_ints, sizeof(rev_ints));
169
170 iopl(3);
171
172 if(devmem >= 0)
173 close(devmem);
174 if(devzero >= 0)
175 close(devzero);
176
177 return vi;
178
179unmapfail:
180 if(magicMem != MAP_FAILED) munmap(magicMem, MAGICMEM_SIZE);
181 if(hole1 != MAP_FAILED) munmap(hole1, HOLE1_SIZE);
182 if(loMem != MAP_FAILED) munmap(loMem, LOMEM_SIZE);
183 if(hole2 != MAP_FAILED) munmap(hole2, HOLE2_SIZE);
184 if(hiMem != MAP_FAILED) munmap(hiMem, HIMEM_SIZE);
185fail:
186 if(devmem >= 0)
187 close(devmem);
188 if(devzero >= 0)
189 close(devzero);
190 if(vi)
191 xfree(vi);
192 return NULL;
193}
194
195void
196Vm86Cleanup(Vm86InfoPtr vi)
197{
198 if(vi->magicMem != MAP_FAILED) munmap(vi->magicMem, MAGICMEM_SIZE);
199 if(vi->hole1 != MAP_FAILED) munmap(vi->hole1, HOLE1_SIZE);
200 if(vi->loMem != MAP_FAILED) munmap(vi->loMem, LOMEM_SIZE);
201 if(vi->hole2 != MAP_FAILED) munmap(vi->hole2, HOLE2_SIZE);
202 if(vi->hiMem != MAP_FAILED) munmap(vi->hiMem, HIMEM_SIZE);
203 xfree(vi);
204}
205
206int
207Vm86DoInterrupt(Vm86InfoPtr vi, int num)
208{
209 U16 seg, off;
210 int code;
211
212 if(num < 0 || num>256) {
213 ErrorF("Interrupt %d doesn't exist\n");
214 return -1;
215 }
216 seg = MMW(vi,num * 4 + 2);
217 off = MMW(vi,num * 4);
218 if(MAKE_POINTER(seg, off) < ROM_BASE ||
219 MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) {
220 ErrorF("Interrupt pointer (seg %x off %x) doesn't point at ROM\n",
221 seg, off);
222 return -1;
223 }
224 memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data));
225 vi->vms.regs.eflags = IF_MASK | IOPL_MASK;
226 vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base);
227 vi->vms.regs.esp = STACK_SIZE;
228 PUSHW(vi, IF_MASK | IOPL_MASK);
229 PUSHW(vi, POINTER_SEGMENT(vi->ret_code));
230 PUSHW(vi, POINTER_OFFSET(vi->ret_code));
231 vi->vms.regs.cs = seg;
232 vi->vms.regs.eip = off;
233 OsBlockSignals ();
234 code = vm86_loop(vi);
235 OsReleaseSignals ();
236 if(code != 0)
237 return -1;
238 else
239 return 0;
240}
241
242int
243Vm86DoPOST(Vm86InfoPtr vi)
244{
245 U16 seg, off;
246 int code;
247
248 seg = 0xC000;
249 off = 3;
250 if(MAKE_POINTER(seg, off) < ROM_BASE ||
251 MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) {
252 ErrorF("BIOS pointer (seg %x off %x) doesn't point at ROM\n",
253 seg, off);
254 return -1;
255 }
256 memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data));
257 vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base);
258 vi->vms.regs.esp = STACK_SIZE;
259 PUSHW(vi, POINTER_SEGMENT(vi->ret_code));
260 PUSHW(vi, POINTER_OFFSET(vi->ret_code));
261 vi->vms.regs.cs = seg;
262 vi->vms.regs.eip = off;
263 OsBlockSignals ();
264 code = vm86_loop(vi);
265 OsReleaseSignals ();
266 if(code != 0)
267 return -1;
268 else
269 return 0;
270}
271
272#define DEBUG_VBE 0
273#if DEBUG_VBE
274#define DBG(x) ErrorF x; usleep(10*1000)
275#else
276#define DBG(x)
277#endif
278
279static inline U8
280vm86_inb(U16 port)
281{
282 U8 value;
283
284 if (port != 0x3da)
285 {
286 DBG(("inb 0x%04x", port));
287 }
288 asm volatile ("inb %w1,%b0" : "=a" (value) : "d" (port));
289 if (port != 0x3da)
290 {
291 DBG((" = 0x%02x\n", value));
292 }
293 return value;
294}
295
296static inline U16
297vm86_inw(U16 port)
298{
299 U16 value;
300 DBG(("inw 0x%04x", port));
301 asm volatile ("inw %w1,%w0" : "=a" (value) : "d" (port));
302 DBG((" = 0x%04x\n", value));
303 return value;
304}
305
306static inline U32
307vm86_inl(U16 port)
308{
309 U32 value;
310 DBG(("inl 0x%04x", port));
311 asm volatile ("inl %w1,%0" : "=a" (value) : "d" (port));
312 DBG((" = 0x%08x\n", value));
313 return value;
314}
315
316static inline void
317vm86_outb(U16 port, U8 value)
318{
319#if 0
320 static U8 CR;
321
322 if (port == 0x3d4)
323 CR = value;
324 if (port == 0x3d5 && CR == 0xa4)
325 {
326 DBG(("outb 0x%04x = 0x%02x (skipped)\n", port, value));
327 return;
328 }
329#endif
330 DBG(("outb 0x%04x = 0x%02x\n", port, value));
331 asm volatile ("outb %b0,%w1" : : "a" (value), "d" (port));
332}
333
334static inline void
335vm86_outw(U16 port, U16 value)
336{
337 DBG(("outw 0x%04x = 0x%04x\n", port, value));
338 asm volatile ("outw %w0,%w1" : : "a" (value), "d" (port));
339}
340
341static inline void
342vm86_outl(U16 port, U32 value)
343{
344 DBG(("outl 0x%04x = 0x%08x\n", port, value));
345 asm volatile ("outl %0,%w1" : : "a" (value), "d" (port));
346}
347
348#define SEG_CS 1
349#define SEG_DS 2
350#define SEG_ES 3
351#define SEG_SS 4
352#define SEG_GS 5
353#define SEG_FS 6
354#define REP 1
355#define REPNZ 2
356#define SET_8(_x, _y) (_x) = ((_x) & ~0xFF) | ((_y) & 0xFF);
357#define SET_16(_x, _y) (_x) = ((_x) & ~0xFFFF) | ((_y) & 0xFFFF);
358#define INC_IP(_i) SET_16(regs->eip, (regs->eip + _i))
359#define AGAIN INC_IP(1); goto again;
360
361static int
362vm86_emulate(Vm86InfoPtr vi)
363{
364 struct vm86_regs *regs = &vi->vms.regs;
365 U8 opcode;
366 int size;
367 int pref_seg = 0, pref_rep = 0, pref_66 = 0, pref_67 = 0;
368
369 again:
370 if(!Vm86IsMemory(vi, MAKE_POINTER(regs->cs, regs->eip))) {
371 ErrorF("Trying to execute unmapped memory\n");
372 return -1;
373 }
374 opcode = Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip));
375 switch(opcode) {
376 case 0x2E: pref_seg = SEG_CS; AGAIN;
377 case 0x3E: pref_seg = SEG_DS; AGAIN;
378 case 0x26: pref_seg = SEG_ES; AGAIN;
379 case 0x36: pref_seg = SEG_SS; AGAIN;
380 case 0x65: pref_seg = SEG_GS; AGAIN;
381 case 0x64: pref_seg = SEG_FS; AGAIN;
382 case 0x66: pref_66 = 1; AGAIN;
383 case 0x67: pref_67 = 1; AGAIN;
384 case 0xF2: pref_rep = REPNZ; AGAIN;
385 case 0xF3: pref_rep = REP; AGAIN;
386
387 case 0xEC: /* IN AL, DX */
388 SET_8(regs->eax, vm86_inb(regs->edx & 0xFFFF));
389 INC_IP(1);
390 break;
391 case 0xED: /* IN AX, DX */
392 if(pref_66)
393 regs->eax = vm86_inl(regs->edx & 0xFFFF);
394 else
395 SET_16(regs->eax, vm86_inw(regs->edx & 0xFFFF));
396 INC_IP(1);
397 break;
398 case 0xE4: /* IN AL, imm8 */
399 SET_8(regs->eax,
400 vm86_inb(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1))));
401 INC_IP(2);
402 break;
403 case 0xE5: /* IN AX, imm8 */
404 if(pref_66)
405 regs->eax =
406 vm86_inl(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)));
407 else
408 SET_16(regs->eax,
409 vm86_inw(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1))));
410 INC_IP(2);
411 break;
412 case 0x6C: /* INSB */
413 case 0x6D: /* INSW */
414 if(opcode == 0x6C) {
415 Vm86WriteMemory(vi, MAKE_POINTER(regs->es, regs->edi),
416 vm86_inb(regs->edx & 0xFFFF));
417 size = 1;
418 } else if(pref_66) {
419 Vm86WriteMemoryL(vi, MAKE_POINTER(regs->es, regs->edi),
420 vm86_inl(regs->edx & 0xFFFF));
421 size = 4;
422 } else {
423 Vm86WriteMemoryW(vi, MAKE_POINTER(regs->es, regs->edi),
424 vm86_inw(regs->edx & 0xFFFF));
425 size = 2;
426 }
427 if(regs->eflags & (1<<10))
428 regs->edi -= size;
429 else
430 regs->edi += size;
431 if(pref_rep) {
432 if(pref_66) {
433 regs->ecx--;
434 if(regs->ecx != 0)
435 goto again;
436 } else {
437 SET_16(regs->ecx, regs->ecx - 1);
438 if((regs->ecx & 0xFFFF) != 0)
439 goto again;
440 }
441 }
442 INC_IP(1);
443 break;
444
445 case 0xEE: /* OUT DX, AL */
446 vm86_outb(regs->edx & 0xFFFF, regs->eax & 0xFF);
447 INC_IP(1);
448 break;
449 case 0xEF: /* OUT DX, AX */
450 if(pref_66)
451 vm86_outl(regs->edx & 0xFFFF, regs->eax);
452 else
453 vm86_outw(regs->edx & 0xFFFF, regs->eax & 0xFFFF);
454 INC_IP(1);
455 break;
456 case 0xE6: /* OUT imm8, AL */
457 vm86_outb(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)),
458 regs->eax & 0xFF);
459 INC_IP(2);
460 break;
461 case 0xE7: /* OUT imm8, AX */
462 if(pref_66)
463 vm86_outl(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)),
464 regs->eax);
465 else
466 vm86_outw(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)),
467 regs->eax & 0xFFFF);
468 INC_IP(2);
469 break;
470 case 0x6E: /* OUTSB */
471 case 0x6F: /* OUTSW */
472 if(opcode == 0x6E) {
473 vm86_outb(regs->edx & 0xFFFF,
474 Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi)));
475 size = 1;
476 } else if(pref_66) {
477 vm86_outl(regs->edx & 0xFFFF,
478 Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi)));
479 size = 4;
480 } else {
481 vm86_outw(regs->edx & 0xFFFF,
482 Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi)));
483 size = 2;
484 }
485 if(regs->eflags & (1<<10))
486 regs->edi -= size;
487 else
488 regs->edi += size;
489 if(pref_rep) {
490 if(pref_66) {
491 regs->ecx--;
492 if(regs->ecx != 0)
493 goto again;
494 } else {
495 SET_16(regs->ecx, regs->ecx - 1);
496 if((regs->ecx & 0xFFFF) != 0)
497 goto again;
498 }
499 }
500 INC_IP(1);
501 break;
502
503 case 0x0F:
504 ErrorF("Hit 0F trap in VM86 code\n");
505 return -1;
506 case 0xF0:
507 ErrorF("Hit lock prefix in VM86 code\n");
508 return -1;
509 case 0xF4:
510 ErrorF("Hit HLT in VM86 code\n");
511 return -1;
512
513 default:
514 ErrorF("Unhandled GP fault in VM86 code (opcode = 0x%02X)\n",
515 opcode);
516 return -1;
517 }
518 return 0;
519}
520#undef SEG_CS
521#undef SEG_DS
522#undef SEG_ES
523#undef SEG_SS
524#undef SEG_GS
525#undef SEG_FS
526#undef REP
527#undef REPNZ
528#undef SET_8
529#undef SET_16
530#undef INC_IP
531#undef AGAIN
532
533static int
534vm86_loop(Vm86InfoPtr vi)
535{
536 int code;
537
538 while(1) {
539 code = vm86old(&vi->vms);
540 switch(VM86_TYPE(code)) {
541 case VM86_SIGNAL:
542 continue;
543 case VM86_UNKNOWN:
544 code = vm86_emulate(vi);
545 if(code < 0) {
546 Vm86Debug(vi);
547 return -1;
548 }
549 break;
550 case VM86_INTx:
551 if(VM86_ARG(code) == 0xFF)
552 return 0;
553 else {
554 PUSHW(vi, vi->vms.regs.eflags)
555 PUSHW(vi, vi->vms.regs.cs);
556 PUSHW(vi, vi->vms.regs.eip);
557 vi->vms.regs.cs = MMW(vi,VM86_ARG(code) * 4 + 2);
558 vi->vms.regs.eip = MMW(vi,VM86_ARG(code) * 4);
559 }
560 break;
561 case VM86_STI:
562 ErrorF("VM86 code enabled interrupts\n");
563 Vm86Debug(vi);
564 return -1;
565 default:
566 if(code < 0) {
567 if(errno == ENOSYS) {
568 ErrorF("No vm86 support. Are you running on AMD64?\n");
569 } else {
570 ErrorF("vm86 failed (%s).\n", strerror(errno));
571 Vm86Debug(vi);
572 }
573 } else {
574 ErrorF("Unexpected result code 0x%X from vm86\n", code);
575 Vm86Debug(vi);
576 }
577 return -1;
578 }
579 }
580}
581
582int
583Vm86IsMemory(Vm86InfoPtr vi, U32 i)
584{
585 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
586 return 1;
587 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
588 return 1;
589 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
590 return 1;
591 else
592 return 0;
593}
594
595U8
596Vm86Memory(Vm86InfoPtr vi, U32 i)
597{
598 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
599 return MM(vi, i);
600 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
601 return LM(vi, i);
602 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
603 return HM(vi, i);
604 else {
605 ErrorF("Reading unmapped memory at 0x%08X\n", i);
606 return 0;
607 }
608}
609
610U16
611Vm86MemoryW(Vm86InfoPtr vi, U32 i)
612{
613 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
614 return MMW(vi, i);
615 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
616 return LMW(vi, i);
617 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
618 return HMW(vi, i);
619 else {
620 ErrorF("Reading unmapped memory at 0x%08X\n", i);
621 return 0;
622 }
623}
624
625U32
626Vm86MemoryL(Vm86InfoPtr vi, U32 i)
627{
628 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
629 return MML(vi, i);
630 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
631 return LML(vi, i);
632 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
633 return HML(vi, i);
634 else {
635 ErrorF("Reading unmapped memory at 0x%08X\n", i);
636 return 0;
637 }
638}
639
640void
641Vm86WriteMemory(Vm86InfoPtr vi, U32 i, U8 val)
642{
643 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
644 MM(vi, i) = val;
645 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
646 LM(vi, i) = val;
647 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
648 HM(vi, i) = val;
649 else {
650 ErrorF("Writing unmapped memory at 0x%08X\n", i);
651 }
652}
653
654void
655Vm86WriteMemoryW(Vm86InfoPtr vi, U32 i, U16 val)
656{
657 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
658 MMW(vi, i) = val;
659 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
660 LMW(vi, i) = val;
661 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
662 HMW(vi, i) = val;
663 else {
664 ErrorF("Writing unmapped memory at 0x%08X\n", i);
665 }
666}
667
668void
669Vm86WriteMemoryL(Vm86InfoPtr vi, U32 i, U32 val)
670{
671 if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
672 MML(vi, i) = val;
673 else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
674 LML(vi, i) = val;
675 else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
676 HML(vi, i) = val;
677 else {
678 ErrorF("Writing unmapped memory at 0x%08X\n", i);
679 }
680}
681
682int
683Vm86AllocateMemory(Vm86InfoPtr vi, int n)
684{
685 int ret;
686 if(n<0) {
687 ErrorF("Asked to allocate negative amount of memory\n");
688 return vi->brk;
689 }
690
691 n = (n + 15) & ~15;
692 if(vi->brk + n > LOMEM_BASE + LOMEM_SIZE) {
693 ErrorF("Out of low memory\n");
694 exit(2);
695 }
696 ret = vi->brk;
697 vi->brk += n;
698 return ret;
699}
700
701int
702Vm86MarkMemory (Vm86InfoPtr vi)
703{
704 return vi->brk;
705}
706
707void
708Vm86ReleaseMemory (Vm86InfoPtr vi, int mark)
709{
710 vi->brk = mark;
711}
712
713static int
714vm86old(struct vm86_struct *vm)
715{
716 int res;
717
718 asm volatile (
719 "pushl %%ebx\n\t"
720 "movl %2, %%ebx\n\t"
721 "movl %1,%%eax\n\t"
722 "int $0x80\n\t"
723 "popl %%ebx"
724 : "=a" (res) : "n" (113), "r" (vm));
725 if(res < 0) {
726 errno = -res;
727 res = -1;
728 } else
729 errno = 0;
730 return res;
731}
732
733void
734Vm86Debug(Vm86InfoPtr vi)
735{
736 struct vm86_regs *regs = &vi->vms.regs;
737 int i;
738
739 ErrorF("eax=0x%08lX ebx=0x%08lX ecx=0x%08lX edx=0x%08lX\n",
740 regs->eax, regs->ebx, regs->ecx, regs->edx);
741 ErrorF("esi=0x%08lX edi=0x%08lX ebp=0x%08lX\n",
742 regs->esi, regs->edi, regs->ebp);
743 ErrorF("eip=0x%08lX esp=0x%08lX eflags=0x%08lX\n",
744 regs->eip, regs->esp, regs->eflags);
745 ErrorF("cs=0x%04lX ds=0x%04lX es=0x%04lX fs=0x%04lX gs=0x%04lX\n",
746 regs->cs, regs->ds, regs->es, regs->fs, regs->gs);
747 for(i=-7; i<8; i++) {
748 ErrorF(" %s%02X",
749 i==0?"->":"",
750 Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip + i)));
751 }
752 ErrorF("\n");
753}
754
755#ifdef NOT_IN_X_SERVER
756static void
757ErrorF(char *f, ...)
758{
759 va_list args;
760 va_start(args, f);
761 vfprintf(stderr, f, args);
762 va_end(args);
763}
764#endif
diff --git a/hw/kdrive/vesa/vm86.h b/hw/kdrive/vesa/vm86.h
deleted file mode 100644
index 3b4881471..000000000
--- a/hw/kdrive/vesa/vm86.h
+++ /dev/null
@@ -1,173 +0,0 @@
1/*
2 * Copyright © 2000 Keith Packard
3 *
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of Keith Packard not be used in
9 * advertising or publicity pertaining to distribution of the software without
10 * specific, written prior permission. Keith Packard makes no
11 * representations about the suitability of this software for any purpose. It
12 * is provided "as is" without express or implied warranty.
13 *
14 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
15 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
16 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
17 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
18 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
19 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
20 * PERFORMANCE OF THIS SOFTWARE.
21 */
22/*
23Copyright (c) 2000 by Juliusz Chroboczek
24
25Permission is hereby granted, free of charge, to any person obtaining a copy
26of this software and associated documentation files (the "Software"), to deal
27in the Software without restriction, including without limitation the rights
28to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
29copies of the Software, and to permit persons to whom the Software is
30furnished to do so, subject to the following conditions:
31
32The above copyright notice and this permission notice shall be included in
33all copies or substantial portions of the Software.
34
35THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
36IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
37FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
38AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
39LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
40OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
41THE SOFTWARE.
42*/
43
44#ifndef _VM86_H_
45#define _VM86_H_
46
47#include <stdlib.h>
48#include <errno.h>
49#include <unistd.h>
50#include <fcntl.h>
51#include <sys/mman.h>
52#include <sys/vm86.h>
53#include <sys/io.h>
54
55#ifdef NOT_IN_X_SERVER
56#include <stdio.h>
57#include <stdarg.h>
58#include <malloc.h>
59static void ErrorF(char*, ...);
60#define xalloc(a) malloc(a)
61#define xcalloc(a,b) calloc(a,b)
62#define xfree(a) free(a)
63#else
64#include <X11/X.h>
65#include <X11/Xproto.h>
66#include <X11/Xos.h>
67#include "os.h"
68#endif
69
70typedef unsigned char U8;
71typedef unsigned short U16;
72typedef unsigned int U32;
73
74/* The whole addressable memory */
75#define SYSMEM_BASE 0x00000
76#define SYSMEM_SIZE 0x100000
77
78/* Interrupt vectors and BIOS data area */
79/* This is allocated privately from /dev/mem */
80#define MAGICMEM_BASE 0x00000
81#define MAGICMEM_SIZE 0x01000
82
83/* The low memory, allocated privately from /dev/zero */
84/* 64KB should be enough for anyone, as they used to say */
85#define LOMEM_BASE 0x10000
86#define LOMEM_SIZE 0x10000
87
88/* The video memory and BIOS ROM, allocated shared from /dev/mem */
89#define HIMEM_BASE 0xA0000
90#define HIMEM_SIZE (SYSMEM_BASE + SYSMEM_SIZE - HIMEM_BASE)
91
92#define HOLE1_BASE (MAGICMEM_BASE + MAGICMEM_SIZE)
93#define HOLE1_SIZE (LOMEM_BASE - HOLE1_BASE)
94
95#define HOLE2_BASE (LOMEM_BASE + LOMEM_SIZE)
96#define HOLE2_SIZE (HIMEM_BASE - HOLE2_BASE)
97
98/* The BIOS ROM */
99#define ROM_BASE 0xC0000
100#define ROM_SIZE 0x30000
101
102#define STACK_SIZE 0x1000
103
104#define POINTER_SEGMENT(ptr) (((unsigned int)ptr)>>4)
105#define POINTER_OFFSET(ptr) (((unsigned int)ptr)&0x000F)
106#define MAKE_POINTER(seg, off) (((((unsigned int)(seg))<<4) + (unsigned int)(off)))
107#define MAKE_POINTER_1(lw) MAKE_POINTER(((lw)&0xFFFF0000)/0x10000, (lw)&0xFFFF)
108#define ALLOC_FAIL ((U32)-1)
109
110typedef struct _Vm86InfoRec {
111 void *magicMem, *loMem, *hiMem;
112 void *hole1, *hole2;
113 U32 brk;
114 struct vm86_struct vms;
115 U32 ret_code, stack_base;
116} Vm86InfoRec, *Vm86InfoPtr;
117
118#define LM(vi,i) (((char*)vi->loMem)[i-LOMEM_BASE])
119#define LMW(vi,i) (*(U16*)(&LM(vi,i)))
120#define LML(vi,i) (*(U32*)(&LM(vi,i)))
121#define MM(vi,i) (((char*)vi->magicMem)[i-MAGICMEM_BASE])
122#define MMW(vi,i) (*(U16*)(&MM(vi,i)))
123#define MML(vi,i) (*(U32*)(&MM(vi,i)))
124#define HM(vi,i) (((char*)vi->hiMem)[i-HIMEM_BASE])
125#define HMW(vi,i) (*(U16*)(&MM(vi,i)))
126#define HML(vi,i) (*(U32*)(&MM(vi,i)))
127
128Vm86InfoPtr
129Vm86Setup(int);
130
131void
132Vm86Cleanup(Vm86InfoPtr vi);
133
134int
135Vm86DoInterrupt(Vm86InfoPtr vi, int num);
136
137int
138Vm86DoPOST(Vm86InfoPtr vi);
139
140int
141Vm86IsMemory(Vm86InfoPtr vi, U32 i);
142
143U8
144Vm86Memory(Vm86InfoPtr, U32);
145
146U16
147Vm86MemoryW(Vm86InfoPtr, U32);
148
149U32
150Vm86MemoryL(Vm86InfoPtr, U32);
151
152void
153Vm86WriteMemory(Vm86InfoPtr, U32, U8);
154
155void
156Vm86WriteMemoryW(Vm86InfoPtr, U32, U16);
157
158void
159Vm86WriteMemoryL(Vm86InfoPtr, U32, U32);
160
161int
162Vm86AllocateMemory(Vm86InfoPtr, int);
163
164int
165Vm86MarkMemory (Vm86InfoPtr vi);
166
167void
168Vm86ReleaseMemory (Vm86InfoPtr vi, int mark);
169
170void
171Vm86Debug(Vm86InfoPtr vi);
172
173#endif /* _VM86_H_ */