From 52c93bdc1de797080d57f092315ec6b873ed4edb Mon Sep 17 00:00:00 2001 From: AJR Date: Fri, 25 May 2018 17:41:00 -0400 Subject: [PATCH] sega_315_5250: Interrupt callback modernization (nw) --- src/mame/drivers/segaxbd.cpp | 81 ++++++++--------------------------- src/mame/includes/segaxbd.h | 13 ++---- src/mame/machine/segaic16.cpp | 76 ++++++++++++++++++++++++++------ src/mame/machine/segaic16.h | 29 +++++++------ 4 files changed, 99 insertions(+), 100 deletions(-) diff --git a/src/mame/drivers/segaxbd.cpp b/src/mame/drivers/segaxbd.cpp index 7c695f20413..fc2de312927 100644 --- a/src/mame/drivers/segaxbd.cpp +++ b/src/mame/drivers/segaxbd.cpp @@ -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)) diff --git a/src/mame/includes/segaxbd.h b/src/mame/includes/segaxbd.h index c47d227b230..916aba02ed8 100644 --- a/src/mame/includes/segaxbd.h +++ b/src/mame/includes/segaxbd.h @@ -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 m_sprites; required_device m_segaic16vid; required_device m_segaic16road; - required_device m_soundlatch; required_shared_ptr m_subram0; // configuration diff --git a/src/mame/machine/segaic16.cpp b/src/mame/machine/segaic16.cpp index 1e6431cb0a3..b3690fd06cc 100644 --- a/src/mame/machine/segaic16.cpp +++ b/src/mame/machine/segaic16.cpp @@ -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]; } diff --git a/src/mame/machine/segaic16.h b/src/mame/machine/segaic16.h index 9a6a5027045..90216fa1ef9 100644 --- a/src/mame/machine/segaic16.h +++ b/src/mame/machine/segaic16.h @@ -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(*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(*device).set_sound_write(DEVCB_##_devcb); +#define MCFG_SEGA_315_5250_68KINT_CALLBACK(_devcb) \ + devcb = &downcast(*device).set_68kint_callback(DEVCB_##_devcb); +#define MCFG_SEGA_315_5250_ZINT_CALLBACK(_devcb) \ + devcb = &downcast(*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 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 devcb_base &set_sound_write(Object &&object) { return m_sound_write.set_callback(std::forward(object)); } + template devcb_base &set_68kint_callback(Object &&object) { return m_68kint_callback.set_callback(std::forward(object)); } + template devcb_base &set_zint_callback(Object &&object) { return m_zint_callback.set_callback(std::forward(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; };