Pacing music with the screen off

Discussion of programming and development for the original Game Boy and Game Boy Color.
Post Reply
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Pacing music with the screen off

Post by adam_smasher »

Currently I update my sound engine in my vblank handler, after it's done with any necessary VRAM access. This works great for keeping the music going at a steady pace - as long as the screen's on. When I do turn off the screen (for a large transfer of data to VRAM, generally), there's inevitably a slight hiccup in the music as the tempo's thrown off.

I'm considering moving sound updates to a timer interrupt handler, but my impression was that this wasn't done all that often. Is that the case? And if so, why/why not?

Is there any particular approach that I should be taking?
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

When you turn off the screen are you also disabling NMI? NMI I believe still occurs even if you disable rendering. So you can still time your music updates that way, but you'll need your NMI routine to know not to do its own PPU updates or anything else that would interfere.

Edit: Oh I didn't even realize when I pulled up the thread that this was the GB. However it might still be true.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

MottZilla wrote:Edit: Oh I didn't even realize when I pulled up the thread that this was the GB. However it might still be true.
Heh, the exact same thing happened to me. I was about to answer when I realized this was about the GB. On the NES I'd just keep running the VBlank handler, but use a flag or something to indicate it's not supposed to perform VRAM updates. I don't know if things are so different on the GB that VBlank interrupts are not generated when rendering is off...
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Post by adam_smasher »

Yeah, near as I can tell vblank interrupts aren't generated on the GB while the screen's off - a HALT (wait for next interrupt) instruction will actually lock up the system.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

Lots and lots of games use timer interrupts for the music. I know this because I included code to disable double speed mode in a GBC emulator, and since the timers ran at half speed, the music in many games played slower. So I changed it to make the CPU run at non-double speed, except for the timers.
Heck, you can also use the timers to get a more steady tempo than a multiple of 60Hz.
When using timers for the sound engine, you want the timer interrupts to be lower priority than the vblank or vcount interrupts, so make your timer interrupts interruptible, and temporarily disable interrupts when a more import interrupt (vblank or vcount) is running.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Post by adam_smasher »

Alright, cool, I'll give that a shot. I had gotten my impression from this article about implementing a GB emulator:
Since the "counter" timer triggers an interrupt when it overflows, it can be especially useful if a game requires something to happen at a regular interval. However, a Gameboy game can generally use the vertical blank to much the same effect...Therefore, there's little call for use of the timer in traditional Gameboy games, though it can be used to greater effect in graphic demos.
...so I figured that if I needed to rely on them for something as basic as sound, I must've been doing something wrong.

Thanks!
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

Well you don't have to if you aren't running music while you have the screen off for PPU updates. Most NES games I've heard don't ever turn off the screen but instead just blank the screen and update the PPU over more frames.
adam_smasher
Posts: 271
Joined: Sun Mar 27, 2011 10:49 am
Location: Victoria, BC

Post by adam_smasher »

True - I guess the average game never really needs to stream in a lot of data to VRAM quickly with music running. Usually you'd change music between levels (when you need a new tileset) and it'd only take a few frames to black out the screen and stream in a new map (between sub-levels, for instance).

Is the NES' bandwidth much better than the GB's? I can only get around 64 bytes of data into VRAM per vblank (working on the B&W GB, so no DMA or double speed mode), once you factor in pushing/popping registers in the interrupt handler and doing an OAM DMA.

I'm working on an RPG, and by design there's never text and the background on screen simultaneously. So I max out VRAM with tiles when there's no visible text, and then load my font in when switching to a dialogue screen or the menu. Since the font's nearly 1KB big, it's way too slow to load it into VRAM just during vblanks.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Post by Drag »

Bugs Bunny's Crazy Castle 2 has this same thing; the music has a slight hiccup whenever a level starts, since the game disables the LCD controller to fill the pattern tables. It didn't take away from the game or anything, so I don't think most people would mind.

And yes, the timer interrupt is actually quite commonly used for music engines. Donkey Kong 94 used it, and tons of Konami games used it.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Yes, the vblank on the 8-bit Game Boy is far shorter than that on the NES. But I seem to remember that Game Boy games are supposed to stuff VRAM during hblank.

Even Pokemon Blue doesn't get this perfect; music lags during big VRAM uploads and catches up after the loads finish.
Post Reply