Leaked source code of windows server 2003
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

/******************************************************************************\
*
* $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 */