SDS: Add more complex (but optional) Next behavior

Allow -f switch with Next to move forward in code.
Allow -a switch with Next for "atomic" behavior that excludes interrupts for all instructions.

Update sds_doc.doc to describe the new behavior.
This commit is contained in:
Mark Emmer 2014-04-19 14:50:15 -05:00
parent 3946eb710e
commit 6f9f387c39
2 changed files with 94 additions and 13 deletions

View file

@ -1509,25 +1509,106 @@ return SCPE_OK;
TRUE if so with a list of addresses where dynamic (temporary) TRUE if so with a list of addresses where dynamic (temporary)
breakpoints should be set. breakpoints should be set.
*/ */
typedef enum Next_Case { /* Next Next Atomic Next Forward */
Next_BadOp = 0, /* FALSE FALSE FALSE */
Next_Branch, /* FALSE EA FALSE */
Next_BRM, /* P+1,P+2,P+3 EA,P+1,P+2,P+3 P+1,P+2,P+3 */
Next_BRX, /* FALSE EA,P+1 P+1 */
Next_Simple, /* FALSE P+1 P+1 */
Next_POP, /* P+1,P+2 100+OP,P+1,P+2 P+1,P+2 */
Next_Skip, /* P+1,P+2 P+1,P+2 P+1,P+2 */
Next_EXU /* ?? ?? ?? */
} Next_Case;
Next_Case Op_Cases[64] = {
Next_BadOp, Next_Branch, Next_Simple, Next_BadOp, /* HLT BRU EOM ... */
Next_BadOp, Next_BadOp, Next_Simple, Next_BadOp, /* ... ... EOD ... */
Next_Simple, Next_Branch, Next_Simple, Next_Simple, /* MIY BRI MIW POT */
Next_Simple, Next_BadOp, Next_Simple, Next_Simple, /* ETR ... MRG EOR */
Next_Simple, Next_BadOp, Next_Simple, Next_EXU, /* NOP ... ROV EXU */
Next_BadOp, Next_BadOp, Next_BadOp, Next_BadOp, /* ... ... ... ... */
Next_Simple, Next_BadOp, Next_Simple, Next_Simple, /* YIM ... WIM PIN */
Next_BadOp, Next_Simple, Next_Simple, Next_Simple, /* ... STA STB STX */
Next_Skip, Next_BRX, Next_BadOp, Next_BRM, /* SKS BRX ... BRM */
Next_BadOp, Next_BadOp, Next_Simple, Next_BadOp, /* ... ... RCH ... */
Next_Skip, Next_Branch, Next_Skip, Next_Skip, /* SKE BRR SKB SKN */
Next_Simple, Next_Simple, Next_Simple, Next_Simple, /* SUB ADD SUC ADC */
Next_Skip, Next_Simple, Next_Simple, Next_Simple, /* SKR MIN XMA ADM */
Next_Simple, Next_Simple, Next_Simple, Next_Simple, /* MUL DIV RSH LSH */
Next_Skip, Next_Simple, Next_Skip, Next_Skip, /* SKM LDX SKA SKG */
Next_Skip, Next_Simple, Next_Simple, Next_Simple }; /* SKD LDB LDA EAX */
t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs) t_bool cpu_is_pc_a_subroutine_call (t_addr **ret_addrs)
{ {
static t_addr returns[3] = {0, 0, 0}; static t_addr returns[10];
t_stat reason;
uint32 inst; uint32 inst;
Next_Case op_case;
int32 atomic, forward;
t_addr *return_p;
uint32 va;
int32 exu_cnt = 0;
reason = Read (P, &inst); /* get instr */ *ret_addrs = return_p = returns;
if ((reason == SCPE_OK) && atomic = sim_switches & SWMASK('A');
((I_GETOP(inst) == BRM) || /* if BRM or */ forward = sim_switches & SWMASK('F');
(I_POP & inst) || /* POP or SYSPOP or */
(sim_switches & SWMASK('F')))) { /* Force switch */ if (Read (P, &inst) != SCPE_OK) /* get instruction */
returns[0] = (P + 1) & VA_MASK;
returns[1] = (P + 2) & VA_MASK;
*ret_addrs = returns;
return TRUE;
}
else
return FALSE; return FALSE;
Exu_Loop:
if (I_POP & inst) /* determine inst case */
op_case = Next_POP;
else
op_case = Op_Cases[I_GETOP(inst)];
switch (op_case) {
case Next_BadOp:
break;
case Next_BRM:
*return_p++ = (P + 1) & VA_MASK;
*return_p++ = (P + 2) & VA_MASK;
*return_p++ = (P + 3) & VA_MASK;
/* -- fall through to Next_Branch case -- */
case Next_Branch:
if (atomic) {
if (Ea (inst, &va) != SCPE_OK)
return FALSE;
*return_p++ = va & VA_MASK;
}
break;
case Next_BRX:
if (atomic) {
if (Ea (inst, &va) != SCPE_OK)
return FALSE;
*return_p++ = va & VA_MASK;
}
/* -- fall through to Next_Simple case -- */
case Next_Simple:
if (atomic || forward)
*return_p++ = (P + 1) & VA_MASK;
break;
case Next_POP:
if (atomic)
*return_p++ = 0100 + I_GETOP(inst);
/* -- fall through to Next_Skip case -- */
case Next_Skip:
*return_p++ = (P + 1) & VA_MASK;
*return_p++ = (P + 2) & VA_MASK;
break;
case Next_EXU: /* execute inst at EA */
if (++exu_cnt > exu_lim) /* too many? */
return FALSE;
if (Ea (inst, &va) != SCPE_OK) /* decode eff addr */
return FALSE;
if (Read (va, &inst) != SCPE_OK) /* get operand */
return FALSE;
goto Exu_Loop;
}
if (return_p == returns) /* if no cases added, */
return FALSE; /* return FALSE */
else
*return_p = (t_addr)0; /* else append terminator */
return TRUE; /* and return TRUE */
} }
/* Memory examine */ /* Memory examine */

Binary file not shown.