diff options
author | wilbertpol <wilbertpol@users.noreply.github.com> | 2022-07-23 17:46:36 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-23 11:46:36 -0400 |
commit | 2393899c979264ce3c75bc94fee3f2a73c91c9a7 (patch) | |
tree | 9925c1f2fe6b4d604b6c34e5dd619a9096cfcf29 /src/devices/bus | |
parent | c2c4a2dd13a01decc087f6762e146a599bed0e1a (diff) |
atari/a2600.cpp: Remove device lookups. (#10094)
* atari/a2600.cpp: Remove device lookups.
* a2600.xml: Fix description for challenge and add usage note.
* a2600.cpp: Simplified vcs_cart_slot_device. Let cartridges install themselves.
* bus/vcs/rom.cpp: Reorganized code so each class's code is together.
* bus/vcs/vcs_slot.cpp: Moved pcb enum from .h to .cpp file
Diffstat (limited to 'src/devices/bus')
-rw-r--r-- | src/devices/bus/vcs/compumat.cpp | 7 | ||||
-rw-r--r-- | src/devices/bus/vcs/compumat.h | 10 | ||||
-rw-r--r-- | src/devices/bus/vcs/dpc.cpp | 19 | ||||
-rw-r--r-- | src/devices/bus/vcs/dpc.h | 9 | ||||
-rw-r--r-- | src/devices/bus/vcs/harmony_melody.cpp | 30 | ||||
-rw-r--r-- | src/devices/bus/vcs/harmony_melody.h | 13 | ||||
-rw-r--r-- | src/devices/bus/vcs/rom.cpp | 856 | ||||
-rw-r--r-- | src/devices/bus/vcs/rom.h | 223 | ||||
-rw-r--r-- | src/devices/bus/vcs/scharger.cpp | 76 | ||||
-rw-r--r-- | src/devices/bus/vcs/scharger.h | 21 | ||||
-rw-r--r-- | src/devices/bus/vcs/vcs_slot.cpp | 121 | ||||
-rw-r--r-- | src/devices/bus/vcs/vcs_slot.h | 112 |
12 files changed, 748 insertions, 749 deletions
diff --git a/src/devices/bus/vcs/compumat.cpp b/src/devices/bus/vcs/compumat.cpp index 6b176bf1e03..a177637da6a 100644 --- a/src/devices/bus/vcs/compumat.cpp +++ b/src/devices/bus/vcs/compumat.cpp @@ -46,8 +46,13 @@ ioport_constructor a26_rom_cm_device::device_input_ports() const } +void a26_rom_cm_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_cm_device::read))); +} + -uint8_t a26_rom_cm_device::read_rom(offs_t offset) +uint8_t a26_rom_cm_device::read(offs_t offset) { return m_rom[offset + (m_base_bank * 0x1000)]; } diff --git a/src/devices/bus/vcs/compumat.h b/src/devices/bus/vcs/compumat.h index 8841ea6c660..4dd0c7f0092 100644 --- a/src/devices/bus/vcs/compumat.h +++ b/src/devices/bus/vcs/compumat.h @@ -20,12 +20,14 @@ public: a26_rom_cm_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); // device-level overrides - virtual void device_start() override; virtual ioport_constructor device_input_ports() const override; - virtual void device_reset() override; - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; + virtual void install_memory_handlers(address_space *space) override; + +protected: + virtual void device_start() override; + virtual void device_reset() override; + uint8_t read(offs_t offset); }; diff --git a/src/devices/bus/vcs/dpc.cpp b/src/devices/bus/vcs/dpc.cpp index 4e6989bf86a..e4c742c18e4 100644 --- a/src/devices/bus/vcs/dpc.cpp +++ b/src/devices/bus/vcs/dpc.cpp @@ -243,11 +243,6 @@ a26_rom_dpc_device::a26_rom_dpc_device(const machine_config &mconfig, const char // mapper specific start/reset //------------------------------------------------- -void a26_rom_dpc_device::device_start() -{ - save_item(NAME(m_base_bank)); -} - void a26_rom_dpc_device::device_reset() { m_base_bank = 0; @@ -264,18 +259,24 @@ void a26_rom_dpc_device::device_add_mconfig(machine_config &config) ATARI_DPC(config, m_dpc, 0); } -uint8_t a26_rom_dpc_device::read_rom(offs_t offset) +void a26_rom_dpc_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_dpc_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_dpc_device::write))); +} + +uint8_t a26_rom_dpc_device::read(offs_t offset) { if (offset < 0x40) return m_dpc->read(offset); else - return a26_rom_f8_device::read_rom(offset); + return a26_rom_f8_device::read(offset); } -void a26_rom_dpc_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_dpc_device::write(offs_t offset, uint8_t data) { if (offset >= 0x40 && offset < 0x80) m_dpc->write(offset, data); else - a26_rom_f8_device::write_bank(space, offset, data); + a26_rom_f8_device::write(offset, data); } diff --git a/src/devices/bus/vcs/dpc.h b/src/devices/bus/vcs/dpc.h index 1b339c98515..acb411707ac 100644 --- a/src/devices/bus/vcs/dpc.h +++ b/src/devices/bus/vcs/dpc.h @@ -67,22 +67,19 @@ DECLARE_DEVICE_TYPE(ATARI_DPC, dpc_device) class a26_rom_dpc_device : public a26_rom_f8_device { public: - // construction/destruction a26_rom_dpc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); required_device<dpc_device> m_dpc; - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; virtual void setup_addon_ptr(uint8_t *ptr) override; protected: - // device-level overrides - virtual void device_start() override; virtual void device_add_mconfig(machine_config &config) override; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); }; diff --git a/src/devices/bus/vcs/harmony_melody.cpp b/src/devices/bus/vcs/harmony_melody.cpp index b6bd4211e7b..79be1c3a137 100644 --- a/src/devices/bus/vcs/harmony_melody.cpp +++ b/src/devices/bus/vcs/harmony_melody.cpp @@ -65,7 +65,7 @@ DEFINE_DEVICE_TYPE(A26_ROM_HARMONY, a26_rom_harmony_device, "a2600_harmony", "At a26_rom_harmony_device::a26_rom_harmony_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a26_rom_f8_device(mconfig, A26_ROM_HARMONY, tag, owner, clock), m_cpu(*this, "arm") + : a26_rom_f6_device(mconfig, A26_ROM_HARMONY, tag, owner, clock), m_cpu(*this, "arm") { } @@ -73,11 +73,6 @@ a26_rom_harmony_device::a26_rom_harmony_device(const machine_config &mconfig, co // mapper specific start/reset //------------------------------------------------- -void a26_rom_harmony_device::device_start() -{ - save_item(NAME(m_base_bank)); -} - void a26_rom_harmony_device::harmony_arm7_map(address_map &map) { } @@ -114,17 +109,23 @@ void a26_rom_harmony_device::check_bankswitch(offs_t offset) { switch (offset) { - case 0x0FF6: m_base_bank = 0; break; - case 0x0FF7: m_base_bank = 1; break; - case 0x0FF8: m_base_bank = 2; break; - case 0x0FF9: m_base_bank = 3; break; - case 0x0FFa: m_base_bank = 4; break; - case 0x0FFb: m_base_bank = 5; break; + case 0x0ff6: m_base_bank = 0; break; + case 0x0ff7: m_base_bank = 1; break; + case 0x0ff8: m_base_bank = 2; break; + case 0x0ff9: m_base_bank = 3; break; + case 0x0ffa: m_base_bank = 4; break; + case 0x0ffb: m_base_bank = 5; break; default: break; } } -uint8_t a26_rom_harmony_device::read_rom(offs_t offset) +void a26_rom_harmony_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_harmony_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_harmony_device::write))); +} + +uint8_t a26_rom_harmony_device::read(offs_t offset) { uint8_t retvalue = read8_r(offset + 0xc00); // banks start at 0xc00 @@ -133,8 +134,7 @@ uint8_t a26_rom_harmony_device::read_rom(offs_t offset) return retvalue; } -void a26_rom_harmony_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_harmony_device::write(offs_t offset, uint8_t data) { check_bankswitch(offset); -// a26_rom_f8_device::write_bank(space, offset, data); } diff --git a/src/devices/bus/vcs/harmony_melody.h b/src/devices/bus/vcs/harmony_melody.h index d8198ba0b59..9376a797b95 100644 --- a/src/devices/bus/vcs/harmony_melody.h +++ b/src/devices/bus/vcs/harmony_melody.h @@ -11,28 +11,23 @@ // ======================> a26_rom_harmony_device -class a26_rom_harmony_device : public a26_rom_f8_device +class a26_rom_harmony_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_harmony_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); private: - // device-level overrides - virtual void device_start() override; virtual void device_reset() override; virtual void device_add_mconfig(machine_config &config) override; - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; private: void check_bankswitch(offs_t offset); - + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); uint8_t read8_r(offs_t offset); - void harmony_arm7_map(address_map &map); required_device<lpc210x_device> m_cpu; diff --git a/src/devices/bus/vcs/rom.cpp b/src/devices/bus/vcs/rom.cpp index 996c8237050..b823531b7d4 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,150 +43,49 @@ 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) -{ -} - - -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) -{ -} - - -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) -{ -} - -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) -{ -} +/*------------------------------------------------- + BASE 2K & 4K Carts: + no bankswitch -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) -{ -} - + GAMES: a large majority + -------------------------------------------------*/ -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_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_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) +void a26_rom_2k_4k_device::install_memory_handlers(address_space *space) { + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_2k_4k_device::read))); } - -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) -{ -} - - -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) +uint8_t a26_rom_2k_4k_device::read(offs_t offset) { + return m_rom[offset & (m_rom_size - 1)]; } -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) -{ -} - -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) -{ -} +/*------------------------------------------------- + "F6 Bankswitch" Carts: + read/write access to 0x1ff6-0x1ff9 determines the + 4K ROM bank to be read -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) -{ -} + GAMES: Atari 16K games, like Crossbow, Crystal + Castles and the 2-in-1 carts + -------------------------------------------------*/ -void a26_rom_2k_device::device_start() +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_base_bank(0xff) { } -void a26_rom_2k_device::device_reset() +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) { } @@ -201,154 +99,13 @@ 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; -} - -void a26_rom_e0_device::device_start() -{ - 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() +void a26_rom_f6_device::install_memory_handlers(address_space *space) { - m_base_bank = 0; + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_f6_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_f6_device::write))); } -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)); -} - -void a26_rom_8in1_device::device_reset() -{ - // 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; -} - - -void a26_rom_32in1_device::device_reset() -{ - m_base_bank++; - m_base_bank &= 0x1f; -} - - -/*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ - -/*------------------------------------------------- - BASE 2K & 4K Carts: - no bankswitch - - GAMES: a large majority - -------------------------------------------------*/ - -uint8_t a26_rom_2k_device::read_rom(offs_t offset) -{ - // 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: - read/write access to 0x1ff4-0x1ffb determines the - 4K ROM bank to be read - - GAMES: Fatal Run - -------------------------------------------------*/ - -uint8_t a26_rom_f4_device::read_rom(offs_t offset) +uint8_t a26_rom_f6_device::read(offs_t offset) { // Super Chip RAM reads are mapped in 0x1080-0x10ff if (!m_ram.empty() && offset >= 0x80 && offset < 0x100) @@ -361,15 +118,11 @@ uint8_t a26_rom_f4_device::read_rom(offs_t offset) { switch (offset) { - case 0x0ff4: - case 0x0ff5: case 0x0ff6: case 0x0ff7: case 0x0ff8: case 0x0ff9: - case 0x0ffa: - case 0x0ffb: - m_base_bank = offset - 0x0ff4; + m_base_bank = offset - 0x0ff6; break; } } @@ -377,7 +130,7 @@ uint8_t a26_rom_f4_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_f4_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_f6_device::write(offs_t offset, uint8_t data) { // Super Chip RAM writes are mapped in 0x1000-0x107f if (!m_ram.empty() && offset < 0x80) @@ -388,15 +141,11 @@ void a26_rom_f4_device::write_bank(address_space &space, offs_t offset, uint8_t switch (offset) { - case 0x0ff4: - case 0x0ff5: case 0x0ff6: case 0x0ff7: case 0x0ff8: case 0x0ff9: - case 0x0ffa: - case 0x0ffb: - m_base_bank = offset - 0x0ff4; + m_base_bank = offset - 0x0ff6; break; default: logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000); @@ -404,17 +153,33 @@ void a26_rom_f4_device::write_bank(address_space &space, offs_t offset, uint8_t } } + + /*------------------------------------------------- - "F6 Bankswitch" Carts: - read/write access to 0x1ff6-0x1ff9 determines the + "F4 Bankswitch" Carts: + read/write access to 0x1ff4-0x1ffb determines the 4K ROM bank to be read - GAMES: Atari 16K games, like Crossbow, Crystal - Castles and the 2-in-1 carts - + GAMES: Fatal Run -------------------------------------------------*/ -uint8_t a26_rom_f6_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_f4_device::device_reset() +{ + m_base_bank = 7; +} + +void a26_rom_f4_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_f4_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_f4_device::write))); +} + +uint8_t a26_rom_f4_device::read(offs_t offset) { // Super Chip RAM reads are mapped in 0x1080-0x10ff if (!m_ram.empty() && offset >= 0x80 && offset < 0x100) @@ -427,11 +192,15 @@ uint8_t a26_rom_f6_device::read_rom(offs_t offset) { switch (offset) { + case 0x0ff4: + case 0x0ff5: case 0x0ff6: case 0x0ff7: case 0x0ff8: case 0x0ff9: - m_base_bank = offset - 0x0ff6; + case 0x0ffa: + case 0x0ffb: + m_base_bank = offset - 0x0ff4; break; } } @@ -439,7 +208,7 @@ uint8_t a26_rom_f6_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_f6_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_f4_device::write(offs_t offset, uint8_t data) { // Super Chip RAM writes are mapped in 0x1000-0x107f if (!m_ram.empty() && offset < 0x80) @@ -450,11 +219,15 @@ void a26_rom_f6_device::write_bank(address_space &space, offs_t offset, uint8_t switch (offset) { + case 0x0ff4: + case 0x0ff5: case 0x0ff6: case 0x0ff7: case 0x0ff8: case 0x0ff9: - m_base_bank = offset - 0x0ff6; + case 0x0ffa: + case 0x0ffb: + m_base_bank = offset - 0x0ff4; break; default: logerror("Write Bank outside expected range (0x%X).\n", offset + 0x1000); @@ -462,6 +235,7 @@ void a26_rom_f6_device::write_bank(address_space &space, offs_t offset, uint8_t } } + /*------------------------------------------------- "F8 Bankswitch" Carts: read/write access to 0x1ff8-0x1ff9 determines the @@ -472,7 +246,23 @@ void a26_rom_f6_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_f8_device::read_rom(offs_t 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) +{ +} + +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) +{ +} + +void a26_rom_f8_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_f8_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_f8_device::write))); +} + +uint8_t a26_rom_f8_device::read(offs_t offset) { // Super Chip RAM reads are mapped in 0x1080-0x10ff if (!m_ram.empty() && offset >= 0x80 && offset < 0x100) @@ -495,7 +285,7 @@ uint8_t a26_rom_f8_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_f8_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_f8_device::write(offs_t offset, uint8_t data) { // Super Chip RAM writes are mapped in 0x1000-0x107f if (!m_ram.empty() && offset < 0x80) @@ -516,6 +306,21 @@ void a26_rom_f8_device::write_bank(address_space &space, offs_t offset, uint8_t } } + +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) +{ +} + +void a26_rom_f8_sw_device::device_reset() +{ + // Snow White proto starts from bank 1!!! + m_base_bank = 1; +} + + + + /*------------------------------------------------- "FA Bankswitch" Carts: read/write access to 0x1ff8-0x1ffa determines the @@ -528,7 +333,18 @@ void a26_rom_f8_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_fa_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_fa_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_fa_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_fa_device::write))); +} + +uint8_t a26_rom_fa_device::read(offs_t offset) { // CBS RAM+ reads are mapped in 0x1100-0x11ff if (!m_ram.empty() && offset >= 0x100 && offset < 0x200) @@ -552,12 +368,13 @@ uint8_t a26_rom_fa_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_fa_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_fa_device::write(offs_t offset, uint8_t data) { // CBS RAM+ writes are mapped in 0x1000-0x10ff if (!m_ram.empty() && offset < 0x100) { m_ram[offset & (m_ram.size() - 1)] = data; + return; } switch (offset) @@ -573,6 +390,8 @@ void a26_rom_fa_device::write_bank(address_space &space, offs_t offset, uint8_t } } + + /*------------------------------------------------- "FE Bankswitch" Carts: read/write access to 0x01fe-0x1ff determines the @@ -581,6 +400,41 @@ void a26_rom_fa_device::write_bank(address_space &space, offs_t offset, uint8_t 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_base_bank(0) + , m_trigger_on_next_access(0) +{ +} + +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 = 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) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_fe_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_fe_device::write))); + 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, "bank", + [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,7 +447,7 @@ void a26_rom_fa_device::write_bank(address_space &space, offs_t offset, uint8_t */ -uint8_t a26_rom_fe_device::read_rom(offs_t offset) +uint8_t a26_rom_fe_device::read(offs_t offset) { uint8_t data; @@ -607,17 +461,13 @@ uint8_t a26_rom_fe_device::read_rom(offs_t offset) if (!machine().side_effects_disabled()) { - if (m_trigger_on_next_access) - { - m_base_bank = BIT(data, 5) ? 0 : 1; - m_trigger_on_next_access = 0; - } + switch_bank(data); } return data; } -void a26_rom_fe_device::write_ram(offs_t offset, uint8_t data) +void a26_rom_fe_device::write(offs_t offset, uint8_t data) { // Super Chip RAM writes are mapped in 0x1000-0x107f if (!m_ram.empty() && offset < 0x80) @@ -626,41 +476,26 @@ void a26_rom_fe_device::write_ram(offs_t offset, uint8_t data) } } -uint8_t a26_rom_fe_device::read_bank(address_space &space, offs_t offset) +void a26_rom_fe_device::switch_bank(uint8_t data) { - uint8_t data = space.read_byte(0xfe + offset); - - if (!machine().side_effects_disabled()) + if (m_trigger_on_next_access) { - 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; - } + m_base_bank = BIT(data, 5) ? 0 : 1; + m_trigger_on_next_access = false; } - return data; } -void a26_rom_fe_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_fe_device::trigger_bank() { - space.write_byte(0xfe, data); - if (!machine().side_effects_disabled()) - { + 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 = 1; - } + m_trigger_on_next_access = true; } + + /*------------------------------------------------- "3E Bankswitch" Carts: write access to 0x3e determines the 2K ROM bank to @@ -671,36 +506,69 @@ void a26_rom_fe_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_3e_device::read_rom(offs_t offset) +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_bank_mask(0) + , m_ram_bank(0) + , m_ram_enable(false) +{ +} + +void a26_rom_3e_device::device_start() +{ + a26_rom_f6_device::device_start(); + save_item(NAME(m_ram_bank)); + save_item(NAME(m_ram_enable)); +} + +void a26_rom_3e_device::device_reset() +{ + m_bank_mask = (m_rom_size / 0x800) - 1; + m_base_bank = m_bank_mask; + m_ram_bank = 0; + m_ram_enable = false; +} + +void a26_rom_3e_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_3e_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_3e_device::write))); + space->install_write_tap(0x00, 0x3f, "bank", + [this](offs_t offset, u8 &data, u8) { if(!machine().side_effects_disabled()) write_bank(offset, data); } + ); +} + +uint8_t a26_rom_3e_device::read(offs_t offset) { 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]; + return m_rom[(offset & 0x7ff) + m_bank_mask * 0x800]; else return m_rom[offset + m_base_bank * 0x800]; } -void a26_rom_3e_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_3e_device::write(offs_t offset, uint8_t data) +{ + if (!m_ram.empty() && m_ram_enable && offset >= 0x400 && offset < 0x800) + m_ram[(offset & 0x3ff) + (m_ram_bank * 0x400)] = data; +} + +void a26_rom_3e_device::write_bank(offs_t offset, uint8_t data) { if (offset == 0x3f) { - m_base_bank = data & (m_num_bank - 1); - m_ram_enable = 0; + m_base_bank = data & m_bank_mask; + m_ram_enable = false; } else if (offset == 0x3e) { m_ram_bank = data & 0x1f; - m_ram_enable = 1; + m_ram_enable = true; } } -void a26_rom_3e_device::write_ram(offs_t offset, uint8_t data) -{ - if (!m_ram.empty() && m_ram_enable && offset >= 0x400 && offset < 0x800) - m_ram[(offset & 0x3ff) + (m_ram_bank * 0x400)] = data; -} /*------------------------------------------------- @@ -714,19 +582,42 @@ void a26_rom_3e_device::write_ram(offs_t offset, uint8_t data) -------------------------------------------------*/ -uint8_t a26_rom_3f_device::read_rom(offs_t offset) +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_bank_mask(0) +{ +} + +void a26_rom_3f_device::device_reset() +{ + m_bank_mask = (m_rom_size / 0x800) - 1; + m_base_bank = m_bank_mask; +} + +void a26_rom_3f_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_3f_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_3f_device::write))); + space->install_write_tap(0x00, 0x3f, "bank", + [this](offs_t offset, u8 &data, u8) { if(!machine().side_effects_disabled()) write_bank(offset, data); } + ); +} + +uint8_t a26_rom_3f_device::read(offs_t offset) { if (offset >= 0x800) - return m_rom[(offset & 0x7ff) + (m_num_bank - 1) * 0x800]; + return m_rom[(offset & 0x7ff) + m_bank_mask * 0x800]; else return m_rom[offset + m_base_bank * 0x800]; } -void a26_rom_3f_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_3f_device::write_bank(offs_t offset, uint8_t data) { - m_base_bank = data & (m_num_bank - 1); + m_base_bank = data & m_bank_mask; } + + /*------------------------------------------------- "E0 Bankswitch" Carts: read/write access to 0x1fe0-0x1ff8 determines the @@ -737,7 +628,31 @@ void a26_rom_3f_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_e0_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_e0_device::device_start() +{ + 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_e0_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_e0_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_e0_device::write))); +} + +uint8_t a26_rom_e0_device::read(offs_t offset) { // update banks if (!machine().side_effects_disabled()) @@ -749,13 +664,14 @@ uint8_t a26_rom_e0_device::read_rom(offs_t offset) return m_rom[(offset & 0x3ff) + (m_base_banks[(offset >> 10) & 3] * 0x400)]; } -void a26_rom_e0_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_e0_device::write(offs_t offset, uint8_t data) { if (offset >= 0xfe0 && offset <= 0xff8) m_base_banks[(offset >> 3) & 3] = offset & 7; } + /*------------------------------------------------- "E7 Bankswitch" Carts: this PCB can handle up to 16K of ROM and 2K of RAM, @@ -776,7 +692,30 @@ void a26_rom_e0_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_e7_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_e7_device::device_start() +{ + a26_rom_f6_device::device_start(); + save_item(NAME(m_ram_bank)); +} + +void a26_rom_e7_device::device_reset() +{ + m_base_bank = 0; + m_ram_bank = 0; +} + +void a26_rom_e7_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_e7_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_e7_device::write))); +} + +uint8_t a26_rom_e7_device::read(offs_t offset) { // update banks if (!machine().side_effects_disabled()) @@ -806,7 +745,7 @@ uint8_t a26_rom_e7_device::read_rom(offs_t offset) return m_rom[(offset & 0x7ff) + (m_base_bank * 0x800)]; } -void a26_rom_e7_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_e7_device::write(offs_t offset, uint8_t data) { if (offset >= 0xfe0 && offset <= 0xfe7) m_base_bank = offset - 0xfe0; @@ -827,6 +766,8 @@ void a26_rom_e7_device::write_bank(address_space &space, offs_t offset, uint8_t } } + + /*------------------------------------------------- "UA Bankswitch" Carts: read/write access to 0x200-0x27f determines the @@ -838,25 +779,37 @@ void a26_rom_e7_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_ua_device::read_rom(offs_t offset) +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) { - return m_rom[(offset + (m_base_bank * 0x1000)) & (m_rom_size - 1)]; } -uint8_t a26_rom_ua_device::read_bank(address_space &space, offs_t offset) +void a26_rom_ua_device::device_reset() { - if (!machine().side_effects_disabled()) - m_base_bank = offset >> 6; + m_base_bank = 0; +} - return 0; +void a26_rom_ua_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_ua_device::read))); + 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); } + ); } -void a26_rom_ua_device::write_bank(address_space &space, offs_t offset, uint8_t data) +uint8_t a26_rom_ua_device::read(offs_t offset) +{ + return m_rom[(offset + (m_base_bank * 0x1000)) & (m_rom_size - 1)]; +} + +void a26_rom_ua_device::change_bank(offs_t offset) { m_base_bank = offset >> 6; } + /*------------------------------------------------- Commavid Carts: It allows for both ROM and RAM on the cartridge, @@ -867,7 +820,18 @@ void a26_rom_ua_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_cv_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_cv_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_cv_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_cv_device::write))); +} + +uint8_t a26_rom_cv_device::read(offs_t offset) { if (!m_ram.empty() && offset < 0x400) { @@ -879,7 +843,7 @@ uint8_t a26_rom_cv_device::read_rom(offs_t offset) return m_rom[offset & 0x7ff]; } -void a26_rom_cv_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_cv_device::write(offs_t offset, uint8_t data) { if (!m_ram.empty() && offset >= 0x400 && offset < 0x800) { @@ -888,6 +852,7 @@ void a26_rom_cv_device::write_bank(address_space &space, offs_t offset, uint8_t } + /*------------------------------------------------- Dynacom Megaboy Carts (aka "F0 Banswitch"): read/write access to 0x1ff0 determines the 4K ROM @@ -898,7 +863,18 @@ void a26_rom_cv_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_dc_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_dc_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_dc_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_dc_device::write))); +} + +uint8_t a26_rom_dc_device::read(offs_t offset) { if (!machine().side_effects_disabled()) { @@ -912,13 +888,14 @@ uint8_t a26_rom_dc_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_dc_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_dc_device::write(offs_t offset, uint8_t data) { if (offset == 0xff0) m_base_bank = (m_base_bank + 1) & 0x0f; } + /*------------------------------------------------- "FV Bankswitch" Carts: The first access to 0x1fd0 switch the bank, but @@ -928,15 +905,39 @@ void a26_rom_dc_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_fv_device::read_rom(offs_t offset) +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(false) +{ +} + +void a26_rom_fv_device::device_start() +{ + a26_rom_f6_device::device_start(); + save_item(NAME(m_locked)); +} + +void a26_rom_fv_device::device_reset() +{ + m_base_bank = 0; + m_locked = false; +} + +void a26_rom_fv_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_fv_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_fv_device::write))); +} + +uint8_t a26_rom_fv_device::read(offs_t offset) { if (!machine().side_effects_disabled()) { if (offset == 0xfd0) { - if (!m_locked && (machine().device<cpu_device>("maincpu")->pc() & 0x1f00) == 0x1f00) + if (!m_locked) { - m_locked = 1; + m_locked = true; m_base_bank = m_base_bank ^ 0x01; } } @@ -945,19 +946,20 @@ uint8_t a26_rom_fv_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_fv_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_fv_device::write(offs_t offset, uint8_t data) { if (offset == 0xfd0) { - if (!m_locked && (machine().device<cpu_device>("maincpu")->pc() & 0x1f00) == 0x1f00) + if (!m_locked) { - m_locked = 1; + m_locked = true; m_base_bank = m_base_bank ^ 0x01; } } } + /*------------------------------------------------- "JVP Bankswitch" Carts: read/write access to 0x0fa0-0x0fc0 determines the @@ -969,12 +971,26 @@ void a26_rom_fv_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_jvp_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_jvp_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_jvp_device::read))); + space->install_readwrite_tap(0xfa0, 0xfc0, "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); } + ); +} + +uint8_t a26_rom_jvp_device::read(offs_t offset) { return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_jvp_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_jvp_device::change_bank(offs_t offset) { switch (offset) { @@ -989,6 +1005,7 @@ void a26_rom_jvp_device::write_bank(address_space &space, offs_t offset, uint8_t } + /*------------------------------------------------- 4 in 1 Carts (Reset based): the 4K bank changes at each reset @@ -997,12 +1014,28 @@ void a26_rom_jvp_device::write_bank(address_space &space, offs_t offset, uint8_t -------------------------------------------------*/ -uint8_t a26_rom_4in1_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_4in1_device::device_reset() +{ + m_base_bank = (m_base_bank + 1) & 3; +} + +void a26_rom_4in1_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_4in1_device::read))); +} + +uint8_t a26_rom_4in1_device::read(offs_t offset) { return m_rom[offset + (m_base_bank * 0x1000)]; } + /*------------------------------------------------- 8 in 1 Carts (Reset based): the 8K banks change at each reset, and internally @@ -1012,7 +1045,33 @@ uint8_t a26_rom_4in1_device::read_rom(offs_t offset) -------------------------------------------------*/ -uint8_t a26_rom_8in1_device::read_rom(offs_t offset) +a26_rom_8in1_device::a26_rom_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a26_rom_f6_device(mconfig, A26_ROM_8IN1, tag, owner, clock) + , m_reset_bank(0xff) +{ +} + +void a26_rom_8in1_device::device_start() +{ + a26_rom_f6_device::device_start(); + save_item(NAME(m_reset_bank)); +} + +void a26_rom_8in1_device::device_reset() +{ + // we use two different bank counters: 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 + 1) & 7; + m_base_bank = 0; +} + +void a26_rom_8in1_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_8in1_device::read))); + space->install_write_handler(0x1000, 0x1fff, write8sm_delegate(*this, FUNC(a26_rom_8in1_device::write))); +} + +uint8_t a26_rom_8in1_device::read(offs_t offset) { if (!machine().side_effects_disabled()) { @@ -1028,6 +1087,21 @@ uint8_t a26_rom_8in1_device::read_rom(offs_t offset) return m_rom[offset + (m_base_bank * 0x1000) + (m_reset_bank * 0x2000)]; } +void a26_rom_8in1_device::write(offs_t offset, uint8_t data) +{ + 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; + } +} + + /*------------------------------------------------- 32 in 1 Carts (Reset based): @@ -1037,12 +1111,28 @@ uint8_t a26_rom_8in1_device::read_rom(offs_t offset) -------------------------------------------------*/ -uint8_t a26_rom_32in1_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_32in1_device::device_reset() +{ + m_base_bank = (m_base_bank + 1) & 0x1f; +} + +void a26_rom_32in1_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_32in1_device::read))); +} + +uint8_t a26_rom_32in1_device::read(offs_t offset) { return m_rom[(offset & 0x7ff) + (m_base_bank * 0x800)]; } + /*------------------------------------------------- "X07 Bankswitch" Carts: banking done with a PALC22V10B @@ -1050,43 +1140,49 @@ uint8_t a26_rom_32in1_device::read_rom(offs_t offset) http://blog.kevtris.org/blogfiles/Atari%202600%20Mappers.txt --------------------------------------------------*/ -uint8_t a26_rom_x07_device::read_rom(offs_t offset) +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) +{ +} + +void a26_rom_x07_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_x07_device::read))); + space->install_readwrite_tap(0x0000, 0x0fff, "bank", + [this](offs_t offset, u8 &, u8) { if(!machine().side_effects_disabled()) change_bank(offset); }, + [this](offs_t offset, u8 &, u8) { if(!machine().side_effects_disabled()) change_bank(offset); } + ); +} + +uint8_t a26_rom_x07_device::read(offs_t offset) { return m_rom[offset + (m_base_bank * 0x1000)]; } -void a26_rom_x07_device::write_bank(address_space &space, offs_t offset, uint8_t data) +void a26_rom_x07_device::change_bank(offs_t offset) { /* A13 A0 ---------------- 0 1xxx nnnn 1101 */ - if ((offset & 0x180f) == 0x080d) - { m_base_bank = (offset & 0x00f0) >> 4; - } + /* A13 A0 ---------------- 0 0xxx 0nxx xxxx */ - if ((offset & 0x1880) == 0x0000) { // 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; - } - } } } diff --git a/src/devices/bus/vcs/rom.h b/src/devices/bus/vcs/rom.h index 60e3ec5663f..dd85e183d48 100644 --- a/src/devices/bus/vcs/rom.h +++ b/src/devices/bus/vcs/rom.h @@ -10,60 +10,49 @@ // ======================> a26_rom_2k_device -class a26_rom_2k_device : public device_t, - public device_vcs_cart_interface +class a26_rom_base_device : public device_t, + public device_vcs_cart_interface { -public: - // construction/destruction - a26_rom_2k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - protected: - a26_rom_2k_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + a26_rom_base_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) + { } - // device-level overrides - virtual void device_start() override; - virtual void device_reset() override; + virtual void device_start() override { } }; -// ======================> a26_rom_4k_device - -class a26_rom_4k_device : public a26_rom_2k_device +class a26_rom_2k_4k_device : public a26_rom_base_device { public: - // construction/destruction - a26_rom_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + a26_rom_2k_4k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing + virtual void install_memory_handlers(address_space *space) override; - // accesses just use the 2K ones, since it is just direct access to ROM/RAM - // masked with its size! +protected: + uint8_t read(offs_t offset); }; // ======================> a26_rom_f6_device -class a26_rom_f6_device : public a26_rom_2k_device +class a26_rom_f6_device : public a26_rom_base_device { public: - // construction/destruction a26_rom_f6_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: a26_rom_f6_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; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); - int m_base_bank; + uint8_t m_base_bank; }; @@ -72,16 +61,14 @@ protected: class a26_rom_f4_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_f4_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); }; @@ -90,15 +77,14 @@ protected: class a26_rom_f8_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_f8_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: a26_rom_f8_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock); + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); }; @@ -107,11 +93,9 @@ protected: class a26_rom_f8_sw_device : public a26_rom_f8_device { public: - // construction/destruction a26_rom_f8_sw_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); protected: - // device-level overrides virtual void device_reset() override; }; @@ -121,36 +105,36 @@ protected: class a26_rom_fa_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_fa_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; + +protected: + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); }; // ======================> a26_rom_fe_device -class a26_rom_fe_device : public a26_rom_2k_device +class a26_rom_fe_device : public a26_rom_base_device { public: - // construction/destruction a26_rom_fe_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual uint8_t read_bank(address_space &space, offs_t offset) override; - virtual void write_ram(offs_t offset, uint8_t data) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; - - int m_base_bank; - int m_trigger_on_next_access; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); + void trigger_bank(); + void switch_bank(uint8_t data); + + uint8_t m_base_bank; + bool m_trigger_on_next_access; + bool m_ignore_first_read; }; @@ -159,22 +143,20 @@ protected: class a26_rom_3e_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_3e_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; - virtual void write_ram(offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); + void write_bank(offs_t offset, uint8_t data); - int m_num_bank; - int m_ram_bank; - int m_ram_enable; + uint8_t m_bank_mask; + uint8_t m_ram_bank; + bool m_ram_enable; }; @@ -183,39 +165,35 @@ protected: class a26_rom_3f_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_3f_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_reset() override; + uint8_t read(offs_t offset); + void write_bank(offs_t offset, uint8_t data); - int m_num_bank; + uint8_t m_bank_mask; }; // ======================> a26_rom_e0_device -class a26_rom_e0_device : public a26_rom_f6_device +class a26_rom_e0_device : public a26_rom_base_device { public: - // construction/destruction a26_rom_e0_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); - int m_base_banks[4]; + uint8_t m_base_banks[4]; }; @@ -224,19 +202,17 @@ protected: class a26_rom_e7_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_e7_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); - int m_ram_bank; + uint8_t m_ram_bank; }; @@ -245,31 +221,29 @@ protected: class a26_rom_ua_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_ua_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual uint8_t read_bank(address_space &space, offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_reset() override; + void change_bank(offs_t offset); + uint8_t read(offs_t offset); }; // ======================> a26_rom_cv_device -class a26_rom_cv_device : public a26_rom_2k_device +class a26_rom_cv_device : public a26_rom_base_device { public: - // construction/destruction a26_rom_cv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; + +protected: + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); }; @@ -278,12 +252,13 @@ public: class a26_rom_dc_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_dc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; + +protected: + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); }; @@ -292,19 +267,17 @@ public: class a26_rom_fv_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_fv_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); - int m_locked; + bool m_locked; }; @@ -313,12 +286,13 @@ protected: class a26_rom_jvp_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_jvp_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; + +protected: + void change_bank(offs_t offset); + uint8_t read(offs_t offset); }; @@ -327,35 +301,32 @@ public: class a26_rom_4in1_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_4in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_reset() override; + uint8_t read(offs_t offset); }; // ======================> a26_rom_8in1_device -class a26_rom_8in1_device : public a26_rom_f8_device +class a26_rom_8in1_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_8in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; + uint8_t read(offs_t offset); + void write(offs_t offset, uint8_t data); - int m_reset_bank; + uint8_t m_reset_bank; }; @@ -364,15 +335,13 @@ protected: class a26_rom_32in1_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_32in1_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; + virtual void install_memory_handlers(address_space *space) override; protected: - // device-level overrides virtual void device_reset() override; + uint8_t read(offs_t offset); }; @@ -381,19 +350,19 @@ protected: class a26_rom_x07_device : public a26_rom_f6_device { public: - // construction/destruction a26_rom_x07_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) override; + virtual void install_memory_handlers(address_space *space) override; + +private: + void change_bank(offs_t offset); + uint8_t read(offs_t offset); }; // device type definition -DECLARE_DEVICE_TYPE(A26_ROM_2K, a26_rom_2k_device) -DECLARE_DEVICE_TYPE(A26_ROM_4K, a26_rom_4k_device) +DECLARE_DEVICE_TYPE(A26_ROM_2K_4K, a26_rom_2k_4k_device) DECLARE_DEVICE_TYPE(A26_ROM_F4, a26_rom_f4_device) DECLARE_DEVICE_TYPE(A26_ROM_F6, a26_rom_f6_device) DECLARE_DEVICE_TYPE(A26_ROM_F8, a26_rom_f8_device) diff --git a/src/devices/bus/vcs/scharger.cpp b/src/devices/bus/vcs/scharger.cpp index 91cf7cdf3d0..583d7407475 100644 --- a/src/devices/bus/vcs/scharger.cpp +++ b/src/devices/bus/vcs/scharger.cpp @@ -37,20 +37,22 @@ #include "sound/wave.h" #include "formats/a26_cas.h" +//#define VERBOSE (LOG_GENERAL) +#include "logmacro.h" + + DEFINE_DEVICE_TYPE(A26_ROM_SUPERCHARGER, a26_rom_ss_device, "a2600_ss", "Atari 2600 ROM Cart Supercharger") a26_rom_ss_device::a26_rom_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a26_rom_f6_device(mconfig, A26_ROM_SUPERCHARGER, tag, owner, clock), + : a26_rom_base_device(mconfig, A26_ROM_SUPERCHARGER, tag, owner, clock), m_cassette(*this, "cassette"), - m_maincpu(nullptr), m_reg(0), m_write_delay(0), m_ram_write_enabled(0), m_rom_enabled(0), - m_byte_started(0), - m_last_address(0), - m_diff_adjust(0) + m_last_address_bus(0), + m_address_bus_changes(0) { } @@ -60,16 +62,13 @@ a26_rom_ss_device::a26_rom_ss_device(const machine_config &mconfig, const char * void a26_rom_ss_device::device_start() { - m_maincpu = machine().device<cpu_device>("maincpu"); - save_item(NAME(m_base_banks)); save_item(NAME(m_reg)); save_item(NAME(m_write_delay)); save_item(NAME(m_ram_write_enabled)); save_item(NAME(m_rom_enabled)); - save_item(NAME(m_byte_started)); - save_item(NAME(m_last_address)); - save_item(NAME(m_diff_adjust)); + save_item(NAME(m_last_address_bus)); + save_item(NAME(m_address_bus_changes)); } void a26_rom_ss_device::device_reset() @@ -78,12 +77,11 @@ void a26_rom_ss_device::device_reset() m_base_banks[0] = 2; m_base_banks[1] = 3; m_ram_write_enabled = 0; - m_byte_started = 0; m_reg = 0; m_write_delay = 0; m_rom_enabled = 1; - m_last_address = 0; - m_diff_adjust = 0; + m_last_address_bus = 0; + m_address_bus_changes = 0; } @@ -109,7 +107,23 @@ inline uint8_t a26_rom_ss_device::read_byte(uint32_t offset) return 0xff; } -uint8_t a26_rom_ss_device::read_rom(offs_t offset) +void a26_rom_ss_device::install_memory_handlers(address_space *space) +{ + space->install_read_handler(0x1000, 0x1fff, read8sm_delegate(*this, FUNC(a26_rom_ss_device::read))); + space->install_readwrite_tap(0x0000, 0x1fff, "bank", + [this](offs_t offset, u8 &, u8) { if(!machine().side_effects_disabled()) tap(offset); }, + [this](offs_t offset, u8 &, u8) { if(!machine().side_effects_disabled()) tap(offset); } + ); +} + +void a26_rom_ss_device::tap(offs_t offset) +{ + if (m_last_address_bus != offset) + m_address_bus_changes++; + m_last_address_bus = offset; +} + +uint8_t a26_rom_ss_device::read(offs_t offset) { if (machine().side_effects_disabled()) return read_byte(offset); @@ -117,13 +131,13 @@ uint8_t a26_rom_ss_device::read_rom(offs_t offset) // Bankswitch if (offset == 0xff8) { - //logerror("%04X: Access to control register data = %02X\n", m_maincpu->pc(), m_modeSS_byte); + LOG("write control register %02X\n", m_reg); m_write_delay = m_reg >> 5; m_ram_write_enabled = BIT(m_reg, 1); m_rom_enabled = !BIT(m_reg, 0); - // compensate time spent in this access to avoid spurious RAM write - m_byte_started -= 5; + // prevent spurious RAM write + m_address_bus_changes += 6; // handle bankswitch switch (m_reg & 0x1c) @@ -167,11 +181,10 @@ uint8_t a26_rom_ss_device::read_rom(offs_t offset) // Cassette port read else if (offset == 0xff9) { - //logerror("%04X: Cassette port read, tap_val = %f\n", m_maincpu->pc(), tap_val); double tap_val = m_cassette->input(); - // compensate time spent in this access to avoid spurious RAM write - m_byte_started -= 5; + // prevent spurious RAM write + m_address_bus_changes += 6; if (tap_val < 0) return 0x00; @@ -183,35 +196,30 @@ uint8_t a26_rom_ss_device::read_rom(offs_t offset) { if (m_ram_write_enabled) { - /* Check for dummy read from same address */ - if (m_last_address == offset) - m_diff_adjust++; - - int diff = m_maincpu->total_cycles() - m_byte_started; - //logerror("%04X: offset = %04X, %d\n", m_maincpu->pc(), offset, diff); - - if (diff - m_diff_adjust == 5) + if (m_address_bus_changes == 5) { - //logerror("%04X: RAM write offset = %04X, data = %02X\n", m_maincpu->pc(), offset, m_modeSS_byte ); if (offset < 0x800) + { + LOG("%s: RAM write offset %04X, data %02X\n", machine().describe_context(), (offset & 0x7ff) + (m_base_banks[0] * 0x800), m_reg); m_ram[(offset & 0x7ff) + (m_base_banks[0] * 0x800)] = m_reg; + } else if (m_base_banks[1] != 3) + { + LOG("%s: RAM write offset %04X, data %02X\n", machine().describe_context(), (offset & 0x7ff) + (m_base_banks[1] * 0x800), m_reg); m_ram[(offset & 0x7ff) + (m_base_banks[1] * 0x800)] = m_reg; + } } else if (offset < 0x0100) { m_reg = offset; - m_byte_started = m_maincpu->total_cycles(); - m_diff_adjust = 0; + m_address_bus_changes = 0; } } else if (offset < 0x0100) { m_reg = offset; - m_byte_started = m_maincpu->total_cycles(); - m_diff_adjust = 0; + m_address_bus_changes = 0; } - m_last_address = offset; return read_byte(offset); } } diff --git a/src/devices/bus/vcs/scharger.h b/src/devices/bus/vcs/scharger.h index 46d43c00b00..83e70910057 100644 --- a/src/devices/bus/vcs/scharger.h +++ b/src/devices/bus/vcs/scharger.h @@ -14,17 +14,15 @@ // ======================> a26_rom_ss_device -class a26_rom_ss_device : public a26_rom_f6_device +class a26_rom_ss_device : public a26_rom_base_device { public: - // construction/destruction a26_rom_ss_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); - // reading and writing - virtual uint8_t read_rom(offs_t offset) override; + virtual void install_memory_handlers(address_space *space) override; + uint8_t read(offs_t offset); private: - // device-level overrides virtual void device_start() override; virtual void device_reset() override; @@ -32,15 +30,16 @@ private: required_device<cassette_image_device> m_cassette; - cpu_device *m_maincpu; - inline uint8_t read_byte(uint32_t offset); + uint8_t read_byte(uint32_t offset); + void tap(offs_t offset); int m_base_banks[2]; uint8_t m_reg; - uint8_t m_write_delay, m_ram_write_enabled, m_rom_enabled; - uint32_t m_byte_started; - uint16_t m_last_address; - uint32_t m_diff_adjust; + uint8_t m_write_delay; + bool m_ram_write_enabled; + bool m_rom_enabled; + uint16_t m_last_address_bus; + uint32_t m_address_bus_changes; }; diff --git a/src/devices/bus/vcs/vcs_slot.cpp b/src/devices/bus/vcs/vcs_slot.cpp index 7be008584c5..cc6fd49d7b4 100644 --- a/src/devices/bus/vcs/vcs_slot.cpp +++ b/src/devices/bus/vcs/vcs_slot.cpp @@ -23,6 +23,34 @@ DEFINE_DEVICE_TYPE(VCS_CART_SLOT, vcs_cart_slot_device, "vcs_cart_slot", "Atari VCS 2600 Cartridge Slot") +/* PCB */ +enum +{ + A26_2K_4K = 0, + A26_F4, + A26_F6, + A26_F8, + A26_F8SW, + A26_FA, + A26_FE, + A26_3E, // to test + A26_3F, + A26_E0, + A26_E7, + A26_UA, + A26_DC, + A26_CV, + A26_FV, + A26_JVP, // to test + A26_32IN1, + A26_8IN1, + A26_4IN1, + A26_DPC, + A26_SS, + A26_CM, + A26_X07, + A26_HARMONY, +}; //------------------------------------------------- // device_vcs_cart_interface - constructor @@ -52,7 +80,7 @@ void device_vcs_cart_interface::rom_alloc(uint32_t size, const char *tag) { if (m_rom == nullptr) { - m_rom = device().machine().memory().region_alloc(std::string(tag).append(A26SLOT_ROM_REGION_TAG).c_str(), size, 1, ENDIANNESS_LITTLE)->base(); + m_rom = device().machine().memory().region_alloc(std::string(tag).append(":cart:rom").c_str(), size, 1, ENDIANNESS_LITTLE)->base(); m_rom_size = size; } } @@ -80,7 +108,9 @@ vcs_cart_slot_device::vcs_cart_slot_device(const machine_config &mconfig, const device_t(mconfig, VCS_CART_SLOT, tag, owner, clock), device_cartrom_image_interface(mconfig, *this), device_single_card_slot_interface<device_vcs_cart_interface>(mconfig, *this), - m_cart(nullptr), m_type(0) + m_cart(nullptr), + m_type(0), + m_address_space(*this, finder_base::DUMMY_TAG, -1, 8) { } @@ -121,8 +151,7 @@ struct vcs_slot // Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it static const vcs_slot slot_list[] = { - { A26_2K, "a26_2k" }, - { A26_4K, "a26_4k" }, + { A26_2K_4K, "a26_2k_4k" }, { A26_F4, "a26_f4" }, { A26_F6, "a26_f6" }, { A26_F8, "a26_f8" }, @@ -167,22 +196,14 @@ static const char *vcs_get_slot(int type) return elem.slot_option; } - return "a26_4k"; + return "a26_2k_4k"; } image_init_result vcs_cart_slot_device::call_load() { if (m_cart) { - uint8_t *ROM; - uint32_t len; - - if (loaded_through_softlist()) - len = get_software_region_length("rom"); - else - len = length(); - - //printf("Size: 0x%X\n", len); + const uint32_t len = loaded_through_softlist() ? get_software_region_length("rom") : length(); // check that filesize is among the supported ones switch (len) @@ -205,15 +226,14 @@ image_init_result vcs_cart_slot_device::call_load() } m_cart->rom_alloc(len, tag()); - ROM = m_cart->get_rom_base(); + uint8_t *ROM = m_cart->get_rom_base(); if (loaded_through_softlist()) { - const char *pcb_name; - bool has_ram = get_software_region("ram") ? true : false; memcpy(ROM, get_software_region("rom"), len); + const char *pcb_name = get_feature("slot"); - if ((pcb_name = get_feature("slot")) != nullptr) + if (pcb_name != nullptr) m_type = vcs_get_pcb_id(pcb_name); else { @@ -221,10 +241,8 @@ image_init_result vcs_cart_slot_device::call_load() switch (len) { case 0x800: - m_type = A26_2K; - break; case 0x1000: - m_type = A26_4K; + m_type = A26_2K_4K; break; case 0x2000: m_type = A26_F8; @@ -249,13 +267,13 @@ image_init_result vcs_cart_slot_device::call_load() m_type = A26_3F; break; default: - m_type = A26_4K; + m_type = A26_2K_4K; printf("Unrecognized cart type!\n"); break; } } - if (has_ram) + if (get_software_region("ram")) m_cart->ram_alloc(get_software_region_length("ram")); } else @@ -263,17 +281,12 @@ image_init_result vcs_cart_slot_device::call_load() fread(ROM, len); m_type = identify_cart_type(ROM, len); - // check for Special Chip (128bytes of RAM) + // check for Super Chip (128bytes of RAM) if (len == 0x2000 || len == 0x4000 || len == 0x8000) if (detect_super_chip(ROM, len)) { m_cart->ram_alloc(0x80); - //printf("Super Chip detected!\n"); } - // Super chip games: - // dig dig, crystal castles, millipede, stargate, defender ii, jr. Pac Man, - // desert falcon, dark chambers, super football, sprintmaster, fatal run, - // off the wall, shooting arcade, secret quest, radar lock, save mary, klax // add CBS RAM+ (256bytes of RAM) if (m_type == A26_FA) @@ -292,12 +305,12 @@ image_init_result vcs_cart_slot_device::call_load() m_cart->ram_alloc(0x8000); } - //printf("Type: %s\n", vcs_get_slot(m_type)); - // pass a pointer to the now allocated ROM for the DPC chip if (m_type == A26_DPC) m_cart->setup_addon_ptr((uint8_t *)m_cart->get_rom_base() + 0x2000); + m_cart->install_memory_handlers(m_address_space.target()); + return image_init_result::PASS; } @@ -717,10 +730,8 @@ int vcs_cart_slot_device::identify_cart_type(const uint8_t *ROM, uint32_t len) switch (len) { case 0x800: - type = A26_2K; - break; case 0x1000: - type = A26_4K; + type = A26_2K_4K; break; case 0x2000: type = A26_F8; @@ -745,7 +756,7 @@ int vcs_cart_slot_device::identify_cart_type(const uint8_t *ROM, uint32_t len) type = A26_3F; break; default: - type = A26_4K; + type = A26_2K_4K; printf("Unrecognized cart type!\n"); break; } @@ -775,43 +786,5 @@ std::string vcs_cart_slot_device::get_default_card_software(get_default_card_sof return std::string(slot_string); } else - return software_get_default_slot("a26_4k"); -} - - -/*------------------------------------------------- - read - -------------------------------------------------*/ - -uint8_t vcs_cart_slot_device::read_rom(offs_t offset) -{ - if (m_cart) - return m_cart->read_rom(offset); - else - return 0xff; -} - -uint8_t vcs_cart_slot_device::read_bank(address_space &space, offs_t offset) -{ - if (m_cart) - return m_cart->read_bank(space, offset); - else - return 0xff; -} - - -/*------------------------------------------------- - write - -------------------------------------------------*/ - -void vcs_cart_slot_device::write_bank(address_space &space, offs_t offset, uint8_t data) -{ - if (m_cart) - m_cart->write_bank(space, offset, data); -} - -void vcs_cart_slot_device::write_ram(offs_t offset, uint8_t data) -{ - if (m_cart) - m_cart->write_ram(offset, data); + return software_get_default_slot("a26_2k_4k"); } diff --git a/src/devices/bus/vcs/vcs_slot.h b/src/devices/bus/vcs/vcs_slot.h index 0f1b7d22509..d5c023e094b 100644 --- a/src/devices/bus/vcs/vcs_slot.h +++ b/src/devices/bus/vcs/vcs_slot.h @@ -8,80 +8,8 @@ #include "imagedev/cartrom.h" -/*************************************************************************** - TYPE DEFINITIONS - ***************************************************************************/ +class device_vcs_cart_interface; -#define A26SLOT_ROM_REGION_TAG ":cart:rom" - -/* PCB */ -enum -{ - A26_2K = 0, - A26_4K, - A26_F4, - A26_F6, - A26_F8, - A26_F8SW, - A26_FA, - A26_FE, - A26_3E, // to test - A26_3F, - A26_E0, - A26_E7, - A26_UA, - A26_DC, - A26_CV, - A26_FV, - A26_JVP, // to test - A26_32IN1, - A26_8IN1, - A26_4IN1, - A26_DPC, - A26_SS, - A26_CM, - A26_X07, - A26_HARMONY, -}; - - -// ======================> device_vcs_cart_interface - -class device_vcs_cart_interface : public device_interface -{ -public: - // construction/destruction - virtual ~device_vcs_cart_interface(); - - // reading from ROM - virtual uint8_t read_rom(offs_t offset) { return 0xff; } - // writing to RAM chips (sometimes it is in a different range than write_bank!) - virtual void write_ram(offs_t offset, uint8_t data) { } - - // read/write to bankswitch address - virtual uint8_t read_bank(address_space &space, offs_t offset) { return 0xff; } - virtual void write_bank(address_space &space, offs_t offset, uint8_t data) { } - - virtual void setup_addon_ptr(uint8_t *ptr) { } - - void rom_alloc(uint32_t size, const char *tag); - void ram_alloc(uint32_t size); - uint8_t* get_rom_base() { return m_rom; } - uint8_t* get_ram_base() { return &m_ram[0]; } - uint32_t get_rom_size() { return m_rom_size; } - uint32_t get_ram_size() { return m_ram.size(); } - -protected: - device_vcs_cart_interface(const machine_config &mconfig, device_t &device); - - // internal state - uint8_t *m_rom; - uint32_t m_rom_size; - std::vector<uint8_t> m_ram; -}; - - -// ======================> vcs_cart_slot_device class vcs_cart_slot_device : public device_t, public device_cartrom_image_interface, @@ -101,6 +29,8 @@ public: vcs_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0); virtual ~vcs_cart_slot_device(); + template <typename T> void set_address_space(T &&tag, int no) { m_address_space.set_tag(std::forward<T>(tag), no); } + // image-level overrides virtual image_init_result call_load() override; virtual void call_unload() override; @@ -115,12 +45,6 @@ public: int get_cart_type() { return m_type; } static int identify_cart_type(const uint8_t *ROM, uint32_t len); - // reading and writing - virtual uint8_t read_rom(offs_t offset); - virtual uint8_t read_bank(address_space &space, offs_t offset); - virtual void write_bank(address_space &space, offs_t offset, uint8_t data); - virtual void write_ram(offs_t offset, uint8_t data); - protected: // device-level overrides virtual void device_start() override; @@ -128,6 +52,7 @@ protected: private: device_vcs_cart_interface* m_cart; int m_type; + optional_address_space m_address_space; static bool detect_snowhite(const uint8_t *cart, uint32_t len); static bool detect_modeDC(const uint8_t *cart, uint32_t len); @@ -144,6 +69,35 @@ private: static bool detect_8K_mode3F(const uint8_t *cart, uint32_t len); static bool detect_32K_mode3F(const uint8_t *cart, uint32_t len); static bool detect_super_chip(const uint8_t *cart, uint32_t len); + + friend class device_vcs_cart_interface; +}; + + +class device_vcs_cart_interface : public device_interface +{ +public: + // construction/destruction + virtual ~device_vcs_cart_interface(); + + virtual void install_memory_handlers(address_space *space) { } + + virtual void setup_addon_ptr(uint8_t *ptr) { } + + void rom_alloc(uint32_t size, const char *tag); + void ram_alloc(uint32_t size); + uint8_t* get_rom_base() { return m_rom; } + uint8_t* get_ram_base() { return &m_ram[0]; } + uint32_t get_rom_size() { return m_rom_size; } + uint32_t get_ram_size() { return m_ram.size(); } + +protected: + device_vcs_cart_interface(const machine_config &mconfig, device_t &device); + + // internal state + uint8_t *m_rom; + uint32_t m_rom_size; + std::vector<uint8_t> m_ram; }; |