diff options
Diffstat (limited to 'src/devices/bus/nes_ctrl/joypad.cpp')
-rw-r--r-- | src/devices/bus/nes_ctrl/joypad.cpp | 194 |
1 files changed, 107 insertions, 87 deletions
diff --git a/src/devices/bus/nes_ctrl/joypad.cpp b/src/devices/bus/nes_ctrl/joypad.cpp index f6c8116c72c..c4972912d78 100644 --- a/src/devices/bus/nes_ctrl/joypad.cpp +++ b/src/devices/bus/nes_ctrl/joypad.cpp @@ -25,6 +25,14 @@ game (an image of such connection is shown e.g. in Nekketsu Koukou Dodgeball Bu manual) + FIXME: The official Nintendo stick mentioned above by Hori has the + P1/P2 and 4/8-way switches but it DOESN'T have a daisy chain port. + ASCII made at least two sticks, AS-2088-FC and AS-3399-FC, that may + be the only two that exist with a daisy chain port. The former has + no additional switches at all, so its port may be a pass-thru. The + latter has many features: P1/P2 and 4/8-way switches, turbo, jacks + for data recorder, etc. + **********************************************************************/ #include "emu.h" @@ -35,15 +43,17 @@ //************************************************************************** DEFINE_DEVICE_TYPE(NES_JOYPAD, nes_joypad_device, "nes_joypad", "Nintendo NES / FC Control Pad") +DEFINE_DEVICE_TYPE(NES_FCPAD_EXP, nes_fcpadexp_device, "nes_fcpadexp", "Nintendo Family Computer Expansion Port Pad") DEFINE_DEVICE_TYPE(NES_FCPAD_P2, nes_fcpad2_device, "nes_fcpad2", "Nintendo Family Computer P2 Pad") DEFINE_DEVICE_TYPE(NES_CCPAD_LEFT, nes_ccpadl_device, "nes_ccpadl", "FC Crazy Climber Left Pad") DEFINE_DEVICE_TYPE(NES_CCPAD_RIGHT, nes_ccpadr_device, "nes_ccpadr", "FC Crazy Climber Right Pad") DEFINE_DEVICE_TYPE(NES_ARCSTICK, nes_arcstick_device, "nes_arcstick", "Nintendo Family Computer Arcade Stick") +DEFINE_DEVICE_TYPE(NES_VBOYCTRL, nes_vboyctrl_device, "nes_vboyctrl", "Nintendo Virtual Boy Controller") -static INPUT_PORTS_START( nes_joypad ) +INPUT_PORTS_START( nes_joypad ) PORT_START("JOYPAD") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("%p A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("%p B") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY @@ -53,15 +63,15 @@ static INPUT_PORTS_START( nes_joypad ) INPUT_PORTS_END static INPUT_PORTS_START( nes_fcpad_p2 ) - PORT_START("JOYPAD") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") - PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_NAME("Microphone") - PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) - PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY - PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY - PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY - PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY + PORT_INCLUDE( nes_joypad ) + + PORT_MODIFY("JOYPAD") + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNUSED ) // no select button + PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_UNUSED ) // or start button on controller 2 + + PORT_START("MIC") + PORT_BIT( 0x03, IP_ACTIVE_HIGH, IPT_UNUSED ) + PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("%p Microphone") INPUT_PORTS_END static INPUT_PORTS_START( nes_ccpad_left ) @@ -98,8 +108,8 @@ static INPUT_PORTS_START( nes_arcstick ) PORT_CONFSETTING( 0x02, "Player II" ) PORT_START("JOYPAD") - PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("A") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("B") + PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("%p A") + PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("%p B") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_SELECT ) PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x01) @@ -112,6 +122,26 @@ static INPUT_PORTS_START( nes_arcstick ) PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_4WAY PORT_CONDITION("CONFIG", 0x01, EQUALS, 0x00) INPUT_PORTS_END +static INPUT_PORTS_START( nes_vboyctrl ) + PORT_START("JOYPAD") + PORT_BIT( 0x0001, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_DOWN ) PORT_8WAY + PORT_BIT( 0x0002, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_LEFT ) PORT_8WAY + PORT_BIT( 0x0004, IP_ACTIVE_HIGH, IPT_SELECT ) + PORT_BIT( 0x0008, IP_ACTIVE_HIGH, IPT_START ) + PORT_BIT( 0x0010, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_UP ) PORT_8WAY + PORT_BIT( 0x0020, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_DOWN ) PORT_8WAY + PORT_BIT( 0x0040, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_LEFT ) PORT_8WAY + PORT_BIT( 0x0080, IP_ACTIVE_HIGH, IPT_JOYSTICKLEFT_RIGHT ) PORT_8WAY + PORT_BIT( 0x0100, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_RIGHT ) PORT_8WAY + PORT_BIT( 0x0200, IP_ACTIVE_HIGH, IPT_JOYSTICKRIGHT_UP ) PORT_8WAY + PORT_BIT( 0x0400, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("%p L") // Left button on back + PORT_BIT( 0x0800, IP_ACTIVE_HIGH, IPT_BUTTON4 ) PORT_NAME("%p R") // Right button on back + PORT_BIT( 0x1000, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("%p B") + PORT_BIT( 0x2000, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("%p A") + PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_UNUSED ) // Always 1 + PORT_BIT( 0x8000, IP_ACTIVE_HIGH, IPT_UNUSED ) // Battery low +INPUT_PORTS_END + //------------------------------------------------- // input_ports - device-specific input ports //------------------------------------------------- @@ -141,6 +171,11 @@ ioport_constructor nes_arcstick_device::device_input_ports() const return INPUT_PORTS_NAME( nes_arcstick ); } +ioport_constructor nes_vboyctrl_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( nes_vboyctrl ); +} + static void arcstick_daisy(device_slot_interface &device) { device.option_add("arcstick", NES_ARCSTICK); @@ -168,58 +203,67 @@ void nes_arcstick_device::device_add_mconfig(machine_config &config) // nes_joypad_device - constructor //------------------------------------------------- -nes_joypad_device::nes_joypad_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : - device_t(mconfig, type, tag, owner, clock), - device_nes_control_port_interface(mconfig, *this), - m_joypad(*this, "JOYPAD"), m_latch(0) +nes_joypad_device::nes_joypad_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 latch_fill) + : device_t(mconfig, type, tag, owner, clock) + , device_nes_control_port_interface(mconfig, *this) + , m_joypad(*this, "JOYPAD") + , m_latch(0) + , m_latch_fill(latch_fill) { } -nes_joypad_device::nes_joypad_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - nes_joypad_device(mconfig, NES_JOYPAD, tag, owner, clock) +nes_joypad_device::nes_joypad_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_joypad_device(mconfig, NES_JOYPAD, tag, owner, clock) { } -nes_fcpad2_device::nes_fcpad2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - nes_joypad_device(mconfig, NES_FCPAD_P2, tag, owner, clock) +nes_fcpadexp_device::nes_fcpadexp_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, u32 latch_fill) + : nes_joypad_device(mconfig, type, tag, owner, clock, latch_fill) { } -nes_ccpadl_device::nes_ccpadl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - nes_joypad_device(mconfig, NES_CCPAD_LEFT, tag, owner, clock) +nes_fcpadexp_device::nes_fcpadexp_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_fcpadexp_device(mconfig, NES_FCPAD_EXP, tag, owner, clock) { } -nes_ccpadr_device::nes_ccpadr_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - nes_joypad_device(mconfig, NES_CCPAD_RIGHT, tag, owner, clock) +nes_fcpad2_device::nes_fcpad2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_joypad_device(mconfig, NES_FCPAD_P2, tag, owner, clock) + , m_mic(*this, "MIC") { } -nes_arcstick_device::nes_arcstick_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : - nes_joypad_device(mconfig, NES_ARCSTICK, tag, owner, clock), - m_daisychain(*this, "subexp"), - m_cfg(*this, "CONFIG") +nes_ccpadl_device::nes_ccpadl_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_joypad_device(mconfig, NES_CCPAD_LEFT, tag, owner, clock) { } +nes_ccpadr_device::nes_ccpadr_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_joypad_device(mconfig, NES_CCPAD_RIGHT, tag, owner, clock) +{ +} -//------------------------------------------------- -// device_start -//------------------------------------------------- +nes_arcstick_device::nes_arcstick_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_fcpadexp_device(mconfig, NES_ARCSTICK, tag, owner, clock) + , m_daisychain(*this, "subexp") + , m_cfg(*this, "CONFIG") +{ +} -void nes_joypad_device::device_start() +nes_vboyctrl_device::nes_vboyctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : nes_joypad_device(mconfig, NES_VBOYCTRL, tag, owner, clock, 0x8000) { - save_item(NAME(m_latch)); } //------------------------------------------------- -// device_reset +// device_start //------------------------------------------------- -void nes_joypad_device::device_reset() +void nes_joypad_device::device_start() { - m_latch = 0; + save_item(NAME(m_latch)); + save_item(NAME(m_strobe)); } @@ -227,20 +271,26 @@ void nes_joypad_device::device_reset() // read //------------------------------------------------- -uint8_t nes_joypad_device::read_bit0() +u8 nes_joypad_device::read_bit0() { - uint8_t ret = m_latch & 1; + if (m_strobe) + set_latch(); + + u8 ret = m_latch & 1; m_latch >>= 1; + m_latch |= m_latch_fill; + return ret; } -uint8_t nes_fcpad2_device::read_exp(offs_t offset) +u8 nes_fcpadexp_device::read_exp(offs_t offset) { - uint8_t ret = 0; - if (!offset) // microphone input - ret |= m_joypad->read() & 0x04; + return offset ? 0 : nes_joypad_device::read_bit0() << 1; +} - return ret; +u8 nes_fcpad2_device::read_bit2() +{ + return m_mic->read(); } // NOTE: I haven't found any documentation about what happens when @@ -249,29 +299,14 @@ uint8_t nes_fcpad2_device::read_exp(offs_t offset) // with each other? currently, we only support the following setup: // if the first pad is set as P1, the daisy chained pad is checked // for P2 only, and vice versa. -uint8_t nes_arcstick_device::read_exp(offs_t offset) +u8 nes_arcstick_device::read_exp(offs_t offset) { - uint8_t ret = 0; - if (offset == 0) //$4016 - { - if ((m_cfg->read() & 2) == 0) // we are P1 input - { - ret |= (m_latch & 1) << 1; - m_latch >>= 1; - } - else - ret |= m_daisychain->read_exp(0); - } - else //$4017 - { - if ((m_cfg->read() & 2) == 2) // we are P2 input - { - ret |= (m_latch & 1) << 1; - m_latch >>= 1; - } - else - ret |= m_daisychain->read_exp(1); - } + u8 ret = 0; + + if (BIT(m_cfg->read(), 1) == offset) // P# matches the port? That's us! + ret = nes_fcpadexp_device::read_exp(0); + else // otherwise it's possibly the other controller + ret = m_daisychain->read_exp(offset); return ret; } @@ -280,29 +315,14 @@ uint8_t nes_arcstick_device::read_exp(offs_t offset) // write //------------------------------------------------- -void nes_joypad_device::write(uint8_t data) -{ - if (data & 0x01) - return; - - m_latch = m_joypad->read(); -} - -void nes_fcpad2_device::write(uint8_t data) +void nes_joypad_device::write(u8 data) { - if (data & 0x01) - return; - - // microphone is hooked to expansion bits, not to the controller bit - m_latch = m_joypad->read() & ~0x04; + if (write_strobe(data)) + set_latch(); } -void nes_arcstick_device::write(uint8_t data) +void nes_arcstick_device::write(u8 data) { m_daisychain->write(data); - - if (data & 0x01) - return; - - m_latch = m_joypad->read(); + nes_fcpadexp_device::write(data); } |