From 5466b7f0c943b6f0fc5bdb92afe5993d87bc132a Mon Sep 17 00:00:00 2001 From: Sylvain Glaize Date: Thu, 29 Feb 2024 01:07:49 +0100 Subject: [PATCH] trs/mc10.cpp: Add "Multiport" cartridge and RAM expansion for the Matra & Hachette Alice (#12080) --- scripts/src/bus.lua | 2 + src/devices/bus/mc10/mc10_cart.cpp | 10 ++ src/devices/bus/mc10/multiports_ext.cpp | 133 ++++++++++++++++++++++++ src/devices/bus/mc10/multiports_ext.h | 12 +++ 4 files changed, 157 insertions(+) create mode 100644 src/devices/bus/mc10/multiports_ext.cpp create mode 100644 src/devices/bus/mc10/multiports_ext.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index a0b51b85142..4687be66586 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -2079,6 +2079,8 @@ if (BUSES["MC10"]~=null) then MAME_DIR .. "src/devices/bus/mc10/pak.h", MAME_DIR .. "src/devices/bus/mc10/ram.cpp", MAME_DIR .. "src/devices/bus/mc10/ram.h", + MAME_DIR .. "src/devices/bus/mc10/multiports_ext.cpp", + MAME_DIR .. "src/devices/bus/mc10/multiports_ext.h", } end diff --git a/src/devices/bus/mc10/mc10_cart.cpp b/src/devices/bus/mc10/mc10_cart.cpp index 77d2ae58332..cb413b13034 100644 --- a/src/devices/bus/mc10/mc10_cart.cpp +++ b/src/devices/bus/mc10/mc10_cart.cpp @@ -27,6 +27,10 @@ 16 A3 33 GND 17 A5 34 GND + Alice 32 and Alice 90 have 2 more pins: + 35 IRQ (optional) + 36 SOUND + SEL is an input to the MC-10 that allows the cartridge to remove the internal chips from the bus. @@ -38,6 +42,7 @@ #include "mcx128.h" #include "pak.h" #include "ram.h" +#include "multiports_ext.h" //#define VERBOSE 1 #include "logmacro.h" @@ -104,6 +109,8 @@ std::pair mc10cart_slot_device::call_load() util::string_format("Unsupported cartridge size (must be no more than %u bytes)", m_cart->max_rom_length())); } + // TODO: add the min_rom_length() method to the interface + if (!loaded_through_softlist()) { LOG("Allocating %u byte cartridge ROM region\n", len); @@ -198,6 +205,7 @@ void mc10_cart_add_basic_devices(device_slot_interface &device) device.option_add("mcx128", MC10_PAK_MCX128); device.option_add("pak", MC10_PAK); device.option_add("ram", MC10_PAK_RAM); + device.option_add("multi", ALICE_MULTIPORTS_EXT); } //------------------------------------------------- @@ -210,6 +218,7 @@ void alice_cart_add_basic_devices(device_slot_interface &device) device.option_add("alice128", ALICE_PAK_MCX128); device.option_add("pak", MC10_PAK); device.option_add("ram", MC10_PAK_RAM); + device.option_add("multi", ALICE_MULTIPORTS_EXT); } //------------------------------------------------- @@ -221,4 +230,5 @@ void alice32_cart_add_basic_devices(device_slot_interface &device) // basic devices device.option_add("pak", MC10_PAK); device.option_add("ram", MC10_PAK_RAM); + device.option_add("multi", ALICE_MULTIPORTS_EXT); } diff --git a/src/devices/bus/mc10/multiports_ext.cpp b/src/devices/bus/mc10/multiports_ext.cpp new file mode 100644 index 00000000000..c15c85c3420 --- /dev/null +++ b/src/devices/bus/mc10/multiports_ext.cpp @@ -0,0 +1,133 @@ +/*************************************************************************** + + multiports_ext.cpp + + Emulation of the Alice Multiports Extension + + Features: + The extension provides an extension doubler and two joystick ports. + + The extension also provides (for the whole Alice family and MC-10): + - 16K of RAM expansion ($5000-$8FFF) + - 64K of ROM expansion in two possible configurations: + - 8K of ROM between $1000 and $2FFF, as 8 banks (Cartridge mode). + - 16K of ROM between $C000 and $FFFF, as 4 banks (ROM mode). + + Only the RAM/ROM expansion is emulated here. + + Banks are selected by writing to: + - $1000 to $1FFF in Cartridge mode (number of bank between 0 and 7) + - $C000 to $CFFF in ROM mode (number of bank between 0 and 3) + +***************************************************************************/ + +#include "emu.h" +#include "multiports_ext.h" + +//************************************************************************** +// TYPE DECLARATIONS +//************************************************************************** + +class mc10_multiports_ext_device : public device_t, + public device_mc10cart_interface +{ +public: + mc10_multiports_ext_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual int max_rom_length() const override; + virtual std::pair load() override; + +protected: + mc10_multiports_ext_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device_t implementation + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_post_load() override; + + void control_register_write(offs_t offset, u8 data); + + void multiports_mem(address_map &map); + void update_bank(); + +private: + memory_bank_creator m_bank; + uint8_t rom_bank_index; + memory_share_creator m_extention_ram; +}; + +DEFINE_DEVICE_TYPE_PRIVATE(ALICE_MULTIPORTS_EXT, device_mc10cart_interface, mc10_multiports_ext_device, "mc10_multiports_ext", "Fred_72 and 6502man's Multiports Extension") + +//------------------------------------------------- +// IMPLEMENTATION +//------------------------------------------------- + +mc10_multiports_ext_device::mc10_multiports_ext_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : mc10_multiports_ext_device(mconfig, ALICE_MULTIPORTS_EXT, tag, owner, clock) +{ +} + +mc10_multiports_ext_device::mc10_multiports_ext_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, type, tag, owner, clock), device_mc10cart_interface(mconfig, *this), m_bank(*this, "cart_bank"), rom_bank_index(0), m_extention_ram(*this, "ext_ram", 1024 * 16, ENDIANNESS_BIG) +{ +} + +int mc10_multiports_ext_device::max_rom_length() const +{ + return 1024 * 64; +} + +void mc10_multiports_ext_device::multiports_mem(address_map &map) +{ + map(0x0000, 0x1fff).bankr("cart_bank").w(FUNC(mc10_multiports_ext_device::control_register_write)); +} + +//------------------------------------------------- + +void mc10_multiports_ext_device::device_start() +{ + save_item(NAME(rom_bank_index)); + + owning_slot().memspace().install_device(0x1000, 0x2fff, *this, &mc10_multiports_ext_device::multiports_mem); + owning_slot().memspace().install_ram(0x5000, 0x8fff, &m_extention_ram[0]); +} + +//------------------------------------------------- + +void mc10_multiports_ext_device::device_reset() +{ + rom_bank_index = 0; + update_bank(); +} + +void mc10_multiports_ext_device::device_post_load() +{ + update_bank(); +} + +void mc10_multiports_ext_device::control_register_write(offs_t offset, u8 data) +{ + if (offset < 0x1000) + { + rom_bank_index = data & 0x07; + update_bank(); + } +} + +void mc10_multiports_ext_device::update_bank() +{ + m_bank.target()->set_entry(rom_bank_index); +} + +std::pair mc10_multiports_ext_device::load() +{ + memory_region *const romregion(memregion("^rom")); + if (!romregion) + { + return std::make_pair(image_error::BADSOFTWARE, "Software item lacks 'rom' data area"); + } + + m_bank.target()->configure_entries(0, 8, romregion->base(), 0x2000); + + return std::make_pair(std::error_condition(), std::string()); +} diff --git a/src/devices/bus/mc10/multiports_ext.h b/src/devices/bus/mc10/multiports_ext.h new file mode 100644 index 00000000000..2c31b9020a4 --- /dev/null +++ b/src/devices/bus/mc10/multiports_ext.h @@ -0,0 +1,12 @@ +#ifndef MAME_BUS_MC10_MULTIPORTS_EXT_H +#define MAME_BUS_MC10_MULTIPORTS_EXT_H + +#pragma once + +#include "mc10_cart.h" + +// device type definition +DECLARE_DEVICE_TYPE(ALICE_MULTIPORTS_EXT, device_mc10cart_interface) + +#endif // MAME_BUS_MC10_MC10_MULTIPORTS_EXT_H +