t_stat mt_map_err (UNIT *uptr, t_stat st) { int32 u = uptr - mt_dev.units; switch (st) { case MTSE_FMT: /* illegal fmt */ case MTSE_UNATT: /* not attached */ case MTSE_WRP: /* write protect */ chan_set_chf (mt_dib.dva, CHF_XMME); case MTSE_OK: /* no error */ chan_uen (mt_dib.dva); /* uend */ return SCPE_IERR; case MTSE_TMK: /* end of file */ uptr->UST |= MTDV_EOF; /* set eof flag */ chan_uen (mt_dib.dva); /* uend */ return CHS_INACTV; case MTSE_IOERR: /* IO error */ uptr->UST |= MTDV_DTE; /* set DTE flag */ chan_set_chf (mt_dib.dva, CHF_XMDE); chan_uen (mt_dib.dva); /* force uend */ return SCPE_IOERR; case MTSE_INVRL: /* invalid rec lnt */ uptr->UST |= MTDV_DTE; /* set DTE flag */ chan_set_chf (mt_dib.dva, CHF_XMDE); chan_uen (mt_dib.dva); /* force uend */ return SCPE_MTRLNT; case MTSE_RECE: /* record in error */ case MTSE_EOM: /* end of medium */ uptr->UST |= MTDV_DTE; /* set DTE flag */ return chan_set_chf (mt_dib.dva, CHF_XMDE); /* possible error */ case MTSE_BOT: /* reverse into BOT */ uptr->UST |= MTDV_BOT; /* set BOT */ chan_uen (mt_dib.dva); /* uend */ return CHS_INACTV; } /* end switch */ return SCPE_OK; }
uint32 lp_print (UNIT *uptr) { uint32 i, bp, c; uint32 max = (lp_model == LP_7440)? BUF_LNT4: BUF_LNT5; uint32 st; if (lp_pass == 0) { /* pass 1? clr buf */ for (i = 0; i < BUF_LNT4; i++) lp_buf[i] = ' '; } for (bp = 0, st = 0; (bp < max) && !st; bp++) { /* fill buffer */ st = chan_RdMemB (lp_dib.dva, &c); /* get char */ if (CHS_IFERR (st)) /* channel error? */ return st; /* caller handles */ if ((lp_model == LP_7440) || /* 7440 or */ ((bp & 1) == lp_pass)) /* correct pass? */ lp_buf[bp] = lp_to_ascii[c & 0x3F]; } if ((lp_model == LP_7440) || lp_pass) { /* ready to print? */ lp_pass = 0; for (i = BUF_LNT4; (i > 0) && (lp_buf[i - 1] == ' '); i--) ; /* trim */ if (i) /* write line */ sim_fwrite (lp_buf, 1, i, uptr->fileref); fputc (lp_inh? '\r': '\n', uptr->fileref); /* cr or nl */ uptr->pos = ftell (uptr->fileref); /* update position */ if (ferror (uptr->fileref)) { /* error? */ sim_perror ("Line printer I/O error"); clearerr (uptr->fileref); chan_set_chf (lp_dib.dva, CHF_XMDE); return SCPE_IOERR; } if ((lp_model == LP_7440) && /* 7440? */ ((bp != BUF_LNT4) || (st != CHS_ZBC)) && /* check lnt err */ chan_set_chf (lp_dib.dva, CHF_LNTE)) return CHS_INACTV; /* stop if asked */ } else lp_pass = 1; /* 7450 pass 2 */ lp_cmd = LPS_END; /* end state */ return 0; }
uint32 lp_space (UNIT *uptr, uint32 cnt, t_bool skp) { uint32 i; lp_cctp = (lp_cctp + cnt) % lp_cctl; /* adv cct, mod lnt */ if (skp && CHP (CH_TOF, lp_cct[lp_cctp])) /* skip, TOF? */ fputs ("\f", uptr->fileref); /* ff */ else { /* space */ for (i = 0; i < cnt; i++) fputc ('\n', uptr->fileref); } uptr->pos = ftell (uptr->fileref); /* update position */ if (ferror (uptr->fileref)) { /* error? */ sim_perror ("Line printer I/O error"); clearerr (uptr->fileref); chan_set_chf (lp_dib.dva, CHF_XMDE); return SCPE_IOERR; } return 0; }
t_stat mtu_svc (UNIT *uptr) { uint32 cmd = uptr->UCMD; uint32 un = uptr - mt_unit; uint32 c; uint32 st; int32 t; t_mtrlnt tbc; t_stat r; if (cmd == MCM_INIT) { /* init state */ if ((t = sim_activate_time (uptr + MT_REW)) != 0) { /* rewinding? */ sim_activate (uptr, t); /* retry later */ return SCPE_OK; } st = chan_get_cmd (mt_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if ((cmd & 0x80) || /* invalid cmd? */ (mt_op[cmd] == 0)) { uptr->UCMD = MCM_END; /* end state */ sim_activate (uptr, chan_ctl_time); /* resched ctlr */ return SCPE_OK; } else { /* valid cmd */ if ((mt_op[cmd] & O_REV) && /* reverse op */ (mt_unit[un].UST & MTDV_BOT)) { /* at load point? */ chan_uen (mt_dib.dva); /* channel end */ return SCPE_OK; } uptr->UCMD = cmd; /* unit state */ if (!(mt_op[cmd] & O_NMT)) /* motion? */ uptr->UST = 0; /* clear status */ } mt_blim = 0; /* no buffer yet */ sim_activate (uptr, chan_ctl_time); /* continue thread */ return SCPE_OK; /* done */ } if (cmd == MCM_END) { /* end state */ st = chan_end (mt_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if (st == CHS_CCH) { /* command chain? */ uptr->UCMD = MCM_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); } else uptr->UCMD = 0; /* ctlr idle */ return SCPE_OK; /* done */ } if ((mt_op[cmd] & O_ATT) && /* op req att and */ ((uptr->flags & UNIT_ATT) == 0)) { /* not attached? */ sim_activate (uptr, mt_ctime); /* retry */ return mt_stopioe? SCPE_UNATT: SCPE_OK; } if ((mt_op[cmd] & O_WRE) && /* write op and */ sim_tape_wrp (uptr)) { /* write protected? */ uptr->UST |= MTDV_WLE; /* set status */ chan_uen (mt_dib.dva); /* unusual end */ return SCPE_OK; } r = SCPE_OK; switch (cmd) { /* case on command */ case MCM_SFWR: /* space forward */ if (r = sim_tape_sprecf (uptr, &tbc)) /* spc rec fwd, err? */ r = mt_map_err (uptr, r); /* map error */ break; case MCM_SBKR: /* space reverse */ if (r = sim_tape_sprecr (uptr, &tbc)) /* spc rec rev, err? */ r = mt_map_err (uptr, r); /* map error */ break; case MCM_SFWF: /* space fwd file */ while ((r = sim_tape_sprecf (uptr, &tbc)) == MTSE_OK) ; if (r != MTSE_TMK) /* stopped by tmk? */ r = mt_map_err (uptr, r); /* no, map error */ else r = SCPE_OK; break; case MCM_SBKF: /* space rev file */ while ((r = sim_tape_sprecr (uptr, &tbc)) == MTSE_OK) ; if (r != MTSE_TMK) /* stopped by tmk? */ r = mt_map_err (uptr, r); /* no, map error */ else r = SCPE_OK; break; case MCM_WTM: /* write eof */ if (r = sim_tape_wrtmk (uptr)) /* write tmk, err? */ r = mt_map_err (uptr, r); /* map error */ uptr->UST |= MTDV_EOF; /* set eof */ break; case MCM_RWU: /* rewind unload */ r = detach_unit (uptr); break; case MCM_REW: /* rewind */ case MCM_RWI: /* rewind and int */ if (r = sim_tape_rewind (uptr)) /* rewind */ r = mt_map_err (uptr, r); /* map error */ mt_unit[un + MT_REW].UCMD = uptr->UCMD; /* copy command */ sim_activate (uptr + MT_REW, mt_rwtime); /* sched compl */ break; case MCM_READ: /* read */ if (mt_blim == 0) { /* first read? */ r = sim_tape_rdrecf (uptr, mt_xb, &mt_blim, MT_MAXFR); if (r != MTSE_OK) { /* tape error? */ r = mt_map_err (uptr, r); /* map error */ break; } mt_bptr = 0; /* init rec ptr */ } c = mt_xb[mt_bptr++]; /* get char */ st = chan_WrMemB (mt_dib.dva, c); /* write to memory */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if ((st != CHS_ZBC) && (mt_bptr != mt_blim)) { /* not done? */ sim_activate (uptr, mt_time); /* continue thread */ return SCPE_OK; } if (((st == CHS_ZBC) ^ (mt_bptr == mt_blim)) && /* length err? */ chan_set_chf (mt_dib.dva, CHF_LNTE)) /* uend taken? */ return SCPE_OK; /* finished */ break; /* normal end */ case MCM_RDBK: /* read reverse */ if (mt_blim == 0) { /* first read? */ r = sim_tape_rdrecr (uptr, mt_xb, &mt_blim, MT_MAXFR); if (r != MTSE_OK) { /* tape error? */ r = mt_map_err (uptr, r); /* map error */ break; } mt_bptr = mt_blim; /* init rec ptr */ } c = mt_xb[--mt_bptr]; /* get char */ st = chan_WrMemBR (mt_dib.dva, c); /* write mem rev */ if (CHS_IFERR (st)) /* channel error? */ return mt_chan_err (st); if ((st != CHS_ZBC) && (mt_bptr != 0)) { /* not done? */ sim_activate (uptr, mt_time); /* continue thread */ return SCPE_OK; } if (((st == CHS_ZBC) ^ (mt_bptr == 0)) && /* length err? */ chan_set_chf (mt_dib.dva, CHF_LNTE)) /* uend taken? */ return SCPE_OK; /* finished */ break; /* normal end */ case MCM_WRITE: /* write */ st = chan_RdMemB (mt_dib.dva, &c); /* read char */ if (CHS_IFERR (st)) { /* channel error? */ mt_flush_buf (uptr); /* flush buffer */ return mt_chan_err (st); } mt_xb[mt_blim++] = c; /* store in buffer */ if (st != CHS_ZBC) { /* end record? */ sim_activate (uptr, mt_time); /* continue thread */ return SCPE_OK; } r = mt_flush_buf (uptr); /* flush buffer */ break; } if (r != SCPE_OK) /* error? abort */ return CHS_IFERR(r)? SCPE_OK: r; uptr->UCMD = MCM_END; /* end state */ sim_activate (uptr, mt_ctime); /* sched ctlr */ return SCPE_OK; }
t_stat lp_svc (UNIT *uptr) { uint32 cmd; uint32 st; switch (lp_cmd) { /* case on state */ case LPS_INIT: /* I/O init */ st = chan_get_cmd (lp_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return lp_chan_err (st); lp_inh = 0; /* clear inhibit, */ lp_run = 0; /* runaway */ lp_cmd = lp_lastcmd = cmd; /* save command */ sim_activate (uptr, chan_ctl_time); /* continue thread */ break; case LPS_FMT: case LPS_FMT|LPS_INT: /* format only */ sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return lp_stopioe? SCPE_UNATT: SCPE_OK; st = lp_fmt (uptr); /* format */ if (CHS_IFERR (st)) /* error? */ return lp_chan_err (st); if ((lp_model == LP_7440) && /* 7440? lnt chk */ (st != CHS_ZBC) && chan_set_chf (lp_dib.dva, CHF_LNTE)) /* not ignored? */ return lp_chan_err (SCPE_OK); /* force uend */ lp_cmd = LPS_END; /* actual print */ break; case LPS_FMTP: case LPS_FMTP|LPS_INT: /* format and print */ sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return lp_stopioe? SCPE_UNATT: SCPE_OK; st = lp_fmt (uptr); /* format */ if (CHS_IFERR (st)) /* error? */ return lp_chan_err (st); if (st == CHS_ZBC) { /* command done? */ if ((lp_model == LP_7440) && /* 7440? lnt err */ chan_set_chf (lp_dib.dva, CHF_LNTE)) /* not ignored? */ return lp_chan_err (SCPE_OK); } else { /* more to do */ st = lp_print (uptr); /* print */ if (CHS_IFERR (st)) /* error */ return lp_chan_err (st); } break; case LPS_PRI: case LPS_PRI|LPS_INT: /* print only */ sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return lp_stopioe? SCPE_UNATT: SCPE_OK; st = lp_print (uptr); /* print */ if (CHS_IFERR (st)) /* error? */ return lp_chan_err (st); break; case LPS_END: /* command done */ if ((lp_lastcmd & LPS_INT) && !lp_pass) /* int requested? */ chan_set_chi (lp_dib.dva, 0); st = chan_end (lp_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ return lp_chan_err (st); if (st == CHS_CCH) { /* command chain? */ lp_cmd = LPS_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); } break; default: /* invalid cmd */ chan_uen (lp_dib.dva); /* uend */ break; } return SCPE_OK; }
t_stat pt_svc (UNIT *uptr) { int32 c; uint32 cmd; uint32 st; switch (pt_cmd) { /* case on state */ case PTS_INIT: /* I/O init */ st = chan_get_cmd (pt_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return pt_chan_err (st); if ((cmd == PTS_WRITE) || /* valid command? */ ((cmd & 0x7F) == PTS_READ)) pt_cmd = cmd; /* next state */ else pt_cmd = PTS_END; /* no, end state */ sim_activate (uptr, chan_ctl_time); /* continue thread */ break; case PTS_READ: case PTS_READI: sim_activate (uptr, uptr->wait); /* continue thread */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return ptr_stopioe? SCPE_UNATT: SCPE_OK; if ((c = getc (uptr->fileref)) == EOF) { /* read char */ if (feof (uptr->fileref)) { /* end of file? */ chan_set_chf (pt_dib.dva, CHF_LNTE); /* length error */ pt_cmd = PTS_END; /* end state */ break; } else { /* real error */ perror ("PTR I/O error"); clearerr (uptr->fileref); chan_set_chf (pt_dib.dva, CHF_XMDE); /* data error */ return pt_chan_err (SCPE_IOERR); /* force uend */ } } uptr->pos = uptr->pos + 1; if (c != 0) /* leader done? */ ptr_nzc = 1; /* set flag */ if ((pt_cmd == PTS_READI) || ptr_nzc) { st = chan_WrMemB (pt_dib.dva, c); /* write to memory */ if (CHS_IFERR (st)) /* channel error? */ return pt_chan_err (st); if (st == CHS_ZBC) /* bc == 0? */ pt_cmd = PTS_END; /* end state */ } break; case PTS_WRITE: /* write */ sim_activate (uptr, pt_unit[PTP].wait); /* continue thread */ if ((pt_unit[PTP].flags & UNIT_ATT) == 0) /* not attached? */ return ptp_stopioe? SCPE_UNATT: SCPE_OK; st = chan_RdMemB (pt_dib.dva, &c); /* read from channel */ if (CHS_IFERR (st)) /* channel error? */ return pt_chan_err (st); if (putc (c, pt_unit[PTP].fileref) == EOF) { perror ("PTP I/O error"); clearerr (pt_unit[PTP].fileref); chan_set_chf (pt_dib.dva, CHF_XMDE); /* data error */ return pt_chan_err (SCPE_IOERR); /* force uend */ } pt_unit[PTP].pos = pt_unit[PTP].pos + 1; if (st == CHS_ZBC) /* bc == 0? */ pt_cmd = PTS_END; /* end state */ break; case PTS_END: /* command done */ st = chan_end (pt_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ return pt_chan_err (st); if (st == CHS_CCH) { /* command chain? */ pt_cmd = PTS_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); } break; } return SCPE_OK; }