t_stat muxi_rtc_svc (UNIT *uptr) { t_stat r; int32 newln, ln, c; if ((mux_unit[MUXC].flags & UNIT_ATT) == 0) /* attached? */ return SCPE_OK; newln = tmxr_poll_conn (&mux_desc); /* look for connect */ if ((newln >= 0) && (mux_sta[newln] & MUXL_REP)) { /* rcv enb pending? */ mux_ldsc[newln].rcve = 1; /* enable rcv */ mux_sta[newln] &= ~MUXL_REP; /* clr pending */ } tmxr_poll_rx (&mux_desc); /* poll for input */ for (ln = 0; ln < MUX_NUMLIN; ln++) { /* loop thru lines */ if (mux_ldsc[ln].conn) { /* connected? */ if (c = tmxr_getc_ln (&mux_ldsc[ln])) { /* get char */ if (c & SCPE_BREAK) /* break? */ mux_sta[ln] |= MUXL_RBP; /* set rcv brk */ else { /* normal char */ mux_sta[ln] &= ~MUXL_RBP; /* clr rcv brk */ c = sim_tt_inpcvt (c, TT_GET_MODE (muxl_unit[ln].flags)); mux_rbuf[ln] = c; /* save char */ if ((muxc_cmd == MUXC_RCV) && /* chan active? */ (r = muxi_put_char (c, ln))) /* char to chan */ return r; } /* end else char */ } /* end if char */ } /* end if conn */ else mux_sta[ln] &= ~MUXL_RBP; /* disconnected */ } /* end for */ return SCPE_OK; }
t_stat ttix_svc (UNIT *uptr) { int32 ln, c, temp; if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ return SCPE_OK; sim_clock_coschedule (uptr, tmxr_poll); /* continue poll */ ln = tmxr_poll_conn (&ttx_desc); /* look for connect */ if (ln >= 0) /* got one? rcv enb*/ ttx_ldsc[ln].rcve = 1; tmxr_poll_rx (&ttx_desc); /* poll for input */ for (ln = 0; ln < TTX_LINES; ln++) { /* loop thru lines */ if (ttx_ldsc[ln].conn) { /* connected? */ if (dev_done & (INT_TTI1 << ln)) /* Last character still pending? */ continue; if ((temp = tmxr_getc_ln (&ttx_ldsc[ln]))) { /* get char */ if (temp & SCPE_BREAK) /* break? */ c = 0; else c = sim_tt_inpcvt (temp, TT_GET_MODE (ttox_unit[ln].flags)); ttix_buf[ln] = c; dev_done = dev_done | (INT_TTI1 << ln); int_req = INT_UPDATE; } } } return SCPE_OK; }
int qty_update_rcvi( TMXR * mp ) { int line ; TMLN * lp ; int32 datum ; int changes ; /*------------------------------------------------------*/ /* Search through connected telnet lines for any input */ /* activity. */ /* */ /* enter: mp master telnet qty desc ptr */ /* */ /* return: int change count (0 = none seen) */ /*------------------------------------------------------*/ for ( changes = line = 0; line < mp->lines; ++line ) if ( (lp=mp->ldsc+line)->conn && lp->rcve ) if ( (datum=tmxr_getc_ln(lp)) ) { if ( datum & SCPE_BREAK ) { /* what should we do here - set QTY_L_BREAK? */ datum = datum & 0x00FF ; } else { datum = datum & 0x00FF ; } /* <check parity, masking, forced parity, CR/LF xlation> */ QTY_LINE_CLEAR_BIT( line, (QTY_L_RXBZ | QTY_L_DMASK) ) ; QTY_LINE_SET_BIT( line, (QTY_L_RXDN | datum) ) ; ++changes ; } return ( changes ) ; } /* end of 'qty_update_rcvi' */
t_stat ttix_svc (UNIT *uptr) { int32 ln, c, temp; if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ return SCPE_OK; sim_activate (uptr, clk_cosched (tmxr_poll)); /* continue poll */ ln = tmxr_poll_conn (&ttx_desc); /* look for connect */ if (ln >= 0) /* got one? rcv enab */ ttx_ldsc[ln].rcve = 1; tmxr_poll_rx (&ttx_desc); /* poll for input */ for (ln = 0; ln < TTX_MAXL; ln++) { /* loop thru lines */ if (ttx_ldsc[ln].conn) { /* connected? */ if (temp = tmxr_getc_ln (&ttx_ldsc[ln])) { /* get char */ if (temp & SCPE_BREAK) /* break? */ c = 0; else c = sim_tt_inpcvt (temp, TT_GET_MODE (ttox_unit[ln].flags) | TTUF_KSR); ttix_buf[ln] = c; ttix_set_done (ln); } } } return SCPE_OK; }
t_stat dtco_srv(UNIT * uptr) { int c, ln, t, c1; sim_clock_coschedule(uptr, tmxr_poll); ln = tmxr_poll_conn(&dtc_desc); /* look for connect */ if (ln >= 0) { /* got one? */ dtc_ldsc[ln].rcve = 1; dtc_blimit[ln] = dtc_bufsize-1; dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufWriteRdy; IAR |= IRQ_12; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm connect %d\n", ln); } /* For each line that is in idle state enable recieve */ for (ln = 0; ln < dtc_desc.lines; ln++) { dtc_ldsc[ln].rcve = 0; if (dtc_ldsc[ln].conn && (dtc_lstatus[ln] & BufSMASK) < BufWrite) { dtc_ldsc[ln].rcve = 1; } } tmxr_poll_rx(&dtc_desc); /* poll for input */ for (ln = 0; ln < DTC_MLINES; ln++) { /* loop thru mux */ /* Check for disconnect */ if (dtc_ldsc[ln].conn == 0 && (dtc_lstatus[ln] & BufDisco) == 0) { /* connected? */ dtc_ldsc[ln].rcve = 0; switch(dtc_lstatus[ln] & BufSMASK) { case BufIdle: /* Idle Flag as disconnected */ dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufIdle|BufDisco; dtc_bsize[ln] = 0; IAR |= IRQ_12; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d idle\n", ln); break; case BufWriteRdy: /* Awaiting output, terminate */ dtc_bufptr[ln] = 0; /* Fall through */ case BufInputBusy: /* reading, terminate with EOT */ dtc_buf[ln][dtc_bufptr[ln]++] = 017; dtc_bsize[ln] = dtc_bufptr[ln]+1; dtc_lstatus[ln] = BufIRQ|BufAbnormal|BufReadRdy; IAR |= IRQ_12; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d write\n", ln); break; case BufOutBusy: /* Terminate Output */ dtc_lstatus[ln] = BufIRQ|BufIdle|BufAbnormal; dtc_bsize[ln] = 0; IAR |= IRQ_12; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d out\n", ln); break; default: /* Other cases, ignore until in better state */ break; break; } continue; /* Skip if not connected */ } switch(dtc_lstatus[ln] & BufSMASK) { case BufIdle: /* If we have any data to receive */ if (tmxr_rqln(&dtc_ldsc[ln]) > 0) { dtc_lstatus[ln] &= ~(BufSMASK); dtc_lstatus[ln] |= BufInputBusy; } else break; /* Nothing to do */ sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve %d idle\n", ln); dtc_bufptr[ln] = 0; dtc_bsize[ln] = 0; /* Fall through */ case BufInputBusy: t = 1; while (t) { c = tmxr_getc_ln(&dtc_ldsc[ln]); /* get char */ if (c == 0) break; c &= 0x7f; c1 = ascii_to_con[c]; switch(c) { case '\005': /* ^E ENQ who-are-you */ dtc_lstatus[ln] &= ~(BufSMASK); dtc_lstatus[ln] |= BufIRQ|BufWriteRdy|BufAbnormal; IAR |= IRQ_12; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve ENQ %d\n", ln); t = 0; break; case '\003': /* ^B send STX */ dtc_lstatus[ln] &= ~BufSMASK; dtc_lstatus[ln] |= BufIRQ|BufReadRdy|BufAbnormal; dtc_buf[ln][0] = 0; dtc_buf[ln][1] = 017; dtc_buf[ln][2] = 077; dtc_bsize[ln] = 1; IAR |= IRQ_12; t = 0; break; case '}': dtc_buf[ln][dtc_bufptr[ln]++] = 017; dtc_lstatus[ln] |= BufAbnormal; /* Fall through to next */ case '\r': /* Fall through */ case '\n': /* Fall through */ case '~': dtc_lstatus[ln] &= ~BufSMASK; dtc_lstatus[ln] |= BufIRQ|BufReadRdy; /* Force at least one character for GM */ dtc_buf[ln][dtc_bufptr[ln]++] = 077; dtc_bsize[ln] = dtc_bufptr[ln]; IAR |= IRQ_12; t = 0; c1 = 0; sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve %d return\n", ln); break; case '\025': /* Control U clear input buffer. */ dtc_bsize[ln] = 0; c1 = 0; break; case '\b': case 0x7f: if (dtc_bufptr[ln] > 0) { tmxr_putc_ln(&dtc_ldsc[ln], '\b'); tmxr_putc_ln(&dtc_ldsc[ln], ' '); tmxr_putc_ln(&dtc_ldsc[ln], '\b'); dtc_bufptr[ln]--; } else { tmxr_putc_ln(&dtc_ldsc[ln], '\007'); } c1 = 0; sim_debug(DEBUG_DATA, &dtc_dev, "Datacomm recieve %d backspace %d\n", ln, dtc_bufptr[ln]); break; case '?': sim_debug(DEBUG_DATA, &dtc_dev, "Datacomm recieve %d ?\n", ln); dtc_lstatus[ln] |= BufAbnormal; tmxr_putc_ln(&dtc_ldsc[ln], '?'); dtc_buf[ln][dtc_bufptr[ln]++] = c1; break; default: sim_debug(DEBUG_DATA, &dtc_dev, "Datacomm recieve %d %02x %c %02o %d\n", ln, c, c, c1, dtc_bufptr[ln]); } if (t && c1) { tmxr_putc_ln(&dtc_ldsc[ln], con_to_ascii[c1]); dtc_buf[ln][dtc_bufptr[ln]++] = c1; } if (dtc_bufptr[ln] >= dtc_blimit[ln]) { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm recieve %d full\n", ln); dtc_lstatus[ln] &= ~(BufSMASK); dtc_lstatus[ln] |= BufGM|BufIRQ|BufReadRdy; dtc_bsize[ln] = dtc_bufptr[ln]; IAR |= IRQ_12; t = 0; break; } } break; case BufOutBusy: /* Get next char and send to output */ t = 1; while(t && dtc_bufptr[ln] < dtc_bsize[ln] && dtc_ldsc[ln].xmte) { c = dtc_buf[ln][dtc_bufptr[ln]++]; c1 = con_to_ascii[c]; switch(c) { case 057: /* { */ c1 = '\r'; /* CR */ break; case 032: /* ! */ c1 = '\n'; /* LF */ break; case 076: /* < */ c1 = 0; /* X-ON */ break; case 016: /* > */ c1 = 0; /* DEL */ break; case 017: /* } */ /* Disconnect line */ tmxr_reset_ln(&dtc_ldsc[ln]); sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm disconnect %d\n", ln); t = 0; continue; /* On to next line */ } sim_debug(DEBUG_DATA, &dtc_dev, "Datacomm transmit %d %02o %c\n", ln, c&077, c1); tmxr_putc_ln(&dtc_ldsc[ln], c1); if (c1 == '\n') { tmxr_putc_ln(&dtc_ldsc[ln], '\r'); } } if (dtc_bufptr[ln] >= dtc_bsize[ln]) { if (dtc_lstatus[ln] & BufGM) { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm idle %d\n", ln); dtc_lstatus[ln] = BufIRQ|BufIdle; } else { sim_debug(DEBUG_DETAIL, &dtc_dev, "Datacomm writerdy %d\n", ln); dtc_lstatus[ln] = BufIRQ|BufWriteRdy; } IAR |= IRQ_12; } break; default: /* Other states are an ignore */ break; } } /* end for */ tmxr_poll_tx(&dtc_desc); /* poll xmt */ return SCPE_OK; }
t_stat ports_rcv_svc(UNIT *uptr) { uint8 cid, subdev; int32 temp, ln; char c; cio_entry rentry = {0}; cio_entry centry = {0}; uint8 rapp_data[4] = {0}; uint8 capp_data[4] = {0}; if ((uptr->flags & UNIT_ATT) == 0) { return SCPE_OK; } ln = tmxr_poll_conn(&ports_desc); if (ln >= 0) { ports_update_conn(ln); } tmxr_poll_rx(&ports_desc); for (ln = 0; ln < ports_desc.lines; ln++) { cid = LCID(ln); subdev = LPORT(ln); if (!ports_ldsc[ln].conn && ports_state[ln].conn) { ports_update_conn(ln); } else if (ports_ldsc[ln].conn && ports_state[ln].conn) { temp = tmxr_getc_ln(&ports_ldsc[ln]); if (temp && !(temp & SCPE_BREAK)) { c = (char) (temp & 0xff); sim_debug(IO_DBG, &ports_dev, "[LINE %d RECEIVE] char = %02x (%c)\n", ln, c, c); if (c == 0xd && (ports_state[ln].iflag & ICRNL)) { c = 0xa; } if (cio[cid].ivec > 0 && cio_rqueue(cid, PORTS_RCV_QUEUE, PPQESIZE, &rentry, rapp_data) == SCPE_OK) { cio[cid].intr = TRUE; /* Write the character to the memory address */ pwrite_b(rentry.address, c); centry.subdevice = LPORT(ln); centry.opcode = PPC_RECV; centry.address = rentry.address; capp_data[3] = RC_TMR; cio_cqueue(cid, CIO_STAT, PPQESIZE, ¢ry, capp_data); } } } } tmxr_clock_coschedule(uptr, tmxr_poll); return SCPE_OK; }