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);
            }
        }
Beispiel #2
0
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;
}
Beispiel #3
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}