QBus VAX and PDP11: Add support for HDLC framing to DUP11/DPV11

This commit extends the existing DUP11/DPV11 support to add support for HDLC framing. There
is no requirement to support bit/byte stuffing, so the aim is simply to encapsulate/decapsulate
the datalink frame provided by the host driver.

DDCMP has been regression tested on VMS, RSX and TOPS20, and the HDLC mode was developed
and tested with VAX/VMS DECnet Phase V, only using the HDLC datalink implementation.

In theory this support is sufficient to allow Phase IV/V P.S.I and even VMS/SNA to be used,
but these remain to be demonstrated.
This commit is contained in:
Trevor Warwick 2022-08-03 10:38:17 +01:00
parent 58809e35b4
commit 1ab955be30

View file

@ -125,6 +125,7 @@ static t_stat dup_set_W5 (UNIT* uptr, int32 val, CONST char* cptr, void* desc);
static t_stat dup_show_W5 (FILE* st, UNIT* uptr, int32 val, CONST void* desc); static t_stat dup_show_W5 (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
static t_stat dup_set_W6 (UNIT* uptr, int32 val, CONST char* cptr, void* desc); static t_stat dup_set_W6 (UNIT* uptr, int32 val, CONST char* cptr, void* desc);
static t_stat dup_show_W6 (FILE* st, UNIT* uptr, int32 val, CONST void* desc); static t_stat dup_show_W6 (FILE* st, UNIT* uptr, int32 val, CONST void* desc);
static uint16 dup_crc_ccitt (uint8 const *bytes, uint32 len);
static t_stat dup_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); static t_stat dup_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
static t_stat dup_help_attach (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); static t_stat dup_help_attach (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr);
static const char *dup_description (DEVICE *dptr); static const char *dup_description (DEVICE *dptr);
@ -414,7 +415,7 @@ static BITFIELD dpv_parcsr_bits[] = {
#define PARCSR_V_DPV_ADSYNC 0 #define PARCSR_V_DPV_ADSYNC 0
#define PARCSR_S_DPV_ADSYNC 8 #define PARCSR_S_DPV_ADSYNC 8
#define PARCSR_M_DPV_ADSYNC (((1<<PARCSR_S_DPV_ADSYNC)-1)<<PARCSR_V_DPV_ADSYNC) #define PARCSR_M_DPV_ADSYNC (((1<<PARCSR_S_DPV_ADSYNC)-1)<<PARCSR_V_DPV_ADSYNC)
BITF(DPV_ERRDET,8), /* CRC Type */ BITF(DPV_ERRDET,3), /* CRC Type */
#define PARCSR_V_DPV_ERRDET 8 #define PARCSR_V_DPV_ERRDET 8
#define PARCSR_S_DPV_ERRDET 3 #define PARCSR_S_DPV_ERRDET 3
#define PARCSR_M_DPV_ERRDET (((1<<PARCSR_S_DPV_ERRDET)-1)<<PARCSR_V_DPV_ERRDET) #define PARCSR_M_DPV_ERRDET (((1<<PARCSR_S_DPV_ERRDET)-1)<<PARCSR_V_DPV_ERRDET)
@ -935,7 +936,7 @@ switch ((PA >> 1) & 03) { /* case on PA<2:1> */
if (dup_txcsr[dup] & TXCSR_M_DPV_SEND) { if (dup_txcsr[dup] & TXCSR_M_DPV_SEND) {
dup_txcsr[dup] |= TXCSR_M_DPV_TXACT; dup_txcsr[dup] |= TXCSR_M_DPV_TXACT;
sim_activate (dup_units+dup, dup_wait[dup]); sim_activate (dup_units+dup, dup_wait[dup]);
/* Go ahead, Abort not supported */ /* Go ahead not supported */
} }
} }
break; break;
@ -1205,10 +1206,13 @@ return SCPE_OK;
t_bool dup_put_msg_bytes (int32 dup, uint8 *bytes, size_t len, t_bool start, t_bool end) t_bool dup_put_msg_bytes (int32 dup, uint8 *bytes, size_t len, t_bool start, t_bool end)
{ {
t_bool breturn = FALSE; t_bool breturn = FALSE;
int32 charmode;
if ((dup < 0) || (dup >= dup_desc.lines) || (DUPDPTR->flags & DEV_DIS)) if ((dup < 0) || (dup >= dup_desc.lines) || (DUPDPTR->flags & DEV_DIS))
return FALSE; return FALSE;
charmode = ((UNIBUS) ? (dup_parcsr[dup] & PARCSR_M_DECMODE) : (dup_parcsr[dup] & PARCSR_M_DPV_PROTSEL));
if (!tmxr_tpbusyln(&dup_ldsc[dup])) { /* Not Busy sending? */ if (!tmxr_tpbusyln(&dup_ldsc[dup])) { /* Not Busy sending? */
if (start) { if (start) {
dup_xmtpkoffset[dup] = 0; dup_xmtpkoffset[dup] = 0;
@ -1220,6 +1224,7 @@ if (!tmxr_tpbusyln(&dup_ldsc[dup])) { /* Not Busy sending? */
dup_xmtpacket[dup] = (uint8 *)realloc (dup_xmtpacket[dup], dup_xmtpksize[dup]); dup_xmtpacket[dup] = (uint8 *)realloc (dup_xmtpacket[dup], dup_xmtpksize[dup]);
} }
/* Strip sync bytes at the beginning of a message */ /* Strip sync bytes at the beginning of a message */
if (dup_kmc[dup] || charmode)
while (len && (dup_xmtpkoffset[dup] == 0) && (bytes[0] == DDCMP_SYN)) { while (len && (dup_xmtpkoffset[dup] == 0) && (bytes[0] == DDCMP_SYN)) {
--len; --len;
++bytes; ++bytes;
@ -1237,14 +1242,25 @@ if (!tmxr_tpbusyln(&dup_ldsc[dup])) { /* Not Busy sending? */
dup_set_txint (dup); dup_set_txint (dup);
/* On End of Message, insert CRC and flag delivery start */ /* On End of Message, insert CRC and flag delivery start */
if (end) { if (end) {
uint16 crc16 = ddcmp_crc16 (0, dup_xmtpacket[dup], dup_xmtpkoffset[dup]); uint16 crc16;
if (charmode) {
crc16 = ddcmp_crc16 (0, dup_xmtpacket[dup], dup_xmtpkoffset[dup]);
dup_xmtpacket[dup][dup_xmtpkoffset[dup]++] = crc16 & 0xFF; dup_xmtpacket[dup][dup_xmtpkoffset[dup]++] = crc16 & 0xFF;
dup_xmtpacket[dup][dup_xmtpkoffset[dup]++] = crc16 >> 8; dup_xmtpacket[dup][dup_xmtpkoffset[dup]++] = crc16 >> 8;
if ((dup_xmtpkoffset[dup] > 8) || (dup_xmtpacket[dup][0] == DDCMP_ENQ)) { if ((dup_xmtpkoffset[dup] > 8) || (dup_xmtpacket[dup][0] == DDCMP_ENQ)) {
dup_xmtpkbytes[dup] = dup_xmtpkoffset[dup]; dup_xmtpkbytes[dup] = dup_xmtpkoffset[dup];
ddcmp_tmxr_put_packet_ln (&dup_ldsc[dup], dup_xmtpacket[dup], dup_xmtpkbytes[dup], dup_corruption[dup]); ddcmp_tmxr_put_packet_ln (&dup_ldsc[dup], dup_xmtpacket[dup], dup_xmtpkbytes[dup], dup_corruption[dup]);
} }
} else
{
crc16 = dup_crc_ccitt (dup_xmtpacket[dup], dup_xmtpkoffset[dup]);
/* this crc is transmitted in big-endian order */
dup_xmtpacket[dup][dup_xmtpkoffset[dup]++] = crc16 >> 8;
dup_xmtpacket[dup][dup_xmtpkoffset[dup]++] = crc16 & 0xFF;
dup_xmtpkbytes[dup] = dup_xmtpkoffset[dup];
tmxr_put_packet_ln (&dup_ldsc[dup], dup_xmtpacket[dup], dup_xmtpkbytes[dup]);
}
} }
breturn = TRUE; breturn = TRUE;
} }
@ -1279,7 +1295,7 @@ return SCPE_OK;
static t_stat dup_rcv_byte (int32 dup) static t_stat dup_rcv_byte (int32 dup)
{ {
int32 crcoffset; int32 crcoffset, bytemodeeom, charmode;
sim_debug (DBG_TRC, DUPDPTR, "dup_rcv_byte(dup=%d) - %s, byte %d of %d\n", dup, 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_rxcsr[dup] & RXCSR_M_RCVEN) ? "enabled" : "disabled",
@ -1292,33 +1308,73 @@ if (dup_rcv_packet_data_callback[dup]) {
dup_rcv_packet_data_callback[dup](dup, dup_rcvpkbytes[dup]); dup_rcv_packet_data_callback[dup](dup, dup_rcvpkbytes[dup]);
return SCPE_OK; return SCPE_OK;
} }
charmode = ((UNIBUS) ? (dup_parcsr[dup] & PARCSR_M_DECMODE) : (dup_parcsr[dup] & PARCSR_M_DPV_PROTSEL));
/* if we added trailing SYNs, don't include them in the CRC calc */ /* if we added trailing SYNs, don't include them in the CRC calc */
crcoffset = (dup_kmc[dup] ? 0 : TRAILING_SYNS); crcoffset = (dup_kmc[dup] ? 0 : TRAILING_SYNS);
dup_rxcsr[dup] |= RXCSR_M_RXACT; dup_rxcsr[dup] |= RXCSR_M_RXACT;
if (UNIBUS) if (UNIBUS)
dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER; dup_rxdbuf[dup] &= ~(RXDBUF_M_RCRCER|RXDBUF_M_RENDMSG|RXDBUF_M_RSTRMSG);
else else
dup_rxdbuf[dup] &= ~RXDBUF_M_DPV_RCRCER; dup_rxdbuf[dup] &= ~(RXDBUF_M_DPV_RCRCER|RXDBUF_M_DPV_RENDMSG|RXDBUF_M_DPV_RSTRMSG);
dup_rxdbuf[dup] &= ~RXDBUF_M_RXDBUF; dup_rxdbuf[dup] &= ~RXDBUF_M_RXDBUF;
dup_rxdbuf[dup] |= dup_rcvpacket[dup][dup_rcvpkinoff[dup]++]; dup_rxdbuf[dup] |= dup_rcvpacket[dup][dup_rcvpkinoff[dup]++];
dup_rxcsr[dup] |= RXCSR_M_RXDONE; dup_rxcsr[dup] |= RXCSR_M_RXDONE;
if (UNIBUS) { if (UNIBUS) { /* DUP */
if (charmode) { /* DDCMP */
if ( ((dup_rcvpkinoff[dup] == 8) || if ( ((dup_rcvpkinoff[dup] == 8) ||
(dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset)) && (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset)) &&
(0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup]))) (0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup])))
dup_rxdbuf[dup] |= RXDBUF_M_RCRCER; dup_rxdbuf[dup] |= RXDBUF_M_RCRCER;
else else
dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER; dup_rxdbuf[dup] &= ~RXDBUF_M_RCRCER;
} else { if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup])
dup_rcvpkinoff[dup] = dup_rcvpkbytes[dup] = 0;
}
else
{ /* HDLC */
/* set End Of Message on fake Flag that was added earlier */
if (dup_rcvpkinoff[dup] == dup_rcvpkbytes[dup]) {
dup_rxdbuf[dup] |= RXDBUF_M_RENDMSG;
/* check CRC only with EOM indication */
if (0 != dup_crc_ccitt (dup_rcvpacket[dup], dup_rcvpkinoff[dup]-1))
dup_rxdbuf[dup] |= RXDBUF_M_RCRCER;
}
/* set Start Of Message on first byte (primary mode only) */
if (dup_rcvpkinoff[dup] == 1)
dup_rxdbuf[dup] |= RXDBUF_M_RSTRMSG;
if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup])
dup_rcvpkinoff[dup] = dup_rcvpkbytes[dup] = 0;
}
}
else { /* DPV */
if (charmode) { /* DDCMP */
if ( ((dup_rcvpkinoff[dup] == 6) || if ( ((dup_rcvpkinoff[dup] == 6) ||
(dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset-2)) && (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]-crcoffset-2)) &&
(0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup]+2))) (0 == ddcmp_crc16 (0, dup_rcvpacket[dup], dup_rcvpkinoff[dup]+2)))
dup_rxdbuf[dup] |= RXDBUF_M_DPV_RCRCER; dup_rxdbuf[dup] |= RXDBUF_M_DPV_RCRCER;
else else
dup_rxdbuf[dup] &= ~RXDBUF_M_DPV_RCRCER; dup_rxdbuf[dup] &= ~RXDBUF_M_DPV_RCRCER;
if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup])
dup_rcvpkinoff[dup] = dup_rcvpkbytes[dup] = 0;
}
else { /* HDLC */
/* set End Of Message on last actual message byte, excluding the CRC */
if (dup_rcvpkinoff[dup] == dup_rcvpkbytes[dup] - 2) {
dup_rxdbuf[dup] |= RXDBUF_M_DPV_RENDMSG;
dup_rxcsr[dup] |= RXCSR_M_DPV_RSTARY;
/* check CRC only with EOM indication */
if (0 != dup_crc_ccitt (dup_rcvpacket[dup], dup_rcvpkinoff[dup] + 2))
dup_rxdbuf[dup] |= RXDBUF_M_DPV_RCRCER;
}
/* set Start Of Message on first byte (primary mode only) */
if (dup_rcvpkinoff[dup] == 1)
dup_rxdbuf[dup] |= RXDBUF_M_DPV_RSTRMSG;
/* DPV doesn't return the CRC bytes */
if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup] - 2 )
dup_rcvpkinoff[dup] = dup_rcvpkbytes[dup] = 0;
}
} }
if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]) { if (dup_rcvpkinoff[dup] >= dup_rcvpkbytes[dup]) {
dup_rcvpkinoff[dup] = dup_rcvpkbytes[dup] = 0;
dup_rxcsr[dup] &= ~RXCSR_M_RXACT; dup_rxcsr[dup] &= ~RXCSR_M_RXACT;
} }
if (dup_rxcsr[dup] & RXCSR_M_RXIE) if (dup_rxcsr[dup] & RXCSR_M_RXIE)
@ -1332,19 +1388,32 @@ return SCPE_OK;
static t_stat dup_svc (UNIT *uptr) static t_stat dup_svc (UNIT *uptr)
{ {
DEVICE *dptr = DUPDPTR; DEVICE *dptr = DUPDPTR;
int32 dup = (int32)(uptr-dptr->units); int32 dup = (int32)(uptr-dptr->units), charmode, putlen = 1;
TMLN *lp = &dup_desc.ldsc[dup]; TMLN *lp = &dup_desc.ldsc[dup];
t_bool txdone; t_bool txdone;
sim_debug(DBG_TRC, DUPDPTR, "dup_svc(dup=%d)\n", dup); sim_debug(DBG_TRC, DUPDPTR, "dup_svc(dup=%d)\n", dup);
if (UNIBUS) if (UNIBUS) {
txdone = !(dup_txcsr[dup] & TXCSR_M_TXDONE); txdone = !(dup_txcsr[dup] & TXCSR_M_TXDONE);
else charmode = (dup_parcsr[dup] & PARCSR_M_DECMODE);
if ((dup_txdbuf[dup] & TXDBUF_M_TEOM) ||
(!charmode && ((dup_txdbuf[dup] & TXDBUF_M_TSOM))))
putlen = 0;
}
else {
txdone = !(dup_txcsr[dup] & TXCSR_M_DPV_TBEMPTY); txdone = !(dup_txcsr[dup] & TXCSR_M_DPV_TBEMPTY);
charmode = (dup_parcsr[dup] & PARCSR_M_DPV_PROTSEL);
if (!charmode && (dup_txdbuf[dup] & TXDBUF_M_TSOM))
putlen = 0;
}
if (txdone && (!tmxr_tpbusyln (lp))) { if (txdone && (!tmxr_tpbusyln (lp))) {
uint8 data = dup_txdbuf[dup] & TXDBUF_M_TXDBUF; 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)); if (!charmode && (dup_txdbuf[dup] & TXDBUF_M_TABRT))
/* HDLC mode abort, just reset the current TX frame back to the start */
dup_put_msg_bytes (dup, &data, 0, TRUE, FALSE);
else
dup_put_msg_bytes (dup, &data, putlen, dup_txdbuf[dup] & TXDBUF_M_TSOM, (dup_txdbuf[dup] & TXDBUF_M_TEOM));
if (tmxr_tpbusyln (lp)) { /* Packet ready to send? */ if (tmxr_tpbusyln (lp)) { /* Packet ready to send? */
sim_debug(DBG_TRC, DUPDPTR, "dup_svc(dup=%d) - Packet Done %d bytes\n", dup, dup_xmtpkoffset[dup]); sim_debug(DBG_TRC, DUPDPTR, "dup_svc(dup=%d) - Packet Done %d bytes\n", dup, dup_xmtpkoffset[dup]);
} }
@ -1425,19 +1494,29 @@ for (dup=active=attached=0; dup < dup_desc.lines; dup++) {
r = tmxr_get_packet_ln (lp, &buf, &size_t_size); r = tmxr_get_packet_ln (lp, &buf, &size_t_size);
size = (uint16)size_t_size; size = (uint16)size_t_size;
} }
/* in DEC mode add some SYN bytes to the end to deal with host drivers that /* In HDLC mode, we need a minimum frame size of 1 byte + CRC
implement the DDCMP CRC performance optimisation (DDCMP V4.0 section 5.1.2) */ In DEC mode add some SYN bytes to the end to deal with host drivers that
if ((r == SCPE_OK) && (buf)) { implement the DDCMP CRC performance optimisation (DDCMP V4.0 section 5.1.2).
In HDLC mode on DUP only, add a flag because RENDMSG happens after the last actual frame character */
if ((r == SCPE_OK) && (buf) && ((charmode) || size > 3)) {
if (dup_rcvpksize[dup] < size + TRAILING_SYNS) { if (dup_rcvpksize[dup] < size + TRAILING_SYNS) {
dup_rcvpksize[dup] = size + TRAILING_SYNS; dup_rcvpksize[dup] = size + TRAILING_SYNS;
dup_rcvpacket[dup] = (uint8 *)realloc (dup_rcvpacket[dup], dup_rcvpksize[dup]); dup_rcvpacket[dup] = (uint8 *)realloc (dup_rcvpacket[dup], dup_rcvpksize[dup]);
} }
memcpy (dup_rcvpacket[dup], buf, size); memcpy (dup_rcvpacket[dup], buf, size);
dup_rcvpkbytes[dup] = size; dup_rcvpkbytes[dup] = size;
if (!dup_kmc[dup] && charmode) { if (!dup_kmc[dup]) {
if (charmode) {
memcpy(&(dup_rcvpacket[dup][size]), tsyns, TRAILING_SYNS); memcpy(&(dup_rcvpacket[dup][size]), tsyns, TRAILING_SYNS);
dup_rcvpkbytes[dup] += TRAILING_SYNS ; dup_rcvpkbytes[dup] += TRAILING_SYNS ;
} }
else {
if (UNIBUS) {
dup_rcvpacket[dup][size] = 0x7E;
dup_rcvpkbytes[dup] += 1 ;
}
}
}
dup_rcvpkinoff[dup] = 0; dup_rcvpkinoff[dup] = 0;
dup_rxcsr[dup] |= RXCSR_M_RXACT; dup_rxcsr[dup] |= RXCSR_M_RXACT;
dup_rcv_byte (dup); dup_rcv_byte (dup);
@ -1829,6 +1908,58 @@ dptr->numunits = newln + 1;
return dup_reset (dptr); /* setup lines and auto config */ return dup_reset (dptr); /* setup lines and auto config */
} }
/*
* Finding a definitive definition of the correct HDLC CRC is not easy. This
* one is the same calculation as in a couple of good quality public examples
* that both agree with each other, so hopefully it's the correct one.
*/
uint16 dup_crc_ccitt (uint8 const *bytes, uint32 len)
{ static uint16 const crc_ccitt_lookup[256] = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
uint32 i = 0;
uint16 crc = 0xffff;
while (i++ < len)
crc = ((crc << 8) ^ crc_ccitt_lookup[(crc >> 8) ^ *bytes++]);
/* sim_debug (DBG_TRC, DUPDPTR, "dup_crc_ccitt (len=%d, crc=0x%04x)\n",
(int)len, crc); */
return crc;
}
static t_stat dup_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) static t_stat dup_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr)
{ {
const char helpString[] = const char helpString[] =
@ -1839,8 +1970,8 @@ const char helpString[] =
" serial synchronous line. The original hardware is capable of handling\n" " serial synchronous line. The original hardware is capable of handling\n"
" a wide variety of protocols, including byte oriented protocols, such\n" " a wide variety of protocols, including byte oriented protocols, such\n"
" as DDCMP and BISYNC and bit-oriented protocols such as SDLC, HDLC\n" " as DDCMP and BISYNC and bit-oriented protocols such as SDLC, HDLC\n"
" and ADCCP. The emulated device currently only supports connections\n" " and ADCCP. The emulated device supports connections\n"
" using the DDCMP protocol.\n\n" " using the DDCMP or HDLC protocols.\n"
" The %D11 is ideally suited for interfacing the %1s system\n" " The %D11 is ideally suited for interfacing the %1s system\n"
" to medium-speed synchronous lines for remote batch, remote data\n" " to medium-speed synchronous lines for remote batch, remote data\n"
" collection, remote concentration and network applications. Multiple\n" " collection, remote concentration and network applications. Multiple\n"
@ -1851,7 +1982,7 @@ const char helpString[] =
" data rates. The maximum emulated rate is dependent on the host CPU's\n" " data rates. The maximum emulated rate is dependent on the host CPU's\n"
" available cycles.\n" " available cycles.\n"
"1 Hardware Description\n" "1 Hardware Description\n"
" The %1s %D11 consists of a microprocessor module and a synchronous line\n" " The %1s %D11 consists of a synchronous line\n"
" unit module.\n" " unit module.\n"
"2 $Registers\n" "2 $Registers\n"
"\n" "\n"
@ -1972,12 +2103,12 @@ const char helpString[] =
"1 Implementation\n" "1 Implementation\n"
" A real %D11 transports host generated protocol implemented data via a\n" " A real %D11 transports host generated protocol implemented data via a\n"
" synchronous connection, the emulated device makes a TCP (or UDP)\n" " synchronous connection, the emulated device makes a TCP (or UDP)\n"
" connection to another emulated device which either speaks DDCMP over the\n" " connection to another emulated device which either speaks DDCMP/HDLC over the\n"
" TCP connection directly, or interfaces to a simulated computer where the\n" " TCP/UDP connection directly, or interfaces to a simulated computer where the\n"
" operating system speaks the DDCMP protocol on the wire.\n" " operating system speaks the DDCMP protocol on the wire.\n"
"\n" "\n"
" The %D11 can be used for point-to-point DDCMP connections carrying\n" " The %D11 can be used for point-to-point DDCMP connections carrying\n"
" DECnet and other types of networking, e.g. from ULTRIX or DSM.\n" " DECnet, X.25 and other types of networking, e.g. from ULTRIX or DSM.\n"
"1 Debugging\n" "1 Debugging\n"
" The simulator has a number of debug options, these are:\n" " The simulator has a number of debug options, these are:\n"
"\n" "\n"