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.

1049 lines
28 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. drawscrn.c
  5. Abstract:
  6. This is the console fullscreen driver for the VGA card.
  7. Environment:
  8. kernel mode only
  9. Notes:
  10. Revision History:
  11. --*/
  12. #include "fsvga.h"
  13. #define COMMON_LVB_MASK (COMMON_LVB_GRID_HORIZONTAL | \
  14. COMMON_LVB_GRID_LVERTICAL | \
  15. COMMON_LVB_GRID_RVERTICAL | \
  16. COMMON_LVB_REVERSE_VIDEO | \
  17. COMMON_LVB_UNDERSCORE )
  18. /* ----- Macros -----*/
  19. /*++
  20. Macro Description:
  21. This Macro calcurate a scan line in graphics buffer.
  22. Arguments:
  23. WindowY - Coord to Y.
  24. FontSizeY - Font size of Y.
  25. Return Value:
  26. Returen to graphics buffer offset.
  27. --*/
  28. #define CalcGRAMScanLine(WindowY,FontSizeY) \
  29. (WindowY * FontSizeY)
  30. /*++
  31. Macro Description:
  32. This Macro calcurate a graphics buffer offset.
  33. Arguments:
  34. WindowSize - Coord of window size.
  35. DeviceExtension - Pointer to the miniport driver's device extension.
  36. Return Value:
  37. Returen to graphics buffer offset.
  38. --*/
  39. #define CalcGRAMOffs(WindowSize,ScreenIfno,EmulateInfo) \
  40. (EmulateInfo->StartAddress + \
  41. CalcGRAMSize(WindowSize,ScreenInfo,EmulateInfo) \
  42. )
  43. /*++
  44. Macro Description:
  45. This Macro gets the byte per one scan line.
  46. Arguments:
  47. EmulateInfo - Pointer to screen emualte information structure.
  48. Return Value:
  49. Byte pre line number.
  50. --*/
  51. #define GetBytePerLine(HardwareScroll) \
  52. ((HardwareScroll & OFFSET_128_TO_NEXT_SLICE) ? \
  53. (1024 / 8) : \
  54. (640 / 8) \
  55. )
  56. ULONG
  57. CalcGRAMSize(
  58. IN COORD WindowSize,
  59. IN PFSVIDEO_SCREEN_INFORMATION ScreenInfo,
  60. IN PEMULATE_BUFFER_INFORMATION EmulateInfo
  61. )
  62. /*++
  63. Routine Description:
  64. This Macro calcurate a graphics buffer size.
  65. Arguments:
  66. WindowSize - Coord of window size.
  67. DeviceExtension - Pointer to the miniport driver's device extension.
  68. Return Value:
  69. Returen to graphics buffer offset.
  70. --*/
  71. {
  72. return WindowSize.X +
  73. CalcGRAMScanLine(WindowSize.Y, ScreenInfo->FontSize.Y) *
  74. EmulateInfo->BytePerLine;
  75. }
  76. PUCHAR
  77. CalcGRAMAddress(
  78. IN COORD WindowSize,
  79. IN PFSVIDEO_MODE_INFORMATION VideoModeInfo,
  80. IN PFSVIDEO_SCREEN_INFORMATION ScreenInfo,
  81. IN PEMULATE_BUFFER_INFORMATION EmulateInfo
  82. )
  83. /*++
  84. Routine Description:
  85. This routine calcurate a graphics buffer address.
  86. Arguments:
  87. WindowSize - Coord of window size.
  88. DeviceExtension - Pointer to the miniport driver's device extension.
  89. Return Value:
  90. Returen to graphics buffer address.
  91. --*/
  92. {
  93. PUCHAR BufPtr = (PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase;
  94. BufPtr += CalcGRAMOffs(WindowSize, ScreenInfo, EmulateInfo);
  95. if ((ULONG)(BufPtr -
  96. (PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
  97. >= EmulateInfo->LimitGRAM)
  98. return (BufPtr - EmulateInfo->LimitGRAM);
  99. else
  100. return BufPtr;
  101. }
  102. #ifdef LATER_HIGH_SPPED_VRAM_ACCESS // kazum
  103. BOOLEAN
  104. IsGRAMRowOver(
  105. PUCHAR BufPtr,
  106. BOOLEAN fDbcs,
  107. IN PFSVIDEO_MODE_INFORMATION VideoModeInfo,
  108. IN PEMULATE_BUFFER_INFORMATION EmulateInfo
  109. )
  110. /*++
  111. Routine Description:
  112. This Routine check ROW overflow as GRAM limit line.
  113. Arguments:
  114. BufPtr - Pointer to graphics buffer.
  115. fDbcs - Flag of DBCS(true) or SBCS(false).
  116. Return Value:
  117. TRUE: if font box is overflow as GRAMlimit line.
  118. FALSE: not overflow.
  119. --*/
  120. {
  121. if (fDbcs)
  122. {
  123. if ((ULONG)(BufPtr + 1 +
  124. EmulateInfo->DeltaNextFontRow -
  125. (PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
  126. >= EmulateInfo->LimitGRAM)
  127. return TRUE;
  128. else
  129. return FALSE;
  130. }
  131. else
  132. {
  133. if ((ULONG)(BufPtr +
  134. EmulateInfo->DeltaNextFontRow -
  135. (PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
  136. >= EmulateInfo->LimitGRAM)
  137. return TRUE;
  138. else
  139. return FALSE;
  140. }
  141. }
  142. #endif // LATER_HIGH_SPPED_VRAM_ACCESS // kazum
  143. PUCHAR
  144. NextGRAMRow(
  145. PUCHAR BufPtr,
  146. IN PFSVIDEO_MODE_INFORMATION VideoModeInfo,
  147. IN PEMULATE_BUFFER_INFORMATION EmulateInfo
  148. )
  149. /*++
  150. Routine Description:
  151. This Routine add next row a graphics buffer address.
  152. Arguments:
  153. BufPtr - Pointer to graphics buffer.
  154. Return Value:
  155. Returen to graphics buffer address.
  156. --*/
  157. {
  158. if ((ULONG)(BufPtr +
  159. EmulateInfo->BytePerLine -
  160. (PUCHAR)VideoModeInfo->VideoMemory.FrameBufferBase)
  161. >= EmulateInfo->LimitGRAM)
  162. return (BufPtr +
  163. EmulateInfo->BytePerLine -
  164. EmulateInfo->LimitGRAM);
  165. else
  166. return (BufPtr + EmulateInfo->BytePerLine);
  167. }
  168. VOID
  169. memcpyGRAM(
  170. IN PCHAR TargetPtr,
  171. IN PCHAR SourcePtr,
  172. IN ULONG Length
  173. )
  174. /*++
  175. Routine Description:
  176. This routine is a memory copy for byte order.
  177. Arguments:
  178. TargetPtr - Pointer to target graphics buffer.
  179. SourcePtr - Pointer to source graphics buffer.
  180. Length - Fill length.
  181. Return Value:
  182. --*/
  183. {
  184. while (Length--)
  185. *TargetPtr++ = *SourcePtr++;
  186. }
  187. VOID
  188. memcpyGRAMOver(
  189. IN PCHAR TargetPtr,
  190. IN PCHAR SourcePtr,
  191. IN ULONG Length,
  192. IN PUCHAR FrameBufPtr,
  193. IN PEMULATE_BUFFER_INFORMATION EmulateInfo
  194. )
  195. /*++
  196. Routine Description:
  197. This routine move a graphics buffer.
  198. Arguments:
  199. TargetPtr - Pointer to target graphics buffer.
  200. SourcePtr - Pointer to source graphics buffer.
  201. Length - Fill length.
  202. Return Value:
  203. --*/
  204. {
  205. ULONG tmpLen;
  206. if ((ULONG)(SourcePtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
  207. tmpLen = EmulateInfo->LimitGRAM - (SourcePtr - FrameBufPtr);
  208. memcpyGRAM(TargetPtr, SourcePtr, tmpLen);
  209. TargetPtr += tmpLen;
  210. Length -= tmpLen;
  211. SourcePtr = FrameBufPtr;
  212. }
  213. if ((ULONG)(TargetPtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
  214. tmpLen = EmulateInfo->LimitGRAM - (TargetPtr - FrameBufPtr);
  215. memcpyGRAM(TargetPtr, SourcePtr, tmpLen);
  216. SourcePtr += tmpLen;
  217. Length -= tmpLen;
  218. TargetPtr = FrameBufPtr;
  219. }
  220. if (Length) {
  221. memcpyGRAM(TargetPtr, SourcePtr, Length);
  222. }
  223. }
  224. VOID
  225. MoveGRAM(
  226. IN PCHAR TargetPtr,
  227. IN PCHAR SourcePtr,
  228. IN ULONG Length,
  229. IN PUCHAR FrameBufPtr,
  230. IN PFSVGA_RESOURCE_INFORMATION ResourceInfo,
  231. IN PEMULATE_BUFFER_INFORMATION EmulateInfo
  232. )
  233. /*++
  234. Routine Description:
  235. This routine move a graphics buffer.
  236. Arguments:
  237. TargetPtr - Pointer to target graphics buffer.
  238. SourcePtr - Pointer to source graphics buffer.
  239. Length - Fill length.
  240. Return Value:
  241. none.
  242. --*/
  243. {
  244. PCHAR tmpSrc;
  245. PCHAR tmpTrg;
  246. ULONG tmpLen;
  247. //
  248. // Set copy mode of graphics register
  249. //
  250. SetGRAMCopyMode(ResourceInfo->PortList);
  251. if ((ULONG)(SourcePtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM ||
  252. (ULONG)(TargetPtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM ) {
  253. if (SourcePtr > TargetPtr) {
  254. memcpyGRAMOver(TargetPtr,SourcePtr,Length,FrameBufPtr,EmulateInfo);
  255. }
  256. else if ((ULONG)(TargetPtr - SourcePtr) >= Length) {
  257. memcpyGRAMOver(TargetPtr,SourcePtr,Length,FrameBufPtr,EmulateInfo);
  258. }
  259. else {
  260. if ((ULONG)(SourcePtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
  261. tmpLen = SourcePtr + Length - FrameBufPtr - EmulateInfo->LimitGRAM;
  262. tmpTrg = TargetPtr + Length - tmpLen - EmulateInfo->LimitGRAM;
  263. memcpyGRAM(tmpTrg, FrameBufPtr, tmpLen);
  264. Length -= tmpLen;
  265. }
  266. if ((ULONG)(TargetPtr + Length - FrameBufPtr) >= EmulateInfo->LimitGRAM) {
  267. tmpLen = TargetPtr + Length - FrameBufPtr - EmulateInfo->LimitGRAM;
  268. tmpSrc = SourcePtr + Length - tmpLen;
  269. memcpyGRAM(FrameBufPtr, tmpSrc, tmpLen);
  270. Length -= tmpLen;
  271. }
  272. if (Length) {
  273. memcpyGRAM(TargetPtr, SourcePtr, Length);
  274. }
  275. }
  276. }
  277. else {
  278. memcpyGRAM(TargetPtr, SourcePtr, Length);
  279. }
  280. SetGRAMWriteMode(ResourceInfo->PortList);
  281. }
  282. NTSTATUS
  283. FsgVgaInitializeHWFlags(
  284. PDEVICE_EXTENSION DeviceExtension
  285. )
  286. /*++
  287. Routine Description:
  288. This routine initialize the hardware scrolls flag and any values.
  289. Arguments:
  290. EmulateInfo - Pointer to screen emulate information structure.
  291. Return Value:
  292. --*/
  293. {
  294. ULONG Index;
  295. GetHardwareScrollReg(DeviceExtension->Resource.PortList,
  296. &DeviceExtension->EmulateInfo);
  297. DeviceExtension->EmulateInfo.BytePerLine =
  298. (USHORT)GetBytePerLine(Globals.Configuration.HardwareScroll);
  299. DeviceExtension->EmulateInfo.MaxScanLine =
  300. (USHORT)CalcGRAMScanLine(DeviceExtension->ScreenAndFont.ScreenSize.Y,
  301. DeviceExtension->ScreenAndFont.FontSize.Y);
  302. DeviceExtension->EmulateInfo.DeltaNextFontRow =
  303. DeviceExtension->EmulateInfo.BytePerLine * DeviceExtension->ScreenAndFont.FontSize.Y;
  304. if (Globals.Configuration.HardwareScroll & USE_LINE_COMPARE) {
  305. DeviceExtension->EmulateInfo.LimitGRAM =
  306. DeviceExtension->EmulateInfo.MaxScanLine * DeviceExtension->EmulateInfo.BytePerLine;
  307. }
  308. else {
  309. DeviceExtension->EmulateInfo.LimitGRAM = LIMIT_64K;
  310. }
  311. DeviceExtension->EmulateInfo.ColorFg = (UCHAR)-1;
  312. DeviceExtension->EmulateInfo.ColorBg = (UCHAR)-1;
  313. DeviceExtension->EmulateInfo.CursorAttributes.Enable = 0;
  314. DeviceExtension->EmulateInfo.ShowCursor = FALSE;
  315. SetGRAMWriteMode(DeviceExtension->Resource.PortList);
  316. return STATUS_SUCCESS;
  317. }
  318. NTSTATUS
  319. FsgCopyFrameBuffer(
  320. PDEVICE_EXTENSION DeviceExtension,
  321. PFSVIDEO_COPY_FRAME_BUFFER CopyFrameBuffer,
  322. ULONG inputBufferLength
  323. )
  324. /*++
  325. Routine Description:
  326. This routine copy the frame buffer.
  327. Arguments:
  328. DeviceExtension - Pointer to the miniport driver's device extension.
  329. CopyFrameBuffer - Pointer to the structure containing the information about the copy frame buffer.
  330. inputBufferLength - Length of the input buffer supplied by the user.
  331. Return Value:
  332. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  333. for the input data.
  334. STATUS_SUCCESS if the operation completed successfully.
  335. --*/
  336. {
  337. PUCHAR SourcePtr, TargetPtr;
  338. FsgInvertCursor(DeviceExtension,FALSE);
  339. SourcePtr = CalcGRAMAddress (CopyFrameBuffer->SrcScreen.Position,
  340. &DeviceExtension->CurrentMode,
  341. &DeviceExtension->ScreenAndFont,
  342. &DeviceExtension->EmulateInfo);
  343. TargetPtr = CalcGRAMAddress (CopyFrameBuffer->DestScreen.Position,
  344. &DeviceExtension->CurrentMode,
  345. &DeviceExtension->ScreenAndFont,
  346. &DeviceExtension->EmulateInfo);
  347. MoveGRAM (TargetPtr,
  348. SourcePtr,
  349. CopyFrameBuffer->SrcScreen.nNumberOfChars *
  350. DeviceExtension->ScreenAndFont.FontSize.Y,
  351. DeviceExtension->CurrentMode.VideoMemory.FrameBufferBase,
  352. &DeviceExtension->Resource,
  353. &DeviceExtension->EmulateInfo
  354. );
  355. FsgInvertCursor(DeviceExtension,TRUE);
  356. return STATUS_SUCCESS;
  357. }
  358. NTSTATUS
  359. FsgWriteToFrameBuffer(
  360. PDEVICE_EXTENSION DeviceExtension,
  361. PFSVIDEO_WRITE_TO_FRAME_BUFFER WriteFrameBuffer,
  362. ULONG inputBufferLength
  363. )
  364. /*++
  365. Routine Description:
  366. This routine write the frame buffer.
  367. Arguments:
  368. DeviceExtension - Pointer to the miniport driver's device extension.
  369. WriteFrameBuffer - Pointer to the structure containing the information about the write frame buffer.
  370. inputBufferLength - Length of the input buffer supplied by the user.
  371. Return Value:
  372. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  373. for the input data.
  374. STATUS_SUCCESS if the operation completed successfully.
  375. --*/
  376. {
  377. PCHAR_IMAGE_INFO pCharInfoUni = WriteFrameBuffer->SrcBuffer;
  378. PUCHAR TargetPtr;
  379. COORD Position = WriteFrameBuffer->DestScreen.Position;
  380. ULONG Length = WriteFrameBuffer->DestScreen.nNumberOfChars;
  381. COORD FontSize1 = DeviceExtension->ScreenAndFont.FontSize;
  382. COORD FontSize2;
  383. PVOID pCapBuffer = NULL;
  384. ULONG cCapBuffer = 0;
  385. BOOLEAN fDbcs = FALSE;
  386. NTSTATUS Status;
  387. FsgInvertCursor(DeviceExtension,FALSE);
  388. DeviceExtension->EmulateInfo.ColorFg = (UCHAR)-1;
  389. DeviceExtension->EmulateInfo.ColorBg = (UCHAR)-1;
  390. FontSize2 = FontSize1;
  391. FontSize2.X *= 2;
  392. cCapBuffer = CalcBitmapBufferSize(FontSize2,BYTE_ALIGN);
  393. pCapBuffer = ExAllocatePool(PagedPool, cCapBuffer);
  394. while (Length--)
  395. {
  396. if (pCharInfoUni->FontImageInfo.ImageBits != NULL)
  397. {
  398. try
  399. {
  400. fDbcs = (BOOLEAN)(!!(pCharInfoUni->CharInfo.Attributes & COMMON_LVB_SBCSDBCS));
  401. AlignCopyMemory((PVOID)pCapBuffer, // pDestBits
  402. BYTE_ALIGN, // dwDestAlign
  403. pCharInfoUni->FontImageInfo.ImageBits,// pSrcBits
  404. WORD_ALIGN, // dwSrcAlign
  405. fDbcs ? FontSize2 : FontSize1);
  406. TargetPtr = CalcGRAMAddress (Position,
  407. &DeviceExtension->CurrentMode,
  408. &DeviceExtension->ScreenAndFont,
  409. &DeviceExtension->EmulateInfo);
  410. if (fDbcs)
  411. {
  412. if (Length)
  413. {
  414. FsgWriteToScreen(TargetPtr, pCapBuffer, 2, fDbcs,
  415. pCharInfoUni->CharInfo.Attributes,
  416. (pCharInfoUni+1)->CharInfo.Attributes,
  417. DeviceExtension);
  418. }
  419. else
  420. {
  421. FsgWriteToScreen(TargetPtr, pCapBuffer, 2, FALSE,
  422. pCharInfoUni->CharInfo.Attributes,
  423. (USHORT)-1,
  424. DeviceExtension);
  425. }
  426. }
  427. else
  428. {
  429. FsgWriteToScreen(TargetPtr, pCapBuffer, 1, fDbcs,
  430. pCharInfoUni->CharInfo.Attributes,
  431. (USHORT)-1,
  432. DeviceExtension);
  433. }
  434. }
  435. except (EXCEPTION_EXECUTE_HANDLER)
  436. {
  437. }
  438. }
  439. if (fDbcs && Length)
  440. {
  441. Length--;
  442. Position.X += 2;
  443. pCharInfoUni += 2;
  444. }
  445. else
  446. {
  447. Position.X++;
  448. pCharInfoUni++;
  449. }
  450. }
  451. FsgInvertCursor(DeviceExtension,TRUE);
  452. if (pCapBuffer != NULL)
  453. ExFreePool(pCapBuffer);
  454. return STATUS_SUCCESS;
  455. }
  456. NTSTATUS
  457. FsgReverseMousePointer(
  458. PDEVICE_EXTENSION DeviceExtension,
  459. PFSVIDEO_REVERSE_MOUSE_POINTER MouseBuffer,
  460. ULONG inputBufferLength
  461. )
  462. /*++
  463. Routine Description:
  464. This routine reverse the frame buffer for mouse pointer.
  465. Arguments:
  466. DeviceExtension - Pointer to the miniport driver's device extension.
  467. MouseBuffer - Pointer to the structure containing the information about the mouse frame buffer.
  468. inputBufferLength - Length of the input buffer supplied by the user.
  469. Return Value:
  470. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  471. for the input data.
  472. STATUS_SUCCESS if the operation completed successfully.
  473. --*/
  474. {
  475. PUCHAR CurFrameBufPtr;
  476. COORD CursorPosition;
  477. COORD FontSize;
  478. SHORT i;
  479. BOOLEAN fOneMore = FALSE;
  480. FsgInvertCursor(DeviceExtension,FALSE);
  481. FontSize = DeviceExtension->ScreenAndFont.FontSize;
  482. CursorPosition.X = MouseBuffer->Screen.Position.X;
  483. CursorPosition.Y = MouseBuffer->Screen.Position.Y;
  484. if ( (0 <= CursorPosition.X &&
  485. CursorPosition.X < MouseBuffer->Screen.ScreenSize.X) &&
  486. (0 <= CursorPosition.Y &&
  487. CursorPosition.Y < MouseBuffer->Screen.ScreenSize.Y) )
  488. {
  489. switch (MouseBuffer->dwType)
  490. {
  491. case CHAR_TYPE_LEADING:
  492. if (CursorPosition.X != MouseBuffer->Screen.ScreenSize.X-1)
  493. {
  494. fOneMore = TRUE;
  495. }
  496. break;
  497. case CHAR_TYPE_TRAILING:
  498. if (CursorPosition.X != 0)
  499. {
  500. fOneMore = TRUE;
  501. CursorPosition.X--;
  502. }
  503. break;
  504. }
  505. CurFrameBufPtr = CalcGRAMAddress (CursorPosition,
  506. &DeviceExtension->CurrentMode,
  507. &DeviceExtension->ScreenAndFont,
  508. &DeviceExtension->EmulateInfo);
  509. //
  510. // Set invert mode of graphics register
  511. //
  512. SetGRAMInvertMode(DeviceExtension->Resource.PortList);
  513. /*
  514. * CursorAttributes.Width is bottom scan lines.
  515. */
  516. for (i=0 ; i < FontSize.Y; i++)
  517. {
  518. AccessGRAM_AND(CurFrameBufPtr, (UCHAR)-1);
  519. if (fOneMore)
  520. AccessGRAM_AND(CurFrameBufPtr+1, (UCHAR)-1);
  521. CurFrameBufPtr = NextGRAMRow(CurFrameBufPtr,
  522. &DeviceExtension->CurrentMode,
  523. &DeviceExtension->EmulateInfo);
  524. }
  525. SetGRAMWriteMode(DeviceExtension->Resource.PortList);
  526. }
  527. FsgInvertCursor(DeviceExtension,TRUE);
  528. return STATUS_SUCCESS;
  529. }
  530. NTSTATUS
  531. FsgInvertCursor(
  532. PDEVICE_EXTENSION DeviceExtension,
  533. BOOLEAN Invert
  534. )
  535. /*++
  536. Routine Description:
  537. This routine inverts the cursor.
  538. Arguments:
  539. DeviceExtension - Pointer to the miniport driver's device extension.
  540. Invert -
  541. Return Value:
  542. STATUS_INSUFFICIENT_BUFFER if the input buffer was not large enough
  543. for the input data.
  544. STATUS_SUCCESS if the operation completed successfully.
  545. --*/
  546. {
  547. PUCHAR CurFrameBufPtr;
  548. COORD CursorPosition;
  549. COORD FontSize;
  550. SHORT i;
  551. SHORT TopScanLine;
  552. BOOLEAN fOneMore = FALSE;
  553. if (DeviceExtension->EmulateInfo.ShowCursor == Invert)
  554. return STATUS_SUCCESS;
  555. DeviceExtension->EmulateInfo.ShowCursor = Invert;
  556. if (!(DeviceExtension->EmulateInfo.CursorAttributes.Enable))
  557. return STATUS_SUCCESS;
  558. FontSize = DeviceExtension->ScreenAndFont.FontSize;
  559. if (DeviceExtension->ScreenAndFont.ScreenSize.Y > 25)
  560. {
  561. TopScanLine = ((DeviceExtension->EmulateInfo.CursorAttributes.Height + 8) * 100 / 8) - 100;
  562. }
  563. else
  564. {
  565. TopScanLine = ((DeviceExtension->EmulateInfo.CursorAttributes.Height + 16) * 100 / 16) - 100;
  566. }
  567. TopScanLine = (FontSize.Y * TopScanLine) / 100;
  568. CursorPosition.X = DeviceExtension->EmulateInfo.CursorPosition.Coord.Column;
  569. CursorPosition.Y = DeviceExtension->EmulateInfo.CursorPosition.Coord.Row;
  570. if ( (0 <= CursorPosition.X &&
  571. CursorPosition.X < DeviceExtension->ScreenAndFont.ScreenSize.X) &&
  572. (0 <= CursorPosition.Y &&
  573. CursorPosition.Y < DeviceExtension->ScreenAndFont.ScreenSize.Y) )
  574. {
  575. switch (DeviceExtension->EmulateInfo.CursorPosition.dwType)
  576. {
  577. case CHAR_TYPE_LEADING:
  578. if (CursorPosition.X != DeviceExtension->ScreenAndFont.ScreenSize.X-1)
  579. {
  580. fOneMore = TRUE;
  581. }
  582. break;
  583. case CHAR_TYPE_TRAILING:
  584. if (CursorPosition.X != 0)
  585. {
  586. fOneMore = TRUE;
  587. CursorPosition.X--;
  588. }
  589. break;
  590. }
  591. CurFrameBufPtr = CalcGRAMAddress (CursorPosition,
  592. &DeviceExtension->CurrentMode,
  593. &DeviceExtension->ScreenAndFont,
  594. &DeviceExtension->EmulateInfo);
  595. /*
  596. * CursorAttributes.Height is top scan lines.
  597. */
  598. for (i = 0; i < TopScanLine; i++)
  599. {
  600. CurFrameBufPtr = NextGRAMRow(CurFrameBufPtr,
  601. &DeviceExtension->CurrentMode,
  602. &DeviceExtension->EmulateInfo);
  603. }
  604. //
  605. // Set invert mode of graphics register
  606. //
  607. SetGRAMInvertMode(DeviceExtension->Resource.PortList);
  608. /*
  609. * CursorAttributes.Width is bottom scan lines.
  610. */
  611. for ( ; i < FontSize.Y; i++)
  612. {
  613. AccessGRAM_AND(CurFrameBufPtr, (UCHAR)-1);
  614. if (fOneMore) {
  615. AccessGRAM_AND(CurFrameBufPtr+1, (UCHAR)-1);
  616. }
  617. CurFrameBufPtr = NextGRAMRow(CurFrameBufPtr,
  618. &DeviceExtension->CurrentMode,
  619. &DeviceExtension->EmulateInfo);
  620. }
  621. SetGRAMWriteMode(DeviceExtension->Resource.PortList);
  622. }
  623. return STATUS_SUCCESS;
  624. }
  625. NTSTATUS
  626. FsgWriteToScreen(
  627. PUCHAR FrameBuffer,
  628. PUCHAR BitmapBuffer,
  629. ULONG cjBytes,
  630. BOOLEAN fDbcs,
  631. USHORT Attributes1,
  632. USHORT Attributes2,
  633. PDEVICE_EXTENSION DeviceExtension
  634. )
  635. {
  636. USHORT Index;
  637. PCHAR CurFrameBufPtrTmp;
  638. PCHAR CurFrameBufPtr2nd;
  639. PUSHORT CurFrameBufPtrWord;
  640. PUCHAR BitmapBufferTmp;
  641. #ifdef LATER_HIGH_SPPED_VRAM_ACCESS // kazum
  642. if (! IsGRAMRowOver(FrameBuffer,fDBCS,DeviceExtension)) {
  643. if (!fDbcs) {
  644. if (cjBytes == 2)
  645. BitmapBuffer++;
  646. (*WriteGramInfo->pfnWriteFontToByteGRAM)(WriteGramInfo);
  647. }
  648. else if (cjBytes == 2 && fDBCS) {
  649. if (DeviceExtension->Configuration.EmulationMode & ENABLE_WORD_WRITE_VRAM) {
  650. (*WriteGramInfo->pfnWriteFontToFirstWordGRAM)(WriteGramInfo);
  651. }
  652. else {
  653. (*WriteGramInfo->pfnWriteFontToWordGRAM)(WriteGramInfo);
  654. }
  655. }
  656. }
  657. else
  658. #endif // LATER_HIGH_SPPED_VRAM_ACCESS // kazum
  659. try
  660. {
  661. set_opaque_bkgnd_proc(DeviceExtension->Resource.PortList,
  662. &DeviceExtension->EmulateInfo,
  663. FrameBuffer,Attributes1);
  664. if (!fDbcs) {
  665. CurFrameBufPtrTmp = FrameBuffer;
  666. if (cjBytes == 2)
  667. BitmapBuffer++;
  668. for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
  669. *CurFrameBufPtrTmp = *BitmapBuffer;
  670. BitmapBuffer += cjBytes;
  671. CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
  672. &DeviceExtension->CurrentMode,
  673. &DeviceExtension->EmulateInfo);
  674. }
  675. }
  676. else if (cjBytes == 2 && fDbcs) {
  677. if ((Globals.Configuration.EmulationMode & ENABLE_WORD_WRITE_VRAM) &&
  678. !((ULONG)FrameBuffer & 1) &&
  679. (Attributes2 != -1) &&
  680. (Attributes1 == Attributes2)
  681. ) {
  682. CurFrameBufPtrWord = (PUSHORT)FrameBuffer;
  683. for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
  684. *CurFrameBufPtrWord = *((PUSHORT)BitmapBuffer);
  685. BitmapBuffer += cjBytes;
  686. CurFrameBufPtrWord=(PUSHORT)NextGRAMRow((PCHAR)CurFrameBufPtrWord,
  687. &DeviceExtension->CurrentMode,
  688. &DeviceExtension->EmulateInfo);
  689. }
  690. }
  691. else {
  692. CurFrameBufPtrTmp = FrameBuffer;
  693. CurFrameBufPtr2nd = FrameBuffer + 1;
  694. BitmapBufferTmp = BitmapBuffer + 1;
  695. for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
  696. *CurFrameBufPtrTmp = *BitmapBuffer;
  697. BitmapBuffer += cjBytes;
  698. CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
  699. &DeviceExtension->CurrentMode,
  700. &DeviceExtension->EmulateInfo);
  701. }
  702. if (Attributes2 != -1 &&
  703. Attributes1 != Attributes2) {
  704. set_opaque_bkgnd_proc(DeviceExtension->Resource.PortList,
  705. &DeviceExtension->EmulateInfo,
  706. FrameBuffer,Attributes2);
  707. }
  708. for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
  709. *CurFrameBufPtr2nd = *BitmapBufferTmp;
  710. BitmapBufferTmp += cjBytes;
  711. CurFrameBufPtr2nd=NextGRAMRow(CurFrameBufPtr2nd,
  712. &DeviceExtension->CurrentMode,
  713. &DeviceExtension->EmulateInfo);
  714. }
  715. }
  716. }
  717. }
  718. except (EXCEPTION_EXECUTE_HANDLER)
  719. {
  720. }
  721. if (Attributes1 & COMMON_LVB_MASK)
  722. {
  723. FsgWriteToScreenCommonLVB(FrameBuffer,
  724. Attributes1,
  725. DeviceExtension);
  726. }
  727. if ((Attributes2 != (USHORT)-1) && (Attributes2 & COMMON_LVB_MASK))
  728. {
  729. FsgWriteToScreenCommonLVB(FrameBuffer+1,
  730. Attributes2,
  731. DeviceExtension);
  732. }
  733. return STATUS_SUCCESS;
  734. }
  735. NTSTATUS
  736. FsgWriteToScreenCommonLVB(
  737. PUCHAR FrameBuffer,
  738. USHORT Attributes,
  739. PDEVICE_EXTENSION DeviceExtension
  740. )
  741. {
  742. USHORT Index;
  743. PUCHAR CurFrameBufPtrTmp;
  744. try
  745. {
  746. if (Attributes & COMMON_LVB_UNDERSCORE)
  747. {
  748. set_opaque_bkgnd_proc(DeviceExtension->Resource.PortList,
  749. &DeviceExtension->EmulateInfo,
  750. FrameBuffer,Attributes);
  751. CurFrameBufPtrTmp = FrameBuffer;
  752. for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y - 1; Index++) {
  753. CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
  754. &DeviceExtension->CurrentMode,
  755. &DeviceExtension->EmulateInfo);
  756. }
  757. *CurFrameBufPtrTmp = 0xff;
  758. }
  759. if (Attributes & COMMON_LVB_GRID_HORIZONTAL)
  760. {
  761. ColorSetDirect(DeviceExtension->Resource.PortList,
  762. FrameBuffer,
  763. FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED,
  764. 0);
  765. *FrameBuffer = 0xff;
  766. }
  767. if ( (Attributes & COMMON_LVB_GRID_LVERTICAL) ||
  768. (Attributes & COMMON_LVB_GRID_RVERTICAL) )
  769. {
  770. UCHAR mask = ((Attributes & COMMON_LVB_GRID_LVERTICAL) ? 0x80 : 0) +
  771. ((Attributes & COMMON_LVB_GRID_RVERTICAL) ? 0x01 : 0);
  772. ColorSetGridMask(DeviceExtension->Resource.PortList,
  773. mask
  774. );
  775. CurFrameBufPtrTmp = FrameBuffer;
  776. for (Index=0; Index < DeviceExtension->ScreenAndFont.FontSize.Y; Index++) {
  777. AccessGRAM_RW(CurFrameBufPtrTmp, mask);
  778. CurFrameBufPtrTmp=NextGRAMRow(CurFrameBufPtrTmp,
  779. &DeviceExtension->CurrentMode,
  780. &DeviceExtension->EmulateInfo);
  781. }
  782. SetGRAMWriteMode(DeviceExtension->Resource.PortList);
  783. }
  784. DeviceExtension->EmulateInfo.ColorFg = (UCHAR)-1;
  785. DeviceExtension->EmulateInfo.ColorBg = (UCHAR)-1;
  786. }
  787. except (EXCEPTION_EXECUTE_HANDLER)
  788. {
  789. }
  790. return STATUS_SUCCESS;
  791. }
  792. #pragma optimize("",off)
  793. /*
  794. * because, frame buffer memory access is need by write/read.
  795. */
  796. UCHAR
  797. AccessGRAM_WR(
  798. PUCHAR FrameBuffer,
  799. UCHAR write
  800. )
  801. {
  802. *FrameBuffer = write;
  803. return *FrameBuffer;
  804. }
  805. UCHAR
  806. AccessGRAM_RW(
  807. PUCHAR FrameBuffer,
  808. UCHAR write
  809. )
  810. {
  811. UCHAR tmp;
  812. tmp = *FrameBuffer;
  813. *FrameBuffer = write;
  814. return tmp;
  815. }
  816. UCHAR
  817. AccessGRAM_AND(
  818. PUCHAR FrameBuffer,
  819. UCHAR write
  820. )
  821. {
  822. return *FrameBuffer &= write;
  823. }
  824. #pragma optimize("",on)