1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-01-13 15:27:04 +00:00

IBM360: Fixed channel status handling.

This commit is contained in:
Richard Cornwell 2020-02-03 22:19:35 -05:00
parent c48cb3f7ff
commit cde7ef8bb5
2 changed files with 55 additions and 17 deletions

View File

@ -94,6 +94,7 @@ uint16 chan_status[CHAN_SZ]; /* Channel status */
uint16 chan_dev[CHAN_SZ]; /* Device on channel */
uint32 chan_buf[CHAN_SZ]; /* Channel data buffer */
uint8 chan_byte[CHAN_SZ]; /* Current byte, dirty/full */
uint8 chan_pend[CHAN_SZ]; /* Pending status on this channel */
DIB *dev_unit[MAX_DEV]; /* Pointer to Device info block */
uint8 dev_status[MAX_DEV]; /* last device status flags */
@ -545,8 +546,10 @@ set_devattn(uint16 addr, uint8 flags) {
if (chan_dev[chan] == addr && (chan_status[chan] & STATUS_CEND) != 0 &&
(flags & SNS_DEVEND) != 0) {
chan_status[chan] |= ((uint16)flags) << 8;
} else
} else {
dev_status[addr] = flags;
chan_pend[chan] = 1;
}
sim_debug(DEBUG_EXP, &cpu_dev, "set_devattn(%x, %x) %x\n",
addr, flags, chan_dev[chan]);
irq_pend = 1;
@ -610,7 +613,7 @@ chan_end(uint16 addr, uint8 flags) {
/*
* Save full csw.
*/
int
void
store_csw(uint16 chan) {
M[0x40 >> 2] = caw[chan];
M[0x44 >> 2] = (((uint32)ccw_count[chan])) | ((uint32)chan_status[chan]<<16);
@ -623,7 +626,6 @@ store_csw(uint16 chan) {
}
sim_debug(DEBUG_EXP, &cpu_dev, "Channel store csw %02x %06x %08x\n",
chan, M[0x40>>2], M[0x44 >> 2]);
return chan_dev[chan];
}
/*
@ -637,15 +639,31 @@ startio(uint16 addr) {
uint8 status;
/* Find channel this device is on, if no none return cc=3 */
if (chan < 0 || dibp == 0)
if (chan < 0 || dibp == 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x cc=3\n", addr, chan);
return 3;
}
uptr = find_chan_dev(addr);
if (uptr == 0)
if (uptr == 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x cc=3u\n", addr, chan);
return 3;
}
/* If channel is active return cc=2 */
if (ccw_cmd[chan] != 0 || (ccw_flags[chan] & (FLAG_CD|FLAG_CC)) != 0 || chan_status[chan] != 0)
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);
return 2;
}
if (dev_status[addr] != 0) {
M[0x44 >> 2] = (((uint32)dev_status[addr]) << 24);
M[0x40>>2] = 0;
sim_debug(DEBUG_EXP, &cpu_dev,
"SIO Set atten %03x %x %02x [%08x] %08x\n",
addr, chan, dev_status[addr], M[0x40 >> 2], M[0x44 >> 2]);
dev_status[addr] = 0;
return 1;
}
sim_debug(DEBUG_CMD, &cpu_dev, "SIO %x %x %x %x\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
@ -741,12 +759,6 @@ int testio(uint16 addr) {
return 2;
}
/* If error pending for another device, return cc=2 */
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;
}
/* Device finished and channel status pending return it and cc=1 */
if (ccw_cmd[chan] == 0 && chan_status[chan] != 0) {
@ -764,9 +776,28 @@ int testio(uint16 addr) {
M[0x40 >> 2] = 0;
M[0x44 >> 2] = ((uint32)dev_status[addr]) << 24;
dev_status[addr] = 0;
chan_pend[chan] = 0;
return 1;
}
/* If error pending for another device, return cc=2 */
// if (chan_dev[chan] != 0 && chan_dev[chan] != addr) {
if (chan_pend[chan] != 0) {
int pend, ch;
chan_pend[chan] = 0;
/* Check if might be false */
for (pend = 0; pend < MAX_DEV; pend++) {
if (dev_status[pend] != 0) {
ch = find_subchan(pend);
if (ch == chan) {
chan_pend[ch] = 1;
sim_debug(DEBUG_CMD, &cpu_dev, "TIO %x %x %x %x %x cc=2a\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan], pend);
return 2;
}
}
}
}
/* Nothing pending, send a 0 command to device to get status */
status = dibp->start_cmd(uptr, chan, 0) << 8;
@ -801,11 +832,15 @@ int haltio(uint16 addr) {
uint8 status;
/* Find channel this device is on, if no none return cc=3 */
if (chan < 0 || dibp == 0)
if (chan < 0 || dibp == 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x\n", addr, chan);
return 3;
uptr = find_chan_dev(chan_dev[chan]);
if (uptr == 0)
}
uptr = find_chan_dev(addr);
if (uptr == 0) {
sim_debug(DEBUG_CMD, &cpu_dev, "HIOu %x %x\n", addr, chan);
return 3;
}
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x %x %x\n", addr, chan,
ccw_cmd[chan], ccw_flags[chan]);
@ -827,7 +862,7 @@ int haltio(uint16 addr) {
int testchan(uint16 channel) {
uint16 st = 0;
channel >>= 8;
if (channel == 0)
if (channel == 0 || channel == 4)
return 0;
if (channel > channels)
return 3;
@ -944,6 +979,7 @@ scan_chan(uint16 mask, int irq_en) {
if (ch >= 0 && loading == 0) {
sim_debug(DEBUG_EXP, &cpu_dev, "Scan end (%x %x)\n", chan_dev[ch], pend);
store_csw(ch);
dev_status[pend] = 0;
return pend;
}
} else {

View File

@ -1128,6 +1128,7 @@ opr:
cregs[6] |= (uint32)(sysmsk) << 16;
irq_pend = 1;
}
dest = src1;
}
break;
@ -4139,6 +4140,7 @@ supress:
hst[hst_p].src2 = src2;
}
lpsw:
sim_debug(DEBUG_DETAIL, &cpu_dev, " LPSW %08x %08x\n", src1, src2);
if (ec_mode) {
dat_en = (src1 >> 26) & 3;
irq_en = (src1 & 0x2000000) != 0;
@ -4148,7 +4150,7 @@ lpsw:
cregs[6] = src1 & 0xfe000000;
sysmsk = (cregs[6] >> 16) & 0xfe00;
if (sysmsk) {
cregs[reg] |= 0x1000000;
cregs[6] |= 0x1000000;
irq_en = 1;
} else
irq_en = 0;