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; }
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; }
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; }
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; }
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 */ }