Source code of Windows XP (NT5)
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.

2184 lines
71 KiB

  1. /**********************************************************
  2. * Copyright (c) 1996-1997 Microsoft Corporation.
  3. * Copyright (c) 1996-1997 Cirrus Logic, Inc.
  4. ***********************************************************
  5. * File Name: 7555OVER.C
  6. *
  7. * Module Abstract:
  8. * ----------------
  9. * This contains functions needed to support overlay hardware.
  10. *
  11. * Functions:
  12. * ----------
  13. *
  14. ***********************************************************
  15. * Author: Teresa Tao
  16. * Date: 10/22/96
  17. *
  18. * Revision History:
  19. * -----------------
  20. * myf31 :02-24-97 : Fixed enable HW Video, panning scrolling enable,screen move
  21. * video window have follow moving
  22. * myf34 :04-15-97 : Supported YUY2 format for NT.
  23. ***********************************************************/
  24. /* #includes ---------------------------------------------*/
  25. #include "PreComp.h"
  26. #if DIRECTDRAW
  27. #include "overlay.h"
  28. #include "7555bw.h"
  29. static int ScaleMultiply(DWORD dw1,
  30. DWORD dw2,
  31. LPDWORD pdwResult);
  32. /**********************************************************
  33. *
  34. * Name: RegInit7555Video
  35. *
  36. * Module Abstract:
  37. * ----------------
  38. * This function is called to program the video format and
  39. * the physicall offset of the video data in the frame buffer.
  40. *
  41. * Output Parameters:
  42. * ------------------
  43. * none
  44. *
  45. ***********************************************************
  46. * Author: Teresa Tao
  47. * Date: 10/22/96
  48. *
  49. * Revision History:
  50. * -----------------
  51. *
  52. *********************************************************/
  53. VOID RegInit7555Video (PDEV * ppdev,PDD_SURFACE_LOCAL lpSurface)
  54. {
  55. DWORD dwTemp;
  56. DWORD dwFourcc;
  57. WORD wBitCount;
  58. LONG lPitch;
  59. WORD wTemp;
  60. RECTL rDest;
  61. WORD wSrcWidth;
  62. WORD wSrcWidth_clip;
  63. WORD wDestWidth;
  64. WORD wSrcHeight;
  65. WORD wSrcHeight_clip;
  66. WORD wDestHeight;
  67. DWORD dwFBOffset;
  68. BYTE bRegCR31;
  69. BYTE bRegCR32;
  70. BYTE bRegCR33;
  71. BYTE bRegCR34;
  72. BYTE bRegCR35;
  73. BYTE bRegCR36;
  74. BYTE bRegCR37;
  75. BYTE bRegCR38;
  76. BYTE bRegCR39;
  77. BYTE bRegCR3A;
  78. BYTE bRegCR3B;
  79. BYTE bRegCR3C;
  80. BYTE bRegCR3D;
  81. BYTE bRegCR3E;
  82. BYTE bRegCR3F;
  83. BYTE bRegCR40;
  84. BYTE bRegCR41;
  85. BYTE bRegCR42;
  86. BYTE bRegCR51;
  87. BYTE bRegCR5D; //myf32
  88. BYTE bRegCR5F; //myf32
  89. BYTE bRegSR2F; //myf32
  90. BYTE bRegSR32; //myf32
  91. BYTE bRegSR34; //myf32
  92. BYTE bTemp;
  93. BYTE bVZoom;
  94. WORD fTemp=0;
  95. ULONG ulTemp=0;
  96. BOOL bOverlayTooSmall = FALSE;
  97. static DWORD giAdjustSource;
  98. //myf32 added
  99. bRegSR2F = Regs.bSR2F;
  100. bRegSR32 = Regs.bSR32;
  101. bRegSR34 = Regs.bSR34;
  102. bRegCR5D = Regs.bCR5D;
  103. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x5F);
  104. bRegCR5F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  105. bRegCR5F |= (Regs.bCR5F & 0x80);
  106. //myf32 end
  107. /*
  108. * Init some values
  109. */
  110. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x42);
  111. // bRegCR42 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0xFC; //mask Chroma key
  112. // & FIFO
  113. bRegCR42 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0xF0; //mask Chroma key
  114. // & FIFO, myf32
  115. bRegCR42 |= (Regs.bCR42 & CR42_MVWTHRESH); //myf32
  116. bRegCR42 |= 0x10;
  117. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36); //myf29
  118. bRegCR36 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x40; //myf29
  119. bRegCR36 |= 0x20; //set Excess 128 Data Format, myf29
  120. /*
  121. * Determine the format of the video data
  122. */
  123. if (lpSurface->dwFlags & DDRAWISURF_HASPIXELFORMAT)
  124. {
  125. GetFormatInfo (ppdev,&(lpSurface->lpGbl->ddpfSurface),
  126. &dwFourcc, &wBitCount);
  127. }
  128. else
  129. {
  130. // This needs to be changed when primary surface is RGB 5:6:5
  131. dwFourcc = BI_RGB;
  132. wBitCount = (WORD) ppdev->cBitsPerPixel;
  133. }
  134. /*
  135. * Determine the rectangle for the video window
  136. */
  137. PanOverlay1_Init(ppdev, lpSurface, &rDest, &ppdev->rOverlaySrc,
  138. &ppdev->rOverlayDest, dwFourcc, wBitCount);
  139. // rVideoRect is now adjusted and clipped to the panning viewport.
  140. // disable overlay if totally clipped by viewport
  141. if (((rDest.right - rDest.left) <= 0) ||
  142. ((rDest.bottom - rDest.top) <= 0))
  143. {
  144. bOverlayTooSmall = TRUE;
  145. }
  146. dwTemp = (DWORD)(ppdev->min_Yscreen - ppdev->rOverlayDest.top);
  147. if ((ppdev->rOverlaySrc.bottom - ppdev->rOverlaySrc.top -(LONG)dwTemp) <=0)
  148. bOverlayTooSmall = TRUE;
  149. lPitch = lpSurface->lpGbl->lPitch;
  150. wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip);
  151. wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip);
  152. wSrcWidth = (WORD)(LONG)(ppdev->rOverlaySrc.right - ppdev->rOverlaySrc.left);
  153. wDestWidth = (WORD)(LONG)(ppdev->rOverlayDest.right - ppdev->rOverlayDest.left);
  154. wSrcHeight = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - ppdev->rOverlaySrc.top);
  155. wDestHeight = (WORD)(LONG)(ppdev->rOverlayDest.bottom - ppdev->rOverlayDest.top);
  156. // Determine horizontal upscale coefficient (CR31[7:0],CR39[7:4])
  157. wTemp = ((WORD)(((DWORD)wSrcWidth << 12) / (DWORD)wDestWidth)) & 0x0FFF;
  158. if (wTemp != 0 && bLeft_clip)
  159. {
  160. srcLeft_clip = srcLeft_clip *(LONG)wTemp/4096 + ppdev->rOverlaySrc.left;
  161. wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip);
  162. }
  163. else if (bLeft_clip)
  164. {
  165. srcLeft_clip = srcLeft_clip + ppdev->rOverlaySrc.left;
  166. wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip);
  167. }
  168. bRegCR39 = (BYTE)((wTemp & 0x0F) << 4);
  169. bRegCR31 = (BYTE)(wTemp >> 4) & 0xFF;
  170. // Determine vertical upscale coefficient (CR32[7:0],CR39[3:0])
  171. bVZoom=0;
  172. wTemp = ((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)wDestHeight)) & 0x0FFF;
  173. if (wTemp != 0) {
  174. bVZoom=1;
  175. fTemp = wTemp;
  176. if (fTemp < 2048 ) // Zoom > 2.0
  177. wTemp=((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)(wDestHeight+1))) & 0x0FFF;
  178. }
  179. if (wTemp != 0 && bTop_clip)
  180. {
  181. srcTop_clip = srcTop_clip * (LONG)wTemp/4096 + ppdev->rOverlaySrc.top;
  182. wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom -srcTop_clip);
  183. }
  184. else if (bTop_clip)
  185. {
  186. srcTop_clip = srcTop_clip + ppdev->rOverlaySrc.top;
  187. wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom -srcTop_clip);
  188. }
  189. bRegCR39 |= (BYTE)(wTemp & 0x0F);
  190. bRegCR32 = (BYTE)(wTemp >> 4) & 0xFF;
  191. DISPDBG((0,"wTemp = 0x%x",wTemp));
  192. // Determine Vertical Height (CR38[7:0], CR36[3:2])
  193. // wTemp = wSrcHeight;
  194. wTemp = wSrcHeight_clip; //myf32
  195. DISPDBG((0,"fTemp = 0x%x",fTemp));
  196. if (wTemp != 0 &&
  197. (fTemp > 2730 || fTemp ==0 || ( fTemp > 1365 && fTemp < 2048 ) ) )
  198. wTemp--; //#tt10, Height minus one only if upscale rate <1.5
  199. //#tt10 2 < <3
  200. bRegCR38 = (BYTE)wTemp;
  201. bRegCR36 |= (wTemp & 0x0300) >> 6;
  202. // Determine Horizontal position start (CR34[7:0], CR33[7:5])
  203. // handle 7555-BB MVA pitch bug (QWORD should be DWORD)
  204. wTemp = (WORD)rDest.left;
  205. bRegCR34 = (BYTE)wTemp;
  206. bRegCR33 = (wTemp & 0x0700) >> 3;
  207. // Reset Brightness control (CR35[7:0])
  208. bRegCR35 = 0x0;
  209. // Determine Vertical Start (CR37[7:0], CR36[1:0])
  210. wTemp = (WORD)rDest.top;
  211. bRegCR37 = (BYTE)wTemp;
  212. bRegCR36 |= (wTemp & 0x0300) >> 8;
  213. // Determine Video Start Address (CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0])
  214. giAdjustSource = (srcTop_clip * lpSurface->lpGbl->lPitch)
  215. + ((srcLeft_clip * wBitCount) >> 3); //myf32
  216. // giAdjustSource = (ppdev->rOverlaySrc.top * lpSurface->lpGbl->lPitch)
  217. // + ((ppdev->rOverlaySrc.left * wBitCount) >> 3);
  218. ppdev->sOverlay1.lAdjustSource = giAdjustSource; //myf32
  219. dwFBOffset = (DWORD)(lpSurface->lpGbl->fpVidMem + giAdjustSource);
  220. // dwFBOffset = (lpSurface->lpGbl->fpVidMem - ppdev->dwScreenFlatAddr)
  221. // + giAdjustSource; //myf32
  222. DISPDBG((0,"lpSurface->lpGbl->fpVidMem = 0x%08x",
  223. lpSurface->lpGbl->fpVidMem));
  224. DISPDBG((0,"giAdjustSource = 0x%08x",giAdjustSource));
  225. DISPDBG((0,"dwFBOffset = 0x%08x",dwFBOffset));
  226. dwFBOffset >>= 2;
  227. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3A);
  228. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  229. bRegCR3A = (bTemp & ~0x7F) | (BYTE)((dwFBOffset & 0x0FE000) >> 13);
  230. bRegCR3E = (BYTE)((dwFBOffset & 0x001FE0) >> 5);
  231. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3F);
  232. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  233. bRegCR3F = (bTemp & ~0x0F) | (BYTE)((dwFBOffset & 0x00001E) >> 1);
  234. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x40);
  235. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  236. bRegCR40 = (bTemp & ~0x01) | (BYTE)(dwFBOffset & 0x000001);
  237. //Determine Video Pitch (CR3B[7:0], CR36[4])
  238. wTemp = (WORD)(lpSurface->lpGbl->lPitch >> 4); //QWORDs
  239. bRegCR3B = (BYTE)wTemp;
  240. bRegCR36 |= (wTemp & 0x0100) >> 4;
  241. // Determine Data Format (CR3E[3:0])
  242. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C);
  243. bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x10;
  244. //mask out prev VW width
  245. switch (dwFourcc)
  246. {
  247. case FOURCC_PACKJR:
  248. bRegCR3C |= 0x02; // Pack JR
  249. break;
  250. case BI_RGB:
  251. switch(wBitCount)
  252. {
  253. case 8:
  254. bRegCR3C |= 0x09; // 8 bit palettized
  255. break;
  256. case 16:
  257. bRegCR3C |= 0x01; // RGB 5:5:5
  258. break;
  259. }
  260. break;
  261. //myf32 added
  262. case BI_BITFIELDS:
  263. switch(wBitCount)
  264. {
  265. case 8:
  266. bRegCR3C |= 0x09; // 8 bit palettized
  267. break;
  268. case 16:
  269. bRegCR3C |= 0x04; // RGB 5:6:5
  270. break;
  271. }
  272. break;
  273. //myf32 end
  274. case FOURCC_YUV422:
  275. bRegCR3C |= 0x03; // YUV 4:2:2
  276. break;
  277. case FOURCC_YUY2: //myf34 test
  278. bRegCR3C |= 0x03; // YUY2
  279. // CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x2C);
  280. // bRegSR2C = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
  281. // bRegSR2C |= 0x40; //SR2c[6] = 1
  282. // CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x2C |(WORD)bRegSR2C << 8);
  283. break;
  284. }
  285. // Determine Horizontal width (CR3D[7:0], CR3C[7:5])
  286. // NOTE: assumes Horz Pixel Width [0] = 0
  287. wTemp = wSrcWidth_clip; //myf32
  288. // wTemp = wSrcWidth;
  289. if (wTemp != 0 ) wTemp--; //Width minus one for laptop
  290. bRegCR3D = (BYTE)((WORD)wTemp >> 1);
  291. bRegCR3C |= (wTemp & 0x0600) >> 3;
  292. bRegCR3C |= (BYTE)((wTemp & 0x0001) << 5) ;
  293. // Enable Horizontal Pixel Interpolation (CR3F[7])
  294. bRegCR3F |= 0x80;
  295. // Enable Vertical Pixel Interpolation (CR3F[6])
  296. //#tt Debug- The CE rev. has problem when vertical interpolation is on
  297. //#tt Debug- Disable it for now.
  298. //#tt bRegCR3F |= 0x40;
  299. // Enable Right Side transition threshold (CR41[5:0])
  300. bRegCR41 = 0x3E;
  301. // Disable V-PORT (CR58[7:0])
  302. bRegCR51 = 0x0;
  303. /*
  304. * If we are color keying, we will set that up now
  305. */
  306. if (lpSurface->dwReserved1 & OVERLAY_FLG_COLOR_KEY)
  307. {
  308. bRegCR3F |= 0x20; //Enable Occlusion
  309. bRegCR42 &= ~0x1; //Disable Chroma Key
  310. bRegCR5F &= ~0x80; //myf32 //Disable CR5D[7:0] if color key,
  311. //so disable CR5F[7]
  312. bRegCR5D = 0; //myf32
  313. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1A);
  314. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  315. // Set CR1A[3:2] to timing ANDed w/ color
  316. bTemp &= ~0x0C;
  317. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, bTemp);
  318. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1D);
  319. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  320. if (ppdev->cBitsPerPixel == 8)
  321. {
  322. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (bTemp & ~0x38));
  323. ulTemp= 0x0C | (ppdev->wColorKey << 8);
  324. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRC
  325. ulTemp= 0x0D;
  326. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRD
  327. }
  328. else
  329. {
  330. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (bTemp & ~0x30) | 0x08);
  331. ulTemp= 0x0C | (ppdev->wColorKey << 8);
  332. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRC
  333. ulTemp= 0x0D | (ppdev->wColorKey & 0xff00);
  334. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, ulTemp);// Output color to GRD
  335. }
  336. }
  337. else if (lpSurface->dwReserved1 & OVERLAY_FLG_SRC_COLOR_KEY)
  338. {
  339. BYTE bYMax, bYMin, bUMax, bUMin, bVMax, bVMin;
  340. bRegCR3F |= 0x20; //Enable Occlusion
  341. bRegCR42 |= 0x1; //Enable Chroma Key
  342. bRegCR5F &= ~0x80; //myf32 //Disable CR5D[7:0] if color key,
  343. //so disable CR5F[7]
  344. bRegCR5D = 0; //myf32
  345. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1A);
  346. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  347. // Set CR1A[3:2] to timing ANDed w/ color
  348. bTemp &= ~0x0C;
  349. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, bTemp);
  350. /*
  351. * Determine min/max values
  352. */
  353. if ((dwFourcc == FOURCC_YUV422) || (dwFourcc == FOURCC_YUVPLANAR) ||
  354. (dwFourcc == FOURCC_YUY2) || //myf34
  355. (dwFourcc == FOURCC_PACKJR)) //myf32
  356. {
  357. bYMax = (BYTE)(DWORD)(ppdev->dwSrcColorKeyHigh >> 16);
  358. bYMin = (BYTE)(DWORD)(ppdev->dwSrcColorKeyLow >> 16);
  359. bUMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 8) & 0xff);
  360. bUMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 8) & 0xff);
  361. bVMax = (BYTE)(ppdev->dwSrcColorKeyHigh & 0xff);
  362. bVMin = (BYTE)(ppdev->dwSrcColorKeyLow & 0xff);
  363. if (dwFourcc == FOURCC_PACKJR)
  364. {
  365. bYMax |= 0x07;
  366. bUMax |= 0x03;
  367. bVMax |= 0x03;
  368. bYMin &= ~0x07;
  369. bUMin &= ~0x03;
  370. bVMin &= ~0x03;
  371. }
  372. }
  373. else if ((dwFourcc == 0) && (wBitCount == 16))
  374. {
  375. /*
  376. * RGB 5:5:5
  377. */
  378. bYMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 7) & 0xF8);
  379. bYMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 7) & 0xF8);
  380. bUMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 2) & 0xF8);
  381. bUMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 2) & 0xF8);
  382. bVMax = (BYTE)(ppdev->dwSrcColorKeyHigh << 3);
  383. bVMin = (BYTE)(ppdev->dwSrcColorKeyLow << 3);
  384. bYMax |= 0x07;
  385. bUMax |= 0x07;
  386. bVMax |= 0x07;
  387. }
  388. else if (dwFourcc == BI_BITFIELDS)
  389. {
  390. /*
  391. * RGB 5:6:5
  392. */
  393. bYMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 8) & 0xF8);
  394. bYMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 8) & 0xF8);
  395. bUMax = (BYTE)(DWORD)((ppdev->dwSrcColorKeyHigh >> 3) & 0xFC);
  396. bUMin = (BYTE)(DWORD)((ppdev->dwSrcColorKeyLow >> 3) & 0xFC);
  397. bVMax = (BYTE)(ppdev->dwSrcColorKeyHigh << 3);
  398. bVMin = (BYTE)(ppdev->dwSrcColorKeyLow << 3);
  399. bYMax |= 0x07;
  400. bUMax |= 0x03;
  401. bVMax |= 0x07;
  402. }
  403. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x0C | (WORD)bYMin <<8));//GRC
  404. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x0D | (WORD)bYMax <<8));//GRd
  405. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1C | (WORD)bUMin <<8));//GR1C
  406. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1D | (WORD)bUMax <<8));//GR1D
  407. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1E | (WORD)bVMin <<8));//GR1E
  408. CP_OUT_WORD(ppdev->pjPorts, INDEX_REG, (0x1F | (WORD)bVMax <<8));//GR1F
  409. }
  410. else
  411. {
  412. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x1A);
  413. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  414. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, (bTemp & ~0x0C));
  415. bRegCR3F &= ~0x20; // disable occlusion
  416. }
  417. /*
  418. * Set up alignment info
  419. */
  420. if (ppdev->cBitsPerPixel != 24)
  421. {
  422. WORD wXAlign;
  423. WORD wXSize;
  424. if (ppdev->cBitsPerPixel == 8)
  425. {
  426. wXAlign = (WORD)rDest.left & 0x03;
  427. wXSize = (WORD)(rDest.right - rDest.left) & 0x03;
  428. }
  429. else
  430. {
  431. wXAlign = (WORD)(rDest.left & 0x01) << 1;
  432. wXSize = (WORD)((rDest.right - rDest.left) & 0x01) << 1;
  433. }
  434. }
  435. // disable overlay if totally clipped by viewport
  436. // or overlay is too small to be supported by HW
  437. //
  438. if (bOverlayTooSmall)
  439. {
  440. DisableVideoWindow(ppdev); // disable overlay
  441. ppdev->dwPanningFlag |= OVERLAY_OLAY_REENABLE; // totally clipped
  442. }
  443. else
  444. {
  445. /*
  446. * Program the video window registers
  447. */
  448. //myf32 added
  449. CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x2F |(WORD)bRegSR2F << 8);//SR2F
  450. CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x32 |(WORD)bRegSR32 << 8);//SR32
  451. CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x34 |(WORD)bRegSR34 << 8);//SR34
  452. //myf32 end
  453. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x31 | (WORD)bRegCR31 << 8);//CR31
  454. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x32 | (WORD)bRegCR32 << 8);//CR32
  455. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x34 | (WORD)bRegCR34 << 8);//CR34
  456. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x33 | (WORD)bRegCR33 << 8);//CR33
  457. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x35 | (WORD)bRegCR35 << 8);//CR35
  458. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x36 | (WORD)bRegCR36 << 8);//CR36
  459. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x37 | (WORD)bRegCR37 << 8);//CR37
  460. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x38 | (WORD)bRegCR38 << 8);//CR38
  461. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x39 | (WORD)bRegCR39 << 8);//CR39
  462. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3B | (WORD)bRegCR3B << 8);//CR3B
  463. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3C | (WORD)bRegCR3C << 8);//CR3C
  464. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3D | (WORD)bRegCR3D << 8);//CR3D
  465. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x41 | (WORD)bRegCR41 << 8);//CR41
  466. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x42 | (WORD)bRegCR42 << 8);//CR42
  467. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x51 | (WORD)bRegCR51 << 8);//CR51
  468. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x40 | (WORD)bRegCR40 << 8);//CR40
  469. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3A | (WORD)bRegCR3A << 8);//CR3A
  470. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3E | (WORD)bRegCR3E << 8);//CR3E
  471. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3F | (WORD)bRegCR3F << 8);//CR3F
  472. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x5D | (WORD)bRegCR5D << 8);//CR5D
  473. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x5F | (WORD)bRegCR5F << 8);//CR5F
  474. if (lpSurface->dwReserved1 & OVERLAY_FLG_YUVPLANAR)
  475. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3F |(WORD)0x10 <<8);
  476. EnableVideoWindow (ppdev);
  477. }
  478. }
  479. /**********************************************************
  480. *
  481. * Name: RegMoveVideo
  482. *
  483. * Module Abstract:
  484. * ----------------
  485. * This function is called to move the video window that has
  486. * already been programed.
  487. *
  488. * Output Parameters:
  489. * ------------------
  490. * none
  491. *
  492. ***********************************************************
  493. * Author: Teresa Tao
  494. * Date: 10/22/96
  495. *
  496. * Revision History:
  497. * -----------------
  498. *
  499. *********************************************************/
  500. VOID RegMove7555Video (PDEV * ppdev,PDD_SURFACE_LOCAL lpSurface)
  501. {
  502. RegInitVideo (ppdev,lpSurface);
  503. }
  504. /**********************************************************
  505. *
  506. * Name: DisableVideoWindow
  507. *
  508. * Module Abstract:
  509. * ----------------
  510. * turn off video window
  511. *
  512. * Output Parameters:
  513. * ------------------
  514. * none
  515. *
  516. ***********************************************************
  517. * Author: Teresa Tao
  518. * Date: 10/22/96
  519. *
  520. * Revision History:
  521. * -----------------
  522. *
  523. *********************************************************/
  524. VOID DisableVideoWindow (PDEV * ppdev)
  525. {
  526. UCHAR temp;
  527. DISPDBG((0, "DisableVideoWindow"));
  528. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3c);
  529. temp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  530. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (temp & ~0x10));
  531. }
  532. /**********************************************************
  533. *
  534. * Name: EnableVideoWindow
  535. *
  536. * Module Abstract:
  537. * ----------------
  538. * turn on video window
  539. *
  540. * Output Parameters:
  541. * ------------------
  542. * none
  543. *
  544. ***********************************************************
  545. * Author: Teresa Tao
  546. * Date: 10/22/96
  547. *
  548. * Revision History:
  549. * -----------------
  550. *
  551. *********************************************************/
  552. VOID EnableVideoWindow (PDEV * ppdev)
  553. {
  554. UCHAR temp;
  555. DISPDBG((0, "EnableVideoWindow"));
  556. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3c);
  557. temp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  558. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (temp | 0x10));
  559. }
  560. /**********************************************************
  561. *
  562. * Name: ClearAltFIFOThreshold
  563. *
  564. * Module Abstract:
  565. * ----------------
  566. *
  567. *
  568. * Output Parameters:
  569. * ------------------
  570. * none
  571. *
  572. ***********************************************************
  573. * Author: Teresa Tao
  574. * Date: 10/22/96
  575. *
  576. * Revision History:
  577. * -----------------
  578. *
  579. *********************************************************/
  580. VOID ClearAltFIFOThreshold (PDEV * ppdev)
  581. {
  582. UCHAR temp;
  583. DISPDBG((0, "ClearAltFIFOThreshold"));
  584. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x41);
  585. temp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  586. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (temp & ~0x20));
  587. }
  588. /**********************************************************
  589. *
  590. * Name: Is7555SufficientBandwidth
  591. *
  592. * Module Abstract:
  593. * ----------------
  594. * Determines is sufficient bandwidth exists for the requested
  595. * configuration.
  596. *
  597. * Output Parameters:
  598. * ------------------
  599. * TRUE/FALSE
  600. * It also sets the global parameter lFifoThresh, which gets
  601. * programed in RegInitVideo().
  602. *
  603. ***********************************************************
  604. * Author: Teresa Tao
  605. * Date: 10/22/96
  606. *
  607. * Revision History:
  608. * -----------------
  609. *
  610. *
  611. *
  612. ***********************************************************
  613. *
  614. * The FIFOs:
  615. *
  616. * CRT FIFO is 28 levels x 64-bits wide (SR7[0])
  617. * MVA FIFO is ?? levels x ??-bits wide (????)
  618. * DSTN FIFO is 16 levels x 32-bits wide (SR2F[3:0])
  619. *
  620. *
  621. ***********************************************************/
  622. BOOL Is7555SufficientBandwidth (PDEV * ppdev,WORD wVideoDepth, LPRECTL lpSrc, LPRECTL lpDest, DWORD dwFlags)
  623. {
  624. //myf33 - New Bandwith Code
  625. BOOL fSuccess = FALSE;
  626. DWORD dwVCLK, dwMCLK;
  627. USHORT uMCLKsPerRandom; //RAS# cycles in MCLKs
  628. USHORT uMCLKsPerPage; //CAS# cycles in MCLKs
  629. USHORT uGfxThresh; //Graphic FIFO Threshold (always 8)
  630. USHORT uMVWThresh; //MVW FIFO Threshold (8,16 or 32)
  631. USHORT uDSTNGfxThresh, uDSTNMVWThresh;
  632. //VPort BW document variables
  633. USHORT uGfx, uMVW; //Graphics, Video Window
  634. USHORT uDSTNGfxA, uDSTNGfxB, uDSTNMVWA, uDSTNMVWB;
  635. USHORT nVW = 0; //n (VW), n (Graphics)
  636. USHORT nGfx = 0x40; //n (VW), n (Graphics)
  637. USHORT vVW, vGfx; //v (VW), v (Gfx)
  638. DWORD dwTemp;
  639. BOOL fDSTN;
  640. BYTE bSR0F, bSR20, bSR2F, bSR32, bSR34;
  641. BYTE bGR18, bCR42;
  642. BYTE bCR51, bCR5A, bCR5D, bCR01, bCR5F;
  643. BYTE b3V;
  644. BOOL fColorKey = FALSE; //myf32
  645. DWORD dwSrcWidth, dwDestWidth;
  646. if (dwFlags & (OVERLAY_FLG_COLOR_KEY | OVERLAY_FLG_SRC_COLOR_KEY))
  647. fColorKey = TRUE;
  648. // if ((ppdev->cBitsPerPixel == 16) && (ppdev->cxScreen == 1024))
  649. // fColorKey = FALSE;
  650. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80);
  651. bSR0F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  652. if ((ppdev->cBitsPerPixel == 16) && fColorKey)
  653. {
  654. if (((ppdev->Hres == 1024) && (bSR0F & 1)) ||
  655. (ppdev->cxScreen == 1024))
  656. {
  657. DISPDBG((0, "IsSufficientBandwidth() : 16bpp XGA PANEL || 1K mode"));
  658. return (FALSE);
  659. }
  660. }
  661. //myf32 begin
  662. if (ppdev->flCaps & CAPS_TV_ON) //if TV on disable HW video
  663. {
  664. // ppdev->ulCAPS |= CAPS_SW_POINTER;
  665. DISPDBG((0, "IsSufficientBandwidth() : TV Enable"));
  666. return (FALSE);
  667. }
  668. #if 0 //don't support panning scrolling
  669. if ((ppdev->cxScreen > ppdev->Hres) && (bSR0F & 1))
  670. {
  671. DISPDBG((0, "IsSufficientBandwidth() : Panning Scroll Enable"));
  672. return (FALSE);
  673. }
  674. #endif
  675. //myf32 end
  676. /*
  677. * Don's support overlay if >=24bpp
  678. */
  679. if (ppdev->cBitsPerPixel == 24 || ppdev->cBitsPerPixel == 32)
  680. {
  681. DISPDBG((0, "IsSufficientBandwidth() : 24bpp Mode enable"));
  682. return (FALSE);
  683. }
  684. /*
  685. * Get current register settings from the chip
  686. */
  687. CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x0f);
  688. bSR0F = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
  689. CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x20);
  690. bSR20 = CP_IN_BYTE(ppdev->pjPorts, SR_DATA);
  691. CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x2f);
  692. bSR2F = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) & ~(BYTE)SR2F_HFAFIFOGFX_THRESH;
  693. CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x32);
  694. bSR32 = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) & ~(BYTE)SR32_HFAFIFOMVW_THRESH;
  695. CP_OUT_BYTE(ppdev->pjPorts, INDEX_REG, 0x18);
  696. bGR18 = CP_IN_BYTE(ppdev->pjPorts, DATA_REG) ;
  697. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x01);
  698. bCR01 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  699. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x5F);
  700. bCR5F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & ~0x80;
  701. bCR5D = 0;
  702. bCR51 = 0;
  703. bCR5A = 0x40; //Alan Kobayashi
  704. bSR34 = 0; // @@@ Is this right?
  705. /*
  706. * Determine MCLK and VCLK
  707. */
  708. dwMCLK = Get7555MCLK(ppdev); // Measured in KHz
  709. dwVCLK = GetVCLK(ppdev); // Measured in KHz
  710. if ( dwVCLK ==0 )
  711. return (FALSE);
  712. //myf32 added
  713. // check if 3.3 voltage, (SR2F[5] =0 : 3V, =1 : 5V)
  714. if (bSR2F & 0x40)
  715. b3V = 0;
  716. else
  717. b3V = 1;
  718. if (ppdev->ulChipID == CL7556_ID)
  719. {
  720. if (dwVCLK > 80000)
  721. {
  722. DISPDBG ((0,"Insuffieint bandwidth() : dwVCLK > 80MHz"));
  723. return(FALSE);
  724. }
  725. }
  726. else if (ppdev->ulChipID == CL7555_ID)
  727. {
  728. if (b3V)
  729. {
  730. if (dwVCLK > 65000)
  731. {
  732. DISPDBG ((0,"Insuffieint bandwidth() : dwVCLK > 65MHz"));
  733. return(FALSE);
  734. }
  735. }
  736. else
  737. {
  738. if (dwVCLK > 75000)
  739. {
  740. DISPDBG ((0,"Insuffieint bandwidth() : dwVCLK > 75MHz"));
  741. return(FALSE);
  742. }
  743. }
  744. }
  745. //myf32 end
  746. /*
  747. * See if there is enough bandwidth.
  748. *
  749. * CL-GD7555 has sufficient bandwidth when the following
  750. * equation is satisfied:
  751. *
  752. * (Gfx + MVW + VP + DSTN) * MCLK Period <= v * VCLK period
  753. *
  754. * (Gfx = Graphics, MVW = Motion Video Window, VP = Video
  755. * Port, DSTN = Dual Scan Transistor Network, MCLK =
  756. * Memory Clock, VCLK = Video Clock)
  757. *
  758. * In color/chroma key mode, this equation is checked once
  759. * with VP based on n(Gfx), and using v(Gfx). In non-color/chroma
  760. * key mode, this equation is checked twice, once without the
  761. * MVW term, basing VP on n(Gfx), using DSTN for Gfx, and using
  762. * v(Gfx), and once without the Gfx term, basing VP on n(MVW),
  763. * using DSTN for MVW, and using v(MVW).
  764. */
  765. /*
  766. * Graphics = R + (GFX FIFO Threshold - 1)P
  767. */
  768. // Get R based on the table (from AHRM v1.1):
  769. //
  770. // SR20[6] GR18[2] SR0F[2] R(MCLKs)
  771. //
  772. // 0 1 0 8
  773. // 1 1 0 9
  774. //
  775. uMCLKsPerRandom = 100; // Start with an invalid value
  776. if (!(bSR20 & SR20_9MCLK_RAS))
  777. {
  778. if (bGR18 & GR18_LONG_RAS)
  779. {
  780. if (!(bSR0F & SR0F_DISPLAY_RAS))
  781. uMCLKsPerRandom = 8;
  782. }
  783. }
  784. else
  785. {
  786. if (bGR18 & GR18_LONG_RAS)
  787. {
  788. if (!(bSR0F & SR0F_DISPLAY_RAS))
  789. uMCLKsPerRandom = 9;
  790. }
  791. }
  792. // See if we got a valid value
  793. if (100 == uMCLKsPerRandom)
  794. {
  795. DISPDBG ((0,"IsSufficientBandwidth(): Unknown RAS# cycle timing."));
  796. goto Error;
  797. }
  798. DISPDBG ((0," uMCLKsPerRandom = %u", uMCLKsPerRandom));
  799. // Get P - We assume 2 MCLKs per page cycle
  800. uMCLKsPerPage = 2;
  801. DISPDBG ((0," uMCLKsPerPage = %u", uMCLKsPerPage));
  802. // Get GFX FIFO Threshold - It's hardwired to 8
  803. uGfxThresh = GFXFIFO_THRESH;
  804. DISPDBG ((0," uGfxThresh = %u", uGfxThresh));
  805. // Graphics = R + (GFX FIFO Threshold - 1) * P
  806. uGfx = uMCLKsPerRandom + ((uGfxThresh - 1) * uMCLKsPerPage);
  807. DISPDBG ((0," uGfx = %u", uGfx));
  808. /*
  809. * Video Window = R + (VW FIFO Threshold - 1) * P
  810. */
  811. // Get VW FIFO Threshold - From table (on BW sheet)
  812. //
  813. // GFX Depth MVW Depth VW FIFO Thresh
  814. //
  815. // 8 8 8
  816. // 16 8 8
  817. // 8 16 16
  818. // 16 16 8
  819. //
  820. if (fColorKey)
  821. {
  822. if (wVideoDepth > 8)
  823. {
  824. if (ppdev->cBitsPerPixel > 8)
  825. uMVWThresh = 8;
  826. else
  827. uMVWThresh = 16;
  828. }
  829. else
  830. uMVWThresh = 8;
  831. }
  832. else
  833. {
  834. if (wVideoDepth > 8)
  835. uMVWThresh = 8;
  836. else
  837. uMVWThresh = 16;
  838. }
  839. DISPDBG ((0," uMVWThresh = %u", uMVWThresh));
  840. // Video Window = R + (VW FIFO Threshold - 1) * P
  841. uMVW = uMCLKsPerRandom + ((uMVWThresh - 1) * uMCLKsPerPage);
  842. DISPDBG ((0," uMVW = %u", uMVW));
  843. // Determine Source and Destination VW Widths
  844. dwSrcWidth = lpSrc->right - lpSrc->left;
  845. dwDestWidth = lpDest->right - lpDest->left;
  846. DISPDBG ((0," dwSrcWidth = %d", dwSrcWidth));
  847. DISPDBG ((0," dwDestWidth = %d", dwDestWidth));
  848. // If the video port capture is enabled, calculate VPort stuff
  849. #if 0 //00 for New structure Code
  850. if (dwFlags & OVERLAY_FLG_CAPTURE )
  851. {
  852. int iNumShift, iDenomShift;
  853. DWORD dwNum, dwDenom;
  854. DWORD dwXferRate;
  855. DWORD dwVPortFreq;
  856. // Convert transfer rate to video port frequency, which assumes
  857. // 16-bits per clock
  858. if (!dwMaxPixelsPerSecond)
  859. dwXferRate = 14750000ul;
  860. else
  861. dwXferRate = dwMaxPixelsPerSecond;
  862. dwXferRate = 14750000ul; //hardcoded temporarily
  863. dwVPortFreq = (dwXferRate * (DWORD)wVideoDepth) / 16;
  864. DISPDBG ((0," dwVPortFreq = %lu", dwVPortFreq));
  865. /*
  866. * V-Port = R + (n - 1) * P
  867. *
  868. * n is calculated for graphics and video window.
  869. */
  870. // Calculate n(Gfx) and VPort(Gfx)
  871. // n(Gfx) = VPort freq * Gfx Thresh * VPort depth cap wdth
  872. // ------------------------------------- * ---------
  873. // VCLK * Gfx depth xfer wdth
  874. // Being very careful to avoid overflows while maintaining decent
  875. // accuracy.
  876. iNumShift = ScaleMultiply(dwVPortFreq, (DWORD)uGfxThresh, &dwNum);
  877. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  878. iNumShift += ScaleMultiply(dwNum, (DWORD)wVideoDepth, &dwNum);
  879. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  880. iNumShift += ScaleMultiply(dwNum, (DWORD)dwPrescaleWidth, &dwNum);
  881. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  882. iDenomShift = ScaleMultiply(dwVCLK, (DWORD)wGfxDepth,&dwDenom);
  883. DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
  884. iDenomShift += ScaleMultiply(dwDenom, (DWORD)dwCropWidth, &dwDenom);
  885. DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
  886. // Even things up for the divide
  887. if (iNumShift > iDenomShift)
  888. {
  889. dwDenom >>= (iNumShift - iDenomShift);
  890. }
  891. else if (iDenomShift > iNumShift)
  892. {
  893. dwNum >>= (iDenomShift - iNumShift);
  894. }
  895. DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
  896. // Be sure rounding below doesn't overflow
  897. if ((0xFFFFFFFF - dwDenom) < dwNum)
  898. {
  899. dwNum >>= 1;
  900. dwDenom >>= 1;
  901. }
  902. DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
  903. // Protect from a divide by 0 - this should never happen
  904. if (0 == dwDenom)
  905. {
  906. DISPDBG ((0,"ChipCheckBandwidth(): Invalid n(Gfx) denominator (0)."));
  907. goto Error;
  908. }
  909. // Round up
  910. nGfx = (UINT)((dwNum + dwDenom - 1ul) / dwDenom);
  911. DISPDBG ((0," nGfx = %u", nGfx));
  912. // Only 3 bits for nGfx, so scale it and save factor
  913. uGfxFactor = 1;
  914. while (nGfx > 7)
  915. {
  916. nGfx++;
  917. nGfx >>= 1;
  918. uGfxFactor <<= 1;
  919. DISPDBG ((0," nGfx = %u, uGfxFactor = %u", nGfx, uGfxFactor));
  920. }
  921. // For a 0 n(Gfx), we assume the overhead is negligible.
  922. if (0 == nGfx)
  923. {
  924. uVPortGfx = 0;
  925. }
  926. else
  927. {
  928. // V-Port = R + (n - 1) * P
  929. uVPortGfx = uMCLKsPerRandom + ((nGfx - 1) * uMCLKsPerPage);
  930. uVPortGfx *= uGfxFactor;
  931. }
  932. DISPDBG ((0," uVPortGfx = %u", uVPortGfx));
  933. // If the video window is enabled, calculate n(MVW) and VPort(MVW)
  934. if (dwFlags & OVERLAY_FLG_CAPTURE)
  935. {
  936. // n(VW) = VPort freq * VW Thresh * VPort depth disp wdth cap wdth
  937. // ------------------------------------ * --------- * ---------
  938. // VCLK * VW depth src wdth xfer wdth
  939. // Being very careful to avoid overflows while maintaining decent
  940. // accuracy.
  941. iNumShift = ScaleMultiply(dwVPortFreq, (DWORD)uMVWThresh, &dwNum);
  942. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  943. iNumShift += ScaleMultiply(dwNum, (DWORD)wVideoDepth, &dwNum);
  944. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  945. iNumShift += ScaleMultiply(dwNum, (DWORD)dwDestWidth, &dwNum);
  946. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  947. iNumShift += ScaleMultiply(dwNum, (DWORD)dwPrescaleWidth, &dwNum);
  948. DISPDBG ((0," dwNum = %lu, iNumShift = %d", dwNum, iNumShift));
  949. iDenomShift = ScaleMultiply(dwVCLK, (DWORD)wVideoDepth, &dwDenom);
  950. DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
  951. iDenomShift += ScaleMultiply(dwDenom, (DWORD)dwSrcWidth, &dwDenom);
  952. DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
  953. iDenomShift += ScaleMultiply(dwDenom, (DWORD)dwCropWidth, &dwDenom);
  954. DISPDBG ((0," dwDenom = %lu, iDenomShift = %d", dwDenom, iDenomShift));
  955. // Even things up for the divide
  956. if (iNumShift > iDenomShift)
  957. {
  958. dwDenom >>= (iNumShift - iDenomShift);
  959. }
  960. else if (iDenomShift > iNumShift)
  961. {
  962. dwNum >>= (iDenomShift - iNumShift);
  963. }
  964. DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
  965. // Be sure rounding below doesn't overflow
  966. if ((0xFFFFFFFF - dwDenom) < dwNum)
  967. {
  968. dwNum >>= 1;
  969. dwDenom >>= 1;
  970. }
  971. DISPDBG ((0," dwNum = %lu, dwDenom = %lu", dwNum, dwDenom));
  972. // Protect from a divide by 0 even though this should never happen
  973. if (0 == dwDenom)
  974. {
  975. DISPDBG ((0,"ChipCheckBandwidth(): Invalid n(VW) denominator (0)."));
  976. goto Error;
  977. }
  978. // Divide (round up)
  979. nVW = (UINT)((dwNum + dwDenom - 1) / dwDenom);
  980. DISPDBG ((0," nVW = %u", nVW));
  981. // Only 3 bits for nVW, so scale it and save factor
  982. uMVWFactor = 1;
  983. while (nVW > 7)
  984. {
  985. nVW++;
  986. nVW >>= 1;
  987. uMVWFactor <<= 1;
  988. DISPDBG ((0," nVW = %u, uMVWFactor = %u", nVW, uMVWFactor));
  989. }
  990. // For a 0 n(VW), we assume the overhead is negligible.
  991. if (0 == nVW)
  992. {
  993. uVPortMVW = 0;
  994. }
  995. else
  996. {
  997. // V-Port = R + (n - 1) * P
  998. uVPortMVW = uMCLKsPerRandom + ((nVW - 1) * uMCLKsPerPage);
  999. uVPortMVW *= uMVWFactor;
  1000. }
  1001. DISPDBG((0," uVPortMVW = %u", uVPortMVW));
  1002. }
  1003. }
  1004. #endif //00 -- fr new structure code
  1005. /*
  1006. * DSTN Frame Buffer = [R + P] + [1 + (2 * P)] (a)
  1007. * or = [R + (2 * P)] + [1 + (3 * P)] (b)
  1008. */
  1009. dwTemp = (DWORD)(uMCLKsPerRandom + uMCLKsPerPage + 1 + (2 * uMCLKsPerPage));
  1010. uDSTNGfxA = (UINT)dwTemp;
  1011. dwTemp *= dwDestWidth;
  1012. dwTemp /= dwSrcWidth;
  1013. uDSTNMVWA = (UINT)dwTemp;
  1014. dwTemp = (DWORD)(uMCLKsPerRandom + (2 * uMCLKsPerPage) + 1 + (3 * uMCLKsPerPage));
  1015. uDSTNGfxB = (UINT)dwTemp;
  1016. dwTemp *= dwDestWidth;
  1017. dwTemp /= dwSrcWidth;
  1018. uDSTNMVWB = (UINT)dwTemp;
  1019. DISPDBG((0,"uDSTNGfxA = %u, uDSTNMVWA = %u, uDSTNGfxB = %u,uDSTNMVWB = %u",
  1020. uDSTNGfxA, uDSTNMVWA, uDSTNGfxB, uDSTNMVWB));
  1021. /*
  1022. * (Gfx + MVW + VP + DSTN) * MCLK Period <= VCLK period
  1023. */
  1024. // Calculate v(VW) and v(Graphics) for comparison below
  1025. // Div 0 Protection done above
  1026. vVW = (UINT)((64ul * (DWORD)uMVWThresh * dwDestWidth)
  1027. / (wVideoDepth * dwSrcWidth));
  1028. DISPDBG((0," vVW = %u", vVW));
  1029. // Div 0 Protection done above
  1030. vGfx = (USHORT)((64 * uGfxThresh) / ppdev->cBitsPerPixel);
  1031. DISPDBG((0," vGfx = %u", vGfx));
  1032. // See if DSTN is enabled
  1033. fDSTN = IsDSTN(ppdev);
  1034. // Check main equation, starting with Gfx-based equation (we won't
  1035. // do MVW-based equation below unless we are non-color/chroma keyed
  1036. // and the MVW is enabled.
  1037. {
  1038. DWORD dwLeft, dwRight, dwScaledRandomMCLKPeriod;
  1039. // Begin building left side of equation with DSTN contribution
  1040. if (fDSTN)
  1041. {
  1042. if (16 == ppdev->cBitsPerPixel)
  1043. {
  1044. dwLeft = (DWORD)uDSTNGfxA;
  1045. uDSTNGfxThresh = 4;
  1046. }
  1047. else
  1048. {
  1049. dwLeft = (DWORD)uDSTNGfxB;
  1050. uDSTNGfxThresh = 6;
  1051. }
  1052. if (uMVWThresh == wVideoDepth)
  1053. uDSTNMVWThresh = 6;
  1054. else
  1055. uDSTNMVWThresh = 4;
  1056. }
  1057. else
  1058. {
  1059. dwLeft = 0;
  1060. }
  1061. DISPDBG((0," dwLeft = %lu", dwLeft));
  1062. // Are we being displayed and color or chroma keyed?
  1063. if (fColorKey)
  1064. {
  1065. // Add graphics contribution (scaled)
  1066. dwLeft += ((DWORD)uGfx * dwDestWidth) / dwSrcWidth;
  1067. DISPDBG((0," dwLeft = %lu", dwLeft));
  1068. // Add video window contribution
  1069. dwLeft += (DWORD)uMVW;
  1070. }
  1071. else
  1072. {
  1073. // Add graphics contribution (1x)
  1074. dwLeft += (DWORD)uGfx;
  1075. }
  1076. DISPDBG((0," dwLeft = %lu", dwLeft));
  1077. if (fColorKey)
  1078. dwRight = (DWORD)vVW;
  1079. else
  1080. dwRight = (DWORD)vGfx;
  1081. DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
  1082. // Only add video port if it's in use
  1083. #if 0 //00 - for new structure code
  1084. if (dwFlags & OVERLAY_FLG_CAPTURE)
  1085. {
  1086. if (fColorKey)
  1087. dwLeft += (DWORD)uVPortMVW;
  1088. else
  1089. dwLeft += (DWORD)uVPortGfx;
  1090. }
  1091. #endif //0 - for new structure code
  1092. DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
  1093. // To avoid the divisions in (left/MCLK) <= (right/VCLK), we'll
  1094. // instead multiply left * VCLK and right * MCLK since the relationship
  1095. // will be the same.
  1096. {
  1097. int iLeftShift, iRightShift, iRandomMCLKShift;
  1098. iLeftShift = ScaleMultiply(dwLeft, dwVCLK, &dwLeft);
  1099. DISPDBG((0," dwLeft = %lu, iLeftShift = %d", dwLeft, iLeftShift));
  1100. iRightShift = ScaleMultiply(dwRight, dwMCLK, &dwRight);
  1101. DISPDBG((0," dwRight = %lu, iRightShift = %d", dwRight, iRightShift));
  1102. iRandomMCLKShift = ScaleMultiply((DWORD)uMCLKsPerRandom, dwVCLK,
  1103. &dwScaledRandomMCLKPeriod);
  1104. DISPDBG((0," dwScaledRandomMCLKPeriod = %lu,iRandomMCLKShift = %d",
  1105. dwScaledRandomMCLKPeriod, iRandomMCLKShift));
  1106. // Even things up
  1107. {
  1108. int iShift = iLeftShift;
  1109. if (iRightShift > iShift)
  1110. iShift = iRightShift;
  1111. if (iRandomMCLKShift > iShift)
  1112. iShift = iRandomMCLKShift;
  1113. if (iShift > iLeftShift)
  1114. dwLeft >>= (iShift - iLeftShift);
  1115. if (iShift > iRightShift)
  1116. dwRight >>= (iShift - iRightShift);
  1117. if (iShift > iRandomMCLKShift)
  1118. dwScaledRandomMCLKPeriod >>= (iShift - iRandomMCLKShift);
  1119. }
  1120. }
  1121. DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
  1122. DISPDBG((0," dwScaledRandomMCLKPeriod = %lu", dwScaledRandomMCLKPeriod));
  1123. // See if there is enough bandwidth
  1124. if (dwLeft > dwRight)
  1125. {
  1126. DISPDBG((0,"IsSufficientBandwidth(): Insufficient bandwidth (Gfx)."));
  1127. goto Error;
  1128. }
  1129. if (dwLeft > (dwRight - dwScaledRandomMCLKPeriod))
  1130. {
  1131. // Set CPU stop bits
  1132. DISPDBG((0,"IsSufficientBandwidth(): CPU stop bits set (Gfx)."));
  1133. bSR34 = SR34_CPUSTOP_ENABLE | SR34_GFX_CPUSTOP | SR34_MVW_CPUSTOP;
  1134. if (fDSTN)
  1135. bSR34 |= SR34_DSTN_CPUSTOP;
  1136. DISPDBG((0," bSR34 = 0x%x", bSR34));
  1137. }
  1138. }
  1139. // Check main equation using MVW-based values if we are not
  1140. // color/chroma keyed and the MVW is enabled.
  1141. if (!fColorKey)
  1142. {
  1143. DWORD dwLeft, dwRight, dwScaledRandomMCLKPeriod;
  1144. // Begin building left side of equation with DSTN contribution
  1145. if (fDSTN)
  1146. {
  1147. if (uMVWThresh == wVideoDepth)
  1148. dwLeft = (DWORD)uDSTNMVWB;
  1149. else
  1150. dwLeft = (DWORD)uDSTNMVWA;
  1151. }
  1152. else
  1153. {
  1154. dwLeft = 0;
  1155. }
  1156. DISPDBG((0," dwLeft = %lu", dwLeft));
  1157. // Add MVW contribution
  1158. dwLeft += (DWORD)uMVW;
  1159. DISPDBG((0," dwLeft = %lu", dwLeft));
  1160. // Use v(MVW) for right
  1161. dwRight = (DWORD)vVW;
  1162. DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
  1163. // To avoid the divisions in (left/MCLK) <= (right/VCLK), we'll
  1164. // instead multiply left * VCLK and right * MCLK since the relationship
  1165. // will be the same.
  1166. {
  1167. int iLeftShift, iRightShift, iRandomMCLKShift;
  1168. iLeftShift = ScaleMultiply(dwLeft, dwVCLK, &dwLeft);
  1169. DISPDBG((0," dwLeft = %lu, iLeftShift = %d", dwLeft, iLeftShift));
  1170. iRightShift = ScaleMultiply(dwRight, dwMCLK, &dwRight);
  1171. DISPDBG((0," dwRight = %lu, iRightShift = %d", dwRight, iRightShift));
  1172. iRandomMCLKShift = ScaleMultiply((DWORD)uMCLKsPerRandom, dwVCLK,
  1173. &dwScaledRandomMCLKPeriod);
  1174. DISPDBG((0," dwScaledRandomMCLKPeriod = %lu, iRandomMCLKShift = %d",
  1175. dwScaledRandomMCLKPeriod, iRandomMCLKShift));
  1176. // Even things up
  1177. {
  1178. int iShift = iLeftShift;
  1179. if (iRightShift > iShift)
  1180. iShift = iRightShift;
  1181. if (iRandomMCLKShift > iShift)
  1182. iShift = iRandomMCLKShift;
  1183. if (iShift > iLeftShift)
  1184. dwLeft >>= (iShift - iLeftShift);
  1185. if (iShift > iRightShift)
  1186. dwRight >>= (iShift - iRightShift);
  1187. if (iShift > iRandomMCLKShift)
  1188. dwScaledRandomMCLKPeriod >>= (iShift - iRandomMCLKShift);
  1189. }
  1190. }
  1191. DISPDBG((0," dwLeft = %lu, dwRight = %lu", dwLeft, dwRight));
  1192. DISPDBG((0," dwScaledRandomMCLKPeriod = %lu", dwScaledRandomMCLKPeriod));
  1193. // See if there is enough bandwidth
  1194. if (dwLeft > dwRight)
  1195. {
  1196. DISPDBG((0,"IsSufficientBandwidth(): Insufficient bandwidth (MVW)."));
  1197. goto Error;
  1198. }
  1199. if (dwLeft > (dwRight - dwScaledRandomMCLKPeriod))
  1200. {
  1201. // Set CPU stop bits
  1202. DISPDBG((0,"IsSufficientBandwidth(): CPU stop bits set (MVW)."));
  1203. bSR34 = SR34_CPUSTOP_ENABLE | SR34_MVW_CPUSTOP;
  1204. if (fDSTN)
  1205. bSR34 |= SR34_DSTN_CPUSTOP;
  1206. DISPDBG((0," bSR34 = 0x%x", bSR34));
  1207. }
  1208. }
  1209. // Return register settings
  1210. bSR2F |= (BYTE)uDSTNGfxThresh & SR2F_HFAFIFOGFX_THRESH;
  1211. bSR32 |= (BYTE)uDSTNMVWThresh & SR32_HFAFIFOMVW_THRESH;
  1212. switch (uMVWThresh)
  1213. {
  1214. case 8:
  1215. bCR42 = 0x04;
  1216. break;
  1217. case 16:
  1218. bCR42 = 0x00;
  1219. break;
  1220. default:
  1221. DISPDBG((0,"IsSufficientBandwidth(): Illegal MVW Thresh (%u).", uMVWThresh));
  1222. goto Error;
  1223. }
  1224. bCR51 |= ((BYTE)nVW << 5) & CR51_VPORTMVW_THRESH;
  1225. DISPDBG((0," bCR51 = 0x%02X", (int)bCR51));
  1226. bCR5A |= (BYTE)nGfx & CR5A_VPORTGFX_THRESH;
  1227. DISPDBG((0," bCR5A = 0x%02X", (int)bCR5A));
  1228. bCR5D=(BYTE)(((8 * (WORD)(bCR01 + 1)) + dwSrcWidth - dwDestWidth) / 8);
  1229. DISPDBG((0," bCR5D = 0x%02X", (int)bCR5D));
  1230. if (bCR5D)
  1231. bCR5F |= 0x80;
  1232. // Set global registers to be programmed in RegInitVideo()
  1233. //myf33 if (lpRegs)
  1234. {
  1235. Regs.bSR2F = bSR2F;
  1236. Regs.bSR32 = bSR32;
  1237. Regs.bSR34 = bSR34;
  1238. Regs.bCR42 = bCR42;
  1239. Regs.bCR51 = bCR51;
  1240. Regs.bCR5A = bCR5A;
  1241. Regs.bCR5D = bCR5D;
  1242. Regs.bCR5F = bCR5F;
  1243. }
  1244. fSuccess = TRUE;
  1245. DISPDBG((0,"IsSufficientBandwidth: OK!"));
  1246. Error:
  1247. return(fSuccess);
  1248. }
  1249. /**********************************************************
  1250. *
  1251. * Get7555MCLK()
  1252. *
  1253. * Determines the current MCLK frequency.
  1254. *
  1255. * Return: The MCLK frequency in KHz (Since the frequency
  1256. * could exceed 65535KHz, a DWORD is used).
  1257. *
  1258. ***********************************************************
  1259. * Author: Rick Tillery
  1260. * Date: 09/27/95
  1261. *
  1262. * Revision History:
  1263. * -----------------
  1264. * WHO WHEN WHAT/WHY/HOW
  1265. * --- ---- ------------
  1266. *
  1267. *********************************************************/
  1268. DWORD Get7555MCLK(PDEV * ppdev)
  1269. {
  1270. DWORD dwMCLK;
  1271. int nMCLK;
  1272. BYTE bTemp;
  1273. // Get MCLK register value
  1274. CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x1f);
  1275. nMCLK = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) & 0x3F;
  1276. // Calculate actual MCLK frequency
  1277. dwMCLK = (14318l * (DWORD)nMCLK) >> 3;
  1278. CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x12);
  1279. bTemp = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
  1280. // Account for MCLK scaling
  1281. if (bTemp & 0x10)
  1282. {
  1283. dwMCLK >>= 1;
  1284. }
  1285. return(dwMCLK);
  1286. }
  1287. /**********************************************************
  1288. *
  1289. * IsDSTN()
  1290. *
  1291. * Determines whether a DSTN panel is being used for display.
  1292. *
  1293. * Return: TRUE/FALSE
  1294. *
  1295. ***********************************************************
  1296. * Author: Teresa Tao
  1297. * Date: 10/22/96
  1298. *
  1299. * Revision History:
  1300. * -----------------
  1301. * WHO WHEN WHAT/WHY/HOW
  1302. * --- ---- ------------
  1303. *
  1304. *********************************************************/
  1305. BOOL IsDSTN(PDEV * ppdev)
  1306. {
  1307. BOOL bTemp;
  1308. /*
  1309. * Is this an LCD?
  1310. */
  1311. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80);
  1312. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1313. if (bTemp & 0x01)
  1314. {
  1315. /*
  1316. * Determine type of LCD.
  1317. */
  1318. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x83);
  1319. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x70;
  1320. bTemp >>= 4 ;
  1321. if (bTemp == 0)
  1322. return (TRUE);
  1323. }
  1324. return(FALSE);
  1325. }
  1326. /**********************************************************
  1327. *
  1328. * IsXGA()
  1329. *
  1330. * Determines whether a XGA panel is being used for display.
  1331. *
  1332. * Return: TRUE/FALSE
  1333. *
  1334. ***********************************************************
  1335. * Author: Teresa Tao
  1336. * Date: 10/22/96
  1337. *
  1338. * Revision History:
  1339. * -----------------
  1340. * WHO WHEN WHAT/WHY/HOW
  1341. * --- ---- ------------
  1342. *
  1343. *********************************************************/
  1344. BOOL IsXGA(PDEV * ppdev)
  1345. {
  1346. BOOL bTemp;
  1347. /*
  1348. * Is this an LCD?
  1349. */
  1350. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80);
  1351. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1352. if (bTemp & 0x01)
  1353. {
  1354. /*
  1355. * Determine size of LCD.
  1356. */
  1357. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x83);
  1358. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x03;
  1359. if (bTemp == 0x02)
  1360. return (TRUE);
  1361. }
  1362. return (FALSE);
  1363. }
  1364. /**********************************************************
  1365. *
  1366. * ScaleMultiply()
  1367. *
  1368. * Calculates product of two DWORD factors supplied. If the
  1369. * result would overflow a DWORD, the larger of the two factors
  1370. * is divided by 2 (shifted right) until the overflow will
  1371. * not occur.
  1372. *
  1373. * Returns: Number of right shifts applied to the product.
  1374. * Product of the factors shifted by the value above.
  1375. *
  1376. ***********************************************************
  1377. * Author: Rick Tillery
  1378. * Date: 11/18/95
  1379. *
  1380. * Revision History:
  1381. * -----------------
  1382. * WHO WHEN WHAT/WHY/HOW
  1383. * --- ---- ------------
  1384. *********************************************************/
  1385. static int ScaleMultiply(DWORD dw1,
  1386. DWORD dw2,
  1387. LPDWORD pdwResult)
  1388. {
  1389. int iShift = 0; // Start with no shifts
  1390. DWORD dwLimit;
  1391. // Either factor 0 will be a zero result and also cause a problem
  1392. // in our divide below.
  1393. if ((0 == dw1) || (0 == dw2))
  1394. {
  1395. *pdwResult = 0;
  1396. }
  1397. else
  1398. {
  1399. // Determine which factor is larger
  1400. if (dw1 > dw2)
  1401. {
  1402. // Determine largest number by with dw2 can be multiplied without
  1403. // overflowing a DWORD.
  1404. dwLimit = 0xFFFFFFFFul / dw2;
  1405. // Shift dw1, keeping track of how many times, until it won't
  1406. // overflow when multiplied by dw2.
  1407. while (dw1 > dwLimit)
  1408. {
  1409. dw1 >>= 1;
  1410. iShift++;
  1411. }
  1412. }
  1413. else
  1414. {
  1415. // Determine largest number by with dw1 can be multiplied without
  1416. // overflowing a DWORD.
  1417. dwLimit = 0xFFFFFFFFul / dw1;
  1418. // Shift dw2, keeping track of how many times, until it won't
  1419. // overflow when multiplied by dw1.
  1420. while (dw2 > dwLimit)
  1421. {
  1422. dw2 >>= 1;
  1423. iShift++;
  1424. }
  1425. }
  1426. // Calculate (scaled) product
  1427. *pdwResult = dw1 * dw2;
  1428. }
  1429. // Return the number of shifts we had to use
  1430. return(iShift);
  1431. }
  1432. //myf31 :
  1433. #if 1
  1434. /**********************************************************
  1435. *
  1436. * PanOverlay7555
  1437. *
  1438. * If panning scrolling enable, and enable HW video, modified video window value
  1439. *
  1440. * Return: none
  1441. *
  1442. ***********************************************************
  1443. * Author: Rita Ma
  1444. * Date: 02/24/97
  1445. *
  1446. * Revision History:
  1447. * -----------------
  1448. *********************************************************/
  1449. VOID PanOverlay7555 (PDEV * ppdev,LONG x,LONG y)
  1450. // RegInit7555Video (PDEV * ppdev,PDD_SURFACE_LOCAL lpSurface)
  1451. {
  1452. DWORD dwTemp;
  1453. DWORD dwFourcc;
  1454. WORD wBitCount;
  1455. LONG lPitch;
  1456. WORD wTemp;
  1457. RECTL rDest;
  1458. WORD wSrcWidth;
  1459. WORD wSrcWidth_clip;
  1460. WORD wDestWidth;
  1461. WORD wSrcHeight;
  1462. WORD wSrcHeight_clip;
  1463. WORD wDestHeight;
  1464. DWORD dwFBOffset;
  1465. BYTE bRegCR31;
  1466. BYTE bRegCR32;
  1467. BYTE bRegCR33;
  1468. BYTE bRegCR34;
  1469. BYTE bRegCR35;
  1470. BYTE bRegCR36;
  1471. BYTE bRegCR37;
  1472. BYTE bRegCR38;
  1473. BYTE bRegCR39;
  1474. BYTE bRegCR3A;
  1475. BYTE bRegCR3B;
  1476. BYTE bRegCR3C;
  1477. BYTE bRegCR3D;
  1478. BYTE bRegCR3E;
  1479. BYTE bRegCR3F;
  1480. BYTE bRegCR40;
  1481. BYTE bRegCR41;
  1482. BYTE bRegCR42;
  1483. BYTE bRegCR51;
  1484. BYTE bTemp;
  1485. BYTE bVZoom;
  1486. WORD fTemp=0;
  1487. ULONG ulTemp=0;
  1488. BOOL bOverlayTooSmall = FALSE;
  1489. static DWORD giAdjustSource;
  1490. // USHORT VW_h_position, VW_v_position;
  1491. // USHORT VW_h_width, VW_v_height;
  1492. // ULONG VW_s_addr;
  1493. // PanOverlay1_Init return FALSE, exit here
  1494. if (!PanOverlay1_7555(ppdev, &rDest))
  1495. return;
  1496. // rDest is now adjusted & clipped to the panning viewport
  1497. // Disable overlay if totally clipped by viewport
  1498. //
  1499. if (((rDest.right - rDest.left) <= 15) ||
  1500. ((rDest.bottom - rDest.top) <= 0) )
  1501. {
  1502. DisableVideoWindow(ppdev); // disable overlay
  1503. return;
  1504. }
  1505. // Initial some value
  1506. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x42);
  1507. bRegCR42 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0xFC; //mask Chroma Key
  1508. // keep bit6 video LUT enable
  1509. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36);
  1510. bRegCR36 = (CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x40) | 0x20;
  1511. //
  1512. // Get video format and color depth of overlay data
  1513. //
  1514. dwFourcc = ppdev->sOverlay1.dwFourcc;
  1515. wBitCount= ppdev->sOverlay1.wBitCount;
  1516. lPitch = ppdev->lPitch_gbls; //??????????
  1517. wSrcWidth = (WORD)(LONG)(ppdev->rOverlaySrc.right - ppdev->rOverlaySrc.left);
  1518. wSrcHeight = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - ppdev->rOverlaySrc.top);
  1519. wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip);
  1520. wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip);
  1521. wDestWidth = (WORD)(LONG)(ppdev->rOverlayDest.right - ppdev->rOverlayDest.left);
  1522. wDestHeight = (WORD)(LONG)(ppdev->rOverlayDest.bottom - ppdev->rOverlayDest.top);
  1523. // Determine horizontal upscale coefficient (CR39[7:4],CR31[7:0])
  1524. wTemp = ((WORD)(((DWORD)wSrcWidth << 12) / (DWORD)wDestWidth)) & 0x0FFF;
  1525. if (wTemp != 0 && bLeft_clip)
  1526. {
  1527. srcLeft_clip = srcLeft_clip * (LONG)wTemp/4096 +ppdev->rOverlaySrc.left;
  1528. wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip);
  1529. DISPDBG((0,"srcLeft_clip after zoom:%x",srcLeft_clip));
  1530. }
  1531. else if (bLeft_clip)
  1532. {
  1533. srcLeft_clip = srcLeft_clip + ppdev->rOverlaySrc.left;
  1534. wSrcWidth_clip = (WORD)(LONG)(ppdev->rOverlaySrc.right - srcLeft_clip);
  1535. DISPDBG((0,"srcLeft_clip after zoom:%x",srcLeft_clip));
  1536. }
  1537. bRegCR39 = (BYTE)((wTemp & 0x0F) << 4);
  1538. bRegCR31 = (BYTE)(wTemp >> 4) & 0xFF;
  1539. // Determine vertical upscale coefficient (CR39[3:0],CR32[7:0])
  1540. bVZoom=0;
  1541. wTemp = ((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)wDestHeight)) & 0x0FFF;
  1542. if (wTemp != 0) {
  1543. bVZoom=1;
  1544. fTemp = wTemp;
  1545. if ( fTemp < 2048 ) // Zoom > 2.0
  1546. wTemp=((WORD)(((DWORD)wSrcHeight << 12) / (DWORD)(wDestHeight+1))) & 0x0FFF;
  1547. }
  1548. if (wTemp != 0 && bTop_clip)
  1549. {
  1550. srcTop_clip = srcTop_clip * (LONG)wTemp/4096 + ppdev->rOverlaySrc.top;
  1551. wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip);
  1552. DISPDBG((0,"srcTop_clip after zoom:%x",srcTop_clip));
  1553. }
  1554. else if (bTop_clip)
  1555. {
  1556. srcTop_clip = srcTop_clip + ppdev->rOverlaySrc.top;
  1557. wSrcHeight_clip = (WORD)(LONG)(ppdev->rOverlaySrc.bottom - srcTop_clip);
  1558. DISPDBG((0,"srcTop_clip after zoom:%x",srcTop_clip));
  1559. }
  1560. bRegCR39 |= (BYTE)(wTemp & 0x0F);
  1561. bRegCR32 = (BYTE)(wTemp >> 4) & 0xFF;
  1562. DISPDBG((0,"wTemp = 0x%x",wTemp));
  1563. // Determine Vertical Height (CR38[7:0], CR36[3:2])
  1564. wTemp = wSrcHeight_clip;
  1565. if (wTemp != 0 &&
  1566. ( fTemp > 2730 || fTemp ==0 || ( fTemp > 1365 && fTemp < 2048 ) ) )
  1567. wTemp--; //#tt10, Height minus one only if upscale rate <1.5
  1568. //#tt10 2 < <3
  1569. bRegCR38 = (BYTE)wTemp;
  1570. bRegCR36 |= (wTemp & 0x0300) >> 6;
  1571. // Determine Horizontal position start (CR34[7:0], CR33[7:5])
  1572. wTemp = (WORD)rDest.left;
  1573. bRegCR34 = (BYTE)wTemp;
  1574. bRegCR33 = (wTemp & 0x0700) >> 3;
  1575. // Reset Brightness control (CR35[7:0])
  1576. bRegCR35 = 0x0;
  1577. // Determine Vertical Start (CR37[7:0], CR36[1:0])
  1578. wTemp = (WORD)rDest.top;
  1579. bRegCR37 = (BYTE)wTemp;
  1580. bRegCR36 |= (wTemp & 0x0300) >> 8;
  1581. // Determine Video Start Address (CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0])
  1582. // giAdjustSource = (ppdev->rOverlaySrc.top * lpSurface->lpGbl->lPitch)
  1583. // + ((ppdev->rOverlaySrc.left * wBitCount) >> 3);
  1584. dwTemp = srcTop_clip * lPitch;
  1585. dwTemp = (srcLeft_clip * wBitCount) >> 3;
  1586. giAdjustSource = (srcTop_clip * lPitch)
  1587. + ((srcLeft_clip * wBitCount) >> 3);
  1588. ppdev->sOverlay1.lAdjustSource = giAdjustSource; //myf32
  1589. dwFBOffset = (DWORD)(ppdev->fpVidMem_gbls + giAdjustSource);
  1590. DISPDBG((0,"giAdjustSource = 0x%08x",giAdjustSource));
  1591. DISPDBG((0,"dwFBOffset = 0x%08x",dwFBOffset));
  1592. dwFBOffset >>= 2;
  1593. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3A);
  1594. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  1595. bRegCR3A = (bTemp & ~0x7F) | (BYTE)((dwFBOffset & 0x0FE000) >> 13);
  1596. bRegCR3E = (BYTE)((dwFBOffset & 0x001FE0) >> 5);
  1597. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3F);
  1598. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1599. bRegCR3F = (bTemp & ~0x0F) | (BYTE)((dwFBOffset & 0x00001E) >> 1);
  1600. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x40);
  1601. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) ;
  1602. bRegCR40 = (bTemp & ~0x01) | (BYTE)(dwFBOffset & 0x000001);
  1603. //Determine Video Pitch (CR3B[7:0], CR36[4])
  1604. wTemp = (WORD)(lPitch >> 4); //QWORDs
  1605. bRegCR3B = (BYTE)wTemp;
  1606. bRegCR36 |= (wTemp & 0x0100) >> 4;
  1607. // Determine Data Format (CR3E[3:0])
  1608. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C);
  1609. bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x10;
  1610. switch (dwFourcc)
  1611. {
  1612. case FOURCC_PACKJR:
  1613. bRegCR3C |= 0x02; // Pack JR
  1614. break;
  1615. case BI_RGB:
  1616. switch(wBitCount)
  1617. {
  1618. case 8:
  1619. bRegCR3C |= 0x09; // 8 bit palettized
  1620. break;
  1621. case 16:
  1622. bRegCR3C |= 0x01; // RGB 5:5:5
  1623. break;
  1624. }
  1625. break;
  1626. case BI_BITFIELDS:
  1627. switch(wBitCount)
  1628. {
  1629. case 8:
  1630. bRegCR3C |= 0x09; // 8 bit palettized
  1631. break;
  1632. case 16:
  1633. bRegCR3C |= 0x04; // RGB 5:6:5
  1634. break;
  1635. }
  1636. break;
  1637. case FOURCC_YUV422:
  1638. bRegCR3C |= 0x03; // YUV 4:2:2
  1639. break;
  1640. case FOURCC_YUY2: //myf34 test
  1641. bRegCR3C |= 0x03; // YUY2
  1642. // CP_OUT_BYTE(ppdev->pjPorts, SR_INDEX, 0x2C);
  1643. // bRegSR2C = CP_IN_BYTE(ppdev->pjPorts, SR_DATA) ;
  1644. // bRegSR2C |= 0x40; //SR2c[6] = 1
  1645. // CP_OUT_WORD(ppdev->pjPorts, SR_INDEX, 0x2C |(WORD)bRegSR2C << 8);
  1646. break;
  1647. }
  1648. // Determine Horizontal width (CR3D[7:0], CR3C[7:5])
  1649. // NOTE: assumes Horz Pixel Width [0] = 0
  1650. wTemp = wSrcWidth_clip;
  1651. if (wTemp != 0 ) wTemp--; //Width minus one for laptop
  1652. bRegCR3D = (BYTE)((WORD)wTemp >> 1);
  1653. bRegCR3C |= (wTemp & 0x0600) >> 3;
  1654. bRegCR3C |= (BYTE)((wTemp & 0x0001) << 5) ;
  1655. // Enable Horizontal Pixel Interpolation (CR3F[7])
  1656. bRegCR3F |= 0x80;
  1657. // Enable Vertical Pixel Interpolation (CR3F[6])
  1658. //#tt Debug- The CE rev. has problem when vertical interpolation is on
  1659. //#tt Debug- Disable it for now.
  1660. //#tt bRegCR3F |= 0x40;
  1661. // Enable Right Side transition threshold (CR41[5:0])
  1662. bRegCR41 = 0x3E;
  1663. // Disable V-PORT (CR58[7:0])
  1664. bRegCR51 = 0x0;
  1665. // Disable CR5D if in panning & upscaling
  1666. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x80);
  1667. //myf33 if (bVZoom && (BYTE)wPanFlag)
  1668. if (bVZoom && (CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x01)) //myf33
  1669. {
  1670. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x5F);
  1671. bTemp = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & ~0x80;
  1672. CP_OUT_BYTE(ppdev->pjPorts, CRTC_DATA, (UCHAR)bTemp);
  1673. }
  1674. #if 0 // bad ideal code
  1675. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C);
  1676. bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA) & 0x10;
  1677. if (bRegCR3C)
  1678. {
  1679. // Horizontal position start (CR33[7:5], CR34[7:0])
  1680. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x34);
  1681. bRegCR34 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1682. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x33);
  1683. bRegCR33 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1684. VW_h_position = ((USHORT)(bRegCR33 & 0xE0)) << 3;
  1685. VW_h_position |= (USHORT)bRegCR34;
  1686. // Vertical position start (CR36[1:0], CR37[7:0])
  1687. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x37);
  1688. bRegCR37 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1689. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36);
  1690. bRegCR36 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1691. VW_v_position = ((USHORT)(bRegCR36 & 0x03)) << 8;
  1692. VW_v_position |= (USHORT)bRegCR37;
  1693. //Video horizontal width (CR3C[7:6], CR3D[7:0], CR3C[5])
  1694. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3D);
  1695. bRegCR3D = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1696. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3C);
  1697. bRegCR3C = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1698. VW_h_width = (WORD)(bRegCR3C & 0x01);
  1699. VW_h_width |= (((USHORT)(bRegCR3C & 0xC0)) << 3);
  1700. VW_h_width |= (((USHORT)bRegCR3D) << 1);
  1701. //Video vertical height (CR36[3:2], CR38[7:0])
  1702. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x38);
  1703. bRegCR38 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1704. // CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x36);
  1705. // bRegCR36 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1706. VW_v_height = ((USHORT)(bRegCR36 & 0x0C)) << 6;
  1707. VW_v_height |= ((USHORT)bRegCR38);
  1708. //Video memory offset register (CR36[4], CR3B[7:0])
  1709. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3B);
  1710. bRegCR3B = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1711. lPitch = ((USHORT)(bRegCR36 & 0x10)) << 4;
  1712. lPitch |= ((USHORT)bRegCR3B);
  1713. lPitch <<= 4;
  1714. //Video memory start address (CR3A[6:0], CR3E[7:0], CR3F[3:0], CR40[0])
  1715. // update sequence CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0]
  1716. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x40);
  1717. bRegCR40 = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1718. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3A);
  1719. bRegCR3A = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1720. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3E);
  1721. bRegCR3E = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1722. CP_OUT_BYTE(ppdev->pjPorts, CRTC_INDEX, 0x3F);
  1723. bRegCR3F = CP_IN_BYTE(ppdev->pjPorts, CRTC_DATA);
  1724. #if 0
  1725. VW_s_addr = (ULONG)(bRegCR40 & 0x01);
  1726. VW_s_addr |= (((ULONG)(bRegCR3F & 0x0F)) << 1);
  1727. VW_s_addr |= (((ULONG)bRegCR3E) << 5);
  1728. VW_s_addr |= (((ULONG)(bRegCR3A & 0x7F)) << 13);
  1729. VW_s_addr <<= 2;
  1730. #endif
  1731. // Update Video window Horizontal & Vertical position
  1732. DISPDBG((0,"PAN--Xmin=%x, Xmax=%x\n",ppdev->min_Xscrren,ppdev->max_Xscrren));
  1733. DISPDBG((0,"PAN--Ymin=%x, Ymax=%x\n",ppdev->min_Yscrren,ppdev->max_Yscrren));
  1734. DISPDBG((0,"PAN--h_position=%x, v_position=%x\n",VW_h_position,
  1735. VW_v_position));
  1736. DISPDBG((0,"PAN--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width));
  1737. if (((ppdev->min_Xscreen <= VW_h_position) &&
  1738. (ppdev->max_Xscreen >= VW_h_position)) &&
  1739. ((ppdev->min_Yscreen <= VW_v_position) &&
  1740. (ppdev->max_Yscreen >= VW_v_position)))
  1741. {
  1742. VW_h_position -= ppdev->min_Xscreen;
  1743. VW_v_position -= ppdev->min_Yscreen;
  1744. DISPDBG((0,"(1)--h_position=%x, v_position=%x\n",VW_h_position,
  1745. VW_v_position));
  1746. DISPDBG((0,"(1)--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width));
  1747. }
  1748. // Video window in the left or right
  1749. else if ((ppdev->max_Xscreen < VW_h_position) ||
  1750. (ppdev->min_Xscreen > (VW_h_position+VW_h_width)))
  1751. {
  1752. DisableVideoWindow(ppdev); // disable overlay
  1753. ppdev->dwPanningFlag |= OVERLAY_OLAY_REENABLE; // totally clipped
  1754. DISPDBG((0,"(2)--DisableVideoWindow\n"));
  1755. }
  1756. // Video window in the top or bottom
  1757. else if ((ppdev->max_Yscreen < VW_v_position) ||
  1758. (ppdev->min_Yscreen > (VW_v_position+VW_v_height)))
  1759. {
  1760. DisableVideoWindow(ppdev); // disable overlay
  1761. ppdev->dwPanningFlag |= OVERLAY_OLAY_REENABLE; // totally clipped
  1762. DISPDBG((0,"(3)--DisableVideoWindow\n"));
  1763. }
  1764. // Update Video window memory start address
  1765. else if ((ppdev->min_Xscreen > VW_h_position) &&
  1766. (ppdev->min_Xscreen < (VW_h_position+VW_h_width)))
  1767. {
  1768. if ((ppdev->min_Xscreen-VW_h_position) > 0)
  1769. {
  1770. ppdev->rOverlaySrc.left = ppdev->min_Xscreen - VW_h_position;
  1771. VW_h_position = ppdev->min_Xscreen;
  1772. VW_h_width -= ppdev->rOverlaySrc.left;
  1773. }
  1774. if ((ppdev->min_Yscreen-VW_v_position) > 0)
  1775. {
  1776. ppdev->rOverlaySrc.top = ppdev->min_Yscreen - VW_v_position;
  1777. VW_v_position = ppdev->min_Yscreen;
  1778. VW_v_height -= ppdev->rOverlaySrc.top;
  1779. }
  1780. DISPDBG((0,"(4)--h_position=%x, v_position=%x\n",VW_h_position,
  1781. VW_v_position));
  1782. DISPDBG((0,"(4)--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width));
  1783. DISPDBG((0,"(4)--Overlay.top=%x, left=%x\n",ppdev->rOverlaySrc.top,
  1784. ppdev->rOverlaySrc.left));
  1785. }
  1786. else if ((ppdev->min_Yscreen > VW_v_position) &&
  1787. (ppdev->min_Yscreen < (VW_v_position+VW_v_height)))
  1788. {
  1789. if ((ppdev->min_Xscreen-VW_h_position) > 0)
  1790. {
  1791. ppdev->rOverlaySrc.left = ppdev->min_Xscreen - VW_h_position;
  1792. VW_h_position = ppdev->min_Xscreen;
  1793. VW_h_width -= ppdev->rOverlaySrc.left;
  1794. }
  1795. if ((ppdev->min_Yscreen-VW_v_position) > 0)
  1796. {
  1797. ppdev->rOverlaySrc.top = ppdev->min_Yscreen - VW_v_position;
  1798. VW_v_position = ppdev->min_Yscreen;
  1799. VW_v_height -= ppdev->rOverlaySrc.top;
  1800. }
  1801. DISPDBG((0,"(5)--h_position=%x, v_position=%x\n",VW_h_position,
  1802. VW_v_position));
  1803. DISPDBG((0,"(5)--h_height=%x, v_width=%x\n",VW_h_height,VW_v_width));
  1804. }
  1805. giAdjustSource = (ppdev->rOverlaySrc.top * lPitch)
  1806. // ppdev->lpSrcColorSurface->lpGbl->lPitch)
  1807. + ((ppdev->rOverlaySrc.left
  1808. * ppdev->sOverlay1.wBitCount) >> 3);
  1809. // DISPDBG((0,"lpSurface->fpVisibleOverlay= \n0x%08x\n",
  1810. // ppdev->fpVisibleOverlay));
  1811. // DISPDBG((0,"lpSurface->fpBaseOverlay = 0x%08x\n",
  1812. // ppdev->fpBaseOverlay));
  1813. DISPDBG((0,"PAN--fpVidMem=0x%8x\t",ppdev->fpVidMem));
  1814. DISPDBG((0,"PAN--giAdjustSource = 0x%08x\n",giAdjustSource));
  1815. dwFBOffset = (ppdev->fpVidMem_gbls - ) + giAdjustSource;
  1816. DISPDBG((0,"PAN--dwFBOffset = 0x%08x\n",dwFBOffset));
  1817. dwFBOffset >>= 2;
  1818. //Update Horizontal position start (CR33[7:5], CR34[7:0])
  1819. bRegCR34 = (BYTE)(VW_h_position & 0xFF);
  1820. bRegCR33 &= 0x1F;
  1821. bRegCR33 |= ((BYTE)((VW_h_position & 0x0700) >> 3));
  1822. // Vertical position start (CR36[1:0], CR37[7:0])
  1823. bRegCR37 = (BYTE)(VW_v_position & 0xFF);
  1824. bRegCR36 &= 0xFC;
  1825. bRegCR36 |= ((BYTE)((VW_v_position & 0x0300) >> 8));
  1826. //Video horizontal width (CR3C[7:6], CR3D[7:0], CR3C[5])
  1827. bRegCR3D = (BYTE)((VW_h_width & 0x1FE) >> 1);
  1828. bRegCR3C &= 0x1F;
  1829. bRegCR3C |= ((BYTE)(VW_h_width & 0x01)) << 5;
  1830. bRegCR3C |= ((BYTE)((VW_h_width & 0x0600) >> 3));
  1831. //Video vertical height (CR36[3:2], CR38[7:0])
  1832. bRegCR38 = (BYTE)(VW_v_height & 0xFF);
  1833. bRegCR36 &= 0xF3;
  1834. bRegCR36 |= ((BYTE)((VW_v_height & 0x0300) >> 6));
  1835. //Video memory start address (CR3A[6:0], CR3E[7:0], CR3F[3:0], CR40[0])
  1836. // update sequence CR40[0], CR3A[6:0], CR3E[7:0], CR3F[3:0]
  1837. bRegCR40 &= 0xFE;
  1838. bRegCR40 |= (BYTE)(dwFBOffset & 0x01);
  1839. bRegCR3F &= 0xF0;
  1840. bRegCR3F |= ((BYTE)(dwFBOffset & 0x1E)) >> 1;
  1841. bRegCR3E = (BYTE)((dwFBOffset & 0x1FE0) >> 5);
  1842. bRegCR3A &= 0x80;
  1843. bRegCR3A |= ((BYTE)((dwFBOffset & 0xFE000) >> 13));
  1844. #endif /0 - bad ideal
  1845. //
  1846. /*
  1847. * Program the video window registers
  1848. */
  1849. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x31 | (WORD)bRegCR31 << 8);//CR31
  1850. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x32 | (WORD)bRegCR32 << 8);//CR32
  1851. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x33 | (WORD)bRegCR33 << 8);//CR33
  1852. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x34 | (WORD)bRegCR34 << 8);//CR34
  1853. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x35 | (WORD)bRegCR35 << 8);//CR35
  1854. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x36 | (WORD)bRegCR36 << 8);//CR36
  1855. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x37 | (WORD)bRegCR37 << 8);//CR37
  1856. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x38 | (WORD)bRegCR38 << 8);//CR38
  1857. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x39 | (WORD)bRegCR39 << 8);//CR39
  1858. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3B | (WORD)bRegCR3B << 8);//CR3B
  1859. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3C | (WORD)bRegCR3C << 8);//CR3C
  1860. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3D | (WORD)bRegCR3D << 8);//CR3D
  1861. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x41 | (WORD)bRegCR41 << 8);//CR41
  1862. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x42 | (WORD)bRegCR42 << 8);//CR42
  1863. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x51 | (WORD)bRegCR51 << 8);//CR51
  1864. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x40 | (WORD)bRegCR40 << 8);//CR40
  1865. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3A | (WORD)bRegCR3A << 8);//CR3A
  1866. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3E | (WORD)bRegCR3E << 8);//CR3E
  1867. CP_OUT_WORD(ppdev->pjPorts, CRTC_INDEX, 0x3F | (WORD)bRegCR3F << 8);//CR3F
  1868. // enable overlay if overlay was totally clipped by pnning viewport
  1869. //
  1870. if (ppdev->dwPanningFlag & OVERLAY_OLAY_REENABLE)
  1871. EnableVideoWindow (ppdev);
  1872. }
  1873. #endif
  1874. //myf31 end
  1875. #endif // DirectDraw