From 0c4bf36e1eff63437ef2e84bc80891bd700a47d9 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Wed, 14 Jun 2017 15:44:47 -0700 Subject: [PATCH] I620: Provide optional rate limited I/O for TTY, PTR & ptp Default behavior is to schedule the inter character I/O based on the TIME (PTP, PTR) and TTIME (TTY) register variables. With default values here I/O completes very quickly. A user may influence I/O rate behavior to proceed at a particular character rate per second by using: sim> SET CPU CPS=nnn or equivalently: sim> SET CPS=nnn The resulting I/O completion rate will be independent of host system processor speed and/or any I/O throttling that may be in effect. The above commands set the deferred I/O character completion rate for all devices that do deferred I/O (PTP, PTR and TTY). Each deferred I/O device can have its particular character delivery rates specified with one of these commands: sim> deposit PTP CPS xxx sim> deposit PTR CPS yyy sim> deposit TTY CPS zzz A CPS register value of 0 indicates that the default cycle based delays specified by TIME (PTP & PTR) and TTIME (TTY) registers will control character completion rates. --- I1620/i1620_cpu.c | 2 +- I1620/i1620_defs.h | 4 +++- I1620/i1620_pt.c | 14 ++++++++------ I1620/i1620_tty.c | 7 ++++--- 4 files changed, 16 insertions(+), 11 deletions(-) diff --git a/I1620/i1620_cpu.c b/I1620/i1620_cpu.c index d047d515..75862d21 100644 --- a/I1620/i1620_cpu.c +++ b/I1620/i1620_cpu.c @@ -2170,7 +2170,7 @@ cpuio_inp = 1; cpuio_opc = op; cpuio_cnt = 0; if (uptr != NULL) - sim_activate_after_abs (uptr, 1000000/uptr->wait); + DEFIO_ACTIVATE_ABS (uptr); return SCPE_OK; } diff --git a/I1620/i1620_defs.h b/I1620/i1620_defs.h index a0a68995..d03e2cc1 100644 --- a/I1620/i1620_defs.h +++ b/I1620/i1620_defs.h @@ -240,7 +240,9 @@ enum opcodes { #define DEV_DEFIO (1 << (DEV_V_UF + 0)) -#define DEFIO_CPS 50 /* Default Characters per Second */ +#define DEFIO_CPS u4 /* Default Characters per Second field */ +#define DEFIO_ACTIVATE(uptr) ((uptr)->DEFIO_CPS) ? sim_activate_after (uptr, 1000000/(uptr)->DEFIO_CPS) : sim_activate (uptr, (uptr)->wait) +#define DEFIO_ACTIVATE_ABS(uptr) ((uptr)->DEFIO_CPS) ? sim_activate_after_abs (uptr, 1000000/(uptr)->DEFIO_CPS) : sim_activate_abs (uptr, (uptr)->wait) /* Function declarations */ diff --git a/I1620/i1620_pt.c b/I1620/i1620_pt.c index 5043bd75..09dac0f3 100644 --- a/I1620/i1620_pt.c +++ b/I1620/i1620_pt.c @@ -74,13 +74,14 @@ t_stat ptp_num (void); */ UNIT ptr_unit = { - UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), DEFIO_CPS + UDATA (&ptr_svc, UNIT_SEQ+UNIT_ATTABLE+UNIT_ROABLE, 0), SERIAL_OUT_WAIT }; REG ptr_reg[] = { { FLDATA (BIN, ptr_mode, 0) }, { DRDATA (POS, ptr_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (CPS, ptr_unit.wait, 24), PV_LEFT }, + { DRDATA (TIME, ptr_unit.wait, 24), PV_LEFT }, + { DRDATA (CPS, ptr_unit.DEFIO_CPS, 24), PV_LEFT }, { NULL } }; @@ -100,13 +101,14 @@ DEVICE ptr_dev = { */ UNIT ptp_unit = { - UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), DEFIO_CPS + UDATA (&ptp_svc, UNIT_SEQ+UNIT_ATTABLE, 0), SERIAL_OUT_WAIT }; REG ptp_reg[] = { { FLDATA (BIN, ptp_mode, 0) }, { DRDATA (POS, ptp_unit.pos, T_ADDR_W), PV_LEFT }, - { DRDATA (CPS, ptp_unit.wait, 24), PV_LEFT }, + { DRDATA (TIME, ptp_unit.wait, 24), PV_LEFT }, + { DRDATA (CPS, ptr_unit.DEFIO_CPS, 24), PV_LEFT }, { NULL } }; @@ -268,7 +270,7 @@ if (cpuio_cnt >= MEMSIZE) { /* over the limit? */ cpuio_clr_inp (uptr); /* done */ return STOP_RWRAP; } -sim_activate_after (uptr, 1000000/uptr->wait); /* sched another xfer */ +DEFIO_ACTIVATE (uptr); /* sched another xfer */ if ((uptr->flags & UNIT_ATT) == 0) /* not attached? */ return SCPE_UNATT; @@ -425,7 +427,7 @@ if ((cpuio_opc != OP_DN) && (cpuio_cnt >= MEMSIZE)) { /* wrap, ~dump? */ cpuio_clr_inp (uptr); /* done */ return STOP_RWRAP; } -sim_activate_after (uptr, 1000000/uptr->wait); /* sched another xfer */ +DEFIO_ACTIVATE (uptr); /* 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 02a5d78d..5a488dc1 100644 --- a/I1620/i1620_tty.c +++ b/I1620/i1620_tty.c @@ -90,7 +90,7 @@ t_stat tty_set_12digit (UNIT *uptr, int32 val, CONST char *cptr, void *desc); */ UNIT tty_unit[] = { - { UDATA (&tto_svc, 0, 0), DEFIO_CPS }, + { UDATA (&tto_svc, 0, 0), SERIAL_OUT_WAIT }, { UDATA (&tti_svc, 0, 0), KBD_POLL_WAIT } }; @@ -99,7 +99,8 @@ 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 (CPS, tty_unit[UTTO].wait, 24), REG_NZ + PV_LEFT }, + { DRDATA (TTIME, tty_unit[UTTO].wait, 24), REG_NZ + PV_LEFT }, + { DRDATA (CPS, tty_unit[UTTO].DEFIO_CPS, 24), REG_NZ + PV_LEFT }, { NULL } }; @@ -389,7 +390,7 @@ if ((cpuio_opc != OP_DN) && (cpuio_cnt >= MEMSIZE)) { /* wrap, ~dump? */ cpuio_clr_inp (uptr); /* done */ return STOP_RWRAP; } -sim_activate_after (uptr, 1000000/uptr->wait); /* sched another xfer */ +DEFIO_ACTIVATE (uptr); /* sched another xfer */ switch (cpuio_opc) { /* decode op */