mame/src/emu/video/tlc34076.c
Zsolt Vasvari 171060dca7 - Changed TLC34076 and games using it to RGB32
- Removed global Machine variable where possible
2008-01-14 02:38:35 +00:00

267 lines
6.1 KiB
C

/***************************************************************************
tlc34076.c
Basic implementation of the TLC34076 palette chip and similar
compatible chips.
***************************************************************************/
#include "driver.h"
#include "tlc34076.h"
static UINT8 local_paletteram[0x300];
static UINT8 regs[0x10];
static UINT8 palettedata[3];
static UINT8 writeindex, readindex;
static UINT8 dacbits;
static rgb_t pens[0x100];
#define PALETTE_WRITE_ADDR 0x00
#define PALETTE_DATA 0x01
#define PIXEL_READ_MASK 0x02
#define PALETTE_READ_ADDR 0x03
#define GENERAL_CONTROL 0x08
#define INPUT_CLOCK_SEL 0x09
#define OUTPUT_CLOCK_SEL 0x0a
#define MUX_CONTROL 0x0b
#define PALETTE_PAGE 0x0c
#define TEST_REGISTER 0x0e
#define RESET_STATE 0x0f
/*************************************
*
* Retrieve Current Palette
*
*************************************/
pen_t *tlc34076_get_pens(void)
{
offs_t i;
for (i = 0; i < 0x100; i++)
{
int r, g, b;
if ((i & regs[PIXEL_READ_MASK]) == i)
{
r = local_paletteram[3 * i + 0];
g = local_paletteram[3 * i + 1];
b = local_paletteram[3 * i + 2];
if (dacbits == 6)
{
r = pal6bit(r);
g = pal6bit(g);
b = pal6bit(b);
}
}
else
{
r = 0;
g = 0;
b = 0;
}
pens[i] = MAKE_RGB(r, g, b);
}
return pens;
}
/*************************************
*
* State reset
*
*************************************/
void tlc34076_reset(int dacwidth)
{
assert_always((dacbits == 6) || (dacbits != 8), "tlc34076_reset: dacwidth must be 6 or 8!");
dacbits = dacwidth;
/* reset the registers */
regs[PIXEL_READ_MASK] = 0xff;
regs[GENERAL_CONTROL] = 0x03;
regs[INPUT_CLOCK_SEL] = 0x00;
regs[OUTPUT_CLOCK_SEL] = 0x3f;
regs[MUX_CONTROL] = 0x2d;
regs[PALETTE_PAGE] = 0x00;
regs[TEST_REGISTER] = 0x00;
regs[RESET_STATE] = 0x00;
}
/*************************************
*
* Read access
*
*************************************/
READ8_HANDLER( tlc34076_r )
{
UINT8 result;
/* keep in range */
offset &= 0x0f;
result = regs[offset];
/* switch off the offset */
switch (offset)
{
case PALETTE_DATA:
if (readindex == 0)
{
palettedata[0] = local_paletteram[3 * regs[PALETTE_READ_ADDR] + 0];
palettedata[1] = local_paletteram[3 * regs[PALETTE_READ_ADDR] + 1];
palettedata[2] = local_paletteram[3 * regs[PALETTE_READ_ADDR] + 2];
}
result = palettedata[readindex++];
if (readindex == 3)
{
readindex = 0;
regs[PALETTE_READ_ADDR]++;
}
break;
}
return result;
}
/*************************************
*
* Write access
*
*************************************/
WRITE8_HANDLER( tlc34076_w )
{
UINT8 oldval;
/* keep in range */
offset &= 0x0f;
oldval = regs[offset];
regs[offset] = data;
/* switch off the offset */
switch (offset)
{
case PALETTE_WRITE_ADDR:
writeindex = 0;
break;
case PALETTE_DATA:
palettedata[writeindex++] = data;
if (writeindex == 3)
{
local_paletteram[3 * regs[PALETTE_WRITE_ADDR] + 0] = palettedata[0];
local_paletteram[3 * regs[PALETTE_WRITE_ADDR] + 1] = palettedata[1];
local_paletteram[3 * regs[PALETTE_WRITE_ADDR] + 2] = palettedata[2];
writeindex = 0;
regs[PALETTE_WRITE_ADDR]++;
}
break;
case PALETTE_READ_ADDR:
readindex = 0;
break;
case GENERAL_CONTROL:
/*
7 6 5 4 3 2 1 0
X X X X X X X 0 HSYNCOUT is active-low
X X X X X X X 1 HSYNCOUT is active-high (default)
X X X X X X 0 X VSYNCOUT is active-low
X X X X X X 1 X VSYNCOUT is active-high (default)
X X X X X 0 X X Disable split shift register transfer (default)
X X X X 0 1 X X Enable split shift register transfer
X X X X 0 X X X Disable special nibble mode (default)
X X X X 1 0 X X Enable special nibble mode
X X X 0 X X X X 0-IRE pedestal (default)
X X X 1 X X X X 7.5-IRE pedestal
X X 0 X X X X X Disable sync (default)
X X 1 X X X X X Enable sync
X 0 X X X X X X Little-endian mode (default)
X 1 X X X X X X Big-endian mode
0 X X X X X X X MUXOUT is low (default)
1 X X X X X X X MUXOUT is high
*/
break;
case INPUT_CLOCK_SEL:
/*
3 2 1 0
0 0 0 0 Select CLK0 as clock source?
0 0 0 1 Select CLK1 as clock source
0 0 1 0 Select CLK2 as clock source
0 0 1 1 Select CLK3 as TTL clock source
0 1 0 0 Select CLK3 as TTL clock source
1 0 0 0 Select CLK3 and CLK3 as ECL clock sources
*/
break;
case OUTPUT_CLOCK_SEL:
/*
0 0 0 X X X VCLK frequency = DOTCLK frequency
0 0 1 X X X VCLK frequency = DOTCLK frequency/2
0 1 0 X X X VCLK frequency = DOTCLK frequency/4
0 1 1 X X X VCLK frequency = DOTCLK frequency/8
1 0 0 X X X VCLK frequency = DOTCLK frequency/16
1 0 1 X X X VCLK frequency = DOTCLK frequency/32
1 1 X X X X VCLK output held at logic high level (default condition)
X X X 0 0 0 SCLK frequency = DOTCLK frequency
X X X 0 0 1 SCLK frequency = DOTCLK frequency/2
X X X 0 1 0 SCLK frequency = DOTCLK frequency/4
X X X 0 1 1 SCLK frequency = DOTCLK frequency/8
X X X 1 0 0 SCLK frequency = DOTCLK frequency/16
X X X 1 0 1 SCLK frequency = DOTCLK frequency/32
X X X 1 1 X SCLK output held at logic level low (default condition)
*/
break;
case RESET_STATE:
tlc34076_reset(dacbits);
break;
}
}
/*************************************
*
* 16-bit accessors
*
*************************************/
READ16_HANDLER( tlc34076_lsb_r )
{
return tlc34076_r(offset);
}
WRITE16_HANDLER( tlc34076_lsb_w )
{
if (ACCESSING_LSB)
tlc34076_w(offset, data);
}
READ16_HANDLER( tlc34076_msb_r )
{
return tlc34076_r(offset) << 8;
}
WRITE16_HANDLER( tlc34076_msb_w )
{
if (ACCESSING_MSB)
tlc34076_w(offset, data >> 8);
}