diff --git a/PDP10/pdp10_defs.h b/PDP10/pdp10_defs.h index 907f5cba..d30a8808 100644 --- a/PDP10/pdp10_defs.h +++ b/PDP10/pdp10_defs.h @@ -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 diff --git a/PDP10/pdp10_ksio.c b/PDP10/pdp10_ksio.c index 2c1d51cf..7066cf1c 100644 --- a/PDP10/pdp10_ksio.c +++ b/PDP10/pdp10_ksio.c @@ -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 */ diff --git a/PDP11/pdp11_defs.h b/PDP11/pdp11_defs.h index 49eed930..d19f4ac5 100644 --- a/PDP11/pdp11_defs.h +++ b/PDP11/pdp11_defs.h @@ -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 diff --git a/PDP11/pdp11_io.c b/PDP11/pdp11_io.c index 612bb68d..41dd2ea0 100644 --- a/PDP11/pdp11_io.c +++ b/PDP11/pdp11_io.c @@ -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 */ diff --git a/PDP11/pdp11_io_lib.c b/PDP11/pdp11_io_lib.c index 757759f1..13249cb0 100644 --- a/PDP11/pdp11_io_lib.c +++ b/PDP11/pdp11_io_lib.c @@ -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 */ diff --git a/PDP11/pdp11_rq.c b/PDP11/pdp11_rq.c index fbf77d9b..e1cafa69 100644 --- a/PDP11/pdp11_rq.c +++ b/PDP11/pdp11_rq.c @@ -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 */ diff --git a/PDP11/pdp11_tq.c b/PDP11/pdp11_tq.c index d4b6e391..b38e6513 100644 --- a/PDP11/pdp11_tq.c +++ b/PDP11/pdp11_tq.c @@ -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 */ diff --git a/PDP11/pdp11_xq.c b/PDP11/pdp11_xq.c index f3ec9c44..f69f6d34 100644 --- a/PDP11/pdp11_xq.c +++ b/PDP11/pdp11_xq.c @@ -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; diff --git a/VAX/vax610_defs.h b/VAX/vax610_defs.h index 7476898a..6bf3156d 100644 --- a/VAX/vax610_defs.h +++ b/VAX/vax610_defs.h @@ -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 */ diff --git a/VAX/vax610_io.c b/VAX/vax610_io.c index 8d5c7179..eee4994c 100644 --- a/VAX/vax610_io.c +++ b/VAX/vax610_io.c @@ -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; diff --git a/VAX/vax630_defs.h b/VAX/vax630_defs.h index 0bfba8fe..82fad7d5 100644 --- a/VAX/vax630_defs.h +++ b/VAX/vax630_defs.h @@ -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 */ diff --git a/VAX/vax630_io.c b/VAX/vax630_io.c index 2f6a1a39..fa771e84 100644 --- a/VAX/vax630_io.c +++ b/VAX/vax630_io.c @@ -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; diff --git a/VAX/vax730_defs.h b/VAX/vax730_defs.h index 53531bbb..d25054dc 100644 --- a/VAX/vax730_defs.h +++ b/VAX/vax730_defs.h @@ -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 */ diff --git a/VAX/vax730_sys.c b/VAX/vax730_sys.c index 81e72829..ff6e853e 100644 --- a/VAX/vax730_sys.c +++ b/VAX/vax730_sys.c @@ -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); diff --git a/VAX/vax730_uba.c b/VAX/vax730_uba.c index 6ebe88ff..76ecaf85 100644 --- a/VAX/vax730_uba.c +++ b/VAX/vax730_uba.c @@ -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; diff --git a/VAX/vax750_defs.h b/VAX/vax750_defs.h index cf45e9bc..3bd2ae07 100644 --- a/VAX/vax750_defs.h +++ b/VAX/vax750_defs.h @@ -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 */ diff --git a/VAX/vax750_uba.c b/VAX/vax750_uba.c index 2c009d56..431cb374 100644 --- a/VAX/vax750_uba.c +++ b/VAX/vax750_uba.c @@ -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 diff --git a/VAX/vax780_defs.h b/VAX/vax780_defs.h index 5bb9b253..9c4088ca 100644 --- a/VAX/vax780_defs.h +++ b/VAX/vax780_defs.h @@ -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 */ diff --git a/VAX/vax780_uba.c b/VAX/vax780_uba.c index 3dd369bb..66cf8ba1 100644 --- a/VAX/vax780_uba.c +++ b/VAX/vax780_uba.c @@ -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])); } } } diff --git a/VAX/vax860_defs.h b/VAX/vax860_defs.h index 209c8838..e8e17a91 100644 --- a/VAX/vax860_defs.h +++ b/VAX/vax860_defs.h @@ -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 */ diff --git a/VAX/vax_cpu1.c b/VAX/vax_cpu1.c index 9447a505..869dbf3c 100644 --- a/VAX/vax_cpu1.c +++ b/VAX/vax_cpu1.c @@ -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 */ diff --git a/VAX/vax_io.c b/VAX/vax_io.c index fb96970d..5f5d3366 100644 --- a/VAX/vax_io.c +++ b/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; diff --git a/VAX/vax_vc.c b/VAX/vax_vc.c index 56464bc0..ba6b4258 100644 --- a/VAX/vax_vc.c +++ b/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; } diff --git a/VAX/vaxmod_defs.h b/VAX/vaxmod_defs.h index 4bf1239b..9ae7dc32 100644 --- a/VAX/vaxmod_defs.h +++ b/VAX/vaxmod_defs.h @@ -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 */