diff options
Diffstat (limited to 'src/emu/video/tlc34076.c')
-rw-r--r-- | src/emu/video/tlc34076.c | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/src/emu/video/tlc34076.c b/src/emu/video/tlc34076.c new file mode 100644 index 00000000000..a750dd334ad --- /dev/null +++ b/src/emu/video/tlc34076.c @@ -0,0 +1,262 @@ +/*************************************************************************** + + 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; + + +#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 + + + +/************************************* + * + * Palette update + * + *************************************/ + +static void update_palette(int which) +{ + int totalcolors = (Machine->drv->total_colors <= 256) ? Machine->drv->total_colors : 256; + int i, mask = regs[PIXEL_READ_MASK]; + + for (i = 0; i < totalcolors; i++) + if (which == -1 || (i & mask) == which) + { + int r = local_paletteram[3 * i + 0]; + int g = local_paletteram[3 * i + 1]; + int b = local_paletteram[3 * i + 2]; + if (dacbits == 6) + { + r = pal6bit(r); + g = pal6bit(g); + b = pal6bit(b); + } + palette_set_color(Machine, i, MAKE_RGB(r, g, b)); + } +} + + + +/************************************* + * + * State reset + * + *************************************/ + +void tlc34076_reset(int dacwidth) +{ + /* set the DAC width */ + dacbits = dacwidth; + if (dacbits != 6 && dacbits != 8) + { + logerror("tlc34076_reset: dacwidth must be 6 or 8!\n"); + dacbits = 6; + } + + /* 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]; + update_palette(regs[PALETTE_WRITE_ADDR]); + 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 PIXEL_READ_MASK: + case PALETTE_PAGE: + update_palette(-1); + 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); +} + |