SDS: Clean up CPU modes and record CPU mode in instruction history record

The three CPU modes -- normal, monitor and user were represented by two binary flags (nml_mode and usr_mode). The code is simpler and easier to read if the three modes are represented by one three-valued variable, cpu_mode. In addition, record the CPU mode in the instruction history record, and add the mode to the history display.

In addition, add an optional flag to the SET CPU HISTORY=n command to *not* record instructions executed in a particular CPU mode.  Flags are -n, -m and -u for normal, monitor and user mode respectively.  For example, SET -m CPU HISTORY=n will only record instructions executed in normal or user mode, and will not record instructions executed in monitor mode. This change aids user-mode program debugging by not filling the history with monitor-mode service functions and interrupt activity.
This commit is contained in:
Mark Emmer 2014-04-09 22:11:55 -05:00
parent be18514beb
commit bf06cb4f87
3 changed files with 88 additions and 70 deletions

View file

@ -39,8 +39,9 @@
X<0:23> X (index) register X<0:23> X (index) register
OV overflow indicator OV overflow indicator
P<0:13> program counter P<0:13> program counter
nml_mode compatible (1) vs 940 (0) mode cpu_mode SDS 930 normal (compatible) mode (0)
usr_mode user (1) vs monitor (0) mode SDS 940 monitor mode (1)
SDS 940 user mode (2)
RL1<0:23> user map low RL1<0:23> user map low
RL2<0:23> user map high RL2<0:23> user map high
RL4<12:23> monitor map high RL4<12:23> monitor map high
@ -168,8 +169,7 @@ uint32 int_reqhi = 0; /* highest int request *
uint32 api_lvl = 0; /* api active */ uint32 api_lvl = 0; /* api active */
uint32 api_lvlhi = 0; /* highest api active */ uint32 api_lvlhi = 0; /* highest api active */
t_bool chan_req; /* chan request */ t_bool chan_req; /* chan request */
uint32 nml_mode = 1; /* normal mode */ uint32 cpu_mode = NML_MODE; /* normal mode */
uint32 usr_mode = 0; /* user mode */
uint32 mon_usr_trap = 0; /* mon-user trap */ uint32 mon_usr_trap = 0; /* mon-user trap */
uint32 EM2 = 2, EM3 = 3; /* extension registers */ uint32 EM2 = 2, EM3 = 3; /* extension registers */
uint32 RL1, RL2, RL4; /* relocation maps */ uint32 RL1, RL2, RL4; /* relocation maps */
@ -190,6 +190,7 @@ int32 pcq_p = 0; /* PC queue ptr */
REG *pcq_r = NULL; /* PC queue reg ptr */ REG *pcq_r = NULL; /* PC queue reg ptr */
int32 hst_p = 0; /* history pointer */ int32 hst_p = 0; /* history pointer */
int32 hst_lnt = 0; /* history length */ int32 hst_lnt = 0; /* history length */
uint32 hst_exclude = BAD_MODE; /* cpu_mode excluded from history */
InstHistory *hst = NULL; /* instruction history */ InstHistory *hst = NULL; /* instruction history */
int32 rtc_pie = 0; /* rtc pulse ie */ int32 rtc_pie = 0; /* rtc pulse ie */
int32 rtc_tps = 60; /* rtc ticks/sec */ int32 rtc_tps = 60; /* rtc ticks/sec */
@ -251,8 +252,7 @@ REG cpu_reg[] = {
{ ORDATA (RL1, RL1, 24) }, { ORDATA (RL1, RL1, 24) },
{ ORDATA (RL2, RL2, 24) }, { ORDATA (RL2, RL2, 24) },
{ ORDATA (RL4, RL4, 12) }, { ORDATA (RL4, RL4, 12) },
{ FLDATA (NML, nml_mode, 0) }, { ORDATA (MODE, cpu_mode, 2) },
{ FLDATA (USR, usr_mode, 0) },
{ FLDATA (MONUSR, mon_usr_trap, 0) }, { FLDATA (MONUSR, mon_usr_trap, 0) },
{ FLDATA (ION, ion, 0) }, { FLDATA (ION, ion, 0) },
{ FLDATA (INTDEF, ion_defer, 0) }, { FLDATA (INTDEF, ion_defer, 0) },
@ -402,14 +402,14 @@ while (reason == 0) { /* loop until halted */
break; break;
} }
tinst = ReadP (pa); /* get inst */ tinst = ReadP (pa); /* get inst */
save_mode = usr_mode; /* save mode */ save_mode = cpu_mode; /* save mode */
usr_mode = 0; /* switch to mon */ cpu_mode = MON_MODE; /* switch to mon */
if (hst_lnt) /* record inst */ if (hst_lnt) /* record inst */
inst_hist (tinst, P, HIST_INT); inst_hist (tinst, P, HIST_INT);
if (pa != VEC_RTCP) { /* normal intr? */ if (pa != VEC_RTCP) { /* normal intr? */
tr = one_inst (tinst, P, save_mode); /* exec intr inst */ tr = one_inst (tinst, P, save_mode); /* exec intr inst */
if (tr) { /* stop code? */ if (tr) { /* stop code? */
usr_mode = save_mode; /* restore mode */ cpu_mode = save_mode; /* restore mode */
reason = (tr > 0)? tr: STOP_MMINT; reason = (tr > 0)? tr: STOP_MMINT;
break; break;
} }
@ -418,7 +418,7 @@ while (reason == 0) { /* loop until halted */
} }
else { /* clock intr */ else { /* clock intr */
tr = rtc_inst (tinst); /* exec RTC inst */ tr = rtc_inst (tinst); /* exec RTC inst */
usr_mode = save_mode; /* restore mode */ cpu_mode = save_mode; /* restore mode */
if (tr) { /* stop code? */ if (tr) { /* stop code? */
reason = (tr > 0)? tr: STOP_MMINT; reason = (tr > 0)? tr: STOP_MMINT;
break; break;
@ -429,14 +429,12 @@ while (reason == 0) { /* loop until halted */
} }
else { /* normal instr */ else { /* normal instr */
if (sim_brk_summ) { if (sim_brk_summ) {
uint32 btyp = SWMASK ('E'); static uint32 bmask[] = {SWMASK ('E') | SWMASK ('N'),
SWMASK ('E') | SWMASK ('M'),
SWMASK ('E') | SWMASK ('U')};
uint32 btyp;
if (nml_mode) btyp = sim_brk_test (P, bmask[cpu_mode]);
btyp = SWMASK ('E') | SWMASK ('N');
else
btyp = usr_mode ? SWMASK ('E') | SWMASK ('U')
: SWMASK ('E') | SWMASK ('M');
btyp = sim_brk_test (P, btyp);
if (btyp) { if (btyp) {
if (btyp & SWMASK ('E')) /* unqualified breakpoint? */ if (btyp & SWMASK ('E')) /* unqualified breakpoint? */
reason = STOP_IBKPT; /* stop simulation */ reason = STOP_IBKPT; /* stop simulation */
@ -460,7 +458,7 @@ while (reason == 0) { /* loop until halted */
ion_defer = 0; /* clear ion */ ion_defer = 0; /* clear ion */
if (hst_lnt) if (hst_lnt)
inst_hist (inst, save_P, HIST_XCT); inst_hist (inst, save_P, HIST_XCT);
reason = one_inst (inst, save_P, usr_mode); /* exec inst */ reason = one_inst (inst, save_P, cpu_mode); /* exec inst */
if (reason > 0) { /* stop code? */ if (reason > 0) { /* stop code? */
if (reason != STOP_HALT) if (reason != STOP_HALT)
P = save_P; P = save_P;
@ -478,14 +476,14 @@ while (reason == 0) { /* loop until halted */
reason = STOP_TRPINS; /* fatal err */ reason = STOP_TRPINS; /* fatal err */
break; break;
} }
save_mode = usr_mode; /* save mode */ save_mode = cpu_mode; /* save mode */
usr_mode = 0; /* switch to mon */ cpu_mode = MON_MODE; /* switch to mon */
mon_usr_trap = 0; mon_usr_trap = 0;
if (hst_lnt) if (hst_lnt)
inst_hist (tinst, save_P, HIST_TRP); inst_hist (tinst, save_P, HIST_TRP);
tr = one_inst (tinst, save_P, save_mode); /* trap inst */ tr = one_inst (tinst, save_P, save_mode); /* trap inst */
if (tr) { /* stop code? */ if (tr) { /* stop code? */
usr_mode = save_mode; /* restore mode */ cpu_mode = save_mode; /* restore mode */
P = save_P; /* restore PC */ P = save_P; /* restore PC */
reason = (tr > 0)? tr: STOP_MMTRP; reason = (tr > 0)? tr: STOP_MMTRP;
break; break;
@ -514,26 +512,29 @@ EXU_LOOP:
op = I_GETOP (inst); /* get opcode */ op = I_GETOP (inst); /* get opcode */
if (inst & I_POP) { /* POP? */ if (inst & I_POP) { /* POP? */
dat = (EM3 << 18) | (EM2 << 15) | I_IND | pc; /* data to save */ dat = (EM3 << 18) | (EM2 << 15) | I_IND | pc; /* data to save */
if (nml_mode) { /* normal mode? */ switch (cpu_mode)
{
case NML_MODE:
dat = (OV << 23) | dat; /* ov in <0> */ dat = (OV << 23) | dat; /* ov in <0> */
WriteP (0, dat); WriteP (0, dat);
} break;
else if (usr_mode) { /* user mode? */ case USR_MODE:
if (inst & I_USR) { /* SYSPOP? */ if (inst & I_USR) { /* SYSPOP? */
dat = I_USR | (OV << 21) | dat; /* ov in <2> */ dat = I_USR | (OV << 21) | dat; /* ov in <2> */
WriteP (0, dat); WriteP (0, dat);
usr_mode = 0; /* set mon mode */ cpu_mode = MON_MODE; /* set mon mode */
} }
else { /* normal POP */ else { /* normal POP */
dat = (OV << 23) | dat; /* ov in <0> */ dat = (OV << 23) | dat; /* ov in <0> */
if ((r = Write (0, dat))) if ((r = Write (0, dat)))
return r; return r;
} }
} break;
else { /* mon mode */ case MON_MODE:
dat = (OV << 21) | dat; /* ov in <2> */ dat = (OV << 21) | dat; /* ov in <2> */
WriteP (0, dat); /* store return */ WriteP (0, dat); /* store return */
} break;
}
PCQ_ENTRY; /* save PC */ PCQ_ENTRY; /* save PC */
P = 0100 | op; /* new PC */ P = 0100 | op; /* new PC */
OV = 0; /* clear ovflo */ OV = 0; /* clear ovflo */
@ -589,7 +590,7 @@ switch (op) { /* case on opcode */
case EAX: case EAX:
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
if (nml_mode || usr_mode) /* normal or user? */ if (cpu_mode != MON_MODE) /* normal or user? */
X = (X & ~VA_MASK) | (va & VA_MASK); /* only 14b */ X = (X & ~VA_MASK) | (va & VA_MASK); /* only 14b */
else X = (X & ~XVA_MASK) | (va & XVA_MASK); /* mon, 15b */ else X = (X & ~XVA_MASK) | (va & XVA_MASK); /* mon, 15b */
break; break;
@ -786,7 +787,7 @@ switch (op) { /* case on opcode */
break; break;
case HLT: case HLT:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
return STOP_HALT; /* halt CPU */ return STOP_HALT; /* halt CPU */
@ -802,15 +803,16 @@ switch (op) { /* case on opcode */
goto EXU_LOOP; goto EXU_LOOP;
case BRU: case BRU:
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */ if ((cpu_mode == NML_MODE) && (inst & I_IND))
api_dismiss (); /* normal-mode BRU*, dism */
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
if ((r = Read (va, &dat))) /* get operand */ if ((r = Read (va, &dat))) /* get operand */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = va & VA_MASK; /* branch */ P = va & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */ if ((va & VA_USR) && (cpu_mode == MON_MODE)) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */ cpu_mode = USR_MODE; /* transition to user mode */
if (mon_usr_trap) if (mon_usr_trap)
return MM_MONUSR; return MM_MONUSR;
} }
@ -825,8 +827,8 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = va & VA_MASK; /* branch */ P = va & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */ if ((va & VA_USR) && (cpu_mode == MON_MODE)) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */ cpu_mode = USR_MODE; /* transition to user mode */
if (mon_usr_trap) if (mon_usr_trap)
return MM_MONUSR; return MM_MONUSR;
} }
@ -837,15 +839,15 @@ switch (op) { /* case on opcode */
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
dat = (EM3 << 18) | (EM2 << 15) | pc; /* form return word */ dat = (EM3 << 18) | (EM2 << 15) | pc; /* form return word */
if (!nml_mode && !usr_mode) /* monitor mode? */ if (cpu_mode == MON_MODE) /* monitor mode? */
dat = dat | (mode << 23) | (OV << 21); dat = dat | ((mode == USR_MODE) << 23) | (OV << 21);
else dat = dat | (OV << 23); /* normal or user */ else dat = dat | (OV << 23); /* normal or user */
if ((r = Write (va, dat))) /* write ret word */ if ((r = Write (va, dat))) /* write ret word */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = (va + 1) & VA_MASK; /* branch */ P = (va + 1) & VA_MASK; /* branch */
if ((va & VA_USR) && !nml_mode && !usr_mode) { /* user ref from mon. mode? */ if ((va & VA_USR) && (cpu_mode == MON_MODE)) { /* user ref from mon. mode? */
usr_mode = 1; /* transition to user mode */ cpu_mode = USR_MODE; /* transition to user mode */
if (mon_usr_trap) if (mon_usr_trap)
return MM_MONUSR; return MM_MONUSR;
} }
@ -858,10 +860,10 @@ switch (op) { /* case on opcode */
return r; return r;
PCQ_ENTRY; PCQ_ENTRY;
P = (dat + 1) & VA_MASK; /* branch */ P = (dat + 1) & VA_MASK; /* branch */
if (!nml_mode && !usr_mode) { /* monitor mode? */ if (cpu_mode == MON_MODE) { /* monitor mode? */
OV = OV | ((dat >> 21) & 1); /* restore OV */ OV = OV | ((dat >> 21) & 1); /* restore OV */
if ((va & VA_USR) | (dat & I_USR)) { /* mode change? */ if ((va & VA_USR) | (dat & I_USR)) { /* mode change? */
usr_mode = 1; cpu_mode = USR_MODE;
if (mon_usr_trap) if (mon_usr_trap)
return MM_MONUSR; return MM_MONUSR;
} }
@ -870,7 +872,7 @@ switch (op) { /* case on opcode */
break; break;
case BRI: case BRI:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
@ -879,10 +881,10 @@ switch (op) { /* case on opcode */
api_dismiss (); /* dismiss hi api */ api_dismiss (); /* dismiss hi api */
PCQ_ENTRY; PCQ_ENTRY;
P = dat & VA_MASK; /* branch */ P = dat & VA_MASK; /* branch */
if (!nml_mode) { /* monitor mode? */ if (cpu_mode == MON_MODE) { /* monitor mode? */
OV = (dat >> 21) & 1; /* restore OV */ OV = (dat >> 21) & 1; /* restore OV */
if ((va & VA_USR) | (dat & I_USR)) { /* mode change? */ if ((va & VA_USR) | (dat & I_USR)) { /* mode change? */
usr_mode = 1; cpu_mode = USR_MODE;
if (mon_usr_trap) if (mon_usr_trap)
return MM_MONUSR; return MM_MONUSR;
} }
@ -1022,7 +1024,7 @@ switch (op) { /* case on opcode */
/* I/O instructions */ /* I/O instructions */
case MIW: case MIY: case MIW: case MIY:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
@ -1035,7 +1037,7 @@ switch (op) { /* case on opcode */
break; break;
case WIM: case YIM: case WIM: case YIM:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
@ -1048,7 +1050,7 @@ switch (op) { /* case on opcode */
break; break;
case EOM: case EOD: case EOM: case EOD:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = op_eomd (inst))) /* process inst */ if ((r = op_eomd (inst))) /* process inst */
return r; return r;
@ -1058,7 +1060,7 @@ switch (op) { /* case on opcode */
break; break;
case POT: case POT:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
@ -1071,7 +1073,7 @@ switch (op) { /* case on opcode */
break; break;
case PIN: case PIN:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = Ea (inst, &va))) /* decode eff addr */ if ((r = Ea (inst, &va))) /* decode eff addr */
return r; return r;
@ -1084,7 +1086,7 @@ switch (op) { /* case on opcode */
break; break;
case SKS: case SKS:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
if ((r = op_sks (inst, &dat))) /* process inst */ if ((r = op_sks (inst, &dat))) /* process inst */
return r; return r;
@ -1093,7 +1095,7 @@ switch (op) { /* case on opcode */
break; break;
default: default:
if (!nml_mode && usr_mode) /* priv inst */ if (cpu_mode == USR_MODE) /* priv inst */
return MM_PRVINS; return MM_PRVINS;
CRETINS; /* invalid inst */ CRETINS; /* invalid inst */
break; break;
@ -1160,7 +1162,7 @@ t_stat Read (uint32 va, uint32 *dat)
{ {
uint32 pgn, map, pa; uint32 pgn, map, pa;
if (nml_mode) { /* normal? */ if (cpu_mode == NML_MODE) { /* normal? */
va = va & VA_MASK; /* ignore user */ va = va & VA_MASK; /* ignore user */
if (va < 020000) /* first 8K: 1 for 1 */ if (va < 020000) /* first 8K: 1 for 1 */
pa = va; pa = va;
@ -1168,7 +1170,7 @@ if (nml_mode) { /* normal? */
pa = va + em2_dyn; pa = va + em2_dyn;
else pa = va + em3_dyn; /* next 4K: ext EM3 */ else pa = va + em3_dyn; /* next 4K: ext EM3 */
} }
else if (usr_mode || (va & VA_USR)) { /* user mapping? */ else if ((cpu_mode == USR_MODE) || (va & VA_USR)) { /* user mapping? */
pgn = VA_GETPN (va); /* get page no */ pgn = VA_GETPN (va); /* get page no */
map = usr_map[pgn]; /* get map entry */ map = usr_map[pgn]; /* get map entry */
if (map == MAP_PROT) /* prot? no access */ if (map == MAP_PROT) /* prot? no access */
@ -1192,7 +1194,7 @@ t_stat Write (uint32 va, uint32 dat)
{ {
uint32 pgn, map, pa; uint32 pgn, map, pa;
if (nml_mode) { /* normal? */ if (cpu_mode == NML_MODE) { /* normal? */
va = va & VA_MASK; /* ignore user */ va = va & VA_MASK; /* ignore user */
if (va < 020000) /* first 8K: 1 for 1 */ if (va < 020000) /* first 8K: 1 for 1 */
pa = va; pa = va;
@ -1200,7 +1202,7 @@ if (nml_mode) { /* normal? */
pa = va + em2_dyn; pa = va + em2_dyn;
else pa = va + em3_dyn; /* next 4K: ext EM3 */ else pa = va + em3_dyn; /* next 4K: ext EM3 */
} }
else if (usr_mode || (va & VA_USR)) { /* user mapping? */ else if ((cpu_mode == USR_MODE) || (va & VA_USR)) { /* user mapping? */
pgn = VA_GETPN (va); /* get page no */ pgn = VA_GETPN (va); /* get page no */
map = usr_map[pgn]; /* get map entry */ map = usr_map[pgn]; /* get map entry */
if (map & MAP_PROT) { /* protected page? */ if (map & MAP_PROT) { /* protected page? */
@ -1226,21 +1228,20 @@ return SCPE_OK;
uint32 RelocC (int32 va, int32 sw) uint32 RelocC (int32 va, int32 sw)
{ {
uint32 nml = nml_mode, usr = usr_mode; uint32 mode = cpu_mode;
uint32 pa, pgn, map; uint32 pa, pgn, map;
if (sw & SWMASK ('N')) /* -n: normal */ if (sw & SWMASK ('N')) /* -n: normal */
nml = 1; mode = NML_MODE;
else if (sw & SWMASK ('X')) /* -x: mon */ else if (sw & SWMASK ('X')) /* -x: mon */
nml = usr = 0; mode = MON_MODE;
else if (sw & SWMASK ('U')) { /* -u: user */ else if (sw & SWMASK ('U')) { /* -u: user */
nml = 0; mode = USR_MODE;
usr = 1;
} }
else if (!(sw & SWMASK ('V'))) /* -v: curr */ else if (!(sw & SWMASK ('V'))) /* -v: curr */
return va; return va;
set_dyn_map (); set_dyn_map ();
if (nml) { /* normal? */ if (mode == NML_MODE) { /* normal? */
if (va < 020000) /* first 8K: 1 for 1 */ if (va < 020000) /* first 8K: 1 for 1 */
pa = va; pa = va;
else if (va < 030000) /* next 4K: ext EM2 */ else if (va < 030000) /* next 4K: ext EM2 */
@ -1249,7 +1250,7 @@ if (nml) { /* normal? */
} }
else { else {
pgn = VA_GETPN (va); /* get page no */ pgn = VA_GETPN (va); /* get page no */
map = usr? usr_map[pgn]: mon_map[pgn]; /* get map entry */ map = (mode == USR_MODE)? usr_map[pgn]: mon_map[pgn]; /* get map entry */
if (map == MAP_PROT) /* no access page? */ if (map == MAP_PROT) /* no access page? */
return MAXMEMSIZE + 1; return MAXMEMSIZE + 1;
pa = (map & ~MAP_PROT) | (va & VA_POFF); /* map address */ pa = (map & ~MAP_PROT) | (va & VA_POFF); /* map address */
@ -1483,8 +1484,7 @@ EM2 = 2;
EM3 = 3; EM3 = 3;
RL1 = RL2 = RL4 = 0; RL1 = RL2 = RL4 = 0;
ion = ion_defer = 0; ion = ion_defer = 0;
nml_mode = 1; cpu_mode = NML_MODE;
usr_mode = 0;
mon_usr_trap = 0; mon_usr_trap = 0;
int_req = 0; int_req = 0;
int_reqhi = 0; int_reqhi = 0;
@ -1652,10 +1652,12 @@ return SCPE_OK;
void inst_hist (uint32 ir, uint32 pc, uint32 tp) void inst_hist (uint32 ir, uint32 pc, uint32 tp)
{ {
if (cpu_mode == hst_exclude)
return;
hst_p = (hst_p + 1); /* next entry */ hst_p = (hst_p + 1); /* next entry */
if (hst_p >= hst_lnt) if (hst_p >= hst_lnt)
hst_p = 0; hst_p = 0;
hst[hst_p].typ = tp | (OV << 4); hst[hst_p].typ = tp | (OV << 4) | (cpu_mode << 5);
hst[hst_p].pc = pc; hst[hst_p].pc = pc;
hst[hst_p].ir = ir; hst[hst_p].ir = ir;
hst[hst_p].a = A; hst[hst_p].a = A;
@ -1682,6 +1684,14 @@ lnt = (int32) get_uint (cptr, 10, HIST_MAX, &r);
if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN))) if ((r != SCPE_OK) || (lnt && (lnt < HIST_MIN)))
return SCPE_ARG; return SCPE_ARG;
hst_p = 0; hst_p = 0;
if (sim_switches & SWMASK('M'))
hst_exclude = MON_MODE;
else if (sim_switches & SWMASK('N'))
hst_exclude = NML_MODE;
else if (sim_switches & SWMASK('U'))
hst_exclude = USR_MODE;
else
hst_exclude = BAD_MODE;
if (hst_lnt) { if (hst_lnt) {
free (hst); free (hst);
hst_lnt = 0; hst_lnt = 0;
@ -1706,6 +1716,7 @@ t_stat r;
t_value sim_eval; t_value sim_eval;
InstHistory *h; InstHistory *h;
static char *cyc[] = { " ", " ", "INT", "TRP" }; static char *cyc[] = { " ", " ", "INT", "TRP" };
static char *modes = "NMU?";
if (hst_lnt == 0) /* enabled? */ if (hst_lnt == 0) /* enabled? */
return SCPE_NOFNC; return SCPE_NOFNC;
@ -1718,13 +1729,13 @@ else lnt = hst_lnt;
di = hst_p - lnt; /* work forward */ di = hst_p - lnt; /* work forward */
if (di < 0) if (di < 0)
di = di + hst_lnt; di = di + hst_lnt;
fprintf (st, "CYC PC OV A B X EA IR\n\n"); fprintf (st, "CYC PC MD OV A B X EA IR\n\n");
for (k = 0; k < lnt; k++) { /* print specified */ for (k = 0; k < lnt; k++) { /* print specified */
h = &hst[(++di) % hst_lnt]; /* entry pointer */ h = &hst[(++di) % hst_lnt]; /* entry pointer */
if (h->typ) { /* instruction? */ if (h->typ) { /* instruction? */
ov = (h->typ >> 4) & 1; /* overflow */ ov = (h->typ >> 4) & 1; /* overflow */
fprintf (st, "%s %05o %o %08o %08o %08o ", cyc[h->typ & 3], fprintf (st, "%s %05o %c %o %08o %08o %08o ", cyc[h->typ & 3],
h->pc, ov, h->a, h->b, h->x); h->pc, modes[(h->typ >> 5) & 3], ov, h->a, h->b, h->x);
if (h->ea & HIST_NOEA) if (h->ea & HIST_NOEA)
fprintf (st, " "); fprintf (st, " ");
else fprintf (st, "%05o ", h->ea); else fprintf (st, "%05o ", h->ea);

View file

@ -81,6 +81,13 @@
#define SXT_EXP(x) ((int32) (((x) & EXPS)? ((x) | ~EXPMASK): \ #define SXT_EXP(x) ((int32) (((x) & EXPS)? ((x) | ~EXPMASK): \
((x) & EXPMASK))) ((x) & EXPMASK)))
/* CPU modes */
#define NML_MODE 0
#define MON_MODE 1
#define USR_MODE 2
#define BAD_MODE 3
/* Memory */ /* Memory */
#define MAXMEMSIZE (1 << 16) /* max memory size */ #define MAXMEMSIZE (1 << 16) /* max memory size */

View file

@ -81,7 +81,7 @@ extern uint32 int_req; /* int req */
extern uint32 xfr_req; /* xfer req */ extern uint32 xfr_req; /* xfer req */
extern uint32 alert; /* pin/pot alert */ extern uint32 alert; /* pin/pot alert */
extern uint32 X, EM2, EM3, OV, ion, bpt; extern uint32 X, EM2, EM3, OV, ion, bpt;
extern uint32 nml_mode, usr_mode; extern uint32 cpu_mode;
extern int32 rtc_pie; extern int32 rtc_pie;
extern int32 stop_invins, stop_invdev, stop_inviop; extern int32 stop_invins, stop_invdev, stop_inviop;
extern uint32 mon_usr_trap; extern uint32 mon_usr_trap;
@ -431,7 +431,7 @@ switch (mod) {
else if (inst & 01000) /* alert RL2 */ else if (inst & 01000) /* alert RL2 */
alert = POT_RL2; alert = POT_RL2;
if (inst & 02000) { /* nml to mon */ if (inst & 02000) { /* nml to mon */
nml_mode = usr_mode = 0; cpu_mode = MON_MODE;
if (inst & 00400) if (inst & 00400)
mon_usr_trap = 1; mon_usr_trap = 1;
} }