cscg22-gearboy

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

emu_debug.c (5264B)


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