summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/vcs/rom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/vcs/rom.cpp')
-rw-r--r--src/devices/bus/vcs/rom.cpp1171
1 files changed, 482 insertions, 689 deletions
diff --git a/src/devices/bus/vcs/rom.cpp b/src/devices/bus/vcs/rom.cpp
index 9650bc29661..f40591e1173 100644
--- a/src/devices/bus/vcs/rom.cpp
+++ b/src/devices/bus/vcs/rom.cpp
@@ -21,8 +21,7 @@
// a26_rom_*k_device - constructor
//-------------------------------------------------
-DEFINE_DEVICE_TYPE(A26_ROM_2K, a26_rom_2k_device, "vcs_2k", "Atari VCS 2600 2K ROM Carts")
-DEFINE_DEVICE_TYPE(A26_ROM_4K, a26_rom_4k_device, "vcs_4k", "Atari VCS 2600 4K ROM Carts")
+DEFINE_DEVICE_TYPE(A26_ROM_2K_4K, a26_rom_2k_4k_device, "vcs_2k_4k", "Atari VCS 2600 2K/4K ROM Carts")
DEFINE_DEVICE_TYPE(A26_ROM_F4, a26_rom_f4_device, "vcs_f4", "Atari VCS 2600 ROM Carts w/F4 bankswitch")
DEFINE_DEVICE_TYPE(A26_ROM_F6, a26_rom_f6_device, "vcs_f6", "Atari VCS 2600 ROM Carts w/F6 bankswitch")
DEFINE_DEVICE_TYPE(A26_ROM_F8, a26_rom_f8_device, "vcs_f8", "Atari VCS 2600 ROM Carts w/F8 bankswitch")
@@ -44,301 +43,95 @@ DEFINE_DEVICE_TYPE(A26_ROM_32IN1, a26_rom_32in1_device, "vcs_32in1", "Atari VCS
DEFINE_DEVICE_TYPE(A26_ROM_X07, a26_rom_x07_device, "vcs_x07", "Atari VCS 2600 ROM Carts w/X07 bankswitch")
-a26_rom_2k_device::a26_rom_2k_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_vcs_cart_interface(mconfig, *this)
-{
-}
-
-a26_rom_2k_device::a26_rom_2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_2k_device(mconfig, A26_ROM_2K, tag, owner, clock)
-{
-}
-
-a26_rom_4k_device::a26_rom_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_2k_device(mconfig, A26_ROM_4K, tag, owner, clock)
-{
-}
-
-
-a26_rom_f6_device::a26_rom_f6_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_2k_device(mconfig, type, tag, owner, clock)
- , m_base_bank(-1) // set to -1 to help the Xin1 multicart...
-{
-}
-
-a26_rom_f6_device::a26_rom_f6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_F6, tag, owner, clock)
+bool a26_rom_base_device::is_ram_present(size_t minimum_size)
{
+ return m_ram.size() >= minimum_size;
}
-
-a26_rom_f4_device::a26_rom_f4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_F4, tag, owner, clock)
+uint8_t a26_rom_base_device::read_ram(offs_t offset)
{
+ return m_ram[offset];
}
-
-a26_rom_f8_device::a26_rom_f8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, type, tag, owner, clock)
+void a26_rom_base_device::write_ram(offs_t offset, uint8_t data)
{
+ m_ram[offset] = data;
}
-a26_rom_f8_device::a26_rom_f8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f8_device(mconfig, A26_ROM_F8, tag, owner, clock)
-{
-}
-a26_rom_f8_sw_device::a26_rom_f8_sw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f8_device(mconfig, A26_ROM_F8_SW, tag, owner, clock)
-{
-}
-
-a26_rom_fa_device::a26_rom_fa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_FA, tag, owner, clock)
-{
-}
-
-
-a26_rom_fe_device::a26_rom_fe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_2k_device(mconfig, A26_ROM_FE, tag, owner, clock), m_base_bank(0), m_trigger_on_next_access(0)
-{
-}
-
-
-a26_rom_3e_device::a26_rom_3e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_3E, tag, owner, clock), m_num_bank(0), m_ram_bank(0), m_ram_enable(0)
-{
-}
-
-
-a26_rom_3f_device::a26_rom_3f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_3F, tag, owner, clock), m_num_bank(0)
-{
-}
-
-
-a26_rom_e0_device::a26_rom_e0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_E0, tag, owner, clock)
-{
-}
-
-
-a26_rom_e7_device::a26_rom_e7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_E7, tag, owner, clock), m_ram_bank(0)
-{
-}
-
-
-a26_rom_ua_device::a26_rom_ua_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_UA, tag, owner, clock)
-{
-}
-
-
-a26_rom_cv_device::a26_rom_cv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_2k_device(mconfig, A26_ROM_CV, tag, owner, clock)
-{
-}
-
-
-a26_rom_dc_device::a26_rom_dc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_DC, tag, owner, clock)
-{
-}
-
-
-a26_rom_fv_device::a26_rom_fv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_FV, tag, owner, clock), m_locked(0)
-{
-}
-
-
-a26_rom_jvp_device::a26_rom_jvp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_JVP, tag, owner, clock)
-{
-}
+/*-------------------------------------------------
+ BASE 2K & 4K Carts:
+ no bankswitch
+ GAMES: a large majority
+ -------------------------------------------------*/
-a26_rom_4in1_device::a26_rom_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_4IN1, tag, owner, clock)
+a26_rom_2k_4k_device::a26_rom_2k_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_2K_4K, tag, owner, clock)
{
}
-
-a26_rom_8in1_device::a26_rom_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f8_device(mconfig, A26_ROM_8IN1, tag, owner, clock), m_reset_bank(0)
+void a26_rom_2k_4k_device::install_memory_handlers(address_space *space)
{
+ if (m_rom_size < 0x1000)
+ space->install_rom(0x1000, 0x17ff, 0x800, get_rom_base());
+ else
+ space->install_rom(0x1000, 0x1fff, get_rom_base());
}
-a26_rom_32in1_device::a26_rom_32in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_32IN1, tag, owner, clock)
-{
-}
-a26_rom_x07_device::a26_rom_x07_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : a26_rom_f6_device(mconfig, A26_ROM_X07, tag, owner, clock)
-{
-}
+/*-------------------------------------------------
+ "F6 Bankswitch" Carts:
+ read/write access to 0x1ff6-0x1ff9 determines the
+ 4K ROM bank to be read
+ GAMES: Atari 16K games, like Crossbow, Crystal
+ Castles and the 2-in-1 carts
-void a26_rom_2k_device::device_start()
-{
-}
+ -------------------------------------------------*/
-void a26_rom_2k_device::device_reset()
+a26_rom_f6_device::a26_rom_f6_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, type, tag, owner, clock)
+ , m_bank(*this, "bank")
{
}
-void a26_rom_f6_device::device_start()
+a26_rom_f6_device::a26_rom_f6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_f6_device(mconfig, A26_ROM_F6, tag, owner, clock)
{
- save_item(NAME(m_base_bank));
}
void a26_rom_f6_device::device_reset()
{
- m_base_bank = 0;
-}
-
-void a26_rom_f4_device::device_reset()
-{
- m_base_bank = 7;
-}
-
-void a26_rom_f8_sw_device::device_reset()
-{
- // Snow White proto starts from bank 1!!!
- m_base_bank = 1;
-}
-
-void a26_rom_fe_device::device_start()
-{
- save_item(NAME(m_base_bank));
- save_item(NAME(m_trigger_on_next_access));
-}
-
-void a26_rom_fe_device::device_reset()
-{
- m_base_bank = 0;
- m_trigger_on_next_access = 0;
-}
-
-void a26_rom_3e_device::device_start()
-{
- save_item(NAME(m_base_bank));
- save_item(NAME(m_ram_bank));
- save_item(NAME(m_ram_enable));
-}
-
-void a26_rom_3e_device::device_reset()
-{
- m_num_bank = m_rom_size / 0x800;
- m_base_bank = m_num_bank - 1;
- m_ram_bank = 0;
- m_ram_enable = 0;
-}
-
-void a26_rom_3f_device::device_reset()
-{
- m_num_bank = m_rom_size / 0x800;
- m_base_bank = m_num_bank - 1;
+ m_bank->set_entry(get_start_bank());
}
-void a26_rom_e0_device::device_start()
+void a26_rom_f6_device::install_super_chip_handlers(address_space *space)
{
- save_item(NAME(m_base_banks));
-}
-
-void a26_rom_e0_device::device_reset()
-{
- m_base_banks[0] = 4;
- m_base_banks[1] = 5;
- m_base_banks[2] = 6;
- m_base_banks[3] = 7;
-}
-
-void a26_rom_e7_device::device_start()
-{
- save_item(NAME(m_base_bank));
- save_item(NAME(m_ram_bank));
-}
-
-void a26_rom_e7_device::device_reset()
-{
- m_base_bank = 0;
- m_ram_bank = 0;
-}
-
-void a26_rom_ua_device::device_reset()
-{
- m_base_bank = 0;
-}
-
-void a26_rom_fv_device::device_start()
-{
- save_item(NAME(m_base_bank));
- save_item(NAME(m_locked));
-}
-
-void a26_rom_fv_device::device_reset()
-{
- m_base_bank = 0;
- m_locked = 0;
-}
-
-
-void a26_rom_4in1_device::device_reset()
-{
- m_base_bank++;
- m_base_bank &= 3;
-}
-
-
-void a26_rom_8in1_device::device_start()
-{
- save_item(NAME(m_base_bank));
- save_item(NAME(m_reset_bank));
+ if (is_ram_present(0x80)) {
+ space->install_read_handler(0x1080, 0x10ff, read8sm_delegate(*this, FUNC(a26_rom_f6_device::read_ram)));
+ space->install_write_handler(0x1000, 0x107f, write8sm_delegate(*this, FUNC(a26_rom_f6_device::write_ram)));
+ }
}
-void a26_rom_8in1_device::device_reset()
+void a26_rom_f6_device::install_memory_handlers(address_space *space)
{
- // we use here two different bank counter: the main one for the 8x8K chunks,
- // and the usual one (m_base_bank) for the 4K bank of the current game
- m_reset_bank++;
- m_reset_bank &= 7;
- m_base_bank = 0;
+ m_bank->configure_entries(0, 4, get_rom_base(), 0x1000);
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_write_handler(0x1ff6, 0x1ff9, write8sm_delegate(*this, FUNC(a26_rom_f6_device::switch_bank)));
+ install_super_chip_handlers(space);
+ space->install_read_tap(0x1ff6, 0x1ff9, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(address - 0x1ff6, 0); });
}
-
-void a26_rom_32in1_device::device_reset()
+void a26_rom_f6_device::switch_bank(offs_t offset, uint8_t data)
{
- m_base_bank++;
- m_base_bank &= 0x1f;
+ m_bank->set_entry(offset);
}
-/*-------------------------------------------------
- mapper specific handlers
- -------------------------------------------------*/
-
-/*-------------------------------------------------
- BASE 2K & 4K Carts:
- no bankswitch
-
- GAMES: a large majority
- -------------------------------------------------*/
-
-READ8_MEMBER(a26_rom_2k_device::read_rom)
-{
- // Super Chip RAM reads are mapped in 0x1080-0x10ff
- if (!m_ram.empty() && offset >= 0x80 && offset < 0x100)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- return m_rom[offset & (m_rom_size - 1)];
-}
/*-------------------------------------------------
"F4 Bankswitch" Carts:
@@ -348,119 +141,21 @@ READ8_MEMBER(a26_rom_2k_device::read_rom)
GAMES: Fatal Run
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_f4_device::read_rom)
-{
- // Super Chip RAM reads are mapped in 0x1080-0x10ff
- if (!m_ram.empty() && offset >= 0x80 && offset < 0x100)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- // update banks
- if (!machine().side_effects_disabled())
- {
- switch (offset)
- {
- case 0x0ff4:
- case 0x0ff5:
- case 0x0ff6:
- case 0x0ff7:
- case 0x0ff8:
- case 0x0ff9:
- case 0x0ffa:
- case 0x0ffb:
- m_base_bank = offset - 0x0ff4;
- break;
- }
- }
-
- return m_rom[offset + (m_base_bank * 0x1000)];
-}
-
-WRITE8_MEMBER(a26_rom_f4_device::write_bank)
+a26_rom_f4_device::a26_rom_f4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_f6_device(mconfig, A26_ROM_F4, tag, owner, clock)
{
- // Super Chip RAM writes are mapped in 0x1000-0x107f
- if (!m_ram.empty() && offset < 0x80)
- {
- m_ram[offset & (m_ram.size() - 1)] = data;
- return;
- }
-
- switch (offset)
- {
- case 0x0ff4:
- case 0x0ff5:
- case 0x0ff6:
- case 0x0ff7:
- case 0x0ff8:
- case 0x0ff9:
- case 0x0ffa:
- case 0x0ffb:
- m_base_bank = offset - 0x0ff4;
- break;
- default:
- logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000);
- break;
- }
}
-/*-------------------------------------------------
- "F6 Bankswitch" Carts:
- read/write access to 0x1ff6-0x1ff9 determines the
- 4K ROM bank to be read
-
- GAMES: Atari 16K games, like Crossbow, Crystal
- Castles and the 2-in-1 carts
-
- -------------------------------------------------*/
-
-READ8_MEMBER(a26_rom_f6_device::read_rom)
+void a26_rom_f4_device::install_memory_handlers(address_space *space)
{
- // Super Chip RAM reads are mapped in 0x1080-0x10ff
- if (!m_ram.empty() && offset >= 0x80 && offset < 0x100)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- // update banks
- if (!machine().side_effects_disabled())
- {
- switch (offset)
- {
- case 0x0ff6:
- case 0x0ff7:
- case 0x0ff8:
- case 0x0ff9:
- m_base_bank = offset - 0x0ff6;
- break;
- }
- }
-
- return m_rom[offset + (m_base_bank * 0x1000)];
+ m_bank->configure_entries(0, 8, get_rom_base(), 0x1000);
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_write_handler(0x1ff4, 0x1ffb, write8sm_delegate(*this, FUNC(a26_rom_f4_device::switch_bank)));
+ install_super_chip_handlers(space);
+ space->install_read_tap(0x1ff4, 0x1ffb, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(address - 0x1ff4, 0); });
}
-WRITE8_MEMBER(a26_rom_f6_device::write_bank)
-{
- // Super Chip RAM writes are mapped in 0x1000-0x107f
- if (!m_ram.empty() && offset < 0x80)
- {
- m_ram[offset & (m_ram.size() - 1)] = data;
- return;
- }
-
- switch (offset)
- {
- case 0x0ff6:
- case 0x0ff7:
- case 0x0ff8:
- case 0x0ff9:
- m_base_bank = offset - 0x0ff6;
- break;
- default:
- logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000);
- break;
- }
-}
/*-------------------------------------------------
"F8 Bankswitch" Carts:
@@ -472,50 +167,33 @@ WRITE8_MEMBER(a26_rom_f6_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_f8_device::read_rom)
+a26_rom_f8_device::a26_rom_f8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_f6_device(mconfig, type, tag, owner, clock)
{
- // Super Chip RAM reads are mapped in 0x1080-0x10ff
- if (!m_ram.empty() && offset >= 0x80 && offset < 0x100)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- // update banks
- if (!machine().side_effects_disabled())
- {
- switch (offset)
- {
- case 0x0ff8:
- case 0x0ff9:
- m_base_bank = offset - 0x0ff8;
- break;
- }
- }
+}
- return m_rom[offset + (m_base_bank * 0x1000)];
+a26_rom_f8_device::a26_rom_f8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_f8_device(mconfig, A26_ROM_F8, tag, owner, clock)
+{
}
-WRITE8_MEMBER(a26_rom_f8_device::write_bank)
+void a26_rom_f8_device::install_memory_handlers(address_space *space)
{
- // Super Chip RAM writes are mapped in 0x1000-0x107f
- if (!m_ram.empty() && offset < 0x80)
- {
- m_ram[offset & (m_ram.size() - 1)] = data;
- return;
- }
+ m_bank->configure_entries(0, 2, get_rom_base(), 0x1000);
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_write_handler(0x1ff8, 0x1ff9, write8sm_delegate(*this, FUNC(a26_rom_f8_device::switch_bank)));
+ install_super_chip_handlers(space);
+ space->install_read_tap(0x1ff8, 0x1ff9, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(address - 0x1ff8, 0); });
+}
- switch (offset)
- {
- case 0x0ff8:
- case 0x0ff9:
- m_base_bank = offset - 0x0ff8;
- break;
- default:
- logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000);
- break;
- }
+
+a26_rom_f8_sw_device::a26_rom_f8_sw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_f8_device(mconfig, A26_ROM_F8_SW, tag, owner, clock)
+{
}
+
/*-------------------------------------------------
"FA Bankswitch" Carts:
read/write access to 0x1ff8-0x1ffa determines the
@@ -528,51 +206,24 @@ WRITE8_MEMBER(a26_rom_f8_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_fa_device::read_rom)
+a26_rom_fa_device::a26_rom_fa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_f6_device(mconfig, A26_ROM_FA, tag, owner, clock)
{
- // CBS RAM+ reads are mapped in 0x1100-0x11ff
- if (!m_ram.empty() && offset >= 0x100 && offset < 0x200)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- // update banks
- if (!machine().side_effects_disabled())
- {
- switch (offset)
- {
- case 0x0ff8:
- case 0x0ff9:
- case 0x0ffa:
- m_base_bank = offset - 0x0ff8;
- break;
- }
- }
-
- return m_rom[offset + (m_base_bank * 0x1000)];
}
-WRITE8_MEMBER(a26_rom_fa_device::write_bank)
+void a26_rom_fa_device::install_memory_handlers(address_space *space)
{
- // CBS RAM+ writes are mapped in 0x1000-0x10ff
- if (!m_ram.empty() && offset < 0x100)
- {
- m_ram[offset & (m_ram.size() - 1)] = data;
- }
-
- switch (offset)
- {
- case 0x0ff8:
- case 0x0ff9:
- case 0x0ffa:
- m_base_bank = offset - 0x0ff8;
- break;
- default:
- logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000);
- break;
- }
+ m_bank->configure_entries(0, 3, get_rom_base(), 0x1000);
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_write_handler(0x1ff8, 0x1ffa, write8sm_delegate(*this, FUNC(a26_rom_fa_device::switch_bank)));
+ space->install_read_tap(0x1ff8, 0x1ffa, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(address - 0x1ff8, 0); });
+ space->install_read_handler(0x1100, 0x11ff, read8sm_delegate(*this, FUNC(a26_rom_fa_device::read_ram)));
+ space->install_write_handler(0x1000, 0x10ff, write8sm_delegate(*this, FUNC(a26_rom_fa_device::write_ram)));
}
+
+
/*-------------------------------------------------
"FE Bankswitch" Carts:
read/write access to 0x01fe-0x1ff determines the
@@ -581,6 +232,43 @@ WRITE8_MEMBER(a26_rom_fa_device::write_bank)
GAMES: Activision 8K games like Decathlon
-------------------------------------------------*/
+
+a26_rom_fe_device::a26_rom_fe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_FE, tag, owner, clock)
+ , m_bank(*this, "bank")
+ , m_trigger_on_next_access(false)
+ , m_ignore_first_read(true)
+{
+}
+
+void a26_rom_fe_device::device_start()
+{
+ save_item(NAME(m_trigger_on_next_access));
+ save_item(NAME(m_ignore_first_read));
+}
+
+void a26_rom_fe_device::device_reset()
+{
+ m_bank->set_entry(0);
+ m_trigger_on_next_access = false;
+ // During cpu startup, before reading the boot vector a read from $01fe occurs
+ m_ignore_first_read = true;
+}
+
+void a26_rom_fe_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 8, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_readwrite_tap(0x1fe, 0x1fe, "trigger_bank",
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) trigger_bank(); },
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) trigger_bank(); });
+ space->install_read_tap(0x1ff, 0x1ff, "switch_bank1",
+ [this] (offs_t, u8 &data, u8) { if (!machine().side_effects_disabled()) switch_bank(data); });
+ space->install_read_tap(0x1000, 0x1fff, "switch_bank2",
+ [this] (offs_t, u8 &data, u8) { if (!machine().side_effects_disabled()) switch_bank(data); });
+}
+
/*
There seems to be a kind of lag between the writing to address 0x1FE and the
@@ -593,73 +281,25 @@ WRITE8_MEMBER(a26_rom_fa_device::write_bank)
*/
-READ8_MEMBER(a26_rom_fe_device::read_rom)
+void a26_rom_fe_device::switch_bank(uint8_t data)
{
- uint8_t data;
-
- // Super Chip RAM reads are mapped in 0x1080-0x10ff
- if (!m_ram.empty() && offset >= 0x80 && offset < 0x100)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- data = m_rom[offset + (m_base_bank * 0x1000)];
-
- if (!machine().side_effects_disabled())
+ if (m_trigger_on_next_access)
{
- if (m_trigger_on_next_access)
- {
- m_base_bank = BIT(data, 5) ? 0 : 1;
- m_trigger_on_next_access = 0;
- }
+ m_bank->set_entry(BIT(data, 5) ? 0 : 1);
+ m_trigger_on_next_access = false;
}
-
- return data;
}
-WRITE8_MEMBER(a26_rom_fe_device::write_ram)
+void a26_rom_fe_device::trigger_bank()
{
- // Super Chip RAM writes are mapped in 0x1000-0x107f
- if (!m_ram.empty() && offset < 0x80)
- {
- m_ram[offset & (m_ram.size() - 1)] = data;
- }
+ if (m_ignore_first_read)
+ m_ignore_first_read = false;
+ else
+ // The next byte on the data bus determines which bank to switch to
+ m_trigger_on_next_access = true;
}
-READ8_MEMBER(a26_rom_fe_device::read_bank)
-{
- uint8_t data = space.read_byte(0xfe + offset);
- if (!machine().side_effects_disabled())
- {
- switch (offset & 1)
- {
- case 0:
- // The next byte on the data bus determines which bank to switch to
- m_trigger_on_next_access = 1;
- break;
-
- case 1:
- if (m_trigger_on_next_access)
- {
- m_base_bank = BIT(data, 5) ? 0 : 1;
- m_trigger_on_next_access = 0;
- }
- break;
- }
- }
- return data;
-}
-
-WRITE8_MEMBER(a26_rom_fe_device::write_bank)
-{
- space.write_byte(0xfe, data);
- if (!machine().side_effects_disabled())
- {
- // The next byte on the data bus determines which bank to switch to
- m_trigger_on_next_access = 1;
- }
-}
/*-------------------------------------------------
"3E Bankswitch" Carts:
@@ -671,38 +311,58 @@ WRITE8_MEMBER(a26_rom_fe_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_3e_device::read_rom)
+a26_rom_3e_device::a26_rom_3e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_3E, tag, owner, clock)
+ , m_rom_bank(*this, "rom_bank")
+ , m_ram_bank(*this, "ram_bank")
+ , m_view(*this, "view")
+ , m_rom_bank_mask(0)
+ , m_ram_bank_mask(0)
{
- if (!m_ram.empty() && m_ram_enable && offset < 0x400)
- return m_ram[offset + (m_ram_bank * 0x400)];
+}
- if (offset >= 0x800)
- return m_rom[(offset & 0x7ff) + (m_num_bank - 1) * 0x800];
- else
- return m_rom[offset + m_base_bank * 0x800];
+void a26_rom_3e_device::device_reset()
+{
+ m_rom_bank->set_entry(m_rom_bank_mask);
+ m_view.select(0);
}
-WRITE8_MEMBER(a26_rom_3e_device::write_bank)
+void a26_rom_3e_device::install_memory_handlers(address_space *space)
{
- if (offset == 0x3f)
- {
- m_base_bank = data & (m_num_bank - 1);
- m_ram_enable = 0;
- }
- else if (offset == 0x3e)
- {
- m_ram_bank = data & 0x1f;
- m_ram_enable = 1;
- }
+ m_rom_bank_mask = (get_rom_size() / 0x800) - 1;
+ m_ram_bank_mask = (get_ram_size() / 0x400) - 1;
+ m_rom_bank->configure_entries(0, m_rom_bank_mask + 1, get_rom_base(), 0x800);
+ m_ram_bank->configure_entries(0, m_ram_bank_mask + 1, get_ram_base(), 0x400);
+
+ space->install_view(0x1000, 0x17ff, m_view);
+ // RAM disabled
+ m_view[0].install_read_bank(0x1000, 0x17ff, m_rom_bank);
+ // RAM enabled
+ m_view[1].install_read_bank(0x1000, 0x17ff, m_rom_bank);
+ m_view[1].install_read_bank(0x1000, 0x13ff, m_ram_bank);
+ m_view[1].install_write_bank(0x1400, 0x17ff, m_ram_bank);
+
+ space->install_rom(0x1800, 0x1fff, get_rom_base() + m_rom_bank_mask * 0x800);
+ space->install_write_tap(0x3e, 0x3e, "ram_bank",
+ [this] (offs_t address, u8 &data, u8) { if (!machine().side_effects_disabled()) select_ram_bank(address, data); });
+ space->install_write_tap(0x3f, 0x3f, "rom_bank",
+ [this] (offs_t address, u8 &data, u8) { if (!machine().side_effects_disabled()) select_rom_bank(address, data); });
+}
+
+void a26_rom_3e_device::select_ram_bank(offs_t address, uint8_t data)
+{
+ m_ram_bank->set_entry(data & m_ram_bank_mask);
+ m_view.select(1);
}
-WRITE8_MEMBER(a26_rom_3e_device::write_ram)
+void a26_rom_3e_device::select_rom_bank(offs_t address, uint8_t data)
{
- if (!m_ram.empty() && m_ram_enable && offset >= 0x400 && offset < 0x800)
- m_ram[(offset & 0x3ff) + (m_ram_bank * 0x400)] = data;
+ m_rom_bank->set_entry(data & m_rom_bank_mask);
+ m_view.select(0);
}
+
/*-------------------------------------------------
"3F Bankswitch" Carts:
write access to 0x00-0x3f determines the 2K ROM bank
@@ -714,22 +374,40 @@ WRITE8_MEMBER(a26_rom_3e_device::write_ram)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_3f_device::read_rom)
+a26_rom_3f_device::a26_rom_3f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_3F, tag, owner, clock)
+ , m_bank(*this, "bank")
+ , m_bank_mask(0)
{
- if (offset >= 0x800)
- return m_rom[(offset & 0x7ff) + (m_num_bank - 1) * 0x800];
- else
- return m_rom[offset + m_base_bank * 0x800];
}
-WRITE8_MEMBER(a26_rom_3f_device::write_bank)
+void a26_rom_3f_device::device_reset()
+{
+ m_bank->set_entry(m_bank_mask);
+}
+
+void a26_rom_3f_device::install_memory_handlers(address_space *space)
+{
+ m_bank_mask = (get_rom_size() / 0x800) - 1;
+ m_bank->configure_entries(0, get_rom_size() / 0x800, get_rom_base(), 0x800);
+
+ space->install_read_bank(0x1000, 0x17ff, m_bank);
+ // last bank
+ space->install_rom(0x1800, 0x1fff, get_rom_base() + m_bank_mask * 0x800);
+ space->install_write_tap(0x00, 0x3f, "bank",
+ [this] (offs_t offset, u8 &data, u8) { if (!machine().side_effects_disabled()) select_bank(offset, data); });
+}
+
+void a26_rom_3f_device::select_bank(offs_t offset, uint8_t data)
{
- m_base_bank = data & (m_num_bank - 1);
+ m_bank->set_entry(data & m_bank_mask);
}
+
+
/*-------------------------------------------------
"E0 Bankswitch" Carts:
- read/write access to 0x1fe0-0x1ff8 determines the
+ read/write access to 0x1fe0-0x1ff7 determines the
1K ROM bank to be read in each 1K chunk (0x1c00-0x1fff
always points to the last 1K of the ROM)
@@ -737,25 +415,48 @@ WRITE8_MEMBER(a26_rom_3f_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_e0_device::read_rom)
+a26_rom_e0_device::a26_rom_e0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_E0, tag, owner, clock)
+ , m_bank(*this, "bank%u", 0U)
{
- // update banks
- if (!machine().side_effects_disabled())
- {
- if (offset >= 0xfe0 && offset <= 0xff8)
- m_base_banks[(offset >> 3) & 3] = offset & 7;
- }
+}
- return m_rom[(offset & 0x3ff) + (m_base_banks[(offset >> 10) & 3] * 0x400)];
+void a26_rom_e0_device::device_reset()
+{
+ m_bank[0]->set_entry(4);
+ m_bank[1]->set_entry(5);
+ m_bank[2]->set_entry(6);
}
-WRITE8_MEMBER(a26_rom_e0_device::write_bank)
+void a26_rom_e0_device::install_memory_handlers(address_space *space)
{
- if (offset >= 0xfe0 && offset <= 0xff8)
- m_base_banks[(offset >> 3) & 3] = offset & 7;
+ m_bank[0]->configure_entries(0, 8, get_rom_base(), 0x400);
+ m_bank[1]->configure_entries(0, 8, get_rom_base(), 0x400);
+ m_bank[2]->configure_entries(0, 8, get_rom_base(), 0x400);
+
+ space->install_read_bank(0x1000, 0x13ff, m_bank[0]);
+ space->install_read_bank(0x1400, 0x17ff, m_bank[1]);
+ space->install_read_bank(0x1800, 0x1bff, m_bank[2]);
+ space->install_rom(0x1c00, 0x1fff, get_rom_base() + 7 * 0x400);
+ space->install_write_handler(0x1fe0, 0x1fe7, write8sm_delegate(*this, FUNC(a26_rom_e0_device::switch_bank<0>)));
+ space->install_write_handler(0x1fe8, 0x1fef, write8sm_delegate(*this, FUNC(a26_rom_e0_device::switch_bank<1>)));
+ space->install_write_handler(0x1ff0, 0x1ff7, write8sm_delegate(*this, FUNC(a26_rom_e0_device::switch_bank<2>)));
+ space->install_read_tap(0x1fe0, 0x1fe7, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank<0>(address, 0); });
+ space->install_read_tap(0x1fe8, 0x1fef, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank<1>(address, 0); });
+ space->install_read_tap(0x1ff0, 0x1ff7, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank<2>(address, 0); });
+}
+
+template <uint8_t Bank>
+void a26_rom_e0_device::switch_bank(offs_t offset, uint8_t data)
+{
+ m_bank[Bank]->set_entry(offset & 7);
}
+
/*-------------------------------------------------
"E7 Bankswitch" Carts:
this PCB can handle up to 16K of ROM and 2K of RAM,
@@ -776,57 +477,59 @@ WRITE8_MEMBER(a26_rom_e0_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_e7_device::read_rom)
+a26_rom_e7_device::a26_rom_e7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_E7, tag, owner, clock)
+ , m_rom_bank(*this, "rom_bank")
+ , m_lo_ram_bank(*this, "low_ram")
+ , m_hi_ram_bank(*this, "high_ram")
+ , m_view(*this, "view")
{
- // update banks
- if (!machine().side_effects_disabled())
- {
- if (offset >= 0xfe0 && offset <= 0xfe7)
- m_base_bank = offset - 0xfe0;
- if (offset >= 0xfe8 && offset <= 0xfeb)
- m_ram_bank = offset - 0xfe8;
- }
+}
- if (!m_ram.empty())
- {
- // 1K of RAM
- if (m_base_bank == 0x07 && offset >= 0x400 && offset < 0x800)
- return m_ram[0x400 + (offset & 0x3ff)];
- // the other 1K of RAM
- if (offset >= 0x900 && offset < 0xa00)
- {
- offset -= 0x900;
- return m_ram[offset + (m_ram_bank * 0x100)];
- }
- }
+void a26_rom_e7_device::device_reset()
+{
+ m_rom_bank->set_entry(0);
+ m_hi_ram_bank->set_entry(0);
+}
- if (offset > 0x800)
- return m_rom[(offset & 0x7ff) + 0x3800];
- else
- return m_rom[(offset & 0x7ff) + (m_base_bank * 0x800)];
+void a26_rom_e7_device::install_memory_handlers(address_space *space)
+{
+ m_rom_bank->configure_entries(0, 8, get_rom_base(), 0x800);
+ m_lo_ram_bank->configure_entry(0, get_ram_base() + 0x400);
+ m_hi_ram_bank->configure_entries(0, 4, get_ram_base(), 0x100);
+
+ space->install_view(0x1000, 0x17ff, m_view);
+ // RAM disabled
+ m_view[0].install_read_bank(0x1000, 0x17ff, m_rom_bank);
+ // RAM enabled
+ m_view[1].install_read_bank(0x1000, 0x17ff, m_rom_bank);
+ m_view[1].install_write_bank(0x1000, 0x13ff, m_lo_ram_bank);
+ m_view[1].install_read_bank(0x1400, 0x17ff, m_lo_ram_bank);
+
+ space->install_rom(0x1800, 0x1fff, get_rom_base() + 7 * 0x800);
+ space->install_write_bank(0x1800, 0x18ff, m_hi_ram_bank);
+ space->install_read_bank(0x1900, 0x19ff, m_hi_ram_bank);
+ space->install_write_handler(0x1fe0, 0x1fe7, write8sm_delegate(*this, FUNC(a26_rom_e7_device::switch_rom_bank)));
+ space->install_read_tap(0x1fe0, 0x1fe7, "rom_bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_rom_bank(address - 0x1fe0, 0); });
+ space->install_write_handler(0x1fe8, 0x1feb, write8sm_delegate(*this, FUNC(a26_rom_e7_device::switch_ram_bank)));
+ space->install_read_tap(0x1fe8, 0x1feb, "ram_bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_ram_bank(address - 0x1fe8, 0); });
}
-WRITE8_MEMBER(a26_rom_e7_device::write_bank)
+void a26_rom_e7_device::switch_rom_bank(offs_t offset, uint8_t data)
{
- if (offset >= 0xfe0 && offset <= 0xfe7)
- m_base_bank = offset - 0xfe0;
- if (offset >= 0xfe8 && offset <= 0xfeb)
- m_ram_bank = offset - 0xfe8;
+ m_view.select(offset == 0x07 ? 1 : 0);
+ m_rom_bank->set_entry(offset);
+}
- if (!m_ram.empty())
- {
- // 1K of RAM
- if (m_base_bank == 0x07 && offset < 0x400)
- m_ram[0x400 + (offset & 0x3ff)] = data;
- // the other 1K of RAM
- if (offset >= 0x800 && offset < 0x900)
- {
- offset -= 0x800;
- m_ram[offset + (m_ram_bank * 0x100)] = data;
- }
- }
+void a26_rom_e7_device::switch_ram_bank(offs_t offset, uint8_t data)
+{
+ m_hi_ram_bank->set_entry(offset);
}
+
+
/*-------------------------------------------------
"UA Bankswitch" Carts:
read/write access to 0x200-0x27f determines the
@@ -838,25 +541,34 @@ WRITE8_MEMBER(a26_rom_e7_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_ua_device::read_rom)
+a26_rom_ua_device::a26_rom_ua_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_UA, tag, owner, clock)
+ , m_bank(*this, "bank")
{
- return m_rom[(offset + (m_base_bank * 0x1000)) & (m_rom_size - 1)];
}
-READ8_MEMBER(a26_rom_ua_device::read_bank)
+void a26_rom_ua_device::device_reset()
{
- if (!machine().side_effects_disabled())
- m_base_bank = offset >> 6;
+ m_bank->set_entry(0);
+}
- return 0;
+void a26_rom_ua_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 2, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_readwrite_tap(0x200, 0x27f, "bank",
+ [this] (offs_t offset, u8 &data, u8) { if (!machine().side_effects_disabled()) change_bank(offset); },
+ [this] (offs_t offset, u8 &data, u8) { if (!machine().side_effects_disabled()) change_bank(offset); });
}
-WRITE8_MEMBER(a26_rom_ua_device::write_bank)
+void a26_rom_ua_device::change_bank(offs_t offset)
{
- m_base_bank = offset >> 6;
+ m_bank->set_entry((offset >> 6) & 1);
}
+
/*-------------------------------------------------
Commavid Carts:
It allows for both ROM and RAM on the cartridge,
@@ -867,27 +579,20 @@ WRITE8_MEMBER(a26_rom_ua_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_cv_device::read_rom)
+a26_rom_cv_device::a26_rom_cv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_CV, tag, owner, clock)
{
- if (!m_ram.empty() && offset < 0x400)
- {
- return m_ram[offset & (m_ram.size() - 1)];
- }
-
- // games shall not read from 0x1400-0x17ff (RAM write)
- // but we fall back to ROM just in case...
- return m_rom[offset & 0x7ff];
}
-WRITE8_MEMBER(a26_rom_cv_device::write_bank)
+void a26_rom_cv_device::install_memory_handlers(address_space *space)
{
- if (!m_ram.empty() && offset >= 0x400 && offset < 0x800)
- {
- m_ram[offset & (m_ram.size() - 1)] = data;
- }
+ space->install_rom(0x1000, 0x17ff, 0x800, get_rom_base());
+ space->install_read_handler(0x1000, 0x13ff, read8sm_delegate(*this, FUNC(a26_rom_cv_device::read_ram)));
+ space->install_write_handler(0x1400, 0x17ff, write8sm_delegate(*this, FUNC(a26_rom_cv_device::write_ram)));
}
+
/*-------------------------------------------------
Dynacom Megaboy Carts (aka "F0 Banswitch"):
read/write access to 0x1ff0 determines the 4K ROM
@@ -898,96 +603,115 @@ WRITE8_MEMBER(a26_rom_cv_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_dc_device::read_rom)
+a26_rom_dc_device::a26_rom_dc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_DC, tag, owner, clock)
+ , m_bank(*this, "bank")
+{
+}
+
+void a26_rom_dc_device::device_reset()
{
- if (!machine().side_effects_disabled())
- {
- if (offset == 0xff0)
- m_base_bank = (m_base_bank + 1) & 0x0f;
- }
+ m_bank->set_entry(0);
+}
+
+void a26_rom_dc_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 16, get_rom_base(), 0x1000);
- if (offset == 0xfec)
- return m_base_bank;
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_read_handler(0x1fec, 0x1fec, read8sm_delegate(*this, FUNC(a26_rom_dc_device::read_current_bank)));
+ space->install_write_handler(0x1ff0, 0x1ff0, write8sm_delegate(*this, FUNC(a26_rom_dc_device::switch_bank)));
+ space->install_read_tap(0x1ff0, 0x1ff0, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(0, 0); });
+}
- return m_rom[offset + (m_base_bank * 0x1000)];
+uint8_t a26_rom_dc_device::read_current_bank(offs_t offset)
+{
+ return m_bank->entry();
}
-WRITE8_MEMBER(a26_rom_dc_device::write_bank)
+void a26_rom_dc_device::switch_bank(offs_t offset, uint8_t data)
{
- if (offset == 0xff0)
- m_base_bank = (m_base_bank + 1) & 0x0f;
+ m_bank->set_entry((m_bank->entry() + 1) & 0x0f);
}
+
/*-------------------------------------------------
"FV Bankswitch" Carts:
- The first access to 0x1fd0 switch the bank, but
- only if pc() & 0x1f00 == 0x1f00!
+ The first access to 0x1fd0 switch the bank.
GAMES: Challenge by HES
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_fv_device::read_rom)
+a26_rom_fv_device::a26_rom_fv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_FV, tag, owner, clock)
+ , m_bank(*this, "bank")
{
- if (!machine().side_effects_disabled())
- {
- if (offset == 0xfd0)
- {
- if (!m_locked && (machine().device<cpu_device>("maincpu")->pc() & 0x1f00) == 0x1f00)
- {
- m_locked = 1;
- m_base_bank = m_base_bank ^ 0x01;
- }
- }
- }
+}
- return m_rom[offset + (m_base_bank * 0x1000)];
+void a26_rom_fv_device::device_reset()
+{
+ m_bank->set_entry(0);
}
-WRITE8_MEMBER(a26_rom_fv_device::write_bank)
+void a26_rom_fv_device::install_memory_handlers(address_space *space)
{
- if (offset == 0xfd0)
- {
- if (!m_locked && (machine().device<cpu_device>("maincpu")->pc() & 0x1f00) == 0x1f00)
- {
- m_locked = 1;
- m_base_bank = m_base_bank ^ 0x01;
- }
- }
+ m_bank->configure_entries(0, 2, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_write_handler(0x1fd0, 0x1fd0, write8sm_delegate(*this, FUNC(a26_rom_fv_device::switch_bank)));
+ space->install_read_tap(0x1fd0, 0x1fd0, "bank",
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(0, 0); });
}
+void a26_rom_fv_device::switch_bank(offs_t offset, uint8_t data)
+{
+ m_bank->set_entry(1);
+}
+
+
/*-------------------------------------------------
"JVP Bankswitch" Carts:
read/write access to 0x0fa0-0x0fc0 determines the
- 4K ROM bank to be read (notice that this overlaps
- the RIOT, currently handled in the main driver until
- I can better investigate the behavior)
+ 4K ROM bank to be read.
GAMES: No test case!?!
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_jvp_device::read_rom)
+a26_rom_jvp_device::a26_rom_jvp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_JVP, tag, owner, clock)
+ , m_bank(*this, "bank")
{
- return m_rom[offset + (m_base_bank * 0x1000)];
}
-WRITE8_MEMBER(a26_rom_jvp_device::write_bank)
+void a26_rom_jvp_device::device_reset()
{
- switch (offset)
- {
- case 0x00:
- case 0x20:
- m_base_bank ^= 1;
- break;
- default:
- //printf("%04X: write to unknown mapper address %02X\n", m_maincpu->pc(), 0xfa0 + offset);
- break;
- }
+ m_bank->set_entry(0);
+}
+
+void a26_rom_jvp_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 2, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_readwrite_tap(0xfa0, 0xfa0, "bank_fa0",
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank(); },
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank(); });
+ space->install_readwrite_tap(0xfc0, 0xfc0, "bank_fc0",
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank(); },
+ [this] (offs_t, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank(); });
}
+void a26_rom_jvp_device::change_bank()
+{
+ m_bank->set_entry(m_bank->entry() ^ 1);
+}
+
+
/*-------------------------------------------------
4 in 1 Carts (Reset based):
@@ -997,11 +721,33 @@ WRITE8_MEMBER(a26_rom_jvp_device::write_bank)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_4in1_device::read_rom)
+a26_rom_4in1_device::a26_rom_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_4IN1, tag, owner, clock)
+ , m_bank(*this, "bank")
+ , m_current_game(0)
+{
+}
+
+void a26_rom_4in1_device::device_start()
+{
+ save_item(NAME(m_current_game));
+ m_current_game = 0;
+}
+
+void a26_rom_4in1_device::device_reset()
{
- return m_rom[offset + (m_base_bank * 0x1000)];
+ m_bank->set_entry(m_current_game);
+ m_current_game = (m_current_game + 1) & 3;
}
+void a26_rom_4in1_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 4, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+}
+
+
/*-------------------------------------------------
8 in 1 Carts (Reset based):
@@ -1012,23 +758,43 @@ READ8_MEMBER(a26_rom_4in1_device::read_rom)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_8in1_device::read_rom)
+a26_rom_8in1_device::a26_rom_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_8IN1, tag, owner, clock)
+ , m_bank(*this, "bank")
{
- if (!machine().side_effects_disabled())
- {
- switch (offset)
- {
- case 0x0ff8:
- case 0x0ff9:
- m_base_bank = offset - 0x0ff8;
- break;
- }
- }
+}
+
+void a26_rom_8in1_device::device_start()
+{
+ save_item(NAME(m_game_bank));
+
+ // starting from last game so first reset will get us to game #0
+ m_game_bank = 14;
+}
+
+void a26_rom_8in1_device::device_reset()
+{
+ m_game_bank = (m_game_bank + 2) & 15;
+ m_bank->set_entry(m_game_bank);
+}
+
+void a26_rom_8in1_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 16, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
+ space->install_write_handler(0x1ff8, 0x1ff9, write8sm_delegate(*this, FUNC(a26_rom_8in1_device::switch_bank)));
+ space->install_read_tap(0x1ff8, 0x1ff9, "bank",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) switch_bank(address - 0x1ff8, 0); });
+}
- return m_rom[offset + (m_base_bank * 0x1000) + (m_reset_bank * 0x2000)];
+void a26_rom_8in1_device::switch_bank(offs_t offset, uint8_t data)
+{
+ m_bank->set_entry(m_game_bank + offset);
}
+
/*-------------------------------------------------
32 in 1 Carts (Reset based):
the 2K banks change at each reset
@@ -1037,11 +803,33 @@ READ8_MEMBER(a26_rom_8in1_device::read_rom)
-------------------------------------------------*/
-READ8_MEMBER(a26_rom_32in1_device::read_rom)
+a26_rom_32in1_device::a26_rom_32in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_32IN1, tag, owner, clock)
+ , m_bank(*this, "bank")
+ , m_current_game(0)
+{
+}
+
+void a26_rom_32in1_device::device_start()
{
- return m_rom[(offset & 0x7ff) + (m_base_bank * 0x800)];
+ save_item(NAME(m_current_game));
+ m_current_game = 0;
}
+void a26_rom_32in1_device::device_reset()
+{
+ m_bank->set_entry(m_current_game);
+ m_current_game = (m_current_game + 1) & 0x1f;
+}
+
+void a26_rom_32in1_device::install_memory_handlers(address_space *space)
+{
+ m_bank->configure_entries(0, 32, get_rom_base(), 0x800);
+
+ space->install_read_bank(0x1000, 0x17ff, 0x800, m_bank);
+}
+
+
/*-------------------------------------------------
"X07 Bankswitch" Carts:
@@ -1050,43 +838,48 @@ READ8_MEMBER(a26_rom_32in1_device::read_rom)
http://blog.kevtris.org/blogfiles/Atari%202600%20Mappers.txt
--------------------------------------------------*/
-READ8_MEMBER(a26_rom_x07_device::read_rom)
+a26_rom_x07_device::a26_rom_x07_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : a26_rom_base_device(mconfig, A26_ROM_X07, tag, owner, clock)
+ , m_bank(*this, "bank")
{
- return m_rom[offset + (m_base_bank * 0x1000)];
}
-WRITE8_MEMBER(a26_rom_x07_device::write_bank)
+void a26_rom_x07_device::install_memory_handlers(address_space *space)
{
+ m_bank->configure_entries(0, 16, get_rom_base(), 0x1000);
+
+ space->install_read_bank(0x1000, 0x1fff, m_bank);
/*
A13 A0
----------------
- 0 1xxx nnnn 1101
+ 0 0xxx 0nxx xxxx
*/
-
- if ((offset & 0x180f) == 0x080d)
- {
- m_base_bank = (offset & 0x00f0) >> 4;
- }
+ space->install_readwrite_tap(0x0000, 0x0000, 0x077f, "bank1",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank1(address); },
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank1(address); });
/*
A13 A0
----------------
- 0 0xxx 0nxx xxxx
+ 0 1xxx nnnn 1101
*/
+ space->install_readwrite_tap(0x080d, 0x080d, 0x07f0, "bank2",
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank2(address); },
+ [this] (offs_t address, u8 &, u8) { if (!machine().side_effects_disabled()) change_bank2(address); });
+}
- if ((offset & 0x1880) == 0x0000)
+void a26_rom_x07_device::change_bank1(offs_t address)
+{
+ // only has an effect if bank is already 14 or 15
+ if (m_bank->entry() >= 14)
{
- // only has an effect if bank is already 14 or 15
- if (m_base_bank == 14 || m_base_bank == 15)
- {
- if (offset & 0x0040)
- {
- m_base_bank = 15;
- }
- else
- {
- m_base_bank = 14;
- }
-
- }
+ if (address & 0x0040)
+ m_bank->set_entry(15);
+ else
+ m_bank->set_entry(14);
}
}
+
+void a26_rom_x07_device::change_bank2(offs_t address)
+{
+ m_bank->set_entry((address >> 4) & 0x0f);
+}