ARM: Add framework for coprocessor support

This commit is contained in:
Vicki Pfau 2024-06-02 17:30:17 -07:00
parent 942167acdf
commit e4e455dd5e
4 changed files with 45 additions and 3 deletions

View File

@ -7,6 +7,7 @@ Features:
- New unlicensed GB mappers: NT (older types 1 and 2), Li Cheng, GGB-81
- Debugger: Add range watchpoints
Emulation fixes:
- ARM: Add framework for coprocessor support
- GB Audio: Fix audio envelope timing resetting too often (fixes mgba.io/i/3164)
- GB I/O: Fix STAT writing IRQ trigger conditions (fixes mgba.io/i/2501)
- GB Serialize: Add missing Pocket Cam state to savestates

View File

@ -134,6 +134,12 @@ struct ARMMemory {
void (*setActiveRegion)(struct ARMCore*, uint32_t address);
};
struct ARMCoprocessor {
int32_t (*mrc)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2);
void (*mcr)(struct ARMCore*, int crn, int crm, int opcode1, int opcode2, int32_t value);
void (*cdp)(struct ARMCore*, int crn, int crm, int crd, int opcode1, int opcode2);
};
struct ARMInterruptHandler {
void (*reset)(struct ARMCore* cpu);
void (*processEvents)(struct ARMCore* cpu);
@ -179,6 +185,7 @@ struct ARMCore {
struct ARMMemory memory;
struct ARMInterruptHandler irqh;
struct ARMCoprocessor cp[16];
struct mCPUComponent* master;

View File

@ -45,6 +45,7 @@ void ARMSetPrivilegeMode(struct ARMCore* cpu, enum PrivilegeMode mode) {
}
void ARMInit(struct ARMCore* cpu) {
memset(cpu->cp, 0, sizeof(cpu->cp));
cpu->master->init(cpu, cpu->master);
size_t i;
for (i = 0; i < cpu->numComponents; ++i) {

View File

@ -655,11 +655,44 @@ DEFINE_INSTRUCTION_ARM(BX,
// Begin coprocessor definitions
DEFINE_INSTRUCTION_ARM(CDP, ARM_STUB)
#define DEFINE_COPROCESSOR_INSTRUCTION(NAME, BODY) \
DEFINE_INSTRUCTION_ARM(NAME, \
int op1 = (opcode >> 21) & 7; \
int op2 = (opcode >> 5) & 7; \
int rd = (opcode >> 12) & 0xF; \
int cp = (opcode >> 8) & 0xF; \
int crn = (opcode >> 16) & 0xF; \
int crm = opcode & 0xF; \
UNUSED(op1); \
UNUSED(op2); \
UNUSED(rd); \
UNUSED(crn); \
UNUSED(crm); \
BODY;)
DEFINE_COPROCESSOR_INSTRUCTION(MRC,
if (cpu->cp[cp].mrc) {
cpu->gprs[rd] = cpu->cp[cp].mrc(cpu, crn, crm, op1, op2);
} else {
ARM_ILL;
})
DEFINE_COPROCESSOR_INSTRUCTION(MCR,
if (cpu->cp[cp].mcr) {
cpu->cp[cp].mcr(cpu, crn, crm, op1, op2, cpu->gprs[rd]);
} else {
ARM_ILL;
})
DEFINE_COPROCESSOR_INSTRUCTION(CDP,
if (cpu->cp[cp].cdp) {
cpu->cp[cp].cdp(cpu, crn, crm, rd, op1, op2);
} else {
ARM_ILL;
})
DEFINE_INSTRUCTION_ARM(LDC, ARM_STUB)
DEFINE_INSTRUCTION_ARM(STC, ARM_STUB)
DEFINE_INSTRUCTION_ARM(MCR, ARM_STUB)
DEFINE_INSTRUCTION_ARM(MRC, ARM_STUB)
// Begin miscellaneous definitions