| Previous | 199869 Revisions | Next |
| r23786 Wednesday 19th June, 2013 at 06:50:07 UTC by Fabio Priuli |
|---|
| (MESS) sms: Converted SMS inputs to use slot devices. You now select controllers in the Slot Devices menu of the internal UI, not in the Driver Configurations anymore. [Enik] |
| [src/mess] | mess.mak |
| [src/mess/drivers] | sms.c |
| [src/mess/includes] | sms.h |
| [src/mess/machine] | sms.c sms_joypad.c* sms_joypad.h* sms_lphaser.c* sms_lphaser.h* sms_paddle.c* sms_paddle.h* sms_rfu.c* sms_rfu.h* sms_sports.c* sms_sports.h* smsctrl.c* smsctrl.h* |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Rapid Fire Unit" emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #include "sms_rfu.h" | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | //************************************************************************** | |
| 15 | // DEVICE DEFINITIONS | |
| 16 | //************************************************************************** | |
| 17 | ||
| 18 | const device_type SMS_RAPID_FIRE = &device_creator<sms_rapid_fire_device>; | |
| 19 | ||
| 20 | ||
| 21 | #define RAPID_FIRE_INTERVAL attotime::from_hz(10) | |
| 22 | ||
| 23 | ||
| 24 | static INPUT_PORTS_START( sms_rapid_fire ) | |
| 25 | PORT_START("rfu_sw") // Rapid Fire Unit switches | |
| 26 | PORT_CONFNAME( 0x03, 0x00, "Rapid Fire Unit" ) | |
| 27 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) | |
| 28 | PORT_CONFSETTING( 0x01, "Button 1" ) | |
| 29 | PORT_CONFSETTING( 0x02, "Button 2" ) | |
| 30 | PORT_CONFSETTING( 0x03, "Button 1 + 2" ) | |
| 31 | INPUT_PORTS_END | |
| 32 | ||
| 33 | ||
| 34 | //------------------------------------------------- | |
| 35 | // input_ports - device-specific input ports | |
| 36 | //------------------------------------------------- | |
| 37 | ||
| 38 | ioport_constructor sms_rapid_fire_device::device_input_ports() const | |
| 39 | { | |
| 40 | return INPUT_PORTS_NAME( sms_rapid_fire ); | |
| 41 | } | |
| 42 | ||
| 43 | ||
| 44 | ||
| 45 | //************************************************************************** | |
| 46 | // LIVE DEVICE | |
| 47 | //************************************************************************** | |
| 48 | ||
| 49 | //------------------------------------------------- | |
| 50 | // sms_rapid_fire_device - constructor | |
| 51 | //------------------------------------------------- | |
| 52 | ||
| 53 | sms_rapid_fire_device::sms_rapid_fire_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 54 | device_t(mconfig, SMS_RAPID_FIRE, "Rapid Fire", tag, owner, clock, "sms_rapid_fire", __FILE__), | |
| 55 | device_sms_control_port_interface(mconfig, *this), | |
| 56 | m_rfire_sw(*this, "rfu_sw"), | |
| 57 | m_subctrl_port(*this, "ctrl"), | |
| 58 | m_rapid_fire_interval(RAPID_FIRE_INTERVAL) | |
| 59 | { | |
| 60 | } | |
| 61 | ||
| 62 | ||
| 63 | //------------------------------------------------- | |
| 64 | // device_start - device-specific startup | |
| 65 | //------------------------------------------------- | |
| 66 | ||
| 67 | void sms_rapid_fire_device::device_start() | |
| 68 | { | |
| 69 | save_item(NAME(m_rapid_fire_state)); | |
| 70 | m_subctrl_port->device_start(); | |
| 71 | } | |
| 72 | ||
| 73 | ||
| 74 | void sms_rapid_fire_device::device_reset() | |
| 75 | { | |
| 76 | m_rapid_fire_state = 0; | |
| 77 | } | |
| 78 | ||
| 79 | ||
| 80 | //------------------------------------------------- | |
| 81 | // sms_peripheral_r - rapid fire read | |
| 82 | //------------------------------------------------- | |
| 83 | ||
| 84 | UINT8 sms_rapid_fire_device::peripheral_r() | |
| 85 | { | |
| 86 | UINT8 data = 0xff; | |
| 87 | ||
| 88 | int n_intervals = machine().time().as_double() / m_rapid_fire_interval.as_double(); | |
| 89 | m_rapid_fire_state = n_intervals & 1; | |
| 90 | ||
| 91 | data = m_subctrl_port->port_r(); | |
| 92 | ||
| 93 | /* Check Rapid Fire switch for Button 1 (TL) */ | |
| 94 | if (!(data & 0x20) && (m_rfire_sw->read() & 0x01)) | |
| 95 | data |= m_rapid_fire_state << 5; | |
| 96 | ||
| 97 | /* Check Rapid Fire switch for Button 2 (TR) */ | |
| 98 | if (!(data & 0x80) && (m_rfire_sw->read() & 0x02)) | |
| 99 | data |= m_rapid_fire_state << 7; | |
| 100 | ||
| 101 | return data; | |
| 102 | } | |
| 103 | ||
| 104 | ||
| 105 | //------------------------------------------------- | |
| 106 | // sms_peripheral_w - rapid fire write | |
| 107 | //------------------------------------------------- | |
| 108 | ||
| 109 | void sms_rapid_fire_device::peripheral_w(UINT8 data) | |
| 110 | { | |
| 111 | m_subctrl_port->port_w(data); | |
| 112 | } | |
| 113 | ||
| 114 | ||
| 115 | //------------------------------------------------- | |
| 116 | // machine_config_additions - device-specific | |
| 117 | // machine configurations | |
| 118 | //------------------------------------------------- | |
| 119 | ||
| 120 | WRITE16_MEMBER( sms_rapid_fire_device::th_pin_w ) | |
| 121 | { | |
| 122 | m_port->th_pin_w(data); | |
| 123 | } | |
| 124 | ||
| 125 | ||
| 126 | READ32_MEMBER( sms_rapid_fire_device::pixel_r ) | |
| 127 | { | |
| 128 | return m_port->pixel_r(); | |
| 129 | } | |
| 130 | ||
| 131 | ||
| 132 | static MACHINE_CONFIG_FRAGMENT( rfire_slot ) | |
| 133 | MCFG_SMS_CONTROL_PORT_ADD("ctrl", sms_control_port_devices, "joypad") | |
| 134 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_rapid_fire_device, th_pin_w)) | |
| 135 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_rapid_fire_device, pixel_r)) | |
| 136 | MACHINE_CONFIG_END | |
| 137 | ||
| 138 | ||
| 139 | machine_config_constructor sms_rapid_fire_device::device_mconfig_additions() const | |
| 140 | { | |
| 141 | return MACHINE_CONFIG_NAME( rfire_slot ); | |
| 142 | } | |
| 143 |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Rapid Fire Unit" emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #pragma once | |
| 11 | ||
| 12 | #ifndef __SMS_RAPID_FIRE__ | |
| 13 | #define __SMS_RAPID_FIRE__ | |
| 14 | ||
| 15 | ||
| 16 | #include "emu.h" | |
| 17 | #include "machine/smsctrl.h" | |
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | //************************************************************************** | |
| 22 | // TYPE DEFINITIONS | |
| 23 | //************************************************************************** | |
| 24 | ||
| 25 | // ======================> sms_rapid_fire_device | |
| 26 | ||
| 27 | class sms_rapid_fire_device : public device_t, | |
| 28 | public device_sms_control_port_interface | |
| 29 | { | |
| 30 | public: | |
| 31 | // construction/destruction | |
| 32 | sms_rapid_fire_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 33 | ||
| 34 | // optional information overrides | |
| 35 | virtual ioport_constructor device_input_ports() const; | |
| 36 | ||
| 37 | WRITE16_MEMBER(th_pin_w); | |
| 38 | READ32_MEMBER(pixel_r); | |
| 39 | ||
| 40 | protected: | |
| 41 | // device-level overrides | |
| 42 | virtual void device_start(); | |
| 43 | virtual void device_reset(); | |
| 44 | virtual machine_config_constructor device_mconfig_additions() const; | |
| 45 | ||
| 46 | // device_sms_control_port_interface overrides | |
| 47 | virtual UINT8 peripheral_r(); | |
| 48 | virtual void peripheral_w(UINT8 data); | |
| 49 | ||
| 50 | private: | |
| 51 | required_ioport m_rfire_sw; | |
| 52 | required_device<sms_control_port_device> m_subctrl_port; | |
| 53 | ||
| 54 | UINT8 m_rapid_fire_state; | |
| 55 | const attotime m_rapid_fire_interval; | |
| 56 | }; | |
| 57 | ||
| 58 | ||
| 59 | // device type definition | |
| 60 | extern const device_type SMS_RAPID_FIRE; | |
| 61 | ||
| 62 | ||
| 63 | #endif |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Paddle Control" emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #include "sms_paddle.h" | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | //************************************************************************** | |
| 15 | // DEVICE DEFINITIONS | |
| 16 | //************************************************************************** | |
| 17 | ||
| 18 | const device_type SMS_PADDLE = &device_creator<sms_paddle_device>; | |
| 19 | ||
| 20 | ||
| 21 | #define PADDLE_INTERVAL attotime::from_hz(XTAL_53_693175MHz/15/256) | |
| 22 | ||
| 23 | ||
| 24 | DECLARE_CUSTOM_INPUT_MEMBER( sms_paddle_device::dir_pins_r ) | |
| 25 | { | |
| 26 | UINT8 data = m_paddle_x->read(); | |
| 27 | ||
| 28 | if (m_paddle_read_state) | |
| 29 | data >>= 4; | |
| 30 | ||
| 31 | // Return the inverted value for the PORT_BIT mapping. | |
| 32 | return ~data; | |
| 33 | } | |
| 34 | ||
| 35 | ||
| 36 | DECLARE_CUSTOM_INPUT_MEMBER( sms_paddle_device::tr_pin_r ) | |
| 37 | { | |
| 38 | // Return the inverted value for the PORT_BIT mapping. | |
| 39 | return ~m_paddle_read_state; | |
| 40 | } | |
| 41 | ||
| 42 | ||
| 43 | static INPUT_PORTS_START( sms_paddle ) | |
| 44 | PORT_START("CTRL_PORT") | |
| 45 | PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_paddle_device, dir_pins_r, NULL) // Directional pins | |
| 46 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc | |
| 47 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL | |
| 48 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // TH | |
| 49 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_paddle_device, tr_pin_r, NULL) | |
| 50 | ||
| 51 | PORT_START("PADDLE_X") // Paddle knob | |
| 52 | PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) | |
| 53 | INPUT_PORTS_END | |
| 54 | ||
| 55 | ||
| 56 | //------------------------------------------------- | |
| 57 | // input_ports - device-specific input ports | |
| 58 | //------------------------------------------------- | |
| 59 | ||
| 60 | ioport_constructor sms_paddle_device::device_input_ports() const | |
| 61 | { | |
| 62 | return INPUT_PORTS_NAME( sms_paddle ); | |
| 63 | } | |
| 64 | ||
| 65 | ||
| 66 | ||
| 67 | //************************************************************************** | |
| 68 | // LIVE DEVICE | |
| 69 | //************************************************************************** | |
| 70 | ||
| 71 | //------------------------------------------------- | |
| 72 | // sms_paddle_device - constructor | |
| 73 | //------------------------------------------------- | |
| 74 | ||
| 75 | sms_paddle_device::sms_paddle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 76 | device_t(mconfig, SMS_PADDLE, "Paddle", tag, owner, clock, "sms_paddle", __FILE__), | |
| 77 | device_sms_control_port_interface(mconfig, *this), | |
| 78 | m_paddle_pins(*this, "CTRL_PORT"), | |
| 79 | m_paddle_x(*this, "PADDLE_X"), | |
| 80 | m_paddle_interval(PADDLE_INTERVAL) | |
| 81 | { | |
| 82 | } | |
| 83 | ||
| 84 | ||
| 85 | //------------------------------------------------- | |
| 86 | // device_start - device-specific startup | |
| 87 | //------------------------------------------------- | |
| 88 | ||
| 89 | void sms_paddle_device::device_start() | |
| 90 | { | |
| 91 | save_item(NAME(m_paddle_read_state)); | |
| 92 | } | |
| 93 | ||
| 94 | ||
| 95 | void sms_paddle_device::device_reset() | |
| 96 | { | |
| 97 | m_paddle_read_state = 0; | |
| 98 | } | |
| 99 | ||
| 100 | ||
| 101 | //------------------------------------------------- | |
| 102 | // sms_peripheral_r - paddle read | |
| 103 | //------------------------------------------------- | |
| 104 | ||
| 105 | UINT8 sms_paddle_device::peripheral_r() | |
| 106 | { | |
| 107 | int n_intervals = machine().time().as_double() / m_paddle_interval.as_double(); | |
| 108 | m_paddle_read_state = n_intervals & 1; | |
| 109 | ||
| 110 | return m_paddle_pins->read(); | |
| 111 | } | |
| 112 |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Paddle Control" emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #pragma once | |
| 11 | ||
| 12 | #ifndef __SMS_PADDLE__ | |
| 13 | #define __SMS_PADDLE__ | |
| 14 | ||
| 15 | ||
| 16 | #include "emu.h" | |
| 17 | #include "machine/smsctrl.h" | |
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | //************************************************************************** | |
| 22 | // TYPE DEFINITIONS | |
| 23 | //************************************************************************** | |
| 24 | ||
| 25 | // ======================> sms_paddle_device | |
| 26 | ||
| 27 | class sms_paddle_device : public device_t, | |
| 28 | public device_sms_control_port_interface | |
| 29 | { | |
| 30 | public: | |
| 31 | // construction/destruction | |
| 32 | sms_paddle_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 33 | ||
| 34 | // optional information overrides | |
| 35 | virtual ioport_constructor device_input_ports() const; | |
| 36 | ||
| 37 | CUSTOM_INPUT_MEMBER( dir_pins_r ); | |
| 38 | CUSTOM_INPUT_MEMBER( tr_pin_r ); | |
| 39 | ||
| 40 | protected: | |
| 41 | // device-level overrides | |
| 42 | virtual void device_start(); | |
| 43 | virtual void device_reset(); | |
| 44 | ||
| 45 | // device_sms_control_port_interface overrides | |
| 46 | virtual UINT8 peripheral_r(); | |
| 47 | ||
| 48 | private: | |
| 49 | required_ioport m_paddle_pins; | |
| 50 | required_ioport m_paddle_x; | |
| 51 | ||
| 52 | UINT8 m_paddle_read_state; | |
| 53 | const attotime m_paddle_interval; | |
| 54 | }; | |
| 55 | ||
| 56 | ||
| 57 | // device type definition | |
| 58 | extern const device_type SMS_PADDLE; | |
| 59 | ||
| 60 | ||
| 61 | #endif |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System controller port emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #include "machine/smsctrl.h" | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | //************************************************************************** | |
| 15 | // GLOBAL VARIABLES | |
| 16 | //************************************************************************** | |
| 17 | ||
| 18 | const device_type SMS_CONTROL_PORT = &device_creator<sms_control_port_device>; | |
| 19 | ||
| 20 | ||
| 21 | ||
| 22 | //************************************************************************** | |
| 23 | // CARD INTERFACE | |
| 24 | //************************************************************************** | |
| 25 | ||
| 26 | //------------------------------------------------- | |
| 27 | // device_sms_control_port_interface - constructor | |
| 28 | //------------------------------------------------- | |
| 29 | ||
| 30 | device_sms_control_port_interface::device_sms_control_port_interface(const machine_config &mconfig, device_t &device) | |
| 31 | : device_slot_card_interface(mconfig,device) | |
| 32 | { | |
| 33 | m_port = dynamic_cast<sms_control_port_device *>(device.owner()); | |
| 34 | } | |
| 35 | ||
| 36 | ||
| 37 | //------------------------------------------------- | |
| 38 | // ~device_sms_control_port_interface - destructor | |
| 39 | //------------------------------------------------- | |
| 40 | ||
| 41 | device_sms_control_port_interface::~device_sms_control_port_interface() | |
| 42 | { | |
| 43 | } | |
| 44 | ||
| 45 | ||
| 46 | ||
| 47 | //************************************************************************** | |
| 48 | // LIVE DEVICE | |
| 49 | //************************************************************************** | |
| 50 | ||
| 51 | //------------------------------------------------- | |
| 52 | // sms_control_port_device - constructor | |
| 53 | //------------------------------------------------- | |
| 54 | ||
| 55 | sms_control_port_device::sms_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 56 | device_t(mconfig, SMS_CONTROL_PORT, "Sega SMS control port", tag, owner, clock), | |
| 57 | device_slot_interface(mconfig, *this), | |
| 58 | m_th_pin_handler(*this), | |
| 59 | m_pixel_handler(*this) | |
| 60 | { | |
| 61 | } | |
| 62 | ||
| 63 | ||
| 64 | //------------------------------------------------- | |
| 65 | // sms_control_port_device - destructor | |
| 66 | //------------------------------------------------- | |
| 67 | ||
| 68 | sms_control_port_device::~sms_control_port_device() | |
| 69 | { | |
| 70 | } | |
| 71 | ||
| 72 | ||
| 73 | //------------------------------------------------- | |
| 74 | // device_start - device-specific startup | |
| 75 | //------------------------------------------------- | |
| 76 | ||
| 77 | void sms_control_port_device::device_start() | |
| 78 | { | |
| 79 | m_device = dynamic_cast<device_sms_control_port_interface *>(get_card_device()); | |
| 80 | ||
| 81 | m_th_pin_handler.resolve_safe(); | |
| 82 | m_pixel_handler.resolve_safe(0); | |
| 83 | } | |
| 84 | ||
| 85 | ||
| 86 | UINT8 sms_control_port_device::port_r() | |
| 87 | { | |
| 88 | UINT8 data = 0xff; | |
| 89 | if (m_device) | |
| 90 | data = m_device->peripheral_r(); | |
| 91 | return data; | |
| 92 | } | |
| 93 | ||
| 94 | void sms_control_port_device::port_w( UINT8 data ) | |
| 95 | { | |
| 96 | if (m_device) | |
| 97 | m_device->peripheral_w(data); | |
| 98 | } | |
| 99 | ||
| 100 | ||
| 101 | void sms_control_port_device::th_pin_w(UINT16 data) | |
| 102 | { | |
| 103 | m_th_pin_handler(data); | |
| 104 | } | |
| 105 | ||
| 106 | UINT32 sms_control_port_device::pixel_r() | |
| 107 | { | |
| 108 | return m_pixel_handler(); | |
| 109 | } | |
| 110 | ||
| 111 | ||
| 112 | //------------------------------------------------- | |
| 113 | // SLOT_INTERFACE( sms_control_port_devices ) | |
| 114 | //------------------------------------------------- | |
| 115 | ||
| 116 | SLOT_INTERFACE_START( sms_control_port_devices ) | |
| 117 | SLOT_INTERFACE("joypad", SMS_JOYPAD) | |
| 118 | SLOT_INTERFACE("lphaser", SMS_LIGHT_PHASER) | |
| 119 | SLOT_INTERFACE("paddle", SMS_PADDLE) | |
| 120 | SLOT_INTERFACE("sportspad", SMS_SPORTS_PAD) | |
| 121 | SLOT_INTERFACE("rapidfire", SMS_RAPID_FIRE) | |
| 122 | SLOT_INTERFACE_END |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System controller port emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | ********************************************************************** | |
| 9 | ||
| 10 | ||
| 11 | **********************************************************************/ | |
| 12 | ||
| 13 | #pragma once | |
| 14 | ||
| 15 | #ifndef __SMS_CONTROL_PORT__ | |
| 16 | #define __SMS_CONTROL_PORT__ | |
| 17 | ||
| 18 | #include "emu.h" | |
| 19 | ||
| 20 | ||
| 21 | ||
| 22 | //************************************************************************** | |
| 23 | // INTERFACE CONFIGURATION MACROS | |
| 24 | //************************************************************************** | |
| 25 | ||
| 26 | #define MCFG_SMS_CONTROL_PORT_ADD(_tag, _slot_intf, _def_slot) \ | |
| 27 | MCFG_DEVICE_ADD(_tag, SMS_CONTROL_PORT, 0) \ | |
| 28 | MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) | |
| 29 | ||
| 30 | ||
| 31 | #define MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(_devcb) \ | |
| 32 | devcb = &sms_control_port_device::set_th_input_handler(*device, DEVCB2_##_devcb); | |
| 33 | ||
| 34 | ||
| 35 | #define MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(_devcb) \ | |
| 36 | devcb = &sms_control_port_device::set_pixel_handler(*device, DEVCB2_##_devcb); | |
| 37 | ||
| 38 | ||
| 39 | ||
| 40 | //************************************************************************** | |
| 41 | // TYPE DEFINITIONS | |
| 42 | //************************************************************************** | |
| 43 | ||
| 44 | // ======================> sms_control_port_device | |
| 45 | ||
| 46 | class device_sms_control_port_interface; | |
| 47 | ||
| 48 | class sms_control_port_device : public device_t, | |
| 49 | public device_slot_interface | |
| 50 | { | |
| 51 | public: | |
| 52 | // construction/destruction | |
| 53 | sms_control_port_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 54 | virtual ~sms_control_port_device(); | |
| 55 | ||
| 56 | // static configuration helpers | |
| 57 | template<class _Object> static devcb2_base &set_th_input_handler(device_t &device, _Object object) { return downcast<sms_control_port_device &>(device).m_th_pin_handler.set_callback(object); } | |
| 58 | ||
| 59 | template<class _Object> static devcb2_base &set_pixel_handler(device_t &device, _Object object) { return downcast<sms_control_port_device &>(device).m_pixel_handler.set_callback(object); } | |
| 60 | ||
| 61 | // Physical DE-9 connector interface | |
| 62 | ||
| 63 | // Data returned by the port_r methods: | |
| 64 | // bit 0 - pin 1 - Up | |
| 65 | // bit 1 - pin 2 - Down | |
| 66 | // bit 2 - pin 3 - Left | |
| 67 | // bit 3 - pin 4 - Right | |
| 68 | // bit 4 - pin 5 - Vcc (no data) | |
| 69 | // bit 5 - pin 6 - TL (Button 1/Light Phaser Trigger) | |
| 70 | // bit 6 - pin 7 - TH (Light Phaser sensor) | |
| 71 | // pin 8 - GND | |
| 72 | // bit 7 - pin 9 - TR (Button 2) | |
| 73 | // | |
| 74 | UINT8 port_r(); | |
| 75 | void port_w( UINT8 data ); | |
| 76 | ||
| 77 | void th_pin_w(UINT16 data); | |
| 78 | UINT32 pixel_r(); | |
| 79 | ||
| 80 | //protected: | |
| 81 | // device-level overrides | |
| 82 | virtual void device_start(); | |
| 83 | ||
| 84 | device_sms_control_port_interface *m_device; | |
| 85 | ||
| 86 | private: | |
| 87 | devcb2_write16 m_th_pin_handler; | |
| 88 | devcb2_read32 m_pixel_handler; | |
| 89 | }; | |
| 90 | ||
| 91 | ||
| 92 | // ======================> device_sms_control_port_interface | |
| 93 | ||
| 94 | // class representing interface-specific live sms_expansion card | |
| 95 | class device_sms_control_port_interface : public device_slot_card_interface | |
| 96 | { | |
| 97 | public: | |
| 98 | // construction/destruction | |
| 99 | device_sms_control_port_interface(const machine_config &mconfig, device_t &device); | |
| 100 | virtual ~device_sms_control_port_interface(); | |
| 101 | ||
| 102 | virtual UINT8 peripheral_r() { return 0xff; }; | |
| 103 | virtual void peripheral_w(UINT8 data) { }; | |
| 104 | ||
| 105 | protected: | |
| 106 | sms_control_port_device *m_port; | |
| 107 | }; | |
| 108 | ||
| 109 | ||
| 110 | // device type definition | |
| 111 | extern const device_type SMS_CONTROL_PORT; | |
| 112 | ||
| 113 | ||
| 114 | // slot devices | |
| 115 | #include "machine/sms_joypad.h" | |
| 116 | #include "machine/sms_lphaser.h" | |
| 117 | #include "machine/sms_paddle.h" | |
| 118 | #include "machine/sms_sports.h" | |
| 119 | #include "machine/sms_rfu.h" | |
| 120 | ||
| 121 | SLOT_INTERFACE_EXTERN( sms_control_port_devices ); | |
| 122 | ||
| 123 | ||
| 124 | #endif |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Sports Pad" emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #include "sms_sports.h" | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | //************************************************************************** | |
| 15 | // DEVICE DEFINITIONS | |
| 16 | //************************************************************************** | |
| 17 | ||
| 18 | const device_type SMS_SPORTS_PAD = &device_creator<sms_sports_pad_device>; | |
| 19 | ||
| 20 | ||
| 21 | #define SPORTS_PAD_INTERVAL attotime::from_hz(XTAL_53_693175MHz/15/512) | |
| 22 | ||
| 23 | ||
| 24 | DECLARE_CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r ) | |
| 25 | { | |
| 26 | UINT8 data = 0xff; | |
| 27 | ||
| 28 | switch (m_sports_pad_state) | |
| 29 | { | |
| 30 | case 0: | |
| 31 | data = (m_sports_x->read() >> 4); | |
| 32 | break; | |
| 33 | case 1: | |
| 34 | data = m_sports_x->read(); | |
| 35 | break; | |
| 36 | case 2: | |
| 37 | data = (m_sports_y->read() >> 4); | |
| 38 | break; | |
| 39 | case 3: | |
| 40 | data = m_sports_y->read(); | |
| 41 | break; | |
| 42 | } | |
| 43 | ||
| 44 | // Return the inverted value for the PORT_BIT mapping. | |
| 45 | return ~(data & 0x0f); | |
| 46 | } | |
| 47 | ||
| 48 | ||
| 49 | DECLARE_CUSTOM_INPUT_MEMBER( sms_sports_pad_device::th_pin_r ) | |
| 50 | { | |
| 51 | return m_sports_pad_last_data; | |
| 52 | } | |
| 53 | ||
| 54 | ||
| 55 | DECLARE_INPUT_CHANGED_MEMBER( sms_sports_pad_device::th_pin_w ) | |
| 56 | { | |
| 57 | attotime cur_time = machine().time(); | |
| 58 | ||
| 59 | if (cur_time - m_sports_pad_last_time > m_sports_pad_interval) | |
| 60 | { | |
| 61 | m_sports_pad_state = 0; | |
| 62 | } | |
| 63 | else | |
| 64 | { | |
| 65 | m_sports_pad_state = (m_sports_pad_state + 1) & 3; | |
| 66 | } | |
| 67 | m_sports_pad_last_time = cur_time; | |
| 68 | m_sports_pad_last_data = newval; | |
| 69 | } | |
| 70 | ||
| 71 | ||
| 72 | static INPUT_PORTS_START( sms_sports_pad ) | |
| 73 | PORT_START("SPORTS_IN") | |
| 74 | PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, dir_pins_r, NULL) // Directional pins | |
| 75 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc | |
| 76 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (Button 1) | |
| 77 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_r, NULL) | |
| 78 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) // TR (Button 2) | |
| 79 | ||
| 80 | PORT_START("SPORTS_OUT") | |
| 81 | PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) // Directional pins | |
| 82 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc | |
| 83 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // TL (Button 1) | |
| 84 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OUTPUT ) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_w, NULL) | |
| 85 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // TR (Button 2) | |
| 86 | ||
| 87 | PORT_START("SPORTS_X") /* Sports Pad X axis */ | |
| 88 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE | |
| 89 | ||
| 90 | PORT_START("SPORTS_Y") /* Sports Pad Y axis */ | |
| 91 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE | |
| 92 | INPUT_PORTS_END | |
| 93 | ||
| 94 | ||
| 95 | //------------------------------------------------- | |
| 96 | // input_ports - device-specific input ports | |
| 97 | //------------------------------------------------- | |
| 98 | ||
| 99 | ioport_constructor sms_sports_pad_device::device_input_ports() const | |
| 100 | { | |
| 101 | return INPUT_PORTS_NAME( sms_sports_pad ); | |
| 102 | } | |
| 103 | ||
| 104 | ||
| 105 | ||
| 106 | //************************************************************************** | |
| 107 | // LIVE DEVICE | |
| 108 | //************************************************************************** | |
| 109 | ||
| 110 | //------------------------------------------------- | |
| 111 | // sms_sports_pad_device - constructor | |
| 112 | //------------------------------------------------- | |
| 113 | ||
| 114 | sms_sports_pad_device::sms_sports_pad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 115 | device_t(mconfig, SMS_SPORTS_PAD, "Sports Pad", tag, owner, clock, "sms_sports_pad", __FILE__), | |
| 116 | device_sms_control_port_interface(mconfig, *this), | |
| 117 | m_sports_in(*this, "SPORTS_IN"), | |
| 118 | m_sports_out(*this, "SPORTS_OUT"), | |
| 119 | m_sports_x(*this, "SPORTS_X"), | |
| 120 | m_sports_y(*this, "SPORTS_Y"), | |
| 121 | m_sports_pad_interval(SPORTS_PAD_INTERVAL) | |
| 122 | { | |
| 123 | } | |
| 124 | ||
| 125 | ||
| 126 | //------------------------------------------------- | |
| 127 | // device_start - device-specific startup | |
| 128 | //------------------------------------------------- | |
| 129 | ||
| 130 | void sms_sports_pad_device::device_start() | |
| 131 | { | |
| 132 | save_item(NAME(m_sports_pad_state)); | |
| 133 | save_item(NAME(m_sports_pad_last_data)); | |
| 134 | save_item(NAME(m_sports_pad_last_time)); | |
| 135 | } | |
| 136 | ||
| 137 | ||
| 138 | void sms_sports_pad_device::device_reset() | |
| 139 | { | |
| 140 | m_sports_pad_state = 0; | |
| 141 | m_sports_pad_last_data = 0; | |
| 142 | m_sports_pad_last_time = machine().time(); | |
| 143 | } | |
| 144 | ||
| 145 | ||
| 146 | //------------------------------------------------- | |
| 147 | // sms_peripheral_r - sports pad read | |
| 148 | //------------------------------------------------- | |
| 149 | ||
| 150 | UINT8 sms_sports_pad_device::peripheral_r() | |
| 151 | { | |
| 152 | return m_sports_in->read(); | |
| 153 | } | |
| 154 | ||
| 155 | ||
| 156 | //------------------------------------------------- | |
| 157 | // sms_peripheral_w - sports pad write | |
| 158 | //------------------------------------------------- | |
| 159 | ||
| 160 | void sms_sports_pad_device::peripheral_w(UINT8 data) | |
| 161 | { | |
| 162 | m_sports_out->write(data); | |
| 163 | } | |
| 164 |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Sports Pad" emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #pragma once | |
| 11 | ||
| 12 | #ifndef __SMS_SPORTS_PAD__ | |
| 13 | #define __SMS_SPORTS_PAD__ | |
| 14 | ||
| 15 | ||
| 16 | #include "emu.h" | |
| 17 | #include "machine/smsctrl.h" | |
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | //************************************************************************** | |
| 22 | // TYPE DEFINITIONS | |
| 23 | //************************************************************************** | |
| 24 | ||
| 25 | // ======================> sms_sports_pad_device | |
| 26 | ||
| 27 | class sms_sports_pad_device : public device_t, | |
| 28 | public device_sms_control_port_interface | |
| 29 | { | |
| 30 | public: | |
| 31 | // construction/destruction | |
| 32 | sms_sports_pad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 33 | ||
| 34 | // optional information overrides | |
| 35 | virtual ioport_constructor device_input_ports() const; | |
| 36 | ||
| 37 | CUSTOM_INPUT_MEMBER( dir_pins_r ); | |
| 38 | CUSTOM_INPUT_MEMBER( th_pin_r ); | |
| 39 | INPUT_CHANGED_MEMBER( th_pin_w ); | |
| 40 | ||
| 41 | protected: | |
| 42 | // device-level overrides | |
| 43 | virtual void device_start(); | |
| 44 | virtual void device_reset(); | |
| 45 | ||
| 46 | // device_sms_control_port_interface overrides | |
| 47 | virtual UINT8 peripheral_r(); | |
| 48 | virtual void peripheral_w(UINT8 data); | |
| 49 | ||
| 50 | private: | |
| 51 | required_ioport m_sports_in; | |
| 52 | required_ioport m_sports_out; | |
| 53 | required_ioport m_sports_x; | |
| 54 | required_ioport m_sports_y; | |
| 55 | ||
| 56 | UINT8 m_sports_pad_state; | |
| 57 | UINT8 m_sports_pad_last_data; | |
| 58 | const attotime m_sports_pad_interval; | |
| 59 | attotime m_sports_pad_last_time; | |
| 60 | }; | |
| 61 | ||
| 62 | ||
| 63 | // device type definition | |
| 64 | extern const device_type SMS_SPORTS_PAD; | |
| 65 | ||
| 66 | ||
| 67 | #endif |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r23785 | r23786 | |
|---|---|---|
| 13 | 13 | #define ENABLE_CART 3 |
| 14 | 14 | #define ENABLE_BIOS 4 |
| 15 | 15 | |
| 16 | #define LGUN_RADIUS 6 | |
| 17 | #define LGUN_X_INTERVAL 4 | |
| 18 | 16 | |
| 19 | void sms_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) | |
| 20 | { | |
| 21 | switch (id) | |
| 22 | { | |
| 23 | case TIMER_RAPID_FIRE: | |
| 24 | rapid_fire_callback(ptr, param); | |
| 25 | break; | |
| 26 | case TIMER_LIGHTGUN_TICK: | |
| 27 | lightgun_tick(ptr, param); | |
| 28 | break; | |
| 29 | case TIMER_LPHASER_1: | |
| 30 | lphaser_1_callback(ptr, param); | |
| 31 | break; | |
| 32 | case TIMER_LPHASER_2: | |
| 33 | lphaser_2_callback(ptr, param); | |
| 34 | break; | |
| 35 | default: | |
| 36 | assert_always(FALSE, "Unknown id in sms_state::device_timer"); | |
| 37 | } | |
| 38 | } | |
| 39 | ||
| 40 | ||
| 41 | TIMER_CALLBACK_MEMBER(sms_state::rapid_fire_callback) | |
| 42 | { | |
| 43 | m_rapid_fire_state_1 ^= 0xff; | |
| 44 | m_rapid_fire_state_2 ^= 0xff; | |
| 45 | } | |
| 46 | ||
| 47 | ||
| 48 | ||
| 49 | WRITE8_MEMBER(sms_state::sms_input_write) | |
| 50 | { | |
| 51 | switch (offset) | |
| 52 | { | |
| 53 | case 0: | |
| 54 | switch (m_port_ctrlsel->read_safe(0x00) & 0x0f) | |
| 55 | { | |
| 56 | case 0x04: /* Sports Pad */ | |
| 57 | if (data != m_sports_pad_last_data_1) | |
| 58 | { | |
| 59 | UINT32 cpu_cycles = m_maincpu->total_cycles(); | |
| 60 | ||
| 61 | m_sports_pad_last_data_1 = data; | |
| 62 | if (cpu_cycles - m_last_sports_pad_time_1 > 512) | |
| 63 | { | |
| 64 | m_sports_pad_state_1 = 3; | |
| 65 | m_sports_pad_1_x = m_port_sport0->read(); | |
| 66 | m_sports_pad_1_y = m_port_sport1->read(); | |
| 67 | } | |
| 68 | m_last_sports_pad_time_1 = cpu_cycles; | |
| 69 | m_sports_pad_state_1 = (m_sports_pad_state_1 + 1) & 3; | |
| 70 | } | |
| 71 | break; | |
| 72 | } | |
| 73 | break; | |
| 74 | ||
| 75 | case 1: | |
| 76 | switch (m_port_ctrlsel->read_safe(0x00) & 0xf0) | |
| 77 | { | |
| 78 | case 0x40: /* Sports Pad */ | |
| 79 | if (data != m_sports_pad_last_data_2) | |
| 80 | { | |
| 81 | UINT32 cpu_cycles = m_maincpu->total_cycles(); | |
| 82 | ||
| 83 | m_sports_pad_last_data_2 = data; | |
| 84 | if (cpu_cycles - m_last_sports_pad_time_2 > 2048) | |
| 85 | { | |
| 86 | m_sports_pad_state_2 = 3; | |
| 87 | m_sports_pad_2_x = m_port_sport2->read(); | |
| 88 | m_sports_pad_2_y = m_port_sport3->read(); | |
| 89 | } | |
| 90 | m_last_sports_pad_time_2 = cpu_cycles; | |
| 91 | m_sports_pad_state_2 = (m_sports_pad_state_2 + 1) & 3; | |
| 92 | } | |
| 93 | break; | |
| 94 | } | |
| 95 | break; | |
| 96 | } | |
| 97 | } | |
| 98 | ||
| 99 | ||
| 100 | /* | |
| 101 | Light Phaser (light gun) emulation notes: | |
| 102 | - The sensor is activated based on color brightness of some individual | |
| 103 | pixels being drawn by the beam, at circular area where the gun is aiming. | |
| 104 | - Currently, brightness is calculated based only on single pixels. | |
| 105 | - In general, after the trigger is pressed, games draw the next frame using | |
| 106 | a light color pattern, to make sure sensor will be activated. If emulation | |
| 107 | skips that frame, sensor may stay deactivated. Frameskip set to 0 (no skip) is | |
| 108 | recommended to avoid problems. | |
| 109 | - When sensor switches from off to on, a value is latched for HCount register | |
| 110 | and a flag is set. The emulation uses the flag to avoid sequential latches and | |
| 111 | to signal that TH line is activated when the status of the input port is read. | |
| 112 | When the status is read, the flag is cleared, or else it is cleared later when | |
| 113 | the Pause status is read (end of a frame). This is necessary because the | |
| 114 | "Color & Switch Test" ROM only reads the TH bit after the VINT line. | |
| 115 | - The gun test of "Color & Switch Test" is an example that requires checks | |
| 116 | of sensor status independent of other events, like trigger press or TH bit | |
| 117 | reads. Another example is the title screen of "Hang-On & Safari Hunt", where | |
| 118 | the game only reads HCount register in a loop, expecting a latch by the gun. | |
| 119 | - The whole procedure is managed by a timer callback, that always reschedule | |
| 120 | itself to run in some intervals when the beam is at the circular area. | |
| 121 | */ | |
| 122 | int sms_state::lgun_bright_aim_area( emu_timer *timer, int lgun_x, int lgun_y ) | |
| 123 | { | |
| 124 | const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; | |
| 125 | const rectangle &visarea = m_main_scr->visible_area(); | |
| 126 | int beam_x = m_main_scr->hpos(); | |
| 127 | int beam_y = m_main_scr->vpos(); | |
| 128 | int dx, dy; | |
| 129 | int result = 0; | |
| 130 | int pos_changed = 0; | |
| 131 | double dx_radius; | |
| 132 | ||
| 133 | while (1) | |
| 134 | { | |
| 135 | /* If beam's y isn't at a line where the aim area is, change it | |
| 136 | the next line it enters that area. */ | |
| 137 | dy = abs(beam_y - lgun_y); | |
| 138 | if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y) | |
| 139 | { | |
| 140 | beam_y = lgun_y - LGUN_RADIUS; | |
| 141 | if (beam_y < visarea.min_y) | |
| 142 | beam_y = visarea.min_y; | |
| 143 | dy = abs(beam_y - lgun_y); | |
| 144 | pos_changed = 1; | |
| 145 | } | |
| 146 | ||
| 147 | /* Caculate distance in x of the radius, relative to beam's y distance. | |
| 148 | First try some shortcuts. */ | |
| 149 | switch (dy) | |
| 150 | { | |
| 151 | case LGUN_RADIUS: | |
| 152 | dx_radius = 0; | |
| 153 | break; | |
| 154 | case 0: | |
| 155 | dx_radius = LGUN_RADIUS; | |
| 156 | break; | |
| 157 | default: | |
| 158 | /* step 1: r^2 = dx^2 + dy^2 */ | |
| 159 | /* step 2: dx^2 = r^2 - dy^2 */ | |
| 160 | /* step 3: dx = sqrt(r^2 - dy^2) */ | |
| 161 | dx_radius = ceil((float) sqrt((float) (r_x_r - (dy * dy)))); | |
| 162 | } | |
| 163 | ||
| 164 | /* If beam's x isn't in the circular aim area, change it | |
| 165 | to the next point it enters that area. */ | |
| 166 | dx = abs(beam_x - lgun_x); | |
| 167 | if (dx > dx_radius || beam_x < visarea.min_x || beam_x > visarea.max_x) | |
| 168 | { | |
| 169 | /* If beam's x has passed the aim area, advance to | |
| 170 | next line and recheck y/x coordinates. */ | |
| 171 | if (beam_x > lgun_x) | |
| 172 | { | |
| 173 | beam_x = 0; | |
| 174 | beam_y++; | |
| 175 | continue; | |
| 176 | } | |
| 177 | beam_x = lgun_x - dx_radius; | |
| 178 | if (beam_x < visarea.min_x) | |
| 179 | beam_x = visarea.min_x; | |
| 180 | pos_changed = 1; | |
| 181 | } | |
| 182 | ||
| 183 | if (!pos_changed) | |
| 184 | { | |
| 185 | bitmap_rgb32 &bitmap = m_vdp->get_bitmap(); | |
| 186 | ||
| 187 | /* brightness of the lightgray color in the frame drawn by Light Phaser games */ | |
| 188 | const UINT8 sensor_min_brightness = 0x7f; | |
| 189 | ||
| 190 | /* TODO: Check how Light Phaser behaves for border areas. For Gangster Town, should */ | |
| 191 | /* a shot at right border (HC~=0x90) really appear at active scr, near to left border? */ | |
| 192 | if (beam_x < SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH || beam_x >= SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256) | |
| 193 | return 0; | |
| 194 | ||
| 195 | rgb_t color = bitmap.pix32(beam_y, beam_x); | |
| 196 | ||
| 197 | /* reference: http://www.w3.org/TR/AERT#color-contrast */ | |
| 198 | UINT8 brightness = (RGB_RED(color) * 0.299) + (RGB_GREEN(color) * 0.587) + (RGB_BLUE(color) * 0.114); | |
| 199 | //printf ("color brightness: %2X for x %d y %d\n", brightness, beam_x, beam_y); | |
| 200 | ||
| 201 | result = (brightness >= sensor_min_brightness) ? 1 : 0; | |
| 202 | ||
| 203 | /* next check at same line */ | |
| 204 | beam_x += LGUN_X_INTERVAL; | |
| 205 | pos_changed = 1; | |
| 206 | } | |
| 207 | else | |
| 208 | break; | |
| 209 | } | |
| 210 | timer->adjust(m_main_scr->time_until_pos(beam_y, beam_x)); | |
| 211 | ||
| 212 | return result; | |
| 213 | } | |
| 214 | ||
| 215 | ||
| 216 | 17 | void sms_state::lphaser_hcount_latch( int hpos ) |
| 217 | 18 | { |
| 218 | 19 | /* A delay seems to occur when the Light Phaser latches the |
| r23785 | r23786 | |
| 221 | 22 | } |
| 222 | 23 | |
| 223 | 24 | |
| 224 | ||
| 25 | WRITE16_MEMBER(sms_state::sms_ctrl1_th_input) | |
| 225 | 26 | { |
| 226 | const rectangle &visarea = m_main_scr->visible_area(); | |
| 227 | int offset_x = (scaled_hpos * (visarea.max_x - visarea.min_x)) / 255; | |
| 228 | return visarea.min_x + offset_x; | |
| 229 | } | |
| 230 | ||
| 231 | ||
| 232 | UINT16 sms_state::screen_vpos_nonscaled(int scaled_vpos) | |
| 233 | { | |
| 234 | const rectangle &visarea = m_main_scr->visible_area(); | |
| 235 | int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255; | |
| 236 | return visarea.min_y + offset_y; | |
| 237 | } | |
| 238 | ||
| 239 | ||
| 240 | void sms_state::lphaser1_sensor_check() | |
| 241 | { | |
| 242 | const int x = screen_hpos_nonscaled(m_port_lphas0->read()); | |
| 243 | const int y = screen_vpos_nonscaled(m_port_lphas1->read()); | |
| 244 | ||
| 245 | if (lgun_bright_aim_area(m_lphaser_1_timer, x, y)) | |
| 27 | if (m_ctrl1_th_latch == 0) | |
| 246 | 28 | { |
| 247 | if (m_lphaser_1_latch == 0) | |
| 248 | { | |
| 249 | m_lphaser_1_latch = 1; | |
| 250 | lphaser_hcount_latch(x); | |
| 251 | } | |
| 29 | m_ctrl1_th_latch = 1; | |
| 30 | lphaser_hcount_latch(data); | |
| 252 | 31 | } |
| 253 | 32 | } |
| 254 | 33 | |
| 255 | void sms_state::lphaser2_sensor_check() | |
| 256 | { | |
| 257 | const int x = screen_hpos_nonscaled(m_port_lphas2->read()); | |
| 258 | const int y = screen_vpos_nonscaled(m_port_lphas3->read()); | |
| 259 | 34 | |
| 260 | if (lgun_bright_aim_area(m_lphaser_2_timer, x, y)) | |
| 261 | { | |
| 262 | if (m_lphaser_2_latch == 0) | |
| 263 | { | |
| 264 | m_lphaser_2_latch = 1; | |
| 265 | lphaser_hcount_latch(x); | |
| 266 | } | |
| 267 | } | |
| 268 | } | |
| 269 | ||
| 270 | ||
| 271 | // at each input port read we check if lightguns are enabled in one of the ports: | |
| 272 | // if so, we turn on crosshair and the lightgun timer | |
| 273 | TIMER_CALLBACK_MEMBER(sms_state::lightgun_tick) | |
| 35 | WRITE16_MEMBER(sms_state::sms_ctrl2_th_input) | |
| 274 | 36 | { |
| 275 | if ( | |
| 37 | if (m_ctrl2_th_latch == 0) | |
| 276 | 38 | { |
| 277 | /* enable crosshair */ | |
| 278 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_ALL); | |
| 279 | if (!m_lphaser_1_timer->enabled()) | |
| 280 | lphaser1_sensor_check(); | |
| 39 | m_ctrl2_th_latch = 1; | |
| 40 | lphaser_hcount_latch(data); | |
| 281 | 41 | } |
| 282 | else | |
| 283 | { | |
| 284 | /* disable crosshair */ | |
| 285 | crosshair_set_screen(machine(), 0, CROSSHAIR_SCREEN_NONE); | |
| 286 | m_lphaser_1_timer->enable(0); | |
| 287 | } | |
| 288 | ||
| 289 | if ((m_port_ctrlsel->read_safe(0x00) & 0xf0) == 0x10) | |
| 290 | { | |
| 291 | /* enable crosshair */ | |
| 292 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_ALL); | |
| 293 | if (!m_lphaser_2_timer->enabled()) | |
| 294 | lphaser2_sensor_check(); | |
| 295 | } | |
| 296 | else | |
| 297 | { | |
| 298 | /* disable crosshair */ | |
| 299 | crosshair_set_screen(machine(), 1, CROSSHAIR_SCREEN_NONE); | |
| 300 | m_lphaser_2_timer->enable(0); | |
| 301 | } | |
| 302 | 42 | } |
| 303 | 43 | |
| 304 | 44 | |
| 305 | TIMER_CALLBACK_MEMBER(sms_state::lphaser_1_callback) | |
| 306 | { | |
| 307 | lphaser1_sensor_check(); | |
| 308 | } | |
| 309 | ||
| 310 | ||
| 311 | TIMER_CALLBACK_MEMBER(sms_state::lphaser_2_callback) | |
| 312 | { | |
| 313 | lphaser2_sensor_check(); | |
| 314 | } | |
| 315 | ||
| 316 | ||
| 317 | INPUT_CHANGED_MEMBER(sms_state::lgun1_changed) | |
| 318 | { | |
| 319 | if (!m_lphaser_1_timer || | |
| 320 | (m_port_ctrlsel->read_safe(0x00) & 0x0f) != 0x01) | |
| 321 | return; | |
| 322 | ||
| 323 | if (newval != oldval) | |
| 324 | lphaser1_sensor_check(); | |
| 325 | } | |
| 326 | ||
| 327 | INPUT_CHANGED_MEMBER(sms_state::lgun2_changed) | |
| 328 | { | |
| 329 | if (!m_lphaser_2_timer || | |
| 330 | (m_port_ctrlsel->read_safe(0x00) & 0xf0) != 0x10) | |
| 331 | return; | |
| 332 | ||
| 333 | if (newval != oldval) | |
| 334 | lphaser2_sensor_check(); | |
| 335 | } | |
| 336 | ||
| 337 | ||
| 338 | 45 | void sms_state::sms_get_inputs( address_space &space ) |
| 339 | 46 | { |
| 340 | UINT8 data = 0x00; | |
| 341 | UINT32 cpu_cycles = m_maincpu->total_cycles(); | |
| 47 | UINT8 data; | |
| 342 | 48 | |
| 343 | m_input_port0 = 0xff; | |
| 344 | m_input_port1 = 0xff; | |
| 49 | m_port_dc_reg = 0xff; | |
| 50 | m_port_dd_reg = 0xff; | |
| 345 | 51 | |
| 346 | if (cpu_cycles - m_last_paddle_read_time > 256) | |
| 347 | { | |
| 348 | m_paddle_read_state ^= 0xff; | |
| 349 | m_last_paddle_read_time = cpu_cycles; | |
| 350 | } | |
| 52 | data = m_port_ctrl1->port_r(); | |
| 53 | m_port_dc_reg &= ~0x0F | data; // Up, Down, Left, Right | |
| 54 | m_port_dc_reg &= ~0x10 | (data >> 1); // TL (Button 1) | |
| 55 | m_port_dc_reg &= ~0x20 | (data >> 2); // TR (Button 2) | |
| 56 | m_port_dd_reg &= ~0x40 | data; // TH | |
| 351 | 57 | |
| 352 | /* Check if lightgun has been chosen as input: if so, enable crosshair */ | |
| 353 | timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); | |
| 354 | ||
| 355 | /* Player 1 */ | |
| 356 | switch (m_port_ctrlsel->read_safe(0x00) & 0x0f) | |
| 357 | { | |
| 358 | case 0x00: /* Joystick */ | |
| 359 | data = m_port_dc->read(); | |
| 360 | /* Check Rapid Fire setting for Button A */ | |
| 361 | if (!(data & 0x10) && (m_port_rfu->read() & 0x01)) | |
| 362 | data |= m_rapid_fire_state_1 & 0x10; | |
| 363 | ||
| 364 | /* Check Rapid Fire setting for Button B */ | |
| 365 | if (!(data & 0x20) && (m_port_rfu->read() & 0x02)) | |
| 366 | data |= m_rapid_fire_state_1 & 0x20; | |
| 367 | ||
| 368 | m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f); | |
| 369 | break; | |
| 370 | ||
| 371 | case 0x01: /* Light Phaser */ | |
| 372 | data = (m_port_ctrlipt->read() & 0x01) << 4; | |
| 373 | /* Check Rapid Fire setting for Trigger */ | |
| 374 | if (!(data & 0x10) && (m_port_rfu->read() & 0x01)) | |
| 375 | data |= m_rapid_fire_state_1 & 0x10; | |
| 376 | ||
| 377 | /* just consider the trigger (button) bit */ | |
| 378 | data |= ~0x10; | |
| 379 | ||
| 380 | m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x3f); | |
| 381 | break; | |
| 382 | ||
| 383 | case 0x02: /* Paddle Control */ | |
| 384 | /* Get button A state */ | |
| 385 | data = m_port_paddle0->read(); | |
| 386 | ||
| 387 | if (m_paddle_read_state) | |
| 388 | data = data >> 4; | |
| 389 | ||
| 390 | m_input_port0 = (m_input_port0 & 0xc0) | (data & 0x0f) | (m_paddle_read_state & 0x20) | |
| 391 | | ((m_port_ctrlipt->read() & 0x02) << 3); | |
| 392 | break; | |
| 393 | ||
| 394 | case 0x04: /* Sega Sports Pad */ | |
| 395 | switch (m_sports_pad_state_1) | |
| 396 | { | |
| 397 | case 0: | |
| 398 | data = (m_sports_pad_1_x >> 4) & 0x0f; | |
| 399 | break; | |
| 400 | case 1: | |
| 401 | data = m_sports_pad_1_x & 0x0f; | |
| 402 | break; | |
| 403 | case 2: | |
| 404 | data = (m_sports_pad_1_y >> 4) & 0x0f; | |
| 405 | break; | |
| 406 | case 3: | |
| 407 | data = m_sports_pad_1_y & 0x0f; | |
| 408 | break; | |
| 409 | } | |
| 410 | m_input_port0 = (m_input_port0 & 0xc0) | data | ((m_port_ctrlipt->read() & 0x0c) << 2); | |
| 411 | break; | |
| 412 | } | |
| 413 | ||
| 414 | /* Player 2 */ | |
| 415 | switch (m_port_ctrlsel->read_safe(0x00) & 0xf0) | |
| 416 | { | |
| 417 | case 0x00: /* Joystick */ | |
| 418 | data = m_port_dc->read(); | |
| 419 | m_input_port0 = (m_input_port0 & 0x3f) | (data & 0xc0); | |
| 420 | ||
| 421 | data = m_port_dd->read(); | |
| 422 | /* Check Rapid Fire setting for Button A */ | |
| 423 | if (!(data & 0x04) && (m_port_rfu->read() & 0x04)) | |
| 424 | data |= m_rapid_fire_state_2 & 0x04; | |
| 425 | ||
| 426 | /* Check Rapid Fire setting for Button B */ | |
| 427 | if (!(data & 0x08) && (m_port_rfu->read() & 0x08)) | |
| 428 | data |= m_rapid_fire_state_2 & 0x08; | |
| 429 | ||
| 430 | m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f); | |
| 431 | break; | |
| 432 | ||
| 433 | case 0x10: /* Light Phaser */ | |
| 434 | data = (m_port_ctrlipt->read() & 0x10) >> 2; | |
| 435 | /* Check Rapid Fire setting for Trigger */ | |
| 436 | if (!(data & 0x04) && (m_port_rfu->read() & 0x04)) | |
| 437 | data |= m_rapid_fire_state_2 & 0x04; | |
| 438 | ||
| 439 | /* just consider the trigger (button) bit */ | |
| 440 | data |= ~0x04; | |
| 441 | ||
| 442 | m_input_port1 = (m_input_port1 & 0xf0) | (data & 0x0f); | |
| 443 | break; | |
| 444 | ||
| 445 | case 0x20: /* Paddle Control */ | |
| 446 | /* Get button A state */ | |
| 447 | data = m_port_paddle1->read(); | |
| 448 | if (m_paddle_read_state) | |
| 449 | data = data >> 4; | |
| 450 | ||
| 451 | m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6); | |
| 452 | m_input_port1 = (m_input_port1 & 0xf0) | ((data & 0x0c) >> 2) | (m_paddle_read_state & 0x08) | |
| 453 | | ((m_port_ctrlipt->read() & 0x20) >> 3); | |
| 454 | break; | |
| 455 | ||
| 456 | case 0x40: /* Sega Sports Pad */ | |
| 457 | switch (m_sports_pad_state_2) | |
| 458 | { | |
| 459 | case 0: | |
| 460 | data = m_sports_pad_2_x & 0x0f; | |
| 461 | break; | |
| 462 | case 1: | |
| 463 | data = (m_sports_pad_2_x >> 4) & 0x0f; | |
| 464 | break; | |
| 465 | case 2: | |
| 466 | data = m_sports_pad_2_y & 0x0f; | |
| 467 | break; | |
| 468 | case 3: | |
| 469 | data = (m_sports_pad_2_y >> 4) & 0x0f; | |
| 470 | break; | |
| 471 | } | |
| 472 | m_input_port0 = (m_input_port0 & 0x3f) | ((data & 0x03) << 6); | |
| 473 | m_input_port1 = (m_input_port1 & 0xf0) | (data >> 2) | ((m_port_ctrlipt->read() & 0xc0) >> 4); | |
| 474 | break; | |
| 475 | } | |
| 58 | data = m_port_ctrl2->port_r(); | |
| 59 | m_port_dc_reg &= ~0xc0 | (data << 6); // Up, Down | |
| 60 | m_port_dd_reg &= ~0x03 | (data >> 2); // Left, Right | |
| 61 | m_port_dd_reg &= ~0x04 | (data >> 3); // TL (Button 1) | |
| 62 | m_port_dd_reg &= ~0x08 | (data >> 4); // TR (Button 2) | |
| 63 | m_port_dd_reg &= ~0x80 | (data << 1); // TH | |
| 476 | 64 | } |
| 477 | 65 | |
| 478 | 66 | |
| r23785 | r23786 | |
| 498 | 86 | else |
| 499 | 87 | { |
| 500 | 88 | sms_get_inputs(space); |
| 501 | return m_ | |
| 89 | return m_port_dc_reg; | |
| 502 | 90 | } |
| 503 | 91 | } |
| 504 | 92 | } |
| 505 | 93 | |
| 94 | ||
| 506 | 95 | WRITE8_MEMBER(sms_state::sms_io_control_w) |
| 507 | 96 | { |
| 508 | 97 | bool latch_hcount = false; |
| 98 | UINT8 ctrl1_port_data = 0xff; | |
| 99 | UINT8 ctrl2_port_data = 0xff; | |
| 509 | 100 | |
| 510 | if (data & 0x08) | |
| 101 | // Controller Port 1: | |
| 102 | ||
| 103 | // check if TR or TH are set to output (0). | |
| 104 | if ((data & 0x03) != 0x03) | |
| 511 | 105 | { |
| 512 | /* check if TH pin level is high (1) and was low last time */ | |
| 513 | if (data & 0x80 && !(m_ctrl_reg & 0x80)) | |
| 106 | if (!(data & 0x01)) // TR set to output | |
| 514 | 107 | { |
| 515 | | |
| 108 | ctrl1_port_data &= ~0x80 | (data << 3); | |
| 516 | 109 | } |
| 517 | sms_input_write(space, 0, (data & 0x20) >> 5); | |
| 110 | if (!(data & 0x02)) // TH set to output | |
| 111 | { | |
| 112 | ctrl1_port_data &= ~0x40 | (data << 1); | |
| 113 | } | |
| 114 | if (!m_is_gamegear) | |
| 115 | m_port_ctrl1->port_w(ctrl1_port_data); | |
| 518 | 116 | } |
| 519 | ||
| 117 | // check if TH is set to input (1). | |
| 520 | 118 | if (data & 0x02) |
| 521 | 119 | { |
| 522 | if (data & 0x20 && !(m_ctrl_reg & 0x20)) | |
| 523 | { | |
| 120 | UINT8 th_level = (m_port_ctrl1->port_r() & 0x40) >> 1; | |
| 121 | ||
| 122 | // check if TH pin level is high (1) and was low (0) | |
| 123 | if ((th_level & 0x20) && !(m_io_ctrl_reg & 0x20)) | |
| 524 | 124 | latch_hcount = true; |
| 125 | } | |
| 126 | ||
| 127 | // Controller Port 2: | |
| 128 | ||
| 129 | // check if TR or TH are set to output (0). | |
| 130 | if ((data & 0x0c) != 0x0c) | |
| 131 | { | |
| 132 | if (!(data & 0x04)) // TR set to output | |
| 133 | { | |
| 134 | ctrl2_port_data &= ~0x80 | (data << 1); | |
| 525 | 135 | } |
| 526 | sms_input_write(space, 1, (data & 0x80) >> 7); | |
| 136 | if (!(data & 0x08)) // TH set to output | |
| 137 | { | |
| 138 | ctrl2_port_data &= ~0x40 | (data >> 1); | |
| 139 | } | |
| 140 | if (!m_is_gamegear) | |
| 141 | m_port_ctrl2->port_w(ctrl2_port_data); | |
| 527 | 142 | } |
| 143 | // check if TH is set to input (1). | |
| 144 | if (data & 0x08) | |
| 145 | { | |
| 146 | UINT8 th_level = (m_port_ctrl2->port_r() & 0x40) << 1; | |
| 528 | 147 | |
| 148 | // check if TH pin level is high (1) and was low (0) | |
| 149 | if ((th_level & 0x80) && !(m_io_ctrl_reg & 0x80)) | |
| 150 | latch_hcount = true; | |
| 151 | } | |
| 152 | ||
| 529 | 153 | if (latch_hcount) |
| 530 | 154 | { |
| 531 | 155 | m_vdp->hcount_latch(); |
| 532 | 156 | } |
| 533 | ||
| 534 | m_ctrl_reg = data; | |
| 157 | m_io_ctrl_reg = data; | |
| 535 | 158 | } |
| 536 | 159 | |
| 537 | 160 | |
| r23785 | r23786 | |
| 563 | 186 | else |
| 564 | 187 | m_paused = 0; |
| 565 | 188 | |
| 566 | /* clear Light Phaser latch flags for next frame */ | |
| 567 | m_lphaser_1_latch = 0; | |
| 568 | m_lphaser_2_latch = 0; | |
| 189 | // clear TH latch of the controller ports | |
| 190 | m_ctrl1_th_latch = 0; | |
| 191 | m_ctrl2_th_latch = 0; | |
| 569 | 192 | } |
| 570 | 193 | |
| 571 | READ8_MEMBER(sms_state::sms_input_port_0_r) | |
| 194 | ||
| 195 | READ8_MEMBER(sms_state::sms_input_port_dc_r) | |
| 572 | 196 | { |
| 573 | 197 | if (m_bios_port & IO_CHIP) |
| 574 | 198 | { |
| r23785 | r23786 | |
| 577 | 201 | else |
| 578 | 202 | { |
| 579 | 203 | sms_get_inputs(space); |
| 580 | return m_input_port0; | |
| 204 | ||
| 205 | // Check if TR of controller port 1 is set to output (0) | |
| 206 | if (!(m_io_ctrl_reg & 0x01)) | |
| 207 | { | |
| 208 | // Read TR state set through IO control port | |
| 209 | m_port_dc_reg &= ~0x20 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x10) << 1); | |
| 210 | } | |
| 211 | ||
| 212 | return m_port_dc_reg; | |
| 581 | 213 | } |
| 582 | 214 | } |
| 583 | 215 | |
| 584 | 216 | |
| 585 | READ8_MEMBER(sms_state::sms_input_port_ | |
| 217 | READ8_MEMBER(sms_state::sms_input_port_dd_r) | |
| 586 | 218 | { |
| 587 | 219 | if (m_bios_port & IO_CHIP) |
| 588 | 220 | return 0xff; |
| 589 | 221 | |
| 590 | 222 | sms_get_inputs(space); |
| 591 | 223 | |
| 592 | /* Reset Button */ | |
| 593 | m_input_port1 = (m_input_port1 & 0xef) | (m_port_reset->read_safe(0x01) & 0x01) << 4; | |
| 224 | // Reset Button | |
| 225 | m_port_dd_reg &= ~0x10 | (m_port_reset->read_safe(0x01) & 0x01) << 4; | |
| 594 | 226 | |
| 595 | /* Do region detection if TH of ports A and B are set to output (0) */ | |
| 596 | if (!(m_ctrl_reg & 0x0a)) | |
| 227 | // Check if TR of controller port 2 is set to output (0) | |
| 228 | if (!(m_io_ctrl_reg & 0x04)) | |
| 597 | 229 | { |
| 598 | /* Move bits 7,5 of IO control port into bits 7, 6 */ | |
| 599 | m_input_port1 = (m_input_port1 & 0x3f) | (m_ctrl_reg & 0x80) | (m_ctrl_reg & 0x20) << 1; | |
| 230 | // Read TR state set through IO control port | |
| 231 | m_port_dd_reg &= ~0x08 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x40) >> 3); | |
| 232 | } | |
| 600 | 233 | |
| 601 | /* Inverse region detect value for Japanese machines */ | |
| 602 | if (m_is_region_japan) | |
| 603 | m_input_port1 ^= 0xc0; | |
| 234 | // Check if TH of controller port 1 is set to output (0) | |
| 235 | if (!(m_io_ctrl_reg & 0x02)) | |
| 236 | { | |
| 237 | // Read TH state set through IO control port | |
| 238 | m_port_dd_reg &= ~0x40 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x20) << 1); | |
| 604 | 239 | } |
| 605 | else | |
| 240 | else // TH set to input (1) | |
| 606 | 241 | { |
| 607 | if (m_ctrl_ | |
| 242 | if (m_ctrl1_th_latch) | |
| 608 | 243 | { |
| 609 | m_input_port1 &= ~0x40; | |
| 610 | m_lphaser_1_latch = 0; | |
| 244 | m_port_dd_reg &= ~0x40; | |
| 245 | m_ctrl1_th_latch = 0; | |
| 611 | 246 | } |
| 247 | } | |
| 612 | 248 | |
| 613 | if (m_ctrl_reg & 0x08 && m_lphaser_2_latch) | |
| 249 | // Check if TH of controller port 2 is set to output (0) | |
| 250 | if (!(m_io_ctrl_reg & 0x08)) | |
| 251 | { | |
| 252 | // Read TH state set through IO control port | |
| 253 | m_port_dd_reg &= ~0x80 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x80)); | |
| 254 | } | |
| 255 | else // TH set to input (1) | |
| 256 | { | |
| 257 | if (m_ctrl2_th_latch) | |
| 614 | 258 | { |
| 615 | m_input_port1 &= ~0x80; | |
| 616 | m_lphaser_2_latch = 0; | |
| 259 | m_port_dd_reg &= ~0x80; | |
| 260 | m_ctrl2_th_latch = 0; | |
| 617 | 261 | } |
| 618 | 262 | } |
| 619 | 263 | |
| 620 | return m_ | |
| 264 | return m_port_dd_reg; | |
| 621 | 265 | } |
| 622 | 266 | |
| 623 | 267 | |
| 624 | ||
| 625 | WRITE8_MEMBER(sms_state::sms_ym2413_register_port_0_w) | |
| 268 | WRITE8_MEMBER(sms_state::sms_ym2413_register_port_w) | |
| 626 | 269 | { |
| 627 | 270 | if (m_has_fm) |
| 628 | 271 | m_ym->write(space, 0, (data & 0x3f)); |
| 629 | 272 | } |
| 630 | 273 | |
| 631 | 274 | |
| 632 | WRITE8_MEMBER(sms_state::sms_ym2413_data_port_ | |
| 275 | WRITE8_MEMBER(sms_state::sms_ym2413_data_port_w) | |
| 633 | 276 | { |
| 634 | 277 | if (m_has_fm) |
| 635 | 278 | { |
| 636 | logerror("data_port_ | |
| 279 | logerror("data_port_w %x %x\n", offset, data); | |
| 637 | 280 | m_ym->write(space, 1, data); |
| 638 | 281 | } |
| 639 | 282 | } |
| r23785 | r23786 | |
| 1056 | 699 | { |
| 1057 | 700 | char str[7]; |
| 1058 | 701 | |
| 1059 | m_rapid_fire_timer = timer_alloc(TIMER_RAPID_FIRE); | |
| 1060 | m_rapid_fire_timer->adjust(attotime::from_hz(10), 0, attotime::from_hz(10)); | |
| 1061 | ||
| 1062 | m_lphaser_1_timer = timer_alloc(TIMER_LPHASER_1); | |
| 1063 | m_lphaser_2_timer = timer_alloc(TIMER_LPHASER_2); | |
| 1064 | ||
| 1065 | 702 | m_left_lcd = machine().device("left_lcd"); |
| 1066 | 703 | m_right_lcd = machine().device("right_lcd"); |
| 1067 | 704 | m_space = &m_maincpu->space(AS_PROGRAM); |
| 1068 | 705 | |
| 1069 | /* Check if lightgun has been chosen as input: if so, enable crosshair */ | |
| 1070 | timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); | |
| 1071 | ||
| 1072 | 706 | // alibaba and blockhol are ports of games for the MSX system. The |
| 1073 | 707 | // MSX bios usually initializes callback "vectors" at the top of RAM. |
| 1074 | 708 | // The code in alibaba does not do this so the IRQ vector only contains |
| r23785 | r23786 | |
| 1083 | 717 | } |
| 1084 | 718 | |
| 1085 | 719 | save_item(NAME(m_fm_detect)); |
| 1086 | save_item(NAME(m_ctrl_reg)); | |
| 720 | save_item(NAME(m_io_ctrl_reg)); | |
| 1087 | 721 | save_item(NAME(m_paused)); |
| 1088 | 722 | save_item(NAME(m_bios_port)); |
| 1089 | 723 | save_item(NAME(m_mapper)); |
| 1090 | save_item(NAME(m_input_port0)); | |
| 1091 | save_item(NAME(m_input_port1)); | |
| 724 | save_item(NAME(m_port_dc_reg)); | |
| 725 | save_item(NAME(m_port_dd_reg)); | |
| 1092 | 726 | save_item(NAME(m_gg_sio)); |
| 1093 | 727 | save_item(NAME(m_bank_enabled)); |
| 1094 | 728 | save_item(NAME(m_bios_page)); |
| 1095 | 729 | |
| 1096 | save_item(NAME(m_rapid_fire_state_1)); | |
| 1097 | save_item(NAME(m_rapid_fire_state_2)); | |
| 1098 | save_item(NAME(m_last_paddle_read_time)); | |
| 1099 | save_item(NAME(m_paddle_read_state)); | |
| 1100 | save_item(NAME(m_last_sports_pad_time_1)); | |
| 1101 | save_item(NAME(m_last_sports_pad_time_2)); | |
| 1102 | save_item(NAME(m_sports_pad_state_1)); | |
| 1103 | save_item(NAME(m_sports_pad_state_2)); | |
| 1104 | save_item(NAME(m_sports_pad_last_data_1)); | |
| 1105 | save_item(NAME(m_sports_pad_last_data_2)); | |
| 1106 | save_item(NAME(m_sports_pad_1_x)); | |
| 1107 | save_item(NAME(m_sports_pad_1_y)); | |
| 1108 | save_item(NAME(m_sports_pad_2_x)); | |
| 1109 | save_item(NAME(m_sports_pad_2_y)); | |
| 1110 | save_item(NAME(m_lphaser_1_latch)); | |
| 1111 | save_item(NAME(m_lphaser_2_latch)); | |
| 730 | save_item(NAME(m_ctrl1_th_latch)); | |
| 731 | save_item(NAME(m_ctrl2_th_latch)); | |
| 1112 | 732 | save_item(NAME(m_sscope_state)); |
| 1113 | 733 | save_item(NAME(m_frame_sscope_state)); |
| 1114 | 734 | |
| r23785 | r23786 | |
| 1142 | 762 | |
| 1143 | 763 | MACHINE_RESET_MEMBER(sms_state,sms) |
| 1144 | 764 | { |
| 1145 | m_ctrl_reg = 0xff; | |
| 765 | m_io_ctrl_reg = 0xff; | |
| 1146 | 766 | if (m_has_fm) |
| 1147 | 767 | m_fm_detect = 0x01; |
| 1148 | 768 | |
| r23785 | r23786 | |
| 1168 | 788 | |
| 1169 | 789 | setup_rom(); |
| 1170 | 790 | |
| 1171 | m_rapid_fire_state_1 = 0; | |
| 1172 | m_rapid_fire_state_2 = 0; | |
| 1173 | ||
| 1174 | m_last_paddle_read_time = 0; | |
| 1175 | m_paddle_read_state = 0; | |
| 1176 | ||
| 1177 | m_last_sports_pad_time_1 = 0; | |
| 1178 | m_last_sports_pad_time_2 = 0; | |
| 1179 | m_sports_pad_state_1 = 0; | |
| 1180 | m_sports_pad_state_2 = 0; | |
| 1181 | m_sports_pad_last_data_1 = 0; | |
| 1182 | m_sports_pad_last_data_2 = 0; | |
| 1183 | m_sports_pad_1_x = 0; | |
| 1184 | m_sports_pad_1_y = 0; | |
| 1185 | m_sports_pad_2_x = 0; | |
| 1186 | m_sports_pad_2_y = 0; | |
| 1187 | ||
| 1188 | m_lphaser_1_latch = 0; | |
| 1189 | m_lphaser_2_latch = 0; | |
| 791 | m_ctrl1_th_latch = 0; | |
| 792 | m_ctrl2_th_latch = 0; | |
| 1190 | 793 | m_lphaser_x_offs = (m_cartslot->m_cart) ? m_cartslot->m_cart->get_lphaser_xoffs() : 51; |
| 1191 | 794 | |
| 1192 | 795 | m_sscope_state = 0; |
| r23785 | r23786 | |
| 1206 | 809 | |
| 1207 | 810 | logerror("switching in part of %s slot #%d\n", slottype ? "card" : "cartridge", slot ); |
| 1208 | 811 | /* cartridge? slot #0 */ |
| 1209 | // if (slottype == 0) | |
| 1210 | // m_current_cartridge = slot; | |
| 812 | //if (slottype == 0) | |
| 813 | // m_current_cartridge = slot; | |
| 1211 | 814 | |
| 1212 | 815 | setup_rom(); |
| 1213 | 816 | } |
| r23785 | r23786 | |
| 1336 | 939 | } |
| 1337 | 940 | |
| 1338 | 941 | |
| 942 | READ32_MEMBER(sms_state::sms_pixel_color) | |
| 943 | { | |
| 944 | bitmap_rgb32 &vdp_bitmap = m_vdp->get_bitmap(); | |
| 945 | int beam_x = m_main_scr->hpos(); | |
| 946 | int beam_y = m_main_scr->vpos(); | |
| 947 | ||
| 948 | return vdp_bitmap.pix32(beam_y, beam_x); | |
| 949 | } | |
| 950 | ||
| 951 | ||
| 1339 | 952 | void sms_state::screen_vblank_sms1(screen_device &screen, bool state) |
| 1340 | 953 | { |
| 1341 | 954 | // on falling edge |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Control Pad"/generic joystick emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #include "sms_joypad.h" | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | //************************************************************************** | |
| 15 | // DEVICE DEFINITIONS | |
| 16 | //************************************************************************** | |
| 17 | ||
| 18 | const device_type SMS_JOYPAD = &device_creator<sms_joypad_device>; | |
| 19 | ||
| 20 | ||
| 21 | static INPUT_PORTS_START( sms_joypad ) | |
| 22 | PORT_START("JOYPAD") | |
| 23 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_8WAY | |
| 24 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_8WAY | |
| 25 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_8WAY | |
| 26 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_8WAY | |
| 27 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc | |
| 28 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL | |
| 29 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // TH | |
| 30 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) // TR | |
| 31 | INPUT_PORTS_END | |
| 32 | ||
| 33 | ||
| 34 | //------------------------------------------------- | |
| 35 | // input_ports - device-specific input ports | |
| 36 | //------------------------------------------------- | |
| 37 | ||
| 38 | ioport_constructor sms_joypad_device::device_input_ports() const | |
| 39 | { | |
| 40 | return INPUT_PORTS_NAME( sms_joypad ); | |
| 41 | } | |
| 42 | ||
| 43 | ||
| 44 | ||
| 45 | //************************************************************************** | |
| 46 | // LIVE DEVICE | |
| 47 | //************************************************************************** | |
| 48 | ||
| 49 | //------------------------------------------------- | |
| 50 | // sms_joypad_device - constructor | |
| 51 | //------------------------------------------------- | |
| 52 | ||
| 53 | sms_joypad_device::sms_joypad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 54 | device_t(mconfig, SMS_JOYPAD, "Control Pad", tag, owner, clock, "sms_joypad", __FILE__), | |
| 55 | device_sms_control_port_interface(mconfig, *this), | |
| 56 | m_joypad(*this, "JOYPAD") | |
| 57 | { | |
| 58 | } | |
| 59 | ||
| 60 | ||
| 61 | //------------------------------------------------- | |
| 62 | // device_start - device-specific startup | |
| 63 | //------------------------------------------------- | |
| 64 | ||
| 65 | void sms_joypad_device::device_start() | |
| 66 | { | |
| 67 | } | |
| 68 | ||
| 69 | ||
| 70 | //------------------------------------------------- | |
| 71 | // sms_peripheral_r - joypad read | |
| 72 | //------------------------------------------------- | |
| 73 | ||
| 74 | UINT8 sms_joypad_device::peripheral_r() | |
| 75 | { | |
| 76 | return m_joypad->read(); | |
| 77 | } |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Control Pad"/generic joystick emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #pragma once | |
| 11 | ||
| 12 | #ifndef __SMS_JOYPAD__ | |
| 13 | #define __SMS_JOYPAD__ | |
| 14 | ||
| 15 | ||
| 16 | #include "emu.h" | |
| 17 | #include "machine/smsctrl.h" | |
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | //************************************************************************** | |
| 22 | // TYPE DEFINITIONS | |
| 23 | //************************************************************************** | |
| 24 | ||
| 25 | // ======================> sms_joypad_device | |
| 26 | ||
| 27 | class sms_joypad_device : public device_t, | |
| 28 | public device_sms_control_port_interface | |
| 29 | { | |
| 30 | public: | |
| 31 | // construction/destruction | |
| 32 | sms_joypad_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 33 | ||
| 34 | // optional information overrides | |
| 35 | virtual ioport_constructor device_input_ports() const; | |
| 36 | ||
| 37 | protected: | |
| 38 | // device-level overrides | |
| 39 | virtual void device_start(); | |
| 40 | ||
| 41 | // device_sms_control_port_interface overrides | |
| 42 | virtual UINT8 peripheral_r(); | |
| 43 | ||
| 44 | private: | |
| 45 | required_ioport m_joypad; | |
| 46 | }; | |
| 47 | ||
| 48 | ||
| 49 | // device type definition | |
| 50 | extern const device_type SMS_JOYPAD; | |
| 51 | ||
| 52 | ||
| 53 | #endif |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Light Phaser" (light gun) emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #include "sms_lphaser.h" | |
| 11 | ||
| 12 | ||
| 13 | ||
| 14 | //************************************************************************** | |
| 15 | // DEVICE DEFINITIONS | |
| 16 | //************************************************************************** | |
| 17 | ||
| 18 | const device_type SMS_LIGHT_PHASER = &device_creator<sms_light_phaser_device>; | |
| 19 | ||
| 20 | ||
| 21 | #define LGUN_RADIUS 6 | |
| 22 | #define LGUN_X_INTERVAL 4 | |
| 23 | ||
| 24 | ||
| 25 | INPUT_CHANGED_MEMBER( sms_light_phaser_device::th_pin_w ) | |
| 26 | { | |
| 27 | m_port->th_pin_w(newval); | |
| 28 | } | |
| 29 | ||
| 30 | ||
| 31 | INPUT_CHANGED_MEMBER( sms_light_phaser_device::position_changed ) | |
| 32 | { | |
| 33 | if (newval != oldval) | |
| 34 | sensor_check(); | |
| 35 | } | |
| 36 | ||
| 37 | ||
| 38 | static INPUT_PORTS_START( sms_light_phaser ) | |
| 39 | PORT_START("CTRL_PORT") | |
| 40 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (trigger) | |
| 41 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, th_pin_w, 0) | |
| 42 | PORT_BIT( 0x9f, IP_ACTIVE_LOW, IPT_UNUSED ) | |
| 43 | ||
| 44 | PORT_START("LPHASER_X") | |
| 45 | PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_X) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, position_changed, 0) | |
| 46 | ||
| 47 | PORT_START("LPHASER_Y") | |
| 48 | PORT_BIT( 0xff, 0x00, IPT_LIGHTGUN_Y) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_light_phaser_device, position_changed, 0) | |
| 49 | INPUT_PORTS_END | |
| 50 | ||
| 51 | ||
| 52 | //------------------------------------------------- | |
| 53 | // input_ports - device-specific input ports | |
| 54 | //------------------------------------------------- | |
| 55 | ||
| 56 | ioport_constructor sms_light_phaser_device::device_input_ports() const | |
| 57 | { | |
| 58 | return INPUT_PORTS_NAME( sms_light_phaser ); | |
| 59 | } | |
| 60 | ||
| 61 | ||
| 62 | ||
| 63 | //************************************************************************** | |
| 64 | // LIVE DEVICE | |
| 65 | //************************************************************************** | |
| 66 | ||
| 67 | //------------------------------------------------- | |
| 68 | // sms_light_phaser_device - constructor | |
| 69 | //------------------------------------------------- | |
| 70 | ||
| 71 | sms_light_phaser_device::sms_light_phaser_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : | |
| 72 | device_t(mconfig, SMS_LIGHT_PHASER, "Light Phaser", tag, owner, clock, "sms_light_phaser", __FILE__), | |
| 73 | device_sms_control_port_interface(mconfig, *this), | |
| 74 | m_lphaser_pins(*this, "CTRL_PORT"), | |
| 75 | m_lphaser_x(*this, "LPHASER_X"), | |
| 76 | m_lphaser_y(*this, "LPHASER_Y") | |
| 77 | { | |
| 78 | } | |
| 79 | ||
| 80 | ||
| 81 | //------------------------------------------------- | |
| 82 | // device_start - device-specific startup | |
| 83 | //------------------------------------------------- | |
| 84 | ||
| 85 | void sms_light_phaser_device::device_start() | |
| 86 | { | |
| 87 | m_screen = machine().first_screen(); | |
| 88 | m_lphaser_timer = timer_alloc(TIMER_LPHASER); | |
| 89 | } | |
| 90 | ||
| 91 | ||
| 92 | //------------------------------------------------- | |
| 93 | // sms_peripheral_r - light phaser read | |
| 94 | //------------------------------------------------- | |
| 95 | ||
| 96 | UINT8 sms_light_phaser_device::peripheral_r() | |
| 97 | { | |
| 98 | return m_lphaser_pins->read(); | |
| 99 | } | |
| 100 | ||
| 101 | ||
| 102 | /* | |
| 103 | Light Phaser (light gun) emulation notes: | |
| 104 | - The sensor is activated based on color brightness of some individual | |
| 105 | pixels being drawn by the beam, at circular area where the gun is aiming. | |
| 106 | - Currently, brightness is calculated based only on single pixels. | |
| 107 | - In general, after the trigger is pressed, games draw the next frame using | |
| 108 | a light color pattern, to make sure sensor will be activated. If emulation | |
| 109 | skips that frame, sensor may stay deactivated. Frameskip set to 0 (no skip) is | |
| 110 | recommended to avoid problems. | |
| 111 | - When sensor switches from off to on, a value is latched for HCount register | |
| 112 | and a flag is set. The emulation uses the flag to avoid sequential latches and | |
| 113 | to signal that TH line is activated when the status of the input port is read. | |
| 114 | When the status is read, the flag is cleared, or else it is cleared later when | |
| 115 | the Pause status is read (end of a frame). This is necessary because the | |
| 116 | "Color & Switch Test" ROM only reads the TH bit after the VINT line. | |
| 117 | - The gun test of "Color & Switch Test" is an example that requires checks | |
| 118 | of sensor status independent of other events, like trigger press or TH bit | |
| 119 | reads. Another example is the title screen of "Hang-On & Safari Hunt", where | |
| 120 | the game only reads HCount register in a loop, expecting a latch by the gun. | |
| 121 | - The whole procedure is managed by a timer callback, that always reschedule | |
| 122 | itself to run in some intervals when the beam is at the circular area. | |
| 123 | */ | |
| 124 | int sms_light_phaser_device::bright_aim_area( emu_timer *timer, int lgun_x, int lgun_y ) | |
| 125 | { | |
| 126 | const int r_x_r = LGUN_RADIUS * LGUN_RADIUS; | |
| 127 | const rectangle &visarea = m_screen->visible_area(); | |
| 128 | int beam_x = m_screen->hpos(); | |
| 129 | int beam_y = m_screen->vpos(); | |
| 130 | int dx, dy; | |
| 131 | int result = 0; | |
| 132 | int pos_changed = 0; | |
| 133 | double dx_radius; | |
| 134 | ||
| 135 | while (1) | |
| 136 | { | |
| 137 | /* If beam's y isn't at a line where the aim area is, change it | |
| 138 | the next line it enters that area. */ | |
| 139 | dy = abs(beam_y - lgun_y); | |
| 140 | if (dy > LGUN_RADIUS || beam_y < visarea.min_y || beam_y > visarea.max_y) | |
| 141 | { | |
| 142 | beam_y = lgun_y - LGUN_RADIUS; | |
| 143 | if (beam_y < visarea.min_y) | |
| 144 | beam_y = visarea.min_y; | |
| 145 | dy = abs(beam_y - lgun_y); | |
| 146 | pos_changed = 1; | |
| 147 | } | |
| 148 | ||
| 149 | /* Caculate distance in x of the radius, relative to beam's y distance. | |
| 150 | First try some shortcuts. */ | |
| 151 | switch (dy) | |
| 152 | { | |
| 153 | case LGUN_RADIUS: | |
| 154 | dx_radius = 0; | |
| 155 | break; | |
| 156 | case 0: | |
| 157 | dx_radius = LGUN_RADIUS; | |
| 158 | break; | |
| 159 | default: | |
| 160 | /* step 1: r^2 = dx^2 + dy^2 */ | |
| 161 | /* step 2: dx^2 = r^2 - dy^2 */ | |
| 162 | /* step 3: dx = sqrt(r^2 - dy^2) */ | |
| 163 | dx_radius = ceil((float) sqrt((float) (r_x_r - (dy * dy)))); | |
| 164 | } | |
| 165 | ||
| 166 | /* If beam's x isn't in the circular aim area, change it | |
| 167 | to the next point it enters that area. */ | |
| 168 | dx = abs(beam_x - lgun_x); | |
| 169 | if (dx > dx_radius || beam_x < visarea.min_x || beam_x > visarea.max_x) | |
| 170 | { | |
| 171 | /* If beam's x has passed the aim area, advance to | |
| 172 | next line and recheck y/x coordinates. */ | |
| 173 | if (beam_x > lgun_x) | |
| 174 | { | |
| 175 | beam_x = 0; | |
| 176 | beam_y++; | |
| 177 | continue; | |
| 178 | } | |
| 179 | beam_x = lgun_x - dx_radius; | |
| 180 | if (beam_x < visarea.min_x) | |
| 181 | beam_x = visarea.min_x; | |
| 182 | pos_changed = 1; | |
| 183 | } | |
| 184 | ||
| 185 | if (!pos_changed) | |
| 186 | { | |
| 187 | /* brightness of the lightgray color in the frame drawn by Light Phaser games */ | |
| 188 | const UINT8 sensor_min_brightness = 0x7f; | |
| 189 | ||
| 190 | rgb_t color = m_port->pixel_r(); | |
| 191 | ||
| 192 | /* reference: http://www.w3.org/TR/AERT#color-contrast */ | |
| 193 | UINT8 brightness = (RGB_RED(color) * 0.299) + (RGB_GREEN(color) * 0.587) + (RGB_BLUE(color) * 0.114); | |
| 194 | //printf ("color brightness: %2X for x %d y %d\n", brightness, beam_x, beam_y); | |
| 195 | ||
| 196 | result = (brightness >= sensor_min_brightness) ? 1 : 0; | |
| 197 | ||
| 198 | /* next check at same line */ | |
| 199 | beam_x += LGUN_X_INTERVAL; | |
| 200 | pos_changed = 1; | |
| 201 | } | |
| 202 | else | |
| 203 | break; | |
| 204 | } | |
| 205 | timer->adjust(m_screen->time_until_pos(beam_y, beam_x)); | |
| 206 | ||
| 207 | return result; | |
| 208 | } | |
| 209 | ||
| 210 | ||
| 211 | UINT16 sms_light_phaser_device::screen_hpos_nonscaled(int scaled_hpos) | |
| 212 | { | |
| 213 | const rectangle &visarea = m_screen->visible_area(); | |
| 214 | int offset_x = (scaled_hpos * (visarea.max_x - visarea.min_x)) / 255; | |
| 215 | return visarea.min_x + offset_x; | |
| 216 | } | |
| 217 | ||
| 218 | ||
| 219 | UINT16 sms_light_phaser_device::screen_vpos_nonscaled(int scaled_vpos) | |
| 220 | { | |
| 221 | const rectangle &visarea = m_screen->visible_area(); | |
| 222 | int offset_y = (scaled_vpos * (visarea.max_y - visarea.min_y)) / 255; | |
| 223 | return visarea.min_y + offset_y; | |
| 224 | } | |
| 225 | ||
| 226 | ||
| 227 | void sms_light_phaser_device::sensor_check() | |
| 228 | { | |
| 229 | const int x = screen_hpos_nonscaled(m_lphaser_x->read()); | |
| 230 | const int y = screen_vpos_nonscaled(m_lphaser_y->read()); | |
| 231 | ||
| 232 | if (bright_aim_area(m_lphaser_timer, x, y)) | |
| 233 | { | |
| 234 | m_port->th_pin_w(x); | |
| 235 | } | |
| 236 | } | |
| 237 | ||
| 238 | ||
| 239 | void sms_light_phaser_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) | |
| 240 | { | |
| 241 | switch (id) | |
| 242 | { | |
| 243 | case TIMER_LPHASER: | |
| 244 | sensor_check(); | |
| 245 | break; | |
| 246 | default: | |
| 247 | assert_always(FALSE, "Unknown id in sms_light_phaser_device::device_timer"); | |
| 248 | } | |
| 249 | } | |
| 250 | ||
| 251 |
| Added: svn:eol-style + native Added: svn:mime-type + text/plain |
| r0 | r23786 | |
|---|---|---|
| 1 | /********************************************************************** | |
| 2 | ||
| 3 | Sega Master System "Light Phaser" (light gun) emulation | |
| 4 | ||
| 5 | Copyright MESS Team. | |
| 6 | Visit http://mamedev.org for licensing and usage restrictions. | |
| 7 | ||
| 8 | **********************************************************************/ | |
| 9 | ||
| 10 | #pragma once | |
| 11 | ||
| 12 | #ifndef __SMS_LIGHT_PHASER__ | |
| 13 | #define __SMS_LIGHT_PHASER__ | |
| 14 | ||
| 15 | ||
| 16 | #include "emu.h" | |
| 17 | #include "machine/smsctrl.h" | |
| 18 | ||
| 19 | ||
| 20 | ||
| 21 | //************************************************************************** | |
| 22 | // TYPE DEFINITIONS | |
| 23 | //************************************************************************** | |
| 24 | ||
| 25 | // ======================> sms_light_phaser_device | |
| 26 | ||
| 27 | class sms_light_phaser_device : public device_t, | |
| 28 | public device_sms_control_port_interface | |
| 29 | { | |
| 30 | public: | |
| 31 | // construction/destruction | |
| 32 | sms_light_phaser_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); | |
| 33 | ||
| 34 | // optional information overrides | |
| 35 | virtual ioport_constructor device_input_ports() const; | |
| 36 | ||
| 37 | DECLARE_INPUT_CHANGED_MEMBER( th_pin_w ); | |
| 38 | DECLARE_INPUT_CHANGED_MEMBER( position_changed ); | |
| 39 | ||
| 40 | protected: | |
| 41 | // device-level overrides | |
| 42 | virtual void device_start(); | |
| 43 | ||
| 44 | // device_sms_control_port_interface overrides | |
| 45 | virtual UINT8 peripheral_r(); | |
| 46 | ||
| 47 | private: | |
| 48 | required_ioport m_lphaser_pins; | |
| 49 | required_ioport m_lphaser_x; | |
| 50 | required_ioport m_lphaser_y; | |
| 51 | ||
| 52 | screen_device *m_screen; | |
| 53 | emu_timer *m_lphaser_timer; | |
| 54 | static const device_timer_id TIMER_LPHASER = 0; | |
| 55 | ||
| 56 | void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); | |
| 57 | void sensor_check(); | |
| 58 | int bright_aim_area( emu_timer *timer, int lgun_x, int lgun_y ); | |
| 59 | UINT16 screen_hpos_nonscaled(int scaled_hpos); | |
| 60 | UINT16 screen_vpos_nonscaled(int scaled_vpos); | |
| 61 | }; | |
| 62 | ||
| 63 | ||
| 64 | // device type definition | |
| 65 | extern const device_type SMS_LIGHT_PHASER; | |
| 66 | ||
| 67 | ||
| 68 | #endif |
| Added: svn:mime-type + text/plain Added: svn:eol-style + native |
| r23785 | r23786 | |
|---|---|---|
| 16 | 16 | |
| 17 | 17 | #define MAX_CARTRIDGES 16 |
| 18 | 18 | |
| 19 | #define CONTROL1_TAG "ctrl1" | |
| 20 | #define CONTROL2_TAG "ctrl2" | |
| 21 | ||
| 22 | #include "machine/smsctrl.h" | |
| 19 | 23 | #include "machine/sega8_slot.h" |
| 20 | 24 | |
| 21 | 25 | |
| 22 | 26 | class sms_state : public driver_device |
| 23 | 27 | { |
| 24 | 28 | public: |
| 25 | enum | |
| 26 | { | |
| 27 | TIMER_RAPID_FIRE, | |
| 28 | TIMER_LIGHTGUN_TICK, | |
| 29 | TIMER_LPHASER_1, | |
| 30 | TIMER_LPHASER_2 | |
| 31 | }; | |
| 32 | ||
| 33 | 29 | sms_state(const machine_config &mconfig, device_type type, const char *tag) |
| 34 | 30 | : driver_device(mconfig, type, tag), |
| 35 | 31 | m_maincpu(*this, "maincpu"), |
| r23785 | r23786 | |
| 40 | 36 | m_cartslot(*this, "slot"), |
| 41 | 37 | m_card(*this, "mycard"), |
| 42 | 38 | m_region_maincpu(*this, "maincpu"), |
| 43 | m_port_dd(*this, "PORT_DD"), | |
| 44 | m_port_dc(*this, "PORT_DC"), | |
| 39 | m_port_ctrl1(*this, CONTROL1_TAG), | |
| 40 | m_port_ctrl2(*this, CONTROL2_TAG), | |
| 45 | 41 | m_port_pause(*this, "PAUSE"), |
| 46 | 42 | m_port_reset(*this, "RESET"), |
| 47 | 43 | m_port_start(*this, "START"), |
| 48 | m_port_ctrlsel(*this, "CTRLSEL"), | |
| 49 | m_port_lphas0(*this, "LPHASER0"), | |
| 50 | m_port_lphas1(*this, "LPHASER1"), | |
| 51 | m_port_lphas2(*this, "LPHASER2"), | |
| 52 | m_port_lphas3(*this, "LPHASER3"), | |
| 53 | m_port_rfu(*this, "RFU"), | |
| 54 | m_port_paddle0(*this, "PADDLE0"), | |
| 55 | m_port_paddle1(*this, "PADDLE1"), | |
| 56 | m_port_ctrlipt(*this, "CTRLIPT"), | |
| 57 | m_port_sport0(*this, "SPORT0"), | |
| 58 | m_port_sport1(*this, "SPORT1"), | |
| 59 | m_port_sport2(*this, "SPORT2"), | |
| 60 | m_port_sport3(*this, "SPORT3"), | |
| 61 | 44 | m_port_scope(*this, "SEGASCOPE"), |
| 62 | 45 | m_port_persist(*this, "PERSISTENCE"), |
| 63 | 46 | m_is_gamegear(0), |
| r23785 | r23786 | |
| 78 | 61 | required_device<sega8_cart_slot_device> m_cartslot; |
| 79 | 62 | optional_device<sega8_card_slot_device> m_card; |
| 80 | 63 | required_memory_region m_region_maincpu; |
| 81 | required_ioport m_port_dd; | |
| 82 | required_ioport m_port_dc; | |
| 64 | optional_device<sms_control_port_device> m_port_ctrl1; | |
| 65 | optional_device<sms_control_port_device> m_port_ctrl2; | |
| 83 | 66 | optional_ioport m_port_pause; |
| 84 | 67 | optional_ioport m_port_reset; |
| 85 | 68 | optional_ioport m_port_start; |
| 86 | optional_ioport m_port_ctrlsel; | |
| 87 | optional_ioport m_port_lphas0; | |
| 88 | optional_ioport m_port_lphas1; | |
| 89 | optional_ioport m_port_lphas2; | |
| 90 | optional_ioport m_port_lphas3; | |
| 91 | optional_ioport m_port_rfu; | |
| 92 | optional_ioport m_port_paddle0; | |
| 93 | optional_ioport m_port_paddle1; | |
| 94 | optional_ioport m_port_ctrlipt; | |
| 95 | optional_ioport m_port_sport0; | |
| 96 | optional_ioport m_port_sport1; | |
| 97 | optional_ioport m_port_sport2; | |
| 98 | optional_ioport m_port_sport3; | |
| 99 | 69 | optional_ioport m_port_scope; |
| 100 | 70 | optional_ioport m_port_persist; |
| 101 | 71 | |
| r23785 | r23786 | |
| 105 | 75 | |
| 106 | 76 | UINT8 m_bios_page_count; |
| 107 | 77 | UINT8 m_fm_detect; |
| 108 | UINT8 m_ctrl_reg; | |
| 78 | UINT8 m_io_ctrl_reg; | |
| 109 | 79 | int m_paused; |
| 110 | 80 | UINT8 m_bios_port; |
| 111 | 81 | UINT8 *m_BIOS; |
| 112 | 82 | UINT8 m_mapper[4]; |
| 113 | UINT8 m_input_port0; | |
| 114 | UINT8 m_input_port1; | |
| 83 | UINT8 m_port_dc_reg; | |
| 84 | UINT8 m_port_dd_reg; | |
| 115 | 85 | UINT8 m_gg_sio[5]; |
| 116 | 86 | |
| 117 | 87 | // [0] for 0x400-0x3fff, [1] for 0x4000-0x7fff, [2] for 0x8000-0xffff, [3] for 0x0000-0x0400 |
| r23785 | r23786 | |
| 135 | 105 | UINT8 m_has_bios; |
| 136 | 106 | UINT8 m_has_fm; |
| 137 | 107 | |
| 138 | // Data needed for Rapid Fire Unit support | |
| 139 | emu_timer *m_rapid_fire_timer; | |
| 140 | UINT8 m_rapid_fire_state_1; | |
| 141 | UINT8 m_rapid_fire_state_2; | |
| 142 | ||
| 143 | // Data needed for Paddle Control controller | |
| 144 | UINT32 m_last_paddle_read_time; | |
| 145 | UINT8 m_paddle_read_state; | |
| 146 | ||
| 147 | // Data needed for Sports Pad controller | |
| 148 | UINT32 m_last_sports_pad_time_1; | |
| 149 | UINT32 m_last_sports_pad_time_2; | |
| 150 | UINT8 m_sports_pad_state_1; | |
| 151 | UINT8 m_sports_pad_state_2; | |
| 152 | UINT8 m_sports_pad_last_data_1; | |
| 153 | UINT8 m_sports_pad_last_data_2; | |
| 154 | UINT8 m_sports_pad_1_x; | |
| 155 | UINT8 m_sports_pad_1_y; | |
| 156 | UINT8 m_sports_pad_2_x; | |
| 157 | UINT8 m_sports_pad_2_y; | |
| 158 | ||
| 159 | 108 | // Data needed for Light Phaser |
| 160 | emu_timer *m_lphaser_1_timer; | |
| 161 | emu_timer *m_lphaser_2_timer; | |
| 162 | UINT8 m_lphaser_1_latch; | |
| 163 | UINT8 m_lphaser_2_latch; | |
| 109 | UINT8 m_ctrl1_th_latch; | |
| 110 | UINT8 m_ctrl2_th_latch; | |
| 164 | 111 | int m_lphaser_x_offs; /* Needed to 'calibrate' lphaser; set at cart loading */ |
| 165 | 112 | |
| 166 | 113 | // Data needed for SegaScope (3D glasses) |
| r23785 | r23786 | |
| 174 | 121 | sega8_card_slot_device *m_cards[16]; |
| 175 | 122 | |
| 176 | 123 | /* Cartridge slot info */ |
| 177 | DECLARE_WRITE8_MEMBER(sms_input_write); | |
| 178 | 124 | DECLARE_WRITE8_MEMBER(sms_fm_detect_w); |
| 179 | 125 | DECLARE_READ8_MEMBER(sms_fm_detect_r); |
| 180 | 126 | DECLARE_WRITE8_MEMBER(sms_io_control_w); |
| 181 | 127 | DECLARE_READ8_MEMBER(sms_count_r); |
| 182 | DECLARE_READ8_MEMBER(sms_input_port_0_r); | |
| 183 | DECLARE_READ8_MEMBER(sms_input_port_1_r); | |
| 184 | DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_0_w); | |
| 185 | DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_0_w); | |
| 128 | DECLARE_READ8_MEMBER(sms_input_port_dc_r); | |
| 129 | DECLARE_READ8_MEMBER(sms_input_port_dd_r); | |
| 130 | DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w); | |
| 131 | DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w); | |
| 186 | 132 | DECLARE_READ8_MEMBER(gg_input_port_2_r); |
| 187 | 133 | DECLARE_READ8_MEMBER(sms_sscope_r); |
| 188 | 134 | DECLARE_WRITE8_MEMBER(sms_sscope_w); |
| r23785 | r23786 | |
| 211 | 157 | UINT32 screen_update_sms(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 212 | 158 | UINT32 screen_update_sms1(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); |
| 213 | 159 | void screen_vblank_sms1(screen_device &screen, bool state); |
| 214 | DECLARE_INPUT_CHANGED_MEMBER(lgun1_changed); | |
| 215 | DECLARE_INPUT_CHANGED_MEMBER(lgun2_changed); | |
| 216 | TIMER_CALLBACK_MEMBER(rapid_fire_callback); | |
| 217 | TIMER_CALLBACK_MEMBER(lightgun_tick); | |
| 218 | TIMER_CALLBACK_MEMBER(lphaser_1_callback); | |
| 219 | TIMER_CALLBACK_MEMBER(lphaser_2_callback); | |
| 220 | 160 | DECLARE_WRITE_LINE_MEMBER(sms_int_callback); |
| 221 | 161 | DECLARE_WRITE_LINE_MEMBER(sms_pause_callback); |
| 162 | DECLARE_READ32_MEMBER(sms_pixel_color); | |
| 163 | DECLARE_WRITE16_MEMBER(sms_ctrl1_th_input); | |
| 164 | DECLARE_WRITE16_MEMBER(sms_ctrl2_th_input); | |
| 222 | 165 | |
| 223 | 166 | protected: |
| 224 | 167 | void setup_bios(); |
| 225 | 168 | void setup_rom(); |
| 226 | 169 | void setup_sms_cart(); |
| 227 | 170 | void lphaser_hcount_latch(int hpos); |
| 228 | void lphaser1_sensor_check(); | |
| 229 | void lphaser2_sensor_check(); | |
| 230 | UINT16 screen_hpos_nonscaled(int scaled_hpos); | |
| 231 | UINT16 screen_vpos_nonscaled(int scaled_vpos); | |
| 232 | int lgun_bright_aim_area(emu_timer *timer, int lgun_x, int lgun_y); | |
| 233 | 171 | void sms_get_inputs(address_space &space); |
| 234 | virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr); | |
| 235 | 172 | }; |
| 236 | 173 | |
| 237 | 174 | class smssdisp_state : public sms_state |
| r23785 | r23786 | |
|---|---|---|
| 276 | 276 | AM_RANGE(0x40, 0x7f) AM_DEVWRITE("segapsg", segapsg_device, write) |
| 277 | 277 | AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) |
| 278 | 278 | AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) |
| 279 | AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_0_r) | |
| 280 | AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_1_r) | |
| 281 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_0_r) | |
| 282 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_1_r) | |
| 283 | AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_0_r, sms_ym2413_register_port_0_w) | |
| 284 | AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_1_r, sms_ym2413_data_port_0_w) | |
| 279 | AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_dc_r) | |
| 280 | AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_dd_r) | |
| 281 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_dc_r) | |
| 282 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_dd_r) | |
| 283 | AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_dc_r, sms_ym2413_register_port_w) | |
| 284 | AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_dd_r, sms_ym2413_data_port_w) | |
| 285 | 285 | AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_fm_detect_r, sms_fm_detect_w) |
| 286 | AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_1_r) | |
| 287 | AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_0_r) | |
| 288 | AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_1_r) | |
| 289 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_0_r) | |
| 290 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_1_r) | |
| 286 | AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_dd_r) | |
| 287 | AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_dc_r) | |
| 288 | AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_dd_r) | |
| 289 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_dc_r) | |
| 290 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_dd_r) | |
| 291 | 291 | ADDRESS_MAP_END |
| 292 | 292 | |
| 293 | 293 | |
| r23785 | r23786 | |
| 299 | 299 | AM_RANGE(0x40, 0x7f) AM_DEVWRITE("segapsg", segapsg_device, write) |
| 300 | 300 | AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) |
| 301 | 301 | AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) |
| 302 | AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_0_r) | |
| 303 | AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_1_r) | |
| 304 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_0_r) | |
| 305 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_1_r) | |
| 306 | AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_0_r, sms_ym2413_register_port_0_w) | |
| 307 | AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_1_r, sms_ym2413_data_port_0_w) | |
| 302 | AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_dc_r) | |
| 303 | AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_dd_r) | |
| 304 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_dc_r) | |
| 305 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_dd_r) | |
| 306 | AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_dc_r, sms_ym2413_register_port_w) | |
| 307 | AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_dd_r, sms_ym2413_data_port_w) | |
| 308 | 308 | AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_fm_detect_r, sms_fm_detect_w) |
| 309 | AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_1_r) | |
| 310 | AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_0_r) | |
| 311 | AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_1_r) | |
| 312 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_0_r) | |
| 313 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_1_r) | |
| 309 | AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_dd_r) | |
| 310 | AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_dc_r) | |
| 311 | AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_dd_r) | |
| 312 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_dc_r) | |
| 313 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_dd_r) | |
| 314 | 314 | ADDRESS_MAP_END |
| 315 | 315 | |
| 316 | 316 | |
| r23785 | r23786 | |
| 327 | 327 | AM_RANGE(0x40, 0x7f) AM_DEVWRITE("segapsg", segapsg_device, write) |
| 328 | 328 | AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) |
| 329 | 329 | AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) |
| 330 | AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_0_r) | |
| 331 | AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_1_r) | |
| 332 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_0_r) | |
| 333 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_1_r) | |
| 334 | AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_0_r, sms_ym2413_register_port_0_w) | |
| 335 | AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_1_r, sms_ym2413_data_port_0_w) | |
| 330 | AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_dc_r) | |
| 331 | AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_dd_r) | |
| 332 | AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_dc_r) | |
| 333 | AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_dd_r) | |
| 334 | AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_dc_r, sms_ym2413_register_port_w) | |
| 335 | AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_dd_r, sms_ym2413_data_port_w) | |
| 336 | 336 | AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_fm_detect_r, sms_fm_detect_w) |
| 337 | AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_1_r) | |
| 338 | AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_0_r) | |
| 339 | AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_1_r) | |
| 340 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_0_r) | |
| 341 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_1_r) | |
| 337 | AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_dd_r) | |
| 338 | AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_dc_r) | |
| 339 | AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_dd_r) | |
| 340 | AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_dc_r) | |
| 341 | AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_dd_r) | |
| 342 | 342 | ADDRESS_MAP_END |
| 343 | 343 | |
| 344 | 344 | static ADDRESS_MAP_START( gg_io, AS_IO, 8, sms_state ) |
| r23785 | r23786 | |
| 358 | 358 | AM_RANGE(0x40, 0x7f) AM_DEVWRITE("gamegear", gamegear_device, write) |
| 359 | 359 | AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) |
| 360 | 360 | AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) |
| 361 | AM_RANGE(0xc0, 0xc0) AM_READ_PORT("PORT_DC") | |
| 362 | AM_RANGE(0xc1, 0xc1) AM_READ_PORT("PORT_DD") | |
| 363 | AM_RANGE(0xdc, 0xdc) AM_READ_PORT("PORT_DC") | |
| 364 | AM_RANGE(0xdd, 0xdd) AM_READ_PORT("PORT_DD") | |
| 361 | AM_RANGE(0xc0, 0xc0) AM_READ_PORT("GG_PORT_DC") | |
| 362 | AM_RANGE(0xc1, 0xc1) AM_READ_PORT("GG_PORT_DD") | |
| 363 | AM_RANGE(0xdc, 0xdc) AM_READ_PORT("GG_PORT_DC") | |
| 364 | AM_RANGE(0xdd, 0xdd) AM_READ_PORT("GG_PORT_DD") | |
| 365 | 365 | ADDRESS_MAP_END |
| 366 | 366 | |
| 367 | 367 | |
| 368 | 368 | static INPUT_PORTS_START( sms ) |
| 369 | PORT_START("PORT_DC") | |
| 370 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) | |
| 371 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) | |
| 372 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) | |
| 373 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_8WAY PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) | |
| 374 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) | |
| 375 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x00) | |
| 376 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) | |
| 377 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) | |
| 378 | ||
| 379 | PORT_START("PORT_DD") | |
| 380 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) | |
| 381 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_8WAY PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) | |
| 382 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) | |
| 383 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x00) | |
| 384 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) /* Software Reset bit */ | |
| 385 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) | |
| 386 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port A TH */ | |
| 387 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) /* Port B TH */ | |
| 388 | ||
| 389 | 369 | PORT_START("PAUSE") |
| 390 | 370 | PORT_BIT( 0x7f, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 391 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_START ) PORT_NAME(DEF_STR(Pause)) | |
| 392 | ||
| 393 | PORT_START("LPHASER0") /* Light phaser X - player 1 */ | |
| 394 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_state, lgun1_changed, NULL) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01) | |
| 395 | ||
| 396 | PORT_START("LPHASER1") /* Light phaser Y - player 1 */ | |
| 397 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(1) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_state, lgun1_changed, NULL) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01) | |
| 398 | ||
| 399 | PORT_START("LPHASER2") /* Light phaser X - player 2 */ | |
| 400 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_X ) PORT_CROSSHAIR( X, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_state, lgun2_changed, NULL) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10) | |
| 401 | ||
| 402 | PORT_START("LPHASER3") /* Light phaser Y - player 2 */ | |
| 403 | PORT_BIT( 0xff, 0x80, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR( Y, 1.0, 0.0, 0 ) PORT_SENSITIVITY(50) PORT_KEYDELTA(15) PORT_PLAYER(2) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_state, lgun2_changed, NULL) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10) | |
| 404 | ||
| 405 | PORT_START("RFU") /* Rapid Fire Unit */ | |
| 406 | PORT_CONFNAME( 0x03, 0x00, "Rapid Fire Unit - Player 1" ) | |
| 407 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) | |
| 408 | PORT_CONFSETTING( 0x01, "Button A" ) | |
| 409 | PORT_CONFSETTING( 0x02, "Button B" ) | |
| 410 | PORT_CONFSETTING( 0x03, "Button A + B" ) | |
| 411 | PORT_CONFNAME( 0x0c, 0x00, "Rapid Fire Unit - Player 2" ) | |
| 412 | PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) | |
| 413 | PORT_CONFSETTING( 0x04, "Button A" ) | |
| 414 | PORT_CONFSETTING( 0x08, "Button B" ) | |
| 415 | PORT_CONFSETTING( 0x0c, "Button A + B" ) | |
| 416 | ||
| 417 | PORT_START("PADDLE0") /* Paddle player 1 */ | |
| 418 | PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x02) | |
| 419 | ||
| 420 | PORT_START("PADDLE1") /* Paddle player 2 */ | |
| 421 | PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x20) | |
| 422 | ||
| 423 | PORT_START("CTRLIPT") /* Light Phaser and Paddle Control buttons */ | |
| 424 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x01) | |
| 425 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x02) | |
| 426 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x04) | |
| 427 | PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x04) | |
| 428 | PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x10) | |
| 429 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x20) | |
| 430 | PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x40) | |
| 431 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x40) | |
| 432 | ||
| 433 | PORT_START("CTRLSEL") /* Controller selection */ | |
| 434 | PORT_CONFNAME( 0x0f, 0x00, "Player 1 Controller" ) | |
| 435 | PORT_CONFSETTING( 0x00, DEF_STR( Joystick ) ) | |
| 436 | PORT_CONFSETTING( 0x01, "Light Phaser" ) | |
| 437 | PORT_CONFSETTING( 0x02, "Sega Paddle Control" ) | |
| 438 | PORT_CONFSETTING( 0x04, "Sega Sports Pad" ) | |
| 439 | PORT_CONFNAME( 0xf0, 0x00, "Player 2 Controller" ) | |
| 440 | PORT_CONFSETTING( 0x00, DEF_STR( Joystick ) ) | |
| 441 | PORT_CONFSETTING( 0x10, "Light Phaser" ) | |
| 442 | PORT_CONFSETTING( 0x20, "Sega Paddle Control" ) | |
| 443 | PORT_CONFSETTING( 0x40, "Sega Sports Pad" ) | |
| 444 | ||
| 445 | PORT_START("SPORT0") /* Player 1 Sports Pad X axis */ | |
| 446 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x04) | |
| 447 | ||
| 448 | PORT_START("SPORT1") /* Player 1 Sports Pad Y axis */ | |
| 449 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(1) PORT_CONDITION("CTRLSEL", 0x0f, EQUALS, 0x04) | |
| 450 | ||
| 451 | PORT_START("SPORT2") /* Player 2 Sports Pad X axis */ | |
| 452 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x40) | |
| 453 | ||
| 454 | PORT_START("SPORT3") /* Player 2 Sports Pad Y axis */ | |
| 455 | PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE PORT_PLAYER(2) PORT_CONDITION("CTRLSEL", 0xf0, EQUALS, 0x40) | |
| 371 | PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_1) | |
| 456 | 372 | INPUT_PORTS_END |
| 457 | 373 | |
| 458 | 374 | static INPUT_PORTS_START( sms1 ) |
| r23785 | r23786 | |
| 476 | 392 | INPUT_PORTS_END |
| 477 | 393 | |
| 478 | 394 | static INPUT_PORTS_START( gg ) |
| 479 | PORT_START("PORT_DC") | |
| 395 | PORT_START("GG_PORT_DC") | |
| 480 | 396 | PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY |
| 481 | 397 | PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_8WAY |
| 482 | 398 | PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_8WAY |
| r23785 | r23786 | |
| 485 | 401 | PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) |
| 486 | 402 | PORT_BIT( 0xc0, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 487 | 403 | |
| 488 | PORT_START("PORT_DD") | |
| 404 | PORT_START("GG_PORT_DD") | |
| 489 | 405 | PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) |
| 490 | 406 | |
| 491 | 407 | PORT_START("START") |
| r23785 | r23786 | |
| 595 | 511 | MCFG_SMS_CARTRIDGE_ADD("slot", sms_cart, NULL) |
| 596 | 512 | |
| 597 | 513 | MCFG_SOFTWARE_LIST_ADD("cart_list","sms") |
| 514 | ||
| 515 | MCFG_SMS_CONTROL_PORT_ADD(CONTROL1_TAG, sms_control_port_devices, "joypad") | |
| 516 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_state, sms_ctrl1_th_input)) | |
| 517 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) | |
| 518 | ||
| 519 | MCFG_SMS_CONTROL_PORT_ADD(CONTROL2_TAG, sms_control_port_devices, "joypad") | |
| 520 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_state, sms_ctrl2_th_input)) | |
| 521 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) | |
| 598 | 522 | MACHINE_CONFIG_END |
| 599 | 523 | |
| 600 | 524 | static MACHINE_CONFIG_DERIVED( sms2_ntsc, sms_ntsc_base ) |
| r23785 | r23786 | |
| 721 | 645 | MCFG_SMS_CARD_ADD("slot32", sms_cart, NULL) |
| 722 | 646 | |
| 723 | 647 | MCFG_SOFTWARE_LIST_ADD("cart_list","sms") |
| 648 | ||
| 649 | MCFG_SMS_CONTROL_PORT_ADD(CONTROL1_TAG, sms_control_port_devices, "joypad") | |
| 650 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_state, sms_ctrl1_th_input)) | |
| 651 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) | |
| 652 | ||
| 653 | MCFG_SMS_CONTROL_PORT_ADD(CONTROL2_TAG, sms_control_port_devices, "joypad") | |
| 654 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_state, sms_ctrl2_th_input)) | |
| 655 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) | |
| 724 | 656 | MACHINE_CONFIG_END |
| 725 | 657 | |
| 726 | 658 | static MACHINE_CONFIG_START( sms_pal_base, sms_state ) |
| r23785 | r23786 | |
| 743 | 675 | MCFG_SMS_CARTRIDGE_ADD("slot", sms_cart, NULL) |
| 744 | 676 | |
| 745 | 677 | MCFG_SOFTWARE_LIST_ADD("cart_list","sms") |
| 678 | ||
| 679 | MCFG_SMS_CONTROL_PORT_ADD(CONTROL1_TAG, sms_control_port_devices, "joypad") | |
| 680 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_state, sms_ctrl1_th_input)) | |
| 681 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) | |
| 682 | ||
| 683 | MCFG_SMS_CONTROL_PORT_ADD(CONTROL2_TAG, sms_control_port_devices, "joypad") | |
| 684 | MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITE16(sms_state, sms_ctrl2_th_input)) | |
| 685 | MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) | |
| 746 | 686 | MACHINE_CONFIG_END |
| 747 | 687 | |
| 748 | 688 | static MACHINE_CONFIG_DERIVED( sms2_pal, sms_pal_base ) |
| r23785 | r23786 | |
|---|---|---|
| 1928 | 1928 | $(MESS_MACHINE)/sat_bram.o \ |
| 1929 | 1929 | $(MESS_DRIVERS)/saturn.o \ |
| 1930 | 1930 | $(MESS_MACHINE)/sms.o \ |
| 1931 | $(MESS_MACHINE)/sega8_slot.o \ | |
| 1931 | $(MESS_MACHINE)/smsctrl.o \ | |
| 1932 | $(MESS_MACHINE)/sms_joypad.o \ | |
| 1933 | $(MESS_MACHINE)/sms_lphaser.o \ | |
| 1934 | $(MESS_MACHINE)/sms_paddle.o \ | |
| 1935 | $(MESS_MACHINE)/sms_sports.o \ | |
| 1936 | $(MESS_MACHINE)/sms_rfu.o \ | |
| 1937 | $(MESS_MACHINE)/sega8_slot.o \ | |
| 1932 | 1938 | $(MESS_MACHINE)/sega8_rom.o \ |
| 1933 | 1939 | $(MESS_DRIVERS)/sms.o \ |
| 1934 | 1940 | $(MESS_DRIVERS)/svmu.o \ |
| Previous | 199869 Revisions | Next |