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 (*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);
|
||||
};
|
||||
|
|
|
@ -687,7 +687,12 @@ DEFINE_INSTRUCTION_ARM(BLX2,
|
|||
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) {
|
||||
|
|
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 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 @@ void DS7InterruptHandlerInit(struct ARMInterruptHandler* irqh) {
|
|||
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 @@ void DS9InterruptHandlerInit(struct ARMInterruptHandler* irqh) {
|
|||
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 _writeCache(struct ARMCore* cpu, int crm, int opcode2, uint32_t valu
|
|||
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;
|
||||
|
@ -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) {
|
||||
if (io[DS_REG_IME >> 1] && (value & io[DS_REG_IF_LO >> 1] || (value >> 16) & io[DS_REG_IF_HI >> 1])) {
|
||||
ARMRaiseIRQ(cpu);
|
||||
|
|
Loading…
Reference in New Issue