diff --git a/higan/emulator/emulator.hpp b/higan/emulator/emulator.hpp index a1b8676e..35471153 100644 --- a/higan/emulator/emulator.hpp +++ b/higan/emulator/emulator.hpp @@ -6,7 +6,7 @@ using namespace nall; namespace Emulator { static const string Name = "higan"; - static const string Version = "097.20"; + static const string Version = "097.21"; static const string Author = "byuu"; static const string License = "GPLv3"; static const string Website = "http://byuu.org/"; diff --git a/higan/processor/r65816/disassembler.cpp b/higan/processor/r65816/disassembler.cpp index c86caa2d..b48c8c7c 100644 --- a/higan/processor/r65816/disassembler.cpp +++ b/higan/processor/r65816/disassembler.cpp @@ -410,8 +410,8 @@ auto R65816::disassemble_opcode(char* output, uint32 addr, bool e, bool m, bool strcat(s, t); strcat(s, " "); - sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ", - regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db); + sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x B:%.2x ", + regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, (uint8_t)regs.db); strcat(s, t); if(regs.e) { diff --git a/higan/sfc/GNUmakefile b/higan/sfc/GNUmakefile index 8adba23d..4aa55e3e 100644 --- a/higan/sfc/GNUmakefile +++ b/higan/sfc/GNUmakefile @@ -3,7 +3,7 @@ processors += r65816 spc700 arm gsu hg51b upd96050 objects += sfc-interface sfc-system sfc-scheduler sfc-controller objects += sfc-cartridge sfc-cheat objects += sfc-memory sfc-cpu sfc-smp sfc-dsp sfc-ppu -objects += sfc-satellaview sfc-eboot +objects += sfc-satellaview sfc-superdisc sfc-eboot objects += sfc-icd2 sfc-mcc sfc-nss sfc-event objects += sfc-sa1 sfc-superfx objects += sfc-armdsp sfc-hitachidsp sfc-necdsp @@ -47,6 +47,7 @@ obj/sfc-dsp.o: sfc/$(sfcdsp)/dsp.cpp $(call rwildcard,sfc/$(sfcdsp)/) obj/sfc-ppu.o: sfc/$(sfcppu)/ppu.cpp $(call rwildcard,sfc/$(sfcppu)/) obj/sfc-satellaview.o: sfc/expansion/satellaview/satellaview.cpp $(call rwildcard,sfc/expansion/satellaview/) +obj/sfc-superdisc.o: sfc/expansion/superdisc/superdisc.cpp $(call rwildcard,sfc/expansion/superdisc/) obj/sfc-eboot.o: sfc/expansion/eboot/eboot.cpp $(call rwildcard,sfc/expansion/eboot/) obj/sfc-icd2.o: sfc/coprocessor/icd2/icd2.cpp $(call rwildcard,sfc/coprocessor/icd2/) diff --git a/higan/sfc/expansion/expansion.hpp b/higan/sfc/expansion/expansion.hpp index ea8bfc2e..f5bd1714 100644 --- a/higan/sfc/expansion/expansion.hpp +++ b/higan/sfc/expansion/expansion.hpp @@ -1,2 +1,3 @@ -#include #include +#include +#include diff --git a/higan/sfc/expansion/superdisc/superdisc.cpp b/higan/sfc/expansion/superdisc/superdisc.cpp new file mode 100644 index 00000000..8d75c985 --- /dev/null +++ b/higan/sfc/expansion/superdisc/superdisc.cpp @@ -0,0 +1,33 @@ +#include + +namespace SuperFamicom { + +SuperDisc superdisc; + +auto SuperDisc::init() -> void { +} + +auto SuperDisc::load() -> void { + bus.map({&SuperDisc::read, &superdisc}, {&SuperDisc::write, &superdisc}, 0x00, 0x3f, 0x21e0, 0x21e5); + bus.map({&SuperDisc::read, &superdisc}, {&SuperDisc::write, &superdisc}, 0x80, 0xbf, 0x21e0, 0x21e5); +} + +auto SuperDisc::unload() -> void { +} + +auto SuperDisc::power() -> void { +} + +auto SuperDisc::reset() -> void { +} + +auto SuperDisc::read(uint24 addr, uint8 data) -> uint8 { + addr = 0x21e0 | (addr & 7); + return data; +} + +auto SuperDisc::write(uint24 addr, uint8 data) -> void { + addr = 0x21e0 | (addr & 7); +} + +} diff --git a/higan/sfc/expansion/superdisc/superdisc.hpp b/higan/sfc/expansion/superdisc/superdisc.hpp new file mode 100644 index 00000000..928aedf7 --- /dev/null +++ b/higan/sfc/expansion/superdisc/superdisc.hpp @@ -0,0 +1,14 @@ +struct SuperDisc : Memory { + auto init() -> void; + auto load() -> void; + auto unload() -> void; + auto power() -> void; + auto reset() -> void; + + auto read(uint24 addr, uint8 data) -> uint8; + auto write(uint24 addr, uint8 data) -> void; + +private: +}; + +extern SuperDisc superdisc; diff --git a/higan/sfc/interface/interface.cpp b/higan/sfc/interface/interface.cpp index 4c1a6014..bf1190f3 100644 --- a/higan/sfc/interface/interface.cpp +++ b/higan/sfc/interface/interface.cpp @@ -117,7 +117,11 @@ Interface::Interface() { this->device.append(device); } - { Device device{9, ID::ExpansionPort, "eBoot"}; + { Device device{9, ID::ExpansionPort, "Super Disc"}; + this->device.append(device); + } + + { Device device{10, ID::ExpansionPort, "eBoot"}; this->device.append(device); } diff --git a/higan/sfc/system/device.hpp b/higan/sfc/system/device.hpp index 965353e2..ef69c8ab 100644 --- a/higan/sfc/system/device.hpp +++ b/higan/sfc/system/device.hpp @@ -19,6 +19,7 @@ struct Device { //expansion port devices Satellaview, + SuperDisc, eBoot, }; diff --git a/higan/sfc/system/system.cpp b/higan/sfc/system/system.cpp index 73070445..0021b312 100644 --- a/higan/sfc/system/system.cpp +++ b/higan/sfc/system/system.cpp @@ -32,6 +32,7 @@ auto System::init() -> void { assert(interface != nullptr); satellaview.init(); + superdisc.init(); eboot.init(); icd2.init(); @@ -81,6 +82,7 @@ auto System::load() -> void { ppu.enable(); if(expansionPort() == Device::ID::Satellaview) satellaview.load(); + if(expansionPort() == Device::ID::SuperDisc) superdisc.load(); if(expansionPort() == Device::ID::eBoot) eboot.load(); if(cartridge.hasICD2()) icd2.load(); @@ -109,6 +111,7 @@ auto System::load() -> void { auto System::unload() -> void { if(!loaded()) return; if(expansionPort() == Device::ID::Satellaview) satellaview.unload(); + if(expansionPort() == Device::ID::SuperDisc) superdisc.unload(); if(expansionPort() == Device::ID::eBoot) eboot.unload(); if(cartridge.hasICD2()) icd2.unload(); @@ -143,6 +146,7 @@ auto System::power() -> void { ppu.power(); if(expansionPort() == Device::ID::Satellaview) satellaview.power(); + if(expansionPort() == Device::ID::SuperDisc) superdisc.power(); if(expansionPort() == Device::ID::eBoot) eboot.power(); if(cartridge.hasICD2()) icd2.power(); @@ -173,6 +177,7 @@ auto System::reset() -> void { ppu.reset(); if(expansionPort() == Device::ID::Satellaview) satellaview.reset(); + if(expansionPort() == Device::ID::SuperDisc) superdisc.reset(); if(expansionPort() == Device::ID::eBoot) eboot.reset(); if(cartridge.hasICD2()) icd2.reset(); diff --git a/higan/target-tomoko/program/interface.cpp b/higan/target-tomoko/program/interface.cpp index 248d9c6b..04a8c247 100644 --- a/higan/target-tomoko/program/interface.cpp +++ b/higan/target-tomoko/program/interface.cpp @@ -41,6 +41,7 @@ auto Program::loadRequest(uint id, string filename, bool required) -> void { auto Program::saveRequest(uint id, string filename) -> void { string pathname = mediaPaths(emulator->group(id)); string location = {pathname, filename}; + if(!pathname) return; //should never occur filestream stream{location, file::mode::write}; return emulator->save(id, stream); diff --git a/higan/ws/cartridge/cartridge.cpp b/higan/ws/cartridge/cartridge.cpp index 7c415f93..ba6815a3 100644 --- a/higan/ws/cartridge/cartridge.cpp +++ b/higan/ws/cartridge/cartridge.cpp @@ -23,18 +23,20 @@ auto Cartridge::load() -> void { } if(auto node = document["board/ram"]) { - ram.name = node["name"].text(); - ram.size = node["size"].natural(); - ram.mask = bit::round(ram.size) - 1; - if(ram.size) ram.data = new uint8[ram.mask + 1](); - if(ram.name) interface->loadRequest(ID::RAM, ram.name, false); - } + if(node["type"].text() == "sram") { + ram.name = node["name"].text(); + ram.size = node["size"].natural(); + ram.mask = bit::round(ram.size) - 1; + if(ram.size) ram.data = new uint8[ram.mask + 1](); + if(ram.name) interface->loadRequest(ID::RAM, ram.name, false); + } - if(auto node = document["board/eeprom"]) { - eeprom.setName(node["name"].text()); - eeprom.setSize(node["size"].natural() / sizeof(uint16)); - eeprom.erase(); - if(eeprom.name()) interface->loadRequest(ID::EEPROM, eeprom.name(), false); + if(node["type"].text() == "eeprom") { + eeprom.setName(node["name"].text()); + eeprom.setSize(node["size"].natural() / sizeof(uint16)); + eeprom.erase(); + if(eeprom.name()) interface->loadRequest(ID::EEPROM, eeprom.name(), false); + } } information.title = document["information/title"].text(); diff --git a/higan/ws/cartridge/cartridge.hpp b/higan/ws/cartridge/cartridge.hpp index 06676029..3a194ca5 100644 --- a/higan/ws/cartridge/cartridge.hpp +++ b/higan/ws/cartridge/cartridge.hpp @@ -3,11 +3,11 @@ struct Cartridge : IO { auto unload() -> void; auto power() -> void; - auto romRead(uint addr) -> uint8; - auto romWrite(uint addr, uint8 data) -> void; + auto romRead(uint20 addr) -> uint8; + auto romWrite(uint20 addr, uint8 data) -> void; - auto ramRead(uint addr) -> uint8; - auto ramWrite(uint addr, uint8 data) -> void; + auto ramRead(uint20 addr) -> uint8; + auto ramWrite(uint20 addr, uint8 data) -> void; auto portRead(uint16 addr) -> uint8 override; auto portWrite(uint16 addr, uint8 data) -> void override; diff --git a/higan/ws/cartridge/memory.cpp b/higan/ws/cartridge/memory.cpp index 67b8584b..98b1a857 100644 --- a/higan/ws/cartridge/memory.cpp +++ b/higan/ws/cartridge/memory.cpp @@ -1,26 +1,27 @@ //20000-fffff -auto Cartridge::romRead(uint addr) -> uint8 { - switch((uint4)(addr >> 16)) { - case 2: addr = r.bank_rom0 << 16 | (uint16)addr; break; //20000-2ffff - case 3: addr = r.bank_rom1 << 16 | (uint16)addr; break; //30000-3ffff - default: addr = r.bank_rom2 << 20 | (uint20)addr; break; //40000-fffff - } +auto Cartridge::romRead(uint20 addr) -> uint8 { if(!rom.data) return 0x00; - return rom.data[addr & rom.mask]; + uint28 offset; + switch(addr.byte(2)) { + case 2: offset = r.bank_rom0 << 16 | addr.bits(0,15); break; //20000-2ffff + case 3: offset = r.bank_rom1 << 16 | addr.bits(0,15); break; //30000-3ffff + default: offset = r.bank_rom2 << 20 | addr.bits(0,19); break; //40000-fffff + } + return rom.data[offset & rom.mask]; } -auto Cartridge::romWrite(uint addr, uint8 data) -> void { +auto Cartridge::romWrite(uint20 addr, uint8 data) -> void { } //10000-1ffff -auto Cartridge::ramRead(uint addr) -> uint8 { - addr = r.bank_sram << 16 | (uint16)addr; +auto Cartridge::ramRead(uint20 addr) -> uint8 { if(!ram.data) return 0x00; - return ram.data[addr & ram.mask]; + uint24 offset = r.bank_sram << 16 | addr.bits(0,15); + return ram.data[offset & ram.mask]; } -auto Cartridge::ramWrite(uint addr, uint8 data) -> void { - addr = r.bank_sram << 16 | (uint16)addr; +auto Cartridge::ramWrite(uint20 addr, uint8 data) -> void { if(!ram.data) return; - ram.data[addr & ram.mask] = data; + uint24 offset = r.bank_sram << 16 | addr.bits(0,15); + ram.data[offset & ram.mask] = data; } diff --git a/higan/ws/cpu/cpu.cpp b/higan/ws/cpu/cpu.cpp index faa1461a..2afe126b 100644 --- a/higan/ws/cpu/cpu.cpp +++ b/higan/ws/cpu/cpu.cpp @@ -53,6 +53,7 @@ auto CPU::power() -> void { iomap[0x00b0] = this; iomap[0x00b2] = this; iomap[0x00b4] = this; + iomap[0x00b5] = this; iomap[0x00b6] = this; if(WSC() || SC()) { diff --git a/higan/ws/cpu/cpu.hpp b/higan/ws/cpu/cpu.hpp index c03bae46..c57b5581 100644 --- a/higan/ws/cpu/cpu.hpp +++ b/higan/ws/cpu/cpu.hpp @@ -27,6 +27,7 @@ struct CPU : Processor::V30MZ, Thread, IO { auto ramWrite(uint16 addr, uint8 data) -> void; //io.cpp + auto keypadRead() -> uint4; auto portRead(uint16 addr) -> uint8 override; auto portWrite(uint16 addr, uint8 data) -> void override; @@ -49,8 +50,8 @@ struct CPU : Processor::V30MZ, Thread, IO { uint16 dmaLength; //$0048 DMA_CTRL - bool dmaEnable; - bool dmaMode; //0 = increment; 1 = decrement + uint1 dmaEnable; + uint1 dmaMode; //0 = increment; 1 = decrement //$00b0 INT_BASE uint8 interruptBase; @@ -60,6 +61,11 @@ struct CPU : Processor::V30MZ, Thread, IO { //$00b4 INT_STATUS uint8 interruptStatus; + + //$00b5 KEYPAD + uint1 ypadEnable; + uint1 xpadEnable; + uint1 buttonEnable; } r; }; diff --git a/higan/ws/cpu/io.cpp b/higan/ws/cpu/io.cpp index c0045809..4cf779c2 100644 --- a/higan/ws/cpu/io.cpp +++ b/higan/ws/cpu/io.cpp @@ -1,3 +1,30 @@ +auto CPU::keypadRead() -> uint4 { + uint1 orientation = 1; + uint4 data = 0; + + if(r.ypadEnable) { + data |= interface->inputPoll(orientation, 0, (uint)Keypad::Y1) << 0; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::Y2) << 1; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::Y3) << 2; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::Y4) << 3; + } + + if(r.xpadEnable) { + data |= interface->inputPoll(orientation, 0, (uint)Keypad::X1) << 0; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::X2) << 1; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::X3) << 2; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::X4) << 3; + } + + if(r.buttonEnable) { + data |= interface->inputPoll(orientation, 0, (uint)Keypad::Start) << 1; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::A) << 2; + data |= interface->inputPoll(orientation, 0, (uint)Keypad::B) << 3; + } + + return data; +} + auto CPU::portRead(uint16 addr) -> uint8 { //DMA_SRC if(addr == 0x0040) return r.dmaSource.byte(0); @@ -42,6 +69,14 @@ auto CPU::portRead(uint16 addr) -> uint8 { //INT_STATUS if(addr == 0x00b4) return r.interruptStatus; + //KEYPAD + if(addr == 0x00b5) return ( + keypadRead() << 0 + | r.ypadEnable << 4 + | r.xpadEnable << 5 + | r.buttonEnable << 6 + ); + return 0x00; } @@ -91,6 +126,14 @@ auto CPU::portWrite(uint16 addr, uint8 data) -> void { return; } + //KEYPAD + if(addr == 0x00b5) { + r.ypadEnable = data.bit(4); + r.xpadEnable = data.bit(5); + r.buttonEnable = data.bit(6); + return; + } + //INT_ACK if(addr == 0x00b6) { r.interruptStatus &= ~data; diff --git a/higan/ws/interface/interface.cpp b/higan/ws/interface/interface.cpp index ea242bf1..0b5b8a0f 100644 --- a/higan/ws/interface/interface.cpp +++ b/higan/ws/interface/interface.cpp @@ -23,14 +23,14 @@ Interface::Interface() { media.append({ID::WonderSwanColor, "WonderSwan Color", "wsc", true}); { Device device{0, ID::DeviceHorizontal, "Controller"}; - device.input.append({ 0, 0, "X1"}); - device.input.append({ 1, 0, "X2"}); - device.input.append({ 2, 0, "X3"}); - device.input.append({ 3, 0, "X4"}); - device.input.append({ 4, 0, "Y1"}); - device.input.append({ 5, 0, "Y2"}); - device.input.append({ 6, 0, "Y3"}); - device.input.append({ 7, 0, "Y4"}); + device.input.append({ 0, 0, "Y1"}); + device.input.append({ 1, 0, "Y2"}); + device.input.append({ 2, 0, "Y3"}); + device.input.append({ 3, 0, "Y4"}); + device.input.append({ 4, 0, "X1"}); + device.input.append({ 5, 0, "X2"}); + device.input.append({ 6, 0, "X3"}); + device.input.append({ 7, 0, "X4"}); device.input.append({ 8, 0, "B"}); device.input.append({ 9, 0, "A"}); device.input.append({10, 0, "Start"}); @@ -39,14 +39,14 @@ Interface::Interface() { } { Device device{1, ID::DeviceVertical, "Controller"}; - device.input.append({ 0, 0, "X1"}); - device.input.append({ 1, 0, "X2"}); - device.input.append({ 2, 0, "X3"}); - device.input.append({ 3, 0, "X4"}); - device.input.append({ 4, 0, "Y1"}); - device.input.append({ 5, 0, "Y2"}); - device.input.append({ 6, 0, "Y3"}); - device.input.append({ 7, 0, "Y4"}); + device.input.append({ 0, 0, "Y1"}); + device.input.append({ 1, 0, "Y2"}); + device.input.append({ 2, 0, "Y3"}); + device.input.append({ 3, 0, "Y4"}); + device.input.append({ 4, 0, "X1"}); + device.input.append({ 5, 0, "X2"}); + device.input.append({ 6, 0, "X3"}); + device.input.append({ 7, 0, "X4"}); device.input.append({ 8, 0, "B"}); device.input.append({ 9, 0, "A"}); device.input.append({10, 0, "Start"}); diff --git a/higan/ws/memory/memory.cpp b/higan/ws/memory/memory.cpp index 271ca68d..d0004501 100644 --- a/higan/ws/memory/memory.cpp +++ b/higan/ws/memory/memory.cpp @@ -2,8 +2,8 @@ namespace WonderSwan { -uint8 iram[64 * 1024] = {0}; -IO* iomap[64 * 1024] = {0}; +uint8 iram[64 * 1024]; +IO* iomap[64 * 1024] = {nullptr}; Bus bus; auto IO::power() -> void { @@ -21,15 +21,16 @@ auto IO::portWrite(uint16 addr, uint8 data) -> void { } auto Bus::read(uint20 addr) -> uint8 { - if(addr < 0x10000) return cpu.ramRead(addr); - if(addr < 0x20000) return cartridge.ramRead(addr); - return cartridge.romRead(addr); + if(addr.bits(16,19) == 0) return cpu.ramRead(addr); + if(addr.bits(16,19) == 1) return cartridge.ramRead(addr); + if(addr.bits(16,19) >= 2) return cartridge.romRead(addr); + unreachable; } auto Bus::write(uint20 addr, uint8 data) -> void { - if(addr < 0x10000) return cpu.ramWrite(addr, data); - if(addr < 0x20000) return cartridge.ramWrite(addr, data); - return cartridge.romWrite(addr, data); + if(addr.bits(16,19) == 0) return cpu.ramWrite(addr, data); + if(addr.bits(16,19) == 1) return cartridge.ramWrite(addr, data); + if(addr.bits(16,19) >= 2) return cartridge.romWrite(addr, data); } } diff --git a/higan/ws/ppu/ppu.cpp b/higan/ws/ppu/ppu.cpp index 8edb79eb..267a8b3d 100644 --- a/higan/ws/ppu/ppu.cpp +++ b/higan/ws/ppu/ppu.cpp @@ -14,7 +14,7 @@ auto PPU::Enter() -> void { auto PPU::main() -> void { if(status.vclk < 144) { for(uint x = 0; x < 224; x++) { - pixel = {Pixel::Source::None, 0xfff}; + renderBack(); renderScreenOne(); renderScreenTwo(); renderSprite(); diff --git a/higan/ws/ppu/ppu.hpp b/higan/ws/ppu/ppu.hpp index fe63c058..bd2517f5 100644 --- a/higan/ws/ppu/ppu.hpp +++ b/higan/ws/ppu/ppu.hpp @@ -13,6 +13,7 @@ struct PPU : Thread, IO { auto portWrite(uint16 addr, uint8 data) -> void override; //render.cpp + auto renderBack() -> void; auto renderScreenOne() -> void; auto renderScreenTwo() -> void; auto renderSprite() -> void; @@ -26,7 +27,7 @@ struct PPU : Thread, IO { } status; struct Pixel { - enum class Source : uint { None, ScreenOne, ScreenTwo, Sprite }; + enum class Source : uint { Back, ScreenOne, ScreenTwo, Sprite }; Source source; uint12 color; } pixel; diff --git a/higan/ws/ppu/render.cpp b/higan/ws/ppu/render.cpp index 24c57182..b694fe74 100644 --- a/higan/ws/ppu/render.cpp +++ b/higan/ws/ppu/render.cpp @@ -1,3 +1,8 @@ +auto PPU::renderBack() -> void { + uint4 poolColor = 15 - r.pool[r.backColorIndex]; + pixel = {Pixel::Source::Back, poolColor << 0 | poolColor << 4 | poolColor << 8}; +} + auto PPU::renderScreenOne() -> void { if(!r.screenOneEnable) return; @@ -81,7 +86,7 @@ auto PPU::renderSprite() -> void { uint14 spriteBase = r.spriteBase << 9; uint7 spriteIndex = r.spriteFirst; - uint8 spriteCount = max(128, (uint)r.spriteCount); + uint8 spriteCount = min(128, (uint)r.spriteCount); while(spriteCount--) { uint32 sprite; sprite.byte(0) = iram[spriteBase + (spriteIndex << 2) + 0]; @@ -91,7 +96,6 @@ auto PPU::renderSprite() -> void { spriteIndex++; if(r.spriteWindowEnable && sprite.bit(12) && !windowInside) continue; - if(pixel.source == Pixel::Source::ScreenTwo && !sprite.bit(13)) continue; uint8 spriteY = sprite.bits(16,23); uint8 spriteX = sprite.bits(24,31); @@ -112,6 +116,7 @@ auto PPU::renderSprite() -> void { uint2 tileColor = (d0 & tileMask ? 1 : 0) | (d1 & tileMask ? 2 : 0); if(sprite.bit(11) && tileColor == 0) continue; + if(!sprite.bit(13) && pixel.source == Pixel::Source::ScreenTwo) continue; uint3 paletteColor = r.palette[8 + sprite.bits(9,11)].color[tileColor]; uint4 poolColor = 15 - r.pool[paletteColor]; diff --git a/higan/ws/system/system.hpp b/higan/ws/system/system.hpp index b7a8fe2a..fb5c9b31 100644 --- a/higan/ws/system/system.hpp +++ b/higan/ws/system/system.hpp @@ -1,3 +1,9 @@ +enum class Keypad : uint { + Y1, Y2, Y3, Y4, + X1, X2, X3, X4, + B, A, Start, +}; + struct System : IO { enum class Revision : uint { WonderSwan, //SW-001 (ASWAN) diff --git a/icarus/core/wonderswan-color.cpp b/icarus/core/wonderswan-color.cpp index c0fcd18d..1745121f 100644 --- a/icarus/core/wonderswan-color.cpp +++ b/icarus/core/wonderswan-color.cpp @@ -18,7 +18,7 @@ auto Icarus::wonderSwanColorManifest(vector& buffer, string location) - } if(settings["icarus/UseHeuristics"].boolean() && !manifest) { - WonderSwanColorCartridge cartridge{buffer.data(), buffer.size()}; + WonderSwanCartridge cartridge{buffer.data(), buffer.size()}; if(manifest = cartridge.manifest) { manifest.append("\n"); manifest.append("information\n"); diff --git a/icarus/heuristics/wonderswan-color.cpp b/icarus/heuristics/wonderswan-color.cpp deleted file mode 100644 index 4d5927b1..00000000 --- a/icarus/heuristics/wonderswan-color.cpp +++ /dev/null @@ -1,16 +0,0 @@ -struct WonderSwanColorCartridge { - WonderSwanColorCartridge(uint8_t* data, uint size); - - string manifest; - -//private: - struct Information { - } information; -}; - -WonderSwanColorCartridge::WonderSwanColorCartridge(uint8_t* data, uint size) { - if(size < 0x10000) return; - - manifest.append("board\n"); - manifest.append(" rom name=program.rom size=0x", hex(size), "\n"); -} diff --git a/icarus/heuristics/wonderswan.cpp b/icarus/heuristics/wonderswan.cpp index b68c2969..be1f5d50 100644 --- a/icarus/heuristics/wonderswan.cpp +++ b/icarus/heuristics/wonderswan.cpp @@ -5,12 +5,34 @@ struct WonderSwanCartridge { //private: struct Information { + bool color; + + string ramType; + uint ramSize; } information; }; WonderSwanCartridge::WonderSwanCartridge(uint8_t* data, uint size) { if(size < 0x10000) return; + auto metadata = data + size - 16; + + information.color = metadata[7]; + + switch(metadata[11]) { + default: information.ramType = ""; information.ramSize = 0; break; + case 0x01: information.ramType = "sram"; information.ramSize = 8 * 1024; break; + case 0x02: information.ramType = "sram"; information.ramSize = 32 * 1024; break; + case 0x03: information.ramType = "sram"; information.ramSize = 128 * 1024; break; + case 0x04: information.ramType = "sram"; information.ramSize = 256 * 1024; break; + case 0x05: information.ramType = "sram"; information.ramSize = 512 * 1024; break; + case 0x10: information.ramType = "eeprom"; information.ramSize = 128; break; + case 0x20: information.ramType = "eeprom"; information.ramSize = 2048; break; + case 0x50: information.ramType = "eeprom"; information.ramSize = 1024; break; + } + manifest.append("board\n"); manifest.append(" rom name=program.rom size=0x", hex(size), "\n"); + if(information.ramType && information.ramSize) + manifest.append(" ram name=save.ram type=", information.ramType, " size=0x", hex(information.ramSize), "\n"); } diff --git a/icarus/icarus.cpp b/icarus/icarus.cpp index 8a1aca54..61374449 100644 --- a/icarus/icarus.cpp +++ b/icarus/icarus.cpp @@ -23,7 +23,6 @@ Settings settings; #include "heuristics/game-boy.cpp" #include "heuristics/game-boy-advance.cpp" #include "heuristics/wonderswan.cpp" -#include "heuristics/wonderswan-color.cpp" #include "heuristics/bs-memory.cpp" #include "heuristics/sufami-turbo.cpp"