From ad7fdda12b4cade7032a0e34c3f6ae6dd3964cfa Mon Sep 17 00:00:00 2001 From: Dirk Best Date: Sat, 13 Apr 2024 17:01:24 +0200 Subject: coleco: Add expansion bus and support for the Super Game Module This obsoletes PR#10816. Thanks to 0kmg for the initial implementation. --- scripts/src/bus.lua | 17 ++++ src/devices/bus/coleco/expansion/cards.cpp | 18 ++++ src/devices/bus/coleco/expansion/cards.h | 16 ++++ src/devices/bus/coleco/expansion/expansion.cpp | 60 ++++++++++++ src/devices/bus/coleco/expansion/expansion.h | 123 +++++++++++++++++++++++++ src/devices/bus/coleco/expansion/sgm.cpp | 101 ++++++++++++++++++++ src/devices/bus/coleco/expansion/sgm.h | 48 ++++++++++ src/mame/coleco/coleco.cpp | 12 +++ 8 files changed, 395 insertions(+) create mode 100644 src/devices/bus/coleco/expansion/cards.cpp create mode 100644 src/devices/bus/coleco/expansion/cards.h create mode 100644 src/devices/bus/coleco/expansion/expansion.cpp create mode 100644 src/devices/bus/coleco/expansion/expansion.h create mode 100644 src/devices/bus/coleco/expansion/sgm.cpp create mode 100644 src/devices/bus/coleco/expansion/sgm.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 2ae59a041cc..ed8419d7b6c 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1190,6 +1190,23 @@ if (BUSES["COLECO_CART"]~=null) then end +--------------------------------------------------- +-- +--@src/devices/bus/coleco/expansion/expansion.h,BUSES["COLECO_EXPANSION"] = true +--------------------------------------------------- + +if (BUSES["COLECO_EXPANSION"]~=null) then + files { + MAME_DIR .. "src/devices/bus/coleco/expansion/expansion.cpp", + MAME_DIR .. "src/devices/bus/coleco/expansion/expansion.h", + MAME_DIR .. "src/devices/bus/coleco/expansion/cards.cpp", + MAME_DIR .. "src/devices/bus/coleco/expansion/cards.h", + MAME_DIR .. "src/devices/bus/coleco/expansion/sgm.cpp", + MAME_DIR .. "src/devices/bus/coleco/expansion/sgm.h", + } +end + + --------------------------------------------------- -- --@src/devices/bus/crvision/slot.h,BUSES["CRVISION"] = true diff --git a/src/devices/bus/coleco/expansion/cards.cpp b/src/devices/bus/coleco/expansion/cards.cpp new file mode 100644 index 00000000000..5789b370456 --- /dev/null +++ b/src/devices/bus/coleco/expansion/cards.cpp @@ -0,0 +1,18 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Colecovision Expansion Slot cards + +***************************************************************************/ + +#include "emu.h" +#include "cards.h" + +#include "sgm.h" + + +void coleco_expansion_cards(device_slot_interface &device) +{ + device.option_add("sgm", COLECO_SGM); +} diff --git a/src/devices/bus/coleco/expansion/cards.h b/src/devices/bus/coleco/expansion/cards.h new file mode 100644 index 00000000000..08577a2cba9 --- /dev/null +++ b/src/devices/bus/coleco/expansion/cards.h @@ -0,0 +1,16 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Colecovision Expansion Slot cards + +***************************************************************************/ + +#ifndef MAME_BUS_COlECO_EXPANSION_CARDS_H +#define MAME_BUS_COlECO_EXPANSION_CARDS_H + +#pragma once + +void coleco_expansion_cards(device_slot_interface &device); + +#endif // MAME_BUS_COlECO_EXPANSION_CARDS_H diff --git a/src/devices/bus/coleco/expansion/expansion.cpp b/src/devices/bus/coleco/expansion/expansion.cpp new file mode 100644 index 00000000000..87223699c2b --- /dev/null +++ b/src/devices/bus/coleco/expansion/expansion.cpp @@ -0,0 +1,60 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Colecovision Expansion Slot + + 60-pin slot + +***************************************************************************/ + +#include "emu.h" +#include "expansion.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(COLECO_EXPANSION, coleco_expansion_device, "coleco_expansion", "Colecovision Expansion Bus") + + +//************************************************************************** +// SLOT DEVICE +//************************************************************************** + +coleco_expansion_device::coleco_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, COLECO_EXPANSION, tag, owner, clock), + device_single_card_slot_interface(mconfig, *this), + m_program(*this, finder_base::DUMMY_TAG, -1), + m_io(*this, finder_base::DUMMY_TAG, -1), + m_int_handler(*this), + m_nmi_handler(*this), + m_card(nullptr) +{ +} + +coleco_expansion_device::~coleco_expansion_device() +{ +} + +void coleco_expansion_device::device_start() +{ + // get inserted card + m_card = get_card_device(); +} + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +device_coleco_expansion_interface::device_coleco_expansion_interface(const machine_config &mconfig, device_t &device) : + device_interface(device, "colecoexp") +{ + m_expansion = dynamic_cast(device.owner()); +} + +device_coleco_expansion_interface::~device_coleco_expansion_interface() +{ +} diff --git a/src/devices/bus/coleco/expansion/expansion.h b/src/devices/bus/coleco/expansion/expansion.h new file mode 100644 index 00000000000..421a2ab70d7 --- /dev/null +++ b/src/devices/bus/coleco/expansion/expansion.h @@ -0,0 +1,123 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Colecovision Expansion Slot + + 60-pin slot + + 1 GND 60 -5V + 2 GND 59 +5V + 3 D3 58 +5V + 4 A14 57 +12V + 5 EN40 56 AUDOUT + 6 EN20 55 IORQ + 7 HALT 54 MREQ + 8 WR 53 RD + 9 NMI 52 BUSACK + 10 FX-9 51 INT + 11 BUSREQ 50 WAIT + 12 D1 49 RFSH + 13 RESET 48 D5 + 14 D0 47 A0 + 15 M1 46 D5 + 16 D2 45 CPUCLK + 17 D6 44 A3 + 18 A1 43 A15 + 19 D4 42 N/C + 20 A2 41 N/C + 21 A4 40 CPUCLK + 22 A13 39 EXVDCRST + 23 A5 38 A12 + 24 A8 37 A11 + 25 A7 36 EXRES2 + 26 A8 35 AUDCLK + 27 A9 34 EXRES1 + 28 A10 33 EXVID + 29 N/C 32 EXVIDEN + 30 N/C 31 EXAUD + +***************************************************************************/ + +#ifndef MAME_BUS_COlECO_EXPANSION_EXPANSION_H +#define MAME_BUS_COlECO_EXPANSION_EXPANSION_H + +#pragma once + +// include here so drivers don't need to +#include "cards.h" + +// forward declaration +class device_coleco_expansion_interface; + + +//************************************************************************** +// BUS DEVICE +//************************************************************************** + +class coleco_expansion_device : public device_t, public device_single_card_slot_interface +{ +public: + // construction/destruction + coleco_expansion_device(machine_config const &mconfig, char const *tag, device_t *owner, const char *dflt) : + coleco_expansion_device(mconfig, tag, owner, uint32_t(0)) + { + option_reset(); + coleco_expansion_cards(*this); + set_default_option(dflt); + set_fixed(false); + } + + coleco_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + virtual ~coleco_expansion_device(); + + template void set_program_space(T &&tag, int spacenum) { m_program.set_tag(std::forward(tag), spacenum); } + template void set_io_space(T &&tag, int spacenum) { m_io.set_tag(std::forward(tag), spacenum); } + + // callbacks + auto int_handler() { return m_int_handler.bind(); } + auto nmi_handler() { return m_nmi_handler.bind(); } + + // called from card device + void int_w(int state) { m_int_handler(state); } + void nmi_w(int state) { m_nmi_handler(state); } + + address_space &mem_space() { return *m_program; } + address_space &io_space() { return *m_io; } + +protected: + // device-level overrides + virtual void device_start() override; + +private: + required_address_space m_program; + required_address_space m_io; + + devcb_write_line m_int_handler; + devcb_write_line m_nmi_handler; + + device_coleco_expansion_interface *m_card; +}; + + +//************************************************************************** +// CARD INTERFACE +//************************************************************************** + +class device_coleco_expansion_interface : public device_interface +{ +public: + virtual ~device_coleco_expansion_interface(); + +protected: + device_coleco_expansion_interface(const machine_config &mconfig, device_t &device); + + coleco_expansion_device *m_expansion; +}; + + +// device type declaration +DECLARE_DEVICE_TYPE(COLECO_EXPANSION, coleco_expansion_device) + + +#endif // MAME_BUS_COlECO_EXPANSION_EXPANSION_H diff --git a/src/devices/bus/coleco/expansion/sgm.cpp b/src/devices/bus/coleco/expansion/sgm.cpp new file mode 100644 index 00000000000..8f074c3e2a9 --- /dev/null +++ b/src/devices/bus/coleco/expansion/sgm.cpp @@ -0,0 +1,101 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Opcode Super Game Module + +***************************************************************************/ + +#include "emu.h" +#include "sgm.h" +#include "sound/ay8910.h" +#include "speaker.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(COLECO_SGM, coleco_sgm_device, "coleco_sgm", "Opcode Super Game Module") + +coleco_sgm_device::coleco_sgm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : + device_t(mconfig, COLECO_SGM, tag, owner, clock), + device_coleco_expansion_interface(mconfig, *this), + m_view_lower(*this, "view_lower"), + m_view_upper(*this, "view_upper") +{ +} + + +//************************************************************************** +// ADDRESS MAPS +//************************************************************************** + +void coleco_sgm_device::io_map(address_map &map) +{ + map(0x50, 0x50).w("ay", FUNC(ay8910_device::address_w)); + map(0x51, 0x51).w("ay", FUNC(ay8910_device::data_w)); + map(0x52, 0x52).r("ay", FUNC(ay8910_device::data_r)); + map(0x53, 0x53).w(FUNC(coleco_sgm_device::upper_enable_w)); + map(0x7f, 0x7f).w(FUNC(coleco_sgm_device::lower_enable_w)); +} + + +//************************************************************************** +// MACHINE DEFINITIONS +//************************************************************************** + +void coleco_sgm_device::device_add_mconfig(machine_config &config) +{ + SPEAKER(config, "mono").front_center(); + + ay8910_device &ay(AY8910(config, "ay", 7.15909_MHz_XTAL / 4)); + ay.add_route(ALL_OUTPUTS, "mono", 1.00); +} + + +//************************************************************************** +// MACHINE EMULATION +//************************************************************************** + +void coleco_sgm_device::device_start() +{ + // allocate memory for ram + m_ram_lower = std::make_unique(0x2000); + m_ram_upper = std::make_unique(0x6000); + + // register for save states + save_pointer(NAME(m_ram_lower), 0x2000); + save_pointer(NAME(m_ram_upper), 0x6000); + + // install device into memory map + m_expansion->io_space().install_device(0x00, 0x7f, *this, coleco_sgm_device::io_map); + + m_expansion->mem_space().install_view(0x0000, 0x1fff, m_view_lower); + m_view_lower[0].install_ram(0x0000, 0x1fff, &m_ram_lower[0]); + + m_expansion->mem_space().install_view(0x2000, 0x7fff, m_view_upper); + m_view_upper[0].install_ram(0x2000, 0x7fff, &m_ram_upper[0]); +} + +void coleco_sgm_device::device_reset() +{ + m_view_lower.disable(); + m_view_upper.disable(); +} + +void coleco_sgm_device::upper_enable_w(uint8_t data) +{ + if (BIT(data, 0)) + m_view_upper.select(0); + else + m_view_upper.disable(); +} + +void coleco_sgm_device::lower_enable_w(uint8_t data) +{ + if (BIT(data, 1)) + m_view_lower.disable(); + else + m_view_lower.select(0); +} diff --git a/src/devices/bus/coleco/expansion/sgm.h b/src/devices/bus/coleco/expansion/sgm.h new file mode 100644 index 00000000000..cd77dbaa78e --- /dev/null +++ b/src/devices/bus/coleco/expansion/sgm.h @@ -0,0 +1,48 @@ +// license: BSD-3-Clause +// copyright-holders: Dirk Best +/*************************************************************************** + + Colecovision Super Game Module + +***************************************************************************/ + +#ifndef MAME_BUS_COLECO_EXPANSION_SGM_H +#define MAME_BUS_COLECO_EXPANSION_SGM_H + +#pragma once + +#include "expansion.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +class coleco_sgm_device : public device_t, public device_coleco_expansion_interface +{ +public: + // construction/destruction + coleco_sgm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + virtual void device_add_mconfig(machine_config &config) override; + virtual void device_start() override; + virtual void device_reset() override; + +private: + memory_view m_view_lower; + memory_view m_view_upper; + + std::unique_ptr m_ram_lower; + std::unique_ptr m_ram_upper; + + void io_map(address_map &map); + + void upper_enable_w(uint8_t data); + void lower_enable_w(uint8_t data); +}; + +// device type declaration +DECLARE_DEVICE_TYPE(COLECO_SGM, coleco_sgm_device) + +#endif // MAME_BUS_COLECO_EXPANSION_SGM_H diff --git a/src/mame/coleco/coleco.cpp b/src/mame/coleco/coleco.cpp index feacf10b146..8580899cf89 100644 --- a/src/mame/coleco/coleco.cpp +++ b/src/mame/coleco/coleco.cpp @@ -69,7 +69,11 @@ */ #include "emu.h" + #include "coleco.h" + +#include "bus/coleco/expansion/expansion.h" + #include "screen.h" #include "softlist_dev.h" #include "speaker.h" @@ -593,6 +597,12 @@ void coleco_state::coleco(machine_config &config) SOFTWARE_LIST(config, "cart_list").set_original("coleco"); TIMER(config, "paddle_timer").configure_periodic(FUNC(coleco_state::paddle_update_callback), attotime::from_msec(20)); + + coleco_expansion_device &exp(COLECO_EXPANSION(config, "exp", nullptr)); + exp.set_program_space(m_maincpu, AS_PROGRAM); + exp.set_io_space(m_maincpu, AS_IO); + exp.int_handler().set_inputline(m_maincpu, INPUT_LINE_IRQ0); // TODO: Merge with other IRQs? + exp.nmi_handler().set_inputline(m_maincpu, INPUT_LINE_NMI); } void coleco_state::colecop(machine_config &config) @@ -643,6 +653,8 @@ void coleco_state::czz50(machine_config &config) { coleco(config); + config.device_remove("exp"); // this system has a different expansion port + /* basic machine hardware */ m_maincpu->set_addrmap(AS_PROGRAM, &coleco_state::czz50_map); // note: cpu speed unverified, assume it's the same as ColecoVision } -- cgit v1.2.3