diff --git a/src/sim.c b/src/sim.c index 6439c0a9..0a5421a3 100644 --- a/src/sim.c +++ b/src/sim.c @@ -114,6 +114,12 @@ int run_instruction(struct sim_state *s, const struct element *i, void *run_data g->dd == 1 || g->dd == 2, g->dd == 1); } +static int updates_P(const struct insn_or_data i) +{ + struct instruction_typeany t = i.u.typeany; + return (t.z == 15) && (t.dd == 0 || t.dd == 3); +} + int interp_step_sim(struct sim_state *s, const struct run_ops *ops, void **run_data, void *ops_data) { @@ -137,10 +143,25 @@ int interp_step_sim(struct sim_state *s, const struct run_ops *ops, if (ops->post_insn(s, &i, ops_data)) return 0; + // return 2 means "successful step, updated P register" // return 1 means "successful step, can continue as-is" // return 0 means "stopped because a hook told us to stop" // return -1 means "stopped because some error occurred" - return 1; + // TODO use an enumeration + return updates_P(i.insn) ? 2 : 1; +} + +int interp_run_sim_block(struct sim_state *s, const struct run_ops *ops, + void **run_data, void *ops_data) +{ + int rc = 0; + + *run_data = NULL; // this runner needs no data yet + do { + rc = interp_step_sim(s, ops, run_data, ops_data); + } while (rc > 0 && rc != 2); + + return rc; } int interp_run_sim(struct sim_state *s, const struct run_ops *ops, diff --git a/src/sim.h b/src/sim.h index 39ef2819..0c3123bb 100644 --- a/src/sim.h +++ b/src/sim.h @@ -63,7 +63,7 @@ struct run_ops { }; typedef int sim_runner(struct sim_state *s, const struct run_ops *ops, void **run_data, void *ops_data); -extern sim_runner interp_run_sim, interp_step_sim; +extern sim_runner interp_run_sim, interp_step_sim, interp_run_sim_block; int load_sim(op_dispatcher *dispatch_op, void *sud, const struct format *f, void *fud, FILE *in, int load_address);