diff --git a/0readmeAsynchIO.txt b/0readmeAsynchIO.txt index 76af706d..c718b254 100644 --- a/0readmeAsynchIO.txt +++ b/0readmeAsynchIO.txt @@ -155,7 +155,10 @@ The pdp11_rq.c module has been refactored to leverage the asynch I/O features of the sim_disk library. The impact to this code to adopt the asynch I/O paradigm was quite minimal. The pdp11_rp.c module has also been refactored to leverage the asynch I/O -features of the sim_disk library. +features of the sim_disk library. The impact to this code to adopt the +asynch I/O paradigm was also quite minimal. After conversion a latent +but in the VAX Massbus adapter implementation was illuminated due to the +more realistic delays to perform I/O operations. The pdp11_tq.c module has been refactored to leverage the asynch I/O features of the sim_tape library. The impact to this code to adopt the asynch I/O paradigm was very significant. This was due to the two facts: diff --git a/VAX/vax7x0_mba.c b/VAX/vax7x0_mba.c index 14aa9966..a17e3dcf 100644 --- a/VAX/vax7x0_mba.c +++ b/VAX/vax7x0_mba.c @@ -49,6 +49,8 @@ #define MBA_EXTDRV(x) (((x) >> MBA_V_DRV) & MBA_M_DRV) #define MBA_EXTOFS(x) (((x) >> MBA_V_DEVOFS) & MBA_M_DEVOFS) +char *mba_regnames[] = {"CNF", "CR", "SR", "VA", "BC", "DR", "SMR", "CMD"}; + /* Massbus configuration register */ #define MBACNF_OF 0x0 @@ -58,6 +60,22 @@ #define MBACNF_RD (SBI_FAULTS|MBACNF_W1C) #define MBACNF_W1C 0x00C00000 +BITFIELD mba_cnf_bits[] = { + BITF(CODE,8), /* Adapter Code */ + BITNCF(13), /* 08:20 Reserved */ + BIT(OT), /* Over Temperature */ + BIT(PU), /* Power Up */ + BIT(PD), /* Power Down */ + BITNCF(2), /* 24:25 Reserved */ + BIT(XMTFLT), /* Transmit Fault */ + BIT(MT), /* Multiple Transmitter */ + BITNCF(1), /* 28 Reserved */ + BIT(URD), /* Unexpected Read Data */ + BIT(WS), /* Write Data Sequence (Fault B) */ + BIT(PE), /* SBI Parity Error */ + ENDBITS +}; + /* Control register */ #define MBACR_OF 0x1 @@ -68,6 +86,15 @@ #define MBACR_RD 0x0000000E #define MBACR_WR 0x0000000E +BITFIELD mba_cr_bits[] = { + BIT(INIT), /* Initialization */ + BIT(ABORT), /* Abort Data Transfer */ + BIT(IE), /* Interrupt Enable */ + BIT(MM), /* Maintenance Mode */ + BITNCF(28), /* 04:31 Reserved */ + ENDBITS +}; + /* Status register */ #define MBASR_OF 0x2 @@ -100,33 +127,98 @@ #define MBASR_ERRORS 0x608E49FF #define MBASR_INTR 0x000F7000 +BITFIELD mba_sr_bits[] = { + BIT(RDTIMEOUT), /* Read Data Timeout */ + BIT(ISTIMEOUT), /* Interface Sequence Timeout */ + BIT(RDS), /* Read Data Substitute */ + BIT(ERRCONF), /* Error Confirmation */ + BIT(INVMAP), /* Invalid Map */ + BIT(MAPPE), /* Page Frame Map Parity Error */ + BIT(MDPE), /* Massbus Data Parity Error */ + BIT(MBEXC), /* Massbus Exception */ + BIT(MXF), /* Missed Transfer Error */ + BIT(WCLWRERR), /* Write Check Lower Byte Error */ + BIT(WCUPERR), /* Write Check Upper Byte Error */ + BIT(DLT), /* Data Late */ + BIT(DTABT), /* Data Transfer Aborted */ + BIT(DTCOMP), /* Data Transfer Complete */ + BITNCF(2), /* 14:15 Reserved */ + BIT(ATTN), /* Attention */ + BIT(MCPE), /* Massbus Control Parity Error */ + BIT(NED), /* Non Existing Drive */ + BIT(PGE), /* Programming Error */ + BITNCF(9), /* 20:28 Reserved */ + BIT(CRD), /* Corrected Read Data */ + BIT(NRCONF), /* No Response Confirmation */ + BIT(DTBUSY), /* Data Transfer Busy */ + ENDBITS +}; + /* Virtual address register */ #define MBAVA_OF 0x3 #define MBAVA_RD 0x0001FFFF #define MBAVA_WR (MBAVA_RD) +BITFIELD mba_va_bits[] = { + BITF(PAGEBYTE,9), /* Page Byte Address */ + BITF(MAPPOINTER,8), /* Map Pointer */ + ENDBITS +}; + /* Byte count */ #define MBABC_OF 0x4 #define MBABC_WR 0x0000FFFF #define MBABC_V_MBC 16 /* MB count */ +BITFIELD mba_bc_bits[] = { + BITF(SBIBYTECOUNT,16), /* SBI Byte Counter */ + BITF(MBBYTECOUNT,16), /* Massbus Byte Counter */ + ENDBITS +}; + /* Diagnostic register */ #define MBADR_OF 0x5 #define MBADR_RD 0xFFFFFFFF #define MBADR_WR 0xFFC00000 +BITFIELD mba_dr_bits[] = { + BITF(DR,32), /* Diagnostic Register */ + ENDBITS +}; + /* Selected map entry - read only */ #define MBASMR_OF 0x6 #define MBASMR_RD (MBAMAP_RD) +BITFIELD mba_smr_bits[] = { + BITF(SMR,32), /* Selected Map Register */ + ENDBITS +}; + /* Command register (SBI) - read only */ #define MBACMD_OF 0x7 +BITFIELD mba_cmd_bits[] = { + BITF(CAR,32), /* Command Address Register */ + ENDBITS +}; + +BITFIELD *mba_reg_bits[] = { + mba_cnf_bits, + mba_cr_bits, + mba_sr_bits, + mba_va_bits, + mba_bc_bits, + mba_dr_bits, + mba_smr_bits, + mba_cmd_bits +}; + /* External registers */ #define MBA_CS1 0x00 /* device CSR1 */ @@ -148,6 +240,7 @@ #define MBA_DEB_MWR 0x08 /* map writes */ #define MBA_DEB_XFR 0x10 /* transfers */ #define MBA_DEB_ERR 0x20 /* errors */ +#define MBA_DEB_INT 0x40 /* interrupts */ uint32 mba_cnf[MBA_NUM]; /* config reg */ uint32 mba_cr[MBA_NUM]; /* control reg */ @@ -161,7 +254,6 @@ uint32 mba_map[MBA_NUM][MBA_NMAPR]; /* map */ extern uint32 nexus_req[NEXUS_HLVL]; extern UNIT cpu_unit; extern FILE *sim_log; -extern FILE *sim_deb; extern int32 sim_switches; t_stat mba_reset (DEVICE *dptr); @@ -239,6 +331,7 @@ DEBTAB mba_deb[] = { { "MAPWRITE", MBA_DEB_MWR }, { "XFER", MBA_DEB_XFR }, { "ERROR", MBA_DEB_ERR }, + { "INTERRUPT", MBA_DEB_INT }, { NULL, 0 } }; @@ -271,7 +364,7 @@ t_stat r; mb = NEXUS_GETNEX (pa) - TR_MBA0; /* get MBA */ if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */ - printf (">>MBA%d: invalid adapter read mask, pa = %X, lnt = %d\r\n", mb, pa, lnt); + printf (">>MBA%d: invalid adapter read mask, pa = 0x%X, lnt = %d\r\n", mb, pa, lnt); #if defined(VAX_780) sbi_set_errcnf (); /* err confirmation */ #endif @@ -323,8 +416,8 @@ switch (rtype) { /* case on type */ default: return SCPE_NXM; } - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RRD)) - fprintf (sim_deb, ">>MBA%d: int reg %d read, value = %X\n", mb, ofs, *val); + sim_debug (MBA_DEB_RRD, &mba_dev[mb], "mba_rdreg(Reg=%s, val=0x%X)\n", mba_regnames[ofs], *val); + sim_debug_bits(MBA_DEB_RRD, &mba_dev[mb], mba_reg_bits[ofs], *val, *val, 1); break; case MBART_EXT: /* external */ @@ -338,15 +431,13 @@ switch (rtype) { /* case on type */ else if (r == MBE_NXR) /* nx reg? */ return SCPE_NXM; *val |= (mba_sr[mb] & ~WMASK); /* upper 16b from SR */ - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RRD)) - fprintf (sim_deb, ">>MBA%d: drv %d ext reg %d read, value = %X\n", mb, drv, ofs, *val); + sim_debug (MBA_DEB_RRD, &mba_dev[mb], "mba_rdreg(drv %d ext reg=%d, val=0x%X)\n", drv, ofs, *val); break; case MBART_MAP: /* map */ ofs = MBA_INTOFS (pa); *val = mba_map[mb][ofs] & MBAMAP_RD; - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_MRD)) - fprintf (sim_deb, ">>MBA%d: map %d read, value = %X\n", mb, ofs, *val); + sim_debug (MBA_DEB_MRD, &mba_dev[mb], "mba_rdreg(map %d read, val=0x%X)\n", ofs, *val); break; default: @@ -361,12 +452,13 @@ return SCPE_OK; t_stat mba_wrreg (int32 val, int32 pa, int32 lnt) { int32 mb, ofs, drv, rtype; +uint32 old_reg, old_sr; t_stat r; t_bool cs1dt; mb = NEXUS_GETNEX (pa) - TR_MBA0; /* get MBA */ if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */ - printf (">>MBA%d: invalid adapter write mask, pa = %X, lnt = %d\r\n", mb, pa, lnt); + printf (">>MBA%d: invalid adapter write mask, pa = 0x%X, lnt = %d\r\n", mb, pa, lnt); #if defined(VAX_780) sbi_set_errcnf (); /* err confirmation */ #endif @@ -376,17 +468,24 @@ if (mb >= MBA_NUM) /* valid? */ return SCPE_NXM; rtype = MBA_RTYPE (pa); /* get reg type */ +old_sr = mba_sr[mb]; + switch (rtype) { /* case on type */ case MBART_INT: /* internal */ ofs = MBA_INTOFS (pa); /* check range */ + sim_debug (MBA_DEB_RWR, &mba_dev[mb], "mba_wrreg(reg=%s write, val=0x%X)\n", mba_regnames[ofs], val); + switch (ofs) { case MBACNF_OF: /* CNF */ + old_reg = mba_cnf[mb]; mba_cnf[mb] &= ~(val & MBACNF_W1C); + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_cnf[mb], 1); break; case MBACR_OF: /* CR */ + old_reg = mba_cr[mb]; if (val & MBACR_INIT) /* init? */ mba_reset (&mba_dev[mb]); /* reset MBA */ if ((val & MBACR_ABORT) && @@ -404,6 +503,7 @@ switch (rtype) { /* case on type */ mba_clr_int (mb); mba_cr[mb] = (mba_cr[mb] & ~MBACR_WR) | (val & MBACR_WR); + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_cr[mb], 1); break; case MBASR_OF: /* SR */ @@ -411,27 +511,32 @@ switch (rtype) { /* case on type */ break; case MBAVA_OF: /* VA */ + old_reg = mba_va[mb]; + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], mba_va[mb], val, 1); if (mba_sr[mb] & MBASR_DTBUSY) /* err if xfr */ mba_upd_sr (MBASR_PGE, 0, mb); else mba_va[mb] = val & MBAVA_WR; + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_va[mb], 1); break; case MBABC_OF: /* BC */ + old_reg = mba_bc[mb]; if (mba_sr[mb] & MBASR_DTBUSY) /* err if xfr */ mba_upd_sr (MBASR_PGE, 0, mb); else mba_bc[mb] = val & MBABC_WR; + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_bc[mb], 1); break; case MBADR_OF: /* DR */ + old_reg = mba_dr[mb]; mba_dr[mb] = (mba_dr[mb] & ~MBADR_WR) | (val & MBADR_WR); + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_reg_bits[ofs], old_reg, mba_dr[mb], 1); break; default: return SCPE_NXM; } - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RWR)) - fprintf (sim_deb, ">>MBA%d: int reg %d write, value = %X\n", mb, ofs, val); break; case MBART_EXT: /* external */ @@ -439,6 +544,7 @@ switch (rtype) { /* case on type */ return SCPE_NXM; drv = MBA_EXTDRV (pa); /* get dev num */ ofs = MBA_EXTOFS (pa); /* get reg offs */ + sim_debug (MBA_DEB_RWR, &mba_dev[mb], "mba_wrreg(drv=%d ext reg=%d write, val=0x%X)\n", drv, ofs, val); cs1dt = (ofs == MBA_CS1) && (val & CSR_GO) && /* starting xfr? */ ((val & MBA_CS1_WR) >= MBA_CS1_DT); if (cs1dt && (mba_sr[mb] & MBASR_DTBUSY)) { /* xfr while busy? */ @@ -452,21 +558,21 @@ switch (rtype) { /* case on type */ return SCPE_NXM; if (cs1dt && (r == SCPE_OK)) /* did dt start? */ mba_sr[mb] = (mba_sr[mb] | MBASR_DTBUSY) & ~MBASR_W1C; - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_RWR)) - fprintf (sim_deb, ">>MBA%d: drv %d ext reg %d write, value = %X\n", mb, drv, ofs, val); break; case MBART_MAP: /* map */ ofs = MBA_INTOFS (pa); mba_map[mb][ofs] = val & MBAMAP_WR; - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_MWR)) - fprintf (sim_deb, ">>MBA%d: map %d write, value = %X\n", mb, ofs, val); + sim_debug (MBA_DEB_MWR, &mba_dev[mb], "mba_wrreg(map %d write, val=0x%X)\n", ofs, val); break; default: return SCPE_NXM; } +if (old_sr != mba_sr[mb]) + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, old_sr, mba_sr[mb], 1); + return SCPE_OK; } @@ -500,8 +606,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */ if (pbc > (bc - i)) /* limit to rem xfr */ pbc = bc - i; - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_XFR)) - fprintf (sim_deb, ">>MBA%d: read, pa = %X, bc = %X\n", mb, pa, pbc); + sim_debug (MBA_DEB_XFR, &mba_dev[mb], "mba_rdbufW(pa=0x%X, bc=0x%X)\n", pa, pbc); if ((pa | pbc) & 1) { /* aligned word? */ for (j = 0; j < pbc; pa++, j++) { /* no, bytes */ if ((i + j) & 1) { /* odd byte? */ @@ -550,8 +655,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */ if (pbc > (bc - i)) /* limit to rem xfr */ pbc = bc - i; - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_XFR)) - fprintf (sim_deb, ">>MBA%d: write, pa = %X, bc = %X\n", mb, pa, pbc); + sim_debug (MBA_DEB_XFR, &mba_dev[mb], "mba_wrbufW(pa=0x%X, bc=0x%X)\n", pa, pbc); if ((pa | pbc) & 1) { /* aligned word? */ for (j = 0; j < pbc; pa++, j++) { /* no, bytes */ if ((i + j) & 1) { @@ -599,8 +703,7 @@ for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ break; } pbc = VA_PAGSIZE - VA_GETOFF (pa); /* left in page */ - if (DEBUG_PRI (mba_dev[mb], MBA_DEB_XFR)) - fprintf (sim_deb, ">>MBA%d: check, pa = %X, bc = %X\n", mb, pa, pbc); + sim_debug (MBA_DEB_XFR, &mba_dev[mb], "mba_chbufW(pa=0x%X, bc=0x%X)\n", pa, pbc); if (pbc > (bc - i)) /* limit to rem xfr */ pbc = bc - i; for (j = 0; j < pbc; j++, pa++) { /* byte by byte */ @@ -639,23 +742,30 @@ return 0; void mba_set_don (uint32 mb) { +uint32 old_sr = mba_sr[mb]; + mba_upd_sr (MBASR_DTCMP, 0, mb); +if (old_sr != mba_sr[mb]) + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, old_sr, mba_sr[mb], 1); return; } void mba_upd_ata (uint32 mb, uint32 val) { +uint32 old_sr = mba_sr[mb]; + if (val) mba_upd_sr (MBASR_ATA, 0, mb); else mba_upd_sr (0, MBASR_ATA, mb); +if (old_sr != mba_sr[mb]) + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, old_sr, mba_sr[mb], 1); return; } void mba_set_exc (uint32 mb) { +sim_debug (MBA_DEB_ERR, &mba_dev[mb], "mba_set_exc(EXC write)\n"); mba_upd_sr (MBASR_MBEXC, 0, mb); -if (DEBUG_PRI (mba_dev[mb], MBA_DEB_ERR)) - fprintf (sim_deb, ">>MBA%d: EXC write\n", mb); return; } @@ -673,8 +783,10 @@ DIB *dibp; if (mb >= MBA_NUM) return; dibp = (DIB *) mba_dev[mb].ctxt; -if (dibp) +if (dibp) { nexus_req[dibp->vloc >> 5] |= (1u << (dibp->vloc & 0x1F)); + sim_debug (MBA_DEB_INT, &mba_dev[mb], "mba_set_int(0x%X)\n", dibp->vloc); + } return; } @@ -685,24 +797,31 @@ DIB *dibp; if (mb >= MBA_NUM) return; dibp = (DIB *) mba_dev[mb].ctxt; -if (dibp) +if (dibp) { nexus_req[dibp->vloc >> 5] &= ~(1u << (dibp->vloc & 0x1F)); + sim_debug (MBA_DEB_INT, &mba_dev[mb], "mba_clr_int(0x%X)\n", dibp->vloc); + } return; } void mba_upd_sr (uint32 set, uint32 clr, uint32 mb) { +uint32 o_sr; + if (mb >= MBA_NUM) return; +o_sr = mba_sr[mb]; if (set & MBASR_ABORTS) set |= (MBASR_DTCMP|MBASR_DTABT); if (set & (MBASR_DTCMP|MBASR_DTABT)) mba_sr[mb] &= ~MBASR_DTBUSY; mba_sr[mb] = (mba_sr[mb] | set) & ~clr; -if ((set & MBASR_INTR) && (mba_cr[mb] & MBACR_IE)) +if (mba_sr[mb] != o_sr) + sim_debug_bits(MBA_DEB_RWR, &mba_dev[mb], mba_sr_bits, o_sr, mba_sr[mb], 1); +if ((set & MBASR_INTR) && (mba_cr[mb] & MBACR_IE) && !(mba_sr[mb] & MBASR_DTBUSY)) mba_set_int (mb); -if ((set & MBASR_ERRORS) && (DEBUG_PRI (mba_dev[mb], MBA_DEB_ERR))) - fprintf (sim_deb, ">>MBA%d: CS error = %X\n", mb, mba_sr[mb]); +if (set & MBASR_ERRORS) + sim_debug (MBA_DEB_ERR, &mba_dev[mb], "mba_upd_sr(CS error=0x%X)\n", mba_sr[mb]); return; }