mirror of
https://github.com/simh/simh.git
synced 2026-05-03 22:48:35 +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
7fcaa7cf02
commit
72f75ec1b5
@@ -1,6 +1,6 @@
|
|||||||
/* pdp11_cpu.c: PDP-11 CPU simulator
|
/* pdp11_cpu.c: PDP-11 CPU simulator
|
||||||
|
|
||||||
Copyright (c) 1993-2016, Robert M Supnik
|
Copyright (c) 1993-2022, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -25,6 +25,14 @@
|
|||||||
|
|
||||||
cpu PDP-11 CPU
|
cpu PDP-11 CPU
|
||||||
|
|
||||||
|
25-Aug-22 RMS 11/45,70 clear MMR1 in trap sequence (Walter Mueller)
|
||||||
|
23-Aug-22 RMS 11/45,70 detect red stack abort before memory write
|
||||||
|
in JSR, MFPx (Walter Mueller)
|
||||||
|
20-Aug-22 RMS MMR1 reads as 0 on subset memory mmgt systems
|
||||||
|
11/44, 45, 70 track PC changes (Walter Mueller)
|
||||||
|
J11 tracks PC changes on -(PC) and @-(PC)
|
||||||
|
25-Jul-22 RMS Removed deprecated CPU models (Q22, UHR11, URH70)
|
||||||
|
04-Jun-18 RMS Removed CPU model entries for UC15 (Mark Pizzolato)
|
||||||
04-Dec-16 RMS Removed duplicate IDLE entries in MTAB
|
04-Dec-16 RMS Removed duplicate IDLE entries in MTAB
|
||||||
30-Aug-16 RMS Fixed overloading of -d in ex/mod
|
30-Aug-16 RMS Fixed overloading of -d in ex/mod
|
||||||
14-Mar-16 RMS Added UC15 support
|
14-Mar-16 RMS Added UC15 support
|
||||||
@@ -338,6 +346,7 @@ int32 relocR (int32 addr);
|
|||||||
int32 relocW (int32 addr);
|
int32 relocW (int32 addr);
|
||||||
void relocR_test (int32 va, int32 apridx);
|
void relocR_test (int32 va, int32 apridx);
|
||||||
void relocW_test (int32 va, int32 apridx);
|
void relocW_test (int32 va, int32 apridx);
|
||||||
|
int32 clean_MMR1 (int32 mmr1);
|
||||||
t_bool PLF_test (int32 va, int32 apr);
|
t_bool PLF_test (int32 va, int32 apr);
|
||||||
void reloc_abort (int32 err, int32 apridx);
|
void reloc_abort (int32 err, int32 apridx);
|
||||||
int32 ReadE (int32 addr);
|
int32 ReadE (int32 addr);
|
||||||
@@ -609,9 +618,9 @@ MTAB cpu_mod[] = {
|
|||||||
{ MTAB_XTD|MTAB_VDV, MOD_1184, NULL, "11/84", &cpu_set_model, NULL, NULL, "Set CPU type to 11/84" },
|
{ MTAB_XTD|MTAB_VDV, MOD_1184, NULL, "11/84", &cpu_set_model, NULL, NULL, "Set CPU type to 11/84" },
|
||||||
{ MTAB_XTD|MTAB_VDV, MOD_1193, NULL, "11/93", &cpu_set_model, NULL, NULL, "Set CPU type to 11/93" },
|
{ MTAB_XTD|MTAB_VDV, MOD_1193, NULL, "11/93", &cpu_set_model, NULL, NULL, "Set CPU type to 11/93" },
|
||||||
{ MTAB_XTD|MTAB_VDV, MOD_1194, NULL, "11/94", &cpu_set_model, NULL, NULL, "Set CPU type to 11/94" },
|
{ MTAB_XTD|MTAB_VDV, MOD_1194, NULL, "11/94", &cpu_set_model, NULL, NULL, "Set CPU type to 11/94" },
|
||||||
{ MTAB_XTD|MTAB_VDV, MOD_1173, NULL, "Q22", &cpu_set_model, NULL, NULL, "deprecated: same as 11/73" },
|
// { MTAB_XTD|MTAB_VDV, MOD_1173, NULL, "Q22", &cpu_set_model, NULL, NULL, "deprecated: same as 11/73" },
|
||||||
{ MTAB_XTD|MTAB_VDV, MOD_1184, NULL, "URH11", &cpu_set_model, NULL, NULL, "deprecated: same as 11/84" },
|
// { MTAB_XTD|MTAB_VDV, MOD_1184, NULL, "URH11", &cpu_set_model, NULL, NULL, "deprecated: same as 11/84" },
|
||||||
{ MTAB_XTD|MTAB_VDV, MOD_1170, NULL, "URH70", &cpu_set_model, NULL, NULL, "deprecated: same as 11/70" },
|
// { MTAB_XTD|MTAB_VDV, MOD_1170, NULL, "URH70", &cpu_set_model, NULL, NULL, "deprecated: same as 11/70" },
|
||||||
{ MTAB_XTD|MTAB_VDV, MOD_1145, NULL, "U18", &cpu_set_model, NULL, NULL, "deprecated: same as 11/45" },
|
{ MTAB_XTD|MTAB_VDV, MOD_1145, NULL, "U18", &cpu_set_model, NULL, NULL, "deprecated: same as 11/45" },
|
||||||
{ MTAB_XTD|MTAB_VDV, OPT_EIS, NULL, "EIS", &cpu_set_opt, NULL, NULL, "enable EIS instructions" },
|
{ MTAB_XTD|MTAB_VDV, OPT_EIS, NULL, "EIS", &cpu_set_opt, NULL, NULL, "enable EIS instructions" },
|
||||||
{ MTAB_XTD|MTAB_VDV, OPT_EIS, NULL, "NOEIS", &cpu_clr_opt, NULL, NULL, "disable EIS instructions" },
|
{ MTAB_XTD|MTAB_VDV, OPT_EIS, NULL, "NOEIS", &cpu_clr_opt, NULL, NULL, "disable EIS instructions" },
|
||||||
@@ -888,8 +897,10 @@ while (reason == 0) {
|
|||||||
PSW = get_PSW (); /* assemble PSW */
|
PSW = get_PSW (); /* assemble PSW */
|
||||||
oldrs = rs;
|
oldrs = rs;
|
||||||
if (CPUT (HAS_MMTR)) { /* 45,70? */
|
if (CPUT (HAS_MMTR)) { /* 45,70? */
|
||||||
if (update_MM) /* save vector */
|
if (update_MM) { /* if not frozen */
|
||||||
MMR2 = trapea;
|
MMR1 = 0; /* clear MMR1 */
|
||||||
|
MMR2 = trapea; /* save vector */
|
||||||
|
}
|
||||||
MMR0 = MMR0 & ~MMR0_IC; /* clear IC */
|
MMR0 = MMR0 & ~MMR0_IC; /* clear IC */
|
||||||
}
|
}
|
||||||
src = ReadCW (trapea | calc_ds (MD_KER)); /* new PC */
|
src = ReadCW (trapea | calc_ds (MD_KER)); /* new PC */
|
||||||
@@ -1222,9 +1233,9 @@ while (reason == 0) {
|
|||||||
reg_mods = calc_MMR1 (0366);
|
reg_mods = calc_MMR1 (0366);
|
||||||
if (update_MM)
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
WriteW (R[srcspec], SP | dsenable);
|
|
||||||
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (SP);
|
set_stack_trap (SP);
|
||||||
|
WriteW (R[srcspec], SP | dsenable);
|
||||||
R[srcspec] = PC;
|
R[srcspec] = PC;
|
||||||
if (hst_ent)
|
if (hst_ent)
|
||||||
hst_ent->dst = dst;
|
hst_ent->dst = dst;
|
||||||
@@ -1424,9 +1435,9 @@ while (reason == 0) {
|
|||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
if (hst_ent)
|
if (hst_ent)
|
||||||
hst_ent->dst = dst;
|
hst_ent->dst = dst;
|
||||||
WriteW (dst, SP | dsenable);
|
|
||||||
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (SP);
|
set_stack_trap (SP);
|
||||||
|
WriteW (dst, SP | dsenable);
|
||||||
}
|
}
|
||||||
else setTRAP (TRAP_ILL);
|
else setTRAP (TRAP_ILL);
|
||||||
break;
|
break;
|
||||||
@@ -1715,7 +1726,7 @@ while (reason == 0) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((((uint32)src) == 020000000000) && (src2 == 0177777)) {
|
if ((((uint32)src) == 020000000000) && (src2 == 0177777)) {
|
||||||
V = 1; /* J11,11/70 compat */
|
V = 1; /* V = 1 */
|
||||||
N = Z = C = 0; /* N = Z = 0 */
|
N = Z = C = 0; /* N = Z = 0 */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1730,7 +1741,7 @@ while (reason == 0) {
|
|||||||
}
|
}
|
||||||
N = (dst < 0); /* N set on 32b result */
|
N = (dst < 0); /* N set on 32b result */
|
||||||
if ((dst > 077777) || (dst < -0100000)) {
|
if ((dst > 077777) || (dst < -0100000)) {
|
||||||
V = 1; /* J11,11/70 compat */
|
V = 1; /* V = 1 */
|
||||||
Z = C = 0; /* Z = C = 0 */
|
Z = C = 0; /* Z = C = 0 */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2215,9 +2226,9 @@ while (reason == 0) {
|
|||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
if (hst_ent)
|
if (hst_ent)
|
||||||
hst_ent->dst = dst;
|
hst_ent->dst = dst;
|
||||||
WriteW (dst, SP | dsenable);
|
|
||||||
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (SP);
|
set_stack_trap (SP);
|
||||||
|
WriteW (dst, SP | dsenable);
|
||||||
}
|
}
|
||||||
else setTRAP (TRAP_ILL);
|
else setTRAP (TRAP_ILL);
|
||||||
break;
|
break;
|
||||||
@@ -2414,6 +2425,7 @@ for (i = 0; i < 6; i++)
|
|||||||
REGFILE[i][rs] = R[i];
|
REGFILE[i][rs] = R[i];
|
||||||
STACKFILE[cm] = SP;
|
STACKFILE[cm] = SP;
|
||||||
saved_PC = PC & 0177777;
|
saved_PC = PC & 0177777;
|
||||||
|
MMR1 = clean_MMR1 (MMR1); /* clean up MMR1 */
|
||||||
pcq_r->qptr = pcq_p; /* update pc q ptr */
|
pcq_r->qptr = pcq_p; /* update pc q ptr */
|
||||||
set_r_display (rs, cm);
|
set_r_display (rs, cm);
|
||||||
return reason;
|
return reason;
|
||||||
@@ -2454,7 +2466,7 @@ return reason;
|
|||||||
explicitly reference the PC. For the J-11, this is only true for
|
explicitly reference the PC. For the J-11, this is only true for
|
||||||
autodecrement operands, autodecrement deferred operands, and
|
autodecrement operands, autodecrement deferred operands, and
|
||||||
autoincrement destination operands that involve a write to memory.
|
autoincrement destination operands that involve a write to memory.
|
||||||
The simulator follows the Handbook, for simplicity.
|
This is cleaned up at simulator exit or MMR1 read.
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
||||||
@@ -2482,14 +2494,14 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
case 2: /* (R)+ */
|
case 2: /* (R)+ */
|
||||||
R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
||||||
reg_mods = calc_MMR1 (020 | reg);
|
reg_mods = calc_MMR1 (020 | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
return (adr | ds);
|
return (adr | ds);
|
||||||
|
|
||||||
case 3: /* @(R)+ */
|
case 3: /* @(R)+ */
|
||||||
R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
||||||
reg_mods = calc_MMR1 (020 | reg);
|
reg_mods = calc_MMR1 (020 | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
adr = ReadW (adr | ds);
|
adr = ReadW (adr | ds);
|
||||||
return (adr | dsenable);
|
return (adr | dsenable);
|
||||||
@@ -2497,7 +2509,7 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
case 4: /* -(R) */
|
case 4: /* -(R) */
|
||||||
adr = R[reg] = (R[reg] - 2) & 0177777;
|
adr = R[reg] = (R[reg] - 2) & 0177777;
|
||||||
reg_mods = calc_MMR1 (0360 | reg);
|
reg_mods = calc_MMR1 (0360 | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
@@ -2506,7 +2518,7 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
case 5: /* @-(R) */
|
case 5: /* @-(R) */
|
||||||
adr = R[reg] = (R[reg] - 2) & 0177777;
|
adr = R[reg] = (R[reg] - 2) & 0177777;
|
||||||
reg_mods = calc_MMR1 (0360 | reg);
|
reg_mods = calc_MMR1 (0360 | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
@@ -2551,7 +2563,7 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
case 3: /* @(R)+ */
|
case 3: /* @(R)+ */
|
||||||
R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
R[reg] = ((adr = R[reg]) + 2) & 0177777;
|
||||||
reg_mods = calc_MMR1 (020 | reg);
|
reg_mods = calc_MMR1 (020 | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
adr = ReadW (adr | ds);
|
adr = ReadW (adr | ds);
|
||||||
return (adr | dsenable);
|
return (adr | dsenable);
|
||||||
@@ -2560,7 +2572,7 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
delta = 1 + (reg >= 6); /* 2 if R6, PC */
|
delta = 1 + (reg >= 6); /* 2 if R6, PC */
|
||||||
adr = R[reg] = (R[reg] - delta) & 0177777;
|
adr = R[reg] = (R[reg] - delta) & 0177777;
|
||||||
reg_mods = calc_MMR1 ((((-delta) & 037) << 3) | reg);
|
reg_mods = calc_MMR1 ((((-delta) & 037) << 3) | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
@@ -2569,7 +2581,7 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
case 5: /* @-(R) */
|
case 5: /* @-(R) */
|
||||||
adr = R[reg] = (R[reg] - 2) & 0177777;
|
adr = R[reg] = (R[reg] - 2) & 0177777;
|
||||||
reg_mods = calc_MMR1 (0360 | reg);
|
reg_mods = calc_MMR1 (0360 | reg);
|
||||||
if (update_MM && (reg != 7))
|
if (update_MM)
|
||||||
MMR1 = reg_mods;
|
MMR1 = reg_mods;
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
@@ -3087,7 +3099,8 @@ switch ((pa >> 1) & 3) { /* decode pa<2:1> */
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 2: /* MMR1 */
|
case 2: /* MMR1 */
|
||||||
*data = MMR1;
|
MMR1 = clean_MMR1 (MMR1); /* clean up MMR1 */
|
||||||
|
*data = MMR1; /* return data */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: /* MMR2 */
|
case 3: /* MMR2 */
|
||||||
@@ -3133,6 +3146,29 @@ dsenable = calc_ds (cm);
|
|||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clean up MMR1 for presentation
|
||||||
|
|
||||||
|
!HAS_SID MMR1 is 0
|
||||||
|
HAS_SID && J11 MMR1 values corresponding to # and @# are cleared
|
||||||
|
HAS_SID && !J11 MMR1 is unchanged
|
||||||
|
|
||||||
|
Note that # and @# always generate reg = 7 and change = 2;
|
||||||
|
no other specifier combination can do that.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int32 clean_MMR1 (int32 mmr1)
|
||||||
|
{
|
||||||
|
if (!CPUT (HAS_SID)) /* not full mmgt? */
|
||||||
|
return 0; /* always 0 */
|
||||||
|
if (CPUT (CPUT_J)) { /* J11? */
|
||||||
|
if ((mmr1 >> 8) == 027) /* high byte # or @#? */
|
||||||
|
mmr1 = mmr1 & 0377; /* erase high byte */
|
||||||
|
if ((mmr1 & 0377) == 027) /* low byte # or @#? */
|
||||||
|
mmr1 = mmr1 >> 8; /* erase low byte */
|
||||||
|
}
|
||||||
|
return mmr1;
|
||||||
|
}
|
||||||
|
|
||||||
/* PARs and PDRs. These are grouped in I/O space as follows:
|
/* PARs and PDRs. These are grouped in I/O space as follows:
|
||||||
|
|
||||||
17772200 - 17772276 supervisor block
|
17772200 - 17772276 supervisor block
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/* pdp11_fp.c: PDP-11 floating point simulator (32b version)
|
/* pdp11_fp.c: PDP-11 floating point simulator (32b version)
|
||||||
|
|
||||||
Copyright (c) 1993-2015, Robert M Supnik
|
Copyright (c) 1993-2018, Robert M Supnik
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
copy of this software and associated documentation files (the "Software"),
|
copy of this software and associated documentation files (the "Software"),
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
used in advertising or otherwise to promote the sale, use or other dealings
|
used in advertising or otherwise to promote the sale, use or other dealings
|
||||||
in this Software without prior written authorization from Robert M Supnik.
|
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)
|
||||||
24-Mar-15 RMS MMR1 does not track register changes (Johnny Billquist)
|
24-Mar-15 RMS MMR1 does not track register changes (Johnny Billquist)
|
||||||
20-Apr-13 RMS MMR1 does not track PC changes (Johnny Billquist)
|
20-Apr-13 RMS MMR1 does not track PC changes (Johnny Billquist)
|
||||||
22-Sep-05 RMS Fixed declarations (Sterling Garwood)
|
22-Sep-05 RMS Fixed declarations (Sterling Garwood)
|
||||||
@@ -248,9 +249,10 @@ static const uint32 and_mask[33] = { 0,
|
|||||||
int32 backup_PC;
|
int32 backup_PC;
|
||||||
int32 fp_change;
|
int32 fp_change;
|
||||||
|
|
||||||
int32 fpnotrap (int32 code);
|
t_bool fpnotrap (int32 code);
|
||||||
int32 GeteaFW (int32 spec);
|
int32 GeteaFW (int32 spec);
|
||||||
int32 GeteaFP (int32 spec, int32 len);
|
int32 GeteaFP (int32 spec, int32 len);
|
||||||
|
void fp_reg_change (int32 len, int32 reg);
|
||||||
uint32 ReadI (int32 addr, int32 spec, int32 len);
|
uint32 ReadI (int32 addr, int32 spec, int32 len);
|
||||||
t_bool ReadFP (fpac_t *fac, 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);
|
void WriteI (int32 data, int32 addr, int32 spec, int32 len);
|
||||||
@@ -606,33 +608,25 @@ switch (spec >> 3) { /* decode spec<5:3> */
|
|||||||
|
|
||||||
case 2: /* (R)+ */
|
case 2: /* (R)+ */
|
||||||
adr = R[reg]; /* post increment */
|
adr = R[reg]; /* post increment */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (2, reg); /* update */
|
||||||
R[reg] = (R[reg] + 2) & 0177777;
|
|
||||||
else fp_change = FPCHG (2, reg); /* others, update later */
|
|
||||||
return (adr | ds);
|
return (adr | ds);
|
||||||
|
|
||||||
case 3: /* @(R)+ */
|
case 3: /* @(R)+ */
|
||||||
adr = R[reg]; /* post increment */
|
adr = R[reg]; /* post increment */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (2, reg); /* update */
|
||||||
R[reg] = (R[reg] + 2) & 0177777;
|
|
||||||
else fp_change = FPCHG (2, reg); /* others, update later */
|
|
||||||
adr = ReadW (adr | ds);
|
adr = ReadW (adr | ds);
|
||||||
return (adr | dsenable);
|
return (adr | dsenable);
|
||||||
|
|
||||||
case 4: /* -(R) */
|
case 4: /* -(R) */
|
||||||
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (-2, reg); /* update */
|
||||||
R[reg] = adr;
|
|
||||||
else fp_change = FPCHG (-2, reg); /* others, update later */
|
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
return (adr | ds);
|
return (adr | ds);
|
||||||
|
|
||||||
case 5: /* @-(R) */
|
case 5: /* @-(R) */
|
||||||
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (-2, reg); /* update */
|
||||||
R[reg] = adr;
|
|
||||||
else fp_change = FPCHG (-2, reg); /* others, update later */
|
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
adr = ReadW (adr | ds);
|
adr = ReadW (adr | ds);
|
||||||
@@ -687,33 +681,27 @@ switch (spec >> 3) { /* case on spec */
|
|||||||
|
|
||||||
case 2: /* (R)+ */
|
case 2: /* (R)+ */
|
||||||
adr = R[reg]; /* post increment */
|
adr = R[reg]; /* post increment */
|
||||||
if (reg == 7) /* commit PC chg now */
|
if (reg == 7) /* # is always length 2 */
|
||||||
R[reg] = (R[reg] + 2) & 0177777;
|
len = 2;
|
||||||
else fp_change = FPCHG (len, reg); /* others, update later */
|
fp_reg_change (len, reg); /* update */
|
||||||
return (adr | ds);
|
return (adr | ds);
|
||||||
|
|
||||||
case 3: /* @(R)+ */
|
case 3: /* @(R)+ */
|
||||||
adr = R[reg]; /* post increment */
|
adr = R[reg]; /* post increment */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (2, reg); /* update */
|
||||||
R[reg] = (R[reg] + 2) & 0177777;
|
|
||||||
else fp_change = FPCHG (2, reg); /* others, update later */
|
|
||||||
adr = ReadW (adr | ds);
|
adr = ReadW (adr | ds);
|
||||||
return (adr | dsenable);
|
return (adr | dsenable);
|
||||||
|
|
||||||
case 4: /* -(R) */
|
case 4: /* -(R) */
|
||||||
adr = (R[reg] - len) & 0177777; /* predecrement */
|
adr = (R[reg] - len) & 0177777; /* predecrement */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (-len, reg); /* update */
|
||||||
R[reg] = adr;
|
|
||||||
else fp_change = FPCHG (-len, reg); /* others, udpate later */
|
|
||||||
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && (adr < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
return (adr | ds);
|
return (adr | ds);
|
||||||
|
|
||||||
case 5: /* @-(R) */
|
case 5: /* @-(R) */
|
||||||
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
adr = (R[reg] - 2) & 0177777; /* predecrement */
|
||||||
if (reg == 7) /* commit PC chg now */
|
fp_reg_change (-2, reg); /* update */
|
||||||
R[reg] = adr;
|
|
||||||
else fp_change = FPCHG (-2, reg); /* others, update later */
|
|
||||||
if ((reg == 6) && (cm == MD_KER) && ((adr - 2) < (STKLIM + STKL_Y)))
|
if ((reg == 6) && (cm == MD_KER) && ((adr - 2) < (STKLIM + STKL_Y)))
|
||||||
set_stack_trap (adr);
|
set_stack_trap (adr);
|
||||||
adr = ReadW (adr | ds);
|
adr = ReadW (adr | ds);
|
||||||
@@ -734,6 +722,35 @@ switch (spec >> 3) { /* case on spec */
|
|||||||
return 0;
|
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
|
/* Read integer operand
|
||||||
|
|
||||||
Inputs:
|
Inputs:
|
||||||
@@ -785,10 +802,12 @@ else {
|
|||||||
(ReadW (exta | ((VA + 6) & 0177777)) << FP_V_F3);
|
(ReadW (exta | ((VA + 6) & 0177777)) << FP_V_F3);
|
||||||
else fptr->l = 0;
|
else fptr->l = 0;
|
||||||
}
|
}
|
||||||
if ((GET_SIGN (fptr->h) != 0) &&
|
if ((GET_SIGN (fptr->h) != 0) && /* undef variable? */
|
||||||
(GET_EXP (fptr->h) == 0) &&
|
(GET_EXP (fptr->h) == 0) &&
|
||||||
(fpnotrap (FEC_UNDFV) == 0))
|
!fpnotrap (FEC_UNDFV)) { /* trap enabled? */
|
||||||
return FALSE;
|
fp_change = 0; /* J11, no reg changes */
|
||||||
|
return FALSE; /* NOP instruction */
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1393,7 +1412,7 @@ return 0;
|
|||||||
int = FALSE if interrupt enabled, TRUE if disabled
|
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 };
|
static const int32 test_code[] = { 0, 0, 0, FPS_IC, FPS_IV, FPS_IU, FPS_IUV };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user