diff options
Diffstat (limited to 'src/devices/bus/ti99/peb/samsmem.cpp')
-rw-r--r-- | src/devices/bus/ti99/peb/samsmem.cpp | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/src/devices/bus/ti99/peb/samsmem.cpp b/src/devices/bus/ti99/peb/samsmem.cpp new file mode 100644 index 00000000000..dc4e1694822 --- /dev/null +++ b/src/devices/bus/ti99/peb/samsmem.cpp @@ -0,0 +1,136 @@ +// license:LGPL-2.1+ +// copyright-holders:Michael Zapf +/**************************************************************************** + + TI-99 SuperAMS Memory Expansion Card. Uses a 74LS612 memory mapper. + The card can be equipped with up to 1 MiB of static CMOS memory; it is + not buffered, however. + + SAMS organizes memory in 4 KiB blocks which are mapped into the address + space by a memory mapper. The mapper can be configured via a sequence of + addresses at 4000, 4002, ..., 401e, which correspond to memory locations + 0000-0fff, 1000-1fff, ..., f000-ffff. + + According to a software distribution disk from the South West 99ers group, + the predecessor of this card was the Asgard Expanded Memory System (AEMS). + Although some documentation and software was available for it, it was never + built. Instead, a simpler memory card called the Asgard Memory System (AMS) + was built. The South West 99ers group built a better version of this card + called the Super AMS. Any documentation and software containing a reference + to the AEMS are applicable to either AMS or SAMS. + + Michael Zapf + +*****************************************************************************/ + +#include "emu.h" +#include "samsmem.h" + +#define SAMS_CRU_BASE 0x1e00 + +sams_memory_expansion_device::sams_memory_expansion_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : ti_expansion_card_device(mconfig, TI99_SAMSMEM, tag, owner, clock), + m_ram(*this, RAM_TAG), + m_map_mode(false), m_access_mapper(false) +{ +} + +/* + Memory read. The SAMS card has two address areas: The memory is at locations + 0x2000-0x3fff and 0xa000-0xffff, and the mapper area is at 0x4000-0x401e + (only even addresses). +*/ +READ8Z_MEMBER(sams_memory_expansion_device::readz) +{ + int base; + + if (m_access_mapper && ((offset & 0xe000)==0x4000)) + { + *value = m_mapper[(offset>>1)&0x000f]; + } + + if (((offset & 0xe000)==0x2000) || ((offset & 0xe000)==0xa000) || ((offset & 0xe000)==0xc000) || ((offset & 0xe000)==0xe000)) + { + if (!m_map_mode) + { + // transparent mode + *value = m_ram->pointer()[offset & 0xffff]; + } + else + { + base = (m_mapper[(offset & 0xf000)>>12] << 12); + *value = m_ram->pointer()[base | (offset & 0x0fff)]; + } + } +} + +WRITE8_MEMBER(sams_memory_expansion_device::write) +{ + int base; + + if (m_access_mapper && ((offset & 0xe000)==0x4000)) + { + m_mapper[(offset>>1)&0x000f] = data; + } + + if (((offset & 0xe000)==0x2000) || ((offset & 0xe000)==0xa000) || ((offset & 0xe000)==0xc000) || ((offset & 0xe000)==0xe000)) + { + if (!m_map_mode) + { + // transparent mode + m_ram->pointer()[offset & 0xffff] = data; + } + else + { + base = (m_mapper[(offset & 0xf000)>>12] << 12); + m_ram->pointer()[base | (offset & 0x0fff)] = data; + } + } +} + +/* + CRU read. None here. +*/ +READ8Z_MEMBER(sams_memory_expansion_device::crureadz) +{ +} + +/* + CRU write. Turns on the mapper and allows to change it. +*/ +WRITE8_MEMBER(sams_memory_expansion_device::cruwrite) +{ + if ((offset & 0xff00)==SAMS_CRU_BASE) + { + if ((offset & 0x000e)==0) m_access_mapper = (data!=0); + if ((offset & 0x000e)==2) m_map_mode = (data!=0); + } +} + +MACHINE_CONFIG_FRAGMENT( sams_mem ) + MCFG_RAM_ADD(RAM_TAG) + MCFG_RAM_DEFAULT_SIZE("1M") + MCFG_RAM_DEFAULT_VALUE(0) +MACHINE_CONFIG_END + +machine_config_constructor sams_memory_expansion_device::device_mconfig_additions() const +{ + return MACHINE_CONFIG_NAME( sams_mem ); +} + +void sams_memory_expansion_device::device_start() +{ + save_pointer(NAME(m_mapper),16); + save_item(NAME(m_map_mode)); + save_item(NAME(m_mapper)); +} + +void sams_memory_expansion_device::device_reset() +{ + // Resetting values + m_map_mode = false; + m_access_mapper = false; + for (auto & elem : m_mapper) elem = 0; +} + +DEFINE_DEVICE_TYPE(TI99_SAMSMEM, sams_memory_expansion_device, "ti99_sams", "SuperAMS memory expansion card") |