Open jeremyBanks opened 6 years ago
[ ] DI
instruction, F3
opcode: disable interrupts after next instruction
[ ] EI
instruction, FB
opcode: enable interrupts after next instruction
[ ] TAC
register, FF07
address: timer enable and interval selection
What are interrupts?
The Game Boy defines five types of "interrupts". Each is a type of event that can occur during execution. Each interrupt type has a constant handler address. When an interrupt is triggered, the CPU jumps to the handler instead of executing the next instruction. It will also temporarily disable interrupts, so that your interrupt doesn't itself get interrupted, although this can be toggled back if desired. Each interrupt handler routine typically ends with a
RETI
instruction to jump back to the original instruction address and re-enable interrupts.An interrupt is "triggered", either manually or automatically, by setting the appropriate bit of the interrupt trigger flag register at
0xFF0F
. The corresponding bit in the interrupt enable flag register at0xFFFF
must be set, or else the request is ignored. If the interrupt is triggered, the corresponding request flag bit is cleared, but if it's ignored it remains set, and may be triggered if the corresponding enable bit becomes set later.0b00000001
0x0040
V-BlankTriggered after each frame, when VRAM becomes available for general writing again.
0b00000010
0x0048
LCD StatusTriggered at different points during a frame based on the value of the "STAT" register at
0xFF41
.0b00000100
0x0050
Timer OverflowTriggered when the timer overflows and resets, based on the the frequency and limits set in the timer registers at
0xFF04
,0xFF05
, and0xFF06
.0b00001000
0x0058
Serial TransferTriggered after a byte of data has been received over the serial port. The byte will be available at
0xFF01
.0b00100000
0x0060
Button ReleasedTriggered after a button has been released. Often requires debouncing due to duplicate triggers on physical hardware.
What do I need to implement?
[x] Jump to interrupts when they're triggered. This should be a pretty simple new branch at the beginning of each CPU tick. If interrupt trigger register bitwise-and interrupt enable register is nonzero, then clear the first set bit and jump to the corresponding handler instead of running the next instruction.
Trigger interrupts
The VideoController already keeps track of our draw line, so we just needs it to signal the CPU every time that value reaches the first "off-screen" v-blank line.
I'd like to punt on this, at least for a little while. My currently very-primitive drawing routines do not work like they really do on the game boy, and probably don't have any notion of the timings that should trigger this.
This shouldn't be very complicated, and I'm sure it's very widely used.
When hell freezes over.
It'll probably be a while before we get any game to the point where it's actually waiting on this, but connecting our UI input events into the Game Boy state should be a useful, feasible, and neat.