Пример #1
0
int32 ts_skipf (UNIT *uptr, int32 fc)
{
t_stat st;
t_mtrlnt tbc;
t_bool tmkprv = FALSE;

msgrfc = fc;
if (sim_tape_bot (uptr) && (wchopt & WCH_ENB))
    tmkprv = TRUE;
do {
    st = sim_tape_sprecf (uptr, &tbc);                  /* space rec fwd */
    if (st == MTSE_TMK) {                               /* tape mark? */
        msgrfc = (msgrfc - 1) & DMASK;                  /* decr count */
        msgxs0 = msgxs0 | XS0_MOT;                      /* tape has moved */
        if (tmkprv && (wchopt & WCH_ESS))               /* 2nd tmk & ESS? */
            return (XTC ((msgrfc? XS0_RLS: 0) |
                XS0_TMK | XS0_LET, TC2));
        tmkprv = TRUE;                                  /* flag tmk */
        }
    else if (st != MTSE_OK)
        return ts_map_status (st);
    else tmkprv = FALSE;                                /* not a tmk */
    msgxs0 = msgxs0 | XS0_MOT;                          /* tape has moved */
    } while (msgrfc != 0);
return 0;
}
Пример #2
0
t_stat mt_reset (DEVICE *dptr)
{
hp_enbdis_pair (dptr,                                   /* make pair cons */
    (dptr == &mtd_dev) ? &mtc_dev : &mtd_dev);

if (dptr == &mtc_dev)                                   /* command channel reset? */
    mtcio (mtc_dib.devno, ioPOPIO, 0);                  /* send POPIO signal to command channel */
else                                                    /* data channel reset */
    mtdio (mtd_dib.devno, ioPOPIO, 0);                  /* send POPIO signal to data channel */

mtc_fnc = 0;
mtc_1st = mtc_dtf = 0;

sim_cancel (&mtc_unit);                                 /* cancel activity */
sim_tape_reset (&mtc_unit);

if (mtc_unit.flags & UNIT_ATT)
    mtc_sta = (sim_tape_bot (&mtc_unit)? STA_BOT: 0) |
              (sim_tape_wrp (&mtc_unit)? STA_WLK: 0);
else
    mtc_sta = STA_LOCAL | STA_BUSY;

return SCPE_OK;
}
Пример #3
0
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;
}
Пример #4
0
/* Handle processing of tape requests. */
t_stat mt_srv(UNIT * uptr)
{
    int                 chan = uptr->u5 & MT_CHAN;
    int                 unit = uptr - mt_unit;
    int                 cmd = uptr->u5 & MT_CMD;
    DEVICE              *dptr = find_dev_from_unit(uptr);
    t_mtrlnt            reclen;
    t_stat              r = SCPE_ARG;   /* Force error if not set */
    uint8               ch;
    int                 mode;
    t_mtrlnt            loc;


    /* Simulate tape load delay */
    if (uptr->u5 & MT_LOADED) {
        uptr->u5 &= ~MT_LOADED;
        uptr->u5 |= MT_BSY|MT_RDY;
        sim_debug(DEBUG_DETAIL, dptr, "Unit=%d Loaded\n", unit);
        sim_activate(uptr, 50000);
        return SCPE_OK;
    }

    if (uptr->u5 & MT_BSY) {
        uptr->u5 &= ~MT_BSY;
        sim_debug(DEBUG_DETAIL, dptr, "Unit=%d Online\n", unit);
        iostatus |= 1 << (uptr - mt_unit);
        if (uptr->u5 & MT_IDLE)
           sim_activate(uptr, 50000);
        return SCPE_OK;
    }

    if (uptr->u5 & MT_IDLE) {
        uptr->u5 &= ~MT_IDLE;
        if (uptr->u5 & MT_RDY) {
           sim_debug(DEBUG_DETAIL, dptr, "Unit=%d idling\n", unit);
           return SCPE_OK;
        }
        sim_debug(DEBUG_DETAIL, dptr, "Unit=%d start %02o\n", unit, cmd);
    }

    switch (cmd) {
    /* Handle interrogate */
    case MT_INT: 
         if (sim_tape_wrp(uptr)) 
            chan_set_wrp(chan);
         uptr->u5 &= ~(MT_CMD|MT_BIN);
         uptr->u5 |= MT_RDY;
         chan_set_end(chan);
         sim_debug(DEBUG_DETAIL, dptr, "Status\n");
         return SCPE_OK;

    case  MT_RD:                /* Read */
        /* If at end of record, fill buffer */
        if (BUF_EMPTY(uptr)) {
            sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d %s ", unit,
                (uptr->u5 & MT_BIN)? "bin": "bcd");
            if (sim_tape_eot(uptr)) {
                sim_activate(uptr, 4000);
                return mt_error(uptr, chan, MTSE_EOM, dptr);
            }
            r = sim_tape_rdrecf(uptr, &mt_buffer[chan][0], &reclen, BUFFSIZE);
            if (r != MTSE_OK) {
                if (r == MTSE_TMK) {
                    sim_debug(DEBUG_DETAIL, dptr, "TM\n");
                    ch = 017;
                    (void)chan_write_char(chan, &ch, 1);
                    sim_activate(uptr, 4000);
                } else { 
                    sim_debug(DEBUG_DETAIL, dptr, "r=%d\n", r);
                    sim_activate(uptr, 5000);
                }
                return mt_error(uptr, chan, r, dptr);
            } else {
                uptr->u5 &= ~(MT_BOT|MT_EOT);
                uptr->hwmark = reclen;
            }
            sim_debug(DEBUG_DETAIL, dptr, "%d chars\n", uptr->hwmark);
            uptr->u6 = 0;
            if ((uptr->u5 & MT_BIN) == 0)
                mode = 0100;
            else
                mode = 0;
            for (loc = 0; loc < reclen; loc++) {
                ch = mt_buffer[chan][loc] & 0177;
                if (((parity_table[ch & 077]) ^ (ch & 0100) ^ mode) == 0) {
                    chan_set_error(chan);
                    break;
                }
            }
        }
        ch = mt_buffer[chan][uptr->u6++] & 0177;
        /* 00 characters are not transfered in BCD mode */
        if (ch == 0) {
              if (((uint32)uptr->u6) >= uptr->hwmark) {
                   sim_activate(uptr, 4000);
                   return mt_error(uptr, chan, MTSE_OK, dptr);
              } else {
                   sim_activate(uptr, HT);
                   return SCPE_OK;
              }
        }

        if (chan_write_char(chan, &ch, 
                             (((uint32)uptr->u6) >= uptr->hwmark) ? 1 : 0)) {
                sim_debug(DEBUG_DATA, dptr, "Read unit=%d %d EOR\n", unit,
                         uptr->hwmark-uptr->u6);
                sim_activate(uptr, 4000);
                return mt_error(uptr, chan, MTSE_OK, dptr);
        } else {
            sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %03o\n",
                          unit, uptr->u6, ch);
            sim_activate(uptr, HT);
        }
        return SCPE_OK;

    case  MT_RDBK:              /* Read Backword */
        /* If at end of record, fill buffer */
        if (BUF_EMPTY(uptr)) {
            sim_debug(DEBUG_DETAIL, dptr, "Read back unit=%d %s ", unit,
                (uptr->u5 & MT_BIN)? "bin": "bcd");
            if (sim_tape_bot(uptr)) {
                sim_activate(uptr, 4000);
                return mt_error(uptr, chan, MTSE_BOT, dptr);
            }
            r = sim_tape_rdrecr(uptr, &mt_buffer[chan][0], &reclen, BUFFSIZE);
            if (r != MTSE_OK) {
                if (r == MTSE_TMK) {
                    sim_debug(DEBUG_DETAIL, dptr, "TM\n");
                    ch = 017;
                    (void)chan_write_char(chan, &ch, 1);
                    sim_activate(uptr, 4000);
                } else { 
                    uptr->u5 |= MT_BSY;
                    sim_debug(DEBUG_DETAIL, dptr, "r=%d\n", r);
                    sim_activate(uptr, 100);
                }
                return mt_error(uptr, chan, r, dptr);
            } else {
                uptr->u5 &= ~(MT_BOT|MT_EOT);
                uptr->hwmark = reclen;
            }
            sim_debug(DEBUG_DETAIL, dptr, "%d chars\n", uptr->hwmark);
            uptr->u6 = uptr->hwmark;
            if ((uptr->u5 & MT_BIN) == 0)
                mode = 0100;
            else
                mode = 0;
            for (loc = 0; loc < reclen; loc++) {
                ch = mt_buffer[chan][loc] & 0177;
                if (((parity_table[ch & 077]) ^ (ch & 0100) ^ mode) == 0) {
                    chan_set_error(chan);
                    break;
                }
            }
        }
        ch = mt_buffer[chan][--uptr->u6] & 0177;
        /* 00 characters are not transfered in BCD mode */
        if (ch == 0) {
              if (uptr->u6 <= 0) {
                    sim_activate(uptr, 4000);
                return mt_error(uptr, chan, MTSE_OK, dptr);
              } else {
                sim_activate(uptr, HT);
                return SCPE_OK;
              }
        }

        if (chan_write_char(chan, &ch, (uptr->u6 > 0) ? 0 : 1)) {
                sim_debug(DEBUG_DATA, dptr, "Read back unit=%d %d EOR\n",
                                 unit, uptr->hwmark-uptr->u6);
                sim_activate(uptr, 100);
                return mt_error(uptr, chan, MTSE_OK, dptr);
        } else {
            sim_debug(DEBUG_DATA, dptr, "Read  back data unit=%d %d %03o\n",
                          unit, uptr->u6, ch);
            sim_activate(uptr, HT);
        }
        return SCPE_OK;

    case MT_WR:                 /* Write */
        /* Check if write protected */
        if (uptr->u6 == 0 && sim_tape_wrp(uptr)) {
            sim_activate(uptr, 100);
            return mt_error(uptr, chan, MTSE_WRP, dptr);
        }
        if (chan_read_char(chan, &ch,
                          (uptr->u6 > BUFFSIZE) ? 1 : 0)) {
            reclen = uptr->u6;
            /* If no transfer, then either erase */
            if (reclen == 0) {
                 sim_debug(DEBUG_DETAIL, dptr, "Erase\n");
                 r = MTSE_OK;
            } else if ((reclen == 1) && (cmd & MT_BIN) == 0 &&
                 (mt_buffer[chan][0] == 017)) {
            /* Check if write rtape mark */
                 sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
                 r = sim_tape_wrtmk(uptr);
            } else {
                sim_debug(DEBUG_DETAIL, dptr, 
                        "Write unit=%d Block %d %s chars\n", unit, reclen,
                                (uptr->u5 & MT_BIN)? "bin": "bcd");
                r = sim_tape_wrrecf(uptr, &mt_buffer[chan][0], reclen);
            }
            uptr->u5 &= ~(MT_BOT|MT_EOT);
            sim_activate(uptr, 4000);
            return mt_error(uptr, chan, r, dptr);       /* Record errors */
        } else {
            /* Copy data to buffer */
            ch &= 077;
            ch |= parity_table[ch];
            if ((uptr->u5 & MT_BIN)) 
                ch ^= 0100;
            /* Don't write out even parity zeros */
            if (ch != 0) 
                mt_buffer[chan][uptr->u6++] = ch;
            sim_debug(DEBUG_DATA, dptr, "Write data unit=%d %d %03o\n",
                      unit, uptr->u6, ch);
            uptr->hwmark = uptr->u6;
        }
        sim_activate(uptr, HT);
        return SCPE_OK;

    case  MT_FSR:               /* Space forward one record */
        if (BUF_EMPTY(uptr)) {
            /* If at end of record, fill buffer */
            sim_debug(DEBUG_DETAIL, dptr, "Space unit=%d ", unit);
            if (sim_tape_eot(uptr)) {
                uptr->u5 &= ~MT_BOT;
                sim_debug(DEBUG_DETAIL, dptr, "EOT\n");
                sim_activate(uptr, 4000);
                return mt_error(uptr, chan, MTSE_EOM, dptr);
            }
            r = sim_tape_rdrecf(uptr, &mt_buffer[chan][0], &reclen, BUFFSIZE);
            if (r != MTSE_OK) {
                if (r == MTSE_TMK) {
                    sim_debug(DEBUG_DETAIL, dptr, "TM ");
                    reclen = 1;
                    chan_set_eof(chan);
                } else { 
                    sim_debug(DEBUG_DETAIL, dptr, "r=%d ", r);
                    reclen = 10;
                }
            }
            uptr->u5 &= ~(MT_BOT|MT_EOT);
            uptr->hwmark = reclen;
            sim_debug(DEBUG_DETAIL, dptr, "%d chars\n", uptr->hwmark);
            sim_activate(uptr, uptr->hwmark * HT);
            return SCPE_OK;
        }
        sim_activate(uptr, 4000);
        return mt_error(uptr, chan, MTSE_OK, dptr);

    case  MT_BSR:               /* Backspace record */
        if (BUF_EMPTY(uptr)) {
            /* If at end of record, fill buffer */
            sim_debug(DEBUG_DETAIL, dptr, "backspace unit=%d ", unit);
            if (sim_tape_bot(uptr)) {
                sim_debug(DEBUG_DETAIL, dptr, "BOT\n");
                sim_activate(uptr, 100);
                return mt_error(uptr, chan, MTSE_BOT, dptr);
            }
            r = sim_tape_rdrecr(uptr, &mt_buffer[chan][0], &reclen, BUFFSIZE);
            if (r != MTSE_OK) {
                if (r == MTSE_TMK) {
                    sim_debug(DEBUG_DETAIL, dptr, "TM ");
                    reclen = 1;
                    chan_set_eof(chan);
                } else { 
                    reclen = 10;
                    sim_debug(DEBUG_DETAIL, dptr, "r=%d ", r);
                }
            }
            uptr->u5 &= ~(MT_BOT|MT_EOT);
            uptr->hwmark = reclen;
            sim_debug(DEBUG_DETAIL, dptr, "%d chars\n", uptr->hwmark);
            sim_activate(uptr, uptr->hwmark * HT);
            return SCPE_OK;
        }
        sim_activate(uptr, 4000);
        return mt_error(uptr, chan, MTSE_OK, dptr);

    case MT_REW:                /* Rewind */
        sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d pos=%d\n", unit,
                        uptr->pos);
        uptr->u5 &= ~(MT_CMD | MT_BIN | MT_IDLE | MT_RDY);
        uptr->u5 |= MT_BSY|MT_RDY;
        iostatus &= ~(1 << (uptr - mt_unit));
        sim_activate(uptr, (uptr->pos/100) + 100);
        r = sim_tape_rewind(uptr);
        uptr->u5 &= ~MT_EOT;
        uptr->u5 |= MT_BOT;
        chan_set_end(chan);
        return r;
    }
    return mt_error(uptr, chan, r, dptr);
}
Пример #5
0
t_stat sim_tape_rdlntr (UNIT *uptr, t_mtrlnt *bc)
{
uint8 c;
t_bool all_eof;
uint32 f = MT_GET_FMT (uptr);
t_addr ppos;
t_mtrlnt sbc;
t_tpclnt tpcbc;

MT_CLR_PNU (uptr);
if ((uptr->flags & UNIT_ATT) == 0)                      /* not attached? */
    return MTSE_UNATT;
if (sim_tape_bot (uptr))                                /* at BOT? */
    return MTSE_BOT;
switch (f) {                                            /* switch on fmt */

    case MTUF_F_STD: case MTUF_F_E11:
        do {
            sim_fseek (uptr->fileref, uptr->pos - sizeof (t_mtrlnt), SEEK_SET);
            sim_fread (bc, sizeof (t_mtrlnt), 1, uptr->fileref);    /* read rec lnt */
            sbc = MTR_L (*bc);
            if (ferror (uptr->fileref))                 /* error? */
                return sim_tape_ioerr (uptr);
            if (feof (uptr->fileref))                   /* eof? */
                return MTSE_EOM;
            uptr->pos = uptr->pos - sizeof (t_mtrlnt);  /* spc over rec lnt */
            if (*bc == MTR_EOM)                         /* eom? */
                return MTSE_EOM;
            if (*bc == MTR_TMK)                         /* tape mark? */
                return MTSE_TMK;
            if ((*bc & MTR_M_RHGAP) == MTR_RHGAP) {     /* half gap? */
                uptr->pos = uptr->pos + sizeof (t_mtrlnt) / 2;  /* half space rev */
                sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* resync */
                }
            else if (*bc != MTR_GAP) {
                uptr->pos = uptr->pos - sizeof (t_mtrlnt) - /* spc over record */
                    ((f == MTUF_F_STD)? ((sbc + 1) & ~1): sbc);
                sim_fseek (uptr->fileref, uptr->pos + sizeof (t_mtrlnt), SEEK_SET);
                }
            else if (sim_tape_bot (uptr))               /* backed into BOT? */
                return MTSE_BOT;
        }
        while ((*bc == MTR_GAP) || (*bc == MTR_RHGAP));
        break;

    case MTUF_F_TPC:
        ppos = sim_tape_tpc_fnd (uptr, (t_addr *) uptr->filebuf); /* find prev rec */
        sim_fseek (uptr->fileref, ppos, SEEK_SET);      /* position */
        sim_fread (&tpcbc, sizeof (t_tpclnt), 1, uptr->fileref);
        *bc = tpcbc;                                    /* save rec lnt */
        if (ferror (uptr->fileref))                     /* error? */
            return sim_tape_ioerr (uptr);
        if (feof (uptr->fileref))                       /* eof? */
            return MTSE_EOM;
        uptr->pos = ppos;                               /* spc over record */
        if (*bc == MTR_TMK)                             /* tape mark? */
            return MTSE_TMK;
        sim_fseek (uptr->fileref, uptr->pos + sizeof (t_tpclnt), SEEK_SET);
        break;

    case MTUF_F_P7B:
        for (sbc = 1, all_eof = 1; (t_addr) sbc <= uptr->pos ; sbc++) {
            sim_fseek (uptr->fileref, uptr->pos - sbc, SEEK_SET);
            sim_fread (&c, sizeof (uint8), 1, uptr->fileref);
            if (ferror (uptr->fileref))                 /* error? */
                return sim_tape_ioerr (uptr);
            if (feof (uptr->fileref))                   /* eof? */
                return MTSE_EOM;
            if ((c & P7B_DPAR) != P7B_EOF)
                all_eof = 0;
            if (c & P7B_SOR)                            /* start of record? */
                break;
            }
        uptr->pos = uptr->pos - sbc;                    /* update position */
        *bc = sbc;                                      /* save rec lnt */
        sim_fseek (uptr->fileref, uptr->pos, SEEK_SET); /* for read */
        if (all_eof)                                    /* tape mark? */
            return MTSE_TMK;
        break;

    default:
        return MTSE_FMT;
        }

return MTSE_OK;
}