mirror of https://github.com/mgba-emu/mgba.git
Merge branch 'master' (early part) into medusa
This commit is contained in:
commit
44438d42dc
|
@ -72,6 +72,9 @@ CXX_GUARD_START
|
|||
#define ARM_MEMORY_DECREMENT_BEFORE 0x0200
|
||||
#define ARM_MEMORY_INCREMENT_BEFORE 0x0300
|
||||
#define ARM_MEMORY_SPSR_SWAP 0x0400
|
||||
#define ARM_MEMORY_STORE 0x1000
|
||||
#define ARM_MEMORY_LOAD 0x2000
|
||||
#define ARM_MEMORY_SWAP 0x3000
|
||||
|
||||
#define ARM_PSR_C 1
|
||||
#define ARM_PSR_X 2
|
||||
|
|
|
@ -192,61 +192,68 @@
|
|||
} \
|
||||
CYCLES;)
|
||||
|
||||
#define DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
#define DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
|
||||
ARM_MEMORY_POST_INCREMENT | \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
|
||||
ARM_MEMORY_POST_INCREMENT | \
|
||||
ARM_MEMORY_WRITEBACK, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## P, MNEMONIC, \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PW, MNEMONIC, \
|
||||
ARM_MEMORY_PRE_INCREMENT | \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PU, MNEMONIC, \
|
||||
0, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## PUW, MNEMONIC, \
|
||||
ARM_MEMORY_WRITEBACK, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
|
||||
#define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE, OTHER_AFFECTED)
|
||||
#define DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(NAME, MNEMONIC, FORMAT, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, TYPE, FORMAT, OTHER_AFFECTED)
|
||||
|
||||
#define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_3_IMM, CYCLES, TYPE, OTHER_AFFECTED)
|
||||
#define DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(NAME, MNEMONIC, FORMAT, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME, MNEMONIC, ADDR_MODE_3_REG, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_3_IMM, TYPE, FORMAT, OTHER_AFFECTED)
|
||||
|
||||
#define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
#define DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME, MNEMONIC, ADDRESSING_MODE, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME, MNEMONIC, \
|
||||
ARM_MEMORY_POST_INCREMENT | \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
ARM_MEMORY_OFFSET_SUBTRACT | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_DECODER_EX_ARM(NAME ## U, MNEMONIC, \
|
||||
ARM_MEMORY_POST_INCREMENT | \
|
||||
ARM_MEMORY_WRITEBACK, \
|
||||
ADDRESSING_MODE, CYCLES, TYPE, OTHER_AFFECTED)
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_ ## FORMAT, \
|
||||
ADDRESSING_MODE, FORMAT ## _CYCLES, ARM_ACCESS_ ## TYPE, OTHER_AFFECTED)
|
||||
|
||||
#define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, CYCLES, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, CYCLES, TYPE, OTHER_AFFECTED)
|
||||
#define DEFINE_LOAD_STORE_T_DECODER_ARM(NAME, MNEMONIC, FORMAT, TYPE, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSL_, MNEMONIC, ADDR_MODE_2_LSL, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _LSR_, MNEMONIC, ADDR_MODE_2_LSR, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ASR_, MNEMONIC, ADDR_MODE_2_ASR, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## _ROR_, MNEMONIC, ADDR_MODE_2_ROR, TYPE, FORMAT, OTHER_AFFECTED) \
|
||||
DEFINE_LOAD_STORE_T_DECODER_SET_ARM(NAME ## I, MNEMONIC, ADDR_MODE_2_IMM, TYPE, FORMAT, OTHER_AFFECTED)
|
||||
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, WRITEBACK) \
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME, MNEMONIC, DIRECTION, FORMAT) \
|
||||
DEFINE_DECODER_ARM(NAME, MNEMONIC, \
|
||||
info->memory.baseReg = (opcode >> 16) & 0xF; \
|
||||
info->op1.immediate = opcode & 0x0000FFFF; \
|
||||
|
@ -255,30 +262,30 @@
|
|||
} \
|
||||
info->operandFormat = ARM_OPERAND_MEMORY_1; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
WRITEBACK | \
|
||||
FORMAT | \
|
||||
ARM_MEMORY_ ## DIRECTION;)
|
||||
|
||||
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, SUFFIX) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DA, NAME, DECREMENT_AFTER, 0) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DB, NAME, DECREMENT_BEFORE, 0) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IA, NAME, INCREMENT_AFTER, 0) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IB, NAME, INCREMENT_BEFORE, 0) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK) \
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, SUFFIX, FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DA, NAME, DECREMENT_AFTER, ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DB, NAME, DECREMENT_BEFORE, ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## DBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IA, NAME, INCREMENT_AFTER, ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IB, NAME, INCREMENT_BEFORE, ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SUFFIX ## IBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_ ## FORMAT) \
|
||||
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME, ) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA, NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB, NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIA, NAME, INCREMENT_AFTER, ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIB, NAME, INCREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP)
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(NAME, FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(NAME,, FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDA, NAME, DECREMENT_AFTER, ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDAW, NAME, DECREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDB, NAME, DECREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SDBW, NAME, DECREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIA, NAME, INCREMENT_AFTER, ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIAW, NAME, INCREMENT_AFTER, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIB, NAME, INCREMENT_BEFORE, ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_EX_ARM(NAME ## SIBW, NAME, INCREMENT_BEFORE, ARM_MEMORY_WRITEBACK | ARM_MEMORY_SPSR_SWAP | ARM_MEMORY_ ## FORMAT)
|
||||
|
||||
#define DEFINE_SWP_DECODER_ARM(NAME, TYPE) \
|
||||
DEFINE_DECODER_ARM(NAME, SWP, \
|
||||
|
@ -288,8 +295,8 @@
|
|||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_1 | \
|
||||
ARM_OPERAND_REGISTER_2 | \
|
||||
ARM_OPERAND_MEMORY_3; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE; \
|
||||
ARM_OPERAND_MEMORY_3 | ARM_OPERAND_AFFECTED_3; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | ARM_MEMORY_SWAP; \
|
||||
info->memory.width = TYPE;)
|
||||
|
||||
DEFINE_ALU_DECODER_ARM(ADD, 0)
|
||||
|
@ -334,26 +341,26 @@ DEFINE_MULTIPLY_DECODER_EX_ARM(SMULWT, SMULWT, 0, 0)
|
|||
|
||||
// Begin load/store definitions
|
||||
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRv5, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRD, LDR, LOAD_CYCLES, ARM_ACCESS_DUALWORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STR, STR, STORE_CYCLES, ARM_ACCESS_WORD, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STRB, STR, STORE_CYCLES, ARM_ACCESS_BYTE, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRD, STR, STORE_CYCLES, ARM_ACCESS_DUALWORD, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDR, LDR, LOAD, WORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRv5, LDR, LOAD, WORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(LDRB, LDR, LOAD, BYTE, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRD, LDR, LOAD, DUALWORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRH, LDR, LOAD, HALFWORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSB, LDR, LOAD, SIGNED_BYTE, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(LDRSH, LDR, LOAD, SIGNED_HALFWORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STR, STR, STORE, WORD, ARM_OPERAND_AFFECTED_2)
|
||||
DEFINE_LOAD_STORE_MODE_2_DECODER_ARM(STRB, STR, STORE, BYTE, ARM_OPERAND_AFFECTED_2)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRD, STR, STORE, DUALWORD, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_MODE_3_DECODER_ARM(STRH, STR, STORE, HALFWORD, ARM_OPERAND_AFFECTED_2)
|
||||
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_BYTE, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD_CYCLES, ARM_ACCESS_TRANSLATED_WORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_BYTE, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE_CYCLES, ARM_ACCESS_TRANSLATED_WORD, ARM_OPERAND_NONE)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(LDRBT, LDR, LOAD, TRANSLATED_BYTE, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(LDRT, LDR, LOAD, TRANSLATED_WORD, ARM_OPERAND_AFFECTED_1)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(STRBT, STR, STORE, TRANSLATED_BYTE, ARM_OPERAND_AFFECTED_2)
|
||||
DEFINE_LOAD_STORE_T_DECODER_ARM(STRT, STR, STORE, TRANSLATED_WORD, ARM_OPERAND_AFFECTED_2)
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(LDM, v5)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(LDM, LOAD)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM_NO_S(LDM, v5, LOAD)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_DECODER_ARM(STM, STORE)
|
||||
|
||||
DEFINE_SWP_DECODER_ARM(SWP, ARM_ACCESS_WORD)
|
||||
DEFINE_SWP_DECODER_ARM(SWPB, ARM_ACCESS_BYTE)
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
ARM_OPERAND_REGISTER_2 | \
|
||||
ARM_OPERAND_IMMEDIATE_3;)
|
||||
|
||||
#define DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(NAME, MNEMONIC, CYCLES, WIDTH, AFFECTED) \
|
||||
#define DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(NAME, MNEMONIC, FORMAT, WIDTH, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->memory.baseReg = (opcode >> 3) & 0x0007; \
|
||||
|
@ -37,18 +37,19 @@
|
|||
ARM_OPERAND_AFFECTED_ ## AFFECTED | \
|
||||
ARM_OPERAND_MEMORY_2; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_IMMEDIATE_OFFSET; \
|
||||
CYCLES)
|
||||
ARM_MEMORY_IMMEDIATE_OFFSET | \
|
||||
ARM_MEMORY_ ## FORMAT; \
|
||||
FORMAT ## _CYCLES)
|
||||
|
||||
DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(LSL1, LSL)
|
||||
DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(LSR1, LSR)
|
||||
DEFINE_IMMEDIATE_5_DECODER_DATA_THUMB(ASR1, ASR)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDR1, LDR, LOAD_CYCLES, 4, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRB1, LDR, LOAD_CYCLES, 1, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRH1, LDR, LOAD_CYCLES, 2, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STR1, STR, STORE_CYCLES, 4, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRB1, STR, STORE_CYCLES, 1, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRH1, STR, STORE_CYCLES, 2, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDR1, LDR, LOAD, 4, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRB1, LDR, LOAD, 1, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(LDRH1, LDR, LOAD, 2, 1)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STR1, STR, STORE, 4, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRB1, STR, STORE, 1, 2)
|
||||
DEFINE_IMMEDIATE_5_DECODER_MEM_THUMB(STRH1, STR, STORE, 2, 2)
|
||||
|
||||
#define DEFINE_DATA_FORM_1_DECODER_THUMB(NAME, MNEMONIC) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
|
@ -151,7 +152,7 @@ DEFINE_DECODER_WITH_HIGH_THUMB(MOV3, MOV, ARM_OPERAND_AFFECTED_1, 0)
|
|||
ARM_OPERAND_REGISTER_2 | \
|
||||
ARM_OPERAND_IMMEDIATE_3;)
|
||||
|
||||
#define DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(NAME, MNEMONIC, REG, CYCLES, AFFECTED) \
|
||||
#define DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(NAME, MNEMONIC, REG, FORMAT, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->op1.reg = (opcode >> 8) & 0x0007; \
|
||||
info->memory.baseReg = REG; \
|
||||
|
@ -161,40 +162,42 @@ DEFINE_DECODER_WITH_HIGH_THUMB(MOV3, MOV, ARM_OPERAND_AFFECTED_1, 0)
|
|||
ARM_OPERAND_AFFECTED_ ## AFFECTED | \
|
||||
ARM_OPERAND_MEMORY_2; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_IMMEDIATE_OFFSET; \
|
||||
CYCLES;)
|
||||
ARM_MEMORY_IMMEDIATE_OFFSET | \
|
||||
ARM_MEMORY_ ## FORMAT; \
|
||||
FORMAT ## _CYCLES;)
|
||||
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR3, LDR, ARM_PC, LOAD_CYCLES, 1)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR4, LDR, ARM_SP, LOAD_CYCLES, 1)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(STR3, STR, ARM_SP, STORE_CYCLES, 2)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR3, LDR, ARM_PC, LOAD, 1)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(LDR4, LDR, ARM_SP, LOAD, 1)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_MEM_THUMB(STR3, STR, ARM_SP, STORE, 2)
|
||||
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_DATA_THUMB(ADD5, ADD, ARM_PC)
|
||||
DEFINE_IMMEDIATE_WITH_REGISTER_DATA_THUMB(ADD6, ADD, ARM_SP)
|
||||
|
||||
#define DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(NAME, MNEMONIC, CYCLES, TYPE, AFFECTED) \
|
||||
#define DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(NAME, MNEMONIC, FORMAT, TYPE, AFFECTED) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->memory.offset.reg = (opcode >> 6) & 0x0007; \
|
||||
info->op1.reg = opcode & 0x0007; \
|
||||
info->memory.baseReg = (opcode >> 3) & 0x0007; \
|
||||
info->memory.width = TYPE; \
|
||||
info->memory.width = ARM_ACCESS_ ## TYPE; \
|
||||
info->operandFormat = ARM_OPERAND_REGISTER_1 | \
|
||||
ARM_OPERAND_AFFECTED_ ## AFFECTED | \
|
||||
ARM_OPERAND_MEMORY_2; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_REGISTER_OFFSET; \
|
||||
CYCLES;)
|
||||
ARM_MEMORY_REGISTER_OFFSET | \
|
||||
ARM_MEMORY_ ## FORMAT; \
|
||||
FORMAT ## _CYCLES;)
|
||||
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDR2, LDR, LOAD_CYCLES, ARM_ACCESS_WORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, LDR, LOAD_CYCLES, ARM_ACCESS_BYTE, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, LDR, LOAD_CYCLES, ARM_ACCESS_HALFWORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_BYTE, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, LDR, LOAD_CYCLES, ARM_ACCESS_SIGNED_HALFWORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, STR, STORE_CYCLES, ARM_ACCESS_WORD, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRB2, STR, STORE_CYCLES, ARM_ACCESS_BYTE, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE_CYCLES, ARM_ACCESS_HALFWORD, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDR2, LDR, LOAD, WORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRB2, LDR, LOAD, BYTE, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRH2, LDR, LOAD, HALFWORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSB, LDR, LOAD, SIGNED_BYTE, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(LDRSH, LDR, LOAD, SIGNED_HALFWORD, 1)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STR2, STR, STORE, WORD, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRB2, STR, STORE, BYTE, 2)
|
||||
DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE, HALFWORD, 2)
|
||||
|
||||
// TODO: Estimate memory cycles
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME, RN, MNEMONIC, DIRECTION, ADDITIONAL_REG) \
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME, RN, MNEMONIC, DIRECTION, FORMAT, ADDITIONAL_REG) \
|
||||
DEFINE_THUMB_DECODER(NAME, MNEMONIC, \
|
||||
info->memory.baseReg = RN; \
|
||||
info->op1.immediate = (opcode & 0xFF) | ADDITIONAL_REG; \
|
||||
|
@ -204,13 +207,14 @@ DEFINE_LOAD_STORE_WITH_REGISTER_THUMB(STRH2, STR, STORE_CYCLES, ARM_ACCESS_HALFW
|
|||
info->operandFormat = ARM_OPERAND_MEMORY_1 | ARM_OPERAND_AFFECTED_1; \
|
||||
info->memory.format = ARM_MEMORY_REGISTER_BASE | \
|
||||
ARM_MEMORY_WRITEBACK | \
|
||||
ARM_MEMORY_ ## FORMAT | \
|
||||
DIRECTION;)
|
||||
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_THUMB(NAME) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME ## IA, (opcode >> 8) & 0x0007, NAME, ARM_MEMORY_INCREMENT_AFTER, 0)
|
||||
#define DEFINE_LOAD_STORE_MULTIPLE_THUMB(NAME, FORMAT) \
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(NAME ## IA, (opcode >> 8) & 0x0007, NAME, ARM_MEMORY_INCREMENT_AFTER, FORMAT, 0)
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_THUMB(LDM)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_THUMB(STM)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_THUMB(LDM, LOAD)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_THUMB(STM, STORE)
|
||||
|
||||
#define DEFINE_CONDITIONAL_BRANCH_THUMB(COND) \
|
||||
DEFINE_THUMB_DECODER(B ## COND, B, \
|
||||
|
@ -246,11 +250,11 @@ DEFINE_CONDITIONAL_BRANCH_THUMB(LE)
|
|||
DEFINE_SP_MODIFY_THUMB(ADD7, ADD)
|
||||
DEFINE_SP_MODIFY_THUMB(SUB4, SUB)
|
||||
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POP, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, 0)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPR, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, 1 << ARM_PC)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPRv4, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, 1 << ARM_PC)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSH, ARM_SP, STM, ARM_MEMORY_DECREMENT_BEFORE, 0)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSHR, ARM_SP, STM, ARM_MEMORY_DECREMENT_BEFORE, 1 << ARM_LR)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POP, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, LOAD, 0)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPR, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, LOAD, 1 << ARM_PC)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(POPRv4, ARM_SP, LDM, ARM_MEMORY_INCREMENT_AFTER, LOAD, 1 << ARM_PC)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSH, ARM_SP, STM, ARM_MEMORY_DECREMENT_BEFORE, STORE, 0)
|
||||
DEFINE_LOAD_STORE_MULTIPLE_EX_THUMB(PUSHR, ARM_SP, STM, ARM_MEMORY_DECREMENT_BEFORE, STORE, 1 << ARM_LR)
|
||||
|
||||
DEFINE_THUMB_DECODER(ILL, ILL,
|
||||
info->operandFormat = ARM_OPERAND_NONE;
|
||||
|
|
|
@ -164,17 +164,20 @@ static int _decodeMemory(struct ARMMemoryAccess memory, struct ARMCore* cpu, con
|
|||
}
|
||||
int total = 0;
|
||||
bool elideClose = false;
|
||||
char comment[64];
|
||||
int written;
|
||||
comment[0] = '\0';
|
||||
if (memory.format & ARM_MEMORY_REGISTER_BASE) {
|
||||
if (memory.baseReg == ARM_PC && memory.format & ARM_MEMORY_IMMEDIATE_OFFSET) {
|
||||
uint32_t addrBase = memory.format & ARM_MEMORY_OFFSET_SUBTRACT ? -memory.offset.immediate : memory.offset.immediate;
|
||||
if (!cpu) {
|
||||
if (!cpu || memory.format & ARM_MEMORY_STORE) {
|
||||
strlcpy(buffer, "[", blen);
|
||||
ADVANCE(1);
|
||||
written = _decodePCRelative(addrBase, symbols, pc & 0xFFFFFFFC, false, buffer, blen);
|
||||
ADVANCE(written);
|
||||
} else {
|
||||
uint32_t value;
|
||||
_decodePCRelative(addrBase, symbols, pc & 0xFFFFFFFC, false, comment, sizeof(comment));
|
||||
addrBase += pc & 0xFFFFFFFC; // Thumb does not have PC-relative LDRH/LDRB
|
||||
switch (memory.width & 7) {
|
||||
case 1:
|
||||
|
@ -247,6 +250,10 @@ static int _decodeMemory(struct ARMMemoryAccess memory, struct ARMCore* cpu, con
|
|||
strlcpy(buffer, "!", blen);
|
||||
ADVANCE(1);
|
||||
}
|
||||
if (comment[0]) {
|
||||
written = snprintf(buffer, blen, " @ %s", comment);
|
||||
ADVANCE(written);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
|
|
|
@ -469,7 +469,7 @@ void GBReset(struct SM83Core* cpu) {
|
|||
GBVideoReset(&gb->video);
|
||||
GBTimerReset(&gb->timer);
|
||||
GBIOReset(gb);
|
||||
if (!gb->biosVf) {
|
||||
if (!gb->biosVf && gb->memory.rom) {
|
||||
GBSkipBIOS(gb);
|
||||
} else {
|
||||
mTimingSchedule(&gb->timing, &gb->timer.event, 0);
|
||||
|
|
|
@ -186,7 +186,7 @@ void FrameView::updateTilesGBA(bool) {
|
|||
{ LayerId::SPRITE, sprite },
|
||||
!m_disabled.contains({ LayerId::SPRITE, sprite }),
|
||||
QPixmap::fromImage(obj),
|
||||
{}, offset, false
|
||||
{}, offset, false, false
|
||||
});
|
||||
if (m_queue.back().image.hasAlpha()) {
|
||||
m_queue.back().mask = QRegion(m_queue.back().image.mask());
|
||||
|
@ -212,7 +212,7 @@ void FrameView::updateTilesGBA(bool) {
|
|||
{ LayerId::BACKGROUND, bg },
|
||||
!m_disabled.contains({ LayerId::BACKGROUND, bg }),
|
||||
QPixmap::fromImage(compositeMap(bg, m_mapStatus[bg])),
|
||||
{}, offset, true
|
||||
{}, offset, true, false
|
||||
});
|
||||
if (m_queue.back().image.hasAlpha()) {
|
||||
m_queue.back().mask = QRegion(m_queue.back().image.mask());
|
||||
|
@ -228,7 +228,7 @@ void FrameView::updateTilesGBA(bool) {
|
|||
{ LayerId::BACKDROP },
|
||||
!m_disabled.contains({ LayerId::BACKDROP }),
|
||||
QPixmap::fromImage(backdropImage),
|
||||
{}, {0, 0}, false
|
||||
{}, {0, 0}, false, true
|
||||
});
|
||||
updateRendered();
|
||||
}
|
||||
|
@ -237,7 +237,6 @@ void FrameView::updateTilesGBA(bool) {
|
|||
|
||||
void FrameView::injectGBA() {
|
||||
mVideoLogger* logger = m_vl->videoLogger;
|
||||
mVideoLoggerInjectionPoint(logger, LOGGER_INJECTION_FIRST_SCANLINE);
|
||||
GBA* gba = static_cast<GBA*>(m_vl->board);
|
||||
gba->video.renderer->highlightBG[0] = false;
|
||||
gba->video.renderer->highlightBG[1] = false;
|
||||
|
@ -276,11 +275,6 @@ void FrameView::injectGBA() {
|
|||
if (m_overrideBackdrop.isValid()) {
|
||||
mVideoLoggerInjectPalette(logger, 0, M_RGB8_TO_RGB5(m_overrideBackdrop.rgb()));
|
||||
}
|
||||
if (m_ui.disableScanline->checkState() == Qt::Checked) {
|
||||
mVideoLoggerIgnoreAfterInjection(logger, (1 << DIRTY_PALETTE) | (1 << DIRTY_OAM) | (1 << DIRTY_REGISTER));
|
||||
} else {
|
||||
mVideoLoggerIgnoreAfterInjection(logger, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -292,13 +286,49 @@ void FrameView::updateTilesGB(bool) {
|
|||
m_queue.clear();
|
||||
{
|
||||
CoreController::Interrupter interrupter(m_controller);
|
||||
for (int sprite = 0; sprite < 40; ++sprite) {
|
||||
ObjInfo info;
|
||||
lookupObj(sprite, &info);
|
||||
|
||||
if (!info.enabled) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QPointF offset(info.x, info.y);
|
||||
QImage obj(compositeObj(info));
|
||||
if (info.hflip || info.vflip) {
|
||||
obj = obj.mirrored(info.hflip, info.vflip);
|
||||
}
|
||||
m_queue.append({
|
||||
{ LayerId::SPRITE, sprite },
|
||||
!m_disabled.contains({ LayerId::SPRITE, sprite }),
|
||||
QPixmap::fromImage(obj),
|
||||
{}, offset, false, false
|
||||
});
|
||||
if (m_queue.back().image.hasAlpha()) {
|
||||
m_queue.back().mask = QRegion(m_queue.back().image.mask());
|
||||
} else {
|
||||
m_queue.back().mask = QRegion(0, 0, m_queue.back().image.width(), m_queue.back().image.height());
|
||||
}
|
||||
}
|
||||
|
||||
updateRendered();
|
||||
}
|
||||
invalidateQueue(m_controller->screenDimensions());
|
||||
}
|
||||
|
||||
void FrameView::injectGB() {
|
||||
mVideoLogger* logger = m_vl->videoLogger;
|
||||
|
||||
m_vl->reset(m_vl);
|
||||
for (const Layer& layer : m_queue) {
|
||||
switch (layer.id.type) {
|
||||
case LayerId::SPRITE:
|
||||
if (!layer.enabled) {
|
||||
mVideoLoggerInjectOAM(logger, layer.id.index << 2, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -310,6 +340,8 @@ void FrameView::invalidateQueue(const QSize& dims) {
|
|||
bool blockSignals = m_ui.queue->blockSignals(true);
|
||||
QMutexLocker locker(&m_mutex);
|
||||
if (m_vl) {
|
||||
mVideoLogger* logger = m_vl->videoLogger;
|
||||
mVideoLoggerInjectionPoint(logger, LOGGER_INJECTION_FIRST_SCANLINE);
|
||||
switch (m_controller->platform()) {
|
||||
#ifdef M_CORE_GBA
|
||||
case PLATFORM_GBA:
|
||||
|
@ -322,6 +354,11 @@ void FrameView::invalidateQueue(const QSize& dims) {
|
|||
break;
|
||||
#endif
|
||||
}
|
||||
if (m_ui.disableScanline->checkState() == Qt::Checked) {
|
||||
mVideoLoggerIgnoreAfterInjection(logger, (1 << DIRTY_PALETTE) | (1 << DIRTY_OAM) | (1 << DIRTY_REGISTER));
|
||||
} else {
|
||||
mVideoLoggerIgnoreAfterInjection(logger, 0);
|
||||
}
|
||||
m_vl->runFrame(m_vl);
|
||||
}
|
||||
|
||||
|
@ -335,7 +372,7 @@ void FrameView::invalidateQueue(const QSize& dims) {
|
|||
item = m_ui.queue->item(i);
|
||||
}
|
||||
item->setText(layer.id.readable());
|
||||
item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
|
||||
item->setFlags(Qt::ItemIsSelectable | (layer.fixed ? Qt::NoItemFlags : Qt::ItemIsUserCheckable) | Qt::ItemIsEnabled);
|
||||
item->setCheckState(layer.enabled ? Qt::Checked : Qt::Unchecked);
|
||||
item->setData(Qt::UserRole, i);
|
||||
item->setSelected(layer.id == m_active);
|
||||
|
@ -351,8 +388,12 @@ void FrameView::invalidateQueue(const QSize& dims) {
|
|||
updateRendered();
|
||||
composited = m_rendered;
|
||||
} else {
|
||||
QImage framebuffer(m_framebuffer);
|
||||
m_ui.exportButton->setEnabled(true);
|
||||
composited.convertFromImage(m_framebuffer);
|
||||
if (framebuffer.size() != m_dims) {
|
||||
framebuffer = framebuffer.copy({QPoint(), m_dims});
|
||||
}
|
||||
composited.convertFromImage(framebuffer);
|
||||
}
|
||||
m_composited = composited.scaled(m_dims * m_ui.magnification->value());
|
||||
m_ui.compositedView->setPixmap(m_composited);
|
||||
|
@ -461,6 +502,9 @@ QString FrameView::LayerId::readable() const {
|
|||
case BACKDROP:
|
||||
typeStr = tr("Backdrop");
|
||||
break;
|
||||
case FRAME:
|
||||
typeStr = tr("Frame");
|
||||
break;
|
||||
}
|
||||
if (index < 0) {
|
||||
return typeStr;
|
||||
|
|
|
@ -66,7 +66,8 @@ private:
|
|||
BACKGROUND,
|
||||
WINDOW,
|
||||
SPRITE,
|
||||
BACKDROP
|
||||
BACKDROP,
|
||||
FRAME
|
||||
} type = NONE;
|
||||
int index = -1;
|
||||
|
||||
|
@ -82,6 +83,7 @@ private:
|
|||
QRegion mask;
|
||||
QPointF location;
|
||||
bool repeats;
|
||||
bool fixed;
|
||||
};
|
||||
|
||||
bool lookupLayer(const QPointF& coord, Layer*&);
|
||||
|
@ -117,4 +119,4 @@ private:
|
|||
std::shared_ptr<bool> m_callbackLocker{std::make_shared<bool>(true)};
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue