Debug messages

From GbdevWiki
Revision as of 12:13, 22 December 2024 by Nitro2k01 (Talk | contribs)

Jump to: navigation, search

Debug messages is a feature in Gameboy debuggers that allows you to output debug data from the running program into a log window or file. Currently, two standards exist. Both use the ld d,d instruction followed by a relative jump (jr) jumping over the message payload, and a unique identifier, followed by the message payload itself. Similar to how source code breakpoint use the ld b,b instruction, which is normally a no-op, debug messages use ld d,d. Because of this, debug messages will be ignored with minimal overhaad if executed on real hardware or an emulator without support for them.

Classic (no$gmb style) debug messages

This style of debug message dates back to no$gmb, but is supported in BGB, Emulicious and possibly other emulators with debug support as well.

Message specified directly

This style of debug message has the syntax shown in the following example code: (RGBDS syntax)

        ; Macro definition. (Usually defined in an include file.)
MACRO debug_message
        ld      d,d
        jr      :+
        dw      $6464           ; Two ASCII characters: "dd"
        dw      $0000           ; Identifier for this debug message type
        db      \1
:
ENDM

        ; Invoke the macro
        debug_message "Hello!"

Message specified with a pointer

Alternatively, you can point to a message somewhere else using a far pointer, consisting of an address and a bank, both represented as 16 bit numbers.

        ; Macro definition. (Usually defined in an include file.)
macro debug_message_pointer
        ld      d,d
        jr      :+
        dw      $6464           ; Two ASCII characters: "dd"
        dw      $0001           ; Identifier for this debug message type
        dw      \1
        dw      bank(\1)
:
endm
        
        ; Invoke the macro
        debug_message_pointer a_msg

        ; A null-terminated string. (Defined somewhere else so code doesn't fall right into it!)
a_msg:
        db      "Hello!",0

Operands

Several special operands can be used to print information about the internal state of the emulated machine.

Operand Description
%A%  %B%  %C%  %D%  %E%  %H%  %L% 
%AF% %BC% %DE% %HL% %PC% %SP% 
%ALLREGS% 
The current value of a 8-bit CPU register, 16-bit CPU register or a dump of all registers.
%ZF% %Z% %ZERO%
%CF% %CARRY%
%IME%
The current value of a CPU flag or the interrupt master enable. (Note: these operands are only supported in BGB and not in Emulicious.)
%ROMBANK% %SRAMBANK% %XRAMBANK% 
%WRAMBANK% %VRAMBANK%
The selected ROM or RAM bank of various types. (Note: %XRAMBANK% is only supported in BGB and not in Emulicious. %XRAMBANK% is an alias for %SRAMBANK% so you can use %SRAMBANK% to be compatible with both.)
%TOTALCLKS%
Number of clock cycles since power on. All these operands output in units of 1 nop in GBC double speed mode. So exeucintg a nop in single speed mode will increment the clock timers by 2.
%CLKS2VBLANK%
Number of clock cycles until the next VBlank.
%LASTCLKS%
Number of clock cycles since last user of %ZEROCLKS%. (Can be used for benchmarking.)
%ZEROCLKS%
Reset the timer used for %LASTCLKS%.

Emulator and toolchain specific caveats

Case sensitivity

Any operands above that are full words must be uppercase when used with Emulicious. In BGB, they are case insensitive, and you could even use something like %RoMbAnK%, mocking Spongebob style.

Garbled text due to charmaps

In RGBDS, if you use a custom charmap globally, this will garble the message strings. In this case, make sure to specify a standard ASCII charmap. The example below assumes the "default" charmap is untouched.

        ; Macro definition. (Usually defined in an include file.)
MACRO debug_message
        ld      d,d
        jr      :+
        dw      $6464           ; Two ASCII characters: "dd"
        dw      $0000           ; Identifier for this debug message type
        pushc
        setcharmap default
        db      \1
        popc
:
ENDM

        ; Invoke the macro
        debug_message "Hello!"