Esempio n. 1
0
t_stat mt_boot (int32 unitno, DEVICE *dptr)
{
extern int32 saved_IS;
extern int32 sim_switches;

if ((sim_switches & SWMASK ('N')) == 0)                 /* unless -n */
    sim_tape_rewind (&mt_unit[unitno]);                 /* force rewind */
BS = 1;                                                 /* set BS = 001 */
mt_io (unitno, MD_WM + MD_BOOT, BCD_R);                 /* LDA %U1 001 R */
saved_IS = 1;
return SCPE_OK;
}
Esempio n. 2
0
File: id_mt.c Progetto: ST3ALth/simh
t_stat mt_boot (int32 unitno, DEVICE *dptr)
{
extern DIB sch_dib;
uint32 sch_dev;

if (decrom[0xD5] & dec_flgs)                            /* AL defined? */
    return SCPE_NOFNC;
sim_tape_rewind (&mt_unit[unitno]);                     /* rewind */
sch_dev = sch_dib.dno + mt_dib.sch;                     /* sch dev # */
IOWriteBlk (BOOT_START, BOOT_LEN, boot_rom);            /* copy boot */
IOWriteB (AL_DEV, mt_dib.dno + (unitno * o_MT0));       /* set dev no for unit */
IOWriteB (AL_IOC, 0xA1);                                /* set dev cmd */
IOWriteB (AL_SCH, sch_dev);                             /* set dev no for chan */
PC = BOOT_START;
return SCPE_OK;
}
Esempio n. 3
0
t_stat sim_tape_attach (UNIT *uptr, char *cptr)
{
uint32 objc;
char gbuf[CBUFSIZE];
t_stat r;

if (sim_switches & SWMASK ('F')) {                      /* format spec? */
    cptr = get_glyph (cptr, gbuf, 0);                   /* get spec */
    if (*cptr == 0)                                     /* must be more */
        return SCPE_2FARG;
    if (sim_tape_set_fmt (uptr, 0, gbuf, NULL) != SCPE_OK)
        return SCPE_ARG;
    }
r =
    (uptr, cptr);                           /* attach unit */
if (r != SCPE_OK)                                       /* error? */
    return r;
switch (MT_GET_FMT (uptr)) {                            /* case on format */

    case MTUF_F_TPC:                                    /* TPC */
        objc = sim_tape_tpc_map (uptr, NULL);           /* get # objects */
        if (objc == 0) {                                /* tape empty? */
            sim_tape_detach (uptr);
            return SCPE_FMT;                            /* yes, complain */
            }
        uptr->filebuf = calloc (objc + 1, sizeof (t_addr));
        if (uptr->filebuf == NULL) {                    /* map allocated? */
            sim_tape_detach (uptr);
            return SCPE_MEM;                            /* no, complain */
            }
        uptr->hwmark = objc + 1;                        /* save map size */
        sim_tape_tpc_map (uptr, (t_addr *) uptr->filebuf);      /* fill map */
        break;

    default:
        break;
        }

sim_tape_rewind (uptr);
return SCPE_OK;
}
Esempio n. 4
0
t_stat sim_tape_detach (UNIT *uptr)
{
uint32 f = MT_GET_FMT (uptr);
t_stat r;

r = detach_unit (uptr);                                 /* detach unit */
if (r != SCPE_OK)
    return r;
switch (f) {                                            /* case on format */

    case MTUF_F_TPC:                                    /* TPC */
        if (uptr->filebuf)                              /* free map */
            free (uptr->filebuf);
        uptr->filebuf = NULL;
        uptr->hwmark = 0;
        break;

    default:
        break;
        }

sim_tape_rewind (uptr);
return SCPE_OK;
}
Esempio n. 5
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;
}
Esempio n. 6
0
t_stat mtu_svc (UNIT *uptr)
{
uint32 cmd = uptr->UCMD;
uint32 un = uptr - mt_unit;
uint32 c;
uint32 st;
int32 t;
t_mtrlnt tbc;
t_stat r;

if (cmd == MCM_INIT) {                                  /* init state */
    if ((t = sim_activate_time (uptr + MT_REW)) != 0) { /* rewinding? */
        sim_activate (uptr, t);                         /* retry later */
        return SCPE_OK;
        }
    st = chan_get_cmd (mt_dib.dva, &cmd);               /* get command */
    if (CHS_IFERR (st))                                 /* channel error? */
        return mt_chan_err (st);
    if ((cmd & 0x80) ||                                 /* invalid cmd? */
        (mt_op[cmd] == 0)) {
        uptr->UCMD = MCM_END;                           /* end state */
        sim_activate (uptr, chan_ctl_time);             /* resched ctlr */
        return SCPE_OK;
        }
    else {                                              /* valid cmd */
        if ((mt_op[cmd] & O_REV) &&                     /* reverse op */
            (mt_unit[un].UST & MTDV_BOT)) {             /* at load point? */
            chan_uen (mt_dib.dva);                      /* channel end */
            return SCPE_OK;
            }
        uptr->UCMD = cmd;                               /* unit state */
        if (!(mt_op[cmd] & O_NMT))                      /* motion? */
            uptr->UST = 0;                              /* clear status */
        }
    mt_blim = 0;                                        /* no buffer yet */
    sim_activate (uptr, chan_ctl_time);                 /* continue thread */
    return SCPE_OK;                                     /* done */
    }

if (cmd == MCM_END) {                                   /* end state */
    st = chan_end (mt_dib.dva);                         /* set channel end */
    if (CHS_IFERR (st))                                 /* channel error? */
        return mt_chan_err (st);
    if (st == CHS_CCH) {                                /* command chain? */
        uptr->UCMD = MCM_INIT;                          /* restart thread */
        sim_activate (uptr, chan_ctl_time);
        }
    else uptr->UCMD = 0;                                /* ctlr idle */
    return SCPE_OK;                                     /* done */
    }

if ((mt_op[cmd] & O_ATT) &&                             /* op req att and */
    ((uptr->flags & UNIT_ATT) == 0)) {                  /* not attached? */
    sim_activate (uptr, mt_ctime);                      /* retry */
    return mt_stopioe? SCPE_UNATT: SCPE_OK;
    }
if ((mt_op[cmd] & O_WRE) &&                             /* write op and */
    sim_tape_wrp (uptr)) {                              /* write protected? */
    uptr->UST |= MTDV_WLE;                              /* set status */
    chan_uen (mt_dib.dva);                              /* unusual end */
    return SCPE_OK;
    }

r = SCPE_OK;
switch (cmd) {                                          /* case on command */

    case MCM_SFWR:                                      /* space forward */
        if (r = sim_tape_sprecf (uptr, &tbc))           /* spc rec fwd, err? */
            r = mt_map_err (uptr, r);                   /* map error */
        break;

    case MCM_SBKR:                                      /* space reverse */
        if (r = sim_tape_sprecr (uptr, &tbc))           /* spc rec rev, err? */
            r = mt_map_err (uptr, r);                   /* map error */
        break;

    case MCM_SFWF:                                      /* space fwd file */
        while ((r = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ;
        if (r != MTSE_TMK)                              /* stopped by tmk? */
            r = mt_map_err (uptr, r);                   /* no, map error */
        else r = SCPE_OK;
        break;

    case MCM_SBKF:                                       /* space rev file */
        while ((r = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ;
        if (r != MTSE_TMK)                              /* stopped by tmk? */
            r = mt_map_err (uptr, r);                   /* no, map error */
        else r = SCPE_OK;
        break;

    case MCM_WTM:                                       /* write eof */
        if (r = sim_tape_wrtmk (uptr))                  /* write tmk, err? */
            r = mt_map_err (uptr, r);                   /* map error */
        uptr->UST |= MTDV_EOF;                          /* set eof */
        break;

    case MCM_RWU:                                       /* rewind unload */
        r = detach_unit (uptr);
        break;

    case MCM_REW:                                       /* rewind */
    case MCM_RWI:                                       /* rewind and int */
        if (r = sim_tape_rewind (uptr))                 /* rewind */
            r = mt_map_err (uptr, r);                   /* map error */
        mt_unit[un + MT_REW].UCMD = uptr->UCMD;         /* copy command */
        sim_activate (uptr + MT_REW, mt_rwtime);        /* sched compl */
        break;

    case MCM_READ:                                      /* read */
        if (mt_blim == 0) {                             /* first read? */
            r = sim_tape_rdrecf (uptr, mt_xb, &mt_blim, MT_MAXFR);
            if (r != MTSE_OK) {                         /* tape error? */
                r = mt_map_err (uptr, r);               /* map error */
                break;
                }
            mt_bptr = 0;                                /* init rec ptr */
            }
        c = mt_xb[mt_bptr++];                           /* get char */
        st = chan_WrMemB (mt_dib.dva, c);               /* write to memory */
        if (CHS_IFERR (st))                             /* channel error? */
            return mt_chan_err (st);
        if ((st != CHS_ZBC) && (mt_bptr != mt_blim)) {  /* not done? */
            sim_activate (uptr, mt_time);               /* continue thread */
            return SCPE_OK;
            }
        if (((st == CHS_ZBC) ^ (mt_bptr == mt_blim)) && /* length err? */ 
              chan_set_chf (mt_dib.dva, CHF_LNTE))      /* uend taken? */
            return SCPE_OK;                             /* finished */
        break;                                          /* normal end */

    case MCM_RDBK:                                      /* read reverse */
        if (mt_blim == 0) {                             /* first read? */
            r = sim_tape_rdrecr (uptr, mt_xb, &mt_blim, MT_MAXFR);
            if (r != MTSE_OK) {                         /* tape error? */
                r = mt_map_err (uptr, r);               /* map error */
                break;
                }
            mt_bptr = mt_blim;                          /* init rec ptr */
            }
        c = mt_xb[--mt_bptr];                           /* get char */
        st = chan_WrMemBR (mt_dib.dva, c);              /* write mem rev */
        if (CHS_IFERR (st))                             /* channel error? */
            return mt_chan_err (st);
        if ((st != CHS_ZBC) && (mt_bptr != 0)) {        /* not done? */
            sim_activate (uptr, mt_time);               /* continue thread */
            return SCPE_OK;
            }
        if (((st == CHS_ZBC) ^ (mt_bptr == 0)) &&       /* length err? */
              chan_set_chf (mt_dib.dva, CHF_LNTE))      /* uend taken? */
            return SCPE_OK;                             /* finished */
        break;                                          /* normal end */

    case MCM_WRITE:                                     /* write */
        st = chan_RdMemB (mt_dib.dva, &c);              /* read char */
        if (CHS_IFERR (st)) {                           /* channel error? */
            mt_flush_buf (uptr);                        /* flush buffer */
            return mt_chan_err (st);
            }
        mt_xb[mt_blim++] = c;                           /* store in buffer */
        if (st != CHS_ZBC) {                            /* end record? */
             sim_activate (uptr, mt_time);              /* continue thread */
             return SCPE_OK;
             }
        r = mt_flush_buf (uptr);                        /* flush buffer */
        break;
        }

if (r != SCPE_OK)                                       /* error? abort */
    return CHS_IFERR(r)? SCPE_OK: r;
uptr->UCMD = MCM_END;                                   /* end state */
sim_activate (uptr, mt_ctime);                          /* sched ctlr */
return SCPE_OK;
}
Esempio n. 7
0
t_stat mtc_svc (UNIT *uptr)
{
t_mtrlnt tbc;
t_stat st, r = SCPE_OK;

if ((mtc_unit.flags & UNIT_ATT) == 0) {                 /* offline? */
    mtc_sta = STA_LOCAL | STA_REJ;                      /* rejected */
    mtcio (mtc_dib.devno, ioENF, 0);                    /* set cch flg */
    return IORETURN (mtc_stopioe, SCPE_UNATT);
    }

switch (mtc_fnc) {                                      /* case on function */

    case FNC_REW:                                       /* rewind */
        sim_tape_rewind (uptr);                         /* BOT */
        mtc_sta = STA_BOT;                              /* update status */
        break;

    case FNC_RWS:                                       /* rewind and offline */
        sim_tape_rewind (uptr);                         /* clear position */
        return sim_tape_detach (uptr);                  /* don't set cch flg */

    case FNC_WFM:                                       /* write file mark */
        if (st = sim_tape_wrtmk (uptr))                 /* write tmk, err? */
            r = mt_map_err (uptr, st);                  /* map error */
        mtc_sta = STA_EOF;                              /* set EOF status */
        break;

    case FNC_GAP:                                       /* erase gap */
        break;

    case FNC_FSR:                                       /* space forward */
        if (st = sim_tape_sprecf (uptr, &tbc))          /* space rec fwd, err? */
            r = mt_map_err (uptr, st);                  /* map error */
        break;

    case FNC_BSR:                                       /* space reverse */
        if (st = sim_tape_sprecr (uptr, &tbc))          /* space rec rev, err? */
            r = mt_map_err (uptr, st);                  /* map error */
        break;

    case FNC_RC:                                        /* read */
        if (mtc_1st) {                                  /* first svc? */
            mtc_1st = mt_ptr = 0;                       /* clr 1st flop */
            st = sim_tape_rdrecf (uptr, mtxb, &mt_max, DBSIZE); /* read rec */
            if (st == MTSE_RECE) mtc_sta = mtc_sta | STA_PAR;   /* rec in err? */
            else if (st != MTSE_OK) {                   /* other error? */
                r = mt_map_err (uptr, st);              /* map error */
                if (r == SCPE_OK) {                     /* recoverable? */
                    sim_activate (uptr, mtc_gtime);     /* sched IRG */
                    mtc_fnc = 0;                        /* NOP func */
                    return SCPE_OK;
                    }
                break;                                  /* non-recov, done */
                }
            if (mt_max < 12) {                          /* record too short? */
                mtc_sta = mtc_sta | STA_PAR;            /* set flag */
                break;
                }
            }
        if (mtc_dtf && (mt_ptr < mt_max)) {             /* more chars? */
            if (mtd_flag) mtc_sta = mtc_sta | STA_TIM;
            mtc_unit.buf = mtxb[mt_ptr++];              /* fetch next */
            mtdio (mtd_dib.devno, ioENF, 0);            /* set dch flg */
            sim_activate (uptr, mtc_xtime);             /* re-activate */
            return SCPE_OK;
            }
        sim_activate (uptr, mtc_gtime);                 /* schedule gap */
        mtc_fnc = 0;                                    /* nop */
        return SCPE_OK;

    case FNC_WC:                                                /* write */
        if (mtc_1st) mtc_1st = 0;                       /* no xfr on first */
        else {
            if (mt_ptr < DBSIZE) {                      /* room in buffer? */
                mtxb[mt_ptr++] = mtc_unit.buf;
                mtc_sta = mtc_sta & ~STA_BOT;           /* clear BOT */
                }
            else mtc_sta = mtc_sta | STA_PAR;
            }
        if (mtc_dtf) {                                  /* xfer flop set? */
            mtdio (mtd_dib.devno, ioENF, 0);            /* set dch flg */
            sim_activate (uptr, mtc_xtime);             /* re-activate */
            return SCPE_OK;
            }
        if (mt_ptr) {                                   /* write buffer */
            if (st = sim_tape_wrrecf (uptr, mtxb, mt_ptr)) {    /* write, err? */
                r = mt_map_err (uptr, st);              /* map error */
                break;                                  /* done */
                }
            }
        sim_activate (uptr, mtc_gtime);                 /* schedule gap */
        mtc_fnc = 0;                                    /* nop */
        return SCPE_OK;

    default:                                            /* unknown */
        break;
        }

mtcio (mtc_dib.devno, ioENF, 0);                        /* set cch flg */
mtc_sta = mtc_sta & ~STA_BUSY;                          /* not busy */
return r;
}
Esempio n. 8
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);
}
Esempio n. 9
0
t_stat mt (uint32 fnc, uint32 inst, uint32 *dat)
{
int32 u = inst & MT_UNIT;                               /* get unit */
UNIT *uptr = mt_dev.units + u;                          /* get unit ptr */
int32 t, new_ch;
uint8 chr;
t_stat r;

switch (fnc) {                                          /* case function */

    case IO_CONN:                                       /* connect */
        new_ch = I_GETEOCH (inst);                      /* get new chan */
        if (new_ch != mt_dib.chan)                      /* wrong chan? */
            return SCPE_IERR;
        if (mt_gap) {                                   /* in gap? */
            mt_gap = 0;                                 /* clr gap flg */
            sim_cancel (uptr);                          /* cancel timer */
            }
        else if (sim_is_active (uptr))                  /* busy? */
            CRETIOP;
        uptr->eotf = 0;                                 /* clr eot flag */      
        mt_eof = 0;                                     /* clr eof flag */
        mt_skip = 0;                                    /* clr skp flag */
        mt_bptr = mt_blnt = 0;                          /* init buffer */
        if ((inst & DEV_MTS)? (CHC_GETCPW (inst) < 2):  /* scn & cpw<3? */
            (inst & CHC_REV))                           /* rw & rev? */
            return STOP_INVIOP;
        mt_inst = inst;                                 /* save inst */
        if ((inst & DEV_MTS) && !(inst & DEV_OUT))      /* scanning? */
            chan_set_flag (mt_dib.chan, CHF_SCAN);      /* set chan flg */
        xfr_req = xfr_req & ~XFR_MT0;                   /* clr xfr flag */
        sim_activate (uptr, mt_gtime);                  /* start timer */
        break;

    case IO_EOM1:                                       /* EOM mode 1 */
        new_ch = I_GETEOCH (inst);                      /* get new chan */
        if (new_ch != mt_dib.chan)                      /* wrong chan? */
            CRETIOP;
        t = inst & 07670;                               /* get command */
        if ((t == 04010) && !sim_is_active (uptr)) {    /* rewind? */
            sim_tape_rewind (uptr);                     /* rewind unit */
            uptr->eotf = 0;                             /* clr eot */
            uptr->botf = 1;                             /* set bot */
            }
        else if ((t == 03610) && sim_is_active (uptr) &&/* skip rec? */
            ((mt_inst & DEV_OUT) == 0))
            mt_skip = 1;                                /* set flag */
        else CRETINS;
        break;

    case IO_DISC:                                       /* disconnect */
        sim_cancel (uptr);                              /* no more xfr's */
        if (inst & DEV_OUT) {                           /* write? */
            if (r = mt_wrend (inst))                    /* end record */
                return r;
            }
        break;

    case IO_WREOR:                                      /* write eor */
        chan_set_flag (mt_dib.chan, CHF_EOR);           /* set eor flg */
        if (r = mt_wrend (inst))                        /* end record */
            return r;
        mt_gap = 1;                                     /* in gap */
        sim_activate (uptr, mt_gtime);                  /* start timer */        
        break;

    case IO_SKS:                                        /* SKS */
        new_ch = I_GETSKCH (inst);                      /* get chan # */
        if (new_ch != mt_dib.chan)                      /* wrong chan? */
            return SCPE_IERR;
        if ((inst & (DEV_OUT | DEV_MTS)) == 0) {        /* not sks 1n? */
            t = I_GETSKCND (inst);                      /* get skip cond */
            switch (t) {                                /* case sks cond */
            case 001:                                   /* sks 1021n */
                *dat = 1;                               /* not magpak */
                break;
            case 002:                                   /* sks 1041n */
                if (!(uptr->flags & UNIT_ATT) ||        /* not ready */
                    sim_is_active (uptr)) *dat = 1;
                break;
            case 004:                                   /* sks 1101n */
                if (!uptr->eotf) *dat = 1;              /* not EOT */
                break;
            case 010:                                   /* sks 1201n */
                if (!uptr->botf) *dat = 1;              /* not BOT */
                break;
            case 013:                                   /* sks 12610 */
                if (!mt_gap) *dat = 1;                  /* not in gap */
                break;
            case 017:                                   /* sks 13610 */
                if (!mt_eof) *dat = 1;                  /* not EOF */
                break;
            case 020:                                   /* sks 1401n */
                if (!sim_tape_wrp (uptr)) *dat = 1;     /* not wrp */
                break;
            case 031:                                   /* sks 1621n */
            case 033:                                   /* sks 1661n */
                *dat = 1;                               /* not 556bpi */
            case 035:                                   /* sks 1721n */
                break;                                  /* not 800bpi */
                }
            }                                           /* end if */
        break;

    case IO_READ:                                       /* read */
        xfr_req = xfr_req & ~XFR_MT0;                   /* clr xfr flag */
        if (mt_blnt == 0) {                             /* first read? */
            r = mt_readrec (uptr);                      /* get data */
            if ((r != SCPE_OK) || (mt_blnt == 0))       /* err, inv reclnt? */
                return r;
            }
        uptr->botf = 0;                                 /* off BOT */
        if (mt_inst & CHC_REV)                          /* get next rev */
            chr = mtxb[--mt_bptr] & 077;
        else chr = mtxb[mt_bptr++] & 077;               /* get next fwd */
        if (!(mt_inst & CHC_BIN))                       /* bcd? */
            chr = bcd_to_sds[chr];
        *dat = chr & 077;                               /* give to chan */
        if ((mt_inst & CHC_REV)? (mt_bptr <= 0):        /* rev or fwd, */
            (mt_bptr >= mt_blnt))                       /* recd done? */
            mt_readend (uptr);
        break;

    case IO_WRITE:                                      /* write */
        uptr->botf = 0;                                 /* off BOT */
        chr = (*dat) & 077;
        xfr_req = xfr_req & ~XFR_MT0;                   /* clr xfr flag */
        if (!(mt_inst & CHC_BIN))                       /* bcd? */
            chr = sds_to_bcd[chr];
        if (mt_bptr < MT_MAXFR) mtxb[mt_bptr++] = chr;  /* insert in buf */
        break;

    default:
        CRETINS;
        }

return SCPE_OK;
} 
Esempio n. 10
0
File: id_mt.c Progetto: ST3ALth/simh
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;
}
Esempio n. 11
0
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);
}