diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 9258a9ea108..88345bbc04e 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -1747,6 +1747,24 @@ if (BUSES["MTX"]~=null) then end +--------------------------------------------------- +-- +--@src/devices/bus/mc10/mc10_cart.h,BUSES["MC10"] = true +--------------------------------------------------- +if (BUSES["MC10"]~=null) then + files { + MAME_DIR .. "src/devices/bus/mc10/mc10_cart.cpp", + MAME_DIR .. "src/devices/bus/mc10/mc10_cart.h", + MAME_DIR .. "src/devices/bus/mc10/mcx128.cpp", + MAME_DIR .. "src/devices/bus/mc10/mcx128.h", + MAME_DIR .. "src/devices/bus/mc10/pak.cpp", + MAME_DIR .. "src/devices/bus/mc10/pak.h", + MAME_DIR .. "src/devices/bus/mc10/ram.cpp", + MAME_DIR .. "src/devices/bus/mc10/ram.h", + } +end + + --------------------------------------------------- -- --@src/devices/bus/kc/kc.h,BUSES["KC"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index d7384d21b45..dc299592c17 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -831,25 +831,25 @@ BUSES["ACORN"] = true BUSES["ADAM"] = true BUSES["ADAMNET"] = true BUSES["ADB"] = true +BUSES["AMIGA_KEYBOARD"] = true BUSES["APF"] = true BUSES["APRICOT_EXPANSION"] = true BUSES["APRICOT_KEYBOARD"] = true BUSES["AQUARIUS"] = true -BUSES["AMIGA_KEYBOARD"] = true BUSES["ARCADIA"] = true BUSES["ASTROCADE"] = true BUSES["ATA"] = true -BUSES["BBC_FDC"] = true +BUSES["BBC_1MHZBUS"] = true BUSES["BBC_ANALOGUE"] = true BUSES["BBC_CART"] = true BUSES["BBC_EXP"] = true +BUSES["BBC_FDC"] = true BUSES["BBC_INTERNAL"] = true BUSES["BBC_JOYPORT"] = true BUSES["BBC_MODEM"] = true -BUSES["BBC_1MHZBUS"] = true +BUSES["BBC_ROM"] = true BUSES["BBC_TUBE"] = true BUSES["BBC_USERPORT"] = true -BUSES["BBC_ROM"] = true BUSES["BML3"] = true BUSES["BW2"] = true BUSES["C64"] = true @@ -861,8 +861,8 @@ BUSES["CGENIE_EXPANSION"] = true BUSES["CGENIE_PARALLEL"] = true BUSES["CHANNELF"] = true BUSES["COCO"] = true -BUSES["COLECO_CONTROLLER"] = true BUSES["COLECO_CART"] = true +BUSES["COLECO_CONTROLLER"] = true BUSES["COMPIS_GRAPHICS"] = true BUSES["COMPUCOLOR"] = true BUSES["COMX35"] = true @@ -871,10 +871,10 @@ BUSES["CRVISION"] = true BUSES["DMV"] = true BUSES["ECBBUS"] = true BUSES["ECONET"] = true -BUSES["EKARA"] = true BUSES["EINSTEIN_USERPORT"] = true -BUSES["ELECTRON"] = true +BUSES["EKARA"] = true BUSES["ELECTRON_CART"] = true +BUSES["ELECTRON"] = true BUSES["EP64"] = true BUSES["EPSON_SIO"] = true BUSES["FMT_SCSI"] = true @@ -885,38 +885,39 @@ BUSES["GBA"] = true BUSES["GENERIC"] = true BUSES["GIO64"] = true BUSES["HEXBUS"] = true -BUSES["HPHIL"] = true +BUSES["HP_IPC_IO"] = true +BUSES["HP80_IO"] = true +BUSES["HP9845_IO"] = true BUSES["HPDIO"] = true +BUSES["HPHIL"] = true BUSES["IEEE488"] = true BUSES["IMI7000"] = true BUSES["INTELLEC4"] = true -BUSES["INTERPRO_SR"] = true BUSES["INTERPRO_KEYBOARD"] = true BUSES["INTERPRO_MOUSE"] = true -BUSES["INTV"] = true +BUSES["INTERPRO_SR"] = true BUSES["INTV_CTRL"] = true +BUSES["INTV"] = true BUSES["IQ151"] = true BUSES["ISA"] = true BUSES["ISBX"] = true BUSES["JAKKS_GAMEKEY"] = true -BUSES["HP80_IO"] = true -BUSES["HP9845_IO"] = true -BUSES["HP_IPC_IO"] = true BUSES["KC"] = true BUSES["LPCI"] = true BUSES["M5"] = true BUSES["MACKBD"] = true BUSES["MACPDS"] = true -BUSES["MIDI"] = true +BUSES["MC10"] = true BUSES["MEGADRIVE"] = true +BUSES["MIDI"] = true BUSES["MSX_SLOT"] = true BUSES["MTX"] = true BUSES["MULTIBUS"] = true BUSES["NASBUS"] = true -BUSES["NEOGEO"] = true BUSES["NEOGEO_CTRL"] = true -BUSES["NES"] = true +BUSES["NEOGEO"] = true BUSES["NES_CTRL"] = true +BUSES["NES"] = true BUSES["NEWBRAIN"] = true BUSES["NSCSI"] = true BUSES["NUBUS"] = true @@ -924,18 +925,18 @@ BUSES["O2"] = true BUSES["ORICEXT"] = true BUSES["P2000"] = true BUSES["PASOPIA"] = true -BUSES["PC1512"] = true -BUSES["PCE"] = true BUSES["PC_JOY"] = true BUSES["PC_KBD"] = true +BUSES["PC1512"] = true +BUSES["PCE"] = true BUSES["PET"] = true BUSES["PLUS4"] = true BUSES["POFO"] = true BUSES["PSI_KEYBOARD"] = true BUSES["PSX_CONTROLLER"] = true BUSES["PSX_PARALLEL"] = true -BUSES["QL"] = true BUSES["QBUS"] = true +BUSES["QL"] = true BUSES["RS232"] = true BUSES["RTPC_KBD"] = true BUSES["S100"] = true @@ -954,8 +955,8 @@ BUSES["SG1000_EXP"] = true BUSES["SGIKBD"] = true BUSES["SMS_CTRL"] = true BUSES["SMS_EXP"] = true -BUSES["SNES"] = true BUSES["SNES_CTRL"] = true +BUSES["SNES"] = true BUSES["SPC1000"] = true BUSES["SPECTRUM"] = true BUSES["SS50"] = true @@ -966,11 +967,11 @@ BUSES["SVI_SLOT"] = true BUSES["TANBUS"] = true BUSES["TATUNG_PIPE"] = true BUSES["THOMSON"] = true -BUSES["TMC600"] = true BUSES["TI8X"] = true BUSES["TI99"] = true BUSES["TI99X"] = true BUSES["TIKI100"] = true +BUSES["TMC600"] = true BUSES["TVC"] = true BUSES["UTS_KBD"] = true BUSES["VBOY"] = true diff --git a/src/devices/bus/mc10/mc10_cart.cpp b/src/devices/bus/mc10/mc10_cart.cpp new file mode 100644 index 00000000000..f7858a087bc --- /dev/null +++ b/src/devices/bus/mc10/mc10_cart.cpp @@ -0,0 +1,230 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/********************************************************************* + + mc10cart.cpp + + MC-10 / Alice expansion slot - typically used for the 16K external + RAM expansion. + + MC-10 and Alice pinout listing + --- ------- --- ------- + 1 GND 18 A6 + 2 GND 19 A7 + 3 D0 20 A8 + 4 D1 21 A9 + 5 D2 22 A10 + 6 D3 23 A11 + 7 D4 24 A12 + 8 D5 25 A13 + 9 D6 26 A14 + 10 D7 27 A15 + 11 R/!W 28 E + 12 A0 29 SEL + 13 A1 30 RESET + 14 A2 31 !NMI + 15 A3 32 +5V + 16 A3 33 GND + 17 A5 34 GND + + SEL is an input to the MC-10 that allows the cartridge to remove + the internal chips from the bus. + +*********************************************************************/ + +#include "emu.h" +#include "mc10_cart.h" + +#include "mcx128.h" +#include "pak.h" +#include "ram.h" + +//#define VERBOSE 1 +#include "logmacro.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(MC10CART_SLOT, mc10cart_slot_device, "mc10cart_slot", "MC-10 Cartridge Slot") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// mc10cart_slot_device - constructor +//------------------------------------------------- +mc10cart_slot_device::mc10cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : + device_t(mconfig, MC10CART_SLOT, tag, owner, clock), + device_single_card_slot_interface(mconfig, *this), + device_image_interface(mconfig, *this), + m_nmi_callback(*this), + m_cart(nullptr), + m_memspace(*this, finder_base::DUMMY_TAG, -1) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10cart_slot_device::device_start() +{ + m_nmi_callback.resolve_safe(); + m_cart = get_card_device(); +} + +//------------------------------------------------- +// set_nmi_line +//------------------------------------------------- + +void mc10cart_slot_device::set_nmi_line(int state) +{ + m_nmi_callback(state); +} + +//------------------------------------------------- +// call_load +//------------------------------------------------- + +image_init_result mc10cart_slot_device::call_load() +{ + if (!m_cart) + return image_init_result::PASS; + + memory_region *romregion(loaded_through_softlist() ? memregion("rom") : nullptr); + if (loaded_through_softlist() && !romregion) + { + seterror(IMAGE_ERROR_INVALIDIMAGE, "Software list item has no 'rom' data area"); + return image_init_result::FAIL; + } + + u32 const len(loaded_through_softlist() ? romregion->bytes() : length()); + if (len > m_cart->max_rom_length()) + { + seterror(IMAGE_ERROR_UNSUPPORTED, "Unsupported cartridge size"); + return image_init_result::FAIL; + } + + if (!loaded_through_softlist()) + { + LOG("Allocating %u byte cartridge ROM region\n", len); + romregion = machine().memory().region_alloc(subtag("rom").c_str(), len, 1, ENDIANNESS_BIG); + u32 const cnt(fread(romregion->base(), len)); + if (cnt != len) + { + seterror(IMAGE_ERROR_UNSPECIFIED, "Error reading cartridge file"); + return image_init_result::FAIL; + } + } + + return m_cart->load(); +} + +//------------------------------------------------- +// get_default_card_software +//------------------------------------------------- + +std::string mc10cart_slot_device::get_default_card_software(get_default_card_software_hook &hook) const +{ + return software_get_default_slot("pak"); +} + +//************************************************************************** +// DEVICE MC-10 CART INTERFACE - Implemented by devices that plug into +// MC-10 cartridge slots +//************************************************************************** + +template class device_finder; +template class device_finder; + +//------------------------------------------------- +// device_mc10cart_interface - constructor +//------------------------------------------------- + +device_mc10cart_interface::device_mc10cart_interface(const machine_config &mconfig, device_t &device) + : device_interface(device, "mc10cart") + , m_owning_slot(nullptr) +{ +} + +//------------------------------------------------- +// ~device_mc10cart_interface - destructor +//------------------------------------------------- + +device_mc10cart_interface::~device_mc10cart_interface() +{ +} + +//------------------------------------------------- +// interface_config_complete +//------------------------------------------------- + +void device_mc10cart_interface::interface_config_complete() +{ + m_owning_slot = dynamic_cast(device().owner()); +} + +//------------------------------------------------- +// interface_pre_start +//------------------------------------------------- + +void device_mc10cart_interface::interface_pre_start() +{ + if (!m_owning_slot) + throw emu_fatalerror("Expected device().owner() to be of type mc10cart_slot_device"); +} + +/*------------------------------------------------- + max_rom_length +-------------------------------------------------*/ + +int device_mc10cart_interface::max_rom_length() const +{ + return 0; +} + +/*------------------------------------------------- + load +-------------------------------------------------*/ + +image_init_result device_mc10cart_interface::load() +{ + return image_init_result::FAIL; +} + +//------------------------------------------------- +// mc10_cart_add_basic_devices +//------------------------------------------------- + +void mc10_cart_add_basic_devices(device_slot_interface &device) +{ + // basic devices + device.option_add("mcx128", MC10_PAK_MCX128); + device.option_add("pak", MC10_PAK); + device.option_add("ram", MC10_PAK_RAM); +} + +//------------------------------------------------- +// alice_cart_add_basic_devices +//------------------------------------------------- + +void alice_cart_add_basic_devices(device_slot_interface &device) +{ + // basic devices + device.option_add("alice128", ALICE_PAK_MCX128); + device.option_add("pak", MC10_PAK); + device.option_add("ram", MC10_PAK_RAM); +} + +//------------------------------------------------- +// alice32_cart_add_basic_devices +//------------------------------------------------- + +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); +} diff --git a/src/devices/bus/mc10/mc10_cart.h b/src/devices/bus/mc10/mc10_cart.h new file mode 100644 index 00000000000..eba93284325 --- /dev/null +++ b/src/devices/bus/mc10/mc10_cart.h @@ -0,0 +1,118 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/********************************************************************* + + mc10_cart.h + + MC-10 / Alice cartridge management + +*********************************************************************/ + +#ifndef MAME_BUS_MC10_MC10CART_H +#define MAME_BUS_MC10_MC10CART_H + +#pragma once + +#include "softlist_dev.h" + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + + +// ======================> mc10cart_slot_device +class device_mc10cart_interface; + +class mc10cart_slot_device final : public device_t, + public device_single_card_slot_interface, + public device_image_interface +{ +public: + + // construction/destruction + template + mc10cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock, T &&opts, const char *dflt) + : mc10cart_slot_device(mconfig, tag, owner, clock) + { + option_reset(); + opts(*this); + set_default_option(dflt); + set_fixed(false); + } + + mc10cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + // inline configuration + template void set_memspace(T &&tag, int spacenum) { m_memspace.set_tag(std::forward(tag), spacenum); } + auto nmi_callback() { return m_nmi_callback.bind(); } + + // address map manipulations + address_space &memspace() const { return *m_memspace; }; + + // device-level overrides + virtual void device_start() override; + + // image-level overrides + virtual image_init_result call_load() override; + virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); } + + virtual iodevice_t image_type() const noexcept override { return IO_CARTSLOT; } + + virtual bool is_readable() const noexcept override { return true; } + virtual bool is_writeable() const noexcept override { return false; } + virtual bool is_creatable() const noexcept override { return false; } + virtual bool must_be_loaded() const noexcept override { return false; } + virtual bool is_reset_on_load() const noexcept override { return true; } + virtual const char *image_interface() const noexcept override { return "mc10_cart"; } + virtual const char *file_extensions() const noexcept override { return "mcc,rom"; } + + // manipulation of nmi line + void set_nmi_line(int state); + devcb_write_line m_nmi_callback; + + // slot interface overrides + virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; + +private: + + // cartridge + device_mc10cart_interface *m_cart; + +protected: + required_address_space m_memspace; +}; + +// device type definition +DECLARE_DEVICE_TYPE(MC10CART_SLOT, mc10cart_slot_device) + +class device_mc10cart_interface : public device_interface +{ +public: + // construction/destruction + virtual ~device_mc10cart_interface(); + + virtual int max_rom_length() const; + virtual image_init_result load(); + +protected: + void raise_cart_nmi() { m_owning_slot->set_nmi_line(ASSERT_LINE); } + void lower_cart_nmi() { m_owning_slot->set_nmi_line(CLEAR_LINE); } + + virtual void interface_config_complete() override; + virtual void interface_pre_start() override; + + device_mc10cart_interface(const machine_config &mconfig, device_t &device); + + // accessors for containers + mc10cart_slot_device &owning_slot() const { assert(m_owning_slot); return *m_owning_slot; } + +private: + mc10cart_slot_device * m_owning_slot; +}; + +// methods for configuring MC-10 slot devices +void mc10_cart_add_basic_devices(device_slot_interface &device); +void alice_cart_add_basic_devices(device_slot_interface &device); +void alice32_cart_add_basic_devices(device_slot_interface &device); + +#endif // MAME_BUS_MC10_MC10CART_H diff --git a/src/devices/bus/mc10/mcx128.cpp b/src/devices/bus/mc10/mcx128.cpp new file mode 100644 index 00000000000..32c9239afb5 --- /dev/null +++ b/src/devices/bus/mc10/mcx128.cpp @@ -0,0 +1,371 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/*************************************************************************** + + mcx128.cpp + + Code for emulating Darren Atkinson's MCX-128 cartridge + + Features: + 128K of RAM expansion + 16K of ROM expansion + + New MC-10 memory map defined by this cartridge: + + 0000 - 0003 6803 Ports + 0004 - 0007 Expansion RAM + 0008 - 000E 6803 Status / Control + 000F Expansion RAM + 0010 - 0013 6803 UART + 0014 6803 RAM Control Reg + 0015 - 001F Unused + 0020 - 007F Expansion RAM + 0080 - 00FF On-chip CPU RAM / Expansion RAM + 0100 - 3FFF Expansion RAM + 4000 - 5FFF Built-In RAM / Expansion RAM + 6000 - BEFF Expansion RAM + BF00 RAM Bank Control Reg + BF01 ROM Map Control Reg + BF80 - BFFF Keyboard / VDG / Sound + C000 - DFFF EPROM or Expansion RAM + E000 - FFFF Built-in ROM, EPROM or Expansion RAM + + Deficiency: + + * Writing to 6803 chip RAM at $80 to $ff should be mirrored + to external RAM. + +***************************************************************************/ + +#include "emu.h" +#include "mcx128.h" + +//#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" + + +ROM_START(mc10_mcx128) + ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) + ROM_LOAD("mcx128bas.rom", 0x0000, 0x4000, CRC(11202e4b) SHA1(36c30d0f198a1bffee88ef29d92f2401447a91f4)) +ROM_END + +ROM_START(alice_mcx128) + ROM_REGION(0x4000, "eprom", ROMREGION_ERASE00) + ROM_LOAD("alice128bas.rom", 0x0000, 0x4000, CRC(a737544a) SHA1(c8fd92705fc42deb6a0ffac6274e27fd61ecd4cc)) +ROM_END + +//************************************************************************** +// TYPE DECLARATIONS +//************************************************************************** + +// ======================> mc10_pak_device + +class mc10_pak_mcx128_device : + public device_t, + public device_mc10cart_interface +{ +public: + // construction/destruction + mc10_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // construction/destruction + mc10_pak_mcx128_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_post_load() override; + + virtual const tiny_rom_entry *device_rom_region() const override + { + return ROM_NAME(mc10_mcx128); + } + + u8 control_register_read(offs_t offset); + void control_register_write(offs_t offset, u8 data); + + void write_ram_mirror(address_space &space, offs_t offset, u8 data); + + void view_map0(address_map &map); + void view_map1(address_map &map); + void view_map2(address_map &map); + void view_map3(address_map &map); + void view_map4(address_map &map); + void view_map5(address_map &map); + void view_map6(address_map &map); + void view_map7(address_map &map); + + +private: + memory_share_creator m_share; + memory_view m_view; + memory_bank_array_creator<8> m_bank; + uint8_t ram_bank_cr; + uint8_t rom_map_cr; + + void update_banks(); + +}; + +DEFINE_DEVICE_TYPE_PRIVATE(MC10_PAK_MCX128, device_mc10cart_interface, mc10_pak_mcx128_device, "mc10_mcx128", "Darren Atkinson's MCX-128 cartridge") + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- + +mc10_pak_mcx128_device::mc10_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + :mc10_pak_mcx128_device(mconfig, MC10_PAK_MCX128, tag, owner, clock) +{ +} + +mc10_pak_mcx128_device::mc10_pak_mcx128_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_share(*this, "ext_ram", 1024*128, ENDIANNESS_BIG) + , m_view(*this, "mcx_view") + , m_bank(*this, "bank%u", 0U) +{ +} + +void mc10_pak_mcx128_device::view_map0(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).rom().region("eprom",0x0000).bankw("bank5"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map1(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).rom().region("eprom",0x2000).bankw("bank6"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map2(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).bankw("bank6"); + map(0xff00, 0xffff).bankw("bank7"); +// 0xe000, 0xffff: read internal ROM +} + +void mc10_pak_mcx128_device::view_map3(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0x5fff).bankr("bank3").w(FUNC(mc10_pak_mcx128_device::write_ram_mirror)); + map(0x6000, 0xbeff).bankrw("bank4"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).bankrw("bank5"); + map(0xff00, 0xffff).bankrw("bank7"); +} + +void mc10_pak_mcx128_device::view_map4(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).rom().region("eprom",0x0000).bankw("bank5"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map5(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).rom().region("eprom",0x2000).bankw("bank6"); + map(0xff00, 0xffff).rom().region("eprom",0x3f00).bankw("bank7"); +} + +void mc10_pak_mcx128_device::view_map6(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xdfff).bankrw("bank5"); + map(0xe000, 0xfeff).bankw("bank6"); + map(0xff00, 0xffff).bankw("bank7"); +// 0xe000, 0xffff: read internal ROM +} + +void mc10_pak_mcx128_device::view_map7(address_map &map) +{ + map(0x0004, 0x0007).bankrw("bank0"); + map(0x000f, 0x000f).bankrw("bank1"); + map(0x0020, 0x3fff).bankrw("bank2"); + map(0x4000, 0xbeff).bankrw("bank3"); + map(0xbf00, 0xbf01).rw(FUNC(mc10_pak_mcx128_device::control_register_read), FUNC(mc10_pak_mcx128_device::control_register_write)); + map(0xc000, 0xfeff).bankrw("bank5"); + map(0xff00, 0xffff).bankrw("bank7"); +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10_pak_mcx128_device::device_start() +{ + save_item(NAME(ram_bank_cr)); + save_item(NAME(rom_map_cr)); + + // 0x0004 - 0x0007 + m_bank[0]->configure_entry(0, &m_share[0x00004]); + m_bank[0]->configure_entry(1, &m_share[0x10004]); + + // 0x000f - 0x000f + m_bank[1]->configure_entry(0, &m_share[0x0000f]); + m_bank[1]->configure_entry(1, &m_share[0x1000f]); + + // 0x0000 - 0x3fff + m_bank[2]->configure_entry(0, &m_share[0x00020]); + m_bank[2]->configure_entry(1, &m_share[0x10020]); + + // 0x4000 - 0x5fff + m_bank[3]->configure_entry(0, &m_share[0x08000]); + m_bank[3]->configure_entry(1, &m_share[0x18000]); + + // 0x6000 - 0xbeff + m_bank[4]->configure_entry(0, &m_share[0x0a000]); + m_bank[4]->configure_entry(1, &m_share[0x1a000]); + + // 0xc000 - 0xdfff + m_bank[5]->configure_entry(0, &m_share[0x04000]); + m_bank[5]->configure_entry(1, &m_share[0x14000]); + + // 0xe000 - 0xffff + m_bank[6]->configure_entry(0, &m_share[0x06000]); + m_bank[6]->configure_entry(1, &m_share[0x16000]); + + // 0xff00 - 0xffff + m_bank[7]->configure_entry(0, &m_share[0x07f00]); + m_bank[7]->configure_entry(1, &m_share[0x07f00]); + + owning_slot().memspace().install_view(0x0000, 0xffff, m_view); + + m_view[0].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map0); + m_view[1].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map1); + m_view[2].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map2); + m_view[3].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map3); + m_view[4].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map4); + m_view[5].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map5); + m_view[6].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map6); + m_view[7].install_device(0x0000, 0xffff, *this, &mc10_pak_mcx128_device::view_map7); +} + +//------------------------------------------------- +// device_reset - device-specific startup +//------------------------------------------------- + +void mc10_pak_mcx128_device::device_reset() +{ + ram_bank_cr = 0; + rom_map_cr = 0; + update_banks(); +} + +void mc10_pak_mcx128_device::device_post_load() +{ + update_banks(); +} + +void mc10_pak_mcx128_device::write_ram_mirror(address_space &space, offs_t offset, u8 data) +{ + std::optional cur_slot = m_view.entry(); + m_share[0x08000+offset] = data; + + if (cur_slot.has_value()) + { + int cur_slot_int = *cur_slot; + m_view.disable(); + space.write_byte(0x4000+offset, data); + m_view.select(cur_slot_int); + } +} + +u8 mc10_pak_mcx128_device::control_register_read(offs_t offset) +{ + if (offset==0) + return ram_bank_cr & 0x03; + + return rom_map_cr & 0x03; +} + +void mc10_pak_mcx128_device::control_register_write(offs_t offset, u8 data) +{ + if (offset==0) + ram_bank_cr = data; + else + rom_map_cr = data; + + update_banks(); +} + +void mc10_pak_mcx128_device::update_banks() +{ + int bank0 = ram_bank_cr & 0x01; + int bank1 = (ram_bank_cr & 0x02) >> 1; + + m_bank[0]->set_entry(bank0); + m_bank[1]->set_entry(bank0); + m_bank[2]->set_entry(bank0); + m_bank[3]->set_entry(bank1); + m_bank[4]->set_entry(bank1); + m_bank[5]->set_entry(bank0); + m_bank[6]->set_entry(bank0); + m_bank[7]->set_entry(bank0); + + m_view.select((bank1 << 2) | (rom_map_cr & 0x03)); + LOG("view select: %d, bank cr: %d\n", (bank1 << 2) | (rom_map_cr & 0x03), ram_bank_cr & 0x03 ); +} + +class alice_pak_mcx128_device : public mc10_pak_mcx128_device +{ +public: + // construction/destruction + alice_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + +protected: + // device-level overrides + virtual const tiny_rom_entry *device_rom_region() const override + { + return ROM_NAME(alice_mcx128); + } +}; + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- + +alice_pak_mcx128_device::alice_pak_mcx128_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : mc10_pak_mcx128_device(mconfig, ALICE_PAK_MCX128, tag, owner, clock) +{ +} + +DEFINE_DEVICE_TYPE_PRIVATE(ALICE_PAK_MCX128, device_mc10cart_interface, alice_pak_mcx128_device, "alice_mcx128", "Darren Atkinson's MCX-128 cartridge (Alice ROM)") diff --git a/src/devices/bus/mc10/mcx128.h b/src/devices/bus/mc10/mcx128.h new file mode 100644 index 00000000000..29ae63b64e2 --- /dev/null +++ b/src/devices/bus/mc10/mcx128.h @@ -0,0 +1,15 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +#ifndef MAME_BUS_MC10_MC10_MCX128_H +#define MAME_BUS_MC10_MC10_MCX128_H + +#pragma once + +#include "mc10_cart.h" + +// device type definition +DECLARE_DEVICE_TYPE(MC10_PAK_MCX128, device_mc10cart_interface) +DECLARE_DEVICE_TYPE(ALICE_PAK_MCX128, device_mc10cart_interface) + +#endif // MAME_BUS_MC10_MC10_MCX128_H + diff --git a/src/devices/bus/mc10/pak.cpp b/src/devices/bus/mc10/pak.cpp new file mode 100644 index 00000000000..8e27d58ab8b --- /dev/null +++ b/src/devices/bus/mc10/pak.cpp @@ -0,0 +1,69 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/*************************************************************************** + + pak.cpp + + Code for emulating standard MC-10 cartridges with only ROM + +***************************************************************************/ + +#include "emu.h" +#include "pak.h" + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(MC10_PAK, mc10_pak_device, "mc10pak", "MC-10 Program PAK") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- +mc10_pak_device::mc10_pak_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) +{ +} + +mc10_pak_device::mc10_pak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : mc10_pak_device(mconfig, MC10_PAK, tag, owner, clock) +{ +} + +//------------------------------------------------- +// max_rom_length - device-specific startup +//------------------------------------------------- + +int mc10_pak_device::max_rom_length() const +{ + return 1024 * 16; +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10_pak_device::device_start() +{ +} + +//------------------------------------------------- +// load - install rom region +//------------------------------------------------- + +image_init_result mc10_pak_device::load() +{ + // if the host has supplied a ROM space, install it + memory_region *const romregion(memregion("^rom")); + if (romregion) + owning_slot().memspace().install_rom(0x5000, 0x5000 + romregion->bytes(), romregion->base()); + else + return image_init_result::FAIL; + + return image_init_result::PASS; +} diff --git a/src/devices/bus/mc10/pak.h b/src/devices/bus/mc10/pak.h new file mode 100644 index 00000000000..797cea2f691 --- /dev/null +++ b/src/devices/bus/mc10/pak.h @@ -0,0 +1,37 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +#ifndef MAME_BUS_MC10_MC10_PAK_H +#define MAME_BUS_MC10_MC10_PAK_H + +#pragma once + +#include "mc10_cart.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> mc10_pak_device + +class mc10_pak_device : + public device_t, + public device_mc10cart_interface +{ +public: + // construction/destruction + mc10_pak_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + virtual int max_rom_length() const override; + virtual image_init_result load() override; + +protected: + mc10_pak_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock); + + // device-level overrides + virtual void device_start() override; +}; + +// device type definitions +DECLARE_DEVICE_TYPE(MC10_PAK, mc10_pak_device) + +#endif // MAME_BUS_MC10_MC10_PAK_H diff --git a/src/devices/bus/mc10/ram.cpp b/src/devices/bus/mc10/ram.cpp new file mode 100644 index 00000000000..f6a6f488955 --- /dev/null +++ b/src/devices/bus/mc10/ram.cpp @@ -0,0 +1,78 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +/*************************************************************************** + + ram.cpp + + Code for emulating the Radio Shack 16K RAM Cartridge + +***************************************************************************/ + +#include "emu.h" +#include "ram.h" + +// #include "machine/ram.h" + +// #define VERBOSE (LOG_GENERAL ) +#include "logmacro.h" + + +//************************************************************************** +// TYPE DECLARATIONS +//************************************************************************** + +namespace +{ + // ======================> mc10_pak_device + + class mc10_pak_ram_device : + public device_t, + public device_mc10cart_interface + { + public: + // construction/destruction + mc10_pak_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock); + + protected: + // device-level overrides + virtual void device_start() override; + private: + memory_share_creator m_share; + }; +}; + + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE_PRIVATE(MC10_PAK_RAM, device_mc10cart_interface, mc10_pak_ram_device, "mc10pakram", "Radio Shack 16K RAM Cartridge") + + + +//------------------------------------------------- +// mc10_pak_device - constructor +//------------------------------------------------- + +mc10_pak_ram_device::mc10_pak_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) + : device_t(mconfig, MC10_PAK_RAM, tag, owner, clock) + , device_mc10cart_interface(mconfig, *this) + , m_share(*this, "ext_ram", 1024*16, ENDIANNESS_BIG) +{ +} + + + +//************************************************************************** +// MACHINE FRAGMENTS AND ADDRESS MAPS +//************************************************************************** + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void mc10_pak_ram_device::device_start() +{ + owning_slot().memspace().install_ram(0x5000, 0x8fff, &m_share[0]); +} diff --git a/src/devices/bus/mc10/ram.h b/src/devices/bus/mc10/ram.h new file mode 100644 index 00000000000..e32530f81e6 --- /dev/null +++ b/src/devices/bus/mc10/ram.h @@ -0,0 +1,14 @@ +// license:BSD-3-Clause +// copyright-holders:tim lindner +#ifndef MAME_BUS_MC10_MC10_RAM_H +#define MAME_BUS_MC10_MC10_RAM_H + +#pragma once + +#include "mc10_cart.h" + +// device type definition +DECLARE_DEVICE_TYPE(MC10_PAK_RAM, device_mc10cart_interface) + +#endif // MAME_BUS_MC10_MC10_RAM_H + diff --git a/src/mame/drivers/mc10.cpp b/src/mame/drivers/mc10.cpp index c389f7055c9..82764d6f977 100644 --- a/src/mame/drivers/mc10.cpp +++ b/src/mame/drivers/mc10.cpp @@ -4,16 +4,14 @@ TRS-80 Radio Shack MicroColor Computer - May 2020: Added emulation for Darren Atkinson's MCX 128. - ***************************************************************************/ - #include "emu.h" #include "cpu/m6800/m6801.h" #include "imagedev/cassette.h" #include "imagedev/printer.h" +#include "bus/mc10/mc10_cart.h" #include "bus/rs232/rs232.h" #include "machine/ram.h" #include "machine/timer.h" @@ -26,7 +24,6 @@ #include "formats/coco_cas.h" - namespace { @@ -41,33 +38,30 @@ public: : driver_device(mconfig, type, tag) , m_maincpu(*this, "maincpu") , m_ram(*this, RAM_TAG) - , m_bank1(*this, "bank1") - , m_bank2(*this, "bank2") + , m_mc10cart(*this, "ext") , m_mc6847(*this, "mc6847") - , m_ef9345(*this, "ef9345") , m_dac(*this, "dac") , m_cassette(*this, "cassette") , m_rs232(*this, "rs232") , m_pb(*this, "pb%u", 0U) - { } + {} - void alice90(machine_config &config); - void alice32(machine_config &config); + void mc10_base(machine_config &config); + void mc10_video(machine_config &config); void mc10(machine_config &config); + void alice(machine_config &config); + void mc10_bfff_w_dac(uint8_t data); + uint8_t mc10_bfff_r(); protected: - uint8_t mc10_bfff_r(); void mc10_bfff_w(uint8_t data); uint8_t mc10_port1_r(); void mc10_port1_w(uint8_t data); uint8_t mc10_port2_r(); void mc10_port2_w(uint8_t data); - uint8_t alice90_bfff_r(); - void alice32_bfff_w(uint8_t data); uint8_t mc6847_videoram_r(offs_t offset); - TIMER_DEVICE_CALLBACK_MEMBER(alice32_scanline); // device-level overrides virtual void driver_start() override; @@ -75,74 +69,48 @@ protected: required_device m_maincpu; required_device m_ram; - required_memory_bank m_bank1; - optional_memory_bank m_bank2; + optional_device m_mc10cart; - uint8_t *m_ram_base; - uint32_t m_ram_size; uint8_t m_keyboard_strobe; uint8_t m_port2; uint8_t read_keyboard_strobe(bool single_line); + mc10cart_slot_device &mc10cart() { return *m_mc10cart; } + private: - void alice32_mem(address_map &map); - void alice90_mem(address_map &map); void mc10_mem(address_map &map); optional_device m_mc6847; - optional_device m_ef9345; required_device m_dac; required_device m_cassette; required_device m_rs232; required_ioport_array<8> m_pb; }; -class mcx128_state : public mc10_state +class alice32_state : public mc10_state { public: - mcx128_state(const machine_config &mconfig, device_type type, const char *tag) + alice32_state(const machine_config &mconfig, device_type type, const char *tag) : mc10_state(mconfig, type, tag) - , m_mcx_ram(*this, "mcx_ram") - , m_mcx_cart_rom_base(*this, "cart") - , m_mcx_int_rom_base(*this, "maincpu") - , m_bank3(*this, "bank3") - , m_bank4r(*this, "bank4r") - , m_bank4w(*this, "bank4w") - , m_bank5r(*this, "bank5r") - , m_bank5w(*this, "bank5w") - , m_bank6r(*this, "bank6r") - , m_bank6w(*this, "bank6w") - { } + , m_ef9345(*this, "ef9345") + {} - void mcx128(machine_config &config); - -private: - uint8_t mcx128_bf00_r(offs_t offset); - void mcx128_bf00_w(offs_t offset, uint8_t data); - - void mcx128_mem(address_map &map); - void update_mcx128_banking(); + void alice32(machine_config &config); + void alice90(machine_config &config); + void alice32_bfff_w(uint8_t data); + uint8_t alice90_bfff_r(); +protected: // device-level overrides virtual void driver_start() override; - virtual void driver_reset() override; - required_device m_mcx_ram; - required_region_ptr m_mcx_cart_rom_base; - required_region_ptr m_mcx_int_rom_base; - required_memory_bank m_bank3; - required_memory_bank m_bank4r; - required_memory_bank m_bank4w; - required_memory_bank m_bank5r; - required_memory_bank m_bank5w; - required_memory_bank m_bank6r; - required_memory_bank m_bank6w; + TIMER_DEVICE_CALLBACK_MEMBER(alice32_scanline); + required_device m_ef9345; - uint8_t *m_mcx_ram_base; - - uint8_t m_bank_control; - uint8_t m_map_control; +private: + void alice32_mem(address_map &map); + void alice90_mem(address_map &map); }; /*************************************************************************** @@ -162,16 +130,16 @@ uint8_t mc10_state::read_keyboard_strobe(bool single_line) read = true; } } + return result; } - uint8_t mc10_state::mc10_bfff_r() { return read_keyboard_strobe(false); } -uint8_t mc10_state::alice90_bfff_r() +uint8_t alice32_state::alice90_bfff_r() { return read_keyboard_strobe(true); } @@ -186,119 +154,29 @@ void mc10_state::mc10_bfff_w(uint8_t data) m_mc6847->ag_w(BIT(data, 5)); m_mc6847->css_w(BIT(data, 6)); - // bit 7, dac output - m_dac->write(BIT(data, 7)); + mc10_bfff_w_dac(data); } -void mc10_state::alice32_bfff_w(uint8_t data) +void mc10_state::mc10_bfff_w_dac(uint8_t data) { // bit 7, dac output m_dac->write(BIT(data, 7)); } -/*************************************************************************** - $bf00: RAM Bank Control Register - 7 6 5 4 3 2 1 0 - | | | | | | | | - | | | | | | | +- Bank Selection for Page 0 - | | | | | | +--- Bank Selection for Page 1 - +-+-+-+-+-+----- N/C - $bf01: ROM Map Control Register - 7 6 5 4 3 2 1 0 | reading | writing | - | | | | | | | | 0 0 - 16K External ROM 16K RAM - | | | | | | | +-\_ 0 1 - 8K RAM / 8K External ROM 16K RAM - | | | | | | +---/ 1 0 - 8K RAM / 8K Internal ROM 16K RAM - | | | | | | 1 1 - 16K RAM 16K RAM - +-+-+-+-+-+--------N/C -***************************************************************************/ - -void mcx128_state::update_mcx128_banking() +void alice32_state::alice32_bfff_w(uint8_t data) { - int32_t bank_offset_page_0 = 0x10000 * BIT(m_bank_control,0); - int32_t bank_offset_page_1 = 0x10000 * BIT(m_bank_control,1); - - // 0x0000 - 0x3fff - m_bank1->set_base(m_mcx_ram_base + bank_offset_page_0 + 0); - - // 0x4000 - 0x4fff - if( bank_offset_page_1 == 0) - m_bank2->set_base(m_ram_base); /* internal 4K when page is 0 */ - else - m_bank2->set_base(m_mcx_ram_base + bank_offset_page_1 + 0x8000); - - // 0x5000 - 0xbeff - m_bank3->set_base(m_mcx_ram_base + bank_offset_page_1 + 0x8000 + 0x1000); - - // 0xc000 - 0xdfff - m_bank4w->set_base(m_mcx_ram_base + bank_offset_page_0 + 0x4000); - - // 0xe000 - 0xfeff - m_bank5w->set_base(m_mcx_ram_base + bank_offset_page_0 + 0x6000); - - // 0xff00 - 0xffff - m_bank6w->set_base(m_mcx_ram_base + 0 + 0x7f00); /* always bank 0 */ - - switch( m_map_control ) - { - case 0: - m_bank4r->set_base(m_mcx_cart_rom_base); - m_bank5r->set_base(m_mcx_cart_rom_base + 0x2000); - m_bank6r->set_entry(0); - break; - - case 1: - m_bank4r->set_base(m_mcx_ram_base + bank_offset_page_0 + 0x4000); - m_bank5r->set_base(m_mcx_cart_rom_base + 0x2000 + 0x2000); // invalid address, what should it be? - m_bank6r->set_entry(1); - break; - - case 2: - m_bank4r->set_base(m_mcx_ram_base + bank_offset_page_0 + 0x4000); - m_bank5r->set_base(m_mcx_int_rom_base); - m_bank6r->set_entry(2); - break; - - case 3: - m_bank4r->set_base(m_mcx_ram_base + bank_offset_page_0 + 0x4000); - m_bank5r->set_base(m_mcx_ram_base + bank_offset_page_0 + 0x6000); - m_bank6r->set_entry(3); /* always bank 0 */ - break; - - default: - // can't get here - break; - } + mc10_bfff_w_dac(data); } -uint8_t mcx128_state::mcx128_bf00_r(offs_t offset) -{ - if( (offset & 1) == 0 ) return m_bank_control; - - return m_map_control; -} - -void mcx128_state::mcx128_bf00_w(offs_t offset, uint8_t data) -{ - if( (offset & 1) == 0 ) - m_bank_control = data & 3; - else - m_map_control = data & 3; - - update_mcx128_banking(); -} - - /*************************************************************************** MC6803 I/O ***************************************************************************/ -/* keyboard strobe */ uint8_t mc10_state::mc10_port1_r() { return m_keyboard_strobe; } -/* keyboard strobe */ void mc10_state::mc10_port1_w(uint8_t data) { m_keyboard_strobe = data; @@ -329,7 +207,6 @@ void mc10_state::mc10_port2_w(uint8_t data) { // bit 0, cassette & printer output m_cassette->output( BIT(data, 0) ? +1.0 : -1.0); - m_rs232->write_txd(BIT(data, 0) ? 1 : 0); m_port2 = data; @@ -343,13 +220,14 @@ void mc10_state::mc10_port2_w(uint8_t data) uint8_t mc10_state::mc6847_videoram_r(offs_t offset) { if (offset == ~0) return 0xff; - m_mc6847->inv_w(BIT(m_ram_base[offset], 6)); - m_mc6847->as_w(BIT(m_ram_base[offset], 7)); - return m_ram_base[offset]; + uint8_t result = m_ram->read(offset); + m_mc6847->inv_w(BIT(result, 6)); + m_mc6847->as_w(BIT(result, 7)); + return result; } -TIMER_DEVICE_CALLBACK_MEMBER(mc10_state::alice32_scanline) +TIMER_DEVICE_CALLBACK_MEMBER(alice32_state::alice32_scanline) { m_ef9345->update_scanline((uint16_t)param); } @@ -358,73 +236,37 @@ TIMER_DEVICE_CALLBACK_MEMBER(mc10_state::alice32_scanline) DRIVER INIT ***************************************************************************/ - void mc10_state::driver_reset() { - /* initialize keyboard strobe */ m_keyboard_strobe = 0x00; } void mc10_state::driver_start() { - // call base device_start driver_device::driver_start(); - address_space &prg = m_maincpu->space(AS_PROGRAM); - - /* initialize memory */ - m_ram_base = m_ram->pointer(); - m_ram_size = m_ram->size(); - m_bank1->set_base(m_ram_base); - - /* initialize memory expansion */ - if (m_bank2) - { - if (m_ram_size == 20 * 1024) - m_bank2->set_base(m_ram_base + 0x1000); - else if (m_ram_size == 24 * 1024) - m_bank2->set_base(m_ram_base + 0x2000); - else if (m_ram_size != 32 * 1024) //ensure that is not alice90 - prg.nop_readwrite(0x5000, 0x8fff); - } - - /* register for state saving */ save_item(NAME(m_keyboard_strobe)); - //for alice32 force port4 DDR to 0xff at startup - //if (!strcmp(machine().system().name, "alice32") || !strcmp(machine().system().name, "alice90")) - //m_maincpu->m6801_io_w(prg, 0x05, 0xff); + address_space &space = m_maincpu->space(AS_PROGRAM); + u32 ram_size = m_ram->size(); + + // don't step on hardware page at 0xbf00 + if (ram_size == 0x8000) + ram_size -= 0x100; + + space.install_ram(0x4000, 0x4000+ram_size-1, m_ram->pointer()); } -void mcx128_state::driver_start() +void alice32_state::driver_start() { - // call base device_start driver_device::driver_start(); - /* initialize memory */ - m_ram_base = m_ram->pointer(); - m_ram_size = m_ram->size(); + save_item(NAME(m_keyboard_strobe)); - m_mcx_ram_base = m_mcx_ram->pointer(); + address_space &space = m_maincpu->space(AS_PROGRAM); + u32 ram_size = m_ram->size(); - save_item(NAME(m_bank_control)); - save_item(NAME(m_map_control)); - - m_bank6r->configure_entry(0, m_mcx_cart_rom_base + 0x3f00); - m_bank6r->configure_entry(1, m_mcx_cart_rom_base + 0x5f00); // invalid address, what should it be? - m_bank6r->configure_entry(2, m_mcx_int_rom_base + 0x1f00); - m_bank6r->configure_entry(3, m_mcx_ram_base + 0x7f00); -} - -void mcx128_state::driver_reset() -{ - // call base device_start - mc10_state::driver_reset(); - - m_bank_control = 0; - m_map_control = 0; - - update_mcx128_banking(); + space.install_ram(0x3000, 0x3000+ram_size-1, m_ram->pointer()); } /*************************************************************************** @@ -433,47 +275,28 @@ void mcx128_state::driver_reset() void mc10_state::mc10_mem(address_map &map) { - map(0x0100, 0x3fff).noprw(); /* unused */ - map(0x4000, 0x4fff).bankrw("bank1"); /* 4k internal ram */ - map(0x5000, 0x8fff).bankrw("bank2"); /* 16k memory expansion */ - map(0x9000, 0xbffe).noprw(); /* unused */ + // mc10 / alice: RAM start at 0x4000, installed in driver_start map(0xbfff, 0xbfff).rw(FUNC(mc10_state::mc10_bfff_r), FUNC(mc10_state::mc10_bfff_w)); - map(0xe000, 0xffff).rom().region("maincpu", 0x0000); /* ROM */ + map(0xe000, 0xffff).rom().region("maincpu", 0x0000); } -void mc10_state::alice32_mem(address_map &map) +void alice32_state::alice32_mem(address_map &map) { - map(0x0100, 0x2fff).noprw(); /* unused */ - map(0x3000, 0x4fff).bankrw("bank1"); /* 8k internal ram */ - map(0x5000, 0x8fff).bankrw("bank2"); /* 16k memory expansion */ - map(0x9000, 0xafff).noprw(); /* unused */ + // alice32: RAM start at 0x3000, installed in driver_start map(0xbf20, 0xbf29).rw(m_ef9345, FUNC(ef9345_device::data_r), FUNC(ef9345_device::data_w)); - map(0xbfff, 0xbfff).rw(FUNC(mc10_state::mc10_bfff_r), FUNC(mc10_state::alice32_bfff_w)); - map(0xc000, 0xffff).rom().region("maincpu", 0x0000); /* ROM */ + map(0xbfff, 0xbfff).rw(FUNC(mc10_state::mc10_bfff_r), FUNC(alice32_state::alice32_bfff_w)); + map(0xc000, 0xffff).rom().region("maincpu", 0x0000); } -void mc10_state::alice90_mem(address_map &map) +void alice32_state::alice90_mem(address_map &map) { - map(0x0100, 0x2fff).noprw(); /* unused */ - map(0x3000, 0xafff).bankrw("bank1"); /* 32k internal ram */ + // alice90: RAM start at 0x3000, installed in driver_start map(0xbf20, 0xbf29).rw(m_ef9345, FUNC(ef9345_device::data_r), FUNC(ef9345_device::data_w)); - map(0xbfff, 0xbfff).rw(FUNC(mc10_state::alice90_bfff_r), FUNC(mc10_state::alice32_bfff_w)); - map(0xc000, 0xffff).rom().region("maincpu", 0x0000); /* ROM */ + map(0xbfff, 0xbfff).rw(FUNC(alice32_state::alice90_bfff_r), FUNC(alice32_state::alice32_bfff_w)); + map(0xc000, 0xffff).rom().region("maincpu", 0x0000); } -void mcx128_state::mcx128_mem(address_map &map) -{ - map(0x0000, 0x3fff).bankrw("bank1"); - map(0x4000, 0x4fff).bankrw("bank2"); - map(0x5000, 0xbeff).bankrw("bank3"); - map(0xbf00, 0xbf01).rw(FUNC(mcx128_state::mcx128_bf00_r), FUNC(mcx128_state::mcx128_bf00_w)); - map(0xbf02, 0xbf7f).noprw(); /* unused */ - map(0xbf80, 0xbffe).noprw(); /* unused */ - map(0xbfff, 0xbfff).rw(FUNC(mcx128_state::mc10_bfff_r), FUNC(mcx128_state::mc10_bfff_w)); - map(0xc000, 0xdfff).bankr("bank4r").bankw("bank4w"); - map(0xe000, 0xfeff).bankr("bank5r").bankw("bank5w"); - map(0xff00, 0xffff).bankr("bank6r").bankw("bank6w"); -} + /*************************************************************************** INPUT PORTS @@ -659,7 +482,7 @@ DEVICE_INPUT_DEFAULTS_END MACHINE DRIVERS ***************************************************************************/ -void mc10_state::mc10(machine_config &config) +void mc10_state::mc10_base(machine_config &config) { /* basic machine hardware */ M6803(config, m_maincpu, XTAL(3'579'545)); /* 0,894886 MHz */ @@ -669,56 +492,6 @@ void mc10_state::mc10(machine_config &config) m_maincpu->in_p2_cb().set(FUNC(mc10_state::mc10_port2_r)); m_maincpu->out_p2_cb().set(FUNC(mc10_state::mc10_port2_w)); - /* video hardware */ - SCREEN(config, "screen", SCREEN_TYPE_RASTER); - - mc6847_ntsc_device &vdg(MC6847_NTSC(config, "mc6847", XTAL(3'579'545))); - vdg.set_screen("screen"); - vdg.input_callback().set(FUNC(mc10_state::mc6847_videoram_r)); - - /* sound hardware */ - SPEAKER(config, "speaker").front_center(); - DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.0625); - - CASSETTE(config, m_cassette); - m_cassette->set_formats(coco_cassette_formats); - m_cassette->set_default_state(CASSETTE_STOPPED | CASSETTE_SPEAKER_ENABLED | CASSETTE_MOTOR_ENABLED); - m_cassette->add_route(ALL_OUTPUTS, "speaker", 0.05); - m_cassette->set_interface("mc10_cass"); - - /* printer */ - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "printer")); - rs232.set_option_device_input_defaults("printer", DEVICE_INPUT_DEFAULTS_NAME(printer)); - - /* internal ram */ - RAM(config, m_ram).set_default_size("20K").set_extra_options("4K"); - - /* Software lists */ - SOFTWARE_LIST(config, "cass_list").set_original("mc10"); -} - -void mc10_state::alice32(machine_config &config) -{ - M6803(config, m_maincpu, XTAL(3'579'545)); - m_maincpu->set_addrmap(AS_PROGRAM, &mc10_state::alice32_mem); - m_maincpu->in_p1_cb().set(FUNC(mc10_state::mc10_port1_r)); - m_maincpu->out_p1_cb().set(FUNC(mc10_state::mc10_port1_w)); - m_maincpu->in_p2_cb().set(FUNC(mc10_state::mc10_port2_r)); - m_maincpu->out_p2_cb().set(FUNC(mc10_state::mc10_port2_w)); - - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(60); - screen.set_screen_update("ef9345", FUNC(ef9345_device::screen_update)); - screen.set_size(336, 270); - screen.set_visarea(00, 336-1, 00, 270-1); - PALETTE(config, "palette").set_entries(8); - - EF9345(config, m_ef9345, 0); - m_ef9345->set_screen("screen"); - m_ef9345->set_palette_tag("palette"); - TIMER(config, "alice32_sl").configure_scanline(FUNC(mc10_state::alice32_scanline), "screen", 0, 10); - /* sound hardware */ SPEAKER(config, "speaker").front_center(); DAC_1BIT(config, m_dac, 0).add_route(ALL_OUTPUTS, "speaker", 0.0625); @@ -730,22 +503,91 @@ void mc10_state::alice32(machine_config &config) m_cassette->set_interface("mc10_cass"); /* printer */ - rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "printer")); - rs232.set_option_device_input_defaults("printer", DEVICE_INPUT_DEFAULTS_NAME(printer)); + rs232_port_device &rs232(RS232_PORT(config, "rs232", default_rs232_devices, "rs_printer")); + rs232.set_option_device_input_defaults("rs_printer", DEVICE_INPUT_DEFAULTS_NAME(printer)); +} +void mc10_state::mc10_video(machine_config &config) +{ /* internal ram */ - RAM(config, m_ram).set_default_size("24K").set_extra_options("8K"); + RAM(config, m_ram).set_default_size("4K").set_extra_options("8K,20K,32K"); + + /* video hardware */ + SCREEN(config, "screen", SCREEN_TYPE_RASTER).set_raw(9.828_MHz_XTAL / 2, 320, 0, 320, 243, 0, 243); + + mc6847_ntsc_device &vdg(MC6847_NTSC(config, "mc6847", XTAL(3'579'545))); + vdg.set_screen("screen"); + vdg.input_callback().set(FUNC(mc10_state::mc6847_videoram_r)); +} + +void mc10_state::mc10(machine_config &config) +{ + mc10_base(config); + mc10_video(config); + + /* expansion port hardware */ + mc10cart_slot_device &cartslot(MC10CART_SLOT(config, "ext", DERIVED_CLOCK(1, 1), mc10_cart_add_basic_devices, nullptr)); + cartslot.set_memspace(m_maincpu, AS_PROGRAM); + cartslot.nmi_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); + + /* Software lists */ + SOFTWARE_LIST(config, "cass_list").set_original("mc10"); +} + +void mc10_state::alice(machine_config &config) +{ + mc10_base(config); + mc10_video(config); + + /* expansion port hardware */ + mc10cart_slot_device &cartslot(MC10CART_SLOT(config, "ext", DERIVED_CLOCK(1, 1), alice_cart_add_basic_devices, nullptr)); + cartslot.set_memspace(m_maincpu, AS_PROGRAM); + cartslot.nmi_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); + + /* Software lists */ + SOFTWARE_LIST(config, "cass_list").set_original("mc10"); +} + +void alice32_state::alice32(machine_config &config) +{ + mc10_base(config); + + /* basic machine hardware */ + m_maincpu->set_addrmap(AS_PROGRAM, &alice32_state::alice32_mem); + + /* video hardware */ + screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); + screen.set_refresh_hz(60); + screen.set_screen_update("ef9345", FUNC(ef9345_device::screen_update)); + screen.set_size(336, 270); + screen.set_visarea(00, 336-1, 00, 270-1); + PALETTE(config, "palette").set_entries(8); + + EF9345(config, m_ef9345, 0); + m_ef9345->set_screen("screen"); + m_ef9345->set_palette_tag("palette"); + TIMER(config, "alice32_sl").configure_scanline(FUNC(alice32_state::alice32_scanline), "screen", 0, 10); + + /* expansion port hardware */ + mc10cart_slot_device &cartslot(MC10CART_SLOT(config, "ext", DERIVED_CLOCK(1, 1), alice32_cart_add_basic_devices, nullptr)); + cartslot.set_memspace(m_maincpu, AS_PROGRAM); + cartslot.nmi_callback().set_inputline(m_maincpu, INPUT_LINE_NMI); + /* internal ram */ + RAM(config, m_ram).set_default_size("8K").set_extra_options("24K"); /* Software lists */ SOFTWARE_LIST(config, "cass_list").set_original("alice32"); SOFTWARE_LIST(config, "mc10_cass").set_compatible("mc10"); } -void mc10_state::alice90(machine_config &config) +void alice32_state::alice90(machine_config &config) { alice32(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mc10_state::alice90_mem); + /* basic machine hardware */ + m_maincpu->set_addrmap(AS_PROGRAM, &alice32_state::alice90_mem); + + /* internal ram */ m_ram->set_default_size("32K"); /* Software lists */ @@ -754,20 +596,6 @@ void mc10_state::alice90(machine_config &config) config.device_remove("mc10_cass"); } -void mcx128_state::mcx128(machine_config &config) -{ - mc10(config); - m_maincpu->set_addrmap(AS_PROGRAM, &mcx128_state::mcx128_mem); - - /* internal ram */ - m_ram->set_default_size("4K"); - RAM(config, m_mcx_ram).set_default_size("128K"); - - /* Software lists */ - /* to do */ -} - - /*************************************************************************** ROM DEFINITIONS ***************************************************************************/ @@ -798,31 +626,14 @@ ROM_START( alice90 ) ROM_LOAD( "charset.rom", 0x0000, 0x2000, BAD_DUMP CRC(b2f49eb3) SHA1(d0ef530be33bfc296314e7152302d95fdf9520fc) ) // from dcvg5k ROM_END -ROM_START( mcx128 ) - ROM_REGION(0x2000, "maincpu", 0) - ROM_LOAD("mc10.rom", 0x0000, 0x2000, CRC(11fda97e) SHA1(4afff2b4c120334481aab7b02c3552bf76f1bc43)) - ROM_REGION(0x4000, "cart", 0) - ROM_LOAD("mcx128bas.rom", 0x0000, 0x4000, CRC(11202e4b) SHA1(36c30d0f198a1bffee88ef29d92f2401447a91f4)) -ROM_END - -ROM_START( alice128 ) - ROM_REGION(0x2000, "maincpu", 0) - ROM_LOAD("alice.rom", 0x0000, 0x2000, CRC(f876abe9) SHA1(c2166b91e6396a311f486832012aa43e0d2b19f8)) - ROM_REGION(0x4000, "cart", 0) - ROM_LOAD("alice128bas.rom", 0x0000, 0x4000, CRC(a737544a) SHA1(c8fd92705fc42deb6a0ffac6274e27fd61ecd4cc)) -ROM_END - } /*************************************************************************** GAME DRIVERS ***************************************************************************/ -// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS -COMP( 1983, mc10, 0, 0, mc10, mc10, mc10_state, empty_init, "Tandy Radio Shack", "MC-10", MACHINE_SUPPORTS_SAVE ) -COMP( 1983, alice, mc10, 0, mc10, alice, mc10_state, empty_init, "Matra & Hachette", "Alice", MACHINE_SUPPORTS_SAVE ) -COMP( 1984, alice32, 0, 0, alice32, alice, mc10_state, empty_init, "Matra & Hachette", "Alice 32", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -COMP( 1985, alice90, alice32, 0, alice90, alice, mc10_state, empty_init, "Matra & Hachette", "Alice 90", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) -COMP( 2011, mcx128, mc10, 0, mcx128, mc10, mcx128_state, empty_init, "Tandy Radio Shack", "MCX-128", MACHINE_SUPPORTS_SAVE | MACHINE_UNOFFICIAL ) -COMP( 2011, alice128,mc10, 0, mcx128, alice, mcx128_state, empty_init, "Matra & Hachette", "Alice with MCX-128", MACHINE_SUPPORTS_SAVE | MACHINE_UNOFFICIAL ) - +// YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS +COMP( 1983, mc10, 0, 0, mc10, mc10, mc10_state, empty_init, "Tandy Radio Shack", "MC-10", MACHINE_SUPPORTS_SAVE ) +COMP( 1983, alice, mc10, 0, alice, alice, mc10_state, empty_init, "Matra & Hachette", "Alice", MACHINE_SUPPORTS_SAVE ) +COMP( 1984, alice32, 0, 0, alice32, alice, alice32_state, empty_init, "Matra & Hachette", "Alice 32", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) +COMP( 1985, alice90, alice32, 0, alice90, alice, alice32_state, empty_init, "Matra & Hachette", "Alice 90", MACHINE_IMPERFECT_GRAPHICS | MACHINE_SUPPORTS_SAVE ) diff --git a/src/mame/mame.lst b/src/mame/mame.lst index d367adba8fd..1dab778ecb0 100644 --- a/src/mame/mame.lst +++ b/src/mame/mame.lst @@ -22423,8 +22423,6 @@ alice // Matra & Hachette Ordinateur Alice alice32 // Matra & Hachette Alice 32 alice90 // Matra & Hachette Alice 90 mc10 // MC-10 -mcx128 // MCX-128 -alice128 // Alice with a MCX-128 @source:mc1000.cpp mc1000 //