TMXR: Support input speed limits with a multiplier factor
Many simulators run instructions one or more orders of magnitude faster than the original systems did. Limiting simulated serial port input speeds to legacy bits per second values presents the arriving data much slower than the original systems ever saw it. Given the processing capacity of the simulated systems and the fact that the software and device interfaces only know how to deal with the legacy speed values there is a need to provide a way to allow input to arrive faster. This problem is solved by providing a speed factor as a part of a speed specification. For example a speed can be specified as "speed*factor" or "9600*10".
This commit is contained in:
parent
a18a4f42b9
commit
f322f4b044
3 changed files with 51 additions and 14 deletions
|
@ -1333,8 +1333,12 @@ return tmxr_set_line_speed (&sim_con_ldsc, cptr);
|
|||
|
||||
t_stat sim_show_cons_speed (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, char *cptr)
|
||||
{
|
||||
if (sim_con_ldsc.rxbps)
|
||||
fprintf (st, "Speed = %dbps\n", sim_con_ldsc.rxbps);
|
||||
if (sim_con_ldsc.rxbps) {
|
||||
fprintf (st, "Speed = %d", sim_con_ldsc.rxbps);
|
||||
if (sim_con_ldsc.rxbpsfactor != TMXR_RX_BPS_UNIT_SCALE)
|
||||
fprintf (st, "*%.0f", sim_con_ldsc.rxbpsfactor/TMXR_RX_BPS_UNIT_SCALE);
|
||||
fprintf (st, " bps\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -1923,7 +1927,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.rxnexttime > sim_gtime ())) /* too soon? */
|
||||
(sim_gtime () < sim_con_ldsc.rxnexttime)) /* too soon? */
|
||||
return SCPE_OK; /* not yet */
|
||||
c = sim_os_poll_kbd (); /* get character */
|
||||
if (c == SCPE_STOP) { /* ^E */
|
||||
|
@ -1934,7 +1938,7 @@ if (!sim_rem_master_mode) {
|
|||
(sim_con_ldsc.serport == 0)) { /* and not serial? */
|
||||
if (c && sim_con_ldsc.rxbps) /* got something && rate limiting? */
|
||||
sim_con_ldsc.rxnexttime = /* compute next input time */
|
||||
sim_gtime () + ((sim_con_ldsc.rxdelta * sim_timer_inst_per_sec ())/1000000.0);
|
||||
sim_gtime () + ((sim_con_ldsc.rxdelta * sim_timer_inst_per_sec ())/sim_con_ldsc.rxbpsfactor);
|
||||
return c; /* in-window */
|
||||
}
|
||||
if (!sim_con_ldsc.conn) { /* no telnet or serial connection? */
|
||||
|
@ -2196,6 +2200,7 @@ return NULL;
|
|||
|
||||
t_stat sim_ttinit (void)
|
||||
{
|
||||
sim_con_tmxr.ldsc->mp = &sim_con_tmxr;
|
||||
sim_register_internal_device (&sim_con_telnet);
|
||||
tmxr_startup ();
|
||||
return sim_os_ttinit ();
|
||||
|
|
50
sim_tmxr.c
50
sim_tmxr.c
|
@ -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->rxnexttime = sim_gtime () + ((lp->rxdelta * sim_timer_inst_per_sec ())/1000000.0);
|
||||
lp->rxnexttime = sim_gtime () + ((lp->rxdelta * sim_timer_inst_per_sec ())/lp->rxbpsfactor);
|
||||
tmxr_debug_return(lp, val);
|
||||
return val;
|
||||
}
|
||||
|
@ -2187,10 +2187,10 @@ struct {
|
|||
{"115200", TMLN_SPD_115200_BPS},
|
||||
{"0", 0}}; /* End of List, last valid value */
|
||||
int nspeed;
|
||||
char speed[20];
|
||||
char speed[24];
|
||||
|
||||
nspeed = (uint32)strtotv (cptr, &cptr, 10);
|
||||
if ((*cptr != '\0') && (*cptr != '-'))
|
||||
if ((*cptr != '\0') && (*cptr != '-') && (*cptr != '*'))
|
||||
return -1;
|
||||
sprintf (speed, "%d", nspeed);
|
||||
|
||||
|
@ -2208,12 +2208,20 @@ return -1;
|
|||
t_stat tmxr_set_line_speed (TMLN *lp, const char *speed)
|
||||
{
|
||||
UNIT *uptr;
|
||||
const char *cptr;
|
||||
t_stat r;
|
||||
|
||||
if (!speed || !*speed)
|
||||
return SCPE_2FARG;
|
||||
if (_tmln_speed_delta (speed) < 0)
|
||||
return SCPE_ARG;
|
||||
lp->rxbps = atoi (speed);
|
||||
lp->rxbps = (uint32)strtotv (speed, &cptr, 10);
|
||||
if (*cptr == '*') {
|
||||
uint32 rxbpsfactor = (uint32) get_uint (cptr+1, 10, 32, &r);
|
||||
if (r != SCPE_OK)
|
||||
return r;
|
||||
lp->rxbpsfactor = TMXR_RX_BPS_UNIT_SCALE * rxbpsfactor;
|
||||
}
|
||||
lp->rxdelta = _tmln_speed_delta (speed);
|
||||
lp->rxnexttime = 0;
|
||||
uptr = lp->uptr;
|
||||
|
@ -2221,6 +2229,8 @@ if ((!uptr) && (lp->mp))
|
|||
uptr = lp->mp->uptr;
|
||||
if (uptr)
|
||||
uptr->wait = lp->rxdelta;
|
||||
if (lp->rxbpsfactor == 0.0)
|
||||
lp->rxbpsfactor = TMXR_RX_BPS_UNIT_SCALE;
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
|
@ -2256,6 +2266,8 @@ for (i = 0; i < mp->lines; i++) { /* initialize lines */
|
|||
lp = mp->ldsc + i;
|
||||
lp->mp = mp; /* set the back pointer */
|
||||
lp->modem_control = mp->modem_control;
|
||||
if (lp->rxbpsfactor == 0.0)
|
||||
lp->rxbpsfactor = TMXR_RX_BPS_UNIT_SCALE;
|
||||
}
|
||||
tmxr_debug_trace (mp, "tmxr_open_master()");
|
||||
while (*tptr) {
|
||||
|
@ -3567,6 +3579,14 @@ else {
|
|||
free (attach);
|
||||
tmxr_show_summ(st, NULL, 0, mp);
|
||||
fprintf(st, ", sessions=%d", mp->sessions);
|
||||
if (mp->lines == 1) {
|
||||
if (mp->ldsc->rxbps) {
|
||||
fprintf(st, ", Speed=%d", mp->ldsc->rxbps);
|
||||
if (mp->ldsc->rxbpsfactor != TMXR_RX_BPS_UNIT_SCALE)
|
||||
fprintf(st, "*%.0f", mp->ldsc->rxbpsfactor/TMXR_RX_BPS_UNIT_SCALE);
|
||||
fprintf(st, " bps");
|
||||
}
|
||||
}
|
||||
fprintf(st, "\n");
|
||||
for (j = 0; j < mp->lines; j++) {
|
||||
lp = mp->ldsc + j;
|
||||
|
@ -3582,13 +3602,14 @@ else {
|
|||
fprintf(st, ", ModemControl=%s", lp->modem_control ? "enabled" : "disabled");
|
||||
if (lp->loopback)
|
||||
fprintf(st, ", Loopback");
|
||||
if (lp->rxbps)
|
||||
fprintf(st, ", Speed=%dbps", lp->rxbps);
|
||||
if (lp->rxbps) {
|
||||
fprintf(st, ", Speed=%d", lp->rxbps);
|
||||
if (lp->rxbpsfactor != TMXR_RX_BPS_UNIT_SCALE)
|
||||
fprintf(st, "*%.0f", lp->rxbpsfactor/TMXR_RX_BPS_UNIT_SCALE);
|
||||
fprintf(st, " bps");
|
||||
}
|
||||
fprintf (st, "\n");
|
||||
}
|
||||
else
|
||||
if (lp->rxbps)
|
||||
fprintf(st, ", Speed=%dbps", lp->rxbps);
|
||||
if ((!lp->sock) && (!lp->connecting) && (!lp->serport) && (!lp->master)) {
|
||||
if (lp->modem_control)
|
||||
tmxr_fconns (st, lp, -1);
|
||||
|
@ -3858,13 +3879,22 @@ fprintf (st, "port as fast as it arrives.\n\n");
|
|||
fprintf (st, "If a simulated multiplexor devices can programmatically set a serial\n");
|
||||
fprintf (st, "port line speed, the programmatically specified speed will take precidence\n");
|
||||
fprintf (st, "over any input speed specified on an attach command.\n");
|
||||
fprintf (st, "Some simulated systems run very much faster than the original system\n");
|
||||
fprintf (st, "which is being simulated. To accomodate this, the speed specified may\n");
|
||||
fprintf (st, "include a factor which will increase the input data delivery rate by\n");
|
||||
fprintf (st, "the specified facctor. A factor is specified with a speed value of the\n");
|
||||
fprintf (st, "form \"speed*factor\". Factor values can range from 1 thru 32.\n");
|
||||
fprintf (st, "Example:\n\n");
|
||||
fprintf (st, " sim> ATTACH %s 1234,SPEED=2400\n", dptr->name);
|
||||
fprintf (st, " sim> ATTACH %s 1234,SPEED=9600*8\n", dptr->name);
|
||||
if (!single_line)
|
||||
fprintf (st, " sim> ATTACH %s Line=2,SPEED=2400\n", dptr->name);
|
||||
fprintf (st, "\n");
|
||||
fprintf (st, "The SPEED parameter only influences the rate at which data is deliverd\n");
|
||||
fprintf (st, "into the simulated multiplexor port. Output data rates are unaffected\n\n");
|
||||
fprintf (st, "into the simulated multiplexor port. Output data rates are unaffected\n");
|
||||
fprintf (st, "If an attach command specifies a speed multiply factor, that value will\n");
|
||||
fprintf (st, "persist independent of any programatic action by the simulated system to\n");
|
||||
fprintf (st, "change the port speed.\n\n");
|
||||
fprintf (st, "An optional serial port configuration string may be present after the port\n");
|
||||
fprintf (st, "name. If present, it must be separated from the port name with a semicolon\n");
|
||||
fprintf (st, "and has this form:\n\n");
|
||||
|
|
|
@ -167,6 +167,8 @@ struct tmln {
|
|||
uint32 rxpbsize; /* rcv packet buffer size */
|
||||
uint32 rxpboffset; /* rcv packet buffer offset */
|
||||
uint32 rxbps; /* rcv bps speed (0 - unlimited) */
|
||||
double rxbpsfactor; /* receive speed factor (scaled to usecs) */
|
||||
#define TMXR_RX_BPS_UNIT_SCALE 1000000.0
|
||||
uint32 rxdelta; /* rcv inter character min time (usecs) */
|
||||
double rxnexttime; /* min time for next receive character */
|
||||
uint8 *txpb; /* xmt packet buffer */
|
||||
|
|
Loading…
Add table
Reference in a new issue