|
|
/**********************************************************
* Copyright (c) 1996-1997 Microsoft Corporation. * Copyright (c) 1996-1997 Cirrus Logic, Inc. *********************************************************** * File Name: 7555OVER.C * * Module Abstract: * ---------------- * This contains functions needed to support overlay hardware. * * Functions: * ---------- * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * myf31 :02-24-97 : Fixed enable HW Video, panning scrolling enable,screen move * video window have follow moving * myf34 :04-15-97 : Supported YUY2 format for NT. ***********************************************************/
/* #includes ---------------------------------------------*/ #include "PreComp.h"
#if DIRECTDRAW
#include "overlay.h"
#include "7555bw.h"
static int ScaleMultiply(DWORD dw1, DWORD dw2, LPDWORD pdwResult);
/**********************************************************
* * Name: RegInit7555Video * * Module Abstract: * ---------------- * This function is called to program the video format and * the physicall offset of the video data in the frame buffer. * * Output Parameters: * ------------------ * none * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * *********************************************************/
VOID RegInit7555Video (PDEV * ppdev,PDD_SURFACE_LOCAL lpSurface) { DWORD dwTemp; DWORD dwFourcc; WORD wBitCount;
LONG lPitch; WORD wTemp; RECTL rDest; WORD wSrcWidth; WORD wSrcWidth_clip; WORD wDestWidth; WORD wSrcHeight; WORD wSrcHeight_clip; WORD wDestHeight; DWORD dwFBOffset; BYTE bRegCR31; BYTE bRegCR32; BYTE bRegCR33; BYTE bRegCR34; BYTE bRegCR35; BYTE bRegCR36; BYTE bRegCR37; BYTE bRegCR38; BYTE bRegCR39; BYTE bRegCR3A; BYTE bRegCR3B; BYTE bRegCR3C; BYTE bRegCR3D; BYTE bRegCR3E; BYTE bRegCR3F; BYTE bRegCR40; BYTE bRegCR41; BYTE bRegCR42; BYTE bRegCR51; BYTE bRegCR5D; //myf32
BYTE bRegCR5F; //myf32
BYTE bRegSR2F; //myf32
BYTE bRegSR32; //myf32
BYTE bRegSR34; //myf32
BYTE bTemp; BYTE bVZoom; WORD fTemp=0; ULONG ulTemp=0; BOOL bOverlayTooSmall = FALSE; static DWORD giAdjustSource;
//myf32 added
bRegSR2F = Regs.bSR2F; bRegSR32 = Regs.bSR32; bRegSR34 = Regs.bSR34;
bRegCR5D = Regs.bCR5D; CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x5F); bRegCR5F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); bRegCR5F |= (Regs.bCR5F & 0x80); //myf32 end
/*
* Init some values */ CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x42); // bRegCR42 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0xFC; //mask Chroma key
// & FIFO
bRegCR42 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0xF0; //mask Chroma key
// & FIFO, myf32
bRegCR42 |= (Regs.bCR42 & CR42_MVWTHRESH); //myf32
bRegCR42 |= 0x10; CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36); //myf29
bRegCR36 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x40; //myf29
bRegCR36 |= 0x20; //set Excess 128 Data Format, myf29
/*
* Determine the format of the video data */ if (lpSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT) { GetFormatInfo (ppdev,&(lpSurface->lpGbl->ddpfSurface), &dwFourcc, &wBitCount); } else { // This needs to be changed when primary surface is RGB 5:6:5
dwFourcc = BI_RGB; wBitCount = (WORD) ppdev->cBitsPerPixel; }
/*
* Determine the rectangle for the video window */ PanOverlay1_Init(ppdev, lpSurface, &rDest, &ppdev->rOverlaySrc, &ppdev->rOverlayDest, dwFourcc, wBitCount); // rVideoRect is now adjusted and clipped to the panning viewport.
// disable overlay if totally clipped by viewport
if (((rDest.right - rDest.left) <= 0) || ((rDest.bottom - rDest.top) <= 0)) { bOverlayTooSmall = TRUE; } dwTemp = (DWORD)(ppdev->min_Yscreen - ppdev->rOverlayDest.top); if ((ppdev->rOverlaySrc.bottom - ppdev->rOverlaySrc.top -(LONG)dwTemp) <=0) bOverlayTooSmall = TRUE;
lPitch = lpSurface->lpGbl->lPitch;
wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip); wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip);
wSrcWidth = (WORD)(LONG)(ppdev->rOverlaySrc.right - ppdev->rOverlaySrc.left); wDestWidth = (WORD)(LONG)(ppdev->rOverlayDest.right - ppdev->rOverlayDest.left); wSrcHeight = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - ppdev->rOverlaySrc.top); wDestHeight = (WORD)(LONG)(ppdev->rOverlayDest.bottom - ppdev->rOverlayDest.top);
// Determine horizontal upscale coefficient (CR31[7:0],CR39[7:4])
wTemp = ((WORD)(((DWORD)wSrcWidth << 12) / (DWORD)wDestWidth)) & 0x0FFF; if (wTemp != 0 && bLeft_clip) { srcLeft_clip = srcLeft_clip *(LONG)wTemp/4096 + ppdev->rOverlaySrc.left; wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip); } else if (bLeft_clip) { srcLeft_clip = srcLeft_clip + ppdev->rOverlaySrc.left; wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip); }
bRegCR39 = (BYTE)((wTemp & 0x0F) << 4); bRegCR31 = (BYTE)(wTemp >> 4) & 0xFF;
// Determine vertical upscale coefficient (CR32[7:0],CR39[3:0])
bVZoom=0; wTemp = ((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)wDestHeight)) & 0x0FFF; if (wTemp != 0) { bVZoom=1; fTemp = wTemp; if (fTemp < 2048 ) // Zoom > 2.0
wTemp=((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)(wDestHeight+1))) & 0x0FFF; } if (wTemp != 0 && bTop_clip) { srcTop_clip = srcTop_clip * (LONG)wTemp/4096 + ppdev->rOverlaySrc.top; wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom -srcTop_clip); } else if (bTop_clip) { srcTop_clip = srcTop_clip + ppdev->rOverlaySrc.top; wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom -srcTop_clip); }
bRegCR39 |= (BYTE)(wTemp & 0x0F); bRegCR32 = (BYTE)(wTemp >> 4) & 0xFF; DISPDBG((0,"wTemp = 0x%x",wTemp));
// Determine Vertical Height (CR38[7:0], CR36[3:2])
// wTemp = wSrcHeight;
wTemp = wSrcHeight_clip; //myf32
DISPDBG((0,"fTemp = 0x%x",fTemp)); if (wTemp != 0 && (fTemp > 2730 || fTemp ==0 || ( fTemp > 1365 && fTemp < 2048 ) ) ) wTemp--; //#tt10, Height minus one only if upscale rate <1.5
//#tt10 2 < <3
bRegCR38 = (BYTE)wTemp; bRegCR36 |= (wTemp & 0x0300) >> 6;
// Determine Horizontal position start (CR34[7:0], CR33[7:5])
// handle 7555-BB MVA pitch bug (QWORD should be DWORD)
wTemp = (WORD)rDest.left; bRegCR34 = (BYTE)wTemp; bRegCR33 = (wTemp & 0x0700) >> 3;
// Reset Brightness control (CR35[7:0])
bRegCR35 = 0x0;
// Determine Vertical Start (CR37[7:0], CR36[1:0])
wTemp = (WORD)rDest.top; bRegCR37 = (BYTE)wTemp; bRegCR36 |= (wTemp & 0x0300) >> 8;
// Determine Video Start Address (CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0])
giAdjustSource = (srcTop_clip * lpSurface->lpGbl->lPitch) + ((srcLeft_clip * wBitCount) >> 3); //myf32
// giAdjustSource = (ppdev->rOverlaySrc.top * lpSurface->lpGbl->lPitch)
// + ((ppdev->rOverlaySrc.left * wBitCount) >> 3);
ppdev->sOverlay1.lAdjustSource = giAdjustSource; //myf32
dwFBOffset = (DWORD)(lpSurface->lpGbl->fpVidMem + giAdjustSource); // dwFBOffset = (lpSurface->lpGbl->fpVidMem - ppdev->dwScreenFlatAddr)
// + giAdjustSource; //myf32
DISPDBG((0,"lpSurface->lpGbl->fpVidMem = 0x%08x", lpSurface->lpGbl->fpVidMem)); DISPDBG((0,"giAdjustSource = 0x%08x",giAdjustSource)); DISPDBG((0,"dwFBOffset = 0x%08x",dwFBOffset));
dwFBOffset >>= 2;
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3A); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
bRegCR3A = (bTemp & ~0x7F) | (BYTE)((dwFBOffset & 0x0FE000) >> 13); bRegCR3E = (BYTE)((dwFBOffset & 0x001FE0) >> 5);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3F); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); bRegCR3F = (bTemp & ~0x0F) | (BYTE)((dwFBOffset & 0x00001E) >> 1);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x40); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ; bRegCR40 = (bTemp & ~0x01) | (BYTE)(dwFBOffset & 0x000001);
//Determine Video Pitch (CR3B[7:0], CR36[4])
wTemp = (WORD)(lpSurface->lpGbl->lPitch >> 4); //QWORDs
bRegCR3B = (BYTE)wTemp; bRegCR36 |= (wTemp & 0x0100) >> 4;
// Determine Data Format (CR3E[3:0])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C); bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x10; //mask out prev VW width
switch (dwFourcc) { case FOURCC_PACKJR: bRegCR3C |= 0x02; // Pack JR
break;
case BI_RGB: switch(wBitCount) { case 8: bRegCR3C |= 0x09; // 8 bit palettized
break;
case 16: bRegCR3C |= 0x01; // RGB 5:5:5
break; } break;
//myf32 added
case BI_BITFIELDS: switch(wBitCount) { case 8: bRegCR3C |= 0x09; // 8 bit palettized
break;
case 16: bRegCR3C |= 0x04; // RGB 5:6:5
break; } break; //myf32 end
case FOURCC_YUV422: bRegCR3C |= 0x03; // YUV 4:2:2
break;
case FOURCC_YUY2: //myf34 test
bRegCR3C |= 0x03; // YUY2
// CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x2C);
// bRegSR2C = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
// bRegSR2C |= 0x40; //SR2c[6] = 1
// CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x2C |(WORD)bRegSR2C << 8);
break; }
// Determine Horizontal width (CR3D[7:0], CR3C[7:5])
// NOTE: assumes Horz Pixel Width [0] = 0
wTemp = wSrcWidth_clip; //myf32
// wTemp = wSrcWidth;
if (wTemp != 0 ) wTemp--; //Width minus one for laptop
bRegCR3D = (BYTE)((WORD)wTemp >> 1); bRegCR3C |= (wTemp & 0x0600) >> 3; bRegCR3C |= (BYTE)((wTemp & 0x0001) << 5) ;
// Enable Horizontal Pixel Interpolation (CR3F[7])
bRegCR3F |= 0x80;
// Enable Vertical Pixel Interpolation (CR3F[6])
//#tt Debug- The CE rev. has problem when vertical interpolation is on
//#tt Debug- Disable it for now.
//#tt bRegCR3F |= 0x40;
// Enable Right Side transition threshold (CR41[5:0])
bRegCR41 = 0x3E;
// Disable V-PORT (CR58[7:0])
bRegCR51 = 0x0;
/*
* If we are color keying, we will set that up now */ if (lpSurface->dwReserved1 & OVERLAY_FLG_COLOR_KEY) { bRegCR3F |= 0x20; //Enable Occlusion
bRegCR42 &= ~0x1; //Disable Chroma Key
bRegCR5F &= ~0x80; //myf32 //Disable CR5D[7:0] if color key,
//so disable CR5F[7]
bRegCR5D = 0; //myf32
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1A); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
// Set CR1A[3:2] to timing ANDed w/ color
bTemp &= ~0x0C; CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, bTemp);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1D); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
if (ppdev->cBitsPerPixel == 8) { CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (bTemp & ~0x38)); ulTemp= 0x0C | (ppdev->wColorKey << 8); CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRC
ulTemp= 0x0D; CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRD
} else { CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (bTemp & ~0x30) | 0x08); ulTemp= 0x0C | (ppdev->wColorKey << 8); CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRC
ulTemp= 0x0D | (ppdev->wColorKey & 0xff00); CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRD
} } else if (lpSurface->dwReserved1 & OVERLAY_FLG_SRC_COLOR_KEY) { BYTE bYMax, bYMin, bUMax, bUMin, bVMax, bVMin;
bRegCR3F |= 0x20; //Enable Occlusion
bRegCR42 |= 0x1; //Enable Chroma Key
bRegCR5F &= ~0x80; //myf32 //Disable CR5D[7:0] if color key,
//so disable CR5F[7]
bRegCR5D = 0; //myf32
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1A); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ; // Set CR1A[3:2] to timing ANDed w/ color
bTemp &= ~0x0C; CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, bTemp);
/*
* Determine min/max values */ if ((dwFourcc == FOURCC_YUV422) || (dwFourcc == FOURCC_YUVPLANAR) || (dwFourcc == FOURCC_YUY2) || //myf34
(dwFourcc == FOURCC_PACKJR)) //myf32
{ bYMax = (BYTE)(DWORD)(ppdev->dwSrcColorKeyHigh >> 16); bYMin = (BYTE)(DWORD)(ppdev->dwSrcColorKeyLow >> 16); bUMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 8) & 0xff); bUMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 8) & 0xff); bVMax = (BYTE)(ppdev->dwSrcColorKeyHigh & 0xff); bVMin = (BYTE)(ppdev->dwSrcColorKeyLow & 0xff); if (dwFourcc == FOURCC_PACKJR) { bYMax |= 0x07; bUMax |= 0x03; bVMax |= 0x03; bYMin &= ~0x07; bUMin &= ~0x03; bVMin &= ~0x03; } } else if ((dwFourcc == 0) && (wBitCount == 16)) { /*
* RGB 5:5:5 */ bYMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 7) & 0xF8); bYMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 7) & 0xF8); bUMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 2) & 0xF8); bUMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 2) & 0xF8); bVMax = (BYTE)(ppdev->dwSrcColorKeyHigh << 3); bVMin = (BYTE)(ppdev->dwSrcColorKeyLow << 3); bYMax |= 0x07; bUMax |= 0x07; bVMax |= 0x07;
} else if (dwFourcc == BI_BITFIELDS) { /*
* RGB 5:6:5 */ bYMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 8) & 0xF8); bYMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 8) & 0xF8); bUMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 3) & 0xFC); bUMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 3) & 0xFC); bVMax = (BYTE)(ppdev->dwSrcColorKeyHigh << 3); bVMin = (BYTE)(ppdev->dwSrcColorKeyLow << 3); bYMax |= 0x07; bUMax |= 0x03; bVMax |= 0x07; } CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x0C | (WORD)bYMin <<8));//GRC
CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x0D | (WORD)bYMax <<8));//GRd
CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1C | (WORD)bUMin <<8));//GR1C
CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1D | (WORD)bUMax <<8));//GR1D
CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1E | (WORD)bVMin <<8));//GR1E
CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1F | (WORD)bVMax <<8));//GR1F
} else { CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1A); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ; CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, (bTemp & ~0x0C)); bRegCR3F &= ~0x20; // disable occlusion
}
/*
* Set up alignment info */ if (ppdev->cBitsPerPixel != 24) { WORD wXAlign; WORD wXSize;
if (ppdev->cBitsPerPixel == 8) { wXAlign = (WORD)rDest.left & 0x03; wXSize = (WORD)(rDest.right - rDest.left) & 0x03; } else { wXAlign = (WORD)(rDest.left & 0x01) << 1; wXSize = (WORD)((rDest.right - rDest.left) & 0x01) << 1; } }
// disable overlay if totally clipped by viewport
// or overlay is too small to be supported by HW
//
if (bOverlayTooSmall) { DisableVideoWindow(ppdev); // disable overlay
ppdev->dwPanningFlag |= OVERLAY_OLAY_REENABLE; // totally clipped
} else {
/*
* Program the video window registers */ //myf32 added
CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x2F |(WORD)bRegSR2F << 8);//SR2F
CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x32 |(WORD)bRegSR32 << 8);//SR32
CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x34 |(WORD)bRegSR34 << 8);//SR34
//myf32 end
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x31 | (WORD)bRegCR31 << 8);//CR31
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x32 | (WORD)bRegCR32 << 8);//CR32
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x34 | (WORD)bRegCR34 << 8);//CR34
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x33 | (WORD)bRegCR33 << 8);//CR33
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x35 | (WORD)bRegCR35 << 8);//CR35
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x36 | (WORD)bRegCR36 << 8);//CR36
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x37 | (WORD)bRegCR37 << 8);//CR37
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x38 | (WORD)bRegCR38 << 8);//CR38
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x39 | (WORD)bRegCR39 << 8);//CR39
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3B | (WORD)bRegCR3B << 8);//CR3B
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3C | (WORD)bRegCR3C << 8);//CR3C
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3D | (WORD)bRegCR3D << 8);//CR3D
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x41 | (WORD)bRegCR41 << 8);//CR41
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x42 | (WORD)bRegCR42 << 8);//CR42
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x51 | (WORD)bRegCR51 << 8);//CR51
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x40 | (WORD)bRegCR40 << 8);//CR40
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3A | (WORD)bRegCR3A << 8);//CR3A
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3E | (WORD)bRegCR3E << 8);//CR3E
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3F | (WORD)bRegCR3F << 8);//CR3F
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x5D | (WORD)bRegCR5D << 8);//CR5D
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x5F | (WORD)bRegCR5F << 8);//CR5F
if (lpSurface->dwReserved1 & OVERLAY_FLG_YUVPLANAR) CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3F |(WORD)0x10 <<8);
EnableVideoWindow (ppdev); } } /**********************************************************
* * Name: RegMoveVideo * * Module Abstract: * ---------------- * This function is called to move the video window that has * already been programed. * * Output Parameters: * ------------------ * none * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * *********************************************************/
VOID RegMove7555Video (PDEV * ppdev,PDD_SURFACE_LOCAL lpSurface) { RegInitVideo (ppdev,lpSurface); }
/**********************************************************
* * Name: DisableVideoWindow * * Module Abstract: * ---------------- * turn off video window * * Output Parameters: * ------------------ * none * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * *********************************************************/ VOID DisableVideoWindow (PDEV * ppdev) { UCHAR temp;
DISPDBG((0, "DisableVideoWindow"));
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3c); temp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (temp & ~0x10));
}
/**********************************************************
* * Name: EnableVideoWindow * * Module Abstract: * ---------------- * turn on video window * * Output Parameters: * ------------------ * none * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * *********************************************************/ VOID EnableVideoWindow (PDEV * ppdev) { UCHAR temp; DISPDBG((0, "EnableVideoWindow"));
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3c); temp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (temp | 0x10));
}
/**********************************************************
* * Name: ClearAltFIFOThreshold * * Module Abstract: * ---------------- * * * Output Parameters: * ------------------ * none * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * *********************************************************/ VOID ClearAltFIFOThreshold (PDEV * ppdev) { UCHAR temp; DISPDBG((0, "ClearAltFIFOThreshold"));
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x41); temp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (temp & ~0x20)); }
/**********************************************************
* * Name: Is7555SufficientBandwidth * * Module Abstract: * ---------------- * Determines is sufficient bandwidth exists for the requested * configuration. * * Output Parameters: * ------------------ * TRUE/FALSE * It also sets the global parameter lFifoThresh, which gets * programed in RegInitVideo(). * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * * * *********************************************************** * * The FIFOs: * * CRT FIFO is 28 levels x 64-bits wide (SR7[0]) * MVA FIFO is ?? levels x ??-bits wide (????) * DSTN FIFO is 16 levels x 32-bits wide (SR2F[3:0]) * * ***********************************************************/ BOOL Is7555SufficientBandwidth (PDEV * ppdev,WORD wVideoDepth, LPRECTL lpSrc, LPRECTL lpDest, DWORD dwFlags) { //myf33 - New Bandwith Code
BOOL fSuccess = FALSE; DWORD dwVCLK, dwMCLK;
USHORT uMCLKsPerRandom; //RAS# cycles in MCLKs
USHORT uMCLKsPerPage; //CAS# cycles in MCLKs
USHORT uGfxThresh; //Graphic FIFO Threshold (always 8)
USHORT uMVWThresh; //MVW FIFO Threshold (8,16 or 32)
USHORT uDSTNGfxThresh, uDSTNMVWThresh;
//VPort BW document variables
USHORT uGfx, uMVW; //Graphics, Video Window
USHORT uDSTNGfxA, uDSTNGfxB, uDSTNMVWA, uDSTNMVWB;
USHORT nVW = 0; //n (VW), n (Graphics)
USHORT nGfx = 0x40; //n (VW), n (Graphics)
USHORT vVW, vGfx; //v (VW), v (Gfx)
DWORD dwTemp; BOOL fDSTN; BYTE bSR0F, bSR20, bSR2F, bSR32, bSR34; BYTE bGR18, bCR42; BYTE bCR51, bCR5A, bCR5D, bCR01, bCR5F; BYTE b3V; BOOL fColorKey = FALSE; //myf32
DWORD dwSrcWidth, dwDestWidth;
if (dwFlags & (OVERLAY_FLG_COLOR_KEY | OVERLAY_FLG_SRC_COLOR_KEY)) fColorKey = TRUE;
// if ((ppdev->cBitsPerPixel == 16) && (ppdev->cxScreen == 1024))
// fColorKey = FALSE;
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80); bSR0F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ; if ((ppdev->cBitsPerPixel == 16) && fColorKey) { if (((ppdev->Hres == 1024) && (bSR0F & 1)) || (ppdev->cxScreen == 1024)) { DISPDBG((0, "IsSufficientBandwidth() : 16bpp XGA PANEL || 1K mode")); return (FALSE); } }
//myf32 begin
if (ppdev->flCaps & CAPS_TV_ON) //if TV on disable HW video
{ // ppdev->ulCAPS |= CAPS_SW_POINTER;
DISPDBG((0, "IsSufficientBandwidth() : TV Enable")); return (FALSE); }
#if 0 //don't support panning scrolling
if ((ppdev->cxScreen > ppdev->Hres) && (bSR0F & 1)) { DISPDBG((0, "IsSufficientBandwidth() : Panning Scroll Enable")); return (FALSE); } #endif
//myf32 end
/*
* Don's support overlay if >=24bpp */ if (ppdev->cBitsPerPixel == 24 || ppdev->cBitsPerPixel == 32) { DISPDBG((0, "IsSufficientBandwidth() : 24bpp Mode enable")); return (FALSE); }
/*
* Get current register settings from the chip */ CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x0f); bSR0F = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x20); bSR20 = CP_IN_BYTE(ppdev->pjPorts, SR_DATA);
CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x2f); bSR2F = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) & ~(BYTE)SR2F_HFAFIFOGFX_THRESH;
CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x32); bSR32 = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) & ~(BYTE)SR32_HFAFIFOMVW_THRESH;
CP_OUT_BYTE(ppdev->pjPorts, INDEX_REG, 0x18); bGR18 = CP_IN_BYTE(ppdev->pjPorts, DATA_REG) ;
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x01); bCR01 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x5F); bCR5F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & ~0x80;
bCR5D = 0; bCR51 = 0; bCR5A = 0x40; //Alan Kobayashi
bSR34 = 0; // @@@ Is this right?
/*
* Determine MCLK and VCLK */ dwMCLK = Get7555MCLK(ppdev); // Measured in KHz
dwVCLK = GetVCLK(ppdev); // Measured in KHz
if ( dwVCLK ==0 ) return (FALSE);
//myf32 added
// check if 3.3 voltage, (SR2F[5] =0 : 3V, =1 : 5V)
if (bSR2F & 0x40) b3V = 0; else b3V = 1;
if (ppdev->ulChipID == CL7556_ID) { if (dwVCLK > 80000) { DISPDBG ((0,"Insuffieint bandwidth() : dwVCLK > 80MHz")); return(FALSE); } } else if (ppdev->ulChipID == CL7555_ID) { if (b3V) { if (dwVCLK > 65000) { DISPDBG ((0,"Insuffieint bandwidth() : dwVCLK > 65MHz")); return(FALSE); } } else { if (dwVCLK > 75000) { DISPDBG ((0,"Insuffieint bandwidth() : dwVCLK > 75MHz")); return(FALSE); } } } //myf32 end
/*
* See if there is enough bandwidth. * * CL-GD7555 has sufficient bandwidth when the following * equation is satisfied: * * (Gfx + MVW + VP + DSTN) * MCLK Period <= v * VCLK period * * (Gfx = Graphics, MVW = Motion Video Window, VP = Video * Port, DSTN = Dual Scan Transistor Network, MCLK = * Memory Clock, VCLK = Video Clock) * * In color/chroma key mode, this equation is checked once * with VP based on n(Gfx), and using v(Gfx). In non-color/chroma * key mode, this equation is checked twice, once without the * MVW term, basing VP on n(Gfx), using DSTN for Gfx, and using * v(Gfx), and once without the Gfx term, basing VP on n(MVW), * using DSTN for MVW, and using v(MVW). */
/*
* Graphics = R + (GFX FIFO Threshold - 1)P */
// Get R based on the table (from AHRM v1.1):
//
// SR20[6] GR18[2] SR0F[2] R(MCLKs)
//
// 0 1 0 8
// 1 1 0 9
//
uMCLKsPerRandom = 100; // Start with an invalid value
if (!(bSR20 & SR20_9MCLK_RAS)) { if (bGR18 & GR18_LONG_RAS) { if (!(bSR0F & SR0F_DISPLAY_RAS)) uMCLKsPerRandom = 8; } } else { if (bGR18 & GR18_LONG_RAS) { if (!(bSR0F & SR0F_DISPLAY_RAS)) uMCLKsPerRandom = 9; } }
// See if we got a valid value
if (100 == uMCLKsPerRandom) { DISPDBG ((0,"IsSufficientBandwidth(): Unknown RAS# cycle timing.")); goto Error; } DISPDBG ((0," uMCLKsPerRandom = %u", uMCLKsPerRandom));
// Get P - We assume 2 MCLKs per page cycle
uMCLKsPerPage = 2; DISPDBG ((0," uMCLKsPerPage = %u", uMCLKsPerPage));
// Get GFX FIFO Threshold - It's hardwired to 8
uGfxThresh = GFXFIFO_THRESH; DISPDBG ((0," uGfxThresh = %u", uGfxThresh));
// Graphics = R + (GFX FIFO Threshold - 1) * P
uGfx = uMCLKsPerRandom + ((uGfxThresh - 1) * uMCLKsPerPage); DISPDBG ((0," uGfx = %u", uGfx));
/*
* Video Window = R + (VW FIFO Threshold - 1) * P */
// Get VW FIFO Threshold - From table (on BW sheet)
//
// GFX Depth MVW Depth VW FIFO Thresh
//
// 8 8 8
// 16 8 8
// 8 16 16
// 16 16 8
//
if (fColorKey) { if (wVideoDepth > 8) { if (ppdev->cBitsPerPixel > 8) uMVWThresh = 8; else uMVWThresh = 16; } else uMVWThresh = 8; } else { if (wVideoDepth > 8) uMVWThresh = 8; else uMVWThresh = 16; } DISPDBG ((0," uMVWThresh = %u", uMVWThresh));
// Video Window = R + (VW FIFO Threshold - 1) * P
uMVW = uMCLKsPerRandom + ((uMVWThresh - 1) * uMCLKsPerPage); DISPDBG ((0," uMVW = %u", uMVW));
// Determine Source and Destination VW Widths
dwSrcWidth = lpSrc->right - lpSrc->left; dwDestWidth = lpDest->right - lpDest->left; DISPDBG ((0," dwSrcWidth = %d", dwSrcWidth)); DISPDBG ((0," dwDestWidth = %d", dwDestWidth));
// If the video port capture is enabled, calculate VPort stuff
#if 0 //00 for New structure Code
if (dwFlags & OVERLAY_FLG_CAPTURE ) { int iNumShift, iDenomShift; DWORD dwNum, dwDenom; DWORD dwXferRate; DWORD dwVPortFreq;
// Convert transfer rate to video port frequency, which assumes
// 16-bits per clock
if (!dwMaxPixelsPerSecond) dwXferRate = 14750000ul; else dwXferRate = dwMaxPixelsPerSecond;
dwXferRate = 14750000ul; //hardcoded temporarily
dwVPortFreq = (dwXferRate * (DWORD)wVideoDepth) / 16; DISPDBG ((0," dwVPortFreq = %lu", dwVPortFreq));
/*
* V-Port = R + (n - 1) * P * * n is calculated for graphics and video window. */
// Calculate n(Gfx) and VPort(Gfx)
// n(Gfx) = VPort freq * Gfx Thresh * VPort depth cap wdth
// ------------------------------------- * ---------
// VCLK * Gfx depth xfer wdth
// Being very careful to avoid overflows while maintaining decent
// accuracy.
iNumShift = ScaleMultiply(dwVPortFreq, (DWORD)uGfxThresh, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift)); iNumShift += ScaleMultiply(dwNum, (DWORD)wVideoDepth, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift)); iNumShift += ScaleMultiply(dwNum, (DWORD)dwPrescaleWidth, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
iDenomShift = ScaleMultiply(dwVCLK, (DWORD)wGfxDepth,&dwDenom); DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift)); iDenomShift += ScaleMultiply(dwDenom, (DWORD)dwCropWidth, &dwDenom); DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
// Even things up for the divide
if (iNumShift > iDenomShift) { dwDenom >>= (iNumShift - iDenomShift); } else if (iDenomShift > iNumShift) { dwNum >>= (iDenomShift - iNumShift); } DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
// Be sure rounding below doesn't overflow
if ((0xFFFFFFFF - dwDenom) < dwNum) { dwNum >>= 1; dwDenom >>= 1; } DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
// Protect from a divide by 0 - this should never happen
if (0 == dwDenom) { DISPDBG ((0,"ChipCheckBandwidth(): Invalid n(Gfx) denominator (0).")); goto Error; }
// Round up
nGfx = (UINT)((dwNum + dwDenom - 1ul) / dwDenom); DISPDBG ((0," nGfx = %u", nGfx));
// Only 3 bits for nGfx, so scale it and save factor
uGfxFactor = 1; while (nGfx > 7) { nGfx++; nGfx >>= 1; uGfxFactor <<= 1; DISPDBG ((0," nGfx = %u, uGfxFactor = %u", nGfx, uGfxFactor)); }
// For a 0 n(Gfx), we assume the overhead is negligible.
if (0 == nGfx) { uVPortGfx = 0; } else { // V-Port = R + (n - 1) * P
uVPortGfx = uMCLKsPerRandom + ((nGfx - 1) * uMCLKsPerPage); uVPortGfx *= uGfxFactor; } DISPDBG ((0," uVPortGfx = %u", uVPortGfx));
// If the video window is enabled, calculate n(MVW) and VPort(MVW)
if (dwFlags & OVERLAY_FLG_CAPTURE) { // n(VW) = VPort freq * VW Thresh * VPort depth disp wdth cap wdth
// ------------------------------------ * --------- * ---------
// VCLK * VW depth src wdth xfer wdth
// Being very careful to avoid overflows while maintaining decent
// accuracy.
iNumShift = ScaleMultiply(dwVPortFreq, (DWORD)uMVWThresh, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift)); iNumShift += ScaleMultiply(dwNum, (DWORD)wVideoDepth, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift)); iNumShift += ScaleMultiply(dwNum, (DWORD)dwDestWidth, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift)); iNumShift += ScaleMultiply(dwNum, (DWORD)dwPrescaleWidth, &dwNum); DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
iDenomShift = ScaleMultiply(dwVCLK, (DWORD)wVideoDepth, &dwDenom); DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift)); iDenomShift += ScaleMultiply(dwDenom, (DWORD)dwSrcWidth, &dwDenom); DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift)); iDenomShift += ScaleMultiply(dwDenom, (DWORD)dwCropWidth, &dwDenom); DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
// Even things up for the divide
if (iNumShift > iDenomShift) { dwDenom >>= (iNumShift - iDenomShift); } else if (iDenomShift > iNumShift) { dwNum >>= (iDenomShift - iNumShift); } DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
// Be sure rounding below doesn't overflow
if ((0xFFFFFFFF - dwDenom) < dwNum) { dwNum >>= 1; dwDenom >>= 1; } DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
// Protect from a divide by 0 even though this should never happen
if (0 == dwDenom) { DISPDBG ((0,"ChipCheckBandwidth(): Invalid n(VW) denominator (0).")); goto Error; }
// Divide (round up)
nVW = (UINT)((dwNum + dwDenom - 1) / dwDenom); DISPDBG ((0," nVW = %u", nVW));
// Only 3 bits for nVW, so scale it and save factor
uMVWFactor = 1; while (nVW > 7) { nVW++; nVW >>= 1; uMVWFactor <<= 1; DISPDBG ((0," nVW = %u, uMVWFactor = %u", nVW, uMVWFactor)); }
// For a 0 n(VW), we assume the overhead is negligible.
if (0 == nVW) { uVPortMVW = 0; } else { // V-Port = R + (n - 1) * P
uVPortMVW = uMCLKsPerRandom + ((nVW - 1) * uMCLKsPerPage); uVPortMVW *= uMVWFactor; } DISPDBG((0," uVPortMVW = %u", uVPortMVW)); } } #endif //00 -- fr new structure code
/*
* DSTN Frame Buffer = [R + P] + [1 + (2 * P)] (a) * or = [R + (2 * P)] + [1 + (3 * P)] (b) */ dwTemp = (DWORD)(uMCLKsPerRandom + uMCLKsPerPage + 1 + (2 * uMCLKsPerPage)); uDSTNGfxA = (UINT)dwTemp; dwTemp *= dwDestWidth; dwTemp /= dwSrcWidth; uDSTNMVWA = (UINT)dwTemp;
dwTemp = (DWORD)(uMCLKsPerRandom + (2 * uMCLKsPerPage) + 1 + (3 * uMCLKsPerPage)); uDSTNGfxB = (UINT)dwTemp; dwTemp *= dwDestWidth; dwTemp /= dwSrcWidth; uDSTNMVWB = (UINT)dwTemp;
DISPDBG((0,"uDSTNGfxA = %u, uDSTNMVWA = %u, uDSTNGfxB = %u,uDSTNMVWB = %u", uDSTNGfxA, uDSTNMVWA, uDSTNGfxB, uDSTNMVWB));
/*
* (Gfx + MVW + VP + DSTN) * MCLK Period <= VCLK period */
// Calculate v(VW) and v(Graphics) for comparison below
// Div 0 Protection done above
vVW = (UINT)((64ul * (DWORD)uMVWThresh * dwDestWidth) / (wVideoDepth * dwSrcWidth)); DISPDBG((0," vVW = %u", vVW));
// Div 0 Protection done above
vGfx = (USHORT)((64 * uGfxThresh) / ppdev->cBitsPerPixel); DISPDBG((0," vGfx = %u", vGfx));
// See if DSTN is enabled
fDSTN = IsDSTN(ppdev);
// Check main equation, starting with Gfx-based equation (we won't
// do MVW-based equation below unless we are non-color/chroma keyed
// and the MVW is enabled.
{ DWORD dwLeft, dwRight, dwScaledRandomMCLKPeriod;
// Begin building left side of equation with DSTN contribution
if (fDSTN) { if (16 == ppdev->cBitsPerPixel) { dwLeft = (DWORD)uDSTNGfxA; uDSTNGfxThresh = 4; } else { dwLeft = (DWORD)uDSTNGfxB; uDSTNGfxThresh = 6; } if (uMVWThresh == wVideoDepth) uDSTNMVWThresh = 6; else uDSTNMVWThresh = 4; } else { dwLeft = 0; } DISPDBG((0," dwLeft = %lu", dwLeft));
// Are we being displayed and color or chroma keyed?
if (fColorKey) { // Add graphics contribution (scaled)
dwLeft += ((DWORD)uGfx * dwDestWidth) / dwSrcWidth;
DISPDBG((0," dwLeft = %lu", dwLeft));
// Add video window contribution
dwLeft += (DWORD)uMVW; } else { // Add graphics contribution (1x)
dwLeft += (DWORD)uGfx; } DISPDBG((0," dwLeft = %lu", dwLeft));
if (fColorKey) dwRight = (DWORD)vVW; else dwRight = (DWORD)vGfx; DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
// Only add video port if it's in use
#if 0 //00 - for new structure code
if (dwFlags & OVERLAY_FLG_CAPTURE) { if (fColorKey) dwLeft += (DWORD)uVPortMVW; else dwLeft += (DWORD)uVPortGfx; } #endif //0 - for new structure code
DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
// To avoid the divisions in (left/MCLK) <= (right/VCLK), we'll
// instead multiply left * VCLK and right * MCLK since the relationship
// will be the same.
{ int iLeftShift, iRightShift, iRandomMCLKShift;
iLeftShift = ScaleMultiply(dwLeft, dwVCLK, &dwLeft); DISPDBG((0," dwLeft = %lu, iLeftShift = %d", dwLeft, iLeftShift));
iRightShift = ScaleMultiply(dwRight, dwMCLK, &dwRight); DISPDBG((0," dwRight = %lu, iRightShift = %d", dwRight, iRightShift));
iRandomMCLKShift = ScaleMultiply((DWORD)uMCLKsPerRandom, dwVCLK, &dwScaledRandomMCLKPeriod); DISPDBG((0," dwScaledRandomMCLKPeriod = %lu,iRandomMCLKShift = %d", dwScaledRandomMCLKPeriod, iRandomMCLKShift));
// Even things up
{ int iShift = iLeftShift;
if (iRightShift > iShift) iShift = iRightShift;
if (iRandomMCLKShift > iShift) iShift = iRandomMCLKShift;
if (iShift > iLeftShift) dwLeft >>= (iShift - iLeftShift);
if (iShift > iRightShift) dwRight >>= (iShift - iRightShift);
if (iShift > iRandomMCLKShift) dwScaledRandomMCLKPeriod >>= (iShift - iRandomMCLKShift); } } DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight)); DISPDBG((0," dwScaledRandomMCLKPeriod = %lu", dwScaledRandomMCLKPeriod));
// See if there is enough bandwidth
if (dwLeft > dwRight) { DISPDBG((0,"IsSufficientBandwidth(): Insufficient bandwidth (Gfx).")); goto Error; }
if (dwLeft > (dwRight - dwScaledRandomMCLKPeriod)) { // Set CPU stop bits
DISPDBG((0,"IsSufficientBandwidth(): CPU stop bits set (Gfx).")); bSR34 = SR34_CPUSTOP_ENABLE | SR34_GFX_CPUSTOP | SR34_MVW_CPUSTOP; if (fDSTN) bSR34 |= SR34_DSTN_CPUSTOP; DISPDBG((0," bSR34 = 0x%x", bSR34)); } }
// Check main equation using MVW-based values if we are not
// color/chroma keyed and the MVW is enabled.
if (!fColorKey) { DWORD dwLeft, dwRight, dwScaledRandomMCLKPeriod;
// Begin building left side of equation with DSTN contribution
if (fDSTN) { if (uMVWThresh == wVideoDepth) dwLeft = (DWORD)uDSTNMVWB; else dwLeft = (DWORD)uDSTNMVWA; } else { dwLeft = 0; } DISPDBG((0," dwLeft = %lu", dwLeft));
// Add MVW contribution
dwLeft += (DWORD)uMVW; DISPDBG((0," dwLeft = %lu", dwLeft));
// Use v(MVW) for right
dwRight = (DWORD)vVW; DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
// To avoid the divisions in (left/MCLK) <= (right/VCLK), we'll
// instead multiply left * VCLK and right * MCLK since the relationship
// will be the same.
{ int iLeftShift, iRightShift, iRandomMCLKShift;
iLeftShift = ScaleMultiply(dwLeft, dwVCLK, &dwLeft); DISPDBG((0," dwLeft = %lu, iLeftShift = %d", dwLeft, iLeftShift));
iRightShift = ScaleMultiply(dwRight, dwMCLK, &dwRight); DISPDBG((0," dwRight = %lu, iRightShift = %d", dwRight, iRightShift));
iRandomMCLKShift = ScaleMultiply((DWORD)uMCLKsPerRandom, dwVCLK, &dwScaledRandomMCLKPeriod); DISPDBG((0," dwScaledRandomMCLKPeriod = %lu, iRandomMCLKShift = %d", dwScaledRandomMCLKPeriod, iRandomMCLKShift));
// Even things up
{ int iShift = iLeftShift;
if (iRightShift > iShift) iShift = iRightShift;
if (iRandomMCLKShift > iShift) iShift = iRandomMCLKShift;
if (iShift > iLeftShift) dwLeft >>= (iShift - iLeftShift);
if (iShift > iRightShift) dwRight >>= (iShift - iRightShift);
if (iShift > iRandomMCLKShift) dwScaledRandomMCLKPeriod >>= (iShift - iRandomMCLKShift); } }
DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight)); DISPDBG((0," dwScaledRandomMCLKPeriod = %lu", dwScaledRandomMCLKPeriod));
// See if there is enough bandwidth
if (dwLeft > dwRight) { DISPDBG((0,"IsSufficientBandwidth(): Insufficient bandwidth (MVW).")); goto Error; }
if (dwLeft > (dwRight - dwScaledRandomMCLKPeriod)) { // Set CPU stop bits
DISPDBG((0,"IsSufficientBandwidth(): CPU stop bits set (MVW)."));
bSR34 = SR34_CPUSTOP_ENABLE | SR34_MVW_CPUSTOP;
if (fDSTN) bSR34 |= SR34_DSTN_CPUSTOP; DISPDBG((0," bSR34 = 0x%x", bSR34)); } }
// Return register settings
bSR2F |= (BYTE)uDSTNGfxThresh & SR2F_HFAFIFOGFX_THRESH; bSR32 |= (BYTE)uDSTNMVWThresh & SR32_HFAFIFOMVW_THRESH;
switch (uMVWThresh) { case 8: bCR42 = 0x04; break;
case 16: bCR42 = 0x00; break;
default: DISPDBG((0,"IsSufficientBandwidth(): Illegal MVW Thresh (%u).", uMVWThresh)); goto Error; }
bCR51 |= ((BYTE)nVW << 5) & CR51_VPORTMVW_THRESH; DISPDBG((0," bCR51 = 0x%02X", (int)bCR51));
bCR5A |= (BYTE)nGfx & CR5A_VPORTGFX_THRESH; DISPDBG((0," bCR5A = 0x%02X", (int)bCR5A));
bCR5D=(BYTE)(((8 * (WORD)(bCR01 + 1)) + dwSrcWidth - dwDestWidth) / 8); DISPDBG((0," bCR5D = 0x%02X", (int)bCR5D)); if (bCR5D) bCR5F |= 0x80;
// Set global registers to be programmed in RegInitVideo()
//myf33 if (lpRegs)
{ Regs.bSR2F = bSR2F; Regs.bSR32 = bSR32; Regs.bSR34 = bSR34;
Regs.bCR42 = bCR42; Regs.bCR51 = bCR51; Regs.bCR5A = bCR5A; Regs.bCR5D = bCR5D; Regs.bCR5F = bCR5F; }
fSuccess = TRUE; DISPDBG((0,"IsSufficientBandwidth: OK!")); Error: return(fSuccess); }
/**********************************************************
* * Get7555MCLK() * * Determines the current MCLK frequency. * * Return: The MCLK frequency in KHz (Since the frequency * could exceed 65535KHz, a DWORD is used). * *********************************************************** * Author: Rick Tillery * Date: 09/27/95 * * Revision History: * ----------------- * WHO WHEN WHAT/WHY/HOW * --- ---- ------------ * *********************************************************/ DWORD Get7555MCLK(PDEV * ppdev) { DWORD dwMCLK; int nMCLK; BYTE bTemp;
// Get MCLK register value
CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x1f); nMCLK = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) & 0x3F;
// Calculate actual MCLK frequency
dwMCLK = (14318l * (DWORD)nMCLK) >> 3; CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x12); bTemp = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
// Account for MCLK scaling
if (bTemp & 0x10) { dwMCLK >>= 1; }
return(dwMCLK); }
/**********************************************************
* * IsDSTN() * * Determines whether a DSTN panel is being used for display. * * Return: TRUE/FALSE * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * WHO WHEN WHAT/WHY/HOW * --- ---- ------------ * *********************************************************/ BOOL IsDSTN(PDEV * ppdev) { BOOL bTemp;
/*
* Is this an LCD? */ CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
if (bTemp & 0x01) { /*
* Determine type of LCD. */ CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x83); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x70; bTemp >>= 4 ; if (bTemp == 0) return (TRUE); } return(FALSE); }
/**********************************************************
* * IsXGA() * * Determines whether a XGA panel is being used for display. * * Return: TRUE/FALSE * *********************************************************** * Author: Teresa Tao * Date: 10/22/96 * * Revision History: * ----------------- * WHO WHEN WHAT/WHY/HOW * --- ---- ------------ * *********************************************************/ BOOL IsXGA(PDEV * ppdev) { BOOL bTemp;
/*
* Is this an LCD? */ CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
if (bTemp & 0x01) { /*
* Determine size of LCD. */ CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x83); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x03; if (bTemp == 0x02) return (TRUE); } return (FALSE); }
/**********************************************************
* * ScaleMultiply() * * Calculates product of two DWORD factors supplied. If the * result would overflow a DWORD, the larger of the two factors * is divided by 2 (shifted right) until the overflow will * not occur. * * Returns: Number of right shifts applied to the product. * Product of the factors shifted by the value above. * *********************************************************** * Author: Rick Tillery * Date: 11/18/95 * * Revision History: * ----------------- * WHO WHEN WHAT/WHY/HOW * --- ---- ------------ *********************************************************/ static int ScaleMultiply(DWORD dw1, DWORD dw2, LPDWORD pdwResult) { int iShift = 0; // Start with no shifts
DWORD dwLimit;
// Either factor 0 will be a zero result and also cause a problem
// in our divide below.
if ((0 == dw1) || (0 == dw2)) { *pdwResult = 0; } else { // Determine which factor is larger
if (dw1 > dw2) { // Determine largest number by with dw2 can be multiplied without
// overflowing a DWORD.
dwLimit = 0xFFFFFFFFul / dw2;
// Shift dw1, keeping track of how many times, until it won't
// overflow when multiplied by dw2.
while (dw1 > dwLimit) { dw1 >>= 1; iShift++; } } else { // Determine largest number by with dw1 can be multiplied without
// overflowing a DWORD.
dwLimit = 0xFFFFFFFFul / dw1;
// Shift dw2, keeping track of how many times, until it won't
// overflow when multiplied by dw1.
while (dw2 > dwLimit) { dw2 >>= 1; iShift++; } } // Calculate (scaled) product
*pdwResult = dw1 * dw2; } // Return the number of shifts we had to use
return(iShift); }
//myf31 :
#if 1
/**********************************************************
* * PanOverlay7555 * * If panning scrolling enable, and enable HW video, modified video window value * * Return: none * *********************************************************** * Author: Rita Ma * Date: 02/24/97 * * Revision History: * ----------------- *********************************************************/ VOID PanOverlay7555 (PDEV * ppdev,LONG x,LONG y) // RegInit7555Video (PDEV * ppdev,PDD_SURFACE_LOCAL lpSurface)
{ DWORD dwTemp; DWORD dwFourcc; WORD wBitCount;
LONG lPitch; WORD wTemp; RECTL rDest; WORD wSrcWidth; WORD wSrcWidth_clip; WORD wDestWidth; WORD wSrcHeight; WORD wSrcHeight_clip; WORD wDestHeight; DWORD dwFBOffset; BYTE bRegCR31; BYTE bRegCR32; BYTE bRegCR33; BYTE bRegCR34; BYTE bRegCR35; BYTE bRegCR36; BYTE bRegCR37; BYTE bRegCR38; BYTE bRegCR39; BYTE bRegCR3A; BYTE bRegCR3B; BYTE bRegCR3C; BYTE bRegCR3D; BYTE bRegCR3E; BYTE bRegCR3F; BYTE bRegCR40; BYTE bRegCR41; BYTE bRegCR42;
BYTE bRegCR51; BYTE bTemp; BYTE bVZoom; WORD fTemp=0; ULONG ulTemp=0; BOOL bOverlayTooSmall = FALSE; static DWORD giAdjustSource;
// USHORT VW_h_position, VW_v_position;
// USHORT VW_h_width, VW_v_height;
// ULONG VW_s_addr;
// PanOverlay1_Init return FALSE, exit here
if (!PanOverlay1_7555(ppdev, &rDest)) return;
// rDest is now adjusted & clipped to the panning viewport
// Disable overlay if totally clipped by viewport
//
if (((rDest.right - rDest.left) <= 15) || ((rDest.bottom - rDest.top) <= 0) ) { DisableVideoWindow(ppdev); // disable overlay
return; }
// Initial some value
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x42); bRegCR42 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0xFC; //mask Chroma Key
// keep bit6 video LUT enable
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36); bRegCR36 = (CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x40) | 0x20;
//
// Get video format and color depth of overlay data
//
dwFourcc = ppdev->sOverlay1.dwFourcc; wBitCount= ppdev->sOverlay1.wBitCount; lPitch = ppdev->lPitch_gbls; //??????????
wSrcWidth = (WORD)(LONG)(ppdev->rOverlaySrc.right - ppdev->rOverlaySrc.left); wSrcHeight = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - ppdev->rOverlaySrc.top);
wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip); wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip);
wDestWidth = (WORD)(LONG)(ppdev->rOverlayDest.right - ppdev->rOverlayDest.left); wDestHeight = (WORD)(LONG)(ppdev->rOverlayDest.bottom - ppdev->rOverlayDest.top);
// Determine horizontal upscale coefficient (CR39[7:4],CR31[7:0])
wTemp = ((WORD)(((DWORD)wSrcWidth << 12) / (DWORD)wDestWidth)) & 0x0FFF;
if (wTemp != 0 && bLeft_clip) { srcLeft_clip = srcLeft_clip * (LONG)wTemp/4096 +ppdev->rOverlaySrc.left; wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip); DISPDBG((0,"srcLeft_clip after zoom:%x",srcLeft_clip)); } else if (bLeft_clip) { srcLeft_clip = srcLeft_clip + ppdev->rOverlaySrc.left; wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip); DISPDBG((0,"srcLeft_clip after zoom:%x",srcLeft_clip)); }
bRegCR39 = (BYTE)((wTemp & 0x0F) << 4); bRegCR31 = (BYTE)(wTemp >> 4) & 0xFF;
// Determine vertical upscale coefficient (CR39[3:0],CR32[7:0])
bVZoom=0; wTemp = ((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)wDestHeight)) & 0x0FFF; if (wTemp != 0) { bVZoom=1; fTemp = wTemp; if ( fTemp < 2048 ) // Zoom > 2.0
wTemp=((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)(wDestHeight+1))) & 0x0FFF; } if (wTemp != 0 && bTop_clip) { srcTop_clip = srcTop_clip * (LONG)wTemp/4096 + ppdev->rOverlaySrc.top; wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip); DISPDBG((0,"srcTop_clip after zoom:%x",srcTop_clip)); } else if (bTop_clip) { srcTop_clip = srcTop_clip + ppdev->rOverlaySrc.top; wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip); DISPDBG((0,"srcTop_clip after zoom:%x",srcTop_clip)); }
bRegCR39 |= (BYTE)(wTemp & 0x0F); bRegCR32 = (BYTE)(wTemp >> 4) & 0xFF; DISPDBG((0,"wTemp = 0x%x",wTemp));
// Determine Vertical Height (CR38[7:0], CR36[3:2])
wTemp = wSrcHeight_clip; if (wTemp != 0 && ( fTemp > 2730 || fTemp ==0 || ( fTemp > 1365 && fTemp < 2048 ) ) ) wTemp--; //#tt10, Height minus one only if upscale rate <1.5
//#tt10 2 < <3
bRegCR38 = (BYTE)wTemp; bRegCR36 |= (wTemp & 0x0300) >> 6;
// Determine Horizontal position start (CR34[7:0], CR33[7:5])
wTemp = (WORD)rDest.left; bRegCR34 = (BYTE)wTemp; bRegCR33 = (wTemp & 0x0700) >> 3;
// Reset Brightness control (CR35[7:0])
bRegCR35 = 0x0;
// Determine Vertical Start (CR37[7:0], CR36[1:0])
wTemp = (WORD)rDest.top; bRegCR37 = (BYTE)wTemp; bRegCR36 |= (wTemp & 0x0300) >> 8;
// Determine Video Start Address (CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0])
// giAdjustSource = (ppdev->rOverlaySrc.top * lpSurface->lpGbl->lPitch)
// + ((ppdev->rOverlaySrc.left * wBitCount) >> 3);
dwTemp = srcTop_clip * lPitch; dwTemp = (srcLeft_clip * wBitCount) >> 3; giAdjustSource = (srcTop_clip * lPitch) + ((srcLeft_clip * wBitCount) >> 3);
ppdev->sOverlay1.lAdjustSource = giAdjustSource; //myf32
dwFBOffset = (DWORD)(ppdev->fpVidMem_gbls + giAdjustSource);
DISPDBG((0,"giAdjustSource = 0x%08x",giAdjustSource)); DISPDBG((0,"dwFBOffset = 0x%08x",dwFBOffset));
dwFBOffset >>= 2;
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3A); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
bRegCR3A = (bTemp & ~0x7F) | (BYTE)((dwFBOffset & 0x0FE000) >> 13); bRegCR3E = (BYTE)((dwFBOffset & 0x001FE0) >> 5);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3F); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); bRegCR3F = (bTemp & ~0x0F) | (BYTE)((dwFBOffset & 0x00001E) >> 1);
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x40); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ; bRegCR40 = (bTemp & ~0x01) | (BYTE)(dwFBOffset & 0x000001);
//Determine Video Pitch (CR3B[7:0], CR36[4])
wTemp = (WORD)(lPitch >> 4); //QWORDs
bRegCR3B = (BYTE)wTemp; bRegCR36 |= (wTemp & 0x0100) >> 4;
// Determine Data Format (CR3E[3:0])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C); bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x10;
switch (dwFourcc) { case FOURCC_PACKJR: bRegCR3C |= 0x02; // Pack JR
break;
case BI_RGB: switch(wBitCount) { case 8: bRegCR3C |= 0x09; // 8 bit palettized
break;
case 16: bRegCR3C |= 0x01; // RGB 5:5:5
break; } break;
case BI_BITFIELDS: switch(wBitCount) { case 8: bRegCR3C |= 0x09; // 8 bit palettized
break;
case 16: bRegCR3C |= 0x04; // RGB 5:6:5
break; } break;
case FOURCC_YUV422: bRegCR3C |= 0x03; // YUV 4:2:2
break;
case FOURCC_YUY2: //myf34 test
bRegCR3C |= 0x03; // YUY2
// CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x2C);
// bRegSR2C = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
// bRegSR2C |= 0x40; //SR2c[6] = 1
// CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x2C |(WORD)bRegSR2C << 8);
break; }
// Determine Horizontal width (CR3D[7:0], CR3C[7:5])
// NOTE: assumes Horz Pixel Width [0] = 0
wTemp = wSrcWidth_clip;
if (wTemp != 0 ) wTemp--; //Width minus one for laptop
bRegCR3D = (BYTE)((WORD)wTemp >> 1); bRegCR3C |= (wTemp & 0x0600) >> 3; bRegCR3C |= (BYTE)((wTemp & 0x0001) << 5) ;
// Enable Horizontal Pixel Interpolation (CR3F[7])
bRegCR3F |= 0x80;
// Enable Vertical Pixel Interpolation (CR3F[6])
//#tt Debug- The CE rev. has problem when vertical interpolation is on
//#tt Debug- Disable it for now.
//#tt bRegCR3F |= 0x40;
// Enable Right Side transition threshold (CR41[5:0])
bRegCR41 = 0x3E;
// Disable V-PORT (CR58[7:0])
bRegCR51 = 0x0;
// Disable CR5D if in panning & upscaling
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80); //myf33 if (bVZoom && (BYTE)wPanFlag)
if (bVZoom && (CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x01)) //myf33
{ CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x5F); bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & ~0x80; CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (UCHAR)bTemp); }
#if 0 // bad ideal code
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C); bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x10;
if (bRegCR3C) { // Horizontal position start (CR33[7:5], CR34[7:0])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x34); bRegCR34 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x33); bRegCR33 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); VW_h_position = ((USHORT)(bRegCR33 & 0xE0)) << 3; VW_h_position |= (USHORT)bRegCR34;
// Vertical position start (CR36[1:0], CR37[7:0])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x37); bRegCR37 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36); bRegCR36 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); VW_v_position = ((USHORT)(bRegCR36 & 0x03)) << 8; VW_v_position |= (USHORT)bRegCR37;
//Video horizontal width (CR3C[7:6], CR3D[7:0], CR3C[5])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3D); bRegCR3D = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C); bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); VW_h_width = (WORD)(bRegCR3C & 0x01); VW_h_width |= (((USHORT)(bRegCR3C & 0xC0)) << 3); VW_h_width |= (((USHORT)bRegCR3D) << 1);
//Video vertical height (CR36[3:2], CR38[7:0])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x38); bRegCR38 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); // CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36);
// bRegCR36 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
VW_v_height = ((USHORT)(bRegCR36 & 0x0C)) << 6; VW_v_height |= ((USHORT)bRegCR38);
//Video memory offset register (CR36[4], CR3B[7:0])
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3B); bRegCR3B = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); lPitch = ((USHORT)(bRegCR36 & 0x10)) << 4; lPitch |= ((USHORT)bRegCR3B); lPitch <<= 4;
//Video memory start address (CR3A[6:0], CR3E[7:0], CR3F[3:0], CR40[0])
// update sequence CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0]
CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x40); bRegCR40 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3A); bRegCR3A = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3E); bRegCR3E = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3F); bRegCR3F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA); #if 0
VW_s_addr = (ULONG)(bRegCR40 & 0x01); VW_s_addr |= (((ULONG)(bRegCR3F & 0x0F)) << 1); VW_s_addr |= (((ULONG)bRegCR3E) << 5); VW_s_addr |= (((ULONG)(bRegCR3A & 0x7F)) << 13); VW_s_addr <<= 2; #endif
// Update Video window Horizontal & Vertical position
DISPDBG((0,"PAN--Xmin=%x, Xmax=%x\n",ppdev->min_Xscrren,ppdev->max_Xscrren)); DISPDBG((0,"PAN--Ymin=%x, Ymax=%x\n",ppdev->min_Yscrren,ppdev->max_Yscrren)); DISPDBG((0,"PAN--h_position=%x, v_position=%x\n",VW_h_position, VW_v_position)); DISPDBG((0,"PAN--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width));
if (((ppdev->min_Xscreen <= VW_h_position) && (ppdev->max_Xscreen >= VW_h_position)) && ((ppdev->min_Yscreen <= VW_v_position) && (ppdev->max_Yscreen >= VW_v_position))) { VW_h_position -= ppdev->min_Xscreen; VW_v_position -= ppdev->min_Yscreen; DISPDBG((0,"(1)--h_position=%x, v_position=%x\n",VW_h_position, VW_v_position)); DISPDBG((0,"(1)--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width)); } // Video window in the left or right
else if ((ppdev->max_Xscreen < VW_h_position) || (ppdev->min_Xscreen > (VW_h_position+VW_h_width))) { DisableVideoWindow(ppdev); // disable overlay
ppdev->dwPanningFlag |= OVERLAY_OLAY_REENABLE; // totally clipped
DISPDBG((0,"(2)--DisableVideoWindow\n")); } // Video window in the top or bottom
else if ((ppdev->max_Yscreen < VW_v_position) || (ppdev->min_Yscreen > (VW_v_position+VW_v_height))) { DisableVideoWindow(ppdev); // disable overlay
ppdev->dwPanningFlag |= OVERLAY_OLAY_REENABLE; // totally clipped
DISPDBG((0,"(3)--DisableVideoWindow\n")); } // Update Video window memory start address
else if ((ppdev->min_Xscreen > VW_h_position) && (ppdev->min_Xscreen < (VW_h_position+VW_h_width))) { if ((ppdev->min_Xscreen-VW_h_position) > 0) { ppdev->rOverlaySrc.left = ppdev->min_Xscreen - VW_h_position; VW_h_position = ppdev->min_Xscreen; VW_h_width -= ppdev->rOverlaySrc.left; } if ((ppdev->min_Yscreen-VW_v_position) > 0) { ppdev->rOverlaySrc.top = ppdev->min_Yscreen - VW_v_position; VW_v_position = ppdev->min_Yscreen; VW_v_height -= ppdev->rOverlaySrc.top; } DISPDBG((0,"(4)--h_position=%x, v_position=%x\n",VW_h_position, VW_v_position)); DISPDBG((0,"(4)--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width)); DISPDBG((0,"(4)--Overlay.top=%x, left=%x\n",ppdev->rOverlaySrc.top, ppdev->rOverlaySrc.left)); } else if ((ppdev->min_Yscreen > VW_v_position) && (ppdev->min_Yscreen < (VW_v_position+VW_v_height))) { if ((ppdev->min_Xscreen-VW_h_position) > 0) { ppdev->rOverlaySrc.left = ppdev->min_Xscreen - VW_h_position; VW_h_position = ppdev->min_Xscreen; VW_h_width -= ppdev->rOverlaySrc.left; } if ((ppdev->min_Yscreen-VW_v_position) > 0) { ppdev->rOverlaySrc.top = ppdev->min_Yscreen - VW_v_position; VW_v_position = ppdev->min_Yscreen; VW_v_height -= ppdev->rOverlaySrc.top; } DISPDBG((0,"(5)--h_position=%x, v_position=%x\n",VW_h_position, VW_v_position)); DISPDBG((0,"(5)--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width)); } giAdjustSource = (ppdev->rOverlaySrc.top * lPitch) // ppdev->lpSrcColorSurface->lpGbl->lPitch)
+ ((ppdev->rOverlaySrc.left * ppdev->sOverlay1.wBitCount) >> 3);
// DISPDBG((0,"lpSurface->fpVisibleOverlay= \n0x%08x\n",
// ppdev->fpVisibleOverlay));
// DISPDBG((0,"lpSurface->fpBaseOverlay = 0x%08x\n",
// ppdev->fpBaseOverlay));
DISPDBG((0,"PAN--fpVidMem=0x%8x\t",ppdev->fpVidMem)); DISPDBG((0,"PAN--giAdjustSource = 0x%08x\n",giAdjustSource)); dwFBOffset = (ppdev->fpVidMem_gbls - ) + giAdjustSource;
DISPDBG((0,"PAN--dwFBOffset = 0x%08x\n",dwFBOffset));
dwFBOffset >>= 2;
//Update Horizontal position start (CR33[7:5], CR34[7:0])
bRegCR34 = (BYTE)(VW_h_position & 0xFF); bRegCR33 &= 0x1F; bRegCR33 |= ((BYTE)((VW_h_position & 0x0700) >> 3));
// Vertical position start (CR36[1:0], CR37[7:0])
bRegCR37 = (BYTE)(VW_v_position & 0xFF); bRegCR36 &= 0xFC; bRegCR36 |= ((BYTE)((VW_v_position & 0x0300) >> 8));
//Video horizontal width (CR3C[7:6], CR3D[7:0], CR3C[5])
bRegCR3D = (BYTE)((VW_h_width & 0x1FE) >> 1); bRegCR3C &= 0x1F; bRegCR3C |= ((BYTE)(VW_h_width & 0x01)) << 5; bRegCR3C |= ((BYTE)((VW_h_width & 0x0600) >> 3));
//Video vertical height (CR36[3:2], CR38[7:0])
bRegCR38 = (BYTE)(VW_v_height & 0xFF); bRegCR36 &= 0xF3; bRegCR36 |= ((BYTE)((VW_v_height & 0x0300) >> 6));
//Video memory start address (CR3A[6:0], CR3E[7:0], CR3F[3:0], CR40[0])
// update sequence CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0]
bRegCR40 &= 0xFE; bRegCR40 |= (BYTE)(dwFBOffset & 0x01); bRegCR3F &= 0xF0; bRegCR3F |= ((BYTE)(dwFBOffset & 0x1E)) >> 1; bRegCR3E = (BYTE)((dwFBOffset & 0x1FE0) >> 5); bRegCR3A &= 0x80; bRegCR3A |= ((BYTE)((dwFBOffset & 0xFE000) >> 13)); #endif /0 - bad ideal
//
/*
* Program the video window registers */ CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x31 | (WORD)bRegCR31 << 8);//CR31
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x32 | (WORD)bRegCR32 << 8);//CR32
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x33 | (WORD)bRegCR33 << 8);//CR33
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x34 | (WORD)bRegCR34 << 8);//CR34
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x35 | (WORD)bRegCR35 << 8);//CR35
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x36 | (WORD)bRegCR36 << 8);//CR36
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x37 | (WORD)bRegCR37 << 8);//CR37
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x38 | (WORD)bRegCR38 << 8);//CR38
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x39 | (WORD)bRegCR39 << 8);//CR39
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3B | (WORD)bRegCR3B << 8);//CR3B
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3C | (WORD)bRegCR3C << 8);//CR3C
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3D | (WORD)bRegCR3D << 8);//CR3D
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x41 | (WORD)bRegCR41 << 8);//CR41
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x42 | (WORD)bRegCR42 << 8);//CR42
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x51 | (WORD)bRegCR51 << 8);//CR51
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x40 | (WORD)bRegCR40 << 8);//CR40
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3A | (WORD)bRegCR3A << 8);//CR3A
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3E | (WORD)bRegCR3E << 8);//CR3E
CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3F | (WORD)bRegCR3F << 8);//CR3F
// enable overlay if overlay was totally clipped by pnning viewport
//
if (ppdev->dwPanningFlag & OVERLAY_OLAY_REENABLE) EnableVideoWindow (ppdev); } #endif
//myf31 end
#endif // DirectDraw
|