mirror of
https://github.com/holub/mame
synced 2025-05-18 11:39:29 +03:00
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:
parent
d4a4c81615
commit
e22fd1b2c7
@ -548,7 +548,8 @@ device_t::device_t(running_machine &_machine, const device_config &config)
|
||||
m_baseconfig(config),
|
||||
m_unscaled_clock(config.m_clock),
|
||||
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
|
||||
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
|
||||
for (device_interface *intf = m_interface_list; intf != NULL; intf = intf->interface_next())
|
||||
intf->interface_pre_start();
|
||||
@ -888,3 +893,72 @@ void device_t::notify_clock_changed()
|
||||
// then notify the device
|
||||
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;
|
||||
}
|
||||
|
@ -485,6 +485,111 @@ protected:
|
||||
UINT32 m_unscaled_clock; // unscaled clock
|
||||
double m_clock_scale; // clock scale factor
|
||||
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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1173,10 +1173,6 @@ void driver_device::device_start()
|
||||
if (next() != NULL)
|
||||
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
|
||||
if (m_config.m_game->driver_init != NULL)
|
||||
(*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
|
||||
|
@ -628,107 +628,8 @@ protected:
|
||||
virtual void device_start();
|
||||
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
|
||||
const driver_device_config_base &m_config;
|
||||
auto_finder_base *m_auto_finder_list;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
//**************************************************************************
|
||||
@ -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)
|
||||
: device_config(mconfig, type, name, tag, owner, clock),
|
||||
device_config_memory_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)
|
||||
@ -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
|
||||
@ -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)
|
||||
: device_t(_machine, config),
|
||||
device_memory_interface(_machine, config, *this),
|
||||
device_nvram_interface(_machine, config, *this),
|
||||
m_config(config),
|
||||
m_size(0),
|
||||
m_bits(config.m_type >> 8),
|
||||
m_status(0x80),
|
||||
m_erase_sector(0),
|
||||
m_sector_is_4k(false),
|
||||
m_flash_mode(FM_NORMAL),
|
||||
m_flash_master_lock(false),
|
||||
m_device_id(0),
|
||||
m_maker_id(0),
|
||||
m_timer(NULL),
|
||||
m_flash_memory(NULL)
|
||||
m_timer(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)
|
||||
@ -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_flash_mode );
|
||||
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)
|
||||
{
|
||||
UINT32 bytes = m_region->bytes();
|
||||
if (bytes > m_size)
|
||||
bytes = m_size;
|
||||
memcpy(m_flash_memory, *m_region, bytes);
|
||||
if (bytes > m_config.m_size)
|
||||
bytes = m_config.m_size;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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:
|
||||
case FM_NORMAL:
|
||||
switch( m_bits )
|
||||
switch( m_config.m_bits )
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
UINT8 *flash_memory = (UINT8 *)m_flash_memory;
|
||||
data = flash_memory[ address ];
|
||||
data = m_addrspace[0]->read_byte(address);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
{
|
||||
UINT16 *flash_memory = (UINT16 *)m_flash_memory;
|
||||
data = flash_memory[ address ];
|
||||
data = m_addrspace[0]->read_word(address * 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -309,8 +388,8 @@ UINT32 intelfsh_device::read_full(UINT32 address)
|
||||
case FM_READAMDID3:
|
||||
switch (address)
|
||||
{
|
||||
case 0: data = m_maker_id; break;
|
||||
case 1: data = m_device_id; break;
|
||||
case 0: data = m_config.m_maker_id; break;
|
||||
case 1: data = m_config.m_device_id; break;
|
||||
case 2: data = 0; break;
|
||||
}
|
||||
break;
|
||||
@ -318,10 +397,10 @@ UINT32 intelfsh_device::read_full(UINT32 address)
|
||||
switch (address)
|
||||
{
|
||||
case 0: // maker ID
|
||||
data = m_maker_id;
|
||||
data = m_config.m_maker_id;
|
||||
break;
|
||||
case 1: // chip ID
|
||||
data = m_device_id;
|
||||
data = m_config.m_device_id;
|
||||
break;
|
||||
case 2: // block lock config
|
||||
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
|
||||
if ((address < m_erase_sector) || (address >= m_erase_sector+(64*1024)))
|
||||
{
|
||||
switch( m_bits )
|
||||
switch( m_config.m_bits )
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
UINT8 *flash_memory = (UINT8 *)m_flash_memory;
|
||||
data = flash_memory[ address ];
|
||||
data = m_addrspace[0]->read_byte(address);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
{
|
||||
UINT16 *flash_memory = (UINT16 *)m_flash_memory;
|
||||
data = flash_memory[ address ];
|
||||
data = m_addrspace[0]->read_word(address * 2);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -506,7 +583,8 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
|
||||
if( ( address & 0xfff ) == 0x555 && ( data & 0xff ) == 0x10 )
|
||||
{
|
||||
// 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_flash_mode = FM_ERASEAMD4;
|
||||
@ -517,42 +595,19 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
|
||||
{
|
||||
// sector erase
|
||||
// clear the 4k/64k block containing the current address to all 0xffs
|
||||
switch( m_bits )
|
||||
if (m_config.m_sector_is_4k)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
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;
|
||||
timer_adjust_oneshot( m_timer, ATTOTIME_IN_MSEC( 125 ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( &flash_memory[ address & ~0xffff ], 0xff, 64 * 1024 );
|
||||
m_erase_sector = address & ~0xffff;
|
||||
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;
|
||||
for (offs_t offs = 0; offs < 4 * 1024; offs++)
|
||||
m_addrspace[0]->write_byte((address & ~0xfff) + offs, 0xff);
|
||||
m_erase_sector = address & ~0xfff;
|
||||
timer_adjust_oneshot( m_timer, ATTOTIME_IN_MSEC( 125 ), 0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
for (offs_t offs = 0; offs < 64 * 1024; offs++)
|
||||
m_addrspace[0]->write_byte((address & ~0xffff) + offs, 0xff);
|
||||
m_erase_sector = address & ~0xffff;
|
||||
timer_adjust_oneshot( m_timer, ATTOTIME_IN_SEC( 1 ), 0 );
|
||||
}
|
||||
|
||||
m_status = 1 << 3;
|
||||
@ -564,37 +619,34 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
|
||||
}
|
||||
break;
|
||||
case FM_BYTEPROGRAM:
|
||||
switch( m_bits )
|
||||
switch( m_config.m_bits )
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
UINT8 *flash_memory = (UINT8 *)m_flash_memory;
|
||||
flash_memory[ address ] = data;
|
||||
m_addrspace[0]->write_byte(address, data);
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
m_flash_mode = FM_NORMAL;
|
||||
break;
|
||||
case FM_WRITEPART1:
|
||||
switch( m_bits )
|
||||
switch( m_config.m_bits )
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
UINT8 *flash_memory = (UINT8 *)m_flash_memory;
|
||||
flash_memory[ address ] = data;
|
||||
m_addrspace[0]->write_byte(address, data);
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
{
|
||||
UINT16 *flash_memory = (UINT16 *)m_flash_memory;
|
||||
flash_memory[ address ] = data;
|
||||
m_addrspace[0]->write_word(address * 2, data);
|
||||
}
|
||||
break;
|
||||
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;
|
||||
}
|
||||
m_status = 0x80;
|
||||
@ -604,24 +656,9 @@ void intelfsh_device::write_full(UINT32 address, UINT32 data)
|
||||
if( ( data & 0xff ) == 0xd0 )
|
||||
{
|
||||
// clear the 64k block containing the current address to all 0xffs
|
||||
switch( m_bits )
|
||||
{
|
||||
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;
|
||||
}
|
||||
for (offs_t offs = 0; offs < 64 * 1024; offs++)
|
||||
m_addrspace[0]->write_byte((address & ~0xffff) + offs, 0xff);
|
||||
|
||||
m_status = 0x00;
|
||||
m_flash_mode = FM_READSTATUS;
|
||||
|
||||
|
@ -55,6 +55,7 @@ class intelfsh_device;
|
||||
// ======================> intelfsh_device_config
|
||||
|
||||
class intelfsh_device_config : public device_config,
|
||||
public device_config_memory_interface,
|
||||
public device_config_nvram_interface
|
||||
{
|
||||
friend class intelfsh_device;
|
||||
@ -82,14 +83,24 @@ protected:
|
||||
// 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);
|
||||
|
||||
// device_config_memory_interface overrides
|
||||
virtual const address_space_config *memory_space_config(int spacenum = 0) const;
|
||||
|
||||
// internal state
|
||||
UINT32 m_type;
|
||||
address_space_config m_space_config;
|
||||
UINT32 m_type;
|
||||
INT32 m_size;
|
||||
UINT8 m_bits;
|
||||
UINT8 m_device_id;
|
||||
UINT8 m_maker_id;
|
||||
bool m_sector_is_4k;
|
||||
};
|
||||
|
||||
|
||||
// ======================> intelfsh_device
|
||||
|
||||
class intelfsh_device : public device_t,
|
||||
public device_memory_interface,
|
||||
public device_nvram_interface
|
||||
{
|
||||
friend class intelfsh_device_config;
|
||||
@ -98,16 +109,12 @@ protected:
|
||||
// construction/destruction
|
||||
intelfsh_device(running_machine &_machine, const intelfsh_device_config &config);
|
||||
|
||||
public:
|
||||
// helpers
|
||||
void *memory() const { return m_flash_memory; }
|
||||
|
||||
protected:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
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_read(mame_file &file);
|
||||
virtual void nvram_write(mame_file &file);
|
||||
@ -119,17 +126,11 @@ protected:
|
||||
// internal state
|
||||
const intelfsh_device_config & m_config;
|
||||
|
||||
INT32 m_size;
|
||||
UINT8 m_bits;
|
||||
UINT8 m_status;
|
||||
INT32 m_erase_sector;
|
||||
bool m_sector_is_4k;
|
||||
INT32 m_flash_mode;
|
||||
bool m_flash_master_lock;
|
||||
UINT8 m_device_id;
|
||||
UINT8 m_maker_id;
|
||||
emu_timer * m_timer;
|
||||
void * m_flash_memory;
|
||||
UINT8 m_status;
|
||||
INT32 m_erase_sector;
|
||||
INT32 m_flash_mode;
|
||||
bool m_flash_master_lock;
|
||||
emu_timer * m_timer;
|
||||
};
|
||||
|
||||
|
||||
@ -166,6 +167,9 @@ public:
|
||||
// public interface
|
||||
UINT8 read(offs_t offset) { return read_full(offset); }
|
||||
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
|
||||
UINT16 read(offs_t offset) { return read_full(offset); }
|
||||
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); }
|
||||
};
|
||||
|
||||
|
||||
|
@ -114,7 +114,7 @@ typedef void (*memcard_handler_func)(running_machine *machine, mame_file *file
|
||||
|
||||
|
||||
|
||||
// ======================> address_map_entry
|
||||
// ======================> machine_config
|
||||
|
||||
// machine configuration definition
|
||||
class machine_config
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user