GBA: Support printing debug strings from inside a game

This commit is contained in:
Jeffrey Pfau 2016-09-28 14:37:48 -07:00
parent 278ac5f35b
commit e79963b007
5 changed files with 60 additions and 1 deletions

View File

@ -1,4 +1,6 @@
0.6.0: (Future)
Features:
- GBA: Support printing debug strings from inside a game
Bugfixes:
- GB MBC: Fix MBC7 when size is incorrectly specified
- GB Video: Setting LYC=LY during mode 2 should trigger an IRQ

View File

@ -27,6 +27,7 @@
#include "util/vfs.h"
mLOG_DEFINE_CATEGORY(GBA, "GBA");
mLOG_DEFINE_CATEGORY(GBA_DEBUG, "GBA Debug");
const uint32_t GBA_COMPONENT_MAGIC = 0x1000000;
@ -199,6 +200,9 @@ void GBAReset(struct ARMCore* cpu) {
gba->haltPending = false;
gba->idleDetectionStep = 0;
gba->idleDetectionFailures = 0;
gba->debug = false;
memset(gba->debugString, 0, sizeof(gba->debugString));
}
void GBASkipBIOS(struct GBA* gba) {
@ -681,6 +685,19 @@ void GBAStop(struct GBA* gba) {
gba->stopCallback->stop(gba->stopCallback);
}
void GBADebug(struct GBA* gba, uint16_t flags) {
gba->debugFlags = flags;
if (GBADebugFlagsIsSend(gba->debugFlags)) {
int level = 1 << GBADebugFlagsGetLevel(gba->debugFlags);
level &= 0x1F;
char oolBuf[0x101];
strncpy(oolBuf, gba->debugString, sizeof(gba->debugString));
oolBuf[0x100] = '\0';
mLog(_mLOG_CAT_GBA_DEBUG(), level, "%s", oolBuf);
}
gba->debugFlags = GBADebugFlagsClearSend(gba->debugFlags);
}
bool GBAIsROM(struct VFile* vf) {
if (vf->seek(vf, GBA_ROM_MAGIC_OFFSET, SEEK_SET) < 0) {
return false;

View File

@ -53,6 +53,7 @@ struct Patch;
struct VFile;
mLOG_DECLARE_CATEGORY(GBA);
mLOG_DECLARE_CATEGORY(GBA_DEBUG);
DECL_BITFIELD(GBATimerFlags, uint32_t);
DECL_BITS(GBATimerFlags, PrescaleBits, 0, 4);
@ -60,6 +61,10 @@ DECL_BIT(GBATimerFlags, CountUp, 4);
DECL_BIT(GBATimerFlags, DoIrq, 5);
DECL_BIT(GBATimerFlags, Enable, 6);
DECL_BITFIELD(GBADebugFlags, uint16_t);
DECL_BITS(GBADebugFlags, Level, 0, 3);
DECL_BIT(GBADebugFlags, Send, 8);
struct GBATimer {
uint16_t reload;
uint16_t oldReload;
@ -120,6 +125,10 @@ struct GBA {
bool realisticTiming;
bool hardCrash;
bool allowOpposingDirections;
bool debug;
char debugString[0x100];
GBADebugFlags debugFlags;
};
struct GBACartridge {
@ -153,6 +162,7 @@ void GBARaiseIRQ(struct GBA* gba, enum GBAIRQ irq);
void GBATestIRQ(struct ARMCore* cpu);
void GBAHalt(struct GBA* gba);
void GBAStop(struct GBA* gba);
void GBADebug(struct GBA* gba, uint16_t value);
void GBAAttachDebugger(struct GBA* gba, struct mDebugger* debugger);
void GBADetachDebugger(struct GBA* gba);

View File

@ -540,7 +540,20 @@ void GBAIOWrite(struct GBA* gba, uint32_t address, uint16_t value) {
case REG_MAX:
// Some bad interrupt libraries will write to this
break;
case REG_DEBUG_ENABLE:
gba->debug = value == 0xC0DE;
return;
case REG_DEBUG_FLAGS:
if (gba->debug) {
GBADebug(gba, value);
return;
}
// Fall through
default:
if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
STORE_16LE(value, address - REG_DEBUG_STRING, gba->debugString);
return;
}
mLOG(GBA_IO, STUB, "Stub I/O register write: %03X", address);
if (address >= REG_MAX) {
mLOG(GBA_IO, GAME_ERROR, "Write to unused I/O register: %03X", address);
@ -562,6 +575,10 @@ void GBAIOWrite8(struct GBA* gba, uint32_t address, uint8_t value) {
}
return;
}
if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
gba->debugString[address - REG_DEBUG_STRING] = value;
return;
}
if (address > SIZE_IO) {
return;
}
@ -613,6 +630,10 @@ void GBAIOWrite32(struct GBA* gba, uint32_t address, uint32_t value) {
value = GBAMemoryWriteDMADAD(gba, 3, value);
break;
default:
if (address >= REG_DEBUG_STRING && address - REG_DEBUG_STRING < sizeof(gba->debugString)) {
STORE_32LE(value, address - REG_DEBUG_STRING, gba->debugString);
return;
}
GBAIOWrite(gba, address, value & 0xFFFF);
GBAIOWrite(gba, address | 2, value >> 16);
return;
@ -848,6 +869,11 @@ uint16_t GBAIORead(struct GBA* gba, uint32_t address) {
case 0x8A:
mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
return 0;
case REG_DEBUG_ENABLE:
if (gba->debug) {
return 0x1DEA;
}
// Fall through
default:
mLOG(GBA_IO, GAME_ERROR, "Read from unused I/O register: %03X", address);
return GBALoadBad(gba->cpu);

View File

@ -150,7 +150,11 @@ enum GBAIORegisters {
REG_MAX = 0x20A,
REG_POSTFLG = 0x300,
REG_HALTCNT = 0x301
REG_HALTCNT = 0x301,
REG_DEBUG_STRING = 0xFFF600,
REG_DEBUG_FLAGS = 0xFFF700,
REG_DEBUG_ENABLE = 0xFFF780,
};
mLOG_DECLARE_CATEGORY(GBA_IO);