From c92033a7e283519be4bd1c3c3911a14aa0785ec5 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sat, 29 Jan 2022 13:05:41 -0500 Subject: [PATCH] KA10: added CH11 interface for KS10. --- PDP10/ks10_ch11.c | 577 ++++++++++++++++++++++++++++++++++++++++++++++ PDP10/kx10_defs.h | 6 +- makefile | 8 +- 3 files changed, 584 insertions(+), 7 deletions(-) create mode 100644 PDP10/ks10_ch11.c diff --git a/PDP10/ks10_ch11.c b/PDP10/ks10_ch11.c new file mode 100644 index 0000000..6888778 --- /dev/null +++ b/PDP10/ks10_ch11.c @@ -0,0 +1,577 @@ +/* ks10_ch11.c: CH11 Chaosnet interface. + ------------------------------------------------------------------------------ + + Copyright (c) 2022, Richard Cornwell, original by Lars Brinkhoff. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the name of the author shall not be + used in advertising or otherwise to promote the sale, use or other dealings + in this Software without prior written authorization from the author. + + ------------------------------------------------------------------------------ + +*/ + +#include "kx10_defs.h" +#include "sim_tmxr.h" + +#ifndef NUM_DEVS_CH11 +#define NUM_DEVS_CH11 0 +#endif + +#if (NUM_DEVS_CH11 > 0) + +/* CSR 076410 */ + +#define CSR_BSY 0000001 /* Xmit busy RO */ +#define CSR_LUP 0000002 /* Loop back R/W */ +#define CSR_SPY 0000004 /* Receive msgs from any destination R/W */ +#define CSR_RCL 0000010 /* Clear receiver WO */ +#define CSR_REN 0000020 /* Receiver int enable R/W */ +#define CSR_TEN 0000040 /* Transmitter int enable R/W */ +#define CSR_TAB 0000100 /* Transmit abort by conflict RO */ +#define CSR_TDN 0000200 /* Transmit Done */ +#define CSR_TCL 0000400 /* Clear transmitter WO */ +#define CSR_LOS 0017000 /* Lost count RO */ +#define CSR_RST 0020000 /* I/O Reset WO */ +#define CSR_ERR 0040000 /* CRC Error RO */ +#define CSR_RDN 0100000 /* Receive done */ + + +/* MY # 764142 Host number RO */ + +/* WBF 764142 Write bufffer WO */ + +/* RBF 764144 Read buffer RO */ + +/* RBC 764146 Receive bit counter RO */ + +/* XMT 764152 Read initiates transmission */ + + +#define CHUDP_HEADER 4 +#define IOLN_CH 020 +#define DBG_TRC 0x0001 +#define DBG_REG 0x0002 +#define DBG_PKT 0x0004 +#define DBG_DAT 0x0008 +#define DBG_INT 0x0010 +#define DBG_ERR 0x0020 + +int ch11_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access); +int ch11_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access); +uint16 ch11_checksum (const uint8 *p, int count); +int ch11_test_int (struct pdp_dib *dibp); +void ch11_validate (const uint8 *p, int count); +t_stat ch11_transmit (struct pdp_dib *dibp); +void ch11_receive (struct pdp_dib *dibp); +void ch11_clear (struct pdp_dib *dibp); +t_stat ch11_svc(UNIT *); +t_stat ch11_reset (DEVICE *); +t_stat ch11_attach (UNIT *, CONST char *); +t_stat ch11_detach (UNIT *); +t_stat ch11_show_peer (FILE* st, UNIT* uptr, int32 val, CONST void* desc); +t_stat ch11_set_peer (UNIT* uptr, int32 val, CONST char* cptr, void* desc); +t_stat ch11_show_node (FILE* st, UNIT* uptr, int32 val, CONST void* desc); +t_stat ch11_set_node (UNIT* uptr, int32 val, CONST char* cptr, void* desc); +t_stat ch11_help (FILE *, DEVICE *, UNIT *, int32, const char *); +t_stat ch11_help_attach (FILE *, DEVICE *, UNIT *, int32, const char *); +const char *ch11_description (DEVICE *); + +static char peer[256]; +int address; +static uint16 ch11_csr; +static int rx_count; +static int tx_count; +static uint8 rx_buffer[512+100]; +static uint8 tx_buffer[512+100]; + +TMLN ch11_lines[1] = { {0} }; +TMXR ch11_tmxr = { 1, NULL, 0, ch11_lines}; + +UNIT ch11_unit[] = { + {UDATA (&ch11_svc, UNIT_IDLE|UNIT_ATTABLE, 0) }, +}; + +REG ch11_reg[] = { + { ORDATA(CSR, ch11_csr, 16)}, + { GRDATAD(RXCNT, rx_count, 16, 16, 0, "Receive word count"), REG_FIT|REG_RO}, + { GRDATAD(TXCNT, tx_count, 16, 16, 0, "Transmit word count"), REG_FIT|REG_RO}, + { BRDATAD(RXBUF, rx_buffer, 16, 8, sizeof rx_buffer, "Receive packet buffer"), REG_FIT}, + { BRDATAD(TXBUF, tx_buffer, 16, 8, sizeof tx_buffer, "Transmit packet buffer"), REG_FIT}, + { BRDATAD(PEER, peer, 16, 8, sizeof peer, "Network peer"), REG_HRO}, + { GRDATAD(NODE, address, 16, 16, 0, "Node address"), REG_HRO}, + { NULL } }; + +MTAB ch11_mod[] = { + {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "addr", "addr", &uba_set_addr, uba_show_addr, + NULL, "Sets address of CH11" }, + {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "vect", "vect", &uba_set_vect, uba_show_vect, + NULL, "Sets vect of CH11" }, + {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "br", "br", &uba_set_br, uba_show_br, + NULL, "Sets br of CH11" }, + {MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "ctl", "ctl", &uba_set_ctl, uba_show_ctl, + NULL, "Sets uba of CH11" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "PEER", "PEER", + &ch11_set_peer, &ch11_show_peer, NULL, "Remote host name and port" }, + { MTAB_XTD|MTAB_VDV|MTAB_VALR, 0, "NODE", "NODE", + &ch11_set_node, &ch11_show_node, NULL, "Chaosnet node address" }, + { 0 }, +}; + +DIB ch11_dib = { 0764140, 017, 0270, 6, 3, &ch11_read, &ch11_write, NULL, 0, 0 }; + +DEBTAB ch11_debug[] = { + { "TRC", DBG_TRC, "Detailed trace" }, + { "REG", DBG_REG, "Hardware registers" }, + { "PKT", DBG_PKT, "Packets" }, + { "DAT", DBG_DAT, "Packet data" }, + { "INT", DBG_INT, "Interrupts" }, + { "ERR", DBG_ERR, "Error conditions" }, + { 0 } +}; + +DEVICE ch11_dev = { + "CH", ch11_unit, ch11_reg, ch11_mod, + 1, 8, 16, 1, 8, 16, + NULL, NULL, &ch11_reset, + NULL, &ch11_attach, &ch11_detach, + &ch11_dib, DEV_DISABLE | DEV_DIS | DEV_DEBUG | DEV_MUX, + 0, ch11_debug, NULL, NULL, &ch11_help, &ch11_help_attach, NULL, + &ch11_description + }; + +int +ch11_write(DEVICE *dptr, t_addr addr, uint16 data, int32 access) +{ + struct pdp_dib *dibp = (DIB *)dptr->ctxt; + uint16 temp; + int ln; + TMLN *lp; + int i; + + addr &= dibp->uba_mask; + sim_debug(DEBUG_DETAIL, dptr, "CH11 write %06o %06o %o\n", + addr, data, access); + + switch (addr & 016) { + case 000: /* CSR */ + if (data & CSR_RCL) { + sim_debug (DBG_REG, &ch11_dev, "Clear RX\n"); + ch11_csr &= ~CSR_RDN; + rx_count = 0; + ch11_lines[0].rcve = TRUE; + } + if (data & CSR_RST) { + sim_debug (DBG_REG, &ch11_dev, "Reset\n"); + ch11_clear (dibp); + } + if (data & CSR_TCL) { + sim_debug (DBG_REG, &ch11_dev, "Clear TX\n"); + tx_count = 0; + ch11_csr |= CSR_TDN; + } + ch11_csr &= ~(CSR_REN|CSR_TEN); + ch11_csr |= data & (CSR_REN|CSR_TEN); + break; + + case 002: /* Write buffer */ + ch11_csr &= ~CSR_TDN; + if (tx_count < 512) { + i = CHUDP_HEADER + tx_count; + tx_buffer[i] = (data >> 8) & 0xff; + tx_buffer[i+1] = data & 0xff; + tx_count+=2; + sim_debug (DBG_DAT, &ch11_dev, "Write buffer word %d:%02x %02x %06o %06o\n", + tx_count, tx_buffer[i], tx_buffer[i+1], data, ch11_csr); + } else { + sim_debug (DBG_ERR, &ch11_dev, "Write buffer overflow\n"); + } + break; + case 004: /* Read buffer */ + case 006: /* Bit count */ + case 012: /* Start transmission */ + case 010: /* Empty */ + case 014: /* Empty */ + case 016: /* Empty */ + break; + } + return 0; +} + +int +ch11_read(DEVICE *dptr, t_addr addr, uint16 *data, int32 access) +{ + struct pdp_dib *dibp = (DIB *)dptr->ctxt; + uint16 temp; + int ln; + TMLN *lp; + int i; + + addr &= dibp->uba_mask; + *data = 0; + switch (addr & 016) { + case 000: /* CSR */ + *data = ch11_csr; + break; + + case 002: /* Host number */ + *data = address; + break; + + case 004: /* Read buffer */ + if (rx_count == 0) { + *data = 0; + sim_debug (DBG_ERR, &ch11_dev, "Read empty buffer\n"); + } else { + i = 512-rx_count; + ch11_csr &= ~CSR_RDN; + *data = ((uint64)(rx_buffer[i]) & 0xff) << 8; + *data |= ((uint64)(rx_buffer[i+1]) & 0xff); + rx_count-=2; + sim_debug (DBG_DAT, &ch11_dev, "Read buffer word %d:%02x %02x %06o %06o\n", + rx_count, rx_buffer[i], rx_buffer[i+1], *data, ch11_csr); + } + break; + + case 006: /* Bit count */ + *data = ((512 - rx_count) - 1) & 07777; + break; + case 012: /* Start transmission */ + sim_debug (DBG_REG, &ch11_dev, "XMIT TX\n"); + ch11_transmit(dibp); + break; + + case 010: /* Empty */ + case 014: /* Empty */ + case 016: /* Empty */ + break; + } + sim_debug(DEBUG_DETAIL, dptr, "CH11 read %06o %06o %o\n", + addr, *data, access); + return 0; +} + +uint16 +ch11_checksum (const uint8 *p, int count) +{ + int32 sum = 0; + + while (count > 1) { + sum += (p[0]<<8) | p[1]; + p += 2; + count -= 2; + } + + if ( count > 0) + sum += p[0]; + + while (sum >> 16) + sum = (sum & 0xffff) + (sum >> 16); + + return (~sum) & 0xffff; +} + + +int +ch11_test_int (struct pdp_dib *dibp) +{ + if ((ch11_csr & (CSR_RDN|CSR_REN)) == (CSR_RDN|CSR_REN) || + (ch11_csr & (CSR_TDN|CSR_TEN)) == (CSR_TDN|CSR_TEN)) { + sim_debug (DBG_INT, &ch11_dev, "%s %s Interrupt\n", + ch11_csr & CSR_RDN ? "RX" : "", + ch11_csr & CSR_TDN ? "TX" : ""); + uba_set_irq(dibp); + } else { + /* Nothing found, so clear any flags */ + sim_debug(DEBUG_DETAIL, &dz_dev, "Clr irq\n"); + uba_clr_irq(dibp); + return 0; + } + return 1; +} + +void +ch11_validate (const uint8 *p, int count) +{ + uint16 chksum; + int size; + + sim_debug (DBG_TRC, &ch11_dev, "Packet opcode: %02x\n", p[0]); + sim_debug (DBG_TRC, &ch11_dev, "MBZ: %02x\n", p[1]); + sim_debug (DBG_TRC, &ch11_dev, "Forwarding count: %02x\n", p[2] >> 4); + size = ((p[2] & 0xF) << 8) + p[3]; + sim_debug (DBG_TRC, &ch11_dev, "Packet size: %03x\n", size); + sim_debug (DBG_TRC, &ch11_dev, "Destination address: %o\n", (p[4] << 8) + p[5]); + sim_debug (DBG_TRC, &ch11_dev, "Destination index: %02x\n", (p[6] << 8) + p[7]); + sim_debug (DBG_TRC, &ch11_dev, "Source address: %o\n", (p[8] << 8) + p[9]); + sim_debug (DBG_TRC, &ch11_dev, "Source index: %02x\n", (p[10] << 8) + p[11]); + sim_debug (DBG_TRC, &ch11_dev, "Packet number: %02x\n", (p[12] << 8) + p[13]); + sim_debug (DBG_TRC, &ch11_dev, "Acknowledgement: %02x\n", (p[14] << 8) + p[15]); + + if (p[1] != 0) + sim_debug (DBG_ERR, &ch11_dev, "Bad packet\n"); + + chksum = ch11_checksum (p, count); + if (chksum != 0) { + sim_debug (DBG_ERR, &ch11_dev, "Checksum error: %04x\n", chksum); + ch11_csr |= CSR_ERR; + } else + sim_debug (DBG_TRC, &ch11_dev, "Checksum: %05o\n", chksum); +} + +t_stat +ch11_transmit (struct pdp_dib *dibp) +{ + size_t len; + t_stat r; + int i = CHUDP_HEADER + tx_count; + uint16 chk; + + if (tx_count > (512 - CHUDP_HEADER)) { + sim_debug (DBG_PKT, &ch11_dev, "Pack size failed, %d bytes.\n", (int)tx_count); + ch11_csr |= CSR_ERR; + return SCPE_INCOMP; + } + tx_buffer[i] = tx_buffer[8+CHUDP_HEADER]; + tx_buffer[i+1] = tx_buffer[9+CHUDP_HEADER]; + tx_count += 2; + chk = ch11_checksum(tx_buffer + CHUDP_HEADER, tx_count); + tx_buffer[i+2] = (chk >> 8) & 0xff; + tx_buffer[i+3] = chk & 0xff; + tx_count += 2; + + tmxr_poll_tx (&ch11_tmxr); + len = CHUDP_HEADER + (size_t)tx_count; + r = tmxr_put_packet_ln (&ch11_lines[0], (const uint8 *)&tx_buffer, len); + if (r == SCPE_OK) { + sim_debug (DBG_PKT, &ch11_dev, "Sent UDP packet, %d bytes.\n", (int)len); + tmxr_poll_tx (&ch11_tmxr); + } else { + sim_debug (DBG_ERR, &ch11_dev, "Sending UDP failed: %d.\n", r); + ch11_csr |= CSR_TAB; + } + tx_count = 0; + ch11_test_int (dibp); + return SCPE_OK; +} + +void +ch11_receive (struct pdp_dib *dibp) +{ + size_t count; + const uint8 *p; + uint16 dest; + + tmxr_poll_rx (&ch11_tmxr); + if (tmxr_get_packet_ln (&ch11_lines[0], &p, &count) != SCPE_OK) { + sim_debug (DBG_ERR, &ch11_dev, "TMXR error receiving packet\n"); + return; + } + if (p == NULL) + return; + dest = ((p[4+CHUDP_HEADER] & 0xff) << 8) + (p[5+CHUDP_HEADER] & 0xff); + + sim_debug (DBG_PKT, &ch11_dev, "Received UDP packet, %d bytes for: %o\n", (int)count, dest); + /* Check if packet for us. */ + if (dest != address && dest != 0 && (ch11_csr & CSR_SPY) == 0) + return; + + if ((CSR_RDN & ch11_csr) == 0) { + count = (count + 1) & 0776; + memcpy (rx_buffer + (512 - count), p, count); + rx_count = count; + sim_debug (DBG_TRC, &ch11_dev, "Rx count, %d\n", rx_count); + ch11_validate (p + CHUDP_HEADER, count - CHUDP_HEADER); + ch11_csr |= CSR_RDN; + ch11_lines[0].rcve = FALSE; + sim_debug (DBG_TRC, &ch11_dev, "Rx off\n"); + ch11_test_int (dibp); + } else { + sim_debug (DBG_ERR, &ch11_dev, "Lost packet\n"); + if ((ch11_csr & CSR_LOS) != CSR_LOS) + ch11_csr = (ch11_csr & ~CSR_LOS) | (CSR_LOS & (ch11_csr + 01000)); + } +} + +void +ch11_clear (struct pdp_dib *dibp) +{ + ch11_csr = CSR_TDN; + rx_count = 0; + tx_count = 0; + + tx_buffer[0] = 1; /* CHUDP header */ + tx_buffer[1] = 1; + tx_buffer[2] = 0; + tx_buffer[3] = 0; + ch11_lines[0].rcve = TRUE; + + ch11_test_int (dibp); +} + +t_stat +ch11_svc(UNIT *uptr) +{ + DEVICE *dptr = find_dev_from_unit (uptr); + struct pdp_dib *dibp = (DIB *)dptr->ctxt; + + sim_clock_coschedule (uptr, 1000); + (void)tmxr_poll_conn (&ch11_tmxr); + if (ch11_lines[0].conn) { + ch11_receive (dibp); + } + if (tx_count == 0) + ch11_csr |= CSR_TDN; + ch11_test_int (dibp); + return SCPE_OK; +} + +t_stat ch11_attach (UNIT *uptr, CONST char *cptr) +{ + char linkinfo[256]; + t_stat r; + + ch11_dev.dctrl |= 0xF77F0000; + if (address == -1) + return sim_messagef (SCPE_2FARG, "Must set Chaosnet NODE address first \"SET CH NODE=val\"\n"); + if (peer[0] == '\0') + return sim_messagef (SCPE_2FARG, "Must set Chaosnet PEER \"SET CH PEER=host:port\"\n"); + + snprintf (linkinfo, sizeof(linkinfo), "Buffer=%d,UDP,%s,PACKET,Connect=%.*s,Line=0", + (int)sizeof tx_buffer, cptr, (int)(sizeof(linkinfo) - (45 + strlen(cptr))), peer); + r = tmxr_attach (&ch11_tmxr, uptr, linkinfo); + if (r != SCPE_OK) { + sim_debug (DBG_ERR, &ch11_dev, "TMXR error opening master\n"); + return sim_messagef (r, "Error Opening: %s\n", peer); + } + + uptr->filename = (char *)realloc (uptr->filename, 1 + strlen (cptr)); + strcpy (uptr->filename, cptr); + sim_activate (uptr, 1000); + return SCPE_OK; +} + +t_stat ch11_detach (UNIT *uptr) +{ + sim_cancel (uptr); + tmxr_detach (&ch11_tmxr, uptr); + return SCPE_OK; +} + +t_stat ch11_reset (DEVICE *dptr) +{ + struct pdp_dib *dibp = (DIB *)dptr->ctxt; + + ch11_clear (dibp); + if (ch11_unit[0].flags & UNIT_ATT) + sim_activate (&ch11_unit[0], 100); + return SCPE_OK; +} + +t_stat ch11_show_peer (FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + fprintf (st, "peer=%s", peer[0] ? peer : "unspecified"); + return SCPE_OK; +} + +t_stat ch11_set_peer (UNIT* uptr, int32 val, CONST char* cptr, void* desc) +{ + char host[256], port[256]; + + if ((cptr == NULL) || (*cptr == 0)) + return SCPE_ARG; + if (uptr->flags & UNIT_ATT) + return SCPE_ALATT; + if (sim_parse_addr (cptr, host, sizeof host, NULL, port, sizeof port, NULL, NULL)) + return SCPE_ARG; + if (host[0] == '\0') + return SCPE_ARG; + + strncpy (peer, cptr, sizeof(peer) - 1); + return SCPE_OK; +} + +t_stat ch11_show_node (FILE* st, UNIT* uptr, int32 val, CONST void* desc) +{ + if (address == -1) + fprintf (st, "node=unspecified"); + else + fprintf (st, "node=%o", address); + return SCPE_OK; +} + +t_stat ch11_set_node (UNIT* uptr, int32 val, CONST char* cptr, void* desc) +{ + t_stat r; + int x; + + if ((cptr == NULL) || (*cptr == 0)) + return SCPE_ARG; + if (uptr->flags & UNIT_ATT) + return SCPE_ALATT; + + x = (int)get_uint (cptr, 8, 0177777, &r); + if (r != SCPE_OK) + return SCPE_ARG; + + address = x; + return SCPE_OK; +} + +const char *ch11_description (DEVICE *dptr) +{ + return "CH11 Chaosnet interface"; +} + +t_stat ch11_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf (st, "CH11 Chaosnet interface\n\n"); + fprintf (st, "It's a network interface for MIT's Chaosnet. Options allow\n"); + fprintf (st, "control of the node address and network peer. The node address must\n"); + fprintf (st, "be a 16-bit octal number.\n"); + fprint_set_help (st, dptr); + fprintf (st, "\nConfigured options and controller state can be displayed with:\n"); + fprint_show_help (st, dptr); + fprintf (st, "\nThe CH11 simulation will encapsulate Chaosnet packets in UDP or TCP.\n"); + fprintf (st, "To access the network, the simulated Chaosnet interface must be attached\n"); + fprintf (st, "to a network peer.\n\n"); + ch11_help_attach (st, dptr, uptr, flag, cptr); + fprintf (st, "Software that runs on SIMH that supports this device include:\n"); + fprintf (st, " - ITS, the PDP-10 Incompatible Timesharing System\n"); + fprintf (st, "Outside SIMH, there's KLH10 and Lisp machine simulators. Various\n"); + fprintf (st, "encapsulating transport mechanisms exist: UDP, IP, Ethernet.\n\n"); + fprintf (st, "Documentation:\n"); + fprintf (st, "https://lm-3.github.io/amber.html#Hardware-Programming-Documentation\n\n"); + return SCPE_OK; +} + +t_stat ch11_help_attach (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) +{ + fprintf (st, "To configure CH11, first set the local Chaosnet node address, and\n"); + fprintf (st, "the peer:\n\n"); + fprintf (st, " sim> SET CH NODE=\n"); + fprintf (st, " sim> SET CH PEER=:\n\n"); + fprintf (st, "Then, attach a local port. By default UDP is used:\n\n"); + fprintf (st, " sim> ATTACH CH \n\n"); + fprintf (st, "If TCP is desired, add \"TCP\":\n\n"); + fprintf (st, " sim> ATTACH CH ,TCP\n\n"); + return SCPE_OK; +} +#endif diff --git a/PDP10/kx10_defs.h b/PDP10/kx10_defs.h index 772fb8f..cdc131f 100644 --- a/PDP10/kx10_defs.h +++ b/PDP10/kx10_defs.h @@ -740,15 +740,15 @@ extern void ka10_lights_clear_aux (int); #define NUM_DEVS_TTY 1 #define NUM_LINES_TTY 64 #define NUM_DEVS_NIA 1 -#define NUM_DEVS_DN 0 +#define NUM_DEVS_DN 1 #elif KS #define NUM_DEVS_LP20 1 #define NUM_DEVS_DZ 4 #define NUM_DEVS_TCU 1 #define NUM_DEVS_DUP 0 #if KS_ITS -#define NUM_DEVS_IMP 0 /* KS_ITS */ -#define NUM_DEVS_CH11 0 /* KS_ITS */ +#define NUM_DEVS_IMP 0 /* KS_ITS */ +#define NUM_DEVS_CH11 KS_ITS #endif #endif #if KA | KI diff --git a/makefile b/makefile index 88ec539..4965dbc 100644 --- a/makefile +++ b/makefile @@ -123,8 +123,8 @@ endif ifneq (,$(or $(findstring pdp6,${MAKECMDGOALS}),$(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS}))) VIDEO_USEFUL = true endif -# building the KA10, KI10 or KL10 networking can be used. -ifneq (,$(or $(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS},$(findstring pdp10-kl,${MAKECMDGOALS})))) +# building the KA10, KI10, KL10, KS10 networking can be used. +ifneq (,$(or $(findstring pdp10-ka,${MAKECMDGOALS}),$(findstring pdp10-ki,${MAKECMDGOALS},$(findstring pdp10-kl,${MAKECMDGOALS},$(findstring pdp10-ks,{MAKECMDGOALS}))))) NETWORK_USEFUL = true endif # building the SEL32 networking can be ussed @@ -2153,14 +2153,14 @@ KL10 = ${KL10D}/kx10_cpu.c ${KL10D}/kx10_sys.c ${KL10D}/kx10_df.c \ ${KL10D}/kx10_rp.c ${KL10D}/kx10_tu.c ${KL10D}/kx10_rs.c \ ${KL10D}/kx10_imp.c ${KL10D}/kl10_fe.c ${KL10D}/ka10_pd.c \ ${KL10D}/ka10_ch10.c ${KL10D}/kx10_lp.c ${KL10D}/kl10_nia.c \ - ${KL10D}/kx10_disk.c ${KL10D}/kl10_dn.c + ${KL10D}/kx10_disk.c KL10_OPT = -DKL=1 -DUSE_INT64 -I $(KL10D) ${NETWORK_OPT} KS10D = ${SIMHD}/PDP10 KS10 = ${KS10D}/kx10_cpu.c ${KS10D}/kx10_sys.c ${KS10D}/kx10_disk.c \ ${KS10D}/ks10_cty.c ${KS10D}/ks10_uba.c ${KS10D}/kx10_rh.c \ ${KS10D}/kx10_rp.c ${KS10D}/kx10_tu.c ${KS10D}/ks10_dz.c \ - ${KS10D}/ks10_tcu.c ${KS10D}/ks10_lp.c + ${KS10D}/ks10_tcu.c ${KS10D}/ks10_lp.c ${KS10D}/ks10_ch11.c KS10_OPT = -DKS=1 -DUSE_INT64 -I $(KS10D) ${NETWORK_OPT} ATT3B2D = ${SIMHD}/3B2