From c663c1ff536a9092e68d49dcd99bd119076c24dd Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sun, 12 Nov 2017 14:09:24 -0500 Subject: [PATCH] IBM360: Misc bug fixes, still not working. --- IBM360/ibm360_chan.c | 10 ++++++++++ IBM360/ibm360_cpu.c | 41 +++++++++++++++++++++++++---------------- IBM360/ibm360_dasd.c | 43 +++++++++++++++++++++++++++++++------------ IBM360/ibm360_lpr.c | 14 +++++++------- 4 files changed, 73 insertions(+), 35 deletions(-) diff --git a/IBM360/ibm360_chan.c b/IBM360/ibm360_chan.c index 0c4b2c5..c986fc2 100644 --- a/IBM360/ibm360_chan.c +++ b/IBM360/ibm360_chan.c @@ -493,6 +493,16 @@ chan_end(uint16 addr, uint8 flags) { if (chan_status[chan] & (STATUS_DEND|STATUS_CEND)) { chan_byte[chan] = BUFF_NEWCMD; + + while ((ccw_flags[chan] & FLAG_CD)) { + if (load_ccw(chan, 1)) + break; + if (ccw_count[chan] != 0 && (ccw_flags[chan] & FLAG_SLI) == 0) { + sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end length\n"); + chan_status[chan] |= STATUS_LENGTH; + ccw_flags[chan] = 0; + } + } } irq_pend = 1; diff --git a/IBM360/ibm360_cpu.c b/IBM360/ibm360_cpu.c index 82159b0..752d07b 100644 --- a/IBM360/ibm360_cpu.c +++ b/IBM360/ibm360_cpu.c @@ -53,6 +53,7 @@ uint32 cregs[16]; /* Control registers /67 or 370 only */ uint8 sysmsk; /* Interupt mask */ uint8 st_key; /* Storage key */ uint8 cc; /* CC */ +uint8 ilc; /* Instruction length code */ uint8 pmsk; /* Program mask */ uint16 irqcode; /* Interupt code */ uint8 flags; /* Misc flags */ @@ -195,6 +196,7 @@ MTAB cpu_mod[] = { { UNIT_MSIZE, MEMAMOUNT(12), "196K", "196K", &cpu_set_size }, { UNIT_MSIZE, MEMAMOUNT(16), "256K", "256K", &cpu_set_size }, { UNIT_MSIZE, MEMAMOUNT(32), "512K", "512K", &cpu_set_size }, + { UNIT_MSIZE, MEMAMOUNT(128), "2M", "2M", &cpu_set_size }, { FEAT_PROT, 0, NULL, "NOPROT", NULL, NULL, NULL, "No Storage protection"}, { FEAT_PROT, FEAT_PROT, "PROT", "PROT", NULL, NULL, NULL, "Storage protection"}, { FEAT_DEC, 0, NULL, "NODECIMAL", NULL, NULL, NULL}, @@ -248,9 +250,9 @@ void post_extirq() { void storepsw(uint32 addr, uint16 ircode) { uint32 word; irqaddr = addr + 0x40; - word = ((uint32)sysmsk) << 24 | - ((uint32)st_key) << 16 | - ((uint32)flags) << 16 | + word = (((uint32)sysmsk) << 24) | + (((uint32)st_key) << 16) | + (((uint32)flags) << 16) | ((uint32)ircode); M[addr >> 2] = word; if (hst_lnt) { @@ -261,8 +263,9 @@ void storepsw(uint32 addr, uint16 ircode) { hst[hst_p].src1 = word; } addr += 4; - word = ((uint32)pmsk) << 24 | - ((uint32)cc) << 28 | + word = (((uint32)ilc) << 30) | + (((uint32)cc) << 28) | + (((uint32)pmsk) << 24) | PC; M[addr >> 2] = word; if (hst_lnt) { @@ -536,7 +539,7 @@ sim_instr(void) reason = SCPE_OK; /* Enable timer if option set */ if (cpu_unit.flags & FEAT_TIMER) { - sim_activate(&cpu_unit, 10000); + sim_activate(&cpu_unit, 100); } interval_irq = 0; @@ -598,8 +601,10 @@ wait_loop: } //} + ilc = 0; if (ReadHalf(PC, &src1)) goto supress; + ilc = 1; if (hst_lnt) hst[hst_p].inst[0] = src1; PC += 2; @@ -613,15 +618,17 @@ wait_loop: pmsk += 0x40; if (ReadHalf(PC, &addr1)) goto supress; - if (hst_lnt) - hst[hst_p].inst[1] = addr1; + ilc = 2; PC += 2; + if (hst_lnt) + hst[hst_p].inst[1] = addr1; /* Check if SS */ if ((op & 0xc0) == 0xc0) { pmsk += 0x40; if (ReadHalf(PC, &addr2)) goto supress;; PC += 2; + ilc = 3; if (hst_lnt) hst[hst_p].inst[2] = addr2; } @@ -656,7 +663,7 @@ opr: goto supress; } if (reg1 & 0x9) { - reason=1; +// reason=1; storepsw(OPPSW, IRC_SPEC); goto supress; } @@ -720,7 +727,9 @@ opr: case OP_BALR: case OP_BAL: - dest = ((((cc & 03) << 4) | pmsk) << 24) | PC; + dest = (((uint32)ilc) << 30) | + ((uint32)(cc & 03) << 28) | + (((uint32)pmsk) << 24) | PC; if (op != OP_BALR || (reg & 0xf)) PC = addr1 & 0xffffff; regs[reg1] = dest; @@ -955,9 +964,10 @@ set_cc3: storepsw(OPPSW, IRC_SPEC); break; } + src1 = regs[reg1|1]; case OP_MH: fill = 0; -// fprintf(stderr, "Mul %d x %d = ", src1, src2); + fprintf(stderr, "Mul %d x %d = ", src1, src2); if (src1 & MSIGN) { fill = 1; @@ -991,7 +1001,7 @@ set_cc3: } else { regs[reg1] = src1; } -//fprintf(stderr, " %d %08x %08x\n\r", src1, dest, src1); +fprintf(stderr, " %d %08x %08x\n\r", src1, dest, src1); // reason =1; break; @@ -1601,7 +1611,7 @@ save_dbl: } if (dest & MSIGN) { storepsw(OPPSW, IRC_FIXDIV); - reason =1; +// reason =1; //fprintf(stderr, "\n\r"); break; } @@ -2034,12 +2044,11 @@ rtc_srv(UNIT * uptr) int32 t; t = sim_rtcn_calb (rtc_tps, TMR_RTC); sim_activate_after(uptr, 1000000/rtc_tps); - t = M[0x50>>2]; - M[0x50>>2]--; - if (((t ^ M[0x50>>2]) & MSIGN) != 0 && (t & MSIGN) == 0) { + if (M[0x50>>2] == 0) { fprintf(stderr, "Timer %08x\n\r", M[0x50>>2]); interval_irq = 1; } + M[0x50>>2]--; } return SCPE_OK; } diff --git a/IBM360/ibm360_dasd.c b/IBM360/ibm360_dasd.c index 0020740..7a24e96 100644 --- a/IBM360/ibm360_dasd.c +++ b/IBM360/ibm360_dasd.c @@ -429,6 +429,12 @@ t_stat dasd_srv(UNIT * uptr) if ((uptr->u3 & 0x83) == 0x82) { sim_debug(DEBUG_DETAIL, dptr, "adv head unit=%d %02x %d %d\n", unit, state, data->tpos, uptr->u4 & 0xff); + if ((data->filemsk & DK_MSK_SK) == DK_MSK_SKNONE) { + uptr->u5 |= (SNS_WRP << 8); + uptr->u3 &= ~0xff; + chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + goto index; + } uptr->u4 ++; if ((uptr->u3 & 0x7) == 1 && (uptr->u3 & 0x60) != 0) uptr->u3 &= ~DK_INDEX; @@ -454,6 +460,7 @@ t_stat dasd_srv(UNIT * uptr) uptr->u3 &= ~0xff; chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); } +index: uptr->u3 |= DK_INDEX; data->tstart = data->tsize * (uptr->u4 & 0xff); data->tpos = data->rpos = 0; @@ -503,7 +510,7 @@ t_stat dasd_srv(UNIT * uptr) } break; case DK_POS_KEY: /* In Key area */ - data->tpos++; + data->tpos++; if (data->count == data->klen) { sim_debug(DEBUG_POS, dptr, "state key unit=%d %d %d\n", unit, data->rec, data->count); @@ -517,7 +524,7 @@ t_stat dasd_srv(UNIT * uptr) } break; case DK_POS_DATA: /* In Data area */ - data->tpos++; + data->tpos++; if (data->count == data->dlen) { sim_debug(DEBUG_POS, dptr, "state data unit=%d %d %d\n", unit, data->rec, data->count); @@ -804,13 +811,18 @@ t_stat dasd_srv(UNIT * uptr) case DK_RD_CNT: /* Read count */ /* Wait for next address mark */ if (state == DK_POS_AM) +// if (uptr->u3 & DK_PARAM) { +// uptr->u5 |= (SNS_NOREC << 8); +// uptr->u3 &= ~0xff; +// chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); +// } uptr->u3 |= DK_PARAM; /* If at end of disk, index or home address, stop reading */ - if (state == DK_POS_END || state == DK_POS_INDEX || state == DK_POS_HA) - uptr->u3 &= ~DK_PARAM; +// if (state == DK_POS_END || state == DK_POS_INDEX || state == DK_POS_HA) +// uptr->u3 &= ~DK_PARAM; /* When we are at count segment and passed address mark */ - if (uptr->u3 & DK_PARAM && state == DK_POS_CNT) { + if (uptr->u3 & DK_PARAM && state == DK_POS_CNT && data->rec != 0) { ch = *da; sim_debug(DEBUG_DETAIL, dptr, "readcnt ID unit=%d %d %x %02x %x %d %x\n", unit, count, state, ch, uptr->u4, data->tpos, uptr->u4); @@ -1035,17 +1047,17 @@ rd: chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); break; } - if (state == DK_POS_DATA && count == data->dlen) { - uptr->u3 &= ~(0xff|DK_PARAM); - chan_end(addr, SNS_CHNEND|SNS_DEVEND); - break; - } if (state == DK_POS_INDEX) { uptr->u5 = SNS_TRKOVR << 8; uptr->u3 &= ~(0xff|DK_PARAM); chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } + if (state == DK_POS_DATA && count == data->dlen) { + uptr->u3 &= ~(0xff|DK_PARAM); + chan_end(addr, SNS_CHNEND|SNS_DEVEND); + break; + } ch = *da; sim_debug(DEBUG_DATA, dptr, "RD Char %02x %02x %d %d\n", ch, state, count, data->tpos); @@ -1173,6 +1185,9 @@ rd: if (((uptr->u6 & 0x13) == 0x11 && (uptr->u3 & (DK_SHORTSRC|DK_SRCOK)) == DK_SRCOK)) { uptr->u3 |= DK_PARAM; + sim_debug(DEBUG_DETAIL, dptr, "WR KD unit=%d %d k=%d d=%d %02x %04x %d\n", + unit, data->rec, data->klen, data->dlen, data->state, + 8 + data->klen + data->dlen, count); } else { uptr->u5 |= SNS_CMDREJ | (SNS_INVSEQ << 8); uptr->u6 = 0; @@ -1196,6 +1211,9 @@ rd: if (((uptr->u6 & 0x3) == 1 && (uptr->u6 & 0xE0) != 0 && (uptr->u3 & (DK_SHORTSRC|DK_SRCOK)) == DK_SRCOK)) { uptr->u3 |= DK_PARAM; + sim_debug(DEBUG_DETAIL, dptr, "WR D unit=%d %d k=%d d=%d %02x %04x %d\n", + unit, data->rec, data->klen, data->dlen, data->state, + 8 + data->klen + data->dlen, count); } else { uptr->u5 |= SNS_CMDREJ | (SNS_INVSEQ << 8); uptr->u6 = 0; @@ -1212,7 +1230,7 @@ wrckd: uptr->u3 &= ~(0xff|DK_PARAM); chan_end(addr, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; - } else if (state == DK_POS_DATA && count == data->dlen) { + } else if (state == DK_POS_DATA && data->count == data->dlen) { uptr->u6 = cmd; uptr->u3 &= ~(0xff|DK_PARAM); chan_end(addr, SNS_CHNEND|SNS_DEVEND); @@ -1241,7 +1259,8 @@ wrckd: data->state = DK_POS_KEY; if (data->klen == 0) data->state = DK_POS_DATA; - } + data->count = 0; + } } break; diff --git a/IBM360/ibm360_lpr.c b/IBM360/ibm360_lpr.c index 15fcbf5..af39704 100644 --- a/IBM360/ibm360_lpr.c +++ b/IBM360/ibm360_lpr.c @@ -197,7 +197,7 @@ uint8 lpr_startcmd(UNIT * uptr, uint16 chan, uint8 cmd) sim_debug(DEBUG_CMD, &lpr_dev, "Cmd %02x\n", cmd); - switch (cmd & 0x7) { + switch (cmd & 0x3) { case 1: /* Write command */ uptr->u3 &= ~(LPR_CMDMSK); uptr->u3 |= (cmd & LPR_CMDMSK); @@ -215,14 +215,14 @@ uint8 lpr_startcmd(UNIT * uptr, uint16 chan, uint8 cmd) return SNS_CHNEND; case 0: /* Status */ + if (cmd == 0x4) { /* Sense */ + uptr->u3 &= ~(LPR_CMDMSK); + uptr->u3 |= (cmd & LPR_CMDMSK); + sim_activate(uptr, 10); /* Start unit off */ + return 0; + } break; - case 4: /* Sense */ - uptr->u3 &= ~(LPR_CMDMSK); - uptr->u3 |= (cmd & LPR_CMDMSK); - sim_activate(uptr, 10); /* Start unit off */ - return 0; - default: /* invalid command */ uptr->u5 |= SNS_CMDREJ; break;