Example #1
0
t_stat qty_common_svc( DIB * dibp, UNIT * unitp )
{
    int     line ;
    int     newln ;
    TMLN *      tmlnp ;

    ++qty_polls ;                                       /*  another time 'round the track  */
    newln = tmxr_poll_conn( &qty_desc ) ;               /*  anybody knocking at the door?  */
    if ( (newln >= 0) && qty_mdm )
        if ( newln >= qty_max )
        {
            return SCPE_IERR;                               /*  WTF - sanity check failed, over?  */
        }
        else
        {
            line = newln ;                                  /*  handle modem control  */
            tmlnp =&qty_ldsc[ line ] ;
            tmlnp->rcve = tmlnp->xmte = 1 ;
            /*  do QTY_LINE_ bit fiddling and state machine
             *  manipulation with modem control signals
             */
        }

    tmxr_poll_rx( &qty_desc ) ;                         /*  poll input                          */
    qty_update_rcvi( &qty_desc ) ;                      /*  update receiver interrupt status    */

    tmxr_poll_tx( &qty_desc ) ;                         /*  poll output                         */
    qty_update_xmti( &qty_desc ) ;                      /*  update transmitter interrupt status */

    qty_update_status( dibp, &qty_desc ) ;              /*  update device status                */

    sim_activate( unitp, tmxr_poll ) ;                  /*  restart the bubble machine          */
    return ( SCPE_OK ) ;
}   /*  end of 'qty_common_svc'  */
Example #2
0
t_stat ttox_svc (UNIT *uptr)
{
int32 c, ln = uptr - ttox_unit;                         /* line # */

if (ttx_ldsc[ln].conn) {                                /* connected? */
    if (ttx_ldsc[ln].xmte) {                            /* tx enabled? */
        TMLN *lp = &ttx_ldsc[ln];                       /* get line */
        c = sim_tt_outcvt (ttox_buf[ln], TT_GET_MODE (ttox_unit[ln].flags) | TTUF_KSR);
        if (c >= 0)                                     /* output char */
            tmxr_putc_ln (lp, c);
        tmxr_poll_tx (&ttx_desc);                       /* poll xmt */
        }
    else {
        tmxr_poll_tx (&ttx_desc);                       /* poll xmt */
        sim_activate (uptr, ttox_unit[ln].wait);        /* wait */
        return SCPE_OK;
        }
    }
ttox_set_done (ln);                                     /* set done */
return SCPE_OK;
}
Example #3
0
t_stat muxo_svc (UNIT *uptr)
{
    int32 c;
    uint32 ln = uptr - muxl_unit;                           /* line # */

    if (mux_ldsc[ln].conn) {                                /* connected? */
        if (mux_ldsc[ln].xmte) {                            /* xmt enabled? */
            c = sim_tt_outcvt (mux_xbuf[ln], TT_GET_MODE (muxl_unit[ln].flags));
            if (c >= 0)
                tmxr_putc_ln (&mux_ldsc[ln], c);            /* output char */
            tmxr_poll_tx (&mux_desc);                       /* poll xmt */
            if (mux_sta[ln] & MUXL_XIA) {                   /* armed? */
                mux_sta[ln] |= MUXL_XIR;                    /* req intr */
                mux_scan_next (0);                          /* kick scanner */
            }
        }
        else {                                              /* buf full */
            tmxr_poll_tx (&mux_desc);                       /* poll xmt */
            sim_activate (uptr, muxl_unit[ln].wait);        /* wait */
            return SCPE_OK;
        }
    }
    return SCPE_OK;
}
Example #4
0
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;
}
Example #5
0
t_stat ports_xmt_svc(UNIT *uptr)
{
    uint8 cid, ln;
    char c;
    t_bool tx = FALSE; /* Did a tx ever occur? */
    cio_entry centry = {0};
    uint8 app_data[4] = {0};
    uint32 wait = 0x7fffffff;

    /* Scan all lines for output */
    for (ln = 0; ln < ports_desc.lines; ln++) {
        cid = LCID(ln);
        if (ports_ldsc[ln].conn && ports_state[ln].tx_chars > 0) {
            tx = TRUE; /* Even an attempt at TX counts for rescheduling */
            c = sim_tt_outcvt(pread_b(ports_state[ln].tx_addr),
                              TT_GET_MODE(ports_unit[0].flags));

            /* The PORTS card optionally handles NL->CRLF */
            if (c == 0xa &&
                (ports_state[ln].oflag & ONLCR) &&
                !(ports_state[ln].crlf)) {
                if (tmxr_putc_ln(&ports_ldsc[ln], 0xd) == SCPE_OK) {
                    wait = MIN(wait, ports_ldsc[ln].txdeltausecs);
                    sim_debug(IO_DBG, &ports_dev,
                              "[%08x] [ports_xmt_svc] [LINE %d] XMIT (crlf):  %02x (%c)\n",
                              R[NUM_PC], ln, 0xd, 0xd);
                    /* Indicate that we're in a CRLF translation */
                    ports_state[ln].crlf = TRUE;
                }

                break;
            }

            ports_state[ln].crlf = FALSE;

            if (tmxr_putc_ln(&ports_ldsc[ln], c) == SCPE_OK) {
                wait = MIN(wait, ports_ldsc[ln].txdeltausecs);
                ports_state[ln].tx_chars--;
                ports_state[ln].tx_addr++;
                sim_debug(IO_DBG, &ports_dev,
                          "[%08x] [ports_xmt_svc] [LINE %d] XMIT:         %02x (%c)\n",
                          R[NUM_PC], ln, c, c);
            }

            if (ports_state[ln].tx_chars == 0) {
                sim_debug(TRACE_DBG, &ports_dev,
                          "[%08x] [ports_xmt_svc] Done with xmit, card=%d port=%d. Interrupting.\n",
                          R[NUM_PC], cid, LPORT(ln));
                centry.byte_count = ports_state[ln].tx_req_chars;
                centry.subdevice = LPORT(ln);
                centry.opcode = PPC_XMIT;
                centry.address = ports_state[ln].tx_req_addr;
                app_data[0] = RC_FLU;
                cio_cqueue(cid, CIO_STAT, PPQESIZE, &centry, app_data);
                cio[cid].intr = TRUE;
            }
        }
    }

    tmxr_poll_tx(&ports_desc);

    if (tx) {
        tmxr_activate_after(uptr, wait);
    }

    return SCPE_OK;
}