Early stages of GB emu, trying to understand its interrupts

Discussion of programming and development for the original Game Boy and Game Boy Color.
Post Reply
User avatar
miker00lz
Posts: 235
Joined: Thu Sep 23, 2010 7:28 pm

Early stages of GB emu, trying to understand its interrupts

Post by miker00lz » Sun Jan 13, 2019 5:16 pm

Hi, I'm working on a GB emulator.

I'm trying to understand its interrupt behavior. I'm testing with a simple ROM-only game, Alleyway.

It appears to be doing some initialization, then tries to write a 1 to 0xFF0F. This means it's trying to trigger a VBlank interrupt manually.

HOWEVER, it never seems to set the enable flag for VBlank in the enable register at 0xFFFF.

Right now, it just sits in a tight loop writing 1 to 0xFF0F, but the interrupt never happens because it's not enabled.

If I allow the interrupt to happen anyway, it does continue on to other code and it seems to initialize the game's RAM values.

Three possibilities:
1. The enable flag for VBlank should already be set at startup.
2. I have a different bug than #1.
3. I'm missing something obvious, which I have certainly been known to do!

EDIT: Another question I have is, why is there a VBlank interrupt enable flag in both FF41 LCDC register, AND in the IE at FFFF? Do they both need to enabled, or just one or the other? Maybe this is related to my problem.

EDIT 2: The game is not writing anything to the LCDC yet, so that's not the problem. And nevermind, I get the point of the LCDC VBlank enable flag now. It would trigger a different interrupt vector (0x48 instead of 0x40)

tepples
Posts: 21752
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Early stages of GB emu, trying to understand its interru

Post by tepples » Sun Jan 13, 2019 6:33 pm

miker00lz wrote:EDIT: Another question I have is, why is there a VBlank interrupt enable flag in both FF41 LCDC register, AND in the IE at FFFF? Do they both need to enabled
$FF41 is STAT, which can generate an IRQ in response to the PPU entering any of four different conditions: hblank (mode 0), vblank (mode 1), OAM scan (mode 2), or LY=LYC (scanline counter). Games typically use this for LY=LYC or hblank, not vblank, because (as you figured out) vblank already has a separate interrupt vector. To use STAT interrupts, you need to both enable a condition ($FF41 bits 6-3) and enable STAT interrupts in general ($FFFF bit 1).

If one STAT condition occurs, and a second STAT condition begins at or before the end of the first, you won't get another STAT IRQ. The way it works is all four conditions are OR'd together, and only a 0 to 1 transition of the result causes an interrupt. Thus if hblank and OAM scan are enabled, you'll get only one interrupt for OAM scan per frame, on line 0, and only the hblank interrupt at the end of lines 0-143. Similarly for OAM scan and LY=LYC or LY=LYC and hblank, as LY=LYC begins one cycle after the start of OAM scan.

User avatar
ISSOtm
Posts: 46
Joined: Fri Jan 04, 2019 5:31 pm
Location: France, right of a pile of consoles
Contact:

Re: Early stages of GB emu, trying to understand its interru

Post by ISSOtm » Sun Jan 13, 2019 6:45 pm

Instead of using games to test your emulator in the early stages, you should instead rely on test ROMs.
The basic set is blargg's (note: the attached source code is incomplete/wrong due to the original source being lost, but it's better than nothing.) Try to pass these first - you won't go far if you don't.
The better set is mooneye-gb's, although don't expect to pass all of them.

Why use test ROMs instead of games? Test ROMs rely on individual behaviors, and tend to report them clearly. (Tend. Bugs happen.) Here's an example: the game Airaki! has an emulator detection routine that's supposed to rely on one APU quirk, but actually relies on 3. Emulate one of them, you pass. Emulate a second one, you fail. Emulate all three, you pass again! So you might think this was a regression when it really wasn't.
The French Lord of Laziness (and a huge Legend of Zelda fan)
https://github.com/ISSOtm
ASMu is laifu <3

Post Reply