// 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)); }