diff options
author | 2021-12-08 16:15:34 -0900 | |
---|---|---|
committer | 2021-12-08 20:15:34 -0500 | |
commit | 98bcd68b0b1e0479e04248704759271e2e50b55f (patch) | |
tree | 437bbaa5db4e4b255db994e58d93ed3b3e62127c | |
parent | a95da6eb6d675d63169536d572cc85c427ccf02a (diff) |
bus/nes_ctrl: Disentangled Famicom joypad 2 from expansion port code. (#8949)
- Removed read_exp call from fcpad2. The FC expansion port is not tied to the relevant line at all.
- Replaced with read_bit2 in the control port interface for the same purpose.
- Separated JOYPAD inputs from MIC. The microphone shouldn't be mixed with button inputs' shift register.
machine/nes.cpp: Also removed read_exp calls on FC control ports. Other than the microphone on fcpad2 nothing used these (nor should they as the only line in common is $4017 bit 0, which in general is never used by the expansion port).
-rw-r--r-- | src/devices/bus/nes_ctrl/ctrl.cpp | 40 | ||||
-rw-r--r-- | src/devices/bus/nes_ctrl/ctrl.h | 22 | ||||
-rw-r--r-- | src/devices/bus/nes_ctrl/joypad.cpp | 40 | ||||
-rw-r--r-- | src/devices/bus/nes_ctrl/joypad.h | 8 | ||||
-rw-r--r-- | src/mame/machine/nes.cpp | 17 |
5 files changed, 59 insertions, 68 deletions
diff --git a/src/devices/bus/nes_ctrl/ctrl.cpp b/src/devices/bus/nes_ctrl/ctrl.cpp index 1f4f0274687..33bd74e77cf 100644 --- a/src/devices/bus/nes_ctrl/ctrl.cpp +++ b/src/devices/bus/nes_ctrl/ctrl.cpp @@ -6,18 +6,18 @@ and Family Computer expansion port emulation Here we emulate in fact 3 different kind of ports, which are - connected to different bis of memory locations $4016 and $4017: + connected to different bits of memory locations $4016 and $4017: - NES controller ports: these are hooked to bit 0,3,4 of the corresponding address ($4016 for port1, $4017 for port2) - FC controller ports: these are only hooked to bit 0 of the corresponding address (so that e.g. a NES Zapper could not be connected to a later FC AV model, because its inputs would not be detected) - - FC expansion port: this is hooked to bits 0-4 of both addresses - To make things a little bit more complex, old FC models have the - controller hardwired to the unit, and the P2 controllers are - directly hooked also to one of the expansion port lines (namely, - microphone inputs from P2 go to $4016 bit 2) + - FC expansion port: this is hooked to bit 1 of memory location + $4016 and bits 0-4 of $4017 + To make things a little bit more complex, old FC models have + controllers hardwired to the unit, and the P2 controllers are + directly hooked to bit 2 of $4016 (for microphone inputs). Even if the controller port and the expansion port are physically different (the FC expansion is a 15pin port, while @@ -35,8 +35,8 @@ handlers they have hooks for: Basic usage is that the expansion port calls read_exp, FC ctrl ports call read_bit0, and NES ctrl ports call both read_bit0 and read_bit34. However, to cope with - the original FC microphone, we will have the second controller - port calling read_exp too. + the original FC microphone, we have a one-off read_bit2 handler + called by the second controller. **********************************************************************/ @@ -103,7 +103,7 @@ device_nes_control_port_interface::~device_nes_control_port_interface() // nes_control_port_device - constructor //------------------------------------------------- -nes_control_port_device::nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +nes_control_port_device::nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, NES_CONTROL_PORT, tag, owner, clock), device_single_card_slot_interface<device_nes_control_port_interface>(mconfig, *this), m_screen(*this, finder_base::DUMMY_TAG), @@ -131,31 +131,39 @@ void nes_control_port_device::device_start() } -uint8_t nes_control_port_device::read_bit0() +u8 nes_control_port_device::read_bit0() { - uint8_t data = 0; + u8 data = 0; if (m_device) data = m_device->read_bit0(); return data; } -uint8_t nes_control_port_device::read_bit34() +u8 nes_control_port_device::read_bit2() { - uint8_t data = 0; + u8 data = 0; + if (m_device) + data = m_device->read_bit2(); + return data; +} + +u8 nes_control_port_device::read_bit34() +{ + u8 data = 0; if (m_device) data = m_device->read_bit34(); return data; } -uint8_t nes_control_port_device::read_exp(offs_t offset) +u8 nes_control_port_device::read_exp(offs_t offset) { - uint8_t data = 0; + u8 data = 0; if (m_device) data = m_device->read_exp(offset); return data; } -void nes_control_port_device::write(uint8_t data) +void nes_control_port_device::write(u8 data) { if (m_device) m_device->write(data); diff --git a/src/devices/bus/nes_ctrl/ctrl.h b/src/devices/bus/nes_ctrl/ctrl.h index 6e9e05aac17..560f546db89 100644 --- a/src/devices/bus/nes_ctrl/ctrl.h +++ b/src/devices/bus/nes_ctrl/ctrl.h @@ -34,10 +34,11 @@ public: // construction/destruction virtual ~device_nes_control_port_interface(); - virtual uint8_t read_bit0() { return 0; } - virtual uint8_t read_bit34() { return 0; } - virtual uint8_t read_exp(offs_t offset) { return 0; } - virtual void write(uint8_t data) { } + virtual u8 read_bit0() { return 0; } + virtual u8 read_bit2() { return 0; } // intended only for P2 microphone + virtual u8 read_bit34() { return 0; } + virtual u8 read_exp(offs_t offset) { return 0; } + virtual void write(u8 data) { } protected: device_nes_control_port_interface(const machine_config &mconfig, device_t &device); @@ -55,20 +56,21 @@ public: // construction/destruction template <typename T> nes_control_port_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&opts, char const *dflt) - : nes_control_port_device(mconfig, tag, owner, (uint32_t)0) + : nes_control_port_device(mconfig, tag, owner, (u32)0) { option_reset(); opts(*this); set_default_option(dflt); set_fixed(false); } - nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual ~nes_control_port_device(); - uint8_t read_bit0(); - uint8_t read_bit34(); - uint8_t read_exp(offs_t offset); - void write(uint8_t data); + u8 read_bit0(); + u8 read_bit2(); + u8 read_bit34(); + u8 read_exp(offs_t offset); + void write(u8 data); template <typename T> void set_screen_tag(T &&tag) { m_screen.set_tag(std::forward<T>(tag)); } // for peripherals that interact with the machine's screen diff --git a/src/devices/bus/nes_ctrl/joypad.cpp b/src/devices/bus/nes_ctrl/joypad.cpp index 8336f2158d5..4b0b89ccf9b 100644 --- a/src/devices/bus/nes_ctrl/joypad.cpp +++ b/src/devices/bus/nes_ctrl/joypad.cpp @@ -53,15 +53,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("%p A") - PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("%p 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_OTHER ) PORT_NAME("Microphone") PORT_CODE(KEYCODE_M) INPUT_PORTS_END static INPUT_PORTS_START( nes_ccpad_left ) @@ -180,8 +180,9 @@ nes_joypad_device::nes_joypad_device(const machine_config &mconfig, const char * { } -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_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") { } @@ -234,13 +235,9 @@ uint8_t nes_joypad_device::read_bit0() return ret; } -uint8_t nes_fcpad2_device::read_exp(offs_t offset) +u8 nes_fcpad2_device::read_bit2() { - uint8_t ret = 0; - if (!offset) // microphone input - ret |= m_joypad->read() & 0x04; - - return ret; + return m_mic->read(); } // NOTE: I haven't found any documentation about what happens when @@ -288,15 +285,6 @@ void nes_joypad_device::write(uint8_t data) m_latch = m_joypad->read(); } -void nes_fcpad2_device::write(uint8_t data) -{ - if (data & 0x01) - return; - - // microphone is hooked to expansion bits, not to the controller bit - m_latch = m_joypad->read() & ~0x04; -} - void nes_arcstick_device::write(uint8_t data) { m_daisychain->write(data); diff --git a/src/devices/bus/nes_ctrl/joypad.h b/src/devices/bus/nes_ctrl/joypad.h index 76acd478906..7fb77cbbecc 100644 --- a/src/devices/bus/nes_ctrl/joypad.h +++ b/src/devices/bus/nes_ctrl/joypad.h @@ -49,13 +49,15 @@ class nes_fcpad2_device : public nes_joypad_device { public: // construction/destruction - nes_fcpad2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + nes_fcpad2_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); virtual ioport_constructor device_input_ports() const override; protected: - virtual uint8_t read_exp(offs_t offset) override; - virtual void write(uint8_t data) override; + virtual u8 read_bit2() override; + +private: + required_ioport m_mic; }; // ======================> nes_ccpadl_device diff --git a/src/mame/machine/nes.cpp b/src/mame/machine/nes.cpp index 993215b9b1c..00052b0c437 100644 --- a/src/mame/machine/nes.cpp +++ b/src/mame/machine/nes.cpp @@ -185,14 +185,11 @@ void nes_base_state::nes_in0_w(uint8_t data) uint8_t nes_state::fc_in0_r() { uint8_t ret = 0x40; - // bit 0 to controller port + // bit 0 from controller port ret |= m_ctrl1->read_bit0(); - // expansion port bits (in the original FC, P2 controller was hooked to these lines - // too, so in principle some homebrew hardware modification could use the same - // connection with P1 controller too) - ret |= m_ctrl1->read_exp(0); - ret |= m_ctrl2->read_exp(0); + // bit 2 from P2 controller microphone + ret |= m_ctrl2->read_bit2(); // at the same time, we might have a standard joypad connected to the expansion port which // shall be read as P3 (this is needed here to avoid implementing the expansion port as a @@ -206,15 +203,9 @@ uint8_t nes_state::fc_in0_r() uint8_t nes_state::fc_in1_r() { uint8_t ret = 0x40; - // bit 0 to controller port + // bit 0 from controller port ret |= m_ctrl2->read_bit0(); - // expansion port bits (in the original FC, P2 controller was hooked to these lines - // too, so in principle some homebrew hardware modification could use the same - // connection with P1 controller too) - ret |= m_ctrl1->read_exp(1); - ret |= m_ctrl2->read_exp(1); - // finally, read the expansion port as expected (standard pad cannot be hooked as P4, so // no read_bit0 here) ret |= m_exp->read_exp(1); |