mirror of
https://github.com/holub/mame
synced 2025-04-23 08:49:55 +03:00
Merge pull request #4202 from cam900/serflash_overflow
serflash.cpp : Updates
This commit is contained in:
commit
12bcdb5146
@ -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);
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user