diff options
Diffstat (limited to 'src/devices/bus/a800/oss.cpp')
-rw-r--r-- | src/devices/bus/a800/oss.cpp | 315 |
1 files changed, 159 insertions, 156 deletions
diff --git a/src/devices/bus/a800/oss.cpp b/src/devices/bus/a800/oss.cpp index 70a9375ef28..bd1cf4025a6 100644 --- a/src/devices/bus/a800/oss.cpp +++ b/src/devices/bus/a800/oss.cpp @@ -1,10 +1,17 @@ // license:BSD-3-Clause -// copyright-holders:Fabio Priuli -/*********************************************************************************************************** +// copyright-holders:Fabio Priuli, Angelo Salese +/************************************************************************************************** - A800 ROM cart emulation + "Optimized System Software" OSS ROM cart emulation -***********************************************************************************************************/ +https://en.wikipedia.org/wiki/Optimized_Systems_Software + +Running on similar non-linear but incompatible banking schemes. + +TODO: +- OSS034M doesn't really exist, it's an OSS043M with wrong ROM contents. + +**************************************************************************************************/ #include "emu.h" @@ -15,37 +22,30 @@ // constructor //------------------------------------------------- -DEFINE_DEVICE_TYPE(A800_ROM_OSS8K, a800_rom_oss8k_device, "a800_oss8k", "Atari 800 ROM Carts OSS 8K") -DEFINE_DEVICE_TYPE(A800_ROM_OSS34, a800_rom_oss34_device, "a800_034m", "Atari 800 ROM Carts OSS-034M") -DEFINE_DEVICE_TYPE(A800_ROM_OSS43, a800_rom_oss43_device, "a800_043m", "Atari 800 ROM Carts OSS-043M") -DEFINE_DEVICE_TYPE(A800_ROM_OSS91, a800_rom_oss91_device, "a800_m091", "Atari 800 ROM Carts OSS-M091") +DEFINE_DEVICE_TYPE(A800_ROM_OSS8K, a800_rom_oss8k_device, "a800_oss8k", "Atari 8-bit OSS 8K cart") +DEFINE_DEVICE_TYPE(A800_ROM_OSS34, a800_rom_oss034m_device, "a800_034m", "Atari 8-bit OSS-034M cart") +DEFINE_DEVICE_TYPE(A800_ROM_OSS43, a800_rom_oss043m_device, "a800_043m", "Atari 8-bit OSS-043M cart") +DEFINE_DEVICE_TYPE(A800_ROM_OSS91, a800_rom_oss091m_device, "a800_m091", "Atari 8-bit OSS-M091 cart") +/*------------------------------------------------- -a800_rom_oss8k_device::a800_rom_oss8k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_OSS8K, tag, owner, clock), m_bank(0) -{ -} - + OSS 8K -a800_rom_oss34_device::a800_rom_oss34_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_OSS34, tag, owner, clock), m_bank(0) -{ -} + This is used by The Writer's Tool only. + -------------------------------------------------*/ -a800_rom_oss43_device::a800_rom_oss43_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_OSS43, tag, owner, clock), m_bank(0) +a800_rom_oss8k_device::a800_rom_oss8k_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_device(mconfig, type, tag, owner, clock) + , m_bank(0) { } - -a800_rom_oss91_device::a800_rom_oss91_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_OSS91, tag, owner, clock), m_bank(0) +a800_rom_oss8k_device::a800_rom_oss8k_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_oss8k_device(mconfig, A800_ROM_OSS8K, tag, owner, clock) { } - - void a800_rom_oss8k_device::device_start() { save_item(NAME(m_bank)); @@ -56,197 +56,200 @@ void a800_rom_oss8k_device::device_reset() m_bank = 0; } - -void a800_rom_oss34_device::device_start() -{ - save_item(NAME(m_bank)); -} - -void a800_rom_oss34_device::device_reset() +void a800_rom_oss8k_device::cart_map(address_map &map) { - m_bank = 1; + map(0x2000, 0x2fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank * 0x1000]; }) + ); + map(0x3000, 0x3fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & 0x0fff]; }) + ); } - -void a800_rom_oss43_device::device_start() +/* + * ---- 0--x selects bank 1 + * ---- 1--0 RD5 clear + * ---- 1--1 selects bank 0 + */ +inline void a800_rom_oss8k_device::bank_config_access(offs_t offset) { - save_item(NAME(m_bank)); + if (!(BIT(offset, 3))) + { + rd5_w(1); + m_bank = 1; + } + else + { + rd5_w(BIT(offset, 0)); + m_bank = 0; + } } -void a800_rom_oss43_device::device_reset() +u8 a800_rom_oss8k_device::rom_bank_r(offs_t offset) { - m_bank = 0; + if (!machine().side_effects_disabled()) + bank_config_access(offset); + return 0xff; } - -void a800_rom_oss91_device::device_start() +void a800_rom_oss8k_device::rom_bank_w(offs_t offset, u8 data) { - save_item(NAME(m_bank)); + bank_config_access(offset); } -void a800_rom_oss91_device::device_reset() +void a800_rom_oss8k_device::cctl_map(address_map &map) { - m_bank = 0; + map(0x00, 0xff).rw(FUNC(a800_rom_oss8k_device::rom_bank_r), FUNC(a800_rom_oss8k_device::rom_bank_w)); } - /*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ -/*------------------------------------------------- + OSS 091M - OSS 8K - - This is used by The Writer's Tool only. + Later variant of OSS 8k -------------------------------------------------*/ -READ8_MEMBER(a800_rom_oss8k_device::read_80xx) +a800_rom_oss091m_device::a800_rom_oss091m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_oss8k_device(mconfig, A800_ROM_OSS91, tag, owner, clock) { - if (offset >= 0x1000) - return m_rom[offset & 0xfff]; - else - return m_rom[(offset & 0xfff) + (m_bank * 0x1000)]; } -WRITE8_MEMBER(a800_rom_oss8k_device::write_d5xx) +/* + * ---- 0--0 bank 1 + * ---- 0--1 bank 3 + * ---- 1--0 RD5 clear + * ---- 1--1 bank 2 + */ +inline void a800_rom_oss091m_device::bank_config_access(offs_t offset) { - switch (offset & 0x09) + const u8 a0 = BIT(offset, 0); + if (!(BIT(offset, 3))) + { + rd5_w(1); + m_bank = 1 | (a0 << 1); + } + else { - case 0: - case 1: - m_bank = 1; - break; - case 9: - m_bank = 0; - break; - default: - break; + rd5_w(a0); + m_bank = 2; } } - /*------------------------------------------------- - OSS 034M - - This apparently comes from a dump with the wrong bank order... - investigate whether we should remove it! + OSS 043M -------------------------------------------------*/ -READ8_MEMBER(a800_rom_oss34_device::read_80xx) +a800_rom_oss043m_device::a800_rom_oss043m_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_device(mconfig, type, tag, owner, clock) + , m_bankdev(*this, "bankdev") + , m_bank_base1(0) + , m_bank_base2(0) { - if (offset >= 0x1000) - return m_rom[(offset & 0xfff) + 0x3000]; - else if (m_bank == 3) - return 0xff; - else - return m_rom[(offset & 0xfff) + (m_bank * 0x1000)]; } -WRITE8_MEMBER(a800_rom_oss34_device::write_d5xx) +a800_rom_oss043m_device::a800_rom_oss043m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_oss043m_device(mconfig, A800_ROM_OSS43, tag, owner, clock) { - switch (offset & 0x0f) - { - case 0: - case 1: - m_bank = 0; - break; - case 2: - case 6: - m_bank = 3; // in this case the ROM gets disabled and 0xff is returned in 0xa000-0xafff - break; - case 3: - case 7: - m_bank = 1; - break; - case 4: - case 5: - m_bank = 2; - break; - default: - break; - } } +void a800_rom_oss043m_device::device_add_mconfig(machine_config &config) +{ + ADDRESS_MAP_BANK(config, m_bankdev).set_map(&a800_rom_oss043m_device::bankdev_map).set_options(ENDIANNESS_LITTLE, 8, 12 + 3, 0x1000); +} -/*------------------------------------------------- +void a800_rom_oss043m_device::device_start() +{ + m_bank_base1 = 0x2000; + m_bank_base2 = 0x1000; +} - OSS 043M +void a800_rom_oss043m_device::device_reset() +{ + m_bankdev->set_bank(0); - Same as above but with correct bank order + rd4_w(0); + rd5_w(1); +} - -------------------------------------------------*/ +void a800_rom_oss043m_device::bankdev_map(address_map &map) +{ + map(0x0000, 0x0fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & 0x0fff]; }) + ); + map(0x1000, 0x1fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & 0x0fff] & m_rom[(offset & 0x0fff) | m_bank_base1]; }) + ); + map(0x2000, 0x2fff).mirror(0x4000).lr8( + NAME([]() { return 0xff; }) + ); + map(0x3000, 0x3fff).mirror(0x4000).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank_base1]; }) + ); + map(0x4000, 0x4fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank_base2]; }) + ); + map(0x5000, 0x5fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | m_bank_base1] & m_rom[(offset & 0x0fff) | m_bank_base2]; }) + ); +} -READ8_MEMBER(a800_rom_oss43_device::read_80xx) +void a800_rom_oss043m_device::cart_map(address_map &map) { - if (offset >= 0x1000) - return m_rom[(offset & 0xfff) + 0x3000]; - else if (m_bank == 3) - return 0xff; - else - return m_rom[(offset & 0xfff) + (m_bank * 0x1000)]; + map(0x2000, 0x2fff).m(m_bankdev, FUNC(address_map_bank_device::amap8)); + map(0x3000, 0x3fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x0fff) | 0x3000]; }) + ); } -WRITE8_MEMBER(a800_rom_oss43_device::write_d5xx) +void a800_rom_oss043m_device::cctl_map(address_map &map) { - switch (offset & 0x0f) - { - case 0: - case 1: - m_bank = 0; - break; - case 2: - case 6: - m_bank = 3; // in this case the ROM gets disabled and 0xff is returned in 0xa000-0xafff - break; - case 3: - case 7: - m_bank = 2; - break; - case 4: - case 5: - m_bank = 1; - break; - default: - break; - } + map(0x00, 0xff).rw(FUNC(a800_rom_oss043m_device::rom_bank_r), FUNC(a800_rom_oss043m_device::rom_bank_w)); } +/* + * 0000 bank 0 + * 0001 returns AND-ed contents of banks 0 & 2 + * 0x10 returns 0xff to window (i.e. RD5 is still asserted) + * 0x11 bank 2 + * 0100 bank 1 + * 0101 returns AND-ed contents of banks 1 & 2 + * 1000 RD5 clear + */ +inline void a800_rom_oss043m_device::bank_config_access(offs_t offset) +{ + rd5_w(!(BIT(offset, 3))); + m_bankdev->set_bank(offset & 7); +} -/*------------------------------------------------- +u8 a800_rom_oss043m_device::rom_bank_r(offs_t offset) +{ + if (!machine().side_effects_disabled()) + bank_config_access(offset); + return 0xff; +} - OSS M091 +void a800_rom_oss043m_device::rom_bank_w(offs_t offset, u8 data) +{ + bank_config_access(offset); +} - Simplified banking system which only uses two - address lines (A0 & A3) +/*------------------------------------------------- + + OSS 034M (fake) -------------------------------------------------*/ -READ8_MEMBER(a800_rom_oss91_device::read_80xx) +a800_rom_oss034m_device::a800_rom_oss034m_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_oss043m_device(mconfig, A800_ROM_OSS34, tag, owner, clock) { - if (offset >= 0x1000) - return m_rom[offset & 0xfff]; - else - return m_rom[(offset & 0xfff) + (m_bank * 0x1000)]; } -WRITE8_MEMBER(a800_rom_oss91_device::write_d5xx) +void a800_rom_oss034m_device::device_start() { - switch (offset & 0x09) - { - case 0: - m_bank = 1; - break; - case 1: - m_bank = 3; - break; - case 9: - m_bank = 2; - break; - default: - break; - } + a800_rom_oss043m_device::device_start(); + m_bank_base1 = 0x1000; + m_bank_base2 = 0x2000; } |