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