SDS: Fix bugs in Monitor-to-User Transition
1. When transitioning from monitor to user mode with the trap enabled, the trap was latching the monitor address of the transferring branch rather than the user-mode address of the branch target. 2. When executing a BRU, BRX or BRM in monitor mode, if the effective address was in user mode, the code neglected to transition the machine to user mode. And after doing so, it is necessary to check for an armed monitor-to-user trap. Also removed superfluous trailing blanks from lines in file.
This commit is contained in:
parent
9f0261be11
commit
5270c44117
1 changed files with 21 additions and 4 deletions
|
@ -448,6 +448,8 @@ while (reason == 0) { /* loop until halted */
|
||||||
} /* end if r == 0 */
|
} /* end if r == 0 */
|
||||||
if (reason < 0) { /* mm (fet or ex)? */
|
if (reason < 0) { /* mm (fet or ex)? */
|
||||||
pa = -reason; /* get vector */
|
pa = -reason; /* get vector */
|
||||||
|
if (reason == MM_MONUSR) /* record P of user-mode */
|
||||||
|
save_P = P; /* transition point */
|
||||||
reason = 0; /* defang */
|
reason = 0; /* defang */
|
||||||
tinst = ReadP (pa); /* get inst */
|
tinst = ReadP (pa); /* get inst */
|
||||||
if (I_GETOP (tinst) != BRM) { /* not BRM? */
|
if (I_GETOP (tinst) != BRM) { /* not BRM? */
|
||||||
|
@ -505,7 +507,7 @@ if (inst & I_POP) { /* POP? */
|
||||||
if ((r = Write (0, dat)))
|
if ((r = Write (0, dat)))
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { /* mon mode */
|
else { /* 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 */
|
||||||
|
@ -776,7 +778,7 @@ switch (op) { /* case on opcode */
|
||||||
return r;
|
return r;
|
||||||
inst = dat;
|
inst = dat;
|
||||||
goto EXU_LOOP;
|
goto EXU_LOOP;
|
||||||
|
|
||||||
case BRU:
|
case BRU:
|
||||||
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
|
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
|
||||||
if ((r = Ea (inst, &va))) /* decode eff addr */
|
if ((r = Ea (inst, &va))) /* decode eff addr */
|
||||||
|
@ -785,6 +787,11 @@ 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? */
|
||||||
|
usr_mode = 1; /* transition to user mode */
|
||||||
|
if (mon_usr_trap)
|
||||||
|
return MM_MONUSR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BRX:
|
case BRX:
|
||||||
|
@ -796,6 +803,11 @@ 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? */
|
||||||
|
usr_mode = 1; /* transition to user mode */
|
||||||
|
if (mon_usr_trap)
|
||||||
|
return MM_MONUSR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -810,6 +822,11 @@ switch (op) { /* case on opcode */
|
||||||
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? */
|
||||||
|
usr_mode = 1; /* transition to user mode */
|
||||||
|
if (mon_usr_trap)
|
||||||
|
return MM_MONUSR;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BRR:
|
case BRR:
|
||||||
|
@ -1191,7 +1208,7 @@ uint32 nml = nml_mode, usr = usr_mode;
|
||||||
uint32 pa, pgn, map;
|
uint32 pa, pgn, map;
|
||||||
|
|
||||||
if (sw & SWMASK ('N')) /* -n: normal */
|
if (sw & SWMASK ('N')) /* -n: normal */
|
||||||
nml = 1;
|
nml = 1;
|
||||||
else if (sw & SWMASK ('X')) /* -x: mon */
|
else if (sw & SWMASK ('X')) /* -x: mon */
|
||||||
nml = usr = 0;
|
nml = usr = 0;
|
||||||
else if (sw & SWMASK ('U')) { /* -u: user */
|
else if (sw & SWMASK ('U')) { /* -u: user */
|
||||||
|
@ -1269,7 +1286,7 @@ return;
|
||||||
|
|
||||||
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm
|
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm
|
||||||
runs even for overflow cases. Hence it must be emulated precisely
|
runs even for overflow cases. Hence it must be emulated precisely
|
||||||
to give the right answers for diagnostics. If the dividend is
|
to give the right answers for diagnostics. If the dividend is
|
||||||
negative, AB are 2's complemented starting at B<22>, and B<23>
|
negative, AB are 2's complemented starting at B<22>, and B<23>
|
||||||
is unchanged. */
|
is unchanged. */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue