1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
|
// license:BSD-3-Clause
// copyright-holders:etabeta
/**********************************************************************
Nintendo Family Computer & Entertainment System controller ports
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:
- 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)
Even if the controller port and the expansion port are
physically different (the FC expansion is a 15pin port, while
the controller ports are 7pin), we emulate them as variants of a
common device, exposing the following handlers:
- read_bit0: for bit0 reads, which are typically used for serial
inputs from controllers
- read_bit34: for bit3,4 reading, expected to be at the correct
offset (but we don't currently check for read_bit34 & 0xf8==0)
- read_exp: for reads going through the expansion, with a offset
parameter to decide whether we are reading from $4016 and $4017
- write: to acknowledge writes to $4016
The driver emulation will take care to only call the correct
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.
**********************************************************************/
#include "ctrl.h"
// slot devices
#include "4score.h"
#include "arkpaddle.h"
#include "bcbattle.h"
#include "ftrainer.h"
#include "fckeybrd.h"
#include "hori.h"
#include "joypad.h"
#include "konamihs.h"
#include "miracle.h"
#include "mjpanel.h"
#include "pachinko.h"
#include "partytap.h"
#include "powerpad.h"
#include "suborkey.h"
#include "zapper.h"
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
const device_type NES_CONTROL_PORT = &device_creator<nes_control_port_device>;
//**************************************************************************
// CARD INTERFACE
//**************************************************************************
//-------------------------------------------------
// device_nes_control_port_interface - constructor
//-------------------------------------------------
device_nes_control_port_interface::device_nes_control_port_interface(const machine_config &mconfig, device_t &device) :
device_slot_card_interface(mconfig, device)
{
m_port = dynamic_cast<nes_control_port_device *>(device.owner());
}
//-------------------------------------------------
// ~device_nes_control_port_interface - destructor
//-------------------------------------------------
device_nes_control_port_interface::~device_nes_control_port_interface()
{
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// nes_control_port_device - constructor
//-------------------------------------------------
nes_control_port_device::nes_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
device_t(mconfig, NES_CONTROL_PORT, "Nintendo NES/FC control port", tag, owner, clock, "nes_control_port", __FILE__),
device_slot_interface(mconfig, *this)
{
}
//-------------------------------------------------
// nes_control_port_device - destructor
//-------------------------------------------------
nes_control_port_device::~nes_control_port_device()
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void nes_control_port_device::device_start()
{
m_device = dynamic_cast<device_nes_control_port_interface *>(get_card_device());
m_brightpixel_cb.bind_relative_to(*owner());
}
UINT8 nes_control_port_device::read_bit0()
{
UINT8 data = 0;
if (m_device)
data = m_device->read_bit0();
return data;
}
UINT8 nes_control_port_device::read_bit34()
{
UINT8 data = 0;
if (m_device)
data = m_device->read_bit34();
return data;
}
UINT8 nes_control_port_device::read_exp(offs_t offset)
{
UINT8 data = 0;
if (m_device)
data = m_device->read_exp(offset);
return data;
}
void nes_control_port_device::write(UINT8 data)
{
if (m_device)
m_device->write(data);
}
//-------------------------------------------------
// SLOT_INTERFACE( nes_control_port_devices )
//-------------------------------------------------
SLOT_INTERFACE_START( nes_control_port1_devices )
SLOT_INTERFACE("joypad", NES_JOYPAD)
SLOT_INTERFACE("zapper", NES_ZAPPER)
SLOT_INTERFACE("4score_p1p3", NES_4SCORE_P1P3)
SLOT_INTERFACE("miracle_piano", NES_MIRACLE)
SLOT_INTERFACE_END
SLOT_INTERFACE_START( nes_control_port2_devices )
SLOT_INTERFACE("joypad", NES_JOYPAD)
SLOT_INTERFACE("zapper", NES_ZAPPER)
SLOT_INTERFACE("vaus", NES_ARKPADDLE)
SLOT_INTERFACE("powerpad", NES_POWERPAD)
SLOT_INTERFACE("4score_p2p4", NES_4SCORE_P2P4)
SLOT_INTERFACE_END
SLOT_INTERFACE_START( fc_control_port1_devices )
SLOT_INTERFACE("joypad", NES_JOYPAD)
SLOT_INTERFACE("ccpad_left", NES_CCPAD_LEFT)
SLOT_INTERFACE_END
SLOT_INTERFACE_START( fc_control_port2_devices )
SLOT_INTERFACE("joypad", NES_JOYPAD)
SLOT_INTERFACE("joypad_old", NES_FCPAD_P2)
SLOT_INTERFACE("ccpad_right", NES_CCPAD_RIGHT)
SLOT_INTERFACE_END
SLOT_INTERFACE_START( fc_expansion_devices )
SLOT_INTERFACE("joypad", NES_JOYPAD)
SLOT_INTERFACE("arcstick", NES_ARCSTICK)
SLOT_INTERFACE("fc_keyboard", NES_FCKEYBOARD)
SLOT_INTERFACE("zapper", NES_ZAPPER)
SLOT_INTERFACE("vaus", NES_ARKPADDLE_FC)
SLOT_INTERFACE("family_trainer", NES_FTRAINER)
SLOT_INTERFACE("konamihs", NES_KONAMIHS)
SLOT_INTERFACE("mj_panel", NES_MJPANEL)
SLOT_INTERFACE("pachinko", NES_PACHINKO)
SLOT_INTERFACE("partytap", NES_PARTYTAP)
SLOT_INTERFACE("hori_twin", NES_HORITWIN)
SLOT_INTERFACE("hori_4p", NES_HORI4P)
SLOT_INTERFACE("barcode_battler", NES_BARCODE_BATTLER)
SLOT_INTERFACE("subor_keyboard", NES_SUBORKEYBOARD)
SLOT_INTERFACE_END
|