mirror of
https://github.com/holub/mame
synced 2025-07-05 18:08:04 +03:00
updated pokey to use delegates for its callbacks. nw.
This commit is contained in:
parent
7d95c2eea9
commit
8aafe83a1c
@ -185,8 +185,6 @@ pokey_device::pokey_device(const machine_config &mconfig, const char *tag, devic
|
||||
device_sound_interface(mconfig, *this),
|
||||
device_execute_interface(mconfig, *this),
|
||||
device_state_interface(mconfig, *this),
|
||||
m_kbd_r(NULL),
|
||||
m_irq_f(NULL),
|
||||
m_output_type(LEGACY_LINEAR),
|
||||
m_icount(0),
|
||||
m_stream(NULL),
|
||||
@ -225,6 +223,10 @@ void pokey_device::device_start()
|
||||
m_channel[CHAN2].m_INTMask = IRQ_TIMR2;
|
||||
m_channel[CHAN4].m_INTMask = IRQ_TIMR4;
|
||||
|
||||
// bind callbacks
|
||||
m_keyboard_r.bind_relative_to(*owner());
|
||||
m_irq_f.bind_relative_to(*owner());
|
||||
|
||||
/* calculate the A/D times
|
||||
* In normal, slow mode (SKCTL bit SK_PADDLE is clear) the conversion
|
||||
* takes N scanlines, where N is the paddle value. A single scanline
|
||||
@ -391,31 +393,29 @@ void pokey_device::device_timer(emu_timer &timer, device_timer_id id, int param,
|
||||
{
|
||||
case 3:
|
||||
/* serout_ready_cb */
|
||||
if( m_IRQEN & IRQ_SEROR )
|
||||
if (m_IRQEN & IRQ_SEROR)
|
||||
{
|
||||
m_IRQST |= IRQ_SEROR;
|
||||
if( m_irq_f )
|
||||
(m_irq_f)(this, IRQ_SEROR);
|
||||
if (!m_irq_f.isnull())
|
||||
m_irq_f(IRQ_SEROR);
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
/* serout_complete */
|
||||
if( m_IRQEN & IRQ_SEROC )
|
||||
if (m_IRQEN & IRQ_SEROC)
|
||||
{
|
||||
m_IRQST |= IRQ_SEROC;
|
||||
if( m_irq_f )
|
||||
(m_irq_f)(this, IRQ_SEROC);
|
||||
if (!m_irq_f.isnull())
|
||||
m_irq_f(IRQ_SEROC);
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
/* serin_ready */
|
||||
if( m_IRQEN & IRQ_SERIN )
|
||||
if (m_IRQEN & IRQ_SERIN)
|
||||
{
|
||||
/* set the enabled timer irq status bits */
|
||||
m_IRQST |= IRQ_SERIN;
|
||||
/* call back an application supplied function to handle the interrupt */
|
||||
if( m_irq_f )
|
||||
(m_irq_f)(this, IRQ_SERIN);
|
||||
if (!m_irq_f.isnull())
|
||||
m_irq_f(IRQ_SERIN);
|
||||
}
|
||||
break;
|
||||
case SYNC_WRITE:
|
||||
@ -477,26 +477,27 @@ void pokey_device::step_keyboard()
|
||||
{
|
||||
if (++m_kbd_cnt > 63)
|
||||
m_kbd_cnt = 0;
|
||||
if (m_kbd_r) {
|
||||
UINT8 ret = m_kbd_r(this, m_kbd_cnt);
|
||||
if (!m_keyboard_r.isnull())
|
||||
{
|
||||
UINT8 ret = m_keyboard_r(m_kbd_cnt);
|
||||
|
||||
switch (m_kbd_cnt)
|
||||
{
|
||||
case POK_KEY_BREAK:
|
||||
if (ret & 2)
|
||||
{
|
||||
/* check if the break IRQ is enabled */
|
||||
if( m_IRQEN & IRQ_BREAK )
|
||||
if (m_IRQEN & IRQ_BREAK)
|
||||
{
|
||||
/* set break IRQ status and call back the interrupt handler */
|
||||
m_IRQST |= IRQ_BREAK;
|
||||
if( m_irq_f )
|
||||
(*m_irq_f)(this, IRQ_BREAK);
|
||||
if (!m_irq_f.isnull())
|
||||
m_irq_f(IRQ_BREAK);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case POK_KEY_SHIFT:
|
||||
m_kbd_latch = (m_kbd_latch & 0xbf) | ((ret & 2) << 5);
|
||||
if( m_kbd_latch & 0x40 )
|
||||
if (m_kbd_latch & 0x40)
|
||||
m_SKSTAT |= SK_SHIFT;
|
||||
else
|
||||
m_SKSTAT &= ~SK_SHIFT;
|
||||
@ -522,14 +523,14 @@ void pokey_device::step_keyboard()
|
||||
{
|
||||
m_KBCODE = m_kbd_latch;
|
||||
m_SKSTAT |= SK_KEYBD;
|
||||
if( m_IRQEN & IRQ_KEYBD )
|
||||
if (m_IRQEN & IRQ_KEYBD)
|
||||
{
|
||||
/* last interrupt not acknowledged ? */
|
||||
if( m_IRQST & IRQ_KEYBD )
|
||||
if(m_IRQST & IRQ_KEYBD)
|
||||
m_SKSTAT |= SK_KBERR;
|
||||
m_IRQST |= IRQ_KEYBD;
|
||||
if( m_irq_f )
|
||||
(*m_irq_f)(this, IRQ_KEYBD);
|
||||
if (!m_irq_f.isnull())
|
||||
m_irq_f(IRQ_KEYBD);
|
||||
}
|
||||
m_kbd_state++;
|
||||
}
|
||||
@ -646,8 +647,8 @@ UINT32 pokey_device::step_one_clock(void)
|
||||
process_channel(CHAN2);
|
||||
|
||||
/* check if some of the requested timer interrupts are enabled */
|
||||
if ((m_IRQST & IRQ_TIMR2) && m_irq_f )
|
||||
(*m_irq_f)(this, IRQ_TIMR2);
|
||||
if ((m_IRQST & IRQ_TIMR2) && !m_irq_f.isnull())
|
||||
m_irq_f(IRQ_TIMR2);
|
||||
}
|
||||
|
||||
if (m_channel[CHAN1].check_borrow())
|
||||
@ -659,8 +660,8 @@ UINT32 pokey_device::step_one_clock(void)
|
||||
m_channel[CHAN1].reset_channel();
|
||||
process_channel(CHAN1);
|
||||
/* check if some of the requested timer interrupts are enabled */
|
||||
if ((m_IRQST & IRQ_TIMR1) && m_irq_f )
|
||||
(*m_irq_f)(this, IRQ_TIMR1);
|
||||
if ((m_IRQST & IRQ_TIMR1) && !m_irq_f.isnull())
|
||||
m_irq_f(IRQ_TIMR1);
|
||||
}
|
||||
|
||||
/* do CHAN4 before CHAN3 because CHAN3 may set borrow! */
|
||||
@ -676,8 +677,8 @@ UINT32 pokey_device::step_one_clock(void)
|
||||
m_channel[CHAN2].sample();
|
||||
else
|
||||
m_channel[CHAN2].m_filter_sample = 1;
|
||||
if ((m_IRQST & IRQ_TIMR4) && m_irq_f )
|
||||
(*m_irq_f)(this, IRQ_TIMR4);
|
||||
if ((m_IRQST & IRQ_TIMR4) && !m_irq_f.isnull())
|
||||
m_irq_f(IRQ_TIMR4);
|
||||
}
|
||||
|
||||
if (m_channel[CHAN3].check_borrow())
|
||||
|
@ -58,8 +58,11 @@
|
||||
// CALLBACK HANDLERS
|
||||
//**************************************************************************
|
||||
|
||||
#define POKEY_KEYBOARD_HANDLER(_name) UINT8 _name(pokey_device *device, UINT8 k543210)
|
||||
#define POKEY_INTERRUPT_HANDLER(_name) void _name(pokey_device *device, int mask)
|
||||
typedef device_delegate<UINT8 (UINT8 k543210)> pokey_kb_cb_delegate;
|
||||
typedef device_delegate<void (int mask)> pokey_int_cb_delegate;
|
||||
|
||||
#define POKEY_KEYBOARD_CB_MEMBER(_name) UINT8 _name(UINT8 k543210)
|
||||
#define POKEY_INTERRUPT_CB_MEMBER(_name) void _name(int mask)
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -101,11 +104,12 @@
|
||||
|
||||
/* k543210 = k5 ... k0 returns bit0: kr1, bit1: kr2 */
|
||||
/* all are, in contrast to actual hardware, ACTIVE_HIGH */
|
||||
#define MCFG_POKEY_KEYBOARD_HANDLER(_kbd) \
|
||||
(downcast<pokey_device *>(device))->m_kbd_r = _kbd;
|
||||
#define MCFG_POKEY_KEYBOARD_CB(_class, _method) \
|
||||
pokey_device::set_keyboard_callback(*device, pokey_kb_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
|
||||
|
||||
#define MCFG_POKEY_INTERRUPT_CB(_class, _method) \
|
||||
pokey_device::set_interrupt_callback(*device, pokey_int_cb_delegate(&_class::_method, #_class "::" #_method, downcast<_class *>(owner)));
|
||||
|
||||
#define MCFG_POKEY_INTERRUPT_HANDLER(_irqf) \
|
||||
(downcast<pokey_device *>(device))->m_irq_f = _irqf;
|
||||
|
||||
#define MCFG_POKEY_OUTPUT_RC(_R, _C, _V) \
|
||||
(downcast<pokey_device *>(device))->m_output_type = pokey_device::RC_LOWPASS; \
|
||||
@ -221,6 +225,9 @@ public:
|
||||
template<class _Object> static devcb_base &set_serin_r_callback(device_t &device, _Object object) { return downcast<pokey_device &>(device).m_serin_r_cb.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_serout_w_callback(device_t &device, _Object object) { return downcast<pokey_device &>(device).m_serout_w_cb.set_callback(object); }
|
||||
|
||||
static void set_keyboard_callback(device_t &device, pokey_kb_cb_delegate callback) { downcast<pokey_device &>(device).m_keyboard_r = callback; }
|
||||
static void set_interrupt_callback(device_t &device, pokey_int_cb_delegate callback) { downcast<pokey_device &>(device).m_irq_f = callback; }
|
||||
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
@ -229,11 +236,6 @@ public:
|
||||
|
||||
void serin_ready(int after);
|
||||
|
||||
// internal configuration
|
||||
|
||||
POKEY_KEYBOARD_HANDLER((*m_kbd_r));
|
||||
POKEY_INTERRUPT_HANDLER((*m_irq_f));
|
||||
|
||||
// analog output configuration
|
||||
|
||||
output_type m_output_type;
|
||||
@ -346,6 +348,9 @@ private:
|
||||
devcb_read8 m_serin_r_cb;
|
||||
devcb_write8 m_serout_w_cb;
|
||||
|
||||
pokey_kb_cb_delegate m_keyboard_r;
|
||||
pokey_int_cb_delegate m_irq_f;
|
||||
|
||||
UINT8 m_POTx[8]; /* POTx (R/D200-D207) */
|
||||
UINT8 m_AUDCTL; /* AUDCTL (W/D208) */
|
||||
UINT8 m_ALLPOT; /* ALLPOT (R/D208) */
|
||||
|
@ -147,8 +147,8 @@ static MACHINE_CONFIG_START( a5200, bartop52_state )
|
||||
MCFG_POKEY_POT1_R_CB(IOPORT("analog_1"))
|
||||
MCFG_POKEY_POT2_R_CB(IOPORT("analog_2"))
|
||||
MCFG_POKEY_POT3_R_CB(IOPORT("analog_3"))
|
||||
MCFG_POKEY_KEYBOARD_HANDLER(atari_a5200_keypads)
|
||||
MCFG_POKEY_INTERRUPT_HANDLER(atari_interrupt_cb)
|
||||
MCFG_POKEY_KEYBOARD_CB(atari_common_state, a5200_keypads)
|
||||
MCFG_POKEY_INTERRUPT_CB(atari_common_state, interrupt_cb)
|
||||
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
|
@ -457,7 +457,7 @@ static MACHINE_CONFIG_START( a600xl, maxaflex_state )
|
||||
MCFG_SPEAKER_STANDARD_MONO("mono")
|
||||
|
||||
MCFG_SOUND_ADD("pokey", POKEY, FREQ_17_EXACT)
|
||||
MCFG_POKEY_INTERRUPT_HANDLER(atari_interrupt_cb)
|
||||
MCFG_POKEY_INTERRUPT_CB(atari_common_state, interrupt_cb)
|
||||
MCFG_POKEY_OUTPUT_RC(RES_K(1), CAP_U(0.0), 5.0)
|
||||
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.0)
|
||||
|
@ -39,6 +39,10 @@ public:
|
||||
DECLARE_READ8_MEMBER ( atari_antic_r );
|
||||
DECLARE_WRITE8_MEMBER ( atari_antic_w );
|
||||
|
||||
POKEY_INTERRUPT_CB_MEMBER(interrupt_cb);
|
||||
POKEY_KEYBOARD_CB_MEMBER(a5200_keypads);
|
||||
POKEY_KEYBOARD_CB_MEMBER(a800_keyboard);
|
||||
|
||||
private:
|
||||
UINT32 tv_artifacts ;
|
||||
void prio_init();
|
||||
@ -55,13 +59,8 @@ private:
|
||||
inline void LMS(int new_cmd);
|
||||
void antic_scanline_dma(int param);
|
||||
void generic_atari_interrupt(int button_count);
|
||||
|
||||
};
|
||||
|
||||
void atari_interrupt_cb(pokey_device *device, int mask);
|
||||
POKEY_KEYBOARD_HANDLER(atari_a800_keyboard);
|
||||
POKEY_KEYBOARD_HANDLER(atari_a5200_keypads);
|
||||
|
||||
/* video */
|
||||
|
||||
#define CYCLES_PER_LINE 114 /* total number of cpu cycles per scanline (incl. hblank) */
|
||||
|
@ -18,7 +18,8 @@
|
||||
#define VERBOSE_SERIAL 1
|
||||
#define VERBOSE_TIMERS 1
|
||||
|
||||
void atari_interrupt_cb(pokey_device *device, int mask)
|
||||
|
||||
POKEY_INTERRUPT_CB_MEMBER(atari_common_state::interrupt_cb)
|
||||
{
|
||||
if (VERBOSE_POKEY)
|
||||
{
|
||||
@ -46,7 +47,7 @@ void atari_interrupt_cb(pokey_device *device, int mask)
|
||||
logerror("atari interrupt_cb TIMR1\n");
|
||||
}
|
||||
|
||||
device->machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE);
|
||||
machine().device("maincpu")->execute().set_input_line(0, HOLD_LINE);
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +88,7 @@ void atari_interrupt_cb(pokey_device *device, int mask)
|
||||
|
||||
**************************************************************/
|
||||
|
||||
POKEY_KEYBOARD_HANDLER(atari_a800_keyboard)
|
||||
POKEY_KEYBOARD_CB_MEMBER(atari_common_state::a800_keyboard)
|
||||
{
|
||||
int ipt;
|
||||
static const char *const tag[] = {
|
||||
@ -101,15 +102,15 @@ POKEY_KEYBOARD_HANDLER(atari_a800_keyboard)
|
||||
{
|
||||
case pokey_device::POK_KEY_BREAK:
|
||||
/* special case ... */
|
||||
ret |= ((device->machine().root_device().ioport(tag[0])->read_safe(0) & 0x08) ? 0x02 : 0x00);
|
||||
ret |= ((machine().root_device().ioport(tag[0])->read_safe(0) & 0x08) ? 0x02 : 0x00);
|
||||
break;
|
||||
case pokey_device::POK_KEY_CTRL:
|
||||
/* CTRL */
|
||||
ret |= ((device->machine().root_device().ioport("fake")->read_safe(0) & 0x02) ? 0x02 : 0x00);
|
||||
ret |= ((machine().root_device().ioport("fake")->read_safe(0) & 0x02) ? 0x02 : 0x00);
|
||||
break;
|
||||
case pokey_device::POK_KEY_SHIFT:
|
||||
/* SHIFT */
|
||||
ret |= ((device->machine().root_device().ioport("fake")->read_safe(0) & 0x01) ? 0x02 : 0x00);
|
||||
ret |= ((machine().root_device().ioport("fake")->read_safe(0) & 0x01) ? 0x02 : 0x00);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -118,7 +119,7 @@ POKEY_KEYBOARD_HANDLER(atari_a800_keyboard)
|
||||
return ret;
|
||||
|
||||
/* decode regular key */
|
||||
ipt = device->machine().root_device().ioport(tag[k543210 >> 3])->read_safe(0);
|
||||
ipt = machine().root_device().ioport(tag[k543210 >> 3])->read_safe(0);
|
||||
|
||||
if (ipt & (1 << (k543210 & 0x07)))
|
||||
ret |= 0x01;
|
||||
@ -155,7 +156,7 @@ POKEY_KEYBOARD_HANDLER(atari_a800_keyboard)
|
||||
|
||||
**************************************************************/
|
||||
|
||||
POKEY_KEYBOARD_HANDLER(atari_a5200_keypads)
|
||||
POKEY_KEYBOARD_CB_MEMBER(atari_common_state::a5200_keypads)
|
||||
{
|
||||
int ipt;
|
||||
static const char *const tag[] = { "keypad_0", "keypad_1", "keypad_2", "keypad_3" };
|
||||
@ -166,7 +167,7 @@ POKEY_KEYBOARD_HANDLER(atari_a5200_keypads)
|
||||
{
|
||||
case pokey_device::POK_KEY_BREAK:
|
||||
/* special case ... */
|
||||
ret |= ((device->machine().root_device().ioport(tag[0])->read_safe(0) & 0x01) ? 0x02 : 0x00);
|
||||
ret |= ((machine().root_device().ioport(tag[0])->read_safe(0) & 0x01) ? 0x02 : 0x00);
|
||||
break;
|
||||
case pokey_device::POK_KEY_CTRL:
|
||||
case pokey_device::POK_KEY_SHIFT:
|
||||
@ -184,9 +185,9 @@ POKEY_KEYBOARD_HANDLER(atari_a5200_keypads)
|
||||
if (k543210 == 0)
|
||||
return ret;
|
||||
|
||||
ipt = device->machine().root_device().ioport(tag[k543210 >> 2])->read_safe(0);
|
||||
ipt = machine().root_device().ioport(tag[k543210 >> 2])->read_safe(0);
|
||||
|
||||
if (ipt & (1 <<(k543210 & 0x03)))
|
||||
if (ipt & (1 << (k543210 & 0x03)))
|
||||
ret |= 0x01;
|
||||
|
||||
return ret;
|
||||
|
@ -2028,8 +2028,8 @@ static MACHINE_CONFIG_START( atari_common_nodac, a400_state )
|
||||
MCFG_POKEY_POT7_R_CB(IOPORT("analog_7"))
|
||||
MCFG_POKEY_SERIN_R_CB(DEVREAD8("fdc", atari_fdc_device, serin_r))
|
||||
MCFG_POKEY_SEROUT_W_CB(DEVWRITE8("fdc", atari_fdc_device, serout_w))
|
||||
MCFG_POKEY_KEYBOARD_HANDLER(atari_a800_keyboard)
|
||||
MCFG_POKEY_INTERRUPT_HANDLER(atari_interrupt_cb)
|
||||
MCFG_POKEY_KEYBOARD_CB(atari_common_state, a800_keyboard)
|
||||
MCFG_POKEY_INTERRUPT_CB(atari_common_state, interrupt_cb)
|
||||
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
MACHINE_CONFIG_END
|
||||
@ -2222,8 +2222,8 @@ static MACHINE_CONFIG_DERIVED( a5200, atari_common_nodac )
|
||||
MCFG_SOUND_MODIFY("pokey")
|
||||
MCFG_POKEY_SERIN_R_CB(NULL)
|
||||
MCFG_POKEY_SEROUT_W_CB(NULL)
|
||||
MCFG_POKEY_KEYBOARD_HANDLER(atari_a5200_keypads)
|
||||
MCFG_POKEY_INTERRUPT_HANDLER(atari_interrupt_cb)
|
||||
MCFG_POKEY_KEYBOARD_CB(atari_common_state, a5200_keypads)
|
||||
MCFG_POKEY_INTERRUPT_CB(atari_common_state, interrupt_cb)
|
||||
|
||||
MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user