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.

356 lines
9.7 KiB

  1. //***************************************************************************
  2. // Interrupt process
  3. //
  4. //***************************************************************************
  5. #include "common.h"
  6. #include "regs.h"
  7. #include "dvdcmd.h"
  8. #include "debug.h"
  9. void HwIntDMA( PHW_DEVICE_EXTENSION pHwDevExt, UCHAR val );
  10. void HwIntVideo( PHW_DEVICE_EXTENSION pHwDevExt );
  11. void HwIntVSync( PHW_DEVICE_EXTENSION pHwDevExt );
  12. //void SeemlessProc( PHW_DEVICE_EXTENSION pHwDevExt );
  13. extern void USCC_get( PHW_DEVICE_EXTENSION pHwDevExt );
  14. extern void USCC_put( PHW_DEVICE_EXTENSION pHwDevExt );
  15. /*
  16. ** HwInterrupt()
  17. */
  18. extern "C" BOOLEAN STREAMAPI HwInterrupt( IN PHW_DEVICE_EXTENSION pHwDevExt )
  19. {
  20. UCHAR val;
  21. // UCHAR savedata[7];
  22. BOOLEAN fInterrupt = TRUE;
  23. // savedata[0] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA1 );
  24. // savedata[1] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA2 );
  25. // savedata[2] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA3 );
  26. // savedata[3] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA4 );
  27. // savedata[4] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA5 );
  28. // savedata[5] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA6 );
  29. // savedata[6] = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA7 );
  30. val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_INTF );
  31. // DebugPrint( (DebugLevelVerbose, "TOSDVD:HwInterrupt 0x%x\r\n", (DWORD)val ) );
  32. if( val & 0x03 ) {
  33. HwIntDMA( pHwDevExt, (UCHAR)(val & 0x03) );
  34. }
  35. else if( val & 0x08 ) {
  36. HwIntVideo( pHwDevExt );
  37. }
  38. else if( val & 0x10 ) {
  39. HwIntVSync( pHwDevExt );
  40. }
  41. else if( val != 0 ) {
  42. DebugPrint( (DebugLevelTrace, "TOSDVD:Interrupt! Not impliment\r\n") );
  43. TRAP;
  44. }
  45. else {
  46. // Removed by serges because this was happening an awful lot, possibly
  47. // hurting performance.
  48. // DebugPrint( (DebugLevelTrace, "TOSDVD:Other Board Interrupt ??\r\n") );
  49. // TRAP;
  50. fInterrupt = FALSE;
  51. }
  52. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA7, savedata[6] );
  53. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA6, savedata[5] );
  54. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA5, savedata[4] );
  55. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA4, savedata[3] );
  56. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA3, savedata[2] );
  57. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA2, savedata[1] );
  58. // WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_DATA1, savedata[0] );
  59. return( fInterrupt );
  60. }
  61. void HwIntDMA( PHW_DEVICE_EXTENSION pHwDevExt, UCHAR val )
  62. {
  63. if( pHwDevExt->bKeyDataXfer ) {
  64. if( val & 0x01 )
  65. WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_INTF, 0x01 );
  66. else
  67. TRAP;
  68. pHwDevExt->pfnEndKeyData( pHwDevExt );
  69. return;
  70. }
  71. if( val & 0x01 ) {
  72. WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_INTF, 0x01 );
  73. if( pHwDevExt->pSrbDMA0 == NULL ) {
  74. DebugPrint( (DebugLevelTrace, "TOSDVD: Bad Status! DMA0 HwIntDMA\r\n") );
  75. // TRAP;
  76. return;
  77. }
  78. // error check for debug
  79. {
  80. UCHAR val;
  81. val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_CNTL );
  82. if( val & 0x01 ) {
  83. DebugPrint(( DebugLevelTrace, "TOSDVD: Bad Irq? DMA0\r\n" ));
  84. return;
  85. }
  86. }
  87. // DebugDumpWriteData( pHwDevExt->pSrbDMA0 );
  88. // if( pHwDevExt->lSeemVBuff != 0 ) {
  89. // pHwDevExt->lSeemVBuff -= 2048; // Bad Value!!
  90. // if( pHwDevExt->lSeemVBuff < 0 ) {
  91. // pHwDevExt->lSeemVBuff = 0;
  92. // SeemlessProc( pHwDevExt );
  93. // }
  94. // }
  95. if( pHwDevExt->fSrbDMA0last ) {
  96. DebugPrint(( DebugLevelVerbose, "TOSDVD:HWInt SrbDMA0 0x%x\r\n", pHwDevExt->pSrbDMA0 ) );
  97. // must fix!
  98. // other place that call StreamRequestComplete() does not clear pHwDevExt->bEndCpp;
  99. if( ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA0->SRBExtension))->pfnEndSrb ) {
  100. DebugPrint(( DebugLevelTrace, "TOSDVD:exist pfnEndSrb(HWint0) srb = 0x%x\r\n", pHwDevExt->pSrbDMA0 ));
  101. if( pHwDevExt->pSrbDMA0 == pHwDevExt->pSrbDMA1 || pHwDevExt->pSrbDMA1 == NULL ) {
  102. DebugPrint(( DebugLevelTrace, "TOSDVD:Call TimerCppReset(HWint0)\r\n" ));
  103. StreamClassScheduleTimer(
  104. NULL,
  105. pHwDevExt,
  106. // BUG - must fix
  107. // need wait underflow?
  108. 500000,
  109. ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA0->SRBExtension))->pfnEndSrb,
  110. ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA0->SRBExtension))->parmSrb
  111. );
  112. }
  113. }
  114. pHwDevExt->pSrbDMA0->Status = STATUS_SUCCESS;
  115. StreamClassStreamNotification( StreamRequestComplete,
  116. pHwDevExt->pSrbDMA0->StreamObject,
  117. pHwDevExt->pSrbDMA0 );
  118. }
  119. // Next DMA
  120. pHwDevExt->pSrbDMA0 = NULL;
  121. pHwDevExt->fSrbDMA0last = FALSE;
  122. }
  123. if( val & 0x02 ) {
  124. WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_INTF, 0x02 );
  125. if( pHwDevExt->pSrbDMA1 == NULL ) {
  126. DebugPrint( (DebugLevelTrace, "TOSDVD: Bad Status! DMA1 HwIntDMA\r\n") );
  127. // TRAP;
  128. return;
  129. }
  130. // error check for debug
  131. {
  132. UCHAR val;
  133. val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_CNTL );
  134. if( val & 0x02 ) {
  135. DebugPrint(( DebugLevelTrace, "TOSDVD: Bad Irq? DMA1\r\n" ));
  136. return;
  137. }
  138. }
  139. // DebugDumpWriteData( pHwDevExt->pSrbDMA1 );
  140. // if( pHwDevExt->lSeemVBuff != 0 ) {
  141. // pHwDevExt->lSeemVBuff -= 2048; // Bad Value!!
  142. // if( pHwDevExt->lSeemVBuff < 0 ) {
  143. // pHwDevExt->lSeemVBuff = 0;
  144. // SeemlessProc( pHwDevExt );
  145. // }
  146. // }
  147. if( pHwDevExt->fSrbDMA1last ) {
  148. DebugPrint(( DebugLevelVerbose, "TOSDVD:HWInt SrbDMA1 0x%x\r\n", pHwDevExt->pSrbDMA1 ) );
  149. // must fix!
  150. // other place that call StreamRequestComplete() does not clear pHwDevExt->bEndCpp;
  151. if( ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA1->SRBExtension))->pfnEndSrb ) {
  152. DebugPrint(( DebugLevelTrace, "TOSDVD:exist pfnEndSrb(HWint1) srb = 0x%x\r\n", pHwDevExt->pSrbDMA1 ));
  153. if( pHwDevExt->pSrbDMA0 == NULL ) {
  154. DebugPrint(( DebugLevelTrace, "TOSDVD:Call TimerCppReset(HWint1)\r\n" ));
  155. StreamClassScheduleTimer(
  156. NULL,
  157. pHwDevExt,
  158. 1,
  159. ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA1->SRBExtension))->pfnEndSrb,
  160. ((PSRB_EXTENSION)(pHwDevExt->pSrbDMA1->SRBExtension))->parmSrb
  161. );
  162. }
  163. }
  164. pHwDevExt->pSrbDMA1->Status = STATUS_SUCCESS;
  165. StreamClassStreamNotification( StreamRequestComplete,
  166. pHwDevExt->pSrbDMA1->StreamObject,
  167. pHwDevExt->pSrbDMA1 );
  168. }
  169. // Next DMA
  170. pHwDevExt->pSrbDMA1 = NULL;
  171. pHwDevExt->fSrbDMA1last = FALSE;
  172. }
  173. PreDMAxfer( pHwDevExt/*, val & 0x03 */);
  174. }
  175. void HwIntVideo( PHW_DEVICE_EXTENSION pHwDevExt )
  176. {
  177. UCHAR val;
  178. UCHAR val2;
  179. // DebugPrint( (DebugLevelTrace, "TOSDVD:HwIntVideo\r\n") );
  180. val = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_IRM );
  181. val2 = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_IRF );
  182. val ^= val2;
  183. val2 &= val;
  184. //--- 97.09.23 K.Chujo; User Data Start Code Interrupt for Closed Caption
  185. if( val2 & 0x01 ) {
  186. // DebugPrint( (DebugLevelTrace, "TOSDVD: UDSC\r\n") );
  187. USCC_get( pHwDevExt );
  188. }
  189. //--- End.
  190. #if DBG
  191. if( val2 & 0x02 )
  192. DebugPrint( (DebugLevelTrace, "TOSDVD: Scr\r\n") );
  193. if( val2 & 0x04 )
  194. DebugPrint( (DebugLevelTrace, "TOSDVD: I-PIC\r\n") );
  195. if( val2 & 0x08 )
  196. DebugPrint( (DebugLevelTrace, "TOSDVD: User\r\n") );
  197. // if( val2 & 0x10 )
  198. // DebugPrint( (DebugLevelTrace, "TOSDVD: Error\r\n") );
  199. #endif
  200. if( val2 & 0x10 ) {
  201. UCHAR val3;
  202. DebugPrint( (DebugLevelTrace, "TOSDVD: Error\r\n") );
  203. val3 = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_ERF );
  204. DebugPrint( (DebugLevelTrace, "TOSDVD: Error %x\r\n", val3 ) );
  205. }
  206. if( val2 & 0x40 ) {
  207. DebugPrint( (DebugLevelTrace, "TOSDVD: Underflow\r\n") );
  208. /// pHwDevExt->XferStartCount = 0;
  209. /// pHwDevExt->DecodeStart = FALSE;
  210. /// pHwDevExt->SendFirst = FALSE;
  211. // pHwDevExt->SendFirstTime = GetCurrentTime_ms();
  212. // ???
  213. /// for( int i = 0; i < 0xff /*0xffff*/; i++ )
  214. /// val2 = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_STT1 );
  215. for( int i = 0; i < 0xffff /*0xffff*/; i++ )
  216. val2 = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_STT1 );
  217. val2 = READ_PORT_UCHAR( pHwDevExt->ioBaseLocal + TC812_UOF );
  218. pHwDevExt->dwSTCtemp = pHwDevExt->VDec.VIDEO_GET_STCA();
  219. // Check Audio Underflow
  220. StreamClassScheduleTimer(
  221. pHwDevExt->pstroAud,
  222. pHwDevExt,
  223. 0,
  224. (PHW_TIMER_ROUTINE)CheckAudioUnderflow,
  225. pHwDevExt
  226. );
  227. StreamClassScheduleTimer(
  228. pHwDevExt->pstroAud,
  229. pHwDevExt,
  230. 10000,
  231. (PHW_TIMER_ROUTINE)CheckAudioUnderflow,
  232. pHwDevExt
  233. );
  234. }
  235. }
  236. void HwIntVSync( PHW_DEVICE_EXTENSION pHwDevExt )
  237. {
  238. static v_count = 0;
  239. static v_count2 = 0;
  240. // ULONG TrickMode;
  241. WRITE_PORT_UCHAR( pHwDevExt->ioBaseLocal + PCIF_INTF, 0x10 );
  242. //--- 97.09.15 K.Chujo; Analog Copy Guard for beta 3, always Type 1 (AGC only);
  243. pHwDevExt->CPgd.CPGD_UPDATE_AGC();
  244. //--- End.
  245. //--- 97.09.23 K.Chujo; Closed Caption
  246. USCC_put( pHwDevExt );
  247. //--- End.
  248. if( ++v_count < 3 )
  249. return;
  250. v_count = 0;
  251. // 20 / 1s
  252. // notes: You have to call VIDEO_BUG_SLIDE_01 to recover MPEG2 chip bug
  253. // when trick mode isn't FREEZE mode.
  254. // But don't use VIDEO_GET_TRICK_MODE to get current trick mode.
  255. // Because MPEG2 chip returns wrong value sometimes.
  256. // TrickMode = pHwDevExt->VDec.VIDEO_GET_TRICK_MODE();
  257. // if( TrickMode != 0x02 ) {
  258. if( pHwDevExt->PlayMode != PLAY_MODE_FREEZE /*&& pHwDevExt->DecodeStart == TRUE*/ ) {
  259. pHwDevExt->VDec.VIDEO_BUG_SLIDE_01();
  260. }
  261. if( ++v_count2 < 4 )
  262. return;
  263. v_count2 = 0;
  264. // 5 / 1s ???
  265. ClockEvents( pHwDevExt );
  266. // debug
  267. static v_count3 = 0;
  268. if( ++v_count3 < 50 )
  269. return;
  270. v_count3 = 0;
  271. // 1 / 60s
  272. DebugPrint((
  273. DebugLevelTrace,
  274. "TOSDVD: VSync 10s (0x%s(100ns))\r\n",
  275. DebugLLConvtoStr( ConvertPTStoStrm( pHwDevExt->VDec.VIDEO_GET_STCA() ), 16 )
  276. ));
  277. }
  278. //void SeemlessProc( PHW_DEVICE_EXTENSION pHwDevExt )
  279. //{
  280. // DWORD dwSTC;
  281. //
  282. // DebugPrint( (DebugLevelTrace, "TOSDVD:SeemlessProc\r\n") );
  283. //
  284. // pHwDevExt->VDec.VIDEO_SET_STCA( pHwDevExt->dwSeemSTC );
  285. // dwSTC = pHwDevExt->VDec.VIDEO_GET_STCA();
  286. // pHwDevExt->ADec.AUDIO_ZR38521_VDSCR_OFF( dwSTC );
  287. // pHwDevExt->VPro.SUBP_SET_STC( dwSTC );
  288. // pHwDevExt->VPro.SUBP_STC_ON();
  289. //
  290. //// pHwDevExt->VDec.VIDEO_UFLOW_INT_ON();
  291. //
  292. //}