diff options
author | 2013-03-07 15:28:25 +0000 | |
---|---|---|
committer | 2013-03-07 15:28:25 +0000 | |
commit | 76ac08a0b805820f12be6dac3daee17f8eb26953 (patch) | |
tree | 74a1a81d8e2a6cf242d498978b3573015c4d7a0c /src/mess/machine/at29040a.c | |
parent | 7e0b63efa9978e8611337c4ac80ffc293bb527ee (diff) |
Moved some files to where they belong. (nw)
Diffstat (limited to 'src/mess/machine/at29040a.c')
-rw-r--r-- | src/mess/machine/at29040a.c | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/src/mess/machine/at29040a.c b/src/mess/machine/at29040a.c deleted file mode 100644 index 95982e67bf0..00000000000 --- a/src/mess/machine/at29040a.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - Atmel at29c040a flash EEPROM - - 512k*8 FEEPROM, organized in pages of 256 bytes. - - References: - Datasheets were found on Atmel's site (www.atmel.com) - - Raphael Nabet 2003 - - September 2010: Rewritten as device - February 2012: Rewritten as class -*/ - -#include "at29040a.h" - -#define VERBOSE 2 -#define LOG logerror - -#define FEEPROM_SIZE 0x80000 -#define SECTOR_SIZE 0x00100 -#define BOOT_BLOCK_SIZE 0x04000 - -#define ADDRESS_MASK 0x7ffff -#define SECTOR_ADDRESS_MASK 0x7ff00 -#define BYTE_ADDRESS_MASK 0x000ff - -#define PRG_TIMER 1 - -#define VERSION 0 - -/* - Constructor. -*/ -at29040a_device::at29040a_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) -: device_t(mconfig, AT29040A, "ATMEL 29040A 512K*8 FEEPROM", tag, owner, clock), - device_nvram_interface(mconfig, *this) -{ -} - -//------------------------------------------------- -// nvram_default - called to initialize NVRAM to -// its default state -//------------------------------------------------- - -void at29040a_device::nvram_default() -{ - memset(m_eememory, 0, FEEPROM_SIZE+2); -} - -//------------------------------------------------- -// nvram_read - called to read NVRAM from the -// .nv file -//------------------------------------------------- - -void at29040a_device::nvram_read(emu_file &file) -{ - file.read(m_eememory, FEEPROM_SIZE+2); -} - -//------------------------------------------------- -// nvram_write - called to write NVRAM to the -// .nv file -//------------------------------------------------- - -void at29040a_device::nvram_write(emu_file &file) -{ - m_eememory[0] = VERSION; - file.write(m_eememory, FEEPROM_SIZE+2); -} - -/* - programming timer callback -*/ -void at29040a_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (m_pgm) - { - case PGM_1: - /* programming cycle timeout */ - if (VERBOSE>7) LOG("at29040a: Programming cycle timeout\n"); - m_pgm = PGM_0; - break; - - case PGM_2: - /* programming cycle start */ - if (VERBOSE>7) LOG("at29040a: Sector write start\n"); - m_pgm = PGM_3; - /* max delay 10ms, typical delay 5 to 7 ms */ - m_programming_timer->adjust(attotime::from_msec(5)); - break; - - case PGM_3: - /* programming cycle end */ - memcpy(m_eememory + 2 + (m_programming_last_offset & ~0xff), m_programming_buffer, SECTOR_SIZE); - if (VERBOSE>7) LOG("at29040a: Sector write completed at location %04x + 2\n", (m_programming_last_offset & ~0xff)); - if (m_enabling_sdb) - { - m_sdp = true; - } - if (m_disabling_sdb) - { - m_sdp = false; - } - if (VERBOSE>7) LOG("at29040a: Software data protection = %d\n", m_sdp); - - m_pgm = PGM_0; - m_enabling_sdb = false; - m_disabling_sdb = false; - - break; - - default: - if (VERBOSE>1) LOG("internal error in %s %d\n", __FILE__, __LINE__); - break; - } -} - -void at29040a_device::sync_flags() -{ - if (m_lower_bbl) m_eememory[1] |= 0x04; - else m_eememory[1] &= ~0x04; - - if (m_higher_bbl) m_eememory[1] |= 0x02; - else m_eememory[1] &= ~0x02; - - if (m_sdp) m_eememory[1] |= 0x01; - else m_eememory[1] &= ~0x01; -} - -/* - read a byte from FEEPROM -*/ -READ8_MEMBER( at29040a_device::read ) -{ - int reply; - - offset &= ADDRESS_MASK; - - /* reading in the midst of any command sequence cancels it (right???) */ - m_cmd = CMD_0; - m_long_sequence = false; - // m_higher_bbl = true; // who says that? - - sync_flags(); - - /* reading before the start of a programming cycle cancels it (right???) */ - if (m_pgm == PGM_1) - { - // attempt to access a locked out boot block: cancel programming - // command if necessary - m_pgm = PGM_0; - m_enabling_sdb = false; - m_disabling_sdb = false; - m_programming_timer->adjust(attotime::never); - } - - if (m_id_mode) - { - switch (offset) - { - case 0x00000: - reply = 0x1f; // Manufacturer code - break; - - case 0x00001: - reply = 0xa4; // Device code - break; - - case 0x00002: - reply = m_lower_bbl? 0xff : 0xfe; - break; - - case 0x7fff2: - reply = m_higher_bbl? 0xff : 0xfe; - break; - - default: - reply = 0; - break; - } - } - else if ((m_pgm == PGM_2) || (m_pgm == PGM_3)) - { - if (m_pgm == PGM_2) - { // DATA* polling starts the programming cycle (right???) - m_pgm = PGM_3; - /* max delay 10ms, typical delay 5 to 7 ms */ - m_programming_timer->adjust(attotime::from_msec(5)); - } - - reply = m_toggle_bit? 0x02 : 0x00; - m_toggle_bit = !m_toggle_bit; - - if ((offset == m_programming_last_offset) && (! (m_programming_buffer[m_programming_last_offset & 0xff] & 0x01))) - reply |= 0x01; - } - else - reply = m_eememory[offset+2]; - - if (VERBOSE>7) LOG("at29040a: %05x -> %02x\n", offset, reply); - - return reply; -} - -/* - Write a byte to FEEPROM -*/ -WRITE8_MEMBER( at29040a_device::write ) -{ - offset &= ADDRESS_MASK; - if (VERBOSE>7) LOG("at29040a: %05x <- %02x\n", offset, data); - - /* The special CFI commands assume a smaller address space according */ - /* to the specification ("address format A14-A0") */ - offs_t cfi_offset = offset & 0x7fff; - - if (m_enabling_bbl) - { - if (VERBOSE>7) LOG("at29040a: Enabling boot block lockout\n"); - m_enabling_bbl = false; - - if ((offset == 0x00000) && (data == 0x00)) - { - if (VERBOSE>7) LOG("at29040a: Enabling lower boot block lockout\n"); - m_lower_bbl = true; - sync_flags(); - return; - } - else - { - if ((offset == 0x7ffff) && (data == 0xff)) - { - if (VERBOSE>7) LOG("at29040a: Enabling higher boot block lockout\n"); - m_higher_bbl = true; - sync_flags(); - return; - } - else - { - if (VERBOSE>1) LOG("at29040a: Invalid boot block specification: %05x/%02x\n", offset, data); - } - } - } - - switch (m_cmd) - { - case CMD_0: - if ((cfi_offset == 0x5555) && (data == 0xaa)) - { - if (VERBOSE>7) LOG("at29040a: Command sequence started\n"); - m_cmd = CMD_1; - } - else - { - m_cmd = CMD_0; - m_long_sequence = false; - } - break; - - case CMD_1: - if ((cfi_offset == 0x2aaa) && (data == 0x55)) - { - m_cmd = CMD_2; - } - else - { - m_cmd = CMD_0; - m_long_sequence = false; - if (VERBOSE>7) LOG("at29040a: Command sequence aborted\n"); - } - break; - - case CMD_2: - if (cfi_offset == 0x5555) - { - if (!m_long_sequence) - if (VERBOSE>7) LOG("at29040a: Command sequence completed\n"); - - m_pgm = PGM_0; - m_enabling_sdb = false; - m_disabling_sdb = false; - m_programming_timer->adjust(attotime::never); - - /* process command */ - switch (data) - { - case 0x10: - /* Software chip erase */ - if (m_long_sequence) - { - if (m_lower_bbl || m_higher_bbl) - { - if (VERBOSE>1) LOG("at29040a: Chip erase sequence deactivated due to previous boot block lockout.\n"); - } - else - { - if (VERBOSE>7) LOG("at29040a: Erase chip\n"); - memset(m_eememory+2, 0xff, FEEPROM_SIZE); - } - } - break; - - case 0x20: - /* Software data protection disable */ - if (VERBOSE>7) LOG("at29040a: Software data protection disable\n"); - // The complete sequence is aa-55-80-aa-55-20 - // so we need a 80 before, else the sequence is invalid - if (m_long_sequence) - { - m_pgm = PGM_1; - m_disabling_sdb = true; - /* set command timeout (right???) */ - //m_programming_timer->adjust(attotime::from_usec(150), id, 0.); - } - break; - - case 0x40: - /* Boot block lockout enable */ - // Complete sequence is aa-55-80-aa-55-40 - if (VERBOSE>7) LOG("at29040a: Boot block lockout enable\n"); - if (m_long_sequence) m_enabling_bbl = true; - break; - - case 0x80: - m_long_sequence = true; - break; - - case 0x90: - /* Software product identification entry */ - if (VERBOSE>7) LOG("at29040a: Identification mode (start)\n"); - m_id_mode = true; - break; - - case 0xa0: - /* Software data protection enable */ - if (VERBOSE>7) LOG("at29040a: Software data protection enable\n"); - m_pgm = PGM_1; - m_enabling_sdb = true; - /* set command timeout (right???) */ - //m_programming_timer->adjust(attotime::from_usec(150), id, 0.); - break; - - case 0xf0: - /* Software product identification exit */ - if (VERBOSE>7) LOG("at29040a: Identification mode (end)\n"); - m_id_mode = false; - break; - } - m_cmd = CMD_0; - if (data != 0x80) m_long_sequence = false; - - /* return, because we don't want to write the EEPROM with the command byte */ - return; - } - else - { - m_cmd = CMD_0; - m_long_sequence = false; - } - } - if ((m_pgm == PGM_2) - && ((offset & ~0xff) != (m_programming_last_offset & ~0xff))) - { - /* cancel current programming cycle */ - if (VERBOSE>7) LOG("at29040a: invalid sector change (from %05x to %05x); cancel programming cycle\n",(offset & ~0xff), (m_programming_last_offset & ~0xff)); - m_pgm = PGM_0; - m_enabling_sdb = false; - m_disabling_sdb = false; - m_programming_timer->adjust(attotime::never); - } - - if (((m_pgm == PGM_0) && !m_sdp) // write directly - || (m_pgm == PGM_1)) // write after unlocking - { - if (((offset < BOOT_BLOCK_SIZE) && m_lower_bbl) - || ((offset >= FEEPROM_SIZE-BOOT_BLOCK_SIZE) && m_higher_bbl)) - { - // attempt to access a locked out boot block: cancel programming - // command if necessary - if (VERBOSE>7) LOG("at29040a: attempt to access a locked out boot block: offset = %05x, lowblock=%d, highblock=%d\n", offset, m_lower_bbl, m_higher_bbl); - - m_pgm = PGM_0; - m_enabling_sdb = false; - m_disabling_sdb = false; - } - else - { /* enter programming mode */ - if (VERBOSE>7) LOG("at29040a: enter programming mode (m_pgm=%d)\n", m_pgm); - memset(m_programming_buffer, 0xff, SECTOR_SIZE); - m_pgm = PGM_2; - } - } - if (m_pgm == PGM_2) - { - /* write data to programming buffer */ - if (VERBOSE>7) LOG("at29040a: Write data to programming buffer\n"); - m_programming_buffer[offset & 0xff] = data; - m_programming_last_offset = offset; - m_programming_timer->adjust(attotime::from_usec(150)); // next byte must be written before the timer expires - } -} - -void at29040a_device::device_start(void) -{ - m_programming_buffer = (UINT8*)malloc(SECTOR_SIZE); - m_programming_timer = timer_alloc(PRG_TIMER); - - m_eememory = (UINT8*)malloc(FEEPROM_SIZE+2); -} - -void at29040a_device::device_stop(void) -{ - free(m_programming_buffer); - free(m_eememory); -} - -void at29040a_device::device_reset(void) -{ - if (m_eememory[0] != VERSION) - { - if (VERBOSE>1) LOG("AT29040A: Warning: Version mismatch; expected %d but found %d for %s. Resetting.\n", VERSION, m_eememory[0], tag()); - m_eememory[0] = 0; - m_eememory[1] = 0; - } - - m_lower_bbl = ((m_eememory[1] & 0x04)!=0); - m_higher_bbl = ((m_eememory[1] & 0x02)!=0); - m_sdp = ((m_eememory[1] & 0x01)!=0); - - if (VERBOSE>7) LOG("at29040a (%s): LowerBBL = %d, HigherBBL = %d, SoftDataProt = %d\n", tag(), m_lower_bbl, m_higher_bbl, m_sdp); - - m_id_mode = false; - m_cmd = CMD_0; - m_enabling_bbl = false; - m_long_sequence = false; - m_pgm = PGM_0; - m_enabling_sdb = false; - m_disabling_sdb = false; - m_toggle_bit = false; - m_programming_last_offset = 0; -} - -const device_type AT29040A = &device_creator<at29040a_device>; |