mirror of https://github.com/mgba-emu/mgba.git
ARM: Implement MCR
This commit is contained in:
parent
20296e7f0e
commit
7ff9c0af5b
|
@ -112,6 +112,7 @@ struct ARMInterruptHandler {
|
||||||
void (*bkpt32)(struct ARMCore* cpu, int immediate);
|
void (*bkpt32)(struct ARMCore* cpu, int immediate);
|
||||||
void (*readCPSR)(struct ARMCore* cpu);
|
void (*readCPSR)(struct ARMCore* cpu);
|
||||||
void (*writeCP15)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2, uint32_t value);
|
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);
|
void (*hitStub)(struct ARMCore* cpu, uint32_t opcode);
|
||||||
};
|
};
|
||||||
|
|
|
@ -687,7 +687,12 @@ DEFINE_INSTRUCTION_ARM(BLX2,
|
||||||
UNUSED(crm); \
|
UNUSED(crm); \
|
||||||
BODY;)
|
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,
|
DEFINE_COPROCESSOR_INSTRUCTION(MCR,
|
||||||
if (cp == 15 && cpu->irqh.writeCP15) {
|
if (cp == 15 && cpu->irqh.writeCP15) {
|
||||||
|
|
27
src/ds/ds.c
27
src/ds/ds.c
|
@ -46,6 +46,7 @@ static void DS7ProcessEvents(struct ARMCore* cpu);
|
||||||
static void DS9Reset(struct ARMCore* cpu);
|
static void DS9Reset(struct ARMCore* cpu);
|
||||||
static void DS9TestIRQ(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 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 DS9InterruptHandlerInit(struct ARMInterruptHandler* irqh);
|
||||||
static void DS9ProcessEvents(struct ARMCore* cpu);
|
static void DS9ProcessEvents(struct ARMCore* cpu);
|
||||||
|
|
||||||
|
@ -154,6 +155,7 @@ void DS7InterruptHandlerInit(struct ARMInterruptHandler* irqh) {
|
||||||
irqh->hitIllegal = DSIllegal;
|
irqh->hitIllegal = DSIllegal;
|
||||||
irqh->readCPSR = DS7TestIRQ;
|
irqh->readCPSR = DS7TestIRQ;
|
||||||
irqh->writeCP15 = NULL;
|
irqh->writeCP15 = NULL;
|
||||||
|
irqh->readCP15 = NULL;
|
||||||
irqh->hitStub = DSHitStub;
|
irqh->hitStub = DSHitStub;
|
||||||
irqh->bkpt16 = DSBreakpoint;
|
irqh->bkpt16 = DSBreakpoint;
|
||||||
irqh->bkpt32 = DSBreakpoint;
|
irqh->bkpt32 = DSBreakpoint;
|
||||||
|
@ -167,6 +169,7 @@ void DS9InterruptHandlerInit(struct ARMInterruptHandler* irqh) {
|
||||||
irqh->hitIllegal = DSIllegal;
|
irqh->hitIllegal = DSIllegal;
|
||||||
irqh->readCPSR = DS9TestIRQ;
|
irqh->readCPSR = DS9TestIRQ;
|
||||||
irqh->writeCP15 = DS9WriteCP15;
|
irqh->writeCP15 = DS9WriteCP15;
|
||||||
|
irqh->readCP15 = DS9ReadCP15;
|
||||||
irqh->hitStub = DSHitStub;
|
irqh->hitStub = DSHitStub;
|
||||||
irqh->bkpt16 = DSBreakpoint;
|
irqh->bkpt16 = DSBreakpoint;
|
||||||
irqh->bkpt32 = DSBreakpoint;
|
irqh->bkpt32 = DSBreakpoint;
|
||||||
|
@ -522,7 +525,7 @@ static void _writeCache(struct ARMCore* cpu, int crm, int opcode2, uint32_t valu
|
||||||
static void _writeTCMControl(struct ARMCore* cpu, int crm, int opcode2, uint32_t value) {
|
static void _writeTCMControl(struct ARMCore* cpu, int crm, int opcode2, uint32_t value) {
|
||||||
uint32_t base = ARMTCMControlGetBase(value) << 12;
|
uint32_t base = ARMTCMControlGetBase(value) << 12;
|
||||||
uint32_t size = 512 << ARMTCMControlGetVirtualSize(value);
|
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) {
|
switch (opcode2) {
|
||||||
case 0:
|
case 0:
|
||||||
cpu->cp15.r9.d = value;
|
cpu->cp15.r9.d = value;
|
||||||
|
@ -569,6 +572,28 @@ void DS9WriteCP15(struct ARMCore* cpu, int crn, int crm, int opcode1, int opcode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DSWriteIE(struct ARMCore* cpu, uint16_t* io, uint32_t value) {
|
void DSWriteIE(struct ARMCore* cpu, uint16_t* io, uint32_t value) {
|
||||||
if (io[DS_REG_IME >> 1] && (value & io[DS_REG_IF_LO >> 1] || (value >> 16) & io[DS_REG_IF_HI >> 1])) {
|
if (io[DS_REG_IME >> 1] && (value & io[DS_REG_IF_LO >> 1] || (value >> 16) & io[DS_REG_IF_HI >> 1])) {
|
||||||
ARMRaiseIRQ(cpu);
|
ARMRaiseIRQ(cpu);
|
||||||
|
|
Loading…
Reference in New Issue