mirror of
https://github.com/rcornwell/sims.git
synced 2026-03-01 01:30:04 +00:00
IBM360: Cleanup channels support for protection.
This commit is contained in:
@@ -92,6 +92,7 @@ uint32 ccw_addr[CHAN_SZ]; /* Channel address */
|
||||
uint32 ccw_iaddr[CHAN_SZ]; /* Channel indirect address */
|
||||
uint16 ccw_count[CHAN_SZ]; /* Channel count */
|
||||
uint8 ccw_cmd[CHAN_SZ]; /* Channel command and flags */
|
||||
uint8 ccw_key[CHAN_SZ]; /* Channel key */
|
||||
uint16 ccw_flags[CHAN_SZ]; /* Channel flags */
|
||||
uint16 chan_status[CHAN_SZ]; /* Channel status */
|
||||
uint16 chan_dev[CHAN_SZ]; /* Device on channel */
|
||||
@@ -174,23 +175,21 @@ find_chan(int chan) {
|
||||
*/
|
||||
int
|
||||
readfull(int chan, uint32 addr, uint32 *word) {
|
||||
int sk, k;
|
||||
if ((addr & AMASK) > MEMSIZE) {
|
||||
chan_status[chan] |= STATUS_PCHK;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xf0;
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if (ccw_key[chan] != 0) {
|
||||
int k;
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
k = key[addr >> 9];
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != sk) {
|
||||
if ((k & 0x8) != 0 && (k & 0xf0) != ccw_key[chan]) {
|
||||
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
irq_pend = 1;
|
||||
@@ -239,22 +238,21 @@ readbuff(int chan) {
|
||||
*/
|
||||
int
|
||||
writebuff(int chan) {
|
||||
int sk, k;
|
||||
uint32 addr;
|
||||
int k;
|
||||
if (ccw_flags[chan] & FLAG_IDA && cpu_unit[0].flags & FEAT_370)
|
||||
addr = ccw_iaddr[chan];
|
||||
else
|
||||
addr = ccw_addr[chan];
|
||||
if ((addr & AMASK) > MEMSIZE) {
|
||||
fprintf(stderr, "Mem %08x\n\r", addr);
|
||||
chan_status[chan] |= STATUS_PCHK;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
return 1;
|
||||
}
|
||||
sk = (addr >> 24) & 0xff;
|
||||
addr &= AMASK;
|
||||
addr >>= 2;
|
||||
if (sk != 0) {
|
||||
if (ccw_key[chan] != 0) {
|
||||
if ((cpu_unit[0].flags & FEAT_PROT) == 0) {
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
@@ -262,8 +260,8 @@ writebuff(int chan) {
|
||||
return 1;
|
||||
}
|
||||
k = key[addr >> 9];
|
||||
if ((k & 0xf0) != sk) {
|
||||
//fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, sk);
|
||||
if ((k & 0xf0) != ccw_key[chan]) {
|
||||
fprintf(stderr, "Prot %08x %x %x\n\r", addr << 2, k, ccw_key[addr]);
|
||||
chan_status[chan] |= STATUS_PROT;
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
irq_pend = 1;
|
||||
@@ -324,7 +322,7 @@ loop:
|
||||
return 1;
|
||||
}
|
||||
caw[chan] += 4;
|
||||
caw[chan] &= PMASK|AMASK; /* Mask overflow bits */
|
||||
caw[chan] &= AMASK; /* Mask overflow bits */
|
||||
/* Check if not chaining data */
|
||||
if ((ccw_flags[chan] & FLAG_CD) == 0) {
|
||||
ccw_cmd[chan] = (word >> 24) & 0xff;
|
||||
@@ -332,12 +330,11 @@ loop:
|
||||
}
|
||||
/* Set up for this command */
|
||||
ccw_addr[chan] = word & AMASK;
|
||||
ccw_addr[chan] |= caw[chan] & PMASK; /* Copy key */
|
||||
readfull(chan, caw[chan], &word);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "Channel read ccw2 %02x %06x %08x\n",
|
||||
chan, caw[chan], word);
|
||||
caw[chan]+=4;
|
||||
caw[chan] &= PMASK|AMASK; /* Mask overflow bits */
|
||||
caw[chan] &= AMASK; /* Mask overflow bits */
|
||||
ccw_count[chan] = word & 0xffff;
|
||||
/* Copy SLI indicator on CD command */
|
||||
if ((ccw_flags[chan] & (FLAG_CD|FLAG_SLI)) == (FLAG_CD|FLAG_SLI))
|
||||
@@ -352,7 +349,7 @@ loop:
|
||||
}
|
||||
if (ccw_flags[chan] & FLAG_IDA && cpu_unit[0].flags & FEAT_370) {
|
||||
readfull(chan, ccw_addr[chan], &word);
|
||||
ccw_iaddr[chan] = (ccw_addr[chan] & 0xf000000) | (word & AMASK);
|
||||
ccw_iaddr[chan] = word & AMASK;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel fetch idaw %02x %08x\n",
|
||||
chan, ccw_iaddr[chan]);
|
||||
}
|
||||
@@ -437,7 +434,7 @@ chan_read_byte(uint16 addr, uint8 *data) {
|
||||
uint32 temp;
|
||||
ccw_addr[chan] += 4;
|
||||
readfull(chan, ccw_addr[chan], &temp);
|
||||
ccw_iaddr[chan] = (ccw_addr[chan] & 0xf000000) | (temp & AMASK);
|
||||
ccw_iaddr[chan] = temp & AMASK;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel fetch idaw %02x %08x\n",
|
||||
chan, ccw_iaddr[chan]);
|
||||
}
|
||||
@@ -510,7 +507,7 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
uint32 temp;
|
||||
ccw_addr[chan] += 4;
|
||||
readfull(chan, ccw_addr[chan], &temp);
|
||||
ccw_iaddr[chan] = (ccw_addr[chan] & 0xf000000) | (temp & AMASK);
|
||||
ccw_iaddr[chan] = temp & AMASK;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel fetch idaw %02x %08x\n",
|
||||
chan, ccw_iaddr[chan]);
|
||||
}
|
||||
@@ -520,7 +517,7 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
uint32 temp;
|
||||
ccw_addr[chan] += 4;
|
||||
readfull(chan, ccw_addr[chan], &temp);
|
||||
ccw_iaddr[chan] = (ccw_addr[chan] & 0xf000000) | (temp & AMASK);
|
||||
ccw_iaddr[chan] = temp & AMASK;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel fetch idaw %02x %08x\n",
|
||||
chan, ccw_iaddr[chan]);
|
||||
}
|
||||
@@ -544,7 +541,7 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
uint32 temp;
|
||||
ccw_addr[chan] += 4;
|
||||
readfull(chan, ccw_addr[chan], &temp);
|
||||
ccw_iaddr[chan] = (ccw_addr[chan] & 0xf000000) | (temp & AMASK);
|
||||
ccw_iaddr[chan] = temp & AMASK;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel fetch idaw %02x %08x\n",
|
||||
chan, ccw_iaddr[chan]);
|
||||
}
|
||||
@@ -554,7 +551,7 @@ chan_write_byte(uint16 addr, uint8 *data) {
|
||||
uint32 temp;
|
||||
ccw_addr[chan] += 4;
|
||||
readfull(chan, ccw_addr[chan], &temp);
|
||||
ccw_iaddr[chan] = (ccw_addr[chan] & 0xf000000) | (temp & AMASK);
|
||||
ccw_iaddr[chan] = temp & AMASK;
|
||||
sim_debug(DEBUG_DETAIL, &cpu_dev, "Channel fetch idaw %02x %08x\n",
|
||||
chan, ccw_iaddr[chan]);
|
||||
}
|
||||
@@ -632,8 +629,7 @@ chan_end(uint16 addr, uint8 flags) {
|
||||
}
|
||||
/* Flush buffer if there was any change */
|
||||
if (chan_byte[chan] & BUFF_DIRTY) {
|
||||
if (writebuff(chan))
|
||||
return;
|
||||
(void)(writebuff(chan));
|
||||
chan_byte[chan] = BUFF_EMPTY;
|
||||
}
|
||||
chan_status[chan] |= STATUS_CEND;
|
||||
@@ -732,6 +728,8 @@ startio(uint16 addr) {
|
||||
chan_status[chan] = 0;
|
||||
dev_status[addr] = 0;
|
||||
caw[chan] = M[0x48>>2];
|
||||
ccw_key[chan] = (caw[chan] & PMASK) >> 24;
|
||||
caw[chan] &= AMASK;
|
||||
key[0] |= 0x4;
|
||||
chan_dev[chan] = addr;
|
||||
|
||||
@@ -923,7 +921,7 @@ int haltio(uint16 addr) {
|
||||
if (dibp->halt_io != NULL) {
|
||||
/* Let device do it's thing */
|
||||
cc = dibp->halt_io(uptr);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x cc=%d\n", addr, chan, cc);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIOd %x %x cc=%d\n", addr, chan, cc);
|
||||
if (cc == 1) {
|
||||
M[0x44 >> 2] = (((uint32)chan_status[chan]) << 16) |
|
||||
(M[0x44 >> 2] & 0xffff);
|
||||
@@ -937,7 +935,7 @@ int haltio(uint16 addr) {
|
||||
chan_byte[chan] = BUFF_CHNEND;
|
||||
|
||||
/* Store CSW and return 1. */
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIO %x %x cc=1\n", addr, chan);
|
||||
sim_debug(DEBUG_CMD, &cpu_dev, "HIOx %x %x cc=1\n", addr, chan);
|
||||
M[0x44 >> 2] = (((uint32)chan_status[chan]) << 16) |
|
||||
(M[0x44 >> 2] & 0xffff);
|
||||
key[0] |= 0x6;
|
||||
@@ -950,7 +948,7 @@ int haltio(uint16 addr) {
|
||||
int testchan(uint16 channel) {
|
||||
uint16 st = 0;
|
||||
channel >>= 8;
|
||||
if (channel == 0 || channels == 4)
|
||||
if (channel == 0 || channel == 4)
|
||||
return 0;
|
||||
if (channel > channels)
|
||||
return 3;
|
||||
@@ -991,6 +989,7 @@ t_stat chan_boot(uint16 addr, DEVICE *dptyr) {
|
||||
ccw_count[chan] = 24;
|
||||
ccw_flags[chan] = FLAG_CC|FLAG_SLI;
|
||||
ccw_addr[chan] = 0;
|
||||
ccw_key[chan] = 0;
|
||||
chan_byte[chan] = BUFF_EMPTY;
|
||||
ccw_cmd[chan] = 0x2;
|
||||
chan_status[chan] &= 0xff;
|
||||
@@ -1033,6 +1032,8 @@ scan_chan(uint16 mask, int irq_en) {
|
||||
|
||||
/* If channel end, check if we should continue */
|
||||
if (chan_status[i] & STATUS_CEND) {
|
||||
sim_debug(DEBUG_EXP, &cpu_dev, "Scan(%x %x %x %x) end\n", i,
|
||||
chan_status[i], imask, mask);
|
||||
if (ccw_flags[i] & FLAG_CC) {
|
||||
if (chan_status[i] & STATUS_DEND)
|
||||
(void)load_ccw(i, 1);
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#define SEND 0x0200 /* Sending data */
|
||||
#define ENAB 0x0400 /* Line enabled */
|
||||
#define POLL 0x0800 /* Waiting for connection */
|
||||
#define BOT 0x1000 /* Need to send BOT */
|
||||
|
||||
/* u5 */
|
||||
/* Sense byte 0 */
|
||||
@@ -249,8 +250,9 @@ uint8 coml_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {
|
||||
case 0x3: /* Control */
|
||||
if (cmd == CMD_NOP)
|
||||
break;
|
||||
case 0x1: /* Write command */
|
||||
case 0x2: /* Read command */
|
||||
uptr->u3 |= BOT;
|
||||
case 0x1: /* Write command */
|
||||
uptr->u3 |= cmd;
|
||||
sim_activate(uptr, 200);
|
||||
return 0;
|
||||
@@ -275,7 +277,7 @@ uint8 coml_haltio(UNIT *uptr) {
|
||||
int cmd = uptr->u3 & 0xff;
|
||||
|
||||
sim_debug(DEBUG_CMD, dptr, "HLTIO unit=%d %x\n", unit, cmd);
|
||||
if ((uptr->flags & UNIT_ATT) == 0) /* attached? */
|
||||
if ((com_unit[0].flags & UNIT_ATT) == 0) /* attached? */
|
||||
return 3;
|
||||
|
||||
switch (cmd) {
|
||||
@@ -292,7 +294,7 @@ uint8 coml_haltio(UNIT *uptr) {
|
||||
case CMD_BRK: /* Send break signal */
|
||||
case CMD_PREP: /* Wait for incoming data */
|
||||
case CMD_SRCH: /* Wait for EOT character */
|
||||
uptr->u3 &= ~0xffff;
|
||||
uptr->u3 &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
break;
|
||||
case CMD_ENB: /* Enable line */
|
||||
@@ -343,9 +345,15 @@ t_stat coml_srv(UNIT * uptr)
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK);
|
||||
return SCPE_OK;
|
||||
} else {
|
||||
if (uptr->u3 & BOT) {
|
||||
ch = 0x16;
|
||||
(void)chan_write_byte( addr, &ch);
|
||||
uptr->u3 &= ~BOT;
|
||||
}
|
||||
ch = sim_tt_inpcvt (data, TT_GET_MODE(uptr->flags) |
|
||||
TTUF_KSR);
|
||||
ch = com_2741_in[data & 0x7f];
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d read '%c'\n", unit, data & 0x7f);
|
||||
if (chan_write_byte( addr, &ch)) {
|
||||
uptr->u3 &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
@@ -355,7 +363,7 @@ t_stat coml_srv(UNIT * uptr)
|
||||
ch = 0x1f;
|
||||
(void)chan_write_byte( addr, &ch);
|
||||
uptr->u3 &= ~0xff;
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP);
|
||||
chan_end(addr, SNS_CHNEND|SNS_DEVEND);
|
||||
return SCPE_OK;
|
||||
}
|
||||
}
|
||||
@@ -375,8 +383,10 @@ t_stat coml_srv(UNIT * uptr)
|
||||
data = com_2741_out[ch];
|
||||
data = sim_tt_outcvt(data, TT_GET_MODE(uptr->flags) |
|
||||
TTUF_KSR);
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d send '%c'\n", unit,
|
||||
isprint(data)? data: '^');
|
||||
tmxr_putc_ln( &com_ldsc[unit], data);
|
||||
sim_activate(uptr, 200);
|
||||
sim_activate(uptr, 20000);
|
||||
}
|
||||
} else {
|
||||
sim_debug(DEBUG_CMD, dptr, "COM: unit=%d write error\n", unit);
|
||||
|
||||
@@ -3014,7 +3014,7 @@ save_dbl:
|
||||
M[addr2] &= 0xffff;
|
||||
M[addr2] |= src1 << 16;
|
||||
M[0x9C >> 2] = addr1;
|
||||
key[0] |= 0x6;
|
||||
key[0] |= 0x6;
|
||||
storepsw(OPPSW, IRC_MCE);
|
||||
goto supress;
|
||||
}
|
||||
@@ -5175,7 +5175,7 @@ fpnorm:
|
||||
if (irqaddr != 0) {
|
||||
supress:
|
||||
src1 = M[irqaddr>>2];
|
||||
key[0] |= 0x4;
|
||||
key[0] |= 0x4;
|
||||
if (hst_lnt) {
|
||||
hst_p = hst_p + 1;
|
||||
if (hst_p >= hst_lnt)
|
||||
@@ -5191,6 +5191,8 @@ supress:
|
||||
lpsw:
|
||||
if ((cpu_unit[0].flags & FEAT_370) != 0)
|
||||
ec_mode = (src1 & 0x00080000) != 0;
|
||||
else if ((cpu_unit[0].flags & FEAT_DAT) != 0)
|
||||
ec_mode = (cregs[4] & 0x00800000) != 0;
|
||||
else
|
||||
ec_mode = 0;
|
||||
ext_en = (src1 & 0x01000000) != 0;
|
||||
@@ -5228,7 +5230,6 @@ lpsw:
|
||||
else
|
||||
flags = (src1 >> 16) & 0xf;
|
||||
PC = src2 & AMASK;
|
||||
irq_pend = 1;
|
||||
sim_debug(DEBUG_INST, &cpu_dev, "PSW=%08x %08x ", src1, src2);
|
||||
if (dat_en & 0x2)
|
||||
storepsw(OPPSW, IRC_SPEC);
|
||||
|
||||
@@ -548,7 +548,6 @@ t_stat mt_srv(UNIT * uptr)
|
||||
sim_debug(DEBUG_DATA, dptr, "Write data unit=%d %d %02o\n\r",
|
||||
unit, uptr->u4, ch);
|
||||
uptr->hwmark = uptr->u4;
|
||||
break;
|
||||
}
|
||||
sim_activate(uptr, 20);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user