bsnes/sfc/cartridge/cartridge.hpp

116 lines
3.1 KiB
C++
Raw Normal View History

struct Cartridge : property<Cartridge> {
enum class Region : unsigned { NTSC, PAL };
2011-03-04 08:57:00 +00:00
Update to v074r10 release. byuu says: Major WIP, countless changes. I really went to town on cleaning up the source today with all kinds of new ideas. I'll post the ones I remember, use diff -ru to get the rest. What I like the most is my new within template: template<unsigned lo, unsigned hi> alwaysinline bool within(unsigned addr) { static const unsigned mask = ~(hi ^ lo); return (addr & mask) == lo; } Before, you would see code like this: if((addr & 0xe0e000) == 0x206000) { //$20-3f:6000-7fff The comment is basically necessary, and you have to trust that the mask is right, or do the math yourself. Now, it looks like this: if(within<0x20, 0x3f, 0x6000, 0x7fff>(addr)) { That's the same as within<0x206000, 0x3f7fff>, I just made an SNES-variant to more closely simulate my XML mapping style: 20-3f:6000-7fff. Now obviously this has limitations, it only works in base-2 and it can't manage some tricky edge cases like (addr & 0x408000) == 0x008000 for 00-3f|80-bf:8000-ffff. But for the most part, I'll be using this where I can. The Game Boy is fully ported over to it (via the MBCs), but the SNES only has the BS-X town cartridge moved over so far. SuperFX and SA-1 at the very least could benefit. Next up, since the memory map is now static, there's really no reason to remap the entire thing at power-on and reset. So it is now set up at cartridge load and that's it. I moved the CPU/PPU/WRAM mapping out of memory.cpp and into their respective processors. A bit of duplication only because there are multiple processor cores for the different profiles, but I'm not worried about that. This is also going to be necessary to fix the debugger. Next, Coprocessor::enable() actually does what I initially intended it to now: it is called once to turn a chip on after cartridge load. It's not called on power cycle anymore. This should help fix power-cycle on my serial simulation code, and was needed to map the bus exactly one time. Although most stuff is mapped through XML, some chips still need some manual hooks for monitoring and such (eg S-DD1.) Next, I've started killing off memory::, it was initially an over-reaction to the question of where to put APURAM (in the SMP or DSP?). The idea was to have this namespace that contained all memory for everything. But it was very annoying and tedious, and various chips ignored the convention anyway like ST-0011 RAM, which couldn't work anyway since it is natively uint16 and not uint8. Cx4 will need 24-bit RAM eventually, too. There's 8->24-bit functions in there now, because the HLE code is hideous. So far, all the cartridge.cpp memory:: types have been destroyed. memory::cartrom, memory::cartram become cartridge.rom and cartridge.ram. memory::cartrtc was moved into the SRTC and SPC7110 classes directly. memory::bsxflash was moved into BSXFlash. memory::bsxram and memory::bsxpram were moved into BSXCartridge (the town cartridge). memory::st[AB](rom|ram) were moved into a new area, snes/chip/sufamiturbo. The snes/chip moniker really doesn't work so well, since it also has base units, and the serial communications stuff which is through the controller port, but oh well, now it also has the base structure for the Sufami Turbo cartridge too. So now we have sufamiturbo.slotA.rom, sufamiturbo.slotB.ram, etc. Next, the ST-0010/ST-0011 actually save the data RAM to disk. This wasn't at all compatible with my old system, and I didn't want to keep adding memory types to check inside the main UI cartridge RAM loading and saving routines. So I built a NonVolatileRAM vector inside SNES::Cartridge, and any chip that has memory it wants to save and load from disk can append onto it : data, size, id ("srm", "rtc", "nec", etc) and slot (0 = cartridge, 1 = slot A, 2 = slot B) To load and save memory, we just do a simple: foreach(memory, SNES::cartridge.nvram) load/saveMemory(memory). As a result, you can now keep your save games in F1 Race of Champions II and Hayazashi Nidan Morita Shougi. Technically I think Metal Combat should work this way as well, having the RAM being part of the chip itself, but for now that chip just writes directly into cartridge.ram, so it also technically saves to disk for now. To avoid a potential conflict with a manipulated memory map, BS-X SRAM and PSRAM are now .bss and .bsp, and not .srm and .psr. Honestly I don't like .srm as an extension either, but it doesn't bother me enough to break save RAM compatibility with other emulators, so don't worry about that changing. I finally killed off MappedRAM initializing size to ~0 (-1U). A size of zero means there is no memory there just the same. This was an old holdover for handling MMIO mapping, if I recall correctly. Something about a size of zero on MMIO-Memory objects causing it to wrap the address, so ~0 would let it map direct addresses ... or something. Whatever, that's not needed at all anymore. BSXBase becomes BSXSatellaview, and I've defaulted the device to being attached since it won't affect non-BSX games anyway. Eventually the GUI needs to make that an option. BSXCart becomes BSXCartridge. BSXFlash remains unchanged. I probably need to make Coprocessor::disable() functions now to free up memory on unload, but it shouldn't hurt anything the way it is. libsnes is most definitely broken to all hell and back now, and the debugger is still shot. I suppose we'll need some tricky code to work with the old ID system, and we'll need to add some more IDs for the new memory types.
2011-01-24 08:59:45 +00:00
MappedRAM rom;
MappedRAM ram;
auto loaded() const -> bool { return _loaded; }
auto sha256() const -> string { return _sha256; }
auto region() const -> Region { return _region; }
readonly<bool> hasICD2;
readonly<bool> hasMCC;
readonly<bool> hasNSSDIP;
readonly<bool> hasEvent;
readonly<bool> hasSA1;
readonly<bool> hasSuperFX;
readonly<bool> hasARMDSP;
readonly<bool> hasHitachiDSP;
readonly<bool> hasNECDSP;
readonly<bool> hasEpsonRTC;
readonly<bool> hasSharpRTC;
readonly<bool> hasSPC7110;
readonly<bool> hasSDD1;
readonly<bool> hasOBC1;
readonly<bool> hasMSU1;
readonly<bool> hasSuperGameBoySlot;
readonly<bool> hasSatellaviewSlot;
readonly<bool> hasSufamiTurboSlots;
struct Mapping {
Update to v091r05 release. [No prior releases were posted to the WIP thread. -Ed.] byuu says: Super Famicom mapping system has been reworked as discussed with the mask= changes. offset becomes base, mode is gone. Also added support for comma-separated fields in the address fields, to reduce the number of map lines needed. <?xml version="1.0" encoding="UTF-8"?> <cartridge region="NTSC"> <superfx revision="2"> <rom name="program.rom" size="0x200000"/> <ram name="save.rwm" size="0x8000"/> <map id="io" address="00-3f,80-bf:3000-32ff"/> <map id="rom" address="00-3f:8000-ffff" mask="0x8000"/> <map id="rom" address="40-5f:0000-ffff"/> <map id="ram" address="00-3f,80-bf:6000-7fff" size="0x2000"/> <map id="ram" address="70-71:0000-ffff"/> </superfx> </cartridge> Or in BML: cartridge region=NTSC superfx revision=2 rom name=program.rom size=0x200000 ram name=save.rwm size=0x8000 map id=io address=00-3f,80-bf:3000-32ff map id=rom address=00-3f:8000-ffff mask=0x8000 map id=rom address=40-5f:0000-ffff map id=ram address=00-3f,80-bf:6000-7fff size=0x2000 map id=ram address=70-71:0000-ffff As a result of the changes, old mappings will no longer work. The above XML example will run Super Mario World 2: Yoshi's Island. Otherwise, you'll have to write your own. All that's left now is to work some sort of database mapping system in, so I can start dumping carts en masse. The NES changes that FitzRoy asked for are mostly in as well. Also, part of the reason I haven't released a WIP ... but fuck it, I'm not going to wait forever to post a new WIP. I've added a skeleton driver to emulate Campus Challenge '92 and Powerfest '94. There's no actual emulation, except for the stuff I can glean from looking at the pictures of the board. It has a DSP-1 (so SR/DR registers), four ROMs that map in and out, RAM, etc. I've also added preliminary mapping to upload high scores to a website, but obviously I need the ROMs first.
2012-10-09 08:25:32 +00:00
function<uint8 (unsigned)> reader;
function<void (unsigned, uint8)> writer;
string addr;
unsigned size = 0;
unsigned base = 0;
unsigned mask = 0;
Mapping() = default;
Update to v074r03 release. byuu says: You guys are going to hate the hell out of this one. It's twenty hours of non-stop work, no exaggeration at all. Started at 4AM, just wrapped up now at 8PM. I rewrote the entire memory subsystem. Old system: 65536 pages that map 256 bytes each Mapping a new page overwrites old page Granularity capped at 256 bytes minimum, requiring ST-001x to map 60:0000-00ff instead of 60:0000,0001 Classes inherit from MMIO and Memory, forcing only one mappable function per class, and fixed names MMIO sub-mapper inside memory: 00-3f:2000-5fff for one-byte granularity Can dynamically change the map at run-time, MMC register settings perform dynamic remapping New system: XML mapping is still based around banklo-bankhi:addrlo-addrhi, as that shapes almost everything on the SNES very well Internally, 2048 pages that map 8192 bytes each Pages are vectors, scans O(n) from last to first (O(log n) would not help, n is never > 3) Can multi-cast writes, but not reads [for the obvious reason of: which read do you return?] Can map reads and writes separately Granularity of one for entire 24-bit address range, no need for MMIO - whatever is in XML is exactly what you get Read/Write tables bind function callbacks, so I can have any number of functions with any names from any classes with no inheritance (no more uPD7725DR, uPD7725SR helpers, etc) Less memory usage overall due to less tables [ I tried 16 million tables and it used 2GB of RAM >_o ] Cannot dynamically change the map at run-time, MMC read/write functions perform address translation [worse average case speed, better worst case speed] Now the hate me part, functors can't beat virtual functions for speed. There are speed penalties involved: -4.5% on average games -11% on SuperFX games (SFX has its own bus) -15% on SA-1 games (SA-1 has two buses) Of course the two that need the speed the most get the biggest hits. I'm afraid there's really not a lot of wiggle room to boost speed back up. I suppose one bright spot is that we can much more easily try out entirely new mapping systems now, since the dynamic portions have been eliminated.
2011-01-15 04:30:29 +00:00
Mapping(const function<uint8 (unsigned)>&, const function<void (unsigned, uint8)>&);
Mapping(SuperFamicom::Memory&);
};
vector<Mapping> mapping;
struct Memory {
unsigned id;
string name;
};
vector<Memory> memory;
Update to higan v091r14 and ananke v00r03 releases. byuu says: higan changelog: - generates title displayed in emulator window by asking the core - core builds title solely from "information/title" ... if it's not there, you don't get a title at all - sub-system load menu is gone ... since there are multiple revisions of the SGB, this never really worked well anyway - to load an SGB, BS-X or ST cartridge, load the base cartridge first - "File->Load Game" moved to "Load->Import Game" ... may cause a bit of confusion to new users, but I don't like having a single-item menu, we'll just have to explain it to new users - browser window redone to look like ananke - home button here goes to ~/Emulation rather than just ~ like ananke, since this is the home of game folders - game folder icon is now the executable icon for the Tango theme (orange diamond), meant to represent a complete game rather than a game file or archive ananke changelog: - outputs GBC games to "Game Boy Color/" instead of "Game Boy/" - adds the file basename to "information/title" Known issues: - using ananke to load a GB game trips the Super Famicom SGB mode and fails (need to make the full-path auto-detection ignore non-bootable systems) - need to dump and test some BS-X media before releasing - ananke lacks BS-X Satellaview cartridge support - v092 isn't going to let you retarget the ananke/higan game folder path of ~/Emulation, you will have to wait for a future version if that bothers you so greatly [Later, after the v092 release, byuu posted this additional changelog: - kill laevateinn - add title() - add bootable, remove load - combine file, library - combine [][][] paths - fix SFC subtype handling XML->BML - update file browser to use buttons - update file browser keyboard handling - update system XML->BML - fix sufami turbo hashing - remove Cartridge::manifest ]
2012-12-25 05:31:55 +00:00
struct Information {
struct Markup {
string cartridge;
string gameBoy;
string satellaview;
string sufamiTurboA;
string sufamiTurboB;
} markup;
Update to higan v091r14 and ananke v00r03 releases. byuu says: higan changelog: - generates title displayed in emulator window by asking the core - core builds title solely from "information/title" ... if it's not there, you don't get a title at all - sub-system load menu is gone ... since there are multiple revisions of the SGB, this never really worked well anyway - to load an SGB, BS-X or ST cartridge, load the base cartridge first - "File->Load Game" moved to "Load->Import Game" ... may cause a bit of confusion to new users, but I don't like having a single-item menu, we'll just have to explain it to new users - browser window redone to look like ananke - home button here goes to ~/Emulation rather than just ~ like ananke, since this is the home of game folders - game folder icon is now the executable icon for the Tango theme (orange diamond), meant to represent a complete game rather than a game file or archive ananke changelog: - outputs GBC games to "Game Boy Color/" instead of "Game Boy/" - adds the file basename to "information/title" Known issues: - using ananke to load a GB game trips the Super Famicom SGB mode and fails (need to make the full-path auto-detection ignore non-bootable systems) - need to dump and test some BS-X media before releasing - ananke lacks BS-X Satellaview cartridge support - v092 isn't going to let you retarget the ananke/higan game folder path of ~/Emulation, you will have to wait for a future version if that bothers you so greatly [Later, after the v092 release, byuu posted this additional changelog: - kill laevateinn - add title() - add bootable, remove load - combine file, library - combine [][][] paths - fix SFC subtype handling XML->BML - update file browser to use buttons - update file browser keyboard handling - update system XML->BML - fix sufami turbo hashing - remove Cartridge::manifest ]
2012-12-25 05:31:55 +00:00
struct Title {
string cartridge;
string gameBoy;
string satellaview;
string sufamiTurboA;
string sufamiTurboB;
} title;
} information;
2013-01-14 12:10:20 +00:00
Cartridge() = default;
~Cartridge() { unload(); }
Update to higan v091r14 and ananke v00r03 releases. byuu says: higan changelog: - generates title displayed in emulator window by asking the core - core builds title solely from "information/title" ... if it's not there, you don't get a title at all - sub-system load menu is gone ... since there are multiple revisions of the SGB, this never really worked well anyway - to load an SGB, BS-X or ST cartridge, load the base cartridge first - "File->Load Game" moved to "Load->Import Game" ... may cause a bit of confusion to new users, but I don't like having a single-item menu, we'll just have to explain it to new users - browser window redone to look like ananke - home button here goes to ~/Emulation rather than just ~ like ananke, since this is the home of game folders - game folder icon is now the executable icon for the Tango theme (orange diamond), meant to represent a complete game rather than a game file or archive ananke changelog: - outputs GBC games to "Game Boy Color/" instead of "Game Boy/" - adds the file basename to "information/title" Known issues: - using ananke to load a GB game trips the Super Famicom SGB mode and fails (need to make the full-path auto-detection ignore non-bootable systems) - need to dump and test some BS-X media before releasing - ananke lacks BS-X Satellaview cartridge support - v092 isn't going to let you retarget the ananke/higan game folder path of ~/Emulation, you will have to wait for a future version if that bothers you so greatly [Later, after the v092 release, byuu posted this additional changelog: - kill laevateinn - add title() - add bootable, remove load - combine file, library - combine [][][] paths - fix SFC subtype handling XML->BML - update file browser to use buttons - update file browser keyboard handling - update system XML->BML - fix sufami turbo hashing - remove Cartridge::manifest ]
2012-12-25 05:31:55 +00:00
auto title() -> string;
auto load() -> void;
auto unload() -> void;
auto serialize(serializer&) -> void;
private:
auto loadSuperGameBoy() -> void;
auto loadSatellaview() -> void;
auto loadSufamiTurboA() -> void;
auto loadSufamiTurboB() -> void;
friend class Interface;
//markup.cpp
auto parseMarkup(const string&) -> void;
auto parseMarkupMap(Mapping&, Markup::Node) -> void;
auto parseMarkupMemory(MappedRAM&, Markup::Node, unsigned id, bool writable) -> void;
auto parseMarkupCartridge(Markup::Node) -> void;
auto parseMarkupICD2(Markup::Node) -> void;
auto parseMarkupMCC(Markup::Node) -> void;
auto parseMarkupSatellaview(Markup::Node) -> void;
auto parseMarkupSufamiTurbo(Markup::Node, bool slot) -> void;
auto parseMarkupNSS(Markup::Node) -> void;
auto parseMarkupEvent(Markup::Node) -> void;
auto parseMarkupSA1(Markup::Node) -> void;
auto parseMarkupSuperFX(Markup::Node) -> void;
auto parseMarkupARMDSP(Markup::Node) -> void;
auto parseMarkupHitachiDSP(Markup::Node, unsigned roms) -> void;
auto parseMarkupNECDSP(Markup::Node) -> void;
auto parseMarkupEpsonRTC(Markup::Node) -> void;
auto parseMarkupSharpRTC(Markup::Node) -> void;
auto parseMarkupSPC7110(Markup::Node) -> void;
auto parseMarkupSDD1(Markup::Node) -> void;
auto parseMarkupOBC1(Markup::Node) -> void;
auto parseMarkupMSU1(Markup::Node) -> void;
bool _loaded = false;
string _sha256;
Region _region = Region::NTSC;
};
extern Cartridge cartridge;