diff options
Diffstat (limited to 'src/devices/bus/msx_slot/ram_mm.c')
-rw-r--r-- | src/devices/bus/msx_slot/ram_mm.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/devices/bus/msx_slot/ram_mm.c b/src/devices/bus/msx_slot/ram_mm.c new file mode 100644 index 00000000000..4d70fff80bc --- /dev/null +++ b/src/devices/bus/msx_slot/ram_mm.c @@ -0,0 +1,80 @@ +// license:BSD-3-Clause +// copyright-holders:Wilbert Pol +#include "emu.h" +#include "ram_mm.h" + +const device_type MSX_SLOT_RAM_MM = &device_creator<msx_slot_ram_mm_device>; + +msx_slot_ram_mm_device::msx_slot_ram_mm_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) + : device_t(mconfig, MSX_SLOT_RAM_MM, "MSX Internal Memory Mapped RAM", tag, owner, clock, "msx_slot_ram_mm", __FILE__) + , msx_internal_slot_interface() + , m_total_size(0) + , m_bank_mask(0) + , m_ramio_set_bits(0) +{ +} + +void msx_slot_ram_mm_device::device_start() +{ + // Valid mapper sizes are 64KB, 128KB, 256KB, 512KB, 1MB, 2MB, and 4MB */ + switch (m_total_size) + { + case 64*1024: m_bank_mask = 0x03; break; + case 128*1024: m_bank_mask = 0x07; break; + case 256*1024: m_bank_mask = 0x0F; break; + case 512*1024: m_bank_mask = 0x1F; break; + case 1024*1024: m_bank_mask = 0x3F; break; + case 2048*1024: m_bank_mask = 0x7F; break; + case 4096*1024: m_bank_mask = 0xFF; break; + default: fatalerror("Invalid memory mapper size specified\n"); + } + + m_ram.resize(m_total_size); + + for ( int i = 0; i < 4; i++ ) + { + m_bank_selected[i] = 3 -i; + m_bank_base[i] = &m_ram[0x4000 * m_bank_selected[i]]; + } + + save_item(NAME(m_ram)); + save_item(NAME(m_bank_selected)); + + machine().save().register_postload(save_prepost_delegate(FUNC(msx_slot_ram_mm_device::restore_banks), this)); + + // Install IO read/write handlers + address_space &space = machine().device<cpu_device>("maincpu")->space(AS_IO); + space.install_read_handler(0xFC, 0xFF, read8_delegate(FUNC(msx_slot_ram_mm_device::read_mapper_bank), this)); + space.install_write_handler(0xFC, 0xFF, write8_delegate(FUNC(msx_slot_ram_mm_device::write_mapper_bank), this)); +} + +void msx_slot_ram_mm_device::restore_banks() +{ + for ( int i = 0; i < 3; i++ ) + { + m_bank_base[i] = &m_ram[0x4000 * ( m_bank_selected[i] & m_bank_mask )]; + } +} + +READ8_MEMBER(msx_slot_ram_mm_device::read) +{ + return m_bank_base[offset >> 14][offset & 0x3fff]; +} + +WRITE8_MEMBER(msx_slot_ram_mm_device::write) +{ + m_bank_base[offset >> 14][offset & 0x3fff] = data; +} + +READ8_MEMBER(msx_slot_ram_mm_device::read_mapper_bank) +{ + return m_bank_selected[offset & 3] | m_ramio_set_bits; +} + +WRITE8_MEMBER(msx_slot_ram_mm_device::write_mapper_bank) +{ + offset &= 3; + + m_bank_selected[offset] = data; + m_bank_base[offset] = &m_ram[0x4000 * ( m_bank_selected[offset] & m_bank_mask )]; +} |