From e7a934904c144c8b26f24a4c08d9ef15731b2830 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Thu, 17 Apr 2014 13:07:37 -0700 Subject: [PATCH] PDP11: Added support for the NEXT command to step over subroutine calls. --- PDP11/pdp11_cpu.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/PDP11/pdp11_cpu.c b/PDP11/pdp11_cpu.c index b0e6ae4e..e759aed2 100644 --- a/PDP11/pdp11_cpu.c +++ b/PDP11/pdp11_cpu.c @@ -312,6 +312,7 @@ extern CPUTAB cpu_tab[]; t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw); t_stat cpu_reset (DEVICE *dptr); +t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs); t_stat cpu_set_hist (UNIT *uptr, int32 val, char *cptr, void *desc); t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, void *desc); t_stat cpu_show_virt (FILE *st, UNIT *uptr, int32 val, void *desc); @@ -3019,10 +3020,43 @@ if (pcq_r) pcq_r->qptr = 0; else return SCPE_IERR; sim_brk_types = sim_brk_dflt = SWMASK ('E'); +sim_vm_is_subroutine_call = &cpu_is_pc_a_subroutine_call; set_r_display (0, MD_KER); return SCPE_OK; } +t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs) +{ +#define MAX_SUB_RETURN_SKIP 10 +static t_addr returns[MAX_SUB_RETURN_SKIP + 1] = {0}; + +if (SCPE_OK != get_aval (PC, &cpu_dev, &cpu_unit)) /* get data */ + return FALSE; +if ((sim_eval[0] & 0177000) == 0004000) { /* JSR */ + int32 dst, dstspec; + t_addr i, max_returns = MAX_SUB_RETURN_SKIP; + int32 save_Regs[8]; + + memcpy (save_Regs, R, sizeof(R)); /* save register state */ + PC = PC + 2; /* account for instruction fetch */ + dstspec = sim_eval[0] & 077; + dst = GeteaW (dstspec); + if (CPUT (CPUT_05|CPUT_20) && /* 11/05, 11/20 */ + ((dstspec & 070) == 020)) /* JSR (R)+? */ + dst = R[dstspec & 07]; /* use post incr */ + memcpy (R, save_Regs, sizeof(R)); /* restore register state */ + returns[0] = PC + (1 - fprint_sym (stdnul, PC, sim_eval, &cpu_unit, SWMASK ('M'))); + if (((t_addr)dst > returns[0]) && ((dst - returns[0]) < max_returns*2)) + max_returns = (dst - returns[0])/2; + for (i=1; i