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.

819 lines
26 KiB

  1. /******************************************************************************
  2. *
  3. * Module: SETMODE.C Set Video Mode Function Module
  4. *
  5. * Revision: 1.00
  6. *
  7. * Date: April 8, 1994
  8. *
  9. * Author: Randy Spurlock
  10. *
  11. *******************************************************************************
  12. *
  13. * Module Description:
  14. *
  15. * This module contains code for the SetMode function. This
  16. * function can be used to set a video mode that was obtained via the
  17. * GetModeTable function.
  18. *
  19. *******************************************************************************
  20. *
  21. * Changes:
  22. *
  23. * DATE REVISION DESCRIPTION AUTHOR
  24. * -------- -------- -------------------------------------------------------
  25. * 04/08/94 1.00 Original Randy Spurlock
  26. *
  27. *******************************************************************************
  28. * Include Files
  29. ******************************************************************************/
  30. #include <stdlib.h> /* Include standard library header */
  31. #include <stdio.h> /* Include standard I/O header file */
  32. #include <conio.h> /* Include console I/O header file */
  33. #include <dos.h> /* Include dos header file */
  34. #include <string.h> /* Include string header file */
  35. #include <malloc.h> /* Include malloc header file */
  36. //
  37. // Is this Windows NT or something else?
  38. //
  39. #ifndef WIN_NT
  40. #if NT_MINIPORT
  41. #define WIN_NT 1
  42. #else
  43. #define WIN_NT 0
  44. #endif
  45. #endif
  46. #include "type.h" /* Include type header file */
  47. #include "modemon.h" /* Include mode/monitor header file */
  48. #include "structs.h" /* Include the struct header file */
  49. #if WIN_NT && NT_MINIPORT // If NT and Miniport
  50. #include "cirrus.h"
  51. #endif
  52. /******************************************************************************
  53. * Local Defintions
  54. ******************************************************************************/
  55. #define STACK_SIZE 32 /* Maximum stack size value */
  56. #define VIDEO_BIOS 0x10 /* Video BIOS function value */
  57. #define VIDEO_SETMODE 0x00 /* Video set mode funtion value */
  58. #define DMA_PAGE 0x84 /* Unused DMA page register port */
  59. #if WIN_NT // If NT and Miniport
  60. #if NT_MINIPORT
  61. //
  62. // NT Miniport has it's own set of I/O functions.
  63. //
  64. #define outp(port,val) VideoPortWritePortUchar ((unsigned char *)port, (unsigned char)val)
  65. #define outpw(port,val) VideoPortWritePortUshort((unsigned short *)port, (unsigned short)val)
  66. #define outpd(port,val) VideoPortWritePortUlong ((unsigned long *)port, (unsigned long)val)
  67. #define inp(port) VideoPortReadPortUchar ((unsigned char *)port)
  68. #define inpw(port) VideoPortReadPortUshort ((unsigned short *)port)
  69. #define inpd(port) VideoPortReadPortUlong ((unsigned long *)port)
  70. #else
  71. #define outp(port,val) _outp ((unsigned short)(port), (BYTE) (val))
  72. #define outpw(port,val) _outpw ((unsigned short)(port), (WORD) (val))
  73. #define outpd(port,val) _outpd ((unsigned short)(port), (DWORD)(val))
  74. #define inp(port) _inp ((unsigned short)(port))
  75. #define inpw(port) _inpw ((unsigned short)(port))
  76. #define inpd(port) _inpd ((unsigned short)(port))
  77. #endif
  78. #if 0 // Stress test
  79. #if defined(ALLOC_PRAGMA)
  80. #pragma alloc_text(PAGE,SetMode)
  81. #endif
  82. #endif
  83. #endif
  84. #if WIN_NT
  85. #ifndef NT_MINIPORT
  86. #define VideoDebugPrint(x)
  87. #endif
  88. #endif
  89. #if !(WIN_NT)
  90. int WriteI2CRegister(BYTE * pMem, int nPort, int nAddr, int nReg, int nData);
  91. #endif
  92. void WaitNVsyncs (BYTE * pMemory, WORD wNumVsyncs );
  93. /******************************************************************************
  94. *
  95. * void SetMode(BYTE *pModeTable, BYTE *pMemory)
  96. *
  97. * Where:
  98. *
  99. * pModeTable - Pointer to mode table to set
  100. * pMemory - Pointer to memory mapped I/O space
  101. *
  102. * Notes:
  103. *
  104. * This function will set the video mode using the mode table.
  105. *
  106. ******************************************************************************/
  107. void SetMode(BYTE *pModeTable, BYTE *pMemory, BYTE * pBinaryData, ULONG SkipIO)
  108. {
  109. DWORD nHold; /* Holding register value */
  110. int nPort; /* Register port address value */
  111. int nOffset; /* Memory address offset value */
  112. int nIndex; /* Register port index value */
  113. int nCount; /* Multiple output count value */
  114. int nLoop; /* Generic loop counter */
  115. int nPointer = 0; /* Stack pointer value */
  116. int anStack[STACK_SIZE]; /* Stack array */
  117. BYTE *pPointer; /* Mode table pointer */
  118. #if !(WIN_NT)
  119. union REGS Regs; /* Register union structure */
  120. #endif
  121. int i; /* Temporary Register for Counting */
  122. PI2C pI2C; /* Some data pointers */
  123. PI2CDATA pI2CData;
  124. #if 0 // Stress test
  125. #if NT_MINIPORT
  126. PAGED_CODE();
  127. #endif
  128. #endif
  129. /*
  130. Init nHold to 0 to make PREfast happy. This is a bit risky though
  131. in case write happens before read, but it was working fine so far.
  132. This is an example of the bad programming though and the only reason
  133. we don't really validate it is that this is the legacy part with
  134. the support to be removed soon.
  135. */
  136. nHold = 0;
  137. /* Loop processing the commands in the mode table */
  138. pPointer = pModeTable; /* Initialize the mode table pointer */
  139. while (TRUE == TRUE)
  140. {
  141. /* Switch on the mode command opcode */
  142. #if 0
  143. if (*(DWORD *)(pMemory + 0x3F8) & 0x0100 == 0x0000)
  144. {
  145. fprintf(stdout,"VGA Shadow %x\n", (DWORD *)(pMemory + 0x3F8));
  146. exit(0);
  147. }
  148. fprintf(stdout,"Type %x %x %x Shadow=%x\n", ((Mode *) pPointer)->Mode_Opcode, pPointer, pBinaryData, *(DWORD *)(pMemory + 0x3F8));
  149. #endif
  150. //VideoDebugPrint((2, " Setmode: Processing opcode 0x%X.\n",
  151. // ((Mode *) pPointer)->Mode_Opcode));
  152. switch(((Mode *) pPointer)->Mode_Opcode)
  153. {
  154. case END_TABLE: /* End of table command */
  155. /* Check for end of top level */
  156. if (nPointer == 0)
  157. return; /* End of mode set, return to caller */
  158. else
  159. pPointer = pModeTable + anStack[--nPointer];
  160. break;
  161. case SET_BIOS_MODE: /* Set BIOS mode command */
  162. /* Setup the required registers and do the BIOS mode set */
  163. #if WIN_NT
  164. VideoDebugPrint((2,
  165. "\n* * * * CL546X.SYS * Unsupported BIOS call in SetMode() * * * *\n\n"));
  166. #else
  167. Regs.h.ah = VIDEO_SETMODE;
  168. Regs.h.al = ((SBM *) pPointer)->SBM_Mode;
  169. #ifdef __WATCOMC__
  170. int386(VIDEO_BIOS, &Regs, &Regs);
  171. #else
  172. int86(VIDEO_BIOS, &Regs, &Regs);
  173. #endif
  174. #endif
  175. /* Update the mode table pointer */
  176. pPointer += sizeof(SBM);
  177. break;
  178. case SINGLE_INDEXED_OUTPUT: /* Single indexed output command */
  179. if (!SkipIO) // are VGA regs ours?
  180. {
  181. /* Setup the register index value */
  182. outp(((SIO *) pPointer)->SIO_Port,
  183. ((SIO *) pPointer)->SIO_Index);
  184. /* Output a single byte to the desired port */
  185. outp(((SIO *) pPointer)->SIO_Port + 1,
  186. ((SIO *) pPointer)->SIO_Value);
  187. }
  188. /* Update the mode table pointer */
  189. pPointer += sizeof(SIO);
  190. break;
  191. #if 0
  192. case SINGLE_BYTE_INPUT: /* Single byte input command */
  193. /* Input a single byte into the holding buffer */
  194. nHold = inp(((SBI *) pPointer)->SBI_Port);
  195. /* Update the mode table pointer */
  196. pPointer += sizeof(SBI);
  197. break;
  198. case SINGLE_WORD_INPUT: /* Single word input command */
  199. /* Input a single word into the holding buffer */
  200. nHold = inpw(((SWI *) pPointer)->SWI_Port);
  201. /* Update the mode table pointer */
  202. pPointer += sizeof(SWI);
  203. break;
  204. case SINGLE_DWORD_INPUT: /* Single dword input command */
  205. /* Input a single dword into the holding buffer */
  206. nHold = inpd(((SDI *) pPointer)->SDI_Port);
  207. /* Update the mode table pointer */
  208. pPointer += sizeof(SDI);
  209. break;
  210. case SINGLE_INDEXED_INPUT: /* Single indexed input command */
  211. /* Setup the register index value */
  212. outp(((SII *) pPointer)->SII_Port,
  213. ((SII *) pPointer)->SII_Index);
  214. /* Input a single byte into the holding buffer */
  215. nHold = inp(((SII *) pPointer)->SII_Port + 1);
  216. /* Update the mode table pointer */
  217. pPointer += sizeof(SII);
  218. break;
  219. case SINGLE_BYTE_OUTPUT: /* Single byte output command */
  220. /* Output a single byte to the desired port */
  221. outp(((SBO *) pPointer)->SBO_Port,
  222. ((SBO *) pPointer)->SBO_Value);
  223. /* Update the mode table pointer */
  224. pPointer += sizeof(SBO);
  225. break;
  226. case SINGLE_WORD_OUTPUT: /* Single word output command */
  227. /* Output a single word to the desired port */
  228. outpw(((SWO *) pPointer)->SWO_Port,
  229. ((SWO *) pPointer)->SWO_Value);
  230. /* Update the mode table pointer */
  231. pPointer += sizeof(SWO);
  232. break;
  233. case SINGLE_DWORD_OUTPUT: /* Single dword output command */
  234. /* Output a single dword to the desired port */
  235. outpd(((SDO *) pPointer)->SDO_Port,
  236. ((SDO *) pPointer)->SDO_Value);
  237. /* Update the mode table pointer */
  238. pPointer += sizeof(SDO);
  239. break;
  240. case HOLDING_BYTE_OUTPUT: /* Holding byte output command */
  241. /* Output holding byte to the desired port */
  242. outp(((HBO *) pPointer)->HBO_Port, nHold);
  243. /* Update the mode table pointer */
  244. pPointer += sizeof(HBO);
  245. break;
  246. case HOLDING_WORD_OUTPUT: /* Holding word output command */
  247. /* Output holding word to the desired port */
  248. outpw(((HWO *) pPointer)->HWO_Port, nHold);
  249. /* Update the mode table pointer */
  250. pPointer += sizeof(HWO);
  251. break;
  252. case HOLDING_DWORD_OUTPUT: /* Holding dword output command */
  253. /* Output holding dword to the desired port */
  254. outpd(((HDO *) pPointer)->HDO_Port, nHold);
  255. /* Update the mode table pointer */
  256. pPointer += sizeof(HDO);
  257. break;
  258. case HOLDING_INDEXED_OUTPUT:/* Holding indexed output command */
  259. /* Setup the register index value */
  260. outp(((HIO *) pPointer)->HIO_Port,
  261. ((HIO *) pPointer)->HIO_Index);
  262. /* Output holding byte to the desired port */
  263. outp(((HIO *) pPointer)->HIO_Port + 1, nHold);
  264. /* Update the mode table pointer */
  265. pPointer += sizeof(HIO);
  266. break;
  267. case MULTIPLE_BYTE_OUTPUT: /* Multiple byte output command */
  268. /* Setup the port address and count values */
  269. nPort = ((MBO *) pPointer)->MBO_Port;
  270. nCount = ((MBO *) pPointer)->MBO_Count;
  271. /* Update the mode table pointer */
  272. pPointer += sizeof(MBO);
  273. /* Loop outputting bytes to the desired port */
  274. for (nLoop = 0; nLoop < nCount; nLoop++)
  275. outp(nPort, *((BYTE *) pPointer++));
  276. break;
  277. case MULTIPLE_WORD_OUTPUT: /* Multiple word output command */
  278. /* Setup the port address and count values */
  279. nPort = ((MWO *) pPointer)->MWO_Port;
  280. nCount = ((MWO *) pPointer)->MWO_Count;
  281. /* Update the mode table pointer */
  282. pPointer += sizeof(MWO);
  283. /* Loop outputting words to the desired port */
  284. for (nLoop = 0; nLoop < nCount; nLoop++)
  285. outpw(nPort, *((WORD *) pPointer++));
  286. break;
  287. case MULTIPLE_DWORD_OUTPUT: /* Multiple dword output command */
  288. /* Setup the port address and count values */
  289. nPort = ((MDO *) pPointer)->MDO_Port;
  290. nCount = ((MDO *) pPointer)->MDO_Count;
  291. /* Update the mode table pointer */
  292. pPointer += sizeof(MDO);
  293. /* Loop outputting dwords to the desired port */
  294. for (nLoop = 0; nLoop < nCount; nLoop++)
  295. outpd(nPort, *((DWORD *) pPointer++));
  296. break;
  297. case MULTIPLE_INDEXED_OUTPUT:/* Multiple indexed output command */
  298. /* Setup the port address and count values */
  299. nPort = ((MIO *) pPointer)->MIO_Port;
  300. nIndex = ((MIO *) pPointer)->MIO_Index;
  301. nCount = ((MIO *) pPointer)->MIO_Count;
  302. /* Update the mode table pointer */
  303. pPointer += sizeof(MIO);
  304. /* Loop outputting bytes to the desired port */
  305. for (nLoop = 0; nLoop < nCount; nLoop++)
  306. {
  307. /* Setup the register index value */
  308. outp(nPort, nIndex++);
  309. /* Output the actual data value */
  310. outp(nPort + 1, *((BYTE *) pPointer++));
  311. }
  312. break;
  313. #endif
  314. case SINGLE_BYTE_READ: /* Single byte read command */
  315. /* Read a single byte into the holding buffer */
  316. nHold = *((BYTE *) (pMemory + (((SBR *) pPointer)->SBR_Address)));
  317. /* Update the mode table pointer */
  318. pPointer += sizeof(SBR);
  319. break;
  320. case SINGLE_WORD_READ: /* Single word read command */
  321. /* Read a single word into the holding buffer */
  322. nHold = *((WORD *) (pMemory + (((SWR *) pPointer)->SWR_Address)));
  323. /* Update the mode table pointer */
  324. pPointer += sizeof(SWR);
  325. break;
  326. case SINGLE_DWORD_READ: /* Single dword read command */
  327. /* Read a single dword into the holding buffer */
  328. nHold = *((DWORD *) (pMemory + (((SDR *) pPointer)->SDR_Address)));
  329. /* Update the mode table pointer */
  330. pPointer += sizeof(SDR);
  331. break;
  332. case SINGLE_BYTE_WRITE: /* Single byte write command */
  333. /* Write a single byte to the desired adress */
  334. *((BYTE *) (pMemory + (((SBW *) pPointer)->SBW_Address))) =
  335. (BYTE) ((SBW *) pPointer)->SBW_Value;
  336. #if 0
  337. fprintf(stdout,"SBW %x %x\n",
  338. ((SBW *) pPointer)->SBW_Address,
  339. ((SBW *) pPointer)->SBW_Value);
  340. #endif
  341. /* Update the mode table pointer */
  342. pPointer += sizeof(SBW);
  343. break;
  344. case SINGLE_WORD_WRITE: /* Single word write command */
  345. /* Write a single word to the desired address */
  346. *((WORD *) (pMemory + (((SWW *) pPointer)->SWW_Address))) =
  347. ((SWW *) pPointer)->SWW_Value;
  348. /* Update the mode table pointer */
  349. #if 0
  350. fprintf(stdout,"SWW %x %x\n",
  351. ((SWW *) pPointer)->SWW_Address,
  352. ((SWW *) pPointer)->SWW_Value);
  353. #endif
  354. pPointer += sizeof(SWW);
  355. break;
  356. case SINGLE_DWORD_WRITE: /* Single dword write command */
  357. /* Write a single dword to the desired address */
  358. *((DWORD *) (pMemory + (((SDW *) pPointer)->SDW_Address))) =
  359. ((SDW *) pPointer)->SDW_Value;
  360. /* Update the mode table pointer */
  361. #if 0
  362. fprintf(stdout,"SDW %x %x\n",
  363. ((SDW *) pPointer)->SDW_Address,
  364. ((SDW *) pPointer)->SDW_Value);
  365. #endif
  366. pPointer += sizeof(SDW);
  367. break;
  368. case HOLDING_BYTE_WRITE: /* Holding byte write command */
  369. /* Write holding byte to the desired address */
  370. *((BYTE *) (pMemory + (((HBW *) pPointer)->HBW_Address))) =(BYTE) nHold;
  371. #if 0
  372. fprintf(stdout,"HBW %x %x\n",
  373. ((HBW *) pPointer)->HBW_Address,
  374. nHold);
  375. #endif
  376. /* Update the mode table pointer */
  377. pPointer += sizeof(HBW);
  378. break;
  379. case HOLDING_WORD_WRITE: /* Holding word write command */
  380. /* Write holding word to the desired address */
  381. *((WORD *) (pMemory + (((HWW *) pPointer)->HWW_Address))) = (WORD) nHold;
  382. /* Update the mode table pointer */
  383. #if 0
  384. fprintf(stdout,"HWW %x %x\n",
  385. ((HWW *) pPointer)->HWW_Address,
  386. nHold);
  387. #endif
  388. pPointer += sizeof(HWW);
  389. break;
  390. case HOLDING_DWORD_WRITE: /* Holding dword write command */
  391. /* Write holding dword to the desired address */
  392. *((DWORD *) (pMemory + (((HDW *) pPointer)->HDW_Address))) = nHold;
  393. /* Update the mode table pointer */
  394. #if 0
  395. fprintf(stdout,"HDW %x %x\n",
  396. ((HDW *) pPointer)->HDW_Address,
  397. nHold);
  398. #endif
  399. pPointer += sizeof(HDW);
  400. break;
  401. case MULTIPLE_BYTE_WRITE: /* Multiple byte write command */
  402. /* Setup the offset and count values */
  403. nOffset = ((MBW *) pPointer)->MBW_Address;
  404. nCount = ((MBW *) pPointer)->MBW_Count;
  405. /* Update the mode table pointer */
  406. pPointer += sizeof(MBW);
  407. /* Loop writing bytes to the desired addresses */
  408. for (nLoop = 0; nLoop < nCount; nLoop++)
  409. {
  410. /* Write the next byte and update memory offset value */
  411. #if 0
  412. fprintf(stdout,"MBW %x %x\n", nOffset, (BYTE *)pPointer);
  413. #endif
  414. *((BYTE *) (pMemory + nOffset)) = *((BYTE *) pPointer++);
  415. nOffset += sizeof(BYTE);
  416. }
  417. break;
  418. case MULTIPLE_WORD_WRITE: /* Multiple word write command */
  419. /* Setup the offset and count values */
  420. nOffset = ((MWW *) pPointer)->MWW_Address;
  421. nCount = ((MWW *) pPointer)->MWW_Count;
  422. /* Update the mode table pointer */
  423. pPointer += sizeof(MWW);
  424. /* Loop writing words to the desired addresses */
  425. for (nLoop = 0; nLoop < nCount; nLoop++)
  426. {
  427. /* Write the next word and update memory offset value */
  428. #if 0
  429. fprintf(stdout,"MWW %x %x\n", nOffset, (WORD *)pPointer);
  430. #endif
  431. *((WORD *) (pMemory + nOffset)) = *((WORD *) pPointer++);
  432. nOffset += sizeof(WORD);
  433. }
  434. break;
  435. case MULTIPLE_DWORD_WRITE: /* Multiple dword write command */
  436. /* Setup the address and count values */
  437. nOffset = ((MDW *) pPointer)->MDW_Address;
  438. nCount = ((MDW *) pPointer)->MDW_Count;
  439. /* Update the mode table pointer */
  440. pPointer += sizeof(MDW);
  441. /* Loop writing dwords to the desired addresses */
  442. #if 0
  443. fprintf(stdout,"nOffset %x nCount %d\n", nOffset, nCount);
  444. #endif
  445. for (nLoop = 0; nLoop < nCount; nLoop++)
  446. {
  447. /* Write the next dword and update memory offset value */
  448. #if 0
  449. fprintf(stdout,"nOffset %x Data %x %x\n", nOffset, *pPointer, pPointer);
  450. #endif
  451. *((DWORD *) (pMemory + nOffset)) = *((DWORD *) pPointer);
  452. pPointer += sizeof(DWORD);
  453. nOffset += sizeof(DWORD);
  454. }
  455. break;
  456. case PERFORM_OPERATION: /* Perform logical operation command */
  457. /* Switch on the logical operation type */
  458. switch(((LO *) pPointer)->LO_Operation)
  459. {
  460. case AND_OPERATION: /* Logical AND operation */
  461. /* Perform logical AND operation on holding value */
  462. nHold &= ((LO *) pPointer)->LO_Value;
  463. break;
  464. case OR_OPERATION: /* Logical OR operation */
  465. /* Perform logical OR operation on holding value */
  466. nHold |= ((LO *) pPointer)->LO_Value;
  467. break;
  468. case XOR_OPERATION: /* Logical XOR operation */
  469. /* Perform logical XOR operation on holding value */
  470. nHold ^= ((LO *) pPointer)->LO_Value;
  471. break;
  472. }
  473. /* Update the mode table pointer */
  474. pPointer += sizeof(LO);
  475. break;
  476. case PERFORM_DELAY: /* Perform delay operation command */
  477. // delay by waiting for the specified number of vsyncs
  478. WaitNVsyncs(pMemory, (WORD)((DO *)pPointer)->DO_Time);
  479. /* Update the mode table pointer */
  480. pPointer += sizeof(DO);
  481. break;
  482. case SUB_TABLE: /* Perform mode sub-table command */
  483. /* Check the current nesting level */
  484. if (nPointer < STACK_SIZE)
  485. {
  486. /* Put current offset into stack and update the pointer */
  487. anStack[nPointer++] = pPointer - pModeTable + sizeof(MST);
  488. if (pBinaryData)
  489. pPointer = pBinaryData + ((MST *) pPointer)->MST_Pointer;
  490. else
  491. pPointer = pModeTable + ((MST *) pPointer)->MST_Pointer;
  492. }
  493. else /* Nesting level too deep, skip table */
  494. {
  495. #if WIN_NT
  496. VideoDebugPrint((2,
  497. "\n* * * * CL546X.SYS * Nesting level too deep in SetMode()\n\n"));
  498. #else
  499. fprintf(stdout,"Nesting to depth %s %d\n", __FILE__, __LINE__);
  500. #endif
  501. pPointer += sizeof(MST);
  502. }
  503. break;
  504. case I2COUT_WRITE:
  505. #if WIN_NT
  506. VideoDebugPrint((2,
  507. "\n* * * * CL546X.SYS * Unsupported I2C call in SetMode() \n\n"));
  508. #endif
  509. pI2C = (PI2C)pPointer;
  510. pI2CData = (PI2CDATA)(pPointer + sizeof(I2C));
  511. for (i=0; i<pI2C->I2C_Count; i++)
  512. {
  513. #if !WIN_NT
  514. WriteI2CRegister(pMemory, pI2C->I2C_Port, pI2C->I2C_Addr, pI2CData->I2C_Reg, pI2CData->I2C_Data);
  515. #endif
  516. pI2CData++;
  517. }
  518. pPointer += sizeof(I2C) + pI2C->I2C_Count * sizeof(I2CDATA);
  519. break;
  520. default: /* Unknown mode command, abort */
  521. #if WIN_NT
  522. VideoDebugPrint((2,
  523. "Miniport - Setmode abort. Unknnown command.\n"));
  524. #else
  525. fprintf(stdout,"Unknown Command [%x] %s %d\n", ((Mode *) pPointer)->Mode_Opcode, __FILE__, __LINE__);
  526. #endif
  527. return; /* Invalid command, return to caller */
  528. break;
  529. }
  530. }
  531. /* Mode set is complete, return control to the caller */
  532. return; /* Return control to the caller */
  533. }
  534. void WaitNVsyncs (BYTE * pMemory, WORD wNumVsyncs )
  535. {
  536. volatile BYTE * pMBE = (BYTE *)(pMemory + 0xEC);
  537. unsigned long uCount = 0x00FFFF;
  538. int nPort;
  539. // VideoDebugPrint((2, " ---- WaitNVsyncs. Enter.\n"));
  540. //
  541. // This code will work on 5462, 5464, 5465
  542. //
  543. #if 0
  544. nPort = inp(0x3cc) & 0x01 ? 0x3da : 0x3ba;
  545. while ( (inp(nPort) & 0x08) && (--uCount) )
  546. ;
  547. uCount = 0x00FFFF;
  548. while ( (!(inp(nPort) & 0x08)) && (--uCount) )
  549. ;
  550. #else
  551. while ( ((*pMBE & 0x80) == 0x80) && (--uCount) )
  552. ;
  553. uCount = 0x00FFFF;
  554. while ( ((*pMBE & 0x80) == 0x00) && (--uCount) )
  555. ;
  556. #endif
  557. // VideoDebugPrint((2, " ---- WaitNVsyncs. Exit.\n"));
  558. }