Files
glide/glide2x/sst1/init/init96/initat3d.c
sezero 1f08466bc6 sst96: more of making several global vars static:
- initat3d.c: make ClockTableAT3D[] const and static.
- initad3d.c: make const vars  bPowerOff, bHighSpeed,
  and bBypass static.
2018-08-06 14:00:01 +03:00

1659 lines
51 KiB
C

/*
** Copyright (c) 1996, 3Dfx Interactive, Inc.
** All Rights Reserved.
**
** This is UNPUBLISHED PROPRIETARY SOURCE CODE of 3Dfx Interactive, Inc.;
** the contents of this file may not be disclosed to third parties, copied or
** duplicated in any form, in whole or in part, without the prior written
** permission of 3Dfx Interactive, Inc.
**
** RESTRICTED RIGHTS LEGEND:
** 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.
**
*/
#define INIT_AT3D_LIB
#include <3dfx.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef __linux__
#include <conio.h>
#endif
#include <assert.h>
#include <time.h>
#ifdef __DOS32__
#ifdef __DJGPP__
#include <dos.h>
#else
#include <i86.h>
#endif
#endif
#ifdef __WIN32__
#include <windows.h>
#endif /* __WIN32__ */
#if defined(__WATCOMC__)
#define _inp inp
#define _outp outp
#endif
#ifdef __DJGPP__
#include <fxdpmi.h>
#endif
#if defined(__linux__)
#define _inp(port) pioInByte(port)
#define _outp(port, data) pioOutByte(port, data)
#endif
#define AT3D_BASE 0xffec00
#define FX_DLL_DEFINITION
#include <fxdll.h>
#include <gdebug.h>
#include <init.h>
#include "fxinit96.h"
#include "initat3d.h"
#include "atvga.h"
#include "initvga.h"
#include "physical.h"
/*
** Static Globals
*/
/* Stuff for programming the memory clock */
typedef struct _CLOCK_TABLE {
int iMclk;
unsigned char wN;
unsigned char wM;
unsigned char wL;
unsigned char wFR;
} CLOCK_TABLE;
/* This table is for AT3D, other parts need different tables. */
static const CLOCK_TABLE ClockTableAT3D[] =
{
{ 25, 0x1b, 0x1, 0x3, 0x6 },
{ 40, 0x2c, 0x1, 0x3, 0x3 },
{ 45, 0x32, 0x1, 0x3, 0x1 },
{ 50, 0x1b, 0x1, 0x2, 0x6 },
{ 55, 0x2d, 0x2, 0x2, 0x6 },
{ 60, 0x21, 0x1, 0x2, 0x5 },
{ 62, 0x44, 0x3, 0x2, 0x5 },
{ 65, 0x5a, 0x4, 0x2, 0x4 },
{ 67, 0x37, 0x2, 0x2, 0x4 },
{ 70, 0x26, 0x1, 0x2, 0x4 },
{ 72, 0x27, 0x1, 0x2, 0x4 },
{ 75, 0x29, 0x1, 0x2, 0x3 },
{ 80, 0x2c, 0x1, 0x2, 0x3 },
{ 85, 0x2f, 0x1, 0x2, 0x2 },
{ 90, 0x31, 0x1, 0x2, 0x1 },
{ 95, 0x34, 0x1, 0x2, 0x1 },
{ 100, 0x1b, 0x1, 0x1, 0x6},
{ 0, 0, 0, 0, 0 } /* used for end of table mark */
};
typedef struct _REGVALS {
unsigned char E8;
unsigned char E9;
unsigned char EA;
} REGVALS, *LPREGVALS;
typedef struct _REGINFO {
REGVALS RegVals;
int bFreqFound;
} REGINFO, *LPREGINFO;
/* MCLK Constants */
static const unsigned char bBypass = 0;
static const unsigned char bHighSpeed = 1;
static const unsigned char bPowerOff = 0;
/* HALData required for each partner */
static Init96HALData at3dHALData = {
0x1000000,
initAT3DAperture,
initAT3DSetVideo,
initAT3DEnableRegs,
initAT3DDisableRegs,
NULL,
initAT3DUseTiles,
initAT3DGetInfo,
NULL, /* SwapTiles */
NULL
};
/* Random Kruft */
static FxBool tiling; /* Well, are we? */
static FxU32 workaround; /* Some registers have to be read
after they're written, and we store
that read here*/
static LPCOP at3dRegPtr = NULL;
/* Stuff we squirrel away and put back when we've finished */
static FxU16 tileRegSave[12*8];
FxU16
regWindowSequenceControlSave,
regWindow0BaseAddressSave,
regWindow0StretchFactorHor1Save,
regWindow0StretchFactorHor2Save,
regWindow0StretchFactorVer1Save,
regWindow0StretchFactorVer2Save,
regWindow0ControlSave;
/* Some Constants */
#define GINTERVAL 100
/*
** Assignment Macros/Debugging Support Routines
**
** OK, So these just print out the byte offset of the register, but
** before you come bitch at me, look at physical.h to see how much
** work it is to generate register names, then look at this file and
** see how few of them we actually use.
**
** CHD
**
** Fixme!!! need workaround = d, not workaround = s! Do this after 2.4
**
*/
#ifdef GDBG_INFO_ON
#define SETAT3D(d,s) \
{\
GDBG_INFO((80, "%s: Setting AT3D Register 0x%x with value 0x%x\n", FN_NAME, (FxU32) &d - (FxU32) at3dRegPtr, s));\
d = s; workaround = (FxU32) s ;}
#define GETAT3D(s) readDebugAT3D(&s, FN_NAME)
#define GET8AT3D(s) read8DebugAT3D(&s, FN_NAME)
#define GET16AT3D(s) read16DebugAT3D(&s, FN_NAME)
#else
#define SETAT3D(d,s) d = s; workaround = (FxU32) s
#define GETAT3D(s) s
#define GET8AT3D(s) s
#define GET16AT3D(s) s
#endif
#ifdef GDBG_INFO_ON
static FxU32
readDebugAT3D(volatile FxU32 *s, char *fName) {
FxU32 ret;
ret = *s;
GDBG_INFO((80, "%s: Read 0x%x from register 0x%x\n", fName, ret,
(FxU32) s - (FxU32) at3dRegPtr));
return ret;
} /* readDebugAT3D */
static FxU8
read8DebugAT3D(volatile FxU8 *s, char *fName) {
FxU8
ret;
ret = *s;
GDBG_INFO((80, "%s: Read 0x%x from register 0x%x\n", fName, ret,
(FxU32) s - (FxU32) at3dRegPtr));
return ret;
} /* read8DebugAT3D */
static FxU16
read16DebugAT3D(volatile FxU16 *s, char *fName) {
FxU16
ret;
ret = *s;
GDBG_INFO((80, "%s: Read 0x%x from register 0x%x\n", fName, ret,
(FxU32) s - (FxU32) at3dRegPtr));
return ret;
} /* read16DebugAT3D */
#endif
/*
** AT3D Utility Routines
**
** These routines blah blah blah
*/
#ifdef H3D
void pageflippingSwapWait(void) {
#define FN_NAME "pageflippingSwapWait"
int bailCount = 150000, pending = 1;
FxU32 status;
if (!at3dRegPtr) return;
status = (FxU32)(GETAT3D(at3dRegPtr->Extended_Status) & 0x00400000L);
if (!status) {
do {
status = (FxU32)(GETAT3D(at3dRegPtr->Extended_Status) & 0x00400000L);
} while (!status && --bailCount); // wait for it to go low
bailCount = 150000;
}
if (status) { // is swap pending?
do {
status = (FxU32)(GETAT3D(at3dRegPtr->Extended_Status) & 0x00400000L);
} while (status && --bailCount); // wait for it to go low
}
#undef FN_NAME
}
#endif /* H3D */
/*-------------------------------------------------------------------
Function: initAT3DGetRegVals
Date: 20-May-97
Implementor(s): someone from ALSC, ganked by dow
Library: Init Code for AT3D
Description:
This routine was shamelessly ganked out of the DirectDraw driver
for AT3D/Voodoo Rush.
Basically, it takes a frequency (in MHz), and returns some
mystical values needed for programming the PLL.
Arguments:
Return:
FXTRUE if successful.
-------------------------------------------------------------------*/
REGINFO
initAT3DGetRegVals(int iFreq)
{
#define FN_NAME "initAT3DGetRegVals"
/* Get the E8,E9, and EA values for given frequency. */
const CLOCK_TABLE *lpClockTable = (const CLOCK_TABLE *) ClockTableAT3D;
int i;
REGINFO RegInfo;
BYTE bN, bM, bL, bFreqRange;
/* Scan for MCLK value from array. */
i = 0;
while( lpClockTable[i].iMclk != 0 ) {
if( lpClockTable[i].iMclk == iFreq )
break;
i++;
}
/* Check if there is no MCLK matched. */
if( lpClockTable[i].iMclk == 0 ) {
RegInfo.bFreqFound = FXFALSE;
i=0;
} else {
RegInfo.bFreqFound = FXTRUE;
}
bN = lpClockTable[i].wN;
bM = lpClockTable[i].wM;
bL = lpClockTable[i].wL;
bFreqRange = lpClockTable[i].wFR;
/* Assign values to E8-EA... */
RegInfo.RegVals.E8 = bBypass +
(bPowerOff << 1) +
(bL << 2) +
(bFreqRange << 4) +
(bHighSpeed << 7);
RegInfo.RegVals.E9 = bM;
RegInfo.RegVals.EA = bN;
return(RegInfo);
#undef FN_NAME
} /* GetRegVals */
/*-------------------------------------------------------------------
Function: setmclk32
Date: 20-May-97
Implementor(s): someone from ALSC, ganked by dow
Library: Init Code for AT3D
Description:
This routine sets the memory clock for the AT3D chip. It was
shamelessly ganked out of the DirectDraw driver for
AT3D/Voodoo Rush.
Arguments:
Return:
FXTRUE if successful.
-------------------------------------------------------------------*/
static FxBool
initAT3DSetMClock(int iMclk, LPCOP at3dRegs)
{
#define FN_NAME "initAT3DSetMClock"
REGINFO RegInfo;
FxU8 oE8, oE9, oEA;
FxU8 nE8, nE9, nEA;
GDBG_INFO((80, "%s:\n", FN_NAME));
/* Get values for E8, E9, EA etc. based on iMclk. */
RegInfo = initAT3DGetRegVals(iMclk);
if(!RegInfo.bFreqFound)
return(FXFALSE);
/* Read in the current 3 Bytes starting at 0E8 */
oE8 = GET8AT3D(at3dRegs->MCLK_Ctrl);
oE9 = GET8AT3D(at3dRegs->MCLK_M);
oEA = GET8AT3D(at3dRegs->MCLK_N);
/*
** Set new values....
**
** Assign new E8-EA... (with L=3, and high speed bit set)
** This is done to avoid a temporary illegal setting of the mclk!
*/
nE8 = (oE8 | 0x8C);
nE9 = oE9;
nEA = oEA;
SETAT3D(at3dRegs->MCLK_Ctrl, nE8);
SETAT3D(at3dRegs->MCLK_M, nE9);
SETAT3D(at3dRegs->MCLK_N, nEA);
/*
** Assign new E8-EA... (with desired M and N values)
** This is done to avoid a temporary illegal setting of the mclk!
*/
nE8 = nE8;
nE9 = RegInfo.RegVals.E9;
nEA = RegInfo.RegVals.EA;
SETAT3D(at3dRegs->MCLK_Ctrl, nE8);
SETAT3D(at3dRegs->MCLK_M, nE9);
SETAT3D(at3dRegs->MCLK_N, nEA);
/* Assign new E8-EA... (with correct L value) */
nE8 = RegInfo.RegVals.E8;
nE9 = nE9;
nEA = nEA;
SETAT3D(at3dRegs->MCLK_Ctrl,nE8);
SETAT3D(at3dRegs->MCLK_M, nE9);
SETAT3D(at3dRegs->MCLK_N, nEA);
GDBG_INFO((80, "%s: Returning FXTRUE\n", FN_NAME));
return(FXTRUE);
#undef FN_NAME
} /* initAT3DSetMClock */
/*-------------------------------------------------------------------
Function: initAT3DWait
Date: 21-May-97
Implementor(s): dow
Library: Init Code for AT3D
Description:
Waits for the specified number of milliseconds. This works
because CLOCKS_PER_SEC is equal to 1000 in time.h;
Arguments:
Return:
Nothing ever.
-------------------------------------------------------------------*/
static void
initAT3DWait( FxI32 mSec)
{
#define FN_NAME "initAT3DWait"
clock_t t0, t1;
t0 = clock();
do {
t1 = clock();
} while ((t1 - t0) < mSec);
#undef FN_NAME
} /* initAT3DWait */
/*-------------------------------------------------------------------
Function: initAT3D2DIdle
Date: 21-May-97
Implementor(s): someone from ALSC, dow
Library: Init Code for AT3D
Description:
Waits for the AT3D chip to be idle;
Arguments:
Return:
Nothing ever.
-------------------------------------------------------------------*/
static void
initAT3D2DIdle(LPCOP at3dRegs)
{
#define FN_NAME "initAT3D2DIdle"
volatile FxU32 val;
while ((val = GETAT3D(at3dRegs->Extended_Status)) & EXT_STATUS_DWG_ENG_BUSY);
#undef FN_NAME
} /* initAT3D2DIdle */
/*-------------------------------------------------------------------
Function: initAT3DDisableMemoryRefresh
Date: 09-May-97
Implementor(s): someone from ALSC, dow
Library: Init Code for AT3D
Description:
Disables memory refresh on AT3D.
Notes:
Shamelessly ganked from the AT3D DDRAW code.
Arguments:
Return:
pointer to at3dHALData
-------------------------------------------------------------------*/
static void
initAT3DDisableMemoryRefresh(LPCOP at3dRegs)
{
#define FN_NAME "initAT3DDisableMemoryRefresh"
FxU32 vgaSeq, data;
FxU16 vgaOverride;
/* Make sure the 2D is not making any requests for memory */
initAT3D2DIdle(at3dRegs);
GDBG_INFO((80, "%s: Turning off video refresh\n", FN_NAME));
INP(SC_INDEX, vgaSeq);
OUTP(SC_INDEX, SC_CLOCKING_MODE);
INP(SC_INDEX, data);
data |= VGA_SEQUENCER_SCREEN_OFF;
OUTP(SC_DATA, data);
OUTP(SC_INDEX, vgaSeq);
GDBG_INFO((80, "%s: Turning off DRAM refresh\n", FN_NAME));
GDBG_INFO((80, "%s: VGAOverride\n", FN_NAME));
vgaOverride = GET16AT3D(at3dRegs->VGAOverride);
vgaOverride |= VGA_OVERRIDE_DISABLE_DRAM_REFRESH;
SETAT3D(at3dRegs->VGAOverride, vgaOverride);
#undef FN_NAME
} /* initAT3DDisableMemoryRefresh */
/*-------------------------------------------------------------------
Function: initAT3DEnableMemoryRefresh
Date: 09-May-97
Implementor(s): Someone from ALSC, dow
Library: Init Code for AT3D
Description:
Arguments:
Return:
pointer to at3dHALData
-------------------------------------------------------------------*/
static void
initAT3DEnableMemoryRefresh(LPCOP at3dRegs)
{
#define FN_NAME "initAT3DEnableMemoryRefresh"
FxU32 vgaSeq, data;
FxU16 vgaOverride;
GDBG_INFO((80, "%s: Turning on video refresh\n", FN_NAME));
INP(SC_INDEX, vgaSeq);
OUTP(SC_INDEX, SC_CLOCKING_MODE);
INP(SC_DATA, data);
data &= ~VGA_SEQUENCER_SCREEN_OFF;
OUTP(SC_DATA, data);
OUTP(SC_INDEX, vgaSeq);
GDBG_INFO((80, "%s: Turning on DRAM refresh\n", FN_NAME));
GDBG_INFO((80, "%s: VGAOverride\n", FN_NAME));
vgaOverride = GET16AT3D(at3dRegs->VGAOverride);
vgaOverride &= !VGA_OVERRIDE_DISABLE_DRAM_REFRESH;
SETAT3D(at3dRegs->VGAOverride, vgaOverride);
#undef FN_NAME
} /* initAT3DEnableMemoryRefresh */
/*
** Entry Points
*/
/*-------------------------------------------------------------------
Function: initAT3DGetHALData
Date: 09-May-97
Implementor(s): dow
Library: Init Code for AT3D
Description:
Arguments:
Return:
pointer to at3dHALData
-------------------------------------------------------------------*/
INITAT3DENTRY(initAT3DGetHALData, Init96HALData *, (void) )
{
#define FN_NAME "initAT3DGetHALData"
return &at3dHALData;
#undef FN_NAME
} /* initAT3DGetHALData */
/*-------------------------------------------------------------------
Function: initAT3DAperture
Date: 19-Feb-97
Implementor(s): dow
Library: Init Code for AT3D
Description:
Initialize rd pointers to access apertures
Arguments:
Return:
-------------------------------------------------------------------*/
INITAT3DENTRY(initAT3DAperture, FxBool , (InitRegisterDesc *rd) )
{
#define FN_NAME "initAT3DAperture"
FxBool
rVal = FXTRUE;
GDBG_INFO((80, "%s:\n", FN_NAME));
rd->hwDep.VG96RegDesc.partnerRegPtr =
&rd->hwDep.VG96RegDesc.baseAddress[AT3D_BASE >> 2];
GDBG_INFO((80, "%s: Setting partnerRegPtr to 0x%x\n", FN_NAME, rd->hwDep.VG96RegDesc.partnerRegPtr));
at3dRegPtr = (LPCOP) rd->hwDep.VG96RegDesc.partnerRegPtr;
rd->hwDep.VG96RegDesc.serialStatus = (FxU32 *) &at3dRegPtr->SerialInput;
GDBG_INFO((80, "%s: Setting serialStatus to 0x%x\n", FN_NAME, rd->hwDep.VG96RegDesc.serialStatus));
/* This is not important, but it might be tested for NULL somewhere */
rd->hwDep.VG96RegDesc.fifoApertureBase = rd->hwDep.VG96RegDesc.baseAddress;
GDBG_INFO((80, "%s: returning FXTRUE\n", FN_NAME));
return rVal;
#undef FN_NAME
} /* initAT3DAperture */
INITAT3DENTRY(initAT3DSetVideo, FxBool, (GrScreenResolution_t res, GrScreenRefresh_t refresh, FxU32 *xr, FxU32 *yr ))
{
#define FN_NAME "initAT3DSetVideo"
#if defined(__DOS32__)
union REGS r, rOut;
#endif
FxBool
fixVsync = FXFALSE,
rv = FXTRUE;
GDBG_INFO((80, "%s: \n", FN_NAME));
#if defined(INIT_ACCESS_DIRECT) && defined( __DOS32__ )
/* Wait half a sec */
initAT3DWait( 100);
#endif
switch( res ) {
case GR_RESOLUTION_320x200:
#if defined(__DOS32__)
/* Set up VESA Mode 0x136 - 320x200x16 */
GDBG_INFO((80, "initAT3DSetVideo: Setting up VESA mode 320x200x16\n"));
r.w.ax = 0x4f02;
r.w.bx = 0x136;
int386( 0x10, &r, &rOut );
#endif
*xr = 320;
*yr = 200;
rv = FXTRUE;
break;
case GR_RESOLUTION_320x240:
#if defined(__DOS32__)
/* Set up VESA Mode 0x137 - 320x240x16 */
GDBG_INFO((80, "initAT3DSetVideo: Setting up VESA mode 320x240x16\n"));
r.w.ax = 0x4f02;
r.w.bx = 0x137;
int386( 0x10, &r, &rOut );
#endif
*xr = 320;
*yr = 240;
rv = FXTRUE;
break;
case GR_RESOLUTION_512x384:
fixVsync = FXTRUE;
#if defined(__DOS32__)
/* Set up VESA Mode 0x139 - 512x384x16 */
GDBG_INFO((80, "initAT3DSetVideo: Setting up VESA mode 512x384x16\n"));
r.w.ax = 0x4f02;
r.w.bx = 0x139;
int386( 0x10, &r, &rOut );
#endif
*xr = 512;
*yr = 384;
rv = FXTRUE;
break;
case GR_RESOLUTION_640x400:
fixVsync = FXTRUE;
rv = FXTRUE;
break;
case GR_RESOLUTION_640x480:
#if defined(__DOS32__)
/* Set up VESA Mode 0x111 - 640x480x16 */
GDBG_INFO((80, "initAT3DSetVideo: Setting up VESA mode 640x480x16\n"));
r.w.ax = 0x4f02;
r.w.bx = 0x111;
int386( 0x10, &r, &rOut );
#endif
*xr = 640;
*yr = 480;
rv = FXTRUE;
break;
#ifdef H3D
case GR_RESOLUTION_640x240_AUTOFLIPPED:
*xr = 640;
*yr = 480;
rv = FXTRUE;
break;
case GR_RESOLUTION_800x300_AUTOFLIPPED:
*xr = 800;
*yr = 600;
rv = FXTRUE;
break;
#endif
case GR_RESOLUTION_800x600:
fixVsync = FXTRUE;
#if defined(__DOS32__)
/* Set up VESA Mode 0x114 - 800x600x16 */
GDBG_INFO((80, "initAT3DSetVideo: Setting up VESA mode 800x600x16\n"));
r.w.ax = 0x4f02;
r.w.bx = 0x114;
int386( 0x10, &r, &rOut );
#endif
*xr = 800;
*yr = 600;
rv = FXTRUE;
break;
default:
rv = FXFALSE;
break;
}
if (rv) {
/* For some reason, AT3D reverses the polarity of VSYNC for
512x384 & 800x600, so we need to fix that (NOTE: this code also
sets the polarity of HSYNC, hence c0 instead of 80)
See page 342 of _Programmers_Guide_To_The_EGA_And_VGA_Cards, 2nd
Ed. by Richard F. Ferraro for details on the Miscellaneous Output
Register.
*/
if (fixVsync) {
FxU16 vgaMiscOutput;
GDBG_INFO((80, "initAT3DSetVideo: Setting VSYNC Polarity\n"));
INP(VGA_MISC_OUTPUT_READ, vgaMiscOutput);
vgaMiscOutput |= 0xc0;
OUTP(VGA_MISC_OUTPUT_WRITE, vgaMiscOutput);
}
}
if (myGetenv("INIT96_AT3D_VSYNC_END")) {
FxU16 vSyncEnd = 3;
GDBG_INFO((80, "%s: Setting VSync End\n", FN_NAME));
vSyncEnd = atoi(myGetenv("INIT96_AT3D_VSYNC_END"));
CRTC_SET(CC_VSYNC_END, vSyncEnd);
}
if (myGetenv("INIT96_AT3D_VSYNC_START")) {
FxU16 vSyncStart = 0;
GDBG_INFO((80, "%s: Setting VSync Start\n", FN_NAME));
vSyncStart = atoi(myGetenv("INIT96_AT3D_VSYNC_START"));
CRTC_SET(CC_VSYNC_START, vSyncStart);
}
GDBG_INFO((80, "%s: returning %s\n", FN_NAME, rv?"FXTRUE":"FXFALSE"));
return rv;
#undef FN_NAME
} /* initAT3DSetVideo */
/*-------------------------------------------------------------------
Function: initAT3DEnableRegs
Date: 07-Feb-97
Implementor(s): dow
Library: Init Code for AT3D
Description:
Do all setup necessary to enable direct writes to JR Space
Arguments:
rd - pointer to register description
Return:
FXTRUE if success, FXFALSE if Failure
-------------------------------------------------------------------*/
INITAT3DENTRY(initAT3DEnableRegs,FxBool,(InitRegisterDesc *rd))
{
#define FN_NAME "initAT3DEnableRegs"
#if !defined( __WIN32__) || defined(INIT_ACCESS_DIRECT)
LPCOP
at3dRegs = (LPCOP) rd->hwDep.VG96RegDesc.partnerRegPtr;
FxU8 tmp;
GDBG_INFO((80, "%s:\n", FN_NAME));
GDBG_INFO((80, "%s: Enabling writes to AT3D registers\n", FN_NAME));
GDBG_INFO((80, "%s: Setting VGA sequencer to point at flat model control\n", FN_NAME));
GDBG_INFO((80, "%s: 6MB Memory Aperture\n", FN_NAME));
SEQU_SET(0x1c, 0x27);
GDBG_INFO((80, "%s: VGA sequencer to remap control\n", FN_NAME));
GDBG_INFO((80, "%s: Map Control Registers into end of Flat Space\n", FN_NAME));
SEQU_SET(0x1b, 0x24);
GDBG_INFO((80, "%s: Waiting for 2D Idle", FN_NAME));
initAT3D2DIdle(at3dRegs);
/*
VG96_MCLKFrequency=50
DualCycleThreshold=65
*/
GDBG_INFO((80, "%s: Setting Graphics clock to 50MHz\n", FN_NAME));
/* FIXME!! Add a myGetenv for SST96_MEMCLOCK */
initAT3DSetMClock(50, at3dRegs);
/* Wait two VSYNCs in order to give a few milliseconds for the
on-board MCLK VCO to settle. (LouP) */
while(AT3D_IN_VSYNC);
while(!AT3D_IN_VSYNC);
while(AT3D_IN_VSYNC);
while(!AT3D_IN_VSYNC);
GDBG_INFO((80, "%s: Turning on PUMA\n", FN_NAME));
GDBG_INFO((80, "%s: UMAControl\n", FN_NAME));
SETAT3D(at3dRegs->UMAControl, PUMA_CONTROL_ON);
GDBG_INFO((80, "%s: GPIOControl\n", FN_NAME));
tmp = GET8AT3D(at3dRegs->GPIOControl);
tmp |= GPIO_PUMA_SRESET_N;
SETAT3D(at3dRegs->GPIOControl, 0xd0); /* tmp */
GDBG_INFO((80, "%s: GPIODirection\n", FN_NAME));
tmp = GET8AT3D(at3dRegs->GPIODirection);
tmp |= GPIO_PUMA_SRESET_N;
SETAT3D(at3dRegs->GPIODirection, 0x10);
GDBG_INFO((80, "%s: GPIOLevel\n", FN_NAME));
tmp = GET8AT3D(at3dRegs->GPIOLevel);
tmp |= GPIO_PUMA_SRESET_N; /* active low signal */
SETAT3D(at3dRegs->GPIOLevel, tmp);
GDBG_INFO((80, "%s: FeatureCnctrDisable\n", FN_NAME));
SETAT3D(at3dRegs->FeatureCnctrDisable, 0x80);
GDBG_INFO((80, "%s: GPIOLevel\n", FN_NAME));
SETAT3D(at3dRegs->GPIOLevel, 0x10);
GDBG_INFO((80, "%s: GenFeatureCnctrCtl\n", FN_NAME));
SETAT3D(at3dRegs->GenFeatureCnctrCtl, 0x10);
GDBG_INFO((80, "%s: Setting up AT3D Pixel FIFO Request Points\n", FN_NAME));
GDBG_INFO((80, "%s: HiReqMiss\n", FN_NAME));
SETAT3D(at3dRegs->HiReqMiss, 0x04);
GDBG_INFO((80, "%s: HiReqNoMiss\n", FN_NAME));
SETAT3D(at3dRegs->HiReqNoMiss, 0x04);
GDBG_INFO((80, "%s: LoReq\n", FN_NAME));
SETAT3D(at3dRegs->LoReq, 0x1b);
GDBG_INFO((80, "%s: Enabling FBI Jr. Space\n", FN_NAME));
GDBG_INFO((80, "%s: ExtendedMemoryEnable\n", FN_NAME));
SETAT3D(at3dRegs->ExtendedMemoryEnable, 0x04);
GDBG_INFO((80, "%s: GPIOControl", FN_NAME));
SETAT3D(at3dRegs->GPIOControl, 0x03);
GDBG_INFO((80, "%s: returning FXTRUE\n", FN_NAME));
#endif /* __WIN32__ */
return FXTRUE;
#undef FN_NAME
} /* initAT3DEnableRegs */
/* FIXME!!! jdt - puma/ram timing fixes need to go here */
INITAT3DENTRY(initAT3DDisableRegs,FxBool,(InitRegisterDesc *rd))
{
#define FN_NAME "initAT3DDisableRegs"
int i,j;
#if !defined( __WIN32__) || defined(INIT_ACCESS_DIRECT)
FxU32 status;
FxU8
gpioControl, gpioDirection, gpioLevel;
#endif
#if 0 /* Fixme! delete after 2.4 */
LPCOP
lAT3DRegPtr = (LPCOP) rd->hwDep.VG96RegDesc.partnerRegPtr;
#endif
GDBG_INFO((80, "%s\n", FN_NAME));
#if !defined( __WIN32__) || defined(INIT_ACCESS_DIRECT)
GDBG_INFO((80, "%s: Waiting for 3D Idle", FN_NAME));
do {
status = GETAT3D(*rd->hwDep.VG96RegDesc.serialStatus);
} while (status & 1);
GDBG_INFO((80, "%s: Disabling PUMA\n", FN_NAME));
GDBG_INFO((80, "%s: Disabling Memory Refresh\n", FN_NAME));
initAT3DDisableMemoryRefresh(at3dRegPtr);
GDBG_INFO((80, "%s: Waiting for %d msec\n", FN_NAME, GINTERVAL));
initAT3DWait(GINTERVAL);
SETAT3D(at3dRegPtr->UMAControl, PUMA_CONTROL_OFF);
GDBG_INFO((80, "%s: GPIOControl\n", FN_NAME));
gpioControl = GET8AT3D(at3dRegPtr->GPIOControl);
gpioControl |= GPIO_PUMA_SRESET_N;
SETAT3D(at3dRegPtr->GPIOControl, gpioControl);
GDBG_INFO((80, "%s: GPIODirection\n", FN_NAME));
gpioDirection = GET8AT3D(at3dRegPtr->GPIODirection);
gpioDirection |= GPIO_PUMA_SRESET_N;
SETAT3D(at3dRegPtr->GPIODirection, gpioDirection);
GDBG_INFO((80, "%s: GPIOLevel\n", FN_NAME));
gpioLevel = GET8AT3D(at3dRegPtr->GPIOLevel);
gpioLevel &= ~ GPIO_PUMA_SRESET_N;
SETAT3D(at3dRegPtr->GPIOLevel, gpioLevel);
GDBG_INFO((80, "%s: Enabling Memory refresh\n", FN_NAME));
initAT3DEnableMemoryRefresh(at3dRegPtr);
#endif
/* Undo tile programming regardless */
if ( tiling ) {
GDBG_INFO((80, "%s: Restoring tile registers\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
regWindowSequenceControlSave);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidDataOffset,
regWindow0BaseAddressSave);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorHor,
regWindow0StretchFactorHor1Save);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetHor,
regWindow0StretchFactorHor2Save);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer,
regWindow0StretchFactorVer1Save);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetVer,
regWindow0StretchFactorVer2Save);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidControl,
regWindow0ControlSave);
GDBG_INFO((80, "Restoring all tiles\n"));
for (i=0, j=0; i<MAX_TILES; i++) {
int k;
volatile FxU16 *tileRegPtr = (FxU16 *) &at3dRegPtr->TileRegsSet[i];
for (k=0; k<8; k++, j++) {
SETAT3D(tileRegPtr[k], tileRegSave[j]);
}
} /* end for i */
tiling = 0;
}
GDBG_INFO((80, "%s: returning FXTRUE\n", FN_NAME));
return FXTRUE;
#undef FN_NAME
} /* initAT3DDisableRegs */
/*-------------------------------------------------------------------
Function: initAT3DUseTiles
Date: 07-Feb-97 (Moved into initat3d from init96)
Implementor(s): jdt, paik, murali, dow
Library: Init Code for AT3D
Description:
Arguments:
frontBuffer: FB offset of front buffer
backBuffer: FB offset of back buffer
strideInBytes: Tile width in bytes
Return:
1 if successful
-------------------------------------------------------------------*/
#ifdef H3D
// save framebufferinfo for enabling/disabling h3d
static InitRegisterDesc *h3drd=0;
static FxU32 h3dbuffers[3], h3dnBuffers, h3dstrideInBytes, h3dWidth, h3dHeight, h3dleft, h3dright, h3dbottom;
INITAT3DENTRY(initAT3DUseTiles, int, (InitRegisterDesc *rd,
FxU32 *buffers,
FxU32 nBuffers,
FxU32 strideInBytes,
FxU32 Width, FxU32 Height,
FxU32 PageFlipping))
#else
INITAT3DENTRY(initAT3DUseTiles, int, (InitRegisterDesc *rd,
FxU32 *buffers,
FxU32 nBuffers,
FxU32 strideInBytes,
FxU32 Width, FxU32 Height))
#endif
{
#define FN_NAME "initAT3DUseTiles"
FxU32 left = 0;
FxU32 right = Width;
FxU32 bottom = Height-1;
unsigned int i, j, ntimes;
GDBG_INFO((80, "%s:\n", FN_NAME));
GDBG_INFO((80, "%s: Setting up overlays!\n", FN_NAME));
#ifdef H3D
h3drd = rd;
for(i=0;i<nBuffers;i++)
h3dbuffers[i]=buffers[i];
h3dnBuffers=nBuffers, h3dstrideInBytes=strideInBytes, h3dWidth=Width, h3dHeight=Height;
h3dleft = left, h3dright = right, h3dbottom = bottom;
#endif
tiling = 1;
#ifdef GDBG_INFO_ON
for (i = 0; i < nBuffers; i++)
GDBG_INFO((80, "%s: Buffer %d = 0x%x\n", FN_NAME, i, buffers[i]));
#endif
GDBG_INFO((80, "%s: Saving all tiles\n", FN_NAME));
for (i=0, j=0; i<MAX_TILES; i++) {
int k;
volatile FxU16 *tileRegPtr = (FxU16 *) &at3dRegPtr->TileRegsSet[i];
for (k=0; k<8; k++) {
tileRegSave[j++] = GET16AT3D(tileRegPtr[k]);
}
} /* end for i */
GDBG_INFO((80, "%s: Zeroing out all tiles\n", FN_NAME));
for (i=0; i<MAX_TILES; i++) {
int k;
volatile FxU16 *tileRegPtr = (FxU16 *) &at3dRegPtr->TileRegsSet[i];
for (k=0; k<8; k++) {
SETAT3D(tileRegPtr[k], 0);
}
} /* end for i */
/*---------------------------------
VIDEO WINDOW
---------------------------------*/
/* Set up tile sequence control register
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 - single buffer
[9] - swap buffer on 3D swap signal - 0x1 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "%s: SEtting up tile sequence control register\n", FN_NAME));
{
int a = 0, b = 0;
ntimes = 0;
while( !( a && !b ) ) { /* pass on falling edge of VRETRACE_ACTIVE */
a = b;
b = _inp( VGA_INPUT_STATUS_1C ) & VIS1C_VERTICAL_RETRACE_ACTIVE;
if (ntimes++ > 1000) {
GDBG_INFO((80, "%s: Bailing out after %d checks of VRETRACE check\n", FN_NAME, ntimes));
break;
}
}
}
while (GET16AT3D(at3dRegPtr->CurrentVerticalPosition) > 20) {
if (ntimes++ > 1000) {
GDBG_INFO((80, "%s: Bailing out after %d checks of register 0x1fa\n", FN_NAME, ntimes));
break;
}
}
GDBG_INFO((80, "%s, Setting Window Sequence Control Register to %x\n", FN_NAME, 0x0610));
regWindow0ControlSave =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl);
#ifdef H3D
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping?(FxU16)(0x1610):(FxU16)(0x0610)));
#else
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(FxU16)(0x0610));
#endif
/* 1: video data stride
* Set stride of data buffer in DWORDS
*/
GDBG_INFO((80, "%s: Setting Window 0 Video Data Stride to 0x%x\n", FN_NAME, strideInBytes >> 2));
regWindow0BaseAddressSave =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidDataOffset);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidDataOffset,
(FxU16)(strideInBytes>>2));
/* 2: video scale factor horizontal
* A value of zero represents a factor of 1.0
*/
GDBG_INFO((80, "%s: Setting Window 0 Horizontal Video Scale Factor to 0x%x \n", FN_NAME, 0x0000));
regWindow0StretchFactorHor1Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorHor);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorHor, (FxU16)0x0000);
/* 3: video offset factor horizontal
* 0xFFF - 0x0 * (X) & 0xFFFh = 0xFFF - set for no scale
*/
GDBG_INFO((80, "%s: Setting Window 0 Horizontal Video Offset Factor to 0x%x\n", FN_NAME, 0xfff));
regWindow0StretchFactorHor2Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetHor);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetHor, (FxU16)0xFFF);
/* 4: video scale factor vertical
* A value of zero represents a factor of 1.0
*/
GDBG_INFO((80, "%s: Setting Window 0 Vertical Video Scale Factor to 0x%x\n", FN_NAME, 0x0000));
#if 0 /* Fixme I think this line is bogus, remove after 2.4 !!! XXX ??? */
at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer = (FxU16)0x0000;
#endif
regWindow0StretchFactorVer1Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer);
#ifdef H3D
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer, (PageFlipping?(FxU16)0x07FA:(FxU16)0x0000));
#else
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer, (FxU16)0x0000);
#endif
/* 5: video offset factor vertical
* 0xFFF - 0x0 * (X) & 0xFFFh = 0xFFF - set for no scale
*/
GDBG_INFO((80, "%s: Setting Window 0 Vertical Video Offset Factor \n", FN_NAME, 0xfff));
regWindow0StretchFactorVer2Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetVer);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetVer, (FxU16)0xFFF);
/* 6: control reg, pixel depth, window format, enable bits
[14] - Chromakey - 0x0 - Disable
[13] - Reservered - 0x0
[12] - Smoothing - 0x0 - disable
[11] - VStretch lerp - 0x0 - disable
[10] - HStretch lerp - 0x0 - disable
[9] - Stretch - 0x0 - disable
[8] - YUV-RGB - 0x0 - disable
[7] - Reservered - 0x0
[6:4] - color format - 0x2 - RGB
[3:1] - Pixel Depth - 0x5 - 16 BPP
[0] - enable window - 0x1 - enable
*/
GDBG_INFO((80, "%s: Window 0 Control to 0x%x\n", FN_NAME, 0x20 | 0xa | 0x1));
regWindow0ControlSave =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidControl);
#ifdef H3D
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidControl, (PageFlipping ? (0x0200|0x0020|0x000A|0x0001) : (0x0020|0x000A|0x0001)));
#else
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidControl,
0x0020 | 0x000A | 0x0001);
#endif
#ifdef H3D
/*---------------------------------
CONFIGURE TILES 0, 1, 2 & 3
---------------------------------*/
for (i=0; i < nBuffers*2; i++) {
FxU32 buf;
if (PageFlipping) {
buf = buffers[i>>1];
if (i & 1) // bottom half of page
buf += (strideInBytes*((Height)>>1));
} else {
buf = buffers[i];
if (i == nBuffers) break;
}
#else
/*---------------------------------
CONFIGURE TILES
---------------------------------*/
for (i=0; i < nBuffers; i++) {
FxU32
buf = buffers[i];
#endif
GDBG_INFO((80, "%s: Configuring tile %d ======================\n", FN_NAME, i));
/* display position left register
* Sets the leftmost column of pixels in the tile
* this column lies inside the tile
* [10:0] - integer column - 0
*/
GDBG_INFO((80, "%s: Setting Tile %d Left Register to 0x%x\n", FN_NAME, i, left));
SETAT3D(at3dRegPtr->TileRegsSet[i].DisplayPositionLeft, (FxU16)left);
/* display position right register
* sets the rightmost column of pixels in the tile
* this column lies outside the tile
* [10:0] - integer column - 640
*/
GDBG_INFO((80, "%s: Setting Tile %d Right Register to 0x%x\n", FN_NAME, i, right));
SETAT3D(at3dRegPtr->TileRegsSet[i].DisplayPositionRight, (FxU16)right);
/* display position bottom register
* sets the bottom row of pixels in the tile
* this row of pixels lies inside the tile
* [10:0] - bottomost tile - 480-1;
*/
GDBG_INFO((80, "%s: Setting Tile %d Bottom Register to 0x%x\n", FN_NAME, i, bottom));
SETAT3D(at3dRegPtr->TileRegsSet[i].DisplayPositionBottom, (FxU16)bottom);
/* tile data width register
* sets the width of the source tile data, not the display
* [10:0] - width in pixels( not bytes ) - 640
*/
GDBG_INFO((80, "%s: Setting Tile %d Data Width register to 0x%x\n", FN_NAME, i, strideInBytes >> 1));
SETAT3D(at3dRegPtr->TileRegsSet[i].DataWidth, (FxU16)(strideInBytes>>1));
/* tile data location
* sets the address in bytes of the top-left corner
* of the video tile data where it is stored, not the
* display window.
* [21:0] - byte address - offset - 0
*/
GDBG_INFO((20, "%s: Setting Tile %d Data location to 0x%x\n", FN_NAME, i, buf));
SETAT3D(at3dRegPtr->TileRegsSet[i].DataLocationLo, (FxU16)(buf & 0xFFFF));
SETAT3D(at3dRegPtr->TileRegsSet[i].DataLocationHi,
(FxU8)((buf >> 16) & 0xFF));
/* tile control register
* [4] - rightmost tile - 0x1 - only
* [3] - reserved - 0
* [2:0] - vWindow select - 0x1 - window 1
*/
GDBG_INFO((80, "%s: Setting Tile %d Control Register to 0x%x\n", FN_NAME, i, 0x11));
SETAT3D(at3dRegPtr->TileRegsSet[i].Control, 0x11);
} /* end for i */
/* set window sequence control to disable tile swap on 3d request
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 - single buffer
[9] - swap buffer on 3D swap signal - 0x0 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
#ifdef H3D
GDBG_INFO((80, "%s: Disabling swap on 3d request\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping ? (FxU16)(0x1410) : (FxU16)(0x0410)));
#else
GDBG_INFO((80, "%s: Disabling swap on 3d request\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(FxU16)(0x0410));
#endif
/* set window sequence control to single tile
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 - single buffer
[9] - swap buffer on 3D swap signal - 0x0 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
#ifdef H3D
GDBG_INFO((80, "%s: Setting window sequence control to single tile\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping ? (FxU16)(0x1010) : (FxU16)(0x0010)));
#else
GDBG_INFO((80, "%s: Setting Tile Sequence Control to single tile\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(FxU16)(0x0010));
#endif
/* set window sequence control to enable tile swap on 3d request
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x0 - single buffer
[9] - swap buffer on 3D swap signal - 0x1 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
#ifdef H3D
GDBG_INFO((80, "%s: Enabling swap on 3d request\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping ? (FxU16)(0x1210) : (FxU16)(0x0210)));
#else
GDBG_INFO((80, "%s: Enabling swap on 3d request\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(FxU16)(0x0210));
#endif
GDBG_INFO((80, "%s: Enabling %s buffering\n", FN_NAME,
nBuffers > 2 ? "triple" : "double"));
/* set window sequence control to enable double buffering
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 or 0x2
(double or triple buffer, respectively)
[9] - swap buffer on 3D swap signal - 0x1 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "******* nBuffers = %d\n", nBuffers));
#ifdef H3D
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(
((FxU16)(0x0010)) |
(PageFlipping ? (FxU16)(0x1000) : (FxU16)(0x0000)) |
((nBuffers>2) ? (FxU16)(0x0a00) : (FxU16)(0x0600))
));
#else
if (nBuffers > 2) {
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(FxU16)(0x0a10));
} else
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(FxU16)(0x0610));
#endif
/* wait a few vsyncs */
/* VVVVV--WTF? (CHD) */
for ( i = 0; i < 1; i++ ) {
int a = 0, b = 0;
ntimes = 0;
while( !( a && !b ) ) { /* pass on falling edge of VRETRACE_ACTIVE */
if (ntimes >= 1000) {
GDBG_INFO((80, "Bailing out of vsync check after %d tries\n", FN_NAME, ntimes));
break;
}
a = b;
b = _inp( VGA_INPUT_STATUS_1C ) & VIS1C_VERTICAL_RETRACE_ACTIVE;
}
}
GDBG_INFO((80, "%s: returning %d\n", FN_NAME, 1));
return 1;
#undef FN_NAME
} /* initAT3DUseTiles */
/*-------------------------------------------------------------------
Function: initAT3DGetInfo
Date: 28-Apr-97
Implementor(s): pgj
Library: Init Code for AT3D
Description:
get information about at3d
Arguments:
info - pointer to info struct
Return:
FXTRUE if success, FXFALSE if Failure
-------------------------------------------------------------------*/
INITAT3DENTRY(initAT3DGetInfo,FxBool,(VG96Info *info))
{
#define FN_NAME "initAT3DGetInfo"
#ifdef __DOS32__
union REGS inR, outR;
#endif /* __DOS32__ */
FxU32 bytes;
GDBG_INFO((80, "%s:\n", FN_NAME));
info->vgaChip = 0;
info->vg96Rev = 0;
#ifdef __DOS32__
inR.w.ax = 0x3002;
int386(0x10, &inR, &outR);
bytes = outR.h.al;
#else
#ifdef __linux__
bytes = myGetenv("SST_VRAM_4MB") ? 0x40 : 0x20;
#else
#define PROMOTIONESCAPE 0x80DE
{
HDC hdc = GetDC(GetActiveWindow());
bytes = ExtEscape(hdc, PROMOTIONESCAPE, sizeof("MS"), "MS", 0, NULL);
}
#endif
#endif /* __DOS32__ */
bytes <<= 16;
info->vg96Ram = bytes;
info->nTFX = 1;
info->tfxRev = 1;
info->tfxRam = 2;
GDBG_INFO((135, "%s: %8.8x bytes\n", FN_NAME, bytes));
return FXTRUE;
#undef FN_NAME
} /* initAT3DGetInfo */
#ifdef H3D
/*-------------------------------------------------------------------
Function: initAT3DSetTiles
Date: 28-Apr-97
Implementor(s):
Library: Init Code for AT3D
Description:
get information about at3d
Arguments:
info - pointer to info struct
Return:
FXTRUE if success, FXFALSE if Failure
-------------------------------------------------------------------*/
void initAT3DSetTiles(FxU32 PageFlipping, FxU32 nBuffers)
{
#define FN_NAME "initAT3DSetTiles"
FxU32 i, ntimes;
if (!h3drd) return; // not inited yet
#ifdef GDBG_INFO_ON
for (i = 0; i < nBuffers; i++)
GDBG_INFO((80, "%s: Buffer %d = 0x%x\n", FN_NAME, i, h3dbuffers[i]));
#endif
GDBG_INFO((80, "%s: Zeroing out all tiles\n", FN_NAME));
for (i=0; i<MAX_TILES; i++) {
int k;
volatile FxU16 *tileRegPtr = (FxU16 *) &at3dRegPtr->TileRegsSet[i];
for (k=0; k<8; k++) {
SETAT3D(tileRegPtr[k], 0);
}
} /* end for i */
/*---------------------------------
VIDEO WINDOW
---------------------------------*/
/* Set up tile sequence control register
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 - single buffer
[9] - swap buffer on 3D swap signal - 0x1 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "%s: SEtting up tile sequence control register\n", FN_NAME));
{
int a = 0, b = 0;
ntimes = 0;
while( !( a && !b ) ) { /* pass on falling edge of VRETRACE_ACTIVE */
a = b;
b = _inp( VGA_INPUT_STATUS_1C ) & VIS1C_VERTICAL_RETRACE_ACTIVE;
if (ntimes++ > 1000) {
GDBG_INFO((80, "%s: Bailing out after %d checks of VRETRACE check\n", FN_NAME, ntimes));
break;
}
}
}
while (GET16AT3D(at3dRegPtr->CurrentVerticalPosition) > 20) {
if (ntimes++ > 1000) {
GDBG_INFO((80, "%s: Bailing out after %d checks of register 0x1fa\n", FN_NAME, ntimes));
break;
}
}
GDBG_INFO((80, "%s, Setting Window Sequence Control Register to %x\n", FN_NAME, 0x0610));
regWindow0ControlSave =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping?(FxU16)(0x1610):(FxU16)(0x0610)));
/* 1: video data stride
* Set stride of data buffer in DWORDS
*/
GDBG_INFO((80, "%s: Setting Window 0 Video Data Stride to 0x%x\n", FN_NAME, h3dstrideInBytes >> 2));
regWindow0BaseAddressSave =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidDataOffset);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidDataOffset,
(FxU16)(h3dstrideInBytes>>2));
/* 2: video scale factor horizontal
* A value of zero represents a factor of 1.0
*/
GDBG_INFO((80, "%s: Setting Window 0 Horizontal Video Scale Factor to 0x%x \n", FN_NAME, 0x0000));
regWindow0StretchFactorHor1Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorHor);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorHor, (FxU16)0x0000);
/* 3: video offset factor horizontal
* 0xFFF - 0x0 * (X) & 0xFFFh = 0xFFF - set for no scale
*/
GDBG_INFO((80, "%s: Setting Window 0 Horizontal Video Offset Factor to 0x%x\n", FN_NAME, 0xfff));
regWindow0StretchFactorHor2Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetHor);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetHor, (FxU16)0xFFF);
/* 4: video scale factor vertical
* A value of zero represents a factor of 1.0
*/
GDBG_INFO((80, "%s: Setting Window 0 Vertical Video Scale Factor to 0x%x\n", FN_NAME, 0x0000));
regWindow0StretchFactorVer1Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleFactorVer, (PageFlipping?(FxU16)0x07FA:(FxU16)0x0000));
/* 5: video offset factor vertical
* 0xFFF - 0x0 * (X) & 0xFFFh = 0xFFF - set for no scale
*/
GDBG_INFO((80, "%s: Setting Window 0 Vertical Video Offset Factor \n", FN_NAME, 0xfff));
regWindow0StretchFactorVer2Save =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetVer);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidScaleOffsetVer, (FxU16)0xFFF);
/* 6: control reg, pixel depth, window format, enable bits
[14] - Chromakey - 0x0 - Disable
[13] - Reservered - 0x0
[12] - Smoothing - 0x0 - disable
[11] - VStretch lerp - 0x0 - disable
[10] - HStretch lerp - 0x0 - disable
[9] - Stretch - 0x0 - disable
[8] - YUV-RGB - 0x0 - disable
[7] - Reservered - 0x0
[6:4] - color format - 0x2 - RGB
[3:1] - Pixel Depth - 0x5 - 16 BPP
[0] - enable window - 0x1 - enable
*/
GDBG_INFO((80, "%s: Window 0 Control to 0x%x\n", FN_NAME, 0x20 | 0xa | 0x1));
regWindow0ControlSave =
GET16AT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidControl);
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].VidControl, (PageFlipping ? (0x0200|0x0020|0x000A|0x0001) : (0x0020|0x000A|0x0001)));
/*---------------------------------
CONFIGURE TILES 0, 1, 2 & 3
---------------------------------*/
for (i=0; i < nBuffers*2; i++) {
FxU32 buf;
if (PageFlipping) {
buf = h3dbuffers[i>>1];
if (i & 1) // bottom half of page
buf += (h3dstrideInBytes*((h3dHeight)>>1));
} else {
buf = h3dbuffers[i];
if (i == nBuffers) break;
}
GDBG_INFO((80, "%s: Configuring tile %d ======================\n", FN_NAME, i));
/* display position left register
* Sets the leftmost column of pixels in the tile
* this column lies inside the tile
* [10:0] - integer column - 0
*/
GDBG_INFO((80, "%s: Setting Tile %d Left Register to 0x%x\n", FN_NAME, i, h3dleft));
SETAT3D(at3dRegPtr->TileRegsSet[i].DisplayPositionLeft, (FxU16)h3dleft);
/* display position right register
* sets the rightmost column of pixels in the tile
* this column lies outside the tile
* [10:0] - integer column - 640
*/
GDBG_INFO((80, "%s: Setting Tile %d Right Register to 0x%x\n", FN_NAME, i, h3dright));
SETAT3D(at3dRegPtr->TileRegsSet[i].DisplayPositionRight, (FxU16)h3dright);
/* display position bottom register
* sets the bottom row of pixels in the tile
* this row of pixels lies inside the tile
* [10:0] - bottomost tile - 480-1;
*/
GDBG_INFO((80, "%s: Setting Tile %d Bottom Register to 0x%x\n", FN_NAME, i, h3dbottom));
SETAT3D(at3dRegPtr->TileRegsSet[i].DisplayPositionBottom, (FxU16)h3dbottom);
/* tile data width register
* sets the width of the source tile data, not the display
* [10:0] - width in pixels( not bytes ) - 640
*/
GDBG_INFO((80, "%s: Setting Tile %d Data Width register to 0x%x\n", FN_NAME, i, h3dstrideInBytes >> 1));
SETAT3D(at3dRegPtr->TileRegsSet[i].DataWidth, (FxU16)(h3dstrideInBytes>>1));
/* tile data location
* sets the address in bytes of the top-left corner
* of the video tile data where it is stored, not the
* display window.
* [21:0] - byte address - offset - 0
*/
GDBG_INFO((20, "%s: Setting Tile %d Data location to 0x%x\n", FN_NAME, i, buf));
SETAT3D(at3dRegPtr->TileRegsSet[i].DataLocationLo, (FxU16)(buf & 0xFFFF));
SETAT3D(at3dRegPtr->TileRegsSet[i].DataLocationHi,
(FxU8)((buf >> 16) & 0xFF));
/* tile control register
* [4] - rightmost tile - 0x1 - only
* [3] - reserved - 0
* [2:0] - vWindow select - 0x1 - window 1
*/
GDBG_INFO((80, "%s: Setting Tile %d Control Register to 0x%x\n", FN_NAME, i, 0x11));
SETAT3D(at3dRegPtr->TileRegsSet[i].Control, 0x11);
} /* end for i */
/* set window sequence control to disable tile swap on 3d request
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 - single buffer
[9] - swap buffer on 3D swap signal - 0x0 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "%s: Disabling swap on 3d request\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping ? (FxU16)(0x1410) : (FxU16)(0x0410)));
/* set window sequence control to single tile
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 - single buffer
[9] - swap buffer on 3D swap signal - 0x0 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "%s: Setting window sequence control to single tile\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping ? (FxU16)(0x1010) : (FxU16)(0x0010)));
/* set window sequence control to enable tile swap on 3d request
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x0 - single buffer
[9] - swap buffer on 3D swap signal - 0x1 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "%s: Enabling swap on 3d request\n", FN_NAME));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl, (PageFlipping ? (FxU16)(0x1210) : (FxU16)(0x0210)));
GDBG_INFO((80, "%s: Enabling %s buffering\n", FN_NAME,
nBuffers > 2 ? "triple" : "double"));
/* set window sequence control to enable double buffering
[12] - stereo enable - 0x0 - disable
[11:10] - buffercount - 0x1 or 0x2
(double or triple buffer, respectively)
[9] - swap buffer on 3D swap signal - 0x1 - enable
[8] - buffer swap using TV input - 0x0 - disable
[7:4] - tile sequence length - 0x1 - magic
[3:0] - tile sequence base - 0x0 - magic
*/
GDBG_INFO((80, "******* nBuffers = %d\n", nBuffers));
SETAT3D(at3dRegPtr->V2.VidWindowV2Set[0].TileSequenceControl,
(
((FxU16)(0x0010)) |
(PageFlipping ? (FxU16)(0x1000) : (FxU16)(0x0000)) |
((nBuffers>2) ? (FxU16)(0x0a00) : (FxU16)(0x0600))
));
/* wait a few vsyncs */
/* VVVVV--WTF? (CHD) */
for ( i = 0; i < 1; i++ ) {
int a = 0, b = 0;
ntimes = 0;
while( !( a && !b ) ) { /* pass on falling edge of VRETRACE_ACTIVE */
if (ntimes >= 1000) {
GDBG_INFO((80, "Bailing out of vsync check after %d tries\n", FN_NAME, ntimes));
break;
}
a = b;
b = _inp( VGA_INPUT_STATUS_1C ) & VIS1C_VERTICAL_RETRACE_ACTIVE;
}
}
GDBG_INFO((80, "%s: returning %d\n", FN_NAME, 1));
#undef FN_NAME
} /* initAT3DSetTiles */
#endif /* H3D */