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

                                   





                                                                      
                

                
                   
 
                                                                   
 
                                                                                                       
                                                        
                                     








                                     














                                      
                                   







                                                                            

                             
                        













                                                                                         
                           



                       



                                    










                                                      




                                      








                                               





                                                                                                     






                                             

                                    























                                                                                                      





















                                                 
                                                                            




                                                                               











































                                                                              
                                     































                                                                                                               
// license:BSD-3-Clause
// copyright-holders:Barry Rodewald
/*
 * wpc.c  --  Williams WPC ASIC, used on Williams WPC pinball machines
 *
 *  Created on: 7/10/2013
 */

#include "emu.h"
#include "wpc.h"

#define LOG_WPC (0)

DEFINE_DEVICE_TYPE(WPCASIC, wpc_device, "wpc", "Williams WPC ASIC")

wpc_device::wpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
	: device_t(mconfig, WPCASIC, tag, owner, clock),
		m_dmd_visiblepage(0),
		m_irq_cb(*this),
		m_firq_cb(*this),
		m_sounddata_r(*this),
		m_sounddata_w(*this),
		m_soundctrl_r(*this),
		m_soundctrl_w(*this),
		m_sounds11_w(*this),
		m_bank_w(*this),
		m_dmdbank_w(*this)
{
}


void wpc_device::device_start()
{
	// resolve callbacks
	m_irq_cb.resolve_safe();
	m_firq_cb.resolve_safe();
	m_sounddata_r.resolve_safe(0);
	m_sounddata_w.resolve_safe();
	m_soundctrl_r.resolve_safe(0);
	m_soundctrl_w.resolve_safe();
	m_sounds11_w.resolve_safe();
	m_bank_w.resolve_safe();
	m_dmdbank_w.resolve_safe();

	m_zc_timer = timer_alloc(TIMER_ZEROCROSS);
	m_zc_timer->adjust(attotime::from_hz(120),0,attotime::from_hz(120));
}

void wpc_device::device_reset()
{
	m_memprotect = 0;
	m_dmd_irqsrc = false;
	m_snd_irqsrc = false;
	m_alpha_pos = 0;
}

void wpc_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
	switch(id)
	{
	case TIMER_ZEROCROSS:
		m_zerocross = true;
		break;
	}
}

READ8_MEMBER(wpc_device::read)
{
	uint8_t ret = 0x00;
	char kbdrow[8];

	switch(offset)
	{
	case DMD_FIRQLINE:
		if(m_dmd_irqsrc)
			ret |= 0x80;
		break;
	case WPC_WATCHDOG:
		if(m_zerocross)
		{
			ret |= 0x80;
			m_irq_count = 0;
		}
		m_zerocross = false;
		break;
	case WPC_SWROWREAD:
		sprintf(kbdrow,":INP%X",m_switch_col);
		ret = ~ioport(kbdrow)->read();
//      for(x=0;x<8;x++)
//      {
//          if(m_switch_col & (1<<x))
//              ret = m_switches[3+x];
//      }
		break;
	case WPC_SWCOINDOOR:
		ret = ~ioport(":COIN")->read();
		//ret = m_switches[0];
		break;
	case WPC_DIPSWITCH:
		ret = ~ioport(":DIPS")->read();
		//ret = m_switches[1];
		break;
	case WPC_FLIPPERS:
		if(ioport(":FLIP"))  // just in case some non-fliptronics games tries to read here...
			ret = ~ioport(":FLIP")->read();
		else
			ret = 0x00;
		break;
	case WPC_SOUNDIF:
		ret = m_sounddata_r(space,0);
		break;
	case WPC_SOUNDBACK:
		ret = m_soundctrl_r(space,0);
		break;
	case WPC_FIRQSRC:
		if(m_snd_irqsrc)
			ret |= 0x80;
		break;
	case WPC_SHIFTADRH:
		ret = m_shift_addr_high + ((m_shift_addr_low + (m_shift_bit1 >> 3)) >> 8);
		break;
	case WPC_SHIFTADRL:
		ret = (m_shift_addr_low + (m_shift_bit1 >> 3)) & 0xff;
		break;
	case WPC_SHIFTBIT:
		ret = 1 << (m_shift_bit1 & 0x07);
		break;
	case WPC_SHIFTBIT2:
		ret = 1 << (m_shift_bit2 & 0x07);
		break;
	default:
		logerror("WPC: Unknown or unimplemented WPC register read from offset %02x\n",offset);
		break;
	}
	return ret;
}

WRITE8_MEMBER(wpc_device::write)
{
	switch(offset)
	{
	case DMD_PAGE3000:
		m_dmdbank_w(space,0,data & 0x0f);
		break;
	case DMD_PAGE3200:
		m_dmdbank_w(space,1,data & 0x0f);
		break;
	case DMD_PAGE3400:
		m_dmdbank_w(space,2,data & 0x0f);
		break;
	case DMD_PAGE3600:
		m_dmdbank_w(space,3,data & 0x0f);
		break;
	case DMD_PAGE3800:
		m_dmdbank_w(space,4,data & 0x0f);
		break;
	case DMD_PAGE3A00:
		m_dmdbank_w(space,5,data & 0x0f);
		break;
	case DMD_FIRQLINE:
		m_firq_cb(space,0);
		m_dmd_irqsrc = false;
		m_dmd_irqline = data;
		if(LOG_WPC) logerror("WPC: DMD FIRQ line set to %i\n",data);
		break;
	case DMD_VISIBLEPAGE:
		m_dmd_visiblepage = data;
		if(LOG_WPC) logerror("WPC: DMD Visible page set to %i\n",data);
		break;
	case WPC_ROMBANK:
		m_bank_w(space,0,data);
		if(LOG_WPC) logerror("WPC: ROM bank set to %02x\n",data);
		break;
	case WPC_ALPHAPOS:
		m_alpha_pos = data & 0x1f;
		break;
	case WPC_ALPHA1LO:
		m_alpha_data[m_alpha_pos] |= data;
		break;
	case WPC_ALPHA1HI:
		m_alpha_data[m_alpha_pos] |= (data << 8);
		break;
	case WPC_ALPHA2LO:
		m_alpha_data[20+m_alpha_pos] |= data;
		break;
	case WPC_ALPHA2HI:
		m_alpha_data[20+m_alpha_pos] |= (data << 8);
		break;
	case WPC_IRQACK:
		m_irq_cb(space,CLEAR_LINE);
		break;
	case WPC_WATCHDOG:
		if(data & 0x80)
		{
			m_irq_count++;
			m_irq_cb(space,CLEAR_LINE);
		}
		break;
	case WPC_SWCOLSELECT:
		m_switch_col = data;
		if(LOG_WPC) logerror("WPC: Switch column select %02x\n",data);
		break;
	case WPC_SOUNDIF:
		m_sounddata_w(space,0,data);
		break;
	case WPC_SOUNDBACK:
		m_soundctrl_w(space,0,data);
		break;
	case WPC_SOUNDS11:
		m_sounds11_w(space,0,data);
		break;
	case WPC_FIRQSRC:
		m_firq_cb(space,0);
		m_snd_irqsrc = false;
		break;
	case WPC_PROTMEMCTRL:
		if(m_memprotect == 0xb4)
		{  // may not be correct
			m_memprotect_mask = (((data & 0x01) << 3) |
								((data & 0x02) << 1) |
								((data & 0x04) >> 1) |
								((data & 0x08) >> 3) |
								(data & 0xf0)) + 0x10;
			m_memprotect_mask <<= 8;
		}
		break;
	case WPC_PROTMEM:
		m_memprotect = data;
		break;
	case WPC_SHIFTADRH:
		m_shift_addr_high = data;
		break;
	case WPC_SHIFTADRL:
		m_shift_addr_low = data;
		break;
	case WPC_SHIFTBIT:
		m_shift_bit1 = data;
		break;
	case WPC_SHIFTBIT2:
		m_shift_bit2 = data;
		break;
	default:
		logerror("WPC: Unknown or unimplemented WPC register write %02x to offset %02x\n",data,offset);
		break;
	}
}