diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index f69ae25..517bf94 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -576,7 +576,7 @@ int startio(uint16 addr) { return 3; if ((uptr->flags & UNIT_ATT) == 0) return 3; - if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0) + if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0 || chan_status[chan] != 0) return 2; sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x\n", addr, chan, ccw_cmd[chan], ccw_flags[chan]); @@ -629,28 +629,51 @@ int testio(uint16 addr) { return 3; if ((uptr->flags & UNIT_ATT) == 0) return 3; - if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0) + if (chan_status[chan] & (STATUS_PCI|STATUS_ATTN|STATUS_CHECK|\ + STATUS_PROT|STATUS_PCHK|STATUS_EXPT)) { + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); + store_csw(chan); + // chan_dev[chan] = 0; + return 1; + } + if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0) { + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); return 2; - if (chan_dev[chan] != 0 && chan_dev[chan] != addr) +} + if (chan_dev[chan] != 0 && chan_dev[chan] != addr) { + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=2a\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); return 2; +} if (ccw_cmd[chan] == 0 && chan_status[chan] != 0) { + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1a\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); store_csw(chan); chan_dev[chan] = 0; return 1; } if (dev_status[addr] != 0) { + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1b\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); M[0x40 >> 2] = 0; M[0x44 >> 2] = ((uint32)dev_status[addr]) << 24; dev_status[addr] = 0; return 1; } + chan_status[chan] = dibp->start_cmd(uptr, chan, 0) << 8; if (chan_status[chan] & (STATUS_ATTN|STATUS_CHECK|STATUS_EXPT)) { + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=1c\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); M[0x44 >> 2] = ((uint32)chan_status[chan]<<16) | M[0x44 >> 2] & 0xffff; chan_status[chan] = 0; dev_status[addr] = 0; return 1; } + sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x cc=0\n", addr, chan, + ccw_cmd[chan], ccw_flags[chan]); chan_status[chan] = 0; return 0; } @@ -771,12 +794,21 @@ uint16 scan_chan(uint8 mask) { } } } + /* Only return loading unit on loading */ + if (loading != 0 && loading != pend) + return 0; + /* See if we can post an IRQ */ if (pend) { irq_pend = 1; ch = find_subchan(pend); + if (loading && loading == pend) { + chan_status[ch] = 0; + return pend; + } if (ch >= 0 && loading == 0) { sim_debug(DEBUG_EXP, &cpu_dev, "Scan end (%x %x)\n", chan_dev[ch], pend); store_csw(ch); + return pend; } } else { for (pend = 0; pend < MAX_DEV; pend++) { @@ -794,12 +826,8 @@ uint16 scan_chan(uint8 mask) { } } } - pend = 0; } - /* Only return loading unit on loading */ - if (loading != 0 && loading != pend) - return 0; - return pend; + return 0; } diff --git a/IBM360/ibm360_dasd.c b/IBM360/ibm360_dasd.c index b84a54b..bbd7506 100644 --- a/IBM360/ibm360_dasd.c +++ b/IBM360/ibm360_dasd.c @@ -1349,6 +1349,14 @@ wrckd: ((uptr->u6 & 0x3) == 1 && (uptr->u6 & 0x70) != 0 && (uptr->u3 & (DK_SHORTSRC|DK_SRCOK)) == DK_SRCOK)) { state = data->state = DK_POS_END; + /* Write end mark */ + for(i = 0; i < 8; i++) + rec[i] = 0xff; + + uptr->u6 = cmd; + uptr->u3 &= ~(0xff|DK_PARAM|DK_INDEX); + uptr->u3 |= DK_CYL_DIRTY; + chan_end(addr, SNS_CHNEND|SNS_DEVEND); } else { uptr->u5 |= SNS_CMDREJ | (SNS_INVSEQ << 8); uptr->u6 = 0; @@ -1358,14 +1366,6 @@ wrckd: } } - /* Write end mark */ - for(i = 0; i < 8; i++) - rec[i] = 0xff; - - uptr->u6 = cmd; - uptr->u3 &= ~(0xff|DK_PARAM|DK_INDEX); - uptr->u3 |= DK_CYL_DIRTY; - chan_end(addr, SNS_CHNEND|SNS_DEVEND); break; case DK_WR_SCKD: /* Write special count, key and data */ @@ -1444,6 +1444,14 @@ dasd_format(UNIT * uptr, int flag) { data->cbuf[pos++] = 0; /* dlen */ data->cbuf[pos++] = 8; /* */ pos += 8; + data->cbuf[pos++] = (cyl >> 8); /* R1 */ + data->cbuf[pos++] = (cyl & 0xff); + data->cbuf[pos++] = (hd >> 8); + data->cbuf[pos++] = (hd & 0xff); + data->cbuf[pos++] = 1; /* Rec */ + data->cbuf[pos++] = 0; /* keylen */ + data->cbuf[pos++] = 0; /* dlen */ + data->cbuf[pos++] = 0; /* */ data->cbuf[pos++] = 0xff; /* End record */ data->cbuf[pos++] = 0xff; data->cbuf[pos++] = 0xff;