Viewing file: svpmi.c (4.05 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
/* 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. */ }
|