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

                        



                                                              
            


                           
                        

                           
                        
                                     
                          

                           
                           
                           
                          

                                          
                                                               

                                                                       
 


                                                                                                


                                                                             
                                                                                             
                                                     


                                                                                                                 
 
  
 
 
                                                                                                                       
                                                                                                                                    

                                                                                                                        
 
 
                                       
 

                                                   
                                               




                                           

 
                                                
 




                                                 
                                  
                                                                                       

 










                                                                   
 


                                                       

                                

                                                    
                             


                               

                            





                            
                                                  



                           



                                               

                                        

                                     








                                      

 



                                               
 


                                                           
 

                                                                                                       


                                                              



                                                     
                                  








                                                                           
                                          
         
 







                                                  
                                                   








                                                                                                                        
                                                                           


 

                                                                                                                                          
                                
                           
 
 
 






                                                                       
 
                                          
 
                                                   
 

                                       


                                     


 

















                                                                         
 
                                       
 

                                                       
                                                                               

 
                                                                            
 



                                                                         


                                                            
 





                                                               


 
                                                                    
 
                                                                                                                                    
                                                                                 


 
                                             
 
                                                             
                                                           

 
 
                                                                         
 











                                                                      
                                       
 
                              

 
                                       

                                                       
                                                     
                                                                               

 
                                                

                                                            
                                              
                                               

 

                                             

                                                   

                                        

                                     


                           




                                                 
                          
                                                                                


 







                                                                        





                                                 
                          
                                                                                


 







                                                                        
// license:BSD-3-Clause
// copyright-holders:Ernesto Corvi, Nicola Salmoria, David Haywood, Vas Crabb
#include "emu.h"
#include "machine/taito68705interface.h"

#include "cpu/z80/z80.h"

/*
   Most Taito 68705s share a similar (often identical) hookup.
   This file encapsulates that.

    used by:
    40love.cpp   - 40love
    bigevglf.cpp - bigevglf
    bking.cpp    - bking3
    bublbobl.cpp - tokio
    buggychl.cpp - buggychl
    flstory.cpp  - flstory
    lkage.cpp    - lkage
    lsasquad.cpp - lsasquad, daikaiju
    matmania.cpp - maniach
    nycaptor.cpp - nycaptor
    renegade.cpp - renegade
    retofinv.cpp - retofinv
    slapfght.cpp - slapfght
    xain.cpp     - xsleena

    and the following with slight changes:
    slapfght.cpp - tigerh (inverted status bits read on port C)
    arkanoid.cpp - arkanoid (latch control on port C, inputs on port B)
    taito_l.cpp - puzznic (latch control on port C)

    not hooked up here, but possible (needs investigating)
    pitnrun.cpp - have more functionality on portB, currently using 'instant timers' for latches
    taitosj.cpp - ^^

    68705 sets in Taito drivers that are NOT suitable for hookup here?
    bublbobl.cpp - bub68705 - this is a bootleg, not an official Taito hookup
    changela.cpp - changela - looks like an ancestor of arkanoid without automatic semaphores
    mexico86.cpp - knightb, mexico86 - bootleg 68705s
    sqix.cpp - hotsmash - kaneko hookup, different from Taito ones.

    there are other drivers (and games in existing drivers) that could hookup here, but currently lack MCU dumps.

*/


DEFINE_DEVICE_TYPE(TAITO68705_MCU,       taito68705_mcu_device,       "taito68705",      "Taito MC68705 MCU Interface")
DEFINE_DEVICE_TYPE(TAITO68705_MCU_TIGER, taito68705_mcu_tiger_device, "taito68705tiger", "Taito MC68705 MCU Interface (Tiger-Heli)")
DEFINE_DEVICE_TYPE(ARKANOID_68705P3,     arkanoid_68705p3_device,     "arkanoid68705p3", "Arkanoid MC68705P3 Interface")
DEFINE_DEVICE_TYPE(ARKANOID_68705P5,     arkanoid_68705p5_device,     "arkanoid68705p5", "Arkanoid MC68705P5 Interface")


u8 taito68705_mcu_device_base::data_r()
{
	// clear MCU semaphore flag and return data
	u8 const result(m_mcu_latch);
	if (!machine().side_effects_disabled())
	{
		m_mcu_flag = false;
		m_semaphore_cb(CLEAR_LINE);
	}
	return result;
}

void taito68705_mcu_device_base::data_w(u8 data)
{
	// set host semaphore flag and latch data
	if (!m_reset_input)
		m_host_flag = true;
	m_host_latch = data;
	if (m_latch_driven)
		m_mcu->pa_w(data);
	m_mcu->set_input_line(M68705_IRQ_LINE, m_host_flag ? ASSERT_LINE : CLEAR_LINE);
}

WRITE_LINE_MEMBER(taito68705_mcu_device_base::reset_w)
{
	m_reset_input = ASSERT_LINE == state;
	if (CLEAR_LINE != state)
	{
		m_host_flag = false;
		m_mcu_flag = false;
		m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
	}
	m_mcu->set_input_line(INPUT_LINE_RESET, state);
}

taito68705_mcu_device_base::taito68705_mcu_device_base(
		machine_config const &mconfig,
		device_type type,
		char const *tag,
		device_t *owner,
		u32 clock)
	: device_t(mconfig, type, tag, owner, clock)
	, m_mcu(*this, "mcu")
	, m_semaphore_cb(*this)
	, m_latch_driven(false)
	, m_reset_input(false)
	, m_host_flag(false)
	, m_mcu_flag(false)
	, m_host_latch(0xff)
	, m_mcu_latch(0xff)
	, m_pa_output(0xff)
{
}

void taito68705_mcu_device_base::mcu_pa_w(u8 data)
{
	m_pa_output = data;
}

void taito68705_mcu_device_base::device_start()
{
	m_semaphore_cb.resolve_safe();

	save_item(NAME(m_latch_driven));
	save_item(NAME(m_reset_input));
	save_item(NAME(m_host_flag));
	save_item(NAME(m_mcu_flag));
	save_item(NAME(m_host_latch));
	save_item(NAME(m_mcu_latch));
	save_item(NAME(m_pa_output));

	m_latch_driven = false;
	m_reset_input = false;
	m_host_latch = 0xff;
	m_mcu_latch = 0xff;
	m_pa_output = 0xff;
}

void taito68705_mcu_device_base::device_reset()
{
	m_host_flag = false;
	m_mcu_flag = false;

	m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
	m_semaphore_cb(CLEAR_LINE);
}

void taito68705_mcu_device_base::latch_control(u8 data, u8 &value, unsigned host_bit, unsigned mcu_bit)
{
	// save this here to simulate latch propagation delays
	u8 const old_pa_value(pa_value());

	// rising edge clears the host semaphore flag
	if (BIT(data, host_bit))
	{
		m_latch_driven = false;
		m_mcu->pa_w(0xff);
		if (!BIT(value, host_bit))
		{
			m_host_flag = false;
			m_mcu->set_input_line(M68705_IRQ_LINE, CLEAR_LINE);
		}
	}
	else
	{
		m_latch_driven = true;
		m_mcu->pa_w(m_host_latch);
	}

	// PB2 sets the MCU semaphore when low
	if (!BIT(data, mcu_bit))
	{
		if (!m_reset_input)
			m_mcu_flag = true;

		// data is latched on falling edge
		if (BIT(value, mcu_bit))
			m_mcu_latch = old_pa_value;
	}

	value = data;
	if (!BIT(data, mcu_bit) && !m_reset_input)
		m_semaphore_cb(ASSERT_LINE);
}


taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: taito68705_mcu_device(mconfig, TAITO68705_MCU, tag, owner, clock)
{
}

taito68705_mcu_device::taito68705_mcu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
	: taito68705_mcu_device_base(mconfig, type, tag, owner, clock)
	, m_aux_strobe_cb(*this)
	, m_pb_output(0xff)
{
}

void taito68705_mcu_device::device_add_mconfig(machine_config &config)
{
	M68705P5(config, m_mcu, DERIVED_CLOCK(1, 1));
	m_mcu->porta_w().set(FUNC(taito68705_mcu_device::mcu_pa_w));
	m_mcu->portb_w().set(FUNC(taito68705_mcu_device::mcu_portb_w));
	m_mcu->portc_r().set(FUNC(taito68705_mcu_device::mcu_portc_r));
}

void taito68705_mcu_device::device_start()
{
	taito68705_mcu_device_base::device_start();

	m_aux_strobe_cb.resolve_safe();

	save_item(NAME(m_pb_output));

	m_pb_output = 0xff;
}


/*
 *  Port B connections:
 *  parts in [ ] are optional (not used by buggychl)
 *
 *  all bits are logical 1 when read (+5V pullup)
 *
 *  0   n.c.
 *  1   W  IRQ ack and enable latch which holds data from main Z80 memory
 *  2   W  loads latch to Z80
 *  3   W  to Z80 BUSRQ (put it on hold?)
 *  4   W  n.c.
 *  5   W  [selects Z80 memory access direction (0 = write 1 = read)]
 *  6   W  [loads the latch which holds the low 8 bits of the address of
 *               the main Z80 memory location to access]
 *  7   W  [loads the latch which holds the high 8 bits of the address of
 *               the main Z80 memory location to access]
 */


u8 taito68705_mcu_device::mcu_portc_r()
{
	// PC0 is the host semaphore flag (active high)
	// PC1 is the MCU semaphore flag (active low)
	return (host_flag() ? 0x01 : 0x00) | (mcu_flag() ? 0x00 : 0x02) | 0xfc;
}

void taito68705_mcu_device::mcu_portb_w(offs_t offset, u8 data, u8 mem_mask)
{
	// some games have additional peripherals strobed on falling edge
	u8 const old_pa_value(pa_value());
	u8 const aux_strobes((mem_mask & ~data & m_pb_output) >> 2);

	// rising edge on PB1 clears the host semaphore flag
	// PB2 sets the MCU semaphore when low
	latch_control(data, m_pb_output, 1, 2);

	// callbacks for other peripherals
	for (unsigned i = 0; i < 6; ++i)
	{
		if (BIT(aux_strobes, i))
			m_aux_strobe_cb(i, old_pa_value, 0xff);
	}
}


/* The Tiger-Heli interface has some extensions, handle them here */

taito68705_mcu_tiger_device::taito68705_mcu_tiger_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
	: taito68705_mcu_device(mconfig, TAITO68705_MCU_TIGER, tag, owner, clock)
{
}

u8 taito68705_mcu_tiger_device::mcu_portc_r()
{
	// Tiger-Heli has these status bits inverted MCU-side
	return taito68705_mcu_device::mcu_portc_r() ^ 0x03;
}


// Arkanoid/Puzznic (latch control on PC2 and PC3 instead of PB1 and PB2)

arkanoid_mcu_device_base::arkanoid_mcu_device_base(
		machine_config const &mconfig,
		device_type type,
		char const *tag,
		device_t *owner,
		u32 clock)
	: taito68705_mcu_device_base(mconfig, type, tag, owner, clock)
	, m_portb_r_cb(*this)
	, m_pc_output(0xff)
{
}

u8 arkanoid_mcu_device_base::mcu_pb_r()
{
	return m_portb_r_cb();
}

u8 arkanoid_mcu_device_base::mcu_pc_r()
{
	// PC0 is the host semaphore flag (active high)
	// PC1 is the MCU semaphore flag (active low)
	return (host_flag() ? 0x01 : 0x00) | (mcu_flag() ? 0x00 : 0x02) | 0xfc;
}

void arkanoid_mcu_device_base::mcu_pc_w(u8 data)
{
	// rising edge on PC2 clears the host semaphore flag
	// PC3 sets the MCU semaphore when low
	latch_control(data, m_pc_output, 2, 3);
}

void arkanoid_mcu_device_base::device_start()
{
	taito68705_mcu_device_base::device_start();

	m_portb_r_cb.resolve_safe(0xff);

	save_item(NAME(m_pc_output));

	m_pc_output = 0xff;
}


arkanoid_68705p3_device::arkanoid_68705p3_device(
		machine_config const &mconfig,
		char const *tag,
		device_t *owner,
		u32 clock)
	: arkanoid_mcu_device_base(mconfig, ARKANOID_68705P3, tag, owner, clock)
{
}

void arkanoid_68705p3_device::device_add_mconfig(machine_config &config)
{
	M68705P3(config, m_mcu, DERIVED_CLOCK(1, 1));
	m_mcu->portb_r().set(FUNC(arkanoid_68705p3_device::mcu_pb_r));
	m_mcu->portc_r().set(FUNC(arkanoid_68705p3_device::mcu_pc_r));
	m_mcu->porta_w().set(FUNC(arkanoid_68705p3_device::mcu_pa_w));
	m_mcu->portc_w().set(FUNC(arkanoid_68705p3_device::mcu_pc_w));
}


arkanoid_68705p5_device::arkanoid_68705p5_device(
		machine_config const &mconfig,
		char const *tag,
		device_t *owner,
		u32 clock)
	: arkanoid_mcu_device_base(mconfig, ARKANOID_68705P5, tag, owner, clock)
{
}

void arkanoid_68705p5_device::device_add_mconfig(machine_config &config)
{
	M68705P5(config, m_mcu, DERIVED_CLOCK(1, 1));
	m_mcu->portb_r().set(FUNC(arkanoid_68705p5_device::mcu_pb_r));
	m_mcu->portc_r().set(FUNC(arkanoid_68705p5_device::mcu_pc_r));
	m_mcu->porta_w().set(FUNC(arkanoid_68705p5_device::mcu_pa_w));
	m_mcu->portc_w().set(FUNC(arkanoid_68705p5_device::mcu_pc_w));
}