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:
Mark Emmer 2014-03-02 22:21:13 -06:00
parent 9f0261be11
commit 5270c44117

View file

@ -448,6 +448,8 @@ while (reason == 0) { /* loop until halted */
} /* end if r == 0 */
if (reason < 0) { /* mm (fet or ex)? */
pa = -reason; /* get vector */
if (reason == MM_MONUSR) /* record P of user-mode */
save_P = P; /* transition point */
reason = 0; /* defang */
tinst = ReadP (pa); /* get inst */
if (I_GETOP (tinst) != BRM) { /* not BRM? */
@ -505,7 +507,7 @@ if (inst & I_POP) { /* POP? */
if ((r = Write (0, dat)))
return r;
}
}
}
else { /* mon mode */
dat = (OV << 21) | dat; /* ov in <2> */
WriteP (0, dat); /* store return */
@ -776,7 +778,7 @@ switch (op) { /* case on opcode */
return r;
inst = dat;
goto EXU_LOOP;
case BRU:
if (nml_mode && (inst & I_IND)) api_dismiss (); /* normal BRU*, dism */
if ((r = Ea (inst, &va))) /* decode eff addr */
@ -785,6 +787,11 @@ switch (op) { /* case on opcode */
return r;
PCQ_ENTRY;
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;
case BRX:
@ -796,6 +803,11 @@ switch (op) { /* case on opcode */
return r;
PCQ_ENTRY;
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;
@ -810,6 +822,11 @@ switch (op) { /* case on opcode */
return r;
PCQ_ENTRY;
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;
case BRR:
@ -1191,7 +1208,7 @@ uint32 nml = nml_mode, usr = usr_mode;
uint32 pa, pgn, map;
if (sw & SWMASK ('N')) /* -n: normal */
nml = 1;
nml = 1;
else if (sw & SWMASK ('X')) /* -x: mon */
nml = usr = 0;
else if (sw & SWMASK ('U')) { /* -u: user */
@ -1269,7 +1286,7 @@ return;
/* Divide - the SDS 940 uses a non-restoring divide. The algorithm
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>
is unchanged. */