diff options
Diffstat (limited to 'src/mame/video/x68k_crtc.cpp')
-rw-r--r-- | src/mame/video/x68k_crtc.cpp | 144 |
1 files changed, 52 insertions, 92 deletions
diff --git a/src/mame/video/x68k_crtc.cpp b/src/mame/video/x68k_crtc.cpp index 70453f92b53..c7e870ccf01 100644 --- a/src/mame/video/x68k_crtc.cpp +++ b/src/mame/video/x68k_crtc.cpp @@ -5,7 +5,7 @@ #include "video/x68k_crtc.h" #include "screen.h" -//#define VERBOSE 0 +//#define VERBOSE 1 #include "logmacro.h" // device type definitions @@ -152,18 +152,14 @@ void x68k_crtc_device::refresh_mode() { // Calculate data from register values m_vmultiple = 1; - if ((m_reg[20] & 0x10) != 0 && (m_reg[20] & 0x0c) == 0) - m_vmultiple = 2; // 31.5kHz + 256 lines = doublescan if (m_interlace) m_vmultiple = 0.5f; // 31.5kHz + 1024 lines or 15kHz + 512 lines = interlaced m_htotal = (m_reg[0] + 1) * 8; m_vtotal = (m_reg[4] + 1) / m_vmultiple; // default is 567 (568 scanlines) m_hbegin = (m_reg[2] * 8) + 1; - m_hend = (m_reg[3] * 8); - m_vbegin = (m_reg[6]) / m_vmultiple; + m_hend = m_reg[3] * 8; + m_vbegin = m_reg[6] / m_vmultiple; m_vend = (m_reg[7] - 1) / m_vmultiple; - if ((m_vmultiple == 2) && !(m_reg[7] & 1)) // otherwise if the raster irq line == vblank line, the raster irq fires too late - m_vend++; m_hsync_end = (m_reg[1]) * 8; m_vsync_end = (m_reg[5]) / m_vmultiple; m_hsyncadjust = m_reg[8]; @@ -175,19 +171,9 @@ void x68k_crtc_device::refresh_mode() scr.max_x = m_hend + 2; rectangle visiblescr(m_hbegin, m_hend, m_vbegin, m_vend); - // expand visible area to the size indicated by CRTC reg 20 - int length = m_hend - m_hbegin; - if (length < m_width) - { - visiblescr.min_x = m_hbegin - ((m_width - length)/2); - visiblescr.max_x = m_hend + ((m_width - length)/2); - } - length = m_vend - m_vbegin; - if (length < m_height) - { - visiblescr.min_y = m_vbegin - ((m_height - length)/2); - visiblescr.max_y = m_vend + ((m_height - length)/2); - } + if ((visiblescr.max_y > m_height) || (visiblescr.max_x > m_width)) + logerror("visarea larger then reg[20]: %dx%d, %dx%d\n", visiblescr.max_x, visiblescr.max_y, m_width, m_height); + // bounds check if (visiblescr.min_x < 0) visiblescr.min_x = 0; @@ -200,11 +186,29 @@ void x68k_crtc_device::refresh_mode() // LOG("CRTC regs - %i %i %i %i - %i %i %i %i - %i - %i\n", m_reg[0], m_reg[1], m_reg[2], m_reg[3], // m_reg[4], m_reg[5], m_reg[6], m_reg[7], m_reg[8], m_reg[9]); - unsigned div = (m_reg[20] & 0x03) == 0 ? 4 : 2; - if (BIT(m_reg[20], 4) && !BIT(m_reg[20], 1)) - div = BIT(m_reg[20], 0) ? 3 : 6; - if ((m_reg[20] & 0x0c) == 0) - div *= 2; + int div; + switch (m_reg[20] & 0x1f) + { + case 0: + div = 8; + break; + default: + logerror("Invalid mode %d", m_reg[20] & 0x1f); [[fallthrough]]; + case 1: + case 5: + case 0x11: + div = 4; + break; + case 0x16: + div = 2; + break; + case 0x10: + div = 6; + break; + case 0x15: + div = 3; + break; + } attotime refresh = attotime::from_hz((BIT(m_reg[20], 4) ? clock_69m() : clock_39m()) / div) * (scr.max_x * scr.max_y); LOG("screen().configure(%i,%i,[%i,%i,%i,%i],%f)\n", scr.max_x, scr.max_y, visiblescr.min_x, visiblescr.min_y, visiblescr.max_x, visiblescr.max_y, refresh.as_hz()); screen().configure(scr.max_x, scr.max_y, visiblescr, refresh.as_attoseconds()); @@ -221,69 +225,22 @@ TIMER_CALLBACK_MEMBER(x68k_crtc_device::hsync) if (m_operation & 8) text_copy((m_reg[22] & 0xff00) >> 8, (m_reg[22] & 0x00ff), (m_reg[21] & 0xf)); - if (m_vmultiple == 2) // 256-line (doublescan) + int scan = screen().vpos(); + if (hstate == 1) { - if (hstate == 1) - { - if (m_oddscanline) - { - int scan = screen().vpos(); - if (scan > m_vend) - scan = m_vbegin; - hsync_time = screen().time_until_pos(scan, (m_htotal + m_hend) / 2); - m_scanline_timer->adjust(hsync_time); - if (scan != 0) - screen().update_partial(scan); - } - else - { - int scan = screen().vpos(); - if (scan > m_vend) - scan = m_vbegin; - hsync_time = screen().time_until_pos(scan, m_hend / 2); - m_scanline_timer->adjust(hsync_time); - if (scan != 0) - screen().update_partial(scan); - } - } - if (hstate == 0) - { - if (m_oddscanline) - { - int scan = screen().vpos(); - if (scan > m_vend) - scan = m_vbegin; - else - scan++; - hsync_time = screen().time_until_pos(scan, m_hbegin / 2); - m_scanline_timer->adjust(hsync_time, 1); - m_oddscanline = false; - } - else - { - hsync_time = screen().time_until_pos(screen().vpos(), (m_htotal + m_hbegin) / 2); - m_scanline_timer->adjust(hsync_time, 1); - m_oddscanline = true; - } - } + hsync_time = screen().time_until_pos(scan, m_hend); + m_scanline_timer->adjust(hsync_time); + if ((scan != 0) && (scan < m_vend)) + screen().update_partial(scan - 1); } - else // 512-line + if (hstate == 0) { - if (hstate == 1) - { - int scan = screen().vpos(); - if (scan > m_vend) - scan = 0; - hsync_time = screen().time_until_pos(scan, m_hend); - m_scanline_timer->adjust(hsync_time); - if (scan != 0) - screen().update_partial(scan); - } - if (hstate == 0) - { - hsync_time = screen().time_until_pos(screen().vpos() + 1, m_hbegin); - m_scanline_timer->adjust(hsync_time, 1); - } + if (scan == (m_vtotal - 1)) + scan = 0; + else + scan++; + hsync_time = screen().time_until_pos(scan, m_hbegin); + m_scanline_timer->adjust(hsync_time, 1); } } @@ -301,7 +258,7 @@ TIMER_CALLBACK_MEMBER(x68k_crtc_device::raster_irq) if (scan <= m_vtotal) { m_rint_callback(0); - screen().update_partial(scan); + screen().update_partial(scan - 1); irq_time = screen().time_until_pos(scan, m_hbegin); // end of HBlank period clears GPIP6 also? end_time = screen().time_until_pos(scan, m_hend); @@ -407,14 +364,15 @@ void x68k_crtc_device::crtc_w(offs_t offset, u16 data, u16 mem_mask) case 9: // CRTC raster IRQ (GPIP6) { data = m_reg[9]; - attotime irq_time = screen().time_until_pos((data) / m_vmultiple,2); - - if (data != screen().vpos()) + attotime irq_time = attotime::zero; + if ((data / m_vmultiple) != screen().vpos()) + { + irq_time = screen().time_until_pos((data - 1) / m_vmultiple,2); m_rint_callback(1); - if (irq_time.as_double() > 0) - m_raster_irq_timer->adjust(irq_time, (data) / m_vmultiple); + } + m_raster_irq_timer->adjust(irq_time, (data) / m_vmultiple); + LOG("CRTC: Write to raster IRQ register - %i %i %f\n",data, screen().vpos(), irq_time.as_double()); } - LOG("CRTC: Write to raster IRQ register - %i\n",data); break; case 20: if (ACCESSING_BITS_0_7) @@ -480,6 +438,8 @@ u16 x68k_crtc_device::crtc_r(offs_t offset) switch (offset) { case 9: + if (machine().side_effects_disabled()) + return m_reg[9]; return 0; case 10: // Text X/Y scroll case 11: |