Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2287 lines
83 KiB

  1. #include "precomp.h"
  2. #if PAL_SUPPORT
  3. void Init3D_Info(PDEV*,PVOID);
  4. ULONG GetDisplayMode(PDEV* ,PVOID ) ;
  5. ULONG AccessDevice(PDEV* , PVOID, PVOID ) ;
  6. ULONG GetConfiguration(PDEV* ,PVOID ) ;
  7. ULONG WriteRegFnct(PDEV* ,PVOID ) ;
  8. ULONG ReadRegFnct(PDEV* ,PVOID , PVOID) ;
  9. void I2CAccess_New(PDEV* ,LPI2CSTRUCT_NEW , LPI2CSTRUCT_NEW ) ;
  10. BYTE ReverseByte(BYTE ) ;
  11. WORD Ack(PDEV*, WORD , BOOL ) ;
  12. void Start(PDEV*, WORD ) ;
  13. void Stop(PDEV*, WORD ) ;
  14. void I2CDelay(PDEV*, WORD) ;
  15. void WriteByteI2C(PDEV*, WORD , BYTE ) ;
  16. BYTE ReadByteI2C(PDEV*,WORD ) ;
  17. BOOL DisableOvl(PDEV* ) ;
  18. ULONG AllocOffscreenMem(PDEV* , PVOID , PVOID) ;
  19. ULONG DeallocOffscreenMem(PDEV* ) ;
  20. ULONG AllocOffscreenMem(PDEV* , PVOID , PVOID ) ;
  21. void WriteVT264Reg(PDEV* , WORD , BYTE , DWORD );
  22. DWORD ReadVT264Reg(PDEV* , WORD , BYTE ) ;
  23. void WriteI2CData(PDEV* , WORD , BYTE );
  24. ULONG ReallocMemory(PDEV* ) ;
  25. void SetI2CDataDirection(PDEV* , WORD, BOOL ) ;
  26. void WriteI2CClock(PDEV* , WORD , BYTE ) ;
  27. VOID DbgExtRegsDump(PDEV* );
  28. VOID TempFnct(PDEV* );
  29. VOID DeallocDirectDraw(PDEV* ) ;
  30. VOID ResetPalindrome(PDEV* ,PDEV* );
  31. REGSBT819INFO RegsBT819[NUM_BT819_REGS] = { /* Register's Name*/
  32. { 1, STATUS, 0, 0x7F, 0, 0, 0, 0 }, // 0 - PRES
  33. { 1, STATUS, 1, 0xBF, 0, 0, 0, 0 }, // 1 - HLOC
  34. { 1, STATUS, 2, 0xDF, 0, 0, 0, 0 }, // 2 - FIELD
  35. { 1, STATUS, 3, 0xEF, 0, 0, 0, 0 }, // 3 - NUML
  36. { 1, STATUS, 4, 0xF7, 0, 0, 0, 0 }, // 4 - CSEL
  37. { 1, STATUS, 6, 0xFD, 0, 0, 0, 0 }, // 5 - LOF
  38. { 1, STATUS, 7, 0xFE, 0, 0, 0, 0 }, // 6 - COF
  39. { 1, IFORM, 0, 0x7F, 0, 0, 0, 0 }, // 7 - HACTIVE_I
  40. { 2, IFORM, 1, 0x9F, 0, 0, 0, 0 }, // 8 - MUXEL
  41. { 2, IFORM, 3, 0xE7, 0, 0, 0, 0 }, // 9 - XTSEL
  42. { 2, IFORM, 6, 0xFC, 0, 0, 0, 0 }, // 10 - FORMAT
  43. { 1, TDEC, 0, 0x7F, 0, 0, 0, 0 }, // 11 - DEC_FIELD
  44. { 7, TDEC, 1, 0x80, 0, 0, 0, 0 }, // 12 - DEC_RAT
  45. { 10, VDELAY_LO, 0, 0x00, CROP, 0, 0x3F, 0 }, // 13 - VDELAY
  46. { 10, VACTIVE_LO, 0, 0x00, CROP, 2, 0xCF, 0 }, // 14 - VACTIVE
  47. { 10, HDELAY_LO, 0, 0x00, CROP, 4, 0xF3, 0 }, // 15 - HDELAY
  48. { 10, HACTIVE_LO, 0, 0x00, CROP, 6, 0xFC, 0 }, // 16 - HACTIVE
  49. { 16, HSCALE_LO, 0, 0x00, HSCALE_HI, 0, 0x00, 0 }, // 17 - HSCALE
  50. { 8, BRIGHT, 0, 0x00, 0, 0, 0, 0 }, // 18 - BRIGHT
  51. { 1, CONTROL, 0, 0x7F, 0, 0, 0, 0 }, // 19 - LNOTCH
  52. { 1, CONTROL, 1, 0xBF, 0, 0, 0, 0 }, // 20 - COMP
  53. { 1, CONTROL, 2, 0xDF, 0, 0, 0, 0 }, // 21 - LDEC
  54. { 1, CONTROL, 3, 0xEF, 0, 0, 0, 0 }, // 22 - CBSENSE
  55. { 1, CONTROL, 4, 0xF7, 0, 0, 0, 0 }, // 23 - INTERP
  56. { 9, CONTRAST_LO, 0, 0x00, CONTROL, 5, 0xFB, 0 }, // 24 - CON
  57. { 9, SAT_U_LO, 0, 0x00, CONTROL, 6, 0xFD, 0 }, // 25 - SAT_U
  58. { 9, SAT_V_LO, 0, 0x00, CONTROL, 7, 0xFE, 0 }, // 26 - SAT_V
  59. { 8, HUE, 0, 0x00, 0, 0, 0, 0 }, // 27 - HUE
  60. { 1, OFORM, 0, 0x7F, 0, 0, 0, 0 }, // 28 - RANGE
  61. { 2, OFORM, 1, 0x9F, 0, 0, 0, 0 }, // 29 - RND
  62. { 1, OFORM, 3, 0xEF, 0, 0, 0, 0 }, // 30 - FIFO_BURST
  63. { 1, OFORM, 4, 0xF7, 0, 0, 0, 0 }, // 31 - CODE
  64. { 1, OFORM, 5, 0xFB, 0, 0, 0, 0 }, // 32 - LEN
  65. { 1, OFORM, 6, 0xFD, 0, 0, 0, 0 }, // 33 - SPI
  66. { 1, OFORM, 7, 0xFE, 0, 0, 0, 0 }, // 34 - FULL
  67. { 1, VSCALE_HI, 0, 0x7F, 0, 0, 0, 0 }, // 35 - LINE
  68. { 1, VSCALE_HI, 1, 0xBF, 0, 0, 0, 0 }, // 36 - COMB
  69. { 1, VSCALE_HI, 2, 0xDF, 0, 0, 0, 0 }, // 37 - INT
  70. { 13,VSCALE_LO, 0, 0x00, VSCALE_HI, 3, 0xE0, 0 }, // 38 - VSCALE
  71. { 1, VPOLE, 0, 0x7F, 0, 0, 0, 0 }, // 39 - OUTEN
  72. { 1, VPOLE, 1, 0xBF, 0, 0, 0, 0 }, // 40 - VALID_PIN
  73. { 1, VPOLE, 2, 0xDF, 0, 0, 0, 0 }, // 41 - AFF_PIN
  74. { 1, VPOLE, 3, 0xEF, 0, 0, 0, 0 }, // 42 - CBFLAG_PIN
  75. { 1, VPOLE, 4, 0xF7, 0, 0, 0, 0 }, // 43 - FIELD_PIN
  76. { 1, VPOLE, 5, 0xFB, 0, 0, 0, 0 }, // 44 - ACTIVE_PIN
  77. { 1, VPOLE, 6, 0xFD, 0, 0, 0, 0 }, // 45 - HRESET_PIN
  78. { 1, VPOLE, 7, 0xFE, 0, 0, 0, 0 }, // 46 - VRESET_PIN
  79. { 4, IDCODE, 0, 0, 0, 0, 0, READONLY }, // 47 - PART_ID
  80. { 4, IDCODE, 4, 0, 0, 0, 0, READONLY }, // 48 - PART_REV
  81. { 8, ADELAY, 0, 0x00, 0, 0, 0, 0 }, // 49 - ADELAY
  82. { 8, BDELAY, 0, 0x00, 0, 0, 0, 0 }, // 50 - BDELAY
  83. { 2, ADC, 0, 0x3F, 0, 0, 0, 0 }, // 51 - CLAMP
  84. { 1, ADC, 2, 0xDF, 0, 0, 0, 0 }, // 52 - SYNC_T
  85. { 1, ADC, 3, 0xEF, 0, 0, 0, 0 }, // 53 - AGC_EN
  86. { 1, ADC, 4, 0xF7, 0, 0, 0, 0 }, // 54 - CLK_SLEEP
  87. { 1, ADC, 5, 0xFB, 0, 0, 0, 0 }, // 55 - Y_SLEEP
  88. { 1, ADC, 6, 0xFD, 0, 0, 0, 0 }, // 56 - C_SLEEP
  89. { 8, SRESET, 0, 0x00, 0, 0, 0, 0 }, // 57 - SRESET
  90. };
  91. // enable, disable the hardware for video capture, query the maximum width of the capture
  92. ULONG VideoCaptureFnct(PDEV* ppdev,PVOID pvIn, PVOID pvOut)
  93. {
  94. VIDEOCAPTUREDATA * pBiosCapture, *pBiosCaptureOut;
  95. VIDEO_CAPTURE VideoCaptureDataIn, VideoCaptureDataOut;
  96. DWORD ReturnedDataLength ;
  97. pBiosCapture= ( VIDEOCAPTUREDATA *)pvIn;
  98. VideoCaptureDataIn.dwSubFunct= pBiosCapture->dwSubFunc;
  99. VideoCaptureDataIn.dwCaptureWidth=0;
  100. VideoCaptureDataIn.dwCaptureMode=pBiosCapture->dwCaptureMode;
  101. switch( pBiosCapture->dwSubFunc)
  102. {
  103. case 0:
  104. DISPDBG((DEBUG_ESC_2, "IOCTL_VIDEO_CAPTURE: requested subfunct = ENABLE"));
  105. break;
  106. case 1:
  107. DISPDBG((DEBUG_ESC_2, "IOCTL_VIDEO_CAPTURE: requested subfunct = DISABLE"));
  108. break;
  109. case 2:
  110. DISPDBG((DEBUG_ESC_2, "IOCTL_VIDEO_CAPTURE: requested subfunct = QUERY"));
  111. DISPDBG((DEBUG_ESC_2, "IOCTL_VIDEO_CAPTURE: requested mode = %d", pBiosCapture->dwCaptureMode));
  112. break;
  113. default:
  114. DISPDBG((DEBUG_ESC_2, "IOCTL_VIDEO_CAPTURE: requested subfunct = Wrong Parameter"));
  115. }
  116. if (!AtiDeviceIoControl(ppdev->hDriver,
  117. IOCTL_VIDEO_ATI_CAPTURE,
  118. &VideoCaptureDataIn,
  119. sizeof(VIDEO_CAPTURE),
  120. &VideoCaptureDataOut,
  121. sizeof(VIDEO_CAPTURE),
  122. &ReturnedDataLength))
  123. {
  124. DISPDBG((0, "bInitializeATI - Failed IOCTL_VIDEO_ATI_CAPTURE"));
  125. return 0; // the CWDDE is require a -1, but in win32 we have the return type ULONG
  126. }
  127. DISPDBG((DEBUG_ESC_2, "IOCTL_VIDEO_CAPTURE: maximum capture width returned= %d", VideoCaptureDataOut.dwCaptureWidth));
  128. pBiosCaptureOut= ( VIDEOCAPTUREDATA *)pvOut;
  129. if( pBiosCapture->dwSubFunc==2)
  130. pBiosCaptureOut->dwCaptureWidth=VideoCaptureDataOut.dwCaptureWidth;
  131. else
  132. pBiosCaptureOut->dwCaptureWidth=pBiosCapture->dwCaptureWidth;
  133. pBiosCaptureOut ->dwSubFunc=pBiosCapture->dwSubFunc;
  134. pBiosCaptureOut ->dwSize=pBiosCapture->dwSize;
  135. pBiosCaptureOut ->dwCaptureHeight=pBiosCapture->dwCaptureHeight;
  136. pBiosCaptureOut ->fccFormat=pBiosCapture->fccFormat;
  137. pBiosCaptureOut ->dwBitMasks[1]=pBiosCapture->dwBitMasks[1];
  138. pBiosCaptureOut ->dwBitMasks[2]=pBiosCapture->dwBitMasks[2];
  139. pBiosCaptureOut ->dwBitMasks[3]=pBiosCapture->dwBitMasks[3];
  140. pBiosCaptureOut ->dwCaptureMode=pBiosCapture->dwCaptureMode;
  141. return 1 ;
  142. }
  143. // this function is requested for 3D driver init
  144. void Init3D_Info(PDEV* ppdev,PVOID pvOut)
  145. {
  146. PHX2DHWINFO *pphx; /* Pointer to the structure containing info for 3D driver */
  147. pphx = (PHX2DHWINFO *) pvOut;
  148. // initialize the structure
  149. memset( pvOut, 0, sizeof(PHX2DHWINFO));
  150. // set size
  151. pphx->dwSize=sizeof(PHX2DHWINFO);
  152. // set ASIC type
  153. pphx->dwChipID=ppdev->iAsic;
  154. // set the asic revision
  155. // not implemented for the moment
  156. // detect if it's GT and set the flag
  157. if( ppdev->iAsic>=CI_M64_GTA )
  158. {
  159. pphx->b3DAvail = TRUE;
  160. pphx->dwFIFOSize = 32;
  161. }
  162. else
  163. {
  164. pphx->b3DAvail = FALSE;
  165. }
  166. // linear address of the aperture
  167. pphx->dwVideoBaseAddr=(ULONG)(ppdev->pjScreen);
  168. // linear address of the registers
  169. pphx->dwRegisterBaseAddr=(ULONG)(ppdev->pjMmBase);
  170. // linear address of the offscreen memory start
  171. pphx->dwOffScreenAddr=((ULONG)(ppdev->pjScreen) +
  172. ((ppdev->cxScreen)*(ppdev->cyScreen)*(ppdev->cBitsPerPel))/8);
  173. // offscreen size
  174. pphx->dwOffScreenSize=((ppdev->cyMemory)*ppdev->lDelta) -
  175. ((ppdev->cxScreen)*(ppdev->cyScreen)*(ppdev->cBitsPerPel))/8;
  176. // RAM size
  177. pphx->dwTotalRAM= ((ppdev->cyMemory)*ppdev->lDelta) ;
  178. // screen info
  179. pphx->dwScreenWidth=ppdev->cxScreen;
  180. pphx->dwScreenHeight=ppdev->cyScreen;
  181. pphx->dwScreenPitch=ppdev->cyScreen;
  182. pphx->dwBpp=ppdev->cBitsPerPel;
  183. if(pphx->dwBpp==16)
  184. {
  185. if(ppdev->flGreen==0x3e00)
  186. {
  187. pphx->dwAlphaBitMask=0x8000;
  188. pphx->dwRedBitMask=0x7c00;
  189. pphx->dwGreenBitMask=0x03e0;
  190. pphx->dwBlueBitMask=0x001f;
  191. }
  192. else
  193. {
  194. pphx->dwAlphaBitMask=0;
  195. pphx->dwRedBitMask=0xf800;
  196. pphx->dwGreenBitMask=0x07e0;
  197. pphx->dwBlueBitMask=0x001f;
  198. }
  199. }
  200. else
  201. {
  202. pphx->dwAlphaBitMask=0;
  203. pphx->dwRedBitMask=0;
  204. pphx->dwGreenBitMask=0;
  205. pphx->dwBlueBitMask=0;
  206. }
  207. }
  208. // the following functions are requested for palindrome support
  209. ULONG GetDisplayMode(PDEV* ppdev,PVOID pvOut)
  210. {
  211. ULONG RetVal;
  212. ModeInfo* pModeInfo;
  213. pModeInfo=(ModeInfo*)pvOut;
  214. RetVal=sizeof(ModeInfo);
  215. #ifndef DYNAMIC_REZ_AND_COLOUR_CHANGE // palindrome support for on the fly rez and colour depth
  216. pModeInfo->ScreenWidth= ppdev->cxScreen;
  217. pModeInfo->ScreenHeight=ppdev->cyScreen;
  218. #else // these values are used for dynamic resolution and colour depth support
  219. pModeInfo->ScreenWidth=1280; //ppdev->cxScreen;
  220. pModeInfo->ScreenHeight=1024; //ppdev->cyScreen;
  221. #endif
  222. //pModeInfo->ScreenColorFormat
  223. if (ppdev->cBitsPerPel == 4)
  224. pModeInfo->ScreenColorFormat=ATIConfig_ColorFmt_4_Packed;
  225. else if (ppdev->cBitsPerPel == 8)
  226. pModeInfo->ScreenColorFormat=ATIConfig_ColorFmt_8;
  227. else if (ppdev->cBitsPerPel == 16)
  228. pModeInfo->ScreenColorFormat=ATIConfig_ColorFmt_RGB565;
  229. else if (ppdev->cBitsPerPel == 24)
  230. pModeInfo->ScreenColorFormat=ATIConfig_ColorFmt_RGB888;
  231. else if (ppdev->cBitsPerPel == 32)
  232. pModeInfo->ScreenColorFormat=ATIConfig_ColorFmt_aRGB8888;
  233. else
  234. pModeInfo->ScreenColorFormat=-1;
  235. pModeInfo->DesctopWidth=ppdev->cxScreen;
  236. pModeInfo->DesctopHeight=ppdev->cyScreen;
  237. pModeInfo->SystemColorFormat=pModeInfo->ScreenColorFormat;
  238. return (RetVal);
  239. }
  240. ULONG AccessDevice(PDEV* ppdev,PVOID pvIn, PVOID pvOut)
  241. {
  242. ULONG RetVal;
  243. ACCESSDEVICEDATA* pstrAccessDeviceData;
  244. DWORD* pstrAccessDeviceDataOut;
  245. RetVal=1;
  246. pstrAccessDeviceDataOut=(DWORD*)pvOut;
  247. pstrAccessDeviceData=(ACCESSDEVICEDATA*)pvIn;
  248. if(pstrAccessDeviceData->dwAccessDeviceCode==ACCESSDEVICECODE_CONNECTOR)
  249. {
  250. switch(pstrAccessDeviceData->dwSubFunc)
  251. {
  252. case ACCESSDEVICEDATA_SUBFUNC_ALLOC:
  253. if((ppdev->pal_str.lpOwnerAccessStructConnector)==NULL)
  254. { //the device is not allocated
  255. (ppdev->pal_str.lpOwnerAccessStructConnector)=pstrAccessDeviceData;
  256. (*pstrAccessDeviceDataOut) = (DWORD)pstrAccessDeviceData;
  257. }
  258. else
  259. { // the device is allocated to another owner
  260. (*pstrAccessDeviceDataOut) = (DWORD)(ppdev->pal_str.lpOwnerAccessStructConnector);
  261. }
  262. break;
  263. case ACCESSDEVICEDATA_SUBFUNC_FREE:
  264. if((ppdev->pal_str.lpOwnerAccessStructConnector)!=NULL)
  265. { //the device is allocated
  266. if((ppdev->pal_str.lpOwnerAccessStructConnector)==pstrAccessDeviceData) //if the owner wants to free the device
  267. {
  268. (*pstrAccessDeviceDataOut) = (DWORD)NULL;
  269. (ppdev->pal_str.lpOwnerAccessStructConnector)=NULL; // no owner at this time
  270. }
  271. else
  272. { /*
  273. //other process is the owner, so fail
  274. (*pstrAccessDeviceDataOut) = (DWORD)pstrAccessDeviceData;
  275. */
  276. // Due to the fact that Palindrome is inconsistent in using the same pointer to ACCESSDEVICE struct
  277. // for QUERY, ALLOC and FREE, we have to force the dealocation anyway
  278. (*pstrAccessDeviceDataOut) = (DWORD)NULL;
  279. (ppdev->pal_str.lpOwnerAccessStructConnector)=NULL; // no owner at this time
  280. }
  281. }
  282. else
  283. { // the device is not allocated , so we can free it anyway
  284. (*pstrAccessDeviceDataOut) =(DWORD) NULL;
  285. (ppdev->pal_str.lpOwnerAccessStructConnector)=NULL;
  286. }
  287. break;
  288. case ACCESSDEVICEDATA_SUBFUNC_QUERY:
  289. if(( ppdev->pal_str.lpOwnerAccessStructConnector)==NULL) // if the device is free
  290. {
  291. (*pstrAccessDeviceDataOut) = (DWORD)NULL;
  292. }
  293. else
  294. { // if the device is owned already
  295. (*pstrAccessDeviceDataOut) = (DWORD)(ppdev->pal_str.lpOwnerAccessStructConnector);
  296. }
  297. break;
  298. default:
  299. RetVal=0xffffffff;
  300. }
  301. }
  302. else
  303. {
  304. if(pstrAccessDeviceData->dwAccessDeviceCode==ACCESSDEVICECODE_OVERLAY)
  305. {
  306. switch(pstrAccessDeviceData->dwSubFunc)
  307. {
  308. case ACCESSDEVICEDATA_SUBFUNC_ALLOC:
  309. if((ppdev->pal_str.lpOwnerAccessStructOverlay)==NULL)
  310. {
  311. //the device is not allocated by an external client
  312. // but first verify if DDraw is not using it
  313. if(ppdev->semph_overlay==0) // = 0 resource free; = 1 in use by DDraw; = 2 in use by Palindrome;
  314. {
  315. (ppdev->pal_str.lpOwnerAccessStructOverlay)=pstrAccessDeviceData;
  316. (*pstrAccessDeviceDataOut) =(DWORD) pstrAccessDeviceData;
  317. ppdev->semph_overlay=2;
  318. }
  319. else
  320. {
  321. // the overlay is used by DDraw, so let's try to do this:
  322. (*pstrAccessDeviceDataOut) =(DWORD)NULL;
  323. }
  324. }
  325. else
  326. { // the device is allocated to another owner
  327. (*pstrAccessDeviceDataOut) =(DWORD) (ppdev->pal_str.lpOwnerAccessStructOverlay);
  328. }
  329. break;
  330. case ACCESSDEVICEDATA_SUBFUNC_FREE:
  331. if((ppdev->pal_str.lpOwnerAccessStructOverlay)!=NULL)
  332. { //the device is allocated
  333. if((ppdev->pal_str.lpOwnerAccessStructOverlay)==pstrAccessDeviceData) //if the owner wants to free the device
  334. {
  335. (*pstrAccessDeviceDataOut) = (DWORD)NULL;
  336. (ppdev->pal_str.lpOwnerAccessStructOverlay)=NULL; // no owner at this time
  337. ppdev->semph_overlay=0;
  338. }
  339. else
  340. { //other process is the owner, so we are supposed to fail
  341. // (*pstrAccessDeviceDataOut) = (DWORD)pstrAccessDeviceData;
  342. // but due to the fact that the palindrome code it's not consistently using the same pointer to the ACCESSDEVICEDATA structure
  343. // inside a session of allocation/deallocation, we are failing the owner test so that we will free the overlay anyway if it's used by palindrome
  344. if(ppdev->semph_overlay==2)
  345. {
  346. (*pstrAccessDeviceDataOut) = (DWORD)NULL;
  347. (ppdev->pal_str.lpOwnerAccessStructOverlay)=NULL; // no owner at this time
  348. ppdev->semph_overlay=0;
  349. }
  350. else // DDraw is using the overlay; very improbable at this moment
  351. {
  352. (*pstrAccessDeviceDataOut) = (DWORD)pstrAccessDeviceData;
  353. }
  354. }
  355. }
  356. else
  357. {
  358. if( (ppdev->semph_overlay==0) || (ppdev->semph_overlay==2)) // = 0 resource free; = 1 in use by DDraw; = 2 in use by Palindrome;
  359. {
  360. // the device is not allocated to another process than palindrome, so we can free it anyway
  361. (*pstrAccessDeviceDataOut) = (DWORD)NULL;
  362. (ppdev->pal_str.lpOwnerAccessStructOverlay)=NULL;
  363. }
  364. else
  365. {
  366. // the overlay is used by DDraw, but no external app
  367. (*pstrAccessDeviceDataOut) = (DWORD)pstrAccessDeviceData;
  368. (ppdev->pal_str.lpOwnerAccessStructOverlay)=NULL;
  369. }
  370. }
  371. break;
  372. case ACCESSDEVICEDATA_SUBFUNC_QUERY:
  373. if( (ppdev->pal_str.lpOwnerAccessStructOverlay)==NULL) // if the device is free
  374. {
  375. //the device is not allocated by an external client
  376. // but first verify if DDraw is not using it
  377. if(ppdev->semph_overlay==0) // = 0 resource free; = 1 in use by DDraw; = 2 in use by Palindrome;
  378. {
  379. (*pstrAccessDeviceDataOut) =(DWORD) NULL;
  380. }
  381. else
  382. {
  383. // the overlay is used by DDraw, so let's try to do this (return its own access structure):
  384. (*pstrAccessDeviceDataOut) =(DWORD)pstrAccessDeviceData;
  385. }
  386. }
  387. else
  388. { // if the device is owned already
  389. (*pstrAccessDeviceDataOut) = (DWORD)(ppdev->pal_str.lpOwnerAccessStructOverlay);
  390. }
  391. break;
  392. default:
  393. RetVal=0xffffffff;
  394. }
  395. }
  396. else
  397. {
  398. RetVal=0xffffffff;
  399. }
  400. }
  401. return (RetVal);
  402. }
  403. ULONG GetConfiguration(PDEV* ppdev,PVOID pvOut)
  404. {
  405. ULONG RetVal;
  406. ATIConfig* pATIConfig;
  407. pATIConfig=( ATIConfig*)pvOut;
  408. strcpy(pATIConfig->ATISig,"761295520\x0");
  409. strcpy(pATIConfig->DriverName, "ati\x0\x0\x0\x0\x0\x0");
  410. pATIConfig->dwMajorVersion=2;
  411. pATIConfig->dwMinorVersion=1;
  412. pATIConfig->dwDesktopWidth=ppdev->cxScreen;
  413. pATIConfig->dwDesktopHeight=ppdev->cyScreen;
  414. pATIConfig->dwEnginePitch=ppdev->lDelta;
  415. pATIConfig->dwRealRamAvail=(ppdev->cyMemory)*(ppdev->lDelta);
  416. pATIConfig->dwBpp=ppdev->cBitsPerPel;
  417. pATIConfig->dwBoardBpp=ppdev->cBitsPerPel;
  418. if (ppdev->cBitsPerPel == 4)
  419. pATIConfig->dwColorFormat=ATIConfig_ColorFmt_4_Packed;
  420. else if (ppdev->cBitsPerPel == 8)
  421. pATIConfig->dwColorFormat=ATIConfig_ColorFmt_8;
  422. else if (ppdev->cBitsPerPel == 16)
  423. pATIConfig->dwColorFormat=ATIConfig_ColorFmt_RGB555;
  424. else if (ppdev->cBitsPerPel == 24)
  425. pATIConfig->dwColorFormat=ATIConfig_ColorFmt_RGB888;
  426. else if (ppdev->cBitsPerPel == 32)
  427. pATIConfig->dwColorFormat=ATIConfig_ColorFmt_aRGB8888;
  428. else
  429. pATIConfig->dwColorFormat=0xffffffff;
  430. pATIConfig->dwAlphaBitMask=0;
  431. pATIConfig->dwConfigBits=0;
  432. switch(ppdev->iAsic)
  433. {
  434. case CI_38800_1:
  435. pATIConfig->dwBoardType=1;
  436. break;
  437. case CI_68800_3:
  438. case CI_68800_6:
  439. case CI_68800_AX:
  440. pATIConfig->dwBoardType=2;
  441. break;
  442. case CI_M64_GENERIC:
  443. pATIConfig->dwBoardType=3;
  444. break;
  445. default:
  446. pATIConfig->dwBoardType=0;
  447. }
  448. switch(ppdev->iAperture)
  449. {
  450. case ENGINE_ONLY :
  451. pATIConfig->dwApertureType=1;
  452. break;
  453. case AP_LFB:
  454. pATIConfig->dwApertureType=3;
  455. break;
  456. case AP_VGA_SINGLE:
  457. case FL_VGA_SPLIT:
  458. pATIConfig->dwApertureType=2;
  459. break;
  460. default:
  461. pATIConfig->dwApertureType=0;
  462. }
  463. RetVal=sizeof(ATIConfig);
  464. return (RetVal);
  465. }
  466. ULONG WriteRegFnct(PDEV* ppdev,PVOID pvIn)
  467. {
  468. ULONG RetVal;
  469. DISPDBG( (DEBUG_ESC," reg_block: %u ",((RW_REG_STRUCT*)pvIn)->reg_block ));
  470. DISPDBG( (DEBUG_ESC," reg_offset: 0x%X ",((RW_REG_STRUCT*)pvIn)->reg_offset ));
  471. DISPDBG( (DEBUG_ESC," write_data: 0x%lX " ,((RW_REG_STRUCT*)pvIn)->data ));
  472. //parameters validation for increase roboustness (limited access to certain registers and certaines fields)
  473. if( ((((RW_REG_STRUCT*)pvIn)->reg_block)!=0)&&((((RW_REG_STRUCT*)pvIn)->reg_block)!=1) )
  474. {
  475. RetVal=ESC_FAILED;
  476. DISPDBG( (DEBUG_ESC," Write failed: wrong block no."));
  477. return (RetVal);
  478. }
  479. if( ((RW_REG_STRUCT*)pvIn)->reg_offset>255 )
  480. {
  481. RetVal=ESC_FAILED;
  482. DISPDBG( (DEBUG_ESC," Write failed : wrong offsett value"));
  483. return (RetVal);
  484. }
  485. // end of parameters validation
  486. //what kind of write?
  487. if((((RW_REG_STRUCT*)pvIn)->reg_block)==1) //block 1
  488. {
  489. if( ( (RW_REG_STRUCT*)pvIn)->reg_offset<0x30 )
  490. {
  491. if(ppdev->pal_str.Mode_Switch_flag==TRUE) //if a mode switch intercepts writes to the buffers and use the values stored in ppdev->pal_str
  492. {
  493. switch(((RW_REG_STRUCT*)pvIn)->reg_offset)
  494. {
  495. DWORD key_clr;
  496. DWORD key_mask;
  497. case 0x4:
  498. switch(ppdev->cBitsPerPel)
  499. {
  500. case 8:
  501. key_clr=0xFD;
  502. break;
  503. case 15:
  504. key_clr=0x7C1F;
  505. break;
  506. case 16:
  507. key_clr=0xF81F;
  508. break;
  509. case 24:
  510. key_clr=0xFF00FF;
  511. break;
  512. case 32:
  513. key_clr=0xFF00FF; //?
  514. break;
  515. }
  516. WriteVTReg(0x4,key_clr);
  517. break;
  518. case 0x5:
  519. switch(ppdev->cBitsPerPel)
  520. {
  521. case 8:
  522. key_mask=0xFF;
  523. break;
  524. case 15:
  525. key_mask=0xFFFF;
  526. break;
  527. case 16:
  528. key_mask=0xFFFF;
  529. break;
  530. case 24:
  531. key_mask=0xFFFFFF;
  532. break;
  533. case 32:
  534. key_mask=0xFFFFFF; //?
  535. break;
  536. }
  537. WriteVTReg(0x5,key_mask);
  538. break;
  539. case 0x20:
  540. if( ppdev->iAsic>=CI_M64_GTB )
  541. {
  542. WriteVTReg(0x20,ppdev->pal_str.Buf0_Offset);
  543. WriteVTReg(0x22,ppdev->pal_str.Buf0_Offset);
  544. }
  545. else
  546. {
  547. WriteVTReg(0x20,ppdev->pal_str.Buf0_Offset);
  548. }
  549. break;
  550. case 0x22:
  551. if ((ppdev->iAsic == CI_M64_VTB)||(ppdev->iAsic >= CI_M64_GTB))
  552. {
  553. WriteVTReg(0x22,ppdev->pal_str.Buf0_Offset);
  554. }
  555. break;
  556. case 0xe:
  557. if ((ppdev->iAsic == CI_M64_VTB)||(ppdev->iAsic >= CI_M64_GTB))
  558. {
  559. WriteVTReg(0xe,ppdev->pal_str.Buf0_Offset);
  560. }
  561. break;
  562. case 0x26:
  563. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  564. {
  565. WriteVTReg(0x26,ppdev->pal_str.Buf0_Offset);
  566. }
  567. break;
  568. case 0x2B:
  569. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  570. {
  571. WriteVTReg(0x2B,ppdev->pal_str.Buf0_Offset);
  572. }
  573. break;
  574. case 0x2C:
  575. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  576. {
  577. WriteVTReg(0x2C,ppdev->pal_str.Buf0_Offset);
  578. }
  579. break;
  580. default:
  581. WriteVTReg(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  582. }
  583. }
  584. else
  585. {
  586. WriteVTReg(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  587. // bug in Palindrome application for VTB, GTB: the capture is set in CAPTURE_CONFIG for Continuous Even, One Shot , but without setting
  588. // the ONESHOT_BUF_OFFSET. So I set this reg like CAP_BUF0_OFFSET.
  589. #define CAP_BUF_BUG
  590. #ifdef CAP_BUF_BUG
  591. if ( (((RW_REG_STRUCT*)pvIn)->reg_offset==0x20) && (ppdev->iAsic>=CI_M64_GTB) ) //CAPTURE_BUF0_OFFSET
  592. {
  593. //write also the same value for ONESHOT_BUFFER
  594. WriteVTReg(0x22,((RW_REG_STRUCT*)pvIn)->data);
  595. }
  596. #endif
  597. }
  598. #if 1 // start debug statements for registers monitoring
  599. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x06)
  600. {
  601. DISPDBG( (DEBUG_ESC_2," Write OVERLAY_KEY_CNTL: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  602. }
  603. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x02)
  604. {
  605. DISPDBG( (DEBUG_ESC_2," Write OVERLAY_VIDEO_KEY_CLR: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  606. }
  607. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x03)
  608. {
  609. DISPDBG( (DEBUG_ESC_2," Write OVERLAY_VIDEO_KEY_MSK: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  610. }
  611. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x04)
  612. {
  613. DISPDBG( (DEBUG_ESC_2," Write OVERLAY_GRAPHICS_KEY_CLR: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  614. }
  615. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x05)
  616. {
  617. DISPDBG( (DEBUG_ESC_2," Write OVERLAY_GRAPHICS_KEY_MSK: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  618. }
  619. // debug info for buffer offset and pitch
  620. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x20)
  621. {
  622. DISPDBG( (DEBUG_ESC_2," Write BUFF0_OFFSET: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  623. }
  624. if(((RW_REG_STRUCT*)pvIn)->reg_offset==0x23)
  625. {
  626. DISPDBG( (DEBUG_ESC_2," Write BUFF0_PITCH: 0x%lX ",((RW_REG_STRUCT*)pvIn)->data));
  627. }
  628. #endif // end debug statements
  629. }
  630. else
  631. {
  632. RIP(("Protected Register in block 1"));
  633. }
  634. }
  635. else //block 0
  636. {
  637. // #define NO_VERIFICATION
  638. #ifndef NO_VERIFICATION
  639. // we verify the writings
  640. switch(((RW_REG_STRUCT*)pvIn)->reg_offset)
  641. {
  642. DWORD value;
  643. case 0x1e:
  644. MemR32(((RW_REG_STRUCT*)pvIn)->reg_offset,&value);
  645. value=((value&0x0)|( (((RW_REG_STRUCT*)pvIn)->data)&0xffffffff ));
  646. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset, value);
  647. break;
  648. case 0x34:
  649. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  650. {
  651. MemR32(((RW_REG_STRUCT*)pvIn)->reg_offset,&value);
  652. value=((value&0xffffff80)|( (((RW_REG_STRUCT*)pvIn)->data)&0x3d ));
  653. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset, value);
  654. }
  655. break;
  656. case 0x31:
  657. MemR32(((RW_REG_STRUCT*)pvIn)->reg_offset,&value);
  658. value=((value&0x80ffbfff)|( (((RW_REG_STRUCT*)pvIn)->data)&0x3f004000 ));
  659. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset, value);
  660. break;
  661. case 0x1f:
  662. // bug in GTA hardware
  663. if (ppdev->iAsic == CI_M64_GTA)
  664. {
  665. DWORD local_value;
  666. DWORD HTotal;
  667. MemR32( 0x7 ,&local_value);
  668. MemW32(0x7,(local_value&0xffbfffff));
  669. MemR32(0x0,&HTotal);
  670. MemW32(0x7,local_value);
  671. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  672. MemR32( 0x7 ,&local_value);
  673. MemW32(0x7,(local_value&0xffbfffff));
  674. MemW32(0x0,HTotal);
  675. MemW32(0x7,local_value);
  676. }
  677. else
  678. {
  679. if (ppdev->iAsic ==CI_M64_VTA)
  680. {
  681. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  682. }
  683. }
  684. break;
  685. case 0x28:
  686. MemR32(((RW_REG_STRUCT*)pvIn)->reg_offset,&value);
  687. value=((value&0xf7ffffff)|( (((RW_REG_STRUCT*)pvIn)->data)&0x08000000 ));
  688. // the following line of code is necessary because we cannot allow user code to turn off block1
  689. // due to the fact that this block is also used by DDraw (for this case anyway we are sharing and arbitrating resources)
  690. // and more important by MCD OGL; so we only allow to turn on block1.
  691. value=value | 0x08000000;
  692. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset, value);
  693. break;
  694. #define NO_ACCESS
  695. #ifdef NO_ACCESS
  696. case 0x07: // maybe access to this register is not necessary
  697. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  698. break;
  699. case 0x24: // maybe access to this register is not necessary
  700. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  701. break;
  702. #endif // NO_ACCESS
  703. default:
  704. RetVal=ESC_FAILED;
  705. RIP(("Protected Register in block 0"));
  706. DISPDBG( (DEBUG_ESC," Write failed : this register is protected"));
  707. break;
  708. }
  709. #else
  710. // we don't verify the writings
  711. {
  712. // bug in hardware on GTA
  713. if (((RW_REG_STRUCT*)pvIn)->reg_offset==0x1f)
  714. {
  715. DWORD local_value;
  716. DWORD HTotal;
  717. MemR32( 0x7 ,&local_value);
  718. MemW32(0x7,(local_value&0xffbfffff));
  719. MemR32(0x0,&HTotal);
  720. MemW32(0x7,local_value);
  721. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  722. MemR32( 0x7 ,&local_value);
  723. MemW32(0x7,(local_value&0xffbfffff));
  724. MemW32(0x0,HTotal);
  725. MemW32(0x7,local_value);
  726. }
  727. else
  728. MemW32(((RW_REG_STRUCT*)pvIn)->reg_offset,((RW_REG_STRUCT*)pvIn)->data);
  729. }
  730. #endif // End NO_VERIFICATION
  731. }
  732. RetVal=ESC_OK;
  733. DISPDBG( (DEBUG_ESC," Write OK"));
  734. DISPDBG( (DEBUG_ESC," "));
  735. //DebugBreak() ;
  736. return (RetVal);
  737. }
  738. ULONG ReadRegFnct(PDEV* ppdev,PVOID pvIn, PVOID pvOut)
  739. {
  740. ULONG RetVal;
  741. DISPDBG( (DEBUG_ESC," reg_block: %u ",((RW_REG_STRUCT*)pvIn)->reg_block ));
  742. DISPDBG( (DEBUG_ESC," reg_offset: 0x%X ",((RW_REG_STRUCT*)pvIn)->reg_offset ));
  743. //parameters validation
  744. if( ((((RW_REG_STRUCT*)pvIn)->reg_block)!=0)&&((((RW_REG_STRUCT*)pvIn)->reg_block)!=1) )
  745. {
  746. RetVal=ESC_FAILED;
  747. DISPDBG( (DEBUG_ESC," Write failed: wrong block no."));
  748. return (RetVal);
  749. }
  750. if( ((RW_REG_STRUCT*)pvIn)->reg_offset>255 )
  751. {
  752. RetVal=ESC_FAILED;
  753. DISPDBG( (DEBUG_ESC," Write failed: wrong offset."));
  754. return (RetVal);
  755. }
  756. // end of parameters validation
  757. //what kind of read?
  758. if((((RW_REG_STRUCT*)pvIn)->reg_block)==1)
  759. {
  760. ReadVTReg(((RW_REG_STRUCT*)pvIn)->reg_offset,(DWORD*)pvOut);
  761. }
  762. else
  763. {
  764. MemR32(((RW_REG_STRUCT*)pvIn)->reg_offset,(DWORD*)pvOut);
  765. }
  766. RetVal=ESC_OK;
  767. DISPDBG( (DEBUG_ESC," read_data: 0x%lX " , *((DWORD*)pvOut) ));
  768. DISPDBG( (DEBUG_ESC,"Read OK."));
  769. DISPDBG( (DEBUG_ESC," "));
  770. //DebugBreak() ;
  771. return (RetVal);
  772. }
  773. /*^^*
  774. * Function: I2CAccess
  775. *
  776. * Purpose: To complete an I2C packet.
  777. *
  778. * Inputs: str: LPI2CSTRUCT
  779. *
  780. * Outputs: void.
  781. *^^*/
  782. void I2CAccess_New(PDEV* ppdev,LPI2CSTRUCT_NEW str,LPI2CSTRUCT_NEW str_out)
  783. {
  784. unsigned char i = 0;
  785. str_out->wError = 0;
  786. /*
  787. * Implement WRITE request
  788. */
  789. if (str->wWriteCount) {
  790. Start(ppdev, str->wCard);
  791. // Write Chip Address (for WRITE)
  792. WriteByteI2C(ppdev, str->wCard, (BYTE)(str->wChipID & 0xfe));
  793. // Acc the previous write...
  794. if (!Ack(ppdev, str->wCard, FALSE)) str_out->wError |= I2C_ACK_WR_ERROR;
  795. for (i = 0;i < str->wWriteCount;i++) {
  796. // Write the required data
  797. WriteByteI2C(ppdev, str->wCard, str->lpWrData[i]);
  798. // Acc the previous write...
  799. if (!Ack(ppdev, str->wCard, FALSE)) str_out->wError |= I2C_ACK_WR_ERROR;
  800. }
  801. Stop(ppdev, str->wCard);
  802. }
  803. /*
  804. * Implement READ request
  805. */
  806. if (str->wReadCount) {
  807. Start(ppdev, str->wCard);
  808. // Write Chip Address (for READ)
  809. WriteByteI2C(ppdev, str->wCard, (BYTE)(str->wChipID & 0xfe | 0x01));
  810. //!! Can't do an Ack here with ATI hardware.
  811. //!! SIS claims that they always do one. Don't
  812. //!! know why there would be a difference.
  813. if (!Ack(ppdev, str->wCard, FALSE)) str_out->wError |= I2C_ACK_RD_ERROR;
  814. for (i = 0;i < str->wReadCount;i++) {
  815. // Read the required data
  816. if (i) Ack(ppdev, str->wCard, TRUE);
  817. str_out->lpRdData[i] = ReadByteI2C(ppdev, str->wCard);
  818. }
  819. Stop(ppdev, str->wCard);
  820. }
  821. DISPDBG( (DEBUG_ESC_I2C," PAL : I2C Access"));
  822. DISPDBG( (DEBUG_ESC_I2C," Card no: 0x%X " , str->wCard ));
  823. DISPDBG( (DEBUG_ESC_I2C," Chip ID: 0x%X " , str->wChipID ));
  824. DISPDBG( (DEBUG_ESC_I2C," Error: 0x%X" , str->wError ));
  825. DISPDBG( (DEBUG_ESC_I2C," Write Count: 0x%X " , str->wWriteCount ));
  826. DISPDBG( (DEBUG_ESC_I2C," Read Count: 0x%X " , str->wReadCount ));
  827. for (i = 0;i < str->wWriteCount;i++)
  828. {
  829. DISPDBG( (DEBUG_ESC_I2C," WriteData[%u]: 0x%X " , i, str->lpWrData[0] ));
  830. }
  831. for (i = 0;i < str->wReadCount;i++)
  832. {
  833. DISPDBG( (DEBUG_ESC_I2C," ReadData[%u]: 0x%X " , i, str->lpRdData[0] ));
  834. }
  835. DISPDBG( (DEBUG_ESC_I2C," "));
  836. //DebugBreak() ;
  837. }
  838. // end of I2CAccess_New
  839. ////// Functions for I2C support
  840. /*^^*
  841. * Function: ReadI2CData
  842. *
  843. * Purpose: To read a bit from the I2C data line.
  844. *
  845. * Inputs: PDEV*, wCard: WORD, the card number to write to.
  846. *
  847. * Outputs: BYTE, the read data bit.
  848. *^^*/
  849. BYTE ReadI2CData(PDEV* ppdev, WORD wCard)
  850. {
  851. //return (BYTE) ReadVT264Reg(ppdev, wCard,vtf_GEN_GIO2_DATA_IN);
  852. if ((ppdev->iAsic == CI_M64_VTA)||(ppdev->iAsic == CI_M64_GTA))
  853. return (BYTE) ReadVT264Reg(ppdev, wCard,vtf_GEN_GIO2_DATA_IN);
  854. if ((ppdev->iAsic == CI_M64_VTB)||(ppdev->iAsic >= CI_M64_GTB))
  855. return (BYTE) ReadVT264Reg(ppdev, wCard,vtf_GP_IO_4);
  856. }
  857. /*^^*
  858. * Function: ReadAnyReg
  859. *
  860. * Purpose: To waste a small amount of time in order to
  861. * ensure the I2C bus timing.
  862. *
  863. * Inputs: PDEV*, wCard: WORD, the card number to write to.
  864. *
  865. * Outputs: none.
  866. *^^*/
  867. void ReadAnyReg(PDEV* ppdev, WORD wCard)
  868. {
  869. ReadVT264Reg(ppdev, wCard, vtf_CFG_CHIP_FND_ID);
  870. }
  871. /*^^*
  872. * Function: SetI2CDataDirection
  873. *
  874. * Purpose: To set the data direction of the I2C
  875. * controller chip to allow for reads and/or
  876. * writes to the I2C bus.
  877. *
  878. * Inputs: PDEV*, wCard: WORD, the card number to write to.
  879. *
  880. * Outputs: none.
  881. *
  882. * Note: Some chips may allow read and/or writes without
  883. * any state change. For these chips this should be
  884. * implemented as a NULL function.
  885. *^^*/
  886. void SetI2CDataDirection(PDEV* ppdev, WORD wCard, BOOL fWrite)
  887. {
  888. //WriteVT264Reg(ppdev, wCard, vtf_GEN_GIO2_WRITE, fWrite?1:0);
  889. if ((ppdev->iAsic == CI_M64_VTA)||(ppdev->iAsic == CI_M64_GTA))
  890. WriteVT264Reg(ppdev, wCard, vtf_GEN_GIO2_WRITE, fWrite?1:0);
  891. if ((ppdev->iAsic == CI_M64_VTB)||(ppdev->iAsic >= CI_M64_GTB))
  892. WriteVT264Reg(ppdev, wCard, vtf_GP_IO_DIR_4, fWrite?1:0);
  893. }
  894. /*^^*
  895. * Function: WriteI2CClock
  896. *
  897. * Purpose: To set the state of the I2C clock line.
  898. *
  899. * Inputs: PDEV*, wCard: WORD, the card number to write to.
  900. * cClock: BYTE, the new clock state.
  901. *
  902. * Outputs: none.
  903. *^^*/
  904. void WriteI2CClock(PDEV* ppdev, WORD wCard, BYTE cClock)
  905. {
  906. //WriteVT264Reg(ppdev, wCard, vtf_DAC_GIO_STATE_1, (DWORD)cClock);
  907. if ((ppdev->iAsic == CI_M64_VTA)||(ppdev->iAsic == CI_M64_GTA))
  908. WriteVT264Reg(ppdev, wCard, vtf_DAC_GIO_STATE_1, (DWORD)cClock);
  909. if ((ppdev->iAsic == CI_M64_VTB)||(ppdev->iAsic >= CI_M64_GTB))
  910. WriteVT264Reg(ppdev, wCard, vtf_GP_IO_B, (DWORD)cClock);
  911. }
  912. /*^^*
  913. * Function: WriteI2CData
  914. *
  915. * Purpose: To set the state of the I2C data line.
  916. *
  917. * Inputs: PDEV*, wCard: WORD, the card number to write to.
  918. * cDataBit: BYTE, the new data value.
  919. *
  920. * Outputs: none.
  921. *^^*/
  922. void WriteI2CData(PDEV* ppdev, WORD wCard, BYTE cDataBit)
  923. {
  924. //WriteVT264Reg(ppdev, wCard, vtf_GEN_GIO2_DATA_OUT, (DWORD)cDataBit);
  925. if ((ppdev->iAsic == CI_M64_VTA)||(ppdev->iAsic == CI_M64_GTA))
  926. WriteVT264Reg(ppdev, wCard, vtf_GEN_GIO2_DATA_OUT, (DWORD)cDataBit);
  927. if ((ppdev->iAsic == CI_M64_VTB)||(ppdev->iAsic >= CI_M64_GTB))
  928. WriteVT264Reg(ppdev, wCard, vtf_GP_IO_4, (DWORD)cDataBit);
  929. }
  930. /*^^*
  931. * Function: ReverseByte
  932. *
  933. * Purpose: To reverse the bit order of a byte.
  934. *
  935. * Inputs: wData: BYTE, The data to be reversed.
  936. *
  937. * Outputs: WORD, the reversed word.
  938. *
  939. *^^*/
  940. BYTE ReverseByte(BYTE wData)
  941. {
  942. BYTE result = 0;
  943. BYTE x, y;
  944. // x shifts up through all possible bits (8)
  945. // y shifts down through all possible bits (8)
  946. // if 'x' bit is set the set 'y' bit.
  947. for (x=0x01, y=0x80; y; x<<=1, y>>=1) if (wData & x) result |= y;
  948. return (result);
  949. }
  950. // end of ReverseByte()
  951. /*^^*
  952. * Function: Ack
  953. *
  954. * Purpose: To ask the I2C bus for an acknowledge.
  955. *
  956. * Inputs: PDEV*, wCard: WORD, the card number to write.
  957. *
  958. * Outputs: void.
  959. *^^*/
  960. WORD Ack(PDEV* ppdev, WORD wCard, BOOL fPut)
  961. {
  962. WORD ack = 0;
  963. if (fPut) {
  964. // Push Ack onto I2C bus
  965. // Enable I2C writes
  966. SetI2CDataDirection(ppdev, wCard, I2C_WRITE);
  967. // Drive data line low
  968. WriteI2CData(ppdev, wCard, I2C_LOW);
  969. I2CDelay(ppdev, wCard);
  970. // Drive I2C clock line high
  971. WriteI2CClock(ppdev, wCard, I2C_HIGH);
  972. I2CDelay(ppdev, wCard);
  973. // Write acknowledge from I2C bus
  974. WriteI2CClock(ppdev, wCard, I2C_LOW);
  975. I2CDelay(ppdev, wCard);
  976. // Disable I2C writes
  977. SetI2CDataDirection(ppdev, wCard, I2C_READ);
  978. } else {
  979. // Receive Ack from I2C bus
  980. // Disable I2C writes
  981. SetI2CDataDirection(ppdev, wCard, I2C_READ);
  982. I2CDelay(ppdev, wCard);
  983. // Drive I2C clock line high
  984. WriteI2CClock(ppdev, wCard, I2C_HIGH);
  985. I2CDelay(ppdev, wCard);
  986. // Read acknowledge from I2C bus
  987. ack = (BYTE) ReadI2CData(ppdev, wCard);
  988. // Drive I2C clock low
  989. WriteI2CClock(ppdev, wCard, I2C_LOW);
  990. I2CDelay(ppdev, wCard);
  991. }
  992. // Clock is LOW
  993. // Data is tristate
  994. return (!ack);
  995. }
  996. // end of Ack()
  997. /*^^*
  998. * Function: Start
  999. *
  1000. * Purpose: To start a transfer on the I2C bus.
  1001. *
  1002. * Inputs: PDEV*, wCard: WORD, the card number to write.
  1003. *
  1004. * Outputs: void.
  1005. *^^*/
  1006. void Start(PDEV* ppdev, WORD wCard)
  1007. {
  1008. // Enable I2C writes
  1009. SetI2CDataDirection(ppdev, wCard, I2C_WRITE);
  1010. // Drive data high
  1011. WriteI2CData(ppdev, wCard, I2C_HIGH);
  1012. I2CDelay(ppdev, wCard);
  1013. // Drive clock high
  1014. WriteI2CClock(ppdev, wCard, I2C_HIGH);
  1015. I2CDelay(ppdev, wCard);
  1016. // Drive data low
  1017. WriteI2CData(ppdev, wCard, I2C_LOW);
  1018. I2CDelay(ppdev, wCard);
  1019. // Drive clock low
  1020. WriteI2CClock(ppdev, wCard, I2C_LOW);
  1021. I2CDelay(ppdev, wCard);
  1022. // Clock is LOW
  1023. // Data is LOW
  1024. }
  1025. // end of Start
  1026. /*^^*
  1027. * Function: Stop
  1028. *
  1029. * Purpose: To stop a transfer on the I2C bus.
  1030. *
  1031. * Inputs: PDEV*, wCard: WORD, the card number to write.
  1032. *
  1033. * Outputs: void.
  1034. *^^*/
  1035. void Stop(PDEV* ppdev, WORD wCard)
  1036. {
  1037. // Enable I2C writes
  1038. SetI2CDataDirection(ppdev, wCard, I2C_WRITE);
  1039. // Drive data low
  1040. WriteI2CData(ppdev, wCard, I2C_LOW);
  1041. I2CDelay(ppdev, wCard);
  1042. // Drive clock high
  1043. WriteI2CClock(ppdev, wCard, I2C_HIGH);
  1044. I2CDelay(ppdev, wCard);
  1045. // Drive data high
  1046. WriteI2CData(ppdev, wCard, I2C_HIGH);
  1047. I2CDelay(ppdev, wCard);
  1048. // Disable I2C writes
  1049. SetI2CDataDirection(ppdev, wCard, I2C_READ);
  1050. // Clock is HIGH
  1051. // Data is tri-state
  1052. }
  1053. // end of Stop
  1054. /*^^*
  1055. * Function: WriteByteI2C
  1056. *
  1057. * Purpose: To write a byte of data to the I2C bus.
  1058. *
  1059. * Inputs: PDEV*, wCard: WORD, the card the I2C bus is on.
  1060. * cData: BYTE, the data to write
  1061. *
  1062. * Outputs: void.
  1063. *^^*/
  1064. void WriteByteI2C(PDEV* ppdev, WORD wCard, BYTE cData)
  1065. {
  1066. WORD x;
  1067. cData = ReverseByte(cData);
  1068. // Enable I2C writes
  1069. SetI2CDataDirection(ppdev, wCard, I2C_WRITE);
  1070. for (x=0; x<8; x++, cData>>=1) {
  1071. // Put data bit on I2C bus
  1072. WriteI2CData(ppdev, wCard, (BYTE) (cData&1));
  1073. I2CDelay(ppdev, wCard);
  1074. // Drive I2C clock high
  1075. WriteI2CClock(ppdev, wCard, I2C_HIGH);
  1076. I2CDelay(ppdev, wCard);
  1077. // Drive I2C clock low
  1078. WriteI2CClock(ppdev, wCard, I2C_LOW);
  1079. I2CDelay(ppdev, wCard);
  1080. }
  1081. // Clock is LOW
  1082. // Data is driven (LSB)
  1083. }
  1084. // end of WriteByteI2C
  1085. /*^^*
  1086. * Function: ReadByteI2C
  1087. *
  1088. * Purpose: To read a byte of data from the I2C bus.
  1089. *
  1090. * Inputs: none.
  1091. *
  1092. * Outputs: BYTE, the data that was read.
  1093. *^^*/
  1094. BYTE ReadByteI2C(PDEV* ppdev, WORD wCard)
  1095. {
  1096. BYTE cData = 0;
  1097. WORD x;
  1098. // Disable write on the I2C bus
  1099. SetI2CDataDirection(ppdev, wCard, I2C_READ);
  1100. for (x=0; x<8; x++) {
  1101. // Drive I2C clock high
  1102. WriteI2CClock(ppdev, wCard, I2C_HIGH);
  1103. I2CDelay(ppdev, wCard);
  1104. // Pull data bit from I2C bus
  1105. cData = (cData << 1) | (BYTE) ReadI2CData(ppdev, wCard);
  1106. // Drive I2C clock low
  1107. WriteI2CClock(ppdev, wCard, I2C_LOW);
  1108. I2CDelay(ppdev, wCard);
  1109. }
  1110. return (cData);
  1111. // Clock is LOW
  1112. // Data is tri-state
  1113. }
  1114. // end of ReadByteI2C
  1115. /*^^*
  1116. * Function: I2CDelay
  1117. *
  1118. * Purpose: To delay the accesses to the I2C bus long enough
  1119. * to ensure the correct timimg.
  1120. *
  1121. * Inputs: PDEV*, wCard: WORD the card to wait on.
  1122. *
  1123. * Outputs: none.
  1124. *^^*/
  1125. void I2CDelay(PDEV* ppdev, WORD wCard)
  1126. {
  1127. BYTE x;
  1128. // To ensure correct I2C bus timing, read a register a bunch of times.
  1129. for (x=0; x<I2C_TIME_DELAY; x++) ReadAnyReg(ppdev, wCard);
  1130. }
  1131. // end of I2CDelay
  1132. ////// End functions for I2C support
  1133. //c code for disable overlay and scaler
  1134. BOOL DisableOvl(PDEV* ppdev)
  1135. {
  1136. HLOCAL pbuff;
  1137. // just for test:
  1138. // ULONG temp;
  1139. int i;
  1140. DWORD value;
  1141. VIDEO_CAPTURE VideoCaptureDataIn, VideoCaptureDataOut;
  1142. DWORD ReturnedDataLength ;
  1143. DISPDBG( (DEBUG_ESC_1,"Enter in DisableOverlay"));
  1144. // code for context save (all the regs in block1)
  1145. if(ppdev->pal_str.dos_flag)
  1146. {
  1147. DISPDBG( (DEBUG_ESC_1,"DOS_Flag = TRUE"));
  1148. ppdev->pal_str.dos_flag=FALSE;
  1149. pbuff = AtiAllocMem(LPTR ,FL_ZERO_MEMORY,1072); // 1072 to accomodate also 6 regs from block 0
  1150. if(pbuff!=NULL)
  1151. {
  1152. ppdev->pal_str.preg=(DWORD*)pbuff;
  1153. for(i=0;i<256;i++)
  1154. {
  1155. ReadVTReg(i,(ppdev->pal_str.preg+i));
  1156. if(i<0x31)
  1157. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1158. //TempFnct(ppdev);
  1159. }
  1160. }
  1161. else
  1162. return FALSE;
  1163. }
  1164. // disable capture
  1165. WriteVTReg(TRIG_CNTL,0x0);
  1166. WriteVTReg(CAPTURE_CONFIG, 0x0);
  1167. // code for overlay and scaler disable
  1168. // fisrt the scaler
  1169. WriteVTReg(SCALER_HEIGHT_WIDTH,0x00010001);
  1170. WriteVTReg(OVERLAY_SCALE_INC, 0x10001000);
  1171. ReadVTReg(OVERLAY_SCALE_CNTL,&value);
  1172. value=value&0x7fffffff;
  1173. WriteVTReg(OVERLAY_SCALE_CNTL,value);
  1174. // the overlay
  1175. WriteVTReg(OVERLAY_Y_X,0x0);
  1176. WriteVTReg(OVERLAY_Y_X_END,0x00010001);
  1177. WriteVTReg(OVERLAY_KEY_CNTL,0x00000100);
  1178. WriteVTReg(OVERLAY_SCALE_CNTL,0x0);
  1179. // disable the settings in hardware for videocapture
  1180. VideoCaptureDataIn.dwSubFunct= 0x00000001;
  1181. VideoCaptureDataIn.dwCaptureWidth=0;
  1182. VideoCaptureDataIn.dwCaptureMode=0;
  1183. if (!AtiDeviceIoControl(ppdev->hDriver,
  1184. IOCTL_VIDEO_ATI_CAPTURE,
  1185. &VideoCaptureDataIn,
  1186. sizeof(VIDEO_CAPTURE),
  1187. &VideoCaptureDataOut,
  1188. sizeof(VIDEO_CAPTURE),
  1189. &ReturnedDataLength))
  1190. {
  1191. DISPDBG((0, "bInitializeATI - Failed IOCTL_VIDEO_ATI_CAPTURE"));
  1192. }
  1193. // save the content of the few registers used in block 0 by Palindrome
  1194. MemR32(0x1E,(ppdev->pal_str.preg+i));
  1195. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1196. i++;
  1197. MemR32(0x28,(ppdev->pal_str.preg+i));
  1198. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1199. i++;
  1200. MemR32(0x31,(ppdev->pal_str.preg+i));
  1201. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1202. i++;
  1203. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  1204. {
  1205. MemR32(0x1F,(ppdev->pal_str.preg+i));
  1206. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1207. i++;
  1208. MemR32(0x34,(ppdev->pal_str.preg+i));
  1209. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1210. i++;
  1211. #define EXCLUDE_READ
  1212. #ifndef EXCLUDE_READ
  1213. MemR32(0x07,(ppdev->pal_str.preg+i));
  1214. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1215. i++;
  1216. MemR32(0x24,(ppdev->pal_str.preg+i));
  1217. DISPDBG( (DEBUG_ESC_1,"DOS switch: reg_blk_0 0x%X = 0x%Xl ",i,(DWORD)*(ppdev->pal_str.preg+i)));
  1218. #endif
  1219. }
  1220. //#define TEST_SWITCH_1
  1221. #ifndef TEST_SWITCH_1
  1222. // disable the block 1 of registers
  1223. MemR32(0x28,&value);
  1224. MemW32(0x28,value&0xf7ffffff);
  1225. return TRUE;
  1226. #else
  1227. value;
  1228. #endif
  1229. }
  1230. //code for reinitialization of overlay after a mode switch
  1231. void EnableOvl(PDEV* ppdev)
  1232. {
  1233. int i;
  1234. DWORD value;
  1235. VIDEO_CAPTURE VideoCaptureDataIn, VideoCaptureDataOut;
  1236. DWORD ReturnedDataLength ;
  1237. DISPDBG( (DEBUG_ESC_1,"Enter in EnableOverlay"));
  1238. // enable the settings in hardware for video capture
  1239. VideoCaptureDataIn.dwSubFunct= 0x00000000;
  1240. VideoCaptureDataIn.dwCaptureWidth=0;
  1241. VideoCaptureDataIn.dwCaptureMode=0;
  1242. if (!AtiDeviceIoControl(ppdev->hDriver,
  1243. IOCTL_VIDEO_ATI_CAPTURE,
  1244. &VideoCaptureDataIn,
  1245. sizeof(VIDEO_CAPTURE),
  1246. &VideoCaptureDataOut,
  1247. sizeof(VIDEO_CAPTURE),
  1248. &ReturnedDataLength))
  1249. {
  1250. DISPDBG((0, "bInitializeATI - Failed IOCTL_VIDEO_ATI_CAPTURE"));
  1251. }
  1252. //#define TEST_SWITCH
  1253. #ifndef TEST_SWITCH
  1254. //init the VT regs in block 1 (BUS_CNTL)
  1255. MemR32(0x28,&value);
  1256. value=value|0x08000000;
  1257. MemW32(0x28,value);
  1258. // initialize some overlay/scaler regs on RAGEIII
  1259. if (ppdev->iAsic>=CI_M64_GTC_UMC)
  1260. {
  1261. WriteVTReg(0x54, 0x101000); //DD_SCALER_COLOUR_CNTL
  1262. WriteVTReg(0x55, 0x2000); //DD_SCALER_H_COEFF0
  1263. WriteVTReg(0x56, 0x0D06200D); //DD_SCALER_H_COEFF1
  1264. WriteVTReg(0x57, 0x0D0A1C0D); //DD_SCALER_H_COEFF2
  1265. WriteVTReg(0x58, 0x0C0E1A0C); //DD_SCALER_H_COEFF3
  1266. WriteVTReg(0x59, 0x0C14140C); //DD_SCALER_H_COEFF4
  1267. }
  1268. //connect video (GP_IO_CNTL)
  1269. if (ppdev->iAsic == CI_M64_GTA)
  1270. {
  1271. // Hardware bug in GTA: Black screen after writing 0x1f
  1272. DWORD local_value;
  1273. DWORD HTotal;
  1274. MemR32( 0x7 ,&local_value);
  1275. MemW32(0x7,(local_value&0xffbfffff));
  1276. MemR32(0x0,&HTotal);
  1277. MemW32(0x7,local_value);
  1278. MemW32(0x1F, 0x0);
  1279. // for fixing the above hardware bug
  1280. MemR32( 0x7 ,&local_value);
  1281. MemW32(0x7,(local_value&0xffbfffff));
  1282. MemW32(0x0,HTotal);
  1283. MemW32(0x7,local_value);
  1284. }
  1285. else
  1286. {
  1287. if((ppdev->iAsic==CI_M64_VTA)||(ppdev->iAsic==CI_M64_VTB))
  1288. MemW32(0x1F, 0x0);
  1289. }
  1290. // Enable I2C output.
  1291. WriteVT264Reg(ppdev, 0, vtf_GEN_GIO2_EN, 1);
  1292. // Disable DAC feature connector
  1293. WriteVT264Reg(ppdev, 0, vtf_DAC_FEA_CON_EN, 0);
  1294. // Enable I2C clock output pin
  1295. WriteVT264Reg(ppdev,0, vtf_DAC_GIO_DIR_1, 1);
  1296. // Set data direction of I2C bus
  1297. SetI2CDataDirection(ppdev, 0, I2C_READ);
  1298. // Set I2C Clock High
  1299. WriteI2CClock(ppdev, 0, I2C_HIGH);
  1300. I2CDelay(ppdev, 0);
  1301. #else
  1302. i;
  1303. value;
  1304. #endif
  1305. #ifndef TEST_SWITCH
  1306. if(ppdev->pal_str.preg!=NULL)
  1307. {
  1308. for(i=0;i<256;i++)
  1309. {
  1310. if(((i<0x1a)||(i>0x1e))&&(i<0x30))
  1311. {
  1312. // some registers return a different value at read in respect with write
  1313. switch(i)
  1314. {
  1315. DWORD temp;
  1316. case 0x09: //OVERLAY_SCALE_CNTL
  1317. temp= (DWORD)(*(ppdev->pal_str.preg+i))&0xfbffffff;
  1318. WriteVTReg(i,temp);
  1319. break;
  1320. case 0x14: //CAPTURE_CONFIG
  1321. temp=(DWORD)(*(ppdev->pal_str.preg+i))&0xffffffbf;
  1322. WriteVTReg(i,temp);
  1323. break;
  1324. case 0x15: //TRIG_CNTL
  1325. temp= (DWORD)(*(ppdev->pal_str.preg+i))&0xfffffff0;
  1326. WriteVTReg(i,temp);
  1327. break;
  1328. default:
  1329. WriteVTReg(i,(DWORD)(*(ppdev->pal_str.preg+i)));
  1330. }
  1331. }
  1332. }
  1333. // now restore the content of registers in block 0
  1334. value=(DWORD)(*(ppdev->pal_str.preg+i));
  1335. MemW32(0x1E, value);
  1336. i++;
  1337. MemR32(0x28,&value);
  1338. value=((value&0xf7ffffff)|( (DWORD)(*(ppdev->pal_str.preg+i))&0x08000000 ));
  1339. MemW32(0x28, value);
  1340. i++;
  1341. MemR32(0x31,&value);
  1342. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  1343. value=((value&0x80ffbfff)|( (DWORD)(*(ppdev->pal_str.preg+i))&0x3f004000 ));
  1344. else
  1345. value=((value&0xffffbfff)|( (DWORD)(*(ppdev->pal_str.preg+i))&0x00004000 ));
  1346. MemW32(0x31, value);
  1347. i++;
  1348. if ((ppdev->iAsic ==CI_M64_VTA)||(ppdev->iAsic ==CI_M64_GTA))
  1349. {
  1350. if (ppdev->iAsic == CI_M64_GTA)
  1351. {
  1352. // Hardware bug in GTA: Black screen after writing 0x1f
  1353. DWORD local_value;
  1354. DWORD HTotal;
  1355. MemR32( 0x7 ,&local_value);
  1356. MemW32(0x7,(local_value&0xffbfffff));
  1357. MemR32(0x0,&HTotal);
  1358. MemW32(0x7,local_value);
  1359. MemW32(0x1F, *(ppdev->pal_str.preg+i));
  1360. // for fixing the above hardware bug
  1361. MemR32( 0x7 ,&local_value);
  1362. MemW32(0x7,(local_value&0xffbfffff));
  1363. MemW32(0x0,HTotal);
  1364. MemW32(0x7,local_value);
  1365. }
  1366. else
  1367. {
  1368. MemW32(0x1F, *(ppdev->pal_str.preg+i));
  1369. }
  1370. i++;
  1371. MemR32(0x34,&value);
  1372. value=((value&0xffffffc2)|( (DWORD)(*(ppdev->pal_str.preg+i))&0x3d ));
  1373. MemW32(0x34, value);
  1374. i++;
  1375. #define EXCLUDE_WRITE
  1376. #ifndef EXCLUDE_WRITE
  1377. MemW32(0x07, *(ppdev->pal_str.preg+i));
  1378. i++;
  1379. MemW32(0x24, *(ppdev->pal_str.preg+i));
  1380. #endif
  1381. }
  1382. }
  1383. #endif
  1384. AtiFreeMem((HLOCAL)ppdev->pal_str.preg) ;
  1385. }
  1386. ULONG ReallocMemory(PDEV* ppdev)
  1387. {
  1388. ULONG RetVal;
  1389. OFFSCREEN OffSize; // overlay structure
  1390. OVERLAY_LOCATION Overlay; // pointer in linear memory to the begining of the overlay (top-left)
  1391. int i,j;
  1392. DWORD key_clr;
  1393. DWORD key_mask;
  1394. RetVal=1;
  1395. j=ppdev->pal_str.alloc_cnt;
  1396. ppdev->pal_str.alloc_cnt =0;
  1397. ppdev->pal_str.no_lines_allocated=0;
  1398. //set the flag for mode switch
  1399. ppdev->pal_str.Mode_Switch_flag=TRUE;
  1400. // set the colour key and mask after a mode switch
  1401. switch(ppdev->cBitsPerPel)
  1402. {
  1403. case 8:
  1404. key_clr=0xFD;
  1405. key_mask=0xFF;
  1406. break;
  1407. case 15:
  1408. key_clr=0x7C1F;
  1409. key_mask=0xFFFF;
  1410. break;
  1411. case 16:
  1412. key_clr=0xF81F;
  1413. key_mask=0xFFFF;
  1414. break;
  1415. case 24:
  1416. key_clr=0xFF00FF;
  1417. key_mask=0xFFFFFF;
  1418. break;
  1419. case 32:
  1420. key_clr=0xFF00FF; //?
  1421. key_mask=0xFFFFFF; //?
  1422. break;
  1423. }
  1424. *(ppdev->pal_str.preg+0x4)=(DWORD)key_clr;
  1425. *(ppdev->pal_str.preg+0x5)=(DWORD)key_mask;
  1426. for (i=0;i<j; i++)
  1427. {
  1428. OffSize.cx=ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].x_bits ;
  1429. OffSize.cy=ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].y_bits ;
  1430. ppdev->pal_str.Realloc_mem_flag=TRUE;
  1431. RetVal=AllocOffscreenMem(ppdev, &OffSize, &Overlay);
  1432. if(RetVal==ESC_ALLOC_FAIL)
  1433. {
  1434. ppdev->pal_str.alloc_cnt=j;
  1435. RetVal=0;
  1436. return RetVal;
  1437. }
  1438. if(i==0) //update the buffer registers with the new values
  1439. {
  1440. // save the offset value in the ppdev->pal_str
  1441. ppdev->pal_str.Buf0_Offset =(DWORD)(Overlay.app_offset);
  1442. //set CAPTURE_BUF0_OFFSET
  1443. *(ppdev->pal_str.preg+0x20)=(DWORD)(Overlay.app_offset);
  1444. if ((ppdev->iAsic ==CI_M64_VTB)||(ppdev->iAsic >=CI_M64_GTB))
  1445. {
  1446. //set the SCALER_BUF0_OFFSET
  1447. *(ppdev->pal_str.preg+0x0e)=(DWORD)(Overlay.app_offset);
  1448. //set ONESHOT_BUFF_OFFSET
  1449. *(ppdev->pal_str.preg+0x22)=(DWORD)(Overlay.app_offset);
  1450. }
  1451. else
  1452. { //GTA or VTA
  1453. *(ppdev->pal_str.preg+0x26)=(DWORD)(Overlay.app_offset);
  1454. *(ppdev->pal_str.preg+0x2B)=(DWORD)(Overlay.app_offset);
  1455. *(ppdev->pal_str.preg+0x2C)=(DWORD)(Overlay.app_offset);
  1456. }
  1457. }
  1458. #if 0 // for the moment we are not using double buffering at this moment
  1459. if(i==1)
  1460. {
  1461. //set the SCALER_BUF1_OFFSET
  1462. *(ppdev->pal_str.preg+0xe)=(DWORD)(Overlay.app_offset);
  1463. //set CAPTURE_BUF1_OFFSET
  1464. *(ppdev->pal_str.preg+0x21)=(DWORD)(Overlay.app_offset);
  1465. }
  1466. #endif
  1467. }
  1468. RetVal=1;
  1469. return RetVal;
  1470. }
  1471. ULONG AllocOffscreenMem(PDEV* ppdev, PVOID pvIn, PVOID pvOut)
  1472. {
  1473. //OFFSCREEN OffSize;
  1474. OFFSCREEN* pOffSize; // pointer to the offscreen area size for overlay structure
  1475. OVERLAY_LOCATION* pOverlay; // pointer in linear memory to the begining of the overlay (top-left)
  1476. LONG x_size;
  1477. LONG y_size;
  1478. LONG x_size_orig; // for history purposes
  1479. LONG y_size_orig; // for history purposes
  1480. LONG x_bits; // for history purposes
  1481. LONG y_bits; // for history purposes
  1482. int temp_alloc_lines_cnt;
  1483. ULONG RetVal;
  1484. // If LINEAR is defined then we allocate the memory for the buffer as a contiguous zone (no as a rectangle). This will imply
  1485. // that the BUFF PITCH = width of the capture (for rectangle approach the pitch can be equal with the screen pitch)
  1486. #define LINEAR
  1487. #ifdef LINEAR
  1488. POINTL req;
  1489. #endif
  1490. DISPDBG( (DEBUG_ESC_2,"PAL : AllocOffscreenMem "));
  1491. //DebugBreak() ;
  1492. //NEW APPROACH FOR MEM MANAGEMENT
  1493. // If LINEAR is defined then we allocate the memory for the buffer as a contiguous zone (no as a rectangle). This will imply
  1494. // that the BUFF PITCH = width of the capture (for rectangle approach the pitch can be equal with the screen pitch)
  1495. #ifndef LINEAR
  1496. //allocate memory for the overlay
  1497. pOffSize=(OFFSCREEN*)pvIn;
  1498. //the size is assumed to be in bits
  1499. //we add 64 for alingment provision
  1500. if((ULONG)(pOffSize->cx)<=(ULONG)((ppdev->cxScreen)-64l))
  1501. {
  1502. x_size=(((pOffSize->cx)+63)&(0xfffffffc))/(ppdev->cBitsPerPel);
  1503. }
  1504. else
  1505. {
  1506. //since the maximum width for source is 384 pixels is very improbable that "else" case will be hit
  1507. x_size=(pOffSize->cx)/(ppdev->cBitsPerPel);
  1508. }
  1509. y_size=(pOffSize->cy);
  1510. DISPDBG( (DEBUG_ESC_2," Rectangular allocation : x=%u (RGB pels) y=%u (no of lines)", x_size, y_size));
  1511. (ppdev->pal_str.poh)=NULL;
  1512. // the following statement is for the new architecture for display driver
  1513. pohAllocate(ppdev, NULL, x_size, y_size, FLOH_MAKE_PERMANENT);
  1514. #else
  1515. // linear allocation
  1516. #if TARGET_BUILD > 351
  1517. // first thing, dealloc Heap allocated by DDraw
  1518. if(ppdev->pohDirectDraw!=NULL)
  1519. {
  1520. pohFree(ppdev, ppdev->pohDirectDraw);
  1521. ppdev->pohDirectDraw = NULL;
  1522. }
  1523. #endif
  1524. pOffSize=(OFFSCREEN*)pvIn;
  1525. //the size is assumed to be in bits of RGB pixels at the current resolution
  1526. //(the palindrome is making the conversion: RGB pixels=UYV pixels*16/ current bpp )
  1527. //x_size=(pOffSize->cx)/(ppdev->cBitsPerPel); // now we have pixels (this was introduced because in the palindrome code we have made width=width*16)
  1528. x_size=(pOffSize->cx);
  1529. y_size=(pOffSize->cy);
  1530. x_size_orig=((pOffSize->cx)*16)/(ppdev->cBitsPerPel);
  1531. y_size_orig=(pOffSize->cy);
  1532. if(ppdev->pal_str.Realloc_mem_flag==TRUE)
  1533. {
  1534. x_bits= (pOffSize->cx);
  1535. y_bits= (pOffSize->cy);
  1536. }
  1537. else
  1538. {
  1539. x_bits=(pOffSize->cx)*(ppdev->cBitsPerPel);
  1540. y_bits= (pOffSize->cy);
  1541. }
  1542. // First we will see if it's a real allocation or , if the x,y_size=0, it's a deallocation of the last surface allocated
  1543. if((x_size==0)||(y_size==0))
  1544. {
  1545. if(ppdev->pal_str.No_mem_allocated_flag==TRUE)
  1546. {
  1547. RetVal=ESC_IS_SUPPORTED;
  1548. // in build 1358 we have problems if we return ESC_ALLOC_FAIL
  1549. //RetVal=ESC_ALLOC_FAIL;
  1550. DISPDBG( (DEBUG_ESC_2,"Offscreen memory deallocation failed: ppdev->pal_str.poh==NULL "));
  1551. DISPDBG( (DEBUG_ESC_2," "));
  1552. return (RetVal);
  1553. }
  1554. if(ppdev->pal_str.poh==NULL)
  1555. {
  1556. RetVal=ESC_IS_SUPPORTED;
  1557. // in build 1358 we have problems if we return ESC_ALLOC_FAIL
  1558. //RetVal=ESC_ALLOC_FAIL;
  1559. DISPDBG( (DEBUG_ESC_2,"Offscreen memory deallocation failed: ppdev->pal_str.poh==NULL "));
  1560. DISPDBG( (DEBUG_ESC_2," "));
  1561. return (RetVal);
  1562. }
  1563. //Debug info about OH
  1564. DISPDBG( (DEBUG_ESC_2," Memory deallocation (0,0 params) for the surface starting at x=%d, y=%d; width=%d, heigth=%d", ppdev->pal_str.poh->x, \
  1565. ppdev->pal_str.poh->y, ppdev->pal_str.poh->cx, ppdev->pal_str.poh->cy));
  1566. DISPDBG( (DEBUG_ESC_2," Status of allocation:"));
  1567. switch(ppdev->pal_str.poh->ohState)
  1568. {
  1569. case 0:
  1570. DISPDBG( (DEBUG_ESC_2," OH_FREE"));
  1571. break;
  1572. case 1:
  1573. DISPDBG( (DEBUG_ESC_2," OH_DISCARDABLE"));
  1574. break;
  1575. case 2:
  1576. DISPDBG( (DEBUG_ESC_2," OH_PERMANENT"));
  1577. break;
  1578. default:
  1579. DISPDBG( (DEBUG_ESC_2," Unknown status!!"));
  1580. }
  1581. // end debug info
  1582. // deallocation of the last poh
  1583. pohFree(ppdev,(ppdev->pal_str.poh));
  1584. #ifndef ALLOC_RECT_ANYWHERE
  1585. //decrement the no. of allocated lines with the no. of lines alocated lately
  1586. ppdev->pal_str.no_lines_allocated-=ppdev->pal_str.alloc_hist[(ppdev->pal_str.alloc_cnt)-1].y_lines;
  1587. #endif
  1588. // decrement the allocation counter
  1589. ppdev->pal_str.alloc_cnt--;
  1590. // NULL the pointer to poh
  1591. ppdev->pal_str.poh=NULL;
  1592. // set the overlay_offset to 0
  1593. pOverlay=(OVERLAY_LOCATION*)pvOut;//&overlay_xy;
  1594. pOverlay->app_offset=0L;
  1595. // exit and return OK
  1596. DISPDBG( (DEBUG_ESC_2,"Offscreen memory deallocation OK "));
  1597. DISPDBG( (DEBUG_ESC_2," "));
  1598. RetVal=ESC_IS_SUPPORTED;
  1599. return (RetVal);
  1600. }
  1601. // compute the total pixels
  1602. if(ppdev->pal_str.Realloc_mem_flag==TRUE)
  1603. {
  1604. // if we are reallocating memory due to mode switch, see how much
  1605. x_size=(x_size*y_size)/(ppdev->cBitsPerPel) +1;
  1606. ppdev->pal_str.Realloc_mem_flag=FALSE;
  1607. }
  1608. else
  1609. {
  1610. x_size=x_size*y_size;
  1611. }
  1612. // how big is y if we'll use as x the total screen width (except in 800x600 in 8bpp, where cxMemory=832 and we have some problems)
  1613. #ifdef BUG_800x600_8BPP
  1614. //800x600 8bpp bug
  1615. if(ppdev->cxMemory==832)
  1616. y_size=(x_size/ppdev->cxScreen)+1;
  1617. else
  1618. #endif
  1619. y_size=(x_size/ppdev->cxMemory)+1;
  1620. DISPDBG( (DEBUG_ESC_2," Linear allocation: x=%u (total x*y in RGB pixels) y=%u (lines at current resolution)",x_size, y_size));
  1621. (ppdev->pal_str.poh)=NULL;
  1622. // we want the allocation starting here:
  1623. req.x=0;
  1624. req.y=ppdev->cyScreen + 10 + ppdev->pal_str.no_lines_allocated; //10 lines after the ending of visible screen + no. of lines already allocated before by this fnct.
  1625. DISPDBG( (DEBUG_ESC_2," Visible memory width: x=%u Visible memory height y=%u ",ppdev->cxScreen ,ppdev->cyScreen));
  1626. DISPDBG( (DEBUG_ESC_2," Total Memory width: x=%u Total Memory height y=%u Bpp= %u",ppdev->cxMemory ,ppdev->cyMemory, ppdev->cBitsPerPel));
  1627. DISPDBG( (DEBUG_ESC_2,"Parameters for poh alloc : address x=%u y=%u \n x_dim=%u y_dim=%u ",req.x,req.y,ppdev->cxMemory, y_size));
  1628. // move everything to system memory (this function is absolutely necessary)
  1629. if(!bMoveAllDfbsFromOffscreenToDibs(ppdev))
  1630. {
  1631. DISPDBG( (DEBUG_ESC_2,"bMoveAllDfbsFromOffscreenToDibs failed "));
  1632. }
  1633. //the actual allocation fnct.
  1634. #ifdef BUG_800x600_8BPP
  1635. //800x600 8bpp bug
  1636. if(ppdev->cxMemory==832)
  1637. {
  1638. #ifndef ALLOC_RECT_ANYWHERE
  1639. (ppdev->pal_str.poh)=pohAllocate(ppdev,&req,ppdev->cxScreen,y_size, FLOH_MAKE_PERMANENT);
  1640. #else
  1641. (ppdev->pal_str.poh)=pohAllocate(ppdev,NULL,ppdev->cxScreen,y_size, FLOH_MAKE_PERMANENT);
  1642. #endif
  1643. }
  1644. else
  1645. #endif
  1646. {
  1647. #ifndef ALLOC_RECT_ANYWHERE
  1648. (ppdev->pal_str.poh)=pohAllocate(ppdev,&req,ppdev->cxMemory,y_size, FLOH_MAKE_PERMANENT);
  1649. #else
  1650. (ppdev->pal_str.poh)=pohAllocate(ppdev,NULL,ppdev->cxMemory,y_size, FLOH_MAKE_PERMANENT);
  1651. #endif
  1652. }
  1653. if(ppdev->pal_str.poh==NULL)
  1654. {
  1655. #ifndef ALLOC_RECT_ANYWHERE //jump over loop
  1656. DISPDBG( (DEBUG_ESC_2," Loop for detecting free heap zone"));
  1657. // use a counter for eventually allocated lines
  1658. temp_alloc_lines_cnt=0;
  1659. do
  1660. {
  1661. #ifndef ALLOC_RECT_ANYWHERE
  1662. temp_alloc_lines_cnt++;
  1663. ppdev->pal_str.no_lines_allocated+=1;
  1664. req.y=ppdev->cyScreen + 10 + ppdev->pal_str.no_lines_allocated;
  1665. #endif
  1666. #ifdef BUG_800x600_8BPP
  1667. //800x600 8bpp bug
  1668. if(ppdev->cxMemory==832)
  1669. {
  1670. #ifndef ALLOC_RECT_ANYWHERE
  1671. (ppdev->pal_str.poh)=pohAllocate(ppdev,&req,ppdev->cxScreen,y_size, FLOH_MAKE_PERMANENT);
  1672. #else
  1673. (ppdev->pal_str.poh)=pohAllocate(ppdev,NULL,ppdev->cxScreen,y_size, FLOH_MAKE_PERMANENT);
  1674. #endif
  1675. }
  1676. else
  1677. #endif
  1678. {
  1679. #ifndef ALLOC_RECT_ANYWHERE
  1680. (ppdev->pal_str.poh)=pohAllocate(ppdev,&req,ppdev->cxMemory,y_size, FLOH_MAKE_PERMANENT);
  1681. #else
  1682. (ppdev->pal_str.poh)=pohAllocate(ppdev,NULL,ppdev->cxMemory,y_size, FLOH_MAKE_PERMANENT);
  1683. #endif
  1684. }
  1685. }
  1686. while(((ppdev->pal_str.poh)==NULL)&&(req.y<((ppdev->cyMemory)-y_size))) ;
  1687. #endif // jump over loop
  1688. if((req.y>=((ppdev->cyMemory)-y_size)))
  1689. {
  1690. ppdev->pal_str.poh=NULL;
  1691. ppdev->pal_str.no_lines_allocated=ppdev->pal_str.no_lines_allocated - temp_alloc_lines_cnt;
  1692. DISPDBG( (DEBUG_ESC_2," End loop. Not enough space in off-screen memory"));
  1693. }
  1694. else
  1695. DISPDBG( (DEBUG_ESC_2," End loop. The free zone starts at %u line",req.y));
  1696. }
  1697. #endif
  1698. DISPDBG( (DEBUG_ESC_2," allocation initialy requested (by ESC call): x=%u (in bits) y=%u (in lines)",pOffSize->cx,pOffSize->cy));
  1699. if((ppdev->pal_str.poh)==NULL)
  1700. {
  1701. RetVal=ESC_ALLOC_FAIL;
  1702. //initialize de pointer
  1703. #if 0
  1704. pOverlay=(OVERLAY_LOCATION*)pvOut;
  1705. pOverlay->app_offset= 0L;
  1706. #endif
  1707. DISPDBG( (DEBUG_ESC_2,"Offscreen memory allocation failed "));
  1708. DISPDBG( (DEBUG_ESC_2," "));
  1709. return (RetVal);
  1710. }
  1711. // save info about alloc
  1712. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].x=x_size_orig; //ppdev->cxMemory;
  1713. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].y=y_size_orig;
  1714. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].y_lines=y_size; // no of lines allocated at current memory width
  1715. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh=ppdev->pal_str.poh;
  1716. ppdev->pal_str.no_lines_allocated+=y_size; // total no of lines already allocated at this moment
  1717. // two new fields for 4.0 because the colour depth can be changed on the fly, and we need the original dimensions in bits
  1718. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].x_bits= x_bits;
  1719. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].y_bits= y_bits;
  1720. //Debug info about OH
  1721. DISPDBG( (DEBUG_ESC_2," Memory allocation for the surface starting at x=%d, y=%d; width=%d, heigth=%d", ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->x, \
  1722. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->y, ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->cx, ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->cy));
  1723. DISPDBG( (DEBUG_ESC_2," Status of allocation:"));
  1724. switch(ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->ohState)
  1725. {
  1726. case 0:
  1727. DISPDBG( (DEBUG_ESC_2," OH_FREE"));
  1728. break;
  1729. case 1:
  1730. DISPDBG( (DEBUG_ESC_2," OH_DISCARDABLE"));
  1731. break;
  1732. case 2:
  1733. DISPDBG( (DEBUG_ESC_2," OH_PERMANENT"));
  1734. break;
  1735. default:
  1736. DISPDBG( (DEBUG_ESC_2," Unknown status!!"));
  1737. }
  1738. // end debug info
  1739. // increment the alloc counter
  1740. ppdev->pal_str.alloc_cnt++;
  1741. //send back the info about where the allocated memory is
  1742. //initialize de pointer
  1743. pOverlay=(OVERLAY_LOCATION*)pvOut;//&overlay_xy;
  1744. //compute the location for the off_screen memory enforcing the alingment at 64 bits
  1745. // I abandoned this approach in the new stream code for the display driver
  1746. pOverlay->app_offset=(ULONG)((ppdev->pal_str.poh->y*ppdev->lDelta) +(ppdev->pal_str.poh->x*ppdev->cjPelSize) ) &(ULONG)(0x0fffffff8);
  1747. DISPDBG( (DEBUG_ESC_2," Memory allocation OK at 0x%lX, no. of lines totally allocated %u", pOverlay->app_offset, ppdev->pal_str.no_lines_allocated));
  1748. DISPDBG( (DEBUG_ESC_2," "));
  1749. RetVal=ESC_IS_SUPPORTED;
  1750. return (RetVal);
  1751. }
  1752. ULONG DeallocOffscreenMem(PDEV* ppdev)
  1753. {
  1754. ULONG RetVal;
  1755. int i;
  1756. // support for off-screen memory management for PALINDROME
  1757. // function for deallocation of off-screen memory used by the overlay
  1758. //Seems that we don't need to keep a record with the allocated poh because all of them will be erased in bulk
  1759. // {see ddthunk.c in the original palindrome code)
  1760. //relase all the allocated off_screen space
  1761. DISPDBG( (DEBUG_ESC_2," Memory deallocation for %u surfaces in offscreen mem", ppdev->pal_str.alloc_cnt));
  1762. DISPDBG( (DEBUG_ESC_2," "));
  1763. if(ppdev->pal_str.No_mem_allocated_flag==FALSE)
  1764. {
  1765. for(i=0;i<ppdev->pal_str.alloc_cnt; i++ )
  1766. {
  1767. //debug info
  1768. DISPDBG( (DEBUG_ESC_2," Memory deallocation for the surface starting at x=%d, y=%d; width=%d, heigth=%d", ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->x, \
  1769. ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->y, ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->cx, ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->cy));
  1770. DISPDBG( (DEBUG_ESC_2," Status of allocation:"));
  1771. switch(ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->ohState)
  1772. {
  1773. case 0:
  1774. DISPDBG( (DEBUG_ESC_2," OH_FREE"));
  1775. break;
  1776. case 1:
  1777. DISPDBG( (DEBUG_ESC_2," OH_DISCARDABLE"));
  1778. break;
  1779. case 2:
  1780. DISPDBG( (DEBUG_ESC_2," OH_PERMANENT"));
  1781. break;
  1782. default:
  1783. DISPDBG( (DEBUG_ESC_2," Unknown status!!"));
  1784. }
  1785. // end debug info
  1786. // deallocate only if the poh is valid
  1787. if((ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->x>ppdev->cxScreen) &&(ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->x<ppdev->cxMemory) \
  1788. &&(ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->y>ppdev->cyScreen)&&(ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh->y<ppdev->cyMemory) )
  1789. {
  1790. pohFree(ppdev,(ppdev->pal_str.alloc_hist[ppdev->pal_str.alloc_cnt].poh));
  1791. }
  1792. else
  1793. {
  1794. DISPDBG( (DEBUG_ESC_2," Unvalid poh for DeAllocation"));
  1795. }
  1796. }
  1797. }
  1798. else
  1799. {
  1800. // reset the flag if it was TRUE
  1801. ppdev->pal_str.No_mem_allocated_flag=FALSE;
  1802. }
  1803. // reset the alloc counter
  1804. ppdev->pal_str.alloc_cnt=0;
  1805. ppdev->pal_str.no_lines_allocated=0;
  1806. ppdev->pal_str.poh=NULL;
  1807. RetVal=ESC_IS_SUPPORTED;
  1808. return (RetVal);
  1809. }
  1810. /*^^*
  1811. * Function: WriteVT264Reg
  1812. *
  1813. * Purpose: To write to a VT register.
  1814. *
  1815. * Inputs: PPDEV*, wCard: WORD, the card to write to
  1816. * bField: BYTE, the field to write to.
  1817. * dwData: DWORD, The data to write.
  1818. *
  1819. * Outputs: void.
  1820. */
  1821. void WriteVT264Reg(PDEV* ppdev, WORD wCard, BYTE bField, DWORD dwData )
  1822. {
  1823. DWORD dwMask;
  1824. DWORD dwRegValue;
  1825. DWORD dwRegOff;
  1826. BYTE bShift;
  1827. switch(bField) {
  1828. case vtf_GP_IO_4:
  1829. bShift = 4;
  1830. dwMask = 0xffffffef;
  1831. dwRegOff = 0x1e;
  1832. break;
  1833. case vtf_GP_IO_DIR_4:
  1834. bShift = 20;
  1835. dwMask = 0xffefffff;
  1836. dwRegOff = 0x1e;
  1837. break;
  1838. case vtf_GP_IO_7:
  1839. bShift = 7;
  1840. dwMask = 0xffffff7f;
  1841. dwRegOff = 0x1e;
  1842. break;
  1843. case vtf_GP_IO_B:
  1844. bShift = 11;
  1845. dwMask = 0xfffff7ff;
  1846. dwRegOff = 0x1e;
  1847. break;
  1848. case vtf_GP_IO_DIR_B:
  1849. bShift = 27;
  1850. dwMask = 0xf7ffffff;
  1851. dwRegOff = 0x1e;
  1852. break;
  1853. case vtf_GEN_GIO2_DATA_OUT:
  1854. dwMask = 0xfffffffe;
  1855. bShift = 0;
  1856. dwRegOff = 52;
  1857. break;
  1858. case vtf_GEN_GIO2_WRITE:
  1859. bShift = 5;
  1860. dwMask = 0xffffffdf;
  1861. dwRegOff = 52;
  1862. break;
  1863. case vtf_GEN_GIO3_DATA_OUT:
  1864. bShift = 2;
  1865. dwMask = 0xfffffffb;
  1866. dwRegOff = 52;
  1867. break;
  1868. case vtf_GEN_GIO2_EN:
  1869. bShift = 4;
  1870. dwMask = 0xffffffef;
  1871. dwRegOff = 52;
  1872. break;
  1873. case vtf_DAC_GIO_STATE_1:
  1874. bShift = 24;
  1875. dwMask = 0xfeffffff;
  1876. dwRegOff = 49;
  1877. break;
  1878. case vtf_DAC_FEA_CON_EN:
  1879. bShift = 14;
  1880. dwMask = 0xffffbfff;
  1881. dwRegOff = 49;
  1882. break;
  1883. case vtf_DAC_GIO_DIR_1:
  1884. bShift = 27;
  1885. dwMask = 0xf7ffffff;
  1886. dwRegOff = 49;
  1887. break;
  1888. }
  1889. dwData = dwData << bShift;
  1890. MemR32(dwRegOff,&dwRegValue);
  1891. dwRegValue &= dwMask;
  1892. dwRegValue |= dwData;
  1893. MemW32(dwRegOff,dwRegValue);
  1894. }
  1895. // end of WriteVT264Reg
  1896. /*^^*
  1897. * Function: ReadVT264Reg
  1898. *
  1899. * Purpose: To read a register on the VT
  1900. *
  1901. * Inputs: PPDEV*, wCard: WORD, the card to read from.
  1902. * bField: BYTE, the field to read.
  1903. *
  1904. * Outputs: DWORD, the value read.
  1905. *^^*/
  1906. DWORD ReadVT264Reg(PDEV* ppdev, WORD wCard, BYTE bField )
  1907. {
  1908. DWORD dwMask;
  1909. DWORD dwRegOff;
  1910. DWORD dwRegValue;
  1911. DWORD dwFldValue;
  1912. BYTE bShift;
  1913. switch(bField) {
  1914. case vtf_GEN_GIO2_DATA_IN:
  1915. bShift = 3;
  1916. dwMask = 0x00000008;
  1917. dwRegOff = 52;
  1918. break;
  1919. case vtf_CFG_CHIP_FND_ID:
  1920. bShift = 27;
  1921. dwMask = 0x38000000;
  1922. dwRegOff = 56;
  1923. break;
  1924. case vtf_CFG_CHIP_MAJOR:
  1925. bShift = 24;
  1926. dwMask = 0x03000000;
  1927. dwRegOff = 0x38;
  1928. break;
  1929. case vtf_GP_IO_4:
  1930. bShift = 4;
  1931. dwMask = 0x00000010;
  1932. dwRegOff = 0x1e;
  1933. break;
  1934. }
  1935. MemR32(dwRegOff,&dwRegValue);
  1936. dwFldValue = dwRegValue & dwMask;
  1937. dwFldValue = dwFldValue >> bShift;
  1938. return(dwFldValue);
  1939. }
  1940. // end of ReadVT264Reg
  1941. VOID DbgExtRegsDump(PDEV* ppdev)
  1942. {
  1943. DWORD value;
  1944. int i;
  1945. for(i=0;i<256;i++)
  1946. {
  1947. ReadVTReg(i,&value);
  1948. DISPDBG( (DEBUG_DUMP,"ExtRegs: reg 0x%X = 0x%Xl ",i,value));
  1949. TempFnct(ppdev);
  1950. }
  1951. }
  1952. VOID TempFnct(PDEV* ppdev)
  1953. {
  1954. int i;
  1955. for (i=0;i<800;i++)
  1956. {
  1957. ReadVT264Reg(ppdev, 0, vtf_CFG_CHIP_FND_ID);
  1958. }
  1959. }
  1960. VOID DeallocDirectDraw(PDEV* ppdev)
  1961. {
  1962. #if TARGET_BUILD > 351
  1963. if(ppdev->pohDirectDraw!=NULL)
  1964. {
  1965. pohFree(ppdev, ppdev->pohDirectDraw);
  1966. ppdev->pohDirectDraw = NULL;
  1967. }
  1968. #endif
  1969. }
  1970. VOID ResetPalindrome(
  1971. PDEV* ppdevOld,
  1972. PDEV* ppdevNew)
  1973. {
  1974. ULONG RetVal;
  1975. // save the pal structure in the new ppdev
  1976. ppdevNew->pal_str=ppdevOld->pal_str;
  1977. if((ppdevNew->pal_str.dos_flag==TRUE)&&(ppdevNew->pal_str.Palindrome_flag==TRUE))
  1978. {
  1979. RetVal=0;
  1980. #if 1 // do not disable the following debug statements, they solve a bug
  1981. DISPDBG( (DEBUG_DUMP,"The content of the Extended Registers after DrvResetPDEV"));
  1982. DbgExtRegsDump(ppdevNew);
  1983. #endif
  1984. #ifdef DYNAMIC_REZ_AND_COLOUR_CHANGE // palindrome support for on the fly rez and colour depth
  1985. #define ALWAYS_REALLOC_MEM //always realloc memory for buffers after mode switch or exiting DOS with ALT+ENTER
  1986. #endif
  1987. #ifndef ALWAYS_REALLOC_MEM
  1988. //see if we are exiting DOS full screen with ALT+ENTER or is a mode switch
  1989. if((ppdevNew->cBitsPerPel!=ppdevOld->cBitsPerPel)||(ppdevNew->cxScreen!=ppdevOld->cxScreen)||(ppdevNew->cyScreen!=ppdevOld->cyScreen))
  1990. {
  1991. // mode switch
  1992. #if 0 //no more scaler and overlay after a mode switch
  1993. RetVal=ReallocMemory(ppdevNew);
  1994. #endif
  1995. RetVal=0;
  1996. }
  1997. else
  1998. {
  1999. // exit dos full screen mode by ALT+ENTER
  2000. bAssertModeOffscreenHeap(ppdevNew, FALSE);
  2001. DeallocDirectDraw(ppdevNew);
  2002. RetVal=ReallocMemory(ppdevNew);
  2003. }
  2004. #else
  2005. bAssertModeOffscreenHeap(ppdevNew, FALSE); //not necessary
  2006. DeallocDirectDraw(ppdevNew); // not necessary
  2007. RetVal=ReallocMemory(ppdevNew);
  2008. #endif
  2009. if(RetVal==1)
  2010. {
  2011. vM64QuietDown(ppdevNew, ppdevNew->pjMmBase);
  2012. EnableOvl(ppdevNew);
  2013. ppdevNew->pal_str.dos_flag=FALSE;
  2014. ppdevNew->pal_str.No_mem_allocated_flag=FALSE;
  2015. vM64QuietDown(ppdevNew, ppdevNew->pjMmBase);
  2016. #if 1
  2017. DISPDBG( (DEBUG_DUMP,"The content of the Extended Registers after DrvResetPDEV"));
  2018. DbgExtRegsDump(ppdevNew);
  2019. #endif
  2020. }
  2021. else
  2022. {
  2023. ppdevNew->pal_str.Mode_Switch_flag=FALSE;
  2024. ppdevNew->pal_str.dos_flag=FALSE;
  2025. ppdevNew->pal_str.No_mem_allocated_flag=TRUE;
  2026. // disable mem allocation in pal structure
  2027. ppdevNew->pal_str.no_lines_allocated=0;
  2028. ppdevNew->pal_str.alloc_cnt=0;
  2029. ppdevNew->pal_str.poh=NULL;
  2030. }
  2031. }
  2032. }
  2033. // end of functions for palindrome support
  2034. #endif