diff --git a/PDP11/pdp11_dup.c b/PDP11/pdp11_dup.c index f74f9713..d0b3b5fe 100644 --- a/PDP11/pdp11_dup.c +++ b/PDP11/pdp11_dup.c @@ -318,6 +318,197 @@ static BITFIELD dup_txdbuf_bits[] = { #define TXDBUF_MBZ ((1<<15)|(1<<13)) #define TXDBUF_WRITEABLE (TXDBUF_M_TABRT|TXDBUF_M_TEOM|TXDBUF_M_TSOM|TXDBUF_M_TXDBUF) + +/* Equivalent register definitions for DPV11. Some bits are common; some are nearly common + but with slightly different semantics; some are different altogether */ + +/* DPV RXCSR - 16XXX0 - receiver control/status register */ + +static BITFIELD dpv_rxcsr_bits[] = { + BIT(DPV_SFRL), /* Set Freq / Remote Loop */ +#define RXCSR_V_DPV_SFRL 0 +#define RXCSR_M_DPV_SFRL (1<> 3); /* get line num */ int32 orig_val; @@ -511,12 +748,17 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */ case 00: /* RXCSR */ dup_get_modem (dup); *data = dup_rxcsr[dup]; - dup_rxcsr[dup] &= ~(RXCSR_M_DSCHNG|RXCSR_M_BDATSET); + if (UNIBUS) + dup_rxcsr[dup] &= ~(RXCSR_M_DSCHNG|RXCSR_M_BDATSET); + else + dup_rxcsr[dup] &= ~(RXCSR_M_DPV_DSCHNG); break; case 01: /* RXDBUF */ *data = dup_rxdbuf[dup]; dup_rxcsr[dup] &= ~RXCSR_M_RXDONE; + if (!UNIBUS) + dup_rxcsr[dup] &= ~RXCSR_M_DPV_RSTARY; if (dup_rxcsr[dup] & RXCSR_M_RXACT) sim_activate (dup_units+dup, dup_wait[dup]); break; @@ -531,14 +773,15 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */ } sim_debug(DBG_REG, DUPDPTR, "dup_rd(PA=0x%08X [%s], data=0x%X) ", PA, dup_rd_regs[(PA >> 1) & 03], *data); -sim_debug_bits(DBG_REG, DUPDPTR, bitdefs[(PA >> 1) & 03], (uint32)(orig_val), (uint32)(regs[(PA >> 1) & 03][dup]), TRUE); +sim_debug_bits(DBG_REG, DUPDPTR, ((UNIBUS) ? bitdefs[(PA >> 1) & 03] : dpv_bitdefs[(PA >> 1) & 03]), + (uint32)(orig_val), (uint32)(regs[(PA >> 1) & 03][dup]), TRUE); return SCPE_OK; } - static t_stat dup_wr (int32 data, int32 PA, int32 access) { static BITFIELD* bitdefs[] = {dup_rxcsr_bits, dup_parcsr_bits, dup_txcsr_bits, dup_txdbuf_bits}; +static BITFIELD* dpv_bitdefs[] = {dpv_rxcsr_bits, dpv_parcsr_bits, dpv_txcsr_bits, dpv_txdbuf_bits}; static uint16 *regs[] = {dup_rxcsr, dup_parcsr, dup_txcsr, dup_txdbuf}; int32 dup = ((PA - dup_dib.ba) >> 3); /* get line num */ int32 orig_val; @@ -547,7 +790,8 @@ if (dup >= dup_desc.lines) /* validate line number return SCPE_IERR; orig_val = regs[(PA >> 1) & 03][dup]; -if (PA & 1) /* unaligned byte access? */ + +if (PA & 1) data = ((data << 8) | (orig_val & 0xFF)) & 0xFFFF; /* Merge with original word */ else if (access == WRITEB) /* byte access? */ @@ -557,21 +801,30 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */ case 00: /* RXCSR */ dup_set_modem (dup, data); - dup_rxcsr[dup] &= ~RXCSR_WRITEABLE; - dup_rxcsr[dup] |= (data & RXCSR_WRITEABLE); - if ((dup_rxcsr[dup] & RXCSR_M_DTR) && /* Upward transition of DTR */ - (!(orig_val & RXCSR_M_DTR))) /* Enables Receive on the line */ - dup_desc.ldsc[dup].rcve = TRUE; - if ((dup_rxcsr[dup] & RXCSR_M_RTS) && /* Upward transition of RTS */ - (!(orig_val & RXCSR_M_RTS)) && /* while receiver is enabled and */ - (dup_rxcsr[dup] & RXCSR_M_RCVEN) && /* not stripping sync characters */ - (!(dup_rxcsr[dup] & RXCSR_M_STRSYN)) ) { /* Receive a SYNC character */ - dup_rxcsr[dup] |= RXCSR_M_RXDONE; - dup_rxdbuf[dup] &= ~RXDBUF_M_RXDBUF; - dup_rxdbuf[dup] |= (dup_parcsr[dup] & PARCSR_M_ADSYNC); - if (dup_rxcsr[dup] & RXCSR_M_RXIE) - dup_set_rxint (dup); + if (UNIBUS) { + dup_rxcsr[dup] &= ~RXCSR_WRITEABLE; + dup_rxcsr[dup] |= (data & RXCSR_WRITEABLE); + if ((dup_rxcsr[dup] & RXCSR_M_DTR) && /* Upward transition of DTR */ + (!(orig_val & RXCSR_M_DTR))) /* Enables Receive on the line */ + dup_desc.ldsc[dup].rcve = TRUE; + if ((dup_rxcsr[dup] & RXCSR_M_RTS) && /* Upward transition of RTS */ + (!(orig_val & RXCSR_M_RTS)) && /* while receiver is enabled and */ + (dup_rxcsr[dup] & RXCSR_M_RCVEN) && /* not stripping sync characters */ + (!(dup_rxcsr[dup] & RXCSR_M_STRSYN)) ) { /* Receive a SYNC character */ + dup_rxcsr[dup] |= RXCSR_M_RXDONE; + dup_rxdbuf[dup] &= ~RXDBUF_M_RXDBUF; + dup_rxdbuf[dup] |= (dup_parcsr[dup] & PARCSR_M_ADSYNC); + if (dup_rxcsr[dup] & RXCSR_M_RXIE) + dup_set_rxint (dup); } + } + else { + dup_rxcsr[dup] &= ~RXCSR_DPV_WRITEABLE; + dup_rxcsr[dup] |= (data & RXCSR_DPV_WRITEABLE); + if ((dup_rxcsr[dup] & RXCSR_M_DTR) && /* Upward transition of DTR */ + (!(orig_val & RXCSR_M_DTR))) /* Enables Receive on the line */ + dup_desc.ldsc[dup].rcve = TRUE; + } if ((dup_rxcsr[dup] & RXCSR_M_RCVEN) && (!(orig_val & RXCSR_M_RCVEN))) { /* Upward transition of receiver enable */ dup_rcv_byte (dup); /* start any pending receive */ @@ -592,21 +845,25 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */ break; case 01: /* PARCSR */ - dup_parcsr[dup] &= ~PARCSR_WRITEABLE; - dup_parcsr[dup] |= (data & PARCSR_WRITEABLE); + if (UNIBUS) { + dup_parcsr[dup] &= ~PARCSR_WRITEABLE; + dup_parcsr[dup] |= (data & PARCSR_WRITEABLE); + } else + dup_parcsr[dup] = data ; break; case 02: /* TXCSR */ - dup_txcsr[dup] &= ~TXCSR_WRITEABLE; - dup_txcsr[dup] |= (data & TXCSR_WRITEABLE); - if (dup_txcsr[dup] & TXCSR_M_DRESET) { - dup_clear(dup, dup_W3[dup]); - /* must also clear loopback if it was set */ - tmxr_set_line_loopback (&dup_desc.ldsc[dup], FALSE); - break; + if (UNIBUS) { + dup_txcsr[dup] &= ~TXCSR_WRITEABLE; + dup_txcsr[dup] |= (data & TXCSR_WRITEABLE); + if (dup_txcsr[dup] & TXCSR_M_DRESET) { + dup_clear(dup, dup_W3[dup]); + /* must also clear loopback if it was set */ + tmxr_set_line_loopback (&dup_desc.ldsc[dup], FALSE); + break; } - if (TXCSR_GETMAISEL(dup_txcsr[dup]) != TXCSR_GETMAISEL(orig_val)) { /* Maint Select Changed */ - switch (TXCSR_GETMAISEL(dup_txcsr[dup])) { + if (TXCSR_GETMAISEL(dup_txcsr[dup]) != TXCSR_GETMAISEL(orig_val)) { /* Maint Select Changed */ + switch (TXCSR_GETMAISEL(dup_txcsr[dup])) { case 0: /* User/Normal Mode */ tmxr_set_line_loopback (&dup_desc.ldsc[dup], FALSE); break; @@ -618,38 +875,75 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */ break; } } - if ((dup_txcsr[dup] & TXCSR_M_TXACT) && - (!(orig_val & TXCSR_M_TXACT)) && - (orig_val & TXCSR_M_TXDONE)) { - dup_txcsr[dup] &= ~TXCSR_M_TXDONE; + if ((dup_txcsr[dup] & TXCSR_M_TXACT) && + (!(orig_val & TXCSR_M_TXACT)) && + (orig_val & TXCSR_M_TXDONE)) { + dup_txcsr[dup] &= ~TXCSR_M_TXDONE; } - if ((!(dup_txcsr[dup] & TXCSR_M_SEND)) && - (orig_val & TXCSR_M_SEND)) { - dup_txcsr[dup] &= ~TXCSR_M_TXACT; - dup_put_msg_bytes (dup, NULL, 0, FALSE, TRUE); + if ((!(dup_txcsr[dup] & TXCSR_M_SEND)) && + (orig_val & TXCSR_M_SEND)) { + dup_txcsr[dup] &= ~TXCSR_M_TXACT; + dup_put_msg_bytes (dup, NULL, 0, FALSE, TRUE); } - if ((dup_txcsr[dup] & TXCSR_M_HALFDUP) ^ (orig_val & TXCSR_M_HALFDUP)) - tmxr_set_line_halfduplex (dup_desc.ldsc+dup, dup_txcsr[dup] & TXCSR_M_HALFDUP); - if ((dup_txcsr[dup] & TXCSR_M_TXIE) && - (!(orig_val & TXCSR_M_TXIE)) && - (dup_txcsr[dup] & TXCSR_M_TXDONE)) { - dup_set_txint (dup); + if ((dup_txcsr[dup] & TXCSR_M_HALFDUP) ^ (orig_val & TXCSR_M_HALFDUP)) + tmxr_set_line_halfduplex (dup_desc.ldsc+dup, dup_txcsr[dup] & TXCSR_M_HALFDUP); + if ((dup_txcsr[dup] & TXCSR_M_TXIE) && + (!(orig_val & TXCSR_M_TXIE)) && + (dup_txcsr[dup] & TXCSR_M_TXDONE)) { + dup_set_txint (dup); } + } else { + dup_txcsr[dup] &= ~TXCSR_DPV_WRITEABLE; + dup_txcsr[dup] |= (data & TXCSR_DPV_WRITEABLE); + if (dup_txcsr[dup] & TXCSR_M_DPV_RESET) { + dup_clear(dup, TRUE); + /* must also clear loopback if it was set */ + tmxr_set_line_loopback (&dup_desc.ldsc[dup], FALSE); + break; + } + if ((dup_txcsr[dup] & TXCSR_M_DPV_MAINT) ^ (orig_val & TXCSR_M_DPV_MAINT)) /* maint mode change */ + tmxr_set_line_loopback (&dup_desc.ldsc[dup], dup_txcsr[dup] & TXCSR_M_DPV_MAINT ); + if ((!(dup_txcsr[dup] & TXCSR_M_DPV_SEND)) && + (orig_val & TXCSR_M_DPV_SEND)) { + dup_txcsr[dup] &= ~TXCSR_M_DPV_TXACT; + dup_put_msg_bytes (dup, NULL, 0, FALSE, TRUE); + } + if ((dup_txcsr[dup] & TXCSR_M_DPV_TXIE) && + (!(orig_val & TXCSR_M_DPV_TXIE)) && + (dup_txcsr[dup] & TXCSR_M_DPV_TBEMPTY)) { + dup_set_txint (dup); + } + /* Receive character length, transmit character length, extended HDLC fields, SQ/TM not supported */ + } break; case 03: /* TXDBUF */ - dup_txdbuf[dup] &= ~TXDBUF_WRITEABLE; - dup_txdbuf[dup] |= (data & TXDBUF_WRITEABLE); - dup_txcsr[dup] &= ~TXCSR_M_TXDONE; - if (dup_txcsr[dup] & TXCSR_M_SEND) { - dup_txcsr[dup] |= TXCSR_M_TXACT; - sim_activate (dup_units+dup, dup_wait[dup]); + if (UNIBUS) { + dup_txdbuf[dup] &= ~TXDBUF_WRITEABLE; + dup_txdbuf[dup] |= (data & TXDBUF_WRITEABLE); + dup_txcsr[dup] &= ~TXCSR_M_TXDONE; + dup_clr_txint (dup); /* clear any pending interrupts */ + if (dup_txcsr[dup] & TXCSR_M_SEND) { + dup_txcsr[dup] |= TXCSR_M_TXACT; + sim_activate (dup_units+dup, dup_wait[dup]); } + } else { + dup_txdbuf[dup] &= ~TXDBUF_DPV_WRITEABLE; + dup_txdbuf[dup] |= (data & TXDBUF_DPV_WRITEABLE); + dup_txcsr[dup] &= ~TXCSR_M_DPV_TBEMPTY; + dup_clr_txint (dup); /* clear any pending interrupts */ + if (dup_txcsr[dup] & TXCSR_M_DPV_SEND) { + dup_txcsr[dup] |= TXCSR_M_DPV_TXACT; + sim_activate (dup_units+dup, dup_wait[dup]); + /* Go ahead, Abort not supported */ + } + } break; } sim_debug(DBG_REG, DUPDPTR, "dup_wr(PA=0x%08X [%s], data=0x%X) ", PA, dup_wr_regs[(PA >> 1) & 03], data); -sim_debug_bits(DBG_REG, DUPDPTR, bitdefs[(PA >> 1) & 03], (uint32)orig_val, (uint32)regs[(PA >> 1) & 03][dup], TRUE); +sim_debug_bits(DBG_REG, DUPDPTR, ((UNIBUS) ? bitdefs[(PA >> 1) & 03] : dpv_bitdefs[(PA >> 1) & 03]), + (uint32)orig_val, (uint32)regs[(PA >> 1) & 03][dup], TRUE); dup_get_modem (dup); return SCPE_OK; } @@ -674,48 +968,73 @@ int32 old_rxcsr_a_modem_bits, new_rxcsr_a_modem_bits, old_rxcsr_b_modem_bits, ne TMLN *lp = &dup_desc.ldsc[dup]; t_bool new_modem_change = FALSE; -if (dup_W5[dup]) - old_rxcsr_a_modem_bits = dup_rxcsr[dup] & (RXCSR_M_RING | RXCSR_M_CTS | RXCSR_M_DSR | RXCSR_M_DCD); -else - old_rxcsr_a_modem_bits = dup_rxcsr[dup] & (RXCSR_M_RING | RXCSR_M_CTS); -if (dup_W6[dup]) - old_rxcsr_b_modem_bits = dup_rxcsr[dup] & RXCSR_B_MODEM_BITS; -else - old_rxcsr_b_modem_bits = 0; -tmxr_set_get_modem_bits (lp, 0, 0, &modem_bits); -if (dup_W5[dup]) - new_rxcsr_a_modem_bits = (((modem_bits & TMXR_MDM_RNG) ? RXCSR_M_RING : 0) | - ((modem_bits & TMXR_MDM_CTS) ? RXCSR_M_CTS : 0) | - ((modem_bits & TMXR_MDM_DSR) ? RXCSR_M_DSR : 0) | +if (UNIBUS) { + if (dup_W5[dup]) + old_rxcsr_a_modem_bits = dup_rxcsr[dup] & (RXCSR_M_RING | RXCSR_M_CTS | RXCSR_M_DSR | RXCSR_M_DCD); + else + old_rxcsr_a_modem_bits = dup_rxcsr[dup] & (RXCSR_M_RING | RXCSR_M_CTS); + if (dup_W6[dup]) + old_rxcsr_b_modem_bits = dup_rxcsr[dup] & RXCSR_B_MODEM_BITS; + else + old_rxcsr_b_modem_bits = 0; + tmxr_set_get_modem_bits (lp, 0, 0, &modem_bits); + if (dup_W5[dup]) + new_rxcsr_a_modem_bits = (((modem_bits & TMXR_MDM_RNG) ? RXCSR_M_RING : 0) | + ((modem_bits & TMXR_MDM_CTS) ? RXCSR_M_CTS : 0) | + ((modem_bits & TMXR_MDM_DSR) ? RXCSR_M_DSR : 0) | + ((modem_bits & TMXR_MDM_DCD) ? RXCSR_M_DCD : 0)); + else + new_rxcsr_a_modem_bits = (((modem_bits & TMXR_MDM_RNG) ? RXCSR_M_RING : 0) | + ((modem_bits & TMXR_MDM_CTS) ? RXCSR_M_CTS : 0)); + if (dup_W6[dup]) + new_rxcsr_b_modem_bits = (((modem_bits & TMXR_MDM_DSR) ? RXCSR_M_DSR : 0) | + ((modem_bits & TMXR_MDM_DCD) ? RXCSR_M_DCD : 0)); + else + new_rxcsr_b_modem_bits = 0; + dup_rxcsr[dup] &= ~(RXCSR_A_MODEM_BITS | RXCSR_B_MODEM_BITS); + dup_rxcsr[dup] |= new_rxcsr_a_modem_bits | new_rxcsr_b_modem_bits; + if (old_rxcsr_a_modem_bits != new_rxcsr_a_modem_bits) { + dup_rxcsr[dup] |= RXCSR_M_DSCHNG; + new_modem_change = TRUE; + } + if (old_rxcsr_b_modem_bits != new_rxcsr_b_modem_bits) { + dup_rxcsr[dup] |= RXCSR_M_BDATSET; + new_modem_change = TRUE; + } + if (new_modem_change) { + sim_debug(DBG_MDM, DUPDPTR, "dup_get_modem() - Modem Signal Change "); + sim_debug_bits(DBG_MDM, DUPDPTR, dup_rxcsr_bits, (uint32)old_rxcsr, (uint32)dup_rxcsr[dup], TRUE); + } + if (dup_modem_change_callback[dup] && new_modem_change) + dup_modem_change_callback[dup](dup); + if ((dup_rxcsr[dup] & RXCSR_M_DSCHNG) && + ((dup_rxcsr[dup] & RXCSR_M_DSCHNG) != (old_rxcsr & RXCSR_M_DSCHNG)) && + (dup_rxcsr[dup] & RXCSR_M_DSCIE)) + dup_set_rxint (dup); +} else { + old_rxcsr_a_modem_bits = dup_rxcsr[dup] & (RXCSR_M_DPV_RING | RXCSR_M_DPV_CTS | RXCSR_M_DPV_DSR | RXCSR_M_DPV_DCD); + tmxr_set_get_modem_bits (lp, 0, 0, &modem_bits); + new_rxcsr_a_modem_bits = (((modem_bits & TMXR_MDM_RNG) ? RXCSR_M_DPV_RING : 0) | + ((modem_bits & TMXR_MDM_CTS) ? RXCSR_M_DPV_CTS : 0) | + ((modem_bits & TMXR_MDM_DSR) ? RXCSR_M_DPV_DSR : 0) | ((modem_bits & TMXR_MDM_DCD) ? RXCSR_M_DCD : 0)); -else - new_rxcsr_a_modem_bits = (((modem_bits & TMXR_MDM_RNG) ? RXCSR_M_RING : 0) | - ((modem_bits & TMXR_MDM_CTS) ? RXCSR_M_CTS : 0)); -if (dup_W6[dup]) - new_rxcsr_b_modem_bits = (((modem_bits & TMXR_MDM_DSR) ? RXCSR_M_DSR : 0) | - ((modem_bits & TMXR_MDM_DCD) ? RXCSR_M_DCD : 0)); -else - new_rxcsr_b_modem_bits = 0; -dup_rxcsr[dup] &= ~(RXCSR_A_MODEM_BITS | RXCSR_B_MODEM_BITS); -dup_rxcsr[dup] |= new_rxcsr_a_modem_bits | new_rxcsr_b_modem_bits; -if (old_rxcsr_a_modem_bits != new_rxcsr_a_modem_bits) { - dup_rxcsr[dup] |= RXCSR_M_DSCHNG; - new_modem_change = TRUE; + dup_rxcsr[dup] &= ~(RXCSR_DPV_MODEM_BITS); + dup_rxcsr[dup] |= new_rxcsr_a_modem_bits; + if (old_rxcsr_a_modem_bits != new_rxcsr_a_modem_bits) { + dup_rxcsr[dup] |= RXCSR_M_DPV_DSCHNG; + new_modem_change = TRUE; } -if (old_rxcsr_b_modem_bits != new_rxcsr_b_modem_bits) { - dup_rxcsr[dup] |= RXCSR_M_BDATSET; - new_modem_change = TRUE; + if (new_modem_change) { + sim_debug(DBG_MDM, DUPDPTR, "dup_get_modem() - Modem Signal Change "); + sim_debug_bits(DBG_MDM, DUPDPTR, dpv_rxcsr_bits, (uint32)old_rxcsr, (uint32)dup_rxcsr[dup], TRUE); } -if (new_modem_change) { - sim_debug(DBG_MDM, DUPDPTR, "dup_get_modem() - Modem Signal Change "); - sim_debug_bits(DBG_MDM, DUPDPTR, dup_rxcsr_bits, (uint32)old_rxcsr, (uint32)dup_rxcsr[dup], TRUE); - } -if (dup_modem_change_callback[dup] && new_modem_change) - dup_modem_change_callback[dup](dup); -if ((dup_rxcsr[dup] & RXCSR_M_DSCHNG) && - ((dup_rxcsr[dup] & RXCSR_M_DSCHNG) != (old_rxcsr & RXCSR_M_DSCHNG)) && - (dup_rxcsr[dup] & RXCSR_M_DSCIE)) - dup_set_rxint (dup); + if (dup_modem_change_callback[dup] && new_modem_change) + dup_modem_change_callback[dup](dup); + if ((dup_rxcsr[dup] & RXCSR_M_DPV_DSCHNG) && + ((dup_rxcsr[dup] & RXCSR_M_DPV_DSCHNG) != (old_rxcsr & RXCSR_M_DPV_DSCHNG)) && + (dup_rxcsr[dup] & RXCSR_M_DPV_DSCIE)) + dup_set_rxint (dup); +} return SCPE_OK; } @@ -910,7 +1229,10 @@ if (!tmxr_tpbusyln(&dup_ldsc[dup])) { /* Not Busy sending? */ memcpy (&dup_xmtpacket[dup][dup_xmtpkoffset[dup]], bytes, len); dup_xmtpkoffset[dup] += (uint16)len; } - dup_txcsr[dup] |= TXCSR_M_TXDONE; + if (UNIBUS) + dup_txcsr[dup] |= TXCSR_M_TXDONE; + else + dup_txcsr[dup] |= TXCSR_M_DPV_TBEMPTY; if (dup_txcsr[dup] & TXCSR_M_TXIE) dup_set_txint (dup); /* On End of Message, insert CRC and flag delivery start */ @@ -926,8 +1248,8 @@ if (!tmxr_tpbusyln(&dup_ldsc[dup])) { /* Not Busy sending? */ } breturn = TRUE; } -sim_debug (DBG_TRC, DUPDPTR, "dup_put_msg_bytes(dup=%d, len=%d, start=%s, end=%s) %s\n", - dup, (int)len, start ? "TRUE" : "FALSE", end ? "TRUE" : "FALSE", breturn ? "Good" : "Busy"); +sim_debug (DBG_TRC, DUPDPTR, "dup_put_msg_bytes(dup=%d, len=%d, start=%s, end=%s, byte=0x%02hhx) %s\n", + dup, (int)len, start ? "TRUE" : "FALSE", end ? "TRUE" : "FALSE", *bytes, breturn ? "Good" : "Busy"); if (breturn && (tmxr_tpbusyln (&dup_ldsc[dup]) || dup_xmtpkbytes[dup])) { if (dup_xmt_complete_callback[dup]) dup_svc(dup_units+dup); @@ -958,7 +1280,7 @@ return SCPE_OK; static t_stat dup_rcv_byte (int32 dup) { int32 crcoffset; - + sim_debug (DBG_TRC, DUPDPTR, "dup_rcv_byte(dup=%d) - %s, byte %d of %d\n", dup, (dup_rxcsr[dup] & RXCSR_M_RCVEN) ? "enabled" : "disabled", dup_rcvpkinoff[dup], dup_rcvpkbytes[dup]); @@ -973,16 +1295,28 @@ if (dup_rcv_packet_data_callback[dup]) { /* if we added trailing SYNs, don't include them in the CRC calc */ crcoffset = (dup_kmc[dup] ? 0 : TRAILING_SYNS); dup_rxcsr[dup] |= RXCSR_M_RXACT; -dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER; +if (UNIBUS) + dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER; +else + dup_rxdbuf[dup] &= ~RXDBUF_M_DPV_RCRCER; dup_rxdbuf[dup] &= ~RXDBUF_M_RXDBUF; dup_rxdbuf[dup] |= dup_rcvpacket[dup][dup_rcvpkinoff[dup]++]; dup_rxcsr[dup] |= RXCSR_M_RXDONE; -if ( ((dup_rcvpkinoff[dup] == 8) || - (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset)) && - (0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup]))) - dup_rxdbuf[dup] |= RXDBUF_M_RCRCER; -else - dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER; +if (UNIBUS) { + if ( ((dup_rcvpkinoff[dup] == 8) || + (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset)) && + (0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup]))) + dup_rxdbuf[dup] |= RXDBUF_M_RCRCER; + else + dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER; +} else { + if ( ((dup_rcvpkinoff[dup] == 6) || + (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset-2)) && + (0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup]+2))) + dup_rxdbuf[dup] |= RXDBUF_M_DPV_RCRCER; + else + dup_rxdbuf[dup] &= ~RXDBUF_M_DPV_RCRCER; +} if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]) { dup_rcvpkinoff[dup] = dup_rcvpkbytes[dup] = 0; dup_rxcsr[dup] &= ~RXCSR_M_RXACT; @@ -994,14 +1328,20 @@ return SCPE_OK; /* service routine to delay device activity */ + static t_stat dup_svc (UNIT *uptr) { DEVICE *dptr = DUPDPTR; int32 dup = (int32)(uptr-dptr->units); TMLN *lp = &dup_desc.ldsc[dup]; +t_bool txdone; sim_debug(DBG_TRC, DUPDPTR, "dup_svc(dup=%d)\n", dup); -if (!(dup_txcsr[dup] & TXCSR_M_TXDONE) && (!tmxr_tpbusyln (lp))) { +if (UNIBUS) + txdone = !(dup_txcsr[dup] & TXCSR_M_TXDONE); +else + txdone = !(dup_txcsr[dup] & TXCSR_M_DPV_TBEMPTY); +if (txdone && (!tmxr_tpbusyln (lp))) { uint8 data = dup_txdbuf[dup] & TXDBUF_M_TXDBUF; dup_put_msg_bytes (dup, &data, (dup_txdbuf[dup] & TXDBUF_M_TEOM) && (dptr == &dup_dev) ? 0 : 1, dup_txdbuf[dup] & TXDBUF_M_TSOM, (dup_txdbuf[dup] & TXDBUF_M_TEOM)); @@ -1033,7 +1373,10 @@ if ((tmxr_tpbusyln (lp) || dup_xmtpkbytes[dup]) && (lp->xmte || (!lp->conn))) { sim_activate_notbefore (uptr, dup_xmtpkstart[dup] + (uint32)((tmr_poll*clk_tps)*((double)dup_xmtpkbytes[dup]*8)/dup_speed[dup])); } else { - dup_txcsr[dup] &= ~TXCSR_M_TXACT; /* Set idle */ + if (UNIBUS) + dup_txcsr[dup] &= ~TXCSR_M_TXACT; /* Set idle */ + else + dup_txcsr[dup] &= ~TXCSR_M_DPV_TXACT; /* Set idle */ dup_xmtpkbytes[dup] = 0; dup_xmtpkdelaying[dup] = 0; if (dup_xmt_complete_callback[dup]) @@ -1048,7 +1391,7 @@ return SCPE_OK; static t_stat dup_poll_svc (UNIT *uptr) { -int32 dup, active, attached; + int32 dup, active, attached, charmode; sim_debug(DBG_TRC, DUPDPTR, "dup_poll_svc()\n"); @@ -1072,14 +1415,16 @@ for (dup=active=attached=0; dup < dup_desc.lines; dup++) { uint16 size; t_stat r; - if (dup_parcsr[dup] & PARCSR_M_DECMODE) + charmode = ((UNIBUS) ? (dup_parcsr[dup] & PARCSR_M_DECMODE) : (dup_parcsr[dup] & PARCSR_M_DPV_PROTSEL)); + + if (charmode) r = ddcmp_tmxr_get_packet_ln (lp, &buf, &size, dup_corruption[dup]); else { size_t size_t_size; r = tmxr_get_packet_ln (lp, &buf, &size_t_size); size = (uint16)size_t_size; - } + } /* in DEC mode add some SYN bytes to the end to deal with host drivers that implement the DDCMP CRC performance optimisation (DDCMP V4.0 section 5.1.2) */ if ((r == SCPE_OK) && (buf)) { @@ -1089,7 +1434,7 @@ for (dup=active=attached=0; dup < dup_desc.lines; dup++) { } memcpy (dup_rcvpacket[dup], buf, size); dup_rcvpkbytes[dup] = size; - if (!dup_kmc[dup] && (dup_parcsr[dup] & PARCSR_M_DECMODE)) { + if (!dup_kmc[dup] && charmode) { memcpy(&(dup_rcvpacket[dup][size]), tsyns, TRAILING_SYNS); dup_rcvpkbytes[dup] += TRAILING_SYNS ; } @@ -1190,7 +1535,7 @@ sim_debug(DBG_TRC, DUPDPTR, "dup_clear(dup=%d,flag=%d)\n", dup, flag); dup_rxdbuf[dup] = 0; /* silo empty */ dup_txdbuf[dup] = 0; dup_parcsr[dup] = 0; /* no params */ -dup_txcsr[dup] = TXCSR_M_TXDONE; /* clear CSR */ +dup_txcsr[dup] = ((UNIBUS) ? TXCSR_M_TXDONE : TXCSR_M_DPV_TBEMPTY); /* clear CSR */ dup_wait[dup] = DUP_WAIT; /* initial/default byte delay */ if (flag) { /* INIT? clr all */ dup_rxcsr[dup] = 0;