t_stat mt_chan_err (uint32 st) { chan_uen (mt_dib.dva); /* uend */ if (st < CHS_ERR) return st; return SCPE_OK; }
t_stat mux_chan_err (uint32 st) { chan_uen (mux_dib.dva); /* uend */ muxc_cmd = MUXC_IDLE; /* go idle */ if (st < CHS_ERR) return st; return 0; }
t_stat pt_chan_err (uint32 st) { sim_cancel (&pt_unit[PTR]); /* stop dev thread */ chan_uen (pt_dib.dva); /* uend */ if (st < CHS_ERR) return st; return SCPE_OK; }
t_stat lp_chan_err (uint32 st) { sim_cancel (&lp_unit); /* stop dev thread */ chan_uen (lp_dib.dva); /* uend */ if (st < CHS_ERR) return st; return SCPE_OK; }
t_stat tt_chan_err (uint32 st) { tt_cmd = TTS_IDLE; sim_cancel (&tt_unit[TTO]); /* stop dev thread */ chan_uen (tt_dib.dva); /* uend */ if (st < CHS_ERR) return st; return SCPE_OK; }
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 mt_disp (uint32 op, uint32 dva, uint32 *dvst) { uint32 un = DVA_GETUNIT (dva); UNIT *uptr = &mt_unit[un]; if ((un >= MT_NUMDR) || /* inv unit num? */ (uptr-> flags & UNIT_DIS)) /* disabled unit? */ return DVT_NODEV; switch (op) { /* case on op */ case OP_SIO: /* start I/O */ *dvst = mt_tio_status (un); /* get status */ if ((*dvst & (DVS_CST|DVS_DST)) == 0) { /* ctrl + dev idle? */ uptr->UCMD = MCM_INIT; /* start dev thread */ sim_activate (uptr, chan_ctl_time); } break; case OP_TIO: /* test status */ *dvst = mt_tio_status (un); /* return status */ break; case OP_TDV: /* test status */ *dvst = mt_tdv_status (un); /* return status */ break; case OP_HIO: /* halt I/O */ *dvst = mt_tio_status (un); /* get status */ if ((int32) un == chan_chk_chi (dva)) /* halt active ctlr int? */ chan_clr_chi (dva); /* clear ctlr int */ if (sim_is_active (uptr)) { /* chan active? */ sim_cancel (uptr); /* stop unit */ chan_uen (dva); /* uend */ } mt_clr_rwi (un); /* clear rewind int */ sim_cancel (uptr + MT_REW); /* cancel rewind */ break; case OP_AIO: /* acknowledge int */ un = mt_clr_int (mt_dib.dva); /* clr int, get unit */ *dvst = (mt_tdv_status (un) & MTAI_MASK) | /* device status */ (un & MTAI_INT) | /* device int flag */ ((un & DVA_M_UNIT) << DVT_V_UN); /* unit number */ break; default: *dvst = 0; return SCPE_IERR; } return 0; }
uint32 lp_disp (uint32 op, uint32 dva, uint32 *dvst) { switch (op) { /* case on op */ case OP_SIO: /* start I/O */ *dvst = lp_tio_status (); /* get status */ if ((*dvst & DVS_DST) == 0) { /* idle? */ lp_cmd = LPS_INIT; /* start dev thread */ sim_activate (&lp_unit, chan_ctl_time); } break; case OP_TIO: /* test status */ *dvst = lp_tio_status (); /* return status */ break; case OP_TDV: /* test status */ *dvst = lp_tdv_status (); /* return status */ break; case OP_HIO: /* halt I/O */ chan_clr_chi (lp_dib.dva); /* clear int */ *dvst = lp_tio_status (); /* get status */ if ((*dvst & DVS_DST) != 0) { /* busy? */ sim_cancel (&lp_unit); /* stop dev thread */ chan_uen (lp_dib.dva); /* uend */ } break; case OP_AIO: /* acknowledge int */ chan_clr_chi (lp_dib.dva); /* clear int */ *dvst = lp_lastcmd & LPS_INT; /* int requested */ lp_lastcmd = 0; break; default: *dvst = 0; return SCPE_IERR; } return 0; }
uint32 pt_disp (uint32 op, uint32 dva, uint32 *dvst) { switch (op) { /* case on op */ case OP_SIO: /* start I/O */ *dvst = pt_tio_status (); /* get status */ if ((*dvst & DVS_DST) == 0) { /* idle? */ pt_cmd = PTS_INIT; /* start dev thread */ sim_activate (&pt_unit[PTR], chan_ctl_time); } break; case OP_TIO: /* test status */ *dvst = pt_tio_status (); /* return status */ break; case OP_TDV: /* test status */ *dvst = pt_tdv_status (); /* return status */ break; case OP_HIO: /* halt I/O */ chan_clr_chi (pt_dib.dva); /* clr int*/ *dvst = pt_tio_status (); /* get status */ if ((*dvst & DVS_DST) != 0) { /* busy? */ sim_cancel (&pt_unit[PTR]); /* stop dev thread */ chan_uen (pt_dib.dva); /* uend */ } break; case OP_AIO: /* acknowledge int */ chan_clr_chi (pt_dib.dva); /* clr int*/ *dvst = 0; /* no status */ break; default: *dvst = 0; return SCPE_IERR; } return 0; }
t_stat tti_svc (UNIT *uptr) { int32 c, ebcdic; uint32 st; if ((c = sim_poll_kbd ()) < SCPE_KFLAG) /* no char or err? */ return c; if (c & SCPE_BREAK) { /* break? */ if (tt_cmd == TTS_WRITE) { /* during write? */ tt_cmd = TTS_IDLE; sim_cancel (&tt_unit[TTO]); /* cancel write */ chan_uen (tt_dib.dva); /* uend */ } return SCPE_OK; } c = c & 0x7F; if (c == tti_panel) /* panel interrupt? */ return io_set_pint (); uptr->pos = uptr->pos + 1; /* incr count */ if (c == '\r') /* map CR to NL */ c = '\n'; if (c == 0x7F) /* map ^H back */ c = 0x08; c = sim_tt_inpcvt (c, TT_GET_MODE (uptr->flags)); /* input conversion */ ebcdic = ascii_to_ebcdic[c]; /* then to EBCDIC */ tto_echo (c); /* echo character */ if ((tt_cmd & 0x7F) == TTS_READ) { /* waiting for input? */ st = chan_WrMemB (tt_dib.dva, ebcdic); /* write to memory */ if (CHS_IFERR (st)) /* channel error? */ return tt_chan_err (st); if ((st == CHS_ZBC) || (ebcdic == E_EOM) || /* channel end? */ ((tt_cmd == TTS_READS) && ((ebcdic == E_HT) || (ebcdic == E_NL)))) { tt_cmd = TTS_END; /* new state */ sim_activate (&tt_unit[TTO], chan_ctl_time); /* start dev thread */ } } 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; }