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 */
|
/* 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);
|
uint16 ddcmp_crc16(uint16 crc, const void* vbuf, size_t len);
|
||||||
|
|
||||||
#endif /* PDP11_DDCMP_H_ */
|
#endif /* PDP11_DDCMP_H_ */
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#include "sim_tmxr.h"
|
#include "sim_tmxr.h"
|
||||||
#include "pdp11_ddcmp.h"
|
#include "pdp11_ddcmp.h"
|
||||||
#include "pdp11_dup.h"
|
#include "pdp11_dup.h"
|
||||||
#include <ctype.h>
|
|
||||||
|
|
||||||
#if !defined(DUP_LINES)
|
#if !defined(DUP_LINES)
|
||||||
#define DUP_LINES 8
|
#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_attach (UNIT *uptr, char *ptr);
|
||||||
t_stat dup_detach (UNIT *uptr);
|
t_stat dup_detach (UNIT *uptr);
|
||||||
t_stat dup_clear (int32 dup, t_bool flag);
|
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_rxinta (void);
|
||||||
int32 dup_txinta (void);
|
int32 dup_txinta (void);
|
||||||
void dup_update_rcvi (void);
|
void dup_update_rcvi (void);
|
||||||
|
@ -623,11 +620,16 @@ if ((dup_rxcsr[dup] & RXCSR_M_DSCHNG) &&
|
||||||
return SCPE_OK;
|
return SCPE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Public routines for use by other devices (i.e. KDP11)
|
||||||
|
*/
|
||||||
|
|
||||||
int32 dup_csr_to_linenum (int32 CSRPA)
|
int32 dup_csr_to_linenum (int32 CSRPA)
|
||||||
{
|
{
|
||||||
DEVICE *dptr = DUPDPTR;
|
DEVICE *dptr = DUPDPTR;
|
||||||
DIB *dib = (DIB *)dptr->ctxt;
|
DIB *dib = (DIB *)dptr->ctxt;
|
||||||
|
|
||||||
|
CSRPA += IOPAGEBASE;
|
||||||
if ((dib->ba > (uint32)CSRPA) || ((uint32)CSRPA > (dib->ba + dib->lnt)))
|
if ((dib->ba > (uint32)CSRPA) || ((uint32)CSRPA > (dib->ba + dib->lnt)))
|
||||||
return -1;
|
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)
|
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_rcv_packet_callback[dup] = receive;
|
||||||
dup_xmt_complete_callback[dup] = transmit;
|
dup_xmt_complete_callback[dup] = transmit;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 dup_get_line_speed (int32 dup)
|
int32 dup_get_line_speed (int32 dup)
|
||||||
{
|
{
|
||||||
|
if ((dup < 0) || (dup >= dup_desc.lines))
|
||||||
|
return -1;
|
||||||
return dup_speed[dup];
|
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)
|
t_stat dup_rcv_byte (int32 dup)
|
||||||
{
|
{
|
||||||
|
@ -862,86 +893,6 @@ else {
|
||||||
return SCPE_OK;
|
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 */
|
/* Interrupt routines */
|
||||||
|
|
||||||
void dup_clr_rxint (int32 dup)
|
void dup_clr_rxint (int32 dup)
|
||||||
|
@ -1221,20 +1172,3 @@ char *dup_description (DEVICE *dptr)
|
||||||
return (UNIBUS) ? "DUP11 bit synchronous interface" :
|
return (UNIBUS) ? "DUP11 bit synchronous interface" :
|
||||||
"DPV11 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);
|
typedef void (*PACKET_TRANSMIT_COMPLETE_CALLBACK)(int32 dup, int status);
|
||||||
|
|
||||||
int32 dup_get_line_speed (int32 dup);
|
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);
|
int32 dup_csr_to_linenum (int32 CSRPA);
|
||||||
|
|
||||||
void dup_set_callback_mode (int32 dup, PACKET_RECEIVE_CALLBACK receive, PACKET_TRANSMIT_COMPLETE_CALLBACK transmit);
|
void dup_set_callback_mode (int32 dup, PACKET_RECEIVE_CALLBACK receive, PACKET_TRANSMIT_COMPLETE_CALLBACK transmit);
|
||||||
|
|
Loading…
Add table
Reference in a new issue