diff options
Diffstat (limited to 'src/devices/bus/a800/rom.cpp')
-rw-r--r-- | src/devices/bus/a800/rom.cpp | 415 |
1 files changed, 87 insertions, 328 deletions
diff --git a/src/devices/bus/a800/rom.cpp b/src/devices/bus/a800/rom.cpp index f33c8776d52..c8a3131f206 100644 --- a/src/devices/bus/a800/rom.cpp +++ b/src/devices/bus/a800/rom.cpp @@ -1,33 +1,25 @@ // license:BSD-3-Clause -// copyright-holders:Fabio Priuli -/*********************************************************************************************************** +// copyright-holders:Fabio Priuli, Angelo Salese +/************************************************************************************************** - A800/A5200/XEGS ROM cart emulation - - Basic carts work the same (in addition of being mostly compatible) for all these systems - and thus we deal with them in a single file - -***********************************************************************************************************/ + A800/A5200/XEGS ROM base cart emulation +**************************************************************************************************/ #include "emu.h" #include "rom.h" - //------------------------------------------------- // constructor //------------------------------------------------- -DEFINE_DEVICE_TYPE(A800_ROM, a800_rom_device, "a800_rom", "Atari 800 ROM Carts") -DEFINE_DEVICE_TYPE(A800_ROM_BBSB, a800_rom_bbsb_device, "a800_bbsb", "Atari 800 ROM Carts BBSB") -DEFINE_DEVICE_TYPE(A800_ROM_WILLIAMS, a800_rom_williams_device, "a800_williams", "Atari 800 64K ROM Carts Williams") -DEFINE_DEVICE_TYPE(A800_ROM_EXPRESS, a800_rom_express_device, "a800_express", "Atari 800 64K ROM Carts Express/Diamond") -DEFINE_DEVICE_TYPE(A800_ROM_TURBO, a800_rom_turbo_device, "a800_turbo", "Atari 800 64K ROM Carts Turbosoft") -DEFINE_DEVICE_TYPE(A800_ROM_TELELINK2, a800_rom_telelink2_device, "a800_tlink2", "Atari 800 64K ROM Cart Telelink II") -DEFINE_DEVICE_TYPE(A800_ROM_MICROCALC, a800_rom_microcalc_device, "a800_sitsa", "Atari 800 64K ROM Carts SITSA MicroCalc") -DEFINE_DEVICE_TYPE(XEGS_ROM, xegs_rom_device, "a800_xegs", "Atari XEGS 64K ROM Carts") -DEFINE_DEVICE_TYPE(A5200_ROM_2CHIPS, a5200_rom_2chips_device, "a5200_16k2c", "Atari 5200 ROM Cart 16K in 2 Chips") -DEFINE_DEVICE_TYPE(A5200_ROM_BBSB, a5200_rom_bbsb_device, "a5200_bbsb", "Atari 5200 ROM Cart BBSB") +DEFINE_DEVICE_TYPE(A800_ROM, a800_rom_device, "a800_rom", "Atari 8-bit ROM cart") +DEFINE_DEVICE_TYPE(A800_ROM_16KB, a800_rom_16kb_device, "a800_rom_16kb", "Atari 8-bit ROM 16kb cart") +DEFINE_DEVICE_TYPE(A800_ROM_RIGHT, a800_rom_right_device, "a800_rom_right","Atari 8-bit ROM Right cart") +DEFINE_DEVICE_TYPE(XEGS_ROM, xegs_rom_device, "a800_xegs", "Atari XEGS 64K cart") + +DEFINE_DEVICE_TYPE(A5200_ROM, a5200_rom_device, "a5200_rom", "Atari 5200 ROM cart") +DEFINE_DEVICE_TYPE(A5200_ROM_2CHIPS, a5200_rom_2chips_device, "a5200_16k2c", "Atari 5200 ROM cart 16K in 2 Chips") a800_rom_device::a800_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) @@ -36,74 +28,17 @@ a800_rom_device::a800_rom_device(const machine_config &mconfig, device_type type { } -a800_rom_device::a800_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM, tag, owner, clock) -{ -} - - -a800_rom_bbsb_device::a800_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_BBSB, tag, owner, clock) -{ -} - - - -xegs_rom_device::xegs_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, XEGS_ROM, tag, owner, clock) - , m_bank(0) -{ -} - - -a800_rom_williams_device::a800_rom_williams_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_WILLIAMS, tag, owner, clock) - , m_bank(0) -{ -} - - -a800_rom_express_device::a800_rom_express_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_EXPRESS, tag, owner, clock) - , m_bank(0) -{ -} - - -a800_rom_turbo_device::a800_rom_turbo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_TURBO, tag, owner, clock) - , m_bank(0) -{ -} - - -a800_rom_telelink2_device::a800_rom_telelink2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_TELELINK2, tag, owner, clock) -{ -} - - -a800_rom_microcalc_device::a800_rom_microcalc_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A800_ROM_MICROCALC, tag, owner, clock) - , m_bank(0) -{ -} - +/*------------------------------------------------- -a5200_rom_2chips_device::a5200_rom_2chips_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A5200_ROM_2CHIPS, tag, owner, clock) -{ -} + Generic left cart 8kb + -------------------------------------------------*/ -a5200_rom_bbsb_device::a5200_rom_bbsb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) - : a800_rom_device(mconfig, A5200_ROM_BBSB, tag, owner, clock) +a800_rom_device::a800_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_device(mconfig, A800_ROM, tag, owner, clock) { } - - - void a800_rom_device::device_start() { } @@ -112,291 +47,143 @@ void a800_rom_device::device_reset() { } - -void a800_rom_bbsb_device::device_start() -{ - save_item(NAME(m_banks)); -} - -void a800_rom_bbsb_device::device_reset() -{ - m_banks[0] = 0; - m_banks[1] = 0; -} - - -void xegs_rom_device::device_start() -{ - save_item(NAME(m_bank)); -} - -void xegs_rom_device::device_reset() -{ - m_bank = 0; -} - - -void a800_rom_williams_device::device_start() -{ - save_item(NAME(m_bank)); -} - -void a800_rom_williams_device::device_reset() -{ - m_bank = 0; -} - - -void a800_rom_express_device::device_start() -{ - save_item(NAME(m_bank)); -} - -void a800_rom_express_device::device_reset() -{ - m_bank = 0; -} - - -void a800_rom_turbo_device::device_start() +void a800_rom_device::cart_map(address_map &map) { - save_item(NAME(m_bank)); + map(0x2000, 0x3fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & (m_rom_size - 1)]; }) + ); } -void a800_rom_turbo_device::device_reset() -{ - m_bank = 0; -} +/*------------------------------------------------- + Generic right cart 8kb -void a800_rom_microcalc_device::device_start() -{ - save_item(NAME(m_bank)); -} + -------------------------------------------------*/ -void a800_rom_microcalc_device::device_reset() +a800_rom_right_device::a800_rom_right_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_device(mconfig, A800_ROM_RIGHT, tag, owner, clock) { - m_bank = 0; } - -void a5200_rom_bbsb_device::device_start() +void a800_rom_right_device::device_start() { - save_item(NAME(m_banks)); } -void a5200_rom_bbsb_device::device_reset() +void a800_rom_right_device::device_reset() { - m_banks[0] = 0; - m_banks[1] = 0; + rd4_w(1); + rd5_w(0); } - - -/*------------------------------------------------- - mapper specific handlers - -------------------------------------------------*/ - -/*------------------------------------------------- - - Carts with no bankswitch (8K, 16K) - - The cart accessors are mapped in the correct - range at driver start - - -------------------------------------------------*/ - -READ8_MEMBER(a800_rom_device::read_80xx) +void a800_rom_right_device::cart_map(address_map &map) { - return m_rom[offset & (m_rom_size - 1)]; + map(0x0000, 0x1fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & (m_rom_size - 1)]; }) + ); } - - /*------------------------------------------------- - Bounty Bob Strikes Back! cart (40K) - - Area 0xa000-0xbfff always point to last 8K bank - Areas 0x8000-0x8fff and 0x9000-0x9fff are - separate banks of 4K mapped either in the first - 16K chunk or in the second 16K chunk - Bankswitch is controlled by data written in - 0x8000-0x8fff and 0x9000-0x9fff respectively + Generic 16kb RD4 + RD5 cart -------------------------------------------------*/ -READ8_MEMBER(a800_rom_bbsb_device::read_80xx) +a800_rom_16kb_device::a800_rom_16kb_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_device(mconfig, A800_ROM_16KB, tag, owner, clock) { - if (offset < 0x1000) - return m_rom[(offset & 0xfff) + (m_banks[0] * 0x1000) + 0]; - else if (offset < 0x2000) - return m_rom[(offset & 0xfff) + (m_banks[1] * 0x1000) + 0x4000]; - else - return m_rom[(offset & 0x1fff) + 0x8000]; } -WRITE8_MEMBER(a800_rom_bbsb_device::write_80xx) +void a800_rom_16kb_device::device_start() { - uint16_t addr = offset & 0xfff; - if (addr >= 0xff6 && addr <= 0xff9) - m_banks[BIT(offset, 12)] = (addr - 0xff6); } -/*------------------------------------------------- - - XEGS carts (32K, 64K or 128K) - - Bankswitch is controlled by data written in - 0xd500-0xd5ff - - -------------------------------------------------*/ - -READ8_MEMBER(xegs_rom_device::read_80xx) +void a800_rom_16kb_device::device_reset() { - if (offset < 0x2000) - return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; - else - return m_rom[(offset & 0x1fff) + (m_bank_mask * 0x2000)]; // always last 8K bank - + rd_both_w(1); } -WRITE8_MEMBER(xegs_rom_device::write_d5xx) +void a800_rom_16kb_device::cart_map(address_map &map) { - m_bank = data & m_bank_mask; + map(0x0000, 0x3fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & (m_rom_size - 1)]; }) + ); } - /*------------------------------------------------- - Williams 64K - - The rom is accessed in 8K chunks at 0xa000-0xbfff - Bankswitch is controlled by writing to 7 diff - offsets (their location varies with the cart type): - offs 0 points to bank 0, offs 1 points to bank 1, - and so on... the rom can be disabled by writing to - the offsets 0x8-0xf of the same range as the bankswitch + XEGS carts (32K, 64K or 128K) -------------------------------------------------*/ -READ8_MEMBER(a800_rom_williams_device::read_80xx) +xegs_rom_device::xegs_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a800_rom_device(mconfig, XEGS_ROM, tag, owner, clock) + , m_bank(0) { - return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; } -WRITE8_MEMBER(a800_rom_williams_device::write_d5xx) +void xegs_rom_device::device_start() { - m_bank = (offset & 0x07); + save_item(NAME(m_bank)); } -/*------------------------------------------------- - - Express 64K / Diamond 64K carts - - The rom is accessed in 8K chunks at 0xa000-0xbfff - Bankswitch is the same as above, but writes trigger - banks in reverse order: offs 7 points to bank 0, offs 6 - points to bank 1, and so on... the rom can be disabled - by writing to the offsets 0x8-0xf of the same range - as the bankswitch - - -------------------------------------------------*/ - -READ8_MEMBER(a800_rom_express_device::read_80xx) +void xegs_rom_device::device_reset() { - return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; + // TODO: random + m_bank = 0; } -WRITE8_MEMBER(a800_rom_express_device::write_d5xx) +// RD5 always maps to the last bank +void xegs_rom_device::cart_map(address_map &map) { - m_bank = (offset ^ 0x07) & 0x0f; + map(0x0000, 0x1fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; }) + ); + map(0x2000, 0x3fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + (m_bank_mask * 0x2000)]; }) + ); } - -/*------------------------------------------------- - - Turbosoft 64K / 128K - - - -------------------------------------------------*/ - -READ8_MEMBER(a800_rom_turbo_device::read_80xx) +void xegs_rom_device::cctl_map(address_map &map) { - return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; + map(0x00, 0xff).lw8( + NAME([this](offs_t offset, u8 data) { m_bank = data & m_bank_mask; }) + ); } -WRITE8_MEMBER(a800_rom_turbo_device::write_d5xx) -{ - m_bank = offset & m_bank_mask; -} + +// Atari 5200 /*------------------------------------------------- - Telelink II + Carts with no bankswitch (4K, 8K, 16K, 32K) + Same as base carts above -------------------------------------------------*/ -READ8_MEMBER(a800_rom_telelink2_device::read_80xx) -{ - if (offset >= 0x2000) - return m_rom[offset & 0x1fff]; - if (offset >= 0x1000 && offset < 0x1100) - return m_nvram[offset & 0xff]; - - return 0xff; -} - -WRITE8_MEMBER(a800_rom_telelink2_device::write_80xx) -{ - m_nvram[offset & 0xff] = data | 0xf0; // low 4bits only -} - -READ8_MEMBER(a800_rom_telelink2_device::read_d5xx) +a5200_rom_device::a5200_rom_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_a5200_cart_interface( mconfig, *this ) { - // this should affect NVRAM enable / save - return 0xff; } -WRITE8_MEMBER(a800_rom_telelink2_device::write_d5xx) +a5200_rom_device::a5200_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a5200_rom_device(mconfig, A5200_ROM, tag, owner, clock) { - // this should affect NVRAM enable / save } - - -/*------------------------------------------------- - - SITSA Microcalc - - - -------------------------------------------------*/ - -READ8_MEMBER(a800_rom_microcalc_device::read_80xx) +void a5200_rom_device::cart_map(address_map &map) { - return m_rom[(offset & 0x1fff) + (m_bank * 0x2000)]; + map(0x0000, 0x7fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & (m_rom_size - 1))]; }) + ); } -WRITE8_MEMBER(a800_rom_microcalc_device::write_d5xx) +void a5200_rom_device::device_start() { - m_bank = data; } - - -// Atari 5200 - - -/*------------------------------------------------- - - Carts with no bankswitch (4K, 8K, 16K, 32K) - - Same as base carts above - - -------------------------------------------------*/ - /*------------------------------------------------- Carts with 2x8K (16K) with A13 line not connected @@ -407,45 +194,17 @@ WRITE8_MEMBER(a800_rom_microcalc_device::write_d5xx) -------------------------------------------------*/ -READ8_MEMBER(a5200_rom_2chips_device::read_80xx) -{ - if (offset < 0x4000) - return m_rom[offset & 0x1fff]; - else - return m_rom[(offset & 0x1fff) + 0x2000]; -} - - -/*------------------------------------------------- - - Bounty Bob Strikes Back! cart (40K) - - Similar to the A800 version, but: - Area 0x8000-0xbfff always point to last 8K bank - (repeated twice) - Areas 0x4000-0x4fff and 0x5000-0x5fff are - separate banks of 4K mapped either in the first - 16K chunk or in the second 16K chunk - Bankswitch is controlled by data written in - 0x4000-0x4fff and 0x5000-0x5fff respectively - - -------------------------------------------------*/ - -READ8_MEMBER(a5200_rom_bbsb_device::read_80xx) +a5200_rom_2chips_device::a5200_rom_2chips_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : a5200_rom_device(mconfig, A5200_ROM_2CHIPS, tag, owner, clock) { - if (offset < 0x1000) - return m_rom[(offset & 0xfff) + (m_banks[0] * 0x1000) + 0]; - else if (offset < 0x2000) - return m_rom[(offset & 0xfff) + (m_banks[1] * 0x1000) + 0x4000]; - else if (offset >= 0x4000) - return m_rom[(offset & 0x1fff) + 0x8000]; - else - return 0; } -WRITE8_MEMBER(a5200_rom_bbsb_device::write_80xx) +void a5200_rom_2chips_device::cart_map(address_map &map) { - uint16_t addr = offset & 0xfff; - if (addr >= 0xff6 && addr <= 0xff9) - m_banks[BIT(offset, 12)] = (addr - 0xff6); + map(0x0000, 0x3fff).lr8( + NAME([this](offs_t offset) { return m_rom[offset & 0x1fff]; }) + ); + map(0x4000, 0x7fff).lr8( + NAME([this](offs_t offset) { return m_rom[(offset & 0x1fff) + 0x2000]; }) + ); } |