cscg22-gearboy

CSCG 2022 Challenge 'Gearboy'
git clone https://git.sinitax.com/sinitax/cscg22-gearboy
Log | Files | Refs | sfeed.txt

emu_debug.c (5911B)


      1#include <gbdk/platform.h>
      2#include <stdint.h>
      3#include <stdio.h>      // Just for printf()
      4
      5#include <gbdk/emu_debug.h> // Use this include to add the Emu debug functions
      6
      7
      8// This example shows how to use support for profiling
      9// and logging to the debug window in the emulator (BGB or Emulicious).
     10//
     11// 1. Build this ROM (emu_debug.gb) then load it in the emulator (BGB or Emulicious)
     12// 2. Open the internal debugger by pressing the "ESC" or "F1" key
     13// 3. From the debugger menu choose "debug messages" to open the debug messages window
     14// 4. Reset the gameboy (you may need to press F9 in the debugger to resume running)
     15// 5. The debug window will show the debug messages
     16//
     17// See the BGB Manual for more information
     18// ("expressions, breakpoint conditions, and debug messages")
     19// https://bgb.bircd.org/manual.html#expressions
     20
     21// If you see a message like the following, it is safe to ignore. It is a known
     22// issue with SDCC and should not cause problems.
     23//
     24// " src/emu_debug.c:156: info 218: z80instructionSize() failed to parse line node, assuming 999 bytes ' llbl:'
     25
     26int main(void)
     27{
     28    SHOW_BKG;
     29    DISPLAY_ON;
     30
     31    // Display a message on the screen
     32    printf("Message to the\nScreen\n");
     33
     34    // Log a message to the Emulator debug message window
     35    EMU_MESSAGE(""); // new line
     36    EMU_MESSAGE("Message to the EMU console");
     37
     38    // ==== Normal Speed Mode ====
     39    // Profile code: a single NOP instruction
     40    //
     41    // The clock units are "1 nop in [CGB] doublespeed mode".
     42    // So when *not* running in CGB doublespeed mode you
     43    // have to divide by 2 to get the correct cycle count.
     44    //
     45    // You should see the message "NOP TIME: 2".
     46    //
     47    // So in this case, divide the printed value by 2 = The NOP took "1" cycle
     48
     49    __critical {  // Temporarily turn off interrupts for more accurate measurements
     50        EMU_PROFILE_BEGIN("Profile a single NOP instruction at Normal Speed");
     51            __asm__("nop");
     52        EMU_PROFILE_END("NOP TIME:");
     53    }
     54
     55
     56    #ifdef NINTENDO
     57    // ==== Color Game Boy in Double Speed Mode ====
     58    // Profile code: a single NOP instruction
     59    //
     60    // The EMU_PROFILE_BEGIN/END macros don't support the
     61    // Color Game Boy (CGB) in double speed mode (cpu_fast()).
     62    // The example below shows what to use instead (and how to
     63    // check for a CGB and turn on Double Speed mode).
     64    //
     65    // Check and only run this test if on CGB hardware
     66    if (DEVICE_SUPPORTS_COLOR) {
     67
     68        // Set CGB into double speed mode
     69        // (Requires passing -Wm-yc or -Wm-yC with Lcc during build time)
     70        cpu_fast();
     71        // Set some default DMG styled colors in the CGB Palette
     72        set_default_palette();
     73
     74        // In CGB Double Speed mode, you don't have to
     75        // divide by 2 to get the cycle count.
     76        //
     77        // You should see the message "NOP TIME: 1".
     78
     79        __critical {  // Temporarily turn off interrupts for more accurate measurements
     80            EMU_PROFILE_BEGIN("Profile a single NOP instruction at CGB Double Speed");
     81                __asm__("nop");
     82            // The "-4+" subtracts 4 clocks to compensate for the ones
     83            // used by the debug message itself (Normal speed uses -8)
     84            EMU_MESSAGE("NOP TIME:%-4+LASTCLKS%");
     85        }
     86
     87        // Return the CGB to normal speed
     88        cpu_slow();
     89    }
     90    #endif // NINTENDO
     91
     92
     93    __critical {  // Temporarily turn off interrupts for more accurate measurements
     94
     95        int c;
     96
     97        // Profile code in a loop
     98        EMU_PROFILE_BEGIN("Profile code in a loop");
     99            for(c=0; c<5; c++) {
    100                // Do something
    101                printf("%d\n", c);
    102            }
    103        // Elapsed cycle count output is in hex.
    104        // Remember to divide by 2 for the result (Normal Speed)
    105        EMU_PROFILE_END("LOOP TIME:");
    106    }
    107
    108    // ==== Some other things you can print ====
    109
    110    // - For Game Boy TOTALCLKS shows the clocks counter ("internal divider")
    111    // - For SMS/GG TOTALCLKS is relative to CLKS2VBLANK (so at most it can be the max clocks to vblank)
    112    EMU_MESSAGE("Total Clocks: %TOTALCLKS%");
    113
    114    // CLKS2VBLANK
    115    EMU_MESSAGE("Clocks until VBLANK: %CLKS2VBLANK%");
    116
    117    // Which Banks are currently active (for MBC based cartridges)
    118    EMU_MESSAGE("Current  ROM bank: %ROMBANK%");
    119    EMU_MESSAGE("Current SRAM bank: %SRAMBANK%");
    120    // These are not banked on DMG/MGB Game Boys
    121    EMU_MESSAGE("Current VRAM bank: %VRAMBANK%");
    122    EMU_MESSAGE("Current WRAM bank: %WRAMBANK%");
    123
    124    // Registers (All in this case, or individual ones)
    125    EMU_MESSAGE("All Registers: %ALLREGS%");
    126
    127    // Simple addition with a register
    128    EMU_MESSAGE("Register A + 1: %(A+1)%");
    129
    130    // Note: %SCANLINE% is available in Emulicious (for SMS/GG/GB/GBC) but not BGB
    131    EMU_MESSAGE("Current Scanline: %SCANLINE%");
    132
    133    #if defined(NINTENDO)
    134        // Read the LY Register a couple times
    135        // (Current Y coordinate being rendered to the LCD)
    136        EMU_MESSAGE("LY Register (0xFF44): %($ff44)%");
    137        EMU_MESSAGE("LY Register (0xFF44): %($ff44)%");
    138        // Now print a conditional debug message using it
    139        EMU_MESSAGE("Is LY Register > Line 67: %($ff44)>67%Yes;No;");
    140    #endif
    141
    142
    143    #if defined(NINTENDO)
    144        // Print some profile info using a built-in function.
    145        EMU_MESSAGE("The following lines contain: PROFILE,(SP+$0),(SP+$1),A,TOTALCLKS,ROMBANK,WRAMBANK");
    146
    147        EMU_profiler_message();
    148
    149        // It's equivalent to:
    150        EMU_MESSAGE("PROFILE,%(SP+$0)%,%(SP+$1)%,%A%,%TOTALCLKS%,%ROMBANK%,%WRAMBANK%");
    151
    152    #elif defined(SEGA)
    153        EMU_MESSAGE("PROFILE,%(SP+$0)%,%(SP+$1)%,%A%,%TOTALCLKS%,%ROMBANK%,%WRAMBANK%");
    154    #endif
    155
    156    uint8_t var0 = 16;
    157    int16_t var1 = -10;
    158    EMU_printf("var0: %hd; var1: %d; var0*var1=%d", (uint8_t)var0, var1, var0 * var1);
    159
    160    // The EMU_TEXT() macro will accept a non-quoted string
    161    EMU_TEXT("The End");
    162
    163    return 0;
    164}