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
|
// license:BSD-3-Clause
// copyright-holders:Fabio Priuli
/**********************************************************************
Sega SG-1000/Mark-III/SMS "Rapid Fire Unit" emulation
Release data from the Sega Retro project:
Year: 1985 Country/region: JP Model code: RF-150
Year: 1987 Country/region: US Model code: 3046
Year: 1988 Country/region: EU Model code: MK-3046-50
Year: 1989 Country/region: BR Model code: 011050
Notes:
This emulated device is the version released by Sega. In Brazil, Tec Toy
released a version that does not have any switch to turn on/off auto-repeat.
**********************************************************************/
#include "emu.h"
#include "rfu.h"
//**************************************************************************
// DEVICE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(SMS_RAPID_FIRE, sms_rapid_fire_device, "sms_rapid_fire", "Sega SMS Rapid Fire Unit")
// time interval not verified
#define RAPID_FIRE_INTERVAL attotime::from_hz(10)
static INPUT_PORTS_START( sms_rapid_fire )
PORT_START("rfu_sw") // Rapid Fire Unit switches
PORT_CONFNAME( 0x03, 0x00, "Rapid Fire Unit" )
PORT_CONFSETTING( 0x00, DEF_STR( Off ) )
PORT_CONFSETTING( 0x01, "Button 1" )
PORT_CONFSETTING( 0x02, "Button 2" )
PORT_CONFSETTING( 0x03, "Button 1 + 2" )
INPUT_PORTS_END
//-------------------------------------------------
// input_ports - device-specific input ports
//-------------------------------------------------
ioport_constructor sms_rapid_fire_device::device_input_ports() const
{
return INPUT_PORTS_NAME( sms_rapid_fire );
}
//**************************************************************************
// LIVE DEVICE
//**************************************************************************
//-------------------------------------------------
// sms_rapid_fire_device - constructor
//-------------------------------------------------
sms_rapid_fire_device::sms_rapid_fire_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, SMS_RAPID_FIRE, tag, owner, clock),
device_sms_control_port_interface(mconfig, *this),
m_rfire_sw(*this, "rfu_sw"),
m_subctrl_port(*this, "ctrl"),
m_read_state(0),
m_interval(RAPID_FIRE_INTERVAL)
{
}
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
void sms_rapid_fire_device::device_start()
{
m_start_time = machine().time();
save_item(NAME(m_start_time));
save_item(NAME(m_read_state));
}
//-------------------------------------------------
// sms_peripheral_r - rapid fire read
//-------------------------------------------------
uint8_t sms_rapid_fire_device::peripheral_r()
{
uint8_t data;
int num_intervals = (machine().time() - m_start_time).as_double() / m_interval.as_double();
m_read_state = num_intervals & 1;
data = m_subctrl_port->port_r();
/* Check Rapid Fire switch for Button 1 (TL) */
if (!(data & 0x20) && (m_rfire_sw->read() & 0x01))
data |= m_read_state << 5;
/* Check Rapid Fire switch for Button 2 (TR) */
if (!(data & 0x80) && (m_rfire_sw->read() & 0x02))
data |= m_read_state << 7;
return data;
}
//-------------------------------------------------
// sms_peripheral_w - rapid fire write
//-------------------------------------------------
void sms_rapid_fire_device::peripheral_w(uint8_t data)
{
m_subctrl_port->port_w(data);
}
//-------------------------------------------------
// device_add_mconfig - add device configuration
//-------------------------------------------------
WRITE_LINE_MEMBER( sms_rapid_fire_device::th_pin_w )
{
m_port->th_pin_w(state);
}
void sms_rapid_fire_device::device_add_mconfig(machine_config &config)
{
SMS_CONTROL_PORT(config, m_subctrl_port, sms_control_port_devices, "joypad");
if (m_port != nullptr)
m_subctrl_port->set_screen_tag(m_port->m_screen);
m_subctrl_port->th_input_handler().set(FUNC(sms_rapid_fire_device::th_pin_w));
}
|