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:
42
src/cpu.c
42
src/cpu.c
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user