gamecom : fixed some minor gfx issues in arcadecl and cart startup; fixed unlimited overdraft in monopoly

This commit is contained in:
Robbbert 2018-10-12 02:05:35 +11:00
parent 6c6732e8cf
commit a05c12da09
6 changed files with 130 additions and 138 deletions

View File

@ -272,7 +272,6 @@ void sm8500_cpu_device::process_interrupts()
m_IR0 = m_program->read_byte(0x12); m_IR0 = m_program->read_byte(0x12);
m_IR1 = m_program->read_byte(0x13); m_IR1 = m_program->read_byte(0x13);
m_PS0 = m_program->read_byte(0x1e); m_PS0 = m_program->read_byte(0x1e);
m_PS1 = m_program->read_byte(0x1f);
switch( irqline ) switch( irqline )
{ {
case WDT_INT: case WDT_INT:
@ -284,56 +283,56 @@ void sm8500_cpu_device::process_interrupts()
break; break;
case DMA_INT: case DMA_INT:
m_IR0 |= 0x80; m_IR0 |= 0x80;
if ( ( m_IE0 & 0x80 ) && ( ( m_PS0 & 0x07 ) < 8 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE0, 7) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x1000 ); take_interrupt( 0x1000 );
} }
break; break;
case TIM0_INT: case TIM0_INT:
m_IR0 |= 0x40; m_IR0 |= 0x40;
if ( ( m_IE0 & 0x40 ) && ( ( m_PS0 & 0x07 ) < 8 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE0, 6) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x1002 ); take_interrupt( 0x1002 );
} }
break; break;
case EXT_INT: case EXT_INT:
m_IR0 |= 0x10; m_IR0 |= 0x10;
if ( ( m_IE0 & 0x10 ) && ( ( m_PS0 & 0x07 ) < 7 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE0, 4) && ( ( m_PS0 & 0x07 ) < 7 ) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x1006 ); take_interrupt( 0x1006 );
} }
break; break;
case UART_INT: case UART_INT:
m_IR0 |= 0x08; m_IR0 |= 0x08;
if ( ( m_IE0 & 0x08 ) && ( ( m_PS0 & 0x07 ) < 6 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE0, 3) && ( ( m_PS0 & 0x07 ) < 6 ) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x1008 ); take_interrupt( 0x1008 );
} }
break; break;
case LCDC_INT: case LCDC_INT:
m_IR0 |= 0x01; m_IR0 |= 0x01;
if ( ( m_IE0 & 0x01 ) && ( ( m_PS0 & 0x07 ) < 5 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE0, 0) && ( ( m_PS0 & 0x07 ) < 5 ) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x100E ); take_interrupt( 0x100E );
} }
break; break;
case TIM1_INT: case TIM1_INT:
m_IR1 |= 0x40; m_IR1 |= 0x40;
if ( ( m_IE1 & 0x40 ) && ( ( m_PS0 & 0x07 ) < 4 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE1, 6) && ( ( m_PS0 & 0x07 ) < 4 ) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x1012 ); take_interrupt( 0x1012 );
} }
break; break;
case CK_INT: case CK_INT:
m_IR1 |= 0x10; m_IR1 |= 0x10;
if ( ( m_IE1 & 0x10 ) && ( ( m_PS0 & 0x07 ) < 3 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE1, 4) && ( ( m_PS0 & 0x07 ) < 3 ) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x1016 ); take_interrupt( 0x1016 );
} }
break; break;
case PIO_INT: case PIO_INT:
m_IR1 |= 0x04; m_IR1 |= 0x04;
if ( ( m_IE1 & 0x04 ) && ( ( m_PS0 & 0x07 ) < 2 ) && ( m_PS1 & 0x01 ) ) if ( BIT( m_IE1, 2) && ( ( m_PS0 & 0x07 ) < 2 ) && BIT( m_PS1, 0) )
{ {
take_interrupt( 0x101A ); take_interrupt( 0x101A );
} }

View File

@ -356,7 +356,7 @@
#define OP_INC16(X) d1 = X; \ #define OP_INC16(X) d1 = X; \
res = d1 + 1; \ res = d1 + 1; \
m_PS1 = m_PS1 & ( FLAG_C | FLAG_D | FLAG_H | FLAG_B | FLAG_I ); \ m_PS1 = m_PS1 & ( FLAG_C | FLAG_D | FLAG_H | FLAG_B | FLAG_I ); \
m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \ m_PS1 = m_PS1 | ( ( ( res & 0xFFFF ) == 0 ) ? FLAG_Z : 0 ); \
m_PS1 = m_PS1 | ( ( res & 0x8000 ) ? FLAG_S : 0 ); \ m_PS1 = m_PS1 | ( ( res & 0x8000 ) ? FLAG_S : 0 ); \
m_PS1 = m_PS1 | ( ( ( ( d1 ^ res ) & 0x8000 ) && ! ( res & 0x8000 ) ) ? FLAG_V : 0 ); m_PS1 = m_PS1 | ( ( ( ( d1 ^ res ) & 0x8000 ) && ! ( res & 0x8000 ) ) ? FLAG_V : 0 );
@ -377,7 +377,7 @@
#define OP_AND8(X,Y) d1 = X; \ #define OP_AND8(X,Y) d1 = X; \
d2 = Y; \ d2 = Y; \
res = d1 & d2; \ res = d1 & d2; \
m_PS1 = m_PS1 & ( FLAG_B | FLAG_I | FLAG_H | FLAG_D ); \ m_PS1 = m_PS1 & ( FLAG_B | FLAG_C | FLAG_I | FLAG_H | FLAG_D ); \
m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \ m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \
m_PS1 = m_PS1 | ( ( res & 0x80 ) ? FLAG_S : 0 ); m_PS1 = m_PS1 | ( ( res & 0x80 ) ? FLAG_S : 0 );
@ -390,7 +390,7 @@
#define OP_OR8(X,Y) d1 = X; \ #define OP_OR8(X,Y) d1 = X; \
d2 = Y; \ d2 = Y; \
res = d1 | d2; \ res = d1 | d2; \
m_PS1 = m_PS1 & ( FLAG_B | FLAG_I | FLAG_H | FLAG_D ); \ m_PS1 = m_PS1 & ( FLAG_B | FLAG_C | FLAG_I | FLAG_H | FLAG_D ); \
m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \ m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \
m_PS1 = m_PS1 | ( ( res & 0x80 ) ? FLAG_S : 0 ); m_PS1 = m_PS1 | ( ( res & 0x80 ) ? FLAG_S : 0 );
@ -403,7 +403,7 @@
#define OP_XOR8(X,Y) d1 = X; \ #define OP_XOR8(X,Y) d1 = X; \
d2 = Y; \ d2 = Y; \
res = d1 ^ d2; \ res = d1 ^ d2; \
m_PS1 = m_PS1 & ( FLAG_B | FLAG_I | FLAG_H | FLAG_D ); \ m_PS1 = m_PS1 & ( FLAG_B | FLAG_C | FLAG_I | FLAG_H | FLAG_D ); \
m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \ m_PS1 = m_PS1 | ( ( ( res & 0xFF ) == 0 ) ? FLAG_Z : 0 ); \
m_PS1 = m_PS1 | ( ( res & 0x80 ) ? FLAG_S : 0 ); m_PS1 = m_PS1 | ( ( res & 0x80 ) ? FLAG_S : 0 );
@ -1302,7 +1302,7 @@ case 0x5B: /* unk5B - 6,7,11,8,7 cycles */
case 0x5C: /* DIV RRr,RRs - 47 cycles - Flags affected: -Z-V---- */ case 0x5C: /* DIV RRr,RRs - 47 cycles - Flags affected: -Z-V---- */
/* lower 8 bits of RRs is used to divide */ /* lower 8 bits of RRs is used to divide */
/* remainder in stored upper 8 bits of RRs */ /* remainder in stored upper 8 bits of RRs */
logerror( "%04X: DIV RRr,Rs!\n", m_PC-1 ); // logerror( "%04X: DIV RRr,Rs!\n", m_PC-1 );
ARG_RR; ARG_RR;
m_PS1 = m_PS1 & ~ ( FLAG_Z | FLAG_V ); m_PS1 = m_PS1 & ~ ( FLAG_Z | FLAG_V );
s1 = mem_readbyte( r2 + 1 ); s1 = mem_readbyte( r2 + 1 );
@ -1318,7 +1318,7 @@ logerror( "%04X: DIV RRr,Rs!\n", m_PC-1 );
mycycles += 47; mycycles += 47;
break; break;
case 0x5D: /* DIV RRr,i - 44 cycles - Flags affected: -Z-V---- */ case 0x5D: /* DIV RRr,i - 44 cycles - Flags affected: -Z-V---- */
logerror( "%04X: DIV RRr,i!\n", m_PC-1 ); // logerror( "%04X: DIV RRr,i!\n", m_PC-1 );
ARG_iR; ARG_iR;
m_PS1 = m_PS1 & ~ ( FLAG_Z | FLAG_V ); m_PS1 = m_PS1 & ~ ( FLAG_Z | FLAG_V );
if ( r2 ) { if ( r2 ) {

View File

@ -14,11 +14,16 @@ Todo:
Game Status: Game Status:
- Inbuilt ROM and PDA functions all work - Inbuilt ROM and PDA functions all work
- On the screen where the cart goes into the slot, there are vertical bands of randomness
- 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
- All carts appear to work except: - All carts appear to work except:
- - Henry: crash just after "HENRY" button clicked - - Henry: misbehaviour just after "HENRY" button clicked.
- - Lost World: freeze just after entering Stage 2 (the nest) - --- You can still click where the invisible HENRY button is, and have one
turn. After that, it's game over, and you can't play any more until
you cold boot the emulation.
- - Lost World: freeze just after entering Stage 2 (the nest).
- --- If you do nothing it freezes at the point where the stegasaurus
should turn around. So, straight away start moving to the right
and you can keep playing.
- Weblink and Internet are of no use as there is nothing to connect to. - Weblink and Internet are of no use as there is nothing to connect to.
***************************************************************************/ ***************************************************************************/
@ -71,6 +76,7 @@ static INPUT_PORTS_START( gamecom )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME( "Button D" ) PORT_CODE( KEYCODE_D ) PORT_CODE( KEYCODE_LSHIFT ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME( "Button D" ) PORT_CODE( KEYCODE_D ) PORT_CODE( KEYCODE_LSHIFT )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME( "Stylus press" ) PORT_CODE( KEYCODE_Z ) PORT_CODE( MOUSECODE_BUTTON1 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME( "Stylus press" ) PORT_CODE( KEYCODE_Z ) PORT_CODE( MOUSECODE_BUTTON1 )
// These are used by the "Default Grid" artwork to detect mouse clicks
PORT_START("GRID.0") PORT_START("GRID.0")
PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_OTHER) PORT_BIT( 0x001, IP_ACTIVE_HIGH, IPT_OTHER)
PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_OTHER) PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_OTHER)

View File

@ -155,43 +155,39 @@ enum
struct GAMECOM_DMA struct GAMECOM_DMA
{ {
int enabled; u8 width_x;
int transfer_mode; u8 width_y;
int decrement_y; u8 source_x;
int decrement_x; u8 source_x_current;
int overwrite_mode; u8 source_y;
int width_x; u8 source_width;
int width_y; u8 dest_x;
int width_x_count; u8 dest_x_current;
int width_y_count; u8 dest_y;
int source_x; u8 dest_width;
int source_x_current; u8 palette;
int source_y; u8 block_width;
int source_width; u8 block_height;
int dest_x; u8 *source_bank;
int dest_x_current; u16 source_current;
int dest_y; u16 source_line;
int dest_width; u16 source_mask;
int state_count; u8 *dest_bank;
int state_pixel; u16 dest_current;
int state_limit; u16 dest_line;
uint8_t palette[4]; u16 dest_mask;
uint8_t *source_bank; u8 transfer_mode;
unsigned int source_current; s16 adjust_x;
unsigned int source_line; bool decrement_y;
unsigned int source_mask; bool overwrite_mode;
uint8_t *dest_bank;
unsigned int dest_current;
unsigned int dest_line;
unsigned int dest_mask;
}; };
struct GAMECOM_TIMER struct GAMECOM_TIMER
{ {
int enabled; bool enabled;
int state_count; u32 prescale_count;
int state_limit; u32 prescale_max;
int check_value; u8 upcounter_max;
}; };
struct gamecom_sound_t struct gamecom_sound_t

View File

@ -232,10 +232,6 @@ READ8_MEMBER( gamecom_state::gamecom_pio_r )
READ8_MEMBER( gamecom_state::gamecom_internal_r ) READ8_MEMBER( gamecom_state::gamecom_internal_r )
{ {
// ToDo: Read from vblank bit
// if(SM8521_LCV == offset + 0x20)
// popmessage("Read from vblank bit, TODO");
return m_p_ram[offset + 0x20]; return m_p_ram[offset + 0x20];
} }
@ -295,21 +291,23 @@ WRITE8_MEMBER( gamecom_state::gamecom_internal_w )
data &= 0x7f; data &= 0x7f;
break; break;
case SM8521_TM0D: case SM8521_TM0D:
m_timer[0].check_value = data; m_timer[0].upcounter_max = data;
return; data = 0;
break;
case SM8521_TM0C: case SM8521_TM0C:
m_timer[0].enabled = data & 0x80; m_timer[0].enabled = BIT(data, 7);
m_timer[0].state_limit = gamecom_timer_limit[data & 0x07] >> 1; m_timer[0].prescale_max = gamecom_timer_limit[data & 0x07] >> 1;
m_timer[0].state_count = 0; m_timer[0].prescale_count = 0;
m_p_ram[SM8521_TM0D] = 0; m_p_ram[SM8521_TM0D] = 0;
break; break;
case SM8521_TM1D: case SM8521_TM1D:
m_timer[1].check_value = data; m_timer[1].upcounter_max = data;
return; data = 0;
break;
case SM8521_TM1C: case SM8521_TM1C:
m_timer[1].enabled = data & 0x80; m_timer[1].enabled = BIT(data, 7);
m_timer[1].state_limit = gamecom_timer_limit[data & 0x07] >> 1; m_timer[1].prescale_max = gamecom_timer_limit[data & 0x07] >> 1;
m_timer[1].state_count = 0; m_timer[1].prescale_count = 0;
m_p_ram[SM8521_TM1D] = 0; m_p_ram[SM8521_TM1D] = 0;
break; break;
case SM8521_CLKT: /* bit 6-7 */ case SM8521_CLKT: /* bit 6-7 */
@ -319,7 +317,7 @@ WRITE8_MEMBER( gamecom_state::gamecom_internal_w )
if ( data & 0x40 ) if ( data & 0x40 )
{ {
/* timer resolution 1 minute */ /* timer resolution 1 minute */
m_clock_timer->adjust(attotime::from_seconds(1), 0, attotime::from_seconds(60)); m_clock_timer->adjust(attotime::from_seconds(60), 0, attotime::from_seconds(60));
} }
else else
{ {
@ -457,46 +455,40 @@ 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.
Also, there's nothing about what happens if the block overflows the source or destination. */
WRITE8_MEMBER( gamecom_state::gamecom_handle_dma ) WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
{ {
uint8_t dmc = m_p_ram[SM8521_DMC]; u8 dmc = m_p_ram[SM8521_DMC];
m_dma.overwrite_mode = dmc & 0x01; if (!BIT(dmc, 7))
m_dma.transfer_mode = dmc & 0x06;
m_dma.decrement_x = dmc & 0x08;
m_dma.decrement_y = dmc & 0x10;
m_dma.enabled = dmc & 0x80;
if ( !m_dma.enabled )
{
return; return;
}
m_dma.width_x = m_p_ram[SM8521_DMDX]; m_dma.overwrite_mode = BIT(dmc, 0);
m_dma.width_x_count = 0; m_dma.transfer_mode = dmc & 0x06;
m_dma.width_y = m_p_ram[SM8521_DMDY]; m_dma.adjust_x = BIT(dmc, 3) ? -1 : 1;
m_dma.width_y_count = 0; m_dma.decrement_y = BIT(dmc, 4);
m_dma.block_width = m_p_ram[SM8521_DMDX];
m_dma.block_height = m_p_ram[SM8521_DMDY];
m_dma.source_x = m_p_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 & 3;
m_dma.source_y = m_p_ram[SM8521_DMY1]; m_dma.source_y = m_p_ram[SM8521_DMY1];
m_dma.source_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40; m_dma.source_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40;
m_dma.dest_width = m_dma.source_width;
m_dma.dest_x = m_p_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 & 3;
m_dma.dest_y = m_p_ram[SM8521_DMY2]; m_dma.dest_y = m_p_ram[SM8521_DMY2];
m_dma.dest_width = ( m_p_ram[SM8521_LCH] & 0x20 ) ? 50 : 40; m_dma.palette = m_p_ram[SM8521_DMPL];
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.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, m_p_ram[SM8521_DMVP] ); m_dma.source_bank = &m_p_videoram[BIT(m_p_ram[SM8521_DMVP], 0) ? 0x2000 : 0x0000];
m_dma.dest_bank = &m_p_videoram[BIT(m_p_ram[SM8521_DMVP], 1) ? 0x2000 : 0x0000];
// logerror("DMA: width %Xx%X, source (%X,%X), dest (%X,%X), transfer_mode %X, banks %X \n", block_width, block_height, m_dma.source_x, m_dma.source_y, m_dma.dest_x, m_dma.dest_y, 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[(m_p_ram[SM8521_DMVP] & 0x01) ? 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 */
@ -508,18 +500,14 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
else else
if (m_cart_ptr) if (m_cart_ptr)
m_dma.source_bank = m_cart_ptr + (m_p_ram[SM8521_DMBR] << 14); m_dma.source_bank = m_cart_ptr + (m_p_ram[SM8521_DMBR] << 14);
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[(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[(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;
@ -530,53 +518,51 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
m_dma.dest_current += m_dma.dest_x >> 2; m_dma.dest_current += m_dma.dest_x >> 2;
m_dma.source_line = m_dma.source_current; m_dma.source_line = m_dma.source_current;
m_dma.dest_line = m_dma.dest_current; m_dma.dest_line = m_dma.dest_current;
m_dma.state_count = 0;
unsigned y_count, x_count; for( u16 y_count = 0; y_count <= m_dma.block_height; y_count++ )
for( y_count = 0; y_count <= m_dma.width_y; y_count++ )
{ {
for( x_count = 0; x_count <= m_dma.width_x; x_count++ ) for( u16 x_count = 0; x_count <= m_dma.block_width; x_count++ )
{ {
uint16_t src_addr = m_dma.source_current & m_dma.source_mask; u16 src_addr = m_dma.source_current & m_dma.source_mask;
uint16_t dest_addr = m_dma.dest_current & m_dma.dest_mask; u16 dst_addr = m_dma.dest_current & m_dma.dest_mask;
uint8_t dest_adj = (3 - (m_dma.dest_x_current & 3)) << 1; u8 dst_adj = (m_dma.dest_x_current ^ 3) << 1;
uint8_t src_adj = (3 - (m_dma.source_x_current & 3)) << 1; u8 src_adj = (m_dma.source_x_current ^ 3) << 1;
/* handle DMA for 1 pixel */ /* handle DMA for 1 pixel */
// Get new pixel // Get new pixel
uint8_t source_pixel = (m_dma.source_bank[src_addr] >> src_adj) & 3; u8 source_pixel = (m_dma.source_bank[src_addr] >> src_adj) & 3;
// If overwrite mode, write new pixel // If overwrite mode, write new pixel
if ( m_dma.overwrite_mode || source_pixel) if ( m_dma.overwrite_mode || source_pixel)
{ {
// Get 4 pixels and remove the one about to be replaced // Get 4 pixels and remove the one about to be replaced
uint8_t other_pixels = m_dma.dest_bank[dest_addr] & ~(3 << dest_adj); u8 other_pixels = m_dma.dest_bank[dst_addr] & ~(3 << dst_adj);
// Get palette of new pixel and place into the hole // 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); if (m_dma.transfer_mode == 6 || m_dma.transfer_mode == 0)
m_dma.dest_bank[dst_addr] = other_pixels | (source_pixel << dst_adj);
else
m_dma.dest_bank[dst_addr] = other_pixels | (((m_dma.palette >> (source_pixel << 1)) & 3) << dst_adj);
} }
/* Advance a pixel */ /* Advance a pixel */
if ( m_dma.decrement_x ) m_dma.source_x_current += m_dma.adjust_x;
if (BIT(m_dma.source_x_current, 2))
{ {
m_dma.source_x_current--; m_dma.source_current += m_dma.adjust_x;
if ( ( m_dma.source_x_current & 0x03 ) == 0x03 ) m_dma.source_x_current &= 3;
m_dma.source_current--;
}
else
{
m_dma.source_x_current++;
if ( ( m_dma.source_x_current & 0x03 ) == 0x00 )
m_dma.source_current++;
} }
m_dma.dest_x_current++; m_dma.dest_x_current++;
if ( ( m_dma.dest_x_current & 0x03 ) == 0x00 ) if (BIT(m_dma.dest_x_current, 2))
{
m_dma.dest_current++; m_dma.dest_current++;
m_dma.dest_x_current &= 3;
}
} }
/* Advance a line */ /* Advance a line */
m_dma.source_x_current = m_dma.source_x; m_dma.source_x_current = m_dma.source_x & 3;
m_dma.dest_x_current = m_dma.dest_x; m_dma.dest_x_current = m_dma.dest_x & 3;
if ( m_dma.decrement_y ) if ( m_dma.decrement_y )
m_dma.source_line -= m_dma.source_width; m_dma.source_line -= m_dma.source_width;
else else
@ -585,7 +571,8 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma )
m_dma.dest_line += m_dma.dest_width; m_dma.dest_line += m_dma.dest_width;
m_dma.dest_current = m_dma.dest_line; m_dma.dest_current = m_dma.dest_line;
} }
m_dma.enabled = 0;
m_p_ram[SM8521_DMC] &= 0x7f; // finished; turn off dma
m_maincpu->set_input_line(sm8500_cpu_device::DMA_INT, ASSERT_LINE ); m_maincpu->set_input_line(sm8500_cpu_device::DMA_INT, ASSERT_LINE );
} }
@ -593,28 +580,32 @@ WRITE8_MEMBER( gamecom_state::gamecom_update_timers )
{ {
if ( m_timer[0].enabled ) if ( m_timer[0].enabled )
{ {
m_timer[0].state_count += data; m_timer[0].prescale_count += data;
while ( m_timer[0].state_count >= m_timer[0].state_limit ) while ( m_timer[0].prescale_count >= m_timer[0].prescale_max )
{ {
m_timer[0].state_count -= m_timer[0].state_limit; m_timer[0].prescale_count -= m_timer[0].prescale_max;
m_p_ram[SM8521_TM0D]++; m_p_ram[SM8521_TM0D]++;
if ( m_p_ram[SM8521_TM0D] >= m_timer[0].check_value ) if ( m_p_ram[SM8521_TM0D] >= m_timer[0].upcounter_max )
{ {
m_p_ram[SM8521_TM0D] = 0; m_p_ram[SM8521_TM0D] = 0;
// m_maincpu->set_input_line(sm8500_cpu_device::TIM0_INT, ASSERT_LINE ); // this causes crazy flickering // check if irq is enabled before calling,
// to stop monopoly choking up the interrupt queue
if (BIT(m_p_ram[SM8521_IE0], 6) && BIT(m_p_ram[SM8521_PS1], 0))
m_maincpu->set_input_line(sm8500_cpu_device::TIM0_INT, ASSERT_LINE );
} }
} }
} }
if ( m_timer[1].enabled ) if ( m_timer[1].enabled )
{ {
m_timer[1].state_count += data; m_timer[1].prescale_count += data;
while ( m_timer[1].state_count >= m_timer[1].state_limit ) while ( m_timer[1].prescale_count >= m_timer[1].prescale_max )
{ {
m_timer[1].state_count -= m_timer[1].state_limit; m_timer[1].prescale_count -= m_timer[1].prescale_max;
m_p_ram[SM8521_TM1D]++; m_p_ram[SM8521_TM1D]++;
if ( m_p_ram[SM8521_TM1D] >= m_timer[1].check_value ) if ( m_p_ram[SM8521_TM1D] >= m_timer[1].upcounter_max )
{ {
m_p_ram[SM8521_TM1D] = 0; m_p_ram[SM8521_TM1D] = 0;
if (BIT(m_p_ram[SM8521_IE1], 6) && BIT(m_p_ram[SM8521_PS1], 0) && ((m_p_ram[SM8521_PS0] & 7) < 4))
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

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