t_stat muxi_put_char (uint32 c, uint32 ln) { uint32 st; st = chan_WrMemB (mux_dib.dva, c); /* write char */ if (CHS_IFERR (st)) /* channel error? */ return mux_chan_err (st); st = chan_WrMemB (mux_dib.dva, ln); /* write line */ if (CHS_IFERR (st)) /* channel error? */ return mux_chan_err (st); if (st == CHS_ZBC) { /* bc == 0? */ muxc_cmd = MUXC_END; /* end state */ sim_activate (&mux_unit[MUXC], chan_ctl_time); /* quick schedule */ } io_sclr_req (mux_rint, 1); /* req ext intr */ return SCPE_OK; }
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 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; }