617 lines
15 KiB
C
617 lines
15 KiB
C
/*
|
|
** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
|
|
** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
|
|
** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
|
|
** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
|
|
** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
|
|
** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
|
** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
|
|
** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
|
|
**
|
|
** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
|
|
** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
|
|
** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
|
|
** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
|
|
** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
|
|
** THE UNITED STATES.
|
|
**
|
|
** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
|
|
**
|
|
**
|
|
** $Revision$
|
|
** $Date$
|
|
**
|
|
*/
|
|
static char revString[] = "@#%$Workfile: initmcrx.c $ $Revision$";
|
|
|
|
#include <3dfx.h>
|
|
|
|
#include <stddef.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#ifndef __linux__
|
|
#include <conio.h>
|
|
#else
|
|
#include <fxpci.h>
|
|
#define _inp(port) pioInByte(port);
|
|
#define _outp(port,data) pioOutByte(port, data);
|
|
#define _outpw(port,data) pioOutWord(port, data);
|
|
#endif
|
|
#ifdef __DOS32__
|
|
#include <i86.h>
|
|
#endif
|
|
|
|
#ifdef __WIN32__
|
|
#include <windows.h>
|
|
#endif /* __WIN32__ */
|
|
|
|
#define INIT_MCRX_LIB
|
|
#define FX_DLL_DEFINITION
|
|
#include <fxdll.h>
|
|
#include <gdebug.h>
|
|
#include <init.h>
|
|
|
|
|
|
#include <initvga.h>
|
|
#include "fxinit96.h"
|
|
#include "initmcrx.h"
|
|
|
|
#ifndef BIT
|
|
#define BIT(a) (1 << a)
|
|
#endif
|
|
|
|
/* Global Data */
|
|
static Init96HALData mcrxHALData = {
|
|
0x2000000,
|
|
initMCRXAperture,
|
|
initMCRXSetVideo,
|
|
initMCRXEnableRegs,
|
|
initMCRXDisableRegs,
|
|
initMCRXWrapFIFO,
|
|
initMCRXUseTiles,
|
|
initMCRXGetInfo,
|
|
NULL /* initMCRXSwapTiles */
|
|
};
|
|
|
|
|
|
#if 0 /* ??? needed??? XXX */
|
|
static FxBool tiling;
|
|
#endif
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: intiMCRXGetHALData
|
|
Date: 09-May-97
|
|
Implementor(s): dow
|
|
Library: Init Code for MCRX
|
|
Description:
|
|
|
|
Arguments:
|
|
|
|
Return:
|
|
address of mcrxHALData
|
|
-------------------------------------------------------------------*/
|
|
INITMCRXENTRY(initMCRXGetHALData, Init96HALData *, (void) )
|
|
{
|
|
#define FN_NAME "intiMCRXGetHALData"
|
|
return &mcrxHALData;
|
|
#undef FN_NAME
|
|
} /* intiMCRXGetHALData */
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: initMCRXAperture
|
|
Date: 3-May-97
|
|
Implementor(s): dow
|
|
Library: Init Code for MCRX
|
|
Description:
|
|
Initialize rd pointers to access apertures
|
|
Arguments:
|
|
|
|
Return:
|
|
-------------------------------------------------------------------*/
|
|
INITMCRXENTRY(initMCRXAperture, FxBool , (InitRegisterDesc *rd) )
|
|
{
|
|
#define FN_NAME "initMCRXAperture"
|
|
FxBool
|
|
rVal = FXTRUE;
|
|
|
|
GDBG_INFO((80, "%s:\n", FN_NAME));
|
|
|
|
rd->hwDep.VG96RegDesc.partnerRegPtr = (FxU32 *)
|
|
((FxU32) rd->hwDep.VG96RegDesc.baseAddress +
|
|
0x2000000 - 0x20000);
|
|
|
|
GDBG_INFO((80, "%s: Setting partnerRegPtr to 0x%x\n",
|
|
FN_NAME, rd->hwDep.VG96RegDesc.partnerRegPtr));
|
|
|
|
#if 1
|
|
rd->hwDep.VG96RegDesc.serialStatus = (FxU32 *)
|
|
((FxU32) rd->hwDep.VG96RegDesc.partnerRegPtr + 0x700);
|
|
#else
|
|
GDBG_INFO((80, "%s: Working around invalid serial status\n", FN_NAME));
|
|
rd->hwDep.VG96RegDesc.serialStatus =
|
|
&rd->hwDep.VG96RegDesc.baseAddress[0x100000];
|
|
#endif
|
|
GDBG_INFO((80, "%s: Setting seial status to 0x%x\n", FN_NAME, rd->hwDep.VG96RegDesc.serialStatus));
|
|
|
|
/* BOGUS */
|
|
rd->hwDep.VG96RegDesc.fifoApertureBase =
|
|
(FxU32 *) (((FxU32)rd->hwDep.VG96RegDesc.baseAddress) + 0x400000);
|
|
|
|
GDBG_INFO((80, "%s: returning TRUE\n", FN_NAME));
|
|
|
|
return rVal;
|
|
|
|
#undef FN_NAME
|
|
} /* initMCRXAperture */
|
|
|
|
/* FIXME !! jdt - need to add more resolutions to dos */
|
|
INITMCRXENTRY(initMCRXSetVideo, FxBool, (GrScreenResolution_t res, GrScreenRefresh_t refresh, FxU32 *xr, FxU32 *yr ))
|
|
{
|
|
#define FN_NAME "initMCRXSetVideo"
|
|
FxBool rv = FXTRUE;
|
|
#if defined(INIT_ACCESS_DIRECT) && defined( __DOS32__ )
|
|
union REGS r0, r1;
|
|
#endif
|
|
|
|
GDBG_INFO((80, "%s: \n", FN_NAME));
|
|
|
|
#if defined(INIT_ACCESS_DIRECT) && defined( __DOS32__ )
|
|
switch( res ) {
|
|
case GR_RESOLUTION_320x200:
|
|
/* Set up VESA Mode 0x136 - 320x200x16 */
|
|
r1.w.ax = 0x4f02;
|
|
r1.w.bx = 0x0136;
|
|
*xr = 320;
|
|
*yr = 200;
|
|
rv = FXTRUE;
|
|
break;
|
|
case GR_RESOLUTION_320x240:
|
|
/* Set up VESA Mode 0x137 - 320x240x16 */
|
|
r1.w.ax = 0x4f02;
|
|
r1.w.bx = 0x0137;
|
|
*xr = 320;
|
|
*yr = 240;
|
|
rv = FXTRUE;
|
|
break;
|
|
case GR_RESOLUTION_512x384:
|
|
/* Set up VESA Mode 0x139 - 512x384x16 */
|
|
r1.w.ax = 0x4f02;
|
|
r1.w.bx = 0x0139;
|
|
*xr = 512;
|
|
*yr = 384;
|
|
rv = FXTRUE;
|
|
break;
|
|
case GR_RESOLUTION_640x480:
|
|
/* Set up VESA Mode 0x111 - 640x480x16 */
|
|
r1.w.ax = 0x4f02;
|
|
r1.w.bx = 0x0111;
|
|
*xr = 640;
|
|
*yr = 480;
|
|
rv = FXTRUE;
|
|
break;
|
|
case GR_RESOLUTION_800x600:
|
|
/* Set up VESA Mode 0x114 - 800x600x16 */
|
|
r1.w.ax = 0x4f02;
|
|
r1.w.bx = 0x0114;
|
|
*xr = 800;
|
|
*yr = 600;
|
|
rv = FXTRUE;
|
|
break;
|
|
default:
|
|
rv = FXFALSE;
|
|
break;
|
|
}
|
|
|
|
if (rv == FXTRUE) {
|
|
GDBG_INFO((80, "initMCRXSetVideo: Enabling VESA modes\n"));
|
|
r0.w.ax = 0x6483;
|
|
r0.w.bx = 0x0060;
|
|
int386( 0x10, &r0, &r0 );
|
|
|
|
GDBG_INFO((80, "initMCRXSetVideo: Setting video mode %dx%dx16\n",
|
|
*xr, *yr));
|
|
int386( 0x10, &r1, &r1 );
|
|
}
|
|
|
|
#endif
|
|
GDBG_INFO((80, "%s: returning %s\n", FN_NAME, rv?"TRUE":"FALSE"));
|
|
return rv;
|
|
#undef FN_NAME
|
|
} /* initMCRXSetVideo */
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: initMCRXEnableRegs
|
|
Date: 07-Feb-97
|
|
Implementor(s): dow
|
|
Library: Init Code for MCRX
|
|
Description:
|
|
|
|
Do all setup necessary to enable direct writes to JR Space
|
|
|
|
Arguments:
|
|
rd - pointer to register description
|
|
|
|
Return:
|
|
True if success, False if Failure
|
|
-------------------------------------------------------------------*/
|
|
INITMCRXENTRY(initMCRXEnableRegs, FxBool, (InitRegisterDesc *rd))
|
|
{
|
|
#define FN_NAME "initMCRXEnableRegs"
|
|
FxU32
|
|
tmp;
|
|
FxU8
|
|
crtcIndex;
|
|
FxU16
|
|
protState;
|
|
|
|
const char *envVal;
|
|
|
|
GDBG_INFO((80, "%s:\n", FN_NAME));
|
|
|
|
GDBG_INFO((80, "%s: Unprotect\n", FN_NAME));
|
|
|
|
GDBG_INFO((80, "%s: Save CRTC Index\n", FN_NAME));
|
|
INP(0x3c4, crtcIndex);
|
|
|
|
GDBG_INFO((80, "%s: Save Extended Registers Protection State\n",
|
|
FN_NAME));
|
|
|
|
OUTP(0x3d4, 0x19);
|
|
INP(0x3d5, protState);
|
|
|
|
protState <<= 8;
|
|
protState |= 0x19;
|
|
|
|
GDBG_INFO((80, "%s: Enabling Access to Extended Registers\n", FN_NAME));
|
|
OUTPW(0x3d4, 0x8819);
|
|
|
|
/* Getting initial values of the mclock for later restore */
|
|
GDBG_INFO((80, "%s: Getting macronix mclock registers\n", FN_NAME));
|
|
OUTP(0x3C4, 0x1A);
|
|
INP(0x3C5, rd->hwDep.VG96RegDesc.mclockHi);
|
|
|
|
OUTP(0x3C4, 0x1B);
|
|
INP(0x3C5, rd->hwDep.VG96RegDesc.mclockLo);
|
|
GDBG_INFO((80, "%s: mclock registers: (0x%X : 0x%X)\n", FN_NAME,
|
|
(FxU32)rd->hwDep.VG96RegDesc.mclockHi, (FxU32)rd->hwDep.VG96RegDesc.mclockHi));
|
|
|
|
GDBG_INFO((80, "%s: Enabling FBI Jr.\n", FN_NAME));
|
|
OUTPW(0x3C4, 0x001F);
|
|
|
|
GDBG_INFO((80, "%s: Setting clock to 50MHz\n", FN_NAME));
|
|
OUTPW(0x3c4, 0x011a);
|
|
OUTPW(0x3c4, 0x061b);
|
|
|
|
/* Macronix reset propogation */
|
|
GDBG_INFO((80, "%s: Macronix reset\n", FN_NAME));
|
|
OUTPW(0x3c4, 0x081c);
|
|
OUTPW(0x3c4, 0x001c);
|
|
|
|
GDBG_INFO((80, "%s: Hard Reset of FBI Jr.\n", FN_NAME));
|
|
OUTPW(0x3d4, 0x0029);
|
|
OUTPW(0x3d4, 0x0129);
|
|
|
|
GDBG_INFO((80, "%s: Enabling PUMA\n", FN_NAME));
|
|
CRTC_GET(0x28, tmp);
|
|
tmp |= 1;
|
|
|
|
envVal = myGetenv("MCRX_28");
|
|
if (envVal)
|
|
sscanf(envVal, "%x", &tmp);
|
|
CRTC_SET(0x28, tmp);
|
|
|
|
GDBG_INFO((80, "%s: Restoring Protection\n", FN_NAME));
|
|
OUTP(0x3d4, protState);
|
|
|
|
GDBG_INFO((80, "%s: Restoring Sequencer Index\n", FN_NAME));
|
|
OUTP(0x3c4, crtcIndex);
|
|
|
|
return FXTRUE;
|
|
|
|
#undef FN_NAME
|
|
} /* initMCRXEnableRegs */
|
|
|
|
|
|
/* FIXME!!! jdt - puma/ram timing fixes need to go here */
|
|
INITMCRXENTRY(initMCRXDisableRegs,FxBool,(InitRegisterDesc *rd))
|
|
{
|
|
#define FN_NAME "initMCRXDisableRegs"
|
|
FxU8
|
|
seqSave, crtcSave;
|
|
|
|
FxU16
|
|
protState;
|
|
|
|
FxU32
|
|
tmp;
|
|
|
|
GDBG_INFO((80, "%s:\n", FN_NAME));
|
|
|
|
GDBG_INFO((80, "%s: Saving Sequencer Index\n", FN_NAME));
|
|
INP(0x3c4, seqSave);
|
|
|
|
GDBG_INFO((80, "%s: Saving CRTC Index\n", FN_NAME));
|
|
INP(0x3d4, crtcSave);
|
|
|
|
GDBG_INFO((80, "%s: Saving Protection State\n", FN_NAME));
|
|
OUTP(0x3d4, 0x19);
|
|
INP(0x3d5, protState);
|
|
|
|
protState <<= 9;
|
|
protState |= 0x19;
|
|
|
|
GDBG_INFO((80, "%s: Enabling access to extended registers\n", FN_NAME));
|
|
OUTPW(0x3d4, 0x8819);
|
|
|
|
/* Reset 3Dfx chip via macronix */
|
|
GDBG_INFO((80, "%s: Reset 3Dfx via macronix\n", FN_NAME));
|
|
OUTPW(0x3d4, 0x0029);
|
|
OUTPW(0x3d4, 0x0129);
|
|
|
|
GDBG_INFO((80, "%s: Disabling PUMA\n", FN_NAME));
|
|
CRTC_GET(0x28, tmp);
|
|
GDBG_INFO((80, "%s: crtc 0x28: 0x%X\n", FN_NAME, tmp));
|
|
tmp &= ~1;
|
|
CRTC_SET(0x28, tmp);
|
|
|
|
GDBG_INFO((80, "%s: Turning off FBI Jr.\n", FN_NAME));
|
|
OUTPW(0x3c4, 0x061f);
|
|
|
|
/* Restore the mclock */
|
|
{
|
|
FxU16 tempMclock;
|
|
|
|
GDBG_INFO((80, "%s: Restoring mclock\n", FN_NAME));
|
|
tempMclock = (0x1A | (rd->hwDep.VG96RegDesc.mclockHi << 8));
|
|
OUTPW(0x3C4, tempMclock);
|
|
|
|
tempMclock = (0x1B | (rd->hwDep.VG96RegDesc.mclockLo << 8));
|
|
OUTPW(0x3C4, tempMclock);
|
|
|
|
/* Macronix MCLK reset propogation */
|
|
OUTPW(0x3C4, 0x081C);
|
|
OUTPW(0x3C4, 0x001C);
|
|
}
|
|
|
|
GDBG_INFO((80, "%s: Restoring Protection\n", FN_NAME));
|
|
OUTPW(0x3df, protState);
|
|
|
|
GDBG_INFO((80, "%s: Restoring CRTC Index\n", FN_NAME));
|
|
OUTP(0x3d4, crtcSave);
|
|
|
|
GDBG_INFO((80, "%s: Restoring Sequencer Index\n", FN_NAME));
|
|
OUTP(0x3c4, seqSave);
|
|
|
|
return FXTRUE;
|
|
|
|
#undef FN_NAME
|
|
} /* initMCRXDisableRegs */
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: initMCRXWrapFIFO
|
|
Date: 20-Feb-97
|
|
Implementor(s): tarolli
|
|
Library: Init Code for MCRX
|
|
Description:
|
|
|
|
Arguments:
|
|
|
|
Return:
|
|
-------------------------------------------------------------------*/
|
|
INITMCRXENTRY(initMCRXWrapFIFO, FxBool, (InitRegisterDesc *rd, InitFIFOData *fd) )
|
|
{
|
|
#define FN_NAME "initMCRXWrapFIFO"
|
|
return FXFALSE;
|
|
#undef FN_NAME
|
|
} /* initMCRXWrapFIFO */
|
|
|
|
#define MAX_BUF 3
|
|
|
|
static unsigned char magic[MAX_BUF][3] = {
|
|
{ 0x0d, 0x0c, 0x21 },
|
|
{ 0x71, 0x72, 0x73 },
|
|
/* chd - Fixme!
|
|
* Bogus numbers. Does triple buffering work on Macronix?
|
|
*
|
|
* dpc - 23 jan 1998 -
|
|
* Donny just told me this so hopefully this will work.
|
|
*/
|
|
{ 0x74, 0x75, 0x76 }
|
|
};
|
|
|
|
INITMCRXENTRY(initMCRXSwapTiles, FxBool, (InitRegisterDesc* rd))
|
|
{
|
|
#define FN_NAME "initMCRXSwapTiles"
|
|
FxU8 crtcSwapStatus;
|
|
FxU8 crtcSwapControl;
|
|
|
|
/* Get the # of buffers swapping */
|
|
OUTP(0x3D4, 0x70);
|
|
INP(0x3D5, crtcSwapControl);
|
|
|
|
/* Get the current active buffer setting */
|
|
OUTP(0x3D4, 0x7A);
|
|
INP(0x3D5, crtcSwapStatus);
|
|
|
|
/* Bits 0-1 indicate the current active buffer. Check to see if we
|
|
* need to wrap this and go to the next buffer.
|
|
*/
|
|
{
|
|
const FxU8 bufferBits = (crtcSwapStatus & 0x03);
|
|
const FxU8 maxBufferBits = (((crtcSwapControl & 0x08) == 0) ? 1 : 2);
|
|
|
|
crtcSwapStatus = ((crtcSwapStatus & ~0x03) |
|
|
((bufferBits == maxBufferBits) ? 0x00 : bufferBits + 1));
|
|
CRTC_SET(0x7A, crtcSwapStatus);
|
|
}
|
|
|
|
/* We have no way of knowing that this worked so of course we always
|
|
* return success.
|
|
*/
|
|
return FXTRUE;
|
|
#undef FN_NAME
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: initMCRXUseTiles
|
|
Date: 07-Feb-97 (Moved into initMCRX from init96)
|
|
Implementor(s): pgj, dow
|
|
Library: Init Code for MCRX
|
|
Description:
|
|
|
|
Arguments:
|
|
atmm: Pointer to base of MCRX
|
|
buffers: Pointer to array of offsets to buffers
|
|
nBuffers: Total number of buffers
|
|
backBuffer: FB offset of back buffer
|
|
strideInBytes: Tile width in bytes
|
|
|
|
Return:
|
|
1 if successful, 2 if renderbuffers need to be swapped.
|
|
-------------------------------------------------------------------*/
|
|
#ifdef H3D
|
|
INITMCRXENTRY(initMCRXUseTiles, int, (InitRegisterDesc *rd,
|
|
FxU32 *buffers,
|
|
FxU32 nBuffers,
|
|
FxU32 strideInBytes,
|
|
FxU32 Width, FxU32 Height, FxU32 PageFlipping))
|
|
#else
|
|
INITMCRXENTRY(initMCRXUseTiles, int, (InitRegisterDesc *rd,
|
|
FxU32 *buffers,
|
|
FxU32 nBuffers,
|
|
FxU32 strideInBytes,
|
|
FxU32 Width, FxU32 Height))
|
|
#endif
|
|
{
|
|
#define FN_NAME "initMCRXUseTiles"
|
|
|
|
int ret = 1;
|
|
unsigned int i;
|
|
|
|
FxU32
|
|
dwordOffset;
|
|
|
|
FxU8
|
|
regVal;
|
|
|
|
FxU32
|
|
tmp;
|
|
|
|
const char *envVal;
|
|
|
|
GDBG_INFO((80, "%s:\n", FN_NAME));
|
|
|
|
regVal = _inp(VGA_MISC_OUTPUT_READ);
|
|
/* Mask off bit 7 */
|
|
regVal |= (1<<7);
|
|
_outp(VGA_MISC_OUTPUT_WRITE, regVal);
|
|
|
|
/*---------------------------------
|
|
CONFIGURE TILES
|
|
---------------------------------*/
|
|
for (i=0; i < nBuffers; i++) {
|
|
FxU32
|
|
buf = buffers[i];
|
|
|
|
GDBG_INFO((80, "%s: Setting up buffer %d\n", FN_NAME, i));
|
|
|
|
dwordOffset = buf >> 2;
|
|
|
|
GDBG_INFO((80, "%s: Buffer[%d] = 0x%x, dwordOffset = 0x%x\n",
|
|
FN_NAME, i, buf, dwordOffset));
|
|
|
|
GDBG_INFO((80, "%s: Writing bits 0-7 of buffer 0 offset\n", FN_NAME));
|
|
tmp = (FxU8) (dwordOffset & 0xff);
|
|
|
|
CRTC_SET(magic[i][0], tmp);
|
|
|
|
GDBG_INFO((80, "%s: Writing bits 8-15 of buffer 0 offset\n", FN_NAME));
|
|
tmp = (FxU8) ((dwordOffset >> 8) & 0xff);
|
|
CRTC_SET(magic[i][1], tmp);
|
|
|
|
GDBG_INFO((80, "%s: Writing bits 16-19 of buffer 0 offset\n", FN_NAME));
|
|
tmp = (FxU8) ((dwordOffset >> 16) & 0xf);
|
|
CRTC_SET(magic[i][2], tmp);
|
|
}
|
|
|
|
GDBG_INFO((80, "%s: Setting up Swap Control\n", FN_NAME));
|
|
tmp = 0x01;
|
|
|
|
/* dpc - 26 han 1998
|
|
* If we are triple buffering we need to enable this on the actual
|
|
* macronix part as well. This is set by enabling bit 3 of the crtc
|
|
* register.
|
|
*/
|
|
if (nBuffers == 3) tmp |= 0x08;
|
|
mcrxHALData.initSwapTiles = initMCRXSwapTiles;
|
|
|
|
envVal = myGetenv("MRCX_71");
|
|
if (envVal)
|
|
sscanf(envVal, "%x", &tmp);
|
|
CRTC_SET(0x70, tmp);
|
|
|
|
/* Reset the current display buffer bits (0-1) */
|
|
{
|
|
FxU8 crtcSwapBuffer;
|
|
|
|
OUTP(0x3D4, 0x7A);
|
|
INP(0x3D5, crtcSwapBuffer);
|
|
|
|
crtcSwapBuffer &= ~0x03;
|
|
CRTC_SET(0x7A, crtcSwapBuffer);
|
|
}
|
|
|
|
return ret;
|
|
|
|
#undef FN_NAME
|
|
} /* initMCRXUseTiles */
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: initMCRXGetInfo
|
|
Date: 28-Apr-97
|
|
Implementor(s): pgj, dow
|
|
Library: Init Code for MCRX
|
|
Description:
|
|
|
|
get information about MCRX
|
|
|
|
Arguments:
|
|
info - pointer to info struct
|
|
|
|
Return:
|
|
True if success, False if Failure
|
|
-------------------------------------------------------------------*/
|
|
INITMCRXENTRY(initMCRXGetInfo,FxBool,(VG96Info *info))
|
|
{
|
|
#define FN_NAME "initMCRXGetInfo"
|
|
FxU32 mBytesPow;
|
|
FxU8 res;
|
|
|
|
GDBG_INFO((80, "%s:\n", FN_NAME));
|
|
|
|
CRTC_GET(0x1a, res);
|
|
|
|
/* We care about bit 5 & 6 */
|
|
mBytesPow = ((res >> 5) & 3);
|
|
|
|
/* Watcom warning suppression */
|
|
revString[0] = revString[0];
|
|
|
|
info->vgaChip = 0;
|
|
info->vg96Rev = 0;
|
|
info->nTFX = 1;
|
|
info->tfxRev = 1;
|
|
info->tfxRam = 2;
|
|
|
|
info->vg96Ram = (0x100000 << mBytesPow);
|
|
|
|
GDBG_INFO((80, "%s: frame buffer has 0x%x bytes\n", FN_NAME, info->vg96Ram));
|
|
|
|
return FXTRUE;
|
|
|
|
#undef FN_NAME
|
|
} /* initMCRXGetInfo */
|
|
|
|
|