From 251aea6e01012ed8a6c35b97cc29347f0f244695 Mon Sep 17 00:00:00 2001 From: smf- Date: Tue, 21 Oct 2014 16:16:40 +0100 Subject: renamed psx controller and memory card files, renamed znsec to cat702. (nw) --- src/emu/bus/bus.mak | 12 ++ src/emu/bus/psx/analogue.c | 262 +++++++++++++++++++++++++++++ src/emu/bus/psx/analogue.h | 55 +++++++ src/emu/bus/psx/ctlrport.c | 219 +++++++++++++++++++++++++ src/emu/bus/psx/ctlrport.h | 130 +++++++++++++++ src/emu/bus/psx/memcard.c | 363 +++++++++++++++++++++++++++++++++++++++++ src/emu/bus/psx/memcard.h | 75 +++++++++ src/emu/bus/psx/multitap.c | 273 +++++++++++++++++++++++++++++++ src/emu/bus/psx/multitap.h | 41 +++++ src/mame/drivers/taitogn.c | 22 +-- src/mame/drivers/zn.c | 26 +-- src/mame/machine/cat702.c | 201 +++++++++++++++++++++++ src/mame/machine/cat702.h | 36 ++++ src/mame/machine/znsec.c | 201 ----------------------- src/mame/machine/znsec.h | 36 ---- src/mame/mame.mak | 2 +- src/mess/drivers/psx.c | 2 +- src/mess/machine/psxanalog.c | 262 ----------------------------- src/mess/machine/psxanalog.h | 55 ------- src/mess/machine/psxcard.c | 363 ----------------------------------------- src/mess/machine/psxcard.h | 75 --------- src/mess/machine/psxcport.c | 219 ------------------------- src/mess/machine/psxcport.h | 130 --------------- src/mess/machine/psxmultitap.c | 273 ------------------------------- src/mess/machine/psxmultitap.h | 41 ----- src/mess/mess.mak | 3 +- 26 files changed, 1695 insertions(+), 1682 deletions(-) create mode 100644 src/emu/bus/psx/analogue.c create mode 100644 src/emu/bus/psx/analogue.h create mode 100644 src/emu/bus/psx/ctlrport.c create mode 100644 src/emu/bus/psx/ctlrport.h create mode 100644 src/emu/bus/psx/memcard.c create mode 100644 src/emu/bus/psx/memcard.h create mode 100644 src/emu/bus/psx/multitap.c create mode 100644 src/emu/bus/psx/multitap.h create mode 100644 src/mame/machine/cat702.c create mode 100644 src/mame/machine/cat702.h delete mode 100644 src/mame/machine/znsec.c delete mode 100644 src/mame/machine/znsec.h delete mode 100644 src/mess/machine/psxanalog.c delete mode 100644 src/mess/machine/psxanalog.h delete mode 100644 src/mess/machine/psxcard.c delete mode 100644 src/mess/machine/psxcard.h delete mode 100644 src/mess/machine/psxcport.c delete mode 100644 src/mess/machine/psxcport.h delete mode 100644 src/mess/machine/psxmultitap.c delete mode 100644 src/mess/machine/psxmultitap.h diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak index 3abad75530b..65409ac662c 100644 --- a/src/emu/bus/bus.mak +++ b/src/emu/bus/bus.mak @@ -1463,3 +1463,15 @@ BUSOBJS += $(BUSOBJ)/wswan/slot.o BUSOBJS += $(BUSOBJ)/wswan/rom.o endif +#------------------------------------------------- +# +#@src/emu/bus/psx/ctlrport.h,BUSES += PSX_CONTROLLER +#------------------------------------------------- + +ifneq ($(filter PSX_CONTROLLER,$(BUSES)),) +OBJDIRS += $(BUSOBJ)/psx +BUSOBJS += $(BUSOBJ)/psx/ctlrport.o +BUSOBJS += $(BUSOBJ)/psx/analogue.o +BUSOBJS += $(BUSOBJ)/psx/multitap.o +BUSOBJS += $(BUSOBJ)/psx/memcard.o +endif diff --git a/src/emu/bus/psx/analogue.c b/src/emu/bus/psx/analogue.c new file mode 100644 index 00000000000..e050d7643f0 --- /dev/null +++ b/src/emu/bus/psx/analogue.c @@ -0,0 +1,262 @@ +#include "analogue.h" + +const device_type PSX_ANALOG_JOYSTICK = &device_creator; +const device_type PSX_DUALSHOCK = &device_creator; + +psx_analog_controller_device::psx_analog_controller_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : + device_t(mconfig, type, name, tag, owner, clock, shortname, source), + device_psx_controller_interface(mconfig, *this), + m_pad0(*this, "PSXPAD0"), + m_pad1(*this, "PSXPAD1"), + m_rstickx(*this, "PSXRSTICKX"), + m_rsticky(*this, "PSXRSTICKY"), + m_lstickx(*this, "PSXLSTICKX"), + m_lsticky(*this, "PSXLSTICKY") +{ +} + +psx_dualshock_device::psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + psx_analog_controller_device(mconfig, PSX_DUALSHOCK, "Playstation Dualshock Pad", tag, owner, clock, "psx_dualshock_pad", __FILE__) +{ + m_type = DUALSHOCK; +} + +psx_analog_joystick_device::psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + psx_analog_controller_device(mconfig, PSX_ANALOG_JOYSTICK, "Playstation Analog Joystick", tag, owner, clock, "psx_analog_joystick", __FILE__) +{ + m_type = JOYSTICK; +} + +void psx_analog_controller_device::device_reset() +{ + m_confmode = false; + m_analogmode = false; + m_analoglock = false; + + m_cmd = 0; +} + +UINT8 psx_analog_controller_device::pad_data(int count, bool analog) +{ + UINT8 data = 0; + switch(count) + { + case 2: + data = m_pad0->read(); + if(!analog || (m_type == JOYSTICK)) + data |= 6; // l3/r3 + break; + case 3: + data = m_pad1->read(); + break; + case 4: + data = m_rstickx->read(); + break; + case 5: + data = m_rsticky->read(); + break; + case 6: + data = m_lstickx->read(); + break; + case 7: + data = m_lsticky->read(); + break; + } + return data; +} + +bool psx_analog_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata) +{ + if(m_confmode) + { + switch(count) + { + case 0: + m_temp = 0; + *odata = 0xf3; + break; + case 1: + m_cmd = idata; + if((m_cmd & 0xf0) != 0x40) + return false; + *odata = 0x5a; + break; + default: + switch(m_cmd) + { + default: // 40,41,48,49,4a,4b,4f -- all unknown + *odata = 0x00; + break; + case CONFIG_MODE: // 43 + if(count == 3) + m_temp = idata; + /* no break */ + case QUERY_PAD_STATE: // 42 + *odata = pad_data(count, true); + break; + case 0x44: // set mode and lock ? + switch(count) + { + case 3: + m_analogmode = idata ? true : false; // only 0x01 ? + break; + case 4: + m_analoglock = idata ? true : false; // only 0x03 ? + break; + } + *odata = 0x00; + break; + case 0x45: // get mode ? + { + const UINT8 val[] = { 1, 2, 0, 2, 1, 0 }; + if(count == 4) + *odata = m_analogmode; + else + *odata = val[count-2]; + break; + } + case 0x46: // query act (vibrate) ? + { + const UINT8 val[2][6] = {{ 0, 0, 1, 2, 0, 10 }, + { 0, 0, 1, 1, 1, 14 }}; + *odata = val[m_temp][count-2]; + if(count == 3) + m_temp = idata ? 1 : 0; + break; + } + case 0x47: // query comb (combination?) ? + { + const UINT8 val[] = { 0, 0, 2, 0, 1, 0 }; + *odata = val[count-2]; + break; + } + case 0x4c: // query mode ? + switch(count) + { + case 3: + m_temp = idata; + /* no break */ + default: + *odata = 0x00; + break; + case 5: + *odata = m_analogmode ? 0x07 : 0x04; // ? + break; + } + break; + case 0x4d: // set act (vibrate) ? + *odata = 0xff; + break; + } + break; + case 8: + if(m_cmd == CONFIG_MODE) + m_confmode = m_temp; + return false; + } + } + else if(m_analogmode) + { + switch(count) + { + case 0: + if(m_type == JOYSTICK) + *odata = 0x53; + else + *odata = 0x73; + break; + case 1: + m_cmd = idata; + if((m_cmd & 0xfe) != QUERY_PAD_STATE) + return false; + *odata = 0x5a; + break; + case 3: + if(m_cmd == CONFIG_MODE) + m_temp = idata; + /* no break */ + default: + *odata = pad_data(count, true); + break; + case 8: + if(m_cmd == CONFIG_MODE) + m_confmode = m_temp; + return false; + } + } + else + { + switch(count) + { + case 0: + *odata = 0x41; + break; + case 1: + m_cmd = idata; + if((m_cmd & 0xfe) != QUERY_PAD_STATE) + return false; + *odata = 0x5a; + break; + case 3: + if(m_cmd == CONFIG_MODE) + m_temp = idata; + /* no break */ + default: + *odata = pad_data(count, false); + break; + case 4: + if(m_cmd == CONFIG_MODE) + m_confmode = m_temp; + return false; + } + } + return true; +} + +static INPUT_PORTS_START( psx_analog_controller ) + PORT_START("PSXPAD0") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME("R3") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME("L3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT ) + + PORT_START("PSXPAD1") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2") + + PORT_START("PSXRSTICKX") + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_NAME("Right Analog X") PORT_SENSITIVITY(100) + + PORT_START("PSXRSTICKY") + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_NAME("Right Analog Y") PORT_SENSITIVITY(100) + + PORT_START("PSXLSTICKX") + PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Z ) PORT_NAME("Left Analog X") PORT_SENSITIVITY(100) + + PORT_START("PSXLSTICKY") + PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_NAME("Left Analog Y") PORT_SENSITIVITY(100) + + PORT_START("PSXMISC") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_NAME("Analog") PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, psx_analog_controller_device, change_mode, 0) +INPUT_PORTS_END + +ioport_constructor psx_analog_controller_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(psx_analog_controller); +} + +INPUT_CHANGED_MEMBER(psx_analog_controller_device::change_mode) +{ + if(!m_analoglock) + m_analogmode = newval; +} diff --git a/src/emu/bus/psx/analogue.h b/src/emu/bus/psx/analogue.h new file mode 100644 index 00000000000..4b73d7cffc5 --- /dev/null +++ b/src/emu/bus/psx/analogue.h @@ -0,0 +1,55 @@ +#ifndef PSXANALOG_H_ +#define PSXANALOG_H_ + +#include "ctlrport.h" + +extern const device_type PSX_DUALSHOCK; +extern const device_type PSX_ANALOG_JOYSTICK; + +class psx_analog_controller_device : public device_t, + public device_psx_controller_interface +{ +public: + psx_analog_controller_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); + + virtual ioport_constructor device_input_ports() const; + DECLARE_INPUT_CHANGED_MEMBER(change_mode); +protected: + virtual void device_reset(); + virtual void device_start() {} + enum { + JOYSTICK, + DUALSHOCK + } m_type; +private: + virtual bool get_pad(int count, UINT8 *odata, UINT8 idata); + UINT8 pad_data(int count, bool analog); + + bool m_confmode; + bool m_analogmode; + bool m_analoglock; + + UINT8 m_temp; + UINT8 m_cmd; + + required_ioport m_pad0; + required_ioport m_pad1; + required_ioport m_rstickx; + required_ioport m_rsticky; + required_ioport m_lstickx; + required_ioport m_lsticky; +}; + +class psx_dualshock_device : public psx_analog_controller_device +{ +public: + psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + +class psx_analog_joystick_device : public psx_analog_controller_device +{ +public: + psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); +}; + +#endif /* PSXANALOG_H_ */ diff --git a/src/emu/bus/psx/ctlrport.c b/src/emu/bus/psx/ctlrport.c new file mode 100644 index 00000000000..70d09fbffd9 --- /dev/null +++ b/src/emu/bus/psx/ctlrport.c @@ -0,0 +1,219 @@ +/* PAD emulation */ + +#include "ctlrport.h" +#include "analogue.h" +#include "multitap.h" + +const device_type PSX_CONTROLLER_PORT = &device_creator; + +psx_controller_port_device::psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, PSX_CONTROLLER_PORT, "Playstation Controller Port", tag, owner, clock, "psx_controller_port", __FILE__), + device_slot_interface(mconfig, *this), + m_card(*this, "card") +{ +} + +void psx_controller_port_device::device_config_complete() +{ + m_dev = dynamic_cast(get_card_device()); +} + +static MACHINE_CONFIG_FRAGMENT( psx_memory_card ) + MCFG_PSXCARD_ADD("card") +MACHINE_CONFIG_END + +machine_config_constructor psx_controller_port_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( psx_memory_card ); +} + +void psx_controller_port_device::disable_card(bool state) +{ + if(state) + popmessage("Memory card port %s is disabled\n", m_card->brief_instance_name()); + + m_card->disable(state); +} + +const device_type PSXCONTROLLERPORTS = &device_creator; + +psxcontrollerports_device::psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + psxsiodev_device(mconfig, PSXCONTROLLERPORTS, "PSXCONTROLLERPORTS", tag, owner, clock, "psxcontrollerports", __FILE__) +{ +} + +void psxcontrollerports_device::device_start() +{ + m_port0 = machine().device("port1"); + m_port1 = machine().device("port2"); + m_port0->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this)); + m_port1->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this)); + psxsiodev_device::device_start(); +} + +// add controllers to define so they can be connected to the multitap +#define PSX_CONTROLLERS \ + SLOT_INTERFACE("digital_pad", PSX_STANDARD_CONTROLLER) \ + SLOT_INTERFACE("dualshock_pad", PSX_DUALSHOCK) \ + SLOT_INTERFACE("analog_joystick", PSX_ANALOG_JOYSTICK) + +SLOT_INTERFACE_START(psx_controllers) + PSX_CONTROLLERS + SLOT_INTERFACE("multitap", PSX_MULTITAP) +SLOT_INTERFACE_END + +SLOT_INTERFACE_START(psx_controllers_nomulti) + PSX_CONTROLLERS +SLOT_INTERFACE_END + +void psxcontrollerports_device::data_in( int data, int mask ) +{ + m_port0->sel_w((data & PSX_SIO_OUT_DTR)?1:0); + m_port0->tx_w((data & PSX_SIO_OUT_DATA)?1:0); + m_port0->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0); // clock must be last + + m_port1->tx_w((data & PSX_SIO_OUT_DATA)?1:0); + m_port1->sel_w((data & PSX_SIO_OUT_DTR)?0:1); // not dtr + m_port1->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0); + + data_out(((m_port0->rx_r() && m_port1->rx_r()) * PSX_SIO_IN_DATA), PSX_SIO_IN_DATA); +} + +void psxcontrollerports_device::ack() +{ + data_out((!(m_port0->ack_r() && m_port1->ack_r()) * PSX_SIO_IN_DSR), PSX_SIO_IN_DSR); +} + +device_psx_controller_interface::device_psx_controller_interface(const machine_config &mconfig, device_t &device) : + device_slot_card_interface(mconfig, device), + m_ack(true) +{ +} + +device_psx_controller_interface::~device_psx_controller_interface() +{ +} + +void device_psx_controller_interface::interface_pre_reset() +{ + m_bit = 0; + m_count = 0; + m_idata = 0; + m_memcard = false; + + m_clock = true; + m_sel = true; + m_rx = true; + m_ack = true; + m_owner->ack(); +} + +void device_psx_controller_interface::interface_pre_start() +{ + m_owner = dynamic_cast(device().owner()); + m_ack_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_psx_controller_interface::ack_timer), this)); +} + +void device_psx_controller_interface::ack_timer(void *ptr, int param) +{ + m_ack = param; + m_owner->ack(); + + if(!param) + m_ack_timer->adjust(attotime::from_usec(2), 1); +} + +void device_psx_controller_interface::do_pad() +{ + if(!m_bit) + { + if(!m_count) + m_odata = 0xff; + m_idata = 0; + } + + m_rx = (m_odata & (1 << m_bit)) ? true : false; + m_idata |= (m_owner->tx_r()?1:0) << m_bit; + m_bit = (m_bit + 1) % 8; + + if(!m_bit) + { + if((!m_count) && (m_idata & 0xf0)) + { + m_memcard = true; + return; + } + + if(get_pad(m_count++, &m_odata, m_idata)) + m_ack_timer->adjust(attotime::from_usec(10), 0); + else + m_count = 0; + } +} + +void device_psx_controller_interface::sel_w(bool state) { + if(state && !m_sel) + interface_pre_reset(); // don't reset the controller, just the interface + m_sel = state; +} + +const device_type PSX_STANDARD_CONTROLLER = &device_creator; + +psx_standard_controller_device::psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, PSX_STANDARD_CONTROLLER, "Playstation Standard Controller", tag, owner, clock, "psx_standard_controller", __FILE__), + device_psx_controller_interface(mconfig, *this), + m_pad0(*this,"PSXPAD0"), + m_pad1(*this,"PSXPAD1") +{ +} + +bool psx_standard_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata) +{ + switch(count) + { + case 0: + *odata = 0x41; + break; + case 1: + if(idata != QUERY_PAD_STATE) + return false; + *odata = 0x5a; + break; + case 2: + *odata = m_pad0->read(); + break; + case 3: + *odata = m_pad1->read(); + break; + case 4: + return false; + } + return true; +} + +static INPUT_PORTS_START( psx_standard_controller ) + PORT_START("PSXPAD0") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT ) + + PORT_START("PSXPAD1") + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square") + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross") + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle") + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle") + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1") + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1") + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2") +INPUT_PORTS_END + +ioport_constructor psx_standard_controller_device::device_input_ports() const +{ + return INPUT_PORTS_NAME(psx_standard_controller); +} diff --git a/src/emu/bus/psx/ctlrport.h b/src/emu/bus/psx/ctlrport.h new file mode 100644 index 00000000000..c0a556f114b --- /dev/null +++ b/src/emu/bus/psx/ctlrport.h @@ -0,0 +1,130 @@ +#pragma once + +#ifndef __PSXCPORT_H__ +#define __PSXCPORT_H__ + +#include "cpu/psx/siodev.h" +#include "memcard.h" + +#define MCFG_PSX_CTRL_PORT_ADD(_tag, _slot_intf, _def_slot) \ + MCFG_DEVICE_ADD(_tag, PSX_CONTROLLER_PORT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) + +SLOT_INTERFACE_EXTERN(psx_controllers); + +extern const device_type PSXCONTROLLERPORTS; +extern const device_type PSX_CONTROLLER_PORT; +extern const device_type PSX_STANDARD_CONTROLLER; + +class psx_controller_port_device; + +class device_psx_controller_interface : public device_slot_card_interface +{ + friend class psx_multitap_device; +public: + device_psx_controller_interface(const machine_config &mconfig, device_t &device); + virtual ~device_psx_controller_interface(); + + void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_memcard) do_pad(); m_clock = state; } + void sel_w(bool state); + + bool rx_r() { return m_rx; } + bool ack_r() { return m_ack; } + +protected: + virtual void interface_pre_reset(); + virtual void interface_pre_start(); + + enum + { + QUERY_PAD_STATE = 0x42, + CONFIG_MODE = 0x43, + }; + +private: + virtual bool get_pad(int count, UINT8 *odata, UINT8 idata) = 0; + virtual void do_pad(); + void ack_timer(void *ptr, int param); + + UINT8 m_odata; + UINT8 m_idata; + int m_bit; + int m_count; + bool m_memcard; + + bool m_clock; + bool m_sel; + bool m_ack; + bool m_rx; + + emu_timer *m_ack_timer; + psx_controller_port_device *m_owner; +}; + +class psx_standard_controller_device : public device_t, + public device_psx_controller_interface +{ +public: + psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual ioport_constructor device_input_ports() const; + +protected: + virtual void device_start() { } +private: + virtual bool get_pad(int count, UINT8 *odata, UINT8 idata); + + required_ioport m_pad0; + required_ioport m_pad1; +}; + +class psxcontrollerports_device : public psxsiodev_device +{ +public: + psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + void ack(); + +protected: + virtual void device_start(); + +private: + virtual void data_in(int data, int mask); + + psx_controller_port_device *m_port0; + psx_controller_port_device *m_port1; +}; + +class psx_controller_port_device : public device_t, + public device_slot_interface +{ +public: + psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual machine_config_constructor device_mconfig_additions() const; + + typedef delegate void_cb; + void ack() { if(!ack_cb.isnull()) ack_cb(); } + void setup_ack_cb(void_cb cb) { ack_cb = cb; } + + DECLARE_WRITE_LINE_MEMBER(tx_w) { m_tx = state; } + DECLARE_WRITE_LINE_MEMBER(sel_w) { if(m_dev) m_dev->sel_w(state); m_card->sel_w(state); } + DECLARE_WRITE_LINE_MEMBER(clock_w) { if(m_dev) m_dev->clock_w(state); m_card->clock_w(state); } + + DECLARE_READ_LINE_MEMBER(rx_r) { return (m_dev?m_dev->rx_r():true) && m_card->rx_r(); } + DECLARE_READ_LINE_MEMBER(ack_r) { return (m_dev?m_dev->ack_r():true) && m_card->ack_r(); } + DECLARE_READ_LINE_MEMBER(tx_r) { return m_tx; } + + void disable_card(bool status); + +protected: + virtual void device_start() {} + virtual void device_reset() { m_tx = true; } + virtual void device_config_complete(); + +private: + void_cb ack_cb; + bool m_tx; + + device_psx_controller_interface *m_dev; + required_device m_card; +}; +#endif diff --git a/src/emu/bus/psx/memcard.c b/src/emu/bus/psx/memcard.c new file mode 100644 index 00000000000..6db61c85740 --- /dev/null +++ b/src/emu/bus/psx/memcard.c @@ -0,0 +1,363 @@ +/* + psxcard.c - Sony PlayStation memory card device + + by pSXAuthor + MESS conversion by R. Belmont +*/ + +#include "emu.h" +#include "memcard.h" +#include "ctlrport.h" + +// +// +// + +//#define debug_card + +// +// +// + +static const int block_size = 128; +static const int card_size = block_size * 1024; + +const device_type PSXCARD = &device_creator; + +enum transfer_states +{ + state_illegal=0, + state_command, + state_cmdack, + state_wait, + state_addr_hi, + state_addr_lo, + state_read, + state_write, + state_writeack_2, + state_writechk, + state_end +}; + +psxcard_device::psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock, "psxcard", __FILE__), + device_image_interface(mconfig, *this) +{ +} + +void psxcard_device::device_start() +{ + m_owner = dynamic_cast(owner()); + m_ack_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(psxcard_device::ack_timer), this)); + + m_ack = true; + m_disabled = false; + + // save state registrations + save_item(NAME(pkt)); + save_item(NAME(pkt_ptr)); + save_item(NAME(pkt_sz)); + save_item(NAME(cmd)); + save_item(NAME(addr)); + save_item(NAME(state)); + save_item(NAME(m_disabled)); + save_item(NAME(m_odata)); + save_item(NAME(m_idata)); + save_item(NAME(m_bit)); + save_item(NAME(m_count)); + save_item(NAME(m_pad)); +} + +void psxcard_device::device_reset() +{ + state = state_illegal; + addr = 0; + + m_bit = 0; + m_count = 0; + m_pad = false; + m_idata = 0; + + m_clock = true; + m_sel = true; + m_rx = true; + m_ack = true; + m_owner->ack(); +} + +void psxcard_device::device_config_complete() +{ + update_names(PSXCARD, "memcard", "mc"); +} + +// +// +// + +bool psxcard_device::transfer(UINT8 to, UINT8 *from) +{ + bool ret=true; + + switch (state) + { + case state_illegal: + if (is_loaded()) + { +// printf("CARD: begin\n"); + state = state_command; + *from = 0x00; + } + else + { + ret = false; + } + break; + + case state_command: + cmd=to; + *from=0x5a; + state=state_cmdack; + break; + + case state_cmdack: + *from=0x5d; + state=state_wait; + break; + + case state_wait: + *from=0x00; + state=state_addr_hi; + break; + + case state_addr_hi: + addr=(to<<8); +// printf("addr_hi: %02x, addr = %x\n", to, addr); + *from=to; + state=state_addr_lo; + break; + + case state_addr_lo: + addr|=(to&0xff); +// printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd); + + switch (cmd) + { + case 'R': // 0x52 + { + pkt[0]=*from=0x5c; + pkt[1]=0x5d; + pkt[2]=(addr>>8); + pkt[3]=(addr&0xff); + read_card(addr,&pkt[4]); + pkt[4+128]=checksum_data(&pkt[2],128+2); + pkt[5+128]=0x47; + pkt_sz=6+128; + pkt_ptr=1; + state=state_read; + break; + } + case 'W': // 0x57 + { + pkt[0]=addr>>8; + pkt[1]=addr&0xff; + pkt_sz=129+2; + pkt_ptr=2; + state=state_write; + *from=to; + break; + } + default: + state=state_illegal; + break; + } + break; + + case state_read: + //assert(to==0); +// printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz); + *from=pkt[pkt_ptr++]; + if (pkt_ptr==pkt_sz) + { + #ifdef debug_card + printf("card: read finished\n"); + #endif + + state=state_end; + } + break; + + case state_write: + *from=to; + pkt[pkt_ptr++]=to; + if (pkt_ptr==pkt_sz) + { + *from=0x5c; + state=state_writeack_2; + } + break; + + case state_writeack_2: + *from=0x5d; + state=state_writechk; + break; + + case state_writechk: + { + unsigned char chk=checksum_data(pkt,128+2); + if (chk==pkt[128+2]) + { + #ifdef debug_card + printf("card: write ok\n"); + #endif + + write_card(addr,pkt+2); + + *from='G'; + } else + { + #ifdef debug_card + printf("card: write fail\n"); + #endif + + *from='N'; + } + state=state_end; + break; + } + + case state_end: + ret = false; + state = state_illegal; + break; + + default: /*assert(0);*/ ret=false; break; + } + + #ifdef debug_card +// printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F'); + #endif + + return ret; +} + +void psxcard_device::read_card(const unsigned short addr, unsigned char *buf) +{ + #ifdef debug_card + printf("card: read block %d\n",addr); + #endif + + if (addr<(card_size/block_size)) + { + fseek(addr*block_size, SEEK_SET); + fread(buf, block_size); + } else + { + memset(buf,0,block_size); + } +} + +// +// +// + +void psxcard_device::write_card(const unsigned short addr, unsigned char *buf) +{ + #ifdef debug_card + printf("card: write block %d\n",addr); + #endif + + if (addr<(card_size/block_size)) + { + fseek(addr*block_size, SEEK_SET); + fwrite(buf, block_size); + } +} + +unsigned char psxcard_device::checksum_data(const unsigned char *buf, const unsigned int sz) +{ + unsigned char chk=*buf++; + int left=sz; + while (--left) chk^=*buf++; + return chk; +} + +bool psxcard_device::call_load() +{ + if(m_disabled) + { + logerror("psxcard: port disabled\n"); + return IMAGE_INIT_FAIL; + } + + if(length() != card_size) + return IMAGE_INIT_FAIL; + return IMAGE_INIT_PASS; +} + +bool psxcard_device::call_create(int format_type, option_resolution *format_options) +{ + UINT8 block[block_size]; + int i, ret; + + if(m_disabled) + { + logerror("psxcard: port disabled\n"); + return IMAGE_INIT_FAIL; + } + + memset(block, '\0', block_size); + for(i = 0; i < (card_size/block_size); i++) + { + ret = fwrite(block, block_size); + if(ret != block_size) + return IMAGE_INIT_FAIL; + } + return IMAGE_INIT_PASS; +} + +void psxcard_device::do_card() +{ + if(!m_bit) + { + m_idata = 0; + if(!m_count) + m_odata = 0xff; + } + + m_rx = (m_odata & (1 << m_bit)) ? true : false; + m_idata |= (m_owner->tx_r()?1:0) << m_bit; + m_bit = (m_bit + 1) % 8; + + if(!m_bit) + { + if((!m_count) && !(m_idata & 0x80)) + { + m_pad = true; + return; + } + + if(transfer(m_idata, &m_odata)) + { + m_count++; + m_ack_timer->adjust(attotime::from_usec(10), 0); + } + else + m_count = 0; + } +} + +void psxcard_device::ack_timer(void *ptr, int param) +{ + m_ack = param; + m_owner->ack(); + + if(!param) + m_ack_timer->adjust(attotime::from_usec(2), 1); +} + +void psxcard_device::sel_w(bool state) +{ + if(state && !m_sel) + reset(); + m_sel = state; +} diff --git a/src/emu/bus/psx/memcard.h b/src/emu/bus/psx/memcard.h new file mode 100644 index 00000000000..7763658770a --- /dev/null +++ b/src/emu/bus/psx/memcard.h @@ -0,0 +1,75 @@ +#pragma once + +#ifndef _PSXCARD_ +#define _PSXCARD_ + +#include "emu.h" + +class psx_controller_port_device; + +#define MCFG_PSXCARD_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, PSXCARD, 0) + +class psxcard_device : public device_t, + public device_image_interface +{ +public: + psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + virtual iodevice_t image_type() const { return IO_MEMCARD; } + + virtual bool is_readable() const { return 1; } + virtual bool is_writeable() const { return 1; } + virtual bool is_creatable() const { return 1; } + virtual bool must_be_loaded() const { return 0; } + virtual bool is_reset_on_load() const { return 0; } + virtual const char *file_extensions() const { return "mc"; } + virtual const option_guide *create_option_guide() const { return NULL; } + + virtual bool call_load(); + virtual bool call_create(int format_type, option_resolution *format_options); + + void disable(bool state) { m_disabled = state; if(state) unload(); } + +private: + unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd; + unsigned short addr; + int state; + bool m_disabled; + + UINT8 m_odata; + UINT8 m_idata; + int m_bit; + int m_count; + bool m_pad; + + bool m_clock; + bool m_sel; + bool m_ack; + bool m_rx; + + emu_timer *m_ack_timer; + psx_controller_port_device *m_owner; + + void read_card(const unsigned short addr, unsigned char *buf); + void write_card(const unsigned short addr, unsigned char *buf); + unsigned char checksum_data(const unsigned char *buf, const unsigned int sz); + void do_card(); + bool transfer(UINT8 to, UINT8 *from); + void ack_timer(void *ptr, int param); + +public: + virtual void device_start(); + virtual void device_reset(); + virtual void device_config_complete(); + + void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_pad) do_card(); m_clock = state; } + void sel_w(bool state); + bool rx_r() { return m_rx; } + bool ack_r() { return m_ack; } +}; + +// device type definition +extern const device_type PSXCARD; + +#endif diff --git a/src/emu/bus/psx/multitap.c b/src/emu/bus/psx/multitap.c new file mode 100644 index 00000000000..8efd8c1d257 --- /dev/null +++ b/src/emu/bus/psx/multitap.c @@ -0,0 +1,273 @@ +// psx multitap emulation + +#include "multitap.h" + +const device_type PSX_MULTITAP = &device_creator; + +psx_multitap_device::psx_multitap_device(const machine_config& mconfig, const char* tag, device_t* owner, UINT32 clock) : + device_t(mconfig, PSX_MULTITAP, "Playstation Multitap", tag, owner, clock, "psx_multitap", __FILE__), + device_psx_controller_interface(mconfig, *this), + m_porta(*this, "a"), + m_portb(*this, "b"), + m_portc(*this, "c"), + m_portd(*this, "d") +{ +} + +static MACHINE_CONFIG_FRAGMENT( psx_multitap ) + MCFG_PSX_CTRL_PORT_ADD("a", psx_controllers_nomulti, "digital_pad") + MCFG_PSX_CTRL_PORT_ADD("b", psx_controllers_nomulti, NULL) + MCFG_PSX_CTRL_PORT_ADD("c", psx_controllers_nomulti, NULL) + MCFG_PSX_CTRL_PORT_ADD("d", psx_controllers_nomulti, NULL) +MACHINE_CONFIG_END + +machine_config_constructor psx_multitap_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( psx_multitap ); +} + +void psx_multitap_device::device_start() +{ + m_porta->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); + m_portb->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); + m_portc->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); + m_portd->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); + m_nextmode = false; + + save_item(NAME(m_activeport)); + save_item(NAME(m_cack)); + save_item(NAME(m_singlemode)); + save_item(NAME(m_nextmode)); + save_item(NAME(m_tapmc)); + save_item(NAME(m_data)); +} + +void psx_multitap_device::interface_pre_reset() +{ + m_activeport = -1; + m_singlemode = m_nextmode; + m_tapmc = false; + m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true; + memset(m_data, 0xff, sizeof(m_data)); + m_porta->sel_w(false); + m_portb->sel_w(false); + m_portc->sel_w(false); + m_portd->sel_w(false); + m_porta->sel_w(true); + m_portb->sel_w(true); + m_portc->sel_w(true); + m_portd->sel_w(true); + device_psx_controller_interface::interface_pre_reset(); +} + +void psx_multitap_device::set_tx_line(bool tx, int port) +{ + psx_controller_port_device *dev; + switch(port) + { + default: + case 0: + dev = m_porta; + break; + case 1: + dev = m_portb; + break; + case 2: + dev = m_portc; + break; + case 3: + dev = m_portd; + break; + } + dev->clock_w(1); + dev->tx_w(tx); + dev->clock_w(0); +} + +bool psx_multitap_device::get_rx_line(int port) +{ + psx_controller_port_device *dev; + switch(port) + { + default: + case 0: + dev = m_porta; + break; + case 1: + dev = m_portb; + break; + case 2: + dev = m_portc; + break; + case 3: + dev = m_portd; + break; + } + return dev->rx_r(); +} + +void psx_multitap_device::do_pad() +{ + bool tx = device_psx_controller_interface::m_owner->tx_r(); + + // we don't know which controller until after the first byte + if((m_singlemode || m_tapmc) && (m_count >= 1)) + { + if((m_count == 2) && !m_bit && !m_tapmc) + m_nextmode = !tx; + + set_tx_line(tx, m_activeport); + m_rx = get_rx_line(m_activeport); + m_bit = (m_bit + 1) % 8; + if(!m_bit) + m_count++; + return; + } + + if(!m_count) + { + // first send the select byte to all devices until we know whether it's accessing + // a controller or memcard + if(!m_bit) + { + m_porta->sel_w(false); + m_portb->sel_w(false); + m_portc->sel_w(false); + m_portd->sel_w(false); + } + device_psx_controller_interface::do_pad(); + set_tx_line(tx, 0); + set_tx_line(tx, 1); + set_tx_line(tx, 2); + set_tx_line(tx, 3); + if(!m_bit) + { + m_count = 1; + m_tapmc = m_memcard; + m_memcard = false; // make sure we still receive clocks + if(m_singlemode || m_tapmc) + { + m_activeport = (m_idata & 0xf) - 1; + m_porta->sel_w((m_activeport == 0) ? false : true); + m_portb->sel_w((m_activeport == 1) ? false : true); + m_portc->sel_w((m_activeport == 2) ? false : true); + m_portd->sel_w((m_activeport == 3) ? false : true); + } + } + return; + } + else if(m_count <= 2) + return device_psx_controller_interface::do_pad(); + else if(m_count < 11) + { + if((m_count == 3) && !m_bit) + m_nextmode = !m_idata; + + if((m_count < 5) && m_cack[0] && m_cack[1] && m_cack[2] && m_cack[3]) + return; // no acks? hang up. + + // all of the ports are polled here, port a is passed though. the data + // from the other ports is stored and can be retrieved at a much higher clock rate + // don't poll a port that is inactive or done + if(!m_cack[0]) + { + set_tx_line(tx, 0); + m_rx = m_porta->rx_r(); + } + else + { + m_rx = true; + m_porta->sel_w(true); + } + + if(!m_cack[1]) + { + set_tx_line(tx, 1); + m_data[0][m_count - 3] &= ~(!m_portb->rx_r() << m_bit); + } + else + m_portb->sel_w(true); + + if(!m_cack[2]) + { + set_tx_line(tx, 2); + m_data[1][m_count - 3] &= ~(!m_portc->rx_r() << m_bit); + } + else + m_portc->sel_w(true); + + if(!m_cack[3]) + { + set_tx_line(tx, 3); + m_data[2][m_count - 3] &= ~(!m_portd->rx_r() << m_bit); + } + else + m_portd->sel_w(true); + } + else if(m_count < 19) + // send stored port b data + m_rx = ((m_data[0][m_count - 11] & (1 << m_bit)) ? 1 : 0); + else if(m_count < 27) + // send stored port c data + m_rx = ((m_data[1][m_count - 19] & (1 << m_bit)) ? 1 : 0); + else + // send stored port d data + m_rx = ((m_data[2][m_count - 27] & (1 << m_bit)) ? 1 : 0); + + if(m_bit == 7) + { + // ports won't ack if they are done + m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true; + if(m_count < 11) + m_ack_timer->adjust(attotime::from_usec(12), 0); // give a bit of time for the ports to ack + else if(m_count < 35) + m_ack_timer->adjust(attotime::from_usec(10), 0); + } + + m_bit = (m_bit + 1) % 8; + if(!m_bit) + m_count++; +} + +bool psx_multitap_device::get_pad(int count, UINT8 *odata, UINT8 idata) +{ + if(!count) + *odata = 0x80; + else + *odata = 0x5a; + return true; +} + +void psx_multitap_device::ack() +{ + if(m_activeport != -1) + { + switch(m_activeport) + { + case 0: + m_ack = m_porta->ack_r(); + break; + case 1: + m_ack = m_portb->ack_r(); + break; + case 2: + m_ack = m_portc->ack_r(); + break; + case 3: + m_ack = m_portd->ack_r(); + break; + default: + return; + } + device_psx_controller_interface::m_owner->ack(); + return; + } + if(!m_porta->ack_r()) + m_cack[0] = false; + if(!m_portb->ack_r()) + m_cack[1] = false; + if(!m_portc->ack_r()) + m_cack[2] = false; + if(!m_portd->ack_r()) + m_cack[3] = false; +} diff --git a/src/emu/bus/psx/multitap.h b/src/emu/bus/psx/multitap.h new file mode 100644 index 00000000000..bfbcac17a04 --- /dev/null +++ b/src/emu/bus/psx/multitap.h @@ -0,0 +1,41 @@ +#ifndef PSXMULTITAP_H_ +#define PSXMULTITAP_H_ + +#include "ctlrport.h" + +SLOT_INTERFACE_EXTERN(psx_controllers_nomulti); + +class psx_multitap_device : public device_t, + public device_psx_controller_interface +{ +public: + psx_multitap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual machine_config_constructor device_mconfig_additions() const; + +protected: + virtual void device_start(); + virtual void device_stop() { device_psx_controller_interface::m_owner->disable_card(false); } + virtual void device_reset() { device_psx_controller_interface::m_owner->disable_card(true); } + virtual void device_config_complete() { m_shortname = "psx_multitap"; } + virtual void interface_pre_reset(); + +private: + virtual bool get_pad(int count, UINT8 *odata, UINT8 idata); + virtual void do_pad(); + void ack(); + void set_tx_line(bool tx, int port); + bool get_rx_line(int port); + + int m_activeport; + bool m_cack[4]; + bool m_singlemode, m_nextmode, m_tapmc; + UINT8 m_data[3][8]; // port a is passed though + required_device m_porta; + required_device m_portb; + required_device m_portc; + required_device m_portd; +}; + +extern const device_type PSX_MULTITAP; + +#endif /* PSXMULTITAP_H_ */ diff --git a/src/mame/drivers/taitogn.c b/src/mame/drivers/taitogn.c index 0855e099d85..16add2b2821 100644 --- a/src/mame/drivers/taitogn.c +++ b/src/mame/drivers/taitogn.c @@ -336,7 +336,7 @@ Type 3 (PCMCIA Compact Flash Adaptor + Compact Flash card, sealed together with #include "machine/intelfsh.h" #include "machine/mb3773.h" #include "machine/rf5c296.h" -#include "machine/znsec.h" +#include "machine/cat702.h" #include "machine/zndip.h" #include "sound/spu.h" #include "video/psx.h" @@ -346,8 +346,8 @@ class taitogn_state : public driver_device public: taitogn_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_znsec0(*this,"maincpu:sio0:znsec0"), - m_znsec1(*this,"maincpu:sio0:znsec1"), + m_cat702_1(*this,"maincpu:sio0:cat702_1"), + m_cat702_2(*this,"maincpu:sio0:cat702_2"), m_zndip(*this,"maincpu:sio0:zndip"), m_maincpu(*this, "maincpu"), m_mn10200(*this, "mn10200"), @@ -384,8 +384,8 @@ protected: virtual void machine_reset(); private: - required_device m_znsec0; - required_device m_znsec1; + required_device m_cat702_1; + required_device m_cat702_2; required_device m_zndip; required_device m_maincpu; required_device m_mn10200; @@ -511,8 +511,8 @@ READ8_MEMBER(taitogn_state::znsecsel_r) WRITE8_MEMBER(taitogn_state::znsecsel_w) { - m_znsec0->select( ( data >> 2 ) & 1 ); - m_znsec1->select( ( data >> 3 ) & 1 ); + m_cat702_1->select( ( data >> 2 ) & 1 ); + m_cat702_2->select( ( data >> 3 ) & 1 ); m_zndip->select( ( data & 0x8c ) != 0x8c ); m_n_znsecsel = data; @@ -579,8 +579,8 @@ READ32_MEMBER(taitogn_state::zsg2_ext_r) void taitogn_state::driver_start() { - m_znsec0->init(tt10); - m_znsec1->init(tt16); + m_cat702_1->init(tt10); + m_cat702_2->init(tt16); } void taitogn_state::machine_reset() @@ -657,8 +657,8 @@ static MACHINE_CONFIG_START( coh3002t, taitogn_state ) MCFG_RAM_MODIFY("maincpu:ram") MCFG_RAM_DEFAULT_SIZE("4M") - MCFG_DEVICE_ADD("maincpu:sio0:znsec0", ZNSEC, 0) - MCFG_DEVICE_ADD("maincpu:sio0:znsec1", ZNSEC, 0) + MCFG_DEVICE_ADD("maincpu:sio0:cat702_1", CAT702, 0) + MCFG_DEVICE_ADD("maincpu:sio0:cat702_2", CAT702, 0) MCFG_DEVICE_ADD("maincpu:sio0:zndip", ZNDIP, 0) MCFG_ZNDIP_DATA_HANDLER(IOPORT(":DSW")) diff --git a/src/mame/drivers/zn.c b/src/mame/drivers/zn.c index e71c2e7661a..ca9a53d0bff 100644 --- a/src/mame/drivers/zn.c +++ b/src/mame/drivers/zn.c @@ -17,7 +17,7 @@ #include "machine/nvram.h" #include "machine/mb3773.h" #include "machine/7200fifo.h" -#include "machine/znsec.h" +#include "machine/cat702.h" #include "machine/zndip.h" #include "machine/ataintf.h" #include "machine/vt83c461.h" @@ -38,8 +38,8 @@ public: driver_device(mconfig, type, tag), m_gpu(*this, "gpu"), m_gpu_screen(*this, "gpu:screen"), - m_znsec0(*this,"maincpu:sio0:znsec0"), - m_znsec1(*this,"maincpu:sio0:znsec1"), + m_cat702_1(*this,"maincpu:sio0:cat702_1"), + m_cat702_2(*this,"maincpu:sio0:cat702_2"), m_zndip(*this,"maincpu:sio0:zndip"), m_maincpu(*this, "maincpu"), m_audiocpu(*this, "audiocpu"), @@ -124,8 +124,8 @@ private: required_device m_gpu; required_device m_gpu_screen; - required_device m_znsec0; - required_device m_znsec1; + required_device m_cat702_1; + required_device m_cat702_2; required_device m_zndip; required_device m_maincpu; optional_device m_audiocpu; @@ -333,8 +333,8 @@ WRITE8_MEMBER(zn_state::znsecsel_w) { verboselog(2, "znsecsel_w( %08x, %08x, %08x )\n", offset, data, mem_mask ); - m_znsec0->select( ( data >> 2 ) & 1 ); - m_znsec1->select( ( data >> 3 ) & 1 ); + m_cat702_1->select( ( data >> 2 ) & 1 ); + m_cat702_2->select( ( data >> 3 ) & 1 ); m_zndip->select( ( data & 0x8c ) != 0x8c ); m_n_znsecsel = data; @@ -432,8 +432,8 @@ void zn_state::driver_start() { if( strcmp( machine().system().name, zn_config_table[ n_game ].s_name ) == 0 ) { - m_znsec0->init( zn_config_table[ n_game ].p_n_mainsec ); - m_znsec1->init( zn_config_table[ n_game ].p_n_gamesec ); + m_cat702_1->init( zn_config_table[ n_game ].p_n_mainsec ); + m_cat702_2->init( zn_config_table[ n_game ].p_n_gamesec ); break; } n_game++; @@ -449,8 +449,8 @@ static MACHINE_CONFIG_START( zn1_1mb_vram, zn_state ) MCFG_RAM_MODIFY("maincpu:ram") MCFG_RAM_DEFAULT_SIZE("4M") - MCFG_DEVICE_ADD("maincpu:sio0:znsec0", ZNSEC, 0) - MCFG_DEVICE_ADD("maincpu:sio0:znsec1", ZNSEC, 0) + MCFG_DEVICE_ADD("maincpu:sio0:cat702_1", CAT702, 0) + MCFG_DEVICE_ADD("maincpu:sio0:cat702_2", CAT702, 0) MCFG_DEVICE_ADD("maincpu:sio0:zndip", ZNDIP, 0) MCFG_ZNDIP_DATA_HANDLER(IOPORT(":DSW")) @@ -483,8 +483,8 @@ static MACHINE_CONFIG_START( zn2, zn_state ) MCFG_RAM_MODIFY("maincpu:ram") MCFG_RAM_DEFAULT_SIZE("4M") - MCFG_DEVICE_ADD("maincpu:sio0:znsec0", ZNSEC, 0) - MCFG_DEVICE_ADD("maincpu:sio0:znsec1", ZNSEC, 0) + MCFG_DEVICE_ADD("maincpu:sio0:cat702_1", CAT702, 0) + MCFG_DEVICE_ADD("maincpu:sio0:cat702_2", CAT702, 0) MCFG_DEVICE_ADD("maincpu:sio0:zndip", ZNDIP, 0) MCFG_ZNDIP_DATA_HANDLER(IOPORT(":DSW")) diff --git a/src/mame/machine/cat702.c b/src/mame/machine/cat702.c new file mode 100644 index 00000000000..8c362e65267 --- /dev/null +++ b/src/mame/machine/cat702.c @@ -0,0 +1,201 @@ +/* + + CAT702 ZN security chip + + A serial magic latch. + + It's a DIP20 chip with a sticker of the form XXnn, where XX is the + company and nn a number: + AC = Acclaim + AT = Atlus + CP = Capcom + ET = Raizing + KN = Konami + MG = Tecmo + TT = Taito + TW = Atari + + There usually are 2 of them, one on the cpu board and one on the rom + board. The cpu board one is usually numbered 01. + + Pinout: GND -11 10- GND + ? -12 9- +5V + +5V -13 8- Data in + Data out- 14 7- Clock + +5V -15 6- Select + ? -16 5- Select + +5V -17 4- +5V + +5V -18 3- +5V + +5V -19 2- +5V + +5V -20 1- ? + + The chip works with the '?' lines left unconnected. + + The communication protocol is serial, and in practice the standard + psx controller communication protocol minus the ack. Drive both + select to ground to start a communication, send bits and get the + results on the raising clock. Put both select back to +5V when + finished. The bios seems to use two communication clock speeds, + ~300KHz (standard psx) and ~2MHz. Driving it with lower clocks + works reasonably, at least at 1KHz. + + The data is divided in bytes but there is no signal for end-of-byte. + In all of the following the data will be considered coming and going + lower-bit first. + + Internally the chip has a 8-bit state, initialized at communication + start to 0xfc. The structure is simple: + + + +---------+ bit number +--------+ + Clock ------->| bit |-----+-------------------->| bit |---------> Data out + | counter | | | select | + +---------+ v +-------+ out | | + | +-----+ | 8bit |=====>| | + Data in ------------|------->| TF1 |<=>| state | +--------+ + | +-----+ | | + | | | + | start +-----+ | | + +------->| TF2 |<=>| | + +-----+ +-------+ + + The chip starts by tranforming the state with TF2. Then, for each + input bit from 0 to 7: + - the nth bit from the state is sent to the output + - the state is transformed by TF1 if the input bit is 0 + + TF2 is a fixed linear substitution box (* = and, + = xor): + o = ff*s0 + fe*s1 + fc*s2 + f8*s3 + f0*s4 + e0*s5 + c0*s6 + 7f*s7 + + TF1 is a chip-dependent set of 8 linear sboxes, one per bit number. + In practice, only the sbox for bit 0 is defined for the chip, the 7 + other are derived from it. Defining the byte transformation Shift + as: + Shift(i7..i0) = i6..i0, i7^i6 + + and noting the sboxes as: + Sbox(n, i7..i0) = Xor( c[n, bit]*i[bit]) + 0<=bit<=7 + then + c[n, bit=0..6] = Shift(c[n-1, (bit-1)&7]) + c[n, 7] = Shift(c[n-1, 6])^c[n, 0] + = Shift(c[n-1, 6])^Shift(c[n-1, 7]) +*/ + +#include "cat702.h" + +const device_type CAT702 = &device_creator; + +cat702_device::cat702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + psxsiodev_device(mconfig, CAT702, "CAT702", tag, owner, clock, "cat702", __FILE__) +{ +} + +void cat702_device::device_start() +{ + psxsiodev_device::device_start(); + + save_item(NAME(m_select)); + save_item(NAME(m_state)); + save_item(NAME(m_bit)); +} + +// Given the value for x7..x0 and linear transform coefficients a7..a0 +// compute the value of the transform +#if 0 +static int c_linear(UINT8 x, UINT8 a) +{ + int i; + UINT8 r; + x &= a; + r = 0; + for(i=0; i<8; i++) + if(x & (1<> 7)^(r >> 6)) & 1); + if(bit != 7) + return r; + + return r ^ compute_sbox_coef(sel, 0); +} + +// Apply the sbox for a input 0 bit +void cat702_device::apply_bit_sbox(int sel) +{ + int i; + UINT8 r = 0; + for(i=0; i<8; i++) + if(m_state & (1<> m_bit) & 1) != 0 ? PSX_SIO_IN_DATA : 0, PSX_SIO_IN_DATA); + + if((data & PSX_SIO_OUT_DATA)==0) + apply_bit_sbox(m_bit); + + m_bit++; + m_bit&=7; + } +} diff --git a/src/mame/machine/cat702.h b/src/mame/machine/cat702.h new file mode 100644 index 00000000000..57610327289 --- /dev/null +++ b/src/mame/machine/cat702.h @@ -0,0 +1,36 @@ +/* CAT702 ZN security chip */ + +#pragma once + +#ifndef __CAT702_H__ +#define __CAT702_H__ + +#include "cpu/psx/siodev.h" + +extern const device_type CAT702; + +class cat702_device : public psxsiodev_device +{ +public: + cat702_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + void init(const UINT8 *transform); + void select(int select); + +protected: + virtual void device_start(); + +private: + virtual void data_in( int data, int mask ); + + UINT8 compute_sbox_coef(int sel, int bit); + void apply_bit_sbox(int sel); + void apply_sbox(const UINT8 *sbox); + + const UINT8 *m_transform; + int m_select; + UINT8 m_state; + UINT8 m_bit; +}; + +#endif diff --git a/src/mame/machine/znsec.c b/src/mame/machine/znsec.c deleted file mode 100644 index 22ba75c74ed..00000000000 --- a/src/mame/machine/znsec.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - - CAT702 ZN security chip - - A serial magic latch. - - It's a DIP20 chip with a sticker of the form XXnn, where XX is the - company and nn a number: - AC = Acclaim - AT = Atlus - CP = Capcom - ET = Raizing - KN = Konami - MG = Tecmo - TT = Taito - TW = Atari - - There usually are 2 of them, one on the cpu board and one on the rom - board. The cpu board one is usually numbered 01. - - Pinout: GND -11 10- GND - ? -12 9- +5V - +5V -13 8- Data in - Data out- 14 7- Clock - +5V -15 6- Select - ? -16 5- Select - +5V -17 4- +5V - +5V -18 3- +5V - +5V -19 2- +5V - +5V -20 1- ? - - The chip works with the '?' lines left unconnected. - - The communication protocol is serial, and in practice the standard - psx controller communication protocol minus the ack. Drive both - select to ground to start a communication, send bits and get the - results on the raising clock. Put both select back to +5V when - finished. The bios seems to use two communication clock speeds, - ~300KHz (standard psx) and ~2MHz. Driving it with lower clocks - works reasonably, at least at 1KHz. - - The data is divided in bytes but there is no signal for end-of-byte. - In all of the following the data will be considered coming and going - lower-bit first. - - Internally the chip has a 8-bit state, initialized at communication - start to 0xfc. The structure is simple: - - - +---------+ bit number +--------+ - Clock ------->| bit |-----+-------------------->| bit |---------> Data out - | counter | | | select | - +---------+ v +-------+ out | | - | +-----+ | 8bit |=====>| | - Data in ------------|------->| TF1 |<=>| state | +--------+ - | +-----+ | | - | | | - | start +-----+ | | - +------->| TF2 |<=>| | - +-----+ +-------+ - - The chip starts by tranforming the state with TF2. Then, for each - input bit from 0 to 7: - - the nth bit from the state is sent to the output - - the state is transformed by TF1 if the input bit is 0 - - TF2 is a fixed linear substitution box (* = and, + = xor): - o = ff*s0 + fe*s1 + fc*s2 + f8*s3 + f0*s4 + e0*s5 + c0*s6 + 7f*s7 - - TF1 is a chip-dependent set of 8 linear sboxes, one per bit number. - In practice, only the sbox for bit 0 is defined for the chip, the 7 - other are derived from it. Defining the byte transformation Shift - as: - Shift(i7..i0) = i6..i0, i7^i6 - - and noting the sboxes as: - Sbox(n, i7..i0) = Xor( c[n, bit]*i[bit]) - 0<=bit<=7 - then - c[n, bit=0..6] = Shift(c[n-1, (bit-1)&7]) - c[n, 7] = Shift(c[n-1, 6])^c[n, 0] - = Shift(c[n-1, 6])^Shift(c[n-1, 7]) -*/ - -#include "znsec.h" - -const device_type ZNSEC = &device_creator; - -znsec_device::znsec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - psxsiodev_device(mconfig, ZNSEC, "ZNSEC", tag, owner, clock, "znsec", __FILE__) -{ -} - -void znsec_device::device_start() -{ - psxsiodev_device::device_start(); - - save_item(NAME(m_select)); - save_item(NAME(m_state)); - save_item(NAME(m_bit)); -} - -// Given the value for x7..x0 and linear transform coefficients a7..a0 -// compute the value of the transform -#if 0 -static int c_linear(UINT8 x, UINT8 a) -{ - int i; - UINT8 r; - x &= a; - r = 0; - for(i=0; i<8; i++) - if(x & (1<> 7)^(r >> 6)) & 1); - if(bit != 7) - return r; - - return r ^ compute_sbox_coef(sel, 0); -} - -// Apply the sbox for a input 0 bit -void znsec_device::apply_bit_sbox(int sel) -{ - int i; - UINT8 r = 0; - for(i=0; i<8; i++) - if(m_state & (1<> m_bit) & 1) != 0 ? PSX_SIO_IN_DATA : 0, PSX_SIO_IN_DATA); - - if((data & PSX_SIO_OUT_DATA)==0) - apply_bit_sbox(m_bit); - - m_bit++; - m_bit&=7; - } -} diff --git a/src/mame/machine/znsec.h b/src/mame/machine/znsec.h deleted file mode 100644 index f19ee859374..00000000000 --- a/src/mame/machine/znsec.h +++ /dev/null @@ -1,36 +0,0 @@ -/* CAT702 ZN security chip */ - -#pragma once - -#ifndef __ZNSEC_H__ -#define __ZNSEC_H__ - -#include "cpu/psx/siodev.h" - -extern const device_type ZNSEC; - -class znsec_device : public psxsiodev_device -{ -public: - znsec_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - void init(const UINT8 *transform); - void select(int select); - -protected: - virtual void device_start(); - -private: - virtual void data_in( int data, int mask ); - - UINT8 compute_sbox_coef(int sel, int bit); - void apply_bit_sbox(int sel); - void apply_sbox(const UINT8 *sbox); - - const UINT8 *m_transform; - int m_select; - UINT8 m_state; - UINT8 m_bit; -}; - -#endif diff --git a/src/mame/mame.mak b/src/mame/mame.mak index c8e7d9f6030..397751bd24b 100644 --- a/src/mame/mame.mak +++ b/src/mame/mame.mak @@ -1817,7 +1817,7 @@ $(MAMEOBJ)/snk.a: \ $(DRIVERS)/snk68.o $(VIDEO)/snk68.o \ $(MAMEOBJ)/sony.a: \ - $(DRIVERS)/zn.o $(MACHINE)/zndip.o $(MACHINE)/znsec.o \ + $(DRIVERS)/zn.o $(MACHINE)/zndip.o $(MACHINE)/cat702.o \ $(MAMEOBJ)/stern.a: \ $(DRIVERS)/astinvad.o \ diff --git a/src/mess/drivers/psx.c b/src/mess/drivers/psx.c index 69f518f7ea5..79fbfa68fdd 100644 --- a/src/mess/drivers/psx.c +++ b/src/mess/drivers/psx.c @@ -17,7 +17,7 @@ #include "debugger.h" #include #include "machine/psxcd.h" -#include "machine/psxcport.h" +#include "bus/psx/ctlrport.h" #define PSXCD_TAG "psxcd" diff --git a/src/mess/machine/psxanalog.c b/src/mess/machine/psxanalog.c deleted file mode 100644 index d53d29672a2..00000000000 --- a/src/mess/machine/psxanalog.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "machine/psxanalog.h" - -const device_type PSX_ANALOG_JOYSTICK = &device_creator; -const device_type PSX_DUALSHOCK = &device_creator; - -psx_analog_controller_device::psx_analog_controller_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source) : - device_t(mconfig, type, name, tag, owner, clock, shortname, source), - device_psx_controller_interface(mconfig, *this), - m_pad0(*this, "PSXPAD0"), - m_pad1(*this, "PSXPAD1"), - m_rstickx(*this, "PSXRSTICKX"), - m_rsticky(*this, "PSXRSTICKY"), - m_lstickx(*this, "PSXLSTICKX"), - m_lsticky(*this, "PSXLSTICKY") -{ -} - -psx_dualshock_device::psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - psx_analog_controller_device(mconfig, PSX_DUALSHOCK, "Playstation Dualshock Pad", tag, owner, clock, "psx_dualshock_pad", __FILE__) -{ - m_type = DUALSHOCK; -} - -psx_analog_joystick_device::psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - psx_analog_controller_device(mconfig, PSX_ANALOG_JOYSTICK, "Playstation Analog Joystick", tag, owner, clock, "psx_analog_joystick", __FILE__) -{ - m_type = JOYSTICK; -} - -void psx_analog_controller_device::device_reset() -{ - m_confmode = false; - m_analogmode = false; - m_analoglock = false; - - m_cmd = 0; -} - -UINT8 psx_analog_controller_device::pad_data(int count, bool analog) -{ - UINT8 data = 0; - switch(count) - { - case 2: - data = m_pad0->read(); - if(!analog || (m_type == JOYSTICK)) - data |= 6; // l3/r3 - break; - case 3: - data = m_pad1->read(); - break; - case 4: - data = m_rstickx->read(); - break; - case 5: - data = m_rsticky->read(); - break; - case 6: - data = m_lstickx->read(); - break; - case 7: - data = m_lsticky->read(); - break; - } - return data; -} - -bool psx_analog_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata) -{ - if(m_confmode) - { - switch(count) - { - case 0: - m_temp = 0; - *odata = 0xf3; - break; - case 1: - m_cmd = idata; - if((m_cmd & 0xf0) != 0x40) - return false; - *odata = 0x5a; - break; - default: - switch(m_cmd) - { - default: // 40,41,48,49,4a,4b,4f -- all unknown - *odata = 0x00; - break; - case CONFIG_MODE: // 43 - if(count == 3) - m_temp = idata; - /* no break */ - case QUERY_PAD_STATE: // 42 - *odata = pad_data(count, true); - break; - case 0x44: // set mode and lock ? - switch(count) - { - case 3: - m_analogmode = idata ? true : false; // only 0x01 ? - break; - case 4: - m_analoglock = idata ? true : false; // only 0x03 ? - break; - } - *odata = 0x00; - break; - case 0x45: // get mode ? - { - const UINT8 val[] = { 1, 2, 0, 2, 1, 0 }; - if(count == 4) - *odata = m_analogmode; - else - *odata = val[count-2]; - break; - } - case 0x46: // query act (vibrate) ? - { - const UINT8 val[2][6] = {{ 0, 0, 1, 2, 0, 10 }, - { 0, 0, 1, 1, 1, 14 }}; - *odata = val[m_temp][count-2]; - if(count == 3) - m_temp = idata ? 1 : 0; - break; - } - case 0x47: // query comb (combination?) ? - { - const UINT8 val[] = { 0, 0, 2, 0, 1, 0 }; - *odata = val[count-2]; - break; - } - case 0x4c: // query mode ? - switch(count) - { - case 3: - m_temp = idata; - /* no break */ - default: - *odata = 0x00; - break; - case 5: - *odata = m_analogmode ? 0x07 : 0x04; // ? - break; - } - break; - case 0x4d: // set act (vibrate) ? - *odata = 0xff; - break; - } - break; - case 8: - if(m_cmd == CONFIG_MODE) - m_confmode = m_temp; - return false; - } - } - else if(m_analogmode) - { - switch(count) - { - case 0: - if(m_type == JOYSTICK) - *odata = 0x53; - else - *odata = 0x73; - break; - case 1: - m_cmd = idata; - if((m_cmd & 0xfe) != QUERY_PAD_STATE) - return false; - *odata = 0x5a; - break; - case 3: - if(m_cmd == CONFIG_MODE) - m_temp = idata; - /* no break */ - default: - *odata = pad_data(count, true); - break; - case 8: - if(m_cmd == CONFIG_MODE) - m_confmode = m_temp; - return false; - } - } - else - { - switch(count) - { - case 0: - *odata = 0x41; - break; - case 1: - m_cmd = idata; - if((m_cmd & 0xfe) != QUERY_PAD_STATE) - return false; - *odata = 0x5a; - break; - case 3: - if(m_cmd == CONFIG_MODE) - m_temp = idata; - /* no break */ - default: - *odata = pad_data(count, false); - break; - case 4: - if(m_cmd == CONFIG_MODE) - m_confmode = m_temp; - return false; - } - } - return true; -} - -static INPUT_PORTS_START( psx_analog_controller ) - PORT_START("PSXPAD0") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON9 ) PORT_NAME("R3") - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON10 ) PORT_NAME("L3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT ) - - PORT_START("PSXPAD1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square") - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross") - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle") - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle") - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1") - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1") - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2") - - PORT_START("PSXRSTICKX") - PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_NAME("Right Analog X") PORT_SENSITIVITY(100) - - PORT_START("PSXRSTICKY") - PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_NAME("Right Analog Y") PORT_SENSITIVITY(100) - - PORT_START("PSXLSTICKX") - PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Z ) PORT_NAME("Left Analog X") PORT_SENSITIVITY(100) - - PORT_START("PSXLSTICKY") - PORT_BIT( 0xff, 0x80, IPT_PADDLE ) PORT_NAME("Left Analog Y") PORT_SENSITIVITY(100) - - PORT_START("PSXMISC") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON11 ) PORT_NAME("Analog") PORT_TOGGLE PORT_CHANGED_MEMBER(DEVICE_SELF, psx_analog_controller_device, change_mode, 0) -INPUT_PORTS_END - -ioport_constructor psx_analog_controller_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(psx_analog_controller); -} - -INPUT_CHANGED_MEMBER(psx_analog_controller_device::change_mode) -{ - if(!m_analoglock) - m_analogmode = newval; -} diff --git a/src/mess/machine/psxanalog.h b/src/mess/machine/psxanalog.h deleted file mode 100644 index 9f0f66bdaa2..00000000000 --- a/src/mess/machine/psxanalog.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef PSXANALOG_H_ -#define PSXANALOG_H_ - -#include "machine/psxcport.h" - -extern const device_type PSX_DUALSHOCK; -extern const device_type PSX_ANALOG_JOYSTICK; - -class psx_analog_controller_device : public device_t, - public device_psx_controller_interface -{ -public: - psx_analog_controller_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source); - - virtual ioport_constructor device_input_ports() const; - DECLARE_INPUT_CHANGED_MEMBER(change_mode); -protected: - virtual void device_reset(); - virtual void device_start() {} - enum { - JOYSTICK, - DUALSHOCK - } m_type; -private: - virtual bool get_pad(int count, UINT8 *odata, UINT8 idata); - UINT8 pad_data(int count, bool analog); - - bool m_confmode; - bool m_analogmode; - bool m_analoglock; - - UINT8 m_temp; - UINT8 m_cmd; - - required_ioport m_pad0; - required_ioport m_pad1; - required_ioport m_rstickx; - required_ioport m_rsticky; - required_ioport m_lstickx; - required_ioport m_lsticky; -}; - -class psx_dualshock_device : public psx_analog_controller_device -{ -public: - psx_dualshock_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); -}; - -class psx_analog_joystick_device : public psx_analog_controller_device -{ -public: - psx_analog_joystick_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); -}; - -#endif /* PSXANALOG_H_ */ diff --git a/src/mess/machine/psxcard.c b/src/mess/machine/psxcard.c deleted file mode 100644 index 1d8f6761313..00000000000 --- a/src/mess/machine/psxcard.c +++ /dev/null @@ -1,363 +0,0 @@ -/* - psxcard.c - Sony PlayStation memory card device - - by pSXAuthor - MESS conversion by R. Belmont -*/ - -#include "emu.h" -#include "psxcard.h" -#include "machine/psxcport.h" - -// -// -// - -//#define debug_card - -// -// -// - -static const int block_size = 128; -static const int card_size = block_size * 1024; - -const device_type PSXCARD = &device_creator; - -enum transfer_states -{ - state_illegal=0, - state_command, - state_cmdack, - state_wait, - state_addr_hi, - state_addr_lo, - state_read, - state_write, - state_writeack_2, - state_writechk, - state_end -}; - -psxcard_device::psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) - : device_t(mconfig, PSXCARD, "Sony PSX Memory Card", tag, owner, clock, "psxcard", __FILE__), - device_image_interface(mconfig, *this) -{ -} - -void psxcard_device::device_start() -{ - m_owner = dynamic_cast(owner()); - m_ack_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(psxcard_device::ack_timer), this)); - - m_ack = true; - m_disabled = false; - - // save state registrations - save_item(NAME(pkt)); - save_item(NAME(pkt_ptr)); - save_item(NAME(pkt_sz)); - save_item(NAME(cmd)); - save_item(NAME(addr)); - save_item(NAME(state)); - save_item(NAME(m_disabled)); - save_item(NAME(m_odata)); - save_item(NAME(m_idata)); - save_item(NAME(m_bit)); - save_item(NAME(m_count)); - save_item(NAME(m_pad)); -} - -void psxcard_device::device_reset() -{ - state = state_illegal; - addr = 0; - - m_bit = 0; - m_count = 0; - m_pad = false; - m_idata = 0; - - m_clock = true; - m_sel = true; - m_rx = true; - m_ack = true; - m_owner->ack(); -} - -void psxcard_device::device_config_complete() -{ - update_names(PSXCARD, "memcard", "mc"); -} - -// -// -// - -bool psxcard_device::transfer(UINT8 to, UINT8 *from) -{ - bool ret=true; - - switch (state) - { - case state_illegal: - if (is_loaded()) - { -// printf("CARD: begin\n"); - state = state_command; - *from = 0x00; - } - else - { - ret = false; - } - break; - - case state_command: - cmd=to; - *from=0x5a; - state=state_cmdack; - break; - - case state_cmdack: - *from=0x5d; - state=state_wait; - break; - - case state_wait: - *from=0x00; - state=state_addr_hi; - break; - - case state_addr_hi: - addr=(to<<8); -// printf("addr_hi: %02x, addr = %x\n", to, addr); - *from=to; - state=state_addr_lo; - break; - - case state_addr_lo: - addr|=(to&0xff); -// printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd); - - switch (cmd) - { - case 'R': // 0x52 - { - pkt[0]=*from=0x5c; - pkt[1]=0x5d; - pkt[2]=(addr>>8); - pkt[3]=(addr&0xff); - read_card(addr,&pkt[4]); - pkt[4+128]=checksum_data(&pkt[2],128+2); - pkt[5+128]=0x47; - pkt_sz=6+128; - pkt_ptr=1; - state=state_read; - break; - } - case 'W': // 0x57 - { - pkt[0]=addr>>8; - pkt[1]=addr&0xff; - pkt_sz=129+2; - pkt_ptr=2; - state=state_write; - *from=to; - break; - } - default: - state=state_illegal; - break; - } - break; - - case state_read: - //assert(to==0); -// printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz); - *from=pkt[pkt_ptr++]; - if (pkt_ptr==pkt_sz) - { - #ifdef debug_card - printf("card: read finished\n"); - #endif - - state=state_end; - } - break; - - case state_write: - *from=to; - pkt[pkt_ptr++]=to; - if (pkt_ptr==pkt_sz) - { - *from=0x5c; - state=state_writeack_2; - } - break; - - case state_writeack_2: - *from=0x5d; - state=state_writechk; - break; - - case state_writechk: - { - unsigned char chk=checksum_data(pkt,128+2); - if (chk==pkt[128+2]) - { - #ifdef debug_card - printf("card: write ok\n"); - #endif - - write_card(addr,pkt+2); - - *from='G'; - } else - { - #ifdef debug_card - printf("card: write fail\n"); - #endif - - *from='N'; - } - state=state_end; - break; - } - - case state_end: - ret = false; - state = state_illegal; - break; - - default: /*assert(0);*/ ret=false; break; - } - - #ifdef debug_card -// printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F'); - #endif - - return ret; -} - -void psxcard_device::read_card(const unsigned short addr, unsigned char *buf) -{ - #ifdef debug_card - printf("card: read block %d\n",addr); - #endif - - if (addr<(card_size/block_size)) - { - fseek(addr*block_size, SEEK_SET); - fread(buf, block_size); - } else - { - memset(buf,0,block_size); - } -} - -// -// -// - -void psxcard_device::write_card(const unsigned short addr, unsigned char *buf) -{ - #ifdef debug_card - printf("card: write block %d\n",addr); - #endif - - if (addr<(card_size/block_size)) - { - fseek(addr*block_size, SEEK_SET); - fwrite(buf, block_size); - } -} - -unsigned char psxcard_device::checksum_data(const unsigned char *buf, const unsigned int sz) -{ - unsigned char chk=*buf++; - int left=sz; - while (--left) chk^=*buf++; - return chk; -} - -bool psxcard_device::call_load() -{ - if(m_disabled) - { - logerror("psxcard: port disabled\n"); - return IMAGE_INIT_FAIL; - } - - if(length() != card_size) - return IMAGE_INIT_FAIL; - return IMAGE_INIT_PASS; -} - -bool psxcard_device::call_create(int format_type, option_resolution *format_options) -{ - UINT8 block[block_size]; - int i, ret; - - if(m_disabled) - { - logerror("psxcard: port disabled\n"); - return IMAGE_INIT_FAIL; - } - - memset(block, '\0', block_size); - for(i = 0; i < (card_size/block_size); i++) - { - ret = fwrite(block, block_size); - if(ret != block_size) - return IMAGE_INIT_FAIL; - } - return IMAGE_INIT_PASS; -} - -void psxcard_device::do_card() -{ - if(!m_bit) - { - m_idata = 0; - if(!m_count) - m_odata = 0xff; - } - - m_rx = (m_odata & (1 << m_bit)) ? true : false; - m_idata |= (m_owner->tx_r()?1:0) << m_bit; - m_bit = (m_bit + 1) % 8; - - if(!m_bit) - { - if((!m_count) && !(m_idata & 0x80)) - { - m_pad = true; - return; - } - - if(transfer(m_idata, &m_odata)) - { - m_count++; - m_ack_timer->adjust(attotime::from_usec(10), 0); - } - else - m_count = 0; - } -} - -void psxcard_device::ack_timer(void *ptr, int param) -{ - m_ack = param; - m_owner->ack(); - - if(!param) - m_ack_timer->adjust(attotime::from_usec(2), 1); -} - -void psxcard_device::sel_w(bool state) -{ - if(state && !m_sel) - reset(); - m_sel = state; -} diff --git a/src/mess/machine/psxcard.h b/src/mess/machine/psxcard.h deleted file mode 100644 index 7763658770a..00000000000 --- a/src/mess/machine/psxcard.h +++ /dev/null @@ -1,75 +0,0 @@ -#pragma once - -#ifndef _PSXCARD_ -#define _PSXCARD_ - -#include "emu.h" - -class psx_controller_port_device; - -#define MCFG_PSXCARD_ADD(_tag) \ - MCFG_DEVICE_ADD(_tag, PSXCARD, 0) - -class psxcard_device : public device_t, - public device_image_interface -{ -public: - psxcard_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - virtual iodevice_t image_type() const { return IO_MEMCARD; } - - virtual bool is_readable() const { return 1; } - virtual bool is_writeable() const { return 1; } - virtual bool is_creatable() const { return 1; } - virtual bool must_be_loaded() const { return 0; } - virtual bool is_reset_on_load() const { return 0; } - virtual const char *file_extensions() const { return "mc"; } - virtual const option_guide *create_option_guide() const { return NULL; } - - virtual bool call_load(); - virtual bool call_create(int format_type, option_resolution *format_options); - - void disable(bool state) { m_disabled = state; if(state) unload(); } - -private: - unsigned char pkt[0x8b], pkt_ptr, pkt_sz, cmd; - unsigned short addr; - int state; - bool m_disabled; - - UINT8 m_odata; - UINT8 m_idata; - int m_bit; - int m_count; - bool m_pad; - - bool m_clock; - bool m_sel; - bool m_ack; - bool m_rx; - - emu_timer *m_ack_timer; - psx_controller_port_device *m_owner; - - void read_card(const unsigned short addr, unsigned char *buf); - void write_card(const unsigned short addr, unsigned char *buf); - unsigned char checksum_data(const unsigned char *buf, const unsigned int sz); - void do_card(); - bool transfer(UINT8 to, UINT8 *from); - void ack_timer(void *ptr, int param); - -public: - virtual void device_start(); - virtual void device_reset(); - virtual void device_config_complete(); - - void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_pad) do_card(); m_clock = state; } - void sel_w(bool state); - bool rx_r() { return m_rx; } - bool ack_r() { return m_ack; } -}; - -// device type definition -extern const device_type PSXCARD; - -#endif diff --git a/src/mess/machine/psxcport.c b/src/mess/machine/psxcport.c deleted file mode 100644 index cfb38c27570..00000000000 --- a/src/mess/machine/psxcport.c +++ /dev/null @@ -1,219 +0,0 @@ -/* PAD emulation */ - -#include "machine/psxcport.h" -#include "machine/psxanalog.h" -#include "machine/psxmultitap.h" - -const device_type PSX_CONTROLLER_PORT = &device_creator; - -psx_controller_port_device::psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - device_t(mconfig, PSX_CONTROLLER_PORT, "Playstation Controller Port", tag, owner, clock, "psx_controller_port", __FILE__), - device_slot_interface(mconfig, *this), - m_card(*this, "card") -{ -} - -void psx_controller_port_device::device_config_complete() -{ - m_dev = dynamic_cast(get_card_device()); -} - -static MACHINE_CONFIG_FRAGMENT( psx_memory_card ) - MCFG_PSXCARD_ADD("card") -MACHINE_CONFIG_END - -machine_config_constructor psx_controller_port_device::device_mconfig_additions() const -{ - return MACHINE_CONFIG_NAME( psx_memory_card ); -} - -void psx_controller_port_device::disable_card(bool state) -{ - if(state) - popmessage("Memory card port %s is disabled\n", m_card->brief_instance_name()); - - m_card->disable(state); -} - -const device_type PSXCONTROLLERPORTS = &device_creator; - -psxcontrollerports_device::psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - psxsiodev_device(mconfig, PSXCONTROLLERPORTS, "PSXCONTROLLERPORTS", tag, owner, clock, "psxcontrollerports", __FILE__) -{ -} - -void psxcontrollerports_device::device_start() -{ - m_port0 = machine().device("port1"); - m_port1 = machine().device("port2"); - m_port0->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this)); - m_port1->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psxcontrollerports_device::ack), this)); - psxsiodev_device::device_start(); -} - -// add controllers to define so they can be connected to the multitap -#define PSX_CONTROLLERS \ - SLOT_INTERFACE("digital_pad", PSX_STANDARD_CONTROLLER) \ - SLOT_INTERFACE("dualshock_pad", PSX_DUALSHOCK) \ - SLOT_INTERFACE("analog_joystick", PSX_ANALOG_JOYSTICK) - -SLOT_INTERFACE_START(psx_controllers) - PSX_CONTROLLERS - SLOT_INTERFACE("multitap", PSX_MULTITAP) -SLOT_INTERFACE_END - -SLOT_INTERFACE_START(psx_controllers_nomulti) - PSX_CONTROLLERS -SLOT_INTERFACE_END - -void psxcontrollerports_device::data_in( int data, int mask ) -{ - m_port0->sel_w((data & PSX_SIO_OUT_DTR)?1:0); - m_port0->tx_w((data & PSX_SIO_OUT_DATA)?1:0); - m_port0->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0); // clock must be last - - m_port1->tx_w((data & PSX_SIO_OUT_DATA)?1:0); - m_port1->sel_w((data & PSX_SIO_OUT_DTR)?0:1); // not dtr - m_port1->clock_w((data & PSX_SIO_OUT_CLOCK)?1:0); - - data_out(((m_port0->rx_r() && m_port1->rx_r()) * PSX_SIO_IN_DATA), PSX_SIO_IN_DATA); -} - -void psxcontrollerports_device::ack() -{ - data_out((!(m_port0->ack_r() && m_port1->ack_r()) * PSX_SIO_IN_DSR), PSX_SIO_IN_DSR); -} - -device_psx_controller_interface::device_psx_controller_interface(const machine_config &mconfig, device_t &device) : - device_slot_card_interface(mconfig, device), - m_ack(true) -{ -} - -device_psx_controller_interface::~device_psx_controller_interface() -{ -} - -void device_psx_controller_interface::interface_pre_reset() -{ - m_bit = 0; - m_count = 0; - m_idata = 0; - m_memcard = false; - - m_clock = true; - m_sel = true; - m_rx = true; - m_ack = true; - m_owner->ack(); -} - -void device_psx_controller_interface::interface_pre_start() -{ - m_owner = dynamic_cast(device().owner()); - m_ack_timer = device().machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(device_psx_controller_interface::ack_timer), this)); -} - -void device_psx_controller_interface::ack_timer(void *ptr, int param) -{ - m_ack = param; - m_owner->ack(); - - if(!param) - m_ack_timer->adjust(attotime::from_usec(2), 1); -} - -void device_psx_controller_interface::do_pad() -{ - if(!m_bit) - { - if(!m_count) - m_odata = 0xff; - m_idata = 0; - } - - m_rx = (m_odata & (1 << m_bit)) ? true : false; - m_idata |= (m_owner->tx_r()?1:0) << m_bit; - m_bit = (m_bit + 1) % 8; - - if(!m_bit) - { - if((!m_count) && (m_idata & 0xf0)) - { - m_memcard = true; - return; - } - - if(get_pad(m_count++, &m_odata, m_idata)) - m_ack_timer->adjust(attotime::from_usec(10), 0); - else - m_count = 0; - } -} - -void device_psx_controller_interface::sel_w(bool state) { - if(state && !m_sel) - interface_pre_reset(); // don't reset the controller, just the interface - m_sel = state; -} - -const device_type PSX_STANDARD_CONTROLLER = &device_creator; - -psx_standard_controller_device::psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : - device_t(mconfig, PSX_STANDARD_CONTROLLER, "Playstation Standard Controller", tag, owner, clock, "psx_standard_controller", __FILE__), - device_psx_controller_interface(mconfig, *this), - m_pad0(*this,"PSXPAD0"), - m_pad1(*this,"PSXPAD1") -{ -} - -bool psx_standard_controller_device::get_pad(int count, UINT8 *odata, UINT8 idata) -{ - switch(count) - { - case 0: - *odata = 0x41; - break; - case 1: - if(idata != QUERY_PAD_STATE) - return false; - *odata = 0x5a; - break; - case 2: - *odata = m_pad0->read(); - break; - case 3: - *odata = m_pad1->read(); - break; - case 4: - return false; - } - return true; -} - -static INPUT_PORTS_START( psx_standard_controller ) - PORT_START("PSXPAD0") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SELECT ) - - PORT_START("PSXPAD1") - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Square") - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Cross") - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Circle") - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("Triangle") - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("R1") - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("L1") - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("R2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("L2") -INPUT_PORTS_END - -ioport_constructor psx_standard_controller_device::device_input_ports() const -{ - return INPUT_PORTS_NAME(psx_standard_controller); -} diff --git a/src/mess/machine/psxcport.h b/src/mess/machine/psxcport.h deleted file mode 100644 index 5059ebc02c1..00000000000 --- a/src/mess/machine/psxcport.h +++ /dev/null @@ -1,130 +0,0 @@ -#pragma once - -#ifndef __PSXCPORT_H__ -#define __PSXCPORT_H__ - -#include "cpu/psx/siodev.h" -#include "machine/psxcard.h" - -#define MCFG_PSX_CTRL_PORT_ADD(_tag, _slot_intf, _def_slot) \ - MCFG_DEVICE_ADD(_tag, PSX_CONTROLLER_PORT, 0) \ - MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) - -SLOT_INTERFACE_EXTERN(psx_controllers); - -extern const device_type PSXCONTROLLERPORTS; -extern const device_type PSX_CONTROLLER_PORT; -extern const device_type PSX_STANDARD_CONTROLLER; - -class psx_controller_port_device; - -class device_psx_controller_interface : public device_slot_card_interface -{ - friend class psx_multitap_device; -public: - device_psx_controller_interface(const machine_config &mconfig, device_t &device); - virtual ~device_psx_controller_interface(); - - void clock_w(bool state) { if(m_clock && !m_sel && !state && !m_memcard) do_pad(); m_clock = state; } - void sel_w(bool state); - - bool rx_r() { return m_rx; } - bool ack_r() { return m_ack; } - -protected: - virtual void interface_pre_reset(); - virtual void interface_pre_start(); - - enum - { - QUERY_PAD_STATE = 0x42, - CONFIG_MODE = 0x43, - }; - -private: - virtual bool get_pad(int count, UINT8 *odata, UINT8 idata) = 0; - virtual void do_pad(); - void ack_timer(void *ptr, int param); - - UINT8 m_odata; - UINT8 m_idata; - int m_bit; - int m_count; - bool m_memcard; - - bool m_clock; - bool m_sel; - bool m_ack; - bool m_rx; - - emu_timer *m_ack_timer; - psx_controller_port_device *m_owner; -}; - -class psx_standard_controller_device : public device_t, - public device_psx_controller_interface -{ -public: - psx_standard_controller_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - - virtual ioport_constructor device_input_ports() const; - -protected: - virtual void device_start() { } -private: - virtual bool get_pad(int count, UINT8 *odata, UINT8 idata); - - required_ioport m_pad0; - required_ioport m_pad1; -}; - -class psxcontrollerports_device : public psxsiodev_device -{ -public: - psxcontrollerports_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - void ack(); - -protected: - virtual void device_start(); - -private: - virtual void data_in(int data, int mask); - - psx_controller_port_device *m_port0; - psx_controller_port_device *m_port1; -}; - -class psx_controller_port_device : public device_t, - public device_slot_interface -{ -public: - psx_controller_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - virtual machine_config_constructor device_mconfig_additions() const; - - typedef delegate void_cb; - void ack() { if(!ack_cb.isnull()) ack_cb(); } - void setup_ack_cb(void_cb cb) { ack_cb = cb; } - - DECLARE_WRITE_LINE_MEMBER(tx_w) { m_tx = state; } - DECLARE_WRITE_LINE_MEMBER(sel_w) { if(m_dev) m_dev->sel_w(state); m_card->sel_w(state); } - DECLARE_WRITE_LINE_MEMBER(clock_w) { if(m_dev) m_dev->clock_w(state); m_card->clock_w(state); } - - DECLARE_READ_LINE_MEMBER(rx_r) { return (m_dev?m_dev->rx_r():true) && m_card->rx_r(); } - DECLARE_READ_LINE_MEMBER(ack_r) { return (m_dev?m_dev->ack_r():true) && m_card->ack_r(); } - DECLARE_READ_LINE_MEMBER(tx_r) { return m_tx; } - - void disable_card(bool status); - -protected: - virtual void device_start() {} - virtual void device_reset() { m_tx = true; } - virtual void device_config_complete(); - -private: - void_cb ack_cb; - bool m_tx; - - device_psx_controller_interface *m_dev; - required_device m_card; -}; -#endif diff --git a/src/mess/machine/psxmultitap.c b/src/mess/machine/psxmultitap.c deleted file mode 100644 index ad39d254160..00000000000 --- a/src/mess/machine/psxmultitap.c +++ /dev/null @@ -1,273 +0,0 @@ -// psx multitap emulation - -#include "machine/psxmultitap.h" - -const device_type PSX_MULTITAP = &device_creator; - -psx_multitap_device::psx_multitap_device(const machine_config& mconfig, const char* tag, device_t* owner, UINT32 clock) : - device_t(mconfig, PSX_MULTITAP, "Playstation Multitap", tag, owner, clock, "psx_multitap", __FILE__), - device_psx_controller_interface(mconfig, *this), - m_porta(*this, "a"), - m_portb(*this, "b"), - m_portc(*this, "c"), - m_portd(*this, "d") -{ -} - -static MACHINE_CONFIG_FRAGMENT( psx_multitap ) - MCFG_PSX_CTRL_PORT_ADD("a", psx_controllers_nomulti, "digital_pad") - MCFG_PSX_CTRL_PORT_ADD("b", psx_controllers_nomulti, NULL) - MCFG_PSX_CTRL_PORT_ADD("c", psx_controllers_nomulti, NULL) - MCFG_PSX_CTRL_PORT_ADD("d", psx_controllers_nomulti, NULL) -MACHINE_CONFIG_END - -machine_config_constructor psx_multitap_device::device_mconfig_additions() const -{ - return MACHINE_CONFIG_NAME( psx_multitap ); -} - -void psx_multitap_device::device_start() -{ - m_porta->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); - m_portb->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); - m_portc->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); - m_portd->setup_ack_cb(psx_controller_port_device::void_cb(FUNC(psx_multitap_device::ack), this)); - m_nextmode = false; - - save_item(NAME(m_activeport)); - save_item(NAME(m_cack)); - save_item(NAME(m_singlemode)); - save_item(NAME(m_nextmode)); - save_item(NAME(m_tapmc)); - save_item(NAME(m_data)); -} - -void psx_multitap_device::interface_pre_reset() -{ - m_activeport = -1; - m_singlemode = m_nextmode; - m_tapmc = false; - m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true; - memset(m_data, 0xff, sizeof(m_data)); - m_porta->sel_w(false); - m_portb->sel_w(false); - m_portc->sel_w(false); - m_portd->sel_w(false); - m_porta->sel_w(true); - m_portb->sel_w(true); - m_portc->sel_w(true); - m_portd->sel_w(true); - device_psx_controller_interface::interface_pre_reset(); -} - -void psx_multitap_device::set_tx_line(bool tx, int port) -{ - psx_controller_port_device *dev; - switch(port) - { - default: - case 0: - dev = m_porta; - break; - case 1: - dev = m_portb; - break; - case 2: - dev = m_portc; - break; - case 3: - dev = m_portd; - break; - } - dev->clock_w(1); - dev->tx_w(tx); - dev->clock_w(0); -} - -bool psx_multitap_device::get_rx_line(int port) -{ - psx_controller_port_device *dev; - switch(port) - { - default: - case 0: - dev = m_porta; - break; - case 1: - dev = m_portb; - break; - case 2: - dev = m_portc; - break; - case 3: - dev = m_portd; - break; - } - return dev->rx_r(); -} - -void psx_multitap_device::do_pad() -{ - bool tx = device_psx_controller_interface::m_owner->tx_r(); - - // we don't know which controller until after the first byte - if((m_singlemode || m_tapmc) && (m_count >= 1)) - { - if((m_count == 2) && !m_bit && !m_tapmc) - m_nextmode = !tx; - - set_tx_line(tx, m_activeport); - m_rx = get_rx_line(m_activeport); - m_bit = (m_bit + 1) % 8; - if(!m_bit) - m_count++; - return; - } - - if(!m_count) - { - // first send the select byte to all devices until we know whether it's accessing - // a controller or memcard - if(!m_bit) - { - m_porta->sel_w(false); - m_portb->sel_w(false); - m_portc->sel_w(false); - m_portd->sel_w(false); - } - device_psx_controller_interface::do_pad(); - set_tx_line(tx, 0); - set_tx_line(tx, 1); - set_tx_line(tx, 2); - set_tx_line(tx, 3); - if(!m_bit) - { - m_count = 1; - m_tapmc = m_memcard; - m_memcard = false; // make sure we still receive clocks - if(m_singlemode || m_tapmc) - { - m_activeport = (m_idata & 0xf) - 1; - m_porta->sel_w((m_activeport == 0) ? false : true); - m_portb->sel_w((m_activeport == 1) ? false : true); - m_portc->sel_w((m_activeport == 2) ? false : true); - m_portd->sel_w((m_activeport == 3) ? false : true); - } - } - return; - } - else if(m_count <= 2) - return device_psx_controller_interface::do_pad(); - else if(m_count < 11) - { - if((m_count == 3) && !m_bit) - m_nextmode = !m_idata; - - if((m_count < 5) && m_cack[0] && m_cack[1] && m_cack[2] && m_cack[3]) - return; // no acks? hang up. - - // all of the ports are polled here, port a is passed though. the data - // from the other ports is stored and can be retrieved at a much higher clock rate - // don't poll a port that is inactive or done - if(!m_cack[0]) - { - set_tx_line(tx, 0); - m_rx = m_porta->rx_r(); - } - else - { - m_rx = true; - m_porta->sel_w(true); - } - - if(!m_cack[1]) - { - set_tx_line(tx, 1); - m_data[0][m_count - 3] &= ~(!m_portb->rx_r() << m_bit); - } - else - m_portb->sel_w(true); - - if(!m_cack[2]) - { - set_tx_line(tx, 2); - m_data[1][m_count - 3] &= ~(!m_portc->rx_r() << m_bit); - } - else - m_portc->sel_w(true); - - if(!m_cack[3]) - { - set_tx_line(tx, 3); - m_data[2][m_count - 3] &= ~(!m_portd->rx_r() << m_bit); - } - else - m_portd->sel_w(true); - } - else if(m_count < 19) - // send stored port b data - m_rx = ((m_data[0][m_count - 11] & (1 << m_bit)) ? 1 : 0); - else if(m_count < 27) - // send stored port c data - m_rx = ((m_data[1][m_count - 19] & (1 << m_bit)) ? 1 : 0); - else - // send stored port d data - m_rx = ((m_data[2][m_count - 27] & (1 << m_bit)) ? 1 : 0); - - if(m_bit == 7) - { - // ports won't ack if they are done - m_cack[0] = m_cack[1] = m_cack[2] = m_cack[3] = true; - if(m_count < 11) - m_ack_timer->adjust(attotime::from_usec(12), 0); // give a bit of time for the ports to ack - else if(m_count < 35) - m_ack_timer->adjust(attotime::from_usec(10), 0); - } - - m_bit = (m_bit + 1) % 8; - if(!m_bit) - m_count++; -} - -bool psx_multitap_device::get_pad(int count, UINT8 *odata, UINT8 idata) -{ - if(!count) - *odata = 0x80; - else - *odata = 0x5a; - return true; -} - -void psx_multitap_device::ack() -{ - if(m_activeport != -1) - { - switch(m_activeport) - { - case 0: - m_ack = m_porta->ack_r(); - break; - case 1: - m_ack = m_portb->ack_r(); - break; - case 2: - m_ack = m_portc->ack_r(); - break; - case 3: - m_ack = m_portd->ack_r(); - break; - default: - return; - } - device_psx_controller_interface::m_owner->ack(); - return; - } - if(!m_porta->ack_r()) - m_cack[0] = false; - if(!m_portb->ack_r()) - m_cack[1] = false; - if(!m_portc->ack_r()) - m_cack[2] = false; - if(!m_portd->ack_r()) - m_cack[3] = false; -} diff --git a/src/mess/machine/psxmultitap.h b/src/mess/machine/psxmultitap.h deleted file mode 100644 index 35ec57098dc..00000000000 --- a/src/mess/machine/psxmultitap.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef PSXMULTITAP_H_ -#define PSXMULTITAP_H_ - -#include "machine/psxcport.h" - -SLOT_INTERFACE_EXTERN(psx_controllers_nomulti); - -class psx_multitap_device : public device_t, - public device_psx_controller_interface -{ -public: - psx_multitap_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); - virtual machine_config_constructor device_mconfig_additions() const; - -protected: - virtual void device_start(); - virtual void device_stop() { device_psx_controller_interface::m_owner->disable_card(false); } - virtual void device_reset() { device_psx_controller_interface::m_owner->disable_card(true); } - virtual void device_config_complete() { m_shortname = "psx_multitap"; } - virtual void interface_pre_reset(); - -private: - virtual bool get_pad(int count, UINT8 *odata, UINT8 idata); - virtual void do_pad(); - void ack(); - void set_tx_line(bool tx, int port); - bool get_rx_line(int port); - - int m_activeport; - bool m_cack[4]; - bool m_singlemode, m_nextmode, m_tapmc; - UINT8 m_data[3][8]; // port a is passed though - required_device m_porta; - required_device m_portb; - required_device m_portc; - required_device m_portd; -}; - -extern const device_type PSX_MULTITAP; - -#endif /* PSXMULTITAP_H_ */ diff --git a/src/mess/mess.mak b/src/mess/mess.mak index e37665920aa..d926bde0cab 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -613,6 +613,7 @@ BUSES += PC_JOY BUSES += PC_KBD BUSES += PET BUSES += PLUS4 +BUSES += PSX_CONTROLLER BUSES += QL BUSES += RS232 BUSES += S100 @@ -1620,7 +1621,7 @@ $(MESSOBJ)/snk.a: \ $(MESS_DRIVERS)/ngp.o $(MESS_VIDEO)/k1ge.o \ $(MESSOBJ)/sony.a: \ - $(MESS_DRIVERS)/pockstat.o $(MESS_DRIVERS)/psx.o $(MESS_MACHINE)/psxanalog.o $(MESS_MACHINE)/psxcard.o $(MESS_MACHINE)/psxcd.o $(MESS_MACHINE)/psxcport.o $(MESS_MACHINE)/psxmultitap.o \ + $(MESS_DRIVERS)/pockstat.o $(MESS_DRIVERS)/psx.o $(MESS_MACHINE)/psxcd.o \ $(MESS_DRIVERS)/pve500.o \ $(MESS_DRIVERS)/smc777.o \ -- cgit v1.2.3