From dd7750b3ab51dc20da87c29ee25313aab65ecc7d Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 27 Jan 2019 14:24:00 -0500 Subject: [PATCH] IBM360: Added support for 2703 comm controller. --- IBM360/ibm360_chan.c | 2 + IBM360/ibm360_com.c | 430 +++++++++++++++++++++++++++---------------- IBM360/ibm360_defs.h | 1 + IBM360/ibm360_sys.c | 1 + 4 files changed, 272 insertions(+), 162 deletions(-) diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index c8d1a86..f443c8f 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -705,6 +705,8 @@ int haltio(uint16 addr) { uptr = find_chan_dev(chan_dev[chan]); if (uptr == 0) return 3; + sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x %x %x\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); if (ccw_cmd[chan]) { chan_byte[chan] = BUFF_CHNEND; return 2; diff --git a/IBM360/ibm360_com.c b/IBM360/ibm360_com.c index 4e8a613..11139ff 100644 --- a/IBM360/ibm360_com.c +++ b/IBM360/ibm360_com.c @@ -23,98 +23,55 @@ */ #include "ibm360_defs.h" +#include "sim_sock.h" +#include "sim_tmxr.h" #ifdef NUM_DEVS_COM -#define UNIT_COM UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE +#define UNIT_COM TT_MODE_7B /* u3 */ -#define DK_NOP 0x03 /* Nop operation */ -#define DK_RELEASE 0x17 /* Release from channel */ -#define DK_RESTORE 0x13 /* Restore */ -#define DK_SEEK 0x07 /* Seek */ -#define DK_SEEKCYL 0x0B /* Seek Cylinder */ -#define DK_SEEKHD 0x09 /* Seek Head */ -#define DK_SETMSK 0x1f /* Set file mask */ -#define DK_SPACE 0x0f /* Space record */ -#define DK_SRCH_HAEQ 0x39 /* Search HA equal */ -#define DK_SRCH_IDEQ 0x31 /* Search ID equal */ -#define DK_SRCH_IDGT 0x51 /* Search ID greater */ -#define DK_SRCH_IDGE 0x71 /* Search ID greater or equal */ -#define DK_SRCH_KYEQ 0x29 /* Search Key equal */ -#define DK_SRCH_KYGT 0x49 /* Search Key greater */ -#define DK_SRCH_KYGE 0x69 /* Search Key greater or equal */ -#define DK_RD_IPL 0x02 /* Read IPL record */ -#define DK_RD_HA 0x1A /* Read home address */ -#define DK_RD_CNT 0x12 /* Read count */ -#define DK_RD_R0 0x16 /* Read R0 */ -#define DK_RD_D 0x06 /* Read Data */ -#define DK_RD_KD 0x0e /* Read key and data */ -#define DK_RD_CKD 0x1e /* Read count, key and data */ -#define DK_WR_HA 0x19 /* Write home address */ -#define DK_WR_R0 0x15 /* Write R0 */ -#define DK_WR_D 0x05 /* Write Data */ -#define DK_WR_KD 0x0d /* Write key and data */ -#define DK_WR_CKD 0x1d /* Write count, key and data */ -#define DK_WR_SCKD 0x01 /* Write special count, key and data */ -#define DK_ERASE 0x11 /* Erase to end of track */ -#define DK_MT 0x80 /* Multi track flag */ +#define CMD_RD 0x02 /* Read in data from com line */ +#define CMD_WR 0x01 /* Write data to com line */ +#define CMD_DIAL 0x29 /* Dial call */ +#define CMD_BRK 0x0D /* Send break signal */ +#define CMD_PREP 0x06 /* Wait for incoming data */ +#define CMD_INH 0x0A /* Read data without timeout */ +#define CMD_SRCH 0x0E /* Wait for EOT character */ +#define CMD_ENB 0x27 /* Enable line */ +#define CMD_DIS 0x2F /* Disable line */ -#define DK_CYL_DIRTY 0x100 /* Current cylinder dirty */ - -#define DK_MSK_INHWR0 0x00 /* Inhbit writing of HA/R0 */ -#define DK_MSK_INHWRT 0x40 /* Inhbit all writes */ -#define DK_MSK_ALLWRU 0x80 /* Allow all updates */ -#define DK_MSK_ALLWRT 0xc0 /* Allow all writes */ -#define DK_MSK_WRT 0xc0 /* Write mask */ - -#define DK_MSK_SKALLSKR 0x00 /* Allow all seek/recal */ -#define DK_MSK_SKALLCLY 0x01 /* Allow cyl/head only */ -#define DK_MSK_SKALLHD 0x02 /* Allow head only */ -#define DK_MSK_SKNONE 0x03 /* Allow no seeks */ -#define DK_MSK_SK 0x03 /* Seek mask */ - - -/* u4 */ -/* Position around disk */ +/* u3 second byte */ +#define RECV 0x0100 /* Recieving data */ +#define SEND 0x0200 /* Sending data */ +#define ENAB 0x0400 /* Line enabled */ +#define POLL 0x0800 /* Waiting for connection */ /* u5 */ /* Sense byte 0 */ -#define SNS_CMDREJ 0x01 /* Command reject */ -#define SNS_INTVENT 0x02 /* Unit intervention required */ -#define SNS_BUSCHK 0x04 /* Parity error on bus */ -#define SNS_EQUCHK 0x08 /* Equipment check */ -#define SNS_DATCHK 0x10 /* Data Check */ -#define SNS_OVRRUN 0x20 /* Data overrun */ -#define SNS_TRKCND 0x40 /* Track Condition */ -#define SNS_SEEKCK 0x80 /* Seek Check */ - -/* Sense byte 1 */ -#define SNS_DCCNT 0x01 /* Data Check Count */ -#define SNS_TRKOVR 0x02 /* Track Overrun */ -#define SNS_ENDCYL 0x04 /* End of Cylinder */ -#define SNS_INVSEQ 0x08 /* Invalid Sequence */ -#define SNS_NOREC 0x10 /* No record found */ -#define SNS_WRP 0x20 /* Write Protect */ -#define SNS_ADDR 0x40 /* Missing Address Mark */ -#define SNS_OVRINC 0x80 /* Overflow Incomplete */ - -/* Sense byte 2 */ -#define SNS_BYTE2 0x00 /* Diags Use */ -/* Sense byte 3 */ -#define SNS_BYTE3 0x00 /* Diags Use */ +#define SNS_CMDREJ 0x80 /* Command reject */ +#define SNS_INTVENT 0x40 /* Unit intervention required */ +#define SNS_BUSCHK 0x20 /* Parity error on bus */ +#define SNS_EQUCHK 0x10 /* Equipment check */ +#define SNS_DATCHK 0x08 /* Data Check */ +#define SNS_OVRRUN 0x04 /* Data overrun */ +#define SNS_RECV 0x02 /* Receiving */ +#define SNS_TIMEOUT 0x01 /* Timeout */ /* u6 */ -uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ; -uint8 com_haltio(uint16 addr); -t_stat com_srv(UNIT *); -void com_ini(UNIT *, t_bool); -t_stat com_reset(DEVICE *); -t_stat com_attach(UNIT *, CONST char *); -t_stat com_detach(UNIT *); -t_stat com_boot(int32, DEVICE *); +uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) ; +uint8 coml_haltio(UNIT *uptr); +t_stat coml_srv(UNIT *uptr); +void coml_ini(UNIT *uptr, t_bool); +t_stat com_reset(DEVICE *dptr); +t_stat com_scan(UNIT *uptr); +t_stat com_attach(UNIT *uptr, CONST char *); +t_stat com_detach(UNIT *uptr); +TMLN com_ldsc[NUM_UNITS_COM]; +TMXR com_desc = { NUM_UNITS_COM, 0, 0, com_ldsc}; +int32 tmxr_poll = 10000; MTAB com_mod[] = { @@ -123,60 +80,79 @@ MTAB com_mod[] = { {0} }; -UNIT com_unit[] = { - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x030)}, /* 0 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x031)}, /* 1 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x032)}, /* 2 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x033)}, /* 3 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x034)}, /* 4 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x035)}, /* 5 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x036)}, /* 6 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x037)}, /* 7 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x038)}, /* 8 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x039)}, /* 9 */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03A)}, /* A */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03B)}, /* B */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03C)}, /* C */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03D)}, /* D */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03E)}, /* E */ - {UDATA(&com_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03F)}, /* F */ +MTAB coml_mod[] = { + { TT_MODE, TT_MODE_KSR, "KSR", "KSR", NULL }, + { TT_MODE, TT_MODE_7B, "7b", "7B", NULL }, + { TT_MODE, TT_MODE_8B, "8b", "8B", NULL }, + { TT_MODE, TT_MODE_7P, "7p", "7P", NULL }, + {0} }; -struct dib com_dib = { 0xF0, NUM_UNITS_MT, NULL, com_startcmd, NULL, com_unit, NULL}; +UNIT com_unit[] = { + {UDATA(&com_scan, UNIT_ATTABLE | UNIT_IDLE, 0)}, /* Line scanner */ +}; + +UNIT coml_unit[] = { + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x030)}, /* 0 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x031)}, /* 1 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x032)}, /* 2 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x033)}, /* 3 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x034)}, /* 4 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x035)}, /* 5 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x036)}, /* 6 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x037)}, /* 7 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x038)}, /* 8 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x039)}, /* 9 */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03A)}, /* A */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03B)}, /* B */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03C)}, /* C */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03D)}, /* D */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03E)}, /* E */ + {UDATA(&coml_srv, UNIT_COM, 0), 0, UNIT_ADDR(0x03F)}, /* F */ +}; + +struct dib com_dib = { 0xF0, NUM_UNITS_COM, NULL, coml_startcmd, + coml_haltio, coml_unit, coml_ini}; DEVICE com_dev = { "COM", com_unit, NULL, com_mod, - NUM_UNITS_COM, 8, 15, 1, 8, 8, - NULL, NULL, &com_reset, NULL, &com_attach, &com_detach, - &com_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug + NUM_DEVS_COM, 8, 15, 1, 8, 8, + NULL, NULL, com_reset, NULL, &com_attach, &com_detach, + NULL, DEV_MUX | DEV_DISABLE | DEV_DEBUG, 0, dev_debug }; +DEVICE coml_dev = { + "COML", coml_unit, NULL, coml_mod, + NUM_UNITS_COM, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, NULL, NULL, + &com_dib, DEV_DISABLE | DEV_DEBUG, 0, dev_debug +}; -uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { +uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { uint16 addr = GET_UADDR(uptr->u3); DEVICE *dptr = find_dev_from_unit(uptr); int unit = (uptr - dptr->units); uint8 ch; + sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd); if ((uptr->u3 & 0xff) != 0) { return SNS_BSY; } - sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x", unit, cmd); switch (cmd & 0x3) { case 0x3: /* Control */ - if ((cmd & 0xfc) == 0) - return SNS_CHNEND|SNS_DEVEND; case 0x1: /* Write command */ case 0x2: /* Read command */ uptr->u3 |= cmd; + sim_activate(uptr, 200); return 0; case 0x0: /* Status */ if (cmd == 0x4) { /* Sense */ uptr->u3 |= cmd; + sim_activate(uptr, 200); return 0; } break; @@ -186,105 +162,235 @@ uint8 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { return SNS_CHNEND|SNS_DEVEND; } -/* Handle processing of disk requests. */ -t_stat com_srv(UNIT * uptr) +uint8 coml_haltio(UNIT *uptr) { + uint16 addr = GET_UADDR(uptr->u3); + DEVICE *dptr = find_dev_from_unit(uptr); + int unit = (uptr - dptr->units); + int cmd = uptr->u3 & 0xff; + uint8 ch; + + sim_debug(DEBUG_CMD, dptr, "HLTIO unit=%d %x\n", unit, cmd); + + switch (cmd) { + case 0: + case CMD_DIS: /* Disable line */ + case CMD_DIAL: /* Dial call */ + case 0x4: + /* Short commands nothing to do */ + return 0; + + case CMD_INH: /* Read data without timeout */ + case CMD_RD: /* Read in data from com line */ + case CMD_WR: /* Write data to com line */ + case CMD_BRK: /* Send break signal */ + case CMD_PREP: /* Wait for incoming data */ + case CMD_SRCH: /* Wait for EOT character */ + uptr->u3 &= ~0xffff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + break; + case CMD_ENB: /* Enable line */ + /* Terminate the operation */ + (void)tmxr_set_get_modem_bits(&com_ldsc[unit], 0, TMXR_MDM_DTR, NULL); + (void)tmxr_reset_ln(&com_ldsc[unit]); + uptr->u3 &= ~0xffff; + break; + } + return SNS_CHNEND|SNS_DEVEND; +} + +/* Handle per unit commands */ +t_stat coml_srv(UNIT * uptr) { uint16 addr = GET_UADDR(uptr->u3); DEVICE *dptr = find_dev_from_unit(uptr); - struct com_t *data = (struct com_t *)(uptr->up7); int unit = (uptr - dptr->units); int cmd = uptr->u3 & 0xff; uint8 ch; switch (cmd) { - case 0: /* No command, stop tape */ - sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit); + case 0: break; case 0x4: ch = uptr->u5 & 0xff; sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch); chan_write_byte(addr, &ch) ; - ch = (uptr->u5 >> 8) & 0xff; - sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 2 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; - ch = 0xc0; - sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 3 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; - ch = (uptr->u5 >> 16) & 0xff; - sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; - ch = 0; - chan_write_byte(addr, &ch) ; - chan_write_byte(addr, &ch); uptr->u3 &= ~0xff; chan_end(addr, SNS_CHNEND|SNS_DEVEND); break; - case DK_RELEASE: /* Release from channel */ - case DK_RESTORE: /* Restore */ - case DK_SEEK: /* Seek */ - case DK_SEEKCYL: /* Seek Cylinder */ - case DK_SEEKHD: /* Seek Head */ - case DK_SETMSK: /* Set file mask */ - case DK_SPACE: /* Space record */ - case DK_SRCH_HAEQ: /* Search HA equal */ - case DK_SRCH_IDEQ: /* Search ID equal */ - case DK_SRCH_IDGT: /* Search ID greater */ - case DK_SRCH_IDGE: /* Search ID greater or equal */ - case DK_SRCH_KYEQ: /* Search Key equal */ - case DK_SRCH_KYGT: /* Search Key greater */ - case DK_SRCH_KYGE: /* Search Key greater or equal */ - case DK_RD_IPL: /* Read IPL record */ - case DK_RD_HA: /* Read home address */ - case DK_RD_CNT: /* Read count */ - case DK_RD_R0: /* Read R0 */ - case DK_RD_D: /* Read Data */ - case DK_RD_KD: /* Read key and data */ - case DK_RD_CKD: /* Read count, key and data */ - case DK_WR_HA: /* Write home address */ - case DK_WR_R0: /* Write R0 */ - case DK_WR_D: /* Write Data */ - case DK_WR_KD: /* Write key and data */ - case DK_WR_CKD: /* Write count, key and data */ - case DK_WR_SCKD: /* Write special count, key and data */ - case DK_ERASE: /* Erase to end of track */ + case CMD_DIAL: /* Dial call */ + uptr->u5 = SNS_CMDREJ; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + + case CMD_INH: /* Read data without timeout */ + case CMD_RD: /* Read in data from com line */ + if (uptr->u3 & ENAB) { + if (tmxr_rqln(&com_ldsc[unit]) > 0) { + int32 data = tmxr_getc_ln (&com_ldsc[unit]); + if (ch & SCPE_BREAK) { + uptr->u3 &= ~0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } else { + ch = sim_tt_inpcvt (data, TT_GET_MODE(uptr->flags) | + TTUF_KSR); + if (chan_write_byte( addr, &ch)) { + uptr->u3 &= 0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + return SCPE_OK; + } + } + } + sim_activate(uptr, 200); + } + break; + + case CMD_WR: /* Write data to com line */ + if (uptr->u3 & ENAB) { + if (chan_read_byte (addr, &ch)) { + uptr->u3 &= 0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + } else { + int32 data = ch; + data = sim_tt_outcvt(data, TT_GET_MODE(uptr->flags) | + TTUF_KSR); + tmxr_putc_ln( &com_ldsc[unit], data); + sim_activate(uptr, 200); + } + } else { + uptr->u3 &= ~0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + } + break; + + case CMD_BRK: /* Send break signal */ + uptr->u3 &= 0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + break; + + case CMD_PREP: /* Wait for incoming data */ + if (uptr->u3 & ENAB) { + if (tmxr_rqln(&com_ldsc[unit]) > 0) { + uptr->u3 &= 0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + } else + sim_activate(uptr, 200); + } else { + uptr->u3 &= ~0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); + } + break; + + case CMD_SRCH: /* Wait for EOT character */ + uptr->u3 &= 0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + break; + + case CMD_ENB: /* Enable line */ + sim_debug(DEBUG_CMD, dptr, "COM: unit=%d enable\n", unit); + if ((uptr->u3 & (POLL|ENAB)) == ENAB) { + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + } else { + (void)tmxr_set_get_modem_bits(&com_ldsc[unit], TMXR_MDM_DTR, + 0, NULL); + uptr->u3 |= POLL; + sim_activate(uptr, 200); + } + break; + + case CMD_DIS: /* Disable line */ + sim_debug(DEBUG_CMD, dptr, "COM: unit=%d disable\n", unit); + (void)tmxr_set_get_modem_bits(&com_ldsc[unit], 0, TMXR_MDM_DTR, NULL); + (void)tmxr_reset_ln(&com_ldsc[unit]); + uptr->u3 &= ~(0xff|POLL|ENAB) ; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); break; } return SCPE_OK; } -void -com_ini(UNIT * uptr, t_bool f) +/* Scan for new connections, flush and poll for data */ +t_stat com_scan(UNIT * uptr) { - DEVICE *dptr = find_dev_from_unit(uptr); + UNIT *line; + int32 ln; + + sim_activate(uptr, tmxr_poll); /* continue poll */ + if ((uptr->flags & UNIT_ATT) == 0) /* attached? */ + return SCPE_OK; + ln = tmxr_poll_conn (&com_desc); /* look for connect */ + sim_debug(DEBUG_DETAIL, &com_dev, "COM Poll %d\n", ln); + if (ln >= 0) { /* got one? rcv enb*/ + line = &coml_unit[ln]; + sim_debug(DEBUG_DETAIL, &com_dev, "COM line connect %d\n", ln); + if (line->u3 & ENAB) /* Already connected */ + return SCPE_OK; + if ((line->u3 & POLL) == 0) { /* Check if not polling */ + (void)tmxr_set_get_modem_bits(&com_ldsc[ln], 0, + TMXR_MDM_DTR, NULL); + (void)tmxr_reset_ln(&com_ldsc[ln]); + } else { + com_ldsc[ln].rcve = 1; /* Mark as ok */ + line->u3 &= ~POLL; + line->u3 |= ENAB; + sim_debug(DEBUG_DETAIL, &com_dev, "COM line connect %d\n", ln); + } + } + tmxr_poll_tx(&com_desc); + tmxr_poll_rx(&com_desc); + return SCPE_OK; } t_stat com_reset(DEVICE * dptr) { + sim_activate(&com_unit[0], tmxr_poll); return SCPE_OK; } -t_stat -com_attach(UNIT * uptr, CONST char *file) + +void +coml_ini(UNIT * uptr, t_bool f) { - uint16 addr = GET_UADDR(uptr->u3); - t_stat r; + UNIT *srv; +} - if ((r = attach_unit(uptr, file)) != SCPE_OK) +t_stat +com_attach(UNIT * uptr, CONST char *cptr) +{ + t_stat r; + int i; + + if ((r = tmxr_attach(&com_desc, uptr, cptr)) != SCPE_OK) return r; - - set_devattn(addr, SNS_DEVEND); + for (i = 0; i< com_desc.lines; i++) { + // (void)tmxr_set_line_modem_control(&com_ldsc[i], TRUE); +// (void)tmxr_set_get_modem_bits(&com_ldsc[i], 0, TMXR_MDM_DTR, NULL); +// (void)tmxr_reset_ln(&com_ldsc[i]); + coml_unit[i].u3 &= ~0xffff; + } + sim_activate(uptr, tmxr_poll); return SCPE_OK; } t_stat com_detach(UNIT * uptr) { - uptr->u3 = 0; - return detach_unit(uptr); + t_stat r; + int i; + UNIT *srv; + + for (i = 0; i< com_desc.lines; i++) { + (void)tmxr_set_get_modem_bits(&com_ldsc[i], 0, TMXR_MDM_DTR, NULL); + (void)tmxr_reset_ln(&com_ldsc[i]); + coml_unit[i].u3 &= ~0xffff; + } + sim_cancel(uptr); + r = tmxr_detach(&com_desc, uptr); + return r; } t_stat com_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, @@ -298,7 +404,7 @@ return SCPE_OK; const char *com_description (DEVICE *dptr) { -return "IBM 2703 communications controller"; +return "IBM 2701 communications controller"; } #endif diff --git a/IBM360/ibm360_defs.h b/IBM360/ibm360_defs.h index 0d18ff3..0ed9555 100644 --- a/IBM360/ibm360_defs.h +++ b/IBM360/ibm360_defs.h @@ -361,6 +361,7 @@ extern DEVICE dda_dev; extern DEVICE ddb_dev; extern DEVICE ddc_dev; extern DEVICE ddd_dev; +extern DEVICE coml_dev; extern DEVICE com_dev; extern UNIT cpu_unit; diff --git a/IBM360/ibm360_sys.c b/IBM360/ibm360_sys.c index ac43a65..aea6017 100644 --- a/IBM360/ibm360_sys.c +++ b/IBM360/ibm360_sys.c @@ -79,6 +79,7 @@ DEVICE *sim_devices[] = { #endif #endif #ifdef NUM_DEVS_COM + &coml_dev, &com_dev, #endif NULL };