PDP11, VAX: Move DZ input character silo into device to properly rate limit received data
Previously, the input silo was modeled by using the pending input data in the TMXR line buffer. This was fine when bps rate limiting wasn't happening. In order to properly pace arriving data from multiple lines the silo is now implemented in a way which more precisely reflects the original hardware.
This commit is contained in:
parent
bbd5f9bf95
commit
619e33466b
1 changed files with 35 additions and 22 deletions
|
@ -228,6 +228,8 @@ uint16 dz_lpr[MAX_DZ_MUXES] = { 0 }; /* line param */
|
||||||
uint16 dz_tcr[MAX_DZ_MUXES] = { 0 }; /* xmit control */
|
uint16 dz_tcr[MAX_DZ_MUXES] = { 0 }; /* xmit control */
|
||||||
uint16 dz_msr[MAX_DZ_MUXES] = { 0 }; /* modem status */
|
uint16 dz_msr[MAX_DZ_MUXES] = { 0 }; /* modem status */
|
||||||
uint16 dz_tdr[MAX_DZ_MUXES] = { 0 }; /* xmit data */
|
uint16 dz_tdr[MAX_DZ_MUXES] = { 0 }; /* xmit data */
|
||||||
|
uint16 dz_silo[MAX_DZ_MUXES][DZ_SILO_ALM] = { 0 }; /* silo */
|
||||||
|
uint16 dz_scnt[MAX_DZ_MUXES] = { 0 }; /* silo used */
|
||||||
uint8 dz_sae[MAX_DZ_MUXES] = { 0 }; /* silo alarm enabled */
|
uint8 dz_sae[MAX_DZ_MUXES] = { 0 }; /* silo alarm enabled */
|
||||||
uint32 dz_rxi = 0; /* rcv interrupts */
|
uint32 dz_rxi = 0; /* rcv interrupts */
|
||||||
uint32 dz_txi = 0; /* xmt interrupts */
|
uint32 dz_txi = 0; /* xmt interrupts */
|
||||||
|
@ -241,6 +243,7 @@ TMXR dz_desc = { DZ_MUXES * DZ_LINES, 0, 0, NULL }; /* mux descriptor */
|
||||||
#define DBG_INT 0x0002 /* display interrupt activities */
|
#define DBG_INT 0x0002 /* display interrupt activities */
|
||||||
#define DBG_XMT TMXR_DBG_XMT /* display Transmitted Data */
|
#define DBG_XMT TMXR_DBG_XMT /* display Transmitted Data */
|
||||||
#define DBG_RCV TMXR_DBG_RCV /* display Received Data */
|
#define DBG_RCV TMXR_DBG_RCV /* display Received Data */
|
||||||
|
#define DBG_RET TMXR_DBG_RET /* display Read Data */
|
||||||
#define DBG_MDM TMXR_DBG_MDM /* display Modem Signals */
|
#define DBG_MDM TMXR_DBG_MDM /* display Modem Signals */
|
||||||
#define DBG_CON TMXR_DBG_CON /* display connection activities */
|
#define DBG_CON TMXR_DBG_CON /* display connection activities */
|
||||||
#define DBG_TRC TMXR_DBG_TRC /* display trace routine calls */
|
#define DBG_TRC TMXR_DBG_TRC /* display trace routine calls */
|
||||||
|
@ -251,6 +254,7 @@ DEBTAB dz_debug[] = {
|
||||||
{"INT", DBG_INT, "interrupt activities"},
|
{"INT", DBG_INT, "interrupt activities"},
|
||||||
{"XMT", DBG_XMT, "Transmitted Data"},
|
{"XMT", DBG_XMT, "Transmitted Data"},
|
||||||
{"RCV", DBG_RCV, "Received Data"},
|
{"RCV", DBG_RCV, "Received Data"},
|
||||||
|
{"RET", DBG_RET, "Read Data"},
|
||||||
{"MDM", DBG_MDM, "Modem Signals"},
|
{"MDM", DBG_MDM, "Modem Signals"},
|
||||||
{"CON", DBG_CON, "connection activities"},
|
{"CON", DBG_CON, "connection activities"},
|
||||||
{"TRC", DBG_TRC, "trace routine calls"},
|
{"TRC", DBG_TRC, "trace routine calls"},
|
||||||
|
@ -591,40 +595,47 @@ return SCPE_OK;
|
||||||
|
|
||||||
uint16 dz_getc (int32 dz)
|
uint16 dz_getc (int32 dz)
|
||||||
{
|
{
|
||||||
uint32 i, line, c;
|
uint16 ret;
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
for (i = c = 0; (i < DZ_LINES) && (c == 0); i++) { /* loop thru lines */
|
if (!dz_scnt[dz])
|
||||||
line = (dz * DZ_LINES) + i; /* get line num */
|
return 0;
|
||||||
c = tmxr_getc_ln (&dz_ldsc[line]); /* test for input */
|
ret = dz_silo[dz][0]; /* first fifo element */
|
||||||
if (c & SCPE_BREAK) /* break? frame err */
|
for (i=1; i < dz_scnt[dz]; i++) /* slide down remaining entries */
|
||||||
c = RBUF_VALID | RBUF_FRME;
|
dz_silo[dz][i-1] = dz_silo[dz][i];
|
||||||
if (c) /* or in line # */
|
--dz_scnt[dz]; /* adjust count */
|
||||||
c = (c & RBUF_CHAR) | RBUF_VALID | (i << RBUF_V_RLINE);
|
sim_debug(DBG_RCV, &dz_dev, "DZ Device %d - Received: 0x%X - '%c'\n", dz, ret, sim_isprint(ret&0xFF) ? ret & 0xFF : '.');
|
||||||
} /* end for */
|
return ret;
|
||||||
return (uint16)c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Update receive interrupts */
|
/* Update receive interrupts */
|
||||||
|
|
||||||
void dz_update_rcvi (void)
|
void dz_update_rcvi (void)
|
||||||
{
|
{
|
||||||
int32 i, dz, line, scnt[MAX_DZ_MUXES];
|
int32 i, dz, c;
|
||||||
TMLN *lp;
|
TMLN *lp;
|
||||||
|
|
||||||
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* loop thru muxes */
|
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* loop thru muxes */
|
||||||
scnt[dz] = 0; /* clr input count */
|
if (dz_csr[dz] & CSR_MSE) { /* enabled? */
|
||||||
for (i = 0; i < DZ_LINES; i++) { /* poll lines */
|
for (i = 0; i < DZ_LINES; i++) { /* poll lines */
|
||||||
line = (dz * DZ_LINES) + i; /* get line num */
|
if (dz_scnt[dz] >= DZ_SILO_ALM)
|
||||||
lp = &dz_ldsc[line]; /* get line desc */
|
break;
|
||||||
scnt[dz] = scnt[dz] + tmxr_rqln (lp); /* sum buffers */
|
lp = &dz_ldsc[(dz * DZ_LINES) + i]; /* get line desc */
|
||||||
if (dz_mctl && !lp->conn) /* if disconn */
|
c = tmxr_getc_ln (lp); /* test for input */
|
||||||
dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */
|
if (c & SCPE_BREAK) /* break? frame err */
|
||||||
|
c = RBUF_FRME;
|
||||||
|
if (c) { /* save in silo */
|
||||||
|
c = (c & (RBUF_CHAR | RBUF_FRME)) | RBUF_VALID | (i << RBUF_V_RLINE);
|
||||||
|
dz_silo[dz][dz_scnt[dz]] = (uint16)c;
|
||||||
|
++dz_scnt[dz];
|
||||||
|
}
|
||||||
|
if (dz_mctl && !lp->conn) /* if disconn */
|
||||||
|
dz_msr[dz] &= ~(1 << (i + MSR_V_CD)); /* reset car det */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (dz_scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */
|
||||||
for (dz = 0; dz < dz_desc.lines/DZ_LINES; dz++) { /* loop thru muxes */
|
|
||||||
if (scnt[dz] && (dz_csr[dz] & CSR_MSE)) { /* input & enabled? */
|
|
||||||
dz_csr[dz] |= CSR_RDONE; /* set done */
|
dz_csr[dz] |= CSR_RDONE; /* set done */
|
||||||
if (dz_sae[dz] && (scnt[dz] >= DZ_SILO_ALM)) { /* alm enb & cnt hi? */
|
if (dz_sae[dz] && (dz_scnt[dz] >= DZ_SILO_ALM)) {/* alm enb & cnt hi? */
|
||||||
dz_csr[dz] |= CSR_SA; /* set status */
|
dz_csr[dz] |= CSR_SA; /* set status */
|
||||||
dz_sae[dz] = 0; /* disable alarm */
|
dz_sae[dz] = 0; /* disable alarm */
|
||||||
}
|
}
|
||||||
|
@ -671,6 +682,8 @@ return;
|
||||||
|
|
||||||
void dz_clr_rxint (int32 dz)
|
void dz_clr_rxint (int32 dz)
|
||||||
{
|
{
|
||||||
|
if (dz_rxi & (1 << dz))
|
||||||
|
sim_debug(DBG_INT, &dz_dev, "dz_clr_rxint(dz=%d, rxi=0x%X)\n", dz, dz_rxi);
|
||||||
dz_rxi = dz_rxi & ~(1 << dz); /* clr mux rcv int */
|
dz_rxi = dz_rxi & ~(1 << dz); /* clr mux rcv int */
|
||||||
if (dz_rxi == 0) /* all clr? */
|
if (dz_rxi == 0) /* all clr? */
|
||||||
CLR_INT (DZRX);
|
CLR_INT (DZRX);
|
||||||
|
|
Loading…
Add table
Reference in a new issue