mirror of
https://github.com/rkujawa/rk65c02.git
synced 2024-06-15 05:29:28 +00:00
Avoid getting instruction definition again when emulating.
While here try to make program counter incrementation more universal and flexible.
This commit is contained in:
parent
c7633feb87
commit
e763ca0d3a
|
@ -14,7 +14,7 @@ BEGIN {
|
||||||
|
|
||||||
END {
|
END {
|
||||||
for (i in emuls)
|
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_ */"
|
print "#endif /* _EMULATION_H_ */"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,14 +4,11 @@
|
||||||
|
|
||||||
/* AND - logical AND */
|
/* AND - logical AND */
|
||||||
void
|
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;
|
uint8_t rv;
|
||||||
|
|
||||||
id = instruction_decode(i->opcode);
|
rv = e->regs.A & (instruction_data_read_1(e, (instrdef_t *) id, i));
|
||||||
|
|
||||||
rv = e->regs.A & (instruction_data_read_1(e, &id, i));
|
|
||||||
e->regs.A = rv;
|
e->regs.A = rv;
|
||||||
|
|
||||||
instruction_status_adjust_zero(e, e->regs.A);
|
instruction_status_adjust_zero(e, e->regs.A);
|
||||||
|
@ -20,13 +17,9 @@ emul_and(rk65c02emu_t *e, instruction_t *i)
|
||||||
|
|
||||||
/* LDA - load to accumulator */
|
/* LDA - load to accumulator */
|
||||||
void
|
void
|
||||||
emul_lda(rk65c02emu_t *e, instruction_t *i)
|
emul_lda(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||||
{
|
{
|
||||||
instrdef_t id;
|
e->regs.A = instruction_data_read_1(e, (instrdef_t *) id, i);
|
||||||
|
|
||||||
id = instruction_decode(i->opcode);
|
|
||||||
|
|
||||||
e->regs.A = instruction_data_read_1(e, &id, i);
|
|
||||||
|
|
||||||
instruction_status_adjust_zero(e, e->regs.A);
|
instruction_status_adjust_zero(e, e->regs.A);
|
||||||
instruction_status_adjust_negative(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 */
|
/* NOP - do nothing */
|
||||||
void
|
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 */
|
/* PHA - push accumulator to stack */
|
||||||
void
|
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);
|
stack_push(e, e->regs.A);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PLA - pull from stack to accumulator */
|
/* PLA - pull from stack to accumulator */
|
||||||
void
|
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);
|
e->regs.A = stack_pop(e);
|
||||||
|
|
||||||
|
@ -58,19 +50,15 @@ emul_pla(rk65c02emu_t *e, instruction_t *i)
|
||||||
|
|
||||||
/* STP - stop the processor */
|
/* STP - stop the processor */
|
||||||
void
|
void
|
||||||
emul_stp(rk65c02emu_t *e, instruction_t *i)
|
emul_stp(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||||
{
|
{
|
||||||
e->state = STOPPED;
|
e->state = STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STZ - store zero */
|
/* STZ - store zero */
|
||||||
void
|
void
|
||||||
emul_stz(rk65c02emu_t *e, instruction_t *i)
|
emul_stz(rk65c02emu_t *e, void *id, instruction_t *i)
|
||||||
{
|
{
|
||||||
instrdef_t id;
|
instruction_data_write_1(e, id, i, 0);
|
||||||
|
|
||||||
id = instruction_decode(i->opcode);
|
|
||||||
|
|
||||||
instruction_data_write_1(e, &id, i, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -278,3 +278,10 @@ stack_pop(rk65c02emu_t *e)
|
||||||
return val;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ struct instrdef {
|
||||||
const char *mnemonic;
|
const char *mnemonic;
|
||||||
addressing_t mode;
|
addressing_t mode;
|
||||||
uint8_t size;
|
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;
|
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 instruction_status_adjust_negative(rk65c02emu_t *, uint8_t);
|
||||||
void stack_push(rk65c02emu_t *, uint8_t);
|
void stack_push(rk65c02emu_t *, uint8_t);
|
||||||
uint8_t stack_pop(rk65c02emu_t *);
|
uint8_t stack_pop(rk65c02emu_t *);
|
||||||
|
void program_counter_increment(rk65c02emu_t *, instrdef_t *);
|
||||||
|
|
||||||
#endif /* _INSTRUCTION_H_ */
|
#endif /* _INSTRUCTION_H_ */
|
||||||
|
|
|
@ -32,16 +32,15 @@ rk65c02_start(rk65c02emu_t *e) {
|
||||||
i = instruction_fetch(e->bus, e->regs.PC);
|
i = instruction_fetch(e->bus, e->regs.PC);
|
||||||
id = instruction_decode(i.opcode);
|
id = instruction_decode(i.opcode);
|
||||||
|
|
||||||
if (id.emul != NULL)
|
if (id.emul != NULL) {
|
||||||
id.emul(e, &i);
|
id.emul(e, &id, &i);
|
||||||
else {
|
/* if (!instruction_modify_pc) */
|
||||||
|
program_counter_increment(e, &id);
|
||||||
|
} else {
|
||||||
printf("unimplemented opcode %X @ %X\n", i.opcode,
|
printf("unimplemented opcode %X @ %X\n", i.opcode,
|
||||||
e->regs.PC);
|
e->regs.PC);
|
||||||
e->state = STOPPED;
|
e->state = STOPPED;
|
||||||
}
|
}
|
||||||
|
|
||||||
e->regs.PC += id.size;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue
Block a user