mirror of
https://github.com/holub/mame
synced 2025-05-31 18:11:50 +03:00
213 lines
6.5 KiB
C
213 lines
6.5 KiB
C
/***************************************************************************
|
|
|
|
er2055.c
|
|
|
|
GI 512 bit electrically alterable read-only memory.
|
|
|
|
***************************************************************************/
|
|
|
|
#include "emu.h"
|
|
#include "machine/er2055.h"
|
|
|
|
|
|
//**************************************************************************
|
|
// GLOBAL VARIABLES
|
|
//**************************************************************************
|
|
|
|
const device_type ER2055 = er2055_device_config::static_alloc_device_config;
|
|
|
|
static ADDRESS_MAP_START( er2055_map, ADDRESS_SPACE_PROGRAM, 8 )
|
|
AM_RANGE(0x0000, 0x003f) AM_RAM
|
|
ADDRESS_MAP_END
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// DEVICE CONFIGURATION
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// er2055_device_config - constructor
|
|
//-------------------------------------------------
|
|
|
|
er2055_device_config::er2055_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
|
|
: device_config(mconfig, static_alloc_device_config, "ER2055", tag, owner, clock),
|
|
device_config_memory_interface(mconfig, *this),
|
|
device_config_nvram_interface(mconfig, *this),
|
|
m_space_config("EAROM", ENDIANNESS_BIG, 8, 6, 0, *ADDRESS_MAP_NAME(er2055_map))
|
|
{
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// static_alloc_device_config - allocate a new
|
|
// configuration object
|
|
//-------------------------------------------------
|
|
|
|
device_config *er2055_device_config::static_alloc_device_config(const machine_config &mconfig, const char *tag, const device_config *owner, UINT32 clock)
|
|
{
|
|
return global_alloc(er2055_device_config(mconfig, tag, owner, clock));
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// alloc_device - allocate a new device object
|
|
//-------------------------------------------------
|
|
|
|
device_t *er2055_device_config::alloc_device(running_machine &machine) const
|
|
{
|
|
return auto_alloc(&machine, er2055_device(machine, *this));
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// memory_space_config - return a description of
|
|
// any address spaces owned by this device
|
|
//-------------------------------------------------
|
|
|
|
const address_space_config *er2055_device_config::memory_space_config(int spacenum) const
|
|
{
|
|
return (spacenum == 0) ? &m_space_config : NULL;
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// LIVE DEVICE
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// er2055_device - constructor
|
|
//-------------------------------------------------
|
|
|
|
er2055_device::er2055_device(running_machine &_machine, const er2055_device_config &config)
|
|
: device_t(_machine, config),
|
|
device_memory_interface(_machine, config, *this),
|
|
device_nvram_interface(_machine, config, *this),
|
|
m_config(config),
|
|
m_control_state(0),
|
|
m_address(0),
|
|
m_data(0)
|
|
{
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// device_start - device-specific startup
|
|
//-------------------------------------------------
|
|
|
|
void er2055_device::device_start()
|
|
{
|
|
state_save_register_device_item(this, 0, m_control_state);
|
|
state_save_register_device_item(this, 0, m_address);
|
|
state_save_register_device_item(this, 0, m_data);
|
|
|
|
m_control_state = 0;
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// nvram_default - called to initialize NVRAM to
|
|
// its default state
|
|
//-------------------------------------------------
|
|
|
|
void er2055_device::nvram_default()
|
|
{
|
|
// default to all-0xff
|
|
for (int byte = 0; byte < SIZE_DATA; byte++)
|
|
m_addrspace[0]->write_byte(byte, 0xff);
|
|
|
|
// populate from a memory region if present
|
|
if (m_region != NULL)
|
|
{
|
|
if (m_region->bytes() != SIZE_DATA)
|
|
fatalerror("er2055 region '%s' wrong size (expected size = 0x100)", tag());
|
|
if (m_region->width() != 1)
|
|
fatalerror("er2055 region '%s' needs to be an 8-bit region", tag());
|
|
|
|
for (int byte = 0; byte < SIZE_DATA; byte++)
|
|
m_addrspace[0]->write_byte(byte, m_region->u8(byte));
|
|
}
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// nvram_read - called to read NVRAM from the
|
|
// .nv file
|
|
//-------------------------------------------------
|
|
|
|
void er2055_device::nvram_read(mame_file &file)
|
|
{
|
|
UINT8 buffer[SIZE_DATA];
|
|
mame_fread(&file, buffer, sizeof(buffer));
|
|
for (int byte = 0; byte < SIZE_DATA; byte++)
|
|
m_addrspace[0]->write_byte(byte, buffer[byte]);
|
|
}
|
|
|
|
|
|
//-------------------------------------------------
|
|
// nvram_write - called to write NVRAM to the
|
|
// .nv file
|
|
//-------------------------------------------------
|
|
|
|
void er2055_device::nvram_write(mame_file &file)
|
|
{
|
|
UINT8 buffer[SIZE_DATA];
|
|
for (int byte = 0; byte < SIZE_DATA; byte++)
|
|
buffer[byte] = m_addrspace[0]->read_byte(byte);
|
|
mame_fwrite(&file, buffer, sizeof(buffer));
|
|
}
|
|
|
|
|
|
|
|
//**************************************************************************
|
|
// I/O OPERATIONS
|
|
//**************************************************************************
|
|
|
|
//-------------------------------------------------
|
|
// set_control - set the control lines; these
|
|
// must be done simultaneously because the chip
|
|
// reacts to various combinations
|
|
//-------------------------------------------------
|
|
|
|
void er2055_device::set_control(UINT8 cs1, UINT8 cs2, UINT8 c1, UINT8 c2, UINT8 ck)
|
|
{
|
|
// create a new composite control state
|
|
UINT8 oldstate = m_control_state;
|
|
m_control_state = (ck != 0) ? CK : 0;
|
|
m_control_state |= (c1 != 0) ? C1 : 0;
|
|
m_control_state |= (c2 != 0) ? C2 : 0;
|
|
m_control_state |= (cs1 != 0) ? CS1 : 0;
|
|
m_control_state |= (cs2 != 0) ? CS2 : 0;
|
|
|
|
// if not selected, or if change from previous, we're done
|
|
if ((m_control_state & (CS1 | CS2)) != (CS1 | CS2) || m_control_state == oldstate)
|
|
return;
|
|
|
|
// something changed, see what it is based on what mode we're in
|
|
switch (m_control_state & (C1 | C2))
|
|
{
|
|
// write mode; erasing is required, so we perform an AND against previous
|
|
// data to simulate incorrect behavior if erasing was not done
|
|
case 0:
|
|
m_addrspace[0]->write_byte(m_address, m_addrspace[0]->read_byte(m_address) & m_data);
|
|
//printf("Write %02X = %02X\n", m_address, m_data);
|
|
break;
|
|
|
|
// erase mode
|
|
case C2:
|
|
m_addrspace[0]->write_byte(m_address, 0xff);
|
|
//printf("Erase %02X\n", m_address);
|
|
break;
|
|
|
|
// read mode
|
|
case C1:
|
|
if ((oldstate & CK) != 0 && (m_control_state & CK) == 0)
|
|
{
|
|
m_data = m_addrspace[0]->read_byte(m_address);
|
|
//printf("Read %02X = %02X\n", m_address, m_data);
|
|
}
|
|
break;
|
|
}
|
|
}
|