ARM: Implement MCR
Vicki Pfau vi@endrift.com
Mon, 30 Jan 2017 12:17:08 -0800
3 files changed,
33 insertions(+),
2 deletions(-)
M
include/mgba/internal/arm/arm.h
→
include/mgba/internal/arm/arm.h
@@ -112,6 +112,7 @@ void (*bkpt16)(struct ARMCore* cpu, int immediate);
void (*bkpt32)(struct ARMCore* cpu, int immediate); void (*readCPSR)(struct ARMCore* cpu); void (*writeCP15)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2, uint32_t value); + uint32_t (*readCP15)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2); void (*hitStub)(struct ARMCore* cpu, uint32_t opcode); };
M
src/arm/isa-arm.c
→
src/arm/isa-arm.c
@@ -687,7 +687,12 @@ UNUSED(crn); \
UNUSED(crm); \ BODY;) -DEFINE_COPROCESSOR_INSTRUCTION(MRC, ARM_STUB) +DEFINE_COPROCESSOR_INSTRUCTION(MRC, + if (cp == 15 && cpu->irqh.readCP15) { + cpu->gprs[rd] = cpu->irqh.readCP15(cpu, crn, crm, op1, op2); + } else { + ARM_STUB; + }) DEFINE_COPROCESSOR_INSTRUCTION(MCR, if (cp == 15 && cpu->irqh.writeCP15) {
M
src/ds/ds.c
→
src/ds/ds.c
@@ -46,6 +46,7 @@
static void DS9Reset(struct ARMCore* cpu); static void DS9TestIRQ(struct ARMCore* cpu); static void DS9WriteCP15(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2, uint32_t value); +static uint32_t DS9ReadCP15(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2); static void DS9InterruptHandlerInit(struct ARMInterruptHandler* irqh); static void DS9ProcessEvents(struct ARMCore* cpu);@@ -154,6 +155,7 @@ irqh->swi32 = DS7Swi32;
irqh->hitIllegal = DSIllegal; irqh->readCPSR = DS7TestIRQ; irqh->writeCP15 = NULL; + irqh->readCP15 = NULL; irqh->hitStub = DSHitStub; irqh->bkpt16 = DSBreakpoint; irqh->bkpt32 = DSBreakpoint;@@ -167,6 +169,7 @@ irqh->swi32 = NULL;
irqh->hitIllegal = DSIllegal; irqh->readCPSR = DS9TestIRQ; irqh->writeCP15 = DS9WriteCP15; + irqh->readCP15 = DS9ReadCP15; irqh->hitStub = DSHitStub; irqh->bkpt16 = DSBreakpoint; irqh->bkpt32 = DSBreakpoint;@@ -522,7 +525,7 @@
static void _writeTCMControl(struct ARMCore* cpu, int crm, int opcode2, uint32_t value) { uint32_t base = ARMTCMControlGetBase(value) << 12; uint32_t size = 512 << ARMTCMControlGetVirtualSize(value); - mLOG(DS, STUB, "CP15 TCM control write: CRm: %i, Op2: %i, Base: %08X, Size: %08X", crm, opcode2, base, size); + mLOG(DS, DEBUG, "CP15 TCM control write: CRm: %i, Op2: %i, Base: %08X, Size: %08X", crm, opcode2, base, size); switch (opcode2) { case 0: cpu->cp15.r9.d = value;@@ -566,6 +569,28 @@ break;
case 9: _writeTCMControl(cpu, crm, opcode2, value); break; + } +} + +static uint32_t _readTCMControl(struct ARMCore* cpu, int crm, int opcode2) { + switch (opcode2) { + case 0: + return cpu->cp15.r9.d; + case 1: + return cpu->cp15.r9.i; + default: + mLOG(DS, GAME_ERROR, "CP15 TCM control bad op2: %i", opcode2); + return 0; + } +} + +uint32_t DS9ReadCP15(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode2) { + switch (crn) { + default: + mLOG(DS, STUB, "CP15 unknown read: CRn: %i, CRm: %i, Op1: %i, Op2: %i", crn, crm, opcode1, opcode2); + return 0; + case 9: + return _readTCMControl(cpu, crm, opcode2); } }