coleco: Add expansion bus and support for the Super Game Module

This obsoletes PR#10816. Thanks to 0kmg for the initial implementation.
This commit is contained in:
Dirk Best 2024-04-13 17:01:24 +02:00
parent c0e8399c43
commit ad7fdda12b
8 changed files with 395 additions and 0 deletions

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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<device_coleco_expansion_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<coleco_expansion_device *>(device.owner());
}
device_coleco_expansion_interface::~device_coleco_expansion_interface()
{
}

View File

@ -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<device_coleco_expansion_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 <typename T> void set_program_space(T &&tag, int spacenum) { m_program.set_tag(std::forward<T>(tag), spacenum); }
template <typename T> void set_io_space(T &&tag, int spacenum) { m_io.set_tag(std::forward<T>(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

View File

@ -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<uint8_t []>(0x2000);
m_ram_upper = std::make_unique<uint8_t []>(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);
}

View File

@ -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<uint8_t []> m_ram_lower;
std::unique_ptr<uint8_t []> 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

View File

@ -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
}