Low-Power Mode --------------
It is recommended that the HALT instruction be used whenever possible to reduce power consumption & extend the life of the batteries. This command stops the system clock reducing the power consumption of both the CPU and ROM.
The CPU will remain suspended until an interrupt occurs at which point the interrupt is serviced and then the instruction immediately following the HALT is executed. If interrupts are disabled (DI) then halt doesn't suspend operation but it does cause the program counter to stop counting for one instruction on the GB,GBP, and SGB as mentioned below.
Depending on how much CPU time is required by a game, the HALT instruction can extend battery life anywhere from 5 to 50% or possibly more.
WARNING: The instruction immediately following the HALT instruction is "skipped" when interrupts are disabled (DI) on the GB,GBP, and SGB. As a result, always put a NOP after the HALT instruction. This instruction skipping doesn't occur when interrupts are enabled (EI). This "skipping" does not seem to occur on the GameBoy Color even in regular GB mode. ($143=$00)
EXAMPLES from Martin Korth who documented this problem: (assuming interrupts disabled for all examples)
1) This code causes the 'a' register to be incremented TWICE. 76 halt 3C inc a
2) The next example is a bit more difficult. The following code 76 halt FA 34 12 ld a,(1234)
is effectively executed as
76 halt FA FA 34 ld a,(34FA) 12 ld (de),a
3) Finally an interesting side effect 76 halt 76 halt
This combination hangs the cpu. The first HALT causes the second HALT to be repeated, which therefore causes the following command (=itself) to be repeated - again and again. Placing a NOP between the two halts would cause the NOP to be repeated once, the second HALT wouldn't lock the cpu.
Below is suggested code for GameBoy programs:
; **** Main Game Loop **** Main: halt ; stop system clock ; return from halt when interrupted nop ; (See WARNING above.)
ld a,(VblnkFlag) or a ; V-Blank interrupt ? jr z,Main ; No, some other interrupt
xor a ld (VblnkFlag),a ; Clear V-Blank flag
call Controls ; button inputs call Game ; game operation
jr Main
; **** V-Blank Interrupt Routine **** Vblnk: push af push bc push de push hl
call SpriteDma ; Do sprite updates
ld a,1 ld (VblnkFlag),a
pop hl pop de pop bc pop af reti