Rework vesa driver for shadowing and multiple screen support. Allow enable

to fail and avoid crashing
This commit is contained in:
Keith Packard 2000-09-03 05:11:46 +00:00
parent 3805965684
commit c97fb611dd
28 changed files with 859 additions and 211 deletions

13
hw/kdrive/Kdrive.tmpl Normal file
View File

@ -0,0 +1,13 @@
XCOMM $XFree86$
#include <Server.tmpl>
#if BuildRender
RENDERINCS=-I$(KDRIVE)/../../render -I$(EXTINCSRC)
#endif
KDINCS = -I$(KDRIVE) -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I$(KDRIVE)/../../fb -I$(KDRIVE)/../../mi \
-I$(KDRIVE)/../../miext/shadow \
-I$(KDRIVE)/../../include -I$(KDRIVE)/../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC) $(RENDERINCS)

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = fbdev.c fbinit.c
OBJS = fbdev.o fbinit.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = $(KDINCS) -I.
NormalLibraryObjectRule()
NormalLibraryTarget(fbdev,$(OBJS))

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.2 1999/12/30 03:03:08 robin Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.c,v 1.4 2000/05/06 22:17:41 keithp Exp $ */
#include "fbdev.h"
@ -136,7 +136,7 @@ fbdevPreserve (KdCardInfo *card)
{
}
void
Bool
fbdevEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
@ -148,7 +148,11 @@ fbdevEnable (ScreenPtr pScreen)
/* display it on the LCD */
k = ioctl (priv->fd, FBIOPUT_VSCREENINFO, &priv->var);
if (k < 0)
{
perror ("FBIOPUT_VSCREENINFO");
return FALSE;
}
return TRUE;
}
Bool

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h,v 1.2 1999/12/30 03:03:08 robin Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/fbdev/fbdev.h,v 1.4 2000/05/06 22:17:42 keithp Exp $ */
#ifndef _FBDEV_H_
#define _FBDEV_H_
@ -56,7 +56,7 @@ fbdevInitScreen (ScreenPtr pScreen);
void
fbdevPreserve (KdCardInfo *card);
void
Bool
fbdevEnable (ScreenPtr pScreen);
Bool

View File

@ -1,13 +1,12 @@
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/igs/Imakefile,v 1.1 2000/05/06 22:17:42 keithp Exp $
#include <Server.tmpl>
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/igs/Imakefile,v 1.2 2000/05/24 23:52:47 keithp Exp $
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = igs.c igscmap.c igscurs.c igsdraw.c igsreg.c igsstub.c
OBJS = igs.o igscmap.o igscurs.o igsdraw.o igsreg.o igsstub.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(igs,$(OBJS))

View File

@ -1,5 +1,5 @@
/*
* $XFree86: xc/programs/Xserver/hw/kdrive/igs/igs.c,v 1.1 2000/05/06 22:17:43 keithp Exp $
* $XFree86: xc/programs/Xserver/hw/kdrive/igs/igs.c,v 1.2 2000/05/24 23:52:47 keithp Exp $
*
* Copyright © 1999 SuSE, Inc.
*
@ -331,7 +331,7 @@ igsGetClock (int target, int *Mp, int *Np, int *Pp, int maxM, int maxN, int maxP
*Pp = P;
}
void
Bool
igsEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
@ -562,6 +562,7 @@ igsEnable (ScreenPtr pScreen)
VgaFetch (&igsvga->card, reg));
}
#endif
return TRUE;
}
Bool

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = itsy.c ts.c kbd.c
OBJS = itsy.o ts.o kbd.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(itsy,$(OBJS))

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = keyboard.c linux.c ps2.c
OBJS = keyboard.o linux.o ps2.o
INCLUDES = -I. -I.. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(linux,$(OBJS))

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = s3.c s3clock.c s3cmap.c s3curs.c s3draw.c s3gc.c s3reg.c s3stub.c
OBJS = s3.o s3clock.o s3cmap.o s3curs.o s3draw.o s3gc.o s3reg.o s3stub.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(savage,$(OBJS))

View File

@ -964,7 +964,7 @@ s3SetGlobalBitmap (ScreenPtr pScreen, int ma)
}
}
void
Bool
s3Enable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
@ -1667,6 +1667,7 @@ s3Enable (ScreenPtr pScreen)
}
}
#endif
return TRUE;
}
void

View File

@ -463,7 +463,7 @@ typedef struct _s3ScreenInfo {
Bool s3CardInit (KdCardInfo *);
Bool s3ScreenInit (KdScreenInfo *);
void s3Enable (ScreenPtr pScreen);
Bool s3Enable (ScreenPtr pScreen);
void s3Disable (ScreenPtr pScreen);
void s3Fini (ScreenPtr pScreen);

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = sis.c sisclock.c siscmap.c siscurs.c sisdraw.c sisio.c sisstub.c
OBJS = sis.o sisclock.o siscmap.o siscurs.o sisdraw.o sisio.o sisstub.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(sis530,$(OBJS))

View File

@ -530,7 +530,7 @@ sisPreserve (KdCardInfo *card)
memcpy (sisc->save.text_save, sisc->frameBuffer, SIS_TEXT_SAVE);
}
void
Bool
sisEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
@ -827,6 +827,7 @@ sisEnable (ScreenPtr pScreen)
#endif
_sisSetCrtc (sisc, &crtc);
return TRUE;
}
Bool

View File

@ -1149,7 +1149,7 @@ typedef struct _sisScreenInfo {
Bool sisCardInit (KdCardInfo *);
Bool sisScreenInit (KdScreenInfo *);
void sisEnable (ScreenPtr pScreen);
Bool sisEnable (ScreenPtr pScreen);
void sisDisable (ScreenPtr pScreen);
void sisFini (ScreenPtr pScreen);

View File

@ -1,6 +1,7 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
XCOMM $XFree86: xc/programs/Xserver/hw/kdrive/trident/Imakefile,v 1.2 2000/08/29 17:20:15 keithp Exp $
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = trident.c tridentdraw.c tridentcurs.c tridentstub.c
@ -8,9 +9,7 @@ OBJS = trident.o tridentdraw.o tridentcurs.o tridentstub.o
DEFINES = -DVESA
INCLUDES = -I.. -I../fbdev -I../vesa -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS) -I$(KDRIVE)/fbdev -I$(KDRIVE)/vesa
NormalLibraryObjectRule()
NormalLibraryTarget(trident,$(OBJS))

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.6 2000/08/26 00:17:50 keithp Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.7 2000/08/29 17:20:15 keithp Exp $ */
#include "trident.h"
#define extern
@ -72,7 +72,7 @@ tridentScreenInit (KdScreenInfo *screen)
return FALSE;
memset (tridents, '\0', sizeof (TridentScreenInfo));
#ifdef VESA
if (!vesaScreenInit (screen))
if (!vesaScreenInitialize (screen, &tridents->vesa))
#else
if (!fbdevScreenInit (screen))
#endif
@ -83,14 +83,16 @@ tridentScreenInit (KdScreenInfo *screen)
if (!tridentc->cop)
screen->dumb = TRUE;
#ifdef VESA
tridentc->screen = tridentc->vesa.fb;
if (tridents->vesa.mapping != VESA_LINEAR)
screen->dumb = TRUE;
tridents->screen = tridents->vesa.fb;
#else
tridentc->screen = tridentc->fb.fb;
tridents->screen = tridentc->fb.fb;
#endif
screen_size = screen->fb[0].byteStride * screen->height;
memory = (2048 + 512) * 1024;
if (memory >= screen_size + 2048)
tridents->cursor_base = tridentc->screen + memory - 2048;
if (tridents->screen && memory >= screen_size + 2048)
tridents->cursor_base = tridents->screen + memory - 2048;
else
tridents->cursor_base = 0;
screen->driver = tridents;
@ -100,7 +102,11 @@ tridentScreenInit (KdScreenInfo *screen)
Bool
tridentInitScreen (ScreenPtr pScreen)
{
#ifdef VESA
return vesaInitScreen (pScreen);
#else
return fbdevInitScreen (pScreen);
#endif
}
CARD8
@ -215,18 +221,21 @@ tridentResetMMIO (TridentCardInfo *tridentc)
tridentPause ();
}
void
Bool
tridentEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
TridentCardInfo *tridentc = pScreenPriv->card->driver;
#ifdef VESA
vesaEnable (pScreen);
if (!vesaEnable (pScreen))
return FALSE;
#else
fbdevEnable (pScreen);
if (!fbdevEnable (pScreen))
return FALSE;
#endif
tridentSetMMIO (tridentc);
return TRUE;
}
void

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.h,v 1.2 1999/12/30 03:03:16 robin Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.h,v 1.4 2000/08/29 17:20:15 keithp Exp $ */
#ifndef _TRIDENT_H_
#define _TRIDENT_H_
@ -151,11 +151,10 @@ typedef struct _tridentSave {
typedef struct _tridentCardInfo {
#ifdef VESA
VesaPrivRec vesa;
VesaCardPrivRec vesa;
#else
FbdevPriv fb;
#endif
CARD8 *screen;
CARD8 *cop_base;
Cop *cop;
CARD32 cop_depth;
@ -178,7 +177,11 @@ typedef struct _tridentCursor {
#define TRIDENT_CURSOR_HEIGHT 64
typedef struct _tridentScreenInfo {
#ifdef VESA
VesaScreenPrivRec vesa;
#endif
CARD8 *cursor_base;
CARD8 *screen;
TridentCursor cursor;
} TridentScreenInfo;

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentcurs.c,v 1.4 2000/05/06 22:17:51 keithp Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/tridentcurs.c,v 1.5 2000/08/29 17:20:15 keithp Exp $ */
#include "trident.h"
#include "cursorstr.h"
@ -221,7 +221,7 @@ tridentLoadCursor (ScreenPtr pScreen, int x, int y)
}
/* Set address for cursor bits */
offset = tridents->cursor_base - (CARD8 *) tridentc->screen;
offset = tridents->cursor_base - (CARD8 *) tridents->screen;
offset >>= 10;
tridentWriteIndex (tridentc, 0x3d4, 0x44, (CARD8) (offset & 0xff));
tridentWriteIndex (tridentc, 0x3d4, 0x45, (CARD8) (offset >> 8));

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = s3.c s3clock.c s3cmap.c s3curs.c s3draw.c s3gc.c s3stub.c
OBJS = s3.o s3clock.o s3cmap.o s3curs.o s3draw.o s3gc.o s3stub.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
DEFINES = -DS3_TRIO

View File

@ -636,7 +636,7 @@ s3Preserve (KdCardInfo *card)
* Enable the card for rendering. Manipulate the initial settings
* of the card here.
*/
void
Bool
s3Enable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
@ -904,6 +904,7 @@ s3Enable (ScreenPtr pScreen)
LockS3 (s3c);
_s3SetDepth (s3c->s3, crtc);
UnlockS3 (s3c);
return TRUE;
}
void

View File

@ -21,7 +21,7 @@
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/* $XFree86: xc/programs/Xserver/hw/kdrive/trio/s3.h,v 1.2 1999/12/30 03:03:19 robin Exp $ */
/* $XFree86: xc/programs/Xserver/hw/kdrive/trio/s3.h,v 1.4 2000/05/06 22:17:53 keithp Exp $ */
#ifndef _S3_H_
#define _S3_H_
@ -1126,7 +1126,7 @@ typedef struct _s3ScreenInfo {
Bool s3CardInit (KdCardInfo *);
Bool s3ScreenInit (KdScreenInfo *);
void s3Enable (ScreenPtr pScreen);
Bool s3Enable (ScreenPtr pScreen);
void s3Disable (ScreenPtr pScreen);
void s3Fini (ScreenPtr pScreen);

View File

@ -1,14 +1,13 @@
XCOMM $XConsortium: Imakefile /main/10 1996/12/02 10:20:33 lehors $
XCOMM $XFree86: xc/programs/Xserver/hw/nvfb/Imakefile,v 3.8 1996/12/23 06:30:19 dawes Exp $
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = ts300.c
OBJS = ts300.o
INCLUDES = -I../trio -I../sis530 -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS) -I../trio -I../sis530
NormalLibraryObjectRule()
NormalLibraryTarget(ts300,$(OBJS))

View File

@ -1,14 +1,12 @@
XCOMM $XFree86$
#include <Server.tmpl>
KDRIVE=..
#include "../Kdrive.tmpl"
SRCS = vesa.c vesainit.c vbe.c
OBJS = vesa.o vesainit.o vbe.o
INCLUDES = -I.. -I. -I$(XBUILDINCDIR) -I$(FONTINCSRC) \
-I../../../fb -I../../../mi -I../../../include -I../../../os \
-I$(EXTINCSRC) -I$(XINCLUDESRC)
INCLUDES = -I. $(KDINCS)
NormalLibraryObjectRule()
NormalLibraryTarget(vesa,$(OBJS))

View File

@ -7,8 +7,12 @@ Xvesa \- VESA VBE tiny X server
.RI [ :display ]
.RI [ option ...]
.SH DESCRIPTION
Xvesa is an X server for Linux on the x86 platform. Xvesa manipulates
the video hardware by running the VESA BIOS in VM86 mode. It
.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
therefore runs untrusted code with full priviledges, and is one of the
most insecure X servers available.
.B Run at your own risk.
@ -23,11 +27,10 @@ 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, or make your monitor explode. You are on
your own. The list of video modes that your BIOS claims to support
can be obtained by using the
.B -listmodes
option.
will fail, hang your system, or make your monitor explode; you are on
your own. This option is ignored if the
.B -screen
option was used.
.TP 8
.B -listmodes
tells the server to list all supported video modes. If
@ -40,8 +43,20 @@ the
server won't be able to use.
.TP 8
.B -force
tells the server to disable some sanity checks and use the specified
mode even if the BIOS claims not to support it.
disables 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 machines.
.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 my machine. Use this if
the colours are wrong in PseudoColor modes.
.SH KEYBOARD
Xvesa handles the keyboard in the same manner as the
.B Xfbdev

View File

@ -114,7 +114,8 @@ VbeSetup()
MAP_SHARED | MAP_FIXED,
devmem, HIMEM_BASE);
if(hiMem == MAP_FAILED) {
munmap(magicMem, MAGICMEM_SIZE);
ErrorF("Couldn't map high memory\n");
munmap(magicMem, MAGICMEM_SIZE);
munmap(loMem, LOMEM_SIZE);
goto fail;
}
@ -128,7 +129,6 @@ VbeSetup()
vi->magicMem = magicMem;
vi->loMem = loMem;
vi->hiMem = hiMem;
vi->fb = NULL;
vi->brk = LOMEM_BASE;
stack_base = VbeAllocateMemory(vi, STACK_SIZE);
@ -152,7 +152,10 @@ VbeSetup()
vi->palette_scratch_base = ~0;
vi->palette_format = 6;
vi->palette_wait = 0;
vi->windowA_offset = vi->windowB_offset = -1;
vi->last_window = 1;
vi->vga_palette = 1;
memset(&vi->vms, 0, sizeof(struct vm86_struct));
vi->vms.flags = 0;
vi->vms.screen_bitmap = 0;
@ -181,8 +184,6 @@ VbeSetup()
void
VbeCleanup(VbeInfoPtr vi)
{
if(vi->fb)
VbeUnmapFramebuffer(vi);
munmap(vi->magicMem, MAGICMEM_SIZE);
munmap(vi->loMem, LOMEM_SIZE);
munmap(vi->hiMem, HIMEM_SIZE);
@ -233,12 +234,17 @@ VbeGetModeInfo(VbeInfoPtr vi, int mode)
}
int
VbeSetMode(VbeInfoPtr vi, int mode)
VbeSetMode(VbeInfoPtr vi, int mode, int linear)
{
int code;
vi->windowA_offset = vi->windowB_offset = -1;
vi->last_window = 1;
vi->vms.regs.eax = 0x4F02;
vi->vms.regs.ebx = (mode & 0xFFFF) | 0xC000;
vi->vms.regs.ebx = (mode & 0xFFFF) | 0x8000;
if(linear)
vi->vms.regs.ebx |= 0x4000;
code = VbeDoInterrupt10(vi);
if(code < 0)
return -1;
@ -306,11 +312,24 @@ VbeRestoreState(VbeInfoPtr vi)
return 0;
}
int
VbeSetTextMode(VbeInfoPtr vi, int mode)
{
int code;
vi->vms.regs.eax = mode & 0x7f;
code = VbeDoInterrupt10(vi);
if(code < 0)
return -1;
return 0;
}
void *
VbeMapFramebuffer(VbeInfoPtr vi) {
VbeMapFramebuffer(VbeInfoPtr vi,
VbeModeInfoBlock *vmib)
{
U8 *fb;
VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base));
VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base));
int size;
int pagesize = getpagesize(), before, after;
@ -329,18 +348,28 @@ VbeMapFramebuffer(VbeInfoPtr vi) {
return NULL;
}
vi->fb = fb;
vi->fb_size = before + size + after;
return fb + before;
}
int
VbeUnmapFramebuffer(VbeInfoPtr vi)
VbeUnmapFramebuffer(VbeInfoPtr vi,
VbeModeInfoBlock *vmib,
void *fb)
{
int code;
if(!vi->fb)
ErrorF("Unmapping frambuffer not mapped\n");
code = munmap(vi->fb, vi->fb_size);
VbeInfoBlock *vib = (VbeInfoBlock*)&(LM(vi, vi->vib_base));
int size;
int pagesize = getpagesize(), before, after;
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);
code = munmap(fb, before + size + after);
if(code) {
ErrorF("Couldn't unmap framebuffer: %d\n", errno);
return -1;
@ -375,7 +404,7 @@ int
VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
{
U8 *palette_scratch;
int i, code;
int i, j, code;
if(number == 0)
return 0;
@ -395,21 +424,41 @@ VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
return -1;
}
for(i=0; i<number*4; i++)
palette_scratch[i] = entries[i] >> (8 - vi->palette_format);
vi->vms.regs.eax = 0x4F09;
if(vi->palette_wait)
vi->vms.regs.ebx = 0x80;
if (vi->vga_palette)
{
vi->vms.regs.eax = 0x1012;
vi->vms.regs.ebx = first;
vi->vms.regs.ecx = number;
vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
vi->vms.regs.edx = POINTER_OFFSET(vi->palette_scratch_base);
j = 0;
i = 0;
while (number--)
{
palette_scratch[j++] = entries[i++] >> (8-vi->palette_format);
palette_scratch[j++] = entries[i++] >> (8-vi->palette_format);
palette_scratch[j++] = entries[i++] >> (8-vi->palette_format);
i++;
}
}
else
vi->vms.regs.ebx = 0x00;
vi->vms.regs.ecx = number;
vi->vms.regs.edx = first;
vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
{
for(i=0; i<number*4; i++)
palette_scratch[i] = entries[i] >> (8 - vi->palette_format);
vi->vms.regs.eax = 0x4F09;
if(vi->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(vi->palette_scratch_base);
vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
}
code = VbeDoInterrupt10(vi);
if(code < 0)
return -1;
return -1;
return 0;
}
@ -417,7 +466,7 @@ int
VbeGetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
{
U8 *palette_scratch;
int i, code;
int i, j, code;
code = PreparePalette(vi);
if(code < 0)
@ -434,18 +483,45 @@ VbeGetPalette(VbeInfoPtr vi, int first, int number, U8 *entries)
return -1;
}
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(vi->palette_scratch_base);
vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
code = VbeDoInterrupt10(vi);
if(code < 0)
return -1;
for(i=0; i<number*4; i++)
entries[i] = palette_scratch[i] << (8-vi->palette_format);
retry:
if (vi->vga_palette)
{
vi->vms.regs.eax = 0x1017;
vi->vms.regs.ebx = first;
vi->vms.regs.ecx = number;
vi->vms.regs.es = POINTER_SEGMENT(vi->palette_scratch_base);
vi->vms.regs.edx = POINTER_OFFSET(vi->palette_scratch_base);
code = VbeDoInterrupt10(vi);
if(code < 0)
return -1;
j = 0;
i = 0;
while (number--)
{
entries[i++] = palette_scratch[j++] << (8-vi->palette_format);
entries[i++] = palette_scratch[j++] << (8-vi->palette_format);
entries[i++] = palette_scratch[j++] << (8-vi->palette_format);
entries[i++] = 0;
}
}
else
{
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(vi->palette_scratch_base);
vi->vms.regs.edi = POINTER_OFFSET(vi->palette_scratch_base);
code = VbeDoInterrupt10(vi);
if(code < 0)
{
vi->vga_palette = TRUE;
goto retry;
}
for(i=0; i<number*4; i++)
entries[i] = palette_scratch[i] << (8-vi->palette_format);
}
return 0;
}
@ -458,7 +534,6 @@ VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait)
ErrorF("Impossible palette format %d\n", vi->palette_format);
return -1;
}
ErrorF("Setting palette format to %d\n", vi->palette_format);
if(bits != vi->palette_format) {
vi->palette_format = 0;
vi->vms.regs.eax = 0x4F08;
@ -472,6 +547,94 @@ VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait)
return 0;
}
static int
VbeReallySetWindow(VbeInfoPtr 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(VbeInfoPtr vi, int offset, int purpose, int *size_return)
{
VbeModeInfoBlock *vmib = (VbeModeInfoBlock*)&(LM(vi, vi->vmib_base));
int window_size = vmib->WinSize * 1024;
int code;
int winnum;
if(vi->windowA_offset >= 0)
if(vi->windowA_offset <= offset && vi->windowA_offset + window_size > offset)
if(vmib->WinAAttributes & purpose)
goto windowA;
if(vi->windowB_offset >= 0)
if(vi->windowB_offset <= offset && vi->windowB_offset + window_size > offset)
if(vmib->WinBAttributes & purpose)
goto windowB;
if(!(vmib->WinBAttributes & purpose) ||
!(vmib->WinBAttributes & VBE_WINDOW_RELOCATE))
goto set_windowA;
if(!(vmib->WinAAttributes & purpose) ||
!(vmib->WinAAttributes & VBE_WINDOW_RELOCATE))
goto set_windowB;
if(vi->last_window)
goto set_windowA;
else
goto set_windowB;
set_windowA:
winnum = offset / (vmib->WinGranularity * 1024);
code = VbeReallySetWindow(vi, 0, winnum);
if(code < 0) {
ErrorF("Couldn't set window A to %d*%d\n",
(int)winnum, (int)vmib->WinGranularity);
return NULL;
}
vi->windowA_offset = winnum * vmib->WinGranularity * 1024;
windowA:
vi->last_window = 0;
*size_return = vmib->WinSize * 1024 - (offset - vi->windowA_offset);
return ((U8*)&(LM(vi, MAKE_POINTER(vmib->WinASegment, 0)))) +
offset - vi->windowA_offset;
set_windowB:
winnum = offset / (vmib->WinGranularity * 1024);
code = VbeReallySetWindow(vi, 1, winnum);
if(code < 0) {
ErrorF("Couldn't set window B to %d*%d\n",
(int)winnum, (int)vmib->WinGranularity);
return NULL;
}
vi->windowB_offset = winnum * vmib->WinGranularity * 1024;
windowB:
vi->last_window = 1;
*size_return = vmib->WinSize * 1024 - (offset - vi->windowB_offset);
return ((U8*)&(LM(vi, MAKE_POINTER(vmib->WinBSegment, 0)))) + offset - vi->windowB_offset;
}
int
VbeSetWritePlaneMask(VbeInfoPtr vi, int mask)
{
asm volatile ("outb %b0,%w1" : : "a" (2), "d" (0x3c4));
asm volatile ("outb %b0,%w1" : : "a" (mask), "d" (0x3c5));
}
int
VbeSetReadPlaneMap(VbeInfoPtr vi, int map)
{
asm volatile ("outb %b0,%w1" : : "a" (4), "d" (0x3ce));
asm volatile ("outb %b0,%w1" : : "a" (map), "d" (0x3cf));
}
int
VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib)
{
@ -496,12 +659,12 @@ VbeReportInfo(VbeInfoPtr vi, VbeInfoBlock *vib)
(vib->Capabilities[0]&1)?"fixed":"switchable",
(vib->Capabilities[0]&2)?"not ":"",
(vib->Capabilities[0]&3)?", RAMDAC causes snow":"");
ErrorF("Total memory: %lu bytes\n", 64L*vib->TotalMemory);
ErrorF("Total memory: %lu kilobytes\n", 64L*vib->TotalMemory);
if(error)
return -1;
return 0;
}
int
VbeReportModeInfo(VbeInfoPtr vi, U16 mode, VbeModeInfoBlock *vmib)
{
@ -572,7 +735,7 @@ VbeDoInterrupt10(VbeInfoPtr vi)
if(code < 0)
return -1;
if((vi->vms.regs.eax & 0xFFFF) != 0x4F) {
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) {
@ -627,7 +790,9 @@ VbeDoInterrupt(VbeInfoPtr vi, int num)
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) {
perror("vm86 failed");
return -1;
@ -873,6 +1038,7 @@ static int
vm86_loop(VbeInfoPtr vi)
{
int code;
while(1) {
code = vm86old(&vi->vms);
switch(VM86_TYPE(code)) {
@ -1030,18 +1196,20 @@ 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));
"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;
errno = -res;
res = -1;
} else
errno = 0;
errno = 0;
OsReleaseSignals ();
return res;
}

View File

@ -23,6 +23,10 @@ THE SOFTWARE.
#ifndef _VBE_H
#define _VBE_H
#define VBE_WINDOW_RELOCATE 1
#define VBE_WINDOW_READ 2
#define VBE_WINDOW_WRITE 4
#ifndef U8
#define U8 unsigned char
#define U16 unsigned short
@ -61,13 +65,16 @@ THE SOFTWARE.
typedef struct _VbeInfoRec {
int devmem, devzero;
void *magicMem, *loMem, *hiMem, *fb;
U32 fb_size;
void *magicMem, *loMem, *hiMem;
U32 brk;
struct vm86_struct vms;
U32 ret_code, stack_base, vib_base, vmib_base, statebuffer_base, palette_scratch_base;
U8 palette_format;
int palette_wait;
int windowA_offset;
int windowB_offset;
int last_window;
int vga_palette;
} VbeInfoRec, *VbeInfoPtr;
typedef struct _VbeInfoBlock {
@ -143,15 +150,16 @@ VbeInfoPtr VbeSetup(void);
void VbeCleanup(VbeInfoPtr vi);
VbeInfoBlock *VbeGetInfo(VbeInfoPtr vi);
VbeModeInfoBlock *VbeGetModeInfo(VbeInfoPtr vi, int mode);
int VbeSetMode(VbeInfoPtr vi, int mode);
int VbeSetMode(VbeInfoPtr vi, int mode, int linear);
int VbeGetMode(VbeInfoPtr vi, int *mode);
int VbeSetupStateBuffer(VbeInfoPtr vi);
int VbeSaveState(VbeInfoPtr vi);
int VbeRestoreState(VbeInfoPtr vi);
void *VbeMapFramebuffer(VbeInfoPtr vi);
int VbeUnmapFrambuffer(VbeInfoPtr vi);
void *VbeMapFramebuffer(VbeInfoPtr vi, VbeModeInfoBlock *vmib);
int VbeUnmapFrambuffer(VbeInfoPtr vi, VbeModeInfoBlock *vmib, void *fb);
int VbeSetPalette(VbeInfoPtr vi, int first, int number, U8 *entries);
int VbeSetPaletteOptions(VbeInfoPtr vi, U8 bits, int wait);
void *VbeSetWindow(VbeInfoPtr vi, int offset, int purpose, int *size_return);
int VbeReportInfo(VbeInfoPtr, VbeInfoBlock *);
int VbeReportModeInfo(VbeInfoPtr, U16 mode, VbeModeInfoBlock *);

View File

@ -22,11 +22,12 @@ THE SOFTWARE.
#include "vesa.h"
#define DEFAULT_MODE 0x115
int vesa_video_mode = DEFAULT_MODE;
int vesa_video_mode = 0;
Bool vesa_force_mode = FALSE;
Bool vesa_swap_rgb = FALSE;
Bool vesa_shadow = FALSE;
Bool vesa_linear_fb = TRUE;
Bool vesa_restore = FALSE;
static Bool
vesaModeSupported(VbeInfoPtr vi, VbeModeInfoBlock *vmib, Bool complain)
@ -36,17 +37,19 @@ vesaModeSupported(VbeInfoPtr vi, VbeModeInfoBlock *vmib, Bool complain)
ErrorF("Text mode specified.\n");
return FALSE;
}
if(vmib->MemoryModel != 0x06 && vmib->MemoryModel != 0x04) {
if(vmib->MemoryModel != 0x06 && vmib->MemoryModel != 0x04 && vmib->MemoryModel != 0x03) {
if(complain)
ErrorF("Unsupported memory model 0x%X\n", vmib->MemoryModel);
return FALSE;
}
if((vmib->ModeAttributes & 0x80) == 0) {
if(complain)
ErrorF("No linear framebuffer available in this mode\n");
return FALSE;
if ((vmib->WinAAttributes & 0x5) != 0x5) {
if(complain)
ErrorF("Neither linear nor windowed framebuffer available in this mode\n");
return FALSE;
}
}
if(!(vmib->ModeAttributes&1)) {
if(!(vmib->ModeAttributes & 1)) {
if(complain)
ErrorF("Mode not supported on this hardware\n");
return FALSE;
@ -61,7 +64,8 @@ vesaListModes()
VbeInfoPtr vi = NULL;
VbeInfoBlock *vib;
VbeModeInfoBlock *vmib;
unsigned i;
unsigned p, num_modes, i;
CARD16 *modes_list = NULL;
vi = VbeSetup();
if(!vi)
@ -72,32 +76,91 @@ vesaListModes()
goto fail;
VbeReportInfo(vi, vib);
i = MAKE_POINTER_1(vib->VideoModePtr);
while(VbeMemoryW(vi, i) != 0xFFFF) {
vmib = VbeGetModeInfo(vi, VbeMemoryW(vi, i));
/* The spec says you need to copy the list */
p = MAKE_POINTER_1(vib->VideoModePtr);
num_modes = 0;
while(VbeMemoryW(vi, p) != 0xFFFF) {
num_modes++;
p+=2;
}
modes_list = ALLOCATE_LOCAL(num_modes * sizeof(CARD16));
if(!modes_list)
goto fail;
p = MAKE_POINTER_1(vib->VideoModePtr);
for(i=0; i<num_modes; i++) {
modes_list[i] = VbeMemoryW(vi, p);
p += 2;
}
for(i=0; i<num_modes; i++) {
vmib = VbeGetModeInfo(vi, modes_list[i]);
if(!vmib)
goto fail;
if(vesa_force_mode || vesaModeSupported(vi, vmib, FALSE))
VbeReportModeInfo(vi, VbeMemoryW(vi, i), vmib);
i+=2;
VbeReportModeInfo(vi, modes_list[i], vmib);
}
if(modes_list)
DEALLOCATE_LOCAL(modes_list);
VbeCleanup(vi);
return TRUE;
fail:
if(modes_list)
DEALLOCATE_LOCAL(modes_list);
VbeCleanup(vi);
return FALSE;
}
Bool
vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
vesaGetModes (KdCardInfo *card, VesaCardPrivPtr priv)
{
VesaModePtr mode;
int nmode;
unsigned int i;
VbeInfoPtr vi = priv->vi;
VbeInfoBlock *vib = priv->vib;
VbeModeInfoBlock *vmib;
/* The spec says you need to copy the list */
i = MAKE_POINTER_1(vib->VideoModePtr);
nmode = 0;
while(VbeMemoryW(vi, i) != 0xFFFF) {
nmode++;
i+=2;
}
if (!nmode)
return FALSE;
priv->modes = xalloc (nmode * sizeof (VesaModeRec));
if (!priv->modes)
return FALSE;
priv->nmode = nmode;
i = MAKE_POINTER_1(vib->VideoModePtr);
nmode = 0;
while(nmode < priv->nmode) {
priv->modes[nmode].mode = VbeMemoryW(vi, i);
nmode++;
i+=2;
}
i = MAKE_POINTER_1(vib->VideoModePtr);
nmode = 0;
while(nmode < priv->nmode) {
vmib = VbeGetModeInfo(vi, priv->modes[nmode].mode);
if(!vmib)
break;
priv->modes[nmode].vmib = *vmib;
i += 2;
nmode++;
}
return TRUE;
}
Bool
vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv)
{
int code;
priv->mode = vesa_video_mode;
priv->vi = VbeSetup();
if(!priv->vi)
goto fail;
@ -106,13 +169,6 @@ vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
if(!priv->vib)
goto fail;
priv->vmib = VbeGetModeInfo(priv->vi, priv->mode);
if(!priv->vmib)
goto fail;
if(!vesa_force_mode && !vesaModeSupported(priv->vi, priv->vmib, TRUE))
goto fail;
code = VbeSetupStateBuffer(priv->vi);
if(code < 0)
goto fail;
@ -121,10 +177,9 @@ vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
if(code<0)
goto fail;
priv->fb = VbeMapFramebuffer(priv->vi);
if(!priv->vi)
goto fail;
if (!vesaGetModes (card, priv))
goto fail;
card->driver = priv;
return TRUE;
@ -138,9 +193,9 @@ vesaInitialize (KdCardInfo *card, VesaPrivPtr priv)
Bool
vesaCardInit(KdCardInfo *card)
{
VesaPrivPtr priv;
VesaCardPrivPtr priv;
priv = xalloc(sizeof(VesaPrivRec));
priv = xalloc(sizeof(VesaCardPrivRec));
if(!priv)
return FALSE;
@ -153,30 +208,137 @@ vesaCardInit(KdCardInfo *card)
return TRUE;
}
Bool
vesaScreenInit(KdScreenInfo *screen)
int
vesaDepth (VbeModeInfoBlock *m)
{
VesaPrivPtr priv = screen->card->driver;
if (m->MemoryModel == 0x06)
return (m->RedMaskSize +
m->GreenMaskSize +
m->BlueMaskSize);
else
return m->BitsPerPixel;
}
Bool
vesaModeGood (KdScreenInfo *screen,
VbeModeInfoBlock *a)
{
if (a->XResolution <= screen->width &&
a->YResolution <= screen->height &&
vesaDepth (a) >= screen->fb[0].depth)
{
return TRUE;
}
}
#define vabs(a) ((a) >= 0 ? (a) : -(a))
int
vesaSizeError (KdScreenInfo *screen,
VbeModeInfoBlock *a)
{
int xdist, ydist;
xdist = vabs (screen->width - a->XResolution);
ydist = vabs (screen->height - a->YResolution);
return xdist * xdist + ydist * ydist;
}
Bool
vesaModeBetter (KdScreenInfo *screen,
VbeModeInfoBlock *a,
VbeModeInfoBlock *b)
{
int aerr, berr;
if (vesaModeGood (screen, a))
{
if (!vesaModeGood (screen, b))
return TRUE;
}
else
{
if (vesaModeGood (screen, b))
return FALSE;
}
aerr = vesaSizeError (screen, a);
berr = vesaSizeError (screen, b);
if (aerr < berr)
return TRUE;
if (berr < aerr)
return FALSE;
if (vabs (screen->fb[0].depth - vesaDepth (a)) <
vabs (screen->fb[0].depth - vesaDepth (b)))
return TRUE;
return FALSE;
}
VesaModePtr
vesaSelectMode (KdScreenInfo *screen)
{
VesaCardPrivPtr priv = screen->card->driver;
int i, best;
if (vesa_video_mode)
{
for (best = 0; best < priv->nmode; best++)
if (priv->modes[best].mode == vesa_video_mode &&
(vesaModeSupported (priv->vi, &priv->modes[best].vmib, FALSE) ||
vesa_force_mode))
return &priv->modes[best];
}
for (best = 0; best < priv->nmode; best++)
{
if (vesaModeSupported (priv->vi, &priv->modes[best].vmib, FALSE))
break;
}
if (best == priv->nmode)
return 0;
for (i = best + 1; i < priv->nmode; i++)
if (vesaModeSupported (priv->vi, &priv->modes[i].vmib, FALSE) &&
vesaModeBetter (screen, &priv->modes[i].vmib,
&priv->modes[best].vmib))
best = i;
return &priv->modes[best];
}
Bool
vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr)
{
VesaCardPrivPtr priv = screen->card->driver;
VbeModeInfoBlock *vmib;
Pixel allbits;
int depth;
screen->width = priv->vmib->XResolution;
screen->height = priv->vmib->YResolution;
screen->fb[0].depth = priv->vmib->BitsPerPixel;
screen->fb[0].bitsPerPixel = priv->vmib->BitsPerPixel;
screen->fb[0].byteStride = priv->vmib->BytesPerScanLine;
screen->fb[0].pixelStride =
(priv->vmib->BytesPerScanLine * 8) / priv->vmib->BitsPerPixel;
pscr->mode = vesaSelectMode (screen);
if (!pscr->mode)
return FALSE;
if(priv->vmib->MemoryModel == 0x06) {
pscr->shadow = vesa_shadow;
if (vesa_linear_fb)
pscr->mapping = VESA_LINEAR;
else
pscr->mapping = VESA_WINDOWED;
vmib = &pscr->mode->vmib;
screen->width = vmib->XResolution;
screen->height = vmib->YResolution;
screen->fb[0].depth = vesaDepth (vmib);
screen->fb[0].bitsPerPixel = vmib->BitsPerPixel;
screen->fb[0].byteStride = vmib->BytesPerScanLine;
screen->fb[0].pixelStride = ((vmib->BytesPerScanLine * 8) /
vmib->BitsPerPixel);
switch (vmib->MemoryModel) {
case 0x06:
/* TrueColor or DirectColor */
screen->fb[0].visuals = (1 << TrueColor);
screen->fb[0].redMask =
FbStipMask(priv->vmib->RedFieldPosition, priv->vmib->RedMaskSize);
FbStipMask(vmib->RedFieldPosition, vmib->RedMaskSize);
screen->fb[0].greenMask =
FbStipMask(priv->vmib->GreenFieldPosition, priv->vmib->GreenMaskSize);
FbStipMask(vmib->GreenFieldPosition, vmib->GreenMaskSize);
screen->fb[0].blueMask =
FbStipMask(priv->vmib->BlueFieldPosition, priv->vmib->BlueMaskSize);
FbStipMask(vmib->BlueFieldPosition, vmib->BlueMaskSize);
allbits =
screen->fb[0].redMask |
screen->fb[0].greenMask |
@ -185,7 +347,8 @@ vesaScreenInit(KdScreenInfo *screen)
while (depth && !(allbits & (1 << (depth - 1))))
depth--;
screen->fb[0].depth = depth;
} else if (priv->vmib->MemoryModel == 0x04) {
break;
case 0x04:
/* PseudoColor */
screen->fb[0].visuals = ((1 << StaticGray) |
(1 << GrayScale) |
@ -196,35 +359,204 @@ vesaScreenInit(KdScreenInfo *screen)
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
} else {
break;
case 0x03:
/* 4 plane planar */
screen->fb[0].visuals = (1 << StaticColor);
screen->fb[0].blueMask = 0x00;
screen->fb[0].greenMask = 0x00;
screen->fb[0].redMask = 0x00;
screen->fb[0].depth = 4;
screen->fb[0].bitsPerPixel = 4;
pscr->mapping = VESA_PLANAR;
break;
default:
ErrorF("Unsupported VESA MemoryModel 0x%02X\n",
priv->vmib->MemoryModel);
vmib->MemoryModel);
return FALSE;
}
screen->rate = 72;
screen->fb[0].frameBuffer = (CARD8 *)(priv->fb);
if (pscr->mapping == VESA_LINEAR && !(vmib->ModeAttributes & 0x80))
pscr->mapping = VESA_WINDOWED;
switch (pscr->mapping) {
case VESA_LINEAR:
pscr->fb = VbeMapFramebuffer(priv->vi, vmib);
break;
case VESA_WINDOWED:
pscr->fb = NULL;
pscr->shadow = TRUE;
break;
case VESA_PLANAR:
pscr->fb = NULL;
pscr->shadow = TRUE;
break;
}
screen->rate = 72;
screen->fb[0].frameBuffer = (CARD8 *)(pscr->fb);
if (pscr->shadow)
return KdShadowScreenInit (screen);
return TRUE;
}
Bool
vesaInitScreen(ScreenPtr pScreen)
vesaScreenInit(KdScreenInfo *screen)
{
VesaScreenPrivPtr pscr;
pscr = xcalloc (1, sizeof (VesaScreenPrivRec));
if (!pscr)
return FALSE;
if (!vesaScreenInitialize (screen, pscr))
return FALSE;
screen->driver = pscr;
return TRUE;
}
void
void *
vesaWindowPlanar (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
CARD32 *size)
{
KdScreenPriv(pScreen);
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
VbeModeInfoBlock *vmib = &pscr->mode->vmib;
static int plane;
int winSize;
void *base;
if (!pScreenPriv->enabled)
return 0;
plane = offset & 3;
VbeSetWritePlaneMask (priv->vi, (1 << plane));
offset = offset >> 2;
base = VbeSetWindow (priv->vi,
vmib->BytesPerScanLine * row + offset,
mode,
&winSize);
*size = (CARD32) winSize;
return base;
}
void *
vesaWindowLinear (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
CARD32 *size)
{
KdScreenPriv(pScreen);
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
VbeModeInfoBlock *vmib = &pscr->mode->vmib;
if (!pScreenPriv->enabled)
return 0;
*size = vmib->BytesPerScanLine;
return (CARD8 *) pscr->fb + row * vmib->BytesPerScanLine + offset;
}
void *
vesaWindowWindowed (ScreenPtr pScreen,
CARD32 row,
CARD32 offset,
int mode,
CARD32 *size)
{
KdScreenPriv(pScreen);
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
VbeModeInfoBlock *vmib = &pscr->mode->vmib;
int winSize;
void *base;
if (!pScreenPriv->enabled)
return 0;
base = VbeSetWindow (priv->vi,
vmib->BytesPerScanLine * row + offset,
mode,
&winSize);
*size = (CARD32) winSize;
return base;
}
static CARD16 vga16Colors[16][3] = {
{ 0, 0, 0, }, /* 0 */
{ 0x80,0, 0, }, /* 1 */
{ 0, 0x80,0, }, /* 2 */
{ 0x80,0x80,0, }, /* 3 */
{ 0, 0, 0x80,}, /* 4 */
{ 0x80,0, 0x80,}, /* 5 */
{ 0, 0x80,0x80,}, /* 6 */
{ 0x80,0x80,0x80,}, /* 7 */
{ 0xC0,0xC0,0xC0,}, /* 8 */
{ 0xFF,0, 0 ,}, /* 9 */
{ 0, 0xFF,0 ,}, /* 10 */
{ 0xFF,0xFF,0 ,}, /* 11 */
{ 0 ,0, 0xFF,}, /* 12 */
{ 0xFF,0, 0xFF,}, /* 13 */
{ 0, 0xFF,0xFF,}, /* 14 */
{ 0xFF,0xFF,0xFF,}, /* 15 */
};
Bool
vesaCreateColormap16 (ColormapPtr pmap)
{
int i;
for (i = 0; i < 16; i++)
{
pmap->red[i].co.local.red = (vga16Colors[i][0]<<8)|vga16Colors[i][0];
pmap->red[i].co.local.green = (vga16Colors[i][1]<<8)|vga16Colors[i][1];
pmap->red[i].co.local.blue = (vga16Colors[i][2]<<8)|vga16Colors[i][2];
}
return TRUE;
}
Bool
vesaInitScreen(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
if (pscr->shadow)
{
switch (pscr->mapping) {
case VESA_LINEAR:
return KdShadowInitScreen (pScreen, shadowUpdatePacked, vesaWindowLinear);
case VESA_WINDOWED:
return KdShadowInitScreen (pScreen, shadowUpdatePacked, vesaWindowWindowed);
case VESA_PLANAR:
pScreen->CreateColormap = vesaCreateColormap16;
return KdShadowInitScreen (pScreen, shadowUpdatePlanar4, vesaWindowPlanar);
}
}
return TRUE;
}
Bool
vesaEnable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
VesaPrivPtr priv = pScreenPriv->card->driver;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
int code;
int palette_wait = 0, palette_hi = 0;
int i=0;
int size;
char *p;
code = VbeSetMode(priv->vi, priv->mode);
code = VbeSetMode(priv->vi, pscr->mode->mode, pscr->mapping == VESA_LINEAR);
if(code < 0)
FatalError("Couldn't set mode\n");
return FALSE;
if(priv->vib->Capabilities[0] & 1)
palette_hi = 1;
@ -233,23 +565,85 @@ vesaEnable(ScreenPtr pScreen)
if(palette_hi || palette_wait)
VbeSetPaletteOptions(priv->vi, palette_hi?8:6, palette_wait);
return;
switch (pscr->mapping) {
case VESA_LINEAR:
memcpy (priv->text, pscr->fb, VESA_TEXT_SAVE);
break;
case VESA_WINDOWED:
while(i < VESA_TEXT_SAVE) {
p = VbeSetWindow(priv->vi, i, VBE_WINDOW_READ, &size);
if(!p) {
ErrorF("Couldn't set window for saving VGA font\n");
break;
}
if(i + size > VESA_TEXT_SAVE)
size = VESA_TEXT_SAVE - i;
memcpy(((char*)priv->text) + i, p, size);
i += size;
}
break;
case VESA_PLANAR:
p = VbeSetWindow (priv->vi, 0, VBE_WINDOW_READ, &size);
for (i = 0; i < 4; i++)
{
VbeSetReadPlaneMap (priv->vi, i);
memcpy (((char *)priv->text) + i * (VESA_TEXT_SAVE/4), p,
(VESA_TEXT_SAVE/4));
}
break;
}
return TRUE;
}
void
vesaDisable(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
VesaPrivPtr priv = pScreenPriv->card->driver;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
int i=0;
int size;
char *p;
switch (pscr->mapping) {
case VESA_LINEAR:
memcpy(pscr->fb, priv->text, VESA_TEXT_SAVE);
break;
case VESA_WINDOWED:
while(i < VESA_TEXT_SAVE) {
p = VbeSetWindow(priv->vi, i, VBE_WINDOW_WRITE, &size);
if(!p) {
ErrorF("Couldn't set window for restoring VGA font\n");
break;
}
if(i + size > VESA_TEXT_SAVE)
size = VESA_TEXT_SAVE - i;
memcpy(p, ((char*)priv->text) + i, size);
i += size;
}
break;
case VESA_PLANAR:
p = VbeSetWindow (priv->vi, 0, VBE_WINDOW_WRITE, &size);
for (i = 0; i < 4; i++)
{
VbeSetWritePlaneMask (priv->vi, 1 << i);
memcpy (p,
((char *)priv->text) + i * (VESA_TEXT_SAVE/4),
(VESA_TEXT_SAVE/4));
}
break;
}
}
void
vesaPreserve(KdCardInfo *card)
{
VesaPrivPtr priv = card->driver;
VesaCardPrivPtr priv = card->driver;
int code;
/* The framebuffer might not be valid at this point, so we cannot
save the VGA fonts now; we do it in vesaEnable. */
code = VbeSaveState(priv->vi);
if(code < 0)
FatalError("Couldn't save state\n");
@ -260,7 +654,7 @@ vesaPreserve(KdCardInfo *card)
void
vesaRestore(KdCardInfo *card)
{
VesaPrivPtr priv = card->driver;
VesaCardPrivPtr priv = card->driver;
VbeRestoreState(priv->vi);
return;
}
@ -268,8 +662,9 @@ vesaRestore(KdCardInfo *card)
void
vesaCardFini(KdCardInfo *card)
{
VesaPrivPtr priv = card->driver;
VbeUnmapFramebuffer(priv->vi);
VesaCardPrivPtr priv = card->driver;
if (vesa_restore)
VbeSetTextMode(priv->vi,3);
VbeCleanup(priv->vi);
return;
}
@ -277,15 +672,21 @@ vesaCardFini(KdCardInfo *card)
void
vesaScreenFini(KdScreenInfo *screen)
{
return;
VesaScreenPrivPtr pscr = screen->driver;
VesaCardPrivPtr priv = screen->card->driver;
if (pscr->fb)
VbeUnmapFramebuffer(priv->vi, &pscr->mode->vmib, pscr->fb);
return;
}
void
vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
VesaPrivPtr priv = pScreenPriv->card->driver;
int i, j, k;
VesaScreenPrivPtr pscr = pScreenPriv->screen->driver;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
int i, j, k, start;
CARD8 scratch[4*256];
int red, green, blue;
@ -314,7 +715,14 @@ vesaPutColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
scratch[k+blue] = pdefs[i+k].blue >> 8;
scratch[k+3] = 0;
}
VbeSetPalette(priv->vi, pdefs[i].pixel, j - i, scratch);
start = pdefs[i].pixel;
if (pscr->mapping == VESA_PLANAR)
{
for (start = pdefs[i].pixel; start < 256; start += 16)
VbeSetPalette(priv->vi, start, j - i, scratch);
}
else
VbeSetPalette(priv->vi, start, j - i, scratch);
i = j;
}
}
@ -323,7 +731,7 @@ void
vesaGetColors (ScreenPtr pScreen, int fb, int n, xColorItem *pdefs)
{
KdScreenPriv(pScreen);
VesaPrivPtr priv = pScreenPriv->card->driver;
VesaCardPrivPtr priv = pScreenPriv->card->driver;
int first, i, j, k;
CARD8 scratch[4];
int red, green, blue;
@ -367,6 +775,15 @@ vesaProcessArgument (int argc, char **argv, int i)
} else if(!strcmp(argv[i], "-swaprgb")) {
vesa_swap_rgb = TRUE;
return 1;
} else if(!strcmp(argv[i], "-shadow")) {
vesa_shadow = TRUE;
return 1;
} else if(!strcmp(argv[i], "-nolinear")) {
vesa_linear_fb = FALSE;
return 1;
} else if(!strcmp(argv[i], "-restore")) {
vesa_restore = TRUE;
return 1;
}
return 0;

View File

@ -27,24 +27,42 @@ THE SOFTWARE.
#include <sys/vm86.h>
#include "vbe.h"
typedef struct _VesaPriv {
#define VESA_TEXT_SAVE (64*1024)
typedef struct _VesaMode {
int mode;
VbeModeInfoBlock vmib;
} VesaModeRec, *VesaModePtr;
typedef struct _VesaCardPriv {
VbeInfoPtr vi;
VbeInfoBlock *vib;
VbeModeInfoBlock *vmib;
VesaModePtr modes;
int nmode;
char text[VESA_TEXT_SAVE];
} VesaCardPrivRec, *VesaCardPrivPtr;
#define VESA_LINEAR 0
#define VESA_WINDOWED 1
#define VESA_PLANAR 2
typedef struct _VesaScreenPriv {
VesaModePtr mode;
Bool shadow;
int mapping;
void *fb;
} VesaPrivRec, *VesaPrivPtr;
} VesaScreenPrivRec, *VesaScreenPrivPtr;
extern int vesa_video_mode;
extern Bool vesa_force_mode;
Bool vesaListModes(void);
Bool vesaInitialize(KdCardInfo *card, VesaPrivPtr priv);
Bool vesaInitialize(KdCardInfo *card, VesaCardPrivPtr priv);
Bool vesaCardInit(KdCardInfo *card);
Bool vesaInitialize (KdCardInfo *card, VesaPrivPtr priv);
Bool vesaScreenInit(KdScreenInfo *screen);
Bool vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv);
Bool vesaScreenInitialize (KdScreenInfo *screen, VesaScreenPrivPtr pscr);
Bool vesaScreenInit(KdScreenInfo *screen);
Bool vesaInitScreen(ScreenPtr pScreen);
void vesaEnable(ScreenPtr pScreen);
Bool vesaEnable(ScreenPtr pScreen);
void vesaDisable(ScreenPtr pScreen);
void vesaPreserve(KdCardInfo *card);
void vesaRestore(KdCardInfo *card);