Skip to content

Instantly share code, notes, and snippets.

@Leandros
Created March 12, 2016 20:16
Show Gist options
  • Select an option

  • Save Leandros/9eae69ba027b1c83a9a7 to your computer and use it in GitHub Desktop.

Select an option

Save Leandros/9eae69ba027b1c83a9a7 to your computer and use it in GitHub Desktop.
Debugging Messages in no$gmb and BGB
IF !DEF(DEBUG_INC)
DEBUG_INC SET 1
; Prints a message to the no$gmb / bgb debugger
; Accepts a string as input, see emulator doc for support
DBGMSG: MACRO
ld d, d
jr .end\@
DW $6464
DW $0000
DB \1
.end\@:
ENDM
ENDC ; DEBUG_INC
@konsumer
Copy link

How can this be translated to GBDK? I'm not sure I understand it, but I tried this:

char* PTR_DEBUG = (char*) 0x6464;

void DEBUG(char* message) {
  memcpy(PTR_DEBUG[0], message, sizeof(message));
}

Which means "copy the debug message to the mem-location $6464". It doesn't seem to work. any suggestions?

@leefogg
Copy link

leefogg commented Mar 15, 2020

What this macro is doing is writing 0x64, 0x64, 0x00, 0x00 followed by whatever you want to be written to the debug output (argument 1 in this macro) straight into the binary where you want it to run it.
memcopy wouldn't work as that is runtime and can only write to RAM, but you need the debug message to already exist in the binary ROM so will have to be done in the compiler, probably with an asm block.
I'm guessing the string is null-terminated.

@konsumer
Copy link

@leefogg Yep, from what I can tell, based on BGB docs, it's \0 terminated. Looks like someone else had this question with no answer. Still not sure how to actually do it, though. Do you mean something like this?

@Leandros
Copy link
Author

I'm assuming that no$gmb is requiring this exact sequence to trigger the debug output, which is why I doubt this will be easily implemented in C (without __asm__ support).

@leefogg
Copy link

leefogg commented Apr 1, 2020

I can't speak for no$gmb as I use RGBDS but as this is a run-time feature it must be implemented by the emulator; Are you using bgb by any chance? It seems it was the one that started this trend/feature.
I think there is miscommunication around how this works, when compilers say they support the feature, what they mean is they've made the feature easier to use, but aren't the one actually providing the functionality - the emulator is.

@konsumer
Copy link

konsumer commented Apr 1, 2020

Yeh, I use BGB. I guess my question is "how do I actually do this in GBDK?" Like I'm fine with inlining ASM, if it supports it, I'm just not sure how to actually do it. I am pretty new to GB dev, and have a game-rom that does funny stuff with the memory using custom hardware cart, so I emulate that the RAM has a list of games in it. I tried a few ASM-in-GBDK snippets of demo-code, but couldn't get it to actually work. My ROM/hardware is working pretty well, so I'd really prefer to ignore the overwhelming (but I'm sure well-intentioned) advice to "rewrite it in ASM", which seems so prevalent in the GB programming scene. If I could add debugging when I'm working on the ROM in BGB, that'd be great, though. gbdkjs handles this by adding some webasm functions that allow debugging, so if I can't get it to work in regular ROMs, I might have to just switch to using that, even though BGB has a much nicer emulator. As a sidenote, if you want to have my exact GB dev setup, I assembled it all as a docker container here. Basically, I'm using gbdk-n.

@leefogg
Copy link

leefogg commented Apr 4, 2020

It shouldn't matter exactly how you have your development environment set up. Most assemblers use very similar syntax.
I found this documentation on mixing assembly with your C code however I couldn't find any documentation on which assembly syntax they use so you'll have to experiment I guess. I also can't see any support for macros so you might have to write a specific function for each debug message you want.

You'll want to write something like this in your .s (assembly) file for each debug message you want:

.global my_msg
    ld  d, d
    ret
    .db 64, 64, 00, 00
    .db "hello world"

As I said, I'm not sure on exactly which compiler directives it has so research how to write data like I have with the db directive.

@JL2210
Copy link

JL2210 commented May 17, 2020

__asm blocks can accomplish this in C:

#define DEBUG(message) \
__asm \
    ld d, d \
    jr .end \
    .dw 0x6464 \
    .dw 0x0000 \
    .ascii message \
.end: \
__endasm

For non-constant strings, they must have a fixed address and bank:

#define DYN_DEBUG(address, bank) \
__asm \
    ld d, d \
    jr .end \
    .dw 0x6464 \
    .dw 0x0001 \
    .dw address \
    .dw bank \
.end: \
__endasm

@konsumer
Copy link

I tried this:

#include <gb/gb.h>
#include <gb/drawing.h>

// this allows you to debug in BGB
#define DEBUG(message)
__asm \
    ld d, d \
    jr .end \
    .dw 0x6464 \
    .dw 0x0000 \
    .ascii message \
.end: \
__endasm

// do dynamic debugging with a bank
#define DYN_DEBUG(addr, bank) \
__asm \
    ld d, d \
    jr .end
    .dw 0x6464 \
    .dw 0x0001 \
    .dw address \
    .dw bank \
.end: \
__endasm

void main () {
    gotogxy(7, 8);
    gprintf("O HAI!");
    DEBUG("O HAI");
}

and go this error:

demo.c:6: syntax error: token -> '__endasm' ; column 13
make: *** [<builtin>: demo.o] Error 1

I am using gbdk-2020.

@JL2210
Copy link

JL2210 commented May 18, 2020

@konsumer If you're using gbdk-2020 then you can just #include <gb/bgb_emu.h> and use BGB_MESSAGE.

However, I did forget a couple backslashes. That should be fixed.

@konsumer
Copy link

That works great. Thanks so much!!! I didn't realize they have their own header for this. works perfectly.

#include <gb/gb.h>
#include <gb/drawing.h>
#include <gb/bgb_emu.h>

void main () {
    gotogxy(7, 8);
    gprintf("O HAI!");
    BGB_MESSAGE("O HAI!");
}

Screenshot from 2020-05-18 15-47-06

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment