A very basic hardware test shows that the ARMMSG doesn't change until
IOS replies. (People could have disassembled IOS to verify this too...)
Console:
sending request at 00034640 - ARMMSG 133e0fa0
00000000000000000000000000000010(ack) - ARMMSG 133e0fa0
00000000000000000000000000000100(reply) - ARMMSG 00034640
Dolphin, prior to this fix:
sending request (00034640) - ARMMSG 133e0fa0
00000000000000000000000000000011(ack) - ARMMSG 00034640
00000000000000000000000000000100(reply) - ARMMSG 00034640
Dolphin, after this fix:
sending request at 00034640 - ARMMSG 133e0fa0
00000000000000000000000000000011(ack) - ARMMSG 133e0fa0
00000000000000000000000000000100(reply) - ARMMSG 00034640
(Yes, note that the X1 bit is still set. This is a bug that I will
fix in the next commit.)
The IPC interrupt is triggered when IY1/IY2 is set and Y1/Y2 is written
to even when this results in clearing the bit.
This shouldn't change anything in practice but it's a difference
that Dolphin wasn't taking into account, which made me waste some time
when I was writing a hwtest :/
This adjusts IOS IPC timing to be closer to actual hardware:
* Emulate the IPC interrupt delay. On a real Wii, from the point of
view of the PPC, the IPC interrupt appears to fire about 100 TB ticks
after Y1/Y2 is seen.
* Fix the IPC acknowledgement delay. Dolphin was much, much too fast.
* Fix Device::GetDefaultReply to return more reasonable delays. Again,
Dolphin was way too fast. We now use a more realistic, average reply
time for most requests.
Note: the previous result from https://dolp.in/pr6374 is flawed.
GetTicketViews definitely takes more than 25µs to reply.
The reason the reply delay was so low is because an invalid
parameter was passed to the libogc wrapper, which causes it to
immediately return an error code (-4100).
* Fix the response delay for various replies that come from the kernel:
fd table full, unknown resource manager / device, invalid fd,
unknown IPC command.
Source: af320e4/iostest/ipc_timing.cpp
While the code is namespaced out properly, the files weren't separated
into their own directory. This moves the files so that introducing a general
interface is easier in the future for supporting other architectures.
This saves us from having to call GetPath when the same file is being
read over and over. (GetPath is more expensive than GetOffset due to
it iterating through parts of the file system and creating strings.)
This lets Dolphin know if a configured GameCube Controller should actually
be treated as connected or not.
Talked to @JMC47 a bit about this last night. My use-case is that all of
my controllers are the same hardware (Xbox One controllers) so share the
same configuration (modulo device number). Treating them all as always
connected isn't a problem for most games, but in some (Smash Bros.) it
forces me to go find a keyboard/mouse and unconfigure any controllers
that I don't actually have connected. Hotplugging devices (works on macOS,
at least) + this patch remove my need to ever touch the Controller Config
dialog while in a game.
This patch makes the following changes:
- A new `BooleanSetting` in `GCPadEmu` called "Always Connected", which
defaults to false.
- `ControllerEmu` tracks whether the default device is connected on every
call to `UpdateReferences()`.
- `GCPadEmu.GetStatus()` now sets err bit to `PAD_ERR_NO_CONTROLLER` if
the default device isn't connected.
- `SIDevice_GCController` handles `PAD_ERR_NO_CONTROLLER` by imitating the
behaviour of `SIDevice_Null` (as far as I can tell, this is the only use
of the error bit from `GCPadStatus`).
I wanted to add an OSD message akin to the ones when Wiimotes get
connected/disconnected, but I haven't yet found where to put the logic.
The main problem was that the volume of the mixer wasn't savestated.
The volume is typically 0 at the beginning of a game, so loading a
savestate at the beginning of a game would lead to silent DTK audio.
I also added savestating to StreamADPCM.cpp.
Nowadays that Dolphin detects regions of discs properly and doesn't
force programs with unknown regions (such as homebrew) into running
under a certain region, the "Force Console as NTSC-J" option is
practically useless for making anything run correctly. Enabling it
is however an easy way to totally break many non-Japanese games.
The GameCube's sample rate is slightly different due to a hardware bug.
The exact numbers are (54000000 / 1124) for GameCube and (54000000 / 1125)
on Wii. I also modified 32KHz mode. This fixes audio desyncs in several
GameCube games and severe issues in Sonic Mega Collection.
A bunch of changes, looks mainly like bug fixes and code cleanup.
Notable changes:
- `cubeb_get_min_latency`'s signature was changed to take params via
pointer, requiring Dolphin code to be tweaked in two places.
- A fix for kinetiknz/cubeb#320, as reported by @shuffle2
- Fixed build on FreeBSD (kinetiknz/cubeb#344), as contributed by @endrift
When an ACCOV is triggered, the accelerator stops reading back anything
and updating the current address until the YN2 register is set.
This is kept track of internally by the DSP; this state is not exposed
via any register.
However, we need to emulate this behaviour correctly because some
ucodes rely on it (notably AX GC); failure to emulate it will result
in reading past the end and start address for non-looped voices.
Slightly cleaner, allows DSP accelerator behaviour to be
added to both HLE and LLE pretty easily, and makes the accelerator
easier to unit test.
I chose to include all accelerator state as private members, and
to expose state that is accessible via registers with getters/setters.
It's more verbose, yes, but it makes it very clear what is part of
the accelerator state and what isn't (e.g. coefs).
This works quite well for registers, since the accelerator can do
whatever it wants internally. For example, the start/end/current
addresses are masked -- having a getter/setter makes it easier to
enforce the mask.
The logic is entirely the same; only the inputs and outputs are
different, so deduplicating makes sense.
This will make fixing accelerator issues easier.
Ideally Common.h wouldn't be a header in the Common library, and instead be renamed to something else, like PlatformCompatibility.h or something, but even then, there's still some things in the header that don't really fall under that label
This moves the version strings out to their own version header that doesn't dump a bunch of other unrelated things into scope, like what Common.h was doing.
This also places them into the Common namespace, as opposed to letting them sit in the global namespace.
Based on hardware tests, masking occurs for the accelerator registers.
This fixes Red Steel and Far Cry Vengeance, which rely on this behavior
when reading back the current playback position from the DSP.
Since all queues are FIFO data structures, the name wasn't informative
as to why you'd use it over a normal queue. I originally thought it had
something to do with the hardware graphics FIFO.
This renames it using the common acronym SPSC, which stands for
single-producer single-consumer, and is most commonly used to talk about
lock-free data structures, both of which this is.