// license:BSD-3-Clause // copyright-holders:Barry Rodewald /********************************************************************* fmt_icmem.cpp FM Towns IC Memory Card PCMCIA SRAM Memory Cards, up to 64MB supported *********************************************************************/ #include "emu.h" #include "emuopts.h" #include "fmt_icmem.h" // device type definition DEFINE_DEVICE_TYPE(FMT_ICMEM, fmt_icmem_device, "fmt_icmem", "FM Towns IC Memory Card") //------------------------------------------------- // fmt_icmem_device - constructor //------------------------------------------------- fmt_icmem_device::fmt_icmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : device_t(mconfig, FMT_ICMEM, tag, owner, clock), device_image_interface(mconfig, *this), m_writeprotect(*this,"icmem"), m_change(false), m_attr_select(false), m_detect(false), m_bank(0) { } static INPUT_PORTS_START( fmt_icmem ) PORT_START("icmem") PORT_CONFNAME(0x01, 0x00, "IC Memory Card Write Protect") PORT_CONFSETTING(0x00, DEF_STR( Off )) PORT_CONFSETTING(0x01, DEF_STR( On )) INPUT_PORTS_END //------------------------------------------------- // device_start - device-specific startup //------------------------------------------------- void fmt_icmem_device::device_start() { m_memcard_ram = std::make_unique(0x1000000); m_bank = 0; m_detect = false; m_change = false; save_item(NAME(m_change)); save_item(NAME(m_detect)); save_item(NAME(m_bank)); } ioport_constructor fmt_icmem_device::device_input_ports() const { return INPUT_PORTS_NAME(fmt_icmem); } image_init_result fmt_icmem_device::call_load() { memset(m_memcard_ram.get(), 0xff, 0x1000000); fseek(0, SEEK_SET); size_t ret = fread(m_memcard_ram.get(), 0x1000000); if(ret != length()) return image_init_result::FAIL; m_change = true; m_detect = true; return image_init_result::PASS; } void fmt_icmem_device::call_unload() { fseek(0, SEEK_SET); if(!m_writeprotect->read()) fwrite(m_memcard_ram.get(), 0x1000000); m_change = true; m_detect = false; } image_init_result fmt_icmem_device::call_create(int format_type, util::option_resolution *format_options) { memset(m_memcard_ram.get(), 0xff, 0x1000000); size_t ret = fwrite(m_memcard_ram.get(), 0x1000000); if(ret != 0x1000000) return image_init_result::FAIL; m_change = true; m_detect = true; return image_init_result::PASS; } READ8_MEMBER(fmt_icmem_device::static_mem_read) { return m_memcard_ram[offset]; } WRITE8_MEMBER(fmt_icmem_device::static_mem_write) { m_memcard_ram[offset] = data; } READ8_MEMBER(fmt_icmem_device::mem_read) { return m_memcard_ram[(m_bank*0x100000) + offset]; } WRITE8_MEMBER(fmt_icmem_device::mem_write) { m_memcard_ram[(m_bank*0x100000) + offset] = data; } // Memory Card status: // bit 0 - 0 = Write Enable, 1 = Write Protect // bit 1,2 - Card Detect - 00 = Card Inserted, 11 = No card inserted, 10 or 01 = Card error? // bit 3,4,5 - not memory card related (EEPROM and backup battery level) // bit 6 - unknown // bit 7 - 1 = card changed, flips back to 0 when read READ8_MEMBER(fmt_icmem_device::status_r) { uint8_t ret = 0x00; ret |= (m_writeprotect->read() & 0x01); if(is_readonly()) // if image is read-only, then set write protect. ret |= 0x01; if(!m_detect) ret |= 0x06; if(m_change) ret |= 0x80; m_change = false; return ret; } // Memory Card bank select (0x490) // bit 0-5: bank select (bits 0-3 not used in non-386SX systems?) // Attribute/Common memory select (0x491) // bit 0: 0 = common memory, 1 = attribute memory (TODO) // bit 7: 0 indicates that card is JEIDA v4 compliant READ8_MEMBER(fmt_icmem_device::bank_r) { switch(offset) { case 0: return m_bank & 0x0f; case 1: return m_attr_select ? 1 : 0; } return 0xff; } WRITE8_MEMBER(fmt_icmem_device::bank_w) { switch(offset) { case 0: m_bank = data & 0x0f; break; case 1: m_attr_select = data & 0x01; break; } }