Originally Posted by Knurek
Shining Wisdom (1995)(Sonic! Software Planning)(Sega) minissf repack (shaves 4 MB smile ).

kingshriek, the tracks still pop at beginning, even when using the latest ssfmake.py. Another bug in DSP RAM zeroing or something non related?

http://ssf.hcs64.com/

Turns out to be a legitimate bug in the driver when it initializes DSP RAM. I noticed something was amiss when I logged DSP reads from DSP RAM:
Code
DSP->READ : SCSPRAM[54418]=0006
DSP->READ : SCSPRAM[5441A]=6000
DSP->READ : SCSPRAM[5F218]=0006
DSP->READ : SCSPRAM[5F21A]=6000
DSP->READ : SCSPRAM[56ACA]=6000
...

These should all be 0x6000 if the driver is initializing DSP RAM properly.

Next, I logged CPU writes to DSP RAM to see what exactly was being written here:

Code
CPU->WRITE @ 02B20: SCSPRAM[50000]=66000
CPU->WRITE @ 02B22: SCSPRAM[50004]=66000
CPU->WRITE @ 02B24: SCSPRAM[50008]=66000
CPU->WRITE @ 02B26: SCSPRAM[5000C]=66000
CPU->WRITE @ 02B20: SCSPRAM[50010]=66000
...

And here we see values of 0x66000 being written in 32-bit chunks which agrees with the DSP seeing 0x0006 occasionally since it reads in 16-bit chunks. I logged the program counter so now it was time to disassemble the problematic code:

Code
0x00002B0A: 0x303C 0x6000                       MOVE.W   #0x6000,D0
0x00002B0E: 0x2603                              MOVE.L   D3,D3
0x00002B10: 0x6718                              BEQ.S    *+0x1A [0x2B2A]
0x00002B12: 0x2445                              MOVEA.L  D5,A2
0x00002B14: 0xE88B                              LSR.L    #4,D3
0x00002B16: 0x6712                              BEQ.S    *+0x14 [0x2B2A]
0x00002B18: 0x5343                              SUBQ.W   #1,D3
0x00002B1A: 0x3603                              MOVE.W   D3,D3
0x00002B1C: 0x670C                              BEQ.S    *+0xE [0x2B2A]
0x00002B1E: 0x24C0                              MOVE.L   D0,(A2)+
0x00002B20: 0x24C0                              MOVE.L   D0,(A2)+
0x00002B22: 0x24C0                              MOVE.L   D0,(A2)+
0x00002B24: 0x24C0                              MOVE.L   D0,(A2)+
0x00002B26: 0x51CB 0xFFF6                       DBF      D3,*-0x8 [0x2B1E]
...

A quick glance at the disassembly shows that the DSP RAM init value is in register D0 (0x6000 is the DSP's floating point representation of zero) and the DSP RAM address is in A2. The values are written 32-bits at a time in a somewhat unrolled loop with D3 as the loop counter. The problem is clear - the init value in D0 is set with a MOVE.W instruction which only writes the 16 lower order bits of the register. The upper 16 bits is uninitialized data that just happens to have the value 0x0006 at runtime.

Fixing the code isn't hard. We just need to replace the MOVE.L instructions in the init loop with MOVE.W's so the DSP RAM is initialized in 16-bit (where we have a known value) chunks instead. The loop counter will need to be increased by a factor of 2 so the same amount of data is written.

Code
0x00002B0A: 0x303C 0x6000                       MOVE.W   #0x6000,D0
0x00002B0E: 0x2603                              MOVE.L   D3,D3
0x00002B10: 0x6718                              BEQ.S    *+0x1A [0x2B2A]
0x00002B12: 0x2445                              MOVEA.L  D5,A2
0x00002B14: 0xE68B                              LSR.L    #3,D3
0x00002B16: 0x6712                              BEQ.S    *+0x14 [0x2B2A]
0x00002B18: 0x5343                              SUBQ.W   #1,D3
0x00002B1A: 0x3603                              MOVE.W   D3,D3
0x00002B1C: 0x670C                              BEQ.S    *+0xE [0x2B2A]
0x00002B1E: 0x34C0                              MOVE.W   D0,(A2)+
0x00002B20: 0x34C0                              MOVE.W   D0,(A2)+
0x00002B22: 0x34C0                              MOVE.W   D0,(A2)+
0x00002B24: 0x34C0                              MOVE.W   D0,(A2)+
0x00002B26: 0x51CB 0xFFF6                       DBF      D3,*-0x8 [0x2B1E]
...

Shorthand binary patch:
Code
2B14: E88B --> E68B
2B1E: 24C0 --> 34C0 (x4)

Updated sw.ssflib:
http://h1.ripway.com/kingshriek/sw.ssflib

BTW, the tracks pop in the beginning in the actual game itself (tested out on a real Saturn) so the SSF set is technically more accurate as is.