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 dp_set_size (UNIT *uptr, int32 val, char *cptr, void *desc) { if (uptr->flags & UNIT_ATT) return SCPE_ALATT; uptr->capac = drv_tab[GET_DTYPE (val)].size; return SCPE_OK; }
t_bool dp_dter (UNIT *uptr, uint32 first) { uint32 hd, sc, sa; uint32 dtype = GET_DTYPE (uptr->flags); /* get drive type */ if (((uptr->flags & UNIT_ATT) == 0) || /* not attached? */ ((uptr->flags & UNIT_WPRT) && (dp_cmd == CMC_WR))) { dp_done (STC_DTE); /* error, done */ return TRUE; } hd = GET_SRF (dp_hdsc); /* get head */ sc = GET_SEC (dp_hdsc); /* get sector */ if (dp_cyl != (uint32) uptr->CYL) { /* wrong cylinder? */ if (dp_cyl == 0) uptr->CYL = 0; else { dp_done (STC_ACF); /* error, done */ return TRUE; } } if (sc >= DP_NUMSC) { /* bad sector? */ dp_done (STC_OVR); /* error, done */ return TRUE; } if (!first && (sc == 0) && (hd == 0)) { /* cyl overflow? */ dp_done (STC_CYO); /* error, done */ return TRUE; } sa = GET_SA (dp_plat, uptr->CYL, hd, sc, dtype); /* curr disk addr */ fseek (uptr->fileref, sa * DP_NUMBY, SEEK_SET); if ((sc + 1) < DP_NUMSC) /* end of track? */ dp_hdsc = dp_hdsc + 1; else dp_hdsc = (dp_hdsc ^ HS_HMASK) & HS_HMASK; /* sec 0, nxt srf */ return FALSE; }
t_stat rs_mbrd (int32 *data, int32 ofs, int32 drv) { uint32 val, dtype, i; UNIT *uptr; rs_update_ds (0, drv); /* update ds */ uptr = rs_dev.units + drv; /* get unit */ if (uptr->flags & UNIT_DIS) { /* nx disk */ *data = 0; return MBE_NXD; } dtype = GET_DTYPE (uptr->flags); /* get drive type */ ofs = ofs & MBA_RMASK; /* mask offset */ switch (ofs) { /* decode offset */ case RS_CS1_OF: /* RSCS1 */ val = (rscs1[drv] & CS1_RW) | CS1_DVA; /* DVA always set */ break; case RS_DA_OF: /* RSDA */ val = rsda[drv]; break; case RS_DS_OF: /* RSDS */ val = rsds[drv] & ~DS_MBZ; break; case RS_ER_OF: /* RSER */ val = rser[drv] & ~ER_MBZ; break; case RS_AS_OF: /* RSAS */ val = 0; for (i = 0; i < RS_NUMDR; i++) { if (rsds[i] & DS_ATA) val |= (AS_U0 << i); } break; case RS_LA_OF: /* RSLA */ val = GET_POS (rs_wait); break; case RS_MR_OF: /* RSMR */ val = rsmr[drv]; break; case RS_DT_OF: /* RSDT */ val = dtype? RS04_ID: RS03_ID; break; default: /* all others */ *data = 0; return MBE_NXR; } *data = val; return SCPE_OK; }
uint32 dp (uint32 dev, uint32 op, uint32 dat) { int32 diff; uint32 t, u; UNIT *uptr; if (dev == dp_dib.dno) /* controller? */ return dpc (dev, op, dat); u = (dev - dp_dib.dno - o_DP0) / o_DP0; /* get unit num */ uptr = dp_dev.units + u; /* get unit ptr */ switch (op) { /* case IO op */ case IO_ADR: /* select */ if (dp_sta & STC_IDL) /* idle? save unit */ dp_svun = dev; return BY; /* byte only */ case IO_WD: /* write data */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DP%d WD = %02X, STA = %02X\n", u, dat, dp_sta); if (GET_DTYPE (uptr->flags) == TYPE_2315) /* 2.5MB drive? */ dp_cyl = dat & 0xFF; /* cyl is 8b */ else dp_cyl = ((dp_cyl << 8) | dat) & DMASK16; /* insert byte */ break; case IO_SS: /* status */ if (uptr->flags & UNIT_ATT) t = /* onl? */ ((uptr->flags & UNIT_WPRT)? STD_WRP: 0) | ((dp_sta & STC_IDL)? 0: STD_ILK) | (uptr->STD & STD_UST); else t = STD_MOV | STD_NRDY; /* off = X'09' */ if (t & SETD_EX) /* test for ex */ t = t | STA_EX; return t; case IO_OC: /* command */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DP%d OC = %02X, STA = %02X\n", u, dat, dp_sta); dpd_arm[u] = int_chg (v_DPC + u + 1, dat, dpd_arm[u]); if (dat & CMD_SK) /* seek? get cyl */ t = dp_cyl; else if (dat & CMD_RST) /* rest? cyl 0 */ t = 0; else break; /* no action */ diff = t - uptr->CYL; if (diff < 0) /* ABS cyl diff */ diff = -diff; else if (diff == 0) /* must be nz */ diff = 1; uptr->STD = STD_MOV; /* stat = moving */ uptr->CYL = t; /* put on cyl */ sim_activate (uptr, diff * dp_stime); /* schedule */ break; } return 0; }
t_stat rs_go (int32 drv) { int32 fnc, dtype, t; UNIT *uptr; fnc = GET_FNC (rscs1[drv]); /* get function */ if (DEBUG_PRS (rs_dev)) fprintf (sim_deb, ">>RS%d STRT: fnc=%s, ds=%o, da=%o, er=%o\n", drv, rs_fname[fnc], rsds[drv], rsda[drv], rser[drv]); uptr = rs_dev.units + drv; /* get unit */ rs_clr_as (AS_U0 << drv); /* clear attention */ dtype = GET_DTYPE (uptr->flags); /* get drive type */ if ((fnc != FNC_DCLR) && (rsds[drv] & DS_ERR)) { /* err & ~clear? */ rs_set_er (ER_ILF, drv); /* not allowed */ rs_update_ds (DS_ATA, drv); /* set attention */ return MBE_GOE; } switch (fnc) { /* case on function */ case FNC_DCLR: /* drive clear */ rser[drv] = 0; /* clear errors */ case FNC_NOP: /* no operation */ return SCPE_OK; case FNC_SEARCH: /* search */ case FNC_WRITE: /* write */ case FNC_WCHK: /* write check */ case FNC_READ: /* read */ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rs_set_er (ER_UNS, drv); /* unsafe */ break; } if (rsda[drv] & DA_INV) { /* bad address? */ rs_set_er (ER_IAE, drv); break; } rsds[drv] = rsds[drv] & ~DS_RDY; /* clr drive rdy */ if (fnc == FNC_SEARCH) /* search? */ rsds[drv] = rsds[drv] | DS_PIP; /* set PIP */ t = abs (rsda[drv] - GET_POS (rs_wait)); /* pos diff */ if (t < 1) /* min time */ t = 1; sim_activate (uptr, rs_wait * t); /* schedule */ return SCPE_OK; default: /* all others */ rs_set_er (ER_ILF, drv); /* not supported */ break; } rs_update_ds (DS_ATA, drv); /* set attn, req int */ return MBE_GOE; }
void dp_ini (t_bool dtpl) { int32 u, j, dev; dp_tplte[0] = 0; /* controller */ for (u = 0, j = 1; u < DP_NUMDR; u++) { /* loop thru units */ dev = (u + 1) * o_DP0; /* drive dev # */ dp_tplte[j++] = dev; if (dtpl && (GET_DTYPE (dp_unit[u].flags) == TYPE_5440)) dp_tplte[j++] = dev + o_DPF; /* if fixed */ } dp_tplte[j] = TPL_END; /* end marker */ return; }
t_stat rs_mbwr (int32 data, int32 ofs, int32 drv) { int32 dtype; UNIT *uptr; uptr = rs_dev.units + drv; /* get unit */ if (uptr->flags & UNIT_DIS) /* nx disk */ return MBE_NXD; if ((ofs != RS_AS_OF) && sim_is_active (uptr)) { /* unit busy? */ rs_set_er (ER_RMR, drv); /* won't write */ rs_update_ds (0, drv); return SCPE_OK; } dtype = GET_DTYPE (uptr->flags); /* get drive type */ ofs = ofs & MBA_RMASK; /* mask offset */ switch (ofs) { /* decode PA<5:1> */ case RS_CS1_OF: /* RSCS1 */ rscs1[drv] = data & CS1_RW; if (data & CS1_GO) /* start op */ return rs_go (drv); break; case RS_DA_OF: /* RSDA */ rsda[drv] = data; break; case RS_AS_OF: /* RSAS */ rs_clr_as (data); break; case RS_MR_OF: /* RSMR */ rsmr[drv] = data; break; case RS_ER_OF: /* RSER */ case RS_DS_OF: /* RSDS */ case RS_LA_OF: /* RSLA */ case RS_DT_OF: /* RSDT */ break; /* read only */ default: /* all others */ return MBE_NXR; } /* end switch */ rs_update_ds (0, drv); /* update status */ return SCPE_OK; }
t_stat dp_attach (UNIT *uptr, char *cptr) { uint32 i, p; t_stat r; uptr->capac = drv_tab[GET_DTYPE (uptr->flags)].size; r = attach_unit (uptr, cptr); /* attach unit */ if (r != SCPE_OK) /* error? */ return r; uptr->CYL = 0; if ((uptr->flags & UNIT_AUTO) == 0) /* autosize? */ return SCPE_OK; if ((p = ftell (uptr->fileref)) == 0) return SCPE_OK; for (i = 0; drv_tab[i].surf != 0; i++) { if (p <= drv_tab[i].size) { uptr->flags = (uptr->flags & ~UNIT_DTYPE) | (i << UNIT_V_DTYPE); uptr->capac = drv_tab[i].size; return SCPE_OK; } } return SCPE_OK; }
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 */
t_stat rp_go (int32 drv) { int32 dc, fnc, dtype, t; UNIT *uptr; fnc = GET_FNC (rpcs1[drv]); /* get function */ if (DEBUG_PRS (rp_dev)) fprintf (sim_deb, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n", drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]); uptr = rp_dev.units + drv; /* get unit */ rp_clr_as (AS_U0 << drv); /* clear attention */ dtype = GET_DTYPE (uptr->flags); /* get drive type */ dc = rpdc[drv]; /* assume seek, sch */ if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) { /* err & ~clear? */ rp_set_er (ER1_ILF, drv); /* not allowed */ rp_update_ds (DS_ATA, drv); /* set attention */ return MBE_GOE; } switch (fnc) { /* case on function */ case FNC_DCLR: /* drive clear */ rper1[drv] = rper2[drv] = rper3[drv] = 0; /* clear errors */ rpec2[drv] = 0; /* clear EC2 */ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? */ rpmr[drv] = 0; /* clear maint */ else rpec1[drv] = 0; /* RP, clear EC1 */ case FNC_NOP: /* no operation */ case FNC_RELEASE: /* port release */ return SCPE_OK; case FNC_PRESET: /* read-in preset */ rpdc[drv] = 0; /* clear disk addr */ rpda[drv] = 0; rpof[drv] = 0; /* clear offset */ case FNC_PACK: /* pack acknowledge */ rpds[drv] = rpds[drv] | DS_VV; /* set volume valid */ return SCPE_OK; case FNC_OFFSET: /* offset mode */ case FNC_RETURN: if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* unsafe */ break; } rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */ sim_activate (uptr, rp_swait); /* time operation */ return SCPE_OK; case FNC_UNLOAD: /* unload */ if (drv_tab[dtype].ctrl == RM_CTRL) { /* RM? */ rp_set_er (ER1_ILF, drv); /* not supported */ break; } rp_detach (uptr); /* detach unit */ return SCPE_OK; case FNC_RECAL: /* recalibrate */ dc = 0; /* seek to 0 */ case FNC_SEEK: /* seek */ case FNC_SEARCH: /* search */ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* unsafe */ break; } if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */ (GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */ (GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */ rp_set_er (ER1_IAE, drv); break; } rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP; /* set positioning */ t = abs (dc - uptr->CYL); /* cyl diff */ if (t == 0) /* min time */ t = 1; sim_activate (uptr, rp_swait * t); /* schedule */ uptr->CYL = dc; /* save cylinder */ return SCPE_OK; case FNC_WRITEH: /* write headers */ case FNC_WRITE: /* write */ case FNC_WCHK: /* write check */ case FNC_READ: /* read */ case FNC_READH: /* read headers */ if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ rp_set_er (ER1_UNS, drv); /* unsafe */ break; } if ((GET_CY (dc) >= drv_tab[dtype].cyl) || /* bad cylinder */ (GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */ (GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */ rp_set_er (ER1_IAE, drv); break; } rpds[drv] = rpds[drv] & ~DS_RDY; /* clear drive rdy */ sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr->CYL))); uptr->CYL = dc; /* save cylinder */ return SCPE_OK; default: /* all others */ rp_set_er (ER1_ILF, drv); /* not supported */ break; } rp_update_ds (DS_ATA, drv); /* set attn, req int */ return MBE_GOE; }
t_stat rp_mbwr (int32 data, int32 ofs, int32 drv) { int32 dtype; UNIT *uptr; uptr = rp_dev.units + drv; /* get unit */ if (uptr->flags & UNIT_DIS) /* nx disk */ return MBE_NXD; if ((ofs != RP_AS_OF) && sim_is_active (uptr)) { /* unit busy? */ rp_set_er (ER1_RMR, drv); /* won't write */ rp_update_ds (0, drv); return SCPE_OK; } rmhr[drv] = data; /* save write */ dtype = GET_DTYPE (uptr->flags); /* get drive type */ ofs = ofs & MBA_RMASK; /* mask offset */ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? convert */ ofs = ofs + RM_OF; switch (ofs) { /* decode PA<5:1> */ case RP_CS1_OF: case RM_CS1_OF: /* RPCS1 */ rpcs1[drv] = data & CS1_RW; if (data & CS1_GO) /* start op */ return rp_go (drv); break; case RP_DA_OF: case RM_DA_OF: /* RPDA */ rpda[drv] = data & ~DA_MBZ; break; case RP_AS_OF: case RM_AS_OF: /* RPAS */ rp_clr_as (data); break; case RP_MR_OF: case RM_MR_OF: /* RPMR */ rpmr[drv] = data; break; case RP_OF_OF: case RM_OF_OF: /* RPOF */ rpof[drv] = data & ~OF_MBZ; break; case RP_DC_OF: case RM_DC_OF: /* RPDC */ rpdc[drv] = data & ~DC_MBZ; break; case RM_MR2_OF: /* RMMR2 */ rmmr2[drv] = data; break; case RP_ER1_OF: case RM_ER1_OF: /* RPER1 */ case RP_DS_OF: case RM_DS_OF: /* RPDS */ case RP_LA_OF: case RM_LA_OF: /* RPLA */ case RP_DT_OF: case RM_DT_OF: /* RPDT */ case RP_SN_OF: case RM_SN_OF: /* RPSN */ case RP_CC_OF: /* RPCC */ case RP_ER2_OF: case RM_ER2_OF: /* RPER2 */ case RP_ER3_OF: /* RPER3 */ case RP_EC1_OF: case RM_EC1_OF: /* RPEC1 */ case RP_EC2_OF: case RM_EC2_OF: /* RPEC2 */ case RM_HR_OF: /* RMHR */ break; /* read only */ default: /* all others */ return MBE_NXR; } /* end switch */ rp_update_ds (0, drv); /* update status */ return SCPE_OK; }
t_stat rp_mbrd (int32 *data, int32 ofs, int32 drv) { uint32 val, dtype, i; UNIT *uptr; rp_update_ds (0, drv); /* update ds */ uptr = rp_dev.units + drv; /* get unit */ if (uptr->flags & UNIT_DIS) { /* nx disk */ *data = 0; return MBE_NXD; } dtype = GET_DTYPE (uptr->flags); /* get drive type */ ofs = ofs & MBA_RMASK; /* mask offset */ if (drv_tab[dtype].ctrl == RM_CTRL) /* RM? convert */ ofs = ofs + RM_OF; switch (ofs) { /* decode offset */ case RP_CS1_OF: case RM_CS1_OF: /* RPCS1 */ val = (rpcs1[drv] & CS1_RW) | CS1_DVA; /* DVA always set */ break; case RP_DA_OF: case RM_DA_OF: /* RPDA */ val = rpda[drv] = rpda[drv] & ~DA_MBZ; break; case RP_DS_OF: case RM_DS_OF: /* RPDS */ val = rpds[drv]; break; case RP_ER1_OF: case RM_ER1_OF: /* RPER1 */ val = rper1[drv]; break; case RP_AS_OF: case RM_AS_OF: /* RPAS */ val = 0; for (i = 0; i < RP_NUMDR; i++) { if (rpds[i] & DS_ATA) val |= (AS_U0 << i); } break; case RP_LA_OF: case RM_LA_OF: /* RPLA */ val = GET_SECTOR (rp_rwait, dtype) << LA_V_SC; break; case RP_MR_OF: case RM_MR_OF: /* RPMR */ val = rpmr[drv]; break; case RP_DT_OF: case RM_DT_OF: /* RPDT */ val = drv_tab[dtype].devtype; break; case RP_SN_OF: case RM_SN_OF: /* RPSN */ val = 020 | (drv + 1); break; case RP_OF_OF: case RM_OF_OF: /* RPOF */ val = rpof[drv] = rpof[drv] & ~OF_MBZ; break; case RP_DC_OF: case RM_DC_OF: /* RPDC */ val = rpdc[drv] = rpdc[drv] & ~DC_MBZ; break; case RP_CC_OF: /* RPCC */ val = rp_unit[drv].CYL; break; case RP_ER2_OF: case RM_ER2_OF: /* RPER2 */ val = rper2[drv]; break; case RP_ER3_OF: /* RPER3 */ val = rper3[drv]; break; case RP_EC1_OF: case RM_EC1_OF: /* RPEC1 */ val = rpec1[drv]; break; case RP_EC2_OF: case RM_EC2_OF: /* RPEC2 */ val = rpec2[drv]; break; case RM_HR_OF: /* RMHR */ val = rmhr[drv] ^ DMASK; break; case RM_MR2_OF: /* RHMR2 */ val = rmmr2[drv]; break; default: /* all others */ *data = 0; return MBE_NXR; } *data = val; return SCPE_OK; }
t_stat dp_svc (UNIT *uptr) { uint32 u = uptr - dp_dev.units; /* get unit number */ int32 cyl = uptr->CYL; /* get cylinder */ uint32 dtype = GET_DTYPE (uptr->flags); /* get drive type */ t_stat r; if (uptr->STD & STD_MOV) { /* seek? */ uptr->STD = 0; /* clr seek in prog */ if ((uptr->flags & UNIT_ATT) == 0) /* offl? hangs */ return SCPE_OK; if (cyl >= drv_tab[dtype].cyl) { /* bad cylinder? */ uptr->STD = STD_ILA; /* error */ uptr->CYL = drv_tab[dtype].cyl - 1; /* put at edge */ } if (dpd_arm[u]) /* req intr */ SET_INT (v_DPC + u + 1); return SCPE_OK; } switch (dp_cmd & 0x7) { /* case on func */ case CMC_RCHK: /* read check */ dp_dter (uptr, 1); /* check xfr err */ break; case CMC_RD: /* read */ if (sch_actv (dp_dib.sch, dp_dib.dno)) { /* sch transfer? */ if (dp_dter (uptr, dp_1st)) /* check xfr err */ return SCPE_OK; if ((r = dp_rds (uptr))) /* read sec, err? */ return r; dp_1st = 0; sch_wrmem (dp_dib.sch, dpxb, DP_NUMBY); /* write to memory */ if (sch_actv (dp_dib.sch, dp_dib.dno)) { /* more to do? */ sim_activate (uptr, dp_rtime); /* reschedule */ return SCPE_OK; } break; /* no, set done */ } dp_sta = dp_sta | STC_DTE; /* can't work */ break; case CMC_WR: /* write */ if (sch_actv (dp_dib.sch, dp_dib.dno)) { /* sch transfer? */ if (dp_dter (uptr, dp_1st)) /* check xfr err */ return SCPE_OK; dp_bptr = sch_rdmem (dp_dib.sch, dpxb, DP_NUMBY); /* read from mem */ dp_db = dpxb[dp_bptr - 1]; /* last byte */ if ((r = dp_wds (uptr))) /* write sec, err? */ return r; dp_1st = 0; if (sch_actv (dp_dib.sch, dp_dib.dno)) { /* more to do? */ sim_activate (uptr, dp_rtime); /* reschedule */ return SCPE_OK; } break; /* no, set done */ } dp_sta = dp_sta | STC_DTE; /* can't work */ break; } /* end case func */ dp_done (0); /* done */ return SCPE_OK; }