summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/sms_ctrl
diff options
context:
space:
mode:
author Scott Stone <tafoid@gmail.com>2015-09-14 17:54:24 -0400
committer Scott Stone <tafoid@gmail.com>2015-09-14 17:54:24 -0400
commit249d8f752cd1e4fe12e7212d29138c6058f5c3ba (patch)
treef0f9074559d37863a6f299af1311e9bca8ebb0a7 /src/devices/bus/sms_ctrl
parent54f43da62d75a29be676106ba99a587fd4cb5b19 (diff)
315-5124.c: Minor changes and fix a regression that in theory could affect zoomed sprites in TMS9918 modes. [Enik Land]
gamegear.c / sms.c: Improve GG-SMS scaling code a little and update the Todo list. Fixed MT#05872 regarding incorrect behavior of the Sports Pad (US model) emulation. [Enik Land]
Diffstat (limited to 'src/devices/bus/sms_ctrl')
-rw-r--r--src/devices/bus/sms_ctrl/sports.c100
-rw-r--r--src/devices/bus/sms_ctrl/sports.h7
2 files changed, 74 insertions, 33 deletions
diff --git a/src/devices/bus/sms_ctrl/sports.c b/src/devices/bus/sms_ctrl/sports.c
index f5bc15e170b..4050159beb1 100644
--- a/src/devices/bus/sms_ctrl/sports.c
+++ b/src/devices/bus/sms_ctrl/sports.c
@@ -6,6 +6,22 @@
**********************************************************************/
+// The games designed for the US model of the Sports Pad controller use the
+// TH line of the controller port as output, to select which nibble, of the
+// two axis bytes, will be read at a time. The Japanese cartridge Sports Pad
+// Soccer uses a different mode, because the Sega Mark III lacks TH output, so
+// there is a different Sports Pad model released in Japan (see sportsjp.c).
+
+// It was discovered that games designed for the Paddle Controller, released
+// in Japan, switch to a mode incompatible with the original Paddle when
+// detect the system region as Export. Similar to how the US model of the
+// Sports Pad works, that mode uses the TH line as output to select which
+// nibble of the X axis will be read. So, on an Export console version, paddle
+// games are somewhat playable with the US Sport Pad model, though it needs to
+// be used inverted and the trackball needs to be moved slowly, else the
+// software for the paddle think it's moving backward.
+// See http://mametesters.org/view.php?id=5872 for discussion.
+
#include "sports.h"
@@ -16,32 +32,33 @@
const device_type SMS_SPORTS_PAD = &device_creator<sms_sports_pad_device>;
-
+// time interval not verified
#define SPORTS_PAD_INTERVAL attotime::from_hz(XTAL_53_693175MHz/15/512)
-CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r )
+void sms_sports_pad_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- UINT8 data = 0;
-
- switch (m_read_state)
+ switch (id)
{
- case 0:
- data = m_sports_x->read() >> 4;
- break;
- case 1:
- data = m_sports_x->read();
- break;
- case 2:
- data = m_sports_y->read() >> 4;
- break;
- case 3:
- data = m_sports_y->read();
+ case TIMER_SPORTSPAD:
+ // values for x and y axis need to be resetted for Sports Pad games, but
+ // are not resetted for paddle games, so it was assumed the reset occurs
+ // only when this timer fires after the read state reached maximum value.
+ if (m_read_state == 3)
+ {
+ m_x_axis_reset_value = m_sports_x->read();
+ m_y_axis_reset_value = m_sports_y->read();
+ }
+ else
+ {
+ // set to maximum value, so it wraps to 0 at next increment
+ m_read_state = 3;
+ }
+
break;
+ default:
+ assert_always(FALSE, "Unknown id in sms_sports_pad_device::device_timer");
}
-
- // The returned value is inverted due to IP_ACTIVE_LOW mapping.
- return ~(data & 0x0f);
}
@@ -53,18 +70,34 @@ CUSTOM_INPUT_MEMBER( sms_sports_pad_device::th_pin_r )
INPUT_CHANGED_MEMBER( sms_sports_pad_device::th_pin_w )
{
- attotime cur_time = machine().time();
+ m_read_state = (m_read_state + 1) & 3;
+ m_sportspad_timer->adjust(m_interval);
+ m_last_data = newval;
+}
- if (cur_time - m_last_time > m_interval)
- {
- m_read_state = 0;
- }
- else
+
+CUSTOM_INPUT_MEMBER( sms_sports_pad_device::dir_pins_r )
+{
+ UINT8 data = 0;
+
+ switch (m_read_state)
{
- m_read_state = (m_read_state + 1) & 3;
+ case 0:
+ data = (m_sports_x->read() - m_x_axis_reset_value) >> 4;
+ break;
+ case 1:
+ data = (m_sports_x->read() - m_x_axis_reset_value);
+ break;
+ case 2:
+ data = (m_sports_y->read() - m_y_axis_reset_value) >> 4;
+ break;
+ case 3:
+ data = (m_sports_y->read() - m_y_axis_reset_value);
+ break;
}
- m_last_time = cur_time;
- m_last_data = newval;
+
+ // The returned value is inverted due to IP_ACTIVE_LOW mapping.
+ return ~(data & 0x0f);
}
@@ -84,10 +117,10 @@ static INPUT_PORTS_START( sms_sports_pad )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) // TR (Button 2)
PORT_START("SPORTS_X") /* Sports Pad X axis */
- PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_REVERSE
PORT_START("SPORTS_Y") /* Sports Pad Y axis */
- PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_RESET PORT_REVERSE
+ PORT_BIT( 0xff, 0x00, IPT_TRACKBALL_Y ) PORT_SENSITIVITY(50) PORT_KEYDELTA(40) PORT_REVERSE
INPUT_PORTS_END
@@ -119,6 +152,8 @@ sms_sports_pad_device::sms_sports_pad_device(const machine_config &mconfig, cons
m_sports_y(*this, "SPORTS_Y"),
m_read_state(0),
m_last_data(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)
{
}
@@ -130,11 +165,12 @@ sms_sports_pad_device::sms_sports_pad_device(const machine_config &mconfig, cons
void sms_sports_pad_device::device_start()
{
- m_last_time = machine().time();
+ m_sportspad_timer = timer_alloc(TIMER_SPORTSPAD);
save_item(NAME(m_read_state));
save_item(NAME(m_last_data));
- save_item(NAME(m_last_time));
+ 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 b0efde2abe8..f303b140a5b 100644
--- a/src/devices/bus/sms_ctrl/sports.h
+++ b/src/devices/bus/sms_ctrl/sports.h
@@ -53,8 +53,13 @@ private:
UINT8 m_read_state;
UINT8 m_last_data;
+ UINT8 m_x_axis_reset_value;
+ UINT8 m_y_axis_reset_value;
const attotime m_interval;
- attotime m_last_time;
+ emu_timer *m_sportspad_timer;
+ static const device_timer_id TIMER_SPORTSPAD = 0;
+
+ void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
};