/* * Copyright 1997 through 2004 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org * * Permission to use, copy, modify, distribute, and sell this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that copyright * notice and this permission notice appear in supporting documentation, and * that the name of Marc Aurele La France not be used in advertising or * publicity pertaining to distribution of the software without specific, * written prior permission. Marc Aurele La France makes no representations * about the suitability of this software for any purpose. It is provided * "as-is" without express or implied warranty. * * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif /* * The ATI x8800 chips use special registers for their extended VGA features. * These registers are accessible through an index I/O port and a data I/O * port. BIOS initialisation stores the index port number in the Graphics * register bank (0x03CE), indices 0x50 and 0x51. Unfortunately, for all but * the 18800-x series of adapters, these registers are write-only (a.k.a. black * holes). On all but 88800's, the index port number can be found in the short * integer at offset 0x10 in the BIOS. For 88800's, this driver will use * 0x01CE or 0x03CE as the index port number, depending on the I/O port * decoding used. The data port number is one more than the index port number * (i.e. 0x01CF). These ports differ slightly in their I/O behaviour from the * normal VGA ones: * * write: outw(0x01CE, (data << 8) | index); (16-bit, not used) * outb(0x01CE, index); outb(0x01CF, data); (8-bit) * read: outb(0x01CE, index); data = inb(0x01CF); * * Two consecutive byte-writes to the data port will not work. Furthermore an * index written to 0x01CE is usable only once. Note also that the setting of * ATI extended registers (especially those with clock selection bits) should * be bracketed by a sequencer reset. * * The number of these extended VGA registers varies by chipset. The 18800 * series have 16, the 28800 series have 32, while 68800's and 88800's have 64. * The last 16 on each have almost identical definitions. Thus, the BIOS sets * up an indexing scheme whereby the last 16 extended VGA registers are * accessed at indices 0xB0 through 0xBF on all chipsets. */ #include "ati.h" #include "atichip.h" #include "atiwonder.h" #include "atiwonderio.h" #ifndef AVOID_CPIO /* * ATIVGAWonderPreInit -- * * This function is called to initialise the VGA Wonder part of an ATIHWRec * that is common to all modes generated by the driver. */ void ATIVGAWonderPreInit ( ATIPtr pATI, ATIHWPtr pATIHW ) { pATIHW->b3 = ATIGetExtReg(0xB3U) & 0x20U; pATIHW->b6 = 0x04U; pATIHW->b6 |= 0x01U; pATIHW->bf = ATIGetExtReg(0xBFU) & 0x5FU; pATIHW->a3 = ATIGetExtReg(0xA3U) & 0x67U; pATIHW->ab = ATIGetExtReg(0xABU) & 0xE7U; pATIHW->ae = ATIGetExtReg(0xAEU) & 0xE0U; } /* * ATIVGAWonderSave -- * * This function is called to save the VGA Wonder portion of the current video * state. */ void ATIVGAWonderSave ( ATIPtr pATI, ATIHWPtr pATIHW ) { pATIHW->b0 = ATIGetExtReg(0xB0U); pATIHW->b1 = ATIGetExtReg(0xB1U); pATIHW->b2 = ATIGetExtReg(0xB2U); pATIHW->b3 = ATIGetExtReg(0xB3U); pATIHW->b5 = ATIGetExtReg(0xB5U); pATIHW->b6 = ATIGetExtReg(0xB6U); pATIHW->b8 = ATIGetExtReg(0xB8U); pATIHW->b9 = ATIGetExtReg(0xB9U); pATIHW->ba = ATIGetExtReg(0xBAU); pATIHW->bd = ATIGetExtReg(0xBDU); { pATIHW->be = ATIGetExtReg(0xBEU); { pATIHW->bf = ATIGetExtReg(0xBFU); pATIHW->a3 = ATIGetExtReg(0xA3U); pATIHW->a6 = ATIGetExtReg(0xA6U); pATIHW->a7 = ATIGetExtReg(0xA7U); pATIHW->ab = ATIGetExtReg(0xABU); pATIHW->ac = ATIGetExtReg(0xACU); pATIHW->ad = ATIGetExtReg(0xADU); pATIHW->ae = ATIGetExtReg(0xAEU); } } } /* * ATIVGAWonderSet -- * * This function loads the VGA Wonder portion of a video state. */ void ATIVGAWonderSet ( ATIPtr pATI, ATIHWPtr pATIHW ) { { ATIModifyExtReg(pATI, 0xBEU, -1, 0x00U, pATIHW->be); { ATIModifyExtReg(pATI, 0xBFU, -1, 0x00U, pATIHW->bf); ATIModifyExtReg(pATI, 0xA3U, -1, 0x00U, pATIHW->a3); ATIModifyExtReg(pATI, 0xA6U, -1, 0x00U, pATIHW->a6); ATIModifyExtReg(pATI, 0xA7U, -1, 0x00U, pATIHW->a7); ATIModifyExtReg(pATI, 0xABU, -1, 0x00U, pATIHW->ab); ATIModifyExtReg(pATI, 0xACU, -1, 0x00U, pATIHW->ac); ATIModifyExtReg(pATI, 0xADU, -1, 0x00U, pATIHW->ad); ATIModifyExtReg(pATI, 0xAEU, -1, 0x00U, pATIHW->ae); } } ATIModifyExtReg(pATI, 0xB0U, -1, 0x00U, pATIHW->b0); ATIModifyExtReg(pATI, 0xB1U, -1, 0x00U, pATIHW->b1); ATIModifyExtReg(pATI, 0xB3U, -1, 0x00U, pATIHW->b3); ATIModifyExtReg(pATI, 0xB5U, -1, 0x00U, pATIHW->b5); ATIModifyExtReg(pATI, 0xB6U, -1, 0x00U, pATIHW->b6); ATIModifyExtReg(pATI, 0xB8U, -1, 0x00U, pATIHW->b8); ATIModifyExtReg(pATI, 0xB9U, -1, 0x00U, pATIHW->b9); ATIModifyExtReg(pATI, 0xBAU, -1, 0x00U, pATIHW->ba); ATIModifyExtReg(pATI, 0xBDU, -1, 0x00U, pATIHW->bd); } #endif /* AVOID_CPIO */