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