|
|
1.1 ! root 1: //--------------------------------------------------------------------------- ! 2: /*++ ! 3: ! 4: Copyright (c) 1992 Microsoft Corporation ! 5: ! 6: Module Name: ! 7: ! 8: cirrus.c ! 9: ! 10: Abstract: ! 11: ! 12: This is the miniport driver for the Cirrus Logic 6410/6420/542x VGA's. ! 13: ! 14: Environment: ! 15: ! 16: kernel mode only ! 17: ! 18: Notes: ! 19: ! 20: Revision History: ! 21: ! 22: --*/ ! 23: //--------------------------------------------------------------------------- ! 24: ! 25: #include "dderror.h" ! 26: #include "devioctl.h" ! 27: #include "miniport.h" ! 28: ! 29: #include "ntddvdeo.h" ! 30: #include "video.h" ! 31: #include "cirrus.h" ! 32: #include "cl_data.h" ! 33: ! 34: //--------------------------------------------------------------------------- ! 35: // ! 36: // Function declarations ! 37: // ! 38: // Functions that start with 'VGA' are entry points for the OS port driver. ! 39: // ! 40: ! 41: VP_STATUS ! 42: VgaFindAdapter( ! 43: PVOID HwDeviceExtension, ! 44: PVOID HwContext, ! 45: PWSTR ArgumentString, ! 46: PVIDEO_PORT_CONFIG_INFO ConfigInfo, ! 47: PUCHAR Again ! 48: ); ! 49: ! 50: BOOLEAN ! 51: VgaInitialize( ! 52: PVOID HwDeviceExtension ! 53: ); ! 54: ! 55: BOOLEAN ! 56: VgaStartIO( ! 57: PVOID HwDeviceExtension, ! 58: PVIDEO_REQUEST_PACKET RequestPacket ! 59: ); ! 60: ! 61: // ! 62: // Private function prototypes. ! 63: // ! 64: ! 65: VP_STATUS ! 66: VgaQueryAvailableModes( ! 67: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 68: PVIDEO_MODE_INFORMATION ModeInformation, ! 69: ULONG ModeInformationSize, ! 70: PULONG OutputSize ! 71: ); ! 72: ! 73: VP_STATUS ! 74: VgaQueryNumberOfAvailableModes( ! 75: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 76: PVIDEO_NUM_MODES NumModes, ! 77: ULONG NumModesSize, ! 78: PULONG OutputSize ! 79: ); ! 80: ! 81: VP_STATUS ! 82: VgaQueryCurrentMode( ! 83: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 84: PVIDEO_MODE_INFORMATION ModeInformation, ! 85: ULONG ModeInformationSize, ! 86: PULONG OutputSize ! 87: ); ! 88: ! 89: VP_STATUS ! 90: VgaSetMode( ! 91: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 92: PVIDEO_MODE Mode, ! 93: ULONG ModeSize ! 94: ); ! 95: ! 96: VP_STATUS ! 97: VgaLoadAndSetFont( ! 98: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 99: PVIDEO_LOAD_FONT_INFORMATION FontInformation, ! 100: ULONG FontInformationSize ! 101: ); ! 102: ! 103: VP_STATUS ! 104: VgaQueryCursorPosition( ! 105: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 106: PVIDEO_CURSOR_POSITION CursorPosition, ! 107: ULONG CursorPositionSize, ! 108: PULONG OutputSize ! 109: ); ! 110: ! 111: VP_STATUS ! 112: VgaSetCursorPosition( ! 113: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 114: PVIDEO_CURSOR_POSITION CursorPosition, ! 115: ULONG CursorPositionSize ! 116: ); ! 117: ! 118: VP_STATUS ! 119: VgaQueryCursorAttributes( ! 120: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 121: PVIDEO_CURSOR_ATTRIBUTES CursorAttributes, ! 122: ULONG CursorAttributesSize, ! 123: PULONG OutputSize ! 124: ); ! 125: ! 126: VP_STATUS ! 127: VgaSetCursorAttributes( ! 128: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 129: PVIDEO_CURSOR_ATTRIBUTES CursorAttributes, ! 130: ULONG CursorAttributesSize ! 131: ); ! 132: ! 133: BOOLEAN ! 134: VgaIsPresent( ! 135: PHW_DEVICE_EXTENSION HwDeviceExtension ! 136: ); ! 137: ! 138: BOOLEAN ! 139: CirrusLogicIsPresent( ! 140: PHW_DEVICE_EXTENSION HwDeviceExtension ! 141: ); ! 142: ! 143: ULONG ! 144: CirrusFindVmemSize( ! 145: PHW_DEVICE_EXTENSION HwDeviceExtension ! 146: ); ! 147: ! 148: VOID ! 149: CirrusValidateModes( ! 150: PHW_DEVICE_EXTENSION HwDeviceExtension ! 151: ); ! 152: ! 153: VOID ! 154: SetCirrusBanking( ! 155: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 156: USHORT BankNumber ! 157: ); ! 158: ! 159: USHORT ! 160: CirrusFind6410DisplayType( ! 161: PHW_DEVICE_EXTENSION HwDeviceExtension ! 162: ); ! 163: ! 164: BOOLEAN ! 165: CirrusFind6340( ! 166: PHW_DEVICE_EXTENSION HwDeviceExtension ! 167: ); ! 168: ! 169: VOID ! 170: VgaInterpretCmdStream( ! 171: PVOID HwDeviceExtension, ! 172: PUSHORT pusCmdStream ! 173: ); ! 174: ! 175: VP_STATUS ! 176: VgaSetPaletteReg( ! 177: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 178: PVIDEO_PALETTE_DATA PaletteBuffer, ! 179: ULONG PaletteBufferSize ! 180: ); ! 181: ! 182: VP_STATUS ! 183: VgaSetColorLookup( ! 184: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 185: PVIDEO_CLUT ClutBuffer, ! 186: ULONG ClutBufferSize ! 187: ); ! 188: ! 189: VP_STATUS ! 190: VgaRestoreHardwareState( ! 191: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 192: PVIDEO_HARDWARE_STATE HardwareState, ! 193: ULONG HardwareStateSize ! 194: ); ! 195: ! 196: VP_STATUS ! 197: VgaSaveHardwareState( ! 198: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 199: PVIDEO_HARDWARE_STATE HardwareState, ! 200: ULONG HardwareStateSize, ! 201: PULONG OutputSize ! 202: ); ! 203: ! 204: VP_STATUS ! 205: VgaGetBankSelectCode( ! 206: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 207: PVIDEO_BANK_SELECT BankSelect, ! 208: ULONG BankSelectSize, ! 209: PULONG OutputSize ! 210: ); ! 211: ! 212: ! 213: //--------------------------------------------------------------------------- ! 214: ULONG ! 215: DriverEntry( ! 216: PVOID Context1, ! 217: PVOID Context2 ! 218: ) ! 219: ! 220: /*++ ! 221: ! 222: Routine Description: ! 223: ! 224: Installable driver initialization entry point. ! 225: This entry point is called directly by the I/O system. ! 226: ! 227: Arguments: ! 228: ! 229: Context1 - First context value passed by the operating system. This is ! 230: the value with which the miniport driver calls VideoPortInitialize(). ! 231: ! 232: Context2 - Second context value passed by the operating system. This is ! 233: the value with which the miniport driver calls VideoPortInitialize(). ! 234: ! 235: Return Value: ! 236: ! 237: Status from VideoPortInitialize() ! 238: ! 239: --*/ ! 240: ! 241: { ! 242: ! 243: VIDEO_HW_INITIALIZATION_DATA hwInitData; ! 244: ULONG status; ! 245: ULONG initializationStatus; ! 246: ! 247: // ! 248: // Zero out structure. ! 249: // ! 250: ! 251: VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA)); ! 252: ! 253: // ! 254: // Specify sizes of structure and extension. ! 255: // ! 256: ! 257: hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA); ! 258: ! 259: // ! 260: // Set entry points. ! 261: // ! 262: ! 263: hwInitData.HwFindAdapter = VgaFindAdapter; ! 264: hwInitData.HwInitialize = VgaInitialize; ! 265: hwInitData.HwInterrupt = NULL; ! 266: hwInitData.HwStartIO = VgaStartIO; ! 267: ! 268: // ! 269: // Determine the size we require for the device extension. ! 270: // ! 271: ! 272: hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION); ! 273: ! 274: // ! 275: // Always start with parameters for device0 in this case. ! 276: // We can leave it like this since we know we will only ever find one ! 277: // VGA type adapter in a machine. ! 278: // ! 279: ! 280: // hwInitData.StartingDeviceNumber = 0; ! 281: ! 282: // ! 283: // Once all the relevant information has been stored, call the video ! 284: // port driver to do the initialization. ! 285: // For this device we will repeat this call three times, for ISA, EISA ! 286: // and MCA. ! 287: // We will return the minimum of all return values. ! 288: // ! 289: ! 290: hwInitData.AdapterInterfaceType = Isa; ! 291: ! 292: initializationStatus = VideoPortInitialize(Context1, ! 293: Context2, ! 294: &hwInitData, ! 295: NULL); ! 296: ! 297: hwInitData.AdapterInterfaceType = Eisa; ! 298: ! 299: status = VideoPortInitialize(Context1, ! 300: Context2, ! 301: &hwInitData, ! 302: NULL); ! 303: ! 304: if (initializationStatus > status) { ! 305: initializationStatus = status; ! 306: } ! 307: ! 308: hwInitData.AdapterInterfaceType = MicroChannel; ! 309: ! 310: status = VideoPortInitialize(Context1, ! 311: Context2, ! 312: &hwInitData, ! 313: NULL); ! 314: ! 315: if (initializationStatus > status) { ! 316: initializationStatus = status; ! 317: } ! 318: ! 319: return initializationStatus; ! 320: ! 321: } // end DriverEntry() ! 322: ! 323: //--------------------------------------------------------------------------- ! 324: VP_STATUS ! 325: VgaFindAdapter( ! 326: PVOID HwDeviceExtension, ! 327: PVOID HwContext, ! 328: PWSTR ArgumentString, ! 329: PVIDEO_PORT_CONFIG_INFO ConfigInfo, ! 330: PUCHAR Again ! 331: ) ! 332: ! 333: /*++ ! 334: ! 335: Routine Description: ! 336: ! 337: This routine is called to determine if the adapter for this driver ! 338: is present in the system. ! 339: If it is present, the function fills out some information describing ! 340: the adapter. ! 341: ! 342: Arguments: ! 343: ! 344: HwDeviceExtension - Supplies the miniport driver's adapter storage. This ! 345: storage is initialized to zero before this call. ! 346: ! 347: HwContext - Supplies the context value which was passed to ! 348: VideoPortInitialize(). ! 349: ! 350: ArgumentString - Supplies a NULL terminated ASCII string. This string ! 351: originates from the user. ! 352: ! 353: ConfigInfo - Returns the configuration information structure which is ! 354: filled by the miniport driver. This structure is initialized with ! 355: any known configuration information (such as SystemIoBusNumber) by ! 356: the port driver. Where possible, drivers should have one set of ! 357: defaults which do not require any supplied configuration information. ! 358: ! 359: Again - Indicates if the miniport driver wants the port driver to call ! 360: its VIDEO_HW_FIND_ADAPTER function again with a new device extension ! 361: and the same config info. This is used by the miniport drivers which ! 362: can search for several adapters on a bus. ! 363: ! 364: Return Value: ! 365: ! 366: This routine must return: ! 367: ! 368: NO_ERROR - Indicates a host adapter was found and the ! 369: configuration information was successfully determined. ! 370: ! 371: ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an ! 372: error obtaining the configuration information. If possible an error ! 373: should be logged. ! 374: ! 375: ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the ! 376: supplied configuration information. ! 377: ! 378: --*/ ! 379: ! 380: { ! 381: ! 382: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 383: VP_STATUS status; ! 384: ! 385: // ! 386: // Make sure the size of the structure is at least as large as what we ! 387: // are expecting (check version of the config info structure). ! 388: // ! 389: ! 390: if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) { ! 391: ! 392: return ERROR_INVALID_PARAMETER; ! 393: ! 394: } ! 395: ! 396: // ! 397: // No interrupt information is necessary. ! 398: // ! 399: ! 400: // ! 401: // Check to see if there is a hardware resource conflict. ! 402: // ! 403: ! 404: status = VideoPortVerifyAccessRanges(HwDeviceExtension, ! 405: NUM_VGA_ACCESS_RANGES, ! 406: VgaAccessRange); ! 407: ! 408: if (status != NO_ERROR) { ! 409: ! 410: return status; ! 411: ! 412: } ! 413: ! 414: // ! 415: // Get logical IO port addresses. ! 416: // ! 417: ! 418: if ( (hwDeviceExtension->IOAddress = ! 419: VideoPortGetDeviceBase(hwDeviceExtension, ! 420: VgaAccessRange->RangeStart, ! 421: VGA_MAX_IO_PORT - VGA_BASE_IO_PORT + 1, ! 422: TRUE)) == NULL) { ! 423: ! 424: VideoDebugPrint((2, "VgaFindAdapter - Fail to get io address\n")); ! 425: ! 426: return ERROR_INVALID_PARAMETER; ! 427: ! 428: } ! 429: ! 430: // ! 431: // Determine whether a VGA is present. ! 432: // ! 433: ! 434: if (!VgaIsPresent(hwDeviceExtension)) { ! 435: ! 436: return ERROR_DEV_NOT_EXIST; ! 437: ! 438: } ! 439: ! 440: // ! 441: // Pass a pointer to the emulator range we are using. ! 442: // ! 443: ! 444: ConfigInfo->NumEmulatorAccessEntries = VGA_NUM_EMULATOR_ACCESS_ENTRIES; ! 445: ConfigInfo->EmulatorAccessEntries = VgaEmulatorAccessEntries; ! 446: ConfigInfo->EmulatorAccessEntriesContext = (ULONG) hwDeviceExtension; ! 447: ! 448: ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart = MEM_VGA; ! 449: ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000; ! 450: ConfigInfo->VdmPhysicalVideoMemoryLength = MEM_VGA_SIZE; ! 451: ! 452: // ! 453: // Minimum size of the buffer required to store the hardware state ! 454: // information returned by IOCTL_VIDEO_SAVE_HARDWARE_STATE. ! 455: // ! 456: ! 457: ConfigInfo->HardwareStateSize = VGA_TOTAL_STATE_SIZE; ! 458: ! 459: // ! 460: // Video memory information ! 461: // ! 462: ! 463: hwDeviceExtension->PhysicalVideoMemoryBase.HighPart = 0x00000000; ! 464: hwDeviceExtension->PhysicalVideoMemoryBase.LowPart = MEM_VGA; ! 465: hwDeviceExtension->PhysicalVideoMemoryLength = MEM_VGA_SIZE; ! 466: ! 467: // ! 468: // Map the video memory into the system virtual address space so we can ! 469: // clear it out and use it for save and restore. ! 470: // ! 471: ! 472: if ( (hwDeviceExtension->VideoMemoryAddress = ! 473: VideoPortGetDeviceBase(hwDeviceExtension, ! 474: hwDeviceExtension->PhysicalVideoMemoryBase, ! 475: hwDeviceExtension->PhysicalVideoMemoryLength, FALSE)) == NULL) { ! 476: ! 477: VideoDebugPrint((1, "VgaFindAdapter - Fail to get memory address\n")); ! 478: ! 479: return ERROR_INVALID_PARAMETER; ! 480: ! 481: } ! 482: // ! 483: // now that we have the video memory address in portected mode, lets do ! 484: // the required video card initialization. We will try to detect a Cirrus ! 485: // Logic chipset... ! 486: // ! 487: // ! 488: // Determine whether an CL6410/6420/542x is present. ! 489: // ! 490: ! 491: if (!CirrusLogicIsPresent(hwDeviceExtension)) { ! 492: ! 493: return ERROR_DEV_NOT_EXIST; ! 494: ! 495: } ! 496: ! 497: // ! 498: // Indicate we do not wish to be called again for another initialization. ! 499: // ! 500: ! 501: *Again = 0; ! 502: ! 503: // ! 504: // Indicate a successful completion status. ! 505: // ! 506: ! 507: return NO_ERROR; ! 508: ! 509: } // VgaFindAdapter() ! 510: ! 511: //--------------------------------------------------------------------------- ! 512: BOOLEAN ! 513: VgaInitialize( ! 514: PVOID HwDeviceExtension ! 515: ) ! 516: ! 517: /*++ ! 518: ! 519: Routine Description: ! 520: ! 521: This routine does one time initialization of the device. ! 522: ! 523: Arguments: ! 524: ! 525: HwDeviceExtension - Pointer to the miniport driver's adapter information. ! 526: ! 527: Return Value: ! 528: ! 529: None. ! 530: ! 531: --*/ ! 532: ! 533: { ! 534: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 535: ! 536: // ! 537: // set up the default cursor position and type. ! 538: // ! 539: ! 540: hwDeviceExtension->CursorPosition.Column = 0; ! 541: hwDeviceExtension->CursorPosition.Row = 0; ! 542: hwDeviceExtension->CursorTopScanLine = 0; ! 543: hwDeviceExtension->CursorBottomScanLine = 31; ! 544: hwDeviceExtension->CursorEnable = TRUE; ! 545: ! 546: return TRUE; ! 547: ! 548: } // VgaInitialize() ! 549: ! 550: //--------------------------------------------------------------------------- ! 551: BOOLEAN ! 552: VgaStartIO( ! 553: PVOID HwDeviceExtension, ! 554: PVIDEO_REQUEST_PACKET RequestPacket ! 555: ) ! 556: ! 557: /*++ ! 558: ! 559: Routine Description: ! 560: ! 561: This routine is the main execution routine for the miniport driver. It ! 562: accepts a Video Request Packet, performs the request, and then returns ! 563: with the appropriate status. ! 564: ! 565: Arguments: ! 566: ! 567: HwDeviceExtension - Pointer to the miniport driver's adapter information. ! 568: ! 569: RequestPacket - Pointer to the video request packet. This structure ! 570: contains all the parameters passed to the VideoIoControl function. ! 571: ! 572: Return Value: ! 573: ! 574: This routine will return error codes from the various support routines ! 575: and will also return ERROR_INSUFFICIENT_BUFFER for incorrectly sized ! 576: buffers and ERROR_INVALID_FUNCTION for unsupported functions. ! 577: ! 578: --*/ ! 579: ! 580: { ! 581: PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension; ! 582: VP_STATUS status; ! 583: VIDEO_MODE videoMode; ! 584: PVIDEO_MEMORY_INFORMATION memoryInformation; ! 585: ULONG inIoSpace; ! 586: ! 587: // ! 588: // Switch on the IoContolCode in the RequestPacket. It indicates which ! 589: // function must be performed by the driver. ! 590: // ! 591: ! 592: switch (RequestPacket->IoControlCode) { ! 593: ! 594: ! 595: case IOCTL_VIDEO_MAP_VIDEO_MEMORY: ! 596: ! 597: VideoDebugPrint((2, "VgaStartIO - MapVideoMemory\n")); ! 598: ! 599: if ( (RequestPacket->OutputBufferLength < ! 600: (RequestPacket->StatusBlock->Information = ! 601: sizeof(VIDEO_MEMORY_INFORMATION))) || ! 602: (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) { ! 603: ! 604: status = ERROR_INSUFFICIENT_BUFFER; ! 605: } ! 606: ! 607: memoryInformation = RequestPacket->OutputBuffer; ! 608: ! 609: memoryInformation->VideoRamBase = ((PVIDEO_MEMORY) ! 610: (RequestPacket->InputBuffer))->RequestedVirtualAddress; ! 611: ! 612: memoryInformation->VideoRamLength = ! 613: hwDeviceExtension->PhysicalVideoMemoryLength; ! 614: ! 615: inIoSpace = 0; ! 616: ! 617: status = VideoPortMapMemory(hwDeviceExtension, ! 618: hwDeviceExtension->PhysicalVideoMemoryBase, ! 619: &(memoryInformation->VideoRamLength), ! 620: &inIoSpace, ! 621: &(memoryInformation->VideoRamBase)); ! 622: ! 623: memoryInformation->FrameBufferBase = ! 624: ((PUCHAR) (memoryInformation->VideoRamBase)) + ! 625: (hwDeviceExtension->PhysicalFrameBase.LowPart - ! 626: hwDeviceExtension->PhysicalVideoMemoryBase.LowPart); ! 627: ! 628: memoryInformation->FrameBufferLength = ! 629: hwDeviceExtension->PhysicalFrameLength; ! 630: ! 631: break; ! 632: ! 633: ! 634: case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY: ! 635: ! 636: VideoDebugPrint((2, "VgaStartIO - UnMapVideoMemory\n")); ! 637: ! 638: if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) { ! 639: ! 640: status = ERROR_INSUFFICIENT_BUFFER; ! 641: } ! 642: ! 643: status = VideoPortUnmapMemory(hwDeviceExtension, ! 644: ((PVIDEO_MEMORY) ! 645: (RequestPacket->InputBuffer))-> ! 646: RequestedVirtualAddress, ! 647: 0); ! 648: ! 649: break; ! 650: ! 651: ! 652: case IOCTL_VIDEO_QUERY_AVAIL_MODES: ! 653: ! 654: VideoDebugPrint((2, "VgaStartIO - QueryAvailableModes\n")); ! 655: ! 656: status = VgaQueryAvailableModes(HwDeviceExtension, ! 657: (PVIDEO_MODE_INFORMATION) ! 658: RequestPacket->OutputBuffer, ! 659: RequestPacket->OutputBufferLength, ! 660: &RequestPacket->StatusBlock->Information); ! 661: ! 662: break; ! 663: ! 664: ! 665: case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES: ! 666: ! 667: VideoDebugPrint((2, "VgaStartIO - QueryNumAvailableModes\n")); ! 668: ! 669: status = VgaQueryNumberOfAvailableModes(HwDeviceExtension, ! 670: (PVIDEO_NUM_MODES) ! 671: RequestPacket->OutputBuffer, ! 672: RequestPacket->OutputBufferLength, ! 673: &RequestPacket->StatusBlock->Information); ! 674: ! 675: break; ! 676: ! 677: ! 678: case IOCTL_VIDEO_QUERY_CURRENT_MODE: ! 679: ! 680: VideoDebugPrint((2, "VgaStartIO - QueryCurrentMode\n")); ! 681: ! 682: status = VgaQueryCurrentMode(HwDeviceExtension, ! 683: (PVIDEO_MODE_INFORMATION) RequestPacket->OutputBuffer, ! 684: RequestPacket->OutputBufferLength, ! 685: &RequestPacket->StatusBlock->Information); ! 686: ! 687: break; ! 688: ! 689: ! 690: case IOCTL_VIDEO_SET_CURRENT_MODE: ! 691: ! 692: VideoDebugPrint((2, "VgaStartIO - SetCurrentModes\n")); ! 693: ! 694: status = VgaSetMode(HwDeviceExtension, ! 695: (PVIDEO_MODE) RequestPacket->InputBuffer, ! 696: RequestPacket->InputBufferLength); ! 697: ! 698: break; ! 699: ! 700: ! 701: case IOCTL_VIDEO_RESET_DEVICE: ! 702: ! 703: VideoDebugPrint((2, "VgaStartIO - Reset Device\n")); ! 704: ! 705: videoMode.RequestedMode = DEFAULT_MODE; ! 706: ! 707: status = VgaSetMode(HwDeviceExtension, ! 708: (PVIDEO_MODE) &videoMode, ! 709: sizeof(videoMode)); ! 710: ! 711: break; ! 712: ! 713: ! 714: case IOCTL_VIDEO_LOAD_AND_SET_FONT: ! 715: ! 716: VideoDebugPrint((2, "VgaStartIO - LoadAndSetFont\n")); ! 717: ! 718: status = VgaLoadAndSetFont(HwDeviceExtension, ! 719: (PVIDEO_LOAD_FONT_INFORMATION) RequestPacket->InputBuffer, ! 720: RequestPacket->InputBufferLength); ! 721: ! 722: break; ! 723: ! 724: ! 725: case IOCTL_VIDEO_QUERY_CURSOR_POSITION: ! 726: ! 727: VideoDebugPrint((2, "VgaStartIO - QueryCursorPosition\n")); ! 728: ! 729: status = VgaQueryCursorPosition(HwDeviceExtension, ! 730: (PVIDEO_CURSOR_POSITION) RequestPacket->OutputBuffer, ! 731: RequestPacket->OutputBufferLength, ! 732: &RequestPacket->StatusBlock->Information); ! 733: ! 734: break; ! 735: ! 736: ! 737: case IOCTL_VIDEO_SET_CURSOR_POSITION: ! 738: ! 739: VideoDebugPrint((2, "VgaStartIO - SetCursorPosition\n")); ! 740: ! 741: status = VgaSetCursorPosition(HwDeviceExtension, ! 742: (PVIDEO_CURSOR_POSITION) ! 743: RequestPacket->InputBuffer, ! 744: RequestPacket->InputBufferLength); ! 745: ! 746: break; ! 747: ! 748: ! 749: case IOCTL_VIDEO_QUERY_CURSOR_ATTR: ! 750: ! 751: VideoDebugPrint((2, "VgaStartIO - QueryCursorAttributes\n")); ! 752: ! 753: status = VgaQueryCursorAttributes(HwDeviceExtension, ! 754: (PVIDEO_CURSOR_ATTRIBUTES) RequestPacket->OutputBuffer, ! 755: RequestPacket->OutputBufferLength, ! 756: &RequestPacket->StatusBlock->Information); ! 757: ! 758: break; ! 759: ! 760: ! 761: case IOCTL_VIDEO_SET_CURSOR_ATTR: ! 762: ! 763: VideoDebugPrint((2, "VgaStartIO - SetCursorAttributes\n")); ! 764: ! 765: status = VgaSetCursorAttributes(HwDeviceExtension, ! 766: (PVIDEO_CURSOR_ATTRIBUTES) RequestPacket->InputBuffer, ! 767: RequestPacket->InputBufferLength); ! 768: ! 769: break; ! 770: ! 771: ! 772: case IOCTL_VIDEO_SET_PALETTE_REGISTERS: ! 773: ! 774: VideoDebugPrint((2, "VgaStartIO - SetPaletteRegs\n")); ! 775: ! 776: status = VgaSetPaletteReg(HwDeviceExtension, ! 777: (PVIDEO_PALETTE_DATA) RequestPacket->InputBuffer, ! 778: RequestPacket->InputBufferLength); ! 779: ! 780: break; ! 781: ! 782: ! 783: case IOCTL_VIDEO_SET_COLOR_REGISTERS: ! 784: ! 785: VideoDebugPrint((2, "VgaStartIO - SetColorRegs\n")); ! 786: ! 787: status = VgaSetColorLookup(HwDeviceExtension, ! 788: (PVIDEO_CLUT) RequestPacket->InputBuffer, ! 789: RequestPacket->InputBufferLength); ! 790: ! 791: break; ! 792: ! 793: ! 794: case IOCTL_VIDEO_ENABLE_VDM: ! 795: ! 796: VideoDebugPrint((2, "VgaStartIO - EnableVDM\n")); ! 797: ! 798: hwDeviceExtension->TrappedValidatorCount = 0; ! 799: hwDeviceExtension->SequencerAddressValue = 0; ! 800: ! 801: hwDeviceExtension->CurrentNumVdmAccessRanges = ! 802: NUM_MINIMAL_VGA_VALIDATOR_ACCESS_RANGE; ! 803: hwDeviceExtension->CurrentVdmAccessRange = ! 804: MinimalVgaValidatorAccessRange; ! 805: ! 806: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 807: hwDeviceExtension->CurrentNumVdmAccessRanges, ! 808: hwDeviceExtension->CurrentVdmAccessRange); ! 809: ! 810: status = NO_ERROR; ! 811: ! 812: break; ! 813: ! 814: ! 815: case IOCTL_VIDEO_RESTORE_HARDWARE_STATE: ! 816: ! 817: VideoDebugPrint((2, "VgaStartIO - RestoreHardwareState\n")); ! 818: ! 819: status = VgaRestoreHardwareState(HwDeviceExtension, ! 820: (PVIDEO_HARDWARE_STATE) RequestPacket->InputBuffer, ! 821: RequestPacket->InputBufferLength); ! 822: ! 823: break; ! 824: ! 825: ! 826: case IOCTL_VIDEO_SAVE_HARDWARE_STATE: ! 827: ! 828: VideoDebugPrint((2, "VgaStartIO - SaveHardwareState\n")); ! 829: ! 830: status = VgaSaveHardwareState(HwDeviceExtension, ! 831: (PVIDEO_HARDWARE_STATE) RequestPacket->OutputBuffer, ! 832: RequestPacket->OutputBufferLength, ! 833: &RequestPacket->StatusBlock->Information); ! 834: ! 835: break; ! 836: ! 837: case IOCTL_VIDEO_GET_BANK_SELECT_CODE: ! 838: ! 839: VideoDebugPrint((2, "VgaStartIO - GetBankSelectCode\n")); ! 840: ! 841: status = VgaGetBankSelectCode(HwDeviceExtension, ! 842: (PVIDEO_BANK_SELECT) RequestPacket->OutputBuffer, ! 843: RequestPacket->OutputBufferLength, ! 844: &RequestPacket->StatusBlock->Information); ! 845: ! 846: VideoDebugPrint((2, "VgaStartIO - END GetBankSelectCode\n")); ! 847: break; ! 848: ! 849: ! 850: // ! 851: // if we get here, an invalid IoControlCode was specified. ! 852: // ! 853: ! 854: default: ! 855: ! 856: VideoDebugPrint((1, "Fell through vga startIO routine - invalid command\n")); ! 857: ! 858: status = ERROR_INVALID_FUNCTION; ! 859: ! 860: break; ! 861: ! 862: } ! 863: ! 864: RequestPacket->StatusBlock->Status = status; ! 865: ! 866: return TRUE; ! 867: ! 868: } // VgaStartIO() ! 869: ! 870: //--------------------------------------------------------------------------- ! 871: // ! 872: // private routines ! 873: // ! 874: ! 875: VP_STATUS ! 876: VgaLoadAndSetFont( ! 877: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 878: PVIDEO_LOAD_FONT_INFORMATION FontInformation, ! 879: ULONG FontInformationSize ! 880: ) ! 881: ! 882: /*++ ! 883: ! 884: Routine Description: ! 885: ! 886: Takes a buffer containing a user-defined font and loads it into the ! 887: VGA soft font memory and programs the VGA to the appropriate character ! 888: cell size. ! 889: ! 890: Arguments: ! 891: ! 892: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 893: ! 894: FontInformation - Pointer to the structure containing the information ! 895: about the loadable ROM font to be set. ! 896: ! 897: FontInformationSize - Length of the input buffer supplied by the user. ! 898: ! 899: Return Value: ! 900: ! 901: NO_ERROR - information returned successfully ! 902: ! 903: ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data. ! 904: ! 905: ERROR_INVALID_PARAMETER - invalid video mode ! 906: ! 907: --*/ ! 908: ! 909: { ! 910: PUCHAR destination; ! 911: PUCHAR source; ! 912: USHORT width; ! 913: ULONG i; ! 914: ! 915: // ! 916: // Text mode only; If we are in a graphics mode, return an error ! 917: // ! 918: ! 919: if (HwDeviceExtension->CurrentMode->fbType & VIDEO_MODE_GRAPHICS) { ! 920: ! 921: return ERROR_INVALID_PARAMETER; ! 922: ! 923: } ! 924: ! 925: // ! 926: // Check if the size of the data in the input buffer is large enough ! 927: // and that it contains all the data. ! 928: // ! 929: ! 930: if ( (FontInformationSize < sizeof(VIDEO_LOAD_FONT_INFORMATION)) || ! 931: (FontInformationSize < sizeof(VIDEO_LOAD_FONT_INFORMATION) + ! 932: sizeof(UCHAR) * (FontInformation->FontSize - 1)) ) { ! 933: ! 934: return ERROR_INSUFFICIENT_BUFFER; ! 935: ! 936: } ! 937: ! 938: // ! 939: // Check for the width and height of the font ! 940: // ! 941: ! 942: if ( ((FontInformation->WidthInPixels != 8) && ! 943: (FontInformation->WidthInPixels != 9)) || ! 944: (FontInformation->HeightInPixels > 32) ) { ! 945: ! 946: return ERROR_INVALID_PARAMETER; ! 947: ! 948: } ! 949: ! 950: // ! 951: // Check the size of the font buffer is the right size for the size ! 952: // font being passed down. ! 953: // ! 954: ! 955: if (FontInformation->FontSize < FontInformation->HeightInPixels * 256 * ! 956: sizeof(UCHAR) ) { ! 957: ! 958: return ERROR_INSUFFICIENT_BUFFER; ! 959: ! 960: } ! 961: ! 962: // ! 963: // Since the font parameters are valid, store the parameters in the ! 964: // device extension and load the font. ! 965: // ! 966: ! 967: HwDeviceExtension->FontPelRows = FontInformation->HeightInPixels; ! 968: HwDeviceExtension->FontPelColumns = FontInformation->WidthInPixels; ! 969: ! 970: HwDeviceExtension->CurrentMode->row = ! 971: HwDeviceExtension->CurrentMode->vres / HwDeviceExtension->FontPelRows; ! 972: ! 973: width = ! 974: HwDeviceExtension->CurrentMode->hres / HwDeviceExtension->FontPelColumns; ! 975: ! 976: if (width < (USHORT)HwDeviceExtension->CurrentMode->col) { ! 977: ! 978: HwDeviceExtension->CurrentMode->col = width; ! 979: ! 980: } ! 981: ! 982: source = &(FontInformation->Font[0]); ! 983: ! 984: // ! 985: // Set up the destination and source pointers for the font ! 986: // ! 987: ! 988: destination = (PUCHAR)HwDeviceExtension->VideoMemoryAddress; ! 989: ! 990: // ! 991: // Map font buffer at A0000 ! 992: // ! 993: ! 994: VgaInterpretCmdStream(HwDeviceExtension, EnableA000Data); ! 995: ! 996: // ! 997: // Move the font to its destination ! 998: // ! 999: ! 1000: for (i = 1; i <= 256; i++) { ! 1001: ! 1002: VideoPortWriteRegisterBufferUchar(destination, ! 1003: source, ! 1004: FontInformation->HeightInPixels); ! 1005: ! 1006: destination += 32; ! 1007: source += FontInformation->HeightInPixels; ! 1008: ! 1009: } ! 1010: ! 1011: VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color); ! 1012: ! 1013: // ! 1014: // Restore to a text mode. ! 1015: // ! 1016: ! 1017: // ! 1018: // Set Height of font. ! 1019: // ! 1020: ! 1021: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1022: CRTC_ADDRESS_PORT_COLOR, 0x9); ! 1023: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1024: CRTC_DATA_PORT_COLOR, ! 1025: (UCHAR)(FontInformation->HeightInPixels - 1)); ! 1026: ! 1027: // ! 1028: // Set Width of font. ! 1029: // ! 1030: ! 1031: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1032: CRTC_ADDRESS_PORT_COLOR, 0x12); ! 1033: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1034: CRTC_DATA_PORT_COLOR, ! 1035: (UCHAR)(((USHORT)FontInformation->HeightInPixels * ! 1036: (USHORT)HwDeviceExtension->CurrentMode->row) - 1)); ! 1037: ! 1038: i = HwDeviceExtension->CurrentMode->vres / ! 1039: HwDeviceExtension->CurrentMode->row; ! 1040: ! 1041: // ! 1042: // Set Cursor End ! 1043: // ! 1044: ! 1045: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1046: CRTC_ADDRESS_PORT_COLOR, 0xb); ! 1047: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1048: CRTC_DATA_PORT_COLOR, (UCHAR)--i); ! 1049: ! 1050: // ! 1051: // Set Cursor Statr ! 1052: // ! 1053: ! 1054: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1055: CRTC_ADDRESS_PORT_COLOR, 0xa); ! 1056: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1057: CRTC_DATA_PORT_COLOR, (UCHAR)--i); ! 1058: ! 1059: return NO_ERROR; ! 1060: ! 1061: } //end VgaLoadAndSetFont() ! 1062: ! 1063: //--------------------------------------------------------------------------- ! 1064: VP_STATUS ! 1065: VgaQueryCursorPosition( ! 1066: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1067: PVIDEO_CURSOR_POSITION CursorPosition, ! 1068: ULONG CursorPositionSize, ! 1069: PULONG OutputSize ! 1070: ) ! 1071: ! 1072: /*++ ! 1073: ! 1074: Routine Description: ! 1075: ! 1076: This routine returns the row and column of the cursor. ! 1077: ! 1078: Arguments: ! 1079: ! 1080: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1081: ! 1082: CursorPosition - Pointer to the output buffer supplied by the user. This ! 1083: is where the cursor position is stored. ! 1084: ! 1085: CursorPositionSize - Length of the output buffer supplied by the user. ! 1086: ! 1087: OutputSize - Pointer to a buffer in which to return the actual size of ! 1088: the data in the buffer. If the buffer was not large enough, this ! 1089: contains the minimum required buffer size. ! 1090: ! 1091: Return Value: ! 1092: ! 1093: NO_ERROR - information returned successfully ! 1094: ! 1095: ERROR_INSUFFICIENT_BUFFER - output buffer not large enough to return ! 1096: any useful data ! 1097: ! 1098: ERROR_INVALID_PARAMETER - invalid video mode ! 1099: ! 1100: --*/ ! 1101: ! 1102: { ! 1103: // ! 1104: // Text mode only; If we are in a graphics mode, return an error ! 1105: // ! 1106: ! 1107: if (HwDeviceExtension->CurrentMode->fbType & VIDEO_MODE_GRAPHICS) { ! 1108: ! 1109: *OutputSize = 0; ! 1110: return ERROR_INVALID_PARAMETER; ! 1111: ! 1112: } ! 1113: ! 1114: // ! 1115: // If the buffer passed in is not large enough return an ! 1116: // appropriate error code. ! 1117: // ! 1118: ! 1119: if (CursorPositionSize < (*OutputSize = sizeof(VIDEO_CURSOR_POSITION)) ) { ! 1120: ! 1121: *OutputSize = 0; ! 1122: return ERROR_INSUFFICIENT_BUFFER; ! 1123: ! 1124: } ! 1125: ! 1126: // ! 1127: // Store the postition of the cursor into the buffer. ! 1128: // ! 1129: ! 1130: CursorPosition->Column = HwDeviceExtension->CursorPosition.Column; ! 1131: CursorPosition->Row = HwDeviceExtension->CursorPosition.Row; ! 1132: ! 1133: return NO_ERROR; ! 1134: ! 1135: } // end VgaQueryCursorPosition() ! 1136: ! 1137: //--------------------------------------------------------------------------- ! 1138: VP_STATUS ! 1139: VgaSetCursorPosition( ! 1140: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1141: PVIDEO_CURSOR_POSITION CursorPosition, ! 1142: ULONG CursorPositionSize ! 1143: ) ! 1144: ! 1145: /*++ ! 1146: ! 1147: Routine Description: ! 1148: ! 1149: This routine verifies that the requested cursor position is within ! 1150: the row and column bounds of the current mode and font. If valid, then ! 1151: it sets the row and column of the cursor. ! 1152: ! 1153: Arguments: ! 1154: ! 1155: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1156: ! 1157: CursorPosition - Pointer to the structure containing the cursor position. ! 1158: ! 1159: CursorPositionSize - Length of the input buffer supplied by the user. ! 1160: ! 1161: Return Value: ! 1162: ! 1163: NO_ERROR - information returned successfully ! 1164: ! 1165: ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data ! 1166: ! 1167: ERROR_INVALID_PARAMETER - invalid video mode ! 1168: ! 1169: --*/ ! 1170: ! 1171: { ! 1172: USHORT position; ! 1173: ! 1174: // ! 1175: // Text mode only; If we are in a graphics mode, return an error ! 1176: // ! 1177: ! 1178: if (HwDeviceExtension->CurrentMode->fbType & VIDEO_MODE_GRAPHICS) { ! 1179: ! 1180: return ERROR_INVALID_PARAMETER; ! 1181: ! 1182: } ! 1183: ! 1184: // ! 1185: // Check if the size of the data in the input buffer is large enough. ! 1186: // ! 1187: ! 1188: if (CursorPositionSize < sizeof(VIDEO_CURSOR_POSITION)) { ! 1189: ! 1190: return ERROR_INSUFFICIENT_BUFFER; ! 1191: ! 1192: } ! 1193: ! 1194: // ! 1195: // Check if the new values for the cursor positions are in the valid ! 1196: // bounds for the screen. ! 1197: // ! 1198: ! 1199: if ((CursorPosition->Column >= HwDeviceExtension->CurrentMode->col) || ! 1200: (CursorPosition->Row >= HwDeviceExtension->CurrentMode->row)) { ! 1201: ! 1202: return ERROR_INVALID_PARAMETER; ! 1203: ! 1204: } ! 1205: ! 1206: // ! 1207: // Store these new values in the device extension so we can use them in ! 1208: // a QUERY. ! 1209: // ! 1210: ! 1211: HwDeviceExtension->CursorPosition.Column = CursorPosition->Column; ! 1212: HwDeviceExtension->CursorPosition.Row = CursorPosition->Row; ! 1213: ! 1214: // ! 1215: // Calculate the position on the screen at which the cursor must be ! 1216: // be displayed ! 1217: // ! 1218: ! 1219: position = (USHORT) (HwDeviceExtension->CurrentMode->col * ! 1220: CursorPosition->Row + CursorPosition->Column); ! 1221: ! 1222: ! 1223: // ! 1224: // Address Cursor Location Low Register in CRT Controller Registers ! 1225: // ! 1226: ! 1227: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1228: CRTC_ADDRESS_PORT_COLOR, IND_CURSOR_LOW_LOC); ! 1229: ! 1230: // ! 1231: // Set Cursor Location Low Register ! 1232: // ! 1233: ! 1234: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1235: CRTC_DATA_PORT_COLOR, (UCHAR) (position & 0x00FF)); ! 1236: ! 1237: // ! 1238: // Address Cursor Location High Register in CRT Controller Registers ! 1239: // ! 1240: ! 1241: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1242: CRTC_ADDRESS_PORT_COLOR, IND_CURSOR_HIGH_LOC); ! 1243: ! 1244: // ! 1245: // Set Cursor Location High Register ! 1246: // ! 1247: ! 1248: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1249: CRTC_DATA_PORT_COLOR, (UCHAR) (position >> 8)); ! 1250: ! 1251: return NO_ERROR; ! 1252: ! 1253: } // end VgaSetCursorPosition() ! 1254: ! 1255: //--------------------------------------------------------------------------- ! 1256: VP_STATUS ! 1257: VgaQueryCursorAttributes( ! 1258: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1259: PVIDEO_CURSOR_ATTRIBUTES CursorAttributes, ! 1260: ULONG CursorAttributesSize, ! 1261: PULONG OutputSize ! 1262: ) ! 1263: ! 1264: /*++ ! 1265: ! 1266: Routine Description: ! 1267: ! 1268: This routine returns information about the height and visibility of the ! 1269: cursor. ! 1270: ! 1271: Arguments: ! 1272: ! 1273: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1274: ! 1275: CursorAttributes - Pointer to the output buffer supplied by the user. ! 1276: This is where the cursor type is stored. ! 1277: ! 1278: CursorAttributesSize - Length of the output buffer supplied by the user. ! 1279: ! 1280: OutputSize - Pointer to a buffer in which to return the actual size of ! 1281: the data in the buffer. If the buffer was not large enough, this ! 1282: contains the minimum required buffer size. ! 1283: ! 1284: Return Value: ! 1285: ! 1286: NO_ERROR - information returned successfully ! 1287: ! 1288: ERROR_INSUFFICIENT_BUFFER - output buffer not large enough to return ! 1289: any useful data ! 1290: ! 1291: ERROR_INVALID_PARAMETER - invalid video mode ! 1292: ! 1293: --*/ ! 1294: ! 1295: { ! 1296: // ! 1297: // Text mode only; If we are in a graphics mode, return an error ! 1298: // ! 1299: ! 1300: if (HwDeviceExtension->CurrentMode->fbType & VIDEO_MODE_GRAPHICS) { ! 1301: ! 1302: *OutputSize = 0; ! 1303: return ERROR_INVALID_PARAMETER; ! 1304: ! 1305: } ! 1306: ! 1307: // ! 1308: // Find out the size of the data to be put in the the buffer and return ! 1309: // that in the status information (whether or not the information is ! 1310: // there). If the buffer passed in is not large enough return an ! 1311: // appropriate error code. ! 1312: // ! 1313: ! 1314: if (CursorAttributesSize < (*OutputSize = ! 1315: sizeof(VIDEO_CURSOR_ATTRIBUTES)) ) { ! 1316: ! 1317: *OutputSize = 0; ! 1318: return ERROR_INSUFFICIENT_BUFFER; ! 1319: ! 1320: } ! 1321: ! 1322: // ! 1323: // Store the cursor information into the buffer. ! 1324: // ! 1325: ! 1326: CursorAttributes->Height = (USHORT) HwDeviceExtension->CursorTopScanLine; ! 1327: CursorAttributes->Width = (USHORT) HwDeviceExtension->CursorBottomScanLine; ! 1328: CursorAttributes->Enable = HwDeviceExtension->CursorEnable; ! 1329: ! 1330: return NO_ERROR; ! 1331: ! 1332: } // end VgaQueryCursorAttributes() ! 1333: ! 1334: //--------------------------------------------------------------------------- ! 1335: VP_STATUS ! 1336: VgaSetCursorAttributes( ! 1337: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1338: PVIDEO_CURSOR_ATTRIBUTES CursorAttributes, ! 1339: ULONG CursorAttributesSize ! 1340: ) ! 1341: ! 1342: /*++ ! 1343: ! 1344: Routine Description: ! 1345: ! 1346: This routine verifies that the requested cursor height is within the ! 1347: bounds of the character cell. If valid, then it sets the new ! 1348: visibility and height of the cursor. ! 1349: ! 1350: Arguments: ! 1351: ! 1352: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1353: ! 1354: CursorType - Pointer to the structure containing the cursor information. ! 1355: ! 1356: CursorTypeSize - Length of the input buffer supplied by the user. ! 1357: ! 1358: Return Value: ! 1359: ! 1360: NO_ERROR - information returned successfully ! 1361: ! 1362: ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data ! 1363: ! 1364: ERROR_INVALID_PARAMETER - invalid video mode ! 1365: ! 1366: --*/ ! 1367: ! 1368: { ! 1369: UCHAR cursorLine; ! 1370: ! 1371: // ! 1372: // Text mode only; If we are in a graphics mode, return an error ! 1373: // ! 1374: ! 1375: if (HwDeviceExtension->CurrentMode->fbType & VIDEO_MODE_GRAPHICS) { ! 1376: ! 1377: return ERROR_INVALID_PARAMETER; ! 1378: ! 1379: } ! 1380: ! 1381: // ! 1382: // Check if the size of the data in the input buffer is large enough. ! 1383: // ! 1384: ! 1385: if (CursorAttributesSize < sizeof(VIDEO_CURSOR_ATTRIBUTES)) { ! 1386: ! 1387: return ERROR_INSUFFICIENT_BUFFER; ! 1388: ! 1389: } ! 1390: ! 1391: // ! 1392: // Check if the new values for the cursor type are in the valid range. ! 1393: // ! 1394: ! 1395: if ((CursorAttributes->Height >= HwDeviceExtension->FontPelRows) || ! 1396: (CursorAttributes->Width > 31)) { ! 1397: ! 1398: return ERROR_INVALID_PARAMETER; ! 1399: ! 1400: } ! 1401: ! 1402: // ! 1403: // Store the cursor information in the device extension so we can use ! 1404: // them in a QUERY. ! 1405: // ! 1406: ! 1407: HwDeviceExtension->CursorTopScanLine = (UCHAR) CursorAttributes->Height; ! 1408: HwDeviceExtension->CursorBottomScanLine = (UCHAR) CursorAttributes->Width; ! 1409: HwDeviceExtension->CursorEnable = CursorAttributes->Enable; ! 1410: ! 1411: // ! 1412: // Address Cursor Start Register in CRT Controller Registers ! 1413: // ! 1414: ! 1415: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1416: CRTC_ADDRESS_PORT_COLOR, ! 1417: IND_CURSOR_START); ! 1418: ! 1419: // ! 1420: // Set Cursor Start Register by writting to CRTCtl Data Register ! 1421: // Preserve the high three bits of this register. ! 1422: // ! 1423: // Only the Five low bits are used for the cursor height. ! 1424: // Bit 5 is cursor enable, bit 6 and 7 preserved. ! 1425: // ! 1426: ! 1427: cursorLine = (UCHAR) CursorAttributes->Height & 0x1F; ! 1428: ! 1429: cursorLine |= VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1430: CRTC_DATA_PORT_COLOR) & 0xC0; ! 1431: ! 1432: if (!CursorAttributes->Enable) { ! 1433: ! 1434: cursorLine |= 0x20; // Flip cursor off bit ! 1435: ! 1436: } ! 1437: ! 1438: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + CRTC_DATA_PORT_COLOR, ! 1439: cursorLine); ! 1440: ! 1441: // ! 1442: // Address Cursor End Register in CRT Controller Registers ! 1443: // ! 1444: ! 1445: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1446: CRTC_ADDRESS_PORT_COLOR, ! 1447: IND_CURSOR_END); ! 1448: ! 1449: // ! 1450: // Set Cursor End Register. Preserve the high three bits of this ! 1451: // register. ! 1452: // ! 1453: ! 1454: cursorLine = ! 1455: (CursorAttributes->Width < (USHORT)(HwDeviceExtension->FontPelRows - 1)) ? ! 1456: CursorAttributes->Width : (HwDeviceExtension->FontPelRows - 1); ! 1457: ! 1458: cursorLine &= 0x1f; ! 1459: ! 1460: cursorLine |= VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1461: CRTC_DATA_PORT_COLOR) & 0xE0; ! 1462: ! 1463: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + CRTC_DATA_PORT_COLOR, ! 1464: cursorLine); ! 1465: ! 1466: return NO_ERROR; ! 1467: ! 1468: } // end VgaSetCursorAttributes() ! 1469: ! 1470: //--------------------------------------------------------------------------- ! 1471: BOOLEAN ! 1472: VgaIsPresent( ! 1473: PHW_DEVICE_EXTENSION HwDeviceExtension ! 1474: ) ! 1475: ! 1476: /*++ ! 1477: ! 1478: Routine Description: ! 1479: ! 1480: This routine returns TRUE if a VGA is present. Determining whether a VGA ! 1481: is present is a two-step process. First, this routine walks bits through ! 1482: the Bit Mask register, to establish that there are readable indexed ! 1483: registers (EGAs normally don't have readable registers, and other adapters ! 1484: are unlikely to have indexed registers). This test is done first because ! 1485: it's a non-destructive EGA rejection test (correctly rejects EGAs, but ! 1486: doesn't potentially mess up the screen or the accessibility of display ! 1487: memory). Normally, this would be an adequate test, but some EGAs have ! 1488: readable registers, so next, we check for the existence of the Chain4 bit ! 1489: in the Memory Mode register; this bit doesn't exist in EGAs. It's ! 1490: conceivable that there are EGAs with readable registers and a register bit ! 1491: where Chain4 is stored, although I don't know of any; if a better test yet ! 1492: is needed, memory could be written to in Chain4 mode, and then examined ! 1493: plane by plane in non-Chain4 mode to make sure the Chain4 bit did what it's ! 1494: supposed to do. However, the current test should be adequate to eliminate ! 1495: just about all EGAs, and 100% of everything else. ! 1496: ! 1497: If this function fails to find a VGA, it attempts to undo any damage it ! 1498: may have inadvertently done while testing. The underlying assumption for ! 1499: the damage control is that if there's any non-VGA adapter at the tested ! 1500: ports, it's an EGA or an enhanced EGA, because: a) I don't know of any ! 1501: other adapters that use 3C4/5 or 3CE/F, and b), if there are other ! 1502: adapters, I certainly don't know how to restore their original states. So ! 1503: all error recovery is oriented toward putting an EGA back in a writable ! 1504: state, so that error messages are visible. The EGA's state on entry is ! 1505: assumed to be text mode, so the Memory Mode register is restored to the ! 1506: default state for text mode. ! 1507: ! 1508: If a VGA is found, the VGA is returned to its original state after ! 1509: testing is finished. ! 1510: ! 1511: Arguments: ! 1512: ! 1513: None. ! 1514: ! 1515: Return Value: ! 1516: ! 1517: TRUE if a VGA is present, FALSE if not. ! 1518: ! 1519: --*/ ! 1520: ! 1521: { ! 1522: UCHAR originalGCAddr; ! 1523: UCHAR originalSCAddr; ! 1524: UCHAR originalBitMask; ! 1525: UCHAR originalReadMap; ! 1526: UCHAR originalMemoryMode; ! 1527: UCHAR testMask; ! 1528: BOOLEAN returnStatus; ! 1529: ! 1530: // ! 1531: // Remember the original state of the Graphics Controller Address register. ! 1532: // ! 1533: ! 1534: originalGCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1535: GRAPH_ADDRESS_PORT); ! 1536: ! 1537: // ! 1538: // Write the Read Map register with a known state so we can verify ! 1539: // that it isn't changed after we fool with the Bit Mask. This ensures ! 1540: // that we're dealing with indexed registers, since both the Read Map and ! 1541: // the Bit Mask are addressed at GRAPH_DATA_PORT. ! 1542: // ! 1543: ! 1544: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1545: GRAPH_ADDRESS_PORT, IND_READ_MAP); ! 1546: ! 1547: // ! 1548: // If we can't read back the Graphics Address register setting we just ! 1549: // performed, it's not readable and this isn't a VGA. ! 1550: // ! 1551: ! 1552: if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1553: GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_READ_MAP) { ! 1554: ! 1555: return FALSE; ! 1556: } ! 1557: ! 1558: // ! 1559: // Set the Read Map register to a known state. ! 1560: // ! 1561: ! 1562: originalReadMap = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1563: GRAPH_DATA_PORT); ! 1564: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1565: GRAPH_DATA_PORT, READ_MAP_TEST_SETTING); ! 1566: ! 1567: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1568: GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) { ! 1569: ! 1570: // ! 1571: // The Read Map setting we just performed can't be read back; not a ! 1572: // VGA. Restore the default Read Map state. ! 1573: // ! 1574: ! 1575: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1576: GRAPH_DATA_PORT, READ_MAP_DEFAULT); ! 1577: ! 1578: return FALSE; ! 1579: } ! 1580: ! 1581: // ! 1582: // Remember the original setting of the Bit Mask register. ! 1583: // ! 1584: ! 1585: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1586: GRAPH_ADDRESS_PORT, IND_BIT_MASK); ! 1587: if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1588: GRAPH_ADDRESS_PORT) & GRAPH_ADDR_MASK) != IND_BIT_MASK) { ! 1589: ! 1590: // ! 1591: // The Graphics Address register setting we just made can't be read ! 1592: // back; not a VGA. Restore the default Read Map state. ! 1593: // ! 1594: ! 1595: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1596: GRAPH_ADDRESS_PORT, IND_READ_MAP); ! 1597: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1598: GRAPH_DATA_PORT, READ_MAP_DEFAULT); ! 1599: ! 1600: return FALSE; ! 1601: } ! 1602: ! 1603: originalBitMask = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1604: GRAPH_DATA_PORT); ! 1605: ! 1606: // ! 1607: // Set up the initial test mask we'll write to and read from the Bit Mask. ! 1608: // ! 1609: ! 1610: testMask = 0xBB; ! 1611: ! 1612: do { ! 1613: ! 1614: // ! 1615: // Write the test mask to the Bit Mask. ! 1616: // ! 1617: ! 1618: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1619: GRAPH_DATA_PORT, testMask); ! 1620: ! 1621: // ! 1622: // Make sure the Bit Mask remembered the value. ! 1623: // ! 1624: ! 1625: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1626: GRAPH_DATA_PORT) != testMask) { ! 1627: ! 1628: // ! 1629: // The Bit Mask is not properly writable and readable; not a VGA. ! 1630: // Restore the Bit Mask and Read Map to their default states. ! 1631: // ! 1632: ! 1633: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1634: GRAPH_DATA_PORT, BIT_MASK_DEFAULT); ! 1635: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1636: GRAPH_ADDRESS_PORT, IND_READ_MAP); ! 1637: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1638: GRAPH_DATA_PORT, READ_MAP_DEFAULT); ! 1639: ! 1640: return FALSE; ! 1641: } ! 1642: ! 1643: // ! 1644: // Cycle the mask for next time. ! 1645: // ! 1646: ! 1647: testMask >>= 1; ! 1648: ! 1649: } while (testMask != 0); ! 1650: ! 1651: // ! 1652: // There's something readable at GRAPH_DATA_PORT; now switch back and ! 1653: // make sure that the Read Map register hasn't changed, to verify that ! 1654: // we're dealing with indexed registers. ! 1655: // ! 1656: ! 1657: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1658: GRAPH_ADDRESS_PORT, IND_READ_MAP); ! 1659: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1660: GRAPH_DATA_PORT) != READ_MAP_TEST_SETTING) { ! 1661: ! 1662: // ! 1663: // The Read Map is not properly writable and readable; not a VGA. ! 1664: // Restore the Bit Mask and Read Map to their default states, in case ! 1665: // this is an EGA, so subsequent writes to the screen aren't garbled. ! 1666: // ! 1667: ! 1668: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1669: GRAPH_DATA_PORT, READ_MAP_DEFAULT); ! 1670: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1671: GRAPH_ADDRESS_PORT, IND_BIT_MASK); ! 1672: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1673: GRAPH_DATA_PORT, BIT_MASK_DEFAULT); ! 1674: ! 1675: return FALSE; ! 1676: } ! 1677: ! 1678: // ! 1679: // We've pretty surely verified the existence of the Bit Mask register. ! 1680: // Put the Graphics Controller back to the original state. ! 1681: // ! 1682: ! 1683: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1684: GRAPH_DATA_PORT, originalReadMap); ! 1685: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1686: GRAPH_ADDRESS_PORT, IND_BIT_MASK); ! 1687: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1688: GRAPH_DATA_PORT, originalBitMask); ! 1689: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1690: GRAPH_ADDRESS_PORT, originalGCAddr); ! 1691: ! 1692: // ! 1693: // Now, check for the existence of the Chain4 bit. ! 1694: // ! 1695: ! 1696: // ! 1697: // Remember the original states of the Sequencer Address and Memory Mode ! 1698: // registers. ! 1699: // ! 1700: ! 1701: originalSCAddr = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1702: SEQ_ADDRESS_PORT); ! 1703: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1704: SEQ_ADDRESS_PORT, IND_MEMORY_MODE); ! 1705: if ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1706: SEQ_ADDRESS_PORT) & SEQ_ADDR_MASK) != IND_MEMORY_MODE) { ! 1707: ! 1708: // ! 1709: // Couldn't read back the Sequencer Address register setting we just ! 1710: // performed. ! 1711: // ! 1712: ! 1713: return FALSE; ! 1714: } ! 1715: originalMemoryMode = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1716: SEQ_DATA_PORT); ! 1717: ! 1718: // ! 1719: // Toggle the Chain4 bit and read back the result. This must be done during ! 1720: // sync reset, since we're changing the chaining state. ! 1721: // ! 1722: ! 1723: // ! 1724: // Begin sync reset. ! 1725: // ! 1726: ! 1727: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 1728: SEQ_ADDRESS_PORT), ! 1729: (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8))); ! 1730: ! 1731: // ! 1732: // Toggle the Chain4 bit. ! 1733: // ! 1734: ! 1735: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1736: SEQ_ADDRESS_PORT, IND_MEMORY_MODE); ! 1737: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1738: SEQ_DATA_PORT, (UCHAR)(originalMemoryMode ^ CHAIN4_MASK)); ! 1739: ! 1740: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1741: SEQ_DATA_PORT) != (UCHAR) (originalMemoryMode ^ CHAIN4_MASK)) { ! 1742: ! 1743: // ! 1744: // Chain4 bit not there; not a VGA. ! 1745: // Set text mode default for Memory Mode register. ! 1746: // ! 1747: ! 1748: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1749: SEQ_DATA_PORT, MEMORY_MODE_TEXT_DEFAULT); ! 1750: // ! 1751: // End sync reset. ! 1752: // ! 1753: ! 1754: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 1755: SEQ_ADDRESS_PORT), ! 1756: (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8))); ! 1757: ! 1758: returnStatus = FALSE; ! 1759: ! 1760: } else { ! 1761: ! 1762: // ! 1763: // It's a VGA. ! 1764: // ! 1765: ! 1766: // ! 1767: // Restore the original Memory Mode setting. ! 1768: // ! 1769: ! 1770: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1771: SEQ_DATA_PORT, originalMemoryMode); ! 1772: ! 1773: // ! 1774: // End sync reset. ! 1775: // ! 1776: ! 1777: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 1778: SEQ_ADDRESS_PORT), ! 1779: (USHORT)(IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8))); ! 1780: ! 1781: // ! 1782: // Restore the original Sequencer Address setting. ! 1783: // ! 1784: ! 1785: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1786: SEQ_ADDRESS_PORT, originalSCAddr); ! 1787: ! 1788: returnStatus = TRUE; ! 1789: } ! 1790: ! 1791: return returnStatus; ! 1792: ! 1793: } // VgaIsPresent() ! 1794: ! 1795: //--------------------------------------------------------------------------- ! 1796: VP_STATUS ! 1797: VgaSetPaletteReg( ! 1798: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1799: PVIDEO_PALETTE_DATA PaletteBuffer, ! 1800: ULONG PaletteBufferSize ! 1801: ) ! 1802: ! 1803: /*++ ! 1804: ! 1805: Routine Description: ! 1806: ! 1807: This routine sets a specified portion of the EGA (not DAC) palette ! 1808: registers. ! 1809: ! 1810: Arguments: ! 1811: ! 1812: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1813: ! 1814: PaletteBuffer - Pointer to the structure containing the palette data. ! 1815: ! 1816: PaletteBufferSize - Length of the input buffer supplied by the user. ! 1817: ! 1818: Return Value: ! 1819: ! 1820: NO_ERROR - information returned successfully ! 1821: ! 1822: ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data. ! 1823: ! 1824: ERROR_INVALID_PARAMETER - invalid palette size. ! 1825: ! 1826: --*/ ! 1827: ! 1828: { ! 1829: USHORT i; ! 1830: ! 1831: // ! 1832: // Check if the size of the data in the input buffer is large enough. ! 1833: // ! 1834: ! 1835: if ((PaletteBufferSize) < (sizeof(VIDEO_PALETTE_DATA)) || ! 1836: (PaletteBufferSize < (sizeof(VIDEO_PALETTE_DATA) + ! 1837: (sizeof(USHORT) * (PaletteBuffer->NumEntries -1)) ))) { ! 1838: ! 1839: return ERROR_INSUFFICIENT_BUFFER; ! 1840: ! 1841: } ! 1842: ! 1843: // ! 1844: // Check to see if the parameters are valid. ! 1845: // ! 1846: ! 1847: if ( (PaletteBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER ) || ! 1848: (PaletteBuffer->NumEntries == 0) || ! 1849: (PaletteBuffer->FirstEntry + PaletteBuffer->NumEntries > ! 1850: VIDEO_MAX_PALETTE_REGISTER + 1 ) ) { ! 1851: ! 1852: return ERROR_INVALID_PARAMETER; ! 1853: ! 1854: } ! 1855: ! 1856: // ! 1857: // Reset ATC to index mode ! 1858: // ! 1859: ! 1860: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 1861: ATT_INITIALIZE_PORT_COLOR); ! 1862: ! 1863: // ! 1864: // Blast out our palette values. ! 1865: // ! 1866: ! 1867: for (i = 0; i < PaletteBuffer->NumEntries; i++) { ! 1868: ! 1869: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, ! 1870: (UCHAR)(i+PaletteBuffer->FirstEntry)); ! 1871: ! 1872: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1873: ATT_DATA_WRITE_PORT, ! 1874: (UCHAR)PaletteBuffer->Colors[i]); ! 1875: } ! 1876: ! 1877: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ATT_ADDRESS_PORT, ! 1878: VIDEO_ENABLE); ! 1879: ! 1880: return NO_ERROR; ! 1881: ! 1882: } // end VgaSetPaletteReg() ! 1883: ! 1884: ! 1885: //--------------------------------------------------------------------------- ! 1886: VP_STATUS ! 1887: VgaSetColorLookup( ! 1888: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1889: PVIDEO_CLUT ClutBuffer, ! 1890: ULONG ClutBufferSize ! 1891: ) ! 1892: ! 1893: /*++ ! 1894: ! 1895: Routine Description: ! 1896: ! 1897: This routine sets a specified portion of the DAC color lookup table ! 1898: settings. ! 1899: ! 1900: Arguments: ! 1901: ! 1902: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1903: ! 1904: ClutBufferSize - Length of the input buffer supplied by the user. ! 1905: ! 1906: ClutBuffer - Pointer to the structure containing the color lookup table. ! 1907: ! 1908: Return Value: ! 1909: ! 1910: NO_ERROR - information returned successfully ! 1911: ! 1912: ERROR_INSUFFICIENT_BUFFER - input buffer not large enough for input data. ! 1913: ! 1914: ERROR_INVALID_PARAMETER - invalid clut size. ! 1915: ! 1916: --*/ ! 1917: ! 1918: { ! 1919: ULONG i; ! 1920: ! 1921: // ! 1922: // Check if the size of the data in the input buffer is large enough. ! 1923: // ! 1924: ! 1925: if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) || ! 1926: (ClutBufferSize < sizeof(VIDEO_CLUT) + ! 1927: (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) ) { ! 1928: ! 1929: return ERROR_INSUFFICIENT_BUFFER; ! 1930: ! 1931: } ! 1932: ! 1933: // ! 1934: // Check to see if the parameters are valid. ! 1935: // ! 1936: ! 1937: if ( (ClutBuffer->NumEntries == 0) || ! 1938: (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) || ! 1939: (ClutBuffer->FirstEntry + ClutBuffer->NumEntries > ! 1940: VIDEO_MAX_COLOR_REGISTER + 1) ) { ! 1941: ! 1942: return ERROR_INVALID_PARAMETER; ! 1943: ! 1944: } ! 1945: ! 1946: // ! 1947: // Set CLUT registers directly on the hardware ! 1948: // ! 1949: ! 1950: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 1951: DAC_ADDRESS_WRITE_PORT, ! 1952: (UCHAR) ClutBuffer->FirstEntry); ! 1953: ! 1954: for (i = 0; i < ClutBuffer->NumEntries; i++) { ! 1955: ! 1956: VideoPortWritePortBufferUchar((PUCHAR)HwDeviceExtension->IOAddress + ! 1957: DAC_DATA_REG_PORT, ! 1958: &(ClutBuffer->LookupTable[i].RgbArray.Red), ! 1959: 0x03); ! 1960: ! 1961: } ! 1962: ! 1963: return NO_ERROR; ! 1964: ! 1965: } // end VgaSetColorLookup() ! 1966: ! 1967: //--------------------------------------------------------------------------- ! 1968: VP_STATUS ! 1969: VgaRestoreHardwareState( ! 1970: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 1971: PVIDEO_HARDWARE_STATE HardwareState, ! 1972: ULONG HardwareStateSize ! 1973: ) ! 1974: ! 1975: /*++ ! 1976: ! 1977: Routine Description: ! 1978: ! 1979: Restores all registers and memory of the VGA. ! 1980: ! 1981: Note: HardwareState points to the actual buffer from which the state ! 1982: is to be restored. This buffer will always be big enough (we specified ! 1983: the required size at DriverEntry). ! 1984: ! 1985: Note: The offset in the hardware state header from which each general ! 1986: register is restored is the offset of the write address of that register ! 1987: from the base I/O address of the VGA. ! 1988: ! 1989: ! 1990: Arguments: ! 1991: ! 1992: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 1993: ! 1994: HardwareState - Pointer to a structure from which the saved state is to be ! 1995: restored (actually only info about and a pointer to the actual save ! 1996: buffer). ! 1997: ! 1998: HardwareStateSize - Length of the input buffer supplied by the user. ! 1999: (Actually only the size of the HardwareState structure, not the ! 2000: buffer it points to from which the state is actually restored. The ! 2001: pointed-to buffer is assumed to be big enough.) ! 2002: ! 2003: Return Value: ! 2004: ! 2005: NO_ERROR - restore performed successfully ! 2006: ! 2007: ERROR_INSUFFICIENT_BUFFER - input buffer not large enough to provide data ! 2008: ! 2009: --*/ ! 2010: ! 2011: { ! 2012: PVIDEO_HARDWARE_STATE_HEADER hardwareStateHeader; ! 2013: ULONG i; ! 2014: UCHAR dummy; ! 2015: PUCHAR pScreen; ! 2016: PUCHAR pucLatch; ! 2017: PULONG pulBuffer; ! 2018: PUCHAR port; ! 2019: PUCHAR portValue; ! 2020: PUCHAR portValueDAC; ! 2021: ULONG bIsColor; ! 2022: ! 2023: ! 2024: // ! 2025: // Check if the size of the data in the input buffer is large enough. ! 2026: // ! 2027: ! 2028: if ((HardwareStateSize < sizeof(VIDEO_HARDWARE_STATE)) || ! 2029: (HardwareState->StateLength < VGA_TOTAL_STATE_SIZE)) { ! 2030: ! 2031: return ERROR_INSUFFICIENT_BUFFER; ! 2032: ! 2033: } ! 2034: ! 2035: // ! 2036: // Point to the buffer where the restore data is actually stored. ! 2037: // ! 2038: ! 2039: hardwareStateHeader = HardwareState->StateHeader; ! 2040: ! 2041: // ! 2042: // Make sure the offset are in the structure ... ! 2043: // ! 2044: ! 2045: if ((hardwareStateHeader->BasicSequencerOffset + VGA_NUM_SEQUENCER_PORTS > ! 2046: HardwareState->StateLength) || ! 2047: ! 2048: (hardwareStateHeader->BasicCrtContOffset + VGA_NUM_CRTC_PORTS > ! 2049: HardwareState->StateLength) || ! 2050: ! 2051: (hardwareStateHeader->BasicGraphContOffset + VGA_NUM_GRAPH_CONT_PORTS > ! 2052: HardwareState->StateLength) || ! 2053: ! 2054: (hardwareStateHeader->BasicAttribContOffset + VGA_NUM_ATTRIB_CONT_PORTS > ! 2055: HardwareState->StateLength) || ! 2056: ! 2057: (hardwareStateHeader->BasicDacOffset + (3 * VGA_NUM_DAC_ENTRIES) > ! 2058: HardwareState->StateLength) || ! 2059: ! 2060: (hardwareStateHeader->BasicLatchesOffset + 4 > ! 2061: HardwareState->StateLength) || ! 2062: ! 2063: (hardwareStateHeader->ExtendedSequencerOffset + EXT_NUM_SEQUENCER_PORTS > ! 2064: HardwareState->StateLength) || ! 2065: ! 2066: (hardwareStateHeader->ExtendedCrtContOffset + EXT_NUM_CRTC_PORTS > ! 2067: HardwareState->StateLength) || ! 2068: ! 2069: (hardwareStateHeader->ExtendedGraphContOffset + EXT_NUM_GRAPH_CONT_PORTS > ! 2070: HardwareState->StateLength) || ! 2071: ! 2072: (hardwareStateHeader->ExtendedAttribContOffset + EXT_NUM_ATTRIB_CONT_PORTS > ! 2073: HardwareState->StateLength) || ! 2074: ! 2075: (hardwareStateHeader->ExtendedDacOffset + (4 * EXT_NUM_DAC_ENTRIES) > ! 2076: HardwareState->StateLength) || ! 2077: ! 2078: // ! 2079: // Only check the validator state offset if there is unemulated data. ! 2080: // ! 2081: ! 2082: ((hardwareStateHeader->VGAStateFlags & VIDEO_STATE_UNEMULATED_VGA_STATE) && ! 2083: (hardwareStateHeader->ExtendedValidatorStateOffset + VGA_VALIDATOR_AREA_SIZE > ! 2084: HardwareState->StateLength)) || ! 2085: ! 2086: (hardwareStateHeader->ExtendedMiscDataOffset + VGA_MISC_DATA_AREA_OFFSET > ! 2087: HardwareState->StateLength) || ! 2088: ! 2089: (hardwareStateHeader->Plane1Offset + hardwareStateHeader->PlaneLength > ! 2090: HardwareState->StateLength) || ! 2091: ! 2092: (hardwareStateHeader->Plane2Offset + hardwareStateHeader->PlaneLength > ! 2093: HardwareState->StateLength) || ! 2094: ! 2095: (hardwareStateHeader->Plane3Offset + hardwareStateHeader->PlaneLength > ! 2096: HardwareState->StateLength) || ! 2097: ! 2098: (hardwareStateHeader->Plane4Offset + hardwareStateHeader->PlaneLength > ! 2099: HardwareState->StateLength) || ! 2100: ! 2101: (hardwareStateHeader->DIBOffset + ! 2102: hardwareStateHeader->DIBBitsPerPixel / 8 * ! 2103: hardwareStateHeader->DIBXResolution * ! 2104: hardwareStateHeader->DIBYResolution > HardwareState->StateLength) || ! 2105: ! 2106: (hardwareStateHeader->DIBXlatOffset + hardwareStateHeader->DIBXlatLength > ! 2107: HardwareState->StateLength)) { ! 2108: ! 2109: return ERROR_INVALID_PARAMETER; ! 2110: ! 2111: } ! 2112: ! 2113: // ! 2114: // Turn off the screen to avoid flickering. The screen will turn back on ! 2115: // when we restore the DAC state at the end of this routine. ! 2116: // ! 2117: ! 2118: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 2119: MISC_OUTPUT_REG_READ_PORT) & 0x01) { ! 2120: port = INPUT_STATUS_1_COLOR + HwDeviceExtension->IOAddress; ! 2121: } else { ! 2122: port = INPUT_STATUS_1_MONO + HwDeviceExtension->IOAddress; ! 2123: } ! 2124: ! 2125: // ! 2126: // Set DAC register 0 to display black. ! 2127: // ! 2128: ! 2129: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2130: DAC_ADDRESS_WRITE_PORT, 0); ! 2131: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2132: DAC_DATA_REG_PORT, 0); ! 2133: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2134: DAC_DATA_REG_PORT, 0); ! 2135: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2136: DAC_DATA_REG_PORT, 0); ! 2137: ! 2138: // ! 2139: // Set the DAC mask register to force DAC register 0 to display all the ! 2140: // time (this is the register we just set to display black). From now on, ! 2141: // nothing but black will show up on the screen. ! 2142: // ! 2143: ! 2144: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2145: DAC_PIXEL_MASK_PORT, 0); ! 2146: ! 2147: ! 2148: // ! 2149: // Restore the latches and the contents of display memory. ! 2150: // ! 2151: // Set up the VGA's hardware to allow us to copy to each plane in turn. ! 2152: // ! 2153: // Begin sync reset. ! 2154: // ! 2155: ! 2156: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2157: SEQ_ADDRESS_PORT), ! 2158: (USHORT) (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8))); ! 2159: ! 2160: // ! 2161: // Turn off Chain mode and map display memory at A0000 for 64K. ! 2162: // ! 2163: ! 2164: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2165: GRAPH_ADDRESS_PORT, IND_GRAPH_MISC); ! 2166: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2167: GRAPH_DATA_PORT, (UCHAR) ((VideoPortReadPortUchar( ! 2168: HwDeviceExtension->IOAddress + GRAPH_DATA_PORT) & 0xF1) | 0x04)); ! 2169: ! 2170: // ! 2171: // Turn off Chain4 mode and odd/even. ! 2172: // ! 2173: ! 2174: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2175: SEQ_ADDRESS_PORT, IND_MEMORY_MODE); ! 2176: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2177: SEQ_DATA_PORT, ! 2178: (UCHAR) ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 2179: SEQ_DATA_PORT) & 0xF3) | 0x04)); ! 2180: ! 2181: // ! 2182: // End sync reset. ! 2183: // ! 2184: ! 2185: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2186: SEQ_ADDRESS_PORT), (USHORT) (IND_SYNC_RESET + ! 2187: (END_SYNC_RESET_VALUE << 8))); ! 2188: ! 2189: // ! 2190: // Set the write mode to 0, the read mode to 0, and turn off odd/even. ! 2191: // ! 2192: ! 2193: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2194: GRAPH_ADDRESS_PORT, IND_GRAPH_MODE); ! 2195: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2196: GRAPH_DATA_PORT, ! 2197: (UCHAR) ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 2198: GRAPH_DATA_PORT) & 0xE4) | 0x00)); ! 2199: ! 2200: // ! 2201: // Set the Bit Mask to 0xFF to allow all CPU bits through. ! 2202: // ! 2203: ! 2204: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2205: GRAPH_ADDRESS_PORT), (USHORT) (IND_BIT_MASK + (0xFF << 8))); ! 2206: ! 2207: // ! 2208: // Set the Data Rotation and Logical Function fields to 0 to allow CPU ! 2209: // data through unmodified. ! 2210: // ! 2211: ! 2212: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 2213: GRAPH_ADDRESS_PORT), (USHORT) (IND_DATA_ROTATE + (0 << 8))); ! 2214: ! 2215: // ! 2216: // Set Set/Reset Enable to 0 to select CPU data for all planes. ! 2217: // ! 2218: ! 2219: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2220: GRAPH_ADDRESS_PORT), (USHORT) (IND_SET_RESET_ENABLE + (0 << 8))); ! 2221: ! 2222: // ! 2223: // Point the Sequencer Index to the Map Mask register. ! 2224: // ! 2225: ! 2226: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2227: SEQ_ADDRESS_PORT, IND_MAP_MASK); ! 2228: ! 2229: // ! 2230: // Restore the latches. ! 2231: // ! 2232: // Point to the saved data for the first latch. ! 2233: // ! 2234: ! 2235: pucLatch = ((PUCHAR) (hardwareStateHeader)) + ! 2236: hardwareStateHeader->BasicLatchesOffset; ! 2237: ! 2238: // ! 2239: // Point to first byte of display memory. ! 2240: // ! 2241: ! 2242: pScreen = (PUCHAR) HwDeviceExtension->VideoMemoryAddress; ! 2243: ! 2244: // ! 2245: // Write the contents to be restored to each of the four latches in turn. ! 2246: // ! 2247: ! 2248: for (i = 0; i < 4; i++) { ! 2249: ! 2250: // ! 2251: // Set the Map Mask to select the plane we want to restore next. ! 2252: // ! 2253: ! 2254: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2255: SEQ_DATA_PORT, (UCHAR)(1<<i)); ! 2256: ! 2257: // ! 2258: // Write this plane's latch. ! 2259: // ! 2260: ! 2261: VideoPortWriteRegisterUchar(pScreen, *pucLatch++); ! 2262: ! 2263: } ! 2264: ! 2265: // ! 2266: // Read the latched data into the latches, and the latches are set. ! 2267: // ! 2268: ! 2269: dummy = VideoPortReadRegisterUchar(pScreen); ! 2270: ! 2271: // ! 2272: // Point to the offset of the saved data for the first plane. ! 2273: // ! 2274: ! 2275: pulBuffer = &(hardwareStateHeader->Plane1Offset); ! 2276: ! 2277: // ! 2278: // Restore each of the four planes in turn. ! 2279: // ! 2280: ! 2281: for (i = 0; i < 4; i++) { ! 2282: ! 2283: // ! 2284: // Set the Map Mask to select the plane we want to restore next. ! 2285: // ! 2286: ! 2287: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2288: SEQ_DATA_PORT, (UCHAR)(1<<i)); ! 2289: ! 2290: // ! 2291: // Restore this plane from the buffer. ! 2292: // ! 2293: ! 2294: VideoPortMoveMemory((PUCHAR) HwDeviceExtension->VideoMemoryAddress, ! 2295: ((PUCHAR) (hardwareStateHeader)) + *pulBuffer, ! 2296: hardwareStateHeader->PlaneLength); ! 2297: ! 2298: pulBuffer++; ! 2299: ! 2300: } ! 2301: ! 2302: // ! 2303: // If we have some unemulated data, put it back into the buffer ! 2304: // ! 2305: ! 2306: if (hardwareStateHeader->VGAStateFlags & VIDEO_STATE_UNEMULATED_VGA_STATE) { ! 2307: ! 2308: if (!hardwareStateHeader->ExtendedValidatorStateOffset) { ! 2309: ! 2310: return ERROR_INVALID_PARAMETER; ! 2311: ! 2312: } ! 2313: ! 2314: // ! 2315: // Get the right offset in the struct and save all the data associated ! 2316: // with the trapped validator data. ! 2317: // ! 2318: ! 2319: VideoPortMoveMemory(&(HwDeviceExtension->TrappedValidatorCount), ! 2320: ((PUCHAR) (hardwareStateHeader)) + ! 2321: hardwareStateHeader->ExtendedValidatorStateOffset, ! 2322: VGA_VALIDATOR_AREA_SIZE); ! 2323: ! 2324: // ! 2325: // Check to see if this is an appropriate access range. ! 2326: // We are trapping - so we must have the trapping access range enabled. ! 2327: // ! 2328: ! 2329: if (((HwDeviceExtension->CurrentVdmAccessRange != FullVgaValidatorAccessRange) || ! 2330: (HwDeviceExtension->CurrentNumVdmAccessRanges != NUM_FULL_VGA_VALIDATOR_ACCESS_RANGE)) && ! 2331: ((HwDeviceExtension->CurrentVdmAccessRange != MinimalVgaValidatorAccessRange) || ! 2332: (HwDeviceExtension->CurrentNumVdmAccessRanges != NUM_MINIMAL_VGA_VALIDATOR_ACCESS_RANGE))) { ! 2333: ! 2334: return ERROR_INVALID_PARAMETER; ! 2335: ! 2336: } ! 2337: ! 2338: VideoPortSetTrappedEmulatorPorts(HwDeviceExtension, ! 2339: HwDeviceExtension->CurrentNumVdmAccessRanges, ! 2340: HwDeviceExtension->CurrentVdmAccessRange); ! 2341: ! 2342: } ! 2343: ! 2344: // ! 2345: // Set the critical registers (clock and timing states) during sync reset. ! 2346: // ! 2347: // Begin sync reset. ! 2348: // ! 2349: ! 2350: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2351: SEQ_ADDRESS_PORT), (USHORT) (IND_SYNC_RESET + ! 2352: (START_SYNC_RESET_VALUE << 8))); ! 2353: ! 2354: // ! 2355: // Restore the Miscellaneous Output register. ! 2356: // ! 2357: ! 2358: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2359: MISC_OUTPUT_REG_WRITE_PORT, ! 2360: (UCHAR) (hardwareStateHeader->PortValue[MISC_OUTPUT_REG_WRITE_PORT] & 0xF7)); ! 2361: ! 2362: // ! 2363: // Restore all Sequencer registers except the Sync Reset register, which ! 2364: // is always not in reset (except when we send out a batched sync reset ! 2365: // register set, but that can't be interrupted, so we know we're never in ! 2366: // sync reset at save/restore time). ! 2367: // ! 2368: ! 2369: portValue = ((PUCHAR) hardwareStateHeader) + ! 2370: hardwareStateHeader->BasicSequencerOffset + 1; ! 2371: ! 2372: for (i = 1; i < VGA_NUM_SEQUENCER_PORTS; i++) { ! 2373: ! 2374: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2375: SEQ_ADDRESS_PORT), (USHORT) (i + ((*portValue++) << 8)) ); ! 2376: ! 2377: } ! 2378: ! 2379: // ! 2380: // Restore extended sequencer registers ! 2381: // ! 2382: ! 2383: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 2384: ! 2385: if (hardwareStateHeader->ExtendedSequencerOffset) { ! 2386: ! 2387: portValue = ((PUCHAR) hardwareStateHeader) + ! 2388: hardwareStateHeader->ExtendedSequencerOffset; ! 2389: ! 2390: if (HwDeviceExtension->ChipType == CL542x) { ! 2391: ! 2392: // ! 2393: // No extended sequencer registers for the CL64xx ! 2394: // ! 2395: ! 2396: // ! 2397: // The first section in restore must open the extension registers ! 2398: // ! 2399: ! 2400: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2401: SEQ_ADDRESS_PORT), ! 2402: IND_CL_EXTS_ENB + (0x0012 << 8) ); ! 2403: ! 2404: for (i = CL542x_SEQUENCER_EXT_START; ! 2405: i <= CL542x_SEQUENCER_EXT_END; ! 2406: i++) { ! 2407: ! 2408: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2409: SEQ_ADDRESS_PORT), ! 2410: (USHORT) (i + ((*portValue++) << 8)) ); ! 2411: ! 2412: } ! 2413: } ! 2414: } ! 2415: ! 2416: #endif ! 2417: ! 2418: // ! 2419: // Restore the Graphics Controller Miscellaneous register, which contains ! 2420: // the Chain bit. ! 2421: // ! 2422: ! 2423: portValue = ((PUCHAR) hardwareStateHeader) + ! 2424: hardwareStateHeader->BasicGraphContOffset + IND_GRAPH_MISC; ! 2425: ! 2426: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2427: GRAPH_ADDRESS_PORT), (USHORT)(IND_GRAPH_MISC + (*portValue << 8))); ! 2428: ! 2429: // ! 2430: // End sync reset. ! 2431: // ! 2432: ! 2433: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2434: SEQ_ADDRESS_PORT), (USHORT) (IND_SYNC_RESET + ! 2435: (END_SYNC_RESET_VALUE << 8))); ! 2436: ! 2437: // ! 2438: // Figure out if color/mono switchable registers are at 3BX or 3DX. ! 2439: // At the same time, save the state of the Miscellaneous Output register ! 2440: // which is read from 3CC but written at 3C2. ! 2441: // ! 2442: ! 2443: if (hardwareStateHeader->PortValue[MISC_OUTPUT_REG_WRITE_PORT] & 0x01) { ! 2444: bIsColor = TRUE; ! 2445: } else { ! 2446: bIsColor = FALSE; ! 2447: } ! 2448: ! 2449: ! 2450: // ! 2451: // Restore the CRT Controller indexed registers. ! 2452: // ! 2453: // Unlock CRTC registers 0-7. ! 2454: // ! 2455: ! 2456: portValue = (PUCHAR) hardwareStateHeader + ! 2457: hardwareStateHeader->BasicCrtContOffset; ! 2458: ! 2459: if (bIsColor) { ! 2460: ! 2461: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2462: CRTC_ADDRESS_PORT_COLOR), (USHORT) (IND_CRTC_PROTECT + ! 2463: (((*(portValue + IND_CRTC_PROTECT)) & 0x7F) << 8))); ! 2464: ! 2465: } else { ! 2466: ! 2467: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2468: CRTC_ADDRESS_PORT_MONO), (USHORT) (IND_CRTC_PROTECT + ! 2469: (((*(portValue + IND_CRTC_PROTECT)) & 0x7F) << 8))); ! 2470: ! 2471: } ! 2472: ! 2473: // ! 2474: // Restore extended crtc registers. ! 2475: // ! 2476: ! 2477: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 2478: ! 2479: if (hardwareStateHeader->ExtendedCrtContOffset) { ! 2480: ! 2481: portValue = (PUCHAR) hardwareStateHeader + ! 2482: hardwareStateHeader->ExtendedCrtContOffset; ! 2483: ! 2484: if (HwDeviceExtension->ChipType == CL542x) { ! 2485: ! 2486: // ! 2487: // No CRTC Extensions in CL64xx chipset ! 2488: // ! 2489: ! 2490: for (i = CL542x_CRTC_EXT_START; i <= CL542x_CRTC_EXT_END; i++) { ! 2491: ! 2492: if (bIsColor) { ! 2493: ! 2494: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2495: CRTC_ADDRESS_PORT_COLOR), ! 2496: (USHORT) (i + ((*portValue++) << 8))); ! 2497: ! 2498: } else { ! 2499: ! 2500: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2501: CRTC_ADDRESS_PORT_MONO), ! 2502: (USHORT) (i + ((*portValue++) << 8))); ! 2503: ! 2504: } ! 2505: } ! 2506: } ! 2507: } ! 2508: ! 2509: #endif ! 2510: ! 2511: // ! 2512: // Now restore the CRTC registers. ! 2513: // ! 2514: ! 2515: portValue = (PUCHAR) hardwareStateHeader + ! 2516: hardwareStateHeader->BasicCrtContOffset; ! 2517: ! 2518: for (i = 0; i < VGA_NUM_CRTC_PORTS; i++) { ! 2519: ! 2520: if (bIsColor) { ! 2521: ! 2522: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2523: CRTC_ADDRESS_PORT_COLOR), ! 2524: (USHORT) (i + ((*portValue++) << 8))); ! 2525: ! 2526: } else { ! 2527: ! 2528: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2529: CRTC_ADDRESS_PORT_MONO), ! 2530: (USHORT) (i + ((*portValue++) << 8))); ! 2531: ! 2532: } ! 2533: ! 2534: } ! 2535: ! 2536: // ! 2537: // Restore the Graphics Controller indexed registers. ! 2538: // ! 2539: ! 2540: portValue = (PUCHAR) hardwareStateHeader + ! 2541: hardwareStateHeader->BasicGraphContOffset; ! 2542: ! 2543: for (i = 0; i < VGA_NUM_GRAPH_CONT_PORTS; i++) { ! 2544: ! 2545: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2546: GRAPH_ADDRESS_PORT), (USHORT) (i + ((*portValue++) << 8))); ! 2547: ! 2548: } ! 2549: ! 2550: // ! 2551: // Restore extended graphics controller registers. ! 2552: // ! 2553: ! 2554: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 2555: ! 2556: if (hardwareStateHeader->ExtendedGraphContOffset) { ! 2557: ! 2558: portValue = (PUCHAR) hardwareStateHeader + ! 2559: hardwareStateHeader->ExtendedGraphContOffset; ! 2560: ! 2561: if (HwDeviceExtension->ChipType == CL542x) { ! 2562: ! 2563: for (i = CL542x_GRAPH_EXT_START; i <= CL542x_GRAPH_EXT_END; i++) { ! 2564: ! 2565: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2566: GRAPH_ADDRESS_PORT), ! 2567: (USHORT) (i + ((*portValue++) << 8))); ! 2568: } ! 2569: ! 2570: } else { // must be a CL64xx ! 2571: ! 2572: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 2573: GRAPH_ADDRESS_PORT), ! 2574: CL64xx_EXTENSION_ENABLE_INDEX + ! 2575: (CL64xx_EXTENSION_ENABLE_VALUE << 8)); ! 2576: ! 2577: for (i = CL64xx_GRAPH_EXT_START; i <= CL64xx_GRAPH_EXT_END; i++) { ! 2578: ! 2579: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 2580: GRAPH_ADDRESS_PORT), ! 2581: (USHORT) (i + ((*portValue++) << 8))); ! 2582: ! 2583: } ! 2584: } ! 2585: } ! 2586: ! 2587: #endif ! 2588: ! 2589: // ! 2590: // Restore the Attribute Controller indexed registers. ! 2591: // ! 2592: ! 2593: portValue = (PUCHAR) hardwareStateHeader + ! 2594: hardwareStateHeader->BasicAttribContOffset; ! 2595: ! 2596: // ! 2597: // Reset the AC index/data toggle, then blast out all the register ! 2598: // settings. ! 2599: // ! 2600: ! 2601: if (bIsColor) { ! 2602: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 2603: INPUT_STATUS_1_COLOR); ! 2604: } else { ! 2605: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 2606: INPUT_STATUS_1_MONO); ! 2607: } ! 2608: ! 2609: for (i = 0; i < VGA_NUM_ATTRIB_CONT_PORTS; i++) { ! 2610: ! 2611: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2612: ATT_ADDRESS_PORT, (UCHAR)i); ! 2613: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2614: ATT_DATA_WRITE_PORT, *portValue++); ! 2615: ! 2616: } ! 2617: ! 2618: // ! 2619: // Restore DAC registers 1 through 255. We'll do register 0, the DAC Mask, ! 2620: // and the index registers later. ! 2621: // Set the DAC address port Index, then write out the DAC Data registers. ! 2622: // Each three reads get Red, Green, and Blue components for that register. ! 2623: // ! 2624: // Write them one at a time due to problems on local bus machines. ! 2625: // ! 2626: ! 2627: portValueDAC = (PUCHAR) hardwareStateHeader + ! 2628: hardwareStateHeader->BasicDacOffset + 3; ! 2629: ! 2630: for (i = 1; i < VGA_NUM_DAC_ENTRIES; i++) { ! 2631: ! 2632: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2633: DAC_ADDRESS_WRITE_PORT, (UCHAR)i); ! 2634: ! 2635: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2636: DAC_DATA_REG_PORT, *portValueDAC++); ! 2637: ! 2638: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2639: DAC_DATA_REG_PORT, *portValueDAC++); ! 2640: ! 2641: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2642: DAC_DATA_REG_PORT, *portValueDAC++); ! 2643: ! 2644: } ! 2645: ! 2646: // ! 2647: // Is this color or mono ? ! 2648: // ! 2649: ! 2650: if (bIsColor) { ! 2651: port = HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR; ! 2652: } else { ! 2653: port = HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO; ! 2654: } ! 2655: ! 2656: // ! 2657: // Restore the Feature Control register. ! 2658: // ! 2659: ! 2660: if (bIsColor) { ! 2661: ! 2662: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2663: FEAT_CTRL_WRITE_PORT_COLOR, ! 2664: hardwareStateHeader->PortValue[FEAT_CTRL_WRITE_PORT_COLOR]); ! 2665: ! 2666: } else { ! 2667: ! 2668: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2669: FEAT_CTRL_WRITE_PORT_MONO, ! 2670: hardwareStateHeader->PortValue[FEAT_CTRL_WRITE_PORT_MONO]); ! 2671: ! 2672: } ! 2673: ! 2674: ! 2675: // ! 2676: // Restore the Sequencer Index. ! 2677: // ! 2678: ! 2679: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2680: SEQ_ADDRESS_PORT, ! 2681: hardwareStateHeader->PortValue[SEQ_ADDRESS_PORT]); ! 2682: ! 2683: // ! 2684: // Restore the CRT Controller Index. ! 2685: // ! 2686: ! 2687: if (bIsColor) { ! 2688: ! 2689: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2690: CRTC_ADDRESS_PORT_COLOR, ! 2691: hardwareStateHeader->PortValue[CRTC_ADDRESS_PORT_COLOR]); ! 2692: ! 2693: } else { ! 2694: ! 2695: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2696: CRTC_ADDRESS_PORT_MONO, ! 2697: hardwareStateHeader->PortValue[CRTC_ADDRESS_PORT_MONO]); ! 2698: ! 2699: } ! 2700: ! 2701: ! 2702: // ! 2703: // Restore the Graphics Controller Index. ! 2704: // ! 2705: ! 2706: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2707: GRAPH_ADDRESS_PORT, ! 2708: hardwareStateHeader->PortValue[GRAPH_ADDRESS_PORT]); ! 2709: ! 2710: ! 2711: // ! 2712: // Restore the Attribute Controller Index and index/data toggle state. ! 2713: // ! 2714: ! 2715: if (bIsColor) { ! 2716: port = HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR; ! 2717: } else { ! 2718: port = HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO; ! 2719: } ! 2720: ! 2721: VideoPortReadPortUchar(port); // reset the toggle to Index state ! 2722: ! 2723: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2724: ATT_ADDRESS_PORT, // restore the AC Index ! 2725: hardwareStateHeader->PortValue[ATT_ADDRESS_PORT]); ! 2726: ! 2727: // ! 2728: // If the toggle should be in Data state, we're all set. If it should be in ! 2729: // Index state, reset it to that condition. ! 2730: // ! 2731: ! 2732: if (hardwareStateHeader->AttribIndexDataState == 0) { ! 2733: ! 2734: // ! 2735: // Reset the toggle to Index state. ! 2736: // ! 2737: ! 2738: VideoPortReadPortUchar(port); ! 2739: ! 2740: } ! 2741: ! 2742: ! 2743: // ! 2744: // Restore DAC register 0 and the DAC Mask, to unblank the screen. ! 2745: // ! 2746: ! 2747: portValueDAC = (PUCHAR) hardwareStateHeader + ! 2748: hardwareStateHeader->BasicDacOffset; ! 2749: ! 2750: // ! 2751: // Restore the DAC Mask register. ! 2752: // ! 2753: ! 2754: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2755: DAC_PIXEL_MASK_PORT, ! 2756: hardwareStateHeader->PortValue[DAC_PIXEL_MASK_PORT]); ! 2757: ! 2758: // ! 2759: // Restore DAC register 0. ! 2760: // ! 2761: ! 2762: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2763: DAC_ADDRESS_WRITE_PORT, 0); ! 2764: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2765: DAC_DATA_REG_PORT, *portValueDAC++); ! 2766: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2767: DAC_DATA_REG_PORT, *portValueDAC++); ! 2768: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2769: DAC_DATA_REG_PORT, *portValueDAC++); ! 2770: ! 2771: ! 2772: // ! 2773: // Restore the read/write state and the current index of the DAC. ! 2774: // ! 2775: // See whether the Read or Write Index was written to most recently. ! 2776: // (The upper nibble stored at DAC_STATE_PORT is the # of reads/writes ! 2777: // for the current index.) ! 2778: // ! 2779: ! 2780: if ((hardwareStateHeader->PortValue[DAC_STATE_PORT] & 0x0F) == 3) { ! 2781: ! 2782: // ! 2783: // The DAC Read Index was written to last. Restore the DAC by setting ! 2784: // up to read from the saved index - 1, because the way the Read ! 2785: // Index works is that it autoincrements after reading, so you actually ! 2786: // end up reading the data for the index you read at the DAC Write ! 2787: // Mask register - 1. ! 2788: // ! 2789: // Set the Read Index to the index we read, minus 1, accounting for ! 2790: // wrap from 255 back to 0. The DAC hardware immediately reads this ! 2791: // register into a temporary buffer, then adds 1 to the index. ! 2792: // ! 2793: ! 2794: if (hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT] == 0) { ! 2795: ! 2796: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2797: DAC_ADDRESS_READ_PORT, 255); ! 2798: ! 2799: } else { ! 2800: ! 2801: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2802: DAC_ADDRESS_READ_PORT, (UCHAR) ! 2803: (hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT] - ! 2804: 1)); ! 2805: ! 2806: } ! 2807: ! 2808: // ! 2809: // Now read the hardware however many times are required to get to ! 2810: // the partial read state we saved. ! 2811: // ! 2812: ! 2813: for (i = hardwareStateHeader->PortValue[DAC_STATE_PORT] >> 4; ! 2814: i > 0; i--) { ! 2815: ! 2816: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 2817: DAC_DATA_REG_PORT); ! 2818: ! 2819: } ! 2820: ! 2821: } else { ! 2822: ! 2823: // ! 2824: // The DAC Write Index was written to last. Set the Write Index to the ! 2825: // index value we read out of the DAC. Then, if a partial write ! 2826: // (partway through an RGB triplet) was in place, write the partial ! 2827: // values, which we obtained by writing them to the current DAC ! 2828: // register. This DAC register will be wrong until the write is ! 2829: // completed, but at least the values will be right once the write is ! 2830: // finished, and most importantly we won't have messed up the sequence ! 2831: // of RGB writes (which can be as long as 768 in a row). ! 2832: // ! 2833: ! 2834: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2835: DAC_ADDRESS_WRITE_PORT, ! 2836: hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT]); ! 2837: ! 2838: // ! 2839: // Now write to the hardware however many times are required to get to ! 2840: // the partial write state we saved (if any). ! 2841: // ! 2842: // Point to the saved value for the DAC register that was in the ! 2843: // process of being written to; we wrote the partial value out, so now ! 2844: // we can restore it. ! 2845: // ! 2846: ! 2847: portValueDAC = (PUCHAR) hardwareStateHeader + ! 2848: hardwareStateHeader->BasicDacOffset + ! 2849: (hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT] * 3); ! 2850: ! 2851: for (i = hardwareStateHeader->PortValue[DAC_STATE_PORT] >> 4; ! 2852: i > 0; i--) { ! 2853: ! 2854: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 2855: DAC_DATA_REG_PORT, *portValueDAC++); ! 2856: ! 2857: } ! 2858: ! 2859: } ! 2860: ! 2861: return NO_ERROR; ! 2862: ! 2863: } // end VgaRestoreHardwareState() ! 2864: ! 2865: //--------------------------------------------------------------------------- ! 2866: VP_STATUS ! 2867: VgaSaveHardwareState( ! 2868: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 2869: PVIDEO_HARDWARE_STATE HardwareState, ! 2870: ULONG HardwareStateSize, ! 2871: PULONG OutputSize ! 2872: ) ! 2873: ! 2874: /*++ ! 2875: ! 2876: Routine Description: ! 2877: ! 2878: Saves all registers and memory of the VGA. ! 2879: ! 2880: Note: HardwareState points to the actual buffer in which the state ! 2881: is saved. This buffer will always be big enough (we specified ! 2882: the required size at DriverEntry). ! 2883: ! 2884: Note: This routine leaves registers in any state it cares to, except ! 2885: that it will not mess with any of the CRT or Sequencer parameters that ! 2886: might make the monitor unhappy. It leaves the screen blanked by setting ! 2887: the DAC Mask and DAC register 0 to all zero values. The next video ! 2888: operation we expect after this is a mode set to take us back to Win32. ! 2889: ! 2890: Note: The offset in the hardware state header in which each general ! 2891: register is saved is the offset of the write address of that register from ! 2892: the base I/O address of the VGA. ! 2893: ! 2894: Arguments: ! 2895: ! 2896: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 2897: ! 2898: HardwareState - Pointer to a structure in which the saved state will be ! 2899: returned (actually only info about and a pointer to the actual save ! 2900: buffer). ! 2901: ! 2902: HardwareStateSize - Length of the output buffer supplied by the user. ! 2903: (Actually only the size of the HardwareState structure, not the ! 2904: buffer it points to where the state is actually saved. The pointed- ! 2905: to buffer is assumed to be big enough.) ! 2906: ! 2907: OutputSize - Pointer to a buffer in which to return the actual size of ! 2908: the data returned in the buffer. ! 2909: ! 2910: Return Value: ! 2911: ! 2912: NO_ERROR - information returned successfully ! 2913: ! 2914: ERROR_INSUFFICIENT_BUFFER - output buffer not large enough to return ! 2915: any useful data ! 2916: ! 2917: --*/ ! 2918: ! 2919: { ! 2920: PVIDEO_HARDWARE_STATE_HEADER hardwareStateHeader; ! 2921: PUCHAR port; ! 2922: PUCHAR pScreen; ! 2923: PUCHAR portValue; ! 2924: PUCHAR portValueDAC; ! 2925: PUCHAR bufferPointer; ! 2926: ULONG i; ! 2927: UCHAR dummy, originalACIndex, originalACData; ! 2928: UCHAR ucCRTC03; ! 2929: ULONG bIsColor; ! 2930: ! 2931: ! 2932: // ! 2933: // See if the buffer is big enough to hold the hardware state structure. ! 2934: // (This is only the HardwareState structure itself, not the buffer it ! 2935: // points to.) ! 2936: // ! 2937: ! 2938: if (HardwareStateSize < sizeof(VIDEO_HARDWARE_STATE) ) { ! 2939: ! 2940: *OutputSize = 0; // nothing returned ! 2941: return ERROR_INSUFFICIENT_BUFFER; ! 2942: ! 2943: } ! 2944: ! 2945: // ! 2946: // Amount of data we're going to return in the output buffer. ! 2947: // (The VIDEO_HARDWARE_STATE in the output buffer points to the actual ! 2948: // buffer in which the state is stored, which is assumed to be large ! 2949: // enough.) ! 2950: // ! 2951: ! 2952: *OutputSize = sizeof(VIDEO_HARDWARE_STATE); ! 2953: ! 2954: // ! 2955: // Indicate the size of the full state save info. ! 2956: // ! 2957: ! 2958: HardwareState->StateLength = VGA_TOTAL_STATE_SIZE; ! 2959: ! 2960: // ! 2961: // hardwareStateHeader is a structure of offsets at the start of the ! 2962: // actual save area that indicates the locations in which various VGA ! 2963: // register and memory components are saved. ! 2964: // ! 2965: ! 2966: hardwareStateHeader = HardwareState->StateHeader; ! 2967: ! 2968: // ! 2969: // Zero out the structure. ! 2970: // ! 2971: ! 2972: VideoPortZeroMemory(hardwareStateHeader, sizeof(VIDEO_HARDWARE_STATE_HEADER)); ! 2973: ! 2974: // ! 2975: // Set the Length field, which is basically a version ID. ! 2976: // ! 2977: ! 2978: hardwareStateHeader->Length = sizeof(VIDEO_HARDWARE_STATE_HEADER); ! 2979: ! 2980: // ! 2981: // Set the basic register offsets properly. ! 2982: // ! 2983: ! 2984: hardwareStateHeader->BasicSequencerOffset = VGA_BASIC_SEQUENCER_OFFSET; ! 2985: hardwareStateHeader->BasicCrtContOffset = VGA_BASIC_CRTC_OFFSET; ! 2986: hardwareStateHeader->BasicGraphContOffset = VGA_BASIC_GRAPH_CONT_OFFSET; ! 2987: hardwareStateHeader->BasicAttribContOffset = VGA_BASIC_ATTRIB_CONT_OFFSET; ! 2988: hardwareStateHeader->BasicDacOffset = VGA_BASIC_DAC_OFFSET; ! 2989: hardwareStateHeader->BasicLatchesOffset = VGA_BASIC_LATCHES_OFFSET; ! 2990: ! 2991: // ! 2992: // Set the entended register offsets properly. ! 2993: // ! 2994: ! 2995: hardwareStateHeader->ExtendedSequencerOffset = VGA_EXT_SEQUENCER_OFFSET; ! 2996: hardwareStateHeader->ExtendedCrtContOffset = VGA_EXT_CRTC_OFFSET; ! 2997: hardwareStateHeader->ExtendedGraphContOffset = VGA_EXT_GRAPH_CONT_OFFSET; ! 2998: hardwareStateHeader->ExtendedAttribContOffset = VGA_EXT_ATTRIB_CONT_OFFSET; ! 2999: hardwareStateHeader->ExtendedDacOffset = VGA_EXT_DAC_OFFSET; ! 3000: ! 3001: // ! 3002: // Figure out if color/mono switchable registers are at 3BX or 3DX. ! 3003: // At the same time, save the state of the Miscellaneous Output register ! 3004: // which is read from 3CC but written at 3C2. ! 3005: // ! 3006: ! 3007: if ((hardwareStateHeader->PortValue[MISC_OUTPUT_REG_WRITE_PORT] = ! 3008: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3009: MISC_OUTPUT_REG_READ_PORT)) ! 3010: & 0x01) { ! 3011: bIsColor = TRUE; ! 3012: } else { ! 3013: bIsColor = FALSE; ! 3014: } ! 3015: ! 3016: // ! 3017: // Force the video subsystem enable state to enabled. ! 3018: // ! 3019: ! 3020: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3021: VIDEO_SUBSYSTEM_ENABLE_PORT, 1); ! 3022: ! 3023: // ! 3024: // Save the DAC state first, so we can set the DAC to blank the screen ! 3025: // so nothing after this shows up at all. ! 3026: // ! 3027: // Save the DAC Mask register. ! 3028: // ! 3029: ! 3030: hardwareStateHeader->PortValue[DAC_PIXEL_MASK_PORT] = ! 3031: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3032: DAC_PIXEL_MASK_PORT); ! 3033: ! 3034: // ! 3035: // Save the DAC Index register. Note that there is actually only one DAC ! 3036: // Index register, which functions as either the Read Index or the Write ! 3037: // Index as needed. ! 3038: // ! 3039: ! 3040: hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT] = ! 3041: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3042: DAC_ADDRESS_WRITE_PORT); ! 3043: ! 3044: // ! 3045: // Save the DAC read/write state. We determine if the DAC has been written ! 3046: // to or read from at the current index 0, 1, or 2 times (the application ! 3047: // is in the middle of reading or writing a DAC register triplet if the ! 3048: // count is 1 or 2), and save enough info so we can restore things ! 3049: // properly. The only hole is if the application writes to the Write Index, ! 3050: // then reads from instead of writes to the Data register, or vice-versa, ! 3051: // or if they do a partial read write, then never finish it. ! 3052: // This is fairly ridiculous behavior, however, and anyway there's nothing ! 3053: // we can do about it. ! 3054: // ! 3055: ! 3056: hardwareStateHeader->PortValue[DAC_STATE_PORT] = ! 3057: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3058: DAC_STATE_PORT); ! 3059: ! 3060: if (hardwareStateHeader->PortValue[DAC_STATE_PORT] == 3) { ! 3061: ! 3062: // ! 3063: // The DAC Read Index was written to last. Figure out how many reads ! 3064: // have been done from the current index. We'll restart this on restore ! 3065: // by setting the Read Index to the current index - 1 (the read index ! 3066: // is one greater than the index being read), then doing the proper ! 3067: // number of reads. ! 3068: // ! 3069: // Read the Data register once, and see if the index changes. ! 3070: // ! 3071: ! 3072: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3073: DAC_DATA_REG_PORT); ! 3074: ! 3075: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3076: DAC_ADDRESS_WRITE_PORT) != ! 3077: hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT]) { ! 3078: ! 3079: // ! 3080: // The DAC Index changed, so two reads had already been done from ! 3081: // the current index. Store the count "2" in the upper nibble of ! 3082: // the read/write state field. ! 3083: // ! 3084: ! 3085: hardwareStateHeader->PortValue[DAC_STATE_PORT] |= 0x20; ! 3086: ! 3087: } else { ! 3088: ! 3089: // ! 3090: // Read the Data register again, and see if the index changes. ! 3091: // ! 3092: ! 3093: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3094: DAC_DATA_REG_PORT); ! 3095: ! 3096: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3097: DAC_ADDRESS_WRITE_PORT) != ! 3098: hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT]) { ! 3099: ! 3100: // ! 3101: // The DAC Index changed, so one read had already been done ! 3102: // from the current index. Store the count "1" in the upper ! 3103: // nibble of the read/write state field. ! 3104: // ! 3105: ! 3106: hardwareStateHeader->PortValue[DAC_STATE_PORT] |= 0x10; ! 3107: } ! 3108: ! 3109: // ! 3110: // If neither 2 nor 1 reads had been done from the current index, ! 3111: // then 0 reads were done, and we're all set, since the upper ! 3112: // nibble of the read/write state field is already 0. ! 3113: // ! 3114: ! 3115: } ! 3116: ! 3117: } else { ! 3118: ! 3119: // ! 3120: // The DAC Write Index was written to last. Figure out how many writes ! 3121: // have been done to the current index. We'll restart this on restore ! 3122: // by setting the Write Index to the proper index, then doing the ! 3123: // proper number of writes. When we do the DAC register save, we'll ! 3124: // read out the value that gets written (if there was a partial write ! 3125: // in progress), so we can restore the proper data later. This will ! 3126: // cause this current DAC location to be briefly wrong in the 1- and ! 3127: // 2-bytes-written case (until the app finishes the write), but that's ! 3128: // better than having the wrong DAC values written for good. ! 3129: // ! 3130: // Write the Data register once, and see if the index changes. ! 3131: // ! 3132: ! 3133: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3134: DAC_DATA_REG_PORT, 0); ! 3135: ! 3136: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3137: DAC_ADDRESS_WRITE_PORT) != ! 3138: hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT]) { ! 3139: ! 3140: // ! 3141: // The DAC Index changed, so two writes had already been done to ! 3142: // the current index. Store the count "2" in the upper nibble of ! 3143: // the read/write state field. ! 3144: // ! 3145: ! 3146: hardwareStateHeader->PortValue[DAC_STATE_PORT] |= 0x20; ! 3147: ! 3148: } else { ! 3149: ! 3150: // ! 3151: // Write the Data register again, and see if the index changes. ! 3152: // ! 3153: ! 3154: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3155: DAC_DATA_REG_PORT, 0); ! 3156: ! 3157: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3158: DAC_ADDRESS_WRITE_PORT) != ! 3159: hardwareStateHeader->PortValue[DAC_ADDRESS_WRITE_PORT]) { ! 3160: ! 3161: // ! 3162: // The DAC Index changed, so one write had already been done ! 3163: // to the current index. Store the count "1" in the upper ! 3164: // nibble of the read/write state field. ! 3165: // ! 3166: ! 3167: hardwareStateHeader->PortValue[DAC_STATE_PORT] |= 0x10; ! 3168: } ! 3169: ! 3170: // ! 3171: // If neither 2 nor 1 writes had been done to the current index, ! 3172: // then 0 writes were done, and we're all set. ! 3173: // ! 3174: ! 3175: } ! 3176: ! 3177: } ! 3178: ! 3179: // ! 3180: // Now, read out the 256 18-bit DAC palette registers (256 RGB triplets), ! 3181: // and blank the screen. ! 3182: // ! 3183: ! 3184: portValueDAC = (PUCHAR) hardwareStateHeader + VGA_BASIC_DAC_OFFSET; ! 3185: ! 3186: // ! 3187: // Read out DAC register 0, so we can set it to black. ! 3188: // ! 3189: ! 3190: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3191: DAC_ADDRESS_READ_PORT, 0); ! 3192: *portValueDAC++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3193: DAC_DATA_REG_PORT); ! 3194: *portValueDAC++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3195: DAC_DATA_REG_PORT); ! 3196: *portValueDAC++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3197: DAC_DATA_REG_PORT); ! 3198: ! 3199: // ! 3200: // Set DAC register 0 to display black. ! 3201: // ! 3202: ! 3203: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3204: DAC_ADDRESS_WRITE_PORT, 0); ! 3205: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3206: DAC_DATA_REG_PORT, 0); ! 3207: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3208: DAC_DATA_REG_PORT, 0); ! 3209: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3210: DAC_DATA_REG_PORT, 0); ! 3211: ! 3212: // ! 3213: // Set the DAC mask register to force DAC register 0 to display all the ! 3214: // time (this is the register we just set to display black). From now on, ! 3215: // nothing but black will show up on the screen. ! 3216: // ! 3217: ! 3218: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3219: DAC_PIXEL_MASK_PORT, 0); ! 3220: ! 3221: // ! 3222: // Read out the Attribute Controller Index state, and deduce the Index/Data ! 3223: // toggle state at the same time. ! 3224: // ! 3225: // Save the state of the Attribute Controller, both Index and Data, ! 3226: // so we can test in which state the toggle currently is. ! 3227: // ! 3228: ! 3229: originalACIndex = hardwareStateHeader->PortValue[ATT_ADDRESS_PORT] = ! 3230: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3231: ATT_ADDRESS_PORT); ! 3232: originalACData = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3233: ATT_DATA_READ_PORT); ! 3234: ! 3235: // ! 3236: // Sequencer Index. ! 3237: // ! 3238: ! 3239: hardwareStateHeader->PortValue[SEQ_ADDRESS_PORT] = ! 3240: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3241: SEQ_ADDRESS_PORT); ! 3242: ! 3243: // ! 3244: // Begin sync reset, just in case this is an SVGA and the currently ! 3245: // indexed Attribute Controller register controls clocking stuff (a ! 3246: // normal VGA won't require this). ! 3247: // ! 3248: ! 3249: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 3250: SEQ_ADDRESS_PORT), ! 3251: (USHORT) (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8))); ! 3252: ! 3253: // ! 3254: // Now, write a different Index setting to the Attribute Controller, and ! 3255: // see if the Index changes. ! 3256: // ! 3257: ! 3258: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3259: ATT_ADDRESS_PORT, (UCHAR) (originalACIndex ^ 0x10)); ! 3260: ! 3261: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3262: ATT_ADDRESS_PORT) == originalACIndex) { ! 3263: ! 3264: // ! 3265: // The Index didn't change, so the toggle was in the Data state. ! 3266: // ! 3267: ! 3268: hardwareStateHeader->AttribIndexDataState = 1; ! 3269: ! 3270: // ! 3271: // Restore the original Data state; we just corrupted it, and we need ! 3272: // to read it out later; also, it may glitch the screen if not ! 3273: // corrected. The toggle is already in the Index state. ! 3274: // ! 3275: ! 3276: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3277: ATT_ADDRESS_PORT, originalACIndex); ! 3278: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3279: ATT_DATA_WRITE_PORT, originalACData); ! 3280: ! 3281: } else { ! 3282: ! 3283: // ! 3284: // The Index did change, so the toggle was in the Index state. ! 3285: // No need to restore anything, because the Data register didn't ! 3286: // change, and we've already read out the Index register. ! 3287: // ! 3288: ! 3289: hardwareStateHeader->AttribIndexDataState = 0; ! 3290: ! 3291: } ! 3292: ! 3293: // ! 3294: // End sync reset. ! 3295: // ! 3296: ! 3297: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 3298: SEQ_ADDRESS_PORT), ! 3299: (USHORT) (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8))); ! 3300: ! 3301: ! 3302: ! 3303: // ! 3304: // Save the rest of the DAC registers. ! 3305: // Set the DAC address port Index, then read out the DAC Data registers. ! 3306: // Each three reads get Red, Green, and Blue components for that register. ! 3307: // ! 3308: // Read them one at a time due to problems on local bus machines. ! 3309: // ! 3310: ! 3311: for (i = 1; i < VGA_NUM_DAC_ENTRIES; i++) { ! 3312: ! 3313: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3314: DAC_ADDRESS_READ_PORT, (UCHAR)i); ! 3315: ! 3316: *portValueDAC++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3317: DAC_DATA_REG_PORT); ! 3318: ! 3319: *portValueDAC++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3320: DAC_DATA_REG_PORT); ! 3321: ! 3322: *portValueDAC++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3323: DAC_DATA_REG_PORT); ! 3324: ! 3325: } ! 3326: ! 3327: // ! 3328: // Is this color or mono ? ! 3329: // ! 3330: ! 3331: if (bIsColor) { ! 3332: port = HwDeviceExtension->IOAddress + INPUT_STATUS_1_COLOR; ! 3333: } else { ! 3334: port = HwDeviceExtension->IOAddress + INPUT_STATUS_1_MONO; ! 3335: } ! 3336: ! 3337: // ! 3338: // The Feature Control register is read from 3CA but written at 3BA/3DA. ! 3339: // ! 3340: ! 3341: if (bIsColor) { ! 3342: ! 3343: hardwareStateHeader->PortValue[FEAT_CTRL_WRITE_PORT_COLOR] = ! 3344: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3345: FEAT_CTRL_READ_PORT); ! 3346: ! 3347: } else { ! 3348: ! 3349: hardwareStateHeader->PortValue[FEAT_CTRL_WRITE_PORT_MONO] = ! 3350: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3351: FEAT_CTRL_READ_PORT); ! 3352: ! 3353: } ! 3354: ! 3355: // ! 3356: // CRT Controller Index. ! 3357: // ! 3358: ! 3359: if (bIsColor) { ! 3360: ! 3361: hardwareStateHeader->PortValue[CRTC_ADDRESS_PORT_COLOR] = ! 3362: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3363: CRTC_ADDRESS_PORT_COLOR); ! 3364: ! 3365: } else { ! 3366: ! 3367: hardwareStateHeader->PortValue[CRTC_ADDRESS_PORT_MONO] = ! 3368: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3369: CRTC_ADDRESS_PORT_MONO); ! 3370: ! 3371: } ! 3372: ! 3373: // ! 3374: // Graphics Controller Index. ! 3375: // ! 3376: ! 3377: hardwareStateHeader->PortValue[GRAPH_ADDRESS_PORT] = ! 3378: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3379: GRAPH_ADDRESS_PORT); ! 3380: ! 3381: ! 3382: // ! 3383: // Sequencer indexed registers. ! 3384: // ! 3385: ! 3386: portValue = ((PUCHAR) hardwareStateHeader) + VGA_BASIC_SEQUENCER_OFFSET; ! 3387: ! 3388: for (i = 0; i < VGA_NUM_SEQUENCER_PORTS; i++) { ! 3389: ! 3390: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3391: SEQ_ADDRESS_PORT, (UCHAR)i); ! 3392: *portValue++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3393: SEQ_DATA_PORT); ! 3394: ! 3395: } ! 3396: ! 3397: // ! 3398: // Save extended sequencer registers. ! 3399: // ! 3400: ! 3401: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 3402: ! 3403: portValue = ((PUCHAR) hardwareStateHeader) + VGA_EXT_SEQUENCER_OFFSET; ! 3404: ! 3405: if (HwDeviceExtension->ChipType == CL542x) { ! 3406: ! 3407: // ! 3408: // No extended sequencer registers for the CL64xx ! 3409: // ! 3410: ! 3411: for (i = CL542x_SEQUENCER_EXT_START; ! 3412: i <= CL542x_SEQUENCER_EXT_END; ! 3413: i++) { ! 3414: ! 3415: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3416: SEQ_ADDRESS_PORT, (UCHAR)i); ! 3417: ! 3418: *portValue++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3419: SEQ_DATA_PORT); ! 3420: ! 3421: } ! 3422: } ! 3423: ! 3424: #endif ! 3425: ! 3426: // ! 3427: // CRT Controller indexed registers. ! 3428: // ! 3429: ! 3430: // ! 3431: // Remember the state of CRTC register 3, then force bit 7 ! 3432: // to 1 so we will read back the Vertical Retrace start and ! 3433: // end registers rather than the light pen info. ! 3434: // ! 3435: ! 3436: if (bIsColor) { ! 3437: ! 3438: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3439: CRTC_ADDRESS_PORT_COLOR, 3); ! 3440: ucCRTC03 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3441: CRTC_DATA_PORT_COLOR); ! 3442: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3443: CRTC_DATA_PORT_COLOR, (UCHAR) (ucCRTC03 | 0x80)); ! 3444: } else { ! 3445: ! 3446: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3447: CRTC_ADDRESS_PORT_MONO, 3); ! 3448: ucCRTC03 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3449: CRTC_DATA_PORT_MONO); ! 3450: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3451: CRTC_DATA_PORT_MONO, (UCHAR) (ucCRTC03 | 0x80)); ! 3452: } ! 3453: ! 3454: portValue = (PUCHAR) hardwareStateHeader + VGA_BASIC_CRTC_OFFSET; ! 3455: ! 3456: for (i = 0; i < VGA_NUM_CRTC_PORTS; i++) { ! 3457: ! 3458: if (bIsColor) { ! 3459: ! 3460: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3461: CRTC_ADDRESS_PORT_COLOR, (UCHAR)i); ! 3462: *portValue++ = ! 3463: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3464: CRTC_DATA_PORT_COLOR); ! 3465: } ! 3466: else { ! 3467: ! 3468: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3469: CRTC_ADDRESS_PORT_MONO, (UCHAR)i); ! 3470: *portValue++ = ! 3471: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3472: CRTC_DATA_PORT_MONO); ! 3473: } ! 3474: ! 3475: } ! 3476: ! 3477: portValue = (PUCHAR) hardwareStateHeader + VGA_BASIC_CRTC_OFFSET; ! 3478: portValue[3] = ucCRTC03; ! 3479: ! 3480: ! 3481: // ! 3482: // Save extended crtc registers. ! 3483: // ! 3484: ! 3485: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 3486: ! 3487: portValue = (PUCHAR) hardwareStateHeader + VGA_EXT_CRTC_OFFSET; ! 3488: ! 3489: if (HwDeviceExtension->ChipType == CL542x) { ! 3490: ! 3491: // ! 3492: // No CRTC Extensions in CL64xx chipset ! 3493: // ! 3494: ! 3495: for (i = CL542x_CRTC_EXT_START; i <= CL542x_CRTC_EXT_END; i++) { ! 3496: ! 3497: if (bIsColor) { ! 3498: ! 3499: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3500: CRTC_ADDRESS_PORT_COLOR, (UCHAR)i); ! 3501: ! 3502: *portValue++ = ! 3503: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3504: CRTC_DATA_PORT_COLOR); ! 3505: ! 3506: } else { ! 3507: ! 3508: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3509: CRTC_ADDRESS_PORT_MONO, (UCHAR)i); ! 3510: ! 3511: *portValue++ = ! 3512: VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3513: CRTC_DATA_PORT_MONO); ! 3514: } ! 3515: } ! 3516: } ! 3517: ! 3518: #endif ! 3519: ! 3520: // ! 3521: // Graphics Controller indexed registers. ! 3522: // ! 3523: ! 3524: portValue = (PUCHAR) hardwareStateHeader + VGA_BASIC_GRAPH_CONT_OFFSET; ! 3525: ! 3526: for (i = 0; i < VGA_NUM_GRAPH_CONT_PORTS; i++) { ! 3527: ! 3528: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3529: GRAPH_ADDRESS_PORT, (UCHAR)i); ! 3530: *portValue++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3531: GRAPH_DATA_PORT); ! 3532: ! 3533: } ! 3534: ! 3535: // ! 3536: // Save extended graphics controller registers. ! 3537: // ! 3538: ! 3539: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 3540: ! 3541: portValue = (PUCHAR) hardwareStateHeader + VGA_EXT_GRAPH_CONT_OFFSET; ! 3542: ! 3543: if (HwDeviceExtension->ChipType == CL542x) { ! 3544: ! 3545: for (i = CL542x_GRAPH_EXT_START; i <= CL542x_GRAPH_EXT_END; i++) { ! 3546: ! 3547: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3548: GRAPH_ADDRESS_PORT, (UCHAR)i); ! 3549: ! 3550: *portValue++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3551: GRAPH_DATA_PORT); ! 3552: ! 3553: } ! 3554: ! 3555: } else { // must be a CL64xx ! 3556: ! 3557: for (i = CL64xx_GRAPH_EXT_START; i <= CL64xx_GRAPH_EXT_END; i++) { ! 3558: ! 3559: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3560: GRAPH_ADDRESS_PORT, (UCHAR)i); ! 3561: ! 3562: *portValue++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3563: GRAPH_DATA_PORT); ! 3564: } ! 3565: } ! 3566: ! 3567: #endif ! 3568: ! 3569: // ! 3570: // Attribute Controller indexed registers. ! 3571: // ! 3572: ! 3573: portValue = (PUCHAR) hardwareStateHeader + VGA_BASIC_ATTRIB_CONT_OFFSET; ! 3574: ! 3575: // ! 3576: // For each indexed AC register, reset the flip-flop for reading the ! 3577: // attribute register, then write the desired index to the AC Index, ! 3578: // then read the value of the indexed register from the AC Data register. ! 3579: // ! 3580: ! 3581: for (i = 0; i < VGA_NUM_ATTRIB_CONT_PORTS; i++) { ! 3582: ! 3583: if (bIsColor) { ! 3584: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3585: INPUT_STATUS_1_COLOR); ! 3586: } else { ! 3587: dummy = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3588: INPUT_STATUS_1_MONO); ! 3589: } ! 3590: ! 3591: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3592: ATT_ADDRESS_PORT, (UCHAR)i); ! 3593: *portValue++ = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3594: ATT_DATA_READ_PORT); ! 3595: ! 3596: } ! 3597: ! 3598: // ! 3599: // Save the latches. This destroys one byte of display memory in each ! 3600: // plane, which is unfortunate but unavoidable. Chips that provide ! 3601: // a way to read back the latches can avoid this problem. ! 3602: // ! 3603: // Set up the VGA's hardware so we can write the latches, then read them ! 3604: // back. ! 3605: // ! 3606: ! 3607: // ! 3608: // Begin sync reset. ! 3609: // ! 3610: ! 3611: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 3612: SEQ_ADDRESS_PORT), ! 3613: (USHORT) (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8))); ! 3614: ! 3615: // ! 3616: // Set the Miscellaneous register to make sure we can access video RAM. ! 3617: // ! 3618: ! 3619: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3620: MISC_OUTPUT_REG_WRITE_PORT, (UCHAR)( ! 3621: hardwareStateHeader->PortValue[MISC_OUTPUT_REG_WRITE_PORT] | ! 3622: 0x02)); ! 3623: ! 3624: // ! 3625: // Turn off Chain mode and map display memory at A0000 for 64K. ! 3626: // ! 3627: ! 3628: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3629: GRAPH_ADDRESS_PORT, IND_GRAPH_MISC); ! 3630: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3631: GRAPH_DATA_PORT, ! 3632: (UCHAR) ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3633: GRAPH_DATA_PORT) & 0xF1) | 0x04)); ! 3634: ! 3635: // ! 3636: // Turn off Chain4 mode and odd/even. ! 3637: // ! 3638: ! 3639: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3640: SEQ_ADDRESS_PORT, IND_MEMORY_MODE); ! 3641: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3642: SEQ_DATA_PORT, ! 3643: (UCHAR) ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3644: SEQ_DATA_PORT) & 0xF3) | 0x04)); ! 3645: ! 3646: // ! 3647: // End sync reset. ! 3648: // ! 3649: ! 3650: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 3651: SEQ_ADDRESS_PORT), ! 3652: (USHORT) (IND_SYNC_RESET + (END_SYNC_RESET_VALUE << 8))); ! 3653: ! 3654: // ! 3655: // Set the Map Mask to write to all planes. ! 3656: // ! 3657: ! 3658: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 3659: SEQ_ADDRESS_PORT), (USHORT) (IND_MAP_MASK + (0x0F << 8))); ! 3660: ! 3661: // ! 3662: // Set the write mode to 0, the read mode to 0, and turn off odd/even. ! 3663: // ! 3664: ! 3665: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3666: GRAPH_ADDRESS_PORT, IND_GRAPH_MODE); ! 3667: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3668: GRAPH_DATA_PORT, ! 3669: (UCHAR) ((VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 3670: GRAPH_DATA_PORT) & 0xE4) | 0x01)); ! 3671: ! 3672: // ! 3673: // Point to the last byte of display memory. ! 3674: // ! 3675: ! 3676: pScreen = (PUCHAR) HwDeviceExtension->VideoMemoryAddress + ! 3677: VGA_PLANE_SIZE - 1; ! 3678: ! 3679: // ! 3680: // Write the latches to the last byte of display memory. ! 3681: // ! 3682: ! 3683: VideoPortWriteRegisterUchar(pScreen, 0); ! 3684: ! 3685: // ! 3686: // Cycle through the four planes, reading the latch data from each plane. ! 3687: // ! 3688: ! 3689: // ! 3690: // Point the Graphics Controller Index to the Read Map register. ! 3691: // ! 3692: ! 3693: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3694: GRAPH_ADDRESS_PORT, IND_READ_MAP); ! 3695: ! 3696: portValue = (PUCHAR) hardwareStateHeader + VGA_BASIC_LATCHES_OFFSET; ! 3697: ! 3698: for (i=0; i<4; i++) { ! 3699: ! 3700: // ! 3701: // Set the Read Map for the current plane. ! 3702: // ! 3703: ! 3704: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3705: GRAPH_DATA_PORT, (UCHAR)i); ! 3706: ! 3707: // ! 3708: // Read the latched data we've written to memory. ! 3709: // ! 3710: ! 3711: *portValue++ = VideoPortReadRegisterUchar(pScreen); ! 3712: ! 3713: } ! 3714: ! 3715: // ! 3716: // Set the VDM flags ! 3717: // We are a standard VGA, and then check if we have unemulated state. ! 3718: // ! 3719: ! 3720: hardwareStateHeader->VGAStateFlags = 0; ! 3721: ! 3722: #ifdef EXTENDED_REGISTER_SAVE_RESTORE ! 3723: ! 3724: hardwareStateHeader->VGAStateFlags |= VIDEO_STATE_NON_STANDARD_VGA; ! 3725: ! 3726: #endif ! 3727: ! 3728: if (HwDeviceExtension->TrappedValidatorCount) { ! 3729: ! 3730: hardwareStateHeader->VGAStateFlags |= VIDEO_STATE_UNEMULATED_VGA_STATE; ! 3731: ! 3732: // ! 3733: // Save the VDM Emulator data ! 3734: // No need to save the state of the seuencer port register for our ! 3735: // emulated data since it may change when we come back. It will be ! 3736: // recomputed. ! 3737: // ! 3738: ! 3739: hardwareStateHeader->ExtendedValidatorStateOffset = VGA_VALIDATOR_OFFSET; ! 3740: ! 3741: VideoPortMoveMemory(((PUCHAR) (hardwareStateHeader)) + ! 3742: hardwareStateHeader->ExtendedValidatorStateOffset, ! 3743: &(HwDeviceExtension->TrappedValidatorCount), ! 3744: VGA_VALIDATOR_AREA_SIZE); ! 3745: ! 3746: } else { ! 3747: ! 3748: hardwareStateHeader->ExtendedValidatorStateOffset = 0; ! 3749: ! 3750: } ! 3751: ! 3752: // ! 3753: // Set the size of each plane. ! 3754: // ! 3755: ! 3756: hardwareStateHeader->PlaneLength = VGA_PLANE_SIZE; ! 3757: ! 3758: // ! 3759: // Store all the offsets for the planes in the structure. ! 3760: // ! 3761: ! 3762: hardwareStateHeader->Plane1Offset = VGA_PLANE_0_OFFSET; ! 3763: hardwareStateHeader->Plane2Offset = VGA_PLANE_1_OFFSET; ! 3764: hardwareStateHeader->Plane3Offset = VGA_PLANE_2_OFFSET; ! 3765: hardwareStateHeader->Plane4Offset = VGA_PLANE_3_OFFSET; ! 3766: ! 3767: // ! 3768: // Now copy the contents of video VRAM into the buffer. ! 3769: // ! 3770: // The VGA hardware is already set up so that video memory is readable; ! 3771: // we already turned off Chain mode, mapped in at A0000, turned off Chain4, ! 3772: // turned off odd/even, and set read mode 0 when we saved the latches. ! 3773: // ! 3774: // Point the Graphics Controller Index to the Read Map register. ! 3775: // ! 3776: ! 3777: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3778: GRAPH_ADDRESS_PORT, IND_READ_MAP); ! 3779: ! 3780: // ! 3781: // Point to the save area for the first plane. ! 3782: // ! 3783: ! 3784: bufferPointer = ((PUCHAR) (hardwareStateHeader)) + ! 3785: hardwareStateHeader->Plane1Offset; ! 3786: ! 3787: // ! 3788: // Save the four planes consecutively. ! 3789: // ! 3790: ! 3791: for (i = 0; i < 4; i++) { ! 3792: ! 3793: // ! 3794: // Set the Read Map to select the plane we want to save next. ! 3795: // ! 3796: ! 3797: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 3798: GRAPH_DATA_PORT, (UCHAR)i); ! 3799: ! 3800: // ! 3801: // Copy this plane into the buffer. ! 3802: // ! 3803: ! 3804: VideoPortMoveMemory(bufferPointer, ! 3805: (PUCHAR) HwDeviceExtension->VideoMemoryAddress, ! 3806: VGA_PLANE_SIZE); ! 3807: // ! 3808: // Point to the next plane's save area. ! 3809: // ! 3810: ! 3811: bufferPointer += VGA_PLANE_SIZE; ! 3812: } ! 3813: ! 3814: return NO_ERROR; ! 3815: ! 3816: } // end VgaSaveHardwareState() ! 3817: ! 3818: //--------------------------------------------------------------------------- ! 3819: VP_STATUS ! 3820: VgaGetBankSelectCode( ! 3821: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 3822: PVIDEO_BANK_SELECT BankSelect, ! 3823: ULONG BankSelectSize, ! 3824: PULONG OutputSize ! 3825: ) ! 3826: ! 3827: /*++ ! 3828: ! 3829: Routine Description: ! 3830: ! 3831: Returns information needed in order for caller to implement bank ! 3832: management. ! 3833: ! 3834: Arguments: ! 3835: ! 3836: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 3837: ! 3838: BankSelect - Pointer to a VIDEO_BANK_SELECT structure in which the bank ! 3839: select data will be returned (output buffer). ! 3840: ! 3841: BankSelectSize - Length of the output buffer supplied by the user. ! 3842: ! 3843: OutputSize - Pointer to a variable in which to return the actual size of ! 3844: the data returned in the output buffer. ! 3845: ! 3846: Return Value: ! 3847: ! 3848: NO_ERROR - information returned successfully ! 3849: ! 3850: ERROR_MORE_DATA - output buffer not large enough to hold all info (but ! 3851: Size is returned, so caller can tell how large a buffer to allocate) ! 3852: ! 3853: ERROR_INSUFFICIENT_BUFFER - output buffer not large enough to return ! 3854: any useful data ! 3855: ! 3856: ERROR_INVALID_PARAMETER - invalid video mode selection ! 3857: ! 3858: --*/ ! 3859: ! 3860: { ! 3861: ! 3862: ULONG codeSize; ! 3863: ULONG codePlanarSize; ! 3864: ULONG codeEnablePlanarSize; ! 3865: ULONG codeDisablePlanarSize; ! 3866: PUCHAR pCodeDest; ! 3867: PUCHAR pCodeBank; ! 3868: PUCHAR pCodePlanarBank; ! 3869: PUCHAR pCodeEnablePlanar; ! 3870: PUCHAR pCodeDisablePlanar; ! 3871: ! 3872: ULONG AdapterType = HwDeviceExtension->ChipType; ! 3873: PVIDEOMODE pMode = HwDeviceExtension->CurrentMode; ! 3874: ! 3875: // ! 3876: // The minimum passed buffer size is a VIDEO_BANK_SELECT ! 3877: // structure, so that we can return the required size; we can't do ! 3878: // anything if we don't have at least that much buffer. ! 3879: // ! 3880: ! 3881: if (BankSelectSize < sizeof(VIDEO_BANK_SELECT)) { ! 3882: ! 3883: return ERROR_INSUFFICIENT_BUFFER; ! 3884: ! 3885: } ! 3886: ! 3887: // ! 3888: // Determine the banking type, and set whether any banking is actually ! 3889: // supported in this mode. ! 3890: // ! 3891: ! 3892: BankSelect->BankingFlags = 0; ! 3893: codeSize = 0; ! 3894: codePlanarSize = 0; ! 3895: pCodeBank = NULL; ! 3896: ! 3897: switch(pMode->banktype) { ! 3898: ! 3899: case NoBanking: ! 3900: ! 3901: BankSelect->BankingType = VideoNotBanked; ! 3902: BankSelect->Granularity = 0; ! 3903: ! 3904: break; ! 3905: ! 3906: case PlanarHCBanking: ! 3907: ! 3908: BankSelect->BankingFlags = PLANAR_HC; // planar mode supported ! 3909: ! 3910: #if ONE_64K_BANK ! 3911: // ! 3912: // The Cirrus Logic VGA's support one 64K read/write bank. ! 3913: // ! 3914: ! 3915: BankSelect->PlanarHCBankingType = VideoBanked1RW; ! 3916: BankSelect->PlanarHCGranularity = 0x10000; // 64K bank start adjustment ! 3917: // in planar HC mode as well ! 3918: #endif ! 3919: #if TWO_32K_BANKS ! 3920: // ! 3921: // The Cirrus Logic VGA's support two 32K read/write banks. ! 3922: // ! 3923: ! 3924: BankSelect->PlanarHCBankingType = VideoBanked2RW; ! 3925: BankSelect->PlanarHCGranularity = 0x8000; // 32K bank start adjustment ! 3926: // in planar HC mode as well ! 3927: #endif ! 3928: ! 3929: // 64K bank start adjustment in planar HC mode as well ! 3930: ! 3931: if (HwDeviceExtension->ChipType == CL542x) { ! 3932: ! 3933: codePlanarSize = ((ULONG)&CL542xPlanarHCBankSwitchEnd) - ! 3934: ((ULONG)&CL542xPlanarHCBankSwitchStart); ! 3935: ! 3936: codeEnablePlanarSize = ((ULONG)&CL542xEnablePlanarHCEnd) - ! 3937: ((ULONG)&CL542xEnablePlanarHCStart); ! 3938: ! 3939: codeDisablePlanarSize = ((ULONG)&CL542xDisablePlanarHCEnd) - ! 3940: ((ULONG)&CL542xDisablePlanarHCStart); ! 3941: ! 3942: pCodePlanarBank = &CL542xPlanarHCBankSwitchStart; ! 3943: pCodeEnablePlanar = &CL542xEnablePlanarHCStart; ! 3944: pCodeDisablePlanar = &CL542xDisablePlanarHCStart; ! 3945: ! 3946: } else { // must be a CL64xx product ! 3947: ! 3948: codePlanarSize = ((ULONG)&CL64xxPlanarHCBankSwitchEnd) - ! 3949: ((ULONG)&CL64xxPlanarHCBankSwitchStart); ! 3950: ! 3951: codeEnablePlanarSize = ((ULONG)&CL64xxEnablePlanarHCEnd) - ! 3952: ((ULONG)&CL64xxEnablePlanarHCStart); ! 3953: ! 3954: codeDisablePlanarSize = ((ULONG)&CL64xxDisablePlanarHCEnd) - ! 3955: ((ULONG)&CL64xxDisablePlanarHCStart); ! 3956: ! 3957: pCodePlanarBank = &CL64xxPlanarHCBankSwitchStart; ! 3958: pCodeEnablePlanar = &CL64xxEnablePlanarHCStart; ! 3959: pCodeDisablePlanar = &CL64xxDisablePlanarHCStart; ! 3960: ! 3961: ! 3962: } ! 3963: ! 3964: // ! 3965: // Fall through to the normal banking case ! 3966: // ! 3967: ! 3968: case NormalBanking: ! 3969: ! 3970: #if ONE_64K_BANK ! 3971: // ! 3972: // The Cirrus Logic VGA's support one 64K read/write bank. ! 3973: // ! 3974: ! 3975: BankSelect->BankingType = VideoBanked1RW; ! 3976: BankSelect->Granularity = 0x10000; ! 3977: #endif ! 3978: #if TWO_32K_BANKS ! 3979: // ! 3980: // The Cirrus Logic VGA's support two 32K read/write banks. ! 3981: // ! 3982: ! 3983: BankSelect->BankingType = VideoBanked2RW; ! 3984: BankSelect->Granularity = 0x8000; ! 3985: #endif ! 3986: ! 3987: if (AdapterType == CL542x) { ! 3988: ! 3989: codeSize = ((ULONG)&CL542xBankSwitchEnd) - ! 3990: ((ULONG)&CL542xBankSwitchStart); ! 3991: ! 3992: pCodeBank = &CL542xBankSwitchStart; ! 3993: ! 3994: } else { // must be a CL64xx ! 3995: ! 3996: codeSize = ((ULONG)&CL64xxBankSwitchEnd) - ! 3997: ((ULONG)&CL64xxBankSwitchStart); ! 3998: ! 3999: pCodeBank = &CL64xxBankSwitchStart; ! 4000: ! 4001: } ! 4002: ! 4003: break; ! 4004: } ! 4005: ! 4006: // ! 4007: // Size of banking info. ! 4008: // ! 4009: ! 4010: BankSelect->Size = sizeof(VIDEO_BANK_SELECT) + codeSize; ! 4011: ! 4012: if (BankSelect->BankingFlags & PLANAR_HC) { ! 4013: ! 4014: BankSelect->Size += codePlanarSize + codeEnablePlanarSize + ! 4015: codeDisablePlanarSize; ! 4016: ! 4017: } ! 4018: ! 4019: // ! 4020: // This serves an a ID for the version of the structure we're using. ! 4021: // ! 4022: ! 4023: BankSelect->Length = sizeof(VIDEO_BANK_SELECT); ! 4024: ! 4025: // ! 4026: // If the buffer isn't big enough to hold all info, just return ! 4027: // ERROR_MORE_DATA; Size is already set. ! 4028: // ! 4029: ! 4030: if (BankSelectSize < BankSelect->Size ) { ! 4031: ! 4032: // ! 4033: // We're returning only the VIDEO_BANK_SELECT structure. ! 4034: // ! 4035: ! 4036: *OutputSize = sizeof(VIDEO_BANK_SELECT); ! 4037: return ERROR_MORE_DATA; ! 4038: } ! 4039: ! 4040: // ! 4041: // There's room enough for everything, so fill in all fields in ! 4042: // VIDEO_BANK_SELECT. (All fields are always returned; the caller can ! 4043: // just choose to ignore them, based on BankingFlags and BankingType.) ! 4044: // ! 4045: ! 4046: BankSelect->BitmapWidthInBytes = pMode->wbytes; ! 4047: BankSelect->BitmapSize = pMode->sbytes; ! 4048: ! 4049: // ! 4050: // Copy all banking code into the output buffer. ! 4051: // ! 4052: ! 4053: pCodeDest = (PUCHAR)BankSelect + sizeof(VIDEO_BANK_SELECT); ! 4054: ! 4055: if (pCodeBank != NULL) { ! 4056: ! 4057: BankSelect->CodeOffset = pCodeDest - (PUCHAR)BankSelect; ! 4058: ! 4059: VideoPortMoveMemory(pCodeDest, ! 4060: pCodeBank, ! 4061: codeSize); ! 4062: ! 4063: pCodeDest += codeSize; ! 4064: } ! 4065: ! 4066: if (BankSelect->BankingFlags & PLANAR_HC) { ! 4067: ! 4068: // ! 4069: // Copy appropriate high-color planar Bank Switch code: ! 4070: // ! 4071: ! 4072: BankSelect->PlanarHCBankCodeOffset = pCodeDest - (PUCHAR)BankSelect; ! 4073: ! 4074: VideoPortMoveMemory(pCodeDest, ! 4075: pCodePlanarBank, ! 4076: codePlanarSize); ! 4077: ! 4078: pCodeDest += codePlanarSize; ! 4079: ! 4080: // ! 4081: // Copy high-color planar bank mode Enable code: ! 4082: // ! 4083: ! 4084: BankSelect->PlanarHCEnableCodeOffset = pCodeDest - (PUCHAR)BankSelect; ! 4085: ! 4086: VideoPortMoveMemory(pCodeDest, ! 4087: pCodeEnablePlanar, ! 4088: codeEnablePlanarSize); ! 4089: ! 4090: pCodeDest += codeEnablePlanarSize; ! 4091: ! 4092: // ! 4093: // Copy high-color planar bank mode Disable code: ! 4094: // ! 4095: ! 4096: BankSelect->PlanarHCDisableCodeOffset = pCodeDest - (PUCHAR)BankSelect; ! 4097: ! 4098: VideoPortMoveMemory(pCodeDest, ! 4099: pCodeDisablePlanar, ! 4100: codeDisablePlanarSize); ! 4101: ! 4102: } ! 4103: ! 4104: // ! 4105: // Number of bytes we're returning is the full banking info size. ! 4106: // ! 4107: ! 4108: *OutputSize = BankSelect->Size; ! 4109: ! 4110: return NO_ERROR; ! 4111: ! 4112: } // end VgaGetBankSelectCode() ! 4113: ! 4114: //--------------------------------------------------------------------------- ! 4115: VP_STATUS ! 4116: VgaValidatorUcharEntry( ! 4117: ULONG Context, ! 4118: ULONG Port, ! 4119: UCHAR AccessMode, ! 4120: PUCHAR Data ! 4121: ) ! 4122: ! 4123: /*++ ! 4124: ! 4125: Routine Description: ! 4126: ! 4127: Entry point into the validator for byte I/O operations. ! 4128: ! 4129: The entry point will be called whenever a byte operation was performed ! 4130: by a DOS application on one of the specified Video ports. The kernel ! 4131: emulator will forward these requests. ! 4132: ! 4133: Arguments: ! 4134: ! 4135: Context - Context value that is passed to each call made to the validator ! 4136: function. This is the value the miniport driver specified in the ! 4137: MiniportConfigInfo->EmulatorAccessEntriesContext. ! 4138: ! 4139: Port - Port on which the operation is to be performed. ! 4140: ! 4141: AccessMode - Determines if it is a read or write operation. ! 4142: ! 4143: Data - Pointer to a variable containing the data to be written or a ! 4144: variable into which the read data should be stored. ! 4145: ! 4146: Return Value: ! 4147: ! 4148: NO_ERROR. ! 4149: ! 4150: --*/ ! 4151: ! 4152: { ! 4153: ! 4154: PHW_DEVICE_EXTENSION hwDeviceExtension = (PHW_DEVICE_EXTENSION) Context; ! 4155: ULONG endEmulation; ! 4156: UCHAR temp; ! 4157: ! 4158: Port -= VGA_BASE_IO_PORT; ! 4159: ! 4160: if (hwDeviceExtension->TrappedValidatorCount) { ! 4161: ! 4162: // ! 4163: // If we are processing a WRITE instruction, then store it in the ! 4164: // playback buffer. If the buffer is full, then play it back right ! 4165: // away, end sync reset and reinitialize the buffer with a sync ! 4166: // reset instruction. ! 4167: // ! 4168: // If we have a READ, we must flush the buffer (which has the side ! 4169: // effect of starting SyncReset), perform the read operation, stop ! 4170: // sync reset, and put back a sync reset instruction in the buffer ! 4171: // so we can go on appropriately ! 4172: // ! 4173: ! 4174: if (AccessMode & EMULATOR_WRITE_ACCESS) { ! 4175: ! 4176: // ! 4177: // Make sure Bit 3 of the Miscellaneous register is always 0. ! 4178: // If it is 1 it could select a non-existent clock, and kill the ! 4179: // system ! 4180: // ! 4181: ! 4182: if (Port == MISC_OUTPUT_REG_WRITE_PORT) { ! 4183: ! 4184: *Data &= 0xF7; ! 4185: ! 4186: } ! 4187: ! 4188: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4189: TrappedValidatorCount].Port = Port; ! 4190: ! 4191: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4192: TrappedValidatorCount].AccessType = VGA_VALIDATOR_UCHAR_ACCESS; ! 4193: ! 4194: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4195: TrappedValidatorCount].Data = *Data; ! 4196: ! 4197: hwDeviceExtension->TrappedValidatorCount++; ! 4198: ! 4199: // ! 4200: // Check to see if this instruction was ending sync reset. ! 4201: // If it did, we must flush the buffer and reset the trapped ! 4202: // IO ports to the minimal set. ! 4203: // ! 4204: ! 4205: if ( (Port == SEQ_DATA_PORT) && ! 4206: ((*Data & END_SYNC_RESET_VALUE) == END_SYNC_RESET_VALUE) && ! 4207: (hwDeviceExtension->SequencerAddressValue == IND_SYNC_RESET)) { ! 4208: ! 4209: endEmulation = 1; ! 4210: ! 4211: } else { ! 4212: ! 4213: // ! 4214: // If we are accessing the seq address port, keep track of the ! 4215: // data value ! 4216: // ! 4217: ! 4218: if (Port == SEQ_ADDRESS_PORT) { ! 4219: ! 4220: hwDeviceExtension->SequencerAddressValue = *Data; ! 4221: ! 4222: } ! 4223: ! 4224: // ! 4225: // If the buffer is not full, then just return right away. ! 4226: // ! 4227: ! 4228: if (hwDeviceExtension->TrappedValidatorCount < ! 4229: VGA_MAX_VALIDATOR_DATA - 1) { ! 4230: ! 4231: return NO_ERROR; ! 4232: ! 4233: } ! 4234: ! 4235: endEmulation = 0; ! 4236: } ! 4237: } ! 4238: ! 4239: // ! 4240: // We are either in a READ path or a WRITE path that caused a ! 4241: // a full buffer. So flush the buffer either way. ! 4242: // ! 4243: // To do this put an END_SYNC_RESET at the end since we want to make ! 4244: // the buffer is ended sync reset ended. ! 4245: // ! 4246: ! 4247: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4248: TrappedValidatorCount].Port = SEQ_ADDRESS_PORT; ! 4249: ! 4250: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4251: TrappedValidatorCount].AccessType = VGA_VALIDATOR_USHORT_ACCESS; ! 4252: ! 4253: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4254: TrappedValidatorCount].Data = (USHORT) (IND_SYNC_RESET + ! 4255: (END_SYNC_RESET_VALUE << 8)); ! 4256: ! 4257: hwDeviceExtension->TrappedValidatorCount++; ! 4258: ! 4259: VideoPortSynchronizeExecution(hwDeviceExtension, ! 4260: VpHighPriority, ! 4261: (PMINIPORT_SYNCHRONIZE_ROUTINE) ! 4262: VgaPlaybackValidatorData, ! 4263: hwDeviceExtension); ! 4264: ! 4265: // ! 4266: // Write back the real value of the sequencer address port. ! 4267: // ! 4268: ! 4269: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + ! 4270: SEQ_ADDRESS_PORT, ! 4271: (UCHAR) hwDeviceExtension->SequencerAddressValue); ! 4272: ! 4273: // ! 4274: // If we are in a READ path, read the data ! 4275: // ! 4276: ! 4277: if (AccessMode & EMULATOR_READ_ACCESS) { ! 4278: ! 4279: *Data = VideoPortReadPortUchar(hwDeviceExtension->IOAddress + Port); ! 4280: ! 4281: endEmulation = 0; ! 4282: ! 4283: } ! 4284: ! 4285: // ! 4286: // If we are ending emulation, reset trapping to the minimal amount ! 4287: // and exit. ! 4288: // ! 4289: ! 4290: if (endEmulation) { ! 4291: ! 4292: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 4293: NUM_MINIMAL_VGA_VALIDATOR_ACCESS_RANGE, ! 4294: MinimalVgaValidatorAccessRange); ! 4295: ! 4296: return NO_ERROR; ! 4297: ! 4298: } ! 4299: ! 4300: // ! 4301: // For both cases, put back a START_SYNC_RESET in the buffer. ! 4302: // ! 4303: ! 4304: hwDeviceExtension->TrappedValidatorCount = 1; ! 4305: ! 4306: hwDeviceExtension->TrappedValidatorData[0].Port = SEQ_ADDRESS_PORT; ! 4307: ! 4308: hwDeviceExtension->TrappedValidatorData[0].AccessType = ! 4309: VGA_VALIDATOR_USHORT_ACCESS; ! 4310: ! 4311: hwDeviceExtension->TrappedValidatorData[0].Data = ! 4312: (ULONG) (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)); ! 4313: ! 4314: } else { ! 4315: ! 4316: // ! 4317: // Nothing trapped. ! 4318: // Lets check is the IO is trying to do something that would require ! 4319: // us to stop trapping ! 4320: // ! 4321: ! 4322: if (AccessMode & EMULATOR_WRITE_ACCESS) { ! 4323: ! 4324: // ! 4325: // Make sure Bit 3 of the Miscelaneous register is always 0. ! 4326: // If it is 1 it could select a non-existant clock, and kill the ! 4327: // system ! 4328: // ! 4329: ! 4330: if (Port == MISC_OUTPUT_REG_WRITE_PORT) { ! 4331: ! 4332: temp = VideoPortReadPortUchar(hwDeviceExtension->IOAddress + ! 4333: SEQ_ADDRESS_PORT); ! 4334: ! 4335: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4336: SEQ_ADDRESS_PORT), ! 4337: (USHORT) (IND_SYNC_RESET + ! 4338: (START_SYNC_RESET_VALUE << 8))); ! 4339: ! 4340: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + Port, ! 4341: (UCHAR) (*Data & 0xF7) ); ! 4342: ! 4343: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4344: SEQ_ADDRESS_PORT), ! 4345: (USHORT) (IND_SYNC_RESET + ! 4346: (END_SYNC_RESET_VALUE << 8))); ! 4347: ! 4348: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + ! 4349: SEQ_ADDRESS_PORT, ! 4350: temp); ! 4351: ! 4352: return NO_ERROR; ! 4353: ! 4354: } ! 4355: ! 4356: // ! 4357: // If we get an access to the sequencer register, start trapping. ! 4358: // ! 4359: ! 4360: if ( (Port == SEQ_DATA_PORT) && ! 4361: ((*Data & END_SYNC_RESET_VALUE) != END_SYNC_RESET_VALUE) && ! 4362: (VideoPortReadPortUchar(hwDeviceExtension->IOAddress + ! 4363: SEQ_ADDRESS_PORT) == IND_SYNC_RESET)) { ! 4364: ! 4365: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 4366: NUM_FULL_VGA_VALIDATOR_ACCESS_RANGE, ! 4367: FullVgaValidatorAccessRange); ! 4368: ! 4369: hwDeviceExtension->TrappedValidatorCount = 1; ! 4370: hwDeviceExtension->TrappedValidatorData[0].Port = Port; ! 4371: hwDeviceExtension->TrappedValidatorData[0].AccessType = ! 4372: VGA_VALIDATOR_UCHAR_ACCESS; ! 4373: ! 4374: hwDeviceExtension->TrappedValidatorData[0].Data = *Data; ! 4375: ! 4376: // ! 4377: // Start keeping track of the state of the sequencer port. ! 4378: // ! 4379: ! 4380: hwDeviceExtension->SequencerAddressValue = IND_SYNC_RESET; ! 4381: ! 4382: } else { ! 4383: ! 4384: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + Port, ! 4385: *Data); ! 4386: ! 4387: } ! 4388: ! 4389: } else { ! 4390: ! 4391: *Data = VideoPortReadPortUchar(hwDeviceExtension->IOAddress + Port); ! 4392: ! 4393: } ! 4394: } ! 4395: ! 4396: return NO_ERROR; ! 4397: ! 4398: } // end VgaValidatorUcharEntry() ! 4399: ! 4400: //--------------------------------------------------------------------------- ! 4401: VP_STATUS ! 4402: VgaValidatorUshortEntry( ! 4403: ULONG Context, ! 4404: ULONG Port, ! 4405: UCHAR AccessMode, ! 4406: PUSHORT Data ! 4407: ) ! 4408: ! 4409: /*++ ! 4410: ! 4411: Routine Description: ! 4412: ! 4413: Entry point into the validator for word I/O operations. ! 4414: ! 4415: The entry point will be called whenever a byte operation was performed ! 4416: by a DOS application on one of the specified Video ports. The kernel ! 4417: emulator will forward these requests. ! 4418: ! 4419: Arguments: ! 4420: ! 4421: Context - Context value that is passed to each call made to the validator ! 4422: function. This is the value the miniport driver specified in the ! 4423: MiniportConfigInfo->EmulatorAccessEntriesContext. ! 4424: ! 4425: Port - Port on which the operation is to be performed. ! 4426: ! 4427: AccessMode - Determines if it is a read or write operation. ! 4428: ! 4429: Data - Pointer to a variable containing the data to be written or a ! 4430: variable into which the read data should be stored. ! 4431: ! 4432: Return Value: ! 4433: ! 4434: NO_ERROR. ! 4435: ! 4436: --*/ ! 4437: ! 4438: { ! 4439: ! 4440: PHW_DEVICE_EXTENSION hwDeviceExtension = (PHW_DEVICE_EXTENSION) Context; ! 4441: ULONG endEmulation; ! 4442: UCHAR temp; ! 4443: ! 4444: Port -= VGA_BASE_IO_PORT; ! 4445: ! 4446: if (hwDeviceExtension->TrappedValidatorCount) { ! 4447: ! 4448: // ! 4449: // If we are processing a WRITE instruction, then store it in the ! 4450: // playback buffer. If the buffer is full, then play it back right ! 4451: // away, end sync reset and reinitialize the buffer with a sync ! 4452: // reset instruction. ! 4453: // ! 4454: // If we have a READ, we must flush the buffer (which has the side ! 4455: // effect of starting SyncReset), perform the read operation, stop ! 4456: // sync reset, and put back a sync reset instruction in the buffer ! 4457: // so we can go on appropriately ! 4458: // ! 4459: ! 4460: if (AccessMode & EMULATOR_WRITE_ACCESS) { ! 4461: ! 4462: // ! 4463: // Make sure Bit 3 of the Miscellaneous register is always 0. ! 4464: // If it is 1 it could select a non-existent clock, and kill the ! 4465: // system ! 4466: // ! 4467: ! 4468: if (Port == MISC_OUTPUT_REG_WRITE_PORT) { ! 4469: ! 4470: *Data &= 0xFFF7; ! 4471: ! 4472: } ! 4473: ! 4474: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4475: TrappedValidatorCount].Port = Port; ! 4476: ! 4477: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4478: TrappedValidatorCount].AccessType = VGA_VALIDATOR_USHORT_ACCESS; ! 4479: ! 4480: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4481: TrappedValidatorCount].Data = *Data; ! 4482: ! 4483: hwDeviceExtension->TrappedValidatorCount++; ! 4484: ! 4485: // ! 4486: // Check to see if this instruction was ending sync reset. ! 4487: // If it did, we must flush the buffer and reset the trapped ! 4488: // IO ports to the minimal set. ! 4489: // ! 4490: ! 4491: if (Port == SEQ_ADDRESS_PORT) { ! 4492: ! 4493: // ! 4494: // If we are accessing the seq address port, keep track of its ! 4495: // value ! 4496: // ! 4497: ! 4498: hwDeviceExtension->SequencerAddressValue = (*Data & 0xFF); ! 4499: ! 4500: } ! 4501: ! 4502: if ((Port == SEQ_ADDRESS_PORT) && ! 4503: ( ((*Data >> 8) & END_SYNC_RESET_VALUE) == ! 4504: END_SYNC_RESET_VALUE) && ! 4505: (hwDeviceExtension->SequencerAddressValue == IND_SYNC_RESET)) { ! 4506: ! 4507: endEmulation = 1; ! 4508: ! 4509: } else { ! 4510: ! 4511: // ! 4512: // If the buffer is not full, then just return right away. ! 4513: // ! 4514: ! 4515: if (hwDeviceExtension->TrappedValidatorCount < ! 4516: VGA_MAX_VALIDATOR_DATA - 1) { ! 4517: ! 4518: return NO_ERROR; ! 4519: ! 4520: } ! 4521: ! 4522: endEmulation = 0; ! 4523: } ! 4524: } ! 4525: ! 4526: // ! 4527: // We are either in a READ path or a WRITE path that caused a ! 4528: // a full buffer. So flush the buffer either way. ! 4529: // ! 4530: // To do this put an END_SYNC_RESET at the end since we want to make ! 4531: // the buffer is ended sync reset ended. ! 4532: // ! 4533: ! 4534: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4535: TrappedValidatorCount].Port = SEQ_ADDRESS_PORT; ! 4536: ! 4537: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4538: TrappedValidatorCount].AccessType = VGA_VALIDATOR_USHORT_ACCESS; ! 4539: ! 4540: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4541: TrappedValidatorCount].Data = (USHORT) (IND_SYNC_RESET + ! 4542: (END_SYNC_RESET_VALUE << 8)); ! 4543: ! 4544: hwDeviceExtension->TrappedValidatorCount++; ! 4545: ! 4546: VideoPortSynchronizeExecution(hwDeviceExtension, ! 4547: VpHighPriority, ! 4548: (PMINIPORT_SYNCHRONIZE_ROUTINE) ! 4549: VgaPlaybackValidatorData, ! 4550: hwDeviceExtension); ! 4551: ! 4552: // ! 4553: // Write back the real value of the sequencer address port. ! 4554: // ! 4555: ! 4556: VideoPortWritePortUchar((PUCHAR) (hwDeviceExtension->IOAddress + ! 4557: SEQ_ADDRESS_PORT), ! 4558: (UCHAR) hwDeviceExtension->SequencerAddressValue); ! 4559: ! 4560: // ! 4561: // If we are in a READ path, read the data ! 4562: // ! 4563: ! 4564: if (AccessMode & EMULATOR_READ_ACCESS) { ! 4565: ! 4566: *Data = VideoPortReadPortUshort((PUSHORT)(hwDeviceExtension->IOAddress ! 4567: + Port)); ! 4568: ! 4569: endEmulation = 0; ! 4570: ! 4571: } ! 4572: ! 4573: // ! 4574: // If we are ending emulation, reset trapping to the minimal amount ! 4575: // and exit. ! 4576: // ! 4577: ! 4578: if (endEmulation) { ! 4579: ! 4580: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 4581: NUM_MINIMAL_VGA_VALIDATOR_ACCESS_RANGE, ! 4582: MinimalVgaValidatorAccessRange); ! 4583: ! 4584: return NO_ERROR; ! 4585: ! 4586: } ! 4587: ! 4588: // ! 4589: // For both cases, put back a START_SYNC_RESET in the buffer. ! 4590: // ! 4591: ! 4592: hwDeviceExtension->TrappedValidatorCount = 1; ! 4593: ! 4594: hwDeviceExtension->TrappedValidatorData[0].Port = SEQ_ADDRESS_PORT; ! 4595: ! 4596: hwDeviceExtension->TrappedValidatorData[0].AccessType = ! 4597: VGA_VALIDATOR_USHORT_ACCESS; ! 4598: ! 4599: hwDeviceExtension->TrappedValidatorData[0].Data = ! 4600: (ULONG) (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)); ! 4601: ! 4602: } else { ! 4603: ! 4604: // ! 4605: // Nothing trapped. ! 4606: // Lets check is the IO is trying to do something that would require ! 4607: // us to stop trapping ! 4608: // ! 4609: ! 4610: if (AccessMode & EMULATOR_WRITE_ACCESS) { ! 4611: ! 4612: // ! 4613: // Make sure Bit 3 of the Miscelaneous register is always 0. ! 4614: // If it is 1 it could select a non-existant clock, and kill the ! 4615: // system ! 4616: // ! 4617: ! 4618: if (Port == MISC_OUTPUT_REG_WRITE_PORT) { ! 4619: ! 4620: temp = VideoPortReadPortUchar(hwDeviceExtension->IOAddress + ! 4621: SEQ_ADDRESS_PORT); ! 4622: ! 4623: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4624: SEQ_ADDRESS_PORT), ! 4625: (USHORT) (IND_SYNC_RESET + ! 4626: (START_SYNC_RESET_VALUE << 8))); ! 4627: ! 4628: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4629: (ULONG)Port), ! 4630: (USHORT) (*Data & 0xFFF7) ); ! 4631: ! 4632: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4633: SEQ_ADDRESS_PORT), ! 4634: (USHORT) (IND_SYNC_RESET + ! 4635: (END_SYNC_RESET_VALUE << 8))); ! 4636: ! 4637: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, ! 4638: temp); ! 4639: ! 4640: return NO_ERROR; ! 4641: ! 4642: } ! 4643: ! 4644: if ( (Port == SEQ_ADDRESS_PORT) && ! 4645: (((*Data>> 8) & END_SYNC_RESET_VALUE) != END_SYNC_RESET_VALUE) && ! 4646: ((*Data & 0xFF) == IND_SYNC_RESET)) { ! 4647: ! 4648: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 4649: NUM_FULL_VGA_VALIDATOR_ACCESS_RANGE, ! 4650: FullVgaValidatorAccessRange); ! 4651: ! 4652: hwDeviceExtension->TrappedValidatorCount = 1; ! 4653: hwDeviceExtension->TrappedValidatorData[0].Port = Port; ! 4654: hwDeviceExtension->TrappedValidatorData[0].AccessType = ! 4655: VGA_VALIDATOR_USHORT_ACCESS; ! 4656: ! 4657: hwDeviceExtension->TrappedValidatorData[0].Data = *Data; ! 4658: ! 4659: // ! 4660: // Start keeping track of the state of the sequencer port. ! 4661: // ! 4662: ! 4663: hwDeviceExtension->SequencerAddressValue = IND_SYNC_RESET; ! 4664: ! 4665: } else { ! 4666: ! 4667: VideoPortWritePortUshort((PUSHORT)(hwDeviceExtension->IOAddress + ! 4668: Port), ! 4669: *Data); ! 4670: ! 4671: } ! 4672: ! 4673: } else { ! 4674: ! 4675: *Data = VideoPortReadPortUshort((PUSHORT)(hwDeviceExtension->IOAddress + ! 4676: Port)); ! 4677: ! 4678: } ! 4679: } ! 4680: ! 4681: return NO_ERROR; ! 4682: ! 4683: } // end VgaValidatorUshortEntry() ! 4684: ! 4685: //--------------------------------------------------------------------------- ! 4686: VP_STATUS ! 4687: VgaValidatorUlongEntry( ! 4688: ULONG Context, ! 4689: ULONG Port, ! 4690: UCHAR AccessMode, ! 4691: PULONG Data ! 4692: ) ! 4693: ! 4694: /*++ ! 4695: ! 4696: Routine Description: ! 4697: ! 4698: Entry point into the validator for dword I/O operations. ! 4699: ! 4700: The entry point will be called whenever a byte operation was performed ! 4701: by a DOS application on one of the specified Video ports. The kernel ! 4702: emulator will forward these requests. ! 4703: ! 4704: Arguments: ! 4705: ! 4706: Context - Context value that is passed to each call made to the validator ! 4707: function. This is the value the miniport driver specified in the ! 4708: MiniportConfigInfo->EmulatorAccessEntriesContext. ! 4709: ! 4710: Port - Port on which the operation is to be performed. ! 4711: ! 4712: AccessMode - Determines if it is a read or write operation. ! 4713: ! 4714: Data - Pointer to a variable containing the data to be written or a ! 4715: variable into which the read data should be stored. ! 4716: ! 4717: Return Value: ! 4718: ! 4719: NO_ERROR. ! 4720: ! 4721: --*/ ! 4722: ! 4723: { ! 4724: ! 4725: PHW_DEVICE_EXTENSION hwDeviceExtension = (PHW_DEVICE_EXTENSION) Context; ! 4726: ULONG endEmulation; ! 4727: UCHAR temp; ! 4728: ! 4729: Port -= VGA_BASE_IO_PORT; ! 4730: ! 4731: if (hwDeviceExtension->TrappedValidatorCount) { ! 4732: ! 4733: // ! 4734: // If we are processing a WRITE instruction, then store it in the ! 4735: // playback buffer. If the buffer is full, then play it back right ! 4736: // away, end sync reset and reinitialize the buffer with a sync ! 4737: // reset instruction. ! 4738: // ! 4739: // If we have a READ, we must flush the buffer (which has the side ! 4740: // effect of starting SyncReset), perform the read operation, stop ! 4741: // sync reset, and put back a sync reset instruction in the buffer ! 4742: // so we can go on appropriately ! 4743: // ! 4744: ! 4745: if (AccessMode & EMULATOR_WRITE_ACCESS) { ! 4746: ! 4747: // ! 4748: // Make sure Bit 3 of the Miscellaneous register is always 0. ! 4749: // If it is 1 it could select a non-existent clock, and kill the ! 4750: // system ! 4751: // ! 4752: ! 4753: if (Port == MISC_OUTPUT_REG_WRITE_PORT) { ! 4754: ! 4755: *Data &= 0xFFFFFFF7; ! 4756: ! 4757: } ! 4758: ! 4759: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4760: TrappedValidatorCount].Port = Port; ! 4761: ! 4762: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4763: TrappedValidatorCount].AccessType = VGA_VALIDATOR_ULONG_ACCESS; ! 4764: ! 4765: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4766: TrappedValidatorCount].Data = *Data; ! 4767: ! 4768: hwDeviceExtension->TrappedValidatorCount++; ! 4769: ! 4770: // ! 4771: // Check to see if this instruction was ending sync reset. ! 4772: // If it did, we must flush the buffer and reset the trapped ! 4773: // IO ports to the minimal set. ! 4774: // ! 4775: ! 4776: if (Port == SEQ_ADDRESS_PORT) { ! 4777: ! 4778: // ! 4779: // If we are accessing the seq address port, keep track of its ! 4780: // value ! 4781: // ! 4782: ! 4783: hwDeviceExtension->SequencerAddressValue = (*Data & 0xFF); ! 4784: ! 4785: } ! 4786: ! 4787: if ((Port == SEQ_ADDRESS_PORT) && ! 4788: ( ((*Data >> 8) & END_SYNC_RESET_VALUE) == ! 4789: END_SYNC_RESET_VALUE) && ! 4790: (hwDeviceExtension->SequencerAddressValue == IND_SYNC_RESET)) { ! 4791: ! 4792: endEmulation = 1; ! 4793: ! 4794: } else { ! 4795: ! 4796: // ! 4797: // If the buffer is not full, then just return right away. ! 4798: // ! 4799: ! 4800: if (hwDeviceExtension->TrappedValidatorCount < ! 4801: VGA_MAX_VALIDATOR_DATA - 1) { ! 4802: ! 4803: return NO_ERROR; ! 4804: ! 4805: } ! 4806: ! 4807: endEmulation = 0; ! 4808: } ! 4809: } ! 4810: ! 4811: // ! 4812: // We are either in a READ path or a WRITE path that caused a ! 4813: // a full buffer. So flush the buffer either way. ! 4814: // ! 4815: // To do this put an END_SYNC_RESET at the end since we want to make ! 4816: // the buffer is ended sync reset ended. ! 4817: // ! 4818: ! 4819: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4820: TrappedValidatorCount].Port = SEQ_ADDRESS_PORT; ! 4821: ! 4822: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4823: TrappedValidatorCount].AccessType = VGA_VALIDATOR_USHORT_ACCESS; ! 4824: ! 4825: hwDeviceExtension->TrappedValidatorData[hwDeviceExtension-> ! 4826: TrappedValidatorCount].Data = (USHORT) (IND_SYNC_RESET + ! 4827: (END_SYNC_RESET_VALUE << 8)); ! 4828: ! 4829: hwDeviceExtension->TrappedValidatorCount++; ! 4830: ! 4831: VideoPortSynchronizeExecution(hwDeviceExtension, ! 4832: VpHighPriority, ! 4833: (PMINIPORT_SYNCHRONIZE_ROUTINE) ! 4834: VgaPlaybackValidatorData, ! 4835: hwDeviceExtension); ! 4836: ! 4837: // ! 4838: // Write back the real value of the sequencer address port. ! 4839: // ! 4840: ! 4841: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + ! 4842: SEQ_ADDRESS_PORT, ! 4843: (UCHAR) hwDeviceExtension->SequencerAddressValue); ! 4844: ! 4845: // ! 4846: // If we are in a READ path, read the data ! 4847: // ! 4848: ! 4849: if (AccessMode & EMULATOR_READ_ACCESS) { ! 4850: ! 4851: *Data = VideoPortReadPortUlong((PULONG) (hwDeviceExtension->IOAddress + ! 4852: Port)); ! 4853: ! 4854: endEmulation = 0; ! 4855: ! 4856: } ! 4857: ! 4858: // ! 4859: // If we are ending emulation, reset trapping to the minimal amount ! 4860: // and exit. ! 4861: // ! 4862: ! 4863: if (endEmulation) { ! 4864: ! 4865: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 4866: NUM_MINIMAL_VGA_VALIDATOR_ACCESS_RANGE, ! 4867: MinimalVgaValidatorAccessRange); ! 4868: ! 4869: return NO_ERROR; ! 4870: ! 4871: } ! 4872: ! 4873: // ! 4874: // For both cases, put back a START_SYNC_RESET in the buffer. ! 4875: // ! 4876: ! 4877: hwDeviceExtension->TrappedValidatorCount = 1; ! 4878: ! 4879: hwDeviceExtension->TrappedValidatorData[0].Port = SEQ_ADDRESS_PORT; ! 4880: ! 4881: hwDeviceExtension->TrappedValidatorData[0].AccessType = ! 4882: VGA_VALIDATOR_USHORT_ACCESS; ! 4883: ! 4884: hwDeviceExtension->TrappedValidatorData[0].Data = ! 4885: (ULONG) (IND_SYNC_RESET + (START_SYNC_RESET_VALUE << 8)); ! 4886: ! 4887: } else { ! 4888: ! 4889: // ! 4890: // Nothing trapped. ! 4891: // Lets check is the IO is trying to do something that would require ! 4892: // us to stop trapping ! 4893: // ! 4894: ! 4895: if (AccessMode & EMULATOR_WRITE_ACCESS) { ! 4896: ! 4897: // ! 4898: // Make sure Bit 3 of the Miscelaneous register is always 0. ! 4899: // If it is 1 it could select a non-existant clock, and kill the ! 4900: // system ! 4901: // ! 4902: ! 4903: if (Port == MISC_OUTPUT_REG_WRITE_PORT) { ! 4904: ! 4905: temp = VideoPortReadPortUchar(hwDeviceExtension->IOAddress + ! 4906: SEQ_ADDRESS_PORT); ! 4907: ! 4908: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4909: SEQ_ADDRESS_PORT), ! 4910: (USHORT) (IND_SYNC_RESET + ! 4911: (START_SYNC_RESET_VALUE << 8))); ! 4912: ! 4913: VideoPortWritePortUlong((PULONG) (hwDeviceExtension->IOAddress + ! 4914: Port), ! 4915: (ULONG) (*Data & 0xFFFFFFF7) ); ! 4916: ! 4917: VideoPortWritePortUshort((PUSHORT) (hwDeviceExtension->IOAddress + ! 4918: SEQ_ADDRESS_PORT), ! 4919: (USHORT) (IND_SYNC_RESET + ! 4920: (END_SYNC_RESET_VALUE << 8))); ! 4921: ! 4922: VideoPortWritePortUchar(hwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, ! 4923: temp); ! 4924: ! 4925: return NO_ERROR; ! 4926: ! 4927: } ! 4928: ! 4929: if ( (Port == SEQ_ADDRESS_PORT) && ! 4930: (((*Data>> 8) & END_SYNC_RESET_VALUE) != END_SYNC_RESET_VALUE) && ! 4931: ((*Data & 0xFF) == IND_SYNC_RESET)) { ! 4932: ! 4933: VideoPortSetTrappedEmulatorPorts(hwDeviceExtension, ! 4934: NUM_FULL_VGA_VALIDATOR_ACCESS_RANGE, ! 4935: FullVgaValidatorAccessRange); ! 4936: ! 4937: hwDeviceExtension->TrappedValidatorCount = 1; ! 4938: hwDeviceExtension->TrappedValidatorData[0].Port = Port; ! 4939: hwDeviceExtension->TrappedValidatorData[0].AccessType = ! 4940: VGA_VALIDATOR_ULONG_ACCESS; ! 4941: ! 4942: hwDeviceExtension->TrappedValidatorData[0].Data = *Data; ! 4943: ! 4944: // ! 4945: // Start keeping track of the state of the sequencer port. ! 4946: // ! 4947: ! 4948: hwDeviceExtension->SequencerAddressValue = IND_SYNC_RESET; ! 4949: ! 4950: } else { ! 4951: ! 4952: VideoPortWritePortUlong((PULONG) (hwDeviceExtension->IOAddress + ! 4953: Port), ! 4954: *Data); ! 4955: ! 4956: } ! 4957: ! 4958: } else { ! 4959: ! 4960: *Data = VideoPortReadPortUlong((PULONG) (hwDeviceExtension->IOAddress + ! 4961: Port)); ! 4962: ! 4963: } ! 4964: } ! 4965: ! 4966: return NO_ERROR; ! 4967: ! 4968: } // end VgaValidatorUlongEntry() ! 4969: ! 4970: ! 4971: //--------------------------------------------------------------------------- ! 4972: BOOLEAN ! 4973: VgaPlaybackValidatorData( ! 4974: PVOID Context ! 4975: ) ! 4976: ! 4977: /*++ ! 4978: ! 4979: Routine Description: ! 4980: ! 4981: Performs all the DOS apps IO port accesses that were trapped by the ! 4982: validator. Only IO accesses that can be processed are WRITEs ! 4983: ! 4984: The number of outstanding IO access in deviceExtension is set to ! 4985: zero as a side effect. ! 4986: ! 4987: This function must be called via a call to VideoPortSynchronizeRoutine. ! 4988: ! 4989: Arguments: ! 4990: ! 4991: Context - Context parameter passed to the synchronized routine. ! 4992: Must be a pointer to the miniport driver's device extension. ! 4993: ! 4994: Return Value: ! 4995: ! 4996: TRUE. ! 4997: ! 4998: --*/ ! 4999: ! 5000: { ! 5001: PHW_DEVICE_EXTENSION hwDeviceExtension = Context; ! 5002: ULONG ioBaseAddress = (ULONG) hwDeviceExtension->IOAddress; ! 5003: UCHAR i; ! 5004: PVGA_VALIDATOR_DATA validatorData = hwDeviceExtension->TrappedValidatorData; ! 5005: ! 5006: // ! 5007: // Loop through the array of data and do instructions one by one. ! 5008: // ! 5009: ! 5010: for (i = 0; i < hwDeviceExtension->TrappedValidatorCount; ! 5011: i++, validatorData++) { ! 5012: ! 5013: // ! 5014: // Calculate base address first ! 5015: // ! 5016: ! 5017: ioBaseAddress = (ULONG)hwDeviceExtension->IOAddress + ! 5018: validatorData->Port; ! 5019: ! 5020: ! 5021: // ! 5022: // This is a write operation. We will automatically stop when the ! 5023: // buffer is empty. ! 5024: // ! 5025: ! 5026: switch (validatorData->AccessType) { ! 5027: ! 5028: case VGA_VALIDATOR_UCHAR_ACCESS : ! 5029: ! 5030: VideoPortWritePortUchar((PUCHAR)ioBaseAddress, ! 5031: (UCHAR) validatorData->Data); ! 5032: ! 5033: break; ! 5034: ! 5035: case VGA_VALIDATOR_USHORT_ACCESS : ! 5036: ! 5037: VideoPortWritePortUshort((PUSHORT)ioBaseAddress, ! 5038: (USHORT) validatorData->Data); ! 5039: ! 5040: break; ! 5041: ! 5042: case VGA_VALIDATOR_ULONG_ACCESS : ! 5043: ! 5044: VideoPortWritePortUlong((PULONG)ioBaseAddress, ! 5045: (ULONG) validatorData->Data); ! 5046: ! 5047: break; ! 5048: ! 5049: default: ! 5050: ! 5051: VideoDebugPrint((0, "InvalidValidatorAccessType\n" )); ! 5052: ! 5053: } ! 5054: } ! 5055: ! 5056: hwDeviceExtension->TrappedValidatorCount = 0; ! 5057: ! 5058: return TRUE; ! 5059: ! 5060: } // end VgaPlaybackValidatorData() ! 5061: ! 5062: ! 5063: //--------------------------------------------------------------------------- ! 5064: BOOLEAN ! 5065: CirrusLogicIsPresent( ! 5066: PHW_DEVICE_EXTENSION HwDeviceExtension ! 5067: ) ! 5068: ! 5069: /*++ ! 5070: ! 5071: Routine Description: ! 5072: ! 5073: This routine returns TRUE if an CL6410, 6420 or 542x is present. It ! 5074: assumes that it's already been established that a VGA is present. ! 5075: It performs the Cirrus Logic recommended ID test for each chip type: ! 5076: ! 5077: 6410: we try to enable the extension registers and read back a 1, then ! 5078: disable the extensions are read back a 0 in GR0A. ! 5079: ! 5080: 6420: same as above ! 5081: ! 5082: 542x: Enable extended registers by writing 0x12 to the extensions ! 5083: enable register, and reading back 0x12. Then read from the ! 5084: ID register and make sure it specifies a 5420, 5422, 5424, ! 5085: or 5426. Finally, disable the extensions and make sure the ! 5086: extensions enable register reads back 0x0F. ! 5087: ! 5088: If this function fails to find an Cirrus Logic VGA, it attempts to undo any ! 5089: damage it may have inadvertently done while testing. ! 5090: ! 5091: If a Cirrus Logic VGA is found, the adapter is returned to its original ! 5092: state after testing is finished, except that extensions are left enabled. ! 5093: ! 5094: Arguments: ! 5095: ! 5096: None. ! 5097: ! 5098: Return Value: ! 5099: ! 5100: TRUE if an CL6410/6420/542x is present, FALSE if not. ! 5101: ! 5102: --*/ ! 5103: ! 5104: { ! 5105: UCHAR originalGRIndex; ! 5106: UCHAR originalGR0A; ! 5107: UCHAR originalCRTCIndex; ! 5108: UCHAR originalSeqIndex; ! 5109: UCHAR originalExtsEnb; ! 5110: PUCHAR CRTCAddressPort, CRTCDataPort; ! 5111: UCHAR temp1, temp2, temp3; ! 5112: UCHAR revision; ! 5113: BOOLEAN retvalue = FALSE; // default return value ! 5114: ULONG i; ! 5115: ! 5116: // first, save the Graphics controller index ! 5117: originalGRIndex = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5118: GRAPH_ADDRESS_PORT); ! 5119: ! 5120: // Then save the value of GR0A ! 5121: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5122: GRAPH_ADDRESS_PORT, CL64xx_EXTENSION_ENABLE_INDEX); ! 5123: originalGR0A = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5124: GRAPH_DATA_PORT); ! 5125: ! 5126: // then, Unlock the CL6410 extended registers., GR0A = 0ECH ! 5127: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5128: GRAPH_DATA_PORT, CL64xx_EXTENSION_ENABLE_VALUE); ! 5129: ! 5130: // read back GR0A, it should be a 1 ! 5131: temp1 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5132: GRAPH_DATA_PORT); ! 5133: ! 5134: // then, Lock the CL6410 extended registers., GR0A = 0CEH ! 5135: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5136: GRAPH_DATA_PORT, CL64xx_EXTENSION_DISABLE_VALUE); ! 5137: ! 5138: // read back GR0A, it should be a 0 ! 5139: temp2 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5140: GRAPH_DATA_PORT); ! 5141: ! 5142: // restore the GR0A value ! 5143: // this will not have any effect if the chip IS a CL6410 or 6420 ! 5144: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5145: GRAPH_DATA_PORT, originalGR0A); ! 5146: ! 5147: // now restore the graphics index ! 5148: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5149: GRAPH_ADDRESS_PORT, originalGRIndex); ! 5150: ! 5151: // now test to see if the returned values were correct! ! 5152: // ! 5153: if ((temp1 == 1) && (temp2 == 0)) { ! 5154: // ! 5155: // By golly, it *is* a CL6410 or CL6420! ! 5156: // ! 5157: // but now we have to determine the chip type, and which display is ! 5158: // active. ! 5159: // reenable the extension registers first ! 5160: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5161: GRAPH_ADDRESS_PORT), CL64xx_EXTENSION_ENABLE_INDEX + ! 5162: (CL64xx_EXTENSION_ENABLE_VALUE << 8)); ! 5163: ! 5164: // now get the chip type at ERAA ! 5165: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5166: GRAPH_ADDRESS_PORT, 0xaa); ! 5167: ! 5168: revision = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5169: GRAPH_DATA_PORT); ! 5170: ! 5171: // now restore the graphics index ! 5172: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5173: GRAPH_ADDRESS_PORT, originalGRIndex); ! 5174: ! 5175: if ((revision & 0xf0) == 0x80) { // 6410 rev code ! 5176: VideoDebugPrint((1, "CL 6410 found\n")); ! 5177: // ! 5178: // we don't support 6340 in this driver, so force it not to be installed ! 5179: // ! 5180: if (!CirrusFind6340(HwDeviceExtension)) { ! 5181: HwDeviceExtension->ChipType = CL6410; ! 5182: HwDeviceExtension->AdapterMemorySize = 0x00040000; // 256K ! 5183: HwDeviceExtension->DisplayType = ! 5184: CirrusFind6410DisplayType(HwDeviceExtension); ! 5185: retvalue = TRUE; ! 5186: } ! 5187: } ! 5188: else if ((revision & 0xf0) == 0x70) { // 6420 rev code ! 5189: VideoDebugPrint((1, "CL 6420 found\n")); ! 5190: // ! 5191: // we don't support 6340 in this driver, so force it not to be installed ! 5192: // ! 5193: if (!CirrusFind6340(HwDeviceExtension)) { ! 5194: HwDeviceExtension->ChipType = CL6420; ! 5195: HwDeviceExtension->ChipRevision = (USHORT) revision; ! 5196: HwDeviceExtension->AdapterMemorySize = ! 5197: CirrusFindVmemSize(HwDeviceExtension); ! 5198: HwDeviceExtension->DisplayType = ! 5199: CirrusFind6410DisplayType(HwDeviceExtension); ! 5200: retvalue = TRUE; ! 5201: } ! 5202: } ! 5203: else { // we dont support 5410 at this time ! 5204: ! 5205: VideoDebugPrint((1, "Unsupported CL VGA chip found\n")); ! 5206: // retvalue = FALSE; // already FALSE ! 5207: } ! 5208: } ! 5209: if (!retvalue) // Did not detect a 64x0, see if it's a 542x ! 5210: { ! 5211: // ! 5212: // Determine where the CRTC registers are addressed (color or mono). ! 5213: // ! 5214: CRTCAddressPort = HwDeviceExtension->IOAddress; ! 5215: CRTCDataPort = HwDeviceExtension->IOAddress; ! 5216: ! 5217: if (VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5218: MISC_OUTPUT_REG_READ_PORT) & 0x01) { ! 5219: ! 5220: CRTCAddressPort += CRTC_ADDRESS_PORT_COLOR; ! 5221: CRTCDataPort += CRTC_DATA_PORT_COLOR; ! 5222: ! 5223: } else { ! 5224: ! 5225: CRTCAddressPort += CRTC_ADDRESS_PORT_MONO; ! 5226: CRTCDataPort += CRTC_DATA_PORT_MONO; ! 5227: } ! 5228: // ! 5229: // Save the original state of the CRTC and Sequencer Indices. ! 5230: // ! 5231: originalCRTCIndex = VideoPortReadPortUchar(CRTCAddressPort); ! 5232: originalSeqIndex = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5233: SEQ_ADDRESS_PORT); ! 5234: // ! 5235: // Try to enable all extensions: ! 5236: // a) Set the Sequencer Index to IND_CL_EXTS_ENB. ! 5237: // ! 5238: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, ! 5239: IND_CL_EXTS_ENB); ! 5240: // ! 5241: // b) Save the original state of Sequencer register IND_CL_EXTS_ENB. ! 5242: // ! 5243: originalExtsEnb = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5244: SEQ_ADDRESS_PORT); ! 5245: // ! 5246: // c) Write enabling value (0x12) to extension enable register ! 5247: // ! 5248: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5249: SEQ_ADDRESS_PORT),(USHORT)((0x12 << 8) + IND_CL_EXTS_ENB)); ! 5250: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, ! 5251: IND_CL_EXTS_ENB); ! 5252: temp1 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5253: SEQ_DATA_PORT); ! 5254: // ! 5255: // Read Chip ID Value from CRTC Register (Ignoring revision bits) ! 5256: // ! 5257: VideoPortWritePortUchar(CRTCAddressPort, IND_CL_ID_REG); ! 5258: temp3 = (VideoPortReadPortUchar(CRTCDataPort) & 0xFC); ! 5259: // ! 5260: // Write another value (!= 0x12) to IND_CL_EXTS_ENB to disable extensions ! 5261: // Should read back as 0x0F ! 5262: // ! 5263: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5264: SEQ_ADDRESS_PORT),(USHORT)((0 << 8) + IND_CL_EXTS_ENB)); ! 5265: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, ! 5266: IND_CL_EXTS_ENB); ! 5267: temp2 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5268: SEQ_DATA_PORT); ! 5269: // ! 5270: // Restore the original IND_CL_EXTS_ENB state. ! 5271: // ! 5272: ! 5273: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress ! 5274: + SEQ_ADDRESS_PORT), ! 5275: (USHORT)((originalExtsEnb << 8) + IND_CL_EXTS_ENB)); ! 5276: // ! 5277: // Restore the original Sequencer and CRTC Indices. ! 5278: // ! 5279: VideoPortWritePortUchar((HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT), ! 5280: originalSeqIndex); ! 5281: VideoPortWritePortUchar(CRTCAddressPort, originalCRTCIndex); ! 5282: // ! 5283: // Check values read from IND_CL_EXTS_ENB and IND_CL_ID_REG to be correct ! 5284: // ! 5285: if ((temp1 != (UCHAR) (0x12)) || ! 5286: (temp2 != (UCHAR) (0x0F)) || ! 5287: (temp3 > (UCHAR) (0x26 << 2)) || // 26 is 5428 ! 5288: (temp3 < (UCHAR) (0x22 << 2))) { // 22 is 5420 ! 5289: // ! 5290: // Did not find appropriate CL VGA Chip. ! 5291: // ! 5292: ! 5293: VideoDebugPrint((1, "CL VGA chip not found\n")); ! 5294: ! 5295: retvalue = FALSE; ! 5296: ! 5297: } ! 5298: else { ! 5299: // ! 5300: // It's a supported CL adapter. ! 5301: // ! 5302: VideoDebugPrint((1, "CL 542x found\n")); ! 5303: HwDeviceExtension->ChipType = CL542x; ! 5304: HwDeviceExtension->DisplayType = crt; ! 5305: HwDeviceExtension->AdapterMemorySize = ! 5306: CirrusFindVmemSize(HwDeviceExtension); ! 5307: ! 5308: retvalue = TRUE; ! 5309: } ! 5310: } ! 5311: ! 5312: // ! 5313: // Determines whic modes are valid. ! 5314: // ! 5315: ! 5316: if (retvalue) { ! 5317: ! 5318: CirrusValidateModes(HwDeviceExtension); ! 5319: ! 5320: } ! 5321: ! 5322: return retvalue; ! 5323: ! 5324: } // CirrusLogicIsPresent() ! 5325: ! 5326: //--------------------------------------------------------------------------- ! 5327: ULONG ! 5328: CirrusFindVmemSize( ! 5329: PHW_DEVICE_EXTENSION HwDeviceExtension ! 5330: ) ! 5331: ! 5332: /*++ ! 5333: ! 5334: Routine Description: ! 5335: ! 5336: This routine returns the amount of vram detected for the ! 5337: Cirrus Logic 6420 and 542x ONLY. It assumes that it is already known that ! 5338: a Cirrus Logic VGA is in the system. ! 5339: ! 5340: Arguments: ! 5341: ! 5342: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 5343: ! 5344: Return Value: ! 5345: ! 5346: Number of butes of VRAM. ! 5347: ! 5348: --*/ ! 5349: { ! 5350: ! 5351: UCHAR temp; ! 5352: ULONG memsize; ! 5353: UCHAR originalSeqIndex; ! 5354: UCHAR originalGraphicsIndex; ! 5355: UCHAR PostScratchPad; ! 5356: ! 5357: if (HwDeviceExtension->ChipType == CL6420) { ! 5358: ! 5359: originalGraphicsIndex = ! 5360: VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5361: GRAPH_ADDRESS_PORT)); ! 5362: ! 5363: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5364: GRAPH_ADDRESS_PORT, 0x9a); // Video memory config register ! 5365: ! 5366: temp = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5367: GRAPH_DATA_PORT); // get the data ! 5368: ! 5369: if ((temp & 0x07) == 0) { // 0 is accurate always ! 5370: ! 5371: memsize = 0x00040000; ! 5372: ! 5373: } else { ! 5374: ! 5375: // ! 5376: // We know now that the amount of vram is >256k. But we don't ! 5377: // know if it is 512k or 1meg. ! 5378: // They tell us to actually go out and see if memory is there by ! 5379: // writing into it and reading it back. ! 5380: // ! 5381: ! 5382: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5383: SEQ_ADDRESS_PORT),0x0f02); ! 5384: ! 5385: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5386: GRAPH_ADDRESS_PORT),0x0506); ! 5387: ! 5388: // ! 5389: // now pick a bank, and do the write ! 5390: // ! 5391: ! 5392: SetCirrusBanking(HwDeviceExtension,1); // start of 2nd 256k ! 5393: ! 5394: VideoPortWriteRegisterUchar(HwDeviceExtension->VideoMemoryAddress, ! 5395: 0x55); ! 5396: ! 5397: SetCirrusBanking(HwDeviceExtension,3); // 3*256k is 768k ! 5398: ! 5399: VideoPortWriteRegisterUchar(HwDeviceExtension->VideoMemoryAddress, ! 5400: 0xaa); ! 5401: ! 5402: SetCirrusBanking(HwDeviceExtension,1); // start of 2nd 256k ! 5403: ! 5404: if (VideoPortReadRegisterUchar(HwDeviceExtension->VideoMemoryAddress) ! 5405: == 0x55) { ! 5406: ! 5407: memsize = 0x00100000; // 1 MEG ! 5408: ! 5409: } else { ! 5410: ! 5411: memsize = 0x00080000; // 512K ! 5412: ! 5413: } ! 5414: ! 5415: SetCirrusBanking(HwDeviceExtension,0); // reset the memory value ! 5416: ! 5417: VgaInterpretCmdStream(HwDeviceExtension, DisableA000Color); ! 5418: ! 5419: VideoPortWritePortUchar((HwDeviceExtension->IOAddress ! 5420: + GRAPH_ADDRESS_PORT), ! 5421: originalGraphicsIndex); ! 5422: ! 5423: ! 5424: } ! 5425: ! 5426: VideoPortWritePortUchar((HwDeviceExtension->IOAddress + ! 5427: GRAPH_ADDRESS_PORT), originalGraphicsIndex); ! 5428: ! 5429: return memsize; ! 5430: ! 5431: } else { // its 542x ! 5432: ! 5433: originalSeqIndex = VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5434: SEQ_ADDRESS_PORT)); ! 5435: ! 5436: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5437: SEQ_ADDRESS_PORT), ! 5438: (USHORT)((0x12 << 8) + IND_CL_EXTS_ENB)); ! 5439: ! 5440: // ! 5441: // Read the POST scratch pad reg SR0A to determine amount of Video ! 5442: // memory ! 5443: // ! 5444: ! 5445: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT, ! 5446: IND_CL_SCRATCH_PAD); ! 5447: ! 5448: PostScratchPad = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5449: SEQ_DATA_PORT); ! 5450: ! 5451: VideoPortWritePortUchar((HwDeviceExtension->IOAddress + SEQ_ADDRESS_PORT), ! 5452: originalSeqIndex); ! 5453: ! 5454: // ! 5455: // Installed video memory is stored in scratch pad register by POST. ! 5456: // ! 5457: ! 5458: switch (PostScratchPad & 0x18) { // It's in bits 3 and 4 ! 5459: ! 5460: case 0x00: ! 5461: ! 5462: return 0x00040000; // 256K ! 5463: break; ! 5464: ! 5465: case 0x08: ! 5466: ! 5467: return 0x00080000; // 512K ! 5468: break; ! 5469: ! 5470: case 0x10: ! 5471: return 0x00100000; // 1 MEG ! 5472: break; ! 5473: ! 5474: case 0x18: ! 5475: return 0x00200000; // 2 MEG ! 5476: break; ! 5477: ! 5478: } ! 5479: ! 5480: } ! 5481: ! 5482: } // CirrusFindVmemSize() ! 5483: ! 5484: //--------------------------------------------------------------------------- ! 5485: VOID ! 5486: SetCirrusBanking( ! 5487: PHW_DEVICE_EXTENSION HwDeviceExtension, ! 5488: USHORT BankNumber ! 5489: ) ! 5490: /*++ ! 5491: ! 5492: Routine Description: ! 5493: ! 5494: Arguments: ! 5495: ! 5496: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 5497: ! 5498: BankNumber - the 256k bank number to set in 1RW mode(we will set this mode). ! 5499: ! 5500: Return Value: ! 5501: ! 5502: vmem256k, vmem512k, or vmem1Meg ONLY ( these are defined in cirrus.h). ! 5503: ! 5504: --*/ ! 5505: { ! 5506: ! 5507: if (HwDeviceExtension->ChipType == CL542x) { ! 5508: ! 5509: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 5510: GRAPH_ADDRESS_PORT), 0x1206); ! 5511: ! 5512: VideoPortWritePortUshort((PUSHORT) (HwDeviceExtension->IOAddress + ! 5513: GRAPH_ADDRESS_PORT), 0x010b); ! 5514: ! 5515: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5516: GRAPH_ADDRESS_PORT), ! 5517: (USHORT)(0x0009 + (BankNumber << (8+4))) ); ! 5518: ! 5519: } else { // 6410 or 6420 ! 5520: ! 5521: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5522: GRAPH_ADDRESS_PORT), 0xec0a); ! 5523: ! 5524: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5525: GRAPH_ADDRESS_PORT), 0x030d); ! 5526: ! 5527: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5528: GRAPH_ADDRESS_PORT), ! 5529: (USHORT)(0x000e + (BankNumber << (8+4))) ); ! 5530: ! 5531: } ! 5532: ! 5533: } // SetCirrusBanking() ! 5534: ! 5535: //--------------------------------------------------------------------------- ! 5536: USHORT ! 5537: CirrusFind6410DisplayType( ! 5538: PHW_DEVICE_EXTENSION HwDeviceExtension ! 5539: ) ! 5540: ! 5541: /*++ ! 5542: ! 5543: Routine Description: ! 5544: ! 5545: Determines the display type for CL6410 or CL6420 crt/panel controllers. ! 5546: Arguments: ! 5547: ! 5548: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 5549: ! 5550: Return Value: ! 5551: ! 5552: crt, panel, (no simulscan yet) as defined in cirrus.h ! 5553: ! 5554: --*/ ! 5555: { ! 5556: UCHAR originalGraphicsIndex; ! 5557: UCHAR temp1; ! 5558: ! 5559: // ! 5560: // now we need to check to see which display we are on... ! 5561: // ! 5562: ! 5563: originalGraphicsIndex = ! 5564: VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5565: GRAPH_ADDRESS_PORT)); ! 5566: ! 5567: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5568: GRAPH_ADDRESS_PORT, 0xd6); ! 5569: ! 5570: temp1 = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5571: GRAPH_DATA_PORT); ! 5572: ! 5573: VideoPortWritePortUchar((HwDeviceExtension->IOAddress ! 5574: + GRAPH_ADDRESS_PORT), originalGraphicsIndex); ! 5575: ! 5576: ! 5577: if (temp1 & 0x02) { // display is LCD Panel(or simulscan) ! 5578: ! 5579: return panel; ! 5580: ! 5581: } else { // the display is a crt ! 5582: ! 5583: return crt; ! 5584: ! 5585: } ! 5586: ! 5587: } // CirrusFind6410DisplayType() ! 5588: ! 5589: //--------------------------------------------------------------------------- ! 5590: BOOLEAN ! 5591: CirrusFind6340( ! 5592: PHW_DEVICE_EXTENSION HwDeviceExtension ! 5593: ) ! 5594: /*++ ! 5595: ! 5596: Routine Description: ! 5597: ! 5598: Determines if a CL6340 (Peacock) Color LCD controller is in the system ! 5599: along with a 6410 or 6420. ! 5600: ! 5601: Assumes that a 6410 or 6420 is already in the system. ! 5602: ! 5603: Arguments: ! 5604: ! 5605: HwDeviceExtension - Pointer to the miniport driver's device extension. ! 5606: ! 5607: Return Value: ! 5608: ! 5609: TRUE, 6340 detected ! 5610: FALSE, 6340 not detected ! 5611: ! 5612: --*/ ! 5613: { ! 5614: UCHAR originalGraphicsIndex; ! 5615: UCHAR originalSRIndex; ! 5616: UCHAR GRA1value; ! 5617: UCHAR temp1,temp2; ! 5618: ! 5619: originalGraphicsIndex = ! 5620: VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5621: GRAPH_ADDRESS_PORT)); ! 5622: ! 5623: originalSRIndex = ! 5624: VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5625: SEQ_ADDRESS_PORT)); ! 5626: ! 5627: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5628: GRAPH_ADDRESS_PORT, CL64xx_TRISTATE_CONTROL_REG); ! 5629: ! 5630: GRA1value = VideoPortReadPortUchar(HwDeviceExtension->IOAddress + ! 5631: GRAPH_DATA_PORT); ! 5632: ! 5633: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5634: GRAPH_DATA_PORT, (UCHAR) (0x80 | GRA1value)); ! 5635: ! 5636: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5637: SEQ_ADDRESS_PORT), (USHORT) CL6340_ENABLE_READBACK_REGISTER + ! 5638: (CL6340_ENABLE_READBACK_ALLSEL_VALUE << 8)); ! 5639: ! 5640: VideoPortWritePortUchar((HwDeviceExtension->IOAddress + ! 5641: SEQ_ADDRESS_PORT), CL6340_IDENTIFICATION_REGISTER); ! 5642: ! 5643: temp1 = VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5644: SEQ_DATA_PORT)); ! 5645: ! 5646: temp2 = VideoPortReadPortUchar((HwDeviceExtension->IOAddress + ! 5647: SEQ_DATA_PORT)); ! 5648: ! 5649: VideoPortWritePortUshort((PUSHORT)(HwDeviceExtension->IOAddress + ! 5650: SEQ_ADDRESS_PORT), (USHORT) CL6340_ENABLE_READBACK_REGISTER + ! 5651: (CL6340_ENABLE_READBACK_OFF_VALUE << 8)); ! 5652: ! 5653: // Graphics index still points to CL64xx_TRISTATE_CONTROL_REG ! 5654: VideoPortWritePortUchar(HwDeviceExtension->IOAddress + ! 5655: GRAPH_DATA_PORT, (UCHAR) (0x7f & GRA1value)); ! 5656: ! 5657: // now restore the Graphics and Sequencer indexes ! 5658: VideoPortWritePortUchar((HwDeviceExtension->IOAddress + ! 5659: GRAPH_ADDRESS_PORT),originalGraphicsIndex); ! 5660: ! 5661: VideoPortWritePortUchar((HwDeviceExtension->IOAddress + ! 5662: SEQ_ADDRESS_PORT),originalSRIndex); ! 5663: ! 5664: // check the values for value peacock data ! 5665: if ( ((temp1 & 0xf0) == 0x70 && (temp2 & 0xf0) == 0x80) || ! 5666: ((temp1 & 0xf0) == 0x80 && (temp2 & 0xf0) == 0x70) ) ! 5667: return TRUE; ! 5668: else ! 5669: return FALSE; ! 5670: ! 5671: } // CirrusFind6410DisplayType() ! 5672: //---------------------------------------------------------------------------
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.