/******************************Module*Header*******************************\ * Module Name: misc.c * * Miscellaneous common routines. * * Copyright (c) 1992-1995 Microsoft Corporation * \**************************************************************************/ #include "precomp.h" /******************************Public*Table********************************\ * ULONG gaul32HwMixFromRop2[] * * Table to convert from a Source and Destination Rop2 to the Mach32's * hardware mix. \**************************************************************************/ ULONG gaul32HwMixFromRop2[] = { LOGICAL_0, // 00 -- 0 BLACKNESS NOT_SCREEN_AND_NOT_NEW, // 11 -- DSon NOTSRCERASE SCREEN_AND_NOT_NEW, // 22 -- DSna NOT_NEW, // 33 -- Sn NOSRCCOPY NOT_SCREEN_AND_NEW, // 44 -- SDna SRCERASE NOT_SCREEN, // 55 -- Dn DSTINVERT SCREEN_XOR_NEW, // 66 -- DSx SRCINVERT NOT_SCREEN_OR_NOT_NEW, // 77 -- DSan SCREEN_AND_NEW, // 88 -- DSa SRCAND NOT_SCREEN_XOR_NEW, // 99 -- DSxn LEAVE_ALONE, // AA -- D SCREEN_OR_NOT_NEW, // BB -- DSno MERGEPAINT OVERPAINT, // CC -- S SRCCOPY NOT_SCREEN_OR_NEW, // DD -- SDno SCREEN_OR_NEW, // EE -- DSo SRCPAINT LOGICAL_1 // FF -- 1 WHITENESS }; /******************************Public*Table********************************\ * ULONG gaul32HwMixFromMix[] * * Table to convert from a GDI mix value to the Mach32's hardware mix. * * Ordered so that the mix may be calculated from gaul32HwMixFromMix[mix & 0xf] * or gaul32HwMixFromMix[mix & 0xff]. \**************************************************************************/ ULONG gaul32HwMixFromMix[] = { LOGICAL_1, // 0 -- 1 LOGICAL_0, // 1 -- 0 NOT_SCREEN_AND_NOT_NEW, // 2 -- DPon SCREEN_AND_NOT_NEW, // 3 -- DPna NOT_NEW, // 4 -- Pn NOT_SCREEN_AND_NEW, // 5 -- PDna NOT_SCREEN, // 6 -- Dn SCREEN_XOR_NEW, // 7 -- DPx NOT_SCREEN_OR_NOT_NEW, // 8 -- DPan SCREEN_AND_NEW, // 9 -- DPa NOT_SCREEN_XOR_NEW, // 10 -- DPxn LEAVE_ALONE, // 11 -- D SCREEN_OR_NOT_NEW, // 12 -- DPno OVERPAINT, // 13 -- P NOT_SCREEN_OR_NEW, // 14 -- PDno SCREEN_OR_NEW, // 15 -- DPo LOGICAL_1 // 16 -- 1 }; /******************************Public*Table********************************\ * ULONG gaul64HwMixFromRop2[] * * Table to convert from a Source and Destination Rop2 to the Mach64's * foreground hardware mix. \**************************************************************************/ ULONG gaul64HwMixFromRop2[] = { LOGICAL_0 << 16, // 00 -- 0 BLACKNESS NOT_SCREEN_AND_NOT_NEW << 16, // 11 -- DSon NOTSRCERASE SCREEN_AND_NOT_NEW << 16, // 22 -- DSna NOT_NEW << 16, // 33 -- Sn NOSRCCOPY NOT_SCREEN_AND_NEW << 16, // 44 -- SDna SRCERASE NOT_SCREEN << 16, // 55 -- Dn DSTINVERT SCREEN_XOR_NEW << 16, // 66 -- DSx SRCINVERT NOT_SCREEN_OR_NOT_NEW << 16, // 77 -- DSan SCREEN_AND_NEW << 16, // 88 -- DSa SRCAND NOT_SCREEN_XOR_NEW << 16, // 99 -- DSxn LEAVE_ALONE << 16, // AA -- D SCREEN_OR_NOT_NEW << 16, // BB -- DSno MERGEPAINT OVERPAINT << 16, // CC -- S SRCCOPY NOT_SCREEN_OR_NEW << 16, // DD -- SDno SCREEN_OR_NEW << 16, // EE -- DSo SRCPAINT LOGICAL_1 << 16 // FF -- 1 WHITENESS }; /******************************Public*Table********************************\ * ULONG gaul64HwMixFromMix[] * * Table to convert from a GDI mix value to the Mach64's foreground hardware * mix. * * Ordered so that the mix may be calculated from gaul64HwMixFromMix[mix & 0xf] * or gaul64HwMixFromMix[mix & 0xff]. \**************************************************************************/ ULONG gaul64HwMixFromMix[] = { LOGICAL_1 << 16, // 0 -- 1 LOGICAL_0 << 16, // 1 -- 0 NOT_SCREEN_AND_NOT_NEW << 16, // 2 -- DPon SCREEN_AND_NOT_NEW << 16, // 3 -- DPna NOT_NEW << 16, // 4 -- Pn NOT_SCREEN_AND_NEW << 16, // 5 -- PDna NOT_SCREEN << 16, // 6 -- Dn SCREEN_XOR_NEW << 16, // 7 -- DPx NOT_SCREEN_OR_NOT_NEW << 16, // 8 -- DPan SCREEN_AND_NEW << 16, // 9 -- DPa NOT_SCREEN_XOR_NEW << 16, // 10 -- DPxn LEAVE_ALONE << 16, // 11 -- D SCREEN_OR_NOT_NEW << 16, // 12 -- DPno OVERPAINT << 16, // 13 -- P NOT_SCREEN_OR_NEW << 16, // 14 -- PDno SCREEN_OR_NEW << 16, // 15 -- DPo LOGICAL_1 << 16 // 16 -- 1 }; /******************************Public*Data*********************************\ * MIX translation table * * Translates a mix 1-16, into an old style Rop 0-255. * \**************************************************************************/ BYTE gaRop3FromMix[] = { 0xFF, // R2_WHITE - Allow rop = gaRop3FromMix[mix & 0x0F] 0x00, // R2_BLACK 0x05, // R2_NOTMERGEPEN 0x0A, // R2_MASKNOTPEN 0x0F, // R2_NOTCOPYPEN 0x50, // R2_MASKPENNOT 0x55, // R2_NOT 0x5A, // R2_XORPEN 0x5F, // R2_NOTMASKPEN 0xA0, // R2_MASKPEN 0xA5, // R2_NOTXORPEN 0xAA, // R2_NOP 0xAF, // R2_MERGENOTPEN 0xF0, // R2_COPYPEN 0xF5, // R2_MERGEPENNOT 0xFA, // R2_MERGEPEN 0xFF // R2_WHITE - Allow rop = gaRop3FromMix[mix & 0xFF] }; /******************************Public*Routine******************************\ * BOOL bIntersect * * If 'prcl1' and 'prcl2' intersect, has a return value of TRUE and returns * the intersection in 'prclResult'. If they don't intersect, has a return * value of FALSE, and 'prclResult' is undefined. * \**************************************************************************/ BOOL bIntersect( RECTL* prcl1, RECTL* prcl2, RECTL* prclResult) { prclResult->left = max(prcl1->left, prcl2->left); prclResult->right = min(prcl1->right, prcl2->right); if (prclResult->left < prclResult->right) { prclResult->top = max(prcl1->top, prcl2->top); prclResult->bottom = min(prcl1->bottom, prcl2->bottom); if (prclResult->top < prclResult->bottom) { return(TRUE); } } return(FALSE); } /******************************Public*Routine******************************\ * LONG cIntersect * * This routine takes a list of rectangles from 'prclIn' and clips them * in-place to the rectangle 'prclClip'. The input rectangles don't * have to intersect 'prclClip'; the return value will reflect the * number of input rectangles that did intersect, and the intersecting * rectangles will be densely packed. * \**************************************************************************/ LONG cIntersect( RECTL* prclClip, RECTL* prclIn, // List of rectangles LONG c) // Can be zero { LONG cIntersections; RECTL* prclOut; cIntersections = 0; prclOut = prclIn; for (; c != 0; prclIn++, c--) { prclOut->left = max(prclIn->left, prclClip->left); prclOut->right = min(prclIn->right, prclClip->right); if (prclOut->left < prclOut->right) { prclOut->top = max(prclIn->top, prclClip->top); prclOut->bottom = min(prclIn->bottom, prclClip->bottom); if (prclOut->top < prclOut->bottom) { prclOut++; cIntersections++; } } } return(cIntersections); } /******************************Public*Routine******************************\ * VOID vResetClipping \**************************************************************************/ VOID vResetClipping( PDEV* ppdev) { BYTE* pjMmBase; BYTE* pjIoBase; if (ppdev->iMachType == MACH_MM_64) { pjMmBase = ppdev->pjMmBase; M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 2); M64_OD(pjMmBase, SC_LEFT_RIGHT, PACKPAIR(0, M64_MAX_SCISSOR_R)); M64_OD(pjMmBase, SC_TOP_BOTTOM, PACKPAIR(0, ppdev->cyMemory)); } else if (ppdev->iMachType == MACH_MM_32) { pjMmBase = ppdev->pjMmBase; M32_CHECK_FIFO_SPACE(ppdev, pjMmBase, 4); M32_OW(pjMmBase, EXT_SCISSOR_L, 0); M32_OW(pjMmBase, EXT_SCISSOR_R, M32_MAX_SCISSOR); M32_OW(pjMmBase, EXT_SCISSOR_T, 0); M32_OW(pjMmBase, EXT_SCISSOR_B, M32_MAX_SCISSOR); } else { pjIoBase = ppdev->pjIoBase; I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 4); I32_OW(pjIoBase, EXT_SCISSOR_L, 0); I32_OW(pjIoBase, EXT_SCISSOR_R, M32_MAX_SCISSOR); I32_OW(pjIoBase, EXT_SCISSOR_T, 0); I32_OW(pjIoBase, EXT_SCISSOR_B, M32_MAX_SCISSOR); } } /******************************Public*Routine******************************\ * VOID vSetClipping \**************************************************************************/ VOID vSetClipping( PDEV* ppdev, RECTL* prclClip) // In relative coordinates { LONG xOffset; LONG yOffset; BYTE* pjMmBase; BYTE* pjIoBase; xOffset = ppdev->xOffset; yOffset = ppdev->yOffset; if (ppdev->iMachType == MACH_MM_64) { pjMmBase = ppdev->pjMmBase; M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 2); if (ppdev->iBitmapFormat != BMF_24BPP) { M64_OD(pjMmBase, SC_LEFT_RIGHT, PACKPAIR(xOffset + prclClip->left, xOffset + prclClip->right - 1)); } else { M64_OD(pjMmBase, SC_LEFT_RIGHT, PACKPAIR((xOffset + prclClip->left) * 3, (xOffset + prclClip->right) * 3 - 1)); } M64_OD(pjMmBase, SC_TOP_BOTTOM, PACKPAIR(yOffset + prclClip->top, yOffset + prclClip->bottom - 1)); } else if (ppdev->iMachType == MACH_MM_32) { pjMmBase = ppdev->pjMmBase; M32_CHECK_FIFO_SPACE(ppdev, pjMmBase, 4); M32_OW(pjMmBase, EXT_SCISSOR_L, xOffset + prclClip->left); M32_OW(pjMmBase, EXT_SCISSOR_R, xOffset + prclClip->right - 1); M32_OW(pjMmBase, EXT_SCISSOR_T, yOffset + prclClip->top); M32_OW(pjMmBase, EXT_SCISSOR_B, yOffset + prclClip->bottom - 1); } else { pjIoBase = ppdev->pjIoBase; I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 4); I32_OW(pjIoBase, EXT_SCISSOR_L, xOffset + prclClip->left); I32_OW(pjIoBase, EXT_SCISSOR_R, xOffset + prclClip->right - 1); I32_OW(pjIoBase, EXT_SCISSOR_T, yOffset + prclClip->top); I32_OW(pjIoBase, EXT_SCISSOR_B, yOffset + prclClip->bottom - 1); } } //////////////////////////////////////////////////////////////////////////////// // For mach8 cards only... // VOID vI32DataPortIn(PDEV *ppdev, WORD *pw, UINT count) { BYTE *pjIoBase = ppdev->pjIoBase; UINT i; for (i=0; i < count; i++) { *((USHORT UNALIGNED *)pw)++ = I32_IW(pjIoBase, PIX_TRANS); } } VOID vI32GetBits( PDEV *ppdev, SURFOBJ *psoDst, RECTL *prclDst, POINTL *pptlSrc ) { LONG xPunt, yPunt, cxPunt, cyPunt, nwords; LONG lDeltaDst = psoDst->lDelta; PBYTE pjPunt, pjIoBase = ppdev->pjIoBase; PWORD pw; WORD Cmd; // pptlSrc gives the starting point on the screen. xPunt = pptlSrc->x; yPunt = pptlSrc->y; // prclDst gives the region size. cxPunt = prclDst->right - prclDst->left; cyPunt = prclDst->bottom - prclDst->top; // Do not optimize for word alignment if prclDst points to beginning of scan. if ((prclDst->left) && (xPunt & 0x1)) { xPunt--; cxPunt++; pjPunt = (PBYTE) psoDst->pvScan0 + (prclDst->top * lDeltaDst) + prclDst->left - 1; } else pjPunt = (PBYTE) psoDst->pvScan0 + (prclDst->top * lDeltaDst) + prclDst->left; // Make sure the cx is an even number of words. if (cxPunt & 0x1) { cxPunt++; } // Set the engine up for the copy. Cmd = READ | FG_COLOR_SRC_HOST | DATA_WIDTH | DATA_ORDER | DRAW; I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 7); I32_OW(pjIoBase, DP_CONFIG, Cmd ); I32_OW(pjIoBase, WRT_MASK, 0xffff ); I32_OW(pjIoBase, CUR_X, (SHORT) xPunt ); I32_OW(pjIoBase, CUR_Y, (SHORT) yPunt ); I32_OW(pjIoBase, DEST_X_START, (SHORT) xPunt ); I32_OW(pjIoBase, DEST_X_END, (SHORT) (xPunt + cxPunt) ); I32_OW(pjIoBase, DEST_Y_END, (SHORT) (yPunt + cyPunt) ); // Wait for the Data Available. while (!(I32_IW(pjIoBase, GE_STAT) & 0x100)); // Now transfer the data from the screen to the host memory bitmap. pw = (PWORD) pjPunt; nwords = (cxPunt + 1)/2; while (cyPunt-- > 0) { vI32DataPortIn(ppdev, pw, nwords); ((PBYTE) pw) += lDeltaDst; } } VOID vI32DataPortOut(PDEV *ppdev, WORD *pw, UINT count) { BYTE *pjIoBase = ppdev->pjIoBase; UINT i; for (i=0; i < count; i++) { if (i % 8 == 0) I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 10); I32_OW(pjIoBase, PIX_TRANS, *((USHORT UNALIGNED *)pw)++); } } VOID vI32PutBits( PDEV *ppdev, SURFOBJ *psoSrc, RECTL *prclDst, POINTL *pptlSrc ) { BOOL leftScissor = FALSE, rightScissor = FALSE; LONG xPunt, yPunt, cxPunt, cyPunt, nwords; LONG lDeltaSrc = psoSrc->lDelta; PBYTE pjPunt, pjIoBase = ppdev->pjIoBase; PWORD pw; WORD Cmd; // prclDst gives the starting point on the screen. xPunt = prclDst->left; yPunt = prclDst->top; // prclDst gives the region size. cxPunt = min( prclDst->right, (LONG) ppdev->cxMemory ) - xPunt; cyPunt = prclDst->bottom - yPunt; // Do not optimize for word alignment if pptlSrc points to beginning of scan. if ((pptlSrc->x) && (xPunt & 0x1)) { I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 1); I32_OW(pjIoBase, EXT_SCISSOR_L, (SHORT) xPunt ); xPunt--; cxPunt++; leftScissor = TRUE; pjPunt = (PBYTE) psoSrc->pvScan0 + (pptlSrc->y * lDeltaSrc) + pptlSrc->x - 1; } else pjPunt = (PBYTE) psoSrc->pvScan0 + (pptlSrc->y * lDeltaSrc) + pptlSrc->x; // Make sure the cx is an even number of words. if (cxPunt & 0x1) { I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 1); I32_OW(pjIoBase, EXT_SCISSOR_R, (SHORT) (xPunt + cxPunt - 1) ); cxPunt++; rightScissor = TRUE; } // Set the engine up for the copy. Cmd = FG_COLOR_SRC_HOST | DATA_ORDER | DATA_WIDTH | DRAW | WRITE; I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 9); I32_OW(pjIoBase, DP_CONFIG, Cmd ); I32_OW(pjIoBase, WRT_MASK, 0xffff ); I32_OW(pjIoBase, ALU_FG_FN, OVERPAINT ); I32_OW(pjIoBase, ALU_BG_FN, OVERPAINT ); I32_OW(pjIoBase, CUR_X, (SHORT) xPunt ); I32_OW(pjIoBase, CUR_Y, (SHORT) yPunt ); I32_OW(pjIoBase, DEST_X_START, (SHORT) xPunt ); I32_OW(pjIoBase, DEST_X_END, (SHORT) (xPunt + cxPunt) ); I32_OW(pjIoBase, DEST_Y_END, (SHORT) (yPunt + cyPunt) ); // Now transfer the data, from the host memory bitmap to the screen. pw = (PWORD) pjPunt; nwords = (cxPunt + 1)/2; while (cyPunt-- > 0) { I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 1); vI32DataPortOut(ppdev, pw, nwords); ((PBYTE) pw) += lDeltaSrc; } if (leftScissor) { I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 1); I32_OW(pjIoBase, EXT_SCISSOR_L, 0 ); } if (rightScissor) { I32_CHECK_FIFO_SPACE(ppdev, pjIoBase, 1); I32_OW(pjIoBase, EXT_SCISSOR_R, (SHORT) M32_MAX_SCISSOR ); } } //////////////////////////////////////////////////////////////////////////////// // Context Stuff // #define _bit(x) (1 << (x)) #define CONTEXT_ADDR(ppdev,p) (ppdev->pjContextBase - (((p)+1) * 0x100)) #define cxtCONTEXT_MASK 0 #define cxtDST_OFF_PITCH 2 #define cxtDST_Y_X 3 #define cxtDST_HEIGHT_WIDTH 4 #define cxtDST_BRES_ERR 5 #define cxtDST_BRES_INC 6 #define cxtDST_BRES_DEC 7 #define cxtSRC_OFF_PITCH 8 #define cxtSRC_Y_X 9 #define cxtSRC_HEIGHT1_WIDTH1 10 #define cxtSRC_Y_X_START 11 #define cxtSRC_HEIGHT2_WIDTH2 12 #define cxtPAT_REG0 13 #define cxtPAT_REG1 14 #define cxtSC_LEFT_RIGHT 15 #define cxtSC_TOP_BOTTOM 16 #define cxtDP_BKGD_CLR 17 #define cxtDP_FRGD_CLR 18 #define cxtDP_WRITE_MASK 19 #define cxtDP_CHAIN_MASK 20 #define cxtDP_PIX_WIDTH 21 #define cxtDP_MIX 22 #define cxtDP_SRC 23 #define cxtCLR_CMP_CLR 24 #define cxtCLR_CMP_MASK 25 #define cxtCLR_CMP_CNTL 26 #define cxtGUI_TRAJ_CNTL 27 #define cxtCONTEXT_LOAD_CNTL 28 BYTE *ContextBaseAddress(PDEV *ppdev) { ULONG context_addr = 0; DWORD mem_cntl; mem_cntl = M64_ID(ppdev->pjMmBase, M64_MEM_CNTL); switch (mem_cntl & 7) { case 0: context_addr = 0x80000; // 512 K break; case 1: context_addr = 0x100000; // 1 M break; case 2: context_addr = 0x200000; break; case 3: context_addr = 0x400000; break; case 4: context_addr = 0x600000; break; case 5: context_addr = 0x800000; break; } return (BYTE *) context_addr; } VOID SetContextWorkspace( PDEV *ppdev, DWORD *context_regs, DWORD context_mask, DWORD context_load_cntl ) { BYTE* pjMmBase = ppdev->pjMmBase; INT i; for (i = 0; i < 64; i++) context_regs[i] = 0; context_regs[ 0] = context_mask; if (context_mask & 0x00000004) *(context_regs+ 2) = M64_ID(pjMmBase, DST_OFF_PITCH); if (context_mask & 0x00000008) *(context_regs+ 3) = M64_ID(pjMmBase, DST_Y_X); if (context_mask & 0x00000010) *(context_regs+ 4) = M64_ID(pjMmBase, DST_HEIGHT_WIDTH); if (context_mask & 0x00000020) *(context_regs+ 5) = M64_ID(pjMmBase, DST_BRES_ERR); if (context_mask & 0x00000040) *(context_regs+ 6) = M64_ID(pjMmBase, DST_BRES_INC); if (context_mask & 0x00000080) *(context_regs+ 7) = M64_ID(pjMmBase, DST_BRES_DEC); if (context_mask & 0x00000100) *(context_regs+ 8) = M64_ID(pjMmBase, SRC_OFF_PITCH); if (context_mask & 0x00000200) *(context_regs+ 9) = M64_ID(pjMmBase, SRC_Y_X); if (context_mask & 0x00000400) *(context_regs+10) = M64_ID(pjMmBase, SRC_HEIGHT1_WIDTH1); if (context_mask & 0x00000800) *(context_regs+11) = M64_ID(pjMmBase, SRC_Y_X_START); if (context_mask & 0x00001000) *(context_regs+12) = M64_ID(pjMmBase, SRC_HEIGHT2_WIDTH2); if (context_mask & 0x00002000) *(context_regs+13) = M64_ID(pjMmBase, PAT_REG0); if (context_mask & 0x00004000) *(context_regs+14) = M64_ID(pjMmBase, PAT_REG1); if (context_mask & 0x00008000) *(context_regs+15) = M64_ID(pjMmBase, SC_LEFT_RIGHT); if (context_mask & 0x00010000) *(context_regs+16) = M64_ID(pjMmBase, SC_TOP_BOTTOM); if (context_mask & 0x00020000) *(context_regs+17) = M64_ID(pjMmBase, DP_BKGD_CLR); if (context_mask & 0x00040000) *(context_regs+18) = M64_ID(pjMmBase, DP_FRGD_CLR); if (context_mask & 0x00080000) *(context_regs+19) = M64_ID(pjMmBase, DP_WRITE_MASK); if (context_mask & 0x00100000) *(context_regs+20) = M64_ID(pjMmBase, DP_CHAIN_MASK); if (context_mask & 0x00200000) *(context_regs+21) = M64_ID(pjMmBase, DP_PIX_WIDTH); if (context_mask & 0x00400000) *(context_regs+22) = M64_ID(pjMmBase, DP_MIX); if (context_mask & 0x00800000) *(context_regs+23) = M64_ID(pjMmBase, DP_SRC); if (context_mask & 0x01000000) *(context_regs+24) = M64_ID(pjMmBase, CLR_CMP_CLR); if (context_mask & 0x02000000) *(context_regs+25) = M64_ID(pjMmBase, CLR_CMP_MSK); if (context_mask & 0x04000000) *(context_regs+26) = M64_ID(pjMmBase, CLR_CMP_CNTL); if (context_mask & 0x08000000) *(context_regs+27) = M64_ID(pjMmBase, GUI_TRAJ_CNTL); context_regs[28] = context_load_cntl; } VOID UploadContext( PDEV *ppdev, DWORD *context_regs, BYTE *context_addr ) { BYTE* pjMmBase = ppdev->pjMmBase; M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 10); M64_OD(pjMmBase, CLR_CMP_CNTL, 0 ); M64_OD(pjMmBase, SC_LEFT_RIGHT, (255) << 16 ); M64_OD(pjMmBase, SC_TOP_BOTTOM, 0 ); M64_OD(pjMmBase, DP_SRC, DP_SRC_Host << 8 ); M64_OD(pjMmBase, DST_CNTL, DST_CNTL_XDir | DST_CNTL_YDir ); M64_OD(pjMmBase, DP_MIX, OVERPAINT << 16 ); M64_OD(pjMmBase, DP_PIX_WIDTH, DP_PIX_WIDTH_8bpp | (DP_PIX_WIDTH_8bpp << 16) ); M64_OD(pjMmBase, DST_OFF_PITCH, (ULONG)((ULONG_PTR) context_addr/8 | (256 << 19) )); M64_OD(pjMmBase, DST_Y_X, 0 ); M64_OD(pjMmBase, DST_HEIGHT_WIDTH, 0x01000001 ); // 256x1 vM64DataPortOutB(ppdev, (BYTE *)context_regs, 256); M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 4); M64_OD(pjMmBase, DST_OFF_PITCH, ppdev->ulScreenOffsetAndPitch ); M64_OD(pjMmBase, DP_PIX_WIDTH, ppdev->ulMonoPixelWidth ); M64_OD(pjMmBase, SC_LEFT_RIGHT, M64_MAX_SCISSOR_R << 16 ); M64_OD(pjMmBase, SC_TOP_BOTTOM, ppdev->cyMemory << 16 ); } VOID vSetDefaultContext(PDEV * ppdev) { DWORD work_context [64]; SetContextWorkspace( ppdev, work_context, _bit(cxtCONTEXT_MASK) | _bit(cxtDP_WRITE_MASK) | _bit(cxtCLR_CMP_CNTL) | _bit(cxtGUI_TRAJ_CNTL), 0); // Fix vanishing text and fills, as well as other color problems: work_context[cxtDP_WRITE_MASK] = 0xFFFFFFFF; work_context[cxtCLR_CMP_CNTL] = 0; // Fix frizzy text and RGB ordering problems: work_context[cxtGUI_TRAJ_CNTL] = DST_CNTL_XDir | DST_CNTL_YDir; UploadContext( ppdev, work_context, CONTEXT_ADDR(ppdev,ppdev->iDefContext) ); } VOID vEnableContexts(PDEV * ppdev) { ppdev->pjContextBase = ContextBaseAddress(ppdev); if (ppdev->cjBank == (LONG)((ULONG_PTR)ppdev->pjContextBase)) ppdev->ulContextCeiling =(ULONG)((ULONG_PTR)ppdev->pjContextBase - 1024); else ppdev->ulContextCeiling = (ULONG)((ULONG_PTR) ppdev->pjContextBase); // Compute ALL context pointers needed in the driver. ppdev->iDefContext = (ULONG)((ULONG_PTR)ppdev->pjContextBase - (ULONG_PTR)ppdev->ulContextCeiling)/256; ppdev->ulContextCeiling -= 256; // In general, you need to check whether a context allocation will decrease // cyMemory. Here, we only have the one and FIRST allocation, so decrement cyMemory. ppdev->cyMemory--; } //////////////////////////////////////////////////////////////////////////////// // DataPortOutB routine for the mach64 // VOID vM64DataPortOutB(PDEV *ppdev, PBYTE pb, UINT count) { PBYTE pjMmBase = ppdev->pjMmBase; UINT i, DWLeft, LastBytes; DWORD UNALIGNED *pdw; PBYTE Byte_in_Dword; DWORD Buffer; #define THRESH 14 pdw = (DWORD*)pb; DWLeft = (count + 3)/4; LastBytes = count % 4; while ( DWLeft > 0 ) { if (DWLeft < THRESH || (DWLeft == THRESH && LastBytes != 0)) { M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, DWLeft); if (LastBytes > 0) { for (i=0; i< DWLeft-1 ; i++) M64_OD(pjMmBase, HOST_DATA0, *(pdw+i)); Byte_in_Dword = (PBYTE) (pdw+i); Buffer = 0; for (i=0; i < LastBytes; i++) { Buffer |= (*Byte_in_Dword) << (i*8); Byte_in_Dword++; } M64_OD(pjMmBase, HOST_DATA0, Buffer); } else { for (i=0; i< DWLeft ; i++) M64_OD(pjMmBase, HOST_DATA0, *(pdw+i)); } pdw += DWLeft; DWLeft = 0; } else { M64_CHECK_FIFO_SPACE(ppdev, pjMmBase, 16); /* Inline coded for greater performance */ M64_OD(pjMmBase, HOST_DATA0, *(pdw)); // 1 Word M64_OD(pjMmBase, HOST_DATA0, *(pdw+1)); // 2 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+2)); // 3 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+3)); // 4 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+4)); // 5 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+5)); // 6 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+6)); // 7 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+7)); // 8 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+8)); // 9 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+9)); // 10 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+10)); // 11 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+11)); // 12 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+12)); // 13 Words M64_OD(pjMmBase, HOST_DATA0, *(pdw+13)); // 14 Words pdw += 14; DWLeft -= THRESH; } /*if*/ } /* while */ #undef THRESH }