mirror of
https://github.com/holub/mame
synced 2025-04-17 22:13:04 +03:00
(MESS) wswan.c: converted to use slot devices for carts. [Fabio Priuli]
out of whatsnew: another case of on-cart SRAM & EEPROM pointers removed from the main system...
This commit is contained in:
parent
218bf5c577
commit
66fab3cf5c
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -1725,6 +1725,10 @@ src/emu/bus/wangpc/wangpc.c svneol=native#text/plain
|
||||
src/emu/bus/wangpc/wangpc.h svneol=native#text/plain
|
||||
src/emu/bus/wangpc/wdc.c svneol=native#text/plain
|
||||
src/emu/bus/wangpc/wdc.h svneol=native#text/plain
|
||||
src/emu/bus/wswan/rom.c svneol=native#text/plain
|
||||
src/emu/bus/wswan/rom.h svneol=native#text/plain
|
||||
src/emu/bus/wswan/slot.c svneol=native#text/plain
|
||||
src/emu/bus/wswan/slot.h svneol=native#text/plain
|
||||
src/emu/bus/x68k/x68k_neptunex.c svneol=native#text/plain
|
||||
src/emu/bus/x68k/x68k_neptunex.h svneol=native#text/plain
|
||||
src/emu/bus/x68k/x68k_scsiext.c svneol=native#text/plain
|
||||
|
311
hash/wscolor.xml
311
hash/wscolor.xml
File diff suppressed because it is too large
Load Diff
370
hash/wswan.xml
370
hash/wswan.xml
File diff suppressed because it is too large
Load Diff
@ -1393,3 +1393,15 @@ BUSOBJS += $(BUSOBJ)/vtech/ioexp/carts.o
|
||||
BUSOBJS += $(BUSOBJ)/vtech/ioexp/joystick.o
|
||||
BUSOBJS += $(BUSOBJ)/vtech/ioexp/printer.o
|
||||
endif
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/bus/wswan/slot.h,BUSES += WSWAN
|
||||
#-------------------------------------------------
|
||||
|
||||
ifneq ($(filter WSWAN,$(BUSES)),)
|
||||
OBJDIRS += $(BUSOBJ)/wswan
|
||||
BUSOBJS += $(BUSOBJ)/wswan/slot.o
|
||||
BUSOBJS += $(BUSOBJ)/wswan/rom.o
|
||||
endif
|
||||
|
||||
|
535
src/emu/bus/wswan/rom.c
Normal file
535
src/emu/bus/wswan/rom.c
Normal file
@ -0,0 +1,535 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
|
||||
Bandai Wonderswan / Wonderswan Color cart emulation
|
||||
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "rom.h"
|
||||
|
||||
enum
|
||||
{
|
||||
EEPROM_1K, EEPROM_8K, EEPROM_16K
|
||||
};
|
||||
|
||||
//-------------------------------------------------
|
||||
// ws_rom_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_type WS_ROM_STD = &device_creator<ws_rom_device>;
|
||||
const device_type WS_ROM_SRAM = &device_creator<ws_rom_sram_device>;
|
||||
const device_type WS_ROM_EEPROM = &device_creator<ws_rom_eeprom_device>;
|
||||
|
||||
|
||||
ws_rom_device::ws_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source)
|
||||
: device_t(mconfig, type, name, tag, owner, clock, shortname, source),
|
||||
device_ws_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
ws_rom_device::ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, WS_ROM_STD, "Wonderswan Standard Carts", tag, owner, clock, "ws_rom", __FILE__),
|
||||
device_ws_cart_interface( mconfig, *this )
|
||||
{
|
||||
}
|
||||
|
||||
ws_rom_sram_device::ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: ws_rom_device(mconfig, WS_ROM_SRAM, "Wonderswan Carts w/SRAM", tag, owner, clock, "ws_sram", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ws_rom_eeprom_device::ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: ws_rom_device(mconfig, WS_ROM_EEPROM, "Wonderswan Carts w/EEPROM", tag, owner, clock, "ws_eeprom", __FILE__)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void ws_rom_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_base20));
|
||||
save_item(NAME(m_base30));
|
||||
save_item(NAME(m_base40));
|
||||
save_item(NAME(m_io_regs));
|
||||
|
||||
// Set up RTC timer
|
||||
if (m_has_rtc)
|
||||
{
|
||||
rtc_timer = timer_alloc(TIMER_RTC);
|
||||
rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1));
|
||||
}
|
||||
|
||||
save_item(NAME(m_rtc_setting));
|
||||
save_item(NAME(m_rtc_year));
|
||||
save_item(NAME(m_rtc_month));
|
||||
save_item(NAME(m_rtc_day));
|
||||
save_item(NAME(m_rtc_day_of_week));
|
||||
save_item(NAME(m_rtc_hour));
|
||||
save_item(NAME(m_rtc_minute));
|
||||
save_item(NAME(m_rtc_second));
|
||||
save_item(NAME(m_rtc_index));
|
||||
}
|
||||
|
||||
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);
|
||||
printf("%x - %x - %x\n", m_base20, m_base30, m_base40);
|
||||
|
||||
memset(m_io_regs, 0, sizeof(m_io_regs));
|
||||
|
||||
// Initialize RTC
|
||||
m_rtc_index = 0;
|
||||
m_rtc_year = 0;
|
||||
m_rtc_month = 0;
|
||||
m_rtc_day = 0;
|
||||
m_rtc_day_of_week = 0;
|
||||
m_rtc_hour = 0;
|
||||
m_rtc_minute = 0;
|
||||
m_rtc_second = 0;
|
||||
m_rtc_setting = 0xff;
|
||||
}
|
||||
|
||||
void ws_rom_sram_device::device_start()
|
||||
{
|
||||
save_item(NAME(m_nvram_base));
|
||||
ws_rom_device::device_start();
|
||||
}
|
||||
|
||||
void ws_rom_sram_device::device_reset()
|
||||
{
|
||||
m_nvram_base = 0;
|
||||
ws_rom_device::device_reset();
|
||||
}
|
||||
|
||||
void ws_rom_eeprom_device::device_start()
|
||||
{
|
||||
ws_rom_device::device_start();
|
||||
|
||||
save_item(NAME(m_eeprom_address));
|
||||
save_item(NAME(m_eeprom_command));
|
||||
save_item(NAME(m_eeprom_start));
|
||||
save_item(NAME(m_eeprom_write_enabled));
|
||||
}
|
||||
|
||||
void ws_rom_eeprom_device::device_reset()
|
||||
{
|
||||
m_eeprom_address = 0;
|
||||
m_eeprom_command = 0;
|
||||
m_eeprom_start = 0;
|
||||
m_eeprom_write_enabled = 0;
|
||||
switch (m_nvram.count())
|
||||
{
|
||||
case 0x80:
|
||||
m_eeprom_mode = EEPROM_1K;
|
||||
break;
|
||||
case 0x400:
|
||||
m_eeprom_mode = EEPROM_8K;
|
||||
break;
|
||||
case 0x800:
|
||||
m_eeprom_mode = EEPROM_16K;
|
||||
break;
|
||||
}
|
||||
ws_rom_device::device_reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_timer - handler timer events
|
||||
//-------------------------------------------------
|
||||
|
||||
void ws_rom_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||
{
|
||||
if (id == TIMER_RTC)
|
||||
{
|
||||
// a second passed
|
||||
m_rtc_second++;
|
||||
if ((m_rtc_second & 0x0f) > 9)
|
||||
m_rtc_second = (m_rtc_second & 0xf0) + 0x10;
|
||||
|
||||
// check for minute passed
|
||||
if (m_rtc_second >= 0x60)
|
||||
{
|
||||
m_rtc_second = 0;
|
||||
m_rtc_minute++;
|
||||
if ((m_rtc_minute & 0x0f) > 9)
|
||||
m_rtc_minute = (m_rtc_minute & 0xf0) + 0x10;
|
||||
}
|
||||
|
||||
// check for hour passed
|
||||
if (m_rtc_minute >= 0x60)
|
||||
{
|
||||
m_rtc_minute = 0;
|
||||
m_rtc_hour++;
|
||||
if ((m_rtc_hour & 0x0f) > 9)
|
||||
m_rtc_hour = (m_rtc_hour & 0xf0) + 0x10;
|
||||
if (m_rtc_hour == 0x12)
|
||||
m_rtc_hour |= 0x80;
|
||||
}
|
||||
|
||||
// check for day passed
|
||||
if (m_rtc_hour >= 0x24)
|
||||
{
|
||||
m_rtc_hour = 0;
|
||||
m_rtc_day++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
mapper specific handlers
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(ws_rom_device::read_rom20)
|
||||
{
|
||||
return m_rom[offset + m_base20];
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(ws_rom_device::read_rom30)
|
||||
{
|
||||
return m_rom[offset + m_base30];
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(ws_rom_device::read_rom40)
|
||||
{
|
||||
// we still need to mask in some cases, e.g. when game is 512K
|
||||
return m_rom[(offset + m_base40) & (m_rom_size - 1)];
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(ws_rom_device::read_io)
|
||||
{
|
||||
UINT8 value = m_io_regs[offset];
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x0b: // RTC data
|
||||
if (!m_has_rtc)
|
||||
break;
|
||||
|
||||
if (m_io_regs[0x0a] == 0x95 && (m_rtc_index < 7))
|
||||
{
|
||||
switch (m_rtc_index)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_rtc_index++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(ws_rom_device::write_io)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x00:
|
||||
// Bit 0-3 - ROM bank base register for segments 3-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);
|
||||
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 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);
|
||||
}
|
||||
break;
|
||||
case 0x0b: // RTC Data
|
||||
if (!m_has_rtc)
|
||||
break;
|
||||
|
||||
if (m_io_regs[0x0a] == 0x94 && m_rtc_index < 7)
|
||||
{
|
||||
switch (m_rtc_index)
|
||||
{
|
||||
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;
|
||||
}
|
||||
m_rtc_index++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
m_io_regs[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(ws_rom_sram_device::read_ram)
|
||||
{
|
||||
return m_nvram[m_nvram_base + offset];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(ws_rom_sram_device::write_ram)
|
||||
{
|
||||
m_nvram[m_nvram_base + offset] = data;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(ws_rom_sram_device::write_io)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x01: // SRAM bank to select
|
||||
m_nvram_base = (data * 0x10000) & (m_nvram.count() - 1);
|
||||
default:
|
||||
ws_rom_device::write_io(space, offset, data);
|
||||
break;
|
||||
}
|
||||
|
||||
m_io_regs[offset] = data;
|
||||
}
|
||||
|
||||
READ8_MEMBER(ws_rom_eeprom_device::read_ram)
|
||||
{
|
||||
return m_nvram[offset & (m_nvram.count() - 1)];
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(ws_rom_eeprom_device::write_ram)
|
||||
{
|
||||
m_nvram[offset & (m_nvram.count() - 1)] = data;
|
||||
}
|
||||
|
||||
|
||||
READ8_MEMBER(ws_rom_eeprom_device::read_io)
|
||||
{
|
||||
UINT8 value = m_io_regs[offset];
|
||||
|
||||
switch (offset)
|
||||
{
|
||||
case 0x04:
|
||||
case 0x05:
|
||||
case 0x06:
|
||||
case 0x07:
|
||||
case 0x08:
|
||||
// EEPROM reads, taken from regs
|
||||
break;
|
||||
default:
|
||||
value = ws_rom_device::read_io(space, offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER(ws_rom_eeprom_device::write_io)
|
||||
{
|
||||
switch (offset)
|
||||
{
|
||||
case 0x06: /* EEPROM address lower bits port/EEPROM address and command port
|
||||
1KBit EEPROM:
|
||||
Bit 0-5 - EEPROM address bit 1-6
|
||||
Bit 6-7 - Command
|
||||
00 - Extended command address bit 4-5:
|
||||
00 - Write disable
|
||||
01 - Write all
|
||||
10 - Erase all
|
||||
11 - Write enable
|
||||
01 - Write
|
||||
10 - Read
|
||||
11 - Erase
|
||||
16KBit EEPROM:
|
||||
Bit 0-7 - EEPROM address bit 1-8
|
||||
*/
|
||||
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;
|
||||
|
||||
case EEPROM_8K:
|
||||
case EEPROM_16K:
|
||||
m_eeprom_address = (m_eeprom_address & 0xff00) | data;
|
||||
break;
|
||||
|
||||
default:
|
||||
logerror( "Write EEPROM address/register register C6 for unsupported EEPROM type\n" );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x07: /* EEPROM higher bits/command bits port
|
||||
1KBit EEPROM:
|
||||
Bit 0 - Start
|
||||
Bit 1-7 - Unknown
|
||||
16KBit EEPROM:
|
||||
Bit 0-1 - EEPROM address bit 9-10
|
||||
Bit 2-3 - Command
|
||||
00 - Extended command address bit 0-1:
|
||||
00 - Write disable
|
||||
01 - Write all
|
||||
10 - Erase all
|
||||
11 - Write enable
|
||||
01 - Write
|
||||
10 - Read
|
||||
11 - Erase
|
||||
Bit 4 - Start
|
||||
Bit 5-7 - Unknown
|
||||
*/
|
||||
switch (m_eeprom_mode)
|
||||
{
|
||||
case EEPROM_1K:
|
||||
m_eeprom_start = data & 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_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;
|
||||
|
||||
default:
|
||||
logerror( "Write EEPROM address/command register C7 for unsupported EEPROM type\n" );
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08: /* EEPROM command
|
||||
Bit 0 - Read complete (read only)
|
||||
Bit 1 - Write complete (read only)
|
||||
Bit 2-3 - Unknown
|
||||
Bit 4 - Read
|
||||
Bit 5 - Write
|
||||
Bit 6 - Protect
|
||||
Bit 7 - Initialize
|
||||
*/
|
||||
if (data & 0x80) // Initialize
|
||||
logerror("Unsupported EEPROM command 'Initialize'\n");
|
||||
|
||||
if (data & 0x40) // Protect
|
||||
{
|
||||
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 & 0x20) // Write
|
||||
{
|
||||
if (m_eeprom_write_enabled)
|
||||
{
|
||||
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];
|
||||
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(space, offset, data);
|
||||
break;
|
||||
}
|
||||
|
||||
m_io_regs[offset] = data;
|
||||
}
|
106
src/emu/bus/wswan/rom.h
Normal file
106
src/emu/bus/wswan/rom.h
Normal file
@ -0,0 +1,106 @@
|
||||
#ifndef __WS_ROM_H
|
||||
#define __WS_ROM_H
|
||||
|
||||
#include "slot.h"
|
||||
|
||||
|
||||
// ======================> ws_rom_device
|
||||
|
||||
class ws_rom_device : public device_t,
|
||||
public device_ws_cart_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
ws_rom_device(const machine_config &mconfig, device_type type, const char *name, const char *tag, device_t *owner, UINT32 clock, const char *shortname, const char *source);
|
||||
ws_rom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_rom20);
|
||||
virtual DECLARE_READ8_MEMBER(read_rom30);
|
||||
virtual DECLARE_READ8_MEMBER(read_rom40);
|
||||
virtual DECLARE_READ8_MEMBER(read_io);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_io);
|
||||
|
||||
protected:
|
||||
UINT8 m_io_regs[0x10];
|
||||
UINT32 m_base20, m_base30, m_base40;
|
||||
|
||||
// RTC
|
||||
UINT8 m_rtc_setting; /* Timer setting byte */
|
||||
UINT8 m_rtc_year; /* Year */
|
||||
UINT8 m_rtc_month; /* Month */
|
||||
UINT8 m_rtc_day; /* Day */
|
||||
UINT8 m_rtc_day_of_week; /* Day of the week */
|
||||
UINT8 m_rtc_hour; /* Hour, high bit = 0 => AM, high bit = 1 => PM */
|
||||
UINT8 m_rtc_minute; /* Minute */
|
||||
UINT8 m_rtc_second; /* Second */
|
||||
UINT8 m_rtc_index; /* index for reading/writing of current of alarm time */
|
||||
|
||||
static const device_timer_id TIMER_RTC = 0;
|
||||
emu_timer *rtc_timer;
|
||||
};
|
||||
|
||||
|
||||
// ======================> ws_rom_sram_device
|
||||
|
||||
class ws_rom_sram_device : public ws_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
ws_rom_sram_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_io);
|
||||
|
||||
private:
|
||||
UINT32 m_nvram_base;
|
||||
};
|
||||
|
||||
|
||||
// ======================> ws_rom_eeprom_device
|
||||
|
||||
class ws_rom_eeprom_device : public ws_rom_device
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
ws_rom_eeprom_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||
virtual DECLARE_READ8_MEMBER(read_io);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_io);
|
||||
|
||||
private:
|
||||
UINT8 m_eeprom_mode; /* eeprom mode */
|
||||
UINT16 m_eeprom_address; /* Read/write address */
|
||||
UINT8 m_eeprom_command; /* Commands: 00, 01, 02, 03, 04, 08, 0C */
|
||||
UINT8 m_eeprom_start; /* start bit */
|
||||
UINT8 m_eeprom_write_enabled; /* write enabled yes/no */
|
||||
int m_eeprom_size; /* size of eeprom/sram area */
|
||||
};
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type WS_ROM_STD;
|
||||
extern const device_type WS_ROM_SRAM;
|
||||
extern const device_type WS_ROM_EEPROM;
|
||||
|
||||
|
||||
#endif
|
491
src/emu/bus/wswan/slot.c
Normal file
491
src/emu/bus/wswan/slot.c
Normal file
@ -0,0 +1,491 @@
|
||||
/***********************************************************************************************************
|
||||
|
||||
Bandai Wonderswan / Wonderswan Color cart emulation
|
||||
(through slot devices)
|
||||
|
||||
***********************************************************************************************************/
|
||||
|
||||
|
||||
#include "emu.h"
|
||||
#include "slot.h"
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
const device_type WS_CART_SLOT = &device_creator<ws_cart_slot_device>;
|
||||
|
||||
//**************************************************************************
|
||||
// Wonderswan Cartridges Interface
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_ws_cart_interface - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_ws_cart_interface::device_ws_cart_interface(const machine_config &mconfig, device_t &device)
|
||||
: device_slot_card_interface(mconfig, device),
|
||||
m_rom(NULL),
|
||||
m_rom_size(0),
|
||||
m_bank_mask(0),
|
||||
m_has_rtc(false),
|
||||
m_is_rotated(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~device_ws_cart_interface - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
device_ws_cart_interface::~device_ws_cart_interface()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// rom_alloc - alloc the space for the cart
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_ws_cart_interface::rom_alloc(UINT32 size, const char *tag)
|
||||
{
|
||||
if (m_rom == NULL)
|
||||
{
|
||||
astring tempstring(tag);
|
||||
tempstring.cat(WSSLOT_ROM_REGION_TAG);
|
||||
m_rom = device().machine().memory().region_alloc(tempstring, size, 1, ENDIANNESS_LITTLE)->base();
|
||||
m_rom_size = size;
|
||||
m_bank_mask = ((m_rom_size >> 16) - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// nvram_alloc - alloc the space for the ram
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_ws_cart_interface::nvram_alloc(UINT32 size)
|
||||
{
|
||||
m_nvram.resize(size);
|
||||
}
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// ws_cart_slot_device - constructor
|
||||
//-------------------------------------------------
|
||||
ws_cart_slot_device::ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock) :
|
||||
device_t(mconfig, WS_CART_SLOT, "Wonderswan Cartridge Slot", tag, owner, clock, "ws_cart_slot", __FILE__),
|
||||
device_image_interface(mconfig, *this),
|
||||
device_slot_interface(mconfig, *this),
|
||||
m_type(WS_STD)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ws_cart_slot_device - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
ws_cart_slot_device::~ws_cart_slot_device()
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void ws_cart_slot_device::device_start()
|
||||
{
|
||||
m_cart = dynamic_cast<device_ws_cart_interface *>(get_card_device());
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_config_complete - perform any
|
||||
// operations now that the configuration is
|
||||
// complete
|
||||
//-------------------------------------------------
|
||||
|
||||
void ws_cart_slot_device::device_config_complete()
|
||||
{
|
||||
// set brief and instance name
|
||||
update_names();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// WSWAN PCB
|
||||
//-------------------------------------------------
|
||||
|
||||
struct ws_slot
|
||||
{
|
||||
int pcb_id;
|
||||
const char *slot_option;
|
||||
};
|
||||
|
||||
// Here, we take the feature attribute from .xml (i.e. the PCB name) and we assign a unique ID to it
|
||||
static const ws_slot slot_list[] =
|
||||
{
|
||||
{ WS_STD, "ws_rom" },
|
||||
{ WS_SRAM, "ws_sram" },
|
||||
{ WS_EEPROM, "ws_eeprom" }
|
||||
};
|
||||
|
||||
static int ws_get_pcb_id(const char *slot)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||
{
|
||||
if (!core_stricmp(slot_list[i].slot_option, slot))
|
||||
return slot_list[i].pcb_id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *ws_get_slot(int type)
|
||||
{
|
||||
for (int i = 0; i < ARRAY_LENGTH(slot_list); i++)
|
||||
{
|
||||
if (slot_list[i].pcb_id == type)
|
||||
return slot_list[i].slot_option;
|
||||
}
|
||||
|
||||
return "std";
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
call load
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool ws_cart_slot_device::call_load()
|
||||
{
|
||||
if (m_cart)
|
||||
{
|
||||
UINT8 *ROM;
|
||||
UINT32 size = (software_entry() == NULL) ? length() : get_software_region_length("rom");
|
||||
UINT32 nvram_size = 0;
|
||||
|
||||
m_cart->rom_alloc(size, tag());
|
||||
ROM = m_cart->get_rom_base();
|
||||
|
||||
if (software_entry() == NULL)
|
||||
fread(ROM, size);
|
||||
else
|
||||
memcpy(ROM, get_software_region("rom"), size);
|
||||
|
||||
if (software_entry() == NULL)
|
||||
{
|
||||
int chunks = size / 0x10000;
|
||||
// get cart type and nvram length
|
||||
m_type = get_cart_type(ROM, size, nvram_size);
|
||||
|
||||
if (ROM[(chunks - 1) * 0x10000 + 0xfffd])
|
||||
m_cart->set_has_rtc(true);
|
||||
if (ROM[(chunks - 1) * 0x10000 + 0xfffc] & 0x01)
|
||||
m_cart->set_is_rotated(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *pcb_name = get_feature("slot");
|
||||
if (pcb_name)
|
||||
m_type = ws_get_pcb_id(pcb_name);
|
||||
|
||||
if (m_type == WS_SRAM)
|
||||
nvram_size = get_software_region_length("sram");
|
||||
if (m_type == WS_EEPROM)
|
||||
nvram_size = get_software_region_length("eeprom");
|
||||
|
||||
if (get_feature("rtc"))
|
||||
{
|
||||
if (!core_stricmp(get_feature("rtc"), "yes"))
|
||||
m_cart->set_has_rtc(true);
|
||||
}
|
||||
if (get_feature("rotated"))
|
||||
{
|
||||
if (!core_stricmp(get_feature("rotated"), "yes"))
|
||||
m_cart->set_is_rotated(true);
|
||||
}
|
||||
}
|
||||
|
||||
//printf("Type: %s\n", ws_get_slot(m_type));
|
||||
|
||||
if (nvram_size)
|
||||
{
|
||||
// allocate NVRAM
|
||||
m_cart->nvram_alloc(nvram_size);
|
||||
// and load possible battery save
|
||||
battery_load(m_cart->get_nvram_base(), m_cart->get_nvram_size(), 0x00);
|
||||
}
|
||||
|
||||
internal_header_logging(ROM, size);
|
||||
}
|
||||
|
||||
return IMAGE_INIT_PASS;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
call_unload
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ws_cart_slot_device::call_unload()
|
||||
{
|
||||
if (m_cart && m_cart->get_nvram_size())
|
||||
battery_save(m_cart->get_nvram_base(), m_cart->get_nvram_size());
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
call softlist load
|
||||
-------------------------------------------------*/
|
||||
|
||||
bool ws_cart_slot_device::call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry)
|
||||
{
|
||||
load_software_part_region(*this, swlist, swname, start_entry);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
get cart type from cart file
|
||||
-------------------------------------------------*/
|
||||
|
||||
int ws_cart_slot_device::get_cart_type(UINT8 *ROM, UINT32 len, UINT32 &nvram_len)
|
||||
{
|
||||
int chunks = len / 0x10000;
|
||||
int type = WS_STD;
|
||||
|
||||
switch (ROM[(chunks - 1) * 0x10000 + 0xfffb])
|
||||
{
|
||||
case 0x00:
|
||||
break;
|
||||
case 0x01: // SRAM 64Kbit
|
||||
type = WS_SRAM;
|
||||
nvram_len = 0x2000;
|
||||
break;
|
||||
case 0x02: // SRAM 256Kbit
|
||||
type = WS_SRAM;
|
||||
nvram_len = 0x8000;
|
||||
break;
|
||||
case 0x05: // SRAM 512Kbit
|
||||
type = WS_SRAM;
|
||||
nvram_len = 0x10000;
|
||||
break;
|
||||
case 0x03: // SRAM 1Mbit
|
||||
type = WS_SRAM;
|
||||
nvram_len = 0x20000;
|
||||
break;
|
||||
case 0x04: // SRAM 2Mbit
|
||||
type = WS_SRAM;
|
||||
nvram_len = 0x40000;
|
||||
break;
|
||||
case 0x10: // EEPROM 1Kbit
|
||||
type = WS_EEPROM;
|
||||
nvram_len = 0x80;
|
||||
break;
|
||||
case 0x50: // EEPROM 8Kbit
|
||||
type = WS_EEPROM;
|
||||
nvram_len = 0x400;
|
||||
break;
|
||||
case 0x20: // EEPROM 16Kbit
|
||||
type = WS_EEPROM;
|
||||
nvram_len = 0x800;
|
||||
break;
|
||||
default:
|
||||
printf("Unknown RAM size [0x%X]\n", ROM[(chunks - 1) * 0x10000 + 0xfffb]);
|
||||
logerror("Unknown RAM size [0x%X]\n", ROM[(chunks - 1) * 0x10000 + 0xfffb]);
|
||||
break;
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
get default card software
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ws_cart_slot_device::get_default_card_software(astring &result)
|
||||
{
|
||||
if (open_image_file(mconfig().options()))
|
||||
{
|
||||
const char *slot_string = "ws_rom";
|
||||
UINT32 size = core_fsize(m_file);
|
||||
dynamic_buffer rom(size);
|
||||
int type;
|
||||
UINT32 nvram;
|
||||
|
||||
core_fread(m_file, rom, size);
|
||||
|
||||
// nvram size is not really used here, but we set it up nevertheless
|
||||
type = get_cart_type(rom, size, nvram);
|
||||
slot_string = ws_get_slot(type);
|
||||
|
||||
//printf("type: %s\n", slot_string);
|
||||
clear();
|
||||
|
||||
result.cpy(slot_string);
|
||||
return;
|
||||
}
|
||||
|
||||
software_get_default_slot(result, "ws_rom");
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_rom20
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(ws_cart_slot_device::read_rom20)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_rom20(space, offset);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_rom30
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(ws_cart_slot_device::read_rom30)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_rom30(space, offset);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_rom40
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(ws_cart_slot_device::read_rom40)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_rom40(space, offset);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_ram
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(ws_cart_slot_device::read_ram)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_ram(space, offset);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
write_ram
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(ws_cart_slot_device::write_ram)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->write_ram(space, offset, data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
read_io
|
||||
-------------------------------------------------*/
|
||||
|
||||
READ8_MEMBER(ws_cart_slot_device::read_io)
|
||||
{
|
||||
if (m_cart)
|
||||
return m_cart->read_io(space, offset);
|
||||
else
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
write_io
|
||||
-------------------------------------------------*/
|
||||
|
||||
WRITE8_MEMBER(ws_cart_slot_device::write_io)
|
||||
{
|
||||
if (m_cart)
|
||||
m_cart->write_io(space, offset, data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------------------------------------
|
||||
Internal header logging
|
||||
-------------------------------------------------*/
|
||||
|
||||
void ws_cart_slot_device::internal_header_logging(UINT8 *ROM, UINT32 len)
|
||||
{
|
||||
#if 0
|
||||
enum enum_sram { SRAM_NONE=0, SRAM_64K, SRAM_256K, SRAM_512K, SRAM_1M, SRAM_2M, EEPROM_1K, EEPROM_16K, EEPROM_8K, SRAM_UNKNOWN };
|
||||
static const char *const wswan_sram_str[] = { "none", "64Kbit SRAM", "256Kbit SRAM", "512Kbit SRAM", "1Mbit SRAM", "2Mbit SRAM", "1Kbit EEPROM", "16Kbit EEPROM", "8Kbit EEPROM", "Unknown" };
|
||||
static const int wswan_sram_size[] = { 0, 64*1024/8, 256*1024/8, 512*1024/8, 1024*1024/8, 2*1024*1024/8, 1024/8, 16*1024/8, 8*1024/8, 0 };
|
||||
|
||||
int sum = 0;
|
||||
/* Spit out some info */
|
||||
logerror("ROM DETAILS\n" );
|
||||
logerror("\tDeveloper ID: %X\n", m_ROMMap[m_ROMBanks - 1][0xfff6]);
|
||||
logerror("\tMinimum system: %s\n", m_ROMMap[m_ROMBanks - 1][0xfff7] ? "WonderSwan Color" : "WonderSwan");
|
||||
logerror("\tCart ID: %X\n", m_ROMMap[m_ROMBanks - 1][0xfff8]);
|
||||
logerror("\tROM size: %s\n", wswan_determine_romsize(m_ROMMap[m_ROMBanks - 1][0xfffa]));
|
||||
logerror("\tSRAM size: %s\n", sram_str);
|
||||
logerror("\tFeatures: %X\n", m_ROMMap[m_ROMBanks - 1][0xfffc]);
|
||||
logerror("\tRTC: %s\n", m_ROMMap[m_ROMBanks - 1][0xfffd] ? "yes" : "no");
|
||||
for (int i = 0; i < m_ROMBanks; i++)
|
||||
{
|
||||
int count;
|
||||
for (count = 0; count < 0x10000; count++)
|
||||
{
|
||||
sum += m_ROMMap[i][count];
|
||||
}
|
||||
}
|
||||
sum -= m_ROMMap[m_ROMBanks - 1][0xffff];
|
||||
sum -= m_ROMMap[m_ROMBanks - 1][0xfffe];
|
||||
sum &= 0xffff;
|
||||
logerror("\tChecksum: %X%X (calculated: %04X)\n", m_ROMMap[m_ROMBanks - 1][0xffff], m_ROMMap[m_ROMBanks - 1][0xfffe], sum);
|
||||
|
||||
const char* wswan_state::wswan_determine_sram(UINT8 data )
|
||||
{
|
||||
m_eeprom.write_enabled = 0;
|
||||
m_eeprom.mode = SRAM_UNKNOWN;
|
||||
switch( data )
|
||||
{
|
||||
case 0x00: m_eeprom.mode = SRAM_NONE; break;
|
||||
case 0x01: m_eeprom.mode = SRAM_64K; break;
|
||||
case 0x02: m_eeprom.mode = SRAM_256K; break;
|
||||
case 0x03: m_eeprom.mode = SRAM_1M; break;
|
||||
case 0x04: m_eeprom.mode = SRAM_2M; break;
|
||||
case 0x05: m_eeprom.mode = SRAM_512K; break;
|
||||
case 0x10: m_eeprom.mode = EEPROM_1K; break;
|
||||
case 0x20: m_eeprom.mode = EEPROM_16K; break;
|
||||
case 0x50: m_eeprom.mode = EEPROM_8K; break;
|
||||
}
|
||||
m_eeprom.size = wswan_sram_size[ m_eeprom.mode ];
|
||||
return wswan_sram_str[ m_eeprom.mode ];
|
||||
}
|
||||
|
||||
enum enum_romsize { ROM_4M=0, ROM_8M, ROM_16M, ROM_32M, ROM_64M, ROM_128M, ROM_UNKNOWN };
|
||||
static const char *const wswan_romsize_str[] = {
|
||||
"4Mbit", "8Mbit", "16Mbit", "32Mbit", "64Mbit", "128Mbit", "Unknown"
|
||||
};
|
||||
|
||||
const char* wswan_state::wswan_determine_romsize( UINT8 data )
|
||||
{
|
||||
switch( data )
|
||||
{
|
||||
case 0x02: return wswan_romsize_str[ ROM_4M ];
|
||||
case 0x03: return wswan_romsize_str[ ROM_8M ];
|
||||
case 0x04: return wswan_romsize_str[ ROM_16M ];
|
||||
case 0x06: return wswan_romsize_str[ ROM_32M ];
|
||||
case 0x08: return wswan_romsize_str[ ROM_64M ];
|
||||
case 0x09: return wswan_romsize_str[ ROM_128M ];
|
||||
}
|
||||
return wswan_romsize_str[ ROM_UNKNOWN ];
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
130
src/emu/bus/wswan/slot.h
Normal file
130
src/emu/bus/wswan/slot.h
Normal file
@ -0,0 +1,130 @@
|
||||
#ifndef __WS_SLOT_H
|
||||
#define __WS_SLOT_H
|
||||
|
||||
/***************************************************************************
|
||||
TYPE DEFINITIONS
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/* PCB */
|
||||
enum
|
||||
{
|
||||
WS_STD = 0,
|
||||
WS_SRAM,
|
||||
WS_EEPROM
|
||||
};
|
||||
|
||||
|
||||
// ======================> device_ws_cart_interface
|
||||
|
||||
class device_ws_cart_interface : public device_slot_card_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
device_ws_cart_interface(const machine_config &mconfig, device_t &device);
|
||||
virtual ~device_ws_cart_interface();
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_rom20) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_rom30) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_rom40) { return 0xff; }
|
||||
virtual DECLARE_READ8_MEMBER(read_ram) { return 0xff; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write_ram) {}
|
||||
virtual DECLARE_READ8_MEMBER(read_io) { return 0xff; }
|
||||
virtual DECLARE_WRITE8_MEMBER(write_io) {}
|
||||
|
||||
void rom_alloc(UINT32 size, const char *tag);
|
||||
void nvram_alloc(UINT32 size);
|
||||
UINT8* get_rom_base() { return m_rom; }
|
||||
UINT8* get_nvram_base() { return m_nvram; }
|
||||
UINT32 get_rom_size() { return m_rom_size; }
|
||||
UINT32 get_nvram_size() { return m_nvram.count(); }
|
||||
|
||||
void save_nvram() { device().save_item(NAME(m_nvram)); }
|
||||
void set_has_rtc(bool val) { m_has_rtc = val; }
|
||||
void set_is_rotated(bool val) { m_is_rotated = val; }
|
||||
int get_is_rotated() { return m_is_rotated ? 1 : 0; }
|
||||
|
||||
protected:
|
||||
// internal state
|
||||
UINT8 *m_rom;
|
||||
UINT32 m_rom_size;
|
||||
dynamic_buffer m_nvram;
|
||||
int m_bank_mask;
|
||||
|
||||
bool m_has_rtc, m_is_rotated;
|
||||
};
|
||||
|
||||
|
||||
// ======================> ws_cart_slot_device
|
||||
|
||||
class ws_cart_slot_device : public device_t,
|
||||
public device_image_interface,
|
||||
public device_slot_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
ws_cart_slot_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
virtual ~ws_cart_slot_device();
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_config_complete();
|
||||
|
||||
// image-level overrides
|
||||
virtual bool call_load();
|
||||
virtual void call_unload();
|
||||
virtual bool call_softlist_load(software_list_device &swlist, const char *swname, const rom_entry *start_entry);
|
||||
|
||||
int get_type() { return m_type; }
|
||||
int get_is_rotated() { return m_cart->get_is_rotated(); }
|
||||
int get_cart_type(UINT8 *ROM, UINT32 len, UINT32 &nvram_len);
|
||||
void internal_header_logging(UINT8 *ROM, UINT32 len);
|
||||
|
||||
void save_nvram() { if (m_cart && m_cart->get_nvram_size()) m_cart->save_nvram(); }
|
||||
|
||||
virtual iodevice_t image_type() const { return IO_CARTSLOT; }
|
||||
virtual bool is_readable() const { return 1; }
|
||||
virtual bool is_writeable() const { return 0; }
|
||||
virtual bool is_creatable() const { return 0; }
|
||||
virtual bool must_be_loaded() const { return 1; }
|
||||
virtual bool is_reset_on_load() const { return 1; }
|
||||
virtual const option_guide *create_option_guide() const { return NULL; }
|
||||
virtual const char *image_interface() const { return "wswan_cart"; }
|
||||
virtual const char *file_extensions() const { return "ws,wsc,bin"; }
|
||||
|
||||
// slot interface overrides
|
||||
virtual void get_default_card_software(astring &result);
|
||||
|
||||
// reading and writing
|
||||
virtual DECLARE_READ8_MEMBER(read_rom20);
|
||||
virtual DECLARE_READ8_MEMBER(read_rom30);
|
||||
virtual DECLARE_READ8_MEMBER(read_rom40);
|
||||
virtual DECLARE_READ8_MEMBER(read_ram);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_ram);
|
||||
virtual DECLARE_READ8_MEMBER(read_io);
|
||||
virtual DECLARE_WRITE8_MEMBER(write_io);
|
||||
|
||||
protected:
|
||||
|
||||
int m_type;
|
||||
device_ws_cart_interface* m_cart;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type WS_CART_SLOT;
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
DEVICE CONFIGURATION MACROS
|
||||
***************************************************************************/
|
||||
|
||||
#define WSSLOT_ROM_REGION_TAG ":cart:rom"
|
||||
|
||||
#define MCFG_WSWAN_CARTRIDGE_ADD(_tag,_slot_intf,_def_slot) \
|
||||
MCFG_DEVICE_ADD(_tag, WS_CART_SLOT, 0) \
|
||||
MCFG_DEVICE_SLOT_INTERFACE(_slot_intf, _def_slot, false) \
|
||||
|
||||
#endif
|
@ -35,61 +35,35 @@
|
||||
#include "wswan.lh"
|
||||
|
||||
static ADDRESS_MAP_START (wswan_mem, AS_PROGRAM, 8, wswan_state)
|
||||
AM_RANGE(0x00000, 0x03fff) AM_RAM /* 16kb RAM / 4 colour tiles */
|
||||
AM_RANGE(0x04000, 0x0ffff) AM_NOP /* nothing */
|
||||
AM_RANGE(0x10000, 0x1ffff) AM_READWRITE(wswan_sram_r, wswan_sram_w) /* SRAM bank */
|
||||
AM_RANGE(0x20000, 0x2ffff) AM_ROMBANK("rom1") /* ROM bank 1 */
|
||||
AM_RANGE(0x30000, 0x3ffff) AM_ROMBANK("rom2") /* ROM bank 2 */
|
||||
AM_RANGE(0x40000, 0x4ffff) AM_ROMBANK("rom3") /* ROM bank 3 */
|
||||
AM_RANGE(0x50000, 0x5ffff) AM_ROMBANK("rom4") /* ROM bank 4 */
|
||||
AM_RANGE(0x60000, 0x6ffff) AM_ROMBANK("rom5") /* ROM bank 5 */
|
||||
AM_RANGE(0x70000, 0x7ffff) AM_ROMBANK("rom6") /* ROM bank 6 */
|
||||
AM_RANGE(0x80000, 0x8ffff) AM_ROMBANK("rom7") /* ROM bank 7 */
|
||||
AM_RANGE(0x90000, 0x9ffff) AM_ROMBANK("rom8") /* ROM bank 8 */
|
||||
AM_RANGE(0xa0000, 0xaffff) AM_ROMBANK("rom9") /* ROM bank 9 */
|
||||
AM_RANGE(0xb0000, 0xbffff) AM_ROMBANK("rom10") /* ROM bank 10 */
|
||||
AM_RANGE(0xc0000, 0xcffff) AM_ROMBANK("rom11") /* ROM bank 11 */
|
||||
AM_RANGE(0xd0000, 0xdffff) AM_ROMBANK("rom12") /* ROM bank 12 */
|
||||
AM_RANGE(0xe0000, 0xeffff) AM_ROMBANK("rom13") /* ROM bank 13 */
|
||||
AM_RANGE(0xf0000, 0xfffff) AM_ROMBANK("rom14") /* ROM bank 14 */
|
||||
AM_RANGE(0x00000, 0x03fff) AM_RAM // 16kb RAM / 4 colour tiles
|
||||
AM_RANGE(0x04000, 0x0ffff) AM_NOP // nothing
|
||||
//AM_RANGE(0x10000, 0xeffff) // cart range, setup at machine_start
|
||||
AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START (wscolor_mem, AS_PROGRAM, 8, wswan_state)
|
||||
AM_RANGE(0x00000, 0x0ffff) AM_RAM /* 16kb RAM / 4 colour tiles, 16 colour tiles + palettes */
|
||||
AM_RANGE(0x10000, 0x1ffff) AM_READWRITE(wswan_sram_r, wswan_sram_w) /* SRAM bank */
|
||||
AM_RANGE(0x20000, 0x2ffff) AM_ROMBANK("rom1") /* ROM bank 1 */
|
||||
AM_RANGE(0x30000, 0x3ffff) AM_ROMBANK("rom2") /* ROM bank 2 */
|
||||
AM_RANGE(0x40000, 0x4ffff) AM_ROMBANK("rom3") /* ROM bank 3 */
|
||||
AM_RANGE(0x50000, 0x5ffff) AM_ROMBANK("rom4") /* ROM bank 4 */
|
||||
AM_RANGE(0x60000, 0x6ffff) AM_ROMBANK("rom5") /* ROM bank 5 */
|
||||
AM_RANGE(0x70000, 0x7ffff) AM_ROMBANK("rom6") /* ROM bank 6 */
|
||||
AM_RANGE(0x80000, 0x8ffff) AM_ROMBANK("rom7") /* ROM bank 7 */
|
||||
AM_RANGE(0x90000, 0x9ffff) AM_ROMBANK("rom8") /* ROM bank 8 */
|
||||
AM_RANGE(0xa0000, 0xaffff) AM_ROMBANK("rom9") /* ROM bank 9 */
|
||||
AM_RANGE(0xb0000, 0xbffff) AM_ROMBANK("rom10") /* ROM bank 10 */
|
||||
AM_RANGE(0xc0000, 0xcffff) AM_ROMBANK("rom11") /* ROM bank 11 */
|
||||
AM_RANGE(0xd0000, 0xdffff) AM_ROMBANK("rom12") /* ROM bank 12 */
|
||||
AM_RANGE(0xe0000, 0xeffff) AM_ROMBANK("rom13") /* ROM bank 13 */
|
||||
AM_RANGE(0xf0000, 0xfffff) AM_ROMBANK("rom14") /* ROM bank 14 */
|
||||
AM_RANGE(0x00000, 0x0ffff) AM_RAM // 16kb RAM / 4 colour tiles, 16 colour tiles + palettes
|
||||
//AM_RANGE(0x10000, 0xeffff) // cart range, setup at machine_start
|
||||
AM_RANGE(0xf0000, 0xfffff) AM_READ(bios_r)
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static ADDRESS_MAP_START (wswan_io, AS_IO, 8, wswan_state)
|
||||
AM_RANGE(0x00, 0xff) AM_READWRITE(wswan_port_r, wswan_port_w) /* I/O ports */
|
||||
AM_RANGE(0x00, 0xff) AM_READWRITE(port_r, port_w) // I/O ports
|
||||
ADDRESS_MAP_END
|
||||
|
||||
static INPUT_PORTS_START( wswan )
|
||||
PORT_START("CURSX") /* Cursors (X1-X4) */
|
||||
PORT_START("CURSX")
|
||||
PORT_BIT( 0x1, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_NAME("X1 - Up")
|
||||
PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_NAME("X3 - Down")
|
||||
PORT_BIT( 0x8, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_NAME("X4 - Left")
|
||||
PORT_BIT( 0x2, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_NAME("X2 - Right")
|
||||
|
||||
PORT_START("BUTTONS") /* Buttons */
|
||||
PORT_START("BUTTONS")
|
||||
PORT_BIT( 0x2, IP_ACTIVE_HIGH, IPT_START1 ) PORT_NAME("Start")
|
||||
PORT_BIT( 0x4, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("Button A")
|
||||
PORT_BIT( 0x8, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("Button B")
|
||||
|
||||
PORT_START("CURSY") /* Cursors (Y1-Y4) */
|
||||
PORT_START("CURSY")
|
||||
PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Y1 - Up") PORT_CODE(KEYCODE_W)
|
||||
PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Y3 - Down") PORT_CODE(KEYCODE_S)
|
||||
PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_NAME("Y4 - Left") PORT_CODE(KEYCODE_A)
|
||||
@ -102,18 +76,16 @@ GFXDECODE_END
|
||||
/* WonderSwan can display 16 shades of grey */
|
||||
PALETTE_INIT_MEMBER(wswan_state, wswan)
|
||||
{
|
||||
int ii;
|
||||
for (ii = 0; ii < 16; ii++)
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
UINT8 shade = ii * (256 / 16);
|
||||
palette.set_pen_color(15 - ii, shade, shade, shade);
|
||||
UINT8 shade = i * (256 / 16);
|
||||
palette.set_pen_color(15 - i, shade, shade, shade);
|
||||
}
|
||||
}
|
||||
|
||||
PALETTE_INIT_MEMBER(wswan_state,wscolor)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 4096; i++)
|
||||
for (int i = 0; i < 4096; i++)
|
||||
{
|
||||
int r = (i & 0x0f00) >> 8;
|
||||
int g = (i & 0x00f0) >> 4;
|
||||
@ -122,6 +94,12 @@ PALETTE_INIT_MEMBER(wswan_state,wscolor)
|
||||
}
|
||||
}
|
||||
|
||||
static SLOT_INTERFACE_START(wswan_cart)
|
||||
SLOT_INTERFACE_INTERNAL("ws_rom", WS_ROM_STD)
|
||||
SLOT_INTERFACE_INTERNAL("ws_sram", WS_ROM_SRAM)
|
||||
SLOT_INTERFACE_INTERNAL("ws_eeprom", WS_ROM_EEPROM)
|
||||
SLOT_INTERFACE_END
|
||||
|
||||
static MACHINE_CONFIG_START( wswan, wswan_state )
|
||||
/* Basic machine hardware */
|
||||
MCFG_CPU_ADD("maincpu", V30MZ, 3072000)
|
||||
@ -142,7 +120,6 @@ static MACHINE_CONFIG_START( wswan, wswan_state )
|
||||
|
||||
MCFG_NVRAM_ADD_1FILL("nvram")
|
||||
|
||||
|
||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", wswan)
|
||||
MCFG_PALETTE_ADD("palette", 16)
|
||||
MCFG_PALETTE_INIT_OWNER(wswan_state, wswan)
|
||||
@ -154,11 +131,7 @@ static MACHINE_CONFIG_START( wswan, wswan_state )
|
||||
MCFG_SOUND_ROUTE(1, "rspeaker", 0.50)
|
||||
|
||||
/* cartridge */
|
||||
MCFG_CARTSLOT_ADD("cart")
|
||||
MCFG_CARTSLOT_EXTENSION_LIST("ws,wsc,bin")
|
||||
MCFG_CARTSLOT_MANDATORY
|
||||
MCFG_CARTSLOT_INTERFACE("wswan_cart")
|
||||
MCFG_CARTSLOT_LOAD(wswan_state,wswan_cart)
|
||||
MCFG_WSWAN_CARTRIDGE_ADD("cartslot", wswan_cart, NULL)
|
||||
|
||||
/* software lists */
|
||||
MCFG_SOFTWARE_LIST_ADD("cart_list","wswan")
|
||||
@ -174,7 +147,6 @@ static MACHINE_CONFIG_DERIVED( wscolor, wswan )
|
||||
MCFG_PALETTE_ENTRIES(4096)
|
||||
MCFG_PALETTE_INIT_OWNER(wswan_state, wscolor )
|
||||
|
||||
|
||||
/* software lists */
|
||||
MCFG_DEVICE_REMOVE("cart_list")
|
||||
MCFG_DEVICE_REMOVE("wsc_list")
|
||||
@ -199,5 +171,5 @@ ROM_START( wscolor )
|
||||
ROM_END
|
||||
|
||||
/* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME*/
|
||||
CONS( 1999, wswan, 0, 0, wswan, wswan, wswan_state, wswan, "Bandai", "WonderSwan", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
||||
CONS( 2000, wscolor, wswan, 0, wscolor, wswan, wswan_state, wswan, "Bandai", "WonderSwan Color", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
||||
CONS( 1999, wswan, 0, 0, wswan, wswan, driver_device, 0, "Bandai", "WonderSwan", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
||||
CONS( 2000, wscolor, wswan, 0, wscolor, wswan, driver_device, 0, "Bandai", "WonderSwan Color", GAME_IMPERFECT_SOUND | GAME_SUPPORTS_SAVE )
|
||||
|
@ -17,36 +17,11 @@
|
||||
|
||||
#include "emu.h"
|
||||
#include "cpu/v30mz/v30mz.h"
|
||||
#include "imagedev/cartslot.h"
|
||||
#include "machine/nvram.h"
|
||||
#include "bus/wswan/slot.h"
|
||||
#include "bus/wswan/rom.h"
|
||||
|
||||
|
||||
struct EEPROM
|
||||
{
|
||||
UINT8 mode; /* eeprom mode */
|
||||
UINT16 address; /* Read/write address */
|
||||
UINT8 command; /* Commands: 00, 01, 02, 03, 04, 08, 0C */
|
||||
UINT8 start; /* start bit */
|
||||
UINT8 write_enabled; /* write enabled yes/no */
|
||||
int size; /* size of eeprom/sram area */
|
||||
UINT8 *data; /* pointer to start of sram/eeprom data */
|
||||
UINT8 *page; /* pointer to current sram/eeprom page */
|
||||
};
|
||||
|
||||
struct RTC
|
||||
{
|
||||
UINT8 present; /* Is an RTC present */
|
||||
UINT8 setting; /* Timer setting byte */
|
||||
UINT8 year; /* Year */
|
||||
UINT8 month; /* Month */
|
||||
UINT8 day; /* Day */
|
||||
UINT8 day_of_week; /* Day of the week */
|
||||
UINT8 hour; /* Hour, high bit = 0 => AM, high bit = 1 => PM */
|
||||
UINT8 minute; /* Minute */
|
||||
UINT8 second; /* Second */
|
||||
UINT8 index; /* index for reading/writing of current of alarm time */
|
||||
};
|
||||
|
||||
struct SoundDMA
|
||||
{
|
||||
UINT32 source; /* Source address */
|
||||
@ -110,6 +85,7 @@ public:
|
||||
: driver_device(mconfig, type, tag),
|
||||
m_maincpu(*this, "maincpu"),
|
||||
m_sound(*this, "custom"),
|
||||
m_cart(*this, "cartslot"),
|
||||
m_cursx(*this, "CURSX"),
|
||||
m_cursy(*this, "CURSY"),
|
||||
m_buttons(*this, "BUTTONS") { }
|
||||
@ -120,19 +96,15 @@ public:
|
||||
|
||||
required_device<cpu_device> m_maincpu;
|
||||
required_device<wswan_sound_device> m_sound;
|
||||
DECLARE_READ8_MEMBER(wswan_port_r);
|
||||
DECLARE_WRITE8_MEMBER(wswan_port_w);
|
||||
DECLARE_READ8_MEMBER(wswan_sram_r);
|
||||
DECLARE_WRITE8_MEMBER(wswan_sram_w);
|
||||
required_device<ws_cart_slot_device> m_cart;
|
||||
DECLARE_READ8_MEMBER(bios_r);
|
||||
DECLARE_READ8_MEMBER(port_r);
|
||||
DECLARE_WRITE8_MEMBER(port_w);
|
||||
|
||||
VDP m_vdp;
|
||||
UINT8 m_ws_portram[256];
|
||||
UINT8 *m_ROMMap[256];
|
||||
UINT32 m_ROMBanks;
|
||||
UINT8 m_internal_eeprom[INTERNAL_EEPROM_SIZE];
|
||||
UINT8 m_system_type;
|
||||
EEPROM m_eeprom;
|
||||
RTC m_rtc;
|
||||
SoundDMA m_sound_dma;
|
||||
UINT8 *m_ws_ram;
|
||||
UINT8 *m_ws_bios_bank;
|
||||
@ -140,19 +112,15 @@ public:
|
||||
int m_pal[16][16];
|
||||
bitmap_ind16 m_bitmap;
|
||||
UINT8 m_rotate;
|
||||
UINT8 m_bank_base[14];
|
||||
|
||||
void wswan_clear_irq_line(int irq);
|
||||
void common_start();
|
||||
virtual void machine_start();
|
||||
virtual void machine_reset();
|
||||
DECLARE_PALETTE_INIT(wswan);
|
||||
DECLARE_MACHINE_START(wscolor);
|
||||
DECLARE_PALETTE_INIT(wscolor);
|
||||
TIMER_CALLBACK_MEMBER(wswan_rtc_callback);
|
||||
TIMER_CALLBACK_MEMBER(wswan_scanline_interrupt);
|
||||
void wswan_machine_stop();
|
||||
DECLARE_DRIVER_INIT( wswan );
|
||||
DECLARE_DEVICE_IMAGE_LOAD_MEMBER( wswan_cart );
|
||||
|
||||
protected:
|
||||
/* Interrupt flags */
|
||||
@ -178,10 +146,7 @@ protected:
|
||||
required_ioport m_cursx;
|
||||
required_ioport m_cursy;
|
||||
required_ioport m_buttons;
|
||||
memory_bank *m_rom_bank[14];
|
||||
|
||||
void wswan_setup_bios();
|
||||
void wswan_setup_banks();
|
||||
void wswan_register_save();
|
||||
void wswan_postload();
|
||||
void wswan_handle_irqs();
|
||||
@ -193,8 +158,6 @@ protected:
|
||||
void wswan_draw_foreground_3();
|
||||
void wswan_handle_sprites( int mask );
|
||||
void wswan_refresh_scanline( );
|
||||
const char* wswan_determine_sram( UINT8 data );
|
||||
const char* wswan_determine_romsize( UINT8 data );
|
||||
};
|
||||
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -633,6 +633,7 @@ BUSES += VIP
|
||||
BUSES += VTECH_IOEXP
|
||||
BUSES += VTECH_MEMEXP
|
||||
BUSES += WANGPC
|
||||
BUSES += WSWAN
|
||||
BUSES += X68K
|
||||
BUSES += Z88
|
||||
BUSES += ZORRO
|
||||
|
Loading…
Reference in New Issue
Block a user