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:
parent
17cc00f33e
commit
605ede8c7b
4 changed files with 54 additions and 13 deletions
|
@ -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_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_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_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);
|
int32 get_2d (uint32 ad);
|
||||||
t_stat get_addr (uint32 alast, int32 lnt, t_bool indexok, uint32 *addr);
|
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 },
|
&cpu_set_hist, &cpu_show_hist },
|
||||||
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, NULL, "RELEASE",
|
{ MTAB_XTD|MTAB_VDV|MTAB_NMO, 0, NULL, "RELEASE",
|
||||||
&cpu_set_release, NULL },
|
&cpu_set_release, NULL },
|
||||||
|
{ MTAB_XTD|MTAB_VDV|MTAB_NMO|MTAB_VALR, 0, "CPS", "CPS",
|
||||||
|
&cpu_set_cps, &cpu_show_cps },
|
||||||
{ 0 }
|
{ 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2166,7 +2170,7 @@ cpuio_inp = 1;
|
||||||
cpuio_opc = op;
|
cpuio_opc = op;
|
||||||
cpuio_cnt = 0;
|
cpuio_cnt = 0;
|
||||||
if (uptr != NULL)
|
if (uptr != NULL)
|
||||||
sim_activate_abs (uptr, uptr->wait);
|
sim_activate_after_abs (uptr, 1000000/uptr->wait);
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2236,6 +2240,41 @@ else sim_printf ("PC unchanged\n");
|
||||||
return SCPE_OK;
|
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 */
|
/* Memory examine */
|
||||||
|
|
||||||
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
t_stat cpu_ex (t_value *vptr, t_addr addr, UNIT *uptr, int32 sw)
|
||||||
|
|
|
@ -240,6 +240,8 @@ enum opcodes {
|
||||||
|
|
||||||
#define DEV_DEFIO (1 << (DEV_V_UF + 0))
|
#define DEV_DEFIO (1 << (DEV_V_UF + 0))
|
||||||
|
|
||||||
|
#define DEFIO_CPS 50 /* Default Characters per Second */
|
||||||
|
|
||||||
/* Function declarations */
|
/* Function declarations */
|
||||||
|
|
||||||
t_stat cpuio_set_inp (uint32 op, UNIT *uptr);
|
t_stat cpuio_set_inp (uint32 op, UNIT *uptr);
|
||||||
|
|
|
@ -74,13 +74,13 @@ t_stat ptp_num (void);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT ptr_unit = {
|
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[] = {
|
REG ptr_reg[] = {
|
||||||
{ FLDATA (BIN, ptr_mode, 0) },
|
{ FLDATA (BIN, ptr_mode, 0) },
|
||||||
{ DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT },
|
{ 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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -100,13 +100,13 @@ DEVICE ptr_dev = {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
UNIT ptp_unit = {
|
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[] = {
|
REG ptp_reg[] = {
|
||||||
{ FLDATA (BIN, ptp_mode, 0) },
|
{ FLDATA (BIN, ptp_mode, 0) },
|
||||||
{ DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT },
|
{ 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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -268,7 +268,7 @@ if (cpuio_cnt >= MEMSIZE) { /* over the limit? */
|
||||||
cpuio_clr_inp (uptr); /* done */
|
cpuio_clr_inp (uptr); /* done */
|
||||||
return STOP_RWRAP;
|
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? */
|
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
return SCPE_UNATT;
|
return SCPE_UNATT;
|
||||||
|
|
||||||
|
@ -425,7 +425,7 @@ if ((cpuio_opc != OP_DN) && (cpuio_cnt >= MEMSIZE)) { /* wrap, ~dump? */
|
||||||
cpuio_clr_inp (uptr); /* done */
|
cpuio_clr_inp (uptr); /* done */
|
||||||
return STOP_RWRAP;
|
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? */
|
if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */
|
||||||
return SCPE_UNATT;
|
return SCPE_UNATT;
|
||||||
|
|
||||||
|
|
|
@ -47,8 +47,8 @@
|
||||||
#define TTO_COLMAX 80
|
#define TTO_COLMAX 80
|
||||||
#define UF_V_1DIG (UNIT_V_UF)
|
#define UF_V_1DIG (UNIT_V_UF)
|
||||||
#define UF_1DIG (1 << UF_V_1DIG)
|
#define UF_1DIG (1 << UF_V_1DIG)
|
||||||
#define UTTI 0
|
#define UTTI 1
|
||||||
#define UTTO 1
|
#define UTTO 0
|
||||||
|
|
||||||
uint32 tti_unlock = 0; /* expecting input */
|
uint32 tti_unlock = 0; /* expecting input */
|
||||||
uint32 tti_flag = 0; /* flag typed */
|
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[] = {
|
UNIT tty_unit[] = {
|
||||||
{ UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT },
|
{ UDATA (&tto_svc, 0, 0), DEFIO_CPS },
|
||||||
{ UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT }
|
{ UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT }
|
||||||
};
|
};
|
||||||
|
|
||||||
REG tty_reg[] = {
|
REG tty_reg[] = {
|
||||||
|
@ -99,7 +99,7 @@ REG tty_reg[] = {
|
||||||
{ FLDATA (FLAG, tti_flag, 0), REG_HRO },
|
{ FLDATA (FLAG, tti_flag, 0), REG_HRO },
|
||||||
{ DRDATA (COL, tto_col, 7) },
|
{ DRDATA (COL, tto_col, 7) },
|
||||||
{ DRDATA (KTIME, tty_unit[UTTI].wait, 24), REG_NZ + PV_LEFT },
|
{ 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 }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -389,7 +389,7 @@ if ((cpuio_opc != OP_DN) && (cpuio_cnt >= MEMSIZE)) { /* wrap, ~dump? */
|
||||||
cpuio_clr_inp (uptr); /* done */
|
cpuio_clr_inp (uptr); /* done */
|
||||||
return STOP_RWRAP;
|
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 */
|
switch (cpuio_opc) { /* decode op */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue