Пример #1
0
t_stat ptr_svc (UNIT *uptr)
{
int32 temp;

if ((ptr_unit.flags & UNIT_ATT) == 0) {                 /* attached? */
    ptr_set_err ();                                     /* no, err, disc */
    CRETIOE (ptr_stopioe, SCPE_UNATT);
    }
if ((temp = getc (ptr_unit.fileref)) == EOF) {          /* end of file? */
    ptr_set_err ();                                     /* yes, err, disc */
    if (feof (ptr_unit.fileref)) {                      /* end of file? */
        if (ptr_stopioe)
            sim_printf ("PTR end of file\n");
        else return SCPE_OK;
        }
    else perror ("PTR I/O error");                      /* I/O error */
    clearerr (ptr_unit.fileref);
    return SCPE_IOERR;
    }
ptr_unit.pos = ptr_unit.pos + 1;                        /* inc position */
if (temp) {                                             /* leader/gap? */
    ptr_unit.buf = temp & 0177;                         /* no, save char */
    xfr_req = xfr_req | XFR_PTR;                        /* set xfr flag */
    ptr_sor = 0;                                        /* in record */
    }
else if (!ptr_sor)                                      /* end record? */
    chan_set_flag (ptr_dib.chan, CHF_EOR);              /* ignore leader */
sim_activate (&ptr_unit, ptr_unit.wait);                /* get next char */
return SCPE_OK;
}
Пример #2
0
t_stat ptp_out (int32 dat)
{
if ((ptp_unit.flags & UNIT_ATT) == 0) {                 /* attached? */
    ptp_set_err ();                                     /* no, disc, err */
    CRETIOE (ptp_stopioe, SCPE_UNATT);
    }
if (putc (dat, ptp_unit.fileref) == EOF) {              /* I/O error? */
    ptp_set_err ();                                     /* yes, disc, err */
    perror ("PTP I/O error");                           /* print msg */
    clearerr (ptp_unit.fileref);
    return SCPE_IOERR;
    }
ptp_unit.pos = ptp_unit.pos + 1;                        /* inc position */
return SCPE_OK;
}
Пример #3
0
t_stat lpt_status (UNIT *uptr)
{
if (uptr->flags & UNIT_ATT) {                           /* attached? */
    uptr->pos = ftell (uptr->fileref);                  /* update position */
    if (ferror (uptr->fileref)) {                       /* I/O error? */
        lpt_end_op (CHF_EOR | CHF_ERR);                 /* set err, disc */
        perror ("LPT I/O error");                       /* print msg */
        clearerr (uptr->fileref);
        return SCPE_IOERR;                              /* ret error */
        }
    }
else {
    lpt_end_op (CHF_EOR | CHF_ERR);                     /* set err, disc */
    CRETIOE (lpt_stopioe, SCPE_UNATT);                  /* ret error */
    }
return SCPE_OK;
}
Пример #4
0
t_stat dp_io (int32 fnc, int32 flg, int32 mod)
{
int32 dcf, drv, sec, psec, cnt, qwc, qzr, diff;
UNIT *uptr;
t_stat r;

dcf = BS;						/* save DCF addr */
qwc = 0;						/* not wcheck */
ind[IN_DPW] = ind[IN_LNG] = ind[IN_UNA] = 0;		/* clr indicators */
ind[IN_DSK] = ind[IN_ACC] = ind[IN_DBY] = 0;
if (sim_is_active (&dp_unit[0])) {			/* ctlr busy? */
	ind[IN_DBY] = ind[IN_DSK] = 1;			/* set indicators */
	return SCPE_OK;  }				/* done */

AS = dcf + 6;						/* AS for most ops */
BS = dcf + DCF_CNT - 1;					/* minimum DCF */
if (ADDR_ERR (BS)) return STOP_WRAP;			/* DCF in memory? */
if (M[dcf] & BBIT) drv = M[dcf + DCF_SEC + 1] & 0xE;	/* impl sel? cyl 8-4-2 */
else drv = M[dcf] & DIGIT;				/* get drive sel */
if ((drv == 0) || (drv & 1) || (drv > BCD_ZERO))	/* bad drive #? */
	return STOP_INVDSK;
drv = bcd_to_bin[drv] >> 1;				/* convert */
uptr = dp_dev.units + drv;				/* get unit ptr */
if ((uptr->flags & UNIT_ATT) == 0) {			/* attached? */
	ind[IN_DSK] = ind[IN_ACC] = 1;			/* no, error */
	CRETIOE (iochk, SCPE_UNATT);  }

if ((fnc == FNC_SEEK) &&				/* seek and */
    (M[dcf + DCF_DIR_FL] & DCF_DSEEK) == DCF_DSEEK) {	/* direct flag? */
	diff = dp_cvt_bcd (dcf + DCF_DIR, DCF_DIR_LEN);	/* cvt diff */
	if (diff < 0) return STOP_INVDSC;		/* error? */
	diff = diff >> 1;				/* diff is *2 */
	if ((M[dcf + DCF_DIR + DCF_DIR_LEN - 1] & ZONE) == BBIT)
	    diff = -diff;				/* get sign */
	uptr->CYL = uptr->CYL + diff;			/* bound seek */
	if (uptr->CYL < 0) uptr->CYL = 0;
	else if (uptr->CYL >= DP_NUMCY) {		/* too big? */
	    uptr->CYL = 0;				/* system hangs */
	    return STOP_INVDCY;  }
	sim_activate (&dp_unit[0], dp_time);		/* set ctlr busy */
	return SCPE_OK;  }				/* done! */
Пример #5
0
t_stat dp (uint32 op, uint32 pa, uint32 f0, uint32 f1)
{
    int32 drv, sa, sec, psec, cnt, qwc, qnr, t;
    UNIT *uptr;
    t_stat r;

    if (pa & 1)                                             /* dcf must be even */
        return STOP_INVDCF;
    ind[IN_DACH] = ind[IN_DWLR] = 0;                        /* clr indicators */
    ind[IN_DERR] = ind[IN_DCYO] = 0;
    sa = ADDR_A (pa, DCF_SEC);                              /* ptr to sector */
    if (((dp_unit[0].flags & UNIT_DIS) == 0) &&             /* only drive 0? */
            (dp_unit[1].flags & UNIT_DIS) &&
            (dp_unit[2].flags & UNIT_DIS) &&
            (dp_unit[3].flags & UNIT_DIS)) drv = 0;            /* ignore drv select */
    else drv = (((M[pa] & 1)? M[pa]: M[sa]) & 0xE) >> 1;    /* drive # */
    if (drv >= DP_NUMDR)                                    /* invalid? */
        return STOP_INVDRV;
    uptr = dp_dev.units + drv;                              /* get unit ptr */
    if ((uptr->flags & UNIT_ATT) == 0) {                    /* attached? */
        ind[IN_DERR] = 1;                                   /* no, error */
        CRETIOE (dp_stop, SCPE_UNATT);
    }

    sec = dp_cvt_bcd (sa, DCF_SEC_LEN);                     /* cvt sector */
    if ((sec < 0) || (sec >= (DP_NUMDR * DP_TOTSC)))        /* bad sector? */
        return STOP_INVDSC;
    if (op == OP_K) {                                       /* seek? */
        if (f1 != FNC_SEEK)                                 /* really? */
            return STOP_INVFNC;
        uptr->CYL = (sec / (DP_NUMSF * DP_NUMSC)) %         /* set cyl # */
                    DP_NUMCY;
        return SCPE_OK;                                     /* done! */
    }

    cnt = dp_cvt_bcd (ADDR_A (pa, DCF_CNT), DCF_CNT_LEN);   /* get count */
    t = dp_cvt_bcd (ADDR_A (pa, DCF_ADR), DCF_ADR_LEN);     /* get address */
    if ((t < 0) || (t & 1))                                 /* bad address? */
        return STOP_INVDBA;
    dp_ba = t;                                              /* save addr */

    if (f1 >= FNC_WRI)                                      /* invalid func? */
        return STOP_INVFNC;
    if (op == OP_RN)                                        /* read? set wch */
        qwc = f1 & FNC_WCH;
    else if (op == OP_WN) {                                 /* write? */
        if (op & FNC_WCH)                                   /* cant check */
            return STOP_INVFNC;
        f1 = f1 + FNC_WRI;                                  /* offset fnc */
    }
    else return STOP_INVFNC;                                /* not R or W */
    qnr = f1 & FNC_NRL;                                     /* no rec check? */

    switch (f1 & ~(FNC_WCH | FNC_NRL)) {                    /* case on function */

    case FNC_SEC:                                       /* read sectors */
        if (cnt <= 0)                                   /* bad count? */
            return STOP_INVDCN;
        psec = dp_fndsec (uptr, sec, TRUE);             /* find sector */
        if (psec < 0)                                   /* error? */
            CRETIOE (dp_stop, STOP_DACERR);
        do {                                            /* loop on count */
            if ((r = dp_rdsec (uptr, psec, qnr, qwc)))  /* read sector */
                break;
            sec++;
            psec++;                              /* next sector */
        } while ((--cnt > 0) &&
                 ((r = dp_nexsec (uptr, sec, psec, TRUE)) == SCPE_OK));
        break;                                          /* done, clean up */

    case FNC_TRK:                                       /* read track */
        psec = dp_trkop (drv, sec);                     /* start of track */
        for (cnt = 0; cnt < DP_NUMSC; cnt++) {          /* full track */
            if ((r = dp_rdadr (uptr, psec, qnr, qwc)))  /* read addr */
                break;                                  /* error? */
            if ((r = dp_rdsec (uptr, psec, qnr, qwc)))  /* read data */
                break;                                  /* error? */
            psec = dp_trkop (drv, sec) + ((psec + 1) % DP_NUMSC);
        }
        break;                                          /* done, clean up */

    case FNC_SEC + FNC_WRI:                             /* write */
        if (cnt <= 0)                                   /* bad count? */
            return STOP_INVDCN;
        psec = dp_fndsec (uptr, sec, FALSE);            /* find sector */
        if (psec < 0)                                   /* error? */
            CRETIOE (dp_stop, STOP_DACERR);
        do {                                            /* loop on count */
            if ((r = dp_tstgm (M[dp_ba], qnr)))         /* start with gm? */
                break;
            if ((r = dp_wrsec (uptr, psec, qnr)))       /* write data */
                break;
            sec++;
            psec++;                              /* next sector */
        } while ((--cnt > 0) &&
                 ((r = dp_nexsec (uptr, sec, psec, FALSE)) == SCPE_OK));
        break;                                          /* done, clean up */

    case FNC_TRK + FNC_WRI:                             /* write track */
        if ((uptr->flags & UNIT_WAE) == 0)              /* enabled? */
            return STOP_WRADIS;
        psec = dp_trkop (drv, sec);                     /* start of track */
        for (cnt = 0; cnt < DP_NUMSC; cnt++) {          /* full track */
            if ((r = dp_tstgm (M[dp_ba], qnr)))         /* start with gm? */
                break;
            if ((r = dp_wradr (uptr, psec, qnr)))       /* write addr */
                break;
            if ((r = dp_wrsec (uptr, psec, qnr)))       /* write data */
                break;
            psec = dp_trkop (drv, sec) + ((psec + 1) % DP_NUMSC);
        }
        break;                                          /* done, clean up */

    default:                                            /* unknown */
        return STOP_INVFNC;
    }

    if ((r == SCPE_OK) && !qnr) {                           /* eor check? */
        if ((M[dp_ba] & DIGIT) != GRP_MARK) {               /* GM at end? */
            ind[IN_DWLR] = ind[IN_DERR] = 1;                /* no, error */
            r = STOP_WRLERR;
        }
    }
    if ((r != SCPE_OK) &&                                   /* error? */
            (dp_stop || !ind[IN_DERR]))                         /* iochk or stop? */
        return r;
    return SCPE_OK;                                         /* continue */
}