From 66fab3cf5c75cd1eca9e4d1b1df29964c052ada3 Mon Sep 17 00:00:00 2001 From: Fabio Priuli Date: Sun, 5 Oct 2014 11:51:41 +0000 Subject: (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... --- .gitattributes | 4 + hash/wscolor.xml | 311 +++++++++++++++-- hash/wswan.xml | 370 ++++++++++++++++---- src/emu/bus/bus.mak | 12 + src/emu/bus/wswan/rom.c | 535 +++++++++++++++++++++++++++++ src/emu/bus/wswan/rom.h | 106 ++++++ src/emu/bus/wswan/slot.c | 491 +++++++++++++++++++++++++++ src/emu/bus/wswan/slot.h | 130 +++++++ src/mess/drivers/wswan.c | 76 ++--- src/mess/includes/wswan.h | 53 +-- src/mess/machine/wswan.c | 844 ++++++++++------------------------------------ src/mess/mess.mak | 1 + 12 files changed, 2084 insertions(+), 849 deletions(-) create mode 100644 src/emu/bus/wswan/rom.c create mode 100644 src/emu/bus/wswan/rom.h create mode 100644 src/emu/bus/wswan/slot.c create mode 100644 src/emu/bus/wswan/slot.h diff --git a/.gitattributes b/.gitattributes index 46cb970467e..74266d9661b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/hash/wscolor.xml b/hash/wscolor.xml index d3ffc7c4882..344c54ee999 100644 --- a/hash/wscolor.xml +++ b/hash/wscolor.xml @@ -10,11 +10,13 @@ - + + + @@ -27,9 +29,12 @@ + + + @@ -42,9 +47,12 @@ + + + @@ -57,9 +65,12 @@ + + + @@ -72,9 +83,12 @@ + + + @@ -87,9 +101,12 @@ + + + @@ -102,9 +119,12 @@ + + + @@ -116,9 +136,13 @@ + + + + @@ -130,11 +154,13 @@ - + + + @@ -145,9 +171,12 @@ Bandai + + + @@ -160,9 +189,12 @@ + + + @@ -175,9 +207,12 @@ + + + @@ -190,9 +225,12 @@ + + + @@ -205,9 +243,13 @@ + + + + @@ -220,9 +262,12 @@ + + + @@ -235,9 +280,12 @@ + + + @@ -249,11 +297,14 @@ - + + + + @@ -265,11 +316,13 @@ - + + + @@ -282,6 +335,7 @@ + @@ -296,11 +350,13 @@ - + + + @@ -312,11 +368,13 @@ - + + + @@ -329,9 +387,12 @@ + + + @@ -343,11 +404,13 @@ - + + + @@ -359,11 +422,13 @@ - + + + @@ -376,9 +441,12 @@ + + + @@ -390,9 +458,12 @@ + + + @@ -405,9 +476,12 @@ + + + @@ -419,11 +493,13 @@ - + + + @@ -436,9 +512,12 @@ + + + @@ -451,9 +530,12 @@ + + + @@ -466,9 +548,12 @@ + + + @@ -481,9 +566,12 @@ + + + @@ -495,11 +583,13 @@ - + + + @@ -512,9 +602,12 @@ + + + @@ -527,9 +620,12 @@ + + + @@ -541,11 +637,13 @@ - + + + @@ -558,9 +656,12 @@ + + + @@ -573,9 +674,12 @@ + + + @@ -588,9 +692,12 @@ + + + @@ -603,9 +710,12 @@ + + + @@ -617,11 +727,13 @@ - + + + @@ -634,9 +746,12 @@ + + + @@ -649,9 +764,13 @@ + + + + @@ -664,9 +783,12 @@ + + + @@ -677,9 +799,13 @@ Qute + + + + @@ -690,9 +816,13 @@ Qute + + + + @@ -705,9 +835,12 @@ + + + @@ -720,9 +853,12 @@ + + + @@ -735,9 +871,12 @@ + + + @@ -750,9 +889,12 @@ + + + @@ -765,9 +907,12 @@ + + + @@ -780,9 +925,12 @@ + + + @@ -794,11 +942,13 @@ - + + + @@ -810,11 +960,13 @@ - + + + @@ -826,11 +978,13 @@ - + + + @@ -843,9 +997,12 @@ + + + @@ -858,9 +1015,12 @@ + + + @@ -873,9 +1033,12 @@ + + + @@ -888,9 +1051,12 @@ + + + @@ -903,9 +1069,12 @@ + + + @@ -918,9 +1087,13 @@ + + + + @@ -933,9 +1106,12 @@ + + + @@ -947,11 +1123,13 @@ - + + + @@ -964,9 +1142,12 @@ + + + @@ -979,9 +1160,12 @@ + + + @@ -994,9 +1178,12 @@ + + + @@ -1009,9 +1196,12 @@ + + + @@ -1024,9 +1214,12 @@ + + + @@ -1039,9 +1232,12 @@ + + + @@ -1054,9 +1250,12 @@ + + + @@ -1069,9 +1268,12 @@ + + + @@ -1083,11 +1285,13 @@ - + + + @@ -1099,11 +1303,13 @@ - + + + @@ -1116,9 +1322,12 @@ + + + @@ -1131,9 +1340,12 @@ + + + @@ -1146,9 +1358,12 @@ + + + @@ -1160,11 +1375,13 @@ - + + + @@ -1177,9 +1394,12 @@ + + + @@ -1192,9 +1412,12 @@ + + + @@ -1206,11 +1429,13 @@ - + + + @@ -1223,6 +1448,7 @@ + @@ -1238,9 +1464,12 @@ + + + @@ -1250,9 +1479,12 @@ 2001 Bandai + + + @@ -1265,9 +1497,12 @@ + + + @@ -1280,9 +1515,12 @@ + + + @@ -1295,9 +1533,12 @@ + + + @@ -1310,9 +1551,12 @@ + + + @@ -1325,9 +1569,12 @@ + + + @@ -1340,9 +1587,12 @@ + + + @@ -1354,11 +1604,13 @@ - + + + @@ -1370,11 +1622,13 @@ - + + + @@ -1387,9 +1641,12 @@ + + + @@ -1401,11 +1658,13 @@ - + + + @@ -1418,9 +1677,12 @@ + + + @@ -1433,9 +1695,12 @@ + + + diff --git a/hash/wswan.xml b/hash/wswan.xml index d6dc7ef3666..a08af0cfd27 100644 --- a/hash/wswan.xml +++ b/hash/wswan.xml @@ -9,11 +9,13 @@ - + + + @@ -24,11 +26,13 @@ - + + + @@ -39,11 +43,13 @@ - + + + @@ -54,11 +60,13 @@ - + + + @@ -69,11 +77,13 @@ - + + + @@ -85,6 +95,7 @@ + @@ -98,11 +109,13 @@ - + + + @@ -113,11 +126,13 @@ - + + + @@ -128,11 +143,13 @@ - + + + @@ -143,11 +160,13 @@ - + + + @@ -159,9 +178,12 @@ + + + @@ -172,11 +194,13 @@ - + + + @@ -188,6 +212,7 @@ + @@ -202,6 +227,7 @@ + @@ -215,11 +241,13 @@ - + + + @@ -230,11 +258,13 @@ - + + + @@ -245,11 +275,13 @@ - + + + @@ -261,9 +293,12 @@ + + + @@ -273,11 +308,13 @@ 19?? Bandai - + + + @@ -289,9 +326,12 @@ + + + @@ -303,9 +343,12 @@ + + + @@ -316,11 +359,13 @@ - + + + @@ -331,11 +376,13 @@ - + + + @@ -346,11 +393,13 @@ - + + + @@ -361,11 +410,13 @@ - + + + @@ -376,11 +427,13 @@ - + + + @@ -391,11 +444,13 @@ - + + + @@ -406,11 +461,13 @@ - + + + @@ -422,6 +479,7 @@ + @@ -436,6 +494,7 @@ + @@ -449,11 +508,13 @@ - + + + @@ -465,9 +526,12 @@ + + + @@ -478,11 +542,13 @@ - + + + @@ -493,11 +559,13 @@ - + + + @@ -508,11 +576,13 @@ - + + + @@ -524,6 +594,7 @@ + @@ -537,11 +608,13 @@ - + + + @@ -553,9 +626,12 @@ + + + @@ -567,9 +643,12 @@ + + + @@ -581,9 +660,12 @@ + + + @@ -595,9 +677,12 @@ + + + @@ -608,11 +693,13 @@ - + + + @@ -623,11 +710,13 @@ - + + + @@ -639,9 +728,12 @@ + + + @@ -653,9 +745,12 @@ + + + @@ -666,11 +761,13 @@ - + + + @@ -682,9 +779,12 @@ + + + @@ -696,9 +796,12 @@ + + + @@ -710,9 +813,12 @@ + + + @@ -724,6 +830,7 @@ + @@ -738,9 +845,12 @@ + + + @@ -751,11 +861,13 @@ - + + + @@ -766,11 +878,13 @@ - + + + @@ -782,9 +896,12 @@ + + + @@ -796,9 +913,12 @@ + + + @@ -810,9 +930,12 @@ + + + @@ -824,6 +947,7 @@ + @@ -838,9 +962,12 @@ + + + @@ -852,21 +979,26 @@ + + + - MobileWonderGate 19?? <unknown> + + + @@ -878,9 +1010,12 @@ + + + @@ -892,9 +1027,12 @@ + + + @@ -906,9 +1044,12 @@ + + + @@ -919,11 +1060,13 @@ - + + + @@ -934,11 +1077,13 @@ - + + + @@ -949,11 +1094,13 @@ - + + + @@ -964,11 +1111,13 @@ - + + + @@ -979,11 +1128,13 @@ - + + + @@ -994,11 +1145,13 @@ - + + + @@ -1009,11 +1162,13 @@ - + + + @@ -1025,6 +1180,7 @@ + @@ -1038,11 +1194,13 @@ - + + + @@ -1053,11 +1211,13 @@ - + + + @@ -1069,9 +1229,12 @@ + + + @@ -1082,11 +1245,13 @@ - + + + @@ -1097,11 +1262,13 @@ - + + + @@ -1112,11 +1279,13 @@ - + + + @@ -1128,9 +1297,13 @@ + + + + @@ -1142,9 +1315,13 @@ + + + + @@ -1155,11 +1332,13 @@ - + + + @@ -1170,11 +1349,13 @@ - + + + @@ -1186,9 +1367,12 @@ + + + @@ -1199,11 +1383,13 @@ - + + + @@ -1215,9 +1401,12 @@ + + + @@ -1228,11 +1417,13 @@ - + + + @@ -1243,11 +1434,13 @@ - + + + @@ -1258,11 +1451,13 @@ - + + + @@ -1274,9 +1469,12 @@ + + + @@ -1288,9 +1486,12 @@ + + + @@ -1302,9 +1503,12 @@ + + + @@ -1316,6 +1520,7 @@ + @@ -1329,11 +1534,13 @@ - + + + @@ -1345,6 +1552,7 @@ + @@ -1358,11 +1566,13 @@ - + + + @@ -1374,6 +1584,7 @@ + @@ -1388,9 +1599,12 @@ + + + @@ -1402,9 +1616,12 @@ + + + @@ -1427,11 +1644,13 @@ - + + + @@ -1442,11 +1661,13 @@ - + + + @@ -1457,11 +1678,13 @@ - + + + @@ -1472,11 +1695,13 @@ - + + + @@ -1487,11 +1712,13 @@ - + + + @@ -1502,11 +1729,13 @@ - + + + @@ -1518,9 +1747,12 @@ + + + @@ -1532,6 +1764,7 @@ + @@ -1558,6 +1791,7 @@ + @@ -1571,11 +1805,13 @@ - + + + @@ -1587,6 +1823,7 @@ + @@ -1601,9 +1838,12 @@ + + + @@ -1614,11 +1854,13 @@ - + + + @@ -1629,11 +1871,13 @@ - + + + @@ -1644,11 +1888,13 @@ - + + + diff --git a/src/emu/bus/bus.mak b/src/emu/bus/bus.mak index 405fcc284df..d3f7c3b7cab 100644 --- a/src/emu/bus/bus.mak +++ b/src/emu/bus/bus.mak @@ -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 + diff --git a/src/emu/bus/wswan/rom.c b/src/emu/bus/wswan/rom.c new file mode 100644 index 00000000000..cdba3af7892 --- /dev/null +++ b/src/emu/bus/wswan/rom.c @@ -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; +const device_type WS_ROM_SRAM = &device_creator; +const device_type WS_ROM_EEPROM = &device_creator; + + +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; +} diff --git a/src/emu/bus/wswan/rom.h b/src/emu/bus/wswan/rom.h new file mode 100644 index 00000000000..a3f590ef133 --- /dev/null +++ b/src/emu/bus/wswan/rom.h @@ -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 diff --git a/src/emu/bus/wswan/slot.c b/src/emu/bus/wswan/slot.c new file mode 100644 index 00000000000..30762d9982d --- /dev/null +++ b/src/emu/bus/wswan/slot.c @@ -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; + +//************************************************************************** +// 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(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 +} diff --git a/src/emu/bus/wswan/slot.h b/src/emu/bus/wswan/slot.h new file mode 100644 index 00000000000..9d8aa145287 --- /dev/null +++ b/src/emu/bus/wswan/slot.h @@ -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 diff --git a/src/mess/drivers/wswan.c b/src/mess/drivers/wswan.c index 9961219ad07..edbc4eab746 100644 --- a/src/mess/drivers/wswan.c +++ b/src/mess/drivers/wswan.c @@ -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 ) diff --git a/src/mess/includes/wswan.h b/src/mess/includes/wswan.h index 20ccca7087e..3cf394adebf 100644 --- a/src/mess/includes/wswan.h +++ b/src/mess/includes/wswan.h @@ -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 m_maincpu; required_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 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 ); }; diff --git a/src/mess/machine/wswan.c b/src/mess/machine/wswan.c index 1295dc7e6e6..d8a219e37d1 100644 --- a/src/mess/machine/wswan.c +++ b/src/mess/machine/wswan.c @@ -20,11 +20,6 @@ TODO: #define INTERNAL_EEPROM_SIZE 1024 enum enum_system { TYPE_WSWAN=0, TYPE_WSC }; -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 }; - - static const UINT8 ws_portram_init[256] = @@ -138,82 +133,12 @@ void wswan_state::wswan_clear_irq_line(int irq) wswan_handle_irqs(); } -TIMER_CALLBACK_MEMBER(wswan_state::wswan_rtc_callback) -{ - /* A second passed */ - m_rtc.second = m_rtc.second + 1; - 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 = m_rtc.minute + 1; - 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 = m_rtc.hour + 1; - 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 = m_rtc.day + 1; - } -} - -void wswan_state::wswan_machine_stop() -{ - device_image_interface *image = dynamic_cast(machine().device("cart")); - if ( m_eeprom.size ) - { - image->battery_save(m_eeprom.data, m_eeprom.size ); - } -} - -void wswan_state::wswan_setup_bios() -{ - if ( m_ws_bios_bank == NULL ) - { - m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000 ); - memcpy( m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40 ); - } -} - -void wswan_state::wswan_setup_banks() -{ - static const char *rom_bank_tags[14] = { "rom1", "rom2", "rom3", "rom4", "rom5", "rom6", "rom7", - "rom8", "rom9", "rom10", "rom11", "rom12", "rom13", "rom14" }; - for (int i = 0; i < 14; i++) - m_rom_bank[i] = membank(rom_bank_tags[i]); -} - void wswan_state::wswan_register_save() { save_item(NAME(m_ws_portram)); save_item(NAME(m_internal_eeprom)); save_item(NAME(m_bios_disabled)); save_item(NAME(m_rotate)); - save_item(NAME(m_bank_base)); save_item(NAME(m_vdp.layer_bg_enable)); save_item(NAME(m_vdp.layer_fg_enable)); @@ -254,30 +179,13 @@ void wswan_state::wswan_register_save() save_item(NAME(m_vdp.timer_vblank_count)); save_item(NAME(m_vdp.main_palette)); - save_item(NAME(m_eeprom.mode)); - 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)); - save_item(NAME(m_eeprom.size)); - if (m_eeprom.size) - save_pointer(NAME(m_eeprom.data), m_eeprom.size); - - save_item(NAME(m_rtc.present)); - 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)); - save_item(NAME(m_sound_dma.source)); save_item(NAME(m_sound_dma.size)); save_item(NAME(m_sound_dma.enable)); + if (m_cart->exists()) + m_cart->save_nvram(); + machine().save().register_postload(save_prepost_delegate(FUNC(wswan_state::wswan_postload), this)); } @@ -286,55 +194,63 @@ void wswan_state::wswan_postload() address_space &space = m_maincpu->space(AS_PROGRAM); // restore the vdp pointers m_vdp.vram = (UINT8*)space.get_read_ptr(0); - m_vdp.palette_vram = (UINT8*)space.get_read_ptr(( m_system_type == TYPE_WSC ) ? 0xFE00 : 0 ); - // restore banks - for (int i = 0; i < 14; i++) - m_rom_bank[i]->set_entry(m_bank_base[i]); + m_vdp.palette_vram = (UINT8*)space.get_read_ptr((m_system_type == TYPE_WSC) ? 0xfe00 : 0); } +void wswan_state::common_start() +{ + m_ws_bios_bank = auto_alloc_array(machine(), UINT8, 0x10000); + memcpy(m_ws_bios_bank + 0xffc0, ws_fake_bios_code, 0x40); + + m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp); + m_vdp.timer->adjust(attotime::from_ticks(256, 3072000), 0, attotime::from_ticks(256, 3072000)); + + wswan_register_save(); + + machine().device("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); + + if (m_cart->exists()) + { + // ROM + m_maincpu->space(AS_PROGRAM).install_read_handler(0x20000, 0x2ffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom20),(ws_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x30000, 0x3ffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom30),(ws_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_read_handler(0x40000, 0xeffff, read8_delegate(FUNC(ws_cart_slot_device::read_rom40),(ws_cart_slot_device*)m_cart)); + + // SRAM + if (m_cart->get_type() == WS_SRAM) + { + m_maincpu->space(AS_PROGRAM).install_read_handler(0x10000, 0x1ffff, read8_delegate(FUNC(ws_cart_slot_device::read_ram),(ws_cart_slot_device*)m_cart)); + m_maincpu->space(AS_PROGRAM).install_write_handler(0x10000, 0x1ffff, write8_delegate(FUNC(ws_cart_slot_device::write_ram),(ws_cart_slot_device*)m_cart)); + } + } +} void wswan_state::machine_start() { - m_ws_bios_bank = NULL; + common_start(); m_system_type = TYPE_WSWAN; - machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_state::wswan_machine_stop),this)); - m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); - m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); - - wswan_setup_bios(); - wswan_setup_banks(); - wswan_register_save(); - - /* Set up RTC timer */ - if (m_rtc.present) - machine().scheduler().timer_pulse(attotime::from_seconds(1), timer_expired_delegate(FUNC(wswan_state::wswan_rtc_callback),this)); - - machine().device("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); } MACHINE_START_MEMBER(wswan_state,wscolor) { - m_ws_bios_bank = NULL; + common_start(); m_system_type = TYPE_WSC; - machine().add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(wswan_state::wswan_machine_stop),this)); - m_vdp.timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(wswan_state::wswan_scanline_interrupt),this), &m_vdp ); - m_vdp.timer->adjust( attotime::from_ticks( 256, 3072000 ), 0, attotime::from_ticks( 256, 3072000 ) ); - - wswan_setup_bios(); - wswan_setup_banks(); - wswan_register_save(); - - /* Set up RTC timer */ - if (m_rtc.present) - machine().scheduler().timer_pulse(attotime::from_seconds(1), timer_expired_delegate(FUNC(wswan_state::wswan_rtc_callback),this)); - - machine().device("nvram")->set_base(m_internal_eeprom, INTERNAL_EEPROM_SIZE); } void wswan_state::machine_reset() { address_space &space = m_maincpu->space(AS_PROGRAM); + m_bios_disabled = 0; + + m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0); + memset(m_ws_ram, 0, 0xffff); + + if (m_cart->exists()) + m_rotate = m_cart->get_is_rotated(); + else + m_rotate = 0; + /* Intialize ports */ memcpy(m_ws_portram, ws_portram_init, 256); @@ -353,131 +269,94 @@ void wswan_state::machine_reset() /* Initialize sound DMA */ memset(&m_sound_dma, 0, sizeof(m_sound_dma)); - - /* Switch in the banks */ - for (int bank = 0; bank < 14; bank++) - { - for (int i = 0; i < m_ROMBanks; i++) - m_rom_bank[bank]->configure_entries(i, 1, m_ROMMap[i], 0x10000); - } - m_rom_bank[13]->configure_entries(m_ROMBanks, 1, m_ws_bios_bank, 0x10000); - - m_bank_base[0] = (m_ROMBanks - 1) & (m_ROMBanks - 1); - m_bank_base[1] = (m_ROMBanks - 1) & (m_ROMBanks - 1); - m_bank_base[2] = (m_ROMBanks - 12) & (m_ROMBanks - 1); - m_bank_base[3] = (m_ROMBanks - 11) & (m_ROMBanks - 1); - m_bank_base[4] = (m_ROMBanks - 10) & (m_ROMBanks - 1); - m_bank_base[5] = (m_ROMBanks - 9) & (m_ROMBanks - 1); - m_bank_base[6] = (m_ROMBanks - 8) & (m_ROMBanks - 1); - m_bank_base[7] = (m_ROMBanks - 7) & (m_ROMBanks - 1); - m_bank_base[8] = (m_ROMBanks - 6) & (m_ROMBanks - 1); - m_bank_base[9] = (m_ROMBanks - 5) & (m_ROMBanks - 1); - m_bank_base[10] = (m_ROMBanks - 4) & (m_ROMBanks - 1); - m_bank_base[11] = (m_ROMBanks - 3) & (m_ROMBanks - 1); - m_bank_base[12] = (m_ROMBanks - 2) & (m_ROMBanks - 1); - m_bank_base[13] = m_ROMBanks; // the last bank is mapped to bios at start! - - m_bios_disabled = 0; - - for (int i = 0; i < 14; i++) - m_rom_bank[i]->set_entry(m_bank_base[i]); } -READ8_MEMBER( wswan_state::wswan_sram_r ) +READ8_MEMBER( wswan_state::bios_r ) { - if ( m_eeprom.data == NULL ) - { - return 0xFF; - } - return m_eeprom.page[ offset & ( m_eeprom.size - 1 ) ]; -} - -WRITE8_MEMBER( wswan_state::wswan_sram_w ) -{ - if ( m_eeprom.data == NULL ) - { - return; - } - m_eeprom.page[ offset & ( m_eeprom.size - 1 ) ] = data; + if (!m_bios_disabled) + return m_ws_bios_bank[offset]; + else + return m_cart->read_rom40(space, offset + 0xb0000); } -READ8_MEMBER( wswan_state::wswan_port_r ) +READ8_MEMBER( wswan_state::port_r ) { UINT8 value = m_ws_portram[offset]; - if ( offset != 2 ) - logerror( "PC=%X: port read %02X\n", m_maincpu->pc(), offset ); - switch( offset ) + if (offset != 2) + logerror("PC=%X: port read %02X\n", m_maincpu->pc(), offset); + switch (offset) { - case 0x02: /* Current line */ + case 0x02: // Current line value = m_vdp.current_line; break; - case 0x4A: /* Sound DMA source address (low) */ - value = m_sound_dma.source & 0xFF; + case 0x4a: // Sound DMA source address (low) + value = m_sound_dma.source & 0xff; break; - case 0x4B: /* Sound DMA source address (high) */ - value = ( m_sound_dma.source >> 8 ) & 0xFF; + case 0x4b: // Sound DMA source address (high) + value = (m_sound_dma.source >> 8) & 0xff; break; - case 0x4C: /* Sound DMA source memory segment */ - value = ( m_sound_dma.source >> 16 ) & 0xFF; + case 0x4c: // Sound DMA source memory segment + value = (m_sound_dma.source >> 16) & 0xff; break; - case 0x4E: /* Sound DMA transfer size (low) */ - value = m_sound_dma.size & 0xFF; + case 0x4e: // Sound DMA transfer size (low) + value = m_sound_dma.size & 0xff; break; - case 0x4F: /* Sound DMA transfer size (high) */ - value = ( m_sound_dma.size >> 8 ) & 0xFF; + case 0x4f: // Sound DMA transfer size (high) + value = (m_sound_dma.size >> 8) & 0xff; break; - case 0x52: /* Sound DMA start/stop */ + case 0x52: // Sound DMA start/stop value = m_sound_dma.enable; break; - case 0xA0: /* Hardware type */ - /* Bit 0 - Disable/enable Bios */ - /* Bit 1 - Determine mono/color */ - /* Bit 2 - Determine color/crystal */ + case 0xa0: // Hardware type + // Bit 0 - Disable/enable Bios + // Bit 1 - Determine mono/color + // Bit 2 - Determine color/crystal value = value & ~ 0x02; - if ( m_system_type == TYPE_WSC ) - { + if (m_system_type == TYPE_WSC) value |= 2; - } break; - case 0xA8: - value = m_vdp.timer_hblank_count & 0xFF; + case 0xa8: + value = m_vdp.timer_hblank_count & 0xff; break; - case 0xA9: + case 0xa9: value = m_vdp.timer_hblank_count >> 8; break; - case 0xAA: - value = m_vdp.timer_vblank_count & 0xFF; + case 0xaa: + value = m_vdp.timer_vblank_count & 0xff; break; - case 0xAB: + case 0xab: value = m_vdp.timer_vblank_count >> 8; break; - case 0xCB: /* RTC data */ - if ( m_ws_portram[0xca] == 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++; - } + case 0xc0: + case 0xc1: + case 0xc2: + case 0xc3: + case 0xc4: // EEPROM data + case 0xc5: // EEPROM data + case 0xc6: + case 0xc7: + case 0xc8: + case 0xc9: + case 0xca: + case 0xcb: // RTC data + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + value = m_cart->read_io(space, offset & 0x0f); + break; } return value; } -WRITE8_MEMBER( wswan_state::wswan_port_w ) +WRITE8_MEMBER( wswan_state::port_w ) { address_space &mem = m_maincpu->space(AS_PROGRAM); UINT8 input; - logerror( "PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data ); - switch( offset ) + logerror("PC=%X: port write %02X <- %02X\n", m_maincpu->pc(), offset, data); + switch (offset) { case 0x00: /* Display control Bit 0 - Background layer enable @@ -555,32 +434,32 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) */ m_vdp.window_fg_top = data; break; - case 0x0A: /* Right coordinate of foreground window + case 0x0a: /* Right coordinate of foreground window Bit 0-7 - Right coordinate of foreground window area */ m_vdp.window_fg_right = data; break; - case 0x0B: /* Bottom coordinate of foreground window + case 0x0b: /* Bottom coordinate of foreground window Bit 0-7 - Bottom coordinate of foreground window area */ m_vdp.window_fg_bottom = data; break; - case 0x0C: /* Left coordinate of sprite window + case 0x0c: /* Left coordinate of sprite window Bit 0-7 - Left coordinate of sprite window area */ m_vdp.window_sprites_left = data; break; - case 0x0D: /* Top coordinate of sprite window + case 0x0d: /* Top coordinate of sprite window Bit 0-7 - Top coordinate of sprite window area */ m_vdp.window_sprites_top = data; break; - case 0x0E: /* Right coordinate of sprite window + case 0x0e: /* Right coordinate of sprite window Bit 0-7 - Right coordinate of sprite window area */ m_vdp.window_sprites_right = data; break; - case 0x0F: /* Bottom coordinate of sprite window + case 0x0f: /* Bottom coordinate of sprite window Bit 0-7 - Bottom coordiante of sprite window area */ m_vdp.window_sprites_bottom = data; @@ -626,7 +505,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 0 Bit 4-7 - Gray tone setting for main palette index 1 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -643,7 +522,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 2 Bit 4-7 - Gray tone setting for main palette index 3 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -660,7 +539,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 4 Bit 4-7 - Gray tone setting for main paeltte index 5 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -677,7 +556,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Gray tone setting for main palette index 6 Bit 4-7 - Gray tone setting for main palette index 7 */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { int i = 15 - ( data & 0x0F ); int j = 15 - ( ( data & 0xF0 ) >> 4 ); @@ -711,17 +590,17 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 4-7 - Palette 4 index 1 */ case 0x29: /* Bit 0-3 - Palette 4 index 2 Bit 4-7 - Palette 4 index 3 */ - case 0x2A: /* Bit 0-3 - Palette 5 index 0 + case 0x2a: /* Bit 0-3 - Palette 5 index 0 Bit 4-7 - Palette 5 index 1 */ - case 0x2B: /* Bit 0-3 - Palette 5 index 2 + case 0x2b: /* Bit 0-3 - Palette 5 index 2 Bit 4-7 - Palette 5 index 3 */ - case 0x2C: /* Bit 0-3 - Palette 6 index 0 + case 0x2c: /* Bit 0-3 - Palette 6 index 0 Bit 4-7 - Palette 6 index 1 */ - case 0x2D: /* Bit 0-3 - Palette 6 index 2 + case 0x2d: /* Bit 0-3 - Palette 6 index 2 Bit 4-7 - Palette 6 index 3 */ - case 0x2E: /* Bit 0-3 - Palette 7 index 0 + case 0x2e: /* Bit 0-3 - Palette 7 index 0 Bit 4-7 - Palette 7 index 1 */ - case 0x2F: /* Bit 0-3 - Palette 7 index 2 + case 0x2f: /* Bit 0-3 - Palette 7 index 2 Bit 4-7 - Palette 7 index 3 */ case 0x30: /* Bit 0-3 - Palette 8 / Sprite Palette 0 index 0 Bit 4-7 - Palette 8 / Sprite Palette 0 index 1 */ @@ -743,17 +622,17 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 4-7 - Palette 12 / Sprite Palette 4 index 1 */ case 0x39: /* Bit 0-3 - Palette 12 / Sprite Palette 4 index 2 Bit 4-7 - Palette 12 / Sprite Palette 4 index 3 */ - case 0x3A: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0 + case 0x3a: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 0 Bit 4-7 - Palette 13 / Sprite Palette 5 index 1 */ - case 0x3B: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2 + case 0x3b: /* Bit 0-3 - Palette 13 / Sprite Palette 5 index 2 Bit 4-7 - Palette 13 / Sprite Palette 5 index 3 */ - case 0x3C: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0 + case 0x3c: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 0 Bit 4-7 - Palette 14 / Sprite Palette 6 index 1 */ - case 0x3D: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2 + case 0x3d: /* Bit 0-3 - Palette 14 / Sprite Palette 6 index 2 Bit 4-7 - Palette 14 / Sprite Palette 6 index 3 */ - case 0x3E: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0 + case 0x3e: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 0 Bit 4-7 - Palette 15 / Sprite Palette 7 index 1 */ - case 0x3F: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2 + case 0x3f: /* Bit 0-3 - Palette 15 / Sprite Palette 7 index 2 Bit 4-7 - Palette 15 / Sprite Palette 7 index 3 */ break; case 0x40: /* DMA source address (low) @@ -785,7 +664,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-6 - Unknown Bit 7 - DMA stop/start */ - if( data & 0x80 ) + if (data & 0x80) { UINT32 src, dst; UINT16 length; @@ -793,51 +672,51 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) src = m_ws_portram[0x40] + (m_ws_portram[0x41] << 8) + (m_ws_portram[0x42] << 16); dst = m_ws_portram[0x44] + (m_ws_portram[0x45] << 8) + (m_ws_portram[0x43] << 16); length = m_ws_portram[0x46] + (m_ws_portram[0x47] << 8); - for( ; length > 0; length-- ) + for ( ; length > 0; length--) { - mem.write_byte(dst, mem.read_byte(src ) ); + mem.write_byte(dst, mem.read_byte(src)); src++; dst++; } #ifdef MAME_DEBUG - logerror( "DMA src:%X dst:%X length:%d\n", src, dst, length ); + logerror("DMA src:%X dst:%X length:%d\n", src, dst, length); #endif - m_ws_portram[0x40] = src & 0xFF; - m_ws_portram[0x41] = ( src >> 8 ) & 0xFF; - m_ws_portram[0x44] = dst & 0xFF; - m_ws_portram[0x45] = ( dst >> 8 ) & 0xFF; - m_ws_portram[0x46] = length & 0xFF; - m_ws_portram[0x47] = ( length >> 8 ) & 0xFF; - data &= 0x7F; + m_ws_portram[0x40] = src & 0xff; + m_ws_portram[0x41] = (src >> 8) & 0xff; + m_ws_portram[0x44] = dst & 0xff; + m_ws_portram[0x45] = (dst >> 8) & 0xff; + m_ws_portram[0x46] = length & 0xff; + m_ws_portram[0x47] = (length >> 8) & 0xff; + data &= 0x7f; } break; - case 0x4A: /* Sound DMA source address (low) + case 0x4a: /* Sound DMA source address (low) Bit 0-7 - Sound DMA source address bit 0-7 */ - m_sound_dma.source = ( m_sound_dma.source & 0x0FFF00 ) | data; + m_sound_dma.source = (m_sound_dma.source & 0x0fff00) | data; break; - case 0x4B: /* Sound DMA source address (high) + case 0x4b: /* Sound DMA source address (high) Bit 0-7 - Sound DMA source address bit 8-15 */ - m_sound_dma.source = ( m_sound_dma.source & 0x0F00FF ) | ( data << 8 ); + m_sound_dma.source = (m_sound_dma.source & 0x0f00ff) | (data << 8); break; - case 0x4C: /* Sound DMA source memory segment + case 0x4c: /* Sound DMA source memory segment Bit 0-3 - Sound DMA source address segment Bit 4-7 - Unknown */ - m_sound_dma.source = ( m_sound_dma.source & 0xFFFF ) | ( ( data & 0x0F ) << 16 ); + m_sound_dma.source = (m_sound_dma.source & 0xffff) | ((data & 0x0f) << 16); break; - case 0x4D: /* Unknown */ + case 0x4d: /* Unknown */ break; - case 0x4E: /* Sound DMA transfer size (low) + case 0x4e: /* Sound DMA transfer size (low) Bit 0-7 - Sound DMA transfer size bit 0-7 */ - m_sound_dma.size = ( m_sound_dma.size & 0xFF00 ) | data; + m_sound_dma.size = (m_sound_dma.size & 0xff00) | data; break; - case 0x4F: /* Sound DMA transfer size (high) + case 0x4f: /* Sound DMA transfer size (high) Bit 0-7 - Sound DMA transfer size bit 8-15 */ - m_sound_dma.size = ( m_sound_dma.size & 0xFF ) | ( data << 8 ); + m_sound_dma.size = (m_sound_dma.size & 0xff) | (data << 8); break; case 0x50: /* Unknown */ case 0x51: /* Unknown */ @@ -864,7 +743,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) * 001 - packed, 4 color, use 2000, monochrome * 000 - not packed, 4 color, use 2000, monochrome - Regular WS monochrome */ - if ( m_system_type == TYPE_WSC ) + if (m_system_type == TYPE_WSC) { m_vdp.color_mode = data & 0x80; m_vdp.colors_16 = data & 0x40; @@ -903,27 +782,27 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Right volume audio channel 2 Bit 4-7 - Left volume audio channel 2 */ - case 0x8A: /* Audio 3 volume + case 0x8a: /* Audio 3 volume Bit 0-3 - Right volume audio channel 3 Bit 4-7 - Left volume audio channel 3 */ - case 0x8B: /* Audio 4 volume + case 0x8b: /* Audio 4 volume Bit 0-3 - Right volume audio channel 4 Bit 4-7 - Left volume audio channel 4 */ - case 0x8C: /* Sweep step + case 0x8c: /* Sweep step Bit 0-7 - Sweep step */ - case 0x8D: /* Sweep time + case 0x8d: /* Sweep time Bit 0-7 - Sweep time */ - case 0x8E: /* Noise control + case 0x8e: /* Noise control Bit 0-2 - Noise generator type Bit 3 - Reset Bit 4 - Enable Bit 5-7 - Unknown */ - case 0x8F: /* Sample location + case 0x8f: /* Sample location Bit 0-7 - Sample address location 0 00xxxxxx xx000000 */ case 0x90: /* Audio control @@ -954,7 +833,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 0-3 - Master volume Bit 4-7 - Unknown */ - m_sound->port_w( space, offset, data ); + m_sound->port_w(space, offset, data); break; case 0xa0: /* Hardware type - this is probably read only Bit 0 - Enable cartridge slot and/or disable bios @@ -962,11 +841,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 2-7 - Unknown */ if ((data & 0x01) && !m_bios_disabled) - { m_bios_disabled = 1; - m_bank_base[13] = (((m_ws_portram[0xc0] & 0x0f) << 4) | 15) & (m_ROMBanks - 1); - m_rom_bank[13]->set_entry(m_bank_base[13]); - } break; case 0xa2: /* Timer control Bit 0 - HBlank Timer enable @@ -975,10 +850,10 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 3 - VBlank Timer mode: 0 = one shot, 1 = auto reset Bit 4-7 - Unknown */ - m_vdp.timer_hblank_enable = data & 0x1; - m_vdp.timer_hblank_mode = (data & 0x2) >> 1; - m_vdp.timer_vblank_enable = (data & 0x4) >> 2; - m_vdp.timer_vblank_mode = (data & 0x8) >> 3; + m_vdp.timer_hblank_enable = BIT(data, 0); + m_vdp.timer_hblank_mode = BIT(data, 1); + m_vdp.timer_vblank_enable = BIT(data, 2); + m_vdp.timer_vblank_mode = BIT(data, 3); break; case 0xa4: /* HBlank timer frequency (low) - reload value Bit 0-7 - HBlank timer reload value bit 0-7 @@ -1051,13 +926,13 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) bit 7 - Receive data interrupt generation */ // data |= 0x02; - m_ws_portram[0xb1] = 0xFF; - if ( data & 0x80 ) + m_ws_portram[0xb1] = 0xff; + if (data & 0x80) { // m_ws_portram[0xb1] = 0x00; data |= 0x04; } - if (data & 0x20 ) + if (data & 0x20) { // data |= 0x01; } @@ -1070,8 +945,8 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) 100 - Read START,A,B buttons Bit 7 - Unknown */ - data = data & 0xF0; - switch( data ) + data = data & 0xf0; + switch (data) { case 0x10: /* Read Y cursors: Y1 - Y2 - Y3 - Y4 */ input = m_cursy->read(); @@ -1113,7 +988,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 7 - HBlank timer interrupt acknowledge */ wswan_clear_irq_line(data); - data = m_ws_portram[0xB6]; + data = m_ws_portram[0xb6]; break; case 0xba: /* Internal EEPROM data (low) Bit 0-7 - Internal EEPROM data transfer bit 0-7 @@ -1140,7 +1015,7 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) Bit 6 - Protect Bit 7 - Initialize */ - if ( data & 0x20 ) + if (data & 0x20) { UINT16 addr = ( ( ( m_ws_portram[0xbd] << 8 ) | m_ws_portram[0xbc] ) << 1 ) & 0x1FF; m_internal_eeprom[ addr ] = m_ws_portram[0xba]; @@ -1159,240 +1034,23 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) logerror( "Unsupported internal EEPROM command: %X\n", data ); } break; - case 0xc0: - // Bit 0-3 - ROM bank base register for rom3-rom14 - // Bit 4-7 - Unknown - m_bank_base[2] = (((data & 0x0f) << 4) | 4) & (m_ROMBanks - 1); - m_bank_base[3] = (((data & 0x0f) << 4) | 5) & (m_ROMBanks - 1); - m_bank_base[4] = (((data & 0x0f) << 4) | 6) & (m_ROMBanks - 1); - m_bank_base[5] = (((data & 0x0f) << 4) | 7) & (m_ROMBanks - 1); - m_bank_base[6] = (((data & 0x0f) << 4) | 8) & (m_ROMBanks - 1); - m_bank_base[7] = (((data & 0x0f) << 4) | 9) & (m_ROMBanks - 1); - m_bank_base[8] = (((data & 0x0f) << 4) | 10) & (m_ROMBanks - 1); - m_bank_base[9] = (((data & 0x0f) << 4) | 11) & (m_ROMBanks - 1); - m_bank_base[10] = (((data & 0x0f) << 4) | 12) & (m_ROMBanks - 1); - m_bank_base[11] = (((data & 0x0f) << 4) | 13) & (m_ROMBanks - 1); - m_bank_base[12] = (((data & 0x0f) << 4) | 14) & (m_ROMBanks - 1); - for (int i = 2; i < 13; i++) - m_rom_bank[i]->set_entry(m_bank_base[i]); - - m_bank_base[13] = m_ROMBanks; // the last bank is mapped to bios at start! - if (m_bios_disabled) - { - m_bank_base[13] = (((data & 0x0f) << 4) | 14) & (m_ROMBanks - 1); - m_rom_bank[13]->set_entry(m_bank_base[13]); - } - break; - case 0xc1: /* SRAM bank select - Bit 0-7 - SRAM bank to select - */ - if ( m_eeprom.mode == SRAM_64K || m_eeprom.mode == SRAM_256K || m_eeprom.mode == SRAM_512K || m_eeprom.mode == SRAM_1M || m_eeprom.mode == SRAM_2M ) - { - m_eeprom.page = &m_eeprom.data[ ( data * 64 * 1024 ) & ( m_eeprom.size - 1 ) ]; - } - break; - case 0xc2: - // Bit 0-7 - ROM bank for segment 2 (0x20000 - 0x2ffff) - m_bank_base[0] = data & (m_ROMBanks - 1); - m_rom_bank[0]->set_entry(m_bank_base[0]); - break; - case 0xc3: - // Bit 0-7 - ROM bank for segment 3 (0x30000 - 0x3ffff) - m_bank_base[1] = data & (m_ROMBanks - 1); - m_rom_bank[1]->set_entry(m_bank_base[1]); - break; - case 0xc6: /* 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_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 0xc7: /* 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_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 0xc8: /* 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 ( m_eeprom.mode == EEPROM_1K || m_eeprom.mode == EEPROM_16K ) - { - 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 ); - } - } - if ( data & 0x20 ) - { /* Write */ - if ( m_eeprom.write_enabled ) - { - switch( m_eeprom.command ) - { - case 0x04: - m_eeprom.data[ ( m_eeprom.address << 1 ) + 1 ] = m_ws_portram[0xc4]; - m_eeprom.data[ m_eeprom.address << 1 ] = m_ws_portram[0xc5]; - data |= 0x02; - break; - default: - logerror( "Unsupported 'Write' command %X\n", m_eeprom.command ); - } - } - } - if ( data & 0x10 ) - { /* Read */ - m_ws_portram[0xc4] = m_eeprom.data[ ( m_eeprom.address << 1 ) + 1 ]; - m_ws_portram[0xc5] = m_eeprom.data[ m_eeprom.address << 1 ]; - data |= 0x01; - } - } - else - { - logerror( "EEPROM command for unknown EEPROM type\n" ); - } - break; - case 0xca: /* 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) - */ - 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_ws_portram[0xcb]; - data |= 0x80; - break; - case 0x13: /* Read Timer Settings (Alarm) */ - m_rtc.index = 8; - m_ws_portram[0xcb] = m_rtc.setting; - data |= 0x80; - break; - case 0x14: /* Set Time/Date */ - m_rtc.year = m_ws_portram[0xcb]; - m_rtc.index = 1; - data |= 0x80; - break; - case 0x15: /* Get Time/Date */ - m_rtc.index = 0; - data |= 0x80; - m_ws_portram[0xcb] = m_rtc.year; - break; - default: - logerror( "%X: Unknown RTC command (%X) requested\n", mem.device().safe_pc(), data ); - } - break; - case 0xcb: /* RTC Data */ - if ( m_ws_portram[0xca] == 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++; - } + case 0xc0: // ROM bank $40000-$fffff + case 0xc1: // SRAM bank + case 0xc2: // ROM bank $20000-$2ffff + case 0xc3: // ROM bank $30000-$3ffff + case 0xc4: + case 0xc5: + case 0xc6: // EEPROM address / command + case 0xc7: // EEPROM address / command + case 0xc8: // EEPROM command + case 0xc9: + case 0xca: // RTC command + case 0xcb: // RTC data + case 0xcc: + case 0xcd: + case 0xce: + case 0xcf: + m_cart->write_io(space, offset & 0x0f, data); break; default: logerror( "Write to unsupported port: %X - %X\n", offset, data ); @@ -1403,154 +1061,6 @@ WRITE8_MEMBER( wswan_state::wswan_port_w ) m_ws_portram[offset] = data; } -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 ]; -} - - -DRIVER_INIT_MEMBER(wswan_state, wswan) -{ - /* Initialize EEPROM structure */ - memset( &m_eeprom, 0, sizeof( m_eeprom ) ); - m_eeprom.data = NULL; - m_eeprom.page = NULL; - - /* Initialize RTC structure */ - m_rtc.present = 0; - 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; -} - - -DEVICE_IMAGE_LOAD_MEMBER(wswan_state,wswan_cart) -{ - UINT32 size; - const char *sram_str; - - if (image.software_entry() == NULL) - size = image.length(); - else - size = image.get_software_region_length("rom"); - - m_ws_ram = (UINT8*) m_maincpu->space(AS_PROGRAM).get_read_ptr(0); - memset(m_ws_ram, 0, 0xffff); - m_ROMBanks = size / 65536; - - for (int i = 0; i < m_ROMBanks; i++) - { - if ((m_ROMMap[i] = auto_alloc_array(machine(), UINT8, 0x10000))) - { - if (image.software_entry() == NULL) - { - if (image.fread( m_ROMMap[i], 0x10000) != 0x10000) - { - image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Wrongly sized ROM"); - image.message(" Wrongly sized ROM"); - logerror("Error while reading loading rom!\n"); - return IMAGE_INIT_FAIL; - } - } - else - memcpy(m_ROMMap[i], image.get_software_region("rom") + i * 0x10000, 0x10000); - } - else - { - image.seterror(IMAGE_ERROR_INVALIDIMAGE, "Unable to allocate memory for ROM"); - image.message(" Unable to allocate memory for ROM"); - logerror("Memory allocation failed reading rom!\n"); - return IMAGE_INIT_FAIL; - } - } - - sram_str = wswan_determine_sram(m_ROMMap[m_ROMBanks - 1][0xfffb]); - - m_rtc.present = m_ROMMap[m_ROMBanks - 1][0xfffd] ? 1 : 0; - m_rotate = m_ROMMap[m_ROMBanks-1][0xfffc] & 0x01; - - { - 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); - } - - if (m_eeprom.size != 0) - { - m_eeprom.data = auto_alloc_array(machine(), UINT8, m_eeprom.size); - image.battery_load(m_eeprom.data, m_eeprom.size, 0x00); - m_eeprom.page = m_eeprom.data; - } - - if (image.software_entry() == NULL) - { - logerror("Image Name: %s\n", image.longname()); - logerror("Image Year: %s\n", image.year()); - logerror("Image Manufacturer: %s\n", image.manufacturer()); - } - - /* All done */ - return IMAGE_INIT_PASS; -} TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt) { @@ -1584,7 +1094,7 @@ TIMER_CALLBACK_MEMBER(wswan_state::wswan_scanline_interrupt) { address_space &space = m_maincpu->space(AS_PROGRAM ); /* TODO: Output sound DMA byte */ - wswan_port_w( space, 0x89, space.read_byte(m_sound_dma.source ) ); + port_w( space, 0x89, space.read_byte(m_sound_dma.source ) ); m_sound_dma.size--; m_sound_dma.source = ( m_sound_dma.source + 1 ) & 0x0FFFFF; if ( m_sound_dma.size == 0 ) diff --git a/src/mess/mess.mak b/src/mess/mess.mak index 58cabc3ea51..ca411b1e79d 100644 --- a/src/mess/mess.mak +++ b/src/mess/mess.mak @@ -633,6 +633,7 @@ BUSES += VIP BUSES += VTECH_IOEXP BUSES += VTECH_MEMEXP BUSES += WANGPC +BUSES += WSWAN BUSES += X68K BUSES += Z88 BUSES += ZORRO -- cgit v1.2.3-70-g09d2