Many specializations of stringify store a reference to the wrapped
value. Therefore, passing arguments to make_string() by value can be
disastrous if the compiler does not perform copy elision and stringify
stores a reference to a variable that goes out of scope when
make_string() returns.
Cherry-picked from ares commit 3d826f5b266027529f0c12211c744a23bbe25a56.
Commit 712ed9b6b0 changed the way that the Sufami
Turbo base cartridge was detected, but it caused crashes. Apparently the way we
were converting the binary ROM data to a string for comparison, was actually
calling the wrong `string` constructor. Let's more explicitly create a
string_view instead of hoping for the compiler to pick a suitable constructor
chain.
The Sufami Turbo base cartridge is listed in the Super Famicom verified dump
database, so it did not use the heuristics. It turns out the heuristic detection
wouldn't have worked anyway - although the game's header does contain the serial
A9PJ, the heuristic revision() method does not report that serial at all.
Meanwhile, the serial A9PJ is *also* used by the game Bishoujo Senshi Sailor
Moon SuperS - Fuwafuwa Panic, so loading this game would prompt for Sufami Turbo
mini-cartridges even though the game could not make use of them.
Fixes#323
Since we have different hosts for different builds, let's try linking to them
directly. I vaguely recall this stopped working at some point, but we'll try
again.
>Regarding PLB, it looks like it reads from $200 and snes9x, mesen,
bsnes, and the official CPU manual all got it wrong.
Reproduced and verified on real hardware via
https://github.com/gilyon/snes-tests
Although Nintendo made many different cartridge circuit boards with different
memory mappings, ROMs do not indicate which specific board they are intended
to work with. Super Famicom emulators traditionally group mutually-compatible
mappings together and use heuristics to guess which family of mappings the
game expects.
There's one family of mappings that maps ROM data to the top half ($8000-$FFFF)
of memory banks in the Super Famicom address space. For historical reasons,
this family is called "LoROM" and has three main variants:
1. ROM only, mapped to the top half of every possible bank.
The boards database calls this "LOROM".
2. ROM mapped to the top half of every possible bank,
RAM mapped to the bottom half of banks 70-7d,f0-ff.
The boards database calls this "LOROM-RAM"
3. ROM mapped to the top half of low-numbered banks,
RAM mapped to both halves of banks 70-7d,f0-ff.
The boards database calls this "LOROM-RAM#A"
The largest official game that used variant 3 was 1MiB, so a common heuristic
is "if the ROM is 2MiB or less, use variant 3, otherwise use variant 2".
2MiB is used as the threshold instead of 1MiB, perhaps so somebody can expand a
commercial ROM that uses variant 3 without having to rework it to suit a
different mapping.
Since v107 or so, higan (and by extension, bsnes) has implemented variant 3 by
mapping ROM to banks 00-3f,80-bf, which exactly fits a 2MiB ROM. However,
other emulators like Mesen, snes9x and higan v106 implement it by mapping ROM
to banks 00-6f,80-ef, all the space that is left after the RAM is mapped.
This doesn't affect any verified games in the `Super Famicom.bml` database,
since those have specific, accurate memory maps. It also won't affect
well-written games that only read from memory addresses they have populated.
However, homebrew games and ROM hacks that have never existed on a real circuit
board depend on these heuristics across all devices that read Super Famicom
ROMs, including software emulators, flash-carts, and FPGA implementations, so
bsnes should match what other emulators do.
Fixes#278.