summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/stfight.cpp
blob: b439b98708296df8c133cc3365ac4b0359f263cd (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
                       
                                   

                                                                            
           





                                                                            
                
                             
 


                             




















                                                                           
 
                                  
 
                                                    
 
                                             
         
                                     

                                
                                        













                                                                             
 

 
                                  
 
                       

 
                                   
 

 

                                   


                                                                                             

                                                              
                                      
 
                                   
 
                                            




                                           
                                       
                                           

 
 
                                   
 
                      

                                  
 

                                      



                                                              
                                            
 
                                                    





                                       
                                                                                            
 



                                       
                                                                         

                      
                                                                                  
         

 
                                                         
 
                     
                                                                       
                                                     





                         
                                          
 
                               

                                                            

 
                                           
 
                            

 
                                            
 





                                                

 



                                                        
                                                   
 
                                                                     

                                                                                  
 
                           
         
                                                                                  
 
                                               
                                         
                                    
 
                                                 
         

 

  
                                                    

   
                                          
 

                                                              

 
                                         
 
                                       
 
                                  
                                               
                                   
 
                    
 
 
 
  
                      

   

                                           
                                        
                                   

 
                                                    
 
                            

 
                                                   
 



                                                            

 
                                                    
 
                                  

                                          




                                                    
                                                  
                                   
                                                  
                                   
 




                                                                 
 

                                                                                           
 
                            
 
// license:BSD-3-Clause
// copyright-holders:Mark McDougall
/***************************************************************************

  stfight.c

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

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

#include "emu.h"
#include "includes/stfight.h"

#include "cpu/m6805/m68705.h"
#include "cpu/z80/z80.h"
#include "sound/msm5205.h"


/*

Encryption PAL 16R4 on CPU board

          +---U---+
     CP --|       |-- VCC
 ROM D1 --|       |-- ROM D0          M1 = 0                M1 = 1
 ROM D3 --|       |-- (NC)
 ROM D4 --|       |-- D6         D6 = D1 ^^ D3          D6 = / ( D1 ^^ D0 )
 ROM D6 --|       |-- D4         D4 = / ( D6 ^^ A7 )    D4 = D3 ^^ A0
     A0 --|       |-- D3         D3 = / ( D0 ^^ A1 )    D3 = D4 ^^ A4
     A1 --|       |-- D0         D0 = D1 ^^ D4          D0 = / ( D6 ^^ A0 )
     A4 --|       |-- (NC)
     A7 --|       |-- /M1
    GND --|       |-- /OE
          +-------+

*/


void stfight_state::init_empcity()
{
	uint8_t *rom = memregion("maincpu")->base();

	for (uint32_t A = 0; A < 0x8000; ++A)
	{
		uint8_t src = rom[A];

		// decode opcode
		m_decrypted_opcodes[A] =
				( src & 0xA6 ) |
				( ( ( ( src << 2 ) ^ src ) << 3 ) & 0x40 ) |
				( ~( ( src ^ ( A >> 1 ) ) >> 2 ) & 0x10 ) |
				( ~( ( ( src << 1 ) ^ A ) << 2 ) & 0x08 ) |
				( ( ( src ^ ( src >> 3 ) ) >> 1 ) & 0x01 );

		// decode operand
		rom[A] =
				( src & 0xA6 ) |
				( ~( ( src ^ ( src << 1 ) ) << 5 ) & 0x40 ) |
				( ( ( src ^ ( A << 3 ) ) << 1 ) & 0x10 ) |
				( ( ( src ^ A ) >> 1 ) & 0x08 ) |
				( ~( ( src >> 6 ) ^ A ) & 0x01 );
	}

}

void stfight_state::init_stfight()
{
	init_empcity();
}

void stfight_state::init_cshooter()
{
}

void stfight_state::machine_start()
{
	m_main_bank->configure_entries(0, 4, memregion("maincpu")->base() + 0x10000, 0x4000);
	m_main_bank->set_entry(0);

	m_int1_timer = timer_alloc(TIMER_STFIGHT_INTERRUPT_1);

	save_item(NAME(m_coin_state));

	save_item(NAME(m_fm_data));

	save_item(NAME(m_cpu_to_mcu_empty));
	save_item(NAME(m_cpu_to_mcu_data));
	save_item(NAME(m_port_a_out));
	save_item(NAME(m_port_c_out));

	save_item(NAME(m_vck2));
	save_item(NAME(m_adpcm_reset));
	save_item(NAME(m_adpcm_data_offs));
}


void stfight_state::machine_reset()
{
	m_fm_data = 0;
	m_cpu_to_mcu_empty = true;
	m_adpcm_reset = true;

	// Coin signals are active low
	m_coin_state = 3;
}

// It's entirely possible that this bank is never switched out
// - in fact I don't even know how/where it's switched in!
WRITE8_MEMBER(stfight_state::stfight_bank_w)
{
	m_main_bank->set_entry(bitswap(data, 7, 2));
}

/*
 *      CPU 1 timed interrupt - 60Hz???
 */

void stfight_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch (id)
	{
	case TIMER_STFIGHT_INTERRUPT_1:
		// Do a RST08
		m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 0xd7);
		break;
	default:
		assert_always(false, "Unknown id in stfight_state::device_timer");
	}
}

INTERRUPT_GEN_MEMBER(stfight_state::stfight_vb_interrupt)
{
	// Do a RST10
	device.execute().set_input_line_and_vector(0, HOLD_LINE, 0xcf);
	m_int1_timer->adjust(attotime::from_hz(120));
}

/*
 *      Hardware handlers
 */

WRITE8_MEMBER(stfight_state::stfight_io_w)
{
	// TODO: What is bit 4?
	machine().bookkeeping().coin_counter_w(0, data & 1);
	machine().bookkeeping().coin_counter_w(1, data & 2);
}

READ8_MEMBER(stfight_state::stfight_coin_r)
{
	return m_coin_state;
}

WRITE8_MEMBER(stfight_state::stfight_coin_w)
{
	// Acknowledge coin signals (active low)
	if (!BIT(data, 0))
		m_coin_state |= 1;

	if (!BIT(data, 1))
		m_coin_state |= 2;
}

/*
 *      Machine hardware for MSM5205 ADPCM sound control
 */

WRITE_LINE_MEMBER(stfight_state::stfight_adpcm_int)
{
	// Falling edge triggered interrupt at half the rate of /VCK?
	m_mcu->set_input_line(M68705_IRQ_LINE, m_vck2 ? ASSERT_LINE : CLEAR_LINE);
	m_vck2 = !m_vck2;

	if (!m_adpcm_reset)
	{
		uint8_t adpcm_data = m_samples[(m_adpcm_data_offs >> 1) & 0x7fff];

		if (!BIT(m_adpcm_data_offs, 0))
			adpcm_data >>= 4;
		++m_adpcm_data_offs;

		m_msm->data_w(adpcm_data & 0x0f);
	}
}


/*
 *      Machine hardware for YM2303 FM sound control
 */

WRITE8_MEMBER(stfight_state::stfight_fm_w)
{
	// The sound cpu ignores any FM data without bit 7 set
	m_fm_data = 0x80 | data;
}

READ8_MEMBER(stfight_state::stfight_fm_r)
{
	uint8_t const data = m_fm_data;

	// Acknowledge the command
	if (!machine().side_effects_disabled())
		m_fm_data &= ~0x80;

	return data;
}


/*
 *  MCU communications
 */

WRITE8_MEMBER(stfight_state::stfight_mcu_w)
{
	m_cpu_to_mcu_data = data & 0x0f;
	m_cpu_to_mcu_empty = false;
}

WRITE8_MEMBER(stfight_state::stfight_68705_port_a_w)
{
	m_port_a_out = data;
}

READ8_MEMBER(stfight_state::stfight_68705_port_b_r)
{
	return
			(m_coin_mech->read() << 6) |
			(m_cpu_to_mcu_empty ? 0x10 : 0x00) |
			(m_cpu_to_mcu_data & 0x0f);
}

WRITE8_MEMBER(stfight_state::stfight_68705_port_b_w)
{
	// Acknowledge Z80 command
	if (!BIT(data, 5))
		m_cpu_to_mcu_empty = true;
}

WRITE8_MEMBER(stfight_state::stfight_68705_port_c_w)
{
	// Signal a valid coin on the falling edge
	if (BIT(m_port_c_out, 0) && !BIT(data, 0))
		m_coin_state &= ~1;
	if (BIT(m_port_c_out, 1) && !BIT(data, 1))
		m_coin_state &= ~2;

	// Latch ADPCM data address when dropping the reset line
	m_adpcm_reset = BIT(data, 2);
	if (!m_adpcm_reset && BIT(m_port_c_out, 2))
		m_adpcm_data_offs = m_port_a_out << 9;
	m_msm->reset_w(m_adpcm_reset ? ASSERT_LINE : CLEAR_LINE);

	// Generate NMI on host CPU (used on handshake error or stuck coin)
	m_maincpu->set_input_line(INPUT_LINE_NMI, BIT(data, 3) ? CLEAR_LINE : ASSERT_LINE);

	m_port_c_out = data;
}