coleco/cartridge: Add support for 'Activision' type cartridges

Software list items promoted to working (coleco_homebrew.xml)
-------------------------------------------------------------
The Black Onyx
Boxxle
Space Shuttle: A Journey Into Space (64k)
This commit is contained in:
Dirk Best 2024-04-20 01:21:05 +02:00
parent 54b05196ee
commit 1c5e5b9b43
16 changed files with 269 additions and 34 deletions

View File

@ -136,12 +136,12 @@ Unoffical software releases for the Coleco Colecovision
</part>
</software>
<!-- Needs 'Activison PCB' emulation with EEPROM -->
<software name="blackonx" supported="no">
<software name="blackonx">
<description>The Black Onyx</description>
<year>2013</year>
<publisher>Team Pixelboy</publisher>
<part name="cart" interface="coleco_cart">
<feature name="slot" value="activision_256b" />
<dataarea name="rom" size="65536">
<rom name="black-onyx-the-2013.rom" size="65536" crc="dddd1396" sha1="9bc148c38bd94ba52efa335a08f5c2660b5dbf32" />
</dataarea>
@ -171,12 +171,12 @@ Unoffical software releases for the Coleco Colecovision
</part>
</software>
<!-- Needs 'Activison PCB' emulation with EEPROM -->
<software name="boxxle" supported="no">
<software name="boxxle">
<description>Boxxle</description>
<year>2015</year>
<publisher>Team Pixelboy</publisher>
<part name="cart" interface="coleco_cart">
<feature name="slot" value="activision_32k" />
<dataarea name="rom" size="65536">
<rom name="boxxle-2015.rom" size="65536" crc="62dacf07" sha1="98dc774cb4e954a026a298d2cb91d662f0f484cd" />
</dataarea>
@ -1362,13 +1362,13 @@ Unoffical software releases for the Coleco Colecovision
</part>
</software>
<software name="spacesha" supported="no">
<software name="spacesha">
<description>Space Shuttle: A Journey Into Space (64k)</description>
<year>2022</year>
<publisher>Team Pixelboy</publisher>
<info name="usage" value="req. Super Game Module" />
<part name="cart" interface="coleco_cart">
<feature name="slot" value="megacart" />
<feature name="slot" value="activision" />
<dataarea name="rom" size="65536">
<rom name="space-shuttle-a-journey-into-space-2022.rom" size="65536" crc="bb0f6678" sha1="6365c5f36052202954161007932d328db2d4bb8b" />
</dataarea>

View File

@ -1180,6 +1180,8 @@ if (BUSES["COLECO_CART"]~=null) then
files {
MAME_DIR .. "src/devices/bus/coleco/cartridge/exp.cpp",
MAME_DIR .. "src/devices/bus/coleco/cartridge/exp.h",
MAME_DIR .. "src/devices/bus/coleco/cartridge/activision.cpp",
MAME_DIR .. "src/devices/bus/coleco/cartridge/activision.h",
MAME_DIR .. "src/devices/bus/coleco/cartridge/megacart.cpp",
MAME_DIR .. "src/devices/bus/coleco/cartridge/megacart.h",
MAME_DIR .. "src/devices/bus/coleco/cartridge/std.cpp",

View File

@ -0,0 +1,132 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/**********************************************************************
ColecoVision 'Activision' cartridge emulation
**********************************************************************/
#include "emu.h"
#include "activision.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
DEFINE_DEVICE_TYPE(COLECOVISION_ACTIVISION, colecovision_activision_cartridge_device, "coleco_activision", "ColecoVision Activision Cartridge")
DEFINE_DEVICE_TYPE(COLECOVISION_ACTIVISION_256B, colecovision_activision_256b_cartridge_device, "coleco_activision_256b", "ColecoVision Activision Cartridge (256B EEPROM)")
DEFINE_DEVICE_TYPE(COLECOVISION_ACTIVISION_32K, colecovision_activision_32k_cartridge_device, "coleco_activision_32k", "ColecoVision Activision Cartridge (32K EEPROM)")
colecovision_activision_cartridge_device::colecovision_activision_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, COLECOVISION_ACTIVISION, tag, owner, clock),
device_colecovision_cartridge_interface(mconfig, *this),
m_eeprom(*this, "eeprom"),
m_active_bank(0)
{
}
colecovision_activision_cartridge_device::colecovision_activision_cartridge_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
device_t(mconfig, type, tag, owner, clock),
device_colecovision_cartridge_interface(mconfig, *this),
m_eeprom(*this, "eeprom"),
m_active_bank(0)
{
}
colecovision_activision_256b_cartridge_device::colecovision_activision_256b_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
colecovision_activision_cartridge_device(mconfig, COLECOVISION_ACTIVISION_256B, tag, owner, clock)
{
}
colecovision_activision_32k_cartridge_device::colecovision_activision_32k_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
colecovision_activision_cartridge_device(mconfig, COLECOVISION_ACTIVISION_32K, tag, owner, clock)
{
}
//**************************************************************************
// MACHINE DEFINITIONS
//**************************************************************************
void colecovision_activision_256b_cartridge_device::device_add_mconfig(machine_config &config)
{
I2C_24C02(config, m_eeprom, 0);
}
void colecovision_activision_32k_cartridge_device::device_add_mconfig(machine_config &config)
{
I2C_24C256(config, m_eeprom, 0);
}
//**************************************************************************
// MACHINE EMULATION
//**************************************************************************
void colecovision_activision_cartridge_device::device_start()
{
// register for save states
save_item(NAME(m_active_bank));
}
uint8_t colecovision_activision_cartridge_device::read(offs_t offset, int _8000, int _a000, int _c000, int _e000)
{
uint8_t data = 0xff;
if (!_8000 || !_a000 || !_c000 || !_e000)
{
if (offset < 0x4000)
{
// fixed first rom bank
data = m_rom[offset];
}
else if (offset == 0x7f80)
{
// eeprom data
if (m_eeprom.found())
data = m_eeprom->read_sda();
else
data = 0xff;
}
else if (offset > 0x7f80)
{
// "dead" area
data = 0xff;
}
else
{
// bankswitched rom
data = m_rom[(m_active_bank << 14) | (offset & 0x3fff)];
}
}
return data;
}
void colecovision_activision_cartridge_device::write(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000)
{
switch (offset)
{
// bankswitch
case 0x7f90:
case 0x7fa0:
case 0x7fb0:
m_active_bank = (offset >> 4) & 0x03;
break;
// eeprom scl
case 0x7fc0:
case 0x7fd0:
if (m_eeprom.found())
m_eeprom->write_scl(BIT(offset, 4));
break;
// eeprom sda
case 0x7fe0:
case 0x7ff0:
if (m_eeprom.found())
m_eeprom->write_sda(BIT(offset, 4));
break;
}
}

View File

@ -0,0 +1,65 @@
// license: BSD-3-Clause
// copyright-holders: Dirk Best
/**********************************************************************
ColecoVision 'Activision' cartridge emulation
**********************************************************************/
#ifndef MAME_BUS_COLECO_CARTRIDGE_ACTIVISION_H
#define MAME_BUS_COLECO_CARTRIDGE_ACTIVISION_H
#pragma once
#include "exp.h"
#include "machine/i2cmem.h"
//**************************************************************************
// TYPE DEFINITIONS
//**************************************************************************
class colecovision_activision_cartridge_device : public device_t, public device_colecovision_cartridge_interface
{
public:
colecovision_activision_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
colecovision_activision_cartridge_device(const machine_config &mconfig, device_type type, const char* tag, device_t* owner, uint32_t clock);
optional_device<i2cmem_device> m_eeprom;
virtual void device_start() override;
// cartridge interface
virtual uint8_t read(offs_t offset, int _8000, int _a000, int _c000, int _e000) override;
virtual void write(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000) override;
private:
uint8_t m_active_bank;
};
class colecovision_activision_256b_cartridge_device : public colecovision_activision_cartridge_device
{
public:
colecovision_activision_256b_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
class colecovision_activision_32k_cartridge_device : public colecovision_activision_cartridge_device
{
public:
colecovision_activision_32k_cartridge_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
protected:
virtual void device_add_mconfig(machine_config &config) override;
};
// device type declaration
DECLARE_DEVICE_TYPE(COLECOVISION_ACTIVISION, colecovision_activision_cartridge_device)
DECLARE_DEVICE_TYPE(COLECOVISION_ACTIVISION_256B, colecovision_activision_256b_cartridge_device)
DECLARE_DEVICE_TYPE(COLECOVISION_ACTIVISION_32K, colecovision_activision_32k_cartridge_device)
#endif // MAME_BUS_COLECO_CARTRIDGE_ACTIVISION_H

View File

@ -121,23 +121,36 @@ std::string colecovision_cartridge_slot_device::get_default_card_software(get_de
//-------------------------------------------------
// bd_r - cartridge data read
// read - cartridge data read
//-------------------------------------------------
uint8_t colecovision_cartridge_slot_device::bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000)
uint8_t colecovision_cartridge_slot_device::read(offs_t offset, int _8000, int _a000, int _c000, int _e000)
{
uint8_t data = 0xff;
if (m_card)
data = m_card->bd_r(offset , data, _8000, _a000, _c000, _e000);
data = m_card->read(offset, _8000, _a000, _c000, _e000);
return data;
}
//-------------------------------------------------
// write - cartridge data write
//-------------------------------------------------
void colecovision_cartridge_slot_device::write(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000)
{
if (m_card)
m_card->write(offset, data, _8000, _a000, _c000, _e000);
}
//-------------------------------------------------
// SLOT_INTERFACE( colecovision_cartridges )
//-------------------------------------------------
#include "activision.h"
#include "megacart.h"
#include "std.h"
#include "xin1.h"
@ -145,6 +158,9 @@ uint8_t colecovision_cartridge_slot_device::bd_r(offs_t offset, uint8_t data, in
void colecovision_cartridges(device_slot_interface &device)
{
// the following need ROMs from the software list
device.option_add_internal("activision", COLECOVISION_ACTIVISION);
device.option_add_internal("activision_256b", COLECOVISION_ACTIVISION_256B);
device.option_add_internal("activision_32k", COLECOVISION_ACTIVISION_32K);
device.option_add_internal("megacart", COLECOVISION_MEGACART);
device.option_add_internal("standard", COLECOVISION_STANDARD);
device.option_add_internal("xin1", COLECOVISION_XIN1);

View File

@ -65,7 +65,8 @@ public:
colecovision_cartridge_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
// computer interface
uint8_t bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000);
uint8_t read(offs_t offset, int _8000, int _a000, int _c000, int _e000);
void write(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000);
protected:
// device_t implementation
@ -92,7 +93,8 @@ class device_colecovision_cartridge_interface : public device_interface
friend class colecovision_cartridge_slot_device;
public:
virtual uint8_t bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000) { return 0xff; }
virtual uint8_t read(offs_t offset, int _8000, int _a000, int _c000, int _e000) { return 0xff; }
virtual void write(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000) { }
void rom_alloc(size_t size);

View File

@ -62,15 +62,17 @@ void colecovision_megacart_cartridge_device::device_reset()
// read - cartridge data read
//-------------------------------------------------
uint8_t colecovision_megacart_cartridge_device::bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000)
uint8_t colecovision_megacart_cartridge_device::read(offs_t offset, int _8000, int _a000, int _c000, int _e000)
{
uint8_t data = 0xff;
if (!_8000 || !_a000 || !_c000 || !_e000)
{
if (m_bankcount > 2)
{
// offset as passed to us is a delta from address 0x8000.
if (offset >= 0x7FC0)
if (offset >= 0x7fc0)
{
// Reads within the final 64 bytes select which megacart bank is active.
m_activebank = offset & (m_bankcount - 1);

View File

@ -34,7 +34,7 @@ protected:
virtual void device_reset() override;
// device_colecovision_cartridge_interface overrides
virtual uint8_t bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000) override;
virtual uint8_t read(offs_t offset, int _8000, int _a000, int _c000, int _e000) override;
private:
uint32_t m_bankcount;

View File

@ -47,14 +47,14 @@ void colecovision_standard_cartridge_device::device_start()
// read - cartridge data read
//-------------------------------------------------
uint8_t colecovision_standard_cartridge_device::bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000)
uint8_t colecovision_standard_cartridge_device::read(offs_t offset, int _8000, int _a000, int _c000, int _e000)
{
uint8_t data = 0xff;
if (!_8000 || !_a000 || !_c000 || !_e000)
{
if (offset < m_rom_size)
data = m_rom[offset];
else
data = 0xff;
}
return data;

View File

@ -33,7 +33,7 @@ protected:
virtual void device_start() override;
// device_colecovision_expansion_card_interface overrides
virtual uint8_t bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000) override;
virtual uint8_t read(offs_t offset, int _8000, int _a000, int _c000, int _e000) override;
};

View File

@ -59,8 +59,10 @@ void colecovision_xin1_cartridge_device::device_reset()
// read - cartridge data read
//-------------------------------------------------
uint8_t colecovision_xin1_cartridge_device::bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000)
uint8_t colecovision_xin1_cartridge_device::read(offs_t offset, int _8000, int _a000, int _c000, int _e000)
{
uint8_t data = 0xff;
if (!_8000 || !_a000 || !_c000 || !_e000)
{
data = m_rom[m_current_offset + offset];

View File

@ -34,7 +34,7 @@ protected:
virtual void device_reset() override;
// device_colecovision_expansion_card_interface overrides
virtual uint8_t bd_r(offs_t offset, uint8_t data, int _8000, int _a000, int _c000, int _e000) override;
virtual uint8_t read(offs_t offset, int _8000, int _a000, int _c000, int _e000) override;
private:
uint32_t m_current_offset;

View File

@ -105,17 +105,17 @@ uint8_t sv603_device::mreq_r(offs_t offset)
uint8_t data = 0xff;
// ls138 (active low)
int ccs1 = ((offset >> 13) == 0) ? 0 : 1;
int ccs2 = ((offset >> 13) == 1) ? 0 : 1;
int ccs3 = ((offset >> 13) == 2) ? 0 : 1;
int ccs4 = ((offset >> 13) == 3) ? 0 : 1;
int bios = ((offset >> 13) == 4) ? 0 : 1;
const int ccs1 = ((offset >> 13) == 0) ? 0 : 1;
const int ccs2 = ((offset >> 13) == 1) ? 0 : 1;
const int ccs3 = ((offset >> 13) == 2) ? 0 : 1;
const int ccs4 = ((offset >> 13) == 3) ? 0 : 1;
const int bios = ((offset >> 13) == 4) ? 0 : 1;
// 5, 6, 7: not connected
m_expander->romdis_w(0);
m_expander->ramdis_w(bios);
data &= m_cart->bd_r(offset, data, ccs1, ccs2, ccs3, ccs4);
data &= m_cart->read(offset, ccs1, ccs2, ccs3, ccs4);
if (bios == 0)
data &= m_bios->as_u8(offset & 0x1fff);
@ -125,7 +125,16 @@ uint8_t sv603_device::mreq_r(offs_t offset)
void sv603_device::mreq_w(offs_t offset, uint8_t data)
{
const int ccs1 = ((offset >> 13) == 0) ? 0 : 1;
const int ccs2 = ((offset >> 13) == 1) ? 0 : 1;
const int ccs3 = ((offset >> 13) == 2) ? 0 : 1;
const int ccs4 = ((offset >> 13) == 3) ? 0 : 1;
const int bios = ((offset >> 13) == 4) ? 0 : 1;
m_expander->romdis_w(0);
m_expander->ramdis_w(bios);
m_cart->write(offset, data, ccs1, ccs2, ccs3, ccs4);
}
uint8_t sv603_device::iorq_r(offs_t offset)

View File

@ -457,7 +457,7 @@ uint8_t adam_state::mreq_r(offs_t offset)
}
}
data = m_cart->bd_r(offset & 0x7fff, data, cs1, cs2, cs3, cs4);
data &= m_cart->read(offset & 0x7fff, cs1, cs2, cs3, cs4);
data = m_slot[0]->bd_r(offset & 0xff, data, 1, biorq, 1, 1, 1);
data = m_slot[1]->bd_r(offset, data, bmreq, biorq, aux_rom_cs, 1, cas2);
data = m_slot[2]->bd_r(offset, data, 1, 1, 1, cas1, cas2);
@ -516,6 +516,7 @@ void adam_state::mreq_w(offs_t offset, uint8_t data)
m_ram->pointer()[offset] = data;
}
// TODO: cartridge slot write
m_slot[0]->bd_w(offset & 0xff, data, 1, biorq, 1, 1, 1);
m_slot[1]->bd_w(offset, data, bmreq, biorq, aux_rom_cs, 1, cas2);
m_slot[2]->bd_w(offset, data, 1, 1, 1, cas1, cas2);

View File

@ -164,7 +164,7 @@ void coleco_state::coleco_map(address_map &map)
{
map(0x0000, 0x1fff).rom();
map(0x6000, 0x63ff).ram().mirror(0x1c00);
map(0x8000, 0xffff).rom();
map(0x8000, 0xffff).rw(FUNC(coleco_state::cart_r), FUNC(coleco_state::cart_w));
}
void bit90_state::bit90_map(address_map &map)
@ -173,7 +173,7 @@ void bit90_state::bit90_map(address_map &map)
map(0x2000, 0x3fff).rom();
map(0x4000, 0x5fff).rom(); // Decoded through pin 5 of the Bit90 expansion port
map(0x6000, 0x67ff).ram().mirror(0x1800);
map(0x8000, 0xffff).ram();
map(0x8000, 0xffff).rw(FUNC(coleco_state::cart_r), FUNC(coleco_state::cart_w));
}
void coleco_state::coleco_io_map(address_map &map)
@ -416,7 +416,12 @@ TIMER_DEVICE_CALLBACK_MEMBER(coleco_state::paddle_update_callback)
uint8_t coleco_state::cart_r(offs_t offset)
{
return m_cart->bd_r(offset & 0x7fff, 0, 0, 0, 0, 0);
return m_cart->read(offset, 0, 0, 0, 0);
}
void coleco_state::cart_w(offs_t offset, uint8_t data)
{
m_cart->write(offset, data, 0, 0, 0, 0);
}
uint8_t coleco_state::coleco_scan_paddles(uint8_t *joy_status0, uint8_t *joy_status1)
@ -524,9 +529,6 @@ void coleco_state::machine_start()
m_joy_analog_state[port] = 0;
}
if (m_cart->exists())
m_maincpu->space(AS_PROGRAM).install_read_handler(0x8000, 0xffff, read8sm_delegate(*this, FUNC(coleco_state::cart_r)));
save_item(NAME(m_joy_mode));
save_item(NAME(m_last_nmi_state));
save_item(NAME(m_joy_irq_state));

View File

@ -44,6 +44,8 @@ public:
virtual void machine_reset() override;
uint8_t cart_r(offs_t offset);
void cart_w(offs_t offset, uint8_t data);
uint8_t paddle_1_r();
uint8_t paddle_2_r();
void paddle_off_w(uint8_t data);