Esempio n. 1
0
t_stat rs_svc (UNIT *uptr)
{
int32 i, fnc, dtype, drv;
int32 wc, abc, awc, mbc, da;
uint16 *fbuf = (uint16 *)uptr->filebuf;

dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
drv = (int32) (uptr - rs_dev.units);                    /* get drv number */
da = rsda[drv] * RS_NUMWD (dtype);                      /* get disk addr */
fnc = GET_FNC (rscs1[drv]);                             /* get function */

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not attached? */
    rs_set_er (ER_UNS, drv);                            /* set drive error */
    if (fnc >= FNC_XFR)                                 /* xfr? set done */
        mba_set_don (rs_dib.ba);
    rs_update_ds (DS_ATA, drv);                         /* set attn */
    return (rs_stopioe? SCPE_UNATT: SCPE_OK);
    }
rsds[drv] = (rsds[drv] & ~DS_PIP) | DS_RDY;             /* change drive status */

switch (fnc) {                                          /* case on function */
 
    case FNC_SEARCH:                                    /* search */
        rs_update_ds (DS_ATA, drv);
        break;

    case FNC_WRITE:                                     /* write */
        if ((uptr->flags & UNIT_WLK) &&                 /* write locked? */
            (GET_TK (rsda[drv]) <= (int32) rswlk[drv])) {
            rs_set_er (ER_WLE, drv);                    /* set drive error */
            mba_set_exc (rs_dib.ba);                    /* set exception */
            rs_update_ds (DS_ATA, drv);                 /* set attn */
            return SCPE_OK;
            }
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
        if (rsda[drv] & DA_INV) {                       /* bad addr? */
            rs_set_er (ER_IAE, drv);                   /* set error */
            mba_set_exc (rs_dib.ba);                    /* set exception */
            rs_update_ds (DS_ATA, drv);                 /* set attn */
            break;
            }
        fbuf = fbuf + da;                               /* ptr into buffer */
        mbc = mba_get_bc (rs_dib.ba);                   /* get byte count */
        wc = (mbc + 1) >> 1;                            /* convert to words */
        if ((da + wc) > RS_SIZE (dtype)) {              /* disk overrun? */
            rs_set_er (ER_AOE, drv);                    /* set err */
            wc = RS_SIZE (dtype) - da;                  /* trim xfer */
            mbc = wc << 1;                              /* trim mb count */
            }
        if (fnc == FNC_WRITE) {                         /* write? */
            abc = mba_rdbufW (rs_dib.ba, mbc, fbuf);    /* rd mem to buf */
            wc = (abc + 1) >> 1;                        /* actual # wds */
            awc = (wc + (RS_NUMWD (dtype) - 1)) & ~(RS_NUMWD (dtype) - 1);
            for (i = wc; i < awc; i++)                  /* fill buf */
                fbuf[i] = 0;
            if ((da + awc) > (int32) uptr->hwmark)      /* update hw mark*/
                uptr->hwmark = da + awc;
            }                                           /* end if wr */
        else if (fnc == FNC_READ)                       /* read  */
Esempio n. 2
0
t_stat rs_go (int32 drv)
{
int32 fnc, dtype, t;
UNIT *uptr;

fnc = GET_FNC (rscs1[drv]);                             /* get function */
if (DEBUG_PRS (rs_dev))
    fprintf (sim_deb, ">>RS%d STRT: fnc=%s, ds=%o, da=%o, er=%o\n",
             drv, rs_fname[fnc], rsds[drv], rsda[drv], rser[drv]);
uptr = rs_dev.units + drv;                              /* get unit */
rs_clr_as (AS_U0 << drv);                               /* clear attention */
dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
if ((fnc != FNC_DCLR) && (rsds[drv] & DS_ERR)) {        /* err & ~clear? */
    rs_set_er (ER_ILF, drv);                            /* not allowed */
    rs_update_ds (DS_ATA, drv);                         /* set attention */
    return MBE_GOE;
    }

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

    case FNC_DCLR:                                      /* drive clear */
        rser[drv] = 0;                                  /* clear errors */
    case FNC_NOP:                                       /* no operation */
        return SCPE_OK;

    case FNC_SEARCH:                                    /* search */
    case FNC_WRITE:                                     /* write */
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
        if ((uptr->flags & UNIT_ATT) == 0) {            /* not attached? */
            rs_set_er (ER_UNS, drv);                    /* unsafe */
            break;
            }
        if (rsda[drv] & DA_INV) {                       /* bad address? */
            rs_set_er (ER_IAE, drv);
            break;
            }
        rsds[drv] = rsds[drv] & ~DS_RDY;                /* clr drive rdy */
        if (fnc == FNC_SEARCH)                          /* search? */
            rsds[drv] = rsds[drv] | DS_PIP;             /* set PIP */
        t = abs (rsda[drv] - GET_POS (rs_wait));        /* pos diff */
        if (t < 1)                                      /* min time */
            t = 1;
        sim_activate (uptr, rs_wait * t);               /* schedule */
        return SCPE_OK;

    default:                                            /* all others */
        rs_set_er (ER_ILF, drv);                        /* not supported */
        break;
        }

rs_update_ds (DS_ATA, drv);                             /* set attn, req int */
return MBE_GOE;
}
Esempio n. 3
0
t_stat rp_svc (UNIT *uptr)
{
int32 i, fnc, dtype, drv, err;
int32 wc, abc, awc, mbc, da;

dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
drv = (int32) (uptr - rp_dev.units);                    /* get drv number */
da = GET_DA (rpdc[drv], rpda[drv], dtype) * RP_NUMWD;   /* get disk addr */
fnc = GET_FNC (rpcs1[drv]);                             /* get function */

if ((uptr->flags & UNIT_ATT) == 0) {                    /* not attached? */
    rp_set_er (ER1_UNS, drv);                           /* set drive error */
    if (fnc >= FNC_XFER)                                /* xfr? set done */
        mba_set_don (rp_dib.ba);
    rp_update_ds (DS_ATA, drv);                         /* set attn */
    return (rp_stopioe? SCPE_UNATT: SCPE_OK);
    }
rpds[drv] = (rpds[drv] & ~DS_PIP) | DS_RDY;             /* change drive status */

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

    case FNC_OFFSET:                                    /* offset */
        rp_update_ds (DS_OFM | DS_ATA, drv);
        break;

    case FNC_RETURN:                                    /* return to centerline */
        rpds[drv] = rpds[drv] & ~DS_OFM;                /* clear offset, set attn */
        rp_update_ds (DS_ATA, drv);
        break;  

    case FNC_UNLOAD:                                    /* unload */
        rp_detach (uptr);                               /* detach unit */
        break;

    case FNC_RECAL:                                     /* recalibrate */
    case FNC_SEARCH:                                    /* search */
    case FNC_SEEK:                                      /* seek */
        rp_update_ds (DS_ATA, drv);
        break;

    case FNC_WRITE:                                     /* write */
        if (uptr->flags & UNIT_WPRT) {                  /* write locked? */
            rp_set_er (ER1_WLE, drv);                   /* set drive error */
            mba_set_exc (rp_dib.ba);                    /* set exception */
            rp_update_ds (DS_ATA, drv);                 /* set attn */
            return SCPE_OK;
            }
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
    case FNC_READH:                                     /* read headers */
        err = fseek (uptr->fileref, da * sizeof (int16), SEEK_SET);
        mbc = mba_get_bc (rp_dib.ba);                   /* get byte count */
        wc = (mbc + 1) >> 1;                            /* convert to words */
        if ((da + wc) > drv_tab[dtype].size) {          /* disk overrun? */
            rp_set_er (ER1_AOE, drv);                   /* set err */
            wc = drv_tab[dtype].size - da;              /* trim xfer */
            mbc = wc << 1;                              /* trim mb count */
            if (da >= drv_tab[dtype].size) {            /* none left? */
                mba_set_exc (rp_dib.ba);                /* set exception */
                rp_update_ds (DS_ATA, drv);             /* set attn */
                break;
                }
            }
        if (fnc == FNC_WRITE) {                         /* write? */
            abc = mba_rdbufW (rp_dib.ba, mbc, rpxb);    /* get buffer */
            wc = (abc + 1) >> 1;                        /* actual # wds */
            awc = (wc + (RP_NUMWD - 1)) & ~(RP_NUMWD - 1);
            for (i = wc; i < awc; i++)                  /* fill buf */
                rpxb[i] = 0;
            if (wc && !err) {                           /* write buf */
                fxwrite (rpxb, sizeof (uint16), awc, uptr->fileref);
                err = ferror (uptr->fileref);
                }
            }                                           /* end if wr */
        else {                                          /* read or wchk */
Esempio n. 4
0
t_stat rp_go (int32 drv)
{
int32 dc, fnc, dtype, t;
UNIT *uptr;

fnc = GET_FNC (rpcs1[drv]);                             /* get function */
if (DEBUG_PRS (rp_dev))
    fprintf (sim_deb, ">>RP%d STRT: fnc=%s, ds=%o, cyl=%o, da=%o, er=%o\n",
             drv, rp_fname[fnc], rpds[drv], rpdc[drv], rpda[drv], rper1[drv]);
uptr = rp_dev.units + drv;                              /* get unit */
rp_clr_as (AS_U0 << drv);                               /* clear attention */
dtype = GET_DTYPE (uptr->flags);                        /* get drive type */
dc = rpdc[drv];                                         /* assume seek, sch */
if ((fnc != FNC_DCLR) && (rpds[drv] & DS_ERR)) {        /* err & ~clear? */
    rp_set_er (ER1_ILF, drv);                           /* not allowed */
    rp_update_ds (DS_ATA, drv);                         /* set attention */
    return MBE_GOE;
    }

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

    case FNC_DCLR:                                      /* drive clear */
        rper1[drv] = rper2[drv] = rper3[drv] = 0;       /* clear errors */
        rpec2[drv] = 0;                                 /* clear EC2 */
        if (drv_tab[dtype].ctrl == RM_CTRL)             /* RM? */
            rpmr[drv] = 0;                              /* clear maint */
        else rpec1[drv] = 0;                            /* RP, clear EC1 */
    case FNC_NOP:                                       /* no operation */
    case FNC_RELEASE:                                   /* port release */
        return SCPE_OK;

    case FNC_PRESET:                                    /* read-in preset */
        rpdc[drv] = 0;                                  /* clear disk addr */
        rpda[drv] = 0;
        rpof[drv] = 0;                                  /* clear offset */
    case FNC_PACK:                                      /* pack acknowledge */
        rpds[drv] = rpds[drv] | DS_VV;                  /* set volume valid */
        return SCPE_OK;

    case FNC_OFFSET:                                    /* offset mode */
    case FNC_RETURN:
        if ((uptr->flags & UNIT_ATT) == 0) {            /* not attached? */
            rp_set_er (ER1_UNS, drv);                   /* unsafe */
            break;
            }
        rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP;     /* set positioning */
        sim_activate (uptr, rp_swait);                  /* time operation */
        return SCPE_OK;

    case FNC_UNLOAD:                                    /* unload */
        if (drv_tab[dtype].ctrl == RM_CTRL) {           /* RM? */
            rp_set_er (ER1_ILF, drv);                   /* not supported */
            break;
            }
        rp_detach (uptr);                               /* detach unit */
        return SCPE_OK;

    case FNC_RECAL:                                     /* recalibrate */
        dc = 0;                                         /* seek to 0 */
    case FNC_SEEK:                                      /* seek */
    case FNC_SEARCH:                                    /* search */
        if ((uptr->flags & UNIT_ATT) == 0) {            /* not attached? */
            rp_set_er (ER1_UNS, drv);                   /* unsafe */
            break;
            }
        if ((GET_CY (dc) >= drv_tab[dtype].cyl) ||      /* bad cylinder */
            (GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
            (GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
            rp_set_er (ER1_IAE, drv);
            break;
            }
        rpds[drv] = (rpds[drv] & ~DS_RDY) | DS_PIP;     /* set positioning */
        t = abs (dc - uptr->CYL);                       /* cyl diff */
        if (t == 0)                                     /* min time */
            t = 1;
        sim_activate (uptr, rp_swait * t);              /* schedule */
        uptr->CYL = dc;                                 /* save cylinder */
        return SCPE_OK;

    case FNC_WRITEH:                                    /* write headers */
    case FNC_WRITE:                                     /* write */
    case FNC_WCHK:                                      /* write check */
    case FNC_READ:                                      /* read */
    case FNC_READH:                                     /* read headers */
        if ((uptr->flags & UNIT_ATT) == 0) {            /* not attached? */
            rp_set_er (ER1_UNS, drv);                   /* unsafe */
            break;
            }
        if ((GET_CY (dc) >= drv_tab[dtype].cyl) ||      /* bad cylinder */
            (GET_SF (rpda[drv]) >= drv_tab[dtype].surf) || /* bad surface */
            (GET_SC (rpda[drv]) >= drv_tab[dtype].sect)) { /* or bad sector? */
            rp_set_er (ER1_IAE, drv);
            break;
            }
        rpds[drv] = rpds[drv] & ~DS_RDY;                /* clear drive rdy */
        sim_activate (uptr, rp_rwait + (rp_swait * abs (dc - uptr->CYL)));
        uptr->CYL = dc;                                 /* save cylinder */
        return SCPE_OK;

    default:                                            /* all others */
        rp_set_er (ER1_ILF, drv);                       /* not supported */
        break;
        }

rp_update_ds (DS_ATA, drv);                             /* set attn, req int */
return MBE_GOE;
}
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;
}