Felisp
84436a5ae0
http://my.svgalib.org/svgalib/svgalib-1.9.25.tar.gz http://my.svgalib.org/svgalib/
185 lines
4 KiB
C
185 lines
4 KiB
C
/* This library is free software; you can redistribute it and/or */
|
|
/* modify it without any restrictions. This library is distributed */
|
|
/* in the hope that it will be useful, but without any warranty. */
|
|
|
|
/* Copyright (C) 1994 Harm Hanemaayer */
|
|
|
|
/*
|
|
Basic initial untested SVPMI skeleton driver.
|
|
Includes computer-generated mode setting/bank switching
|
|
routines and mode information table.
|
|
|
|
Untested, may not be finished.
|
|
|
|
A better way to do this would be to have a seperate svpmi server
|
|
program set modes. This way there would be no need to recompile
|
|
the shared library. For performance it would be nice to move the
|
|
bank-switching over to svgalib. I imagine one way to do this would
|
|
be to encode the SVPMI procedure code (simple as it is, just a few
|
|
outs and a few basic bit operations) and have the svgalib driver
|
|
interpret that. This could also be used for mode setting.
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include "../vga.h"
|
|
#include "../libvga.h"
|
|
#include "../driver.h"
|
|
|
|
#include "svpmi.h"
|
|
#include "modes.svpmi"
|
|
#include "modetable.svpmi"
|
|
|
|
|
|
|
|
static svpmi_currentmode = NULL;
|
|
|
|
static svpmi_modeentry *
|
|
svpmi_lookupmode (int w, int h, int colors)
|
|
{
|
|
int i;
|
|
for (i = 0; i < sizeof (svpmi_modes); i++)
|
|
if (w == svpmi_modes[i].width && h == svpmi_modes[i].height &&
|
|
colors = (1 << svpmi_mode[i].bitsperpixel))
|
|
return &svpmi_modes[i];
|
|
return NULL;
|
|
}
|
|
|
|
|
|
static int
|
|
svpmi_getmodeinfo (int mode, vga_modeinfo * modeinfo)
|
|
{
|
|
modeinfo->maxlogicalwidth = modeinfo->width;
|
|
modeinfo->startaddressrange = 0;
|
|
modeinfo->haveblit = 0;
|
|
modeinfo->flags &= ~HAVE_RWPAGE;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* Return non-zero if mode is available */
|
|
|
|
static int
|
|
svpmi_modeavailable (int mode)
|
|
{
|
|
struct info *info;
|
|
svpmi_modeentry *sm;
|
|
|
|
if (mode < 10)
|
|
return vga_chipsetfunctions[CHIPSET_MODEAVAILABLE] (mode);
|
|
if (mode == 32)
|
|
return 0;
|
|
|
|
sm = svpmi_lookupmode (modeinfo->width, modeinfo->height,
|
|
modeinfo->colors);
|
|
return (sm != NULL)
|
|
}
|
|
|
|
|
|
/* Set a mode */
|
|
|
|
static int
|
|
svpmi_setmode (int mode, int prv_mode)
|
|
{
|
|
svpmi_modeentry *sm;
|
|
|
|
if (mode == TEXT)
|
|
{
|
|
svpmi_setmode_text ();
|
|
return 0;
|
|
}
|
|
|
|
if (!SVGAMODE (mode))
|
|
/* Let the standard VGA driver set standard VGA modes. */
|
|
return vga_chipsetfunctions[CHIPSET_SETMODE] (mode);
|
|
|
|
sm = svpmi_lookupmode (infotable[mode].width, infotable[mode].height,
|
|
infotable[mode].colors);
|
|
if (sm == NULL)
|
|
return 1; /* No match. */
|
|
|
|
sm->setmode (); /* Call the SVPMI mode setting code. */
|
|
svpmi_currentmode = sm;
|
|
|
|
/* Hack similar to what the ATI mach32 driver does for some */
|
|
/* truecolor modes. I think S3 uses only a few fixed scanline */
|
|
/* widths (e.g. 1024, 1280) so may happen a lot. */
|
|
infotable[mode].xbytes = sm->bytesperscanline;
|
|
}
|
|
|
|
|
|
/* Indentify chipset; return non-zero if detected */
|
|
|
|
static int
|
|
svpmi_test ()
|
|
{
|
|
/* Detection with environment variable -- better change into */
|
|
/* config file option. */
|
|
if (getenv ("SVGALIB_SVPMI"))
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/* Bank switching function - set 64K bank number */
|
|
|
|
static void
|
|
svpmi_setpage (int page)
|
|
{
|
|
svpmi_currentmode->setwindow (page *
|
|
(64 / svpmi_currentmode->windowgranularity));
|
|
}
|
|
|
|
|
|
/* Set display start address (not for 16 color modes) */
|
|
|
|
static int
|
|
svpmi_setdisplaystart (int address)
|
|
{
|
|
}
|
|
|
|
|
|
/* Set logical scanline length (usually multiple of 8) */
|
|
/* Multiples of 8 to 2040 */
|
|
|
|
static int
|
|
svpmi_setlogicalwidth (int width)
|
|
{
|
|
outw (0x3d4, 0x13 + (width >> 3) * 256); /* lw3-lw11 */
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
nothing ()
|
|
{
|
|
}
|
|
|
|
|
|
/* Function table (exported) */
|
|
|
|
int (*svpmi_chipsetfunctions[]) () =
|
|
{
|
|
(int (*)()) nothing, /* saveregs */
|
|
(int (*)()) nothing, /* setregs */
|
|
(int (*)()) nothing, /* unlock */
|
|
(int (*)()) nothing, /* lock */
|
|
svpmi_test,
|
|
svpmi_init,
|
|
(int (*)()) svpmi_setpage,
|
|
(int (*)()) nothing,
|
|
(int (*)()) nothing,
|
|
svpmi_setmode,
|
|
svpmi_modeavailable,
|
|
nothing, /* setdisplaystart */
|
|
svmi_setlogicalwidth,
|
|
svpmi_getmodeinfo
|
|
};
|
|
|
|
|
|
/* Initialize chipset (called after detection) */
|
|
|
|
static int
|
|
svpmi_init (int force, int par1, int par2)
|
|
{
|
|
/* Not required. */
|
|
}
|