SameBoy | Accurate GB/GBC emulator |
| download: https://git.y1.nz/archives/sameboy.tar.gz | |
| README | Files | Log | Refs | LICENSE |
commit f706988171a83402a7e982115abe8359c3ae4cc3 parent bed9f8220c3ff58760ceb76db3976748812ee816 Author: Lior Halphon <LIJI32@gmail.com> Date: Fri, 6 Jun 2025 19:26:25 +0300 Add CPU usage command (#654) Diffstat:
| M | Core/debugger.c | 26 | ++++++++++++++++++++++++++ |
| M | Core/display.c | 15 | +++++++++++++++ |
| M | Core/gb.h | 8 | ++++++++ |
| M | Core/timing.c | 2 | ++ |
4 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/Core/debugger.c b/Core/debugger.c @@ -1728,6 +1728,31 @@ static bool ticks(GB_gameboy_t *gb, char *arguments, char *modifiers, const debu return true; } +static bool usage(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugger_command_t *command) +{ + NO_MODIFIERS + + if (strlen(lstrip(arguments))) { + print_usage(gb, command); + return true; + } + + if (gb->last_frame_busy_cycles || gb->last_frame_idle_cycles) { + GB_log(gb, "CPU usage (last frame): %.2f%%\n", (double)gb->last_frame_busy_cycles / (gb->last_frame_busy_cycles + gb->last_frame_idle_cycles) * 100); + } + else { + GB_log(gb, "CPU usage (last frame): N/A\n"); + } + + if (gb->last_second_busy_cycles || gb->last_second_idle_cycles) { + GB_log(gb, "CPU usage (last 60 frames): %.2f%%\n", (double)gb->last_second_busy_cycles / (gb->last_second_busy_cycles + gb->last_second_idle_cycles) * 100); + } + else { + GB_log(gb, "CPU usage (last 60 frames): N/A\n"); + } + + return true; +} static bool palettes(GB_gameboy_t *gb, char *arguments, char *modifiers, const debugger_command_t *command) { @@ -2184,6 +2209,7 @@ static const debugger_command_t commands[] = { {"ticks", 2, ticks, "Display the number of CPU ticks since the last time 'ticks' was " "used. Use 'keep' as an argument to display ticks without reseeting " "the count.", "(keep)", .argument_completer = keep_completer}, + {"usage", 2, usage, "Display CPU usage"}, {"cartridge", 2, mbc, "Display information about the MBC and cartridge"}, {"mbc", 3, }, /* Alias */ {"apu", 3, apu, "Display information about the current state of the audio processing unit", diff --git a/Core/display.c b/Core/display.c @@ -176,6 +176,21 @@ void GB_display_vblank(GB_gameboy_t *gb, GB_vblank_type_t type) gb->cycles_since_vblank_callback = 0; gb->lcd_disabled_outside_of_vblank = false; +#ifndef GB_DISABLE_DEBUGGER + gb->last_frame_idle_cycles = gb->current_frame_idle_cycles; + gb->last_frame_busy_cycles = gb->current_frame_busy_cycles; + gb->current_frame_idle_cycles = 0; + gb->current_frame_busy_cycles = 0; + + if (gb->usage_frame_count++ == 60) { + gb->last_second_idle_cycles = gb->current_second_idle_cycles; + gb->last_second_busy_cycles = gb->current_second_busy_cycles; + gb->current_second_idle_cycles = 0; + gb->current_second_busy_cycles = 0; + gb->usage_frame_count = 0; + } +#endif + /* TODO: Slow in turbo mode! */ if (GB_is_hle_sgb(gb)) { GB_sgb_render(gb); diff --git a/Core/gb.h b/Core/gb.h @@ -785,6 +785,14 @@ struct GB_gameboy_internal_s { /* Callbacks */ GB_debugger_reload_callback_t debugger_reload_callback; + + /* CPU usage */ + uint32_t current_frame_idle_cycles, current_frame_busy_cycles; + uint32_t last_frame_idle_cycles, last_frame_busy_cycles; + + uint32_t current_second_idle_cycles, current_second_busy_cycles; + uint32_t last_second_idle_cycles, last_second_busy_cycles; + uint8_t usage_frame_count; #endif #ifndef GB_DISABLE_REWIND diff --git a/Core/timing.c b/Core/timing.c @@ -472,6 +472,8 @@ void GB_advance_cycles(GB_gameboy_t *gb, uint8_t cycles) #ifndef GB_DISABLE_DEBUGGER gb->absolute_debugger_ticks += cycles; + *((gb->halted || gb->stopped)? &gb->current_frame_idle_cycles : &gb->current_frame_busy_cycles) += cycles; + *((gb->halted || gb->stopped)? &gb->current_second_idle_cycles : &gb->current_second_busy_cycles) += cycles; #endif // Not affected by speed boost
This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.