diff --git a/IBM360/ibm360_cdp.c b/IBM360/ibm360_cdp.c index ec720fd..0b6ab49 100644 --- a/IBM360/ibm360_cdp.c +++ b/IBM360/ibm360_cdp.c @@ -37,9 +37,8 @@ #define UNIT_CDP UNIT_ATTABLE | UNIT_DISABLE | UNIT_SEQ | MODE_029 -#define CHN_SNS 0x04 /* Sense command */ - /* Device status information stored in u3 */ +#define CMD u3 #define CDR_RD 0x02 /* Read command */ #define CDR_FEED 0x03 /* Feed next card */ #define CDP_CMDMSK 0x27 /* Mask command part. */ @@ -51,21 +50,11 @@ /* Upper 11 bits of u3 hold the device address */ /* u4 holds current column, */ +#define COL u4 -/* in u5 packs sense byte 0,1 and 3 */ +/* in u5 packs sense byte 0 */ /* Sense byte 0 */ -#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_SEQUENCE 0x02 /* Unusual sequence */ -#define SNS_CHN9 0x01 /* Channel 9 on printer */ - -#define CMD u3 -#define COL u4 -#define SNS u5 +#define SNS u5 @@ -92,9 +81,9 @@ UNIT cdp_unit[] = { #if NUM_DEVS_CDP > 1 {UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x01D)}, #if NUM_DEVS_CDP > 2 - {UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x40D)}, + {UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x02D)}, #if NUM_DEVS_CDP > 3 - {UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x41D)}, + {UDATA(cdp_srv, UNIT_CDP | UNIT_DIS, 0), 600, UNIT_ADDR(0x03D)}, #endif #endif #endif @@ -149,7 +138,7 @@ uint8 cdp_startcmd(UNIT *uptr, uint8 cmd) { sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %x\n", unit, cmd); switch (cmd & 0x7) { - case 1: /* Write command */ + case CMD_WRITE: /* Write command */ uptr->CMD &= ~(CDP_CMDMSK); uptr->CMD |= (cmd & CDP_CMDMSK); sim_activate(uptr, 100); /* Start unit off */ @@ -157,7 +146,7 @@ uint8 cdp_startcmd(UNIT *uptr, uint8 cmd) { uptr->SNS = 0; return 0; - case 3: + case CMD_CTL: if (cmd != 0x3) { uptr->SNS |= SNS_CMDREJ; return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; @@ -167,7 +156,7 @@ uint8 cdp_startcmd(UNIT *uptr, uint8 cmd) { case 0: /* Status */ break; - case 4: /* Sense */ + case CMD_SENSE: /* Sense */ uptr->CMD &= ~(CDP_CMDMSK); uptr->CMD |= (cmd & CDP_CMDMSK); sim_activate(uptr, 100); diff --git a/IBM360/ibm360_cdr.c b/IBM360/ibm360_cdr.c index b3e1f9f..eefcf90 100644 --- a/IBM360/ibm360_cdr.c +++ b/IBM360/ibm360_cdr.c @@ -36,10 +36,8 @@ #ifdef NUM_DEVS_CDR #define UNIT_CDR UNIT_ATTABLE | UNIT_RO | UNIT_DISABLE | MODE_029 - -#define CHN_SNS 0x04 /* Sense command */ - /* Device status information stored in u3 */ +#define CMD u3 #define CDR_RD 0x02 /* Read command */ #define CDR_FEED 0x03 /* Feed next card */ #define CDR_CMDMSK 0x27 /* Mask command part. */ @@ -53,21 +51,11 @@ /* Upper 11 bits of u3 hold the device address */ /* u4 holds current column, */ +#define COL u4 -/* in u5 packs sense byte 0,1 and 3 */ +/* in u5 packs sense byte 0 */ /* Sense byte 0 */ -#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_SEQUENCE 0x02 /* Unusual sequence */ -#define SNS_CHN9 0x01 /* Channel 9 on printer */ - -#define CMD u3 -#define COL u4 -#define SNS u5 +#define SNS u5 /* std devices. data structures @@ -94,9 +82,9 @@ UNIT cdr_unit[] = { #if NUM_DEVS_CDR > 1 {UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x1C)}, #if NUM_DEVS_CDR > 2 - {UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x40C)}, + {UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x2C)}, #if NUM_DEVS_CDR > 3 - {UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x41C)}, + {UDATA(cdr_srv, UNIT_CDR | UNIT_DIS, 0), 300, UNIT_ADDR(0x3C)}, #endif #endif #endif @@ -140,7 +128,7 @@ uint8 cdr_startcmd(UNIT *uptr, uint8 cmd) { } switch (cmd & 0x7) { - case 2: /* Read command */ + case CMD_READ: /* Read command */ uptr->SNS = 0; uptr->COL = 0; /* Check if there was End of file */ @@ -173,7 +161,7 @@ uint8 cdr_startcmd(UNIT *uptr, uint8 cmd) { sim_activate(uptr, 100); /* Start unit off */ return 0; - case 3: /* Control */ + case CMD_CTL: /* Control */ uptr->SNS = 0; uptr->CMD &= ~(0xff); if (cmd == 0x3) @@ -191,7 +179,7 @@ uint8 cdr_startcmd(UNIT *uptr, uint8 cmd) { case 0: /* Status */ return 0; - case 4: /* Sense */ + case CMD_SENSE: /* Sense */ uptr->CMD &= ~(0xff); uptr->CMD |= (cmd & 0xff); sim_activate(uptr, 10); @@ -214,7 +202,7 @@ cdr_srv(UNIT *uptr) { uint16 *image = (uint16 *)(uptr->up7); int fl = 0; - if ((uptr->CMD & CDR_CMDMSK) == CHN_SNS) { + if ((uptr->CMD & CDR_CMDMSK) == CMD_SENSE) { uint8 ch = uptr->SNS; if (ch == 0 && (uptr->flags & UNIT_ATT) == 0) ch = SNS_INTVENT; diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index f8c2638..ccb2f2f 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -36,33 +36,6 @@ #define PCI 0x08000000 /* Program controlled interuption */ #define IDA 0x04000000 /* Indirect Channel addressing */ -/* Command masks */ -#define CMD_TYPE 0x3 /* Type mask */ -#define CMD_CHAN 0x0 /* Channel command */ -#define CMD_WRITE 0x1 /* Write command */ -#define CMD_READ 0x2 /* Read command */ -#define CMD_CTL 0x3 /* Control command */ -#define CMD_SENSE 0x4 /* Sense channel command */ -#define CMD_TIC 0x8 /* Transfer in channel */ -#define CMD_RDBWD 0xc /* Read backward */ - -#define STATUS_ATTN 0x8000 /* Device raised attention */ -#define STATUS_MOD 0x4000 /* Status modifier */ -#define STATUS_CTLEND 0x2000 /* Control end */ -#define STATUS_BUSY 0x1000 /* Device busy */ -#define STATUS_CEND 0x0800 /* Channel end */ -#define STATUS_DEND 0x0400 /* Device end */ -#define STATUS_CHECK 0x0200 /* Unit check */ -#define STATUS_EXPT 0x0100 /* Unit excpetion */ -#define STATUS_PCI 0x0080 /* Program interupt */ -#define STATUS_LENGTH 0x0040 /* Incorrect length */ -#define STATUS_PCHK 0x0020 /* Program check */ -#define STATUS_PROT 0x0010 /* Protection check */ -#define STATUS_CDATA 0x0008 /* Channel data check */ -#define STATUS_CCNTL 0x0004 /* Channel control check */ -#define STATUS_INTER 0x0002 /* Channel interface check */ -#define STATUS_CHAIN 0x0001 /* Channel chain check */ - #define ERROR_STATUS (STATUS_ATTN|STATUS_PCI|STATUS_EXPT|STATUS_CHECK| \ STATUS_PROT|STATUS_CDATA|STATUS_CCNTL|STATUS_INTER| \ STATUS_CHAIN) @@ -479,7 +452,7 @@ start_cmd: if (chan->chan_status & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel %03x abort %04x\n", chan->daddr, chan->chan_status); - chan->chan_status |= STATUS_CEND; +// chan->chan_status |= STATUS_CEND; chan->ccw_flags = 0; chan->ccw_cmd = 0; irq_pend = 1; @@ -737,7 +710,7 @@ set_devattn(uint16 addr, uint8 flags) { if (chan->daddr == addr && chan->chain_flg != 0 && (flags & SNS_DEVEND) != 0) { chan->chan_status |= ((uint16)flags) << 8; - } else + } else /* Check if device is current on channel */ if (chan->daddr == addr && (chan->chan_status & STATUS_CEND) != 0 && (flags & SNS_DEVEND) != 0) { @@ -855,12 +828,13 @@ startio(uint16 addr) { sim_debug(DEBUG_CMD, &cpu_dev, "SIO %03x %08x cc=2\n", addr, chan->chan_status); return 2; } - - if (dev_status[addr] == SNS_DEVEND || + if (dev_status[addr] == SNS_DEVEND || dev_status[addr] == (SNS_DEVEND|SNS_CHNEND)) dev_status[addr] = 0; /* Check for any pending status for this device */ if (dev_status[addr] != 0) { +// if (dev_status[addr] & SNS_DEVEND) +// dev_status[addr] |= SNS_BSY; M[0x44 >> 2] = (((uint32)dev_status[addr]) << 24); M[0x40 >> 2] = 0; key[0] |= 0x6; @@ -927,6 +901,7 @@ startio(uint16 addr) { return 1; } +//#if 0 /* If immediate command and not command chaining */ if ((chan->chan_status & (STATUS_CEND)) != 0 && (chan->ccw_flags & FLAG_CC) == 0) { @@ -938,6 +913,7 @@ startio(uint16 addr) { addr, M[0x44 >> 2]); return 1; } +//#endif return 0; } @@ -1180,6 +1156,12 @@ int testchan(uint16 channel) { return 2; } + /* If channel has pending status, return 1 */ + if (chan->chan_status != 0) { + sim_debug(DEBUG_CMD, &cpu_dev, "TCH CC %x cc=1, error\n", channel); + return 1; + } + /* Otherwise return 0. */ sim_debug(DEBUG_CMD, &cpu_dev, "TCH CC %x cc=0, ok\n", channel); return 0; @@ -1582,6 +1564,7 @@ set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc) dev->dibp = NULL; dev->unit = NULL; } else { +fprintf(stderr, "not found %x\n\r", devaddr + i); r = SCPE_ARG; } } @@ -1591,17 +1574,21 @@ set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc) if (ndev == NULL) { r = SCPE_ARG; +fprintf(stderr, "not found2\n\r"); } else { /* Check if device already at newdev */ if (dptr->flags & DEV_UADDR) { - if (dev->unit != NULL) + if (dev->unit != NULL && dev->unit != uptr) { r = SCPE_ARG; +fprintf(stderr, "not same\n\r"); + } } else { newdev &= dibp->mask | 0xf00; for (i = 0; i < dibp->numunits; i++) { ndev = find_device(newdev + i); if (dev == NULL || dev->unit != NULL) { r = SCPE_ARG; +fprintf(stderr, "not same2\n\r"); } } } @@ -1614,14 +1601,15 @@ set_dev_addr(UNIT * uptr, int32 val, CONST char *cptr, void *desc) dev = find_device(devaddr); /* Update device entry */ if (dptr->flags & DEV_UADDR) { + int unit = uptr - dptr->units; dev->dibp = dibp; dev->unit = uptr; dev->dev_addr = devaddr; uptr->u3 &= ~UNIT_ADDR(0xfff); uptr->u3 |= UNIT_ADDR(devaddr); - sim_printf("Set dev %s %x\r\n", dptr->name, GET_UADDR(uptr->u3) & 0xfff); + sim_printf("Set dev %s%d %x\r\n", dptr->name, unit, GET_UADDR(uptr->u3) & 0xfff); } else { - sim_printf("Set dev %s0 %x\r\n", dptr->name, (uint32)(devaddr & 0xfff)); + sim_printf("Set dev %s %x\r\n", dptr->name, (uint32)(devaddr & 0xfff)); for (i = 0; i < dibp->numunits; i++) { dev = find_device(devaddr + i); uptr = &((dibp->units)[i]); diff --git a/IBM360/ibm360_com.c b/IBM360/ibm360_com.c index e211b61..b0d0495 100644 --- a/IBM360/ibm360_com.c +++ b/IBM360/ibm360_com.c @@ -27,59 +27,90 @@ #include "sim_tmxr.h" #ifdef NUM_DEVS_COM -#define UNIT_COM 0 +#define UNIT_COM UNIT_DISABLE #define UNIT_V_DIRECT (UNIT_V_UF + 0) #define UNIT_DIRECT (1 << UNIT_V_DIRECT) +#define UNIT_V_UTYPE (UNIT_V_UF + 1) /* 2741 - ni */ +#define UNIT_2741 (0 << UNIT_V_UTYPE) +#define UNIT_1052 (1 << UNIT_V_UTYPE) +#define UNIT_2780 (2 << UNIT_V_UTYPE) +#define UNIT_UTYPE (3 << UNIT_V_UTYPE) /* u3 */ -#define CMD_WR 0x01 /* Write data to com line */ -#define CMD_RD 0x02 /* Read in data from com line */ -#define CMD_NOP 0x03 /* Nop command */ -#define CMD_PREP 0x06 /* Wait for incoming data */ -#define CMD_INH 0x0A /* Read data without timeout */ -#define CMD_BRK 0x0D /* Send break signal */ -#define CMD_SRCH 0x0E /* Wait for EOT character */ -#define CMD_ENB 0x27 /* Enable line */ -#define CMD_DIAL 0x29 /* Dial call */ -#define CMD_DIS 0x2F /* Disable line */ +#define CMD u3 + +#define CMD_WR 0x01 /* Write data to com line */ +#define CMD_RD 0x02 /* Read in data from com line */ +#define CMD_NOP 0x03 /* Nop command */ +#define CMD_PREP 0x06 /* Wait for incoming data */ +#define CMD_POLL 0x09 /* Poll (BSC) */ +#define CMD_INH 0x0A /* Read data without timeout */ +#define CMD_BRK 0x0D /* Send break signal */ +#define CMD_SRCH 0x0E /* Wait for EOT character */ +#define CMD_SETM 0x23 /* Set Mode (BSC) */ +#define CMD_ENB 0x27 /* Enable line */ +#define CMD_DIAL 0x29 /* Dial call */ +#define CMD_DIS 0x2F /* Disable line */ /* u3 second byte */ -#define RECV 0x00100 /* Recieving data */ -#define SEND 0x00200 /* Sending data */ -#define ENAB 0x00400 /* Line enabled */ -#define POLL 0x00800 /* Waiting for connection */ -#define ADDR 0x01000 /* Address request recieved. */ -#define INPUT 0x02000 /* Input ready */ -#define ATTN 0x04000 /* Send attention signal */ -#define ADDR9 0x08000 /* Address char 9 recieved */ -#define BYPASS 0x10000 /* Don't echo output */ -#define BREAK 0x20000 /* Return unit exception */ +#define RECV 0x00100 /* Recieving data */ +#define SEND 0x00200 /* Sending data */ +#define ENAB 0x00400 /* Line enabled */ +#define POLL 0x00800 /* Waiting for connection */ +#define ADDR 0x01000 /* Address request recieved. */ +#define INPUT 0x02000 /* Input ready */ +#define ATTN 0x04000 /* Send attention signal */ +#define ADDR9 0x08000 /* Address char 9 recieved */ +#define BYPASS 0x10000 /* Don't echo output */ +#define BREAK 0x20000 /* Return unit exception */ /* Upper 11 bits of u3 hold the device address */ /* u4 */ /* Where we are reading from */ +#define IPTR u4 /* u5 */ /* Sense byte 0 */ -#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 */ +#define SNS u5 /* u6 */ /* Pointer into buffer */ -#define CMD u3 -#define IPTR u4 -#define SNS u5 +/* us9 */ +/* BSC status */ +#define BSCDLE 0x0001 /* BSC DLE Char output */ +#define BSCTXT 0x0002 /* BSC Text mode */ +#define BSCXPR 0x0004 /* BSC transparent mode */ +#define BSCEIB 0x0008 /* BSC EIB byte after ITB/EBT/ETX */ +#define BSCCC2 0x0010 /* BSC CC Character 2 */ +#define BSCCC1 0x0020 /* BSC CC Character 1 */ +#define BSCSYN1 0x0100 /* One SYNC Char recieved */ +#define BSCSYN2 0x0200 /* Second SYNC Char recieved */ +#define BSCSYN 0x0400 /* Sync recieved */ +#define BSCIDLE 0x1000 /* Input DLE recieved */ + #define BPTR u6 +#define BSCSTATE us9 + +/* BSC characters */ +#define SOH 0x01 +#define STX 0x02 +#define ETX 0x03 +#define HT 0x05 +#define DLE 0x10 +#define EOM 0x19 +#define IBC 0x1f +#define ETB 0x26 +#define ESC 0x27 +#define ENQ 0x2d +#define SYN 0x32 +#define EOT 0x37 +#define NAK 0x3d +#define ACK0 0x61 +#define ACK1 0x70 uint8 coml_startcmd(UNIT *uptr, uint8 cmd) ; uint8 coml_haltio(UNIT *uptr); @@ -104,6 +135,9 @@ MTAB com_mod[] = { MTAB coml_mod[] = { {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, &show_dev_addr, NULL}, + {UNIT_UTYPE, UNIT_2741, "2741", "2741", NULL, NULL, NULL, "IBM 2741 terminal"}, + {UNIT_UTYPE, UNIT_1052, "1052", "1052", NULL, NULL, NULL, "IBM 1052 terminal"}, + {UNIT_UTYPE, UNIT_2780, "2780", "2780", NULL, NULL, NULL, "IBM 2780 RJE station"}, {UNIT_DIRECT, 0, "DIALUP", "DIALUP", NULL, NULL, NULL, "Dailup line" }, {UNIT_DIRECT, UNIT_DIRECT, "NODIAL", "NODIAL", NULL, NULL, NULL, "Hard wired line" }, @@ -111,7 +145,7 @@ MTAB coml_mod[] = { }; UNIT com_unit[] = { - {UDATA(&com_scan, UNIT_ATTABLE | UNIT_IDLE, 0)}, /* Line scanner */ + {UDATA(&com_scan, UNIT_ATTABLE | UNIT_DISABLE | UNIT_IDLE, 0)}, /* Line scanner */ }; UNIT coml_unit[] = { @@ -270,18 +304,18 @@ uint8 coml_startcmd(UNIT *uptr, uint8 cmd) { switch (cmd & 0x3) { - case 0x3: /* Control */ + case CMD_CTL: /* Control */ if ((cmd == CMD_NOP) || (cmd & 0x10) != 0) return SNS_CHNEND|SNS_DEVEND; - case 0x2: /* Read command */ - case 0x1: /* Write command */ + case CMD_READ: /* Read command */ + case CMD_WRITE: /* Write command */ uptr->CMD |= cmd; uptr->SNS = 0; sim_activate(uptr, 200); return 0; case 0x0: /* Status */ - if (cmd == 0x4) { /* Sense */ + if (cmd == CMD_SENSE) { /* Sense */ uptr->CMD |= cmd; sim_activate(uptr, 200); return 0; @@ -310,7 +344,8 @@ uint8 coml_haltio(UNIT *uptr) { case 0: case CMD_DIS: /* Disable line */ case CMD_DIAL: /* Dial call */ - case 0x4: + case CMD_SENSE: + case CMD_SETM: /* Set mode */ /* Short commands nothing to do */ break; @@ -319,6 +354,7 @@ uint8 coml_haltio(UNIT *uptr) { chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); break; + case CMD_POLL: /* Poll command */ case CMD_INH: /* Read data without timeout */ case CMD_RD: /* Read in data from com line */ case CMD_WR: /* Write data to com line */ @@ -345,13 +381,14 @@ t_stat coml_srv(UNIT * uptr) int unit = (uptr - dptr->units); int cmd = uptr->CMD & 0xff; uint8 ch; + int bsc = (uptr->flags & UNIT_UTYPE) == UNIT_2780; switch (cmd) { case 0: break; - case 0x4: + case CMD_SENSE: ch = uptr->SNS & 0xff; sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch); chan_write_byte(addr, &ch) ; @@ -377,7 +414,7 @@ t_stat coml_srv(UNIT * uptr) chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); return SCPE_OK; } - if ((uptr->CMD & ADDR) != 0 && uptr->BPTR == 0) { + if (!bsc && (uptr->CMD & ADDR) != 0 && uptr->BPTR == 0) { ch = 0x16; sim_debug(DEBUG_CMD, dptr, "COM: unit=%d addr %02x\n", unit, ch); uptr->CMD &= ~ADDR; @@ -400,6 +437,8 @@ t_stat coml_srv(UNIT * uptr) chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK|SNS_UNITEXP); return SCPE_OK; } else if (uptr->CMD & INPUT) { + int ack = bsc && ((uptr->BSCSTATE & BSCIDLE) != 0); + if (uptr->BPTR == uptr->IPTR) { uptr->CMD &= ~(0xff|INPUT|RECV); uptr->BPTR = 0; @@ -408,6 +447,21 @@ t_stat coml_srv(UNIT * uptr) return SCPE_OK; } ch = com_buf[unit][uptr->IPTR++]; + if (!bsc && ch == 0x1f) { + uptr->CMD |= ADDR; + } + if (ack && ((ch == ACK0) || (ch == ACK1))) { + uptr->CMD &= ~(0xff|INPUT|RECV); + uptr->IPTR = 0; + uptr->BPTR = 0; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|(ch == ACK1 ? SNS_UNITEXP:0)); + return SCPE_OK; + } + if (bsc && ch == DLE) { + uptr->BSCSTATE |= BSCIDLE; + } else { + uptr->BSCSTATE &= ~BSCIDLE; + } if (chan_write_byte( addr, &ch)) { uptr->CMD &= ~(0xff|INPUT|RECV); uptr->IPTR = 0; @@ -424,6 +478,36 @@ t_stat coml_srv(UNIT * uptr) } break; + case CMD_SETM: /* Set mode */ + if (bsc) { + uptr->SNS = 0; + uptr->CMD &= ~(0xff|BSCTXT|BSCXPR|BSCDLE|BSCEIB); + if (!chan_read_byte (addr, &ch)) + ch = 0; + uptr->CMD |= ch & 0x40 ? BSCEIB : 0; + if (uptr->CMD & ENAB) { + /* bisync: If line already enabled, set mode CCW is restart of + device. Tell 2780 that previous transmission ends. */ + tmxr_putc_ln( &com_ldsc[unit], SYN); + tmxr_putc_ln( &com_ldsc[unit], EOT); + } + sim_debug(DEBUG_CMD, dptr, "COM: unit=%d set mode (%02x)\n", unit, ch); + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + } else { + uptr->SNS = SNS_CMDREJ; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + } + break; + + case CMD_POLL: + if (!bsc) { + uptr->SNS = SNS_CMDREJ; + uptr->CMD &= ~(0xff|BREAK|INPUT|RECV|SEND|POLL); + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* Fall through */ + case CMD_WR: /* Write data to com line */ uptr->SNS = 0; if (uptr->CMD & ENAB) { @@ -435,7 +519,7 @@ t_stat coml_srv(UNIT * uptr) chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); return SCPE_OK; } - if (uptr->CMD & BREAK) { + if (!bsc && uptr->CMD & BREAK) { sim_debug(DEBUG_CMD, dptr, "COM: unit=%d attn write\n", unit); uptr->CMD &= ~(0xff|BREAK); uptr->SNS |= SNS_INTVENT; @@ -446,6 +530,26 @@ t_stat coml_srv(UNIT * uptr) if (chan_read_byte (addr, &ch)) { uptr->CMD &= ~0xff; chan_end(addr, SNS_CHNEND|SNS_DEVEND); + if (bsc) { + tmxr_send_buffered_data(&com_ldsc[unit]); /* Flush data */ + } + } else if (bsc) { + if (uptr->CMD & BSCXPR) { + if (ch == DLE) { + tmxr_putc_ln(&com_ldsc[unit], DLE); + } else if (ch == DLE) { + uptr->CMD |= BSCDLE; + } else { + if ((uptr->CMD & BSCDLE) && (ch == ETX)) { + uptr->CMD |= BSCXPR; + } + uptr->CMD &= ~BSCDLE; + } + sim_debug(DEBUG_CMD, dptr, "COM: unit=%d BSC send %02x\n", + unit, ch); + tmxr_putc_ln(&com_ldsc[unit], ch); + sim_activate(uptr, 200); + } } else { int32 data; data = com_2741_out[ch]; @@ -537,70 +641,155 @@ t_stat coml_srv(UNIT * uptr) uptr->CMD &= ~(0xff|POLL|ENAB) ; chan_end(addr, SNS_CHNEND|SNS_DEVEND); break; + + default: + uptr->SNS = SNS_CMDREJ; + uptr->CMD &= ~(0xff|BREAK|INPUT|RECV|SEND|POLL); + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; } if ((uptr->CMD & (ENAB|RECV)) == (ENAB|RECV)) { int32 data = tmxr_getc_ln(&com_ldsc[unit]); if ((data & TMXR_VALID) != 0) { - ch = com_2741_in[data & 0x7f]; - sim_debug(DEBUG_DATA, dptr, "COML: unit=%d read '%c' %02x\n", unit, data, ch); - if (data & SCPE_BREAK) { - uptr->CMD |= BREAK; - return SCPE_OK; - } - /* Handle end of buffer */ - switch (data & 0x7f) { - case '\r': - case '\n': - com_buf[unit][uptr->BPTR++] = 0x5b; - com_buf[unit][uptr->BPTR++] = 0x1f; - uptr->CMD |= INPUT; - uptr->CMD &= ~RECV; - uptr->IPTR = 0; - tmxr_putc_ln( &com_ldsc[unit], '\r'); - tmxr_putc_ln( &com_ldsc[unit], '\n'); - break; + if (bsc) { + int gotdle = (uptr->CMD & BSCDLE) != 0; + ch = data & 0xff; + if (ch == DLE) { + uptr->CMD |= BSCDLE; + } else { + uptr->CMD &= ~(BSCDLE); + } + if ((uptr->CMD & BSCTXT) != 0) { + /* Text mode */ + if ((uptr->CMD & BSCXPR) != 0) { + switch (ch) { + case DLE: + if (gotdle) { + com_buf[unit][uptr->BPTR++] = ch; + } + break; + case SYN: + break; + case ETB: + (void) tmxr_getc_ln(&com_ldsc[unit]); /* BCC */ + (void) tmxr_getc_ln(&com_ldsc[unit]); /* BCC */ + /* Fall through */ + case EOT: + case ETX: + /* End transparent mode, end read */ + case IBC: + /* End transparent mode, continue read */ + if (gotdle) { + uptr->CMD &= ~(BSCXPR); + com_buf[unit][uptr->BPTR++] = DLE; + com_buf[unit][uptr->BPTR++] = ch; + } + if ((uptr->CMD & BSCEIB) != 0) { + com_buf[unit][uptr->BPTR++] = 0; + } + if (ch != IBC) { + com_buf[unit][uptr->BPTR++] = ACK0; + uptr->CMD |= INPUT; + uptr->CMD &= ~RECV; + sim_activate( uptr, 200); + return SCPE_OK; + } + break; + case ENQ: + if (gotdle) { + uptr->CMD &= ~(BSCXPR|BSCTXT); + com_buf[unit][uptr->BPTR++] = DLE; + com_buf[unit][uptr->BPTR++] = ch; + com_buf[unit][uptr->BPTR++] = ACK0; + uptr->CMD |= INPUT; + uptr->CMD &= ~RECV; + sim_activate(uptr, 200); + return SCPE_OK; + } else { + if ((uptr->CMD & BSCEIB) != 0) { + com_buf[unit][uptr->BPTR++] = 0; + } + if (ch != IBC) { + com_buf[unit][uptr->BPTR++] = ACK0; + uptr->CMD |= INPUT; + uptr->CMD &= ~RECV; + } + } + sim_activate( uptr, 200); + return SCPE_OK; - case 0177: - case '\b': - if (uptr->BPTR != 0) { - uptr->BPTR--; - tmxr_putc_ln( &com_ldsc[unit], '\b'); - tmxr_putc_ln( &com_ldsc[unit], ' '); - tmxr_putc_ln( &com_ldsc[unit], '\b'); - } - break; + default: + if (gotdle) { + com_buf[unit][uptr->BPTR++] = DLE; + } + com_buf[unit][uptr->BPTR++] = ch; + break; + } - case 025: /* ^U clear line */ - while(uptr->BPTR > 0) { - tmxr_putc_ln( &com_ldsc[unit], '\b'); - tmxr_putc_ln( &com_ldsc[unit], ' '); - tmxr_putc_ln( &com_ldsc[unit], '\b'); - uptr->BPTR--; - } - break; - - case 03: /* ^C */ - uptr->CMD |= BREAK; - uptr->CMD &= ~RECV; - break; - - default: - if (uptr->BPTR < 253) { - if (ch == 0x00) { - sim_putchar('\007'); - } else { - com_buf[unit][uptr->BPTR++] = ch; - if ((uptr->CMD & BYPASS) == 0) - tmxr_putc_ln( &com_ldsc[unit], data); - } - } else { + } + } else { + ch = com_2741_in[data & 0x7f]; + sim_debug(DEBUG_DATA, dptr, "COML: unit=%d read '%c' %02x\n", unit, data, ch); + if (data & SCPE_BREAK) { + uptr->CMD |= BREAK; + return SCPE_OK; + } + /* Handle end of buffer */ + switch (data & 0x7f) { + case '\r': + case '\n': com_buf[unit][uptr->BPTR++] = 0x5b; com_buf[unit][uptr->BPTR++] = 0x1f; uptr->CMD |= INPUT; uptr->CMD &= ~RECV; - uptr->BPTR &= 0xff; - } + uptr->IPTR = 0; + tmxr_putc_ln( &com_ldsc[unit], '\r'); + tmxr_putc_ln( &com_ldsc[unit], '\n'); + break; + + case 0177: + case '\b': + if (uptr->BPTR != 0) { + uptr->BPTR--; + tmxr_putc_ln( &com_ldsc[unit], '\b'); + tmxr_putc_ln( &com_ldsc[unit], ' '); + tmxr_putc_ln( &com_ldsc[unit], '\b'); + } + break; + + case 025: /* ^U clear line */ + while(uptr->BPTR > 0) { + tmxr_putc_ln( &com_ldsc[unit], '\b'); + tmxr_putc_ln( &com_ldsc[unit], ' '); + tmxr_putc_ln( &com_ldsc[unit], '\b'); + uptr->BPTR--; + } + break; + + case 03: /* ^C */ + uptr->CMD |= BREAK; + uptr->CMD &= ~RECV; + break; + + default: + if (uptr->BPTR < 253) { + if (ch == 0x00) { + sim_putchar('\007'); + } else { + com_buf[unit][uptr->BPTR++] = ch; + if ((uptr->CMD & BYPASS) == 0) + tmxr_putc_ln( &com_ldsc[unit], data); + } + } else { + com_buf[unit][uptr->BPTR++] = 0x5b; + com_buf[unit][uptr->BPTR++] = 0x1f; + uptr->CMD |= INPUT; + uptr->CMD &= ~RECV; + uptr->BPTR &= 0xff; + } + } + } } } } diff --git a/IBM360/ibm360_con.c b/IBM360/ibm360_con.c index 93a1acf..aa08c83 100644 --- a/IBM360/ibm360_con.c +++ b/IBM360/ibm360_con.c @@ -36,7 +36,8 @@ #ifdef NUM_DEVS_CON /* Held in u3 */ -#define CHN_SNS 0x04 /* Sense command */ +#define CMD u3 + #define CON_WR 0x01 /* Write console */ #define CON_ACR 0x09 /* Auto carrage return */ #define CON_RD 0x0a /* Read console */ @@ -54,15 +55,12 @@ /* Upper 11 bits of u3 hold the device address */ /* Input buffer pointer held in u4 */ +#define IPTR u4 -/* in u5 packs sense byte 0,1 and 3 */ +/* in u5 packs sense byte 0 */ /* Sense byte 0 */ -#define SNS_CMDREJ 0x80 /* Command reject */ -#define SNS_INTVENT 0x40 /* Unit intervention required */ +#define SNS u5 -#define CMD u3 -#define IPTR u4 -#define SNS u5 /* std devices. data structures @@ -135,7 +133,7 @@ uint8 con_startcmd(UNIT *uptr, uint8 cmd) { } switch (cmd & 0x7) { - case 2: /* Read command */ + case CMD_READ: /* Read command */ sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd RD\n", u); if (uptr->CMD & CON_REQ) { uptr->CMD &= ~CON_REQ; @@ -158,7 +156,7 @@ uint8 con_startcmd(UNIT *uptr, uint8 cmd) { uptr->SNS = 0; return 0; - case 1: /* Write command */ + case CMD_WRITE: /* Write command */ sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd WR\n", u); if (uptr->CMD & CON_REQ) { uptr->CMD &= ~CON_REQ; @@ -174,7 +172,7 @@ uint8 con_startcmd(UNIT *uptr, uint8 cmd) { } return 0; - case 3: /* Control */ + case CMD_CTL: /* Control */ if (cmd == 0xb) { sim_putchar('\a'); } @@ -189,7 +187,7 @@ uint8 con_startcmd(UNIT *uptr, uint8 cmd) { case 0: /* Status */ return 0; - case 4: /* Sense */ + case CMD_SENSE: /* Sense */ uptr->CMD |= cmd & CON_MSK; return 0; @@ -216,7 +214,7 @@ uint8 con_haltio(UNIT *uptr) { switch (cmd) { case 0: - case 0x4: + case CMD_SENSE: /* Short commands nothing to do */ break; @@ -245,7 +243,7 @@ con_srv(UNIT *uptr) { switch (cmd) { - case 4: /* Sense */ + case CMD_SENSE: /* Sense */ sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd SNS %02x\n", u, uptr->SNS); /* Check if request pending */ ch = uptr->SNS; diff --git a/IBM360/ibm360_cpu.c b/IBM360/ibm360_cpu.c index daa26bf..c1711eb 100644 --- a/IBM360/ibm360_cpu.c +++ b/IBM360/ibm360_cpu.c @@ -3099,11 +3099,18 @@ save_dbl: } switch(reg) { case 0x0: /* CONCS */ - /* Connect channel set */ + /* Connect channel set */ case 0x1: /* DISCS */ - /* Disconnect channel set */ - cc = 3; + /* Disconnect channel set */ + if (addr1 == 0) { + cc = 0; + } else { + cc = 3; + } break; +// cc = 3; +// storepsw(OPPSW, IRC_OPR); +// goto supress; case 0x2: /* STIDP */ /* Store CPUID in double word */ diff --git a/IBM360/ibm360_dasd.c b/IBM360/ibm360_dasd.c index b81cc65..9788ddc 100644 --- a/IBM360/ibm360_dasd.c +++ b/IBM360/ibm360_dasd.c @@ -68,117 +68,112 @@ UNIT_FIX | SET_TYPE(6) -#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 0x1B /* 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_RD_SECT 0x22 /* Read sector counter */ -#define DK_SETSECT 0x23 /* Set sector */ -#define DK_RD_BUFF 0xA4 /* Read and reset record log */ -#define DK_MT 0x80 /* Multi track flag */ +/* Held in u3 */ +#define CMD 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 0x1B /* 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_RD_SECT 0x22 /* Read sector counter */ +#define DK_SETSECT 0x23 /* Set sector */ +#define DK_RD_BUFF 0xA4 /* Read and reset record log */ +#define DK_MT 0x80 /* Multi track flag */ /* u3 */ -#define DK_INDEX 0x00100 /* Index seen in command */ -#define DK_NOEQ 0x00200 /* Not equal compare */ -#define DK_HIGH 0x00400 /* High compare */ -#define DK_PARAM 0x00800 /* Parameter in u4 */ -#define DK_MSET 0x01000 /* Mode set command already */ -#define DK_SHORTSRC 0x02000 /* Last search was short */ -#define DK_SRCOK 0x04000 /* Last search good */ -#define DK_CYL_DIRTY 0x08000 /* Current cylinder dirty */ -#define DK_DONE 0x10000 /* Write command done, zero fill */ -#define DK_INDEX2 0x20000 /* Second index seen */ -#define DK_OVFLOW 0x40000 /* Reading in overflow */ +#define DK_INDEX 0x00100 /* Index seen in command */ +#define DK_NOEQ 0x00200 /* Not equal compare */ +#define DK_HIGH 0x00400 /* High compare */ +#define DK_PARAM 0x00800 /* Parameter in u4 */ +#define DK_MSET 0x01000 /* Mode set command already */ +#define DK_SHORTSRC 0x02000 /* Last search was short */ +#define DK_SRCOK 0x04000 /* Last search good */ +#define DK_CYL_DIRTY 0x08000 /* Current cylinder dirty */ +#define DK_DONE 0x10000 /* Write command done, zero fill */ +#define DK_INDEX2 0x20000 /* Second index seen */ +#define DK_OVFLOW 0x40000 /* Reading in overflow */ -#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_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 0x08 /* Allow cyl/head only */ -#define DK_MSK_SKALLHD 0x10 /* Allow head only */ -#define DK_MSK_SKNONE 0x18 /* Allow no seeks */ -#define DK_MSK_SK 0x18 /* Seek mask */ +#define DK_MSK_SKALLSKR 0x00 /* Allow all seek/recal */ +#define DK_MSK_SKALLCLY 0x08 /* Allow cyl/head only */ +#define DK_MSK_SKALLHD 0x10 /* Allow head only */ +#define DK_MSK_SKNONE 0x18 /* Allow no seeks */ +#define DK_MSK_SK 0x18 /* Seek mask */ /* Top 11 bits of u3 hold the device address */ /* u4 */ /* Holds the current track and head */ +#define CCH u4 #define DK_V_TRACK 8 -#define DK_M_TRACK 0x3ff00 /* Max 1024 cylinders */ +#define DK_M_TRACK 0x3ff00 /* Max 1024 cylinders */ #define DK_V_HEAD 0 -#define DK_M_HEAD 0xff /* Max 256 heads */ +#define DK_M_HEAD 0xff /* Max 256 heads */ +#define DK_IDLE 0x80000 /* Drive is idle */ /* u5 */ +/* Sense bytes 0,1,2,3, rest generated */ +#define SNS u5 /* Sense byte 0 */ -#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_TRKCND 0x02 /* Track Condition */ -#define SNS_SEEKCK 0x01 /* Seek Check */ /* Sense byte 1 */ -#define SNS_DCCNT 0x80 /* Data Check Count */ -#define SNS_TRKOVR 0x40 /* Track Overrun */ -#define SNS_ENDCYL 0x20 /* End of Cylinder */ -#define SNS_INVSEQ 0x10 /* Invalid Sequence */ -#define SNS_NOREC 0x08 /* No record found */ -#define SNS_WRP 0x04 /* Write Protect */ -#define SNS_ADDR 0x02 /* Missing Address Mark */ -#define SNS_OVRINC 0x01 /* Overflow Incomplete */ +#define SNS_DCCNT 0x80 /* Data Check Count */ +#define SNS_TRKOVR 0x40 /* Track Overrun */ +#define SNS_ENDCYL 0x20 /* End of Cylinder */ +#define SNS_INVSEQ 0x10 /* Invalid Sequence */ +#define SNS_NOREC 0x08 /* No record found */ +#define SNS_WRP 0x04 /* Write Protect */ +#define SNS_ADDR 0x02 /* Missing Address Mark */ +#define SNS_OVRINC 0x01 /* Overflow Incomplete */ /* Sense byte 2 */ -#define SNS_BYTE2 0x00 /* Diags Use */ +#define SNS_BYTE2 0x00 /* Diags Use */ /* Sense byte 3 */ -#define SNS_BYTE3 0x00 /* Diags Use */ +#define SNS_BYTE3 0x00 /* Diags Use */ /* saved in state field of data */ /* Record position, high 4 bits, low internal short count */ -#define DK_POS_INDEX 0x0 /* At Index Mark */ -#define DK_POS_HA 0x1 /* In home address (c) */ -#define DK_POS_CNT 0x2 /* In count (c) */ -#define DK_POS_KEY 0x3 /* In Key area */ -#define DK_POS_DATA 0x4 /* In Data area */ -#define DK_POS_AM 0x5 /* Address mark before record */ -#define DK_POS_END 0x8 /* Past end of data */ -#define DK_POS_SEEK 0xF /* In seek */ +#define DK_POS_INDEX 0x0 /* At Index Mark */ +#define DK_POS_HA 0x1 /* In home address (c) */ +#define DK_POS_CNT 0x2 /* In count (c) */ +#define DK_POS_KEY 0x3 /* In Key area */ +#define DK_POS_DATA 0x4 /* In Data area */ +#define DK_POS_AM 0x5 /* Address mark before record */ +#define DK_POS_END 0x8 /* Past end of data */ +#define DK_POS_SEEK 0xF /* In seek */ /* u6 holds last command */ /* Held in ccyl entry */ - -#define CMD u3 -#define CCH u4 -#define SNS u5 #define LCMD u6 /* Pointer held in up7 */ @@ -199,6 +194,7 @@ struct dasd_t uint8 rec; /* Current record number */ uint8 ovfl; /* Current record overflow record */ uint16 count; /* Remaining in current operation */ + int rcount; /* Number of rotations without command */ }; struct disk_t @@ -396,6 +392,10 @@ uint8 dasd_startio(UNIT *uptr) { sim_debug(DEBUG_CMD, dptr, "start io unit=%d %d %d %d\n", unit, data->tstart, data->tpos, data->rpos); } + if ((uptr->CCH & DK_IDLE) != 0) { + uptr->CCH &= ~DK_IDLE; + sim_activate(uptr, 100); + } sim_debug(DEBUG_CMD, dptr, "start io unit=%d\n", unit); return 0; } @@ -700,6 +700,15 @@ ntrack: uptr->CMD &= ~DK_SRCOK; data->tstart = data->tsize * (uptr->CCH & 0xff); data->tpos = data->rpos = 0; + if (cmd == 0) { + if (++data->rcount == 10) { + uptr->CCH |= DK_IDLE; + break; + } + } else { + data->rcount = 0; + uptr->CCH &= ~DK_IDLE; + } rec = &data->cbuf[data->rpos + data->tstart]; da = &data->cbuf[data->tpos + data->tstart]; data->state = DK_POS_HA; @@ -1025,7 +1034,7 @@ sense_end: if (disk_type[type].sen_cnt > 6) { uptr->SNS |= SNS_CMDREJ | (0 << 28) | (3 << 24); } else { - uptr->SNS |= SNS_CMDREJ|SNS_SEEKCK; + uptr->SNS |= SNS_CMDREJ|SNS_OPRCHK; } chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; @@ -1044,7 +1053,7 @@ sense_end: if (disk_type[type].sen_cnt > 6) { uptr->SNS |= SNS_CMDREJ | (0 << 28) | (4 << 24); } else { - uptr->SNS |= SNS_CMDREJ|SNS_SEEKCK; + uptr->SNS |= SNS_CMDREJ|SNS_OPRCHK; } chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; @@ -1063,7 +1072,7 @@ sense_end: if (disk_type[type].sen_cnt > 6) { uptr->SNS |= SNS_CMDREJ | (0 << 28) | (4 << 24); } else { - uptr->SNS |= SNS_CMDREJ|SNS_SEEKCK; + uptr->SNS |= SNS_CMDREJ|SNS_OPRCHK; } chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; diff --git a/IBM360/ibm360_defs.h b/IBM360/ibm360_defs.h index b4cf72a..1416b85 100644 --- a/IBM360/ibm360_defs.h +++ b/IBM360/ibm360_defs.h @@ -308,43 +308,54 @@ typedef struct dib { #define UNIT_M_CTYPE (3 << UNIT_V_CTYPE) /* Channel sense bytes */ -#define SNS_ATTN 0x80 /* Unit attention */ -#define SNS_SMS 0x40 /* Status modifier */ -#define SNS_CTLEND 0x20 /* Control unit end */ -#define SNS_BSY 0x10 /* Unit Busy */ -#define SNS_CHNEND 0x08 /* Channel end */ -#define SNS_DEVEND 0x04 /* Device end */ -#define SNS_UNITCHK 0x02 /* Unit check */ -#define SNS_UNITEXP 0x01 /* Unit exception */ +#define SNS_ATTN 0x80 /* Unit attention */ +#define SNS_SMS 0x40 /* Status modifier */ +#define SNS_CTLEND 0x20 /* Control unit end */ +#define SNS_BSY 0x10 /* Unit Busy */ +#define SNS_CHNEND 0x08 /* Channel end */ +#define SNS_DEVEND 0x04 /* Device end */ +#define SNS_UNITCHK 0x02 /* Unit check */ +#define SNS_UNITEXP 0x01 /* Unit exception */ /* Command masks */ -#define CMD_TYPE 0x3 /* Type mask */ -#define CMD_CHAN 0x0 /* Channel command */ -#define CMD_WRITE 0x1 /* Write command */ -#define CMD_READ 0x2 /* Read command */ -#define CMD_CTL 0x3 /* Control command */ -#define CMD_SENSE 0x4 /* Sense channel command */ -#define CMD_TIC 0x8 /* Transfer in channel */ -#define CMD_RDBWD 0xc /* Read backward */ +#define CMD_TYPE 0x3 /* Type mask */ +#define CMD_CHAN 0x0 /* Channel command */ +#define CMD_WRITE 0x1 /* Write command */ +#define CMD_READ 0x2 /* Read command */ +#define CMD_CTL 0x3 /* Control command */ +#define CMD_SENSE 0x4 /* Sense channel command */ +#define CMD_TIC 0x8 /* Transfer in channel */ +#define CMD_RDBWD 0xc /* Read backward */ -#define STATUS_ATTN 0x8000 /* Device raised attention */ -#define STATUS_MOD 0x4000 /* Status modifier */ -#define STATUS_CTLEND 0x2000 /* Control end */ -#define STATUS_BUSY 0x1000 /* Device busy */ -#define STATUS_CEND 0x0800 /* Channel end */ -#define STATUS_DEND 0x0400 /* Device end */ -#define STATUS_CHECK 0x0200 /* Unit check */ -#define STATUS_EXPT 0x0100 /* Unit excpetion */ -#define STATUS_PCI 0x0080 /* Program interupt */ -#define STATUS_LENGTH 0x0040 /* Incorrect lenght */ -#define STATUS_PCHK 0x0020 /* Program check */ -#define STATUS_PROT 0x0010 /* Protection check */ -#define STATUS_CDATA 0x0008 /* Channel data check */ -#define STATUS_CCNTL 0x0004 /* Channel control check */ -#define STATUS_INTER 0x0002 /* Channel interface check */ -#define STATUS_CHAIN 0x0001 /* Channel chain check */ +#define STATUS_ATTN 0x8000 /* Device raised attention */ +#define STATUS_MOD 0x4000 /* Status modifier */ +#define STATUS_CTLEND 0x2000 /* Control end */ +#define STATUS_BUSY 0x1000 /* Device busy */ +#define STATUS_CEND 0x0800 /* Channel end */ +#define STATUS_DEND 0x0400 /* Device end */ +#define STATUS_CHECK 0x0200 /* Unit check */ +#define STATUS_EXPT 0x0100 /* Unit excpetion */ +#define STATUS_PCI 0x0080 /* Program interupt */ +#define STATUS_LENGTH 0x0040 /* Incorrect lenght */ +#define STATUS_PCHK 0x0020 /* Program check */ +#define STATUS_PROT 0x0010 /* Protection check */ +#define STATUS_CDATA 0x0008 /* Channel data check */ +#define STATUS_CCNTL 0x0004 /* Channel control check */ +#define STATUS_INTER 0x0002 /* Channel interface check */ +#define STATUS_CHAIN 0x0001 /* Channel chain check */ -#define NO_DEV 0xffff /* Code for no device */ +#define NO_DEV 0xffff /* Code for no device */ + +/* Basic sense information */ +#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_UNITSPC 0x04 /* Specific to unit */ +#define SNS_CTLCHK 0x02 /* Timeout on device */ +#define SNS_OVRRUN 0x02 /* Data Overrun */ +#define SNS_OPRCHK 0x01 /* Invalid operation to device */ void post_extirq(); diff --git a/IBM360/ibm360_lpr.c b/IBM360/ibm360_lpr.c index 1740fce..3df0745 100644 --- a/IBM360/ibm360_lpr.c +++ b/IBM360/ibm360_lpr.c @@ -39,37 +39,29 @@ #define UNIT_M_FCB (3 << UNIT_V_FCB) /* u3 hold command and status information */ -#define CHN_SNS 0x04 /* Sense command */ +#define CMD u3 -#define LPR_WR 0x01 /* Write command */ -#define LPR_SPKCMD 0x03 /* Skip command */ -#define LPR_SPCMSK 0x18 /* Space after printing */ -#define LPR_SKIP 0x80 /* Skip Flag */ -#define LPR_SKPCHN 0x78 /* Skip Channel */ -#define LPR_CMDMSK 0xff /* Mask command part. */ -#define LPR_FULL 0x100 /* Buffer full */ -#define LPR_DATCHK 0x200 /* Don't return data-check */ +#define LPR_WR 0x01 /* Write command */ +#define LPR_SPKCMD 0x03 /* Skip command */ +#define LPR_SPCMSK 0x18 /* Space after printing */ +#define LPR_SKIP 0x80 /* Skip Flag */ +#define LPR_SKPCHN 0x78 /* Skip Channel */ +#define LPR_CMDMSK 0xff /* Mask command part. */ +#define LPR_FULL 0x100 /* Buffer full */ +#define LPR_DATCHK 0x200 /* Don't return data-check */ /* Upper 11 bits of u3 hold the device address */ /* u4 holds current line */ -/* in u5 packs sense byte 0,1 and 3 */ +#define LINE u4 + +/* in u5 packs sense byte 0 */ /* Sense byte 0 */ -#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_SEQUENCE 0x02 /* Unusual sequence */ -#define SNS_CHN9 0x01 /* Channel 9 on printer */ -#define SNS_CHN12 0x100 +#define SNS u5 +#define SNS_CHN9 SNS_OPRCHK /* Channel 9 on printer, 0x1 */ +#define SNS_CHN12 0x100 /* u6 hold buffer position */ - -#define CMD u3 -#define LINE u4 -#define SNS u5 #define POS u6 @@ -109,9 +101,9 @@ UNIT lpr_unit[] = { #if NUM_DEVS_LPR > 1 {UDATA(lpr_srv, UNIT_LPR | UNIT_DIS, 66), 300, UNIT_ADDR(0x1E)}, #if NUM_DEVS_LPR > 2 - {UDATA(lpr_srv, UNIT_LPR | UNIT_DIS, 66), 300, UNIT_ADDR(0x40E)}, + {UDATA(lpr_srv, UNIT_LPR | UNIT_DIS, 66), 300, UNIT_ADDR(0x2E)}, #if NUM_DEVS_LPR > 3 - {UDATA(lpr_srv, UNIT_LPR | UNIT_DIS, 66), 300, UNIT_ADDR(0x41E)}, + {UDATA(lpr_srv, UNIT_LPR | UNIT_DIS, 66), 300, UNIT_ADDR(0x3E)}, #endif #endif #endif @@ -147,7 +139,7 @@ static CONST uint16 legacy[] = { 0x040, 0x000, 0x000, 0x000, 0x000, 0x000, 0x020, 0x000, 0x000, 0x000, /* 31 - 40 */ 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, 0x000, 0x000, 0x004, 0x000, /* 41 - 50 */ 0x000, 0x000, 0x000, 0x000, 0x002, 0x000, 0x000, 0x000, 0x000, 0x000, /* 51 - 60 */ -0x001, 0x000, 0x008, 0x000, 0x000, 0x000, 0x1000 }; /* 61 - 66 */ +0x001, 0x000, 0x008, 0x000, 0x000, 0x001, 0x1000 }; /* 61 - 66 */ /* PROGRAMMMING NOTE: the below cctape value SHOULD match the same corresponding fcb value! @@ -160,7 +152,7 @@ static CONST uint16 std1[] = { 0x040, 0x000, 0x000, 0x000, 0x000, 0x000, 0x020, 0x000, 0x000, 0x000, /* 31 - 40 */ 0x000, 0x000, 0x010, 0x000, 0x000, 0x000, 0x000, 0x000, 0x008, 0x000, /* 41 - 50 */ 0x000, 0x000, 0x000, 0x000, 0x004, 0x000, 0x000, 0x000, 0x000, 0x000, /* 51 - 60 */ -0x002, 0x000, 0x001, 0x000, 0x000, 0x000, 0x1000 }; /* 61 - 66 */ +0x002, 0x000, 0x001, 0x000, 0x000, 0x001, 0x1000 }; /* 61 - 66 */ static CONST uint16 none[] = { /* 1 2 3 4 5 6 7 8 9 10 lines */ @@ -170,7 +162,7 @@ static CONST uint16 none[] = { 0x040, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 31 - 40 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 41 - 50 */ 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, 0x000, /* 51 - 60 */ -0x002, 0x000, 0x000, 0x000, 0x000, 0x000, 0x1000 }; /* 61 - 66 */ +0x002, 0x000, 0x000, 0x000, 0x000, 0x001, 0x1000 }; /* 61 - 66 */ static CONST uint16 *fcb_ptr[] = { legacy, std1, none, NULL}; @@ -262,8 +254,9 @@ print_line(UNIT * uptr) char out[150]; /* Temp conversion buffer */ int i; int u = (uptr - lpr_unit); - int l = (uptr->CMD >> 3) & 0x1f; - int f; + int space = (uptr->CMD >> 3) & 0x1f; + int flag; + int line; int mask; /* Dump buffer if full */ @@ -293,12 +286,12 @@ print_line(UNIT * uptr) memset(&lpr_data[u].lbuff[0], 0, 144); } - f = 0; - if (l < 4) { - while(l != 0) { + flag = 0; + if (space < 4) { + while(space != 0) { sim_fwrite("\r\n", 1, 2, uptr->fileref); - f = 1; uptr->pos += 2; + flag = 1; if ((uptr->CMD & 03) == 0x1) { if ((lpr_data[u].fcb[uptr->LINE] & (0x1000 >> 9)) != 0) { uptr->SNS |= SNS_CHN9; @@ -309,41 +302,46 @@ print_line(UNIT * uptr) } if ((lpr_data[u].fcb[uptr->LINE] & 0x1000) != 0 || ((uint32)uptr->LINE) >= uptr->capac) { - if (f) + if (flag) { sim_fwrite("\r\n", 1, 2, uptr->fileref); + uptr->pos += 2; + } sim_fwrite("\f\r\n", 1, 3, uptr->fileref); + uptr->SNS |= SNS_CHN12; + uptr->pos += 3; uptr->LINE = 0; } else { uptr->LINE++; } - l--; + space--; } return; } - mask = 0x1000 >> (1 & 0xf); - f = 0; /* Flag if we skipped to new page */ - l = 0; /* What line we should be on */ + mask = 0x1000 >> (space & 0xf); + flag = 0; /* Flag if we skipped to new page */ + line = 0; /* What line we should be on */ - for (i = uptr->LINE; (lpr_data[u].fcb[i] & mask) == 0 && - uptr->LINE != i; i++) { - l++; + for (i = uptr->LINE; (lpr_data[u].fcb[i] & mask) == 0; i++) { + line++; if ((lpr_data[u].fcb[i] & 0x1000) != 0 || ((uint32)i) >= uptr->capac) { sim_fwrite("\r\n\f\r\n", 1, 5, uptr->fileref); - uptr->pos += 3; - f = 1; - l = 0; + uptr->pos += 5; + uptr->SNS |= SNS_CHN12; + flag = 1; + line = 0; + break; } } /* If past end of form clear row */ - if (f) { + if (flag) { uptr->LINE = 0; } if ((lpr_data[u].fcb[i] & mask) != 0) { - while (l-- > 0) { + while (line-- > 0) { sim_fwrite("\r\n", 1, 2, uptr->fileref); uptr->pos += 2; uptr->LINE++; diff --git a/IBM360/ibm360_mt.c b/IBM360/ibm360_mt.c index bd76de4..03f4edb 100644 --- a/IBM360/ibm360_mt.c +++ b/IBM360/ibm360_mt.c @@ -48,6 +48,9 @@ DEV_BUF_NUM(x) +/* u3 hold command and status information */ +#define CMD u3 + #define MT_WRITE 0x01 /* Write command */ #define MT_READ 0x02 /* Read command */ #define MT_RDBK 0x0c /* Read Backward */ @@ -98,17 +101,11 @@ /* Upper 11 bits of u3 hold the device address */ /* in u4 is current buffer position */ +#define POS u4 /* in u5 packs sense byte 0,1 and 3 */ +#define SNS u5 /* Sense byte 0 */ -#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_WCZERO 0x02 /* Write with no data */ -#define SNS_CVTCHK 0x01 /* Data conversion error */ /* Sense byte 1 */ #define SNS_NOISE 0x80 /* Noise record */ @@ -140,13 +137,10 @@ #define MT_CONV3 0xc0 /* u6 holds the packed characters and unpack counter */ +#define CPOS u6 #define BUF_EMPTY(u) (u->hwmark == 0xFFFFFFFF) #define CLR_BUF(u) u->hwmark = 0xFFFFFFFF -#define CMD u3 -#define POS u4 -#define SNS u5 -#define CPOS u6 uint8 mt_startio(UNIT *uptr); uint8 mt_startcmd(UNIT *uptr, uint8 cmd); @@ -726,7 +720,7 @@ t_stat mt_srv(UNIT * uptr) uptr->CMD &= ~MT_CMDMSK; mt_error(uptr, addr, r, dptr); /* Record errors */ } else { - uptr->SNS |= SNS_WCZERO; /* Write with no data */ + uptr->SNS |= SNS_UNITCHK; /* Write with no data */ } } else { if ((uptr->flags & MTUF_9TR) == 0) { diff --git a/IBM360/ibm360_scom.c b/IBM360/ibm360_scom.c index cd31ae8..436fd60 100644 --- a/IBM360/ibm360_scom.c +++ b/IBM360/ibm360_scom.c @@ -32,6 +32,8 @@ /* u3 */ +#define CMD u3 + #define CMD_WR 0x01 /* Write data to com line */ #define CMD_RD 0x02 /* Read buffer */ #define CMD_NOP 0x03 /* Nop scommand */ @@ -43,7 +45,7 @@ #define CMD_WSF 0x11 /* Write structured field */ #define CMD_SNSID 0xE4 /* Sense ID */ -/* u3 second byte */ +/* u3 second byte, status */ #define RECV 0x00100 /* Recieving data */ #define SEND 0x00200 /* Sending data */ #define ENAB 0x00400 /* Line enabled */ @@ -57,26 +59,18 @@ /* u4 */ /* Where we are reading from */ +#define IPTR u4 /* u5 */ +#define SNS u5 /* Sense byte 0 */ -#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_UNITSPC 0x04 /* Specific to unit */ -#define SNS_CTLCHK 0x02 /* Timeout on device */ -#define SNS_OPRCHK 0x01 /* Invalid operation to device */ +#define CONN 0x100 /* Unit connected */ /* u6 */ /* Pointer into buffer */ - -#define CMD u3 -#define IPTR u4 -#define SNS u5 #define BPTR u6 + #define TC_WILL 0x1 /* Option in will state */ #define TC_WONT 0x2 /* Wont do option */ #define TC_DO 0x4 /* Will do option. */ @@ -207,14 +201,25 @@ uint8 scoml_startcmd(UNIT *uptr, uint8 cmd) { case 0x2: /* Read scommand */ case 0x1: /* Write scommand */ case 0x3: /* Control */ - if (cmd != CMD_NOP) - uptr->SNS = 0; + if (cmd != CMD_NOP) { + if ((uptr->SNS & CONN) == 0) { + /* If no connection yet, pretend unit is powered off. + ATTN & DE at connection will revive activity. */ +// uptr->CMD &= ~0xff; + // if ((uptr->SNS & SNS_INTVENT) == 0) { + // set_devattn(addr, SNS_UNITCHK); + // } + uptr->SNS |= SNS_INTVENT; + return SNS_UNITCHK; + } + uptr->SNS &= CONN; + } uptr->CMD |= cmd; sim_activate(uptr, 200); return 0; case 0x0: /* Status */ - if (cmd == 0x4 || cmd == CMD_SNSID) { /* Sense */ + if (cmd == CMD_SENSE || cmd == CMD_SNSID) { /* Sense */ uptr->CMD |= cmd; sim_activate(uptr, 200); return 0; @@ -241,7 +246,7 @@ uint8 scoml_haltio(UNIT *uptr) { switch (cmd) { case 0: - case 0x4: + case CMD_SENSE: case CMD_SNSID: /* Sense ID */ case CMD_SEL: /* Select */ case CMD_NOP: /* Nop scommand */ @@ -272,14 +277,22 @@ t_stat scoml_srv(UNIT * uptr) int cmd = uptr->CMD & 0xff; uint8 ch; - if (scom_ldsc[unit].conn == 0 && cmd != 0x4) { + +#if 0 + if (scom_ldsc[unit].conn == 0 && + cmd != CMD_SENSE && cmd != CMD_SNSID && cmd != CMD_NOP) { + sim_debug(DEBUG_DETAIL, dptr, "unit=%d disco\n", unit); /* If no connection yet, pretend unit is powered off. ATTN & DE at connection will revive activity. */ - uptr->SNS |= SNS_INTVENT; uptr->CMD &= ~0xff; + // if ((uptr->SNS & SNS_INTVENT) == 0) { + // set_devattn(addr, SNS_UNITCHK); + // } +// uptr->SNS |= SNS_INTVENT; chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); return SCPE_OK; } +#endif if ((uptr->CMD & (RECV|DATA)) != 0) { sim_activate(uptr, 200); @@ -290,7 +303,7 @@ t_stat scoml_srv(UNIT * uptr) case 0: break; - case 0x4: + case CMD_SENSE: ch = uptr->SNS & 0xff; sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch); chan_write_byte(addr, &ch) ; @@ -314,7 +327,6 @@ t_stat scoml_srv(UNIT * uptr) case CMD_RDMD: /* Read modified */ case CMD_RD: /* Read in data from scom line */ - uptr->SNS = 0; if (uptr->CMD & HALT) { uptr->CMD &= ~(0xFF|RECV); return SCPE_OK; @@ -323,7 +335,7 @@ t_stat scoml_srv(UNIT * uptr) if (scom_ldsc[unit].conn == 0) { sim_debug(DEBUG_DETAIL, dptr, "unit=%d disco\n", unit); uptr->CMD &= ~(0xff|INPUT|ENAB|RECV|INIT1|SEND|DATA); - uptr->SNS = SNS_CTLCHK; + uptr->SNS = SNS_UNITCHK; uptr->BPTR = 0; uptr->IPTR = 0; chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); @@ -366,7 +378,6 @@ t_stat scoml_srv(UNIT * uptr) case CMD_WR: /* Write data to com line */ ch = REMOTE_WRT; write: - uptr->SNS = 0; if (uptr->CMD & HALT) { uptr->CMD &= ~(0xFF|SEND); return SCPE_OK; @@ -380,7 +391,7 @@ write: if (scom_ldsc[unit].conn == 0) { sim_debug(DEBUG_DETAIL, dptr, "unit=%d disco\n", unit); uptr->CMD &= ~(0xff|INPUT|ENAB|RECV|INIT1|SEND|DATA); - uptr->SNS = SNS_CTLCHK; + uptr->SNS = SNS_UNITCHK; uptr->BPTR = 0; uptr->IPTR = 0; chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); @@ -412,7 +423,7 @@ write: case CMD_SEL: /* Select */ uptr->CMD &= ~0xff; - uptr->SNS = 0; + uptr->SNS &= CONN; sim_debug(DEBUG_CMD, dptr, "COM: unit=%d select done\n", unit); chan_end(addr, SNS_CHNEND|SNS_DEVEND); break; @@ -445,8 +456,8 @@ t_stat scom_scan(UNIT * uptr) scom_sendoption(line, ln, DO, OPTION_EOR); line->CMD |= ENAB|DATA|INIT1; line->CMD &= ~(RECV|SEND); - line->SNS = 0; - set_devattn(GET_UADDR(line->CMD), SNS_ATTN); + line->SNS = CONN; + set_devattn(GET_UADDR(line->CMD), SNS_DEVEND); sim_activate(line, 20000); } @@ -454,10 +465,18 @@ t_stat scom_scan(UNIT * uptr) for (ln = 0; ln < scom_desc.lines; ln++) { line = &scoml_unit[ln]; if ((line->CMD & (SEND|RECV|ENAB)) == ENAB && tmxr_rqln(&scom_ldsc[ln]) > 0) { - if ((line->CMD & (DATA|INIT1)) != 0 || (line->CMD & 0xff) != 0) + if ((line->CMD & (DATA|INIT1)) != 0 || (line->CMD & 0xff) != 0) { sim_activate(line, 200); - else - set_devattn(GET_UADDR(line->CMD), SNS_ATTN); +// } else { +// tmxr_reset_ln(&scom_ldsc[ln]); + // sim_debug(DEBUG_DETAIL, &scom_dev, "SCOM line disconnect %d\n", ln); + // set_devattn(GET_UADDR(line->CMD), SNS_ATTN); + } + } + if (scom_ldsc[ln].conn == 0 && (line->SNS & CONN) != 0) { + sim_debug(DEBUG_DETAIL, &scom_dev, "SCOM line disconnect %d\n", ln); + set_devattn(GET_UADDR(line->CMD), SNS_ATTN); +// tmxr_reset_ln(&scom_ldsc[ln]); } } tmxr_poll_tx(&scom_desc); @@ -545,7 +564,7 @@ scom_readinput(UNIT *uptr) scom_sendoption(uptr, unit, DO, OPTION_BINARY); } } - + break; default: if ((data->option_state[ch] & TC_DONT) == 0) diff --git a/IBM360/ibm360_scon.c b/IBM360/ibm360_scon.c index 3cdef14..4ee2a92 100644 --- a/IBM360/ibm360_scon.c +++ b/IBM360/ibm360_scon.c @@ -38,7 +38,8 @@ #ifdef NUM_DEVS_SCON /* Held in u3 */ -#define CHN_SNS 0x04 /* Sense command */ +/* For 1052/3215 type console */ +#define CON_SNS 0x04 /* Sense command */ #define CON_WR 0x01 /* Write console */ #define CON_ACR 0x09 /* Auto carrage return */ #define CON_RD 0x0a /* Read console */ @@ -46,13 +47,73 @@ #define CON_NOP 0x03 /* No op command */ #define CON_MSK 0x0f /* Command mask */ +/* For 3277 type console */ +#define CMD_WR 0x01 /* Write data to com line */ +#define CMD_RD 0x02 /* Read buffer */ +#define CMD_NOP 0x03 /* Nop scommand */ +#define CMD_WRER 0x05 /* Erase and write data */ +#define CMD_RDMD 0x06 /* Read modified */ +#define CMD_SEL 0x0B /* Select */ +#define CMD_WRERALT 0x0D /* Write erase alternative */ +#define CMD_EAU 0x0F /* Erase all un protected */ +#define CMD_WSF 0x11 /* Write structured field */ +#define CMD_SNSID 0xE4 /* Sense ID */ + /* Status held in u3 */ +/* For 1052/3215 type console */ #define CON_INPUT 0x100 /* Input ready for unit */ #define CON_CR 0x200 /* Output at beginning of line */ #define CON_REQ 0x400 /* Request key pressed */ #define CON_OUTPUT 0x800 /* Output characters since R */ #define CON_CANCEL 0x1000 /* Control C pressed */ +/* For 3277 type console */ +#define RECV 0x00100 /* Recieving data */ +#define SEND 0x00200 /* Sending data */ +#define ENAB 0x00400 /* Line enabled */ +#define DATA 0x00800 /* Data available */ +#define INIT1 0x01000 /* Send DO EOR, waiting WILL EOR */ +#define INPUT 0x02000 /* Input ready */ +#define ATTN 0x04000 /* Send attention signal */ +#define HALT 0x08000 /* Halt operation */ + +#define TC_WILL 0x1 /* Option in will state */ +#define TC_WONT 0x2 /* Wont do option */ +#define TC_DO 0x4 /* Will do option. */ +#define TC_DONT 0x8 /* Dont do option */ + +#define IAC 255 /* Interpret as command */ +#define DONT 254 /* Dont use option */ +#define DO 253 /* Use this option */ +#define WONT 252 /* I wont use this option */ +#define WILL 251 /* I will use this option */ +#define IP 244 /* Interrupt pending */ +#define BREAK 243 /* Break */ +#define EOR 239 /* End of record */ + +/* Telnet options we care about */ +#define OPTION_BINARY 0 /* Send 8 bit data */ +#define OPTION_ECHO 1 /* Echo */ +#define OPTION_SGA 3 /* Set go ahead */ +#define OPTION_TERMINAL 24 /* Request terminal type */ +#define OPTION_EOR 25 /* Handle end of record */ + +#define TS_DATA 0 /* Regular state */ +#define TS_IAC 1 /* Have seen IAC */ +#define TS_WILL 2 /* Have seen IAC WILL */ +#define TS_WONT 3 /* Have seen IAC WONT */ +#define TS_DO 4 /* Have seen IAC DO */ +#define TS_DONT 5 /* Have seen IAC DONT */ + +/* Remote orders */ +#define REMOTE_EAU 0x6F /* Erase all unprotected */ +#define REMOTE_EW 0xF5 /* Erase/Write */ +#define REMOTE_RB 0xF2 /* Read Buffer */ +#define REMOTE_RM 0x6e /* Read Modified */ +#define REMOTE_WRERALT 0x7e /* Write erase alternative */ +#define REMOTE_WRT 0xF1 /* Write */ +#define REMOTE_WSF 0xF3 /* Write structured field */ + /* Upper 11 bits of u3 hold the device address */ /* Input buffer pointer held in u4 */ @@ -146,7 +207,7 @@ uint8 scon_startcmd(UNIT *uptr, uint8 cmd) { } switch (cmd & 0x7) { - case 2: /* Read command */ + case CMD_READ: /* Read command */ sim_debug(DEBUG_CMD, &scon_dev, "%d: Cmd RD\n", u); if (uptr->CMD & CON_REQ) { uptr->CMD &= ~CON_REQ; @@ -169,7 +230,7 @@ uint8 scon_startcmd(UNIT *uptr, uint8 cmd) { uptr->SNS = 0; return 0; - case 1: /* Write command */ + case CMD_WRITE: /* Write command */ sim_debug(DEBUG_CMD, &scon_dev, "%d: Cmd WR\n", u); if (uptr->CMD & CON_REQ) { uptr->CMD &= ~CON_REQ; @@ -185,7 +246,7 @@ uint8 scon_startcmd(UNIT *uptr, uint8 cmd) { } return 0; - case 3: /* Control */ + case CMD_CTL: /* Control */ if (cmd == CON_ALR) { tmxr_putc_ln(&scon_ldsc[u], '\a'); } @@ -200,7 +261,7 @@ uint8 scon_startcmd(UNIT *uptr, uint8 cmd) { case 0: /* Status */ return 0; - case 4: /* Sense */ + case CMD_SENSE: /* Sense */ uptr->CMD |= cmd & CON_MSK; return 0; @@ -255,7 +316,7 @@ scon_srv(UNIT *uptr) { int delay = 1000; switch (cmd) { - case 4: /* Sense */ + case CMD_SENSE: /* Sense */ sim_debug(DEBUG_CMD, &scon_dev, "%d: Cmd SNS %02x\n", u, uptr->SNS); /* Check if request pending */ data = uptr->SNS;