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:
parent
e62070ad8f
commit
be4e3c4e33
2 changed files with 65 additions and 84 deletions
143
PDP11/pdp11_td.c
143
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;
|
||||
|
|
|
@ -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") },
|
||||
|
|
Loading…
Add table
Reference in a new issue