From be4e3c4e3320cb2987b5653e03b448dbb751bed6 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Mon, 5 Apr 2021 15:14:15 -0700 Subject: [PATCH] PDP11, Qbus & Unibus VAX: Fix TDC device REGisters definitions - The REG definitions support having a REGister be pointing at an element in an array of structures (or UNITs) as long as the element is a scalar. Something that is not supported is when the element is already an array (or buffer). The approach used in the TDC device creates n additional registers each of which points at the individual array element in each of the structure in the structure array. - Fix simple REG declarations which didn't fully describe the size of the underlying storage holding the REG contents in the TDC and VH DEVICEs. As reported in #1025 --- PDP11/pdp11_td.c | 143 ++++++++++++++++++++--------------------------- PDP11/pdp11_vh.c | 6 +- 2 files changed, 65 insertions(+), 84 deletions(-) diff --git a/PDP11/pdp11_td.c b/PDP11/pdp11_td.c index 8727aec0..4c7b922b 100644 --- a/PDP11/pdp11_td.c +++ b/PDP11/pdp11_td.c @@ -636,7 +636,7 @@ struct CTLR { int32 ecode; /* end packet success code */ }; -static CTLR td_ctlr[TD_NUMCTLR+1]; /* one for each DL based TU58 plus console */ +static CTLR td_ctlr[TD_NUMCTLR+1]; /* one for each DL based TU58 plus console */ static t_stat td_rd (int32 *data, int32 PA, int32 access); static t_stat td_wr (int32 data, int32 PA, int32 access); @@ -684,24 +684,25 @@ static REG td_reg[] = { #define RDATA(nm,loc,wd,desc) STRDATAD(nm,td_ctlr[0].loc,16,wd,0,TD_NUMCTLR+1,sizeof(CTLR),REG_RO,desc) #define RDATAF(nm,loc,wd,desc,flds) STRDATADF(nm,td_ctlr[0].loc,16,wd,0,TD_NUMCTLR+1,sizeof(CTLR),REG_RO,desc,flds) - { RDATA (ECODE, ecode, 16, "end packet success code") }, - { RDATA (BLOCK, block, 16, "current block number") }, + { RDATA (ECODE, ecode, 32, "end packet success code") }, + { RDATA (BLOCK, block, 32, "current block number") }, { RDATAF (RX_CSR, rx_csr, 16, "input control/status register", rx_csr_bits) }, { RDATAF (RX_BUF, rx_buf, 16, "input buffer register", rx_buf_bits) }, { RDATAF (TX_CSR, tx_csr, 16, "output control/status register", tx_csr_bits) }, { RDATAF (TX_BUF, tx_buf, 16, "output buffer register", tx_buf_bits) }, - { RDATA (P_STATE,p_state, 4, "protocol state") }, - { RDATA (O_STATE,o_state, 4, "output state") }, - { RDATA (IBPTR, ibptr, 16, "input buffer pointer") }, - { RDATA (OBPTR, obptr, 16, "output buffer pointer") }, - { RDATA (ILEN, ilen, 16, "input length") }, - { RDATA (OLEN, olen, 16, "output length") }, - { RDATA (TXSIZE, txsize, 16, "remaining transfer size") }, - { RDATA (OFFSET, offset, 16, "offset into current transfer") }, - { RDATA (UNITNO, unitno, 16, "active unit number") }, - - { BRDATAD (IBUF, td_ctlr[0].ibuf,16, 8, TD_NUMBY+1, "input buffer"), }, - { BRDATAD (OBUF, td_ctlr[0].obuf,16, 8, TD_NUMBY+1, "output buffer"), }, + { RDATA (P_STATE,p_state,32, "protocol state") }, + { RDATA (O_STATE,o_state,32, "output state") }, + { RDATA (IBPTR, ibptr, 32, "input buffer pointer") }, + { RDATA (OBPTR, obptr, 32, "output buffer pointer") }, + { RDATA (ILEN, ilen, 32, "input length") }, + { RDATA (OLEN, olen, 32, "output length") }, + { RDATA (TXSIZE, txsize, 32, "remaining transfer size") }, + { RDATA (OFFSET, offset, 32, "offset into current transfer") }, + { RDATA (UNITNO, unitno, 32, "active unit number") }, +/* + REG entries for each controller's IBUF and OBUF are dynamically established + on first call to td_reset. +*/ { NULL } }; @@ -1325,8 +1326,6 @@ return 0; static t_stat td_reset_ctlr (CTLR *ctlr) { -REG *reg; - ctlr->tx_buf = 0; ctlr->tx_csr = CSR_DONE; CSI_CLR_INT; @@ -1339,70 +1338,6 @@ ctlr->offset = 0; ctlr->txsize = 0; ctlr->p_state = 0; ctlr->ecode = 0; -/* fixup/connect registers to actual data */ -reg = find_reg ("ECODE", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->ecode; -reg = find_reg ("BLOCK", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->block; -reg = find_reg ("P_STATE", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->p_state; -reg = find_reg ("O_STATE", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->o_state; -reg = find_reg ("IBPTR", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->ibptr; -reg = find_reg ("ILEN", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->ilen; -reg = find_reg ("OBPTR", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->obptr; -reg = find_reg ("OLEN", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->olen; -reg = find_reg ("TXSIZE", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->txsize; -reg = find_reg ("OFFSET", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->offset; -reg = find_reg ("IBUF", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->ibuf; -reg = find_reg ("OBUF", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->obuf; -reg = find_reg ("RX_CSR", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->rx_csr; -reg = find_reg ("RX_BUF", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->rx_buf; -reg = find_reg ("TX_CSR", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->tx_csr; -reg = find_reg ("TX_BUF", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->tx_buf; -reg = find_reg ("UNIT", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&ctlr->unitno; -reg = find_reg ("CTIME", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&td_ctime; -reg = find_reg ("STIME", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&td_stime; -reg = find_reg ("XTIME", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&td_xtime; -reg = find_reg ("ITIME", NULL, ctlr->dptr); -if (reg) - reg->loc = (void *)&td_itime; return SCPE_OK; } @@ -1413,6 +1348,52 @@ static t_stat td_reset (DEVICE *dptr) CTLR *ctlr; int ctl; static t_bool td_enabled_reset = FALSE; +static t_bool td_regs_inited = FALSE; + +if (!td_regs_inited) { + int regs; + int reg; + REG *registers; + + /* Count initial register array */ + for (regs = 0; dptr->registers [regs].name != NULL; regs++) + ; + /* Allocate new register array with room for input and output buffer registers */ + registers = (REG *)calloc (regs + 2 * (TD_NUMCTLR + 1) + 1, sizeof (*registers)); + if (registers == NULL) + return SCPE_MEM; + /* Copy initial register array */ + for (reg = 0; reg < regs; reg++) + registers[reg] = dptr->registers[reg]; + /* For each controller add input and output buffer register entries */ + for (ctl = 0; ctl < TD_NUMCTLR + 1; ctl++) { + char reg_name[32]; + char reg_desc[64]; + static REG reg_template[] = { + { BRDATAD(TBUF, td_ctlr[0].ibuf, 16, 8, TD_NUMBY + 1, "input buffer") }, + { NULL } }; + + snprintf(reg_name, sizeof(reg_name), "IBUF_%d", ctl); + registers[reg] = reg_template[0]; + registers[reg].name = (char *)calloc (strlen (reg_name) + 1, sizeof (char)); + strcpy ((char *)registers[reg].name, reg_name); + snprintf(reg_desc, sizeof(reg_desc), "input buffer for %s%d", dptr->name, ctl); + registers[reg].desc = (char*)calloc(strlen(reg_desc) + 1, sizeof(char)); + strcpy((char*)registers[reg].desc, reg_desc); + registers[reg].loc = td_ctlr[ctl].ibuf; + snprintf(reg_name, sizeof(reg_name), "OBUF_%d", ctl); + registers[reg + 1] = reg_template[0]; + registers[reg + 1].name = (char*)calloc(strlen(reg_name) + 1, sizeof(char)); + strcpy((char*)registers[reg + 1].name, reg_name); + snprintf(reg_desc, sizeof(reg_desc), "output buffer for %s%d", dptr->name, ctl); + registers[reg + 1].desc = (char*)calloc(strlen(reg_desc) + 1, sizeof(char)); + strcpy((char*)registers[reg + 1].desc, reg_desc); + registers[reg + 1].loc = td_ctlr[ctl].obuf; + reg += 2; + } + dptr->registers = registers; + td_regs_inited = TRUE; + } if (dptr->flags & DEV_DIS) td_enabled_reset = FALSE; diff --git a/PDP11/pdp11_vh.c b/PDP11/pdp11_vh.c index 99855bac..cfda72cd 100644 --- a/PDP11/pdp11_vh.c +++ b/PDP11/pdp11_vh.c @@ -523,9 +523,9 @@ static const REG vh_reg[] = { { BRDATADF (CSR, vh_csr, DEV_RDX, 16, VH_MUXES, "control/status register, boards 0 to 3", vh_csr_bits) }, { BRDATAD (TIMER, vh_timer, DEV_RDX, 16, VH_MUXES, "controller timeout, boards 0 to 3") }, { BRDATAD (MCOUNT, vh_mcount, DEV_RDX, 16, VH_MUXES, "count down timer, boards 0 to 3") }, - { BRDATAD (TIMEO, vh_timeo, DEV_RDX, 16, VH_MUXES, "receive interrupt count down timer, boards 0 to 3") }, - { BRDATAD (OVRRUN, vh_ovrrun, DEV_RDX, 16, VH_MUXES, "line overrun bits, boards 0 to 3") }, - { BRDATAD (STALL, vh_stall, DEV_RDX, 16, VH_MUXES, "XOFF'd channels 1 bit/channel, boards 0 to 3") }, + { BRDATAD (TIMEO, vh_timeo, DEV_RDX, 32, VH_MUXES, "receive interrupt count down timer, boards 0 to 3") }, + { BRDATAD (OVRRUN, vh_ovrrun, DEV_RDX, 32, VH_MUXES, "line overrun bits, boards 0 to 3") }, + { BRDATAD (STALL, vh_stall, DEV_RDX, 32, VH_MUXES, "XOFF'd channels 1 bit/channel, boards 0 to 3") }, { BRDATAD (LOOP, vh_loop, DEV_RDX, 16, VH_MUXES, "loopback status, boards 0 to 3") }, { GRDATAD (RCVINT, vh_rxi, DEV_RDX, 32, 0, "rcv interrupts 1 bit/channel") }, { GRDATAD (TXINT, vh_txi, DEV_RDX, 32, 0, "xmt interrupts 1 bit/channel") },