mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
sega_315_5250: Interrupt callback modernization (nw)
This commit is contained in:
parent
66153a3df5
commit
52c93bdc1d
@ -294,7 +294,6 @@ segaxbd_state::segaxbd_state(const machine_config &mconfig, device_type type, co
|
||||
, m_sprites(*this, "sprites")
|
||||
, m_segaic16vid(*this, "segaic16vid")
|
||||
, m_segaic16road(*this, "segaic16road")
|
||||
, m_soundlatch(*this, "soundlatch")
|
||||
, m_subram0(*this, "subram0")
|
||||
, m_road_priority(1)
|
||||
, m_scanline_timer(nullptr)
|
||||
@ -348,7 +347,7 @@ void segaxbd_state::device_reset()
|
||||
m_maincpu->set_reset_callback(write_line_delegate(FUNC(segaxbd_state::m68k_reset_callback),this));
|
||||
|
||||
// start timers to track interrupts
|
||||
m_scanline_timer->adjust(m_screen->time_until_pos(1), 1);
|
||||
m_scanline_timer->adjust(m_screen->time_until_pos(0), 0);
|
||||
}
|
||||
|
||||
|
||||
@ -452,28 +451,18 @@ const auto SOUND_CLOCK = XTAL(16'000'000);
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// timer_ack_callback - acknowledge a timer chip
|
||||
// interrupt signal
|
||||
// timer_irq_w - handle the interrupt signal from
|
||||
// the timer chip
|
||||
//-------------------------------------------------
|
||||
|
||||
void segaxbd_state::timer_ack_callback()
|
||||
WRITE_LINE_MEMBER(segaxbd_state::timer_irq_w)
|
||||
{
|
||||
// clear the timer IRQ
|
||||
m_timer_irq_state = 0;
|
||||
// set/clear the timer IRQ
|
||||
m_timer_irq_state = (state == ASSERT_LINE);
|
||||
update_main_irqs();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_data_w - write data to the sound CPU
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE8_MEMBER(segaxbd_state::sound_data_w)
|
||||
{
|
||||
synchronize(TID_SOUND_WRITE, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// MAIN CPU READ/WRITE CALLBACKS
|
||||
@ -631,22 +620,6 @@ WRITE16_MEMBER( segaxbd_state::smgp_excs_w )
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// SOUND Z80 CPU READ/WRITE CALLBACKS
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_data_r - read latched sound data
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER( segaxbd_state::sound_data_r )
|
||||
{
|
||||
m_soundcpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE);
|
||||
return m_soundlatch->read(space, 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DRIVER OVERRIDES
|
||||
//**************************************************************************
|
||||
@ -659,48 +632,30 @@ void segaxbd_state::device_timer(emu_timer &timer, device_timer_id id, int param
|
||||
{
|
||||
switch (id)
|
||||
{
|
||||
case TID_SOUND_WRITE:
|
||||
m_soundlatch->write(m_soundcpu->space(AS_PROGRAM), 0, param);
|
||||
m_soundcpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
|
||||
// if an extra sound board is attached, do an nmi there as well
|
||||
if (m_soundcpu2 != nullptr)
|
||||
m_soundcpu2->set_input_line(INPUT_LINE_NMI, ASSERT_LINE);
|
||||
break;
|
||||
|
||||
case TID_SCANLINE:
|
||||
{
|
||||
int scanline = param;
|
||||
int next_scanline = (scanline + 2) % 262;
|
||||
bool update = false;
|
||||
int next_scanline = (scanline + 1) % 262;
|
||||
|
||||
// clock the timer and set the IRQ if something happened
|
||||
if ((scanline % 2) != 0 && m_cmptimer_1->clock())
|
||||
m_timer_irq_state = 1, update = true;
|
||||
// clock the timer with V0
|
||||
m_cmptimer_1->exck_w(scanline % 2);
|
||||
|
||||
// set VBLANK on scanline 223
|
||||
if (scanline == 223)
|
||||
{
|
||||
m_vblank_irq_state = 1;
|
||||
update = true;
|
||||
m_subcpu->set_input_line(4, ASSERT_LINE);
|
||||
next_scanline = scanline + 1;
|
||||
update_main_irqs();
|
||||
}
|
||||
|
||||
// clear VBLANK on scanline 224
|
||||
else if (scanline == 224)
|
||||
{
|
||||
m_vblank_irq_state = 0;
|
||||
update = true;
|
||||
m_subcpu->set_input_line(4, CLEAR_LINE);
|
||||
next_scanline = scanline + 1;
|
||||
update_main_irqs();
|
||||
}
|
||||
|
||||
// update IRQs on the main CPU
|
||||
if (update)
|
||||
update_main_irqs();
|
||||
|
||||
// come back in 2 scanlines
|
||||
m_scanline_timer->adjust(m_screen->time_until_pos(next_scanline), next_scanline);
|
||||
break;
|
||||
}
|
||||
@ -1035,7 +990,7 @@ void segaxbd_state::sound_portmap(address_map &map)
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x00, 0x01).mirror(0x3e).rw("ymsnd", FUNC(ym2151_device::read), FUNC(ym2151_device::write));
|
||||
map(0x40, 0x40).mirror(0x3f).r(this, FUNC(segaxbd_state::sound_data_r));
|
||||
map(0x40, 0x40).mirror(0x3f).r("cmptimer_main", FUNC(sega_315_5250_compare_timer_device::zread));
|
||||
}
|
||||
|
||||
|
||||
@ -1059,7 +1014,7 @@ void segaxbd_state::smgp_sound2_portmap(address_map &map)
|
||||
{
|
||||
map.unmap_value_high();
|
||||
map.global_mask(0xff);
|
||||
map(0x40, 0x40).mirror(0x3f).r(this, FUNC(segaxbd_state::sound_data_r));
|
||||
map(0x40, 0x40).mirror(0x3f).r("cmptimer_main", FUNC(sega_315_5250_compare_timer_device::zread));
|
||||
}
|
||||
|
||||
|
||||
@ -1728,8 +1683,8 @@ MACHINE_CONFIG_START(segaxbd_state::xboard_base_mconfig )
|
||||
MCFG_SEGA_315_5249_DIVIDER_ADD("divider_subx")
|
||||
|
||||
MCFG_SEGA_315_5250_COMPARE_TIMER_ADD("cmptimer_main")
|
||||
MCFG_SEGA_315_5250_TIMER_ACK(segaxbd_state, timer_ack_callback)
|
||||
MCFG_SEGA_315_5250_SOUND_WRITE_CALLBACK(WRITE8(*this, segaxbd_state, sound_data_w))
|
||||
MCFG_SEGA_315_5250_68KINT_CALLBACK(WRITELINE(*this, segaxbd_state, timer_irq_w))
|
||||
MCFG_SEGA_315_5250_ZINT_CALLBACK(INPUTLINE("soundcpu", INPUT_LINE_NMI))
|
||||
|
||||
MCFG_SEGA_315_5250_COMPARE_TIMER_ADD("cmptimer_subx")
|
||||
|
||||
@ -1765,8 +1720,6 @@ MACHINE_CONFIG_START(segaxbd_state::xboard_base_mconfig )
|
||||
SPEAKER(config, "lspeaker").front_left();
|
||||
SPEAKER(config, "rspeaker").front_right();
|
||||
|
||||
MCFG_GENERIC_LATCH_8_ADD("soundlatch")
|
||||
|
||||
MCFG_DEVICE_ADD("ymsnd", YM2151, SOUND_CLOCK/4)
|
||||
MCFG_YM2151_IRQ_HANDLER(INPUTLINE("soundcpu", 0))
|
||||
MCFG_SOUND_ROUTE(0, "lspeaker", 0.43)
|
||||
@ -1945,6 +1898,10 @@ MACHINE_CONFIG_START(segaxbd_smgp_fd1094_state::device_add_mconfig)
|
||||
MCFG_DEVICE_PROGRAM_MAP(smgp_airdrive_map)
|
||||
MCFG_DEVICE_IO_MAP(smgp_airdrive_portmap)
|
||||
|
||||
MCFG_DEVICE_MODIFY("cmptimer_main")
|
||||
MCFG_SEGA_315_5250_ZINT_CALLBACK(INPUTLINE("soundcpu", INPUT_LINE_NMI))
|
||||
MCFG_DEVCB_CHAIN_OUTPUT(INPUTLINE("soundcpu2", INPUT_LINE_NMI))
|
||||
|
||||
MCFG_DEVICE_MODIFY("iochip_0")
|
||||
MCFG_CXD1095_IN_PORTA_CB(READ8(*this, segaxbd_state, smgp_motor_r))
|
||||
MCFG_CXD1095_OUT_PORTB_CB(WRITE8(*this, segaxbd_state, smgp_motor_w))
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "cpu/m68000/m68000.h"
|
||||
#include "cpu/mcs51/mcs51.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "machine/gen_latch.h"
|
||||
#include "machine/mb3773.h"
|
||||
#include "machine/watchdog.h"
|
||||
#include "video/resnet.h"
|
||||
@ -53,9 +52,6 @@ public:
|
||||
DECLARE_READ8_MEMBER(lastsurv_port_r);
|
||||
DECLARE_WRITE8_MEMBER(lastsurv_muxer_w);
|
||||
|
||||
// sound Z80 CPU read/write handlers
|
||||
DECLARE_READ8_MEMBER(sound_data_r);
|
||||
|
||||
// video updates
|
||||
uint32_t screen_update(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
|
||||
|
||||
@ -85,8 +81,7 @@ protected:
|
||||
enum
|
||||
{
|
||||
TID_SCANLINE,
|
||||
TID_IRQ2_GEN,
|
||||
TID_SOUND_WRITE
|
||||
TID_IRQ2_GEN
|
||||
};
|
||||
|
||||
segaxbd_state(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -101,9 +96,8 @@ protected:
|
||||
DECLARE_WRITE_LINE_MEMBER(m68k_reset_callback);
|
||||
void generic_iochip0_lamps_w(uint8_t data);
|
||||
|
||||
// compare/timer chip callbacks
|
||||
void timer_ack_callback();
|
||||
DECLARE_WRITE8_MEMBER(sound_data_w);
|
||||
// compare/timer chip callbacks
|
||||
DECLARE_WRITE_LINE_MEMBER(timer_irq_w);
|
||||
|
||||
DECLARE_WRITE8_MEMBER(pc_0_w);
|
||||
DECLARE_WRITE8_MEMBER(pd_0_w);
|
||||
@ -121,7 +115,6 @@ protected:
|
||||
required_device<sega_xboard_sprite_device> m_sprites;
|
||||
required_device<segaic16_video_device> m_segaic16vid;
|
||||
required_device<segaic16_road_device> m_segaic16road;
|
||||
required_device<generic_latch_8_device> m_soundlatch;
|
||||
required_shared_ptr<uint16_t> m_subram0;
|
||||
|
||||
// configuration
|
||||
|
@ -974,30 +974,50 @@ void sega_315_5249_divider_device::execute(int mode)
|
||||
|
||||
sega_315_5250_compare_timer_device::sega_315_5250_compare_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, SEGA_315_5250_COMPARE_TIMER, tag, owner, clock)
|
||||
, m_sound_write(*this)
|
||||
, m_68kint_callback(*this)
|
||||
, m_zint_callback(*this)
|
||||
, m_exck(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// clock - clock the timer
|
||||
// exck_w - clock the timer
|
||||
//-------------------------------------------------
|
||||
|
||||
bool sega_315_5250_compare_timer_device::clock()
|
||||
WRITE_LINE_MEMBER(sega_315_5250_compare_timer_device::exck_w)
|
||||
{
|
||||
if (m_exck == bool(state))
|
||||
return;
|
||||
|
||||
// update on rising edge
|
||||
m_exck = bool(state);
|
||||
if (!m_exck)
|
||||
return;
|
||||
|
||||
// if we're enabled, clock the upcounter
|
||||
int old_counter = m_counter;
|
||||
if (m_regs[10] & 1)
|
||||
m_counter++;
|
||||
|
||||
// regardless of the enable, a value of 0xfff will generate the IRQ
|
||||
bool result = false;
|
||||
if (old_counter == 0xfff)
|
||||
{
|
||||
result = true;
|
||||
if (!m_68kint_callback.isnull())
|
||||
m_68kint_callback(ASSERT_LINE);
|
||||
m_counter = m_regs[8] & 0xfff;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// interrupt_ack - acknowledge timer interrupt
|
||||
//-------------------------------------------------
|
||||
|
||||
void sega_315_5250_compare_timer_device::interrupt_ack()
|
||||
{
|
||||
if (!m_68kint_callback.isnull())
|
||||
m_68kint_callback(CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
@ -1005,7 +1025,7 @@ bool sega_315_5250_compare_timer_device::clock()
|
||||
// read - read the registers
|
||||
//-------------------------------------------------
|
||||
|
||||
READ16_MEMBER( sega_315_5250_compare_timer_device::read )
|
||||
READ16_MEMBER(sega_315_5250_compare_timer_device::read)
|
||||
{
|
||||
if (LOG_COMPARE) logerror("compare_r(%X) = %04X\n", offset, m_regs[offset]);
|
||||
switch (offset & 15)
|
||||
@ -1019,7 +1039,7 @@ READ16_MEMBER( sega_315_5250_compare_timer_device::read )
|
||||
case 0x6: return m_regs[2];
|
||||
case 0x7: return m_regs[7];
|
||||
case 0x9:
|
||||
case 0xd: interrupt_ack(); break;
|
||||
case 0xd: if (!machine().side_effects_disabled()) interrupt_ack(); break;
|
||||
}
|
||||
return 0xffff;
|
||||
}
|
||||
@ -1029,7 +1049,7 @@ READ16_MEMBER( sega_315_5250_compare_timer_device::read )
|
||||
// write - write to the registers
|
||||
//-------------------------------------------------
|
||||
|
||||
WRITE16_MEMBER( sega_315_5250_compare_timer_device::write )
|
||||
WRITE16_MEMBER(sega_315_5250_compare_timer_device::write)
|
||||
{
|
||||
if (LOG_COMPARE) logerror("compare_w(%X) = %04X\n", offset, data);
|
||||
switch (offset & 15)
|
||||
@ -1047,9 +1067,7 @@ WRITE16_MEMBER( sega_315_5250_compare_timer_device::write )
|
||||
case 0xe: COMBINE_DATA(&m_regs[10]); break;
|
||||
case 0xb:
|
||||
case 0xf:
|
||||
COMBINE_DATA(&m_regs[11]);
|
||||
if (!m_sound_write.isnull())
|
||||
m_sound_write(m_regs[11]);
|
||||
machine().scheduler().synchronize(timer_expired_delegate(FUNC(sega_315_5250_compare_timer_device::write_to_sound), this), data & 0xff);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -1062,13 +1080,14 @@ WRITE16_MEMBER( sega_315_5250_compare_timer_device::write )
|
||||
void sega_315_5250_compare_timer_device::device_start()
|
||||
{
|
||||
// bind our handlers
|
||||
m_timer_ack.bind_relative_to(*owner());
|
||||
m_sound_write.resolve();
|
||||
m_68kint_callback.resolve();
|
||||
m_zint_callback.resolve();
|
||||
|
||||
// save states
|
||||
save_item(NAME(m_regs));
|
||||
save_item(NAME(m_counter));
|
||||
save_item(NAME(m_bit));
|
||||
save_item(NAME(m_exck));
|
||||
}
|
||||
|
||||
|
||||
@ -1081,6 +1100,35 @@ void sega_315_5250_compare_timer_device::device_reset()
|
||||
memset(m_regs, 0, sizeof(m_regs));
|
||||
m_counter = 0;
|
||||
m_bit = 0;
|
||||
|
||||
interrupt_ack();
|
||||
if (!m_zint_callback.isnull())
|
||||
m_zint_callback(CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// write_to_sound - write data for the sound CPU
|
||||
//-------------------------------------------------
|
||||
|
||||
TIMER_CALLBACK_MEMBER(sega_315_5250_compare_timer_device::write_to_sound)
|
||||
{
|
||||
m_regs[11] = param;
|
||||
if (!m_zint_callback.isnull())
|
||||
m_zint_callback(ASSERT_LINE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// zread - read data from sound CPU bus
|
||||
//-------------------------------------------------
|
||||
|
||||
READ8_MEMBER(sega_315_5250_compare_timer_device::zread)
|
||||
{
|
||||
if (!m_zint_callback.isnull() && !machine().side_effects_disabled())
|
||||
m_zint_callback(CLEAR_LINE);
|
||||
|
||||
return m_regs[11];
|
||||
}
|
||||
|
||||
|
||||
|
@ -38,10 +38,10 @@
|
||||
|
||||
#define MCFG_SEGA_315_5250_COMPARE_TIMER_ADD(_tag) \
|
||||
MCFG_DEVICE_ADD(_tag, SEGA_315_5250_COMPARE_TIMER, 0)
|
||||
#define MCFG_SEGA_315_5250_TIMER_ACK(_class, _func) \
|
||||
downcast<sega_315_5250_compare_timer_device &>(*device).set_timer_ack(sega_315_5250_compare_timer_device::timer_ack_delegate(&_class::_func, #_class "::" #_func, nullptr, (_class *)nullptr));
|
||||
#define MCFG_SEGA_315_5250_SOUND_WRITE_CALLBACK(_devcb) \
|
||||
devcb = &downcast<sega_315_5250_compare_timer_device &>(*device).set_sound_write(DEVCB_##_devcb);
|
||||
#define MCFG_SEGA_315_5250_68KINT_CALLBACK(_devcb) \
|
||||
devcb = &downcast<sega_315_5250_compare_timer_device &>(*device).set_68kint_callback(DEVCB_##_devcb);
|
||||
#define MCFG_SEGA_315_5250_ZINT_CALLBACK(_devcb) \
|
||||
devcb = &downcast<sega_315_5250_compare_timer_device &>(*device).set_zint_callback(DEVCB_##_devcb);
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
@ -247,19 +247,18 @@ private:
|
||||
class sega_315_5250_compare_timer_device : public device_t
|
||||
{
|
||||
public:
|
||||
typedef device_delegate<void ()> timer_ack_delegate;
|
||||
|
||||
// construction/destruction
|
||||
sega_315_5250_compare_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
// configuration helpers
|
||||
void set_timer_ack(timer_ack_delegate callback) { m_timer_ack = callback; }
|
||||
template<class Object> devcb_base &set_sound_write(Object &&object) { return m_sound_write.set_callback(std::forward<Object>(object)); }
|
||||
template<class Object> devcb_base &set_68kint_callback(Object &&object) { return m_68kint_callback.set_callback(std::forward<Object>(object)); }
|
||||
template<class Object> devcb_base &set_zint_callback(Object &&object) { return m_zint_callback.set_callback(std::forward<Object>(object)); }
|
||||
|
||||
// public interface
|
||||
bool clock();
|
||||
DECLARE_READ16_MEMBER( read );
|
||||
DECLARE_WRITE16_MEMBER( write );
|
||||
DECLARE_WRITE_LINE_MEMBER(exck_w);
|
||||
DECLARE_READ16_MEMBER(read);
|
||||
DECLARE_WRITE16_MEMBER(write);
|
||||
DECLARE_READ8_MEMBER(zread);
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
@ -269,16 +268,18 @@ protected:
|
||||
private:
|
||||
// internal helpers
|
||||
void execute(bool update_history = false);
|
||||
void interrupt_ack() { if (!m_timer_ack.isnull()) m_timer_ack(); }
|
||||
void interrupt_ack();
|
||||
TIMER_CALLBACK_MEMBER(write_to_sound);
|
||||
|
||||
// configuration
|
||||
timer_ack_delegate m_timer_ack;
|
||||
devcb_write8 m_sound_write;
|
||||
devcb_write_line m_68kint_callback;
|
||||
devcb_write_line m_zint_callback;
|
||||
|
||||
// internal state
|
||||
uint16_t m_regs[16];
|
||||
uint16_t m_counter;
|
||||
uint8_t m_bit;
|
||||
bool m_exck;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user