t_stat tto_svc (UNIT *uptr) { int32 c; uint32 uc, cmd, st; switch (tt_cmd) { /* case on state */ case TTS_INIT: /* I/O init */ st = chan_get_cmd (tt_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ return tt_chan_err (st); if ((cmd == TTS_WRITE) || /* valid command? */ ((cmd & 0x7F) == TTS_READ)) tt_cmd = cmd; /* next state */ else tt_cmd = TTS_END; /* no, end state */ sim_activate (uptr, chan_ctl_time); /* continue thread */ break; case TTS_WRITE: /* char output */ st = chan_RdMemB (tt_dib.dva, &uc); /* get char */ if (CHS_IFERR (st)) /* channel error? */ return tt_chan_err (st); c = ebcdic_to_ascii[uc & 0xFF]; /* convert to ASCII */ tto_echo (c); /* echo character */ sim_activate (uptr, uptr->wait); /* continue thread */ if (st == CHS_ZBC) /* st = zbc? */ tt_cmd = TTS_END; /* next is end */ else tt_cmd = TTS_WRITE; /* next is write */ break; case TTS_END: /* command done */ st = chan_end (tt_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ return tt_chan_err (st); if (st == CHS_CCH) { /* command chain? */ tt_cmd = TTS_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); } else tt_cmd = TTS_IDLE; /* all done */ break; } return SCPE_OK; }
t_stat muxc_svc (UNIT *uptr) { uint32 st; uint32 cmd; if (muxc_cmd == MUXC_INIT) { /* init state? */ st = chan_get_cmd (mux_dib.dva, &cmd); /* get command */ if (CHS_IFERR (st)) /* channel error? */ mux_chan_err (st); /* go idle */ else muxc_cmd = MUXC_RCV; /* no, receive */ } else if (muxc_cmd == MUXC_END) { /* end state? */ st = chan_end (mux_dib.dva); /* set channel end */ if (CHS_IFERR (st)) /* channel error? */ mux_chan_err (st); /* go idle */ else if (st == CHS_CCH) { /* command chain? */ muxc_cmd = MUXC_INIT; /* restart thread */ sim_activate (uptr, chan_ctl_time); /* schedule soon */ } else muxc_cmd = MUXC_IDLE; /* else idle */ } return SCPE_OK; }
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; }