Annotation of ntddk/src/video/miniport/s3/s3.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990-1993  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     s3.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This module contains the code that implements the S3 miniport driver.
        !            12: 
        !            13: Environment:
        !            14: 
        !            15:     Kernel mode
        !            16: 
        !            17: Revision History:
        !            18: 
        !            19: --*/
        !            20: 
        !            21: #include "s3.h"
        !            22: #include "s3data.h"
        !            23: #include "s3logerr.h"
        !            24: 
        !            25: #include <string.h>
        !            26: 
        !            27: 
        !            28: #define MAX_CONTROL_HISTORY 512
        !            29: 
        !            30: ULONG giControlCode;
        !            31: ULONG gaIOControlCode[MAX_CONTROL_HISTORY];
        !            32: 
        !            33: #ifdef i386
        !            34: 
        !            35: /*************************************************************************************************
        !            36:  * 801/805, 928 mode mask bit table.
        !            37:  ************************************************************************************************/
        !            38: UCHAR   ModeMaskBits[] = {(UCHAR) ~0x00,    // 640 X 480   DEFAULT
        !            39:                           (UCHAR) ~0x03,    // 640 X 480 @ 43Hz
        !            40:                           (UCHAR) ~0x03,    // 640 X 480 @ 56Hz
        !            41:                           (UCHAR) ~0x03,    // 640 X 480 @ 60Hz
        !            42:                           (UCHAR) ~0x03,    // 640 X 480 @ 72Hz
        !            43: 
        !            44:                           (UCHAR) ~0x00,    // 800 X 600   DEFAULT
        !            45:                           (UCHAR) ~0x0C,    // 800 X 600 @ 43Hz
        !            46:                           (UCHAR) ~0x0C,    // 800 X 600 @ 56Hz
        !            47:                           (UCHAR) ~0x0C,    // 800 X 600 @ 60Hz
        !            48:                           (UCHAR) ~0x0C,    // 800 X 600 @ 72Hz
        !            49: 
        !            50:                           (UCHAR) ~0x00,    // 1024 X 768   DEFAULT
        !            51:                           (UCHAR) ~0x30,    // 1024 X 768 @ 43Hz
        !            52:                           (UCHAR) ~0x30,    // 1024 X 768 @ 56Hz
        !            53:                           (UCHAR) ~0x30,    // 1024 X 768 @ 60Hz
        !            54:                           (UCHAR) ~0x30,    // 1024 X 768 @ 72Hz
        !            55: 
        !            56:                           (UCHAR) ~0x00,    // 1280 X 1024   DEFAULT
        !            57:                           (UCHAR) ~0xC0,    // 1280 X 1024 @ 43Hz
        !            58:                           (UCHAR) ~0xC0,    // 1280 X 1024 @ 56Hz
        !            59:                           (UCHAR) ~0xC0,    // 1280 X 1024 @ 60Hz
        !            60:                           (UCHAR) ~0xC0     // 1280 X 1024 @ 72Hz
        !            61: };
        !            62: 
        !            63: /*************************************************************************************************
        !            64:  * 801/805, 928 mode set bits table
        !            65:  ************************************************************************************************/
        !            66: UCHAR   GenericModeBits[] = { (UCHAR) 0x00,    // 640 X 480   DEFAULT
        !            67:                           (UCHAR) 0x00,    // 640 X 480 @ 43Hz
        !            68:                           (UCHAR) 0x01,    // 640 X 480 @ 56Hz
        !            69:                           (UCHAR) 0x02,    // 640 X 480 @ 60Hz
        !            70:                           (UCHAR) 0x03,    // 640 X 480 @ 72Hz
        !            71: 
        !            72:                           (UCHAR) 0x00,    // 800 X 600   DEFAULT
        !            73:                           (UCHAR) 0x00,    // 800 X 600 @ 43Hz
        !            74:                           (UCHAR) 0x04,    // 800 X 600 @ 56Hz
        !            75:                           (UCHAR) 0x08,    // 800 X 600 @ 60Hz
        !            76:                           (UCHAR) 0x0C,    // 800 X 600 @ 72Hz
        !            77: 
        !            78:                           (UCHAR) 0x00,    // 1024 X 768   DEFAULT
        !            79:                           (UCHAR) 0x00,    // 1024 X 768 @ 43Hz
        !            80:                           (UCHAR) 0x10,    // 1024 X 768 @ 56Hz
        !            81:                           (UCHAR) 0x20,    // 1024 X 768 @ 60Hz
        !            82:                           (UCHAR) 0x30,    // 1024 X 768 @ 72Hz
        !            83: 
        !            84:                           (UCHAR) 0x00,    // 1280 X 1024   DEFAULT
        !            85:                           (UCHAR) 0x00,    // 1280 X 1024 @ 43Hz
        !            86:                           (UCHAR) 0x40,    // 1280 X 1024 @ 56Hz
        !            87:                           (UCHAR) 0x80,    // 1280 X 1024 @ 60Hz
        !            88:                           (UCHAR) 0xC0     // 1280 X 1024 @ 72Hz
        !            89: };
        !            90: 
        !            91: /*************************************************************************************************
        !            92:  * Number Nine Computer 928 mode set bits table
        !            93:  *  BIOS versions before 1.10.04 have the following refresh index to
        !            94:  *  vertical refresh rate association:
        !            95:  *
        !            96:  *      0   default (56/60 depending upon mode)
        !            97:  *      1   70 Hz
        !            98:  *      2   72 Hz
        !            99:  *      3   76 Hz
        !           100:  *
        !           101:  *  This miniport will always map down (better safe than sorry)
        !           102:  *  The mapping is:
        !           103:  *
        !           104:  *  index   registry value     #9 value
        !           105:  *    0         43          56/60 (default)
        !           106:  *    1         56              "
        !           107:  *    2         60              "
        !           108:  *    3         72              72
        !           109:  ************************************************************************************************/
        !           110: UCHAR   NumberNineModeBits[] = { (UCHAR) 0x00,    // 640 X 480   DEFAULT
        !           111:                           (UCHAR) 0x00,    // 640 X 480 @ 43Hz
        !           112:                           (UCHAR) 0x00,    // 640 X 480 @ 56Hz
        !           113:                           (UCHAR) 0x00,    // 640 X 480 @ 60Hz
        !           114:                           (UCHAR) 0x02,    // 640 X 480 @ 72Hz
        !           115: 
        !           116:                           (UCHAR) 0x00,    // 800 X 600   DEFAULT
        !           117:                           (UCHAR) 0x00,    // 800 X 600 @ 43Hz
        !           118:                           (UCHAR) 0x00,    // 800 X 600 @ 56Hz
        !           119:                           (UCHAR) 0x00,    // 800 X 600 @ 60Hz
        !           120:                           (UCHAR) 0x08,    // 800 X 600 @ 72Hz
        !           121: 
        !           122:                           (UCHAR) 0x00,    // 1024 X 768   DEFAULT
        !           123:                           (UCHAR) 0x00,    // 1024 X 768 @ 43Hz
        !           124:                           (UCHAR) 0x00,    // 1024 X 768 @ 56Hz
        !           125:                           (UCHAR) 0x00,    // 1024 X 768 @ 60Hz
        !           126:                           (UCHAR) 0x20,    // 1024 X 768 @ 72Hz
        !           127: 
        !           128:                           (UCHAR) 0x00,    // 1280 X 1024   DEFAULT
        !           129:                           (UCHAR) 0x00,    // 1280 X 1024 @ 43Hz
        !           130:                           (UCHAR) 0x00,    // 1280 X 1024 @ 56Hz
        !           131:                           (UCHAR) 0x00,    // 1280 X 1024 @ 60Hz
        !           132:                           (UCHAR) 0x80     // 1280 X 1024 @ 72Hz
        !           133: };
        !           134: 
        !           135: /*************************************************************************************************
        !           136:  * DELL 805 mode set bits table
        !           137:  *
        !           138:  *  Dell has a different mapping for each resolution.
        !           139:  *
        !           140:  *  index   registry    640     800     1024    1280
        !           141:  *    0         43       60      56      43      43
        !           142:  *    1         56       72      60      60      --
        !           143:  *    2         60       --      72      70      --
        !           144:  *    3         72       56      56      72      --
        !           145:  ************************************************************************************************/
        !           146: UCHAR   DellModeBits[] = {(UCHAR) 0x00,    // 640 X 480   DEFAULT
        !           147:                           (UCHAR) 0x00,    // 640 X 480 @ 43Hz
        !           148:                           (UCHAR) 0x03,    // 640 X 480 @ 56Hz
        !           149:                           (UCHAR) 0x00,    // 640 X 480 @ 60Hz
        !           150:                           (UCHAR) 0x01,    // 640 X 480 @ 72Hz
        !           151: 
        !           152:                           (UCHAR) 0x00,    // 800 X 600   DEFAULT
        !           153:                           (UCHAR) 0x00,    // 800 X 600 @ 43Hz
        !           154:                           (UCHAR) 0x00,    // 800 X 600 @ 56Hz
        !           155:                           (UCHAR) 0x04,    // 800 X 600 @ 60Hz
        !           156:                           (UCHAR) 0x08,    // 800 X 600 @ 72Hz
        !           157: 
        !           158:                           (UCHAR) 0x00,    // 1024 X 768   DEFAULT
        !           159:                           (UCHAR) 0x00,    // 1024 X 768 @ 43Hz
        !           160:                           (UCHAR) 0x10,    // 1024 X 768 @ 56Hz
        !           161:                           (UCHAR) 0x10,    // 1024 X 768 @ 60Hz
        !           162:                           (UCHAR) 0x30,    // 1024 X 768 @ 72Hz
        !           163: 
        !           164:                           (UCHAR) 0x00,    // 1280 X 1024   DEFAULT
        !           165:                           (UCHAR) 0x00,    // 1280 X 1024 @ 43Hz
        !           166:                           (UCHAR) 0x00,    // 1280 X 1024 @ 56Hz
        !           167:                           (UCHAR) 0x00,    // 1280 X 1024 @ 60Hz
        !           168:                           (UCHAR) 0x00     // 1280 X 1024 @ 72Hz
        !           169: };
        !           170: 
        !           171: 
        !           172: // This table is only used for the 801/805 and 928 chips.
        !           173: // When this table was used on the Stealth or Orchid 911 boards the
        !           174: // full screen had two images side by side.
        !           175: 
        !           176: typedef struct {
        !           177:     UCHAR   port,
        !           178:             val;
        !           179: } REGVALS;
        !           180: 
        !           181: REGVALS   arvExtendedRegs[] = {{0x30, 0x0},
        !           182:                                {0x31, 0x0},
        !           183:                                {0x32, 0x0},
        !           184:                                {0x33, 0x0},
        !           185:                                {0x34, 0x0},
        !           186:                                {0x35, 0x0},
        !           187:                                {0x36, 0x0},
        !           188:                                {0x37, 0x0},
        !           189:                                {0x3A, 0x0},
        !           190:                                {0x3B, 0x0},
        !           191:                                {0x3C, 0x0},
        !           192: 
        !           193:                                {0x40, 0x0},
        !           194:                                {0x41, 0x0},
        !           195:                                {0x42, 0x0},
        !           196:                                {0x43, 0x0},
        !           197:                                {0x44, 0x0},
        !           198:                                {0x45, 0x0},
        !           199:                                {0x46, 0x0},
        !           200:                                {0x47, 0x0},
        !           201:                                {0x48, 0x0},
        !           202:                                {0x49, 0x0},
        !           203:                                {0x4A, 0x0},
        !           204:                                {0x4B, 0x0},
        !           205:                                {0x4C, 0x0},
        !           206:                                {0x4D, 0x0},
        !           207:                                {0x4E, 0x0},
        !           208:                                {0x4F, 0x0},
        !           209: 
        !           210:                                {0x50, 0x0},
        !           211:                                {0x51, 0x0},
        !           212:                                {0x52, 0x0},
        !           213:                                {0x53, 0x0},
        !           214:                                {0x54, 0x0},
        !           215:                                {0x55, 0x0},
        !           216:                                {0x56, 0x0},
        !           217:                                {0x57, 0x0},
        !           218:                                {0x58, 0x0},
        !           219:                                {0x59, 0x0},
        !           220:                                {0x5A, 0x0},
        !           221:                                {0x5B, 0x0},
        !           222:                                {0x5C, 0x0},
        !           223:                                {0x5D, 0x0},
        !           224:                                {0x5E, 0x0},
        !           225:                                {0x5F, 0x0}};
        !           226: 
        !           227: ULONG nExtendedRegs = sizeof(arvExtendedRegs) / sizeof (REGVALS);
        !           228: 
        !           229: #endif
        !           230: 
        !           231: 
        !           232: 
        !           233: #ifndef i386
        !           234: 
        !           235: long calc_clock(long, int);
        !           236: VOID set_clock(
        !           237:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !           238:     LONG clock_value);
        !           239: 
        !           240: #endif
        !           241: 
        !           242: 
        !           243: //
        !           244: // Function Prototypes
        !           245: //
        !           246: // Functions that start with 'S3' are entry points for the OS port driver.
        !           247: //
        !           248: 
        !           249: VP_STATUS
        !           250: S3FindAdapter(
        !           251:     PVOID HwDeviceExtension,
        !           252:     PVOID HwContext,
        !           253:     PWSTR ArgumentString,
        !           254:     PVIDEO_PORT_CONFIG_INFO ConfigInfo,
        !           255:     PUCHAR Again
        !           256:     );
        !           257: 
        !           258: BOOLEAN
        !           259: S3Initialize(
        !           260:     PVOID HwDeviceExtension
        !           261:     );
        !           262: 
        !           263: BOOLEAN
        !           264: S3StartIO(
        !           265:     PVOID HwDeviceExtension,
        !           266:     PVIDEO_REQUEST_PACKET RequestPacket
        !           267:     );
        !           268: 
        !           269: VP_STATUS
        !           270: S3SetColorLookup(
        !           271:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !           272:     PVIDEO_CLUT ClutBuffer,
        !           273:     ULONG ClutBufferSize
        !           274:     );
        !           275: 
        !           276: VOID
        !           277: ZeroMemAndDac(
        !           278:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !           279:     );
        !           280: 
        !           281: VOID
        !           282: SetHWMode(
        !           283:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !           284:     PUSHORT pusCmdStream
        !           285:     );
        !           286: 
        !           287: VP_STATUS
        !           288: S3RegistryCallback(
        !           289:     PVOID HwDeviceExtension,
        !           290:     PVOID Context,
        !           291:     PWSTR ValueName,
        !           292:     PVOID ValueData,
        !           293:     ULONG ValueLength
        !           294:     );
        !           295: 
        !           296: BOOLEAN
        !           297: Reset_Bt485(
        !           298:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !           299:     );
        !           300: 
        !           301: //
        !           302: // Non-x86 platform support
        !           303: //
        !           304: 
        !           305: #ifndef i386
        !           306: 
        !           307: VP_STATUS
        !           308: Set_Oem_Clock(
        !           309:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !           310:     );
        !           311: 
        !           312: VP_STATUS
        !           313: Wait_VSync(
        !           314:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !           315:     );
        !           316: 
        !           317: BOOLEAN
        !           318: Bus_Test(
        !           319:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !           320:     );
        !           321: 
        !           322: #endif // i386
        !           323: 
        !           324: 
        !           325: ULONG
        !           326: DriverEntry (
        !           327:     PVOID Context1,
        !           328:     PVOID Context2
        !           329:     )
        !           330: 
        !           331: /*++
        !           332: 
        !           333: Routine Description:
        !           334: 
        !           335:     Installable driver initialization entry point.
        !           336:     This entry point is called directly by the I/O system.
        !           337: 
        !           338: Arguments:
        !           339: 
        !           340:     Context1 - First context value passed by the operating system. This is
        !           341:         the value with which the miniport driver calls VideoPortInitialize().
        !           342: 
        !           343:     Context2 - Second context value passed by the operating system. This is
        !           344:         the value with which the miniport driver calls VideoPortInitialize().
        !           345: 
        !           346: Return Value:
        !           347: 
        !           348:     Status from VideoPortInitialize()
        !           349: 
        !           350: --*/
        !           351: 
        !           352: {
        !           353: 
        !           354:     VIDEO_HW_INITIALIZATION_DATA hwInitData;
        !           355:     ULONG initializationStatus;
        !           356:     ULONG status;
        !           357: 
        !           358:     //
        !           359:     // Zero out structure.
        !           360:     //
        !           361: 
        !           362:     VideoPortZeroMemory(&hwInitData, sizeof(VIDEO_HW_INITIALIZATION_DATA));
        !           363: 
        !           364:     //
        !           365:     // Specify sizes of structure and extension.
        !           366:     //
        !           367: 
        !           368:     hwInitData.HwInitDataSize = sizeof(VIDEO_HW_INITIALIZATION_DATA);
        !           369: 
        !           370:     //
        !           371:     // Set entry points.
        !           372:     //
        !           373: 
        !           374:     hwInitData.HwFindAdapter = S3FindAdapter;
        !           375:     hwInitData.HwInitialize = S3Initialize;
        !           376:     hwInitData.HwInterrupt = NULL;
        !           377:     hwInitData.HwStartIO = S3StartIO;
        !           378: 
        !           379:     //
        !           380:     // Determine the size we require for the device extension.
        !           381:     //
        !           382: 
        !           383:     hwInitData.HwDeviceExtensionSize = sizeof(HW_DEVICE_EXTENSION);
        !           384: 
        !           385:     //
        !           386:     // Always start with parameters for device0 in this case.
        !           387:     //
        !           388: 
        !           389: //    hwInitData.StartingDeviceNumber = 0;
        !           390: 
        !           391:     //
        !           392:     // This device only supports many bus types.
        !           393:     //
        !           394: 
        !           395:     hwInitData.AdapterInterfaceType = Isa;
        !           396: 
        !           397:     initializationStatus = VideoPortInitialize(Context1,
        !           398:                                                Context2,
        !           399:                                                &hwInitData,
        !           400:                                                NULL);
        !           401: 
        !           402:     hwInitData.AdapterInterfaceType = Eisa;
        !           403: 
        !           404:     status = VideoPortInitialize(Context1,
        !           405:                                      Context2,
        !           406:                                      &hwInitData,
        !           407:                                      NULL);
        !           408: 
        !           409:     if (initializationStatus > status) {
        !           410:         initializationStatus = status;
        !           411:     }
        !           412: 
        !           413:     hwInitData.AdapterInterfaceType = Internal;
        !           414: 
        !           415:     status = VideoPortInitialize(Context1,
        !           416:                                  Context2,
        !           417:                                  &hwInitData,
        !           418:                                  NULL);
        !           419: 
        !           420:     if (initializationStatus > status) {
        !           421:         initializationStatus = status;
        !           422:     }
        !           423: 
        !           424:     return initializationStatus;
        !           425: 
        !           426: } // end DriverEntry()
        !           427: 
        !           428: 
        !           429: VP_STATUS
        !           430: S3FindAdapter(
        !           431:     PVOID HwDeviceExtension,
        !           432:     PVOID HwContext,
        !           433:     PWSTR ArgumentString,
        !           434:     PVIDEO_PORT_CONFIG_INFO ConfigInfo,
        !           435:     PUCHAR Again
        !           436:     )
        !           437: 
        !           438: /*++
        !           439: 
        !           440: Routine Description:
        !           441: 
        !           442:     This routine is called to determine if the adapter for this driver
        !           443:     is present in the system.
        !           444:     If it is present, the function fills out some information describing
        !           445:     the adapter.
        !           446: 
        !           447: Arguments:
        !           448: 
        !           449:     HwDeviceExtension - Supplies the miniport driver's adapter storage. This
        !           450:         storage is initialized to zero before this call.
        !           451: 
        !           452:     HwContext - Supplies the context value which was passed to
        !           453:         VideoPortInitialize().
        !           454: 
        !           455:     ArgumentString - Suuplies a NULL terminated ASCII string. This string
        !           456:         originates from the user.
        !           457: 
        !           458:     ConfigInfo - Returns the configuration information structure which is
        !           459:         filled by the miniport driver. This structure is initialized with
        !           460:         any knwon configuration information (such as SystemIoBusNumber) by
        !           461:         the port driver. Where possible, drivers should have one set of
        !           462:         defaults which do not require any supplied configuration information.
        !           463: 
        !           464:     Again - Indicates if the miniport driver wants the port driver to call
        !           465:         its VIDEO_HW_FIND_ADAPTER function again with a new device extension
        !           466:         and the same config info. This is used by the miniport drivers which
        !           467:         can search for several adapters on a bus.
        !           468: 
        !           469: Return Value:
        !           470: 
        !           471:     This routine must return:
        !           472: 
        !           473:     NO_ERROR - Indicates a host adapter was found and the
        !           474:         configuration information was successfully determined.
        !           475: 
        !           476:     ERROR_INVALID_PARAMETER - Indicates an adapter was found but there was an
        !           477:         error obtaining the configuration information. If possible an error
        !           478:         should be logged.
        !           479: 
        !           480:     ERROR_DEV_NOT_EXIST - Indicates no host adapter was found for the
        !           481:         supplied configuration information.
        !           482: 
        !           483: --*/
        !           484: 
        !           485: {
        !           486: 
        !           487:     //
        !           488:     // Size of the ROM we map in
        !           489:     //
        !           490: 
        !           491:     #define MAX_ROM_SCAN    512
        !           492: 
        !           493:     PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
        !           494:     ULONG i;
        !           495:     VP_STATUS status;
        !           496:     UCHAR jChipID, s3MemSizeCode;
        !           497:     UCHAR DataReg, IndexReg, reg38, reg39;
        !           498:     UCHAR reg40, reg43;
        !           499:     BOOLEAN useAlternateRegisters = FALSE;
        !           500: 
        !           501:     USHORT usRomSignature;
        !           502:     PVOID romAddress;
        !           503:     BOOLEAN bMatch;
        !           504:     UCHAR   *pjBiosVersion, *pjRefString, offset;
        !           505:     LONG    iCmpRet;
        !           506: 
        !           507:     VIDEO_ACCESS_RANGE accessRange[] = {
        !           508:         {0x000C0000, 0x00000000, 0x00008000, 0, 0, 0}, // 0 ROM location
        !           509:         {0x000A0000, 0x00000000, 0x00010000, 0, 0, 1}, // 1 Frame buf
        !           510:         {0x000003C0, 0x00000000, 0x00000010, 1, 1, 1}, // 2 Various VGA regs
        !           511:         {0x000003D4, 0x00000000, 0x00000008, 1, 1, 1}, // 3 System Control Registers
        !           512:         {0x000042E8, 0x00000000, 0x00000002, 1, 1, 0}, // 4 SubSys-Stat/Cntl
        !           513:         {0x00004AE8, 0x00000000, 0x00000002, 1, 1, 0}, // 5 AdvFunc-Cntl
        !           514:         {0x000082E8, 0x00000000, 0x00000002, 1, 1, 0}, // 6 Cur-Y
        !           515:         {0x000086E8, 0x00000000, 0x00000002, 1, 1, 0}, // 7 Cur-X
        !           516:         {0x00008AE8, 0x00000000, 0x00000002, 1, 1, 0}, // 8 DestY-AxStp
        !           517:         {0x00008EE8, 0x00000000, 0x00000002, 1, 1, 0}, // 9 DestX-SiaStp
        !           518:         {0x000092E8, 0x00000000, 0x00000002, 1, 1, 0}, // 10 Err-Term
        !           519:         {0x000096E8, 0x00000000, 0x00000002, 1, 1, 0}, // 11 Maj-Axis-Pcnt(Rec-Width)
        !           520:         {0x00009AE8, 0x00000000, 0x00000002, 1, 1, 0}, // 12 Gp-Stat/Cmd
        !           521:         {0x00009EE8, 0x00000000, 0x00000002, 1, 1, 0}, // 13 Short-Stroke
        !           522:         {0x0000A2E8, 0x00000000, 0x00000002, 1, 1, 0}, // 14 Bkgd-Color
        !           523:         {0x0000A6E8, 0x00000000, 0x00000002, 1, 1, 0}, // 15 Frgd-Color
        !           524:         {0x0000AAE8, 0x00000000, 0x00000002, 1, 1, 0}, // 16 Wrt_Mask
        !           525:         {0x0000AEE8, 0x00000000, 0x00000002, 1, 1, 0}, // 17 Rd-Mask
        !           526:         {0x0000B6E8, 0x00000000, 0x00000002, 1, 1, 0}, // 18 Bkgd-Mix
        !           527:         {0x0000BAE8, 0x00000000, 0x00000002, 1, 1, 0}, // 19 Frgd-Mix
        !           528:         {0x0000BEE8, 0x00000000, 0x00000002, 1, 1, 0}, // 20 Mulitfucn_Cntl
        !           529:         {0x0000E2E8, 0x00000000, 0x00000002, 1, 1, 0}  // 21 Pix-Trans
        !           530:     };
        !           531: 
        !           532:     //
        !           533:     // Make sure the size of the structure is at least as large as what we
        !           534:     // are expecting (check version of the config info structure).
        !           535:     //
        !           536: 
        !           537:     if (ConfigInfo->Length < sizeof(VIDEO_PORT_CONFIG_INFO)) {
        !           538: 
        !           539:         return (ERROR_INVALID_PARAMETER);
        !           540: 
        !           541:     }
        !           542: 
        !           543: 
        !           544: #ifdef MIPS
        !           545: 
        !           546:     //
        !           547:     // For MIPS machine with an Internal Bus, adjust the access ranges.
        !           548:     //
        !           549: 
        !           550:     if (ConfigInfo->AdapterInterfaceType == Internal) {
        !           551: 
        !           552:         #define INTERNAL_BUS_VIDEO_MEMORY_BASE 0x40000000
        !           553:         #define INTERNAL_BUS_IO_PORT_BASE      0x60000000
        !           554: 
        !           555:         VideoDebugPrint((1, "S3: Internal Bus, get new IO bases\n"));
        !           556: 
        !           557:         //
        !           558:         // Adjust memory location
        !           559:         //
        !           560: 
        !           561:         accessRange[0].RangeStart.LowPart += INTERNAL_BUS_VIDEO_MEMORY_BASE;
        !           562:         accessRange[1].RangeStart.LowPart += INTERNAL_BUS_VIDEO_MEMORY_BASE;
        !           563: 
        !           564:         //
        !           565:         // Adjust io port locations, and change IO port from IO port to memory.
        !           566:         //
        !           567: 
        !           568:         for (i = 2; i < NUM_S3_ACCESS_RANGES; i++) {
        !           569: 
        !           570:             accessRange[i].RangeStart.LowPart += INTERNAL_BUS_IO_PORT_BASE;
        !           571:             accessRange[i].RangeInIoSpace = 0;
        !           572: 
        !           573:         }
        !           574:     }
        !           575: 
        !           576: #endif
        !           577: 
        !           578: 
        !           579:     //
        !           580:     // Check to see if there is a hardware resource conflict.
        !           581:     //
        !           582: 
        !           583:     status = VideoPortVerifyAccessRanges(hwDeviceExtension,
        !           584:                                          NUM_S3_ACCESS_RANGES,
        !           585:                                          accessRange);
        !           586: 
        !           587:     if (status != NO_ERROR) {
        !           588: 
        !           589:         VideoDebugPrint((1, "S3: Access Range conflict\n"));
        !           590:         return status;
        !           591: 
        !           592:     }
        !           593: 
        !           594:     //
        !           595:     // Get the mapped addresses for all the registers.
        !           596:     //
        !           597:     // NOTE: the ROM is not mapped here. It will only be mapped later, if
        !           598:     // we really need it (non int10 initialization).
        !           599:     //
        !           600: 
        !           601:     for (i = 1; i < NUM_S3_ACCESS_RANGES; i++) {
        !           602: 
        !           603:         if ( (hwDeviceExtension->MappedAddress[i] =
        !           604:                   VideoPortGetDeviceBase(hwDeviceExtension,
        !           605:                                          accessRange[i].RangeStart,
        !           606:                                          accessRange[i].RangeLength,
        !           607:                                          accessRange[i].RangeInIoSpace)) == NULL) {
        !           608: 
        !           609:             VideoDebugPrint((1, "S3: DeviceBase mapping failed\n"));
        !           610:             return ERROR_INVALID_PARAMETER;
        !           611: 
        !           612:         }
        !           613:     }
        !           614: 
        !           615:     //
        !           616:     // Save the initial value of the S3 lock registers.
        !           617:     // it's possible, a non-s3 bios may expect them in a state
        !           618:     // define in POST.
        !           619:     //
        !           620: 
        !           621:     DataReg = VideoPortReadPortUchar(CRT_DATA_REG);
        !           622:     IndexReg = VideoPortReadPortUchar(CRT_ADDRESS_REG);
        !           623: 
        !           624:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x38);
        !           625:     reg38 = VideoPortReadPortUchar(CRT_DATA_REG);
        !           626: 
        !           627:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x39);
        !           628:     reg39 = VideoPortReadPortUchar(CRT_DATA_REG);
        !           629: 
        !           630:     //
        !           631:     // Now unlock all the S3 registers, for use in this routine.
        !           632:     //
        !           633: 
        !           634:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x4838);
        !           635:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0xA039);
        !           636: 
        !           637:     //
        !           638:     // Make sure we're working with an S3
        !           639:     // And while were at it, pickup the chip ID
        !           640:     //
        !           641: 
        !           642:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x30);
        !           643:     jChipID = VideoPortReadPortUchar(CRT_DATA_REG);
        !           644: 
        !           645:     //
        !           646:     // In this driver we just care about the major chip ID, not the revision
        !           647:     //
        !           648: 
        !           649:     jChipID &= 0xf0;
        !           650: 
        !           651:     switch(jChipID) {
        !           652: 
        !           653:         case 0x80: // 911 or 924
        !           654: 
        !           655:             VideoDebugPrint((2, "S3: 911 Chip Set\n"));
        !           656:             hwDeviceExtension->ChipID = S3_911;
        !           657:             break;
        !           658: 
        !           659: 
        !           660:         case 0x90: // 928
        !           661: 
        !           662:             VideoDebugPrint((2, "S3: 928 Chip Set\n"));
        !           663:             hwDeviceExtension->ChipID = S3_928;
        !           664:             break;
        !           665: 
        !           666:         case 0xA0: // 801/805
        !           667: 
        !           668:             VideoDebugPrint((2, "S3: 801/805 Chip Set\n"));
        !           669:             hwDeviceExtension->ChipID = S3_801;
        !           670:             break;
        !           671: 
        !           672:         default:
        !           673: 
        !           674:             VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg38 << 8) | 0x38));
        !           675:             VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg39 << 8) | 0x39));
        !           676:             VideoPortWritePortUchar(CRT_ADDRESS_REG, IndexReg);
        !           677:             VideoPortWritePortUchar(CRT_DATA_REG, DataReg);
        !           678: 
        !           679:             //
        !           680:             // Log an error to the event log. The unique Id of 0 is only used
        !           681:             // to identify which call to VideoPortLogError actually generated
        !           682:             // the message; a line # would also be appropriate.
        !           683:             //
        !           684: 
        !           685:             //
        !           686:             // NOTE
        !           687:             // This message has been removed because we hit it each time an
        !           688:             // S3 is not detected.
        !           689:             //
        !           690: 
        !           691:             // VideoPortLogError(hwDeviceExtension,
        !           692:             //                  NULL,
        !           693:             //                  S3_UNSUPPORTED_CHIP,
        !           694:             //                  __LINE__);
        !           695: 
        !           696:             VideoDebugPrint((2, "S3: unsupported chip set\n"));
        !           697:             return ERROR_DEV_NOT_EXIST;
        !           698:             break;
        !           699: 
        !           700:     }
        !           701: 
        !           702:     //
        !           703:     // At this point we know we have an S3 chip in the system.
        !           704:     // Set the defaults for the board type.
        !           705:     //
        !           706: 
        !           707:     hwDeviceExtension->BoardID = S3_GENERIC;
        !           708: 
        !           709:     //
        !           710:     // Get the Size the Video Memory.
        !           711:     //
        !           712: 
        !           713:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x36);
        !           714:     s3MemSizeCode = VideoPortReadPortUchar(CRT_DATA_REG) >> 5;
        !           715: 
        !           716:     if (hwDeviceExtension->ChipID == S3_911) {
        !           717: 
        !           718:         //
        !           719:         // This is for the 911 & 924
        !           720:         //
        !           721: 
        !           722:         if (s3MemSizeCode & 0x01) {
        !           723: 
        !           724:             VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg38 << 8) | 0x38));
        !           725:             VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg39 << 8) | 0x39));
        !           726:             VideoPortWritePortUchar(CRT_ADDRESS_REG, IndexReg);
        !           727: 
        !           728:             return ERROR_DEV_NOT_EXIST;
        !           729: 
        !           730:         } else {
        !           731: 
        !           732:             hwDeviceExtension->AdapterMemorySize = 0x00100000;
        !           733: 
        !           734:         }
        !           735: 
        !           736:     } else {
        !           737: 
        !           738:         //
        !           739:         // This is for the 801/805, and 928.
        !           740:         // If an invalid size or there is less than 1 meg on the card fail.
        !           741:         //
        !           742: 
        !           743:         switch (s3MemSizeCode) {
        !           744: 
        !           745:         case 0x0:   // 4 meg
        !           746: 
        !           747:             hwDeviceExtension->AdapterMemorySize = 0x00400000;
        !           748:             break;
        !           749: 
        !           750:         case 0x2:   // 3 meg
        !           751: 
        !           752:             hwDeviceExtension->AdapterMemorySize = 0x00300000;
        !           753:             break;
        !           754: 
        !           755:         case 0x4:   // 2 meg
        !           756: 
        !           757:             hwDeviceExtension->AdapterMemorySize = 0x00200000;
        !           758:             break;
        !           759: 
        !           760:         case 0x6:   // 1 meg
        !           761: 
        !           762:             hwDeviceExtension->AdapterMemorySize = 0x00100000;
        !           763:             break;
        !           764: 
        !           765:         case 0x1:   // invalid
        !           766:         case 0x3:   // invalid
        !           767:         case 0x5:   // invalid
        !           768:         case 0x7:   // 1/2 meg
        !           769:         default:
        !           770: 
        !           771:             VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg38 << 8) | 0x38));
        !           772:             VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg39 << 8) | 0x39));
        !           773:             VideoPortWritePortUchar(CRT_ADDRESS_REG, IndexReg);
        !           774: 
        !           775:             VideoPortLogError(hwDeviceExtension,
        !           776:                               NULL,
        !           777:                               S3_NOT_ENOUGH_VRAM,
        !           778:                               __LINE__);
        !           779: 
        !           780:             return ERROR_INVALID_PARAMETER;
        !           781: 
        !           782:         }
        !           783:     }
        !           784: 
        !           785:     //
        !           786:     // From the size of video memory calculate which modes are valid.
        !           787:     //
        !           788: 
        !           789:     hwDeviceExtension->NumAvailableModes = 0;
        !           790: 
        !           791:     for (i=0; i < NumS3VideoModes; i++) {
        !           792: 
        !           793:         //
        !           794:         // Set the mode so it does not have to be hardcoded in the mode table.
        !           795:         //
        !           796: 
        !           797:         S3Modes[i].ModeInformation.ModeIndex = i;
        !           798: 
        !           799:         //
        !           800:         // Set the mode to valid if it is.
        !           801:         //
        !           802: 
        !           803:         if (S3Modes[i].RequiredVideoMemory <=
        !           804:             hwDeviceExtension->AdapterMemorySize) {
        !           805: 
        !           806: #ifdef i386
        !           807:             if (S3Modes[i].Int10ModeNumber) {
        !           808: #else
        !           809:             if (S3Modes[i].CRTCTables[hwDeviceExtension->ChipID]) {
        !           810: #endif
        !           811: 
        !           812:                 S3Modes[i].ModeValid = TRUE;
        !           813:                 hwDeviceExtension->NumAvailableModes++;
        !           814:             }
        !           815:         }
        !           816:     }
        !           817: 
        !           818:     //
        !           819:     // Check if we need to remap the registers of the S3 due to a register
        !           820:     // contention with the COM3 COM4.
        !           821:     //
        !           822:     // Allow allow for override to use alternate register set from the
        !           823:     // registry.
        !           824:     //
        !           825: 
        !           826:     if (NO_ERROR == VideoPortGetRegistryParameters(hwDeviceExtension,
        !           827:                                                    L"UseAlternateRegisterSet",
        !           828:                                                    FALSE,
        !           829:                                                    S3RegistryCallback,
        !           830:                                                    NULL)) {
        !           831: 
        !           832:         useAlternateRegisters = TRUE;
        !           833: 
        !           834:     }
        !           835: 
        !           836:     //
        !           837:     // This assumes the S3 registers are unlocked.
        !           838:     //
        !           839: 
        !           840:     //
        !           841:     // Get the original register values.
        !           842:     //
        !           843: 
        !           844:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x40);
        !           845:     reg40 = VideoPortReadPortUchar(CRT_DATA_REG);
        !           846: 
        !           847:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x43);
        !           848:     reg43 = VideoPortReadPortUchar(CRT_DATA_REG);
        !           849: 
        !           850: //
        !           851: // Using the BIOS and registers to detect conflict does appear to work *ONLY*
        !           852: // on x86 based machines
        !           853: //
        !           854: // We will keep the manual override (above) for everyone, just in case ....
        !           855: //
        !           856: 
        !           857: #ifdef i386
        !           858: 
        !           859:     //
        !           860:     // The 801/805 and 928 allow quesrying of the extended registers to
        !           861:     // determine if the registers should be remapped
        !           862:     //
        !           863: 
        !           864:     switch(hwDeviceExtension->ChipID) {
        !           865: 
        !           866:     case S3_801:
        !           867:     case S3_928:
        !           868: 
        !           869:         {
        !           870:         LONG i;
        !           871: 
        !           872:         //
        !           873:         // Disable the enhanced registers.
        !           874:         //
        !           875: 
        !           876:         VideoPortWritePortUshort(CRT_ADDRESS_REG,
        !           877:                                  ((USHORT)(((USHORT) (reg40 & ~0x01) << 8) | 0x40)));
        !           878: 
        !           879:         //
        !           880:         // Make sure there is no remapping.
        !           881:         //
        !           882: 
        !           883:         reg43 &= ~0x10;
        !           884: 
        !           885:         VideoPortWritePortUshort(CRT_ADDRESS_REG,
        !           886:                                  ((USHORT)(((USHORT) reg43 << 8) | 0x43)));
        !           887: 
        !           888:         //
        !           889:         // Read each of the enhanced registers.  If any of them do not
        !           890:         // come back 0xff, then we have an I/O conflict, and we should remap
        !           891:         // the I/O registers, by setting bit 4 of register 0x43.
        !           892:         //
        !           893: 
        !           894:         for (i = S3_EXTENDED_RANGE_START; i < NUM_S3_ACCESS_RANGES; i++) {
        !           895: 
        !           896:             if (VideoPortReadPortUshort(
        !           897:                     (PUSHORT) hwDeviceExtension->MappedAddress[i]) != 0xFFFF) {
        !           898: 
        !           899:                 //
        !           900:                 // We have detected an I/O conflict,
        !           901:                 // So we must remap the registers.
        !           902:                 //
        !           903: 
        !           904:                 useAlternateRegisters = TRUE;
        !           905: 
        !           906:                 break;
        !           907: 
        !           908:             }
        !           909:         }
        !           910: 
        !           911:         break;
        !           912:         }
        !           913: 
        !           914:     default:
        !           915: 
        !           916:         break;
        !           917: 
        !           918:     }
        !           919: 
        !           920: #endif
        !           921: 
        !           922:     //
        !           923:     // If we do use the alternate, update all of our resources.
        !           924:     //
        !           925: 
        !           926:     if (useAlternateRegisters) {
        !           927: 
        !           928:         VideoDebugPrint((1, "S3: S3 registers relocated to support COM3 COM4\n"));
        !           929: 
        !           930:         //
        !           931:         // Calculate the updated value for reg 43.
        !           932:         //
        !           933: 
        !           934:         reg43 |= 0x10;
        !           935: 
        !           936:         for (i = 1; i < NUM_S3_ACCESS_RANGES; i++) {
        !           937: 
        !           938:             //
        !           939:             // First free the mapped address.
        !           940:             //
        !           941: 
        !           942:             VideoPortFreeDeviceBase(hwDeviceExtension,
        !           943:                                     hwDeviceExtension->MappedAddress[i]);
        !           944: 
        !           945:             //
        !           946:             // Get the new address (by XORing 3A0)
        !           947:             //
        !           948: 
        !           949:             accessRange[i].RangeStart.LowPart ^= 0x3A0;
        !           950: 
        !           951:             //
        !           952:             // Map the new address.
        !           953:             //
        !           954: 
        !           955:             if ( (hwDeviceExtension->MappedAddress[i] =
        !           956:                       VideoPortGetDeviceBase(hwDeviceExtension,
        !           957:                                              accessRange[i].RangeStart,
        !           958:                                              accessRange[i].RangeLength,
        !           959:                                              accessRange[i].RangeInIoSpace)) == NULL) {
        !           960: 
        !           961:                 return ERROR_INVALID_PARAMETER;
        !           962: 
        !           963:             }
        !           964:         }
        !           965:     }
        !           966: 
        !           967:     //
        !           968:     // Reset regs to the original (or modified) value.
        !           969:     //
        !           970: 
        !           971:     VideoPortWritePortUshort(CRT_ADDRESS_REG,
        !           972:                              ((USHORT)(((USHORT) reg43 << 8) | 0x43)));
        !           973: 
        !           974:     VideoPortWritePortUshort(CRT_ADDRESS_REG,
        !           975:                              ((USHORT)(((USHORT) reg40 << 8) | 0x40)));
        !           976: 
        !           977: 
        !           978:     //
        !           979:     // Were done mucking about with the S3 chip, so lock all the registers.
        !           980:     //
        !           981: 
        !           982:     VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg38 << 8) | 0x38));
        !           983:     VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg39 << 8) | 0x39));
        !           984:     VideoPortWritePortUchar(CRT_ADDRESS_REG, IndexReg);
        !           985: 
        !           986: 
        !           987:     //
        !           988:     // We will try to recognize a few boards.
        !           989:     // If this fails we must exit since we do not know how to initialize the
        !           990:     // board
        !           991:     //
        !           992: 
        !           993:     bMatch = FALSE;
        !           994: 
        !           995:     //
        !           996:     // Look for brand name signatures in the ROM.
        !           997:     //
        !           998: 
        !           999:     romAddress = VideoPortGetDeviceBase(hwDeviceExtension,
        !          1000:                                         accessRange[0].RangeStart,
        !          1001:                                         accessRange[0].RangeLength,
        !          1002:                                         accessRange[0].RangeInIoSpace);
        !          1003: 
        !          1004:     if (romAddress) {
        !          1005: 
        !          1006:         usRomSignature = VideoPortReadRegisterUshort(romAddress);
        !          1007: 
        !          1008:         if (usRomSignature == 0xAA55) {
        !          1009: 
        !          1010:             bMatch = VideoPortScanRom(hwDeviceExtension,
        !          1011:                                       romAddress,
        !          1012:                                       MAX_ROM_SCAN,
        !          1013:                                       "Number Nine Computer");
        !          1014: 
        !          1015:             if (bMatch == TRUE) {
        !          1016: 
        !          1017:                 hwDeviceExtension->BoardID = S3_NUMBER_NINE;
        !          1018: 
        !          1019:                 //
        !          1020:                 // We know (at least we think) this is number nine board.
        !          1021:                 // there was a bios change at #9 to change the refresh rate
        !          1022:                 // mapping.  This change was made at Microsofts request.  the
        !          1023:                 // problem is that the change has not make into production at
        !          1024:                 // the time this driver was written.  For this reason, we must
        !          1025:                 // check the bios version number, before we special case the
        !          1026:                 // card as the number nine card.
        !          1027:                 //
        !          1028:                 // There is a byte in the bios at offset 0x190, that is the
        !          1029:                 // offset from the beginning of the bios for the bios version
        !          1030:                 // number.  the bios version number is a string.  all the
        !          1031:                 // bios versions before 1.10.04 need this special translation.
        !          1032:                 // all the other bios's use a translation closer to the s3
        !          1033:                 // standard.
        !          1034:                 //
        !          1035: 
        !          1036:                 //
        !          1037:                 // We only do this on x86 because on MIPS we do not use the
        !          1038:                 // BIOS.
        !          1039:                 //
        !          1040: 
        !          1041: #ifdef i386
        !          1042: 
        !          1043:                 offset = * (((PUCHAR) romAddress) + 0x190);
        !          1044:                 pjBiosVersion = (PUCHAR) romAddress + offset;
        !          1045: 
        !          1046:                 pjRefString = "1.10.04";
        !          1047:                 iCmpRet = strncmp(pjBiosVersion,
        !          1048:                                   pjRefString,
        !          1049:                                   strlen(pjRefString));
        !          1050: 
        !          1051:                 if (iCmpRet >= 0) {
        !          1052: 
        !          1053:                     hwDeviceExtension->BoardID = S3_GENERIC;
        !          1054: 
        !          1055:                 }
        !          1056: 
        !          1057: #endif
        !          1058: 
        !          1059:             } else {
        !          1060: 
        !          1061:                 //
        !          1062:                 // Look for an Orchid board
        !          1063:                 //
        !          1064: 
        !          1065:                 bMatch = VideoPortScanRom(hwDeviceExtension,
        !          1066:                                           romAddress,
        !          1067:                                           MAX_ROM_SCAN,
        !          1068:                                           "Orchid Technology Fahrenheit 1280");
        !          1069: 
        !          1070:                 if (bMatch == TRUE) {
        !          1071: 
        !          1072:                     hwDeviceExtension->BoardID = S3_ORCHID;
        !          1073: 
        !          1074:                 } else {
        !          1075: 
        !          1076:                     //
        !          1077:                     // Look for the DELL trademark
        !          1078:                     //
        !          1079: 
        !          1080:                     bMatch = VideoPortScanRom(hwDeviceExtension,
        !          1081:                                               romAddress,
        !          1082:                                               MAX_ROM_SCAN,
        !          1083:                                               "DELL");
        !          1084: 
        !          1085:                     if (bMatch == TRUE) {
        !          1086: 
        !          1087:                         hwDeviceExtension->BoardID = S3_DELL;
        !          1088: 
        !          1089:                     }
        !          1090:                 }
        !          1091: 
        !          1092:             }
        !          1093: 
        !          1094:         }
        !          1095: 
        !          1096:         //
        !          1097:         // Free the ROM address since we do not need it anymore.
        !          1098:         //
        !          1099: 
        !          1100:         VideoPortFreeDeviceBase(hwDeviceExtension,
        !          1101:                                 romAddress);
        !          1102: 
        !          1103:     }
        !          1104: 
        !          1105: #ifdef i386
        !          1106: 
        !          1107:     //
        !          1108:     // We use int10 on x86
        !          1109:     //
        !          1110: 
        !          1111:     hwDeviceExtension->bUsingInt10 = TRUE;
        !          1112: 
        !          1113:     //
        !          1114:     // We have this so that the int10 will also work on the VGA also if we
        !          1115:     // use it in this driver.
        !          1116:     //
        !          1117: 
        !          1118:     ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart  = 0x000A0000;
        !          1119:     ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
        !          1120:     ConfigInfo->VdmPhysicalVideoMemoryLength           = 0x00020000;
        !          1121: 
        !          1122: #else
        !          1123: 
        !          1124:     //
        !          1125:     // On non-x86 platforms we can not use int 10.
        !          1126:     //
        !          1127: 
        !          1128:     hwDeviceExtension->bUsingInt10 = FALSE;
        !          1129: 
        !          1130:     ConfigInfo->VdmPhysicalVideoMemoryAddress.LowPart  = 0x00000000;
        !          1131:     ConfigInfo->VdmPhysicalVideoMemoryAddress.HighPart = 0x00000000;
        !          1132:     ConfigInfo->VdmPhysicalVideoMemoryLength           = 0x00000000;
        !          1133: 
        !          1134: #endif // i386
        !          1135: 
        !          1136:     //
        !          1137:     // Clear out the Emulator entries and the state size since this driver
        !          1138:     // does not support them.
        !          1139:     //
        !          1140: 
        !          1141:     ConfigInfo->NumEmulatorAccessEntries     = 0;
        !          1142:     ConfigInfo->EmulatorAccessEntries        = NULL;
        !          1143:     ConfigInfo->EmulatorAccessEntriesContext = 0;
        !          1144: 
        !          1145:     //
        !          1146:     // This driver does not do SAVE/RESTORE of hardware state.
        !          1147:     //
        !          1148: 
        !          1149:     ConfigInfo->HardwareStateSize = 0;
        !          1150: 
        !          1151:     //
        !          1152:     // Frame buffer information
        !          1153:     //
        !          1154: 
        !          1155:     hwDeviceExtension->PhysicalFrameAddress = accessRange[1].RangeStart;
        !          1156:     hwDeviceExtension->FrameLength          = accessRange[1].RangeLength;
        !          1157: 
        !          1158:     //
        !          1159:     // IO Port information
        !          1160:     // Get the base address, starting at zero and map all registers
        !          1161:     //
        !          1162: 
        !          1163:     hwDeviceExtension->PhysicalRegisterAddress = accessRange[2].RangeStart;
        !          1164:     hwDeviceExtension->PhysicalRegisterAddress.LowPart &= 0xFFFF0000;
        !          1165: 
        !          1166:     hwDeviceExtension->RegisterLength = 0x10000;
        !          1167:     hwDeviceExtension->RegisterSpace = accessRange[2].RangeInIoSpace;
        !          1168: 
        !          1169:     //
        !          1170:     // Indicate we do not wish to be called over
        !          1171:     //
        !          1172: 
        !          1173:     *Again = 0;
        !          1174: 
        !          1175:     //
        !          1176:     // Indicate a successful completion status.
        !          1177:     //
        !          1178: 
        !          1179:     return NO_ERROR;
        !          1180: 
        !          1181: } // end S3FindAdapter()
        !          1182: 
        !          1183: 
        !          1184: VP_STATUS
        !          1185: S3RegistryCallback(
        !          1186:     PVOID HwDeviceExtension,
        !          1187:     PVOID Context,
        !          1188:     PWSTR ValueName,
        !          1189:     PVOID ValueData,
        !          1190:     ULONG ValueLength
        !          1191:     )
        !          1192: 
        !          1193: /*++
        !          1194: 
        !          1195: Routine Description:
        !          1196: 
        !          1197:     This routine determines if the alternate register set was requested via
        !          1198:     the registry.
        !          1199: 
        !          1200: Arguments:
        !          1201: 
        !          1202:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          1203: 
        !          1204:     Context - Context value passed to the get registry paramters routine.
        !          1205: 
        !          1206:     ValueName - Name of the value requested.
        !          1207: 
        !          1208:     ValueData - Pointer to the requested data.
        !          1209: 
        !          1210:     ValueLength - Length of the requested data.
        !          1211: 
        !          1212: Return Value:
        !          1213: 
        !          1214:     returns NO_ERROR if the paramter was TRUE.
        !          1215:     returns ERROR_INVALID_PARAMETER otherwise.
        !          1216: 
        !          1217: --*/
        !          1218: 
        !          1219: {
        !          1220: 
        !          1221:     if (ValueLength && *((PULONG)ValueData)) {
        !          1222: 
        !          1223:         return NO_ERROR;
        !          1224: 
        !          1225:     } else {
        !          1226: 
        !          1227:         return ERROR_INVALID_PARAMETER;
        !          1228: 
        !          1229:     }
        !          1230: 
        !          1231: } // end S3RegistryCallback()
        !          1232: 
        !          1233: 
        !          1234: BOOLEAN
        !          1235: S3Initialize(
        !          1236:     PVOID HwDeviceExtension
        !          1237:     )
        !          1238: 
        !          1239: /*++
        !          1240: 
        !          1241: Routine Description:
        !          1242: 
        !          1243:     This routine does one time initialization of the device.
        !          1244: 
        !          1245: Arguments:
        !          1246: 
        !          1247:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          1248: 
        !          1249: Return Value:
        !          1250: 
        !          1251: 
        !          1252:     Always returns TRUE since this routine can never fail.
        !          1253: 
        !          1254: --*/
        !          1255: 
        !          1256: {
        !          1257: #if i386
        !          1258: 
        !          1259:     UCHAR   IndexReg, reg38, reg39;
        !          1260:     ULONG   i;
        !          1261: 
        !          1262:     IndexReg = VideoPortReadPortUchar(CRT_ADDRESS_REG);
        !          1263: 
        !          1264:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x38);
        !          1265:     reg38 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1266: 
        !          1267:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x39);
        !          1268:     reg39 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1269: 
        !          1270:     //
        !          1271:     // Unlock the S3 registers.
        !          1272:     //
        !          1273: 
        !          1274:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x4838);
        !          1275:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0xA039);
        !          1276: 
        !          1277:     //
        !          1278:     // read all the extended registers.
        !          1279:     //
        !          1280: 
        !          1281:     for (i = 0; i < nExtendedRegs; i++) {
        !          1282: 
        !          1283:         VideoPortWritePortUchar(CRT_ADDRESS_REG, arvExtendedRegs[i].port);
        !          1284:         arvExtendedRegs[i].val = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1285: 
        !          1286:     }
        !          1287: 
        !          1288:     //
        !          1289:     // restore the chip to the same state is was in when we got here.
        !          1290:     //
        !          1291: 
        !          1292:     VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg38 << 8) | 0x38));
        !          1293:     VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg39 << 8) | 0x39));
        !          1294:     VideoPortWritePortUchar(CRT_ADDRESS_REG, IndexReg);
        !          1295: 
        !          1296: #endif
        !          1297: 
        !          1298:     return TRUE;
        !          1299: 
        !          1300:     UNREFERENCED_PARAMETER(HwDeviceExtension);
        !          1301: 
        !          1302: } // end S3Initialize()
        !          1303: 
        !          1304: BOOLEAN
        !          1305: S3StartIO(
        !          1306:     PVOID HwDeviceExtension,
        !          1307:     PVIDEO_REQUEST_PACKET RequestPacket
        !          1308:     )
        !          1309: 
        !          1310: /*++
        !          1311: 
        !          1312: Routine Description:
        !          1313: 
        !          1314:     This routine is the main execution routine for the miniport driver. It
        !          1315:     acceptss a Video Request Packet, performs the request, and then returns
        !          1316:     with the appropriate status.
        !          1317: 
        !          1318: Arguments:
        !          1319: 
        !          1320:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          1321: 
        !          1322:     RequestPacket - Pointer to the video request packet. This structure
        !          1323:         contains all the parameters passed to the VideoIoControl function.
        !          1324: 
        !          1325: Return Value:
        !          1326: 
        !          1327: 
        !          1328: --*/
        !          1329: 
        !          1330: {
        !          1331:     PHW_DEVICE_EXTENSION hwDeviceExtension = HwDeviceExtension;
        !          1332:     VP_STATUS status;
        !          1333:     ULONG inIoSpace;
        !          1334:     PVIDEO_MODE_INFORMATION modeInformation;
        !          1335:     PVIDEO_MEMORY_INFORMATION memoryInformation;
        !          1336:     PVIDEO_CLUT clutBuffer;
        !          1337:     ULONG i;
        !          1338:     UCHAR byte, ModeControlByte;
        !          1339: 
        !          1340:     VIDEO_X86_BIOS_ARGUMENTS biosArguments;
        !          1341:     ULONG modeNumber;
        !          1342:     PUCHAR pModeBits;
        !          1343: 
        !          1344:     //
        !          1345:     // Keep a history of the commands.
        !          1346:     // This will help track down the chip being in a DOS session while
        !          1347:     // GDI and the S3 display driver "think" it's in GUI mode.
        !          1348: 
        !          1349:     gaIOControlCode[giControlCode++] = RequestPacket->IoControlCode;
        !          1350:     giControlCode                   %= MAX_CONTROL_HISTORY;
        !          1351: 
        !          1352:     //
        !          1353:     // Switch on the IoContolCode in the RequestPacket. It indicates which
        !          1354:     // function must be performed by the driver.
        !          1355:     //
        !          1356: 
        !          1357:     switch (RequestPacket->IoControlCode) {
        !          1358: 
        !          1359: 
        !          1360:     case IOCTL_VIDEO_MAP_VIDEO_MEMORY:
        !          1361: 
        !          1362:         VideoDebugPrint((2, "S3tartIO - MapVideoMemory\n"));
        !          1363: 
        !          1364:         if ( (RequestPacket->OutputBufferLength <
        !          1365:               (RequestPacket->StatusBlock->Information =
        !          1366:                                      sizeof(VIDEO_MEMORY_INFORMATION))) ||
        !          1367:              (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) ) {
        !          1368: 
        !          1369:             status = ERROR_INSUFFICIENT_BUFFER;
        !          1370:         }
        !          1371: 
        !          1372:         memoryInformation = RequestPacket->OutputBuffer;
        !          1373: 
        !          1374:         memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
        !          1375:                 (RequestPacket->InputBuffer))->RequestedVirtualAddress;
        !          1376: 
        !          1377:         memoryInformation->VideoRamLength =
        !          1378:                 hwDeviceExtension->FrameLength;
        !          1379: 
        !          1380:         inIoSpace = 0;
        !          1381: 
        !          1382:         status = VideoPortMapMemory(hwDeviceExtension,
        !          1383:                                     hwDeviceExtension->PhysicalFrameAddress,
        !          1384:                                     &(memoryInformation->VideoRamLength),
        !          1385:                                     &inIoSpace,
        !          1386:                                     &(memoryInformation->VideoRamBase));
        !          1387: 
        !          1388:         //
        !          1389:         // The frame buffer and virtual memory and equivalent in this
        !          1390:         // case.
        !          1391:         //
        !          1392: 
        !          1393:         memoryInformation->FrameBufferBase =
        !          1394:             memoryInformation->VideoRamBase;
        !          1395: 
        !          1396:         memoryInformation->FrameBufferLength =
        !          1397:             memoryInformation->VideoRamLength;
        !          1398: 
        !          1399:         break;
        !          1400: 
        !          1401: 
        !          1402:     case IOCTL_VIDEO_UNMAP_VIDEO_MEMORY:
        !          1403: 
        !          1404:         VideoDebugPrint((2, "S3StartIO - UnMapVideoMemory\n"));
        !          1405: 
        !          1406:         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
        !          1407: 
        !          1408:             status = ERROR_INSUFFICIENT_BUFFER;
        !          1409:         }
        !          1410: 
        !          1411:         status = VideoPortUnmapMemory(hwDeviceExtension,
        !          1412:                                       ((PVIDEO_MEMORY)
        !          1413:                                        (RequestPacket->InputBuffer))->
        !          1414:                                            RequestedVirtualAddress,
        !          1415:                                       0);
        !          1416: 
        !          1417:         break;
        !          1418: 
        !          1419: 
        !          1420:     case IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES:
        !          1421: 
        !          1422:         VideoDebugPrint((2, "S3StartIO - QueryPublicAccessRanges\n"));
        !          1423: 
        !          1424:         {
        !          1425: 
        !          1426:            PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
        !          1427:            ULONG physicalPortLength;
        !          1428: 
        !          1429:            if ( RequestPacket->OutputBufferLength <
        !          1430:                  (RequestPacket->StatusBlock->Information =
        !          1431:                                         sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) ) {
        !          1432: 
        !          1433:                status = ERROR_INSUFFICIENT_BUFFER;
        !          1434:            }
        !          1435: 
        !          1436:            portAccess = RequestPacket->OutputBuffer;
        !          1437: 
        !          1438:            portAccess->VirtualAddress  = (PVOID) NULL;    // Requested VA
        !          1439:            portAccess->InIoSpace       = hwDeviceExtension->RegisterSpace;
        !          1440:            portAccess->MappedInIoSpace = portAccess->InIoSpace;
        !          1441: 
        !          1442:            physicalPortLength = hwDeviceExtension->RegisterLength;
        !          1443: 
        !          1444:            status = VideoPortMapMemory(hwDeviceExtension,
        !          1445:                                        hwDeviceExtension->PhysicalRegisterAddress,
        !          1446:                                        &physicalPortLength,
        !          1447:                                        &(portAccess->MappedInIoSpace),
        !          1448:                                        &(portAccess->VirtualAddress));
        !          1449:         }
        !          1450: 
        !          1451:         break;
        !          1452: 
        !          1453: 
        !          1454:     case IOCTL_VIDEO_FREE_PUBLIC_ACCESS_RANGES:
        !          1455: 
        !          1456:         VideoDebugPrint((2, "S3StartIO - FreePublicAccessRanges\n"));
        !          1457: 
        !          1458:         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MEMORY)) {
        !          1459: 
        !          1460:             status = ERROR_INSUFFICIENT_BUFFER;
        !          1461:         }
        !          1462: 
        !          1463:         status = VideoPortUnmapMemory(hwDeviceExtension,
        !          1464:                                       ((PVIDEO_MEMORY)
        !          1465:                                        (RequestPacket->InputBuffer))->
        !          1466:                                            RequestedVirtualAddress,
        !          1467:                                       0);
        !          1468: 
        !          1469:         break;
        !          1470: 
        !          1471: 
        !          1472:     case IOCTL_VIDEO_QUERY_AVAIL_MODES:
        !          1473: 
        !          1474:         VideoDebugPrint((2, "S3StartIO - QueryAvailableModes\n"));
        !          1475: 
        !          1476:         if (RequestPacket->OutputBufferLength <
        !          1477:             (RequestPacket->StatusBlock->Information =
        !          1478:                  hwDeviceExtension->NumAvailableModes
        !          1479:                  * sizeof(VIDEO_MODE_INFORMATION)) ) {
        !          1480: 
        !          1481:             status = ERROR_INSUFFICIENT_BUFFER;
        !          1482: 
        !          1483:         } else {
        !          1484: 
        !          1485:             modeInformation = RequestPacket->OutputBuffer;
        !          1486: 
        !          1487:             for (i = 0; i < NumS3VideoModes; i++) {
        !          1488: 
        !          1489:                 if (S3Modes[i].ModeValid) {
        !          1490: 
        !          1491:                     *modeInformation = S3Modes[i].ModeInformation;
        !          1492:                     modeInformation++;
        !          1493: 
        !          1494:                 }
        !          1495:             }
        !          1496: 
        !          1497:             status = NO_ERROR;
        !          1498:         }
        !          1499: 
        !          1500:         break;
        !          1501: 
        !          1502: 
        !          1503:      case IOCTL_VIDEO_QUERY_CURRENT_MODE:
        !          1504: 
        !          1505:         VideoDebugPrint((2, "S3StartIO - QueryCurrentModes\n"));
        !          1506: 
        !          1507:         if (RequestPacket->OutputBufferLength <
        !          1508:             (RequestPacket->StatusBlock->Information =
        !          1509:             sizeof(VIDEO_MODE_INFORMATION)) ) {
        !          1510: 
        !          1511:             status = ERROR_INSUFFICIENT_BUFFER;
        !          1512: 
        !          1513:         } else {
        !          1514: 
        !          1515:             *((PVIDEO_MODE_INFORMATION)RequestPacket->OutputBuffer) =
        !          1516:                 S3Modes[hwDeviceExtension->ModeNumber].ModeInformation;
        !          1517: 
        !          1518:             status = NO_ERROR;
        !          1519: 
        !          1520:         }
        !          1521: 
        !          1522:         break;
        !          1523: 
        !          1524: 
        !          1525: 
        !          1526:     case IOCTL_VIDEO_QUERY_NUM_AVAIL_MODES:
        !          1527: 
        !          1528:         VideoDebugPrint((2, "S3StartIO - QueryNumAvailableModes\n"));
        !          1529: 
        !          1530:         //
        !          1531:         // Find out the size of the data to be put in the the buffer and
        !          1532:         // return that in the status information (whether or not the
        !          1533:         // information is there). If the buffer passed in is not large
        !          1534:         // enough return an appropriate error code.
        !          1535:         //
        !          1536: 
        !          1537:         if (RequestPacket->OutputBufferLength <
        !          1538:                 (RequestPacket->StatusBlock->Information =
        !          1539:                                                 sizeof(VIDEO_NUM_MODES)) ) {
        !          1540: 
        !          1541:             status = ERROR_INSUFFICIENT_BUFFER;
        !          1542: 
        !          1543:         } else {
        !          1544: 
        !          1545:             ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->NumModes =
        !          1546:                 hwDeviceExtension->NumAvailableModes;
        !          1547: 
        !          1548:             ((PVIDEO_NUM_MODES)RequestPacket->OutputBuffer)->ModeInformationLength =
        !          1549:                 sizeof(VIDEO_MODE_INFORMATION);
        !          1550: 
        !          1551: 
        !          1552:             status = NO_ERROR;
        !          1553:         }
        !          1554: 
        !          1555:         break;
        !          1556: 
        !          1557: 
        !          1558:     case IOCTL_VIDEO_SET_CURRENT_MODE:
        !          1559: 
        !          1560:         VideoDebugPrint((2, "S3StartIO - SetCurrentMode\n"));
        !          1561: 
        !          1562:         //
        !          1563:         // Check if the size of the data in the input buffer is large enough.
        !          1564:         //
        !          1565: 
        !          1566:         if (RequestPacket->InputBufferLength < sizeof(VIDEO_MODE)) {
        !          1567: 
        !          1568:             return ERROR_INSUFFICIENT_BUFFER;
        !          1569: 
        !          1570:         }
        !          1571: 
        !          1572:         //
        !          1573:         // Check to see if we are requesting a valid mode
        !          1574:         //
        !          1575: 
        !          1576:         modeNumber = ((PVIDEO_MODE) RequestPacket->InputBuffer)->RequestedMode;
        !          1577: 
        !          1578:         if ( (modeNumber >= NumS3VideoModes) ||
        !          1579:              (!S3Modes[modeNumber].ModeValid) ) {
        !          1580: 
        !          1581:             return ERROR_INVALID_PARAMETER;
        !          1582: 
        !          1583:         }
        !          1584: 
        !          1585: #ifdef i386
        !          1586: 
        !          1587:         VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
        !          1588: 
        !          1589:         //
        !          1590:         // Unlock the S3 registers.
        !          1591:         //
        !          1592: 
        !          1593:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x4838);
        !          1594:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0xA039);
        !          1595: 
        !          1596:         /*
        !          1597:          Important Note: The Actix 911 board did not boot when the low order
        !          1598:                          bits of reg 41 were changed in the 640 X 480 or the
        !          1599:                          800 X 600 modes.  The Stealth did not change to 60Hz
        !          1600:                          in the 1024 X 768 mode when the low order bits were
        !          1601:                          set, it stayed at 70Hz.  And the Orchid would come up
        !          1602:                          in interlaced in 1024 X 768 when it should have been
        !          1603:                          60Hz.  Since the 911 is at the end of it's product
        !          1604:                          life cycle it would be unreasonable to expect the
        !          1605:                          board manufactures to upgrade the ROMS.  And the user
        !          1606:                          currently know how to set the board dip switches, so
        !          1607:                          the V refresh rate control is being removed for the
        !          1608:                          911 and 924 based boards.
        !          1609:         */
        !          1610: 
        !          1611:         //
        !          1612:         // If this is a 801/805 or 928 pickup the refresh control byte from
        !          1613:         // the chip, set the mode we want, and put the bits back in the chip.
        !          1614:         //
        !          1615: 
        !          1616:         //
        !          1617:         // A refresh rate of 1 indicates to use whatever is left in the BIOS
        !          1618:         // data area ...
        !          1619:         //
        !          1620: 
        !          1621:         if (S3Modes[modeNumber].ModeInformation.Frequency != 1) {
        !          1622: 
        !          1623:             switch(hwDeviceExtension->ChipID) {
        !          1624: 
        !          1625:             case S3_801:
        !          1626:             case S3_928:
        !          1627: 
        !          1628:                 VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x52);
        !          1629: 
        !          1630:                 ModeControlByte  = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1631:                 ModeControlByte &= ModeMaskBits[modeNumber];
        !          1632: 
        !          1633:                 switch(hwDeviceExtension->BoardID) {
        !          1634: 
        !          1635:                 case S3_NUMBER_NINE:
        !          1636: 
        !          1637:                     pModeBits = NumberNineModeBits;
        !          1638:                     break;
        !          1639: 
        !          1640:                 case S3_DELL:
        !          1641: 
        !          1642:                     pModeBits = DellModeBits;
        !          1643:                     break;
        !          1644: 
        !          1645:                 // case S3_GENERIC:
        !          1646:                 default:
        !          1647: 
        !          1648:                     pModeBits = GenericModeBits;
        !          1649:                     break;
        !          1650: 
        !          1651:                 }
        !          1652: 
        !          1653:                 ModeControlByte |= pModeBits[modeNumber];
        !          1654: 
        !          1655:                 VideoPortWritePortUchar(CRT_DATA_REG, ModeControlByte);
        !          1656: 
        !          1657:                 break;
        !          1658: 
        !          1659:             default:
        !          1660: 
        !          1661:                 break;
        !          1662: 
        !          1663:             }
        !          1664:         }
        !          1665: 
        !          1666:         biosArguments.Ebx = S3Modes[modeNumber].Int10ModeNumber;
        !          1667:         biosArguments.Eax = 0x4f02;
        !          1668: 
        !          1669:         status = VideoPortInt10(HwDeviceExtension, &biosArguments);
        !          1670: 
        !          1671:         //
        !          1672:         // If we get an error, return it.
        !          1673:         //
        !          1674: 
        !          1675:         if (status != NO_ERROR) {
        !          1676: 
        !          1677:             break;
        !          1678: 
        !          1679:         }
        !          1680: 
        !          1681:         //
        !          1682:         // Save the mode number since we know the rest will work.
        !          1683:         //
        !          1684: 
        !          1685:         hwDeviceExtension->ModeNumber = modeNumber;
        !          1686: 
        !          1687:         //
        !          1688:         // Unlock the S3 registers,  we need to unlock the registers a second time,
        !          1689:         // since we do not know what state the locks were in after the Int10.
        !          1690:         //
        !          1691: 
        !          1692:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x4838);
        !          1693:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0xA039);
        !          1694: 
        !          1695:         //
        !          1696:         // If this is a 1280 mode then set to non-contiguous memory mode.
        !          1697:         //
        !          1698: 
        !          1699:         if (S3Modes[modeNumber].ModeInformation.VisScreenWidth == 1280) {
        !          1700: 
        !          1701:             //
        !          1702:             // Make sure we are not in linear address mode
        !          1703:             //
        !          1704: 
        !          1705:             VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x58);
        !          1706:             byte = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1707:             byte &= ~0x10;
        !          1708:             VideoPortWritePortUchar(CRT_DATA_REG, byte);
        !          1709: 
        !          1710:             //
        !          1711:             // Turn on the graphics engine.
        !          1712:             //
        !          1713: 
        !          1714:             VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x40);
        !          1715:             byte = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1716:             byte |= 0x01;
        !          1717:             VideoPortWritePortUchar(CRT_DATA_REG, byte);
        !          1718: 
        !          1719:             //
        !          1720:             // Set the 2K by 1K memory map.
        !          1721:             //
        !          1722: 
        !          1723:             VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x0013);
        !          1724:             VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x8f31);
        !          1725:             VideoPortWritePortUshort(ADV_FUNC_CTL,    0x0003);
        !          1726:             VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x0050);
        !          1727:             VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x5051);
        !          1728: 
        !          1729:             //
        !          1730:             // Some of the number nine boards do set the chip up correctly
        !          1731:             // for an external cursor. We must OR in the bits, because if we
        !          1732:             // don't the metheus board will not init.
        !          1733:             //
        !          1734: 
        !          1735:             VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x45);
        !          1736:             byte = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1737:             byte |= 0x20;
        !          1738:             VideoPortWritePortUchar(CRT_DATA_REG, byte);
        !          1739: 
        !          1740:             VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x55);
        !          1741:             byte = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1742:             byte |= 0x20;
        !          1743:             VideoPortWritePortUchar(CRT_DATA_REG, byte);
        !          1744: 
        !          1745:         }
        !          1746: 
        !          1747: #else
        !          1748:         //
        !          1749:         // For MIPS program according to the mode tables
        !          1750:         //
        !          1751: 
        !          1752:         //
        !          1753:         // Save the mode number since we will reference it in SetHWMode.
        !          1754:         //
        !          1755: 
        !          1756:         hwDeviceExtension->ModeNumber = modeNumber;
        !          1757: 
        !          1758:         //
        !          1759:         // Select the Enhanced mode init depending upon the type of chip
        !          1760:         // found.
        !          1761: 
        !          1762:         if ( (hwDeviceExtension->BoardID == S3_NUMBER_NINE) &&
        !          1763:              (S3Modes[modeNumber].ModeInformation.VisScreenWidth == 1280) ) {
        !          1764: 
        !          1765:             SetHWMode(hwDeviceExtension, S3_928_1280_Enhanced_Mode);
        !          1766: 
        !          1767:         } else {
        !          1768: 
        !          1769:             //
        !          1770:             // Use defaults for all other boards
        !          1771:             //
        !          1772: 
        !          1773:             switch(hwDeviceExtension->ChipID) {
        !          1774: 
        !          1775:             case S3_911:
        !          1776: 
        !          1777:                 SetHWMode(hwDeviceExtension, S3_911_Enhanced_Mode);
        !          1778:                 break;
        !          1779: 
        !          1780:             case S3_801:
        !          1781: 
        !          1782:                 SetHWMode(hwDeviceExtension, S3_801_Enhanced_Mode);
        !          1783:                 break;
        !          1784: 
        !          1785:             case S3_928:
        !          1786: 
        !          1787:                 SetHWMode(hwDeviceExtension, S3_928_Enhanced_Mode);
        !          1788:                 break;
        !          1789: 
        !          1790:             default:
        !          1791: 
        !          1792:                 VideoDebugPrint((0, "S3: Bad chip type for these boards"));
        !          1793:                 break;
        !          1794:             }
        !          1795: 
        !          1796:         }
        !          1797: 
        !          1798:         //
        !          1799:         // Unlock the S3 registers,  we need to unlock the registers a second
        !          1800:         // time since the interperter has them locked when it returns to us.
        !          1801:         //
        !          1802: 
        !          1803:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x4838);
        !          1804:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0xA039);
        !          1805: 
        !          1806: #endif  // i386
        !          1807: 
        !          1808:         //
        !          1809:         // On a certain version of the DELL BIOS reg 5A was set to 0.
        !          1810:         // This will ensure that the linear address window is always set
        !          1811:         // where I expect it to be, regardless of the bios.
        !          1812:         //
        !          1813: 
        !          1814:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x0059);
        !          1815:         VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x0A5A);
        !          1816: 
        !          1817:         //
        !          1818:         // Enable the Graphics engine.
        !          1819:         //
        !          1820: 
        !          1821:         VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x40);
        !          1822:         byte = VideoPortReadPortUchar(CRT_DATA_REG);
        !          1823:         byte |= 0x01;
        !          1824:         VideoPortWritePortUchar(CRT_DATA_REG, byte);
        !          1825: 
        !          1826: #ifndef i386
        !          1827: 
        !          1828:         //
        !          1829:         // Zero the DAC and the Screen buffer memory.
        !          1830:         //
        !          1831: 
        !          1832:         ZeroMemAndDac(HwDeviceExtension);
        !          1833: #endif
        !          1834: 
        !          1835:         status = NO_ERROR;
        !          1836: 
        !          1837:         break;
        !          1838: 
        !          1839:     case IOCTL_VIDEO_SET_COLOR_REGISTERS:
        !          1840: 
        !          1841:         VideoDebugPrint((2, "S3StartIO - SetColorRegs\n"));
        !          1842: 
        !          1843:         clutBuffer = RequestPacket->InputBuffer;
        !          1844: 
        !          1845:         status = S3SetColorLookup(HwDeviceExtension,
        !          1846:                                    (PVIDEO_CLUT) RequestPacket->InputBuffer,
        !          1847:                                    RequestPacket->InputBufferLength);
        !          1848:         break;
        !          1849: 
        !          1850: 
        !          1851: #ifdef i386
        !          1852: 
        !          1853:     case IOCTL_VIDEO_RESET_DEVICE:
        !          1854: 
        !          1855:         VideoDebugPrint((2, "S3StartIO - RESET_DEVICE\n"));
        !          1856: 
        !          1857:         //
        !          1858:         // Wait for the GP to become idle,
        !          1859:         //
        !          1860: 
        !          1861:         while (VideoPortReadPortUshort(GP_STAT) & 0x0200);
        !          1862: 
        !          1863:         //
        !          1864:         // Reset the board to a default mode
        !          1865:         //
        !          1866: 
        !          1867:         SetHWMode(HwDeviceExtension, s3_set_vga_mode);
        !          1868: 
        !          1869:         VideoDebugPrint((2, "S3 RESET_DEVICE - About to do int10\n"));
        !          1870: 
        !          1871:         //
        !          1872:         // Do an Int10 to mode 3 will put the board to a known state.
        !          1873:         //
        !          1874: 
        !          1875:         VideoPortZeroMemory(&biosArguments, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
        !          1876: 
        !          1877:         biosArguments.Eax = 0x0003;
        !          1878: 
        !          1879:         VideoPortInt10(HwDeviceExtension,
        !          1880:                        &biosArguments);
        !          1881: 
        !          1882:         VideoDebugPrint((2, "S3 RESET_DEVICE - Did int10\n"));
        !          1883: 
        !          1884:         status = NO_ERROR;
        !          1885:         break;
        !          1886: 
        !          1887: #endif
        !          1888: 
        !          1889:     //
        !          1890:     // if we get here, an invalid IoControlCode was specified.
        !          1891:     //
        !          1892: 
        !          1893:     default:
        !          1894: 
        !          1895:         VideoDebugPrint((1, "Fell through S3 startIO routine - invalid command\n"));
        !          1896: 
        !          1897:         status = ERROR_INVALID_FUNCTION;
        !          1898: 
        !          1899:         break;
        !          1900: 
        !          1901:     }
        !          1902: 
        !          1903:     //
        !          1904:     // Keep a history of the commands.
        !          1905:     // This will help track down the chip being in a DOS session while
        !          1906:     // GDI and the S3 display driver "think" it's in GUI mode.
        !          1907: 
        !          1908:     gaIOControlCode[giControlCode++] = 0x00005555;
        !          1909:     giControlCode                   %= MAX_CONTROL_HISTORY;
        !          1910: 
        !          1911:     VideoDebugPrint((2, "Leaving S3 startIO routine\n"));
        !          1912: 
        !          1913:     RequestPacket->StatusBlock->Status = status;
        !          1914: 
        !          1915:     return TRUE;
        !          1916: 
        !          1917: } // end S3StartIO()
        !          1918: 
        !          1919: 
        !          1920: VP_STATUS
        !          1921: S3SetColorLookup(
        !          1922:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !          1923:     PVIDEO_CLUT ClutBuffer,
        !          1924:     ULONG ClutBufferSize
        !          1925:     )
        !          1926: 
        !          1927: /*++
        !          1928: 
        !          1929: Routine Description:
        !          1930: 
        !          1931:     This routine sets a specified portion of the color lookup table settings.
        !          1932: 
        !          1933: Arguments:
        !          1934: 
        !          1935:     HwDeviceExtension - Pointer to the miniport driver's device extension.
        !          1936: 
        !          1937:     ClutBufferSize - Length of the input buffer supplied by the user.
        !          1938: 
        !          1939:     ClutBuffer - Pointer to the structure containing the color lookup table.
        !          1940: 
        !          1941: Return Value:
        !          1942: 
        !          1943:     None.
        !          1944: 
        !          1945: --*/
        !          1946: 
        !          1947: {
        !          1948:     USHORT i;
        !          1949: 
        !          1950:     //
        !          1951:     // Check if the size of the data in the input buffer is large enough.
        !          1952:     //
        !          1953: 
        !          1954:     if ( (ClutBufferSize < sizeof(VIDEO_CLUT) - sizeof(ULONG)) ||
        !          1955:          (ClutBufferSize < sizeof(VIDEO_CLUT) +
        !          1956:                      (sizeof(ULONG) * (ClutBuffer->NumEntries - 1)) ) ) {
        !          1957: 
        !          1958:         return ERROR_INSUFFICIENT_BUFFER;
        !          1959: 
        !          1960:     }
        !          1961: 
        !          1962:     //
        !          1963:     // Check to see if the parameters are valid.
        !          1964:     //
        !          1965: 
        !          1966:     if ( (ClutBuffer->NumEntries == 0) ||
        !          1967:          (ClutBuffer->FirstEntry > VIDEO_MAX_COLOR_REGISTER) ||
        !          1968:          (ClutBuffer->FirstEntry + ClutBuffer->NumEntries >
        !          1969:                                      VIDEO_MAX_COLOR_REGISTER + 1) ) {
        !          1970: 
        !          1971:     return ERROR_INVALID_PARAMETER;
        !          1972: 
        !          1973:     }
        !          1974: 
        !          1975:     //
        !          1976:     //  Set CLUT registers directly on the hardware
        !          1977:     //
        !          1978: 
        !          1979:     for (i = 0; i < ClutBuffer->NumEntries; i++) {
        !          1980: 
        !          1981:         VideoPortWritePortUchar(DAC_ADDRESS_WRITE_PORT, (UCHAR) (ClutBuffer->FirstEntry + i));
        !          1982:         VideoPortWritePortUchar(DAC_DATA_REG_PORT, (UCHAR) (((ClutBuffer->LookupTable[i].RgbArray.Red)) >> 2));
        !          1983:         VideoPortWritePortUchar(DAC_DATA_REG_PORT, (UCHAR) (((ClutBuffer->LookupTable[i].RgbArray.Green)) >> 2));
        !          1984:         VideoPortWritePortUchar(DAC_DATA_REG_PORT, (UCHAR) (((ClutBuffer->LookupTable[i].RgbArray.Blue)) >> 2));
        !          1985: 
        !          1986:     }
        !          1987: 
        !          1988:     return NO_ERROR;
        !          1989: 
        !          1990: } // end S3SetColorLookup()
        !          1991: 
        !          1992: 
        !          1993: VOID
        !          1994: SetHWMode(
        !          1995:     PHW_DEVICE_EXTENSION HwDeviceExtension,
        !          1996:     PUSHORT pusCmdStream
        !          1997:     )
        !          1998: 
        !          1999: /*++
        !          2000: 
        !          2001: Routine Description:
        !          2002: 
        !          2003:     Interprets the appropriate command array to set up VGA registers for the
        !          2004:     requested mode. Typically used to set the VGA into a particular mode by
        !          2005:     programming all of the registers
        !          2006: 
        !          2007: Arguments:
        !          2008: 
        !          2009:     HwDeviceExtension - Pointer to the miniport driver's device extension.
        !          2010: 
        !          2011:     pusCmdStream - pointer to a command stream to execute.
        !          2012: 
        !          2013: Return Value:
        !          2014: 
        !          2015:     The status of the operation (can only fail on a bad command); TRUE for
        !          2016:     success, FALSE for failure.
        !          2017: 
        !          2018: --*/
        !          2019: 
        !          2020: {
        !          2021:     ULONG ulCmd;
        !          2022:     ULONG ulPort;
        !          2023:     UCHAR jValue;
        !          2024:     USHORT usValue;
        !          2025:     ULONG culCount;
        !          2026:     ULONG ulIndex,
        !          2027:           Microseconds;
        !          2028:     ULONG mappedAddressIndex;
        !          2029:     ULONG mappedAddressOffset;
        !          2030: 
        !          2031:     //
        !          2032:     // If there is no command string, just return
        !          2033:     //
        !          2034: 
        !          2035:     if (!pusCmdStream) {
        !          2036: 
        !          2037:         return;
        !          2038: 
        !          2039:     }
        !          2040: 
        !          2041:     while ((ulCmd = *pusCmdStream++) != EOD) {
        !          2042: 
        !          2043:         //
        !          2044:         // Determine major command type
        !          2045:         //
        !          2046: 
        !          2047:         switch (ulCmd & 0xF0) {
        !          2048: 
        !          2049:         case SELECTACCESSRANGE:
        !          2050: 
        !          2051:             //
        !          2052:             // Determine which address range to use for commands that follow
        !          2053:             //
        !          2054: 
        !          2055:             switch (ulCmd & 0x0F) {
        !          2056: 
        !          2057:             case VARIOUSVGA:
        !          2058: 
        !          2059:                 //
        !          2060:                 // Used for registers in the range 0x3c0 - 0x3cf
        !          2061:                 //
        !          2062: 
        !          2063:                 mappedAddressIndex  = 2;
        !          2064:                 mappedAddressOffset = 0x3c0;
        !          2065: 
        !          2066:                 break;
        !          2067: 
        !          2068:             case SYSTEMCONTROL:
        !          2069: 
        !          2070:                 //
        !          2071:                 // Used for registers in the range 0x3d4 - 0x3df
        !          2072:                 //
        !          2073: 
        !          2074:                 mappedAddressIndex  = 3;
        !          2075:                 mappedAddressOffset = 0x3d4;
        !          2076: 
        !          2077:                 break;
        !          2078: 
        !          2079:             case ADVANCEDFUNCTIONCONTROL:
        !          2080: 
        !          2081:                 //
        !          2082:                 // Used for registers in the range 0x4ae8-0x4ae9
        !          2083:                 //
        !          2084: 
        !          2085:                 mappedAddressIndex  = 5;
        !          2086:                 mappedAddressOffset = 0x4ae8;
        !          2087: 
        !          2088:                 break;
        !          2089: 
        !          2090:             }
        !          2091: 
        !          2092:             break;
        !          2093: 
        !          2094: 
        !          2095:         case OWM:
        !          2096: 
        !          2097:             ulPort   = *pusCmdStream++;
        !          2098:             culCount = *pusCmdStream++;
        !          2099: 
        !          2100:             while (culCount--) {
        !          2101:                 usValue = *pusCmdStream++;
        !          2102:                 VideoPortWritePortUshort((PUSHORT)((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort),
        !          2103:                                          usValue);
        !          2104:             }
        !          2105: 
        !          2106:             break;
        !          2107: 
        !          2108: 
        !          2109:         // Basic input/output command
        !          2110: 
        !          2111:         case INOUT:
        !          2112: 
        !          2113:             // Determine type of inout instruction
        !          2114:             if (!(ulCmd & IO)) {
        !          2115: 
        !          2116:                 // Out instruction
        !          2117:                 // Single or multiple outs?
        !          2118:                 if (!(ulCmd & MULTI)) {
        !          2119: 
        !          2120:                     // Single out
        !          2121:                     // Byte or word out?
        !          2122:                     if (!(ulCmd & BW)) {
        !          2123: 
        !          2124:                         // Single byte out
        !          2125:                         ulPort = *pusCmdStream++;
        !          2126:                         jValue = (UCHAR) *pusCmdStream++;
        !          2127:                         VideoPortWritePortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort,
        !          2128:                                                 jValue);
        !          2129: 
        !          2130:                     } else {
        !          2131: 
        !          2132:                         // Single word out
        !          2133:                         ulPort = *pusCmdStream++;
        !          2134:                         usValue = *pusCmdStream++;
        !          2135:                         VideoPortWritePortUshort((PUSHORT)((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort),
        !          2136:                                                 usValue);
        !          2137: 
        !          2138:                     }
        !          2139: 
        !          2140:                 } else {
        !          2141: 
        !          2142:                     // Output a string of values
        !          2143:                     // Byte or word outs?
        !          2144:                     if (!(ulCmd & BW)) {
        !          2145: 
        !          2146:                         // String byte outs. Do in a loop; can't use
        !          2147:                         // VideoPortWritePortBufferUchar because the data
        !          2148:                         // is in USHORT form
        !          2149:                         ulPort = *pusCmdStream++;
        !          2150:                         culCount = *pusCmdStream++;
        !          2151:                         while (culCount--) {
        !          2152:                             jValue = (UCHAR) *pusCmdStream++;
        !          2153:                             VideoPortWritePortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort,
        !          2154:                                                     jValue);
        !          2155: 
        !          2156:                         }
        !          2157: 
        !          2158:                     } else {
        !          2159: 
        !          2160:                         // String word outs
        !          2161:                         ulPort = *pusCmdStream++;
        !          2162:                         culCount = *pusCmdStream++;
        !          2163:                         VideoPortWritePortBufferUshort((PUSHORT)((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort),
        !          2164:                                                        pusCmdStream,
        !          2165:                                                        culCount);
        !          2166:                         pusCmdStream += culCount;
        !          2167: 
        !          2168:                     }
        !          2169:                 }
        !          2170: 
        !          2171:             } else {
        !          2172: 
        !          2173:                 // In instruction
        !          2174: 
        !          2175:                 // Currently, string in instructions aren't supported; all
        !          2176:                 // in instructions are handled as single-byte ins
        !          2177: 
        !          2178:                 // Byte or word in?
        !          2179:                 if (!(ulCmd & BW)) {
        !          2180: 
        !          2181:                     // Single byte in
        !          2182:                     ulPort = *pusCmdStream++;
        !          2183:                     jValue = VideoPortReadPortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort);
        !          2184: 
        !          2185:                 } else {
        !          2186: 
        !          2187:                     // Single word in
        !          2188:                     ulPort = *pusCmdStream++;
        !          2189:                     usValue = VideoPortReadPortUshort((PUSHORT)((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort));
        !          2190:                 }
        !          2191: 
        !          2192:             }
        !          2193: 
        !          2194:             break;
        !          2195: 
        !          2196: 
        !          2197:         // Higher-level input/output commands
        !          2198: 
        !          2199:         case METAOUT:
        !          2200: 
        !          2201:             // Determine type of metaout command, based on minor command field
        !          2202:             switch (ulCmd & 0x0F) {
        !          2203: 
        !          2204:                 // Indexed outs
        !          2205:                 case INDXOUT:
        !          2206: 
        !          2207:                     ulPort = *pusCmdStream++;
        !          2208:                     culCount = *pusCmdStream++;
        !          2209:                     ulIndex = *pusCmdStream++;
        !          2210: 
        !          2211:                     while (culCount--) {
        !          2212: 
        !          2213:                         usValue = (USHORT) (ulIndex +
        !          2214:                                   (((ULONG)(*pusCmdStream++)) << 8));
        !          2215:                         VideoPortWritePortUshort((PUSHORT)((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort),
        !          2216:                                              usValue);
        !          2217: 
        !          2218:                         ulIndex++;
        !          2219: 
        !          2220:                     }
        !          2221: 
        !          2222:                     break;
        !          2223: 
        !          2224: 
        !          2225:                 // Masked out (read, AND, XOR, write)
        !          2226:                 case MASKOUT:
        !          2227: 
        !          2228:                     ulPort = *pusCmdStream++;
        !          2229:                     jValue = VideoPortReadPortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort);
        !          2230:                     jValue &= *pusCmdStream++;
        !          2231:                     jValue ^= *pusCmdStream++;
        !          2232:                     VideoPortWritePortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort,
        !          2233:                                             jValue);
        !          2234:                     break;
        !          2235: 
        !          2236: 
        !          2237:                 // Attribute Controller out
        !          2238:                 case ATCOUT:
        !          2239: 
        !          2240:                     ulPort = *pusCmdStream++;
        !          2241:                     culCount = *pusCmdStream++;
        !          2242:                     ulIndex = *pusCmdStream++;
        !          2243: 
        !          2244:                     while (culCount--) {
        !          2245: 
        !          2246:                         // Write Attribute Controller index
        !          2247:                         VideoPortWritePortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort,
        !          2248:                                                 (UCHAR)ulIndex);
        !          2249: 
        !          2250:                         // Write Attribute Controller data
        !          2251:                         jValue = (UCHAR) *pusCmdStream++;
        !          2252:                         VideoPortWritePortUchar((PUCHAR)HwDeviceExtension->MappedAddress[mappedAddressIndex] - mappedAddressOffset + ulPort,
        !          2253:                                                 jValue);
        !          2254: 
        !          2255:                         ulIndex++;
        !          2256: 
        !          2257:                     }
        !          2258: 
        !          2259:                     break;
        !          2260: 
        !          2261:                 case DELAY:
        !          2262: 
        !          2263:                     Microseconds = (ULONG) *pusCmdStream++;
        !          2264:                     VideoPortStallExecution(Microseconds);
        !          2265: 
        !          2266:                     break;
        !          2267: 
        !          2268:                 case BT485RESET:
        !          2269: 
        !          2270:                     Reset_Bt485(HwDeviceExtension);
        !          2271: 
        !          2272:                     break;
        !          2273: 
        !          2274: #ifndef i386
        !          2275:                 case VBLANK:
        !          2276: 
        !          2277:                     Wait_VSync(HwDeviceExtension);
        !          2278: 
        !          2279:                     break;
        !          2280: 
        !          2281:                 case SETCLK:
        !          2282: 
        !          2283:                     Set_Oem_Clock(HwDeviceExtension);
        !          2284: 
        !          2285:                     break;
        !          2286: 
        !          2287:                 case SETCRTC:
        !          2288: 
        !          2289:                     //
        !          2290:                     // NOTE:
        !          2291:                     // beware: recursive call ...
        !          2292:                     //
        !          2293: 
        !          2294:                     SetHWMode(HwDeviceExtension,
        !          2295:                               S3Modes[HwDeviceExtension->ModeNumber].
        !          2296:                                   CRTCTables[HwDeviceExtension->ChipID]);
        !          2297: 
        !          2298: 
        !          2299:                     break;
        !          2300: 
        !          2301:                 case BUSTEST:
        !          2302: 
        !          2303:                     Bus_Test(HwDeviceExtension);
        !          2304: 
        !          2305:                     break;
        !          2306: #endif // i386
        !          2307: 
        !          2308:                 // None of the above; error
        !          2309:                 default:
        !          2310: 
        !          2311:                     return;
        !          2312: 
        !          2313:             }
        !          2314: 
        !          2315:             break;
        !          2316: 
        !          2317: 
        !          2318:         // NOP
        !          2319: 
        !          2320:         case NCMD:
        !          2321: 
        !          2322:             break;
        !          2323: 
        !          2324: 
        !          2325:         // Unknown command; error
        !          2326: 
        !          2327:         default:
        !          2328: 
        !          2329:             return;
        !          2330: 
        !          2331:         }
        !          2332: 
        !          2333:     }
        !          2334: 
        !          2335:     return;
        !          2336: 
        !          2337: } // end SetHWMode()
        !          2338: 
        !          2339: 
        !          2340: BOOLEAN
        !          2341: Reset_Bt485(
        !          2342:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !          2343:     )
        !          2344: 
        !          2345: /*++
        !          2346: 
        !          2347: Routine Description:
        !          2348: 
        !          2349:     This routine detects the presence of a 928 and a Bt485 and if both are
        !          2350:     found it makes sure the DAC is resets all the command registers, to make
        !          2351:     sure the DAC will function in the VGA mode.
        !          2352: 
        !          2353: Arguments:
        !          2354: 
        !          2355:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          2356: 
        !          2357: Return Value:
        !          2358: 
        !          2359:     TRUE  -
        !          2360:     FALSE -
        !          2361: 
        !          2362: --*/
        !          2363: {
        !          2364:     UCHAR OriginalReg55, Reg55;
        !          2365:     UCHAR reg38, reg39;
        !          2366: 
        !          2367:     //
        !          2368:     // This routine assumes we are dealing with an S3.
        !          2369:     // Make sure the registers are unlocked.
        !          2370:     //
        !          2371: 
        !          2372:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x38);
        !          2373:     reg38 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          2374: 
        !          2375:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x39);
        !          2376:     reg39 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          2377: 
        !          2378:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x4838);
        !          2379:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0xA039);
        !          2380: 
        !          2381:     //
        !          2382:     // First make sure this is a 928.
        !          2383:     //
        !          2384: 
        !          2385:     if (HwDeviceExtension->ChipID != S3_928) {
        !          2386: 
        !          2387:         return FALSE;
        !          2388: 
        !          2389:     }
        !          2390: 
        !          2391:     //
        !          2392:     // It's a 928 so now we have to make sure this is Bt485
        !          2393:     //
        !          2394: 
        !          2395:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x55);
        !          2396:     OriginalReg55 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          2397:     OriginalReg55 &= ~0x03;
        !          2398: 
        !          2399:     //
        !          2400:     // BUGBUG
        !          2401:     // The ID for the BT485 did not work on all DACs so I'll switch off the
        !          2402:     // resolution.
        !          2403:     // This ID changed between the prototype chips and the release component,
        !          2404:     // at the time of this release there are too many prototype chips in the
        !          2405:     // field to rely on this ID.
        !          2406:     //
        !          2407: 
        !          2408:     if (S3Modes[HwDeviceExtension->ModeNumber].ModeInformation.VisScreenWidth
        !          2409:         != 1280) {
        !          2410: 
        !          2411:         return FALSE;
        !          2412: 
        !          2413:     }
        !          2414: 
        !          2415:     //
        !          2416:     // We know the board uses a Bt485 DAC.
        !          2417:     //
        !          2418: 
        !          2419:     //
        !          2420:     // Zero out Command register 3.
        !          2421:     //
        !          2422: 
        !          2423:     Reg55 = OriginalReg55 | 0x01;
        !          2424:     VideoPortWritePortUchar(CRT_DATA_REG, Reg55);
        !          2425:     VideoPortWritePortUchar((PUCHAR) 0x3C6, 0x80);
        !          2426: 
        !          2427:     Reg55 = OriginalReg55;
        !          2428:     VideoPortWritePortUchar(CRT_DATA_REG, Reg55);
        !          2429:     VideoPortWritePortUchar((PUCHAR) 0x3C8, 0x01);
        !          2430: 
        !          2431:     Reg55 = OriginalReg55 | 0x02;
        !          2432:     VideoPortWritePortUchar(CRT_DATA_REG, Reg55);
        !          2433:     VideoPortWritePortUchar((PUCHAR) 0x3C6, 0x00);
        !          2434: 
        !          2435:     //
        !          2436:     // Now zero out command register 2, 1, & 0
        !          2437:     //
        !          2438: 
        !          2439:     VideoPortWritePortUchar((PUCHAR) 0x3C9, 0x00);
        !          2440:     VideoPortWritePortUchar((PUCHAR) 0x3C8, 0x00);
        !          2441: 
        !          2442:     Reg55 = OriginalReg55 | 0x01;
        !          2443:     VideoPortWritePortUchar(CRT_DATA_REG, Reg55);
        !          2444:     VideoPortWritePortUchar((PUCHAR) 0x3C6, 0x00);
        !          2445: 
        !          2446:     //
        !          2447:     // Now set the extended DAC control back to it's original val.
        !          2448:     //
        !          2449: 
        !          2450:     VideoPortWritePortUchar(CRT_DATA_REG, OriginalReg55);
        !          2451: 
        !          2452:     //
        !          2453:     // Were done mucking about with the S3 chip, so lock all the registers.
        !          2454:     //
        !          2455: 
        !          2456:     VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg38 << 8) | 0x38));
        !          2457:     VideoPortWritePortUshort(CRT_ADDRESS_REG, (USHORT)(((USHORT) reg39 << 8) | 0x39));
        !          2458: 
        !          2459:     return TRUE;
        !          2460: 
        !          2461: }
        !          2462: 
        !          2463: #ifndef i386
        !          2464: 
        !          2465: 
        !          2466: VOID
        !          2467: ZeroMemAndDac(
        !          2468:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !          2469:     )
        !          2470: 
        !          2471: /*++
        !          2472: 
        !          2473: Routine Description:
        !          2474: 
        !          2475:     Initialize the DAC to 0 (black).
        !          2476: 
        !          2477: Arguments:
        !          2478: 
        !          2479:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          2480: 
        !          2481: Return Value:
        !          2482: 
        !          2483:     None
        !          2484: 
        !          2485: --*/
        !          2486: 
        !          2487: {
        !          2488:     ULONG i;
        !          2489:     USHORT Cmd;
        !          2490: 
        !          2491:     //
        !          2492:     // Turn off the screen at the DAC.
        !          2493:     //
        !          2494: 
        !          2495:     VideoPortWritePortUchar(DAC_PIXEL_MASK_REG, 0x0);
        !          2496: 
        !          2497:     for (i = 0; i < 256; i++) {
        !          2498: 
        !          2499:         VideoPortWritePortUchar(DAC_ADDRESS_WRITE_PORT, (UCHAR)i);
        !          2500:         VideoPortWritePortUchar(DAC_DATA_REG_PORT, 0x0);
        !          2501:         VideoPortWritePortUchar(DAC_DATA_REG_PORT, 0x0);
        !          2502:         VideoPortWritePortUchar(DAC_DATA_REG_PORT, 0x0);
        !          2503: 
        !          2504:     }
        !          2505: 
        !          2506:     //
        !          2507:     // Zero the memory.
        !          2508:     //
        !          2509:     // First open up the clipping.
        !          2510:     //
        !          2511: 
        !          2512:     FIFOWAIT(FIFO_4_EMPTY);
        !          2513: 
        !          2514:     VideoPortWritePortUshort (MULTIFUNC_CNTL, (CLIP_TOP    | 0));
        !          2515:     VideoPortWritePortUshort (MULTIFUNC_CNTL, (CLIP_LEFT   | 0));
        !          2516:     VideoPortWritePortUshort (MULTIFUNC_CNTL, (CLIP_BOTTOM | S3BM_HEIGHT));
        !          2517:     VideoPortWritePortUshort (MULTIFUNC_CNTL, (CLIP_RIGHT  | S3BM_WIDTH));
        !          2518: 
        !          2519:     //
        !          2520:     // Now do the blit.
        !          2521:     //
        !          2522:     // Zero out coprocessor memory for the masks, color data,
        !          2523:     // and the save area.
        !          2524:     //
        !          2525: 
        !          2526:     Cmd = RECTANGLE_FILL |
        !          2527:           DRAW           | DRAWING_DIR_TBLRXM | DIR_TYPE_XY |
        !          2528:           LAST_PIXEL_ON  | SINGLE_PIXEL       | WRITE;
        !          2529: 
        !          2530:     FIFOWAIT(FIFO_3_EMPTY);
        !          2531: 
        !          2532:     VideoPortWritePortUshort(FRGD_MIX, LOGICAL_0);
        !          2533:     VideoPortWritePortUshort(WRT_MASK, 0xff);
        !          2534:     VideoPortWritePortUshort(MULTIFUNC_CNTL, (DATA_EXTENSION | ALL_ONES));
        !          2535: 
        !          2536:     FIFOWAIT(FIFO_5_EMPTY);
        !          2537: 
        !          2538:     VideoPortWritePortUshort(CUR_X, 0);
        !          2539:     VideoPortWritePortUshort(CUR_Y, 0);
        !          2540:     VideoPortWritePortUshort(RECT_WIDTH, S3BM_WIDTH - 1);
        !          2541:     VideoPortWritePortUshort(MULTIFUNC_CNTL, (RECT_HEIGHT | S3BM_HEIGHT - 1));
        !          2542:     VideoPortWritePortUshort(CMD, Cmd);
        !          2543: 
        !          2544:     //
        !          2545:     // Turn on the screen at the DAC
        !          2546:     //
        !          2547: 
        !          2548:     VideoPortWritePortUchar(DAC_PIXEL_MASK_REG, 0x0ff);
        !          2549: 
        !          2550:     return;
        !          2551: 
        !          2552: }
        !          2553: 
        !          2554: VP_STATUS
        !          2555: Set_Oem_Clock(
        !          2556:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !          2557:     )
        !          2558: 
        !          2559: /*++
        !          2560: 
        !          2561: Routine Description:
        !          2562: 
        !          2563:     Set the clock chip on each of the supported cards.
        !          2564: 
        !          2565: Arguments:
        !          2566: 
        !          2567:     HwDeviceExtension - Pointer to the miniport driver's device extension.
        !          2568: 
        !          2569: Return Value:
        !          2570: 
        !          2571:     Always TRUE
        !          2572: 
        !          2573: --*/
        !          2574: 
        !          2575: {
        !          2576:     ULONG ul;
        !          2577:     ULONG clock_numbers;
        !          2578: 
        !          2579:     switch(HwDeviceExtension->BoardID) {
        !          2580: 
        !          2581:     case S3_NUMBER_NINE:
        !          2582: 
        !          2583:         VideoPortStallExecution(1000);
        !          2584: 
        !          2585:         // Jerry said to make the M clock not multiple of the P clock
        !          2586:         // on the 3 meg (level 12) board.  This solves the shimmy
        !          2587:         // problem.
        !          2588: 
        !          2589:         if (HwDeviceExtension->AdapterMemorySize == 0x00300000) {
        !          2590: 
        !          2591:             ul = 49000000;
        !          2592:             clock_numbers = calc_clock(ul, 3);
        !          2593:             set_clock(HwDeviceExtension, clock_numbers);
        !          2594:             VideoPortStallExecution(3000);
        !          2595: 
        !          2596:         }
        !          2597: 
        !          2598:         ul = aulNumberNineClk[HwDeviceExtension->ModeNumber];
        !          2599:         clock_numbers = calc_clock(ul, 2);
        !          2600:         set_clock(HwDeviceExtension, clock_numbers);
        !          2601: 
        !          2602:         VideoPortStallExecution(3000);
        !          2603: 
        !          2604:         break;
        !          2605: 
        !          2606:     case S3_ORCHID:
        !          2607: 
        !          2608:         //
        !          2609:         // Only the 911 Orchid board needs specific init parameters.
        !          2610:         // Otherwise, fall through the generic function.
        !          2611:         //
        !          2612: 
        !          2613:         if (HwDeviceExtension->ChipID == S3_911) {
        !          2614: 
        !          2615:             ul = aulOrchidClk[HwDeviceExtension->ModeNumber];
        !          2616:             VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x42);
        !          2617:             VideoPortWritePortUchar(CRT_DATA_REG, (UCHAR) ul);
        !          2618: 
        !          2619:             break;
        !          2620: 
        !          2621:         }
        !          2622: 
        !          2623:         //
        !          2624:         // Genric S3 board.
        !          2625:         //
        !          2626: 
        !          2627:     case S3_GENERIC:
        !          2628:     default:
        !          2629: 
        !          2630:         ul = aulGenericClk[HwDeviceExtension->ModeNumber];
        !          2631:         VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x42);
        !          2632:         VideoPortWritePortUchar(CRT_DATA_REG, (UCHAR) ul);
        !          2633:         break;
        !          2634: 
        !          2635:     }
        !          2636: 
        !          2637:     return TRUE;
        !          2638: }
        !          2639: 
        !          2640: 
        !          2641: VP_STATUS
        !          2642: Wait_VSync(
        !          2643:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !          2644:     )
        !          2645: 
        !          2646: /*++
        !          2647: 
        !          2648: Routine Description:
        !          2649: 
        !          2650:     Wait for the vertical blanking interval on the chip
        !          2651: 
        !          2652: Arguments:
        !          2653: 
        !          2654:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          2655: 
        !          2656: Return Value:
        !          2657: 
        !          2658:     Always TRUE
        !          2659: 
        !          2660: --*/
        !          2661: 
        !          2662: {
        !          2663: 
        !          2664:     ULONG i;
        !          2665:     UCHAR byte;
        !          2666: 
        !          2667:     // It's real possible that this routine will get called
        !          2668:     // when the 911 is in a zombie state, meaning there is no
        !          2669:     // vertical sync being generated.  This is why we have some long
        !          2670:     // time out loops here.
        !          2671:     // !!! What is the correct NT way to do this type of time out?
        !          2672: 
        !          2673:     // First wait for getting into vertical blanking.
        !          2674: 
        !          2675:     for (i = 0; i < 0x100000; i++) {
        !          2676: 
        !          2677:         byte = VideoPortReadPortUchar(SYSTEM_CONTROL_REG);
        !          2678:         if (byte & 0x08)
        !          2679:             break;
        !          2680: 
        !          2681:     }
        !          2682: 
        !          2683:     //
        !          2684:     // We are either in a vertical blaning interval or we have timmed out.
        !          2685:     // Wait for the Vertical display interval.
        !          2686:     // This is done to make sure we exit this routine at the beginning
        !          2687:     // of a vertical blanking interval, and not in the middle or near
        !          2688:     // the end of one.
        !          2689:     //
        !          2690: 
        !          2691:     for (i = 0; i < 0x100000; i++) {
        !          2692: 
        !          2693:         byte = VideoPortReadPortUchar(SYSTEM_CONTROL_REG);
        !          2694:         if (!(byte & 0x08))
        !          2695:             break;
        !          2696: 
        !          2697:     }
        !          2698: 
        !          2699:     //
        !          2700:     // Now wait to get into the vertical blank interval again.
        !          2701:     //
        !          2702: 
        !          2703:     for (i = 0; i < 0x100000; i++) {
        !          2704: 
        !          2705:         byte = VideoPortReadPortUchar(SYSTEM_CONTROL_REG);
        !          2706:         if (byte & 0x08)
        !          2707:             break;
        !          2708: 
        !          2709:     }
        !          2710: 
        !          2711:     return (TRUE);
        !          2712: 
        !          2713: }
        !          2714: 
        !          2715: BOOLEAN
        !          2716: Bus_Test(
        !          2717:     PHW_DEVICE_EXTENSION HwDeviceExtension
        !          2718:     )
        !          2719: 
        !          2720: /*++
        !          2721: 
        !          2722: Routine Description:
        !          2723: 
        !          2724:     Test the bus to determine in the ISA address latch needs to be
        !          2725:     enabled.
        !          2726: 
        !          2727: Arguments:
        !          2728: 
        !          2729:     HwDeviceExtension - Supplies a pointer to the miniport's device extension.
        !          2730: 
        !          2731: Return Value:
        !          2732: 
        !          2733:     TRUE - need to Enable the ISA Address Latch.
        !          2734:            And it is enabled when we return.
        !          2735: 
        !          2736:     FALSE - do not enable the ISA Address Latch.
        !          2737:             And it's disabled when we return.
        !          2738: 
        !          2739:     NOTE: The test #9 gave me; to set the ISA Address Latch,
        !          2740:           then do the test failed on a DELL 50Mhz machine
        !          2741:           Now, we'll try resetting the ISA Address Latch.
        !          2742:           The reset of the latch bit passed on the DELL, but failed on
        !          2743:           the OPTI chip set.  Now I'll change the test to writting
        !          2744:           a pattern to the entire Video Memory and try to read it back,
        !          2745:           with a default state of the ISA latch bit being reset.
        !          2746: 
        !          2747:           3/26/93
        !          2748: 
        !          2749:           This routine does not seem to necessary with the later versions of the BIOS.
        !          2750:           The new Number Nine BIOS seems to detect the need to set or reset the ISA address
        !          2751:           latch.  AT this point I will leave it in to cover all the older #9 boards in
        !          2752:           the field.
        !          2753: --*/
        !          2754: {
        !          2755: 
        !          2756: 
        !          2757:     UCHAR reg35, reg51, reg58, reg59, reg5a;
        !          2758:     UCHAR *pRamAddr;
        !          2759:     PHYSICAL_ADDRESS memoryAddress;
        !          2760: 
        !          2761:     volatile ULONG *pulRamAddr;
        !          2762: 
        !          2763:     LONG i;
        !          2764:     LONG iBank;
        !          2765:     LONG nBanks;
        !          2766: 
        !          2767:     ULONG ulTestPat;
        !          2768: 
        !          2769:     BOOLEAN bEnbLa;
        !          2770: 
        !          2771:     //
        !          2772:     // Note: this routine assumes the S3 registers are unlocked
        !          2773:     //             when it is called.
        !          2774:     //
        !          2775:     // Map in 64K of VRAM address space at 0xA000:0
        !          2776:     //
        !          2777: 
        !          2778:     memoryAddress.HighPart = 0;
        !          2779:     memoryAddress.LowPart  = 0xA0000;
        !          2780: 
        !          2781:     pRamAddr = VideoPortGetDeviceBase(HwDeviceExtension,
        !          2782:                                       memoryAddress,
        !          2783:                                       0x10000,
        !          2784:                                       0);
        !          2785: 
        !          2786:     //
        !          2787:     // Wait for the GP to be idle
        !          2788:     //
        !          2789: 
        !          2790:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x40);
        !          2791: 
        !          2792:     if (VideoPortReadPortUchar(CRT_DATA_REG) & 0x1) {
        !          2793: 
        !          2794:         while (VideoPortReadPortUshort(GP_STAT) & 0x0200);
        !          2795: 
        !          2796:     }
        !          2797: 
        !          2798:     //
        !          2799:     // Get the original values for all the registers.
        !          2800:     // So we can restore them before we leave the driver.
        !          2801:     //
        !          2802: 
        !          2803:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x35);
        !          2804:     reg35 = VideoPortReadPortUchar(CRT_DATA_REG) & 0xF0;
        !          2805: 
        !          2806:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x51);
        !          2807:     reg51 = VideoPortReadPortUchar(CRT_DATA_REG) & ~0x0C;
        !          2808: 
        !          2809:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x58);
        !          2810:     reg58 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          2811: 
        !          2812:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x59);
        !          2813:     reg59 = VideoPortReadPortUchar(CRT_DATA_REG);
        !          2814: 
        !          2815:     VideoPortWritePortUchar(CRT_ADDRESS_REG, 0x5A);
        !          2816:     reg5a = VideoPortReadPortUchar(CRT_DATA_REG);
        !          2817: 
        !          2818:     //
        !          2819:     // Set the Linear Address Window to A0000.
        !          2820:     //
        !          2821: 
        !          2822:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x0059);
        !          2823:     VideoPortWritePortUshort(CRT_ADDRESS_REG, 0x0a5a);
        !          2824: 
        !          2825:     //
        !          2826:     // Do the test for enabling the ISA address latch feature on the chip.
        !          2827:     //
        !          2828: 
        !          2829:     bEnbLa = FALSE;
        !          2830: 
        !          2831:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg58 & ~0x08) | 0x10) << 8) | 0x58)));
        !          2832: 
        !          2833:     //
        !          2834:     // Write out the test pattern to the Video memory.
        !          2835:     // This is a dword write.
        !          2836:     //
        !          2837: 
        !          2838:     ulTestPat = 0x55AA6699;
        !          2839:     pulRamAddr= (ULONG *) pRamAddr;
        !          2840: 
        !          2841:     nBanks = HwDeviceExtension->AdapterMemorySize >> 16;
        !          2842: 
        !          2843:     for (iBank = 0; iBank < nBanks; iBank++) {
        !          2844: 
        !          2845:         //
        !          2846:         // Set the bank address.
        !          2847:         //
        !          2848: 
        !          2849:         VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg51 | ((0x30 & iBank) << 6)) << 8) | 0x51))));
        !          2850:         VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg35 | (0x0F & iBank)) << 8) | 0x35))));
        !          2851: 
        !          2852:         //
        !          2853:         // Write 64K of pattern.
        !          2854:         //
        !          2855: 
        !          2856:         for (i = 0; i < 0x1000; i++) {
        !          2857: 
        !          2858:             pulRamAddr[i] = ulTestPat;
        !          2859:         }
        !          2860: 
        !          2861:     }
        !          2862: 
        !          2863:     //
        !          2864:     // Write 64 of Zeros to the first bank, this should take care of bus
        !          2865:     // float.
        !          2866:     //
        !          2867: 
        !          2868:     iBank = 0;
        !          2869: 
        !          2870:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg51 | ((0x30 & iBank) << 6)) << 8) | 0x51))));
        !          2871:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg35 | (0x0F & iBank)) << 8) | 0x35))));
        !          2872: 
        !          2873:     //
        !          2874:     // Write 64K of 0.
        !          2875:     //
        !          2876: 
        !          2877:     for (i = 0; i < 0x1000; i++) {
        !          2878: 
        !          2879:         pulRamAddr[i] = 0;
        !          2880:     }
        !          2881: 
        !          2882:     //
        !          2883:     // Now read back the pattern.
        !          2884:     // If the data is different at any point then the ISA latch addr.
        !          2885:     // should be enabled.
        !          2886:     //
        !          2887: 
        !          2888:     for (iBank = 1; iBank < nBanks; iBank++) {
        !          2889: 
        !          2890:         //
        !          2891:         // Set the bank address.
        !          2892:         //
        !          2893: 
        !          2894:         VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg51 | ((0x30 & iBank) << 6)) << 8) | 0x51))));
        !          2895:         VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)((((reg35 | (0x0F & iBank)) << 8) | 0x35))));
        !          2896: 
        !          2897:         //
        !          2898:         // Set the address for the beginning of this bank.
        !          2899:         //
        !          2900: 
        !          2901:         pulRamAddr= (ULONG *) pRamAddr;
        !          2902: 
        !          2903:         for (i = 0; i < 0x1000; i++) {
        !          2904: 
        !          2905:             if (pulRamAddr[i] != ulTestPat) {
        !          2906: 
        !          2907:                 bEnbLa = TRUE;
        !          2908:                 break;
        !          2909: 
        !          2910:             }
        !          2911:         }
        !          2912: 
        !          2913:         if (bEnbLa == TRUE) {
        !          2914: 
        !          2915:             break;
        !          2916: 
        !          2917:         }
        !          2918:     }
        !          2919: 
        !          2920:     //
        !          2921:     // Set register 5A, this includes the ISA address latch.
        !          2922:     //
        !          2923: 
        !          2924:     if (bEnbLa == TRUE) {
        !          2925: 
        !          2926:         VideoPortWritePortUshort(CRT_ADDRESS_REG,
        !          2927:                                  ((USHORT)(((reg58 | 0x8) << 8) | 0x58)));
        !          2928: 
        !          2929:     } else {
        !          2930: 
        !          2931:         VideoPortWritePortUshort(CRT_ADDRESS_REG,
        !          2932:                                  ((USHORT)(((reg58 & ~0x8) << 8) | 0x58)));
        !          2933: 
        !          2934:     }
        !          2935: 
        !          2936:     //
        !          2937:     // Restore the registers we used to test memory.
        !          2938:     //
        !          2939: 
        !          2940:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)(((USHORT) reg35 << 8) | 0x35)));
        !          2941:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)(((USHORT) reg51 << 8) | 0x51)));
        !          2942:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)(((USHORT) reg59 << 8) | 0x59)));
        !          2943:     VideoPortWritePortUshort(CRT_ADDRESS_REG, ((USHORT)(((USHORT) reg5a << 8) | 0x5A)));
        !          2944: 
        !          2945:     //
        !          2946:     // Free the memory mapping we used for the RAM access
        !          2947:     //
        !          2948: 
        !          2949:     VideoPortFreeDeviceBase(HwDeviceExtension, pRamAddr);
        !          2950: 
        !          2951:     //
        !          2952:     // return the results.
        !          2953:     //
        !          2954: 
        !          2955:     return bEnbLa;
        !          2956: 
        !          2957: }
        !          2958: 
        !          2959: #endif // i386

unix.superglobalmegacorp.com

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