summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--hash/sms.xml1
-rw-r--r--src/devices/bus/sms_ctrl/lphaser.cpp11
-rw-r--r--src/devices/bus/sms_ctrl/lphaser.h2
-rw-r--r--src/devices/bus/sms_ctrl/paddle.cpp8
-rw-r--r--src/devices/bus/sms_ctrl/paddle.h4
-rw-r--r--src/devices/bus/sms_ctrl/sports.cpp20
-rw-r--r--src/devices/bus/sms_ctrl/sports.h8
-rw-r--r--src/devices/bus/sms_ctrl/sportsjp.cpp88
-rw-r--r--src/devices/bus/sms_ctrl/sportsjp.h9
-rw-r--r--src/mame/drivers/sms.cpp8
10 files changed, 85 insertions, 74 deletions
diff --git a/hash/sms.xml b/hash/sms.xml
index 03d0930f9f7..a5e70ea41e8 100644
--- a/hash/sms.xml
+++ b/hash/sms.xml
@@ -6128,6 +6128,7 @@
</part>
</software>
+ <!-- Notes: This has a player 2 input bug: it reads part of player 1 data instead (see sportsjp.cpp) -->
<software name="sportssc" cloneof="worldsoc">
<description>Sports Pad Soccer (Jpn)</description>
<year>1988</year>
diff --git a/src/devices/bus/sms_ctrl/lphaser.cpp b/src/devices/bus/sms_ctrl/lphaser.cpp
index 8a49c9a1554..ccf240d9eec 100644
--- a/src/devices/bus/sms_ctrl/lphaser.cpp
+++ b/src/devices/bus/sms_ctrl/lphaser.cpp
@@ -12,6 +12,13 @@ Release data from the Sega Retro project:
Year: 1989 Country/region: BR Model code: 010470
Year: 198? Country/region: KR Model code: ?
+Notes:
+
+ The Light Phaser gun doesn't work with the Japanese SMS and Sega Mark III.
+ There are reports about Light Phaser working on the second Korean SMS
+ version, and a Korean advert shows support on the first version (Gam*Boy I,
+ although based on Japanese SMS).
+
**********************************************************************/
#include "lphaser.h"
@@ -29,7 +36,7 @@ const device_type SMS_LIGHT_PHASER = &device_creator<sms_light_phaser_device>;
#define LGUN_X_INTERVAL 4
-CUSTOM_INPUT_MEMBER( sms_light_phaser_device::th_pin_r )
+READ_LINE_MEMBER( sms_light_phaser_device::th_pin_r )
{
// The returned value is inverted due to IP_ACTIVE_LOW mapping.
return ~m_sensor_last_state;
@@ -46,7 +53,7 @@ INPUT_CHANGED_MEMBER( sms_light_phaser_device::position_changed )
static INPUT_PORTS_START( sms_light_phaser )
PORT_START("CTRL_PORT")
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (trigger)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_light_phaser_device, th_pin_r, nullptr)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER(DEVICE_SELF, sms_light_phaser_device, th_pin_r)
PORT_BIT( 0x9f, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("LPHASER_X")
diff --git a/src/devices/bus/sms_ctrl/lphaser.h b/src/devices/bus/sms_ctrl/lphaser.h
index 7d2f9ca1ed6..860b8d4007f 100644
--- a/src/devices/bus/sms_ctrl/lphaser.h
+++ b/src/devices/bus/sms_ctrl/lphaser.h
@@ -34,7 +34,7 @@ public:
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
- DECLARE_CUSTOM_INPUT_MEMBER( th_pin_r );
+ DECLARE_READ_LINE_MEMBER( th_pin_r );
DECLARE_INPUT_CHANGED_MEMBER( position_changed );
protected:
diff --git a/src/devices/bus/sms_ctrl/paddle.cpp b/src/devices/bus/sms_ctrl/paddle.cpp
index f502b9ad196..964a00f5133 100644
--- a/src/devices/bus/sms_ctrl/paddle.cpp
+++ b/src/devices/bus/sms_ctrl/paddle.cpp
@@ -38,7 +38,7 @@ const device_type SMS_PADDLE = &device_creator<sms_paddle_device>;
#define PADDLE_INTERVAL attotime::from_hz(XTAL_53_693175MHz/15/100)
-CUSTOM_INPUT_MEMBER( sms_paddle_device::dir_pins_r )
+CUSTOM_INPUT_MEMBER( sms_paddle_device::rldu_pins_r )
{
UINT8 data = m_paddle_x->read();
@@ -50,7 +50,7 @@ CUSTOM_INPUT_MEMBER( sms_paddle_device::dir_pins_r )
}
-CUSTOM_INPUT_MEMBER( sms_paddle_device::tr_pin_r )
+READ_LINE_MEMBER( sms_paddle_device::tr_pin_r )
{
// The returned value is inverted due to IP_ACTIVE_LOW mapping.
return ~m_read_state;
@@ -59,11 +59,11 @@ CUSTOM_INPUT_MEMBER( sms_paddle_device::tr_pin_r )
static INPUT_PORTS_START( sms_paddle )
PORT_START("CTRL_PORT")
- PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_paddle_device, dir_pins_r, nullptr) // Directional pins
+ PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_paddle_device, rldu_pins_r, nullptr) // R,L,D,U
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // TH
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_paddle_device, tr_pin_r, nullptr)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER( DEVICE_SELF, sms_paddle_device, tr_pin_r ) // TR
PORT_START("PADDLE_X") // Paddle knob
PORT_BIT( 0xff, 0x80, IPT_PADDLE) PORT_SENSITIVITY(40) PORT_KEYDELTA(20) PORT_CENTERDELTA(0) PORT_MINMAX(0,255)
diff --git a/src/devices/bus/sms_ctrl/paddle.h b/src/devices/bus/sms_ctrl/paddle.h
index fae7a93fb19..968abe1b345 100644
--- a/src/devices/bus/sms_ctrl/paddle.h
+++ b/src/devices/bus/sms_ctrl/paddle.h
@@ -33,8 +33,8 @@ public:
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
- DECLARE_CUSTOM_INPUT_MEMBER( dir_pins_r );
- DECLARE_CUSTOM_INPUT_MEMBER( tr_pin_r );
+ DECLARE_CUSTOM_INPUT_MEMBER( rldu_pins_r ); // Right, Left, Down and Up lines.
+ DECLARE_READ_LINE_MEMBER( tr_pin_r );
protected:
// device-level overrides
diff --git a/src/devices/bus/sms_ctrl/sports.cpp b/src/devices/bus/sms_ctrl/sports.cpp
index b4bd54d81a1..54fa867a8c1 100644
--- a/src/devices/bus/sms_ctrl/sports.cpp
+++ b/src/devices/bus/sms_ctrl/sports.cpp
@@ -82,21 +82,21 @@ void sms_sports_pad_device::device_timer(emu_timer &timer, device_timer_id id, i
}
-CUSTOM_INPUT_MEMBER( sms_sports_pad_device::th_pin_r )
+READ_LINE_MEMBER( sms_sports_pad_device::th_pin_r )
{
- return m_last_data;
+ return m_th_pin_state;
}
-INPUT_CHANGED_MEMBER( sms_sports_pad_device::th_pin_w )
+WRITE_LINE_MEMBER( sms_sports_pad_device::th_pin_w )
{
m_read_state = (m_read_state + 1) & 3;
m_sportspad_timer->adjust(m_interval);
- m_last_data = newval;
+ m_th_pin_state = state;
}
-CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r )
+CUSTOM_INPUT_MEMBER( sms_sports_pad_device::rldu_pins_r )
{
UINT8 data = 0;
@@ -123,17 +123,17 @@ CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r )
static INPUT_PORTS_START( sms_sports_pad )
PORT_START("SPORTS_IN")
- PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, dir_pins_r, nullptr) // Directional pins
+ PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, rldu_pins_r, nullptr) // R,L,D,U
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (Button 1)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_r, nullptr)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_r) // TH
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) // TR (Button 2)
PORT_START("SPORTS_OUT")
PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_UNUSED ) // Directional pins
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) // TL (Button 1)
- PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OUTPUT ) PORT_CHANGED_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_w, nullptr)
+ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_OUTPUT ) PORT_WRITE_LINE_DEVICE_MEMBER(DEVICE_SELF, sms_sports_pad_device, th_pin_w) // TH
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // TR (Button 2)
PORT_START("SPORTS_X") /* Sports Pad X axis */
@@ -171,7 +171,7 @@ sms_sports_pad_device::sms_sports_pad_device(const machine_config &mconfig, cons
m_sports_x(*this, "SPORTS_X"),
m_sports_y(*this, "SPORTS_Y"),
m_read_state(0),
- m_last_data(0),
+ m_th_pin_state(0),
m_x_axis_reset_value(0x80), // value 0x80 helps when start playing paddle games.
m_y_axis_reset_value(0x80),
m_interval(SPORTS_PAD_INTERVAL), m_sportspad_timer(nullptr)
@@ -188,7 +188,7 @@ void sms_sports_pad_device::device_start()
m_sportspad_timer = timer_alloc(TIMER_SPORTSPAD);
save_item(NAME(m_read_state));
- save_item(NAME(m_last_data));
+ save_item(NAME(m_th_pin_state));
save_item(NAME(m_x_axis_reset_value));
save_item(NAME(m_y_axis_reset_value));
}
diff --git a/src/devices/bus/sms_ctrl/sports.h b/src/devices/bus/sms_ctrl/sports.h
index fe98c9e5e70..5ca209e748d 100644
--- a/src/devices/bus/sms_ctrl/sports.h
+++ b/src/devices/bus/sms_ctrl/sports.h
@@ -33,9 +33,9 @@ public:
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
- DECLARE_CUSTOM_INPUT_MEMBER( dir_pins_r );
- DECLARE_CUSTOM_INPUT_MEMBER( th_pin_r );
- DECLARE_INPUT_CHANGED_MEMBER( th_pin_w );
+ DECLARE_CUSTOM_INPUT_MEMBER( rldu_pins_r ); // Right, Left, Down and Up lines.
+ DECLARE_READ_LINE_MEMBER( th_pin_r );
+ DECLARE_WRITE_LINE_MEMBER( th_pin_w );
protected:
// device-level overrides
@@ -52,7 +52,7 @@ private:
required_ioport m_sports_y;
UINT8 m_read_state;
- UINT8 m_last_data;
+ UINT8 m_th_pin_state;
UINT8 m_x_axis_reset_value;
UINT8 m_y_axis_reset_value;
const attotime m_interval;
diff --git a/src/devices/bus/sms_ctrl/sportsjp.cpp b/src/devices/bus/sms_ctrl/sportsjp.cpp
index fef04df69e8..e9b148c19e9 100644
--- a/src/devices/bus/sms_ctrl/sportsjp.cpp
+++ b/src/devices/bus/sms_ctrl/sportsjp.cpp
@@ -22,6 +22,13 @@ Notes:
used by the US model, due to the missing TH line on Sega Mark III
controller ports.
+ A bug was discovered in the player 2 input handling code of the only known
+ good ROM dump of Sports Pad Soccer (JP):
+ size="131072" crc="41c948bf" sha1="7634ce39e87049dad1ee4f32a80d728e4bd1f81f"
+ At address $12D1, instead read the upper 2 bits of port $DC and lower 2 bits
+ of port $DD (to obtain the lower nibble of the current axis for player 2),
+ the code wrongly reads the lower nibble of port $DC, that is player 1 data.
+
**********************************************************************/
#include "sportsjp.h"
@@ -39,38 +46,24 @@ const device_type SMS_SPORTS_PAD_JP = &device_creator<sms_sports_pad_jp_device>;
-DECLARE_CUSTOM_INPUT_MEMBER( sms_sports_pad_jp_device::dir_pins_r )
-{
- UINT8 data = 0;
-
- switch (m_read_state)
- {
- case 0:
- data = m_sports_jp_x->read() >> 4;
- break;
- case 1:
- data = m_sports_jp_x->read();
- break;
- case 2:
- data = m_sports_jp_y->read() >> 4;
- break;
- case 3:
- data = m_sports_jp_y->read();
- break;
- }
-
- // The returned value is inverted due to IP_ACTIVE_LOW mapping.
- return ~(data & 0x0f);
-}
+// The returned value is inverted due to IP_ACTIVE_LOW mapping.
+READ_LINE_MEMBER( sms_sports_pad_jp_device::tl_pin_r ) { return ~m_tl_pin_state; }
+READ_LINE_MEMBER( sms_sports_pad_jp_device::tr_pin_r ) { return ~m_tr_pin_state; }
+CUSTOM_INPUT_MEMBER( sms_sports_pad_jp_device::rldu_pins_r ) { return ~(m_rldu_pins_state & 0x0f); }
static INPUT_PORTS_START( sms_sports_pad_jp )
PORT_START("SPORTS_JP_IN")
- PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_jp_device, dir_pins_r, nullptr) // Directional pins
+ PORT_BIT( 0x0f, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_CUSTOM_MEMBER(DEVICE_SELF, sms_sports_pad_jp_device, rldu_pins_r, nullptr) // R,L,D,U
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) // Vcc
- PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // TL (Button 1)
+ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER( DEVICE_SELF, sms_sports_pad_jp_device, tl_pin_r ) // TL
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNUSED ) // TH
- PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON2 ) // TR (Button 2)
+ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SPECIAL ) PORT_READ_LINE_DEVICE_MEMBER( DEVICE_SELF, sms_sports_pad_jp_device, tr_pin_r ) // TR
+
+ PORT_START("SPORTS_JP_BT") /* Sports Pad buttons nibble */
+ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 )
+ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 )
+ PORT_BIT( 0x0c, IP_ACTIVE_LOW, IPT_UNUSED )
PORT_START("SPORTS_JP_X") /* Sports Pad X axis */
PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40)
@@ -103,9 +96,12 @@ sms_sports_pad_jp_device::sms_sports_pad_jp_device(const machine_config &mconfig
device_t(mconfig, SMS_SPORTS_PAD_JP, "Sega SMS Sports Pad JP", tag, owner, clock, "sms_sports_pad_jp", __FILE__),
device_sms_control_port_interface(mconfig, *this),
m_sports_jp_in(*this, "SPORTS_JP_IN"),
+ m_sports_jp_bt(*this, "SPORTS_JP_BT"),
m_sports_jp_x(*this, "SPORTS_JP_X"),
m_sports_jp_y(*this, "SPORTS_JP_Y"),
- m_read_state(0),
+ m_rldu_pins_state(0x0f),
+ m_tl_pin_state(1),
+ m_tr_pin_state(1),
m_interval(SPORTS_PAD_JP_INTERVAL)
{
}
@@ -120,7 +116,9 @@ void sms_sports_pad_jp_device::device_start()
m_start_time = machine().time();
save_item(NAME(m_start_time));
- save_item(NAME(m_read_state));
+ save_item(NAME(m_rldu_pins_state));
+ save_item(NAME(m_tl_pin_state));
+ save_item(NAME(m_tr_pin_state));
}
@@ -130,41 +128,41 @@ void sms_sports_pad_jp_device::device_start()
UINT8 sms_sports_pad_jp_device::peripheral_r()
{
- UINT8 data;
int num_intervals = (machine().time() - m_start_time).as_double() / m_interval.as_double();
- m_read_state = num_intervals % 5;
-
- data = m_sports_jp_in->read();
- switch (m_read_state)
+ switch (num_intervals % 5)
{
case 0:
// X high nibble
- data &= ~0x20; // TL 0
- data &= ~0x80; // TR 0
+ m_rldu_pins_state = m_sports_jp_x->read() >> 4;
+ m_tl_pin_state = 0;
+ m_tr_pin_state = 0;
break;
case 1:
// X low nibble
- data |= 0x20; // TL 1
- data &= ~0x80; // TR 0
+ m_rldu_pins_state = m_sports_jp_x->read();
+ m_tl_pin_state = 1;
+ m_tr_pin_state = 0;
break;
case 2:
// Y high nibble
- data &= ~0x20; // TL 0
- data &= ~0x80; // TR 0
+ m_rldu_pins_state = m_sports_jp_y->read() >> 4;
+ m_tl_pin_state = 0;
+ m_tr_pin_state = 0;
break;
case 3:
// Y low nibble
- data |= 0x20; // TL 1
- data &= ~0x80; // TR 0
+ m_rldu_pins_state = m_sports_jp_y->read();
+ m_tl_pin_state = 1;
+ m_tr_pin_state = 0;
break;
case 4:
// buttons 1 and 2
- data = (data & 0x20) >> 5 | (data & 0x80) >> 6 | 0xfc;
- data |= 0x20; // TL 1
- data |= 0x80; // TR 1
+ m_rldu_pins_state = m_sports_jp_bt->read();
+ m_tl_pin_state = 1;
+ m_tr_pin_state = 1;
break;
}
- return data;
+ return m_sports_jp_in->read();
}
diff --git a/src/devices/bus/sms_ctrl/sportsjp.h b/src/devices/bus/sms_ctrl/sportsjp.h
index ad438d12bb1..3e82c18dd85 100644
--- a/src/devices/bus/sms_ctrl/sportsjp.h
+++ b/src/devices/bus/sms_ctrl/sportsjp.h
@@ -33,7 +33,9 @@ public:
// optional information overrides
virtual ioport_constructor device_input_ports() const override;
- CUSTOM_INPUT_MEMBER( dir_pins_r );
+ DECLARE_CUSTOM_INPUT_MEMBER( rldu_pins_r ); // Right, Left, Down and Up lines.
+ DECLARE_READ_LINE_MEMBER( tl_pin_r );
+ DECLARE_READ_LINE_MEMBER( tr_pin_r );
protected:
// device-level overrides
@@ -44,10 +46,13 @@ protected:
private:
required_ioport m_sports_jp_in;
+ required_ioport m_sports_jp_bt;
required_ioport m_sports_jp_x;
required_ioport m_sports_jp_y;
- UINT8 m_read_state;
+ UINT8 m_rldu_pins_state;
+ UINT8 m_tl_pin_state;
+ UINT8 m_tr_pin_state;
attotime m_start_time;
const attotime m_interval;
};
diff --git a/src/mame/drivers/sms.cpp b/src/mame/drivers/sms.cpp
index a3839649aac..1f2ddde1437 100644
--- a/src/mame/drivers/sms.cpp
+++ b/src/mame/drivers/sms.cpp
@@ -60,7 +60,7 @@ General compatibility issues on real hardware (not emulation bugs):
Paddle controller;
- Few games of the ones with FM support need to detect the system region as
Japanese to play FM sound;
-- The Light Phaser gun doesn't work with the Japanese SMS;
+- The Light Phaser gun doesn't work with the Japanese SMS and Sega Mark III;
- There are reports about Light Phaser working on the second Korean SMS
version, and a Korean advert shows support on the first version (Gam*Boy I,
although based on Japanese SMS);
@@ -337,10 +337,10 @@ ADDRESS_MAP_END
// The first Korean SMS version also seems to lack I/O port $3F. Games execute
// a region detection procedure that, through that port, sets the mode used by
-// the TH bits of port $DD and tests their behavior. The region of the first SMS
+// the TH bits of port $DD and tests their behaviour. The region of the first SMS
// version is detected as Japanese (opposite to the second version). However,
-// as it supports Light Phaser games, it doesn't have the same behavior of the
-// Japanese SMS. If it had the behavior of other SMS versions, the system
+// as it supports Light Phaser games, it doesn't have the same behaviour of the
+// Japanese SMS. If it had the behaviour of other SMS versions, the system
// region would be detected as Export, so it probably lacks the port.
static ADDRESS_MAP_START( sms1kr_io, AS_IO, 8, sms_state )
AM_IMPORT_FROM(sg1000m3_io)