(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:
- The DAC sound partially works, sound from ports 1,2,3 not done
- 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
- 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
- Centipede works with bad flickering
- Frogger works, but there are bugs on the 2nd row of cars (if you turn your
frog to the right it dies, and also one car goes in reverse), and not possible
to get the female frog.
- Wheel of Fortune 1&2, playable although the spinner is corrupt
- Centipede works
- Wheel of Fortune 1 & 2 are working.
- Frogger works, but it is difficult to capture the female frog or the insect.
- Quiz Wiz works, but the end-of-round score doesn't show
- 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
- 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.
***************************************************************************/

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)
{
UINT8 * RAM = m_region_maincpu->base();
UINT8 val = RAM[SM8521_CLKT] + 1;
RAM[SM8521_CLKT] = ( RAM[SM8521_CLKT] & 0xC0 ) | (val & 0x3f);
UINT8 val = m_p_ram[SM8521_CLKT] + 1;
m_p_ram[SM8521_CLKT] = ( m_p_ram[SM8521_CLKT] & 0xC0 ) | (val & 0x3f);
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
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 )
{
UINT8 * RAM = m_region_maincpu->base();
UINT8 dmc = RAM[SM8521_DMC];
UINT8 dmc = m_p_ram[SM8521_DMC];
m_dma.overwrite_mode = dmc & 0x01;
m_dma.transfer_mode = dmc & 0x06;
m_dma.decrement_x = dmc & 0x08;
@ -435,60 +429,55 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
return;
}
//if ( m_dma.decrement_x || m_dma.decrement_y )
//{
//popmessage( "TODO: Decrement-x and decrement-y are not supported yet\n" );
//}
m_dma.width_x = RAM[SM8521_DMDX];
m_dma.width_x = m_p_ram[SM8521_DMDX];
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.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_y = RAM[SM8521_DMY1];
m_dma.source_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.dest_x = RAM[SM8521_DMX2];
m_dma.source_y = m_p_ram[SM8521_DMY1];
m_dma.source_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.dest_x = m_p_ram[SM8521_DMX2];
m_dma.dest_x_current = m_dma.dest_x;
m_dma.dest_y = RAM[SM8521_DMY2];
m_dma.dest_width = ( RAM[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.palette[0] = RAM[SM8521_DMPL] & 0x03;
m_dma.palette[1] = ( RAM[SM8521_DMPL] >> 2 ) & 3;
m_dma.palette[2] = ( RAM[SM8521_DMPL] >> 4 ) & 3;
m_dma.palette[3] = RAM[SM8521_DMPL] >> 6;
m_dma.dest_y = m_p_ram[SM8521_DMY2];
m_dma.dest_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.palette[0] = m_p_ram[SM8521_DMPL] & 0x03;
m_dma.palette[1] = ( m_p_ram[SM8521_DMPL] >> 2 ) & 3;
m_dma.palette[2] = ( m_p_ram[SM8521_DMPL] >> 4 ) & 3;
m_dma.palette[3] = m_p_ram[SM8521_DMPL] >> 6;
m_dma.source_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] );
switch( m_dma.transfer_mode )
{
case 0x00:
/* VRAM->VRAM */
m_dma.source_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
m_dma.dest_bank = &m_p_videoram[(RAM[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
m_dma.source_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x01) ? 0x2000 : 0x0000];
m_dma.dest_bank = &m_p_videoram[(m_p_ram[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000];
break;
case 0x02:
/* 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_mask = 0x3FFF;
if (RAM[SM8521_DMBR] < 16)
m_dma.source_bank = m_region_kernel->base() + (RAM[SM8521_DMBR] << 14);
if (m_p_ram[SM8521_DMBR] < 16)
m_dma.source_bank = m_region_kernel->base() + (m_p_ram[SM8521_DMBR] << 14);
else
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;
case 0x04:
/* Extend RAM->VRAM */
m_dma.source_width = 64;
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;
case 0x06:
/* 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_bank = &m_p_nvram[0x0000];
break;
@ -507,50 +496,22 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
{
for( x_count = 0; x_count <= m_dma.width_x; x_count++ )
{
int source_pixel = 0;
int dest_pixel = 0;
int src_addr = m_dma.source_current & m_dma.source_mask;
int dest_addr = m_dma.dest_current & m_dma.dest_mask;
UINT16 src_addr = m_dma.source_current & m_dma.source_mask;
UINT16 dest_addr = m_dma.dest_current & m_dma.dest_mask;
UINT8 dest_adj = (3 - (m_dma.dest_x_current & 3)) << 1;
UINT8 src_adj = (3 - (m_dma.source_x_current & 3)) << 1;
/* handle DMA for 1 pixel */
/* Read pixel data */
switch ( m_dma.source_x_current & 0x03 )
{
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;
}
// Get new pixel
UINT8 source_pixel = (m_dma.source_bank[src_addr] >> src_adj) & 3;
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 )
{
case 0x00: dest_pixel = m_dma.dest_bank[dest_addr] >> 6; break;
case 0x01: dest_pixel = ( m_dma.dest_bank[dest_addr] >> 4 ) & 3; break;
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;
// Get 4 pixels and remove the one about to be replaced
UINT8 other_pixels = m_dma.dest_bank[dest_addr] & ~(3 << dest_adj);
// Get palette of new pixel and place into the hole
m_dma.dest_bank[dest_addr] = other_pixels | (m_dma.palette[ source_pixel ] << dest_adj);
}
/* Advance a pixel */
@ -588,17 +549,16 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
WRITE8_MEMBER( gamecom_state::gamecom_update_timers )
{
UINT8 * RAM = m_region_maincpu->base();
if ( m_timer[0].enabled )
{
m_timer[0].state_count += data;
while ( m_timer[0].state_count >= m_timer[0].state_limit )
{
m_timer[0].state_count -= m_timer[0].state_limit;
RAM[SM8521_TM0D]++;
if ( RAM[SM8521_TM0D] >= m_timer[0].check_value )
m_p_ram[SM8521_TM0D]++;
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 );
}
}
@ -609,10 +569,10 @@ WRITE8_MEMBER( gamecom_state::gamecom_update_timers )
while ( m_timer[1].state_count >= m_timer[1].state_limit )
{
m_timer[1].state_count -= m_timer[1].state_limit;
RAM[SM8521_TM1D]++;
if ( RAM[SM8521_TM1D] >= m_timer[1].check_value )
m_p_ram[SM8521_TM1D]++;
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 );
}
}

View File

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