From 01ef9a6a44963ae33bee5a45c2f3e4838acc9c5d Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Wed, 16 Jan 2019 20:03:48 +0000 Subject: [PATCH] bbc: Re-implemented ROM slots to be able to handle non-standard ROM devices, and added support for: - 32K ROM slots in B+ and Master series. - PALPROM carrier boards from Computer Concepts, Watford Electronics, etc. - Real Time Clock ROM devices from Solidisk and PMS. - UserRAM sideways RAM from Acorn User. - MRM E00 DFS. --- scripts/src/bus.lua | 23 +++ src/devices/bus/bbc/rom/dfs.cpp | 63 +++++++ src/devices/bus/bbc/rom/dfs.h | 42 +++++ src/devices/bus/bbc/rom/pal.cpp | 308 +++++++++++++++++++++++++++++++ src/devices/bus/bbc/rom/pal.h | 167 +++++++++++++++++ src/devices/bus/bbc/rom/ram.cpp | 57 ++++++ src/devices/bus/bbc/rom/ram.h | 42 +++++ src/devices/bus/bbc/rom/rom.cpp | 50 +++++ src/devices/bus/bbc/rom/rom.h | 41 ++++ src/devices/bus/bbc/rom/rtc.cpp | 122 ++++++++++++ src/devices/bus/bbc/rom/rtc.h | 72 ++++++++ src/devices/bus/bbc/rom/slot.cpp | 234 +++++++++++++++++++++++ src/devices/bus/bbc/rom/slot.h | 155 ++++++++++++++++ src/mame/drivers/bbc.cpp | 47 ++--- src/mame/includes/bbc.h | 31 +--- src/mame/machine/bbc.cpp | 129 +++++-------- 16 files changed, 1438 insertions(+), 145 deletions(-) create mode 100644 src/devices/bus/bbc/rom/dfs.cpp create mode 100644 src/devices/bus/bbc/rom/dfs.h create mode 100644 src/devices/bus/bbc/rom/pal.cpp create mode 100644 src/devices/bus/bbc/rom/pal.h create mode 100644 src/devices/bus/bbc/rom/ram.cpp create mode 100644 src/devices/bus/bbc/rom/ram.h create mode 100644 src/devices/bus/bbc/rom/rom.cpp create mode 100644 src/devices/bus/bbc/rom/rom.h create mode 100644 src/devices/bus/bbc/rom/rtc.cpp create mode 100644 src/devices/bus/bbc/rom/rtc.h create mode 100644 src/devices/bus/bbc/rom/slot.cpp create mode 100644 src/devices/bus/bbc/rom/slot.h diff --git a/scripts/src/bus.lua b/scripts/src/bus.lua index 211542d8189..5350a2d510a 100644 --- a/scripts/src/bus.lua +++ b/scripts/src/bus.lua @@ -363,6 +363,29 @@ if (BUSES["BBC_1MHZBUS"]~=null) then end +--------------------------------------------------- +-- +--@src/devices/bus/bbc/rom/slot.h,BUSES["BBC_ROM"] = true +--------------------------------------------------- + +if (BUSES["BBC_ROM"]~=null) then + files { + MAME_DIR .. "src/devices/bus/bbc/rom/slot.cpp", + MAME_DIR .. "src/devices/bus/bbc/rom/slot.h", + MAME_DIR .. "src/devices/bus/bbc/rom/rom.cpp", + MAME_DIR .. "src/devices/bus/bbc/rom/rom.h", + MAME_DIR .. "src/devices/bus/bbc/rom/ram.cpp", + MAME_DIR .. "src/devices/bus/bbc/rom/ram.h", + MAME_DIR .. "src/devices/bus/bbc/rom/dfs.cpp", + MAME_DIR .. "src/devices/bus/bbc/rom/dfs.h", + MAME_DIR .. "src/devices/bus/bbc/rom/pal.cpp", + MAME_DIR .. "src/devices/bus/bbc/rom/pal.h", + MAME_DIR .. "src/devices/bus/bbc/rom/rtc.cpp", + MAME_DIR .. "src/devices/bus/bbc/rom/rtc.h", + } +end + + --------------------------------------------------- -- --@src/devices/bus/bbc/tube/tube.h,BUSES["BBC_TUBE"] = true diff --git a/src/devices/bus/bbc/rom/dfs.cpp b/src/devices/bus/bbc/rom/dfs.cpp new file mode 100644 index 00000000000..a1f1908dca4 --- /dev/null +++ b/src/devices/bus/bbc/rom/dfs.cpp @@ -0,0 +1,63 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro MRM E00 DFS emulation + + Comprises of 8K ROM and 2K/4K? RAM on a carrier board, with flying lead + to RW line to enable writing to RAM. + +***************************************************************************/ + +#include "emu.h" +#include "dfs.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_MRME00, bbc_mrme00_device, "bbc_mrme00", "BBC Micro MRM E00 DFS") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_rom_device - constructor +//------------------------------------------------- + +bbc_mrme00_device::bbc_mrme00_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_MRME00, tag, owner, clock) + , device_bbc_rom_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_mrme00_device::device_start() +{ +} + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(bbc_mrme00_device::read) +{ + if (offset < get_rom_size()) + return get_rom_base()[offset & (get_rom_size() - 1)]; + else + return get_ram_base()[offset & (get_ram_size() - 1)]; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +WRITE8_MEMBER(bbc_mrme00_device::write) +{ + get_ram_base()[offset & (get_ram_size() - 1)] = data; +} \ No newline at end of file diff --git a/src/devices/bus/bbc/rom/dfs.h b/src/devices/bus/bbc/rom/dfs.h new file mode 100644 index 00000000000..03d1dec7997 --- /dev/null +++ b/src/devices/bus/bbc/rom/dfs.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro MRM E00 DFS emulation + +***************************************************************************/ + +#ifndef MAME_BUS_BBC_ROM_DFS_H +#define MAME_BUS_BBC_ROM_DFS_H + +#pragma once + +#include "slot.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_mrme00_device + +class bbc_mrme00_device : public device_t, + public device_bbc_rom_interface +{ +public: + // construction/destruction + bbc_mrme00_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; +}; + +// device type definition +DECLARE_DEVICE_TYPE(BBC_MRME00, bbc_mrme00_device) + + +#endif // MAME_BUS_BBC_ROM_DFS_H diff --git a/src/devices/bus/bbc/rom/pal.cpp b/src/devices/bus/bbc/rom/pal.cpp new file mode 100644 index 00000000000..e7066d8eac1 --- /dev/null +++ b/src/devices/bus/bbc/rom/pal.cpp @@ -0,0 +1,308 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro PALPROM carrier boards + + Computer Concepts PALPROM carrier boards (PAL16R4): + These were the first to provide a 32K ROM banked into a 16K slot using + a PAL to perform the switching upon reads from pre-programmed zones. In + addition to being able to provide larger ROM based applications such + as Inter-Word and Inter-Base, it also served as copy protection since + the carrier board and PAL would have to be reproduced to support the + ROM. + Other publishers such as Beebug and PMS also used the carrier boards + and PAL provided by Computer Concepts. + + Watford Electronics PALPROM carrier boards (PAL16L8): + The PALPROM device provides a means of running 32K software within the + space allocated to a 16K sideways ROM whilst providing a good degree of + software protection. + Within a PALPROM, a 32K EPROM is divided into 4 banks of 8K. These are + arranged in a 3 plus 1 arrangement. Bank 0, which occupies &8000 to + &9FFF is permanently enabled, whilst banks 1 to 3, which occupy the + region &A000 to &BFFF, are swapped in one at a time. This swapping is + made by performing an access to a special switching zone, of which there + are 8 in total. Accessing a switching zone, which is 32 bytes in length + and aligned to start on a 32 byte boundary, selects a pre-specified bank + (1 to 3) + + P.R.E.S. PALPROM carrier boards: + This was based on the Computer Concepts carrier board. + + Instant Mini Office 2: + Not a PALPROM carrier board but a larger ROM carrier containing 4x32K + and TTL circuits to enable and page each ROM into 16K banks. + +***************************************************************************/ + +#include "emu.h" +#include "pal.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_CCIWORD, bbc_cciword_device, "bbc_cciword", "Computer Concepts 32K ROM Carrier (Inter-Word)") +DEFINE_DEVICE_TYPE(BBC_CCIBASE, bbc_ccibase_device, "bbc_ccibase", "Computer Concepts 64K ROM Carrier (Inter-Base)") +DEFINE_DEVICE_TYPE(BBC_CCISPELL, bbc_ccispell_device, "bbc_ccispell", "Computer Concepts 128K ROM Carrier (SpellMaster)") +DEFINE_DEVICE_TYPE(BBC_PALQST, bbc_palqst_device, "bbc_palqst", "Watford Electronics ROM Carrier (Quest Paint)") +DEFINE_DEVICE_TYPE(BBC_PALWAP, bbc_palwap_device, "bbc_palwap", "Watford Electronics ROM Carrier (Wapping Editor)") +DEFINE_DEVICE_TYPE(BBC_PALTED, bbc_palted_device, "bbc_palted", "Watford Electronics ROM Carrier (TED)") +DEFINE_DEVICE_TYPE(BBC_PALABEP, bbc_palabep_device, "bbc_palabep", "P.R.E.S. 32K ROM Carrier (ABE+)") +DEFINE_DEVICE_TYPE(BBC_PALABE, bbc_palabe_device, "bbc_palabe", "P.R.E.S. 32K ROM Carrier (ABE)") +DEFINE_DEVICE_TYPE(BBC_PALMO2, bbc_palmo2_device, "bbc_palmo2", "Instant Mini Office 2 ROM Carrier") + + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_palprom_device - constructor +//------------------------------------------------- + +bbc_pal_device::bbc_pal_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_bbc_rom_interface(mconfig, *this) + , m_bank(0) +{ +} + +bbc_cciword_device::bbc_cciword_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_CCIWORD, tag, owner, clock) +{ +} + +bbc_ccibase_device::bbc_ccibase_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_CCIBASE, tag, owner, clock) +{ +} + +bbc_ccispell_device::bbc_ccispell_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_CCISPELL, tag, owner, clock) +{ +} + +bbc_palqst_device::bbc_palqst_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_PALQST, tag, owner, clock) +{ +} + +bbc_palwap_device::bbc_palwap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_PALWAP, tag, owner, clock) +{ +} + +bbc_palted_device::bbc_palted_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_PALTED, tag, owner, clock) +{ +} + +bbc_palabep_device::bbc_palabep_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_PALABEP, tag, owner, clock) +{ +} + +bbc_palabe_device::bbc_palabe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_PALABE, tag, owner, clock) +{ +} + +bbc_palmo2_device::bbc_palmo2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_pal_device(mconfig, BBC_PALMO2, tag, owner, clock) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_pal_device::device_start() +{ + save_item(NAME(m_bank)); +} + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(bbc_cciword_device::read) +{ + if (!machine().side_effects_disabled()) + { + switch (offset & 0x3fe0) + { + case 0x0040: m_bank = 1; break; + case 0x0060: m_bank = 0; break; + } + } + + return get_rom_base()[(offset & 0x3fff) | (m_bank << 14)]; +} + +READ8_MEMBER(bbc_ccibase_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for Inter-Base */ + switch (offset & 0x3fe0) + { + case 0x3f80: m_bank = 0; break; + case 0x3fa0: m_bank = 1; break; + case 0x3fc0: m_bank = 2; break; + case 0x3fe0: m_bank = 3; break; + } + } + + return get_rom_base()[(offset & 0x3fff) | (m_bank << 14)]; +} + +READ8_MEMBER(bbc_ccispell_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for SpellMaster */ + if (offset == 0x3fe0) + { + m_bank = 0; + } + else if (m_bank == 0) + { + switch (offset & 0x3fe0) + { + case 0x3fc0: m_bank = 1; break; + case 0x3fa0: m_bank = 2; break; + case 0x3f80: m_bank = 3; break; + case 0x3f60: m_bank = 4; break; + case 0x3f40: m_bank = 5; break; + case 0x3f20: m_bank = 6; break; + case 0x3f00: m_bank = 7; break; + } + } + } + + return get_rom_base()[(offset & 0x3fff) | (m_bank << 14)]; +} + +READ8_MEMBER(bbc_palqst_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for Quest Paint and ConQuest */ + switch (offset & 0x3fe0) + { + case 0x0820: m_bank = 2; break; + case 0x11e0: m_bank = 1; break; + case 0x12c0: m_bank = 3; break; + case 0x1340: m_bank = 0; break; + } + } + + if (offset & 0x2000) + { + return get_rom_base()[(offset & 0x1fff) | (m_bank << 13)]; + } + else + { + return get_rom_base()[offset & 0x1fff]; + } +} + +READ8_MEMBER(bbc_palwap_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for Wapping Editor */ + switch (offset & 0x3fe0) + { + case 0x1f00: m_bank = 0; break; + case 0x1f20: m_bank = 1; break; + case 0x1f40: m_bank = 2; break; + case 0x1f60: m_bank = 3; break; + case 0x1f80: m_bank = 4; break; + case 0x1fa0: m_bank = 5; break; + case 0x1fc0: m_bank = 6; break; + case 0x1fe0: m_bank = 7; break; + } + } + + if (offset & 0x2000) + { + return get_rom_base()[(offset & 0x1fff) | (m_bank << 13)]; + } + else + { + return get_rom_base()[offset & 0x1fff]; + } +} + +READ8_MEMBER(bbc_palted_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for TED */ + switch (offset & 0x3fe0) + { + case 0x1f80: m_bank = 0; break; + case 0x1fa0: m_bank = 1; break; + case 0x1fc0: m_bank = 2; break; + case 0x1fe0: m_bank = 3; break; + } + } + + if (offset & 0x2000) + { + return get_rom_base()[(offset & 0x1fff) | (m_bank << 13)]; + } + else + { + return get_rom_base()[offset & 0x1fff]; + } +} + +READ8_MEMBER(bbc_palabep_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for Advanced BASIC Editor Plus */ + switch (offset & 0x3ffc) + { + case 0x3ff8: m_bank = 0; break; + case 0x3ffc: m_bank = 1; break; + } + } + + return get_rom_base()[(offset & 0x3fff) | (m_bank << 14)]; +} + +READ8_MEMBER(bbc_palabe_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for Advanced BASIC Editor */ + switch (offset & 0x3ffc) + { + case 0x3ff8: m_bank = 1; break; + case 0x3ffc: m_bank = 0; break; + } + } + + return get_rom_base()[(offset & 0x3fff) | (m_bank << 14)]; +} + +READ8_MEMBER(bbc_palmo2_device::read) +{ + if (!machine().side_effects_disabled()) + { + /* switching zones for Instant Mini Office 2 */ + switch (offset & 0x3ff0) + { + case 0x2000: m_bank = offset & 0x0f; break; + } + } + + return get_rom_base()[(offset & 0x3fff) | (m_bank << 13)]; +} diff --git a/src/devices/bus/bbc/rom/pal.h b/src/devices/bus/bbc/rom/pal.h new file mode 100644 index 00000000000..32dd8a23b85 --- /dev/null +++ b/src/devices/bus/bbc/rom/pal.h @@ -0,0 +1,167 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro PALPROM carrier boards + +***************************************************************************/ + +#ifndef MAME_BUS_BBC_ROM_PAL_H +#define MAME_BUS_BBC_ROM_PAL_H + +#pragma once + +#include "slot.h" + + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_pal_device + +class bbc_pal_device : public device_t, + public device_bbc_rom_interface +{ +protected: + // construction/destruction + bbc_pal_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + // device_bbc_rom_interface overrides + virtual uint32_t get_rom_size() override { return 0x4000; } + + uint8_t m_bank; +}; + +// ======================> bbc_cciword_device + +class bbc_cciword_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_cciword_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_ccibase_device + +class bbc_ccibase_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_ccibase_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_ccispell_device + +class bbc_ccispell_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_ccispell_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_palqst_device + +class bbc_palqst_device : public bbc_pal_device +{ +public: + bbc_palqst_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_palwap_device + +class bbc_palwap_device : public bbc_pal_device +{ +public: + bbc_palwap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_palted_device + +class bbc_palted_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_palted_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_palabep_device + +class bbc_palabep_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_palabep_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_palabe_device + +class bbc_palabe_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_palabe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// ======================> bbc_palmo2_device + +class bbc_palmo2_device : public bbc_pal_device +{ +public: + // construction/destruction + bbc_palmo2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_CCIWORD, bbc_cciword_device) +DECLARE_DEVICE_TYPE(BBC_CCIBASE, bbc_ccibase_device) +DECLARE_DEVICE_TYPE(BBC_CCISPELL, bbc_ccispell_device) +DECLARE_DEVICE_TYPE(BBC_PALQST, bbc_palqst_device) +DECLARE_DEVICE_TYPE(BBC_PALWAP, bbc_palwap_device) +DECLARE_DEVICE_TYPE(BBC_PALTED, bbc_palted_device) +DECLARE_DEVICE_TYPE(BBC_PALABEP, bbc_palabep_device) +DECLARE_DEVICE_TYPE(BBC_PALABE, bbc_palabe_device) +DECLARE_DEVICE_TYPE(BBC_PALMO2, bbc_palmo2_device) + + +#endif // MAME_BUS_BBC_ROM_PAL_H diff --git a/src/devices/bus/bbc/rom/ram.cpp b/src/devices/bus/bbc/rom/ram.cpp new file mode 100644 index 00000000000..a1f5283956b --- /dev/null +++ b/src/devices/bus/bbc/rom/ram.cpp @@ -0,0 +1,57 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro Sideways RAM emulation + +***************************************************************************/ + +#include "emu.h" +#include "ram.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_RAM, bbc_ram_device, "bbc_ram", "BBC Micro Sideways RAM") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_ram_device - constructor +//------------------------------------------------- + +bbc_ram_device::bbc_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_RAM, tag, owner, clock) + , device_bbc_rom_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_ram_device::device_start() +{ +} + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(bbc_ram_device::read) +{ + return get_ram_base()[offset & (get_ram_size() - 1)]; +} + +//------------------------------------------------- +// write +//------------------------------------------------- + +WRITE8_MEMBER(bbc_ram_device::write) +{ + get_ram_base()[offset & (get_ram_size() - 1)] = data; +} diff --git a/src/devices/bus/bbc/rom/ram.h b/src/devices/bus/bbc/rom/ram.h new file mode 100644 index 00000000000..7cc075f7388 --- /dev/null +++ b/src/devices/bus/bbc/rom/ram.h @@ -0,0 +1,42 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro Sideways RAM emulation + +***************************************************************************/ + +#ifndef MAME_BUS_BBC_ROM_RAM_H +#define MAME_BUS_BBC_ROM_RAM_H + +#pragma once + +#include "slot.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_ram_device + +class bbc_ram_device : public device_t, + public device_bbc_rom_interface +{ +public: + // construction/destruction + bbc_ram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; + virtual DECLARE_WRITE8_MEMBER(write) override; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_RAM, bbc_ram_device) + +#endif // MAME_BUS_BBC_ROM_RAM_H diff --git a/src/devices/bus/bbc/rom/rom.cpp b/src/devices/bus/bbc/rom/rom.cpp new file mode 100644 index 00000000000..9e9193d0d70 --- /dev/null +++ b/src/devices/bus/bbc/rom/rom.cpp @@ -0,0 +1,50 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro Sideways ROM emulation + +***************************************************************************/ + +#include "emu.h" +#include "rom.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_ROM, bbc_rom_device, "bbc_rom", "BBC Micro Sideways ROM") + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_rom_device - constructor +//------------------------------------------------- + +bbc_rom_device::bbc_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_ROM, tag, owner, clock) + , device_bbc_rom_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_rom_device::device_start() +{ +} + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(bbc_rom_device::read) +{ + uint32_t size = std::min((int32_t)get_rom_size(), 0x4000); + + return get_rom_base()[offset & (size - 1)]; +} diff --git a/src/devices/bus/bbc/rom/rom.h b/src/devices/bus/bbc/rom/rom.h new file mode 100644 index 00000000000..d84cd8cd9d0 --- /dev/null +++ b/src/devices/bus/bbc/rom/rom.h @@ -0,0 +1,41 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + BBC Micro Sideways ROM emulation + +***************************************************************************/ + +#ifndef MAME_BUS_BBC_ROM_ROM_H +#define MAME_BUS_BBC_ROM_ROM_H + +#pragma once + +#include "slot.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_rom_device + +class bbc_rom_device : public device_t, + public device_bbc_rom_interface +{ +public: + // construction/destruction + bbc_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_start() override; + + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; +}; + +// device type definition +DECLARE_DEVICE_TYPE(BBC_ROM, bbc_rom_device) + + +#endif // MAME_BUS_BBC_ROM_ROM_H diff --git a/src/devices/bus/bbc/rom/rtc.cpp b/src/devices/bus/bbc/rom/rtc.cpp new file mode 100644 index 00000000000..ada8646cff1 --- /dev/null +++ b/src/devices/bus/bbc/rom/rtc.cpp @@ -0,0 +1,122 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Solidisk Real Time Clock + + http://chrisacorns.computinghistory.org.uk/8bit_Upgrades/Solidisk_RTC.html + + PMS Genie Watch (RTC for the BBC) + +***************************************************************************/ + +#include "emu.h" +#include "rtc.h" + + +//************************************************************************** +// DEVICE DEFINITIONS +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_STLRTC, bbc_stlrtc_device, "bbc_stlrtc", "Solidisk Real Time Clock") +DEFINE_DEVICE_TYPE(BBC_PMSRTC, bbc_pmsrtc_device, "bbc_pmsrtc", "PMS Genie Real Time Clock") + + +//------------------------------------------------- +// device_add_mconfig - add device configuration +//------------------------------------------------- + +void bbc_stlrtc_device::device_add_mconfig(machine_config &config) +{ + MC146818(config, m_rtc, 32.768_kHz_XTAL); // TODO: verify clock +} + +void bbc_pmsrtc_device::device_add_mconfig(machine_config &config) +{ + /* Dallas DS1216 SmartWatch RAM */ + DS1315(config, m_rtc, 0); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_stlrtc_device - constructor +//------------------------------------------------- + +bbc_stlrtc_device::bbc_stlrtc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_STLRTC, tag, owner, clock) + , device_bbc_rom_interface(mconfig, *this) + , m_rtc(*this, "rtc") +{ +} + +bbc_pmsrtc_device::bbc_pmsrtc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, BBC_PMSRTC, tag, owner, clock) + , device_bbc_rom_interface(mconfig, *this) + , m_rtc(*this, "rtc") +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_stlrtc_device::device_start() +{ +} + +void bbc_pmsrtc_device::device_start() +{ +} + +//------------------------------------------------- +// read +//------------------------------------------------- + +READ8_MEMBER(bbc_stlrtc_device::read) +{ + uint8_t data = get_rom_base()[offset & 0x3fff]; + + switch (offset & 0x3fc0) + { + case 0x3e00: + data = m_rtc->read(space, 1); + break; + case 0x3e40: + m_rtc->write(space, 0, data); + break; + case 0x3e80: + case 0x3ec0: + data = m_rtc->read(space, 0); + break; + case 0x3f00: + case 0x3f40: + case 0x3f80: + case 0x3fc0: + m_rtc->write(space, 1, data); + break; + } + return data; +} + +READ8_MEMBER(bbc_pmsrtc_device::read) +{ + uint8_t data = get_rom_base()[offset & 0x1fff]; + + switch (offset) + { + case 0x00: + data |= m_rtc->read_0(space, 0); + break; + case 0x01: + data |= m_rtc->read_1(space, 0); + break; + case 0x04: + if (m_rtc->chip_enable()) + data = m_rtc->read_data(space, 0) & 0x01; + break; + } + return data; +} diff --git a/src/devices/bus/bbc/rom/rtc.h b/src/devices/bus/bbc/rom/rtc.h new file mode 100644 index 00000000000..5ad99e2b500 --- /dev/null +++ b/src/devices/bus/bbc/rom/rtc.h @@ -0,0 +1,72 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/*************************************************************************** + + Solidisk Real Time Clock emulation + + PMS Genie Watch (RTC for the BBC) + +***************************************************************************/ + +#ifndef MAME_BUS_BBC_ROM_RTC_H +#define MAME_BUS_BBC_ROM_RTC_H + +#pragma once + +#include "slot.h" +#include "machine/mc146818.h" +#include "machine/ds1315.h" + +//************************************************************************** +// TYPE DEFINITIONS +//************************************************************************** + +// ======================> bbc_stlrtc_device + +class bbc_stlrtc_device : public device_t, + public device_bbc_rom_interface +{ +public: + // construction/destruction + bbc_stlrtc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual void device_start() override; + + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; + +private: + required_device m_rtc; +}; + +// ======================> bbc_pmsrtc_device + +class bbc_pmsrtc_device : public device_t, + public device_bbc_rom_interface +{ +public: + // construction/destruction + bbc_pmsrtc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + +protected: + // device-level overrides + virtual void device_add_mconfig(machine_config &config) override; + + virtual void device_start() override; + + // device_bbc_rom_interface overrides + virtual DECLARE_READ8_MEMBER(read) override; + +private: + required_device m_rtc; +}; + +// device type definition +DECLARE_DEVICE_TYPE(BBC_STLRTC, bbc_stlrtc_device) +DECLARE_DEVICE_TYPE(BBC_PMSRTC, bbc_pmsrtc_device) + +#endif // MAME_BUS_BBC_ROM_RTC_H diff --git a/src/devices/bus/bbc/rom/slot.cpp b/src/devices/bus/bbc/rom/slot.cpp new file mode 100644 index 00000000000..210ba2db1cd --- /dev/null +++ b/src/devices/bus/bbc/rom/slot.cpp @@ -0,0 +1,234 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************* + + BBC Micro ROM slot emulation + +*********************************************************************/ + +#include "emu.h" +#include "slot.h" + + +//************************************************************************** +// GLOBAL VARIABLES +//************************************************************************** + +DEFINE_DEVICE_TYPE(BBC_ROMSLOT16, bbc_romslot16_device, "bbc_romslot16", "BBC Micro 16K ROM Slot") +DEFINE_DEVICE_TYPE(BBC_ROMSLOT32, bbc_romslot32_device, "bbc_romslot32", "BBC Micro 32K ROM Slot") + + +//************************************************************************** +// DEVICE BBC_ROMSLOT CARD INTERFACE +//************************************************************************** + +//------------------------------------------------- +// device_bbc_rom_interface - constructor +//------------------------------------------------- + +device_bbc_rom_interface::device_bbc_rom_interface(const machine_config &mconfig, device_t &device) + : device_slot_card_interface(mconfig, device) + , m_rom(nullptr) + , m_rom_size(0) +{ +} + + +//------------------------------------------------- +// ~device_bbc_rom_interface - destructor +//------------------------------------------------- + +device_bbc_rom_interface::~device_bbc_rom_interface() +{ +} + +//------------------------------------------------- +// rom_alloc - alloc the space for the ROM +//------------------------------------------------- + +void device_bbc_rom_interface::rom_alloc(uint32_t size, const char *tag) +{ + if (m_rom == nullptr) + { + m_rom = device().machine().memory().region_alloc(std::string(tag).append(BBC_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base(); + m_rom_size = size; + } +} + +//------------------------------------------------- +// ram_alloc - alloc the space for the RAM +//------------------------------------------------- + +void device_bbc_rom_interface::ram_alloc(uint32_t size) +{ + m_ram.resize(size); + device().save_item(NAME(m_ram)); +} + +//------------------------------------------------- +// nvram_alloc - alloc the space for the NVRAM +//------------------------------------------------- + +void device_bbc_rom_interface::nvram_alloc(uint32_t size) +{ + m_nvram.resize(size); +} + +//************************************************************************** +// LIVE DEVICE +//************************************************************************** + +//------------------------------------------------- +// bbc_romslot_device - constructor +//------------------------------------------------- +bbc_romslot_device::bbc_romslot_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_image_interface(mconfig, *this) + , device_slot_interface(mconfig, *this) + , m_cart(nullptr) +{ +} + +bbc_romslot16_device::bbc_romslot16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_romslot_device(mconfig, BBC_ROMSLOT16, tag, owner, clock) +{ +} + +bbc_romslot32_device::bbc_romslot32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : bbc_romslot_device(mconfig, BBC_ROMSLOT32, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void bbc_romslot_device::device_start() +{ + m_cart = dynamic_cast(get_card_device()); +} + + +//------------------------------------------------- +// call load +//------------------------------------------------- + +image_init_result bbc_romslot_device::call_load() +{ + if (m_cart) + { + uint32_t size = !loaded_through_softlist() ? length() : get_software_region_length("rom"); + + if (size % 0x2000) + { + seterror(IMAGE_ERROR_INVALIDIMAGE, "Invalid ROM size"); + return image_init_result::FAIL; + } + + m_cart->rom_alloc(size, tag()); + + if (!loaded_through_softlist()) + fread(m_cart->get_rom_base(), size); + else + memcpy(m_cart->get_rom_base(), get_software_region("rom"), size); + + if (get_software_region("ram")) + m_cart->ram_alloc(get_software_region_length("ram")); + + if (get_software_region("nvram")) + m_cart->nvram_alloc(get_software_region_length("nvram")); + } + + return image_init_result::PASS; +} + +//------------------------------------------------- +// call_unload +//------------------------------------------------- + +void bbc_romslot_device::call_unload() +{ + if (m_cart && m_cart->get_nvram_base() && m_cart->get_nvram_size()) + battery_save(m_cart->get_nvram_base(), m_cart->get_nvram_size()); +} + + +//------------------------------------------------- +// get default card software +//------------------------------------------------- + +std::string bbc_romslot_device::get_default_card_software(get_default_card_software_hook &hook) const +{ + return software_get_default_slot("rom"); +} + + +//------------------------------------------------- +// rom size +//------------------------------------------------- + +uint32_t bbc_romslot_device::get_rom_size() +{ + if (m_cart) + return m_cart->get_rom_size(); + else + return 0; +} + + +//------------------------------------------------- +// read - rom read +//------------------------------------------------- + +READ8_MEMBER(bbc_romslot_device::read) +{ + if (m_cart) + return m_cart->read(space, offset); + else + return 0xff; +} + + +//------------------------------------------------- +// write - rom write +//------------------------------------------------- + +WRITE8_MEMBER(bbc_romslot_device::write) +{ + if (m_cart) + m_cart->write(space, offset, data); +} + + +//------------------------------------------------- +// SLOT_INTERFACE( bbc_rom ) +//------------------------------------------------- + +#include "rom.h" +#include "ram.h" +#include "dfs.h" +//#include "genie.h" +#include "pal.h" +//#include "replay.h" +#include "rtc.h" + + +void bbc_rom_devices(device_slot_interface &device) +{ + device.option_add_internal("rom", BBC_ROM); + device.option_add_internal("ram", BBC_RAM); + device.option_add_internal("cciword", BBC_CCIWORD); + device.option_add_internal("ccibase", BBC_CCIBASE); + device.option_add_internal("ccispell", BBC_CCISPELL); + device.option_add_internal("palqst", BBC_PALQST); + device.option_add_internal("palwap", BBC_PALWAP); + device.option_add_internal("palted", BBC_PALTED); + device.option_add_internal("palabep", BBC_PALABEP); + device.option_add_internal("palabe", BBC_PALABE); + device.option_add_internal("palmo2", BBC_PALMO2); + //device.option_add_internal("genie", BBC_PMSGENIE); + device.option_add_internal("mrme00", BBC_MRME00); + //device.option_add_internal("replay", BBC_REPLAY); + device.option_add_internal("stlrtc", BBC_STLRTC); + device.option_add_internal("pmsrtc", BBC_PMSRTC); +} diff --git a/src/devices/bus/bbc/rom/slot.h b/src/devices/bus/bbc/rom/slot.h new file mode 100644 index 00000000000..2b6b634f6a8 --- /dev/null +++ b/src/devices/bus/bbc/rom/slot.h @@ -0,0 +1,155 @@ +// license:BSD-3-Clause +// copyright-holders:Nigel Barnes +/********************************************************************* + + BBC Micro ROM slot emulation + +*********************************************************************/ + +#ifndef MAME_BUS_BBC_ROM_SLOT_H +#define MAME_BUS_BBC_ROM_SLOT_H + +#pragma once + +#include "softlist_dev.h" + + +#define BBC_ROM_REGION_TAG ":cart:rom" + +/*************************************************************************** + TYPE DEFINITIONS +***************************************************************************/ + +// ======================> bbc_romslot_device + +class device_bbc_rom_interface; + +class bbc_romslot_device : public device_t, + public device_image_interface, + public device_slot_interface +{ +public: + // image-level overrides + virtual image_init_result call_load() override; + virtual void call_unload() override; + virtual const software_list_loader &get_software_list_loader() const override { return rom_software_list_loader::instance(); } + + virtual iodevice_t image_type() const override { return IO_ROM; } + virtual bool is_readable() const override { return 1; } + virtual bool is_writeable() const override { return 0; } + virtual bool is_creatable() const override { return 0; } + virtual bool must_be_loaded() const override { return 0; } + virtual bool is_reset_on_load() const override { return 1; } + virtual const char *image_interface() const override { return "bbc_rom"; } + virtual const char *file_extensions() const override { return "rom,bin"; } + + // slot interface overrides + virtual std::string get_default_card_software(get_default_card_software_hook &hook) const override; + + // reading and writing + virtual DECLARE_READ8_MEMBER(read); + virtual DECLARE_WRITE8_MEMBER(write); + + uint32_t get_rom_size(); + uint32_t get_slot_size() const { return m_slot_size; } + +protected: + // construction/destruction + bbc_romslot_device(const machine_config &mconfig, device_type type, char const *tag, device_t *owner, uint32_t clock); + + // device-level overrides + virtual void device_start() override; + + uint32_t m_slot_size; + +private: + device_bbc_rom_interface* m_cart; +}; + +// ======================> bbc_romslot16_device + +class bbc_romslot16_device : public bbc_romslot_device +{ +public: + // construction/destruction + template + bbc_romslot16_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, char const *default_option) + : bbc_romslot16_device(mconfig, tag, owner) + { + option_reset(); + slot_options(*this); + set_default_option(default_option); + set_fixed(false); + m_slot_size = 0x4000; + } + + bbc_romslot16_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); +}; + +// ======================> bbc_romslot32_device + +class bbc_romslot32_device : public bbc_romslot_device +{ +public: + // construction/destruction + template + bbc_romslot32_device(machine_config const &mconfig, char const *tag, device_t *owner, T &&slot_options, char const *default_option) + : bbc_romslot32_device(mconfig, tag, owner) + { + option_reset(); + slot_options(*this); + set_default_option(default_option); + set_fixed(false); + m_slot_size = 0x8000; + } + + bbc_romslot32_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); +}; + + +// ======================> device_bbc_rom_interface + +class device_bbc_rom_interface : public device_slot_card_interface +{ +public: + // construction/destruction + virtual ~device_bbc_rom_interface(); + + // reading and writing + virtual DECLARE_READ8_MEMBER(read) { return 0xff; } + virtual DECLARE_WRITE8_MEMBER(write) { m_device.logerror("unhandled ROM write to %04X = %02X\n", offset | 0x8000, data); } + + void rom_alloc(uint32_t size, const char *tag); + void ram_alloc(uint32_t size); + void nvram_alloc(uint32_t size); + + uint8_t* get_rom_base() { return m_rom; } + virtual uint32_t get_rom_size() { return m_rom_size; } + + uint8_t* get_ram_base() { return &m_ram[0]; } + uint32_t get_ram_size() { return m_ram.size(); } + + uint8_t* get_nvram_base() { return &m_nvram[0]; } + uint32_t get_nvram_size() { return m_nvram.size(); } + +protected: + device_bbc_rom_interface(const machine_config &mconfig, device_t &device); + + bbc_romslot_device *m_slot; + +private: + // internal state + uint8_t *m_rom; + uint32_t m_rom_size; + std::vector m_ram; + std::vector m_nvram; +}; + + +// device type definition +DECLARE_DEVICE_TYPE(BBC_ROMSLOT16, bbc_romslot16_device) +DECLARE_DEVICE_TYPE(BBC_ROMSLOT32, bbc_romslot32_device) + +void bbc_rom_devices(device_slot_interface &device); + +#endif // MAME_BUS_BBC_ROM_SLOT_H diff --git a/src/mame/drivers/bbc.cpp b/src/mame/drivers/bbc.cpp index 3452810516c..c2ade862351 100644 --- a/src/mame/drivers/bbc.cpp +++ b/src/mame/drivers/bbc.cpp @@ -907,14 +907,10 @@ void bbc_state::bbca(machine_config &config) m_via6522_0->irq_handler().set(m_irqs, FUNC(input_merger_device::in_w<1>)); /* eprom sockets */ - GENERIC_SOCKET(config, m_rom[12], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic101 */ - m_rom[12]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_romc, this)); - GENERIC_SOCKET(config, m_rom[13], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic100 */ - m_rom[13]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_romd, this)); - GENERIC_SOCKET(config, m_rom[14], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic88 */ - m_rom[14]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rome, this)); - GENERIC_SOCKET(config, m_rom[15], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic52 */ - m_rom[15]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_romf, this)); + BBC_ROMSLOT16(config, m_rom[0x0c], bbc_rom_devices, nullptr); /* ic101 */ + BBC_ROMSLOT16(config, m_rom[0x0d], bbc_rom_devices, nullptr); /* ic100 */ + BBC_ROMSLOT16(config, m_rom[0x0e], bbc_rom_devices, nullptr); /* ic88 */ + BBC_ROMSLOT16(config, m_rom[0x0f], bbc_rom_devices, nullptr); /* ic52 */ /* software lists */ SOFTWARE_LIST(config, "cass_ls_a").set_original("bbca_cass"); @@ -1133,16 +1129,11 @@ void bbcbp_state::bbcbp(machine_config &config) FLOPPY_CONNECTOR(config, "wd1770:1", bbc_floppies, "525qd", bbc_state::floppy_formats).enable_sound(true); /* eprom sockets */ - GENERIC_SOCKET(config, m_rom[2], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic35 */ - m_rom[2]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom23, this)); - GENERIC_SOCKET(config, m_rom[4], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic44 */ - m_rom[4]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom45, this)); - GENERIC_SOCKET(config, m_rom[6], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic57 */ - m_rom[6]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom67, this)); - GENERIC_SOCKET(config, m_rom[8], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic62 */ - m_rom[8]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom89, this)); - GENERIC_SOCKET(config, m_rom[10], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic68 */ - m_rom[10]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_romab, this)); + BBC_ROMSLOT32(config, m_rom[0x02], bbc_rom_devices, nullptr); /* ic35 */ + BBC_ROMSLOT32(config, m_rom[0x04], bbc_rom_devices, nullptr); /* ic44 */ + BBC_ROMSLOT32(config, m_rom[0x06], bbc_rom_devices, nullptr); /* ic57 */ + BBC_ROMSLOT32(config, m_rom[0x08], bbc_rom_devices, nullptr); /* ic62 */ + BBC_ROMSLOT32(config, m_rom[0x0a], bbc_rom_devices, nullptr); /* ic68 */ config.device_remove("romslot12"); config.device_remove("romslot13"); config.device_remove("romslot14"); @@ -1479,12 +1470,9 @@ void bbcm_state::bbcm(machine_config &config) m_cart[1]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_cart2, this)); /* eprom sockets */ - GENERIC_SOCKET(config, m_rom[8], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic27 */ - m_rom[8]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom8, this)); - GENERIC_SOCKET(config, m_rom[4], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic41 */ - m_rom[4]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom45, this)); - GENERIC_SOCKET(config, m_rom[6], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic37 */ - m_rom[6]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom67, this)); + BBC_ROMSLOT16(config, m_rom[0x08], bbc_rom_devices, nullptr); /* ic27 */ + BBC_ROMSLOT32(config, m_rom[0x04], bbc_rom_devices, nullptr); /* ic41 */ + BBC_ROMSLOT32(config, m_rom[0x06], bbc_rom_devices, nullptr); /* ic37 */ /* software lists */ SOFTWARE_LIST(config, "cass_ls_m").set_original("bbcm_cass"); @@ -1686,14 +1674,13 @@ void bbcm_state::bbcmc(machine_config &config) config.device_remove("cartslot2"); /* eprom sockets */ - GENERIC_SOCKET(config, m_rom[2], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic23 */ - m_rom[2]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom2, this)); - GENERIC_SOCKET(config, m_rom[3], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic17 */ - m_rom[3]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom3, this)); - GENERIC_SOCKET(config, m_rom[0], generic_linear_slot, "bbc_rom", "bin,rom"); /* ic38 */ - m_rom[0]->set_device_load(device_image_load_delegate(&bbc_state::device_image_load_rom01, this)); config.device_remove("romslot4"); config.device_remove("romslot6"); + config.device_remove("romslot8"); + BBC_ROMSLOT16(config, m_rom[0x03], bbc_rom_devices, nullptr); /* ic17 */ + BBC_ROMSLOT16(config, m_rom[0x02], bbc_rom_devices, nullptr); /* ic23 */ + BBC_ROMSLOT32(config, m_rom[0x00], bbc_rom_devices, nullptr); /* ic38 */ + BBC_ROMSLOT16(config, m_rom[0x08], bbc_rom_devices, nullptr); /* ic29 */ /* software lists */ SOFTWARE_LIST(config, "flop_ls_mc").set_original("bbcmc_flop"); diff --git a/src/mame/includes/bbc.h b/src/mame/includes/bbc.h index a912a651cde..143e6559d1c 100644 --- a/src/mame/includes/bbc.h +++ b/src/mame/includes/bbc.h @@ -38,6 +38,7 @@ #include "bus/rs232/rs232.h" #include "bus/centronics/ctronics.h" #include "bus/econet/econet.h" +#include "bus/bbc/rom/slot.h" #include "bus/bbc/fdc/fdc.h" #include "bus/bbc/analogue/analogue.h" #include "bus/bbc/1mhzbus/1mhzbus.h" @@ -186,34 +187,6 @@ public: void insert_device_rom(memory_region *rom); void setup_device_roms(); - image_init_result load_rom16(device_image_interface &image, generic_slot_device *slot); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom0) { return load_rom16(image, m_rom[0]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom1) { return load_rom16(image, m_rom[1]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom2) { return load_rom16(image, m_rom[2]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom3) { return load_rom16(image, m_rom[3]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom4) { return load_rom16(image, m_rom[4]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom5) { return load_rom16(image, m_rom[5]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom6) { return load_rom16(image, m_rom[6]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom7) { return load_rom16(image, m_rom[7]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom8) { return load_rom16(image, m_rom[8]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom9) { return load_rom16(image, m_rom[9]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(roma) { return load_rom16(image, m_rom[10]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romb) { return load_rom16(image, m_rom[11]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romc) { return load_rom16(image, m_rom[12]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romd) { return load_rom16(image, m_rom[13]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rome) { return load_rom16(image, m_rom[14]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romf) { return load_rom16(image, m_rom[15]); } - - image_init_result load_rom32(device_image_interface &image, generic_slot_device *slot); - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom01) { return load_rom32(image, m_rom[0]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom23) { return load_rom32(image, m_rom[2]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom45) { return load_rom32(image, m_rom[4]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom67) { return load_rom32(image, m_rom[6]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(rom89) { return load_rom32(image, m_rom[8]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romab) { return load_rom32(image, m_rom[10]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romcd) { return load_rom32(image, m_rom[12]); } - DECLARE_DEVICE_IMAGE_LOAD_MEMBER(romef) { return load_rom32(image, m_rom[14]); } - image_init_result load_cart(device_image_interface &image, generic_slot_device *slot); DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart1) { return load_cart(image, m_cart[0]); } DECLARE_DEVICE_IMAGE_LOAD_MEMBER(cart2) { return load_cart(image, m_cart[1]); } @@ -279,7 +252,7 @@ protected: optional_device m_i8271; optional_device m_wd1770; optional_device m_wd1772; - optional_device_array m_rom; + optional_device_array m_rom; optional_device_array m_cart; required_memory_region m_region_mos; diff --git a/src/mame/machine/bbc.cpp b/src/mame/machine/bbc.cpp index 2a861da480c..4613ae9d981 100644 --- a/src/mame/machine/bbc.cpp +++ b/src/mame/machine/bbc.cpp @@ -50,9 +50,9 @@ READ8_MEMBER(bbc_state::bbc_paged_r) uint8_t data; std::string region_tag; - if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(GENERIC_ROM_REGION_TAG).c_str())) + if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) { - data = m_rom[m_swrbank]->read_rom(space, offset); + data = m_rom[m_swrbank]->read(space, offset); } else { @@ -71,8 +71,13 @@ WRITE8_MEMBER(bbc_state::bbc_paged_w) { 0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0 }, // 2: 64K (banks 4 to 7) for Acorn sideways ram FE30 bank latch { 0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1 }, // 3: 128K (banks 8 to 15) for Acorn sideways ram FE30 bank latch }; + std::string region_tag; - if (swramtype[m_swramtype][m_swrbank]) + if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) + { + m_rom[m_swrbank]->write(space, offset, data); + } + else if (swramtype[m_swramtype][m_swrbank]) { m_region_swr->base()[offset + (m_swrbank << 14)] = data; } @@ -149,9 +154,9 @@ READ8_MEMBER(bbc_state::bbcbp_paged_r) } else { - if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(GENERIC_ROM_REGION_TAG).c_str())) + if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) { - data = m_rom[m_swrbank]->read_rom(space, offset); + data = m_rom[m_swrbank]->read(space, offset); } else { @@ -166,14 +171,22 @@ WRITE8_MEMBER(bbc_state::bbcbp_paged_w) { /* the BBC Model B+ 128K has extra RAM mapped in replacing the ROM banks 0,1,c and d. */ static const unsigned short swram_banks[16] = { 1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0 }; + std::string region_tag; if (m_paged_ram && offset < 0x3000) { m_ram->pointer()[offset + 0x8000] = data; } - else if (m_ram->size() == 128 * 1024 && swram_banks[m_swrbank]) + else { - m_region_swr->base()[offset + (m_swrbank << 14)] = data; + if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) + { + m_rom[m_swrbank]->write(space, offset, data); + } + else if (m_ram->size() == 128 * 1024 && swram_banks[m_swrbank]) + { + m_region_swr->base()[offset + (m_swrbank << 14)] = data; + } } } @@ -282,9 +295,9 @@ READ8_MEMBER(bbc_state::bbcm_paged_r) } else { - if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(GENERIC_ROM_REGION_TAG).c_str())) + if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) { - data = m_rom[m_swrbank]->read_rom(space, offset); + data = m_rom[m_swrbank]->read(space, offset); } else { @@ -297,13 +310,22 @@ READ8_MEMBER(bbc_state::bbcm_paged_r) WRITE8_MEMBER(bbc_state::bbcm_paged_w) { + std::string region_tag; + if (m_paged_ram && offset < 0x1000) { m_ram->pointer()[offset + 0x8000] = data; } - else if ((!m_lk19_ic37_paged_rom && (m_swrbank == 4 || m_swrbank == 5)) || (!m_lk18_ic41_paged_rom && (m_swrbank == 6 || m_swrbank == 7))) + else { - m_region_swr->base()[offset + (m_swrbank << 14)] = data; + if (m_rom[m_swrbank] && memregion(region_tag.assign(m_rom[m_swrbank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) + { + m_rom[m_swrbank]->write(space, offset, data); + } + else if ((!m_lk19_ic37_paged_rom && (m_swrbank == 4 || m_swrbank == 5)) || (!m_lk18_ic41_paged_rom && (m_swrbank == 6 || m_swrbank == 7))) + { + m_region_swr->base()[offset + (m_swrbank << 14)] = data; + } } } @@ -1153,65 +1175,6 @@ WRITE8_MEMBER(bbc_state::bbcmc_drive_control_w) if (!BIT(data, 2)) m_wd1772->soft_reset(); } -/************************************** - BBC romslot loading functions -***************************************/ - -image_init_result bbc_state::load_rom16(device_image_interface &image, generic_slot_device *slot) -{ - uint32_t size = slot->common_get_size("rom"); - - // socket accepts 8K and 16K ROM only - if (size > 0x4000) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "ROM socket accepts 16K/8K only"); - return image_init_result::FAIL; - } - - slot->rom_alloc(0x4000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - slot->common_load_rom(slot->get_rom_base(), size, "rom"); - - uint8_t *crt = slot->get_rom_base(); - if (size <= 0x2000) - { - /* mirror 8K ROMs */ - memcpy(crt + 0x2000, crt, 0x2000); - } - - return image_init_result::PASS; -} - -image_init_result bbc_state::load_rom32(device_image_interface &image, generic_slot_device *slot) -{ - uint32_t size = slot->common_get_size("rom"); - - // socket accepts 32K,16K and 8K ROM only - if (size > 0x8000) - { - image.seterror(IMAGE_ERROR_UNSPECIFIED, "ROM socket accepts 32K/16K/8K only"); - return image_init_result::FAIL; - } - - slot->rom_alloc(0x8000, GENERIC_ROM8_WIDTH, ENDIANNESS_LITTLE); - slot->common_load_rom(slot->get_rom_base(), size, "rom"); - - uint8_t *crt = slot->get_rom_base(); - if (size <= 0x2000) - { - /* mirror 8K ROMs */ - memcpy(crt + 0x2000, crt, 0x2000); - memcpy(crt + 0x4000, crt, 0x2000); - memcpy(crt + 0x6000, crt, 0x2000); - } - else if (size <= 0x4000) - { - /* mirror 16K ROMs */ - memcpy(crt + 0x4000, crt, 0x4000); - } - - return image_init_result::PASS; -} - /************************************** BBC cartslot loading functions ***************************************/ @@ -1290,7 +1253,7 @@ void bbc_state::init_bbcm() init_bbc(); /* set links if ROM present, disabling RAM */ - if (m_rom[4] && memregion(region_tag.assign(m_rom[4]->tag()).append(GENERIC_ROM_REGION_TAG).c_str())) + if (m_rom[4] && memregion(region_tag.assign(m_rom[4]->tag()).append(BBC_ROM_REGION_TAG).c_str())) { /* link for ROM in slots 4 and 5 */ m_lk19_ic37_paged_rom = true; @@ -1299,7 +1262,7 @@ void bbc_state::init_bbcm() { m_lk18_ic41_paged_rom = false; } - if (m_rom[6] && memregion(region_tag.assign(m_rom[6]->tag()).append(GENERIC_ROM_REGION_TAG).c_str())) + if (m_rom[6] && memregion(region_tag.assign(m_rom[6]->tag()).append(BBC_ROM_REGION_TAG).c_str())) { /* link for ROM in slots 6 and 7 */ m_lk18_ic41_paged_rom = true; @@ -1362,7 +1325,7 @@ void bbc_state::insert_device_rom(memory_region *rom) for (int bank = 15; bank >= 0; bank--) { /* if bank has socket and is empty */ - if (m_rom[bank] && !memregion(region_tag.assign(m_rom[bank]->tag()).append(GENERIC_ROM_REGION_TAG).c_str())) + if (m_rom[bank] && !memregion(region_tag.assign(m_rom[bank]->tag()).append(BBC_ROM_REGION_TAG).c_str())) { uint8_t *swr = m_region_swr->base() + (bank * 0x4000); switch (rom->bytes()) @@ -1371,7 +1334,7 @@ void bbc_state::insert_device_rom(memory_region *rom) /* 32K (or 2x16K) ROM, check whether ROM exists in this and next bank */ if (swr[0x0006] == 0xff && swr[0x4006] == 0xff) { - memcpy(m_region_swr->base() + (bank * 0x4000), rom->base(), 0x8000); + memcpy(m_region_swr->base() + (bank * 0x4000), rom->base(), rom->bytes()); osd_printf_verbose("Inserting '%s' into romslot%d\n", get_rom_name(rom->base() + 0x4000).c_str(), bank + 1); osd_printf_verbose("Inserting '%s' into romslot%d\n", get_rom_name(rom->base()).c_str(), bank); return; @@ -1382,7 +1345,7 @@ void bbc_state::insert_device_rom(memory_region *rom) /* 16/8K ROM, check whether ROM exists in this bank */ if (swr[0x0006] == 0xff) { - memcpy(m_region_swr->base() + (bank * 0x4000), rom->base(), 0x4000); + memcpy(m_region_swr->base() + (bank * 0x4000), rom->base(), rom->bytes()); osd_printf_verbose("Inserting '%s' into romslot%d\n", get_rom_name(rom->base()).c_str(), bank); return; } @@ -1414,18 +1377,12 @@ void bbc_state::setup_device_roms() /* configure romslots */ for (int i = 0; i < 16; i++) { - if (m_rom[i] && (rom_region = memregion(region_tag.assign(m_rom[i]->tag()).append(GENERIC_ROM_REGION_TAG).c_str()))) + if (m_rom[i] && (rom_region = memregion(region_tag.assign(m_rom[i]->tag()).append(BBC_ROM_REGION_TAG).c_str()))) { - switch (rom_region->bytes()) - { - case 0x4000: /* 16K socket */ - memcpy(m_region_swr->base() + (i * 0x4000), rom_region->base(), rom_region->bytes()); - break; - case 0x8000: /* 32K socket */ - memcpy(m_region_swr->base() + (i * 0x4000), rom_region->base(), rom_region->bytes()); - i++; - break; - } + if (m_rom[i]->get_rom_size()) + memcpy(m_region_swr->base() + (i * 0x4000), rom_region->base(), std::min((int32_t)m_rom[i]->get_slot_size(), (int32_t)m_rom[i]->get_rom_size())); + else + memset(m_region_swr->base() + (i * 0x4000), 0, 0x4000); } }