Views: 33,115,549 Homepage | Main | Rules/FAQ | Memberlist | Active users | Last posts | Calendar | Stats | Online users | Search 09-05-26 11:02 AM
Guest:

0 users reading DSP binary notes | 1 bot

Main - Development - DSP binary notes Hide post layouts | New reply


Arisotura
Posted on 07-03-25 11:18 PM (rev. 16 of 07-24-25 07:49 PM) Link | #7797
so far, this is about what I observe with the Let's Golf DSP binary. the basic idea is to observe the comm protocol and figure out how it works, so we can HLE it.

basic idea is that most DSP titles have ucodes with pretty similar feature sets, and likely share a same base protocol. then there's shit like the AAC binary in the DSi sound app, that's something else... but we'll work on it, too.

so.

Let's Golf


basic info

commands are sent by using the CMD registers to signal a new command then writing parameters over the DSP pipe (a FIFO buffer in DSP memory).

there are two separate channels for commands.

CMD0 seems to be graphics stuff:
* 0001 = scaling
* 0002 = yuv2rgb

CMD2 seems to be audio stuff:
* 0002 = play sound?

CMD2 serves to tell the other side that data was just written in a given pipe

other binaries have more commands, but prolly the same base shit.


init

after loading the binary and starting the DSP, the ARM9 checks CMD0/1/2. when all 3 registers return 1, the DSP is ready.

DSP sends a pointer to DSPiPipeMonitor over CMD2.

address is 0x08D2 in Let's Golf.

table contains 16 pipe entries, 5 words each:

00: base address of FIFO buffer (in DSP memory)
01: length of FIFO buffer in bytes
02: read pointer in bytes
03: write pointer in bytes
04: pipe index

first FIFO buffer is at 0x0922. each buffer is 0x100 words long (ie 0x200 bytes).

the pipes are as follows, according to Gericom's DSP code:

0: console, in
1: console, out
2: DMA, in
3: DMA, out
4: audio, in
5: audio, out
6: binary, in
7: binary, out
8: temp, in
9: temp, out
10-15: ???

'in'/'out' seem to be from the viewpoint of the ARM9 (ie. 'out' = ARM9 sending data to DSP).

'console' would be a debug console? not sure if it's used in retail binaries.

'DMA' would be to arrange DMA transfers? not sure.

'audio' is for anything pertaining to audio playback.

'binary' seems to be for specific commands, ie. scaling/yuv2rgb for Let's Golf, AAC stuff for the DSi sound app, ...

no idea what 'temp' is about.


graphics commands

* command ID is sent via CMD0
* command parameters are written into pipe 7
* pipe write pointer is updated
* pipe index is sent via CMD2
* DSP responds by re-sending pipe index over CMD2 (to signal command/data reception?)
* DSP sends 0001 over CMD1 (to signal it's ready?)

command 0001: scaling

parameters: 14 words

01/00: src ARM9 address
03/02: dst ARM9 address
04: filtering
05: src width
06: src height
07: width scale
08: height scale
09: rect X offset
0A: rect Y offset
0B: rect width
0C: rect height
0D: 'reserved' / garbage

the provided dst width/height are expressed unscaled. for example: src=256x192, rect=256x192, scale=500/500 (ie half), will result in a 128x96 output size.

the rect width/height affect how big the output bitmap is, but the scaling itself only uses the scale factors.

basically, src width/height define the source bitmap, and rect X/Y/width/height define which section of it is taken - and scaled.

the stride for the destination bitmap will be (rect width * X scale) / 1000.

scale factors work as follows: (presumably)
* dst width = (params[0B] * params[07]) / 1000
* dst height = (params[0C] * params[08]) / 1000

settings can add sub-offsets and shit, too...

filtering modes:
* 1: nearest neighbor
* 2: bilinear
* 3: bicubic
* 10: 1/3 scaling
* anything else: nearest neighbor

mode 10 requires that the rect width/height be multiples of 3 (otherwise it just fails). in this mode, the X/Y scale values are ignored, and the bitmap is scaled down to 1/3 of the original size. rect X/Y still apply.

https://en.wikipedia.org/wiki/Bicubic_interpolation

bicubic scaling seems to use a = -1.0 in the convolution formula.

1/3 scaling works by reading a 3x3 block of source pixels and averaging the values of the 8 outer pixels.

command 0002: yuv2rgb

parameters: 6 words

01/00: length in bytes
03/02: src ARM9 address
05/04: dst ARM9 address

algorith implemented is similar to this: https://github.com/Epicpkmn11/dsi-camera/blob/master/arm9/source/main.c#L11-L14

basically it's heavily based on bitshifts

the equivalent multiplication-based formula is as follows
* R = Y + ((V * 359 * 256) >> 16)
* G = Y - ((((U * 352) + (V * 731)) * 256) >> 18)
* B = Y + ((U * 1815 * 256) >> 18)


____________________
Kuribo64

Arisotura
Posted on 07-24-25 01:34 AM (rev. 4 of 07-29-25 06:56 PM) Link | #7824
the AAC decoder ucode (DSi sound app)

(it also has the standard "play sound"/"sample mic" stuff, which seems common to all ucodes)


commands and parameters are sent over CMD1. it doesn't use the pipe.

first word is the command ID, but only command 1 is supported. ARM9 sends command 0 right before the first command 1. the ucode ignores it.

command 1: decode AAC frame

00: command ID (0001)
01: input frame length
02: sampling frequency hi (bit16-31)
03: sampling frequency lo (bit0-15)
04: channel setup
05: input ARM9 address hi
06: input ARM9 address lo
07: left output ARM9 address hi
08: left output ARM9 address lo
09: right output ARM9 address hi
0A: right output ARM9 address lo

the output buffers must be 0x800 bytes long. an AAC frame produces 1024 samples of output.

error code 1 is returned if any of those conditions are met:
* input frame length is 0 or greater than 1700
* frequency is 0 or greater than 48000
* channel setup is any value other than 1 or 2
* input frame address is 0
* left output address is 0
* channel setup is not 1 and right output address is 0

frequency must be one of those: 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000. if it's any other value, it will fail to initialize the decoder (but the return value from that is ignored, so it just uses whatever the previous state was?)

response is sent over REPLY0:

0 = success
1 = incorrect parameters
2 = decoding failure

it seems that the ucode can fail to decode data if frames are sent in too fast?

-

given a MP4 file (.m4a), the input data the ucode receives comes from the file's mdat chunk. the stsz chunk defines the size of each frame. the mp4a chunk contains info like the number of channels and sampling frequency.

the same data is found in a .aac file, but the structure/metadata are different.

____________________
Kuribo64

Arisotura
Posted on 07-24-25 07:50 PM (rev. 11 of 08-07-25 12:11 AM) Link | #7825
audio commands

command set seems common to all ucodes

* command parameters are written into pipe 5
* pipe write pointer is updated
* pipe index is sent via CMD2
* DSP responds by re-sending pipe index over CMD2 (to signal command/data reception?)
* DSP sends 0004 over CMD2 (to signal new data in pipe 4)
* ARM9 reads data in pipe 4
* pipe read pointer is updated
* ARM9 sends pipe index over CMD2 (to signal that it has received the data?)

command parameters: 8 words

00: command mask hi
01: command mask lo
02: ARM9 addr hi
03: ARM9 addr lo
04: length hi
05: length lo
06: reserved
07: reserved

command must be 8 words - anything less is ignored

example command: 0000 1102 0220 E10C 0000 1FDD 0000 0000

command mask
bit1: volume (0=normal, 1=half)
bit8-11: command
bit12-15: command type (1=output, 2=input)

command meaning varies depending on the command type

for command type 1: must be 1. 1=play sound
for command type 2: values 1 or 2 are possible. 1=start, 2=stop?

data is PCM16. length is in samples. frequency is the same as the I2S output frequency.

volume bit isn't supported by the DSi sound app ucode. all the more recent ucodes support it.


response: 4 words (sent over pipe 4)

response to "play sound" command: sent when sound is finished

00: 0000
01: 1200
02: ??? hi
03: ??? lo

example response (to above command): 0000 1200 0000 0000

the first couple words might follow a format similar to the command mask above (ie. 1200 = output, stop). in practice, they are hardcoded.

the last couple words seem to be some remaining length? they're always zero. maybe error cases produce different values?


mic sampling is different: it doesn't use the addr/len params

instead, it responds with the command word and an address in DSP memory

address to the FIFO buffer for mic data. it doesn't DMA to ARM9 RAM.

buffer is 0x1000 words long, plus 3 words of header:

00: pointer to buffer data
01: buffer length
02: write cursor within buffer
typically, buffer is just after this

DSP doesn't provide any "stop after X length" or alert mechanism for this, so one would have to set up a timer for this

____________________
Kuribo64

Arisotura
Posted on 07-31-25 09:40 AM (rev. 4 of 07-31-25 10:35 AM) Link | #7834
G711


commands are sent over pipe 7

the command is 8 words

00: command hi
01: command lo
02: source addr hi
03: source addr lo
04: dest addr hi
05: dest addr lo
06: length hi
07: length lo

length is in samples

response is 2 words, sent over pipe 6

response seems to be the length that was processed


command mask:
bit0-7 = encoding (1=A-law, 2=ยต-law)
bit8-11 = task (1=encode, other=decode)

____________________
Kuribo64


Main - Development - DSP binary notes Hide post layouts | New reply

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