Moved auto-finding code down into the device_t object so it can be more

broadly used.

Added memory interface to the intelfsh device so you can access/view the
data in the debugger and via the standard memory interfaces. Removed the
old memory() method in favor of new functions read_raw()/write_raw() which
do direct reads/writes of the data.

Cleaned up CPS3 No-CD sets to break up the "ROMs" into individual flash
pieces which are automatically loaded by the intelfsh device on initialization.
Also split the MACHINE_CONFIG to only populate the number of SIMMs actually
present for each game, as documented in the top of the file. And replaced
the NVRAM_HANDLER with an NVRAM device.
This commit is contained in:
Aaron Giles 2010-09-14 09:54:56 +00:00
parent d4a4c81615
commit e22fd1b2c7
8 changed files with 1206 additions and 652 deletions

View File

@ -548,7 +548,8 @@ device_t::device_t(running_machine &_machine, const device_config &config)
m_baseconfig(config), m_baseconfig(config),
m_unscaled_clock(config.m_clock), m_unscaled_clock(config.m_clock),
m_clock_scale(1.0), m_clock_scale(1.0),
m_attoseconds_per_clock((config.m_clock == 0) ? 0 : HZ_TO_ATTOSECONDS(config.m_clock)) m_attoseconds_per_clock((config.m_clock == 0) ? 0 : HZ_TO_ATTOSECONDS(config.m_clock)),
m_auto_finder_list(NULL)
{ {
} }
@ -692,6 +693,10 @@ void device_t::start()
// populate the region field // populate the region field
m_region = m_machine.region(tag()); m_region = m_machine.region(tag());
// find all the registered devices
for (auto_finder_base *autodev = m_auto_finder_list; autodev != NULL; autodev = autodev->m_next)
autodev->findit(*this);
// let the interfaces do their pre-work // let the interfaces do their pre-work
for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next()) for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next())
intf->interface_pre_start(); intf->interface_pre_start();
@ -888,3 +893,72 @@ void device_t::notify_clock_changed()
// then notify the device // then notify the device
device_clock_changed(); device_clock_changed();
} }
//-------------------------------------------------
// register_auto_finder - add a new item to the
// list of stuff to find after we go live
//-------------------------------------------------
void device_t::register_auto_finder(auto_finder_base &autodev)
{
// add to this list
autodev.m_next = m_auto_finder_list;
m_auto_finder_list = &autodev;
}
//-------------------------------------------------
// auto_finder_base - constructor
//-------------------------------------------------
device_t::auto_finder_base::auto_finder_base(device_t &base, const char *tag)
: m_next(NULL),
m_tag(tag)
{
// register ourselves with our device class
base.register_auto_finder(*this);
}
//-------------------------------------------------
// ~auto_finder_base - destructor
//-------------------------------------------------
device_t::auto_finder_base::~auto_finder_base()
{
}
//-------------------------------------------------
// find_device - find a device; done here instead
// of inline in the template due to include
// dependency ordering
//-------------------------------------------------
device_t *device_t::auto_finder_base::find_device(device_t &base, const char *tag)
{
return base.subdevice(tag);
}
//-------------------------------------------------
// find_shared_ptr - find a shared pointer
//-------------------------------------------------
void *device_t::auto_finder_base::find_shared_ptr(device_t &base, const char *tag)
{
return memory_get_shared(*base.machine, tag);
}
//-------------------------------------------------
// find_shared_size - find a shared pointer size
//-------------------------------------------------
size_t device_t::auto_finder_base::find_shared_size(device_t &base, const char *tag)
{
size_t result = 0;
memory_get_shared(*base.machine, tag, result);
return result;
}

View File

@ -485,6 +485,111 @@ protected:
UINT32 m_unscaled_clock; // unscaled clock UINT32 m_unscaled_clock; // unscaled clock
double m_clock_scale; // clock scale factor double m_clock_scale; // clock scale factor
attoseconds_t m_attoseconds_per_clock;// period in attoseconds attoseconds_t m_attoseconds_per_clock;// period in attoseconds
// helper class to request auto-object discovery in the constructor of a derived class
class auto_finder_base
{
public:
// construction/destruction
auto_finder_base(device_t &base, const char *tag);
virtual ~auto_finder_base();
// getters
virtual void findit(device_t &base) = 0;
// helpers
device_t *find_device(device_t &device, const char *tag);
void *find_shared_ptr(device_t &device, const char *tag);
size_t find_shared_size(device_t &device, const char *tag);
// internal state
auto_finder_base *m_next;
const char *m_tag;
};
// templated version bound to a specific type
template<typename _TargetType, bool _Required>
class auto_finder_type : public auto_finder_base
{
public:
// construction/destruction
auto_finder_type(device_t &base, const char *tag)
: auto_finder_base(base, tag),
m_target(0) { }
// operators to make use transparent
operator _TargetType() { return m_target; }
operator _TargetType() const { return m_target; }
_TargetType operator->() { return m_target; }
// setter for setting the object
void set_target(_TargetType target)
{
m_target = target;
if (target == 0 && _Required)
throw emu_fatalerror("Unable to find required object '%s'", this->m_tag);
}
// internal state
_TargetType m_target;
};
// optional device finder
template<class _DeviceClass>
class optional_device : public auto_finder_type<_DeviceClass *, false>
{
public:
optional_device(device_t &base, const char *tag) : auto_finder_type<_DeviceClass *, false>(base, tag) { }
virtual void findit(device_t &base) { set_target(downcast<_DeviceClass *>(find_device(base, this->m_tag))); }
};
// required devices are similar but throw an error if they are not found
template<class _DeviceClass>
class required_device : public auto_finder_type<_DeviceClass *, true>
{
public:
required_device(device_t &base, const char *tag) : auto_finder_type<_DeviceClass *, true>(base, tag) { }
virtual void findit(device_t &base) { set_target(downcast<_DeviceClass *>(find_device(base, this->m_tag))); }
};
// optional shared pointer finder
template<typename _PointerType>
class optional_shared_ptr : public auto_finder_type<_PointerType *, false>
{
public:
optional_shared_ptr(device_t &base, const char *tag) : auto_finder_type<_PointerType *, false>(base, tag) { }
virtual void findit(device_t &base) { set_target(reinterpret_cast<_PointerType *>(find_shared_ptr(base, this->m_tag))); }
};
// required shared pointer finder
template<typename _PointerType>
class required_shared_ptr : public auto_finder_type<_PointerType *, true>
{
public:
required_shared_ptr(device_t &base, const char *tag) : auto_finder_type<_PointerType *, true>(base, tag) { }
virtual void findit(device_t &base) { set_target(reinterpret_cast<_PointerType *>(find_shared_ptr(base, this->m_tag))); }
};
// optional shared pointer size finder
class optional_shared_size : public auto_finder_type<size_t, false>
{
public:
optional_shared_size(device_t &base, const char *tag) : auto_finder_type<size_t, false>(base, tag) { }
virtual void findit(device_t &base) { set_target(find_shared_size(base, this->m_tag)); }
};
// required shared pointer size finder
class required_shared_size : public auto_finder_type<size_t, true>
{
public:
required_shared_size(device_t &base, const char *tag) : auto_finder_type<size_t, true>(base, tag) { }
virtual void findit(device_t &base) { set_target(find_shared_size(base, this->m_tag)); }
};
// internal helpers
void register_auto_finder(auto_finder_base &autodev);
auto_finder_base * m_auto_finder_list;
}; };

View File

@ -1173,10 +1173,6 @@ void driver_device::device_start()
if (next() != NULL) if (next() != NULL)
throw device_missing_dependencies(); throw device_missing_dependencies();
// find all the registered devices
for (auto_finder_base *autodev = m_auto_finder_list; autodev != NULL; autodev = autodev->m_next)
autodev->findit(*this);
// call the game-specific init // call the game-specific init
if (m_config.m_game->driver_init != NULL) if (m_config.m_game->driver_init != NULL)
(*m_config.m_game->driver_init)(&m_machine); (*m_config.m_game->driver_init)(&m_machine);
@ -1211,40 +1207,6 @@ void driver_device::device_reset()
} }
//-------------------------------------------------
// auto_finder_base - constructor
//-------------------------------------------------
void driver_device::register_auto_finder(auto_finder_base &autodev)
{
// add to this list
autodev.m_next = m_auto_finder_list;
m_auto_finder_list = &autodev;
}
//-------------------------------------------------
// auto_finder_base - constructor
//-------------------------------------------------
driver_device::auto_finder_base::auto_finder_base(driver_device &base, const char *tag)
: m_next(NULL),
m_tag(tag)
{
// register ourselves with our device class
base.register_auto_finder(*this);
}
//-------------------------------------------------
// ~auto_finder_base - destructor
//-------------------------------------------------
driver_device::auto_finder_base::~auto_finder_base()
{
}
//************************************************************************** //**************************************************************************
// SYSTEM TIME // SYSTEM TIME

View File

@ -628,107 +628,8 @@ protected:
virtual void device_start(); virtual void device_start();
virtual void device_reset(); virtual void device_reset();
// helper class to request auto-object discovery in the constructor of a derived class
class auto_finder_base
{
public:
// construction/destruction
auto_finder_base(driver_device &base, const char *tag);
virtual ~auto_finder_base();
// getters
virtual void findit(driver_device &base) = 0;
// internal state
auto_finder_base *m_next;
const char *m_tag;
};
// templated version bound to a specific type
template<typename _TargetType, bool _Required>
class auto_finder_type : public auto_finder_base
{
public:
// construction/destruction
auto_finder_type(driver_device &base, const char *tag)
: auto_finder_base(base, tag),
m_target(0) { }
// operators to make use transparent
operator _TargetType() { return m_target; }
operator _TargetType() const { return m_target; }
_TargetType operator->() { return m_target; }
// setter for setting the object
void set_target(_TargetType target)
{
m_target = target;
if (target == 0 && _Required)
throw emu_fatalerror("Unable to find required object '%s'", this->m_tag);
}
// internal state
_TargetType m_target;
};
// optional device finder
template<class _DeviceClass>
class optional_device : public auto_finder_type<_DeviceClass *, false>
{
public:
optional_device(driver_device &base, const char *tag) : auto_finder_type<_DeviceClass *, false>(base, tag) { }
virtual void findit(driver_device &base) { set_target(base.m_machine.device<_DeviceClass>(this->m_tag)); }
};
// required devices are similar but throw an error if they are not found
template<class _DeviceClass>
class required_device : public auto_finder_type<_DeviceClass *, true>
{
public:
required_device(driver_device &base, const char *tag) : auto_finder_type<_DeviceClass *, true>(base, tag) { }
virtual void findit(driver_device &base) { set_target(base.m_machine.device<_DeviceClass>(this->m_tag)); }
};
// optional shared pointer finder
template<typename _PointerType>
class optional_shared_ptr : public auto_finder_type<_PointerType *, false>
{
public:
optional_shared_ptr(driver_device &base, const char *tag) : auto_finder_type<_PointerType *, false>(base, tag) { }
virtual void findit(driver_device &base) { set_target(reinterpret_cast<_PointerType *>(memory_get_shared(base.m_machine, this->m_tag))); }
};
// required shared pointer finder
template<typename _PointerType>
class required_shared_ptr : public auto_finder_type<_PointerType *, true>
{
public:
required_shared_ptr(driver_device &base, const char *tag) : auto_finder_type<_PointerType *, true>(base, tag) { }
virtual void findit(driver_device &base) { set_target(reinterpret_cast<_PointerType *>(memory_get_shared(base.m_machine, this->m_tag))); }
};
// optional shared pointer size finder
class optional_shared_size : public auto_finder_type<size_t, false>
{
public:
optional_shared_size(driver_device &base, const char *tag) : auto_finder_type<size_t, false>(base, tag) { }
virtual void findit(driver_device &base) { size_t size; memory_get_shared(base.m_machine, this->m_tag, size); set_target(size); }
};
// required shared pointer size finder
class required_shared_size : public auto_finder_type<size_t, true>
{
public:
required_shared_size(driver_device &base, const char *tag) : auto_finder_type<size_t, true>(base, tag) { }
virtual void findit(driver_device &base) { size_t size; memory_get_shared(base.m_machine, this->m_tag, size); set_target(size); }
};
// internal helpers
void register_auto_finder(auto_finder_base &autodev);
// internal state // internal state
const driver_device_config_base &m_config; const driver_device_config_base &m_config;
auto_finder_base *m_auto_finder_list;
}; };

View File

@ -74,6 +74,41 @@ const device_type SHARP_UNK128MBIT = sharp_unk128mbit_device_config::static_allo
//**************************************************************************
// GLOBAL VARIABLES
//**************************************************************************
static ADDRESS_MAP_START( memory_map8_512Kb, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x00000, 0x00ffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( memory_map8_1Mb, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x00000, 0x01ffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( memory_map8_8Mb, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x00000, 0x0fffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( memory_map8_16Mb, ADDRESS_SPACE_PROGRAM, 8 )
AM_RANGE(0x00000, 0x1fffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( memory_map16_4Mb, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x00000, 0x07ffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( memory_map16_16Mb, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x00000, 0x1fffff) AM_RAM
ADDRESS_MAP_END
static ADDRESS_MAP_START( memory_map16_64Mb, ADDRESS_SPACE_PROGRAM, 16 )
AM_RANGE(0x00000, 0x7fffff) AM_RAM
ADDRESS_MAP_END
//************************************************************************** //**************************************************************************
// DEVICE CONFIGURATION // DEVICE CONFIGURATION
//************************************************************************** //**************************************************************************
@ -84,9 +119,94 @@ const device_type SHARP_UNK128MBIT = sharp_unk128mbit_device_config::static_allo
intelfsh_device_config::intelfsh_device_config(const machine_config &mconfig, device_type type, const char *name, const char *tag, const device_config *owner, UINT32 clock, UINT32 variant) intelfsh_device_config::intelfsh_device_config(const machine_config &mconfig, device_type type, const char *name, const char *tag, const device_config *owner, UINT32 clock, UINT32 variant)
: device_config(mconfig, type, name, tag, owner, clock), : device_config(mconfig, type, name, tag, owner, clock),
device_config_memory_interface(mconfig, *this),
device_config_nvram_interface(mconfig, *this), device_config_nvram_interface(mconfig, *this),
m_type(variant) m_type(variant),
m_size(0),
m_bits(8),
m_device_id(0),
m_maker_id(0),
m_sector_is_4k(false)
{ {
address_map_constructor map = NULL;
switch( variant )
{
case FLASH_INTEL_28F016S5:
case FLASH_SHARP_LH28F016S:
m_bits = 8;
m_size = 0x200000;
m_maker_id = 0x89;
m_device_id = 0xaa;
map = ADDRESS_MAP_NAME( memory_map8_16Mb );
break;
case FLASH_SHARP_LH28F400:
case FLASH_INTEL_E28F400:
m_bits = 16;
m_size = 0x80000;
m_maker_id = 0xb0;
m_device_id = 0xed;
map = ADDRESS_MAP_NAME( memory_map16_4Mb );
break;
case FLASH_FUJITSU_29F016A:
m_bits = 8;
m_size = 0x200000;
m_maker_id = 0x04;
m_device_id = 0xad;
map = ADDRESS_MAP_NAME( memory_map8_16Mb );
break;
case FLASH_INTEL_E28F008SA:
m_bits = 8;
m_size = 0x100000;
m_maker_id = 0x89;
m_device_id = 0xa2;
map = ADDRESS_MAP_NAME( memory_map8_8Mb );
break;
case FLASH_INTEL_TE28F160:
m_bits = 16;
m_size = 0x200000;
m_maker_id = 0xb0;
m_device_id = 0xd0;
map = ADDRESS_MAP_NAME( memory_map16_16Mb );
break;
case FLASH_SHARP_UNK128MBIT:
m_bits = 16;
m_size = 0x800000;
m_maker_id = 0xb0;
m_device_id = 0xb0;
map = ADDRESS_MAP_NAME( memory_map16_64Mb );
break;
case FLASH_MACRONIX_29L001MC:
m_bits = 8;
m_size = 0x20000;
m_maker_id = 0xc2;
m_device_id = 0x51;
map = ADDRESS_MAP_NAME( memory_map8_1Mb );
break;
case FLASH_PANASONIC_MN63F805MNP:
m_bits = 8;
m_size = 0x10000;
m_maker_id = 0x32;
m_device_id = 0x1b;
m_sector_is_4k = true;
map = ADDRESS_MAP_NAME( memory_map8_512Kb );
break;
case FLASH_SANYO_LE26FV10N1TS:
m_bits = 8;
m_size = 0x20000;
m_maker_id = 0x62;
m_device_id = 0x13;
m_sector_is_4k = true;
map = ADDRESS_MAP_NAME( memory_map8_1Mb );
break;
}
int addrbits;
for (addrbits = 24; addrbits > 0; addrbits--)
if ((m_size & (1 << addrbits)) != 0)
break;
m_space_config = address_space_config("flash", ENDIANNESS_BIG, m_bits, addrbits, 0, map);
} }
intelfsh8_device_config::intelfsh8_device_config(const machine_config &mconfig, device_type type, const char *name, const char *tag, const device_config *owner, UINT32 clock, UINT32 variant) intelfsh8_device_config::intelfsh8_device_config(const machine_config &mconfig, device_type type, const char *name, const char *tag, const device_config *owner, UINT32 clock, UINT32 variant)
@ -100,6 +220,17 @@ intelfsh16_device_config::intelfsh16_device_config(const machine_config &mconfig
} }
//-------------------------------------------------
// memory_space_config - return a description of
// any address spaces owned by this device
//-------------------------------------------------
const address_space_config *intelfsh_device_config::memory_space_config(int spacenum) const
{
return (spacenum == 0) ? &m_space_config : NULL;
}
//************************************************************************** //**************************************************************************
// LIVE DEVICE // LIVE DEVICE
@ -111,84 +242,15 @@ intelfsh16_device_config::intelfsh16_device_config(const machine_config &mconfig
intelfsh_device::intelfsh_device(running_machine &_machine, const intelfsh_device_config &config) intelfsh_device::intelfsh_device(running_machine &_machine, const intelfsh_device_config &config)
: device_t(_machine, config), : device_t(_machine, config),
device_memory_interface(_machine, config, *this),
device_nvram_interface(_machine, config, *this), device_nvram_interface(_machine, config, *this),
m_config(config), m_config(config),
m_size(0),
m_bits(config.m_type >> 8),
m_status(0x80), m_status(0x80),
m_erase_sector(0), m_erase_sector(0),
m_sector_is_4k(false),
m_flash_mode(FM_NORMAL), m_flash_mode(FM_NORMAL),
m_flash_master_lock(false), m_flash_master_lock(false),
m_device_id(0), m_timer(NULL)
m_maker_id(0),
m_timer(NULL),
m_flash_memory(NULL)
{ {
switch( config.m_type )
{
case intelfsh_device_config::FLASH_INTEL_28F016S5:
case intelfsh_device_config::FLASH_SHARP_LH28F016S:
m_bits = 8;
m_size = 0x200000;
m_maker_id = 0x89;
m_device_id = 0xaa;
break;
case intelfsh_device_config::FLASH_SHARP_LH28F400:
case intelfsh_device_config::FLASH_INTEL_E28F400:
m_bits = 16;
m_size = 0x80000;
m_maker_id = 0xb0;
m_device_id = 0xed;
break;
case intelfsh_device_config::FLASH_FUJITSU_29F016A:
m_bits = 8;
m_size = 0x200000;
m_maker_id = 0x04;
m_device_id = 0xad;
break;
case intelfsh_device_config::FLASH_INTEL_E28F008SA:
m_bits = 8;
m_size = 0x100000;
m_maker_id = 0x89;
m_device_id = 0xa2;
break;
case intelfsh_device_config::FLASH_INTEL_TE28F160:
m_bits = 16;
m_size = 0x200000;
m_maker_id = 0xb0;
m_device_id = 0xd0;
break;
case intelfsh_device_config::FLASH_SHARP_UNK128MBIT:
m_bits = 16;
m_size = 0x800000;
m_maker_id = 0xb0;
m_device_id = 0xb0;
break;
case intelfsh_device_config::FLASH_MACRONIX_29L001MC:
m_bits = 8;
m_size = 0x20000;
m_maker_id = 0xc2;
m_device_id = 0x51;
break;
case intelfsh_device_config::FLASH_PANASONIC_MN63F805MNP:
m_bits = 8;
m_size = 0x10000;
m_maker_id = 0x32;
m_device_id = 0x1b;
m_sector_is_4k = true;
break;
case intelfsh_device_config::FLASH_SANYO_LE26FV10N1TS:
m_bits = 8;
m_size = 0x20000;
m_maker_id = 0x62;
m_device_id = 0x13;
m_sector_is_4k = true;
break;
}
m_flash_memory = auto_alloc_array( &m_machine, UINT8, m_size );
} }
intelfsh8_device::intelfsh8_device(running_machine &_machine, const intelfsh_device_config &config) intelfsh8_device::intelfsh8_device(running_machine &_machine, const intelfsh_device_config &config)
@ -209,7 +271,6 @@ void intelfsh_device::device_start()
state_save_register_device_item( this, 0, m_status ); state_save_register_device_item( this, 0, m_status );
state_save_register_device_item( this, 0, m_flash_mode ); state_save_register_device_item( this, 0, m_flash_mode );
state_save_register_device_item( this, 0, m_flash_master_lock ); state_save_register_device_item( this, 0, m_flash_master_lock );
state_save_register_memory( machine, name(), tag(), 0, "m_flash_memory", m_flash_memory, m_bits/8, m_size / (m_bits/8), __FILE__, __LINE__ );
} }
@ -243,13 +304,25 @@ void intelfsh_device::nvram_default()
if (m_region != NULL) if (m_region != NULL)
{ {
UINT32 bytes = m_region->bytes(); UINT32 bytes = m_region->bytes();
if (bytes > m_size) if (bytes > m_config.m_size)
bytes = m_size; bytes = m_config.m_size;
memcpy(m_flash_memory, *m_region, bytes);
if (m_config.m_bits == 8)
{
for (offs_t offs = 0; offs < bytes; offs++)
m_addrspace[0]->write_byte(offs, m_region->u8(offs));
}
else
{
for (offs_t offs = 0; offs < bytes; offs += 2)
m_addrspace[0]->write_word(offs, m_region->u16(offs / 2));
}
return; return;
} }
memset( m_flash_memory, 0xff, m_size ); // otherwise, default to 0xff
for (offs_t offs = 0; offs < m_config.m_size; offs++)
m_addrspace[0]->write_byte(offs, 0xff);
} }
@ -260,7 +333,11 @@ void intelfsh_device::nvram_default()
void intelfsh_device::nvram_read(mame_file &file) void intelfsh_device::nvram_read(mame_file &file)
{ {
mame_fread(&file, m_flash_memory, m_size); UINT8 *buffer = global_alloc_array(UINT8, m_config.m_size);
mame_fread(&file, buffer, m_config.m_size);
for (int byte = 0; byte < m_config.m_size; byte++)
m_addrspace[0]->write_byte(byte, buffer[byte]);
global_free(buffer);
} }
@ -271,7 +348,11 @@ void intelfsh_device::nvram_read(mame_file &file)
void intelfsh_device::nvram_write(mame_file &file) void intelfsh_device::nvram_write(mame_file &file)
{ {
mame_fwrite(&file, m_flash_memory, m_size); UINT8 *buffer = global_alloc_array(UINT8, m_config.m_size);
for (int byte = 0; byte < m_config.m_size; byte++)
buffer[byte] = m_addrspace[0]->read_byte(byte);
mame_fwrite(&file, buffer, m_config.m_size);
global_free(buffer);
} }
@ -287,18 +368,16 @@ UINT32 intelfsh_device::read_full(UINT32 address)
{ {
default: default:
case FM_NORMAL: case FM_NORMAL:
switch( m_bits ) switch( m_config.m_bits )
{ {
case 8: case 8:
{ {
UINT8 *flash_memory = (UINT8 *)m_flash_memory; data = m_addrspace[0]->read_byte(address);
data = flash_memory[ address ];
} }
break; break;
case 16: case 16:
{ {
UINT16 *flash_memory = (UINT16 *)m_flash_memory; data = m_addrspace[0]->read_word(address * 2);
data = flash_memory[ address ];
} }
break; break;
} }
@ -309,8 +388,8 @@ UINT32 intelfsh_device::read_full(UINT32 address)
case FM_READAMDID3: case FM_READAMDID3:
switch (address) switch (address)
{ {
case 0: data = m_maker_id; break; case 0: data = m_config.m_maker_id; break;
case 1: data = m_device_id; break; case 1: data = m_config.m_device_id; break;
case 2: data = 0; break; case 2: data = 0; break;
} }
break; break;
@ -318,10 +397,10 @@ UINT32 intelfsh_device::read_full(UINT32 address)
switch (address) switch (address)
{ {
case 0: // maker ID case 0: // maker ID
data = m_maker_id; data = m_config.m_maker_id;
break; break;
case 1: // chip ID case 1: // chip ID
data = m_device_id; data = m_config.m_device_id;
break; break;
case 2: // block lock config case 2: // block lock config
data = 0; // we don't support this yet data = 0; // we don't support this yet
@ -342,18 +421,16 @@ UINT32 intelfsh_device::read_full(UINT32 address)
// reads outside of the erasing sector return normal data // reads outside of the erasing sector return normal data
if ((address < m_erase_sector) || (address >= m_erase_sector+(64*1024))) if ((address < m_erase_sector) || (address >= m_erase_sector+(64*1024)))
{ {
switch( m_bits ) switch( m_config.m_bits )
{ {
case 8: case 8:
{ {
UINT8 *flash_memory = (UINT8 *)m_flash_memory; data = m_addrspace[0]->read_byte(address);
data = flash_memory[ address ];
} }
break; break;
case 16: case 16:
{ {
UINT16 *flash_memory = (UINT16 *)m_flash_memory; data = m_addrspace[0]->read_word(address * 2);
data = flash_memory[ address ];
} }
break; break;
} }
@ -506,7 +583,8 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
if( ( address & 0xfff ) == 0x555 && ( data & 0xff ) == 0x10 ) if( ( address & 0xfff ) == 0x555 && ( data & 0xff ) == 0x10 )
{ {
// chip erase // chip erase
memset( m_flash_memory, 0xff, m_size); for (offs_t offs = 0; offs < m_config.m_size; offs++)
m_addrspace[0]->write_byte(offs, 0xff);
m_status = 1 << 3; m_status = 1 << 3;
m_flash_mode = FM_ERASEAMD4; m_flash_mode = FM_ERASEAMD4;
@ -517,43 +595,20 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
{ {
// sector erase // sector erase
// clear the 4k/64k block containing the current address to all 0xffs // clear the 4k/64k block containing the current address to all 0xffs
switch( m_bits ) if (m_config.m_sector_is_4k)
{ {
case 8: for (offs_t offs = 0; offs < 4 * 1024; offs++)
{ m_addrspace[0]->write_byte((address & ~0xfff) + offs, 0xff);
UINT8 *flash_memory = (UINT8 *)m_flash_memory;
if (m_sector_is_4k)
{
memset( &flash_memory[ address & ~0xfff ], 0xff, 4 * 1024 );
m_erase_sector = address & ~0xfff; m_erase_sector = address & ~0xfff;
timer_adjust_oneshot( m_timer, ATTOTIME_IN_MSEC( 125 ), 0 ); timer_adjust_oneshot( m_timer, ATTOTIME_IN_MSEC( 125 ), 0 );
} }
else else
{ {
memset( &flash_memory[ address & ~0xffff ], 0xff, 64 * 1024 ); for (offs_t offs = 0; offs < 64 * 1024; offs++)
m_addrspace[0]->write_byte((address & ~0xffff) + offs, 0xff);
m_erase_sector = address & ~0xffff; m_erase_sector = address & ~0xffff;
timer_adjust_oneshot( m_timer, ATTOTIME_IN_SEC( 1 ), 0 ); timer_adjust_oneshot( m_timer, ATTOTIME_IN_SEC( 1 ), 0 );
} }
}
break;
case 16:
{
UINT16 *flash_memory = (UINT16 *)m_flash_memory;
if (m_sector_is_4k)
{
memset( &flash_memory[ address & ~0x7ff ], 0xff, 4 * 1024 );
m_erase_sector = address & ~0x7ff;
timer_adjust_oneshot( m_timer, ATTOTIME_IN_MSEC( 125 ), 0 );
}
else
{
memset( &flash_memory[ address & ~0x7fff ], 0xff, 64 * 1024 );
m_erase_sector = address & ~0x7fff;
timer_adjust_oneshot( m_timer, ATTOTIME_IN_SEC( 1 ), 0 );
}
}
break;
}
m_status = 1 << 3; m_status = 1 << 3;
m_flash_mode = FM_ERASEAMD4; m_flash_mode = FM_ERASEAMD4;
@ -564,37 +619,34 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
} }
break; break;
case FM_BYTEPROGRAM: case FM_BYTEPROGRAM:
switch( m_bits ) switch( m_config.m_bits )
{ {
case 8: case 8:
{ {
UINT8 *flash_memory = (UINT8 *)m_flash_memory; m_addrspace[0]->write_byte(address, data);
flash_memory[ address ] = data;
} }
break; break;
default: default:
logerror( "FM_BYTEPROGRAM not supported when m_bits == %d\n", m_bits ); logerror( "FM_BYTEPROGRAM not supported when m_bits == %d\n", m_config.m_bits );
break; break;
} }
m_flash_mode = FM_NORMAL; m_flash_mode = FM_NORMAL;
break; break;
case FM_WRITEPART1: case FM_WRITEPART1:
switch( m_bits ) switch( m_config.m_bits )
{ {
case 8: case 8:
{ {
UINT8 *flash_memory = (UINT8 *)m_flash_memory; m_addrspace[0]->write_byte(address, data);
flash_memory[ address ] = data;
} }
break; break;
case 16: case 16:
{ {
UINT16 *flash_memory = (UINT16 *)m_flash_memory; m_addrspace[0]->write_word(address * 2, data);
flash_memory[ address ] = data;
} }
break; break;
default: default:
logerror( "FM_WRITEPART1 not supported when m_bits == %d\n", m_bits ); logerror( "FM_WRITEPART1 not supported when m_bits == %d\n", m_config.m_bits );
break; break;
} }
m_status = 0x80; m_status = 0x80;
@ -604,24 +656,9 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
if( ( data & 0xff ) == 0xd0 ) if( ( data & 0xff ) == 0xd0 )
{ {
// clear the 64k block containing the current address to all 0xffs // clear the 64k block containing the current address to all 0xffs
switch( m_bits ) for (offs_t offs = 0; offs < 64 * 1024; offs++)
{ m_addrspace[0]->write_byte((address & ~0xffff) + offs, 0xff);
case 8:
{
UINT8 *flash_memory = (UINT8 *)m_flash_memory;
memset( &flash_memory[ address & ~0xffff ], 0xff, 64 * 1024 );
}
break;
case 16:
{
UINT16 *flash_memory = (UINT16 *)m_flash_memory;
memset( &flash_memory[ address & ~0x7fff ], 0xff, 64 * 1024 );
}
break;
default:
logerror( "FM_CLEARPART1 not supported when m_bits == %d\n", m_bits );
break;
}
m_status = 0x00; m_status = 0x00;
m_flash_mode = FM_READSTATUS; m_flash_mode = FM_READSTATUS;

View File

@ -55,6 +55,7 @@ class intelfsh_device;
// ======================> intelfsh_device_config // ======================> intelfsh_device_config
class intelfsh_device_config : public device_config, class intelfsh_device_config : public device_config,
public device_config_memory_interface,
public device_config_nvram_interface public device_config_nvram_interface
{ {
friend class intelfsh_device; friend class intelfsh_device;
@ -82,14 +83,24 @@ protected:
// construction/destruction // construction/destruction
intelfsh_device_config(const machine_config &mconfig, device_type type, const char *name, const char *tag, const device_config *owner, UINT32 clock, UINT32 variant); intelfsh_device_config(const machine_config &mconfig, device_type type, const char *name, const char *tag, const device_config *owner, UINT32 clock, UINT32 variant);
// device_config_memory_interface overrides
virtual const address_space_config *memory_space_config(int spacenum = 0) const;
// internal state // internal state
address_space_config m_space_config;
UINT32 m_type; UINT32 m_type;
INT32 m_size;
UINT8 m_bits;
UINT8 m_device_id;
UINT8 m_maker_id;
bool m_sector_is_4k;
}; };
// ======================> intelfsh_device // ======================> intelfsh_device
class intelfsh_device : public device_t, class intelfsh_device : public device_t,
public device_memory_interface,
public device_nvram_interface public device_nvram_interface
{ {
friend class intelfsh_device_config; friend class intelfsh_device_config;
@ -98,16 +109,12 @@ protected:
// construction/destruction // construction/destruction
intelfsh_device(running_machine &_machine, const intelfsh_device_config &config); intelfsh_device(running_machine &_machine, const intelfsh_device_config &config);
public:
// helpers
void *memory() const { return m_flash_memory; }
protected: protected:
// device-level overrides // device-level overrides
virtual void device_start(); virtual void device_start();
virtual void device_timer(emu_timer &timer, int param, void *ptr); virtual void device_timer(emu_timer &timer, int param, void *ptr);
// device_intelfsh_interface overrides // device_config_nvram_interface overrides
virtual void nvram_default(); virtual void nvram_default();
virtual void nvram_read(mame_file &file); virtual void nvram_read(mame_file &file);
virtual void nvram_write(mame_file &file); virtual void nvram_write(mame_file &file);
@ -119,17 +126,11 @@ protected:
// internal state // internal state
const intelfsh_device_config & m_config; const intelfsh_device_config & m_config;
INT32 m_size;
UINT8 m_bits;
UINT8 m_status; UINT8 m_status;
INT32 m_erase_sector; INT32 m_erase_sector;
bool m_sector_is_4k;
INT32 m_flash_mode; INT32 m_flash_mode;
bool m_flash_master_lock; bool m_flash_master_lock;
UINT8 m_device_id;
UINT8 m_maker_id;
emu_timer * m_timer; emu_timer * m_timer;
void * m_flash_memory;
}; };
@ -166,6 +167,9 @@ public:
// public interface // public interface
UINT8 read(offs_t offset) { return read_full(offset); } UINT8 read(offs_t offset) { return read_full(offset); }
void write(offs_t offset, UINT8 data) { write_full(offset, data); } void write(offs_t offset, UINT8 data) { write_full(offset, data); }
UINT8 read_raw(offs_t offset) { return m_addrspace[0]->read_byte(offset); }
void write_raw(offs_t offset, UINT8 data) { m_addrspace[0]->write_byte(offset, data); }
}; };
@ -199,6 +203,9 @@ public:
// public interface // public interface
UINT16 read(offs_t offset) { return read_full(offset); } UINT16 read(offs_t offset) { return read_full(offset); }
void write(offs_t offset, UINT16 data) { write_full(offset, data); } void write(offs_t offset, UINT16 data) { write_full(offset, data); }
UINT16 read_raw(offs_t offset) { return m_addrspace[0]->read_word(offset * 2); }
void write_raw(offs_t offset, UINT16 data) { m_addrspace[0]->write_word(offset * 2, data); }
}; };

View File

@ -114,7 +114,7 @@ typedef void (*memcard_handler_func)(running_machine *machine, mame_file *file
// ======================> address_map_entry // ======================> machine_config
// machine configuration definition // machine configuration definition
class machine_config class machine_config

File diff suppressed because it is too large Load Diff