#7392 - einhaender - Mon Jun 16, 2003 10:29 pm
Hi all,
iam having a little difficulties to add sound support with the Neimod player to my project. Heres what I did so far. First I compiled one of the gcc examples using this makefile:
ASFLAGS = -mthumb-interwork -marm7tdmi
all: nmod.o
nmod.o : nmod.s
as $(ASFLAGS) -o nmod.o nmod.s
Then Iam adding nmod.o to my project using this makefile:
LIBS = neimod/nmod.o
OBJECTS = myfile.c
CC = arm-agb-elf-gcc
LDFLAGS = -nostartfiles -nostdlib
OBJDUMP = arm-agb-elf-objdump
CFLAGS = -Wall
all : myfile.gba
myfile.gba : main.elf
arm-agb-elf-objcopy -O binary main.elf myfile.gba
main.elf: $(OBJECTS)
$(CC) -mthumb-interwork -o main.elf $(OBJECTS) $(LIBS) -lgcc -lm
.c.o: $<
$(CC) $(CSFLAGS) -c -o $@ $<
So far so good, but now inside my main function in myfile.c I want to start
and stop a module, i assume by using the same code as in the main.cpp from the Neimod example:
NMOD_Play( (u32)(&BIN(module)) );
NMOD_Stop()
However, &BIN(module) in the above code should be pointing to a memory location where a binary file (my module) has been loaded.
How can I load the .bin into memory and how can I create a .bin from a .mod in the first place?
Thanks in advance
#7404 - Quirky - Tue Jun 17, 2003 7:55 am
I used this bit of code in a file called sound.c :
Code: |
extern unsigned long int _binary_theme_mod_start[];
void PlaySong( .... ) {
NMOD_Play( (u32)_binary_theme_mod_start );
}
|
The _binary_theme_mod_start comes from the fact that I have a mod file called theme.mod - which I use bin2o to convert to an .o file. My conversion step looks like this:
bin2o .rodata theme.mod theme.o
bin2o.bat comes with devkit advance, and basically uses objcopy to convert the binary mod file to a gcc linkable .o file. I link that .o into the project and it all works a treat. Or it did; I recently switched over to Krawall, as the nmod licence freeness for homebrew stuff is under some doubt since it was added to Catapult. Plus Krawall can be used for sound fx.
#7407 - einhaender - Tue Jun 17, 2003 11:41 am
Ok I did this. With bin2o I get awarning like:
objcopy: Warning: Output file cannot represent architecture UNKNOWN!
which I can probably ignore.
In the next step I added module.o into my makefile from above:
LIBS = neimod/nmod.o module.o
Unfortunately now I get a:
module.o does not support interworking, whereas main.elf does
warning, even tho I have the -mthumb-interworking option in the above makefile, strange.
Now if I add the code snipped you gave me:
extern unsigned long int _binary_theme_mod_start[];
void PlaySong( .... ) {
NMOD_Play( (u32)_binary_theme_mod_start );
}
into myfile.c and call PlaySong() within my main method, the game hangs on the emulator, right after it loaded. If I comment out the PlaySong() statement it works properly. Any ideas?
#7408 - Quirky - Tue Jun 17, 2003 11:52 am
You didn't copy that literally did you? And leave the dots in and everything :p That was just a "I have some arguments here and do other stuff" sort of thing. The actual code I use is:
Code: |
void PlaySong(unsigned char nSong) {
NMOD_SetMasterVol(64,0);
NMOD_SetMasterVol(64,1);
NMOD_SetMasterVol(64,2);
NMOD_SetMasterVol(64,3);
unsigned long int regs = REG_IE;
if (nSong == 0) {
NMOD_Play( (u32)_binary_theme_mod_start );
} else {
// play another mod
}
REG_IE |= regs;
}
|
You need to make a copy of the interrupt registers as nmod blitzs them otherwise.
And you need the interrupt table to look a little like this (with any other interrupts you fancy added on):
Code: |
//IntrTable for crt0
void (*IntrTable[])() = {
VblankIntr, // v-blank
0, // h-blank
0, // vcount
0, // timer0
NMOD_Timer1iRQ, // timer1
0, // timer2
0, // timer3
0, // serial
0, // dma0
0, // dma1
0, // dma2
0, // dma3
0, // key
0 // cart
};
// set up interupts like this in main()
REG_IME = 0x00; // interrupts off
REG_IE = INT_VBLANK; // we want vblank interupts
REG_DISPSTAT = BIT03; // switch on vblank intrpt
REG_IME = 0x1; // interrupts on
|
And make sure you have the correct multiple-interrupts-at-once settings in crt0.s (make sure ".equ __MultipleInterrupts, 1" is not commented out)
#7409 - einhaender - Tue Jun 17, 2003 12:07 pm
Holy moly, what is crt0.s ?
Ive seen it with Krawall but I dont see this file being used from the Neimod examples nor is it in my project.
#7411 - Quirky - Tue Jun 17, 2003 12:34 pm
crt0.s is the start up script. You can download it from devrs.com, or it comes with devkitadvance. I used the one from krawall with nmod, as it already has the modifications needed so that nmod's timer 1 update interrupt is never itself interrrupted.
Your best bet is to see if you can get Krawall working first, I think. It's similar to nmod in all but function names, but has a lot more documentation. Then if you *really* must use nmod, you can easily swap between the two later.
#7460 - einhaender - Wed Jun 18, 2003 9:41 am
Wow, I was able to set up Krawall in my project, nice. However I have difficulties using .xm files, or better the Converter tool gives me a error message with the .xm.
Anyways, I'd really love to try out Neimod too. How exactly can I adapt Neimod to use the crt0.s that comes with Krawall? In the compile process I cant just add it or I get compile errors.
Also with Krawall i had includes like:
#include "krawall.h"
#include "mtypes.h"
#include "modules/modules.h"
#include "modules/samples.h"
with Neimod you would use:
#include "neimod/nmodgcc.h"
#include "neimod/res.h"
instead?
In my main method the first I did was setting the
interrupts:
DISPCNT = 4 | ( 1 << 10 );
INT_ME = 1;
INT_IE |= ( 1 << 13 ); // cart-remove-interrupt (crt0)
WSCNT = ( 5 << 2 ) | ( 1 << 14 ); // set rom-timing
can I keep this?
Then to actually start playing:
kragInit( KRAG_INIT_STEREO );
krapPlay( &mod_bla, KRAP_MODE_LOOP, 0 );
this will change to:
NMOD_Play( (u32)(&BIN(mod_bla)) );
no init needed.
in the while(1) loop I used
kramWorker(); but what is it with Neimod?
Any help is appriciated, thanks.
#7463 - Quirky - Wed Jun 18, 2003 9:55 am
The free version of Krawall has had .xm support removed, maybe that's the error?
As for the rest, that all sounds pretty much like what I have done, but in reverse (i.e. I started out with nmod and then moved to Krawall when I already had nmod working)
kramWorker doesn't have an nmod equivalent, just NMOD_Timer1iRQ on the timer 1 interrupt. To keep your other interrupts, you'll have to store REG_IE before calling NMOD_Play and then replace them afterwards as I guess Play() does the equivalent of a REG_IE = TIMER_1 as opposed to REG_IE |= TIMER_1.
To use the Krawall crt0.s with nmod, just link in the crt0.o that you already compiled. No other changes needed, it's just that the docs that came with nmod recommended doing the change, but without knowing asm it's a bit tricky and as it's already there in kw, may as well use it.
#7526 - einhaender - Thu Jun 19, 2003 10:09 am
Now I got Neimod running. Thanks for all your support Quirky.
I wonder which Player uses less memory, Neimod or Krawall.
Anyway setting up Codewaves is next :)
#7617 - wizardgsz - Sat Jun 21, 2003 12:56 pm
To set up NMOD I used the same Krawall example framework (plus Quirky tips) that is:
* lnkscript
* crt0.s
* Makefile (just a short edit to add the nmod.s source code)
The Krawall example main.c can be also used with a little effort and 4 easy steps.
1) The void (*IntrTable[])() has to be edited (NMOD_Timer1iRQ substites kradInterrupt timer-1 handler).
2) Following useful Quirky tips just remove the kragInit and krapPlay with the NMOD setup code
NMOD_SetMasterVol(64,0);
NMOD_SetMasterVol(64,1);
NMOD_SetMasterVol(64,2);
NMOD_SetMasterVol(64,3);
NMOD_Play( (u32)module );
3) Remove the kram function-calls within the while(true) loop as you don't need them.
NMOD worker is called while executing its timer-1 interrupt handler!
4) Before compiling your code remember to add the standard GBA machine type definitions (s8, u8 and so on):
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned long u32;
typedef signed char s8;
typedef signed short s16;
typedef signed long s32;
then #include your NMOD header file, and (maybe) defines both #pragma long_calls and your module symbol (extern const unsigned char module[];).
Et voila, now you can build your ROM, burn and launch it!
_________________
http://www.geocities.com/gabriele_scibilia/