/************************************************************************/
/*                                                                      */
/*                              INIT_M.C                                */
/*                                                                      */
/*        Sep 27  1993 (c) 1993, ATI Technologies Incorporated.         */
/************************************************************************/

/**********************       PolyTron RCS Utilities

  $Revision:   1.16  $
      $Date:   15 May 1996 16:35:42  $
	$Author:   RWolff  $
	   $Log:   S:/source/wnt/ms11/miniport/archive/init_m.c_v  $
 *
 *    Rev 1.16   15 May 1996 16:35:42   RWolff
 * Waits for idle after setting accelerator mode.
 *
 *    Rev 1.15   17 Apr 1996 13:09:26   RWolff
 * Backed out Alpha LFB mapping as dense.
 *
 *    Rev 1.14   11 Apr 1996 15:12:40   RWolff
 * Now maps framebuffer as dense on DEC Alpha with PCI graphics card.
 *
 *    Rev 1.13   31 Mar 1995 11:53:46   RWOLFF
 * Changed from all-or-nothing debug print statements to thresholds
 * depending on importance of the message.
 *
 *    Rev 1.12   14 Feb 1995 15:41:20   RWOLFF
 * Changed conditional compile that uses or fakes failure of
 * VideoPortMapBankedMemory() to look for IOCTL_VIDEO_SHARE_VIDEO_MEMORY
 * instead of the routine itself. Looking for the routine always failed,
 * and since the routine is supplied in order to allow DCI to be used
 * on systems without a linear framebuffer, it should be available on
 * any DDK version that supports the IOCTL. If it isn't, a compile-time
 * error will be generated (unresolved external reference).
 *
 *    Rev 1.11   03 Feb 1995 15:17:00   RWOLFF
 * Added support for DCI, removed dead code.
 *
 *    Rev 1.10   23 Dec 1994 10:47:18   ASHANMUG
 * ALPHA/Chrontel-DAC
 *
 *    Rev 1.9   22 Jul 1994 17:48:50   RWOLFF
 * Merged with Richard's non-x86 code stream.
 *
 *    Rev 1.8   27 Jun 1994 16:30:12   RWOLFF
 * Now reports all hardware default mode tables as noninterlaced to
 * avoid confusing the display applet.
 *
 *    Rev 1.7   15 Jun 1994 11:07:08   RWOLFF
 * Now uses VideoPortZeroDeviceMemory() to clear 24BPP screens on NT builds
 * where this function is available.
 *
 *    Rev 1.6   12 May 1994 11:05:32   RWOLFF
 * Reports the refresh rate from the mode table, rather than always
 * reporting "Use hardware default".
 *
 *    Rev 1.5   31 Mar 1994 15:02:00   RWOLFF
 * Added SetPowerManagement_m() function to implement DPMS handling.
 *
 *    Rev 1.4   14 Mar 1994 16:31:36   RWOLFF
 * XMillimeter field of mode information structure now set properly.
 *
 *    Rev 1.3   03 Mar 1994 12:37:54   ASHANMUG
 * Pageable
 *
 *    Rev 1.1   31 Jan 1994 16:27:06   RWOLFF
 * Now fills in Frequency and VideoMemoryBitmap[Width|Height] fields of
 * mode information structure. Sets Number[Red|Green|Blue]Bits fields
 * for palette modes to 6 (assumes VGA-compatible DAC) instead of 0
 * to allow Windows NT to set the palette colours to the best match
 * for the colours to be displayed.
 *
 *    Rev 1.0   31 Jan 1994 11:10:40   RWOLFF
 * Initial revision.
 *
 *    Rev 1.6   24 Jan 1994 18:04:28   RWOLFF
 * Now puts DAC in known state before setting video mode. This is to
 * accomodate the Graphics Wonder (1M DRAM Mach 32 with BT48x DAC).
 *
 *    Rev 1.5   14 Jan 1994 15:21:22   RWOLFF
 * SetCurrentMode_m() and (new routine) ResetDevice_m() now initialize
 * and deinitialize the bank manager.
 *
 *    Rev 1.4   15 Dec 1993 15:26:48   RWOLFF
 * Added note to clean up before sending to Microsoft.
 *
 *    Rev 1.3   30 Nov 1993 18:16:34   RWOLFF
 * MapVideoMemory_m() now sets memoryInformation->FrameBufferLength to
 * aperture size rather than amount of video memory present.
 *
 *    Rev 1.2   05 Nov 1993 13:25:24   RWOLFF
 * Switched to defined values for memory type, 1280x1024 DAC initialization is
 * now done in the same manner as for other resolutions.
 *
 *    Rev 1.0   08 Oct 1993 11:20:34   RWOLFF
 * Initial revision.

End of PolyTron RCS section                             *****************/

#ifdef DOC
INIT_M.C - Highest-level card-dependent routines for miniport.

DESCRIPTION
    This file contains initialization and packet handling routines
    for 8514/A-compatible ATI accelerators. Routines in this module
    are called only by routines in ATIMP.C, which is card-independent.

OTHER FILES

#endif

#include "dderror.h"

#include "miniport.h"
#include "ntddvdeo.h"
#include "video.h"

#include "stdtyp.h"
#include "amach.h"
#include "amach1.h"
#include "atimp.h"
#include "atint.h"

#define INCLUDE_INIT_M
#include "init_m.h"
#include "modes_m.h"
#include "services.h"
#include "setup_m.h"


/*
 * Prototypes for static functions.
 */
static void QuerySingleMode_m(PVIDEO_MODE_INFORMATION ModeInformation, struct query_structure *QueryPtr, ULONG ModeIndex);


/*
 * Allow miniport to be swapped out when not needed.
 */
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(PAGE_M, AlphaInit_m)
#pragma alloc_text(PAGE_M, Initialize_m)
#pragma alloc_text(PAGE_M, MapVideoMemory_m)
#pragma alloc_text(PAGE_M, QueryPublicAccessRanges_m)
#pragma alloc_text(PAGE_M, QueryCurrentMode_m)
#pragma alloc_text(PAGE_M, QueryAvailModes_m)
#pragma alloc_text(PAGE_M, QuerySingleMode_m)
#pragma alloc_text(PAGE_M, SetCurrentMode_m)
#pragma alloc_text(PAGE_M, ResetDevice_m)
#pragma alloc_text(PAGE_M, SetPowerManagement_m)
#pragma alloc_text(PAGE_M, ShareVideoMemory_m)
/* BankMap_m() can't be made pageable */
#endif



/***************************************************************************
 *
 * void AlphaInit_m(void);
 *
 * DESCRIPTION:
 *  Perform the initialization that would normally be done by the ROM
 *  BIOS on x86 machines.
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  ATIMPFindAdapter()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

void AlphaInit_m(void)
{
    OUTPW(MEM_CFG, 0);
    DEC_DELAY
    OUTPW(MISC_OPTIONS, 0xb0a9);
    DEC_DELAY
    OUTPW(MEM_BNDRY, 0);
    DEC_DELAY
#if 0
    OUTPW(CONFIG_STATUS_1, 0x1410);
    DEC_DELAY
    OUTPW(SCRATCH_PAD_1, 0);
    DEC_DELAY
    OUTPW(SCRATCH_PAD_0, 0);
    DEC_DELAY
#endif
    OUTPW(CLOCK_SEL, 0x250);
    DEC_DELAY
    OUTPW(DAC_W_INDEX, 0x40);
    DEC_DELAY
    OUTPW(MISC_CNTL, 0xC00);
    DEC_DELAY
    OUTPW(LOCAL_CONTROL, 0x1402);
#if defined (MIPS) || defined (_MIPS_)
    DEC_DELAY
    OUTPW(OVERSCAN_COLOR_8, 0);    //RKE: to eliminate left overscan on MIPS
#endif
    DEC_DELAY

    return;

}   /* AlphaInit_m() */



/***************************************************************************
 *
 * void Initialize_m(void);
 *
 * DESCRIPTION:
 *  This routine is the 8514/A-compatible hardware initialization routine
 *  for the miniport driver. It is called once an adapter has been found
 *  and all the required data structures for it have been created.
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  ATIMPInitialize()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

void Initialize_m(void)
{
    /*
     * Make sure we have enough available FIFO entries
     * to initialize the card.
     */
    CheckFIFOSpace_m(SIXTEEN_WORDS);

    /*
     * On the 68800, set the memory boundary to shared VGA memory.
     * On all cards, set the screen and drawing engine to start
     * at the beginning of accelerator memory and MEM_CNTL
     * to linear.
     */
    if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
        OUTP (MEM_BNDRY,0);

    OUTPW(CRT_OFFSET_LO, 0);
    OUTPW(GE_OFFSET_LO,  0);
    OUTPW(CRT_OFFSET_HI, 0);
    OUTPW(GE_OFFSET_HI,  0);
    OUTPW(MEM_CNTL,0x5006);

    /*
     * Reset the engine and FIFO, then return to normal operation.
     */
    OUTPW(SUBSYS_CNTL,0x9000);
    OUTPW(SUBSYS_CNTL,0x5000);

    /*
     * The hardware cursor is available only for Mach 32 cards.
     * disable the cursor and initialize it to display quadrant I - 0
     */
    if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
        {
        OUTPW(CURSOR_OFFSET_HI,0);

        OUTPW(HORZ_CURSOR_OFFSET,0);
        OUTP(VERT_CURSOR_OFFSET,0);
        OUTPW(CURSOR_COLOR_0, 0x0FF00);         /* Colour 0 black, colour 1 white */
        OUTPW(EXT_CURSOR_COLOR_0,0);	// black
        OUTPW(EXT_CURSOR_COLOR_1,0xffff);	// white
        }

    return;

}   /* Initialize_m() */


/**************************************************************************
 *
 * VP_STATUS MapVideoMemory_m(RequestPacket, QueryPtr);
 *
 * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
 * struct query_structure *QueryPtr;    Query information for the card
 *
 * DESCRIPTION:
 *  Map the card's video memory into system memory and store the mapped
 *  address and size in OutputBuffer.
 *
 * RETURN VALUE:
 *  NO_ERROR if successful
 *  error code if failed
 *
 * GLOBALS CHANGED:
 *  FrameLength and PhysicalFrameAddress fields of phwDeviceExtension
 *  if Mach 32 card without linear framebuffer.
 *
 * CALLED BY:
 *  IOCTL_VIDEO_MAP_VIDEO_MEMORY packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

VP_STATUS MapVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
{
    PVIDEO_MEMORY_INFORMATION memoryInformation;
    ULONG inIoSpace;        /* Scratch variable used by VideoPortMapMemory() */
    VP_STATUS status;       /* Error code obtained from O/S calls */

    memoryInformation = RequestPacket->OutputBuffer;

    memoryInformation->VideoRamBase = ((PVIDEO_MEMORY)
        (RequestPacket->InputBuffer))->RequestedVirtualAddress;

    /*
     * The VideoRamLength field contains the amount of video memory
     * on the card. The FrameBufferLength field contains the
     * size of the aperture in bytes
     *
     * Initially assume that the linear aperture is available.
     * For our 8514/A-compatible cards, we always enable a 4M aperture
     * if the LFB is available, so map the full 4M even if the
     * aperture size is greater than the amount of video memory.
     */
    memoryInformation->VideoRamLength    = phwDeviceExtension->VideoRamSize;
    memoryInformation->FrameBufferLength = 4 * ONE_MEG;

    /*
     * If the linear aperture is not available (==0), and we are
     * dealing with a card which can use the VGA 64k aperture,
     * map it in.
     */
    if (QueryPtr->q_aperture_cfg == 0)
        {
        if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
            (QueryPtr->q_VGA_type == 1))
            {
            phwDeviceExtension->FrameLength = 0x10000;
            phwDeviceExtension->PhysicalFrameAddress.LowPart = 0x0A0000;
            memoryInformation->FrameBufferLength = phwDeviceExtension->FrameLength;
            }
        else{
            /*
             * This card can't use either linear or VGA aperture.
             * Set frame buffer size to zero and return.
             */
            memoryInformation->VideoRamBase      = 0;
            memoryInformation->FrameBufferLength = 0;
            memoryInformation->FrameBufferBase   = 0;
            return NO_ERROR;
            }
        }
    inIoSpace = 0;
#if 0   /* defined(ALPHA) if display driver can handle dense LFB */
    if (QueryPtr->q_bus_type == BUS_PCI)
        inIoSpace = 4;
#endif

    status = VideoPortMapMemory(phwDeviceExtension,
                    	        phwDeviceExtension->PhysicalFrameAddress,
                                &(memoryInformation->FrameBufferLength),
                                &inIoSpace,
                                &(memoryInformation->VideoRamBase));

    memoryInformation->FrameBufferBase    = memoryInformation->VideoRamBase;

    return status;

}   /* MapVideoMemory_m() */


/**************************************************************************
 *
 * VP_STATUS QueryPublicAccessRanges_m(RequestPacket);
 *
 * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
 *
 * DESCRIPTION:
 *  Map and return information on the video card's public access ranges.
 *
 * RETURN VALUE:
 *  NO_ERROR if successful
 *  error code if failed
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  IOCTL_VIDEO_QUERY_PUBLIC_ACCESS_RANGES packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

VP_STATUS QueryPublicAccessRanges_m(PVIDEO_REQUEST_PACKET RequestPacket)
{
    PVIDEO_PUBLIC_ACCESS_RANGES portAccess;
    PHYSICAL_ADDRESS physicalPortBase;
    ULONG physicalPortLength;

    if ( RequestPacket->OutputBufferLength <
        (RequestPacket->StatusBlock->Information =
        sizeof(VIDEO_PUBLIC_ACCESS_RANGES)) )
        {
        return ERROR_INSUFFICIENT_BUFFER;
        }

    portAccess = RequestPacket->OutputBuffer;
	
    portAccess->VirtualAddress  = (PVOID) NULL;    // Requested VA
    portAccess->InIoSpace       = 1;               // In IO space
    portAccess->MappedInIoSpace = portAccess->InIoSpace;

    physicalPortBase.HighPart   = 0x00000000;
    physicalPortBase.LowPart    = 0x00000000;
//    physicalPortLength          = LINEDRAW+2 - physicalPortBase.LowPart;
    physicalPortLength = 0x10000;


// *SANITIZE* If MM available, give MM ports instead.

    return VideoPortMapMemory(phwDeviceExtension,
                              physicalPortBase,
                              &physicalPortLength,
                              &(portAccess->MappedInIoSpace),
                              &(portAccess->VirtualAddress));

}   /* QueryPublicAccessRanges_m() */


/**************************************************************************
 *
 * VP_STATUS QueryCurrentMode_m(RequestPacket, QueryPtr);
 *
 * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
 * struct query_structure *QueryPtr;    Query information for the card
 *
 * DESCRIPTION:
 *  Get screen information and colour masks for the current video mode.
 *
 * RETURN VALUE:
 *  NO_ERROR if successful
 *  error code if failed
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  IOCTL_VIDEO_QUERY_CURRENT_MODE packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

VP_STATUS QueryCurrentMode_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
{
    PVIDEO_MODE_INFORMATION ModeInformation;

    /*
     * If the output buffer is too small to hold the information we need
     * to put in it, return with the appropriate error code.
     */
    if (RequestPacket->OutputBufferLength <
        (RequestPacket->StatusBlock->Information =
        sizeof(VIDEO_MODE_INFORMATION)) )
        {
        return ERROR_INSUFFICIENT_BUFFER;
        }

    /*
     * Fill in the mode information structure.
     */
    ModeInformation = RequestPacket->OutputBuffer;

    QuerySingleMode_m(ModeInformation, QueryPtr, phwDeviceExtension->ModeIndex);

    return NO_ERROR;

}   /* QueryCurrentMode_m() */


/**************************************************************************
 *
 * VP_STATUS QueryAvailModes_m(RequestPacket, QueryPtr);
 *
 * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
 * struct query_structure *QueryPtr;    Query information for the card
 *
 * DESCRIPTION:
 *  Get screen information and colour masks for all available video modes.
 *
 * RETURN VALUE:
 *  NO_ERROR if successful
 *  error code if failed
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  IOCTL_VIDEO_QUERY_AVAIL_MODES packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

VP_STATUS QueryAvailModes_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
{
    PVIDEO_MODE_INFORMATION ModeInformation;
    ULONG CurrentMode;

    /*
     * If the output buffer is too small to hold the information we need
     * to put in it, return with the appropriate error code.
     */
    if (RequestPacket->OutputBufferLength <
        (RequestPacket->StatusBlock->Information =
        QueryPtr->q_number_modes * sizeof(VIDEO_MODE_INFORMATION)) )
        {
        return ERROR_INSUFFICIENT_BUFFER;
        }

    /*
     * Fill in the mode information structure.
     */
    ModeInformation = RequestPacket->OutputBuffer;

    /*
     * For each mode supported by the card, store the mode characteristics
     * in the output buffer.
     */
    for (CurrentMode = 0; CurrentMode < QueryPtr->q_number_modes; CurrentMode++, ModeInformation++)
        QuerySingleMode_m(ModeInformation, QueryPtr, CurrentMode);

    return NO_ERROR;

}   /* QueryCurrentMode_m() */



/**************************************************************************
 *
 * static void QuerySingleMode_m(ModeInformation, QueryPtr, ModeIndex);
 *
 * PVIDEO_MODE_INFORMATION ModeInformation; Table to be filled in
 * struct query_structure *QueryPtr;        Query information for the card
 * ULONG ModeIndex;                         Index of mode table to use
 *
 * DESCRIPTION:
 *  Fill in a single Windows NT mode information table using data from
 *  one of our CRT parameter tables.
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  QueryCurrentMode_m() and QueryAvailModes_m()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

static void QuerySingleMode_m(PVIDEO_MODE_INFORMATION ModeInformation,
                              struct query_structure *QueryPtr,
                              ULONG ModeIndex)
{
    struct st_mode_table *CrtTable;     /* Pointer to current mode table */
    CrtTable = (struct st_mode_table *)QueryPtr;
    ((struct query_structure *)CrtTable)++;
    CrtTable += ModeIndex;


    ModeInformation->Length = sizeof(VIDEO_MODE_INFORMATION);
    ModeInformation->ModeIndex = ModeIndex;

    ModeInformation->VisScreenWidth  = CrtTable->m_x_size;
    ModeInformation->VisScreenHeight = CrtTable->m_y_size;

    // * Bytes per line = ((pixels/line) * (bits/pixel)) / (bits/byte))
    ModeInformation->ScreenStride = (CrtTable->m_screen_pitch * CrtTable->m_pixel_depth) / 8;

    ModeInformation->NumberOfPlanes = 1;
    ModeInformation->BitsPerPlane = (USHORT) CrtTable->m_pixel_depth;

    ModeInformation->Frequency = CrtTable->Refresh;

    /*
     * Driver can't measure the screen size,
     * so take reasonable values (16" diagonal).
     */
    ModeInformation->XMillimeter = 320;
    ModeInformation->YMillimeter = 240;

    switch(ModeInformation->BitsPerPlane)
        {
        case 16:
            ModeInformation->RedMask   = 0x0000f800;
            ModeInformation->GreenMask = 0x000007e0;
            ModeInformation->BlueMask  = 0x0000001f;
            ModeInformation->NumberRedBits      = 5;
            ModeInformation->NumberGreenBits    = 6;
            ModeInformation->NumberBlueBits     = 5;
            CrtTable->ColourDepthInfo = PIX_WIDTH_16BPP | ORDER_16BPP_565;
            break;

        case 24:
            /*
             * Windows NT uses RGB as the standard 24BPP mode,
             * so use this ordering for all DACs except the
             * Brooktree 48x which only supports BGR.
             */
            if (QueryPtr->q_DAC_type != DAC_BT48x)
                {
                ModeInformation->RedMask   = 0x00ff0000;
                ModeInformation->GreenMask = 0x0000ff00;
                ModeInformation->BlueMask  = 0x000000ff;
                CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_RGB;
                }
            else{
                ModeInformation->RedMask   = 0x000000ff;
                ModeInformation->GreenMask = 0x0000ff00;
                ModeInformation->BlueMask  = 0x00ff0000;
                CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_BGR;
                }
            ModeInformation->NumberRedBits      = 8;
            ModeInformation->NumberGreenBits    = 8;
            ModeInformation->NumberBlueBits     = 8;
            break;

        case 32:
            /*
             * Only the Brooktree 481 requires BGR,
             * and it doesn't support 32BPP.
             */
            ModeInformation->RedMask   = 0xff000000;
            ModeInformation->GreenMask = 0x00ff0000;
            ModeInformation->BlueMask  = 0x0000ff00;
            ModeInformation->NumberRedBits      = 8;
            ModeInformation->NumberGreenBits    = 8;
            ModeInformation->NumberBlueBits     = 8;
            CrtTable->ColourDepthInfo = PIX_WIDTH_24BPP | ORDER_24BPP_RGBx;
            break;

        default:
            ModeInformation->RedMask   = 0x00000000;
            ModeInformation->GreenMask = 0x00000000;
            ModeInformation->BlueMask  = 0x00000000;
            ModeInformation->NumberRedBits      = 6;
            ModeInformation->NumberGreenBits    = 6;
            ModeInformation->NumberBlueBits     = 6;
            CrtTable->ColourDepthInfo = PIX_WIDTH_8BPP;
            break;
        }

    ModeInformation->AttributeFlags = VIDEO_MODE_COLOR | VIDEO_MODE_GRAPHICS;

    if (CrtTable->m_pixel_depth <= 8)
        {
        ModeInformation->AttributeFlags |= VIDEO_MODE_PALETTE_DRIVEN |
            VIDEO_MODE_MANAGED_PALETTE;
        }

    /*
     * Bit 4 of the m_disp_cntl field is set for interlaced and
     * cleared for noninterlaced.
     *
     * The display applet gets confused if some of the "Use hardware
     * default" modes are interlaced and some are noninterlaced
     * (two "Use hardware default" entries are shown in the refresh
     * rate list). To avoid this, report all mode tables stored in
     * the EEPROM as noninterlaced, even if they are interlaced.
     * "Canned" mode tables give true reports.
     */
    if ((CrtTable->m_disp_cntl & 0x010) && (ModeInformation->Frequency != DEFAULT_REFRESH))
        ModeInformation->AttributeFlags |= VIDEO_MODE_INTERLACED;
    else
        ModeInformation->AttributeFlags &= ~VIDEO_MODE_INTERLACED;

    /*
     * Fill in the video memory bitmap width and height fields.
     * The descriptions are somewhat ambiguous - assume that
     * "bitmap width" is the same as ScreenStride (bytes from
     * start of one scanline to start of the next) and "bitmap
     * height" refers to the number of complete scanlines which
     * will fit into video memory.
     */
    ModeInformation->VideoMemoryBitmapWidth = ModeInformation->ScreenStride;
    ModeInformation->VideoMemoryBitmapHeight = (QueryPtr->q_memory_size * QUARTER_MEG) / ModeInformation->VideoMemoryBitmapWidth;

    return;

}   /* QuerySingleMode_m() */

//
//  When coming back from hibernate, mach32s can lock up and blackscreen.
//  This is because the card itself has to be reinitialized.
//  This initialization include at least the frame buffer initialization
//  and the initialization of the use of memory mapped registers.
//

VOID
EnableMach32FrameBufferAndMemMappedRegisters(
    PHW_DEVICE_EXTENSION pHwDeviceExtension
    )
{
    USHORT temp, temp1;

    //
    // enable the framebuffer.
    //

    temp = INPW(MEM_CFG) & 0x0fffc;     /* Preserve bits 2-15 */
    temp  |= 0x0002;                     /* 4M aperture        */
    OUTPW(MEM_CFG, temp);

    //
    // enable memory mapped register use.
    // save SRC_X ???

    OUTPW(SRC_X, 0x0AAAA);
    temp = INPW(R_SRC_X);
    if (temp  != 0x02AA)
       VideoDebugPrint((DEBUG_NORMAL, "Can't use memory mapped ranges, read %x\n", temp));

    temp1 = INPW(LOCAL_CONTROL);
    temp1 |= 0x0020;   // Enable memory mapped registers
    OUTPW(LOCAL_CONTROL, temp1);

    //restore SRC_X???: OUTPW(SRC_X, temp);
}


/**************************************************************************
 *
 * void SetCurrentMode_m(QueryPtr, CrtTable);
 *
 * struct query_structure *QueryPtr;    Query information for the card
 * struct st_mode_table *CrtTable;      CRT parameter table for desired mode
 *
 * DESCRIPTION:
 *  Switch into the specified video mode.
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  IOCTL_VIDEO_SET_CURRENT_MODE packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *  1994 01 13  Added initialization of bank manager
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

void SetCurrentMode_m(struct query_structure *QueryPtr, struct st_mode_table *CrtTable)
{
    WORD MiscOptions;   /* Contents of MISC_OPTIONS register */
    USHORT Scratch, USTemp;     /* Temporary variable */

    //
    //  When coming back from hibernate, mach32s can lock up and blackscreen.
    //  This is because the card itself has to be reinitialized.
    //  This initialization include at least the frame buffer initialization
    //  and the initialization of the use of memory mapped registers.
    //

    if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
        {
        // enable the framebuffer.
        Scratch = INPW(MEM_CFG) & 0x0fffc;     /* Preserve bits 2-15 */
        Scratch  |= 0x0002;                     /* 4M aperture        */
        OUTPW(MEM_CFG, Scratch);

        // enable memory mapped register use.
        // save SRC_X ???
        OUTPW(SRC_X, 0x0AAAA);
        Scratch = INPW(R_SRC_X);
        if (Scratch  != 0x02AA)
           VideoDebugPrint((DEBUG_NORMAL, "Can't use memory mapped ranges, read %x\n", Scratch));

        USTemp = INPW(LOCAL_CONTROL);
        USTemp |= 0x0020;   // Enable memory mapped registers
        OUTPW(LOCAL_CONTROL, USTemp);
        //restore SRC_X???: OUTPW(SRC_X, Scratch);
        }


    /*
     * Put the DAC in a known state before we start.
     */
    UninitTiDac_m();

    Passth8514_m(SHOW_ACCEL);    // turn vga pass through off

    /*
     * On cards with the "MISC_OPTIONS doesn't report video memory size
     * correctly" bug, reset MISC_OPTIONS to show the true amount of
     * video memory. This is done here rather than when we determine
     * how much memory is present in order to avoid trashing the "blue
     * screen" (no adverse effects on operation, but would generate
     * large numbers of user complaints).
     */
    if (((QueryPtr->q_asic_rev == CI_68800_6) || (QueryPtr->q_asic_rev == CI_68800_AX)) &&
        (QueryPtr->q_VGA_type == 1) &&
        ((QueryPtr->q_memory_type == VMEM_DRAM_256Kx4) ||
         (QueryPtr->q_memory_type == VMEM_DRAM_256Kx16) ||
         (QueryPtr->q_memory_type == VMEM_DRAM_256Kx4_GRAP)))
        {
        MiscOptions = INPW(MISC_OPTIONS) & MEM_SIZE_STRIPPED;

        switch (QueryPtr->q_memory_size)
            {
            case VRAM_512k:
                MiscOptions |= MEM_SIZE_512K;
                break;

            case VRAM_1mb:
                MiscOptions |= MEM_SIZE_1M;
                break;

            case VRAM_2mb:
                MiscOptions |= MEM_SIZE_2M;
                break;

            case VRAM_4mb:
                MiscOptions |= MEM_SIZE_4M;
                break;
            }
        OUTPW(MISC_OPTIONS, MiscOptions);
        }

    setmode_m(CrtTable, (ULONG_PTR) &(phwDeviceExtension->RomBaseRange), (ULONG) phwDeviceExtension->ModelNumber);

    /*
     * On a Mach 8 card, 1280x1024 can only be done in split
     * pixel mode. If we are running on a Mach 8, and this
     * resolution was selected, go into split pixel mode.
     *
     * Bit 4 of EXT_GE_CONFIG is set for split pixel mode and
     * clear for normal mode. Bit 3 must be set, since clearing
     * it accesses EEPROM read/write mode.
     */
    if    ((phwDeviceExtension->ModelNumber == _8514_ULTRA)
        || (phwDeviceExtension->ModelNumber == GRAPHICS_ULTRA))
        {
        if (QueryPtr->q_desire_x == 1280)
                OUTPW(EXT_GE_CONFIG, 0x0018);
        else    OUTPW(EXT_GE_CONFIG, 0x0008);
        }

    /*
     * Default to 8 bits per pixel. Modes which require a different
     * setting will change this in the init_ti_<depth>_m() function.
     */
    OUTP(DAC_MASK, 0xff);

    if (phwDeviceExtension->ModelNumber == MACH32_ULTRA)
        {
        switch (CrtTable->m_pixel_depth)    // program the DAC for the
            {                               // other resolutions
            case 4:
            case 8:
                InitTi_8_m((WORD)(CrtTable->ColourDepthInfo | 0x0a));
                break;

            case 16:
                InitTi_16_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG_PTR) &(phwDeviceExtension->RomBaseRange));   /* 16 bit 565 */
                break;

            case 24:
            case 32:
                /*
                 * RGB/BGR and 24/32 bit mode information is
                 * stored in CrtTable->ColourDepthInfo.
                 */
                InitTi_24_m((WORD)(CrtTable->ColourDepthInfo | 0x0a), (ULONG_PTR) &(phwDeviceExtension->RomBaseRange));
                break;
            }
        }

    /*
     * If we are going to be using the VGA aperture on a Mach 32,
     * initialize the bank manager by saving the ATI extended register
     * values and putting the VGA controller into packed pixel mode.
     *
     * We can't identify this case by looking at
     * phwDeviceExtension->FrameLength because it is set to 0x10000
     * when the VGA aperture is being used in the
     * IOCTL_VIDEO_MAP_VIDEO_MEMORY packet which may or may not
     * have been called by the time we reach this point.
     */
    if ((phwDeviceExtension->ModelNumber == MACH32_ULTRA) &&
        (QueryPtr->q_aperture_cfg == 0) &&
        (QueryPtr->q_VGA_type == 1))
        {
        for (Scratch = 0; Scratch <= 2; Scratch++)
            {
            OUTP(reg1CE, (BYTE)(SavedExtRegs[Scratch] & 0x00FF));
            SavedExtRegs[Scratch] = (SavedExtRegs[Scratch] & 0x00FF) | (INP(reg1CF) << 8);
            }
        OUTPW(HI_SEQ_ADDR, 0x0F02);
        OUTPW(HI_SEQ_ADDR, 0x0A04);
        OUTPW(reg3CE, 0x1000);
        OUTPW(reg3CE, 0x0001);
        OUTPW(reg3CE, 0x0002);
        OUTPW(reg3CE, 0x0003);
        OUTPW(reg3CE, 0x0004);
        OUTPW(reg3CE, 0x0005);
        OUTPW(reg3CE, 0x0506);
        OUTPW(reg3CE, 0x0F07);
        OUTPW(reg3CE, 0xFF08);
        OUTPW(reg1CE, 0x28B0);  /* Enable 256 colour, 1M video RAM */
        OUTPW(reg1CE, 0x04B6);  /* Select linear addressing */
        OUTP(reg1CE, 0xBE);
        OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE));
        }


    /*
     * phwDeviceExtension->ReInitializing becomes TRUE in
     * IOCTL_VIDEO_SET_COLOR_REGISTERS packet of ATIMPStartIO().
     *
     * If this is not the first time we are switching into graphics
     * mode, set the palette to the last set of colours that was
     * selected while in graphics mode.
     */
    if (phwDeviceExtension->ReInitializing)
        {
        SetPalette_m(phwDeviceExtension->Clut,
                     phwDeviceExtension->FirstEntry,
                     phwDeviceExtension->NumEntries);
        }

    /*
     * Clear visible screen.
     *
     * 24 and 32 BPP would require a q_desire_y value beyond the
     * maximum allowable clipping value (1535) if we clear the screen
     * using a normal blit. Since these pixel depths are only supported
     * up to 800x600, we can fake it by doing a 16BPP blit of double the
     * screen height, clipping the special case of 640x480 24BPP on
     * a 1M card (this is the only true colour mode that will fit in
     * 1M, so if we hit this case on a 1M card, we know which mode
     * we're dealing with) to avoid running off the end of video memory.
     */
    if (CrtTable->m_pixel_depth >= 24)
        {
        /*
         * Save the colour depth configuration and switch into 16BPP
         */
        Scratch = INPW(R_EXT_GE_CONFIG);
        OUTPD(EXT_GE_CONFIG, (Scratch & 0xFFCF) | PIX_WIDTH_16BPP);

        CheckFIFOSpace_m(SIXTEEN_WORDS);

        OUTPW(DP_CONFIG, 0x2011);
        OUTPW(ALU_FG_FN, 0x7);          // Paint
        OUTPW(FRGD_COLOR, 0);	        // Black
        OUTPW(CUR_X, 0);
        OUTPW(CUR_Y, 0);
        OUTPW(DEST_X_START, 0);
        OUTPW(DEST_X_END, QueryPtr->q_desire_x);

        if (QueryPtr->q_memory_size == VRAM_1mb)
            OUTPW(DEST_Y_END, 720);     /* Only 640x480 24BPP will fit in 1M */
        else
            OUTPW(DEST_Y_END, (WORD)(2*(QueryPtr->q_desire_y)));

        /*
         * Let the blit finish then restore the colour depth configuration
         */
        WaitForIdle_m();
        OUTPD(EXT_GE_CONFIG, Scratch);

        }
    else{
        /*
         * Other colour depths can be handled by a normal blit, and the
         * LFB may not be available, so use a blit to clear the screen.
         */
        CheckFIFOSpace_m(SIXTEEN_WORDS);

        OUTPW(DP_CONFIG, 0x2011);
        OUTPW(ALU_FG_FN, 0x7);          // Paint
        OUTPW(FRGD_COLOR, 0);	        // Black
        OUTPW(CUR_X, 0);
        OUTPW(CUR_Y, 0);
        OUTPW(DEST_X_START, 0);
        OUTPW(DEST_X_END, QueryPtr->q_desire_x);
        OUTPW(DEST_Y_END, QueryPtr->q_desire_y);
        }

#if 0
    /*
     * In 800x600 24BPP, set the offset to start 1 pixel into video
     * memory to avoid screen tearing. The MAP_VIDEO_MEMORY packet
     * must adjust the framebuffer base to compensate for this.
     */
    if ((QueryPtr->q_desire_x == 800) && (QueryPtr->q_pix_depth == 24))
        {
        OUTPW(CRT_OFFSET_LO, 3);
        }
    else
        {
        OUTPW(CRT_OFFSET_HI, 0);
        }
#endif

    WaitForIdle_m();

    return;

}   /* SetCurrentMode_m() */



/**************************************************************************
 *
 * void ResetDevice_m(void);
 *
 * DESCRIPTION:
 *  Reset the accelerator to allow the VGA miniport to switch
 *  into a VGA mode.
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  IOCTL_VIDEO_RESET_DEVICE packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

void ResetDevice_m(void)
{
    VIDEO_X86_BIOS_ARGUMENTS Registers; /* Used in VideoPortInt10() calls */

    /*
     * If we are using the VGA aperture on a Mach 32, put its
     * VGA controller into planar mode.
     */
    if (phwDeviceExtension->FrameLength == 0x10000)
        {
        OUTPW(reg1CE, SavedExtRegs[0]);
        OUTPW(reg1CE, SavedExtRegs[1]);
        OUTPW(reg1CE, SavedExtRegs[2]);
        OUTP(reg1CE, 0xBE);
        OUTPW(reg1CE, (WORD)(((INP(reg1CF) & 0xF7) << 8) | 0xBE));
        }
    UninitTiDac_m();
    Passth8514_m(SHOW_VGA);

    VideoPortZeroMemory(&Registers, sizeof(VIDEO_X86_BIOS_ARGUMENTS));
    Registers.Eax = 0x0003;         // set text mode 3
    VideoPortInt10(phwDeviceExtension, &Registers);

}   /* ResetDevice_m() */



/**************************************************************************
 *
 * VP_STATUS SetPowerManagement_m(QueryPtr, DpmsState);
 *
 * struct query_structure *QueryPtr;    Query information for the card
 * DWORD DpmsState;                     Desired DPMS state
 *                                      (VIDEO_POWER_STATE enumeration)
 *
 * DESCRIPTION:
 *  Switch into the desired DPMS state.
 *
 * RETURN VALUE:
 *  NO_ERROR if successful
 *  ERROR_INVALID_PARAMETER if invalid state requested.
 *
 * GLOBALS CHANGED:
 *  none
 *
 * CALLED BY:
 *  IOCTL_VIDEO_SET_POWER_MANAGEMENT packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

VP_STATUS SetPowerManagement_m(struct query_structure *QueryPtr, DWORD DpmsState)
{
    struct st_mode_table *CrtTable; /* Mode table, used to obtain sync values */

    /*
     * Only accept valid states.
     */
    if ((DpmsState < VideoPowerOn) || (DpmsState > VideoPowerOff))
        return ERROR_INVALID_PARAMETER;

    /*
     * Set CrtTable to point to the mode table associated with the
     * selected mode.
     *
     * When a pointer to a structure is incremented by an integer,
     * the integer represents the number of structure-sized blocks
     * to skip over, not the number of bytes to skip over.
     */
    CrtTable = (struct st_mode_table *)QueryPtr;
    ((struct query_structure *)CrtTable)++;
    CrtTable += phwDeviceExtension->ModeIndex;

    SavedDPMSState = DpmsState;

    /*
     * Mach 32 rev. 6 and later supports turning the sync signals on and off
     * through the HORZ_OVERSCAN registers, but some chips that report as
     * rev. 6 don't have this implemented. Also, Mach 32 rev. 3 and Mach 8
     * don't support this mechanism.
     *
     * Disabling the sync by setting it to start after the total will work
     * for all chips. Most chips will de-synchronize if the sync is set
     * to 1 more than the total, but some need higher values. To be sure
     * of de-synchronizing, set the disabled sync signal to start at
     * the highest possible value.
     */
    switch (DpmsState)
        {
        case VideoPowerOn:
            OUTP(H_SYNC_STRT,	CrtTable->m_h_sync_strt);
            OUTPW(V_SYNC_STRT,	CrtTable->m_v_sync_strt);
            break;

        case VideoPowerStandBy:
            OUTP(H_SYNC_STRT,	0xFF);
            OUTPW(V_SYNC_STRT,	CrtTable->m_v_sync_strt);
            break;

        case VideoPowerSuspend:
            OUTP(H_SYNC_STRT,	CrtTable->m_h_sync_strt);
            OUTPW(V_SYNC_STRT,	0x0FFF);
            break;

        case VideoPowerOff:
            OUTP(H_SYNC_STRT,	0xFF);
            OUTPW(V_SYNC_STRT,	0x0FFF);
            break;

        /*
         * This case should never happen, because the initial
         * acceptance of only valid states should have already
         * rejected anything that will appear here.
         */
        default:
            break;
        }
        return NO_ERROR;

}   /* SetPowerManagement_m() */


DWORD GetPowerManagement_m(PHW_DEVICE_EXTENSION phwDeviceExtension)
/*
 * DESCRIPTION:
 *  Report which DPMS state we are in.
 *
 * PARAMETERS:
 *  phwDeviceExtension  Points to per-adapter device extension.
 *
 * RETURN VALUE:
 *  Current DPMS state (VIDEO_POWER_STATE enumeration).
 */
{
    ASSERT(phwDeviceExtension != NULL);

    /*
     * On the Mach 8, the sync start registers are write-only, so
     * we can't check which state we are in. For this reason, we
     * have saved the state we switched into using SetPowerManagement_m().
     * On the Mach 32, we can either use this saved state or read
     * the sync start registers, but using the same method as for
     * the Mach 8 reduces complexity.
     */
    return SavedDPMSState;
}   /* GetPowerManagement_m() */



/**************************************************************************
 *
 * VP_STATUS ShareVideoMemory_m(RequestPacket, QueryPtr);
 *
 * PVIDEO_REQUEST_PACKET RequestPacket; Request packet with input and output buffers
 * struct query_structure *QueryPtr;    Query information for the card
 *
 * DESCRIPTION:
 *  Allow applications to do direct screen access through DCI.
 *
 * RETURN VALUE:
 *  NO_ERROR if successful
 *  error code if failed
 *
 * CALLED BY:
 *  IOCTL_VIDEO_SHARE_VIDEO_MEMORY packet of ATIMPStartIO()
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

VP_STATUS ShareVideoMemory_m(PVIDEO_REQUEST_PACKET RequestPacket, struct query_structure *QueryPtr)
{
    PVIDEO_SHARE_MEMORY InputPtr;               /* Pointer to input structure */
    PVIDEO_SHARE_MEMORY_INFORMATION OutputPtr;  /* Pointer to output structure */
    PHYSICAL_ADDRESS ShareAddress;              /* Physical address of video memory */
    PVOID VirtualAddress;                       /* Virtual address to map video memory at */
    ULONG SharedViewSize;                       /* Size of block to share */
    ULONG SpaceType;                            /* Sparse or dense space? */
    VP_STATUS Status;                           /* Status to return */

    /*
     * We can only share the aperture with application programs if there
     * is an aperture available. If both the LFB and the on-board VGA
     * and therefore the VGA aperture) are disabled, report that we
     * can't share the aperture.
     */
    if ((QueryPtr->q_aperture_cfg == 0) && (QueryPtr->q_VGA_type == 0))
        return ERROR_INVALID_FUNCTION;

    InputPtr = RequestPacket->InputBuffer;

    if ((InputPtr->ViewOffset > phwDeviceExtension->VideoRamSize) ||
        ((InputPtr->ViewOffset + InputPtr->ViewSize) > phwDeviceExtension->VideoRamSize))
        {
        VideoDebugPrint((DEBUG_ERROR, "ShareVideoMemory_m() - access beyond video memory\n"));
        return ERROR_INVALID_PARAMETER;
        }

    RequestPacket->StatusBlock->Information = sizeof(VIDEO_SHARE_MEMORY_INFORMATION);

    /*
     * Beware: the input buffer and the output buffer are the same buffer,
     * and therefore data should not be copied from one to the other.
     */
    VirtualAddress = InputPtr->ProcessHandle;
    SharedViewSize = InputPtr->ViewSize;

    SpaceType = 0;
#if defined(_ALPHA_)
    /*
     * Use dense space mapping whenever we can, because that will
     * allow us to support DCI and direct GDI access.
     *
     * Dense space is extremely slow with ISA cards on the newer Alphas,
     * because any byte- or word-write requires a read/modify/write
     * operation, and the ALpha can only ever do 64-bit reads when in
     * dense mode. As a result, these operations would always require
     * 4 reads and 2 writes on the ISA bus. Also, some older Alphas
     * don't support dense space mapping.
     *
     * Any Alpha that supports PCI can support dense space mapping, and
     * because the bus is wider and faster, the read/modify/write has
     * less of an impact on performance.
     */
    if (QueryPtr->q_bus_type == BUS_PCI)
        SpaceType = 4;
#endif

    /*
     * NOTE: we are ignoring ViewOffset
     */
    ShareAddress.QuadPart = phwDeviceExtension->PhysicalFrameAddress.QuadPart;


    /*
     * If the LFB is enabled, use ordinary mapping. If we have only
     * the paged aperture, we must map to banked memory. Since the
     * LFB is always aligned on a 1M boundary (4M boundary for 4M
     * aperture), this check for the paged aperture will never falsely
     * detect a LFB as paged.
     */
    if (phwDeviceExtension->PhysicalFrameAddress.LowPart == 0x0A0000)
        {
        /*
         * On some versions of the DDK, VideoPortMapBankedMemory() is
         * not available. If this is the case, force an error.
         * This routine should be available in all versions of
         * the DDK which support DCI, since it is used for DCI
         * support on cards with banked apertures.
         */
#if defined(IOCTL_VIDEO_SHARE_VIDEO_MEMORY)
        Status = VideoPortMapBankedMemory(
            phwDeviceExtension,
            ShareAddress,
            &SharedViewSize,
            &SpaceType,
            &VirtualAddress,
            0x10000,            /* 64k VGA aperture */
            FALSE,              /* No separate read/write banks */
            BankMap_m,          /* Our bank-mapping routine */
            (PVOID) phwDeviceExtension);
#else
        Status = ERROR_INVALID_FUNCTION;
#endif
        }
    else    /* LFB */
        {
        Status = VideoPortMapMemory(phwDeviceExtension,
                                    ShareAddress,
                                    &SharedViewSize,
                                    &SpaceType,
                                    &VirtualAddress);
        }

    OutputPtr = RequestPacket->OutputBuffer;
    OutputPtr->SharedViewOffset = InputPtr->ViewOffset;
    OutputPtr->VirtualAddress = VirtualAddress;
    OutputPtr->SharedViewSize = SharedViewSize;

    return Status;

}   /* ShareVideoMemory_m() */



/**************************************************************************
 *
 * void BankMap_m(BankRead, BankWrite, Context);
 *
 * ULONG BankRead;       Bank to read
 * ULONG BankWrite;      Bank to write
 * PVOID Context;       Pointer to hardware-specific information
 *
 * DESCRIPTION:
 *  Map the selected bank of video memory into the 64k VGA aperture.
 *  We don't support separate read and write banks, so we use BankWrite
 *  to set the read/write bank, and ignore BankRead.
 *
 * CALLED BY:
 *  This is an entry point, rather than being called
 *  by other miniport functions.
 *
 * NOTE:
 *  This function is called directly by the memory manager during page
 *  fault handling, and so cannot be made pageable.
 *
 * AUTHOR:
 *  Robert Wolff
 *
 * CHANGE HISTORY:
 *
 * TEST HISTORY:
 *
 ***************************************************************************/

void BankMap_m(ULONG BankRead, ULONG BankWrite, PVOID Context)
{
    OUTPW( reg1CE, (USHORT)(((BankWrite & 0x0f) << 9) | 0xb2));
    OUTPW( reg1CE, (USHORT)(((BankWrite & 0x30) << 4) | 0xae));

    return;

}   /* BankMap_m() */