mirror of
https://github.com/open-simh/simh.git
synced 2026-04-28 12:57:40 +00:00
PDP11: CPU MMR1 and FP changes
There are a lot of niggling fixes, mostly for incompatibility issues found by Walter Mueller. Working out the 11/70 behavior is still not fully done, but it's a lot better than it was, and it passes more of the 11/70 MMU diagnostic. - Floating point. Now model sensitive in treating MMR1, for 2.11 BSD. - MMR1 now tracks PC changes on 11/44, 11/45, 11/70, and J11 -(PC) and @-(PC). - MMR1 is cleared at start of trap sequence on 11/45, 11/70. - Red stack abort occurs before memory writes on 11/45, 11/70 (no other model has them).
This commit is contained in:
committed by
Mark Pizzolato
parent
e93d21ac79
commit
a847ee13a3
@@ -23,6 +23,7 @@
|
||||
used in advertising or otherwise to promote the sale, use or other dealings
|
||||
in this Software without prior written authorization from Robert M Supnik.
|
||||
|
||||
21-Aug-22 RMS Restored MMR1 operation for 11/44, 11/45-70 (Walter Mueller)
|
||||
28-May-18 RMS Fixed FPCHG macro to avoid undefined operation (Mark Pizzolato)
|
||||
24-Mar-15 RMS MMR1 does not track register changes (Johnny Billquist)
|
||||
20-Apr-13 RMS MMR1 does not track PC changes (Johnny Billquist)
|
||||
@@ -248,9 +249,10 @@ static const uint32 and_mask[33] = { 0,
|
||||
int32 backup_PC;
|
||||
int32 fp_change;
|
||||
|
||||
int32 fpnotrap (int32 code);
|
||||
t_bool fpnotrap (int32 code);
|
||||
int32 GeteaFW (int32 spec);
|
||||
int32 GeteaFP (int32 spec, int32 len);
|
||||
void fp_reg_change (int32 len, int32 reg);
|
||||
uint32 ReadI (int32 addr, int32 spec, int32 len);
|
||||
t_bool ReadFP (fpac_t *fac, int32 addr, int32 spec, int32 len);
|
||||
void WriteI (int32 data, int32 addr, int32 spec, int32 len);
|
||||
@@ -603,33 +605,25 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
||||
|
||||
case 2: /* (R)+ */
|
||||
adr = R[reg]; /* post increment */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = (R[reg] + 2) & 0177777;
|
||||
else fp_change = FPCHG (2, reg); /* others, update later */
|
||||
fp_reg_change (2, reg); /* update */
|
||||
return (adr | ds);
|
||||
|
||||
case 3: /* @(R)+ */
|
||||
adr = R[reg]; /* post increment */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = (R[reg] + 2) & 0177777;
|
||||
else fp_change = FPCHG (2, reg); /* others, update later */
|
||||
fp_reg_change (2, reg); /* update */
|
||||
adr = ReadW (adr | ds);
|
||||
return (adr | dsenable);
|
||||
|
||||
case 4: /* -(R) */
|
||||
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = adr;
|
||||
else fp_change = FPCHG (-2, reg); /* others, update later */
|
||||
fp_reg_change (-2, reg); /* update */
|
||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||
set_stack_trap (adr);
|
||||
return (adr | ds);
|
||||
|
||||
case 5: /* @-(R) */
|
||||
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = adr;
|
||||
else fp_change = FPCHG (-2, reg); /* others, update later */
|
||||
fp_reg_change (-2, reg); /* update */
|
||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||
set_stack_trap (adr);
|
||||
adr = ReadW (adr | ds);
|
||||
@@ -684,33 +678,27 @@ switch (spec >> 3) { /* case on spec */
|
||||
|
||||
case 2: /* (R)+ */
|
||||
adr = R[reg]; /* post increment */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = (R[reg] + 2) & 0177777;
|
||||
else fp_change = FPCHG (len, reg); /* others, update later */
|
||||
if (reg == 7) /* # is always length 2 */
|
||||
len = 2;
|
||||
fp_reg_change (len, reg); /* update */
|
||||
return (adr | ds);
|
||||
|
||||
case 3: /* @(R)+ */
|
||||
adr = R[reg]; /* post increment */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = (R[reg] + 2) & 0177777;
|
||||
else fp_change = FPCHG (2, reg); /* others, update later */
|
||||
fp_reg_change (2, reg); /* update */
|
||||
adr = ReadW (adr | ds);
|
||||
return (adr | dsenable);
|
||||
|
||||
case 4: /* -(R) */
|
||||
adr = (R[reg] - len) & 0177777; /* predecrement */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = adr;
|
||||
else fp_change = FPCHG (-len, reg); /* others, udpate later */
|
||||
fp_reg_change (-len, reg); /* update */
|
||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||
set_stack_trap (adr);
|
||||
return (adr | ds);
|
||||
|
||||
case 5: /* @-(R) */
|
||||
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
||||
if (reg == 7) /* commit PC chg now */
|
||||
R[reg] = adr;
|
||||
else fp_change = FPCHG (-2, reg); /* others, update later */
|
||||
fp_reg_change (-2, reg); /* update */
|
||||
if ((reg == 6) && (cm == MD_KER) && ((adr - 2) < (STKLIM + STKL_Y)))
|
||||
set_stack_trap (adr);
|
||||
adr = ReadW (adr | ds);
|
||||
@@ -731,6 +719,35 @@ switch (spec >> 3) { /* case on spec */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Specifier register change
|
||||
|
||||
On systems with full memory management, the 11/44, 11/45, and 11/70
|
||||
operate differently than J11. The former do normal register modification
|
||||
and track changes in MMR1; on an abort, the register modifications
|
||||
are visible. The J11 does not perform normal register modification
|
||||
and tracking. Instead, it tracks changes internally and only updates
|
||||
the general registers upon successful completion of the instruction.
|
||||
On an abort, the general registers are unchanged.
|
||||
|
||||
This routine performs the appropriate bookkeeping for the different
|
||||
models.
|
||||
*/
|
||||
|
||||
void fp_reg_change (int32 len, int32 reg)
|
||||
{
|
||||
if (CPUT (CPUT_J)) { /* J11? */
|
||||
if (reg == 7)
|
||||
R[reg] = (R[reg] + len) & 0177777; /* commit PC changes now */
|
||||
else fp_change = FPCHG (len, reg); /* track other changes */
|
||||
}
|
||||
else { /* all others */
|
||||
R[reg] = (R[reg] + len) & 0177777; /* commit reg changes */
|
||||
if (update_MM) /* if not frozen */
|
||||
MMR1 = ((len & 037) << 3) | reg; /* update MMR1 */
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* Read integer operand
|
||||
|
||||
Inputs:
|
||||
@@ -782,10 +799,12 @@ else {
|
||||
(ReadW (exta | ((VA + 6) & 0177777)) << FP_V_F3);
|
||||
else fptr->l = 0;
|
||||
}
|
||||
if ((GET_SIGN (fptr->h) != 0) &&
|
||||
if ((GET_SIGN (fptr->h) != 0) && /* undef variable? */
|
||||
(GET_EXP (fptr->h) == 0) &&
|
||||
(fpnotrap (FEC_UNDFV) == 0))
|
||||
return FALSE;
|
||||
!fpnotrap (FEC_UNDFV)) { /* trap enabled? */
|
||||
fp_change = 0; /* J11, no reg changes */
|
||||
return FALSE; /* NOP instruction */
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -1332,7 +1351,7 @@ return 0;
|
||||
int = FALSE if interrupt enabled, TRUE if disabled
|
||||
*/
|
||||
|
||||
int32 fpnotrap (int32 code)
|
||||
t_bool fpnotrap (int32 code)
|
||||
{
|
||||
static const int32 test_code[] = { 0, 0, 0, FPS_IC, FPS_IV, FPS_IU, FPS_IUV };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user