Annotation of ntddk/src/video/miniport/cirrus/cirrus.c, revision 1.1.1.1

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: //---------------------------------------------------------------------------

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.