All VAX: Always return the correct Qbus/Unibus interrupt vector bits for all devices. Fix #239
Vector values contained in device information blocks are the true bus relative vector values. CPU specific biased vector values are produced by the respective vector fetching logic and vector values are limited to 9 bits with <1:0> = 0 as specified in both the Unibus and Qbus documents.
This commit is contained in:
parent
b05c7419f0
commit
ed57f061e2
24 changed files with 176 additions and 59 deletions
|
@ -751,7 +751,6 @@ typedef struct pdp_dib DIB;
|
|||
#define INT_IPL5 0x000FFF00
|
||||
#define INT_IPL4 0x7FF00000
|
||||
|
||||
#define VEC_Q 0000 /* vector base */
|
||||
#define VEC_TU 0224 /* interrupt vectors */
|
||||
#define VEC_RP 0254
|
||||
#define VEC_LP20 0754
|
||||
|
|
|
@ -1773,9 +1773,9 @@ if (dptr == NULL)
|
|||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
newvec = (uint32) get_uint (cptr, 8, VEC_Q + 01000, &r);
|
||||
if ((r != SCPE_OK) || (newvec == VEC_Q) ||
|
||||
((newvec + (dibp->vnum * 4)) >= (VEC_Q + 01000)) ||
|
||||
newvec = (uint32) get_uint (cptr, 8, 01000, &r);
|
||||
if ((r != SCPE_OK) ||
|
||||
((newvec + (dibp->vnum * 4)) >= (01000)) ||
|
||||
(newvec & ((dibp->vnum > 1)? 07: 03)))
|
||||
return SCPE_ARG;
|
||||
dibp->vec = newvec;
|
||||
|
@ -2217,7 +2217,7 @@ AUTO_CON auto_tab[] = {/*c #v am vm fxa fxv */
|
|||
t_stat auto_config (const char *name, int32 nctrl)
|
||||
{
|
||||
uint32 csr = IOPAGEBASE + AUTO_CSRBASE;
|
||||
uint32 vec = VEC_Q + AUTO_VECBASE;
|
||||
uint32 vec = AUTO_VECBASE;
|
||||
AUTO_CON *autp;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
|
@ -2260,7 +2260,7 @@ for (autp = auto_tab; autp->numc >= 0; autp++) { /* loop thru table */
|
|||
if (autp->numv) { /* vec needed? */
|
||||
if (autp->fixv[j]) { /* fixed vec avail? */
|
||||
if (autp->numv > 0)
|
||||
dibp->vec = VEC_Q + autp->fixv[j]; /* use it */
|
||||
dibp->vec = autp->fixv[j]; /* use it */
|
||||
}
|
||||
else { /* no fixed left */
|
||||
uint32 numv = abs (autp->numv); /* get num vec */
|
||||
|
|
|
@ -765,8 +765,6 @@ typedef struct pdp_dib DIB;
|
|||
#define VEC_AUTO (0) /* Assigned by Auto Configure */
|
||||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_Q 0000 /* vector base */
|
||||
|
||||
/* Processor specific internal fixed vectors */
|
||||
#define VEC_PIRQ 0240
|
||||
#define VEC_TTI 0060
|
||||
|
|
|
@ -157,7 +157,8 @@ for (i = IPL_HLVL - 1; i > nipl; i--) { /* loop thru lvls */
|
|||
int_req[i] = int_req[i] & ~(1u << j); /* clr irq */
|
||||
if (int_ack[i][j])
|
||||
vec = int_ack[i][j]();
|
||||
else vec = int_vec[i][j];
|
||||
else
|
||||
vec = int_vec[i][j];
|
||||
return vec; /* return vector */
|
||||
} /* end if t */
|
||||
} /* end for j */
|
||||
|
|
|
@ -39,6 +39,12 @@
|
|||
|
||||
extern int32 autcon_enb;
|
||||
extern int32 int_vec[IPL_HLVL][32];
|
||||
#if !defined(VEC_SET)
|
||||
#define VEC_SET 0
|
||||
#endif
|
||||
#if (VEC_SET != 0)
|
||||
extern int32 int_vec_set[IPL_HLVL][32]; /* bits to set in vector */
|
||||
#endif
|
||||
extern int32 (*int_ack[IPL_HLVL][32])(void);
|
||||
extern t_stat (*iodispR[IOPAGESIZE >> 1])(int32 *dat, int32 ad, int32 md);
|
||||
extern t_stat (*iodispW[IOPAGESIZE >> 1])(int32 dat, int32 ad, int32 md);
|
||||
|
@ -47,6 +53,8 @@ extern t_stat build_dib_tab (void);
|
|||
|
||||
static DIB *iodibp[IOPAGESIZE >> 1];
|
||||
|
||||
static void build_vector_tab (void);
|
||||
|
||||
#if !defined(UNIMEMSIZE)
|
||||
#define UNIMEMSIZE 001000000 /* 2**18 */
|
||||
#endif
|
||||
|
@ -181,10 +189,10 @@ if (dptr == NULL)
|
|||
dibp = (DIB *) dptr->ctxt;
|
||||
if (dibp == NULL)
|
||||
return SCPE_IERR;
|
||||
newvec = (uint32) get_uint (cptr, DEV_RDX, VEC_Q + 01000, &r);
|
||||
if ((r != SCPE_OK) || (newvec == VEC_Q) ||
|
||||
((newvec + (dibp->vnum * 4)) >= (VEC_Q + 01000)) ||
|
||||
(newvec & ((dibp->vnum > 1)? 07: 03)))
|
||||
newvec = (uint32) get_uint (cptr, DEV_RDX, 01000, &r);
|
||||
if ((r != SCPE_OK) ||
|
||||
((newvec + (dibp->vnum * 4)) >= 01000) || /* total too big? */
|
||||
(newvec & ((dibp->vnum > 1)? 07: 03))) /* properly aligned value? */
|
||||
return SCPE_ARG;
|
||||
dibp->vec = newvec;
|
||||
autcon_enb = 0; /* autoconfig off */
|
||||
|
@ -214,10 +222,15 @@ if (sim_switches & SWMASK ('O'))
|
|||
vec = dibp->vec;
|
||||
if (arg)
|
||||
numvec = arg;
|
||||
else numvec = dibp->vnum;
|
||||
else
|
||||
numvec = dibp->vnum;
|
||||
if (vec == 0)
|
||||
fprintf (st, "no vector");
|
||||
else {
|
||||
#if (VEC_SET != 0)
|
||||
vec |= (int_vec_set[dibp->vloc / 32][dibp->vloc % 32] & ~3);
|
||||
vec &= (int_vec_set[dibp->vloc / 32][dibp->vloc % 32] | 0x1FF);
|
||||
#endif
|
||||
fprintf (st, "vector=");
|
||||
fprint_val (st, (t_value) vec, DEV_RDX, 16, PV_LEFT);
|
||||
if (radix != DEV_RDX) {
|
||||
|
@ -235,7 +248,7 @@ else {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (vec >= VEC_Q + AUTO_VECBASE)
|
||||
if (vec >= ((VEC_SET | AUTO_VECBASE) & ~3))
|
||||
fprintf (st, "*");
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
@ -257,6 +270,7 @@ void init_ubus_tab (void)
|
|||
{
|
||||
size_t i, j;
|
||||
|
||||
build_vector_tab ();
|
||||
for (i = 0; i < IPL_HLVL; i++) { /* clear intr tab */
|
||||
for (j = 0; j < 32; j++) {
|
||||
int_vec[i][j] = 0;
|
||||
|
@ -285,6 +299,12 @@ if ((dptr == NULL) || (dibp == NULL)) /* validate args */
|
|||
if (dibp->vnum > VEC_DEVMAX)
|
||||
return SCPE_IERR;
|
||||
vec = dibp->vec;
|
||||
ilvl = dibp->vloc / 32;
|
||||
ibit = dibp->vloc % 32;
|
||||
#if (VEC_SET != 0)
|
||||
if (vec)
|
||||
vec |= (int_vec_set[ilvl][ibit] & ~3);
|
||||
#endif
|
||||
/* hivec & cdhivec are first vector AFTER device */
|
||||
hivec = vec + (dibp->vnum * 4 * (dibp->ulnt? dibp->lnt/dibp->ulnt:
|
||||
(dptr->numunits? dptr->numunits: 1)));
|
||||
|
@ -296,10 +316,17 @@ if (vec && !(sim_switches & SWMASK ('P'))) {
|
|||
for (j = 0; vec && (cdptr = sim_devices[j]) != NULL; j++) {
|
||||
DIB *cdibp = (DIB *)(cdptr->ctxt);
|
||||
int32 cdvec, cdhivec;
|
||||
|
||||
if (!cdibp || (cdptr->flags & DEV_DIS)) {
|
||||
continue;
|
||||
}
|
||||
cdvec = cdibp->vec;
|
||||
ilvl = cdibp->vloc / 32;
|
||||
ibit = cdibp->vloc % 32;
|
||||
#if (VEC_SET != 0)
|
||||
if (cdvec)
|
||||
cdvec |= (int_vec_set[ilvl][ibit] & ~3);
|
||||
#endif
|
||||
cdhivec = cdvec + (cdibp->vnum * 4 *
|
||||
(cdibp->ulnt? cdibp->lnt/cdibp->ulnt:
|
||||
(cdptr->numunits? cdptr->numunits: 1)));
|
||||
|
@ -326,6 +353,10 @@ for (i = 0; i < dibp->vnum; i++) { /* loop thru vec */
|
|||
vec = dibp->vec? (dibp->vec + (i * 4)): 0; /* vector addr */
|
||||
ilvl = idx / 32;
|
||||
ibit = idx % 32;
|
||||
#if (VEC_SET != 0)
|
||||
if (vec)
|
||||
vec |= (int_vec_set[ilvl][ibit] & ~3);
|
||||
#endif
|
||||
if ((int_ack[ilvl][ibit] && dibp->ack[i] && /* conflict? */
|
||||
(int_ack[ilvl][ibit] != dibp->ack[i])) ||
|
||||
(int_vec[ilvl][ibit] && vec &&
|
||||
|
@ -336,8 +367,10 @@ for (i = 0; i < dibp->vnum; i++) { /* loop thru vec */
|
|||
}
|
||||
if (dibp->ack[i])
|
||||
int_ack[ilvl][ibit] = dibp->ack[i];
|
||||
else if (vec)
|
||||
int_vec[ilvl][ibit] = vec;
|
||||
else {
|
||||
if (vec)
|
||||
int_vec[ilvl][ibit] = vec;
|
||||
}
|
||||
}
|
||||
/* Register I/O space address and check for conflicts */
|
||||
for (i = 0; i < (int32) dibp->lnt; i = i + 2) { /* create entries */
|
||||
|
@ -750,10 +783,44 @@ AUTO_CON auto_tab[] = {/*c #v am vm fxa fxv */
|
|||
#define DEV_NEXUS 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static void build_vector_tab (void)
|
||||
{
|
||||
int32 ilvl, ibit;
|
||||
static t_bool done = FALSE;
|
||||
AUTO_CON *autp;
|
||||
DEVICE *dptr;
|
||||
DIB *dibp;
|
||||
uint32 j, k;
|
||||
|
||||
if (done)
|
||||
return;
|
||||
/* Locate all Unibus/Qbus devices and make sure vector masks are set */
|
||||
for (j = 0; (dptr = sim_devices[j]) != NULL; j++) {
|
||||
if ((dptr->flags & (DEV_UBUS | DEV_QBUS)) == 0)
|
||||
continue;
|
||||
for (autp = auto_tab; autp->numc >= 0; autp++) {
|
||||
for (k=0; autp->dnam[k]; k++) {
|
||||
if (!strcmp(dptr->name, autp->dnam[k])) {
|
||||
dibp = (DIB *)dptr->ctxt;
|
||||
ilvl = dibp->vloc / 32;
|
||||
ibit = dibp->vloc % 32;
|
||||
#if (VEC_SET != 0)
|
||||
int_vec_set[ilvl][ibit] = VEC_SET;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
t_stat auto_config (const char *name, int32 nctrl)
|
||||
{
|
||||
uint32 csr = IOPAGEBASE + AUTO_CSRBASE;
|
||||
uint32 vec = VEC_Q + AUTO_VECBASE;
|
||||
uint32 vec = AUTO_VECBASE;
|
||||
int32 ilvl, ibit;
|
||||
extern UNIT cpu_unit;
|
||||
AUTO_CON *autp;
|
||||
DEVICE *dptr;
|
||||
|
@ -803,6 +870,8 @@ for (autp = auto_tab; autp->numc >= 0; autp++) { /* loop thru table */
|
|||
dibp = (DIB *) dptr->ctxt; /* get DIB */
|
||||
if (dibp == NULL) /* not there??? */
|
||||
return SCPE_IERR;
|
||||
ilvl = dibp->vloc / 32;
|
||||
ibit = dibp->vloc % 32;
|
||||
if (autp->fixa[j]) /* fixed csr avail? */
|
||||
dibp->ba = IOPAGEBASE + autp->fixa[j]; /* use it */
|
||||
else { /* no fixed left */
|
||||
|
@ -812,7 +881,7 @@ for (autp = auto_tab; autp->numc >= 0; autp++) { /* loop thru table */
|
|||
if (autp->numv) { /* vec needed? */
|
||||
if (autp->fixv[j]) { /* fixed vec avail? */
|
||||
if (autp->numv > 0)
|
||||
dibp->vec = VEC_Q + autp->fixv[j]; /* use it */
|
||||
dibp->vec = autp->fixv[j]; /* use it */
|
||||
}
|
||||
else { /* no fixed left */
|
||||
uint32 numv = abs (autp->numv); /* get num vec */
|
||||
|
|
|
@ -1465,8 +1465,6 @@ if (cp->csta < CST_UP) { /* still init? */
|
|||
else {
|
||||
cp->s1dat = cp->saw; /* save data */
|
||||
dibp->vec = (cp->s1dat & SA_S1H_VEC) << 2; /* get vector */
|
||||
if (dibp->vec) /* if nz, bias */
|
||||
dibp->vec = dibp->vec + VEC_Q;
|
||||
cp->sa = SA_S2 | SA_S2C_PT | SA_S2C_EC (cp->s1dat);
|
||||
cp->csta = CST_S2; /* now in step 2 */
|
||||
rq_init_int (cp); /* intr if req */
|
||||
|
|
|
@ -678,8 +678,6 @@ if (tq_csta < CST_UP) { /* still init? */
|
|||
else {
|
||||
tq_s1dat = tq_saw; /* save data */
|
||||
tq_dib.vec = (tq_s1dat & SA_S1H_VEC) << 2; /* get vector */
|
||||
if (tq_dib.vec) /* if nz, bias */
|
||||
tq_dib.vec = tq_dib.vec + VEC_Q;
|
||||
tq_sa = SA_S2 | SA_S2C_PT | SA_S2C_EC (tq_s1dat);
|
||||
tq_csta = CST_S2; /* now in step 2 */
|
||||
tq_init_int (); /* intr if req */
|
||||
|
|
|
@ -2183,7 +2183,7 @@ t_stat xq_wr_var(CTLR* xq, int32 data)
|
|||
|
||||
/* set vector of SIMH device */
|
||||
if (data & XQ_VEC_IV)
|
||||
xq->dib->vec = (data & XQ_VEC_IV) + VEC_Q;
|
||||
xq->dib->vec = (data & XQ_VEC_IV);
|
||||
else
|
||||
xq->dib->vec = 0;
|
||||
|
||||
|
@ -2361,7 +2361,7 @@ t_stat xq_wr_srqr(CTLR* xq, int32 data)
|
|||
|
||||
xq_debug_turbo_setup(xq);
|
||||
|
||||
xq->dib->vec = xq->var->init.vector + VEC_Q;
|
||||
xq->dib->vec = xq->var->init.vector;
|
||||
xq->var->tbindx = xq->var->rbindx = 0;
|
||||
if ((xq->var->sanity.enabled) && (xq->var->init.options & XQ_IN_OP_HIT)) {
|
||||
xq->var->sanity.quarter_secs = 4*xq->var->init.hit_timeout;
|
||||
|
|
|
@ -308,7 +308,7 @@ typedef struct {
|
|||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 1 /* Qbus system */
|
||||
#define VEC_Q 0x200 /* Qbus vector offset */
|
||||
#define VEC_SET 0x201 /* Vector bits to set in Qbus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "vax_defs.h"
|
||||
|
||||
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
|
||||
int32 int_vec_set[IPL_HLVL][32] = { 0 }; /* bits to set in vector */
|
||||
int32 autcon_enb = 1; /* autoconfig enable */
|
||||
|
||||
extern int32 PSL, SISR, trpirq, mem_err, hlt_pin;
|
||||
|
@ -92,6 +93,8 @@ int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
|
|||
|
||||
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
|
||||
|
||||
#define QB_VEC_MASK 0x1FC /* Interrupt Vector value mask */
|
||||
|
||||
/* The KA610 handles errors in I/O space as follows
|
||||
|
||||
- read: machine check
|
||||
|
@ -310,10 +313,16 @@ if (lvl > IPL_HMAX) { /* error req lvl? */
|
|||
}
|
||||
for (i = 0; int_req[l] && (i < 32); i++) {
|
||||
if ((int_req[l] >> i) & 1) {
|
||||
int32 vec;
|
||||
|
||||
int_req[l] = int_req[l] & ~(1u << i);
|
||||
if (int_ack[l][i])
|
||||
return int_ack[l][i]();
|
||||
return int_vec[l][i];
|
||||
vec =int_ack[l][i]();
|
||||
else
|
||||
vec = int_vec[l][i];
|
||||
vec |= int_vec_set[l][i];
|
||||
vec &= (int_vec_set[l][i] | QB_VEC_MASK);
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -364,7 +364,7 @@ typedef struct {
|
|||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 1 /* Qbus system */
|
||||
#define VEC_Q 0x200 /* Qbus vector offset */
|
||||
#define VEC_SET 0x201 /* Vector bits to set in Qbus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
|
@ -61,11 +61,14 @@ BITFIELD qb_ipc_bits[] = {
|
|||
#define QBMAP_RD (QBMAP_VLD | QBMAP_PAG)
|
||||
#define QBMAP_WR (QBMAP_VLD | QBMAP_PAG)
|
||||
|
||||
#define QB_VEC_MASK 0x1FC /* Interrupt Vector value mask */
|
||||
|
||||
/* KA630 Memory system error register */
|
||||
|
||||
#define MSER_NXM 0x00000080 /* CPU NXM */
|
||||
|
||||
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
|
||||
int32 int_vec_set[IPL_HLVL][32] = { 0 }; /* bits to set in vector */
|
||||
int32 qb_ipc = 0; /* IPC */
|
||||
int32 qb_map[QBNMAPR] = { 0 }; /* map registers */
|
||||
int32 autcon_enb = 1; /* autoconfig enable */
|
||||
|
@ -375,10 +378,16 @@ if (lvl > IPL_HMAX) { /* error req lvl? */
|
|||
}
|
||||
for (i = 0; int_req[l] && (i < 32); i++) {
|
||||
if ((int_req[l] >> i) & 1) {
|
||||
int32 vec;
|
||||
|
||||
int_req[l] = int_req[l] & ~(1u << i);
|
||||
if (int_ack[l][i])
|
||||
return int_ack[l][i]();
|
||||
return int_vec[l][i];
|
||||
vec =int_ack[l][i]();
|
||||
else
|
||||
vec = int_vec[l][i];
|
||||
vec |= int_vec_set[l][i];
|
||||
vec &= (int_vec_set[l][i] | QB_VEC_MASK);
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
|
@ -322,8 +322,8 @@ typedef struct {
|
|||
#define VEC_AUTO (0) /* Assigned by Auto Configure */
|
||||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 0
|
||||
#define VEC_Q 0x200
|
||||
#define VEC_QBUS 0 /* Unibus system */
|
||||
#define VEC_SET 0x200 /* Vector bits to set in Unibus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
|
@ -546,7 +546,7 @@ for (i = 0; boot_tab[i].name != NULL; i++) {
|
|||
R[0] = boot_tab[i].code;
|
||||
if (boot_tab[i].code == BOOT_RB) { /* vector set by console for RB730 */
|
||||
extern DIB rb_dib;
|
||||
R[0] = R[0] | ((rb_dib.vec - VEC_Q) << 16);
|
||||
R[0] = R[0] | ((rb_dib.vec) << 16);
|
||||
}
|
||||
R[1] = TR_UBA;
|
||||
R[2] = boot_tab[i].let | (ba & UBADDRMASK);
|
||||
|
|
|
@ -55,6 +55,8 @@
|
|||
/* Vector registers - read only */
|
||||
|
||||
#define UBA_UVEC 0x80000000
|
||||
#define UBA_VEC_MASK 0x1FC /* Vector value mask */
|
||||
|
||||
|
||||
/* RB730 registers */
|
||||
|
||||
|
@ -85,7 +87,8 @@
|
|||
#define UBA_DEB_ERR 0x20 /* errors */
|
||||
|
||||
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
|
||||
uint32 uba_csr = 0; /* control & status reg */
|
||||
int32 int_vec_set[IPL_HLVL][32] = { 0 }; /* bits to set in vector */
|
||||
uint32 uba_csr = 0; /* control & status reg */
|
||||
uint32 uba_fmer = 0; /* failing map reg */
|
||||
uint32 uba_map[UBA_NMAPR] = { 0 }; /* map registers */
|
||||
int32 autcon_enb = 1; /* autoconfig enable */
|
||||
|
@ -385,8 +388,12 @@ for (i = 0; int_req[lvl] && (i < 32); i++) {
|
|||
if ((int_req[lvl] >> i) & 1) {
|
||||
int_req[lvl] = int_req[lvl] & ~(1u << i);
|
||||
if (int_ack[lvl][i])
|
||||
return (vec | int_ack[lvl][i]());
|
||||
return (vec | int_vec[lvl][i]);
|
||||
vec = int_ack[lvl][i]();
|
||||
else
|
||||
vec = int_vec[lvl][i];
|
||||
vec |= int_vec_set[lvl][i];
|
||||
vec &= (int_vec_set[lvl][i] | UBA_VEC_MASK);
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
|
|
|
@ -361,8 +361,9 @@ typedef struct {
|
|||
#define VEC_AUTO (0) /* Assigned by Auto Configure */
|
||||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 0
|
||||
#define VEC_Q 0x200
|
||||
#define VEC_QBUS 0 /* Unibus system */
|
||||
#define VEC_SET 0x200 /* Vector bits to set in Unibus vectors */
|
||||
#define VEC_MASK 0x3FF /* Vector bits to return in Unibus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@
|
|||
#define UBADPR_RD 0xE0000000
|
||||
#define UBADPR_W1C 0xC0000000
|
||||
|
||||
#define UBA_VEC_MASK 0x1FC /* Vector value mask */
|
||||
|
||||
/* Map registers */
|
||||
|
||||
#define UBAMAP_OF 0x200
|
||||
|
@ -136,6 +138,7 @@ int32 (*int_ack[IPL_HLVL][32])(void); /* int ack routines */
|
|||
/* Unibus interrupt request to vector map */
|
||||
|
||||
int32 int_vec[IPL_HLVL][32]; /* int req to vector */
|
||||
int32 int_vec_set[IPL_HLVL][32] = { 0 }; /* bits to set in vector */
|
||||
|
||||
/* Unibus adapter data structures
|
||||
|
||||
|
@ -424,21 +427,26 @@ return;
|
|||
|
||||
int32 uba_get_ubvector (int32 lvl)
|
||||
{
|
||||
int32 i, vec;
|
||||
int32 i;
|
||||
|
||||
vec = 0;
|
||||
if ((lvl == (IPL_UBA - IPL_HMIN)) && uba_int) { /* UBA lvl, int? */
|
||||
uba_int = 0; /* clear int */
|
||||
}
|
||||
for (i = 0; int_req[lvl] && (i < 32); i++) {
|
||||
if ((int_req[lvl] >> i) & 1) {
|
||||
int32 vec;
|
||||
|
||||
int_req[lvl] = int_req[lvl] & ~(1u << i);
|
||||
if (int_ack[lvl][i])
|
||||
return (vec | int_ack[lvl][i]());
|
||||
return (vec | int_vec[lvl][i]);
|
||||
vec = int_ack[lvl][i]();
|
||||
else
|
||||
vec = int_vec[lvl][i];
|
||||
vec |= int_vec_set[lvl][i];
|
||||
vec &= (int_vec_set[lvl][i] | UBA_VEC_MASK);
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
return vec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Unibus I/O buffer routines
|
||||
|
|
|
@ -375,8 +375,8 @@ typedef struct {
|
|||
#define VEC_AUTO (0) /* Assigned by Auto Configure */
|
||||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 0
|
||||
#define VEC_Q 0000
|
||||
#define VEC_QBUS 0 /* Unibus system */
|
||||
#define VEC_SET 0x000 /* Vector bits to set in Unibus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
|
@ -122,6 +122,7 @@
|
|||
|
||||
#define UBABRRVR_OF 0x0C
|
||||
#define UBA_UVEC 0x80000000
|
||||
#define UBA_VEC_MASK 0x1FC /* Vector value mask */
|
||||
|
||||
/* Data path registers */
|
||||
|
||||
|
@ -595,8 +596,8 @@ if (((uba_dr & UBADR_DINTR) == 0) && !uba_uiip && /* intr enabled? */
|
|||
if ((int_req[lvl] >> i) & 1) {
|
||||
int_req[lvl] = int_req[lvl] & ~(1u << i);
|
||||
if (int_ack[lvl][i])
|
||||
return (vec | int_ack[lvl][i]());
|
||||
return (vec | int_vec[lvl][i]);
|
||||
return ((UBA_VEC_MASK|UBA_UVEC) & (vec | int_ack[lvl][i]()));
|
||||
return ((UBA_VEC_MASK|UBA_UVEC) & (vec | int_vec[lvl][i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -405,8 +405,8 @@ typedef struct {
|
|||
#define VEC_AUTO (0) /* Assigned by Auto Configure */
|
||||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 0
|
||||
#define VEC_Q 0000
|
||||
#define VEC_QBUS 0 /* Unibus system */
|
||||
#define VEC_SET 0x000 /* Vector bits to set in Unibus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
|
@ -1138,13 +1138,15 @@ else {
|
|||
}
|
||||
if (ei > 0) { /* if int, new IPL */
|
||||
int32 newipl;
|
||||
if (VEC_QBUS && ((vec & VEC_Q) != 0)) /* Qbus and Qbus vector? */
|
||||
if ((VEC_QBUS & vec) != 0) /* Qbus vector? */
|
||||
newipl = PSL_IPL17; /* force IPL 17 */
|
||||
else newipl = ipl << PSL_V_IPL; /* otherwise, int IPL */
|
||||
else
|
||||
newipl = ipl << PSL_V_IPL; /* otherwise, int IPL */
|
||||
PSL = newpsl | newipl;
|
||||
}
|
||||
else PSL = newpsl | /* exc, old IPL/1F */
|
||||
((newpc & 1)? PSL_IPL1F: (oldpsl & PSL_IPL)) | (oldcur << PSL_V_PRV);
|
||||
else
|
||||
PSL = newpsl | /* exc, old IPL/1F */
|
||||
((newpc & 1)? PSL_IPL1F: (oldpsl & PSL_IPL)) | (oldcur << PSL_V_PRV);
|
||||
sim_debug (LOG_CPU_I, &cpu_dev, "PC=%08x, PSL=%08x, SP=%08x, VEC=%08x, nPSL=%08x, nSP=%08x\n",
|
||||
PC, oldpsl, oldsp, vec, PSL, SP);
|
||||
acc = ACC_MASK (KERN); /* new mode is kernel */
|
||||
|
|
13
VAX/vax_io.c
13
VAX/vax_io.c
|
@ -103,7 +103,10 @@
|
|||
#define CQMAP_VLD 0x80000000 /* valid */
|
||||
#define CQMAP_PAG 0x000FFFFF /* mem page */
|
||||
|
||||
#define QB_VEC_MASK 0x1FC /* Interrupt Vector value mask */
|
||||
|
||||
int32 int_req[IPL_HLVL] = { 0 }; /* intr, IPL 14-17 */
|
||||
int32 int_vec_set[IPL_HLVL][32] = { 0 }; /* bits to set in vector */
|
||||
int32 cq_scr = 0; /* SCR */
|
||||
int32 cq_dser = 0; /* DSER */
|
||||
int32 cq_mear = 0; /* MEAR */
|
||||
|
@ -427,10 +430,16 @@ if (lvl > IPL_HMAX) { /* error req lvl? */
|
|||
}
|
||||
for (i = 0; int_req[l] && (i < 32); i++) {
|
||||
if ((int_req[l] >> i) & 1) {
|
||||
int32 vec;
|
||||
|
||||
int_req[l] = int_req[l] & ~(1u << i);
|
||||
if (int_ack[l][i])
|
||||
return int_ack[l][i]();
|
||||
return int_vec[l][i];
|
||||
vec = int_ack[l][i]();
|
||||
else
|
||||
vec = int_vec[l][i];
|
||||
vec |= int_vec_set[l][i];
|
||||
vec &= (int_vec_set[l][i] | QB_VEC_MASK);
|
||||
return vec;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
12
VAX/vax_vc.c
12
VAX/vax_vc.c
|
@ -566,7 +566,15 @@ switch (rg) {
|
|||
else if (vc_intc.ptr == 9) /* ACR */
|
||||
vc_intc.acr = data & 0xFFFF;
|
||||
else
|
||||
vc_intc.vec[vc_intc.ptr] = data & 0xFFFF; /* Vector */
|
||||
/*
|
||||
Masking the vector with 0x1FC is probably storing
|
||||
one more bit than the original hardware did.
|
||||
Doing this allows a maximal simulated hardware
|
||||
configuration use a reasonable vector where real
|
||||
hardware could never be assembled with that many
|
||||
devices.
|
||||
*/
|
||||
vc_intc.vec[vc_intc.ptr] = data & 0x1FC; /* Vector */
|
||||
break;
|
||||
|
||||
case 7: /* ICSR */
|
||||
|
@ -860,7 +868,7 @@ for (i = 0; i < 8; i++) {
|
|||
vc_intc.isr &= ~(1u << i);
|
||||
else vc_intc.isr |= (1u << i);
|
||||
vc_checkint();
|
||||
result = (vc_intc.vec[i] + VEC_Q);
|
||||
result = vc_intc.vec[i];
|
||||
sim_debug (DBG_INT, &vc_dev, "Int Ack Vector: 0%03o (0x%X)\n", result, result);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -414,7 +414,7 @@ typedef struct {
|
|||
#define VEC_FLOAT (0) /* Assigned by Auto Configure */
|
||||
|
||||
#define VEC_QBUS 1 /* Qbus system */
|
||||
#define VEC_Q 0x200 /* Qbus vector offset */
|
||||
#define VEC_SET 0x201 /* Vector bits to set in Qbus vectors */
|
||||
|
||||
/* Interrupt macros */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue