Beispiel #1
0
t_stat rs_svc (UNIT *uptr)
{
int32 i, fnc, dtype, drv;
int32 wc, abc, awc, mbc, da;
uint16 *fbuf = (uint16 *)uptr->filebuf;

dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
drv = (int32) (uptr - rs_dev.units);                    /* get drv number */
da = rsda[drv] * RS_NUMWD (dtype);                      /* get disk addr */
fnc = GET_FNC (rscs1[drv]);                             /* get function */

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not attached? */
    rs_set_er (ER_UNS, drv);                            /* set drive error */
    if (fnc >= FNC_XFR)                                 /* xfr? set done */
        mba_set_don (rs_dib.ba);
    rs_update_ds (DS_ATA, drv);                         /* set attn */
    return (rs_stopioe? SCPE_UNATT: SCPE_OK);
    }
rsds[drv] = (rsds[drv] & ~DS_PIP) | DS_RDY;             /* change drive status */

switch (fnc) {                                          /* case on function */
 
    case FNC_SEARCH:                                    /* search */
        rs_update_ds (DS_ATA, drv);
        break;

    case FNC_WRITE:                                     /* write */
        if ((uptr->flags & UNIT_WLK) &&                 /* write locked? */
            (GET_TK (rsda[drv]) <= (int32) rswlk[drv])) {
            rs_set_er (ER_WLE, drv);                    /* set drive error */
            mba_set_exc (rs_dib.ba);                    /* set exception */
            rs_update_ds (DS_ATA, drv);                 /* set attn */
            return SCPE_OK;
            }
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
        if (rsda[drv] & DA_INV) {                       /* bad addr? */
            rs_set_er (ER_IAE, drv);                   /* set error */
            mba_set_exc (rs_dib.ba);                    /* set exception */
            rs_update_ds (DS_ATA, drv);                 /* set attn */
            break;
            }
        fbuf = fbuf + da;                               /* ptr into buffer */
        mbc = mba_get_bc (rs_dib.ba);                   /* get byte count */
        wc = (mbc + 1) >> 1;                            /* convert to words */
        if ((da + wc) > RS_SIZE (dtype)) {              /* disk overrun? */
            rs_set_er (ER_AOE, drv);                    /* set err */
            wc = RS_SIZE (dtype) - da;                  /* trim xfer */
            mbc = wc << 1;                              /* trim mb count */
            }
        if (fnc == FNC_WRITE) {                         /* write? */
            abc = mba_rdbufW (rs_dib.ba, mbc, fbuf);    /* rd mem to buf */
            wc = (abc + 1) >> 1;                        /* actual # wds */
            awc = (wc + (RS_NUMWD (dtype) - 1)) & ~(RS_NUMWD (dtype) - 1);
            for (i = wc; i < awc; i++)                  /* fill buf */
                fbuf[i] = 0;
            if ((da + awc) > (int32) uptr->hwmark)      /* update hw mark*/
                uptr->hwmark = da + awc;
            }                                           /* end if wr */
        else if (fnc == FNC_READ)                       /* read  */
Beispiel #2
0
t_stat rp_svc (UNIT *uptr)
{
int32 i, fnc, dtype, drv, err;
int32 wc, abc, awc, mbc, da;

dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
drv = (int32) (uptr - rp_dev.units);                    /* get drv number */
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD;   /* get disk addr */
fnc = GET_FNC (rpcs1[drv]);                             /* get function */

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not attached? */
    rp_set_er (ER1_UNS, drv);                           /* set drive error */
    if (fnc >= FNC_XFER)                                /* xfr? set done */
        mba_set_don (rp_dib.ba);
    rp_update_ds (DS_ATA, drv);                         /* set attn */
    return (rp_stopioe? SCPE_UNATT: SCPE_OK);
    }
rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY;             /* change drive status */

switch (fnc) {                                          /* case on function */

    case FNC_OFFSET:                                    /* offset */
        rp_update_ds (DS_OFM | DS_ATA, drv);
        break;

    case FNC_RETURN:                                    /* return to centerline */
        rpds[drv] = rpds[drv] & ~DS_OFM;                /* clear offset, set attn */
        rp_update_ds (DS_ATA, drv);
        break;  

    case FNC_UNLOAD:                                    /* unload */
        rp_detach (uptr);                               /* detach unit */
        break;

    case FNC_RECAL:                                     /* recalibrate */
    case FNC_SEARCH:                                    /* search */
    case FNC_SEEK:                                      /* seek */
        rp_update_ds (DS_ATA, drv);
        break;

    case FNC_WRITE:                                     /* write */
        if (uptr->flags & UNIT_WPRT) {                  /* write locked? */
            rp_set_er (ER1_WLE, drv);                   /* set drive error */
            mba_set_exc (rp_dib.ba);                    /* set exception */
            rp_update_ds (DS_ATA, drv);                 /* set attn */
            return SCPE_OK;
            }
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
    case FNC_READH:                                     /* read headers */
        err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET);
        mbc = mba_get_bc (rp_dib.ba);                   /* get byte count */
        wc = (mbc + 1) >> 1;                            /* convert to words */
        if ((da + wc) > drv_tab[dtype].size) {          /* disk overrun? */
            rp_set_er (ER1_AOE, drv);                   /* set err */
            wc = drv_tab[dtype].size - da;              /* trim xfer */
            mbc = wc << 1;                              /* trim mb count */
            if (da >= drv_tab[dtype].size) {            /* none left? */
                mba_set_exc (rp_dib.ba);                /* set exception */
                rp_update_ds (DS_ATA, drv);             /* set attn */
                break;
                }
            }
        if (fnc == FNC_WRITE) {                         /* write? */
            abc = mba_rdbufW (rp_dib.ba, mbc, rpxb);    /* get buffer */
            wc = (abc + 1) >> 1;                        /* actual # wds */
            awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
            for (i = wc; i < awc; i++)                  /* fill buf */
                rpxb[i] = 0;
            if (wc && !err) {                           /* write buf */
                fxwrite (rpxb, sizeof (uint16), awc, uptr->fileref);
                err = ferror (uptr->fileref);
                }
            }                                           /* end if wr */
        else {                                          /* read or wchk */