PDP11, VAX: Support multiplexer input speeds greater than 9600bps for console, DZ, VH, DL and DC devices

Each of the speeds greater than 9600bps deliver a character in less than
1ms.  Computing inter-character delays in microseconds therefore can't
be precise enough to be well behaved.  Measuring the inter-character
delays in instructions (scalled by the calibrated clock) gets us the needed
precision.
This commit is contained in:
Mark Pizzolato 2015-11-25 04:25:21 -08:00
parent 44ef17f971
commit 62e36241a4
6 changed files with 14 additions and 11 deletions

View file

@ -229,7 +229,7 @@ uint16 dz_tcr[MAX_DZ_MUXES] = { 0 }; /* xmit control */
uint16 dz_msr[MAX_DZ_MUXES] = { 0 }; /* modem status */ uint16 dz_msr[MAX_DZ_MUXES] = { 0 }; /* modem status */
uint16 dz_tdr[MAX_DZ_MUXES] = { 0 }; /* xmit data */ uint16 dz_tdr[MAX_DZ_MUXES] = { 0 }; /* xmit data */
uint8 dz_sae[MAX_DZ_MUXES] = { 0 }; /* silo alarm enabled */ uint8 dz_sae[MAX_DZ_MUXES] = { 0 }; /* silo alarm enabled */
uint32 dz_wait = SERIAL_IN_WAIT; /* input polling adjustment */ uint32 dz_wait = 1; /* input polling adjustment */
uint32 dz_rxi = 0; /* rcv interrupts */ uint32 dz_rxi = 0; /* rcv interrupts */
uint32 dz_txi = 0; /* xmt interrupts */ uint32 dz_txi = 0; /* xmt interrupts */
int32 dz_mctl = 0; /* modem ctrl enabled */ int32 dz_mctl = 0; /* modem ctrl enabled */

View file

@ -283,7 +283,7 @@ static uint32 vh_rxi = 0; /* rcv interrupts */
static uint32 vh_txi = 0; /* xmt interrupts */ static uint32 vh_txi = 0; /* xmt interrupts */
static uint32 vh_crit = 0;/* FIFO.CRIT */ static uint32 vh_crit = 0;/* FIFO.CRIT */
static uint32 vh_wait = SERIAL_IN_WAIT; /* input polling adjustment */ static uint32 vh_wait = 0; /* input polling adjustment */
static const int32 bitmask[4] = { 037, 077, 0177, 0377 }; static const int32 bitmask[4] = { 037, 077, 0177, 0377 };

View file

@ -1923,7 +1923,7 @@ if (sim_send_poll_data (&sim_con_send, &c)) /* injected input ch
return c; return c;
if (!sim_rem_master_mode) { if (!sim_rem_master_mode) {
if ((sim_con_ldsc.rxbps) && /* rate limiting && */ if ((sim_con_ldsc.rxbps) && /* rate limiting && */
((sim_con_ldsc.rxlasttime + (sim_con_ldsc.rxdelta + 500)/1000) > sim_os_msec ())) /* too soon? */ (sim_con_ldsc.rxnexttime > sim_gtime ())) /* too soon? */
return SCPE_OK; /* not yet */ return SCPE_OK; /* not yet */
c = sim_os_poll_kbd (); /* get character */ c = sim_os_poll_kbd (); /* get character */
if (c == SCPE_STOP) { /* ^E */ if (c == SCPE_STOP) { /* ^E */
@ -1933,7 +1933,8 @@ if (!sim_rem_master_mode) {
if ((sim_con_tmxr.master == 0) && /* not Telnet? */ if ((sim_con_tmxr.master == 0) && /* not Telnet? */
(sim_con_ldsc.serport == 0)) { /* and not serial? */ (sim_con_ldsc.serport == 0)) { /* and not serial? */
if (c && sim_con_ldsc.rxbps) /* got something && rate limiting? */ if (c && sim_con_ldsc.rxbps) /* got something && rate limiting? */
sim_con_ldsc.rxlasttime = sim_os_msec (); /* save last input time */ sim_con_ldsc.rxnexttime = /* compute next input time */
sim_gtime () + ((sim_con_ldsc.rxdelta * sim_timer_inst_per_sec ())/1000000.0);
return c; /* in-window */ return c; /* in-window */
} }
if (!sim_con_ldsc.conn) { /* no telnet or serial connection? */ if (!sim_con_ldsc.conn) { /* no telnet or serial connection? */

View file

@ -1558,6 +1558,8 @@ pthread_mutex_unlock (&sim_timer_lock);
pthread_cond_signal (&sim_timer_wake); /* wake the timer thread to deal with it */ pthread_cond_signal (&sim_timer_wake); /* wake the timer thread to deal with it */
return SCPE_OK; return SCPE_OK;
#else #else
sim_debug (DBG_TIM, &sim_timer_dev, "sim_timer_activate_after() - queue addition %s at %d (%d usecs)\n",
sim_uname(uptr), inst_delay, usec_delay);
return _sim_activate (uptr, inst_delay); /* queue it now */ return _sim_activate (uptr, inst_delay); /* queue it now */
#endif #endif
} }

View file

@ -1547,8 +1547,8 @@ uint32 tmp;
tmxr_debug_trace_line (lp, "tmxr_getc_ln()"); tmxr_debug_trace_line (lp, "tmxr_getc_ln()");
if ((lp->conn && lp->rcve) && /* conn & enb & */ if ((lp->conn && lp->rcve) && /* conn & enb & */
((!lp->rxbps) || /* (!rate limited | enough time passed)? */ ((!lp->rxbps) || /* (!rate limited || enough time passed)? */
((lp->rxlasttime + (lp->rxdelta+500)/1000) <= sim_os_msec ()))) { (sim_gtime () >= lp->rxnexttime))) {
if (!sim_send_poll_data (&lp->send, &val)) { /* injected input characters available? */ if (!sim_send_poll_data (&lp->send, &val)) { /* injected input characters available? */
j = lp->rxbpi - lp->rxbpr; /* # input chrs */ j = lp->rxbpi - lp->rxbpr; /* # input chrs */
if (j) { /* any? */ if (j) { /* any? */
@ -1565,7 +1565,7 @@ if ((lp->conn && lp->rcve) && /* conn & enb & */
if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */ if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */
lp->rxbpi = lp->rxbpr = 0; lp->rxbpi = lp->rxbpr = 0;
if (val && lp->rxbps) if (val && lp->rxbps)
lp->rxlasttime = sim_os_msec (); lp->rxnexttime = sim_gtime () + ((lp->rxdelta * sim_timer_inst_per_sec ())/1000000.0);
tmxr_debug_return(lp, val); tmxr_debug_return(lp, val);
return val; return val;
} }
@ -1886,7 +1886,7 @@ return;
int32 tmxr_rqln (TMLN *lp) int32 tmxr_rqln (TMLN *lp)
{ {
if ((lp->rxbps && (lp->rxlasttime + (lp->rxdelta + 500)/1000) > sim_os_msec ())) if ((lp->rxbps) && (sim_gtime () < lp->rxnexttime)) /* rate limiting and too soon */
return 0; return 0;
return (lp->rxbpi - lp->rxbpr + ((lp->rxbpi < lp->rxbpr)? lp->rxbsz: 0)); return (lp->rxbpi - lp->rxbpr + ((lp->rxbpi < lp->rxbpr)? lp->rxbsz: 0));
} }
@ -2215,7 +2215,7 @@ if (_tmln_speed_delta (speed) < 0)
return SCPE_ARG; return SCPE_ARG;
lp->rxbps = atoi (speed); lp->rxbps = atoi (speed);
lp->rxdelta = _tmln_speed_delta (speed); lp->rxdelta = _tmln_speed_delta (speed);
lp->rxlasttime = 0; lp->rxnexttime = 0;
uptr = lp->uptr; uptr = lp->uptr;
if ((!uptr) && (lp->mp)) if ((!uptr) && (lp->mp))
uptr = lp->mp->uptr; uptr = lp->mp->uptr;

View file

@ -167,8 +167,8 @@ struct tmln {
uint32 rxpbsize; /* rcv packet buffer size */ uint32 rxpbsize; /* rcv packet buffer size */
uint32 rxpboffset; /* rcv packet buffer offset */ uint32 rxpboffset; /* rcv packet buffer offset */
uint32 rxbps; /* rcv bps speed (0 - unlimited) */ uint32 rxbps; /* rcv bps speed (0 - unlimited) */
uint32 rxdelta; /* rcv inter character min time (ms) */ uint32 rxdelta; /* rcv inter character min time (usecs) */
uint32 rxlasttime; /* time last received character was read */ double rxnexttime; /* min time for next receive character */
uint8 *txpb; /* xmt packet buffer */ uint8 *txpb; /* xmt packet buffer */
uint32 txpbsize; /* xmt packet buffer size */ uint32 txpbsize; /* xmt packet buffer size */
uint32 txppsize; /* xmt packet packet size */ uint32 txppsize; /* xmt packet packet size */