summaryrefslogblamecommitdiffstatshomepage
path: root/src/mame/machine/decopincpu.cpp
blob: 38e9d5c2d062d1e6b0a4da704f4465d1bbde1433 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

                                   












                                                                                                   
                

                       



                                                                                                        
 



                                                                                                                    
                                                                                    




                                                                                                                         
                                    
 
 



                                                                                                                    
                                                                                    




                                                                                                                         
                                    
 


















                                                                                                                                                                    
                                                                           






                                                                                
                                                                          












                                                                                            
                                                                        























                                                                                    





                                                      
                                                
 
                                                          
                                  

 
                                                
 
                                  

 
                                                
 
                           






                                                         
                                                         



                                     
                                                       



                                     
                                                       



                                     
                                                       



                                     
                                             



                                 
                                                 



                                    
                                        



                                
                                           
 


                                   
                                                       



                                     
                                                



                                        
                                                    



               
                                                    



               

                                                                     
                                    

                                                                            

                     





































                                                                                     
 
                                                            
 
 




                                                                   
                                                                                                                           
                                                                    

  

                                                                                                                                             






                                        
                                                     







                                          



                                         













                                                                            
                                                                           

 
                                                                                                                           
                                                                    

  

                                                                                                                                             

  

                                                                     


                                                         

                                                                            





                                             
                                                                                                                           
                                                                    

  

                                                                                                                                             

  



                                             
 
                                                                                                                             
                                                                     





                                             
// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
/*
 *  Data East Pinball CPU boards
 *
 *  Type 1:  Based on Williams System 11 CPU boards, but without the generic pinball audio hardware
 *  Type 2:  RAM increased from 2kB to 8kB
 *  Type 3:  Adds CPU controlled solenoids
 *  Type 3b: Adds printer option
 *
 *  TODO:
 *   - make use of solenoid callbacks
 *   - printer option (type 3b)
 */

#include "emu.h"
#include "decopincpu.h"

DEFINE_DEVICE_TYPE(DECOCPU1,  decocpu_type1_device,  "decocpu1",  "Data East Pinball CPU Board Type 1")
DEFINE_DEVICE_TYPE(DECOCPU2,  decocpu_type2_device,  "decocpu2",  "Data East Pinball CPU Board Type 2")
DEFINE_DEVICE_TYPE(DECOCPU3,  decocpu_type3_device,  "decocpu3",  "Data East Pinball CPU Board Type 3")
DEFINE_DEVICE_TYPE(DECOCPU3B, decocpu_type3b_device, "decocpu3b", "Data East Pinball CPU Board Type 3B")

void decocpu_type1_device::decocpu1_map(address_map &map)
{
	map(0x0000, 0x07ff).ram().share("nvram");
	map(0x2100, 0x2103).rw("pia21", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // sound+solenoids
	map(0x2200, 0x2200).w(FUNC(decocpu_type1_device::solenoid2_w)); // solenoids
	map(0x2400, 0x2403).rw("pia24", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // lamps
	map(0x2800, 0x2803).rw("pia28", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // display
	map(0x2c00, 0x2c03).rw("pia2c", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // alphanumeric display
	map(0x3000, 0x3003).rw("pia30", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // inputs
	map(0x3400, 0x3403).rw("pia34", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // widget
	//map(0x4000, 0xffff).rom();
}

void decocpu_type2_device::decocpu2_map(address_map &map)
{
	map(0x0000, 0x1fff).ram().share("nvram");
	map(0x2100, 0x2103).rw("pia21", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // sound+solenoids
	map(0x2200, 0x2200).w(FUNC(decocpu_type2_device::solenoid2_w)); // solenoids
	map(0x2400, 0x2403).rw("pia24", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // lamps
	map(0x2800, 0x2803).rw("pia28", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // display
	map(0x2c00, 0x2c03).rw("pia2c", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // alphanumeric display
	map(0x3000, 0x3003).rw("pia30", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // inputs
	map(0x3400, 0x3403).rw("pia34", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); // widget
	//map(0x4000, 0xffff).rom();
}

static INPUT_PORTS_START( decocpu1 )
	PORT_START("DIAGS")
	PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Audio Diag") PORT_CODE(KEYCODE_F1) PORT_CHANGED_MEMBER(DEVICE_SELF, decocpu_type1_device, audio_nmi, 1)
	PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Main Diag") PORT_CODE(KEYCODE_F2) PORT_CHANGED_MEMBER(DEVICE_SELF, decocpu_type1_device, main_nmi, 1)
	PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Advance") PORT_CODE(KEYCODE_0)
	PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_OTHER) PORT_NAME("Up/Down") PORT_CODE(KEYCODE_9) PORT_TOGGLE
	PORT_CONFNAME( 0x10, 0x10, "Language" )
	PORT_CONFSETTING( 0x00, "German" )
	PORT_CONFSETTING( 0x10, "English" )
INPUT_PORTS_END

void decocpu_type1_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch(id)
	{
	case TIMER_IRQ:
		if(param == 1)
		{
			m_cpu->set_input_line(M6808_IRQ_LINE, ASSERT_LINE);
			m_irq_timer->adjust(attotime::from_ticks(32,E_CLOCK),0);
			m_irq_active = true;
			m_pia28->ca1_w(BIT(ioport("DIAGS")->read(), 2));
			m_pia28->cb1_w(BIT(ioport("DIAGS")->read(), 3));
		}
		else
		{
			m_cpu->set_input_line(M6808_IRQ_LINE, CLEAR_LINE);
			m_irq_timer->adjust(attotime::from_ticks(S11_IRQ_CYCLES,E_CLOCK),1);
			m_irq_active = false;
			m_pia28->ca1_w(1);
			m_pia28->cb1_w(1);
		}
		break;
	}
}

INPUT_CHANGED_MEMBER( decocpu_type1_device::main_nmi )
{
	// Diagnostic button sends a pulse to NMI pin
	if (newval==CLEAR_LINE)
		m_cpu->pulse_input_line(INPUT_LINE_NMI, attotime::zero);
}

INPUT_CHANGED_MEMBER( decocpu_type1_device::audio_nmi )
{
	// Not on DECO board?
}

WRITE_LINE_MEMBER(decocpu_type1_device::cpu_pia_irq)
{
	if(state == CLEAR_LINE)
	{
		// restart IRQ timer
		m_irq_timer->adjust(attotime::from_ticks(S11_IRQ_CYCLES,E_CLOCK),1);
		m_irq_active = false;
	}
	else
	{
		// disable IRQ timer while other IRQs are being handled
		// (counter is reset every 32 cycles while a PIA IRQ is handled)
		m_irq_timer->adjust(attotime::zero);
		m_irq_active = true;
	}
}

WRITE_LINE_MEMBER( decocpu_type1_device::pia21_ca2_w )
{
// sound ns
	m_ca2 = state;
}

void decocpu_type1_device::lamp0_w(uint8_t data)
{
	m_cpu->set_input_line(M6808_IRQ_LINE, CLEAR_LINE);
	m_write_lamp(0,data,0xff);
}

void decocpu_type1_device::lamp1_w(uint8_t data)
{
	m_write_lamp(1,data,0xff);
}

uint8_t decocpu_type1_device::display_strobe_r()
{
	uint8_t ret = 0x80;

	if(BIT(ioport("DIAGS")->read(), 4))  // W7 Jumper
		ret &= ~0x80;

	return ret | (m_read_display(0) & 0x7f);
}

void decocpu_type1_device::display_strobe_w(uint8_t data)
{
	m_write_display(0,data,0xff);
}

void decocpu_type1_device::display_out1_w(uint8_t data)
{
	m_write_display(1,data,0xff);
}

void decocpu_type1_device::display_out2_w(uint8_t data)
{
	m_write_display(2,data,0xff);
}

void decocpu_type1_device::display_out3_w(uint8_t data)
{
	m_write_display(3,data,0xff);
}

uint8_t decocpu_type1_device::display_in3_r()
{
	return m_read_display(3);
}

void decocpu_type1_device::switch_w(uint8_t data)
{
	m_write_switch(0,data,0xff);
}

uint8_t decocpu_type1_device::switch_r()
{
	return m_read_switch(0);
}

uint8_t decocpu_type1_device::dmdstatus_r()
{
	return m_read_dmdstatus(0);
}

void decocpu_type1_device::display_out4_w(uint8_t data)
{
	m_write_display(4,data,0xff);
}

void decocpu_type1_device::sound_w(uint8_t data)
{
	m_write_soundlatch(0,data,0xff);
}

void decocpu_type1_device::solenoid1_w(uint8_t data)
{
	// todo
}

void decocpu_type1_device::solenoid2_w(uint8_t data)
{
	// todo
}

void decocpu_type1_device::device_add_mconfig(machine_config &config)
{
	/* basic machine hardware */
	M6808(config, m_cpu, XTAL(4'000'000));
	m_cpu->set_addrmap(AS_PROGRAM, &decocpu_type1_device::decocpu1_map);

	/* Devices */
	PIA6821(config, m_pia21, 0); // 5F - PIA at 0x2100
	m_pia21->writepa_handler().set(FUNC(decocpu_type1_device::solenoid1_w));
	m_pia21->ca2_handler().set(FUNC(decocpu_type1_device::pia21_ca2_w));
	m_pia21->irqa_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));
	m_pia21->irqb_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));

	PIA6821(config, m_pia24, 0); // 11D - PIA at 0x2400
	m_pia24->writepa_handler().set(FUNC(decocpu_type1_device::lamp0_w));
	m_pia24->writepb_handler().set(FUNC(decocpu_type1_device::lamp1_w));
	m_pia24->irqa_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));
	m_pia24->irqb_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));

	PIA6821(config, m_pia28, 0); // 11B - PIA at 0x2800
	m_pia28->readpa_handler().set(FUNC(decocpu_type1_device::display_strobe_r));
	m_pia28->writepa_handler().set(FUNC(decocpu_type1_device::display_strobe_w));
	m_pia28->writepb_handler().set(FUNC(decocpu_type1_device::display_out1_w));
	m_pia28->irqa_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));
	m_pia28->irqb_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));

	PIA6821(config, m_pia2c, 0); // 9B - PIA at 0x2c00
	m_pia2c->readpb_handler().set(FUNC(decocpu_type1_device::display_in3_r));
	m_pia2c->writepa_handler().set(FUNC(decocpu_type1_device::display_out2_w));
	m_pia2c->writepb_handler().set(FUNC(decocpu_type1_device::display_out3_w));
	m_pia2c->irqa_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));
	m_pia2c->irqb_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));

	PIA6821(config, m_pia30, 0); // 8H - PIA at 0x3000
	m_pia30->readpa_handler().set(FUNC(decocpu_type1_device::switch_r));
	m_pia30->writepb_handler().set(FUNC(decocpu_type1_device::switch_w));
	m_pia30->irqa_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));
	m_pia30->irqb_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));

	PIA6821(config, m_pia34, 0); // 7B - PIA at 0x3400
	m_pia34->readpa_handler().set(FUNC(decocpu_type1_device::dmdstatus_r));
	m_pia34->writepa_handler().set(FUNC(decocpu_type1_device::display_out4_w));
	m_pia34->writepb_handler().set(FUNC(decocpu_type1_device::sound_w));
	m_pia34->irqa_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));
	m_pia34->irqb_handler().set(FUNC(decocpu_type1_device::cpu_pia_irq));

	NVRAM(config, "nvram", nvram_device::DEFAULT_ALL_1);
}

ioport_constructor decocpu_type1_device::device_input_ports() const
{
	return INPUT_PORTS_NAME( decocpu1 );
}

decocpu_type1_device::decocpu_type1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: decocpu_type1_device(mconfig, DECOCPU1, tag, owner, clock)
{}

decocpu_type1_device::decocpu_type1_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, type, tag, owner, clock),
		m_cpu(*this,"maincpu"),
		m_pia21(*this, "pia21"),
		m_pia24(*this, "pia24"),
		m_pia28(*this, "pia28"),
		m_pia2c(*this, "pia2c"),
		m_pia30(*this, "pia30"),
		m_pia34(*this, "pia34"),
		m_rom(*this, finder_base::DUMMY_TAG),
		m_read_display(*this),
		m_write_display(*this),
		m_read_dmdstatus(*this),
		m_write_soundlatch(*this),
		m_read_switch(*this),
		m_write_switch(*this),
		m_write_lamp(*this),
		m_write_solenoid(*this)
{}

void decocpu_type1_device::device_start()
{
	// resolve callbacks
	m_read_display.resolve_safe(0);
	m_write_display.resolve_safe();
	m_read_dmdstatus.resolve_safe(0);
	m_write_soundlatch.resolve_safe();
	m_read_switch.resolve_safe(0);
	m_write_switch.resolve_safe();
	m_write_lamp.resolve_safe();
	m_write_solenoid.resolve_safe();

	m_irq_timer = timer_alloc(TIMER_IRQ);
	m_irq_timer->adjust(attotime::from_ticks(S11_IRQ_CYCLES,E_CLOCK),1);
	m_irq_active = false;

	m_cpu->space(AS_PROGRAM).install_rom(0x4000,0xffff,&m_rom[0x4000]);
}

decocpu_type2_device::decocpu_type2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: decocpu_type2_device(mconfig, DECOCPU2, tag, owner, clock)
{}

decocpu_type2_device::decocpu_type2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
	: decocpu_type1_device(mconfig, type, tag, owner, clock)
{}

void decocpu_type2_device::device_add_mconfig(machine_config &config)
{
	decocpu_type1_device::device_add_mconfig(config);

	/* basic machine hardware */
	m_cpu->set_addrmap(AS_PROGRAM, &decocpu_type2_device::decocpu2_map);
}

void decocpu_type2_device::device_start()
{
	decocpu_type1_device::device_start();
}

decocpu_type3_device::decocpu_type3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: decocpu_type3_device(mconfig, DECOCPU3, tag, owner, clock)
{}

decocpu_type3_device::decocpu_type3_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
	: decocpu_type2_device(mconfig, type, tag, owner, clock)
{}

void decocpu_type3_device::device_start()
{
	decocpu_type1_device::device_start();
}

decocpu_type3b_device::decocpu_type3b_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: decocpu_type3_device(mconfig, DECOCPU3B, tag, owner, clock)
{}

void decocpu_type3b_device::device_start()
{
	decocpu_type1_device::device_start();
}