I1620: Provide consistent rate limited I/O for TTY, PTR & PTP

- Default CPS is 50
- Add SET {CPU}  CPS=nnn and SHOW {CPU} CPS commands.
   Individual device specific rates are changeable and visible as CPS register
   in each device.
This commit is contained in:
Mark Pizzolato 2017-06-13 09:05:03 -07:00
parent 17cc00f33e
commit 605ede8c7b
4 changed files with 54 additions and 13 deletions

View file

@ -174,6 +174,8 @@ t_stat cpu_set_table (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cpu_set_release (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cpu_set_hist (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cpu_show_hist (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
t_stat cpu_set_cps (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
t_stat cpu_show_cps (FILE *st, UNIT *uptr, int32 val, CONST void *desc);
int32 get_2d (uint32 ad);
t_stat get_addr (uint32 alast, int32 lnt, t_bool indexok, uint32 *addr);
@ -285,6 +287,8 @@ MTAB cpu_mod[] = {
&cpu_set_hist, &cpu_show_hist },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, NULL, "RELEASE",
&cpu_set_release, NULL },
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_VALR, 0, "CPS", "CPS",
&cpu_set_cps, &cpu_show_cps },
{ 0 }
};
@ -2166,7 +2170,7 @@ cpuio_inp = 1;
cpuio_opc = op;
cpuio_cnt = 0;
if (uptr != NULL)
sim_activate_abs (uptr, uptr->wait);
sim_activate_after_abs (uptr, 1000000/uptr->wait);
return SCPE_OK;
}
@ -2236,6 +2240,41 @@ else sim_printf ("PC unchanged\n");
return SCPE_OK;
}
/* Character rate */
t_stat cpu_set_cps (UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
uint32 i, cps;
DEVICE *dptr;
t_stat r;
if (cptr == NULL)
return SCPE_ARG;
cps = get_uint (cptr, 10, 1000000, &r);
if (r != SCPE_OK)
return SCPE_ARG;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
if ((dptr->flags & DEV_DEFIO) != 0)
dptr->units->wait = cps;
}
return SCPE_OK;
}
/* Show CPS */
t_stat cpu_show_cps (FILE *st, UNIT *uptr, int32 val, CONST void *desc)
{
uint32 i;
DEVICE *dptr;
for (i = 0; (dptr = sim_devices[i]) != NULL; i++) {
if ((dptr->flags & DEV_DEFIO) != 0)
fprintf (st, "%s CPS: %d\n", dptr->name, dptr->units->wait);
}
return SCPE_OK;
}
/* Memory examine */
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)

View file

@ -240,6 +240,8 @@ enum opcodes {
#define DEV_DEFIO (1 << (DEV_V_UF + 0))
#define DEFIO_CPS 50 /* Default Characters per Second */
/* Function declarations */
t_stat cpuio_set_inp (uint32 op, UNIT *uptr);

View file

@ -74,13 +74,13 @@ t_stat ptp_num (void);
*/
UNIT ptr_unit = {
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), SERIAL_IN_WAIT
UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), DEFIO_CPS
};
REG ptr_reg[] = {
{ FLDATA (BIN, ptr_mode, 0) },
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT },
{ DRDATA (CPS, ptr_unit.wait, 24), PV_LEFT },
{ NULL }
};
@ -100,13 +100,13 @@ DEVICE ptr_dev = {
*/
UNIT ptp_unit = {
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT
UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), DEFIO_CPS
};
REG ptp_reg[] = {
{ FLDATA (BIN, ptp_mode, 0) },
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
{ DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT },
{ DRDATA (CPS, ptp_unit.wait, 24), PV_LEFT },
{ NULL }
};
@ -268,7 +268,7 @@ if (cpuio_cnt >= MEMSIZE) { /* over the limit? */
cpuio_clr_inp (uptr); /* done */
return STOP_RWRAP;
}
sim_activate (uptr, uptr->wait); /* sched another xfer */
sim_activate_after (uptr, 1000000/uptr->wait); /* sched another xfer */
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
return SCPE_UNATT;
@ -425,7 +425,7 @@ if ((cpuio_opc != OP_DN) && (cpuio_cnt >= MEMSIZE)) { /* wrap, ~dump? */
cpuio_clr_inp (uptr); /* done */
return STOP_RWRAP;
}
sim_activate (uptr, uptr->wait); /* sched another xfer */
sim_activate_after (uptr, 1000000/uptr->wait); /* sched another xfer */
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
return SCPE_UNATT;

View file

@ -47,8 +47,8 @@
#define TTO_COLMAX 80
#define UF_V_1DIG (UNIT_V_UF)
#define UF_1DIG (1 << UF_V_1DIG)
#define UTTI 0
#define UTTO 1
#define UTTI 1
#define UTTO 0
uint32 tti_unlock = 0; /* expecting input */
uint32 tti_flag = 0; /* flag typed */
@ -90,8 +90,8 @@ t_stat tty_set_12digit (UNIT *uptr, int32 val, CONST char *cptr, void *desc);
*/
UNIT tty_unit[] = {
{ UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT },
{ UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT }
{ UDATA (&tto_svc, 0, 0), DEFIO_CPS },
{ UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT }
};
REG tty_reg[] = {
@ -99,7 +99,7 @@ REG tty_reg[] = {
{ FLDATA (FLAG, tti_flag, 0), REG_HRO },
{ DRDATA (COL, tto_col, 7) },
{ DRDATA (KTIME, tty_unit[UTTI].wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (TTIME, tty_unit[UTTO].wait, 24), REG_NZ + PV_LEFT },
{ DRDATA (CPS, tty_unit[UTTO].wait, 24), REG_NZ + PV_LEFT },
{ NULL }
};
@ -389,7 +389,7 @@ if ((cpuio_opc != OP_DN) && (cpuio_cnt >= MEMSIZE)) { /* wrap, ~dump? */
cpuio_clr_inp (uptr); /* done */
return STOP_RWRAP;
}
sim_activate (uptr, uptr->wait); /* sched another xfer */
sim_activate_after (uptr, 1000000/uptr->wait); /* sched another xfer */
switch (cpuio_opc) { /* decode op */