Init
This commit is contained in:
parent
62644cad9e
commit
5d73ccc77a
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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)
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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>
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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
|
|
@ -0,0 +1,12 @@
|
||||||
|
OUTPUT_FORMAT("coff-go32")
|
||||||
|
|
||||||
|
FORCE_COMMON_ALLOCATION
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.text 0 : {
|
||||||
|
*(.text)
|
||||||
|
*(.data)
|
||||||
|
*(.bss)
|
||||||
|
*(COMMON)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
||||||
|
______ ____ ______ _____ ______
|
||||||
|
| ____| | _ \| ____| / / _ \| ____|
|
||||||
|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
|
||||||
|
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
|
||||||
|
| | | | | __/ __/ |_) | |____ / / | | | | |
|
||||||
|
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
|
||||||
|
|
||||||
|
|
||||||
|
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).
|
|
@ -0,0 +1,411 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>FreeBE/AF - the free VBE/AF driver project</title>
|
||||||
|
<body>
|
||||||
|
<pre>
|
||||||
|
<p>
|
||||||
|
______ ____ ______ _____ ______
|
||||||
|
| ____| | _ \| ____| / / _ \| ____|
|
||||||
|
| |__ _ __ ___ ___| |_) | |__ / / |_| | |__
|
||||||
|
| __| '__/ _ \/ _ \ _ <| __| / /| _ | __|
|
||||||
|
| | | | | __/ __/ |_) | |____ / / | | | | |
|
||||||
|
|_| |_| \___|\___|____/|______/_/ |_| |_|_|
|
||||||
|
<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>
|
|
@ -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
|
|
@ -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).
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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};
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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__ */
|
||||||
|
|
|
@ -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}
|
||||||
|
};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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)
|
|
@ -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);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 */
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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
|
File diff suppressed because it is too large
Load Diff
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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
|
||||||
|
};
|
|
@ -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]
|
||||||
|
=á
|
||||||
|
‚=é
|
||||||
|
¡=í
|
||||||
|
¢=ó
|
||||||
|
£=ú
|
||||||
|
¤=ñ
|
||||||
|
¥=Ñ
|
||||||
|
=¡
|
||||||
|
¨=¿
|
||||||
|
„=ä
|
||||||
|
‰=ë
|
||||||
|
‹=ï
|
||||||
|
”=ö
|
||||||
|
<EFBFBD>=ü
|
||||||
|
š=Ü
|
||||||
|
…=à
|
||||||
|
Š=è
|
||||||
|
<EFBFBD>=ì
|
||||||
|
•=ò
|
||||||
|
—=ù
|
||||||
|
<=<
|
||||||
|
>=>
|
||||||
|
|
||||||
|
#
|
||||||
|
# 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 <~2>
|
||||||
|
</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>
|
|
@ -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;
|
|
@ -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
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 *)®s[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 *)®s[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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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");
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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)
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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)
|
|
@ -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);
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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 */
|
||||||
|
};
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
Loading…
Reference in New Issue