Debugger: Plumb access source information through to access logger
This commit is contained in:
parent
deb4f547fa
commit
b8c890e1bc
@ -20,6 +20,15 @@ enum mCPUComponentType {
|
|||||||
CPU_COMPONENT_MAX
|
CPU_COMPONENT_MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum mMemoryAccessSource {
|
||||||
|
mACCESS_UNKNOWN = 0,
|
||||||
|
mACCESS_PROGRAM,
|
||||||
|
mACCESS_DMA,
|
||||||
|
mACCESS_SYSTEM,
|
||||||
|
mACCESS_DECOMPRESS,
|
||||||
|
mACCESS_COPY,
|
||||||
|
};
|
||||||
|
|
||||||
struct mCPUComponent {
|
struct mCPUComponent {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
void (*init)(void* cpu, struct mCPUComponent* component);
|
void (*init)(void* cpu, struct mCPUComponent* component);
|
||||||
|
@ -111,6 +111,7 @@ struct mDebuggerEntryInfo {
|
|||||||
uint32_t newValue;
|
uint32_t newValue;
|
||||||
enum mWatchpointType watchType;
|
enum mWatchpointType watchType;
|
||||||
enum mWatchpointType accessType;
|
enum mWatchpointType accessType;
|
||||||
|
enum mMemoryAccessSource accessSource;
|
||||||
} wp;
|
} wp;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -132,6 +132,8 @@ struct ARMMemory {
|
|||||||
uint32_t activeNonseqCycles16;
|
uint32_t activeNonseqCycles16;
|
||||||
int32_t (*stall)(struct ARMCore*, int32_t wait);
|
int32_t (*stall)(struct ARMCore*, int32_t wait);
|
||||||
void (*setActiveRegion)(struct ARMCore*, uint32_t address);
|
void (*setActiveRegion)(struct ARMCore*, uint32_t address);
|
||||||
|
|
||||||
|
enum mMemoryAccessSource accessSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ARMCoprocessor {
|
struct ARMCoprocessor {
|
||||||
|
@ -61,6 +61,8 @@ struct SM83Memory {
|
|||||||
uint16_t activeMask;
|
uint16_t activeMask;
|
||||||
uint16_t activeRegionEnd;
|
uint16_t activeRegionEnd;
|
||||||
void (*setActiveRegion)(struct SM83Core*, uint16_t address);
|
void (*setActiveRegion)(struct SM83Core*, uint16_t address);
|
||||||
|
|
||||||
|
enum mMemoryAccessSource accessSource;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SM83InterruptHandler {
|
struct SM83InterruptHandler {
|
||||||
|
@ -121,6 +121,7 @@ static void _checkWatchpoints(struct ARMDebugger* debugger, uint32_t address, en
|
|||||||
info.type.wp.newValue = newValue;
|
info.type.wp.newValue = newValue;
|
||||||
info.type.wp.watchType = watchpoint->type;
|
info.type.wp.watchType = watchpoint->type;
|
||||||
info.type.wp.accessType = type;
|
info.type.wp.accessType = type;
|
||||||
|
info.type.wp.accessSource = debugger->cpu->memory.accessSource;
|
||||||
info.address = address;
|
info.address = address;
|
||||||
info.segment = 0;
|
info.segment = 0;
|
||||||
info.width = width;
|
info.width = width;
|
||||||
|
@ -69,9 +69,29 @@ static void _mDebuggerAccessLoggerEntered(struct mDebuggerModule* debugger, enum
|
|||||||
}
|
}
|
||||||
offset &= -info->width;
|
offset &= -info->width;
|
||||||
|
|
||||||
|
mDebuggerAccessLogFlagsEx flagsEx = 0;
|
||||||
int i;
|
int i;
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case DEBUGGER_ENTER_WATCHPOINT:
|
case DEBUGGER_ENTER_WATCHPOINT:
|
||||||
|
switch (info->type.wp.accessSource) {
|
||||||
|
case mACCESS_PROGRAM:
|
||||||
|
flagsEx = mDebuggerAccessLogFlagsExFillAccessProgram(flagsEx);
|
||||||
|
break;
|
||||||
|
case mACCESS_DMA:
|
||||||
|
flagsEx = mDebuggerAccessLogFlagsExFillAccessDMA(flagsEx);
|
||||||
|
break;
|
||||||
|
case mACCESS_SYSTEM:
|
||||||
|
flagsEx = mDebuggerAccessLogFlagsExFillAccessSystem(flagsEx);
|
||||||
|
break;
|
||||||
|
case mACCESS_DECOMPRESS:
|
||||||
|
flagsEx = mDebuggerAccessLogFlagsExFillAccessDecompress(flagsEx);
|
||||||
|
break;
|
||||||
|
case mACCESS_COPY:
|
||||||
|
flagsEx = mDebuggerAccessLogFlagsExFillAccessCopy(flagsEx);
|
||||||
|
break;
|
||||||
|
case mACCESS_UNKNOWN:
|
||||||
|
break;
|
||||||
|
}
|
||||||
for (i = 0; i < info->width; ++i) {
|
for (i = 0; i < info->width; ++i) {
|
||||||
if (info->type.wp.accessType & WATCHPOINT_WRITE) {
|
if (info->type.wp.accessType & WATCHPOINT_WRITE) {
|
||||||
region->block[offset + i] = mDebuggerAccessLogFlagsFillWrite(region->block[offset + i]);
|
region->block[offset + i] = mDebuggerAccessLogFlagsFillWrite(region->block[offset + i]);
|
||||||
@ -83,16 +103,29 @@ static void _mDebuggerAccessLoggerEntered(struct mDebuggerModule* debugger, enum
|
|||||||
switch (info->width) {
|
switch (info->width) {
|
||||||
case 1:
|
case 1:
|
||||||
region->block[offset] = mDebuggerAccessLogFlagsFillAccess8(region->block[offset]);
|
region->block[offset] = mDebuggerAccessLogFlagsFillAccess8(region->block[offset]);
|
||||||
|
if (region->blockEx) {
|
||||||
|
region->blockEx[offset] |= flagsEx;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
region->block[offset] = mDebuggerAccessLogFlagsFillAccess16(region->block[offset]);
|
region->block[offset] = mDebuggerAccessLogFlagsFillAccess16(region->block[offset]);
|
||||||
region->block[offset + 1] = mDebuggerAccessLogFlagsFillAccess16(region->block[offset + 1]);
|
region->block[offset + 1] = mDebuggerAccessLogFlagsFillAccess16(region->block[offset + 1]);
|
||||||
|
if (region->blockEx) {
|
||||||
|
region->blockEx[offset] |= flagsEx;
|
||||||
|
region->blockEx[offset + 1] |= flagsEx;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
region->block[offset] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset]);
|
region->block[offset] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset]);
|
||||||
region->block[offset + 1] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset + 1]);
|
region->block[offset + 1] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset + 1]);
|
||||||
region->block[offset + 2] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset + 2]);
|
region->block[offset + 2] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset + 2]);
|
||||||
region->block[offset + 3] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset + 3]);
|
region->block[offset + 3] = mDebuggerAccessLogFlagsFillAccess32(region->block[offset + 3]);
|
||||||
|
if (region->blockEx) {
|
||||||
|
region->blockEx[offset] |= flagsEx;
|
||||||
|
region->blockEx[offset + 1] |= flagsEx;
|
||||||
|
region->blockEx[offset + 2] |= flagsEx;
|
||||||
|
region->blockEx[offset + 3] |= flagsEx;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
region->block[offset] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset]);
|
region->block[offset] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset]);
|
||||||
@ -103,6 +136,16 @@ static void _mDebuggerAccessLoggerEntered(struct mDebuggerModule* debugger, enum
|
|||||||
region->block[offset + 5] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset + 5]);
|
region->block[offset + 5] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset + 5]);
|
||||||
region->block[offset + 6] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset + 6]);
|
region->block[offset + 6] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset + 6]);
|
||||||
region->block[offset + 7] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset + 7]);
|
region->block[offset + 7] = mDebuggerAccessLogFlagsFillAccess64(region->block[offset + 7]);
|
||||||
|
if (region->blockEx) {
|
||||||
|
region->blockEx[offset] |= flagsEx;
|
||||||
|
region->blockEx[offset + 1] |= flagsEx;
|
||||||
|
region->blockEx[offset + 2] |= flagsEx;
|
||||||
|
region->blockEx[offset + 3] |= flagsEx;
|
||||||
|
region->blockEx[offset + 4] |= flagsEx;
|
||||||
|
region->blockEx[offset + 5] |= flagsEx;
|
||||||
|
region->blockEx[offset + 6] |= flagsEx;
|
||||||
|
region->blockEx[offset + 7] |= flagsEx;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -148,6 +148,7 @@ void GBMemoryInit(struct GB* gb) {
|
|||||||
cpu->memory.store8 = GBStore8;
|
cpu->memory.store8 = GBStore8;
|
||||||
cpu->memory.currentSegment = GBCurrentSegment;
|
cpu->memory.currentSegment = GBCurrentSegment;
|
||||||
cpu->memory.setActiveRegion = GBSetActiveRegion;
|
cpu->memory.setActiveRegion = GBSetActiveRegion;
|
||||||
|
cpu->memory.accessSource = mACCESS_UNKNOWN;
|
||||||
|
|
||||||
gb->memory.wram = 0;
|
gb->memory.wram = 0;
|
||||||
gb->memory.wramBank = 0;
|
gb->memory.wramBank = 0;
|
||||||
@ -205,6 +206,7 @@ void GBMemoryReset(struct GB* gb) {
|
|||||||
gb->memory.hdmaDest = 0;
|
gb->memory.hdmaDest = 0;
|
||||||
gb->memory.isHdma = false;
|
gb->memory.isHdma = false;
|
||||||
|
|
||||||
|
gb->cpu->memory.accessSource = mACCESS_UNKNOWN;
|
||||||
|
|
||||||
gb->memory.dmaEvent.context = gb;
|
gb->memory.dmaEvent.context = gb;
|
||||||
gb->memory.dmaEvent.name = "GB DMA";
|
gb->memory.dmaEvent.name = "GB DMA";
|
||||||
@ -576,10 +578,13 @@ void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesL
|
|||||||
struct GB* gb = context;
|
struct GB* gb = context;
|
||||||
int dmaRemaining = gb->memory.dmaRemaining;
|
int dmaRemaining = gb->memory.dmaRemaining;
|
||||||
gb->memory.dmaRemaining = 0;
|
gb->memory.dmaRemaining = 0;
|
||||||
|
enum mMemoryAccessSource oldAccess = gb->cpu->memory.accessSource;
|
||||||
|
gb->cpu->memory.accessSource = mACCESS_DMA;
|
||||||
uint8_t b = GBLoad8(gb->cpu, gb->memory.dmaSource);
|
uint8_t b = GBLoad8(gb->cpu, gb->memory.dmaSource);
|
||||||
// TODO: Can DMA write OAM during modes 2-3?
|
// TODO: Can DMA write OAM during modes 2-3?
|
||||||
gb->video.oam.raw[gb->memory.dmaDest] = b;
|
gb->video.oam.raw[gb->memory.dmaDest] = b;
|
||||||
gb->video.renderer->writeOAM(gb->video.renderer, gb->memory.dmaDest);
|
gb->video.renderer->writeOAM(gb->video.renderer, gb->memory.dmaDest);
|
||||||
|
gb->cpu->memory.accessSource = oldAccess;
|
||||||
++gb->memory.dmaSource;
|
++gb->memory.dmaSource;
|
||||||
++gb->memory.dmaDest;
|
++gb->memory.dmaDest;
|
||||||
gb->memory.dmaRemaining = dmaRemaining - 1;
|
gb->memory.dmaRemaining = dmaRemaining - 1;
|
||||||
@ -591,8 +596,11 @@ void _GBMemoryDMAService(struct mTiming* timing, void* context, uint32_t cyclesL
|
|||||||
void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
void _GBMemoryHDMAService(struct mTiming* timing, void* context, uint32_t cyclesLate) {
|
||||||
struct GB* gb = context;
|
struct GB* gb = context;
|
||||||
gb->cpuBlocked = true;
|
gb->cpuBlocked = true;
|
||||||
|
enum mMemoryAccessSource oldAccess = gb->cpu->memory.accessSource;
|
||||||
|
gb->cpu->memory.accessSource = mACCESS_DMA;
|
||||||
uint8_t b = gb->cpu->memory.load8(gb->cpu, gb->memory.hdmaSource);
|
uint8_t b = gb->cpu->memory.load8(gb->cpu, gb->memory.hdmaSource);
|
||||||
gb->cpu->memory.store8(gb->cpu, gb->memory.hdmaDest, b);
|
gb->cpu->memory.store8(gb->cpu, gb->memory.hdmaDest, b);
|
||||||
|
gb->cpu->memory.accessSource = oldAccess;
|
||||||
++gb->memory.hdmaSource;
|
++gb->memory.hdmaSource;
|
||||||
++gb->memory.hdmaDest;
|
++gb->memory.hdmaDest;
|
||||||
--gb->memory.hdmaRemaining;
|
--gb->memory.hdmaRemaining;
|
||||||
|
@ -174,6 +174,8 @@ static void _BgAffineSet(struct GBA* gba) {
|
|||||||
int destination = cpu->gprs[1];
|
int destination = cpu->gprs[1];
|
||||||
float a, b, c, d;
|
float a, b, c, d;
|
||||||
float rx, ry;
|
float rx, ry;
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_SYSTEM;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
// [ sx 0 0 ] [ cos(theta) -sin(theta) 0 ] [ 1 0 cx - ox ] [ A B rx ]
|
// [ sx 0 0 ] [ cos(theta) -sin(theta) 0 ] [ 1 0 cx - ox ] [ A B rx ]
|
||||||
// [ 0 sy 0 ] * [ sin(theta) cos(theta) 0 ] * [ 0 1 cy - oy ] = [ C D ry ]
|
// [ 0 sy 0 ] * [ sin(theta) cos(theta) 0 ] * [ 0 1 cy - oy ] = [ C D ry ]
|
||||||
@ -205,6 +207,7 @@ static void _BgAffineSet(struct GBA* gba) {
|
|||||||
cpu->memory.store32(cpu, destination + 12, ry * 256, 0);
|
cpu->memory.store32(cpu, destination + 12, ry * 256, 0);
|
||||||
destination += 16;
|
destination += 16;
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _ObjAffineSet(struct GBA* gba) {
|
static void _ObjAffineSet(struct GBA* gba) {
|
||||||
@ -216,6 +219,8 @@ static void _ObjAffineSet(struct GBA* gba) {
|
|||||||
int destination = cpu->gprs[1];
|
int destination = cpu->gprs[1];
|
||||||
int diff = cpu->gprs[3];
|
int diff = cpu->gprs[3];
|
||||||
float a, b, c, d;
|
float a, b, c, d;
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_SYSTEM;
|
||||||
while (i--) {
|
while (i--) {
|
||||||
// [ sx 0 ] [ cos(theta) -sin(theta) ] [ A B ]
|
// [ sx 0 ] [ cos(theta) -sin(theta) ] [ A B ]
|
||||||
// [ 0 sy ] * [ sin(theta) cos(theta) ] = [ C D ]
|
// [ 0 sy ] * [ sin(theta) cos(theta) ] = [ C D ]
|
||||||
@ -237,6 +242,7 @@ static void _ObjAffineSet(struct GBA* gba) {
|
|||||||
cpu->memory.store16(cpu, destination + diff * 3, d * 256, 0);
|
cpu->memory.store16(cpu, destination + diff * 3, d * 256, 0);
|
||||||
destination += diff * 4;
|
destination += diff * 4;
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _MidiKey2Freq(struct GBA* gba) {
|
static void _MidiKey2Freq(struct GBA* gba) {
|
||||||
@ -244,7 +250,10 @@ static void _MidiKey2Freq(struct GBA* gba) {
|
|||||||
|
|
||||||
int oldRegion = gba->memory.activeRegion;
|
int oldRegion = gba->memory.activeRegion;
|
||||||
gba->memory.activeRegion = GBA_REGION_BIOS;
|
gba->memory.activeRegion = GBA_REGION_BIOS;
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_SYSTEM;
|
||||||
uint32_t key = cpu->memory.load32(cpu, cpu->gprs[0] + 4, 0);
|
uint32_t key = cpu->memory.load32(cpu, cpu->gprs[0] + 4, 0);
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
gba->memory.activeRegion = oldRegion;
|
gba->memory.activeRegion = oldRegion;
|
||||||
|
|
||||||
cpu->gprs[0] = key / exp2f((180.f - cpu->gprs[1] - cpu->gprs[2] / 256.f) / 12.f);
|
cpu->gprs[0] = key / exp2f((180.f - cpu->gprs[1] - cpu->gprs[2] / 256.f) / 12.f);
|
||||||
@ -624,6 +633,8 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||||||
uint32_t source = cpu->gprs[0];
|
uint32_t source = cpu->gprs[0];
|
||||||
uint32_t dest = cpu->gprs[1];
|
uint32_t dest = cpu->gprs[1];
|
||||||
int cycles = 20;
|
int cycles = 20;
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_DECOMPRESS;
|
||||||
int remaining = (cpu->memory.load32(cpu, source, &cycles) & 0xFFFFFF00) >> 8;
|
int remaining = (cpu->memory.load32(cpu, source, &cycles) & 0xFFFFFF00) >> 8;
|
||||||
// We assume the signature byte (0x10) is correct
|
// We assume the signature byte (0x10) is correct
|
||||||
int blockheader = 0; // Some compilers warn if this isn't set, even though it's trivially provably always set
|
int blockheader = 0; // Some compilers warn if this isn't set, even though it's trivially provably always set
|
||||||
@ -698,6 +709,7 @@ static void _unLz77(struct GBA* gba, int width) {
|
|||||||
blocksRemaining = 8;
|
blocksRemaining = 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
cpu->gprs[0] = source;
|
cpu->gprs[0] = source;
|
||||||
cpu->gprs[1] = dest;
|
cpu->gprs[1] = dest;
|
||||||
cpu->gprs[3] = 0;
|
cpu->gprs[3] = 0;
|
||||||
@ -713,6 +725,8 @@ static void _unHuffman(struct GBA* gba) {
|
|||||||
struct ARMCore* cpu = gba->cpu;
|
struct ARMCore* cpu = gba->cpu;
|
||||||
uint32_t source = cpu->gprs[0] & 0xFFFFFFFC;
|
uint32_t source = cpu->gprs[0] & 0xFFFFFFFC;
|
||||||
uint32_t dest = cpu->gprs[1];
|
uint32_t dest = cpu->gprs[1];
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_DECOMPRESS;
|
||||||
uint32_t header = cpu->memory.load32(cpu, source, 0);
|
uint32_t header = cpu->memory.load32(cpu, source, 0);
|
||||||
int remaining = header >> 8;
|
int remaining = header >> 8;
|
||||||
unsigned bits = header & 0xF;
|
unsigned bits = header & 0xF;
|
||||||
@ -722,6 +736,7 @@ static void _unHuffman(struct GBA* gba) {
|
|||||||
}
|
}
|
||||||
if (32 % bits || bits == 1) {
|
if (32 % bits || bits == 1) {
|
||||||
mLOG(GBA_BIOS, STUB, "Unimplemented unaligned Huffman");
|
mLOG(GBA_BIOS, STUB, "Unimplemented unaligned Huffman");
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// We assume the signature byte (0x20) is correct
|
// We assume the signature byte (0x20) is correct
|
||||||
@ -773,6 +788,7 @@ static void _unHuffman(struct GBA* gba) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
cpu->gprs[0] = source;
|
cpu->gprs[0] = source;
|
||||||
cpu->gprs[1] = dest;
|
cpu->gprs[1] = dest;
|
||||||
}
|
}
|
||||||
@ -780,6 +796,8 @@ static void _unHuffman(struct GBA* gba) {
|
|||||||
static void _unRl(struct GBA* gba, int width) {
|
static void _unRl(struct GBA* gba, int width) {
|
||||||
struct ARMCore* cpu = gba->cpu;
|
struct ARMCore* cpu = gba->cpu;
|
||||||
uint32_t source = cpu->gprs[0];
|
uint32_t source = cpu->gprs[0];
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_DECOMPRESS;
|
||||||
int remaining = (cpu->memory.load32(cpu, source & 0xFFFFFFFC, 0) & 0xFFFFFF00) >> 8;
|
int remaining = (cpu->memory.load32(cpu, source & 0xFFFFFFFC, 0) & 0xFFFFFF00) >> 8;
|
||||||
int padding = (4 - remaining) & 0x3;
|
int padding = (4 - remaining) & 0x3;
|
||||||
// We assume the signature byte (0x30) is correct
|
// We assume the signature byte (0x30) is correct
|
||||||
@ -846,6 +864,7 @@ static void _unRl(struct GBA* gba, int width) {
|
|||||||
++dest;
|
++dest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
cpu->gprs[0] = source;
|
cpu->gprs[0] = source;
|
||||||
cpu->gprs[1] = dest;
|
cpu->gprs[1] = dest;
|
||||||
}
|
}
|
||||||
@ -854,6 +873,8 @@ static void _unFilter(struct GBA* gba, int inwidth, int outwidth) {
|
|||||||
struct ARMCore* cpu = gba->cpu;
|
struct ARMCore* cpu = gba->cpu;
|
||||||
uint32_t source = cpu->gprs[0] & 0xFFFFFFFC;
|
uint32_t source = cpu->gprs[0] & 0xFFFFFFFC;
|
||||||
uint32_t dest = cpu->gprs[1];
|
uint32_t dest = cpu->gprs[1];
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_DECOMPRESS;
|
||||||
uint32_t header = cpu->memory.load32(cpu, source, 0);
|
uint32_t header = cpu->memory.load32(cpu, source, 0);
|
||||||
int remaining = header >> 8;
|
int remaining = header >> 8;
|
||||||
// We assume the signature nybble (0x8) is correct
|
// We assume the signature nybble (0x8) is correct
|
||||||
@ -888,6 +909,7 @@ static void _unFilter(struct GBA* gba, int inwidth, int outwidth) {
|
|||||||
old = new;
|
old = new;
|
||||||
source += inwidth;
|
source += inwidth;
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
cpu->gprs[0] = source;
|
cpu->gprs[0] = source;
|
||||||
cpu->gprs[1] = dest;
|
cpu->gprs[1] = dest;
|
||||||
}
|
}
|
||||||
@ -897,6 +919,8 @@ static void _unBitPack(struct GBA* gba) {
|
|||||||
uint32_t source = cpu->gprs[0];
|
uint32_t source = cpu->gprs[0];
|
||||||
uint32_t dest = cpu->gprs[1];
|
uint32_t dest = cpu->gprs[1];
|
||||||
uint32_t info = cpu->gprs[2];
|
uint32_t info = cpu->gprs[2];
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
|
cpu->memory.accessSource = mACCESS_DECOMPRESS;
|
||||||
unsigned sourceLen = cpu->memory.load16(cpu, info, 0);
|
unsigned sourceLen = cpu->memory.load16(cpu, info, 0);
|
||||||
unsigned sourceWidth = cpu->memory.load8(cpu, info + 2, 0);
|
unsigned sourceWidth = cpu->memory.load8(cpu, info + 2, 0);
|
||||||
unsigned destWidth = cpu->memory.load8(cpu, info + 3, 0);
|
unsigned destWidth = cpu->memory.load8(cpu, info + 3, 0);
|
||||||
@ -908,6 +932,7 @@ static void _unBitPack(struct GBA* gba) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack source width: %u", sourceWidth);
|
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack source width: %u", sourceWidth);
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (destWidth) {
|
switch (destWidth) {
|
||||||
@ -920,6 +945,7 @@ static void _unBitPack(struct GBA* gba) {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack destination width: %u", destWidth);
|
mLOG(GBA_BIOS, GAME_ERROR, "Bad BitUnPack destination width: %u", destWidth);
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
uint32_t bias = cpu->memory.load32(cpu, info + 4, 0);
|
uint32_t bias = cpu->memory.load32(cpu, info + 4, 0);
|
||||||
@ -949,6 +975,7 @@ static void _unBitPack(struct GBA* gba) {
|
|||||||
dest += 4;
|
dest += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
cpu->gprs[0] = source;
|
cpu->gprs[0] = source;
|
||||||
cpu->gprs[1] = dest;
|
cpu->gprs[1] = dest;
|
||||||
}
|
}
|
||||||
|
@ -248,10 +248,12 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
|
|||||||
uint32_t dest = info->nextDest;
|
uint32_t dest = info->nextDest;
|
||||||
uint32_t sourceRegion = source >> BASE_OFFSET;
|
uint32_t sourceRegion = source >> BASE_OFFSET;
|
||||||
uint32_t destRegion = dest >> BASE_OFFSET;
|
uint32_t destRegion = dest >> BASE_OFFSET;
|
||||||
|
enum mMemoryAccessSource oldAccess = cpu->memory.accessSource;
|
||||||
int32_t cycles = 2;
|
int32_t cycles = 2;
|
||||||
|
|
||||||
gba->cpuBlocked = true;
|
gba->cpuBlocked = true;
|
||||||
gba->performingDMA = 1 | (number << 1);
|
gba->performingDMA = 1 | (number << 1);
|
||||||
|
cpu->memory.accessSource = mACCESS_DMA;
|
||||||
|
|
||||||
if (info->count == info->nextCount) {
|
if (info->count == info->nextCount) {
|
||||||
if (width == 4) {
|
if (width == 4) {
|
||||||
@ -315,6 +317,7 @@ void GBADMAService(struct GBA* gba, int number, struct GBADMA* info) {
|
|||||||
--info->nextCount;
|
--info->nextCount;
|
||||||
|
|
||||||
gba->performingDMA = 0;
|
gba->performingDMA = 0;
|
||||||
|
cpu->memory.accessSource = oldAccess;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 4; ++i) {
|
for (i = 0; i < 4; ++i) {
|
||||||
|
@ -82,6 +82,7 @@ void GBAMemoryInit(struct GBA* gba) {
|
|||||||
cpu->memory.activeSeqCycles16 = 0;
|
cpu->memory.activeSeqCycles16 = 0;
|
||||||
cpu->memory.activeNonseqCycles32 = 0;
|
cpu->memory.activeNonseqCycles32 = 0;
|
||||||
cpu->memory.activeNonseqCycles16 = 0;
|
cpu->memory.activeNonseqCycles16 = 0;
|
||||||
|
cpu->memory.accessSource = mACCESS_UNKNOWN;
|
||||||
gba->memory.biosPrefetch = 0;
|
gba->memory.biosPrefetch = 0;
|
||||||
|
|
||||||
gba->memory.agbPrintProtect = 0;
|
gba->memory.agbPrintProtect = 0;
|
||||||
@ -132,6 +133,7 @@ void GBAMemoryReset(struct GBA* gba) {
|
|||||||
|
|
||||||
gba->memory.prefetch = false;
|
gba->memory.prefetch = false;
|
||||||
gba->memory.lastPrefetchedPc = 0;
|
gba->memory.lastPrefetchedPc = 0;
|
||||||
|
gba->cpu->memory.accessSource = mACCESS_UNKNOWN;
|
||||||
|
|
||||||
if (!gba->memory.wram || !gba->memory.iwram) {
|
if (!gba->memory.wram || !gba->memory.iwram) {
|
||||||
GBAMemoryDeinit(gba);
|
GBAMemoryDeinit(gba);
|
||||||
@ -299,22 +301,27 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||||||
memory->activeRegion = newRegion;
|
memory->activeRegion = newRegion;
|
||||||
switch (newRegion) {
|
switch (newRegion) {
|
||||||
case GBA_REGION_BIOS:
|
case GBA_REGION_BIOS:
|
||||||
|
cpu->memory.accessSource = mACCESS_SYSTEM;
|
||||||
cpu->memory.activeRegion = memory->bios;
|
cpu->memory.activeRegion = memory->bios;
|
||||||
cpu->memory.activeMask = GBA_SIZE_BIOS - 1;
|
cpu->memory.activeMask = GBA_SIZE_BIOS - 1;
|
||||||
break;
|
break;
|
||||||
case GBA_REGION_EWRAM:
|
case GBA_REGION_EWRAM:
|
||||||
|
cpu->memory.accessSource = mACCESS_PROGRAM;
|
||||||
cpu->memory.activeRegion = memory->wram;
|
cpu->memory.activeRegion = memory->wram;
|
||||||
cpu->memory.activeMask = GBA_SIZE_EWRAM - 1;
|
cpu->memory.activeMask = GBA_SIZE_EWRAM - 1;
|
||||||
break;
|
break;
|
||||||
case GBA_REGION_IWRAM:
|
case GBA_REGION_IWRAM:
|
||||||
|
cpu->memory.accessSource = mACCESS_PROGRAM;
|
||||||
cpu->memory.activeRegion = memory->iwram;
|
cpu->memory.activeRegion = memory->iwram;
|
||||||
cpu->memory.activeMask = GBA_SIZE_IWRAM - 1;
|
cpu->memory.activeMask = GBA_SIZE_IWRAM - 1;
|
||||||
break;
|
break;
|
||||||
case GBA_REGION_PALETTE_RAM:
|
case GBA_REGION_PALETTE_RAM:
|
||||||
|
cpu->memory.accessSource = mACCESS_PROGRAM;
|
||||||
cpu->memory.activeRegion = (uint32_t*) gba->video.palette;
|
cpu->memory.activeRegion = (uint32_t*) gba->video.palette;
|
||||||
cpu->memory.activeMask = GBA_SIZE_PALETTE_RAM - 1;
|
cpu->memory.activeMask = GBA_SIZE_PALETTE_RAM - 1;
|
||||||
break;
|
break;
|
||||||
case GBA_REGION_VRAM:
|
case GBA_REGION_VRAM:
|
||||||
|
cpu->memory.accessSource = mACCESS_PROGRAM;
|
||||||
if (address & 0x10000) {
|
if (address & 0x10000) {
|
||||||
cpu->memory.activeRegion = (uint32_t*) &gba->video.vram[0x8000];
|
cpu->memory.activeRegion = (uint32_t*) &gba->video.vram[0x8000];
|
||||||
cpu->memory.activeMask = 0x00007FFF;
|
cpu->memory.activeMask = 0x00007FFF;
|
||||||
@ -324,6 +331,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GBA_REGION_OAM:
|
case GBA_REGION_OAM:
|
||||||
|
cpu->memory.accessSource = mACCESS_PROGRAM;
|
||||||
cpu->memory.activeRegion = (uint32_t*) gba->video.oam.raw;
|
cpu->memory.activeRegion = (uint32_t*) gba->video.oam.raw;
|
||||||
cpu->memory.activeMask = GBA_SIZE_OAM - 1;
|
cpu->memory.activeMask = GBA_SIZE_OAM - 1;
|
||||||
break;
|
break;
|
||||||
@ -333,6 +341,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||||||
case GBA_REGION_ROM1_EX:
|
case GBA_REGION_ROM1_EX:
|
||||||
case GBA_REGION_ROM2:
|
case GBA_REGION_ROM2:
|
||||||
case GBA_REGION_ROM2_EX:
|
case GBA_REGION_ROM2_EX:
|
||||||
|
cpu->memory.accessSource = mACCESS_PROGRAM;
|
||||||
cpu->memory.activeRegion = memory->rom;
|
cpu->memory.activeRegion = memory->rom;
|
||||||
cpu->memory.activeMask = memory->romMask;
|
cpu->memory.activeMask = memory->romMask;
|
||||||
if ((address & (GBA_SIZE_ROM0 - 1)) < memory->romSize) {
|
if ((address & (GBA_SIZE_ROM0 - 1)) < memory->romSize) {
|
||||||
@ -345,6 +354,7 @@ static void GBASetActiveRegion(struct ARMCore* cpu, uint32_t address) {
|
|||||||
}
|
}
|
||||||
// Fall through
|
// Fall through
|
||||||
default:
|
default:
|
||||||
|
cpu->memory.accessSource = mACCESS_UNKNOWN;
|
||||||
memory->activeRegion = -1;
|
memory->activeRegion = -1;
|
||||||
cpu->memory.activeRegion = (uint32_t*) _deadbeef;
|
cpu->memory.activeRegion = (uint32_t*) _deadbeef;
|
||||||
cpu->memory.activeMask = 0;
|
cpu->memory.activeMask = 0;
|
||||||
|
@ -61,6 +61,7 @@ static void _checkWatchpoints(struct SM83Debugger* debugger, uint16_t address, e
|
|||||||
info.type.wp.newValue = newValue;
|
info.type.wp.newValue = newValue;
|
||||||
info.type.wp.watchType = watchpoint->type;
|
info.type.wp.watchType = watchpoint->type;
|
||||||
info.type.wp.accessType = type;
|
info.type.wp.accessType = type;
|
||||||
|
info.type.wp.accessSource = debugger->cpu->memory.accessSource;
|
||||||
info.address = address;
|
info.address = address;
|
||||||
info.segment = debugger->originalMemory.currentSegment(debugger->cpu, address);
|
info.segment = debugger->originalMemory.currentSegment(debugger->cpu, address);
|
||||||
info.width = 1;
|
info.width = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user