diff --git a/SEL32/sel32_chan.c b/SEL32/sel32_chan.c index 833d3f9..38762ce 100644 --- a/SEL32/sel32_chan.c +++ b/SEL32/sel32_chan.c @@ -1,4 +1,3 @@ -/* sel32_chan.c: SEL 32 Channel functions. Copyright (c) 2018-2021, James C. Bevier Portions provided by Richard Cornwell, Geert Rolf and other SIMH contributers @@ -86,9 +85,6 @@ 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; @@ -123,6 +119,7 @@ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc); t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc); DEVICE *get_dev(UNIT *uptr); void store_csw(CHANP *chp); +void push_csw(CHANP *chp); int16 post_csw(CHANP *chp, uint32 rstat); /* FIFO support */ @@ -140,6 +137,32 @@ int16 post_csw(CHANP *chp, uint32 rstat); /* initialize FIFO to empty in boot channel code */ +/* add an entry to the start of the FIFO */ +int32 FIFO_Push(uint16 chsa, uint32 entry) +{ + int32 num; /* number of entries */ + DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + if (dibp == NULL) { + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Push ERR NULL dib ptr for chsa %04x\n", chsa); + return -1; /* FIFO address error */ + } + + if (dibp->chan_fifo_in == ((dibp->chan_fifo_out-1+FIFO_SIZE) % FIFO_SIZE)) { + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Push ERR FIFO full for chsa %04x count %02x\n", chsa, num); + return -1; /* FIFO Full */ + } + dibp->chan_fifo_out += (FIFO_SIZE - 1); /* get index to previous first entry */ + dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */ + dibp->chan_fifo[dibp->chan_fifo_out] = entry; /* add new entry to be new first */ + num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; + sim_debug(DEBUG_EXP, &cpu_dev, + "FIFO_Push to FIFO for chsa %04x count %02x\n", chsa, num); + return SCPE_OK; /* all OK */ +} + /* add an entry to the FIFO */ int32 FIFO_Put(uint16 chsa, uint32 entry) { @@ -213,11 +236,6 @@ 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 */ } @@ -368,7 +386,6 @@ uint32 find_int_lev(uint16 chsa) uint32 find_int_icb(uint16 chsa) { uint32 inta, icba; - uint32 spadent = SPAD[get_chan(chsa)]; /* get spad device entry for logical channel */ inta = find_int_lev(chsa); /* find the int level */ if (inta == 0) { @@ -471,7 +488,8 @@ int readfull(CHANP *chp, uint32 maddr, uint32 *word) return 1; /* show we have error */ } *word = RMW(maddr); /* get 1 word */ - sim_debug(DEBUG_XIO, &cpu_dev, "READFULL read %08x from addr %08x\n", *word, maddr); + sim_debug(DEBUG_XIO, &cpu_dev, "READFULL chsa %04x read %08x from addr %08x\n", + chp->chan_dev, *word, maddr); return 0; /* return OK */ } @@ -733,9 +751,7 @@ 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); @@ -766,7 +782,6 @@ loop: /* write to device */ int chan_read_byte(uint16 chsa, uint8 *data) { - int chan = get_chan(chsa); /* get the channel number */ CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ int byte; @@ -888,7 +903,7 @@ int chan_write_byte(uint16 chsa, uint8 *data) chp->ccw_addr--; /* backward */ else chp->ccw_addr++; /* forward */ - sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_write_byte SKIP ret addr %08x cnt %04x\n", + sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte SKIP ret addr %08x cnt %04x\n", chp->ccw_addr, chp->ccw_count); return 0; } @@ -1022,13 +1037,12 @@ 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; } else { + /* we have channel end and no CC flag, continue channel prog */ UNIT *uptr = chp->unitptr; /* get the unit ptr */ DEVICE *dptr = get_dev(uptr); uint16 chsa = GET_UADDR(uptr->u3); @@ -1081,7 +1095,7 @@ void chan_end(uint16 chsa, uint16 flags) { chp->ccw_flags = 0; /* clear flags */ /* set status words in memory to first IOCD information */ - sim_debug(DEBUG_DETAIL, &cpu_dev, + sim_debug(DEBUG_CMD, &cpu_dev, "$$ CHEND start IOCL processing from IOCLQ num %02x chsa %04x iocla %06x\n", IOCLQ_Num(qp), chsa, iocla); @@ -1089,27 +1103,21 @@ void chan_end(uint16 chsa, uint16 flags) { /* Queue us to continue IOCL from cpu level & make busy */ chp->chan_byte = BUFF_NEXT; /* have main pick us up */ chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ - sim_debug(DEBUG_DETAIL, &cpu_dev, + sim_debug(DEBUG_CMD, &cpu_dev, "chan_end BUFF_NEXT chsa %04x from IOCLQ cnt %02x chp %p chan_byte %04x\n", chsa, IOCLQ_Num(qp), chp, chp->chan_byte); RDYQ_Put(chsa); /* queue us up */ - sim_debug(DEBUG_DETAIL, &cpu_dev, - "$$$ CHEND SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", + sim_debug(DEBUG_CMD, &cpu_dev, + "$$$ CHEND SIOQ 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 } } } goout: - sim_debug(DEBUG_DETAIL, &cpu_dev, + sim_debug(DEBUG_CMD, &cpu_dev, "chan_end done chsa %04x chp %p status %08x chan_byte %02x\n", chsa, chp, chp->chan_status, chp->chan_byte); /* following statement required for boot to work */ @@ -1178,7 +1186,7 @@ void store_csw(CHANP *chp) sim_debug(DEBUG_EXP, &cpu_dev, "store_csw FIFO Overflow ERROR on chsa %04x\n", chsa); } - sim_debug(DEBUG_DETAIL, &cpu_dev, + sim_debug(DEBUG_XIO, &cpu_dev, "store_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x cmd %02x\n", FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr, chp->ccw_cmd); /* added 011321 */ @@ -1186,6 +1194,31 @@ void store_csw(CHANP *chp) irq_pend = 1; /* wakeup controller */ } +/* store the device status into the first entry of the status FIFO for the channel */ +void push_csw(CHANP *chp) +{ + uint32 stwd1, stwd2; /* words 1&2 of stored status */ + uint32 chsa = chp->chan_dev; /* get ch/sa information */ + + /* put sub address in byte 0 */ + stwd1 = ((chsa & 0xff) << 24) | chp->chan_caw; /* subaddress and IOCD address to SW 1 */ + + /* save 16 bit channel status and residual byte count in SW 2 */ + stwd2 = ((uint32)chp->chan_status << 16) | ((uint32)chp->ccw_count); + + /* Push in reverse order to allign status correctly */ + if ((FIFO_Push(chsa, stwd2) == -1) || (FIFO_Push(chsa, stwd1) == -1)) { + sim_debug(DEBUG_EXP, &cpu_dev, + "push_csw FIFO Overflow ERROR on chsa %04x\n", chsa); + } + sim_debug(DEBUG_XIO, &cpu_dev, + "push_csw FIFO #%1x write chsa %04x sw1 %08x sw2 %08x incha %08x cmd %02x\n", + FIFO_Num(chsa), chsa, stwd1, stwd2, chp->chan_inch_addr, chp->ccw_cmd); + /* added 011321 */ + INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */ + irq_pend = 1; /* wakeup controller */ +} + /* check an XIO operation */ /* logical chan channel number 0-7f */ /* suba unit address within channel 0-ff */ @@ -1233,12 +1266,12 @@ nothere: *status = CC1BIT; /* CCs = 1, not busy */ sim_debug(DEBUG_EXP, &cpu_dev, "checkxio rchsa %04x device/unit not enabled, CC1 returned\n", - lchsa, rchsa); + rchsa); } else { *status = CC3BIT; /* not attached, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "checkxio rchsa %04x device/unit not enabled, CC3 returned\n", - lchsa, rchsa); + rchsa); } return SCPE_OK; /* Not found CC3/CC1 */ } @@ -1292,6 +1325,7 @@ t_stat startxio(uint16 lchsa, uint32 *status) { uint16 chsa; uint32 tempa, inta, spadent, chan, incha; uint32 word1, word2, cmd; +#define DEBUG_DISK #ifdef DEBUG_DISK uint32 itva; #endif @@ -1326,12 +1360,12 @@ t_stat startxio(uint16 lchsa, uint32 *status) { itva, chan_icb, iocla, incha, RMW(iocla), RMW(iocla+4)); #endif /* check if we have a valid unit */ - dibp = dib_chan[chan]; /* get DIB pointer for channel */ - if (dibp == 0) goto missing; - chp = find_chanp_ptr(chsa); /* find the chanp pointer */ if (chp == 0) goto missing; + dibp = dib_unit[chsa]; /* get the DIB pointer */ + if (dibp == 0) goto missing; + uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ @@ -1359,7 +1393,7 @@ missing: return SCPE_OK; /* not found, CC3 */ } -#ifdef FOR_DEBUG +#ifndef FOR_DEBUG if ((INTS[inta]&INTS_ACT) || (SPAD[inta+0x80]&SINT_ACT)) { /* look for level active */ /* just output a warning */ sim_debug(DEBUG_XIO, &cpu_dev, @@ -1368,6 +1402,41 @@ missing: } #endif +#ifndef USE_TIO_CODE_03112021 + /* channel not busy and ready to go, check for any status ready */ + /* see if any status ready to post */ + if (FIFO_Num(chsa&0x7f00)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, chp->chan_inch_addr, chp, chan_icb, chp->chan_byte); + if (post_csw(chp, 0)) { + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, chp->chan_inch_addr, RMW(chan_icb+20), chp->chan_byte); + /* change status from BUFF_POST to BUFF_DONE */ + /* if not BUFF_POST we have a PPCI or channel busy interrupt */ + /* so leave the channel status alone */ + if (chp->chan_byte == BUFF_POST) { + chp->chan_byte = BUFF_DONE; /* show done & not busy */ + } + sim_debug(DEBUG_XIO, &cpu_dev, + "SIOT END status stored incha %06x chan_icba+20 %08x chsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), chsa, RMW(incha), RMW(incha+4)); + INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ + return SCPE_OK; /* No CC's all OK */ + } else { + sim_debug(DEBUG_IRQ, &cpu_dev, + "SIOT chsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", + chsa, FIFO_Num(chsa), inta, chp->chan_inch_addr, chan_icb, chp->chan_byte); + /* now store the status dw address into word 5 of the ICB for the channel */ + WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = 0; /* no status stored from SIO, so no CC */ + return SCPE_OK; /* No CC's all OK */ + } + } +#endif +#ifndef TRY_03132021 /* check for a Command or data chain operation in progresss */ if ((chp->chan_byte & BUFF_BUSY) && (chp->chan_byte != BUFF_POST)) { uint16 tstat = chp->chan_status; /* save status */ @@ -1377,6 +1446,7 @@ missing: sim_debug(DEBUG_EXP, &cpu_dev, "startxio busy return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n", chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); +#ifndef DISABLE_03112021_03132021 /* ethernet controller wants an interrupt for busy status */ if ((dptr != NULL) && (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ @@ -1384,7 +1454,8 @@ missing: /* handle an Ethernet controller busy by sending interrupt/status */ chp->chan_status = STATUS_BUSY|STATUS_CEND|STATUS_DEND; /* set busy status */ chp->ccw_count = 0; /* zero count */ - store_csw(chp); /* store the status */ +//0312 store_csw(chp); /* store the status */ + push_csw(chp); /* store the status */ chp->chan_status = tstat; /* restore status */ chp->ccw_count = tcnt; /* restore count */ sim_debug(DEBUG_XIO, &cpu_dev, @@ -1392,7 +1463,20 @@ missing: chp, chsa, chp->ccw_flags, tstat, tcnt); return SCPE_OK; /* just busy CC3&CC4 */ } +#endif +#ifndef ADD_03112021 + sim_debug(DEBUG_EXP, &cpu_dev, + "startxio busy2 return CC3&CC4 chsa %04x chp %p cmd %02x flags %04x byte %02x\n", + chsa, chp, chp->ccw_cmd, chp->ccw_flags, chp->chan_byte); + /* everyone else just gets a busy return */ + *status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */ + sim_debug(DEBUG_XIO, &cpu_dev, + "startxio done2 BUSY chp %p chsa %04x ccw_flags %04x stat %04x cnt %04x\n", + chp, chsa, chp->ccw_flags, tstat, tcnt); + return SCPE_OK; /* just busy CC3&CC4 */ +#endif } +#endif /*TRY_03132021*/ sim_debug(DEBUG_XIO, &cpu_dev, "startxio int spad %08x icb %06x inta %02x chan %04x\n", @@ -1504,18 +1588,10 @@ 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 = QWAIT10; /* run 25 instructions before starting iocl */ 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", @@ -1545,12 +1621,6 @@ 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, @@ -1575,8 +1645,8 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ itva = SPAD[0xf1] + (inta<<2); /* int vector address */ chan_icb = RMW(itva); /* Interrupt context block addr */ sim_debug(DEBUG_XIO, &cpu_dev, - "TIO int spad %08x icb %06x inta %04x rchan %04x\n", - SPAD[inta+0x80], chan_icb, inta, rchan); + "TIO int spad %08x icb %06x inta %04x rchsa %04x\n", + SPAD[inta+0x80], chan_icb, inta, rchsa); incha = chp->chan_inch_addr; /* get inch address */ @@ -1596,8 +1666,8 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ chp->chan_byte = BUFF_DONE; /* show done & not busy */ } sim_debug(DEBUG_XIO, &cpu_dev, - "TIO END status stored incha %06x rchsa %04x sw1 %08x sw2 %08x\n", - incha, rchsa, RMW(incha), RMW(incha+4)); + "TIO END status stored incha %06x chan_icba+20 %08x rchsa %04x sw1 %08x sw2 %08x\n", + incha, RMW(chan_icb+20), rchsa, RMW(incha), RMW(incha+4)); INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ *status = CC2BIT; /* status stored from SIO, so CC2 */ return SCPE_OK; /* No CC's all OK */ @@ -1885,8 +1955,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ /* call the device controller to get halt_io status */ tempa = dibp->halt_io(uptr); /* get status from device */ - /* test for SCPE_IOERR */ - if (tempa != 0) { /* sub channel has status ready */ + /* test for SCPE_IOERR (=2) SCPE_OK (=0)*/ + if (tempa != SCPE_OK) { /* sub channel has status ready */ /* The device I/O has been terminated and status stored. */ sim_debug(DEBUG_EXP, &cpu_dev, "HIO halt_io call return ERROR FIFO #%1x rchsa %04x retstat %08x cstat %08x\n", @@ -1894,36 +1964,12 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ /* chan_end is called in hio device service routine */ /* the device is no longer busy, post status */ - /* remove PPCI status. Unit check should not be set */ - if (tempa == 1) { /* see if console HIO */ - chp->ccw_count = 0; /* zero the count */ - /* 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 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_DONE1a chp %p chan_byte %04x\n", chp, chp->chan_byte); - } - return SCPE_OK; /* CC2 & all OK */ - } - } -#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_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 diags want the interrupt for the disk */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "$$$ HIO END2X 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 */ } /* see if waiting to start */ if (chp->chan_byte == BUFF_NEXT) { @@ -1946,44 +1992,11 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ "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_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 */ + *status = CC1BIT; /* request accepted, post good 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); @@ -1992,7 +2005,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ sim_debug(DEBUG_EXP, &cpu_dev, "haltxio BUFF_DONE2 chp %p chan_byte %04x\n", chp, chp->chan_byte); chp->chan_status = (STATUS_DEND|STATUS_CEND); - store_csw(chp); /* store the status */ +// store_csw(chp); /* store the status */ + push_csw(chp); /* store the status 1st in FIFO */ /* change chan_byte to BUFF_POST */ chp->chan_byte = BUFF_POST; /* show done with data */ chp->chan_status = 0; /* no status anymore */ @@ -2034,7 +2048,8 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ chp->chan_byte = BUFF_BUSY; /* wait for post_csw to be done */ sim_cancel(uptr); /* cancel timer service */ chp->chan_status &= ~STATUS_BUSY; /* remove BUSY status bit */ - chan_end(rchsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ +// chan_end(rchsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ + chan_end(rchsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* show I/O complete */ /* post the channel status */ chp->ccw_count = 0; /* zero the count */ @@ -2381,7 +2396,6 @@ uint32 scan_chan(uint32 *ilev) { chp = find_chanp_ptr(chan); /* find the chanp pointer for channel */ /* this address most likely will be zero here */ tempa = chp->chan_inch_addr; /* get inch status buffer address */ -#if 1 /* before overwriting memory loc 0+4, save PSD for caller in TPSD[] locations */ TPSD[0] = M[0]; /* save PSD from loc 0&4 */ TPSD[1] = M[1]; @@ -2390,7 +2404,6 @@ uint32 scan_chan(uint32 *ilev) { /* set BIT 1 to show status stored */ WMW(tempa, sw1|BIT1); /* save sa & IOCD address in status WD 1 loc */ WMW(tempa+4, sw2); /* save status and residual cnt in status WD 2 loc */ -#endif chp->chan_byte = BUFF_DONE; /* we are done */ sim_debug(DEBUG_IRQ, &cpu_dev, "LOADING %06x %04x FIFO #%1x read inch %06x sw1 %08x sw2 %08x\n", @@ -2400,14 +2413,6 @@ 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++) { if (SPAD[i+0x80] == 0) /* not initialize? */ @@ -2437,23 +2442,12 @@ 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? */ - sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan waitqcnt %02x\n", waitqcnt); - if (CPUSTATUS & BIT24) /* interrupts blocked? */ - 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++) { @@ -2517,15 +2511,15 @@ uint32 scan_chan(uint32 *ilev) { "scan_chan %04x LOOK FIFO #%1x irq %02x inch %06x chp %p icba %06x chan_byte %02x\n", chsa, FIFO_Num(chan), i, chp->chan_inch_addr, chp, chan_icba, chp->chan_byte); if (post_csw(chp, 0)) { - sim_debug(DEBUG_IRQ, &cpu_dev, - "scan_chanx %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", - chan, FIFO_Num(chan), i, chp->chan_inch_addr, RMW(chan_icba+20), chp->chan_byte); /* change status from BUFF_POST to BUFF_DONE */ /* if not BUFF_POST we have a PPCI or channel busy interrupt */ /* so leave the channel status alone */ if (chp->chan_byte == BUFF_POST) { chp->chan_byte = BUFF_DONE; /* show done & not busy */ } + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chanx %04x POST FIFO #%1x irq %02x inch %06x chan_icba+20 %08x chan_byte %02x\n", + chan, FIFO_Num(chan), i, chp->chan_inch_addr, RMW(chan_icba+20), chp->chan_byte); } else { sim_debug(DEBUG_IRQ, &cpu_dev, "scan_chanx %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", diff --git a/SEL32/sel32_con.c b/SEL32/sel32_con.c index e3ee7fc..e079fac 100644 --- a/SEL32/sel32_con.c +++ b/SEL32/sel32_con.c @@ -141,6 +141,7 @@ DIB con_dib = { DEVICE con_dev = { "CON", con_unit, NULL, con_mod, NUM_UNITS_CON, 8, 15, 1, 8, 8, +// NULL, NULL, &con_reset, NULL, &con_attach, &con_detach, NULL, NULL, &con_reset, NULL, NULL, NULL, &con_dib, DEV_DIS|DEV_DISABLE|DEV_DEBUG, 0, dev_debug }; @@ -647,11 +648,13 @@ uint16 con_haltio(UNIT *uptr) { chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ uptr->CMD &= LMASK; /* make non-busy */ uptr->u4 = 0; /* no I/O yet */ + sim_cancel(uptr); /* stop timer */ con_data[unit].incnt = 0; /* no input data */ uptr->SNS = SNS_RDY|SNS_ONLN; /* status is online & ready */ sim_debug(DEBUG_CMD, &con_dev, "con_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ +//BAD chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */ return 1; /* tell chan code to post status */ } uptr->u4 = 0; /* no I/O yet */ diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index bfe6611..c609c74 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -158,9 +158,6 @@ 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 { @@ -1945,11 +1942,6 @@ 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, @@ -2075,69 +2067,53 @@ wait_loop: } } -#ifndef CHANGE_03072021 + /* process IOCL entries that are waiting */ /* loop through the IOCL ready Q and decrement wait counts */ if ((int32c = RDYQ_Num())) { int32 i, rqo = RDYQOUT; for (i=0; ichan_byte != BUFF_NEXT) { + /* if not BUFF_NEXT, channel has been stopped, do nothing */ + sim_debug(DEBUG_XIO, &cpu_dev, + "scan_chan Bad CPU RDYQ entry for chsa %04x chan_byte %02x\n", + chsa, chp->chan_byte); + /* not BUFF_NEXT, just zero entry */ + continue; /* ignore the entry */ + } + /* state is BUFF_NEXT, see if wait is over */ if (chp->chan_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 */ + /* process 0 wait entry */ + if (chp->chan_qwait == 0) { 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); - /* 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); - } - } + /* if not BUFF_NEXT, channel has been stopped, do nothing */ + 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); + continue; + } else + RDYQ_Put(chsa); /* requeue the non-zero entry */ + rqo++; /* next queue entry */ + rqo %= RDYQ_SIZE; /* don't overrun end */ } } @@ -5854,11 +5830,12 @@ doovr2: dest = (D32RMASK & dest); /* zero fill */ if (td == 0) CC |= CC4BIT; /* word is zero, so CC4 */ - else + else { if (td & 0x80000000) CC |= CC3BIT; /* it is neg wd, so CC3 */ else CC |= CC2BIT; /* then td > 0, so CC2 */ + } break; case 2: /* 64 bit double */ /* ARMD */ @@ -5873,12 +5850,13 @@ doovr2: ovr = 1; if (td == 0) CC |= CC4BIT; /* dw is zero, so CC4 */ - else + else { if (td & DMSIGN) CC |= CC3BIT; /* it is neg dw, so CC3 */ else CC |= CC2BIT; /* then td > 0, so CC2 */ - break; + } + break; } if (ovr) CC |= CC1BIT; /* set overflow CC */ @@ -6502,10 +6480,10 @@ sim_debug(DEBUG_IRQ, &cpu_dev, /* SPAD address F1 has interrupt table address */ temp = SPAD[0xf1] + (ix<<2); /* vector address in SPAD */ sim_debug(DEBUG_XIO, &cpu_dev, - "$$ XIO lchan %02x sa %02x spad %08x BLK %1x INTS[%02x] %08x\n", - lchan, suba, t, CPUSTATUS&0x80?1:0, ix, INTS[ix]); + "$$ XIO chsa %04x spad %08x BLK %1x INTS[%02x] %08x\n", + rchsa, t, CPUSTATUS&0x80?1:0, ix, INTS[ix]); sim_debug(DEBUG_XIO, &cpu_dev, - "$$ XIO rchsa %04x PSD1 %08x PSD2 %08x IR %08x ICBA %06x\n", + "$$ XIO chsa %04x PSD1 %08x PSD2 %08x IR %08x ICBA %06x\n", rchsa, PSD1, PSD2, IR, temp); if ((TRAPME = Mem_read(temp, &addr))) { /* get interrupt context block addr */ mcheck: diff --git a/SEL32/sel32_disk.c b/SEL32/sel32_disk.c index 3feb017..bea1ea2 100644 --- a/SEL32/sel32_disk.c +++ b/SEL32/sel32_disk.c @@ -1089,7 +1089,6 @@ uint16 disk_haltio(UNIT *uptr) { /* status must not have an error bit set */ /* otherwise, UTX will panic with "bad status" */ if ((uptr->CMD & DSK_CMDMSK) != 0) { /* is unit busy */ -// sim_debug(DEBUG_CMD, dptr, sim_debug(DEBUG_EXP, dptr, "disk_haltio HIO chsa %04x cmd = %02x ccw_count %02x\n", chsa, cmd, chp->ccw_count); @@ -1098,11 +1097,9 @@ uint16 disk_haltio(UNIT *uptr) { uptr->CMD &= LMASK; /* make non-busy */ uptr->SNS2 |= (SNS_ONC|SNS_UNR); /* on cylinder & ready */ sim_cancel(uptr); /* clear the input timer */ -// sim_debug(DEBUG_CMD, dptr, sim_debug(DEBUG_EXP, dptr, "disk_haltio HIO I/O stop chsa %04x cmd = %02x CHS %08x STAR %08x\n", chsa, cmd, uptr->CHS, uptr->STAR); -//1204 chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITEXP); /* force end */ return SCPE_IOERR; } diff --git a/SEL32/sel32_ec.c b/SEL32/sel32_ec.c index 6b27e52..e823218 100644 --- a/SEL32/sel32_ec.c +++ b/SEL32/sel32_ec.c @@ -197,7 +197,7 @@ struct ec_device { ETH_MAC mac; /* Hardware MAC addresses */ ETH_DEV etherface; ETH_QUE ReadQ; - ETH_PACK rec_buff[64]; /* Buffer for recieved packet */ + ETH_PACK rec_buff[64]; /* Buffer for received packet */ ETH_PACK snd_buff; /* Buffer for sending packet */ int macs_n; /* Number of multi-cast addresses */ ETH_MAC macs[67]; /* Watched Multi-cast addresses */ @@ -223,10 +223,7 @@ static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff}; CHANP ec_chp[NUM_UNITS_ETHER] = {0}; /* forward definitions */ -#define FOR_TEST -#ifdef FOR_TEST uint16 ec_preio(UNIT *uptr, uint16 chan); -#endif uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); t_stat ec_rec_srv(UNIT *uptr); t_stat ec_srv(UNIT *uptr); @@ -235,9 +232,7 @@ uint16 ec_iocl(CHANP *chp, int32 tic_ok); void ec_packet_debug(struct ec_device *ec, const char *action, ETH_PACK *packet); t_stat ec_reset (DEVICE *dptr); void ec_ini(UNIT *, t_bool); -#ifdef FOR_TEST uint16 ec_rschnlio(UNIT *uptr); -#endif t_stat ec_show_mac (FILE* st, UNIT* uptr, int32 val, CONST void* desc); t_stat ec_set_mac (UNIT* uptr, int32 val, CONST char* cptr, void* desc); t_stat ec_show_mode (FILE* st, UNIT* uptr, int32 val, CONST void* desc); @@ -276,21 +271,13 @@ UNIT ec_unit[] = { }; DIB ec_dib = { -#ifdef FOR_TEST ec_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ -#else - NULL, /* Pre start I/O */ -#endif - ec_startcmd, /* Start a command */ + ec_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ ec_haltio, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O */ NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O */ NULL, /* uint16 (*test_io)(UNIT *uptr) */ /* Test I/O */ NULL, /* uint16 (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ -#ifdef FOR_TEST ec_rschnlio, /* uint16 (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ -#else - NULL, /* uint16 (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ -#endif ec_iocl, /* uint16 (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ ec_ini, /* void (*dev_ini)(UNIT *uptr) */ /* init function */ ec_unit, /* UNIT *units */ /* Pointer to units structure */ @@ -400,8 +387,8 @@ loop: } sim_debug(DEBUG_CMD, dptr, - "ec_iocl @%06x read ccw chan %02x IOCD wd 1 %08x wd 2 %08x SNS %08x\n", - chp->chan_caw, chan, word1, word2, uptr->SNS); + "ec_iocl @%06x read ccw chsa %04x IOCD wd 1 %08x wd 2 %08x SNS %08x\n", + chp->chan_caw, chp->chan_dev, word1, word2, uptr->SNS); chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ @@ -588,9 +575,7 @@ 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 + chp->chan_qwait = QWAIT; /* run 0 instructions before starting iocl */ } } else @@ -613,14 +598,12 @@ loop: return 0; /* good return */ } -#ifdef FOR_TEST /* start an ethernet operation */ uint16 ec_preio(UNIT *uptr, uint16 chan) { DEVICE *dptr = get_dev(uptr); int unit = (uptr - dptr->units); uint16 chsa = GET_UADDR(uptr->CMD); -#ifdef WAIT_FOR_TEST sim_debug(DEBUG_CMD, dptr, "ec_preio CMD %08x unit %02x chsa %04x\n", uptr->CMD, unit, chsa); if ((uptr->CMD & EC_CMDMSK) != 0) { /* just return if busy */ @@ -628,13 +611,11 @@ uint16 ec_preio(UNIT *uptr, uint16 chan) { "ec_preio unit %02x chsa %04x BUSY\n", unit, chsa); return SNS_BSY; } -#endif sim_debug(DEBUG_CMD, dptr, "ec_preio CMD %08x unit %02x chsa %04x OK\n", uptr->CMD, unit, chsa); return SCPE_OK; /* good to go */ } -#endif /* Start ethernet command */ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) @@ -655,7 +636,27 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) switch (cmd) { case EC_WRITE: /* Write command 0x01 */ uptr->CMD |= cmd|EC_BUSY; /* save cmd */ - sim_activate(uptr, 5000); /* start things off */ +// This works maybe 1 in 20 times to get to test 30 +//0313 sim_activate(uptr, 5000); /* start things off */ +// This smaller values runs to test 30, but gets lots of length errors */ +// sim_activate(uptr, 3000); /* start things off */ +// +// This works most of the time & stops at test 30 with no len errors + sim_activate(uptr, 4800); /* start things off */ +// This works some of the time, stops at test 30 with lots of len errors +// sim_activate(uptr, 4700); /* start things off */ +// This works some of the time, stops at test 30 with lots of len errors +//* sim_activate(uptr, 4500); /* start things off */ +// This works some of the time, stops at test 30 with lots of len errors +// sim_activate(uptr, 4000); /* start things off */ +// This works some of the time, stops at test 19A, 20 & 30 +// sim_activate(uptr, 6000); /* start things off */ +// This works sometimes, stops at test 20 +// sim_activate(uptr, 7000); /* start things off */ +// This works sometimes, stops at test 20 +// sim_activate(uptr, 8000); /* start things off */ +// This works sometimes, stops at test 19A +// sim_activate(uptr, 9000); /* start things off */ return 0; case EC_INCH: /* INCH cmd 0x0 */ cmd = EC_INCH2; /* set dummy INCH cmd 0xf0 */ @@ -679,7 +680,8 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) } #endif uptr->CMD |= cmd|EC_BUSY; /* save cmd */ - sim_activate(uptr, 100); /* start things off */ +//JB sim_activate(uptr, 100); /* start things off */ + sim_activate(uptr, 50); /* start things off */ return 0; } @@ -706,8 +708,7 @@ t_stat ec_rec_srv(UNIT *uptr) ec_data.rec_ptr = (ec_data.rec_ptr + 1) & 0xf; ec_data.rx_count++; sim_debug(DEBUG_DETAIL, dptr, - "ec_rec_srv received packet %08x\n", - ec_data.rx_count); + "ec_rec_srv received packet %08x\n", ec_data.rx_count); } } } @@ -896,7 +897,7 @@ wr_end: if (ec_data.snd_buff.len > ETH_MAX_PACKET) { sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv WRITE error user 2manybytes %0x\n", chp->ccw_count); - /* diags wants prog check instead of unit check */ + /* diags wants prog check instead of length check test 4E */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); break; } @@ -940,17 +941,18 @@ wr_end: case EC_READ: /* Read command 0x02 */ /* If no data to receive wait for some more */ if (ec_data.xtr_ptr == ec_data.rec_ptr) { - sim_clock_coschedule(uptr, 1000); /* continue poll */ +// sim_clock_coschedule(uptr, 1000); /* continue poll */ + sim_clock_coschedule(uptr, 500); /* continue poll */ return SCPE_OK; } pirq = 0; - sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv read %d %d size=%d\n", ec_data.xtr_ptr, - ec_data.rec_ptr, ec_data.conf[9]); + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv read %d %d size=%d\n", + ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9]); uptr->CMD &= LMASK; /* remove old status bits & cmd */ /* Read must be word bounded */ if (chp->ccw_addr & 0x3) { sim_debug(DEBUG_EXP, dptr, - "ec_iocl iocd bad address caw %06x ccw %06x\n", + "ec_srv iocd bad address caw %06x ccw %06x\n", chp->chan_caw, chp->ccw_addr); ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf; // chp->ccw_flags &= ~FLAG_SLI; @@ -964,12 +966,13 @@ wr_end: pck = (uint8 *)(&ec_data.rec_buff[ec_data.xtr_ptr].msg[0]); len = (int)(ec_data.rec_buff[ec_data.xtr_ptr].len); if (len < ec_data.conf[9]) { - sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short read size %x %x\n",chp->ccw_count, ec_data.conf[9]); - ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf; - chp->ccw_count = 0; - /* diags wants prog check instead of unit check */ - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); - break; + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv READ error short read len %x size %x %x\n", + len, chp->ccw_count, ec_data.conf[9]); + ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf; + chp->ccw_count = 0; + /* diags wants prog check instead of unit check test 4F */ + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + break; } switch (GET_MODE(ec_master_uptr->flags)) { case 0: @@ -1052,17 +1055,17 @@ wr_end: ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf; ec_data.rx_count++; sim_debug(DEBUG_DETAIL, &ec_dev, - "ec_srv received bytes %d of %d count=%08x\n" ,i, - len, ec_data.rx_count); + "ec_srv received bytes %d of %d count=%08x conf %x\n", + i, len, ec_data.rx_count, ec_data.conf[9]); chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); return SCPE_OK; } } chp->ccw_flags |= FLAG_SLI; -// chp->ccw_cmd = 0; /* This is to kill SLI indicator */ ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & 0xf; sim_debug(DEBUG_DETAIL, &ec_dev, - "ec_srv received bytes %d count=%08x\n" ,len, ec_data.rx_count); + "ec_srv received bytes %d count=%08x conf %x\n", + len, ec_data.rx_count, ec_data.conf[9]); if (pirq) chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); else @@ -1160,8 +1163,8 @@ wr_end: /*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; - sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv SNS %d %d\n", ec_data.xtr_ptr, - ec_data.rec_ptr); + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv SNS len %d xt %d rd %d\n", + len, ec_data.xtr_ptr, ec_data.rec_ptr); ch = (uptr->SNS >> 24) & 0xfc; ch |= GET_MODE(ec_master_uptr->flags); sim_debug(DEBUG_DETAIL, dptr, "ec_srv sense b0 1 %02x\n", ch); @@ -1193,14 +1196,10 @@ wr_end: break; default: -#ifdef ALLOW_0_CMD sim_debug(DEBUG_CMD, dptr, "invalid command %02x\n", cmd); uptr->SNS |= SNS_CMDREJ; uptr->CMD &= LMASK; /* remove old status bits & cmd */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); -#else - sim_debug(DEBUG_CMD, dptr, "for testing, allow unknown command %02x\n", cmd); -#endif } sim_debug(DEBUG_DETAIL, dptr, "ec_srv done cmd=%02x chsa %04x count %04x\n", cmd, chsa, chp->ccw_count); @@ -1229,9 +1228,10 @@ uint16 ec_haltio(UNIT *uptr) { uptr->CMD &= LMASK; /* make non-busy */ uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ if (chsa & 0x0f) /* no cancel for 0 */ - sim_cancel(uptr); /* clear the input timer */ + sim_cancel(uptr); /* clear the output timer */ sim_debug(DEBUG_CMD, dptr, "ec_haltio HIO I/O stop chsa %04x cmd = %02x\n", chsa, cmd); + /* No unit exception status for ethernet */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* force end */ return SCPE_IOERR; } @@ -1271,7 +1271,6 @@ void ec_ini(UNIT *uptr, t_bool f) } } -#ifdef FOR_TEST /* handle rschnlio cmds for Ethernet */ uint16 ec_rschnlio(UNIT *uptr) { DEVICE *dptr = get_dev(uptr); @@ -1283,7 +1282,6 @@ uint16 ec_rschnlio(UNIT *uptr) { ec_ini(uptr, 0); /* reset the unit */ return SCPE_OK; } -#endif static char * ipv4_inet_ntoa(struct in_addr ip) diff --git a/SEL32/sel32_hsdp.c b/SEL32/sel32_hsdp.c index d0b891f..736e79e 100644 --- a/SEL32/sel32_hsdp.c +++ b/SEL32/sel32_hsdp.c @@ -3012,9 +3012,6 @@ int hsdp_label(UNIT *uptr, int use_strep) { /* get sector address of vendor defect table VDT */ /* put data = 0xf0000004 0xf4000000 */ int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); - /* make logical */ - int32 logva = vaddr*(SPT(type)-1)/(SPT(type)); - /* get sector address of utx diag map (DMAP) track 0 pointer */ /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ /* 0x9a000000 + (cyl-1), 0xf4000000 */ @@ -3024,16 +3021,9 @@ int hsdp_label(UNIT *uptr, int use_strep) { /* get sector address of utx flaw map sec 1 pointer */ /* use this address for sec 1 label pointer */ -#define NOT_NEEDED_0128 -#ifndef NOT_NEEDED_0128 - int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); - /* make logical */ - int32 logua = uaddr*(SPT(type)-1)/(SPT(type)); -#else int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); /* make logical */ int32 logua = uaddr*(SPT(type)-1)/(SPT(type)); -#endif /* write 30 byte track labels for all tracks on disk */ /* tot_tracks entries will be created starting at end of disk */ @@ -3130,29 +3120,14 @@ int hsdp_label(UNIT *uptr, int use_strep) { /* write vaddr to track label for dmap */ if ((i*SPT(type)) == daddr) { /* get track address in sectors */ -//no_logical #if 1 -#if 0 - if (use_strep) { - /* output logical vendor defect map address of disk */ - label[12] = (logva >> 24) & 0xff; /* Vaddr pointer vdt */ - label[13] = (logva >> 16) & 0xff; - label[14] = (logva >> 8) & 0xff; - label[15] = (logva) & 0xff; - printf("hsdp_label WTL logva@vaddr %08x -> %08x\r\n", logva, vaddr); - sim_debug(DEBUG_CMD, dptr, - "hsdp_label WTL logva@vaddr %08x -> %08x\n", logva, vaddr); - } else -#endif - { - /* output physical vendor defect map address of disk */ - label[12] = (vaddr >> 24) & 0xff; /* Vaddr pointer vdt */ - label[13] = (vaddr >> 16) & 0xff; - label[14] = (vaddr >> 8) & 0xff; - label[15] = (vaddr) & 0xff; - printf("hsdp_label WTL vaddr@vaddr %08x -> %08x\r\n", vaddr, vaddr); - sim_debug(DEBUG_CMD, dptr, - "hsdp_label WTL vaddr@vaddr %08x -> %08x\n", vaddr, vaddr); - } + /* output physical vendor defect map address of disk */ + label[12] = (vaddr >> 24) & 0xff; /* Vaddr pointer vdt */ + label[13] = (vaddr >> 16) & 0xff; + label[14] = (vaddr >> 8) & 0xff; + label[15] = (vaddr) & 0xff; + printf("hsdp_label WTL vaddr@vaddr %08x -> %08x\r\n", vaddr, vaddr); + sim_debug(DEBUG_CMD, dptr, + "hsdp_label WTL vaddr@vaddr %08x -> %08x\n", vaddr, vaddr); } /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ @@ -3160,13 +3135,11 @@ int hsdp_label(UNIT *uptr, int use_strep) { /* area too. Byte 27 is sectors/track and byte 28 is number of heads. */ /* Byte 26 is mode. Byte 25 is copy of byte 27. */ label[25] = SPT(type) & 0xff; /* save sectors per track */ -//no_logical if ((use_strep) && (daddr == (i*SPT(type)) || (i == 0))) { if ((use_strep) && (i == 0)) { label[25] = (SPT(type)-1) & 0xff; } uptr->LSC = label[25]; /* save logical/physical sector count from label */ label[26] = hsdp_type[type].type & 0xfd; /* zero bits 6 in type byte */ -// label[26] = hsdp_type[type].type | 1; /* mode data is 0x41 */ label[27] = label[25]; /* same as label[25] */ label[28] = HDS(type) & 0xff; @@ -3230,34 +3203,6 @@ int hsdp_label(UNIT *uptr, int use_strep) { /* if this is written, UTX will not be able to do a newfs */ /* gets preposterous size 0 error */ -#ifdef XXXX_121720 - /* maybe not needed, but left anyway */ - /* uaddr has umap value for sector one label */ - if (CHS == 1) { /* write umap address in sec 1 */ -#if 1 - if (use_strep) { - /* output logical umap address */ - label[12] = (logua >> 24) & 0xff; /* lumapp UMAP logical pointer */ - label[13] = (logua >> 16) & 0xff; - label[14] = (logua >> 8) & 0xff; - label[15] = (logua) & 0xff; - sim_debug(DEBUG_CMD, dptr, - "hsdp_format WSL uaddr star %02x %02x %02x %02x\n", - label[12], label[13], label[14], label[15]); - } else -#endif - { - /* output physical umap address */ - label[12] = (uaddr >> 24) & 0xff; /* lumapp UMAP physical pointer */ - label[13] = (uaddr >> 16) & 0xff; - label[14] = (uaddr >> 8) & 0xff; - label[15] = (uaddr) & 0xff; - sim_debug(DEBUG_CMD, dptr, - "hsdp_format WSL uaddr star %02x %02x %02x %02x\n", - label[12], label[13], label[14], label[15]); - } - } -#endif /* the tech doc shows the cyl/trk/sec data is in the first 4 bytes */ /* of the track label, BUT it is really in the configuration data */ /* area too. Byte 27 is sectors/track and byte 28 is number of heads. */ @@ -3303,22 +3248,10 @@ int hsdp_format(UNIT *uptr) { /* last sector address of disk (cyl * hds * spt) - 1 */ uint32 laddr = CAP(type) - 1; /* last sector of disk */ - /* make logical */ - int32 logla = laddr*(SPT(type)-1)/(SPT(type)); - -#ifndef NOT_NEEDED_0128 - /* last track address of disk (cyl * hds * spt) - spt */ - uint32 ltaddr = CAP(type)-SPT(type); /* last track of disk */ - /* make logical */ - int32 loglta = ltaddr*(SPT(type)-1)/(SPT(type)); -#endif /* get sector address of vendor defect table VDT */ /* put data = 0xf0000004 0xf4000000 */ int32 vaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-1) * SPT(type); - /* make logical */ - int32 logva = vaddr*(SPT(type)-1)/(SPT(type)); - /* get sector address of utx diag map (DMAP) track 0 pointer */ /* put data = 0xf0000000 + (cyl-1), 0x8a000000 + daddr, */ /* 0x9a000000 + (cyl-1), 0xf4000000 */ @@ -3327,19 +3260,7 @@ int hsdp_format(UNIT *uptr) { /* make logical */ int32 logda = daddr*(SPT(type)-1)/(SPT(type)); -#ifndef NOT_NEEDED_0128 - /* get sector address of utx flaw data (1 track long) */ - /* set trace data to zero */ - int32 faddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); - /* make logical */ - int32 logfa = faddr*(SPT(type)-1)/(SPT(type)); -#endif - -#ifndef NOT_NEEDED_0128 - int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); -#else int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); -#endif /* NULL vendor flaw map */ uint32 vmap[2] = {0xf0000004, 0xf4000000}; @@ -3351,23 +3272,12 @@ int hsdp_format(UNIT *uptr) { uint32 dmap[4] = {0xf0000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))), 0x8a000000 | logda, 0x9a000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))), 0xf4000000}; -#ifndef NOT_NEEDED_0128 - /* utx flaw map */ - uint32 pfmap[4] = {0xf0000000 | (cap-1), 0x8a000000 | daddr, - 0x9a000000 | ltaddr, 0xf4000000}; - - /* utx flaw map */ - uint32 fmap[4] = {0xf0000000 | (((cap-1)*(SPT(type)-1))/(SPT(type))), - 0x8a000000 | logda, - 0x9a000000 | loglta, 0xf4000000}; -#endif /* 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; } @@ -3434,16 +3344,6 @@ int hsdp_format(UNIT *uptr) { pdmap[i] = (((pdmap[i] & 0xff) << 24) | ((pdmap[i] & 0xff00) << 8) | ((pdmap[i] & 0xff0000) >> 8) | ((pdmap[i] >> 24) & 0xff)); } -#ifndef NOT_NEEDED_0128 - for (i=0; i<4; i++) { - fmap[i] = (((fmap[i] & 0xff) << 24) | ((fmap[i] & 0xff00) << 8) | - ((fmap[i] & 0xff0000) >> 8) | ((fmap[i] >> 24) & 0xff)); - } - for (i=0; i<4; i++) { - pfmap[i] = (((pfmap[i] & 0xff) << 24) | ((pfmap[i] & 0xff00) << 8) | - ((pfmap[i] & 0xff0000) >> 8) | ((pfmap[i] >> 24) & 0xff)); - } -#endif /* now seek to end of disk and write the dmap data */ /* setup dmap pointed to by track label 0 wd[3] = (cyl-4) * spt + (spt - 1) */ @@ -3499,32 +3399,6 @@ int hsdp_format(UNIT *uptr) { return 1; } } -#ifndef NOT_NEEDED_0128 - /* write dummy UTX DMAP to faddr */ - if ((sim_fseek(uptr->fileref, faddr*ssize, SEEK_SET)) != 0) { /* seek DMAP */ - sim_debug(DEBUG_CMD, dptr, - "Error on media FMAP seek to sect %06x offset %06x\n", - faddr, faddr*ssize); - return 1; - } - if (use_st_format) { - if ((sim_fwrite((char *)&fmap, sizeof(uint32), 4, uptr->fileref)) != 4) { - sim_debug(DEBUG_CMD, dptr, - "Error writing UTX LFMAP to sect %06x offset %06x\n", - faddr, faddr*ssize); - return 1; - } - } else - { - if ((sim_fwrite((char *)&pfmap, sizeof(uint32), 4, uptr->fileref)) != 4) { - sim_debug(DEBUG_CMD, dptr, - "Error writing UTX FMAP to sect %06x offset %06x\n", - faddr, faddr*ssize); - return 1; - } - } -#endif - printf("Disk %s has %x (%d) cyl, %x (%d) hds, %x (%d) sec\r\n", hsdp_type[type].name, CYL(type), CYL(type), HDS(type), HDS(type), SPT(type), SPT(type)); @@ -3533,10 +3407,6 @@ int hsdp_format(UNIT *uptr) { printf("writing to dmap %x (%d) %x (%d) dmap to %x (%d) %x (%d)\r\n", cap-1, cap-1, (cap-1)*ssize, (cap-1)*ssize, daddr, daddr, daddr*ssize, daddr*ssize); -#ifndef NOT_NEEDED_0128 - printf("writing to fmap sec %x (%d) bytes %x (%d)\r\n", - faddr, faddr, (faddr)*ssize, (faddr)*ssize); -#endif printf("writing to umap sec %x (%d) bytes %x (%d)\r\n", uaddr, uaddr, (uaddr)*ssize, (uaddr)*ssize); @@ -3633,8 +3503,6 @@ t_stat hsdp_attach(UNIT *uptr, CONST char *file) printf("HSDP Disk attach ftell failed s=%06d\r\n", s); goto fmt; /* not setup, go format */ } -// sim_debug(DEBUG_CMD, dptr, "HSDP Disk attach ftell value s=%06d b=%06d CAP %06d\n", s/ssize, s, CAP(type)); -// printf("HSDP 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 */ @@ -3751,45 +3619,6 @@ ldone: return SCPE_FMT; /* error */ } } -#ifdef OLDWAY - else { -#ifndef NOT_NEEDED_0128 - int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-4) * SPT(type); - /* make logical */ - int32 logua = uaddr*(SPT(type)-1)/(SPT(type)); -#else - int32 uaddr = (CYL(type)-4) * SPC(type) + (HDS(type)-3) * SPT(type); - /* make logical */ - int32 logua = uaddr*(SPT(type)-1)/(SPT(type)); -#endif - if (buff[25] == SPT(type)) { - /* uaddr has physical umap value for track zero label */ - /* output physical umap address */ - buff[16] = (uaddr >> 24) & 0xff; /* lumapp DMAP pointer */ - buff[17] = (uaddr >> 16) & 0xff; - buff[18] = (uaddr >> 8) & 0xff; - buff[19] = (uaddr) & 0xff; - } else { - /* logua has logical umap value for track zero label */ - /* output logical umap address */ - buff[16] = (logua >> 24) & 0xff; /* lumapp DMAP pointer */ - buff[17] = (logua >> 16) & 0xff; - buff[18] = (logua >> 8) & 0xff; - buff[19] = (logua) & 0xff; - } - if ((sim_fseek(uptr->fileref, CAP(type)*ssize, SEEK_SET)) != 0) { /* seek end */ - detach_unit(uptr); /* detach if error */ - return SCPE_FMT; /* error */ - } - /* output updated umap address to track 0 for UTX21a */ - if ((sim_fwrite(buff, sizeof(uint8), 30, uptr->fileref)) != 30) { - sim_debug(DEBUG_CMD, dptr, - "Error writing back track 0 label to sect %06x offset %06x\n", - CAP(type), CAP(type)*ssize); - return SCPE_FMT; /* error */ - } - } -#endif /* 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 */ @@ -3822,15 +3651,12 @@ ldone: } info = (buff[0]<<24) | (buff[1]<<16) | (buff[2]<<8) | buff[3]; 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 */ 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 */ detach_unit(uptr); /* detach if error */ @@ -3840,7 +3666,6 @@ ldone: detach_unit(uptr); /* detach if error */ return SCPE_FMT; /* error */ } -// printf("Fix Done i %x info %8x good %8x buff[%x] %02x\r\n", i, info, good, i, buff[i]); } if ((sim_fseek(uptr->fileref, 0, SEEK_SET)) != 0) { /* seek home */ diff --git a/SEL32/sel32_iop.c b/SEL32/sel32_iop.c index 9a24f24..4335464 100644 --- a/SEL32/sel32_iop.c +++ b/SEL32/sel32_iop.c @@ -38,6 +38,7 @@ #define UNIT_IOP UNIT_IDLE | UNIT_DISABLE /* forward definitions */ +uint16 iop_preio(UNIT *uptr, uint16 chan); uint16 iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); void iop_ini(UNIT *uptr, t_bool f); uint16 iop_rschnlio(UNIT *uptr); @@ -99,7 +100,7 @@ UNIT iop_unit[] = { }; DIB iop_dib = { - NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */ + iop_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ iop_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command SIO */ NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O HIO */ NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O HIO */ @@ -155,6 +156,25 @@ uint16 iop_rschnlio(UNIT *uptr) { return SCPE_OK; } +/* start an iop operation */ +uint16 iop_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->u3); + + sim_debug(DEBUG_CMD, dptr, "iop_preio CMD %08x unit %02x chsa %04x\n", + uptr->u3, unit, chsa); + + if ((uptr->u3 & IOP_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "iop_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; /* yes, return busy */ + } + + sim_debug(DEBUG_CMD, dptr, "iop_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + /* start an I/O operation */ uint16 iop_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { diff --git a/SEL32/sel32_mfp.c b/SEL32/sel32_mfp.c index 5857770..d076415 100644 --- a/SEL32/sel32_mfp.c +++ b/SEL32/sel32_mfp.c @@ -39,6 +39,7 @@ #define UNIT_MFP UNIT_IDLE | UNIT_DISABLE /* forward definitions */ +uint16 mfp_preio(UNIT *uptr, uint16 chan); uint16 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd); void mfp_ini(UNIT *uptr, t_bool f); uint16 mfp_rschnlio(UNIT *uptr); @@ -103,7 +104,7 @@ UNIT mfp_unit[] = { //DIB mfp_dib = {NULL, mfp_startcmd, NULL, NULL, NULL, mfp_ini, mfp_unit, mfp_chp, NUM_UNITS_MFP, 0xff, 0x7600,0,0,0}; DIB mfp_dib = { - NULL, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */ + mfp_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ mfp_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ NULL, /* uint16 (*halt_io)(UNIT *uptr) */ /* Halt I/O HIO */ NULL, /* uint16 (*stop_io)(UNIT *uptr) */ /* Stop I/O HIO */ @@ -159,6 +160,25 @@ uint16 mfp_rschnlio(UNIT *uptr) { return SCPE_OK; } +/* start an mfp operation */ +uint16 mfp_preio(UNIT *uptr, uint16 chan) { + DEVICE *dptr = get_dev(uptr); + int unit = (uptr - dptr->units); + uint16 chsa = GET_UADDR(uptr->u3); + + sim_debug(DEBUG_CMD, dptr, "mfp_preio CMD %08x unit %02x chsa %04x\n", + uptr->u3, unit, chsa); + + if ((uptr->u3 & MFP_MSK) != 0) { /* is unit busy */ + sim_debug(DEBUG_CMD, dptr, + "mfp_preio unit %02x chsa %04x BUSY\n", unit, chsa); + return SNS_BSY; /* yes, return busy */ + } + + sim_debug(DEBUG_CMD, dptr, "mfp_preio unit %02x chsa %04x OK\n", unit, chsa); + return SCPE_OK; /* good to go */ +} + /* start an I/O operation */ uint16 mfp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) {