mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
New callback for generic_latch_8/16_device (nw)
- Add MCFG_GENERIC_LATCH_DATA_PENDING_CB to raise and lower a line automatically as the latch is written and read. This should make sound IRQs easier to deliver and reduce the incidence of HOLD_LINE in drivers. - Update a few drivers to use this new callback.
This commit is contained in:
parent
2b74e4c0be
commit
95a914d30e
@ -5,6 +5,7 @@
|
||||
Generic 8bit and 16 bit latch devices
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "gen_latch.h"
|
||||
|
||||
@ -13,26 +14,70 @@
|
||||
//**************************************************************************
|
||||
|
||||
const device_type GENERIC_LATCH_8 = &device_creator<generic_latch_8_device>;
|
||||
|
||||
const device_type GENERIC_LATCH_16 = &device_creator<generic_latch_16_device>;
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// generic_latch_base_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
generic_latch_base_device::generic_latch_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source) :
|
||||
device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
m_latch_read(false),
|
||||
m_data_pending_cb(*this)
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void generic_latch_base_device::device_start()
|
||||
{
|
||||
m_data_pending_cb.resolve_safe();
|
||||
save_item(NAME(m_latch_read));
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// pending_r - tell whether the latch is waiting
|
||||
// to be read
|
||||
//-------------------------------------------------
|
||||
|
||||
READ_LINE_MEMBER(generic_latch_base_device::pending_r)
|
||||
{
|
||||
return !m_latch_read;
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_latch_read - helper to signal that latch
|
||||
// has been read or is waiting to be read
|
||||
//-------------------------------------------------
|
||||
|
||||
void generic_latch_base_device::set_latch_read(bool latch_read)
|
||||
{
|
||||
if (m_latch_read != latch_read)
|
||||
{
|
||||
m_latch_read = latch_read;
|
||||
m_data_pending_cb(!latch_read);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// generic_latch_8_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
generic_latch_8_device::generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, GENERIC_LATCH_8, "Generic 8-bit latch", tag, owner, clock, "generic_latch_8", __FILE__),
|
||||
m_latched_value(0),
|
||||
m_latch_read(0)
|
||||
generic_latch_8_device::generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
generic_latch_base_device(mconfig, GENERIC_LATCH_8, "Generic 8-bit latch", tag, owner, clock, "generic_latch_8", __FILE__),
|
||||
m_latched_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
READ8_MEMBER( generic_latch_8_device::read )
|
||||
{
|
||||
m_latch_read = 1;
|
||||
set_latch_read(true);
|
||||
return m_latched_value;
|
||||
}
|
||||
|
||||
@ -66,17 +111,17 @@ WRITE_LINE_MEMBER( generic_latch_8_device::clear_w )
|
||||
// callback to set a latch value
|
||||
//-------------------------------------------------
|
||||
|
||||
void generic_latch_8_device::sync_callback(void *ptr, int32_t param)
|
||||
void generic_latch_8_device::sync_callback(void *ptr, s32 param)
|
||||
{
|
||||
uint8_t value = param;
|
||||
u8 value = param;
|
||||
|
||||
// if the latch hasn't been read and the value is changed, log a warning
|
||||
if (!m_latch_read && m_latched_value != value)
|
||||
logerror("Warning: latch %s written before being read. Previous: %02x, new: %02x\n", tag(), m_latched_value, value);
|
||||
if (!is_latch_read() && m_latched_value != value)
|
||||
logerror("Warning: latch written before being read. Previous: %02x, new: %02x\n", m_latched_value, value);
|
||||
|
||||
// store the new value and mark it not read
|
||||
m_latched_value = value;
|
||||
m_latch_read = 0;
|
||||
set_latch_read(false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -86,35 +131,23 @@ void generic_latch_8_device::sync_callback(void *ptr, int32_t param)
|
||||
void generic_latch_8_device::device_start()
|
||||
{
|
||||
// register for state saving
|
||||
generic_latch_base_device::device_start();
|
||||
save_item(NAME(m_latched_value));
|
||||
save_item(NAME(m_latch_read));
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
const device_type GENERIC_LATCH_16 = &device_creator<generic_latch_16_device>;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// generic_latch_16_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
generic_latch_16_device::generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||
device_t(mconfig, GENERIC_LATCH_16, "Generic 16-bit latch", tag, owner, clock, "generic_latch_16", __FILE__),
|
||||
m_latched_value(0),
|
||||
m_latch_read(0)
|
||||
generic_latch_16_device::generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
|
||||
generic_latch_base_device(mconfig, GENERIC_LATCH_16, "Generic 16-bit latch", tag, owner, clock, "generic_latch_16", __FILE__),
|
||||
m_latched_value(0)
|
||||
{
|
||||
}
|
||||
|
||||
READ16_MEMBER( generic_latch_16_device::read )
|
||||
{
|
||||
m_latch_read = 1;
|
||||
set_latch_read(true);
|
||||
return m_latched_value;
|
||||
}
|
||||
|
||||
@ -148,17 +181,17 @@ WRITE_LINE_MEMBER( generic_latch_16_device::clear_w )
|
||||
// callback to set a latch value
|
||||
//-------------------------------------------------
|
||||
|
||||
void generic_latch_16_device::sync_callback(void *ptr, int32_t param)
|
||||
void generic_latch_16_device::sync_callback(void *ptr, s32 param)
|
||||
{
|
||||
uint16_t value = param;
|
||||
u16 value = param;
|
||||
|
||||
// if the latch hasn't been read and the value is changed, log a warning
|
||||
if (!m_latch_read && m_latched_value != value)
|
||||
logerror("Warning: latch %s written before being read. Previous: %02x, new: %02x\n", tag(), m_latched_value, value);
|
||||
if (!is_latch_read() && m_latched_value != value)
|
||||
logerror("Warning: latch written before being read. Previous: %02x, new: %02x\n", m_latched_value, value);
|
||||
|
||||
// store the new value and mark it not read
|
||||
m_latched_value = value;
|
||||
m_latch_read = 0;
|
||||
set_latch_read(false);
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
@ -168,6 +201,6 @@ void generic_latch_16_device::sync_callback(void *ptr, int32_t param)
|
||||
void generic_latch_16_device::device_start()
|
||||
{
|
||||
// register for state saving
|
||||
generic_latch_base_device::device_start();
|
||||
save_item(NAME(m_latched_value));
|
||||
save_item(NAME(m_latch_read));
|
||||
}
|
||||
|
@ -11,6 +11,8 @@
|
||||
#ifndef __GEN_LATCH_H__
|
||||
#define __GEN_LATCH_H__
|
||||
|
||||
#include "emu.h"
|
||||
|
||||
//**************************************************************************
|
||||
// INTERFACE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
@ -21,17 +23,46 @@
|
||||
#define MCFG_GENERIC_LATCH_16_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD(_tag, GENERIC_LATCH_16, 0)
|
||||
|
||||
#define MCFG_GENERIC_LATCH_DATA_PENDING_CB(_devcb) \
|
||||
devcb = &generic_latch_base_device::set_data_pending_callback(*device, DEVCB_##_devcb);
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> generic_latch_base_device
|
||||
|
||||
class generic_latch_base_device : public device_t
|
||||
{
|
||||
protected:
|
||||
// construction/destruction
|
||||
generic_latch_base_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, u32 clock, const char *shortname, const char *source);
|
||||
|
||||
public:
|
||||
// static configuration
|
||||
template<class _Object> static devcb_base &set_data_pending_callback(device_t &device, _Object object) { return downcast<generic_latch_base_device &>(device).m_data_pending_cb.set_callback(object); }
|
||||
|
||||
DECLARE_READ_LINE_MEMBER(pending_r);
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
|
||||
bool is_latch_read() const { return m_latch_read; }
|
||||
void set_latch_read(bool latch_read);
|
||||
|
||||
private:
|
||||
bool m_latch_read;
|
||||
devcb_write_line m_data_pending_cb;
|
||||
};
|
||||
|
||||
|
||||
// ======================> generic_latch_8_device
|
||||
|
||||
class generic_latch_8_device : public device_t
|
||||
class generic_latch_8_device : public generic_latch_base_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
generic_latch_8_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
@ -41,15 +72,15 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER( preset_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( clear_w );
|
||||
|
||||
void preset_w(uint16_t value) { m_latched_value = value; }
|
||||
void preset_w(u8 value) { m_latched_value = value; }
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
|
||||
void sync_callback(void *ptr, int32_t param);
|
||||
void sync_callback(void *ptr, s32 param);
|
||||
|
||||
private:
|
||||
uint16_t m_latched_value;
|
||||
uint8_t m_latch_read;
|
||||
u8 m_latched_value;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
@ -58,11 +89,11 @@ extern const device_type GENERIC_LATCH_8;
|
||||
|
||||
// ======================> generic_latch_16_device
|
||||
|
||||
class generic_latch_16_device : public device_t
|
||||
class generic_latch_16_device : public generic_latch_base_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
generic_latch_16_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
|
||||
|
||||
DECLARE_READ16_MEMBER( read );
|
||||
DECLARE_WRITE16_MEMBER( write );
|
||||
@ -72,13 +103,15 @@ public:
|
||||
DECLARE_WRITE_LINE_MEMBER( preset_w );
|
||||
DECLARE_WRITE_LINE_MEMBER( clear_w );
|
||||
|
||||
void preset_w(u16 value) { m_latched_value = value; }
|
||||
|
||||
protected:
|
||||
virtual void device_start() override;
|
||||
|
||||
void sync_callback(void *ptr, int32_t param);
|
||||
void sync_callback(void *ptr, s32 param);
|
||||
|
||||
private:
|
||||
uint16_t m_latched_value;
|
||||
uint8_t m_latch_read;
|
||||
u16 m_latched_value;
|
||||
};
|
||||
|
||||
// device type definition
|
||||
|
@ -229,10 +229,7 @@ WRITE16_MEMBER(dec0_automat_state::automat_control_w)
|
||||
{
|
||||
case 0xe: /* z80 sound cpu */
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
m_soundlatch->write(space, 0, data & 0xff);
|
||||
m_audiocpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
break;
|
||||
|
||||
case 12: /* DMA flag */
|
||||
@ -282,15 +279,6 @@ WRITE16_MEMBER(dec0_state::midres_sound_w)
|
||||
}
|
||||
}
|
||||
|
||||
WRITE16_MEMBER(dec0_automat_state::secretab_sound_w)
|
||||
{
|
||||
if (ACCESSING_BITS_0_7)
|
||||
{
|
||||
m_soundlatch->write(space, 0, data & 0xff);
|
||||
m_audiocpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
static ADDRESS_MAP_START( dec0_map, AS_PROGRAM, 16, dec0_state )
|
||||
@ -621,7 +609,7 @@ static ADDRESS_MAP_START( secretab_map, AS_PROGRAM, 16, dec0_automat_state )
|
||||
// AM_RANGE(0x340400, 0x3407ff) AM_DEVREADWRITE("tilegen1", deco_bac06_device, pf_rowscroll_r, pf_rowscroll_w)
|
||||
|
||||
AM_RANGE(0x314008, 0x31400f) AM_READ(slyspy_controls_r)
|
||||
AM_RANGE(0x314000, 0x314001) AM_WRITE(secretab_sound_w)
|
||||
AM_RANGE(0x314000, 0x314001) AM_DEVWRITE8("soundlatch", generic_latch_8_device, write, 0x00ff)
|
||||
|
||||
AM_RANGE(0x300000, 0x300007) AM_RAM
|
||||
AM_RANGE(0x300010, 0x300017) AM_RAM
|
||||
@ -640,7 +628,7 @@ static ADDRESS_MAP_START( automat_s_map, AS_PROGRAM, 8, dec0_automat_state )
|
||||
AM_RANGE(0xc000, 0xc7ff) AM_RAM
|
||||
AM_RANGE(0xc800, 0xc801) AM_DEVREADWRITE("2203a", ym2203_device, read, write)
|
||||
AM_RANGE(0xd000, 0xd001) AM_DEVREADWRITE("2203b", ym2203_device, read, write)
|
||||
AM_RANGE(0xd800, 0xd800) AM_READ(sound_command_r)
|
||||
AM_RANGE(0xd800, 0xd800) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
|
||||
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("adpcm_select2", ls157_device, ba_w)
|
||||
AM_RANGE(0xe800, 0xe800) AM_WRITE(sound_bankswitch_w)
|
||||
AM_RANGE(0xf000, 0xf000) AM_DEVWRITE("adpcm_select1", ls157_device, ba_w)
|
||||
@ -652,7 +640,7 @@ static ADDRESS_MAP_START( secretab_s_map, AS_PROGRAM, 8, dec0_automat_state )
|
||||
AM_RANGE(0xc000, 0xc7ff) AM_RAM
|
||||
AM_RANGE(0xc800, 0xc801) AM_DEVREADWRITE("2203a", ym2203_device, read, write)
|
||||
AM_RANGE(0xd000, 0xd001) AM_DEVREADWRITE("ym3812", ym3812_device, read, write)
|
||||
AM_RANGE(0xd800, 0xd800) AM_READ(sound_command_r)
|
||||
AM_RANGE(0xd800, 0xd800) AM_DEVREAD("soundlatch", generic_latch_8_device, read)
|
||||
AM_RANGE(0xe000, 0xe000) AM_DEVWRITE("adpcm_select2", ls157_device, ba_w)
|
||||
AM_RANGE(0xe800, 0xe800) AM_WRITE(sound_bankswitch_w)
|
||||
AM_RANGE(0xf000, 0xf000) AM_DEVWRITE("adpcm_select1", ls157_device, ba_w)
|
||||
@ -1385,12 +1373,6 @@ static MACHINE_CONFIG_DERIVED( dec1, dec0_base )
|
||||
MACHINE_CONFIG_END
|
||||
|
||||
|
||||
READ8_MEMBER(dec0_automat_state::sound_command_r)
|
||||
{
|
||||
m_audiocpu->set_input_line(0, CLEAR_LINE);
|
||||
return m_soundlatch->read(space, 0);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(dec0_automat_state::sound_bankswitch_w)
|
||||
{
|
||||
m_msm1->reset_w(BIT(data, 3));
|
||||
@ -1462,6 +1444,7 @@ static MACHINE_CONFIG_START( automat, dec0_automat_state )
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
|
||||
MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
|
||||
|
||||
MCFG_SOUND_ADD("2203a", YM2203, 1250000)
|
||||
MCFG_SOUND_ROUTE(0, "mono", 0.90)
|
||||
@ -1536,6 +1519,7 @@ static MACHINE_CONFIG_START( secretab, dec0_automat_state )
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
|
||||
MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
|
||||
|
||||
MCFG_SOUND_ADD("2203a", YM2203, 1250000)
|
||||
MCFG_SOUND_ROUTE(0, "mono", 0.90)
|
||||
|
@ -88,7 +88,6 @@ public:
|
||||
DECLARE_WRITE8_MEMBER(rambank_select_w);
|
||||
DECLARE_WRITE8_MEMBER(discoboy_port_00_w);
|
||||
DECLARE_WRITE8_MEMBER(discoboy_port_01_w);
|
||||
DECLARE_WRITE8_MEMBER(discoboy_port_03_w);
|
||||
DECLARE_WRITE8_MEMBER(discoboy_port_06_w);
|
||||
DECLARE_WRITE8_MEMBER(rambank_w);
|
||||
DECLARE_READ8_MEMBER(rambank_r);
|
||||
@ -249,14 +248,6 @@ WRITE8_MEMBER(discoboy_state::discoboy_port_01_w)
|
||||
membank("bank1")->set_entry(data & 0x07);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(discoboy_state::discoboy_port_03_w)// sfx? (to sound cpu)
|
||||
{
|
||||
// printf("unk discoboy_port_03_w %02x\n", data);
|
||||
// m_audiocpu->set_input_line(INPUT_LINE_NMI, HOLD_LINE);
|
||||
m_soundlatch->write(space, 0, data);
|
||||
m_audiocpu->set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(discoboy_state::discoboy_port_06_w)
|
||||
{
|
||||
//printf("unk discoboy_port_06_w %02x\n",data);
|
||||
@ -333,7 +324,7 @@ static ADDRESS_MAP_START( io_map, AS_IO, 8, discoboy_state )
|
||||
AM_RANGE(0x00, 0x00) AM_READ_PORT("DSWA") AM_WRITE(discoboy_port_00_w)
|
||||
AM_RANGE(0x01, 0x01) AM_READ_PORT("SYSTEM") AM_WRITE(discoboy_port_01_w)
|
||||
AM_RANGE(0x02, 0x02) AM_READ_PORT("P1")
|
||||
AM_RANGE(0x03, 0x03) AM_READ_PORT("P2") AM_WRITE(discoboy_port_03_w)
|
||||
AM_RANGE(0x03, 0x03) AM_READ_PORT("P2") AM_DEVWRITE("soundlatch", generic_latch_8_device, write)
|
||||
AM_RANGE(0x04, 0x04) AM_READ_PORT("DSWB")
|
||||
AM_RANGE(0x06, 0x06) AM_READWRITE(discoboy_port_06_r, discoboy_port_06_w) // ???
|
||||
AM_RANGE(0x07, 0x07) AM_WRITE(rambank_select_w) // 0x20 is palette bank bit.. others?
|
||||
@ -512,6 +503,7 @@ static MACHINE_CONFIG_START( discoboy, discoboy_state )
|
||||
MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker")
|
||||
|
||||
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
|
||||
MCFG_GENERIC_LATCH_DATA_PENDING_CB(INPUTLINE("audiocpu", 0))
|
||||
|
||||
MCFG_SOUND_ADD("ymsnd", YM3812, XTAL_10MHz/4) /* 2.5 MHz? */
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "lspeaker", 0.6)
|
||||
|
@ -134,14 +134,12 @@ public:
|
||||
uint16_t m_automat_scroll_regs[4];
|
||||
|
||||
DECLARE_WRITE16_MEMBER(automat_control_w);
|
||||
DECLARE_WRITE16_MEMBER(secretab_sound_w);
|
||||
DECLARE_READ16_MEMBER( automat_palette_r );
|
||||
DECLARE_WRITE16_MEMBER( automat_palette_w );
|
||||
DECLARE_WRITE16_MEMBER( automat_scroll_w )
|
||||
{
|
||||
COMBINE_DATA(&m_automat_scroll_regs[offset]);
|
||||
}
|
||||
DECLARE_READ8_MEMBER(sound_command_r);
|
||||
DECLARE_WRITE8_MEMBER(sound_bankswitch_w);
|
||||
DECLARE_WRITE_LINE_MEMBER(msm1_vclk_cb);
|
||||
DECLARE_WRITE_LINE_MEMBER(msm2_vclk_cb);
|
||||
|
Loading…
Reference in New Issue
Block a user