From 62e36241a4a24ca408e7f0a91e9bd4250b49bfb9 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 25 Nov 2015 04:25:21 -0800 Subject: [PATCH] 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. --- PDP11/pdp11_dz.c | 2 +- PDP11/pdp11_vh.c | 2 +- sim_console.c | 5 +++-- sim_timer.c | 2 ++ sim_tmxr.c | 10 +++++----- sim_tmxr.h | 4 ++-- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/PDP11/pdp11_dz.c b/PDP11/pdp11_dz.c index b1175f58..3a4bb65d 100644 --- a/PDP11/pdp11_dz.c +++ b/PDP11/pdp11_dz.c @@ -229,7 +229,7 @@ uint16 dz_tcr[MAX_DZ_MUXES] = { 0 }; /* xmit control */ uint16 dz_msr[MAX_DZ_MUXES] = { 0 }; /* modem status */ uint16 dz_tdr[MAX_DZ_MUXES] = { 0 }; /* xmit data */ 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_txi = 0; /* xmt interrupts */ int32 dz_mctl = 0; /* modem ctrl enabled */ diff --git a/PDP11/pdp11_vh.c b/PDP11/pdp11_vh.c index ee6262b7..e888c81d 100644 --- a/PDP11/pdp11_vh.c +++ b/PDP11/pdp11_vh.c @@ -283,7 +283,7 @@ static uint32 vh_rxi = 0; /* rcv interrupts */ static uint32 vh_txi = 0; /* xmt interrupts */ 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 }; diff --git a/sim_console.c b/sim_console.c index bcba790f..9230914f 100644 --- a/sim_console.c +++ b/sim_console.c @@ -1923,7 +1923,7 @@ if (sim_send_poll_data (&sim_con_send, &c)) /* injected input ch return c; if (!sim_rem_master_mode) { 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 */ c = sim_os_poll_kbd (); /* get character */ if (c == SCPE_STOP) { /* ^E */ @@ -1933,7 +1933,8 @@ if (!sim_rem_master_mode) { if ((sim_con_tmxr.master == 0) && /* not Telnet? */ (sim_con_ldsc.serport == 0)) { /* and not serial? */ 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 */ } if (!sim_con_ldsc.conn) { /* no telnet or serial connection? */ diff --git a/sim_timer.c b/sim_timer.c index 60b687d1..d4e6923a 100644 --- a/sim_timer.c +++ b/sim_timer.c @@ -1558,6 +1558,8 @@ pthread_mutex_unlock (&sim_timer_lock); pthread_cond_signal (&sim_timer_wake); /* wake the timer thread to deal with it */ return SCPE_OK; #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 */ #endif } diff --git a/sim_tmxr.c b/sim_tmxr.c index 578c527a..8b809845 100644 --- a/sim_tmxr.c +++ b/sim_tmxr.c @@ -1547,8 +1547,8 @@ uint32 tmp; tmxr_debug_trace_line (lp, "tmxr_getc_ln()"); if ((lp->conn && lp->rcve) && /* conn & enb & */ - ((!lp->rxbps) || /* (!rate limited | enough time passed)? */ - ((lp->rxlasttime + (lp->rxdelta+500)/1000) <= sim_os_msec ()))) { + ((!lp->rxbps) || /* (!rate limited || enough time passed)? */ + (sim_gtime () >= lp->rxnexttime))) { if (!sim_send_poll_data (&lp->send, &val)) { /* injected input characters available? */ j = lp->rxbpi - lp->rxbpr; /* # input chrs */ if (j) { /* any? */ @@ -1565,7 +1565,7 @@ if ((lp->conn && lp->rcve) && /* conn & enb & */ if (lp->rxbpi == lp->rxbpr) /* empty? zero ptrs */ lp->rxbpi = lp->rxbpr = 0; 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); return val; } @@ -1886,7 +1886,7 @@ return; 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 (lp->rxbpi - lp->rxbpr + ((lp->rxbpi < lp->rxbpr)? lp->rxbsz: 0)); } @@ -2215,7 +2215,7 @@ if (_tmln_speed_delta (speed) < 0) return SCPE_ARG; lp->rxbps = atoi (speed); lp->rxdelta = _tmln_speed_delta (speed); -lp->rxlasttime = 0; +lp->rxnexttime = 0; uptr = lp->uptr; if ((!uptr) && (lp->mp)) uptr = lp->mp->uptr; diff --git a/sim_tmxr.h b/sim_tmxr.h index 8d24994c..9385e304 100644 --- a/sim_tmxr.h +++ b/sim_tmxr.h @@ -167,8 +167,8 @@ struct tmln { uint32 rxpbsize; /* rcv packet buffer size */ uint32 rxpboffset; /* rcv packet buffer offset */ uint32 rxbps; /* rcv bps speed (0 - unlimited) */ - uint32 rxdelta; /* rcv inter character min time (ms) */ - uint32 rxlasttime; /* time last received character was read */ + uint32 rxdelta; /* rcv inter character min time (usecs) */ + double rxnexttime; /* min time for next receive character */ uint8 *txpb; /* xmt packet buffer */ uint32 txpbsize; /* xmt packet buffer size */ uint32 txppsize; /* xmt packet packet size */