void dp_done (uint32 flg) { dp_sta = (dp_sta | STC_IDL | flg) & ~STA_BSY; /* set flag, idle */ SET_INT (v_DPC); /* unmaskable intr */ if (flg) /* if err, stop ch */ sch_stop (dp_dib.sch); return; }
t_stat mt_svc (UNIT *uptr) { uint32 i; int32 u = uptr - mt_dev.units; uint32 dev = mt_dib.dno + (u * o_MT0); t_mtrlnt tbc; t_bool passed_eot; t_stat st, r = SCPE_OK; if ((uptr->flags & UNIT_ATT) == 0) { /* not attached? */ uptr->UCMD = 0; /* clr cmd */ uptr->UST = 0; /* set status */ mt_xfr = 0; /* clr op flags */ mt_sta = STA_ERR | STA_EOM; /* set status */ if (mt_arm[u]) /* interrupt */ SET_INT (v_MT + u); return IORETURN (mt_stopioe, SCPE_UNATT); } if (uptr->UCMD & MTC_STOP2) { /* stop, gen NMTN? */ uptr->UCMD = 0; /* clr cmd */ uptr->UST = uptr->UST | STA_NMTN; /* set nmtn */ mt_xfr = 0; /* clr xfr */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); return SCPE_OK; } if (uptr->UCMD & MTC_STOP1) { /* stop, gen EOM? */ uptr->UCMD = uptr->UCMD | MTC_STOP2; /* clr cmd */ mt_sta = (mt_sta & ~STA_BSY) | STA_EOM; /* clr busy, set eom */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); sim_activate (uptr, mt_rtime); /* schedule */ return SCPE_OK; } passed_eot = sim_tape_eot (uptr); /* passed EOT? */ switch (uptr->UCMD) { /* case on function */ case MTC_REW: /* rewind */ sim_tape_rewind (uptr); /* reposition */ uptr->UCMD = 0; /* clr cmd */ uptr->UST = STA_NMTN | STA_EOT; /* update status */ mt_sta = mt_sta & ~STA_BSY; /* don't set EOM */ if (mt_arm[u]) /* interrupt */ SET_INT (v_MT + u); return SCPE_OK; /* For read, busy = 1 => buffer empty For write, busy = 1 => buffer full For read, data transfers continue for the full length of the record, or the maximum size of the transfer buffer For write, data transfers continue until a write is attempted and the buffer is empty */ case MTC_RD: /* read */ if (mt_blnt == 0) { /* first time? */ st = sim_tape_rdrecf (uptr, mtxb, &tbc, MT_MAXFR); /* read rec */ if (st == MTSE_RECE) /* rec in err? */ mt_sta = mt_sta | STA_ERR; else if (st != SCPE_OK) { /* other error? */ r = mt_map_err (uptr, st); /* map error */ if (sch_actv (mt_dib.sch, dev)) /* if sch, stop */ sch_stop (mt_dib.sch); break; } mt_blnt = tbc; /* set buf lnt */ } if (sch_actv (mt_dib.sch, dev)) { /* sch active? */ i = sch_wrmem (mt_dib.sch, mtxb, mt_blnt); /* store rec in mem */ if (sch_actv (mt_dib.sch, dev)) /* sch still active? */ sch_stop (mt_dib.sch); /* stop chan, long rd */ else if (i < mt_blnt) /* process entire rec? */ mt_sta = mt_sta | STA_ERR; /* no, overrun error */ } else if (mt_bptr < mt_blnt) { /* no, if !eor */ if (!(mt_sta & STA_BSY)) /* busy still clr? */ mt_sta = mt_sta | STA_ERR; /* read overrun */ mt_db = mtxb[mt_bptr++]; /* get next byte */ mt_sta = mt_sta & ~STA_BSY; /* !busy = buf full */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); sim_activate (uptr, mt_wtime); /* reschedule */ return SCPE_OK; } break; /* record done */ case MTC_WR: /* write */ if (sch_actv (mt_dib.sch, dev)) { /* sch active? */ mt_bptr = sch_rdmem (mt_dib.sch, mtxb, MT_MAXFR); /* get rec */ if (sch_actv (mt_dib.sch, dev)) /* not done? */ sch_stop (mt_dib.sch); /* stop chan */ } else if (mt_sta & STA_BSY) { /* no, if !eor */ if (mt_bptr < MT_MAXFR) /* if room */ mtxb[mt_bptr++] = mt_db; /* store in buf */ mt_sta = mt_sta & ~STA_BSY; /* !busy = buf emp */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); sim_activate (uptr, mt_wtime); /* reschedule */ return SCPE_OK; } if (mt_bptr) { /* any chars? */ if ((st = sim_tape_wrrecf (uptr, mtxb, mt_bptr)))/* write, err? */ r = mt_map_err (uptr, st); /* map error */ } break; /* record done */ case MTC_WEOF: /* write eof */ if ((st = sim_tape_wrtmk (uptr))) /* write tmk, err? */ r = mt_map_err (uptr, st); /* map error */ mt_sta = mt_sta | STA_EOF; /* set eof */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); break; case MTC_SKFF: /* skip file fwd */ while ((st = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ; if (st == MTSE_TMK) { /* stopped by tmk? */ mt_sta = mt_sta | STA_EOF; /* set eof */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); } else r = mt_map_err (uptr, st); /* map error */ break; case MTC_SKFR: /* skip file rev */ while ((st = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ; if (st == MTSE_TMK) { /* stopped by tmk? */ mt_sta = mt_sta | STA_EOF; /* set eof */ if (mt_arm[u]) /* set intr */ SET_INT (v_MT + u); } else r = mt_map_err (uptr, st); /* map error */ break; case MTC_SPCR: /* backspace */ if ((st = sim_tape_sprecr (uptr, &tbc))) /* skip rec rev, err? */ r = mt_map_err (uptr, st); /* map error */ break; } /* end case */ if (!passed_eot && sim_tape_eot (uptr)) /* just passed EOT? */ uptr->UST = uptr->UST | STA_EOT; uptr->UCMD = uptr->UCMD | MTC_STOP1; /* set stop stage 1 */ sim_activate (uptr, mt_rtime); /* schedule */ return r; }