// license:BSD-3-Clause
// copyright-holders:Nicola Salmoria
/***************************************************************************
machine.c
Functions to emulate general aspects of the machine (RAM, ROM, interrupts,
I/O ports)
***************************************************************************/
#include "emu.h"
#include "sound/samples.h"
#include "includes/galaga.h"
#include "includes/xevious.h"
/***************************************************************************
BATTLES CPU4(custum I/O Emulation) I/O Handlers
***************************************************************************/
void xevious_state::battles_customio_init()
{
m_battles_customio_command = 0;
m_battles_customio_prev_command = 0;
m_battles_customio_command_count = 0;
m_battles_customio_data = 0;
m_battles_sound_played = 0;
}
TIMER_DEVICE_CALLBACK_MEMBER(xevious_state::battles_nmi_generate)
{
m_battles_customio_prev_command = m_battles_customio_command;
if( m_battles_customio_command & 0x10 )
{
if( m_battles_customio_command_count == 0 )
{
m_subcpu3->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
else
{
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_subcpu3->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
}
else
{
m_maincpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
m_subcpu3->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}
m_battles_customio_command_count++;
}
READ8_MEMBER( xevious_state::battles_customio0_r )
{
logerror("%s: custom I/O Read = %02x\n", machine().describe_context(), m_battles_customio_command);
return m_battles_customio_command;
}
READ8_MEMBER( xevious_state::battles_customio3_r )
{
int return_data;
if( m_subcpu3->pc() == 0xAE ){
/* CPU4 0xAA - 0xB9 : waiting for MB8851 ? */
return_data = ( (m_battles_customio_command & 0x10) << 3)
| 0x00
| (m_battles_customio_command & 0x0f);
}else{
return_data = ( (m_battles_customio_prev_command & 0x10) << 3)
| 0x60
| (m_battles_customio_prev_command & 0x0f);
}
logerror("%s: custom I/O Read = %02x\n", machine().describe_context(), return_data);
return return_data;
}
WRITE8_MEMBER( xevious_state::battles_customio0_w )
{
timer_device *timer = machine().device<timer_device>("battles_nmi");
logerror("%s: custom I/O Write = %02x\n", machine().describe_context(), data);
m_battles_customio_command = data;
m_battles_customio_command_count = 0;
switch (data)
{
case 0x10:
timer->reset();
return; /* nop */
}
timer->adjust(attotime::from_usec(166), 0, attotime::from_usec(166));
}
WRITE8_MEMBER( xevious_state::battles_customio3_w )
{
logerror("%s: custom I/O Write = %02x\n", machine().describe_context(), data);
m_battles_customio_command = data;
}
READ8_MEMBER( xevious_state::battles_customio_data0_r )
{
logerror("%s: custom I/O parameter %02x Read = %02x\n", machine().describe_context(), offset, m_battles_customio_data);
return m_battles_customio_data;
}
READ8_MEMBER( xevious_state::battles_customio_data3_r )
{
logerror("%s: custom I/O parameter %02x Read = %02x\n", machine().describe_context(), offset, m_battles_customio_data);
return m_battles_customio_data;
}
WRITE8_MEMBER( xevious_state::battles_customio_data0_w )
{
logerror("%s: custom I/O parameter %02x Write = %02x\n", machine().describe_context(), offset, data);
m_battles_customio_data = data;
}
WRITE8_MEMBER( xevious_state::battles_customio_data3_w )
{
logerror("%s: custom I/O parameter %02x Write = %02x\n", machine().describe_context(), offset, data);
m_battles_customio_data = data;
}
WRITE8_MEMBER( xevious_state::battles_CPU4_coin_w )
{
m_leds[0] = BIT(data, 1); // Start 1
m_leds[1] = BIT(data, 0); // Start 2
machine().bookkeeping().coin_counter_w(0,data & 0x20);
machine().bookkeeping().coin_counter_w(1,data & 0x10);
machine().bookkeeping().coin_lockout_global_w(~data & 0x04);
}
WRITE8_MEMBER( xevious_state::battles_noise_sound_w )
{
logerror("%s: 50%02x Write = %02x\n", machine().describe_context(), offset, data);
if( (m_battles_sound_played == 0) && (data == 0xFF) ){
if( m_customio[0] == 0x40 ){
m_samples->start(0, 0);
}
else{
m_samples->start(0, 1);
}
}
m_battles_sound_played = data;
}
READ8_MEMBER( xevious_state::battles_input_port_r )
{
switch ( offset )
{
default:
case 0: return ~bitswap<8>(ioport("IN0H")->read(),7,6,5,4,2,3,1,0);
case 1: return ~ioport("IN1L")->read();
case 2: return ~ioport("IN1H")->read();
case 3: return ~ioport("IN0L")->read();
}
}
WRITE_LINE_MEMBER(xevious_state::battles_interrupt_4)
{
if (state)
m_subcpu3->set_input_line(0, HOLD_LINE);
}