This commit is contained in:
Aren Elchinyan 2024-05-29 19:55:33 +03:00
parent 62644cad9e
commit 5d73ccc77a
66 changed files with 30285 additions and 0 deletions

620
ati/driver.c Normal file
View File

@ -0,0 +1,620 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* ATI 18800/28800 driver (based on the Allegro ATI code).
*
* By Shawn Hargreaves.
*
* See freebe.txt for copyright information.
*/
// #define NO_HWPTR
#include <pc.h>
#include "vbeaf.h"
/* chipset information */
#define ATI_18800 1
#define ATI_18800_1 2
#define ATI_28800_2 3
#define ATI_28800_4 4
#define ATI_28800_5 5
int ati_type;
int ati_port = 0x1CE;
/* driver function prototypes */
void SetBank32();
void SetBank32End();
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
void SetBank(AF_DRIVER *af, long bank);
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
/* FreeBE/AF extension allowing farptr access to video memory */
FAF_HWPTR_DATA hwptr;
/* list of available video modes */
typedef struct VIDEO_MODE
{
int w, h;
int bpp;
int num;
} VIDEO_MODE;
VIDEO_MODE mode_list[] =
{
{ 640, 400, 8, 0x61 },
{ 640, 480, 8, 0x62 }
};
#define NUM_MODES (int)(sizeof(mode_list)/sizeof(VIDEO_MODE))
short available_modes[NUM_MODES+1] = { 1, 2, -1 };
/* detect:
* Detects the presence of an ATI card.
*/
char *detect()
{
char *name = NULL;
char buf[16];
int sel, i;
sel = allocate_selector(0, 1024*1024);
if (sel < 0)
return NULL;
for (i=0; i<9; i++) /* check ID string */
buf[i] = _farpeekb(sel, 0xC0031+i);
if (memcmp(buf, "761295520", 9) != 0) {
free_selector(sel);
return NULL;
}
ati_port = _farpeekw(sel, 0xC0010); /* read port address */
if (!ati_port)
ati_port = 0x1CE;
switch (_farpeekb(sel, 0xC0043)) { /* check ATI type */
case '1':
ati_type = ATI_18800;
name = "18800";
break;
case '2':
ati_type = ATI_18800_1;
name = "18800-1";
break;
case '3':
ati_type = ATI_28800_2;
name = "28800-2";
break;
case '4':
ati_type = ATI_28800_4;
name = "28800-4";
break;
case '5':
ati_type = ATI_28800_5;
name = "28800-5";
break;
default:
/* unknown sort of ATI */
free_selector(sel);
return NULL;
}
free_selector(sel);
return name;
}
/* SetupDriver:
* Fills in our driver header block.
*/
int SetupDriver(AF_DRIVER *af)
{
char *name;
int vram_size;
int i;
name = detect();
if (!name)
return 1;
i = 0;
while (af->OemVendorName[i])
i++;
af->OemVendorName[i++] = ',';
af->OemVendorName[i++] = ' ';
while (*name)
af->OemVendorName[i++] = *(name++);
af->OemVendorName[i] = 0;
if (get_vesa_info(&vram_size, NULL, NULL) != 0)
af->TotalMemory = 512;
else
af->TotalMemory = MIN(vram_size/1024, 512);
af->AvailableModes = available_modes;
af->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
af->IOPortsTable = ports_table;
af->SetBank32 = SetBank32;
af->SetBank32Len = (long)SetBank32End - (long)SetBank32;
af->SupplementalExt = ExtStub;
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->SetPaletteData = SetPaletteData;
af->SetBank = SetBank;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
*/
int InitDriver(AF_DRIVER *af)
{
hwptr_init(hwptr.IOMemMaps[0], af->IOMemMaps[0]);
hwptr_init(hwptr.IOMemMaps[1], af->IOMemMaps[1]);
hwptr_init(hwptr.IOMemMaps[2], af->IOMemMaps[2]);
hwptr_init(hwptr.IOMemMaps[3], af->IOMemMaps[3]);
hwptr_init(hwptr.BankedMem, af->BankedMem);
hwptr_init(hwptr.LinearMem, af->LinearMem);
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
#ifndef NO_HWPTR
case FAFEXT_HWPTR:
/* allow farptr access to video memory */
return &hwptr;
#endif
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
VIDEO_MODE *info;
int i;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
for (i=0; i<(int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
modeInfo->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
modeInfo->MaxBuffers = (af->TotalMemory*1024) /
(info->w*info->h*BYTES_PER_PIXEL(info->bpp));
if (info->w > 1024) {
modeInfo->MaxBytesPerScanLine = 2048*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 2048;
}
else {
modeInfo->MaxBytesPerScanLine = 1024*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 1024;
}
modeInfo->BytesPerScanLine = info->w*BYTES_PER_PIXEL(info->bpp);
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
modeInfo->MaxPixelClock = 135000000;
return 0;
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
long available_vram;
long used_vram;
int width;
VIDEO_MODE *info;
RM_REGS r;
/* reject anything with hardware stereo, linear framebuffer, or noclear */
if (mode & 0xC400)
return -1;
mode &= 0x3FF;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
/* call BIOS to set the mode */
r.x.ax = info->num;
rm_int(0x10, &r);
/* adjust the virtual width for widescreen modes */
if (virtualX > info->w) {
if (virtualX > 1024)
return -1;
*bytesPerLine = ((virtualX*BYTES_PER_PIXEL(info->bpp))+15)&0xFFF0;
width = read_vga_register(0x3D4, 0x13);
write_vga_register(0x3D4, 0x13, (width * (*bytesPerLine)) / (info->w*BYTES_PER_PIXEL(info->bpp)));
}
else
*bytesPerLine = info->w*BYTES_PER_PIXEL(info->bpp);
/* set up some hardware registers */
if (ati_type >= ATI_28800_4) /* allow display past 512k */
alter_vga_register(ati_port, 0xB6, 1, 1);
if (ati_type >= ATI_18800_1) /* select single bank mode */
alter_vga_register(ati_port, 0xBE, 8, 0);
/* store info about the current mode */
af_bpp = info->bpp;
af_width = *bytesPerLine;
af_height = MAX(info->h, virtualY);
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
af_bank = -1;
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory*1024 ;
if (used_vram > available_vram)
return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
}
else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
if (waitVRT >= 0) {
long a = (x * BYTES_PER_PIXEL(af_bpp)) + ((y + af_visible_page*af_height) * af_width);
asm volatile ("cli");
if (waitVRT) {
do {
} while (inportb(0x3DA) & 1);
}
/* write high bits to ATI-specific registers */
if (ati_type < ATI_28800_2) {
alter_vga_register(ati_port, 0xB0, 0xC0, a>>12);
}
else {
alter_vga_register(ati_port, 0xB0, 0x40, a>>12);
alter_vga_register(ati_port, 0xA3, 0x10, a>>15);
}
/* write to normal VGA address registers */
write_vga_register(0x3D4, 0x0D, (a>>2) & 0xFF);
write_vga_register(0x3D4, 0x0C, (a>>10) & 0xFF);
asm volatile ("sti");
if (waitVRT) {
do {
} while (!(inportb(0x3DA) & 8));
}
}
af_scroll_x = x;
af_scroll_y = y;
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* SetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _SetBank32, _SetBank32End
.align 4
_SetBank32:
pushl %edx
pushl %eax
movl %edx, %eax
movb %al, %ah /* save al into ah */
movl _ati_port, %edx /* read port 1CE index 0xB2 */
movb $0xB2, %al
outb %al, %dx
incl %edx
inb %dx, %al
decl %edx
andb $0xE1, %al /* mask out bits 1-4 */
shlb $1, %ah /* shift bank number */
orb %al, %ah
movb $0xB2, %al /* write to port 1CE index 0xB2 */
outb %al, %dx
incl %edx
movb %ah, %al
outb %al, %dx
popl %eax
popl %edx
ret
_SetBank32End:
");
/* SetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable SetBank32() above.
*/
void SetBank(AF_DRIVER *af, long bank)
{
asm (
" call _SetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}

45
ati/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF ATI 18800/28800 driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

24
ati/notes.txt Normal file
View File

@ -0,0 +1,24 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
ATI 18800/28800 driver implementation notes.
This is a software-only driver for the ATI 18800/28800 chipsets, based on
the native drivers from old versions of the Allegro library. It only
supports 256 color modes, and has no support for linear framebuffers or
accelerated drawing. As such it is useful primarily because it is faster
than the VESA 1.x bank switching mechanism, and as a workaround for the
many bugs in common VESA driver implementations.
This code is not portable to any platforms other than DOS+DPMI, because
it uses BIOS calls to set the initial video mode.
By Shawn Hargreaves (shawn@talula.demon.co.uk)

948
avance/driver.c Normal file
View File

@ -0,0 +1,948 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Avance Logic driver file.
*
* See freebe.txt for copyright information.
*/
#include <pc.h>
#include "vbeaf.h"
/* driver function prototypes */
void SetBank32();
void SetBank32End();
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
void SetBank(AF_DRIVER *af, long bank);
void WaitTillIdle(AF_DRIVER *af);
void SetMix(AF_DRIVER *af, long foreMix, long backMix);
/* if you need some video memory for internal use by the accelerator
* code (for example storing pattern data), you can define this value to
* reserve room for yourself at the very end of the memory space, that
* the application will not be allowed to use.
*/
#define RESERVED_VRAM 0
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_linear;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
int af_fore_mix;
int af_back_mix;
int af_lines_per_bank;
/* note about VBE/AF multiple page modes: the API supports any number of
* video memory pages, one of which is "active" (being drawn onto), while
* the other is visible on your monitor. Allegro doesn't actually use
* this functionality, so you may safely leave it out and just reject
* any mode set requests with a numBuffers value greater than one, but
* that might upset other VBE/AF applications if they depend on this
* functionality. To support multiple pages, you must offset all the
* hardware drawing operations so their coordinate system is relative
* to the active page. You must also maintain an offset from the start
* of vram to the start of the active page in the OriginOffset of the
* driver structure, and adjust the OffscreenStartY and OffscreenEndY
* values so they will refer to the same offscreen memory region regardless
* of the current accelerator coordinate system. This is all handled by the
* SetActiveBuffer() function below, so in practice you can simply add
* af_active_page*af_height onto the input Y coordinate of any accelerator
* drawing funcs, and multiple page modes should work correctly.
*/
#define ALG_NONE 0
#define ALG_2101 1
#define ALG_2201 2
#define ALG_2228 3
#define ALG_2301 4
#define ALG_UNKNOWN 5
int port_crtc = 0x3d4;
int port_attr = 0x3c0;
int port_seq = 0x3c4;
int port_grc = 0x3ce;
int alg_version = ALG_NONE, alg_vidmem = 0;
char *alg_name[6] = {
"none", "ALG-2101", "ALG-2201", "ALG-2228", "ALG-2301", "unknown"
};
int alg_caps[6] = {
0,
afHaveMultiBuffer | afHaveBankedBuffer | afHaveVirtualScroll /*| afHaveDualBuffers */,
afHaveMultiBuffer | afHaveBankedBuffer | afHaveVirtualScroll /*| afHaveDualBuffers */,
afHaveMultiBuffer | afHaveBankedBuffer | afHaveVirtualScroll /*| afHaveDualBuffers */,
afHaveMultiBuffer | afHaveBankedBuffer | afHaveVirtualScroll /*| afHaveDualBuffers */,
0
};
struct mode_t {
int mode;
int w,h;
int bpp;
};
#define MAX_MODES 20
struct mode_t mode_list[] = {
/* mode width height bpp */
{ 0x28, 512, 512, 8 },
{ 0x29, 640, 400, 8 },
{ 0x2a, 640, 480, 8 },
{ 0x2c, 800, 600, 8 },
{ 0x2e, 768, 1024, 8 },
{ 0x31, 1024, 768, 8 },
{ 0x33, 1024, 1024, 8 },
{ 0x37, 1280, 1024, 8 },
{ 0x40, 320, 200, 16 },
{ 0x41, 512, 512, 16 },
{ 0x42, 640, 400, 16 },
{ 0x43, 640, 480, 16 },
{ 0x44, 800, 600, 16 },
{ 0x45, 1024, 768, 16 },
{ 0x48, 640, 480, 24 },
{ 0x49, 800, 600, 24 },
{ 0, 0, 0, 0 }
};
short available_modes[MAX_MODES] = { -1 };
static inline void clrinx (int pt, int inx, int val)
{
write_vga_register (pt, inx, read_vga_register (pt, inx) & ~val);
}
static inline void setinx (int pt, int inx, int val)
{
write_vga_register (pt, inx, read_vga_register (pt, inx) | val);
}
static inline void modinx (int pt, int inx, int mask, int nwv)
{
write_vga_register (pt, inx, (read_vga_register (pt, inx) & ~mask) | (nwv & mask));
}
/* detect_alg:
* Sees whether or not an Avance Logic graphics card is present,
* and if one is it attempts to identify it.
*/
int detect_alg()
{
int old;
alg_version = ALG_NONE;
alg_vidmem = 0;
old = read_vga_register (port_crtc, 0x1a);
clrinx (port_crtc, 0x1a, 0x10);
if (!test_vga_register (port_crtc, 0x19, 0xcf)) {
setinx (port_crtc, 0x1a, 0x10);
if (test_vga_register (port_crtc, 0x19, 0xcf) && test_vga_register (port_crtc, 0x1a, 0x3f)) {
int tmp = read_vga_register (port_crtc, 0x1a) >> 6;
switch (tmp) {
case 3:
alg_version = ALG_2101;
break;
case 2:
if (read_vga_register (port_crtc, 0x1b) & 4)
alg_version = ALG_2228;
else
alg_version = ALG_2301;
break;
case 1:
alg_version = ALG_2201;
default:
alg_version = ALG_UNKNOWN;
}
alg_vidmem = 256 << (read_vga_register (port_crtc, 0x1e) & 3);
}
}
write_vga_register (port_crtc, 0x1a, old);
return alg_version;
}
/* create_available_mode_list:
* Scans the mode list checking memory requirements. Modes
* which pass the test go into the available_modes list.
*/
void create_available_mode_list()
{
struct mode_t *mode;
short *current_mode_in_list = available_modes;
for (mode = mode_list; mode->mode; mode++)
if (mode->w * mode->h * BYTES_PER_PIXEL (mode->bpp) < alg_vidmem * 1024)
*current_mode_in_list++ = mode->mode;
*current_mode_in_list = -1;
}
/* SetupDriver:
* The first thing ever to be called after our code has been relocated.
* This is in charge of filling in the driver header with all the required
* information and function pointers. We do not yet have access to the
* video memory, so we can't talk directly to the card.
*/
int SetupDriver(AF_DRIVER *af)
{
int i;
if (!detect_alg()) return -1;
create_available_mode_list();
/* pointer to a list of the available mode numbers, ended by -1 */
af->AvailableModes = available_modes;
/* amount of video memory in K */
af->TotalMemory = alg_vidmem;
/* driver attributes (see definitions in vbeaf.h) */
af->Attributes = alg_caps[alg_version];
#if 0
if (linear_addr)
af->Attributes |= afHaveLinearBuffer;
#endif
/* banked memory size and location: zero if not supported */
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
/* linear framebuffer size and location: zero if not supported */
af->LinearSize = 0;
af->LinearBasePtr = 0;
/* list which ports we are going to access (only needed under Linux) */
af->IOPortsTable = ports_table;
/* list physical memory regions that we need to access (zero for none) */
for (i=0; i<4; i++) {
af->IOMemoryBase[i] = 0;
af->IOMemoryLen[i] = 0;
}
/* driver state variables (initialised later during the mode set) */
af->BufferEndX = 0;
af->BufferEndY = 0;
af->OriginOffset = 0;
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
/* relocatable bank switcher (not required by Allgero) */
af->SetBank32 = SetBank32;
af->SetBank32Len = (long)SetBank32End - (long)SetBank32;
/* extension functions */
af->SupplementalExt = ExtStub;
/* device driver functions */
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->EnableStereoMode = NULL;
af->SetPaletteData = SetPaletteData;
af->SetGammaCorrectData = NULL;
af->SetBank = SetBank;
/* hardware cursor functions */
af->SetCursor = NULL;
af->SetCursorPos = NULL;
af->SetCursorColor = NULL;
af->ShowCursor = NULL;
/* wait until the accelerator hardware has finished drawing */
af->WaitTillIdle = WaitTillIdle;
/* on some cards the CPU cannot access the framebuffer while it is in
* hardware drawing mode. If this is the case, you should fill in these
* functions with routines to switch in and out of the accelerator mode.
* The application will call EnableDirectAccess() whenever it is about
* to write to the framebuffer directly, and DisableDirectAccess()
* before it calls any hardware drawing routines. If this arbitration is
* not required, leave these routines as NULL.
*/
af->EnableDirectAccess = NULL;
af->DisableDirectAccess = NULL;
/* sets the hardware drawing mode (solid, XOR, etc). Required. */
af->SetMix = SetMix;
/* pattern download functions. May be NULL if patterns not supported */
af->Set8x8MonoPattern = NULL;
af->Set8x8ColorPattern = NULL;
af->Use8x8ColorPattern = NULL;
/* not supported: not used by Allegro */
af->SetLineStipple = NULL;
af->SetLineStippleCount = NULL;
/* not supported. There really isn't much point in this function because
* a lot of hardware can't do clipping at all, and even when it can there
* are usually problems with very large or negative coordinates. This
* means that a software clip is still required, so you may as well
* ignore this routine.
*/
af->SetClipRect = NULL;
/* DrawScan() is required: patterned versions may be NULL */
af->DrawScan = NULL;
af->DrawPattScan = NULL;
af->DrawColorPattScan = NULL;
/* not supported: not used by Allegro */
af->DrawScanList = NULL;
af->DrawPattScanList = NULL;
af->DrawColorPattScanList = NULL;
/* rectangle filling: may be NULL */
af->DrawRect = NULL;
af->DrawPattRect = NULL;
af->DrawColorPattRect = NULL;
/* line drawing: may be NULL */
af->DrawLine = NULL;
/* not supported: not used by Allegro */
af->DrawStippleLine = NULL;
/* trapezoid filling: may be NULL */
af->DrawTrap = NULL;
/* not supported: not used by Allegro */
af->DrawTri = NULL;
af->DrawQuad = NULL;
/* monochrome character expansion: may be NULL */
af->PutMonoImage = NULL;
/* not supported: not used by Allegro */
af->PutMonoImageLin = NULL;
af->PutMonoImageBM = NULL;
/* opaque blitting: may be NULL */
af->BitBlt = NULL;
af->BitBltSys = NULL;
/* not supported: not used by Allegro */
af->BitBltLin = NULL;
af->BitBltBM = NULL;
/* masked blitting: may be NULL */
af->SrcTransBlt = NULL;
af->SrcTransBltSys = NULL;
/* not supported: not used by Allegro */
af->SrcTransBltLin = NULL;
af->SrcTransBltBM = NULL;
af->DstTransBlt = NULL;
af->DstTransBltSys = NULL;
af->DstTransBltLin = NULL;
af->DstTransBltBM = NULL;
af->StretchBlt = NULL;
af->StretchBltSys = NULL;
af->StretchBltLin = NULL;
af->StretchBltBM = NULL;
af->SrcTransStretchBlt = NULL;
af->SrcTransStretchBltSys = NULL;
af->SrcTransStretchBltLin = NULL;
af->SrcTransStretchBltBM = NULL;
af->DstTransStretchBlt = NULL;
af->DstTransStretchBltSys = NULL;
af->DstTransStretchBltLin = NULL;
af->DstTransStretchBltBM = NULL;
af->SetVideoInput = NULL;
af->SetVideoOutput = NULL;
af->StartVideoFrame = NULL;
af->EndVideoFrame = NULL;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
* This is in charge of finding the card, returning 0 on success or
* -1 to abort.
*/
int InitDriver(AF_DRIVER *af)
{
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* findmode:
* Finds the given mode's entry in the mode list.
*/
struct mode_t *findmode (int mode)
{
struct mode_t *ret;
for (ret = mode_list; ret->mode; ret++)
if (ret->mode == mode) return ret;
return NULL;
}
/* get_field_data:
* Fills in the mask size and position of each part of a pixel
* for the given colour depth.
*/
void get_field_data (int bpp, char *rm, char *rp, char *gm, char *gp, char *bm, char *bp, char *xm, char *xp)
{
int pos = 0;
#define FIELD(xxx,size) *xxx##p = pos; pos += (*xxx##m = size)
switch (bpp) {
case 15:
FIELD (b, 5);
FIELD (g, 5);
FIELD (r, 5);
FIELD (x, 1);
break;
case 16:
FIELD (b, 5);
FIELD (g, 6);
FIELD (r, 5);
FIELD (x, 0);
break;
case 24:
FIELD (b, 8);
FIELD (g, 8);
FIELD (r, 8);
FIELD (x, 0);
break;
case 32:
FIELD (b, 8);
FIELD (g, 8);
FIELD (r, 8);
FIELD (x, 8);
break;
default:
FIELD (b, 0);
FIELD (g, 0);
FIELD (r, 0);
FIELD (x, 0);
}
#undef FIELD
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
int i;
int bytes_per_scanline;
struct mode_t *info = findmode (mode);
if (!info) return -1;
/* clear the structure to zero */
for (i = 0; i < (int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
/* copy data across from our stored list of mode attributes */
modeInfo->Attributes = alg_caps[alg_version];
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
bytes_per_scanline = info->w * BYTES_PER_PIXEL(info->bpp);
/* available pages of video memory */
modeInfo->MaxBuffers = (alg_vidmem * 1024 - RESERVED_VRAM) /
(bytes_per_scanline * info->h);
/* maximum virtual scanline length in both bytes and pixels. How wide
* this can go will very much depend on the card: 1024 is pretty safe
* on anything, but you will want to allow larger limits if the card
* is capable of them.
*/
modeInfo->MaxScanLineWidth = 1024;
modeInfo->MaxBytesPerScanLine = modeInfo->MaxScanLineWidth*BYTES_PER_PIXEL(info->bpp);
/* for banked video modes, fill in these variables: */
modeInfo->BytesPerScanLine = bytes_per_scanline;
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
get_field_data (
info->bpp,
&modeInfo->RedMaskSize, &modeInfo->RedFieldPosition,
&modeInfo->GreenMaskSize, &modeInfo->GreenFieldPosition,
&modeInfo->BlueMaskSize, &modeInfo->BlueFieldPosition,
&modeInfo->RsvdMaskSize, &modeInfo->RsvdFieldPosition
);
/* for linear video modes, fill in these variables: */
modeInfo->LinBytesPerScanLine = bytes_per_scanline;
modeInfo->LinMaxBuffers = modeInfo->MaxBuffers;
modeInfo->LinRedMaskSize = modeInfo->RedMaskSize;
modeInfo->LinRedFieldPosition = modeInfo->RedFieldPosition;
modeInfo->LinGreenMaskSize = modeInfo->GreenMaskSize;
modeInfo->LinGreenFieldPosition = modeInfo->GreenFieldPosition;
modeInfo->LinBlueMaskSize = modeInfo->BlueMaskSize;
modeInfo->LinBlueFieldPosition = modeInfo->BlueFieldPosition;
modeInfo->LinRsvdMaskSize = modeInfo->RsvdMaskSize;
modeInfo->LinRsvdFieldPosition = modeInfo->RsvdFieldPosition;
/* I'm not sure exactly what these should be: Allegro doesn't use them */
modeInfo->MaxPixelClock = 135000000;
modeInfo->VideoCapabilities = 0;
modeInfo->VideoMinXScale = 0;
modeInfo->VideoMinYScale = 0;
modeInfo->VideoMaxXScale = 0;
modeInfo->VideoMaxYScale = 0;
return 0;
}
/* setvstart:
* Sets the display start address.
*/
void setvstart (int x, int y)
{
int addr = af_width * y + x * BYTES_PER_PIXEL (af_bpp);
int display, pixels;
if (read_vga_register (port_grc, 0x0c) & 0x10) {
display = addr >> 3;
pixels = addr & 7;
} else {
display = addr >> 2;
pixels = addr & 3;
}
write_vga_register (port_crtc, 0x20, (display >> 16) & 0x07);
write_vga_register (port_crtc, 0x0c, (display >> 8) & 0xff);
write_vga_register (port_crtc, 0x0d, display & 0xff);
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*
* Possible flag bits that may be or'ed with the mode number:
*
* 0x8000 = don't clear video memory
* 0x4000 = enable linear framebuffer
* 0x2000 = enable multi buffering
* 0x1000 = enable virtual scrolling
* 0x0800 = use refresh rate control
* 0x0400 = use hardware stereo
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
int linear = ((mode & 0x4000) != 0);
long available_vram;
long used_vram;
struct mode_t *info;
RM_REGS r;
int interlaced, word_mode, double_word_mode, _8maps, shift;
/* reject anything with hardware stereo */
if (mode & 0x400)
return -1;
/* mask off the other flag bits */
mode &= 0x3FF;
info = findmode (mode);
if (!info) return -1;
/* reject the linear flag if the mode doesn't support it */
if (linear) return -1;
/* set the mode */
r.x.ax = info->mode;
rm_int (0x10, &r);
if (r.h.ah) return -1;
setinx (port_crtc, 0x1A, 0x10); /* enable extensions */
setinx (port_crtc, 0x19, 0x02); /* enable >256k */
setinx (port_grc, 0x0F, 0x04); /* enable separate R/W banks */
af_bpp = info->bpp;
/* get some information about the mode */
interlaced = read_vga_register (port_crtc, 0x19) & 1;
double_word_mode = !!(read_vga_register (port_crtc, 0x14) & 0x40);
word_mode = !(read_vga_register (port_crtc, 0x17) & 0x40);
_8maps = !!(read_vga_register (0x3ce, 0x0c) & 0x10);
/* calculate the shift factor for the scanline byte width */
shift = 0;
if (_8maps) shift++;
if (double_word_mode)
shift += 3;
else if (word_mode)
shift += 2;
else
shift++;
if (interlaced) shift--;
/* sort out the virtaul screen size */
af_width = MAX (info->w, virtualX) * BYTES_PER_PIXEL (af_bpp);
af_width = (((af_width - 1) >> shift) + 1) << shift;
/* test: force it to be power of two */
{
int i = 1;
while (i < af_width) i <<= 1;
af_width = i;
}
/* Set scanline width */
write_vga_register (port_crtc, 0x13, af_width >> shift);
/* could also write bit 8 to port_crtc:0x28 bit 8 */
af_height = MAX (info->h, virtualY);
af_linear = linear;
af_lines_per_bank = af->BankSize * 1024 / af_width;
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
setvstart (af_scroll_x, af_scroll_y);
af_bank = 0;
/* return framebuffer dimensions to the application */
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory * 1024 - RESERVED_VRAM;
if (used_vram > available_vram) return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
} else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
af_fore_mix = AF_REPLACE_MIX;
af_back_mix = AF_FORE_MIX;
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
af_scroll_x = x;
af_scroll_y = y;
if (waitVRT >= 0) setvstart (x, y);
if (waitVRT == 1) {
while (inportb (0x3da) & 8);
while (!(inportb (0x3da) & 8));
}
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* SetBank32:
* Relocatable bank switch function. This is called with a bank number in
* %edx. I'm not sure what registers it is allowed to clobber, so it is
* probably a good idea to save them all.
*
* This function may be copied anywhere within the address space of the
* calling program, so it must be 100% relocatable. That means that you
* must not refer to any internal variables of the /AF driver, because
* you know nothing about where in memory it will be located. Your only
* input is the bank number in %edx, and your only output should be
* changing the relevant hardware registers.
*
* If you are unable to provide a relocatable bank switcher of this type,
* remove this function (clear the SetBank32 pointer to NULL during the
* header init), and fill in the SetBank() routine below instead. Allegro
* only ever uses SetBank(), so there will be no problem with leaving this
* function out, but you may have problems running other VBE/AF
* applications if you don't provide it.
*/
asm ("
#
.globl _SetBank32, _SetBank32End
.align 4
_SetBank32:
pushal
andl $0x1F, %edx # Bank numbers are 5-bit
movl %edx, %eax
movl $0x3d6, %edx # 0x3d6 = read bank select port
outb %al, %dx
movl $0x3d7, %edx # 0x3d7 = r/w bank select port
outb %al, %dx
popal
ret
_SetBank32End:
#
");
/* SetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable SetBank32() above. If you can't provide a relocatable
* function (because you need access to global variables or some part
* of the /AF driver structure), you should put the bank switch code
* here instead.
*/
void SetBank(AF_DRIVER *af, long bank)
{
asm (
" call _SetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}
/* WaitTillIdle:
* Delay until the hardware controller has finished drawing.
*/
void WaitTillIdle(AF_DRIVER *af)
{
#ifndef USE_ALTERNATIVE_IDLE_CHECK
while (inportb (0x82aa) & 0x0f);
#else
while (inportb (0x82ba) & 0x80);
#endif
}
/* SetMix:
* Specifies the pixel mix mode to be used for hardware drawing functions
* (not the blit routines: they take an explicit mix parameter). Both
* parameters should be one of the AF_mixModes enum defined in vbeaf.h.
*
* VBE/AF requires all drivers to support the REPLACE, AND, OR, XOR,
* and NOP foreground mix types, and a background mix of zero (same as
* the foreground) or NOP. This file implements all the required types,
* but Allegro only actually uses the REPLACE and XOR modes for scanline
* and rectangle fills, REPLACE mode for blitting and color pattern
* drawing, and either REPLACE or foreground REPLACE and background NOP
* for mono pattern drawing.
*
* If you want, you can set the afHaveROP2 bit in the mode attributes
* field and then implement all the AF_R2_* modes as well, but that isn't
* required by the spec, and Allegro never uses them.
*/
void SetMix(AF_DRIVER *af, long foreMix, long backMix)
{
af_fore_mix = foreMix;
if (backMix == AF_FORE_MIX)
af_back_mix = foreMix;
else
af_back_mix = backMix;
}

45
avance/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Avance Logic driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

59
avance/notes.txt Normal file
View File

@ -0,0 +1,59 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Avance Logic driver notes
Notes:
This is based upon the stub driver implementation, with
ALG-specific code added bit by bit.
Information on the Avance Logic range of cards is taken
from the VGADOC package.
As far as I know, this driver should support the following
cards:
ALG-2101, ALG-2201, ALG-2228, ALG-2301, ALG-2302
Some of these cards can provide hardware acceleration on
blits and lines, and a hardware cursor. Support for these
features is not yet implemented into this driver.
Special note for ALG-2101 and ALG-2302 users:
I'm not quite sure how to tell the difference between
ALG-2101 and ALG-2302; I have the latter but have found
no specific documentation about it. The documented
detection routines return ALG-2101. I have used an
underdocumented register to try to tell the difference,
but this might not work. If you have either of these
and the driver detects the wrong one, please let me know.
It won't affect the operation of the driver; it's just
nice when a program detects your hardware correctly.
History:
13/04/98 -- first version; just a copy of the stub driver.
15/04/98 -- removed VESA code, replaced with hardware-
level code.
20/04/98 -- finished implementing DrawScan, started lying
about supporting hardware acceleration, tested with
Allegro, corrected big bug in DrawScan.
01/11/98 -- Shawn Hargreaves removed hardware acceleration bodge: it
now admits that it is a dumb framebuffer driver :-)
Author:
George Foot <george.foot@merton.oxford.ac.uk>

264
cirrus54/cirdefs.h Normal file
View File

@ -0,0 +1,264 @@
#ifndef CIR_DEFS_H
#define CIR_DEFS_H
#include <pc.h>
typedef enum {
CLGD5426, //1
CLGD5428, //1
CLGD5429, //2
CLGD5430, //3
CLGD5434, //4
CLGD5434E, //5
CLGD5436, //6
CLGD5440, //7
CLGD5446, //8
CLGD5480, //9
CLGD7541, //10
CLGD7542, //11
CLGD7543, //10
CLGD7548, //12
CLGD7555, //13
CLGD7556 //13
} cirrus_types;
#define KNOWN_CARDS 16
//54m30
//54m40 - triple buffer, transparent color register
/*
1 - the oldest BitBLT capable chips, !!for color-expand with transparency
transparent color is used !!, maxwidth 2047, maxpitch 4095, maxheight 1023,
all BitBLT registers except src&dstaddr are preserved, allow at most 7 bits
to be discarded with color expansion at the end of each scanline, color
expansion and hw cursor in 8 and 15/16bpp supported
2 - supports MMIO at b8000 or at the end of linear address space (2mb-256),
!!for color-expand with transparency 0 bits are just skipped!!, maxpitch 8191, color expansion
with left edge clipping&pattern vertical preset, supports color expanded
pattern polygon fills
3 - like 2, ? need srcaddr to be written for color expansion system to
screen ?, hw cursor also at 24/32bpp
4 - like 3, but 64 bit, maxwidth 8191, doesn't support clipping&vertical
preset and polygon fills, color expansion in 32bpp supported, for color
expansion with transparency all 4 bytes of fg color has to be written and 4
bytes of color has to be filled with not fg color, has bug in system to
display memory transfers, hw cursor also at 24/32bpp,
5 - the bug is corrected
6 - like 2, but 64 bit, maxwidth 8191, maxheight 2047,supports solid fill,
color expansion in 24 and 32bpp, for 24bpp color expansion transparency must
be enabled, but can invert the meaning of input data, so normal color
expansion can de done in two passes, has auto-start capability, hw cursor
also at 24/32bpp, triple buffer ?
7 - like 3 with video features
8 - like 9, no clipping, no X-Y pos.
9 - like 6, has clip rectangle, X-Y positioning, command list with possible
interrupt on completion, left edge clipping more complex, can probably triple
buffer, color expand with uses transparent color, no transparent mask
10 - (7541,7543) like 1, height is _not_ preserved
11 - (7542) don't know anything
12 - (7548) like 1 with MMIO, autostart, height is _not_ preserved
13 - (7555-6) like 6, MMIO in PCI 0x14 or offset 0x3fff00, triple buffer
GR16-17, no 32bpp color expansion, autostart
if banked GR6[3:2]=01,SR17[6]=0,SR17[7:4]=0
else SR17[6]=1,SR17[7:4]!=0
*/
typedef struct {
cirrus_types model;
int biosnum,pcinum;
char *desc;
int family;
} CIRRUS_DETECT;
extern unsigned long af_mmio;
#define GRX 0x3ce
#define _crtc 0x3d4
__inline__ void _vsync_out_h()
{
do {
} while (inportb(0x3DA) & 1);
}
/* _vsync_out_v:
* Waits until the VGA is not in a vertical retrace.
*/
__inline__ void _vsync_out_v()
{
do {
} while (inportb(0x3DA) & 8);
}
/* _vsync_in:
* Waits until the VGA is in the vertical retrace period.
*/
__inline__ void _vsync_in()
{
do {
} while (!(inportb(0x3DA) & 8));
}
/* _write_hpp:
* Writes to the VGA pelpan register.
*/
__inline__ void _write_hpp(int value)
{
write_vga_register(0x3C0, 0x33, value);
}
#define outm1(index, value) *(volatile char *)(af_mmio + index) = (value)
#define outm2(index, value) *(volatile short *)(af_mmio + index) = (value)
#define outm4(index, value) *(volatile long *)(af_mmio + index) = (value)
#define inmb(index) *(volatile char *)(af_mmio + index)
__inline__ void outp1(unsigned short port,unsigned char index,unsigned char value)
{
unsigned short w;
w=index;
w|=value<<8;
outportw(port,w);
}
__inline__ void outp2(unsigned short port,unsigned char index,unsigned short value)
{
unsigned short w;
w=index;
w|=((value&0xff)<<8);
outportw(port,w);
w=index+1;
w|=(value&0xff00);
outportw(port,w);
}
__inline__ void outp3(unsigned short port,unsigned char index,unsigned long value)
{
unsigned short w;
w=index;
w|=(value&0xff)<<8;
outportw(port,w);
w=index+1;
w|=(value&0xff00);
outportw(port,w);
w=index+2;
w|=(value>>8)&0xff00;
outportw(port,w);
}
#define DISABLE() asm volatile ("cli");
#define ENABLE() asm volatile ("sti");
#define CIR_FORG8(color) outp1(GRX,0x01,(color))
#define CIR_FORG16(color) outp1(GRX,0x01,(color) & 0xff); \
outp1(GRX,0x11,((color)>>8) & 0xff)
#define CIR_FORG24(color) outp1(GRX,0x01,(color) & 0xff); \
outp1(GRX,0x11,((color)>>8) & 0xff); \
outp1(GRX,0x13,((color)>>16) & 0xff)
#define CIR_FORG32(color) outp1(GRX,0x01,(color) & 0xff); \
outp1(GRX,0x11,((color)>>8) & 0xff); \
outp1(GRX,0x13,((color)>>16) & 0xff); \
outp1(GRX,0x15,((color)>>24) & 0xff)
#define CIR_BACKG8(color) outp1(GRX,0x00,(color))
#define CIR_BACKG16(color) outp1(GRX,0x00,(color) & 0xff); \
outp1(GRX,0x10,((color)>>8) & 0xff)
#define CIR_BACKG24(color) outp1(GRX,0x00,(color) & 0xff); \
outp1(GRX,0x10,((color)>>8) & 0xff); \
outp1(GRX,0x12,((color)>>16) & 0xff)
#define CIR_BACKG32(color) outp1(GRX,0x00,(color) & 0xff); \
outp1(GRX,0x10,((color)>>8) & 0xff); \
outp1(GRX,0x12,((color)>>16) & 0xff); \
outp1(GRX,0x14,((color)>>24) & 0xff)
#define CIR_FORG8MMIO(color) outm1(0x04,(color))
#define CIR_FORG16MMIO(color) outm2(0x04,(color))
#define CIR_FORG24MMIO(color) outm4(0x04,(color))
#define CIR_FORG32MMIO(color) outm4(0x04,(color))
#define CIR_BACKG8MMIO(color) outm1(0x00,(color))
#define CIR_BACKG16MMIO(color) outm2(0x00,(color))
#define CIR_BACKG24MMIO(color) outm4(0x00,(color))
#define CIR_BACKG32MMIO(color) outm4(0x00,(color))
#define SET_WIDTH_HEIGHTMMIO(width,height) outm4(0x08,(width)|(((height)<<16)))
#define SET_PITCHESMMIO(src,dst) outm4(0x0c,(dst)|((src)<<16)
#define SET_DSTADDRMMIO(address) outm4(0x10,address)
/* in last byte of is left edge clipping - to be added */
#define SET_SRCADDRMMIO(address) outm4(0x14,address)
#define CIR_ROP_MODEMMIO(rop,mode) outm4(0x18,(mode)|((rop)<<16))
#define CIR_BLTROPMMIO(rop) outm1(0x1a,rop)
#define CIR_BLTMODEMMIO(mode) outm1(0x18,mode)
#define CIR_WIDTH(width) outp2(GRX,0x20,width)
#define CIR_HEIGHT(height) outp2(GRX,0x22,height)
#define CIR_DSTPITCH(pitch) outp2(GRX,0x24,pitch)
#define CIR_SRCPITCH(pitch) outp2(GRX,0x26,pitch)
#define SET_DSTADDR(address) outp3(GRX,0x28,address)
#define SET_SRCADDR(address) outp3(GRX,0x2c,address)
#define CIR_BLTMODE(mode) outp1(GRX,0x30,mode)
#define CIR_BLTROP(rop) outp1(GRX,0x32,rop)
#define CIR_TRANS(color) outp2(GRX,0x34,(color)); \
outp2(GRX,0x38,0);
#define CIR_TRANSMMIO(color) outm2(0x34,(color))
#define CIR_CMD(cmd) outp1(GRX,0x31,cmd)
#define CIR_CMDMMIO(cmd) outm1(0x40,cmd)
#define CIR_BLT_PIX8 0
#define CIR_BLT_PIX15 16
#define CIR_BLT_PIX16 16
#define CIR_BLT_PIX24 32
#define CIR_BLT_PIX32 48
#define CIR_ROP_COPY 0x0d
#define CIR_ROP_XOR 0x59
#define CIR_ROP_AND 0x05
#define CIR_ROP_OR 0x6d
#define CIR_ROP_NOP 0x00
#define CIR_CMD_RUN 0x02
#define CIR_CMD_BUSY 0x01
#define CIR_BLT_BACK 0x01
#define CIR_BLT_TRANS 0x08
#define CIR_BLT_PATT 0x40
#define CIR_BLT_MEM 0x04
#define CIR_BLT_COLEXP 0x80
#define my_int(num,regs) asm("\
pushal; \
pushl %%esi; \
movl (%%esi),%%edi; \
movl 8(%%esi),%%ebp; \
movl 16(%%esi),%%ebx;\
movl 20(%%esi),%%edx;\
movl 24(%%esi),%%ecx;\
movl 28(%%esi),%%eax;\
pushl 4(%%esi); \
popl %%esi; \
int %1; \
xchgl %%esi,(%%esp); \
movl %%eax,28(%%esi);\
movl %%ecx,24(%%esi);\
movl %%edx,20(%%esi);\
movl %%ebx,16(%%esi);\
movl %%ebp,8(%%esi); \
movl %%edi,(%%esi); \
popl %%eax; \
movl %%eax,4(%%esi); \
popal" \
::"S" (regs), "i" (num))
#endif

2017
cirrus54/driver.c Normal file

File diff suppressed because it is too large Load Diff

45
cirrus54/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Cirrus 54xx driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

58
cirrus54/notes.txt Normal file
View File

@ -0,0 +1,58 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Cirrus 54x driver implementation notes.
Pattern fills may be improved quite a lot for cards which supports starting
on different place of pattern than upper left corner (now I always assume
accelerator can't do that so whenever upper left corner changes I change the
pattern). I also don't understand the notation of raster operations cirrus
supports and so SetMix isn't probably implemented properly.
Because of lack of precise specification of right input data to functions, some
of them may be implemented wrong.
Optimization with -O3 helps a bit, also port accesses are on RING 3 quite slow
so checking is the content of registers changed helped quite a bit. I expect
there might be quite a lot of problem with newer cirruses now, definitely
should work with 5426,5428,7541 and 7543.
***Note: Now also tested with a 5446 (rev A) and modified to work
(Keir Fraser, email: kaf24@cam.ac.uk)
I have had some problems with the memory-mapped IO, specifically when the
registers are mapped to low memory (0xb8000). If you are having problems
getting the driver to work, you can disable MMIO by uncommenting the
DISABLE_MMIO line at the top of driver.c. You should also contact me at
the email address given above to look for a more permanent solution!
Supported functions:
WaitTillIdle()
SetMix()
Set8x8MonoPattern()
Set8x8ColorPattern()
Use8x8ColorPattern()
DrawScan()
DrawPattScan()
DrawColorPattScan()
DrawRect()
DrawPattRect()
DrawColorPattRect()
BitBlt()
SrcTransBlt()
SetCursor
SetCursorPos
SetCursorColor
ShowCursor
SrcTransBltSys()
BitBltSys()
PutMonoImage()
Author: Michal Mertl (Czech Republic)
Email: mime@eunet.cz

12
drv.ld Normal file
View File

@ -0,0 +1,12 @@
OUTPUT_FORMAT("coff-go32")
FORCE_COMMON_ALLOCATION
SECTIONS {
.text 0 : {
*(.text)
*(.data)
*(.bss)
*(COMMON)
}
}

220
drvgen.c Normal file
View File

@ -0,0 +1,220 @@
/* This is a modified DXEGEN.C. Here are the original DXEGEN.C's
copyright notices:
Copyright (C) 1995 Charles Sandmann (sandmann@clio.rice.edu)
This software may be freely distributed with above copyright, no warranty.
Based on code by DJ Delorie, it's really his, enhanced, bugs fixed. */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <coff.h>
#include "vbeaf.h"
extern AF_DRIVER drvhdr;
void exit_cleanup(void)
{
remove("drv__tmp.o");
}
int main(int argc, char **argv)
{
int errors = 0;
unsigned bss_start = 0;
FILHDR fh;
FILE *input_f, *output_f;
SCNHDR sc;
char *data, *strings;
SYMENT *sym;
RELOC *relocs;
int strsz, i;
long init1_offset,init2_offset,init3_offset,element_size,nrelocs,vbe_size;
if (argc < 6)
{
printf("Usage: drvgen output.drv oemext pnpinit initdrv input.o [input2.o ... -lgcc -lc]\n");
return 1;
}
input_f = fopen(argv[5], "rb");
if (!input_f)
{
perror(argv[5]);
return 1;
}
fread(&fh, 1, FILHSZ, input_f);
if (fh.f_nscns != 1 || argc > 5)
{
char command[1024];
fclose(input_f);
strcpy(command,"ld -X -S -r -o drv__tmp.o -L");
strcat(command,getenv("DJDIR"));
strcat(command,"/lib ");
for(i=5;argv[i];i++) {
strcat(command,argv[i]);
strcat(command," ");
}
strcat(command,"-T ../drv.ld");
printf("%s\n",command);
i = system(command);
if(i)
return i;
input_f = fopen("drv__tmp.o", "rb");
if (!input_f)
{
perror(argv[5]);
return 1;
} else
atexit(exit_cleanup);
fread(&fh, 1, FILHSZ, input_f);
if (fh.f_nscns != 1) {
printf("Error: input file has more than one section; use -M for map\n");
return 1;
}
}
fseek(input_f, fh.f_opthdr, 1);
fread(&sc, 1, SCNHSZ, input_f);
init1_offset = -1;
init2_offset = -1;
init3_offset = -1;
element_size = sc.s_size;
nrelocs = sc.s_nreloc;
data = malloc(sc.s_size);
fseek(input_f, sc.s_scnptr, 0);
fread(data, 1, sc.s_size, input_f);
sym = malloc(sizeof(SYMENT)*fh.f_nsyms);
fseek(input_f, fh.f_symptr, 0);
fread(sym, fh.f_nsyms, SYMESZ, input_f);
fread(&strsz, 1, 4, input_f);
strings = malloc(strsz);
fread(strings+4, 1, strsz-4, input_f);
strings[0] = 0;
for (i=0; i<(int)fh.f_nsyms; i++)
{
char tmp[9], *name;
if (sym[i].e.e.e_zeroes)
{
memcpy(tmp, sym[i].e.e_name, 8);
tmp[8] = 0;
name = tmp;
}
else
name = strings + sym[i].e.e.e_offset;
#if 0
printf("[%3d] 0x%08x 0x%04x 0x%04x %d %s\n",
i,
sym[i].e_value,
sym[i].e_scnum & 0xffff,
sym[i].e_sclass,
sym[i].e_numaux,
name
);
#endif
if (sym[i].e_scnum == 0)
{
printf("Error: object contains unresolved external symbols (%s)\n", name);
errors ++;
}
if (strncmp(name, argv[2], strlen(argv[2])) == 0)
{
if (init1_offset != -1)
{
printf("Error: multiple symbols that start with %s (%s)!\n", argv[2], name);
errors++;
}
init1_offset = sym[i].e_value;
} else if (strncmp(name, argv[3], strlen(argv[3])) == 0)
{
if (init2_offset != -1)
{
printf("Error: multiple symbols that start with %s (%s)!\n", argv[3], name);
errors++;
}
init2_offset = sym[i].e_value;
} else if (strncmp(name, argv[4], strlen(argv[4])) == 0)
{
if (init3_offset != -1)
{
printf("Error: multiple symbols that start with %s (%s)!\n", argv[4], name);
errors++;
}
init3_offset = sym[i].e_value;
} else if (strcmp(name, ".bss") == 0 && !bss_start) {
bss_start = sym[i].e_value;
/* printf("bss_start 0x%x\n",bss_start); */
memset(data+bss_start, 0, sc.s_size - bss_start);
}
i += sym[i].e_numaux;
}
if (init1_offset == -1)
{
printf("Error: symbol %s not found!\n", argv[2]);
errors++;
}
if (init2_offset == -1)
{
printf("Error: symbol %s not found!\n", argv[3]);
errors++;
}
if (init3_offset == -1)
{
printf("Error: symbol %s not found!\n", argv[4]);
errors++;
}
relocs = malloc(sizeof(RELOC)*sc.s_nreloc);
fseek(input_f, sc.s_relptr, 0);
fread(relocs, sc.s_nreloc, RELSZ, input_f);
#if 0
for (i=0; i<sc.s_nreloc; i++)
printf("0x%08x %3d 0x%04x - 0x%08x\n",
relocs[i].r_vaddr,
relocs[i].r_symndx,
relocs[i].r_type,
*(long *)(data + relocs[i].r_vaddr)
);
#endif
fclose(input_f);
if (errors)
return errors;
output_f = fopen(argv[1], "wb");
if (!output_f)
{
perror(argv[1]);
return 1;
}
for (i=0; i<sc.s_nreloc; i++)
if(relocs[i].r_type == 0x14) /* Don't do these, they are relative */
nrelocs--;
vbe_size=sizeof(drvhdr) + (1+nrelocs)*sizeof(long);
drvhdr.OemExt=(void*)(vbe_size+init1_offset);
drvhdr.PlugAndPlayInit=(void*)(vbe_size+init2_offset);
drvhdr.InitDriver=(void*)(vbe_size+init3_offset);
fwrite(&drvhdr, 1, sizeof(drvhdr), output_f);
fwrite(&nrelocs, 1, sizeof(nrelocs), output_f);
for (i=0; i<sc.s_nreloc; i++)
if(relocs[i].r_type != 0x14) /* Don't do these, they are relative */
fwrite(&(relocs[i].r_vaddr), 1, sizeof(long), output_f);
fwrite(data, 1, sc.s_size, output_f);
fclose(output_f);
return 0;
}

428
freebe._tx Normal file
View File

@ -0,0 +1,428 @@
@#
@# This is the source for the FreeBE/AF readme file, in a weird custom
@# format borrowed from the Allegro documentation. Read the Allegro
@# makedoc.c file for a description of what is going on...
@#
@<html>
@<head>
@<title>FreeBE/AF - the free VBE/AF driver project</title>
@<body>
@<pre>
@startoutput readme.txt
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ &lt| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
The free VBE/AF driver project, version 1.2
<a href="http://www.talula.demon.co.uk/freebe/">http://www.talula.demon.co.uk/freebe/</a>
"The nice thing about standards is that
there are so many of them to choose from."
@</pre>
@heading
Introduction
VBE/AF is a low level driver interface for accessing graphics hardware.
It provides all the same features as VESA 3.0 (access to linear
framebuffer video memory, high speed protected mode bank switching, page
flipping, hardware scrolling, etc), and adds the ability to use 2D
hardware acceleration in an efficient and portable manner. An /AF driver
is provided as a disk file (vbeaf.drv), and contains clean 32 bit machine
code which can be called directly by a C program. If implemented
correctly, these drivers have the potential to be binary portable across
multiple operating systems, so the same driver file can be used from DOS,
Windows, Linux, etc.
FreeBE/AF is an attempt to implement free VBE/AF drivers on as many cards
as possible. This idea came about on the Allegro mailing list, due to the
need for a dynamically loadable driver structure that could support
hardware acceleration. VBE/AF seemed to fit the bill, and Allegro already
had support for the SciTech drivers, so it seemed like a good idea to
adopt this format for ourselves. The primary goal is to make these
drivers work with Allegro, so the emphasis will be on implementing the
functions that Allegro actually uses, but we encourage other developers
to join us in taking advantage of this excellent driver architecture.
This project currently provides fully accelerated drivers for a handful
of chipsets, plus a number of dumb framebuffer implementations based on
the video drivers from older versions of the Allegro library. It has also
defined a few extensions to the stock VBE/AF API, which allow Allegro
programs to use these drivers in a true protected mode environment
without having to resort to the nearptr hack, and provide a number of
hook functions that will be needed to remain compatible with future
generations of the SciTech drivers.
The current status of the VBE/AF standard is somewhat confused. It was
designed by SciTech Software (<a href="http://www.scitechsoft.com/">http://www.scitechsoft.com/</a>), who provide
commercial VBE/AF drivers for a wide range of cards as part of their
Display Doctor package. It was originally going to be released as a VESA
standard, but the VESA people seriously messed this up by charging
exorbitant sums of $$$ for copies of the spec. As a result, very few
people bothered to support these drivers, and the FreeBE/AF project was
only made possible by the information available in the SciTech MGL
library source code, and the helpfulness of Kendall Bennett (the designer
of the spec) himself. Unfortunately SciTech have now abandoned VBE/AF
themselves, replacing it with an equivalent but non-public API called
Nucleus, which is only available under NDA. SciTech will continue to
provide VBE/AF drivers for the cards which they already support, but
will not adding any new ones in the future, so this project is now the
only active source of VBE/AF driver implementations.
At present, the Allegro (<a href="http://www.talula.demon.co.uk/allegro/">http://www.talula.demon.co.uk/allegro/</a>) and MGL
(<a href="http://www.scitechsoft.com">http://www.scitechsoft.com</a>) libraries are the only major packages which
can take advantage of accelerated VBE/AF drivers. As such, this project
is starting to look more like a implementation of video drivers
specifically for the Allegro library, rather than a potential
industry-wide standard :-) But it doesn't have to be this way! VBE/AF is
technically an excellent design: efficient, easy to write and use, and
highly portable. If you are writing graphics code, and getting frustrated
by the many limitiations imposed by VESA, why not think about using
VBE/AF instead? Even better, if you have a card that our project doesn't
yet support, why not add a new driver for it? This can be a lot of fun,
and we would be delighted to offer any help or advice that you might need.
@endoutput readme.txt
@heading
Usage
Each driver is located in a different subdirectory. Run "make" to compile
them, choose the one you want, copy the vbeaf.drv file from this
directory to c:\, and you are ready to go!
The stub directory contains a generic non-accelerated VBE/AF driver. This
is not useful in any way, because it simply sits on top of your existing
VESA driver and emulates a few "hardware" drawing operations with very
slow software implementations. The stub is intended as a starting point
for people who want to make drivers for a specific card, and should not
be used directly.
To recompile FreeBE/AF, you need a working copy of djgpp. Run "make" to
build all the available drivers, or "make dir/vbeaf.drv" to compile a
specific driver (replacing {dir} with the directory name, eg. "make
stub/vbeaf.drv"). To build the install.exe program for a binary
distribution, run "make all" (this requires you to have the Allegro
library installed, and the allegro/tools/ directory in your path). This
documentation is converted from the custom ._tx format into ASCII and
HTML by the Allegro makedoc program: run "make docs" to do this, after
putting the makedoc utility somewhere in your path.
FreeBE/AF only supports the VBE/AF 2.0 API. It is not backward compatible
with the assembler VBE/AF 1.0 interface, and programs that try to use
those obsolete functions will not work correctly.
@startoutput readme.txt
@heading
Supported Hardware
Not all VBE/AF drivers provide the complete set of possible features.
Some may be written in a 100% clean and portable manner, allowing them to
be used on any platform, but others make use of the video BIOS in order
to set the initial video mode: this makes them a lot easier to write, but
means that it can only be used under DOS. Some of the drivers, in
particular the ones based on the old Allegro library chipset support,
don't support any hardware accelerated drawing at all: these are still
usefull because they provide high speed protected mode bank switching and
can work around the bugs in some manufacturer's VESA implementations, but
are obviously not nearly as cool as a fully accelerated driver.
This table lists the currently available FreeBE/AF drivers, and what
features they each provide:<br><br><br>
<table border=3 cellborder=1 cellspacing=2 cellpadding=8>
<tr><td>ATI 18800/28800</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
</tr>
<tr><td>ATI mach64</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>No FreeBE/AF extensions</td>
<td>Hardware accelerated</td>
</tr>
<tr><td>Avance Logic ALG-2101, ALG-2201, ALG-2228, ALG-2301, ALG-2302</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>No FreeBE/AF extensions</td>
<td>Dumb framebuffer</td>
</tr>
<tr><td>Cirrus 54xx (not 546x). Should be ok with 5426, 5428, 7541, 7543</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>No FreeBE/AF extensions</td>
<td>Hardware accelerated</td>
</tr>
<tr><td>Matrox Millenium, Mystique, Millenium II</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>Supports farptr and config extensions</td>
<td>Hardware accelerated</td>
</tr>
<tr><td>NVidia Riva 128, TNT. Conflicts with Windows!</td>
<td>100% portable</td>
<td>Banked and linear modes</td>
<td>Supports config extension</td>
<td>Hardware accelerated</td>
</tr>
<tr><td>Paradise</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
</tr>
<tr><td>S3</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Hardware accelerated</td>
</tr>
<tr><td>Trident TGUI 9440. Doesn't work under Windows!</td>
<td>100% portable</td>
<td>Banked and linear modes</td>
<td>No FreeBE/AF extensions</td>
<td>Hardware accelerated</td>
</tr>
<tr><td>Trident</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
</tr>
<tr><td>Tseng ET3000/ET4000/ET6000</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
</tr>
<tr><td>Video-7</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
</tr>
<tr><td>stub driver (for testing and development purposes only)</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>Supports farptr and config extensions</td>
<td>Slow software emulation of hardware drawing functions</td></tr></table>
@endoutput readme.txt
@heading
Contributing
If you want to add a new driver, follow these steps:
<pre>
md cardname
copy stub\*.* cardname
edit makefile
{ add a new entry to the DRIVERS variable at the top of the file }
cd cardname
edit drvhdr.c
{ replace "stub driver implementation" with your driver name }
edit driver.c
{ fill in the blanks, replacing the VESA calls with chipset-specific }
{ code, and fleshing out the accelerated drawing functions }
edit notes.txt
{ describe anything interesting about your driver, most importantly }
{ listing what drawing functions it supports in hardware }
cd..
done!
</pre>
The makefile requires each driver to provide a drvhdr.c file, which will
be linked into the drvgen.exe utility and used to generate the VBE/AF
header. You must also provide a notes.txt, which will be displayed by the
installation program, but everything else is entirely up to you. Any C
source files placed into your driver directory will automatically be
compiled and linked into the driver binary, so you can organise your code
in whatever style you prefer.
Because the VBE/AF drivers are output as relocatable binary modules, they
cannot use any C library functions. There are a few utility functions in
helper.c, but these will not work on any platforms other than DOS+DPMI,
so it would be better to avoid using them if you can manage without.
A great deal of hardware information can be found in the VGADOC package
(<a href="ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/vgadoc4b.zip">ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/vgadoc4b.zip</a>) and the
XFree86 sources (<a href="http://www.xfree86.org/">http://www.xfree86.org/</a>). If this isn't enough, try
asking the manufacturer for more details.
@heading
Files
<pre>
freebe.txt - ASCII format documentation
freebe.html - HTML format documentation
freebe._tx - custom format documentation source file
makefile - script for building the drivers
vbeaf.h - VBE/AF structures and constants
start.s - driver relocation code
helper.c - debugging trace printf() and VESA helper routines
drvgen.c - modified version of DXEGEN, for building vbeaf.drv
drv.ld - linker script
install.c - installation program for binary distributions
stub/vbeaf.drv - example driver, using VESA to access the hardware
stub/driver.c - main implementation file for the example driver
stub/drvhdr.c - VBE/AF header structure for the example driver
stub/notes.txt - more information about the example driver
ati/ - ATI 18800/28800 driver, based on old Allegro code
avance/ - Avance Logic driver, by George Foot
cirrus54/ - Cirrus 54x driver, by Michal Mertl
mach64/ - ATI mach64 driver, by Ove Kaaven
matrox/ - Matrox driver, by Shawn Hargreaves
nvidia/ - NVidia driver, by Shawn Hargreaves
paradise/ - Paradise driver, based on old Allegro code
s3/ - S3 driver, by Michal Stencl
tgui/ - Trident TGUI 9440 driver, by Salvador Eduardo Tropea
trident/ - Trident driver, based on old Allegro code
tseng/ - Tseng driver, based on old Allegro code
video7/ - Video-7 driver, based on old Allegro code
</pre>
@startoutput readme.txt
@heading
Copyright
As the name implies, FreeBE/AF is free. Both the driver binaries and
sources may be distributed and modified without restriction. If you find
any of this stuff useful, the best way to repay us is by writing a new
driver for a card that isn't currently supported.
Disclaimer: no warranty is provided with this software. We are not to be
held liable if it fries your monitor, eats your graphics card, or roasts
your motherboard.
@heading
Credits
The DRVGEN utility is based on the djgpp DXEGEN system, by Charles
Sandmann (<a href="mailto:sandmann@clio.rice.edu">sandmann@clio.rice.edu</a>) and DJ Delorie (<a href="mailto:dj@delorie.com">dj@delorie.com</a>).
Linking/relocation system and ATI mach64 driver by Ove Kaaven
(<a href="mailto:ovek@arcticnet.no">ovek@arcticnet.no</a>).
VBE/AF framework, stub driver, Matrox driver, NVidia driver, most of the
old Allegro chipset drivers, conversion from Allegro to VBE/AF format,
and installation program by Shawn Hargreaves (<a href="mailto:shawn@talula.demon.co.uk">shawn@talula.demon.co.uk</a>).
Cirrus 54x driver by Michal Mertl (<a href="mailto:mime@eunet.cz">mime@eunet.cz</a>).
Trident TGUI 9440 driver by Salvador Eduardo Tropea (<a href="mailto:set-soft@usa.net">set-soft@usa.net</a>).
Avance Logic driver by George Foot (<a href="mailto:george.foot@merton.oxford.ac.uk">george.foot@merton.oxford.ac.uk</a>).
Fixes to the Cirrus 5446 MMIO routines by Keir Fraser (<a href="mailto:kaf24@cam.ac.uk">kaf24@cam.ac.uk</a>).
Tseng ET6000 support by Ben Chauveau (<a href="mailto:bendomc@worldnet.fr">bendomc@worldnet.fr</a>).
Paradise driver by Francois Charton (<a href="mailto:deef@pobox.oleane.com">deef@pobox.oleane.com</a>).
Tseng ET4000 15/24 bit support by Marco Campinoti (<a href="mailto:marco@etruscan.li.it">marco@etruscan.li.it</a>).
Trident driver improved by Mark Habersack (<a href="mailto:grendel@ananke.amu.edu.pl">grendel@ananke.amu.edu.pl</a>).
Video-7 fixes by Markus Oberhumer (<a href="mailto:markus.oberhumer@jk.uni-linz.ac.at">markus.oberhumer@jk.uni-linz.ac.at</a>).
S3 driver improved by Michael Bukin (<a href="mailto:M.A.Bukin@inp.nsk.su">M.A.Bukin@inp.nsk.su</a>).
Video-7 driver by Peter Monks (<a href="mailto:Peter_Monks@australia.notes.pw.com">Peter_Monks@australia.notes.pw.com</a>).
S3 hardware acceleration by Michal Stencl (<a href="mailto:stenclpmd@ba.telecom.sk">stenclpmd@ba.telecom.sk</a>).
Website logo by Colin Walsh (<a href="mailto:cwalsh@nf.sympatico.ca">cwalsh@nf.sympatico.ca</a>).
More graphics hardware support by [insert your name here] :-)
VBE/AF itself is the brainchild of SciTech software, and in particular
Kendall Bennett (<a href="mailto:KendallB@scitechsoft.com">KendallB@scitechsoft.com</a>).
The Video Electronics Standards Association does _not_ deserve any
mention here. The absurd prices they charge for copies of the /AF
specification have prevented it from being widely supported, and I think
this is a great pity. Long live freedom!
@heading
History
30 March, 1998 - v0.1.
First public release, containing an example driver implementation that
runs on top of VESA.
31 March, 1998 - v0.11.
Added support for multi-buffered modes.
5 April, 1998 - v0.2.
Added an accelerated Matrox driver.
8 April, 1998 - v0.3.
Added accelerated drivers for ATI mach64 and Cirrus 54x cards, plus
minor updates to the Matrox driver.
12 April, 1998 - v0.4.
Proper installation program, more drawing functions implemented by the
stub and Matrox drivers, improved ATI driver, compiled with PGCC for a
5% speed boost.
26 April, 1998 - v0.5.
More accelerated features in the Cirrus and ATI drivers. Fixed bugs in
the Matrox driver. Added an option to disable hardware emulation in
the stub driver, which produces a non-accelerated, dumb framebuffer
implementation. The init code will now politely fail any programs that
try to use VBE/AF 1.0 functions, rather than just crashing.
10 June, 1998 - v0.6.
Fixed scrolling problem on Millenium cards.
1 November, 1998 - v0.7.
Added drivers for Trident TGUI 9440 and Avance Logic cards, and
improved the build process.
14 December, 1998 - v0.8.
Bugfixes to the Matrox Millenium II and Cirrus drivers. Converted all
the old Allegro library chipset drivers into non-accelerated VBE/AF
format, adding support for ATI 18800/28800, Paradise, S3, Trident,
Tseng ET3000/ET4000/ET6000, and Video-7 boards. Designed and
implemented an API extension mechanism, providing the ability to use
these drivers in a true protected mode environment, a more rational
relocation scheme, and various hooks that will later be needed for
supporting the SciTech Nucleus drivers.
20 December, 1998 - v0.9.
Bugfixes. Added a config mechanism, allowing the install program to
optionally disable some features of a driver.
3 January, 1999 - v1.0
Bugfixes.
27 March, 1999 - v1.1
Added acceleration support to the S3 driver, plus some bugfixes.
27 June, 1999 - v1.2
Added driver for NVidia cards. Improved the PCI bus scanning code to
know about bridges to secondary devices (so it can locate AGP cards).
Minor bugfix to the Mach64 driver (it was using the wrong clip rect
for scrolling displays). Minor bugfix to the Matrox driver (it was
setting the wrong background color for the hardware cursor).

411
freebe.html Normal file
View File

@ -0,0 +1,411 @@
<html>
<head>
<title>FreeBE/AF - the free VBE/AF driver project</title>
<body>
<pre>
<p>
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ &lt;| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
<p>
<br>
The free VBE/AF driver project, version 1.2
<p>
<a href="http://www.talula.demon.co.uk/freebe/">http://www.talula.demon.co.uk/freebe/</a>
<p>
<br>
"The nice thing about standards is that
there are so many of them to choose from."
</pre>
<p>
<br>
<br>
<h1><a name="Introduction">Introduction</a></h1>
<p>
VBE/AF is a low level driver interface for accessing graphics hardware.
It provides all the same features as VESA 3.0 (access to linear
framebuffer video memory, high speed protected mode bank switching, page
flipping, hardware scrolling, etc), and adds the ability to use 2D
hardware acceleration in an efficient and portable manner. An /AF driver
is provided as a disk file (vbeaf.drv), and contains clean 32 bit machine
code which can be called directly by a C program. If implemented
correctly, these drivers have the potential to be binary portable across
multiple operating systems, so the same driver file can be used from DOS,
Windows, Linux, etc.
<p>
FreeBE/AF is an attempt to implement free VBE/AF drivers on as many cards
as possible. This idea came about on the Allegro mailing list, due to the
need for a dynamically loadable driver structure that could support
hardware acceleration. VBE/AF seemed to fit the bill, and Allegro already
had support for the SciTech drivers, so it seemed like a good idea to
adopt this format for ourselves. The primary goal is to make these
drivers work with Allegro, so the emphasis will be on implementing the
functions that Allegro actually uses, but we encourage other developers
to join us in taking advantage of this excellent driver architecture.
<p>
This project currently provides fully accelerated drivers for a handful
of chipsets, plus a number of dumb framebuffer implementations based on
the video drivers from older versions of the Allegro library. It has also
defined a few extensions to the stock VBE/AF API, which allow Allegro
programs to use these drivers in a true protected mode environment
without having to resort to the nearptr hack, and provide a number of
hook functions that will be needed to remain compatible with future
generations of the SciTech drivers.
<p>
The current status of the VBE/AF standard is somewhat confused. It was
designed by SciTech Software (<a href="http://www.scitechsoft.com/">http://www.scitechsoft.com/</a>), who provide
commercial VBE/AF drivers for a wide range of cards as part of their
Display Doctor package. It was originally going to be released as a VESA
standard, but the VESA people seriously messed this up by charging
exorbitant sums of $$$ for copies of the spec. As a result, very few
people bothered to support these drivers, and the FreeBE/AF project was
only made possible by the information available in the SciTech MGL
library source code, and the helpfulness of Kendall Bennett (the designer
of the spec) himself. Unfortunately SciTech have now abandoned VBE/AF
themselves, replacing it with an equivalent but non-public API called
Nucleus, which is only available under NDA. SciTech will continue to
provide VBE/AF drivers for the cards which they already support, but
will not adding any new ones in the future, so this project is now the
only active source of VBE/AF driver implementations.
<p>
At present, the Allegro (<a href="http://www.talula.demon.co.uk/allegro/">http://www.talula.demon.co.uk/allegro/</a>) and MGL
(<a href="http://www.scitechsoft.com">http://www.scitechsoft.com</a>) libraries are the only major packages which
can take advantage of accelerated VBE/AF drivers. As such, this project
is starting to look more like a implementation of video drivers
specifically for the Allegro library, rather than a potential
industry-wide standard :-) But it doesn't have to be this way! VBE/AF is
technically an excellent design: efficient, easy to write and use, and
highly portable. If you are writing graphics code, and getting frustrated
by the many limitiations imposed by VESA, why not think about using
VBE/AF instead? Even better, if you have a card that our project doesn't
yet support, why not add a new driver for it? This can be a lot of fun,
and we would be delighted to offer any help or advice that you might need.
<p>
<br>
<br>
<h1><a name="Usage">Usage</a></h1>
<p>
Each driver is located in a different subdirectory. Run "make" to compile
them, choose the one you want, copy the vbeaf.drv file from this
directory to c:\, and you are ready to go!
<p>
The stub directory contains a generic non-accelerated VBE/AF driver. This
is not useful in any way, because it simply sits on top of your existing
VESA driver and emulates a few "hardware" drawing operations with very
slow software implementations. The stub is intended as a starting point
for people who want to make drivers for a specific card, and should not
be used directly.
<p>
To recompile FreeBE/AF, you need a working copy of djgpp. Run "make" to
build all the available drivers, or "make dir/vbeaf.drv" to compile a
specific driver (replacing {dir} with the directory name, eg. "make
stub/vbeaf.drv"). To build the install.exe program for a binary
distribution, run "make all" (this requires you to have the Allegro
library installed, and the allegro/tools/ directory in your path). This
documentation is converted from the custom ._tx format into ASCII and
HTML by the Allegro makedoc program: run "make docs" to do this, after
putting the makedoc utility somewhere in your path.
<p>
FreeBE/AF only supports the VBE/AF 2.0 API. It is not backward compatible
with the assembler VBE/AF 1.0 interface, and programs that try to use
those obsolete functions will not work correctly.
<p>
<br>
<br>
<h1><a name="Supported Hardware">Supported Hardware</a></h1>
<p>
Not all VBE/AF drivers provide the complete set of possible features.
Some may be written in a 100% clean and portable manner, allowing them to
be used on any platform, but others make use of the video BIOS in order
to set the initial video mode: this makes them a lot easier to write, but
means that it can only be used under DOS. Some of the drivers, in
particular the ones based on the old Allegro library chipset support,
don't support any hardware accelerated drawing at all: these are still
usefull because they provide high speed protected mode bank switching and
can work around the bugs in some manufacturer's VESA implementations, but
are obviously not nearly as cool as a fully accelerated driver.
<p>
This table lists the currently available FreeBE/AF drivers, and what
features they each provide:<br><br><br>
<p> <table border=3 cellborder=1 cellspacing=2 cellpadding=8>
<tr><td>ATI 18800/28800</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
<p> </tr>
<tr><td>ATI mach64</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>No FreeBE/AF extensions</td>
<td>Hardware accelerated</td>
<p> </tr>
<tr><td>Avance Logic ALG-2101, ALG-2201, ALG-2228, ALG-2301, ALG-2302</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>No FreeBE/AF extensions</td>
<td>Dumb framebuffer</td>
<p> </tr>
<tr><td>Cirrus 54xx (not 546x). Should be ok with 5426, 5428, 7541, 7543</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>No FreeBE/AF extensions</td>
<td>Hardware accelerated</td>
<p> </tr>
<tr><td>Matrox Millenium, Mystique, Millenium II</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>Supports farptr and config extensions</td>
<td>Hardware accelerated</td>
<p> </tr>
<tr><td>NVidia Riva 128, TNT. Conflicts with Windows!</td>
<td>100% portable</td>
<td>Banked and linear modes</td>
<td>Supports config extension</td>
<td>Hardware accelerated</td>
<p> </tr>
<tr><td>Paradise</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
<p> </tr>
<tr><td>S3</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Hardware accelerated</td>
<p> </tr>
<tr><td>Trident TGUI 9440. Doesn't work under Windows!</td>
<td>100% portable</td>
<td>Banked and linear modes</td>
<td>No FreeBE/AF extensions</td>
<td>Hardware accelerated</td>
<p> </tr>
<tr><td>Trident</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
<p> </tr>
<tr><td>Tseng ET3000/ET4000/ET6000</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
<p> </tr>
<tr><td>Video-7</td>
<td>Uses BIOS</td>
<td>Banked modes only</td>
<td>Supports farptr extension</td>
<td>Dumb framebuffer</td>
<p> </tr>
<tr><td>stub driver (for testing and development purposes only)</td>
<td>Uses BIOS</td>
<td>Banked and linear modes</td>
<td>Supports farptr and config extensions</td>
<td>Slow software emulation of hardware drawing functions</td></tr></table>
<p>
<br>
<br>
<h1><a name="Contributing">Contributing</a></h1>
<p>
If you want to add a new driver, follow these steps:
<p><pre>
md cardname
copy stub\*.* cardname
edit makefile
{ add a new entry to the DRIVERS variable at the top of the file }
cd cardname
edit drvhdr.c
{ replace "stub driver implementation" with your driver name }
edit driver.c
{ fill in the blanks, replacing the VESA calls with chipset-specific }
{ code, and fleshing out the accelerated drawing functions }
edit notes.txt
{ describe anything interesting about your driver, most importantly }
{ listing what drawing functions it supports in hardware }
cd..
done!
<p></pre>
The makefile requires each driver to provide a drvhdr.c file, which will
be linked into the drvgen.exe utility and used to generate the VBE/AF
header. You must also provide a notes.txt, which will be displayed by the
installation program, but everything else is entirely up to you. Any C
source files placed into your driver directory will automatically be
compiled and linked into the driver binary, so you can organise your code
in whatever style you prefer.
<p>
Because the VBE/AF drivers are output as relocatable binary modules, they
cannot use any C library functions. There are a few utility functions in
helper.c, but these will not work on any platforms other than DOS+DPMI,
so it would be better to avoid using them if you can manage without.
<p>
A great deal of hardware information can be found in the VGADOC package
(<a href="ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/vgadoc4b.zip">ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/vgadoc4b.zip</a>) and the
XFree86 sources (<a href="http://www.xfree86.org/">http://www.xfree86.org/</a>). If this isn't enough, try
asking the manufacturer for more details.
<p>
<br>
<br>
<h1><a name="Files">Files</a></h1>
<p><pre>
freebe.txt - ASCII format documentation
freebe.html - HTML format documentation
freebe._tx - custom format documentation source file
makefile - script for building the drivers
vbeaf.h - VBE/AF structures and constants
start.s - driver relocation code
helper.c - debugging trace printf() and VESA helper routines
drvgen.c - modified version of DXEGEN, for building vbeaf.drv
drv.ld - linker script
install.c - installation program for binary distributions
<p>
stub/vbeaf.drv - example driver, using VESA to access the hardware
stub/driver.c - main implementation file for the example driver
stub/drvhdr.c - VBE/AF header structure for the example driver
stub/notes.txt - more information about the example driver
<p>
ati/ - ATI 18800/28800 driver, based on old Allegro code
avance/ - Avance Logic driver, by George Foot
cirrus54/ - Cirrus 54x driver, by Michal Mertl
mach64/ - ATI mach64 driver, by Ove Kaaven
matrox/ - Matrox driver, by Shawn Hargreaves
nvidia/ - NVidia driver, by Shawn Hargreaves
paradise/ - Paradise driver, based on old Allegro code
s3/ - S3 driver, by Michal Stencl
tgui/ - Trident TGUI 9440 driver, by Salvador Eduardo Tropea
trident/ - Trident driver, based on old Allegro code
tseng/ - Tseng driver, based on old Allegro code
video7/ - Video-7 driver, based on old Allegro code
<p></pre>
<br>
<br>
<h1><a name="Copyright">Copyright</a></h1>
<p>
As the name implies, FreeBE/AF is free. Both the driver binaries and
sources may be distributed and modified without restriction. If you find
any of this stuff useful, the best way to repay us is by writing a new
driver for a card that isn't currently supported.
<p>
Disclaimer: no warranty is provided with this software. We are not to be
held liable if it fries your monitor, eats your graphics card, or roasts
your motherboard.
<p>
<br>
<br>
<h1><a name="Credits">Credits</a></h1>
<p>
The DRVGEN utility is based on the djgpp DXEGEN system, by Charles
Sandmann (<a href="mailto:sandmann@clio.rice.edu">sandmann@clio.rice.edu</a>) and DJ Delorie (<a href="mailto:dj@delorie.com">dj@delorie.com</a>).
<p>
Linking/relocation system and ATI mach64 driver by Ove Kaaven
(<a href="mailto:ovek@arcticnet.no">ovek@arcticnet.no</a>).
<p>
VBE/AF framework, stub driver, Matrox driver, NVidia driver, most of the
old Allegro chipset drivers, conversion from Allegro to VBE/AF format,
and installation program by Shawn Hargreaves (<a href="mailto:shawn@talula.demon.co.uk">shawn@talula.demon.co.uk</a>).
<p>
Cirrus 54x driver by Michal Mertl (<a href="mailto:mime@eunet.cz">mime@eunet.cz</a>).
<p>
Trident TGUI 9440 driver by Salvador Eduardo Tropea (<a href="mailto:set-soft@usa.net">set-soft@usa.net</a>).
<p>
Avance Logic driver by George Foot (<a href="mailto:george.foot@merton.oxford.ac.uk">george.foot@merton.oxford.ac.uk</a>).
<p>
Fixes to the Cirrus 5446 MMIO routines by Keir Fraser (<a href="mailto:kaf24@cam.ac.uk">kaf24@cam.ac.uk</a>).
<p>
Tseng ET6000 support by Ben Chauveau (<a href="mailto:bendomc@worldnet.fr">bendomc@worldnet.fr</a>).
<p>
Paradise driver by Francois Charton (<a href="mailto:deef@pobox.oleane.com">deef@pobox.oleane.com</a>).
<p>
Tseng ET4000 15/24 bit support by Marco Campinoti (<a href="mailto:marco@etruscan.li.it">marco@etruscan.li.it</a>).
<p>
Trident driver improved by Mark Habersack (<a href="mailto:grendel@ananke.amu.edu.pl">grendel@ananke.amu.edu.pl</a>).
<p>
Video-7 fixes by Markus Oberhumer (<a href="mailto:markus.oberhumer@jk.uni-linz.ac.at">markus.oberhumer@jk.uni-linz.ac.at</a>).
<p>
S3 driver improved by Michael Bukin (<a href="mailto:M.A.Bukin@inp.nsk.su">M.A.Bukin@inp.nsk.su</a>).
<p>
Video-7 driver by Peter Monks (<a href="mailto:Peter_Monks@australia.notes.pw.com">Peter_Monks@australia.notes.pw.com</a>).
<p>
S3 hardware acceleration by Michal Stencl (<a href="mailto:stenclpmd@ba.telecom.sk">stenclpmd@ba.telecom.sk</a>).
<p>
Website logo by Colin Walsh (<a href="mailto:cwalsh@nf.sympatico.ca">cwalsh@nf.sympatico.ca</a>).
<p>
More graphics hardware support by [insert your name here] :-)
<p>
VBE/AF itself is the brainchild of SciTech software, and in particular
Kendall Bennett (<a href="mailto:KendallB@scitechsoft.com">KendallB@scitechsoft.com</a>).
<p>
The Video Electronics Standards Association does _not_ deserve any
mention here. The absurd prices they charge for copies of the /AF
specification have prevented it from being widely supported, and I think
this is a great pity. Long live freedom!
<p>
<br>
<br>
<h1><a name="History">History</a></h1>
<p>
30 March, 1998 - v0.1.
First public release, containing an example driver implementation that
runs on top of VESA.
<p>
31 March, 1998 - v0.11.
Added support for multi-buffered modes.
<p>
5 April, 1998 - v0.2.
Added an accelerated Matrox driver.
<p>
8 April, 1998 - v0.3.
Added accelerated drivers for ATI mach64 and Cirrus 54x cards, plus
minor updates to the Matrox driver.
<p>
12 April, 1998 - v0.4.
Proper installation program, more drawing functions implemented by the
stub and Matrox drivers, improved ATI driver, compiled with PGCC for a
5% speed boost.
<p>
26 April, 1998 - v0.5.
More accelerated features in the Cirrus and ATI drivers. Fixed bugs in
the Matrox driver. Added an option to disable hardware emulation in
the stub driver, which produces a non-accelerated, dumb framebuffer
implementation. The init code will now politely fail any programs that
try to use VBE/AF 1.0 functions, rather than just crashing.
<p>
10 June, 1998 - v0.6.
Fixed scrolling problem on Millenium cards.
<p>
1 November, 1998 - v0.7.
Added drivers for Trident TGUI 9440 and Avance Logic cards, and
improved the build process.
<p>
14 December, 1998 - v0.8.
Bugfixes to the Matrox Millenium II and Cirrus drivers. Converted all
the old Allegro library chipset drivers into non-accelerated VBE/AF
format, adding support for ATI 18800/28800, Paradise, S3, Trident,
Tseng ET3000/ET4000/ET6000, and Video-7 boards. Designed and
implemented an API extension mechanism, providing the ability to use
these drivers in a true protected mode environment, a more rational
relocation scheme, and various hooks that will later be needed for
supporting the SciTech Nucleus drivers.
<p>
20 December, 1998 - v0.9.
Bugfixes. Added a config mechanism, allowing the install program to
optionally disable some features of a driver.
<p>
3 January, 1999 - v1.0
Bugfixes.
<p>
27 March, 1999 - v1.1
Added acceleration support to the S3 driver, plus some bugfixes.
<p>
27 June, 1999 - v1.2
Added driver for NVidia cards. Improved the PCI bus scanning code to
know about bridges to secondary devices (so it can locate AGP cards).
Minor bugfix to the Mach64 driver (it was using the wrong clip rect
for scrolling displays). Minor bugfix to the Matrox driver (it was
setting the wrong background color for the hardware cursor).
<p>

80
freebe.mft Normal file
View File

@ -0,0 +1,80 @@
freebe/
freebe/makefile
freebe/drvgen.c
freebe/vbeaf.h
freebe/start.s
freebe/drv.ld
freebe/zipup.btm
freebe/freebe._tx
freebe/helper.c
freebe/install.c
freebe/nvidia/
freebe/nvidia/notes.txt
freebe/nvidia/riva_hw.c
freebe/nvidia/riva_hw.h
freebe/nvidia/drvhdr.c
freebe/nvidia/font.h
freebe/nvidia/driver.c
freebe/nvidia/riva_tbl.h
freebe/freebe.html
freebe/video7/
freebe/video7/driver.c
freebe/video7/drvhdr.c
freebe/video7/notes.txt
freebe/tseng/
freebe/tseng/driver.c
freebe/tseng/drvhdr.c
freebe/tseng/notes.txt
freebe/trident/
freebe/trident/driver.c
freebe/trident/drvhdr.c
freebe/trident/notes.txt
freebe/paradise/
freebe/paradise/driver.c
freebe/paradise/drvhdr.c
freebe/paradise/notes.txt
freebe/s3/
freebe/s3/driver.c
freebe/s3/drvhdr.c
freebe/s3/notes.txt
freebe/tgui/
freebe/tgui/notes.txt
freebe/tgui/driver.c
freebe/tgui/setmode.c
freebe/tgui/drvhdr.c
freebe/tgui/mytypes.h
freebe/tgui/regs.h
freebe/tgui/rw_regs.c
freebe/tgui/font.h
freebe/tgui/setmode.h
freebe/tgui/tgui.h
freebe/tgui/vga.h
freebe/tgui/vbeaf.htm
freebe/tgui/html.frt
freebe/ati/
freebe/ati/driver.c
freebe/ati/drvhdr.c
freebe/ati/notes.txt
freebe/avance/
freebe/avance/driver.c
freebe/avance/drvhdr.c
freebe/avance/notes.txt
freebe/mach64/
freebe/mach64/notes.txt
freebe/mach64/driver.c
freebe/mach64/drvhdr.c
freebe/cirrus54/
freebe/cirrus54/drvhdr.c
freebe/cirrus54/driver.c
freebe/cirrus54/cirdefs.h
freebe/cirrus54/notes.txt
freebe/matrox/
freebe/matrox/notes.txt
freebe/matrox/drvhdr.c
freebe/matrox/driver.c
freebe/stub/
freebe/stub/driver.c
freebe/stub/drvhdr.c
freebe/stub/notes.txt
freebe/freebe.txt
freebe/freebe.mft

421
freebe.txt Normal file
View File

@ -0,0 +1,421 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
The free VBE/AF driver project, version 1.2
http://www.talula.demon.co.uk/freebe/
"The nice thing about standards is that
there are so many of them to choose from."
======================================
============ Introduction ============
======================================
VBE/AF is a low level driver interface for accessing graphics hardware.
It provides all the same features as VESA 3.0 (access to linear
framebuffer video memory, high speed protected mode bank switching, page
flipping, hardware scrolling, etc), and adds the ability to use 2D
hardware acceleration in an efficient and portable manner. An /AF driver
is provided as a disk file (vbeaf.drv), and contains clean 32 bit machine
code which can be called directly by a C program. If implemented
correctly, these drivers have the potential to be binary portable across
multiple operating systems, so the same driver file can be used from DOS,
Windows, Linux, etc.
FreeBE/AF is an attempt to implement free VBE/AF drivers on as many cards
as possible. This idea came about on the Allegro mailing list, due to the
need for a dynamically loadable driver structure that could support
hardware acceleration. VBE/AF seemed to fit the bill, and Allegro already
had support for the SciTech drivers, so it seemed like a good idea to
adopt this format for ourselves. The primary goal is to make these
drivers work with Allegro, so the emphasis will be on implementing the
functions that Allegro actually uses, but we encourage other developers
to join us in taking advantage of this excellent driver architecture.
This project currently provides fully accelerated drivers for a handful
of chipsets, plus a number of dumb framebuffer implementations based on
the video drivers from older versions of the Allegro library. It has also
defined a few extensions to the stock VBE/AF API, which allow Allegro
programs to use these drivers in a true protected mode environment
without having to resort to the nearptr hack, and provide a number of
hook functions that will be needed to remain compatible with future
generations of the SciTech drivers.
The current status of the VBE/AF standard is somewhat confused. It was
designed by SciTech Software (http://www.scitechsoft.com/), who provide
commercial VBE/AF drivers for a wide range of cards as part of their
Display Doctor package. It was originally going to be released as a VESA
standard, but the VESA people seriously messed this up by charging
exorbitant sums of $$$ for copies of the spec. As a result, very few
people bothered to support these drivers, and the FreeBE/AF project was
only made possible by the information available in the SciTech MGL
library source code, and the helpfulness of Kendall Bennett (the designer
of the spec) himself. Unfortunately SciTech have now abandoned VBE/AF
themselves, replacing it with an equivalent but non-public API called
Nucleus, which is only available under NDA. SciTech will continue to
provide VBE/AF drivers for the cards which they already support, but
will not adding any new ones in the future, so this project is now the
only active source of VBE/AF driver implementations.
At present, the Allegro (http://www.talula.demon.co.uk/allegro/) and MGL
(http://www.scitechsoft.com) libraries are the only major packages which
can take advantage of accelerated VBE/AF drivers. As such, this project
is starting to look more like a implementation of video drivers
specifically for the Allegro library, rather than a potential
industry-wide standard :-) But it doesn't have to be this way! VBE/AF is
technically an excellent design: efficient, easy to write and use, and
highly portable. If you are writing graphics code, and getting frustrated
by the many limitiations imposed by VESA, why not think about using
VBE/AF instead? Even better, if you have a card that our project doesn't
yet support, why not add a new driver for it? This can be a lot of fun,
and we would be delighted to offer any help or advice that you might need.
===============================
============ Usage ============
===============================
Each driver is located in a different subdirectory. Run "make" to compile
them, choose the one you want, copy the vbeaf.drv file from this
directory to c:\, and you are ready to go!
The stub directory contains a generic non-accelerated VBE/AF driver. This
is not useful in any way, because it simply sits on top of your existing
VESA driver and emulates a few "hardware" drawing operations with very
slow software implementations. The stub is intended as a starting point
for people who want to make drivers for a specific card, and should not
be used directly.
To recompile FreeBE/AF, you need a working copy of djgpp. Run "make" to
build all the available drivers, or "make dir/vbeaf.drv" to compile a
specific driver (replacing {dir} with the directory name, eg. "make
stub/vbeaf.drv"). To build the install.exe program for a binary
distribution, run "make all" (this requires you to have the Allegro
library installed, and the allegro/tools/ directory in your path). This
documentation is converted from the custom ._tx format into ASCII and
HTML by the Allegro makedoc program: run "make docs" to do this, after
putting the makedoc utility somewhere in your path.
FreeBE/AF only supports the VBE/AF 2.0 API. It is not backward compatible
with the assembler VBE/AF 1.0 interface, and programs that try to use
those obsolete functions will not work correctly.
============================================
============ Supported Hardware ============
============================================
Not all VBE/AF drivers provide the complete set of possible features.
Some may be written in a 100% clean and portable manner, allowing them to
be used on any platform, but others make use of the video BIOS in order
to set the initial video mode: this makes them a lot easier to write, but
means that it can only be used under DOS. Some of the drivers, in
particular the ones based on the old Allegro library chipset support,
don't support any hardware accelerated drawing at all: these are still
usefull because they provide high speed protected mode bank switching and
can work around the bugs in some manufacturer's VESA implementations, but
are obviously not nearly as cool as a fully accelerated driver.
This table lists the currently available FreeBE/AF drivers, and what
features they each provide:
ATI 18800/28800
Uses BIOS
Banked modes only
Supports farptr extension
Dumb framebuffer
ATI mach64
Uses BIOS
Banked and linear modes
No FreeBE/AF extensions
Hardware accelerated
Avance Logic ALG-2101, ALG-2201, ALG-2228, ALG-2301, ALG-2302
Uses BIOS
Banked modes only
No FreeBE/AF extensions
Dumb framebuffer
Cirrus 54xx (not 546x). Should be ok with 5426, 5428, 7541, 7543
Uses BIOS
Banked and linear modes
No FreeBE/AF extensions
Hardware accelerated
Matrox Millenium, Mystique, Millenium II
Uses BIOS
Banked and linear modes
Supports farptr and config extensions
Hardware accelerated
NVidia Riva 128, TNT. Conflicts with Windows!
100% portable
Banked and linear modes
Supports config extension
Hardware accelerated
Paradise
Uses BIOS
Banked modes only
Supports farptr extension
Dumb framebuffer
S3
Uses BIOS
Banked modes only
Supports farptr extension
Hardware accelerated
Trident TGUI 9440. Doesn't work under Windows!
100% portable
Banked and linear modes
No FreeBE/AF extensions
Hardware accelerated
Trident
Uses BIOS
Banked modes only
Supports farptr extension
Dumb framebuffer
Tseng ET3000/ET4000/ET6000
Uses BIOS
Banked modes only
Supports farptr extension
Dumb framebuffer
Video-7
Uses BIOS
Banked modes only
Supports farptr extension
Dumb framebuffer
stub driver (for testing and development purposes only)
Uses BIOS
Banked and linear modes
Supports farptr and config extensions
Slow software emulation of hardware drawing functions
======================================
============ Contributing ============
======================================
If you want to add a new driver, follow these steps:
md cardname
copy stub\*.* cardname
edit makefile
{ add a new entry to the DRIVERS variable at the top of the file }
cd cardname
edit drvhdr.c
{ replace "stub driver implementation" with your driver name }
edit driver.c
{ fill in the blanks, replacing the VESA calls with chipset-specific }
{ code, and fleshing out the accelerated drawing functions }
edit notes.txt
{ describe anything interesting about your driver, most importantly }
{ listing what drawing functions it supports in hardware }
cd..
done!
The makefile requires each driver to provide a drvhdr.c file, which will
be linked into the drvgen.exe utility and used to generate the VBE/AF
header. You must also provide a notes.txt, which will be displayed by the
installation program, but everything else is entirely up to you. Any C
source files placed into your driver directory will automatically be
compiled and linked into the driver binary, so you can organise your code
in whatever style you prefer.
Because the VBE/AF drivers are output as relocatable binary modules, they
cannot use any C library functions. There are a few utility functions in
helper.c, but these will not work on any platforms other than DOS+DPMI,
so it would be better to avoid using them if you can manage without.
A great deal of hardware information can be found in the VGADOC package
(ftp://x2ftp.oulu.fi/pub/msdos/programming/docs/vgadoc4b.zip) and the
XFree86 sources (http://www.xfree86.org/). If this isn't enough, try
asking the manufacturer for more details.
===============================
============ Files ============
===============================
freebe.txt - ASCII format documentation
freebe.html - HTML format documentation
freebe._tx - custom format documentation source file
makefile - script for building the drivers
vbeaf.h - VBE/AF structures and constants
start.s - driver relocation code
helper.c - debugging trace printf() and VESA helper routines
drvgen.c - modified version of DXEGEN, for building vbeaf.drv
drv.ld - linker script
install.c - installation program for binary distributions
stub/vbeaf.drv - example driver, using VESA to access the hardware
stub/driver.c - main implementation file for the example driver
stub/drvhdr.c - VBE/AF header structure for the example driver
stub/notes.txt - more information about the example driver
ati/ - ATI 18800/28800 driver, based on old Allegro code
avance/ - Avance Logic driver, by George Foot
cirrus54/ - Cirrus 54x driver, by Michal Mertl
mach64/ - ATI mach64 driver, by Ove Kaaven
matrox/ - Matrox driver, by Shawn Hargreaves
nvidia/ - NVidia driver, by Shawn Hargreaves
paradise/ - Paradise driver, based on old Allegro code
s3/ - S3 driver, by Michal Stencl
tgui/ - Trident TGUI 9440 driver, by Salvador Eduardo Tropea
trident/ - Trident driver, based on old Allegro code
tseng/ - Tseng driver, based on old Allegro code
video7/ - Video-7 driver, based on old Allegro code
===================================
============ Copyright ============
===================================
As the name implies, FreeBE/AF is free. Both the driver binaries and
sources may be distributed and modified without restriction. If you find
any of this stuff useful, the best way to repay us is by writing a new
driver for a card that isn't currently supported.
Disclaimer: no warranty is provided with this software. We are not to be
held liable if it fries your monitor, eats your graphics card, or roasts
your motherboard.
=================================
============ Credits ============
=================================
The DRVGEN utility is based on the djgpp DXEGEN system, by Charles
Sandmann (sandmann@clio.rice.edu) and DJ Delorie (dj@delorie.com).
Linking/relocation system and ATI mach64 driver by Ove Kaaven
(ovek@arcticnet.no).
VBE/AF framework, stub driver, Matrox driver, NVidia driver, most of the
old Allegro chipset drivers, conversion from Allegro to VBE/AF format,
and installation program by Shawn Hargreaves (shawn@talula.demon.co.uk).
Cirrus 54x driver by Michal Mertl (mime@eunet.cz).
Trident TGUI 9440 driver by Salvador Eduardo Tropea (set-soft@usa.net).
Avance Logic driver by George Foot (george.foot@merton.oxford.ac.uk).
Fixes to the Cirrus 5446 MMIO routines by Keir Fraser (kaf24@cam.ac.uk).
Tseng ET6000 support by Ben Chauveau (bendomc@worldnet.fr).
Paradise driver by Francois Charton (deef@pobox.oleane.com).
Tseng ET4000 15/24 bit support by Marco Campinoti (marco@etruscan.li.it).
Trident driver improved by Mark Habersack (grendel@ananke.amu.edu.pl).
Video-7 fixes by Markus Oberhumer (markus.oberhumer@jk.uni-linz.ac.at).
S3 driver improved by Michael Bukin (M.A.Bukin@inp.nsk.su).
Video-7 driver by Peter Monks (Peter_Monks@australia.notes.pw.com).
S3 hardware acceleration by Michal Stencl (stenclpmd@ba.telecom.sk).
Website logo by Colin Walsh (cwalsh@nf.sympatico.ca).
More graphics hardware support by [insert your name here] :-)
VBE/AF itself is the brainchild of SciTech software, and in particular
Kendall Bennett (KendallB@scitechsoft.com).
The Video Electronics Standards Association does _not_ deserve any
mention here. The absurd prices they charge for copies of the /AF
specification have prevented it from being widely supported, and I think
this is a great pity. Long live freedom!
=================================
============ History ============
=================================
30 March, 1998 - v0.1.
First public release, containing an example driver implementation that
runs on top of VESA.
31 March, 1998 - v0.11.
Added support for multi-buffered modes.
5 April, 1998 - v0.2.
Added an accelerated Matrox driver.
8 April, 1998 - v0.3.
Added accelerated drivers for ATI mach64 and Cirrus 54x cards, plus
minor updates to the Matrox driver.
12 April, 1998 - v0.4.
Proper installation program, more drawing functions implemented by the
stub and Matrox drivers, improved ATI driver, compiled with PGCC for a
5% speed boost.
26 April, 1998 - v0.5.
More accelerated features in the Cirrus and ATI drivers. Fixed bugs in
the Matrox driver. Added an option to disable hardware emulation in
the stub driver, which produces a non-accelerated, dumb framebuffer
implementation. The init code will now politely fail any programs that
try to use VBE/AF 1.0 functions, rather than just crashing.
10 June, 1998 - v0.6.
Fixed scrolling problem on Millenium cards.
1 November, 1998 - v0.7.
Added drivers for Trident TGUI 9440 and Avance Logic cards, and
improved the build process.
14 December, 1998 - v0.8.
Bugfixes to the Matrox Millenium II and Cirrus drivers. Converted all
the old Allegro library chipset drivers into non-accelerated VBE/AF
format, adding support for ATI 18800/28800, Paradise, S3, Trident,
Tseng ET3000/ET4000/ET6000, and Video-7 boards. Designed and
implemented an API extension mechanism, providing the ability to use
these drivers in a true protected mode environment, a more rational
relocation scheme, and various hooks that will later be needed for
supporting the SciTech Nucleus drivers.
20 December, 1998 - v0.9.
Bugfixes. Added a config mechanism, allowing the install program to
optionally disable some features of a driver.
3 January, 1999 - v1.0
Bugfixes.
27 March, 1999 - v1.1
Added acceleration support to the S3 driver, plus some bugfixes.
27 June, 1999 - v1.2
Added driver for NVidia cards. Improved the PCI bus scanning code to
know about bridges to secondary devices (so it can locate AGP cards).
Minor bugfix to the Mach64 driver (it was using the wrong clip rect
for scrolling displays). Minor bugfix to the Matrox driver (it was
setting the wrong background color for the hardware cursor).

649
helper.c Normal file
View File

@ -0,0 +1,649 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Assorted helper routines for use by the /AF drivers.
*
* The code in this file makes heavy use of DPMI and VESA functions,
* so any drivers that use these helpers will not be portable to
* Linux. For maximum portability, a driver should use direct hardware
* access for all features, and not touch any of these routines.
*
* See freebe.txt for copyright information.
*/
#include <stdarg.h>
#include <sys/farptr.h>
#include "vbeaf.h"
/* trace_putc:
* Debugging trace function
*/
void trace_putc(char c)
{
asm (
" int $0x21 "
:
: "a" (0x200),
"d" (c)
: "%eax",
"%ebx",
"%ecx",
"%edx",
"%esi",
"%edi"
);
}
/* trace_printf:
* Debugging trace function: supports %c, %s, %d, and %x
*/
void trace_printf(char *msg, ...)
{
static char hex_digit[] =
{
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
unsigned long l;
char *s;
int c, i;
va_list ap;
va_start(ap, msg);
while (*msg) {
if (*msg == '%') {
/* handle escape token */
msg++;
switch (*msg) {
case '%':
trace_putc('%');
break;
case 'c':
c = va_arg(ap, char);
trace_putc(c);
break;
case 's':
s = va_arg(ap, char *);
while (*s) {
if (*s == '\n')
trace_putc('\r');
trace_putc(*s);
s++;
}
break;
case 'd':
c = va_arg(ap, int);
if (c < 0) {
trace_putc('-');
c = -c;
}
i = 1;
while (i*10 <= c)
i *= 10;
while (i) {
trace_putc('0'+c/i);
c %= i;
i /= 10;
}
break;
case 'x':
l = va_arg(ap, unsigned long);
for (i=7; i>=0; i--)
trace_putc(hex_digit[(l>>(i*4))&0xF]);
break;
}
if (*msg)
msg++;
}
else {
/* output normal character */
if (*msg == '\n')
trace_putc('\r');
trace_putc(*msg);
msg++;
}
}
va_end(ap);
}
/* rm_int:
* Calls a real mode interrupt: basically the same thing as __dpmi_int().
*/
void rm_int(int num, RM_REGS *regs)
{
regs->x.flags = 0;
regs->x.sp = 0;
regs->x.ss = 0;
asm (
" int $0x31 "
:
: "a" (0x300),
"b" (num),
"c" (0),
"D" (regs)
: "%eax",
"%ebx",
"%ecx",
"%edx",
"%esi",
"%edi"
);
}
/* allocate_dos_memory:
* Allocates a block of conventional memory, returning a real mode segment
* address, and filling in the protected mode selector for accessing it.
* Returns -1 on error.
*/
int allocate_dos_memory(int size, int *sel)
{
int rm_seg;
int pm_sel;
int ok;
asm (
" int $0x31 ; "
" jc 0f ; "
" movl $1, %2 ; "
" jmp 1f ; "
" 0: "
" movl $0, %2 ; "
" 1: "
: "=a" (rm_seg),
"=d" (pm_sel),
"=m" (ok)
: "a" (0x100),
"b" ((size+15)/16)
: "%eax",
"%ebx",
"%ecx",
"%edx",
"%esi",
"%edi"
);
if (!ok)
return -1;
*sel = pm_sel;
return rm_seg;
}
/* free_dos_memory:
* Frees a block of conventional memory, given a selector previously
* returned by a call allocate_dos_memory().
*/
void free_dos_memory(int sel)
{
asm (
" int $0x31 "
:
: "a" (0x101),
"d" (sel)
: "%eax",
"%ebx",
"%ecx",
"%edx",
"%esi",
"%edi"
);
}
/* allocate_selector:
* Creates a selector for accessing the specified linear memory region,
* returning a selector value or -1 on error.
*/
int allocate_selector(int addr, int size)
{
int sel;
int ok;
asm (
" int $0x31 ; "
" jc 0f ; "
" movl %%eax, %%ebx ; "
" movl $7, %%eax ; "
" movl %4, %%ecx ; "
" movl %5, %%edx ; "
" int $0x31 ; "
" jc 0f ; "
" movl $8, %%eax ; "
" movl %6, %%ecx ; "
" movl %7, %%edx ; "
" int $0x31 ; "
" jc 0f ; "
" movl $1, %1 ; "
" jmp 1f ; "
" 0: "
" movl $1, %1 ; "
" 1: "
: "=b" (sel),
"=D" (ok)
: "a" (0),
"c" (1),
"m" (addr>>16),
"m" (addr&0xFFFF),
"m" ((size-1)>>16),
"m" ((size-1)&0xFFFF)
: "%eax",
"%ebx",
"%ecx",
"%edx",
"%esi",
"%edi"
);
if (!ok)
return -1;
return sel;
}
/* free_selector:
* Destroys a selector that was previously created with the
* allocate_selector() function.
*/
void free_selector(int sel)
{
asm (
" int $0x31 "
:
: "a" (1),
"b" (sel)
: "%eax",
"%ebx",
"%ecx",
"%edx",
"%esi",
"%edi"
);
}
/* Helper routines for accessing the underlying VESA interface.
*/
#define MASK_LINEAR(addr) (addr & 0x000FFFFF)
#define RM_TO_LINEAR(addr) (((addr & 0xFFFF0000) >> 12) + (addr & 0xFFFF))
#define RM_OFFSET(addr) (addr & 0xF)
#define RM_SEGMENT(addr) ((addr >> 4) & 0xFFFF)
typedef struct VESA_INFO /* VESA information block structure */
{
unsigned char VESASignature[4] __attribute__ ((packed));
unsigned short VESAVersion __attribute__ ((packed));
unsigned long OEMStringPtr __attribute__ ((packed));
unsigned char Capabilities[4] __attribute__ ((packed));
unsigned long VideoModePtr __attribute__ ((packed));
unsigned short TotalMemory __attribute__ ((packed));
unsigned short OemSoftwareRev __attribute__ ((packed));
unsigned long OemVendorNamePtr __attribute__ ((packed));
unsigned long OemProductNamePtr __attribute__ ((packed));
unsigned long OemProductRevPtr __attribute__ ((packed));
unsigned char Reserved[222] __attribute__ ((packed));
unsigned char OemData[256] __attribute__ ((packed));
} VESA_INFO;
typedef struct VESA_MODE_INFO /* VESA information for a specific mode */
{
unsigned short ModeAttributes __attribute__ ((packed));
unsigned char WinAAttributes __attribute__ ((packed));
unsigned char WinBAttributes __attribute__ ((packed));
unsigned short WinGranularity __attribute__ ((packed));
unsigned short WinSize __attribute__ ((packed));
unsigned short WinASegment __attribute__ ((packed));
unsigned short WinBSegment __attribute__ ((packed));
unsigned long WinFuncPtr __attribute__ ((packed));
unsigned short BytesPerScanLine __attribute__ ((packed));
unsigned short XResolution __attribute__ ((packed));
unsigned short YResolution __attribute__ ((packed));
unsigned char XCharSize __attribute__ ((packed));
unsigned char YCharSize __attribute__ ((packed));
unsigned char NumberOfPlanes __attribute__ ((packed));
unsigned char BitsPerPixel __attribute__ ((packed));
unsigned char NumberOfBanks __attribute__ ((packed));
unsigned char MemoryModel __attribute__ ((packed));
unsigned char BankSize __attribute__ ((packed));
unsigned char NumberOfImagePages __attribute__ ((packed));
unsigned char Reserved_page __attribute__ ((packed));
unsigned char RedMaskSize __attribute__ ((packed));
unsigned char RedMaskPos __attribute__ ((packed));
unsigned char GreenMaskSize __attribute__ ((packed));
unsigned char GreenMaskPos __attribute__ ((packed));
unsigned char BlueMaskSize __attribute__ ((packed));
unsigned char BlueMaskPos __attribute__ ((packed));
unsigned char ReservedMaskSize __attribute__ ((packed));
unsigned char ReservedMaskPos __attribute__ ((packed));
unsigned char DirectColorModeInfo __attribute__ ((packed));
/* VBE 2.0 extensions */
unsigned long PhysBasePtr __attribute__ ((packed));
unsigned long OffScreenMemOffset __attribute__ ((packed));
unsigned short OffScreenMemSize __attribute__ ((packed));
/* VBE 3.0 extensions */
unsigned short LinBytesPerScanLine __attribute__ ((packed));
unsigned char BnkNumberOfPages __attribute__ ((packed));
unsigned char LinNumberOfPages __attribute__ ((packed));
unsigned char LinRedMaskSize __attribute__ ((packed));
unsigned char LinRedFieldPos __attribute__ ((packed));
unsigned char LinGreenMaskSize __attribute__ ((packed));
unsigned char LinGreenFieldPos __attribute__ ((packed));
unsigned char LinBlueMaskSize __attribute__ ((packed));
unsigned char LinBlueFieldPos __attribute__ ((packed));
unsigned char LinRsvdMaskSize __attribute__ ((packed));
unsigned char LinRsvdFieldPos __attribute__ ((packed));
unsigned long MaxPixelClock __attribute__ ((packed));
unsigned char Reserved[190] __attribute__ ((packed));
} VESA_MODE_INFO;
#define MAX_VESA_MODES 256
#define SAFETY_BUFFER 4096
/* get_vesa_info:
* Retrieves data from the VESA info block structure and mode list,
* returning 0 for success.
*/
int get_vesa_info(int *vram_size, unsigned long *linear_addr, void (*callback)(int vesa_num, int linear, int w, int h, int bpp, int bytes_per_scanline, int redsize, int redpos, int greensize, int greenpos, int bluesize, int bluepos, int rsvdsize, int rsvdpos))
{
VESA_INFO vesa_info;
VESA_MODE_INFO mode_info;
RM_REGS r;
int mode_list[MAX_VESA_MODES];
long mode_ptr;
int num_modes;
int seg, sel;
int c, i;
/* fetch the VESA info block */
seg = allocate_dos_memory(sizeof(VESA_INFO)+SAFETY_BUFFER, &sel);
if (seg < 0)
return -1;
for (c=0; c<(int)sizeof(VESA_INFO); c++)
_farpokeb(sel, c, 0);
_farpokeb(sel, 0, 'V');
_farpokeb(sel, 1, 'B');
_farpokeb(sel, 2, 'E');
_farpokeb(sel, 3, '2');
r.x.ax = 0x4F00;
r.x.di = 0;
r.x.es = seg;
rm_int(0x10, &r);
if (r.h.ah) {
free_dos_memory(sel);
return -1;
}
for (c=0; c<(int)sizeof(VESA_INFO); c++)
((char *)&vesa_info)[c] = _farpeekb(sel, c);
free_dos_memory(sel);
if ((vesa_info.VESASignature[0] != 'V') ||
(vesa_info.VESASignature[1] != 'E') ||
(vesa_info.VESASignature[2] != 'S') ||
(vesa_info.VESASignature[3] != 'A'))
return -1;
*vram_size = vesa_info.TotalMemory << 16;
if (linear_addr)
*linear_addr = 0;
sel = allocate_selector(0, 1024*1024);
if (sel < 0)
return -1;
/* read the mode list */
mode_ptr = RM_TO_LINEAR(vesa_info.VideoModePtr);
num_modes = 0;
while ((mode_list[num_modes] = _farpeekw(sel, mode_ptr)) != 0xFFFF) {
num_modes++;
mode_ptr += 2;
if (num_modes >= MAX_VESA_MODES)
break;
}
free_selector(sel);
seg = allocate_dos_memory(sizeof(VESA_MODE_INFO)+SAFETY_BUFFER, &sel);
if (seg < 0)
return -1;
/* fetch info about each supported mode */
for (c=0; c<num_modes; c++) {
for (i=0; i<(int)sizeof(VESA_MODE_INFO); i++)
_farpokeb(sel, i, 0);
r.x.ax = 0x4F01;
r.x.di = 0;
r.x.es = seg;
r.x.cx = mode_list[c];
rm_int(0x10, &r);
if (r.h.ah == 0) {
for (i=0; i<(int)sizeof(VESA_MODE_INFO); i++)
((char *)&mode_info)[i] = _farpeekb(sel, i);
if ((mode_info.ModeAttributes & 25) == 25) {
/* bodge for VESA drivers that report wrong values */
if ((mode_info.BitsPerPixel == 16) && (mode_info.ReservedMaskSize == 1))
mode_info.BitsPerPixel = 15;
if (mode_info.ModeAttributes & 128) {
/* linear framebuffer mode */
if (linear_addr)
*linear_addr = mode_info.PhysBasePtr;
if (vesa_info.VESAVersion >= 0x300) {
if (callback) {
callback(mode_list[c], TRUE,
mode_info.XResolution, mode_info.YResolution,
mode_info.BitsPerPixel, mode_info.LinBytesPerScanLine,
mode_info.LinRedMaskSize, mode_info.LinRedFieldPos,
mode_info.LinGreenMaskSize, mode_info.LinGreenFieldPos,
mode_info.LinBlueMaskSize, mode_info.LinBlueFieldPos,
mode_info.LinRsvdMaskSize, mode_info.LinRsvdFieldPos);
}
}
else {
if (callback) {
callback(mode_list[c], TRUE,
mode_info.XResolution, mode_info.YResolution,
mode_info.BitsPerPixel, mode_info.BytesPerScanLine,
mode_info.RedMaskSize, mode_info.RedMaskPos,
mode_info.GreenMaskSize, mode_info.GreenMaskPos,
mode_info.BlueMaskSize, mode_info.BlueMaskPos,
mode_info.ReservedMaskSize, mode_info.ReservedMaskPos);
}
}
}
else {
/* banked mode */
if (callback) {
callback(mode_list[c], FALSE,
mode_info.XResolution, mode_info.YResolution,
mode_info.BitsPerPixel, mode_info.BytesPerScanLine,
mode_info.RedMaskSize, mode_info.RedMaskPos,
mode_info.GreenMaskSize, mode_info.GreenMaskPos,
mode_info.BlueMaskSize, mode_info.BlueMaskPos,
mode_info.ReservedMaskSize, mode_info.ReservedMaskPos);
}
}
}
}
}
free_dos_memory(sel);
return 0;
}
/* FindPCIDevice:
* Replacement for the INT 1A - PCI BIOS v2.0c+ - FIND PCI DEVICE, AX = B102h
*
* Note: deviceIndex is because a card can hold more than one PCI chip.
*
* Searches the board of the vendor supplied in vendorID with
* identification number deviceID and index deviceIndex (normally 0).
* The value returned in handle can be used to access the PCI registers
* of this board.
*
* Return: 1 if found 0 if not found.
*/
int FindPCIDevice(int deviceID, int vendorID, int deviceIndex, int *handle)
{
int model, vendor, card, device;
unsigned value, full_id, bus, busMax;
deviceIndex <<= 8;
/* for each PCI bus */
for (bus=0, busMax=0x10000; bus<busMax; bus+=0x10000) {
/* for each hardware device */
for (device=0, card=0; card<32; card++, device+=0x800) {
value = PCIEnable | bus | deviceIndex | device;
outportl(PCIConfigurationAddress, value);
full_id = inportl(PCIConfigurationData);
/* get the vendor and model ID */
vendor = full_id & 0xFFFF;
model = full_id >> 16;
if (vendor != 0xFFFF) {
/* is this the one we want? */
if ((deviceID == model) && (vendorID == vendor)) {
*handle = value;
return 1;
}
/* is it a bridge to a secondary bus? */
outportl(PCIConfigurationAddress, value | 8);
if (((inportl(PCIConfigurationData) >> 16) == 0x0600) || (full_id==0x00011011))
busMax += 0x10000;
}
}
}
return 0;
}
/* fixup_feature_list:
* Helper for the FAF_CFG_FEATURES extension, for blanking out any
* accelerated drawing routines that the install program has disabled.
*/
void fixup_feature_list(AF_DRIVER *af, unsigned long flags)
{
if (!(flags & fafHWCursor)) {
af->Attributes &= ~afHaveHWCursor;
af->SetCursor = NULL;
af->SetCursorPos = NULL;
af->SetCursorColor = NULL;
af->ShowCursor = NULL;
}
if (!(flags & fafDrawScan)) af->DrawScan = NULL;
if (!(flags & fafDrawPattScan)) af->DrawPattScan = NULL;
if (!(flags & fafDrawColorPattScan)) af->DrawColorPattScan = NULL;
if (!(flags & fafDrawScanList)) af->DrawScanList = NULL;
if (!(flags & fafDrawPattScanList)) af->DrawPattScanList = NULL;
if (!(flags & fafDrawColorPattScanList)) af->DrawColorPattScanList = NULL;
if (!(flags & fafDrawRect)) af->DrawRect = NULL;
if (!(flags & fafDrawPattRect)) af->DrawPattRect = NULL;
if (!(flags & fafDrawColorPattRect)) af->DrawColorPattRect = NULL;
if (!(flags & fafDrawLine)) af->DrawLine = NULL;
if (!(flags & fafDrawStippleLine)) af->DrawStippleLine = NULL;
if (!(flags & fafDrawTrap)) af->DrawTrap = NULL;
if (!(flags & fafDrawTri)) af->DrawTri = NULL;
if (!(flags & fafDrawQuad)) af->DrawQuad = NULL;
if (!(flags & fafPutMonoImage)) af->PutMonoImage = NULL;
if (!(flags & fafPutMonoImageLin)) af->PutMonoImageLin = NULL;
if (!(flags & fafPutMonoImageBM)) af->PutMonoImageBM = NULL;
if (!(flags & fafBitBlt)) af->BitBlt = NULL;
if (!(flags & fafBitBltSys)) af->BitBltSys = NULL;
if (!(flags & fafBitBltLin)) af->BitBltLin = NULL;
if (!(flags & fafBitBltBM)) af->BitBltBM = NULL;
if (!(flags & fafSrcTransBlt)) af->SrcTransBlt = NULL;
if (!(flags & fafSrcTransBltSys)) af->SrcTransBltSys = NULL;
if (!(flags & fafSrcTransBltLin)) af->SrcTransBltLin = NULL;
if (!(flags & fafSrcTransBltBM)) af->SrcTransBltBM = NULL;
}

1396
install.c Normal file

File diff suppressed because it is too large Load Diff

1910
mach64/driver.c Normal file

File diff suppressed because it is too large Load Diff

45
mach64/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF ATI mach64 driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

78
mach64/notes.txt Normal file
View File

@ -0,0 +1,78 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
ATI mach64 driver implementation notes.
This driver is currently a limited implementation of VBE/AF for mach64.
It is not very well tested and may not work for you (if it doesn't,
give me your system description and a description of the problems).
It has a built-in table of known VESA modes, as well as all non-VESA
modes that the mach64 BIOS supports, but currently the non-VESA mode
setting doesn't work properly, so only VESA modes are enabled. However,
it is able to take advantage of extra VESA modes provided by tools like
Scitech Display Doctor.
It supports 8, 15, 16, 24, and 32 bits per pixel, if available. It
currently provides acceleration for these primitives:
DrawScan()
DrawPattScan()
DrawRect()
DrawPattRect()
BitBlt()
SrcTransBlt() (not in 24bpp)
DrawLine() (not in 24bpp)
These accelerated functions are planned and may be provided in the
future:
DrawTrap() (actually the mach64 seems to be able to draw entire
polygons, too bad there isn't a DrawPoly() in VBE/AF;
DrawTri() and DrawQuad() may be possible, but since
they are not widely used, who cares about them)
PutMonoImage() (using HOST transfer, perhaps)
BitBltSys() (using HOST transfer)
SrcTransBltSys() (same here)
SetCursor()
SetCursorPos()
SetCursorColor()
ShowCursor()
This driver is not portable to anything but DOS+DPMI, since it uses
DPMI to communicate with the mach64 BIOS.
Both linear and banked modes are supported, but SetBank32 is in the
current (sloppy) implementation not fully relocatable, but this should
rarely be a problem since linear modes are much more fun anyway.
If you want to have 32bpp and 1600x1200 modes without having to
install Scitech Display Doctor, define REFUSE_VESA and try to find out
why the mach64 mode settings doesn't work properly, then uncomment the
appropriate extra modes, and report to me.
Virtual heights above screen height (for hardware scrolling) may not
work properly above 8bpp, I'm not sure why yet, but it looks like it
could be a bug in Allegro.
DrawLine does not seem to be rounded exactly like Allegro's, which
becomes evident when clipping.
I'm not sure how to do patterns. It is possible to load an 8x8 mono
pattern into the mach64 registers and use it, but I'm not sure how,
but I made a guess and implemented that, and it seems to work, but
I'm not totally sure. As for color patterns, I have just disabled
them since I haven't figured out how to do those yet. It would be
possible to use Shawn's technique; to bitblt them from offscreen VRAM,
but use TILE_X enabled for automatic tiling, but it doesn't seem
worthwhile at present, if there is a better way.
Ove Kaaven <ovek@arcticnet.no>

99
makefile Normal file
View File

@ -0,0 +1,99 @@
##############################################################################
# #
# FreeBE/AF makefile. #
# #
# The default target is 'drivers', which will build all the vbeaf.drv #
# files. Run 'make cardname/vbeaf.drv' to compile a specific driver. #
# #
# To build the install program for a binary distribution, run 'make all'. #
# This requires the Allegro utilties dat.exe and exedat.exe (from the #
# allegro/tools/ directory) to be located somewhere on your path. #
# #
# To reconvert the documentation from the ._tx source, run "make docs". #
# This needs the Allegro makedoc utility (allegro/obj/djgpp/makedoc.exe) #
# to be located somewhere on your path. #
# #
# The 'clean' target requires the rm utility from GNU fileutils. #
# #
##############################################################################
DRIVERS = stub ati avance cirrus54 mach64 matrox \
nvidia paradise s3 tgui trident tseng video7
ifdef DEBUGMODE
CFLAGS = -O -Wall -Werror
else
ifdef PGCC
CFLAGS = -O6 -mpentium -fomit-frame-pointer -Wall -Werror
else
CFLAGS = -O3 -m486 -fomit-frame-pointer -Wall -Werror
endif
endif
.PHONY: dummy drivers install all docs clean
.PRECIOUS: %.o drvgen.exe
drivers: $(addsuffix /vbeaf.drv, $(DRIVERS))
install: install.exe
all: drivers install
ifdef DEBUGMODE
install.exe: install.o drivers.dat
gcc -g -o install.exe install.o -lalleg
exedat -c -a install.exe drivers.dat
else
install.exe: install.o drivers.dat
gcc -s -o install.exe install.o -lalleg
-djp -q install.exe
exedat -c -a install.exe drivers.dat
endif
drivers.dat: $(addsuffix .dat, $(DRIVERS))
dat -a -s1 drivers.dat $(addsuffix .dat, $(DRIVERS))
%.dat: %/vbeaf.drv %/notes.txt
dat -a -s1 $*.dat -t DATA $*/vbeaf.drv $*/notes.txt
#special target needed to force recursive makes
dummy:
%/vbeaf.drv: start.o helper.o drvgen.o dummy
@cd $*
make.exe -f ../makefile IFLAGS=-I.. vbeaf.drv
@cd ..
vbeaf.drv: drvgen.exe ../start.o ../helper.o $(subst drvhdr.o ,,$(subst .c,.o,$(wildcard *.c)))
drvgen vbeaf.drv OemExt PlugAndPlayInit StartDriver $(subst drvgen.exe ,,$^)
drvgen.exe: ../drvgen.o drvhdr.o
gcc -s -o drvgen.exe ../drvgen.o drvhdr.o
%.o: %.c
gcc $(CFLAGS) $(IFLAGS) -MMD -o $@ -c $<
%.o: %.s
gcc -x assembler-with-cpp -o $@ -c $<
docs: freebe.html freebe.txt readme.txt
freebe.html: freebe._tx
makedoc -html freebe.html freebe._tx
freebe.txt: freebe._tx
makedoc -ascii freebe.txt freebe._tx
readme.txt: freebe._tx
makedoc -part -ascii readme.txt freebe._tx
clean:
-rm -rv *.o */*.o *.d */*.d *.exe */*.exe *.dat */*.drv freebe.html freebe.txt readme.txt
-include *.d

2300
matrox/driver.c Normal file

File diff suppressed because it is too large Load Diff

45
matrox/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Matrox driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

55
matrox/notes.txt Normal file
View File

@ -0,0 +1,55 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Matrox driver implementation notes.
This driver supports the Millenium, Mystique, and Millenium II (both PCI
and AGP) cards.
It supports color depths of 8, 15, 16, and 32 bits per pixel in both
linear and banked modes, and should be able to use all the resolutions
provided by your underlying VESA driver. It provides accelerated versions
of the VBE/AF functions:
DrawScan()
DrawPattScan()
DrawColorPattScan()
DrawRect()
DrawPattRect()
DrawColorPattRect()
DrawLine()
DrawTrap()
PutMonoImage()
BitBlt()
BitBltSys()
SrcTransBlt() - Mystique only
SrcTransBltSys() - Mystique only
This driver supports the FreeBE/AF extension mechanism for enabling true
protected mode access to video memory. Uncomment the definition of
NO_HWPTR at the top of driver.c if you want to return to the standard
nearptr memory access.
Masked blitting from system memory is only enabled in 256 color modes,
because in truecolor resolutions it is actually faster to do the masking
checks in software (the increased pixel size means that too much time is
wasted copying zeros to the card, so it is more efficient for the cpu to
test and discard these).
Hardware cursors are supported, but only on the Mystique. The Millenium
does them quite differently, and I have no way to test any code for it.
This code is not portable to any platforms other than DOS+DPMI, because
it uses VESA calls to set the initial video mode.
By Shawn Hargreaves
shawn@talula.demon.co.uk

1607
nvidia/driver.c Normal file

File diff suppressed because it is too large Load Diff

45
nvidia/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF NVidia driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

371
nvidia/font.h Normal file
View File

@ -0,0 +1,371 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/* Well, I guess the fonts are Copyrighted by Trident but if you use this
driver then you have a Trident card so I can't see any problem.
But don't use it for other driver without having clear if you can do it.
*/
/* note from Shawn: this font is identical to the one in my NVidia BIOS,
* so I guess the copyright isn't a problem. I'm just using your data to
* save me the bother of having to grab my own. */
unsigned char VGA8x16Font[256*16]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xE7,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x99,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x1E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x3F,0x33,0x3F,0x30,0x30,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,
0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,
0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xFF,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,
0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0xFF,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x0E,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0xE6,0x66,0x6C,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0xC3,0xE7,0xFF,0xDB,0xDB,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00,
0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xDB,0xDB,0xFF,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x6C,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0xFF,0xC3,0x83,0x06,0x0C,0x18,0x30,0x61,0xC3,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x3E,0x00,0x00,0x00,0x00,
0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,
0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0xDC,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00,
0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,
0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xE6,0xFF,0xDB,0xDB,0xDB,0xDB,0xDB,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00,
0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x62,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xDB,0xDB,0xFF,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00,
0x00,0x00,0xCC,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xCC,0xCC,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00,
0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0xC6,0xC6,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x1B,0x7E,0xD8,0xDC,0x77,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,
0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
0x00,0xC6,0xC6,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
0x00,0xC6,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00,
0x00,0x00,0xC3,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0xFC,0x66,0x66,0x7C,0x62,0x66,0x6F,0x66,0x66,0x66,0xF3,0x00,0x00,0x00,0x00,
0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xCE,0x93,0x06,0x0C,0x1F,0x00,0x00,
0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x0F,0x00,0x00,
0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x33,0x66,0xCC,0x66,0x33,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xCC,0x66,0x33,0x66,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,
0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDC,0xC6,0xC3,0xC3,0xC3,0xCE,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00,
0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x06,0x7E,0xCF,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0xFF,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0xFF,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00,
0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x70,0x98,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};
unsigned char DefaultTXTPalette[768]={
0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x2A,0x00,0x00,0x2A,0x2A,0x2A,0x00,0x00,0x2A,
0x00,0x2A,0x2A,0x2A,0x00,0x2A,0x2A,0x2A,0x00,0x00,0x15,0x00,0x00,0x3F,0x00,0x2A,
0x15,0x00,0x2A,0x3F,0x2A,0x00,0x15,0x2A,0x00,0x3F,0x2A,0x2A,0x15,0x2A,0x2A,0x3F,
0x00,0x15,0x00,0x00,0x15,0x2A,0x00,0x3F,0x00,0x00,0x3F,0x2A,0x2A,0x15,0x00,0x2A,
0x15,0x2A,0x2A,0x3F,0x00,0x2A,0x3F,0x2A,0x00,0x15,0x15,0x00,0x15,0x3F,0x00,0x3F,
0x15,0x00,0x3F,0x3F,0x2A,0x15,0x15,0x2A,0x15,0x3F,0x2A,0x3F,0x15,0x2A,0x3F,0x3F,
0x15,0x00,0x00,0x15,0x00,0x2A,0x15,0x2A,0x00,0x15,0x2A,0x2A,0x3F,0x00,0x00,0x3F,
0x00,0x2A,0x3F,0x2A,0x00,0x3F,0x2A,0x2A,0x15,0x00,0x15,0x15,0x00,0x3F,0x15,0x2A,
0x15,0x15,0x2A,0x3F,0x3F,0x00,0x15,0x3F,0x00,0x3F,0x3F,0x2A,0x15,0x3F,0x2A,0x3F,
0x15,0x15,0x00,0x15,0x15,0x2A,0x15,0x3F,0x00,0x15,0x3F,0x2A,0x3F,0x15,0x00,0x3F,
0x15,0x2A,0x3F,0x3F,0x00,0x3F,0x3F,0x2A,0x15,0x15,0x15,0x15,0x15,0x3F,0x15,0x3F,
0x15,0x15,0x3F,0x3F,0x3F,0x15,0x15,0x3F,0x15,0x3F,0x3F,0x3F,0x15,0x3F,0x3F,0x3F,
0x3F,0x1F,0x1F,0x3F,0x27,0x1F,0x3F,0x2F,0x1F,0x3F,0x37,0x1F,0x3F,0x3F,0x1F,0x37,
0x3F,0x1F,0x2F,0x3F,0x1F,0x27,0x3F,0x1F,0x1F,0x3F,0x1F,0x1F,0x3F,0x27,0x1F,0x3F,
0x2F,0x1F,0x3F,0x37,0x1F,0x3F,0x3F,0x1F,0x37,0x3F,0x1F,0x2F,0x3F,0x1F,0x27,0x3F,
0x2D,0x2D,0x3F,0x31,0x2D,0x3F,0x36,0x2D,0x3F,0x3A,0x2D,0x3F,0x3F,0x2D,0x3F,0x3F,
0x2D,0x3A,0x3F,0x2D,0x36,0x3F,0x2D,0x31,0x3F,0x2D,0x2D,0x3F,0x31,0x2D,0x3F,0x36,
0x2D,0x3F,0x3A,0x2D,0x3F,0x3F,0x2D,0x3A,0x3F,0x2D,0x36,0x3F,0x2D,0x31,0x3F,0x2D,
0x2D,0x3F,0x2D,0x2D,0x3F,0x31,0x2D,0x3F,0x36,0x2D,0x3F,0x3A,0x2D,0x3F,0x3F,0x2D,
0x3A,0x3F,0x2D,0x36,0x3F,0x2D,0x31,0x3F,0x00,0x00,0x1C,0x07,0x00,0x1C,0x0E,0x00,
0x1C,0x15,0x00,0x1C,0x1C,0x00,0x1C,0x1C,0x00,0x15,0x1C,0x00,0x0E,0x1C,0x00,0x07,
0x1C,0x00,0x00,0x1C,0x07,0x00,0x1C,0x0E,0x00,0x1C,0x15,0x00,0x1C,0x1C,0x00,0x15,
0x1C,0x00,0x0E,0x1C,0x00,0x07,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x07,0x00,0x1C,
0x0E,0x00,0x1C,0x15,0x00,0x1C,0x1C,0x00,0x15,0x1C,0x00,0x0E,0x1C,0x00,0x07,0x1C,
0x0E,0x0E,0x1C,0x11,0x0E,0x1C,0x15,0x0E,0x1C,0x18,0x0E,0x1C,0x1C,0x0E,0x1C,0x1C,
0x0E,0x18,0x1C,0x0E,0x15,0x1C,0x0E,0x11,0x1C,0x0E,0x0E,0x1C,0x11,0x0E,0x1C,0x15,
0x0E,0x1C,0x18,0x0E,0x1C,0x1C,0x0E,0x18,0x1C,0x0E,0x15,0x1C,0x0E,0x11,0x1C,0x0E,
0x0E,0x1C,0x0E,0x0E,0x1C,0x11,0x0E,0x1C,0x15,0x0E,0x1C,0x18,0x0E,0x1C,0x1C,0x0E,
0x18,0x1C,0x0E,0x15,0x1C,0x0E,0x11,0x1C,0x14,0x14,0x1C,0x16,0x14,0x1C,0x18,0x14,
0x1C,0x1A,0x14,0x1C,0x1C,0x14,0x1C,0x1C,0x14,0x1A,0x1C,0x14,0x18,0x1C,0x14,0x16,
0x1C,0x14,0x14,0x1C,0x16,0x14,0x1C,0x18,0x14,0x1C,0x1A,0x14,0x1C,0x1C,0x14,0x1A,
0x1C,0x14,0x18,0x1C,0x14,0x16,0x1C,0x14,0x14,0x1C,0x14,0x14,0x1C,0x16,0x14,0x1C,
0x18,0x14,0x1C,0x1A,0x14,0x1C,0x1C,0x14,0x1A,0x1C,0x14,0x18,0x1C,0x14,0x16,0x1C,
0x00,0x00,0x10,0x04,0x00,0x10,0x08,0x00,0x10,0x0C,0x00,0x10,0x10,0x00,0x10,0x10,
0x00,0x0C,0x10,0x00,0x08,0x10,0x00,0x04,0x10,0x00,0x00,0x10,0x04,0x00,0x10,0x08,
0x00,0x10,0x0C,0x00,0x10,0x10,0x00,0x0C,0x10,0x00,0x08,0x10,0x00,0x04,0x10,0x00,
0x00,0x10,0x00,0x00,0x10,0x04,0x00,0x10,0x08,0x00,0x10,0x0C,0x00,0x10,0x10,0x00,
0x0C,0x10,0x00,0x08,0x10,0x00,0x04,0x10,0x08,0x08,0x10,0x0A,0x08,0x10,0x0C,0x08,
0x10,0x0E,0x08,0x10,0x10,0x08,0x10,0x10,0x08,0x0E,0x10,0x08,0x0C,0x10,0x08,0x0A,
0x10,0x08,0x08,0x10,0x0A,0x08,0x10,0x0C,0x08,0x10,0x0E,0x08,0x10,0x10,0x08,0x0E,
0x10,0x08,0x0C,0x10,0x08,0x0A,0x10,0x08,0x08,0x10,0x08,0x08,0x10,0x0A,0x08,0x10,
0x0C,0x08,0x10,0x0E,0x08,0x10,0x10,0x08,0x0E,0x10,0x08,0x0C,0x10,0x08,0x0A,0x10,
0x0B,0x0B,0x10,0x0C,0x0B,0x10,0x0D,0x0B,0x10,0x0F,0x0B,0x10,0x10,0x0B,0x10,0x10,
0x0B,0x0F,0x10,0x0B,0x0D,0x10,0x0B,0x0C,0x10,0x0B,0x0B,0x10,0x0C,0x0B,0x10,0x0D,
0x0B,0x10,0x0F,0x0B,0x10,0x10,0x0B,0x0F,0x10,0x0B,0x0D,0x10,0x0B,0x0C,0x10,0x0B,
0x0B,0x10,0x0B,0x0B,0x10,0x0C,0x0B,0x10,0x0D,0x0B,0x10,0x0F,0x0B,0x10,0x10,0x0B,
0x0F,0x10,0x0B,0x0D,0x10,0x0B,0x0C,0x10,0x03,0x00,0x0F,0x02,0x00,0x0C,0x02,0x00,
0x09,0x01,0x00,0x07,0x01,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x00,0x3F,0x3F,0x3F};
unsigned char DefaultVGAPalette[768]={
0x00,0x00,0x00,0x00,0x00,0x2A,0x00,0x2A,0x00,0x00,0x2A,0x2A,0x2A,0x00,0x00,0x2A,
0x00,0x2A,0x2A,0x15,0x00,0x2A,0x2A,0x2A,0x15,0x15,0x15,0x15,0x15,0x3F,0x15,0x3F,
0x15,0x15,0x3F,0x3F,0x3F,0x15,0x15,0x3F,0x15,0x3F,0x3F,0x3F,0x15,0x3F,0x3F,0x3F,
0x00,0x00,0x00,0x05,0x05,0x05,0x08,0x08,0x08,0x0B,0x0B,0x0B,0x0E,0x0E,0x0E,0x11,
0x11,0x11,0x14,0x14,0x14,0x18,0x18,0x18,0x1C,0x1C,0x1C,0x20,0x20,0x20,0x24,0x24,
0x24,0x28,0x28,0x28,0x2D,0x2D,0x2D,0x32,0x32,0x32,0x38,0x38,0x38,0x3F,0x3F,0x3F,
0x00,0x00,0x3F,0x10,0x00,0x3F,0x1F,0x00,0x3F,0x2F,0x00,0x3F,0x3F,0x00,0x3F,0x3F,
0x00,0x2F,0x3F,0x00,0x1F,0x3F,0x00,0x10,0x3F,0x00,0x00,0x3F,0x10,0x00,0x3F,0x1F,
0x00,0x3F,0x2F,0x00,0x3F,0x3F,0x00,0x2F,0x3F,0x00,0x1F,0x3F,0x00,0x10,0x3F,0x00,
0x00,0x3F,0x00,0x00,0x3F,0x10,0x00,0x3F,0x1F,0x00,0x3F,0x2F,0x00,0x3F,0x3F,0x00,
0x2F,0x3F,0x00,0x1F,0x3F,0x00,0x10,0x3F,0x1F,0x1F,0x3F,0x27,0x1F,0x3F,0x2F,0x1F,
0x3F,0x37,0x1F,0x3F,0x3F,0x1F,0x3F,0x3F,0x1F,0x37,0x3F,0x1F,0x2F,0x3F,0x1F,0x27,
0x3F,0x1F,0x1F,0x3F,0x27,0x1F,0x3F,0x2F,0x1F,0x3F,0x37,0x1F,0x3F,0x3F,0x1F,0x37,
0x3F,0x1F,0x2F,0x3F,0x1F,0x27,0x3F,0x1F,0x1F,0x3F,0x1F,0x1F,0x3F,0x27,0x1F,0x3F,
0x2F,0x1F,0x3F,0x37,0x1F,0x3F,0x3F,0x1F,0x37,0x3F,0x1F,0x2F,0x3F,0x1F,0x27,0x3F,
0x2D,0x2D,0x3F,0x31,0x2D,0x3F,0x36,0x2D,0x3F,0x3A,0x2D,0x3F,0x3F,0x2D,0x3F,0x3F,
0x2D,0x3A,0x3F,0x2D,0x36,0x3F,0x2D,0x31,0x3F,0x2D,0x2D,0x3F,0x31,0x2D,0x3F,0x36,
0x2D,0x3F,0x3A,0x2D,0x3F,0x3F,0x2D,0x3A,0x3F,0x2D,0x36,0x3F,0x2D,0x31,0x3F,0x2D,
0x2D,0x3F,0x2D,0x2D,0x3F,0x31,0x2D,0x3F,0x36,0x2D,0x3F,0x3A,0x2D,0x3F,0x3F,0x2D,
0x3A,0x3F,0x2D,0x36,0x3F,0x2D,0x31,0x3F,0x00,0x00,0x1C,0x07,0x00,0x1C,0x0E,0x00,
0x1C,0x15,0x00,0x1C,0x1C,0x00,0x1C,0x1C,0x00,0x15,0x1C,0x00,0x0E,0x1C,0x00,0x07,
0x1C,0x00,0x00,0x1C,0x07,0x00,0x1C,0x0E,0x00,0x1C,0x15,0x00,0x1C,0x1C,0x00,0x15,
0x1C,0x00,0x0E,0x1C,0x00,0x07,0x1C,0x00,0x00,0x1C,0x00,0x00,0x1C,0x07,0x00,0x1C,
0x0E,0x00,0x1C,0x15,0x00,0x1C,0x1C,0x00,0x15,0x1C,0x00,0x0E,0x1C,0x00,0x07,0x1C,
0x0E,0x0E,0x1C,0x11,0x0E,0x1C,0x15,0x0E,0x1C,0x18,0x0E,0x1C,0x1C,0x0E,0x1C,0x1C,
0x0E,0x18,0x1C,0x0E,0x15,0x1C,0x0E,0x11,0x1C,0x0E,0x0E,0x1C,0x11,0x0E,0x1C,0x15,
0x0E,0x1C,0x18,0x0E,0x1C,0x1C,0x0E,0x18,0x1C,0x0E,0x15,0x1C,0x0E,0x11,0x1C,0x0E,
0x0E,0x1C,0x0E,0x0E,0x1C,0x11,0x0E,0x1C,0x15,0x0E,0x1C,0x18,0x0E,0x1C,0x1C,0x0E,
0x18,0x1C,0x0E,0x15,0x1C,0x0E,0x11,0x1C,0x14,0x14,0x1C,0x16,0x14,0x1C,0x18,0x14,
0x1C,0x1A,0x14,0x1C,0x1C,0x14,0x1C,0x1C,0x14,0x1A,0x1C,0x14,0x18,0x1C,0x14,0x16,
0x1C,0x14,0x14,0x1C,0x16,0x14,0x1C,0x18,0x14,0x1C,0x1A,0x14,0x1C,0x1C,0x14,0x1A,
0x1C,0x14,0x18,0x1C,0x14,0x16,0x1C,0x14,0x14,0x1C,0x14,0x14,0x1C,0x16,0x14,0x1C,
0x18,0x14,0x1C,0x1A,0x14,0x1C,0x1C,0x14,0x1A,0x1C,0x14,0x18,0x1C,0x14,0x16,0x1C,
0x00,0x00,0x10,0x04,0x00,0x10,0x08,0x00,0x10,0x0C,0x00,0x10,0x10,0x00,0x10,0x10,
0x00,0x0C,0x10,0x00,0x08,0x10,0x00,0x04,0x10,0x00,0x00,0x10,0x04,0x00,0x10,0x08,
0x00,0x10,0x0C,0x00,0x10,0x10,0x00,0x0C,0x10,0x00,0x08,0x10,0x00,0x04,0x10,0x00,
0x00,0x10,0x00,0x00,0x10,0x04,0x00,0x10,0x08,0x00,0x10,0x0C,0x00,0x10,0x10,0x00,
0x0C,0x10,0x00,0x08,0x10,0x00,0x04,0x10,0x08,0x08,0x10,0x0A,0x08,0x10,0x0C,0x08,
0x10,0x0E,0x08,0x10,0x10,0x08,0x10,0x10,0x08,0x0E,0x10,0x08,0x0C,0x10,0x08,0x0A,
0x10,0x08,0x08,0x10,0x0A,0x08,0x10,0x0C,0x08,0x10,0x0E,0x08,0x10,0x10,0x08,0x0E,
0x10,0x08,0x0C,0x10,0x08,0x0A,0x10,0x08,0x08,0x10,0x08,0x08,0x10,0x0A,0x08,0x10,
0x0C,0x08,0x10,0x0E,0x08,0x10,0x10,0x08,0x0E,0x10,0x08,0x0C,0x10,0x08,0x0A,0x10,
0x0B,0x0B,0x10,0x0C,0x0B,0x10,0x0D,0x0B,0x10,0x0F,0x0B,0x10,0x10,0x0B,0x10,0x10,
0x0B,0x0F,0x10,0x0B,0x0D,0x10,0x0B,0x0C,0x10,0x0B,0x0B,0x10,0x0C,0x0B,0x10,0x0D,
0x0B,0x10,0x0F,0x0B,0x10,0x10,0x0B,0x0F,0x10,0x0B,0x0D,0x10,0x0B,0x0C,0x10,0x0B,
0x0B,0x10,0x0B,0x0B,0x10,0x0C,0x0B,0x10,0x0D,0x0B,0x10,0x0F,0x0B,0x10,0x10,0x0B,
0x0F,0x10,0x0B,0x0D,0x10,0x0B,0x0C,0x10,0x03,0x00,0x0F,0x02,0x00,0x0C,0x02,0x00,
0x09,0x01,0x00,0x07,0x01,0x00,0x04,0x00,0x00,0x02,0x00,0x00,0x00,0x3F,0x3F,0x3F};

90
nvidia/notes.txt Normal file
View File

@ -0,0 +1,90 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
NVidia driver implementation notes.
This driver should in theory support both the NVidia Riva 128 and Riva
TNT cards, but it has only been tested on the TNT. I'd be very interested
to hear whether it works on the 128 or not, although I'm afraid there
isn't much I can do to fix any problems on hardware that I don't own.
This driver doesn't work properly under Windows. It will run ok, but
after using it, you can't switch back to your Windows desktop. I have no
idea why this is.
It supports color depths of 8, 16, and 32 bits per pixel in both linear
and banked modes, and resolutions of 320x200, 320x240, 320x400, 640x400,
640x480, 800x600, 1024x768, and 1280x1024 (this last not in 32 bit mode).
Other modes can easily be added if you know the register values for them.
It provides accelerated versions of the VBE/AF functions:
DrawScan()
DrawRect()
DrawTrap()
PutMonoImage()
BitBlt()
SetCursor()
SetCursorPos()
SetCursorColor()
ShowCursor()
Patterned drawing is not accelerated. I have some routines that sort-of
worked for this, but couldn't get them to do the right thing in all the
possible drawing modes. Since I got that code from an alpha version of an
XFree86 driver which itself doesn't do patterned modes properly, this is
not exactly surprising. I'll add that acceleration as soon as I get some
decent info about how it works.
This driver is unable to use more than 16 meg of video memory, because
I'm unable to detect the amount of vram until after I map the
framebuffer, at which point it is too late to request a larger memory
block.
The hardware scrolling and bank switching code may not be entirely
correct, because I didn't have any docs for how the bank switch system
works, and the scrolling routine supplied in XFree86 is broken. The code
in this driver works correctly on my TNT, but your mileage may vary.
This driver does not implement the FreeBE/AF farptr extension mechanism,
which means that it only works with nearptrs enabled. This could be
altered if enough people feel strongly about it, but would be a
considerable pain because I'd have to rewrite most of the NVidia helper
routines as well as my own driver code.
This code is heavily based on the NVidia driver from XFree86 version
3.3.3.1. In particular, the source file riva_hw.c was copied directly
from XFree86. This imposes two restrictions on me. First, I have to say
that NVidia is an exceptionally cool company, and they deserve much
congratulation for releasing this nice bit of reusable driver source.
Also, to comply with their BSD-style licensing terms, I have to reproduce
this lovely little message:
Copyright 1993-1998 NVIDIA, Corporation. All rights reserved.
NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY OF
THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT
EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPORATION DISCLAIMS
ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A
PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA, CORPORATION BE LIABLE
FOR ANY SPECIAL, INDIRECT, INCIDENTAL, 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
SOURCE CODE.
Also thanks to Salvador Eduardo Tropea for the VGA mode setting routines
in his TGUI driver, which I shamelessly copied.
By Shawn Hargreaves
shawn@talula.demon.co.uk

1395
nvidia/riva_hw.c Normal file

File diff suppressed because it is too large Load Diff

336
nvidia/riva_hw.h Normal file
View File

@ -0,0 +1,336 @@
/***************************************************************************\
|* *|
|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
|* *|
|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
|* international laws. Users and possessors of this source code are *|
|* hereby granted a nonexclusive, royalty-free copyright license to *|
|* use this code in individual and commercial software. *|
|* *|
|* Any use of this source code must include, in the user documenta- *|
|* tion and internal comments to the code, notices to the end user *|
|* as follows: *|
|* *|
|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
|* *|
|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
|* SULTING 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 SOURCE CODE. *|
|* *|
|* U.S. Government End Users. This source code is a "commercial *|
|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
|* consisting of "commercial computer software" and "commercial *|
|* computer software documentation," as such terms are used in *|
|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
|* all U.S. Government End Users acquire the source code with only *|
|* those rights set forth herein. *|
|* *|
\***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/riva_hw.h,v 1.1.2.2 1998/12/22 16:33:19 hohndel Exp $ */
#ifndef __RIVA_HW_H__
#define __RIVA_HW_H__
#define RIVA_SW_VERSION 0x00010000
/***************************************************************************\
* *
* FIFO registers. *
* *
\***************************************************************************/
/*
* Raster OPeration. Windows style ROP3.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop;
unsigned reserved01[0x0BB];
unsigned Rop3;
} RivaRop;
/*
* 8X8 Monochrome pattern.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop;
unsigned reserved01[0x0BD];
unsigned Shape;
unsigned reserved03[0x001];
unsigned Color0;
unsigned Color1;
unsigned Monochrome[2];
} RivaPattern;
/*
* Scissor clip rectangle.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop;
unsigned reserved01[0x0BB];
unsigned TopLeft;
unsigned WidthHeight;
} RivaClip;
/*
* 2D filled rectangle.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop[1];
unsigned reserved01[0x0BC];
unsigned Color;
unsigned reserved03[0x03E];
unsigned TopLeft;
unsigned WidthHeight;
} RivaRectangle;
/*
* 2D screen-screen BLT.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop;
unsigned reserved01[0x0BB];
unsigned TopLeftSrc;
unsigned TopLeftDst;
unsigned WidthHeight;
} RivaScreenBlt;
/*
* 2D pixel BLT.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop[1];
unsigned reserved01[0x0BC];
unsigned TopLeft;
unsigned WidthHeight;
unsigned WidthHeightIn;
unsigned reserved02[0x03C];
unsigned Pixels;
} RivaPixmap;
/*
* Filled rectangle combined with monochrome expand. Useful for glyphs.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop;
unsigned reserved01[0x0BB];
unsigned reserved03[(0x040)-1];
unsigned Color1A;
struct
{
unsigned TopLeft;
unsigned WidthHeight;
} UnclippedRectangle[64];
unsigned reserved04[(0x080)-3];
struct
{
unsigned TopLeft;
unsigned BottomRight;
} ClipB;
unsigned Color1B;
struct
{
unsigned TopLeft;
unsigned BottomRight;
} ClippedRectangle[64];
unsigned reserved05[(0x080)-5];
struct
{
unsigned TopLeft;
unsigned BottomRight;
} ClipC;
unsigned Color1C;
unsigned WidthHeightC;
unsigned PointC;
unsigned MonochromeData1C;
unsigned reserved06[(0x080)+121];
struct
{
unsigned TopLeft;
unsigned BottomRight;
} ClipD;
unsigned Color1D;
unsigned WidthHeightInD;
unsigned WidthHeightOutD;
unsigned PointD;
unsigned MonochromeData1D;
unsigned reserved07[(0x080)+120];
struct
{
unsigned TopLeft;
unsigned BottomRight;
} ClipE;
unsigned Color0E;
unsigned Color1E;
unsigned WidthHeightInE;
unsigned WidthHeightOutE;
unsigned PointE;
unsigned MonochromeData01E;
} RivaBitmap;
/*
* 3D textured, Z buffered triangle.
*/
typedef volatile struct
{
unsigned reserved00[4];
unsigned short FifoFree;
unsigned short Nop;
unsigned reserved01[0x0BC];
unsigned TextureOffset;
unsigned TextureFormat;
unsigned TextureFilter;
unsigned FogColor;
unsigned Control;
unsigned AlphaTest;
unsigned reserved02[0x339];
unsigned FogAndIndex;
unsigned Color;
float ScreenX;
float ScreenY;
float ScreenZ;
float EyeM;
float TextureS;
float TextureT;
} RivaTexturedTriangle03;
/***************************************************************************\
* *
* Virtualized RIVA H/W interface. *
* *
\***************************************************************************/
struct _riva_hw_inst;
struct _riva_hw_state;
/*
* Virtialized chip interface. Makes RIVA 128 and TNT look alike.
*/
typedef struct _riva_hw_inst
{
/*
* Chip specific settings.
*/
unsigned Architecture;
unsigned Version;
unsigned CrystalFreqKHz;
unsigned RamAmountKBytes;
unsigned MaxVClockFreqKHz;
unsigned RamBandwidthKBytesPerSec;
unsigned EnableIRQ;
unsigned IO;
unsigned LockUnlockIO;
unsigned LockUnlockIndex;
unsigned VBlankBit;
unsigned FifoFreeCount;
/*
* Non-FIFO registers.
*/
volatile unsigned *PCRTC;
volatile unsigned *PRAMDAC;
volatile unsigned *PFB;
volatile unsigned *PFIFO;
volatile unsigned *PGRAPH;
volatile unsigned *PEXTDEV;
volatile unsigned *PTIMER;
volatile unsigned *PMC;
volatile unsigned *PRAMIN;
volatile unsigned *FIFO;
volatile unsigned *CURSOR;
volatile unsigned *CURSORPOS;
volatile unsigned *VBLANKENABLE;
volatile unsigned *VBLANK;
/*
* Common chip functions.
*/
int (*Busy)(struct _riva_hw_inst *);
void (*CalcStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *,int,int,int,int,int,int,int,int,int,int,int,int,int);
void (*LoadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *, int all);
void (*UnloadStateExt)(struct _riva_hw_inst *,struct _riva_hw_state *);
void (*SetStartAddress)(struct _riva_hw_inst *,unsigned);
void (*SetSurfaces2D)(struct _riva_hw_inst *,unsigned,unsigned);
void (*SetSurfaces3D)(struct _riva_hw_inst *,unsigned,unsigned);
int (*ShowHideCursor)(struct _riva_hw_inst *,int);
/*
* Current extended mode settings.
*/
struct _riva_hw_state *CurrentState;
/*
* FIFO registers.
*/
RivaRop *Rop;
RivaPattern *Patt;
RivaClip *Clip;
RivaPixmap *Pixmap;
RivaScreenBlt *Blt;
RivaBitmap *Bitmap;
RivaTexturedTriangle03 *Tri03;
} RIVA_HW_INST;
/*
* Extended mode state information.
*/
typedef struct _riva_hw_state
{
unsigned bpp;
unsigned width;
unsigned height;
unsigned repaint0;
unsigned repaint1;
unsigned screen;
unsigned pixel;
unsigned horiz;
unsigned arbitration0;
unsigned arbitration1;
unsigned vpll;
unsigned pllsel;
unsigned general;
unsigned config;
unsigned cursor0;
unsigned cursor1;
unsigned cursor2;
unsigned offset0;
unsigned offset1;
unsigned offset2;
unsigned offset3;
unsigned pitch0;
unsigned pitch1;
unsigned pitch2;
unsigned pitch3;
} RIVA_HW_STATE;
/*
* External routines.
*/
int RivaGetConfig(RIVA_HW_INST *);
/*
* FIFO Free Count. Should attempt to yield processor if RIVA is busy.
*/
#define RIVA_FIFO_FREE(hwinst,hwptr,cnt) \
{ \
while ((hwinst).FifoFreeCount < (cnt)) \
{ \
(hwinst).FifoFreeCount = (hwinst).hwptr->FifoFree >> 2; \
} \
(hwinst).FifoFreeCount -= (cnt); \
}
#endif /* __RIVA_HW_H__ */

395
nvidia/riva_tbl.h Normal file
View File

@ -0,0 +1,395 @@
/***************************************************************************\
|* *|
|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
|* *|
|* NOTICE TO USER: The source code is copyrighted under U.S. and *|
|* international laws. Users and possessors of this source code are *|
|* hereby granted a nonexclusive, royalty-free copyright license to *|
|* use this code in individual and commercial software. *|
|* *|
|* Any use of this source code must include, in the user documenta- *|
|* tion and internal comments to the code, notices to the end user *|
|* as follows: *|
|* *|
|* Copyright 1993-1998 NVIDIA, Corporation. All rights reserved. *|
|* *|
|* NVIDIA, CORPORATION MAKES NO REPRESENTATION ABOUT THE SUITABILITY *|
|* OF THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" *|
|* WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. NVIDIA, CORPOR- *|
|* ATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOURCE CODE, *|
|* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGE- *|
|* MENT, AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL *|
|* NVIDIA, CORPORATION BE LIABLE FOR ANY SPECIAL, INDIRECT, INCI- *|
|* DENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RE- *|
|* SULTING 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 SOURCE CODE. *|
|* *|
|* U.S. Government End Users. This source code is a "commercial *|
|* item," as that term is defined at 48 C.F.R. 2.101 (OCT 1995), *|
|* consisting of "commercial computer software" and "commercial *|
|* computer software documentation," as such terms are used in *|
|* 48 C.F.R. 12.212 (SEPT 1995) and is provided to the U.S. Govern- *|
|* ment only as a commercial end item. Consistent with 48 C.F.R. *|
|* 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (JUNE 1995), *|
|* all U.S. Government End Users acquire the source code with only *|
|* those rights set forth herein. *|
|* *|
\***************************************************************************/
/* $XFree86: xc/programs/Xserver/hw/xfree86/vga256/drivers/nv/riva_tbl.h,v 1.1.2.2 1998/12/22 16:33:20 hohndel Exp $ */
/*
* RIVA Fixed Functionality Init Tables.
*/
static unsigned RivaTablePMC[][2] =
{
{0x00000050, 0x00000000},
{0x00000080, 0xFFFF00FF},
{0x00000080, 0xFFFFFFFF}
};
static unsigned RivaTablePTIMER[][2] =
{
{0x00000080, 0x00000008},
{0x00000084, 0x00000003},
{0x00000050, 0x00000000},
{0x00000040, 0xFFFFFFFF}
};
static unsigned RivaTableFIFO[][2] =
{
{0x00000000, 0x80000000},
{0x00000800, 0x80000001},
{0x00001000, 0x80000002},
{0x00001800, 0x80000010},
{0x00002000, 0x80000011},
{0x00002800, 0x80000012},
{0x00003800, 0x80000013}
};
static unsigned nv3TablePFIFO[][2] =
{
{0x00000140, 0x00000000},
{0x00000480, 0x00000000},
{0x00000490, 0x00000000},
{0x00000494, 0x00000000},
{0x00000481, 0x00000000},
{0x00000084, 0x00000000},
{0x00000086, 0x00002000},
{0x00000085, 0x00002200},
{0x00000484, 0x00000000},
{0x0000049C, 0x00000000},
{0x00000104, 0x00000000},
{0x00000108, 0x00000000},
{0x00000100, 0x00000000},
{0x000004A0, 0x00000000},
{0x000004A4, 0x00000000},
{0x000004A8, 0x00000000},
{0x000004AC, 0x00000000},
{0x000004B0, 0x00000000},
{0x000004B4, 0x00000000},
{0x000004B8, 0x00000000},
{0x000004BC, 0x00000000},
{0x00000050, 0x00000000},
{0x00000040, 0xFFFFFFFF},
{0x00000480, 0x00000001},
{0x00000490, 0x00000001},
{0x00000140, 0x00000001}
};
static unsigned nv3TablePGRAPH[][2] =
{
{0x00000020, 0x1230001F},
{0x00000021, 0x10113000},
{0x00000022, 0x1131F101},
{0x00000023, 0x0100F531},
{0x00000060, 0x00000000},
{0x00000065, 0x00000000},
{0x00000068, 0x00000000},
{0x00000069, 0x00000000},
{0x0000006A, 0x00000000},
{0x0000006B, 0x00000000},
{0x0000006C, 0x00000000},
{0x0000006D, 0x00000000},
{0x0000006E, 0x00000000},
{0x0000006F, 0x00000000},
{0x000001A8, 0x00000000},
{0x00000440, 0xFFFFFFFF},
{0x00000480, 0x00000001},
{0x000001A0, 0x00000000},
{0x000001A2, 0x00000000},
{0x0000018A, 0xFFFFFFFF},
{0x00000190, 0x00000000},
{0x00000142, 0x00000000},
{0x00000154, 0x00000000},
{0x00000155, 0xFFFFFFFF},
{0x00000156, 0x00000000},
{0x00000157, 0xFFFFFFFF},
{0x00000064, 0x10010002},
{0x00000050, 0x00000000},
{0x00000051, 0x00000000},
{0x00000040, 0xFFFFFFFF},
{0x00000041, 0xFFFFFFFF},
{0x00000440, 0xFFFFFFFF},
{0x000001A9, 0x00000001}
};
static unsigned nv3TablePGRAPH_8BPP[][2] =
{
{0x000001AA, 0x00001111}
};
static unsigned nv3TablePGRAPH_15BPP[][2] =
{
{0x000001AA, 0x00002222}
};
static unsigned nv3TablePGRAPH_32BPP[][2] =
{
{0x000001AA, 0x00003333}
};
static unsigned nv3TablePRAMIN[][2] =
{
{0x00000500, 0x00010000},
{0x00000501, 0x007FFFFF},
{0x00000200, 0x80000000},
{0x00000201, 0x00C20341},
{0x00000204, 0x80000001},
{0x00000205, 0x00C50342},
{0x00000208, 0x80000002},
{0x00000209, 0x00C60343},
{0x00000240, 0x80000010},
{0x00000241, 0x00D10344},
{0x00000244, 0x80000011},
{0x00000245, 0x00D00345},
{0x00000248, 0x80000012},
{0x00000249, 0x00CC0346},
{0x0000024C, 0x80000013},
{0x0000024D, 0x00D70347},
{0x00000D05, 0x00000000},
{0x00000D06, 0x00000000},
{0x00000D07, 0x00000000},
{0x00000D09, 0x00000000},
{0x00000D0A, 0x00000000},
{0x00000D0B, 0x00000000},
{0x00000D0D, 0x00000000},
{0x00000D0E, 0x00000000},
{0x00000D0F, 0x00000000},
{0x00000D11, 0x00000000},
{0x00000D12, 0x00000000},
{0x00000D13, 0x00000000},
{0x00000D15, 0x00000000},
{0x00000D16, 0x00000000},
{0x00000D17, 0x00000000},
{0x00000D19, 0x00000000},
{0x00000D1A, 0x00000000},
{0x00000D1B, 0x00000000},
{0x00000D1D, 0x00000140},
{0x00000D1E, 0x00000000},
{0x00000D1F, 0x00000000}
};
static unsigned nv3TablePRAMIN_8BPP[][2] =
{
{0x00000D04, 0x10110203},
{0x00000D08, 0x10110203},
{0x00000D0C, 0x10110203},
{0x00000D10, 0x10118203},
{0x00000D14, 0x10110203},
{0x00000D18, 0x10110203},
{0x00000D1C, 0x10419208}
};
static unsigned nv3TablePRAMIN_15BPP[][2] =
{
{0x00000D04, 0x10110200},
{0x00000D08, 0x10110200},
{0x00000D0C, 0x10110200},
{0x00000D10, 0x10118200},
{0x00000D14, 0x10110200},
{0x00000D18, 0x10110200},
{0x00000D1C, 0x10419208}
};
static unsigned nv3TablePRAMIN_32BPP[][2] =
{
{0x00000D04, 0x10110201},
{0x00000D08, 0x10110201},
{0x00000D0C, 0x10110201},
{0x00000D10, 0x10118201},
{0x00000D14, 0x10110201},
{0x00000D18, 0x10110201},
{0x00000D1C, 0x10419208}
};
static unsigned nv4TablePFIFO[][2] =
{
{0x00000140, 0x00000000},
{0x00000480, 0x00000000},
{0x00000494, 0x00000000},
{0x00000400, 0x00000000},
{0x00000414, 0x00000000},
{0x00000084, 0x03000100},
{0x00000085, 0x00000110},
{0x00000086, 0x00000112},
{0x00000143, 0x0000FFFF},
{0x00000496, 0x0000FFFF},
{0x00000050, 0x00000000},
{0x00000040, 0xFFFFFFFF},
{0x00000415, 0x00000001},
{0x00000480, 0x00000001},
{0x00000494, 0x00000001},
{0x00000495, 0x00000001},
{0x00000140, 0x00000001}
};
static unsigned nv4TablePGRAPH[][2] =
{
{0x00000020, 0x1231C001},
{0x00000021, 0x72111101},
{0x00000022, 0x11D5F071},
{0x00000023, 0x10D4FF31},
{0x00000060, 0x00000000},
{0x00000068, 0x00000000},
{0x00000070, 0x00000000},
{0x00000078, 0x00000000},
{0x00000061, 0x00000000},
{0x00000069, 0x00000000},
{0x00000071, 0x00000000},
{0x00000079, 0x00000000},
{0x00000062, 0x00000000},
{0x0000006A, 0x00000000},
{0x00000072, 0x00000000},
{0x0000007A, 0x00000000},
{0x00000063, 0x00000000},
{0x0000006B, 0x00000000},
{0x00000073, 0x00000000},
{0x0000007B, 0x00000000},
{0x00000064, 0x00000000},
{0x0000006C, 0x00000000},
{0x00000074, 0x00000000},
{0x0000007C, 0x00000000},
{0x00000065, 0x00000000},
{0x0000006D, 0x00000000},
{0x00000075, 0x00000000},
{0x0000007D, 0x00000000},
{0x00000066, 0x00000000},
{0x0000006E, 0x00000000},
{0x00000076, 0x00000000},
{0x0000007E, 0x00000000},
{0x00000067, 0x00000000},
{0x0000006F, 0x00000000},
{0x00000077, 0x00000000},
{0x0000007F, 0x00000000},
{0x00000058, 0x00000000},
{0x00000059, 0x00000000},
{0x0000005A, 0x00000000},
{0x0000005B, 0x00000000},
{0x00000196, 0x00000000},
{0x000001A1, 0x00FFFFFF},
{0x00000197, 0x00000000},
{0x000001A2, 0x00FFFFFF},
{0x00000198, 0x00000000},
{0x000001A3, 0x00FFFFFF},
{0x00000199, 0x00000000},
{0x000001A4, 0x00FFFFFF},
{0x00000050, 0x00000000},
{0x00000040, 0xFFFFFFFF},
{0x0000005C, 0x10010100},
{0x000001C8, 0x00000001}
};
static unsigned nv4TablePGRAPH_8BPP[][2] =
{
{0x000001C4, 0xFFFFFFFF},
{0x000001C9, 0x00111111},
{0x00000186, 0x00001010},
{0x0000020C, 0x01010101}
};
static unsigned nv4TablePGRAPH_15BPP[][2] =
{
{0x000001C4, 0xFFFFFFFF},
{0x000001C9, 0x00226222},
{0x00000186, 0x00002071},
{0x0000020C, 0x09090909}
};
static unsigned nv4TablePGRAPH_16BPP[][2] =
{
{0x000001C4, 0xFFFFFFFF},
{0x000001C9, 0x00556555},
{0x00000186, 0x000050C2},
{0x0000020C, 0x0C0C0C0C}
};
static unsigned nv4TablePGRAPH_32BPP[][2] =
{
{0x000001C4, 0xFFFFFFFF},
{0x000001C9, 0x0077D777},
{0x00000186, 0x000070E5},
{0x0000020C, 0x07070707}
};
static unsigned nv4TablePRAMIN[][2] =
{
{0x00000000, 0x80000010},
{0x00000001, 0x80011145},
{0x00000002, 0x80000011},
{0x00000003, 0x80011146},
{0x00000004, 0x80000012},
{0x00000005, 0x80011147},
{0x00000006, 0x80000013},
{0x00000007, 0x80011148},
{0x00000020, 0x80000000},
{0x00000021, 0x80011142},
{0x00000022, 0x80000001},
{0x00000023, 0x80011143},
{0x00000024, 0x80000002},
{0x00000025, 0x80011144},
{0x00000500, 0x00003000},
{0x00000501, 0x02FFFFFF},
{0x00000502, 0x00000002},
{0x00000503, 0x00000002},
{0x00000508, 0x01008043},
{0x0000050A, 0x00000000},
{0x0000050B, 0x00000000},
{0x0000050C, 0x01008019},
{0x0000050E, 0x00000000},
{0x0000050F, 0x00000000},
{0x00000510, 0x01008018},
{0x00000512, 0x00000000},
{0x00000513, 0x00000000},
{0x00000514, 0x0100A033},
{0x00000516, 0x00000000},
{0x00000517, 0x00000000},
{0x00000518, 0x0100805F},
{0x0000051A, 0x00000000},
{0x0000051B, 0x00000000},
{0x0000051C, 0x0100804B},
{0x0000051E, 0x00000000},
{0x0000051F, 0x00000000},
{0x00000520, 0x0100A048},
{0x00000521, 0x00000D01},
{0x00000522, 0x11401140},
{0x00000523, 0x00000000}
};
static unsigned nv4TablePRAMIN_8BPP[][2] =
{
{0x00000509, 0x00000301},
{0x0000050D, 0x00000301},
{0x00000511, 0x00000301},
{0x00000515, 0x00000301},
{0x00000519, 0x00000301},
{0x0000051D, 0x00000301}
};
static unsigned nv4TablePRAMIN_15BPP[][2] =
{
{0x00000509, 0x00000901},
{0x0000050D, 0x00000901},
{0x00000511, 0x00000901},
{0x00000515, 0x00000901},
{0x00000519, 0x00000901},
{0x0000051D, 0x00000901}
};
static unsigned nv4TablePRAMIN_16BPP[][2] =
{
{0x00000509, 0x00000C01},
{0x0000050D, 0x00000C01},
{0x00000511, 0x00000C01},
{0x00000515, 0x00000C01},
{0x00000519, 0x00000C01},
{0x0000051D, 0x00000C01}
};
static unsigned nv4TablePRAMIN_32BPP[][2] =
{
{0x00000509, 0x00000E01},
{0x0000050D, 0x00000E01},
{0x00000511, 0x00000E01},
{0x00000515, 0x00000E01},
{0x00000519, 0x00000E01},
{0x0000051D, 0x00000E01}
};

673
paradise/driver.c Normal file
View File

@ -0,0 +1,673 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Paradise driver (based on the Allegro Paradise code).
*
* By Francois Charton and Shawn Hargreaves.
*
* See freebe.txt for copyright information.
*/
// #define NO_HWPTR
#include <pc.h>
#include "vbeaf.h"
/* chipset information */
#define PVGA1 1
#define WD90C 2
int paradise_type = 0;
/* driver function prototypes */
void CirrusSetBank32();
void CirrusSetBank32End();
void CirrusSetBank(AF_DRIVER *af, long bank);
void ParadiseSetBank32();
void ParadiseSetBank32End();
void ParadiseSetBank(AF_DRIVER *af, long bank);
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
/* FreeBE/AF extension allowing farptr access to video memory */
FAF_HWPTR_DATA hwptr;
/* list of available video modes */
typedef struct VIDEO_MODE
{
int w, h;
int bpp;
int num;
} VIDEO_MODE;
VIDEO_MODE mode_list[] =
{
{ 640, 400, 8, 0x5E },
{ 640, 480, 8, 0x5F },
{ 800, 600, 8, 0x5C }
};
#define NUM_MODES (int)(sizeof(mode_list)/sizeof(VIDEO_MODE))
short available_modes[NUM_MODES+1] = { 1, 2, 3, -1 };
/* detect:
* Detects the presence of a Paradise card.
*/
char *detect(unsigned long *vidmem)
{
char *name = NULL;
RM_REGS r;
int old, old2;
old = read_vga_register(0x3CE, 0xF);
write_vga_register(0x3CE, 0xF, old | 0x17); /* lock extended registers */
if (test_vga_register(0x3CE, 0x9, 0x7F)) { /* not a Paradise card! */
write_vga_register(0x3CE, 0xF, old);
return NULL;
}
alter_vga_register(0x3CE, 0xF, 0x17, 5); /* unlock extended regs */
if (!test_vga_register(0x3CE, 0x9, 0x7F)) { /* not a Paradise card! */
write_vga_register(0x3CE, 0xF, old);
return NULL;
}
old2 = read_vga_register(0x3D4, 0x29);
alter_vga_register(0x3D4, 0x29, 0x8F, 0x85);
if (!test_vga_register(0x3D4, 0x2B, 0xFF)) {
paradise_type = PVGA1;
name = "PVGA1";
goto end;
}
write_vga_register(0x3C4, 0x06, 0x48);
if (!test_vga_register(0x3C4, 0x7, 0xF0)) {
paradise_type = PVGA1;
name = "WD90C0x";
goto end;
}
if (!test_vga_register(0x3C4, 0x10, 0xFF)) {
paradise_type = PVGA1;
name = "WD90C2x";
write_vga_register(0x3D4, 0x34, 0xA6);
if (read_vga_register(0x3D4, 0x32) & 0x20)
write_vga_register(0x3D4, 0x34, 0);
goto end;
}
paradise_type = WD90C;
name = "WD90C1x or 24+";
end:
write_vga_register(0x3D4, 0x29, old2);
write_vga_register(0x3CE, 0xF, old);
r.x.ax = 0x007F;
r.h.bh = 0x02;
rm_int(0x10, &r);
*vidmem = r.h.ch * 64;
return name;
}
/* SetupDriver:
* Fills in our driver header block.
*/
int SetupDriver(AF_DRIVER *af)
{
char *name;
int i;
name = detect(&af->TotalMemory);
if (!name)
return 1;
i = 0;
while (af->OemVendorName[i])
i++;
af->OemVendorName[i++] = ',';
af->OemVendorName[i++] = ' ';
while (*name)
af->OemVendorName[i++] = *(name++);
af->OemVendorName[i] = 0;
af->AvailableModes = available_modes;
af->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
af->IOPortsTable = ports_table;
if (paradise_type == PVGA1) {
af->SetBank32 = CirrusSetBank32;
af->SetBank32Len = (long)CirrusSetBank32End - (long)CirrusSetBank32;
af->SetBank = CirrusSetBank;
}
else {
af->SetBank32 = ParadiseSetBank32;
af->SetBank32Len = (long)ParadiseSetBank32End - (long)ParadiseSetBank32;
af->SetBank = ParadiseSetBank;
}
af->SupplementalExt = ExtStub;
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->SetPaletteData = SetPaletteData;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
*/
int InitDriver(AF_DRIVER *af)
{
hwptr_init(hwptr.IOMemMaps[0], af->IOMemMaps[0]);
hwptr_init(hwptr.IOMemMaps[1], af->IOMemMaps[1]);
hwptr_init(hwptr.IOMemMaps[2], af->IOMemMaps[2]);
hwptr_init(hwptr.IOMemMaps[3], af->IOMemMaps[3]);
hwptr_init(hwptr.BankedMem, af->BankedMem);
hwptr_init(hwptr.LinearMem, af->LinearMem);
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
#ifndef NO_HWPTR
case FAFEXT_HWPTR:
/* allow farptr access to video memory */
return &hwptr;
#endif
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
VIDEO_MODE *info;
int i;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
for (i=0; i<(int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
modeInfo->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
modeInfo->MaxBuffers = (af->TotalMemory*1024) /
(info->w*info->h*BYTES_PER_PIXEL(info->bpp));
if (info->w > 1024) {
modeInfo->MaxBytesPerScanLine = 2048*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 2048;
}
else {
modeInfo->MaxBytesPerScanLine = 1024*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 1024;
}
modeInfo->BytesPerScanLine = info->w*BYTES_PER_PIXEL(info->bpp);
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
modeInfo->MaxPixelClock = 135000000;
return 0;
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
long available_vram;
long used_vram;
int width;
VIDEO_MODE *info;
RM_REGS r;
/* reject anything with hardware stereo, linear framebuffer, or noclear */
if (mode & 0xC400)
return -1;
mode &= 0x3FF;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
/* call BIOS to set the mode */
r.x.ax = info->num;
rm_int(0x10, &r);
/* adjust the virtual width for widescreen modes */
if (virtualX > info->w) {
if (virtualX > 1024)
return -1;
*bytesPerLine = ((virtualX*BYTES_PER_PIXEL(info->bpp))+15)&0xFFF0;
width = read_vga_register(0x3D4, 0x13);
write_vga_register(0x3D4, 0x13, (width * (*bytesPerLine)) / (info->w*BYTES_PER_PIXEL(info->bpp)));
}
else
*bytesPerLine = info->w*BYTES_PER_PIXEL(info->bpp);
/* set up some hardware registers */
if (paradise_type != PVGA1) {
write_vga_register(0x3C4, 0x06, 0x48);
alter_vga_register(0x3C4, 0x11, 0x80, 0x80);
alter_vga_register(0x3CE, 0x0B, 0x80, 0x80);
write_vga_register(0x3C4, 0x06, 0x00);
}
/* store info about the current mode */
af_bpp = info->bpp;
af_width = *bytesPerLine;
af_height = MAX(info->h, virtualY);
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
af_bank = -1;
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory*1024 ;
if (used_vram > available_vram)
return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
}
else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
if (waitVRT >= 0) {
long a = (x * BYTES_PER_PIXEL(af_bpp)) + ((y + af_visible_page*af_height) * af_width);
asm volatile ("cli");
if (waitVRT) {
do {
} while (inportb(0x3DA) & 1);
}
/* write high bits to Paradise register 3CE indx 0xD, bits 3-4 */
alter_vga_register(0x3CE, 0x0D, 0x18, a>>15);
/* write to normal VGA address registers */
write_vga_register(0x3D4, 0x0D, (a>>2) & 0xFF);
write_vga_register(0x3D4, 0x0C, (a>>10) & 0xFF);
asm volatile ("sti");
if (waitVRT) {
do {
} while (!(inportb(0x3DA) & 8));
}
}
af_scroll_x = x;
af_scroll_y = y;
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* CirrusSetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _CirrusSetBank32, _CirrusSetBank32End
.align 4
_CirrusSetBank32:
pushl %edx
pushl %eax
pushl %edx
movl $0x3CE, %edx /* 3CE index 0x9 */
movb $0x9, %al
outb %al, %dx
popl %eax /* write bank number */
shll $4, %eax
incl %edx
outb %al, %dx
popl %eax
popl %edx
ret
_CirrusSetBank32End:
");
/* CirrusSetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable CirrusSetBank32() above.
*/
void CirrusSetBank(AF_DRIVER *af, long bank)
{
asm (
" call _CirrusSetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}
/* ParadiseSetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _ParadiseSetBank32, _ParadiseSetBank32End
.align 4
_ParadiseSetBank32:
pushl %eax
pushl %ecx
pushl %edx
movl %edx, %ecx
shll $4, %ecx
movl $0x3CE, %edx /* 3CE index 0x9 */
movb $0x9, %al
outb %al, %dx
movl %ecx, %eax /* set read bank number */
incl %edx
outb %al, %dx
decl %edx /* 3CE index 0xA */
movb $0xA, %al
outb %al, %dx
movl %ecx, %eax /* set write bank number */
incl %edx
outb %al, %dx
popl %edx
popl %ecx
popl %eax
ret
_ParadiseSetBank32End:
");
/* ParadiseSetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable ParadiseSetBank32() above.
*/
void ParadiseSetBank(AF_DRIVER *af, long bank)
{
asm (
" call _ParadiseSetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}

45
paradise/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Paradise driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

29
paradise/notes.txt Normal file
View File

@ -0,0 +1,29 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Paradise driver implementation notes.
This is a software-only driver for Paradise chipsets, based on the native
Paradise driver from old versions of the Allegro library. It only
supports 256 color modes, and has no support for linear framebuffers or
accelerated drawing. As such it is useful primarily because it is faster
than the VESA 1.x bank switching mechanism, and as a workaround for the
many bugs in common VESA driver implementations.
This code is not portable to any platforms other than DOS+DPMI, because
it uses BIOS calls to set the initial video mode.
Any volunteers to add hardware accelerator support? That would be very
welcome if you want to do it :-)
By Francois Charton (deef@pobox.oleane.com)
VBE/AF conversion by Shawn Hargreaves (shawn@talula.demon.co.uk)

781
s3/driver.c Normal file
View File

@ -0,0 +1,781 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* S3 driver (based on the Allegro S3 code).
*
* By Shawn Hargreaves and Michael Bukin.
*
* Hardware acceleration by Michal Stencl.
*
* See freebe.txt for copyright information.
*/
// #define NO_HWPTR
#include <pc.h>
#include "../vbeaf.h"
/* driver function prototypes */
void SetBank32();
void SetBank32End();
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
void SetBank(AF_DRIVER *af, long bank);
void BitBlt(AF_DRIVER *af, long left, long top, long width, long height, long dstLeft, long dstTop, long op);
void BitBltSys(AF_DRIVER *af, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op);
void WaitTillIdle(AF_DRIVER *af);
#define S86c911A 0x82
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
int af_chipid;
/* FreeBE/AF extension allowing farptr access to video memory */
FAF_HWPTR_DATA hwptr;
/* list of available video modes */
typedef struct VIDEO_MODE
{
int w, h;
int bpp;
int num;
int bpl;
int redsize;
int redpos;
int greensize;
int greenpos;
int bluesize;
int bluepos;
int rsvdsize;
int rsvdpos;
} VIDEO_MODE;
VIDEO_MODE mode_list[] =
{
{ 640, 400, 8, 0x100, 640 },
{ 640, 480, 8, 0x101, 640 },
{ 800, 600, 8, 0x103, 800 },
{ 1024, 768, 8, 0x105, 1024 },
{ 1280, 1024, 8, 0x107, 1280 },
{ 640, 480, 15, 0x110, 1280,5,10,5,5,5,0,0,0},
{ 800, 600, 15, 0x113, 1600,5,10,5,5,5,0,0,0},
{ 1024, 768, 15, 0x116, 2048,5,10,5,5,5,0,0,0},
{ 1280, 1024, 15, 0x119, 2560,5,10,5,5,5,0,0,0},
{ 640, 480, 16, 0x111, 1024,5,11,6,5,5,0,0,0},
{ 800, 600, 16, 0x114, 1600,5,11,6,5,5,0,0,0},
{ 1024, 768, 16, 0x117, 2048,5,11,6,5,5,0,0,0},
{ 1280, 1024, 16, 0x11A, 2560,5,11,6,5,5,0,0,0},
{ 640, 480, 32, 0x112, 2048,8,16,8,8,8,0,0,0},
{ 800, 600, 32, 0x115, 3200,8,16,8,8,8,0,0,0},
{ 1024, 768, 32, 0x118, 4096,8,16,8,8,8,0,0,0}
};
#define NUM_MODES (int)(sizeof(mode_list)/sizeof(VIDEO_MODE))
short available_modes[NUM_MODES+1] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
13, 14, 15, 16, -1 };
void mod_vga_register_bits ( int reg, int m, int mask, int nwv )
{
int temp = (read_vga_register(reg,m) & (!mask))+(nwv & mask);
write_vga_register(reg, m, temp);
};
void set_vga_register_bits ( int reg, int m, int b )
{
int x = read_vga_register(reg,m);
write_vga_register(reg, m, x | b);
};
void clear_vga_register_bits ( int reg, int m, int b )
{
int x = read_vga_register(reg,m);
write_vga_register(reg, m, x & (!b));
};
void accelIT ( void )
{
write_vga_register(0x3D4, 0x38, 0x48);
write_vga_register(0x3D4, 0x39, 0xA5);
clear_vga_register_bits(0x3D4, 0x58, 0x14);
mod_vga_register_bits(0x3D4, 0x40, 9, 1);
clear_vga_register_bits(0x3D4, 0x53, 0xF);
write_vga_register(0x3D4, 0x54, 0xA0);
outportw(0xBEE8, 0xE000);
outportw(0xAAE8, 0xFFFF);
outportw(0xAEE8, 0xFFFF);
if ( af_bpp >= 24 ) {
outportw(0xBEE8, 0xE010);
outportw(0xAAE8, 0xFFFF);
outportw(0xAEE8, 0xFFFF);
};
};
void unaccelIT ( void )
{
write_vga_register(0x3D4, 0x38, 0x48); /* unlock cr38 */
write_vga_register(0x3D4, 0x39, 0xA5); /* unlock cr39 */
if ( read_vga_register(0x3D4, 0x40) )
do ; while ( inportw(0x9AE8) & 0x200 ); /* if graph. procesor is busy (9bit)*/
clear_vga_register_bits(0x3D4, 0x40, 1); /* not enhanced reg access */
set_vga_register_bits(0x3D4, 0x40, 8); /* enable fast write buffer (3bit) */
};
int readchipid ( void )
{
return read_vga_register(0x3d4, 0x30);
};
/* detect:
* Detects the presence of a S3 card.
*/
int detect()
{
int old;
int result = FALSE;
old = read_vga_register(0x3D4, 0x38);
write_vga_register(0x3D4, 0x38, 0); /* disable ext. */
if (!test_vga_register(0x3D4, 0x35, 0xF)) { /* test */
write_vga_register(0x3D4, 0x38, 0x48); /* enable ext. */
if (test_vga_register(0x3D4, 0x35, 0xF)) /* test again */
result = TRUE; /* found it */
af_chipid = readchipid();
}
write_vga_register(0x3D4, 0x38, old);
return result;
}
/* SetupDriver:
* Fills in our driver header block.
*/
int SetupDriver(AF_DRIVER *af)
{
int vram_size;
if (!detect())
return 1;
if (get_vesa_info(&vram_size, NULL, NULL) != 0)
return -1;
af->AvailableModes = available_modes;
af->TotalMemory = vram_size/1024;
af->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveAccel2D |
afHaveBankedBuffer);
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
af->IOPortsTable = ports_table;
af->SetBank32 = SetBank32;
af->SetBank32Len = (long)SetBank32End - (long)SetBank32;
af->SupplementalExt = ExtStub;
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->SetPaletteData = SetPaletteData;
af->SetBank = SetBank;
// af->WaitTillIdle = WaitTillIdle;
af->Set8x8MonoPattern = NULL;
af->DrawScan = NULL;
af->DrawPattScan = NULL;
af->DrawRect = NULL;
af->DrawPattRect = NULL;
af->DrawLine = NULL;
af->DrawTrap = NULL;
af->PutMonoImage = NULL;
af->BitBlt = BitBlt;
af->BitBltSys = NULL;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
*/
int InitDriver(AF_DRIVER *af)
{
hwptr_init(hwptr.IOMemMaps[0], af->IOMemMaps[0]);
hwptr_init(hwptr.IOMemMaps[1], af->IOMemMaps[1]);
hwptr_init(hwptr.IOMemMaps[2], af->IOMemMaps[2]);
hwptr_init(hwptr.IOMemMaps[3], af->IOMemMaps[3]);
hwptr_init(hwptr.BankedMem, af->BankedMem);
hwptr_init(hwptr.LinearMem, af->LinearMem);
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
#ifndef NO_HWPTR
case FAFEXT_HWPTR:
/* allow farptr access to video memory */
return &hwptr;
#endif
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
VIDEO_MODE *info;
int i;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
for (i=0; i<(int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
modeInfo->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
modeInfo->MaxBuffers = (af->TotalMemory*1024) /
(info->w*info->h*BYTES_PER_PIXEL(info->bpp));
if (info->w > 1024) {
modeInfo->MaxBytesPerScanLine = 2048*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 2048;
}
else {
modeInfo->MaxBytesPerScanLine = 1024*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 1024;
}
modeInfo->BytesPerScanLine = info->w*BYTES_PER_PIXEL(info->bpp);
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
modeInfo->RedMaskSize = info->redsize;
modeInfo->RedFieldPosition = info->redpos;
modeInfo->GreenMaskSize = info->greensize;
modeInfo->GreenFieldPosition = info->greenpos;
modeInfo->BlueMaskSize = info->bluesize;
modeInfo->BlueFieldPosition = info->bluepos;
modeInfo->RsvdMaskSize = info->rsvdsize;
modeInfo->RsvdFieldPosition = info->rsvdpos;
/* for linear video modes, fill in these variables: */
modeInfo->LinBytesPerScanLine = modeInfo->BytesPerScanLine;
modeInfo->LinMaxBuffers = modeInfo->MaxBuffers;
modeInfo->LinRedMaskSize = info->redsize;
modeInfo->LinRedFieldPosition = info->redpos;
modeInfo->LinGreenMaskSize = info->greensize;
modeInfo->LinGreenFieldPosition = info->greenpos;
modeInfo->LinBlueMaskSize = info->bluesize;
modeInfo->LinBlueFieldPosition = info->bluepos;
modeInfo->LinRsvdMaskSize = info->rsvdsize;
modeInfo->LinRsvdFieldPosition = info->rsvdpos;
modeInfo->MaxPixelClock = 135000000;
return 0;
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
int noclear = ((mode & 0x8000) != 0);
long available_vram;
long used_vram;
int pitch;
VIDEO_MODE *info;
RM_REGS r;
/* reject anything with hardware stereo or linear framebuffer */
if (mode & 0x4400)
return -1;
mode &= 0x3FF;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
/* call VESA to set the mode */
r.x.ax = 0x4F02;
r.x.bx = info->num;
if (noclear)
r.x.bx |= 0x8000;
rm_int(0x10, &r);
if (r.h.ah)
return -1;
if (virtualX*BYTES_PER_PIXEL(info->bpp) > info->bpl) {
r.x.ax = 0x4F06;
r.x.bx = 0;
r.x.cx = virtualX;
rm_int(0x10, &r);
if (r.h.ah)
return -1;
*bytesPerLine = r.x.bx;
}
else
*bytesPerLine = info->bpl;
pitch = ((*bytesPerLine)*8)/info->bpp;
/* write_vga_register(0x3D4, 0x13, pitch);*/
clear_vga_register_bits(0x3D4, 0x50, 193);
clear_vga_register_bits(0x3d4, 0x50, 48);
switch ( info->bpp ) {
case 16 : set_vga_register_bits(0x3D4, 0x50, 16); break;
case 24 : set_vga_register_bits(0x3D4, 0x50, 32); break;
case 32 : set_vga_register_bits(0x3D4, 0x50, 48); break;
};
switch ( pitch ) {
case 640 : set_vga_register_bits(0x3D4, 0x50, 64); break;
case 800 : set_vga_register_bits(0x3D4, 0x50, 128); break;
case 1152 : set_vga_register_bits(0x3D4, 0x50, 1); break;
case 1280 : set_vga_register_bits(0x3D4, 0x50, 129); break;
case 1600 : set_vga_register_bits(0x3D4, 0x50, 192); break;
};
/* adjust the virtual width for widescreen modes */
/* store info about the current mode */
af_bpp = info->bpp;
af_width = *bytesPerLine;
af_height = MAX(info->h, virtualY);
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
af_bank = -1;
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory*1024 ;
if (used_vram > available_vram)
return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
}
else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
if (waitVRT >= 0) {
long a = (x * BYTES_PER_PIXEL(af_bpp)) + ((y + af_visible_page*af_height) * af_width);
asm volatile ("cli");
if (waitVRT) {
do {
} while (inportb(0x3DA) & 1);
}
/* write high bits to S3-specific registers */
write_vga_register(0x3D4, 0x38, 0x48);
alter_vga_register(0x3D4, 0x31, 0x30, a>>14);
alter_vga_register(0x3D4, 0x51, 0x03, a>>20);
write_vga_register(0x3D4, 0x38, 0);
/* write to normal VGA address registers */
write_vga_register(0x3D4, 0x0D, (a>>2) & 0xFF);
write_vga_register(0x3D4, 0x0C, (a>>10) & 0xFF);
asm volatile ("sti");
if (waitVRT) {
do {
} while (!(inportb(0x3DA) & 8));
}
}
af_scroll_x = x;
af_scroll_y = y;
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* SetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _SetBank32, _SetBank32End
.align 4
_SetBank32:
pushl %ecx
pushl %edx
movl %edx, %ecx
movl $0x3D4, %edx
movb $0x38, %al /* enable extensions */
outb %al, %dx
incl %edx
movb $0x48, %al
outb %al, %dx
decl %edx
movb $0x31, %al /* read register 0x31 */
outb %al, %dx
incl %edx
inb %dx, %al
decl %edx
movb %al, %ah /* set bank write and vid mem > 256K flags */
movb $0x31, %al
outb %al, %dx
movb %ah, %al
orb $9, %al
incl %edx
outb %al, %dx
decl %edx
movb $0x35, %al /* read register 0x35 */
outb %al, %dx
incl %edx
inb %dx, %al
decl %edx
andb $0xF0, %al /* mix bits 0-3 of bank number */
movb %cl, %ch
andb $0x0F, %ch
orb %al, %ch
movb $0x35, %al /* write the bits 0-3 of bank number */
outb %al, %dx
incl %edx
movb %ch, %al
outb %al, %dx
decl %edx
movb $0x51, %al /* read register 0x51 */
outb %al, %dx
incl %edx
inb %dx, %al
decl %edx
andb $0xF3, %al /* mix bits 4-5 of bank number */
shrb $2, %cl
andb $0x0C, %cl
orb %al, %cl
movb $0x51, %al /* write the bits 4-5 of bank number */
outb %al, %dx
incl %edx
movb %cl, %al
outb %al, %dx
decl %edx
movb $0x38, %al /* disable extensions */
outb %al, %dx
incl %edx
xorb %al, %al
outb %al, %dx
decl %edx
popl %edx
popl %ecx
ret
_SetBank32End:
");
/* SetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable SetBank32() above.
*/
void SetBank(AF_DRIVER *af, long bank)
{
asm (
" call _SetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}
void WaitTillIdle(AF_DRIVER *af) {
unaccelIT();
};
/* BitBlt:
* Blits from one part of video memory to another, using the specified
* mix operation. This must correctly handle the case where the two
* regions overlap.
*/
void blitvram ( int srcx, int srcy, int dstx, int dsty, int dx, int dy, int dir )
{
do ; while ( inportb(0x9AE8) & 0xFF );
outportw(0xBAE8, 0x67);
outportw(0xBEE8, 0xA000);
outportw(0x86E8, srcx);
outportw(0x82E8, srcy);
outportw(0x8EE8, dstx);
outportw(0x8AE8, dsty);
outportw(0x96E8, dx-1);
outportw(0xBEE8, dy-1);
do ; while ( inportb(0x9AE8) & 0xFF ); /* 0xc013 = 14,15,7,0,2 bits set */
if ( dir ) outportw(0x9AE8, 0xC013); else outportw(0x9AE8, 0xC0F3);
/* 0xc0f3 = 14,15,8,5,1,0 bits set */
};
void copyvram ( int srcx, int srcy, int dstx, int dsty, int dx, int dy )
{
int dir = 0;
if ( dsty < srcy || ( srcy == dsty && dstx < srcx )) dir = 0;
else {
dir = 1;
srcx += dx-1;
srcy += dy-1;
dstx += dx-1;
dsty += dy-1;
};
accelIT();
blitvram(srcx, srcy, dstx, dsty, dx, dy, dir);
if ( af_bpp > 8 && af_chipid <= S86c911A )
blitvram(srcx+1024, srcy, dstx+1024, dsty, dx, dy, dir);
unaccelIT();
};
void BitBlt(AF_DRIVER *af, long left, long top, long width, long height, long dstLeft, long dstTop, long op)
{
copyvram(left, top, dstLeft, dstTop, width, height);
};

45
s3/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF S3 driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

44
s3/notes.txt Normal file
View File

@ -0,0 +1,44 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
S3 driver implementation notes.
This is a driver for S3 chipsets. It supports 8/15/16/24/32bits color
modes, and has support for accelerated drawing (currently only for BitBlt
between vram).
This code is not portable to any platforms other than DOS+DPMI, because
it uses BIOS calls to set the initial video mode.
Accelerated functions
---------------------
BitBlt - I'm sorry I didn't add more functions yet, but I haven't got a
time and this function was very important for me. I hope it help
you too. If I had a more time a I will send to Allegro new
functions.
Supported Hardware
------------------
I think all earlier S3 cards and some older. I'm sure for Trio64, I
tested it. If somebody have a problem, please send me note and your
ident. number of S3 card.
Thank you, Michal Stencl
Original Allegro code by Shawn Hargreaves (shawn@talula.demon.co.uk)
Improved by Michael Bukin (M.A.Bukin@inp.nsk.su)
Hardware acceleration by Michal Stencl (stenclpmd@ba.telecom.sk)

132
start.s Normal file
View File

@ -0,0 +1,132 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Startup and relocation code.
*
* See readme.txt for copyright information.
*/
.data
.globl _hdraddr,_reladdr
_hdraddr: .long 0
_reladdr: .long 0
.text
.globl StartDriver, PlugAndPlayInit, OemExt
/* helper for relocating the driver */
#define DO_RELOCATION() \
; \
movl %ebx, _reladdr(%ebx) /* store relocations */ ; \
movl %edx, _hdraddr(%ebx) ; \
; \
movl 876(%edx), %ecx /* get relocation count */ ; \
jecxz 1f ; \
; \
pushl %esi /* get relocation data */ ; \
leal 880(%edx), %esi ; \
cld ; \
; \
0: ; \
lodsl ; \
addl %ebx, (%ebx, %eax) ; \
loop 0b ; \
; \
popl %esi /* relocation is complete */
/* Entry point for the standard VBE/AF interface. When used with our
* extension mechanism, the driver will already have been relocated by
* the OemExt function, so this routine must detect that and do the
* right thing in either case. After sorting out the relocation, it
* chains to a C function called SetupDriver.
*/
PlugAndPlayInit:
movl %ebx, %edx /* save base address in %edx */
movl 576(%ebx), %eax /* retrieve our actual address */
subl $PlugAndPlayInit, %eax /* subtract the linker address */
addl %eax, %ebx /* add to our base address */
cmpl $0, _reladdr(%ebx) /* quit if we are already relocated */
jne 1f
DO_RELOCATION() /* relocate ourselves */
1:
pushl %edx /* do high-level initialization */
call _SetupDriver
popl %edx
ret
/* Driver init function. This is just a wrapper for the C routine called
* InitDriver, with a safety check to bottle out if we are being used
* by a VBE/AF 1.0 program (in that case, we won't have been relocated yet
* so we must give up in disgust).
*/
StartDriver:
pushl %ebx /* check that we have been relocated */
movl 412(%ebx), %eax
subl $StartDriver, %eax
addl %eax, %ebx
cmpl $0, _reladdr(%ebx)
je 0f
call _InitDriver /* ok, this program is using VBE/AF 2.0 */
popl %ebx
ret
0:
movl $-1, %eax /* argh, trying to use VBE/AF 1.0! */
popl %ebx
ret
/* Extension function for the FreeBE/AF enhancements. This will be the
* very first thing called by a FreeBE/AF aware application, and must
* relocate the driver in response. On subsequent calls it will just
* chain to the C function called FreeBEX.
*/
OemExt:
cmpl $0x494E4954, 8(%esp) /* check for FAFEXT_INIT parameter */
jne 2f
pushl %ebx
movl 8(%esp), %ebx /* read driver address from the stack */
movl %ebx, %edx /* save base address in %edx */
movl 580(%ebx), %eax /* retrieve our actual address */
subl $OemExt, %eax /* subtract the linker address */
addl %eax, %ebx /* add to our base address */
cmpl $0, _reladdr(%ebx) /* quit if we are already relocated */
jne 1f
addl %edx, 580(%edx) /* relocate the OemExt pointer */
DO_RELOCATION() /* relocate the rest of the driver */
1:
popl %ebx
movl $0x45583031, %eax /* return FAFEXT_MAGIC1 */
ret
2:
jmp _FreeBEX /* let the driver handle this request */

1624
stub/driver.c Normal file

File diff suppressed because it is too large Load Diff

45
stub/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF stub driver implementation " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

86
stub/notes.txt Normal file
View File

@ -0,0 +1,86 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Stub driver implementation notes.
This is an example driver implementation, intended as a starting point
for anyone who wants to make a real driver for a specific card. It
provides all the essential VBE/AF functions, but it runs on top of your
existing VESA driver, using VESA calls to set the video mode and then
simple software drawing functions to emulate the hardware accelerated
operations. As such it is not useful in any practical way, but it does
work: just copy the vbeaf.drv file to c:\ and you should be able to use
it from any Allegro programs, or the SciTech VBETEST utility (run
"vbetest -f" to use VBE/AF rather than regular VESA).
This driver is not portable, because it uses DPMI calls to communicate
with VESA. This is no problem as long as it is being used with Allegro,
but the binary will not work on any other platforms until you have
removed all the VESA calls and are using direct hardware access for
everything.
This driver provides "accelerated" (emulated in software, and painfully
slow, but they look like hardware functions to the calling program),
versions of the VBE/AF routines:
WaitTillIdle()
SetMix()
Set8x8MonoPattern()
Set8x8ColorPattern()
Use8x8ColorPattern()
DrawScan()
DrawPattScan()
DrawColorPattScan()
DrawRect()
DrawPattRect()
DrawColorPattRect()
DrawLine()
DrawTrap()
PutMonoImage()
BitBlt()
BitBltSys()
SrcTransBlt()
SrcTransBltSys()
If you don't want to support all these in your driver, they should be
replaced with NULL pointers so the caller will know to use their normal
drawing code instead. VBE/AF provides many more routines than these, but
Allegro only uses the ones from that list, so it would be rather futile
to implement any others.
This driver supports the FreeBE/AF extension mechanism for enabling true
protected mode access to video memory. Uncomment the definition of
NO_HWPTR at the top of driver.c if you want to return to the standard
nearptr memory access.
If you comment out the definition of USE_ACCEL at the top of driver.c,
the emulated acceleration routines will be removed, leaving only a dumb
framebuffer driver. This may be useful to see what is the bare minimum of
functions that you need to include in a VBE/AF driver.
This driver implements the FreeBE/AF FAF_CFG_FEATURES extension
mechanism, which allows the installation program to selectively disable
some of the hardware accelerated drawing routines. Comment out the
definition of USE_FEATURES at the top of driver.c if you want to remove
this capability.
There is no support for hardware cursors, 8 bit DAC modes, or the refresh
rate control functions.
The VESA implementation assumes a single 64k memory bank, so it will not
function correctly on cards with dual banks or other granularities. This
won't be a problem for the real drivers, though, because you will know
the granularity in advance. VBE/AF only allows 4k or 64k, so other sizes
must be scaled up to 64k units.
By Shawn Hargreaves
shawn@talula.demon.co.uk

2649
tgui/driver.c Normal file

File diff suppressed because it is too large Load Diff

45
tgui/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0x100, /* DriverRev */
"FreeBE/AF TGUI9440 driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
0x1023, /* PCIVendorID */
0x9440, /* PCIDeviceID */
0xFFFF, /* PCISubSysVendorID */
0xFFFF, /* PCISubSysID */
0 /* Checksum */
};

266
tgui/font.h Normal file
View File

@ -0,0 +1,266 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/* Well, I guess the fonts are Copyrighted by Trident but if you use this
driver then you have a Trident card so I can't see any problem.
But don't use it for other driver without having clear if you can do it.
*/
uchar VGA8x16Font[256*16]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x7E,0x81,0xA5,0x81,0x81,0xBD,0x99,0x81,0x81,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x7E,0xFF,0xDB,0xFF,0xFF,0xC3,0xE7,0xFF,0xFF,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x6C,0xFE,0xFE,0xFE,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x7C,0xFE,0x7C,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x3C,0x3C,0xE7,0xE7,0xE7,0x99,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x3C,0x7E,0xFF,0xFF,0x7E,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE7,0xC3,0xC3,0xE7,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x42,0x42,0x66,0x3C,0x00,0x00,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0x99,0xBD,0xBD,0x99,0xC3,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x1E,0x0E,0x1A,0x32,0x78,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x3F,0x33,0x3F,0x30,0x30,0x30,0x30,0x70,0xF0,0xE0,0x00,0x00,0x00,0x00,
0x00,0x00,0x7F,0x63,0x7F,0x63,0x63,0x63,0x63,0x67,0xE7,0xE6,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x18,0xDB,0x3C,0xE7,0x3C,0xDB,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x80,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x80,0x00,0x00,0x00,0x00,
0x00,0x02,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x7F,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,
0x00,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0xFE,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x7E,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0xFE,0x0C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xFE,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xFF,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x63,0x63,0x63,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,
0x18,0x18,0x7C,0xC6,0xC2,0xC0,0x7C,0x06,0x86,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xC2,0xC6,0x0C,0x18,0x30,0x60,0xC6,0x86,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0x6C,0x38,0x76,0xDC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x0C,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0C,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x18,0x18,0xFF,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x02,0x06,0x0C,0x18,0x30,0x60,0xC0,0x80,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC6,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0x06,0x06,0x3C,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x0C,0x1C,0x3C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xFC,0x0E,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x60,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0xC6,0x06,0x06,0x0C,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7C,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xDE,0xC6,0xC6,0x66,0x3A,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
0x00,0x00,0xE6,0x66,0x6C,0x6C,0x78,0x78,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0xC3,0xE7,0xFF,0xDB,0xDB,0xC3,0xC3,0xC3,0xC3,0xC3,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xDE,0x7C,0x0C,0x0E,0x00,0x00,
0x00,0x00,0xFC,0x66,0x66,0x66,0x7C,0x6C,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xFF,0xDB,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,
0x00,0x00,0xC3,0xC3,0xC3,0xC3,0xC3,0xDB,0xDB,0xFF,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x6C,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0xFF,0xC3,0x83,0x06,0x0C,0x18,0x30,0x61,0xC3,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x06,0x02,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x3E,0x00,0x00,0x00,0x00,
0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,
0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xE0,0x60,0x60,0x78,0x6C,0x66,0x66,0x66,0x66,0xDC,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x1C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00,
0x00,0x00,0xE0,0x60,0x60,0x6C,0x76,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x06,0x06,0x00,0x0E,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3C,0x00,
0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xE6,0xFF,0xDB,0xDB,0xDB,0xDB,0xDB,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00,
0x00,0x00,0x00,0x00,0x00,0xDC,0x76,0x62,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0x60,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x10,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC3,0xC3,0xC3,0xDB,0xDB,0xFF,0x66,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
0x00,0x00,0x00,0x00,0x00,0xFE,0xCC,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x0E,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,
0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x70,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x0C,0x06,0x7C,0x00,0x00,
0x00,0x00,0xCC,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xCC,0xCC,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3C,0x66,0x60,0x60,0x66,0x3C,0x0C,0x06,0x3C,0x00,0x00,0x00,
0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x66,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0xC6,0xC6,0x10,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x38,0x6C,0x38,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x18,0x30,0x60,0x00,0xFE,0x66,0x60,0x7C,0x60,0x60,0x66,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x6E,0x3B,0x1B,0x7E,0xD8,0xDC,0x77,0x00,0x00,0x00,0x00,
0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,
0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0xC6,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
0x00,0xC6,0xC6,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
0x00,0xC6,0xC6,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x18,0x18,0x3C,0x66,0x60,0x60,0x60,0x66,0x3C,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x64,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00,
0x00,0x00,0xC3,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0xFC,0x66,0x66,0x7C,0x62,0x66,0x6F,0x66,0x66,0x66,0xF3,0x00,0x00,0x00,0x00,
0x00,0x0E,0x1B,0x18,0x18,0x18,0x7E,0x18,0x18,0x18,0x18,0x18,0xD8,0x70,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
0x76,0xDC,0x00,0xC6,0xE6,0xF6,0xFE,0xDE,0xCE,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x3C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,
0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x60,0xCE,0x93,0x06,0x0C,0x1F,0x00,0x00,
0x00,0xC0,0xC0,0xC2,0xC6,0xCC,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x0F,0x00,0x00,
0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x33,0x66,0xCC,0x66,0x33,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xCC,0x66,0x33,0x66,0xCC,0x00,0x00,0x00,0x00,0x00,0x00,
0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,
0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,0x55,0xAA,
0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,0xDD,0x77,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,0xF0,
0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,0x0F,
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0xD8,0xD8,0xD8,0xDC,0x76,0x00,0x00,0x00,0x00,
0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDC,0xC6,0xC3,0xC3,0xC3,0xCE,0x00,0x00,0x00,0x00,
0x00,0x00,0xFE,0xC6,0xC6,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x80,0xFE,0x6C,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0xFE,0xC6,0x60,0x30,0x18,0x30,0x60,0xC6,0xFE,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7E,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x76,0xDC,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7E,0x18,0x3C,0x66,0x66,0x66,0x3C,0x18,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xFE,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0x6C,0x6C,0x6C,0x6C,0xEE,0x00,0x00,0x00,0x00,
0x00,0x00,0x1E,0x30,0x18,0x0C,0x3E,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x7E,0xDB,0xDB,0xDB,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x03,0x06,0x7E,0xCF,0xDB,0xF3,0x7E,0x60,0xC0,0x00,0x00,0x00,0x00,
0x00,0x00,0x1C,0x30,0x60,0x60,0x7C,0x60,0x60,0x60,0x30,0x1C,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0xFF,0x18,0x18,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00,0x7E,0x00,0x00,0x00,0x00,
0x00,0x00,0x0E,0x1B,0x1B,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xD8,0xD8,0xD8,0x70,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x18,0x18,0x00,0xFF,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x0F,0x0C,0x0C,0x0C,0x0C,0x0C,0xEC,0x6C,0x6C,0x3C,0x1C,0x00,0x00,0x00,0x00,
0x00,0xD8,0x6C,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x70,0x98,0x30,0x60,0xC8,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x7C,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

263
tgui/html.frt Normal file
View File

@ -0,0 +1,263 @@
#
# This file sets the behavior of the txh generator
#
# Lines starting with # or spaces are skiped except in strings or in [Generate]
# Be carefull with [ it delimits sections!
#
[Configuration]
#
# No external program is needed!
# @.html means: Copy the temporal file to xxxxx.html
#
CommandLine=@.html
Name="Direct HTML 3.X format"
[Delimiters]
# Up to 11 characters
SectionStart=/**[txh]**
# Up to 11 characters
SectionEnd=*********/
[Variables]
#
# Up to 16 definitions
#
# Codes for the behavior of the definitions:
# 1 Normal, put the content if found.
# 2 Repeat, use the last value found in the file, ~no is an exeption, ~clear stops
# 3 If not found replace by the prototype.
# 4 If not found replace by the class.
# 5 If not found replace by the name of the function
# 6 It disables the node generation for this comment. The variable is
# stored in the first variable that have associations and is in the comment.
#
# Additionally there are 2 special variables:
# 90 Name of the file
# 91 Line number of the end of the comment
# 92 Name of the var 0 in the format: ~0 ~~Distinguish{(~Distinguish)~} (node name)
#
# 0 The first variable is the main index variable
#
AddDefinition=Function,5
# 1
AddDefinition=Class,4
# 2
AddDefinition=Include,2
# 3
AddDefinition=Module,2
# 4
AddDefinition=Prototype,3
# 5
AddDefinition=Description,1
# 6
AddDefinition=Return,1
# 7
AddDefinition=Example,1
# 8
AddDefinition=Comments,6
#
# It says what variable is added to distinguish between 2 vars 0 that are equal
#
Distinguish=1
[Associations]
#
# Up to 8 associations
#
# The associations are between the 0 variable and another variable.
#
# Name in main menu, node, variable, optional to add to each node
#
#AddAssoc=List by modules,Modules,3
AddAssoc=List by files,Files,90
[Replace]
#
# All must be delimited by ", they can be used in the GenMain section
#
# Title of the HTML
Constant="FreeBE/AF driver for TGUI9440AGi"
# Description for the help
Constant="This document describes the functions implemented in the
TGUI9440AGi's FreeBE/AF driver.
@p
This document applies to version 1.0 of the driver.
@p"
[Commands]
#
# You can enclose these values between " to make more clear where
# they start and end. Use \n,\r,\t and \" like in C. Use \ at the
# end to concatenate like in C.
#
# @p = end of paragraph
#
EndOfPar="<p>"
#
# @* = break line
#
BreakLine="<br>"
#
# @{value} is the special cross ref.
# ~0 Is the visible name of a reference
# ~1 Is the real name of a reference
#
CrossRef="<a href=\"#~1\">~0</a>"
#
# What we must get from a @@ sequence
#
Double@="@"
[DefinedCommands]
#
# The format is @<name>{parameters ...}
#
subtitle="<Font Size=+1><u>~0</u></Font><p>"
pre=<pre>
/pre=</pre>
#
# This section says how to translate ASCIIs
#
[ASCIIConvert]
 =&aacute;
=&eacute;
¡=&iacute;
¢=&oacute;
£=&uacute;
¤=&ntilde;
¥=&Ntilde;
­=&iexcl;
¨=&iquest;
=&auml;
=&euml;
=&iuml;
=&ouml;
<EFBFBD>=&uuml;
š=&Uuml;
=&agrave;
Š=&egrave;
<EFBFBD>=&igrave;
=&ograve;
=&ugrave;
<=&lt;
>=&gt;
#
# Use ~number to use one variable
# Use ~~number{} for conditional, all the code inside {} will become
# conditional
# This section isn't passed for the macro expansion so here you are
# free to use special commands for the formater.
#
[GenNode]
<p><hr></p>
<a name="~92"></a>
<center><Font Size=+2>~0</Font> (~90 ~91)</center>
<Font Size=+1><u>Syntax</u></Font><p>
~~2{
<pre>
# This line is a comment, but the next is code
#include &lt;~2&gt;
</pre>
~}
~~4{
<pre>
~4;
</pre>
~}
~~1{
<Font Size=+1><u>Member of the class:</u></Font>
~1
<p>
~}
~~5{
<Font Size=+1><u>Description</u></Font><p>
~5
<p>
~}
~~6{
<Font Size=+1><u>Return Value</u></Font><p>
~6
<p>
~}
~~7{
<Font Size=+1><u>Example</u></Font><p>
~7
<p>
~}
[GenMenu]
Start="<Menu>"
#
# ~1 is the visible name
# ~2 is the name of the node
#
Entry="<li><a href=\"#~2\">~1</a>"
End="</Menu>"
#
# ~1 is the name of the association
# ~2 is the menu for it
#
[GenAssoMain]
<p><hr></p>
<a name="~1"></a>
<H1>~1</H1>
~2
#
# ~1 is the name of the association
# ~2 is the name without the distinguish
# ~3 is the comment for it
# ~4 is the menu for it
#
[GenAssoRest]
<p><hr></p>
<a name="~1"></a>
<H1>~2</H1>
~3
~4
#
# ~1 Main menu
# ~2 Name of the function list node
# ~3 Menu for all the functions
# ~4 All the associations code
# ~5 All the function nodes
# ~50+ Values from section Replace
#
[GenMain]
<html>
<head>
<title>~50</title>
</head>
<body>
<H1>~50</H1>
~51
~1
<p><hr></p>
<a name="~2"></a>
<H1>~2</H1>
~3
~4
~5
</body>
</html>

5
tgui/mytypes.h Normal file
View File

@ -0,0 +1,5 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
typedef unsigned char uchar;
typedef unsigned short ushort;

165
tgui/notes.txt Normal file
View File

@ -0,0 +1,165 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Trident TGUI9440AGi driver implementation notes.
Warning: My english is bad ;-)
This is the FreeBE/AF implementation for the Trident 9440 chipset for
PCI boards.
The driver is quite complet but there are some limitations:
1) The driver doesn't work under Windows.
2) The driver doesn't work with SciTech tools like vbetest.exe.
3) The hardware cursor isn't 100% compliant.
Here are explanations about each topic:
1) Trident drivers for Windows aren't good wenough to support a DOS
application setting the mode at register level. The drivers can emulate
VBE calls successfully but virtualize some critical registers avoiding
changes to this registers.
I think that isn't an important limitation because the main goal of
this driver is enhance the performance of DOS Allegro programs and they
works much better under pure DOS.
2) I realised it too late, but this time SciTech taked the desition to
close the Nucleus standard (the VBE/AF sucesor). So I'll address this
topic only if somebody really needs support for it.
3) In the future I'll add a way to disable the hardware cursor
acceleration, but by now I think is better to let it on all the time.
The implemented routines are the following:
WaitTillIdle()
SetMix()
Set8x8MonoPattern()
Set8x8ColorPattern()
Use8x8ColorPattern()
DrawScan()
DrawScanList()
DrawPattScan()
DrawPattScanList()
DrawColorPattScan()
DrawColorPattScanList()
DrawRect()
DrawPattRect()
DrawColorPattRect()
DrawLine()
DrawTrap() *4
SetLineStipple() *1
SetLineStippleCount() *1
DrawStippleLine() *1
PutMonoImage()
BitBlt()
BitBltSys()
SrcTransBlt()
SrcTransBltSys()
GetVideoModeInfo()
SetVideoMode() *3
RestoreTextMode()
SetDisplayStart()
SetActiveBuffer()
SetVisibleBuffer()
GetDisplayStartStatus() *5
SetBank()
SetPaletteData()
SetCursor()
SetCursorPos()
SetCursorColor() *2
ShowCursor()
GetClosestPixelClock()
Notes:
*1 I'm not sure about the implementation but the functions have
equivalent registers in the chip.
*2 9440 doesn't support it, that's a wrapper.
*3 Supports the AF_CRTCInfo parameter!
*4 Implemented using scans because isn't supported by the hard.
*5 Dummy because looks like TGUI doesn't set the interrupt flag.
Additionally I did some attempts to implement the following Inertia
functions, but they are disabled because SciTech dropped it:
GetConfigInfo
GetCurrentMode
SetVSyncWidth
GetVSyncWidth
GetBank
GetVisibleBuffer
GetDisplayStart
SetDisplayStartAddr
IsVSync
WaitVSync
GetActiveBuffer
IsIdle
The driver was implemented without using BIOS calls for this reason is
much more complex than current FreeBE/AF drivers (october 1998).
TGUI9440 doesn't support acelerations in 24 bpp, the modes are supported
but without accelerations.
Supported video modes:
8 bpp 15 bpp 16 bpp 24 bpp
320x200 * * * *
320x240 * * * *
400x300 * * * *
512x384 * * * *
576x432 * * * *
640x400 * * * *
640x480 * * * *
720x540 * * * *
800x600 * * * *
900x675 * * * *
1024x768 * * * (1)
(1) Needs more than 2Mb so is impossible with 9440
Other modes could be implemented using AF_CRTCInfo and
GetClosestPixelClock, that's a good feature of VBE/AF.
Technical notes:
* I'm bliting to the 0xA0000 region instead of the LFB in BitBltSys
because that's faster in the Ivan's motherboard, don't ask me why.
* See the sources for more information.
* Addtionally you can take a look to the vbeaf.htm included, it was
generated by my editor with almost no extra efforts.
Thanks to:
* The rest of the FreeBE/AF team, specially Shawn, the stub helped a lot
and I took ideas from various drivers.
* The people at Trident, they sent me the printed manuals of the board
without asking a cent (they invested money on it!)
* Kendall Benett, even when SciTech taked the desition to close the
Nucleus spec Kendall was very kind answering some questions about
functions, specially about the AF_CRTCInfo structure.
* Ivan Baldo, my beta tester.
Legal notes:
* All trademarks are property of their owners ;-))), I don't know why
manuals point out it, sounds funny no?
* The fonts included where dumped from the Trident's BIOS, I guess that's
OK because the driver works only with Trident boards ;-).
* Here goes another silly one: The information presented in this
publication has been carefully tested for reliability; however, no
responsability is assumed for inaccuracies. Specifications are subject
to change without notice. =-))))))))))
* Now seriously: this driver is under the FreeBE/AF license and no
warranty is provided (after all: try to sue M$ for the time lost
reinstalling Windows over and over each time it screws your HD ;-).
By Salvador Eduardo Tropea (SET)
set-soft@usa.net

144
tgui/regs.h Normal file
View File

@ -0,0 +1,144 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/*
List of ports used:
0x3C0,0x3C1,0x3C2,0x3C3,0x3C4,0x3C5,0x3C6,0x3C7,0x3C8,0x3C9,0x3CC,0x3CE,
0x3CF,0x3D4,0x3D5,0x3DA
TGUI:
0x3D8,0x3D9,0x3DB,0x43C6,0x43C7,0x43C8,0x43C9,0x83C6,0x83C8
0x2100-0x21FF
*/
/* CRT (Cathode Rays Tube) Controller Registers
They control the sync signals.
0x00 to 0x18 */
// SVGALib and XFree86 uses <0x18 so they miss the line compare register,
// don't know why.
#define CRTbase 0
#define CRTcant 25
/* ATT Attribute Controller Registers
They control some attributes like 16 colors palette, overscan color, etc.
0x00 to 0x14 */
#define ATTbase (CRTbase+CRTcant)
#define ATTcant 21
/* GRA Graphics Controller Registers
They control the read/write mode to the video memory.
0x00 to 0x08 */
#define GRAbase (ATTbase+ATTcant)
#define GRAcant 9
/* SEQ Sequence Registers
They control how the memory is scanned.
0x00 to 0x04 */
#define SEQbase (GRAbase+GRAcant)
#define SEQcant 5
/* MOR Miscellaneous Output Register
1 register */
#define MORbase (SEQbase+SEQcant)
#define MORcant 1
#define VGARegsCant (MORbase+MORcant)
/* Status values: Here I store special status values that doesn't
correspond to a physical register but to an operation plus some
special registers */
#define SPbase 0
#define SPcant 12
#define OldNewStatus SPbase+0
#define ALT_BNK_WRITE SPbase+1
#define ALT_BNK_READ SPbase+2
#define ALT_CLK SPbase+3
#define DAC_3C6 SPbase+4
#define DAC_3C6_4th SPbase+5
#define DAC_WR_ADD SPbase+6
#define MCLKLOW SPbase+7
#define MCLKHIG SPbase+8
#define VCLKLOW SPbase+9
#define VCLKHIG SPbase+10
#define DAC_INDEX SPbase+11
/* ESEQ Extra Sequence Registers
0x08 to 0x0F (They have some tricks) */
#define ESEQbase (SPbase+SPcant)
#define ESEQcant 5
#define ESEQ_0D_old ESEQbase+0
#define ESEQ_0E_old ESEQbase+1
#define ESEQ_0D_new ESEQbase+2
#define ESEQ_0E_new ESEQbase+3
#define ESEQ_0F ESEQbase+4
/* ECRT Extra CRT Registers
0x19 to 0x50 */
#define ECRTbase (ESEQbase+ESEQcant)
#define ECRTcant 33
#define ECRT_19 ECRTbase
#define ECRT_1E ECRTbase+1
#define ECRT_1F ECRTbase+2
#define ECRT_20 ECRTbase+3
#define ECRT_21 ECRTbase+4
#define ECRT_22 ECRTbase+5
#define ECRT_23 ECRTbase+6
#define ECRT_24 ECRTbase+7
#define ECRT_25 ECRTbase+8
#define ECRT_26 ECRTbase+9
#define ECRT_27 ECRTbase+10
#define ECRT_28 ECRTbase+11
#define ECRT_29 ECRTbase+12
#define ECRT_2A ECRTbase+13
#define ECRT_2C ECRTbase+14
#define ECRT_2F ECRTbase+15
#define ECRT_30 ECRTbase+16
#define ECRT_33 ECRTbase+17
#define ECRT_34 ECRTbase+18
#define ECRT_35 ECRTbase+19
#define ECRT_36 ECRTbase+20
#define ECRT_37 ECRTbase+21
#define ECRT_38 ECRTbase+22
#define ECRT_39 ECRTbase+23
#define ECRT_40 ECRTbase+24
#define ECRT_41 ECRTbase+25
#define ECRT_42 ECRTbase+26
#define ECRT_43 ECRTbase+27
#define ECRT_44 ECRTbase+28
#define ECRT_45 ECRTbase+29
#define ECRT_46 ECRTbase+30
#define ECRT_47 ECRTbase+31
#define ECRT_50 ECRTbase+32
/* EGRA Extra Graphics Controller Registers
0x0E, 0x0F, 0x23 and 0x2F */
#define EGRAbase (ECRTbase+ECRTcant)
#define EGRAcant 4
#define EGRA_0E_old EGRAbase
#define EGRA_0F EGRAbase+1
#define EGRA_23 EGRAbase+2
#define EGRA_2F EGRAbase+3
/* EDAC Extra DAC/Clk */
#define EDACbase (EGRAbase+EGRAcant)
#define EDACcant 4
#define EDAC_00 EDACbase+0
#define EDAC_01 EDACbase+1
#define EDAC_02 EDACbase+2
#define EDAC_03 EDACbase+3
/* GER Graphics Engine Register. Only the relevant stuff */
/* 0x22 and 0x23 */
#define GERbase (EDACbase+EDACcant)
#define GERcant 6
#define GER_22 GERbase+0
#define GER_23 GERbase+1
#define GER_44 GERbase+2
#define GER_45 GERbase+3
#define GER_46 GERbase+4
#define GER_47 GERbase+5
#define SVGARegsCant (GERbase+GERcant)
#ifdef __cplusplus
extern "C" {
#endif
int VGASaveRegs(uchar *regs, uchar *Sregs);
void VGALoadRegs(const uchar *regs,const uchar *Sregs);
void TGUI9440SaveRegs(uchar *regs);
void TGUI9440LoadRegs(const uchar *regs);
#ifdef __cplusplus
}
#endif

463
tgui/rw_regs.c Normal file
View File

@ -0,0 +1,463 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/*****************************************************************************
ROUTINES to store/retrieve the VGA and TGUI registers.
*****************************************************************************/
#include <pc.h>
#include "mytypes.h"
#include "regs.h"
#include "vga.h"
#include "tgui.h"
//#include <stdio.h>
/**[txh]********************************************************************
Description:
This routines captures the TGUI registers in an array. Not all are stored
because isn't needed by now. In fact I'm storing a lot of registers that
are not needed to store.
***************************************************************************/
void TGUI9440SaveRegs(uchar *regs)
{
int Old_New;
int i,Protect,DACaccess,DACaddress;
/* Extended Sequencer */
/* 8 is an status (old/new mode, field under scaning, FIFO in use) */
Old_New=ReadSEQ(8);
regs[OldNewStatus]=Old_New;
/* 9 is the revision code, A reserved, B chip ID */
/* Enter in old mode */
WriteSEQ(0xB,0);
regs[ESEQ_0D_old]=ReadSEQ(0xD);
regs[ESEQ_0E_old]=ReadSEQ(0xE);
regs[EGRA_0E_old]=ReadGRA(0xE);
/* Enter in new mode */
ReadSEQ(0xB);
regs[ESEQ_0D_new]=ReadSEQ(0xD);
//fprintf(stderr,"Lectura: %X %X\n",ReadSEQ(0x8),ReadSEQ(0xD));
Protect=
regs[ESEQ_0E_new]=ReadSEQ(0xE);
regs[ESEQ_0F] =ReadSEQ(0xF);
/* Unprotect the registers */
WriteSEQ(0xE,Protect | 0x80);
DACaccess=
regs[EGRA_0F]=ReadGRA(0xF);
regs[EGRA_23]=ReadGRA(0x23);
regs[EGRA_2F]=ReadGRA(0x2F);
/* Enable access to the DAC */
WriteGRA(0xF,DACaccess | 4);
/* These are alternative registers so I don't know if I really need to
store your content */
regs[ALT_BNK_WRITE]=inportb(0x3D8);
regs[ALT_BNK_READ] =inportb(0x3D9);
regs[ALT_CLK] =inportb(0x3DB);
/* These extended register are located in the CRT space but they aren't
contiguous */
regs[ECRTbase]=ReadCRT(0x19); // 0 (0x19)
for (i=1; i<14; i++)
regs[ECRTbase+i]=ReadCRT(0x1D+i); // 1-13 (0x1D-0x2A)
regs[ECRTbase+i]=ReadCRT(0x2C); // 14
i++;
regs[ECRTbase+i]=ReadCRT(0x2F); // 15
i++;
regs[ECRTbase+i]=ReadCRT(0x30); // 16
for (i++; i<24; i++)
regs[ECRTbase+i]=ReadCRT(0x22+i); // 17-23
for (; i<32; i++)
regs[ECRTbase+i]=ReadCRT(0x28+i); // 24-31
regs[ECRTbase+i]=ReadCRT(0x50); // 32
/* Map the DAC safetly (0x3C6 so doesn't overlap others) */
DACaddress=ReadCRT(0x29);
WriteCRT(0x29,DACaddress & 0xFC);
regs[DAC_3C6] =inportb(0x3C6);
inportb(0x3C6); inportb(0x3C6); inportb(0x3C6);
regs[DAC_3C6_4th]=inportb(0x3C6);
regs[DAC_WR_ADD] =inportb(0x3C8);
regs[MCLKLOW] =inportb(0x43C6);
regs[MCLKHIG] =inportb(0x43C7);
regs[VCLKLOW] =inportb(0x43C8);
regs[VCLKHIG] =inportb(0x43C9);
regs[DAC_INDEX] =inportb(0x83C8);
for (i=0; i<EDACcant; i++)
regs[EDACbase+i]=ReadEDAC(i);
/* The GER */
/* Enable it and map in memory */
WriteCRT(0x36,MODEINIT);
regs[GER_22]=Getb(0x22);
regs[GER_23]=Getb(0x23);
*((unsigned *)&regs[GER_44])=Getl(0x44);
WriteCRT(0x36,regs[ECRT_36]);
/* Restore the DAC mapping */
WriteCRT(0x29,DACaddress);
/* Restore the DAC access */
if ((DACaccess & 4)==0)
WriteGRA(0xF,DACaccess);
/* Restore the protection */
if ((Protect & 0x80)==0)
WriteSEQ(0xE,Protect);
/* Restore the old/new mode */
if ((Old_New & 0x80)==0)
WriteSEQ(0xB,0);
}
/**[txh]********************************************************************
Description:
This function stores ALL the VGA registers in an array. Additionally it
calls to the routine that stores the TGUI registers around 120 registers
are stored.
***************************************************************************/
int VGASaveRegs(uchar *regs, uchar *Sregs)
{
int i;
uchar MORval;
/* I'm trying to do this routine as strong and generic as possible
without loosing performance.
So I ever put the VGA chip in the color mode (ports=0x3Dx) but I
store the real state */
MORval=ReadMOR();
WriteMOR(MORval | 1);
regs[MORbase]=MORval;
/* I think the best place to put a call to save the chipset specific
registers is here because TGUI9440 can save some interesting things
about the VGA registers. For example: 3x4/5.24.b7 is the current
state of "Attribute Address Register" (3C0: address or data), that's
impossible to know in a VGA card. */
TGUI9440SaveRegs(Sregs);
for (i=0; i<CRTcant; i++)
regs[CRTbase+i]=ReadCRT(i);
/******* The Attribute Registers are worst that a pain in the ass I think
the @#*$ people from the Giant Blue tried to make it hard to
understand on purpose ********/
for (i=0; i<ATTcant; i++)
regs[ATTbase+i]=ReadATT(i);
ATTEndReads();
for (i=0; i<GRAcant; i++)
regs[GRAbase+i]=ReadGRA(i);
for (i=0; i<SEQcant; i++)
regs[SEQbase+i]=ReadSEQ(i);
WriteMOR(MORval);
return VGARegsCant;
}
/**[txh]********************************************************************
Description:
Restores the TGUI registers from an array.
***************************************************************************/
void TGUI9440LoadRegs(const uchar *regs)
{
int i,Protect,DACaccess,DACaddress;
/* Enter in old mode */
WriteSEQ(0xB,0);
WriteSEQ(0xD,regs[ESEQbase]);
WriteSEQ(0xE,regs[ESEQbase+1]);
WriteGRA(0xE,regs[EGRAbase]);
/* Enter in new mode */
ReadSEQ(0xB);
WriteSEQ(0xD,regs[ESEQ_0D_new]);
//fprintf(stderr,"Escritura: %X %X\n",ReadSEQ(0x8),ReadSEQ(0xD));
/* Unprotect the registers */
Protect=regs[ESEQbase+3];
WriteSEQ(0xE,Protect | 0x80);
WriteSEQ(0xF,regs[ESEQbase+4]);
/* Enable access to the DAC */
DACaccess=regs[EGRAbase+1];
WriteGRA(0x0F,DACaccess | 4);
WriteGRA(0x23,regs[EGRAbase+2]);
WriteGRA(0x2F,regs[EGRAbase+3]);
/* These are alternative registers so I don't know if I really need to
store your content */
outportb(0x3D8,regs[SPbase+1]);
outportb(0x3D9,regs[SPbase+2]);
//fprintf(stderr,"Escritura antes 3DB: %X %X\n",ReadSEQ(0x8),ReadSEQ(0xD));
outportb(0x3DB,regs[SPbase+3]);
//fprintf(stderr,"Escritura dopo: %X %X\n",ReadSEQ(0x8),ReadSEQ(0xD));
/* These extended register are located in the CRT space but they aren't
contiguous */
WriteCRT(0x19,regs[ECRTbase]); // 0 (0x19)
for (i=1; i<14; i++)
WriteCRT(0x1D+i,regs[ECRTbase+i]); // 1-13 (0x1D-0x2A)
WriteCRT(0x2C,regs[ECRTbase+i]); // 14
i++;
WriteCRT(0x2F,regs[ECRTbase+i]); // 15
i++;
WriteCRT(0x30,regs[ECRTbase+i]); // 16
for (i++; i<24; i++)
WriteCRT(0x22+i,regs[ECRTbase+i]); // 17-23
for (; i<32; i++)
WriteCRT(0x28+i,regs[ECRTbase+i]); // 24-31
WriteCRT(0x50,regs[ECRTbase+i]); // 32
/* Map the DAC safetly (0x3C6 so doesn't overlap others) */
DACaddress=regs[ECRT_29];
WriteCRT(0x29,DACaddress & 0xFC);
inportb(0x3C8);
outportb(0x3C6,regs[DAC_3C6]);
inportb(0x3C8);
inportb(0x3C6); inportb(0x3C6); inportb(0x3C6); inportb(0x3C6);
outportb(0x3C6,regs[DAC_3C6_4th]);
outportb(0x3C8,regs[SPbase+6]);
outportb(0x43C6,regs[SPbase+7]);
outportb(0x43C7,regs[SPbase+8]);
outportb(0x43C8,regs[SPbase+9]);
outportb(0x43C9,regs[SPbase+10]);
outportb(0x83C8,regs[SPbase+11]);
for (i=0; i<EDACcant; i++)
WriteEDAC(i,regs[EDACbase+i]);
/* The GER */
/* Enable it and map in memory */
WriteCRT(0x36,MODEINIT);
Putb(0x22,regs[GER_22]);
Putb(0x23,regs[GER_23]);
Putl(0x44,*((unsigned *)&regs[GER_44]));
WriteCRT(0x36,regs[ECRT_36]);
/* Restore the DAC mapping */
WriteCRT(0x29,DACaddress);
/* Restore the DAC access */
if ((DACaccess & 4)==0)
WriteGRA(0xF,DACaccess);
/* Restore the protection */
if ((Protect & 0x80)==0)
WriteSEQ(0xE,Protect);
/* Restore the old/new mode */
if ((regs[OldNewStatus] & 0x80)==0)
WriteSEQ(0xB,0);
}
/**[txh]********************************************************************
Description:
Restores the VGA registers from an array.
***************************************************************************/
void VGALoadRegs(const uchar *regs,const uchar *Sregs)
{
int i;
uchar CRT11,MORval;
MORval=ReadMOR();
/* Ensure we are in the color mode or the ports could be moved to 0x3Bx */
WriteMOR(MORval | 1);
/* Wait a full retrace to avoid extra noise in screen */
while (inportb(0x3DA) & 8);
while (!(inportb(0x3DA) & 8));
/* Screen Off to avoid funny things displayed */
WriteSEQ(0x01,regs[SEQbase+1] | 0x20);
/* Synchronous reset ON, we must do it or we could lose video RAM contents */
WriteSEQ(0x00,1);
for (i=2; i<SEQcant; i++)
WriteSEQ(i,regs[SEQbase+i]);
/* Synchronous reset restored */
WriteSEQ(0x00,regs[SEQbase]);
/* Deprotect CRT registers 0-7 */
CRT11=regs[CRTbase+0x11];
WriteCRT(0x11,CRT11 & 0x7F);
/* write CRT registers */
for (i=0; i<CRTcant; i++)
if (i!=0x11)
WriteCRT(i,regs[CRTbase+i]);
/* Restore the protection state */
WriteCRT(0x11,CRT11);
for (i=0; i<GRAcant; i++)
WriteGRA(i,regs[GRAbase+i]);
/******* The Attribute Registers are worst that a pain in the ass I think
the @#*$ people from the Giant Blue tried to make it hard to
understand on purpose ********/
/* Ensure we will write to the index */
inportb(ATTdir);
for (; i<ATTcant; i++)
WriteATT(i,regs[ATTbase+i]);
ATTEndReads();
TGUI9440LoadRegs(Sregs);
/* Restore MOR */
WriteMOR(regs[MORbase]);
/* Restore Screen On/Off status */
WriteSEQ(0x01,regs[SEQbase+1]);
}
#ifdef INCLUDE_OLD_INERTIA_STUFF
/**[txh]********************************************************************
Description:
Returns the vertical sync start and end values. Not optimized because I
think that's a very strange stuff.
***************************************************************************/
void ReadVSync(int *start, int *end)
{
int s,e,aux;
s=ReadCRT(0x10);
aux=ReadCRT(0x7);
s|=((aux & 0x04)<<6); /* b8 */
s|=((aux & 0x80)<<2); /* b9 */
aux=ReadCRT(0x27);
s|=((aux & 0x40)<<4); /* b10 */
*start=s;
/* Only 4 bits are available: */
e=(s & 0xFFF0) | (ReadCRT(0x11) & 0xF);
/* Adjust it */
if (e<s)
e+=0x10;
*end=e;
}
/**[txh]********************************************************************
Description:
Sets the vertical sync start and end values. Not optimized because I
think that's a very strange stuff.
***************************************************************************/
void SetVSync(int start, int end)
{
int a;
WriteCRT(0x10,start);
a=ReadCRT(0x7) & 0x7B;
a|=((start & 0x100)>>6); /* b8 */
a|=((start & 0x200)>>2); /* b9 */
WriteCRT(0x7,a);
a=ReadCRT(0x27) & 0xBF;
a|=((start & 0x400)>>4); /* b10 */
WriteCRT(0x27,a);
WriteCRT(0x11,0x80 | (end & 0x0F));
}
#endif
/*
* means stored
3C3 [No] (Hardware specific)
46E8 [No] (Hardware specific)
*3C5.08 We must save b7 to recreate the old/new mode and manipulate it.
3C5.09 [No!] (RO)
3C5.0A [No] (Reserved)
3C5.0B [No!] (RO)
3C5.0C-1 [No] (Hardware specific)
3C5.0C-2 [No] (BIOS reserved)
*3C5.0D-old [No] CB (Hardware specific)
*3C5.0E-old
*3CF.0E-old
*3C5.0D-new
*3C5.0E-new We must manipulate b7 for other registers (enable from here and
restart at the end).
3CF.0E-new [No!] Have alternative and could mess the alternative.
*3C5.0F [No] (Hardware specific)
*3CF.0F We must enable b2 and restart at the end.
*3CF.23
*3CF.2F
*3D8
*3D9
*3DB
*3D5.19
*3D5.1E
*3D5.1F [No] CB (Reserved) BIOS stores the amount of memory here and the driver
will read it just once so we don't need to save it.
*3D5.20
*3D5.21 [No] CB It contols the Linear Address but I can't understand how it
works.
*3D5.22
*3D5.23 [No] CB It fine tunes the DRAM speed.
*3D5.24
*3D5.25
*3D5.26
*3D5.27
*3D5.28 [No] (Hardware specific)
*3D5.29 we must clear b0-1 and enable at the end to access the DAC.
*3D5.2A [No] (Hardware specific)
*3D5.2C
*3D5.2F
*3D5.30 [No] (Reserved)
*3D5.33
*3D5.34
*3D5.35
*3D5.36
*3D5.37 [No] (Hardware specific)
*3D5.38
*3D5.39 [No] (Hardware specific)
*3D5.40-47,50 Ok Hardware cursor.
*3C6
Here comes a crazy thing: we read 3 times more 3C6
*3C6 (This time is a different value).
3C7 [No!] the read back value isn't usefull
*3C8 Ok the read back is the address.
3C9 [No!] we save the whole palette ;-)
*43C6-9
*83C8 That's the 83C6/8 index.
*83C6.00
*83C6.01
*83C6.02
*83C6.03
*83C6.04
83C6.05 [No!] (RO)
83C6.30 [No] The following are very optional:
83C6.31 [No]
83C6.32 [No]
83C6.34 [No]
83C6.35 [No]
83C6.36 [No]
83C6.37 [No]
83C6.38 [No]
*GER.22
*GER.23 22-23 sets the pitch and offset of the operations
*GER.44-47 (patterned lines parameters)
The rest of the GER can change in any way because I set all the values from
call to call.
*/

1040
tgui/setmode.c Normal file

File diff suppressed because it is too large Load Diff

60
tgui/setmode.h Normal file
View File

@ -0,0 +1,60 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/***** Flags used in the video mode structure *****/
/* b0-b1 */
#define NHSync 1
#define NVSync 2
#define PHSync 0
#define PVSync 0
/* b2-b3 */
#define DoubleScan 4
#define TripleScan 8
#define QuadrupleScan 0xC
/* b4-b6 */
#define BPP8 0x00
#define BPP15 0x10
#define BPP16 0x20
#define BPP24 0x30
/* b7 */
#define Interlaced 0x80
/* b31 */
#define HaveAccel2D 0x80000000
/* This mask erase all the flags passed in the CRTC structure */
#define InternalMask 0xFFFFFF70
#define ExtractBPP(a) ((a & 0x70)>>4)
#define is8BPP 0
#define is15BPP 1
#define is16BPP 2
#define is24BPP 3
/**** Video mode structure ****/
typedef struct
{
int flags;
ushort hDisplay,hSyncStart,hSyncEnd,hTotal;
ushort vDisplay,vSyncStart,vSyncEnd,vTotal;
ushort minBytesPerScan;
uchar ClockType;
uchar ClockValHigh,ClockValLow;
} VideoModeStr;
extern VideoModeStr *SupportedVideoModes[];
extern int NumSupportedVideoModes;
extern short SupportedVideoModesNums[];
#ifdef __cplusplus
extern "C" {
#endif
void CaptureSVGAStart(void);
void Set640x480x8bpp(void);
int GetBestPitchFor(int BytesPerScan, int BytesPerPixel);
void SetVideoModeH(VideoModeStr *modeInfo, int width, int bpp);
void SetTextModeVGA(void);
void ReadVSync(int *start, int *end);
void SetVSync(int start, int end);
#ifdef __cplusplus
}
#endif

330
tgui/tgui.h Normal file
View File

@ -0,0 +1,330 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/* TGUI Alternative bank selector */
/* It select the bank when we use a 32Kb or 64Kb window */
#define DestinationSegmentAddress 0x3D8
#define SourceSegmentAddress 0x3D9
#define INLINE extern inline
//#define IOMAPPED
//#define UNDERTEST
#ifdef UNDERTEST
#include <sys/farptr.h>
#endif
#ifdef IOMAPPED
#define MODEINIT 0x80
INLINE void Putb(unsigned pos, uchar val) { outportb(0x2100+pos,val); }
INLINE void Putw(unsigned pos, ushort val) { outportw(0x2100+pos,val); }
INLINE void Putl(unsigned pos, unsigned val) { outportl(0x2100+pos,val); }
INLINE uchar Getb(unsigned pos) { return inportb(0x2100+pos); }
INLINE ushort Getw(unsigned pos) { return inportw(0x2100+pos); }
INLINE unsigned Getl(unsigned pos) { return inportl(0x2100+pos); }
#else
// Memory mapped
#define MODEINIT 0x81
#ifdef UNDERTEST
#define MMIOBASE 0xB7F00
//#define MMIOBASE 0xBFF00
//#define MODEINIT 0x82
INLINE void Putb(unsigned pos, uchar val) { _farnspokeb(MMIOBASE+pos,val); }
INLINE void Putw(unsigned pos, ushort val) { _farnspokew(MMIOBASE+pos,val); }
INLINE void Putl(unsigned pos, unsigned val) { _farnspokel(MMIOBASE+pos,val); }
INLINE uchar Getb(unsigned pos) { return _farnspeekb(MMIOBASE+pos); }
INLINE ushort Getw(unsigned pos) { return _farnspeekw(MMIOBASE+pos); }
INLINE unsigned Getl(unsigned pos) { return _farnspeekl(MMIOBASE+pos); }
#else
extern unsigned MMIOBASE;
/*
If I don't use volatile the stupid gcc does funny things like that:
movl _MMIOBASE,%eax
movl 0x32(%eax),%al
Lxxx:
testb %al,$0x40
jne Lxxx
:-)))) the silly compiler is specting some gost will change AL by magic.
Using volatile generates good code. Some idiot reloads are performed but
that's normal in the "unoptimizer" module of gcc ;-)
Memory mapped I/O generates much compact code and I guess faster too, I
must test it.
*/
INLINE void Putb(unsigned pos, uchar val) { *((volatile uchar *)(MMIOBASE+pos))=val; }
INLINE void Putw(unsigned pos, ushort val) { *((volatile ushort *)(MMIOBASE+pos))=val; }
INLINE void Putl(unsigned pos, unsigned val) { *((volatile unsigned *)(MMIOBASE+pos))=val; }
INLINE uchar Getb(unsigned pos) { return *((volatile uchar *)(MMIOBASE+pos)); }
INLINE ushort Getw(unsigned pos) { return *((volatile ushort *)(MMIOBASE+pos)); }
INLINE unsigned Getl(unsigned pos) { return *((volatile unsigned *)(MMIOBASE+pos)); }
#endif
#endif
// Register index
#define GECR 0x36
#define CLAR 0x21
// ****************************** GER values ********************************
// Status
#define GESR 0x20
// Operation Mode 0
#define GOMR0 0x22
// Operation Mode 1 (Not implemented in 9440)
#define GOMR1 0x23
// Command
#define GECoR 0x24
// Foreground Mix
#define FMR 0x27
// Drawing Flag 0,1,2 (Not implemented in 9440) and 3
#define GEDFR0 0x28
#define GEDFR1 0x29
#define GEDFR2 0x2A
#define GEDFR3 0x2B
/* All joined in one 32 bits: */
#define PatFromDisplay 0x00000002
#define PatFromSystem 0
#define SourceDataDisplay 0x00000004
#define SourceDataSystem 0
#define PatMono 0x00000020
#define PatColor 0
#define SourceDataMono 0x00000040
#define SourceDataColor 0
#define YDecreasing 0x00000100
#define XDecreasing 0x00000200
#define YMajor 0x00000400
#define TransparentEnable 0x00001000
#define TransparentReverse 0x00002000
#define SolidDrawing 0x00004000
#define PatternedDrawing 0
#define PatternedLines 0x00008000
// Foreground Color 0 (Low 8 bits) and 1
#define FCR0 0x2C
#define FCR1 0x2D
// Background Color 0 (Low 8 bits) and 1
#define BCR0 0x30
#define BCR1 0x31
// Pattern Location 0 (Low) and 1
// Data must be 64 bytes aligned in VRAM, in 16 bits mode the lower bit must
// be 0
#define PLR0 0x34
#define PLR1 0x35
// Destination X Location 0 (Low) and 1
#define DXL0 0x38
#define DXL1 0x39
// Destination Y Location 0 (Low) and 1
// Only 11 bits used
#define DYL0 0x3A
#define DYL1 0x3B
// Source X Location 0 (Low) and 1
// Or diagonal step for line operations (detaY-deltaX) only 12 bits signed
#define SXL0 0x3C
#define SXL1 0x3D
// Source Y Location 0 (Low) and 1
// Or axial step for line operations (detaY) only 11 bits signed
#define SYL0 0x3E
#define SYL1 0x3F
// Operation Dimension X Location 0 (Low) and 1
// Or initial error for line operations (2*detaY-deltaX) only 12 bits signed
#define ODXL0 0x40
#define ODXL1 0x41
// Operation Dimension Y Location 0 (Low) and 1
// Or length for line operations (deltaX) only 12 bits unsigned
// Various bits for short vector operations.
#define ODYL0 0x42
#define ODYL1 0x43
// Pen Style Mask 0 and 1 for lines
#define PSMR0 0x44
#define PSMR1 0x45
// Style Mask First Pixel Repeat Count for lines
#define SMFPRC 0x46
// Style Mask Repeat Count for lines
#define SMRC 0x47
// Registers 0x80 to 0xFF are for the pattern
// ************************* End of GER values *****************************
// ****** Commands for GECoR ******
#define NOP 0
#define BitBLT 1
#define ScanLine 3
// Bresenham Line
#define BLine 4
// Short vector
#define SVector 5
extern unsigned long linearAddress;
#define Screenb ((uchar *)linearAddress)
#define Screenw ((ushort *)linearAddress)
#define Screenl ((unsigned *)linearAddress)
#define SetXLocation(a) Putw(DXL0,a)
#define SetYLocation(a) Putw(DYL0,a)
#define SetXYLocation(a,b) Putl(DXL0,(a) | ((b)<<16))
#define SetXYSource(a,b) Putl(SXL0,(a) | ((b)<<16))
#define SetForeground(a) Putw(FCR0,a)
#define SetBackground(a) Putw(BCR0,a)
#define SetForegroundMix(a) Putb(FMR,a)
#define SetPenStyleMask(a) Putw(PSMR0,a)
#define SetStyleMaskRepeatCount(a) Putb(SMRC,a)
//#define SAFE_IO
INLINE
void SetLineSteps(int deltaY, int deltaX)
{
// Diagonal step is dY-dX, Axial step is dY both 16 bits signed
Putl(SXL0,((deltaY-deltaX) & 0xFFFF) | (deltaY<<16));
}
INLINE
void SetErrAndLen(int deltaY, int deltaX)
{
// Initial error is 2*dY-dX (signed), Length is ABS(dX) (unsigned)
Putl(ODXL0,((2*deltaY-deltaX) & 0xFFFF) | (deltaX<<16));
}
INLINE
void SetDimensions(int width, int height)
{
Putl(ODXL0,width | (height<<16));
}
INLINE
void SetWidth_1(int width)
{
Putw(ODXL0,width-1);
}
INLINE
void SetWidth(int width)
{
Putw(ODXL0,width);
}
INLINE
void SetDrawFlags(int dir)
{
Putl(GEDFR0,dir);
}
INLINE
void SetPatternLocation(unsigned offset)
{
Putw(PLR0,offset);
}
/*
Wait until the GER is idle. That's needed for the BitBlt operation because
we can't write to the screen. If I return the control to the application
and it tries to draw directly to the screen it will fail.
In OS drivers, line Windows drivers, that's not needed because the
application NEVER will draw directly to the screen.
An additional feature not exploited is that the GER can generate interrupts
so we can have a queue of command in memory and transfer it to the TGUI
when the GER is ready.
*/
INLINE
void WaitGE(void)
{
while (Getb(GESR) & 0x80);
}
/*
Wait until the FIFO of the GER is empty, if we don't do it the cached
command will use the new settings ;-)
*/
INLINE
void WaitGEfifo(void)
{
while (Getb(GESR) & 0x20);
}
/*
That's a very bad thing, I must put a full wait after the blit because
during the Blit the CPU can't access the VRAM.
It could be avoided only if ALL the drawing is made by the driver, but
that's not the FreeBE/AF case.
*/
INLINE
void DoBlit(void)
{
Putb(GECoR,BitBLT);
#ifdef WAITTILLIDLE_NOT_NEEDED
WaitGE();
#endif
}
INLINE
void DoBlitDontWait(void)
{
Putb(GECoR,BitBLT);
}
INLINE
void DoBresenhamLine(void)
{
Putb(GECoR,BLine);
}
INLINE
void DoScan(void)
{
Putb(GECoR,ScanLine);
}
INLINE
void SetNewMode(void)
{
ReadSEQ(0xB);
}
INLINE
void SetOldMode(void)
{
WriteSEQ(0xB,0);
}
/**************************** RASTER OPERATIONS ****************************/
/* Most of them are for solid colors or patterns only */
#define ROP_0 0x00
#define ROP_n_PoD 0x05
#define ROP_nPaD 0x0A
#define ROP_nP 0x0F
#define ROP_PanD 0x50
#define ROP_nD 0x55
#define ROP_PxD 0x5A
#define ROP_n_PaD 0x5F
#define ROP_PaD 0xA0
#define ROP_n_PxD 0xA5
#define ROP_D 0xAA
#define ROP_nPoD 0xAF
#define ROP_P 0xF0
#define ROP_PonD 0xF5
#define ROP_PoD 0xFA
#define ROP_1 0xFF
/* These are for image blits only */
/* 0x00 is ROP_0 */
#define ROP_n_SoD 0x11
#define ROP_nSaD 0x22
#define ROP_nS 0x33
#define ROP_SanD 0x44
/* 0x55 is ROP_nD */
#define ROP_SxD 0x66
#define ROP_n_SaD 0x77
#define ROP_SaD 0x88
#define ROP_n_SxD 0x99
/* 0xAA is ROP_D */
#define ROP_nSoD 0xBB
#define ROP_S 0xCC
#define ROP_SonD 0xDD
#define ROP_SoD 0xEE
/* 0xFF is ROP_1 */
#define VClockDiv2 0x20
#define VClockDiv4 0x40
#define VClockDiv1_5 0x60
#define DClockDiv2 0x80

1601
tgui/vbeaf.htm Normal file

File diff suppressed because it is too large Load Diff

248
tgui/vga.h Normal file
View File

@ -0,0 +1,248 @@
/* Copyright 1998 (c) by Salvador Eduardo Tropea
This code is part of the FreeBE/AF project you can use it under the
terms and conditions of the FreeBE/AF project. */
/* (I don't take care about mono by now) */
/* VGA Atttibute controller */
#define ATTindex 0x3C0
#define ATTdataW 0x3C0
#define ATTdataR 0x3C1
#define ATTdir 0x3DA
/* Miscellaneous Output Register */
#define MORdataW 0x3C2
#define MORdataR 0x3CC
/* VGA Sequencer Registers */
#define Sequencer 0x3C4
#define SequencerIndex 0x3C4
#define SequencerData 0x3C5
/* VGA Palette Registers */
#define ReadDataAddress 0x3C7
#define WriteDataAddress 0x3C8
#define PaletteDataRegister 0x3C9
/* VGA Graphics Controller Registers */
#define GraphicsController 0x3CE
#define GraphicsControllerIndex 0x3CE
#define GraphicsControllerData 0x3CF
/* VGA CRT Controller Register */
#define CRTController 0x3D4
#define CRTControllerIndex 0x3D4
#define CRTControllerData 0x3D5
/* VGA Input Status Register 1 */
#define InputStatusRegister1 0x3DA
/* Trident's DAC/Clock */
#define EDACindex 0x83C8
#define EDACdata 0x83C6
//#define SAFE_IO
#ifdef SAFE_IO
/* C approach, safier than my assembler ;-) */
extern inline
uchar ReadCRT(uchar index)
{
outportb(CRTControllerIndex,index);
return inportb(CRTControllerData);
}
extern inline
uchar ReadGRA(uchar index)
{
outportb(GraphicsControllerIndex,index);
return inportb(GraphicsControllerData);
}
extern inline
uchar ReadSEQ(uchar index)
{
outportb(SequencerIndex,index);
return inportb(SequencerData);
}
extern inline
void WriteCRT(uchar index, uchar value)
{
outportb(CRTControllerIndex,index);
outportb(CRTControllerData,value);
}
extern inline
void WriteGRA(uchar index, uchar value)
{
outportb(GraphicsControllerIndex,index);
outportb(GraphicsControllerData,value);
}
extern inline
void WriteSEQ(uchar index, uchar value)
{
outportb(SequencerIndex,index);
outportb(SequencerData,value);
}
extern inline
void WaitVRT()
{
while (inportb(InputStatusRegister1) & 8);
while (!(inportb(InputStatusRegister1) & 8));
}
#else
/*
Assembler stuff: It is normally more compact and in some cases faster. As
the functions are inline I think size is important.
They save 524 bytes in the driver (1.89%).
*/
extern inline
uchar ReadCRT(uchar index)
{
uchar a asm("%eax");
a=index;
asm volatile ("
outb %%al,%%dx
incl %%edx
inb %%dx,%%al
" : "a=" (a) : "a" (a), "d" (CRTController) : "%edx");
return a;
}
extern inline
uchar ReadGRA(uchar index)
{
uchar a asm("%eax");
a=index;
asm volatile ("
outb %%al,%%dx
incl %%edx
inb %%dx,%%al
" : "a=" (a) : "a" (a), "d" (GraphicsController) : "%edx");
return a;
}
extern inline
uchar ReadSEQ(uchar index)
{
uchar a asm("%eax");
a=index;
asm volatile ("
outb %%al,%%dx
incl %%edx
inb %%dx,%%al
" : "a=" (a) : "a" (a), "d" (Sequencer) : "%edx");
return a;
}
extern inline
void WriteCRT(uchar index, uchar value)
{
asm volatile ("
movb %0,%%ah
outw %%ax,%%dx
" : : "qi" (value), "a" (index), "d" (CRTController) : "%eax");
}
extern inline
void WriteGRA(uchar index, uchar value)
{
asm volatile ("
movb %0,%%ah
outw %%ax,%%dx
" : : "qi" (value), "a" (index), "d" (GraphicsController) : "%eax");
}
extern inline
void WriteSEQ(uchar index, uchar value)
{
asm volatile ("
movb %0,%%ah
outw %%ax,%%dx
" : : "qi" (value), "a" (index), "d" (Sequencer) : "%eax");
}
extern inline
void WaitVRT()
{
asm("
1:
inb %%dx,%%al
testb $8,%%al
jne 1b
.align 2,0x90
2:
inb %%dx,%%al
testb $8,%%al
je 2b
" : : "d" (InputStatusRegister1) : "%eax" );
}
#endif
extern inline
uchar ReadATT(int index)
{
/* Ensure we will write to the index */
inportb(ATTdir);
/* Set the index and disable the screen or we will read nothing */
outportb(ATTindex,index);
return inportb(ATTdataR);
}
extern inline
void ATTEndReads(void)
{
/* Ensure we will write to the index */
inportb(ATTdir);
/* Enable the screen */
outportb(ATTindex,0x20);
}
extern inline
void WriteATT(int index, int val)
{
outportb(ATTindex,index);
outportb(ATTdataW,val);
}
extern inline
uchar ReadMOR(void)
{
return inportb(MORdataR);
}
extern inline
void WriteMOR(int val)
{
outportb(MORdataW,val);
}
extern inline
uchar ReadEDAC(int index)
{
outportb(EDACindex,index);
return inportb(EDACdata);
}
extern inline
void WriteEDAC(int index, int val)
{
outportb(EDACindex,index);
outportb(EDACdata,val);
}
extern inline
void RPF_SetPalRange(unsigned char *_pal_ptr, int color, int cant)
{
__asm__("
outb %%al,%%dx
incl %%edx
cli
rep
outsb
sti"
: : "c" (cant*3), "S" (_pal_ptr), "a" (color), "d" (0x3C8)
: "%eax", "%ecx", "%edx", "%esi");
}

673
trident/driver.c Normal file
View File

@ -0,0 +1,673 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Trident driver (based on the Allegro Trident code).
*
* By Shawn Hargreaves and Mark Habersack.
*
* See freebe.txt for copyright information.
*/
// #define NO_HWPTR
#include <pc.h>
#include "vbeaf.h"
/* chipset information */
int chip_id = 0;
char *descriptions[] =
{
"TVGA 8900CL/D", "TVGA 9000i", "TVGA 9200CXr",
"TVGA LCD9100B", "TVGA GUI9420", "TVGA LX8200", "TVGA 9400CXi",
"TVGA LCD9320", "Unknown", "TVGA GUI9420", "TVGA GUI9660",
"TVGA GUI9440", "TVGA GUI9430", "TVGA 9000C"
};
#define TV_LAST 13
/* driver function prototypes */
void DualSetBank32();
void DualSetBank32End();
void DualSetBank(AF_DRIVER *af, long bank);
void SingleSetBank32();
void SingleSetBank32End();
void SingleSetBank(AF_DRIVER *af, long bank);
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
/* FreeBE/AF extension allowing farptr access to video memory */
FAF_HWPTR_DATA hwptr;
/* list of available video modes */
typedef struct VIDEO_MODE
{
int w, h;
int bpp;
int num;
} VIDEO_MODE;
VIDEO_MODE mode_list[] =
{
{ 640, 400, 8, 0x5C },
{ 640, 480, 8, 0x5D },
{ 800, 600, 8, 0x5E },
{ 1024, 768, 8, 0x62 }
};
#define NUM_MODES (int)(sizeof(mode_list)/sizeof(VIDEO_MODE))
short available_modes[NUM_MODES+1] = { 1, 2, 3, 4, -1 };
/* detect:
* Detects the presence of a Trident card.
*/
char *detect(unsigned long *vidmem)
{
int old1, old2, val;
char *name = NULL;
old1 = read_vga_register(0x3C4, 0x0B);
write_vga_register(0x3C4, 0x0B, 0); /* force old mode registers */
chip_id = inportb(0x3C5); /* now we have the ID */
old2 = read_vga_register(0x3C4, 0x0E);
outportb(0x3C4+1, old2^0x55);
val = inportb(0x3C5);
outportb(0x3C5, old2);
if (((val^old2) & 0x0F) == 7) { /* if bit 2 is inverted... */
outportb(0x3C5, old2^2); /* we're dealing with Trident */
if (chip_id <= 2) /* don't like 8800 chips */
return FALSE;
val = read_vga_register(0x3D4, 0x1F); /* determine the memory size */
switch (val & 3) {
case 0: *vidmem = 256; break;
case 1: *vidmem = 512; break;
case 2: *vidmem = 768; break;
case 3: if ((chip_id >= 0x33) && (val & 4))
*vidmem = 2048;
else
*vidmem = 1024;
break;
}
/* provide user with a description of the chip s/he has */
if ((chip_id == 0x33) && (read_vga_register(0x3D4, 0x28) & 0x80))
/* is it TVGA 9000C */
name = descriptions[TV_LAST];
else if (chip_id >= 0x33)
name = descriptions[((chip_id & 0xF0) >> 4) - 3];
else {
switch (chip_id) {
case 3: name = "TR 8900B"; break;
case 4: name = "TVGA 8900C"; break;
case 0x13: name = "TVGA 8900C"; break;
case 0x23: name = "TR 9000"; break;
default: name = "Unknown"; break;
}
}
return name;
}
write_vga_register(0x3C4, 0x0B, old1);
return NULL;
}
/* SetupDriver:
* Fills in our driver header block.
*/
int SetupDriver(AF_DRIVER *af)
{
char *name;
int i;
name = detect(&af->TotalMemory);
if (!name)
return 1;
i = 0;
while (af->OemVendorName[i])
i++;
af->OemVendorName[i++] = ',';
af->OemVendorName[i++] = ' ';
while (*name)
af->OemVendorName[i++] = *(name++);
af->OemVendorName[i] = 0;
af->AvailableModes = available_modes;
af->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
af->IOPortsTable = ports_table;
if (chip_id >= 0x33) {
af->SetBank = DualSetBank;
af->SetBank32 = DualSetBank32;
af->SetBank32Len = (long)DualSetBank32End - (long)DualSetBank32;
}
else {
af->SetBank = SingleSetBank;
af->SetBank32 = SingleSetBank32;
af->SetBank32Len = (long)SingleSetBank32End - (long)SingleSetBank32;
}
af->SupplementalExt = ExtStub;
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->SetPaletteData = SetPaletteData;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
*/
int InitDriver(AF_DRIVER *af)
{
hwptr_init(hwptr.IOMemMaps[0], af->IOMemMaps[0]);
hwptr_init(hwptr.IOMemMaps[1], af->IOMemMaps[1]);
hwptr_init(hwptr.IOMemMaps[2], af->IOMemMaps[2]);
hwptr_init(hwptr.IOMemMaps[3], af->IOMemMaps[3]);
hwptr_init(hwptr.BankedMem, af->BankedMem);
hwptr_init(hwptr.LinearMem, af->LinearMem);
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
#ifndef NO_HWPTR
case FAFEXT_HWPTR:
/* allow farptr access to video memory */
return &hwptr;
#endif
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
VIDEO_MODE *info;
int i;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
for (i=0; i<(int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
modeInfo->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
modeInfo->MaxBuffers = (af->TotalMemory*1024) /
(info->w*info->h*BYTES_PER_PIXEL(info->bpp));
if (info->w > 1024) {
modeInfo->MaxBytesPerScanLine = 2048*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 2048;
}
else {
modeInfo->MaxBytesPerScanLine = 1024*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 1024;
}
modeInfo->BytesPerScanLine = info->w*BYTES_PER_PIXEL(info->bpp);
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
modeInfo->MaxPixelClock = 135000000;
return 0;
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
long available_vram;
long used_vram;
int width;
VIDEO_MODE *info;
RM_REGS r;
/* reject anything with hardware stereo, linear framebuffer, or noclear */
if (mode & 0xC400)
return -1;
mode &= 0x3FF;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
/* call BIOS to set the mode */
r.x.ax = info->num;
rm_int(0x10, &r);
/* adjust the virtual width for widescreen modes */
if (virtualX > info->w) {
if (virtualX > 1024)
return -1;
*bytesPerLine = ((virtualX*BYTES_PER_PIXEL(info->bpp))+15)&0xFFF0;
width = read_vga_register(0x3D4, 0x13);
write_vga_register(0x3D4, 0x13, (width * (*bytesPerLine)) / (info->w*BYTES_PER_PIXEL(info->bpp)));
}
else
*bytesPerLine = info->w*BYTES_PER_PIXEL(info->bpp);
/* set up some hardware registers */
if (chip_id >= 0x33)
write_vga_register(0x3CE, 0x0F, 5); /* read/write banks */
else
read_vga_register(0x3C4, 0x0B); /* switch to new mode */
/* store info about the current mode */
af_bpp = info->bpp;
af_width = *bytesPerLine;
af_height = MAX(info->h, virtualY);
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
af_bank = -1;
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory*1024 ;
if (used_vram > available_vram)
return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
}
else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
if (waitVRT >= 0) {
long a = ((x * BYTES_PER_PIXEL(af_bpp)) + ((y + af_visible_page*af_height) * af_width)) >> 2;
asm volatile ("cli");
if (waitVRT) {
do {
} while (inportb(0x3DA) & 1);
}
/* first set the standard CRT Start registers */
outportw(0x3D4, (a & 0xFF00) | 0x0C);
outportw(0x3D4, ((a & 0x00FF) << 8) | 0x0D);
/* set bit 16 of the screen start address */
outportb(0x3D4, 0x1E);
outportb(0x3D5, (inportb(0x3D5) & 0xDF) | ((a & 0x10000) >> 11) );
/* bits 17-19 of the start address: uses the 8900CL/D+ register */
outportb(0x3D4, 0x27);
outportb(0x3D5, (inportb(0x3D5) & 0xF8) | ((a & 0xE0000) >> 17) );
/* set pel register */
if (waitVRT) {
do {
} while (!(inportb(0x3DA) & 8));
}
write_vga_register(0x3C0, 0x33, x&3);
asm volatile ("sti");
}
af_scroll_x = x;
af_scroll_y = y;
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* DualSetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _DualSetBank32, _DualSetBank32End
.align 4
_DualSetBank32:
pushl %edx
pushl %eax
movl %edx, %eax
movl $0x3D8, %edx
outb %al, %dx
incl %edx
outb %al, %dx
popl %eax
popl %edx
ret
_DualSetBank32End:
");
/* DualSetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable DualSetBank32() above.
*/
void DualSetBank(AF_DRIVER *af, long bank)
{
asm (
" call _DualSetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}
/* SingleSetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _SingleSetBank32, _SingleSetBank32End
.align 4
_SingleSetBank32:
pushl %edx
pushl %eax
movb %dl, %ah /* save bank into ah */
movl $0x3C4, %edx /* read port 3C4 register 0xE */
movb $0xE, %al
outb %al, %dx
incl %edx
inb %dx, %al
decl %edx
andb $0xF0, %al /* mask low four bits */
xorb $2, %ah /* xor bank number with 2 */
orb %al, %ah
movb $0xE, %al /* write to port 3C4 register 0xE */
outb %al, %dx
incl %edx
movb %ah, %al
outb %al, %dx
popl %eax
popl %edx
ret
_SingleSetBank32End:
");
/* SingleSetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable SingleSetBank32() above.
*/
void SingleSetBank(AF_DRIVER *af, long bank)
{
asm (
" call _SingleSetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}

45
trident/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Trident driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

28
trident/notes.txt Normal file
View File

@ -0,0 +1,28 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Trident driver implementation notes.
This is a software-only driver for Trident chipsets, based on the native
Trident driver from old versions of the Allegro library. It only supports
256 color modes, and has no support for linear framebuffers or
accelerated drawing. This code has been made obsolete by the accelerated
TGUI driver recently written by SET, and is included only because it may
support a slightly wider range of chipset variants. Any future
development effort should be spent on improving the TGUI driver instead
of this one.
This code is not portable to any platforms other than DOS+DPMI, because
it uses BIOS calls to set the initial video mode.
By Shawn Hargreaves (shawn@talula.demon.co.uk)
Support for newer chipsets by Mark Habersack (grendel@ananke.amu.edu.pl)

694
tseng/driver.c Normal file
View File

@ -0,0 +1,694 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Tseng driver (based on the Allegro Tseng code).
*
* By Shawn Hargreaves, Marco Campinoti, and Ben Chauveau.
*
* See freebe.txt for copyright information.
*/
// #define NO_HWPTR
#include <pc.h>
#include "vbeaf.h"
/* chipset information */
#define ET_NONE 0
#define ET_3000 1
#define ET_4000 2
#define ET_6000 3
int tseng_type = ET_NONE;
/* driver function prototypes */
void ET3000SetBank32();
void ET3000SetBank32End();
void ET3000SetBank(AF_DRIVER *af, long bank);
void ET4000SetBank32();
void ET4000SetBank32End();
void ET4000SetBank(AF_DRIVER *af, long bank);
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
/* FreeBE/AF extension allowing farptr access to video memory */
FAF_HWPTR_DATA hwptr;
/* list of available video modes */
typedef struct VIDEO_MODE
{
int w, h;
int bpp;
int num;
int bios;
} VIDEO_MODE;
VIDEO_MODE et3000_mode_list[] =
{
{ 640, 350, 8, 0x2D, 0 },
{ 640, 480, 8, 0x2E, 0 },
{ 800, 600, 8, 0x30, 0 }
};
VIDEO_MODE et4000_mode_list[] =
{
{ 640, 350, 8, 0x2D, 0 },
{ 640, 480, 8, 0x2E, 0 },
{ 640, 400, 8, 0x2F, 0 },
{ 800, 600, 8, 0x30, 0 },
{ 1024, 768, 8, 0x38, 0 },
{ 320, 200, 15, 0x13, 0x10F0 },
{ 640, 350, 15, 0x2D, 0x10F0 },
{ 640, 480, 15, 0x2E, 0x10F0 },
{ 640, 400, 15, 0x2F, 0x10F0 },
{ 800, 600, 15, 0x30, 0x10F0 },
{ 1024, 768, 15, 0x38, 0x10F0 },
{ 640, 350, 24, 0x2DFF, 0x10F0 },
{ 640, 480, 24, 0x2EFF, 0x10F0 },
{ 640, 400, 24, 0x2FFF, 0x10F0 },
{ 800, 600, 24, 0x30FF, 0x10F0 }
};
#define NUM_ET3000_MODES (int)(sizeof(et3000_mode_list)/sizeof(VIDEO_MODE))
#define NUM_ET4000_MODES (int)(sizeof(et4000_mode_list)/sizeof(VIDEO_MODE))
short available_et3000_modes[NUM_ET3000_MODES+1] = { 1, 2, 3, -1 };
short available_et4000_modes[NUM_ET4000_MODES+1] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, -1 };
/* detect:
* Detects the presence of a Tseng card.
*/
int detect()
{
int old1, old2, subver;
old1 = inportb(0x3BF);
old2 = inportb(0x3D4+4);
outportb(0x3BF, 3);
outportb(0x3D4+4, 0xA0);
if (test_register(0x3CD, 0x3F)) {
if (test_vga_register(0x3D4, 0x33, 0x0F)) {
if (test_register(0x3CB, 0x33)) {
subver = read_vga_register(0x217A, 0xEC) >> 4;
if (subver <= 11)
return ET_4000;
else if (subver == 15)
return ET_6000;
/* else unknown Tseng */
}
else
return ET_4000;
}
else
return ET_3000;
}
outportb(0x3BF, old1);
outportb(0x3D4+4, old2);
return ET_NONE;
}
/* SetupDriver:
* Fills in our driver header block.
*/
int SetupDriver(AF_DRIVER *af)
{
char *name = NULL;
int vram_size;
int i;
tseng_type = detect();
switch (tseng_type) {
case ET_3000:
name = "ET3000";
break;
case ET_4000:
name = "ET4000";
break;
case ET_6000:
name = "ET6000";
break;
default:
return 1;
}
i = 0;
while (af->OemVendorName[i])
i++;
af->OemVendorName[i++] = ',';
af->OemVendorName[i++] = ' ';
while (*name)
af->OemVendorName[i++] = *(name++);
af->OemVendorName[i] = 0;
if (get_vesa_info(&vram_size, NULL, NULL) != 0) {
if (tseng_type == ET_3000)
af->TotalMemory = 512;
else
af->TotalMemory = 1024;
}
else {
if (tseng_type == ET_3000)
af->TotalMemory = MIN(vram_size/1024, 512);
else
af->TotalMemory = MIN(vram_size/1024, 1024);
}
if (tseng_type == ET_3000) {
af->AvailableModes = available_et3000_modes;
af->SetBank32 = ET3000SetBank32;
af->SetBank32Len = (long)ET3000SetBank32End - (long)ET3000SetBank32;
af->SetBank = ET3000SetBank;
}
else {
af->AvailableModes = available_et4000_modes;
af->SetBank32 = ET4000SetBank32;
af->SetBank32Len = (long)ET4000SetBank32End - (long)ET4000SetBank32;
af->SetBank = ET4000SetBank;
}
af->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
af->IOPortsTable = ports_table;
af->SupplementalExt = ExtStub;
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->SetPaletteData = SetPaletteData;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
*/
int InitDriver(AF_DRIVER *af)
{
hwptr_init(hwptr.IOMemMaps[0], af->IOMemMaps[0]);
hwptr_init(hwptr.IOMemMaps[1], af->IOMemMaps[1]);
hwptr_init(hwptr.IOMemMaps[2], af->IOMemMaps[2]);
hwptr_init(hwptr.IOMemMaps[3], af->IOMemMaps[3]);
hwptr_init(hwptr.BankedMem, af->BankedMem);
hwptr_init(hwptr.LinearMem, af->LinearMem);
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
#ifndef NO_HWPTR
case FAFEXT_HWPTR:
/* allow farptr access to video memory */
return &hwptr;
#endif
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
VIDEO_MODE *info;
int i;
if ((mode <= 0) || (mode > ((tseng_type == ET_3000) ? NUM_ET3000_MODES : NUM_ET4000_MODES)))
return -1;
if (tseng_type == ET_3000)
info = &et3000_mode_list[mode-1];
else
info = &et4000_mode_list[mode-1];
for (i=0; i<(int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
modeInfo->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
modeInfo->MaxBuffers = (af->TotalMemory*1024) /
(info->w*info->h*BYTES_PER_PIXEL(info->bpp));
if (info->w > 1024) {
modeInfo->MaxBytesPerScanLine = 2048*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 2048;
}
else {
modeInfo->MaxBytesPerScanLine = 1024*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 1024;
}
modeInfo->BytesPerScanLine = info->w*BYTES_PER_PIXEL(info->bpp);
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
modeInfo->MaxPixelClock = 135000000;
return 0;
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
long available_vram;
long used_vram;
int width;
VIDEO_MODE *info;
RM_REGS r;
/* reject anything with hardware stereo, linear framebuffer, or noclear */
if (mode & 0xC400)
return -1;
mode &= 0x3FF;
if ((mode <= 0) || (mode > ((tseng_type == ET_3000) ? NUM_ET3000_MODES : NUM_ET4000_MODES)))
return -1;
if (tseng_type == ET_3000)
info = &et3000_mode_list[mode-1];
else
info = &et4000_mode_list[mode-1];
/* call BIOS to set the mode */
if (info->bios) {
r.x.ax = info->bios;
r.x.bx = info->num;
}
else
r.x.ax = info->num;
rm_int(0x10, &r);
/* adjust the virtual width for widescreen modes */
if (virtualX > info->w) {
if (virtualX > 1024)
return -1;
*bytesPerLine = ((virtualX*BYTES_PER_PIXEL(info->bpp))+15)&0xFFF0;
width = read_vga_register(0x3D4, 0x13);
write_vga_register(0x3D4, 0x13, (width * (*bytesPerLine)) / (info->w*BYTES_PER_PIXEL(info->bpp)));
}
else
*bytesPerLine = info->w*BYTES_PER_PIXEL(info->bpp);
/* store info about the current mode */
af_bpp = info->bpp;
af_width = *bytesPerLine;
af_height = MAX(info->h, virtualY);
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
af_bank = -1;
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory*1024 ;
if (used_vram > available_vram)
return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
}
else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
if (waitVRT >= 0) {
long a = (x * BYTES_PER_PIXEL(af_bpp)) + ((y + af_visible_page*af_height) * af_width);
asm volatile ("cli");
if (waitVRT) {
do {
} while (inportb(0x3DA) & 1);
}
/* write high bit(s) to Tseng-specific registers */
if (tseng_type == ET_3000)
alter_vga_register(0x3D4, 0x23, 2, a>>17);
else if (tseng_type == ET_4000)
alter_vga_register(0x3D4, 0x33, 3, a>>18);
else if (tseng_type == ET_6000)
alter_vga_register(0x3D4, 0x33, 3, a>>17);
/* write to normal VGA address registers */
write_vga_register(0x3D4, 0x0D, (a>>2) & 0xFF);
write_vga_register(0x3D4, 0x0C, (a>>10) & 0xFF);
asm volatile ("sti");
if (waitVRT) {
do {
} while (!(inportb(0x3DA) & 8));
}
/* write low 2 bits to VGA horizontal pan register */
if (af_bpp == 8)
write_vga_register(0x3C0, 0x33, a&3);
}
af_scroll_x = x;
af_scroll_y = y;
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* ET3000SetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _ET3000SetBank32, _ET3000SetBank32End
.align 4
_ET3000SetBank32:
pushl %edx
pushl %eax
movb %dl, %al /* mask read and write banks together */
shlb $3, %al
orb %dl, %al
orb $0x40, %al /* select 64k segments */
movl $0x3CD, %edx
outb %al, %dx /* write to the card */
popl %eax
popl %edx
ret
_ET3000SetBank32End:
");
/* ET3000SetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable ET3000SetBank32() above.
*/
void ET3000SetBank(AF_DRIVER *af, long bank)
{
asm (
" call _ET3000SetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}
/* ET4000SetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _ET4000SetBank32, _ET4000SetBank32End
.align 4
_ET4000SetBank32:
pushl %edx
pushl %eax
movb %dl, %al /* mask read and write banks together */
shlb $4, %al
orb %dl, %al
movl $0x3CD, %edx
outb %al, %dx /* write to the card */
popl %eax
popl %edx
ret
_ET4000SetBank32End:
");
/* ET4000SetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable ET4000SetBank32() above.
*/
void ET4000SetBank(AF_DRIVER *af, long bank)
{
asm (
" call _ET4000SetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}

45
tseng/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Tseng driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

30
tseng/notes.txt Normal file
View File

@ -0,0 +1,30 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Tseng driver implementation notes.
This is a software-only driver for the Tseng ET3000, ET4000, and ET6000
chipsets, based on the native Tseng drivers from old versions of the
Allegro library. It has no support for linear framebuffers or accelerated
drawing operations. As such it is useful primarily because it is faster
than the VESA 1.x bank switching mechanism, and as a workaround for the
many bugs in common VESA driver implementations.
This code is not portable to any platforms other than DOS+DPMI, because
it uses BIOS calls to set the initial video mode.
Any volunteers to add hardware accelerator support? That would be very
welcome if you want to do it :-)
By Shawn Hargreaves (shawn@talula.demon.co.uk)
Truecolor support added by Marco Campinoti (marco@etruscan.li.it)
ET6000 support contributed by Ben Chauveau (bendomc@worldnet.fr)

813
vbeaf.h Normal file
View File

@ -0,0 +1,813 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF structure definitions and constants.
*
* See freebe.txt for copyright information.
*/
#define FREEBE_VERSION "v1.2"
#ifndef ALLEGRO_H
#include <pc.h>
#define NULL 0
#define TRUE 1
#define FALSE 0
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#define MID(x,y,z) MAX((x), MIN((y), (z)))
#define ABS(x) (((x) >= 0) ? (x) : (-(x)))
#define BYTES_PER_PIXEL(bpp) (((int)(bpp) + 7) / 8)
typedef long fixed;
#endif
/* mode attribute flags */
#define afHaveMultiBuffer 0x0001 /* multiple buffers */
#define afHaveVirtualScroll 0x0002 /* virtual scrolling */
#define afHaveBankedBuffer 0x0004 /* supports banked framebuffer */
#define afHaveLinearBuffer 0x0008 /* supports linear framebuffer */
#define afHaveAccel2D 0x0010 /* supports 2D acceleration */
#define afHaveDualBuffers 0x0020 /* uses dual buffers */
#define afHaveHWCursor 0x0040 /* supports a hardware cursor */
#define afHave8BitDAC 0x0080 /* 8 bit palette DAC */
#define afNonVGAMode 0x0100 /* not a VGA mode */
#define afHaveDoubleScan 0x0200 /* supports double scanning */
#define afHaveInterlaced 0x0400 /* supports interlacing */
#define afHaveTripleBuffer 0x0800 /* supports triple buffering */
#define afHaveStereo 0x1000 /* supports stereo LCD glasses */
#define afHaveROP2 0x2000 /* supports ROP2 mix codes */
#define afHaveHWStereoSync 0x4000 /* hardware stereo signalling */
#define afHaveEVCStereoSync 0x8000 /* HW stereo sync via EVC connector */
/* drawing modes */
typedef enum
{
AF_FORE_MIX = 0, /* background pixels use the foreground mix */
AF_REPLACE_MIX = 0, /* solid drawing mode */
AF_AND_MIX, /* bitwise AND mode */
AF_OR_MIX, /* bitwise OR mode */
AF_XOR_MIX, /* bitwise XOR mode */
AF_NOP_MIX, /* nothing is drawn */
/* below here need only be supported if you set the afHaveROP2 flag */
AF_R2_BLACK = 0x10,
AF_R2_NOTMERGESRC,
AF_R2_MASKNOTSRC,
AF_R2_NOTCOPYSRC,
AF_R2_MASKSRCNOT,
AF_R2_NOT,
AF_R2_XORSRC,
AF_R2_NOTMASKSRC,
AF_R2_MASKSRC,
AF_R2_NOTXORSRC,
AF_R2_NOP,
AF_R2_MERGENOTSRC,
AF_R2_COPYSRC,
AF_R2_MERGESRCNOT,
AF_R2_MERGESRC,
AF_R2_WHITE,
} AF_mixModes;
/* fixed point coordinate pair */
typedef struct AF_FIX_POINT
{
fixed x;
fixed y;
} AF_FIX_POINT;
/* trapezium information block */
typedef struct AF_TRAP
{
unsigned long y;
unsigned long count;
fixed x1;
fixed x2;
fixed slope1;
fixed slope2;
} AF_TRAP;
/* hardware cursor description */
typedef struct AF_CURSOR
{
unsigned long xorMask[32];
unsigned long andMask[32];
unsigned long hotx;
unsigned long hoty;
} AF_CURSOR;
/* color value */
typedef struct AF_PALETTE
{
unsigned char blue;
unsigned char green;
unsigned char red;
unsigned char alpha;
} AF_PALETTE;
/* CRTC information block for refresh rate control */
typedef struct AF_CRTCInfo
{
unsigned short HorizontalTotal __attribute__ ((packed)); /* horizontal total (pixels) */
unsigned short HorizontalSyncStart __attribute__ ((packed)); /* horizontal sync start position */
unsigned short HorizontalSyncEnd __attribute__ ((packed)); /* horizontal sync end position */
unsigned short VerticalTotal __attribute__ ((packed)); /* vertical total (lines) */
unsigned short VerticalSyncStart __attribute__ ((packed)); /* vertical sync start position */
unsigned short VerticalSyncEnd __attribute__ ((packed)); /* vertical sync end position */
unsigned char Flags __attribute__ ((packed)); /* initialisation flags for mode */
unsigned int PixelClock __attribute__ ((packed)); /* pixel clock in units of Hz */
unsigned short RefreshRate __attribute__ ((packed)); /* expected refresh rate in .01Hz */
unsigned short NumBuffers __attribute__ ((packed)); /* number of display buffers */
} AF_CRTCInfo;
/* definitions for CRTC information block flags */
#define afDoubleScan 0x0001 /* enable double scanned mode */
#define afInterlaced 0x0002 /* enable interlaced mode */
#define afHSyncNeg 0x0004 /* horizontal sync is negative */
#define afVSyncNeg 0x0008 /* vertical sync is negative */
typedef unsigned char AF_PATTERN; /* pattern array elements */
typedef unsigned AF_STIPPLE; /* 16 bit line stipple pattern */
typedef unsigned AF_COLOR; /* packed color values */
/* mode information structure */
typedef struct AF_MODE_INFO
{
unsigned short Attributes __attribute__ ((packed));
unsigned short XResolution __attribute__ ((packed));
unsigned short YResolution __attribute__ ((packed));
unsigned short BytesPerScanLine __attribute__ ((packed));
unsigned short BitsPerPixel __attribute__ ((packed));
unsigned short MaxBuffers __attribute__ ((packed));
unsigned char RedMaskSize __attribute__ ((packed));
unsigned char RedFieldPosition __attribute__ ((packed));
unsigned char GreenMaskSize __attribute__ ((packed));
unsigned char GreenFieldPosition __attribute__ ((packed));
unsigned char BlueMaskSize __attribute__ ((packed));
unsigned char BlueFieldPosition __attribute__ ((packed));
unsigned char RsvdMaskSize __attribute__ ((packed));
unsigned char RsvdFieldPosition __attribute__ ((packed));
unsigned short MaxBytesPerScanLine __attribute__ ((packed));
unsigned short MaxScanLineWidth __attribute__ ((packed));
/* VBE/AF 2.0 extensions */
unsigned short LinBytesPerScanLine __attribute__ ((packed));
unsigned char BnkMaxBuffers __attribute__ ((packed));
unsigned char LinMaxBuffers __attribute__ ((packed));
unsigned char LinRedMaskSize __attribute__ ((packed));
unsigned char LinRedFieldPosition __attribute__ ((packed));
unsigned char LinGreenMaskSize __attribute__ ((packed));
unsigned char LinGreenFieldPosition __attribute__ ((packed));
unsigned char LinBlueMaskSize __attribute__ ((packed));
unsigned char LinBlueFieldPosition __attribute__ ((packed));
unsigned char LinRsvdMaskSize __attribute__ ((packed));
unsigned char LinRsvdFieldPosition __attribute__ ((packed));
unsigned long MaxPixelClock __attribute__ ((packed));
unsigned long VideoCapabilities __attribute__ ((packed));
unsigned short VideoMinXScale __attribute__ ((packed));
unsigned short VideoMinYScale __attribute__ ((packed));
unsigned short VideoMaxXScale __attribute__ ((packed));
unsigned short VideoMaxYScale __attribute__ ((packed));
unsigned char reserved[76] __attribute__ ((packed));
} AF_MODE_INFO;
#define DC struct AF_DRIVER *dc
/* main VBE/AF driver structure */
typedef struct AF_DRIVER
{
/* header */
char Signature[12] __attribute__ ((packed));
unsigned long Version __attribute__ ((packed));
unsigned long DriverRev __attribute__ ((packed));
char OemVendorName[80] __attribute__ ((packed));
char OemCopyright[80] __attribute__ ((packed));
short *AvailableModes __attribute__ ((packed));
unsigned long TotalMemory __attribute__ ((packed));
unsigned long Attributes __attribute__ ((packed));
unsigned long BankSize __attribute__ ((packed));
unsigned long BankedBasePtr __attribute__ ((packed));
unsigned long LinearSize __attribute__ ((packed));
unsigned long LinearBasePtr __attribute__ ((packed));
unsigned long LinearGranularity __attribute__ ((packed));
unsigned short *IOPortsTable __attribute__ ((packed));
unsigned long IOMemoryBase[4] __attribute__ ((packed));
unsigned long IOMemoryLen[4] __attribute__ ((packed));
unsigned long LinearStridePad __attribute__ ((packed));
unsigned short PCIVendorID __attribute__ ((packed));
unsigned short PCIDeviceID __attribute__ ((packed));
unsigned short PCISubSysVendorID __attribute__ ((packed));
unsigned short PCISubSysID __attribute__ ((packed));
unsigned long Checksum __attribute__ ((packed));
unsigned long res2[6] __attribute__ ((packed));
/* near pointers mapped by the application */
void *IOMemMaps[4] __attribute__ ((packed));
void *BankedMem __attribute__ ((packed));
void *LinearMem __attribute__ ((packed));
unsigned long res3[5] __attribute__ ((packed));
/* driver state variables */
unsigned long BufferEndX __attribute__ ((packed));
unsigned long BufferEndY __attribute__ ((packed));
unsigned long OriginOffset __attribute__ ((packed));
unsigned long OffscreenOffset __attribute__ ((packed));
unsigned long OffscreenStartY __attribute__ ((packed));
unsigned long OffscreenEndY __attribute__ ((packed));
unsigned long res4[10] __attribute__ ((packed));
/* relocatable 32 bit bank switch routine, for Windows (ugh!) */
unsigned long SetBank32Len __attribute__ ((packed));
void *SetBank32 __attribute__ ((packed));
/* callback functions provided by the application */
void *Int86 __attribute__ ((packed));
void *CallRealMode __attribute__ ((packed));
/* main driver setup routine */
void *InitDriver __attribute__ ((packed));
/* VBE/AF 1.0 asm interface (obsolete and not supported by Allegro) */
void *af10Funcs[40] __attribute__ ((packed));
/* VBE/AF 2.0 extensions */
void *PlugAndPlayInit __attribute__ ((packed));
/* extension query function, specific to FreeBE/AF */
void *(*OemExt)(DC, unsigned long id);
/* extension hook for implementing additional VESA interfaces */
void *SupplementalExt __attribute__ ((packed));
/* device driver functions */
long (*GetVideoModeInfo)(DC, short mode, AF_MODE_INFO *modeInfo);
long (*SetVideoMode)(DC, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void (*RestoreTextMode)(DC);
long (*GetClosestPixelClock)(DC, short mode, unsigned long pixelClock);
void (*SaveRestoreState)(DC, int subfunc, void *saveBuf);
void (*SetDisplayStart)(DC, long x, long y, long waitVRT);
void (*SetActiveBuffer)(DC, long index);
void (*SetVisibleBuffer)(DC, long index, long waitVRT);
int (*GetDisplayStartStatus)(DC);
void (*EnableStereoMode)(DC, int enable);
void (*SetPaletteData)(DC, AF_PALETTE *pal, long num, long index, long waitVRT);
void (*SetGammaCorrectData)(DC, AF_PALETTE *pal, long num, long index);
void (*SetBank)(DC, long bank);
/* hardware cursor functions */
void (*SetCursor)(DC, AF_CURSOR *cursor);
void (*SetCursorPos)(DC, long x, long y);
void (*SetCursorColor)(DC, unsigned char red, unsigned char green, unsigned char blue);
void (*ShowCursor)(DC, long visible);
/* 2D rendering functions */
void (*WaitTillIdle)(DC);
void (*EnableDirectAccess)(DC);
void (*DisableDirectAccess)(DC);
void (*SetMix)(DC, long foreMix, long backMix);
void (*Set8x8MonoPattern)(DC, unsigned char *pattern);
void (*Set8x8ColorPattern)(DC, int index, unsigned long *pattern);
void (*Use8x8ColorPattern)(DC, int index);
void (*SetLineStipple)(DC, unsigned short stipple);
void (*SetLineStippleCount)(DC, unsigned long count);
void (*SetClipRect)(DC, long minx, long miny, long maxx, long maxy);
void (*DrawScan)(DC, long color, long y, long x1, long x2);
void (*DrawPattScan)(DC, long foreColor, long backColor, long y, long x1, long x2);
void (*DrawColorPattScan)(DC, long y, long x1, long x2);
void (*DrawScanList)(DC, unsigned long color, long y, long length, short *scans);
void (*DrawPattScanList)(DC, unsigned long foreColor, unsigned long backColor, long y, long length, short *scans);
void (*DrawColorPattScanList)(DC, long y, long length, short *scans);
void (*DrawRect)(DC, unsigned long color, long left, long top, long width, long height);
void (*DrawPattRect)(DC, unsigned long foreColor, unsigned long backColor, long left, long top, long width, long height);
void (*DrawColorPattRect)(DC, long left, long top, long width, long height);
void (*DrawLine)(DC, unsigned long color, fixed x1, fixed y1, fixed x2, fixed y2);
void (*DrawStippleLine)(DC, unsigned long foreColor, unsigned long backColor, fixed x1, fixed y1, fixed x2, fixed y2);
void (*DrawTrap)(DC, unsigned long color, AF_TRAP *trap);
void (*DrawTri)(DC, unsigned long color, AF_FIX_POINT *v1, AF_FIX_POINT *v2, AF_FIX_POINT *v3, fixed xOffset, fixed yOffset);
void (*DrawQuad)(DC, unsigned long color, AF_FIX_POINT *v1, AF_FIX_POINT *v2, AF_FIX_POINT *v3, AF_FIX_POINT *v4, fixed xOffset, fixed yOffset);
void (*PutMonoImage)(DC, long foreColor, long backColor, long dstX, long dstY, long byteWidth, long srcX, long srcY, long width, long height, unsigned char *image);
void (*PutMonoImageLin)(DC, long foreColor, long backColor, long dstX, long dstY, long byteWidth, long srcX, long srcY, long width, long height, long imageOfs);
void (*PutMonoImageBM)(DC, long foreColor, long backColor, long dstX, long dstY, long byteWidth, long srcX, long srcY, long width, long height, long imagePhysAddr);
void (*BitBlt)(DC, long left, long top, long width, long height, long dstLeft, long dstTop, long op);
void (*BitBltSys)(DC, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op);
void (*BitBltLin)(DC, long srcOfs, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op);
void (*BitBltBM)(DC, long srcPhysAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op);
void (*SrcTransBlt)(DC, long left, long top, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*SrcTransBltSys)(DC, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*SrcTransBltLin)(DC, long srcOfs, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*SrcTransBltBM)(DC, long srcPhysAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*DstTransBlt)(DC, long left, long top, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*DstTransBltSys)(DC, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*DstTransBltLin)(DC, long srcOfs, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*DstTransBltBM)(DC, long srcPhysAddr, long srcPitch, long srcLeft, long srcTop, long width, long height, long dstLeft, long dstTop, long op, unsigned long transparent);
void (*StretchBlt)(DC, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op);
void (*StretchBltSys)(DC, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op);
void (*StretchBltLin)(DC, long srcOfs, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op);
void (*StretchBltBM)(DC, long srcPhysAddr, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op);
void (*SrcTransStretchBlt)(DC, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*SrcTransStretchBltSys)(DC, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*SrcTransStretchBltLin)(DC, long srcOfs, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*SrcTransStretchBltBM)(DC, long srcPhysAddr, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*DstTransStretchBlt)(DC, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*DstTransStretchBltSys)(DC, void *srcAddr, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*DstTransStretchBltLin)(DC, long srcOfs, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
void (*DstTransStretchBltBM)(DC, long srcPhysAddr, long srcPitch, long srcLeft, long srcTop, long srcWidth, long srcHeight, long dstLeft, long dstTop, long dstWidth, long dstHeight, long flags, long op, unsigned long transparent);
/* hardware video functions */
void (*SetVideoInput)(DC, long width, long height, long format);
void *(*SetVideoOutput)(DC, long left, long top, long width, long height);
void (*StartVideoFrame)(DC);
void (*EndVideoFrame)(DC);
} AF_DRIVER;
#undef DC
/* register data for calling real mode interrupts (DPMI format) */
typedef union
{
struct {
unsigned long edi;
unsigned long esi;
unsigned long ebp;
unsigned long res;
unsigned long ebx;
unsigned long edx;
unsigned long ecx;
unsigned long eax;
} d;
struct {
unsigned short di, di_hi;
unsigned short si, si_hi;
unsigned short bp, bp_hi;
unsigned short res, res_hi;
unsigned short bx, bx_hi;
unsigned short dx, dx_hi;
unsigned short cx, cx_hi;
unsigned short ax, ax_hi;
unsigned short flags;
unsigned short es;
unsigned short ds;
unsigned short fs;
unsigned short gs;
unsigned short ip;
unsigned short cs;
unsigned short sp;
unsigned short ss;
} x;
struct {
unsigned char edi[4];
unsigned char esi[4];
unsigned char ebp[4];
unsigned char res[4];
unsigned char bl, bh, ebx_b2, ebx_b3;
unsigned char dl, dh, edx_b2, edx_b3;
unsigned char cl, ch, ecx_b2, ecx_b3;
unsigned char al, ah, eax_b2, eax_b3;
} h;
} RM_REGS;
/* our API extensions use 32 bit magic numbers */
#define FAF_ID(a,b,c,d) ((a<<24) | (b<<16) | (c<<8) | d)
/* ID code and magic return value for initialising the extensions */
#define FAFEXT_INIT FAF_ID('I','N','I','T')
#define FAFEXT_MAGIC FAF_ID('E','X', 0, 0)
#define FAFEXT_MAGIC1 FAF_ID('E','X','0','1')
/* extension providing a hardware-specific way to access video memory */
#define FAFEXT_HWPTR FAF_ID('H','P','T','R')
#if (defined __i386__) && (!defined NO_HWPTR)
/* use seg+offset far pointers on i386 */
typedef struct FAF_HWPTR
{
int sel;
unsigned long offset;
} FAF_HWPTR;
#include <sys/farptr.h>
#include <sys/segments.h>
#define hwptr_init(ptr, addr) \
if ((addr) && (!(ptr).sel)) { \
(ptr).sel = _my_ds(); \
(ptr).offset = (unsigned long)(addr); \
}
#define hwptr_pokeb(ptr, off, val) _farpokeb((ptr).sel, (ptr).offset+(off), (val))
#define hwptr_pokew(ptr, off, val) _farpokew((ptr).sel, (ptr).offset+(off), (val))
#define hwptr_pokel(ptr, off, val) _farpokel((ptr).sel, (ptr).offset+(off), (val))
#define hwptr_peekb(ptr, off) _farpeekb((ptr).sel, (ptr).offset+(off))
#define hwptr_peekw(ptr, off) _farpeekw((ptr).sel, (ptr).offset+(off))
#define hwptr_peekl(ptr, off) _farpeekl((ptr).sel, (ptr).offset+(off))
#define hwptr_select(ptr) _farsetsel((ptr).sel)
#define hwptr_unselect(ptr) (ptr).sel = _fargetsel()
#define hwptr_nspokeb(ptr, off, val) _farnspokeb((ptr).offset+(off), (val))
#define hwptr_nspokew(ptr, off, val) _farnspokew((ptr).offset+(off), (val))
#define hwptr_nspokel(ptr, off, val) _farnspokel((ptr).offset+(off), (val))
#define hwptr_nspeekb(ptr, off) _farnspeekb((ptr).offset+(off))
#define hwptr_nspeekw(ptr, off) _farnspeekw((ptr).offset+(off))
#define hwptr_nspeekl(ptr, off) _farnspeekl((ptr).offset+(off))
#else
/* use regular C pointers on other platforms or if hwptr is disabled */
typedef void *FAF_HWPTR;
#define hwptr_init(ptr, addr) ptr = (FAF_HWPTR)(addr)
#define hwptr_pokeb(ptr, off, val) *((volatile unsigned char *)((ptr)+(off))) = (val)
#define hwptr_pokew(ptr, off, val) *((volatile unsigned short *)((ptr)+(off))) = (val)
#define hwptr_pokel(ptr, off, val) *((volatile unsigned long *)((ptr)+(off))) = (val)
#define hwptr_peekb(ptr, off) (*((volatile unsigned char *)((ptr)+(off))))
#define hwptr_peekw(ptr, off) (*((volatile unsigned short *)((ptr)+(off))))
#define hwptr_peekl(ptr, off) (*((volatile unsigned long *)((ptr)+(off))))
#define hwptr_select(ptr)
#define hwptr_unselect(ptr) (ptr) = NULL
#define hwptr_nspokeb(ptr, off, val) *((volatile unsigned char *)((ptr)+(off))) = (val)
#define hwptr_nspokew(ptr, off, val) *((volatile unsigned short *)((ptr)+(off))) = (val)
#define hwptr_nspokel(ptr, off, val) *((volatile unsigned long *)((ptr)+(off))) = (val)
#define hwptr_nspeekb(ptr, off) (*((volatile unsigned char *)((ptr)+(off))))
#define hwptr_nspeekw(ptr, off) (*((volatile unsigned short *)((ptr)+(off))))
#define hwptr_nspeekl(ptr, off) (*((volatile unsigned long *)((ptr)+(off))))
#endif /* hwptr structure definitions */
/* interface structure containing hardware pointer data */
typedef struct FAF_HWPTR_DATA
{
FAF_HWPTR IOMemMaps[4];
FAF_HWPTR BankedMem;
FAF_HWPTR LinearMem;
} FAF_HWPTR_DATA;
/* extension providing a way for the config program to set driver variables */
#define FAFEXT_CONFIG FAF_ID('C','O','N','F')
/* config variable, so the install program can communicate with the driver */
typedef struct FAF_CONFIG_DATA
{
unsigned long id;
unsigned long value;
} FAF_CONFIG_DATA;
/* config variable ID used to enable/disable specific hardware functions */
#define FAF_CFG_FEATURES FAF_ID('F','E','A','T')
/* bitfield values for the FAF_CFG_FEATURES variable */
#define fafLinear 0x00000001
#define fafBanked 0x00000002
#define fafHWCursor 0x00000004
#define fafDrawScan 0x00000008
#define fafDrawPattScan 0x00000010
#define fafDrawColorPattScan 0x00000020
#define fafDrawScanList 0x00000040
#define fafDrawPattScanList 0x00000080
#define fafDrawColorPattScanList 0x00000100
#define fafDrawRect 0x00000200
#define fafDrawPattRect 0x00000400
#define fafDrawColorPattRect 0x00000800
#define fafDrawLine 0x00001000
#define fafDrawStippleLine 0x00002000
#define fafDrawTrap 0x00004000
#define fafDrawTri 0x00008000
#define fafDrawQuad 0x00010000
#define fafPutMonoImage 0x00020000
#define fafPutMonoImageLin 0x00040000
#define fafPutMonoImageBM 0x00080000
#define fafBitBlt 0x00100000
#define fafBitBltSys 0x00200000
#define fafBitBltLin 0x00400000
#define fafBitBltBM 0x00800000
#define fafSrcTransBlt 0x01000000
#define fafSrcTransBltSys 0x02000000
#define fafSrcTransBltLin 0x04000000
#define fafSrcTransBltBM 0x08000000
/* helper function for enabling/disabling driver routines */
void fixup_feature_list(AF_DRIVER *af, unsigned long flags);
/* extension providing libc exports (needed for Nucleus compatibility) */
#define FAFEXT_LIBC FAF_ID('L','I','B','C')
typedef struct FAF_LIBC_DATA
{
long size;
void (*abort)();
void *(*calloc)(unsigned long num_elements, unsigned long size);
void (*exit)(int status);
void (*free)(void *ptr);
char *(*getenv)(const char *name);
void *(*malloc)(unsigned long size);
void *(*realloc)(void *ptr, unsigned long size);
int (*system)(const char *s);
int (*putenv)(const char *val);
int (*open)(const char *file, int mode, int permissions);
int (*access)(const char *filename, int flags);
int (*close)(int fd);
int (*lseek)(int fd, int offset, int whence);
int (*read)(int fd, void *buffer, unsigned long count);
int (*unlink)(const char *file);
int (*write)(int fd, const void *buffer, unsigned long count);
int (*isatty)(int fd);
int (*remove)(const char *file);
int (*rename)(const char *oldname, const char *newname);
unsigned int (*time)(unsigned int *t);
void (*setfileattr)(const char *filename, unsigned attrib);
unsigned long (*getcurrentdate)();
} FAF_LIBC_DATA;
/* extension providing pmode exports (needed for Nucleus compatibility) */
#define FAFEXT_PMODE FAF_ID('P','M','O','D')
/* It has to be said, having this many exported functions is truly insane.
* How on earth can SciTech need this much crap just to write a simple
* video driver? Unfortunately we have to include it all in order to
* support their Nucleus drivers...
*/
typedef union
{
struct {
unsigned long eax, ebx, ecx, edx, esi, edi, cflag;
} e;
struct {
unsigned short ax, ax_hi;
unsigned short bx, bx_hi;
unsigned short cx, cx_hi;
unsigned short dx, dx_hi;
unsigned short si, si_hi;
unsigned short di, di_hi;
unsigned short cflag, cflag_hi;
} x;
struct {
unsigned char al, ah; unsigned short ax_hi;
unsigned char bl, bh; unsigned short bx_hi;
unsigned char cl, ch; unsigned short cx_hi;
unsigned char dl, dh; unsigned short dx_hi;
} h;
} SILLY_SCITECH_REGS;
typedef struct
{
unsigned short es, cs, ss, ds, fs, gs;
} SILLY_SCITECH_SREGS;
typedef struct FAF_PMODE_DATA
{
long size;
int (*getModeType)();
void *(*getBIOSPointer)();
void *(*getA0000Pointer)();
void *(*mapPhysicalAddr)(unsigned long base, unsigned long limit);
void *(*mallocShared)(long size);
int (*mapShared)(void *ptr);
void (*freeShared)(void *ptr);
void *(*mapToProcess)(void *linear, unsigned long limit);
void (*loadDS)();
void (*saveDS)();
void *(*mapRealPointer)(unsigned int r_seg, unsigned int r_off);
void *(*allocRealSeg)(unsigned int size, unsigned int *r_seg, unsigned int *r_off);
void (*freeRealSeg)(void *mem);
void *(*allocLockedMem)(unsigned int size, unsigned long *physAddr);
void (*freeLockedMem)(void *p);
void (*callRealMode)(unsigned int seg, unsigned int off, SILLY_SCITECH_REGS *regs, SILLY_SCITECH_SREGS *sregs);
int (*int86)(int intno, SILLY_SCITECH_REGS *in, SILLY_SCITECH_REGS *out);
int (*int86x)(int intno, SILLY_SCITECH_REGS *in, SILLY_SCITECH_REGS *out, SILLY_SCITECH_SREGS *sregs);
void (*DPMI_int86)(int intno, RM_REGS *regs);
void (*segread)(SILLY_SCITECH_SREGS *sregs);
int (*int386)(int intno, SILLY_SCITECH_REGS *in, SILLY_SCITECH_REGS *out);
int (*int386x)(int intno, SILLY_SCITECH_REGS *in, SILLY_SCITECH_REGS *out, SILLY_SCITECH_SREGS *sregs);
void (*availableMemory)(unsigned long *physical, unsigned long *total);
void *(*getVESABuf)(unsigned int *len, unsigned int *rseg, unsigned int *roff);
long (*getOSType)();
void (*fatalError)(const char *msg);
void (*setBankA)(int bank);
void (*setBankAB)(int bank);
const char *(*getCurrentPath)();
const char *(*getVBEAFPath)();
const char *(*getNucleusPath)();
const char *(*getNucleusConfigPath)();
const char *(*getUniqueID)();
const char *(*getMachineName)();
int (*VF_available)();
void *(*VF_init)(unsigned long baseAddr, int bankSize, int codeLen, void *bankFunc);
void (*VF_exit)();
int (*kbhit)();
int (*getch)();
int (*openConsole)();
int (*getConsoleStateSize)();
void (*saveConsoleState)(void *stateBuf, int console_id);
void (*restoreConsoleState)(const void *stateBuf, int console_id);
void (*closeConsole)(int console_id);
void (*setOSCursorLocation)(int x, int y);
void (*setOSScreenWidth)(int width, int height);
int (*enableWriteCombine)(unsigned long base, unsigned long length);
void (*backslash)(char *filename);
} FAF_PMODE_DATA;
/* assorted helper functions */
void trace_putc(char c);
void trace_printf(char *msg, ...);
void rm_int(int num, RM_REGS *regs);
int allocate_dos_memory(int size, int *sel);
void free_dos_memory(int sel);
int allocate_selector(int addr, int size);
void free_selector(int sel);
int get_vesa_info(int *vram_size, unsigned long *linear_addr, void (*callback)(int vesa_num, int linear, int w, int h, int bpp, int bytes_per_scanline, int redsize, int redpos, int greensize, int greenpos, int bluesize, int bluepos, int rsvdsize, int rsvdpos));
/* read_vga_register:
* Reads the contents of a VGA hardware register.
*/
extern inline int read_vga_register(int port, int index)
{
if (port==0x3C0)
inportb(0x3DA);
outportb(port, index);
return inportb(port+1);
}
/* write_vga_register:
* Writes a byte to a VGA hardware register.
*/
extern inline void write_vga_register(int port, int index, int v)
{
if (port==0x3C0) {
inportb(0x3DA);
outportb(port, index);
outportb(port, v);
}
else {
outportb(port, index);
outportb(port+1, v);
}
}
/* alter_vga_register:
* Alters specific bits of a VGA hardware register.
*/
extern inline void alter_vga_register(int port, int index, int mask, int v)
{
int temp;
temp = read_vga_register(port, index);
temp &= (~mask);
temp |= (v & mask);
write_vga_register(port, index, temp);
}
/* test_vga_register:
* Tests whether specific bits of a VGA hardware register can be changed.
*/
extern inline int test_vga_register(int port, int index, int mask)
{
int old, nw1, nw2;
old = read_vga_register(port, index);
write_vga_register(port, index, old & (~mask));
nw1 = read_vga_register(port, index) & mask;
write_vga_register(port, index, old | mask);
nw2 = read_vga_register(port, index) & mask;
write_vga_register(port, index, old);
return ((nw1==0) && (nw2==mask));
}
/* test_register:
* Tests whether specific bits of a hardware register can be changed.
*/
extern inline int test_register(int port, int mask)
{
int old, nw1, nw2;
old = inportb(port);
outportb(port, old & (~mask));
nw1 = inportb(port) & mask;
outportb(port, old | mask);
nw2 = inportb(port) & mask;
outportb(port, old);
return ((nw1==0) && (nw2==mask));
}
/* PCI routines added by SET */
#define PCIConfigurationAddress 0xCF8
#define PCIConfigurationData 0xCFC
#define PCIEnable 0x80000000
extern int FindPCIDevice(int deviceID, int vendorID, int deviceIndex, int *handle);
extern inline unsigned PCIReadLong(int handle, int index)
{
outportl(PCIConfigurationAddress, PCIEnable | handle | index);
return inportl(PCIConfigurationData);
}

571
video7/driver.c Normal file
View File

@ -0,0 +1,571 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* Video-7 driver (based on the Allegro Video-7 code).
*
* By Peter Monks, Markus Oberhumer, and Shawn Hargreaves.
*
* See freebe.txt for copyright information.
*/
// #define NO_HWPTR
#include <pc.h>
#include "vbeaf.h"
/* driver function prototypes */
void SetBank32();
void SetBank32End();
int ExtStub();
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo);
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc);
void RestoreTextMode(AF_DRIVER *af);
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock);
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf);
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT);
void SetActiveBuffer(AF_DRIVER *af, long index);
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT);
int GetDisplayStartStatus(AF_DRIVER *af);
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT);
void SetBank(AF_DRIVER *af, long bank);
/* list which ports we are going to access (only needed under Linux) */
unsigned short ports_table[] = { 0xFFFF };
/* internal driver state variables */
int af_bpp;
int af_width;
int af_height;
int af_visible_page;
int af_active_page;
int af_scroll_x;
int af_scroll_y;
int af_bank;
/* FreeBE/AF extension allowing farptr access to video memory */
FAF_HWPTR_DATA hwptr;
/* list of available video modes */
typedef struct VIDEO_MODE
{
int w, h;
int bpp;
int num;
} VIDEO_MODE;
VIDEO_MODE mode_list[] =
{
{ 640, 400, 8, 0x66 },
{ 640, 480, 8, 0x67 },
{ 720, 540, 8, 0x68 },
{ 800, 600, 8, 0x69 },
{ 1024, 768, 8, 0x6A }
};
#define NUM_MODES (int)(sizeof(mode_list)/sizeof(VIDEO_MODE))
short available_modes[NUM_MODES+1] = { 1, 2, 3, 4, 5, -1 };
/* detect:
* Detects the presence of a Video-7 card.
*/
char *detect(unsigned long *vidmem)
{
RM_REGS r;
unsigned v;
int old;
old = read_vga_register(0x3C4, 6);
write_vga_register(0x3C4, 6, 0xEA); /* enable BIOS extensions */
r.x.ax = 0x6F00; /* installation check */
r.x.bx = 0x0000;
rm_int(0x10, &r);
if ((r.x.bx != 0x5637) && (r.x.bx != 0x4850)) {
write_vga_register(0x3C4, 6, old);
return NULL;
}
r.x.ax = 0x6F07; /* get configuration */
rm_int(0x10, &r);
if (r.h.al != 0x6F) {
write_vga_register(0x3C4, 6, old);
return NULL;
}
*vidmem = (r.h.ah & 0x7F) * 256;
v = (read_vga_register(0x3C4, 0x8F)<<8) + read_vga_register(0x3C4, 0x8E);
switch (v) {
case 0x7140 ...
0x714F: return "V7 208A";
case 0x7151: return "V7 208B";
case 0x7152: return "V7 208CD";
case 0x7760: return "V7 216BC";
case 0x7763: return "V7 216D";
case 0x7764: return "V7 216E";
case 0x7765: return "V7 216F";
default:
return NULL;
}
}
/* SetupDriver:
* Fills in our driver header block.
*/
int SetupDriver(AF_DRIVER *af)
{
char *name;
int i;
name = detect(&af->TotalMemory);
if (!name)
return 1;
i = 0;
while (af->OemVendorName[i])
i++;
af->OemVendorName[i++] = ',';
af->OemVendorName[i++] = ' ';
while (*name)
af->OemVendorName[i++] = *(name++);
af->OemVendorName[i] = 0;
af->AvailableModes = available_modes;
af->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
af->BankSize = 64;
af->BankedBasePtr = 0xA0000;
af->IOPortsTable = ports_table;
af->SetBank32 = SetBank32;
af->SetBank32Len = (long)SetBank32End - (long)SetBank32;
af->SupplementalExt = ExtStub;
af->GetVideoModeInfo = GetVideoModeInfo;
af->SetVideoMode = SetVideoMode;
af->RestoreTextMode = RestoreTextMode;
af->GetClosestPixelClock = GetClosestPixelClock;
af->SaveRestoreState = SaveRestoreState;
af->SetDisplayStart = SetDisplayStart;
af->SetActiveBuffer = SetActiveBuffer;
af->SetVisibleBuffer = SetVisibleBuffer;
af->GetDisplayStartStatus = GetDisplayStartStatus;
af->SetPaletteData = SetPaletteData;
af->SetBank = SetBank;
return 0;
}
/* InitDriver:
* The second thing to be called during the init process, after the
* application has mapped all the memory and I/O resources we need.
*/
int InitDriver(AF_DRIVER *af)
{
hwptr_init(hwptr.IOMemMaps[0], af->IOMemMaps[0]);
hwptr_init(hwptr.IOMemMaps[1], af->IOMemMaps[1]);
hwptr_init(hwptr.IOMemMaps[2], af->IOMemMaps[2]);
hwptr_init(hwptr.IOMemMaps[3], af->IOMemMaps[3]);
hwptr_init(hwptr.BankedMem, af->BankedMem);
hwptr_init(hwptr.LinearMem, af->LinearMem);
return 0;
}
/* FreeBEX:
* Returns an interface structure for the requested FreeBE/AF extension.
*/
void *FreeBEX(AF_DRIVER *af, unsigned long id)
{
switch (id) {
#ifndef NO_HWPTR
case FAFEXT_HWPTR:
/* allow farptr access to video memory */
return &hwptr;
#endif
default:
return NULL;
}
}
/* ExtStub:
* Vendor-specific extension hook: we don't provide any.
*/
int ExtStub()
{
return 0;
}
/* GetVideoModeInfo:
* Retrieves information about this video mode, returning zero on success
* or -1 if the mode is invalid.
*/
long GetVideoModeInfo(AF_DRIVER *af, short mode, AF_MODE_INFO *modeInfo)
{
VIDEO_MODE *info;
int i;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
for (i=0; i<(int)sizeof(AF_MODE_INFO); i++)
((char *)modeInfo)[i] = 0;
modeInfo->Attributes = (afHaveMultiBuffer |
afHaveVirtualScroll |
afHaveBankedBuffer);
modeInfo->XResolution = info->w;
modeInfo->YResolution = info->h;
modeInfo->BitsPerPixel = info->bpp;
modeInfo->MaxBuffers = (af->TotalMemory*1024) /
(info->w*info->h*BYTES_PER_PIXEL(info->bpp));
if (info->w > 1024) {
modeInfo->MaxBytesPerScanLine = 2048*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 2048;
}
else {
modeInfo->MaxBytesPerScanLine = 1024*BYTES_PER_PIXEL(info->bpp);
modeInfo->MaxScanLineWidth = 1024;
}
modeInfo->BytesPerScanLine = info->w*BYTES_PER_PIXEL(info->bpp);
modeInfo->BnkMaxBuffers = modeInfo->MaxBuffers;
modeInfo->MaxPixelClock = 135000000;
return 0;
}
/* SetVideoMode:
* Sets the specified video mode, returning zero on success.
*/
long SetVideoMode(AF_DRIVER *af, short mode, long virtualX, long virtualY, long *bytesPerLine, int numBuffers, AF_CRTCInfo *crtc)
{
long available_vram;
long used_vram;
int width;
VIDEO_MODE *info;
RM_REGS r;
/* reject anything with hardware stereo, linear framebuffer, or noclear */
if (mode & 0xC400)
return -1;
mode &= 0x3FF;
if ((mode <= 0) || (mode > NUM_MODES))
return -1;
info = &mode_list[mode-1];
/* call BIOS to set the mode */
r.x.ax = 0x6F05;
r.x.bx = info->num;
rm_int(0x10, &r);
/* adjust the virtual width for widescreen modes */
if (virtualX > info->w) {
if (virtualX > 1024)
return -1;
*bytesPerLine = ((virtualX*BYTES_PER_PIXEL(info->bpp))+15)&0xFFF0;
width = read_vga_register(0x3D4, 0x13);
write_vga_register(0x3D4, 0x13, (width * (*bytesPerLine)) / (info->w*BYTES_PER_PIXEL(info->bpp)));
}
else
*bytesPerLine = info->w*BYTES_PER_PIXEL(info->bpp);
/* tweak some hardware registers */
write_vga_register(0x3C4, 6, 0xEA); /* enable BIOS extensions */
alter_vga_register(0x3C4, 0xE0, 0x80, 0); /* disable split banks */
alter_vga_register(0x3C4, 0xF6, 0xC0, 0xC0); /* disable wrap-around */
alter_vga_register(0x3C4, 0xFC, 0x07, 4); /* set compatibility control */
/* store info about the current mode */
af_bpp = info->bpp;
af_width = *bytesPerLine;
af_height = MAX(info->h, virtualY);
af_visible_page = 0;
af_active_page = 0;
af_scroll_x = 0;
af_scroll_y = 0;
af_bank = -1;
af->BufferEndX = af_width/BYTES_PER_PIXEL(af_bpp)-1;
af->BufferEndY = af_height-1;
af->OriginOffset = 0;
used_vram = af_width * af_height * numBuffers;
available_vram = af->TotalMemory*1024 ;
if (used_vram > available_vram)
return -1;
if (available_vram-used_vram >= af_width) {
af->OffscreenOffset = used_vram;
af->OffscreenStartY = af_height*numBuffers;
af->OffscreenEndY = available_vram/af_width-1;
}
else {
af->OffscreenOffset = 0;
af->OffscreenStartY = 0;
af->OffscreenEndY = 0;
}
return 0;
}
/* RestoreTextMode:
* Returns to text mode, shutting down the accelerator hardware.
*/
void RestoreTextMode(AF_DRIVER *af)
{
RM_REGS r;
r.x.ax = 3;
rm_int(0x10, &r);
}
/* GetClosestPixelClock:
* I don't have a clue what this should return: it is used for the
* refresh rate control.
*/
long GetClosestPixelClock(AF_DRIVER *af, short mode, unsigned long pixelClock)
{
/* ??? */
return 135000000;
}
/* SaveRestoreState:
* Stores the current driver status: not presently implemented.
*/
void SaveRestoreState(AF_DRIVER *af, int subfunc, void *saveBuf)
{
/* not implemented (not used by Allegro) */
}
/* SetDisplayStart:
* Hardware scrolling function. The waitVRT value may be one of:
*
* -1 = don't set hardware, just store values for next page flip to use
* 0 = set values and return immediately
* 1 = set values and wait for retrace
*/
void SetDisplayStart(AF_DRIVER *af, long x, long y, long waitVRT)
{
if (waitVRT >= 0) {
long a = (x * BYTES_PER_PIXEL(af_bpp)) + ((y + af_visible_page*af_height) * af_width);
asm volatile ("cli");
if (waitVRT) {
do {
} while (inportb(0x3DA) & 1);
}
/* write high bits to Video7 registers */
alter_vga_register(0x3C4, 0xF6, 0x30, a>>(18-4));
/* write to normal VGA address registers */
write_vga_register(0x3D4, 0x0D, (a>>2) & 0xFF);
write_vga_register(0x3D4, 0x0C, (a>>10) & 0xFF);
asm volatile ("sti");
if (waitVRT) {
do {
} while (!(inportb(0x3DA) & 8));
}
/* write low 2 bits to VGA horizontal pan register */
write_vga_register(0x3C0, 0x33, a&3);
}
af_scroll_x = x;
af_scroll_y = y;
}
/* SetActiveBuffer:
* Sets which buffer is being drawn onto, for use in multi buffering
* systems (not used by Allegro).
*/
void SetActiveBuffer(AF_DRIVER *af, long index)
{
if (af->OffscreenOffset) {
af->OffscreenStartY += af_active_page*af_height;
af->OffscreenEndY += af_active_page*af_height;
}
af_active_page = index;
af->OriginOffset = af_width*af_height*index;
if (af->OffscreenOffset) {
af->OffscreenStartY -= af_active_page*af_height;
af->OffscreenEndY -= af_active_page*af_height;
}
}
/* SetVisibleBuffer:
* Sets which buffer is displayed on the screen, for use in multi buffering
* systems (not used by Allegro).
*/
void SetVisibleBuffer(AF_DRIVER *af, long index, long waitVRT)
{
af_visible_page = index;
SetDisplayStart(af, af_scroll_x, af_scroll_y, waitVRT);
}
/* GetDisplayStartStatus:
* Status poll for triple buffering. Not possible on the majority of
* present cards: this function is just a placeholder.
*/
int GetDisplayStartStatus(AF_DRIVER *af)
{
return 1;
}
/* SetPaletteData:
* Palette setting routine.
*/
void SetPaletteData(AF_DRIVER *af, AF_PALETTE *pal, long num, long index, long waitVRT)
{
int i;
if (waitVRT) {
do {
} while (inportb(0x3DA) & 8);
do {
} while (!(inportb(0x3DA) & 8));
}
for (i=0; i<num; i++) {
outportb(0x3C8, index+i);
outportb(0x3C9, pal[i].red/4);
outportb(0x3C9, pal[i].green/4);
outportb(0x3C9, pal[i].blue/4);
}
}
/* SetBank32:
* Relocatable bank switch function, called with a bank number in %edx.
*/
asm ("
.globl _SetBank32, _SetBank32End
.align 4
_SetBank32:
pushl %edx
pushl %eax
movb %dl, %ah
shlb $4, %ah /* bank number */
movb $0xE8, %al
movl $0x3C4, %edx
outw %ax, %dx /* 3C4 index 0xE8 */
popl %eax
popl %edx
ret
_SetBank32End:
");
/* SetBank:
* C-callable bank switch function. This version simply chains to the
* relocatable SetBank32() above.
*/
void SetBank(AF_DRIVER *af, long bank)
{
asm (
" call _SetBank32 "
:
: "d" (bank)
);
af_bank = bank;
}

45
video7/drvhdr.c Normal file
View File

@ -0,0 +1,45 @@
/*
* ______ ____ ______ _____ ______
* | ____| | _ \| ____| / / _ \| ____|
* | |__ _ __ ___ ___| |_) | |__ / / |_| | |__
* | __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
* | | | | | __/ __/ |_) | |____ / / | | | | |
* |_| |_| \___|\___|____/|______/_/ |_| |_|_|
*
*
* VBE/AF driver header, used as input for DRVGEN.
*
* See freebe.txt for copyright information.
*/
#include "vbeaf.h"
AF_DRIVER drvhdr =
{
"VBEAF.DRV", /* Signature */
0x200, /* Version */
0, /* DriverRev */
"FreeBE/AF Video-7 driver " FREEBE_VERSION, /* OemVendorName */
"This driver is free software", /* OemCopyright */
NULL, /* AvailableModes */
0, /* TotalMemory */
0, /* Attributes */
0, /* BankSize */
0, /* BankedBasePtr */
0, /* LinearSize */
0, /* LinearBasePtr */
0, /* LinearGranularity */
NULL, /* IOPortsTable */
{ NULL, NULL, NULL, NULL }, /* IOMemoryBase */
{ 0, 0, 0, 0 }, /* IOMemoryLen */
0, /* LinearStridePad */
-1, /* PCIVendorID */
-1, /* PCIDeviceID */
-1, /* PCISubSysVendorID */
-1, /* PCISubSysID */
0 /* Checksum */
};

30
video7/notes.txt Normal file
View File

@ -0,0 +1,30 @@
______ ____ ______ _____ ______
| ____| | _ \| ____| / / _ \| ____|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
| | | | | __/ __/ |_) | |____ / / | | | | |
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
Video-7 driver implementation notes.
This is a software-only driver for Video-7 chipsets, based on the native
Video-7 driver from old versions of the Allegro library. It only supports
256 color modes, and has no support for linear framebuffers or
accelerated drawing. As such it is useful primarily because it is faster
than the VESA 1.x bank switching mechanism, and as a workaround for the
many bugs in common VESA driver implementations.
This code is not portable to any platforms other than DOS+DPMI, because
it uses BIOS calls to set the initial video mode.
Any volunteers to add hardware accelerator support? That would be very
welcome if you want to do it :-)
By Peter Monks (Peter_Monks@australia.notes.pw.com)
Scrolling fixed by Markus Oberhumer (markus.oberhumer@jk.uni-linz.ac.at)
VBE/AF conversion by Shawn Hargreaves (shawn@talula.demon.co.uk)

15
zipup.btm Normal file
View File

@ -0,0 +1,15 @@
@rem 4DOS batch file for building the distribution zips
@echo off
make.exe clean
make.exe docs
del /q freebe_s.zip
del /q freebe_b.zip
del /q freebe.mft
cd ..
zip -9 -r freebe\freebe_s.zip freebe -x freebe/readme.txt
unzip -Z -1 freebe\freebe_s.zip > freebe\freebe.mft
echo freebe/freebe.mft >> freebe\freebe.mft
zip -9 freebe\freebe_s.zip freebe\freebe.mft
cd freebe
make.exe install.exe
zip -9 freebe_b.zip install.exe readme.txt