From fba531ac58ed526cea0a5787bf2de5452e7d6dd2 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 3 May 2020 12:01:30 -0400 Subject: [PATCH] IBM360: Cleanup channels support for protection. --- IBM360/ibm360_chan.c | 51 ++++++++++++++++++++++---------------------- IBM360/ibm360_com.c | 20 ++++++++++++----- IBM360/ibm360_cpu.c | 7 +++--- IBM360/ibm360_mt.c | 1 - 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index 774b681..95c450c 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -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); diff --git a/IBM360/ibm360_com.c b/IBM360/ibm360_com.c index 2feeceb..b3de612 100644 --- a/IBM360/ibm360_com.c +++ b/IBM360/ibm360_com.c @@ -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); diff --git a/IBM360/ibm360_cpu.c b/IBM360/ibm360_cpu.c index 6859184..e36146e 100644 --- a/IBM360/ibm360_cpu.c +++ b/IBM360/ibm360_cpu.c @@ -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); diff --git a/IBM360/ibm360_mt.c b/IBM360/ibm360_mt.c index 8942dfa..6b2929a 100644 --- a/IBM360/ibm360_mt.c +++ b/IBM360/ibm360_mt.c @@ -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;