Implement NO$GBA debug registers. (#1110)
* Implement NO$GBA debug registers. NO$GBA comes with 4 debug registers that allow a ROM to print text to the emulator terminal and 2 other status registers, one with the name of the emulator and the other with the clock cycles count. This commit implements them for the ARMv5 processor. Some small things to note: - `NocashPrint` was changed and now it takes an address to _the string_ instead of the flags before it (those don't do anything anyways). - The "Emulation ID" register contains the string "melonDS " followed by version, _not_ "NO$GBA" * Fix styling issue and improve comment regarding NO$GBA message flags
This commit is contained in:
parent
308e5df426
commit
f74387a8c1
|
@ -661,7 +661,10 @@ void A_MOV_REG_LSL_IMM_DBG(ARM* cpu)
|
|||
(cpu->NextInstr[0] & 0xFF000000) == 0xEA000000 && // branch
|
||||
(cpu->NextInstr[1] & 0xFFFF) == 0x6464)
|
||||
{
|
||||
u32 addr = cpu->R[15] + 2;
|
||||
// GBATek says the two bytes after the 2nd ID are _reserved_ for flags
|
||||
// but since they serve no purpose ATTOW, we can skip them
|
||||
u32 addr = cpu->R[15] + 4; // Skip 2nd ID and flags
|
||||
// TODO: Pass flags to NocashPrint
|
||||
NDS::NocashPrint(cpu->Num, addr);
|
||||
}
|
||||
}
|
||||
|
@ -1527,7 +1530,10 @@ void T_MOV_HIREG(ARM* cpu)
|
|||
(cpu->NextInstr[0] & 0xF800) == 0xE000 && // branch
|
||||
(cpu->NextInstr[1] & 0xFFFF) == 0x6464)
|
||||
{
|
||||
u32 addr = cpu->R[15] + 2;
|
||||
// GBATek says the two bytes after the 2nd ID are _reserved_ for flags
|
||||
// but since they serve no purpose ATTOW, we can skip them
|
||||
u32 addr = cpu->R[15] + 4; // Skip 2nd ID and flags
|
||||
// TODO: Pass flags to NocashPrint
|
||||
NDS::NocashPrint(cpu->Num, addr);
|
||||
}
|
||||
}
|
||||
|
|
46
src/NDS.cpp
46
src/NDS.cpp
|
@ -1415,10 +1415,7 @@ u64 GetSysClockCycles(int num)
|
|||
|
||||
void NocashPrint(u32 ncpu, u32 addr)
|
||||
{
|
||||
// addr: u16 flags (TODO: research? libnds doesn't use those)
|
||||
// addr+2: debug string
|
||||
|
||||
addr += 2;
|
||||
// addr: debug string
|
||||
|
||||
ARM* cpu = ncpu ? (ARM*)ARM7 : (ARM*)ARM9;
|
||||
u8 (*readfn)(u32) = ncpu ? NDS::ARM7Read8 : NDS::ARM9Read8;
|
||||
|
@ -2846,6 +2843,14 @@ u8 ARM9IORead8(u32 addr)
|
|||
{
|
||||
return GPU3D::Read8(addr);
|
||||
}
|
||||
// NO$GBA debug register "Emulation ID"
|
||||
if(addr >= 0x04FFFA00 && addr < 0x04FFFA10)
|
||||
{
|
||||
// FIX: GBATek says this should be padded with spaces
|
||||
static char const emuID[16] = "melonDS " MELONDS_VERSION;
|
||||
auto idx = addr - 0x04FFFA00;
|
||||
return (u8)(emuID[idx]);
|
||||
}
|
||||
|
||||
printf("unknown ARM9 IO read8 %08X %08X\n", addr, ARM9->R[15]);
|
||||
return 0;
|
||||
|
@ -3104,6 +3109,11 @@ u32 ARM9IORead32(u32 addr)
|
|||
case 0x04100010:
|
||||
if (!(ExMemCnt[0] & (1<<11))) return NDSCart::ReadROMData();
|
||||
return 0;
|
||||
|
||||
// NO$GBA debug register "Clock Cycles"
|
||||
// Since it's a 64 bit reg. the CPU will access it in two parts:
|
||||
case 0x04FFFA20: return (u32)(GetSysClockCycles(0) & 0xFFFFFFFF);
|
||||
case 0x04FFFA24: return (u32)(GetSysClockCycles(0) >> 32);
|
||||
}
|
||||
|
||||
if ((addr >= 0x04000000 && addr < 0x04000060) || (addr == 0x0400006C))
|
||||
|
@ -3532,6 +3542,34 @@ void ARM9IOWrite32(u32 addr, u32 val)
|
|||
case 0x04100010:
|
||||
if (!(ExMemCnt[0] & (1<<11))) NDSCart::WriteROMData(val);
|
||||
return;
|
||||
|
||||
// NO$GBA debug register "String Out (raw)"
|
||||
case 0x04FFFA10:
|
||||
{
|
||||
char output[1024] = { 0 };
|
||||
char ch = '.';
|
||||
for (size_t i = 0; i < 1023 && ch != '\0'; i++)
|
||||
{
|
||||
ch = NDS::ARM9Read8(val + i);
|
||||
output[i] = ch;
|
||||
}
|
||||
printf("%s", output);
|
||||
return;
|
||||
}
|
||||
|
||||
// NO$GBA debug registers "String Out (with parameters)" and "String Out (with parameters, plus linefeed)"
|
||||
case 0x04FFFA14:
|
||||
case 0x04FFFA18:
|
||||
{
|
||||
bool appendLF = 0x04FFFA18 == addr;
|
||||
NocashPrint(0, val);
|
||||
if(appendLF)
|
||||
printf("\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// NO$GBA debug register "Char Out"
|
||||
case 0x04FFFA1C: printf("%lc", val); return;
|
||||
}
|
||||
|
||||
if (addr >= 0x04000000 && addr < 0x04000060)
|
||||
|
|
Loading…
Reference in New Issue