cpu: fix up register accesses

The HL dereference operations cause problems indexing into the
registers array, because it causes a hole in the array that only
exists in the 8-bit register space.

Instead of accessing the registers directly by the same indices used
in in the assembly instructions, create a lookup table to map between
them.

Signed-off-by: Max Regan <mgregan2@gmail.com>
This commit is contained in:
2017-04-07 16:19:42 -07:00
parent 0268f13080
commit 5bbc6097b5
2 changed files with 37 additions and 13 deletions

View File

@@ -382,30 +382,52 @@ static lr35902_instr lr35902_cb_instrs[] = {
/*0xF?*/ set, set,
};
static int cpu_reg16_to_idx[NUM_LR35902_REGS_16] = {
[LR35902_REG_BC] = 0,
[LR35902_REG_DE] = 1,
[LR35902_REG_HL] = 2,
[LR35902_REG_AF] = 3,
[LR35902_REG_PC] = 4,
[LR35902_REG_SP] = 5,
};
uint16_t lr35902_get_reg_16(struct lr35902_state *cpu, lr35902_regs_16 reg)
{
ASSERT(reg >= 0);
ASSERT_MSG(reg < NUM_LR35902_REGS_16, "reg=%d\n", reg);
return cpu->regs_16[reg];
ASSERT_MSG(reg >= 0 && reg < NUM_LR35902_REGS_16, "reg=%d\n", reg);
return cpu->regs_16[cpu_reg16_to_idx[reg]];
}
static int cpu_reg8_to_idx[NUM_LR35902_REGS_8] = {
[LR35902_REG_A] = 6,
[LR35902_REG_B] = 0,
[LR35902_REG_C] = 1,
[LR35902_REG_D] = 2,
[LR35902_REG_E] = 3,
[LR35902_REG_H] = 4,
[LR35902_REG_L] = 5,
[LR35902_REG_F] = 7,
[LR35902_REG_HL_DEREF] = -1,
};
uint8_t lr35902_get_reg_8(struct lr35902_state *cpu, lr35902_regs_8 reg)
{
ASSERT(reg < NUM_LR35902_REGS_8);
ASSERT(reg != LR35902_REG_HL_DEREF);
return cpu->regs_8[reg];
return cpu->regs_8[cpu_reg8_to_idx[reg]];
}
void lr35902_set_reg_16(struct lr35902_state *cpu, lr35902_regs_16 reg,
uint16_t val)
{
cpu->regs_16[reg] = val;
ASSERT(reg < NUM_LR35902_REGS_16 && reg >= 0);
cpu->regs_16[cpu_reg16_to_idx[reg]] = val;
}
void lr35902_set_reg_8(struct lr35902_state *cpu, lr35902_regs_8 reg,
uint8_t val)
{
ASSERT(reg < NUM_LR35902_REGS_8);
cpu->regs_8[reg] = val;
ASSERT(reg < NUM_LR35902_REGS_8 && reg >= 0);
cpu->regs_8[cpu_reg8_to_idx[reg]] = val;
}
@@ -534,15 +556,17 @@ static uint8_t _get_reg_8(struct lr35902_state *cpu, uint8_t reg){
if (reg == LR35902_REG_HL_DEREF){
return cpu->mem_read(cpu, lr35902_get_reg_16(cpu, LR35902_REG_HL));
} else {
return cpu->regs_8[reg];
return cpu->regs_8[cpu_reg8_to_idx[reg]];
}
}
static void _set_reg_8(struct lr35902_state *cpu, uint8_t reg, uint8_t val){
ASSERT(reg < NUM_LR35902_REGS_8 && reg >= 0);
if (reg == LR35902_REG_HL_DEREF){
cpu->mem_write(cpu, lr35902_get_reg_16(cpu, LR35902_REG_HL), val);
} else {
cpu->regs_8[reg] = val;
cpu->regs_8[cpu_reg8_to_idx[reg]] = val;
}
}