kdrive: Bye bye Xvesa
This commit is contained in:
parent
9a874a71a7
commit
6d21fbf006
|
@ -554,7 +554,6 @@ AC_ARG_ENABLE(xephyr, AS_HELP_STRING([--enable-xephyr], [Build the kdriv
|
||||||
AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto])
|
AC_ARG_ENABLE(xsdl, AS_HELP_STRING([--enable-xsdl], [Build the kdrive Xsdl server (default: auto)]), [XSDL=$enableval], [XSDL=auto])
|
||||||
AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto])
|
AC_ARG_ENABLE(xfake, AS_HELP_STRING([--enable-xfake], [Build the kdrive 'fake' server (default: auto)]), [XFAKE=$enableval], [XFAKE=auto])
|
||||||
AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
|
AC_ARG_ENABLE(xfbdev, AS_HELP_STRING([--enable-xfbdev], [Build the kdrive framebuffer device server (default: auto)]), [XFBDEV=$enableval], [XFBDEV=auto])
|
||||||
AC_ARG_ENABLE(kdrive-vesa, AS_HELP_STRING([--enable-kdrive-vesa], [Build the kdrive VESA-based servers (default: auto)]), [KDRIVEVESA=$enableval], [KDRIVEVESA=auto])
|
|
||||||
|
|
||||||
|
|
||||||
dnl chown/chmod to be setuid root as part of build
|
dnl chown/chmod to be setuid root as part of build
|
||||||
|
@ -1875,6 +1874,5 @@ hw/kdrive/fbdev/Makefile
|
||||||
hw/kdrive/linux/Makefile
|
hw/kdrive/linux/Makefile
|
||||||
hw/kdrive/sdl/Makefile
|
hw/kdrive/sdl/Makefile
|
||||||
hw/kdrive/src/Makefile
|
hw/kdrive/src/Makefile
|
||||||
hw/kdrive/vesa/Makefile
|
|
||||||
xorg-server.pc
|
xorg-server.pc
|
||||||
])
|
])
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
if KDRIVEVESA
|
|
||||||
VESA_SUBDIRS = vesa
|
|
||||||
endif
|
|
||||||
|
|
||||||
if BUILD_KDRIVEFBDEVLIB
|
if BUILD_KDRIVEFBDEVLIB
|
||||||
FBDEV_SUBDIRS = fbdev
|
FBDEV_SUBDIRS = fbdev
|
||||||
endif
|
endif
|
||||||
|
@ -25,7 +21,6 @@ endif
|
||||||
SERVER_SUBDIRS = \
|
SERVER_SUBDIRS = \
|
||||||
$(XSDL_SUBDIRS) \
|
$(XSDL_SUBDIRS) \
|
||||||
$(FBDEV_SUBDIRS) \
|
$(FBDEV_SUBDIRS) \
|
||||||
$(VESA_SUBDIRS) \
|
|
||||||
$(XEPHYR_SUBDIRS) \
|
$(XEPHYR_SUBDIRS) \
|
||||||
$(XFAKE_SUBDIRS)
|
$(XFAKE_SUBDIRS)
|
||||||
|
|
||||||
|
@ -34,7 +29,7 @@ SUBDIRS = \
|
||||||
$(LINUX_SUBDIRS) \
|
$(LINUX_SUBDIRS) \
|
||||||
$(SERVER_SUBDIRS)
|
$(SERVER_SUBDIRS)
|
||||||
|
|
||||||
DIST_SUBDIRS = vesa fbdev sdl ephyr src linux fake
|
DIST_SUBDIRS = fbdev sdl ephyr src linux fake
|
||||||
|
|
||||||
relink:
|
relink:
|
||||||
@for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done
|
@for i in $(SERVER_SUBDIRS) ; do make -C $$i relink ; done
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
INCLUDES = \
|
|
||||||
@KDRIVE_INCS@ \
|
|
||||||
@KDRIVE_CFLAGS@
|
|
||||||
|
|
||||||
noinst_LIBRARIES = libvesa.a
|
|
||||||
|
|
||||||
bin_PROGRAMS = Xvesa
|
|
||||||
|
|
||||||
libvesa_a_SOURCES = \
|
|
||||||
vesa.c \
|
|
||||||
vesa.h \
|
|
||||||
vbe.c \
|
|
||||||
vbe.h \
|
|
||||||
vga.c \
|
|
||||||
vga.h \
|
|
||||||
vm86.c \
|
|
||||||
vm86.h
|
|
||||||
|
|
||||||
Xvesa_SOURCES = \
|
|
||||||
vesainit.c
|
|
||||||
|
|
||||||
Xvesa_LDADD = \
|
|
||||||
libvesa.a \
|
|
||||||
@KDRIVE_LIBS@
|
|
||||||
|
|
||||||
Xvesa_DEPENDENCIES = \
|
|
||||||
libvesa.a \
|
|
||||||
@KDRIVE_LOCAL_LIBS@
|
|
||||||
|
|
||||||
Xvesa_LDFLAGS = $(LD_EXPORT_SYMBOLS_FLAG)
|
|
||||||
|
|
||||||
relink:
|
|
||||||
rm -f $(bin_PROGRAMS) && make $(bin_PROGRAMS)
|
|
|
@ -1,105 +0,0 @@
|
||||||
.\" $RCSId: xc/programs/Xserver/hw/kdrive/vesa/Xvesa.man,v 1.5 2001/01/24 00:06:10 dawes Exp $
|
|
||||||
.TH Xvesa 1 __vendorversion__
|
|
||||||
.SH NAME
|
|
||||||
Xvesa \- VESA Bios Extensions tiny X server
|
|
||||||
.SH SYNOPSIS
|
|
||||||
.B Xvesa
|
|
||||||
.RI [ :display ]
|
|
||||||
.RI [ option ...]
|
|
||||||
.SH DESCRIPTION
|
|
||||||
.B Xvesa
|
|
||||||
is a generic X server for Linux on the x86 platform.
|
|
||||||
.B Xvesa
|
|
||||||
doesn't know about any particular hardware, and sets the video mode by
|
|
||||||
running the video BIOS in VM86 mode.
|
|
||||||
.B Xvesa
|
|
||||||
can use both standard VGA BIOS modes and any modes advertised by a
|
|
||||||
VESA BIOS if available.
|
|
||||||
|
|
||||||
.B Xvesa
|
|
||||||
runs untrusted code with full privileges, and is therefore a fairly
|
|
||||||
insecure X server.
|
|
||||||
.B Run at your own risk.
|
|
||||||
.SH OPTIONS
|
|
||||||
In addition to the normal KDrive server's options (see Xkdrive(1)),
|
|
||||||
.B Xvesa
|
|
||||||
accepts the following command line switches:
|
|
||||||
.TP 8
|
|
||||||
.B -mode \fIn\fB
|
|
||||||
specifies the VESA video mode to use. If mode
|
|
||||||
.I n
|
|
||||||
is not supported by your BIOS and hardware,
|
|
||||||
.B Xvesa
|
|
||||||
will fail, hang your system, damage your hardware, or cause a global
|
|
||||||
thermonuclear war; you are on your own. This option overrides any
|
|
||||||
.B -screen
|
|
||||||
options.
|
|
||||||
.TP 8
|
|
||||||
.B -listmodes
|
|
||||||
list all supported video modes. If
|
|
||||||
.B -force
|
|
||||||
was specified before
|
|
||||||
.BR -listmodes ,
|
|
||||||
lists all the modes that your BIOS claims to support, even those that
|
|
||||||
the
|
|
||||||
.B Xvesa
|
|
||||||
server won't be able to use.
|
|
||||||
.TP 8
|
|
||||||
.B -force
|
|
||||||
disable some sanity checks and use the specified mode even if the
|
|
||||||
BIOS claims not to support it.
|
|
||||||
.TP 8
|
|
||||||
.B -shadow
|
|
||||||
use a shadow framebuffer even if it is not strictly necessary. This
|
|
||||||
may dramatically improve performance on some hardware.
|
|
||||||
.TP 8
|
|
||||||
.B -nolinear
|
|
||||||
don't use a linear framebuffer even if one is available. You don't
|
|
||||||
want to use this option.
|
|
||||||
.TP 8
|
|
||||||
.B -swaprgb
|
|
||||||
pass RGB values in the order that works on broken BIOSes. Use this if
|
|
||||||
the colours are wrong in PseudoColor and 16 colour modes.
|
|
||||||
.TP 8
|
|
||||||
.B -map-holes
|
|
||||||
use a contiguous (hole-less) memory map. This fixes a segmentation
|
|
||||||
violation with some rare BIOSes that violate the VESA specification,
|
|
||||||
but may cause slightly higher memory usage on systems that overcommit
|
|
||||||
memory.
|
|
||||||
.TP 8
|
|
||||||
.B -force-text
|
|
||||||
ignore saved video mode and switch back to regular 25x80 text mode
|
|
||||||
on server exit or VT switch.
|
|
||||||
.TP 8
|
|
||||||
.B -verbose
|
|
||||||
emit diagnostic messages during BIOS initialization and teardown.
|
|
||||||
.SH KEYBOARD
|
|
||||||
Multiple key presses recognized directly by
|
|
||||||
.B Xvesa
|
|
||||||
are:
|
|
||||||
.TP 8
|
|
||||||
.B Ctrl+Alt+Backspace
|
|
||||||
Immediately kill the server.
|
|
||||||
.TP 8
|
|
||||||
.B Ctrl+Alt+F1...F12
|
|
||||||
Switch to virtual console 1 through 12.
|
|
||||||
.SH BUGS
|
|
||||||
.B Xvesa
|
|
||||||
opens all IO ports and runs your VESA BIOS, which may be assumed to be
|
|
||||||
buggy. Allowing your users to run
|
|
||||||
.B Xvesa
|
|
||||||
is probably a security hole.
|
|
||||||
|
|
||||||
.B Xvesa
|
|
||||||
records the current BIOS mode when it starts and restores that mode on
|
|
||||||
termination; if the video card has been reprogrammed by another application,
|
|
||||||
the display will almost certainly be trashed. The alternative of saving and
|
|
||||||
restoring the complete video card state has proven unreliable on most video
|
|
||||||
cards.
|
|
||||||
.SH SEE ALSO
|
|
||||||
X(__miscmansuffix__), Xserver(1), Xkdrive(1), xdm(1), xinit(1).
|
|
||||||
.SH AUTHORS
|
|
||||||
The VESA driver was written by Juliusz Chroboczek who didn't realise
|
|
||||||
what he was doing until it was too late. Keith Packard then added
|
|
||||||
support for standard VGA BIOS modes and is especially proud of 320x200
|
|
||||||
16 colour mode.
|
|
|
@ -1,706 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2000 by Juliusz Chroboczek
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <kdrive-config.h>
|
|
||||||
#endif
|
|
||||||
#include "vesa.h"
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
int mark;
|
|
||||||
int vib_base;
|
|
||||||
VbeInfoBlock *vib_low;
|
|
||||||
|
|
||||||
mark = Vm86MarkMemory (vi);
|
|
||||||
vib_base = Vm86AllocateMemory (vi, sizeof (VbeInfoBlock));
|
|
||||||
vib_low = (VbeInfoBlock*)&(LM(vi, vib_base));
|
|
||||||
vi->vms.regs.eax = 0x4F00;
|
|
||||||
vi->vms.regs.es = POINTER_SEGMENT(vib_base);
|
|
||||||
vi->vms.regs.edi = POINTER_OFFSET(vib_base);
|
|
||||||
memcpy(vib_low->VbeSignature, "VBE2", 4);
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code >= 0)
|
|
||||||
{
|
|
||||||
if(memcmp(vib_low->VbeSignature, "VESA", 4) == 0)
|
|
||||||
*vib = *vib_low;
|
|
||||||
else
|
|
||||||
code = -1;
|
|
||||||
}
|
|
||||||
Vm86ReleaseMemory (vi, mark);
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
int mark;
|
|
||||||
int vmib_base;
|
|
||||||
VbeModeInfoBlock *vmib_low;
|
|
||||||
|
|
||||||
mark = Vm86MarkMemory (vi);
|
|
||||||
|
|
||||||
vmib_base = Vm86AllocateMemory (vi, sizeof (VbeModeInfoBlock));
|
|
||||||
vmib_low = (VbeModeInfoBlock*)&(LM(vi, vmib_base));
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x4F01;
|
|
||||||
vi->vms.regs.ecx = mode&0xFFFF;
|
|
||||||
vi->vms.regs.es = POINTER_SEGMENT(vmib_base);
|
|
||||||
vi->vms.regs.edi = POINTER_OFFSET(vmib_base);
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
|
|
||||||
if(code >= 0)
|
|
||||||
*vmib = *vmib_low;
|
|
||||||
Vm86ReleaseMemory (vi, mark);
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
VbeReportVib(Vm86InfoPtr vi, VbeInfoBlock *vib)
|
|
||||||
{
|
|
||||||
U32 i, p;
|
|
||||||
unsigned char c;
|
|
||||||
int error = 0;
|
|
||||||
|
|
||||||
ErrorF("VBE version %c.%c (",
|
|
||||||
((vib->VbeVersion >> 8) & 0xFF) + '0',
|
|
||||||
(vib->VbeVersion & 0xFF)+'0');
|
|
||||||
p = vib->OemStringPtr;
|
|
||||||
for(i = 0; 1; i++) {
|
|
||||||
c = Vm86Memory(vi, MAKE_POINTER_1(p+i));
|
|
||||||
if(!c) break;
|
|
||||||
if (c >= ' ')
|
|
||||||
ErrorF("%c", c);
|
|
||||||
if (i > 32000) {
|
|
||||||
error = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ErrorF(")\n");
|
|
||||||
ErrorF("DAC is %s, controller is %sVGA compatible%s\n",
|
|
||||||
(vib->Capabilities[0]&1)?"switchable":"fixed",
|
|
||||||
(vib->Capabilities[0]&2)?"not ":"",
|
|
||||||
(vib->Capabilities[0]&3)?", RAMDAC causes snow":"");
|
|
||||||
ErrorF("Total memory: %lu kilobytes\n", 64L*vib->TotalMemory);
|
|
||||||
if(error)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
static int
|
|
||||||
VbeReportModeInfo(Vm86InfoPtr vi, U16 mode, VbeModeInfoBlock *vmib)
|
|
||||||
{
|
|
||||||
int supported = (vmib->ModeAttributes&0x1)?1:0;
|
|
||||||
int colour = (vmib->ModeAttributes&0x8)?1:0;
|
|
||||||
int graphics = (vmib->ModeAttributes&0x10)?1:0;
|
|
||||||
int vga_compatible = !((vmib->ModeAttributes&0x20)?1:0);
|
|
||||||
int linear_fb = (vmib->ModeAttributes&0x80)?1:0;
|
|
||||||
|
|
||||||
ErrorF("0x%04X: %dx%dx%d%s",
|
|
||||||
(unsigned)mode,
|
|
||||||
(int)vmib->XResolution, (int)vmib->YResolution,
|
|
||||||
(int)vmib->BitsPerPixel,
|
|
||||||
colour?"":" (monochrome)",
|
|
||||||
graphics?"":" (graphics)",
|
|
||||||
vga_compatible?"":" (vga compatible)",
|
|
||||||
linear_fb?"":" (linear frame buffer)");
|
|
||||||
switch(vmib->MemoryModel) {
|
|
||||||
case 0:
|
|
||||||
ErrorF(" text mode (%dx%d)",
|
|
||||||
(int)vmib->XCharSize, (int)vmib->YCharSize);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
ErrorF(" CGA graphics");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ErrorF(" Hercules graphics");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
ErrorF(" Planar (%d planes)", vmib->NumberOfPlanes);
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
ErrorF(" PseudoColor");
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
ErrorF(" Non-chain 4, 256 colour");
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
if(vmib->DirectColorModeInfo & 1)
|
|
||||||
ErrorF(" DirectColor");
|
|
||||||
else
|
|
||||||
ErrorF(" TrueColor");
|
|
||||||
ErrorF(" [%d:%d:%d:%d]",
|
|
||||||
vmib->RedMaskSize, vmib->GreenMaskSize, vmib->BlueMaskSize,
|
|
||||||
vmib->RsvdMaskSize);
|
|
||||||
if(vmib->DirectColorModeInfo & 2)
|
|
||||||
ErrorF(" (reserved bits are reserved)");
|
|
||||||
break;
|
|
||||||
case 7: ErrorF("YUV");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ErrorF("unknown MemoryModel 0x%X ", vmib->MemoryModel);
|
|
||||||
}
|
|
||||||
if(!supported)
|
|
||||||
ErrorF(" (unsupported)");
|
|
||||||
else if(!linear_fb)
|
|
||||||
ErrorF(" (no linear framebuffer)");
|
|
||||||
ErrorF("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void
|
|
||||||
VbeReportInfo (Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
int code;
|
|
||||||
|
|
||||||
code = VbeGetVib (vi, &vib);
|
|
||||||
if (code >= 0)
|
|
||||||
VbeReportVib(vi, &vib);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetNmode (Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
int code;
|
|
||||||
unsigned int p;
|
|
||||||
int n;
|
|
||||||
int mode;
|
|
||||||
|
|
||||||
code = VbeGetVib (vi, &vib);
|
|
||||||
if (code >= 0)
|
|
||||||
{
|
|
||||||
p = MAKE_POINTER_1(vib.VideoModePtr);
|
|
||||||
for (n = 0; ; n++)
|
|
||||||
{
|
|
||||||
mode = Vm86MemoryW(vi, p);
|
|
||||||
if (mode == 0xffff)
|
|
||||||
break;
|
|
||||||
p += 2;
|
|
||||||
}
|
|
||||||
code = n;
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode)
|
|
||||||
{
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
int code;
|
|
||||||
unsigned int p;
|
|
||||||
int n;
|
|
||||||
int mode;
|
|
||||||
VbeModeInfoBlock vmib;
|
|
||||||
|
|
||||||
code = VbeGetVib (vi, &vib);
|
|
||||||
if (code < 0)
|
|
||||||
return code;
|
|
||||||
|
|
||||||
memset (modes, '\0', nmode * sizeof (VesaModeRec));
|
|
||||||
|
|
||||||
p = MAKE_POINTER_1(vib.VideoModePtr);
|
|
||||||
for (n = 0; n < nmode; n++)
|
|
||||||
{
|
|
||||||
mode = Vm86MemoryW(vi, p);
|
|
||||||
if (mode == 0xffff)
|
|
||||||
break;
|
|
||||||
modes[n].mode = mode;
|
|
||||||
modes[n].vbe = 1;
|
|
||||||
p += 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
nmode = n;
|
|
||||||
|
|
||||||
for (n = 0; n < nmode; n++)
|
|
||||||
{
|
|
||||||
code = VbeGetVmib (vi, modes[n].mode, &vmib);
|
|
||||||
if (code >= 0)
|
|
||||||
{
|
|
||||||
modes[n].ModeAttributes = vmib.ModeAttributes;
|
|
||||||
modes[n].NumberOfPlanes = vmib.NumberOfPlanes;
|
|
||||||
modes[n].BitsPerPixel = vmib.BitsPerPixel;
|
|
||||||
modes[n].MemoryModel = vmib.MemoryModel;
|
|
||||||
modes[n].RedMaskSize = vmib.RedMaskSize;
|
|
||||||
modes[n].RedFieldPosition = vmib.RedFieldPosition;
|
|
||||||
modes[n].GreenMaskSize = vmib.GreenMaskSize;
|
|
||||||
modes[n].GreenFieldPosition = vmib.GreenFieldPosition;
|
|
||||||
modes[n].BlueMaskSize = vmib.BlueMaskSize;
|
|
||||||
modes[n].BlueFieldPosition = vmib.BlueFieldPosition;
|
|
||||||
modes[n].RsvdMaskSize = vmib.RsvdMaskSize;
|
|
||||||
modes[n].RsvdFieldPosition = vmib.RsvdFieldPosition;
|
|
||||||
modes[n].DirectColorModeInfo = vmib.DirectColorModeInfo;
|
|
||||||
modes[n].XResolution = vmib.XResolution;
|
|
||||||
modes[n].YResolution = vmib.YResolution;
|
|
||||||
modes[n].BytesPerScanLine = vmib.BytesPerScanLine;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nmode;
|
|
||||||
}
|
|
||||||
|
|
||||||
VbeInfoPtr
|
|
||||||
VbeInit (Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
VbeInfoPtr vbe;
|
|
||||||
int code;
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
|
|
||||||
code = VbeGetVib (vi, &vib);
|
|
||||||
if (code < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
vbe = xalloc (sizeof (VbeInfoRec));
|
|
||||||
if (!vbe)
|
|
||||||
return 0;
|
|
||||||
vbe->palette_format = 6;
|
|
||||||
vbe->palette_wait = TRUE;
|
|
||||||
return vbe;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe)
|
|
||||||
{
|
|
||||||
xfree (vbe);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
int palette_wait = 0, palette_hi = 0;
|
|
||||||
|
|
||||||
code = VbeGetVib (vi, &vib);
|
|
||||||
if (code < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
code = VbeGetVmib (vi, mode, &vbe->vmib);
|
|
||||||
if (code < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
mode = (mode & 0xffff) &~ 0x8000;
|
|
||||||
if (linear)
|
|
||||||
mode |= 0x4000;
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x4F02;
|
|
||||||
vi->vms.regs.ebx = mode;
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
vbe->windowA_offset = vbe->windowB_offset = -1;
|
|
||||||
vbe->last_window = 1;
|
|
||||||
|
|
||||||
if (!direct)
|
|
||||||
{
|
|
||||||
if(vib.Capabilities[0] & 1)
|
|
||||||
palette_hi = 1;
|
|
||||||
if(vib.Capabilities[0] & 4)
|
|
||||||
palette_wait = 1;
|
|
||||||
|
|
||||||
if(palette_hi || palette_wait)
|
|
||||||
VbeSetPaletteOptions(vi, vbe, palette_hi?8:6, palette_wait);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetMode(Vm86InfoPtr vi, int *mode)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x4F03;
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code < 0)
|
|
||||||
return - 1;
|
|
||||||
*mode = vi->vms.regs.ebx & 0xFFFF;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size, CARD32 *ret_phys)
|
|
||||||
{
|
|
||||||
U8 *fb;
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
VbeModeInfoBlock vmib;
|
|
||||||
int size;
|
|
||||||
int pagesize = getpagesize();
|
|
||||||
int before, after;
|
|
||||||
|
|
||||||
if (VbeGetVib (vi, &vib) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (VbeGetVmib (vi, mode, &vmib) < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
size = 1024 * 64L * vib.TotalMemory;
|
|
||||||
|
|
||||||
*ret_size = size;
|
|
||||||
*ret_phys = vmib.PhysBasePtr;
|
|
||||||
|
|
||||||
before = vmib.PhysBasePtr % pagesize;
|
|
||||||
after = pagesize - ((vmib.PhysBasePtr + size) % pagesize);
|
|
||||||
if(after == pagesize)
|
|
||||||
after = 0;
|
|
||||||
|
|
||||||
fb = KdMapDevice (vmib.PhysBasePtr - before, before + size + after);
|
|
||||||
|
|
||||||
if(fb == 0)
|
|
||||||
{
|
|
||||||
ErrorF("Failed to map framebuffer\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
KdSetMappedMode (vmib.PhysBasePtr - before, before + size + after,
|
|
||||||
KD_MAPPED_MODE_FRAMEBUFFER);
|
|
||||||
|
|
||||||
return fb + before;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb)
|
|
||||||
{
|
|
||||||
VbeInfoBlock vib;
|
|
||||||
VbeModeInfoBlock vmib;
|
|
||||||
int size;
|
|
||||||
int pagesize = getpagesize();
|
|
||||||
int before, after;
|
|
||||||
|
|
||||||
if (VbeGetVib (vi, &vib) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (VbeGetVmib (vi, mode, &vmib) < 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
size = 1024 * 64L * vib.TotalMemory;
|
|
||||||
|
|
||||||
before = vmib.PhysBasePtr % pagesize;
|
|
||||||
after = pagesize - ((vmib.PhysBasePtr + size) % pagesize);
|
|
||||||
if(after == pagesize)
|
|
||||||
after = 0;
|
|
||||||
|
|
||||||
fb = (void *) ((char *) fb - before);
|
|
||||||
|
|
||||||
KdUnmapDevice (fb, before + size + after);
|
|
||||||
KdResetMappedMode (vmib.PhysBasePtr - before, before + size + after,
|
|
||||||
KD_MAPPED_MODE_FRAMEBUFFER);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries)
|
|
||||||
{
|
|
||||||
U8 *palette_scratch;
|
|
||||||
int mark;
|
|
||||||
int palette_base;
|
|
||||||
int i, code;
|
|
||||||
|
|
||||||
if(number == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(first < 0 || number < 0 || first + number > 256) {
|
|
||||||
ErrorF("Cannot set %d, %d palette entries\n", first, number);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(vbe->palette_format < 6 || vbe->palette_format > 8) {
|
|
||||||
ErrorF("Impossible palette format %d\n", vbe->palette_format);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark = Vm86MarkMemory (vi);
|
|
||||||
palette_base = Vm86AllocateMemory (vi, 4 * 256);
|
|
||||||
|
|
||||||
palette_scratch = &LM(vi, palette_base);
|
|
||||||
|
|
||||||
for(i=0; i<number*4; i++)
|
|
||||||
palette_scratch[i] = entries[i] >> (8 - vbe->palette_format);
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x4F09;
|
|
||||||
if(vbe->palette_wait)
|
|
||||||
vi->vms.regs.ebx = 0x80;
|
|
||||||
else
|
|
||||||
vi->vms.regs.ebx = 0x00;
|
|
||||||
vi->vms.regs.ecx = number;
|
|
||||||
vi->vms.regs.edx = first;
|
|
||||||
vi->vms.regs.es = POINTER_SEGMENT(palette_base);
|
|
||||||
vi->vms.regs.edi = POINTER_OFFSET(palette_base);
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
Vm86ReleaseMemory (vi, mark);
|
|
||||||
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries)
|
|
||||||
{
|
|
||||||
U8 *palette_scratch;
|
|
||||||
int mark;
|
|
||||||
int palette_base;
|
|
||||||
int i, code;
|
|
||||||
|
|
||||||
if(number == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(first < 0 || number < 0 || first + number > 256) {
|
|
||||||
ErrorF("Cannot get %d, %d palette entries\n", first, number);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(vbe->palette_format < 6 || vbe->palette_format > 8) {
|
|
||||||
ErrorF("Impossible palette format %d\n", vbe->palette_format);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark = Vm86MarkMemory (vi);
|
|
||||||
palette_base = Vm86AllocateMemory (vi, 4 * 256);
|
|
||||||
|
|
||||||
palette_scratch = &LM(vi, palette_base);
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x4F09;
|
|
||||||
vi->vms.regs.ebx = 0x01;
|
|
||||||
vi->vms.regs.ecx = number;
|
|
||||||
vi->vms.regs.edx = first;
|
|
||||||
vi->vms.regs.es = POINTER_SEGMENT(palette_base);
|
|
||||||
vi->vms.regs.edi = POINTER_OFFSET(palette_base);
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code >= 0)
|
|
||||||
{
|
|
||||||
for(i=0; i<number*4; i++)
|
|
||||||
entries[i] = palette_scratch[i] << (8-vbe->palette_format);
|
|
||||||
}
|
|
||||||
Vm86ReleaseMemory (vi, mark);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
if(bits < 6 || bits > 8) {
|
|
||||||
ErrorF("Impossible palette format %d\n", bits);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if(bits != vbe->palette_format)
|
|
||||||
{
|
|
||||||
vbe->palette_format = 0;
|
|
||||||
vi->vms.regs.eax = 0x4F08;
|
|
||||||
vi->vms.regs.ebx = bits << 8;
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
vbe->palette_format = bits;
|
|
||||||
}
|
|
||||||
vbe->palette_wait = wait;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
VbeReallySetWindow(Vm86InfoPtr vi, U8 window, U16 winnum)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
vi->vms.regs.eax = 0x4F05;
|
|
||||||
vi->vms.regs.ebx = window;
|
|
||||||
vi->vms.regs.edx = winnum;
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return)
|
|
||||||
{
|
|
||||||
int window_size = vbe->vmib.WinSize * 1024;
|
|
||||||
int code;
|
|
||||||
int winnum;
|
|
||||||
|
|
||||||
if(vbe->windowA_offset >= 0)
|
|
||||||
if(vbe->windowA_offset <= offset && vbe->windowA_offset + window_size > offset)
|
|
||||||
if(vbe->vmib.WinAAttributes & purpose)
|
|
||||||
goto windowA;
|
|
||||||
|
|
||||||
if(vbe->windowB_offset >= 0)
|
|
||||||
if(vbe->windowB_offset <= offset && vbe->windowB_offset + window_size > offset)
|
|
||||||
if(vbe->vmib.WinBAttributes & purpose)
|
|
||||||
goto windowB;
|
|
||||||
|
|
||||||
if(!(vbe->vmib.WinBAttributes & purpose) ||
|
|
||||||
!(vbe->vmib.WinBAttributes & VBE_WINDOW_RELOCATE))
|
|
||||||
goto set_windowA;
|
|
||||||
|
|
||||||
if(!(vbe->vmib.WinAAttributes & purpose) ||
|
|
||||||
!(vbe->vmib.WinAAttributes & VBE_WINDOW_RELOCATE))
|
|
||||||
goto set_windowB;
|
|
||||||
|
|
||||||
if(vbe->last_window)
|
|
||||||
goto set_windowA;
|
|
||||||
else
|
|
||||||
goto set_windowB;
|
|
||||||
|
|
||||||
set_windowA:
|
|
||||||
winnum = offset / (vbe->vmib.WinGranularity * 1024);
|
|
||||||
code = VbeReallySetWindow(vi, 0, winnum);
|
|
||||||
if(code < 0) {
|
|
||||||
ErrorF("Couldn't set window A to %d*%d\n",
|
|
||||||
(int)winnum, (int)vbe->vmib.WinGranularity);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
vbe->windowA_offset = winnum * vbe->vmib.WinGranularity * 1024;
|
|
||||||
windowA:
|
|
||||||
vbe->last_window = 0;
|
|
||||||
*size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowA_offset);
|
|
||||||
return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinASegment, 0)))) + offset - vbe->windowA_offset;
|
|
||||||
|
|
||||||
set_windowB:
|
|
||||||
winnum = offset / (vbe->vmib.WinGranularity * 1024);
|
|
||||||
code = VbeReallySetWindow(vi, 1, winnum);
|
|
||||||
if(code < 0) {
|
|
||||||
ErrorF("Couldn't set window B to %d*%d\n",
|
|
||||||
(int)winnum, (int)vbe->vmib.WinGranularity);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
vbe->windowB_offset = winnum * vbe->vmib.WinGranularity * 1024;
|
|
||||||
windowB:
|
|
||||||
vbe->last_window = 1;
|
|
||||||
*size_return = vbe->vmib.WinSize * 1024 - (offset - vbe->windowB_offset);
|
|
||||||
return ((U8*)&(LM(vi, MAKE_POINTER(vbe->vmib.WinBSegment, 0)))) + offset - vbe->windowB_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const int VbeDPMSModes[4] = {
|
|
||||||
0x00, /* KD_DPMS_NORMAL */
|
|
||||||
0x01, /* KD_DPMS_STANDBY */
|
|
||||||
0x02, /* KD_DPMS_SUSPEND */
|
|
||||||
0x04, /* KD_DPMS_POWERDOWN */
|
|
||||||
};
|
|
||||||
|
|
||||||
Bool
|
|
||||||
VbeDPMS(Vm86InfoPtr vi, int mode)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check which modes are supported
|
|
||||||
*/
|
|
||||||
vi->vms.regs.eax = 0x4f10;
|
|
||||||
vi->vms.regs.ebx = 0x0000;
|
|
||||||
vi->vms.regs.es = 0;
|
|
||||||
vi->vms.regs.edi = 0;
|
|
||||||
code = VbeDoInterrupt10 (vi);
|
|
||||||
if (code < 0)
|
|
||||||
{
|
|
||||||
ErrorF ("No DPMS Support %d\n", code);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* Skip this stage if it's not supported */
|
|
||||||
if (((vi->vms.regs.ebx >> 4) & VbeDPMSModes[mode]) != VbeDPMSModes[mode])
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
/* Select this mode */
|
|
||||||
vi->vms.regs.eax = 0x4f10;
|
|
||||||
vi->vms.regs.ebx = (VbeDPMSModes[mode] << 8) | 0x01;
|
|
||||||
code = VbeDoInterrupt10 (vi);
|
|
||||||
if (code < 0)
|
|
||||||
{
|
|
||||||
ErrorF ("DPMS failed %d\n", code);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Bool
|
|
||||||
VbeBoot(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
int bus = 1;
|
|
||||||
int device = 0;
|
|
||||||
int function = 0;
|
|
||||||
|
|
||||||
vi->vms.regs.eax = (bus << 8) | (device << 3) | (function & 0x7);
|
|
||||||
code = VbeDoInterruptE6 (vi);
|
|
||||||
ErrorF ("Boot: %d\n", code);
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeDoInterrupt10(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
int oldax;
|
|
||||||
|
|
||||||
oldax = vi->vms.regs.eax & 0xFFFF;
|
|
||||||
|
|
||||||
code = Vm86DoInterrupt(vi, 0x10);
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if((vi->vms.regs.eax & 0xFFFF) != 0x4F && (oldax & 0xFF00) == 0x4F00) {
|
|
||||||
ErrorF("Int 10h (0x%04X) failed: 0x%04X",
|
|
||||||
oldax, vi->vms.regs.eax & 0xFFFF);
|
|
||||||
if((oldax & 0xFF00) == 0x4F00) {
|
|
||||||
switch((vi->vms.regs.eax & 0xFF00)>>8) {
|
|
||||||
case 0:
|
|
||||||
ErrorF(" (success)\n");
|
|
||||||
return 0;
|
|
||||||
case 1:
|
|
||||||
ErrorF(" (function call failed)\n");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
ErrorF(" (function not supported on this hardware)\n");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
ErrorF(" (function call invalid in this video mode)\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ErrorF(" (unknown error)\n");
|
|
||||||
break;
|
|
||||||
} return -1;
|
|
||||||
} else {
|
|
||||||
ErrorF("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return code;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeDoInterruptE6(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
int oldax;
|
|
||||||
|
|
||||||
oldax = vi->vms.regs.eax & 0xffff;
|
|
||||||
|
|
||||||
code = Vm86DoPOST (vi);
|
|
||||||
ErrorF("POST (0x%04X): 0x%04X\n",
|
|
||||||
oldax, vi->vms.regs.eax & 0xffff);
|
|
||||||
return code;
|
|
||||||
}
|
|
|
@ -1,165 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2000 by Juliusz Chroboczek
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VBE_H
|
|
||||||
#define _VBE_H
|
|
||||||
|
|
||||||
#define VBE_WINDOW_RELOCATE 1
|
|
||||||
#define VBE_WINDOW_READ 2
|
|
||||||
#define VBE_WINDOW_WRITE 4
|
|
||||||
|
|
||||||
typedef struct _VbeInfoBlock {
|
|
||||||
U8 VbeSignature[4]; /* VBE Signature */
|
|
||||||
U16 VbeVersion; /* VBE Version */
|
|
||||||
U32 OemStringPtr; /* Pointer to OEM String */
|
|
||||||
U8 Capabilities[4]; /* Capabilities of graphics controller */
|
|
||||||
U32 VideoModePtr; /* Pointer to VideoModeList */
|
|
||||||
U16 TotalMemory; /* Number of 64kb memory blocks */
|
|
||||||
/* Added for VBE 2.0 */
|
|
||||||
U16 OemSoftwareRev; /* VBE implementation Software revision */
|
|
||||||
U32 OemVendorNamePtr; /* Pointer to Vendor Name String */
|
|
||||||
U32 OemProductNamePtr; /* Pointer to Product Name String */
|
|
||||||
U32 OemProductRevPtr; /* Pointer to Product Revision String */
|
|
||||||
U8 Reserved[222]; /* Reserved for VBE implementation */
|
|
||||||
U8 OemData[256]; /* Data Area for OEM Strings*/
|
|
||||||
} __attribute__((packed)) VbeInfoBlock;
|
|
||||||
|
|
||||||
typedef struct _VbeModeInfoBlock {
|
|
||||||
/* Mandatory information for all VBE revisions */
|
|
||||||
U16 ModeAttributes; /* mode attributes */
|
|
||||||
U8 WinAAttributes; /* window A attributes */
|
|
||||||
U8 WinBAttributes; /* window B attributes */
|
|
||||||
U16 WinGranularity; /* window granularity */
|
|
||||||
U16 WinSize; /* window size */
|
|
||||||
U16 WinASegment; /* window A start segment */
|
|
||||||
U16 WinBSegment; /* window B start segment */
|
|
||||||
U32 WinFuncPtr; /* pointer to window function */
|
|
||||||
U16 BytesPerScanLine; /* bytes per scan line */
|
|
||||||
/* Mandatory information for VBE 1.2 and above */
|
|
||||||
U16 XResolution; /* horizontal resolution */
|
|
||||||
U16 YResolution; /* vertical resolution */
|
|
||||||
U8 XCharSize; /* character cell width in pixels */
|
|
||||||
U8 YCharSize; /* character cell height in pixels */
|
|
||||||
U8 NumberOfPlanes; /* number of memory planes */
|
|
||||||
U8 BitsPerPixel; /* bits per pixel */
|
|
||||||
U8 NumberOfBanks; /* number of banks */
|
|
||||||
U8 MemoryModel; /* memory model type */
|
|
||||||
U8 BankSize; /* bank size in KB */
|
|
||||||
U8 NumberOfImagePages; /* number of images */
|
|
||||||
U8 Reserved; /* reserved for page function */
|
|
||||||
/* Direct Color fields (required for direct/6 and YUV/7 memory models) */
|
|
||||||
U8 RedMaskSize; /* size of direct color red mask in bits */
|
|
||||||
U8 RedFieldPosition; /* bit position of lsb of red mask */
|
|
||||||
U8 GreenMaskSize; /* size of direct color green mask in bits */
|
|
||||||
U8 GreenFieldPosition; /* bit position of lsb of green mask */
|
|
||||||
U8 BlueMaskSize; /* size of direct color blue mask in bits */
|
|
||||||
U8 BlueFieldPosition; /* bit position of lsb of blue mask */
|
|
||||||
U8 RsvdMaskSize; /* size of direct color reserved mask bits*/
|
|
||||||
U8 RsvdFieldPosition; /* bit position of lsb of reserved mask */
|
|
||||||
U8 DirectColorModeInfo; /* direct color mode attributes */
|
|
||||||
/* Mandatory information for VBE 2.0 and above */
|
|
||||||
U32 PhysBasePtr; /* physical address for flat memory fb */
|
|
||||||
U32 OffScreenMemOffset; /* pointer to start of off screen memory */
|
|
||||||
U16 OffScreenMemSize; /* amount of off screen memory in 1k units */
|
|
||||||
U8 Reserved2[206]; /* remainder of ModeInfoBlock */
|
|
||||||
} __attribute__((packed)) VbeModeInfoBlock;
|
|
||||||
|
|
||||||
typedef struct _VbeInfoRec {
|
|
||||||
U8 palette_format;
|
|
||||||
int palette_wait;
|
|
||||||
int windowA_offset;
|
|
||||||
int windowB_offset;
|
|
||||||
int window_size;
|
|
||||||
int last_window;
|
|
||||||
VbeModeInfoBlock vmib;
|
|
||||||
} VbeInfoRec, *VbeInfoPtr;
|
|
||||||
|
|
||||||
typedef struct _SupVbeInfoBlock {
|
|
||||||
U8 SupVbeSignature[7]; /* Supplemental VBE Signature */
|
|
||||||
U16 SupVbeVersion; /* Supplemental VBE Version*/
|
|
||||||
U8 SupVbeSubFunc[8]; /* Bitfield of supported subfunctions */
|
|
||||||
U16 OemSoftwareRev; /* OEM Software revision */
|
|
||||||
U32 OemVendorNamePtr; /* Pointer to Vendor Name String */
|
|
||||||
U32 OemProductNamePtr; /* Pointer to Product Name String */
|
|
||||||
U32 OemProductRevPtr; /* Pointer to Product Revision String */
|
|
||||||
U32 OemStringPtr; /* Pointer to OEM String */
|
|
||||||
U8 Reserved[221]; /* Reserved */
|
|
||||||
} __attribute__((packed)) SupVbeInfoBlock;
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetVib (Vm86InfoPtr vi, VbeInfoBlock *vib);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetVmib (Vm86InfoPtr vi, int mode, VbeModeInfoBlock *vmib);
|
|
||||||
|
|
||||||
void
|
|
||||||
VbeReportInfo (Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetNmode (Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetModes (Vm86InfoPtr vi, VesaModePtr modes, int nmode);
|
|
||||||
|
|
||||||
VbeInfoPtr
|
|
||||||
VbeInit (Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
void
|
|
||||||
VbeCleanup (Vm86InfoPtr vi, VbeInfoPtr vbe);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeSetMode (Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int linear, int direct);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetMode(Vm86InfoPtr vi, int *mode);
|
|
||||||
|
|
||||||
void *
|
|
||||||
VbeMapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, int *ret_size, CARD32 *ret_phys);
|
|
||||||
|
|
||||||
void
|
|
||||||
VbeUnmapFramebuffer(Vm86InfoPtr vi, VbeInfoPtr vbe, int mode, void *fb);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeSetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeGetPalette(Vm86InfoPtr vi, VbeInfoPtr vbe, int first, int number, U8 *entries);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeSetPaletteOptions(Vm86InfoPtr vi, VbeInfoPtr vbe, U8 bits, int wait);
|
|
||||||
|
|
||||||
void *
|
|
||||||
VbeSetWindow(Vm86InfoPtr vi, VbeInfoPtr vbe, int offset, int purpose, int *size_return);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
VbeDPMS(Vm86InfoPtr vi, int mode);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeDoInterrupt10(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
VbeBoot(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
int
|
|
||||||
VbeDoInterruptE6(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,295 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2000 by Juliusz Chroboczek
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VESA_H_
|
|
||||||
#define _VESA_H_
|
|
||||||
|
|
||||||
#include "kdrive.h"
|
|
||||||
#include "shadow.h"
|
|
||||||
#include "vm86.h"
|
|
||||||
#ifdef RANDR
|
|
||||||
#include "randrstr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define VESA_TEXT_SAVE (64*1024)
|
|
||||||
|
|
||||||
#define MODE_SUPPORTED 0x01
|
|
||||||
#define MODE_COLOUR 0x08
|
|
||||||
#define MODE_GRAPHICS 0x10
|
|
||||||
#define MODE_VGA 0x20
|
|
||||||
#define MODE_LINEAR 0x80
|
|
||||||
|
|
||||||
#define MODE_DIRECT 0x1
|
|
||||||
|
|
||||||
#define MEMORY_TEXT 0
|
|
||||||
#define MEMORY_CGA 1
|
|
||||||
#define MEMORY_HERCULES 2
|
|
||||||
#define MEMORY_PLANAR 3
|
|
||||||
#define MEMORY_PSEUDO 4
|
|
||||||
#define MEMORY_NONCHAIN 5
|
|
||||||
#define MEMORY_DIRECT 6
|
|
||||||
#define MEMORY_YUV 7
|
|
||||||
|
|
||||||
typedef struct _VesaMode {
|
|
||||||
int mode; /* mode number */
|
|
||||||
int vbe; /* a VBE mode */
|
|
||||||
int ModeAttributes; /* mode attributes */
|
|
||||||
int NumberOfPlanes; /* number of memory planes */
|
|
||||||
int BitsPerPixel; /* bits per pixel */
|
|
||||||
int MemoryModel; /* memory model type */
|
|
||||||
int RedMaskSize; /* size of direct color red mask in bits */
|
|
||||||
int RedFieldPosition; /* bit position of lsb of red mask */
|
|
||||||
int GreenMaskSize; /* size of direct color green mask in bits */
|
|
||||||
int GreenFieldPosition; /* bit position of lsb of green mask */
|
|
||||||
int BlueMaskSize; /* size of direct color blue mask in bits */
|
|
||||||
int BlueFieldPosition; /* bit position of lsb of blue mask */
|
|
||||||
int RsvdMaskSize; /* size of direct color reserved mask bits*/
|
|
||||||
int RsvdFieldPosition; /* bit position of lsb of reserved mask */
|
|
||||||
int DirectColorModeInfo; /* direct color mode attributes */
|
|
||||||
int XResolution; /* horizontal resolution */
|
|
||||||
int YResolution; /* vertical resolution */
|
|
||||||
int BytesPerScanLine; /* bytes per scan line */
|
|
||||||
} VesaModeRec, *VesaModePtr;
|
|
||||||
|
|
||||||
#include "vbe.h"
|
|
||||||
#include "vga.h"
|
|
||||||
|
|
||||||
typedef struct _VesaCardPriv {
|
|
||||||
int vbe;
|
|
||||||
VesaModePtr modes;
|
|
||||||
int nmode;
|
|
||||||
Vm86InfoPtr vi;
|
|
||||||
int vga_palette;
|
|
||||||
int old_vbe_mode;
|
|
||||||
int old_vga_mode;
|
|
||||||
VbeInfoPtr vbeInfo;
|
|
||||||
char text[VESA_TEXT_SAVE];
|
|
||||||
CARD8 cmap[256*4];
|
|
||||||
} VesaCardPrivRec, *VesaCardPrivPtr;
|
|
||||||
|
|
||||||
#define VESA_LINEAR 0
|
|
||||||
#define VESA_WINDOWED 1
|
|
||||||
#define VESA_PLANAR 2
|
|
||||||
#define VESA_MONO 3
|
|
||||||
|
|
||||||
typedef struct _VesaScreenPriv {
|
|
||||||
VesaModeRec mode;
|
|
||||||
Bool shadow;
|
|
||||||
Rotation randr;
|
|
||||||
int mapping;
|
|
||||||
int origDepth;
|
|
||||||
void *fb;
|
|
||||||
int fb_size;
|
|
||||||
CARD32 fb_phys;
|
|
||||||
PixmapPtr pShadow;
|
|
||||||
Bool mapped;
|
|
||||||
} VesaScreenPrivRec, *VesaScreenPrivPtr;
|
|
||||||
|
|
||||||
extern int vesa_video_mode;
|
|
||||||
extern Bool vesa_force_mode;
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaReportMode (VesaModePtr mode);
|
|
||||||
|
|
||||||
VesaModePtr
|
|
||||||
vesaGetModes (Vm86InfoPtr vi, int *ret_nmode);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaTestMode (void);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaSetWindowPlanar(ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaSetWindowLinear (ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaSetWindowWindowed (ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaWindowPlanar (ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size,
|
|
||||||
void *closure);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaWindowLinear (ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size,
|
|
||||||
void *closure);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaWindowWindowed (ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size,
|
|
||||||
void *closure);
|
|
||||||
|
|
||||||
void *
|
|
||||||
vesaWindowCga (ScreenPtr pScreen,
|
|
||||||
CARD32 row,
|
|
||||||
CARD32 offset,
|
|
||||||
int mode,
|
|
||||||
CARD32 *size,
|
|
||||||
void *closure);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaUpdateMono (ScreenPtr pScreen,
|
|
||||||
shadowBufPtr pBuf);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaCreateColormap16 (ColormapPtr pmap);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaSetScreenSizes (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaSetShadow (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaListModes(void);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaInitialize(KdCardInfo *card, VesaCardPrivPtr priv);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaCardInit(KdCardInfo *card);
|
|
||||||
|
|
||||||
int
|
|
||||||
vesaDepth (VesaModePtr mode);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaModeGood (KdScreenInfo *screen,
|
|
||||||
VesaModePtr a);
|
|
||||||
|
|
||||||
int
|
|
||||||
vesaSizeError (KdScreenInfo *screen,
|
|
||||||
VesaModePtr a);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaModeBetter (KdScreenInfo *screen,
|
|
||||||
VesaModePtr a,
|
|
||||||
VesaModePtr b);
|
|
||||||
|
|
||||||
VesaModePtr
|
|
||||||
vesaSelectMode (KdScreenInfo *screen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaScreenInit(KdScreenInfo *screen);
|
|
||||||
|
|
||||||
PixmapPtr
|
|
||||||
vesaGetPixmap (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaInitScreen(ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaFinishInitScreen(ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaCreateResources (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaSetMode (ScreenPtr pScreen,
|
|
||||||
VesaModePtr mode);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaEnable(ScreenPtr pScreen);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaDPMS (ScreenPtr pScreen, int mode);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaDisable(ScreenPtr pScreen);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaPreserve(KdCardInfo *card);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaRestore(KdCardInfo *card);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaCardFini(KdCardInfo *card);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaScreenFini(KdScreenInfo *screen);
|
|
||||||
|
|
||||||
int
|
|
||||||
vesaSetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries);
|
|
||||||
|
|
||||||
int
|
|
||||||
vesaGetPalette(VesaCardPrivPtr priv, int first, int number, U8 *entries);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs);
|
|
||||||
|
|
||||||
void
|
|
||||||
vesaUseMsg (void);
|
|
||||||
|
|
||||||
int
|
|
||||||
vesaProcessArgument (int argc, char **argv, int i);
|
|
||||||
|
|
||||||
#ifdef RANDR
|
|
||||||
Bool
|
|
||||||
vesaRandRGetInfo (ScreenPtr pScreen, Rotation *rotations);
|
|
||||||
|
|
||||||
Bool
|
|
||||||
vesaRandRSetConfig (ScreenPtr pScreen,
|
|
||||||
Rotation randr,
|
|
||||||
int rate,
|
|
||||||
RRScreenSizePtr pSize);
|
|
||||||
Bool
|
|
||||||
vesaRandRInit (ScreenPtr pScreen);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Bool
|
|
||||||
toshibaDPMS (ScreenPtr pScreen, int mode);
|
|
||||||
|
|
||||||
#endif /* _VESA_H_ */
|
|
|
@ -1,92 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright (c) 2000 by Juliusz Chroboczek
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <kdrive-config.h>
|
|
||||||
#endif
|
|
||||||
#include "vesa.h"
|
|
||||||
|
|
||||||
const KdCardFuncs vesaFuncs = {
|
|
||||||
vesaCardInit, /* cardinit */
|
|
||||||
vesaScreenInit, /* scrinit */
|
|
||||||
vesaInitScreen, /* initScreen */
|
|
||||||
vesaFinishInitScreen, /* finishInitScreen */
|
|
||||||
vesaCreateResources, /* createRes */
|
|
||||||
vesaPreserve, /* preserve */
|
|
||||||
vesaEnable, /* enable */
|
|
||||||
vesaDPMS, /* dpms */
|
|
||||||
vesaDisable, /* disable */
|
|
||||||
vesaRestore, /* restore */
|
|
||||||
vesaScreenFini, /* scrfini */
|
|
||||||
vesaCardFini, /* cardfini */
|
|
||||||
|
|
||||||
0, /* initCursor */
|
|
||||||
0, /* enableCursor */
|
|
||||||
0, /* disableCursor */
|
|
||||||
0, /* finiCursor */
|
|
||||||
0, /* recolorCursor */
|
|
||||||
|
|
||||||
0, /* initAccel */
|
|
||||||
0, /* enableAccel */
|
|
||||||
0, /* disableAccel */
|
|
||||||
0, /* finiAccel */
|
|
||||||
|
|
||||||
vesaGetColors, /* getColors */
|
|
||||||
vesaPutColors, /* putColors */
|
|
||||||
};
|
|
||||||
|
|
||||||
void
|
|
||||||
InitCard(char *name)
|
|
||||||
{
|
|
||||||
KdCardAttr attr;
|
|
||||||
KdCardInfoAdd((KdCardFuncs *) &vesaFuncs, &attr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
|
|
||||||
{
|
|
||||||
KdInitOutput (pScreenInfo, argc, argv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
InitInput (int argc, char **argv)
|
|
||||||
{
|
|
||||||
KdOsAddInputDrivers();
|
|
||||||
KdInitInput();
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
ddxUseMsg (void)
|
|
||||||
{
|
|
||||||
KdUseMsg();
|
|
||||||
vesaUseMsg();
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
ddxProcessArgument (int argc, char **argv, int i)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!(ret = vesaProcessArgument (argc, argv, i)))
|
|
||||||
ret = KdProcessArgument(argc, argv, i);
|
|
||||||
return ret;
|
|
||||||
}
|
|
|
@ -1,242 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2000 Keith Packard
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
||||||
* documentation for any purpose is hereby granted without fee, provided that
|
|
||||||
* the above copyright notice appear in all copies and that both that
|
|
||||||
* copyright notice and this permission notice appear in supporting
|
|
||||||
* documentation, and that the name of Keith Packard not be used in
|
|
||||||
* advertising or publicity pertaining to distribution of the software without
|
|
||||||
* specific, written prior permission. Keith Packard makes no
|
|
||||||
* representations about the suitability of this software for any purpose. It
|
|
||||||
* is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
||||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <kdrive-config.h>
|
|
||||||
#endif
|
|
||||||
#include "vesa.h"
|
|
||||||
|
|
||||||
static const VesaModeRec vgaModes[] = {
|
|
||||||
{
|
|
||||||
6, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
|
|
||||||
1, 1, MEMORY_PLANAR,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
640, 200, 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0xd, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
|
|
||||||
4, 4, MEMORY_PLANAR,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
320, 200, 40,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0xe, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
|
|
||||||
4, 4, MEMORY_PLANAR,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
640, 200, 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0x10, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
|
|
||||||
4, 4, MEMORY_PLANAR,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
640, 350, 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0x11, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_LINEAR,
|
|
||||||
1, 1, MEMORY_PLANAR,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
640, 480, 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0x12, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR,
|
|
||||||
4, 4, MEMORY_PLANAR,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
640, 480, 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0x13, 0,
|
|
||||||
MODE_SUPPORTED | MODE_GRAPHICS | MODE_VGA | MODE_COLOUR | MODE_LINEAR,
|
|
||||||
8, 8, MEMORY_PSEUDO,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
320, 200, 320,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
#define NUM_VGA_MODE (sizeof vgaModes / sizeof vgaModes[0])
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetNmode (Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
return NUM_VGA_MODE;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode)
|
|
||||||
{
|
|
||||||
if (nmode > NUM_VGA_MODE)
|
|
||||||
nmode = NUM_VGA_MODE;
|
|
||||||
memcpy (mode, vgaModes, nmode * sizeof (VesaModeRec));
|
|
||||||
return nmode;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaSetMode(Vm86InfoPtr vi, int mode)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
vi->vms.regs.eax = mode & 0x7f;
|
|
||||||
code = Vm86DoInterrupt (vi, 0x10);
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetMode (Vm86InfoPtr vi, int *mode)
|
|
||||||
{
|
|
||||||
*mode = Vm86Memory (vi, 0x449);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask)
|
|
||||||
{
|
|
||||||
asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4));
|
|
||||||
asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VgaSetReadPlaneMap(Vm86InfoPtr vi, int map)
|
|
||||||
{
|
|
||||||
asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce));
|
|
||||||
asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf));
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries)
|
|
||||||
{
|
|
||||||
U8 *palette_scratch;
|
|
||||||
int mark;
|
|
||||||
int palette_base;
|
|
||||||
int i, j, code;
|
|
||||||
|
|
||||||
if(number == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(first < 0 || number < 0 || first + number > 256) {
|
|
||||||
ErrorF("Cannot set %d, %d palette entries\n", first, number);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark = Vm86MarkMemory (vi);
|
|
||||||
palette_base = Vm86AllocateMemory (vi, 3 * 256);
|
|
||||||
|
|
||||||
palette_scratch = &LM(vi, palette_base);
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x1012;
|
|
||||||
vi->vms.regs.ebx = first;
|
|
||||||
vi->vms.regs.ecx = number;
|
|
||||||
vi->vms.regs.es = POINTER_SEGMENT(palette_base);
|
|
||||||
vi->vms.regs.edx = POINTER_OFFSET(palette_base);
|
|
||||||
j = 0;
|
|
||||||
i = 0;
|
|
||||||
while (number--)
|
|
||||||
{
|
|
||||||
palette_scratch[j++] = entries[i++] >> 2;
|
|
||||||
palette_scratch[j++] = entries[i++] >> 2;
|
|
||||||
palette_scratch[j++] = entries[i++] >> 2;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
code = Vm86DoInterrupt(vi, 0x10);
|
|
||||||
Vm86ReleaseMemory (vi, mark);
|
|
||||||
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries)
|
|
||||||
{
|
|
||||||
U8 *palette_scratch;
|
|
||||||
int mark;
|
|
||||||
int palette_base;
|
|
||||||
int i, j, code;
|
|
||||||
|
|
||||||
if(number == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if(first < 0 || number < 0 || first + number > 256) {
|
|
||||||
ErrorF("Cannot get %d, %d palette entries\n", first, number);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
mark = Vm86MarkMemory (vi);
|
|
||||||
palette_base = Vm86AllocateMemory (vi, 3 * 256);
|
|
||||||
|
|
||||||
palette_scratch = &LM(vi, palette_base);
|
|
||||||
|
|
||||||
vi->vms.regs.eax = 0x1017;
|
|
||||||
vi->vms.regs.ebx = first;
|
|
||||||
vi->vms.regs.ecx = number;
|
|
||||||
vi->vms.regs.es = POINTER_SEGMENT(palette_base);
|
|
||||||
vi->vms.regs.edx = POINTER_OFFSET(palette_base);
|
|
||||||
|
|
||||||
code = VbeDoInterrupt10(vi);
|
|
||||||
if(code < 0)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
i = 0;
|
|
||||||
while (number--)
|
|
||||||
{
|
|
||||||
entries[i++] = palette_scratch[j++] << 2;
|
|
||||||
entries[i++] = palette_scratch[j++] << 2;
|
|
||||||
entries[i++] = palette_scratch[j++] << 2;
|
|
||||||
entries[i++] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vm86ReleaseMemory (vi, mark);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define VGA_FB(vm) ((vm) < 8 ? 0xb8000 : 0xa0000)
|
|
||||||
|
|
||||||
void *
|
|
||||||
VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size)
|
|
||||||
{
|
|
||||||
*size = 0x10000 - bytes;
|
|
||||||
return &LM(vi,VGA_FB(vmode) + bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *ret_phys)
|
|
||||||
{
|
|
||||||
if (VGA_FB(vmode) == 0xa0000)
|
|
||||||
*size = 0x10000;
|
|
||||||
else
|
|
||||||
*size = 0x4000;
|
|
||||||
*ret_phys = VGA_FB(vmode);
|
|
||||||
return &LM(vi,VGA_FB(vmode));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
VgaUnmapFramebuffer (Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
}
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2000 Keith Packard
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
||||||
* documentation for any purpose is hereby granted without fee, provided that
|
|
||||||
* the above copyright notice appear in all copies and that both that
|
|
||||||
* copyright notice and this permission notice appear in supporting
|
|
||||||
* documentation, and that the name of Keith Packard not be used in
|
|
||||||
* advertising or publicity pertaining to distribution of the software without
|
|
||||||
* specific, written prior permission. Keith Packard makes no
|
|
||||||
* representations about the suitability of this software for any purpose. It
|
|
||||||
* is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
||||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VGA_H_
|
|
||||||
#define _VGA_H_
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetNmode (Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetModes (Vm86InfoPtr vi, VesaModePtr mode, int nmode);
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaSetMode(Vm86InfoPtr vi, int mode);
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetMode (Vm86InfoPtr vi, int *mode);
|
|
||||||
|
|
||||||
void
|
|
||||||
VgaSetWritePlaneMask(Vm86InfoPtr vi, int mask);
|
|
||||||
|
|
||||||
void
|
|
||||||
VgaSetReadPlaneMap(Vm86InfoPtr vi, int map);
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaSetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries);
|
|
||||||
|
|
||||||
int
|
|
||||||
VgaGetPalette(Vm86InfoPtr vi, int first, int number, U8 *entries);
|
|
||||||
|
|
||||||
void *
|
|
||||||
VgaSetWindow (Vm86InfoPtr vi, int vmode, int bytes, int mode, int *size);
|
|
||||||
|
|
||||||
void *
|
|
||||||
VgaMapFramebuffer (Vm86InfoPtr vi, int vmode, int *size, CARD32 *phys);
|
|
||||||
|
|
||||||
void
|
|
||||||
VgaUnmapFramebuffer (Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
#endif /* _VGA_H_ */
|
|
|
@ -1,764 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2000 Keith Packard
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
||||||
* documentation for any purpose is hereby granted without fee, provided that
|
|
||||||
* the above copyright notice appear in all copies and that both that
|
|
||||||
* copyright notice and this permission notice appear in supporting
|
|
||||||
* documentation, and that the name of Keith Packard not be used in
|
|
||||||
* advertising or publicity pertaining to distribution of the software without
|
|
||||||
* specific, written prior permission. Keith Packard makes no
|
|
||||||
* representations about the suitability of this software for any purpose. It
|
|
||||||
* is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
||||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
Copyright (c) 2000 by Juliusz Chroboczek
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
|
||||||
#include <kdrive-config.h>
|
|
||||||
#endif
|
|
||||||
#include "vm86.h"
|
|
||||||
|
|
||||||
#define PUSHW(vi, i) \
|
|
||||||
{ vi->vms.regs.esp -= 2;\
|
|
||||||
LMW(vi,MAKE_POINTER(vi->vms.regs.ss, vi->vms.regs.esp)) = i;}
|
|
||||||
|
|
||||||
static int vm86old(struct vm86_struct *vms);
|
|
||||||
static int vm86_loop(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
static const U8 rev_ints[32] =
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0,
|
|
||||||
0, 0, 0, 0, 0, 0, 0, 0x80,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const U8 retcode_data[2] =
|
|
||||||
{ 0xCD, 0xFF };
|
|
||||||
|
|
||||||
Vm86InfoPtr
|
|
||||||
Vm86Setup(int mapHoles)
|
|
||||||
{
|
|
||||||
int devmem = -1, devzero = -1;
|
|
||||||
void *magicMem, *loMem, *hiMem;
|
|
||||||
void *hole1, *hole2;
|
|
||||||
U32 stack_base, ret_code;
|
|
||||||
Vm86InfoPtr vi = NULL;
|
|
||||||
|
|
||||||
devmem = open("/dev/mem", O_RDWR);
|
|
||||||
if(devmem < 0) {
|
|
||||||
perror("open /dev/mem");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
devzero = open("/dev/zero", O_RDWR);
|
|
||||||
if(devzero < 0) {
|
|
||||||
perror("open /dev/zero");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
magicMem = MAP_FAILED;
|
|
||||||
loMem = MAP_FAILED;
|
|
||||||
hiMem = MAP_FAILED;
|
|
||||||
hole1 = MAP_FAILED;
|
|
||||||
hole2 = MAP_FAILED;
|
|
||||||
|
|
||||||
|
|
||||||
magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE,
|
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
||||||
MAP_PRIVATE | MAP_FIXED, devmem, MAGICMEM_BASE);
|
|
||||||
|
|
||||||
if(magicMem == MAP_FAILED) {
|
|
||||||
ErrorF("Couldn't map magic memory\n");
|
|
||||||
goto unmapfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mapHoles) {
|
|
||||||
hole1 = mmap((void*)HOLE1_BASE, HOLE1_SIZE,
|
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
||||||
MAP_PRIVATE | MAP_FIXED, devzero, HOLE1_BASE);
|
|
||||||
|
|
||||||
if(hole1 == MAP_FAILED) {
|
|
||||||
ErrorF("Couldn't map first hole\n");
|
|
||||||
goto unmapfail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE,
|
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
||||||
MAP_PRIVATE | MAP_FIXED, devzero, LOMEM_BASE);
|
|
||||||
if(loMem == MAP_FAILED) {
|
|
||||||
ErrorF("Couldn't map low memory\n");
|
|
||||||
munmap(magicMem, MAGICMEM_SIZE);
|
|
||||||
goto unmapfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mapHoles) {
|
|
||||||
hole2 = mmap((void*)HOLE2_BASE, HOLE2_SIZE,
|
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
||||||
MAP_PRIVATE | MAP_FIXED, devzero, HOLE2_BASE);
|
|
||||||
|
|
||||||
if(hole2 == MAP_FAILED) {
|
|
||||||
ErrorF("Couldn't map first hole\n");
|
|
||||||
goto unmapfail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE,
|
|
||||||
PROT_READ | PROT_WRITE | PROT_EXEC,
|
|
||||||
MAP_SHARED | MAP_FIXED,
|
|
||||||
devmem, HIMEM_BASE);
|
|
||||||
if(hiMem == MAP_FAILED) {
|
|
||||||
ErrorF("Couldn't map high memory\n");
|
|
||||||
goto unmapfail;
|
|
||||||
}
|
|
||||||
|
|
||||||
vi = xalloc(sizeof(Vm86InfoRec));
|
|
||||||
if (!vi)
|
|
||||||
goto unmapfail;
|
|
||||||
|
|
||||||
vi->magicMem = magicMem;
|
|
||||||
vi->hole1 = hole1;
|
|
||||||
vi->loMem = loMem;
|
|
||||||
vi->hole2 = hole2;
|
|
||||||
vi->hiMem = hiMem;
|
|
||||||
vi->brk = LOMEM_BASE;
|
|
||||||
|
|
||||||
stack_base = Vm86AllocateMemory(vi, STACK_SIZE);
|
|
||||||
if(stack_base == ALLOC_FAIL)
|
|
||||||
goto unmapfail;
|
|
||||||
ret_code = Vm86AllocateMemory(vi, sizeof(retcode_data));
|
|
||||||
if(ret_code == ALLOC_FAIL)
|
|
||||||
goto unmapfail;
|
|
||||||
|
|
||||||
vi->stack_base = stack_base;
|
|
||||||
vi->ret_code = ret_code;
|
|
||||||
|
|
||||||
memset(&vi->vms, 0, sizeof(struct vm86_struct));
|
|
||||||
vi->vms.flags = 0;
|
|
||||||
vi->vms.screen_bitmap = 0;
|
|
||||||
vi->vms.cpu_type = CPU_586;
|
|
||||||
memcpy(&vi->vms.int_revectored, rev_ints, sizeof(rev_ints));
|
|
||||||
|
|
||||||
iopl(3);
|
|
||||||
|
|
||||||
if(devmem >= 0)
|
|
||||||
close(devmem);
|
|
||||||
if(devzero >= 0)
|
|
||||||
close(devzero);
|
|
||||||
|
|
||||||
return vi;
|
|
||||||
|
|
||||||
unmapfail:
|
|
||||||
if(magicMem != MAP_FAILED) munmap(magicMem, MAGICMEM_SIZE);
|
|
||||||
if(hole1 != MAP_FAILED) munmap(hole1, HOLE1_SIZE);
|
|
||||||
if(loMem != MAP_FAILED) munmap(loMem, LOMEM_SIZE);
|
|
||||||
if(hole2 != MAP_FAILED) munmap(hole2, HOLE2_SIZE);
|
|
||||||
if(hiMem != MAP_FAILED) munmap(hiMem, HIMEM_SIZE);
|
|
||||||
fail:
|
|
||||||
if(devmem >= 0)
|
|
||||||
close(devmem);
|
|
||||||
if(devzero >= 0)
|
|
||||||
close(devzero);
|
|
||||||
if(vi)
|
|
||||||
xfree(vi);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86Cleanup(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
if(vi->magicMem != MAP_FAILED) munmap(vi->magicMem, MAGICMEM_SIZE);
|
|
||||||
if(vi->hole1 != MAP_FAILED) munmap(vi->hole1, HOLE1_SIZE);
|
|
||||||
if(vi->loMem != MAP_FAILED) munmap(vi->loMem, LOMEM_SIZE);
|
|
||||||
if(vi->hole2 != MAP_FAILED) munmap(vi->hole2, HOLE2_SIZE);
|
|
||||||
if(vi->hiMem != MAP_FAILED) munmap(vi->hiMem, HIMEM_SIZE);
|
|
||||||
xfree(vi);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86DoInterrupt(Vm86InfoPtr vi, int num)
|
|
||||||
{
|
|
||||||
U16 seg, off;
|
|
||||||
int code;
|
|
||||||
|
|
||||||
if(num < 0 || num>256) {
|
|
||||||
ErrorF("Interrupt %d doesn't exist\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
seg = MMW(vi,num * 4 + 2);
|
|
||||||
off = MMW(vi,num * 4);
|
|
||||||
if(MAKE_POINTER(seg, off) < ROM_BASE ||
|
|
||||||
MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) {
|
|
||||||
ErrorF("Interrupt pointer (seg %x off %x) doesn't point at ROM\n",
|
|
||||||
seg, off);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data));
|
|
||||||
vi->vms.regs.eflags = IF_MASK | IOPL_MASK;
|
|
||||||
vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base);
|
|
||||||
vi->vms.regs.esp = STACK_SIZE;
|
|
||||||
PUSHW(vi, IF_MASK | IOPL_MASK);
|
|
||||||
PUSHW(vi, POINTER_SEGMENT(vi->ret_code));
|
|
||||||
PUSHW(vi, POINTER_OFFSET(vi->ret_code));
|
|
||||||
vi->vms.regs.cs = seg;
|
|
||||||
vi->vms.regs.eip = off;
|
|
||||||
OsBlockSignals ();
|
|
||||||
code = vm86_loop(vi);
|
|
||||||
OsReleaseSignals ();
|
|
||||||
if(code != 0)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86DoPOST(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
U16 seg, off;
|
|
||||||
int code;
|
|
||||||
|
|
||||||
seg = 0xC000;
|
|
||||||
off = 3;
|
|
||||||
if(MAKE_POINTER(seg, off) < ROM_BASE ||
|
|
||||||
MAKE_POINTER(seg, off) >= ROM_BASE + ROM_SIZE) {
|
|
||||||
ErrorF("BIOS pointer (seg %x off %x) doesn't point at ROM\n",
|
|
||||||
seg, off);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(&(LM(vi,vi->ret_code)), retcode_data, sizeof(retcode_data));
|
|
||||||
vi->vms.regs.ss = POINTER_SEGMENT(vi->stack_base);
|
|
||||||
vi->vms.regs.esp = STACK_SIZE;
|
|
||||||
PUSHW(vi, POINTER_SEGMENT(vi->ret_code));
|
|
||||||
PUSHW(vi, POINTER_OFFSET(vi->ret_code));
|
|
||||||
vi->vms.regs.cs = seg;
|
|
||||||
vi->vms.regs.eip = off;
|
|
||||||
OsBlockSignals ();
|
|
||||||
code = vm86_loop(vi);
|
|
||||||
OsReleaseSignals ();
|
|
||||||
if(code != 0)
|
|
||||||
return -1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define DEBUG_VBE 0
|
|
||||||
#if DEBUG_VBE
|
|
||||||
#define DBG(x) ErrorF x; usleep(10*1000)
|
|
||||||
#else
|
|
||||||
#define DBG(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline U8
|
|
||||||
vm86_inb(U16 port)
|
|
||||||
{
|
|
||||||
U8 value;
|
|
||||||
|
|
||||||
if (port != 0x3da)
|
|
||||||
{
|
|
||||||
DBG(("inb 0x%04x", port));
|
|
||||||
}
|
|
||||||
asm volatile ("inb %w1,%b0" : "=a" (value) : "d" (port));
|
|
||||||
if (port != 0x3da)
|
|
||||||
{
|
|
||||||
DBG((" = 0x%02x\n", value));
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline U16
|
|
||||||
vm86_inw(U16 port)
|
|
||||||
{
|
|
||||||
U16 value;
|
|
||||||
DBG(("inw 0x%04x", port));
|
|
||||||
asm volatile ("inw %w1,%w0" : "=a" (value) : "d" (port));
|
|
||||||
DBG((" = 0x%04x\n", value));
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline U32
|
|
||||||
vm86_inl(U16 port)
|
|
||||||
{
|
|
||||||
U32 value;
|
|
||||||
DBG(("inl 0x%04x", port));
|
|
||||||
asm volatile ("inl %w1,%0" : "=a" (value) : "d" (port));
|
|
||||||
DBG((" = 0x%08x\n", value));
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
vm86_outb(U16 port, U8 value)
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
static U8 CR;
|
|
||||||
|
|
||||||
if (port == 0x3d4)
|
|
||||||
CR = value;
|
|
||||||
if (port == 0x3d5 && CR == 0xa4)
|
|
||||||
{
|
|
||||||
DBG(("outb 0x%04x = 0x%02x (skipped)\n", port, value));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
DBG(("outb 0x%04x = 0x%02x\n", port, value));
|
|
||||||
asm volatile ("outb %b0,%w1" : : "a" (value), "d" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
vm86_outw(U16 port, U16 value)
|
|
||||||
{
|
|
||||||
DBG(("outw 0x%04x = 0x%04x\n", port, value));
|
|
||||||
asm volatile ("outw %w0,%w1" : : "a" (value), "d" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void
|
|
||||||
vm86_outl(U16 port, U32 value)
|
|
||||||
{
|
|
||||||
DBG(("outl 0x%04x = 0x%08x\n", port, value));
|
|
||||||
asm volatile ("outl %0,%w1" : : "a" (value), "d" (port));
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SEG_CS 1
|
|
||||||
#define SEG_DS 2
|
|
||||||
#define SEG_ES 3
|
|
||||||
#define SEG_SS 4
|
|
||||||
#define SEG_GS 5
|
|
||||||
#define SEG_FS 6
|
|
||||||
#define REP 1
|
|
||||||
#define REPNZ 2
|
|
||||||
#define SET_8(_x, _y) (_x) = ((_x) & ~0xFF) | ((_y) & 0xFF);
|
|
||||||
#define SET_16(_x, _y) (_x) = ((_x) & ~0xFFFF) | ((_y) & 0xFFFF);
|
|
||||||
#define INC_IP(_i) SET_16(regs->eip, (regs->eip + _i))
|
|
||||||
#define AGAIN INC_IP(1); goto again;
|
|
||||||
|
|
||||||
static int
|
|
||||||
vm86_emulate(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
struct vm86_regs *regs = &vi->vms.regs;
|
|
||||||
U8 opcode;
|
|
||||||
int size;
|
|
||||||
int pref_seg = 0, pref_rep = 0, pref_66 = 0, pref_67 = 0;
|
|
||||||
|
|
||||||
again:
|
|
||||||
if(!Vm86IsMemory(vi, MAKE_POINTER(regs->cs, regs->eip))) {
|
|
||||||
ErrorF("Trying to execute unmapped memory\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
opcode = Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip));
|
|
||||||
switch(opcode) {
|
|
||||||
case 0x2E: pref_seg = SEG_CS; AGAIN;
|
|
||||||
case 0x3E: pref_seg = SEG_DS; AGAIN;
|
|
||||||
case 0x26: pref_seg = SEG_ES; AGAIN;
|
|
||||||
case 0x36: pref_seg = SEG_SS; AGAIN;
|
|
||||||
case 0x65: pref_seg = SEG_GS; AGAIN;
|
|
||||||
case 0x64: pref_seg = SEG_FS; AGAIN;
|
|
||||||
case 0x66: pref_66 = 1; AGAIN;
|
|
||||||
case 0x67: pref_67 = 1; AGAIN;
|
|
||||||
case 0xF2: pref_rep = REPNZ; AGAIN;
|
|
||||||
case 0xF3: pref_rep = REP; AGAIN;
|
|
||||||
|
|
||||||
case 0xEC: /* IN AL, DX */
|
|
||||||
SET_8(regs->eax, vm86_inb(regs->edx & 0xFFFF));
|
|
||||||
INC_IP(1);
|
|
||||||
break;
|
|
||||||
case 0xED: /* IN AX, DX */
|
|
||||||
if(pref_66)
|
|
||||||
regs->eax = vm86_inl(regs->edx & 0xFFFF);
|
|
||||||
else
|
|
||||||
SET_16(regs->eax, vm86_inw(regs->edx & 0xFFFF));
|
|
||||||
INC_IP(1);
|
|
||||||
break;
|
|
||||||
case 0xE4: /* IN AL, imm8 */
|
|
||||||
SET_8(regs->eax,
|
|
||||||
vm86_inb(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1))));
|
|
||||||
INC_IP(2);
|
|
||||||
break;
|
|
||||||
case 0xE5: /* IN AX, imm8 */
|
|
||||||
if(pref_66)
|
|
||||||
regs->eax =
|
|
||||||
vm86_inl(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)));
|
|
||||||
else
|
|
||||||
SET_16(regs->eax,
|
|
||||||
vm86_inw(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1))));
|
|
||||||
INC_IP(2);
|
|
||||||
break;
|
|
||||||
case 0x6C: /* INSB */
|
|
||||||
case 0x6D: /* INSW */
|
|
||||||
if(opcode == 0x6C) {
|
|
||||||
Vm86WriteMemory(vi, MAKE_POINTER(regs->es, regs->edi),
|
|
||||||
vm86_inb(regs->edx & 0xFFFF));
|
|
||||||
size = 1;
|
|
||||||
} else if(pref_66) {
|
|
||||||
Vm86WriteMemoryL(vi, MAKE_POINTER(regs->es, regs->edi),
|
|
||||||
vm86_inl(regs->edx & 0xFFFF));
|
|
||||||
size = 4;
|
|
||||||
} else {
|
|
||||||
Vm86WriteMemoryW(vi, MAKE_POINTER(regs->es, regs->edi),
|
|
||||||
vm86_inw(regs->edx & 0xFFFF));
|
|
||||||
size = 2;
|
|
||||||
}
|
|
||||||
if(regs->eflags & (1<<10))
|
|
||||||
regs->edi -= size;
|
|
||||||
else
|
|
||||||
regs->edi += size;
|
|
||||||
if(pref_rep) {
|
|
||||||
if(pref_66) {
|
|
||||||
regs->ecx--;
|
|
||||||
if(regs->ecx != 0)
|
|
||||||
goto again;
|
|
||||||
} else {
|
|
||||||
SET_16(regs->ecx, regs->ecx - 1);
|
|
||||||
if((regs->ecx & 0xFFFF) != 0)
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
INC_IP(1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0xEE: /* OUT DX, AL */
|
|
||||||
vm86_outb(regs->edx & 0xFFFF, regs->eax & 0xFF);
|
|
||||||
INC_IP(1);
|
|
||||||
break;
|
|
||||||
case 0xEF: /* OUT DX, AX */
|
|
||||||
if(pref_66)
|
|
||||||
vm86_outl(regs->edx & 0xFFFF, regs->eax);
|
|
||||||
else
|
|
||||||
vm86_outw(regs->edx & 0xFFFF, regs->eax & 0xFFFF);
|
|
||||||
INC_IP(1);
|
|
||||||
break;
|
|
||||||
case 0xE6: /* OUT imm8, AL */
|
|
||||||
vm86_outb(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)),
|
|
||||||
regs->eax & 0xFF);
|
|
||||||
INC_IP(2);
|
|
||||||
break;
|
|
||||||
case 0xE7: /* OUT imm8, AX */
|
|
||||||
if(pref_66)
|
|
||||||
vm86_outl(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)),
|
|
||||||
regs->eax);
|
|
||||||
else
|
|
||||||
vm86_outw(Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip+1)),
|
|
||||||
regs->eax & 0xFFFF);
|
|
||||||
INC_IP(2);
|
|
||||||
break;
|
|
||||||
case 0x6E: /* OUTSB */
|
|
||||||
case 0x6F: /* OUTSW */
|
|
||||||
if(opcode == 0x6E) {
|
|
||||||
vm86_outb(regs->edx & 0xFFFF,
|
|
||||||
Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi)));
|
|
||||||
size = 1;
|
|
||||||
} else if(pref_66) {
|
|
||||||
vm86_outl(regs->edx & 0xFFFF,
|
|
||||||
Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi)));
|
|
||||||
size = 4;
|
|
||||||
} else {
|
|
||||||
vm86_outw(regs->edx & 0xFFFF,
|
|
||||||
Vm86Memory(vi, MAKE_POINTER(regs->es, regs->edi)));
|
|
||||||
size = 2;
|
|
||||||
}
|
|
||||||
if(regs->eflags & (1<<10))
|
|
||||||
regs->edi -= size;
|
|
||||||
else
|
|
||||||
regs->edi += size;
|
|
||||||
if(pref_rep) {
|
|
||||||
if(pref_66) {
|
|
||||||
regs->ecx--;
|
|
||||||
if(regs->ecx != 0)
|
|
||||||
goto again;
|
|
||||||
} else {
|
|
||||||
SET_16(regs->ecx, regs->ecx - 1);
|
|
||||||
if((regs->ecx & 0xFFFF) != 0)
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
INC_IP(1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x0F:
|
|
||||||
ErrorF("Hit 0F trap in VM86 code\n");
|
|
||||||
return -1;
|
|
||||||
case 0xF0:
|
|
||||||
ErrorF("Hit lock prefix in VM86 code\n");
|
|
||||||
return -1;
|
|
||||||
case 0xF4:
|
|
||||||
ErrorF("Hit HLT in VM86 code\n");
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
default:
|
|
||||||
ErrorF("Unhandled GP fault in VM86 code (opcode = 0x%02X)\n",
|
|
||||||
opcode);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#undef SEG_CS
|
|
||||||
#undef SEG_DS
|
|
||||||
#undef SEG_ES
|
|
||||||
#undef SEG_SS
|
|
||||||
#undef SEG_GS
|
|
||||||
#undef SEG_FS
|
|
||||||
#undef REP
|
|
||||||
#undef REPNZ
|
|
||||||
#undef SET_8
|
|
||||||
#undef SET_16
|
|
||||||
#undef INC_IP
|
|
||||||
#undef AGAIN
|
|
||||||
|
|
||||||
static int
|
|
||||||
vm86_loop(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
int code;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
code = vm86old(&vi->vms);
|
|
||||||
switch(VM86_TYPE(code)) {
|
|
||||||
case VM86_SIGNAL:
|
|
||||||
continue;
|
|
||||||
case VM86_UNKNOWN:
|
|
||||||
code = vm86_emulate(vi);
|
|
||||||
if(code < 0) {
|
|
||||||
Vm86Debug(vi);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VM86_INTx:
|
|
||||||
if(VM86_ARG(code) == 0xFF)
|
|
||||||
return 0;
|
|
||||||
else {
|
|
||||||
PUSHW(vi, vi->vms.regs.eflags)
|
|
||||||
PUSHW(vi, vi->vms.regs.cs);
|
|
||||||
PUSHW(vi, vi->vms.regs.eip);
|
|
||||||
vi->vms.regs.cs = MMW(vi,VM86_ARG(code) * 4 + 2);
|
|
||||||
vi->vms.regs.eip = MMW(vi,VM86_ARG(code) * 4);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VM86_STI:
|
|
||||||
ErrorF("VM86 code enabled interrupts\n");
|
|
||||||
Vm86Debug(vi);
|
|
||||||
return -1;
|
|
||||||
default:
|
|
||||||
if(code < 0) {
|
|
||||||
if(errno == ENOSYS) {
|
|
||||||
ErrorF("No vm86 support. Are you running on AMD64?\n");
|
|
||||||
} else {
|
|
||||||
ErrorF("vm86 failed (%s).\n", strerror(errno));
|
|
||||||
Vm86Debug(vi);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ErrorF("Unexpected result code 0x%X from vm86\n", code);
|
|
||||||
Vm86Debug(vi);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86IsMemory(Vm86InfoPtr vi, U32 i)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
return 1;
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
return 1;
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
return 1;
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
U8
|
|
||||||
Vm86Memory(Vm86InfoPtr vi, U32 i)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
return MM(vi, i);
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
return LM(vi, i);
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
return HM(vi, i);
|
|
||||||
else {
|
|
||||||
ErrorF("Reading unmapped memory at 0x%08X\n", i);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
U16
|
|
||||||
Vm86MemoryW(Vm86InfoPtr vi, U32 i)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
return MMW(vi, i);
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
return LMW(vi, i);
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
return HMW(vi, i);
|
|
||||||
else {
|
|
||||||
ErrorF("Reading unmapped memory at 0x%08X\n", i);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
U32
|
|
||||||
Vm86MemoryL(Vm86InfoPtr vi, U32 i)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
return MML(vi, i);
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
return LML(vi, i);
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
return HML(vi, i);
|
|
||||||
else {
|
|
||||||
ErrorF("Reading unmapped memory at 0x%08X\n", i);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86WriteMemory(Vm86InfoPtr vi, U32 i, U8 val)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
MM(vi, i) = val;
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
LM(vi, i) = val;
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
HM(vi, i) = val;
|
|
||||||
else {
|
|
||||||
ErrorF("Writing unmapped memory at 0x%08X\n", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86WriteMemoryW(Vm86InfoPtr vi, U32 i, U16 val)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
MMW(vi, i) = val;
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
LMW(vi, i) = val;
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
HMW(vi, i) = val;
|
|
||||||
else {
|
|
||||||
ErrorF("Writing unmapped memory at 0x%08X\n", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86WriteMemoryL(Vm86InfoPtr vi, U32 i, U32 val)
|
|
||||||
{
|
|
||||||
if(i >= MAGICMEM_BASE && i< MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
MML(vi, i) = val;
|
|
||||||
else if(i >= LOMEM_BASE && i< LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
LML(vi, i) = val;
|
|
||||||
else if(i >= HIMEM_BASE && i< HIMEM_BASE + HIMEM_SIZE)
|
|
||||||
HML(vi, i) = val;
|
|
||||||
else {
|
|
||||||
ErrorF("Writing unmapped memory at 0x%08X\n", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86AllocateMemory(Vm86InfoPtr vi, int n)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
if(n<0) {
|
|
||||||
ErrorF("Asked to allocate negative amount of memory\n");
|
|
||||||
return vi->brk;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = (n + 15) & ~15;
|
|
||||||
if(vi->brk + n > LOMEM_BASE + LOMEM_SIZE) {
|
|
||||||
ErrorF("Out of low memory\n");
|
|
||||||
exit(2);
|
|
||||||
}
|
|
||||||
ret = vi->brk;
|
|
||||||
vi->brk += n;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86MarkMemory (Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
return vi->brk;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86ReleaseMemory (Vm86InfoPtr vi, int mark)
|
|
||||||
{
|
|
||||||
vi->brk = mark;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
vm86old(struct vm86_struct *vm)
|
|
||||||
{
|
|
||||||
int res;
|
|
||||||
|
|
||||||
asm volatile (
|
|
||||||
"pushl %%ebx\n\t"
|
|
||||||
"movl %2, %%ebx\n\t"
|
|
||||||
"movl %1,%%eax\n\t"
|
|
||||||
"int $0x80\n\t"
|
|
||||||
"popl %%ebx"
|
|
||||||
: "=a" (res) : "n" (113), "r" (vm));
|
|
||||||
if(res < 0) {
|
|
||||||
errno = -res;
|
|
||||||
res = -1;
|
|
||||||
} else
|
|
||||||
errno = 0;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86Debug(Vm86InfoPtr vi)
|
|
||||||
{
|
|
||||||
struct vm86_regs *regs = &vi->vms.regs;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
ErrorF("eax=0x%08lX ebx=0x%08lX ecx=0x%08lX edx=0x%08lX\n",
|
|
||||||
regs->eax, regs->ebx, regs->ecx, regs->edx);
|
|
||||||
ErrorF("esi=0x%08lX edi=0x%08lX ebp=0x%08lX\n",
|
|
||||||
regs->esi, regs->edi, regs->ebp);
|
|
||||||
ErrorF("eip=0x%08lX esp=0x%08lX eflags=0x%08lX\n",
|
|
||||||
regs->eip, regs->esp, regs->eflags);
|
|
||||||
ErrorF("cs=0x%04lX ds=0x%04lX es=0x%04lX fs=0x%04lX gs=0x%04lX\n",
|
|
||||||
regs->cs, regs->ds, regs->es, regs->fs, regs->gs);
|
|
||||||
for(i=-7; i<8; i++) {
|
|
||||||
ErrorF(" %s%02X",
|
|
||||||
i==0?"->":"",
|
|
||||||
Vm86Memory(vi, MAKE_POINTER(regs->cs, regs->eip + i)));
|
|
||||||
}
|
|
||||||
ErrorF("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef NOT_IN_X_SERVER
|
|
||||||
static void
|
|
||||||
ErrorF(char *f, ...)
|
|
||||||
{
|
|
||||||
va_list args;
|
|
||||||
va_start(args, f);
|
|
||||||
vfprintf(stderr, f, args);
|
|
||||||
va_end(args);
|
|
||||||
}
|
|
||||||
#endif
|
|
|
@ -1,173 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright © 2000 Keith Packard
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, distribute, and sell this software and its
|
|
||||||
* documentation for any purpose is hereby granted without fee, provided that
|
|
||||||
* the above copyright notice appear in all copies and that both that
|
|
||||||
* copyright notice and this permission notice appear in supporting
|
|
||||||
* documentation, and that the name of Keith Packard not be used in
|
|
||||||
* advertising or publicity pertaining to distribution of the software without
|
|
||||||
* specific, written prior permission. Keith Packard makes no
|
|
||||||
* representations about the suitability of this software for any purpose. It
|
|
||||||
* is provided "as is" without express or implied warranty.
|
|
||||||
*
|
|
||||||
* KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
|
||||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
|
|
||||||
* EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
|
|
||||||
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
||||||
* DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
|
|
||||||
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
||||||
* PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
Copyright (c) 2000 by Juliusz Chroboczek
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _VM86_H_
|
|
||||||
#define _VM86_H_
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/mman.h>
|
|
||||||
#include <sys/vm86.h>
|
|
||||||
#include <sys/io.h>
|
|
||||||
|
|
||||||
#ifdef NOT_IN_X_SERVER
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <malloc.h>
|
|
||||||
static void ErrorF(char*, ...);
|
|
||||||
#define xalloc(a) malloc(a)
|
|
||||||
#define xcalloc(a,b) calloc(a,b)
|
|
||||||
#define xfree(a) free(a)
|
|
||||||
#else
|
|
||||||
#include <X11/X.h>
|
|
||||||
#include <X11/Xproto.h>
|
|
||||||
#include <X11/Xos.h>
|
|
||||||
#include "os.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef unsigned char U8;
|
|
||||||
typedef unsigned short U16;
|
|
||||||
typedef unsigned int U32;
|
|
||||||
|
|
||||||
/* The whole addressable memory */
|
|
||||||
#define SYSMEM_BASE 0x00000
|
|
||||||
#define SYSMEM_SIZE 0x100000
|
|
||||||
|
|
||||||
/* Interrupt vectors and BIOS data area */
|
|
||||||
/* This is allocated privately from /dev/mem */
|
|
||||||
#define MAGICMEM_BASE 0x00000
|
|
||||||
#define MAGICMEM_SIZE 0x01000
|
|
||||||
|
|
||||||
/* The low memory, allocated privately from /dev/zero */
|
|
||||||
/* 64KB should be enough for anyone, as they used to say */
|
|
||||||
#define LOMEM_BASE 0x10000
|
|
||||||
#define LOMEM_SIZE 0x10000
|
|
||||||
|
|
||||||
/* The video memory and BIOS ROM, allocated shared from /dev/mem */
|
|
||||||
#define HIMEM_BASE 0xA0000
|
|
||||||
#define HIMEM_SIZE (SYSMEM_BASE + SYSMEM_SIZE - HIMEM_BASE)
|
|
||||||
|
|
||||||
#define HOLE1_BASE (MAGICMEM_BASE + MAGICMEM_SIZE)
|
|
||||||
#define HOLE1_SIZE (LOMEM_BASE - HOLE1_BASE)
|
|
||||||
|
|
||||||
#define HOLE2_BASE (LOMEM_BASE + LOMEM_SIZE)
|
|
||||||
#define HOLE2_SIZE (HIMEM_BASE - HOLE2_BASE)
|
|
||||||
|
|
||||||
/* The BIOS ROM */
|
|
||||||
#define ROM_BASE 0xC0000
|
|
||||||
#define ROM_SIZE 0x30000
|
|
||||||
|
|
||||||
#define STACK_SIZE 0x1000
|
|
||||||
|
|
||||||
#define POINTER_SEGMENT(ptr) (((unsigned int)ptr)>>4)
|
|
||||||
#define POINTER_OFFSET(ptr) (((unsigned int)ptr)&0x000F)
|
|
||||||
#define MAKE_POINTER(seg, off) (((((unsigned int)(seg))<<4) + (unsigned int)(off)))
|
|
||||||
#define MAKE_POINTER_1(lw) MAKE_POINTER(((lw)&0xFFFF0000)/0x10000, (lw)&0xFFFF)
|
|
||||||
#define ALLOC_FAIL ((U32)-1)
|
|
||||||
|
|
||||||
typedef struct _Vm86InfoRec {
|
|
||||||
void *magicMem, *loMem, *hiMem;
|
|
||||||
void *hole1, *hole2;
|
|
||||||
U32 brk;
|
|
||||||
struct vm86_struct vms;
|
|
||||||
U32 ret_code, stack_base;
|
|
||||||
} Vm86InfoRec, *Vm86InfoPtr;
|
|
||||||
|
|
||||||
#define LM(vi,i) (((char*)vi->loMem)[i-LOMEM_BASE])
|
|
||||||
#define LMW(vi,i) (*(U16*)(&LM(vi,i)))
|
|
||||||
#define LML(vi,i) (*(U32*)(&LM(vi,i)))
|
|
||||||
#define MM(vi,i) (((char*)vi->magicMem)[i-MAGICMEM_BASE])
|
|
||||||
#define MMW(vi,i) (*(U16*)(&MM(vi,i)))
|
|
||||||
#define MML(vi,i) (*(U32*)(&MM(vi,i)))
|
|
||||||
#define HM(vi,i) (((char*)vi->hiMem)[i-HIMEM_BASE])
|
|
||||||
#define HMW(vi,i) (*(U16*)(&MM(vi,i)))
|
|
||||||
#define HML(vi,i) (*(U32*)(&MM(vi,i)))
|
|
||||||
|
|
||||||
Vm86InfoPtr
|
|
||||||
Vm86Setup(int);
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86Cleanup(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86DoInterrupt(Vm86InfoPtr vi, int num);
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86DoPOST(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86IsMemory(Vm86InfoPtr vi, U32 i);
|
|
||||||
|
|
||||||
U8
|
|
||||||
Vm86Memory(Vm86InfoPtr, U32);
|
|
||||||
|
|
||||||
U16
|
|
||||||
Vm86MemoryW(Vm86InfoPtr, U32);
|
|
||||||
|
|
||||||
U32
|
|
||||||
Vm86MemoryL(Vm86InfoPtr, U32);
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86WriteMemory(Vm86InfoPtr, U32, U8);
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86WriteMemoryW(Vm86InfoPtr, U32, U16);
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86WriteMemoryL(Vm86InfoPtr, U32, U32);
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86AllocateMemory(Vm86InfoPtr, int);
|
|
||||||
|
|
||||||
int
|
|
||||||
Vm86MarkMemory (Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86ReleaseMemory (Vm86InfoPtr vi, int mark);
|
|
||||||
|
|
||||||
void
|
|
||||||
Vm86Debug(Vm86InfoPtr vi);
|
|
||||||
|
|
||||||
#endif /* _VM86_H_ */
|
|
Loading…
Reference in New Issue
Block a user