From 596cb3f5801cd6899fd61fc7f5d745adfc3d71a7 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 2 Jun 2013 13:19:23 -0700 Subject: [PATCH] Added needed DUP interfaces to allow use by KMC11/KDP. --- PDP11/pdp11_ddcmp.h | 100 ++++++++++++++++++++++++++++++++- PDP11/pdp11_dup.c | 134 +++++++++++--------------------------------- PDP11/pdp11_dup.h | 3 + 3 files changed, 136 insertions(+), 101 deletions(-) diff --git a/PDP11/pdp11_ddcmp.h b/PDP11/pdp11_ddcmp.h index 8d6e8d44..6ac3f1a9 100644 --- a/PDP11/pdp11_ddcmp.h +++ b/PDP11/pdp11_ddcmp.h @@ -41,7 +41,105 @@ /* Support routines */ -void ddcmp_packet_trace (uint32 reason, DEVICE *dptr, const char *txt, const uint8 *msg, int32 len, t_bool detail); +/* crc16 polynomial x^16 + x^15 + x^2 + 1 (0xA001) CCITT LSB */ +static uint16 crc16_nibble[16] = { + 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, + 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400, + }; + +static uint16 ddcmp_crc16(uint16 crc, const void* vbuf, size_t len) +{ +const unsigned char* buf = (const unsigned char*)vbuf; + +while(0 != len--) { + crc = (crc>>4) ^ crc16_nibble[(*buf ^ crc) & 0xF]; + crc = (crc>>4) ^ crc16_nibble[((*buf++)>>4 ^ crc) & 0xF]; + }; +return(crc); +} + +/* Debug routines */ + +#include + +static void ddcmp_packet_trace (uint32 reason, DEVICE *dptr, const char *txt, const uint8 *msg, int32 len, t_bool detail) +{ +if (sim_deb && dptr && (reason & dptr->dctrl)) { + sim_debug(reason, dptr, "%s len: %d\n", txt, len); + if (detail) { + int i, same, group, sidx, oidx; + char outbuf[80], strbuf[18]; + static char hex[] = "0123456789ABCDEF"; + + switch (msg[0]) { + case DDCMP_SOH: /* Data Message */ + sim_debug (reason, dptr, "Data Message, Link: %d, Count: %d, Resp: %d, Num: %d, HDRCRC: %s, DATACRC: %s\n", msg[2]>>6, ((msg[2] & 0x3F) << 8)|msg[1], msg[3], msg[4], + (0 == ddcmp_crc16 (0, msg, 8)) ? "OK" : "BAD", (0 == ddcmp_crc16 (0, msg+8, 2+(((msg[2] & 0x3F) << 8)|msg[1]))) ? "OK" : "BAD"); + break; + case DDCMP_ENQ: /* Control Message */ + sim_debug (reason, dptr, "Control: Type: %d ", msg[1]); + switch (msg[1]) { + case 1: /* ACK */ + sim_debug (reason, dptr, "(ACK) ACKSUB: %d, Link: %d, Resp: %d\n", msg[2] & 0x3F, msg[2]>>6, msg[3]); + break; + case 2: /* NAK */ + sim_debug (reason, dptr, "(NAK) Reason: %d, Link: %d, Resp: %d\n", msg[2] & 0x3F, msg[2]>>6, msg[3]); + break; + case 3: /* REP */ + sim_debug (reason, dptr, "(REP) REPSUB: %d, Link: %d, Num: %d\n", msg[2] & 0x3F, msg[2]>>6, msg[4]); + break; + case 6: /* STRT */ + sim_debug (reason, dptr, "(STRT) STRTSUB: %d, Link: %d\n", msg[2] & 0x3F, msg[2]>>6); + break; + case 7: /* STACK */ + sim_debug (reason, dptr, "(STACK) STCKSUB: %d, Link: %d\n", msg[2] & 0x3F, msg[2]>>6); + break; + default: /* Unknown */ + sim_debug (reason, dptr, "(Unknown=0%o)\n", msg[1]); + break; + } + if (len != 8) { + sim_debug (reason, dptr, "Unexpected Control Message Length: %d expected 8\n", len); + } + if (0 != ddcmp_crc16 (0, msg, len)) { + sim_debug (reason, dptr, "Unexpected Message CRC\n"); + } + break; + case DDCMP_DLE: /* Maintenance Message */ + sim_debug (reason, dptr, "Maintenance Message, Link: %d, Count: %d, HDRCRC: %s, DATACRC: %s\n", msg[2]>>6, ((msg[2] & 0x3F) << 8)| msg[1], + (0 == ddcmp_crc16 (0, msg, 8)) ? "OK" : "BAD", (0 == ddcmp_crc16 (0, msg+8, 2+(((msg[2] & 0x3F) << 8)| msg[1]))) ? "OK" : "BAD"); + break; + } + for (i=same=0; i 0) && (0 == memcmp(&msg[i], &msg[i-16], 16))) { + ++same; + continue; + } + if (same > 0) { + sim_debug(reason, dptr, "%04X thru %04X same as above\n", i-(16*same), i-1); + same = 0; + } + group = (((len - i) > 16) ? 16 : (len - i)); + for (sidx=oidx=0; sidx>4)&0xf]; + outbuf[oidx++] = hex[msg[i+sidx]&0xf]; + if (isprint(msg[i+sidx])) + strbuf[sidx] = msg[i+sidx]; + else + strbuf[sidx] = '.'; + } + outbuf[oidx] = '\0'; + strbuf[sidx] = '\0'; + sim_debug(reason, dptr, "%04X%-48s %s\n", i, outbuf, strbuf); + } + if (same > 0) { + sim_debug(reason, dptr, "%04X thru %04X same as above\n", i-(16*same), len-1); + } + } + } +} + uint16 ddcmp_crc16(uint16 crc, const void* vbuf, size_t len); #endif /* PDP11_DDCMP_H_ */ diff --git a/PDP11/pdp11_dup.c b/PDP11/pdp11_dup.c index cf961ee6..7f99d8c5 100644 --- a/PDP11/pdp11_dup.c +++ b/PDP11/pdp11_dup.c @@ -51,7 +51,6 @@ #include "sim_tmxr.h" #include "pdp11_ddcmp.h" #include "pdp11_dup.h" -#include #if !defined(DUP_LINES) #define DUP_LINES 8 @@ -99,8 +98,6 @@ t_stat dup_reset (DEVICE *dptr); t_stat dup_attach (UNIT *uptr, char *ptr); t_stat dup_detach (UNIT *uptr); t_stat dup_clear (int32 dup, t_bool flag); -void ddcmp_packet_trace (uint32 reason, DEVICE *dptr, const char *txt, const uint8 *msg, int32 len, t_bool detail); -uint16 ddcmp_crc16(uint16 crc, const void* vbuf, size_t len); int32 dup_rxinta (void); int32 dup_txinta (void); void dup_update_rcvi (void); @@ -623,11 +620,16 @@ if ((dup_rxcsr[dup] & RXCSR_M_DSCHNG) && return SCPE_OK; } +/* + * Public routines for use by other devices (i.e. KDP11) + */ + int32 dup_csr_to_linenum (int32 CSRPA) { DEVICE *dptr = DUPDPTR; DIB *dib = (DIB *)dptr->ctxt; +CSRPA += IOPAGEBASE; if ((dib->ba > (uint32)CSRPA) || ((uint32)CSRPA > (dib->ba + dib->lnt))) return -1; @@ -636,15 +638,44 @@ return ((uint32)CSRPA - dib->ba)/dib->lnt; void dup_set_callback_mode (int32 dup, PACKET_RECEIVE_CALLBACK receive, PACKET_TRANSMIT_COMPLETE_CALLBACK transmit) { +if ((dup < 0) || (dup >= dup_desc.lines)) + return; dup_rcv_packet_callback[dup] = receive; dup_xmt_complete_callback[dup] = transmit; } int32 dup_get_line_speed (int32 dup) { +if ((dup < 0) || (dup >= dup_desc.lines)) + return -1; return dup_speed[dup]; } +int32 dup_get_DCD (int32 dup) +{ +if ((dup < 0) || (dup >= dup_desc.lines)) + return -1; +return (dup_rxcsr[dup] & RXCSR_M_DCD) ? 1 : 0; +} + +t_stat dup_set_DTR (int32 dup, t_bool state) +{ +if ((dup < 0) || (dup >= dup_desc.lines)) + return SCPE_IERR; +dup_set_modem (dup, state ? (RXCSR_M_DTR | RXCSR_M_RTS) : 0); +return SCPE_OK; +} + +t_stat dup_set_DDCMP (int32 dup, t_bool state) +{ +if ((dup < 0) || (dup >= dup_desc.lines)) + return SCPE_IERR; +dup_parcsr[dup] &= ~PARCSR_M_NOCRC; +dup_parcsr[dup] |= (state ? 0: PARCSR_M_NOCRC); +dup_parcsr[dup] &= ~PARCSR_M_DECMODE; +dup_parcsr[dup] |= (state ? PARCSR_M_DECMODE : 0); +return SCPE_OK; +} t_stat dup_rcv_byte (int32 dup) { @@ -862,86 +893,6 @@ else { return SCPE_OK; } -/* Debug routines */ - -void ddcmp_packet_trace (uint32 reason, DEVICE *dptr, const char *txt, const uint8 *msg, int32 len, t_bool detail) -{ -if (sim_deb && dptr && (reason & dptr->dctrl)) { - sim_debug(reason, dptr, "%s len: %d\n", txt, len); - if (detail) { - int i, same, group, sidx, oidx; - char outbuf[80], strbuf[18]; - static char hex[] = "0123456789ABCDEF"; - - switch (msg[0]) { - case DDCMP_SOH: /* Data Message */ - sim_debug (reason, dptr, "Data Message, Link: %d, Count: %d, Resp: %d, Num: %d, HDRCRC: %s, DATACRC: %s\n", msg[2]>>6, ((msg[2] & 0x3F) << 8)|msg[1], msg[3], msg[4], - (0 == ddcmp_crc16 (0, msg, 8)) ? "OK" : "BAD", (0 == ddcmp_crc16 (0, msg+8, 2+(((msg[2] & 0x3F) << 8)|msg[1]))) ? "OK" : "BAD"); - break; - case DDCMP_ENQ: /* Control Message */ - sim_debug (reason, dptr, "Control: Type: %d ", msg[1]); - switch (msg[1]) { - case 1: /* ACK */ - sim_debug (reason, dptr, "(ACK) ACKSUB: %d, Link: %d, Resp: %d\n", msg[2] & 0x3F, msg[2]>>6, msg[3]); - break; - case 2: /* NAK */ - sim_debug (reason, dptr, "(NAK) Reason: %d, Link: %d, Resp: %d\n", msg[2] & 0x3F, msg[2]>>6, msg[3]); - break; - case 3: /* REP */ - sim_debug (reason, dptr, "(REP) REPSUB: %d, Link: %d, Num: %d\n", msg[2] & 0x3F, msg[2]>>6, msg[4]); - break; - case 6: /* STRT */ - sim_debug (reason, dptr, "(STRT) STRTSUB: %d, Link: %d\n", msg[2] & 0x3F, msg[2]>>6); - break; - case 7: /* STACK */ - sim_debug (reason, dptr, "(STACK) STCKSUB: %d, Link: %d\n", msg[2] & 0x3F, msg[2]>>6); - break; - default: /* Unknown */ - sim_debug (reason, dptr, "(Unknown=0%o)\n", msg[1]); - break; - } - if (len != 8) { - sim_debug (reason, dptr, "Unexpected Control Message Length: %d expected 8\n", len); - } - if (0 != ddcmp_crc16 (0, msg, len)) { - sim_debug (reason, dptr, "Unexpected Message CRC\n"); - } - break; - case DDCMP_DLE: /* Maintenance Message */ - sim_debug (reason, dptr, "Maintenance Message, Link: %d, Count: %d, HDRCRC: %s, DATACRC: %s\n", msg[2]>>6, ((msg[2] & 0x3F) << 8)| msg[1], - (0 == ddcmp_crc16 (0, msg, 8)) ? "OK" : "BAD", (0 == ddcmp_crc16 (0, msg+8, 2+(((msg[2] & 0x3F) << 8)| msg[1]))) ? "OK" : "BAD"); - break; - } - for (i=same=0; i 0) && (0 == memcmp(&msg[i], &msg[i-16], 16))) { - ++same; - continue; - } - if (same > 0) { - sim_debug(reason, dptr, "%04X thru %04X same as above\n", i-(16*same), i-1); - same = 0; - } - group = (((len - i) > 16) ? 16 : (len - i)); - for (sidx=oidx=0; sidx>4)&0xf]; - outbuf[oidx++] = hex[msg[i+sidx]&0xf]; - if (isprint(msg[i+sidx])) - strbuf[sidx] = msg[i+sidx]; - else - strbuf[sidx] = '.'; - } - outbuf[oidx] = '\0'; - strbuf[sidx] = '\0'; - sim_debug(reason, dptr, "%04X%-48s %s\n", i, outbuf, strbuf); - } - if (same > 0) { - sim_debug(reason, dptr, "%04X thru %04X same as above\n", i-(16*same), len-1); - } - } - } -} - /* Interrupt routines */ void dup_clr_rxint (int32 dup) @@ -1221,20 +1172,3 @@ char *dup_description (DEVICE *dptr) return (UNIBUS) ? "DUP11 bit synchronous interface" : "DPV11 bit synchronous interface"; } - -/* crc16 polynomial x^16 + x^15 + x^2 + 1 (0xA001) CCITT LSB */ -static uint16 crc16_nibble[16] = { - 0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401, - 0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400, - }; - -uint16 ddcmp_crc16(uint16 crc, const void* vbuf, size_t len) -{ -const unsigned char* buf = (const unsigned char*)vbuf; - -while(0 != len--) { - crc = (crc>>4) ^ crc16_nibble[(*buf ^ crc) & 0xF]; - crc = (crc>>4) ^ crc16_nibble[((*buf++)>>4 ^ crc) & 0xF]; - }; -return(crc); -} diff --git a/PDP11/pdp11_dup.h b/PDP11/pdp11_dup.h index 1d7e4f66..4e49d603 100644 --- a/PDP11/pdp11_dup.h +++ b/PDP11/pdp11_dup.h @@ -38,6 +38,9 @@ typedef void (*PACKET_RECEIVE_CALLBACK)(int32 dup, uint8 *buf, size_t len); typedef void (*PACKET_TRANSMIT_COMPLETE_CALLBACK)(int32 dup, int status); int32 dup_get_line_speed (int32 dup); +int32 dup_get_DCD (int32 dup); +t_stat dup_set_DTR (int32 dup, t_bool state); +t_stat dup_set_DDCMP (int32 dup, t_bool state); int32 dup_csr_to_linenum (int32 CSRPA); void dup_set_callback_mode (int32 dup, PACKET_RECEIVE_CALLBACK receive, PACKET_TRANSMIT_COMPLETE_CALLBACK transmit);