From ed3345e84f024fdfe4e52a9a13469f8747fa45ce Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Mon, 16 Apr 2018 13:16:05 +0100 Subject: electron: Improved video handling. - Fixed wrap-around for non-standard screen start addresses - Added RAM contention during screen update - Improved interrupt times --- src/mame/drivers/electron.cpp | 1 + src/mame/includes/electron.h | 5 ++--- src/mame/machine/electron.cpp | 18 +++++++++--------- src/mame/video/electron.cpp | 43 +++++++++++++++++++++++++------------------ 4 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/mame/drivers/electron.cpp b/src/mame/drivers/electron.cpp index 09d7ec744d6..dd7dc8ed1f8 100644 --- a/src/mame/drivers/electron.cpp +++ b/src/mame/drivers/electron.cpp @@ -218,6 +218,7 @@ MACHINE_CONFIG_START(electron_state::electron) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_RAW_PARAMS(16_MHz_XTAL, 1024, 0, 640, 312, 0, 256) + //MCFG_SCREEN_RAW_PARAMS(16_MHz_XTAL, 1024, 264, 264 + 640, 312, 31, 31 + 256) MCFG_SCREEN_UPDATE_DRIVER(electron_state, screen_update_electron) MCFG_SCREEN_VIDEO_ATTRIBUTES(VIDEO_UPDATE_SCANLINE) MCFG_SCREEN_PALETTE("palette") diff --git a/src/mame/includes/electron.h b/src/mame/includes/electron.h index 03066fb852a..ba11ea1d2f6 100644 --- a/src/mame/includes/electron.h +++ b/src/mame/includes/electron.h @@ -119,15 +119,14 @@ private: uint8_t rompage; uint16_t screen_start; uint16_t screen_base; - int screen_size; + uint16_t screen_size; uint16_t screen_addr; - uint8_t *vram; + int screen_dispend; int current_pal[16]; int communication_mode; int screen_mode; int cassette_motor_mode; int capslock_mode; - // int scanline; /* tape reading related */ uint32_t tape_value; int tape_steps; diff --git a/src/mame/machine/electron.cpp b/src/mame/machine/electron.cpp index 6e1236fdba0..fa7a085c697 100644 --- a/src/mame/machine/electron.cpp +++ b/src/mame/machine/electron.cpp @@ -18,9 +18,9 @@ void electron_state::waitforramsync() { int cycles = 0; - if (!(m_ula.screen_mode & 4) && m_screen->hpos()<640) + if (!(m_ula.screen_mode & 4) && (m_screen->vpos() > m_screen->visible_area().min_y) && (m_screen->vpos() < m_screen->visible_area().max_y) && !m_screen->hblank()) { - cycles += (640 - m_screen->hpos()) / 8; + cycles += (m_screen->visible_area().max_x - m_screen->hpos()) / 16; } if (cycles & 1) cycles++; @@ -156,7 +156,7 @@ READ8_MEMBER(electron_state::electron_mem_r) case 0x00: /* Normal */ /* The processor will run at 1MHz during an access cycle to the RAM */ m_maincpu->set_clock_scale(0.5f); - //waitforramsync(); + waitforramsync(); break; case 0x01: /* Turbo */ @@ -177,7 +177,7 @@ WRITE8_MEMBER(electron_state::electron_mem_w) case 0x00: /* Normal */ /* The processor will run at 1MHz during an access cycle to the RAM */ m_maincpu->set_clock_scale(0.5f); - //waitforramsync(); + waitforramsync(); break; case 0x01: /* Turbo */ @@ -335,7 +335,8 @@ READ8_MEMBER(electron_state::electron_sheila_r) } static const int electron_palette_offset[4] = { 0, 4, 5, 1 }; -static const uint16_t electron_screen_base[8] = { 0x3000, 0x3000, 0x3000, 0x4000, 0x5800, 0x5800, 0x6000, 0x5800 }; +static const uint16_t electron_screen_base[8] = { 0x3000, 0x3000, 0x3000, 0x4000, 0x5800, 0x5800, 0x6000, 0x6000 }; +static const int electron_mode_end[8] = { 255, 255, 255 ,249 ,255, 255, 249, 249 }; WRITE8_MEMBER(electron_state::electron_sheila_w) { @@ -358,7 +359,7 @@ WRITE8_MEMBER(electron_state::electron_sheila_w) logerror( "screen_start changed to %04x\n", m_ula.screen_start ); break; case 0x03: /* Screen start address #2 */ - m_ula.screen_start = ( m_ula.screen_start & 0x1c0 ) | ( ( data & 0x3f ) << 9 ); + m_ula.screen_start = ( m_ula.screen_start & 0x1ff ) | ( ( data & 0x3f ) << 9 ); logerror( "screen_start changed to %04x\n", m_ula.screen_start ); break; case 0x04: /* Cassette data shift register */ @@ -429,7 +430,7 @@ WRITE8_MEMBER(electron_state::electron_sheila_w) m_ula.screen_mode = ( data >> 3 ) & 0x07; m_ula.screen_base = electron_screen_base[ m_ula.screen_mode ]; m_ula.screen_size = 0x8000 - m_ula.screen_base; - m_ula.vram = (uint8_t *)m_ram->pointer() + m_ula.screen_base; + m_ula.screen_dispend = electron_mode_end[ m_ula.screen_mode ]; logerror( "ULA: screen mode set to %d\n", m_ula.screen_mode ); m_ula.cassette_motor_mode = ( data >> 6 ) & 0x01; m_cassette->change_state(m_ula.cassette_motor_mode ? CASSETTE_MOTOR_ENABLED : CASSETTE_MOTOR_DISABLED, CASSETTE_MOTOR_DISABLED ); @@ -494,9 +495,8 @@ void electron_state::machine_reset() m_ula.screen_start = 0x3000; m_ula.screen_base = 0x3000; m_ula.screen_size = 0x8000 - 0x3000; - m_ula.screen_addr = 0; + m_ula.screen_addr = 0x3000; m_ula.tape_running = 0; - m_ula.vram = (uint8_t *)m_ram->pointer() + m_ula.screen_base; m_mrb_mapped = true; m_vdu_drivers = false; diff --git a/src/mame/video/electron.cpp b/src/mame/video/electron.cpp index 9734ded6ced..64f6b1b11ec 100644 --- a/src/mame/video/electron.cpp +++ b/src/mame/video/electron.cpp @@ -72,9 +72,10 @@ void electron_state::video_start() m_scanline_timer->adjust( m_screen->time_until_pos(0), 0, m_screen->scan_period() ); } -inline uint8_t electron_state::read_vram( uint16_t addr ) +inline uint8_t electron_state::read_vram( uint16_t addr ) { - return m_ula.vram[ addr % m_ula.screen_size ]; + if ( addr & 0x8000 ) addr -= m_ula.screen_size; + return m_ram->read( addr ); } inline void electron_state::electron_plot_pixel(bitmap_ind16 &bitmap, int x, int y, uint32_t color) @@ -84,7 +85,9 @@ inline void electron_state::electron_plot_pixel(bitmap_ind16 &bitmap, int x, int uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect) { - int x = 0; + int min_x = screen.visible_area().min_x; + int min_y = screen.visible_area().min_y; + int x = min_x; int pal[16]; int scanline = screen.vpos(); rectangle r = cliprect; @@ -114,7 +117,7 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in case 0: for( int i = 0; i < 80; i++ ) { - uint8_t pattern = read_vram( m_ula.screen_addr + (i << 3) ); + uint8_t pattern = read_vram( m_ula.screen_addr + i * 8 ); electron_plot_pixel( bitmap, x++, scanline, pal[(pattern>>7)& 1] ); electron_plot_pixel( bitmap, x++, scanline, pal[(pattern>>6)& 1] ); electron_plot_pixel( bitmap, x++, scanline, pal[(pattern>>5)& 1] ); @@ -125,7 +128,7 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in electron_plot_pixel( bitmap, x++, scanline, pal[(pattern>>0)& 1] ); } m_ula.screen_addr++; - if ( ( scanline & 0x07 ) == 7 ) + if ( ( ( scanline - min_y ) & 0x07 ) == 7 ) m_ula.screen_addr += 0x278; break; @@ -143,7 +146,7 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in electron_plot_pixel( bitmap, x++, scanline, pal[m_map4[pattern>>0]] ); } m_ula.screen_addr++; - if ( ( scanline & 0x07 ) == 7 ) + if ( ( ( scanline - min_y ) & 0x07 ) == 7 ) m_ula.screen_addr += 0x278; break; @@ -161,12 +164,12 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in electron_plot_pixel( bitmap, x++, scanline, pal[m_map16[pattern>>0]] ); } m_ula.screen_addr++; - if ( ( scanline & 0x07 ) == 7 ) + if ( ( ( scanline - min_y ) & 0x07 ) == 7 ) m_ula.screen_addr += 0x278; break; case 3: - if ( ( scanline > 249 ) || ( scanline % 10 >= 8 ) ) + if ( ( ( scanline - min_y ) > 249 ) || ( ( scanline - min_y ) % 10 >= 8 ) ) bitmap.fill(7, r ); else { @@ -184,7 +187,7 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in } m_ula.screen_addr++; } - if ( scanline % 10 == 9 ) + if ( ( scanline - min_y ) % 10 == 9 ) m_ula.screen_addr += 0x278; break; @@ -211,7 +214,7 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in electron_plot_pixel( bitmap, x++, scanline, pal[(pattern>>0)&1] ); } m_ula.screen_addr++; - if ( ( scanline & 0x07 ) == 7 ) + if ( ( ( scanline - min_y ) & 0x07 ) == 7 ) m_ula.screen_addr += 0x138; break; @@ -237,12 +240,12 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in electron_plot_pixel( bitmap, x++, scanline, pal[m_map4[pattern>>0]] ); } m_ula.screen_addr++; - if ( ( scanline & 0x07 ) == 7 ) + if ( ( ( scanline - min_y ) & 0x07 ) == 7 ) m_ula.screen_addr += 0x138; break; case 6: - if ( ( scanline > 249 ) || ( scanline % 10 >= 8 ) ) + if ( ( ( scanline - min_y ) > 249) || ( ( scanline - min_y ) % 10 >= 8 ) ) bitmap.fill(7, r ); else { @@ -267,11 +270,13 @@ uint32_t electron_state::screen_update_electron(screen_device &screen, bitmap_in electron_plot_pixel( bitmap, x++, scanline, pal[(pattern>>0)&1] ); } m_ula.screen_addr++; - if ( ( scanline % 10 ) == 7 ) + if ( ( ( scanline - min_y ) % 10 ) == 7 ) m_ula.screen_addr += 0x138; } break; } + if ( m_ula.screen_addr & 0x8000 ) + m_ula.screen_addr -= m_ula.screen_size; return 0; } @@ -280,14 +285,16 @@ TIMER_CALLBACK_MEMBER(electron_state::electron_scanline_interrupt) { switch (m_screen->vpos()) { - case 43: + case 99: electron_interrupt_handler( INT_SET, INT_RTC ); break; - case 199: - electron_interrupt_handler( INT_SET, INT_DISPLAY_END ); + case 249: + case 255: + if ( m_screen->vpos() == m_ula.screen_dispend ) + electron_interrupt_handler( INT_SET, INT_DISPLAY_END ); break; - case 256: - m_ula.screen_addr = m_ula.screen_start - m_ula.screen_base; + case 311: + m_ula.screen_addr = m_ula.screen_start; break; } } -- cgit v1.2.3