/***************************************************************************

  Namco ND-1

  machine.c

  Functions to emulate general aspects of the machine
  (RAM, ROM, interrupts, I/O ports)

***************************************************************************/

#include "driver.h"
#include "cpu/m6809/m6809.h"
#include "namcond1.h"

/* Perform basic machine initialisation */

static UINT8 namcond1_h8_irq5_enabled;
static UINT8 coin_state;
static UINT8 coin_count[4];

MACHINE_INIT( namcond1 )
{
#ifdef MAME_DEBUG
    /*unsigned char   *ROM = memory_region(REGION_CPU1);*/
    /*unsigned int debug_trigger_addr;*/
    /*int             i;*/

#if 0
    // debug trigger patch
    // insert a "move.b $B0000000,D2" into the code
    debug_trigger_addr = 0x152d4; // after ygv_init
    ROM[debug_trigger_addr++] = 0x39;
    ROM[debug_trigger_addr++] = 0x14;
    ROM[debug_trigger_addr++] = 0xB0;
    ROM[debug_trigger_addr++] = 0x00;
    ROM[debug_trigger_addr++] = 0x00;
    ROM[debug_trigger_addr++] = 0x00;
#endif
#endif

    // initialise MCU states
    namcond1_h8_irq5_enabled = 0;
    coin_state = 0;
    coin_count[0] = coin_count[1] =
    coin_count[2] = coin_count[3] = 0;
}

// instance of the shared ram pointer
data16_t *namcond1_shared_ram;

READ16_HANDLER( namcond1_shared_ram_r )
{
    static UINT8 plyr1 = 0, plyr2 = 0;

    data16_t data;
	UINT8 poll_coins;
    UINT8   current, pressed;

    // the H8 IRQ5 does polling of inputs and writes to shared RAM
    if( !namcond1_h8_irq5_enabled )
        return( namcond1_shared_ram[offset] );

    switch( offset )
    {
        case (0>>1) : // sub mailbox - sub busy
            data = 0;    // sub not busy
            break;

        case (2>>1) : // test switch
            // high bit is set/cleared by MCU
            data = ( 1 << 15 ) | readinputport( 2 );
            break;

        case (4>>1) : // plyr1
            current = readinputport( 0 );
            pressed = plyr1 & ( plyr1 ^ current );
            plyr1 = current;
            data = ( ~current << 8 ) | pressed;
            break;

        case (6>>1) : // plyr2
            current = readinputport( 1 );
            pressed = plyr2 & ( plyr2 ^ current );
            plyr2 = current;
            data = ( ~current << 8 ) | pressed;
            break;

	    case (0x18>>1) : // coin #1
		    data = (coin_count[0]<<8) | coin_count[1];
            break;

        case (0x1a>>1) : // coin #2
		    data = (coin_count[2]<<8) | coin_count[3];
            break;

        case (0x51>>1) : // player 1 latched
            plyr1 = input_port_1_r( 0 );
            data = plyr1;
            break;

        case (0x52>>1) : // player 2 latched
            plyr2 = input_port_1_r( 0 );
            data =  plyr2 << 8;
            break;

        case (0x580>>1) : // sub-cpu signal
            data = 0;    // sub finished
            break;

        default :
            data = namcond1_shared_ram[offset];
            break;
    }

    // Is this the best place to so this? maybe not...
	poll_coins = readinputport( 3 );
	if( ( poll_coins & 0x8 ) & ~( coin_state & 0x8 ) ) coin_count[0]++;
	if( ( poll_coins & 0x4 ) & ~( coin_state & 0x4 ) ) coin_count[1]++;
	if( ( poll_coins & 0x2 ) & ~( coin_state & 0x2 ) ) coin_count[2]++;
	if( ( poll_coins & 0x1 ) & ~( coin_state & 0x1 ) ) coin_count[3]++;
	coin_state = poll_coins;

    return( data );
}

// $c3ff00-$c3ffff
READ16_HANDLER( namcond1_cuskey_r )
{
    switch( offset )
    {
        // this address returns a jump vector inside ISR2
        // - if zero then the ISR returns without jumping
        case (0x2e>>1):
            return( 0x0000 );
        case (0x30>>1):
            return( 0x0000 );

        default :
            logerror( "offset $%X accessed from $%X\n",
                      offset<<1, activecpu_get_pc() );
            return( 0 );
    }
}

WRITE16_HANDLER( namcond1_shared_ram_w )
{
    switch( offset )
    {
        default :
        #if 0
            if( namcond1_shared_ram[offset] == 0x0000 &&
                data == 0x0001 )
              logerror( "changing 0$->$1 to $%x @$%x\n",
                        offset<<1, activecpu_get_pc() );
        #endif
            COMBINE_DATA( namcond1_shared_ram + offset );
            break;
    }
}

WRITE16_HANDLER( namcond1_cuskey_w )
{
    switch( offset )
    {
        case (0x0a>>1):
            // this is a kludge until we emulate the h8
            namcond1_h8_irq5_enabled = ( data != 0x0000 );
            break;

        default :
            break;
    }
}

#define NAMCOND1_EEPROM_SIZE    0x200
data16_t *namcond1_eeprom;

/* not used at this point */
NVRAM_HANDLER( namcond1 )
{
  if( file == 0 )
    return;

  if( read_or_write == 0 ) {
    /* read eeprom contents */
    osd_fread( file, namcond1_eeprom, NAMCOND1_EEPROM_SIZE );
  }
  else {
    /* write eeprom contents */
    osd_fwrite( file, namcond1_eeprom, NAMCOND1_EEPROM_SIZE );
  }
}

