Пример #1
0
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;
}
Пример #2
0
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;
}