updated pokey to use delegates for its callbacks. nw.

This commit is contained in:
Fabio Priuli 2014-09-03 16:20:35 +00:00
parent 7d95c2eea9
commit 8aafe83a1c
7 changed files with 70 additions and 64 deletions

View File

@ -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())

View File

@ -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) */

View File

@ -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)

View File

@ -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)

View File

@ -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) */

View File

@ -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;

View File

@ -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)