From 605ede8c7b97efe774dc9415ec76c4e7dc6ebe46 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Tue, 13 Jun 2017 09:05:03 -0700 Subject: [PATCH] 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. --- I1620/i1620_cpu.c | 41 ++++++++++++++++++++++++++++++++++++++++- I1620/i1620_defs.h | 2 ++ I1620/i1620_pt.c | 12 ++++++------ I1620/i1620_tty.c | 12 ++++++------ 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index 26e81a26..d047d515 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -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) diff --git a/I1620/i1620_defs.h b/I1620/i1620_defs.h index f1783b01..a0a68995 100644 --- a/I1620/i1620_defs.h +++ b/I1620/i1620_defs.h @@ -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); diff --git a/I1620/i1620_pt.c b/I1620/i1620_pt.c index 4e327614..5043bd75 100644 --- a/I1620/i1620_pt.c +++ b/I1620/i1620_pt.c @@ -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; diff --git a/I1620/i1620_tty.c b/I1620/i1620_tty.c index 3e3762be..02a5d78d 100644 --- a/I1620/i1620_tty.c +++ b/I1620/i1620_tty.c @@ -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 */