PDP11: Added support for the NEXT command to step over subroutine calls.

This commit is contained in:
Mark Pizzolato 2014-04-17 13:07:37 -07:00
parent 7fc8922a48
commit e7a934904c

View file

@ -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_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_dep (t_value val, t_addr addr, UNIT *uptr, int32 sw);
t_stat cpu_reset (DEVICE *dptr); 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_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_hist (FILE *st, UNIT *uptr, int32 val, void *desc);
t_stat cpu_show_virt (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; pcq_r->qptr = 0;
else return SCPE_IERR; else return SCPE_IERR;
sim_brk_types = sim_brk_dflt = SWMASK ('E'); 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); set_r_display (0, MD_KER);
return SCPE_OK; 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<max_returns; i++)
returns[i] = returns[i-1] + 2; /* Possible skip return */
returns[i] = 0; /* Make sure the address list ends with a zero */
*ret_addrs = returns;
return TRUE;
}
return FALSE;
}
/* Boot setup routine */ /* Boot setup routine */
void cpu_set_boot (int32 pc) void cpu_set_boot (int32 pc)