mirror of https://github.com/mgba-emu/mgba.git
Handle illegal and stub opcodes separately
This commit is contained in:
parent
ce4d0b5203
commit
a969d70de3
|
@ -117,6 +117,7 @@ struct ARMBoard {
|
||||||
void (*processEvents)(struct ARMBoard* board);
|
void (*processEvents)(struct ARMBoard* board);
|
||||||
void (*swi16)(struct ARMBoard* board, int immediate);
|
void (*swi16)(struct ARMBoard* board, int immediate);
|
||||||
void (*swi32)(struct ARMBoard* board, int immediate);
|
void (*swi32)(struct ARMBoard* board, int immediate);
|
||||||
|
void (*hitIllegal)(struct ARMBoard* board, uint32_t opcode);
|
||||||
void (*readCPSR)(struct ARMBoard* board);
|
void (*readCPSR)(struct ARMBoard* board);
|
||||||
|
|
||||||
void (*hitStub)(struct ARMBoard* board, uint32_t opcode);
|
void (*hitStub)(struct ARMBoard* board, uint32_t opcode);
|
||||||
|
|
|
@ -744,10 +744,18 @@ DEFINE_INSTRUCTION_ARM(BX,
|
||||||
|
|
||||||
// End branch definitions
|
// End branch definitions
|
||||||
|
|
||||||
|
// Begin coprocessor definitions
|
||||||
|
|
||||||
|
DEFINE_INSTRUCTION_ARM(CDP, ARM_STUB)
|
||||||
|
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
|
// Begin miscellaneous definitions
|
||||||
|
|
||||||
DEFINE_INSTRUCTION_ARM(BKPT, ARM_STUB) // Not strictly in ARMv4T, but here for convenience
|
DEFINE_INSTRUCTION_ARM(BKPT, ARM_STUB) // Not strictly in ARMv4T, but here for convenience
|
||||||
DEFINE_INSTRUCTION_ARM(ILL, ARM_STUB) // Illegal opcode
|
DEFINE_INSTRUCTION_ARM(ILL, ARM_ILL) // Illegal opcode
|
||||||
|
|
||||||
DEFINE_INSTRUCTION_ARM(MSR,
|
DEFINE_INSTRUCTION_ARM(MSR,
|
||||||
int c = opcode & 0x00010000;
|
int c = opcode & 0x00010000;
|
||||||
|
@ -858,13 +866,12 @@ DEFINE_INSTRUCTION_ARM(SWI, cpu->board->swi32(cpu->board, opcode & 0xFFFFFF))
|
||||||
DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
|
DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
|
||||||
|
|
||||||
// TODO: Support coprocessors
|
// TODO: Support coprocessors
|
||||||
#define DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, NAME, P, U, W, N) \
|
#define DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, NAME, P, U, N, W) \
|
||||||
DO_8(0), \
|
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME)), \
|
||||||
DO_8(0)
|
DO_8(DECLARE_INSTRUCTION_ARM(EMITTER, NAME))
|
||||||
|
|
||||||
#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2) \
|
#define DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, NAME1, NAME2) \
|
||||||
DO_8(DO_8(DO_INTERLACE(0, 0))), \
|
DO_8(DO_8(DO_INTERLACE(DECLARE_INSTRUCTION_ARM(EMITTER, NAME1), DECLARE_INSTRUCTION_ARM(EMITTER, NAME2))))
|
||||||
DO_8(DO_8(DO_INTERLACE(0, 0)))
|
|
||||||
|
|
||||||
#define DECLARE_ARM_SWI_BLOCK(EMITTER) \
|
#define DECLARE_ARM_SWI_BLOCK(EMITTER) \
|
||||||
DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI))
|
DO_256(DECLARE_INSTRUCTION_ARM(EMITTER, SWI))
|
||||||
|
@ -1125,6 +1132,7 @@ DEFINE_INSTRUCTION_ARM(SWI, cpu->board->swi32(cpu->board, opcode & 0xFFFFFF))
|
||||||
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
|
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, STC, P, U, N, W), \
|
||||||
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
|
DECLARE_ARM_LOAD_STORE_COPROCESSOR_BLOCK(EMITTER, LDC, P, U, N, W), \
|
||||||
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \
|
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MCR), \
|
||||||
|
DECLARE_ARM_COPROCESSOR_BLOCK(EMITTER, CDP, MRC), \
|
||||||
DECLARE_ARM_SWI_BLOCK(EMITTER)
|
DECLARE_ARM_SWI_BLOCK(EMITTER)
|
||||||
|
|
||||||
static const ARMInstruction _armTable[0x1000] = {
|
static const ARMInstruction _armTable[0x1000] = {
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#define ARM_STUB cpu->board->hitStub(cpu->board, opcode)
|
#define ARM_STUB cpu->board->hitStub(cpu->board, opcode)
|
||||||
|
#define ARM_ILL cpu->board->hitIllegal(cpu->board, opcode)
|
||||||
|
|
||||||
#define ARM_WRITE_PC \
|
#define ARM_WRITE_PC \
|
||||||
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \
|
cpu->gprs[ARM_PC] = (cpu->gprs[ARM_PC] & -WORD_SIZE_ARM) + WORD_SIZE_ARM; \
|
||||||
|
|
|
@ -448,7 +448,7 @@ DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSHR,
|
||||||
THUMB_STORE_POST_BODY,
|
THUMB_STORE_POST_BODY,
|
||||||
cpu->gprs[ARM_SP] = address + 4)
|
cpu->gprs[ARM_SP] = address + 4)
|
||||||
|
|
||||||
DEFINE_INSTRUCTION_THUMB(ILL, ARM_STUB)
|
DEFINE_INSTRUCTION_THUMB(ILL, ARM_ILL)
|
||||||
DEFINE_INSTRUCTION_THUMB(BKPT, ARM_STUB)
|
DEFINE_INSTRUCTION_THUMB(BKPT, ARM_STUB)
|
||||||
DEFINE_INSTRUCTION_THUMB(B,
|
DEFINE_INSTRUCTION_THUMB(B,
|
||||||
int16_t immediate = (opcode & 0x07FF) << 5;
|
int16_t immediate = (opcode & 0x07FF) << 5;
|
||||||
|
@ -589,7 +589,7 @@ DEFINE_INSTRUCTION_THUMB(SWI, cpu->board->swi16(cpu->board, opcode & 0xFF))
|
||||||
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, B))), \
|
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, B))), \
|
||||||
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL))), \
|
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, ILL))), \
|
||||||
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL1))), \
|
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL1))), \
|
||||||
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL2))) \
|
DO_8(DO_4(DECLARE_INSTRUCTION_THUMB(EMITTER, BL2)))
|
||||||
|
|
||||||
static const ThumbInstruction _thumbTable[0x400] = {
|
static const ThumbInstruction _thumbTable[0x400] = {
|
||||||
DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction)
|
DECLARE_THUMB_EMITTER_BLOCK(_ThumbInstruction)
|
||||||
|
|
|
@ -97,6 +97,7 @@ static const struct GBACartridgeOverride _overrides[] = {
|
||||||
static void GBAProcessEvents(struct ARMBoard* board);
|
static void GBAProcessEvents(struct ARMBoard* board);
|
||||||
static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles);
|
static int32_t GBATimersProcessEvents(struct GBA* gba, int32_t cycles);
|
||||||
static void GBAHitStub(struct ARMBoard* board, uint32_t opcode);
|
static void GBAHitStub(struct ARMBoard* board, uint32_t opcode);
|
||||||
|
static void GBAIllegal(struct ARMBoard* board, uint32_t opcode);
|
||||||
|
|
||||||
static void _checkOverrides(struct GBA* gba, uint32_t code);
|
static void _checkOverrides(struct GBA* gba, uint32_t code);
|
||||||
|
|
||||||
|
@ -146,6 +147,7 @@ void GBABoardInit(struct GBABoard* board) {
|
||||||
board->d.processEvents = GBAProcessEvents;
|
board->d.processEvents = GBAProcessEvents;
|
||||||
board->d.swi16 = GBASwi16;
|
board->d.swi16 = GBASwi16;
|
||||||
board->d.swi32 = GBASwi32;
|
board->d.swi32 = GBASwi32;
|
||||||
|
board->d.hitIllegal = GBAIllegal;
|
||||||
board->d.readCPSR = GBATestIRQ;
|
board->d.readCPSR = GBATestIRQ;
|
||||||
board->d.hitStub = GBAHitStub;
|
board->d.hitStub = GBAHitStub;
|
||||||
}
|
}
|
||||||
|
@ -528,7 +530,16 @@ void GBAHitStub(struct ARMBoard* board, uint32_t opcode) {
|
||||||
#else
|
#else
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void GBAIllegal(struct ARMBoard* board, uint32_t opcode) {
|
||||||
|
struct GBABoard* gbaBoard = (struct GBABoard*) board;
|
||||||
|
GBALog(gbaBoard->p, GBA_LOG_WARN, "Illegal opcode: %08x", opcode);
|
||||||
|
#ifdef USE_DEBUGGER
|
||||||
|
if (gbaBoard->p->debugger) {
|
||||||
|
ARMDebuggerEnter(gbaBoard->p->debugger);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void _checkOverrides(struct GBA* gba, uint32_t id) {
|
void _checkOverrides(struct GBA* gba, uint32_t id) {
|
||||||
|
|
Loading…
Reference in New Issue