You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
644 lines
20 KiB
644 lines
20 KiB
/******************************************************************************\
|
|
*
|
|
* $Workfile: LAGUNA.H $
|
|
*
|
|
* This file to be included by all host programs.
|
|
*
|
|
* Copyright (c) 1995,1997 Cirrus Logic, Inc.
|
|
*
|
|
* $Log: X:/log/laguna/nt35/displays/cl546x/LAGUNA.H $
|
|
*
|
|
* Rev 1.38 Mar 04 1998 16:13:30 frido
|
|
* Removed a warning message for the 5462/5464 chips in the REQUIRE
|
|
* macro.
|
|
*
|
|
* Rev 1.37 Mar 04 1998 16:08:50 frido
|
|
* Removed an invalid break.
|
|
*
|
|
* Rev 1.36 Mar 04 1998 14:54:48 frido
|
|
* Added contional REQUIRE in the new shadow macros.
|
|
*
|
|
* Rev 1.35 Mar 04 1998 14:52:54 frido
|
|
* Added new shadowing macros.
|
|
*
|
|
* Rev 1.34 Feb 27 1998 17:02:16 frido
|
|
* Changed REQUIRE and WRITE_STRING macros for new
|
|
* shadowQFREE register.
|
|
*
|
|
* Rev 1.33 Jan 20 1998 11:42:46 frido
|
|
* Changed REQUIRE and WRITESTRING macros to support the new
|
|
* scheme for GBP on.
|
|
* Added shadowing of BGCOLOR and DRAWBLTDEF registers.
|
|
*
|
|
* Rev 1.32 Jan 16 1998 09:50:38 frido
|
|
* Changed the way the GBP OFF handles WRITE_STRING macros.
|
|
*
|
|
* Rev 1.31 Dec 10 1997 13:24:58 frido
|
|
* Merged from 1.62 branch.
|
|
*
|
|
* Rev 1.30.1.0 Nov 18 1997 18:09:00 frido
|
|
* Changed WRITE_STRING macro so it will work when
|
|
* DATASTREAMING is turned of.
|
|
* Changed FUDGE to 0, we are not using DMA inside NT.
|
|
*
|
|
* Rev 1.30 Nov 04 1997 19:01:18 frido
|
|
* Changed HOSTDATA size from 0x800 DWORDs into 0x800 BYTEs. Silly me!
|
|
*
|
|
* Rev 1.29 Nov 04 1997 09:17:30 frido
|
|
* Added Data Streaming macros (REQUIRE and WRITE_STRING).
|
|
*
|
|
\******************************************************************************/
|
|
|
|
#ifndef _LAGUNA_H
|
|
#define _LAGUNA_H
|
|
|
|
#include "optimize.h"
|
|
#include "config.h"
|
|
#include "lgregs.h"
|
|
|
|
|
|
//
|
|
// PCI ID for Laguna chips.
|
|
//
|
|
#define CL_GD5462 0x00D0 // 5462
|
|
#define CL_GD5464 0x00D4 // 5464
|
|
#define CL_GD5464_BD 0x00D5 // 5464 BD
|
|
#define CL_GD5465 0x00D6 // 5465
|
|
|
|
//
|
|
// These chips don't exist yet, but we're FORWARD COMPATIBLE
|
|
// so we'll define them anyway. I've been GUARENTEED that they
|
|
// will look and feel just like 5465 chips.
|
|
//
|
|
#define CL_GD546x_F7 0x00D7
|
|
#define CL_GD546x_F8 0x00D8
|
|
#define CL_GD546x_F9 0x00D9
|
|
#define CL_GD546x_FA 0x00DA
|
|
#define CL_GD546x_FB 0x00DB
|
|
#define CL_GD546x_FC 0x00DC
|
|
#define CL_GD546x_FD 0x00DD
|
|
#define CL_GD546x_FE 0x00DE
|
|
#define CL_GD546x_FF 0x00DF
|
|
|
|
|
|
//
|
|
// CHIP BUG: For certian values in PRESET register cursor enable/disable
|
|
// causes scanlines to be duplicated at the cursor hot spot. (Seen
|
|
// as screen jump.) There are lots of ways around this. The easiest
|
|
// is to turn the cursor on and leave it on. Enable/Disable is handled by
|
|
// moving the cursor on/off the visable screen.
|
|
//
|
|
#define HW_PRESET_BUG 1
|
|
|
|
|
|
|
|
// The 5465 (to at least AC) has a problem when PCI configuration space
|
|
// is accessible in memory space. On 16-bit writes, a 32-bit write is
|
|
// actually performed, so the next register has garbage written to it.
|
|
// We get around this problem by clearing bit 0 of the Vendor Specific
|
|
// Control register in PCI configuration space. When this bit is set
|
|
// to 0, PCI configuration registers are not available through memory
|
|
// mapped I/O. Since some functions, such as power management, require
|
|
// access to PCI registers, the display driver must post a message to
|
|
// the miniport to enable this bit when needed.
|
|
//
|
|
#define VS_CONTROL_HACK 1
|
|
|
|
|
|
#if ENABLE_LOG_FILE
|
|
extern long lg_i;
|
|
extern char lg_buf[256];
|
|
#endif
|
|
|
|
#if POINTER_SWITCH_ENABLED
|
|
extern int pointer_switch;
|
|
#endif
|
|
|
|
|
|
|
|
// The definitions are not portable. 486 / PC only !!!
|
|
typedef struct {
|
|
BYTE b;
|
|
BYTE g;
|
|
BYTE r;
|
|
} pix24;
|
|
|
|
typedef struct {
|
|
BYTE u;
|
|
BYTE y1;
|
|
BYTE v;
|
|
BYTE y2;
|
|
} yuv_422;
|
|
|
|
typedef struct {
|
|
unsigned int v : 6;
|
|
unsigned int u : 6;
|
|
unsigned int y0: 5;
|
|
unsigned int y1: 5;
|
|
unsigned int y2: 5;
|
|
unsigned int y3: 5;
|
|
} yuv_411;
|
|
|
|
typedef struct {
|
|
unsigned int b : 5;
|
|
unsigned int g : 5;
|
|
unsigned int r : 5;
|
|
} rgb_555;
|
|
|
|
typedef struct {
|
|
unsigned int b : 5;
|
|
unsigned int g : 6;
|
|
unsigned int r : 5;
|
|
} rgb_565;
|
|
|
|
|
|
typedef union {
|
|
DWORD p32;
|
|
yuv_422 yuv422;
|
|
yuv_411 yuv411;
|
|
pix24 p24;
|
|
rgb_555 rgb555;
|
|
rgb_565 rgb565;
|
|
WORD p16[2];
|
|
BYTE p8[4];
|
|
} pixel;
|
|
|
|
|
|
#define FALSE 0
|
|
#ifndef TRUE
|
|
#define TRUE (~FALSE)
|
|
#endif
|
|
|
|
/* from struct.h */
|
|
#define fldoff(str, fld) ((int)&(((struct str *)0)->fld))
|
|
#define fldsiz(str, fld) (sizeof(((struct str *)0)->fld))
|
|
|
|
#define HPRR(pr_reg) (_AP_direct_read(PADDR(pr_reg),fldsiz(PLUTOREGS,pr_reg), (ul)0))
|
|
#define RPR(pr_reg) HPRR(pr_reg)
|
|
#define EHIST (*(EXHIST*)excepttion) /* Exception History buffer */
|
|
#define STAMP (*(bytearray*)0x0) /* time date stamp */
|
|
#define HISTORYBUFFERADDR (ul)&history /* 34020 address of recording */
|
|
|
|
|
|
/* External functions the host program can call */
|
|
|
|
/*-------------------------------------------------------------------------*/
|
|
|
|
/* Function prototypes for emulator. Functions defined in host_if.c */
|
|
int _cdecl _AP_init(int mode, void * frame_buf);
|
|
void _cdecl _AP_write(ul addr, int size, ul data);
|
|
ul _cdecl _AP_read(ul addr,int size);
|
|
void _cdecl _AP_run(void);
|
|
boolean _cdecl _AP_busy();
|
|
boolean _cdecl _AP_done();
|
|
boolean _cdecl _AP_rfifo_empty();
|
|
boolean _cdecl _AP_require(int size);
|
|
ul _cdecl _AP_direct_read(ul addr,int size);
|
|
void _cdecl _AP_fb_write(ul offset, pixel data, ul size);
|
|
pixel _cdecl _AP_fb_read(ul offset, ul size);
|
|
|
|
|
|
#if LOG_QFREE
|
|
|
|
#define START_OF_BLT() \
|
|
do{ \
|
|
CHECK_QFREE(); \
|
|
} while(0)
|
|
|
|
#define END_OF_BLT() \
|
|
do{ \
|
|
} while(0)
|
|
|
|
#else
|
|
#define START_OF_BLT()
|
|
#define END_OF_BLT()
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// This waits for the chip to go idle
|
|
//
|
|
#define WAIT_FOR_IDLE() \
|
|
do { \
|
|
while (LLDR_SZ (grSTATUS) != 0); \
|
|
} while (0)
|
|
|
|
|
|
|
|
//
|
|
// Macro to require a certian number of free queue entries.
|
|
//
|
|
#if DATASTREAMING
|
|
#define FUDGE 2
|
|
#define REQUIRE(n) \
|
|
{ \
|
|
if (ppdev->dwDataStreaming & 0x80000000) \
|
|
{ \
|
|
if (ppdev->shadowQFREE < ((n) + FUDGE)) \
|
|
{ \
|
|
while (ppdev->shadowQFREE < (n) + FUDGE) \
|
|
{ \
|
|
ppdev->shadowQFREE = LLDR_SZ(grQFREE); \
|
|
} \
|
|
} \
|
|
ppdev->shadowQFREE -= (BYTE) n; \
|
|
} \
|
|
else if (ppdev->dwDataStreaming) \
|
|
{ \
|
|
if (LLDR_SZ(grQFREE) < ((n) + FUDGE)) \
|
|
{ \
|
|
while (LLDR_SZ(grSTATUS) & 0x8005) ; \
|
|
ppdev->dwDataStreaming = 0; \
|
|
} \
|
|
} \
|
|
}
|
|
#define ENDREQUIRE() \
|
|
{ \
|
|
ppdev->dwDataStreaming |= 1; \
|
|
}
|
|
#define WRITE_STRING(src, dwords) \
|
|
{ \
|
|
ULONG nDwords, nTotal = (ULONG) (dwords); \
|
|
PULONG data = (PULONG) (src); \
|
|
if (ppdev->dwDataStreaming & 0x80000000) \
|
|
{ \
|
|
while (nTotal > 0) \
|
|
{ \
|
|
nDwords = (ULONG) ppdev->shadowQFREE; \
|
|
if (nDwords > FUDGE) \
|
|
{ \
|
|
nDwords = min(nDwords - FUDGE, nTotal); \
|
|
memcpy((LPVOID) ppdev->pLgREGS->grHOSTDATA, data, nDwords * 4); \
|
|
data += nDwords; \
|
|
nTotal -= nDwords; \
|
|
} \
|
|
ppdev->shadowQFREE = LLDR_SZ(grQFREE); \
|
|
} \
|
|
} \
|
|
else \
|
|
{ \
|
|
if ( ppdev->dwDataStreaming && (LLDR_SZ(grQFREE) < nTotal) ) \
|
|
{ \
|
|
while (LLDR_SZ(grSTATUS) & 0x8005) ; \
|
|
ppdev->dwDataStreaming = 0; \
|
|
} \
|
|
while (nTotal > 0) \
|
|
{ \
|
|
nDwords = min(nTotal, 0x200); \
|
|
memcpy((LPVOID) ppdev->pLgREGS->grHOSTDATA, data, nDwords * 4); \
|
|
data += nDwords; \
|
|
nTotal -= nDwords; \
|
|
} \
|
|
} \
|
|
}
|
|
#else
|
|
#define REQUIRE(n)
|
|
#define ENDREQUIRE()
|
|
#define WRITE_STRING(src, dwords) \
|
|
{ \
|
|
ULONG nDwords, nTotal = (ULONG) (dwords); \
|
|
PULONG data = (PULONG) (src); \
|
|
while (nTotal > 0) \
|
|
{ \
|
|
nDwords = min(nTotal, 0x200); \
|
|
memcpy((LPVOID) ppdev->pLgREGS->grHOSTDATA, data, nDwords * 4); \
|
|
data += nDwords; \
|
|
nTotal -= nDwords; \
|
|
} \
|
|
}
|
|
#endif
|
|
|
|
//
|
|
// Macros to read Laguna registers.
|
|
//
|
|
#define LADDR(pr_reg) fldoff(GAR,pr_reg)
|
|
|
|
// #define LLDR(pr_reg,pr_siz) _AP_direct_read((ul)LADDR(pr_reg),pr_siz)
|
|
#define LLDR(pr_reg,pr_siz) (ppdev->pLgREGS_real->pr_reg)
|
|
#define LLDR_SZ(pr_reg) LLDR(pr_reg, fldsiz(GAR,pr_reg))
|
|
|
|
// #define LLR(pr_reg,pr_siz) _AP_read((ul)LADDR(pr_reg),pr_siz)
|
|
#define LLR(pr_reg,pr_siz) LLDR(pr_reg,pr_siz)
|
|
#define LLR_SZ(pr_reg) LLR(pr_reg, fldsiz(GAR,pr_reg))
|
|
|
|
|
|
#if LOG_WRITES
|
|
#define LG_LOG(reg,val) \
|
|
do { \
|
|
lg_i = sprintf(lg_buf,"LL\t%4X\t%08X\r\n", \
|
|
((DWORD)(&ppdev->pLgREGS->reg) - (DWORD)(&ppdev->pLgREGS->grCR0)), \
|
|
(val)); \
|
|
WriteLogFile(ppdev->pmfile, lg_buf, lg_i, ppdev->TxtBuff, &ppdev->TxtBuffIndex); \
|
|
} while(0)
|
|
#else
|
|
#define LG_LOG(reg,val)
|
|
#endif
|
|
|
|
//
|
|
// Macros to write Laguna registers.
|
|
//
|
|
// This is an amazingly, incredibly hairy macro that, believe it or not,
|
|
// will be greatly reduced by a good compiler. The "if" can be
|
|
// pre-determined by the compiler.
|
|
// The purpose of this is to ensure that exactly the right number of bytes
|
|
// is written to the chip. If the programmer writes, say, a BYTE to a
|
|
// DWORD sized register, we need to be sure that the byte is zero extended
|
|
// and that a full DWORD gets written.
|
|
//
|
|
#define LRWRITE(pr_reg,pr_siz,value) \
|
|
do { \
|
|
LG_LOG(pr_reg,(value)); \
|
|
if (sizeof(ppdev->pLgREGS->pr_reg) == sizeof(BYTE)) \
|
|
{ \
|
|
*(volatile BYTE *)(&ppdev->pLgREGS->pr_reg) = (BYTE)(value); \
|
|
} \
|
|
else if (sizeof(ppdev->pLgREGS->pr_reg) == sizeof(WORD)) \
|
|
{ \
|
|
*(volatile WORD *)(&ppdev->pLgREGS->pr_reg) = (WORD)(value); \
|
|
*(volatile WORD *)(&ppdev->pLgREGS->grBOGUS) = (WORD)(value); \
|
|
LG_LOG(grBOGUS,(value)); \
|
|
} \
|
|
else \
|
|
{ \
|
|
*(volatile DWORD *)(&ppdev->pLgREGS->pr_reg) = (DWORD)(value); \
|
|
} \
|
|
} while(0)
|
|
|
|
#define LL(pr_reg,value) LRWRITE(pr_reg, fldsiz(GAR,pr_reg), value)
|
|
|
|
|
|
|
|
|
|
// ----------------------------------------------------------------------------
|
|
//
|
|
// Certian registers have been giving us problems. We provide special
|
|
// write macros for them.
|
|
//
|
|
|
|
//
|
|
// Writes any 8 bit register.
|
|
//
|
|
#define LL8(pr_reg,value) \
|
|
do { \
|
|
LG_LOG(pr_reg,(value)); \
|
|
(*(volatile BYTE *)(&ppdev->pLgREGS->pr_reg) = (BYTE)(value)); \
|
|
} while(0)
|
|
|
|
|
|
|
|
//
|
|
// Writes any 16 bit register.
|
|
//
|
|
#define LL16(pr_reg,value) \
|
|
do { \
|
|
LG_LOG(pr_reg,(value)); \
|
|
(*(volatile WORD *)(&ppdev->pLgREGS->pr_reg) = (WORD)(value)); \
|
|
} while(0)
|
|
|
|
|
|
|
|
//
|
|
// Double writes any 16 bit register.
|
|
//
|
|
#define LL16d(pr_reg,value) \
|
|
do { \
|
|
(*(volatile WORD *)(&ppdev->pLgREGS->pr_reg) = (WORD)(value)); \
|
|
LG_LOG(pr_reg,(value)); \
|
|
(*(volatile WORD *)(&ppdev->pLgREGS->grBOGUS) = (WORD)(value)); \
|
|
LG_LOG(grBOGUS,(value)); \
|
|
} while(0)
|
|
|
|
|
|
|
|
//
|
|
// Writes any 32 bit register.
|
|
//
|
|
#define LL32(pr_reg,value) \
|
|
{ \
|
|
*(volatile DWORD *)(&ppdev->pLgREGS->pr_reg) = (DWORD)(value); \
|
|
}
|
|
|
|
//
|
|
// MACROS FOR BLTEXT REGISTER.
|
|
//
|
|
|
|
#define LL_BLTEXT(x,y) \
|
|
LL32 (grBLTEXT_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
#if ! DRIVER_5465
|
|
#define LL_MBLTEXT(x,y) \
|
|
do { \
|
|
LL16 (grMBLTEXT_EX.pt.X, x); \
|
|
LL16 (grBLTEXT_EX.pt.Y, y); \
|
|
} while(0)
|
|
#else
|
|
#define LL_MBLTEXT(x,y) \
|
|
LL32 (grMBLTEXT_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
#endif
|
|
|
|
#define LL_BLTEXTR(x,y) \
|
|
LL32 (grBLTEXTR_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
#define LL_BLTEXT_EXT(x,y) \
|
|
LL32 (grBLTEXT.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
#define LL_MBLTEXT_EXT(x,y) \
|
|
LL32 (grMBLTEXT.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
|
|
// Launch a BLT using the color translation features of the
|
|
// resize engine. (1:1 resize)
|
|
#define LL_BLTEXT_XLATE(src_bpp, x, y) \
|
|
do {\
|
|
LL16 (grMIN_X, (~((x)-1)));\
|
|
LL16 (grMAJ_X, (x));\
|
|
LL16 (grACCUM_X, ((x)-1));\
|
|
LL16 (grMIN_Y, (~((y)-1)));\
|
|
LL16 (grMAJ_Y, (y));\
|
|
LL16 (grACCUM_Y, ((y)-1));\
|
|
LL16 (grSRCX, (((x)*(src_bpp)) >> 3) );\
|
|
LL_BLTEXTR((x), (y));\
|
|
} while(0)
|
|
|
|
|
|
|
|
//
|
|
// MACROS FOR CLIPULE/CLIPLOR REGISTERS.
|
|
//
|
|
#define LL_CLIPULE(x,y) \
|
|
LL32 (grCLIPULE.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_MCLIPULE(x,y) \
|
|
LL32 (grMCLIPULE.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_CLIPLOR(x,y) \
|
|
LL32 (grCLIPLOR.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_MCLIPLOR(x,y) \
|
|
LL32 (grMCLIPLOR.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_CLIPULE_EX(x,y) \
|
|
LL32 (grCLIPULE_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_MCLIPULE_EX(x,y) \
|
|
LL32 (grMCLIPULE_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_CLIPLOR_EX(x,y) \
|
|
LL32 (grCLIPLOR_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
#define LL_MCLIPLOR_EX(x,y) \
|
|
LL32 (grMCLIPLOR_EX.dw, (((DWORD)(y) << 16) | ((DWORD)(x))));
|
|
|
|
|
|
|
|
//
|
|
// MACROS FOR OP0_opRDRAM REGISTER.
|
|
//
|
|
#define LL_OP0(x,y) \
|
|
LL32 (grOP0_opRDRAM.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
#define LL_OP0_MONO(x,y) \
|
|
LL32 (grOP0_opMRDRAM.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
|
|
|
|
|
|
//
|
|
// MACROS FOR OP1_opRDRAM REGISTER.
|
|
//
|
|
#define LL_OP1(x,y) \
|
|
LL32 (grOP1_opRDRAM.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
#define LL_OP1_MONO(x,y) \
|
|
LL32 (grOP1_opMRDRAM.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
|
|
|
|
|
|
//
|
|
// MACROS FOR OP2_opRDRAM REGISTER.
|
|
//
|
|
#define LL_OP2(x,y) \
|
|
LL32 (grOP2_opRDRAM.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
#define LL_OP2_MONO(x,y) \
|
|
LL32 (grOP2_opMRDRAM.dw, (((DWORD)(y) << 16) | ((DWORD)(x))))
|
|
|
|
|
|
|
|
|
|
//
|
|
// -- End of special write macros --------------------------------------------
|
|
//
|
|
|
|
|
|
|
|
|
|
/* HPR is the copy of REGISTER_STRUCTURE that the host reads and writes from.
|
|
PR is the actual register state after the information has gone
|
|
through the FIFO. Immediate registers are kept up-to-date in HPR.
|
|
These structures are allocated in the link file. */
|
|
|
|
extern GAR PR; /* the emulator working copy */
|
|
extern GAR HPR[4]; /* the "host" copy */
|
|
|
|
#define LAGUNA_SRAM_SIZE 32 /* dwords */
|
|
|
|
#define IS_SRC 0x03 /* Source mask. */
|
|
|
|
struct _vid_mode {
|
|
BYTE Bpp; // Bytes per pixel (8 / 16 / 24 / 32)
|
|
WORD Xextent; // Display rsolution in pixels eg 1280
|
|
WORD Yextent; // Vertical display resolution
|
|
WORD Xpitch; // Offset in bytes from line 0 to line 1
|
|
int Vesa_Mode; // Mode number for VESA ( if supported by S3 )
|
|
};
|
|
|
|
typedef struct _vid_mode vid_mode;
|
|
typedef vid_mode *vid_ptr;
|
|
|
|
|
|
/***************************************************************************
|
|
*
|
|
* MACRO: SYNC_W_3D
|
|
*
|
|
* DESCRIPTION: If 3d context(s) active, wait until 3d engine idle
|
|
* or until 1,000,000 checks have failed
|
|
*
|
|
****************************************************************************/
|
|
|
|
#if WINNT_VER40 && DRIVER_5465 // WINNT_VER40
|
|
|
|
#define SYNC_3D_CONDITIONS (ST_POLY_ENG_BUSY|ST_EXEC_ENG_3D_BUSY|ST_XY_ENG_BUSY|/*ST_BLT_ENG_BUSY|*/ST_BLT_WF_EMPTY)
|
|
|
|
#define ENSURE_3D_IDLE(ppdev) \
|
|
{ \
|
|
if (ppdev->pLgREGS != NULL) \
|
|
{ \
|
|
int num_syncs=2; \
|
|
/* there is a slight chance of a window in which all bits go off while engine fetching */ \
|
|
/* next command - double read should catch that */ \
|
|
while (num_syncs--) \
|
|
{ \
|
|
int status; \
|
|
volatile int wait_count=0; \
|
|
do \
|
|
{ \
|
|
status = (*((volatile *)((DWORD *)(ppdev->pLgREGS) + PF_STATUS_3D)) & 0x3FF) ^ SYNC_3D_CONDITIONS; \
|
|
/* do something to give bus a breather, and to prevent eternal stall */ \
|
|
wait_count++; \
|
|
} while(((status & SYNC_3D_CONDITIONS) != SYNC_3D_CONDITIONS) && wait_count<1000000); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
#define SYNC_W_3D(ppdev) \
|
|
{ \
|
|
if (ppdev->NumMCDContexts > 0) \
|
|
{ \
|
|
ENSURE_3D_IDLE(ppdev); \
|
|
} \
|
|
}
|
|
|
|
#else // WINNT_VER40 && DRIVER_5465
|
|
|
|
// no 3D on NT before NT4.0. No 3D on 62 and not used on 64.
|
|
#define ENSURE_3D_IDLE(ppdev) {}
|
|
#define SYNC_W_3D(ppdev) {}
|
|
|
|
#endif // WINNT_VER40
|
|
|
|
//
|
|
// New shadowing macros.
|
|
//
|
|
#define LL_FGCOLOR(color, r) \
|
|
{ \
|
|
if ((DWORD) (color) != ppdev->shadowFGCOLOR) \
|
|
{ \
|
|
if (r) REQUIRE(r); \
|
|
LL32(grOP_opFGCOLOR, ppdev->shadowFGCOLOR = (DWORD) (color)); \
|
|
} \
|
|
}
|
|
|
|
#define LL_BGCOLOR(color, r) \
|
|
{ \
|
|
if ((DWORD) (color) != ppdev->shadowBGCOLOR) \
|
|
{ \
|
|
if (r) REQUIRE(r); \
|
|
LL32(grOP_opBGCOLOR, ppdev->shadowBGCOLOR = (DWORD) (color)); \
|
|
} \
|
|
}
|
|
|
|
#define LL_DRAWBLTDEF(drawbltdef, r) \
|
|
{ \
|
|
if ((DWORD) (drawbltdef) != ppdev->shadowDRAWBLTDEF) \
|
|
{ \
|
|
if (r) REQUIRE(r); \
|
|
LL32(grDRAWBLTDEF, ppdev->shadowDRAWBLTDEF = (DWORD) (drawbltdef)); \
|
|
} \
|
|
}
|
|
|
|
#endif /* ndef _LAGUNA_H */
|