mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
added 315-5296 device
This commit is contained in:
parent
e9aea92d1a
commit
1cdd1948ee
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -6865,6 +6865,8 @@ src/mame/layout/wpc_an.lay svneol=native#text/xml
|
||||
src/mame/layout/zac_1.lay svneol=native#text/xml
|
||||
src/mame/layout/zac_2.lay svneol=native#text/xml
|
||||
src/mame/layout/zac_proto.lay svneol=native#text/xml
|
||||
src/mame/machine/315-5296.c svneol=native#text/plain
|
||||
src/mame/machine/315-5296.h svneol=native#text/plain
|
||||
src/mame/machine/3do.c svneol=native#text/plain
|
||||
src/mame/machine/acitya.c svneol=native#text/plain
|
||||
src/mame/machine/ajax.c svneol=native#text/plain
|
||||
|
@ -38,9 +38,9 @@ void fifo7200_device::device_start()
|
||||
m_buffer.resize(m_ram_size);
|
||||
|
||||
// resolve callbacks
|
||||
m_ef_handler.resolve();
|
||||
m_ff_handler.resolve();
|
||||
m_hf_handler.resolve();
|
||||
m_ef_handler.resolve_safe();
|
||||
m_ff_handler.resolve_safe();
|
||||
m_hf_handler.resolve_safe();
|
||||
|
||||
// state save
|
||||
save_item(NAME(m_read_ptr));
|
||||
@ -65,9 +65,9 @@ void fifo7200_device::device_reset()
|
||||
m_ff = 0;
|
||||
m_hf = 0;
|
||||
|
||||
if (!m_ef_handler.isnull()) m_ef_handler(!m_ef);
|
||||
if (!m_ff_handler.isnull()) m_ff_handler(!m_ff);
|
||||
if (!m_hf_handler.isnull()) m_hf_handler(!m_hf);
|
||||
m_ef_handler(!m_ef);
|
||||
m_ff_handler(!m_ff);
|
||||
m_hf_handler(!m_hf);
|
||||
}
|
||||
|
||||
|
||||
@ -87,19 +87,19 @@ void fifo7200_device::fifo_write(UINT16 data)
|
||||
if (m_ef)
|
||||
{
|
||||
m_ef = 0;
|
||||
if (!m_ef_handler.isnull()) m_ef_handler(!m_ef);
|
||||
m_ef_handler(!m_ef);
|
||||
}
|
||||
|
||||
else if (m_read_ptr == m_write_ptr)
|
||||
{
|
||||
m_ff = 1;
|
||||
if (!m_ff_handler.isnull()) m_ff_handler(!m_ff);
|
||||
m_ff_handler(!m_ff);
|
||||
}
|
||||
|
||||
else if (((m_read_ptr + 1 + m_ram_size / 2) % m_ram_size) == m_write_ptr)
|
||||
{
|
||||
m_hf = 1;
|
||||
if (!m_hf_handler.isnull()) m_hf_handler(!m_hf);
|
||||
m_hf_handler(!m_hf);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,19 +118,19 @@ UINT16 fifo7200_device::fifo_read()
|
||||
if (m_ff)
|
||||
{
|
||||
m_ff = 0;
|
||||
if (!m_ff_handler.isnull()) m_ff_handler(!m_ff);
|
||||
m_ff_handler(!m_ff);
|
||||
}
|
||||
|
||||
else if (m_read_ptr == m_write_ptr)
|
||||
{
|
||||
m_ef = 1;
|
||||
if (!m_ef_handler.isnull()) m_ef_handler(!m_ef);
|
||||
m_ef_handler(!m_ef);
|
||||
}
|
||||
|
||||
else if (((m_read_ptr + m_ram_size / 2) % m_ram_size) == m_write_ptr)
|
||||
{
|
||||
m_hf = 0;
|
||||
if (!m_hf_handler.isnull()) m_hf_handler(!m_hf);
|
||||
m_hf_handler(!m_hf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -736,11 +736,11 @@ void upd775x_device::postload()
|
||||
|
||||
*************************************************************/
|
||||
|
||||
void upd775x_device::reset_w(UINT8 data)
|
||||
WRITE_LINE_MEMBER( upd775x_device::reset_w )
|
||||
{
|
||||
/* update the reset value */
|
||||
UINT8 oldreset = m_reset;
|
||||
m_reset = (data != 0);
|
||||
m_reset = (state != 0);
|
||||
|
||||
/* update the stream first */
|
||||
m_channel->update();
|
||||
@ -750,11 +750,11 @@ void upd775x_device::reset_w(UINT8 data)
|
||||
device_reset();
|
||||
}
|
||||
|
||||
void upd7759_device::start_w(UINT8 data)
|
||||
WRITE_LINE_MEMBER( upd7759_device::start_w )
|
||||
{
|
||||
/* update the start value */
|
||||
UINT8 oldstart = m_start;
|
||||
m_start = (data != 0);
|
||||
m_start = (state != 0);
|
||||
|
||||
logerror("upd7759_start_w: %d->%d\n", oldstart, m_start);
|
||||
|
||||
@ -772,11 +772,11 @@ void upd7759_device::start_w(UINT8 data)
|
||||
}
|
||||
}
|
||||
|
||||
void upd7756_device::start_w(UINT8 data)
|
||||
WRITE_LINE_MEMBER( upd7756_device::start_w )
|
||||
{
|
||||
/* update the start value */
|
||||
UINT8 oldstart = m_start;
|
||||
m_start = (data != 0);
|
||||
m_start = (state != 0);
|
||||
|
||||
logerror("upd7759_start_w: %d->%d\n", oldstart, m_start);
|
||||
|
||||
@ -798,7 +798,7 @@ WRITE8_MEMBER( upd775x_device::port_w )
|
||||
}
|
||||
|
||||
|
||||
int upd775x_device::busy_r()
|
||||
READ_LINE_MEMBER( upd775x_device::busy_r )
|
||||
{
|
||||
/* return /BUSY */
|
||||
return (m_state == STATE_IDLE);
|
||||
|
@ -25,8 +25,8 @@ public:
|
||||
|
||||
void set_bank_base(offs_t base);
|
||||
|
||||
void reset_w(UINT8 data);
|
||||
int busy_r();
|
||||
DECLARE_WRITE_LINE_MEMBER( reset_w );
|
||||
DECLARE_READ_LINE_MEMBER( busy_r );
|
||||
DECLARE_WRITE8_MEMBER( port_w );
|
||||
void postload();
|
||||
|
||||
@ -93,9 +93,9 @@ public:
|
||||
upd7759_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
enum
|
||||
{
|
||||
TIMER_SLAVE_UPDATE
|
||||
};
|
||||
{
|
||||
TIMER_SLAVE_UPDATE
|
||||
};
|
||||
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
@ -104,7 +104,7 @@ public:
|
||||
|
||||
emu_timer *m_timer; /* timer */
|
||||
|
||||
void start_w(UINT8 data);
|
||||
DECLARE_WRITE_LINE_MEMBER( start_w );
|
||||
};
|
||||
|
||||
class upd7756_device : public upd775x_device
|
||||
@ -116,7 +116,7 @@ public:
|
||||
virtual void device_reset();
|
||||
virtual void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples);
|
||||
|
||||
void start_w(UINT8 data);
|
||||
DECLARE_WRITE_LINE_MEMBER( start_w );
|
||||
};
|
||||
|
||||
extern const device_type UPD7759;
|
||||
|
@ -70,6 +70,7 @@
|
||||
#include "emu.h"
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "machine/315-5296.h"
|
||||
#include "sound/okim6295.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "sound/2612intf.h"
|
||||
@ -162,11 +163,13 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER(vdp_lv6irqline_callback_c2);
|
||||
DECLARE_WRITE_LINE_MEMBER(vdp_lv4irqline_callback_c2);
|
||||
|
||||
DECLARE_READ8_MEMBER(io_portc_r);
|
||||
DECLARE_WRITE8_MEMBER(io_portd_w);
|
||||
DECLARE_WRITE8_MEMBER(io_porth_w);
|
||||
|
||||
DECLARE_WRITE16_MEMBER( segac2_upd7759_w );
|
||||
DECLARE_READ16_MEMBER( palette_r );
|
||||
DECLARE_WRITE16_MEMBER( palette_w );
|
||||
DECLARE_READ16_MEMBER( io_chip_r );
|
||||
DECLARE_WRITE16_MEMBER( io_chip_w );
|
||||
DECLARE_WRITE16_MEMBER( control_w );
|
||||
DECLARE_READ16_MEMBER( prot_r );
|
||||
DECLARE_WRITE16_MEMBER( prot_w );
|
||||
@ -201,7 +204,6 @@ public:
|
||||
int prot_func_pclubjv2(int in);
|
||||
int prot_func_pclubjv4(int in);
|
||||
int prot_func_pclubjv5(int in);
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -255,7 +257,6 @@ MACHINE_RESET_MEMBER(segac2_state,segac2)
|
||||
m_sp_palbase = 0;
|
||||
|
||||
recompute_palette_tables();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -273,10 +274,10 @@ MACHINE_RESET_MEMBER(segac2_state,segac2)
|
||||
******************************************************************************/
|
||||
|
||||
/* handle writes to the UPD7759 */
|
||||
WRITE16_MEMBER(segac2_state::segac2_upd7759_w )
|
||||
WRITE16_MEMBER(segac2_state::segac2_upd7759_w)
|
||||
{
|
||||
/* make sure we have a UPD chip */
|
||||
if (!m_sound_banks)
|
||||
if (m_upd7759 == NULL)
|
||||
return;
|
||||
|
||||
/* only works if we're accessing the low byte */
|
||||
@ -307,7 +308,7 @@ WRITE16_MEMBER(segac2_state::segac2_upd7759_w )
|
||||
******************************************************************************/
|
||||
|
||||
/* handle reads from the paletteram */
|
||||
READ16_MEMBER(segac2_state::palette_r )
|
||||
READ16_MEMBER(segac2_state::palette_r)
|
||||
{
|
||||
offset &= 0x1ff;
|
||||
if (m_segac2_alt_palette_mode)
|
||||
@ -317,7 +318,7 @@ READ16_MEMBER(segac2_state::palette_r )
|
||||
}
|
||||
|
||||
/* handle writes to the paletteram */
|
||||
WRITE16_MEMBER(segac2_state::palette_w )
|
||||
WRITE16_MEMBER(segac2_state::palette_w)
|
||||
{
|
||||
int r, g, b, newword;
|
||||
int tmpr, tmpg, tmpb;
|
||||
@ -403,143 +404,63 @@ void segac2_state::recompute_palette_tables()
|
||||
m_segac2_sp_pal_lookup[i] = 0x200 * m_palbank + ((~sppal << 2) & 0x100) + ((sppal << 2) & 0x80) + ((~sppal >> 2) & 0x40) + ((sppal >> 2) & 0x20) + (sppal & 0x10);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
I/O Read & Write Handlers
|
||||
*******************************************************************************
|
||||
|
||||
Controls, and Poto Poto reads 'S' 'E' 'G' and 'A' (SEGA) from this area
|
||||
as a form of protection.
|
||||
|
||||
Lots of unknown writes however offset 0E certainly seems to be banking,
|
||||
both colours and sound sample banks.
|
||||
|
||||
Sega 315-5296 I/O chip
|
||||
******************************************************************************/
|
||||
|
||||
READ16_MEMBER(segac2_state::io_chip_r )
|
||||
READ8_MEMBER(segac2_state::io_portc_r)
|
||||
{
|
||||
static const char *const portnames[] = { "P1", "P2", "PORTC", "PORTD", "SERVICE", "COINAGE", "DSW", "PORTH" };
|
||||
offset &= 0x1f/2;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
/* I/O ports */
|
||||
case 0x00/2:
|
||||
case 0x02/2:
|
||||
case 0x04/2:
|
||||
case 0x06/2:
|
||||
case 0x08/2:
|
||||
case 0x0a/2:
|
||||
case 0x0c/2:
|
||||
case 0x0e/2:
|
||||
/* if the port is configured as an output, return the last thing written */
|
||||
if (m_misc_io_data[0x1e/2] & (1 << offset))
|
||||
return m_misc_io_data[offset];
|
||||
|
||||
/* otherwise, return an input port */
|
||||
if (offset == 0x04/2 && m_sound_banks)
|
||||
return (ioport(portnames[offset])->read() & 0xbf) | (m_upd7759->busy_r() << 6);
|
||||
return ioport(portnames[offset])->read();
|
||||
|
||||
/* 'SEGA' protection */
|
||||
case 0x10/2:
|
||||
return 'S';
|
||||
case 0x12/2:
|
||||
return 'E';
|
||||
case 0x14/2:
|
||||
return 'G';
|
||||
case 0x16/2:
|
||||
return 'A';
|
||||
|
||||
/* CNT register & mirror */
|
||||
case 0x18/2:
|
||||
case 0x1c/2:
|
||||
return m_misc_io_data[0x1c/2];
|
||||
|
||||
/* port direction register & mirror */
|
||||
case 0x1a/2:
|
||||
case 0x1e/2:
|
||||
return m_misc_io_data[0x1e/2];
|
||||
}
|
||||
return 0xffff;
|
||||
// D7 : From MB3773P pin 1. (/RESET output)
|
||||
// D6 : From uPD7759 pin 18. (/BUSY output)
|
||||
int busy = (m_upd7759 != NULL) ? (m_upd7759->busy_r() << 6) : 0x40;
|
||||
return 0xbf | busy;
|
||||
|
||||
}
|
||||
|
||||
|
||||
WRITE16_MEMBER(segac2_state::io_chip_w )
|
||||
WRITE8_MEMBER(segac2_state::io_portd_w)
|
||||
{
|
||||
UINT8 newbank;
|
||||
// UINT8 old;
|
||||
/*
|
||||
D7 : To pin 3 of JP15. (Watchdog clock control)
|
||||
D6 : To MUTE input pin on TDA1518BQ amplifier.
|
||||
D5 : To CN2 pin 10. (Unknown purpose)
|
||||
D4 : To CN2 pin 11. (Unknown purpose)
|
||||
D3 : To CN1 pin K. (Coin lockout 2)
|
||||
D2 : To CN1 pin 9. (Coin lockout 1)
|
||||
D1 : To CN1 pin J. (Coin meter 2)
|
||||
D0 : To CN1 pin 8. (Coin meter 1)
|
||||
*/
|
||||
//coin_lockout_w(space.machine(), 1, data & 0x08);
|
||||
//coin_lockout_w(space.machine(), 0, data & 0x04);
|
||||
coin_counter_w(space.machine(), 1, data & 0x02);
|
||||
coin_counter_w(space.machine(), 0, data & 0x01);
|
||||
}
|
||||
|
||||
/* generic implementation */
|
||||
offset &= 0x1f/2;
|
||||
// old = m_misc_io_data[offset];
|
||||
m_misc_io_data[offset] = data;
|
||||
|
||||
switch (offset)
|
||||
WRITE8_MEMBER(segac2_state::io_porth_w)
|
||||
{
|
||||
/*
|
||||
D7 : To pin A19 of CN4
|
||||
D6 : To pin B19 of CN4
|
||||
D5 : ?
|
||||
D4 : ?
|
||||
D3 : To pin 31 of uPD7759 sample ROM (A18 on a 27C040)
|
||||
D2 : To pin 30 of uPD7759 sample ROM (A17 on a 27C040)
|
||||
D1 : To A10 of color RAM
|
||||
D0 : To A9 of color RAM
|
||||
*/
|
||||
int newbank = data & 3;
|
||||
if (newbank != m_palbank)
|
||||
{
|
||||
/* I/O ports */
|
||||
case 0x00/2:
|
||||
case 0x02/2:
|
||||
case 0x04/2:
|
||||
case 0x08/2:
|
||||
case 0x0a/2:
|
||||
case 0x0c/2:
|
||||
break;
|
||||
|
||||
/* miscellaneous output */
|
||||
case 0x06/2:
|
||||
/*
|
||||
D7 : To pin 3 of JP15. (Watchdog clock control)
|
||||
D6 : To MUTE input pin on TDA1518BQ amplifier.
|
||||
D5 : To CN2 pin 10. (Unknown purpose)
|
||||
D4 : To CN2 pin 11. (Unknown purpose)
|
||||
D3 : To CN1 pin K. (Coin lockout 2)
|
||||
D2 : To CN1 pin 9. (Coin lockout 1)
|
||||
D1 : To CN1 pin J. (Coin meter 2)
|
||||
D0 : To CN1 pin 8. (Coin meter 1)
|
||||
*/
|
||||
/* coin_lockout_w(space.machine(), 1, data & 0x08);
|
||||
coin_lockout_w(space.machine(), 0, data & 0x04); */
|
||||
coin_counter_w(space.machine(), 1, data & 0x02);
|
||||
coin_counter_w(space.machine(), 0, data & 0x01);
|
||||
break;
|
||||
|
||||
/* banking */
|
||||
case 0x0e/2:
|
||||
/*
|
||||
D7 : To pin A19 of CN4
|
||||
D6 : To pin B19 of CN4
|
||||
D5 : ?
|
||||
D4 : ?
|
||||
D3 : To pin 31 of uPD7759 sample ROM (A18 on a 27C040)
|
||||
D2 : To pin 30 of uPD7759 sample ROM (A17 on a 27C040)
|
||||
D1 : To A10 of color RAM
|
||||
D0 : To A9 of color RAM
|
||||
*/
|
||||
newbank = data & 3;
|
||||
if (newbank != m_palbank)
|
||||
{
|
||||
//m_screen->update_partial(m_screen->vpos() + 1);
|
||||
m_palbank = newbank;
|
||||
recompute_palette_tables();
|
||||
}
|
||||
if (m_sound_banks > 1)
|
||||
{
|
||||
newbank = (data >> 2) & (m_sound_banks - 1);
|
||||
m_upd7759->set_bank_base(newbank * 0x20000);
|
||||
}
|
||||
break;
|
||||
|
||||
/* CNT register */
|
||||
case 0x1c/2:
|
||||
if (m_sound_banks > 1)
|
||||
{
|
||||
m_upd7759->reset_w((data >> 1) & 1);
|
||||
}
|
||||
break;
|
||||
//m_screen->update_partial(m_screen->vpos() + 1);
|
||||
m_palbank = newbank;
|
||||
recompute_palette_tables();
|
||||
}
|
||||
if (m_sound_banks > 1)
|
||||
{
|
||||
newbank = (data >> 2) & (m_sound_banks - 1);
|
||||
m_upd7759->set_bank_base(newbank * 0x20000);
|
||||
}
|
||||
}
|
||||
|
||||
@ -713,7 +634,7 @@ static ADDRESS_MAP_START( main_map, AS_PROGRAM, 16, segac2_state )
|
||||
AM_RANGE(0x000000, 0x1fffff) AM_ROM
|
||||
AM_RANGE(0x800000, 0x800001) AM_MIRROR(0x13fdfe) AM_READWRITE(prot_r, prot_w)
|
||||
AM_RANGE(0x800200, 0x800201) AM_MIRROR(0x13fdfe) AM_WRITE(control_w)
|
||||
AM_RANGE(0x840000, 0x84001f) AM_MIRROR(0x13fee0) AM_READWRITE(io_chip_r, io_chip_w)
|
||||
AM_RANGE(0x840000, 0x84001f) AM_MIRROR(0x13fee0) AM_DEVREADWRITE8("io", sega_315_5296_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x840100, 0x840107) AM_MIRROR(0x13fef8) AM_DEVREADWRITE8("ymsnd", ym3438_device, read, write, 0x00ff)
|
||||
AM_RANGE(0x880100, 0x880101) AM_MIRROR(0x13fefe) AM_WRITE(counter_timer_w)
|
||||
AM_RANGE(0x8c0000, 0x8c0fff) AM_MIRROR(0x13f000) AM_READWRITE(palette_r, palette_w) AM_SHARE("paletteram")
|
||||
@ -758,14 +679,6 @@ static INPUT_PORTS_START( systemc_generic )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
|
||||
|
||||
PORT_START("PORTC")
|
||||
PORT_BIT( 0x3f, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) /* From uPD7759 pin 18. (/BUSY output) */
|
||||
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) /* From MB3773P pin 1. (/RESET output) */
|
||||
|
||||
PORT_START("PORTD")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
|
||||
PORT_START("SERVICE")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 )
|
||||
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 )
|
||||
@ -788,9 +701,6 @@ static INPUT_PORTS_START( systemc_generic )
|
||||
PORT_DIPUNUSED_DIPLOC( 0x20, IP_ACTIVE_LOW, "SW2:6" )
|
||||
PORT_DIPUNUSED_DIPLOC( 0x40, IP_ACTIVE_LOW, "SW2:7" )
|
||||
PORT_DIPUNUSED_DIPLOC( 0x80, IP_ACTIVE_LOW, "SW2:8" )
|
||||
|
||||
PORT_START("PORTH")
|
||||
PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED )
|
||||
INPUT_PORTS_END
|
||||
|
||||
|
||||
@ -1465,6 +1375,17 @@ static MACHINE_CONFIG_START( segac, segac2_state )
|
||||
MCFG_MACHINE_RESET_OVERRIDE(segac2_state,segac2)
|
||||
MCFG_NVRAM_ADD_1FILL("nvram") // borencha requires 0xff fill or there is no sound (it lacks some of the init code of the borench set)
|
||||
|
||||
MCFG_DEVICE_ADD("io", SEGA_315_5296, 0)
|
||||
MCFG_315_5296_IN_PORTA_CB(IOPORT("P1"))
|
||||
MCFG_315_5296_IN_PORTB_CB(IOPORT("P2"))
|
||||
MCFG_315_5296_IN_PORTC_CB(READ8(segac2_state, io_portc_r))
|
||||
MCFG_315_5296_OUT_PORTD_CB(WRITE8(segac2_state, io_portd_w))
|
||||
MCFG_315_5296_IN_PORTE_CB(IOPORT("SERVICE"))
|
||||
MCFG_315_5296_IN_PORTF_CB(IOPORT("COINAGE"))
|
||||
MCFG_315_5296_IN_PORTG_CB(IOPORT("DSW"))
|
||||
MCFG_315_5296_OUT_PORTH_CB(WRITE8(segac2_state, io_porth_w))
|
||||
|
||||
/* video hardware */
|
||||
MCFG_DEVICE_ADD("gen_vdp", SEGA315_5313, 0)
|
||||
MCFG_SEGA315_5313_IS_PAL(false)
|
||||
MCFG_SEGA315_5313_SND_IRQ_CALLBACK(WRITELINE(segac2_state, vdp_sndirqline_callback_c2));
|
||||
@ -1475,7 +1396,6 @@ static MACHINE_CONFIG_START( segac, segac2_state )
|
||||
|
||||
MCFG_TIMER_DEVICE_ADD_SCANLINE("scantimer", "gen_vdp", sega315_5313_device, megadriv_scanline_timer_callback_alt_timing, "megadriv", 0, 1)
|
||||
|
||||
|
||||
MCFG_SCREEN_ADD("megadriv", RASTER)
|
||||
MCFG_SCREEN_REFRESH_RATE(60)
|
||||
MCFG_SCREEN_SIZE(512, 262)
|
||||
@ -1503,6 +1423,8 @@ MACHINE_CONFIG_END
|
||||
static MACHINE_CONFIG_DERIVED( segac2, segac )
|
||||
|
||||
/* basic machine hardware */
|
||||
MCFG_DEVICE_MODIFY("io")
|
||||
MCFG_315_5296_OUT_CNT1_CB(DEVWRITELINE("upd", upd7759_device, reset_w))
|
||||
|
||||
/* sound hardware */
|
||||
MCFG_SOUND_ADD("upd", UPD7759, XL1_CLOCK)
|
||||
|
178
src/mame/machine/315-5296.c
Normal file
178
src/mame/machine/315-5296.c
Normal file
@ -0,0 +1,178 @@
|
||||
/**********************************************************************
|
||||
|
||||
Sega 315-5296 I/O chip
|
||||
|
||||
Sega 100-pin QFP, with 8 bidirectional I/O ports, and 3 output pins.
|
||||
Commonly used from the late 80s up until Sega Model 2.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#include "machine/315-5296.h"
|
||||
|
||||
|
||||
const device_type SEGA_315_5296 = &device_creator<sega_315_5296_device>;
|
||||
|
||||
//-------------------------------------------------
|
||||
// sega_315_5296_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
|
||||
sega_315_5296_device::sega_315_5296_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, SEGA_315_5296, "Sega 315-5296", tag, owner, clock, "315-5296", __FILE__),
|
||||
m_in_pa_cb(*this),
|
||||
m_in_pb_cb(*this),
|
||||
m_in_pc_cb(*this),
|
||||
m_in_pd_cb(*this),
|
||||
m_in_pe_cb(*this),
|
||||
m_in_pf_cb(*this),
|
||||
m_in_pg_cb(*this),
|
||||
m_in_ph_cb(*this),
|
||||
m_out_pa_cb(*this),
|
||||
m_out_pb_cb(*this),
|
||||
m_out_pc_cb(*this),
|
||||
m_out_pd_cb(*this),
|
||||
m_out_pe_cb(*this),
|
||||
m_out_pf_cb(*this),
|
||||
m_out_pg_cb(*this),
|
||||
m_out_ph_cb(*this),
|
||||
m_out_cnt0_cb(*this),
|
||||
m_out_cnt1_cb(*this),
|
||||
m_out_cnt2_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void sega_315_5296_device::device_start()
|
||||
{
|
||||
// resolve callbacks
|
||||
m_in_pa_cb.resolve_safe(0xff); m_in_port_cb[0] = &m_in_pa_cb;
|
||||
m_in_pb_cb.resolve_safe(0xff); m_in_port_cb[1] = &m_in_pb_cb;
|
||||
m_in_pc_cb.resolve_safe(0xff); m_in_port_cb[2] = &m_in_pc_cb;
|
||||
m_in_pd_cb.resolve_safe(0xff); m_in_port_cb[3] = &m_in_pd_cb;
|
||||
m_in_pe_cb.resolve_safe(0xff); m_in_port_cb[4] = &m_in_pe_cb;
|
||||
m_in_pf_cb.resolve_safe(0xff); m_in_port_cb[5] = &m_in_pf_cb;
|
||||
m_in_pg_cb.resolve_safe(0xff); m_in_port_cb[6] = &m_in_pg_cb;
|
||||
m_in_ph_cb.resolve_safe(0xff); m_in_port_cb[7] = &m_in_ph_cb;
|
||||
|
||||
m_out_pa_cb.resolve_safe(); m_out_port_cb[0] = &m_out_pa_cb;
|
||||
m_out_pb_cb.resolve_safe(); m_out_port_cb[1] = &m_out_pb_cb;
|
||||
m_out_pc_cb.resolve_safe(); m_out_port_cb[2] = &m_out_pc_cb;
|
||||
m_out_pd_cb.resolve_safe(); m_out_port_cb[3] = &m_out_pd_cb;
|
||||
m_out_pe_cb.resolve_safe(); m_out_port_cb[4] = &m_out_pe_cb;
|
||||
m_out_pf_cb.resolve_safe(); m_out_port_cb[5] = &m_out_pf_cb;
|
||||
m_out_pg_cb.resolve_safe(); m_out_port_cb[6] = &m_out_pg_cb;
|
||||
m_out_ph_cb.resolve_safe(); m_out_port_cb[7] = &m_out_ph_cb;
|
||||
|
||||
m_out_cnt0_cb.resolve_safe(); m_out_cnt_cb[0] = &m_out_cnt0_cb;
|
||||
m_out_cnt1_cb.resolve_safe(); m_out_cnt_cb[1] = &m_out_cnt1_cb;
|
||||
m_out_cnt2_cb.resolve_safe(); m_out_cnt_cb[2] = &m_out_cnt2_cb;
|
||||
|
||||
// register for savestates
|
||||
save_item(NAME(m_output_latch));
|
||||
save_item(NAME(m_cnt));
|
||||
save_item(NAME(m_dir));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void sega_315_5296_device::device_reset()
|
||||
{
|
||||
// all ports are set to input
|
||||
m_dir = 0;
|
||||
|
||||
// clear output ports
|
||||
memset(m_output_latch, 0, sizeof(m_output_latch));
|
||||
m_cnt = 0;
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
(*m_out_port_cb[i])((offs_t)i, 0);
|
||||
for (int i = 0; i < 3; i++)
|
||||
(*m_out_cnt_cb[i])(0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER( sega_315_5296_device::read )
|
||||
{
|
||||
offset &= 0xf;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// port A to H
|
||||
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
||||
// if the port is configured as an output, return the last thing written
|
||||
if (m_dir & 1 << offset)
|
||||
return m_output_latch[offset];
|
||||
|
||||
// otherwise, return an input port
|
||||
return (*m_in_port_cb[offset])(offset);
|
||||
|
||||
// 'SEGA' protection
|
||||
case 0x8:
|
||||
return 'S';
|
||||
case 0x9:
|
||||
return 'E';
|
||||
case 0xa:
|
||||
return 'G';
|
||||
case 0xb:
|
||||
return 'A';
|
||||
|
||||
// CNT register & mirror
|
||||
case 0xc: case 0xe:
|
||||
return m_cnt;
|
||||
|
||||
// port direction register & mirror
|
||||
case 0xd: case 0xf:
|
||||
return m_dir;
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
|
||||
WRITE8_MEMBER( sega_315_5296_device::write )
|
||||
{
|
||||
offset &= 0xf;
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
// port A to H
|
||||
case 0x0: case 0x1: case 0x2: case 0x3: case 0x4: case 0x5: case 0x6: case 0x7:
|
||||
// if the port is configured as an output, write it
|
||||
if (m_dir & 1 << offset)
|
||||
(*m_out_port_cb[offset])(offset, data);
|
||||
|
||||
m_output_latch[offset] = data;
|
||||
break;
|
||||
|
||||
// CNT register
|
||||
case 0xe:
|
||||
// d0-2: CNT0-2, other bits: ?
|
||||
for (int i = 0; i < 3; i++)
|
||||
(*m_out_cnt_cb[i])(data >> i & 1);
|
||||
|
||||
m_cnt = data;
|
||||
break;
|
||||
|
||||
// port direction register
|
||||
case 0xf:
|
||||
// refresh output ports if the direction changed
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
if ((m_dir ^ data) & (1 << i))
|
||||
(*m_out_port_cb[i])((offs_t)i, (data & 1 << i) ? m_output_latch[i] : 0);
|
||||
}
|
||||
|
||||
m_dir = data;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
145
src/mame/machine/315-5296.h
Normal file
145
src/mame/machine/315-5296.h
Normal file
@ -0,0 +1,145 @@
|
||||
/**********************************************************************
|
||||
|
||||
Sega 315-5296 I/O chip
|
||||
|
||||
Copyright MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
**********************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _SEGA_315_5296_H
|
||||
#define _SEGA_315_5296_H
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
// A to H 8-bit input ports
|
||||
#define MCFG_315_5296_IN_PORTA_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pa_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTB_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pb_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTC_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pc_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTD_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pd_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTE_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pe_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTF_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pf_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTG_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_pg_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_IN_PORTH_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_in_ph_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
// A to H 8-bit output ports
|
||||
#define MCFG_315_5296_OUT_PORTA_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pa_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTB_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pb_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTC_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pc_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTD_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pd_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTE_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pe_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTF_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pf_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTG_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_pg_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_PORTH_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_ph_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
// CNT output pins
|
||||
#define MCFG_315_5296_OUT_CNT0_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_cnt0_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_CNT1_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_cnt1_callback(*device, DEVCB_##_devcb);
|
||||
#define MCFG_315_5296_OUT_CNT2_CB(_devcb) \
|
||||
devcb = &sega_315_5296_device::set_out_cnt2_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> sega_315_5296_device
|
||||
|
||||
class sega_315_5296_device : public device_t
|
||||
{
|
||||
public:
|
||||
sega_315_5296_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// static configuration helpers
|
||||
template<class _Object> static devcb_base &set_in_pa_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pa_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_pb_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pb_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_pc_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pc_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_pd_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pd_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_pe_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pe_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_pf_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pf_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_pg_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_pg_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_in_ph_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_in_ph_cb.set_callback(object); }
|
||||
|
||||
template<class _Object> static devcb_base &set_out_pa_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pa_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_pb_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pb_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_pc_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pc_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_pd_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pd_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_pe_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pe_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_pf_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pf_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_pg_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_pg_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_ph_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_ph_cb.set_callback(object); }
|
||||
|
||||
template<class _Object> static devcb_base &set_out_cnt0_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_cnt0_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_cnt1_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_cnt1_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_out_cnt2_callback(device_t &device, _Object object) { return downcast<sega_315_5296_device &>(device).m_out_cnt2_cb.set_callback(object); }
|
||||
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
private:
|
||||
devcb_read8 m_in_pa_cb;
|
||||
devcb_read8 m_in_pb_cb;
|
||||
devcb_read8 m_in_pc_cb;
|
||||
devcb_read8 m_in_pd_cb;
|
||||
devcb_read8 m_in_pe_cb;
|
||||
devcb_read8 m_in_pf_cb;
|
||||
devcb_read8 m_in_pg_cb;
|
||||
devcb_read8 m_in_ph_cb;
|
||||
|
||||
devcb_write8 m_out_pa_cb;
|
||||
devcb_write8 m_out_pb_cb;
|
||||
devcb_write8 m_out_pc_cb;
|
||||
devcb_write8 m_out_pd_cb;
|
||||
devcb_write8 m_out_pe_cb;
|
||||
devcb_write8 m_out_pf_cb;
|
||||
devcb_write8 m_out_pg_cb;
|
||||
devcb_write8 m_out_ph_cb;
|
||||
|
||||
devcb_write_line m_out_cnt0_cb;
|
||||
devcb_write_line m_out_cnt1_cb;
|
||||
devcb_write_line m_out_cnt2_cb;
|
||||
|
||||
devcb_read8 *m_in_port_cb[8];
|
||||
devcb_write8 *m_out_port_cb[8];
|
||||
devcb_write_line *m_out_cnt_cb[3];
|
||||
|
||||
UINT8 m_output_latch[8];
|
||||
UINT8 m_cnt;
|
||||
UINT8 m_dir;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
extern const device_type SEGA_315_5296;
|
||||
|
||||
|
||||
#endif /* _SEGA_315_5296_H */
|
@ -1727,6 +1727,7 @@ $(MAMEOBJ)/sega.a: \
|
||||
$(DRIVERS)/turbo.o $(AUDIO)/turbo.o $(VIDEO)/turbo.o \
|
||||
$(DRIVERS)/vicdual.o $(AUDIO)/vicdual.o $(VIDEO)/vicdual.o $(AUDIO)/carnival.o $(AUDIO)/depthch.o $(AUDIO)/invinco.o $(AUDIO)/pulsar.o \
|
||||
$(DRIVERS)/zaxxon.o $(AUDIO)/zaxxon.o $(VIDEO)/zaxxon.o \
|
||||
$(MACHINE)/315-5296.o \
|
||||
$(MACHINE)/fd1089.o \
|
||||
$(MACHINE)/fd1094.o \
|
||||
$(MACHINE)/fddebug.o \
|
||||
|
Loading…
Reference in New Issue
Block a user