diff options
author | 2015-09-14 17:54:24 -0400 | |
---|---|---|
committer | 2015-09-14 17:54:24 -0400 | |
commit | 249d8f752cd1e4fe12e7212d29138c6058f5c3ba (patch) | |
tree | f0f9074559d37863a6f299af1311e9bca8ebb0a7 /src/devices/bus/sms_ctrl | |
parent | 54f43da62d75a29be676106ba99a587fd4cb5b19 (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.c | 100 | ||||
-rw-r--r-- | src/devices/bus/sms_ctrl/sports.h | 7 |
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); }; |