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
This commit is contained in:
Mark Pizzolato 2021-04-05 15:14:15 -07:00
parent e62070ad8f
commit be4e3c4e33
2 changed files with 65 additions and 84 deletions

View file

@ -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;

View file

@ -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") },