diff options
author | 2018-10-27 10:04:51 +0900 | |
---|---|---|
committer | 2018-10-27 10:04:51 +0900 | |
commit | a990050f8f3ea9eb9863f8c3d8196ece26263d56 (patch) | |
tree | ff447c9d490cb7a42f726822e0fd66883b0fc2d8 | |
parent | 0d01ce1c25dcfc20ef7aa1aa1593d7793001ac56 (diff) |
serflash.cpp : Updates
Support address for when overall size is more/less than 0x8400000 bytes, or Flash page size is more/less than 2048+64
Fix block erase command, Add notes, Fix overflow
-rw-r--r-- | src/devices/machine/serflash.cpp | 109 | ||||
-rw-r--r-- | src/devices/machine/serflash.h | 15 |
2 files changed, 84 insertions, 40 deletions
diff --git a/src/devices/machine/serflash.cpp b/src/devices/machine/serflash.cpp index a6775374aa0..32f2524d5eb 100644 --- a/src/devices/machine/serflash.cpp +++ b/src/devices/machine/serflash.cpp @@ -8,6 +8,7 @@ #include "emu.h" #include "machine/serflash.h" +#include <algorithm> ALLOW_SAVE_TYPE(serflash_device::flash_state_t); @@ -27,6 +28,8 @@ serflash_device::serflash_device(const machine_config &mconfig, const char *tag, , device_nvram_interface(mconfig, *this) , m_length(0) , m_region(nullptr) + , m_row_num(0) + , m_flash_page_size(2048+64) , m_flash_state() , m_flash_enab(0) , m_flash_cmd_seq(0), m_flash_cmd_prev(0), m_flash_addr_seq(0), m_flash_read_seq(0) @@ -45,8 +48,12 @@ void serflash_device::device_start() m_length = machine().root_device().memregion(tag())->bytes(); m_region = machine().root_device().memregion(tag())->base(); - m_flashwritemap.resize(m_length / FLASH_PAGE_SIZE); - memset(&m_flashwritemap[0], 0, m_length / FLASH_PAGE_SIZE); + m_row_num = m_length / m_flash_page_size; + + m_flashwritemap.resize(m_row_num); + std::fill(m_flashwritemap.begin(), m_flashwritemap.end(), 0); + + m_flash_page_data.resize(m_flash_page_size); save_item(NAME(m_flash_state)); save_item(NAME(m_flash_enab)); @@ -93,8 +100,8 @@ void serflash_device::nvram_default() void serflash_device::nvram_read(emu_file &file) { - if (m_length % FLASH_PAGE_SIZE) return; // region size must be multiple of flash page size - int size = m_length / FLASH_PAGE_SIZE; + if (m_length % m_flash_page_size) return; // region size must be multiple of flash page size + int size = m_length / m_flash_page_size; if (file.is_open()) @@ -104,7 +111,7 @@ void serflash_device::nvram_read(emu_file &file) while (page < size) { m_flashwritemap[page] = 1; - file.read(m_region + page * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE); + file.read(m_region + page * m_flash_page_size, m_flash_page_size); file.read(&page, 4); } } @@ -119,8 +126,8 @@ void serflash_device::nvram_read(emu_file &file) void serflash_device::nvram_write(emu_file &file) { - if (m_length % FLASH_PAGE_SIZE) return; // region size must be multiple of flash page size - int size = m_length / FLASH_PAGE_SIZE; + if (m_length % m_flash_page_size) return; // region size must be multiple of flash page size + int size = m_length / m_flash_page_size; uint32_t page = 0; while (page < size) @@ -128,7 +135,7 @@ void serflash_device::nvram_write(emu_file &file) if (m_flashwritemap[page]) { file.write(&page, 4); - file.write(m_region + page * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE); + file.write(m_region + page * m_flash_page_size, m_flash_page_size); } page++; } @@ -150,7 +157,7 @@ void serflash_device::flash_hard_reset() m_flash_row = 0; m_flash_col = 0; - memset(m_flash_page_data, 0, FLASH_PAGE_SIZE); + std::fill(m_flash_page_data.begin(), m_flash_page_data.end(), 0); m_flash_page_addr = 0; m_flash_page_index = 0; } @@ -192,7 +199,7 @@ WRITE8_MEMBER( serflash_device::flash_cmd_w ) break; case 0x60: // BLOCK ERASE - m_flash_addr_seq = 0; + m_flash_addr_seq = 2; // row address only break; case 0x70: // READ STATUS @@ -226,10 +233,12 @@ WRITE8_MEMBER( serflash_device::flash_cmd_w ) case 0x00: // READ if (data == 0x30) { - memcpy(m_flash_page_data, m_region + m_flash_row * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE); - m_flash_page_addr = m_flash_col; - m_flash_page_index = m_flash_row; - + if (m_flash_row < m_row_num) + { + std::copy_n(&m_region[m_flash_row * m_flash_page_size], m_flash_page_size, m_flash_page_data.begin()); + m_flash_page_addr = m_flash_col; + m_flash_page_index = m_flash_row; + } flash_change_state( flash_state_t::READ ); //logerror("%08x FLASH: caching page = %04X\n", m_maincpu->pc(), m_flash_row); @@ -240,9 +249,12 @@ WRITE8_MEMBER( serflash_device::flash_cmd_w ) if (data==0xd0) { flash_change_state( flash_state_t::BLOCK_ERASE ); - m_flashwritemap[m_flash_col] |= 1; - memset(m_region + m_flash_col * FLASH_PAGE_SIZE, 0xff, FLASH_PAGE_SIZE); - //logerror("erased block %04x (%08x - %08x)\n", m_flash_col, m_flash_col * FLASH_PAGE_SIZE, ((m_flash_col+1) * FLASH_PAGE_SIZE)-1); + if (m_flash_row < m_row_num) + { + m_flashwritemap[m_flash_row] |= 1; + std::fill_n(&m_region[m_flash_row * m_flash_page_size], m_flash_page_size, 0xff); + } + //logerror("erased block %04x (%08x - %08x)\n", m_flash_col, m_flash_col * m_flash_page_size, ((m_flash_col+1) * m_flash_page_size)-1); } else { @@ -253,10 +265,12 @@ WRITE8_MEMBER( serflash_device::flash_cmd_w ) if (data==0x10) { flash_change_state( flash_state_t::PAGE_PROGRAM ); - m_flashwritemap[m_flash_row] |= (memcmp(m_region + m_flash_row * FLASH_PAGE_SIZE, m_flash_page_data, FLASH_PAGE_SIZE) != 0); - memcpy(m_region + m_flash_row * FLASH_PAGE_SIZE, m_flash_page_data, FLASH_PAGE_SIZE); - //logerror("re-written block %04x (%08x - %08x)\n", m_flash_row, m_flash_row * FLASH_PAGE_SIZE, ((m_flash_row+1) * FLASH_PAGE_SIZE)-1); - + if (m_flash_row < m_row_num) + { + m_flashwritemap[m_flash_row] |= (memcmp(m_region + m_flash_row * m_flash_page_size, &m_flash_page_data[0], m_flash_page_size) != 0); + std::copy_n(m_flash_page_data.begin(), m_flash_page_size, &m_region[m_flash_row * m_flash_page_size]); + } + //logerror("re-written block %04x (%08x - %08x)\n", m_flash_row, m_flash_row * m_flash_page_size, ((m_flash_row+1) * m_flash_page_size)-1); } else { @@ -279,7 +293,10 @@ WRITE8_MEMBER( serflash_device::flash_data_w ) return; //logerror("flash data write %04x\n", m_flash_page_addr); - m_flash_page_data[m_flash_page_addr] = data; + if (m_flash_page_addr < m_flash_page_size) + { + m_flash_page_data[m_flash_page_addr] = data; + } m_flash_page_addr++; } @@ -299,10 +316,21 @@ WRITE8_MEMBER( serflash_device::flash_addr_w ) m_flash_col = (m_flash_col & 0x00ff) | (data << 8); break; case 2: - m_flash_row = (m_flash_row & 0xff00) | data; + m_flash_row = (m_flash_row & 0xffff00) | data; + if (m_row_num <= 256) + { + m_flash_addr_seq = 0; + } break; case 3: - m_flash_row = (m_flash_row & 0x00ff) | (data << 8); + m_flash_row = (m_flash_row & 0xff00ff) | (data << 8); + if (m_row_num <= 65536) + { + m_flash_addr_seq = 0; + } + break; + case 4: + m_flash_row = (m_flash_row & 0x00ffff) | (data << 16); m_flash_addr_seq = 0; break; } @@ -342,8 +370,8 @@ READ8_MEMBER( serflash_device::flash_io_r ) break; case flash_state_t::READ: - if (m_flash_page_addr > FLASH_PAGE_SIZE-1) - m_flash_page_addr = FLASH_PAGE_SIZE-1; + if (m_flash_page_addr > m_flash_page_size-1) + m_flash_page_addr = m_flash_page_size-1; //old = m_flash_page_addr; @@ -402,10 +430,11 @@ WRITE8_MEMBER(serflash_device::n3d_flash_cmd_w) if (data==0x00) { - memcpy(m_flash_page_data, m_region + m_flash_addr * FLASH_PAGE_SIZE, FLASH_PAGE_SIZE); - + if (m_flash_addr < m_row_num) + { + std::copy_n(&m_region[m_flash_addr * m_flash_page_size], m_flash_page_size, m_flash_page_data.begin()); + } } - } WRITE8_MEMBER(serflash_device::n3d_flash_addr_w) @@ -415,16 +444,28 @@ WRITE8_MEMBER(serflash_device::n3d_flash_addr_w) m_flash_addr_seq++; if (m_flash_addr_seq==3) + { m_flash_addr = (m_flash_addr & 0xffff00) | data; - + if (m_row_num <= 256) + { + m_flash_addr_seq = 0; + m_flash_page_addr = 0; + logerror("set flash block to %08x\n", m_flash_addr); + } + } if (m_flash_addr_seq==4) + { m_flash_addr = (m_flash_addr & 0xff00ff) | data << 8; - - if (m_flash_addr_seq==5) - m_flash_addr = (m_flash_addr & 0x00ffff) | data << 16; - + if (m_row_num <= 65536) + { + m_flash_addr_seq = 0; + m_flash_page_addr = 0; + logerror("set flash block to %08x\n", m_flash_addr); + } + } if (m_flash_addr_seq==5) { + m_flash_addr = (m_flash_addr & 0x00ffff) | data << 16; m_flash_addr_seq = 0; m_flash_page_addr = 0; logerror("set flash block to %08x\n", m_flash_addr); diff --git a/src/devices/machine/serflash.h b/src/devices/machine/serflash.h index cae78e0f6f4..20077b00263 100644 --- a/src/devices/machine/serflash.h +++ b/src/devices/machine/serflash.h @@ -20,10 +20,12 @@ public: // custom initialization for default state typedef device_delegate<void (serflash_device &, void *, size_t)> init_delegate; - // construction/destruction serflash_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + // configuration + void set_flash_page_size(uint16_t size) { m_flash_page_size = size; } + DECLARE_READ8_MEMBER( flash_ready_r ); DECLARE_READ8_MEMBER( flash_io_r ); DECLARE_WRITE8_MEMBER( flash_addr_w ); @@ -37,8 +39,6 @@ public: DECLARE_WRITE8_MEMBER(n3d_flash_addr_w); protected: - static constexpr unsigned FLASH_PAGE_SIZE = 2048+64; - enum class flash_state_t : u8 { IDLE = 0, READ, READ_ID, READ_STATUS, BLOCK_ERASE, PAGE_PROGRAM }; // device-level overrides @@ -56,6 +56,8 @@ protected: size_t m_length; uint8_t* m_region; + uint32_t m_row_num; + uint16_t m_flash_page_size; flash_state_t m_flash_state; @@ -67,9 +69,10 @@ protected: uint8_t m_flash_addr_seq; uint8_t m_flash_read_seq; - uint16_t m_flash_row, m_flash_col; + uint32_t m_flash_row; + uint16_t m_flash_col; int m_flash_page_addr; - uint16_t m_flash_page_index; + uint32_t m_flash_page_index; std::vector<uint8_t> m_flashwritemap; @@ -78,7 +81,7 @@ protected: uint32_t m_flash_addr; - uint8_t m_flash_page_data[FLASH_PAGE_SIZE]; + std::vector<uint8_t> m_flash_page_data; }; |