Beispiel #1
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;
}
Beispiel #2
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;
}
Beispiel #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;
}
Beispiel #4
0
uint32 dpc (uint32 dev, uint32 op, uint32 dat)
{
uint32 f, t, u;
UNIT *uptr;
static uint8 good_cmd[8] = { 0, 1, 1, 1, 0, 0, 0, 0 };

switch (op) {                                           /* case IO op */

    case IO_ADR:                                        /* select */
        sch_adr (dp_dib.sch, dev);                      /* inform sel ch */
        return BY;                                      /* byte only */

    case IO_RD:                                         /* read data */
        if (dp_sta & STC_IDL)                           /* if idle */
            return GET_ROTATE (dp_rtime);               /* return sector */
        else dp_sta = dp_sta | STA_BSY;                 /* xfr? set busy */
        return dp_db;                                   /* return data */

    case IO_WD:                                         /* write data */
        if (DEBUG_PRS (dp_dev)) fprintf (sim_deb,
            ">>DPC WD = %02X, STA = %02X\n", dat, dp_sta);
        if (dp_sta & STC_IDL)                           /* idle? hdsc */
            dp_hdsc = dat & HS_MASK;
        else {                                          /* data xfer */
            dp_sta = dp_sta | STA_BSY;                  /* set busy */
            dp_db = dat & 0xFF;                         /* store data */
            }
        break;

    case IO_SS:                                         /* status */
        t = dp_sta & STC_MASK;                          /* get status */
        if (t & SETC_EX)                                /* test for EX */
            t = t | STA_EX;
        return t;

    case IO_OC:                                         /* command */
        if (DEBUG_PRS (dp_dev)) fprintf (sim_deb,
            ">>DPC OC = %02X, STA = %02X\n", dat, dp_sta);
        f = dat & CMC_MASK;                             /* get cmd */
        if (f & CMC_CLR) {                              /* clear? */
            dp_reset (&dp_dev);                         /* reset world */
            break;
            }
        u = (dp_svun - dp_dib.dno - o_DP0) / o_DP0;     /* get unit */
        uptr = dp_dev.units + u;                        /* ignore if busy */
        if (!(dp_sta & STC_IDL) || sim_is_active (uptr))
            break;
        dp_cmd = f;                                     /* save cmd */
        if (dp_cmd == CMC_WR)                           /* write: bsy=0 else */
            dp_sta = 0;
        else dp_sta = STA_BSY;                          /* bsy=1,idl,err=0 */
        dp_1st = 1;                                     /* xfr not started */
        dp_bptr = 0;                                    /* buffer empty */
        if (dp_svun & o_DPF)                            /* upper platter? */
            dp_plat = 1;
        else dp_plat = 0;                               /* no, lower */
        if (good_cmd[f])                                /* legal? sched */
            sim_activate (uptr, dp_rtime);
        break;
        }

return 0;
}
Beispiel #5
0
t_stat mt_io (int32 unit, int32 flag, int32 mod)
{
int32 t, wm_seen;
t_mtrlnt i, tbc;
t_stat st;
t_bool passed_eot;
UNIT *uptr;

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 BCD_R:                                         /* read */
        if (DEBUG_PRS (mt_dev))
            fprintf (sim_deb, ">>MT%d: read from %d", unit, BS);
        wm_seen = 0;                                    /* no word mk seen */
        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 */
            }
        for (i = 0; i < tbc; i++) {                     /* loop thru buf */
            if (!(flag & MD_BOOT) &&                    /* not boot? check */
                (M[BS] == (BCD_GRPMRK + WM))) {         /* GWM in memory? */
                if (DEBUG_PRS (mt_dev))
                    fprintf (sim_deb, " to %d, stopped by GMWM\n", BS);
                BS++;                                   /* incr BS */
                if (ADDR_ERR (BS)) {                    /* test for wrap */
                    BS = BA | (BS % MAXMEMSIZE);
                    return STOP_WRAP;
                    }
                return SCPE_OK;                         /* done */
                }
            t = dbuf[i] & CHAR;                         /* get char, strip parity */
            if (!(flag & MD_BIN) && (t == BCD_ALT))     /* BCD mode alt blank? */
                t = BCD_BLANK;                          /* real blank */
            if (flag & MD_WM) {                         /* word mk mode? */
                if ((t == BCD_WM) && (wm_seen == 0))    /* WM char, none prev? */
                    wm_seen = WM;                       /* set flag */
                else {
                    M[BS] = wm_seen | (t & CHAR);       /* char + wm seen */
                    wm_seen = 0;                        /* clear flag */
                    }
                }
            else M[BS] = (M[BS] & WM) | (t & CHAR);     /* preserve mem WM */
            if (!wm_seen)
                BS++;
            if (ADDR_ERR (BS)) {                        /* check next BS */
                BS = BA | (BS % MAXMEMSIZE);
                return STOP_WRAP;
                }
            }
        if (M[BS] != (BCD_GRPMRK + WM)) {               /* not GM+WM at end? */
            if (flag & MD_WM)                           /* LCA: clear WM */
                M[BS] = BCD_GRPMRK;
            else M[BS] = (M[BS] & WM) | BCD_GRPMRK;     /* MCW: save WM */
            }
        if (DEBUG_PRS (mt_dev))
            fprintf (sim_deb, " to %d, stopped by EOR\n", BS);
        BS++;                                           /* adv BS */
        if (ADDR_ERR (BS)) {                            /* check final BS */
            BS = BA | (BS % MAXMEMSIZE);
            return STOP_WRAP;
            }
        break;

    case BCD_W:
        if (sim_tape_wrp (uptr))                        /* locked? */
            return STOP_MTL;
        if (M[BS] == (BCD_GRPMRK + WM))                 /* eor? */
            return STOP_MTZ;
        if (DEBUG_PRS (mt_dev))
            fprintf (sim_deb, ">>MT%d: write from %d", unit, BS);
        for (tbc = 0; (t = M[BS++]) != (BCD_GRPMRK + WM); ) {
            if ((t & WM) && (flag & MD_WM))             /* WM in wm mode? */
                dbuf[tbc++] = BCD_WM;
            if (((t & CHAR) == BCD_BLANK) && !(flag & MD_BIN))
                dbuf[tbc++] = BCD_ALT;
            else dbuf[tbc++] = t & CHAR;
            if (ADDR_ERR (BS)) {                        /* check next BS */
                BS = BA | (BS % MAXMEMSIZE);
                return STOP_WRAP;
                }
            }
        if (DEBUG_PRS (mt_dev))
            fprintf (sim_deb, " to %d\n", BS - 1);
        passed_eot = sim_tape_eot (uptr);               /* passed EOT? */
        st = sim_tape_wrrecf (uptr, dbuf, tbc);         /* write record */
        if (!passed_eot && sim_tape_eot (uptr))         /* just passed EOT? */
            ind[IN_END] = 1;
        if (ADDR_ERR (BS)) {                            /* check final BS */
            BS = BA | (BS % MAXMEMSIZE);
            return STOP_WRAP;
            }
        break;

    default:
        return STOP_INVM;
        }

return mt_map_status (st);
}
Beispiel #6
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);
}