Copyright 2008 Haiku, Inc. All rights reserved.
Distributed under the terms of the MIT license.
Authors:
Gerald Zajac 2008
*/
#include "accel.h"
#include <unistd.h>
#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
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);
}
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);
}
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);
}
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)
{
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));
}
}
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)
{
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));
}
}
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)
{
if (gInfo.sharedInfo->chipType == S3_TRIO64
|| gInfo.sharedInfo->chipType == S3_TRIO64_VP) {
WritePIO_8(0x3c8, index);
WritePIO_8(0x3c9, red);
WritePIO_8(0x3c9, green);
WritePIO_8(0x3c9, blue);
} else {
OUTREG8(0x83c8, index);
OUTREG8(0x83c9, red);
OUTREG8(0x83c9, green);
OUTREG8(0x83c9, blue);
}
}