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:
Mark Pizzolato 2015-10-08 04:43:21 -07:00
parent b05c7419f0
commit ed57f061e2
24 changed files with 176 additions and 59 deletions

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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 */

View file

@ -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);

View file

@ -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;

View file

@ -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 */

View file

@ -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

View file

@ -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 */

View file

@ -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]));
}
}
}

View file

@ -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 */

View file

@ -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 */

View file

@ -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;

View file

@ -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;
}

View file

@ -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 */