JayFoxRox / xqemu

Personal development repository for XQEMU (original Xbox Emulator)
14 stars 1 forks source link

Implement support for APU DSP Memory access (fix EP, add GP) #11

Closed JayFoxRox closed 6 years ago

JayFoxRox commented 6 years ago

This is required to read-back results of MCPX APU DSP calculations more easily, so without this change, debugging the DSP from the outside is a lot harder.

This is code from 2017, but it has gotten a lot of additional unit testing and research on actual hardware the past weeks.

Once this patch is applied, we can use xboxpy and my existing dsp-homebrew script to send custom code to the DSP. This allows us to verify instruction behaviour, as the script also works with a real Xbox.

I was unsure about the DSP memory sizes, but then decided to confirm them:

I have written a program to measure the DSP data memory sizes (Click to unfold)
Here is the code for measuring Y-Memory size: ``` start move y:$
, a0 move a0, x:$000000 jmp start ``` Where `
` was raised using a step-size. I then wrote a random value to `y:$
` using the CPU and checked if it appeared in `x:$000000`. I did this for 2 random values per `
`. When any of these checks failed, the previous `
` was reverted and a smaller step-size was used. For measuring the size of X-Memory instead of Y-Memory I have simply swapped `x:` and `y:` (and respective lookups on the CPU). For measuring the size of the MIXBUF, I set a higher start offset (0x1400) in X-Memory and re-ran the same program as before for measuring X-Size. Strangely, I got 0x7E0 words here. The last 0x20 words were not accessible. See known problem below.
I also wrote a program to measure the DSP program memory size (Click to unfold) Here is the code for measuring P-Memory size: ``` start move y:$000000, a0 move a0, x:$000000 jmp start ``` Where `` is an increasing number of `nop` instructions. By raising the number of `nop` instructions, the write to `x:$000000` will eventually be outside of program memory. This will result in either the value in `y:$000000` not updating or the Xbox crashing. Keep in mind that the other instructions take up some memory (6 words) so the number of `nop` instructions (1 word each) is not the same as the program memory size.

[The results of these tests have been added to XboxDevWiki](http://xboxdevwiki.net/DSP#Memory_Size). According to existing code, the last 0x400 words of GP X-Memory (so, offset 0xC00) should be MIXBUF. My tests could not confirm this behaviour. I have observed MIXBUF at `x:$001400`, 0x380 words (See problem regarding size below). I assume that DirectSound uses the last 0x400 words of X-Memory RAM for the DMA from the actual MIXBUF; but X-Memory RAM has no relation to MIXBUF in hardware. ### Known problems #### Only 32 bit access works Also see FIXME 91. This might cause trouble in games, so this PR should be tested with a handful of games. I did not test a single game yet. #### MIXBUF size not known I was unable to access the last 0x20 words of MIXBUF with my unit test. I assume this might have to do with VP or EP having control and overwriting my data. I still assume a size of 0x400 bytes, not 0x380; so I implemented 0x400 in XQEMU, but documented 0x380 for now. To be fair, I was surprised that I had write access to MIXBUF at all, as I had assumed the VP would instantly overwrite data. #### EP and GP use the same memory map in XQEMU Memory size defines are used by both DSP instances, so we use the same memory map for GP and EP. This is not so much a problem with this PR, but XQEMU in general. This even means that the EP currently has MIXBUF access which is not possible on real hardware. I'll create an issue after merge. I did not fix it here because it leads to design decisions and what we have works (our EP is just more powerful than on real hardware). --- This patch *could* fix bugs in the following games: * Top Gear RPM Tuning * Grand Theft Auto: San Andreas These games previously ran into the following issue in dsp_cpu: `assert(address < DSP_XRAM_SIZE);`. However, I did not test those games because it's not the motivation for this patch: I just want to be able to debug the DSP. --- If you want to [test this PR with my DSP homebrew](https://github.com/JayFoxRox/xbox-tools/tree/master/python-scripts), keep in mind that nxdk-rdt does not support `CALL` in master yet (meaning it can't remote control the DSP using existing code). You will need to look for nxdk-rdt and xboxpy PRs to work around this. Testing using XBDM should work fine.
JayFoxRox commented 6 years ago

Upstreamed.