diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index 4beced1..6ee0c04 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -363,6 +363,8 @@ loop: chan_status[chan] &= 0xff; chan_status[chan] |= dibp->start_cmd(uptr, chan, ccw_cmd[chan]) << 8; if (chan_status[chan] & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) { + sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel %03x abort %04x\n", + chan, chan_status[chan]); chan_status[chan] |= STATUS_CEND; ccw_flags[chan] = 0; ccw_cmd[chan] = 0; @@ -617,15 +619,7 @@ chan_end(uint16 addr, uint8 flags) { sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x, %x) %x %04x %04x\n", addr, flags, ccw_count[chan], ccw_flags[chan], chan_status[chan]); -#if 0 - /* If PCI flag set, trigger interrupt */ - if (ccw_flags[chan] & FLAG_PCI) { - chan_status[chan] |= STATUS_PCI; - ccw_flags[chan] &= ~FLAG_PCI; - sim_debug(DEBUG_CMD, &cpu_dev, "Set PCI %02x end\n", chan); - irq_pend = 1; - } -#endif + /* Flush buffer if there was any change */ if (chan_byte[chan] & BUFF_DIRTY) { (void)(writebuff(chan)); @@ -649,7 +643,7 @@ chan_end(uint16 addr, uint8 flags) { ccw_flags[chan] = 0; if ((flags & SNS_DEVEND) != 0) - ccw_flags[chan] &= ~FLAG_CD; + ccw_flags[chan] &= ~(FLAG_CD|FLAG_SLI); irq_pend = 1; sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end(%x, %x) %x %04x end\n", addr, flags, @@ -695,14 +689,25 @@ startio(uint16 addr) { return 3; } + sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x %x\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan], chan_status[chan]); + + /* If pending status is for us, return it with status code */ + if (chan_dev[chan] == addr && chan_status[chan] != 0) { + store_csw(chan); + return 1; + } + /* If channel is active return cc=2 */ if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0 || - chan_status[chan] != 0) { - sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x cc=2\n", addr, chan); + chan_status[chan] != 0) { + sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %08x cc=2\n", addr, chan, + chan_status[chan]); return 2; } + if (dev_status[addr] != 0) { M[0x44 >> 2] = (((uint32)dev_status[addr]) << 24); M[0x40 >> 2] = 0; @@ -714,10 +719,6 @@ startio(uint16 addr) { return 1; } - - sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x\n", addr, chan, - ccw_cmd[chan], ccw_flags[chan]); - /* All ok, get caw address */ chan_status[chan] = 0; dev_status[addr] = 0; @@ -741,8 +742,8 @@ startio(uint16 addr) { /* Try to load first command */ if (load_ccw(chan, 0)) { - if (chan_status[chan] & - (STATUS_ATTN|STATUS_CHECK|STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) { +// if (chan_status[chan] & + // (STATUS_ATTN|STATUS_CHECK|STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) { M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | (M[0x44 >> 2] & 0xffff); key[0] |= 0x6; sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x cc=2\n", addr, chan, @@ -751,7 +752,9 @@ startio(uint16 addr) { dev_status[addr] = 0; ccw_cmd[chan] = 0; return 1; - } + // } + } +#if 0 if (chan_status[chan] & (STATUS_PCI)) { M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | (M[0x44 >> 2] & 0xffff); key[0] |= 0x6; @@ -761,7 +764,7 @@ startio(uint16 addr) { dev_status[addr] = 0; return 1; } - } +#endif /* If channel returned busy save CSW and return cc=1 */ if (chan_status[chan] & STATUS_BUSY) { @@ -776,6 +779,7 @@ startio(uint16 addr) { ccw_cmd[chan] = 0; return 1; } + return 0; } diff --git a/IBM360/ibm360_dasd.c b/IBM360/ibm360_dasd.c index 612e165..7233499 100644 --- a/IBM360/ibm360_dasd.c +++ b/IBM360/ibm360_dasd.c @@ -52,7 +52,6 @@ cpos points to where data is actually read/written from Pad to being track to multiple of 512 bytes. - Last record has cyl and head = 0xffffffff */ @@ -397,22 +396,66 @@ uint8 dasd_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { sim_debug(DEBUG_CMD, dptr, "CMD unit=%d %02x\n", unit, cmd); if ((uptr->flags & UNIT_ATT) == 0) { if (cmd == 0x4) { /* Sense */ + int type = GET_TYPE(uptr->flags); + int i; sim_debug(DEBUG_CMD, dptr, "CMD sense\n"); ch = uptr->SNS & 0xff; sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 1 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; + if (chan_write_byte(addr, &ch)) + goto sense_end; ch = (uptr->SNS >> 8) & 0xff; sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 2 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; + if (chan_write_byte(addr, &ch)) + goto sense_end; ch = 0; sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 3 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; - ch = unit; - sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch); - chan_write_byte(addr, &ch) ; + if (chan_write_byte(addr, &ch)) + goto sense_end; + if (disk_type[type].sen_cnt > 6) { + ch = (unit & 07) | ((~unit & 07) << 3); + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + ch = unit; + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 5 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + ch = (uptr->CCH >> 8) & 0xff; + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 6 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + ch = (uptr->CCH & 0x1f) | ((uptr->CCH & 0x10000) ? 0x40 : 0); + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 7 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + ch = 0; /* Compute message code */ + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 8 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + i = 8; + } else { + if (disk_type[type].dev_type == 0x11) + ch = 0xc8; + else + ch = 0x40; + if ((uptr->CCH >> 8) & SNS_ENDCYL) + ch |= 4; + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 4 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + ch = unit; + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d 5 %x\n", unit, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + i = 5; + } ch = 0; - chan_write_byte(addr, &ch) ; - chan_write_byte(addr, &ch) ; + for (; i < disk_type[type].sen_cnt; i++) { + sim_debug(DEBUG_DETAIL, dptr, "sense unit=%d %d %x\n", unit, i, ch); + if (chan_write_byte(addr, &ch)) + goto sense_end; + } +sense_end: uptr->SNS = 0; return SNS_CHNEND|SNS_DEVEND; } @@ -2043,7 +2086,6 @@ t_stat dasd_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, fprintf (st, ".\nEach drive has the following storage capacity:\n\n"); for (i = 0; disk_type[i].name != 0; i++) { int32 size = disk_type[i].bpt * disk_type[i].heads * disk_type[i].cyl; - char sm = 'K'; size /= 1024; size = (10 * size) / 1024; fprintf(st, " %-8s %4d.%1dMB\n", disk_type[i].name, size/10, size%10); diff --git a/IBM360/ibm360_lpr.c b/IBM360/ibm360_lpr.c index 453c99a..56962f4 100644 --- a/IBM360/ibm360_lpr.c +++ b/IBM360/ibm360_lpr.c @@ -387,24 +387,21 @@ lpr_srv(UNIT *uptr) { (l > 3 && l < 0x10) || l > 0x1d) { uptr->SNS = SNS_CMDREJ; uptr->CMD &= ~(LPR_CMDMSK); + sim_debug(DEBUG_DETAIL, &lpr_dev, "%d Invalid skip %x %d", u, l, l); chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); return SCPE_OK; } - /* On control end channel */ - if (cmd == 3) - chan_end(addr, SNS_CHNEND); - /* If at end of buffer, or control do command */ if ((uptr->CMD & LPR_FULL) || cmd == 3) { print_line(uptr); uptr->CMD &= ~(LPR_FULL|LPR_CMDMSK); uptr->POS = 0; if (uptr->SNS & SNS_CHN12) { - set_devattn(addr, SNS_DEVEND|SNS_UNITEXP); + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); uptr->SNS &= 0xff; } else { - set_devattn(addr, SNS_DEVEND); + chan_end(addr, SNS_CHNEND|SNS_DEVEND); } return SCPE_OK; }