From 52bfccb35c222ae1cb9e00d01c58960e1e7e7feb Mon Sep 17 00:00:00 2001 From: Wilbert Pol Date: Thu, 12 Sep 2013 18:48:15 +0000 Subject: [PATCH] (MESS) sms.c: Improved I/O handling for Japanese and Korean drivers (Pause button for sg1000m3, TH input for sg1000m3 and smsj, and output via controller ports for Japanese and Korean drivers) [Enik Land] --- src/mess/drivers/sms.c | 79 +++++++++++++++++++++------------- src/mess/includes/sms.h | 2 + src/mess/machine/sms.c | 58 +++++++++++++------------ src/mess/machine/sms_lphaser.c | 2 +- src/mess/machine/smsctrl.h | 2 + 5 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/mess/drivers/sms.c b/src/mess/drivers/sms.c index fd56b6283c0..801d790d848 100644 --- a/src/mess/drivers/sms.c +++ b/src/mess/drivers/sms.c @@ -10,9 +10,15 @@ To do: - SIO interface for Game Gear (needs netplay, I guess) - - SMS lightgun support - - LCD persistence emulation for GG - - SMS 3D glass support + - SMS Store Display Unit + - Keyboard support for Sega Mark-III (sg1000m3 driver) + - Mark-III expansion slot, used by keyboard and FM module + - Japanese Sports Pad model used by the game Sports Pad Soccer + (info: http://www.smspower.org/forums/viewtopic.php?t=11876) + - Software compatibility flags, by region and/or BIOS + - Emulate SRAM cartridges? (for use with Bock's dump tool) + - Support for other DE-9 compatible controllers, like the Mega Drive 6-Button + that has software support (at least a test tool made by Charles MacDonald) The Game Gear SIO hardware is not emulated but has some placeholders in 'machine/sms.c' @@ -291,8 +297,8 @@ static ADDRESS_MAP_START( sms_io, AS_IO, 8, sms_state ) ADDRESS_MAP_END -// I/O ports $3E and $3F do not exist o Mark-III -static ADDRESS_MAP_START( sms_no3e3f_io, AS_IO, 8, sms_state ) +// I/O ports $3E and $3F do not exist on Mark-III +static ADDRESS_MAP_START( sg1000m3_io, AS_IO, 8, sms_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x40, 0x7f) AM_READ(sms_count_r) @@ -318,11 +324,12 @@ ADDRESS_MAP_END // addresses. // At least the mirrors for I/O ports $3E/$3F don't seem to exist there. // Leaving the mirrors breaks the Korean cartridge bublboky. -static ADDRESS_MAP_START( sms_kor_io, AS_IO, 8, sms_state ) +// The version is derived from japanene SMS, that has no output on its +// controller ports, so port $3F probably does not exist, like on Mark-III. +static ADDRESS_MAP_START( sms_fm_io, AS_IO, 8, sms_state ) ADDRESS_MAP_GLOBAL_MASK(0xff) ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x3e, 0x3e) AM_WRITE(sms_bios_w) - AM_RANGE(0x3f, 0x3f) AM_WRITE(sms_io_control_w) AM_RANGE(0x40, 0x7f) AM_READ(sms_count_r) AM_RANGE(0x40, 0x7f) AM_DEVWRITE("segapsg", segapsg_device, write) AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) @@ -371,12 +378,9 @@ static INPUT_PORTS_START( sms ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME(DEF_STR(Pause)) PORT_CODE(KEYCODE_1) INPUT_PORTS_END -static INPUT_PORTS_START( sms1 ) +static INPUT_PORTS_START( sg1000m3 ) PORT_INCLUDE( sms ) - PORT_START("RESET") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Reset Button") - PORT_START("SEGASCOPE") PORT_CONFNAME( 0x01, 0x00, "SegaScope (3-D Glasses)" ) PORT_CONFSETTING( 0x00, DEF_STR( Off ) ) @@ -391,6 +395,13 @@ static INPUT_PORTS_START( sms1 ) PORT_BIT( 0x03, 0x00, IPT_UNUSED ) PORT_CONDITION("SEGASCOPE", 0x01, EQUALS, 0x00) INPUT_PORTS_END +static INPUT_PORTS_START( sms1 ) + PORT_INCLUDE( sg1000m3 ) + + PORT_START("RESET") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_NAME("Reset Button") +INPUT_PORTS_END + static INPUT_PORTS_START( gg ) PORT_START("GG_PORT_DC") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_8WAY @@ -561,11 +572,11 @@ static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base ) MCFG_DEFAULT_LAYOUT(layout_sms1) - MCFG_PALETTE_LENGTH(SEGA315_5124_PALETTE_SIZE) - MCFG_VIDEO_START_OVERRIDE(sms_state,sms1) MCFG_VIDEO_RESET_OVERRIDE(sms_state,sms1) + MCFG_PALETTE_LENGTH(SEGA315_5124_PALETTE_SIZE) + MCFG_SEGA315_5124_ADD("sms_vdp", _315_5124_ntsc_intf) MCFG_SEGA315_5124_SET_SCREEN("screen") @@ -727,11 +738,11 @@ static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base ) MCFG_DEFAULT_LAYOUT(layout_sms1) - MCFG_PALETTE_LENGTH(SEGA315_5124_PALETTE_SIZE) - MCFG_VIDEO_START_OVERRIDE(sms_state,sms1) MCFG_VIDEO_RESET_OVERRIDE(sms_state,sms1) + MCFG_PALETTE_LENGTH(SEGA315_5124_PALETTE_SIZE) + MCFG_SEGA315_5124_ADD("sms_vdp", _315_5124_pal_intf) MCFG_SEGA315_5124_SET_SCREEN("screen") @@ -741,6 +752,14 @@ static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base ) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( sms_fm, sms1_ntsc ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_IO_MAP(sms_fm_io) + + // Japanese sms and sg1000m3 consoles do not have TH input + MCFG_SMS_CONTROL_PORT_MODIFY(CONTROL1_TAG) + MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(NULL) + MCFG_SMS_CONTROL_PORT_MODIFY(CONTROL2_TAG) + MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(NULL) MCFG_SOUND_ADD("ym2413", YM2413, XTAL_53_693175MHz/15) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) @@ -748,7 +767,7 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( sg1000m3, sms_fm ) MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_IO_MAP(sms_no3e3f_io) + MCFG_CPU_IO_MAP(sg1000m3_io) MCFG_DEVICE_REMOVE("slot") MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sg1000mk3_cart, NULL) @@ -756,7 +775,7 @@ MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( sms2_fm, sms2_ntsc ) MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_IO_MAP(sms_kor_io) + MCFG_CPU_IO_MAP(sms_fm_io) MCFG_SOUND_ADD("ym2413", YM2413, XTAL_53_693175MHz/15) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) @@ -780,10 +799,10 @@ static MACHINE_CONFIG_START( gamegear, sms_state ) SEGA315_5124_HEIGHT_NTSC, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_192_TBORDER_HEIGHT + 3*8, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_192_TBORDER_HEIGHT + 21*8 ) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_gamegear) - MCFG_PALETTE_LENGTH(SEGA315_5378_PALETTE_SIZE) - MCFG_VIDEO_START_OVERRIDE(sms_state,gamegear) + MCFG_PALETTE_LENGTH(SEGA315_5378_PALETTE_SIZE) + MCFG_SEGA315_5378_ADD("sms_vdp", _315_5124_ntsc_intf) MCFG_SEGA315_5378_SET_SCREEN("screen") @@ -947,15 +966,15 @@ ROM_END ***************************************************************************/ -/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ -CONS( 1984, sg1000m3, sms, 0, sg1000m3, sms1, sms_state, sg1000m3, "Sega", "SG-1000 Mark III", GAME_SUPPORTS_SAVE ) -CONS( 1986, sms1, sms, 0, sms1_ntsc, sms1, sms_state, sms1, "Sega", "Master System I", GAME_SUPPORTS_SAVE ) -CONS( 1986, sms1pal, sms, 0, sms1_pal, sms1, sms_state, sms1, "Sega", "Master System I (PAL)" , GAME_SUPPORTS_SAVE ) -CONS( 1986, smssdisp, sms, 0, sms_sdisp, sms, smssdisp_state, smssdisp, "Sega", "Master System Store Display Unit", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) -CONS( 1987, smsj, sms, 0, sms_fm, sms1, sms_state, smsj, "Sega", "Master System (Japan)", GAME_SUPPORTS_SAVE ) -CONS( 1990, sms, 0, 0, sms2_ntsc, sms, sms_state, sms1, "Sega", "Master System II", GAME_SUPPORTS_SAVE ) -CONS( 1990, smspal, sms, 0, sms2_pal, sms, sms_state, sms1, "Sega", "Master System II (PAL)", GAME_SUPPORTS_SAVE ) -CONS( 1990, sms2kr, sms, 0, sms2_fm, sms, sms_state, sms2kr, "Samsung", "Gam*Boy II (Korea)", GAME_SUPPORTS_SAVE ) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +CONS( 1984, sg1000m3, sms, 0, sg1000m3, sg1000m3, sms_state, sg1000m3, "Sega", "SG-1000 Mark III", GAME_SUPPORTS_SAVE ) +CONS( 1986, sms1, sms, 0, sms1_ntsc, sms1, sms_state, sms1, "Sega", "Master System I", GAME_SUPPORTS_SAVE ) +CONS( 1986, sms1pal, sms, 0, sms1_pal, sms1, sms_state, sms1, "Sega", "Master System I (PAL)" , GAME_SUPPORTS_SAVE ) +CONS( 1986, smssdisp, sms, 0, sms_sdisp, sms, smssdisp_state, smssdisp, "Sega", "Master System Store Display Unit", GAME_NOT_WORKING | GAME_SUPPORTS_SAVE ) +CONS( 1987, smsj, sms, 0, sms_fm, sms1, sms_state, smsj, "Sega", "Master System (Japan)", GAME_SUPPORTS_SAVE ) +CONS( 1990, sms, 0, 0, sms2_ntsc, sms, sms_state, sms1, "Sega", "Master System II", GAME_SUPPORTS_SAVE ) +CONS( 1990, smspal, sms, 0, sms2_pal, sms, sms_state, sms1, "Sega", "Master System II (PAL)", GAME_SUPPORTS_SAVE ) +CONS( 1990, sms2kr, sms, 0, sms2_fm, sms, sms_state, sms2kr, "Samsung", "Gam*Boy II (Korea)", GAME_SUPPORTS_SAVE ) -CONS( 1990, gamegear, 0, sms, gamegear, gg, sms_state, gamegear, "Sega", "Game Gear (Europe/America)", GAME_SUPPORTS_SAVE ) -CONS( 1990, gamegeaj, gamegear, 0, gamegear, gg, sms_state, gamegeaj, "Sega", "Game Gear (Japan)", GAME_SUPPORTS_SAVE ) +CONS( 1990, gamegear, 0, sms, gamegear, gg, sms_state, gamegear, "Sega", "Game Gear (Europe/America)", GAME_SUPPORTS_SAVE ) +CONS( 1990, gamegeaj, gamegear, 0, gamegear, gg, sms_state, gamegeaj, "Sega", "Game Gear (Japan)", GAME_SUPPORTS_SAVE ) diff --git a/src/mess/includes/sms.h b/src/mess/includes/sms.h index 93f5000e830..0318b6cdedc 100644 --- a/src/mess/includes/sms.h +++ b/src/mess/includes/sms.h @@ -48,6 +48,7 @@ public: m_port_persist(*this, "PERSISTENCE"), m_is_gamegear(0), m_is_region_japan(0), + m_is_korean(0), m_is_sdisp(0), m_has_bios_0400(0), m_has_bios_2000(0), @@ -102,6 +103,7 @@ public: // model identifiers UINT8 m_is_gamegear; UINT8 m_is_region_japan; + UINT8 m_is_korean; UINT8 m_is_sdisp; UINT8 m_has_bios_0400; UINT8 m_has_bios_2000; diff --git a/src/mess/machine/sms.c b/src/mess/machine/sms.c index d07ed2039ad..c715e43b762 100644 --- a/src/mess/machine/sms.c +++ b/src/mess/machine/sms.c @@ -25,7 +25,7 @@ void sms_state::lphaser_hcount_latch() WRITE_LINE_MEMBER(sms_state::sms_ctrl1_th_input) { // Check if TH of controller port 1 is set to input (1) - if (m_io_ctrl_reg & 0x02) + if (m_is_korean || (m_io_ctrl_reg & 0x02)) { if (state == 0) { @@ -45,7 +45,7 @@ WRITE_LINE_MEMBER(sms_state::sms_ctrl1_th_input) WRITE_LINE_MEMBER(sms_state::sms_ctrl2_th_input) { // Check if TH of controller port 2 is set to input (1) - if (m_io_ctrl_reg & 0x08) + if (m_is_korean || (m_io_ctrl_reg & 0x08)) { if (state == 0) { @@ -64,23 +64,28 @@ WRITE_LINE_MEMBER(sms_state::sms_ctrl2_th_input) void sms_state::sms_get_inputs( address_space &space ) { - UINT8 data; + UINT8 data1, data2; m_port_dc_reg = 0xff; m_port_dd_reg = 0xff; - data = m_port_ctrl1->port_r(); - m_port_dc_reg &= ~0x0F | data; // Up, Down, Left, Right - m_port_dc_reg &= ~0x10 | (data >> 1); // TL (Button 1) - m_port_dc_reg &= ~0x20 | (data >> 2); // TR (Button 2) - m_port_dd_reg &= ~0x40 | data; // TH + data1 = m_port_ctrl1->port_r(); + m_port_dc_reg &= ~0x0f | data1; // Up, Down, Left, Right + m_port_dc_reg &= ~0x10 | (data1 >> 1); // TL (Button 1) + m_port_dc_reg &= ~0x20 | (data1 >> 2); // TR (Button 2) - data = m_port_ctrl2->port_r(); - m_port_dc_reg &= ~0xc0 | (data << 6); // Up, Down - m_port_dd_reg &= ~0x03 | (data >> 2); // Left, Right - m_port_dd_reg &= ~0x04 | (data >> 3); // TL (Button 1) - m_port_dd_reg &= ~0x08 | (data >> 4); // TR (Button 2) - m_port_dd_reg &= ~0x80 | (data << 1); // TH + data2 = m_port_ctrl2->port_r(); + m_port_dc_reg &= ~0xc0 | (data2 << 6); // Up, Down + m_port_dd_reg &= ~0x03 | (data2 >> 2); // Left, Right + m_port_dd_reg &= ~0x04 | (data2 >> 3); // TL (Button 1) + m_port_dd_reg &= ~0x08 | (data2 >> 4); // TR (Button 2) + + // Japanese consoles do not have TH line connected. + if (!m_is_region_japan || m_is_korean) + { + m_port_dd_reg &= ~0x40 | data1; // TH ctrl1 + m_port_dd_reg &= ~0x80 | (data2 << 1); // TH ctrl2 + } } @@ -225,10 +230,10 @@ READ8_MEMBER(sms_state::sms_input_port_dc_r) sms_get_inputs(space); // Check if TR of controller port 1 is set to output (0) - if (!(m_io_ctrl_reg & 0x01)) + if (!m_is_region_japan && !(m_io_ctrl_reg & 0x01)) { // Read TR state set through IO control port - m_port_dc_reg &= ~0x20 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x10) << 1); + m_port_dc_reg &= ~0x20 | ((m_io_ctrl_reg & 0x10) << 1); } return m_port_dc_reg; @@ -248,23 +253,19 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r) { m_port_dd_reg &= ~0x10 | (m_port_reset->read() & 0x01) << 4; } - else - { - m_port_dd_reg |= 0x10; - } // Check if TR of controller port 2 is set to output (0) - if (!(m_io_ctrl_reg & 0x04)) + if (!m_is_region_japan && !(m_io_ctrl_reg & 0x04)) { // Read TR state set through IO control port - m_port_dd_reg &= ~0x08 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x40) >> 3); + m_port_dd_reg &= ~0x08 | ((m_io_ctrl_reg & 0x40) >> 3); } // Check if TH of controller port 1 is set to output (0) - if (!(m_io_ctrl_reg & 0x02)) + if (!m_is_region_japan && !(m_io_ctrl_reg & 0x02)) { // Read TH state set through IO control port - m_port_dd_reg &= ~0x40 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x20) << 1); + m_port_dd_reg &= ~0x40 | ((m_io_ctrl_reg & 0x20) << 1); } else // TH set to input (1) { @@ -276,10 +277,10 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r) } // Check if TH of controller port 2 is set to output (0) - if (!(m_io_ctrl_reg & 0x08)) + if (!m_is_region_japan && !(m_io_ctrl_reg & 0x08)) { // Read TH state set through IO control port - m_port_dd_reg &= ~0x80 | (m_is_region_japan ? 0x00 : (m_io_ctrl_reg & 0x80)); + m_port_dd_reg &= ~0x80 | (m_io_ctrl_reg & 0x80); } else // TH set to input (1) { @@ -628,7 +629,7 @@ WRITE8_MEMBER(sms_state::gg_sio_w) case 0x00: /* Parallel Data */ break; - case 0x01: /* Data Direction/ NMI Enable */ + case 0x01: /* Data Direction / NMI Enable */ break; case 0x02: /* Serial Output */ @@ -652,7 +653,7 @@ READ8_MEMBER(sms_state::gg_sio_r) case 0x00: /* Parallel Data */ break; - case 0x01: /* Data Direction/ NMI Enable */ + case 0x01: /* Data Direction / NMI Enable */ break; case 0x02: /* Serial Output */ @@ -973,6 +974,7 @@ DRIVER_INIT_MEMBER(sms_state,sms2kr) m_is_region_japan = 1; m_has_bios_full = 1; m_has_fm = 1; + m_is_korean = 1; } diff --git a/src/mess/machine/sms_lphaser.c b/src/mess/machine/sms_lphaser.c index 3f28c3c8c4f..abd0674a290 100644 --- a/src/mess/machine/sms_lphaser.c +++ b/src/mess/machine/sms_lphaser.c @@ -78,7 +78,7 @@ sms_light_phaser_device::sms_light_phaser_device(const machine_config &mconfig, m_lphaser_y(*this, "LPHASER_Y") { // Workaround for failed validation that occurs when running on a driver - // with Sega Scope emulation, which adds 2 screens for left/right lens. + // with Sega Scope emulation, which adds 2 screens (left/right lenses). m_screen_tag = ":screen"; } diff --git a/src/mess/machine/smsctrl.h b/src/mess/machine/smsctrl.h index 9962782d895..bcb0b683683 100644 --- a/src/mess/machine/smsctrl.h +++ b/src/mess/machine/smsctrl.h @@ -26,6 +26,8 @@ #define MCFG_SMS_CONTROL_PORT_ADD(_tag, _slot_intf, _def_slot) \ MCFG_DEVICE_ADD(_tag, SMS_CONTROL_PORT, 0) \ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) +#define MCFG_SMS_CONTROL_PORT_MODIFY(_tag) \ + MCFG_DEVICE_MODIFY(_tag) #define MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(_devcb) \