Converted tms34061 to be a device. [Osso]

This commit is contained in:
Scott Stone 2013-07-09 15:42:43 +00:00
parent 2be523bf03
commit 998ca07752
12 changed files with 419 additions and 393 deletions

View File

@ -440,11 +440,8 @@ void _class :: _name(::address_map &map, device_t &device) \
// legacy space writes
#define AM_WRITE_LEGACY(_handler) \
curentry->set_handler(_handler, #_handler);
#define AM_WRITE8_LEGACY(_handler, _unitmask) \
curentry->set_handler(_handler, #_handler, _unitmask);
// legacy space reads/writes
#define AM_READWRITE_LEGACY(_rhandler, _whandler) \
curentry->set_handler(_rhandler, #_rhandler, _whandler, #_whandler);

View File

@ -17,28 +17,115 @@
#define VERBOSE (0)
/*************************************
*
* Internal structure
*
*************************************/
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
struct tms34061_data
//-------------------------------------------------
// tms34061_device - constructor
//-------------------------------------------------
const device_type TMS34061 = &device_creator<tms34061_device>;
tms34061_device::tms34061_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
: device_t(mconfig, TMS34061, "tms34061", tag, owner, clock, "tms34061", __FILE__),
//m_regs[TMS34061_REGCOUNT],
m_xmask(0),
m_yshift(0),
m_vrammask(0),
m_vram(NULL),
m_latchram(NULL),
m_latchdata(0),
m_shiftreg(NULL),
m_timer(NULL)
//m_display.blanked(0),
//m_display.vram(NULL),
//m_display.latchram(NULL),
//m_display.regs(NULL),
//m_display.dispstart(0),
//m_display.screen(NULL)
{
UINT16 regs[TMS34061_REGCOUNT];
UINT16 xmask;
UINT8 yshift;
UINT32 vrammask;
UINT8 * vram;
UINT8 * latchram;
UINT8 latchdata;
UINT8 * shiftreg;
emu_timer * timer;
struct tms34061_interface intf;
screen_device *screen;
};
}
//-------------------------------------------------
// device_config_complete - perform any
// operations now that the configuration is
// complete
//-------------------------------------------------
void tms34061_device::device_config_complete()
{
// inherit a copy of the static data
const tms34061_interface *intf = reinterpret_cast<const tms34061_interface *>(static_config());
if (intf != NULL)
*static_cast<tms34061_interface *>(this) = *intf;
// or initialize to defaults if none provided
else
{
m_screen_tag = "";
m_rowshift = 0;
m_vramsize = 0;
//(*m_interrupt)(int state)
}
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void tms34061_device::device_start()
{
/* reset the data */
m_screen = machine().device<screen_device>(m_screen_tag);
m_vrammask = m_vramsize - 1;
/* allocate memory for VRAM */
m_vram = auto_alloc_array_clear(machine(), UINT8, m_vramsize + 256 * 2);
/* not really a save state, just there for debugging purposes */
machine().save().save_pointer(NAME(m_vram), m_vramsize);
/* allocate memory for latch RAM */
m_latchram = auto_alloc_array_clear(machine(), UINT8, m_vramsize + 256 * 2);
/* add some buffer space for VRAM and latch RAM */
m_vram += 256;
m_latchram += 256;
/* point the shift register to the base of VRAM for now */
m_shiftreg = m_vram;
/* initialize registers to their default values from the manual */
m_regs[TMS34061_HORENDSYNC] = 0x0010;
m_regs[TMS34061_HORENDBLNK] = 0x0020;
m_regs[TMS34061_HORSTARTBLNK] = 0x01f0;
m_regs[TMS34061_HORTOTAL] = 0x0200;
m_regs[TMS34061_VERENDSYNC] = 0x0004;
m_regs[TMS34061_VERENDBLNK] = 0x0010;
m_regs[TMS34061_VERSTARTBLNK] = 0x00f0;
m_regs[TMS34061_VERTOTAL] = 0x0100;
m_regs[TMS34061_DISPUPDATE] = 0x0000;
m_regs[TMS34061_DISPSTART] = 0x0000;
m_regs[TMS34061_VERINT] = 0x0000;
m_regs[TMS34061_CONTROL1] = 0x7000;
m_regs[TMS34061_CONTROL2] = 0x0600;
m_regs[TMS34061_STATUS] = 0x0000;
m_regs[TMS34061_XYOFFSET] = 0x0010;
m_regs[TMS34061_XYADDRESS] = 0x0000;
m_regs[TMS34061_DISPADDRESS] = 0x0000;
m_regs[TMS34061_VERCOUNTER] = 0x0000;
/* start vertical interrupt timer */
m_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(tms34061_device::interrupt), this));
}
//-------------------------------------------------
// device_reset - device-specific reset
//-------------------------------------------------
void tms34061_device::device_reset()
{
}
/*************************************
*
@ -46,8 +133,6 @@ struct tms34061_data
*
*************************************/
static struct tms34061_data tms34061;
static const char *const regnames[] =
{
"HORENDSYNC", "HORENDBLNK", "HORSTARTBLNK", "HORTOTAL",
@ -58,99 +143,33 @@ static const char *const regnames[] =
};
/*************************************
*
* Prototypes
*
*************************************/
static TIMER_CALLBACK( tms34061_interrupt );
/*************************************
*
* Hardware startup
*
*************************************/
void tms34061_start(running_machine &machine, const struct tms34061_interface *interface)
{
/* reset the data */
memset(&tms34061, 0, sizeof(tms34061));
tms34061.intf = *interface;
tms34061.screen = downcast<screen_device *>(machine.device(tms34061.intf.screen_tag));
tms34061.vrammask = tms34061.intf.vramsize - 1;
/* allocate memory for VRAM */
tms34061.vram = auto_alloc_array_clear(machine, UINT8, tms34061.intf.vramsize + 256 * 2);
/* not really a save state, just there for debugging purposes */
machine.save().save_pointer(NAME(tms34061.vram), tms34061.intf.vramsize);
/* allocate memory for latch RAM */
tms34061.latchram = auto_alloc_array_clear(machine, UINT8, tms34061.intf.vramsize + 256 * 2);
/* add some buffer space for VRAM and latch RAM */
tms34061.vram += 256;
tms34061.latchram += 256;
/* point the shift register to the base of VRAM for now */
tms34061.shiftreg = tms34061.vram;
/* initialize registers to their default values from the manual */
tms34061.regs[TMS34061_HORENDSYNC] = 0x0010;
tms34061.regs[TMS34061_HORENDBLNK] = 0x0020;
tms34061.regs[TMS34061_HORSTARTBLNK] = 0x01f0;
tms34061.regs[TMS34061_HORTOTAL] = 0x0200;
tms34061.regs[TMS34061_VERENDSYNC] = 0x0004;
tms34061.regs[TMS34061_VERENDBLNK] = 0x0010;
tms34061.regs[TMS34061_VERSTARTBLNK] = 0x00f0;
tms34061.regs[TMS34061_VERTOTAL] = 0x0100;
tms34061.regs[TMS34061_DISPUPDATE] = 0x0000;
tms34061.regs[TMS34061_DISPSTART] = 0x0000;
tms34061.regs[TMS34061_VERINT] = 0x0000;
tms34061.regs[TMS34061_CONTROL1] = 0x7000;
tms34061.regs[TMS34061_CONTROL2] = 0x0600;
tms34061.regs[TMS34061_STATUS] = 0x0000;
tms34061.regs[TMS34061_XYOFFSET] = 0x0010;
tms34061.regs[TMS34061_XYADDRESS] = 0x0000;
tms34061.regs[TMS34061_DISPADDRESS] = 0x0000;
tms34061.regs[TMS34061_VERCOUNTER] = 0x0000;
/* start vertical interrupt timer */
tms34061.timer = machine.scheduler().timer_alloc(FUNC(tms34061_interrupt));
}
/*************************************
*
* Interrupt handling
*
*************************************/
INLINE void update_interrupts(void)
void tms34061_device::update_interrupts()
{
/* if we have a callback, process it */
if (tms34061.intf.interrupt)
if (m_interrupt)
{
/* if the status bit is set, and ints are enabled, turn it on */
if ((tms34061.regs[TMS34061_STATUS] & 0x0001) && (tms34061.regs[TMS34061_CONTROL1] & 0x0400))
(*tms34061.intf.interrupt)(tms34061.screen->machine(), ASSERT_LINE);
if ((m_regs[TMS34061_STATUS] & 0x0001) && (m_regs[TMS34061_CONTROL1] & 0x0400))
(*m_interrupt)(m_screen->machine(), ASSERT_LINE);
else
(*tms34061.intf.interrupt)(tms34061.screen->machine(), CLEAR_LINE);
(*m_interrupt)(m_screen->machine(), CLEAR_LINE);
}
}
static TIMER_CALLBACK( tms34061_interrupt )
TIMER_CALLBACK_MEMBER( tms34061_device::interrupt )
{
/* set timer for next frame */
tms34061.timer->adjust(tms34061.screen->frame_period());
m_timer->adjust(m_screen->frame_period());
/* set the interrupt bit in the status reg */
tms34061.regs[TMS34061_STATUS] |= 1;
m_regs[TMS34061_STATUS] |= 1;
/* update the interrupt state */
update_interrupts();
@ -164,7 +183,7 @@ static TIMER_CALLBACK( tms34061_interrupt )
*
*************************************/
static void register_w(address_space &space, offs_t offset, UINT8 data)
void tms34061_device::register_w(address_space &space, offs_t offset, UINT8 data)
{
int scanline;
int regnum = offset >> 2;
@ -172,48 +191,48 @@ static void register_w(address_space &space, offs_t offset, UINT8 data)
/* certain registers affect the display directly */
if ((regnum >= TMS34061_HORENDSYNC && regnum <= TMS34061_DISPSTART) ||
(regnum == TMS34061_CONTROL2))
tms34061.screen->update_partial(tms34061.screen->vpos());
m_screen->update_partial(m_screen->vpos());
/* store the hi/lo half */
if (regnum < ARRAY_LENGTH(tms34061.regs))
if (regnum < ARRAY_LENGTH(m_regs))
{
if (offset & 0x02)
tms34061.regs[regnum] = (tms34061.regs[regnum] & 0x00ff) | (data << 8);
m_regs[regnum] = (m_regs[regnum] & 0x00ff) | (data << 8);
else
tms34061.regs[regnum] = (tms34061.regs[regnum] & 0xff00) | data;
m_regs[regnum] = (m_regs[regnum] & 0xff00) | data;
}
/* log it */
if (VERBOSE) logerror("%s:tms34061 %s = %04x\n", space.machine().describe_context(), regnames[regnum], tms34061.regs[regnum]);
if (VERBOSE) logerror("%s:tms34061 %s = %04x\n", space.machine().describe_context(), regnames[regnum], m_regs[regnum]);
/* update the state of things */
switch (regnum)
{
/* vertical interrupt: adjust the timer */
case TMS34061_VERINT:
scanline = tms34061.regs[TMS34061_VERINT] - tms34061.regs[TMS34061_VERENDBLNK];
scanline = m_regs[TMS34061_VERINT] - m_regs[TMS34061_VERENDBLNK];
if (scanline < 0)
scanline += tms34061.regs[TMS34061_VERTOTAL];
scanline += m_regs[TMS34061_VERTOTAL];
tms34061.timer->adjust(tms34061.screen->time_until_pos(scanline, tms34061.regs[TMS34061_HORSTARTBLNK]));
m_timer->adjust(m_screen->time_until_pos(scanline, m_regs[TMS34061_HORSTARTBLNK]));
break;
/* XY offset: set the X and Y masks */
case TMS34061_XYOFFSET:
switch (tms34061.regs[TMS34061_XYOFFSET] & 0x00ff)
switch (m_regs[TMS34061_XYOFFSET] & 0x00ff)
{
case 0x01: tms34061.yshift = 2; break;
case 0x02: tms34061.yshift = 3; break;
case 0x04: tms34061.yshift = 4; break;
case 0x08: tms34061.yshift = 5; break;
case 0x10: tms34061.yshift = 6; break;
case 0x20: tms34061.yshift = 7; break;
case 0x40: tms34061.yshift = 8; break;
case 0x80: tms34061.yshift = 9; break;
default: logerror("Invalid value for XYOFFSET = %04x\n", tms34061.regs[TMS34061_XYOFFSET]); break;
case 0x01: m_yshift = 2; break;
case 0x02: m_yshift = 3; break;
case 0x04: m_yshift = 4; break;
case 0x08: m_yshift = 5; break;
case 0x10: m_yshift = 6; break;
case 0x20: m_yshift = 7; break;
case 0x40: m_yshift = 8; break;
case 0x80: m_yshift = 9; break;
default: logerror("Invalid value for XYOFFSET = %04x\n", m_regs[TMS34061_XYOFFSET]); break;
}
tms34061.xmask = (1 << tms34061.yshift) - 1;
m_xmask = (1 << m_yshift) - 1;
break;
/* CONTROL1: they could have turned interrupts on */
@ -235,14 +254,14 @@ static void register_w(address_space &space, offs_t offset, UINT8 data)
*
*************************************/
static UINT8 register_r(address_space &space, offs_t offset)
UINT8 tms34061_device::register_r(address_space &space, offs_t offset)
{
int regnum = offset >> 2;
UINT16 result;
/* extract the correct portion of the register */
if (regnum < ARRAY_LENGTH(tms34061.regs))
result = tms34061.regs[regnum];
if (regnum < ARRAY_LENGTH(m_regs))
result = m_regs[regnum];
else
result = 0xffff;
@ -251,13 +270,13 @@ static UINT8 register_r(address_space &space, offs_t offset)
{
/* status register: a read here clears it */
case TMS34061_STATUS:
tms34061.regs[TMS34061_STATUS] = 0;
m_regs[TMS34061_STATUS] = 0;
update_interrupts();
break;
/* vertical count register: return the current scanline */
case TMS34061_VERCOUNTER:
result = (tms34061.screen->vpos()+ tms34061.regs[TMS34061_VERENDBLNK]) % tms34061.regs[TMS34061_VERTOTAL];
result = (m_screen->vpos()+ m_regs[TMS34061_VERENDBLNK]) % m_regs[TMS34061_VERTOTAL];
break;
}
@ -274,7 +293,7 @@ static UINT8 register_r(address_space &space, offs_t offset)
*
*************************************/
INLINE void adjust_xyaddress(int offset)
void tms34061_device::adjust_xyaddress(int offset)
{
/* note that carries are allowed if the Y coordinate isn't being modified */
switch (offset & 0x1e)
@ -283,115 +302,115 @@ INLINE void adjust_xyaddress(int offset)
break;
case 0x02: /* X + 1 */
tms34061.regs[TMS34061_XYADDRESS]++;
m_regs[TMS34061_XYADDRESS]++;
break;
case 0x04: /* X - 1 */
tms34061.regs[TMS34061_XYADDRESS]--;
m_regs[TMS34061_XYADDRESS]--;
break;
case 0x06: /* X = 0 */
tms34061.regs[TMS34061_XYADDRESS] &= ~tms34061.xmask;
m_regs[TMS34061_XYADDRESS] &= ~m_xmask;
break;
case 0x08: /* Y + 1 */
tms34061.regs[TMS34061_XYADDRESS] += 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] += 1 << m_yshift;
break;
case 0x0a: /* X + 1, Y + 1 */
tms34061.regs[TMS34061_XYADDRESS] = (tms34061.regs[TMS34061_XYADDRESS] & ~tms34061.xmask) |
((tms34061.regs[TMS34061_XYADDRESS] + 1) & tms34061.xmask);
tms34061.regs[TMS34061_XYADDRESS] += 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] = (m_regs[TMS34061_XYADDRESS] & ~m_xmask) |
((m_regs[TMS34061_XYADDRESS] + 1) & m_xmask);
m_regs[TMS34061_XYADDRESS] += 1 << m_yshift;
break;
case 0x0c: /* X - 1, Y + 1 */
tms34061.regs[TMS34061_XYADDRESS] = (tms34061.regs[TMS34061_XYADDRESS] & ~tms34061.xmask) |
((tms34061.regs[TMS34061_XYADDRESS] - 1) & tms34061.xmask);
tms34061.regs[TMS34061_XYADDRESS] += 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] = (m_regs[TMS34061_XYADDRESS] & ~m_xmask) |
((m_regs[TMS34061_XYADDRESS] - 1) & m_xmask);
m_regs[TMS34061_XYADDRESS] += 1 << m_yshift;
break;
case 0x0e: /* X = 0, Y + 1 */
tms34061.regs[TMS34061_XYADDRESS] &= ~tms34061.xmask;
tms34061.regs[TMS34061_XYADDRESS] += 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] &= ~m_xmask;
m_regs[TMS34061_XYADDRESS] += 1 << m_yshift;
break;
case 0x10: /* Y - 1 */
tms34061.regs[TMS34061_XYADDRESS] -= 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] -= 1 << m_yshift;
break;
case 0x12: /* X + 1, Y - 1 */
tms34061.regs[TMS34061_XYADDRESS] = (tms34061.regs[TMS34061_XYADDRESS] & ~tms34061.xmask) |
((tms34061.regs[TMS34061_XYADDRESS] + 1) & tms34061.xmask);
tms34061.regs[TMS34061_XYADDRESS] -= 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] = (m_regs[TMS34061_XYADDRESS] & ~m_xmask) |
((m_regs[TMS34061_XYADDRESS] + 1) & m_xmask);
m_regs[TMS34061_XYADDRESS] -= 1 << m_yshift;
break;
case 0x14: /* X - 1, Y - 1 */
tms34061.regs[TMS34061_XYADDRESS] = (tms34061.regs[TMS34061_XYADDRESS] & ~tms34061.xmask) |
((tms34061.regs[TMS34061_XYADDRESS] - 1) & tms34061.xmask);
tms34061.regs[TMS34061_XYADDRESS] -= 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] = (m_regs[TMS34061_XYADDRESS] & ~m_xmask) |
((m_regs[TMS34061_XYADDRESS] - 1) & m_xmask);
m_regs[TMS34061_XYADDRESS] -= 1 << m_yshift;
break;
case 0x16: /* X = 0, Y - 1 */
tms34061.regs[TMS34061_XYADDRESS] &= ~tms34061.xmask;
tms34061.regs[TMS34061_XYADDRESS] -= 1 << tms34061.yshift;
m_regs[TMS34061_XYADDRESS] &= ~m_xmask;
m_regs[TMS34061_XYADDRESS] -= 1 << m_yshift;
break;
case 0x18: /* Y = 0 */
tms34061.regs[TMS34061_XYADDRESS] &= tms34061.xmask;
m_regs[TMS34061_XYADDRESS] &= m_xmask;
break;
case 0x1a: /* X + 1, Y = 0 */
tms34061.regs[TMS34061_XYADDRESS]++;
tms34061.regs[TMS34061_XYADDRESS] &= tms34061.xmask;
m_regs[TMS34061_XYADDRESS]++;
m_regs[TMS34061_XYADDRESS] &= m_xmask;
break;
case 0x1c: /* X - 1, Y = 0 */
tms34061.regs[TMS34061_XYADDRESS]--;
tms34061.regs[TMS34061_XYADDRESS] &= tms34061.xmask;
m_regs[TMS34061_XYADDRESS]--;
m_regs[TMS34061_XYADDRESS] &= m_xmask;
break;
case 0x1e: /* X = 0, Y = 0 */
tms34061.regs[TMS34061_XYADDRESS] = 0;
m_regs[TMS34061_XYADDRESS] = 0;
break;
}
}
static void xypixel_w(address_space &space, int offset, UINT8 data)
void tms34061_device::xypixel_w(address_space &space, int offset, UINT8 data)
{
/* determine the offset, then adjust it */
offs_t pixeloffs = tms34061.regs[TMS34061_XYADDRESS];
offs_t pixeloffs = m_regs[TMS34061_XYADDRESS];
if (offset)
adjust_xyaddress(offset);
/* adjust for the upper bits */
pixeloffs |= (tms34061.regs[TMS34061_XYOFFSET] & 0x0f00) << 8;
pixeloffs |= (m_regs[TMS34061_XYOFFSET] & 0x0f00) << 8;
/* mask to the VRAM size */
pixeloffs &= tms34061.vrammask;
if (VERBOSE) logerror("%s:tms34061 xy (%04x) = %02x/%02x\n", space.machine().describe_context(), pixeloffs, data, tms34061.latchdata);
pixeloffs &= m_vrammask;
if (VERBOSE) logerror("%s:tms34061 xy (%04x) = %02x/%02x\n", space.machine().describe_context(), pixeloffs, data, m_latchdata);
/* set the pixel data */
tms34061.vram[pixeloffs] = data;
tms34061.latchram[pixeloffs] = tms34061.latchdata;
m_vram[pixeloffs] = data;
m_latchram[pixeloffs] = m_latchdata;
}
static UINT8 xypixel_r(address_space &space, int offset)
UINT8 tms34061_device::xypixel_r(address_space &space, int offset)
{
/* determine the offset, then adjust it */
offs_t pixeloffs = tms34061.regs[TMS34061_XYADDRESS];
offs_t pixeloffs = m_regs[TMS34061_XYADDRESS];
if (offset)
adjust_xyaddress(offset);
/* adjust for the upper bits */
pixeloffs |= (tms34061.regs[TMS34061_XYOFFSET] & 0x0f00) << 8;
pixeloffs |= (m_regs[TMS34061_XYOFFSET] & 0x0f00) << 8;
/* mask to the VRAM size */
pixeloffs &= tms34061.vrammask;
pixeloffs &= m_vrammask;
/* return the result */
return tms34061.vram[pixeloffs];
return m_vram[pixeloffs];
}
@ -402,7 +421,7 @@ static UINT8 xypixel_r(address_space &space, int offset)
*
*************************************/
void tms34061_w(address_space &space, int col, int row, int func, UINT8 data)
void tms34061_device::write(address_space &space, int col, int row, int func, UINT8 data)
{
offs_t offs;
@ -422,38 +441,38 @@ void tms34061_w(address_space &space, int col, int row, int func, UINT8 data)
/* function 3 maps to direct access */
case 3:
offs = ((row << tms34061.intf.rowshift) | col) & tms34061.vrammask;
if (tms34061.regs[TMS34061_CONTROL2] & 0x0040)
offs |= (tms34061.regs[TMS34061_CONTROL2] & 3) << 16;
if (VERBOSE) logerror("%s:tms34061 direct (%04x) = %02x/%02x\n", space.machine().describe_context(), offs, data, tms34061.latchdata);
if (tms34061.vram[offs] != data || tms34061.latchram[offs] != tms34061.latchdata)
offs = ((row << m_rowshift) | col) & m_vrammask;
if (m_regs[TMS34061_CONTROL2] & 0x0040)
offs |= (m_regs[TMS34061_CONTROL2] & 3) << 16;
if (VERBOSE) logerror("%s:tms34061 direct (%04x) = %02x/%02x\n", space.machine().describe_context(), offs, data, m_latchdata);
if (m_vram[offs] != data || m_latchram[offs] != m_latchdata)
{
tms34061.vram[offs] = data;
tms34061.latchram[offs] = tms34061.latchdata;
m_vram[offs] = data;
m_latchram[offs] = m_latchdata;
}
break;
/* function 4 performs a shift reg transfer to VRAM */
case 4:
offs = col << tms34061.intf.rowshift;
if (tms34061.regs[TMS34061_CONTROL2] & 0x0040)
offs |= (tms34061.regs[TMS34061_CONTROL2] & 3) << 16;
offs &= tms34061.vrammask;
offs = col << m_rowshift;
if (m_regs[TMS34061_CONTROL2] & 0x0040)
offs |= (m_regs[TMS34061_CONTROL2] & 3) << 16;
offs &= m_vrammask;
if (VERBOSE) logerror("%s:tms34061 shiftreg write (%04x)\n", space.machine().describe_context(), offs);
memcpy(&tms34061.vram[offs], tms34061.shiftreg, (size_t)1 << tms34061.intf.rowshift);
memset(&tms34061.latchram[offs], tms34061.latchdata, (size_t)1 << tms34061.intf.rowshift);
memcpy(&m_vram[offs], m_shiftreg, (size_t)1 << m_rowshift);
memset(&m_latchram[offs], m_latchdata, (size_t)1 << m_rowshift);
break;
/* function 5 performs a shift reg transfer from VRAM */
case 5:
offs = col << tms34061.intf.rowshift;
if (tms34061.regs[TMS34061_CONTROL2] & 0x0040)
offs |= (tms34061.regs[TMS34061_CONTROL2] & 3) << 16;
offs &= tms34061.vrammask;
offs = col << m_rowshift;
if (m_regs[TMS34061_CONTROL2] & 0x0040)
offs |= (m_regs[TMS34061_CONTROL2] & 3) << 16;
offs &= m_vrammask;
if (VERBOSE) logerror("%s:tms34061 shiftreg read (%04x)\n", space.machine().describe_context(), offs);
tms34061.shiftreg = &tms34061.vram[offs];
m_shiftreg = &m_vram[offs];
break;
/* log anything else */
@ -464,7 +483,7 @@ void tms34061_w(address_space &space, int col, int row, int func, UINT8 data)
}
UINT8 tms34061_r(address_space &space, int col, int row, int func)
UINT8 tms34061_device::read(address_space &space, int col, int row, int func)
{
int result = 0;
offs_t offs;
@ -485,29 +504,29 @@ UINT8 tms34061_r(address_space &space, int col, int row, int func)
/* funtion 3 maps to direct access */
case 3:
offs = ((row << tms34061.intf.rowshift) | col) & tms34061.vrammask;
result = tms34061.vram[offs];
offs = ((row << m_rowshift) | col) & m_vrammask;
result = m_vram[offs];
break;
/* function 4 performs a shift reg transfer to VRAM */
case 4:
offs = col << tms34061.intf.rowshift;
if (tms34061.regs[TMS34061_CONTROL2] & 0x0040)
offs |= (tms34061.regs[TMS34061_CONTROL2] & 3) << 16;
offs &= tms34061.vrammask;
offs = col << m_rowshift;
if (m_regs[TMS34061_CONTROL2] & 0x0040)
offs |= (m_regs[TMS34061_CONTROL2] & 3) << 16;
offs &= m_vrammask;
memcpy(&tms34061.vram[offs], tms34061.shiftreg, (size_t)1 << tms34061.intf.rowshift);
memset(&tms34061.latchram[offs], tms34061.latchdata, (size_t)1 << tms34061.intf.rowshift);
memcpy(&m_vram[offs], m_shiftreg, (size_t)1 << m_rowshift);
memset(&m_latchram[offs], m_latchdata, (size_t)1 << m_rowshift);
break;
/* function 5 performs a shift reg transfer from VRAM */
case 5:
offs = col << tms34061.intf.rowshift;
if (tms34061.regs[TMS34061_CONTROL2] & 0x0040)
offs |= (tms34061.regs[TMS34061_CONTROL2] & 3) << 16;
offs &= tms34061.vrammask;
offs = col << m_rowshift;
if (m_regs[TMS34061_CONTROL2] & 0x0040)
offs |= (m_regs[TMS34061_CONTROL2] & 3) << 16;
offs &= m_vrammask;
tms34061.shiftreg = &tms34061.vram[offs];
m_shiftreg = &m_vram[offs];
break;
/* log anything else */
@ -528,26 +547,26 @@ UINT8 tms34061_r(address_space &space, int col, int row, int func)
*
*************************************/
READ8_HANDLER( tms34061_latch_r )
READ8_MEMBER( tms34061_device::latch_r )
{
return tms34061.latchdata;
return m_latchdata;
}
WRITE8_HANDLER( tms34061_latch_w )
WRITE8_MEMBER( tms34061_device::latch_w )
{
if (VERBOSE) logerror("tms34061_latch = %02X\n", data);
tms34061.latchdata = data;
m_latchdata = data;
}
void tms34061_get_display_state(struct tms34061_display *state)
void tms34061_device::get_display_state()
{
state->blanked = (~tms34061.regs[TMS34061_CONTROL2] >> 13) & 1;
state->vram = tms34061.vram;
state->latchram = tms34061.latchram;
state->regs = tms34061.regs;
m_display.blanked = (~m_regs[TMS34061_CONTROL2] >> 13) & 1;
m_display.vram = m_vram;
m_display.latchram = m_latchram;
m_display.regs = m_regs;
/* compute the display start */
state->dispstart = (tms34061.regs[TMS34061_DISPSTART] << (tms34061.intf.rowshift - 2)) & tms34061.vrammask;
m_display.dispstart = (m_regs[TMS34061_DISPSTART] << (m_rowshift - 2)) & m_vrammask;
}

View File

@ -35,18 +35,15 @@ enum
TMS34061_REGCOUNT
};
/* interface structure */
struct tms34061_interface
{
const char *screen_tag; /* the screen we are acting on */
UINT8 rowshift; /* VRAM address is (row << rowshift) | col */
UINT32 vramsize; /* size of video RAM */
void (*interrupt)(running_machine &machine, int state); /* interrupt gen callback */
const char *m_screen_tag; /* the screen we are acting on */
UINT8 m_rowshift; /* VRAM address is (row << rowshift) | col */
UINT32 m_vramsize; /* size of video RAM */
void (*m_interrupt)(running_machine &machine, int state); /* interrupt gen callback */
};
/* display state structure */
struct tms34061_display
{
@ -58,18 +55,62 @@ struct tms34061_display
};
/* starts/stops the emulator */
void tms34061_start(running_machine &machine, const struct tms34061_interface *interface);
/* reads/writes to the 34061 */
UINT8 tms34061_r(address_space &space, int col, int row, int func);
void tms34061_w(address_space &space, int col, int row, int func, UINT8 data);
/* latch settings */
DECLARE_READ8_HANDLER( tms34061_latch_r );
DECLARE_WRITE8_HANDLER( tms34061_latch_w );
// ======================> tms34061_device
/* video update handling */
void tms34061_get_display_state(struct tms34061_display *state);
class tms34061_device : public device_t,
public tms34061_interface
{
public:
// construction/destruction
tms34061_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
/* reads/writes to the 34061 */
UINT8 read(address_space &space, int col, int row, int func);
void write(address_space &space, int col, int row, int func, UINT8 data);
/* latch settings */
DECLARE_READ8_MEMBER( latch_r );
DECLARE_WRITE8_MEMBER( latch_w );
/* video update handling */
void get_display_state();
struct tms34061_display m_display;
protected:
// device-level overrides
virtual void device_config_complete();
virtual void device_start();
virtual void device_reset();
private:
UINT16 m_regs[TMS34061_REGCOUNT];
UINT16 m_xmask;
UINT8 m_yshift;
UINT32 m_vrammask;
UINT8 * m_vram;
UINT8 * m_latchram;
UINT8 m_latchdata;
UINT8 * m_shiftreg;
emu_timer * m_timer;
screen_device *m_screen;
void update_interrupts(void);
TIMER_CALLBACK_MEMBER( interrupt );
void register_w(address_space &space, offs_t offset, UINT8 data);
UINT8 register_r(address_space &space, offs_t offset);
void adjust_xyaddress(int offset);
void xypixel_w(address_space &space, int offset, UINT8 data);
UINT8 xypixel_r(address_space &space, int offset);
};
// device type definition
extern const device_type TMS34061;
#define MCFG_TMS34061_ADD(_tag, _interface) \
MCFG_DEVICE_ADD(_tag, TMS34061, 0) \
MCFG_DEVICE_CONFIG(_interface)
#endif

View File

@ -334,6 +334,26 @@ static const ay8910_interface ay8910_config =
DEVCB_DEVICE_MEMBER("ticket", ticket_dispenser_device, write), /* Also a status LED. See memory map above */
};
/*************************************
*
* TMS34061 interfacing
*
*************************************/
static void generate_interrupt( running_machine &machine, int state )
{
capbowl_state *driver = machine.driver_data<capbowl_state>();
driver->m_maincpu->set_input_line(M6809_FIRQ_LINE, state);
}
static const struct tms34061_interface tms34061intf =
{
"screen", /* the screen we are acting on */
8, /* VRAM address is (row << rowshift) | col */
0x10000, /* size of video RAM */
generate_interrupt /* interrupt gen callback */
};
/*************************************
@ -380,6 +400,8 @@ static MACHINE_CONFIG_START( capbowl, capbowl_state )
MCFG_SCREEN_VISIBLE_AREA(0, 359, 0, 244)
MCFG_SCREEN_REFRESH_RATE(57)
MCFG_SCREEN_UPDATE_DRIVER(capbowl_state, screen_update_capbowl)
MCFG_TMS34061_ADD("tms34061", tms34061intf)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")

View File

@ -77,10 +77,13 @@ class guab_state : public driver_device
public:
guab_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_sn(*this, "snsnd") ,
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_tms34061(*this, "tms34061"),
m_sn(*this, "snsnd") { }
/* devices */
required_device<cpu_device> m_maincpu;
required_device<tms34061_device> m_tms34061;
required_device<sn76489_device> m_sn;
struct ef9369 m_pal;
@ -98,10 +101,8 @@ public:
DECLARE_WRITE_LINE_MEMBER(ptm_irq);
virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
UINT32 screen_update_guab(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(fdc_data_callback);
required_device<cpu_device> m_maincpu;
};
@ -162,10 +163,10 @@ WRITE16_MEMBER(guab_state::guab_tms34061_w)
col = offset <<= 1;
if (ACCESSING_BITS_8_15)
tms34061_w(space, col, row, func, data >> 8);
m_tms34061->write(space, col, row, func, data >> 8);
if (ACCESSING_BITS_0_7)
tms34061_w(space, col | 1, row, func, data & 0xff);
m_tms34061->write(space, col | 1, row, func, data & 0xff);
}
@ -182,10 +183,10 @@ READ16_MEMBER(guab_state::guab_tms34061_r)
col = offset <<= 1;
if (ACCESSING_BITS_8_15)
data |= tms34061_r(space, col, row, func) << 8;
data |= m_tms34061->read(space, col, row, func) << 8;
if (ACCESSING_BITS_0_7)
data |= tms34061_r(space, col | 1, row, func);
data |= m_tms34061->read(space, col | 1, row, func);
return data;
}
@ -256,22 +257,14 @@ READ16_MEMBER(guab_state::ef9369_r)
}
}
void guab_state::video_start()
{
tms34061_start(machine(), &tms34061intf);
}
UINT32 guab_state::screen_update_guab(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int x, y;
struct tms34061_display state;
tms34061_get_display_state(&state);
m_tms34061->get_display_state();
/* If blanked, fill with black */
if (state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -279,7 +272,7 @@ UINT32 guab_state::screen_update_guab(screen_device &screen, bitmap_ind16 &bitma
for (y = cliprect.min_y; y <= cliprect.max_y; ++y)
{
UINT8 *src = &state.vram[256 * y];
UINT8 *src = &m_tms34061->m_display.vram[256 * y];
UINT16 *dest = &bitmap.pix16(y);
for (x = cliprect.min_x; x <= cliprect.max_x; x += 2)
@ -831,7 +824,8 @@ static MACHINE_CONFIG_START( guab, guab_state )
MCFG_SCREEN_UPDATE_DRIVER(guab_state, screen_update_guab)
MCFG_PALETTE_LENGTH(16)
MCFG_TMS34061_ADD("tms34061", tms34061intf)
MCFG_SPEAKER_STANDARD_MONO("mono")

View File

@ -503,7 +503,6 @@
#include "machine/6522via.h"
#include "machine/nvram.h"
#include "machine/ticket.h"
#include "video/tms34061.h"
#include "video/tlc34076.h"
#include "includes/itech8.h"
#include "sound/2203intf.h"
@ -857,7 +856,7 @@ static ADDRESS_MAP_START( tmslo_map, AS_PROGRAM, 8, itech8_state )
AM_RANGE(0x1120, 0x1120) AM_WRITE(sound_data_w)
AM_RANGE(0x1140, 0x1140) AM_READ_PORT("40") AM_WRITE(grom_bank_w)
AM_RANGE(0x1160, 0x1160) AM_READ_PORT("60") AM_WRITE(itech8_page_w)
AM_RANGE(0x1180, 0x1180) AM_READ_PORT("80") AM_WRITE_LEGACY(tms34061_latch_w)
AM_RANGE(0x1180, 0x1180) AM_READ_PORT("80") AM_DEVWRITE("tms34061", tms34061_device, latch_w)
AM_RANGE(0x11a0, 0x11a0) AM_WRITE(itech8_nmi_ack_w)
AM_RANGE(0x11c0, 0x11df) AM_READ(itech8_blitter_r) AM_WRITE(blitter_w)
AM_RANGE(0x11e0, 0x11ff) AM_WRITE(itech8_palette_w)
@ -873,7 +872,7 @@ static ADDRESS_MAP_START( tmshi_map, AS_PROGRAM, 8, itech8_state )
AM_RANGE(0x0120, 0x0120) AM_WRITE(sound_data_w)
AM_RANGE(0x0140, 0x0140) AM_READ_PORT("40") AM_WRITE(grom_bank_w)
AM_RANGE(0x0160, 0x0160) AM_READ_PORT("60") AM_WRITE(itech8_page_w)
AM_RANGE(0x0180, 0x0180) AM_READ_PORT("80") AM_WRITE_LEGACY(tms34061_latch_w)
AM_RANGE(0x0180, 0x0180) AM_READ_PORT("80") AM_DEVWRITE("tms34061", tms34061_device, latch_w)
AM_RANGE(0x01a0, 0x01a0) AM_WRITE(itech8_nmi_ack_w)
AM_RANGE(0x01c0, 0x01df) AM_READ(itech8_blitter_r) AM_WRITE(blitter_w)
AM_RANGE(0x01e0, 0x01ff) AM_WRITE(itech8_palette_w)
@ -891,7 +890,7 @@ static ADDRESS_MAP_START( gtg2_map, AS_PROGRAM, 8, itech8_state )
AM_RANGE(0x0160, 0x0160) AM_WRITE(grom_bank_w)
AM_RANGE(0x0180, 0x019f) AM_READ(itech8_blitter_r) AM_WRITE(blitter_w)
AM_RANGE(0x01c0, 0x01c0) AM_WRITE(gtg2_sound_data_w)
AM_RANGE(0x01e0, 0x01e0) AM_WRITE_LEGACY(tms34061_latch_w)
AM_RANGE(0x01e0, 0x01e0) AM_DEVWRITE("tms34061", tms34061_device, latch_w)
AM_RANGE(0x1000, 0x1fff) AM_READWRITE(itech8_tms34061_r, itech8_tms34061_w)
AM_RANGE(0x2000, 0x3fff) AM_RAM AM_SHARE("nvram")
AM_RANGE(0x4000, 0xffff) AM_ROMBANK("bank1")
@ -906,7 +905,7 @@ static ADDRESS_MAP_START( ninclown_map, AS_PROGRAM, 16, itech8_state )
AM_RANGE(0x100080, 0x100081) AM_WRITE8(sound_data_w, 0xff00)
AM_RANGE(0x100100, 0x100101) AM_READ_PORT("40") AM_WRITE(grom_bank16_w)
AM_RANGE(0x100180, 0x100181) AM_READ_PORT("60") AM_WRITE(display_page16_w)
AM_RANGE(0x100240, 0x100241) AM_WRITE8_LEGACY(tms34061_latch_w, 0xff00)
AM_RANGE(0x100240, 0x100241) AM_DEVWRITE8("tms34061", tms34061_device, latch_w, 0xff00)
AM_RANGE(0x100280, 0x100281) AM_READ_PORT("80") AM_WRITENOP
AM_RANGE(0x100300, 0x10031f) AM_READWRITE8(itech8_blitter_r, itech8_blitter_w, 0xffff)
AM_RANGE(0x100380, 0x1003ff) AM_WRITE(palette16_w)
@ -1645,6 +1644,29 @@ static const ay8910_interface ay8910_config =
DEVCB_DRIVER_MEMBER(itech8_state,ym2203_portb_out),
};
/*************************************
*
* TMS34061 interfacing
*
*************************************/
static void generate_interrupt(running_machine &machine, int state_num)
{
itech8_state *state = machine.driver_data<itech8_state>();
state->itech8_update_interrupts(-1, state_num, -1);
if (FULL_LOGGING && state_num) logerror("------------ DISPLAY INT (%d) --------------\n", machine.primary_screen->vpos());
}
static const struct tms34061_interface tms34061intf =
{
"screen", /* the screen we are acting on */
8, /* VRAM address is (row << rowshift) | col */
0x40000, /* size of video RAM */
generate_interrupt /* interrupt gen callback */
};
/*************************************
@ -1674,6 +1696,8 @@ static MACHINE_CONFIG_START( itech8_core_lo, itech8_state )
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_SIZE(512, 263)
MCFG_TMS34061_ADD("tms34061", tms34061intf)
/* sound hardware */
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -1770,6 +1794,8 @@ static MACHINE_CONFIG_DERIVED( wfortune, itech8_core_hi )
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_VISIBLE_AREA(0, 255, 0, 239)
MCFG_SCREEN_UPDATE_DRIVER(itech8_state, screen_update_itech8_2layer)
MACHINE_CONFIG_END
@ -1785,6 +1811,7 @@ static MACHINE_CONFIG_DERIVED( grmatch, itech8_core_hi )
/* palette updater */
MCFG_TIMER_DRIVER_ADD_SCANLINE("palette", itech8_state, grmatch_palette_update, "screen", 0, 0)
MACHINE_CONFIG_END
@ -1797,6 +1824,7 @@ static MACHINE_CONFIG_DERIVED( stratab_hi, itech8_core_hi )
MCFG_SCREEN_MODIFY("screen")
MCFG_SCREEN_VISIBLE_AREA(0, 255, 0, 239)
MCFG_SCREEN_UPDATE_DRIVER(itech8_state, screen_update_itech8_2layer)
MACHINE_CONFIG_END

View File

@ -90,10 +90,10 @@ WRITE16_MEMBER(jpmsys5_state::sys5_tms34061_w)
}
if (ACCESSING_BITS_8_15)
tms34061_w(space, col, row, func, data >> 8);
m_tms34061->write(space, col, row, func, data >> 8);
if (ACCESSING_BITS_0_7)
tms34061_w(space, col | 1, row, func, data & 0xff);
m_tms34061->write(space, col | 1, row, func, data & 0xff);
}
READ16_MEMBER(jpmsys5_state::sys5_tms34061_r)
@ -114,10 +114,10 @@ READ16_MEMBER(jpmsys5_state::sys5_tms34061_r)
}
if (ACCESSING_BITS_8_15)
data |= tms34061_r(space, col, row, func) << 8;
data |= m_tms34061->read(space, col, row, func) << 8;
if (ACCESSING_BITS_0_7)
data |= tms34061_r(space, col | 1, row, func);
data |= m_tms34061->read(space, col | 1, row, func);
return data;
}
@ -147,19 +147,13 @@ WRITE16_MEMBER(jpmsys5_state::ramdac_w)
}
}
VIDEO_START_MEMBER(jpmsys5_state,jpmsys5v)
{
tms34061_start(machine(), &tms34061intf);
}
UINT32 jpmsys5_state::screen_update_jpmsys5v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
int x, y;
struct tms34061_display state;
m_tms34061->get_display_state();
tms34061_get_display_state(&state);
if (state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -167,7 +161,7 @@ UINT32 jpmsys5_state::screen_update_jpmsys5v(screen_device &screen, bitmap_rgb32
for (y = cliprect.min_y; y <= cliprect.max_y; ++y)
{
UINT8 *src = &state.vram[(state.dispstart & 0xffff)*2 + 256 * y];
UINT8 *src = &m_tms34061->m_display.vram[(m_tms34061->m_display.dispstart & 0xffff)*2 + 256 * y];
UINT32 *dest = &bitmap.pix32(y, cliprect.min_x);
for (x = cliprect.min_x; x <= cliprect.max_x; x +=2)
@ -672,7 +666,7 @@ static MACHINE_CONFIG_START( jpmsys5v, jpmsys5_state )
MCFG_SCREEN_RAW_PARAMS(XTAL_40MHz / 4, 676, 20*4, 147*4, 256, 0, 254)
MCFG_SCREEN_UPDATE_DRIVER(jpmsys5_state, screen_update_jpmsys5v)
MCFG_VIDEO_START_OVERRIDE(jpmsys5_state,jpmsys5v)
MCFG_TMS34061_ADD("tms34061", tms34061intf)
MCFG_PALETTE_LENGTH(16)
@ -856,7 +850,7 @@ MACHINE_CONFIG_START( jpmsys5_ym, jpmsys5_state )
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_ROC10937_ADD("vfd",0,RIGHT_TO_LEFT)
MCFG_MACHINE_START_OVERRIDE(jpmsys5_state,jpmsys5)
MCFG_MACHINE_RESET_OVERRIDE(jpmsys5_state,jpmsys5)
MCFG_SPEAKER_STANDARD_MONO("mono")
@ -884,7 +878,7 @@ MACHINE_CONFIG_START( jpmsys5, jpmsys5_state )
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_ROC10937_ADD("vfd",0,RIGHT_TO_LEFT)
MCFG_MACHINE_START_OVERRIDE(jpmsys5_state,jpmsys5)
MCFG_MACHINE_RESET_OVERRIDE(jpmsys5_state,jpmsys5)
MCFG_SPEAKER_STANDARD_MONO("mono")

View File

@ -5,6 +5,7 @@
*************************************************************************/
#include "machine/nvram.h"
#include "video/tms34061.h"
class capbowl_state : public driver_device
{
@ -18,7 +19,8 @@ public:
: driver_device(mconfig, type, tag),
m_rowaddress(*this, "rowaddress"),
m_maincpu(*this, "maincpu"),
m_audiocpu(*this, "audiocpu"){ }
m_audiocpu(*this, "audiocpu"),
m_tms34061(*this, "tms34061") { }
void init_nvram(nvram_device &nvram, void *base, size_t size);
@ -34,6 +36,7 @@ public:
/* devices */
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_audiocpu;
required_device<tms34061_device> m_tms34061;
DECLARE_WRITE8_MEMBER(capbowl_rom_select_w);
DECLARE_READ8_MEMBER(track_0_r);
DECLARE_READ8_MEMBER(track_1_r);
@ -46,7 +49,6 @@ public:
DECLARE_DRIVER_INIT(capbowl);
virtual void machine_start();
virtual void machine_reset();
virtual void video_start();
UINT32 screen_update_capbowl(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
INTERRUPT_GEN_MEMBER(capbowl_interrupt);
TIMER_CALLBACK_MEMBER(capbowl_update);

View File

@ -15,14 +15,18 @@ class itech8_state : public driver_device
public:
itech8_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_tlc34076(*this, "tlc34076"),
m_visarea(0, 0, 0, 0),
m_maincpu(*this, "maincpu"),
m_soundcpu(*this, "soundcpu"),
m_subcpu(*this, "sub") { }
m_subcpu(*this, "sub"),
m_tms34061(*this, "tms34061"),
m_tlc34076(*this, "tlc34076"),
m_visarea(0, 0, 0, 0) { }
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
optional_device<cpu_device> m_subcpu;
required_device<tms34061_device> m_tms34061;
required_device<tlc34076_device> m_tlc34076;
rectangle m_visarea;
UINT8 m_grom_bank;
@ -135,7 +139,4 @@ public:
UINT16 *sens0, UINT16 *sens1, UINT16 *sens2, UINT16 *sens3);
void compute_sensors();
TIMER_CALLBACK_MEMBER( delayed_z80_control_w );
required_device<cpu_device> m_maincpu;
required_device<cpu_device> m_soundcpu;
optional_device<cpu_device> m_subcpu;
};

View File

@ -15,9 +15,14 @@ class jpmsys5_state : public driver_device
public:
jpmsys5_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_vfd(*this, "vfd"),
m_maincpu(*this, "maincpu") { }
m_maincpu(*this, "maincpu"),
m_tms34061(*this, "tms34061"),
m_vfd(*this, "vfd") { }
required_device<cpu_device> m_maincpu;
optional_device<tms34061_device> m_tms34061;
optional_device<roc10937_t> m_vfd;
UINT8 m_palette[16][3];
int m_pal_addr;
int m_pal_idx;
@ -30,7 +35,6 @@ public:
int m_mpxclk;
int m_muxram[255];
int m_alpha_clock;
optional_device<roc10937_t> m_vfd;
UINT8 m_a0_acia_dcd;
UINT8 m_a0_data_out;
UINT8 m_a0_data_in;
@ -69,10 +73,8 @@ public:
void sys5_draw_lamps();
DECLARE_MACHINE_START(jpmsys5v);
DECLARE_MACHINE_RESET(jpmsys5v);
DECLARE_VIDEO_START(jpmsys5v);
DECLARE_MACHINE_START(jpmsys5);
DECLARE_MACHINE_RESET(jpmsys5);
UINT32 screen_update_jpmsys5v(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
TIMER_CALLBACK_MEMBER(touch_cb);
required_device<cpu_device> m_maincpu;
};

View File

@ -5,47 +5,10 @@
***************************************************************************/
#include "emu.h"
#include "video/tms34061.h"
#include "cpu/m6809/m6809.h"
#include "includes/capbowl.h"
/*************************************
*
* TMS34061 interfacing
*
*************************************/
static void generate_interrupt( running_machine &machine, int state )
{
capbowl_state *driver = machine.driver_data<capbowl_state>();
driver->m_maincpu->set_input_line(M6809_FIRQ_LINE, state);
}
static const struct tms34061_interface tms34061intf =
{
"screen", /* the screen we are acting on */
8, /* VRAM address is (row << rowshift) | col */
0x10000, /* size of video RAM */
generate_interrupt /* interrupt gen callback */
};
/*************************************
*
* Video start
*
*************************************/
void capbowl_state::video_start()
{
/* initialize TMS34061 emulation */
tms34061_start(machine(), &tms34061intf);
}
/*************************************
*
* TMS34061 I/O
@ -63,7 +26,7 @@ WRITE8_MEMBER(capbowl_state::capbowl_tms34061_w)
col ^= 2;
/* Row address (RA0-RA8) is not dependent on the offset */
tms34061_w(space, col, *m_rowaddress, func, data);
m_tms34061->write(space, col, *m_rowaddress, func, data);
}
@ -78,7 +41,7 @@ READ8_MEMBER(capbowl_state::capbowl_tms34061_r)
col ^= 2;
/* Row address (RA0-RA8) is not dependent on the offset */
return tms34061_r(space, col, *m_rowaddress, func);
return m_tms34061->read(space, col, *m_rowaddress, func);
}
@ -162,14 +125,13 @@ inline rgb_t capbowl_state::pen_for_pixel( UINT8 *src, UINT8 pix )
UINT32 capbowl_state::screen_update_capbowl(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
struct tms34061_display state;
int x, y;
/* first get the current display state */
tms34061_get_display_state(&state);
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
if (state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -178,7 +140,7 @@ UINT32 capbowl_state::screen_update_capbowl(screen_device &screen, bitmap_rgb32
/* now regenerate the bitmap */
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
UINT8 *src = &state.vram[256 * y];
UINT8 *src = &m_tms34061->m_display.vram[256 * y];
UINT32 *dest = &bitmap.pix32(y);
for (x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2)

View File

@ -88,7 +88,6 @@
***************************************************************************/
#include "emu.h"
#include "video/tms34061.h"
#include "video/tlc34076.h"
#include "cpu/m6809/m6809.h"
#include "includes/itech8.h"
@ -132,31 +131,6 @@
/*************************************
*
* TMS34061 interfacing
*
*************************************/
static void generate_interrupt(running_machine &machine, int state_num)
{
itech8_state *state = machine.driver_data<itech8_state>();
state->itech8_update_interrupts(-1, state_num, -1);
if (FULL_LOGGING && state_num) logerror("------------ DISPLAY INT (%d) --------------\n", machine.primary_screen->vpos());
}
static const struct tms34061_interface tms34061intf =
{
"screen", /* the screen we are acting on */
8, /* VRAM address is (row << rowshift) | col */
0x40000, /* size of video RAM */
generate_interrupt /* interrupt gen callback */
};
/*************************************
*
* Video start
@ -165,11 +139,8 @@ static const struct tms34061_interface tms34061intf =
void itech8_state::video_start()
{
/* initialize TMS34061 emulation */
tms34061_start(machine(), &tms34061intf);
/* get the TMS34061 display state */
tms34061_get_display_state(&m_tms_state);
m_tms34061->get_display_state();
/* reset statics */
m_page_select = 0xc0;
@ -283,16 +254,15 @@ inline void itech8_state::consume_rle(int count)
void itech8_state::perform_blit(address_space &space)
{
struct tms34061_display &tms_state = m_tms_state;
UINT8 *blitter_data = m_blitter_data;
offs_t addr = m_tms_state.regs[TMS34061_XYADDRESS] | ((tms_state.regs[TMS34061_XYOFFSET] & 0x300) << 8);
offs_t addr = m_tms34061->m_display.regs[TMS34061_XYADDRESS] | ((m_tms34061->m_display.regs[TMS34061_XYOFFSET] & 0x300) << 8);
UINT8 shift = (BLITTER_FLAGS & BLITFLAG_SHIFT) ? 4 : 0;
int transparent = (BLITTER_FLAGS & BLITFLAG_TRANSPARENT);
int ydir = (BLITTER_FLAGS & BLITFLAG_YFLIP) ? -1 : 1;
int xdir = (BLITTER_FLAGS & BLITFLAG_XFLIP) ? -1 : 1;
int xflip = (BLITTER_FLAGS & BLITFLAG_XFLIP);
int rle = (BLITTER_FLAGS & BLITFLAG_RLE);
int color = tms34061_latch_r(space, 0);
int color = m_tms34061->latch_r(space, 0);
int width = BLITTER_WIDTH;
int height = BLITTER_HEIGHT;
UINT8 transmaskhi, transmasklo;
@ -305,7 +275,7 @@ void itech8_state::perform_blit(address_space &space)
logerror("Blit: scan=%d src=%06x @ (%05x) for %dx%d ... flags=%02x\n",
space.machine().primary_screen->vpos(),
(m_grom_bank << 16) | (BLITTER_ADDRHI << 8) | BLITTER_ADDRLO,
tms_state.regs[TMS34061_XYADDRESS] | ((tms_state.regs[TMS34061_XYOFFSET] & 0x300) << 8),
m_tms34061->m_display.regs[TMS34061_XYADDRESS] | ((m_tms34061->m_display.regs[TMS34061_XYOFFSET] & 0x300) << 8),
BLITTER_WIDTH, BLITTER_HEIGHT, BLITTER_FLAGS);
/* initialize the fetcher */
@ -380,16 +350,16 @@ void itech8_state::perform_blit(address_space &space)
/* draw upper pixel */
if (!transparent || (pix & transmaskhi))
{
tms_state.vram[addr] = (tms_state.vram[addr] & (0x0f << shift)) | ((pix & 0xf0) >> shift);
tms_state.latchram[addr] = (tms_state.latchram[addr] & (0x0f << shift)) | ((color & 0xf0) >> shift);
m_tms34061->m_display.vram[addr] = (m_tms34061->m_display.vram[addr] & (0x0f << shift)) | ((pix & 0xf0) >> shift);
m_tms34061->m_display.latchram[addr] = (m_tms34061->m_display.latchram[addr] & (0x0f << shift)) | ((color & 0xf0) >> shift);
}
/* draw lower pixel */
if (!transparent || (pix & transmasklo))
{
offs_t addr1 = addr + shift/4;
tms_state.vram[addr1] = (tms_state.vram[addr1] & (0xf0 >> shift)) | ((pix & 0x0f) << shift);
tms_state.latchram[addr1] = (tms_state.latchram[addr1] & (0xf0 >> shift)) | ((color & 0x0f) << shift);
m_tms34061->m_display.vram[addr1] = (m_tms34061->m_display.vram[addr1] & (0xf0 >> shift)) | ((pix & 0x0f) << shift);
m_tms34061->m_display.latchram[addr1] = (m_tms34061->m_display.latchram[addr1] & (0xf0 >> shift)) | ((color & 0x0f) << shift);
}
/* advance to the next byte */
@ -468,8 +438,7 @@ READ8_MEMBER(itech8_state::itech8_blitter_r)
WRITE8_MEMBER(itech8_state::itech8_blitter_w)
{
UINT8 *blitter_data = m_blitter_data;
struct tms34061_display &tms_state = m_tms_state;
/* low bit seems to be ignored */
offset /= 2;
blitter_data[offset] = data;
@ -481,7 +450,7 @@ WRITE8_MEMBER(itech8_state::itech8_blitter_w)
if (BLIT_LOGGING)
{
logerror("Blit: XY=%1X%04X SRC=%02X%02X%02X SIZE=%3dx%3d FLAGS=%02x",
(tms_state.regs[TMS34061_XYOFFSET] >> 8) & 0x0f, tms_state.regs[TMS34061_XYADDRESS],
(m_tms34061->m_display.regs[TMS34061_XYOFFSET] >> 8) & 0x0f, m_tms34061->m_display.regs[TMS34061_XYADDRESS],
m_grom_bank, blitter_data[0], blitter_data[1],
blitter_data[4], blitter_data[5],
blitter_data[2]);
@ -527,7 +496,7 @@ WRITE8_MEMBER(itech8_state::itech8_tms34061_w)
col ^= 2;
/* Row address (RA0-RA8) is not dependent on the offset */
tms34061_w(space, col, 0xff, func, data);
m_tms34061->write(space, col, 0xff, func, data);
}
@ -542,7 +511,7 @@ READ8_MEMBER(itech8_state::itech8_tms34061_r)
col ^= 2;
/* Row address (RA0-RA8) is not dependent on the offset */
return tms34061_r(space, col, 0xff, func);
return m_tms34061->read(space, col, 0xff, func);
}
@ -570,18 +539,17 @@ WRITE8_MEMBER(itech8_state::grmatch_xscroll_w)
TIMER_DEVICE_CALLBACK_MEMBER(itech8_state::grmatch_palette_update)
{
struct tms34061_display &tms_state = m_tms_state;
/* if the high bit is set, we are supposed to latch the palette values */
if (m_grmatch_palcontrol & 0x80)
{
/* the TMS34070s latch at the start of the frame, based on the first few bytes */
UINT32 page_offset = (tms_state.dispstart & 0x0ffff) | m_grmatch_xscroll;
UINT32 page_offset = (m_tms34061->m_display.dispstart & 0x0ffff) | m_grmatch_xscroll;
int page, x;
/* iterate over both pages */
for (page = 0; page < 2; page++)
{
const UINT8 *base = &tms_state.vram[(page * 0x20000 + page_offset) & 0x3ffff];
const UINT8 *base = &m_tms34061->m_display.vram[(page * 0x20000 + page_offset) & 0x3ffff];
for (x = 0; x < 16; x++)
{
UINT8 data0 = base[x * 2 + 0];
@ -602,16 +570,15 @@ TIMER_DEVICE_CALLBACK_MEMBER(itech8_state::grmatch_palette_update)
UINT32 itech8_state::screen_update_itech8_2layer(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
struct tms34061_display &tms_state = m_tms_state;
UINT32 page_offset;
int x, y;
const rgb_t *pens = m_tlc34076->get_pens();
/* first get the current display state */
tms34061_get_display_state(&tms_state);
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
if (tms_state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -620,11 +587,11 @@ UINT32 itech8_state::screen_update_itech8_2layer(screen_device &screen, bitmap_r
/* there are two layers: */
/* top layer @ 0x00000 is only 4bpp, colors come from the first 16 palettes */
/* bottom layer @ 0x20000 is full 8bpp */
page_offset = tms_state.dispstart & 0x0ffff;
page_offset = m_tms34061->m_display.dispstart & 0x0ffff;
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
UINT8 *base0 = &tms_state.vram[(0x00000 + page_offset + y * 256) & 0x3ffff];
UINT8 *base2 = &tms_state.vram[(0x20000 + page_offset + y * 256) & 0x3ffff];
UINT8 *base0 = &m_tms34061->m_display.vram[(0x00000 + page_offset + y * 256) & 0x3ffff];
UINT8 *base2 = &m_tms34061->m_display.vram[(0x20000 + page_offset + y * 256) & 0x3ffff];
UINT32 *dest = &bitmap.pix32(y);
for (x = cliprect.min_x; x <= cliprect.max_x; x++)
@ -639,15 +606,14 @@ UINT32 itech8_state::screen_update_itech8_2layer(screen_device &screen, bitmap_r
UINT32 itech8_state::screen_update_itech8_grmatch(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
struct tms34061_display &tms_state = m_tms_state;
UINT32 page_offset;
int x, y;
/* first get the current display state */
tms34061_get_display_state(&tms_state);
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
if (tms_state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -658,11 +624,11 @@ UINT32 itech8_state::screen_update_itech8_grmatch(screen_device &screen, bitmap_
/* bottom layer @ 0x20000 is 4bpp, colors come from TMS34070, enabled via palette control */
/* 4bpp pixels are packed 2 to a byte */
/* xscroll is set via a separate register */
page_offset = (tms_state.dispstart & 0x0ffff) | m_grmatch_xscroll;
page_offset = (m_tms34061->m_display.dispstart & 0x0ffff) | m_grmatch_xscroll;
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
UINT8 *base0 = &tms_state.vram[0x00000 + ((page_offset + y * 256) & 0xffff)];
UINT8 *base2 = &tms_state.vram[0x20000 + ((page_offset + y * 256) & 0xffff)];
UINT8 *base0 = &m_tms34061->m_display.vram[0x00000 + ((page_offset + y * 256) & 0xffff)];
UINT8 *base2 = &m_tms34061->m_display.vram[0x20000 + ((page_offset + y * 256) & 0xffff)];
UINT32 *dest = &bitmap.pix32(y);
for (x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2)
@ -687,16 +653,15 @@ UINT32 itech8_state::screen_update_itech8_grmatch(screen_device &screen, bitmap_
UINT32 itech8_state::screen_update_itech8_2page(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
struct tms34061_display &tms_state = m_tms_state;
UINT32 page_offset;
int x, y;
const rgb_t *pens = m_tlc34076->get_pens();
/* first get the current display state */
tms34061_get_display_state(&tms_state);
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
if (tms_state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -704,10 +669,10 @@ UINT32 itech8_state::screen_update_itech8_2page(screen_device &screen, bitmap_rg
/* there are two pages, each of which is a full 8bpp */
/* page index is selected by the top bit of the page_select register */
page_offset = ((m_page_select & 0x80) << 10) | (tms_state.dispstart & 0x0ffff);
page_offset = ((m_page_select & 0x80) << 10) | (m_tms34061->m_display.dispstart & 0x0ffff);
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
UINT8 *base = &tms_state.vram[(page_offset + y * 256) & 0x3ffff];
UINT8 *base = &m_tms34061->m_display.vram[(page_offset + y * 256) & 0x3ffff];
UINT32 *dest = &bitmap.pix32(y);
for (x = cliprect.min_x; x <= cliprect.max_x; x++)
@ -719,16 +684,15 @@ UINT32 itech8_state::screen_update_itech8_2page(screen_device &screen, bitmap_rg
UINT32 itech8_state::screen_update_itech8_2page_large(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
struct tms34061_display &tms_state = m_tms_state;
UINT32 page_offset;
int x, y;
const rgb_t *pens = m_tlc34076->get_pens();
/* first get the current display state */
tms34061_get_display_state(&tms_state);
m_tms34061->get_display_state();
/* if we're blanked, just fill with black */
if (tms_state.blanked)
if (m_tms34061->m_display.blanked)
{
bitmap.fill(get_black_pen(machine()), cliprect);
return 0;
@ -738,11 +702,11 @@ UINT32 itech8_state::screen_update_itech8_2page_large(screen_device &screen, bit
/* the low 4 bits come from the bitmap directly */
/* the upper 4 bits were latched on each write into a separate bitmap */
/* page index is selected by the top bit of the page_select register */
page_offset = ((~m_page_select & 0x80) << 10) | (tms_state.dispstart & 0x0ffff);
page_offset = ((~m_page_select & 0x80) << 10) | (m_tms34061->m_display.dispstart & 0x0ffff);
for (y = cliprect.min_y; y <= cliprect.max_y; y++)
{
UINT8 *base = &tms_state.vram[(page_offset + y * 256) & 0x3ffff];
UINT8 *latch = &tms_state.latchram[(page_offset + y * 256) & 0x3ffff];
UINT8 *base = &m_tms34061->m_display.vram[(page_offset + y * 256) & 0x3ffff];
UINT8 *latch = &m_tms34061->m_display.latchram[(page_offset + y * 256) & 0x3ffff];
UINT32 *dest = &bitmap.pix32(y);
for (x = cliprect.min_x & ~1; x <= cliprect.max_x; x += 2)