From a05c12da091697d33c660f0c7103d05290f425b3 Mon Sep 17 00:00:00 2001 From: Robbbert Date: Fri, 12 Oct 2018 02:05:35 +1100 Subject: [PATCH] gamecom : fixed some minor gfx issues in arcadecl and cart startup; fixed unlimited overdraft in monopoly --- src/devices/cpu/sm8500/sm8500.cpp | 17 ++-- src/devices/cpu/sm8500/sm85ops.h | 26 +++--- src/mame/drivers/gamecom.cpp | 12 ++- src/mame/includes/gamecom.h | 62 ++++++------- src/mame/machine/gamecom.cpp | 149 ++++++++++++++---------------- src/mame/video/gamecom.cpp | 2 +- 6 files changed, 130 insertions(+), 138 deletions(-) diff --git a/src/devices/cpu/sm8500/sm8500.cpp b/src/devices/cpu/sm8500/sm8500.cpp index 483cd29707b..9196dc77ac9 100644 --- a/src/devices/cpu/sm8500/sm8500.cpp +++ b/src/devices/cpu/sm8500/sm8500.cpp @@ -272,7 +272,6 @@ void sm8500_cpu_device::process_interrupts() m_IR0 = m_program->read_byte(0x12); m_IR1 = m_program->read_byte(0x13); m_PS0 = m_program->read_byte(0x1e); - m_PS1 = m_program->read_byte(0x1f); switch( irqline ) { case WDT_INT: @@ -284,56 +283,56 @@ void sm8500_cpu_device::process_interrupts() break; case DMA_INT: 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 ); } break; case TIM0_INT: 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 ); } break; case EXT_INT: 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 ); } break; case UART_INT: 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 ); } break; case LCDC_INT: 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 ); } break; case TIM1_INT: 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 ); } break; case CK_INT: 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 ); } break; case PIO_INT: 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 ); } diff --git a/src/devices/cpu/sm8500/sm85ops.h b/src/devices/cpu/sm8500/sm85ops.h index 2e3d0cdcbfb..7b934837bd6 100644 --- a/src/devices/cpu/sm8500/sm85ops.h +++ b/src/devices/cpu/sm8500/sm85ops.h @@ -356,7 +356,7 @@ #define OP_INC16(X) d1 = X; \ res = d1 + 1; \ 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 | ( ( ( ( d1 ^ res ) & 0x8000 ) && ! ( res & 0x8000 ) ) ? FLAG_V : 0 ); @@ -377,7 +377,7 @@ #define OP_AND8(X,Y) d1 = X; \ d2 = Y; \ 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 & 0x80 ) ? FLAG_S : 0 ); @@ -390,7 +390,7 @@ #define OP_OR8(X,Y) d1 = X; \ d2 = Y; \ 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 & 0x80 ) ? FLAG_S : 0 ); @@ -403,7 +403,7 @@ #define OP_XOR8(X,Y) d1 = X; \ d2 = Y; \ 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 & 0x80 ) ? FLAG_S : 0 ); @@ -501,7 +501,7 @@ case 0x00: /* CLR R - 4 cycles - Flags affected: -------- */ ARG_R; mem_writebyte( r1, 0 ); - mycycles += 4; + mycycles += 4; break; case 0x01: /* NEG R - 5 cycles - Flags affected: CZSV---- */ ARG_R; @@ -909,7 +909,7 @@ logerror( "%04X: unk%02x\n", m_PC-1,op ); case 0x2E: /* MOV PS0,#00 - 4 cycles - Flags affected: -------- */ ARG_R; m_PS0 = r1; - mycycles += 4; + mycycles += 4; break; case 0x2F: /* BTST R,i - 6 cycles - Flags affected: -Z-0---- */ ARG_RR; @@ -1144,7 +1144,7 @@ case 0x4A: /* MOVW RRr,RRs - 8 cycles - Flags affected: -------- */ case 0x4B: /* MOVW RRr,ww - 9 cycles - Flags affected: -------- */ ARG_Sw; mem_writeword( r1, s2 ); - mycycles += 9; + mycycles += 9; break; case 0x4C: /* MULT Rrr,Rs - 24 cycles - Flags affected: -Z-0---- */ // operation is not known if r1 is odd, assuming same as even for now @@ -1268,7 +1268,7 @@ case 0x57: /* XOR Rr,i - 6 cycles - Flags affected: -ZS0---- */ case 0x58: /* MOV Rr,i - 6 cycles - Flags affected: -------- */ ARG_iR; mem_writebyte( r1, r2 ); - mycycles += 6; + mycycles += 6; break; case 0x59: /* Invalid - 2? cycles - Flags affected: --------? */ logerror( "%04X: 59h: Invalid instruction\n", m_PC-1 ); @@ -1302,7 +1302,7 @@ case 0x5B: /* unk5B - 6,7,11,8,7 cycles */ case 0x5C: /* DIV RRr,RRs - 47 cycles - Flags affected: -Z-V---- */ /* lower 8 bits of RRs is used to divide */ /* 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; m_PS1 = m_PS1 & ~ ( FLAG_Z | FLAG_V ); s1 = mem_readbyte( r2 + 1 ); @@ -1318,7 +1318,7 @@ logerror( "%04X: DIV RRr,Rs!\n", m_PC-1 ); mycycles += 47; break; 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; m_PS1 = m_PS1 & ~ ( FLAG_Z | FLAG_V ); if ( r2 ) { @@ -1578,7 +1578,7 @@ case 0xC6: case 0xC7: ARG_ri; mem_writebyte( r1, r2 ); - mycycles += 4; + mycycles += 4; break; case 0xC8: /* MOV IE0/IE1/IR0/IR1/P0/P1/P2/P3,i - 4 cycles - Flags affected: -------- */ case 0xC9: @@ -1687,11 +1687,11 @@ case 0xFC: /* SETC - 2 cycles - Flags affected: C------- */ break; case 0xFD: /* EI - 2 cycles - Flags affected: -------I */ m_PS1 = m_PS1 | FLAG_I; - mycycles += 2; + mycycles += 2; break; case 0xFE: /* DI - 2 cycles - Flags affected: -------I */ m_PS1 = m_PS1 & ~ ( FLAG_I ); - mycycles += 2; + mycycles += 2; break; case 0xFF: /* NOP - 2 cycles - Flags affected: -------- */ mycycles += 2; diff --git a/src/mame/drivers/gamecom.cpp b/src/mame/drivers/gamecom.cpp index bb7e765deca..afc4175eec9 100644 --- a/src/mame/drivers/gamecom.cpp +++ b/src/mame/drivers/gamecom.cpp @@ -14,11 +14,16 @@ Todo: Game Status: - 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 - All carts appear to work except: -- - Henry: crash just after "HENRY" button clicked -- - Lost World: freeze just after entering Stage 2 (the nest) +- - Henry: misbehaviour just after "HENRY" button clicked. +- --- 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. ***************************************************************************/ @@ -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( 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_BIT( 0x001, IP_ACTIVE_HIGH, IPT_OTHER) PORT_BIT( 0x002, IP_ACTIVE_HIGH, IPT_OTHER) diff --git a/src/mame/includes/gamecom.h b/src/mame/includes/gamecom.h index fb3638cfdbe..75db40ddb68 100644 --- a/src/mame/includes/gamecom.h +++ b/src/mame/includes/gamecom.h @@ -155,43 +155,39 @@ enum struct GAMECOM_DMA { - int enabled; - int transfer_mode; - int decrement_y; - int decrement_x; - int overwrite_mode; - int width_x; - int width_y; - int width_x_count; - int width_y_count; - int source_x; - int source_x_current; - int source_y; - int source_width; - int dest_x; - int dest_x_current; - int dest_y; - int dest_width; - int state_count; - int state_pixel; - int state_limit; - uint8_t palette[4]; - uint8_t *source_bank; - unsigned int source_current; - unsigned int source_line; - unsigned int source_mask; - uint8_t *dest_bank; - unsigned int dest_current; - unsigned int dest_line; - unsigned int dest_mask; + u8 width_x; + u8 width_y; + u8 source_x; + u8 source_x_current; + u8 source_y; + u8 source_width; + u8 dest_x; + u8 dest_x_current; + u8 dest_y; + u8 dest_width; + u8 palette; + u8 block_width; + u8 block_height; + u8 *source_bank; + u16 source_current; + u16 source_line; + u16 source_mask; + u8 *dest_bank; + u16 dest_current; + u16 dest_line; + u16 dest_mask; + u8 transfer_mode; + s16 adjust_x; + bool decrement_y; + bool overwrite_mode; }; struct GAMECOM_TIMER { - int enabled; - int state_count; - int state_limit; - int check_value; + bool enabled; + u32 prescale_count; + u32 prescale_max; + u8 upcounter_max; }; struct gamecom_sound_t diff --git a/src/mame/machine/gamecom.cpp b/src/mame/machine/gamecom.cpp index b68480574a6..231227c3a19 100644 --- a/src/mame/machine/gamecom.cpp +++ b/src/mame/machine/gamecom.cpp @@ -232,10 +232,6 @@ READ8_MEMBER( gamecom_state::gamecom_pio_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]; } @@ -295,21 +291,23 @@ WRITE8_MEMBER( gamecom_state::gamecom_internal_w ) data &= 0x7f; break; case SM8521_TM0D: - m_timer[0].check_value = data; - return; + m_timer[0].upcounter_max = data; + data = 0; + break; case SM8521_TM0C: - m_timer[0].enabled = data & 0x80; - m_timer[0].state_limit = gamecom_timer_limit[data & 0x07] >> 1; - m_timer[0].state_count = 0; + m_timer[0].enabled = BIT(data, 7); + m_timer[0].prescale_max = gamecom_timer_limit[data & 0x07] >> 1; + m_timer[0].prescale_count = 0; m_p_ram[SM8521_TM0D] = 0; break; case SM8521_TM1D: - m_timer[1].check_value = data; - return; + m_timer[1].upcounter_max = data; + data = 0; + break; case SM8521_TM1C: - m_timer[1].enabled = data & 0x80; - m_timer[1].state_limit = gamecom_timer_limit[data & 0x07] >> 1; - m_timer[1].state_count = 0; + m_timer[1].enabled = BIT(data, 7); + m_timer[1].prescale_max = gamecom_timer_limit[data & 0x07] >> 1; + m_timer[1].prescale_count = 0; m_p_ram[SM8521_TM1D] = 0; break; case SM8521_CLKT: /* bit 6-7 */ @@ -319,7 +317,7 @@ WRITE8_MEMBER( gamecom_state::gamecom_internal_w ) if ( data & 0x40 ) { /* 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 { @@ -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 - 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 ) { - uint8_t dmc = m_p_ram[SM8521_DMC]; - m_dma.overwrite_mode = dmc & 0x01; - 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 ) - { + u8 dmc = m_p_ram[SM8521_DMC]; + if (!BIT(dmc, 7)) return; - } - m_dma.width_x = m_p_ram[SM8521_DMDX]; - m_dma.width_x_count = 0; - m_dma.width_y = m_p_ram[SM8521_DMDY]; - m_dma.width_y_count = 0; + m_dma.overwrite_mode = BIT(dmc, 0); + m_dma.transfer_mode = dmc & 0x06; + m_dma.adjust_x = BIT(dmc, 3) ? -1 : 1; + 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_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_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_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_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.palette = m_p_ram[SM8521_DMPL]; 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, 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] ); switch( m_dma.transfer_mode ) { case 0x00: /* 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; case 0x02: /* ROM->VRAM */ @@ -508,18 +500,14 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma ) else if (m_cart_ptr) 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; 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[(m_p_ram[SM8521_DMVP] & 0x02) ? 0x2000 : 0x0000]; break; case 0x06: /* 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_bank = &m_p_nvram[0x0000]; break; @@ -530,53 +518,51 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma ) m_dma.dest_current += m_dma.dest_x >> 2; m_dma.source_line = m_dma.source_current; m_dma.dest_line = m_dma.dest_current; - m_dma.state_count = 0; - unsigned y_count, x_count; - - for( y_count = 0; y_count <= m_dma.width_y; y_count++ ) + for( u16 y_count = 0; y_count <= m_dma.block_height; 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; - uint16_t dest_addr = m_dma.dest_current & m_dma.dest_mask; - uint8_t dest_adj = (3 - (m_dma.dest_x_current & 3)) << 1; - uint8_t src_adj = (3 - (m_dma.source_x_current & 3)) << 1; + u16 src_addr = m_dma.source_current & m_dma.source_mask; + u16 dst_addr = m_dma.dest_current & m_dma.dest_mask; + u8 dst_adj = (m_dma.dest_x_current ^ 3) << 1; + u8 src_adj = (m_dma.source_x_current ^ 3) << 1; /* handle DMA for 1 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 ( m_dma.overwrite_mode || source_pixel) { // 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 - 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 */ - 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--; - if ( ( m_dma.source_x_current & 0x03 ) == 0x03 ) - m_dma.source_current--; - } - else - { - m_dma.source_x_current++; - if ( ( m_dma.source_x_current & 0x03 ) == 0x00 ) - m_dma.source_current++; + m_dma.source_current += m_dma.adjust_x; + m_dma.source_x_current &= 3; } + 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_x_current &= 3; + } } /* Advance a line */ - m_dma.source_x_current = m_dma.source_x; - m_dma.dest_x_current = m_dma.dest_x; + m_dma.source_x_current = m_dma.source_x & 3; + m_dma.dest_x_current = m_dma.dest_x & 3; if ( m_dma.decrement_y ) m_dma.source_line -= m_dma.source_width; else @@ -585,7 +571,8 @@ WRITE8_MEMBER( gamecom_state::gamecom_handle_dma ) m_dma.dest_line += m_dma.dest_width; 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 ); } @@ -593,29 +580,33 @@ WRITE8_MEMBER( gamecom_state::gamecom_update_timers ) { 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].prescale_count += data; + 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]++; - 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_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 ) { - m_timer[1].state_count += data; - while ( m_timer[1].state_count >= m_timer[1].state_limit ) + m_timer[1].prescale_count += data; + 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]++; - 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_maincpu->set_input_line(sm8500_cpu_device::TIM1_INT, ASSERT_LINE ); + 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 ); } } } diff --git a/src/mame/video/gamecom.cpp b/src/mame/video/gamecom.cpp index f8f2967588d..ea987a07adc 100644 --- a/src/mame/video/gamecom.cpp +++ b/src/mame/video/gamecom.cpp @@ -11,7 +11,7 @@ TIMER_CALLBACK_MEMBER(gamecom_state::gamecom_scanline) - { +{ // draw line m_base_address = ( m_p_ram[SM8521_LCDC] & 0x40 ) ? 0x2000 : 0x0000;