4dsdev
Views: 1,383,821 Main | Rules/FAQ | Memberlist | Active users | Last posts | Calendar | Stats | Online users | Search 03-28-24 04:54 PM
Guest:

0 users reading DSP protocol RE | 1 bot

Main - Reverse-engineering - DSP protocol RE Hide post layouts | New reply


yuriks
Posted on 06-15-15 03:03 AM (rev. 6 of 06-16-15 08:25 PM) Link | #212
I'm starting to reverse engineer the DSP protocol, which games use to communicate with the signed binary running in the DSP. This is interesting to explore a possible HLE implementation in Citra, but more importantly, should hopefully open the way for better and more reliable sound in homebrew.

At least initially I plan to do mostly black-box RE, by taking traces of DSP communication with Citra and trying to decode those and apply them to hardware. Right now I'm examining Bravely Default, but from my analysis of a bunch of DSP bins, they have few differences so this should apply to most games. Hopefully I'll use this thread as a log/dump for any info I discover.


Startup Sequence:

- WriteProcessPipe: 0000 160C, first number is unknown, second is garbage read from the stack and as such tends to differ from game to game.
- WriteReg0x10: 4000, ???
- ReadPipeIfPossible: one u16 is read here, which indicates the number of addresses to read in the next step
- ReadPipeIfPossible: N u16 DSP addresses are read here, which point to the location of various control variables within DSP memory. After reading these are passed through ConvertProcessAddressFromDspRam to convert them to ARM11 userspace addesses. An additional copy of these variables is present with offset 0x10000 (in DSP words).
- WriteReg0x10: 4000, again

In BD the returned addresses and their translations are:
- BFFF -> 1FF5 7FFE
- 9E8E -> 1FF5 3D1C
- 8680 -> 1FF5 0D00
- A78E -> 1FF5 4F1C
- 9430 -> 1FF5 2860
- 8400 -> 1FF5 0800
- 8540 -> 1FF5 0A80
- 948E -> 1FF5 291C
- 8710 -> 1FF5 0E20
- 8410 -> 1FF5 0820
- A90E -> 1FF5 521C
- AA0E -> 1FF5 541C
- AACE -> 1FF5 559C
- AC4E -> 1FF5 589C
- AC58 -> 1FF5 58B0

From here on, when I say "7FFE" for example, I'm referring to the mirror variables at 0x1FF57FFE and 0x1FF77FFE.

From here on communication with the DSP is done by directly writing/reading to the DSP RAM areas mapped in the process at 0x1FF5000 and 0x1FF70000. The two areas (each size 0x8000) are used alternately, and at the end an incrementing counter is written to 7FFE. This indicates that a double-buffering scheme is used where the game writes the data to the variables and then increases the counter to let the DSP know to process the new page. The page switch seems to happen once per audio frame (probably around ~4.88ms).

yuriks
Posted on 06-15-15 09:36 AM Link | #214
After reversing some game init code, I managed to discern a few arrays and sub-structures inside the shared memory areas:

[image]

My current goal is to figure out how the address of the sound buffers which are cache-flushed are passed to the DSP.


Main - Reverse-engineering - DSP protocol RE Hide post layouts | New reply

Page rendered in 0.013 seconds. (2048KB of memory used)
MySQL - queries: 26, rows: 65/65, time: 0.006 seconds.
[powered by Acmlm] Acmlmboard 2.064 (2018-07-20)
© 2005-2008 Acmlm, Xkeeper, blackhole89 et al.