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 */
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 */