fmtowns: add support for IC Memory Card images. Limited to 16MB in size for now, until I can find software that supports more.

This commit is contained in:
mahlemiut 2016-11-25 11:50:24 +13:00
parent cb23c81933
commit 0d13c7115e
5 changed files with 282 additions and 5 deletions

View File

@ -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",

View File

@ -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")

View File

@ -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<mb8877_t> m_fdc;
required_device<floppy_connector> m_flop0;
required_device<floppy_connector> m_flop1;
required_device<fmt_icmem_device> m_icmemcard;
ram_device* m_messram;
cdrom_image_device* m_cdrom;
cdda_device* m_cdda;

View File

@ -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>;
//-------------------------------------------------
// 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<uint8_t[]>(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;
}
}

View File

@ -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<uint8_t[]> 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__ */