From 0babe9da3fcf0d2ce88243528e808b349087cd56 Mon Sep 17 00:00:00 2001 From: AZBevier Date: Mon, 8 Mar 2021 19:11:39 -0700 Subject: [PATCH] SEL32: Fix 'mt offline' crash in UTX. SEL32: Fix device address assignment for ethernet controller. SEL32: Allow mag tape to be enabled/attached after system boot. SEL32: Change delay after SIO to be applied for each unit. SEL32: Create 1 tape backup of /usr for UTX. SEL32: Fix test for device on system to use disabled flag. SEL32: Correct wakeup status for 8-line support. SEL32: Support -i -n flags options to attach command. SEL32: Only support disk track replacement logic for diag tracks. SEL32: Fix two Coverity warning errors from last update. SEL32: Correct status flage setting for mag tape. SEL32: Update SEL32 Documentation. SEL32: Correct mkvmtape in taptools to 8 chars for owner and group names. --- SEL32/sel32_chan.c | 254 ++++++++++++++++++++++++++++---------- SEL32/sel32_clk.c | 8 +- SEL32/sel32_com.c | 97 ++++++++++++--- SEL32/sel32_cpu.c | 62 ++++++++-- SEL32/sel32_defs.h | 14 +++ SEL32/sel32_disk.c | 63 ++++++++-- SEL32/sel32_ec.c | 30 +++-- SEL32/sel32_hsdp.c | 55 +++++++-- SEL32/sel32_mt.c | 212 ++++++++++++++++++------------- SEL32/sel32_scfi.c | 43 ++++++- SEL32/sel32_scsi.c | 35 ++++++ SEL32/taptools/mkvmtape.c | 52 +++++--- doc/sel32_doc.doc | Bin 84480 -> 93696 bytes 13 files changed, 693 insertions(+), 232 deletions(-) diff --git a/SEL32/sel32_chan.c b/SEL32/sel32_chan.c index 7f341cf..833d3f9 100644 --- a/SEL32/sel32_chan.c +++ b/SEL32/sel32_chan.c @@ -86,7 +86,9 @@ extern uint32 CPUSTATUS; /* CPU status word */ extern uint32 INTS[]; /* Interrupt status flags */ extern uint32 TPSD[]; /* Temp save of PSD from memory 0&4 */ extern uint8 waitqcnt; /* # of instructions to xeq b4 int */ +#ifdef REMOVE_03072021 extern uint8 waitrdyq; /* # of instructions to xeq b4 rdy */ +#endif extern uint32 inbusy; extern uint32 outbusy; @@ -211,9 +213,11 @@ int32 RDYQ_Put(uint32 entry) RDYQIN += 1; /* next entry */ RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */ irq_pend = 1; /* do a scan */ +#ifdef REMOVE_03072021 //XXwaitrdyq = 10; /* UTX21A installs with this, but diags hang */ //XXwaitrdyq = 2; waitrdyq = 1; /* wait at least 1 instruction */ +#endif return SCPE_OK; /* all OK */ } @@ -729,6 +733,9 @@ loop: "load_ccw bad status chan %04x status %04x cmd %02x\n", chan, chp->chan_status, chp->ccw_cmd); RDYQ_Put(chp->chan_dev); /* queue us up */ +#ifndef CHANGE_03072021 + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw continue wait chsa %04x status %08x\n", chp->chan_dev, chp->chan_status); @@ -773,21 +780,21 @@ int chan_read_byte(uint16 chsa, uint8 *data) if (chp->ccw_count == 0) { /* see if more data required */ if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if Data Chain */ chp->chan_byte = BUFF_CHNEND; /* buffer end too */ - sim_debug(DEBUG_XIO, &cpu_dev, - "chan_read_byte no DC chan end, cnt %04x addr %06x chan %04x\n", - chp->ccw_count, chp->ccw_addr, chan); + sim_debug(DEBUG_EXP, &cpu_dev, + "chan_read_byte no DC chan end, cnt %04x addr %06x chsa %04x\n", + chp->ccw_count, chp->ccw_addr, chsa); return 1; /* return error */ } else { /* we have data chaining, process iocl */ if (load_ccw(chp, 1)) { /* process data chaining */ sim_debug(DEBUG_EXP, &cpu_dev, - "chan_read_byte with DC error, cnt %04x addr %06x chan %04x\n", - chp->ccw_count, chp->ccw_addr, chan); + "chan_read_byte with DC error, cnt %04x addr %06x chsa %04x\n", + chp->ccw_count, chp->ccw_addr, chsa); return 1; /* return error */ } sim_debug(DEBUG_EXP, &cpu_dev, - "chan_read_byte with DC IOCD loaded, cnt %04x addr %06x chan %04x\n", - chp->ccw_count, chp->ccw_addr, chan); + "chan_read_byte with DC IOCD loaded, cnt %04x addr %06x chsa %04x\n", + chp->ccw_count, chp->ccw_addr, chsa); } } /* get the next byte from memory */ @@ -1015,6 +1022,9 @@ void chan_end(uint16 chsa, uint16 flags) { "chan_end set RDYQ %04x No CC BUFF_NEXT chp %p chan_byte %04x\n", chsa, chp, chp->chan_byte); RDYQ_Put(chsa); /* queue us up */ +#ifndef CHANGE_03072021 + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif } /* just return */ goto goout; @@ -1087,9 +1097,14 @@ void chan_end(uint16 chsa, uint16 flags) { "$$$ CHEND SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", chsa, iocla, RMW(iocla), RMW(iocla+4)); +#ifdef CHANGE_03072021 if (waitqcnt == 0) /* test for UTX delay */ waitqcnt = 25; /* tell cpu to wait 20 instructions before int */ //XX waitqcnt = 15; /* tell cpu to wait 20 instructions before int */ +#else + /* this is the first IOCD for the SIO */ + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif } } } @@ -1208,17 +1223,24 @@ nothere: chp->chan_int = inta; /* make sure it is set in channel */ dptr = get_dev(uptr); /* pointer to DEVICE structure */ - /* check for the device being defined and attached in simh */ - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { - sim_debug(DEBUG_EXP, &cpu_dev, - "checkxio lchsa %04x rchsa %04x is not attached, CC3 return\n", lchsa, rchsa); + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ /* UTX wants CC1 on "mt offline" call. If not, UTX loops forever */ if ((dptr != NULL) && - (DEV_TYPE(dptr) == DEV_TAPE)) /* see if this is a tape */ + (DEV_TYPE(dptr) == DEV_TAPE)) { /* see if this is a tape */ *status = CC1BIT; /* CCs = 1, not busy */ - else + sim_debug(DEBUG_EXP, &cpu_dev, + "checkxio rchsa %04x device/unit not enabled, CC1 returned\n", + lchsa, rchsa); + } else { *status = CC3BIT; /* not attached, so error CC3 */ - return SCPE_OK; /* not found, CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "checkxio rchsa %04x device/unit not enabled, CC3 returned\n", + lchsa, rchsa); + } + return SCPE_OK; /* Not found CC3/CC1 */ } /* try this as MFP says it returns 0 on OK */ @@ -1228,8 +1250,9 @@ nothere: /* return CC1 for non iop/mfp devices */ //1003 *status = CC1BIT; /* CCs = 1, not busy */ *status = 0; /* CCs = 0, OK return */ - sim_debug(DEBUG_DETAIL, &cpu_dev, "checkxio lchsa %04x rchsa %04x done CC status %08x\n", - lchsa, rchsa, *status); + sim_debug(DEBUG_DETAIL, &cpu_dev, + "checkxio lchsa %04x rchsa %04x done CC status %08x\n", + lchsa, rchsa, *status); return SCPE_OK; /* No CC's all OK */ } @@ -1327,10 +1350,11 @@ missing: chsa, chp, (uptr->flags & UNIT_ATTABLE)?1:0, (uptr->flags & UNIT_ATT)?1:0, (uptr->flags & UNIT_DIS)?1:0); - /* is unit marked disabled? */ - if ((uptr->flags & UNIT_DIS) == 1) { + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { sim_debug(DEBUG_EXP, &cpu_dev, - "startxio chsa %04x device disabled, CC3 returned flags %08x\n", chsa, uptr->flags); + "startxio chsa %04x device/unit disabled, CC3 returned flags %08x\n", chsa, uptr->flags); *status = CC3BIT; /* not attached, so error CC3 */ return SCPE_OK; /* not found, CC3 */ } @@ -1345,7 +1369,7 @@ missing: #endif /* check for a Command or data chain operation in progresss */ - if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) { + if ((chp->chan_byte & BUFF_BUSY) && (chp->chan_byte != BUFF_POST)) { uint16 tstat = chp->chan_status; /* save status */ uint16 tcnt = chp->ccw_count; /* save count */ DEVICE *dptr = get_dev(uptr); @@ -1444,7 +1468,7 @@ missing: } else /* check for a Command or data chain operation in progresss */ - if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) { + if ((chp->chan_byte & BUFF_BUSY) && (chp->chan_byte != BUFF_POST)) { uint16 tstat = chp->chan_status; /* save status */ uint16 tcnt = chp->ccw_count; /* save count */ @@ -1480,12 +1504,18 @@ missing: "$$$ SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", chsa, iocla, RMW(iocla), RMW(iocla+4)); +#ifdef CHANGE_03072021 /* a value < 25 gets error ioi: sio at 801 failed, cc2 in UTX 21B */ if (waitqcnt == 0) /* test for UTX delay */ // waitqcnt = 20; /* tell cpu to wait 20 instructions before int */ // waitqcnt = 35; /* tell cpu to wait 20 instructions before int */ //XX waitqcnt = 15; /* tell cpu to wait 20 instructions before int */ waitqcnt = 25; /* tell cpu to wait 20 instructions before int */ +#else + chp->chan_qwait = QWAIT25; /* run 25 instructions before starting iocl */ +// chp->chan_qwait = QWAIT20; /* run 25 instructions before starting iocl */ +// chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ sim_debug(DEBUG_XIO, &cpu_dev, "$$$ SIO done chsa %04x status %08x iocla %08x CC's %08x\n", @@ -1499,6 +1529,7 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ UNIT *uptr; /* pointer to unit in channel */ uint32 chan_icb; /* Interrupt level context block address */ CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* Device ptr */ uint32 inta, incha, itva; uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 spadent; @@ -1514,10 +1545,12 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ dibp = dib_chan[rchan]; /* get the DIB pointer */ chp = find_chanp_ptr(rchan << 8); /* find the device chanp pointer */ +#ifdef CHANGE_03072021 if (waitqcnt != 0) { /* test for UTX delay */ waitqcnt = 0; /* tell cpu ok to int */ irq_pend = 1; /* flag to test for int condition */ } +#endif if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ *status = CC3BIT; /* not found, so CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, @@ -1526,11 +1559,13 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ } uptr = chp->unitptr; /* get the unit 0 ptr */ - /* is unit attached? */ - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { - *status = CC3BIT; /* not attached, so error CC3 */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, - "TIO lchsa %04x rchsa %04x device not attached, CC3 returned\n", lchsa, rchsa); + "TIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); return SCPE_OK; /* Not found, CC3 */ } @@ -1594,6 +1629,7 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ uint32 chan_icb; /* Interrupt level context block address */ uint32 iocla, inta, itva; /* I/O channel IOCL address int ICB */ CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* Device ptr */ uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 spadent; uint16 rchan, rchsa; /* the real channel number, chsa */ @@ -1615,11 +1651,14 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ } uptr = chp->unitptr; /* get the unit ptr */ - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ - *status = CC3BIT; /* not attached, so error CC3 */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, - "STPIO test 2 rchsa %04x device not present, CC3 returned\n", rchsa); - return SCPE_OK; /* not found CC3 */ + "STPIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ } /* the XIO opcode processing software has already checked for F class */ @@ -1707,6 +1746,7 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */ DIB *dibp; /* device information pointer */ UNIT *uptr; /* pointer to unit in channel */ CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* Device ptr */ int i; uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 inta; @@ -1731,12 +1771,14 @@ t_stat rschnlxio(uint16 lchsa, uint32 *status) { /* reset channel XIO */ } uptr = chp->unitptr; /* get the unit ptr */ - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ - *status = CC3BIT; /* not attached, so error CC3 */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, - "rschnlxio test 2 lchsa %04x rchsa %04x device not present, CC3 returned\n", - lchsa, rchsa); - return SCPE_OK; /* not found CC3 */ + "RSCHNL rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ } inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ @@ -1794,6 +1836,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ uint16 lchan = get_chan(lchsa); uint16 rchan, rchsa; CHANP *chp; /* Channel prog pointers */ + DEVICE *dptr; /* DEVICE pointer */ /* get the device entry for the logical channel in SPAD */ spadent = SPAD[lchan]; /* get spad device entry for logical channel */ @@ -1809,12 +1852,16 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ return SCPE_OK; /* not found, CC3 */ } uptr = chp->unitptr; /* get the unit ptr */ - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, - "HIO lchsa %04x rchsa %04x device not attached, CC3 returned\n", lchsa, rchsa); - *status = CC3BIT; /* not attached, so error CC3 */ - return SCPE_OK; /* not found, CC3 */ + "HIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ } + /* see if interrupt is setup in SPAD and determine IVL for channel */ sim_debug(DEBUG_XIO, &cpu_dev, "HIO dev spad %08x lchsa %04x rchsa %04x\n", spadent, lchsa, rchsa); @@ -1841,7 +1888,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ /* test for SCPE_IOERR */ if (tempa != 0) { /* sub channel has status ready */ /* The device I/O has been terminated and status stored. */ - sim_debug(DEBUG_XIO, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "HIO halt_io call return ERROR FIFO #%1x rchsa %04x retstat %08x cstat %08x\n", FIFO_Num(rchsa), rchsa, tempa, chp->chan_status); @@ -1854,36 +1901,93 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ if (post_csw(chp, ((STATUS_PCI) << 16))) { INTS[inta] &= ~INTS_REQ; /* clear any level request */ *status = CC2BIT; /* status stored */ - sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "$$$ HIO END2 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, *status); /* change status from BUFF_POST to BUFF_DONE */ if (chp->chan_byte == BUFF_POST) { chp->chan_byte = BUFF_DONE; /* show done & not busy */ sim_debug(DEBUG_EXP, &cpu_dev, - "HIO BUFF_DONE1 chp %p chan_byte %04x\n", chp, chp->chan_byte); + "HIO BUFF_DONE1a chp %p chan_byte %04x\n", chp, chp->chan_byte); } return SCPE_OK; /* CC2 & all OK */ } - } else { + } +#ifndef OLD_WAY_MAY_GOOD + else { chp->ccw_count = 0; /* zero the count */ /* The diags want the interrupt for the disk */ *status = CC1BIT; /* request accepted, no status, so CC1 */ - sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "$$$ HIO END2 ECHO rchsa %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, *status); return SCPE_OK; /* CC1 & all OK */ } +#endif } - /* the device is not busy, so cmd has not started */ + /* see if waiting to start */ + if (chp->chan_byte == BUFF_NEXT) { + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_NEXT chsa %04x cmd %02x ccw_flags %04x chan_byte %02x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + } + if (chp->chan_byte == BUFF_POST) { + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_POST chsa %04x cmd %02x ccw_flags %04x chan_byte %02x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + } + if (chp->chan_byte == BUFF_DONE) { + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_DONE chsa %04x cmd %02x ccw_flags %04x chan_byte %02x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + } + if (chp->chan_byte == BUFF_EMPTY) { + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_EMPTY chsa %04x cmd %02x ccw_flags %04x chan_byte %02x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + } +#ifdef OLD_WAY + /* see if waiting to start */ + if (chp->chan_byte == BUFF_NEXT) { + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_DONE2a chp %p chan_byte %04x\n", chp, chp->chan_byte); + chp->chan_byte = BUFF_DONE; /* allow to be dropped from RDYQ */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + return SCPE_OK; /* all OK */ + } + /* see if done */ + if (chp->chan_byte == BUFF_POST) { + /* post status for UTX */ + if (post_csw(chp, ((STATUS_PCI) << 16))) { + INTS[inta] &= ~INTS_REQ; /* clear any level request */ + *status = CC2BIT; /* status stored */ + sim_debug(DEBUG_EXP, &cpu_dev, + "$$$ HIO END2b rchsa %04x cmd %02x ccw_flags %04x status %04x\n", + rchsa, chp->ccw_cmd, chp->ccw_flags, *status); + /* change status from BUFF_POST to BUFF_DONE */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_DONE1b chp %p chan_byte %04x\n", chp, chp->chan_byte); + } + return SCPE_OK; /* CC2 & all OK */ + } + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO BUFF_DONE2c chp %p chan_byte %04x\n", chp, chp->chan_byte); + /* allow status to be posted */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + return SCPE_OK; /* all OK */ + } +#endif + /* the device is not busy, so cmd is completed */ sim_debug(DEBUG_EXP, &cpu_dev, - "HIO BUFF_DONE2 chp %p chan_byte %04x\n", chp, chp->chan_byte); + "HIO BUFF_DONE2d chp %p chan_byte %04x\n", chp, chp->chan_byte); /* the channel is not busy, so return OK */ *status = CC1BIT; /* request accepted, no status, so CC1 */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ HIO END3 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, *status); -#ifndef GIVE_INT_ON_NOT_BUSY_121420 +#ifndef GIVE_INT_ON_NOT_BUSY_121420_03082021 chp->chan_byte = BUFF_DONE; /* we are done */ sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE2 chp %p chan_byte %04x\n", chp, chp->chan_byte); @@ -1902,7 +2006,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ if ((chp->chan_byte & BUFF_BUSY) == 0) { /* the channel is not busy, so return OK */ *status = CC1BIT; /* request accepted, no status, so CC1 */ - sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "$$$ HIO END1 not busy return rchsa %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, *status); #ifndef MAYBE_NOT @@ -1922,7 +2026,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ /* a haltxio entry should be provided for a device so busy can be cleared */ /* check for a Command or data chain operation in progresss */ if (chp->chan_byte & BUFF_BUSY) { - sim_debug(DEBUG_XIO, &cpu_dev, "HIO device busy lchsa %04x rchsa %04x\n", lchsa, rchsa); + sim_debug(DEBUG_EXP, &cpu_dev, + "HIO device busy lchsa %04x rchsa %04x\n", lchsa, rchsa); /* reset the DC or CC bits to force completion */ chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ @@ -1937,7 +2042,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ if (post_csw(chp, ((STATUS_PCI) << 16))) { INTS[inta] &= ~INTS_REQ; /* clear any level request */ *status = CC2BIT; /* status stored from SIO, so CC2 */ - sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "$$$ HIO END4 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, *status); /* change status from BUFF_POST to BUFF_DONE */ @@ -1950,7 +2055,7 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ chp->chan_byte = BUFF_DONE; /* chan prog done */ /* the channel is not busy, so return OK */ *status = CC1BIT; /* request accepted, no status, so CC1 */ - sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "$$$ HIO END5 rchsa %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, *status); return SCPE_OK; /* No CC's all OK */ @@ -1962,6 +2067,7 @@ t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u * DIB *dibp; /* device information pointer */ UNIT *uptr; /* pointer to unit in channel */ CHANP *chp; + DEVICE *dptr; /* Device ptr */ uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 spadent; uint16 rchan, rchsa; /* the real channel number, chsa */ @@ -1983,11 +2089,14 @@ t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u * } uptr = chp->unitptr; /* get the unit ptr */ - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ - *status = CC3BIT; /* not attached, so error CC3 */ + /* is device or unit marked disabled? */ + dptr = get_dev(uptr); + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, - "GRIO test 2 lchsa %04x rchsa %04x device not present, CC3 returned\n", lchsa, rchsa); - return SCPE_OK; /* not found CC3 */ + "GRIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); + return SCPE_OK; /* Not found, CC3 */ } /* check for a Command or data chain operation in progresss */ @@ -2037,12 +2146,17 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */ *status = CC3BIT; /* not found, so CC3 */ return SCPE_OK; /* not found, CC3 */ } - sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 2 chan %04x, spad %08x\r\n", chsa, spadent); - if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ - *status = CC3BIT; /* not attached, so error CC3 */ - return SCPE_OK; /* not found, CC3 */ - } + sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 2 chan %04x spad %08x\r\n", chsa, spadent); + /* is device or unit marked disabled? */ dptr = get_dev(uptr); /* get device ptr */ +// if ((uptr->flags & UNIT_ATTABLE) && ((uptr->flags & UNIT_ATT) == 0)) { /* is unit attached? */ + if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { + /* is device/unit disabled? */ + *status = CC3BIT; /* not enabled, so error CC3 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "RSCTL rchsa %04x device/unit not enabled, CC3 returned\n", chsa); + return SCPE_OK; /* Not found, CC3 */ + } lev = find_int_lev(chan); /* get our int level */ INTS[lev] &= ~INTS_ACT; /* clear level active */ SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */ @@ -2176,7 +2290,7 @@ uint32 cont_chan(uint16 chsa) int32 stat; /* return status 0/1 from loadccw */ CHANP *chp = find_chanp_ptr(chsa); /* channel program */ - sim_debug(DEBUG_EXP, &cpu_dev, + sim_debug(DEBUG_XIO, &cpu_dev, "cont_chan entry chp %p chan_byte %02x chsa %04x addr %06x\n", chp, chp->chan_byte, chsa, chp->ccw_addr); /* we have entries, continue channel program */ @@ -2189,7 +2303,7 @@ uint32 cont_chan(uint16 chsa) } if (chp->chan_byte == BUFF_NEXT) { uint32 chan = get_chan(chsa); - sim_debug(DEBUG_EXP, &cpu_dev, + sim_debug(DEBUG_XIO, &cpu_dev, "cont_chan resume chan prog chsa %04x iocla %06x\n", chsa, chp->chan_caw); @@ -2222,13 +2336,13 @@ uint32 cont_chan(uint16 chsa) } /* we get here when the start cmd has been processed without error */ /* go wait for the cmd to finish */ - sim_debug(DEBUG_EXP, &cpu_dev, + sim_debug(DEBUG_XIO, &cpu_dev, "cont_chan continue wait chsa %04x status %08x iocla %06x byte %02x\n", chsa, chp->chan_status, chp->chan_caw, chp->chan_byte); return SCPE_OK; /* done, status stored */ } /* must be more IOCBs, wait for them */ - sim_debug(DEBUG_EXP, &cpu_dev, + sim_debug(DEBUG_XIO, &cpu_dev, "cont_chan continue not next chsa %04x status %08x iocla %06x\n", chsa, chp->chan_status, chp->chan_caw); return SCPE_OK; @@ -2286,11 +2400,13 @@ uint32 scan_chan(uint32 *ilev) { return 0; /* not ready, return */ } +#ifdef TEMP_REMOVE_03072021 /* see if we are able to look for ints */ if (irq_pend == 0) /* pending int? */ return 0; /* no, done */ if (CPUSTATUS & BIT24) /* interrupts blocked? */ return 0; /* yes, done */ +#endif /* ints not blocked, so look for highest requesting interrupt */ for (i=0; i<112; i++) { @@ -2321,6 +2437,7 @@ uint32 scan_chan(uint32 *ilev) { } } +#ifdef TEMP_REMOVE_03072021 /* cannot make anyone active if ints are blocked */ if ((CPUSTATUS & BIT24) || (waitqcnt)) { /* interrupts blocked? */ if (waitqcnt) /* doing wait delay? */ @@ -2329,6 +2446,14 @@ uint32 scan_chan(uint32 *ilev) { sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS blocked!\n"); goto tryme; /* needed for MPX */ } +#else + /* cannot make anyone active if ints are blocked */ + /* irq_pend will be set again when interrupts are unblocked */ + if (CPUSTATUS & BIT24) { /* interrupts blocked? */ + sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS blocked!\n"); + goto tryme; /* needed for MPX */ + } +#endif /* now go process the highest requesting interrupt */ for (i=0; i<112; i++) { @@ -2628,7 +2753,8 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { //printf("Got old chsa %04x\r\n", ochsa); dib_unit[ochsa] = NULL; /* clear sa dib pointer */ dib_unit[ochsa&0x7f00] = NULL; /* clear the channel dib address */ - if (dptr->flags & DEV_CHAN) { /* Is this a channel device IOP/MFP */ +// if (dptr->flags & DEV_CHAN) { /* Is this a channel device IOP/MFP */ + if (ochsa & 0xf0) { /* Is this a channel device IOP/MFP */ chan &= 0x7ff0; /* clean channel sub-address */ chsa = chan | (ochsa & 0xf); /* merge new channel with old sa */ } else { diff --git a/SEL32/sel32_clk.c b/SEL32/sel32_clk.c index 9425da6..62c4685 100644 --- a/SEL32/sel32_clk.c +++ b/SEL32/sel32_clk.c @@ -119,12 +119,16 @@ t_stat rtc_srv (UNIT *uptr) (SPAD[rtc_lvl+0x80] & SINT_ENAB)) && /* in spad too */ (((INTS[rtc_lvl] & INTS_ACT) == 0) || /* and not active */ ((SPAD[rtc_lvl+0x80] & SINT_ACT) == 0))) { /* in spad too */ +#if 0 /* HACK for console I/O stopping */ /* This reduces the number of console I/O stopping errors */ /* need to find real cause of I/O stopping on clock interrupt */ if ((outbusy==0) && (inbusy==0)) /* skip interrupt if con I/O in busy wait */ - INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */ - irq_pend = 1; /* make sure we scan for int */ + INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */ +#else + INTS[rtc_lvl] |= INTS_REQ; /* request the interrupt */ +#endif + irq_pend = 1; /* make sure we scan for int */ } sim_debug(DEBUG_CMD, &rtc_dev, "RT Clock int INTS[%02x] %08x SPAD[%02x] %08x\n", diff --git a/SEL32/sel32_com.c b/SEL32/sel32_com.c index 28e8165..042bcc7 100644 --- a/SEL32/sel32_com.c +++ b/SEL32/sel32_com.c @@ -96,6 +96,49 @@ TMXR com_desc = { COM_LINES_DFLT, 0, 0, com_ldsc }; /* com descr */ #define COM_READ 0x2000 /* Read mode selected */ /* ACE data kept in u4 */ +/* ACE information in u4 */ +#if 0 +/* ACE byte 0 Modem Control/Operation status */ +/* stored in u4 bytes 0-3 */ +#define SNS_HALFD 0x80000000 /* Half-duplix operation set */ +#define SNS_MRINGE 0x40000000 /* Modem ring enabled */ +#define SNS_ACEFP 0x20000000 /* Forced parity 0=odd, 1=even */ +#define SNS_ACEP 0x10000000 /* Parity 0=odd, 1=even */ +#define SNS_ACEPE 0x08000000 /* Parity enable 0=dis, 1=enb */ +#define SNS_ACESTOP 0x04000000 /* Stop bit 0=1, 1=1.5 or 2 */ +#define SNS_ACECLEN 0x02000000 /* Character length 00=5, 01=6, 11=7, 11=8 */ +#define SNS_ACECL2 0x01000000 /* 2nd bit for above */ + +/* ACE byte 1 Baud rate */ +#define SNS_NUB50 0x00800000 /* Zero N/U */ +#define SNS_NUB51 0x00400000 /* Zero N/U */ +#define SNS_RINGCR 0x00200000 /* Ring or wakeup character recognition 0=enb, 1=dis */ +#define SNS_DIAGL 0x00100000 /* Set diagnostic loopback */ +#define SNS_BAUD 0x000F0000 /* Baud rate bits 4-7 */ +#define BAUD50 0x00000000 /* 50 baud */ +#define BAUD75 0x00010000 /* 75 baud */ +#define BAUD110 0x00020000 /* 110 baud */ +#define BAUD114 0x00030000 /* 134 baud */ +#define BAUD150 0x00040000 /* 150 baud */ +#define BAUD300 0x00050000 /* 300 baud */ +#define BAUD600 0x00060000 /* 600 baud */ +#define BAUD1200 0x00070000 /* 1200 baud */ +#define BAUD1800 0x00080000 /* 1800 baud */ +#define BAUD2000 0x00090000 /* 2000 baud */ +#define BAUD2400 0x000A0000 /* 2400 baud */ +#define BAUD3600 0x000B0000 /* 3600 baud */ +#define BAUD4800 0x000C0000 /* 4800 baud */ +#define BAUD7200 0x000D0000 /* 7200 baud */ +#define BAUD9600 0x000E0000 /* 9600 baud */ +#define BAUD19200 0x000F0000 /* 19200 baud */ + +/* ACE byte 2 Wake-up character */ +#define ACE_WAKE 0x0000FF00 /* 8 bit wake-up character */ +#endif +#define ACE_WAKE 0x0000FF00 /* 8 bit wake-up character in byte 2 of ACE */ + +/* in u5 packs sense byte 0,1 and 3 */ +/* sense byte 3 */ /* in u5 packs sense byte 0, 1, 2 and 3 */ /* Sense byte 0 */ @@ -126,6 +169,9 @@ TMXR com_desc = { COM_LINES_DFLT, 0, 0, com_ldsc }; /* com descr */ #define SNS_DELDSR 0x00000200 /* Delta data set ready interrupt */ #define SNS_DELCLR 0x00000100 /* Ring character interrupt */ /* Sense byte 3 Modem Control/Operation status */ +#define SNS_RDY 0x80 /* device ready */ +#define SNS_ONLN 0x40 /* device online */ +//#define SNS_DSR 0x04 /* data set ready */ #define SNS_HALFD 0x00000080 /* Half-duplix operation set */ #define SNS_MRINGE 0x00000040 /* Modem ring enabled (1) */ #define SNS_ACEDEF 0x00000020 /* ACE parameters defined */ @@ -170,18 +216,6 @@ TMXR com_desc = { COM_LINES_DFLT, 0, 0, com_ldsc }; /* com descr */ /* Sense byte 7 Firmware ID, Revision Level */ #define SNS_REV 0x0000004f /* ID part 2 plus 4 bit rev # */ -/* ACE information in u4 */ -#define ACE_WAKE 0x0000FF00 /* 8 bit wake-up character */ - -/* in u5 packs sense byte 0,1 and 3 */ -/* Sense byte 0 */ -#define SNS_CMDREJ 0x80000000 /* Command reject */ -#define SNS_INTVENT 0x40000000 /* Unit intervention required */ -/* sense byte 3 */ -#define SNS_RDY 0x80 /* device ready */ -#define SNS_ONLN 0x40 /* device online */ -#define SNS_DSR 0x04 /* data set ready */ - /* u6 */ /* forward definitions */ @@ -416,7 +450,7 @@ uint16 com_preio(UNIT *uptr, uint16 chan) { uint16 chsa = GET_UADDR(uptr->u3); /* get channel/sub-addr */ // int cmd = uptr->u3 & 0xff; -#ifdef WAIT_FOR_TESTING +#ifndef WAIT_FOR_TESTING sim_debug(DEBUG_CMD, dptr, "com_preio CMD %08x unit %02x chsa %04x\n", uptr->u3, unit, chsa); if ((uptr->u3 & COM_MSK) != 0) { /* just return if busy */ @@ -435,6 +469,7 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { DEVICE *dptr = get_dev(uptr); int unit = (uptr - dptr->units); + uint16 chsa = (((uptr->u3 & LMASK) >> 16) | (chan << 8)); uint8 ch; if ((uptr->u3 & COM_MSK) != 0) { /* is unit busy */ @@ -476,6 +511,7 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) /* bit 3 P=1 Purge input buffer */ case COM_RD: /* 0x02 */ /* Read command */ case COM_RDECHO: /* 0x06 */ /* Read command w/ECHO */ + case 0x32: /* 0x32 */ /* Read command ASCII & Purge input */ case 0x46: /* 0x46 */ /* Read command w/ECHO & ASCII */ case 0x56: /* 0x56 */ /* Read command w/ECHO & ASCII & Purge input */ /* if bit 0 set for COM_RDFC, use DTR for flow, else use RTS for flow control */ @@ -549,12 +585,17 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) case COM_DEFSC: /* 0x0B */ /* Define special char */ sim_debug(DEBUG_CMD, dptr, - "com_startcmd %04x: Cmd %02x DEFSC\n", chan, cmd); + "com_startcmd %04x: Cmd %02x DEFSC\n", chsa, cmd); if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char from memory */ /* nothing to read, error */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ } + uptr->u4 &= ~ACE_WAKE; /* clear out old wake char */ + uptr->u4 |= ((uint32)ch << 8); /* insert special char */ uptr->u5 = ~SNS_RTS; /* Request to send not ready */ + sim_debug(DEBUG_CMD, dptr, + "com_startcmd %04x: Cmd %02x DEFSC char %02x ACE %08x\n", + chsa, cmd, ch, uptr->u4); return SNS_CHNEND|SNS_DEVEND; /* good return */ break; @@ -603,7 +644,7 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) #define SNS_ACEP 0x10000000 /* Parity 0=odd, 1=even */ #define SNS_ACEPE 0x08000000 /* Parity enable 0=dis, 1=enb */ #define SNS_ACESTOP 0x04000000 /* Stop bit 0=1, 1=1.5 or 2 */ -#define SNS_ACECLEN 0x02000000 /* Character length 00=5, 01=6, 11=7, 11=8 */ +#define SNS_ACECLEN 0x02000000 /* Character length 00=5, 01=6, 10=7, 11=8 */ #define SNS_ACECL2 0x01000000 /* 2nd bit for above */ /* ACE byte 1 Baud rate */ @@ -635,25 +676,38 @@ uint16 com_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) case COM_SACE: /* 0xff */ /* Set ACE parameters (3 chars) */ sim_debug(DEBUG_CMD, dptr, - "com_startcmd %04x: Cmd %02x SACE\n", chan, cmd); + "com_startcmd %04x: Cmd %02x SACE\n", chsa, cmd); + if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char 0 */ /* nothing to read, error */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ } uptr->u4 = ((uint32)ch)<<24; /* byte 0 of ACE data */ + sim_debug(DEBUG_CMD, dptr, + "com_startcmd %04x: Cmd %02x ACE byte 0 %02x\n", + chsa, cmd, ch); + if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char 1 */ /* nothing to read, error */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ } uptr->u4 |= ((uint32)ch)<<16; /* byte 1 of ACE data */ + sim_debug(DEBUG_CMD, dptr, + "com_startcmd %04x: Cmd %02x ACE byte 1 %02x\n", + chsa, cmd, ch); + if (chan_read_byte(GET_UADDR(uptr->u3), &ch)) { /* read char 2 */ /* nothing to read, error */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* good return */ } uptr->u4 |= ((uint32)ch)<<8; /* byte 2 of ACE data */ + sim_debug(DEBUG_CMD, dptr, + "com_startcmd %04x: Cmd %02x ACE byte 2 %02x\n", + chsa, cmd, ch); sim_debug(DEBUG_CMD, dptr, "com_startcmd %04x: Cmd %02x ACE bytes %08x\n", chan, cmd, uptr->u4); + return SNS_CHNEND|SNS_DEVEND; /* good return */ break; @@ -719,6 +773,9 @@ t_stat comi_srv(UNIT *uptr) com_sta[newln] &= ~COML_REP; /* clr pending */ /* send attention to OS here for this channel */ /* need to get chsa here for the channel */ + sim_debug(DEBUG_CMD, &com_dev, + "comi_srv wakeup on chsa %04x line %02x cmd %02x ACE %08x\n", + chsa, ln, cmd, uptr->u4); set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); /* tell user */ } /* poll all devices for input */ @@ -762,14 +819,19 @@ t_stat comi_srv(UNIT *uptr) /* send attention to OS here for this channel */ /* need to get chsa here for the channel */ /* tell user */ + sim_debug(DEBUG_CMD, &com_dev, + "comi_srv user wakeup on chsa %04x line %02x cmd %02x ACE %08x\n", + chsa, ln, cmd, uptr->u4); set_devwake(chsa, SNS_ATTN|SNS_DEVEND|SNS_CHNEND); } } } /* end else char */ } /* end if char */ } /* end if conn */ - else + else { com_sta[ln] &= ~COML_RBP; /* disconnected */ + com_sta[ln] |= COML_REP; /* set pending */ + } } /* end for */ return sim_clock_coschedule(uptr, 200); /* continue poll */ } @@ -920,6 +982,7 @@ void com_reset_ln (int32 ln) { sim_cancel(&coml_unit[ln]); com_sta[ln] = 0; + com_sta[ln] |= COML_REP; /* set pending */ com_rbuf[ln] = 0; /* clear read buffer */ com_xbuf[ln] = 0; /* clear write buffer */ com_ldsc[ln].rcve = 0; diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index 5cbe6d9..bfe6611 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -158,7 +158,9 @@ uint32 RDYQIN; /* fifo input index */ uint32 RDYQOUT; /* fifo output index */ uint32 RDYQ[128]; /* channel ready queue */ uint8 waitqcnt = 0; /* # instructions before start */ +#ifdef REMOVE_03072021 uint8 waitrdyq = 0; /* # instructions before post interrupt */ +#endif struct InstHistory { @@ -1453,7 +1455,7 @@ t_stat RealAddr(uint32 addr, uint32 *realaddr, uint32 *prot, uint32 access) if (CPU_MODEL >= MODEL_V6) { /* map is not valid, so we have map fault */ sim_debug(DEBUG_EXP, &cpu_dev, - "AddrMa %06x RealAddr %06x Map0 HIT %04x, TLB[%3x] %08x MAPC[%03x] %08x\n", + "AddrMa %06x RealAddr %06x Map0 MISS %04x, TLB[%3x] %08x MAPC[%03x] %08x\n", addr, word, map, nix, TLB[nix], nix/2, MAPC[nix/2]); /* do a demand page request for the required page */ pfault = nix; /* save page number */ @@ -1674,7 +1676,7 @@ t_stat Mem_read(uint32 addr, uint32 *data) else TRAPSTATUS |= BIT10; /* set bit 10 of trap status */ } - sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read error %02x @ %06x TRAPSTATUS %08x\n", + sim_debug(DEBUG_EXP, &cpu_dev, "Mem_read MISS %02x @ %06x TRAPSTATUS %08x\n", status, addr, TRAPSTATUS); } return status; /* return ALLOK or ERROR status */ @@ -1943,9 +1945,11 @@ wait_loop: uint32 chsa; /* channel/sub adddress */ int32 stat; /* return status 0/1 from loadccw */ +#ifdef REMOVE_03072021 if (waitrdyq > 0) { /* see if we are waiting to start */ waitrdyq--; } else +#endif /* we have entries, continue channel program */ if (RDYQ_Get(&chsa) == SCPE_OK) { /* get chsa for program */ sim_debug(DEBUG_XIO, &cpu_dev, @@ -2071,32 +2075,68 @@ wait_loop: } } +#ifndef CHANGE_03072021 + /* loop through the IOCL ready Q and decrement wait counts */ + if ((int32c = RDYQ_Num())) { + int32 i, rqo = RDYQOUT; + for (i=0; ichan_qwait > 0) /* still waiting? */ + chp->chan_qwait--; /* decrement count */ + rqo++; /* next queue entry */ + rqo %= RDYQ_SIZE; /* don't overrun end */ + } + } +#endif /* process IOCL entries that are waiting */ if (RDYQ_Num()) { uint32 chsa; /* channel/sub adddress */ CHANP *chp; /* get channel prog pointer */ chsa = RDYQ[RDYQOUT]; /* get the next entry */ chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + if (chp->chan_byte != BUFF_NEXT) { + /* chan_byte is not BUFF_NEXT */ + sim_debug(DEBUG_XIO, &cpu_dev, + "scan_chan Bad CPU RDYQ entry for chsa %04x chan_byte %02x\n", + chsa, chp->chan_byte); + } +#ifdef CHANGE_03072021 if (chp->chan_byte == BUFF_NEXT) { +#else + /* checking BUFF_NEXT hangs diag n keyboard termination */ + if ((chp->chan_qwait == 0) || (chp->chan_byte != BUFF_NEXT)) { +// if ((chp->chan_qwait == 0) && (chp->chan_byte == BUFF_NEXT)) { +// if (chp->chan_qwait == 0) { +#endif +#ifdef REMOVE_03072021 /* we have entries, continue channel program */ if (waitrdyq > 0) { waitrdyq--; } else +#endif if (RDYQ_Get(&chsa) == SCPE_OK) { /* get chsa for program */ int32 stat; CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ sim_debug(DEBUG_XIO, &cpu_dev, "scan_chan CPU RDYQ entry for chsa %04x starting byte %02x\n", chsa, chp->chan_byte); - stat = cont_chan(chsa); /* resume the channel program */ - if (stat == SCPE_OK) - sim_debug(DEBUG_XIO, &cpu_dev, - "scan_chan CPU RDYQ entry for chsa %04x processed byte %04x\n", - chsa, chp->chan_byte); - else - sim_debug(DEBUG_XIO, &cpu_dev, - "scan_chan CPU RDYQ entry for chsa %04x processed w/error byte %04x\n", - chsa, chp->chan_byte); + /* if not BUFF_NEXT, channel has been stopped, just continue */ + if (chp->chan_byte == BUFF_NEXT) { + stat = cont_chan(chsa); /* resume the channel program */ + if (stat == SCPE_OK) + sim_debug(DEBUG_XIO, &cpu_dev, + "scan_chan CPU RDYQ entry for chsa %04x processed byte %04x\n", + chsa, chp->chan_byte); + else + sim_debug(DEBUG_XIO, &cpu_dev, + "scan_chan CPU RDYQ entry for chsa %04x processed w/error byte %04x\n", + chsa, chp->chan_byte); + } } } } diff --git a/SEL32/sel32_defs.h b/SEL32/sel32_defs.h index 0af2d26..b1a90ba 100644 --- a/SEL32/sel32_defs.h +++ b/SEL32/sel32_defs.h @@ -212,12 +212,26 @@ typedef struct chp { uint16 ccw_flags; /* Channel flags */ uint16 chan_status; /* Channel status */ uint16 chan_dev; /* Device on channel */ +#ifndef CHANGE_03072021 + uint16 chan_qwait; /* Instr to xeq before iocl proccessing */ +#endif uint8 ccw_cmd; /* Channel command and flags */ uint8 chan_byte; /* Current byte, empty/full */ uint8 chan_int; /* channel interrupt level */ uint8 chan_info; /* misc flags for channel */ } CHANP; +#define QWAIT0 0 +#define QWAIT5 5 +#define QWAIT10 10 +#define QWAIT15 15 +#define QWAIT20 20 +#define QWAIT25 25 +#define QWAIT30 30 +#define QWAIT35 35 +#define QWAIT40 40 +#define QWAIT QWAIT0 + /* Device information block */ #define FIFO_SIZE 256 /* fifo to hold 128 double words of status */ extern int32 FIFO_Put(uint16 chsa, uint32 entry); diff --git a/SEL32/sel32_disk.c b/SEL32/sel32_disk.c index 5c318e2..3feb017 100644 --- a/SEL32/sel32_disk.c +++ b/SEL32/sel32_disk.c @@ -587,14 +587,20 @@ uint32 get_dmatrk(UNIT *uptr, uint32 star, uint8 buf[]) int unit = (uptr - dptr->units); /* get the UNIT number */ int len, i, cn, found = -1; - /* zero the Track Label Buffer */ - for (i = 0; i < 30; i++) - buf[i] = 0; - +#ifdef SPEEDUP + int ds = ((CYL(type) - 3) * HDS(type)) * SPT(type); /* diag start */ /* get file offset in sectors */ tstart = STAR2SEC(star, SPT(type), SPC(type)); /* convert sector number back to chs value to sync disk for diags */ nstar = disksec2star(tstart, type); + if (ds >= tstart) + return nstar; /* not in diag track, return */ +#else + /* get file offset in sectors */ + tstart = STAR2SEC(star, SPT(type), SPC(type)); + /* convert sector number back to chs value to sync disk for diags */ + nstar = disksec2star(tstart, type); +#endif cyl = (nstar >> 16) & 0xffff; /* get the cylinder */ trk = (nstar >> 8) & 0xff; /* get the track */ @@ -610,6 +616,10 @@ uint32 get_dmatrk(UNIT *uptr, uint32 star, uint8 buf[]) /* calc offset in file to track label */ offset = CAPB(type) + (tstart * 30); + /* zero the Track Label Buffer */ + for (i = 0; i < 30; i++) + buf[i] = 0; + /* see if track label is in cache */ for (cn=0; cnchan_dev, chp->chan_status); +#ifndef CHANGE_03072021 + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif } } else @@ -2951,6 +2964,7 @@ int disk_format(UNIT *uptr) { uint32 cylv = cyl; /* number of cylinders */ uint8 *buff; int32 i; + t_stat oldsw = sim_switches; /* save switches */ /* last sector address of disk (cyl * hds * spt) - 1 */ uint32 laddr = CAP(type) - 1; /* last sector of disk */ @@ -2996,9 +3010,16 @@ int disk_format(UNIT *uptr) { 0x9a000000 | ltaddr, 0xf4000000}; #endif - /* see if user wants to initialize the disk */ - if (!get_yn("Initialize disk? [Y] ", TRUE)) { - return 1; + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { +// printf("disk_format init question is false\r\n"); + sim_switches = oldsw; + return 1; + } + sim_switches = oldsw; /* restore switches */ } /* VDT 249264 (819/18/0) 0x3cdb0 for 9346 - 823/19/16 vaddr */ @@ -3177,6 +3198,15 @@ t_stat disk_attach(UNIT *uptr, CONST char *file) return SCPE_FMT; /* error */ } + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nDisk device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nDisk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + /* have simulator attach the file to the unit */ if ((r = attach_unit(uptr, file)) != SCPE_OK) return r; @@ -3194,6 +3224,11 @@ t_stat disk_attach(UNIT *uptr, CONST char *file) disk_type[type].name, disk_type[type].cyl, disk_type[type].nhds, disk_type[type].spt, ssize, uptr->capac); /* disk capacity */ + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + /* seek to end of disk */ if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { sim_debug(DEBUG_CMD, dptr, "UDP Disk attach SEEK end failed\n"); @@ -3207,8 +3242,8 @@ t_stat disk_attach(UNIT *uptr, CONST char *file) printf("Disk attach ftell failed s=%06d\r\n", s); goto fmt; /* not setup, go format */ } -// sim_debug(DEBUG_CMD, dptr, "UDP Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type)); -// printf("Disk attach ftell value s=%06d b=%06d CAP %06d\r\n", s/ssize, s, CAP(type)); + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type)); + printf("Disk attach ftell value s=%06d b=%06d CAP %06d\r\n", s/ssize, s, CAP(type)); if (((int)s/(int)ssize) < ((int)CAP(type))) { /* full sized disk? */ j = (CAP(type) - (s/ssize)); /* get # sectors to write */ @@ -3301,6 +3336,8 @@ fmt: ldone: /* see if disk has labels already, seek to sector past end of disk */ if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */ + sim_debug(DEBUG_CMD, dptr, "UDP Disk attach SEEK last sector @ldone failed\n"); + printf("UDP Disk attach SEEK last sector @ldone failed\r\n"); detach_unit(uptr); /* detach if error */ return SCPE_FMT; /* error */ } @@ -3398,12 +3435,20 @@ t_stat disk_boot(int32 unit_num, DEVICE *dptr) { sim_debug(DEBUG_CMD, dptr, "Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nDisk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + if ((uptr->flags & UNIT_ATT) == 0) { sim_debug(DEBUG_EXP, dptr, "Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); return SCPE_UNATT; /* attached? */ } + SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ SPAD[0xf8] = 0xF000; /* show as F class device */ diff --git a/SEL32/sel32_ec.c b/SEL32/sel32_ec.c index 7003f93..6b27e52 100644 --- a/SEL32/sel32_ec.c +++ b/SEL32/sel32_ec.c @@ -259,6 +259,8 @@ UNIT ec_unit[] = { {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE05)}, /* 5 */ {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE06)}, /* 6 */ {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE07)}, /* 7 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE08)}, /* 8 */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_DIS|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE09)}, /* 9 */ #else {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE01)}, /* 1 */ {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE02)}, /* 2 */ @@ -539,9 +541,6 @@ loop: } } -// if (chp->ccw_cmd == EC_READ) /* Force SLI on READ */ -// chp->ccw_flags |= FLAG_SLI; - chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ sim_debug(DEBUG_XIO, dptr, @@ -589,6 +588,9 @@ loop: sim_debug(DEBUG_EXP, dptr, "ec_iocl continue wait chsa %04x status %08x\n", chp->chan_dev, chp->chan_status); +#ifndef CHANGE_03072021 + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif } } else @@ -1155,8 +1157,9 @@ wr_end: } len = ec_data.rec_buff[ec_data.xtr_ptr].len; +/*JB*/ ec_data.rec_buff[ec_data.xtr_ptr].len = 0; /* clear old count */ // if (ec_data.xtr_ptr == ec_data.rec_ptr) - // len = 0; +// len = 0; sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv SNS %d %d\n", ec_data.xtr_ptr, ec_data.rec_ptr); ch = (uptr->SNS >> 24) & 0xfc; @@ -1185,7 +1188,7 @@ wr_end: break; } uptr->SNS &= ~(SNS_CMDREJ|SNS_EQUCHK); /* clear old status */ - +/*JB*/ uptr->SNS &= 0xffff0000; /* clear last count */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ break; @@ -1221,12 +1224,12 @@ uint16 ec_haltio(UNIT *uptr) { sim_debug(DEBUG_CMD, dptr, "ec_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); // stop any I/O and post status and return error status */ - chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */ chp->ccw_count = 0; /* zero the count */ chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* stop any chaining */ uptr->CMD &= LMASK; /* make non-busy */ uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ - sim_cancel(uptr); /* clear the input timer */ + if (chsa & 0x0f) /* no cancel for 0 */ + sim_cancel(uptr); /* clear the input timer */ sim_debug(DEBUG_CMD, dptr, "ec_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ @@ -1254,12 +1257,18 @@ void ec_ini(UNIT *uptr, t_bool f) ec_data.xtr_ptr = 0; ec_data.drop_cnt = 0; ec_data.amc = 0; - if (ec_master_uptr->flags & UNIT_ATT) + if (ec_master_uptr->flags & UNIT_ATT) { /* multicast on means promiscous is too */ eth_filter (&ec_data.etherface, ec_data.macs_n + 2, ec_data.macs, ec_data.amc, ec_data.macs[0][0] & 1); - sim_debug(DEBUG_EXP, dptr, - "EC init device %s on unit EC%04X\n", dptr->name, GET_UADDR(uptr->CMD)); + sim_debug(DEBUG_EXP, dptr, + "EC init device %s is attached on unit EC%04X\n", + dptr->name, GET_UADDR(uptr->CMD)); + } else { + sim_debug(DEBUG_EXP, dptr, + "EC init device %s not attached on unit EC%04X\n", + dptr->name, GET_UADDR(uptr->CMD)); + } } #ifdef FOR_TEST @@ -1572,6 +1581,7 @@ t_stat ec_attach(UNIT* uptr, CONST char* cptr) /* init read queue (first time only) */ status = ethq_init(&ec_data.ReadQ, 8); +// status = ethq_init(&ec_data.ReadQ, 16); /* try 16 per device */ if (status != SCPE_OK) { eth_close(&ec_data.etherface); uptr->filename = NULL; diff --git a/SEL32/sel32_hsdp.c b/SEL32/sel32_hsdp.c index cc5eccf..d0b891f 100644 --- a/SEL32/sel32_hsdp.c +++ b/SEL32/sel32_hsdp.c @@ -1066,6 +1066,9 @@ loop: sim_debug(DEBUG_EXP, dptr, "hsdp_iocl continue wait chsa %04x status %08x\n", chp->chan_dev, chp->chan_status); +#ifndef CHANGE_03072021 + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif } } else @@ -1202,7 +1205,6 @@ uint16 hsdp_haltio(UNIT *uptr) { sim_debug(DEBUG_CMD, dptr, "hsdp_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); /* stop any I/O and post status and return error status */ -// chp->chan_byte = BUFF_EMPTY; /* there is no data to read/store */ chp->ccw_count = 0; /* zero the count */ chp->chan_caw = 0; /* zero iocd address for diags */ chp->ccw_flags &= ~(FLAG_DC|FLAG_CC);/* stop any chaining */ @@ -3296,7 +3298,8 @@ int hsdp_format(UNIT *uptr) { uint32 cylv = cyl; /* number of cylinders */ uint8 *buff; int i; - int use_st_format = 1; + int use_st_format = 1; /* assume we use s/t replacement */ + t_stat oldsw = sim_switches; /* save switches */ /* last sector address of disk (cyl * hds * spt) - 1 */ uint32 laddr = CAP(type) - 1; /* last sector of disk */ @@ -3359,14 +3362,20 @@ int hsdp_format(UNIT *uptr) { 0x9a000000 | loglta, 0xf4000000}; #endif - - /* see if user wants to initialize the disk */ - if (!get_yn("Initialize disk? [Y] ", TRUE)) { - return 1; + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { +// printf("disk_format init question is false\r\n"); + sim_switches = oldsw; + return 1; + } } - if (!get_yn("Use Sector/Track replacement format? [Y] ", TRUE)) { - use_st_format = 0; + if (!get_yn("Use Sector/Track replacement format? [N] ", FALSE)) { + use_st_format = 0; /* do not use s/t replacement */ } + sim_switches = oldsw; /* restore switches */ /* get physical sector address of media defect table */ /* VDT 286965 (819/9/0) 0x460f5 for 8887 - 823/10/35 */ @@ -3579,6 +3588,15 @@ t_stat hsdp_attach(UNIT *uptr, CONST char *file) return SCPE_FMT; /* error */ } + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nHSDP device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nHSDP device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + /* have simulator attach the file to the unit */ if ((r = attach_unit(uptr, file)) != SCPE_OK) return r; @@ -3597,6 +3615,11 @@ t_stat hsdp_attach(UNIT *uptr, CONST char *file) hsdp_type[type].name, hsdp_type[type].cyl, hsdp_type[type].nhds, hsdp_type[type].spt, ssize, uptr->capac); /* hsdp capacity */ + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + /* seek to end of disk */ if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { sim_debug(DEBUG_CMD, dptr, "HSDP Disk attach SEEK end failed\n"); @@ -3798,11 +3821,15 @@ ldone: return SCPE_FMT; /* error */ } info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; - good = (0x4e<<24) | (0x55<<16) | (0x4d<<8) | 0x50; /* NUMP */ + good = 0x4e554d50; /* NUMP */ // printf("info %8x good %8x cnt %x\r\n", info, good, buff[35]); if (info == good) { /* we have a UTX umap, so fixup the data */ - i = (16*8) + (buff[35]*3*4) - 1; /* byte offset to where to put 0xf4 */ + if (buff[35] <= SPT(type)) +// i = (16*8) + (buff[35]*3*4) - 1; /* byte offset to where to put 0xf4 */ + i = (127) + (buff[35]*12); /* byte offset to where to put 0xf4 */ + else + i = 127; /* only 1 track of replacement */ // printf("Fixing umap i %x info %8x good %8x buff[%x] %02x\r\n", i, info, good, i, buff[i]); buff[i] = 0xf4; /* set stop for UTX search */ if ((sim_fseek(uptr->fileref, umapaddr*ssize, SEEK_SET)) != 0) { /* seek umap */ @@ -3879,9 +3906,17 @@ t_stat hsdp_boot(int32 unit_num, DEVICE * dptr) { sim_debug(DEBUG_CMD, dptr, "HSDP Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nHSDP device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + if ((uptr->flags & UNIT_ATT) == 0) { sim_debug(DEBUG_EXP, dptr, "HSDP Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("HSDP Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); return SCPE_UNATT; /* attached? */ } SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ diff --git a/SEL32/sel32_mt.c b/SEL32/sel32_mt.c index 91bfbea..e2aa2e9 100644 --- a/SEL32/sel32_mt.c +++ b/SEL32/sel32_mt.c @@ -45,6 +45,8 @@ #define UNIT_MT UNIT_ATTABLE | UNIT_DISABLE | UNIT_ROABLE #define DEV_BUF_NUM(x) (((x) & 07) << DEV_V_UF2) #define GET_DEV_BUF(x) (((x) >> DEV_V_UF2) & 07) +//#define MTUF_V_WLK (UNIT_V_UF + 0) /* write lock */ +//#define MTUF_WLK (1u << MTUF_V_WLK) #define CMD u3 /* BTP tape commands */ @@ -116,15 +118,17 @@ #define SNS_DATAWR 0x020000 /* Data written */ #define SNS_SPARE3 0x010000 /* Spare */ -/* Sense byte 2 mode bits */ -#define SNS_MREG0 0x8000 /* Mode register bit 0 */ -#define SNS_MREG1 0x4000 /* Mode register bit 1 */ -#define SNS_MREG2 0x2000 /* Mode register bit 2 */ -#define SNS_MREG3 0x1000 /* Mode register bit 3 */ -#define SNS_MREG4 0x0800 /* Mode register bit 4 */ -#define SNS_MREG5 0x0400 /* Mode register bit 5 */ -#define SNS_MREG6 0x0200 /* Mode register bit 6 */ -#define SNS_MREG7 0x0100 /* Mode register bit 7 */ +/* Sense byte 2 mode register bits */ +#define SNS_MREG0 0x8000 /* 0 - Auto retry on read error */ + /* 1 - Ignore read errors */ +#define SNS_MREG1 0x4000 /* 0 - NRZI */ + /* 1 - PE */ +#define SNS_MREG2 0x2000 /* Mode register bit 2 N/U */ +#define SNS_MREG3 0x1000 /* Mode register bit 3 N/U */ +#define SNS_MREG4 0x0800 /* Mode register bit 4 N/U */ +#define SNS_MREG5 0x0400 /* Mode register bit 5 N/U */ +#define SNS_MREG6 0x0200 /* Mode register bit 6 N/U */ +#define SNS_MREG7 0x0100 /* 1 - HSDP scatter/gather mode */ /* Sense byte 3 */ /* data returned for SENSE cnd (0x04) */ @@ -319,8 +323,8 @@ DEVICE mta_dev = { NUM_UNITS_MT, 16, 24, 4, 16, 32, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, /* ctxt is the DIB pointer */ -// &mta_dib, DEV_BUF_NUM(0)|DEV_DIS|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, - &mta_dib, DEV_BUF_NUM(0)|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, + &mta_dib, DEV_BUF_NUM(0)|DEV_DIS|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, +// &mta_dib, DEV_BUF_NUM(0)|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; @@ -366,7 +370,8 @@ DEVICE mtb_dev = { "MTB", mtb_unit, NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mtb_dib, DEV_BUF_NUM(1)|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug + &mtb_dib, DEV_BUF_NUM(0)|DEV_DIS|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug, +// &mtb_dib, DEV_BUF_NUM(1)|DEV_DISABLE|DEV_DEBUG|DEV_TAPE, 0, dev_debug NULL, NULL, &mt_help, NULL, NULL, &mt_description }; #endif @@ -385,13 +390,15 @@ uint16 mt_preio(UNIT *uptr, uint16 chan) { return SNS_BSY; } if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + /* set status */ uptr->SNS |= SNS_INTVENT; /* unit intervention required */ uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ - return SNS_BSY; + return SCPE_OK; /* good to go */ +// return SNS_BSY; } - sim_debug(DEBUG_CMD, dptr, "mt_preio unit %02x chsa %04xOK\n", unit, chsa); + sim_debug(DEBUG_CMD, dptr, "mt_preio unit %02x chsa %04x OK\n", unit, chsa); return SCPE_OK; /* good to go */ } @@ -448,16 +455,27 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) sim_debug(DEBUG_EXP, dptr, "mt_startcmd READ chan %04x addr %06x cnt %04x\n", chan, chp->ccw_addr, chp->ccw_count); - if (cmd != 0x03) /* if this is a nop do not zero status */ + if (cmd != 0x03) { /* if this is a nop do not zero status */ uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */ - uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */ - /* Fall through */ - if (sim_tape_wrp(uptr)) - uptr->SNS |= (SNS_WRP); /* write protected */ - if (sim_tape_bot(uptr)) - uptr->SNS |= (SNS_LOAD); /* tape at load point */ - if (sim_tape_eot(uptr)) - uptr->SNS |= (SNS_EOT); /* tape at EOM */ +// uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */ + } + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + sim_debug(DEBUG_CMD, dptr, "mt_startcmd detached sense %08x chan %04x cmd %02x\n", + uptr->SNS, chan, cmd); + } else { + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */ + if (sim_tape_wrp(uptr)) + uptr->SNS |= (SNS_WRP); /* write protected */ + if (sim_tape_bot(uptr)) + uptr->SNS |= (SNS_LOAD); /* tape at load point */ + if (sim_tape_eot(uptr)) + uptr->SNS |= (SNS_EOT); /* tape at EOM */ + sim_debug(DEBUG_CMD, dptr, "mt_startcmd attached sense %08x chan %04x cmd %02x\n", + uptr->SNS, chan, cmd); + } /* Fall through */ case 0x04: /* Sense */ @@ -466,10 +484,10 @@ uint16 mt_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) CLR_BUF(uptr); /* buffer is empty */ uptr->POS = 0; /* reset buffer position pointer */ mt_busy[GET_DEV_BUF(dptr->flags)] = 1; /* show we are busy */ - sim_debug(DEBUG_EXP, dptr, "mt_startcmd sense %08x return 0 chan %04x cmd %02x\n", + sim_debug(DEBUG_EXP, dptr, "mt_startcmd sense %08x return OK chan %04x cmd %02x\n", uptr->SNS, chan, cmd); sim_activate(uptr, 100); /* Start unit off */ - return 0; + return SCPE_OK; /* good to go */ default: /* invalid command */ sim_debug(DEBUG_EXP, dptr, "mt_startcmd CMDREJ return chan %04x cmd %02x\n", @@ -560,18 +578,8 @@ t_stat mt_srv(UNIT *uptr) uint8 ch; // uint8 buf[1024]; - sim_debug(DEBUG_DETAIL, dptr, "mt_srv unit %04x cmd %02x\n", unit, cmd); - if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ - uptr->SNS |= SNS_INTVENT; /* unit intervention required */ - uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ - uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ - mt_busy[bufnum] &= ~1; /* make our buffer not busy */ - if (cmd != MT_SENSE) { /* we are completed with unit check status */ - uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); - return SCPE_OK; - } - } +// sim_debug(DEBUG_DETAIL, dptr, "mt_srv unit %04x cmd %02x\n", unit, cmd); + sim_debug(DEBUG_CMD, dptr, "mt_srv unit %04x cmd %02x\n", unit, cmd); switch (cmd) { case MT_CMDMSK: /* 0x0ff for inch 0x00 */ /* INCH is for channel, nothing for us */ @@ -582,24 +590,13 @@ t_stat mt_srv(UNIT *uptr) mema, chsa, chp->ccw_addr, chp->ccw_count); if (len == 0) { - /* we have invalid count, error, bail out */ - uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ - uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); - break; + /* we have invalid count, error, bail out */ + uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; } -#ifdef DIAG_WANTS_COUNT - for (i=0; i < len; i++) { - if (chan_read_byte(chsa, &buf[i])) { - /* we have error, bail out */ - uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ - uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); - break; - } - /* just dump data */ - } -#endif + /* the chp->ccw_addr location contains the inch address */ /* call set_inch() to setup inch buffer */ i = set_inch(uptr, mema); /* new address */ @@ -609,7 +606,7 @@ t_stat mt_srv(UNIT *uptr) uptr->CMD &= ~(0xffff); /* remove old status bits & cmd */ uptr->SNS |= SNS_CMDREJ|SNS_EQUCHK; chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); - break; + return SCPE_OK; } /* set halfwords 16 & 17 to 5 as default retry count in inch data */ /* UTX uses this value to see if the device is a buffered tape processor */ @@ -622,7 +619,7 @@ t_stat mt_srv(UNIT *uptr) uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ mt_busy[bufnum] &= ~1; /* make our buffer not busy */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ - break; + return SCPE_OK; case 0x80: /* other? */ /* default to NOP */ sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 80 DIAG unit=%04x SNS %08x\n", unit, uptr->SNS); @@ -655,13 +652,13 @@ t_stat mt_srv(UNIT *uptr) sim_debug(DEBUG_CMD, dptr, "mt_srv DIAG SNS %08x char complete unit=%02x\n", uptr->SNS, unit); chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ - break; + return SCPE_OK; case MT_NOP: /* 0x03 */ /* NOP motion command */ uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ mt_busy[bufnum] &= ~1; /* make our buffer not busy */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ - break; + return SCPE_OK; case MT_SENSE: /* 0x04 */ /* get sense data */ /* write requested status */ @@ -677,15 +674,57 @@ t_stat mt_srv(UNIT *uptr) uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ mt_busy[bufnum] &= ~1; /* make our buffer not busy */ uptr->SNS = (uptr->SNS & 0x0000ff00); /* clear all but byte 2 */ - if ((uptr->flags & UNIT_ATT) == 0) /* unit attached status */ + if (!(uptr->flags & UNIT_ATT)) /* unit attached status */ uptr->SNS |= SNS_INTVENT; /* unit intervention required */ else - uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* unit not online or rdy */ sim_debug(DEBUG_CMD, dptr, "mt_srv SENSE %08x char complete unit=%02x\n", uptr->SNS, unit); chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* we are done dev|chan end */ - break; + return SCPE_OK; + case MT_SETM: /* 0x83 */ /* set mode byte */ + sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x83 SETM unit=%02x\n", unit); + /* Grab data until channel has no more */ + if (chan_read_byte(chsa, &ch)) { + if (uptr->POS > 0) { /* Only if data in record */ + reclen = uptr->hwmark; /* set record length */ + ch = mt_buffer[bufnum][0]; /* get the first byte read */ + sim_debug(DEBUG_CMD, dptr, + "Write mode data done unit %02x chars %02x mode %02x\n", unit, reclen, ch); + /* put mode bits into byte 2 of SNS */ + uptr->SNS = (uptr->SNS & 0xffff00ff) | (ch << 8); + uptr->POS = 0; /* no bytes anymore */ + uptr->CMD &= ~MT_CMDMSK; /* no cmd to do */ + mt_busy[bufnum] &= ~1; /* set not busy */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */ + } + } else { + mt_buffer[bufnum][uptr->POS++] = ch; /* save the character read in */ + sim_debug(DEBUG_CMD, dptr, "Write mode data in unit %02x POS %04x mode %02x\n", + unit, uptr->POS, ch); + uptr->hwmark = uptr->POS; /* set high water mark */ + sim_activate(uptr, 40); /* wait time */ + } + return SCPE_OK; + default: + break; + } + + /* only run these commands if we have a tape attached */ + if ((uptr->flags & UNIT_ATT) == 0) { /* unit attached status */ + uptr->SNS |= SNS_INTVENT; /* unit intervention required */ + uptr->SNS &= ~(SNS_RDY|SNS_ONLN); /* unit not online or rdy */ + uptr->SNS &= ~SNS_LOAD; /* reset BOT detected */ + mt_busy[bufnum] &= ~1; /* make our buffer not busy */ + /* we are completed with unit check status */ + uptr->CMD &= ~MT_CMDMSK; /* clear the cmd */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + return SCPE_OK; + } +// uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set ready status */ + + switch (cmd) { case MT_READ: /* 0x02 */ /* read a record from the device */ sim_debug(DEBUG_DETAIL, dptr, "mt_srv cmd 2 READ unit=%02x\n", unit); if (uptr->CMD & MT_READDONE) { /* is the read complete */ @@ -759,31 +798,6 @@ t_stat mt_srv(UNIT *uptr) } break; - case MT_SETM: /* 0x83 */ /* set mode byte */ - sim_debug(DEBUG_CMD, dptr, "mt_srv cmd 0x83 SETM unit=%02x\n", unit); - /* Grab data until channel has no more */ - if (chan_read_byte(chsa, &ch)) { - if (uptr->POS > 0) { /* Only if data in record */ - reclen = uptr->hwmark; /* set record length */ - ch = mt_buffer[bufnum][0]; /* get the first byte read */ - sim_debug(DEBUG_CMD, dptr, - "Write mode data done unit %02x chars %02x mode %02x\n", unit, reclen, ch); - /* put mode bits into byte 2 of SNS */ - uptr->SNS = (uptr->SNS & 0xffff00ff) | (ch << 8); - uptr->POS = 0; /* no bytes anymore */ - uptr->CMD &= ~MT_CMDMSK; /* no cmd to do */ - mt_busy[bufnum] &= ~1; /* set not busy */ - chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return end status */ - } - } else { - mt_buffer[bufnum][uptr->POS++] = ch; /* save the character read in */ - sim_debug(DEBUG_CMD, dptr, "Write mode data in unit %02x POS %04x mode %02x\n", - unit, uptr->POS, ch); - uptr->hwmark = uptr->POS; /* set high water mark */ - sim_activate(uptr, 40); /* wait time */ - } - break; - case MT_WRITE: /* 0x01 */ /* write record */ /* Check if write protected */ if (sim_tape_wrp(uptr)) { @@ -1150,7 +1164,7 @@ void mt_ini(UNIT *uptr, t_bool f) uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ uptr->SNS = 0; /* clear sense data */ - uptr->SNS |= (SNS_RDY|SNS_ONLN|SNS_LOAD); /* set initial status */ + uptr->SNS |= (SNS_RDY|SNS_ONLN); /* set initial status */ mt_busy[GET_DEV_BUF(dptr->flags)] = 0; /* set not busy */ sim_cancel(uptr); /* cancel any timers */ sim_debug(DEBUG_EXP, dptr, "MT init device %s unit %02x\n", @@ -1185,9 +1199,17 @@ t_stat mt_attach(UNIT *uptr, CONST char *file) t_stat r; DIB *dibp = 0; + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, "ERROR===ERROR\nMT device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nMT device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + /* mount the specified file to the MT */ if ((r = sim_tape_attach(uptr, file)) != SCPE_OK) { - sim_debug(DEBUG_EXP, dptr, "mt_attach ERROR filename %s status %08x\n", file, r); + fprintf(sim_deb, "mt_attach ERROR filename %s status %08x\r\n", file, r); return r; /* report any error */ } sim_debug(DEBUG_EXP, dptr, "mt_attach complete filename %s\n", file); @@ -1203,7 +1225,9 @@ t_stat mt_attach(UNIT *uptr, CONST char *file) sim_debug(DEBUG_CMD, dptr, "ERROR===ERROR\nMT device %s not configured on system, aborting\n", dptr->name); - printf("ERROR===ERROR\nMT device %s not configured on system, aborting\n", + printf("ERROR===ERROR\nMT device %s not configured on system, aborting\r\n", + dptr->name); + fprintf(sim_deb, "ERROR===ERROR\nMT device %s not configured on system, aborting\r\n", dptr->name); detach_unit(uptr); /* detach if error */ return SCPE_UNATT; /* error */ @@ -1220,6 +1244,8 @@ t_stat mt_detach(UNIT *uptr) uptr->CMD &= ~0xffff; /* clear out the flags but leave ch/sa */ uptr->POS = 0; /* clear position data */ uptr->SNS = 0; /* clear sense data */ + uptr->flags &= ~MTUF_WRP; /* clear write protect */ + uptr->flags &= ~UNIT_RO; /* clear read only */ return sim_tape_detach(uptr); } @@ -1228,10 +1254,18 @@ t_stat mt_boot(int32 unit_num, DEVICE *dptr) { UNIT *uptr = &dptr->units[unit_num]; /* find tape unit pointer */ + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nMT device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } sim_debug(DEBUG_EXP, dptr, "MT Boot dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("MT Boot dev/unit %04x\r\n", GET_UADDR(uptr->CMD)); if ((uptr->flags & UNIT_ATT) == 0) { /* Is MT device already attached? */ sim_debug(DEBUG_EXP, dptr, "MT Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("MT Boot attach error dev/unit %04x\r\n", GET_UADDR(uptr->CMD)); return SCPE_UNATT; /* not attached, return error */ } SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ diff --git a/SEL32/sel32_scfi.c b/SEL32/sel32_scfi.c index 748615d..4e34d9a 100644 --- a/SEL32/sel32_scfi.c +++ b/SEL32/sel32_scfi.c @@ -640,6 +640,9 @@ loop: sim_debug(DEBUG_EXP, dptr, "scfi_iocl continue wait chsa %04x status %08x\n", chp->chan_dev, chp->chan_status); +#ifndef CHANGE_03072021 + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ +#endif } } else @@ -1528,6 +1531,7 @@ int scfi_format(UNIT *uptr) { uint32 cylv = cyl; /* number of cylinders */ uint8 *buff; int32 i; + t_stat oldsw = sim_switches; /* save switches */ /* last sector address of disk (cyl * hds * spt) - 1 */ uint32 laddr = CAP(type) - 1; /* last sector of disk */ @@ -1537,9 +1541,16 @@ int scfi_format(UNIT *uptr) { 0x9a000000 | (cap-1), 0xf4000000}; - /* see if user wants to initialize the disk */ - if (!get_yn("Initialize disk? [Y] ", TRUE)) { - return 1; + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { +// printf("disk_format init question is false\r\n"); + sim_switches = oldsw; + return 1; + } + sim_switches = oldsw; /* restore switches */ } /* seek to sector 0 */ @@ -1641,6 +1652,15 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) return SCPE_FMT; /* error */ } + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nSCFI Disk device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nSCFI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + /* have simulator attach the file to the unit */ if ((r = attach_unit(uptr, file)) != SCPE_OK) return r; @@ -1658,6 +1678,11 @@ t_stat scfi_attach(UNIT *uptr, CONST char *file) scfi_type[type].name, scfi_type[type].cyl, scfi_type[type].nhds, scfi_type[type].spt, ssize, uptr->capac); /* disk capacity */ + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + /* seek to end of disk */ if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { sim_debug(DEBUG_CMD, dptr, "SCFI Disk attach SEEK end failed\n"); @@ -1824,10 +1849,18 @@ t_stat scfi_boot(int32 unit_num, DEVICE *dptr) { sim_debug(DEBUG_CMD, dptr, "SCFI Disk Boot dev/unit %x\n", GET_UADDR(uptr->CMD)); + + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nSCFI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + if ((uptr->flags & UNIT_ATT) == 0) { sim_debug(DEBUG_EXP, dptr, - "SCFI Disk Boot attach error dev/unit %04x\n", - GET_UADDR(uptr->CMD)); + "SCFI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("SCFI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); return SCPE_UNATT; /* attached? */ } SPAD[0xf4] = GET_UADDR(uptr->CMD); /* put boot device chan/sa into spad */ diff --git a/SEL32/sel32_scsi.c b/SEL32/sel32_scsi.c index 050ac95..c8791fc 100644 --- a/SEL32/sel32_scsi.c +++ b/SEL32/sel32_scsi.c @@ -1355,6 +1355,7 @@ int scsi_format(UNIT *uptr) { uint32 cylv = cyl; /* number of cylinders */ uint8 *buff; int i; + t_stat oldsw = sim_switches; /* save switches */ /* last sector address of disk (cyl * hds * spt) - 1 */ uint32 laddr = CAP(type) - 1; /* last sector of disk */ @@ -1403,6 +1404,18 @@ int scsi_format(UNIT *uptr) { uint32 fmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, 0x9a000000 | ltaddr, 0xf4000000}; + /* see if -i or -n specified on attach command */ + if (!(sim_switches & SWMASK('N')) && !(sim_switches & SWMASK('I'))) { + sim_switches = 0; /* simh tests 'N' & 'Y' switches */ + /* see if user wants to initialize the disk */ + if (!get_yn("Initialize disk? [Y] ", TRUE)) { +// printf("disk_format init question is false\r\n"); + sim_switches = oldsw; + return 1; + } + sim_switches = oldsw; /* restore switches */ + } + /* see if user wants to initialize the disk */ if (!get_yn("Initialize disk? [Y] ", TRUE)) { return 1; @@ -1587,6 +1600,15 @@ t_stat scsi_attach(UNIT *uptr, CONST char *file) { return SCPE_FMT; /* error */ } + if (dptr->flags & DEV_DIS) { + fprintf(sim_deb, + "ERROR===ERROR\nSCSI Disk device %s disabled on system, aborting\r\n", + dptr->name); + printf("ERROR===ERROR\nSCSI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + /* have simulator attach the file to the unit */ if ((r = attach_unit(uptr, file)) != SCPE_OK) return r; @@ -1603,6 +1625,11 @@ t_stat scsi_attach(UNIT *uptr, CONST char *file) { scsi_type[type].name, chsa, scsi_type[type].cyl, scsi_type[type].nhds, scsi_type[type].spt, ssize, uptr->capac); /* disk capacity */ + /* see if -i or -n specified on attach command */ + if ((sim_switches & SWMASK('N')) || (sim_switches & SWMASK('I'))) { + goto fmt; /* user wants new disk */ + } + /* seek to end of disk */ if ((sim_fseek(uptr->fileref, 0, SEEK_END)) != 0) { sim_debug(DEBUG_CMD, dptr, "SCSI Disk attach SEEK end failed\n"); @@ -1766,9 +1793,17 @@ t_stat scsi_boot(int32 unit_num, DEVICE *dptr) { sim_debug(DEBUG_CMD, dptr, "SCSI Disk Boot dev/unit %04x\n", GET_UADDR(uptr->CMD)); + /* see if device disabled */ + if (dptr->flags & DEV_DIS) { + printf("ERROR===ERROR\r\nSCSI Disk device %s disabled on system, aborting\r\n", + dptr->name); + return SCPE_UDIS; /* device disabled */ + } + if ((uptr->flags & UNIT_ATT) == 0) { sim_debug(DEBUG_EXP, dptr, "SCSI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); + printf("SCSI Disk Boot attach error dev/unit %04x\n", GET_UADDR(uptr->CMD)); return SCPE_UNATT; /* attached? */ } diff --git a/SEL32/taptools/mkvmtape.c b/SEL32/taptools/mkvmtape.c index 7914730..4c7b929 100644 --- a/SEL32/taptools/mkvmtape.c +++ b/SEL32/taptools/mkvmtape.c @@ -193,8 +193,10 @@ char *argv[]; int32_t filen; /* file number */ // u_int32_t *dirp = dir; /* directory entry pointer */ // u_int32_t *volp = vol; /* volume entry pointer */ - char *dirp = dirname; /* directory entry pointer */ - char *volp = volname; /* volume entry pointer */ +/// char *dirp = dirname; /* directory entry pointer */ +/// char *volp = volname; /* volume entry pointer */ + char *dirp = sysname; /* directory entry pointer */ + char *volp = sysname; /* volume entry pointer */ int32_t totent; /* total smd entries */ char j_vfmt[] = {"!VOLSYST!DIRSYST!FIL J.VFMT "}; char j_mount[] = {"!VOLSYST!DIRSYST!FIL J.MOUNT "}; @@ -747,14 +749,17 @@ printf("image file %s n1 %x (%d) n2 %x (%d) blks %x (%d)\n", resdes[13]= dirlist[n+11]; /* 16 word resource create block */ resdes[14] = dirlist[n+8]; /* owner, system */ - resdes[15] = dirlist[n+9]; - resdes[16]= dirlist[n+10]; - resdes[17]= dirlist[n+11]; - resdes[18] = dirlist[n+8]; /* group, system */ - resdes[19] = dirlist[n+9]; - resdes[20]= dirlist[n+10]; - resdes[21]= dirlist[n+11]; + resdes[15] = dirlist[n+9]; /* only 8 bytes */ +// resdes[16]= dirlist[n+10]; +// resdes[17]= dirlist[n+11]; +/// resdes[18] = dirlist[n+8]; /* group, system */ +/// resdes[19] = dirlist[n+9]; /* only 8 bytes */ + resdes[16] = dirlist[n+8]; /* group, system */ + resdes[17] = dirlist[n+9]; /* only 8 bytes */ +// resdes[20]= dirlist[n+10]; +// resdes[21]= dirlist[n+11]; n += 12; +#ifdef OLDOLD resdes[22]=flip(0x80f00000); /* owner rights */ resdes[23]=flip(0x80b00000); /* group rights */ resdes[24]=flip(0x80800000); /* other rights */ @@ -766,6 +771,19 @@ printf("image file %s n1 %x (%d) n2 %x (%d) blks %x (%d)\n", resdes[29]=flip(size); /* org file size */ resdes[31]=flip(1000); /* file starting address n/u */ resdes[33]=flip(0x00fbfeef); /* option flags */ +#else + resdes[18]=flip(0x80f00000); /* owner rights */ + resdes[19]=flip(0x80b00000); /* group rights */ + resdes[20]=flip(0x80800000); /* other rights */ + if (typ == 0xca) + resdes[21]=flip(0x00040110); /* res mgmt flags */ + else + resdes[21]=flip(0x00040110); /* res mgmt flags */ +// resdes[21]=flip(0x0004011c); /* res mgmt flags */ + resdes[25]=flip(size); /* org file size */ + resdes[27]=flip(1000); /* file starting address n/u */ + resdes[29]=flip(0x00fbfeef); /* option flags */ +#endif /* reset of block is zero */ /* second block is resosurce descriptor from disk */ @@ -794,8 +812,8 @@ printf("image file %s n1 %x (%d) n2 %x (%d) blks %x (%d)\n", //210 //211 - resdes[212] = dirlist[n+8]; /* ownername last changer, system */ - resdes[213] = dirlist[n+9]; +/// resdes[212] = dirlist[n+8]; /* ownername last changer, system */ +/// resdes[213] = dirlist[n+9]; resdes[214] = dirlist[n+8]; /* ownername creator, system */ resdes[215] = dirlist[n+9]; @@ -826,14 +844,18 @@ printf("image file %s n1 %x (%d) n2 %x (%d) blks %x (%d)\n", else if (typ == 0x00) resdes[256]=flip(0x001000f1); /* space definition flags */ - resdes[257]=flip(0x00000018); /* max extends */ - resdes[258]=flip(0x00000008); /* min incr */ +// resdes[257]=flip(0x00000018); /* max extends */ + resdes[257]=flip(0x00000040); /* max extends */ +// resdes[258]=flip(0x00000008); /* min incr */ + resdes[258]=flip(0x00000010); /* min incr */ //259 // resdes[260]=flip(size-1); /* eof */ // resdes[261]=flip(size); /* eom */ - resdes[260]=flip(size); /* eof */ - resdes[261]=flip(size+1); /* eom */ +/// resdes[260]=flip(size); /* eof */ +/// resdes[261]=flip(size+1); /* eom */ + resdes[260]=0; /* eof */ + resdes[261]=flip(size); /* eom */ resdes[262]=flip(0x00000001); /* segment */ //263 diff --git a/doc/sel32_doc.doc b/doc/sel32_doc.doc index de34883324b06544c1abece085999b7c089163b4..1d195b653ccc89521129dd0ce6d668a3ba8b41e9 100644 GIT binary patch delta 27963 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ⅇH0evvl~(5G_{_U4O`R;Q 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