mirror of https://github.com/mgba-emu/mgba.git
LR35902: Support PC-relative opcode decoding
This commit is contained in:
parent
c3ec7311e8
commit
d6ac0dc6f5
1
CHANGES
1
CHANGES
|
@ -22,6 +22,7 @@ Misc:
|
||||||
- Qt: Don't unload ROM immediately if it crashes
|
- Qt: Don't unload ROM immediately if it crashes
|
||||||
- Debugger: Add breakpoint and watchpoint listing
|
- Debugger: Add breakpoint and watchpoint listing
|
||||||
- Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323)
|
- Qt: Add missing HEVC NVENC option (fixes mgba.io/i/1323)
|
||||||
|
- LR35902: Support PC-relative opcode decoding
|
||||||
|
|
||||||
0.7.1: (2019-02-24)
|
0.7.1: (2019-02-24)
|
||||||
Bugfixes:
|
Bugfixes:
|
||||||
|
|
|
@ -86,6 +86,7 @@ enum {
|
||||||
LR35902_OP_FLAG_MEMORY = 2,
|
LR35902_OP_FLAG_MEMORY = 2,
|
||||||
LR35902_OP_FLAG_INCREMENT = 4,
|
LR35902_OP_FLAG_INCREMENT = 4,
|
||||||
LR35902_OP_FLAG_DECREMENT = 8,
|
LR35902_OP_FLAG_DECREMENT = 8,
|
||||||
|
LR35902_OP_FLAG_RELATIVE = 16,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LR35902Operand {
|
struct LR35902Operand {
|
||||||
|
@ -104,7 +105,7 @@ struct LR35902InstructionInfo {
|
||||||
};
|
};
|
||||||
|
|
||||||
size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info);
|
size_t LR35902Decode(uint8_t opcode, struct LR35902InstructionInfo* info);
|
||||||
int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen);
|
int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen);
|
||||||
|
|
||||||
CXX_GUARD_END
|
CXX_GUARD_END
|
||||||
|
|
||||||
|
|
|
@ -199,6 +199,7 @@ DEFINE_DECODER_LR35902(ADDSP, info->mnemonic = LR35902_MN_ADD; \
|
||||||
DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \
|
DEFINE_DECODER_LR35902(JR ## CONDITION_NAME, \
|
||||||
info->mnemonic = LR35902_MN_JR; \
|
info->mnemonic = LR35902_MN_JR; \
|
||||||
info->condition = CONDITION; \
|
info->condition = CONDITION; \
|
||||||
|
info->op1.flags = LR35902_OP_FLAG_RELATIVE; \
|
||||||
return 1;)
|
return 1;)
|
||||||
|
|
||||||
#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
|
#define DEFINE_CALL_INSTRUCTION_LR35902(CONDITION_NAME, CONDITION) \
|
||||||
|
@ -497,7 +498,7 @@ static const char* _lr35902MnemonicStrings[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) {
|
static int _decodeOperand(struct LR35902Operand op, uint16_t pc, char* buffer, int blen) {
|
||||||
int total = 0;
|
int total = 0;
|
||||||
if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
|
if (op.flags & LR35902_OP_FLAG_IMPLICIT) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -511,7 +512,12 @@ static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) {
|
||||||
int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
|
int written = snprintf(buffer, blen - 1, "%s", _lr35902Registers[op.reg]);
|
||||||
ADVANCE(written);
|
ADVANCE(written);
|
||||||
} else {
|
} else {
|
||||||
int written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
|
int written;
|
||||||
|
if (op.flags & LR35902_OP_FLAG_RELATIVE) {
|
||||||
|
written = snprintf(buffer, blen - 1, "$%04X", pc + (int8_t) op.immediate);
|
||||||
|
} else {
|
||||||
|
written = snprintf(buffer, blen - 1, "$%02X", op.immediate);
|
||||||
|
}
|
||||||
ADVANCE(written);
|
ADVANCE(written);
|
||||||
if (op.reg) {
|
if (op.reg) {
|
||||||
strncpy(buffer, "+", blen - 1);
|
strncpy(buffer, "+", blen - 1);
|
||||||
|
@ -533,7 +539,7 @@ static int _decodeOperand(struct LR35902Operand op, char* buffer, int blen) {
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int blen) {
|
int LR35902Disassemble(struct LR35902InstructionInfo* info, uint16_t pc, char* buffer, int blen) {
|
||||||
const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
|
const char* mnemonic = _lr35902MnemonicStrings[info->mnemonic];
|
||||||
int written;
|
int written;
|
||||||
int total = 0;
|
int total = 0;
|
||||||
|
@ -553,7 +559,7 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int bl
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
|
if (info->op1.reg || info->op1.immediate || info->op2.reg || info->op2.immediate) {
|
||||||
written = _decodeOperand(info->op1, buffer, blen);
|
written = _decodeOperand(info->op1, pc, buffer, blen);
|
||||||
ADVANCE(written);
|
ADVANCE(written);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -562,7 +568,7 @@ int LR35902Disassemble(struct LR35902InstructionInfo* info, char* buffer, int bl
|
||||||
strncpy(buffer, ", ", blen - 1);
|
strncpy(buffer, ", ", blen - 1);
|
||||||
ADVANCE(2);
|
ADVANCE(2);
|
||||||
}
|
}
|
||||||
written = _decodeOperand(info->op2, buffer, blen);
|
written = _decodeOperand(info->op2, pc, buffer, blen);
|
||||||
ADVANCE(written);
|
ADVANCE(written);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue