summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/rc2014/rom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/rc2014/rom.cpp')
-rw-r--r--src/devices/bus/rc2014/rom.cpp262
1 files changed, 262 insertions, 0 deletions
diff --git a/src/devices/bus/rc2014/rom.cpp b/src/devices/bus/rc2014/rom.cpp
new file mode 100644
index 00000000000..61d0d8bb191
--- /dev/null
+++ b/src/devices/bus/rc2014/rom.cpp
@@ -0,0 +1,262 @@
+// license:BSD-3-Clause
+// copyright-holders:Miodrag Milanovic
+/***************************************************************************
+
+ RC2014 ROM Module
+
+****************************************************************************/
+
+#include "emu.h"
+#include "rom.h"
+
+namespace {
+
+//**************************************************************************
+// RC2014 Switchable ROM module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class switchable_rom_device : public device_t, public device_rc2014_card_interface
+{
+public:
+ // construction/destruction
+ switchable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+private:
+ required_memory_region m_rom;
+ required_ioport m_rom_selector;
+};
+
+switchable_rom_device::switchable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_SWITCHABLE_ROM, tag, owner, clock)
+ , device_rc2014_card_interface(mconfig, *this)
+ , m_rom(*this, "rom")
+ , m_rom_selector(*this, "A13-A15")
+{
+}
+
+void switchable_rom_device::device_start()
+{
+}
+
+void switchable_rom_device::device_reset()
+{
+ m_bus->installer(AS_PROGRAM)->install_rom(0x0000, 0x1fff, 0x0000, m_rom->base() + (m_rom_selector->read() & 7) * 0x2000);
+}
+
+static INPUT_PORTS_START( switchable_rom_jumpers )
+ PORT_START("A13-A15") /* jumpers to select ROM region */
+ PORT_CONFNAME( 0x7, 0x7, "ROM Bank" )
+ PORT_CONFSETTING( 0x0, "Bank 0" )
+ PORT_CONFSETTING( 0x1, "Bank 1" )
+ PORT_CONFSETTING( 0x2, "Bank 2" )
+ PORT_CONFSETTING( 0x3, "Bank 3" )
+ PORT_CONFSETTING( 0x4, "Bank 4" )
+ PORT_CONFSETTING( 0x5, "Bank 5" )
+ PORT_CONFSETTING( 0x6, "Bank 6" )
+ PORT_CONFSETTING( 0x7, "Bank 7" )
+INPUT_PORTS_END
+
+ioport_constructor switchable_rom_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( switchable_rom_jumpers );
+}
+
+ROM_START(rc2014_switchable_rom)
+ ROM_REGION( 0x10000, "rom",0 )
+ //
+ // Decoding ROM labels
+ //
+ // 0 - Empty bank, available for user to program
+ // R - Microsoft BASIC, for 32k RAM, 68B50 ACIA, with origin 0x0000
+ // K - Microsoft BASIC, for 56k RAM, 68B50 ACIA, with origin 0x0000
+ // 1 - CP/M Monitor, for pageable ROM, 64k RAM, 68B50 ACIA, CF Module at 0x10, with origin at 0x0000
+ // 2 - Microsoft BASIC, for 32k RAM, SIO/2, with origin 0x0000
+ // 4 - Microsoft BASIC, for 56k RAM, SIO/2, with origin 0x0000
+ // 6 - CP/M Monitor, for pageable ROM, 64k RAM, SIO/2, CF Module at 0x10, with origin at 0x0000
+ // 88 - Small Computer Monitor for pageable ROM, 64k RAM, SIO/2 or 68B50 ACIA, with Microsoft BASIC a
+ // and CP/M boot options [Note that this is a 16k image, so Page Size needs to be set to 16k and
+ // only A14 and A15 jumpers to select]
+ // 9 - Small Computer Monitor for any ROM, any RAM, any UART
+ //
+ ROM_DEFAULT_BIOS("r0000009")
+ ROM_SYSTEM_BIOS(0, "r0000009", "BASIC 32K ACIA + SCM")
+ ROMX_LOAD( "r0000009.bin", 0x0000, 0x10000, CRC(3fb1ced7) SHA1(40a030b931ebe6cca654ce056c228297f245b057), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "00001000", "CP/M Monitor ACIA")
+ ROMX_LOAD( "00001000.bin", 0x0000, 0x10000, CRC(e6509de9) SHA1(e5f3b528e972f63cd243bd5057e7e7850436b671), ROM_BIOS(1))
+ ROM_SYSTEM_BIOS(2, "k0001000", "BASIC 56K + CP/M Monitor ACIA")
+ ROMX_LOAD( "k0001000.bin", 0x0000, 0x10000, CRC(619a9c3e) SHA1(c1213316746a6e2a7d2030b283f75c4f3a9c177a), ROM_BIOS(2))
+ ROM_SYSTEM_BIOS(3, "r0001000", "BASIC 32K + CP/M Monitor ACIA")
+ ROMX_LOAD( "r0001000.bin", 0x0000, 0x10000, CRC(5b174833) SHA1(97c204ada65129ef61507faf74e29c8ec7a05064), ROM_BIOS(3))
+ ROM_SYSTEM_BIOS(4, "r0001009", "BASIC 32K + CP/M Monitor ACIA + SCM")
+ ROMX_LOAD( "r0001009.bin", 0x0000, 0x10000, CRC(074a2d70) SHA1(0077ab5e669da6e95ed2f66c9e759067c4236e36), ROM_BIOS(4))
+ROM_END
+
+const tiny_rom_entry *switchable_rom_device::device_rom_region() const
+{
+ return ROM_NAME( rc2014_switchable_rom );
+}
+
+//**************************************************************************
+// RC2014 Pageable ROM module
+// Module author: Spencer Owen
+//**************************************************************************
+
+class pagable_rom_device : public device_t, public device_rc2014_ext_card_interface
+{
+public:
+ // construction/destruction
+ pagable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_post_load() override { update_banks(); }
+ virtual ioport_constructor device_input_ports() const override;
+ virtual const tiny_rom_entry *device_rom_region() const override;
+
+ void reset_bank_w(offs_t, uint8_t) { m_bank = 0; update_banks(); m_bus->page_w(CLEAR_LINE);}
+ void toggle_bank_w(offs_t, uint8_t) { m_bank = m_bank ? 0 : 1; update_banks(); m_bus->page_w(m_bank ? ASSERT_LINE : CLEAR_LINE); }
+
+ void update_banks();
+private:
+ int m_bank;
+ u16 m_start_offset;
+ u16 m_end_addr;
+ required_memory_region m_rom;
+ required_ioport m_page_size_conf;
+ required_ioport_array<6> m_page_addr_conf;
+};
+
+pagable_rom_device::pagable_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+ : device_t(mconfig, RC2014_PAGABLE_ROM, tag, owner, clock)
+ , device_rc2014_ext_card_interface(mconfig, *this)
+ , m_bank(0)
+ , m_rom(*this, "rom")
+ , m_page_size_conf(*this, "PAGE_SIZE")
+ , m_page_addr_conf(*this, "A1%u", 0U)
+{
+}
+
+void pagable_rom_device::device_start()
+{
+ save_item(NAME(m_bank));
+}
+
+void pagable_rom_device::device_reset()
+{
+ static constexpr u16 page_size[] = { 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 };
+ static constexpr u16 page_mask[] = { 0xfc00, 0xf800, 0xf000, 0xe000, 0xc000, 0x8000 };
+
+ int index = 0;
+ m_start_offset = 0x0000;
+ for (auto& addr : m_page_addr_conf)
+ {
+ if (addr->read() != 0)
+ m_start_offset += (addr->read() - 1) * page_size[index];
+ index++;
+ }
+ m_start_offset &= page_mask[m_page_size_conf->read()];
+ m_end_addr = page_size[m_page_size_conf->read()] - 1;
+ reset_bank_w(0,0);
+
+ // A15-A8, A7 and A2-A0 not connected, A6 must be 0
+ m_bus->installer(AS_IO)->install_write_handler(0x30, 0x30, 0, 0xff87, 0, write8sm_delegate(*this, FUNC(pagable_rom_device::reset_bank_w)));
+ m_bus->installer(AS_IO)->install_write_handler(0x38, 0x38, 0, 0xff87, 0, write8sm_delegate(*this, FUNC(pagable_rom_device::toggle_bank_w)));
+}
+
+void pagable_rom_device::update_banks()
+{
+ if (m_bank == 0)
+ m_bus->installer(AS_PROGRAM)->install_rom(0x0000, m_end_addr, 0x0000, m_rom->base() + m_start_offset);
+}
+
+static INPUT_PORTS_START( pagable_rom_jumpers )
+ PORT_START("PAGE_SIZE")
+ PORT_CONFNAME( 0x7, 0x4, "Page Size" )
+ PORT_CONFSETTING( 0x0, "1K" )
+ PORT_CONFSETTING( 0x1, "2K" )
+ PORT_CONFSETTING( 0x2, "4K" )
+ PORT_CONFSETTING( 0x3, "8K" )
+ PORT_CONFSETTING( 0x4, "16K" )
+ PORT_CONFSETTING( 0x5, "32K" )
+ PORT_START("A10")
+ PORT_CONFNAME( 0x3, 0x0, "A10" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A11")
+ PORT_CONFNAME( 0x3, 0x0, "A11" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A12")
+ PORT_CONFNAME( 0x3, 0x0, "A12" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A13")
+ PORT_CONFNAME( 0x3, 0x0, "A13" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A14")
+ PORT_CONFNAME( 0x3, 0x2, "A14" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+ PORT_START("A15")
+ PORT_CONFNAME( 0x3, 0x1, "A15" )
+ PORT_CONFSETTING( 0x0, DEF_STR( None ) )
+ PORT_CONFSETTING( 0x1, "0" )
+ PORT_CONFSETTING( 0x2, "1" )
+INPUT_PORTS_END
+
+ioport_constructor pagable_rom_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME( pagable_rom_jumpers );
+}
+
+ROM_START(rc2014_pagable_rom)
+ //
+ // Decoding ROM labels
+ //
+ // 0 - Empty bank, available for user to program
+ // R - Microsoft BASIC, for 32k RAM, 68B50 ACIA, with origin 0x0000
+ // K - Microsoft BASIC, for 56k RAM, 68B50 ACIA, with origin 0x0000
+ // 1 - CP/M Monitor, for pageable ROM, 64k RAM, 68B50 ACIA, CF Module at 0x10, with origin at 0x0000
+ // 2 - Microsoft BASIC, for 32k RAM, SIO/2, with origin 0x0000
+ // 4 - Microsoft BASIC, for 56k RAM, SIO/2, with origin 0x0000
+ // 6 - CP/M Monitor, for pageable ROM, 64k RAM, SIO/2, CF Module at 0x10, with origin at 0x0000
+ // 88 - Small Computer Monitor for pageable ROM, 64k RAM, SIO/2 or 68B50 ACIA, with Microsoft BASIC a
+ // and CP/M boot options [Note that this is a 16k image, so Page Size needs to be set to 16k and
+ // only A14 and A15 jumpers to select]
+ // 9 - Small Computer Monitor for any ROM, any RAM, any UART
+ //
+ ROM_REGION( 0x10000, "rom",0 )
+ ROM_DEFAULT_BIOS("24886009")
+ ROM_SYSTEM_BIOS(0, "24886009", "BASIC 32K/56K SIO/2 + CP/M + SCM Pagable + SCM")
+ ROMX_LOAD( "24886009.bin", 0x00000, 0x10000, CRC(2731ca52) SHA1(e9ac663cb85de4e3e041bce444712c00f46b6eb2), ROM_BIOS(0))
+ ROM_SYSTEM_BIOS(1, "24006000", "BASIC 32K/56K SIO/2 + CP/M Monitor")
+ ROMX_LOAD( "24006000.bin", 0x00000, 0x10000, CRC(3532872b) SHA1(ff5b3873abdcbe8ab48f62a9dbdf39314b938e89), ROM_BIOS(1))
+ROM_END
+
+const tiny_rom_entry *pagable_rom_device::device_rom_region() const
+{
+ return ROM_NAME( rc2014_pagable_rom );
+}
+
+}
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_SWITCHABLE_ROM, device_rc2014_card_interface, switchable_rom_device, "rc2014_switchable_rom", "RC2014 Switchable ROM module")
+DEFINE_DEVICE_TYPE_PRIVATE(RC2014_PAGABLE_ROM, device_rc2014_ext_card_interface, pagable_rom_device, "rc2014_pagable_rom", "RC2014 Pageable ROM module")