示例#1
0
t_stat fp_zero (FPA *fp)
{
uint32 i, mad = fp->addr;

for (i = 0; i < fp->lnt; i++) {                         /* clear mantissa */
    M[mad] = (i? M[mad] & FLAG: 0);                     /* clear sign bit */
    MM (mad);
    }
M[ADDR_A (fp->addr, 1)] = FLAG + 9;                     /* exp = -99 */
M[ADDR_A (fp->addr, 2)] = FLAG + 9;                     /* exp = -99 */
ind[IN_EZ] = 1;                                         /* result = 0 */
ind[IN_HP] = 0;
return SCPE_OK;
}
示例#2
0
文件: i1620_lp.c 项目: ST3ALth/simh
t_stat lpt (uint32 op, uint32 pa, uint32 f0, uint32 f1)
{
int8 lpc;
uint8 z, d;
t_stat r, sta;

sta = SCPE_OK;
sim_cancel (&lpt_unit);                                 /* "stall" until */
ind[IN_PRBSY] = 0;                                      /* printer free */

switch (op) {                                           /* decode op */

    case OP_K:                                          /* control */
        lpt_savctrl = (f0 << 4) | f1;                   /* form ctrl */
        if (lpt_savctrl & K_IMM)                        /* immediate? */
            return lpt_print ();
        break;

    case OP_DN:
        return lpt_num (pa, f1, TRUE);                  /* dump numeric  (tfm: removed len parm ) */

    case OP_WN:
        return lpt_num (pa, f1, FALSE);                 /* write numeric (tfm: removed len parm ) */

    case OP_WA:
        for ( ; lpt_bptr < LPT_BSIZE; lpt_bptr++) {     /* only fill buf */
            d = M[pa] & DIGIT;                          /* get digit */
            z = M[pa - 1] & DIGIT;                      /* get zone */
            if ((d & REC_MARK) == REC_MARK)             /* 8-2 char? */
                break;
            lpc = alp_to_lpt[(z << 4) | d];             /* translate pair */
            if (lpc < 0) {                              /* bad char? */
                ind[IN_WRCHK] = ind[IN_PRCHK] = 1;      /* wr chk */
                if (io_stop)                            /* set return status */
                    sta = STOP_INVCHR;
                }
            lpt_buf[lpt_bptr] = lpc & 0x7F;             /* fill buffer */
            pa = ADDR_A (pa, 2);                        /* incr mem addr */
            }
        if ((f1 & 1) == 0) {            ;               /* print now? */
            r = lpt_print ();                           /* print line */
            if (r != SCPE_OK)
                return r;
            }
        return sta;

    default:                                            /* invalid function */
        return STOP_INVFNC;
        }

return SCPE_OK;
}
示例#3
0
void fp_lsh_1 (FPA *fp)
{
uint32 i, mad, nxt;

mad = ADDR_S (fp->addr, fp->lnt - 1);                   /* hi order digit */
for (i = 0; i < (fp->lnt - 1); i++) {                   /* move lnt-1 digits */
    nxt = ADDR_A (mad, 1);
    M[mad] = (M[mad] & FLAG) | (M[nxt] & DIGIT);
    mad = nxt;
    }
M[mad] = M[mad] & FLAG;                                 /* clear last digit */
return;
}
示例#4
0
t_stat fp_pack (FPA *fp)
{
int32 e;
uint32 i, mad;

e = (fp->exp >= 0)? fp->exp: -fp->exp;                  /* get |exp| */                                 
if (e > FP_EMAX) {                                      /* too big? */
    ind[IN_EXPCHK] = 1;                                 /* set indicator */
    if (fp->exp < 0)                                    /* underflow? */
        return fp_zero (fp);
    mad = fp->addr;
    for (i = 0; i < fp->lnt; i++) {                     /* mant = 99...99 */
        M[mad] = (M[mad] & FLAG) | 9;
        MM (mad);
        }
    e = FP_EMAX;                                        /* cap at max */
    }
M[ADDR_A (fp->addr, 1)] = (e / 10) | FLAG;              /* high exp digit */
M[ADDR_A (fp->addr, 2)] = (e % 10) |                    /* low exp digit */
     ((fp->exp < 0)? FLAG: 0);
return SCPE_OK;
}
示例#5
0
文件: i1620_dp.c 项目: hstriepe/simh
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 */
}