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,
|
/*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)
|
uint16_t lr35902_get_reg_16(struct lr35902_state *cpu, lr35902_regs_16 reg)
|
||||||
{
|
{
|
||||||
ASSERT(reg >= 0);
|
ASSERT_MSG(reg >= 0 && reg < NUM_LR35902_REGS_16, "reg=%d\n", reg);
|
||||||
ASSERT_MSG(reg < NUM_LR35902_REGS_16, "reg=%d\n", reg);
|
return cpu->regs_16[cpu_reg16_to_idx[reg]];
|
||||||
return cpu->regs_16[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)
|
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);
|
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,
|
void lr35902_set_reg_16(struct lr35902_state *cpu, lr35902_regs_16 reg,
|
||||||
uint16_t val)
|
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,
|
void lr35902_set_reg_8(struct lr35902_state *cpu, lr35902_regs_8 reg,
|
||||||
uint8_t val)
|
uint8_t val)
|
||||||
{
|
{
|
||||||
ASSERT(reg < NUM_LR35902_REGS_8);
|
ASSERT(reg < NUM_LR35902_REGS_8 && reg >= 0);
|
||||||
cpu->regs_8[reg] = val;
|
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){
|
if (reg == LR35902_REG_HL_DEREF){
|
||||||
return cpu->mem_read(cpu, lr35902_get_reg_16(cpu, LR35902_REG_HL));
|
return cpu->mem_read(cpu, lr35902_get_reg_16(cpu, LR35902_REG_HL));
|
||||||
} else {
|
} 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){
|
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){
|
if (reg == LR35902_REG_HL_DEREF){
|
||||||
cpu->mem_write(cpu, lr35902_get_reg_16(cpu, LR35902_REG_HL), val);
|
cpu->mem_write(cpu, lr35902_get_reg_16(cpu, LR35902_REG_HL), val);
|
||||||
} else {
|
} else {
|
||||||
cpu->regs_8[reg] = val;
|
cpu->regs_8[cpu_reg8_to_idx[reg]] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@
|
|||||||
#define LR35902_MAX_EVENTS 16
|
#define LR35902_MAX_EVENTS 16
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LR35902_REG_AF= 0,
|
LR35902_REG_BC = 0,
|
||||||
LR35902_REG_BC,
|
LR35902_REG_DE = 1,
|
||||||
LR35902_REG_DE,
|
LR35902_REG_HL = 2,
|
||||||
LR35902_REG_HL,
|
LR35902_REG_AF = 3,
|
||||||
LR35902_REG_SP,
|
LR35902_REG_SP,
|
||||||
LR35902_REG_PC,
|
LR35902_REG_PC,
|
||||||
NUM_LR35902_REGS_16
|
NUM_LR35902_REGS_16
|
||||||
|
|||||||
Reference in New Issue
Block a user