mirror of https://github.com/mgba-emu/mgba.git
Debugger: Keep track of global cycle count
This commit is contained in:
parent
d7ecdb5e4e
commit
7f64f8cf3b
1
CHANGES
1
CHANGES
|
@ -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
|
||||
|
|
|
@ -25,6 +25,7 @@ struct mTiming {
|
|||
struct mTimingEvent* root;
|
||||
struct mTimingEvent* reroot;
|
||||
|
||||
uint64_t globalCycles;
|
||||
uint32_t masterCycles;
|
||||
int32_t* relativeCycles;
|
||||
int32_t* nextEvent;
|
||||
|
@ -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*);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -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];
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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>
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue