(MESS) gamecom : fixed pixel blending.

Centipede, Wheel of Fortune 1 & 2 are fully playable.
Frogger and Quiz Whiz are 98% playable.
This commit is contained in:
Robert 2014-11-29 00:54:35 +11:00
parent d722385186
commit 64f77ced7c
3 changed files with 52 additions and 94 deletions

View File

@ -11,19 +11,18 @@ Todo:
Game Status: Game Status:
- The DAC sound partially works, sound from ports 1,2,3 not done - The DAC sound partially works, sound from ports 1,2,3 not done
- Inbuilt ROM and PDA functions all work - Inbuilt ROM and PDA functions all work
- When starting a cart, the graphic of the cart going into the slot is corrupt - On the screen where the cart goes into the slot there is video flicker
- Due to an irritating message, the NVRAM is commented out in the machine config - Due to an irritating message, the NVRAM is commented out in the machine config
- Cart games all have severe video issues such as flickering and nonsense gfx - Most of the cart games have severe video issues such as flickering and nonsense gfx
- Lights Out works - Lights Out works
- Centipede works with bad flickering - Centipede works
- Frogger works, but there are bugs on the 2nd row of cars (if you turn your - Wheel of Fortune 1 & 2 are working.
frog to the right it dies, and also one car goes in reverse), and not possible - Frogger works, but it is difficult to capture the female frog or the insect.
to get the female frog. - Quiz Wiz works, but the end-of-round score doesn't show
- Wheel of Fortune 1&2, playable although the spinner is corrupt
- Jeopardy, playable with bad gfx - Jeopardy, playable with bad gfx
- Quiz Wiz works, but the final score doesn't show
- Tiger Web Link & Internet, they look ok, obviously aren't going to connect to anything - Tiger Web Link & Internet, they look ok, obviously aren't going to connect to anything
- Williams Arcade Classics, Robotron works, the rest are no use. - Williams Arcade Classics, Robotron works, the rest are no use.
- Monopoly is starting to show promise. It's playable but the video is terrible.
- The remaining carts are not functional to any useful degree. - The remaining carts are not functional to any useful degree.
***************************************************************************/ ***************************************************************************/

View File

@ -7,9 +7,8 @@ static const int gamecom_timer_limit[8] = { 2, 1024, 2048, 4096, 8192, 16384, 32
TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_clock_timer_callback) TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_clock_timer_callback)
{ {
UINT8 * RAM = m_region_maincpu->base(); UINT8 val = m_p_ram[SM8521_CLKT] + 1;
UINT8 val = RAM[SM8521_CLKT] + 1; m_p_ram[SM8521_CLKT] = ( m_p_ram[SM8521_CLKT] & 0xC0 ) | (val & 0x3f);
RAM[SM8521_CLKT] = ( RAM[SM8521_CLKT] & 0xC0 ) | (val & 0x3f);
m_maincpu->set_input_line(sm8500_cpu_device::CK_INT, ASSERT_LINE ); m_maincpu->set_input_line(sm8500_cpu_device::CK_INT, ASSERT_LINE );
} }
@ -417,14 +416,9 @@ WRITE8_MEMBER( gamecom_state::gamecom_internal_w )
/* The manual is not conclusive as to which bit of the DMVP register (offset 0x3D) determines /* The manual is not conclusive as to which bit of the DMVP register (offset 0x3D) determines
which page for source or destination is used */ which page for source or destination is used */
/* For now the increment/decrement-x and increment/decrement-y parts are NOT supported.
Their usage is also not explained properly in the manuals. Guess we'll have to wait
for them to show up in some rom images...
*/
WRITE8_MEMBER( gamecom_state::gamecom_handle_dma ) WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
{ {
UINT8 * RAM = m_region_maincpu->base(); UINT8 dmc = m_p_ram[SM8521_DMC];
UINT8 dmc = RAM[SM8521_DMC];
m_dma.overwrite_mode = dmc & 0x01; m_dma.overwrite_mode = dmc & 0x01;
m_dma.transfer_mode = dmc & 0x06; m_dma.transfer_mode = dmc & 0x06;
m_dma.decrement_x = dmc & 0x08; m_dma.decrement_x = dmc & 0x08;
@ -435,60 +429,55 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
return; return;
} }
//if ( m_dma.decrement_x || m_dma.decrement_y ) m_dma.width_x = m_p_ram[SM8521_DMDX];
//{
//popmessage( "TODO: Decrement-x and decrement-y are not supported yet\n" );
//}
m_dma.width_x = RAM[SM8521_DMDX];
m_dma.width_x_count = 0; m_dma.width_x_count = 0;
m_dma.width_y = RAM[SM8521_DMDY]; m_dma.width_y = m_p_ram[SM8521_DMDY];
m_dma.width_y_count = 0; m_dma.width_y_count = 0;
m_dma.source_x = RAM[SM8521_DMX1]; m_dma.source_x = m_p_ram[SM8521_DMX1];
m_dma.source_x_current = m_dma.source_x; m_dma.source_x_current = m_dma.source_x;
m_dma.source_y = RAM[SM8521_DMY1]; m_dma.source_y = m_p_ram[SM8521_DMY1];
m_dma.source_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40; m_dma.source_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.dest_x = RAM[SM8521_DMX2]; m_dma.dest_x = m_p_ram[SM8521_DMX2];
m_dma.dest_x_current = m_dma.dest_x; m_dma.dest_x_current = m_dma.dest_x;
m_dma.dest_y = RAM[SM8521_DMY2]; m_dma.dest_y = m_p_ram[SM8521_DMY2];
m_dma.dest_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40; m_dma.dest_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.palette[0] = RAM[SM8521_DMPL] & 0x03; m_dma.palette[0] = m_p_ram[SM8521_DMPL] & 0x03;
m_dma.palette[1] = ( RAM[SM8521_DMPL] >> 2 ) & 3; m_dma.palette[1] = ( m_p_ram[SM8521_DMPL] >> 2 ) & 3;
m_dma.palette[2] = ( RAM[SM8521_DMPL] >> 4 ) & 3; m_dma.palette[2] = ( m_p_ram[SM8521_DMPL] >> 4 ) & 3;
m_dma.palette[3] = RAM[SM8521_DMPL] >> 6; m_dma.palette[3] = m_p_ram[SM8521_DMPL] >> 6;
m_dma.source_mask = 0x1FFF; m_dma.source_mask = 0x1FFF;
m_dma.dest_mask = 0x1FFF; m_dma.dest_mask = 0x1FFF;
// logerror("DMA: width %Xx%X, source (%X,%X), dest (%X,%X), transfer_mode %X, banks %X \n", m_dma.width_x, m_dma.width_y, m_dma.source_x, m_dma.source_y, m_dma.dest_x, m_dma.dest_y, m_dma.transfer_mode, RAM[SM8521_DMVP] ); // logerror("DMA: width %Xx%X, source (%X,%X), dest (%X,%X), transfer_mode %X, banks %X \n", m_dma.width_x, m_dma.width_y, m_dma.source_x, m_dma.source_y, m_dma.dest_x, m_dma.dest_y, m_dma.transfer_mode, m_p_ram[SM8521_DMVP] );
// logerror( " Palette: %d, %d, %d, %d\n", m_dma.palette[0], m_dma.palette[1], m_dma.palette[2], m_dma.palette[3] ); // logerror( " Palette: %d, %d, %d, %d\n", m_dma.palette[0], m_dma.palette[1], m_dma.palette[2], m_dma.palette[3] );
switch( m_dma.transfer_mode ) switch( m_dma.transfer_mode )
{ {
case 0x00: case 0x00:
/* VRAM->VRAM */ /* VRAM->VRAM */
m_dma.source_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000]; m_dma.source_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000]; m_dma.dest_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
break; break;
case 0x02: case 0x02:
/* ROM->VRAM */ /* ROM->VRAM */
// logerror( "DMA DMBR = %X\n", RAM[SM8521_DMBR] ); // logerror( "DMA DMBR = %X\n", m_p_ram[SM8521_DMBR] );
m_dma.source_width = 64; m_dma.source_width = 64;
m_dma.source_mask = 0x3FFF; m_dma.source_mask = 0x3FFF;
if (RAM[SM8521_DMBR] < 16) if (m_p_ram[SM8521_DMBR] < 16)
m_dma.source_bank = m_region_kernel->base() + (RAM[SM8521_DMBR] << 14); m_dma.source_bank = m_region_kernel->base() + (m_p_ram[SM8521_DMBR] << 14);
else else
if (m_cart_ptr) if (m_cart_ptr)
m_dma.source_bank = m_cart_ptr + (RAM[SM8521_DMBR] << 14); m_dma.source_bank = m_cart_ptr + (m_p_ram[SM8521_DMBR] << 14);
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000]; m_dma.dest_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
break; break;
case 0x04: case 0x04:
/* Extend RAM->VRAM */ /* Extend RAM->VRAM */
m_dma.source_width = 64; m_dma.source_width = 64;
m_dma.source_bank = &m_p_nvram[0x0000]; m_dma.source_bank = &m_p_nvram[0x0000];
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000]; m_dma.dest_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
break; break;
case 0x06: case 0x06:
/* VRAM->Extend RAM */ /* VRAM->Extend RAM */
m_dma.source_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000]; m_dma.source_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
m_dma.dest_width = 64; m_dma.dest_width = 64;
m_dma.dest_bank = &m_p_nvram[0x0000]; m_dma.dest_bank = &m_p_nvram[0x0000];
break; break;
@ -507,50 +496,22 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
{ {
for( x_count = 0; x_count <= m_dma.width_x; x_count++ ) for( x_count = 0; x_count <= m_dma.width_x; x_count++ )
{ {
int source_pixel = 0; UINT16 src_addr = m_dma.source_current & m_dma.source_mask;
int dest_pixel = 0; UINT16 dest_addr = m_dma.dest_current & m_dma.dest_mask;
int src_addr = m_dma.source_current & m_dma.source_mask; UINT8 dest_adj = (3 - (m_dma.dest_x_current & 3)) << 1;
int dest_addr = m_dma.dest_current & m_dma.dest_mask; UINT8 src_adj = (3 - (m_dma.source_x_current & 3)) << 1;
/* handle DMA for 1 pixel */ /* handle DMA for 1 pixel */
/* Read pixel data */ // Get new pixel
switch ( m_dma.source_x_current & 0x03 ) UINT8 source_pixel = (m_dma.source_bank[src_addr] >> src_adj) & 3;
{
case 0x00: source_pixel = m_dma.source_bank[src_addr] >> 6; break;
case 0x01: source_pixel = ( m_dma.source_bank[src_addr] >> 4 ) & 3; break;
case 0x02: source_pixel = ( m_dma.source_bank[src_addr] >> 2 ) & 3; break;
case 0x03: source_pixel = m_dma.source_bank[src_addr] & 3; break;
}
if ( !m_dma.overwrite_mode && source_pixel == 0 ) // If overwrite mode, write new pixel
if ( m_dma.overwrite_mode || source_pixel)
{ {
switch ( m_dma.dest_x_current & 0x03 ) // Get 4 pixels and remove the one about to be replaced
{ UINT8 other_pixels = m_dma.dest_bank[dest_addr] & ~(3 << dest_adj);
case 0x00: dest_pixel = m_dma.dest_bank[dest_addr] >> 6; break; // Get palette of new pixel and place into the hole
case 0x01: dest_pixel = ( m_dma.dest_bank[dest_addr] >> 4 ) & 3; break; m_dma.dest_bank[dest_addr] = other_pixels | (m_dma.palette[ source_pixel ] << dest_adj);
case 0x02: dest_pixel = ( m_dma.dest_bank[dest_addr] >> 2 ) & 3; break;
case 0x03: dest_pixel = m_dma.dest_bank[dest_addr] & 3; break;
}
source_pixel = dest_pixel;
}
/* Translate pixel data using DMA palette. */
/* Not sure if this should be done before the compound stuff - WP */
source_pixel = m_dma.palette[ source_pixel ];
/* Write pixel data */
switch( m_dma.dest_x_current & 0x03 )
{
case 0x00:
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0x3F ) | ( source_pixel << 6 );
break;
case 0x01:
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0xCF ) | ( source_pixel << 4 );
break;
case 0x02:
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0xF3 ) | ( source_pixel << 2 );
break;
case 0x03:
m_dma.dest_bank[dest_addr] = ( m_dma.dest_bank[dest_addr] & 0xFC ) | source_pixel;
break;
} }
/* Advance a pixel */ /* Advance a pixel */
@ -588,17 +549,16 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
WRITE8_MEMBER( gamecom_state::gamecom_update_timers ) WRITE8_MEMBER( gamecom_state::gamecom_update_timers )
{ {
UINT8 * RAM = m_region_maincpu->base();
if ( m_timer[0].enabled ) if ( m_timer[0].enabled )
{ {
m_timer[0].state_count += data; m_timer[0].state_count += data;
while ( m_timer[0].state_count >= m_timer[0].state_limit ) while ( m_timer[0].state_count >= m_timer[0].state_limit )
{ {
m_timer[0].state_count -= m_timer[0].state_limit; m_timer[0].state_count -= m_timer[0].state_limit;
RAM[SM8521_TM0D]++; m_p_ram[SM8521_TM0D]++;
if ( RAM[SM8521_TM0D] >= m_timer[0].check_value ) if ( m_p_ram[SM8521_TM0D] >= m_timer[0].check_value )
{ {
RAM[SM8521_TM0D] = 0; m_p_ram[SM8521_TM0D] = 0;
m_maincpu->set_input_line(sm8500_cpu_device::TIM0_INT, ASSERT_LINE ); m_maincpu->set_input_line(sm8500_cpu_device::TIM0_INT, ASSERT_LINE );
} }
} }
@ -609,10 +569,10 @@ WRITE8_MEMBER( gamecom_state::gamecom_update_timers )
while ( m_timer[1].state_count >= m_timer[1].state_limit ) while ( m_timer[1].state_count >= m_timer[1].state_limit )
{ {
m_timer[1].state_count -= m_timer[1].state_limit; m_timer[1].state_count -= m_timer[1].state_limit;
RAM[SM8521_TM1D]++; m_p_ram[SM8521_TM1D]++;
if ( RAM[SM8521_TM1D] >= m_timer[1].check_value ) if ( m_p_ram[SM8521_TM1D] >= m_timer[1].check_value )
{ {
RAM[SM8521_TM1D] = 0; m_p_ram[SM8521_TM1D] = 0;
m_maincpu->set_input_line(sm8500_cpu_device::TIM1_INT, ASSERT_LINE ); m_maincpu->set_input_line(sm8500_cpu_device::TIM1_INT, ASSERT_LINE );
} }
} }

View File

@ -7,7 +7,6 @@
TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_scanline) TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_scanline)
{ {
// draw line // draw line
if ( m_scanline == 0 )
m_base_address = ( m_p_ram[SM8521_LCDC] & 0x40 ) ? 0x2000 : 0x0000; m_base_address = ( m_p_ram[SM8521_LCDC] & 0x40 ) ? 0x2000 : 0x0000;
if ( ~m_p_ram[SM8521_LCDC] & 0x80 ) if ( ~m_p_ram[SM8521_LCDC] & 0x80 )