diff options
Diffstat (limited to 'src/devices/video/315_5124.cpp')
-rw-r--r-- | src/devices/video/315_5124.cpp | 106 |
1 files changed, 71 insertions, 35 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); |