int32 mba_wrbufW (uint32 mb, int32 bc, uint16 *buf) { int32 i, j, ba, mbc, pbc; uint32 pa, dat; if (mb >= MBA_NUM) /* valid MBA? */ return 0; ba = mba_va[mb]; /* get virt addr */ mbc = (MBABC_WR + 1) - mba_bc[mb]; /* get Mbus bc */ if (bc > mbc) /* use smaller */ bc = mbc; for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ if (!mba_map_addr (ba + i, &pa, mb)) /* page inv? */ break; if (!ADDR_IS_MEM (pa)) { /* NXM? */ mba_upd_sr (MBASR_RTMO, 0, mb); break; } 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); if ((pa | pbc) & 1) { /* aligned word? */ for (j = 0; j < pbc; pa++, j++) { /* no, bytes */ if ((i + j) & 1) { WriteB (pa, (*buf >> 8) & BMASK); buf++; } else WriteB (pa, *buf & BMASK); } }
t_stat mctl_wrreg (int32 val, int32 pa, int32 lnt) { int32 ofs; ofs = NEXUS_GETOFS (pa); /* get offset */ switch (ofs) { /* case on offset */ case MCSR0_OF: /* CSR0 */ mcsr0 = mcsr0 & ~(MCSR0_RS & val); break; case MCSR1_OF: /* CSR1 */ mcsr1 = val & MCSR1_RW; break; case MCSR2_OF: /* CSR2 */ break; default: return SCPE_NXM; } if (DEBUG_PRI (mctl_dev, MCTL_DEB_RWR)) fprintf (sim_deb, ">>MCTL: reg %d write, value = %X\n", ofs, val); return SCPE_OK; }
t_stat mctl_rdreg (int32 *val, int32 pa, int32 lnt) { int32 ofs; ofs = NEXUS_GETOFS (pa); /* get offset */ switch (ofs) { /* case on offset */ case MCSR0_OF: /* CSR0 */ *val = mcsr0; break; case MCSR1_OF: /* CSR1 */ *val = mcsr1; break; case MCSR2_OF: /* CSR2 */ *val = mcsr2 & ~MCSR2_MBZ; break; default: return SCPE_NXM; } if (DEBUG_PRI (mctl_dev, MCTL_DEB_RRD)) fprintf (sim_deb, ">>MCTL: reg %d read, value = %X\n", ofs, *val); return SCPE_OK; }
int32 mba_rdbufW (uint32 mb, int32 bc, uint16 *buf) { int32 i, j, ba, mbc, pbc; uint32 pa, dat; if (mb >= MBA_NUM) /* valid MBA? */ return 0; ba = mba_va[mb]; /* get virt addr */ mbc = (MBABC_WR + 1) - mba_bc[mb]; /* get Mbus bc */ if (bc > mbc) /* use smaller */ bc = mbc; for (i = 0; i < bc; i = i + pbc) { /* loop by pages */ if (!mba_map_addr (ba + i, &pa, mb)) /* page inv? */ break; if (!ADDR_IS_MEM (pa)) { /* NXM? */ mba_upd_sr (MBASR_RTMO, 0, mb); break; } 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); if ((pa | pbc) & 1) { /* aligned word? */ for (j = 0; j < pbc; pa++, j++) { /* no, bytes */ if ((i + j) & 1) { /* odd byte? */ *buf = (*buf & BMASK) | (ReadB (pa) << 8); buf++; } else *buf = (*buf & ~BMASK) | ReadB (pa); } } else if ((pa | pbc) & 3) { /* aligned LW? */ for (j = 0; j < pbc; pa = pa + 2, j = j + 2) { /* no, words */ *buf++ = ReadW (pa); /* get word */ } } else { /* yes, do by LW */ for (j = 0; j < pbc; pa = pa + 4, j = j + 4) { dat = ReadL (pa); /* get lw */ *buf++ = dat & WMASK; /* low 16b */ *buf++ = (dat >> 16) & WMASK; /* high 16b */ } } } mba_bc[mb] = (mba_bc[mb] + i) & MBABC_WR; mba_va[mb] = (mba_va[mb] + i) & MBAVA_WR; return i; }
t_stat mba_wrreg (int32 val, int32 pa, int32 lnt) { int32 mb, ofs, drv, rtype; 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); sbi_set_errcnf (); /* err confirmation */ return SCPE_OK; } if (mb >= MBA_NUM) /* valid? */ return SCPE_NXM; rtype = MBA_RTYPE (pa); /* get reg type */ switch (rtype) { /* case on type */ case MBART_INT: /* internal */ ofs = MBA_INTOFS (pa); /* check range */ switch (ofs) { case MBACNF_OF: /* CNF */ mba_cnf[mb] &= ~(val & MBACNF_W1C); break; case MBACR_OF: /* CR */ if (val & MBACR_INIT) /* init? */ mba_reset (&mba_dev[mb]); /* reset MBA */ if ((val & MBACR_ABORT) && (mba_sr[mb] & MBASR_DTBUSY)) { if (mbabort[mb]) /* abort? */ mbabort[mb] (); mba_upd_sr (MBASR_DTABT, 0, mb); } if ((val & MBACR_MNT) && (mba_sr[mb] & MBASR_DTBUSY)) { mba_upd_sr (MBASR_PGE, 0, mb); /* mnt & xfer? */ val = val & ~MBACR_MNT; } if ((val & MBACR_IE) == 0) mba_clr_int (mb); mba_cr[mb] = (mba_cr[mb] & ~MBACR_WR) | (val & MBACR_WR); break; case MBASR_OF: /* SR */ mba_sr[mb] = mba_sr[mb] & ~(val & MBASR_W1C); break; case MBAVA_OF: /* VA */ if (mba_sr[mb] & MBASR_DTBUSY) /* err if xfr */ mba_upd_sr (MBASR_PGE, 0, mb); else mba_va[mb] = val & MBAVA_WR; break; case MBABC_OF: /* BC */ if (mba_sr[mb] & MBASR_DTBUSY) /* err if xfr */ mba_upd_sr (MBASR_PGE, 0, mb); else mba_bc[mb] = val & MBABC_WR; break; case MBADR_OF: /* DR */ mba_dr[mb] = (mba_dr[mb] & ~MBADR_WR) | (val & MBADR_WR); 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 */ if (!mbregW[mb]) /* device there? */ return SCPE_NXM; drv = MBA_EXTDRV (pa); /* get dev num */ ofs = MBA_EXTOFS (pa); /* get reg offs */ 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? */ mba_upd_sr (MBASR_PGE, 0, mb); /* prog error */ break; } r = mbregW[mb] (val & WMASK, ofs, drv); /* write dev reg */ if (r == MBE_NXD) /* nx drive? */ mba_upd_sr (MBASR_NFD, 0, mb); else if (r == MBE_NXR) /* nx reg? */ 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); break; default: return SCPE_NXM; } return SCPE_OK; }
t_stat mba_rdreg (int32 *val, int32 pa, int32 lnt) { int32 mb, ofs, drv, rtype; uint32 t; 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); sbi_set_errcnf (); /* err confirmation */ return SCPE_OK; } if (mb >= MBA_NUM) /* valid? */ return SCPE_NXM; rtype = MBA_RTYPE (pa); /* get reg type */ switch (rtype) { /* case on type */ case MBART_INT: /* internal */ ofs = MBA_INTOFS (pa); /* check range */ switch (ofs) { case MBACNF_OF: /* CNF */ *val = (mba_cnf[mb] & MBACNF_RD) | MBACNF_CODE; break; case MBACR_OF: /* CR */ *val = mba_cr[mb] & MBACR_RD; break; case MBASR_OF: /* SR */ *val = mba_sr[mb] & MBASR_RD; break; case MBAVA_OF: /* VA */ *val = mba_va[mb] & MBAVA_RD; break; case MBABC_OF: /* BC */ t = mba_bc[mb] & MBABC_WR; *val = (t << MBABC_V_MBC) | t; break; case MBADR_OF: /* DR */ *val = mba_dr[mb] & MBADR_RD; break; case MBASMR_OF: /* SMR */ *val = mba_smr[mb] & MBASMR_RD; break; case MBACMD_OF: /* CMD */ *val = 0; break; 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); break; case MBART_EXT: /* external */ if (!mbregR[mb]) /* device there? */ return SCPE_NXM; drv = MBA_EXTDRV (pa); /* get dev num */ ofs = MBA_EXTOFS (pa); /* get reg offs */ r = mbregR[mb] (val, ofs, drv); /* call device */ if (r == MBE_NXD) /* nx drive? */ mba_upd_sr (MBASR_NFD, 0, mb); 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); 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); break; default: return SCPE_NXM; } return SCPE_OK; }
t_stat uba_wrreg (int32 val, int32 pa, int32 lnt) { int32 idx, ofs, old_cr; if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */ sim_printf (">>UBA: invalid adapter write mask, pa = %X, lnt = %d\r\n", pa, lnt); sbi_set_errcnf (); /* err confirmation */ return SCPE_OK; } ofs = NEXUS_GETOFS (pa); /* get offset */ if (uba_aiip && (ofs != UBACNF_OF) && (ofs != UBADR_OF) && (ofs != UBACR_OF) && (ofs != UBASR_OF)) return SCPE_NXM; if (ofs >= UBAMAP_OF) { /* map? */ idx = ofs - UBAMAP_OF; if (idx >= UBA_NMAPR) /* valid? */ return SCPE_NXM; uba_map[idx] = val & UBAMAP_WR; if (DEBUG_PRI (uba_dev, UBA_DEB_MWR)) fprintf (sim_deb, ">>UBA: map %d write, value = %X\n", idx, val); return SCPE_OK; } switch (ofs) { /* case on offset */ case UBACNF_OF: /* CNF */ uba_cnf = uba_cnf & ~(val & UBACNF_W1C); /* W1C bits */ uba_adap_clr_int (); /* possible clr int */ break; case UBACR_OF: /* CR */ old_cr = uba_cr; if (val & UBACR_ADINIT) { /* adapter init */ uba_reset (&uba_dev); /* reset adapter */ uba_aiip = 1; /* set init in prog */ uba_ubpdn (uba_aitime); /* power fail UB */ } if ((val & UBACR_UPF) && !(old_cr & UBACR_UPF) /* Unibus power clear */ && !sim_is_active (&uba_unit)) uba_ubpdn (uba_aitime + uba_uitime); /* power fail UB */ uba_cr = (uba_cr & ~UBACR_WR) | (val & UBACR_WR); uba_adap_set_int (uba_cr & ~old_cr); /* possible int set */ uba_adap_clr_int (); /* possible int clr */ break; case UBASR_OF: /* SR */ uba_sr = uba_sr & ~(val & UBASR_W1C); /* W1C bits */ uba_adap_clr_int (); /* possible clr int */ break; case UBADR_OF: /* DR */ uba_dr = (uba_dr & ~UBADR_WR) | (val & UBADR_WR); uba_cnf = uba_cnf & ~(val & UBACNF_W1C); uba_adap_clr_int (); /* possible clr int */ break; case UBABRSVR_OF + 0: case UBABRSVR_OF + 1: /* BRSVR */ case UBABRSVR_OF + 2: case UBABRSVR_OF + 3: idx = ofs - UBABRSVR_OF; uba_svr[idx] = val; break; case UBADPR_OF + 0: /* DPR */ break; /* direct */ case UBADPR_OF + 1: case UBADPR_OF + 2: case UBADPR_OF + 3: case UBADPR_OF + 4: case UBADPR_OF + 5: case UBADPR_OF + 6: case UBADPR_OF + 7: case UBADPR_OF + 8: case UBADPR_OF + 9: case UBADPR_OF + 10: case UBADPR_OF + 11: case UBADPR_OF + 12: case UBADPR_OF + 13: case UBADPR_OF + 14: case UBADPR_OF + 15: idx = ofs - UBADPR_OF; uba_dpr[idx] = uba_dpr[idx] & ~(val & UBADPR_W1C); break; default: return SCPE_NXM; } if (DEBUG_PRI (uba_dev, UBA_DEB_RWR)) fprintf (sim_deb, ">>UBA: reg %d write, value = %X\n", ofs, val); return SCPE_OK; }
t_stat uba_rdreg (int32 *val, int32 pa, int32 lnt) { int32 idx, ofs; if ((pa & 3) || (lnt != L_LONG)) { /* unaligned or not lw? */ sim_printf (">>UBA: invalid adapter read mask, pa = %X, lnt = %d\r\n", pa, lnt); sbi_set_errcnf (); /* err confirmation */ return SCPE_OK; } ofs = NEXUS_GETOFS (pa); /* get offset */ if (uba_aiip && (ofs != UBACNF_OF)&& (ofs != UBADR_OF)) /* init in prog? */ return SCPE_NXM; /* only cnf, dr */ if (ofs >= UBAMAP_OF) { /* map? */ idx = ofs - UBAMAP_OF; if (idx >= UBA_NMAPR) /* valid? */ return SCPE_NXM; *val = uba_map[idx] & UBAMAP_RD; if (DEBUG_PRI (uba_dev, UBA_DEB_MRD)) fprintf (sim_deb, ">>UBA: map %d read, value = %X\n", idx, *val); return SCPE_OK; } switch (ofs) { /* case on offset */ case UBACNF_OF: /* CNF */ *val = (uba_cnf & UBACNF_RD) | UBACNF_CODE; break; case UBACR_OF: /* CR */ *val = uba_cr & UBACR_RD; break; case UBASR_OF: /* SR */ *val = uba_sr & UBASR_RD; break; case UBADR_OF: /* DR */ *val = (uba_dr & UBADR_RD) | UBADR_MICOK | ((uba_cnf & UBADR_CNF_RD) | UBACNF_CODE); break; case UBAFMER_OF: case UBAFMER_OF1: /* FMER */ *val = uba_fmer & UBAFMER_RD; break; case UBAFUBAR_OF: case UBAFUBAR_OF1: /* FUBAR */ *val = uba_fubar & UBAFUBAR_RD; break; case UBABRSVR_OF + 0: case UBABRSVR_OF + 1: /* BRSVR */ case UBABRSVR_OF + 2: case UBABRSVR_OF + 3: idx = ofs - UBABRSVR_OF; *val = uba_svr[idx]; break; case UBABRRVR_OF + 0: case UBABRRVR_OF + 1: /* BRRVR */ case UBABRRVR_OF + 2: case UBABRRVR_OF + 3: idx = ofs - UBABRRVR_OF; uba_rvr[idx] = uba_get_ubvector (idx); *val = uba_rvr[idx]; break; case UBADPR_OF + 0: /* DPR */ *val = 0; /* direct */ break; case UBADPR_OF + 1: case UBADPR_OF + 2: case UBADPR_OF + 3: case UBADPR_OF + 4: case UBADPR_OF + 5: case UBADPR_OF + 6: case UBADPR_OF + 7: case UBADPR_OF + 8: case UBADPR_OF + 9: case UBADPR_OF + 10: case UBADPR_OF + 11: case UBADPR_OF + 12: case UBADPR_OF + 13: case UBADPR_OF + 14: case UBADPR_OF + 15: idx = ofs - UBADPR_OF; *val = uba_dpr[idx] & UBADPR_RD; break; default: return SCPE_NXM; } if (DEBUG_PRI (uba_dev, UBA_DEB_RRD)) fprintf (sim_deb, ">>UBA: reg %d read, value = %X\n", ofs, *val); return SCPE_OK; }