From 6a8480d120e36ccc4e41bac504a53408789840b0 Mon Sep 17 00:00:00 2001 From: enikland2 Date: Mon, 10 Jun 2019 20:38:44 -0300 Subject: sms.cpp: Change NMI to be routed through VDP on SMS systems (#4871) * sms.cpp: Change NMI to be routed through VDP on SMS systems * Implement /NMI-IN as a line write handler rather than as an input callback * Revert "Implement /NMI-IN as a line write handler rather than as an input callback" This reverts commit 35f67c50873203b13f506be32870ed9837a52ab2. * Implement /NMI-IN as a line write handler rather than as an input callback --- src/devices/video/315_5124.cpp | 106 ++++++++++++++++++++++++++------------- src/devices/video/315_5124.h | 26 ++++++---- src/mame/drivers/megaplay.cpp | 2 +- src/mame/drivers/megatech.cpp | 4 +- src/mame/drivers/segae.cpp | 2 +- src/mame/drivers/sms.cpp | 42 ++++++++-------- src/mame/drivers/sms_bootleg.cpp | 6 +-- src/mame/includes/sms.h | 9 ++-- src/mame/machine/sms.cpp | 72 +++++++++++++------------- 9 files changed, 160 insertions(+), 109 deletions(-) diff --git a/src/devices/video/315_5124.cpp b/src/devices/video/315_5124.cpp index e95b3f92dd3..552df7be283 100644 --- a/src/devices/video/315_5124.cpp +++ b/src/devices/video/315_5124.cpp @@ -212,9 +212,10 @@ sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_t , m_max_sprite_zoom_hcount(max_sprite_zoom_hcount) , m_max_sprite_zoom_vcount(max_sprite_zoom_vcount) , m_is_pal(false) - , m_int_cb(*this) - , m_csync_cb(*this) - , m_pause_cb(*this) + , m_vblank_cb(*this) + , m_n_csync_cb(*this) + , m_n_int_cb(*this) + , m_n_nmi_cb(*this) , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, address_map_constructor(FUNC(sega315_5124_device::sega315_5124), this)) , m_palette(*this, "palette") , m_snsnd(*this, "snsnd") @@ -374,20 +375,22 @@ u8 sega315_5124_device::vcount_read() u8 sega315_5124_device::hcount_read() { + m_hcounter_latched = false; return m_hcounter; } -void sega315_5124_device::hcount_latch_at_hpos(int hpos) +void sega315_5124_device::hcount_latch() { const int active_scr_start = 46; /* 9 + 2 + 14 + 8 + 13 */ /* The hcount value returned by the VDP seems to be based on the previous hpos */ - int hclock = hpos - 1; + int hclock = screen().hpos() - 1; if (hclock < 0) hclock += WIDTH; m_hcounter = ((hclock - active_scr_start) >> 1) & 0xff; + m_hcounter_latched = true; } @@ -452,10 +455,10 @@ void sega315_5124_device::device_timer(emu_timer &timer, device_timer_id id, int { if (BIT(m_reg[0x00], 4)) { - m_irq_state = 1; + m_n_int_state = 0; - if (!m_int_cb.isnull()) - m_int_cb(ASSERT_LINE); + if (!m_n_int_cb.isnull()) + m_n_int_cb(ASSERT_LINE); } } break; @@ -465,22 +468,45 @@ void sega315_5124_device::device_timer(emu_timer &timer, device_timer_id id, int { if (BIT(m_reg[0x01], 5)) { - m_irq_state = 1; + m_n_int_state = 0; - if (!m_int_cb.isnull()) - m_int_cb(ASSERT_LINE); + if (!m_n_int_cb.isnull()) + m_n_int_cb(ASSERT_LINE); } } break; case TIMER_NMI: - if (!m_pause_cb.isnull()) - m_pause_cb(0); + if (!m_n_nmi_in_state) + { + if (m_n_nmi_state) + m_n_nmi_cb(ASSERT_LINE); + } + else + { + if (!m_n_nmi_state) + m_n_nmi_cb(CLEAR_LINE); + } + m_n_nmi_state = m_n_nmi_in_state; break; } } +void sega315_5124_device::vblank_end(int vpos) +{ + m_nmi_timer->adjust(screen().time_until_pos(vpos, m_line_timing[NMI_HPOS])); +} + + +void sega315_5377_device::vblank_end(int vpos) +{ + // Assume the VBlank line is used to trigger the NMI logic performed by the 315-5378 chip. + if (!m_vblank_cb.isnull()) + m_vblank_cb(0); +} + + void sega315_5124_device::process_line_timer() { const int vpos = screen().vpos(); @@ -493,7 +519,7 @@ void sega315_5124_device::process_line_timer() m_reg8copy = m_reg[0x08]; /* Check if the /CSYNC signal must be active (low) */ - if (!m_csync_cb.isnull()) + if (!m_n_csync_cb.isnull()) { /* /CSYNC is signals /HSYNC and /VSYNC (both internals) ANDed together. According to Charles MacDonald, /HSYNC goes low for 28 pixels on beginning @@ -504,7 +530,7 @@ void sega315_5124_device::process_line_timer() */ if (vpos == 0 || vpos > (m_frame_timing[VERTICAL_SYNC] + 1)) { - m_csync_cb(0); + m_n_csync_cb(0); } } @@ -545,6 +571,8 @@ void sega315_5124_device::process_line_timer() { m_vint_timer->adjust(screen().time_until_pos(vpos, m_line_timing[VINT_HPOS])); m_pending_status |= STATUS_VINT; + if (!m_vblank_cb.isnull()) + m_vblank_cb(1); } /* Draw borders */ @@ -600,7 +628,8 @@ void sega315_5124_device::process_line_timer() /* Check if we're on the last line of the top border */ if (vpos == vpos_limit + m_frame_timing[TOP_BORDER] - 1) { - m_nmi_timer->adjust(screen().time_until_pos(vpos, m_line_timing[NMI_HPOS])); + m_hcounter_latched = false; + vblank_end(vpos); } /* Draw borders */ @@ -697,12 +726,12 @@ u8 sega315_5124_device::control_read() m_hint_occurred = false; m_status = u8(~(STATUS_VINT | STATUS_SPROVR | STATUS_SPRCOL)); - if (m_irq_state == 1) + if (m_n_int_state == 0) { - m_irq_state = 0; + m_n_int_state = 1; - if (!m_int_cb.isnull()) - m_int_cb(CLEAR_LINE); + if (!m_n_int_cb.isnull()) + m_n_int_cb(CLEAR_LINE); } } @@ -842,10 +871,10 @@ void sega315_5124_device::control_write(u8 data) // For HINT disabling through register 00: // "Line IRQ VCount" test, of Flubba's VDPTest ROM, disables HINT to wait // for next VINT, but HINT occurs when the operation is about to execute. - // So here, where the setting is done, the irq_state needs to be cleared. + // So here, where the setting is done, the /INT state needs to be cleared. // // For VINT disabling through register 01: - // When running eagles5 on the smskr driver the irq_state is 1 because of some + // When running eagles5 on the smskr driver the /INT state is 0 because of some // previous HINTs that occurred. eagles5 sets register 01 to 0x02 and expects // the irq state to be cleared after that. // The following bit of code takes care of that. @@ -853,28 +882,28 @@ void sega315_5124_device::control_write(u8 data) if ((reg_num == 0 && !BIT(m_reg[0x00], 4)) || (reg_num == 1 && !BIT(m_reg[0x01], 5))) { - if (m_irq_state == 1) + if (m_n_int_state == 0) { - m_irq_state = 0; + m_n_int_state = 1; - if (!m_int_cb.isnull()) + if (!m_n_int_cb.isnull()) { - m_int_cb(CLEAR_LINE); + m_n_int_cb(CLEAR_LINE); } } } else { // For register 01 and VINT enabling: - // Assert the IRQ line for the scoreboard of robocop3, + // Assert the /INT line for the scoreboard of robocop3, // on the sms/smspal driver, be displayed correctly. // // Assume the same behavior for reg0+HINT. // - m_irq_state = 1; + m_n_int_state = 0; - if (!m_int_cb.isnull()) - m_int_cb(ASSERT_LINE); + if (!m_n_int_cb.isnull()) + m_n_int_cb(ASSERT_LINE); } } m_addrmode = 0; @@ -1876,9 +1905,10 @@ void sega315_5124_device::device_post_load() void sega315_5124_device::device_start() { /* Resolve callbacks */ - m_int_cb.resolve(); - m_csync_cb.resolve(); - m_pause_cb.resolve(); + m_vblank_cb.resolve(); + m_n_csync_cb.resolve(); + m_n_int_cb.resolve(); + m_n_nmi_cb.resolve(); /* Make temp bitmap for rendering */ screen().register_screen_bitmap(m_tmpbitmap); @@ -1911,11 +1941,14 @@ void sega315_5124_device::device_start() save_item(NAME(m_control_write_data_latch)); save_item(NAME(m_sega315_5124_compatibility_mode)); save_item(NAME(m_display_disabled)); - save_item(NAME(m_irq_state)); + save_item(NAME(m_n_int_state)); + save_item(NAME(m_n_nmi_state)); + save_item(NAME(m_n_nmi_in_state)); save_item(NAME(m_vdp_mode)); save_item(NAME(m_y_pixels)); save_item(NAME(m_line_counter)); save_item(NAME(m_hcounter)); + save_item(NAME(m_hcounter_latched)); save_item(NAME(m_reg)); save_item(NAME(m_current_palette)); @@ -1961,9 +1994,12 @@ void sega315_5124_device::device_reset() m_cram_dirty = true; m_buffer = 0; m_control_write_data_latch = 0; - m_irq_state = 0; + m_n_int_state = 1; + m_n_nmi_state = 1; + m_n_nmi_in_state = 1; m_line_counter = 0; m_hcounter = 0; + m_hcounter_latched = false; m_draw_time = DRAW_TIME_SMS; std::fill(std::begin(m_current_palette), std::end(m_current_palette), 0); diff --git a/src/devices/video/315_5124.h b/src/devices/video/315_5124.h index 21d149b6729..9dab94e40b9 100644 --- a/src/devices/video/315_5124.h +++ b/src/devices/video/315_5124.h @@ -57,12 +57,14 @@ public: void set_is_pal(bool is_pal) { m_is_pal = is_pal; } - auto irq() { return m_int_cb.bind(); } - auto csync() { return m_csync_cb.bind(); } - auto pause() { return m_pause_cb.bind(); } + auto vblank() { return m_vblank_cb.bind(); } + auto n_csync() { return m_n_csync_cb.bind(); } + auto n_int() { return m_n_int_cb.bind(); } + auto n_nmi() { return m_n_nmi_cb.bind(); } void psg_w(u8 data) { m_snsnd->write(data); } void psg_stereo_w(u8 data) { m_snsnd->stereo_w(data); } + void n_nmi_in_write(int state) { m_n_nmi_in_state = state; } /* /NMI-IN line input, controls the /NMI state */ u8 data_read(); void data_write(u8 data); u8 control_read(); @@ -70,8 +72,8 @@ public: u8 vcount_read(); u8 hcount_read(); - void hcount_latch() { hcount_latch_at_hpos(screen().hpos()); }; - void hcount_latch_at_hpos(int hpos); + void hcount_latch(); + bool hcount_latched() { return m_hcounter_latched; } bitmap_rgb32 &get_bitmap() { return m_tmpbitmap; }; bitmap_ind8 &get_y1_bitmap() { return m_y1_bitmap; }; @@ -102,6 +104,7 @@ protected: void set_display_settings(); void set_frame_timing(); + virtual void vblank_end(int vpos); virtual void update_palette(); virtual void write_memory(u8 data); virtual void cram_write(u8 data); @@ -137,6 +140,7 @@ protected: const u8 m_cram_size; /* CRAM size */ u8 m_cram_mask; /* Mask to switch between SMS and GG CRAM sizes */ bool m_cram_dirty; /* Have there been any changes to the CRAM area */ + bool m_hcounter_latched; bool m_hint_occurred; bool m_pending_hint; bool m_pending_control_write; @@ -144,7 +148,9 @@ protected: u8 m_buffer; u8 m_control_write_data_latch; bool m_sega315_5124_compatibility_mode; /* when true, GG VDP behaves as SMS VDP */ - int m_irq_state; /* The status of the IRQ line of the VDP */ + int m_n_int_state; /* The status of the /INT line of the VDP */ + int m_n_nmi_state; /* The status of the /NMI line of the VDP */ + int m_n_nmi_in_state; /* The status of the /NMI-IN line of the VDP */ int m_vdp_mode; /* Current mode of the VDP: 0,1,2,3,4 */ int m_y_pixels; /* 192, 224, 240 */ int m_draw_time; @@ -170,9 +176,10 @@ protected: int m_max_sprite_zoom_vcount; int m_current_palette[32]; bool m_is_pal; /* false = NTSC, true = PAL */ - devcb_write_line m_int_cb; /* Interrupt callback function */ - devcb_write_line m_csync_cb; /* C-Sync callback function */ - devcb_write_line m_pause_cb; /* Pause callback function */ + devcb_write_line m_vblank_cb; /* VBlank line callback function */ + devcb_write_line m_n_csync_cb; /* /C-SYNC line callback function */ + devcb_write_line m_n_int_cb; /* /INT (Interrupt) line callback function */ + devcb_write_line m_n_nmi_cb; /* /NMI (Non-Maskable Interrupt) line callback function */ emu_timer *m_display_timer; emu_timer *m_hint_timer; emu_timer *m_vint_timer; @@ -227,6 +234,7 @@ protected: virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; + virtual void vblank_end(int vpos) override; virtual void update_palette() override; virtual void cram_write(u8 data) override; virtual void blit_scanline(int *line_buffer, int *priority_selected, int pixel_offset_x, int pixel_plot_y, int line) override; diff --git a/src/mame/drivers/megaplay.cpp b/src/mame/drivers/megaplay.cpp index 29e51560ca4..87b0eca0d00 100644 --- a/src/mame/drivers/megaplay.cpp +++ b/src/mame/drivers/megaplay.cpp @@ -701,7 +701,7 @@ void mplay_state::megaplay(machine_config &config) SEGA315_5246(config, m_vdp1, MASTER_CLOCK / 5); /* ?? */ m_vdp1->set_screen("megadriv"); m_vdp1->set_is_pal(false); - m_vdp1->irq().set_inputline(m_bioscpu, 0); + m_vdp1->n_int().set_inputline(m_bioscpu, 0); m_vdp1->add_route(ALL_OUTPUTS, "lspeaker", 0.25); m_vdp1->add_route(ALL_OUTPUTS, "rspeaker", 0.25); } diff --git a/src/mame/drivers/megatech.cpp b/src/mame/drivers/megatech.cpp index 11731195cb8..33a456e044a 100644 --- a/src/mame/drivers/megatech.cpp +++ b/src/mame/drivers/megatech.cpp @@ -715,7 +715,7 @@ void mtech_state::megatech(machine_config &config) screen.set_screen_update(FUNC(mtech_state::screen_update_main)); screen.screen_vblank().set(FUNC(mtech_state::screen_vblank_main)); - m_vdp->irq().set_inputline(m_z80snd, 0); + m_vdp->n_int().set_inputline(m_z80snd, 0); screen_device &menu(SCREEN(config, "menu", SCREEN_TYPE_RASTER)); // check frq @@ -727,7 +727,7 @@ void mtech_state::megatech(machine_config &config) SEGA315_5246(config, m_vdp1, MASTER_CLOCK / 5); /* ?? */ m_vdp1->set_screen("menu"); m_vdp1->set_is_pal(false); - m_vdp1->irq().set_inputline(m_bioscpu, 0); + m_vdp1->n_int().set_inputline(m_bioscpu, 0); m_vdp1->add_route(ALL_OUTPUTS, "lspeaker", 0.25); m_vdp1->add_route(ALL_OUTPUTS, "rspeaker", 0.25); } diff --git a/src/mame/drivers/segae.cpp b/src/mame/drivers/segae.cpp index ef357426bc1..6b55da0e2cd 100644 --- a/src/mame/drivers/segae.cpp +++ b/src/mame/drivers/segae.cpp @@ -912,7 +912,7 @@ void systeme_state::systeme(machine_config &config) SEGA315_5124(config, m_vdp2, XTAL(10'738'635)); m_vdp2->set_is_pal(false); - m_vdp2->irq().set_inputline(m_maincpu, 0); + m_vdp2->n_int().set_inputline(m_maincpu, 0); m_vdp2->set_addrmap(0, &systeme_state::vdp2_map); m_vdp2->add_route(ALL_OUTPUTS, "mono", 0.50); } diff --git a/src/mame/drivers/sms.cpp b/src/mame/drivers/sms.cpp index d3302bc1bd4..83fb94fd733 100644 --- a/src/mame/drivers/sms.cpp +++ b/src/mame/drivers/sms.cpp @@ -384,7 +384,7 @@ void sms_state::gg_io(address_map &map) static INPUT_PORTS_START( sms ) PORT_START("PAUSE") PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_1) PORT_WRITE_LINE_DEVICE_MEMBER("sms_vdp", sega315_5124_device, n_nmi_in_write) INPUT_PORTS_END static INPUT_PORTS_START( sg1000m3 ) @@ -587,8 +587,8 @@ void sms_state::sms2_ntsc(machine_config &config) SEGA315_5246(config, m_vdp, XTAL(10'738'635)); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(false); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); m_has_bios_full = true; @@ -624,8 +624,8 @@ void sms_state::sms1_ntsc(machine_config &config) SEGA315_5124(config, m_vdp, XTAL(10'738'635)); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(false); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); // card and expansion slots, not present in Master System II @@ -640,7 +640,7 @@ void smssdisp_state::sms_sdisp(machine_config &config) { sms1_ntsc(config); - m_vdp->irq().set(FUNC(smssdisp_state::sms_store_int_callback)); + m_vdp->n_int().set(FUNC(smssdisp_state::sms_store_int_callback)); Z80(config, m_control_cpu, XTAL(10'738'635)/3); m_control_cpu->set_addrmap(AS_PROGRAM, &smssdisp_state::sms_store_mem); @@ -682,8 +682,8 @@ void sms_state::sms2_pal(machine_config &config) SEGA315_5246(config, m_vdp, MASTER_CLOCK_PAL/5); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(true); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); m_has_bios_full = true; @@ -718,8 +718,8 @@ void sms_state::sms1_pal(machine_config &config) SEGA315_5124(config, m_vdp, MASTER_CLOCK_PAL/5); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(true); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); // card and expansion slots, not present in Master System II @@ -754,8 +754,8 @@ void sms_state::sms3_paln(machine_config &config) SEGA315_5246(config, m_vdp, MASTER_CLOCK_PALN); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(true); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); m_has_bios_full = true; @@ -790,8 +790,8 @@ void sms_state::sms1_paln(machine_config &config) SEGA315_5124(config, m_vdp, MASTER_CLOCK_PALN); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(true); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); // card and expansion slots, not present in Tec Toy Master System III @@ -827,8 +827,8 @@ void sms_state::sms3_br(machine_config &config) SEGA315_5246(config, m_vdp, MASTER_CLOCK_PALM); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(false); // PAL-M has same line count of NTSC - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); m_has_bios_full = true; @@ -864,8 +864,8 @@ void sms_state::sms1_br(machine_config &config) SEGA315_5124(config, m_vdp, MASTER_CLOCK_PALM); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(false); // PAL-M has same line count of NTSC - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); // card and expansion slots, not present in Tec Toy Master System III @@ -908,7 +908,7 @@ void sms_state::sms1_kr(machine_config &config) SOFTWARE_LIST(config, "cart_list2").set_original("sg1000"); - m_vdp->csync().set(FUNC(sms_state::sms_csync_callback)); + m_vdp->n_csync().set(FUNC(sms_state::sms_n_csync_callback)); m_has_bios_full = false; m_has_bios_2000 = true; @@ -981,8 +981,8 @@ void sms_state::gamegear(machine_config &config) SEGA315_5377(config, m_vdp, MASTER_CLOCK_GG/3); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(false); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->vblank().set(FUNC(sms_state::gg_pause_callback)); m_vdp->add_route(0, "lspeaker", 1.00); m_vdp->add_route(1, "rspeaker", 1.00); diff --git a/src/mame/drivers/sms_bootleg.cpp b/src/mame/drivers/sms_bootleg.cpp index 6a6b1e51019..d709f537709 100644 --- a/src/mame/drivers/sms_bootleg.cpp +++ b/src/mame/drivers/sms_bootleg.cpp @@ -295,8 +295,8 @@ void smsbootleg_state::sms_supergame(machine_config &config) SEGA315_5246(config, m_vdp, XTAL(10'738'635)); m_vdp->set_screen(m_main_scr); m_vdp->set_is_pal(false); - m_vdp->irq().set_inputline(m_maincpu, 0); - m_vdp->pause().set(FUNC(sms_state::sms_pause_callback)); + m_vdp->n_int().set_inputline(m_maincpu, 0); + m_vdp->n_nmi().set_inputline(m_maincpu, INPUT_LINE_NMI); m_vdp->add_route(ALL_OUTPUTS, "mono", 1.00); } @@ -307,7 +307,7 @@ void smsbootleg_state::sms_supergame(machine_config &config) static INPUT_PORTS_START( sms_supergame ) PORT_START("PAUSE") PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )// PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_1) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED )// PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_1) PORT_WRITE_LINE_DEVICE_MEMBER("sms_vdp", sega315_5124_device, n_nmi_in_write) #if 0 PORT_START("IN0") PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) diff --git a/src/mame/includes/sms.h b/src/mame/includes/sms.h index c7d31260913..d40d936d346 100644 --- a/src/mame/includes/sms.h +++ b/src/mame/includes/sms.h @@ -30,6 +30,7 @@ #include "video/315_5124.h" #include "screen.h" +#include "machine/timer.h" class sms_state : public driver_device @@ -92,7 +93,7 @@ public: void sms2_ntsc(machine_config &config); void sms1_kr(machine_config &config); - DECLARE_WRITE_LINE_MEMBER(sms_pause_callback); + DECLARE_WRITE_LINE_MEMBER(gg_pause_callback); uint32_t screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); @@ -128,7 +129,7 @@ protected: DECLARE_READ8_MEMBER(sms_sscope_r); DECLARE_WRITE8_MEMBER(sms_sscope_w); - DECLARE_WRITE_LINE_MEMBER(sms_csync_callback); + DECLARE_WRITE_LINE_MEMBER(sms_n_csync_callback); DECLARE_WRITE_LINE_MEMBER(sms_ctrl1_th_input); DECLARE_WRITE_LINE_MEMBER(sms_ctrl2_th_input); DECLARE_WRITE_LINE_MEMBER(gg_ext_th_input); @@ -227,7 +228,7 @@ protected: uint8_t m_port_dc_reg; uint8_t m_port_dd_reg; uint8_t m_gg_sio[5]; - int m_paused; + int m_gg_paused; uint8_t m_ctrl1_th_state; uint8_t m_ctrl2_th_state; @@ -236,6 +237,8 @@ protected: // Data needed for Light Phaser int m_lphaser_x_offs; /* Needed to 'calibrate' lphaser; set at cart loading */ + emu_timer *m_lphaser_th_timer; + TIMER_CALLBACK_MEMBER(lphaser_th_generate); // Data needed for SegaScope (3D glasses) uint8_t m_sscope_state; diff --git a/src/mame/machine/sms.cpp b/src/mame/machine/sms.cpp index 359422796dd..e784353b8c0 100644 --- a/src/mame/machine/sms.cpp +++ b/src/mame/machine/sms.cpp @@ -18,11 +18,17 @@ #define ENABLE_EXT_RAM 0x10 +TIMER_CALLBACK_MEMBER(sms_state::lphaser_th_generate) +{ + m_vdp->hcount_latch(); +} + + void sms_state::lphaser_hcount_latch() { /* A delay seems to occur when the Light Phaser latches the VDP hcount, then an offset is added here to the hpos. */ - m_vdp->hcount_latch_at_hpos(m_main_scr->hpos() + m_lphaser_x_offs); + m_lphaser_th_timer->adjust(m_main_scr->time_until_pos(m_main_scr->vpos(), m_main_scr->hpos() + m_lphaser_x_offs)); } @@ -210,47 +216,39 @@ READ8_MEMBER(sms_state::sms_count_r) /* - Check if the pause button is pressed. - If the gamegear is in sms mode, check if the start button is pressed. + If the gamegear is in sms mode, the start button performs the pause function. */ -WRITE_LINE_MEMBER(sms_state::sms_pause_callback) +WRITE_LINE_MEMBER(sms_state::gg_pause_callback) { - bool pause_pressed = false; - - if (!m_is_mark_iii) + if (!state) { - // clear TH latch of the controller ports - m_ctrl1_th_latch = 0; - m_ctrl2_th_latch = 0; - } + bool pause_pressed = false; - if (m_is_gamegear) - { - if (!(m_cartslot->exists() && m_cartslot->get_sms_mode())) - return; + if (m_cartslot->exists() && m_cartslot->get_sms_mode()) + { + if (!(m_port_start->read() & 0x80)) + pause_pressed = true; + } - if (!(m_port_start->read() & 0x80)) - pause_pressed = true; - } - else - { - if (!(m_port_pause->read() & 0x80)) - pause_pressed = true; - } + if (pause_pressed) + { + if (!m_gg_paused) + m_maincpu->set_input_line(INPUT_LINE_NMI, ASSERT_LINE); - if (pause_pressed) - { - if (!m_paused) - m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero); + m_gg_paused = 1; + } + else + { + if (m_gg_paused) + m_maincpu->set_input_line(INPUT_LINE_NMI, CLEAR_LINE); - m_paused = 1; + m_gg_paused = 0; + } } - else - m_paused = 0; } -WRITE_LINE_MEMBER(sms_state::sms_csync_callback) +WRITE_LINE_MEMBER(sms_state::sms_n_csync_callback) { if (m_port_rapid.found()) { @@ -414,7 +412,9 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r) { if (m_ctrl1_th_latch) { - m_port_dd_reg &= ~0x40; + if (m_vdp->hcount_latched()) + m_port_dd_reg &= ~0x40; + m_ctrl1_th_latch = 0; } } @@ -436,7 +436,9 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r) { if (m_ctrl2_th_latch) { - m_port_dd_reg &= ~0x80; + if (m_vdp->hcount_latched()) + m_port_dd_reg &= ~0x80; + m_ctrl2_th_latch = 0; } } @@ -1047,7 +1049,9 @@ void sms_state::machine_start() } } - save_item(NAME(m_paused)); + m_lphaser_th_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sms_state::lphaser_th_generate),this)); + + save_item(NAME(m_gg_paused)); save_item(NAME(m_mapper)); save_item(NAME(m_port_dc_reg)); save_item(NAME(m_port_dd_reg)); -- cgit v1.2.3