gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > Bizarre sound problem (renamed, fixed, and laughed at)

#144283 - HyperHacker - Wed Oct 31, 2007 3:18 am

(Was: Error: invalid offset, value too big (0x00000440), and more

This problem appears to be solved, but the sound problems below aren't.)

Code:
make -C arm7
make[1]: Entering directory `/f/Programs/Sources/DS/bootmenu2/arm7'
make[2]: `/f/Programs/Sources/DS/bootmenu2/bootmenu2.arm7' is up to date.
make[1]: Leaving directory `/f/Programs/Sources/DS/bootmenu2/arm7'
make -C arm9
make[1]: Entering directory `/f/Programs/Sources/DS/bootmenu2/arm9'
boot.c
arm-eabi-gcc -MMD -MP -MF /f/Programs/Sources/DS/bootmenu2/arm9/build/boot.d -g
-std=gnu99 -Wall -O2 -mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer -ffast-
math -mthumb -mthumb-interwork -I/f/Programs/Sources/DS/bootmenu2/arm9/build -I/
f/Programs/Sources/DS/bootmenu2/arm9/../bootmenu2 -I/F/DOS/DevKitPro/libnds/incl
ude -I/f/Programs/Sources/DS/bootmenu2/arm9/build -DARM9 -c /f/Programs/Sources/
DS/bootmenu2/arm9/source/boot.c -o boot.o
C:/DOCUME~1/Admin/LOCALS~1/Temp/ccA64Ehb.s: Assembler messages:
C:/DOCUME~1/Admin/LOCALS~1/Temp/ccA64Ehb.s:623: Error: invalid offset, value too
 big (0x00000440)
make[2]: *** [boot.o] Error 1
make[1]: *** [build] Error 2
make[1]: Leaving directory `/f/Programs/Sources/DS/bootmenu2/arm9'
make: *** [arm9/bootmenu2.elf] Error 2


WTF is this supposed to mean? It's just randomly started giving me this error when I add code to routines in boot.c.


[edit] Here's another good one on ARM7. (Param4 = 8.)

Code:
SCHANNEL_TIMER(Param4) = SOUND_FREQ(2000 << 3);
SCHANNEL_CR(Param4) = SOUND_VOL(32) | SOUND_PAN(64) | SCHANNEL_WAVEDUTY(3) | SOUND_FORMAT_PSG | SCHANNEL_ENABLE;
Gets me a 2000hz tone.

Code:
u32 Param2 = 2000;
SCHANNEL_TIMER(Param4) = SOUND_FREQ(Param2 << 3);
SCHANNEL_CR(Param4) = SOUND_VOL(32) | SOUND_PAN(64) | SCHANNEL_WAVEDUTY(3) | SOUND_FORMAT_PSG | SCHANNEL_ENABLE;
Gets me what sounds like a 100hz tone.

Even these won't do it:
Code:
u32 WTF = 16000;
SCHANNEL_TIMER(Param4) = SOUND_FREQ(WTF);
SCHANNEL_CR(Param4) = SOUND_VOL(32) | SOUND_PAN(64) | SCHANNEL_WAVEDUTY(3) | SOUND_FORMAT_PSG | SCHANNEL_ENABLE;
Code:
u32 WTF = 16000;
SCHANNEL_TIMER(Param4) = WTF;
SCHANNEL_CR(Param4) = SOUND_VOL(32) | SOUND_PAN(64) | SCHANNEL_WAVEDUTY(3) | SOUND_FORMAT_PSG | SCHANNEL_ENABLE;
It only works if I use a constant. The hell? Putting in higher values does get higher frequencies, but nowhere near 2000hz, and only up to about 4000 (which is maybe 200hz), anything above that drops back down to the same as 2000. I can even pass it back to ARM9 to be printed on the screen to verify that it's 2000.
_________________
I'm a PSP hacker now, but I still <3 DS.


Last edited by HyperHacker on Sat Nov 03, 2007 5:37 am; edited 2 times in total

#144293 - chishm - Wed Oct 31, 2007 6:22 am

Do you use inline assembly in boot.c, and does it reference values outside of the assembly code?
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#144294 - HyperHacker - Wed Oct 31, 2007 6:38 am

Only this, which references some hardcoded addresses:
Code:
__asm(".thumb\n"
   //"mov r11, r11\n" //No$GBA breakpoint
   "ldr r0, =begin\n" //switch to ARM mode
   "bx r0\n"
   ".arm\n"
   "begin:\n"
   //"mov r11, r11\n"
   "ldr r0, =0x27FFE24\n" //Get boot address
   "ldr r3, [r0]\n"
   "ldr r0, =0x27FFF6C\n" //Unused header area
   "ldr r1, =0xBBBBBBBB\n" //Magic number
   "ldr r4, =0\n"
   "loop:\n"
   "ldr r2, [r0]\n" //Wait for this word to become 0xBBBBBBBB
   "cmp r1, r2\n"
   "bne loop\n"
   "str r1, [r0, #4]\n" //Set the next word to 0xBBBBBBBB to signal the ARM7
   "str r4, [r0]\n" //Set it to zero so the game doesn't freak out
   "bx r3\n" //Boot
);

_________________
I'm a PSP hacker now, but I still <3 DS.

#144296 - chishm - Wed Oct 31, 2007 8:10 am

Those constants are being put too far from the assembled code.
You can either:
1) Put the assembler code in a separate .s file
2) Load the constants from C code, using the GCC __asm syntax for passing parameters
3) Force the assembler to output the constants close by with a .pool statement.

1 is the easiest and I'm not sure if 3 will work.
_________________
http://chishm.drunkencoders.com
http://dldi.drunkencoders.com

#144371 - HyperHacker - Thu Nov 01, 2007 5:28 am

#3 seems to have worked, thanks. I should have noticed that. D'oh.

This sound problem is still bugging the heck out of me though.
_________________
I'm a PSP hacker now, but I still <3 DS.

#144376 - DekuTree64 - Thu Nov 01, 2007 7:14 am

HyperHacker wrote:
Code:
u32 Param2 = 2000;
SCHANNEL_TIMER(Param4) = SOUND_FREQ(Param2 << 3);
SCHANNEL_CR(Param4) = SOUND_VOL(32) | SOUND_PAN(64) | SCHANNEL_WAVEDUTY(3) | SOUND_FORMAT_PSG | SCHANNEL_ENABLE;
Gets me what sounds like a 100hz tone.

Ah, the joy of macros. SOUND_FREQ is defined as (-0x1000000 / (n)), but I think what's happening is that the compiler applies the negation first, which results in the value 0xFF000000, and then decides to do an unsigned division because the constant is typeless and the variable is unsigned. So try making Param2 an s32.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#144522 - HyperHacker - Sat Nov 03, 2007 5:37 am

Tch, I knew there was something funny with that macro. (Who uses negative hex numbers anyway? <_<) s32 fixed it, thanks.
_________________
I'm a PSP hacker now, but I still <3 DS.