diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 1e515009c4d..9f141d72234 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -1894,6 +1894,8 @@ files { MAME_DIR .. "src/mame/video/fmtowns.cpp", MAME_DIR .. "src/mame/machine/fm_scsi.cpp", MAME_DIR .. "src/mame/machine/fm_scsi.h", + MAME_DIR .. "src/mame/machine/fmt_icmem.cpp", + MAME_DIR .. "src/mame/machine/fmt_icmem.h", MAME_DIR .. "src/mame/drivers/fm7.cpp", MAME_DIR .. "src/mame/includes/fm7.h", MAME_DIR .. "src/mame/video/fm7.cpp", diff --git a/src/mame/drivers/fmtowns.cpp b/src/mame/drivers/fmtowns.cpp index 425169915c3..e434afa7888 100644 --- a/src/mame/drivers/fmtowns.cpp +++ b/src/mame/drivers/fmtowns.cpp @@ -181,6 +181,7 @@ Notes: #include "bus/scsi/scsihd.h" #include "softlist.h" + // CD controller IRQ types #define TOWNS_CD_IRQ_MPU 1 #define TOWNS_CD_IRQ_DMA 2 @@ -2143,8 +2144,8 @@ static ADDRESS_MAP_START(towns_mem, AS_PROGRAM, 32, towns_state) // AM_RANGE(0x00100000, 0x005fffff) AM_RAM // some extra RAM AM_RANGE(0x80000000, 0x8007ffff) AM_READWRITE8(towns_gfx_high_r,towns_gfx_high_w,0xffffffff) AM_MIRROR(0x180000) // VRAM AM_RANGE(0x81000000, 0x8101ffff) AM_READWRITE8(towns_spriteram_r,towns_spriteram_w,0xffffffff) // Sprite RAM - // 0xc0000000 - 0xc0ffffff // IC Memory Card (static, first 16MB only) - // 0xc1000000 - 0xc1ffffff // IC Memory Card (banked, can show any of 4 banks), JEIDA v4 only (UX and later) + AM_RANGE(0xc0000000, 0xc0ffffff) AM_DEVREADWRITE8("icmemcard", fmt_icmem_device, static_mem_read, static_mem_write, 0xffffffff) + AM_RANGE(0xc1000000, 0xc1ffffff) AM_DEVREADWRITE8("icmemcard", fmt_icmem_device, mem_read, mem_write, 0xffffffff) AM_RANGE(0xc2000000, 0xc207ffff) AM_ROM AM_REGION("user",0x000000) // OS ROM AM_RANGE(0xc2080000, 0xc20fffff) AM_ROM AM_REGION("user",0x100000) // DIC ROM AM_RANGE(0xc2100000, 0xc213ffff) AM_ROM AM_REGION("user",0x180000) // FONT ROM @@ -2172,7 +2173,7 @@ static ADDRESS_MAP_START(marty_mem, AS_PROGRAM, 16, towns_state) AM_RANGE(0x00a00000, 0x00a7ffff) AM_READWRITE8(towns_gfx_high_r,towns_gfx_high_w,0xffff) AM_MIRROR(0x180000) // VRAM AM_RANGE(0x00b00000, 0x00b7ffff) AM_ROM AM_REGION("user",0x180000) // FONT AM_RANGE(0x00c00000, 0x00c1ffff) AM_READWRITE8(towns_spriteram_r,towns_spriteram_w,0xffff) // Sprite RAM - AM_RANGE(0x00d00000, 0x00dfffff) AM_RAM // IC Memory Card (is this usable on the Marty?) + AM_RANGE(0x00d00000, 0x00dfffff) AM_DEVREADWRITE8("icmemcard", fmt_icmem_device, mem_read, mem_write, 0xffff) AM_RANGE(0x00e80000, 0x00efffff) AM_ROM AM_REGION("user",0x100000) // DIC ROM AM_RANGE(0x00f00000, 0x00f7ffff) AM_ROM AM_REGION("user",0x180000) // FONT AM_RANGE(0x00f80000, 0x00f8ffff) AM_DEVREADWRITE8("pcm", rf5c68_device, rf5c68_mem_r, rf5c68_mem_w, 0xffff) // WAVE RAM @@ -2195,7 +2196,7 @@ static ADDRESS_MAP_START(ux_mem, AS_PROGRAM, 16, towns_state) AM_RANGE(0x00a00000, 0x00a7ffff) AM_READWRITE8(towns_gfx_high_r,towns_gfx_high_w,0xffff) AM_MIRROR(0x180000) // VRAM AM_RANGE(0x00b00000, 0x00b7ffff) AM_ROM AM_REGION("user",0x180000) // FONT AM_RANGE(0x00c00000, 0x00c1ffff) AM_READWRITE8(towns_spriteram_r,towns_spriteram_w,0xffff) // Sprite RAM - AM_RANGE(0x00d00000, 0x00dfffff) AM_RAM // IC Memory Card + AM_RANGE(0x00d00000, 0x00dfffff) AM_DEVREADWRITE8("icmemcard", fmt_icmem_device, mem_read, mem_write, 0xffff) AM_RANGE(0x00e00000, 0x00e7ffff) AM_ROM AM_REGION("user",0x000000) // OS AM_RANGE(0x00e80000, 0x00efffff) AM_ROM AM_REGION("user",0x100000) // DIC ROM AM_RANGE(0x00f00000, 0x00f7ffff) AM_ROM AM_REGION("user",0x180000) // FONT @@ -2229,6 +2230,9 @@ static ADDRESS_MAP_START( towns_io , AS_IO, 32, towns_state) AM_RANGE(0x0440,0x045f) AM_READWRITE8(towns_video_440_r, towns_video_440_w, 0xffffffff) // System port AM_RANGE(0x0480,0x0483) AM_READWRITE8(towns_sys480_r,towns_sys480_w,0x000000ff) // R/W (0x480) + // IC Memory Card + AM_RANGE(0x0488,0x048b) AM_DEVREAD8("icmemcard",fmt_icmem_device,status_r,0x00ff0000) + AM_RANGE(0x0490,0x0493) AM_DEVREADWRITE8("icmemcard",fmt_icmem_device,bank_r,bank_w,0x0000ffff) // CD-ROM AM_RANGE(0x04c0,0x04cf) AM_READWRITE8(towns_cdrom_r,towns_cdrom_w,0x00ff00ff) // Joystick / Mouse ports @@ -2281,6 +2285,9 @@ static ADDRESS_MAP_START( towns16_io , AS_IO, 16, towns_state) // for the 386SX AM_RANGE(0x0440,0x045f) AM_READWRITE8(towns_video_440_r, towns_video_440_w, 0xffff) // System port AM_RANGE(0x0480,0x0481) AM_READWRITE8(towns_sys480_r,towns_sys480_w,0x00ff) // R/W (0x480) + // IC Memory Card + AM_RANGE(0x048a,0x048b) AM_DEVREAD8("icmemcard",fmt_icmem_device,status_r,0x00ff) + AM_RANGE(0x0490,0x0491) AM_DEVREADWRITE8("icmemcard",fmt_icmem_device,bank_r,bank_w,0xffff) // CD-ROM AM_RANGE(0x04c0,0x04cf) AM_READWRITE8(towns_cdrom_r,towns_cdrom_w,0x00ff) // Joystick / Mouse ports @@ -2322,7 +2329,7 @@ static INPUT_PORTS_START( towns ) PORT_CONFSETTING(0x20, "Mouse") PORT_CONFSETTING(0x40, "6-button joystick") -// Keyboard + // Keyboard PORT_START( "key1" ) // scancodes 0x00-0x1f PORT_BIT(0x00000001,IP_ACTIVE_HIGH,IPT_UNUSED) PORT_BIT(0x00000002,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") PORT_CODE(KEYCODE_TILDE) PORT_CHAR(27) @@ -2768,6 +2775,8 @@ static MACHINE_CONFIG_FRAGMENT( towns_base ) //MCFG_VIDEO_START_OVERRIDE(towns_state,towns) + MCFG_FMT_ICMEMCARD_ADD("icmemcard") + /* internal ram */ MCFG_RAM_ADD(RAM_TAG) MCFG_RAM_DEFAULT_SIZE("6M") diff --git a/src/mame/includes/fmtowns.h b/src/mame/includes/fmtowns.h index b973b9655e0..e761dc2c4ee 100644 --- a/src/mame/includes/fmtowns.h +++ b/src/mame/includes/fmtowns.h @@ -20,6 +20,9 @@ #include "machine/ram.h" #include "machine/nvram.h" #include "machine/fm_scsi.h" +#include "bus/generic/slot.h" +#include "bus/generic/carts.h" +#include "machine/fmt_icmem.h" #define IRQ_LOG 0 // set to 1 to log IRQ line activity @@ -92,6 +95,7 @@ class towns_state : public driver_device m_fdc(*this, "fdc"), m_flop0(*this, "fdc:0"), m_flop1(*this, "fdc:1"), + m_icmemcard(*this, "icmemcard"), m_nvram(*this, "nvram"), m_nvram16(*this, "nvram16"), m_ctrltype(*this, "ctrltype"), @@ -124,6 +128,7 @@ class towns_state : public driver_device required_device m_fdc; required_device m_flop0; required_device m_flop1; + required_device m_icmemcard; ram_device* m_messram; cdrom_image_device* m_cdrom; cdda_device* m_cdda; diff --git a/src/mame/machine/fmt_icmem.cpp b/src/mame/machine/fmt_icmem.cpp new file mode 100644 index 00000000000..da2679a211e --- /dev/null +++ b/src/mame/machine/fmt_icmem.cpp @@ -0,0 +1,184 @@ +// 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 +const device_type FMT_ICMEM = &device_creator; + +//------------------------------------------------- +// 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, "FM Towns IC Memory Card", tag, owner, clock, "fmt_icmem", __FILE__), + 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_config_complete - perform any +// operations now that the configuration is +// complete +//------------------------------------------------- + +void fmt_icmem_device::device_config_complete() +{ + // set brief and instance name + update_names(); +} + + +//------------------------------------------------- +// 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; + } +} + diff --git a/src/mame/machine/fmt_icmem.h b/src/mame/machine/fmt_icmem.h new file mode 100644 index 00000000000..d9eb85cbd30 --- /dev/null +++ b/src/mame/machine/fmt_icmem.h @@ -0,0 +1,77 @@ +// license:BSD-3-Clause +// copyright-holders:Barry Rodewald +/********************************************************************* + + fmt_icmem.h + + FM Towns IC Memory Card + +*********************************************************************/ + +#pragma once + +#ifndef __FMT_ICMEM_H__ +#define __FMT_ICMEM_H__ + +//************************************************************************** +// INTERFACE CONFIGURATION MACROS +//************************************************************************** + +#define MCFG_FMT_ICMEMCARD_ADD(_tag) \ + MCFG_DEVICE_ADD(_tag, FMT_ICMEM, 0) + +/*************************************************************************** + FUNCTION PROTOTYPES +***************************************************************************/ + +class fmt_icmem_device : public device_t, + public device_image_interface +{ +public: + // construction/destruction + fmt_icmem_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + virtual iodevice_t image_type() const override { return IO_MEMCARD; } + + virtual bool is_readable() const override { return true; } + virtual bool is_writeable() const override { return true; } + virtual bool is_creatable() const override { return true; } + virtual bool must_be_loaded() const override { return false; } + virtual bool is_reset_on_load() const override { return false; } + virtual const char *file_extensions() const override { return "icm"; } + + virtual image_init_result call_load() override; + virtual void call_unload() override; + virtual image_init_result call_create(int format_type, util::option_resolution *format_options) override; + + // device-level overrides + virtual void device_start() override; + virtual void device_config_complete() override; + + DECLARE_READ8_MEMBER(static_mem_read); + DECLARE_WRITE8_MEMBER(static_mem_write); + DECLARE_READ8_MEMBER(mem_read); + DECLARE_WRITE8_MEMBER(mem_write); + DECLARE_READ8_MEMBER(status_r); + DECLARE_READ8_MEMBER(bank_r); + DECLARE_WRITE8_MEMBER(bank_w); + + +protected: + virtual ioport_constructor device_input_ports() const override; + +private: + required_ioport m_writeprotect; + std::unique_ptr m_memcard_ram; + bool m_change; + bool m_attr_select; + uint8_t m_detect; + uint8_t m_bank; +}; + + +// device type definition +extern const device_type FMT_ICMEM; + + +#endif /* __FMT_ICMEM_H__ */