PDP11: numerous 11/70 compatibility fixes
This commit is contained in:
parent
8e13ea1d21
commit
86a995b863
7 changed files with 139 additions and 66 deletions
|
@ -25,6 +25,20 @@
|
||||||
|
|
||||||
cpu PDP-11 CPU
|
cpu PDP-11 CPU
|
||||||
|
|
||||||
|
30-Nov022 RMS More 11/45,11/70 trap hackery (Walter Mueller)
|
||||||
|
29-Nov-22 RMS Trap stack abort must clear other traps/aborts (Walter Mueller)
|
||||||
|
23-Oct-22 RMS Fixed priority of MME traps (Walter Mueller)
|
||||||
|
02-Sep-22 RMS Fixed handling of PDR<A> (Walter Mueller)
|
||||||
|
31-Aug-22 RMS MMR0<15:13> != 0 locks bits<15:13> (Walter Mueller)
|
||||||
|
MMR0<12> = 1 disables further traps (Walter Mueller)
|
||||||
|
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
|
||||||
|
@ -373,22 +387,35 @@ extern int32 get_vector (int32 nipl);
|
||||||
/* Trap data structures */
|
/* Trap data structures */
|
||||||
|
|
||||||
int32 trap_vec[TRAP_V_MAX] = { /* trap req to vector */
|
int32 trap_vec[TRAP_V_MAX] = { /* trap req to vector */
|
||||||
VEC_RED, VEC_ODD, VEC_MME, VEC_NXM,
|
VEC_RED, VEC_ODD, VEC_NXM, VEC_MME,
|
||||||
VEC_PAR, VEC_PRV, VEC_ILL, VEC_BPT,
|
VEC_PAR, VEC_PRV, VEC_ILL, VEC_BPT,
|
||||||
VEC_IOT, VEC_EMT, VEC_TRAP, VEC_TRC,
|
VEC_IOT, VEC_EMT, VEC_TRAP, VEC_TRC,
|
||||||
VEC_YEL, VEC_PWRFL, VEC_FPE
|
VEC_YEL, VEC_PWRFL, VEC_FPE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
t_bool trap_load_mmr2[TRAP_V_MAX + 1] = { /* do trap requests load MMR2? */
|
||||||
|
TRUE, TRUE, TRUE, TRUE,
|
||||||
|
TRUE, FALSE, FALSE, FALSE,
|
||||||
|
FALSE, FALSE, FALSE, TRUE,
|
||||||
|
TRUE, TRUE, TRUE, TRUE /* last is interrupt */
|
||||||
|
};
|
||||||
|
|
||||||
int32 trap_clear[TRAP_V_MAX] = { /* trap clears */
|
int32 trap_clear[TRAP_V_MAX] = { /* trap clears */
|
||||||
TRAP_RED+TRAP_PAR+TRAP_YEL+TRAP_TRC+TRAP_ODD+TRAP_NXM,
|
TRAP_RED+TRAP_ODD+TRAP_NXM+TRAP_PAR+TRAP_YEL+TRAP_TRC+TRAP_MME, /* red stack abort */
|
||||||
TRAP_ODD+TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
TRAP_ODD+TRAP_NXM+TRAP_PAR+TRAP_YEL+TRAP_TRC+TRAP_MME, /* odd address abort */
|
||||||
TRAP_MME+TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
TRAP_NXM+TRAP_PAR+TRAP_YEL+TRAP_TRC+TRAP_MME, /* nxm abort */
|
||||||
TRAP_NXM+TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
TRAP_MME+TRAP_PAR+TRAP_YEL+TRAP_TRC, /* mme abort or trap */
|
||||||
TRAP_PAR+TRAP_TRC, TRAP_PRV+TRAP_TRC,
|
TRAP_PAR+TRAP_YEL+TRAP_TRC,
|
||||||
TRAP_ILL+TRAP_TRC, TRAP_BPT+TRAP_TRC,
|
TRAP_PRV+TRAP_TRC, /* instruction traps */
|
||||||
TRAP_IOT+TRAP_TRC, TRAP_EMT+TRAP_TRC,
|
TRAP_ILL+TRAP_TRC, /* occur in fetch or */
|
||||||
TRAP_TRAP+TRAP_TRC, TRAP_TRC,
|
TRAP_BPT+TRAP_TRC, /* initial decode */
|
||||||
TRAP_YEL, TRAP_PWRFL, TRAP_FPE
|
TRAP_IOT+TRAP_TRC, /* no yelstk possible */
|
||||||
|
TRAP_EMT+TRAP_TRC,
|
||||||
|
TRAP_TRAP+TRAP_TRC,
|
||||||
|
TRAP_TRC,
|
||||||
|
TRAP_YEL,
|
||||||
|
TRAP_PWRFL,
|
||||||
|
TRAP_FPE
|
||||||
};
|
};
|
||||||
|
|
||||||
/* CPU data structures
|
/* CPU data structures
|
||||||
|
@ -729,7 +756,7 @@ isenable = calc_is (cm);
|
||||||
dsenable = calc_ds (cm);
|
dsenable = calc_ds (cm);
|
||||||
put_PIRQ (PIRQ); /* rewrite PIRQ */
|
put_PIRQ (PIRQ); /* rewrite PIRQ */
|
||||||
STKLIM = STKLIM & STKLIM_RW; /* clean up STKLIM */
|
STKLIM = STKLIM & STKLIM_RW; /* clean up STKLIM */
|
||||||
MMR0 = MMR0 | MMR0_IC; /* usually on */
|
MMR0 = MMR0 & ~MMR0_IC; /* usually off */
|
||||||
|
|
||||||
trap_req = calc_ints (ipl, trap_req); /* upd int req */
|
trap_req = calc_ints (ipl, trap_req); /* upd int req */
|
||||||
trapea = 0;
|
trapea = 0;
|
||||||
|
@ -791,7 +818,8 @@ else {
|
||||||
(CPUT (STOP_STKA) || stop_spabort))
|
(CPUT (STOP_STKA) || stop_spabort))
|
||||||
reason = STOP_SPABORT;
|
reason = STOP_SPABORT;
|
||||||
if (trapea == ~MD_KER) { /* kernel stk abort? */
|
if (trapea == ~MD_KER) { /* kernel stk abort? */
|
||||||
setTRAP (TRAP_RED);
|
trap_req = trap_req & ~trap_clear[TRAP_RED];/* clear all traps */
|
||||||
|
setTRAP (TRAP_RED); /* set red stack trap */
|
||||||
setCPUERR (CPUE_RED);
|
setCPUERR (CPUE_RED);
|
||||||
STACKFILE[MD_KER] = 4;
|
STACKFILE[MD_KER] = 4;
|
||||||
if (cm == MD_KER)
|
if (cm == MD_KER)
|
||||||
|
@ -879,20 +907,19 @@ while (reason == 0) {
|
||||||
6. Update SP, PSW, and PC
|
6. Update SP, PSW, and PC
|
||||||
7. If not stack overflow, check for stack overflow
|
7. If not stack overflow, check for stack overflow
|
||||||
|
|
||||||
If the reads in step 3, or the writes in step 5, match a data breakpoint,
|
If the MMU registers are not frozen, the 11/45 and 11/70 will
|
||||||
the breakpoint status will be set but the interrupt actions will continue.
|
also clear MMR1 and store the trap vector in MMR2, <except>
|
||||||
The breakpoint stop will occur at the beginning of the next instruction
|
for the four instruction traps (EMT, TRAP, IOT, BPT).
|
||||||
cycle.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
wait_state = 0; /* exit wait state */
|
wait_state = 0; /* exit wait state */
|
||||||
STACKFILE[cm] = SP;
|
STACKFILE[cm] = SP;
|
||||||
PSW = get_PSW (); /* assemble PSW */
|
PSW = get_PSW (); /* assemble PSW */
|
||||||
oldrs = rs;
|
oldrs = rs;
|
||||||
if (CPUT (HAS_MMTR)) { /* 45,70? */
|
if ((CPUT (HAS_MMTR)) && (update_MM)) { /* 45,70, not frozen? */
|
||||||
if (update_MM) /* save vector */
|
MMR1 = 0; /* clear MMR1 */
|
||||||
MMR2 = trapea;
|
if (trap_load_mmr2[trapnum]) /* load MMR2? */
|
||||||
MMR0 = MMR0 & ~MMR0_IC; /* clear IC */
|
MMR2 = trapea; /* save vector */
|
||||||
}
|
}
|
||||||
src = ReadCW (trapea | calc_ds (MD_KER)); /* new PC */
|
src = ReadCW (trapea | calc_ds (MD_KER)); /* new PC */
|
||||||
src2 = ReadCW ((trapea + 2) | calc_ds (MD_KER)); /* new PSW */
|
src2 = ReadCW ((trapea + 2) | calc_ds (MD_KER)); /* new PSW */
|
||||||
|
@ -917,7 +944,6 @@ while (reason == 0) {
|
||||||
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)) &&
|
if ((cm == MD_KER) && (SP < (STKLIM + STKL_Y)) &&
|
||||||
(trapnum != TRAP_V_RED) && (trapnum != TRAP_V_YEL))
|
(trapnum != TRAP_V_RED) && (trapnum != TRAP_V_YEL))
|
||||||
set_stack_trap (SP);
|
set_stack_trap (SP);
|
||||||
MMR0 = MMR0 | MMR0_IC; /* back to instr */
|
|
||||||
continue; /* end if traps */
|
continue; /* end if traps */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2887,14 +2913,16 @@ switch (apr & PDR_ACF) { /* case on ACF */
|
||||||
|
|
||||||
case 1: case 4: /* trap read */
|
case 1: case 4: /* trap read */
|
||||||
if (CPUT (HAS_MMTR)) { /* traps implemented? */
|
if (CPUT (HAS_MMTR)) { /* traps implemented? */
|
||||||
APRFILE[apridx] = APRFILE[apridx] | PDR_A; /* set A */
|
int32 old_mmr0 = MMR0;
|
||||||
if (MMR0 & MMR0_TENB) { /* traps enabled? */
|
APRFILE[apridx] |= PDR_A; /* set A */
|
||||||
|
MMR0 = MMR0 | MMR0_TRAP; /* set trap flag */
|
||||||
|
if ((MMR0 & MMR0_TENB) != 0) { /* traps enabled? */
|
||||||
if (update_MM) /* update MMR0 */
|
if (update_MM) /* update MMR0 */
|
||||||
MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
||||||
MMR0 = MMR0 | MMR0_TRAP; /* set trap flag */
|
if ((old_mmr0 & MMR0_TRAP) == 0) /* first trap? */
|
||||||
setTRAP (TRAP_MME); /* set trap */
|
setTRAP (TRAP_MME); /* set trap */
|
||||||
}
|
}
|
||||||
return; /* continue op */
|
return; /* continue */
|
||||||
} /* not impl, abort NR */
|
} /* not impl, abort NR */
|
||||||
case 0: case 3: case 7: /* non-resident */
|
case 0: case 3: case 7: /* non-resident */
|
||||||
err = MMR0_NR; /* set MMR0 */
|
err = MMR0_NR; /* set MMR0 */
|
||||||
|
@ -2920,10 +2948,10 @@ return ((apr & PDR_ED)? (dbn < plf): (dbn > plf)); /* pg lnt error? */
|
||||||
|
|
||||||
void reloc_abort (int32 err, int32 apridx)
|
void reloc_abort (int32 err, int32 apridx)
|
||||||
{
|
{
|
||||||
if (update_MM) MMR0 = /* update MMR0 */
|
if (update_MM) { /* MMR0 not frozen? */
|
||||||
(MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE); /* record page */
|
||||||
APRFILE[apridx] = APRFILE[apridx] | PDR_A; /* set A */
|
MMR0 = MMR0 | err; /* OR in aborts */
|
||||||
MMR0 = MMR0 | err; /* set aborts */
|
}
|
||||||
ABORT (TRAP_MME); /* abort ref */
|
ABORT (TRAP_MME); /* abort ref */
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2955,7 +2983,7 @@ if (MMR0 & MMR0_MME) { /* if mmgt */
|
||||||
relocW_test (va, apridx); /* long test */
|
relocW_test (va, apridx); /* long test */
|
||||||
if (PLF_test (va, apr)) /* pg lnt error? */
|
if (PLF_test (va, apr)) /* pg lnt error? */
|
||||||
reloc_abort (MMR0_PL, apridx);
|
reloc_abort (MMR0_PL, apridx);
|
||||||
APRFILE[apridx] = apr | PDR_W; /* set W */
|
APRFILE[apridx] |= PDR_W; /* set W */
|
||||||
pa = ((va & VA_DF) + ((apr >> 10) & 017777700)) & PAMASK;
|
pa = ((va & VA_DF) + ((apr >> 10) & 017777700)) & PAMASK;
|
||||||
if ((MMR3 & MMR3_M22E) == 0) {
|
if ((MMR3 & MMR3_M22E) == 0) {
|
||||||
pa = pa & 0777777;
|
pa = pa & 0777777;
|
||||||
|
@ -2995,14 +3023,16 @@ switch (apr & PDR_ACF) { /* case on ACF */
|
||||||
|
|
||||||
case 4: case 5: /* trap write */
|
case 4: case 5: /* trap write */
|
||||||
if (CPUT (HAS_MMTR)) { /* traps implemented? */
|
if (CPUT (HAS_MMTR)) { /* traps implemented? */
|
||||||
APRFILE[apridx] = APRFILE[apridx] | PDR_A; /* set A */
|
int32 old_mmr0 = MMR0;
|
||||||
if (MMR0 & MMR0_TENB) { /* traps enabled? */
|
APRFILE[apridx] |= PDR_A; /* set PDR <A> */
|
||||||
|
MMR0 = MMR0 | MMR0_TRAP; /* set trap flag */
|
||||||
|
if ((MMR0 & MMR0_TENB) != 0) { /* traps enabled? */
|
||||||
if (update_MM) /* update MMR0 */
|
if (update_MM) /* update MMR0 */
|
||||||
MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
MMR0 = (MMR0 & ~MMR0_PAGE) | (apridx << MMR0_V_PAGE);
|
||||||
MMR0 = MMR0 | MMR0_TRAP; /* set trap flag */
|
if ((old_mmr0 & MMR0_TRAP) == 0) /* first trap? */
|
||||||
setTRAP (TRAP_MME); /* set trap */
|
setTRAP (TRAP_MME); /* set trap */
|
||||||
}
|
}
|
||||||
return; /* continue op */
|
return; /* continue, set A */
|
||||||
} /* not impl, abort NR */
|
} /* not impl, abort NR */
|
||||||
case 0: case 3: case 7: /* non-resident */
|
case 0: case 3: case 7: /* non-resident */
|
||||||
err = MMR0_NR; /* MMR0 status */
|
err = MMR0_NR; /* MMR0 status */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_cpumod.c: PDP-11 CPU model-specific features
|
/* pdp11_cpumod.c: PDP-11 CPU model-specific features
|
||||||
|
|
||||||
Copyright (c) 2004-2020, Robert M Supnik
|
Copyright (c) 2004-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,7 @@
|
||||||
|
|
||||||
system PDP-11 model-specific registers
|
system PDP-11 model-specific registers
|
||||||
|
|
||||||
|
19-Nov-22 RMS Fixed byte access errors in PIRQ, STKLIM, CDR (Walter Mueller)
|
||||||
15-Sep-20 RMS Fixed problem in KDJ11E programmable clock (Paul Koning)
|
15-Sep-20 RMS Fixed problem in KDJ11E programmable clock (Paul Koning)
|
||||||
04-Mar-16 RMS Fixed maximum memory sizes to exclude IO page
|
04-Mar-16 RMS Fixed maximum memory sizes to exclude IO page
|
||||||
14-Mar-16 RMS Modified to keep cpu_memsize in sync with MEMSIZE
|
14-Mar-16 RMS Modified to keep cpu_memsize in sync with MEMSIZE
|
||||||
|
@ -49,12 +50,21 @@
|
||||||
#include "pdp11_defs.h"
|
#include "pdp11_defs.h"
|
||||||
#include "pdp11_cpumod.h"
|
#include "pdp11_cpumod.h"
|
||||||
|
|
||||||
/* Byte write macros for system registers */
|
/* Byte write macros for system registers
|
||||||
|
|
||||||
|
EVN_IGN byte writes to the even byte are ignored
|
||||||
|
ODD_IGN byte writes to the odd byte are ignored
|
||||||
|
ODD_SHF byte writes to the odd byte zero the even byte
|
||||||
|
ODD_MRG byte writes write appropriate byte
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define EVN_IGN(cur) \
|
||||||
|
if ((access == WRITEB) && ((pa & 1) == 0)) \
|
||||||
|
return SCPE_OK
|
||||||
#define ODD_IGN(cur) \
|
#define ODD_IGN(cur) \
|
||||||
if ((access == WRITEB) && (pa & 1)) \
|
if ((access == WRITEB) && (pa & 1)) \
|
||||||
return SCPE_OK
|
return SCPE_OK
|
||||||
#define ODD_WO(cur) \
|
#define ODD_SHF(cur) \
|
||||||
if ((access == WRITEB) && (pa & 1)) \
|
if ((access == WRITEB) && (pa & 1)) \
|
||||||
cur = cur << 8
|
cur = cur << 8
|
||||||
#define ODD_MRG(prv,cur) \
|
#define ODD_MRG(prv,cur) \
|
||||||
|
@ -475,7 +485,8 @@ switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 015: /* PIRQ */
|
case 015: /* PIRQ */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
put_PIRQ (data);
|
put_PIRQ (data);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -511,12 +522,14 @@ t_stat CPU45_wr (int32 data, int32 pa, int32 access)
|
||||||
switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
|
|
||||||
case 015: /* PIRQ */
|
case 015: /* PIRQ */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
put_PIRQ (data);
|
put_PIRQ (data);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 016: /* STKLIM */
|
case 016: /* STKLIM */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
STKLIM = data & STKLIM_RW;
|
STKLIM = data & STKLIM_RW;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
} /* end switch pa */
|
} /* end switch pa */
|
||||||
|
@ -590,7 +603,8 @@ switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 016: /* STKLIM */
|
case 016: /* STKLIM */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
STKLIM = data & STKLIM_RW;
|
STKLIM = data & STKLIM_RW;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
} /* end switch pa */
|
} /* end switch pa */
|
||||||
|
@ -661,12 +675,19 @@ switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
return SCPE_NXM; /* unimplemented */
|
return SCPE_NXM; /* unimplemented */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* From Walter Mueller: MEMERR is always written using the standard data
|
||||||
|
on the bus: the whole word for DATO, the high byte for DATOB odd,
|
||||||
|
and the low byte with DATOB even. The simulator always puts a byte
|
||||||
|
in the low 8 bits, so for an odd byte reference, it must be shifted
|
||||||
|
to the high byte.
|
||||||
|
*/
|
||||||
|
|
||||||
t_stat CPU70_wr (int32 data, int32 pa, int32 access)
|
t_stat CPU70_wr (int32 data, int32 pa, int32 access)
|
||||||
{
|
{
|
||||||
switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
|
|
||||||
case 002: /* MEMERR */
|
case 002: /* MEMERR */
|
||||||
ODD_WO (data);
|
ODD_SHF (data);
|
||||||
MEMERR = MEMERR & ~data;
|
MEMERR = MEMERR & ~data;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
|
@ -697,12 +718,14 @@ switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 015: /* PIRQ */
|
case 015: /* PIRQ */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
put_PIRQ (data);
|
put_PIRQ (data);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 016: /* STKLIM */
|
case 016: /* STKLIM */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
STKLIM = data & STKLIM_RW;
|
STKLIM = data & STKLIM_RW;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
} /* end switch pa */
|
} /* end switch pa */
|
||||||
|
@ -779,7 +802,8 @@ switch ((pa >> 1) & 017) { /* decode pa<4:1> */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 015: /* PIRQ */
|
case 015: /* PIRQ */
|
||||||
ODD_WO (data);
|
EVN_IGN (data);
|
||||||
|
ODD_SHF (data);
|
||||||
put_PIRQ (data);
|
put_PIRQ (data);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
} /* end switch pa */
|
} /* end switch pa */
|
||||||
|
@ -818,12 +842,14 @@ switch ((pa >> 1) & 03) { /* decode pa<2:1> */
|
||||||
ODD_MRG (JPCR, data);
|
ODD_MRG (JPCR, data);
|
||||||
JPCR = data & PCRFB_RW;
|
JPCR = data & PCRFB_RW;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 1: /* MAINT */
|
case 1: /* MAINT */
|
||||||
ODD_MRG (MAINT, data);
|
ODD_MRG (MAINT, data);
|
||||||
MAINT = data;
|
MAINT = data;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 2: /* CDR */
|
case 2: /* CDR */
|
||||||
ODD_WO (data);
|
ODD_IGN (data);
|
||||||
DR = data & CDRFB_WR;
|
DR = data & CDRFB_WR;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -881,7 +907,7 @@ switch ((pa >> 1) & 03) { /* decode pa<2:1> */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 2: /* CDR */
|
case 2: /* CDR */
|
||||||
ODD_WO (data);
|
ODD_IGN (data);
|
||||||
DR = data & CDRJB_WR;
|
DR = data & CDRJB_WR;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
@ -972,7 +998,7 @@ switch ((pa >> 1) & 03) { /* decode pa<2:1> */
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
case 2: /* CDR */
|
case 2: /* CDR */
|
||||||
ODD_WO (data);
|
ODD_IGN (data);
|
||||||
DR = data & CDRJE_WR;
|
DR = data & CDRJE_WR;
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
The author gratefully acknowledges the help of Max Burnet, Megan Gentry,
|
||||||
and John Wilson in resolving questions about the PDP-11
|
and John Wilson in resolving questions about the PDP-11
|
||||||
|
|
||||||
|
23-Oct-22 RMS Moved NXM abort priority above MME trap priority
|
||||||
|
25-Jul-22 RMS Removed OPT_RH11 (Mark Pizzolato)
|
||||||
10-Feb-17 RMS Fixed RJS11 register block length (Mark Hill)
|
10-Feb-17 RMS Fixed RJS11 register block length (Mark Hill)
|
||||||
19-Jan-17 RMS Moved CR11 to BR6, leaving CD11 at BR4 (Mark Pizzolato)
|
19-Jan-17 RMS Moved CR11 to BR6, leaving CD11 at BR4 (Mark Pizzolato)
|
||||||
10-Mar-16 RMS Added UC15 support
|
10-Mar-16 RMS Added UC15 support
|
||||||
|
@ -409,14 +411,17 @@ typedef struct {
|
||||||
#define CSR_BUSY (1u << CSR_V_BUSY)
|
#define CSR_BUSY (1u << CSR_V_BUSY)
|
||||||
#define CSR_ERR (1u << CSR_V_ERR)
|
#define CSR_ERR (1u << CSR_V_ERR)
|
||||||
|
|
||||||
/* Trap masks, descending priority order, following J-11
|
/* Trap masks, descending priority order. Rules:
|
||||||
An interrupt summary bit is kept with traps, to minimize overhead
|
|
||||||
|
- Aborts are mutually exclusive, no more than one per instrution.
|
||||||
|
- Aborts must be higher priority than traps. Because MME can be
|
||||||
|
either an abort or a trap, it is lower priority than NXM.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define TRAP_V_RED 0 /* red stk abort 4 */
|
#define TRAP_V_RED 0 /* red stk abort 4 */
|
||||||
#define TRAP_V_ODD 1 /* odd address 4 */
|
#define TRAP_V_ODD 1 /* odd address 4 */
|
||||||
#define TRAP_V_MME 2 /* mem mgt 250 */
|
#define TRAP_V_NXM 2 /* nx memory 4 */
|
||||||
#define TRAP_V_NXM 3 /* nx memory 4 */
|
#define TRAP_V_MME 3 /* mem mgt 250 */
|
||||||
#define TRAP_V_PAR 4 /* parity err 114 */
|
#define TRAP_V_PAR 4 /* parity err 114 */
|
||||||
#define TRAP_V_PRV 5 /* priv inst 4 */
|
#define TRAP_V_PRV 5 /* priv inst 4 */
|
||||||
#define TRAP_V_ILL 6 /* illegal inst 10 */
|
#define TRAP_V_ILL 6 /* illegal inst 10 */
|
||||||
|
|
|
@ -23,6 +23,9 @@
|
||||||
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.
|
||||||
|
|
||||||
|
10-Dec-22 RMS Fixed bug in FUIV operation (James Fehlinger)
|
||||||
|
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)
|
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)
|
||||||
|
@ -86,12 +89,17 @@
|
||||||
accessed; if the operand is 32b or 64b, these
|
accessed; if the operand is 32b or 64b, these
|
||||||
are the high order 16b of the operand.
|
are the high order 16b of the operand.
|
||||||
|
|
||||||
The FP11 cannot update MMR1 on specifier changes, because the
|
The J11 cannot update MMR1 on specifier changes, because the
|
||||||
quantity field is too narrow for +8 or -8. Instead, the simulator
|
quantity field is too narrow for +8 or -8. However, the 11/44 and
|
||||||
records changes to be made and only commits them at instruction
|
11/70 can. So the simulator treats the two cases differently.
|
||||||
completion. Instructions that can overwrite a general register
|
On the J11, the simulator records changes to be made and only
|
||||||
(STFPS, STST, STEXP, STCFi in mode 0) need not check for conflicts;
|
commits them at instruction. On all other systems, changes occur
|
||||||
in mode 0, no general register changes occur in the specifier flow.
|
as they happen and are recorded in MMR1. However, all systems
|
||||||
|
update the general registers on floating point exceptions. Thus,
|
||||||
|
when an exception occurs, the simulator in most cases cannot
|
||||||
|
abort but must let the instruction "run to completion." For
|
||||||
|
undefined variable and divide by zero, this means skipping
|
||||||
|
the actual processing logic.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pdp11_defs.h"
|
#include "pdp11_defs.h"
|
||||||
|
@ -787,8 +795,9 @@ else {
|
||||||
}
|
}
|
||||||
if ((GET_SIGN (fptr->h) != 0) &&
|
if ((GET_SIGN (fptr->h) != 0) &&
|
||||||
(GET_EXP (fptr->h) == 0) &&
|
(GET_EXP (fptr->h) == 0) &&
|
||||||
(fpnotrap (FEC_UNDFV) == 0))
|
!fpnotrap (FEC_UNDFV)) { /* trap enabled? */
|
||||||
return FALSE;
|
return FALSE; /* NOP instruction */
|
||||||
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* pdp11_rk.c: RK11/RKV11 cartridge disk simulator
|
/* pdp11_rk.c: RK11/RKV11 cartridge disk 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,7 @@
|
||||||
|
|
||||||
rk RK11/RKV11/RK05 cartridge disk
|
rk RK11/RKV11/RK05 cartridge disk
|
||||||
|
|
||||||
|
28-Nov-22 RMS Fixed word count adjustment on NXM (Anthony Lawrence)
|
||||||
12-Mar-16 RMS Revised to support UC15 (18b IO)
|
12-Mar-16 RMS Revised to support UC15 (18b IO)
|
||||||
23-Oct-13 RMS Revised for new boot setup routine
|
23-Oct-13 RMS Revised for new boot setup routine
|
||||||
20-Mar-09 RMS Fixed bug in read header (Walter F Mueller)
|
20-Mar-09 RMS Fixed bug in read header (Walter F Mueller)
|
||||||
|
@ -816,6 +817,7 @@ if ((uptr->FUNC == RKCS_READ) && (rkcs & RKCS_FMT)) /* read format? */
|
||||||
else da = da + wc + (RK_NUMWD - 1); /* count by words */
|
else da = da + wc + (RK_NUMWD - 1); /* count by words */
|
||||||
track = (da / RK_NUMWD) / RK_NUMSC;
|
track = (da / RK_NUMWD) / RK_NUMSC;
|
||||||
sect = (da / RK_NUMWD) % RK_NUMSC;
|
sect = (da / RK_NUMWD) % RK_NUMSC;
|
||||||
|
uptr->CYL = track / RK_NUMSF; /* update position */
|
||||||
rkda = (rkda & RKDA_DRIVE) | (track << RKDA_V_TRACK) | (sect << RKDA_V_SECT);
|
rkda = (rkda & RKDA_DRIVE) | (track << RKDA_V_TRACK) | (sect << RKDA_V_SECT);
|
||||||
rk_set_done (0);
|
rk_set_done (0);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
rl RL11(RLV12)/RL01/RL02 cartridge disk
|
rl RL11(RLV12)/RL01/RL02 cartridge disk
|
||||||
|
|
||||||
|
28-Nov-22 RMS Fixed word count adjustment on NXM
|
||||||
23-Oct-13 RMS Revised for new boot setup routine
|
23-Oct-13 RMS Revised for new boot setup routine
|
||||||
24-Mar-11 JAD Various changes to support diagnostics, including:
|
24-Mar-11 JAD Various changes to support diagnostics, including:
|
||||||
- distinguish between RLV11 & 12
|
- distinguish between RLV11 & 12
|
||||||
|
|
Loading…
Add table
Reference in a new issue