/* Copyright 2008 Haiku, Inc. All rights reserved. Distributed under the terms of the MIT license. Authors: Gerald Zajac 2008 */ #include "accel.h" #include // Macros for memory mapped I/O. //============================== #define INREG8(addr) *((vuint8*)(gInfo.regs + addr)) #define INREG16(addr) *((vuint16*)(gInfo.regs + addr)) #define INREG32(addr) *((vuint32*)(gInfo.regs + addr)) #define OUTREG8(addr, val) *((vuint8*)(gInfo.regs + addr)) = val #define OUTREG16(addr, val) *((vuint16*)(gInfo.regs + addr)) = val #define OUTREG32(addr, val) *((vuint32*)(gInfo.regs + addr)) = val // Functions for PIO. //=================== uint32 ReadPIO(uint32 addr, uint8 numBytes) { S3GetSetPIO gsp; gsp.magic = S3_PRIVATE_DATA_MAGIC; gsp.offset = addr; gsp.size = numBytes; gsp.value = 0; status_t result = ioctl(gInfo.deviceFileDesc, S3_GET_PIO, &gsp, sizeof(gsp)); if (result != B_OK) TRACE("ReadPIO() failed, result = 0x%x\n", result); return gsp.value; } void WritePIO(uint32 addr, uint8 numBytes, uint32 value) { S3GetSetPIO gsp; gsp.magic = S3_PRIVATE_DATA_MAGIC; gsp.offset = addr; gsp.size = numBytes; gsp.value = value; status_t result = ioctl(gInfo.deviceFileDesc, S3_SET_PIO, &gsp, sizeof(gsp)); if (result != B_OK) TRACE("WritePIO() failed, result = 0x%x\n", result); } // Functions to read 8/16/32 bit registers. //========================================= uint8 ReadReg8(uint32 addr) { if (gInfo.sharedInfo->chipType == S3_TRIO64) return ReadPIO(addr, 1); return INREG8(addr); } uint16 ReadReg16(uint32 addr) { if (gInfo.sharedInfo->chipType == S3_TRIO64) return ReadPIO(addr, 2); return INREG16(addr); } uint32 ReadReg32(uint32 addr) { if (gInfo.sharedInfo->chipType == S3_TRIO64) return ReadPIO(addr, 4); return INREG32(addr); } // Functions to write 8/16/32 bit registers. //========================================= void WriteReg8(uint32 addr, uint8 value) { if (gInfo.sharedInfo->chipType == S3_TRIO64) WritePIO(addr, 1, value); else OUTREG8(addr, value); } void WriteReg16(uint32 addr, uint16 value) { if (gInfo.sharedInfo->chipType == S3_TRIO64) WritePIO(addr, 2, value); else OUTREG16(addr, value); } void WriteReg32(uint32 addr, uint32 value) { if (gInfo.sharedInfo->chipType == S3_TRIO64) WritePIO(addr, 4, value); else OUTREG32(addr, value); } // Functions to read/write CRTC registers. //======================================== uint8 ReadCrtcReg(uint8 index) { if (gInfo.sharedInfo->chipType == S3_TRIO64) { WritePIO_8(0x3d4, index); return ReadPIO_8(0x3d5); } OUTREG8(0x83d4, index); return INREG8(0x83d5); } void WriteCrtcReg(uint8 index, uint8 value) { if (gInfo.sharedInfo->chipType == S3_TRIO64) { WritePIO_8(0x3d4, index); WritePIO_8(0x3d5, value); } else { OUTREG8(0x83d4, index); OUTREG8(0x83d5, value); } } void WriteCrtcReg(uint8 index, uint8 value, uint8 mask) { // Write a value to a CRTC reg using a mask. The mask selects the // bits to be modified. if (gInfo.sharedInfo->chipType == S3_TRIO64) { WritePIO_8(0x3d4, index); WritePIO_8(0x3d5, (ReadPIO_8(0x3d5) & ~mask) | (value & mask)); } else { OUTREG8(0x83d4, index); OUTREG8(0x83d5, (INREG8(0x83d5) & ~mask) | (value & mask)); } } // Functions to read/write Sequence registers. //============================================ uint8 ReadSeqReg(uint8 index) { if (gInfo.sharedInfo->chipType == S3_TRIO64) { WritePIO_8(0x3c4, index); return ReadPIO_8(0x3c5); } OUTREG8(0x83c4, index); return INREG8(0x83c5); } void WriteSeqReg(uint8 index, uint8 value) { if (gInfo.sharedInfo->chipType == S3_TRIO64) { WritePIO_8(0x3c4, index); WritePIO_8(0x3c5, value); } else { OUTREG8(0x83c4, index); OUTREG8(0x83c5, value); } } void WriteSeqReg(uint8 index, uint8 value, uint8 mask) { // Write a value to a Sequencer reg using a mask. The mask selects the // bits to be modified. if (gInfo.sharedInfo->chipType == S3_TRIO64) { WritePIO_8(0x3c4, index); WritePIO_8(0x3c5, (ReadPIO_8(0x3c5) & ~mask) | (value & mask)); } else { OUTREG8(0x83c4, index); OUTREG8(0x83c5, (INREG8(0x83c5) & ~mask) | (value & mask)); } } // Functions to read/write the misc output register. //================================================== uint8 ReadMiscOutReg() { if (gInfo.sharedInfo->chipType == S3_TRIO64) return ReadPIO_8(0x3cc); return INREG8(0x83cc); } void WriteMiscOutReg(uint8 value) { if (gInfo.sharedInfo->chipType == S3_TRIO64) WritePIO_8(0x3c2, value); else OUTREG8(0x83c2, value); } void WriteIndexedColor(uint8 index, uint8 red, uint8 green, uint8 blue) { // Write an indexed color. Argument index is the index (0-255) of the // color, and arguments red, green, & blue are the components of the color. // Note that although the Trio64V+ chip supports MMIO in nearly all areas, // it does not support MMIO for setting indexed colors; thus, use PIO to // set the indexed color. if (gInfo.sharedInfo->chipType == S3_TRIO64 || gInfo.sharedInfo->chipType == S3_TRIO64_VP) { WritePIO_8(0x3c8, index); // color index WritePIO_8(0x3c9, red); WritePIO_8(0x3c9, green); WritePIO_8(0x3c9, blue); } else { OUTREG8(0x83c8, index); // color index OUTREG8(0x83c9, red); OUTREG8(0x83c9, green); OUTREG8(0x83c9, blue); } }