Added needed DUP interfaces to allow use by KMC11/KDP.
This commit is contained in:
parent
4064cc079a
commit
596cb3f580
3 changed files with 136 additions and 101 deletions
|
@ -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 <ctype.h>
|
||||
|
||||
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<len; i += 16) {
|
||||
if ((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<group; ++sidx) {
|
||||
outbuf[oidx++] = ' ';
|
||||
outbuf[oidx++] = hex[(msg[i+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_ */
|
||||
|
|
|
@ -51,7 +51,6 @@
|
|||
#include "sim_tmxr.h"
|
||||
#include "pdp11_ddcmp.h"
|
||||
#include "pdp11_dup.h"
|
||||
#include <ctype.h>
|
||||
|
||||
#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<len; i += 16) {
|
||||
if ((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<group; ++sidx) {
|
||||
outbuf[oidx++] = ' ';
|
||||
outbuf[oidx++] = hex[(msg[i+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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue