diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 571c75fd48b..5fdd355a955 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2074,6 +2074,22 @@ if (BUSES["SEGA8"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/bus/sg1000_exp/sg1000exp.h,BUSES["SG1000_EXP"] = true +--------------------------------------------------- + +if (BUSES["SG1000_EXP"]~=null) then + files { + MAME_DIR .. "src/devices/bus/sg1000_exp/sg1000exp.cpp", + MAME_DIR .. "src/devices/bus/sg1000_exp/sg1000exp.h", + MAME_DIR .. "src/devices/bus/sg1000_exp/sk1100.cpp", + MAME_DIR .. "src/devices/bus/sg1000_exp/sk1100.h", + MAME_DIR .. "src/devices/bus/sg1000_exp/fm_unit.cpp", + MAME_DIR .. "src/devices/bus/sg1000_exp/fm_unit.h", + } +end + --------------------------------------------------- -- --@src/devices/bus/sms_ctrl/smsctrl.h,BUSES["SMS_CTRL"] = true diff --git a/scripts/target/mame/arcade.lua b/scripts/target/mame/arcade.lua index 2119d2b30f7..470a33a13ad 100644 --- a/scripts/target/mame/arcade.lua +++ b/scripts/target/mame/arcade.lua @@ -642,6 +642,7 @@ BUSES["SAT_CTRL"] = true BUSES["SCSI"] = true --BUSES["SCV"] = true BUSES["SEGA8"] = true +BUSES["SG1000_EXP"] = true BUSES["SMS_CTRL"] = true BUSES["SMS_EXP"] = true --BUSES["SNES"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 76b52c9f669..1063bd71a93 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -666,6 +666,7 @@ BUSES["SATURN"] = true BUSES["SCSI"] = true BUSES["SCV"] = true BUSES["SEGA8"] = true +BUSES["SG1000_EXP"] = true BUSES["SMS_CTRL"] = true BUSES["SMS_EXP"] = true BUSES["SNES"] = true diff --git a/src/devices/bus/gamegear/smsctrladp.cpp b/src/devices/bus/gamegear/smsctrladp.cpp index 54b9139b433..2aec892b279 100644 --- a/src/devices/bus/gamegear/smsctrladp.cpp +++ b/src/devices/bus/gamegear/smsctrladp.cpp @@ -45,7 +45,7 @@ void sms_ctrl_adaptor_device::device_start() //------------------------------------------------- -// sms_peripheral_r - rapid fire read +// sms_peripheral_r - sms_ctrl_adaptor read //------------------------------------------------- UINT8 sms_ctrl_adaptor_device::peripheral_r() @@ -55,7 +55,7 @@ UINT8 sms_ctrl_adaptor_device::peripheral_r() //------------------------------------------------- -// sms_peripheral_w - rapid fire write +// sms_peripheral_w - sms_ctrl_adaptor write //------------------------------------------------- void sms_ctrl_adaptor_device::peripheral_w(UINT8 data) diff --git a/src/devices/bus/sega8/sega8_slot.h b/src/devices/bus/sega8/sega8_slot.h index 439bc3be7a2..7e00a20bb27 100644 --- a/src/devices/bus/sega8/sega8_slot.h +++ b/src/devices/bus/sega8/sega8_slot.h @@ -199,7 +199,7 @@ public: MCFG_DEVICE_ADD(_tag, SEGA8_CART_SLOT, 0) \ MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \ static_cast(device)->set_mandatory(FALSE); \ - static_cast(device)->set_intf("sms_cart"); \ + static_cast(device)->set_intf("sms_cart,sg1000_cart"); \ static_cast(device)->set_ext("bin,sms,sg"); #define MCFG_SMS_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \ diff --git a/src/devices/bus/sg1000_exp/fm_unit.cpp b/src/devices/bus/sg1000_exp/fm_unit.cpp new file mode 100644 index 00000000000..935346e17de --- /dev/null +++ b/src/devices/bus/sg1000_exp/fm_unit.cpp @@ -0,0 +1,119 @@ +// license:BSD-3-Clause +// copyright-holders:Enik Land +/********************************************************************** + + Sega FM Sound Unit emulation + + +Release data from the Sega Retro project: + + Year: 1987 Country/region: JP Model code: FM-70 + +**********************************************************************/ + +#include "fm_unit.h" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SEGA_FM_UNIT = &device_creator; + + +static MACHINE_CONFIG_FRAGMENT( fm_config ) + MCFG_SOUND_ADD("ym2413", YM2413, XTAL_10_738635MHz/3) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, ":mono", 1.00) +MACHINE_CONFIG_END + + +machine_config_constructor sega_fm_unit_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( fm_config ); +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sega_fm_unit_device - constructor +//------------------------------------------------- + +sega_fm_unit_device::sega_fm_unit_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SEGA_FM_UNIT, "Sega FM Sound Unit", tag, owner, clock, "sega_fm_unit", __FILE__), + device_sg1000_expansion_slot_interface(mconfig, *this), + m_ym(*this, "ym2413"), + m_audio_control(0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sega_fm_unit_device::device_start() +{ + /* register for state saving */ + save_item(NAME(m_audio_control)); +} + + +//------------------------------------------------- +// peripheral_r - fm unit read +//------------------------------------------------- + +READ8_MEMBER(sega_fm_unit_device::peripheral_r) +{ + if (offset == 2) + { + return m_audio_control & 0x01; + } + // will not be called for other offsets. + return 0xff; +} + +//------------------------------------------------- +// peripheral_w - fm unit write +//------------------------------------------------- + +WRITE8_MEMBER(sega_fm_unit_device::peripheral_w) +{ + switch (offset) + { + case 0: // register port + if (m_audio_control == 0x01) + { + m_ym->write(space, 0, data & 0x3f); + } + break; + case 1: // data port + if (m_audio_control == 0x01) + { + m_ym->write(space, 1, data); + } + break; + case 2: // control port + m_audio_control = data & 0x01; + break; + default: + break; + } +} + + +bool sega_fm_unit_device::is_readable(UINT8 offset) +{ + return (offset == 2) ? true : false; +} + + +bool sega_fm_unit_device::is_writeable(UINT8 offset) +{ + return (offset <= 2) ? true : false; +} + diff --git a/src/devices/bus/sg1000_exp/fm_unit.h b/src/devices/bus/sg1000_exp/fm_unit.h new file mode 100644 index 00000000000..5b45b14d831 --- /dev/null +++ b/src/devices/bus/sg1000_exp/fm_unit.h @@ -0,0 +1,55 @@ +// license:BSD-3-Clause +// copyright-holders:Enik Land +/********************************************************************** + + Sega FM Sound Unit emulation + +**********************************************************************/ + +#pragma once + +#ifndef __SEGA_FM_UNIT__ +#define __SEGA_FM_UNIT__ + + +#include "emu.h" +#include "sound/2413intf.h" +#include "sg1000exp.h" + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sega_fm_unit_device + +class sega_fm_unit_device : public device_t, + public device_sg1000_expansion_slot_interface +{ +public: + // construction/destruction + sega_fm_unit_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + +protected: + // device-level overrides + virtual void device_start() override; + virtual machine_config_constructor device_mconfig_additions() const override; + + // device_sg1000_expansion_slot_interface overrides + virtual DECLARE_READ8_MEMBER(peripheral_r) override; + virtual DECLARE_WRITE8_MEMBER(peripheral_w) override; + virtual bool is_readable(UINT8 offset) override; + virtual bool is_writeable(UINT8 offset) override; + +private: + required_device m_ym; + UINT8 m_audio_control; +}; + + +// device type definition +extern const device_type SEGA_FM_UNIT; + + +#endif diff --git a/src/devices/bus/sg1000_exp/sg1000exp.cpp b/src/devices/bus/sg1000_exp/sg1000exp.cpp new file mode 100644 index 00000000000..0460efccbef --- /dev/null +++ b/src/devices/bus/sg1000_exp/sg1000exp.cpp @@ -0,0 +1,124 @@ +// license:BSD-3-Clause +// copyright-holders:Enik Land +/********************************************************************** + + Sega SG-1000 expansion slot emulation + +**********************************************************************/ + +#include "sg1000exp.h" +// slot devices +#include "sk1100.h" +#include "fm_unit.h" + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +const device_type SG1000_EXPANSION_SLOT = &device_creator; + + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_sg1000_expansion_slot_interface - constructor +//------------------------------------------------- + +device_sg1000_expansion_slot_interface::device_sg1000_expansion_slot_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig,device) +{ +} + + +//------------------------------------------------- +// ~device_sg1000_expansion_slot_interface - destructor +//------------------------------------------------- + +device_sg1000_expansion_slot_interface::~device_sg1000_expansion_slot_interface() +{ +} + + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sg1000_expansion_slot_device - constructor +//------------------------------------------------- + +sg1000_expansion_slot_device::sg1000_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SG1000_EXPANSION_SLOT, "Sega SG-1000 expansion slot", tag, owner, clock, "sg1000_expansion_slot", __FILE__), + device_slot_interface(mconfig, *this), m_device(nullptr) +{ +} + + +//------------------------------------------------- +// sg1000_expansion_slot_device - destructor +//------------------------------------------------- + +sg1000_expansion_slot_device::~sg1000_expansion_slot_device() +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sg1000_expansion_slot_device::device_start() +{ + m_device = dynamic_cast(get_card_device()); +} + + +// Address offsets are masked with 0x07 because the SG-1000 expansion slot +// has only 3 address lines (A0, A1, A2). + + +READ8_MEMBER(sg1000_expansion_slot_device::read) +{ + UINT8 data = 0xff; + if (m_device) + data = m_device->peripheral_r(space, offset & 0x07); + return data; +} + +WRITE8_MEMBER(sg1000_expansion_slot_device::write) +{ + if (m_device) + m_device->peripheral_w(space, offset & 0x07, data); +} + + +bool sg1000_expansion_slot_device::is_readable(UINT8 offset) +{ + if (m_device) + return m_device->is_readable(offset & 0x07); + return false; +} + + +bool sg1000_expansion_slot_device::is_writeable(UINT8 offset) +{ + if (m_device) + return m_device->is_writeable(offset & 0x07); + return false; +} + + +//------------------------------------------------- +// SLOT_INTERFACE( sg1000_expansion_devices ) +//------------------------------------------------- + +SLOT_INTERFACE_START( sg1000_expansion_devices ) + SLOT_INTERFACE("sk1100", SEGA_SK1100) + SLOT_INTERFACE("fm", SEGA_FM_UNIT) +SLOT_INTERFACE_END diff --git a/src/devices/bus/sg1000_exp/sg1000exp.h b/src/devices/bus/sg1000_exp/sg1000exp.h new file mode 100644 index 00000000000..183ee9ea948 --- /dev/null +++ b/src/devices/bus/sg1000_exp/sg1000exp.h @@ -0,0 +1,91 @@ +// license:BSD-3-Clause +// copyright-holders:Enik Land +/********************************************************************** + + Sega SG-1000 expansion slot emulation + +********************************************************************** + + +**********************************************************************/ + +#pragma once + +#ifndef __SG1000_EXPANSION_SLOT__ +#define __SG1000_EXPANSION_SLOT__ + +#include "emu.h" + + + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_SG1000_EXPANSION_ADD(_tag, _slot_intf, _def_slot, _fixed) \ + MCFG_DEVICE_ADD(_tag, SG1000_EXPANSION_SLOT, 0) \ + MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, _fixed) +#define MCFG_SG1000_EXPANSION_MODIFY(_tag) \ + MCFG_DEVICE_MODIFY(_tag) + + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sg1000_expansion_slot_device + +class device_sg1000_expansion_slot_interface; + +class sg1000_expansion_slot_device : public device_t, + public device_slot_interface +{ +public: + // construction/destruction + sg1000_expansion_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + virtual ~sg1000_expansion_slot_device(); + + DECLARE_READ8_MEMBER(read); + DECLARE_WRITE8_MEMBER(write); + bool is_readable(UINT8 offset); + bool is_writeable(UINT8 offset); + +protected: + // device-level overrides + virtual void device_start() override; + +private: + device_sg1000_expansion_slot_interface *m_device; +}; + + +// ======================> device_sg1000_expansion_slot_interface + +// class representing interface-specific live sg1000_expansion card +class device_sg1000_expansion_slot_interface : public device_slot_card_interface +{ +public: + // construction/destruction + device_sg1000_expansion_slot_interface(const machine_config &mconfig, device_t &device); + virtual ~device_sg1000_expansion_slot_interface(); + + virtual DECLARE_READ8_MEMBER(peripheral_r) { return 0xff; }; + virtual DECLARE_WRITE8_MEMBER(peripheral_w) { }; + + virtual bool is_readable(UINT8 offset) { return true; }; + virtual bool is_writeable(UINT8 offset) { return true; }; + +protected: + sg1000_expansion_slot_device *m_port; +}; + + +// device type definition +extern const device_type SG1000_EXPANSION_SLOT; + + +SLOT_INTERFACE_EXTERN( sg1000_expansion_devices ); + + +#endif diff --git a/src/devices/bus/sg1000_exp/sk1100.cpp b/src/devices/bus/sg1000_exp/sk1100.cpp new file mode 100644 index 00000000000..3c5726f96dc --- /dev/null +++ b/src/devices/bus/sg1000_exp/sk1100.cpp @@ -0,0 +1,337 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Sega SK-1100 keyboard emulation + + +Release data from the Sega Retro project: + + Year: 1984 Country/region: JP Model code: SK-1100 + + +TODO: +- SP-400 serial printer +- Link between two Mark III's through keyboard, supported by F-16 Fighting Falcon + + +**********************************************************************/ + +#include "sk1100.h" +#include "softlist.h" + + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +const device_type SEGA_SK1100 = &device_creator; + + +/*------------------------------------------------- + INPUT_PORTS( sk1100_keys ) +-------------------------------------------------*/ + +static INPUT_PORTS_START( sk1100_keys ) + PORT_START("PA0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ENG DIER'S") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') + + PORT_START("PA1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPC") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') + + PORT_START("PA2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HOME CLR") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') + + PORT_START("PA3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_SMALL_PI) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(0x03c0) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CHAR('`') + + PORT_START("PA4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CHAR('}') + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CHAR('{') + + PORT_START("PA5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CR") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PA6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PB0") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PB1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PB2") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PB3") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PB4") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('^') + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("PB5") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xc2\xa5") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(0x00a5) + PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("FUNC") PORT_CODE(KEYCODE_TAB) + + PORT_START("PB6") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GRAPH") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) +INPUT_PORTS_END + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor sega_sk1100_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( sk1100_keys ); +} + + +static MACHINE_CONFIG_FRAGMENT( sk1100_config ) + /* devices */ + MCFG_DEVICE_ADD(UPD9255_0_TAG, I8255, 0) + MCFG_I8255_IN_PORTA_CB(READ8(sega_sk1100_device, ppi_pa_r)) + MCFG_I8255_IN_PORTB_CB(READ8(sega_sk1100_device, ppi_pb_r)) + MCFG_I8255_OUT_PORTC_CB(WRITE8(sega_sk1100_device, ppi_pc_w)) + +// MCFG_PRINTER_ADD("sp400") /* serial printer */ + + MCFG_CASSETTE_ADD("cassette") + MCFG_CASSETTE_FORMATS(sc3000_cassette_formats) + MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) + MCFG_CASSETTE_INTERFACE("sc3000_cass") + + /* software lists */ + MCFG_SOFTWARE_LIST_ADD("sc3k_cart_list","sc3000_cart") + MCFG_SOFTWARE_LIST_ADD("cass_list","sc3000_cass") +MACHINE_CONFIG_END + + +machine_config_constructor sega_sk1100_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( sk1100_config ); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// sega_sk1100_device - constructor +//------------------------------------------------- + +sega_sk1100_device::sega_sk1100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) : + device_t(mconfig, SEGA_SK1100, "Sega SK-1100 Keyboard", tag, owner, clock, "sega_sk1100", __FILE__), + device_sg1000_expansion_slot_interface(mconfig, *this), + m_cassette(*this, "cassette"), + m_ppi(*this, UPD9255_0_TAG), + m_pa0(*this, "PA0"), + m_pa1(*this, "PA1"), + m_pa2(*this, "PA2"), + m_pa3(*this, "PA3"), + m_pa4(*this, "PA4"), + m_pa5(*this, "PA5"), + m_pa6(*this, "PA6"), + m_pb0(*this, "PB0"), + m_pb1(*this, "PB1"), + m_pb2(*this, "PB2"), + m_pb3(*this, "PB3"), + m_pb4(*this, "PB4"), + m_pb5(*this, "PB5"), + m_pb6(*this, "PB6"), + m_keylatch(0) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void sega_sk1100_device::device_start() +{ + // find keyboard rows + m_key_row[0] = m_pa0; + m_key_row[1] = m_pa1; + m_key_row[2] = m_pa2; + m_key_row[3] = m_pa3; + m_key_row[4] = m_pa4; + m_key_row[5] = m_pa5; + m_key_row[6] = m_pa6; + m_key_row[7] = nullptr; // keyboard disabled + m_key_row[8] = m_pb0; + m_key_row[9] = m_pb1; + m_key_row[10] = m_pb2; + m_key_row[11] = m_pb3; + m_key_row[12] = m_pb4; + m_key_row[13] = m_pb5; + m_key_row[14] = m_pb6; + m_key_row[15] = nullptr; // keyboard disabled + + /* register for state saving */ + save_item(NAME(m_keylatch)); +} + + +//------------------------------------------------- +// peripheral_r - keyboard read +//------------------------------------------------- + +READ8_MEMBER(sega_sk1100_device::peripheral_r) +{ + return m_ppi->read(space, offset & 0x03); +} + + +//------------------------------------------------- +// peripheral_w - keyboard write +//------------------------------------------------- + +WRITE8_MEMBER(sega_sk1100_device::peripheral_w) +{ + m_ppi->write(space, offset & 0x03, data); +} + + +bool sega_sk1100_device::is_readable(UINT8 offset) +{ + return (m_keylatch != 0x07 ? true : false); +} + + +/*------------------------------------------------- + I8255 INTERFACE +-------------------------------------------------*/ + +READ8_MEMBER( sega_sk1100_device::ppi_pa_r ) +{ + /* + Signal Description + + PA0 Keyboard input + PA1 Keyboard input + PA2 Keyboard input + PA3 Keyboard input + PA4 Keyboard input + PA5 Keyboard input + PA6 Keyboard input + PA7 Keyboard input + */ + + return m_key_row[m_keylatch]->read(); +} + +READ8_MEMBER( sega_sk1100_device::ppi_pb_r ) +{ + /* + Signal Description + + PB0 Keyboard input + PB1 Keyboard input + PB2 Keyboard input + PB3 Keyboard input + PB4 /CONT input from cartridge terminal B-11 + PB5 FAULT input from printer + PB6 BUSY input from printer + PB7 Cassette tape input + */ + + /* keyboard */ + UINT8 data = m_key_row[m_keylatch + 8]->read(); + + /* cartridge contact */ + data |= 0x10; + + /* printer */ + data |= 0x60; + + /* tape input */ + if (m_cassette->input() > +0.0) data |= 0x80; + + return data; +} + +WRITE8_MEMBER( sega_sk1100_device::ppi_pc_w ) +{ + /* + Signal Description + + PC0 Keyboard raster output + PC1 Keyboard raster output + PC2 Keyboard raster output + PC3 not connected + PC4 Cassette tape output + PC5 DATA to printer + PC6 /RESET to printer + PC7 /FEED to printer + */ + + /* keyboard */ + m_keylatch = data & 0x07; + + /* cassette */ + m_cassette->output( BIT(data, 4) ? +1.0 : -1.0); + + /* TODO printer */ +} + diff --git a/src/devices/bus/sg1000_exp/sk1100.h b/src/devices/bus/sg1000_exp/sk1100.h new file mode 100644 index 00000000000..80cabb3f30d --- /dev/null +++ b/src/devices/bus/sg1000_exp/sk1100.h @@ -0,0 +1,84 @@ +// license:BSD-3-Clause +// copyright-holders:Curt Coder +/********************************************************************** + + Sega SK-1100 keyboard emulation + +**********************************************************************/ + +#pragma once + +#ifndef __SEGA_SK1100__ +#define __SEGA_SK1100__ + + +#include "emu.h" +#include "sg1000exp.h" +#include "formats/sc3000_bit.h" +#include "imagedev/cassette.h" +#include "imagedev/printer.h" +#include "machine/i8255.h" + + +#define UPD9255_0_TAG "upd9255_0" // "upd9255_1" is being used by the SF-7000 driver + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> sega_sk1100_device + +class sega_sk1100_device : public device_t, + public device_sg1000_expansion_slot_interface +{ +public: + // construction/destruction + sega_sk1100_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock); + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + + DECLARE_READ8_MEMBER( ppi_pa_r ); + DECLARE_READ8_MEMBER( ppi_pb_r ); + DECLARE_WRITE8_MEMBER( ppi_pc_w ); + +protected: + // device-level overrides + virtual void device_start() override; + virtual machine_config_constructor device_mconfig_additions() const override; + + // device_sg1000_expansion_slot_interface overrides + virtual DECLARE_READ8_MEMBER(peripheral_r) override; + virtual DECLARE_WRITE8_MEMBER(peripheral_w) override; + virtual bool is_readable(UINT8 offset) override; + +private: + ioport_port* m_key_row[16]; + required_device m_cassette; + required_device m_ppi; + required_ioport m_pa0; + required_ioport m_pa1; + required_ioport m_pa2; + required_ioport m_pa3; + required_ioport m_pa4; + required_ioport m_pa5; + required_ioport m_pa6; + required_ioport m_pb0; + required_ioport m_pb1; + required_ioport m_pb2; + required_ioport m_pb3; + required_ioport m_pb4; + required_ioport m_pb5; + required_ioport m_pb6; + + /* keyboard state */ + UINT8 m_keylatch; +}; + + +// device type definition +extern const device_type SEGA_SK1100; + + +#endif diff --git a/src/devices/video/315_5124.cpp b/src/devices/video/315_5124.cpp index 399f48e9b26..09e5e6cf1d6 100644 --- a/src/devices/video/315_5124.cpp +++ b/src/devices/video/315_5124.cpp @@ -45,7 +45,7 @@ A scanline contains the following sections: NTSC frame timing 256x192 256x224 256x240 (doesn't work on real hardware) - - vertical blanking 3 D5-D7 3 E5-E7 3 ED-EF + - vertical sync 3 D5-D7 3 E5-E7 3 ED-EF - top blanking 13 D8-E4 13 E8-F4 13 F0-FC - top border 27 E5-FF 11 F5-FF 3 FD-FF - active display 192 00-BF 224 00-DF 240 00-EF @@ -55,7 +55,7 @@ NTSC frame timing PAL frame timing 256x192 256x224 256x240 - - vertical blanking 3 BA-BC 3 CA-CC 3 D2-D4 + - vertical sync 3 BA-BC 3 CA-CC 3 D2-D4 - top blanking 13 BD-C9 13 CD-D9 13 D5-E1 - top border 54 CA-FF 38 DA-FF 30 E2-FF - active display 192 00-BF 224 00-DF 240 00-EF @@ -90,7 +90,7 @@ PAL frame timing #define PRIORITY_BIT 0x1000 #define BACKDROP_COLOR ((m_vdp_mode == 4 ? 0x10 : 0x00) + (m_reg[0x07] & 0x0f)) -#define VERTICAL_BLANKING 0 +#define VERTICAL_SYNC 0 #define TOP_BLANKING 1 #define TOP_BORDER 2 #define ACTIVE_DISPLAY_V 3 @@ -169,6 +169,7 @@ sega315_5124_device::sega315_5124_device(const machine_config &mconfig, const ch , m_supports_224_240( false ) , m_is_pal(false) , m_int_cb(*this) + , m_csync_cb(*this) , m_pause_cb(*this) , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, nullptr, *ADDRESS_MAP_NAME(sega315_5124)) , m_palette(*this, "palette") @@ -185,6 +186,7 @@ sega315_5124_device::sega315_5124_device(const machine_config &mconfig, device_t , m_supports_224_240( supports_224_240 ) , m_is_pal(false) , m_int_cb(*this) + , m_csync_cb(*this) , m_pause_cb(*this) , m_space_config("videoram", ENDIANNESS_LITTLE, 8, 14, 0, nullptr, *ADDRESS_MAP_NAME(sega315_5124)) , m_palette(*this, "palette") @@ -289,7 +291,7 @@ void sega315_5124_device::set_frame_timing() READ8_MEMBER( sega315_5124_device::vcount_read ) { - const int active_scr_start = m_frame_timing[VERTICAL_BLANKING] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER]; + const int active_scr_start = m_frame_timing[VERTICAL_SYNC] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER]; int vpos = m_screen->vpos(); if (m_screen->hpos() < VCOUNT_CHANGE_HPOS) @@ -415,7 +417,7 @@ void sega315_5124_device::device_timer(emu_timer &timer, device_timer_id id, int void sega315_5124_device::process_line_timer() { const int vpos = m_screen->vpos(); - int vpos_limit = m_frame_timing[VERTICAL_BLANKING] + m_frame_timing[TOP_BLANKING] + int vpos_limit = m_frame_timing[VERTICAL_SYNC] + m_frame_timing[TOP_BLANKING] + m_frame_timing[TOP_BORDER] + m_frame_timing[ACTIVE_DISPLAY_V] + m_frame_timing[BOTTOM_BORDER] + m_frame_timing[BOTTOM_BLANKING]; @@ -423,6 +425,22 @@ void sega315_5124_device::process_line_timer() m_display_disabled = !(m_reg[0x01] & 0x40); m_reg8copy = m_reg[0x08]; + /* Check if the /CSYNC signal must be active (low) */ + if ( !m_csync_cb.isnull() ) + { + /* /CSYNC is signals /HSYNC and /VSYNC (both internals) ANDed together. + According to Charles MacDonald, /HSYNC goes low for 28 pixels on beginning + (before active screen) of all lines except on vertical sync area, where + /VSYNC goes low for 3 full lines, and except the two lines that follows, + because /VSYNC goes high for another line and remains high until the + active screen of the next line, what avoids a /HSYNC pulse there. + */ + if (vpos == 0 || vpos > (m_frame_timing[VERTICAL_SYNC] + 1)) + { + m_csync_cb(0); + } + } + vpos_limit -= m_frame_timing[BOTTOM_BLANKING]; /* Check if we're below the bottom border */ @@ -529,7 +547,7 @@ void sega315_5124_device::process_line_timer() return; } - /* we're in the vertical or top blanking area */ + /* we're in the vertical sync or top blanking areas */ m_line_counter = m_reg[0x0a]; } @@ -1575,6 +1593,7 @@ void sega315_5124_device::device_start() { /* Resolve callbacks */ m_int_cb.resolve(); + m_csync_cb.resolve(); m_pause_cb.resolve(); /* Allocate video RAM */ diff --git a/src/devices/video/315_5124.h b/src/devices/video/315_5124.h index 9c2f2484209..d34d54d91d0 100644 --- a/src/devices/video/315_5124.h +++ b/src/devices/video/315_5124.h @@ -68,6 +68,7 @@ public: template static devcb_base &set_int_callback(device_t &device, _Object object) { return downcast(device).m_int_cb.set_callback(object); } + template static devcb_base &set_csync_callback(device_t &device, _Object object) { return downcast(device).m_csync_cb.set_callback(object); } template static devcb_base &set_pause_callback(device_t &device, _Object object) { return downcast(device).m_pause_cb.set_callback(object); } DECLARE_READ8_MEMBER( vram_read ); @@ -156,6 +157,7 @@ protected: int m_current_palette[32]; bool m_is_pal; /* false = NTSC, true = PAL */ devcb_write_line m_int_cb; /* Interrupt callback function */ + devcb_write_line m_csync_cb; /* C-Sync callback function */ devcb_write_line m_pause_cb; /* Pause callback function */ emu_timer *m_display_timer; emu_timer *m_hint_timer; @@ -224,6 +226,9 @@ protected: #define MCFG_SEGA315_5124_INT_CB(_devcb) \ devcb = &sega315_5124_device::set_int_callback(*device, DEVCB_##_devcb); +#define MCFG_SEGA315_5124_CSYNC_CB(_devcb) \ + devcb = &sega315_5124_device::set_csync_callback(*device, DEVCB_##_devcb); + #define MCFG_SEGA315_5124_PAUSE_CB(_devcb) \ devcb = &sega315_5124_device::set_pause_callback(*device, DEVCB_##_devcb); @@ -236,6 +241,9 @@ protected: #define MCFG_SEGA315_5246_INT_CB(_devcb) \ devcb = &sega315_5246_device::set_int_callback(*device, DEVCB_##_devcb); +#define MCFG_SEGA315_5246_CSYNC_CB(_devcb) \ + devcb = &sega315_5246_device::set_csync_callback(*device, DEVCB_##_devcb); + #define MCFG_SEGA315_5246_PAUSE_CB(_devcb) \ devcb = &sega315_5246_device::set_pause_callback(*device, DEVCB_##_devcb); @@ -248,6 +256,9 @@ protected: #define MCFG_SEGA315_5378_INT_CB(_devcb) \ devcb = &sega315_5378_device::set_int_callback(*device, DEVCB_##_devcb); +#define MCFG_SEGA315_5378_CSYNC_CB(_devcb) \ + devcb = &sega315_5378_device::set_csync_callback(*device, DEVCB_##_devcb); + #define MCFG_SEGA315_5378_PAUSE_CB(_devcb) \ devcb = &sega315_5378_device::set_pause_callback(*device, DEVCB_##_devcb); diff --git a/src/mame/drivers/sg1000.cpp b/src/mame/drivers/sg1000.cpp index 102084994d1..d83b0756b5e 100644 --- a/src/mame/drivers/sg1000.cpp +++ b/src/mame/drivers/sg1000.cpp @@ -58,7 +58,6 @@ Notes: - SC-3000 return instruction referenced by R when reading ports 60-7f,e0-ff - connect PSG /READY signal to Z80 WAIT - accurate video timing - - SP-400 serial printer - SH-400 racing controller - SF-7000 serial comms @@ -91,13 +90,31 @@ WRITE8_MEMBER( sg1000_state::omv_w ) m_cart->write_cart(space, offset, data); } -/*------------------------------------------------- - joysel_r - --------------------------------------------------*/ - -READ8_MEMBER( sg1000_state::joysel_r ) +READ8_MEMBER( sg1000_state::peripheral_r ) { - return 0x80; + bool joy_ports_disabled = m_sgexpslot->is_readable(offset); + + if (joy_ports_disabled) + { + return m_sgexpslot->read(space, offset); + } + else + { + if (offset & 0x01) + return m_pb7->read(); + else + return m_pa7->read(); + } +} + +WRITE8_MEMBER( sg1000_state::peripheral_w ) +{ + bool joy_ports_disabled = m_sgexpslot->is_writeable(offset); + + if (joy_ports_disabled) + { + m_sgexpslot->write(space, offset, data); + } } /*------------------------------------------------- @@ -118,10 +135,7 @@ static ADDRESS_MAP_START( sg1000_io_map, AS_IO, 8, sg1000_state ) AM_RANGE(0x40, 0x40) AM_MIRROR(0x3f) AM_DEVWRITE(SN76489AN_TAG, sn76489a_device, write) AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, vram_read, vram_write) AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, register_read, register_write) - AM_RANGE(0xdc, 0xdc) AM_READ_PORT("PA7") - AM_RANGE(0xdd, 0xdd) AM_READ_PORT("PB7") - AM_RANGE(0xde, 0xde) AM_READ(joysel_r) AM_WRITENOP - AM_RANGE(0xdf, 0xdf) AM_NOP + AM_RANGE(0xdc, 0xdf) AM_READWRITE(peripheral_r, peripheral_w) ADDRESS_MAP_END /*------------------------------------------------- @@ -168,7 +182,7 @@ static ADDRESS_MAP_START( sc3000_io_map, AS_IO, 8, sg1000_state ) AM_RANGE(0x7f, 0x7f) AM_DEVWRITE(SN76489AN_TAG, sn76489a_device, write) AM_RANGE(0xbe, 0xbe) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, vram_read, vram_write) AM_RANGE(0xbf, 0xbf) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, register_read, register_write) - AM_RANGE(0xdc, 0xdf) AM_DEVREADWRITE(UPD9255_TAG, i8255_device, read, write) + AM_RANGE(0xdc, 0xdf) AM_READWRITE(peripheral_r, peripheral_w) ADDRESS_MAP_END /* This is how the I/O ports are really mapped, but MAME does not support overlapping ranges @@ -200,7 +214,7 @@ static ADDRESS_MAP_START( sf7000_io_map, AS_IO, 8, sf7000_state ) AM_RANGE(0x7f, 0x7f) AM_DEVWRITE(SN76489AN_TAG, sn76489a_device, write) AM_RANGE(0xbe, 0xbe) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, vram_read, vram_write) AM_RANGE(0xbf, 0xbf) AM_DEVREADWRITE(TMS9918A_TAG, tms9918a_device, register_read, register_write) - AM_RANGE(0xdc, 0xdf) AM_DEVREADWRITE(UPD9255_0_TAG, i8255_device, read, write) + AM_RANGE(0xdc, 0xdf) AM_READWRITE(peripheral_r, peripheral_w) AM_RANGE(0xe0, 0xe1) AM_DEVICE(UPD765_TAG, upd765a_device, map) AM_RANGE(0xe4, 0xe7) AM_DEVREADWRITE(UPD9255_1_TAG, i8255_device, read, write) AM_RANGE(0xe8, 0xe8) AM_DEVREADWRITE(UPD8251_TAG, i8251_device, data_r, data_w) @@ -224,7 +238,7 @@ INPUT_CHANGED_MEMBER( sg1000_state::trigger_nmi ) INPUT_PORTS( sg1000 ) -------------------------------------------------*/ -static INPUT_PORTS_START( sg1000 ) +static INPUT_PORTS_START( sg1000_joy ) PORT_START("PA7") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) @@ -241,6 +255,10 @@ static INPUT_PORTS_START( sg1000 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) +INPUT_PORTS_END + +static INPUT_PORTS_START( sg1000 ) + PORT_INCLUDE( sg1000_joy ) PORT_START("NMI") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("PAUSE") PORT_CODE(KEYCODE_P) PORT_CHANGED_MEMBER(DEVICE_SELF, sg1000_state, trigger_nmi, 0) @@ -299,138 +317,17 @@ static INPUT_PORTS_START( omv ) PORT_BIT( 0xf0, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END -/*------------------------------------------------- - INPUT_PORTS( sk1100 ) --------------------------------------------------*/ - -INPUT_PORTS_START( sk1100 ) - PORT_START("PA0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHAR('q') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHAR('a') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHAR('z') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("ENG DIER'S") PORT_CODE(KEYCODE_RALT) PORT_CHAR(UCHAR_MAMEKEY(RALT)) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',') PORT_CHAR('<') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHAR('k') - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHAR('i') - - PORT_START("PA1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('"') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHAR('w') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHAR('s') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHAR('x') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SPC") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_STOP) PORT_CHAR('.') PORT_CHAR('>') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHAR('l') - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHAR('o') - - PORT_START("PA2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHAR('#') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHAR('e') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHAR('d') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHAR('c') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("HOME CLR") PORT_CODE(KEYCODE_HOME) PORT_CHAR(UCHAR_MAMEKEY(HOME)) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?') - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR('+') - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHAR('p') - - PORT_START("PA3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHAR('$') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHAR('r') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHAR('f') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHAR('v') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("INS DEL") PORT_CODE(KEYCODE_BACKSPACE) PORT_CHAR(8) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_SMALL_PI) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR(0x03c0) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_QUOTE) PORT_CHAR(':') PORT_CHAR('*') - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('@') PORT_CHAR('`') - - PORT_START("PA4") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHAR('%') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHAR('t') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHAR('g') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHAR('b') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_DOWN) PORT_CODE(KEYCODE_DOWN) PORT_CHAR(UCHAR_MAMEKEY(DOWN)) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR(']') PORT_CHAR('}') - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR('[') PORT_CHAR('{') - - PORT_START("PA5") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHAR('&') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHAR('y') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHAR('h') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHAR('n') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_LEFT) PORT_CODE(KEYCODE_LEFT) PORT_CHAR(UCHAR_MAMEKEY(LEFT)) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CR") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(13) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PA6") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHAR('\'') - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHAR('u') - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHAR('j') - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHAR('m') - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_RIGHT) PORT_CODE(KEYCODE_RIGHT) PORT_CHAR(UCHAR_MAMEKEY(RIGHT)) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME(UTF8_UP) PORT_CODE(KEYCODE_UP) PORT_CHAR(UCHAR_MAMEKEY(UP)) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PA7") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) - - PORT_START("PB0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHAR('(') - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PB1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR(')') - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PB2") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_0) PORT_CHAR('0') - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PB3") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHAR('=') - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PB4") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_CODE(KEYCODE_BACKSLASH2) PORT_CHAR('^') - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) - - PORT_START("PB5") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("\xc2\xa5") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(0x00a5) - PORT_BIT( 0x06, IP_ACTIVE_LOW, IPT_UNUSED ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("FUNC") PORT_CODE(KEYCODE_TAB) - - PORT_START("PB6") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("BREAK") PORT_CODE(KEYCODE_ESC) PORT_CHAR(UCHAR_MAMEKEY(ESC)) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("GRAPH") PORT_CODE(KEYCODE_LALT) PORT_CHAR(UCHAR_MAMEKEY(LALT)) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("CTRL") PORT_CODE(KEYCODE_LCONTROL) PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("SHIFT") PORT_CODE(KEYCODE_LSHIFT) PORT_CODE(KEYCODE_RSHIFT) PORT_CHAR(UCHAR_SHIFT_1) - - PORT_START("PB7") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) - - PORT_START("NMI") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F10) PORT_CHANGED_MEMBER(DEVICE_SELF, sg1000_state, trigger_nmi, 0) -INPUT_PORTS_END - /*------------------------------------------------- INPUT_PORTS( sc3000 ) -------------------------------------------------*/ static INPUT_PORTS_START( sc3000 ) - PORT_INCLUDE( sk1100 ) + PORT_INCLUDE( sg1000_joy ) + + // keyboard keys are added by the embedded sk1100 device + + PORT_START("NMI") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_KEYBOARD ) PORT_NAME("RESET") PORT_CODE(KEYCODE_F10) PORT_CHANGED_MEMBER(DEVICE_SELF, sg1000_state, trigger_nmi, 0) INPUT_PORTS_END /*------------------------------------------------- @@ -438,7 +335,7 @@ INPUT_PORTS_END -------------------------------------------------*/ static INPUT_PORTS_START( sf7000 ) - PORT_INCLUDE( sk1100 ) + PORT_INCLUDE( sc3000 ) PORT_START("BAUD") PORT_CONFNAME( 0x07, 0x05, "Baud rate") @@ -458,82 +355,6 @@ INPUT_PORTS_END I8255 INTERFACE -------------------------------------------------*/ -READ8_MEMBER( sc3000_state::ppi_pa_r ) -{ - /* - Signal Description - - PA0 Keyboard input - PA1 Keyboard input - PA2 Keyboard input - PA3 Keyboard input - PA4 Keyboard input - PA5 Keyboard input - PA6 Keyboard input - PA7 Keyboard input - */ - - return m_key_row[m_keylatch]->read(); -} - -READ8_MEMBER( sc3000_state::ppi_pb_r ) -{ - /* - Signal Description - - PB0 Keyboard input - PB1 Keyboard input - PB2 Keyboard input - PB3 Keyboard input - PB4 /CONT input from cartridge terminal B-11 - PB5 FAULT input from printer - PB6 BUSY input from printer - PB7 Cassette tape input - */ - - /* keyboard */ - UINT8 data = m_key_row[m_keylatch + 8]->read(); - - /* cartridge contact */ - data |= 0x10; - - /* printer */ - data |= 0x60; - - /* tape input */ - if (m_cassette->input() > +0.0) data |= 0x80; - - return data; -} - -WRITE8_MEMBER( sc3000_state::ppi_pc_w ) -{ - /* - Signal Description - - PC0 Keyboard raster output - PC1 Keyboard raster output - PC2 Keyboard raster output - PC3 not connected - PC4 Cassette tape output - PC5 DATA to printer - PC6 /RESET to printer - PC7 /FEED to printer - */ - - /* keyboard */ - m_keylatch = data & 0x07; - - /* cassette */ - m_cassette->output( BIT(data, 4) ? +1.0 : -1.0); - - /* TODO printer */ -} - -/*------------------------------------------------- - I8255 INTERFACE --------------------------------------------------*/ - WRITE_LINE_MEMBER( sf7000_state::write_centronics_busy ) { m_centronics_busy = state; @@ -643,27 +464,6 @@ void sc3000_state::machine_start() /* toggle light gun crosshair */ timer_set(attotime::zero, TIMER_LIGHTGUN_TICK); - // find keyboard rows - m_key_row[0] = m_pa0; - m_key_row[1] = m_pa1; - m_key_row[2] = m_pa2; - m_key_row[3] = m_pa3; - m_key_row[4] = m_pa4; - m_key_row[5] = m_pa5; - m_key_row[6] = m_pa6; - m_key_row[7] = m_pa7; - m_key_row[8] = m_pb0; - m_key_row[9] = m_pb1; - m_key_row[10] = m_pb2; - m_key_row[11] = m_pb3; - m_key_row[12] = m_pb4; - m_key_row[13] = m_pb5; - m_key_row[14] = m_pb6; - m_key_row[15] = m_pb7; - - /* register for state saving */ - save_item(NAME(m_keylatch)); - if (m_cart && m_cart->exists() && (m_cart->get_type() == SEGA8_BASIC_L3 || m_cart->get_type() == SEGA8_MUSIC_EDITOR || m_cart->get_type() == SEGA8_DAHJEE_TYPEA || m_cart->get_type() == SEGA8_DAHJEE_TYPEB)) { @@ -725,6 +525,9 @@ static MACHINE_CONFIG_START( sg1000, sg1000_state ) MCFG_SOUND_ADD(SN76489AN_TAG, SN76489A, XTAL_10_738635MHz/3) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) + /* expansion slot */ + MCFG_SG1000_EXPANSION_ADD(EXPSLOT_TAG, sg1000_expansion_devices, nullptr, false) + /* cartridge */ MCFG_SG1000_CARTRIDGE_ADD(CARTSLOT_TAG, sg1000_cart, nullptr) @@ -775,26 +578,15 @@ static MACHINE_CONFIG_START( sc3000, sc3000_state ) MCFG_SOUND_ADD(SN76489AN_TAG, SN76489A, XTAL_10_738635MHz/3) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - /* devices */ - MCFG_DEVICE_ADD(UPD9255_TAG, I8255, 0) - MCFG_I8255_IN_PORTA_CB(READ8(sc3000_state, ppi_pa_r)) - MCFG_I8255_IN_PORTB_CB(READ8(sc3000_state, ppi_pb_r)) - MCFG_I8255_OUT_PORTC_CB(WRITE8(sc3000_state, ppi_pc_w)) - -// MCFG_PRINTER_ADD("sp400") /* serial printer */ - - MCFG_CASSETTE_ADD("cassette") - MCFG_CASSETTE_FORMATS(sc3000_cassette_formats) - MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) - MCFG_CASSETTE_INTERFACE("sc3000_cass") + /* sc3000 has all sk1100 features built-in, so add it as a fixed slot */ + MCFG_SG1000_EXPANSION_ADD(EXPSLOT_TAG, sg1000_expansion_devices, "sk1100", true) /* cartridge */ MCFG_SC3000_CARTRIDGE_ADD(CARTSLOT_TAG, sg1000_cart, nullptr) /* software lists */ MCFG_SOFTWARE_LIST_ADD("cart_list","sg1000") - MCFG_SOFTWARE_LIST_ADD("sc3k_cart_list","sc3000_cart") - MCFG_SOFTWARE_LIST_ADD("cass_list","sc3000_cass") + /* the sk1100 device will add sc3000 cart and cass lists */ /* internal ram */ MCFG_RAM_ADD(RAM_TAG) @@ -825,11 +617,6 @@ static MACHINE_CONFIG_START( sf7000, sf7000_state ) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) /* devices */ - MCFG_DEVICE_ADD(UPD9255_0_TAG, I8255, 0) - MCFG_I8255_IN_PORTA_CB(READ8(sc3000_state, ppi_pa_r)) - MCFG_I8255_IN_PORTB_CB(READ8(sc3000_state, ppi_pb_r)) - MCFG_I8255_OUT_PORTC_CB(WRITE8(sc3000_state, ppi_pc_w)) - MCFG_DEVICE_ADD(UPD9255_1_TAG, I8255, 0) MCFG_I8255_IN_PORTA_CB(READ8(sf7000_state, ppi_pa_r)) MCFG_I8255_OUT_PORTB_CB(DEVWRITE8("cent_data_out", output_latch_device, write)) @@ -851,10 +638,8 @@ static MACHINE_CONFIG_START( sf7000, sf7000_state ) MCFG_CENTRONICS_OUTPUT_LATCH_ADD("cent_data_out", "centronics") - MCFG_CASSETTE_ADD("cassette") - MCFG_CASSETTE_FORMATS(sc3000_cassette_formats) - MCFG_CASSETTE_DEFAULT_STATE(CASSETTE_STOPPED | CASSETTE_MOTOR_ENABLED | CASSETTE_SPEAKER_ENABLED) - MCFG_CASSETTE_INTERFACE("sc3000_cass") + /* sf7000 (sc3000) has all sk1100 features built-in, so add it as a fixed slot */ + MCFG_SG1000_EXPANSION_ADD(EXPSLOT_TAG, sg1000_expansion_devices, "sk1100", true) /* software lists */ MCFG_SOFTWARE_LIST_ADD("flop_list","sf7000") diff --git a/src/mame/drivers/sms.cpp b/src/mame/drivers/sms.cpp index 8f6480c28e7..1e88d602063 100644 --- a/src/mame/drivers/sms.cpp +++ b/src/mame/drivers/sms.cpp @@ -17,12 +17,9 @@ - SIO interface for Game Gear (needs netplay, I guess) - Support for other DE-9 compatible controllers, like the Mega Drive 6-Button that has homebrew software support - - Sega SK-1100 keyboard support for Sega Mark III (sg1000m3 driver) - Link between two Mark III's through keyboard, supported by F-16 Fighting Falcon - - Mark III expansion slot, used by keyboard and FM Sound Unit - - Rapid button of smsj, sms1krfm and sms1kr consoles + - On sms1kr (without FM), verify if Rapid uses C-Sync and PSG can be muted like on smsj - Accurate GG vertical scaling in SMS mode (h-scaling seems right for subpixel rendering) - - SMS drivers for other versions (one has a 10.746168MHz XTAL) - Software compatibility flags, by region and/or BIOS - Samsung modem for Gam*Boy Securities Information Service System - Sega Demo Unit II (SMS kiosk-like expansion device) @@ -256,8 +253,15 @@ DC00 - Selection buttons #2, 9-16 (R) #include "sms1.lh" -#define MASTER_CLOCK_PAL 53203425 /* 12 * subcarrier freq. (4.43361875MHz) */ #define MASTER_CLOCK_GG 32215905 +#define MASTER_CLOCK_PALN 10746168 +// The clocks for PAL and PAL-M used here differ from their nominal values, +// because with the latter errors will occur on Flubba's VDPTest, probably +// due to rounding issues in the core. +// Nominal XTAL value for SMS PAL-M (Brazil) is 10726834. +#define MASTER_CLOCK_PALM 10726833 +// Nominal XTAL value for SMS PAL is 53203424. +#define MASTER_CLOCK_PAL 53203425 /* 12 * subcarrier freq. (4.43361875MHz) */ static ADDRESS_MAP_START( sms1_mem, AS_PROGRAM, 8, sms_state ) @@ -296,35 +300,57 @@ static ADDRESS_MAP_START( sg1000m3_io, AS_IO, 8, sms_state ) AM_RANGE(0x40, 0x7f) AM_READWRITE(sms_count_r, sms_psg_w) AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) - AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x1e) AM_READ(sms_input_port_dc_r) - AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x1e) AM_READ(sms_input_port_dd_r) - AM_RANGE(0xe0, 0xe0) AM_MIRROR(0x0e) AM_READ(sms_input_port_dc_r) - AM_RANGE(0xe1, 0xe1) AM_MIRROR(0x0e) AM_READ(sms_input_port_dd_r) - AM_RANGE(0xf0, 0xf0) AM_READWRITE(sms_input_port_dc_r, sms_ym2413_register_port_w) - AM_RANGE(0xf1, 0xf1) AM_READWRITE(sms_input_port_dd_r, sms_ym2413_data_port_w) - AM_RANGE(0xf2, 0xf2) AM_READWRITE(sms_audio_control_r, sms_audio_control_w) - AM_RANGE(0xf3, 0xf3) AM_READ(sms_input_port_dd_r) - AM_RANGE(0xf4, 0xf4) AM_MIRROR(0x02) AM_READ(sms_input_port_dc_r) - AM_RANGE(0xf5, 0xf5) AM_MIRROR(0x02) AM_READ(sms_input_port_dd_r) - AM_RANGE(0xf8, 0xf8) AM_MIRROR(0x06) AM_READ(sms_input_port_dc_r) - AM_RANGE(0xf9, 0xf9) AM_MIRROR(0x06) AM_READ(sms_input_port_dd_r) + AM_RANGE(0xc0, 0xc7) AM_MIRROR(0x38) AM_READWRITE(sg1000m3_peripheral_r,sg1000m3_peripheral_w) ADDRESS_MAP_END static ADDRESS_MAP_START( sms_io, AS_IO, 8, sms_state ) - AM_IMPORT_FROM(sg1000m3_io) + ADDRESS_MAP_GLOBAL_MASK(0xff) + ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x00, 0x00) AM_MIRROR(0x3e) AM_WRITE(sms_mem_control_w) AM_RANGE(0x01, 0x01) AM_MIRROR(0x3e) AM_WRITE(sms_io_control_w) + AM_RANGE(0x40, 0x7f) AM_READWRITE(sms_count_r, sms_psg_w) + AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) + AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) + AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x3e) AM_READ(sms_input_port_dc_r) + AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x3e) AM_READ(sms_input_port_dd_r) +ADDRESS_MAP_END + + +// It seems the Korean versions do some more strict decoding on the I/O +// 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( smskr_io, AS_IO, 8, sms_state ) + ADDRESS_MAP_GLOBAL_MASK(0xff) + ADDRESS_MAP_UNMAP_HIGH + AM_RANGE(0x3e, 0x3e) AM_WRITE(sms_mem_control_w) + AM_RANGE(0x3f, 0x3f) AM_WRITE(sms_io_control_w) + AM_RANGE(0x40, 0x7f) AM_READWRITE(sms_count_r, sms_psg_w) + AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) + AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) + AM_RANGE(0xc0, 0xc0) AM_MIRROR(0x3e) AM_READ(sms_input_port_dc_r) + AM_RANGE(0xc1, 0xc1) AM_MIRROR(0x3e) AM_READ(sms_input_port_dd_r) ADDRESS_MAP_END // Mirrors for I/O ports $3E/$3F don't exist on the Japanese SMS. -// It seems the Korean versions do the same decoding on those I/O addresses. -// Leaving the mirrors breaks the Korean cartridge bublboky. +// Also, $C0/$C1 are the only mirrors for I/O ports $DC/$DD. static ADDRESS_MAP_START( smsj_io, AS_IO, 8, sms_state ) - AM_IMPORT_FROM(sg1000m3_io) + ADDRESS_MAP_GLOBAL_MASK(0xff) + ADDRESS_MAP_UNMAP_HIGH AM_RANGE(0x3e, 0x3e) AM_WRITE(sms_mem_control_w) AM_RANGE(0x3f, 0x3f) AM_WRITE(sms_io_control_w) + AM_RANGE(0x40, 0x7f) AM_READWRITE(sms_count_r, sms_psg_w) + AM_RANGE(0x80, 0x80) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, vram_read, vram_write) + AM_RANGE(0x81, 0x81) AM_MIRROR(0x3e) AM_DEVREADWRITE("sms_vdp", sega315_5124_device, register_read, register_write) + AM_RANGE(0xc0, 0xc0) AM_READ(sms_input_port_dc_r) + AM_RANGE(0xc1, 0xc1) AM_READ(sms_input_port_dd_r) + AM_RANGE(0xdc, 0xdc) AM_READ(sms_input_port_dc_r) + AM_RANGE(0xdd, 0xdd) AM_READ(sms_input_port_dd_r) + AM_RANGE(0xf0, 0xf0) AM_WRITE(smsj_ym2413_register_port_w) + AM_RANGE(0xf1, 0xf1) AM_WRITE(smsj_ym2413_data_port_w) + AM_RANGE(0xf2, 0xf2) AM_READWRITE(smsj_audio_control_r, smsj_audio_control_w) ADDRESS_MAP_END @@ -381,8 +407,8 @@ INPUT_PORTS_END static INPUT_PORTS_START( smsj ) PORT_INCLUDE( sg1000m3 ) - //PORT_START("RAPID") - //PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Rapid Button") /* Not implemented */ + PORT_START("RAPID") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE2 ) PORT_NAME("Rapid Button") INPUT_PORTS_END static INPUT_PORTS_START( smssdisp ) @@ -460,23 +486,13 @@ static INPUT_PORTS_START( gg ) INPUT_PORTS_END -static MACHINE_CONFIG_START( sms_ntsc_base, sms_state ) - /* basic machine hardware */ - MCFG_CPU_ADD("maincpu", Z80, XTAL_10_738635MHz/3) - MCFG_CPU_PROGRAM_MAP(sms_mem) - MCFG_CPU_IO_MAP(sms_io) - - MCFG_QUANTUM_TIME(attotime::from_hz(60)) - +static MACHINE_CONFIG_START( sms_base, sms_state ) MCFG_MACHINE_START_OVERRIDE(sms_state,sms) MCFG_MACHINE_RESET_OVERRIDE(sms_state,sms) - /* sound hardware */ + /* basic machine hardware */ MCFG_SPEAKER_STANDARD_MONO("mono") - MCFG_SOUND_ADD("segapsg", SEGAPSG, XTAL_10_738635MHz/3) - MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - MCFG_SMS_CARTRIDGE_ADD("slot", sms_cart, nullptr) MCFG_SOFTWARE_LIST_ADD("cart_list","sms") @@ -490,6 +506,18 @@ static MACHINE_CONFIG_START( sms_ntsc_base, sms_state ) MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) MACHINE_CONFIG_END +static MACHINE_CONFIG_DERIVED( sms_ntsc_base, sms_base ) + MCFG_CPU_ADD("maincpu", Z80, XTAL_10_738635MHz/3) + MCFG_CPU_PROGRAM_MAP(sms_mem) + MCFG_CPU_IO_MAP(sms_io) + + MCFG_QUANTUM_TIME(attotime::from_hz(60)) + + /* actually, PSG is embedded in the VDP chip */ + MCFG_SOUND_ADD("segapsg", SEGAPSG, XTAL_10_738635MHz/3) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +MACHINE_CONFIG_END + /* For SMS drivers, the ratio between CPU and pixel clocks, set through dividers, is 2/3. The division that sets the pixel clock, in MCFG_SCREEN_RAW_PARAMS(), results in a remainder @@ -507,13 +535,41 @@ MACHINE_CONFIG_END lines after each MCFG_SCREEN_RAW_PARAMS call below can be removed. */ +#define MCFG_SCREEN_SMS_PAL_RAW_PARAMS(_pixelclock) \ + MCFG_SCREEN_RAW_PARAMS(_pixelclock, \ + SEGA315_5124_WIDTH, \ + SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, \ + SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ + SEGA315_5124_HEIGHT_PAL, \ + SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT, \ + SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT + 240) \ + MCFG_SCREEN_REFRESH_RATE((double) _pixelclock / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_PAL)) + +#define MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(_pixelclock) \ + MCFG_SCREEN_RAW_PARAMS(_pixelclock, \ + SEGA315_5124_WIDTH, \ + SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, \ + SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ + SEGA315_5124_HEIGHT_NTSC, \ + SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT, \ + SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT + 224) \ + MCFG_SCREEN_REFRESH_RATE((double) _pixelclock / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + +#define MCFG_SCREEN_GG_RAW_PARAMS(_pixelclock) \ + MCFG_SCREEN_RAW_PARAMS(_pixelclock, \ + SEGA315_5124_WIDTH, \ + SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 6*8, \ + SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 26*8, \ + 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_REFRESH_RATE((double) _pixelclock / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + + static MACHINE_CONFIG_DERIVED( sms2_ntsc, sms_ntsc_base ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(XTAL_10_738635MHz/2, \ - SEGA315_5124_WIDTH , SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_NTSC, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT + 224) - MCFG_SCREEN_REFRESH_RATE((double) XTAL_10_738635MHz/2 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(XTAL_10_738635MHz/2) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms) MCFG_DEVICE_ADD("sms_vdp", SEGA315_5246, 0) @@ -528,28 +584,18 @@ static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(sms1_mem) // This adds the SegaScope handlers for 3-D glasses - MCFG_CPU_IO_MAP(sms_io) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(XTAL_10_738635MHz/2, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_NTSC, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT + 224) - MCFG_SCREEN_REFRESH_RATE((double) XTAL_10_738635MHz/2 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(XTAL_10_738635MHz/2) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) MCFG_SCREEN_ADD("left_lcd", LCD) // This is needed for SegaScope Left LCD - MCFG_SCREEN_RAW_PARAMS(XTAL_10_738635MHz/2, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_NTSC, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT + 224) - MCFG_SCREEN_REFRESH_RATE((double) XTAL_10_738635MHz/2 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(XTAL_10_738635MHz/2) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) MCFG_SCREEN_ADD("right_lcd", LCD) // This is needed for SegaScope Right LCD - MCFG_SCREEN_RAW_PARAMS(XTAL_10_738635MHz/2, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_NTSC, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_NTSC_224_TBORDER_HEIGHT + 224) - MCFG_SCREEN_REFRESH_RATE((double) XTAL_10_738635MHz/2 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(XTAL_10_738635MHz/2) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) MCFG_SCREEN_VBLANK_DRIVER(sms_state, screen_vblank_sms1) @@ -567,7 +613,7 @@ static MACHINE_CONFIG_DERIVED( sms1_ntsc, sms_ntsc_base ) // card and expansion slots, not present in Master System II MCFG_SMS_CARD_ADD("mycard", sms_cart, nullptr) - MCFG_SMS_EXPANSION_ADD("exp", sms_expansion_devices, nullptr) + MCFG_SMS_EXPANSION_ADD("smsexp", sms_expansion_devices, nullptr) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED_CLASS( sms_sdisp, sms1_ntsc, smssdisp_state ) @@ -581,7 +627,7 @@ static MACHINE_CONFIG_DERIVED_CLASS( sms_sdisp, sms1_ntsc, smssdisp_state ) MCFG_CPU_IO_MAP(sms_io) MCFG_DEVICE_REMOVE("mycard") - MCFG_DEVICE_REMOVE("exp") + MCFG_DEVICE_REMOVE("smsexp") MCFG_SMS_CARTRIDGE_ADD("slot2", sms_cart, nullptr) MCFG_SMS_CARTRIDGE_ADD("slot3", sms_cart, nullptr) @@ -617,7 +663,7 @@ static MACHINE_CONFIG_DERIVED_CLASS( sms_sdisp, sms1_ntsc, smssdisp_state ) MCFG_SMS_CARD_ADD("slot32", sms_cart, nullptr) MACHINE_CONFIG_END -static MACHINE_CONFIG_START( sms_pal_base, sms_state ) +static MACHINE_CONFIG_DERIVED( sms_pal_base, sms_base ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK_PAL/15) MCFG_CPU_PROGRAM_MAP(sms_mem) @@ -625,36 +671,16 @@ static MACHINE_CONFIG_START( sms_pal_base, sms_state ) MCFG_QUANTUM_TIME(attotime::from_hz(50)) - MCFG_MACHINE_START_OVERRIDE(sms_state,sms) - MCFG_MACHINE_RESET_OVERRIDE(sms_state,sms) - - /* sound hardware */ - MCFG_SPEAKER_STANDARD_MONO("mono") - + /* actually, PSG is embedded in the VDP chip */ MCFG_SOUND_ADD("segapsg", SEGAPSG, MASTER_CLOCK_PAL/15) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) - - MCFG_SMS_CARTRIDGE_ADD("slot", sms_cart, nullptr) - - MCFG_SOFTWARE_LIST_ADD("cart_list","sms") - - MCFG_SMS_CONTROL_PORT_ADD(CONTROL1_TAG, sms_control_port_devices, "joypad") - MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITELINE(sms_state, sms_ctrl1_th_input)) - MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) - - MCFG_SMS_CONTROL_PORT_ADD(CONTROL2_TAG, sms_control_port_devices, "joypad") - MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(WRITELINE(sms_state, sms_ctrl2_th_input)) - MCFG_SMS_CONTROL_PORT_PIXEL_HANDLER(READ32(sms_state, sms_pixel_color)) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( sms2_pal, sms_pal_base ) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_PAL, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT + 240) - MCFG_SCREEN_REFRESH_RATE((double) MASTER_CLOCK_PAL/10 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_PAL)) + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PAL/10) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms) MCFG_DEVICE_ADD("sms_vdp", SEGA315_5246, 0) @@ -668,28 +694,18 @@ static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_PROGRAM_MAP(sms1_mem) // This adds the SegaScope handlers for 3-D glasses - MCFG_CPU_IO_MAP(sms_io) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_PAL, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT + 240) - MCFG_SCREEN_REFRESH_RATE((double) MASTER_CLOCK_PAL/10 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_PAL)) + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PAL/10) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) MCFG_SCREEN_ADD("left_lcd", LCD) // This is needed for SegaScope Left LCD - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_PAL, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT + 240) - MCFG_SCREEN_REFRESH_RATE((double) MASTER_CLOCK_PAL/10 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_PAL)) + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PAL/10) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) MCFG_SCREEN_ADD("right_lcd", LCD) // This is needed for SegaScope Right LCD - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_PAL/10, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH - 2, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 256 + 10, \ - SEGA315_5124_HEIGHT_PAL, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT, SEGA315_5124_TBORDER_START + SEGA315_5124_PAL_240_TBORDER_HEIGHT + 240) - MCFG_SCREEN_REFRESH_RATE((double) MASTER_CLOCK_PAL/10 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_PAL)) + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PAL/10) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) MCFG_SCREEN_VBLANK_DRIVER(sms_state, screen_vblank_sms1) @@ -707,26 +723,180 @@ static MACHINE_CONFIG_DERIVED( sms1_pal, sms_pal_base ) // card and expansion slots, not present in Master System II MCFG_SMS_CARD_ADD("mycard", sms_cart, nullptr) - MCFG_SMS_EXPANSION_ADD("exp", sms_expansion_devices, nullptr) + MCFG_SMS_EXPANSION_ADD("smsexp", sms_expansion_devices, nullptr) +MACHINE_CONFIG_END + + +static MACHINE_CONFIG_DERIVED( sms_paln_base, sms_base ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK_PALN/3) + MCFG_CPU_PROGRAM_MAP(sms_mem) + MCFG_CPU_IO_MAP(sms_io) + + MCFG_QUANTUM_TIME(attotime::from_hz(50)) + + /* actually, PSG is embedded in the VDP chip */ + MCFG_SOUND_ADD("segapsg", SEGAPSG, MASTER_CLOCK_PALN/3) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( sms3_paln, sms_paln_base ) + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PALN/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms) + + MCFG_DEVICE_ADD("sms_vdp", SEGA315_5246, 0) + MCFG_SEGA315_5246_SET_SCREEN("screen") + MCFG_SEGA315_5246_IS_PAL(true) + MCFG_SEGA315_5246_INT_CB(INPUTLINE("maincpu", 0)) + MCFG_SEGA315_5246_PAUSE_CB(WRITELINE(sms_state, sms_pause_callback)) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( sms1_paln, sms_paln_base ) + + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(sms1_mem) // This adds the SegaScope handlers for 3-D glasses + + /* video hardware */ + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PALN/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) + + MCFG_SCREEN_ADD("left_lcd", LCD) // This is needed for SegaScope Left LCD + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PALN/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) + + MCFG_SCREEN_ADD("right_lcd", LCD) // This is needed for SegaScope Right LCD + MCFG_SCREEN_SMS_PAL_RAW_PARAMS(MASTER_CLOCK_PALN/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) + + MCFG_SCREEN_VBLANK_DRIVER(sms_state, screen_vblank_sms1) + + MCFG_DEFAULT_LAYOUT(layout_sms1) + + MCFG_VIDEO_START_OVERRIDE(sms_state,sms1) + MCFG_VIDEO_RESET_OVERRIDE(sms_state,sms1) + + MCFG_DEVICE_ADD("sms_vdp", SEGA315_5124, 0) + MCFG_SEGA315_5124_SET_SCREEN("screen") + MCFG_SEGA315_5124_IS_PAL(true) + MCFG_SEGA315_5124_INT_CB(INPUTLINE("maincpu", 0)) + MCFG_SEGA315_5124_PAUSE_CB(WRITELINE(sms_state, sms_pause_callback)) + + // card and expansion slots, not present in Tec Toy Master System III + MCFG_SMS_CARD_ADD("mycard", sms_cart, nullptr) + MCFG_SMS_EXPANSION_ADD("smsexp", sms_expansion_devices, nullptr) +MACHINE_CONFIG_END + + +static MACHINE_CONFIG_DERIVED( sms_br_base, sms_base ) + /* basic machine hardware */ + MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK_PALM/3) + MCFG_CPU_PROGRAM_MAP(sms_mem) + MCFG_CPU_IO_MAP(sms_io) + + // PAL-M has near the same frequency of NTSC + MCFG_QUANTUM_TIME(attotime::from_hz(60)) + + /* actually, PSG is embedded in the VDP chip */ + MCFG_SOUND_ADD("segapsg", SEGAPSG, MASTER_CLOCK_PALM/3) + MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( sms3_br, sms_br_base ) + /* video hardware */ + // PAL-M height/width parameters are the same of NTSC screens. + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(MASTER_CLOCK_PALM/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms) + + MCFG_DEVICE_ADD("sms_vdp", SEGA315_5246, 0) + MCFG_SEGA315_5246_SET_SCREEN("screen") + MCFG_SEGA315_5246_IS_PAL(false) // PAL-M has same line count of NTSC + MCFG_SEGA315_5246_INT_CB(INPUTLINE("maincpu", 0)) + MCFG_SEGA315_5246_PAUSE_CB(WRITELINE(sms_state, sms_pause_callback)) +MACHINE_CONFIG_END + +static MACHINE_CONFIG_DERIVED( sms1_br, sms_br_base ) + + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_PROGRAM_MAP(sms1_mem) // This adds the SegaScope handlers for 3-D glasses + + /* video hardware */ + // PAL-M height/width parameters are the same of NTSC screens. + MCFG_SCREEN_ADD("screen", RASTER) + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(MASTER_CLOCK_PALM/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) + + MCFG_SCREEN_ADD("left_lcd", LCD) // This is needed for SegaScope Left LCD + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(MASTER_CLOCK_PALM/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) + + MCFG_SCREEN_ADD("right_lcd", LCD) // This is needed for SegaScope Right LCD + MCFG_SCREEN_SMS_NTSC_RAW_PARAMS(MASTER_CLOCK_PALM/2) + MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_sms1) + + MCFG_SCREEN_VBLANK_DRIVER(sms_state, screen_vblank_sms1) + + MCFG_DEFAULT_LAYOUT(layout_sms1) + + MCFG_VIDEO_START_OVERRIDE(sms_state,sms1) + MCFG_VIDEO_RESET_OVERRIDE(sms_state,sms1) + + MCFG_DEVICE_ADD("sms_vdp", SEGA315_5124, 0) + MCFG_SEGA315_5124_SET_SCREEN("screen") + MCFG_SEGA315_5124_IS_PAL(false) // PAL-M has same line count of NTSC + MCFG_SEGA315_5124_INT_CB(INPUTLINE("maincpu", 0)) + MCFG_SEGA315_5124_PAUSE_CB(WRITELINE(sms_state, sms_pause_callback)) + + // card and expansion slots, not present in Tec Toy Master System III + MCFG_SMS_CARD_ADD("mycard", sms_cart, nullptr) + MCFG_SMS_EXPANSION_ADD("smsexp", sms_expansion_devices, nullptr) +MACHINE_CONFIG_END + + +static MACHINE_CONFIG_DERIVED( sms2_kr, sms2_ntsc ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_IO_MAP(smskr_io) + + MCFG_DEVICE_REMOVE("slot") + MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sg1000mk3_cart, nullptr) + MCFG_SOFTWARE_LIST_ADD("cart_list2","sg1000") MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( sms1_kr, sms1_ntsc ) MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_IO_MAP(smsj_io) + MCFG_CPU_IO_MAP(smskr_io) MCFG_DEVICE_REMOVE("slot") MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sg1000mk3_cart, nullptr) + MCFG_SOFTWARE_LIST_ADD("cart_list2","sg1000") + + MCFG_DEVICE_MODIFY("sms_vdp") + MCFG_SEGA315_5124_CSYNC_CB(WRITELINE(sms_state, sms_csync_callback)) MACHINE_CONFIG_END static MACHINE_CONFIG_DERIVED( smsj, sms1_kr ) + MCFG_CPU_MODIFY("maincpu") + MCFG_CPU_IO_MAP(smsj_io) + MCFG_SOUND_ADD("ym2413", YM2413, XTAL_10_738635MHz/3) MCFG_SOUND_ROUTE(ALL_OUTPUTS, "mono", 1.00) MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( sg1000m3, smsj ) +static MACHINE_CONFIG_DERIVED( sg1000m3, sms1_ntsc ) MCFG_CPU_MODIFY("maincpu") MCFG_CPU_IO_MAP(sg1000m3_io) + MCFG_DEVICE_REMOVE("slot") + MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sg1000mk3_cart, nullptr) + MCFG_SOFTWARE_LIST_ADD("cart_list2","sg1000") + + MCFG_DEVICE_REMOVE("smsexp") + MCFG_SG1000_EXPANSION_ADD("sgexp", sg1000_expansion_devices, nullptr, false) + // Mark III does not have TH connected. MCFG_SMS_CONTROL_PORT_MODIFY(CONTROL1_TAG) MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(NOOP) @@ -734,14 +904,6 @@ static MACHINE_CONFIG_DERIVED( sg1000m3, smsj ) MCFG_SMS_CONTROL_PORT_TH_INPUT_HANDLER(NOOP) MACHINE_CONFIG_END -static MACHINE_CONFIG_DERIVED( sms2_kr, sms2_ntsc ) - MCFG_CPU_MODIFY("maincpu") - MCFG_CPU_IO_MAP(smsj_io) - - MCFG_DEVICE_REMOVE("slot") - MCFG_SG1000MK3_CARTRIDGE_ADD("slot", sg1000mk3_cart, nullptr) -MACHINE_CONFIG_END - static MACHINE_CONFIG_START( gamegear, sms_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", Z80, MASTER_CLOCK_GG/9) @@ -755,10 +917,7 @@ static MACHINE_CONFIG_START( gamegear, sms_state ) /* video hardware */ MCFG_SCREEN_ADD("screen", LCD) - MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_GG/6, \ - SEGA315_5124_WIDTH, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 6*8, SEGA315_5124_LBORDER_START + SEGA315_5124_LBORDER_WIDTH + 26*8, \ - 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_REFRESH_RATE((double) MASTER_CLOCK_GG/6 / (SEGA315_5124_WIDTH * SEGA315_5124_HEIGHT_NTSC)) + MCFG_SCREEN_GG_RAW_PARAMS(MASTER_CLOCK_GG/6) MCFG_SCREEN_UPDATE_DRIVER(sms_state, screen_update_gamegear) MCFG_VIDEO_START_OVERRIDE(sms_state,gamegear) @@ -880,6 +1039,57 @@ ROM_START(smskr) ROMX_LOAD("akbioskr.rom", 0x000, 0x20000, CRC(9c5bad91) SHA1(2feafd8f1c40fdf1bd5668f8c5c02e5560945b17), ROM_BIOS(1)) ROM_END +ROM_START(sms1br) + ROM_REGION(0x4000, "maincpu", 0) + ROM_FILL(0x0000, 0x4000, 0xff) + + ROM_REGION(0x20000, "user1", 0) + ROM_SYSTEM_BIOS( 0, "hangonsh", "US/European BIOS v2.4 with Hang On and Safari Hunt (1988)" ) + ROMX_LOAD("mpr-11459a.rom", 0x0000, 0x20000, CRC(91e93385) SHA1(9e179392cd416af14024d8f31c981d9ee9a64517), ROM_BIOS(1)) +ROM_END + +ROM_START(sms2br) + ROM_REGION(0x4000, "maincpu", 0) + ROM_FILL(0x0000, 0x4000, 0xff) + + ROM_REGION(0x40000, "user1", 0) + ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) + ROMX_LOAD("mpr-12808.ic2", 0x0000, 0x20000, CRC(cf4a09ea) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) +ROM_END + +ROM_START(smsbr) + ROM_REGION(0x4000, "maincpu", 0) + ROM_FILL(0x0000, 0x4000, 0xff) + + ROM_REGION(0x40000, "user1", 0) + ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) + ROMX_LOAD("mpr-12808.ic2", 0x0000, 0x20000, CRC(cf4a09ea) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) + ROM_SYSTEM_BIOS( 1, "sonic", "European/Brazilian BIOS with Sonic the Hedgehog (1991)" ) + ROMX_LOAD("sonbios.rom", 0x0000, 0x40000, CRC(81c3476b) SHA1(6aca0e3dffe461ba1cb11a86cd4caf5b97e1b8df), ROM_BIOS(2)) + ROM_SYSTEM_BIOS( 2, "hangonsh", "US/European BIOS v2.4 with Hang On and Safari Hunt (1988)" ) + ROMX_LOAD("mpr-11459a.rom", 0x0000, 0x20000, CRC(91e93385) SHA1(9e179392cd416af14024d8f31c981d9ee9a64517), ROM_BIOS(3)) +ROM_END + +ROM_START(sms2paln) + ROM_REGION(0x4000, "maincpu", 0) + ROM_FILL(0x0000, 0x4000, 0xff) + + ROM_REGION(0x40000, "user1", 0) + ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) + ROMX_LOAD("mpr-12808.ic2", 0x0000, 0x20000, CRC(cf4a09ea) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) + ROM_SYSTEM_BIOS( 1, "missiled", "US/European BIOS v4.4 with Missile Defense 3D (1988)" ) + ROMX_LOAD("missiled.rom", 0x0000, 0x20000, CRC(e79bb689) SHA1(aa92ae576ca670b00855e278378d89e9f85e0351), ROM_BIOS(2)) +ROM_END + +ROM_START(smspaln) + ROM_REGION(0x4000, "maincpu", 0) + ROM_FILL(0x0000, 0x4000, 0xff) + + ROM_REGION(0x40000, "user1", 0) + ROM_SYSTEM_BIOS( 0, "alexkidd", "US/European BIOS with Alex Kidd in Miracle World (1990)" ) + ROMX_LOAD("mpr-12808.ic2", 0x0000, 0x20000, CRC(cf4a09ea) SHA1(3af7b66248d34eb26da40c92bf2fa4c73a46a051), ROM_BIOS(1)) +ROM_END + ROM_START(gamegear) ROM_REGION(0x4000, "maincpu", 0) ROM_FILL(0x0000, 0x4000, 0x00) @@ -893,6 +1103,7 @@ ROM_END #define rom_gamegeaj rom_gamegear #define rom_sms1krfm rom_smsj #define rom_sms1kr rom_smsj +#define rom_sms1paln rom_sms1br /*************************************************************************** @@ -938,11 +1149,11 @@ ROM_END - built-in Sonic the Hedgehog - 1991 BR - - Tec Toy Master System (I) (same as sms1) + - Tec Toy Master System (I) (sms1br) - built-in Hang On/Safari Hunt v2.4 - 1989 - - Tec Toy Master System II (same as sms1) + - Tec Toy Master System II (sms2br) - built-in Alex Kidd in Miracle World - 1991 - - Tec Toy Master System III Compact (same as sms) + - Tec Toy Master System III Compact (smsbr) - built-in Alex Kidd in Miracle World - 1992 - built-in Sonic the Hedgehog - 1993 - built-in World Cup Italia '90 (Super Futebol II) - 1994 @@ -955,10 +1166,21 @@ ROM_END - built-in Monica no Castelo do Dragao - 1994 - built-in Sonic the Hedgehog (T. Monica em O Resgate pack) - 199? Notes about BR: - - PAL-M has same frequency and line count of NTSC + - PAL-M has the same line count and near the same frequency of NTSC - Tec Toy later changed its logo twice and its name to Tectoy - 20XX models (Handy, Collection, Evolution...) likely have SoC hardware + PAL-N (Argentina, Paraguay, Uruguay) + - Tec Toy Master System (I) (sms1paln) + - built-in Hang On/Safari Hunt v2.4 + - Tec Toy Master System II (sms2paln) + - built-in Alex Kidd in Miracle World + - built-in Missile Defense 3-D v4.4 + - Tec Toy Master System III Compact (smspaln) + - built-in Alex Kidd in Miracle World + Notes: + - Distributed by: Gameland (Argentina), Forstar (Uruguay) + These are coin-operated machines (stuff for MAME): - Sega Game Box 9 @@ -972,17 +1194,23 @@ ROM_END ***************************************************************************/ -/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ -CONS( 1985, sg1000m3, sms, 0, sg1000m3, sg1000m3, sms_state, sg1000m3, "Sega", "Mark III", MACHINE_SUPPORTS_SAVE ) -CONS( 1986, sms1, sms, 0, sms1_ntsc, sms1, sms_state, sms1, "Sega", "Master System I", MACHINE_SUPPORTS_SAVE ) -CONS( 1986, sms1pal, sms, 0, sms1_pal, sms1, sms_state, sms1, "Sega", "Master System I (PAL)" , MACHINE_SUPPORTS_SAVE ) -CONS( 1986, smssdisp, sms, 0, sms_sdisp, smssdisp, smssdisp_state, smssdisp, "Sega", "Master System Store Display Unit", MACHINE_SUPPORTS_SAVE ) -CONS( 1987, smsj, sms, 0, smsj, smsj, sms_state, smsj, "Sega", "Master System (Japan)", MACHINE_SUPPORTS_SAVE ) -CONS( 1990, sms, 0, 0, sms2_ntsc, sms, sms_state, sms1, "Sega", "Master System II", MACHINE_SUPPORTS_SAVE ) -CONS( 1990, smspal, sms, 0, sms2_pal, sms, sms_state, sms1, "Sega", "Master System II (PAL)", MACHINE_SUPPORTS_SAVE ) -CONS( 1989, sms1krfm, sms, 0, smsj, smsj, sms_state, smsj, "Samsung", "Gam*Boy I (Korea) (FM)", MACHINE_SUPPORTS_SAVE ) -CONS( 19??, sms1kr, sms, 0, sms1_kr, smsj, sms_state, sms1kr, "Samsung", "Gam*Boy I (Korea)", MACHINE_SUPPORTS_SAVE ) -CONS( 1991, smskr, sms, 0, sms2_kr, sms, sms_state, smskr, "Samsung", "Gam*Boy II (Korea)", MACHINE_SUPPORTS_SAVE ) +/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */ +CONS( 1985, sg1000m3, sms, 0, sg1000m3, sg1000m3, sms_state, sg1000m3, "Sega", "Mark III", MACHINE_SUPPORTS_SAVE ) +CONS( 1986, sms1, sms, 0, sms1_ntsc, sms1, sms_state, sms1, "Sega", "Master System I", MACHINE_SUPPORTS_SAVE ) +CONS( 1986, sms1pal, sms, 0, sms1_pal, sms1, sms_state, sms1, "Sega", "Master System I (PAL)" , MACHINE_SUPPORTS_SAVE ) +CONS( 1986, smssdisp, sms, 0, sms_sdisp, smssdisp, smssdisp_state, smssdisp, "Sega", "Master System Store Display Unit", MACHINE_SUPPORTS_SAVE ) +CONS( 1987, smsj, sms, 0, smsj, smsj, sms_state, smsj, "Sega", "Master System (Japan)", MACHINE_SUPPORTS_SAVE ) +CONS( 1990, sms, 0, 0, sms2_ntsc, sms, sms_state, sms, "Sega", "Master System II", MACHINE_SUPPORTS_SAVE ) +CONS( 1990, smspal, sms, 0, sms2_pal, sms, sms_state, sms, "Sega", "Master System II (PAL)", MACHINE_SUPPORTS_SAVE ) +CONS( 1989, sms1krfm, sms, 0, smsj, smsj, sms_state, smsj, "Samsung", "Gam*Boy I (Korea) (FM)", MACHINE_SUPPORTS_SAVE ) +CONS( 19??, sms1kr, sms, 0, sms1_kr, smsj, sms_state, sms1kr, "Samsung", "Gam*Boy I (Korea)", MACHINE_SUPPORTS_SAVE ) +CONS( 1991, smskr, sms, 0, sms2_kr, sms, sms_state, smskr, "Samsung", "Gam*Boy II (Korea)", MACHINE_SUPPORTS_SAVE ) +CONS( 1989, sms1br, sms, 0, sms1_br, sms1, sms_state, sms1, "Tec Toy", "Master System I (Brazil)", MACHINE_SUPPORTS_SAVE ) +CONS( 1991, sms2br, sms, 0, sms1_br, sms1, sms_state, sms1, "Tec Toy", "Master System II (Brazil)", MACHINE_SUPPORTS_SAVE ) +CONS( 1992, smsbr, sms, 0, sms3_br, sms, sms_state, sms, "Tec Toy", "Master System III Compact (Brazil)", MACHINE_SUPPORTS_SAVE ) +CONS( 19??, sms1paln, sms, 0, sms1_paln, sms1, sms_state, sms1, "Tec Toy", "Master System I (PAL-N)", MACHINE_SUPPORTS_SAVE ) +CONS( 19??, sms2paln, sms, 0, sms1_paln, sms1, sms_state, sms1, "Tec Toy", "Master System II (PAL-N)", MACHINE_SUPPORTS_SAVE ) +CONS( 19??, smspaln, sms, 0, sms3_paln, sms, sms_state, sms, "Tec Toy", "Master System III Compact (PAL-N)", MACHINE_SUPPORTS_SAVE ) -CONS( 1991, gamegear, 0, sms, gamegear, gg, sms_state, gamegear, "Sega", "Game Gear (Europe/America)", MACHINE_SUPPORTS_SAVE ) -CONS( 1990, gamegeaj, gamegear, 0, gamegear, gg, sms_state, gamegeaj, "Sega", "Game Gear (Japan)", MACHINE_SUPPORTS_SAVE ) +CONS( 1991, gamegear, 0, sms, gamegear, gg, sms_state, gamegear, "Sega", "Game Gear (Europe/America)", MACHINE_SUPPORTS_SAVE ) +CONS( 1990, gamegeaj, gamegear, 0, gamegear, gg, sms_state, gamegeaj, "Sega", "Game Gear (Japan)", MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/includes/sg1000.h b/src/mame/includes/sg1000.h index 3f994977f7b..673b457d468 100644 --- a/src/mame/includes/sg1000.h +++ b/src/mame/includes/sg1000.h @@ -5,15 +5,14 @@ #include "emu.h" #include "cpu/z80/z80.h" -#include "formats/sc3000_bit.h" #include "formats/sf7000_dsk.h" -#include "imagedev/cassette.h" #include "imagedev/printer.h" #include "bus/centronics/ctronics.h" #include "machine/i8255.h" #include "machine/i8251.h" #include "machine/ram.h" #include "bus/sega8/sega8_slot.h" +#include "bus/sg1000_exp/sg1000exp.h" #include "machine/upd765.h" #include "sound/sn76496.h" #include "video/tms9928a.h" @@ -25,15 +24,14 @@ #define UPD765_TAG "upd765" #define UPD8251_TAG "upd8251" #define UPD9255_TAG "upd9255" -#define UPD9255_0_TAG "upd9255_0" -#define UPD9255_1_TAG "upd9255_1" +#define UPD9255_1_TAG "upd9255_1" // "upd9255_0" is being used by sk1100 device #define CENTRONICS_TAG "centronics" #define TMS9918A_TAG "tms9918a" #define RS232_TAG "rs232" #define CARTSLOT_TAG "slot" +#define EXPSLOT_TAG "sgexp" -INPUT_PORTS_EXTERN( sk1100 ); class sg1000_state : public driver_device { @@ -48,75 +46,38 @@ public: m_maincpu(*this, Z80_TAG), m_ram(*this, RAM_TAG), m_rom(*this, Z80_TAG), - m_cart(*this, CARTSLOT_TAG) + m_cart(*this, CARTSLOT_TAG), + m_sgexpslot(*this, EXPSLOT_TAG), + m_pa7(*this, "PA7"), + m_pb7(*this, "PB7") { } required_device m_maincpu; required_device m_ram; required_memory_region m_rom; optional_device m_cart; + optional_device m_sgexpslot; + required_ioport m_pa7; + required_ioport m_pb7; virtual void machine_start() override; - DECLARE_READ8_MEMBER( joysel_r ); + DECLARE_READ8_MEMBER( peripheral_r ); + DECLARE_WRITE8_MEMBER( peripheral_w ); DECLARE_INPUT_CHANGED_MEMBER( trigger_nmi ); DECLARE_READ8_MEMBER( omv_r ); DECLARE_WRITE8_MEMBER( omv_w ); - - /* keyboard state */ - UINT8 m_keylatch; }; class sc3000_state : public sg1000_state { public: sc3000_state(const machine_config &mconfig, device_type type, const char *tag) - : sg1000_state(mconfig, type, tag), - m_cassette(*this, "cassette"), - m_pa0(*this, "PA0"), - m_pa1(*this, "PA1"), - m_pa2(*this, "PA2"), - m_pa3(*this, "PA3"), - m_pa4(*this, "PA4"), - m_pa5(*this, "PA5"), - m_pa6(*this, "PA6"), - m_pa7(*this, "PA7"), - m_pb0(*this, "PB0"), - m_pb1(*this, "PB1"), - m_pb2(*this, "PB2"), - m_pb3(*this, "PB3"), - m_pb4(*this, "PB4"), - m_pb5(*this, "PB5"), - m_pb6(*this, "PB6"), - m_pb7(*this, "PB7") + : sg1000_state(mconfig, type, tag) { } - required_device m_cassette; - required_ioport m_pa0; - required_ioport m_pa1; - required_ioport m_pa2; - required_ioport m_pa3; - required_ioport m_pa4; - required_ioport m_pa5; - required_ioport m_pa6; - required_ioport m_pa7; - required_ioport m_pb0; - required_ioport m_pb1; - required_ioport m_pb2; - required_ioport m_pb3; - required_ioport m_pb4; - required_ioport m_pb5; - required_ioport m_pb6; - required_ioport m_pb7; - - virtual void machine_start() override; - - DECLARE_READ8_MEMBER( ppi_pa_r ); - DECLARE_READ8_MEMBER( ppi_pb_r ); - DECLARE_WRITE8_MEMBER( ppi_pc_w ); - - ioport_port* m_key_row[16]; + virtual void machine_start() override; }; class sf7000_state : public sc3000_state diff --git a/src/mame/includes/sms.h b/src/mame/includes/sms.h index 259a3f6fd65..2d16c1f9a2c 100644 --- a/src/mame/includes/sms.h +++ b/src/mame/includes/sms.h @@ -22,6 +22,7 @@ #define CONTROL2_TAG "ctrl2" #include "bus/sega8/sega8_slot.h" +#include "bus/sg1000_exp/sg1000exp.h" #include "bus/sms_exp/smsexp.h" #include "bus/sms_ctrl/smsctrl.h" #include "bus/gamegear/ggext.h" @@ -44,6 +45,7 @@ public: m_port_gg_dc(*this, "GG_PORT_DC"), m_port_pause(*this, "PAUSE"), m_port_reset(*this, "RESET"), + m_port_rapid(*this, "RAPID"), m_port_start(*this, "START"), m_port_scope(*this, "SEGASCOPE"), m_port_scope_binocular(*this, "SSCOPE_BINOCULAR"), @@ -51,14 +53,13 @@ public: m_region_maincpu(*this, "maincpu"), m_mainram(nullptr), m_is_gamegear(0), - m_is_gg_region_japan(0), m_is_smsj(0), m_is_mark_iii(0), m_is_sdisp(0), + m_ioctrl_region_is_japan(0), m_has_bios_0400(0), m_has_bios_2000(0), m_has_bios_full(0), - m_has_fm(0), m_has_jpn_sms_cart_slot(0), m_store_cart_selection_data(0) { } @@ -76,6 +77,7 @@ public: optional_ioport m_port_gg_dc; optional_ioport m_port_pause; optional_ioport m_port_reset; + optional_ioport m_port_rapid; optional_ioport m_port_start; optional_ioport m_port_scope; optional_ioport m_port_scope_binocular; @@ -104,14 +106,13 @@ public: // model identifiers UINT8 m_is_gamegear; - UINT8 m_is_gg_region_japan; UINT8 m_is_smsj; UINT8 m_is_mark_iii; UINT8 m_is_sdisp; + UINT8 m_ioctrl_region_is_japan; UINT8 m_has_bios_0400; UINT8 m_has_bios_2000; UINT8 m_has_bios_full; - UINT8 m_has_fm; UINT8 m_has_jpn_sms_cart_slot; // [0] for 0x400-0x3fff, [1] for 0x4000-0x7fff, [2] for 0x8000-0xffff, [3] for 0x0000-0x0400 @@ -122,7 +123,7 @@ public: UINT8 m_io_ctrl_reg; UINT8 m_mem_ctrl_reg; UINT8 m_mem_device_enabled; - UINT8 m_audio_control; + UINT8 m_smsj_audio_control; UINT8 m_port_dc_reg; UINT8 m_port_dd_reg; UINT8 m_gg_sio[5]; @@ -140,10 +141,18 @@ public: UINT8 m_sscope_state; UINT8 m_frame_sscope_state; + // Data needed for Rapid button (smsj, sms1kr, sms1krfm) + UINT16 m_csync_counter; + UINT8 m_rapid_mode; + UINT8 m_rapid_read_state; + UINT8 m_rapid_last_dc; + UINT8 m_rapid_last_dd; + // slot devices sega8_cart_slot_device *m_cartslot; sega8_card_slot_device *m_cardslot; - sms_expansion_slot_device *m_expslot; + sms_expansion_slot_device *m_smsexpslot; + sg1000_expansion_slot_device *m_sgexpslot; // these are only used by the Store Display unit, but we keep them here temporarily to avoid the need of separate start/reset sega8_cart_slot_device *m_slots[16]; @@ -168,19 +177,22 @@ public: DECLARE_READ8_MEMBER(sms_input_port_dc_r); DECLARE_READ8_MEMBER(sms_input_port_dd_r); DECLARE_READ8_MEMBER(gg_input_port_00_r); + DECLARE_READ8_MEMBER(sg1000m3_peripheral_r); + DECLARE_WRITE8_MEMBER(sg1000m3_peripheral_w); DECLARE_READ8_MEMBER(gg_sio_r); DECLARE_WRITE8_MEMBER(gg_sio_w); DECLARE_WRITE8_MEMBER(gg_psg_stereo_w); DECLARE_WRITE8_MEMBER(gg_psg_w); DECLARE_WRITE8_MEMBER(sms_psg_w); - DECLARE_READ8_MEMBER(sms_audio_control_r); - DECLARE_WRITE8_MEMBER(sms_audio_control_w); - DECLARE_WRITE8_MEMBER(sms_ym2413_register_port_w); - DECLARE_WRITE8_MEMBER(sms_ym2413_data_port_w); + DECLARE_READ8_MEMBER(smsj_audio_control_r); + DECLARE_WRITE8_MEMBER(smsj_audio_control_w); + DECLARE_WRITE8_MEMBER(smsj_ym2413_register_port_w); + DECLARE_WRITE8_MEMBER(smsj_ym2413_data_port_w); DECLARE_READ8_MEMBER(sms_sscope_r); DECLARE_WRITE8_MEMBER(sms_sscope_w); DECLARE_WRITE_LINE_MEMBER(sms_pause_callback); + DECLARE_WRITE_LINE_MEMBER(sms_csync_callback); DECLARE_WRITE_LINE_MEMBER(sms_ctrl1_th_input); DECLARE_WRITE_LINE_MEMBER(sms_ctrl2_th_input); DECLARE_WRITE_LINE_MEMBER(gg_ext_th_input); @@ -194,6 +206,7 @@ public: DECLARE_DRIVER_INIT(smskr); DECLARE_DRIVER_INIT(smsj); DECLARE_DRIVER_INIT(sms1); + DECLARE_DRIVER_INIT(sms); DECLARE_MACHINE_START(sms); DECLARE_MACHINE_RESET(sms); DECLARE_VIDEO_START(gamegear); diff --git a/src/mame/machine/sms.cpp b/src/mame/machine/sms.cpp index 8244b542759..8941b2513f2 100644 --- a/src/mame/machine/sms.cpp +++ b/src/mame/machine/sms.cpp @@ -250,6 +250,69 @@ WRITE_LINE_MEMBER(sms_state::sms_pause_callback) } +WRITE_LINE_MEMBER(sms_state::sms_csync_callback) +{ + if ( m_port_rapid ) + { + UINT8 rapid_previous_mode = m_rapid_mode; + + m_csync_counter++; + // counter is 12 bits wide (for 4096 pulses) + m_csync_counter &= 0xfff; + + if (!(m_port_rapid->read() & 0x01)) // Rapid button is pressed + { + sms_get_inputs(); + + if (m_port_dc_reg != m_rapid_last_dc) + { + // Enable/disable rapid fire for any joypad button pressed. + m_rapid_mode ^= (~m_port_dc_reg & 0x30) >> 4; + m_rapid_last_dc = m_port_dc_reg; + } + if (m_port_dd_reg != m_rapid_last_dd) + { + // Enable/disable rapid fire for any joypad button pressed. + m_rapid_mode ^= (~m_port_dd_reg & 0x0c); + m_rapid_last_dd = m_port_dd_reg; + } + } + else // Rapid button is not pressed + { + m_rapid_last_dc = 0xff; + m_rapid_last_dd = 0xff; + } + + if ((m_rapid_mode & 0x0f) != 0) // Rapid Fire enabled for a button + { + // Timings for Rapid Fire and LED verified by Charles MacDonald. + + // Read state is changed at each 256 C-Sync pulses + if ((m_csync_counter & 0xff) == 0) + { + m_rapid_read_state ^= 0xff; + } + + // Power LED blinks while Rapid Fire is enabled. + // It switches between on/off at each 2048 C-Sync pulses. + if ((m_csync_counter & 0x7ff) == 0) + { + output().set_led_value(0, !output().get_led_value(0)); + } + } + else // Rapid Fire disabled + { + if ((rapid_previous_mode & 0x0f) != 0) // it was enabled + { + m_rapid_read_state = 0x00; + // Power LED remains lit again + output().set_led_value(0, 1); + } + } + } +} + + READ8_MEMBER(sms_state::sms_input_port_dc_r) { if (m_is_mark_iii) @@ -282,6 +345,17 @@ READ8_MEMBER(sms_state::sms_input_port_dc_r) m_port_dc_reg &= ~0x20 | ((m_io_ctrl_reg & 0x10) << 1); } + if ( m_port_rapid ) + { + // Check if Rapid Fire is enabled for Button 1 + if (m_rapid_mode & 0x01) + m_port_dc_reg |= m_rapid_read_state & 0x10; + + // Check if Rapid Fire is enabled for Button 2 + if (m_rapid_mode & 0x02) + m_port_dc_reg |= m_rapid_read_state & 0x20; + } + return m_port_dc_reg; } @@ -325,7 +399,7 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r) // Check if TH of controller port 1 is set to output (0) if (!(m_io_ctrl_reg & 0x02)) { - if (m_is_smsj || (m_is_gamegear && m_is_gg_region_japan)) + if (m_ioctrl_region_is_japan) { m_port_dd_reg &= ~0x40; } @@ -347,7 +421,7 @@ 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_smsj || (m_is_gamegear && m_is_gg_region_japan)) + if (m_ioctrl_region_is_japan) { m_port_dd_reg &= ~0x80; } @@ -366,73 +440,69 @@ READ8_MEMBER(sms_state::sms_input_port_dd_r) } } + if ( m_port_rapid ) + { + // Check if Rapid Fire is enabled for Button 1 + if (m_rapid_mode & 0x04) + m_port_dd_reg |= m_rapid_read_state & 0x04; + + // Check if Rapid Fire is enabled for Button 2 + if (m_rapid_mode & 0x08) + m_port_dd_reg |= m_rapid_read_state & 0x08; + } + return m_port_dd_reg; } -WRITE8_MEMBER(sms_state::sms_audio_control_w) +WRITE8_MEMBER(sms_state::smsj_audio_control_w) { - if (m_has_fm) - { - if (m_is_smsj) - m_audio_control = data & 0x03; - else - m_audio_control = data & 0x01; - } + m_smsj_audio_control = data & 0x03; } -READ8_MEMBER(sms_state::sms_audio_control_r) +READ8_MEMBER(sms_state::smsj_audio_control_r) { - if (m_has_fm) - { - if (m_is_smsj) - { - /* Charles MacDonald discovered an internal 12-bit counter that is - incremented on each pulse of the C-Sync line that connects the VDP - with the 315-5297. Only 3 bits of the counter are returned when - read this port: + UINT8 data; - D7 : Counter bit 11 - D6 : Counter bit 7 - D5 : Counter bit 3 - D4 : Always zero - D3 : Always zero - D2 : Always zero - D1 : Mute control bit 1 - D0 : Mute control bit 0 + /* Charles MacDonald discovered an internal 12-bit counter that is + incremented on each pulse of the C-Sync line that connects the VDP + with the 315-5297. Only 3 bits of the counter are returned when + read this port: - For the moment, only the mute bits are handled by this code. - */ - return m_audio_control & 0x03; - } - else - return m_audio_control & 0x01; - } - else - return sms_input_port_dc_r(space, offset); + D7 : Counter bit 11 + D6 : Counter bit 7 + D5 : Counter bit 3 + D4 : Always zero + D3 : Always zero + D2 : Always zero + D1 : Mute control bit 1 + D0 : Mute control bit 0 + + */ + data = 0x00; + data |= (m_smsj_audio_control & 0x03); + data |= (m_csync_counter & 0x008) << 2; + data |= (m_csync_counter & 0x080) >> 1; + data |= (m_csync_counter & 0x800) >> 4; + + return data; } -WRITE8_MEMBER(sms_state::sms_ym2413_register_port_w) +WRITE8_MEMBER(sms_state::smsj_ym2413_register_port_w) { - if (m_has_fm) - { - if (m_audio_control == 0x01 || m_audio_control == 0x03) - m_ym->write(space, 0, data & 0x3f); - } + if (m_smsj_audio_control == 0x01 || m_smsj_audio_control == 0x03) + m_ym->write(space, 0, data & 0x3f); } -WRITE8_MEMBER(sms_state::sms_ym2413_data_port_w) +WRITE8_MEMBER(sms_state::smsj_ym2413_data_port_w) { - if (m_has_fm) + if (m_smsj_audio_control == 0x01 || m_smsj_audio_control == 0x03) { - if (m_audio_control == 0x01 || m_audio_control == 0x03) - { - //logerror("data_port_w %x %x\n", offset, data); - m_ym->write(space, 1, data); - } + //logerror("data_port_w %x %x\n", offset, data); + m_ym->write(space, 1, data); } } @@ -441,7 +511,7 @@ WRITE8_MEMBER(sms_state::sms_psg_w) { if (m_is_smsj) { - if (m_audio_control != 0x00 && m_audio_control != 0x03) + if (m_smsj_audio_control != 0x00 && m_smsj_audio_control != 0x03) return; } @@ -471,7 +541,7 @@ READ8_MEMBER(sms_state::gg_input_port_00_r) else { // bit 6 is NJAP (0=domestic/1=overseas); bit 7 is STT (START button) - UINT8 data = (m_is_gg_region_japan ? 0x00 : 0x40) | (m_port_start->read() & 0x80); + UINT8 data = (m_ioctrl_region_is_japan ? 0x00 : 0x40) | (m_port_start->read() & 0x80); // According to GG official docs, bits 0-4 are meaningless and bit 5 // is NNTS (0=NTSC, 1=PAL). All games run in NTSC and no original GG @@ -488,6 +558,9 @@ READ8_MEMBER(sms_state::sms_sscope_r) { int sscope = m_port_scope->read(); + // On SMSJ, address $fffb also controls the built-in 3-D port, that works + // in parallel with the 3-D adapter that is inserted into the card slot. + if ( sscope ) { // Scope is attached @@ -513,7 +586,8 @@ WRITE8_MEMBER(sms_state::sms_sscope_w) // active screen. Most cases are solid-color frames of scene transitions, but // one exception is the first frame of Zaxxon 3-D's title screen. In that // case, this method is enough for setting the intended state for the frame. - // No information found about a minimum time need for switch open/closed lens. + // According to Charles MacDonald: "It takes around 10 scanlines for the + // display to transition from fully visible to fully obscured by the shutter". if (m_main_scr->vpos() < (m_main_scr->height() >> 1)) { m_frame_sscope_state = m_sscope_state; @@ -533,7 +607,7 @@ READ8_MEMBER(sms_state::read_ram) if (m_mem_device_enabled & ENABLE_CARD) data &= m_cardslot->read_ram(space, offset); if (m_mem_device_enabled & ENABLE_EXPANSION) - data &= m_expslot->read_ram(space, offset); + data &= m_smsexpslot->read_ram(space, offset); return data; } @@ -553,7 +627,7 @@ WRITE8_MEMBER(sms_state::write_ram) if (m_mem_device_enabled & ENABLE_CARD) m_cardslot->write_ram(space, offset, data); if (m_mem_device_enabled & ENABLE_EXPANSION) - m_expslot->write_ram(space, offset, data); + m_smsexpslot->write_ram(space, offset, data); } else { @@ -593,7 +667,7 @@ WRITE8_MEMBER(sms_state::sms_mapper_w) } if (m_mem_device_enabled & ENABLE_EXPANSION) // expansion slot { - m_expslot->write_mapper(space, offset, data); + m_smsexpslot->write_mapper(space, offset, data); } break; @@ -617,7 +691,7 @@ WRITE8_MEMBER(sms_state::sms_mapper_w) } if (m_mem_device_enabled & ENABLE_EXPANSION) { - m_expslot->write_mapper(space, offset, data); + m_smsexpslot->write_mapper(space, offset, data); } break; } @@ -655,7 +729,7 @@ UINT8 sms_state::read_bus(address_space &space, unsigned int page, UINT16 base_a if (m_mem_device_enabled & ENABLE_CARD) data &= m_cardslot->read_cart(space, base_addr + offset); if (m_mem_device_enabled & ENABLE_EXPANSION) - data &= m_expslot->read(space, base_addr + offset); + data &= m_smsexpslot->read(space, base_addr + offset); return data; } @@ -692,7 +766,7 @@ WRITE8_MEMBER(sms_state::write_cart) if (m_mem_device_enabled & ENABLE_CARD) m_cardslot->write_cart(space, offset, data); if (m_mem_device_enabled & ENABLE_EXPANSION) - m_expslot->write(space, offset, data); + m_smsexpslot->write(space, offset, data); } @@ -723,6 +797,35 @@ WRITE8_MEMBER(sms_state::sms_mem_control_w) } +READ8_MEMBER(sms_state::sg1000m3_peripheral_r) +{ + bool joy_ports_disabled = m_sgexpslot->is_readable(offset); + + if (joy_ports_disabled) + { + return m_sgexpslot->read(space, offset); + } + else + { + if (offset & 0x01) + return sms_input_port_dd_r(space, offset); + else + return sms_input_port_dc_r(space, offset); + } +} + + +WRITE8_MEMBER(sms_state::sg1000m3_peripheral_w) +{ + bool joy_ports_disabled = m_sgexpslot->is_writeable(offset); + + if (joy_ports_disabled) + { + m_sgexpslot->write(space, offset, data); + } +} + + WRITE8_MEMBER(sms_state::gg_sio_w) { if (m_cartslot->exists() && m_cartslot->m_cart->get_sms_mode()) @@ -803,7 +906,7 @@ void sms_state::setup_enabled_slots() return; } - if (!(m_mem_ctrl_reg & IO_EXPANSION) && m_expslot && m_expslot->m_device) + if (!(m_mem_ctrl_reg & IO_EXPANSION) && m_smsexpslot && m_smsexpslot->m_device) { m_mem_device_enabled |= ENABLE_EXPANSION; logerror("Expansion port enabled.\n"); @@ -864,7 +967,7 @@ void sms_state::setup_media_slots() else if (m_mem_device_enabled & ENABLE_CARD) m_lphaser_x_offs = m_cardslot->m_cart->get_lphaser_xoffs(); else if (m_mem_device_enabled & ENABLE_EXPANSION) - m_lphaser_x_offs = m_expslot->m_device->get_lphaser_xoffs(); + m_lphaser_x_offs = m_smsexpslot->m_device->get_lphaser_xoffs(); if (m_lphaser_x_offs == -1) m_lphaser_x_offs = 36; @@ -913,7 +1016,8 @@ MACHINE_START_MEMBER(sms_state,sms) m_cartslot = machine().device("slot"); m_cardslot = machine().device("mycard"); - m_expslot = machine().device("exp"); + m_smsexpslot = machine().device("smsexp"); + m_sgexpslot = machine().device("sgexp"); m_space = &m_maincpu->space(AS_PROGRAM); if (m_mainram == nullptr) @@ -945,9 +1049,18 @@ MACHINE_START_MEMBER(sms_state,sms) save_item(NAME(m_port_dd_reg)); save_item(NAME(m_mem_device_enabled)); - if (m_has_fm) + if (m_is_smsj) { - save_item(NAME(m_audio_control)); + save_item(NAME(m_smsj_audio_control)); + } + + if (m_port_rapid) + { + save_item(NAME(m_csync_counter)); + save_item(NAME(m_rapid_mode)); + save_item(NAME(m_rapid_read_state)); + save_item(NAME(m_rapid_last_dc)); + save_item(NAME(m_rapid_last_dd)); } if (!m_is_mark_iii) @@ -993,8 +1106,21 @@ MACHINE_START_MEMBER(sms_state,sms) MACHINE_RESET_MEMBER(sms_state,sms) { - if (m_has_fm) - m_audio_control = 0x00; + if (m_is_smsj) + { + m_smsj_audio_control = 0x00; + } + + if (m_port_rapid) + { + m_csync_counter = 0; + m_rapid_mode = 0x00; + m_rapid_read_state = 0; + m_rapid_last_dc = 0xff; + m_rapid_last_dd = 0xff; + // Power LED remains lit again + output().set_led_value(0, 1); + } if (!m_is_mark_iii) { @@ -1111,14 +1237,23 @@ WRITE_LINE_MEMBER(smssdisp_state::sms_store_int_callback) DRIVER_INIT_MEMBER(sms_state,sg1000m3) { m_is_mark_iii = 1; - m_has_fm = 1; m_has_jpn_sms_cart_slot = 1; + // turn on the Power LED + output().set_led_value(0, 1); +} + + +DRIVER_INIT_MEMBER(sms_state,sms) +{ + m_has_bios_full = 1; } DRIVER_INIT_MEMBER(sms_state,sms1) { m_has_bios_full = 1; + // turn on the Power LED + output().set_led_value(0, 1); } @@ -1126,15 +1261,20 @@ DRIVER_INIT_MEMBER(sms_state,smsj) { m_is_smsj = 1; m_has_bios_2000 = 1; - m_has_fm = 1; + m_ioctrl_region_is_japan = 1; m_has_jpn_sms_cart_slot = 1; + // turn on the Power LED + output().set_led_value(0, 1); } DRIVER_INIT_MEMBER(sms_state,sms1kr) { m_has_bios_2000 = 1; + m_ioctrl_region_is_japan = 1; m_has_jpn_sms_cart_slot = 1; + // turn on the Power LED + output().set_led_value(0, 1); } @@ -1156,6 +1296,8 @@ DRIVER_INIT_MEMBER(sms_state,gamegear) { m_is_gamegear = 1; m_has_bios_0400 = 1; + // turn on the Power LED + output().set_led_value(0, 1); } @@ -1163,7 +1305,9 @@ DRIVER_INIT_MEMBER(sms_state,gamegeaj) { m_is_gamegear = 1; m_has_bios_0400 = 1; - m_is_gg_region_japan = 1; + m_ioctrl_region_is_japan = 1; + // turn on the Power LED + output().set_led_value(0, 1); } diff --git a/src/mame/mame.lst b/src/mame/mame.lst index 7136e82801b..c3c4c0b883a 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -33276,12 +33276,18 @@ gamegear // Sega GameGear sg1000m3 // Sega SG-1000 Mark III (Japan) sms // Sega Master System II (NTSC) sms1 // Sega Master System I (NTSC) +sms1br // Tec Toy Master System I (Brazil) sms1kr // Samsung Gam*Boy I (Korea) sms1krfm // Samsung Gam*Boy I (Korea) with FM Chip sms1pal // Sega Master System I (PAL) +sms1paln // Tec Toy Master System I (PAL-N) +sms2br // Tec Toy Master System II (Brazil) +sms2paln // Tec Toy Master System II (PAL-N) +smsbr // Tec Toy Master System III Compact (Brazil) smsj // Sega Master System (Japan) with FM Chip smskr // Samsung Gam*Boy II (Korea) smspal // Sega Master System II (PAL) +smspaln // Tec Toy Master System III Compact (PAL-N) smssdisp // Sega Master System Store Display Unit @source:smsmcorp.cpp