#include "ati.h"
#include "atidac.h"
#include "atimach64io.h"
#include "atimono.h"
const SymTabRec ATIDACDescriptors[] =
{
{ATI_DAC_ATI68830, "ATI 68830 or similar"},
{ATI_DAC_SC11483, "Sierra 11483 or similar"},
{ATI_DAC_ATI68875, "ATI 68875 or similar"},
{ATI_DAC_TVP3026_A, "TI ViewPoint3026 or similar"},
{ATI_DAC_GENERIC, "Brooktree 476 or similar"},
{ATI_DAC_BT481, "Brooktree 481 or similar"},
{ATI_DAC_ATT20C491, "AT&T 20C491 or similar"},
{ATI_DAC_SC15026, "Sierra 15026 or similar"},
{ATI_DAC_MU9C1880, "Music 9C1880 or similar"},
{ATI_DAC_IMSG174, "Inmos G174 or similar"},
{ATI_DAC_ATI68860_B, "ATI 68860 (Revision B) or similar"},
{ATI_DAC_ATI68860_C, "ATI 68860 (Revision C) or similar"},
{ATI_DAC_TVP3026_B, "TI ViewPoint3026 or similar"},
{ATI_DAC_STG1700, "SGS-Thompson 1700 or similar"},
{ATI_DAC_ATT20C498, "AT&T 20C498 or similar"},
{ATI_DAC_STG1702, "SGS-Thompson 1702 or similar"},
{ATI_DAC_SC15021, "Sierra 15021 or similar"},
{ATI_DAC_ATT21C498, "AT&T 21C498 or similar"},
{ATI_DAC_STG1703, "SGS-Thompson 1703 or similar"},
{ATI_DAC_CH8398, "Chrontel 8398 or similar"},
{ATI_DAC_ATT20C408, "AT&T 20C408 or similar"},
{ATI_DAC_INTERNAL, "Internal"},
{ATI_DAC_IBMRGB514, "IBM RGB 514 or similar"},
{ATI_DAC_UNKNOWN, "Unknown"}
};
#ifndef AVOID_CPIO
void
ATISetDACIOPorts
(
ATIPtr pATI,
ATICRTCType crtc
)
{
switch (crtc)
{
case ATI_CRTC_VGA:
pATI->CPIO_DAC_DATA = VGA_DAC_DATA;
pATI->CPIO_DAC_MASK = VGA_DAC_MASK;
pATI->CPIO_DAC_READ = VGA_DAC_READ;
pATI->CPIO_DAC_WRITE = VGA_DAC_WRITE;
pATI->CPIO_DAC_WAIT = GENS1(pATI->CPIO_VGABase);
break;
case ATI_CRTC_8514:
pATI->CPIO_DAC_DATA = IBM_DAC_DATA;
pATI->CPIO_DAC_MASK = IBM_DAC_MASK;
pATI->CPIO_DAC_READ = IBM_DAC_READ;
pATI->CPIO_DAC_WRITE = IBM_DAC_WRITE;
pATI->CPIO_DAC_WAIT = pATI->CPIO_DAC_MASK;
break;
case ATI_CRTC_MACH64:
pATI->CPIO_DAC_DATA = ATIIOPort(DAC_REGS) + 1;
pATI->CPIO_DAC_MASK = ATIIOPort(DAC_REGS) + 2;
pATI->CPIO_DAC_READ = ATIIOPort(DAC_REGS) + 3;
pATI->CPIO_DAC_WRITE = ATIIOPort(DAC_REGS) + 0;
pATI->CPIO_DAC_WAIT = pATI->CPIOBase;
break;
default:
break;
}
}
#endif
CARD8
ATIGetDACCmdReg
(
ATIPtr pATI
)
{
#ifdef AVOID_CPIO
(void)in8(M64_DAC_WRITE);
(void)in8(M64_DAC_MASK);
(void)in8(M64_DAC_MASK);
(void)in8(M64_DAC_MASK);
return in8(M64_DAC_MASK);
#else
(void)inb(pATI->CPIO_DAC_WRITE);
(void)inb(pATI->CPIO_DAC_MASK);
(void)inb(pATI->CPIO_DAC_MASK);
(void)inb(pATI->CPIO_DAC_MASK);
return inb(pATI->CPIO_DAC_MASK);
#endif
}
void
ATIDACPreInit
(
ScrnInfoPtr pScreenInfo,
ATIPtr pATI,
ATIHWPtr pATIHW
)
{
int Index, Index2;
CARD8 maxColour = (1 << pATI->rgbBits) - 1;
pATIHW->dac_read = pATIHW->dac_write = 0x00U;
pATIHW->dac_mask = 0xFFU;
if (pATI->depth > 8)
for (Index = 1; Index < (NumberOf(pATIHW->lut) / 3); Index++)
{
Index2 = Index * 3;
pATIHW->lut[Index2 + 0] =
pATIHW->lut[Index2 + 1] =
pATIHW->lut[Index2 + 2] = Index;
}
else
{
pATIHW->lut[3] = pATIHW->lut[4] = pATIHW->lut[5] = 0xFFU;
for (Index = 2; Index < (NumberOf(pATIHW->lut) / 3); Index++)
{
Index2 = Index * 3;
pATIHW->lut[Index2 + 0] = maxColour;
pATIHW->lut[Index2 + 1] = 0x00U;
pATIHW->lut[Index2 + 2] = maxColour;
}
#ifndef AVOID_CPIO
if (pATI->depth == 1)
{
rgb blackColour = pScreenInfo->display->blackColour,
whiteColour = pScreenInfo->display->whiteColour;
if (blackColour.red > maxColour)
blackColour.red = maxColour;
if (blackColour.green > maxColour)
blackColour.green = maxColour;
if (blackColour.blue > maxColour)
blackColour.blue = maxColour;
if (whiteColour.red > maxColour)
whiteColour.red = maxColour;
if (whiteColour.green > maxColour)
whiteColour.green = maxColour;
if (whiteColour.blue > maxColour)
whiteColour.blue = maxColour;
if ((blackColour.red == whiteColour.red) &&
(blackColour.green == whiteColour.green) &&
(blackColour.blue == whiteColour.blue))
{
blackColour.red ^= maxColour;
blackColour.green ^= maxColour;
blackColour.blue ^= maxColour;
}
pATIHW->lut[(MONO_BLACK * 3) + 0] = blackColour.red;
pATIHW->lut[(MONO_BLACK * 3) + 1] = blackColour.green;
pATIHW->lut[(MONO_BLACK * 3) + 2] = blackColour.blue;
pATIHW->lut[(MONO_WHITE * 3) + 0] = whiteColour.red;
pATIHW->lut[(MONO_WHITE * 3) + 1] = whiteColour.green;
pATIHW->lut[(MONO_WHITE * 3) + 2] = whiteColour.blue;
}
if (pATIHW->crtc == ATI_CRTC_VGA)
{
Index = pATIHW->attr[17] * 3;
pATIHW->lut[Index + 0] =
pATIHW->lut[Index + 1] =
pATIHW->lut[Index + 2] = 0x00U;
}
#endif
}
}
void
ATIDACSave
(
ATIPtr pATI,
ATIHWPtr pATIHW
)
{
int Index;
#ifdef AVOID_CPIO
pATIHW->dac_read = in8(M64_DAC_READ);
DACDelay;
pATIHW->dac_write = in8(M64_DAC_WRITE);
DACDelay;
pATIHW->dac_mask = in8(M64_DAC_MASK);
DACDelay;
out8(M64_DAC_MASK, 0xFFU);
DACDelay;
out8(M64_DAC_READ, 0x00U);
DACDelay;
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
{
pATIHW->lut[Index] = in8(M64_DAC_DATA);
DACDelay;
}
out8(M64_DAC_MASK, pATIHW->dac_mask);
DACDelay;
out8(M64_DAC_READ, pATIHW->dac_read);
DACDelay;
#else
ATISetDACIOPorts(pATI, pATIHW->crtc);
pATIHW->dac_read = inb(pATI->CPIO_DAC_READ);
DACDelay;
pATIHW->dac_write = inb(pATI->CPIO_DAC_WRITE);
DACDelay;
pATIHW->dac_mask = inb(pATI->CPIO_DAC_MASK);
DACDelay;
outb(pATI->CPIO_DAC_MASK, 0xFFU);
DACDelay;
outb(pATI->CPIO_DAC_READ, 0x00U);
DACDelay;
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
{
pATIHW->lut[Index] = inb(pATI->CPIO_DAC_DATA);
DACDelay;
}
outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
DACDelay;
outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
DACDelay;
#endif
}
void
ATIDACSet
(
ATIPtr pATI,
ATIHWPtr pATIHW
)
{
int Index;
#ifdef AVOID_CPIO
out8(M64_DAC_MASK, 0xFFU);
DACDelay;
out8(M64_DAC_WRITE, 0x00U);
DACDelay;
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
{
out8(M64_DAC_DATA, pATIHW->lut[Index]);
DACDelay;
}
out8(M64_DAC_MASK, pATIHW->dac_mask);
DACDelay;
out8(M64_DAC_READ, pATIHW->dac_read);
DACDelay;
out8(M64_DAC_WRITE, pATIHW->dac_write);
DACDelay;
#else
ATISetDACIOPorts(pATI, pATIHW->crtc);
outb(pATI->CPIO_DAC_MASK, 0xFFU);
DACDelay;
outb(pATI->CPIO_DAC_WRITE, 0x00U);
DACDelay;
for (Index = 0; Index < NumberOf(pATIHW->lut); Index++)
{
outb(pATI->CPIO_DAC_DATA, pATIHW->lut[Index]);
DACDelay;
}
outb(pATI->CPIO_DAC_MASK, pATIHW->dac_mask);
DACDelay;
outb(pATI->CPIO_DAC_READ, pATIHW->dac_read);
DACDelay;
outb(pATI->CPIO_DAC_WRITE, pATIHW->dac_write);
DACDelay;
#endif
}
void
ATILoadPalette
(
ScrnInfoPtr pScreenInfo,
int nColours,
int *Indices,
LOCO *Colours,
VisualPtr pVisual
)
{
ATIPtr pATI = ATIPTR(pScreenInfo);
CARD8 *LUTEntry;
int i, j, Index;
if (((pVisual->class | DynamicClass) == DirectColor) &&
((1 << pVisual->nplanes) > (SizeOf(pATI->NewHW.lut) / 3)))
{
int reds = pVisual->redMask >> pVisual->offsetRed;
int greens = pVisual->greenMask >> pVisual->offsetGreen;
int blues = pVisual->blueMask >> pVisual->offsetBlue;
int redShift = 8 - pATI->weight.red;
int greenShift = 8 - pATI->weight.green;
int blueShift = 8 - pATI->weight.blue;
int redMult = 3 << redShift;
int greenMult = 3 << greenShift;
int blueMult = 3 << blueShift;
int minShift;
CARD8 fChanged[SizeOf(pATI->NewHW.lut) / 3];
(void)memset(fChanged, SizeOf(fChanged), 0);
minShift = redShift;
if (minShift > greenShift)
minShift = greenShift;
if (minShift > blueShift)
minShift = blueShift;
for (i = 0; i < nColours; i++)
{
if((Index = Indices[i]) < 0)
continue;
if (Index <= reds)
{
j = Index * redMult;
pATI->NewHW.lut[j + 0] = Colours[Index].red;
fChanged[j / 3] = TRUE;
}
if (Index <= greens)
{
j = Index * greenMult;
pATI->NewHW.lut[j + 1] = Colours[Index].green;
fChanged[j / 3] = TRUE;
}
if (Index <= blues)
{
j = Index * blueMult;
pATI->NewHW.lut[j + 2] = Colours[Index].blue;
fChanged[j / 3] = TRUE;
}
}
if (pScreenInfo->vtSema || pATI->currentMode)
{
i = 1 << minShift;
LUTEntry = pATI->NewHW.lut;
for (Index = 0;
Index < (SizeOf(pATI->NewHW.lut) / 3);
Index += i, LUTEntry += i * 3)
{
if (!fChanged[Index])
continue;
#ifdef AVOID_CPIO
out8(M64_DAC_WRITE, Index);
DACDelay;
out8(M64_DAC_DATA, LUTEntry[0]);
DACDelay;
out8(M64_DAC_DATA, LUTEntry[1]);
DACDelay;
out8(M64_DAC_DATA, LUTEntry[2]);
DACDelay;
#else
outb(pATI->CPIO_DAC_WRITE, Index);
DACDelay;
outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
DACDelay;
outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
DACDelay;
outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
DACDelay;
#endif
}
}
}
else
{
for (i = 0; i < nColours; i++)
{
Index = Indices[i];
if ((Index < 0) || (Index >= (SizeOf(pATI->NewHW.lut) / 3)))
continue;
LUTEntry = &pATI->NewHW.lut[Index * 3];
LUTEntry[0] = Colours[Index].red;
LUTEntry[1] = Colours[Index].green;
LUTEntry[2] = Colours[Index].blue;
if (pScreenInfo->vtSema || pATI->currentMode)
{
#ifdef AVOID_CPIO
out8(M64_DAC_WRITE, Index);
DACDelay;
out8(M64_DAC_DATA, LUTEntry[0]);
DACDelay;
out8(M64_DAC_DATA, LUTEntry[1]);
DACDelay;
out8(M64_DAC_DATA, LUTEntry[2]);
DACDelay;
#else
outb(pATI->CPIO_DAC_WRITE, Index);
DACDelay;
outb(pATI->CPIO_DAC_DATA, LUTEntry[0]);
DACDelay;
outb(pATI->CPIO_DAC_DATA, LUTEntry[1]);
DACDelay;
outb(pATI->CPIO_DAC_DATA, LUTEntry[2]);
DACDelay;
#endif
}
}
}
}