BESM6: Improved TTY I/O (responsiveness, variable rate, turbo/authentic).

This commit is contained in:
Leo Broukhis 2017-01-15 23:58:38 -08:00
parent d8dbc7e6b5
commit 7d3ede9492
2 changed files with 67 additions and 16 deletions

View file

@ -1799,13 +1799,12 @@ t_stat fast_clk (UNIT * this)
GRP |= GRP_TIMER; GRP |= GRP_TIMER;
if ((counter & 15) == 0) { if ((counter & 3) == 0) {
/* /*
* The OS used the (undocumented, later addition) * The OS used the (undocumented, later addition)
* slow clock interrupt to initiate servicing * slow clock interrupt to initiate servicing
* terminal I/O. Its frequency was reportedly 16 Hz; * terminal I/O. Its frequency was reportedly about 50-60 Hz;
* 64 ms is a good enough approximation. It can be sped up * 16 ms is a good enough approximation.
* for faster console response (16 ms might be a good choice).
*/ */
GRP |= GRP_SLOW_CLK; GRP |= GRP_SLOW_CLK;
} }

View file

@ -75,6 +75,12 @@ int tty_typed [TTY_MAX+1], tty_instate [TTY_MAX+1];
time_t tty_last_time [TTY_MAX+1]; time_t tty_last_time [TTY_MAX+1];
int tty_idle_count [TTY_MAX+1]; int tty_idle_count [TTY_MAX+1];
/* The serial interrupt generator frequency, common for all VT lines */
int tty_rate = 300;
/* Interrupt generator mode: 1 - model time, 0 - wallclock time */
int tty_turbo = 1;
uint32 vt_sending, vt_receiving; uint32 vt_sending, vt_receiving;
uint32 tt_sending, tt_receiving; uint32 tt_sending, tt_receiving;
@ -95,7 +101,6 @@ void tt_print();
void consul_receive(); void consul_receive();
t_stat vt_clk(UNIT *); t_stat vt_clk(UNIT *);
extern const char *get_sim_sw (const char *cptr); extern const char *get_sim_sw (const char *cptr);
extern int32 tmr_poll; /* calibrated clock timer poll */
int attached_console; int attached_console;
@ -177,11 +182,11 @@ t_stat tty_reset (DEVICE *dptr)
* and the device is always ready. */ * and the device is always ready. */
/* Forcing a ready interrupt. */ /* Forcing a ready interrupt. */
PRP |= CONS_CAN_PRINT[0] | CONS_CAN_PRINT[1]; PRP |= CONS_CAN_PRINT[0] | CONS_CAN_PRINT[1];
//return sim_activate_after (tty_unit, 1000*MSEC/300); // Schedule the very first TTY interrupt to match the next clock interrupt.
return sim_clock_coschedule (tty_unit, tmr_poll); return sim_clock_coschedule (tty_unit, 0);
} }
/* Bit 19 of GRP, should be 300 Hz */ /* Bit 19 of GRP, should be <tty_rate> Hz */
t_stat vt_clk (UNIT * this) t_stat vt_clk (UNIT * this)
{ {
int num; int num;
@ -251,13 +256,17 @@ t_stat vt_clk (UNIT * this)
* e.g. until the next 250 Hz wallclock interrupt, but making sure * e.g. until the next 250 Hz wallclock interrupt, but making sure
* that the model time interval between GRP_SERIAL interrupts * that the model time interval between GRP_SERIAL interrupts
* is never less than expected. * is never less than expected.
* Using sim_activate_after() would be more straightforward (no need for a check
* as the host is faster than the target), but likely less efficient for idling.
*/ */
if (vt_is_idle() && sim_activate_time(clocks) > 1000*MSEC/300) if (vt_is_idle()) {
return sim_clock_coschedule (this, tmr_poll); /* When idle, slow down the TTY interrupts to match the clock interrupts. */
else return sim_clock_coschedule (this, 0);
return sim_activate(this, 1000*MSEC/300); } else if (tty_turbo) {
/* In "turbo" mode, the TTY works at the model speed */
return sim_activate(this, 1000*MSEC/tty_rate);
} else {
/* In "non-turbo" mode, the TTY interrupts imitate the true feel of the speed */
return sim_activate_after(this, 1000*MSEC/tty_rate);
}
} }
t_stat tty_setmode (UNIT *u, int32 val, CONST char *cptr, void *desc) t_stat tty_setmode (UNIT *u, int32 val, CONST char *cptr, void *desc)
@ -369,6 +378,43 @@ t_stat tty_detach (UNIT *u)
return tmxr_detach (&tty_desc, &tty_unit[0]); return tmxr_detach (&tty_desc, &tty_unit[0]);
} }
t_stat tty_showrate (FILE *f, UNIT *up, int32 v, CONST void *dp) {
fprintf(f, "%d Baud", tty_rate);
return SCPE_OK;
}
t_stat tty_showturbo (FILE *f, UNIT *up, int32 v, CONST void *dp) {
fprintf(f, tty_turbo ? "Turbo" : "Authentic feel");
return SCPE_OK;
}
t_stat tty_setrate (UNIT *up, int32 v, CONST char *cp, void *dp) {
int rate;
if (cp)
rate = atoi(cp);
else
return SCPE_MISVAL;
if (rate <= 0 || rate > 19200 || rate % 300 != 0)
return SCPE_ARG;
rate /= 300;
if ((rate-1) & rate)
return SCPE_ARG;
tty_rate = rate * 300;
return SCPE_OK;
}
t_stat tty_setturbo (UNIT *up, int32 v, CONST char *cp, void *dp) {
if (!cp)
return SCPE_MISVAL;
if (!strcasecmp(cp, "ON"))
tty_turbo = 1;
else if (!strcasecmp(cp, "OFF"))
tty_turbo = 0;
else
return SCPE_ARG;
return SCPE_OK;
}
/* /*
* TTY control: * TTY control:
* set ttyN unicode - selecting UTF-8 encoding * set ttyN unicode - selecting UTF-8 encoding
@ -381,6 +427,8 @@ t_stat tty_detach (UNIT *u)
* set ttyN destrbs - destructive (erasing) backspace * set ttyN destrbs - destructive (erasing) backspace
* set ttyN authbs - authentic backspace (cursor left) * set ttyN authbs - authentic backspace (cursor left)
* set tty disconnect=N - forceful termination of a telnet connection * set tty disconnect=N - forceful termination of a telnet connection
* set tty rate=N - I/O rate in Hz
* set tty turbo={ON,OFF} - TTY interrupts use model time (on) or wallclock (0ff)
* show tty - showing modes and types * show tty - showing modes and types
* show tty connections - showing IP-addresses and connection times * show tty connections - showing IP-addresses and connection times
* show tty statistics - showing TX/RX byte counts * show tty statistics - showing TX/RX byte counts
@ -404,8 +452,12 @@ MTAB tty_mod[] = {
"DESTRBS" }, "DESTRBS" },
{ TTY_BSPACE_MASK, TTY_AUTHENTIC_BSPACE, NULL, { TTY_BSPACE_MASK, TTY_AUTHENTIC_BSPACE, NULL,
"AUTHBS" }, "AUTHBS" },
{ MTAB_XTD | MTAB_VDV, 1, NULL, { MTAB_XTD | MTAB_VDV | MTAB_VALR, 1, NULL,
"DISCONNECT", &tmxr_dscln, NULL, (void*) &tty_desc }, "DISCONNECT", &tmxr_dscln, NULL, (void*) &tty_desc, "terminates telnet connection" },
{ MTAB_XTD | MTAB_VDV | MTAB_VALR, 1, "RATE",
"RATE", &tty_setrate, &tty_showrate, NULL, "{300,600,1200,2400,4800,9600,19200}" },
{ MTAB_XTD | MTAB_VDV | MTAB_VALR, 1, "TURBO",
"TURBO", &tty_setturbo, &tty_showturbo, NULL, "{ON, OFF}"},
{ UNIT_ATT, UNIT_ATT, "connections", { UNIT_ATT, UNIT_ATT, "connections",
NULL, NULL, &tmxr_show_summ, (void*) &tty_desc }, NULL, NULL, &tmxr_show_summ, (void*) &tty_desc },
{ MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS", { MTAB_XTD | MTAB_VDV | MTAB_NMO, 1, "CONNECTIONS",