Skip to content

Commit

Permalink
Debugger: Keep track of global cycle count
Browse files Browse the repository at this point in the history
  • Loading branch information
endrift committed May 31, 2020
1 parent d7ecdb5 commit 7f64f8c
Show file tree
Hide file tree
Showing 11 changed files with 32 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Other fixes:
- Qt: Force OpenGL paint engine creation thread (fixes mgba.io/i/1642)
- Qt: Fix OpenGL 2.1 support (fixes mgba.io/i/1678)
Misc:
- Debugger: Keep track of global cycle count
- FFmpeg: Add looping option for GIF/APNG
- Qt: Renderer can be changed while a game is running
- Qt: Add hex index to palette view
Expand Down
2 changes: 2 additions & 0 deletions include/mgba/core/timing.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct mTiming {
struct mTimingEvent* root;
struct mTimingEvent* reroot;

uint64_t globalCycles;
uint32_t masterCycles;
int32_t* relativeCycles;
int32_t* nextEvent;
Expand All @@ -38,6 +39,7 @@ void mTimingDeschedule(struct mTiming* timing, struct mTimingEvent*);
bool mTimingIsScheduled(const struct mTiming* timing, const struct mTimingEvent*);
int32_t mTimingTick(struct mTiming* timing, int32_t cycles);
int32_t mTimingCurrentTime(const struct mTiming* timing);
uint64_t mTimingGlobalTime(const struct mTiming* timing);
int32_t mTimingNextEvent(struct mTiming* timing);
int32_t mTimingUntil(const struct mTiming* timing, const struct mTimingEvent*);

Expand Down
7 changes: 5 additions & 2 deletions include/mgba/internal/gb/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ mLOG_DECLARE_CATEGORY(GB_STATE);
* | bit 4: Is HDMA active?
* | bits 5 - 7: Active RTC register
* | 0x00196 - 0x00197: Reserved (leave zero)
* 0x00198 - 0x0025F: Reserved (leave zero)
* 0x00198 - 0x0019F: Global cycle counter
* 0x001A0 - 0x0025F: Reserved (leave zero)
* 0x00260 - 0x002FF: OAM
* 0x00300 - 0x0037F: I/O memory
* 0x00380 - 0x003FE: HRAM
Expand Down Expand Up @@ -388,7 +389,9 @@ struct GBSerializedState {
uint16_t reserved;
} memory;

uint32_t reserved[50];
uint64_t globalCycles;

uint32_t reserved[48];

uint8_t oam[GB_SIZE_OAM];

Expand Down
6 changes: 4 additions & 2 deletions include/mgba/internal/gba/serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ mLOG_DECLARE_CATEGORY(GBA_STATE);
* | 0x002F4 - 0x002F7: GBA BIOS bus prefetch
* | 0x002F8 - 0x002FB: CPU prefecth (decode slot)
* | 0x002FC - 0x002FF: CPU prefetch (fetch slot)
* 0x00300 - 0x00317: Reserved (leave zero)
* 0x00300 - 0x0030F: Reserved (leave zero)
* 0x00310 - 0x00317: Global cycle counter
* 0x00318 - 0x0031B: Last prefetched program counter
* 0x0031C - 0x0031F: Miscellaneous flags
* | bit 0: Is CPU halted?
Expand Down Expand Up @@ -326,8 +327,9 @@ struct GBASerializedState {
uint32_t biosPrefetch;
uint32_t cpuPrefetch[2];

uint32_t reservedCpu[6];
uint32_t reservedCpu[4];

uint64_t globalCycles;
uint32_t lastPrefetchedPc;
GBASerializedMiscFlags miscFlags;
uint32_t nextIrq;
Expand Down
2 changes: 2 additions & 0 deletions src/arm/debugger/cli-debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <mgba/internal/arm/debugger/cli-debugger.h>

#include <mgba/core/core.h>
#include <mgba/core/timing.h>
#include <mgba/internal/arm/debugger/debugger.h>
#include <mgba/internal/arm/debugger/memory-debugger.h>
#include <mgba/internal/arm/decoder.h>
Expand Down Expand Up @@ -138,6 +139,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
}
be->printf(be, "cpsr: ");
_printPSR(be, cpu->cpsr);
be->printf(be, "Cycle: %" PRIu64 "\n", mTimingGlobalTime(debugger->p->d.core->timing));
int instructionLength;
enum ExecutionMode mode = cpu->cpsr.t;
if (mode == MODE_ARM) {
Expand Down
6 changes: 6 additions & 0 deletions src/core/timing.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
void mTimingInit(struct mTiming* timing, int32_t* relativeCycles, int32_t* nextEvent) {
timing->root = NULL;
timing->reroot = NULL;
timing->globalCycles = 0;
timing->masterCycles = 0;
timing->relativeCycles = relativeCycles;
timing->nextEvent = nextEvent;
Expand All @@ -20,6 +21,7 @@ void mTimingDeinit(struct mTiming* timing) {
void mTimingClear(struct mTiming* timing) {
timing->root = NULL;
timing->reroot = NULL;
timing->globalCycles = 0;
timing->masterCycles = 0;
}

Expand Down Expand Up @@ -103,6 +105,10 @@ int32_t mTimingCurrentTime(const struct mTiming* timing) {
return timing->masterCycles + *timing->relativeCycles;
}

uint64_t mTimingGlobalTime(const struct mTiming* timing) {
return timing->globalCycles + *timing->relativeCycles;
}

int32_t mTimingNextEvent(struct mTiming* timing) {
struct mTimingEvent* next = timing->root;
if (!next) {
Expand Down
3 changes: 3 additions & 0 deletions src/gb/gb.c
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,9 @@ void GBProcessEvents(struct SM83Core* cpu) {
int32_t nextEvent;

cpu->cycles = 0;
#ifdef USE_DEBUGGERS
gb->timing.globalCycles += cycles;
#endif
cpu->nextEvent = INT_MAX;

nextEvent = cycles;
Expand Down
2 changes: 2 additions & 0 deletions src/gb/serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ void GBSerialize(struct GB* gb, struct GBSerializedState* state) {
STORE_32LE(GB_SAVESTATE_MAGIC + GB_SAVESTATE_VERSION, 0, &state->versionMagic);
STORE_32LE(gb->romCrc32, 0, &state->romCrc32);
STORE_32LE(gb->timing.masterCycles, 0, &state->masterCycles);
STORE_64LE(gb->timing.globalCycles, 0, &state->globalCycles);

if (gb->memory.rom) {
memcpy(state->title, ((struct GBCartridge*) &gb->memory.rom[0x100])->titleLong, sizeof(state->title));
Expand Down Expand Up @@ -150,6 +151,7 @@ bool GBDeserialize(struct GB* gb, const struct GBSerializedState* state) {
}
mTimingClear(&gb->timing);
LOAD_32LE(gb->timing.masterCycles, 0, &state->masterCycles);
LOAD_64LE(gb->timing.globalCycles, 0, &state->globalCycles);

gb->cpu->a = state->cpu.a;
gb->cpu->f.packed = state->cpu.f;
Expand Down
3 changes: 3 additions & 0 deletions src/gba/gba.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,9 @@ static void GBAProcessEvents(struct ARMCore* cpu) {
do {
int32_t cycles = cpu->cycles;
cpu->cycles = 0;
#ifdef USE_DEBUGGERS
gba->timing.globalCycles += cycles;
#endif
#ifndef NDEBUG
if (cycles < 0) {
mLOG(GBA, FATAL, "Negative cycles passed: %i", cycles);
Expand Down
2 changes: 2 additions & 0 deletions src/gba/serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ void GBASerialize(struct GBA* gba, struct GBASerializedState* state) {
STORE_32(gba->biosChecksum, 0, &state->biosChecksum);
STORE_32(gba->romCrc32, 0, &state->romCrc32);
STORE_32(gba->timing.masterCycles, 0, &state->masterCycles);
STORE_64LE(gba->timing.globalCycles, 0, &state->globalCycles);

if (gba->memory.rom) {
state->id = ((struct GBACartridge*) gba->memory.rom)->id;
Expand Down Expand Up @@ -128,6 +129,7 @@ bool GBADeserialize(struct GBA* gba, const struct GBASerializedState* state) {
}
mTimingClear(&gba->timing);
LOAD_32(gba->timing.masterCycles, 0, &state->masterCycles);
LOAD_64LE(gba->timing.globalCycles, 0, &state->globalCycles);

size_t i;
for (i = 0; i < 16; ++i) {
Expand Down
2 changes: 2 additions & 0 deletions src/sm83/debugger/cli-debugger.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <mgba/internal/sm83/debugger/cli-debugger.h>

#include <mgba/core/core.h>
#include <mgba/core/timing.h>
#include <mgba/internal/debugger/cli-debugger.h>
#include <mgba/internal/sm83/decoder.h>
#include <mgba/internal/sm83/debugger/debugger.h>
Expand Down Expand Up @@ -88,6 +89,7 @@ static void _printStatus(struct CLIDebuggerSystem* debugger) {
be->printf(be, "H: %02X L: %02X (HL: %04X)\n", cpu->h, cpu->l, cpu->hl);
be->printf(be, "PC: %04X SP: %04X\n", cpu->pc, cpu->sp);
_printFlags(be, cpu->f);
be->printf(be, "T-cycle: %" PRIu64 "\n", mTimingGlobalTime(debugger->p->d.core->timing));

struct SM83Debugger* platDebugger = (struct SM83Debugger*) debugger->p->d.platform;
size_t i;
Expand Down

0 comments on commit 7f64f8c

Please sign in to comment.