Avoid getting instruction definition again when emulating.

While here try to make program counter incrementation more universal
and flexible.
This commit is contained in:
Radosław Kujawa 2017-01-22 11:07:19 +01:00
parent c7633feb87
commit e763ca0d3a
5 changed files with 25 additions and 30 deletions

View File

@ -14,7 +14,7 @@ BEGIN {
END {
for (i in emuls)
printf "void %s(rk65c02emu_t *, instruction_t *);\n",i
printf "void %s(rk65c02emu_t *, void *id, instruction_t *);\n",i
print "#endif /* _EMULATION_H_ */"
}

View File

@ -4,14 +4,11 @@
/* AND - logical AND */
void
emul_and(rk65c02emu_t *e, instruction_t *i)
emul_and(rk65c02emu_t *e, void *id, instruction_t *i)
{
instrdef_t id;
uint8_t rv;
id = instruction_decode(i->opcode);
rv = e->regs.A & (instruction_data_read_1(e, &id, i));
rv = e->regs.A & (instruction_data_read_1(e, (instrdef_t *) id, i));
e->regs.A = rv;
instruction_status_adjust_zero(e, e->regs.A);
@ -20,13 +17,9 @@ emul_and(rk65c02emu_t *e, instruction_t *i)
/* LDA - load to accumulator */
void
emul_lda(rk65c02emu_t *e, instruction_t *i)
emul_lda(rk65c02emu_t *e, void *id, instruction_t *i)
{
instrdef_t id;
id = instruction_decode(i->opcode);
e->regs.A = instruction_data_read_1(e, &id, i);
e->regs.A = instruction_data_read_1(e, (instrdef_t *) id, i);
instruction_status_adjust_zero(e, e->regs.A);
instruction_status_adjust_negative(e, e->regs.A);
@ -34,21 +27,20 @@ emul_lda(rk65c02emu_t *e, instruction_t *i)
/* NOP - do nothing */
void
emul_nop(rk65c02emu_t *e, instruction_t *i)
emul_nop(rk65c02emu_t *e, void *id, instruction_t *i)
{
/* printf("nop!\n"); */
}
/* PHA - push accumulator to stack */
void
emul_pha(rk65c02emu_t *e, instruction_t *i)
emul_pha(rk65c02emu_t *e, void *id, instruction_t *i)
{
stack_push(e, e->regs.A);
}
/* PLA - pull from stack to accumulator */
void
emul_pla(rk65c02emu_t *e, instruction_t *i)
emul_pla(rk65c02emu_t *e, void *id, instruction_t *i)
{
e->regs.A = stack_pop(e);
@ -58,19 +50,15 @@ emul_pla(rk65c02emu_t *e, instruction_t *i)
/* STP - stop the processor */
void
emul_stp(rk65c02emu_t *e, instruction_t *i)
emul_stp(rk65c02emu_t *e, void *id, instruction_t *i)
{
e->state = STOPPED;
}
/* STZ - store zero */
void
emul_stz(rk65c02emu_t *e, instruction_t *i)
emul_stz(rk65c02emu_t *e, void *id, instruction_t *i)
{
instrdef_t id;
id = instruction_decode(i->opcode);
instruction_data_write_1(e, &id, i, 0);
instruction_data_write_1(e, id, i, 0);
}

View File

@ -278,3 +278,10 @@ stack_pop(rk65c02emu_t *e)
return val;
}
/* increment program counter based on instruction size (opcode + operands) */
void
program_counter_increment(rk65c02emu_t *e, instrdef_t *id)
{
e->regs.PC += id->size;
}

View File

@ -34,7 +34,7 @@ struct instrdef {
const char *mnemonic;
addressing_t mode;
uint8_t size;
void (*emul)(rk65c02emu_t *e, instruction_t *i);
void (*emul)(rk65c02emu_t *e, void *id, instruction_t *i);
};
typedef struct instrdef instrdef_t;
@ -49,5 +49,6 @@ void instruction_status_adjust_zero(rk65c02emu_t *, uint8_t);
void instruction_status_adjust_negative(rk65c02emu_t *, uint8_t);
void stack_push(rk65c02emu_t *, uint8_t);
uint8_t stack_pop(rk65c02emu_t *);
void program_counter_increment(rk65c02emu_t *, instrdef_t *);
#endif /* _INSTRUCTION_H_ */

View File

@ -32,16 +32,15 @@ rk65c02_start(rk65c02emu_t *e) {
i = instruction_fetch(e->bus, e->regs.PC);
id = instruction_decode(i.opcode);
if (id.emul != NULL)
id.emul(e, &i);
else {
if (id.emul != NULL) {
id.emul(e, &id, &i);
/* if (!instruction_modify_pc) */
program_counter_increment(e, &id);
} else {
printf("unimplemented opcode %X @ %X\n", i.opcode,
e->regs.PC);
e->state = STOPPED;
}
e->regs.PC += id.size;
}
}
/*