summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/bus/nes_ctrl/ctrl.c
blob: 9e81d228f6a2c2b0148d873ed0785eb00d18c86c (plain) (blame)
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
208
/**********************************************************************

    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.

    Copyright MESS Team.
    Visit http://mamedev.org for licensing and usage restrictions.

**********************************************************************/

#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