summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/wswan/rom.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/wswan/rom.cpp')
-rw-r--r--src/devices/bus/wswan/rom.cpp579
1 files changed, 393 insertions, 186 deletions
diff --git a/src/devices/bus/wswan/rom.cpp b/src/devices/bus/wswan/rom.cpp
index 68d4c1d0500..9b1501c885f 100644
--- a/src/devices/bus/wswan/rom.cpp
+++ b/src/devices/bus/wswan/rom.cpp
@@ -24,9 +24,10 @@ enum
DEFINE_DEVICE_TYPE(WS_ROM_STD, ws_rom_device, "ws_rom", "Wonderswan Standard Carts")
DEFINE_DEVICE_TYPE(WS_ROM_SRAM, ws_rom_sram_device, "ws_sram", "Wonderswan Carts w/SRAM")
DEFINE_DEVICE_TYPE(WS_ROM_EEPROM, ws_rom_eeprom_device, "ws_eeprom", "Wonderswan Carts w/EEPROM")
+DEFINE_DEVICE_TYPE(WS_ROM_WWITCH, ws_wwitch_device, "ws_wwitch", "WonderWitch")
-ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) :
+ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
device_t(mconfig, type, tag, owner, clock),
device_ws_cart_interface(mconfig, *this),
m_base20(0),
@@ -45,25 +46,35 @@ ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, co
{
}
-ws_rom_device::ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ws_rom_device::ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ws_rom_device(mconfig, WS_ROM_STD, tag, owner, clock)
{
}
-ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ws_rom_device(mconfig, WS_ROM_SRAM, tag, owner, clock),
m_nvram_base(0)
{
}
+ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) :
+ ws_rom_device(mconfig, type, tag, owner, clock),
+ m_nvram_base(0)
+{
+}
-ws_rom_eeprom_device::ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ws_rom_eeprom_device::ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
ws_rom_device(mconfig, WS_ROM_EEPROM, tag, owner, clock),
m_eeprom_mode(0), m_eeprom_address(0), m_eeprom_command(0), m_eeprom_start(0), m_eeprom_write_enabled(0)
{
}
+ws_wwitch_device::ws_wwitch_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+ ws_rom_sram_device(mconfig, WS_ROM_WWITCH, tag, owner, clock)
+{
+}
+
//-------------------------------------------------
// device_start - device-specific startup
//-------------------------------------------------
@@ -91,15 +102,17 @@ void ws_rom_device::device_start()
save_item(NAME(m_rtc_minute));
save_item(NAME(m_rtc_second));
save_item(NAME(m_rtc_index));
+ save_item(NAME(m_rom_mask));
}
void ws_rom_device::device_reset()
{
- m_base20 = ((0xff & m_bank_mask) << 16) & (m_rom_size - 1);
- m_base30 = ((0xff & m_bank_mask) << 16) & (m_rom_size - 1);
- m_base40 = (((0xf0 & m_bank_mask) | 4) << 16) & (m_rom_size - 1);
+ m_rom_mask = (m_rom_size >> 1) - 1;
+ m_base20 = ((0xff & m_bank_mask) << 15) & m_rom_mask;
+ m_base30 = ((0xff & m_bank_mask) << 15) & m_rom_mask;
+ m_base40 = (((0xf0 & m_bank_mask) | 4) << 15) & m_rom_mask;
- memset(m_io_regs, 0, sizeof(m_io_regs));
+ memset(m_io_regs, 0xff, sizeof(m_io_regs));
// Initialize RTC
m_rtc_index = 0;
@@ -135,6 +148,30 @@ void ws_rom_eeprom_device::device_start()
save_item(NAME(m_eeprom_write_enabled));
}
+void ws_wwitch_device::device_start()
+{
+ save_item(NAME(m_flash_seq));
+ save_item(NAME(m_flash_command));
+ save_item(NAME(m_write_flash));
+ save_item(NAME(m_writing_flash));
+ save_item(NAME(m_write_resetting));
+ save_item(NAME(m_flash_mode));
+ save_item(NAME(m_flash_status));
+ ws_rom_sram_device::device_start();
+}
+
+void ws_wwitch_device::device_reset()
+{
+ m_flash_seq = 0;
+ m_flash_command = 0;
+ m_write_flash = false;
+ m_writing_flash = false;
+ m_write_resetting = false;
+ m_flash_mode = READ_MODE;
+ m_flash_status = 0;
+ ws_rom_sram_device::device_reset();
+}
+
void ws_rom_eeprom_device::device_reset()
{
m_eeprom_address = 0;
@@ -205,48 +242,52 @@ void ws_rom_device::device_timer(emu_timer &timer, device_timer_id id, int param
mapper specific handlers
-------------------------------------------------*/
-uint8_t ws_rom_device::read_rom20(offs_t offset)
+u16 ws_rom_device::read_rom20(offs_t offset, u16 mem_mask)
{
return m_rom[offset + m_base20];
}
-uint8_t ws_rom_device::read_rom30(offs_t offset)
+u16 ws_rom_device::read_rom30(offs_t offset, u16 mem_mask)
{
return m_rom[offset + m_base30];
}
-uint8_t ws_rom_device::read_rom40(offs_t offset)
+u16 ws_rom_device::read_rom40(offs_t offset, u16 mem_mask)
{
// we still need to mask in some cases, e.g. when game is 512K
- return m_rom[(offset + m_base40) & (m_rom_size - 1)];
+ return m_rom[(offset + m_base40) & m_rom_mask];
}
-uint8_t ws_rom_device::read_io(offs_t offset)
+u16 ws_rom_device::read_io(offs_t offset, u16 mem_mask)
{
- uint8_t value = m_io_regs[offset];
+ u16 value = m_io_regs[offset];
switch (offset)
{
- case 0x0b: // RTC data
+ case 0x0a / 2:
if (!m_has_rtc)
break;
- if (m_io_regs[0x0a] == 0x95 && (m_rtc_index < 7))
+ // RTC data
+ if (ACCESSING_BITS_8_15)
{
- switch (m_rtc_index)
+ if ((m_io_regs[0x0a / 2] & 0xff) == 0x95 && (m_rtc_index < 7))
{
- case 0: value = m_rtc_year; break;
- case 1: value = m_rtc_month; break;
- case 2: value = m_rtc_day; break;
- case 3: value = m_rtc_day_of_week; break;
- case 4: value = m_rtc_hour; break;
- case 5: value = m_rtc_minute; break;
- case 6: value = m_rtc_second; break;
+ switch (m_rtc_index)
+ {
+ case 0: value = (value & 0xff) | (m_rtc_year << 8); break;
+ case 1: value = (value & 0xff) | (m_rtc_month << 8); break;
+ case 2: value = (value & 0xff) | (m_rtc_day << 8); break;
+ case 3: value = (value & 0xff) | (m_rtc_day_of_week << 8); break;
+ case 4: value = (value & 0xff) | (m_rtc_hour << 8); break;
+ case 5: value = (value & 0xff) | (m_rtc_minute << 8); break;
+ case 6: value = (value & 0xff) | (m_rtc_second << 8); break;
+ }
+ m_rtc_index++;
}
- m_rtc_index++;
}
break;
}
@@ -254,146 +295,164 @@ uint8_t ws_rom_device::read_io(offs_t offset)
return value;
}
-void ws_rom_device::write_io(offs_t offset, uint8_t data)
+void ws_rom_device::write_io(offs_t offset, u16 data, u16 mem_mask)
{
switch (offset)
{
- case 0x00:
- // Bit 0-3 - ROM bank base register for segments 3-15
+ case 0x00 / 2:
+ // Bit 0-3 - ROM bank base register for segments 4-15
// Bit 4-7 - Unknown
- data = ((data & 0x0f) << 4) | 4;
- m_base40 = ((data & m_bank_mask) << 16) & (m_rom_size - 1);
- break;
- case 0x02: // ROM bank for segment 2 (0x20000 - 0x2ffff)
- m_base20 = ((data & m_bank_mask) << 16) & (m_rom_size - 1);
- break;
- case 0x03: // ROM bank for segment 3 (0x30000 - 0x3ffff)
- m_base30 = ((data & m_bank_mask) << 16) & (m_rom_size - 1);
+ if (ACCESSING_BITS_0_7)
+ {
+ m_base40 = (((((data & 0x0f) << 4) | 4) & m_bank_mask) << 15) & m_rom_mask;
+ }
break;
- case 0x0a: // RTC Command
- // Bit 0-4 - RTC command
- // 10000 - Reset
- // 10010 - Write timer settings (alarm)
- // 10011 - Read timer settings (alarm)
- // 10100 - Set time/date
- // 10101 - Get time/date
- // Bit 5-6 - Unknown
- // Bit 7 - Command done (read only)
- if (!m_has_rtc)
- break;
-
- switch (data)
+ case 0x02 / 2:
+ // ROM bank for segment 2 (0x20000 - 0x2ffff)
+ if (ACCESSING_BITS_0_7)
{
- case 0x10: // Reset
- m_rtc_index = 8;
- m_rtc_year = 0;
- m_rtc_month = 1;
- m_rtc_day = 1;
- m_rtc_day_of_week = 0;
- m_rtc_hour = 0;
- m_rtc_minute = 0;
- m_rtc_second = 0;
- m_rtc_setting = 0xff;
- data |= 0x80;
- break;
- case 0x12: // Write Timer Settings (Alarm)
- m_rtc_index = 8;
- m_rtc_setting = m_io_regs[0x0b];
- data |= 0x80;
- break;
- case 0x13: // Read Timer Settings (Alarm)
- m_rtc_index = 8;
- m_io_regs[0x0b] = m_rtc_setting;
- data |= 0x80;
- break;
- case 0x14: // Set Time/Date
- m_rtc_year = m_io_regs[0x0b];
- m_rtc_index = 1;
- data |= 0x80;
- break;
- case 0x15: // Get Time/Date
- m_rtc_index = 0;
- data |= 0x80;
- m_io_regs[0x0b] = m_rtc_year;
- break;
- default:
- logerror( "Unknown RTC command (%X) requested\n", data);
+ m_base20 = (((data & 0xff) & m_bank_mask) << 15) & m_rom_mask;
+ }
+ // ROM bank for segment 3 (0x30000 - 0x3ffff)
+ if (ACCESSING_BITS_8_15)
+ {
+ m_base30 = (((data >> 8) & m_bank_mask) << 15) & m_rom_mask;
}
break;
- case 0x0b: // RTC Data
+ case 0x0a / 2:
if (!m_has_rtc)
break;
-
- if (m_io_regs[0x0a] == 0x94 && m_rtc_index < 7)
+ // RTC Command
+ // Bit 0-4 - RTC command
+ // 10000 - Reset
+ // 10010 - Write timer settings (alarm)
+ // 10011 - Read timer settings (alarm)
+ // 10100 - Set time/date
+ // 10101 - Get time/date
+ // Bit 5-6 - Unknown
+ // Bit 7 - Command done (read only)
+ if (ACCESSING_BITS_0_7)
+ {
+ switch (data & 0xff)
+ {
+ case 0x10: // Reset
+ m_rtc_index = 8;
+ m_rtc_year = 0;
+ m_rtc_month = 1;
+ m_rtc_day = 1;
+ m_rtc_day_of_week = 0;
+ m_rtc_hour = 0;
+ m_rtc_minute = 0;
+ m_rtc_second = 0;
+ m_rtc_setting = 0xff;
+ data |= 0x80;
+ break;
+ case 0x12: // Write Timer Settings (Alarm)
+ m_rtc_index = 8;
+ m_rtc_setting = m_io_regs[0x0a / 2] >> 8;
+ data |= 0x80;
+ break;
+ case 0x13: // Read Timer Settings (Alarm)
+ m_rtc_index = 8;
+ m_io_regs[0x0a / 2] = (m_io_regs[0x0a / 2] & 0x00ff) | (m_rtc_setting << 8);
+ data |= 0x80;
+ break;
+ case 0x14: // Set Time/Date
+ m_rtc_year = m_io_regs[0x0a / 2] >> 8;
+ m_rtc_index = 1;
+ data |= 0x80;
+ break;
+ case 0x15: // Get Time/Date
+ m_rtc_index = 0;
+ data |= 0x80;
+ m_io_regs[0x0a / 2] = (m_io_regs[0x0a / 2] & 0x00ff) | (m_rtc_year << 8);
+ break;
+ default:
+ logerror( "Unknown RTC command (%X) requested\n", data & 0xff);
+ }
+ }
+ // RTC Data
+ if (ACCESSING_BITS_8_15)
{
- switch (m_rtc_index)
+ if ((m_io_regs[0x0a / 2] & 0xff) == 0x94 && m_rtc_index < 7)
{
- case 0: m_rtc_year = data; break;
- case 1: m_rtc_month = data; break;
- case 2: m_rtc_day = data; break;
- case 3: m_rtc_day_of_week = data; break;
- case 4: m_rtc_hour = data; break;
- case 5: m_rtc_minute = data; break;
- case 6: m_rtc_second = data; break;
+ switch (m_rtc_index)
+ {
+ case 0: m_rtc_year = data >> 8; break;
+ case 1: m_rtc_month = data >> 8; break;
+ case 2: m_rtc_day = data >> 8; break;
+ case 3: m_rtc_day_of_week = data >> 8; break;
+ case 4: m_rtc_hour = data >> 8; break;
+ case 5: m_rtc_minute = data >> 8; break;
+ case 6: m_rtc_second = data >> 8; break;
+ }
+ m_rtc_index++;
}
- m_rtc_index++;
}
break;
}
- m_io_regs[offset] = data;
+ COMBINE_DATA(&m_io_regs[offset]);
}
-uint8_t ws_rom_sram_device::read_ram(offs_t offset)
+u16 ws_rom_sram_device::read_ram(offs_t offset, u16 mem_mask)
{
- return m_nvram[m_nvram_base + offset];
+ u32 nvram_address = (m_nvram_base + (offset << 1)) & (m_nvram_size - 1);
+ return m_nvram[nvram_address] | (m_nvram[nvram_address + 1] << 8);
}
-void ws_rom_sram_device::write_ram(offs_t offset, uint8_t data)
+void ws_rom_sram_device::write_ram(offs_t offset, u16 data, u16 mem_mask)
{
- m_nvram[m_nvram_base + offset] = data;
+ u32 nvram_address = (m_nvram_base + (offset << 1)) & (m_nvram_size - 1);
+ if (ACCESSING_BITS_0_7)
+ m_nvram[nvram_address] = data & 0xff;
+ if (ACCESSING_BITS_8_15)
+ m_nvram[nvram_address + 1] = data >> 8;
}
-void ws_rom_sram_device::write_io(offs_t offset, uint8_t data)
+void ws_rom_sram_device::write_io(offs_t offset, u16 data, u16 mem_mask)
{
switch (offset)
{
- case 0x01: // SRAM bank to select
- m_nvram_base = (data * 0x10000) & (m_nvram.size() - 1);
+ case 0x00 / 2:
+ // SRAM bank to select
+ if (ACCESSING_BITS_8_15)
+ {
+ m_nvram_base = ((data >> 8) * 0x10000) & (m_nvram.size() - 1);
+ }
[[fallthrough]];
default:
- ws_rom_device::write_io(offset, data);
+ ws_rom_device::write_io(offset, data, mem_mask);
break;
}
}
-uint8_t ws_rom_eeprom_device::read_io(offs_t offset)
+u16 ws_rom_eeprom_device::read_io(offs_t offset, u16 mem_mask)
{
- uint8_t value = m_io_regs[offset];
+ u16 value = m_io_regs[offset];
switch (offset)
{
- case 0x04:
- case 0x05:
- case 0x06:
- case 0x07:
- case 0x08:
+ case 0x04 / 2:
+ case 0x06 / 2:
+ case 0x08 / 2:
// EEPROM reads, taken from regs
break;
default:
- value = ws_rom_device::read_io(offset);
+ value = ws_rom_device::read_io(offset, mem_mask);
break;
}
return value;
}
-void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data)
+void ws_rom_eeprom_device::write_io(offs_t offset, u16 data, u16 mem_mask)
{
switch (offset)
{
- case 0x06: /* EEPROM address lower bits port/EEPROM address and command port
+ case 0x06 / 2:
+ /* EEPROM address lower bits port/EEPROM address and command port
1KBit EEPROM:
Bit 0-5 - EEPROM address bit 1-6
Bit 6-7 - Command
@@ -408,27 +467,28 @@ void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data)
16KBit EEPROM:
Bit 0-7 - EEPROM address bit 1-8
*/
- switch (m_eeprom_mode)
+ if (ACCESSING_BITS_0_7)
{
- case EEPROM_1K:
+ switch (m_eeprom_mode)
+ {
+ case EEPROM_1K:
m_eeprom_address = data & 0x3f;
- m_eeprom_command = data >> 4;
- if ((m_eeprom_command & 0x0c) != 0x00)
- m_eeprom_command = m_eeprom_command & 0x0c;
- break;
+ m_eeprom_command = (data >> 4) & 0x0f;
+ if ((m_eeprom_command & 0x0c) != 0x00)
+ m_eeprom_command = m_eeprom_command & 0x0c;
+ break;
- case EEPROM_8K:
- case EEPROM_16K:
- m_eeprom_address = (m_eeprom_address & 0xff00) | data;
- break;
+ case EEPROM_8K:
+ case EEPROM_16K:
+ m_eeprom_address = (m_eeprom_address & 0xff00) | (data & 0xff);
+ break;
- default:
- logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" );
- break;
+ default:
+ logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" );
+ break;
+ }
}
- break;
-
- case 0x07: /* EEPROM higher bits/command bits port
+ /* EEPROM higher bits/command bits port
1KBit EEPROM:
Bit 0 - Start
Bit 1-7 - Unknown
@@ -446,35 +506,39 @@ void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data)
Bit 4 - Start
Bit 5-7 - Unknown
*/
- switch (m_eeprom_mode)
+ if (ACCESSING_BITS_8_15)
{
- case EEPROM_1K:
- m_eeprom_start = data & 0x01;
- break;
+ switch (m_eeprom_mode)
+ {
+ case EEPROM_1K:
+ m_eeprom_start = (data >> 8) & 0x01;
+ break;
- case EEPROM_8K:
- m_eeprom_address = ((data & 0x01) << 8) | (m_eeprom_address & 0xff);
- m_eeprom_command = data & 0x0f;
- if ((m_eeprom_command & 0x0c) != 0x00)
- m_eeprom_command = m_eeprom_command & 0x0c;
- m_eeprom_start = (data >> 4) & 0x01;
- break;
+ case EEPROM_8K:
+ m_eeprom_address = (data & 0x0100) | (m_eeprom_address & 0xff);
+ m_eeprom_command = (data >> 8) & 0x0f;
+ if ((m_eeprom_command & 0x0c) != 0x00)
+ m_eeprom_command = m_eeprom_command & 0x0c;
+ m_eeprom_start = (data >> 12) & 0x01;
+ break;
- case EEPROM_16K:
- m_eeprom_address = ((data & 0x03) << 8) | (m_eeprom_address & 0xff);
- m_eeprom_command = data & 0x0f;
- if ((m_eeprom_command & 0x0c) != 0x00)
- m_eeprom_command = m_eeprom_command & 0x0c;
- m_eeprom_start = (data >> 4) & 0x01;
- break;
+ case EEPROM_16K:
+ m_eeprom_address = (data & 0x0300) | (m_eeprom_address & 0xff);
+ m_eeprom_command = (data >> 8) & 0x0f;
+ if ((m_eeprom_command & 0x0c) != 0x00)
+ m_eeprom_command = m_eeprom_command & 0x0c;
+ m_eeprom_start = (data >> 12) & 0x01;
+ break;
- default:
- logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" );
- break;
+ default:
+ logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" );
+ break;
+ }
}
break;
- case 0x08: /* EEPROM command
+ case 0x08 / 2:
+ /* EEPROM command
Bit 0 - Read complete (read only)
Bit 1 - Write complete (read only)
Bit 2-3 - Unknown
@@ -483,57 +547,200 @@ void ws_rom_eeprom_device::write_io(offs_t offset, uint8_t data)
Bit 6 - Protect
Bit 7 - Initialize
*/
- if (data & 0x80) // Initialize
- logerror("Unsupported EEPROM command 'Initialize'\n");
-
- if (data & 0x40) // Protect
+ if (ACCESSING_BITS_0_7)
{
- switch (m_eeprom_command)
- {
- case 0x00:
- m_eeprom_write_enabled = 0;
- data |= 0x02;
- break;
- case 0x03:
- m_eeprom_write_enabled = 1;
- data |= 0x02;
- break;
- default:
- logerror("Unsupported 'Protect' command %X\n", m_eeprom_command);
- break;
- }
- }
+ if (data & 0x80) // Initialize
+ logerror("Unsupported EEPROM command 'Initialize'\n");
- if (data & 0x20) // Write
- {
- if (m_eeprom_write_enabled)
+ if (data & 0x40) // Protect
{
switch (m_eeprom_command)
{
- case 0x04:
- m_nvram[(m_eeprom_address << 1) + 1] = m_io_regs[0x04];
- m_nvram[m_eeprom_address << 1] = m_io_regs[0x05];
+ case 0x00:
+ m_eeprom_write_enabled = 0;
+ data |= 0x02;
+ break;
+ case 0x03:
+ m_eeprom_write_enabled = 1;
data |= 0x02;
break;
default:
- logerror("Unsupported 'Write' command %X\n", m_eeprom_command);
+ logerror("Unsupported 'Protect' command %X\n", m_eeprom_command);
break;
}
}
- }
- if (data & 0x10) // Read
- {
- m_io_regs[0x04] = m_nvram[(m_eeprom_address << 1) + 1];
- m_io_regs[0x05] = m_nvram[m_eeprom_address << 1];
- data |= 0x01;
+ if (data & 0x20) // Write
+ {
+ if (m_eeprom_write_enabled)
+ {
+ switch (m_eeprom_command)
+ {
+ case 0x04:
+ m_nvram[(m_eeprom_address << 1) + 1] = m_io_regs[0x04 / 2] & 0xff;
+ m_nvram[m_eeprom_address << 1] = m_io_regs[0x04 / 2] >> 8;
+ data |= 0x02;
+ break;
+ default:
+ logerror("Unsupported 'Write' command %X\n", m_eeprom_command);
+ break;
+ }
+ }
+ }
+
+ if (data & 0x10) // Read
+ {
+ m_io_regs[0x04] = m_nvram[(m_eeprom_address << 1) + 1];
+ m_io_regs[0x05] = m_nvram[m_eeprom_address << 1];
+ data |= 0x01;
+ }
}
break;
default:
- ws_rom_device::write_io(offset, data);
+ ws_rom_device::write_io(offset, data, mem_mask);
break;
}
- m_io_regs[offset] = data;
+ COMBINE_DATA(&m_io_regs[offset]);
+}
+
+
+u16 ws_wwitch_device::read_ram(offs_t offset, u16 mem_mask)
+{
+ if (m_flash_mode == COMMAND_MODE)
+ {
+ if (!machine().side_effects_disabled())
+ {
+ if (m_writing_flash)
+ {
+ m_flash_status ^= 0x40;
+ m_flash_count++;
+ if (m_flash_count > 4) {
+ m_writing_flash = false;
+ m_flash_mode = READ_MODE;
+ }
+ }
+ // After initiating an erase block command the wwitch expects to see bit 7 set
+ if (m_flash_command == 0x30)
+ {
+ m_flash_status |= 0x80;
+ m_flash_mode = READ_MODE;
+ }
+ }
+ return m_flash_status;
+ }
+ if (m_io_regs[0x01] >= 8 && m_io_regs[0x01] < 16)
+ {
+ return m_rom[((m_io_regs[0x01] * 0x8000) | offset) & m_rom_mask];
+ }
+ if (m_io_regs[0x01] < 8)
+ {
+ return ws_rom_sram_device::read_ram(offset, mem_mask);
+ }
+ else
+ {
+ return 0xffff;
+ }
+}
+
+
+void ws_wwitch_device::write_ram(offs_t offset, u16 data, u16 mem_mask)
+{
+ if (m_flash_seq == 0 && offset == (0xaaa >> 1) && ACCESSING_BITS_0_7 && data == 0xaa)
+ {
+ m_flash_seq = 1;
+ }
+ else if (m_flash_seq == 1 && offset == (0x555 >> 1) && ACCESSING_BITS_8_15 && data == 0x55)
+ {
+ m_flash_seq = 2;
+ }
+ else if (m_flash_seq == 2 && offset == (0xaaa >> 1) && ACCESSING_BITS_0_7)
+ {
+ switch (data)
+ {
+ case 0x10: // Chip erase
+ if (m_flash_command == 0x80)
+ {
+ // TODO
+ }
+ break;
+ case 0x20: // Set to fast mode
+ m_flash_command = data;
+ m_flash_mode = COMMAND_MODE;
+ break;
+ case 0x30: // (Erase) block
+ // TODO: Any write to a block address triggers the block erase
+ if (m_flash_command == 0x80)
+ {
+ if ((m_io_regs[0x01] & 0x07) < 7)
+ {
+ u32 block_base = (m_io_regs[0x01] & 0x07) << 15;
+ for (u32 address = 0; address < 0x8000; address++)
+ {
+ m_rom[(block_base | address) & m_rom_mask] = 0xffff;
+ }
+ }
+
+ m_flash_command = data;
+ m_flash_mode = COMMAND_MODE;
+ }
+ break;
+ case 0x80: // Erase (chip or block)
+ m_flash_command = data;
+ break;
+ default: // Unknown command
+ m_flash_command = 0;
+ }
+ m_flash_seq = 0;
+ }
+ else if (m_io_regs[0x01] >= 8 && m_io_regs[0x01] < 15)
+ {
+ if (m_write_flash)
+ {
+ // perform write
+ if (!ACCESSING_BITS_0_7)
+ data |= 0xff;
+ if (!ACCESSING_BITS_8_15)
+ data |= 0xff00;
+ m_rom[((m_io_regs[0x01] * 0x8000) | offset) & m_rom_mask] &= data;
+ m_flash_status = (m_flash_status & 0x7f) | ((data ^ 0x80) & 0x80);
+ m_writing_flash = true;
+ m_flash_count = 0;
+ m_write_flash = false;
+ }
+ else if (m_flash_command == 0x20)
+ {
+ switch (data)
+ {
+ case 0x00:
+ if (m_write_resetting)
+ {
+ m_write_flash = false;
+ m_write_resetting = false;
+ m_flash_mode = READ_MODE;
+ }
+ break;
+ case 0xF0: // Reset from fast mode #2
+ m_write_flash = false;
+ m_write_resetting = false;
+ m_flash_mode = READ_MODE;
+ break;
+ case 0x90: // Reset from fast mode #1
+ m_write_resetting = true;
+ break;
+ case 0xA0: // Fast program
+ if (m_flash_command == 0x20)
+ {
+ m_write_flash = true;
+ m_flash_mode = COMMAND_MODE;
+ }
+ break;
+ }
+ }
+ }
+ else if (m_io_regs[0x01] < 8)
+ {
+ ws_rom_sram_device::write_ram(offset, data, mem_mask);
+ }
}