mirror of
https://github.com/holub/mame
synced 2025-04-23 00:39:36 +03:00
electron: Improved video handling.
- Fixed wrap-around for non-standard screen start addresses - Added RAM contention during screen update - Improved interrupt times
This commit is contained in:
parent
001ec452c9
commit
ed3345e84f
@ -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")
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user