1 // license:BSD-3-Clause
2 // copyright-holders:Fabio Priuli
3 /**********************************************************************
4
5 Nintendo Family Computer Hori Twin (and 4P?) adapters
6
7 Emulation of the 4Players adapter is quite pointless: if 2P mode
8 (default mode) it behaves like a Hori Twin adapter, in 4P mode
9 it has P1 and P2 inputs overwriting the inputs coming from the
10 main controllers (possibly creating a bit of confusion, since
11 you get 6 sets of inputs with only 4 acknowledged by the running
12 system).
13 For the moment we keep it available for documentation purposes.
14
15 TODO: find out confirmation whether in 2P mode, inputs from joypads
16 connected to the 4players adapter are really seen as P3 and P4 inputs.
17 it seems the most reasonable setup (so that users with only 2
18 external pads can use the adapter in 4P games), but one never knows...
19
20 **********************************************************************/
21
22 #include "emu.h"
23 #include "hori.h"
24 #include "joypad.h"
25
26 //**************************************************************************
27 // DEVICE DEFINITIONS
28 //**************************************************************************
29
30 DEFINE_DEVICE_TYPE(NES_HORITWIN, nes_horitwin_device, "nes_horitwin", "FC Hori Twin Adapter")
31 DEFINE_DEVICE_TYPE(NES_HORI4P, nes_hori4p_device, "nes_hori4p", "FC Hori 4P Adapter")
32
33
INPUT_PORTS_START(nes_hori4p)34 static INPUT_PORTS_START( nes_hori4p )
35 PORT_START("CONFIG")
36 PORT_CONFNAME( 0x01, 0x00, "4 Players / 2 Players")
37 PORT_CONFSETTING( 0x00, "2 Players" )
38 PORT_CONFSETTING( 0x01, "4 Players" )
39 INPUT_PORTS_END
40
41
42 //-------------------------------------------------
43 // input_ports - device-specific input ports
44 //-------------------------------------------------
45
46 ioport_constructor nes_hori4p_device::device_input_ports() const
47 {
48 return INPUT_PORTS_NAME( nes_hori4p );
49 }
50
51
hori_adapter(device_slot_interface & device)52 static void hori_adapter(device_slot_interface &device)
53 {
54 device.option_add("joypad", NES_JOYPAD);
55 }
56
57
58 //-------------------------------------------------
59 // device_add_mconfig - add device configuration
60 //-------------------------------------------------
61
device_add_mconfig(machine_config & config)62 void nes_horitwin_device::device_add_mconfig(machine_config &config)
63 {
64 NES_CONTROL_PORT(config, m_port1, hori_adapter, "joypad");
65 NES_CONTROL_PORT(config, m_port2, hori_adapter, "joypad");
66 if (m_port != nullptr)
67 {
68 m_port1->set_screen_tag(m_port->m_screen);
69 m_port2->set_screen_tag(m_port->m_screen);
70 }
71 }
72
device_add_mconfig(machine_config & config)73 void nes_hori4p_device::device_add_mconfig(machine_config &config)
74 {
75 NES_CONTROL_PORT(config, m_port1, hori_adapter, "joypad");
76 NES_CONTROL_PORT(config, m_port2, hori_adapter, "joypad");
77 NES_CONTROL_PORT(config, m_port3, hori_adapter, "joypad");
78 NES_CONTROL_PORT(config, m_port4, hori_adapter, "joypad");
79 if (m_port != nullptr)
80 {
81 m_port1->set_screen_tag(m_port->m_screen);
82 m_port2->set_screen_tag(m_port->m_screen);
83 m_port3->set_screen_tag(m_port->m_screen);
84 m_port4->set_screen_tag(m_port->m_screen);
85 }
86 }
87
88
89 //**************************************************************************
90 // LIVE DEVICE
91 //**************************************************************************
92
93 //-------------------------------------------------
94 // nes_horitwin_device - constructor
95 //-------------------------------------------------
96
nes_horitwin_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)97 nes_horitwin_device::nes_horitwin_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
98 device_t(mconfig, NES_HORITWIN, tag, owner, clock),
99 device_nes_control_port_interface(mconfig, *this),
100 m_port1(*this, "port1"),
101 m_port2(*this, "port2")
102 {
103 }
104
nes_hori4p_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)105 nes_hori4p_device::nes_hori4p_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
106 device_t(mconfig, NES_HORI4P, tag, owner, clock),
107 device_nes_control_port_interface(mconfig, *this),
108 m_port1(*this, "port1"),
109 m_port2(*this, "port2"),
110 m_port3(*this, "port3"),
111 m_port4(*this, "port4"),
112 m_cfg(*this, "CONFIG")
113 {
114 }
115
116
117 //-------------------------------------------------
118 // read
119 //-------------------------------------------------
120
read_exp(offs_t offset)121 uint8_t nes_horitwin_device::read_exp(offs_t offset)
122 {
123 uint8_t ret = 0;
124 if (offset == 0) //$4016
125 ret |= (m_port1->read_bit0() << 1);
126 else //$4017
127 ret |= (m_port2->read_bit0() << 1);
128 return ret;
129 }
130
read_exp(offs_t offset)131 uint8_t nes_hori4p_device::read_exp(offs_t offset)
132 {
133 uint8_t ret = 0;
134 if (m_cfg->read() == 0) // 2P
135 {
136 if (offset == 0) //$4016
137 ret |= (m_port1->read_bit0() << 1);
138 else //$4017
139 ret |= (m_port2->read_bit0() << 1);
140 }
141 else // 4P
142 {
143 if (offset == 0) //$4016
144 {
145 ret |= (m_port1->read_bit0() << 0);
146 ret |= (m_port3->read_bit0() << 1);
147 }
148 else //$4017
149 {
150 ret |= (m_port2->read_bit0() << 0);
151 ret |= (m_port4->read_bit0() << 1);
152 }
153 }
154 return ret;
155 }
156
157 //-------------------------------------------------
158 // write
159 //-------------------------------------------------
160
write(uint8_t data)161 void nes_horitwin_device::write(uint8_t data)
162 {
163 m_port1->write(data);
164 m_port2->write(data);
165 }
166
write(uint8_t data)167 void nes_hori4p_device::write(uint8_t data)
168 {
169 m_port1->write(data);
170 m_port2->write(data);
171 m_port3->write(data);
172 m_port4->write(data);
173 }
174