// license:BSD-3-Clause
// copyright-holders:David Haywood
/* Inder / Dinamic Video */
#include "emu.h"
#include "machine/inder_vid.h"
#include "screen.h"
DEFINE_DEVICE_TYPE(INDER_VIDEO, inder_vid_device, "indervd", "Inder / Dinamic TMS Video")
inder_vid_device::inder_vid_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, INDER_VIDEO, tag, owner, clock),
/* device_video_interface(mconfig, *this, false), */
m_vram(*this, "vram"),
m_palette(*this, "palette"),
m_tms(*this, "tms"),
m_bpp_mode(8)
{
}
void inder_vid_device::megaphx_tms_map(address_map &map)
{
map(0x00000000, 0x003fffff).ram().share(m_vram); // vram?
map(0x04000000, 0x0400000f).w("ramdac", FUNC(ramdac_device::index_w)).umask16(0x00ff);
map(0x04000010, 0x0400001f).rw("ramdac", FUNC(ramdac_device::pal_r), FUNC(ramdac_device::pal_w)).umask16(0x00ff);
map(0x04000030, 0x0400003f).w("ramdac", FUNC(ramdac_device::index_r_w)).umask16(0x00ff);
map(0x04000090, 0x0400009f).nopw();
map(0x7fc00000, 0x7fffffff).ram().mirror(0x80000000);
}
TMS340X0_SCANLINE_RGB32_CB_MEMBER(inder_vid_device::scanline)
{
uint16_t *vram = &m_vram[(params->rowaddr << 8) & 0x3ff00];
uint32_t *dest = &bitmap.pix32(scanline);
const pen_t *paldata = m_palette->pens();
int coladdr = params->coladdr;
int x;
if (m_bpp_mode == 8)
{
for (x = params->heblnk; x < params->hsblnk; x += 2)
{
uint16_t pixels = vram[coladdr++ & 0xff];
dest[x + 0] = paldata[pixels & 0xff];
dest[x + 1] = paldata[pixels >> 8];
}
}
else if (m_bpp_mode == 4)
{
for (x = params->heblnk; x < params->hsblnk; x += 4)
{
uint16_t pixels = vram[coladdr++ & 0xff];
dest[x + 3] = paldata[((pixels & 0xf000) >> 12)];
dest[x + 2] = paldata[((pixels & 0x0f00) >> 8)];
dest[x + 1] = paldata[((pixels & 0x00f0) >> 4)];
dest[x + 0] = paldata[((pixels & 0x000f) >> 0)];
}
}
else
{
fatalerror("inder_vid_device unsupported mode, not 4bpp or 8bpp");
}
}
TMS340X0_TO_SHIFTREG_CB_MEMBER(inder_vid_device::to_shiftreg)
{
if (m_shiftfull == 0)
{
//printf("read to shift regs address %08x\n", address);
memcpy(shiftreg, &m_vram[(address & ~0x1fff) >> 4], 0x400); // & ~0x1fff is needed for round 6
m_shiftfull = 1;
}
}
TMS340X0_FROM_SHIFTREG_CB_MEMBER(inder_vid_device::from_shiftreg)
{
// printf("write from shift regs address %08x\n", address);
memcpy(&m_vram[(address & ~0x1fff) >> 4], shiftreg, 0x400);
m_shiftfull = 0;
}
void inder_vid_device::ramdac_map(address_map &map)
{
map(0x000, 0x3ff).rw("ramdac", FUNC(ramdac_device::ramdac_pal_r), FUNC(ramdac_device::ramdac_rgb888_w));
}
void inder_vid_device::device_add_mconfig(machine_config &config)
{
TMS34010(config, m_tms, XTAL(40'000'000));
m_tms->set_addrmap(AS_PROGRAM, &inder_vid_device::megaphx_tms_map);
m_tms->set_halt_on_reset(true);
m_tms->set_pixel_clock(XTAL(40'000'000)/12);
m_tms->set_pixels_per_clock(2);
m_tms->set_scanline_rgb32_callback(FUNC(inder_vid_device::scanline));
m_tms->output_int().set_inputline(":maincpu", 4);
m_tms->set_shiftreg_in_callback(FUNC(inder_vid_device::to_shiftreg));
m_tms->set_shiftreg_out_callback(FUNC(inder_vid_device::from_shiftreg));
screen_device &screen(SCREEN(config, "inder_screen", SCREEN_TYPE_RASTER));
screen.set_raw(XTAL(40'000'000)/12, 424, 0, 338-1, 262, 0, 246-1);
screen.set_screen_update("tms", FUNC(tms34010_device::tms340x0_rgb32));
PALETTE(config, m_palette).set_entries(256);
ramdac_device &ramdac(RAMDAC(config, "ramdac", 0, m_palette));
ramdac.set_addrmap(0, &inder_vid_device::ramdac_map);
ramdac.set_split_read(1);
}
void inder_vid_device::device_start()
{
save_item(NAME(m_shiftfull));
}
void inder_vid_device::device_reset()
{
m_shiftfull = 0;
}