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; }
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 ts_svc (UNIT *uptr) { int32 i, t, bc, fnc, mod, st0, st1; static const int32 fnc_mod[CMD_N_FNC] = { /* max mod+1 0 ill */ 0, 4, 0, 0, 1, 2, 1, 0, /* 00 - 07 */ 5, 3, 5, 1, 0, 0, 0, 1, /* 10 - 17 */ 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 27 */ 0, 0, 0, 0, 0, 0, 0, 0 /* 30 - 37 */ }; static const int32 fnc_flg[CMD_N_FNC] = { 0, FLG_MO+FLG_AD, 0, 0, 0, FLG_MO+FLG_WR+FLG_AD, FLG_AD, 0, FLG_MO, FLG_MO+FLG_WR, FLG_MO, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 20 - 27 */ 0, 0, 0, 0, 0, 0, 0, 0 /* 30 - 37 */ }; static const char *fnc_name[CMD_N_FNC] = { "0", "READ", "2", "3", "WCHR", "WRITE", "WSSM", "7", "POS", "FMT", "CTL", "INIT", "14", "15", "16", "GSTA", "20", "21", "22", "23", "24", "25", "26", "27", "30", "31", "32", "33", "34", "35", "36", "37" }; if (ts_bcmd) { /* boot? */ ts_bcmd = 0; /* clear flag */ sim_tape_rewind (uptr); /* rewind */ if (uptr->flags & UNIT_ATT) { /* attached? */ cmdlnt = cmdadh = cmdadl = 0; /* defang rd */ ts_spacef (uptr, 1, FALSE); /* space fwd */ ts_readf (uptr, 512); /* read blk */ tssr = ts_updtssr (tssr | TSSR_SSR); } else tssr = ts_updtssr (tssr | TSSR_SSR | TC3); if (cmdhdr & CMD_IE) SET_INT (TS); return SCPE_OK; } if (!(cmdhdr & CMD_ACK)) { /* no acknowledge? */ tssr = ts_updtssr (tssr | TSSR_SSR); /* set rdy, int */ if (cmdhdr & CMD_IE) SET_INT (TS); ts_ownc = ts_ownm = 0; /* CPU owns all */ return SCPE_OK; } fnc = GET_FNC (cmdhdr); /* get fnc+mode */ mod = GET_MOD (cmdhdr); if (DEBUG_PRS (ts_dev)) { fprintf (sim_deb, ">>TS: cmd=%s, mod=%o, buf=%o, lnt=%d, pos=", fnc_name[fnc], mod, cmdadl, cmdlnt); fprint_val (sim_deb, ts_unit.pos, 10, T_ADDR_W, PV_LEFT); fprintf (sim_deb, "\n"); } if ((fnc != FNC_WCHR) && (tssr & TSSR_NBA)) { /* ~wr chr & nba? */ ts_endcmd (TC3, 0, 0); /* error */ return SCPE_OK; } if (ts_qatn && (wchopt & WCH_EAI)) { /* attn pending? */ ts_endcmd (TC1, 0, MSG_MATN | MSG_CATN); /* send attn msg */ SET_INT (TS); /* set interrupt */ ts_qatn = 0; /* not pending */ return SCPE_OK; } if (cmdhdr & CMD_CVC) /* cvc? clr vck */ msgxs0 = msgxs0 & ~XS0_VCK; if ((cmdhdr & CMD_MBZ) || (mod >= fnc_mod[fnc])) { /* test mbz */ ts_endcmd (TC3, XS0_ILC, MSG_ACK | MSG_MILL | MSG_CFAIL); return SCPE_OK; } if ((fnc_flg[fnc] & FLG_MO) && /* mot+(vck|!att)? */ ((msgxs0 & XS0_VCK) || !(uptr->flags & UNIT_ATT))) { ts_endcmd (TC3, XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } if ((fnc_flg[fnc] & FLG_WR) && /* write? */ sim_tape_wrp (uptr)) { /* write lck? */ ts_endcmd (TC3, XS0_WLE | XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } if ((((fnc == FNC_READ) && (mod == 1)) || /* read rev */ ((fnc == FNC_POS) && (mod & 1))) && /* space rev */ sim_tape_bot (uptr)) { /* BOT? */ ts_endcmd (TC3, XS0_NEF, MSG_ACK | MSG_MNEF | MSG_CFAIL); return SCPE_OK; } if ((fnc_flg[fnc] & FLG_AD) && (cmdadh & ADDRTEST)) { /* buf addr > 22b? */ ts_endcmd (TC3, XS0_ILA, MSG_ACK | MSG_MILL | MSG_CFAIL); return SCPE_OK; } st0 = st1 = 0; switch (fnc) { /* case on func */ case FNC_INIT: /* init */ if (!sim_tape_bot (uptr)) /* set if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); /* rewind */ case FNC_WSSM: /* write mem */ case FNC_GSTA: /* get status */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); /* send end packet */ return SCPE_OK; case FNC_WCHR: /* write char */ if ((cmdadh & ADDRTEST) || (cmdadl & 1) || (cmdlnt < 6)) { ts_endcmd (TSSR_NBA | TC3, XS0_ILA, 0); break; } tsba = (cmdadh << 16) | cmdadl; bc = ((WCH_PLNT << 1) > cmdlnt)? cmdlnt: WCH_PLNT << 1; t = Map_ReadW (tsba, bc, cpy_buf); /* fetch packet */ tsba = tsba + (bc - t); /* inc tsba */ if (t) { /* nxm? */ ts_endcmd (TSSR_NBA | TSSR_NXM | TC5, 0, 0); return SCPE_OK; } for (i = 0; i < (bc / 2); i++) /* copy packet */ tswchp[i] = cpy_buf[i]; if ((wchlnt < ((MSG_PLNT - 1) * 2)) || (wchadh & 0177700) || (wchadl & 1)) ts_endcmd (TSSR_NBA | TC3, 0, 0); else { msgxs2 = msgxs2 | XS2_XTF | 1; tssr = ts_updtssr (tssr & ~TSSR_NBA); ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); } return SCPE_OK; case FNC_CTL: /* control */ switch (mod) { /* case mode */ case 00: /* msg buf rls */ tssr = ts_updtssr (tssr | TSSR_SSR); /* set SSR */ if (wchopt & WCH_ERI) SET_INT (TS); ts_ownc = 0; ts_ownm = 1; /* keep msg */ break; case 01: /* rewind and unload */ if (!sim_tape_bot (uptr)) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_detach (uptr); /* unload */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); break; case 02: /* clean */ ts_endcmd (TC0, 0, MSG_ACK | MSG_CEND); /* nop */ break; case 03: /* undefined */ ts_endcmd (TC3, XS0_ILC, MSG_ACK | MSG_MILL | MSG_CFAIL); return SCPE_OK; case 04: /* rewind */ if (!sim_tape_bot (uptr)) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); ts_endcmd (TC0, XS0_BOT, MSG_ACK | MSG_CEND); break; } break; case FNC_READ: /* read */ switch (mod) { /* case mode */ case 00: /* fwd */ st0 = ts_readf (uptr, cmdlnt); /* read */ break; case 01: /* back */ st0 = ts_readr (uptr, cmdlnt); /* read */ break; case 02: /* reread fwd */ if (cmdhdr & CMD_OPP) { /* opposite? */ st0 = ts_readr (uptr, cmdlnt); st1 = ts_spacef (uptr, 1, FALSE); } else { st0 = ts_spacer (uptr, 1, FALSE); st1 = ts_readf (uptr, cmdlnt); } break; case 03: /* reread back */ if (cmdhdr & CMD_OPP) { /* opposite */ st0 = ts_readf (uptr, cmdlnt); st1 = ts_spacer (uptr, 1, FALSE); } else { st0 = ts_spacef (uptr, 1, FALSE); st1 = ts_readr (uptr, cmdlnt); } break; } ts_cmpendcmd (st0, st1); break; case FNC_WRIT: /* write */ switch (mod) { /* case mode */ case 00: /* write */ st0 = ts_write (uptr, cmdlnt); break; case 01: /* rewrite */ st0 = ts_spacer (uptr, 1, FALSE); st1 = ts_write (uptr, cmdlnt); break; } ts_cmpendcmd (st0, st1); break; case FNC_FMT: /* format */ switch (mod) { /* case mode */ case 00: /* write tmk */ st0 = ts_wtmk (uptr); break; case 01: /* erase */ break; case 02: /* retry tmk */ st0 = ts_spacer (uptr, 1, FALSE); st1 = ts_wtmk (uptr); break; } ts_cmpendcmd (st0, st1); break; case FNC_POS: /* position */ switch (mod) { /* case mode */ case 00: /* space fwd */ st0 = ts_spacef (uptr, cmdadl, TRUE); break; case 01: /* space rev */ st0 = ts_spacer (uptr, cmdadl, TRUE); break; case 02: /* space ffwd */ st0 = ts_skipf (uptr, cmdadl); break; case 03: /* space frev */ st0 = ts_skipr (uptr, cmdadl); break; case 04: /* rewind */ if (!sim_tape_bot (uptr)) /* if tape moves */ msgxs0 = msgxs0 | XS0_MOT; sim_tape_rewind (uptr); break; } ts_cmpendcmd (st0, 0); break; } return SCPE_OK; }
uint32 dpc (uint32 dev, uint32 op, uint32 dat) { uint32 f, t, u; UNIT *uptr; static uint8 good_cmd[8] = { 0, 1, 1, 1, 0, 0, 0, 0 }; switch (op) { /* case IO op */ case IO_ADR: /* select */ sch_adr (dp_dib.sch, dev); /* inform sel ch */ return BY; /* byte only */ case IO_RD: /* read data */ if (dp_sta & STC_IDL) /* if idle */ return GET_ROTATE (dp_rtime); /* return sector */ else dp_sta = dp_sta | STA_BSY; /* xfr? set busy */ return dp_db; /* return data */ case IO_WD: /* write data */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DPC WD = %02X, STA = %02X\n", dat, dp_sta); if (dp_sta & STC_IDL) /* idle? hdsc */ dp_hdsc = dat & HS_MASK; else { /* data xfer */ dp_sta = dp_sta | STA_BSY; /* set busy */ dp_db = dat & 0xFF; /* store data */ } break; case IO_SS: /* status */ t = dp_sta & STC_MASK; /* get status */ if (t & SETC_EX) /* test for EX */ t = t | STA_EX; return t; case IO_OC: /* command */ if (DEBUG_PRS (dp_dev)) fprintf (sim_deb, ">>DPC OC = %02X, STA = %02X\n", dat, dp_sta); f = dat & CMC_MASK; /* get cmd */ if (f & CMC_CLR) { /* clear? */ dp_reset (&dp_dev); /* reset world */ break; } u = (dp_svun - dp_dib.dno - o_DP0) / o_DP0; /* get unit */ uptr = dp_dev.units + u; /* ignore if busy */ if (!(dp_sta & STC_IDL) || sim_is_active (uptr)) break; dp_cmd = f; /* save cmd */ if (dp_cmd == CMC_WR) /* write: bsy=0 else */ dp_sta = 0; else dp_sta = STA_BSY; /* bsy=1,idl,err=0 */ dp_1st = 1; /* xfr not started */ dp_bptr = 0; /* buffer empty */ if (dp_svun & o_DPF) /* upper platter? */ dp_plat = 1; else dp_plat = 0; /* no, lower */ if (good_cmd[f]) /* legal? sched */ sim_activate (uptr, dp_rtime); break; } return 0; }
t_stat mt_io (int32 unit, int32 flag, int32 mod) { int32 t, wm_seen; t_mtrlnt i, tbc; t_stat st; t_bool passed_eot; UNIT *uptr; ind[IN_TAP] = 0; /* clear error */ if ((uptr = mt_sel_unit (unit)) == NULL) /* sel unit, save */ return STOP_INVMTU; /* (not valid) */ if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ return SCPE_UNATT; switch (mod) { case BCD_R: /* read */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: read from %d", unit, BS); wm_seen = 0; /* no word mk seen */ st = sim_tape_rdrecf (uptr, dbuf, &tbc, MT_MAXFR); /* read rec */ if (st != MTSE_TMK) { /* not tmk? */ if (st == MTSE_RECE) /* rec in error? */ ind[IN_TAP] = 1; else if (st != MTSE_OK) { /* stop on error */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ", stopped by status = %d\n", st); break; } if (!(flag & MD_BIN) && /* BCD tape and */ ((dbuf[0] & CHAR) == BCD_TAPMRK)) /* first char TMK? */ uptr->IND = 1; /* set indicator */ } for (i = 0; i < tbc; i++) { /* loop thru buf */ if (!(flag & MD_BOOT) && /* not boot? check */ (M[BS] == (BCD_GRPMRK + WM))) { /* GWM in memory? */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, " to %d, stopped by GMWM\n", BS); BS++; /* incr BS */ if (ADDR_ERR (BS)) { /* test for wrap */ BS = BA | (BS % MAXMEMSIZE); return STOP_WRAP; } return SCPE_OK; /* done */ } t = dbuf[i] & CHAR; /* get char, strip parity */ if (!(flag & MD_BIN) && (t == BCD_ALT)) /* BCD mode alt blank? */ t = BCD_BLANK; /* real blank */ if (flag & MD_WM) { /* word mk mode? */ if ((t == BCD_WM) && (wm_seen == 0)) /* WM char, none prev? */ wm_seen = WM; /* set flag */ else { M[BS] = wm_seen | (t & CHAR); /* char + wm seen */ wm_seen = 0; /* clear flag */ } } else M[BS] = (M[BS] & WM) | (t & CHAR); /* preserve mem WM */ if (!wm_seen) BS++; if (ADDR_ERR (BS)) { /* check next BS */ BS = BA | (BS % MAXMEMSIZE); return STOP_WRAP; } } if (M[BS] != (BCD_GRPMRK + WM)) { /* not GM+WM at end? */ if (flag & MD_WM) /* LCA: clear WM */ M[BS] = BCD_GRPMRK; else M[BS] = (M[BS] & WM) | BCD_GRPMRK; /* MCW: save WM */ } if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, " to %d, stopped by EOR\n", BS); BS++; /* adv BS */ if (ADDR_ERR (BS)) { /* check final BS */ BS = BA | (BS % MAXMEMSIZE); return STOP_WRAP; } break; case BCD_W: if (sim_tape_wrp (uptr)) /* locked? */ return STOP_MTL; if (M[BS] == (BCD_GRPMRK + WM)) /* eor? */ return STOP_MTZ; if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: write from %d", unit, BS); for (tbc = 0; (t = M[BS++]) != (BCD_GRPMRK + WM); ) { if ((t & WM) && (flag & MD_WM)) /* WM in wm mode? */ dbuf[tbc++] = BCD_WM; if (((t & CHAR) == BCD_BLANK) && !(flag & MD_BIN)) dbuf[tbc++] = BCD_ALT; else dbuf[tbc++] = t & CHAR; if (ADDR_ERR (BS)) { /* check next BS */ BS = BA | (BS % MAXMEMSIZE); return STOP_WRAP; } } if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, " to %d\n", BS - 1); passed_eot = sim_tape_eot (uptr); /* passed EOT? */ st = sim_tape_wrrecf (uptr, dbuf, tbc); /* write record */ if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */ ind[IN_END] = 1; if (ADDR_ERR (BS)) { /* check final BS */ BS = BA | (BS % MAXMEMSIZE); return STOP_WRAP; } break; default: return STOP_INVM; } return mt_map_status (st); }
t_stat mt_func (int32 unit, int32 flag, int32 mod) { t_mtrlnt tbc; UNIT *uptr; t_stat st; ind[IN_TAP] = 0; /* clear error */ if ((uptr = mt_sel_unit (unit)) == NULL) /* sel unit, save */ return STOP_INVMTU; /* (not valid) */ if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ return SCPE_UNATT; switch (mod) { /* case on modifier */ case BCD_A: /* diagnostic read */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: diagnostic read\n", unit); st = sim_tape_rdrecf (uptr, dbuf, &tbc, MT_MAXFR); /* read rec */ if (st != MTSE_TMK) { /* not tmk? */ if (st == MTSE_RECE) /* rec in error? */ ind[IN_TAP] = 1; else if (st != MTSE_OK) { /* stop on error */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ", stopped by status = %d\n", st); break; } if (!(flag & MD_BIN) && /* BCD tape and */ ((dbuf[0] & CHAR) == BCD_TAPMRK)) /* first char TMK? */ uptr->IND = 1; /* set indicator */ } break; case BCD_B: /* backspace */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: backspace\n", unit); st = sim_tape_sprecr (uptr, &tbc); /* space rev */ break; /* end case */ case BCD_E: /* erase = nop */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: erase\n", unit); if (sim_tape_wrp (uptr)) /* write protected? */ return STOP_MTL; return SCPE_OK; case BCD_M: /* write tapemark */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: write tape mark\n", unit); st = sim_tape_wrtmk (uptr); /* write tmk */ break; case BCD_R: /* rewind */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: rewind\n", unit); sim_tape_rewind (uptr); /* update position */ return SCPE_OK; case BCD_U: /* unload */ if (DEBUG_PRS (mt_dev)) fprintf (sim_deb, ">>MT%d: rewind and unload\n", unit); sim_tape_rewind (uptr); /* update position */ st = mt_detach (uptr); /* detach */ break; default: return STOP_INVM; } return mt_map_status (st); }