This is a port of the NTSC patch to the Japanese and PAL regions. Bonta
converted the GBA code, and leoetlino helped convert some addresses for
the japanese version.
The workaround added in 30f9f31 caused a regression where Dolphin
incorrectly replaced runs of one byte with runs of another byte
when writing WIA and RVZ files. ReuseID::operator< was always
returning false unless the ReuseIDs being compared had different
partition keys, which caused std::map<ReuseID, GroupEntry>
to treat all ReuseIDs with the same partition key as equal.
de Blob 2 has the same engine as de blob and shares a lot of the same
issues. I copied the settings used for de blob. It seems defer EFB
copies was the main culprit, but force texture filtering could also
cause problems.
This actually eliminates any setting pertaining to SD cards from the
NetPlay dialog, as it would effectively just be a duplicate of the
setting in the Wii pane, potentially causing confusion.
This also enables save data writing by default, as this is probably
what most players want, and should avoid them losing hours of progress
because they forgot to tick a checkbox.
This implementation is pretty efficient in my opinion. And "As
long as we aren't falling back to interpreter we're winning a lot"
applies to basically every instruction to some degree anyway.
The dcbz instruction needs to lock W30 so that the slowmem code will
push and pop it when calling into C++. Also, the slowmem code expects
that the address is present in W0, so replace the use of W0 as a scratch
register in the fastmem code with the now locked W30.
We currently have a bug when calling Arm64GPRCache::Flush with
FlushMode::MaintainState, zero free host registers, and at least
one guest register containing an immediate. We end up grabbing
a temporary register from the register cache in order to be
able to write the immediate to memory, but grabbing a temporary
register when there are zero free registers causes the least
recently used register to be flushed in a way which does not
maintain the state of the register cache.
To get around this, require callers to pass in a temporary
register in the GPR MaintainState case. In other cases,
passing in a temporary register is not required but can help
avoid spilling a register (if the caller already had a
temporary register at hand anyway, which in particular will
be the case in my upcoming memcheck pull request).