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:
parent
c48cb3f7ff
commit
cde7ef8bb5
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user