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.

Audio > Using my own interrupts with a music library

#35378 - headspin - Thu Feb 03, 2005 8:35 pm

This seems like such a trivial thing, but for the life of me can't get it happening. Any help would be greatly appreciated.

I'm trying to implement AFM (Another F**king MOD Player) by http://www.hitmen-console.org/ to run along side my own VBlank & HBlank interrupts. I can get my own interrupt to work or the AFM interrupts, but not both at the same time.

I'll give you some code to explain what I'm trying to achieve

Code:
void initInterrupt()
{
   REG_IME=0;

   // Or'ing REG_IE should keep the settings done by AFM???
   REG_IE |= INT_VBLANK | INT_HBLANK;

   // These bits enable the VBlank & HBlank interrupts
   // This is where the program will crash & burn
   REG_DISPSTAT |= BIT03 | BIT04;

   REG_IME=1;   //enable interrupt
}

void killInterrupt()
{
   // this function is not required to work as of yet, but
   // comments on the code is welcome
   REG_IME=0; // disable interrupt
   REG_IE = 0;
   REG_DISPSTAT = 0;
}

void HBlankInterrupt(void)
{
   unsigned long int regs = REG_IE;
   REG_IF |= INT_HBLANK;
   
   // do stuff

   REG_IE = regs;
}

void VBlankInterrupt(void)
{
   unsigned long int regs = REG_IE;
   REG_IF |= INT_VBLANK;
   
   // do stuff
   
   REG_IE = regs;
}

//IntrTable for crt0
void (*IntrTable[])() = {
   0, // v-blank
   0, // h-blank
   0, // vcount
   0, // timer0
   0, // timer1
   0, // timer2
   0, // timer3
   0, // serial
   0, // dma0
   0, // dma1
   0, // dma2
   0, // dma3
   0, // key
   0  // cart
};

int main(void)
{
   FILEPTR = find_first_gbfs_file(find_first_gbfs_file);   

   IntrTable[0] = VBlankInterrupt;
   IntrTable[1] = HBlankInterrupt;

   // install player
   afm_install();

   // now setup my vblank and hblank interrupts
   initInterrupt();

   afm_init(gbfs_get_obj(FILEPTR, "Afraid.mod", NULL));
   afm_sound_param(0xff,1); // volume, 1 = Mono, 0 = Stereo

   while (1)
   {
      // call this every frame this routine may be delayed
      afm_update();

      WaitVBlank();

      // must call this right at the start of vblank with minimum delay
      afm_sync();
   }
}


Acording to the AFM docs, only Timer0, Timer1, dma1, dma2 and dma3 interrupts are used, so I can't see why my code would be conflicting.

Until I get some resolution I can't use my own custom interrupts with AFM which is a total bitch.[/code]
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#35399 - Miked0801 - Fri Feb 04, 2005 3:46 am

What are the symptoms of the failure? Missed interrupts or none? Bad music timing?

#35410 - sasq - Fri Feb 04, 2005 9:44 am

Well stuttering will be a problem since you're not allowing an interrupt to happen during another interrupt - but allowing that causes other problems since then you need to save all registers.

Oh, and also - if AFM uses interrupts, where do you make sure the AFM-rotuines are called? a 0 in the IntrTable for an interrupt that occurs will of course crash.

#35415 - headspin - Fri Feb 04, 2005 12:21 pm

Thanks for the reply guys!

Miked0801: As soon as I enable my interrupts the whole thing crashes, rendering Visualboy to GPF and close.

sasq: No stuttering, just a complete crash and burn!

Quote:
since you're not allowing an interrupt to happen during another interrupt


The interrupts I am using (VBLANK & HBLANK) are not used by AFM according to the docs therefore, why should I need to service it's interrupts... unless (i guess your aluding to here) that once I enable interrupts his are ignored.. and somehow I need to service them?

I'm guessing it's some magick code in Jeff's crt0 that I need to address to allow both interrupts. I'm using the crt0 modified for Krawall which also works with AFM and a few other mod players.

I don't know what AFM routines to point the IntrTable to to allow AFM to continue. I don't have that knowledge but I do know I've spent many hours trying to fix it. Any more info would be appreciated!
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#35416 - headspin - Fri Feb 04, 2005 12:25 pm

P.S I was assuming Oring REG_IE would keep the original values intact so that I could just add my two V/HBlank handlers to coencide with AFM's.

I have a feeling my whole idea of how Jeff's crt0 implements interrupts is wrong. Not that I have any clue all the same, my ARM assembly skills are limited to say the least.
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#35417 - sasq - Fri Feb 04, 2005 1:25 pm

AFAIK the Hitmen player does not use interrupts at all (which is the only reason I can see to use that old peace of crap ;) - it uses DMA and Timers to do things but not the interrupts, so I don't think that's your problem. Try disabling interrupts (including your own) completely and see if you can get music to play.

It also uses IWRAM without allocating it first, so if you have your own data there it will be overwitten unless you've taken steps to avoid using the memory space used by the player.

#35467 - headspin - Sat Feb 05, 2005 6:18 am

Your right sasq, AFM dosn't use interrupts at all. That makes things more clear. You were also right about a conflict in IWRAM, AFM was overwriting the my interrupt code.

I modified Jeff's crt0 to place my interrupt handler in ROM and it now works, but there is a slight skipping in the audio. I guess thats because the handler is now in the slower ROM memory.

So now the question is how do I modify crt0 so that I can place my IRQ handler in IWRAM for faster processing but *after* the AFM code?

Below is the code to allocate memory for AFM... so I have to somehow place the handler just after this.
Code:
unsigned char __afm_work[0x400+0x100] __attribute__ ((section (".iwram")));


Here is the line in crt0.s that places the handler in IWRAM. I need to place this section at offset 0x500.

Code:
 .ifdef __ISRinIWRAM
    .SECTION    .iwram,"ax",%progbits
 .endif

_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game

#35481 - DekuTree64 - Sat Feb 05, 2005 10:26 am

Looking at the main AFM header, it looks like what you need to do is change the __iwram_start define in your link script to 0x3000500 instead of 0x3000000. It's up toward the top, hard to miss.
Kind of a strange way to do it, but I guess it works.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#35499 - tepples - Sat Feb 05, 2005 5:26 pm

headspin wrote:
As soon as I enable my interrupts the whole thing crashes, rendering Visualboy to GPF and close.

An emulator should never crash, even with a completely bugged ROM. Get a SourceForge account and report the crash, attaching the ROM as a test case.

(If this doesn't get fixed quickly, Niиtendo will probably have all its licensees use this code to crash emulators that run pirated games.)
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.


Last edited by tepples on Fri Mar 04, 2005 12:41 am; edited 1 time in total

#35512 - headspin - Sat Feb 05, 2005 8:41 pm

Quote:
Looking at the main AFM header, it looks like what you need to do is change the __iwram_start define in your link script to 0x3000500 instead of 0x3000000. It's up toward the top, hard to miss.


That worked! Thanks :)

Quote:
(If this doesn't get fixed quickly, Nintendo will probably have all its licensees use this code to crash emulators that run pirated games.)


I'll just have to secretly offer the big N my top secret emulator crash code for ... one bill-i-on dollars... :D
_________________
Warhawk DS | Manic Miner: The Lost Levels | The Detective Game