From 005bd4178f34db345b002c7dfb7e131b8c7396fb Mon Sep 17 00:00:00 2001 From: AZBevier Date: Mon, 22 Mar 2021 20:44:12 -0700 Subject: [PATCH] SEL32: Update sel32_ec.c to run ecdiags for mode 0, 1, & 2. SEL32: Add eomtap to taptools & change makefile & README.md. SEL32: Code cleanup for sel32_chan.c. SEL32: Leave auto-int active during processing. SEL32: Expand ethernet to 16 channels. --- SEL32/sel32_chan.c | 1774 +++++++++++++++++++------------------- SEL32/sel32_com.c | 4 +- SEL32/sel32_cpu.c | 18 +- SEL32/sel32_defs.h | 2 +- SEL32/sel32_disk.c | 29 +- SEL32/sel32_ec.c | 346 ++++++-- SEL32/taptools/README.md | 18 + SEL32/taptools/eomtap.c | 2 +- SEL32/taptools/makefile | 7 + SEL32/tests/SetupNet | 493 ++++++++--- 10 files changed, 1567 insertions(+), 1126 deletions(-) diff --git a/SEL32/sel32_chan.c b/SEL32/sel32_chan.c index 37fef3a..0932223 100644 --- a/SEL32/sel32_chan.c +++ b/SEL32/sel32_chan.c @@ -78,38 +78,38 @@ /* Bits 16-23 - Channel address (0-127) */ /* Bits 24-31 - Device Sub address (0-255) */ -uint32 channels = MAX_CHAN; /* maximum number of channels */ -int subchannels = SUB_CHANS; /* maximum number of subchannel devices */ -int irq_pend = 0; /* pending interrupt flag */ +uint32 channels = MAX_CHAN; /* maximum number of channels */ +int subchannels = SUB_CHANS; /* maximum number of subchannel devices */ +int irq_pend = 0; /* pending interrupt flag */ -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 */ +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 */ extern uint32 inbusy; extern uint32 outbusy; -DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */ -DIB *dib_chan[MAX_CHAN]; /* pointer to channel mux dib */ -uint16 loading; /* set when booting */ +DIB *dib_unit[MAX_DEV]; /* Pointer to Device info block */ +DIB *dib_chan[MAX_CHAN]; /* pointer to channel mux dib */ +uint16 loading; /* set when booting */ /* forward definitions */ -CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */ -UNIT *find_unit_ptr(uint16 chsa); /* find unit pointer */ +CHANP *find_chanp_ptr(uint16 chsa); /* find chanp pointer */ +UNIT *find_unit_ptr(uint16 chsa); /* find unit pointer */ int chan_read_byte(uint16 chsa, uint8 *data); int chan_write_byte(uint16 chsa, uint8 *data); void set_devattn(uint16 chsa, uint16 flags); -void set_devwake(uint16 chsa, uint16 flags); /* wakeup O/S for async line */ +void set_devwake(uint16 chsa, uint16 flags); /* wakeup O/S for async line */ void chan_end(uint16 chsa, uint16 flags); int test_write_byte_end(uint16 chsa); -t_stat checkxio(uint16 chsa, uint32 *status); /* check XIO */ -t_stat startxio(uint16 chsa, uint32 *status); /* start XIO */ -t_stat testxio(uint16 chsa, uint32 *status); /* test XIO */ -t_stat stoptxio(uint16 chsa, uint32 *status); /* stop XIO */ -t_stat rschnlxio(uint16 chsa, uint32 *status); /* reset channel XIO */ -t_stat haltxio(uint16 chsa, uint32 *status); /* halt XIO */ -t_stat grabxio(uint16 chsa, uint32 *status); /* grab XIO n/u */ -t_stat rsctlxio(uint16 chsa, uint32 *status); /* reset controller XIO */ +t_stat checkxio(uint16 chsa, uint32 *status); /* check XIO */ +t_stat startxio(uint16 chsa, uint32 *status); /* start XIO */ +t_stat testxio(uint16 chsa, uint32 *status); /* test XIO */ +t_stat stoptxio(uint16 chsa, uint32 *status); /* stop XIO */ +t_stat rschnlxio(uint16 chsa, uint32 *status); /* reset channel XIO */ +t_stat haltxio(uint16 chsa, uint32 *status); /* halt XIO */ +t_stat grabxio(uint16 chsa, uint32 *status); /* grab XIO n/u */ +t_stat rsctlxio(uint16 chsa, uint32 *status); /* reset controller XIO */ uint32 find_int_icb(uint16 chsa); uint32 find_int_lev(uint16 chsa); uint32 scan_chan(uint32 *ilev); @@ -141,103 +141,103 @@ int16 post_csw(CHANP *chp, uint32 rstat); /* 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 */ + 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 */ + 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 */ + 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_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 */ + return SCPE_OK; /* all OK */ } /* add an entry to the FIFO */ int32 FIFO_Put(uint16 chsa, uint32 entry) { - int32 num; /* number of entries */ - DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + 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_Put ERR NULL dib ptr for chsa %04x\n", chsa); - return -1; /* FIFO address error */ + 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_Put ERR FIFO full for chsa %04x count %02x\n", chsa, num); - return -1; /* FIFO Full */ + return -1; /* FIFO Full */ } dibp->chan_fifo[dibp->chan_fifo_in] = entry; /* add new entry */ - dibp->chan_fifo_in += 1; /* next entry */ - dibp->chan_fifo_in %= FIFO_SIZE; /* modulo FIFO size */ + dibp->chan_fifo_in += 1; /* next entry */ + dibp->chan_fifo_in %= FIFO_SIZE; /* modulo FIFO size */ num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; - return SCPE_OK; /* all OK */ + return SCPE_OK; /* all OK */ } /* get the next entry from the FIFO */ int32 FIFO_Get(uint16 chsa, uint32 *old) { - DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ if (dibp == NULL) { sim_debug(DEBUG_EXP, &cpu_dev, "FIFO_Get ERR NULL dib ptr for chsa %04x\n", chsa); - return -1; /* FIFO address error */ + return -1; /* FIFO address error */ } /* see if the FIFO is empty */ if (dibp->chan_fifo_in == dibp->chan_fifo_out) { - return -1; /* FIFO is empty, tell caller */ + return -1; /* FIFO is empty, tell caller */ } *old = dibp->chan_fifo[dibp->chan_fifo_out]; /* get the next entry */ - dibp->chan_fifo_out += 1; /* next entry */ - dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */ - return SCPE_OK; /* all OK */ + dibp->chan_fifo_out += 1; /* next entry */ + dibp->chan_fifo_out %= FIFO_SIZE; /* modulo FIFO size */ + return SCPE_OK; /* all OK */ } /* get number of entries in FIFO for channel */ int32 FIFO_Num(uint16 chsa) { - int32 num; /* number of entries */ - DIB *dibp = dib_chan[get_chan(chsa)]; /* get DIB pointer for channel */ + 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_Num ERR NULL dib ptr for chsa %04x\n", chsa); - return 0; /* FIFO address error */ + return 0; /* FIFO address error */ } /* calc entries */ num = (dibp->chan_fifo_in - dibp->chan_fifo_out + FIFO_SIZE) % FIFO_SIZE; - return (num>>1); /*GT*/ /* two words/entry */ + return (num>>1); /*GT*/ /* two words/entry */ } /* add an entry to the RDYQ */ int32 RDYQ_Put(uint32 entry) { - int32 num; /* number of entries */ + int32 num; /* number of entries */ /* see if RDYQ FIFO is full */ if (RDYQIN == ((RDYQOUT-1+RDYQ_SIZE) % RDYQ_SIZE)) { num = (RDYQIN - RDYQOUT + RDYQ_SIZE) % RDYQ_SIZE; /* number of entries */ sim_debug(DEBUG_EXP, &cpu_dev, "RDYQ_Put queue FULL count %02x\n", num); - return -1; /* RDYQ Full */ + return -1; /* RDYQ Full */ } - RDYQ[RDYQIN] = entry; /* add new entry */ - RDYQIN += 1; /* next entry */ - RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */ - irq_pend = 1; /* do a scan */ - return SCPE_OK; /* all OK */ + RDYQ[RDYQIN] = entry; /* add new entry */ + RDYQIN += 1; /* next entry */ + RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */ + irq_pend = 1; /* do a scan */ + return SCPE_OK; /* all OK */ } /* get the next entry from the RDYQ */ @@ -245,12 +245,12 @@ int32 RDYQ_Get(uint32 *old) { /* see if the RDYQ is empty */ if (RDYQIN == RDYQOUT) { - return -1; /* RDYQ is empty, tell caller */ + return -1; /* RDYQ is empty, tell caller */ } - *old = RDYQ[RDYQOUT]; /* get the next entry */ - RDYQOUT += 1; /* next entry */ - RDYQOUT %= RDYQ_SIZE; /* modulo RDYQ size */ - return SCPE_OK; /* all OK */ + *old = RDYQ[RDYQOUT]; /* get the next entry */ + RDYQOUT += 1; /* next entry */ + RDYQOUT %= RDYQ_SIZE; /* modulo RDYQ size */ + return SCPE_OK; /* all OK */ } /* get number of entries in RDYQ for channel */ @@ -264,22 +264,22 @@ int32 RDYQ_Num(void) /* add an entry to the IOCLQ */ int32 IOCLQ_Put(IOCLQ *qptr, uint32 entry) { - int32 num; /* number of entries */ + int32 num; /* number of entries */ if (qptr == NULL) { sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Put ERROR NULL qptr\n"); - return -1; /* IOCLQ address error */ + return -1; /* IOCLQ address error */ } if (qptr->ioclq_in == ((qptr->ioclq_out-1+IOCLQ_SIZE) % IOCLQ_SIZE)) { num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE; sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Put ERROR IOCLQ full, entries %02x\n", num); - return -1; /* IOCLQ Full */ + return -1; /* IOCLQ Full */ } - qptr->ioclq_fifo[qptr->ioclq_in] = entry; /* add new entry */ - qptr->ioclq_in += 1; /* next entry */ - qptr->ioclq_in %= IOCLQ_SIZE; /* modulo IOCLQ size */ + qptr->ioclq_fifo[qptr->ioclq_in] = entry; /* add new entry */ + qptr->ioclq_in += 1; /* next entry */ + qptr->ioclq_in %= IOCLQ_SIZE; /* modulo IOCLQ size */ num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE; - return SCPE_OK; /* all OK */ + return SCPE_OK; /* all OK */ } /* get the next entry from the IOCLQ */ @@ -287,61 +287,61 @@ int32 IOCLQ_Get(IOCLQ *qptr, uint32 *old) { if (qptr == NULL) { sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Get ERROR NULL qptr\n"); - return -1; /* IOCLQ address error */ + return -1; /* IOCLQ address error */ } /* see if the IOCLQ is empty */ if (qptr->ioclq_in == qptr->ioclq_out) { // sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Get IOCLQ empty\n"); - return -1; /* IOCLQ is empty, tell caller */ + return -1; /* IOCLQ is empty, tell caller */ } - *old = qptr->ioclq_fifo[qptr->ioclq_out]; /* get the next entry */ - qptr->ioclq_out += 1; /* next entry */ - qptr->ioclq_out %= IOCLQ_SIZE; /* modulo IOCLQ size */ - return SCPE_OK; /* all OK */ + *old = qptr->ioclq_fifo[qptr->ioclq_out]; /* get the next entry */ + qptr->ioclq_out += 1; /* next entry */ + qptr->ioclq_out %= IOCLQ_SIZE; /* modulo IOCLQ size */ + return SCPE_OK; /* all OK */ } /* get number of entries in IOCLQ for channel */ int32 IOCLQ_Num(IOCLQ *qptr) { - int32 num = 0; /* number of entries */ + int32 num = 0; /* number of entries */ if (qptr == NULL) { sim_debug(DEBUG_EXP, &cpu_dev, "IOCLQ_Num ERROR NULL qptr\n"); - return num; /* IOCLQ address error */ + return num; /* IOCLQ address error */ } /* calc entries */ num = (qptr->ioclq_in - qptr->ioclq_out + IOCLQ_SIZE) % IOCLQ_SIZE; - return num; /* one words/entry */ + return num; /* one words/entry */ } /* Set INCH buffer address for channel */ /* return SCPE_OK or SCPE_MEM if invalid address or SCPE_ARG if already defined */ t_stat set_inch(UNIT *uptr, uint32 inch_addr) { - uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ - uint32 chan = chsa & 0x7f00; /* get just channel address */ + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + uint32 chan = chsa & 0x7f00; /* get just channel address */ CHANP *chp; int i, j; - DIB *dibp = dib_chan[chan>>8]; /* get channel dib ptr */ - CHANP *pchp = 0; /* for channel prog ptr */ + DIB *dibp = dib_chan[chan>>8]; /* get channel dib ptr */ + CHANP *pchp = 0; /* for channel prog ptr */ /* must be valid DIB pointer */ if (dibp == NULL) - return SCPE_MEM; /* return memory error */ - pchp = dibp->chan_prg; /* get parent channel prog ptr */ + return SCPE_MEM; /* return memory error */ + pchp = dibp->chan_prg; /* get parent channel prog ptr */ /* must be valid channel pointer */ if (pchp == NULL) - return SCPE_MEM; /* return memory error */ + return SCPE_MEM; /* return memory error */ /* see if valid memory address */ - if (!MEM_ADDR_OK(inch_addr)) /* see if mem addr >= MEMSIZE */ - return SCPE_MEM; /* return memory error */ + if (!MEM_ADDR_OK(inch_addr)) /* see if mem addr >= MEMSIZE */ + return SCPE_MEM; /* return memory error */ /* set INCH address for all units on master channel */ chp = pchp; for (i=0; inumunits; i++) { - chp->chan_inch_addr = inch_addr; /* set the inch addr */ - chp++; /* next unit channel */ + chp->chan_inch_addr = inch_addr; /* set the inch addr */ + chp++; /* next unit channel */ } sim_debug(DEBUG_XIO, &cpu_dev, @@ -349,20 +349,20 @@ t_stat set_inch(UNIT *uptr, uint32 inch_addr) { /* now go through all the sub addresses for the channel and set inch addr */ for (i=0; ichan_prg; /* get first unit channel prog ptr */ + if (dib_unit[chsa] == 0) /* make sure good address */ + continue; /* must have a DIB, so not used */ + dibp = dib_unit[chsa]; /* finally get the new dib adddress */ + chp = dibp->chan_prg; /* get first unit channel prog ptr */ /* set INCH address for all units on channel */ for (j=0; jnumunits; j++) { - chp->chan_inch_addr = inch_addr; /* set the inch addr */ - chp++; /* next unit channel */ + chp->chan_inch_addr = inch_addr; /* set the inch addr */ + chp++; /* next unit channel */ } } - return SCPE_OK; /* All OK */ + return SCPE_OK; /* All OK */ } /* Find interrupt level for the given physical device (ch/sa) */ @@ -371,15 +371,15 @@ uint32 find_int_lev(uint16 chsa) { uint32 inta; /* get the device entry for channel in SPAD */ - uint32 spadent = SPAD[get_chan(chsa)]; /* get spad device entry for logical channel */ + uint32 spadent = SPAD[get_chan(chsa)]; /* get spad device entry for logical channel */ if (spadent == 0 || spadent == 0xffffffff) { /* see if valid entry */ sim_debug(DEBUG_EXP, &cpu_dev, "find_int_lev ERR chsa %04x spadent %08x\n", chsa, spadent); - return 0; /* not found */ + return 0; /* not found */ } - inta = ((~spadent)>>16)&0x7f; /* get interrupt level */ - return(inta); /* return the level*/ + inta = ((~spadent)>>16)&0x7f; /* get interrupt level */ + return(inta); /* return the level*/ } /* Find interrupt context block address for given device (ch/sa) */ @@ -388,91 +388,91 @@ uint32 find_int_icb(uint16 chsa) { uint32 inta, icba; - inta = find_int_lev(chsa); /* find the int level */ + inta = find_int_lev(chsa); /* find the int level */ if (inta == 0) { sim_debug(DEBUG_EXP, &cpu_dev, "find_int_icb ERR chsa %04x inta %02x\n", chsa, inta); - return 0; /* not found */ + return 0; /* not found */ } /* add interrupt vector table base address plus int # byte address offset */ - icba = SPAD[0xf1] + (inta<<2); /* interrupt vector address in memory */ - if (!MEM_ADDR_OK(icba)) { /* needs to be valid address in memory */ + icba = SPAD[0xf1] + (inta<<2); /* interrupt vector address in memory */ + if (!MEM_ADDR_OK(icba)) { /* needs to be valid address in memory */ sim_debug(DEBUG_EXP, &cpu_dev, "find_int_icb ERR chsa %04x icba %02x\n", chsa, icba); - return 0; /* not found */ + return 0; /* not found */ } - icba = RMW(icba); /* get address of ICB from memory */ - if (!MEM_ADDR_OK(icba)) { /* needs to be valid address in memory */ + icba = RMW(icba); /* get address of ICB from memory */ + if (!MEM_ADDR_OK(icba)) { /* needs to be valid address in memory */ sim_debug(DEBUG_EXP, &cpu_dev, "find_int_icb ERR chsa %04x icba %02x\n", chsa, icba); - return 0; /* not found */ + return 0; /* not found */ } - return(icba); /* return the address */ + return(icba); /* return the address */ } /* Find unit pointer for given device (ch/sa) */ UNIT *find_unit_ptr(uint16 chsa) { - struct dib *dibp; /* DIB pointer */ - UNIT *uptr; /* UNIT pointer */ + struct dib *dibp; /* DIB pointer */ + UNIT *uptr; /* UNIT pointer */ int i; - dibp = dib_unit[chsa]; /* get DIB pointer from device address */ - if (dibp == 0) { /* if zero, not defined on system */ + dibp = dib_unit[chsa]; /* get DIB pointer from device address */ + if (dibp == 0) { /* if zero, not defined on system */ sim_debug(DEBUG_EXP, &cpu_dev, "find_unit_ptr ERR chsa %04x dibp %p\n", chsa, dibp); - return NULL; /* tell caller */ + return NULL; /* tell caller */ } - uptr = dibp->units; /* get the pointer to the units on this channel */ - if (uptr == 0) { /* if zero, no devices defined on system */ + uptr = dibp->units; /* get the pointer to the units on this channel */ + if (uptr == 0) { /* if zero, no devices defined on system */ sim_debug(DEBUG_EXP, &cpu_dev, "find_unit_ptr ERR chsa %04x uptr %p\n", chsa, uptr); - return NULL; /* tell caller */ + return NULL; /* tell caller */ } - for (i = 0; i < dibp->numunits; i++) { /* search through units to get a match */ - if (chsa == GET_UADDR(uptr->u3)) { /* does ch/sa match? */ - return uptr; /* return the pointer */ + for (i = 0; i < dibp->numunits; i++) { /* search through units to get a match */ + if (chsa == GET_UADDR(uptr->u3)) { /* does ch/sa match? */ + return uptr; /* return the pointer */ } - uptr++; /* next unit */ + uptr++; /* next unit */ } - return NULL; /* device not found on system */ + return NULL; /* device not found on system */ } /* Find channel program pointer for given device (ch/sa) */ CHANP *find_chanp_ptr(uint16 chsa) { - struct dib *dibp; /* DIB pointer */ - UNIT *uptr; /* UNIT pointer */ - CHANP *chp; /* CHANP pointer */ + struct dib *dibp; /* DIB pointer */ + UNIT *uptr; /* UNIT pointer */ + CHANP *chp; /* CHANP pointer */ int i; - dibp = dib_unit[chsa]; /* get DIB pointer from unit address */ - if (dibp == 0) { /* if zero, not defined on system */ + dibp = dib_unit[chsa]; /* get DIB pointer from unit address */ + if (dibp == 0) { /* if zero, not defined on system */ sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x dibp %p\n", chsa, dibp); - return NULL; /* tell caller */ + return NULL; /* tell caller */ } if ((chp = (CHANP *)dibp->chan_prg) == NULL) { /* must have channel information for each device */ sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x chp %p\n", chsa, chp); - return NULL; /* tell caller */ + return NULL; /* tell caller */ } - uptr = dibp->units; /* get the pointer to the units on this channel */ - if (uptr == 0) { /* if zero, no devices defined on system */ + uptr = dibp->units; /* get the pointer to the units on this channel */ + if (uptr == 0) { /* if zero, no devices defined on system */ sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x uptr %p\n", chsa, uptr); - return NULL; /* tell caller */ + return NULL; /* tell caller */ } - for (i = 0; i < dibp->numunits; i++) { /* search through units to get a match */ - if (chsa == GET_UADDR(uptr->u3)) { /* does ch/sa match? */ - return chp; /* return the pointer */ + for (i = 0; i < dibp->numunits; i++) { /* search through units to get a match */ + if (chsa == GET_UADDR(uptr->u3)) { /* does ch/sa match? */ + return chp; /* return the pointer */ } - uptr++; /* next UNIT */ - chp++; /* next CHANP */ + uptr++; /* next UNIT */ + chp++; /* next CHANP */ } sim_debug(DEBUG_EXP, &cpu_dev, "find_chanp_ptr ERR chsa %04x no match uptr %p\n", chsa, uptr); - return NULL; /* device not found on system */ + return NULL; /* device not found on system */ } /* Read a full word into memory. @@ -481,17 +481,17 @@ CHANP *find_chanp_ptr(uint16 chsa) */ int readfull(CHANP *chp, uint32 maddr, uint32 *word) { - maddr &= MASK24; /* mask addr to 24 bits */ - if (!MEM_ADDR_OK(maddr)) { /* see if mem addr >= MEMSIZE */ - chp->chan_status |= STATUS_PCHK; /* program check error */ + maddr &= MASK24; /* mask addr to 24 bits */ + if (!MEM_ADDR_OK(maddr)) { /* see if mem addr >= MEMSIZE */ + chp->chan_status |= STATUS_PCHK; /* program check error */ sim_debug(DEBUG_EXP, &cpu_dev, "readfull read %08x from addr %08x ERROR\n", *word, maddr); - return 1; /* show we have error */ + return 1; /* show we have error */ } - *word = RMW(maddr); /* get 1 word */ + *word = RMW(maddr); /* get 1 word */ sim_debug(DEBUG_XIO, &cpu_dev, "READFULL chsa %04x read %08x from addr %08x\n", chp->chan_dev, *word, maddr); - return 0; /* return OK */ + return 0; /* return OK */ } /* Read a byte into the channel buffer. @@ -500,17 +500,17 @@ int readfull(CHANP *chp, uint32 maddr, uint32 *word) */ int readbuff(CHANP *chp) { - uint32 addr = chp->ccw_addr; /* channel buffer address */ + uint32 addr = chp->ccw_addr; /* channel buffer address */ - if (!MEM_ADDR_OK(addr & MASK24)) { /* see if memory address invalid */ - chp->chan_status |= STATUS_PCHK; /* bad, program check */ + if (!MEM_ADDR_OK(addr & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ sim_debug(DEBUG_EXP, &cpu_dev, "readbuff PCHK addr %08x to big mem %08x status %04x\n", addr, MEMSIZE, chp->chan_status); - chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */ - return 1; /* done, with error */ + chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */ + return 1; /* done, with error */ } - chp->chan_buf = RMB(addr&MASK24); /* get 1 byte */ + chp->chan_buf = RMB(addr&MASK24); /* get 1 byte */ return 0; } @@ -522,18 +522,18 @@ int writebuff(CHANP *chp) { uint32 addr = chp->ccw_addr; - if (!MEM_ADDR_OK(addr & MASK24)) { /* make sure write to good addr */ - chp->chan_status |= STATUS_PCHK; /* non-present memory, abort */ + if (!MEM_ADDR_OK(addr & MASK24)) { /* make sure write to good addr */ + chp->chan_status |= STATUS_PCHK; /* non-present memory, abort */ sim_debug(DEBUG_EXP, &cpu_dev, "writebuff PCHK addr %08x to big mem %08x status %04x\n", addr, MEMSIZE, chp->chan_status); - chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */ + chp->chan_byte = BUFF_CHNEND; /* force channel end & busy */ return 1; } - addr &= MASK24; /* good address, write the byte */ + addr &= MASK24; /* good address, write the byte */ sim_debug(DEBUG_DATA, &cpu_dev, "writebuff WRITE addr %06x DATA %08x status %04x\n", addr, chp->chan_buf, chp->chan_status); - WMB(addr, chp->chan_buf); /* write byte to memory */ + WMB(addr, chp->chan_buf); /* write byte to memory */ return 0; } @@ -546,45 +546,45 @@ int32 load_ccw(CHANP *chp, int32 tic_ok) uint32 word2 = 0; int32 docmd = 0; DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ - UNIT *uptr = chp->unitptr; /* get the unit ptr */ + UNIT *uptr = chp->unitptr; /* get the unit ptr */ uint16 chan = get_chan(chp->chan_dev); /* our channel */ uint16 devstat = 0; sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw @%06x entry chan_status[%04x] %04x\n", chp->chan_caw, chan, chp->chan_status); /* determine if channel DIB has a pre iocl processor */ - if (dibp->iocl_io != NULL) { /* NULL if no function */ + if (dibp->iocl_io != NULL) { /* NULL if no function */ /* call the device controller to process the iocl */ int32 tempa = dibp->iocl_io(chp, tic_ok); /* process IOCL */ - if (tempa != SCPE_OK) { /* see if OK */ + if (tempa != SCPE_OK) { /* see if OK */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw iocl_io call return ERROR chan %04x cstat %01x\n", chan, tempa); } else { sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw iocl_io call return OK chan %04x cstat %01x\n", chan, tempa); } - return tempa; /* just return status */ + return tempa; /* just return status */ } /* check for valid iocd address if 1st iocd */ - if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ - if (chp->chan_caw & 0x3) { /* must be word bounded */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_caw & 0x3) { /* must be word bounded */ sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw iocd bad address chan %02x caw %06x\n", chan, chp->chan_caw); /* the disk returns the bad iocl in sw1 */ chp->ccw_addr = chp->chan_caw & MASK24; /* set the bad IOCL address */ - chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ -//** uptr->SNS |= SNS_INAD; /* invalid address status */ - return 1; /* error return */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ +//** uptr->SNS |= SNS_INAD; /* invalid address status */ + return 1; /* error return */ } } loop: sim_debug(DEBUG_XIO, &cpu_dev, - "load_ccw @%06x entry chan_status[%04x] %04x\n", chp->chan_caw, chan, chp->chan_status); + "load_ccw @%06x @loop chan_status[%04x] %04x\n", chp->chan_caw, chan, chp->chan_status); /* Abort if we have any errors */ - if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ + if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw ERROR1 chan_status[%04x] %04x\n", chan, chp->chan_status); return 1; @@ -592,18 +592,18 @@ loop: /* Read in first CCW */ if (readfull(chp, chp->chan_caw, &word1) != 0) { /* read word1 from memory */ - chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw ERROR2 chan_status[%04x] %04x\n", chan, chp->chan_status); - return 1; /* error return */ + return 1; /* error return */ } /* Read in second CCW */ if (readfull(chp, chp->chan_caw+4, &word2) != 0) { /* read word2 from memory */ - chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ + chp->chan_status |= STATUS_PCHK; /* memory read error, program check */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw ERROR3 chan_status[%04x] %04x\n", chan, chp->chan_status); - return 1; /* error return */ + return 1; /* error return */ } sim_debug(DEBUG_XIO, &cpu_dev, @@ -611,35 +611,35 @@ loop: chp->chan_caw, chan, word1, word2); chp->chan_caw = (chp->chan_caw & 0xfffffc) + 8; /* point to next IOCD */ - chp->ccw_cmd = (word1 >> 24) & 0xff; /* set command from IOCD wd 1 */ + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set command from IOCD wd 1 */ /* Check if we had data chaining in previous iocd */ /* if we did, use previous cmd value */ - if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ - (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ + if (((chp->chan_info & INFO_SIOCD) == 0) && /* see if 1st IOCD in channel prog */ + (chp->ccw_flags & FLAG_DC)) { /* last IOCD have DC set? */ sim_debug(DEBUG_XIO, &cpu_dev, "ec_iocl @%06x DO DC, ccw_flags %04x cmd %02x\n", chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); } else - chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ - if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ - chp->chan_status |= STATUS_PCHK; /* bad, program check */ + if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ + chp->chan_status |= STATUS_PCHK; /* bad, program check */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status); - return 1; /* error return */ + return 1; /* error return */ } - chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/ + chp->ccw_count = word2 & 0xffff; /* get 16 bit byte count from IOCD WD 2*/ - if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ + if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ /* 1st command can not be a TIC */ if (chp->ccw_cmd == CMD_TIC) { - chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw TIC/NOP bad cmd chan_status[%04x] %04x\n", chan, chp->chan_status); - return 1; /* error return */ + return 1; /* error return */ } } @@ -652,49 +652,49 @@ loop: "load_ccw tic cmd bad address chan %02x tic caw %06x IOCD wd 1 %08x\n", chan, chp->chan_caw, word1); chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ - chp->chan_caw = word1 & MASK24; /* get new IOCD address */ - return 1; /* error return */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + return 1; /* error return */ } - tic_ok = 0; /* another tic not allowed */ - chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + tic_ok = 0; /* another tic not allowed */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw tic cmd ccw chan %02x tic caw %06x IOCD wd 1 %08x\n", chan, chp->chan_caw, word1); - goto loop; /* restart the IOCD processing */ + goto loop; /* restart the IOCD processing */ } - chp->chan_caw = word1 & MASK24; /* get new IOCD address */ - chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ + chp->chan_caw = word1 & MASK24; /* get new IOCD address */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid tic */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw TIC ERROR chan_status[%04x] %04x\n", chan, chp->chan_status); - return 1; /* error return */ + return 1; /* error return */ } /* Check if we had data chaining in previous iocd */ - if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ - ((chp->ccw_flags & FLAG_DC) == 0)) { /* last IOCD have DC set? */ + if ((chp->chan_info & INFO_SIOCD) || /* see if 1st IOCD in channel prog */ + ((chp->ccw_flags & FLAG_DC) == 0)) { /* last IOCD have DC set? */ sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw @%06x DO CMD No DC, ccw_flags %04x cmd %02x\n", chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); - docmd = 1; /* show we have a command */ + docmd = 1; /* show we have a command */ } /* Set up for this command */ - chp->ccw_flags = (word2 >> 16) & 0xfc00; /* get flags from bits 0-6 of WD 2 of IOCD */ - chp->chan_status = 0; /* clear status for next IOCD */ + chp->ccw_flags = (word2 >> 16) & 0xfc00; /* get flags from bits 0-6 of WD 2 of IOCD */ + chp->chan_status = 0; /* clear status for next IOCD */ /* make a 24 bit address */ - chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ + chp->ccw_addr = word1 & MASK24; /* set the data/seek address */ - if (chp->ccw_flags & FLAG_PCI) { /* do we have prog controlled int? */ - chp->chan_status |= STATUS_PCI; /* set PCI flag in status */ - irq_pend = 1; /* interrupt pending */ + if (chp->ccw_flags & FLAG_PCI) { /* do we have prog controlled int? */ + chp->chan_status |= STATUS_PCI; /* set PCI flag in status */ + irq_pend = 1; /* interrupt pending */ } /* validate parts of IOCD2 that is reserved, bits 5-15 */ if (word2 & 0x07ff0000) { - chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw bad IOCD2 chan_status[%04x] %04x\n", chan, chp->chan_status); - return 1; /* error return */ + return 1; /* error return */ } /* DC can only be used with a read/write cmd */ @@ -707,19 +707,19 @@ loop: } } - chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ + chp->chan_byte = BUFF_BUSY; /* busy & no bytes transferred yet */ sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw @%06x read docmd %01x addr %06x count %04x chan %04x ccw_flags %04x\n", chp->chan_caw, docmd, chp->ccw_addr, chp->ccw_count, chan, chp->ccw_flags); - if (docmd) { /* see if we need to process a command */ - DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ + if (docmd) { /* see if we need to process a command */ + DIB *dibp = dib_unit[chp->chan_dev]; /* get the DIB pointer */ - uptr = chp->unitptr; /* get the unit ptr */ + uptr = chp->unitptr; /* get the unit ptr */ if (dibp == 0 || uptr == 0) { - chp->chan_status |= STATUS_PCHK; /* program check if it is */ - return 1; /* if none, error */ + chp->chan_status |= STATUS_PCHK; /* program check if it is */ + return 1; /* if none, error */ } sim_debug(DEBUG_XIO, &cpu_dev, @@ -728,10 +728,10 @@ loop: /* call the device startcmd function to process the current command */ /* just replace device status bits */ - chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ + chp->chan_info &= ~INFO_CEND; /* show chan_end not called yet */ devstat = dibp->start_cmd(uptr, chan, chp->ccw_cmd); chp->chan_status = (chp->chan_status & 0xff00) | devstat; - chp->chan_info &= ~INFO_SIOCD; /* not first IOCD in channel prog */ + chp->chan_info &= ~INFO_SIOCD; /* not first IOCD in channel prog */ sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw @%06x after start_cmd chan %04x status %08x count %04x\n", @@ -739,20 +739,20 @@ loop: /* see if bad status */ if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { - chp->chan_status |= STATUS_CEND; /* channel end status */ - chp->ccw_flags = 0; /* no flags */ + chp->chan_status |= STATUS_CEND; /* channel end status */ + chp->ccw_flags = 0; /* no flags */ /* see if chan_end already called */ if (chp->chan_info & INFO_CEND) { sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw BUFF_NEXT ERROR chp %p chan_byte %04x\n", chp, chp->chan_byte); } else { - chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ sim_debug(DEBUG_EXP, &cpu_dev, "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 */ - chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ + RDYQ_Put(chp->chan_dev); /* queue us up */ + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ sim_debug(DEBUG_EXP, &cpu_dev, "load_ccw continue wait chsa %04x status %08x\n", chp->chan_dev, chp->chan_status); @@ -764,7 +764,7 @@ loop: /* we have good status */ /* TODO Test if chan_end called? */ if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { - uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ + uint16 chsa = GET_UADDR(uptr->u3); /* get channel & sub address */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw @%06x FIFO #%1x cmd complete chan %04x status %04x count %04x\n", @@ -776,37 +776,37 @@ loop: sim_debug(DEBUG_XIO, &cpu_dev, "load_ccw @%06x return, chan %04x status %04x count %04x irq_pend %1x\n", chp->chan_caw, chan, chp->chan_status, chp->ccw_count, irq_pend); - return 0; /* good return */ + return 0; /* good return */ } /* read byte from memory */ /* write to device */ int chan_read_byte(uint16 chsa, uint8 *data) { - CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ int byte; /* Abort if we have any errors */ - if (chp->chan_status & STATUS_ERROR) /* check channel error status */ - return 1; /* return error */ + if (chp->chan_status & STATUS_ERROR) /* check channel error status */ + return 1; /* return error */ - if (chp->chan_byte == BUFF_CHNEND) /* check for end of data */ - return 1; /* yes, return error */ + if (chp->chan_byte == BUFF_CHNEND) /* check for end of data */ + return 1; /* yes, return error */ - 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 */ + 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_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 */ + return 1; /* return error */ } else { /* we have data chaining, process iocl */ - if (load_ccw(chp, 1)) { /* process data chaining */ + if (load_ccw(chp, 1)) { /* process data chaining */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_read_byte with DC error, cnt %04x addr %06x chsa %04x\n", chp->ccw_count, chp->ccw_addr, chsa); - return 1; /* return error */ + return 1; /* return error */ } sim_debug(DEBUG_EXP, &cpu_dev, "chan_read_byte with DC IOCD loaded, cnt %04x addr %06x chsa %04x\n", @@ -814,79 +814,79 @@ int chan_read_byte(uint16 chsa, uint8 *data) } } /* get the next byte from memory */ - if (readbuff(chp)) /* read next char */ - return 1; /* return error */ + if (readbuff(chp)) /* read next char */ + return 1; /* return error */ /* get the byte of data */ - byte = chp->chan_buf; /* read byte from memory */ - *data = byte; /* return the data */ + byte = chp->chan_buf; /* read byte from memory */ + *data = byte; /* return the data */ sim_debug(DEBUG_DATA, &cpu_dev, "chan_read_byte transferred %02x\n", byte); - chp->ccw_addr += 1; /* next byte address */ - chp->ccw_count--; /* one char less to process */ - return 0; /* good return */ + chp->ccw_addr += 1; /* next byte address */ + chp->ccw_count--; /* one char less to process */ + return 0; /* good return */ } /* test end of write byte I/O (device read) */ int test_write_byte_end(uint16 chsa) { - CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ /* see if at end of buffer */ - if (chp->chan_byte == BUFF_CHNEND) /* check for end of data */ - return 1; /* return done */ + if (chp->chan_byte == BUFF_CHNEND) /* check for end of data */ + return 1; /* return done */ if (chp->ccw_count == 0) { - if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */ - chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */ - return 1; /* return done */ + if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */ + chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */ + return 1; /* return done */ } } - return 0; /* not done yet */ + return 0; /* not done yet */ } /* write byte to memory */ /* read from device */ int chan_write_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 chan = get_chan(chsa); /* get the channel number */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ /* Abort if we have any errors */ - if (chp->chan_status & STATUS_ERROR) /* check channel error status */ - return 1; /* return error */ + if (chp->chan_status & STATUS_ERROR) /* check channel error status */ + return 1; /* return error */ /* see if at end of buffer */ - if (chp->chan_byte == BUFF_CHNEND) { /* check for end of data */ + if (chp->chan_byte == BUFF_CHNEND) { /* check for end of data */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte BUFF_CHNEND ccw_flags %04x addr %06x cnt %04x\n", chp->ccw_flags, chp->ccw_addr, chp->ccw_count); /* if SLI not set, we have incorrect length */ if ((chp->ccw_flags & FLAG_SLI) == 0) { sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte 4 setting SLI ret\n"); - chp->chan_status |= STATUS_LENGTH; /* set SLI */ + chp->chan_status |= STATUS_LENGTH; /* set SLI */ } - return 1; /* return error */ + return 1; /* return error */ } if (chp->ccw_count == 0) { sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte ZERO chan %04x ccw_count %04x addr %06x\n", chan, chp->ccw_count, chp->ccw_addr); - if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */ + if ((chp->ccw_flags & FLAG_DC) == 0) { /* see if we have data chaining */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte no DC ccw_flags %04x\n", chp->ccw_flags); - chp->chan_status |= STATUS_CEND; /* no, end of data */ - chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */ + chp->chan_status |= STATUS_CEND; /* no, end of data */ + chp->chan_byte = BUFF_CHNEND; /* thats all the data we want */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte BUFF_CHNEND chp %p chan_byte %04x\n", chp, chp->chan_byte); - return 1; /* return done error */ + return 1; /* return done error */ } else { /* we have data chaining, process iocl */ - if (load_ccw(chp, 1)) { /* process data chaining */ + if (load_ccw(chp, 1)) { /* process data chaining */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte with DC error, cnt %04x addr %06x chan %04x\n", chp->ccw_count, chp->ccw_addr, chan); - return 1; /* return error */ + return 1; /* return error */ } sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte with DC IOCD loaded cnt %04x addr %06x chan %04x\n", @@ -896,52 +896,52 @@ int chan_write_byte(uint16 chsa, uint8 *data) /* we have data byte to write to chp->ccw_addr */ /* see if we want to skip writing data to memory */ if (chp->ccw_flags & FLAG_SKIP) { - chp->ccw_count--; /* decrement skip count */ - chp->chan_byte = BUFF_BUSY; /* busy, but no data */ + chp->ccw_count--; /* decrement skip count */ + chp->chan_byte = BUFF_BUSY; /* busy, but no data */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte1 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte); if ((chp->ccw_cmd & 0xff) == CMD_RDBWD) - chp->ccw_addr--; /* backward */ + chp->ccw_addr--; /* backward */ else - chp->ccw_addr++; /* forward */ + chp->ccw_addr++; /* forward */ sim_debug(DEBUG_EXP, &cpu_dev, "chan_write_byte SKIP ret addr %08x cnt %04x\n", chp->ccw_addr, chp->ccw_count); return 0; } - chp->chan_buf = *data; /* get data byte */ - if (writebuff(chp)) /* write the byte */ + chp->chan_buf = *data; /* get data byte */ + if (writebuff(chp)) /* write the byte */ return 1; - chp->ccw_count--; /* reduce count */ - chp->chan_byte = BUFF_BUSY; /* busy, but no data */ + chp->ccw_count--; /* reduce count */ + chp->chan_byte = BUFF_BUSY; /* busy, but no data */ sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_write_byte2 BUFF_BUSY chp %p chan_byte %04x\n", chp, chp->chan_byte); - if ((chp->ccw_cmd & 0xff) == CMD_RDBWD) /* see if reading backwards */ - chp->ccw_addr -= 1; /* no, use previous address */ + if ((chp->ccw_cmd & 0xff) == CMD_RDBWD) /* see if reading backwards */ + chp->ccw_addr -= 1; /* no, use previous address */ else - chp->ccw_addr += 1; /* yes, use next address */ + chp->ccw_addr += 1; /* yes, use next address */ return 0; } /* post wakeup interrupt for specified async line */ void set_devwake(uint16 chsa, uint16 flags) { - uint32 stwd1, stwd2; /* words 1&2 of stored status */ + uint32 stwd1, stwd2; /* words 1&2 of stored status */ /* put sub address in byte 0 */ - stwd1 = (chsa & 0xff) << 24; /* subaddress and IOCD address to SW 1 */ + stwd1 = (chsa & 0xff) << 24; /* subaddress and IOCD address to SW 1 */ /* save 16 bit channel status and residual byte count in SW 2 */ stwd2 = (uint32)flags << 16; if ((FIFO_Put(chsa, stwd1) == -1) || (FIFO_Put(chsa, stwd2) == -1)) { sim_debug(DEBUG_EXP, &cpu_dev, "set_devwake FIFO Overflow ERROR on chsa %04x\n", chsa); } - irq_pend = 1; /* wakeup controller */ + irq_pend = 1; /* wakeup controller */ } /* post interrupt for specified channel */ void set_devattn(uint16 chsa, uint16 flags) { - CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ if (chp == NULL) { /* can not do anything, so just return */ @@ -961,15 +961,15 @@ void set_devattn(uint16 chsa, uint16 flags) /* channel operation completed */ void chan_end(uint16 chsa, uint16 flags) { uint16 tstat, tcnt; - CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ + CHANP *chp = find_chanp_ptr(chsa); /* get channel prog pointer */ sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end entry chsa %04x flags %04x status %04x cmd %02x\n", chsa, flags, chp->chan_status, chp->ccw_cmd); - chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */ - chp->chan_status |= STATUS_CEND; /* set channel end */ - chp->chan_status |= ((uint16)flags); /* add in the callers flags */ + chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */ + chp->chan_status |= STATUS_CEND; /* set channel end */ + chp->chan_status |= ((uint16)flags); /* add in the callers flags */ /* read/write must have none-zero byte count */ /* all others can be zero, except NOP, which must be 0 */ @@ -983,7 +983,7 @@ void chan_end(uint16 chsa, uint16 flags) { sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end setting SLI chsa %04x count %04x ccw_flags %04x status %04x\n", chsa, chp->ccw_count, chp->ccw_flags, chp->chan_status); - chp->ccw_flags = 0; /* no iocl flags */ + chp->ccw_flags = 0; /* no iocl flags */ } } @@ -993,7 +993,7 @@ void chan_end(uint16 chsa, uint16 flags) { /* no flags for attention status */ if (flags & (SNS_ATTN|SNS_UNITCHK|SNS_UNITEXP)) { - chp->ccw_flags = 0; /* no flags */ + chp->ccw_flags = 0; /* no flags */ } sim_debug(DEBUG_DETAIL, &cpu_dev, @@ -1002,28 +1002,28 @@ void chan_end(uint16 chsa, uint16 flags) { /* test for device or controller end */ if (chp->chan_status & (STATUS_DEND|STATUS_CEND)) { - chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */ + chp->chan_byte = BUFF_BUSY; /* we are empty & still busy now */ sim_debug(DEBUG_XIO, &cpu_dev, "chan_end FIFO #%1x IOCL done chsa %04x ccw_flags %04x status %04x\n", FIFO_Num(chsa), chsa, chp->ccw_flags, chp->chan_status); /* handle a PPCI here. DC is done and maybe have CC */ if ((chp->chan_status & STATUS_PCI) && (chp->ccw_flags & FLAG_CC)) { - chp->chan_status &= ~STATUS_PCI; /* done with PCI */ - tstat = chp->chan_status; /* save status */ - tcnt = chp->ccw_count; /* save count */ - chp->chan_status = STATUS_PCI; /* set PCI status */ - chp->ccw_count = 0; /* zero count */ - store_csw(chp); /* store the status */ - chp->chan_status = tstat; /* restore status */ - chp->ccw_count = tcnt; /* restore count */ + chp->chan_status &= ~STATUS_PCI; /* done with PCI */ + tstat = chp->chan_status; /* save status */ + tcnt = chp->ccw_count; /* save count */ + chp->chan_status = STATUS_PCI; /* set PCI status */ + chp->ccw_count = 0; /* zero count */ + store_csw(chp); /* store the status */ + chp->chan_status = tstat; /* restore status */ + chp->ccw_count = tcnt; /* restore count */ sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end done PCI chsa %04x ccw_flags %04x stat %04x cnt %04x\n", chsa, chp->ccw_flags, tstat, tcnt); } /* If channel end, check if we should continue */ - if (chp->ccw_flags & FLAG_CC) { /* command chain flag */ + if (chp->ccw_flags & FLAG_CC) { /* command chain flag */ /* we have channel end and CC flag, continue channel prog */ sim_debug(DEBUG_DETAIL, &cpu_dev, "chan_end chan end & CC chsa %04x status %04x\n", @@ -1033,18 +1033,18 @@ void chan_end(uint16 chsa, uint16 flags) { "chan_end dev end & CC chsa %04x status %04x IOCLA %08x\n", chsa, chp->chan_status, chp->chan_caw); /* Queue us to continue from cpu level */ - chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ sim_debug(DEBUG_EXP, &cpu_dev, - "chan_end set RDYQ %04x No CC BUFF_NEXT chp %p chan_byte %04x\n", + "chan_end set RDYQ %04x Have CC BUFF_NEXT chp %p chan_byte %04x\n", chsa, chp, chp->chan_byte); - RDYQ_Put(chsa); /* queue us up */ - chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ + RDYQ_Put(chsa); /* queue us up */ + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ } /* just return */ goto goout; } else { /* we have channel end and no CC flag, continue channel prog */ - UNIT *uptr = chp->unitptr; /* get the unit ptr */ + UNIT *uptr = chp->unitptr; /* get the unit ptr */ DEVICE *dptr = get_dev(uptr); uint16 chsa = GET_UADDR(uptr->u3); int unit = (uptr-dptr->units); /* get the UNIT number */ @@ -1071,29 +1071,29 @@ void chan_end(uint16 chsa, uint16 flags) { chsa, chp->chan_status); } /* store the status in channel FIFO to continue from cpu level */ - chp->chan_byte = BUFF_DONE; /* we are done */ - store_csw(chp); /* store the status */ + chp->chan_byte = BUFF_DONE; /* we are done */ + store_csw(chp); /* store the status */ /* change chan_byte to BUFF_POST */ - chp->chan_byte = BUFF_POST; /* show done with data */ - chp->ccw_cmd = 0; /* no command anymore */ + chp->chan_byte = BUFF_POST; /* show done with data */ + chp->ccw_cmd = 0; /* no command anymore */ if (chp->chan_status & STATUS_ERROR) { /* check channel error status */ - qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ + qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ /* we have an error, so delete all other IOCLQ entries */ while ((dibp->ioclq_ptr != NULL) && (qp != NULL) && IOCLQ_Get(qp, &iocla) == SCPE_OK) { sim_debug(DEBUG_EXP, &cpu_dev, "$$ CHEND removed IOCL from IOCLQ processing chsa %04x iocla %06x\n", chsa, iocla); } - chp->chan_status = 0; /* no channel status yet */ + chp->chan_status = 0; /* no channel status yet */ } else /* no error, see if we have a queued IOCL to start */ if ((dibp->ioclq_ptr != NULL) && (qp != NULL) && IOCLQ_Get(qp, &iocla) == SCPE_OK) { /* channel not busy and ready to go, so start a new command */ - chp->chan_status = 0; /* no channel status yet */ - chp->chan_caw = iocla; /* get iocla address in memory */ + chp->chan_status = 0; /* no channel status yet */ + chp->chan_caw = iocla; /* get iocla address in memory */ /* added 09/25/20 to fix hangs in iocl processing */ - chp->ccw_flags = 0; /* clear flags */ + chp->ccw_flags = 0; /* clear flags */ /* set status words in memory to first IOCD information */ sim_debug(DEBUG_CMD, &cpu_dev, @@ -1102,18 +1102,18 @@ void chan_end(uint16 chsa, uint16 flags) { /* We are queueing the SIO */ /* 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 */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ 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 */ + RDYQ_Put(chsa); /* queue us up */ 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)); /* this is the first IOCD for the SIO */ - chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ + chp->chan_qwait = QWAIT; /* run 25 instructions before starting iocl */ } } } @@ -1122,7 +1122,7 @@ goout: "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 */ - irq_pend = 1; /* flag to test for int condition */ + irq_pend = 1; /* flag to test for int condition */ } /* post the device status from the channel FIFO into memory */ @@ -1130,11 +1130,11 @@ goout: /* rstat are the bits to remove from status */ int16 post_csw(CHANP *chp, uint32 rstat) { - uint32 chsa = chp->chan_dev; /* get ch/sa information */ - uint32 incha = chp->chan_inch_addr; /* get inch status buffer address */ - uint32 sw1, sw2; /* status words */ + uint32 chsa = chp->chan_dev; /* get ch/sa information */ + uint32 incha = chp->chan_inch_addr; /* get inch status buffer address */ + uint32 sw1, sw2; /* status words */ - irq_pend = 1; /* flag to test for int condition */ + irq_pend = 1; /* flag to test for int condition */ /* check channel FIFO for status to post */ if ((FIFO_Num(chsa)) && ((FIFO_Get(chsa, &sw1) == 0) && (FIFO_Get(chsa, &sw2) == 0))) { @@ -1145,7 +1145,7 @@ int16 post_csw(CHANP *chp, uint32 rstat) sim_debug(DEBUG_EXP, &cpu_dev, "post_csw %04x READ FIFO #%1x inch %06x invalid chan_icb %06x\n", chsa, FIFO_Num(chsa), incha, chan_icb); - return 0; /* no status to post */ + return 0; /* no status to post */ } if (chp->chan_byte != BUFF_POST) { sim_debug(DEBUG_EXP, &cpu_dev, @@ -1153,29 +1153,29 @@ int16 post_csw(CHANP *chp, uint32 rstat) chsa, chp, chp->chan_byte, FIFO_Num(chsa), incha, chan_icb); } /* remove user specified bits */ - sw2 &= ~rstat; /* remove bits */ + sw2 &= ~rstat; /* remove bits */ /* we have status to post, do it now */ /* save the status double word to memory */ - WMW(incha, sw1); /* save sa & IOCD address in status WD 1 loc */ - WMW(incha+4, sw2); /* save status and residual cnt in status WD 2 loc */ + WMW(incha, sw1); /* save sa & IOCD address in status WD 1 loc */ + WMW(incha+4, sw2); /* save status and residual cnt in status WD 2 loc */ /* now store the status dw address into word 5 of the ICB for the channel */ - WMW(chan_icb+20, incha|BIT1); /* post sw addr in ICB+5w & set CC2 in INCH addr */ + WMW(chan_icb+20, incha|BIT1); /* post sw addr in ICB+5w & set CC2 in INCH addr */ sim_debug(DEBUG_IRQ, &cpu_dev, "post_csw %04x READ FIFO #%1x inch %06x chan_icb %06x sw1 %08x sw2 %08x\n", chsa, FIFO_Num(chsa), incha, chan_icb, sw1, sw2); - return 1; /* show we posted status */ + return 1; /* show we posted status */ } sim_debug(DEBUG_DETAIL, &cpu_dev, "post_csw %04x chp %p READ FIFO #%1x inch %06x No Status chan_byte %02x\n", chsa, chp, FIFO_Num(chsa), incha, chp->chan_byte); - return 0; /* no status to post */ + return 0; /* no status to post */ } /* store the device status into the status FIFO for the channel */ void store_csw(CHANP *chp) { - uint32 stwd1, stwd2; /* words 1&2 of stored status */ - uint32 chsa = chp->chan_dev; /* get ch/sa information */ + 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 */ @@ -1191,15 +1191,15 @@ void store_csw(CHANP *chp) "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 */ - INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */ - irq_pend = 1; /* wakeup controller */ + INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */ + 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 */ + 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 */ @@ -1216,8 +1216,8 @@ void push_csw(CHANP *chp) "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 */ + INTS[chp->chan_int] |= INTS_REQ; /* request an interrupt for channel */ + irq_pend = 1; /* wakeup controller */ } /* check an XIO operation */ @@ -1225,37 +1225,37 @@ void push_csw(CHANP *chp) /* suba unit address within channel 0-ff */ /* Condition codes to return 0-f as specified above */ t_stat checkxio(uint16 lchsa, uint32 *status) { - DIB *dibp; /* device information pointer */ - UNIT *uptr; /* pointer to unit in channel */ - CHANP *chp; /* channel program pointer */ - uint16 lchan = get_chan(lchsa); /* get the logical channel number */ - DEVICE *dptr; /* DEVICE pointer */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + CHANP *chp; /* channel program pointer */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + DEVICE *dptr; /* DEVICE pointer */ uint32 inta; uint32 spadent; - uint16 rchan, rchsa; /* the real channel number */ + uint16 rchan, rchsa; /* the real channel number */ /* get the device entry for the logical channel in SPAD */ - spadent = SPAD[lchan]; /* get spad device entry for logical channel */ - rchan = (spadent & 0x7f00) >> 8; /* get real channel */ - rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */ - dibp = dib_chan[rchan]; /* get DIB pointer for channel */ + dibp = dib_chan[rchan]; /* get DIB pointer for channel */ if (dibp == 0) goto nothere; - chp = dibp->chan_prg; /* find the chanp pointer */ + chp = dibp->chan_prg; /* find the chanp pointer */ if (chp == 0) goto nothere; - uptr = dibp->units; /* find pointer to 1st unit on channel */ - if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ + uptr = dibp->units; /* find pointer to 1st unit on channel */ + if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ nothere: - *status = CC3BIT; /* not found, so CC3 */ + *status = CC3BIT; /* not found, so CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "checkxio lchsa %04x rchan %04x is not found, CC3 return\n", lchsa, rchan); - return SCPE_OK; /* not found, CC3 */ + return SCPE_OK; /* not found, CC3 */ } - inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ - chp->chan_int = inta; /* make sure it is set in channel */ - dptr = get_dev(uptr); /* pointer to DEVICE structure */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + dptr = get_dev(uptr); /* pointer to DEVICE structure */ /* is device or unit marked disabled? */ dptr = get_dev(uptr); @@ -1263,31 +1263,31 @@ nothere: /* 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 */ - *status = CC1BIT; /* CCs = 1, not busy */ + (DEV_TYPE(dptr) == DEV_TAPE)) { /* see if this is a tape */ + *status = CC1BIT; /* CCs = 1, not busy */ sim_debug(DEBUG_EXP, &cpu_dev, "checkxio rchsa %04x device/unit not enabled, CC1 returned\n", rchsa); } else { - *status = CC3BIT; /* not attached, so error CC3 */ + *status = CC3BIT; /* not attached, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "checkxio rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); } - return SCPE_OK; /* Not found CC3/CC1 */ + return SCPE_OK; /* Not found CC3/CC1 */ } /* try this as MFP says it returns 0 on OK */ if (dptr->flags & DEV_CHAN) - *status = 0; /* CCs = 0, OK return */ + *status = 0; /* CCs = 0, OK return */ else /* return CC1 for non iop/mfp devices */ -//1003 *status = CC1BIT; /* CCs = 1, not busy */ - *status = 0; /* CCs = 0, OK return */ +//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); - return SCPE_OK; /* No CC's all OK */ + return SCPE_OK; /* No CC's all OK */ } /* SIO CC status returned to caller */ @@ -1317,12 +1317,12 @@ nothere: /* suba unit address within channel 0-ff */ /* Condition codes to return 0-f as specified above */ t_stat startxio(uint16 lchsa, uint32 *status) { - DIB *dibp; /* device information pointer */ - UNIT *uptr; /* pointer to unit in channel */ - uint32 chan_icb; /* Interrupt level context block address */ - uint32 iocla; /* I/O channel IOCL address int ICB */ - CHANP *chp; /* channel program pointer */ - uint16 lchan = get_chan(lchsa); /* get the logical channel number */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + uint32 chan_icb; /* Interrupt level context block address */ + uint32 iocla; /* I/O channel IOCL address int ICB */ + CHANP *chp; /* channel program pointer */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint16 chsa; uint32 tempa, inta, spadent, chan, incha; uint32 word1, word2, cmd; @@ -1333,52 +1333,52 @@ t_stat startxio(uint16 lchsa, uint32 *status) { DEVICE *dptr; /* get the device entry for the logical channel in SPAD */ - spadent = SPAD[lchan]; /* get spad device entry for logical channel */ - inta = ((~spadent)>>16)&0x7f; /* get interrupt level */ - chan = (spadent & 0x7f00) >> 8; /* get real channel */ - chsa = (chan << 8) | (lchsa & 0xff); /* merge sa to real channel */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + inta = ((~spadent)>>16)&0x7f; /* get interrupt level */ + chan = (spadent & 0x7f00) >> 8; /* get real channel */ + chsa = (chan << 8) | (lchsa & 0xff); /* merge sa to real channel */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio entry inta %02x lchan %04x spadent %08x rchsa %04x\n", inta, lchan, spadent, chsa); - dibp = dib_unit[chsa & 0x7f00]; /* get the device information pointer */ - uptr = find_unit_ptr(chsa & 0x7f00); /* get unit 0 unit pointer */ + dibp = dib_unit[chsa & 0x7f00]; /* get the device information pointer */ + uptr = find_unit_ptr(chsa & 0x7f00); /* get unit 0 unit pointer */ if (uptr != NULL) { - dptr = get_dev(uptr); /* get device address */ + dptr = get_dev(uptr); /* get device address */ if ((dptr != NULL) && - (DEV_TYPE(dptr) == DEV_DISK)) { /* see if this is a disk */ - chsa = chsa & 0x7ffe; /* clear the odd subaddress */ + (DEV_TYPE(dptr) == DEV_DISK)) { /* see if this is a disk */ + chsa = chsa & 0x7ffe; /* clear the odd subaddress */ } } - chan_icb = find_int_icb(lchsa); /* Interrupt level context block address */ + chan_icb = find_int_icb(lchsa); /* Interrupt level context block address */ #ifdef DEBUG_DISK - itva = SPAD[0xf1] + (inta<<2); /* int vector address */ - chan_icb = RMW(itva); /* Interrupt context block addr */ - iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ - incha = RMW(chan_icb+20); /* post inch addr in ICB+5w */ + itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + incha = RMW(chan_icb+20); /* post inch addr in ICB+5w */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio itva %03x icba %04x iocla %06x incha %06x IOCD1 %08x IOCD2 %08x\n", itva, chan_icb, iocla, incha, RMW(iocla), RMW(iocla+4)); #endif /* check if we have a valid unit */ - chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ if (chp == 0) goto missing; - dibp = dib_unit[chsa]; /* get the DIB pointer */ + dibp = dib_unit[chsa]; /* get the DIB pointer */ if (dibp == 0) goto missing; - uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ + uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ - if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ + if (uptr == 0) { /* if no dib or unit ptr, CC3 on return */ missing: - *status = CC3BIT; /* not found, so CC3 */ + *status = CC3BIT; /* not found, so CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "startxio chsa %04x is not found, CC3 returned\n", chsa); - return SCPE_OK; /* not found, CC3 */ + return SCPE_OK; /* not found, CC3 */ } - inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ - chp->chan_int = inta; /* make sure it is set in channel */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ sim_debug(DEBUG_EXP, &cpu_dev, "startxio chsa %04x chp %p flags UNIT_ATTABLE %1x UNIT_ATT %1x UNIT_DIS %1x\n", @@ -1390,8 +1390,8 @@ missing: if ((dptr->flags & DEV_DIS) || (uptr->flags & UNIT_DIS)) { sim_debug(DEBUG_EXP, &cpu_dev, "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 */ + *status = CC3BIT; /* not attached, so error CC3 */ + return SCPE_OK; /* not found, CC3 */ } #ifndef FOR_DEBUG @@ -1418,30 +1418,30 @@ missing: /* 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 */ + 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 */ + 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 */ + 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 */ - uint16 tcnt = chp->ccw_count; /* save count */ + uint16 tstat = chp->chan_status; /* save status */ + uint16 tcnt = chp->ccw_count; /* save count */ DEVICE *dptr = get_dev(uptr); sim_debug(DEBUG_EXP, &cpu_dev, @@ -1450,19 +1450,19 @@ missing: #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 */ - *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ + (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ + *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ /* 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 */ -//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 */ + chp->ccw_count = 0; /* zero count */ +//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, "startxio done BUSY/INT 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 */ + return SCPE_OK; /* just busy CC3&CC4 */ } #endif #ifndef ADD_03112021 @@ -1470,11 +1470,11 @@ missing: "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 */ + *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 */ + return SCPE_OK; /* just busy CC3&CC4 */ #endif } #endif /*TRY_03132021*/ @@ -1485,66 +1485,66 @@ missing: /* We have to validate all the addresses and parameters for the SIO */ /* before calling load_ccw which does it again for each IOCL step */ - iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ - word1 = RMW(iocla & MASK24); /* get 1st IOCL word */ - word2 = RMW((iocla + 4) & MASK24); /* get 2nd IOCL word */ - cmd = (word1 >> 24) & 0xff; /* get channel cmd from IOCL */ - chp = find_chanp_ptr(chsa&0x7f00); /* find the parent chanp pointer */ - incha = chp->chan_inch_addr; /* get inch address */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + word1 = RMW(iocla & MASK24); /* get 1st IOCL word */ + word2 = RMW((iocla + 4) & MASK24); /* get 2nd IOCL word */ + cmd = (word1 >> 24) & 0xff; /* get channel cmd from IOCL */ + chp = find_chanp_ptr(chsa&0x7f00); /* find the parent chanp pointer */ + incha = chp->chan_inch_addr; /* get inch address */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio do normal chsa %04x iocla %06x incha %06x IOCD1 %08x IOCD2 %08x\n", chsa, iocla, incha, RMW(iocla), RMW(iocla+4)); - iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ - chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio test chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", chsa, iocla, RMW(iocla), RMW(iocla+4)); - iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ SIO %04x %04x cmd %02x ccw_flags %04x\n", chsa, chan, cmd, word2>>16); /* determine if channel DIB has a pre startio command processor */ - if (dibp->pre_io != NULL) { /* NULL if no startio function */ - DEVICE *dptr = get_dev(uptr); /* get device ptr */ - int unit = uptr-dptr->units; /* get unit number */ + if (dibp->pre_io != NULL) { /* NULL if no startio function */ + DEVICE *dptr = get_dev(uptr); /* get device ptr */ + int unit = uptr-dptr->units; /* get unit number */ /* call the device controller to get prestart_io status */ - tempa = dibp->pre_io(uptr, chan); /* get status from device */ + tempa = dibp->pre_io(uptr, chan); /* get status from device */ /* SCPE_OK if unit not busy and IOCLQ is not full */ /* SNS_BSY if unit IOCLQ is full */ /* SNS_SMS if unit IOCLQ is not full, but device is busy */ - if (tempa == SNS_BSY) { /* see if sub channel status is ready */ + if (tempa == SNS_BSY) { /* see if sub channel status is ready */ /* The device must be busy or something, but it is not ready. Return busy */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio pre_io call return busy1 chan %04x cstat %08x\n", chan, tempa); - *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ - return SCPE_OK; /* just busy or something, CC3|CC4 */ + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ } - if (tempa == SNS_SMS) { /* see if sub channel status is ready */ - if (dibp->ioclq_ptr == NULL) { /* see if device has IOCL queue */ + if (tempa == SNS_SMS) { /* see if sub channel status is ready */ + if (dibp->ioclq_ptr == NULL) { /* see if device has IOCL queue */ /* The device must be busy or something, but it is not ready. Return busy */ /* This should not happen for SNS_SMS status */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio pre_io call return busy2 chan %04x cstat %08x\n", chan, tempa); - *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ - return SCPE_OK; /* just busy or something, CC3|CC4 */ + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ } /* device has IOCLQ, queue up the iocla */ if (IOCLQ_Put(&dibp->ioclq_ptr[unit], iocla) == -1) { sim_debug(DEBUG_XIO, &cpu_dev, "startxio IOCLQ_Put error return chsa %04x unit %02x\n", chsa, unit); - *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ - return SCPE_OK; /* just busy or something, CC3|CC4 */ + *status = CC3BIT|CC4BIT; /* sub channel busy, so CC3|CC4 */ + return SCPE_OK; /* just busy or something, CC3|CC4 */ } sim_debug(DEBUG_XIO, &cpu_dev, "startxio IOCLQ_Put call sucessful count %02x chan %04x unit %02x\n", IOCLQ_Num(&dibp->ioclq_ptr[unit]), chan, unit); - *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ - return SCPE_OK; /* CC1 all OK */ + *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ + return SCPE_OK; /* CC1 all OK */ } /* device is not busy */ sim_debug(DEBUG_XIO, &cpu_dev, @@ -1554,26 +1554,26 @@ missing: /* 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 */ - uint16 tcnt = chp->ccw_count; /* save count */ + uint16 tstat = chp->chan_status; /* save status */ + uint16 tcnt = chp->ccw_count; /* save count */ 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); /* everyone else just gets a busy return */ - *status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */ + *status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */ sim_debug(DEBUG_XIO, &cpu_dev, "startxio done 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 */ + return SCPE_OK; /* just busy CC3&CC4 */ } /* channel not busy and ready to go, so start a new command */ - chp->chan_int = inta; /* save interrupt level in channel */ - chp->chan_status = 0; /* no channel status yet */ - chp->chan_caw = iocla; /* get iocla address in memory */ + chp->chan_int = inta; /* save interrupt level in channel */ + chp->chan_status = 0; /* no channel status yet */ + chp->chan_caw = iocla; /* get iocla address in memory */ /* added 09/25/20 to fix hangs in iocl processing */ - chp->ccw_flags = 0; /* clear flags */ + chp->ccw_flags = 0; /* clear flags */ /* set status words in memory to first IOCD information */ sim_debug(DEBUG_XIO, &cpu_dev, @@ -1582,74 +1582,78 @@ missing: /* We are queueing the SIO */ /* 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 */ - RDYQ_Put(chsa); /* queue us up */ + chp->chan_byte = BUFF_NEXT; /* have main pick us up */ + chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ + RDYQ_Put(chsa); /* queue us up */ sim_debug(DEBUG_XIO, &cpu_dev, "$$$ SIO queued chsa %04x iocla %06x IOCD1 %08x IOCD2 %08x\n", chsa, iocla, RMW(iocla), RMW(iocla+4)); -// 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 */ + chp->chan_qwait = QWAIT25; /* run 25 instructions before starting iocl */ - *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ + dptr = get_dev(uptr); + if ((dptr != NULL) && + (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ +// chp->chan_qwait = QWAIT20; /* run 25 instructions before starting iocl */ + chp->chan_qwait = QWAIT25; /* run 25 instructions before starting iocl */ + } + + *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", chsa, chp->chan_status, iocla, *status); - return SCPE_OK; /* No CC's all OK */ + return SCPE_OK; /* No CC's all OK */ } /* TIO - I/O status */ -t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ - DIB *dibp; /* device information pointer */ - UNIT *uptr; /* pointer to unit in channel */ - uint32 chan_icb; /* Interrupt level context block address */ - CHANP *chp; /* Channel prog pointers */ - DEVICE *dptr; /* Device ptr */ +t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ + DIB *dibp; /* device information pointer */ + 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 */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 spadent; - uint16 rchan, rchsa; /* the real channel number, chsa */ + uint16 rchan, rchsa; /* the real channel number, chsa */ - lchsa &= 0x7f00; /* use just chan and sa of 0 */ + lchsa &= 0x7f00; /* use just chan and sa of 0 */ /* get the real channel entry for the logical channel in SPAD */ - spadent = SPAD[lchan]; /* get spad device entry for logical channel */ - rchsa = (spadent & 0x7f00); /* get real channel suba of zero */ - rchan = rchsa >> 8; /* get real channel */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchsa = (spadent & 0x7f00); /* get real channel suba of zero */ + rchan = rchsa >> 8; /* get real channel */ /* get the device entry for the channel in SPAD */ - dibp = dib_chan[rchan]; /* get the DIB pointer */ - chp = find_chanp_ptr(rchan << 8); /* find the device chanp pointer */ + dibp = dib_chan[rchan]; /* get the DIB pointer */ + chp = find_chanp_ptr(rchan << 8); /* find the device chanp pointer */ - if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ - *status = CC3BIT; /* not found, so CC3 */ + 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, "TIO lchsa %04x rchsa %04x device not present, CC3 returned\n", lchsa, rchsa); - return SCPE_OK; /* Not found, CC3 */ + return SCPE_OK; /* Not found, CC3 */ } - uptr = chp->unitptr; /* get the unit 0 ptr */ + uptr = chp->unitptr; /* get the unit 0 ptr */ /* 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 */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "TIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); - return SCPE_OK; /* Not found, CC3 */ + return SCPE_OK; /* Not found, CC3 */ } /* the XIO opcode processing software has already checked for F class */ - inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ - chp->chan_int = inta; /* make sure it is set in channel */ - itva = SPAD[0xf1] + (inta<<2); /* int vector address */ - chan_icb = RMW(itva); /* Interrupt context block addr */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + 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 rchsa %04x\n", SPAD[inta+0x80], chan_icb, inta, rchsa); - incha = chp->chan_inch_addr; /* get inch address */ + incha = chp->chan_inch_addr; /* get inch address */ /* see if any status ready to post */ if (FIFO_Num(rchsa)) { @@ -1664,101 +1668,101 @@ t_stat testxio(uint16 lchsa, uint32 *status) { /* test XIO */ /* 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 */ + chp->chan_byte = BUFF_DONE; /* show done & not busy */ } sim_debug(DEBUG_XIO, &cpu_dev, "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 */ + 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, "TIO rchsa %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", rchsa, FIFO_Num(rchsa), 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 TIO, so no CC */ - return SCPE_OK; /* No CC's all OK */ + WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = 0; /* no status stored from TIO, so no CC */ + return SCPE_OK; /* No CC's all OK */ } } /* nothing going on, so say all OK */ - WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ - INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ + WMW(chan_icb+20, 0); /* post sw addr 0 in ICB+5w & reset CCs */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ + INTS[inta] &= ~INTS_REQ; /* clear any level request if no status */ sim_debug(DEBUG_XIO, &cpu_dev, "$$$ TIO END rchsa %04x rchan %04x ccw_flags %04x chan_stat %04x CCs %08x\n", rchsa, rchan, chp->ccw_flags, chp->chan_status, *status); - return SCPE_OK; /* No CC's all OK */ + return SCPE_OK; /* No CC's all OK */ } /* Stop XIO */ -t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ - DIB *dibp; /* device information pointer */ - UNIT *uptr; /* pointer to unit in channel */ - 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 */ +t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ + DIB *dibp; /* device information pointer */ + UNIT *uptr; /* pointer to unit in channel */ + 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 */ + uint16 rchan, rchsa; /* the real channel number, chsa */ /* get the device entry for the logical channel in SPAD */ - spadent = SPAD[lchan]; /* get spad device entry for logical channel */ - rchan = (spadent & 0x7f00) >> 8; /* get real channel */ - rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* get the read chan & suba */ /* get the device entry for the logical channel in SPAD */ - dibp = dib_unit[rchsa]; /* get the DIB pointer */ - chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */ + dibp = dib_unit[rchsa]; /* get the DIB pointer */ + chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */ - if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ - *status = CC3BIT; /* not found, so CC3 */ + 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, "STPIO test 1 rchsa %04x device not present, CC3 returned\n", rchsa); - return SCPE_OK; /* not found CC3 */ + return SCPE_OK; /* not found CC3 */ } - uptr = chp->unitptr; /* get the unit ptr */ + uptr = chp->unitptr; /* get the unit ptr */ /* 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 */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "STPIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); - return SCPE_OK; /* Not found, CC3 */ + return SCPE_OK; /* Not found, CC3 */ } /* the XIO opcode processing software has already checked for F class */ - inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ - chp->chan_int = inta; /* make sure it is set in channel */ - itva = SPAD[0xf1] + (inta<<2); /* int vector address */ - chan_icb = RMW(itva); /* Interrupt context block addr */ - iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ + itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ sim_debug(DEBUG_CMD, &cpu_dev, "STPIO busy test rchsa %04x cmd %02x ccw_flags %04x IOCD1 %08x IOCD2 %08x\n", rchsa, chp->ccw_cmd, chp->ccw_flags, M[iocla>>2], M[(iocla+4)>>2]); if ((chp->chan_byte & BUFF_BUSY) == 0) { /* the channel is not busy, so return OK */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ STPIO not busy return 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 */ + return SCPE_OK; /* No CC's all OK */ } /* the channel is busy, so process */ /* see if we have a stopio device entry */ - if (dibp->stop_io != NULL) { /* NULL if no stop_io function */ + if (dibp->stop_io != NULL) { /* NULL if no stop_io function */ /* call the device controller to get stop_io status */ - int32 tempa = dibp->stop_io(uptr); /* get status from device */ + int32 tempa = dibp->stop_io(uptr); /* get status from device */ /* test for SCPE_IOERR */ - if (tempa != 0) { /* sub channel has status ready */ + if (tempa != 0) { /* sub channel has status ready */ /* The device I/O has been terminated and status stored. */ sim_debug(DEBUG_XIO, &cpu_dev, "stopxio stop_io call return ERROR FIFO #%1x rchan %04x retstat %08x cstat %08x\n", @@ -1767,12 +1771,12 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ /* chan_end is called in stop 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 */ + 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 */ + INTS[inta] &= ~INTS_REQ; /* clear any level request */ + *status = CC2BIT; /* status stored */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ STOPXIO END2 rchsa %04x rchan %04x cmd %02x ccw_flags %04x status %04x\n", rchsa, rchan, chp->ccw_cmd, chp->ccw_flags, *status); @@ -1780,184 +1784,187 @@ t_stat stopxio(uint16 lchsa, uint32 *status) { /* stop XIO */ if (chp->chan_byte == BUFF_POST) { chp->chan_byte = BUFF_DONE; /* show done & not busy */ } - return SCPE_OK; /* CC2 & all OK */ + return SCPE_OK; /* CC2 & all OK */ } } else { - chp->ccw_count = 0; /* zero the count */ + chp->ccw_count = 0; /* zero the count */ /* The diags want the interrupt for the disk */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ STOPXIO 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 */ + return SCPE_OK; /* CC1 & all OK */ } } /* the channel is not busy, so return OK */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ sim_debug(DEBUG_CMD, &cpu_dev, "$$$ STOPXIO END3 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 */ + return SCPE_OK; /* No CC's all OK */ } /* device does not have stop_io entry, so stop the I/O */ /* check for a Command or data chain operation in progresss */ /* set the return to CC3BIT & CC4BIT causes infinite loop in MPX1X */ /* restore code to old CC1BIT return 12/21/2020 */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ /* reset the DC or CC bits to force completion after current IOCD */ - chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ sim_debug(DEBUG_CMD, &cpu_dev, "STPIO busy return CC1 %08x rchsa %04x status %08x cmd %02x flags %04x\n", CC1BIT, rchsa, *status, chp->ccw_cmd, chp->ccw_flags); - return SCPE_OK; /* go wait CC1 */ + return SCPE_OK; /* go wait CC1 */ } /* Reset Channel XIO */ 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 */ + 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 */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 inta; uint32 spadent; - uint16 rchan, rchsa; /* the real channel number */ + uint16 rchan, rchsa; /* the real channel number */ /* get the device entry for the logical channel in SPAD */ - spadent = SPAD[lchan]; /* get spad device entry for logical channel */ - rchan = (spadent & 0x7f00) >> 8; /* get real channel */ - rchsa = rchan << 8; /* get the real chan & zero suba */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = rchan << 8; /* get the real chan & zero suba */ /* get the device entry for the logical channel in SPAD */ - dibp = dib_unit[rchsa]; /* get the channel device information pointer */ - chp = find_chanp_ptr(rchsa); /* find the channel chanp pointer */ + dibp = dib_unit[rchsa]; /* get the channel device information pointer */ + chp = find_chanp_ptr(rchsa); /* find the channel chanp pointer */ - if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ - *status = CC3BIT; /* not found, so CC3 */ + 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, "rschnlxio test 1 dibp %p chp %p lchsa %04x rchsa %04x device not present, CC3 returned\n", dibp, chp, lchsa, rchsa); - return SCPE_OK; /* not found CC3 */ + return SCPE_OK; /* not found CC3 */ } - uptr = chp->unitptr; /* get the unit ptr */ + uptr = chp->unitptr; /* get the unit ptr */ /* 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 */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "RSCHNL rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); - return SCPE_OK; /* Not found, CC3 */ + return SCPE_OK; /* Not found, CC3 */ } - inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ - chp->chan_int = inta; /* make sure it is set in channel */ + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ /* reset this channel */ - dibp->chan_fifo_in = 0; /* reset the FIFO pointers */ - dibp->chan_fifo_out = 0; /* reset the FIFO pointers */ - chp->chan_inch_addr = 0; /* remove inch status buffer address */ -// lev = find_int_lev(chan); /* Interrupt Level for channel */ - INTS[inta] &= ~INTS_ACT; /* clear level active */ - SPAD[inta+0x80] &= ~SINT_ACT; /* clear in spad too */ + dibp->chan_fifo_in = 0; /* reset the FIFO pointers */ + dibp->chan_fifo_out = 0; /* reset the FIFO pointers */ + chp->chan_inch_addr = 0; /* remove inch status buffer address */ +// lev = find_int_lev(chan); /* Interrupt Level for channel */ + INTS[inta] &= ~INTS_ACT; /* clear level active */ + SPAD[inta+0x80] &= ~SINT_ACT; /* clear in spad too */ /* now go through all the sa for the channel and stop any IOCLs */ for (i=0; iunitptr; /* get the unit ptr */ + continue; /* not used */ + uptr = chp->unitptr; /* get the unit ptr */ /* see if we have a rschnl device entry */ - if (dibp->rschnl_io != NULL) { /* NULL if no rschnl_io function */ + if (dibp->rschnl_io != NULL) { /* NULL if no rschnl_io function */ /* call the device controller to process rschnl */ - j = dibp->rschnl_io(uptr); /* get status from device */ + j = dibp->rschnl_io(uptr); /* get status from device */ sim_debug(DEBUG_EXP, &cpu_dev, "rschnl_io returned %02x chsa %04x\n", j, rchsa); } - chp->chan_status = 0; /* clear the channel status */ - chp->chan_byte = BUFF_EMPTY; /* no data yet */ - chp->ccw_addr = 0; /* clear buffer address */ - chp->chan_caw = 0x0; /* clear IOCD address */ - chp->ccw_count = 0; /* channel byte count 0 bytes*/ - chp->ccw_flags = 0; /* clear flags */ - chp->ccw_cmd = 0; /* read command */ - chp->chan_inch_addr = 0; /* clear inch addr */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* clear buffer address */ + chp->chan_caw = 0x0; /* clear IOCD address */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* clear flags */ + chp->ccw_cmd = 0; /* read command */ + chp->chan_inch_addr = 0; /* clear inch addr */ } sim_debug(DEBUG_XIO, &cpu_dev, "rschnlxio return CC1 lchan %02x lchan %02x inta %04x\n", lchan, rchan, inta); - *status = CC1BIT; /* request accepted, no status, so CC1 TRY THIS */ - return SCPE_OK; /* All OK */ + *status = CC1BIT; /* request accepted, no status, so CC1 TRY THIS */ + return SCPE_OK; /* All OK */ } /* HIO - Halt I/O */ -t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ +t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ DIB *dibp; UNIT *uptr; - uint32 chan_icb; /* Interrupt level context block address */ - uint32 iocla; /* I/O channel IOCL address int ICB */ + uint32 chan_icb; /* Interrupt level context block address */ + uint32 iocla; /* I/O channel IOCL address int ICB */ uint32 inta, spadent, tempa, itva; uint16 lchan = get_chan(lchsa); uint16 rchan, rchsa; - CHANP *chp; /* Channel prog pointers */ - DEVICE *dptr; /* DEVICE pointer */ + 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 */ - rchan = (spadent & 0x7f00) >> 8; /* get real channel */ - rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */ - dibp = dib_unit[rchsa]; /* get the device DIB pointer */ - chp = find_chanp_ptr(rchsa); /* find the chanp pointer */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */ + dibp = dib_unit[rchsa]; /* get the device DIB pointer */ + chp = find_chanp_ptr(rchsa); /* find the chanp pointer */ - if (dibp == 0 || chp == 0) { /* if no dib or chan ptr, CC3 on return */ - *status = CC3BIT; /* not found, so CC3 */ + if (dibp == 0 || chp == 0) { /* if no dib or chan ptr, CC3 on return */ + *status = CC3BIT; /* not found, so CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "HIO lchsa %04x rchsa %04x device not present, CC3 returned\n", lchsa, rchsa); - return SCPE_OK; /* not found, CC3 */ + return SCPE_OK; /* not found, CC3 */ } - uptr = chp->unitptr; /* get the unit ptr */ + uptr = chp->unitptr; /* get the unit ptr */ /* 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 */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "HIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); - return SCPE_OK; /* Not found, CC3 */ + 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); +// sim_debug(DEBUG_XIO, &cpu_dev, "HIO dev spad %08x lchsa %04x rchsa %04x\n", spadent, lchsa, rchsa); + sim_debug(DEBUG_EXP, &cpu_dev, "HIO dev spad %08x lchsa %04x rchsa %04x\n", spadent, lchsa, rchsa); /* the haltio opcode processing software has already checked for F class */ - inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ - chp->chan_int = inta; /* make sure it is set in channel */ - sim_debug(DEBUG_XIO, &cpu_dev, "HIO int spad %08x inta %02x rchan %02x\n", spadent, inta, rchan); + inta = ((~spadent)>>16)&0x7f; /* get channel interrupt level */ + chp->chan_int = inta; /* make sure it is set in channel */ +// sim_debug(DEBUG_XIO, &cpu_dev, "HIO int spad %08x inta %02x rchan %02x\n", spadent, inta, rchan); + sim_debug(DEBUG_EXP, &cpu_dev, "HIO int spad %08x inta %02x rchan %02x\n", spadent, inta, rchan); /* get the address of the interrupt IVL in main memory */ - itva = SPAD[0xf1] + (inta<<2); /* int vector address */ - chan_icb = RMW(itva); /* Interrupt context block addr */ - iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ + itva = SPAD[0xf1] + (inta<<2); /* int vector address */ + chan_icb = RMW(itva); /* Interrupt context block addr */ + iocla = RMW(chan_icb+16); /* iocla is in wd 4 of ICB */ - sim_debug(DEBUG_XIO, &cpu_dev, +// sim_debug(DEBUG_XIO, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "$$ HIO busy test byte %02x rchsa %04x cmd %02x ccw_flags %04x IOCD1 %08x IOCD2 %08x\n", chp->chan_byte, rchsa, chp->ccw_cmd, chp->ccw_flags, RMW(iocla), RMW(iocla+4)); /* the channel is busy, so process */ /* see if we have a haltio device entry */ - if (dibp->halt_io != NULL) { /* NULL if no haltio function */ + if (dibp->halt_io != NULL) { /* NULL if no haltio function */ /* call the device controller to get halt_io status */ - tempa = dibp->halt_io(uptr); /* get status from device */ + tempa = dibp->halt_io(uptr); /* get status from device */ /* test for SCPE_IOERR (=2) SCPE_OK (=0)*/ - if (tempa != SCPE_OK) { /* sub channel has status ready */ + 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", @@ -1966,11 +1973,11 @@ 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 */ /* The diags want the interrupt for the disk */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *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 */ + return SCPE_OK; /* CC1 & all OK */ } /* see if waiting to start */ if (chp->chan_byte == BUFF_NEXT) { @@ -1997,44 +2004,45 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ 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, post good status, so CC1 */ - sim_debug(DEBUG_CMD, &cpu_dev, + *status = CC1BIT; /* request accepted, post good status, so CC1 */ +// sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &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_03082021 - chp->chan_byte = BUFF_DONE; /* we are done */ + 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); chp->chan_status = (STATUS_DEND|STATUS_CEND); -// store_csw(chp); /* store the status */ - push_csw(chp); /* store the status 1st in FIFO */ +// 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 */ - chp->ccw_cmd = 0; /* no command anymore */ - irq_pend = 1; /* flag to test for int condition */ + chp->chan_byte = BUFF_POST; /* show done with data */ + chp->chan_status = 0; /* no status anymore */ + chp->ccw_cmd = 0; /* no command anymore */ + irq_pend = 1; /* flag to test for int condition */ #endif - return SCPE_OK; /* No CC's all OK */ + return SCPE_OK; /* No CC's all OK */ } /* device does not have a HIO entry, so terminate the I/O */ if ((chp->chan_byte & BUFF_BUSY) == 0) { /* the channel is not busy, so return OK */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ 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 - chp->chan_byte = BUFF_DONE; /* we are done */ + chp->chan_byte = BUFF_DONE; /* we are done */ chp->chan_status = (STATUS_DEND|STATUS_CEND|STATUS_EXPT); - store_csw(chp); /* store the status */ + store_csw(chp); /* store the status */ /* change chan_byte to BUFF_POST */ - chp->chan_byte = BUFF_POST; /* show done with data */ - chp->chan_status = 0; /* no status anymore */ - chp->ccw_cmd = 0; /* no command anymore */ - irq_pend = 1; /* flag to test for int condition */ + chp->chan_byte = BUFF_POST; /* show done with data */ + chp->chan_status = 0; /* no status anymore */ + chp->ccw_cmd = 0; /* no command anymore */ + irq_pend = 1; /* flag to test for int condition */ #endif - return SCPE_OK; /* CC1 & all OK */ + return SCPE_OK; /* CC1 & all OK */ } /* device does not have a HIO entry, so terminate the I/O */ @@ -2045,101 +2053,101 @@ t_stat haltxio(uint16 lchsa, uint32 *status) { /* halt XIO */ "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 */ - 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 */ + chp->ccw_flags &= ~(FLAG_DC|FLAG_CC); /* reset chaining bits */ + 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|SNS_UNITEXP); /* show I/O complete */ /* post the channel status */ - chp->ccw_count = 0; /* zero the count */ + chp->ccw_count = 0; /* zero the count */ /* remove SLI, PPCI and Unit check status bits */ if (post_csw(chp, ((STATUS_PCI) << 16))) { - INTS[inta] &= ~INTS_REQ; /* clear any level request */ - *status = CC2BIT; /* status stored from SIO, so CC2 */ + INTS[inta] &= ~INTS_REQ; /* clear any level request */ + *status = CC2BIT; /* status stored from SIO, so CC2 */ 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 */ if (chp->chan_byte == BUFF_POST) { - chp->chan_byte = BUFF_DONE; /* show done & not busy */ + chp->chan_byte = BUFF_DONE; /* show done & not busy */ } - return SCPE_OK; /* CC2 & all OK */ + return SCPE_OK; /* CC2 & all OK */ } } - chp->chan_byte = BUFF_DONE; /* chan prog done */ + chp->chan_byte = BUFF_DONE; /* chan prog done */ /* the channel is not busy, so return OK */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ 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 */ + return SCPE_OK; /* No CC's all OK */ } /* grab controller n/u */ /* TODO return unimplemented function error, not busy */ -t_stat grabxio(uint16 lchsa, uint32 *status) { /* grab controller XIO n/u */ - DIB *dibp; /* device information pointer */ - UNIT *uptr; /* pointer to unit in channel */ +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 */ + DEVICE *dptr; /* Device ptr */ + uint16 lchan = get_chan(lchsa); /* get the logical channel number */ uint32 spadent; - uint16 rchan, rchsa; /* the real channel number, chsa */ + uint16 rchan, rchsa; /* the real channel number, chsa */ /* get the device entry for the logical channel in SPAD */ - spadent = SPAD[lchan]; /* get spad device entry for logical channel */ - rchan = (spadent & 0x7f00) >> 8; /* get real channel */ - rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */ + spadent = SPAD[lchan]; /* get spad device entry for logical channel */ + rchan = (spadent & 0x7f00) >> 8; /* get real channel */ + rchsa = (rchan << 8) | (lchsa & 0xff); /* merge sa to real channel */ /* get the device entry for the logical channel in SPAD */ - dibp = dib_unit[rchsa]; /* get the DIB pointer */ - chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */ + dibp = dib_unit[rchsa]; /* get the DIB pointer */ + chp = find_chanp_ptr(rchsa); /* find the device chanp pointer */ - if (dibp == 0 || chp == 0) { /* if no dib or channel ptr, CC3 return */ - *status = CC3BIT; /* not found, so CC3 */ + 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, "GRIO test 1 rchsa %04x device not present, CC3 returned\n", rchsa); - return SCPE_OK; /* not found CC3 */ + return SCPE_OK; /* not found CC3 */ } - uptr = chp->unitptr; /* get the unit ptr */ + uptr = chp->unitptr; /* get the unit ptr */ /* 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 */ + *status = CC3BIT; /* not enabled, so error CC3 */ sim_debug(DEBUG_EXP, &cpu_dev, "GRIO rchsa %04x device/unit not enabled, CC3 returned\n", rchsa); - return SCPE_OK; /* Not found, CC3 */ + return SCPE_OK; /* Not found, CC3 */ } /* check for a Command or data chain operation in progresss */ if (chp->ccw_cmd != 0 || (chp->ccw_flags & (FLAG_DC|FLAG_CC)) != 0) { - *status = CC4BIT; /* busy, so CC4 */ + *status = CC4BIT; /* busy, so CC4 */ sim_debug(DEBUG_CMD, &cpu_dev, "GRIO busy return CC4 lchsa %04x rchsa %04x status %08x\n", lchsa, rchsa, *status); - return SCPE_OK; /* CC4 all OK */ + return SCPE_OK; /* CC4 all OK */ } /* If this is console, debugger wants CC3 & CC4 = 0 */ if (rchan == 0x7e) { /* returning No CC's causes MPX1X to loop forever */ /* so restore returning CC1 */ - *status = 0; /* return no CC's */ + *status = 0; /* return no CC's */ } else { /* diags want unsupported transaction for disk */ - *status = CC2BIT|CC4BIT; /* unsupported transaction */ + *status = CC2BIT|CC4BIT; /* unsupported transaction */ } sim_debug(DEBUG_CMD, &cpu_dev, "GRIO lchsa %04x rchsa %04x status %08x\n", lchsa, rchsa, *status); - return SCPE_OK; /* dono */ + return SCPE_OK; /* dono */ } /* reset controller XIO */ -t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */ +t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */ DIB *dibp; UNIT *uptr; uint32 spadent; @@ -2147,114 +2155,118 @@ t_stat rsctlxio(uint16 lchsa, uint32 *status) { /* reset controller XIO */ CHANP *chp; int lev, i; uint32 chan = get_chan(lchsa); - DEVICE *dptr; /* get device ptr */ + DEVICE *dptr; /* get device ptr */ /* get the device entry for the logical channel in SPAD */ - spadent = SPAD[chan]; /* get spad device entry for logical channel */ - chan = spadent & 0x7f00; /* get real channel */ - chsa = chan; /* use just channel */ - dibp = dib_unit[chsa]; /* get the DIB pointer */ - chp = find_chanp_ptr(chsa); /* find the chanp pointer */ - uptr = chp->unitptr; /* get the unit ptr */ + spadent = SPAD[chan]; /* get spad device entry for logical channel */ + chan = spadent & 0x7f00; /* get real channel */ + chsa = chan; /* use just channel */ + dibp = dib_unit[chsa]; /* get the DIB pointer */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + uptr = chp->unitptr; /* get the unit ptr */ - sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 1 chan %04x SPAD %08x\n", chsa, spadent); - if (dibp == 0 || uptr == 0) { /* if no dib or unit ptr, CC3 on return */ - *status = CC3BIT; /* not found, so CC3 */ - return SCPE_OK; /* not found, CC3 */ +// sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 1 chan %04x SPAD %08x\n", chsa, spadent); + sim_debug(DEBUG_EXP, &cpu_dev, "rsctlxio 1 chan %04x SPAD %08x\n", chsa, spadent); + if (dibp == 0 || uptr == 0) { /* if no dib or unit ptr, CC3 on return */ + *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); +// sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio 2 chan %04x spad %08x\r\n", chsa, spadent); + sim_debug(DEBUG_EXP, &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 */ + 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 */ + *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 */ + 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 */ - INTS[lev] &= ~INTS_REQ; /* clear level request */ + lev = find_int_lev(chan); /* get our int level */ + INTS[lev] &= ~INTS_ACT; /* clear level active */ + SPAD[lev+0x80] &= ~SINT_ACT; /* clear spad too */ + INTS[lev] &= ~INTS_REQ; /* clear level request */ /* now go through all the sa for the channel and stop any IOCLs */ for (i=0; ichan_fifo_in = 0; /* set no FIFO entries */ - dibp->chan_fifo_out = 0; /* set no FIFO entries */ + dibp->chan_fifo_in = 0; /* set no FIFO entries */ + dibp->chan_fifo_out = 0; /* set no FIFO entries */ - uptr = chp->unitptr; /* get the unit ptr */ - unit = uptr - dptr->units; /* get the UNIT number */ + uptr = chp->unitptr; /* get the unit ptr */ + unit = uptr - dptr->units; /* get the UNIT number */ if (dibp->ioclq_ptr != NULL) { - qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ + qp = &dibp->ioclq_ptr[unit]; /* IOCLQ pointer */ if (qp != NULL) { - qp->ioclq_in = 0; /* clear any entries */ - qp->ioclq_out = 0; /* clear any entries */ + qp->ioclq_in = 0; /* clear any entries */ + qp->ioclq_out = 0; /* clear any entries */ } } /* see if we have a rsctl device entry */ - if (dibp->rsctl_io != NULL) { /* NULL if no rsctl_io function */ + if (dibp->rsctl_io != NULL) { /* NULL if no rsctl_io function */ /* call the device controller to process rsctl */ - j = dibp->rsctl_io(uptr); /* get status from device */ - sim_debug(DEBUG_CMD, &cpu_dev, + j = dibp->rsctl_io(uptr); /* get status from device */ +// sim_debug(DEBUG_CMD, &cpu_dev, + sim_debug(DEBUG_EXP, &cpu_dev, "rsctl_io returned %02x chsa %04x\n", j, chsa); } - chp->chan_status = 0; /* clear the channel status */ - chp->chan_byte = BUFF_EMPTY; /* no data yet */ - chp->ccw_addr = 0; /* clear buffer address */ - chp->chan_caw = 0x0; /* clear IOCD address */ - chp->ccw_count = 0; /* channel byte count 0 bytes*/ - chp->ccw_flags = 0; /* clear flags */ - chp->ccw_cmd = 0; /* read command */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* clear buffer address */ + chp->chan_caw = 0x0; /* clear IOCD address */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* clear flags */ + chp->ccw_cmd = 0; /* read command */ } - sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio return CC1 chan %04x lev %04x\n", chan, lev); +// sim_debug(DEBUG_CMD, &cpu_dev, "rsctlxio return CC1 chan %04x lev %04x\n", chan, lev); + sim_debug(DEBUG_EXP, &cpu_dev, "rsctlxio return CC1 chan %04x lev %04x\n", chan, lev); /* returning 0 for status breaks ethernet controller */ if ((dptr != NULL) && - (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ - *status = CC1BIT; /* request accepted, no status, so CC1 */ + (DEV_TYPE(dptr) == DEV_ETHER)) { /* see if this is ethernet */ + *status = CC1BIT; /* request accepted, no status, so CC1 */ } else - *status = 0; /* request accepted, no status, return 0 */ - return SCPE_OK; /* All OK */ + *status = 0; /* request accepted, no status, return 0 */ + return SCPE_OK; /* All OK */ } /* boot from the device (ch/sa) the caller specified */ /* on CPU reset, the cpu has set the IOCD data at location 0-4 */ t_stat chan_boot(uint16 chsa, DEVICE *dptr) { int chan = get_chan(chsa); - DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */ - UNIT *uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ + DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */ + UNIT *uptr = find_unit_ptr(chsa); /* find pointer to unit on channel */ CHANP *chp = 0; sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot chan/device addr %04x SNS %08x\n", chsa, uptr->u5); - if (dibp == 0) /* if no channel or device, error */ - return SCPE_IOERR; /* error */ - if (dibp->chan_prg == NULL) /* must have channel information for each device */ - return SCPE_IOERR; /* error */ - chp = find_chanp_ptr(chsa); /* find the chanp pointer */ - if (chp == 0) /* if no channel, error */ - return SCPE_IOERR; /* error */ + if (dibp == 0) /* if no channel or device, error */ + return SCPE_IOERR; /* error */ + if (dibp->chan_prg == NULL) /* must have channel information for each device */ + return SCPE_IOERR; /* error */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + if (chp == 0) /* if no channel, error */ + return SCPE_IOERR; /* error */ /* make sure there is an IOP/MFP configured at 7e00 on system */ if (dib_chan[0x7e] == NULL) { sim_debug(DEBUG_CMD, dptr, "ERROR===ERROR\nIOP/MFP device 0x7e00 not configured on system, aborting\n"); printf("ERROR===ERROR\nIOP/MFP device 0x7e00 not configured on system, aborting\n"); - return SCPE_UNATT; /* error */ + return SCPE_UNATT; /* error */ } /* make sure there is an IOP/MFP console configured at 7efc/7efd on system */ @@ -2262,18 +2274,18 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) { sim_debug(DEBUG_CMD, dptr, "ERROR===ERROR\nCON device 0x7efc/0x7ecd not configured on system, aborting\n"); printf("ERROR===ERROR\nCON device 0x7efc/0x7efd not configured on system, aborting\n"); - return SCPE_UNATT; /* error */ + return SCPE_UNATT; /* error */ } - chp->chan_status = 0; /* clear the channel status */ - chp->chan_dev = chsa; /* save our address (ch/sa) */ - chp->chan_byte = BUFF_EMPTY; /* no data yet */ - chp->ccw_addr = 0; /* start loading at loc 0 */ - chp->chan_caw = 0x0; /* set IOCD address to memory location 0 */ - chp->ccw_count = 0; /* channel byte count 0 bytes*/ - chp->ccw_flags = 0; /* Command chain and supress incorrect length */ - chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ - chp->ccw_cmd = 0; /* read command */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_dev = chsa; /* save our address (ch/sa) */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* start loading at loc 0 */ + chp->chan_caw = 0x0; /* set IOCD address to memory location 0 */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* Command chain and supress incorrect length */ + chp->chan_info = INFO_SIOCD; /* show first IOCD in channel prog */ + chp->ccw_cmd = 0; /* read command */ /* moved here to not destry loc 0-0x14 on reset/go cmds */ M[0] = 0x02000000; /* 0x00 IOCD 1 read into address 0 */ M[1] = 0x60000078; /* 0x04 IOCD 1 CMD Chain, Suppress incor length, 120 bytes */ @@ -2281,30 +2293,30 @@ t_stat chan_boot(uint16 chsa, DEVICE *dptr) { M[3] = 0x60000001; /* 0x0C IOCD 2 CMD chain,Supress incor length, 1 byte */ M[4] = 0x02000000; /* 0x10 IOCD 3 Read into address 0 */ M[5] = 0x000006EC; /* 0x14 IOCD 3 Read 0x6EC bytes */ - loading = chsa; /* show we are loading from the boot device */ + loading = chsa; /* show we are loading from the boot device */ sim_debug(DEBUG_CMD, &cpu_dev, "Channel Boot calling load_ccw chan %04x status %08x\n", chan, chp->chan_status); /* start processing the boot IOCL at loc 0 */ - if (load_ccw(chp, 0)) { /* load IOCL starting from location 0 */ + if (load_ccw(chp, 0)) { /* load IOCL starting from location 0 */ sim_debug(DEBUG_EXP, &cpu_dev, "Channel Boot Error return from load_ccw chan %04x status %08x\n", chan, chp->chan_status); - chp->ccw_flags = 0; /* clear the command flags */ - chp->chan_byte = BUFF_DONE; /* done with errors */ - loading = 0; /* show we are done loading from the boot device */ - return SCPE_IOERR; /* return error */ + chp->ccw_flags = 0; /* clear the command flags */ + chp->chan_byte = BUFF_DONE; /* done with errors */ + loading = 0; /* show we are done loading from the boot device */ + return SCPE_IOERR; /* return error */ } sim_debug(DEBUG_XIO, &cpu_dev, "Channel Boot OK return from load_ccw chsa %04x status %04x\n", chsa, chp->chan_status); - return SCPE_OK; /* all OK */ + return SCPE_OK; /* all OK */ } /* Continue a channel program for a device */ uint32 cont_chan(uint16 chsa) { - int32 stat; /* return status 0/1 from loadccw */ - CHANP *chp = find_chanp_ptr(chsa); /* channel program */ + int32 stat; /* return status 0/1 from loadccw */ + CHANP *chp = find_chanp_ptr(chsa); /* channel program */ sim_debug(DEBUG_XIO, &cpu_dev, "cont_chan entry chp %p chan_byte %02x chsa %04x addr %06x\n", @@ -2324,7 +2336,7 @@ uint32 cont_chan(uint16 chsa) chsa, chp->chan_caw); /* start a channel program */ - stat = load_ccw(chp, 1); /* resume the channel program */ + stat = load_ccw(chp, 1); /* resume the channel program */ /* we get status returned if there is an error on the startio cmd call */ if (stat) { /* we have an error or user requested interrupt, return status */ @@ -2340,22 +2352,22 @@ uint32 cont_chan(uint16 chsa) sim_debug(DEBUG_EXP, &cpu_dev, "cont_chan Error1 FIFO #%1x store_csw CC1 chan %04x status %08x\n", FIFO_Num(chsa), chan, chp->chan_status); - return SCPE_OK; /* done */ + return SCPE_OK; /* done */ } /* other error, stop the show */ - chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */ + chp->chan_status &= ~STATUS_PCI; /* remove PCI status bit */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* show I/O complete */ sim_debug(DEBUG_EXP, &cpu_dev, "cont_chan Error2 FIFO #%1x store_csw CC1 chan %04x status %08x\n", FIFO_Num(chsa), chan, chp->chan_status); - return SCPE_OK; /* done */ + return SCPE_OK; /* done */ } /* we get here when the start cmd has been processed without error */ /* go wait for the cmd to finish */ 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 */ + return SCPE_OK; /* done, status stored */ } /* must be more IOCBs, wait for them */ sim_debug(DEBUG_XIO, &cpu_dev, @@ -2369,23 +2381,23 @@ uint32 cont_chan(uint16 chsa) */ uint32 scan_chan(uint32 *ilev) { int i; - uint32 chsa; /* No device */ - uint32 chan; /* channel num 0-7f */ - uint32 tempa; /* icb address */ - uint32 chan_ivl; /* int level table address */ - uint32 chan_icba; /* Interrupt level context block address */ - CHANP *chp; /* channel prog pointer */ - DIB *dibp; /* DIB pointer */ - uint32 sw1, sw2; /* status words */ + uint32 chsa; /* No device */ + uint32 chan; /* channel num 0-7f */ + uint32 tempa; /* icb address */ + uint32 chan_ivl; /* int level table address */ + uint32 chan_icba; /* Interrupt level context block address */ + CHANP *chp; /* channel prog pointer */ + DIB *dibp; /* DIB pointer */ + uint32 sw1, sw2; /* status words */ /* see if we are loading */ if (loading) { /* we are loading see if chan prog complete */ /* get the device entry for the logical channel in SPAD */ - chan = loading & 0x7f00; /* get real channel and zero sa */ - dibp = dib_unit[chan]; /* get the IOP/MFP DIB pointer */ + chan = loading & 0x7f00; /* get real channel and zero sa */ + dibp = dib_unit[chan]; /* get the IOP/MFP DIB pointer */ if (dibp == 0) - return 0; /* skip unconfigured channel */ + return 0; /* skip unconfigured channel */ /* see if status is stored in FIFO */ /* see if the FIFO is empty */ if ((FIFO_Num(chan)) && ((FIFO_Get(chan, &sw1) == 0) && @@ -2394,80 +2406,88 @@ uint32 scan_chan(uint32 *ilev) { /* get the status from the FIFO and throw it away */ /* we really should post it to the current inch address */ /* there is really no need to post, but it might be helpfull */ - chp = find_chanp_ptr(chan); /* find the chanp pointer for channel */ + 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 */ + tempa = chp->chan_inch_addr; /* get inch status buffer address */ /* before overwriting memory loc 0+4, save PSD for caller in TPSD[] locations */ - TPSD[0] = M[0]; /* save PSD from loc 0&4 */ + TPSD[0] = M[0]; /* save PSD from loc 0&4 */ TPSD[1] = M[1]; /* save the status double word to memory */ -// WMW(tempa, sw1); /* save sa & IOCD address in status WD 1 loc */ +// WMW(tempa, sw1); /* save sa & IOCD address in status WD 1 loc */ /* 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 */ - chp->chan_byte = BUFF_DONE; /* we are done */ + 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 */ + 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", chp->chan_caw, chan, FIFO_Num(chan), tempa, sw1|BIT1, sw2); return loading; } - return 0; /* not ready, return */ + return 0; /* not ready, return */ } +#ifndef TEMP_PUTBACK_03172021 + /* 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? */ - continue; /* skip this one */ - if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */ - continue; /* skip this one */ - if (INTS[i] & INTS_REQ) /* if already requesting, skip */ - continue; /* skip this one */ + if (SPAD[i+0x80] == 0) /* not initialize? */ + continue; /* skip this one */ + if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */ + continue; /* skip this one */ + if (INTS[i] & INTS_REQ) /* if already requesting, skip */ + continue; /* skip this one */ /* see if there is pending status for this channel */ /* if there is and the level is not requesting, do it */ /* get the device entry for the logical channel in SPAD */ - chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */ - dibp = dib_chan[get_chan(chan)]; /* get the channel device information pointer */ - if (dibp == 0) /* we have a channel to check */ - continue; /* not defined, skip this one */ + chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */ + dibp = dib_chan[get_chan(chan)]; /* get the channel device information pointer */ + if (dibp == 0) /* we have a channel to check */ + continue; /* not defined, skip this one */ /* we have a channel to check */ /* check for pending status */ if (FIFO_Num(chan)) { - INTS[i] |= INTS_REQ; /* turn on channel interrupt request */ + INTS[i] |= INTS_REQ; /* turn on channel interrupt request */ sim_debug(DEBUG_EXP, &cpu_dev, "scan_chan FIFO REQ FIFO #%1x irq %02x SPAD %08x INTS %08x\n", FIFO_Num(SPAD[i+0x80] & 0x7f00), i, SPAD[i+0x80], INTS[i]); - irq_pend = 1; /* we have pending interrupt */ + irq_pend = 1; /* we have pending interrupt */ continue; } } /* cannot make anyone active if ints are blocked */ /* irq_pend will be set again when interrupts are unblocked */ - if (CPUSTATUS & BIT24) { /* interrupts blocked? */ + if (CPUSTATUS & BIT24) { /* interrupts blocked? */ sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS blocked!\n"); - goto tryme; /* needed for MPX */ + goto tryme; /* needed for MPX */ } /* now go process the highest requesting interrupt */ for (i=0; i<112; i++) { - if (SPAD[i+0x80] == 0) /* not initialize? */ - continue; /* skip this one */ - if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */ - continue; /* skip this one */ + if (SPAD[i+0x80] == 0) /* not initialize? */ + continue; /* skip this one */ + if (SPAD[i+0x80] == 0xffffffff) /* not initialize? */ + continue; /* skip this one */ /* this is a bug fix for MPX 1.x restart command */ - if (SPAD[i+0x80] == 0xefffffff) /* not initialize? */ - continue; /* skip this one */ + if (SPAD[i+0x80] == 0xefffffff) /* not initialize? */ + continue; /* skip this one */ if ((INTS[i]&INTS_ACT) || (SPAD[i+0x80]&SINT_ACT)) { /* look for level active */ sim_debug(DEBUG_DETAIL, &cpu_dev, "scan_chan INTS ACT irq %02x SPAD %08x INTS %08x\n", i, SPAD[i+0x80], INTS[i]); - return 0; /* this level active, so stop looking */ + return 0; /* this level active, so stop looking */ } - if ((INTS[i] & INTS_ENAB) == 0) { /* ints must be enabled */ - continue; /* skip this one */ + if ((INTS[i] & INTS_ENAB) == 0) { /* ints must be enabled */ + continue; /* skip this one */ } /* look for the highest requesting interrupt */ @@ -2480,34 +2500,34 @@ uint32 scan_chan(uint32 *ilev) { i, SPAD[i+0x80], INTS[i]); /* requesting, make active and turn off request flag */ - INTS[i] &= ~INTS_REQ; /* turn off request */ - INTS[i] |= INTS_ACT; /* turn on active */ - SPAD[i+0x80] |= SINT_ACT; /* show active in SPAD too */ + INTS[i] &= ~INTS_REQ; /* turn off request */ + INTS[i] |= INTS_ACT; /* turn on active */ + SPAD[i+0x80] |= SINT_ACT; /* show active in SPAD too */ /* get the address of the interrupt IVL table in main memory */ - chan_ivl = SPAD[0xf1] + (i<<2); /* contents of spad f1 points to chan ivl in mem */ - chan_icba = RMW(chan_ivl); /* get the interrupt context block addr in memory */ + chan_ivl = SPAD[0xf1] + (i<<2); /* contents of spad f1 points to chan ivl in mem */ + chan_icba = RMW(chan_ivl); /* get the interrupt context block addr in memory */ /* see if there is pending status for this channel */ /* get the device entry for the logical channel in SPAD */ - chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */ - dibp = dib_chan[get_chan(chan)]; /* get the channel device information pointer */ - if (dibp == 0) { /* see if we have a channel to check */ + chan = (SPAD[i+0x80] & 0x7f00); /* get real channel and zero sa */ + dibp = dib_chan[get_chan(chan)]; /* get the channel device information pointer */ + if (dibp == 0) { /* see if we have a channel to check */ /* not a channel, must be clk or ext int */ - *ilev = i; /* return interrupt level */ - irq_pend = 0; /* not pending anymore */ + *ilev = i; /* return interrupt level */ + irq_pend = 0; /* not pending anymore */ sim_debug(DEBUG_IRQ, &cpu_dev, "scan_chan %04x POST NON FIFO irq %02x chan_icba %06x SPAD[%02x] %08x\n", chan, i, chan_icba, i+0x80, SPAD[i+0x80]); - return(chan_icba); /* return ICB address */ + return(chan_icba); /* return ICB address */ } /* must be a device, get status ready to post */ if (FIFO_Num(chan)) { /* new 051020 find actual device with the channel program */ /* not the channel, that is not correct most of the time */ tempa = dibp->chan_fifo[dibp->chan_fifo_out]; /* get SW1 of FIFO entry */ - chsa = chan | (tempa >> 24); /* find device address for requesting chan prog */ - chp = find_chanp_ptr(chsa); /* find the chanp pointer for channel */ + chsa = chan | (tempa >> 24); /* find device address for requesting chan prog */ + chp = find_chanp_ptr(chsa); /* find the chanp pointer for channel */ sim_debug(DEBUG_IRQ, &cpu_dev, "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); @@ -2526,9 +2546,9 @@ uint32 scan_chan(uint32 *ilev) { "scan_chanx %04x NOT POSTED FIFO #%1x irq %02x inch %06x chan_icba %06x chan_byte %02x\n", chan, FIFO_Num(chan), i, chp->chan_inch_addr, chan_icba, chp->chan_byte); } - *ilev = i; /* return interrupt level */ - irq_pend = 0; /* not pending anymore */ - return(chan_icba); /* return ICB address */ + *ilev = i; /* return interrupt level */ + irq_pend = 0; /* not pending anymore */ + return(chan_icba); /* return ICB address */ } else { /* we had an interrupt request, but no status is available */ /* clear the interrupt and go on */ @@ -2538,15 +2558,15 @@ uint32 scan_chan(uint32 *ilev) { i, SPAD[i+0x80], INTS[i]); /* requesting, make active and turn off request flag */ - INTS[i] &= ~INTS_ACT; /* turn off active int */ - SPAD[i+0x80] &= ~SINT_ACT; /* clear active in SPAD too */ + INTS[i] &= ~INTS_ACT; /* turn off active int */ + SPAD[i+0x80] &= ~SINT_ACT; /* clear active in SPAD too */ } } } tryme: /* if the interrupt is not zero'd here, we get SPAD error */ - irq_pend = 0; /* not pending anymore */ - return 0; /* done */ + irq_pend = 0; /* not pending anymore */ + return 0; /* done */ } /* part of find_dev_from_unit(UNIT *uptr) in scp.c */ @@ -2559,18 +2579,18 @@ DEVICE *get_dev(UNIT *uptr) DEVICE *dptr = NULL; uint32 i, j; - if (uptr == NULL) /* must be valid unit */ + if (uptr == NULL) /* must be valid unit */ return NULL; - if (uptr->dptr) /* get device pointer from unit */ - return uptr->dptr; /* return valid pointer */ + if (uptr->dptr) /* get device pointer from unit */ + return uptr->dptr; /* return valid pointer */ /* the device pointer in the unit is not set up, do it now */ /* This should never happen as the pointer is setup in first reset call */ for (i = 0; (dptr = sim_devices[i]) != NULL; i++) { /* do all devices */ - for (j = 0; j < dptr->numunits; j++) { /* do all units for device */ - if (uptr == (dptr->units + j)) { /* match found? */ - uptr->dptr = dptr; /* set the pointer in unit */ - return dptr; /* return valid pointer */ + for (j = 0; j < dptr->numunits; j++) { /* do all units for device */ + if (uptr == (dptr->units + j)) { /* match found? */ + uptr->dptr = dptr; /* set the pointer in unit */ + return dptr; /* return valid pointer */ } } } @@ -2583,52 +2603,52 @@ t_stat chan_set_devs() { uint32 i, j; for (i = 0; i < MAX_DEV; i++) { - dib_unit[i] = NULL; /* clear DIB pointer array */ + dib_unit[i] = NULL; /* clear DIB pointer array */ } for (i = 0; i < MAX_CHAN; i++) { - dib_chan[i] = NULL; /* clear DIB pointer array */ + dib_chan[i] = NULL; /* clear DIB pointer array */ } /* Build channel & device arrays */ for (i = 0; sim_devices[i] != NULL; i++) { - DEVICE *dptr = sim_devices[i]; /* get pointer to next configured device */ - UNIT *uptr = dptr->units; /* get pointer to units defined for this device */ - DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */ - CHANP *chp; /* channel program pointer */ - int chsa; /* addr of device chan & subaddress */ + DEVICE *dptr = sim_devices[i]; /* get pointer to next configured device */ + UNIT *uptr = dptr->units; /* get pointer to units defined for this device */ + DIB *dibp = (DIB *)dptr->ctxt; /* get pointer to DIB for this device */ + CHANP *chp; /* channel program pointer */ + int chsa; /* addr of device chan & subaddress */ /* set the device back pointer in the unit structure */ - for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */ - uptr->dptr = dptr; /* set the device pointer in unit structure */ - uptr++; /* next UNIT pointer */ + for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */ + uptr->dptr = dptr; /* set the device pointer in unit structure */ + uptr++; /* next UNIT pointer */ } - uptr = dptr->units; /* get pointer to units again */ + uptr = dptr->units; /* get pointer to units again */ - if (dibp == NULL) /* If no DIB, not channel device */ + if (dibp == NULL) /* If no DIB, not channel device */ continue; - if ((dptr->flags & DEV_DIS) || /* Skip disabled devices */ - ((dibp->chan_prg) == NULL)) { /* must have channel info for each device */ - chsa = GET_UADDR(uptr->u3); /* ch/sa value */ + if ((dptr->flags & DEV_DIS) || /* Skip disabled devices */ + ((dibp->chan_prg) == NULL)) { /* must have channel info for each device */ + chsa = GET_UADDR(uptr->u3); /* ch/sa value */ //printf("Device %s chsa %04x not set up dibp %p\n", dptr->name, chsa, dibp); continue; } - chp = (CHANP *)dibp->chan_prg; /* must have channel information for each device */ + chp = (CHANP *)dibp->chan_prg; /* must have channel information for each device */ /* Check if address is in unit or dev entry */ - for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */ - chsa = GET_UADDR(uptr->u3); /* ch/sa value */ + for (j = 0; j < dptr->numunits; j++) { /* loop through unit entries */ + chsa = GET_UADDR(uptr->u3); /* ch/sa value */ //printf("Setup device %s%d chsa %04x type %02x dibp %p\n", //dptr->name, j, chsa, GET_TYPE(uptr->flags), dibp); /* zero some channel data loc's for device */ - chp->unitptr = uptr; /* set the unit back pointer */ - chp->chan_status = 0; /* clear the channel status */ - chp->chan_dev = chsa; /* save our address (ch/sa) */ - chp->chan_byte = BUFF_EMPTY; /* no data yet */ - chp->ccw_addr = 0; /* start loading at loc 0 */ - chp->chan_caw = 0; /* set IOCD address to memory location 0 */ - chp->ccw_count = 0; /* channel byte count 0 bytes*/ - chp->ccw_flags = 0; /* Command chain and supress incorrect length */ - chp->ccw_cmd = 0; /* read command */ - chp->chan_inch_addr = 0; /* clear address of stat dw in memory */ + chp->unitptr = uptr; /* set the unit back pointer */ + chp->chan_status = 0; /* clear the channel status */ + chp->chan_dev = chsa; /* save our address (ch/sa) */ + chp->chan_byte = BUFF_EMPTY; /* no data yet */ + chp->ccw_addr = 0; /* start loading at loc 0 */ + chp->chan_caw = 0; /* set IOCD address to memory location 0 */ + chp->ccw_count = 0; /* channel byte count 0 bytes*/ + chp->ccw_flags = 0; /* Command chain and supress incorrect length */ + chp->ccw_cmd = 0; /* read command */ + chp->chan_inch_addr = 0; /* clear address of stat dw in memory */ /* is unit marked disabled? */ if ((uptr->flags & UNIT_DIS) == 0 || (uptr->flags & UNIT_SUBCHAN) != 0) { @@ -2644,19 +2664,19 @@ t_stat chan_set_devs() { //printf("Setting Channel mux %04x dibp %p\n", chsa, dibp); /* channel mux, save dib for channel */ dib_chan[get_chan(chsa)] = dibp; - if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */ - dibp->dev_ini(uptr, 1); /* init the channel */ + if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */ + dibp->dev_ini(uptr, 1); /* init the channel */ } else { /* we have unit 0 of non-IOP/MFP device */ if (dib_unit[chsa] != 0) { //printf("Channel/Dev %04x already defined\n", chsa); - return SCPE_IERR; /* no, arg error */ + return SCPE_IERR; /* no, arg error */ } else { /* channel mux, save dib for channel */ /* for now, save any zero dev as chan */ if (chsa) { //printf("Setting Channel zero unit 0 device %04x dibp %p\n", chsa, dibp); - dib_unit[chsa] = dibp; /* no, save the dib address */ + dib_unit[chsa] = dibp; /* no, save the dib address */ if (dibp->dev_ini != NULL) /* if there is an init routine, call it now */ dibp->dev_ini(uptr, 1); /* init the channel */ } @@ -2666,15 +2686,15 @@ t_stat chan_set_devs() { /* see if address already defined */ if (dib_unit[chsa] != 0) { //printf("Channel/SubAddress %04x multiple defined, aborting\n", chsa); - return SCPE_IERR; /* no, arg error */ + return SCPE_IERR; /* no, arg error */ } - dib_unit[chsa] = dibp; /* no, save the dib address */ + dib_unit[chsa] = dibp; /* no, save the dib address */ } } - if (dibp->dev_ini != NULL) /* call channel init if defined */ - dibp->dev_ini(uptr, 1); /* init the channel */ - uptr++; /* next UNIT pointer */ - chp++; /* next CHANP pointer */ + if (dibp->dev_ini != NULL) /* call channel init if defined */ + dibp->dev_ini(uptr, 1); /* init the channel */ + uptr++; /* next UNIT pointer */ + chp++; /* next CHANP pointer */ } } /* now make another pass through the channels and see which integrated */ @@ -2686,7 +2706,7 @@ t_stat chan_set_devs() { /* check device zero for suspected channel */ if (dib_unit[i<<8]) { /* write dibp to channel array */ - dib_chan[i] = dib_unit[i<<8]; /* save the channel dib */ + dib_chan[i] = dib_unit[i<<8]; /* save the channel dib */ //printf("Chan_set_dev new Channel %04x defined at dibp %p\n", i<<8, dib_unit[i<<8]); } } else { @@ -2694,77 +2714,77 @@ t_stat chan_set_devs() { /* channel is defined, see if defined in dib_unit array */ if ((dib_unit[i<<8]) == 0) { /* write dibp to units array */ - dib_unit[i<<8] = dib_chan[i]; /* save the channel dib */ + dib_unit[i<<8] = dib_chan[i]; /* save the channel dib */ } } } - return SCPE_OK; /* all is OK */ + return SCPE_OK; /* all is OK */ } /* Validate and set the device onto a given channel */ t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc) { - DEVICE *dptr; /* device pointer */ - DIB *dibp; /* dib pointer */ - UNIT *tuptr; /* temp unit pointer */ - t_value chan; /* new channel addr */ - t_stat r; /* return status */ - int i; /* temp */ - int chsa, ochsa; /* dev addr */ + DEVICE *dptr; /* device pointer */ + DIB *dibp; /* dib pointer */ + UNIT *tuptr; /* temp unit pointer */ + t_value chan; /* new channel addr */ + t_stat r; /* return status */ + int i; /* temp */ + int chsa, ochsa; /* dev addr */ - if (cptr == NULL) /* is there a UNIT name specified */ - return SCPE_ARG; /* no, arg error */ - if (uptr == NULL) /* is there a UNIT pointer */ - return SCPE_IERR; /* no, arg error */ - dptr = get_dev(uptr); /* find the device from unit pointer */ - if (dptr == NULL) { /* device not found, so error */ + if (cptr == NULL) /* is there a UNIT name specified */ + return SCPE_ARG; /* no, arg error */ + if (uptr == NULL) /* is there a UNIT pointer */ + return SCPE_IERR; /* no, arg error */ + dptr = get_dev(uptr); /* find the device from unit pointer */ + if (dptr == NULL) { /* device not found, so error */ fprintf(stderr, "Set dev no DEVICE cptr %s\r\n", cptr); //printf("Set dev no DEVICE ptr %s\r\n", cptr); - return SCPE_IERR; /* error */ + return SCPE_IERR; /* error */ } //printf("Set dev DEVICE ptr %s\r\n", cptr); - dibp = (DIB *)dptr->ctxt; /* get dib pointer from device struct */ - if (dibp == NULL) { /* we need a DIB */ + dibp = (DIB *)dptr->ctxt; /* get dib pointer from device struct */ + if (dibp == NULL) { /* we need a DIB */ fprintf(stderr, "Set dev no DIB ptr %s\r\n", cptr); //printf("Set dev no DIB ptr %s\r\n", cptr); - return SCPE_IERR; /* no DIB, so error */ + return SCPE_IERR; /* no DIB, so error */ } - chan = get_uint(cptr, 16, 0xffff, &r); /* get new device address */ - if (r != SCPE_OK) /* need good number */ - return r; /* number error, return error */ + chan = get_uint(cptr, 16, 0xffff, &r); /* get new device address */ + if (r != SCPE_OK) /* need good number */ + return r; /* number error, return error */ //printf("Set new dev DEVICE ptr %s chan %04x\r\n", cptr, chan); -//ZZchan &= 0x7f00; /* clean channel address */ - dibp->chan_addr = chan; /* set new parent channel addr */ +//ZZchan &= 0x7f00; /* clean channel address */ + dibp->chan_addr = chan; /* set new parent channel addr */ /* change all the unit addresses with the new channel, but keep sub address */ /* Clear out existing entries for all units on this device */ - tuptr = dptr->units; /* get pointer to units defined for this device */ + tuptr = dptr->units; /* get pointer to units defined for this device */ /* loop through all units for this device */ for (i = 0; i < dibp->numunits; i++) { - ochsa = GET_UADDR(tuptr->u3); /* get old chsa for this unit */ + ochsa = GET_UADDR(tuptr->u3); /* get old chsa for this unit */ //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 (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 */ + 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 (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 { - chan &= 0x7f00; /* clean channel address */ - chsa = chan | (ochsa & 0xff); /* merge new channel with old sa */ + chan &= 0x7f00; /* clean channel address */ + chsa = chan | (ochsa & 0xff); /* merge new channel with old sa */ } if (chsa != ochsa) { fprintf(stderr, "Set new chsa %04x old chsa %04x\r\n", chsa, ochsa); //printf("Set new chsa %04x old chsa %04x\r\n", chsa, ochsa); } - tuptr->u3 &= ~UNIT_ADDR_MASK; /* clear old chsa for this unit */ - tuptr->u3 |= UNIT_ADDR(chsa); /* set new chsa for this unit */ - dib_unit[chan&0x7f00] = dibp; /* set the channel dib address */ - dib_unit[chsa] = dibp; /* save the dib address for new chsa */ - tuptr++; /* next unit pointer */ + tuptr->u3 &= ~UNIT_ADDR_MASK; /* clear old chsa for this unit */ + tuptr->u3 |= UNIT_ADDR(chsa); /* set new chsa for this unit */ + dib_unit[chan&0x7f00] = dibp; /* set the channel dib address */ + dib_unit[chsa] = dibp; /* save the dib address for new chsa */ + tuptr++; /* next unit pointer */ } return SCPE_OK; } @@ -2774,13 +2794,13 @@ t_stat show_dev_addr(FILE *st, UNIT *uptr, int32 v, CONST void *desc) { DEVICE *dptr; int chsa; - if (uptr == NULL) /* valid unit? */ - return SCPE_IERR; /* no, error return */ - dptr = get_dev(uptr); /* get the device pointer from unit */ - if (dptr == NULL) /* valid pointer? */ - return SCPE_IERR; /* return error */ - chsa = GET_UADDR(uptr->u3); /* get the unit address */ - fprintf(st, "CHAN/SA %04x", chsa); /* display channel/subaddress */ - return SCPE_OK; /* we done */ + if (uptr == NULL) /* valid unit? */ + return SCPE_IERR; /* no, error return */ + dptr = get_dev(uptr); /* get the device pointer from unit */ + if (dptr == NULL) /* valid pointer? */ + return SCPE_IERR; /* return error */ + chsa = GET_UADDR(uptr->u3); /* get the unit address */ + fprintf(st, "CHAN/SA %04x", chsa); /* display channel/subaddress */ + return SCPE_OK; /* we done */ } diff --git a/SEL32/sel32_com.c b/SEL32/sel32_com.c index 042bcc7..09f3b40 100644 --- a/SEL32/sel32_com.c +++ b/SEL32/sel32_com.c @@ -923,8 +923,8 @@ endit: /* not connected, so dump char on ground */ if (done) { sim_debug(DEBUG_CMD, dptr, - "com_srvo write dump DONE line %04x status %04x\n", - ln, SNS_CHNEND|SNS_DEVEND); + "com_srvo write dump DONE line %04x status %04x cmd %02x\n", + ln, SNS_CHNEND|SNS_DEVEND, cmd); uptr->u3 &= LMASK; /* nothing left, command complete */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ } diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index c609c74..110e89a 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -1867,13 +1867,19 @@ wait_loop: reason, sim_interval); return reason; break; - } else { + } +#ifdef XXX + else { sim_debug(DEBUG_EXP, &cpu_dev, "Process Event other reason %08x interval %08x\n", reason, sim_interval); - return reason; - break; /* process */ + reason = STOP_IBKPT; + sim_interval= 0; /* count down */ + break; +//JB return reason; +//JB break; /* process */ } +#endif } } @@ -1977,10 +1983,12 @@ wait_loop: sim_debug(DEBUG_IRQ, &cpu_dev, "<|>Normal int cpix %04x OPSD1 %08x OPSD2 %08x\n", bc, PSD1, PSD2); +#ifdef DUMP_REGS for (ix=0; ix<8; ix+=2) { sim_debug(DEBUG_IRQ, &cpu_dev, "<|> GPR[%d] %.8x GPR[%d] %.8x\n", ix, GPR[ix], ix+1, GPR[ix+1]); } +#endif PSD1 = M[(int_icb>>2)+2]; /* get new PSD 1 */ PSD2 = (M[(int_icb>>2)+3] & ~0x3fff) | bc; /* get new PSD 2 w/old cpix */ @@ -2023,6 +2031,7 @@ wait_loop: sim_debug(DEBUG_IRQ, &cpu_dev, "<|>Auto-reset interrupt INTS[%02x] %08x SPAD[%02x] %08x simi %02x\n", il, INTS[il], il+0x80, SPAD[il+0x80], sim_interval); +#define LEAVE_ACTIVE #ifndef LEAVE_ACTIVE /*AIR*/ INTS[irq_auto] &= ~INTS_ACT; /* deactivate specified int level */ /*AIR*/ SPAD[irq_auto+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ @@ -2109,6 +2118,7 @@ wait_loop: sim_debug(DEBUG_XIO, &cpu_dev, "scan_chan CPU RDYQ entry for chsa %04x processed w/error byte %04x\n", chsa, chp->chan_byte); + irq_pend = 1; /* start scanning interrupts again */ continue; } else RDYQ_Put(chsa); /* requeue the non-zero entry */ @@ -7184,7 +7194,7 @@ t_stat cpu_reset(DEVICE *dptr) CMSMC = 0x00ff0a10; /* No V9 Cache/Shadow Memory Configuration */ CSMCW = 0; /* No V9 CPU Shadow Memory Configuration */ ISMCW = 0; /* No V9 IPU Shadow Memory Configuration */ - RDYQIN = RDYQOUT = 0; /* initialize cheannel ready queue */ + RDYQIN = RDYQOUT = 0; /* initialize channel ready queue */ devs = chan_set_devs(); /* set up the defined devices on the simulator */ diff --git a/SEL32/sel32_defs.h b/SEL32/sel32_defs.h index b1a90ba..d0d08e5 100644 --- a/SEL32/sel32_defs.h +++ b/SEL32/sel32_defs.h @@ -136,7 +136,7 @@ #define NUM_DEVS_LPR 1 /* 1 IOP Line printer */ #define NUM_UNITS_LPR 1 /* 1 IOP Line printer device */ #define NUM_DEVS_ETHER 1 /* 1 Ethernet controller */ -#define NUM_UNITS_ETHER 10 /* 10 Ethernet devices */ +#define NUM_UNITS_ETHER 16 /* 16 Ethernet devices */ extern DEVICE cpu_dev; /* cpu device */ extern UNIT cpu_unit; /* the cpu unit */ diff --git a/SEL32/sel32_disk.c b/SEL32/sel32_disk.c index bea1ea2..585e538 100644 --- a/SEL32/sel32_disk.c +++ b/SEL32/sel32_disk.c @@ -1162,10 +1162,10 @@ t_stat disk_srv(UNIT *uptr) chp->chan_inch_addr, chsa, mema, chp->ccw_count); /* to use this inch method, byte count must be 897 */ if (len != 896) { - /* we have invalid count, error, bail out */ - uptr->SNS |= SNS_CMDREJ; - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); - break; + /* we have invalid count, error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; } /* now call set_inch() function to write and test inch buffer addresses */ tstart = set_inch(uptr, mema); /* new address */ @@ -1266,8 +1266,8 @@ t_stat disk_srv(UNIT *uptr) ch = ((2*SPT(type))-1) & 0x3f; /* get index cnt */ uptr->SNS2 = (uptr->SNS2 & 0xc0ff) | ((((uint32)ch) & 0x3f) << 8); sim_debug(DEBUG_CMD, dptr, - "disk_srv RAP %02x cyl %04x trk %02x sec %02x\n", - ch, cyl&0xffff, trk, sec); + "disk_srv RAP %02x cyl %04x trk %02x sec %02x\n", + ch, cyl&0xffff, trk, sec); if (chan_write_byte(chsa, &ch)) { /* put a byte to memory */ sim_debug(DEBUG_CMD, dptr, @@ -1355,15 +1355,15 @@ iha_error: } /* create offset and mask */ ecc = dmle_ecc32(obuf, ssize); /* calc ecc for original sector */ - sim_debug(DEBUG_DETAIL, dptr, - "disk_srv DEC old obuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", - obuf[1016], obuf[1017], obuf[1018], obuf[1019], - obuf[1020], obuf[1021], obuf[1022], obuf[1023]); + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv DEC old obuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", + obuf[1016], obuf[1017], obuf[1018], obuf[1019], + obuf[1020], obuf[1021], obuf[1022], obuf[1023]); cecc = dmle_ecc32(bbuf, ssize); /* calc ecc for bad sector */ - sim_debug(DEBUG_DETAIL, dptr, - "disk_srv DEC bad bbuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", - bbuf[1016], bbuf[1017], bbuf[1018], bbuf[1019], - bbuf[1020], bbuf[1021], bbuf[1022], bbuf[1023]); + sim_debug(DEBUG_DETAIL, dptr, + "disk_srv DEC bad bbuf data %02x%02x%02x%02x %02x%02x%02x%02x\n", + bbuf[1016], bbuf[1017], bbuf[1018], bbuf[1019], + bbuf[1020], bbuf[1021], bbuf[1022], bbuf[1023]); mema = 0; for (i=0, j=0; iSTAR = 0; /* set STAR to 0, 0, 0 */ diff --git a/SEL32/sel32_ec.c b/SEL32/sel32_ec.c index 50556bf..4742f1f 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[1024]; /* Buffer for received packet */ + ETH_PACK rec_buff[1024]; /* 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 */ @@ -221,7 +221,6 @@ extern uint32 readfull(CHANP *chp, uint32 maddr, uint32 *word); static CONST ETH_MAC broadcast_ethaddr = {0xff,0xff,0xff,0xff,0xff,0xff}; /* channel program information */ -//CHANP ec_chp[8] = {0}; CHANP ec_chp[NUM_UNITS_ETHER] = {0}; /* forward definitions */ @@ -235,6 +234,7 @@ void ec_packet_debug(struct ec_device *ec, const char *action, ETH_PACK * t_stat ec_reset (DEVICE *dptr); void ec_ini(UNIT *, t_bool); uint16 ec_rsctrl(UNIT *uptr); +uint16 ec_rschnlio(UNIT *uptr); 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); @@ -268,24 +268,28 @@ UNIT ec_unit[] = { {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE07)}, /* 7 */ {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE08)}, /* 8 */ {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE09)}, /* 9 */ -// {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0A)}, /* A */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0A)}, /* A */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0B)}, /* B */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0C)}, /* C */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0D)}, /* D */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0E)}, /* E */ + {UDATA(ec_srv, UNIT_IDLE|UNIT_SUBCHAN, 0), 0, UNIT_ADDR(0xE0F)}, /* F */ #endif }; DIB ec_dib = { ec_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Pre Start I/O */ 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 */ + 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 */ ec_rsctrl, /* uint16 (*rsctl_io)(UNIT *uptr) */ /* Reset Controller */ - NULL, /* uint16 (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ + ec_rschnlio, /* uint16 (*rschnl_io)(UNIT *uptr) */ /* Reset Channel */ ec_iocl, /* uint16 (*iocl_io)(CHANP *chp, int32 tic_ok)) */ /* Process IOCL */ - ec_ini, /* void (*dev_ini)(UNIT *uptr) */ /* init function */ + ec_ini, /* void (*dev_ini)(UNIT *uptr) */ /* init function */ ec_unit, /* UNIT *units */ /* Pointer to units structure */ ec_chp, /* CHANP *chan_prg */ /* Pointer to chan_prg structure */ NULL, /* IOCLQ *ioclq_ptr */ /* IOCL entries, 1 per UNIT */ -// 8, /* number of units defined */ NUM_UNITS_ETHER, /* number of units defined */ 0x0F, /* device mask */ 0x0E00, /* parent channel address */ @@ -329,7 +333,6 @@ DEBTAB ec_debug[] = { DEVICE ec_dev = { "EC", ec_unit, NULL, ec_mod, -// 8, 16, 24, 4, 16, 32, NUM_UNITS_ETHER, 16, 24, 4, 16, 32, NULL, NULL, &ec_reset, NULL, &ec_attach, &ec_detach, &ec_dib, DEV_DISABLE | DEV_DEBUG | DEV_ETHER, 0, ec_debug, @@ -346,6 +349,7 @@ uint16 ec_iocl(CHANP *chp, int32 tic_ok) int32 docmd = 0; UNIT *uptr = chp->unitptr; /* get the unit ptr */ uint16 chan = get_chan(chp->chan_dev); /* our channel */ + uint16 chsa = chp->chan_dev; uint16 devstat = 0; DEVICE *dptr = get_dev(uptr); @@ -353,8 +357,8 @@ uint16 ec_iocl(CHANP *chp, int32 tic_ok) if (chp->chan_info & INFO_SIOCD) { /* see if 1st IOCD in channel prog */ if (chp->chan_caw & 0x3) { /* must be word bounded */ sim_debug(DEBUG_EXP, dptr, - "ec_iocl iocd bad address chan %02x caw %06x\n", - chan, chp->chan_caw); + "ec_iocl iocd bad address chsa %02x caw %06x\n", + chsa, chp->chan_caw); chp->ccw_addr = chp->chan_caw; /* set the bad iocl address */ chp->chan_status |= STATUS_PCHK; /* program check for invalid iocd addr */ return 1; /* error return */ @@ -362,7 +366,7 @@ uint16 ec_iocl(CHANP *chp, int32 tic_ok) } loop: sim_debug(DEBUG_EXP, dptr, - "ec_iocl @%06x entry chan_status[%04x] %04x SNS %08x\n", + "ec_iocl @%06x @loop chan_status[%04x] %04x SNS %08x\n", chp->chan_caw, chan, chp->chan_status, uptr->SNS); /* Abort if we have any errors */ @@ -403,12 +407,14 @@ loop: chp->chan_caw, chp->ccw_flags, chp->ccw_cmd); } else chp->ccw_cmd = (word1 >> 24) & 0xff; /* set new command from IOCD wd 1 */ + chp->ccw_count = 0; if (!MEM_ADDR_OK(word1 & MASK24)) { /* see if memory address invalid */ chp->chan_status |= STATUS_PCHK; /* bad, program check */ sim_debug(DEBUG_EXP, dptr, - "ec_iocl bad IOCD1 chan_status[%04x] %04x\n", chan, chp->chan_status); + "ec_iocl mem error PCHK chan_status[%04x] %04x addr %08x\n", + chan, chp->chan_status, word1 & MASK24); return 1; /* error return */ } @@ -423,17 +429,72 @@ loop: case 0xf8: uptr->SNS &= ~SNS_CMDREJ; /* remove CMD reject status */ sim_debug(DEBUG_CMD, dptr, - "ec_startcmd illegal at ec_startcmd %02x SNS %08x\n", + "ec_iocl illegal at ec_startcmd %02x SNS %08x\n", chp->ccw_cmd, uptr->SNS); chp->ccw_count = 0; /* diags want zero count */ chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ return 1; /* error return */ - case EC_INCH: case EC_WRITE: case EC_READ: case EC_LIA: - case EC_TIC: case EC_CGA: case EC_LGA: case EC_LCC: - case EC_STATS: case EC_CSTATS: + case EC_READ: + /* read count must be multiple of 4 */ + if ((word2 & 0xffff) & 3) { + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl READ cnt not multiple of 4 %d\n", word2 & 0xffff); + /* diags wants prog check instead of unit check */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + /* see if too few bytes */ +//T20 if (((word2 & 0xffff) < ETH_MIN_PACKET) && /* not at least 60 bytes */ +//UTX if (((word2 & 0xffff) < 20) && /* not at least 20 bytes */ + if (((chp->chan_info & INFO_SIOCD) == 1) && /* see if 1st IOCD in channel prog */ + ((word2 & 0xffff) < 20) && /* not at least 20 bytes */ + ((word2 & BIT0) == 0)) { /* and not data chained */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl READ error small packet 0x%04x\n", word2 & 0xffff); + /* diags wants incorrect length instead of program check */ + chp->chan_status |= STATUS_LENGTH; /* incorrect length error */ + return 1; /* error return */ + } + /* see if too many bytes */ + if ((word2 & 0xffff) > (ETH_MAX_PACKET+2)) { + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl READ error large packet 0x%04x\n", word2 & 0xffff); + /* diags wants prog check instead of length check for test 4E */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } uptr->SNS = 0; break; + case EC_WRITE: + /* see if too few bytes */ +//T20 if (((word2 & 0xffff) < ETH_MIN_PACKET) && /* not at least 60 bytes */ +//T20 if (((word2 & 0xffff) < 10) && /* not at least 10 bytes */ +//UTX if (((word2 & 0xffff) < 8) && /* not at least 8 bytes */ + if (((chp->chan_info & INFO_SIOCD) == 1) && /* see if 1st IOCD in channel prog */ + ((word2 & 0xffff) < 8) && /* not at least 8 bytes */ + ((word2 & BIT0) == 0)) { /* and not data chained */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl WRITE error small packet 0x%04x\n", word2 & 0xffff); + /* diags wants prog check instead of unit check */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + /* see if too many bytes */ + if ((word2 & 0xffff) > ETH_MAX_PACKET) { + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_iocl WRITE error large packet 0x%04x\n", word2 & 0xffff); + /* diags wants prog check instead of length check for test 4E */ + chp->chan_status |= STATUS_PCHK; /* program check for invalid cmd */ + return 1; /* error return */ + } + uptr->SNS = 0; + break; + case EC_INCH: case EC_LIA: + case EC_TIC: case EC_CGA: case EC_LGA: case EC_LCC: + uptr->SNS = 0; + break; + case EC_STATS: case EC_CSTATS: case EC_SNS: break; case EC_NOP: @@ -448,7 +509,7 @@ loop: uptr->SNS |= SNS_CMDREJ; chp->chan_status |= STATUS_CHECK; /* diags want unit check */ sim_debug(DEBUG_CMD, dptr, - "ec_startcmd illegal cmd %02x SNS %08x\n", + "ec_startcmd illegal2 cmd %02x SNS %08x\n", chp->ccw_cmd, uptr->SNS); return 1; /* error return */ break; @@ -542,12 +603,14 @@ loop: uptr = chp->unitptr; /* get the unit ptr */ if (dibp == 0 || uptr == 0) { chp->chan_status |= STATUS_PCHK; /* program check if it is */ + sim_debug(DEBUG_EXP, dptr, + "ec_iocl bad dibp or uptr chan_status[%04x] %04x\n", chan, chp->chan_status); return 1; /* if none, error */ } sim_debug(DEBUG_XIO, dptr, "ec_iocl @%06x before start_cmd chan %04x status %04x count %04x SNS %08x\n", - chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->u5); + chp->chan_caw, chan, chp->chan_status, chp->ccw_count, uptr->SNS); /* call the device startcmd function to process the current command */ /* just replace device status bits */ @@ -556,8 +619,8 @@ loop: chp->chan_info &= ~INFO_SIOCD; /* show not first IOCD in channel prog */ sim_debug(DEBUG_XIO, dptr, - "ec_iocl @%06x after start_cmd chan %04x status %08x count %04x\n", - chp->chan_caw, chan, chp->chan_status, chp->ccw_count); + "ec_iocl @%06x after start_cmd chsa %04x status %08x count %04x SNS %08x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count, uptr->SNS); /* see if bad status */ if (chp->chan_status & (STATUS_ATTN|STATUS_ERROR)) { @@ -595,8 +658,8 @@ loop: /* the device processor returned OK (0), so wait for I/O to complete */ /* nothing happening, so return */ sim_debug(DEBUG_XIO, dptr, - "ec_iocl @%06x return, chan %04x status %04x count %04x\n", - chp->chan_caw, chan, chp->chan_status, chp->ccw_count); + "ec_iocl @%06x return, chsa %04x status %04x count %04x\n", + chp->chan_caw, chsa, chp->chan_status, chp->ccw_count); return 0; /* good return */ } @@ -634,31 +697,15 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) return SNS_BSY; } + uptr->CMD &= LMASK; /* remove old status bits & cmd */ /* Unit is online, so process a command */ switch (cmd) { case EC_WRITE: /* Write command 0x01 */ uptr->CMD |= cmd|EC_BUSY; /* save cmd */ -// 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, 7000); /* 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 */ +//*RC*/ sim_activate(uptr, 7000); /* start things off */ +// This works +/*jb*/ sim_activate(uptr, 7500); /* start things off */ return 0; case EC_INCH: /* INCH cmd 0x0 */ cmd = EC_INCH2; /* set dummy INCH cmd 0xf0 */ @@ -671,24 +718,17 @@ uint16 ec_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) case EC_NOP: /* NOP 0x03 */ case EC_LIA: /* Load individual address */ case EC_LGA: /* Load Multicast address */ - uptr->SNS &= 0xffff0000; /* remove invalid cmd status */ /* Fall through */ case EC_SNS: /* Sense 0x04 */ -#if 0 - /* nop must have non zero count */ - if (cmd == EC_NOP) { - if (chp->ccw_count == 0) - return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* diags want prog check */ - } -#endif uptr->CMD |= cmd|EC_BUSY; /* save cmd */ - sim_activate(uptr, 200); /* start things off */ -// sim_activate(uptr, 50); /* start things off */ +//*RC*/ sim_activate(uptr, 200); /* start things off */ +/*jb*/ sim_activate(uptr, 150); /* start things off */ +//old JBsim_activate(uptr, 50); /* start things off */ return 0; } uptr->SNS |= SNS_CMDREJ; - sim_debug(DEBUG_CMD, dptr, "ec_startcmd illegal cmd %02x SNS %08x\n", + sim_debug(DEBUG_CMD, dptr, "ec_startcmd illegal3 cmd %02x SNS %08x\n", cmd, uptr->SNS); chp->ccw_count = 0; /* diags want zero count */ return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; /* diags want unit check */ @@ -702,10 +742,17 @@ t_stat ec_rec_srv(UNIT *uptr) /* If not in loopback try and receive a packet */ if ((ec_data.conf[0] & 0x40) == 0) { - if (eth_read(&ec_data.etherface, &ec_data.rec_buff[ec_data.rec_ptr], - NULL) > 0) { - if (((ec_data.rec_ptr + 1) & LOOP_MSK) == ec_data.xtr_ptr) { + int q = (((ec_data.rec_ptr + 1) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (q > LOOP_MSK) + q -= (LOOP_MSK + 1); + if (eth_read(&ec_data.etherface, &ec_data.rec_buff[ec_data.rec_ptr], NULL) > 0) { +//jb if (((ec_data.rec_ptr + 1) & LOOP_MSK) == ec_data.xtr_ptr) { +//jb if (q > 16) { + if (q > 716) { ec_data.drop_cnt++; + sim_debug(DEBUG_DETAIL, dptr, + "ec_rec_srv received packet %08x dropped %08x\n", + ec_data.rx_count, ec_data.drop_cnt); } else { ec_data.rec_ptr = (ec_data.rec_ptr + 1) & LOOP_MSK; ec_data.rx_count++; @@ -739,7 +786,8 @@ t_stat ec_srv(UNIT *uptr) struct ec_eth_hdr *hdr; sim_debug(DEBUG_CMD, dptr, - "ec_srv chp %p cmd=%02x chsa %04x count %04x\n", chp, cmd, chsa, chp->ccw_count); + "ec_srv chp %p cmd=%02x chsa %04x count %04x SNS %08x\n", + chp, cmd, chsa, chp->ccw_count, uptr->SNS); switch (cmd) { // case EC_INCH: /* INCH cmd 0x0 */ @@ -835,59 +883,105 @@ t_stat ec_srv(UNIT *uptr) break; case EC_WRITE: /* Write command 0x01 */ + /* get queue length */ + n = (((ec_data.rec_ptr) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (n >LOOP_MSK) + n -= (LOOP_MSK + 1); + len = sizeof(struct ec_eth_hdr); /* header size */ pirq = 0; uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv START %04x write %d %d size=%d cnt %d q %d\n", + chsa, ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9], chp->ccw_count, n); hdr = (struct ec_eth_hdr *)(&ec_data.snd_buff.msg[0]); pck = (uint8 *)(&ec_data.snd_buff.msg[0]); + uptr->SNS &= LMASK; /* remove old count */ switch (GET_MODE(ec_master_uptr->flags)) { case 0: + /* destination / source / type or len / data 46-1500 */ for(i = 0; i < sizeof (struct ec_eth_hdr); i++) { if (chan_read_byte(chsa, &pck[i])) { pirq = 1; goto wr_end; } } + /* set transfer count of user bytes supplied */ + uptr->SNS |= (sizeof(struct ec_eth_hdr) & 0xffff); /* set transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 0 transmit bytes %d (0x%x) SNS %08x\n", + len, len, uptr->SNS); break; case 1: case 2: + /* copy destination */ for(i = 0; i < sizeof (ETH_MAC); i++) { if (chan_read_byte(chsa, &pck[i])) { pirq = 1; goto wr_end; } } + /* insert source */ memcpy(&hdr->src, ec_data.mac, sizeof (ETH_MAC)); + /* copy two byte type */ for(i = sizeof(ETH_MAC) * 2; i < sizeof(struct ec_eth_hdr); i++) { if (chan_read_byte(chsa, &pck[i])) { pirq = 1; goto wr_end; } } + /* set transfer count of user bytes supplied */ + uptr->SNS |= ((sizeof(struct ec_eth_hdr) - sizeof(ETH_MAC)) & 0xffff); + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 1&2 transmit bytes %d (0x%x) SNS %08x\n", + len-6, len-6, uptr->SNS); break; case 3: + /* copy destination */ for(i = 0; i < sizeof (ETH_MAC); i++) { if (chan_read_byte(chsa, &pck[i])) { pirq = 1; goto wr_end; } } + /* insert source */ memcpy(&hdr->src, ec_data.mac, sizeof (ETH_MAC)); + /* insert type */ hdr->type = htons(ETHTYPE_IP); + + /* set transfer count of user bytes supplied */ + uptr->SNS |= ((sizeof(struct ec_eth_hdr) - + sizeof(ETH_MAC) - sizeof(int16)) & 0xffff); + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 3 transmit bytes %d (0x%x) SNS %08x\n", + len-8, len-8, uptr->SNS); break; } + /* copy in packet data */ i = sizeof(struct ec_eth_hdr); while (chan_read_byte(chsa, &ch) == 0) { if (i < ETH_MAX_PACKET) { sim_debug(DEBUG_DATA, &ec_dev, "ec_srv data: %06x %02x\n", - chp->ccw_addr, ch); + chp->ccw_addr, ch); pck[i] = ch; } i++; + uptr->SNS++; /* set count */ } wr_end: ec_data.snd_buff.len = i; ec_packet_debug(&ec_data, "send", &ec_data.snd_buff); + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv @wr_end counts i %04x SNS %04x\n", i, uptr->SNS); + /* make sure packet is minimum size for mode 1,2 & 3 */ + if ((ec_data.snd_buff.len < ec_data.conf[9]) && + GET_MODE(ec_master_uptr->flags)) { + /* Pad the packet */ + while(i < ETH_MIN_PACKET) { + ec_data.snd_buff.len++; + pck[i++] = 0; + } + } +#ifdef NOTHERE /* see if too few bytes */ if (ec_data.snd_buff.len < ec_data.conf[9]) { sim_debug(DEBUG_DETAIL, &ec_dev, @@ -895,6 +989,7 @@ wr_end: /* diags wants prog check instead of unit check */ pirq = 1; } +#endif /* see if too many bytes, did not get channel end before packet filled */ if (ec_data.snd_buff.len > ETH_MAX_PACKET) { sim_debug(DEBUG_DETAIL, &ec_dev, @@ -904,35 +999,47 @@ wr_end: break; } +/*jb*/ ec_data.tx_count++; if ((ec_data.conf[0] & 0x40) != 0) { - if (((ec_data.rec_ptr + 1) & LOOP_MSK) == ec_data.xtr_ptr) { + int q = (((ec_data.rec_ptr + 1) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (q >LOOP_MSK) + q -= (LOOP_MSK + 1); +//jb if (((ec_data.rec_ptr + 1) & LOOP_MSK) == ec_data.xtr_ptr) { +//jb if (q > 16) { + if (q > 716) { ec_data.drop_cnt++; + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv write packet dropped %d q %d\n", + ec_data.drop_cnt, q); } else { memcpy(&ec_data.rec_buff[ec_data.rec_ptr], &ec_data.snd_buff, sizeof(ETH_PACK)); - sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv queued %d\n",ec_data.rec_ptr); ec_data.rec_ptr = (ec_data.rec_ptr + 1) & LOOP_MSK; - ec_data.rx_count++; - ec_data.tx_count++; + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv write rec queued %d xtr %d queue %04x\n", + ec_data.rec_ptr, ec_data.xtr_ptr, q); +//jb ec_data.rx_count++; +//jb ec_data.tx_count++; } } - sim_debug(DEBUG_DETAIL, &ec_dev, - "ec_srv sent packet %d bytes count=%08x\n", - ec_data.snd_buff.len, ec_data.tx_count); if ((ec_data.conf[0] & 0x40) == 0) { +#ifdef NOTHERE /* Pad the packet */ while(i < ETH_MIN_PACKET) { ec_data.snd_buff.len++; pck[i++] = 0; } +#endif if (eth_write(&ec_data.etherface, &ec_data.snd_buff, NULL) != SCPE_OK) { - sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short packet %d\n",i); + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv short packet %d\n", i); /* diags wants prog check instead of unit check */ pirq = 1; - ec_data.tx_count++; +//jb ec_data.tx_count++; } } + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv sent packet %d bytes tx_count=%08x SNS %08x\n", + ec_data.snd_buff.len, ec_data.tx_count, uptr->SNS); + if (pirq) chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); else { @@ -943,133 +1050,168 @@ 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, 500); /* continue poll */ + sim_debug(DEBUG_DETAIL, &ec_dev, "ec_srv WAIT %04x read %d %d size=%d cnt %d\n", + chsa, ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9], chp->ccw_count); +//jb sim_clock_coschedule(uptr, 500); /* continue poll */ +//jb sim_clock_coschedule(uptr, 511); /* continue poll */ + sim_activate(uptr, 511); /* continue poll */ return SCPE_OK; } + /* get queue length */ + n = (((ec_data.rec_ptr) & LOOP_MSK) + LOOP_MSK + 1) - ec_data.xtr_ptr; + if (n >LOOP_MSK) + n -= (LOOP_MSK + 1); 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 START %04x read %d %d size=%d cnt %d q %d\n", + chsa, ec_data.xtr_ptr, ec_data.rec_ptr, ec_data.conf[9], chp->ccw_count, n); uptr->CMD &= LMASK; /* remove old status bits & cmd */ + /* Read must be word bounded */ if (chp->ccw_addr & 0x3) { sim_debug(DEBUG_EXP, dptr, "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) & LOOP_MSK; -// chp->ccw_flags &= ~FLAG_SLI; chp->ccw_count = 0; chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH|STATUS_PCHK); break; } + uptr->SNS &= LMASK; /* remove old count */ ec_master_uptr->SNS |= SNS_RCV_RDY; ec_packet_debug(&ec_data, "recv", &ec_data.rec_buff[ec_data.xtr_ptr]); pck = (uint8 *)(&ec_data.rec_buff[ec_data.xtr_ptr].msg[0]); len = (int)(ec_data.rec_buff[ec_data.xtr_ptr].len); + n = sizeof(struct ec_eth_hdr); +#ifdef NOTHERE if (len < ec_data.conf[9]) { 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) & LOOP_MSK; chp->ccw_count = 0; /* diags wants prog check instead of unit check test 4F */ - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); +//jb chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); break; } +#endif switch (GET_MODE(ec_master_uptr->flags)) { case 0: + /* destination / source / type or len */ for(i = 0; i < sizeof (struct ec_eth_hdr); i++) { if (chan_write_byte(chsa, &pck[i])) { pirq = 1; break; } } + uptr->SNS |= (len & 0xffff); /* set transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 0 received bytes %d (0x%x) SNS %08x\n", + len, len, uptr->SNS); break; case 1: case 2: + /* copy destination */ for(i = 0; i < sizeof (ETH_MAC); i++) { if (chan_write_byte(chsa, &pck[i])) { pirq = 1; break; } } + /* insert length byte 1 */ ch = (len >> 8) & 0xff; if (chan_write_byte(chsa, &ch)) { pirq = 1; break; } + /* insert length byte 2 */ ch = len & 0xff; if (chan_write_byte(chsa, &ch)) { pirq = 1; break; } + /* copy in source / type or len */ for(; i < sizeof(struct ec_eth_hdr); i++) { if (chan_write_byte(chsa, &pck[i])) { pirq = 1; break; } } + uptr->SNS |= ((len + 2) & 0xffff); /* set transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 1&2 received bytes %d (0x%x) SNS %08x\n", + len+2, len+2, uptr->SNS); break; case 3: + /* copy destination */ for(i = 0; i < sizeof (ETH_MAC); i++) { if (chan_write_byte(chsa, &pck[i])) { pirq = 1; break; } } + /* insert length byte 1 */ ch = (len >> 8) & 0xff; if (chan_write_byte(chsa, &ch)) { pirq = 1; break; } + /* insert length byte 2 */ ch = len & 0xff; if (chan_write_byte(chsa, &ch)) { pirq = 1; break; } + /* copy in source */ for(; i < sizeof(ETH_MAC) * 2; i++) { if (chan_write_byte(chsa, &pck[i])) { pirq = 1; break; } } + /* insert length byte 1 */ ch = (len >> 8) & 0xff; if (chan_write_byte(chsa, &ch)) { pirq = 1; break; } + /* insert length byte 2 */ ch = len & 0xff; if (chan_write_byte(chsa, &ch)) { pirq = 1; break; } +//bad n += 2; /* add 2 bytes to header */ + uptr->SNS |= ((len + 4) & 0xffff); /* set transfer count */ + sim_debug(DEBUG_DETAIL, &ec_dev, + "ec_srv case 3 received bytes %d (0x%x) SNS %08x\n", + len+4, len+4, uptr->SNS); break; } - for(i = sizeof(struct ec_eth_hdr); i < len; i++) { +// for(i = sizeof(struct ec_eth_hdr); i < len; i++) { + for(i = n; i < len; i++) { if (chan_write_byte(chsa, &pck[i])) { -// if (len < ec_data.conf[9]) { -// sim_debug(DEBUG_DETAIL, &ec_dev, -// "ec_srv short read size %x %x %x\n", -// chp->ccw_count, i, ec_data.conf[9]); -// /* diags wants prog check instead of unit check */ -// pirq = 1; -// } + /* we read less than or exact bytes, good to go */ ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & LOOP_MSK; ec_data.rx_count++; sim_debug(DEBUG_DETAIL, &ec_dev, - "ec_srv received bytes %d of %d count=%08x conf %x\n", + "ec_srv received bytes %d of %d rx_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; } } + /* we have some bytes left, set count mismatch */ chp->ccw_flags |= FLAG_SLI; ec_data.xtr_ptr = (ec_data.xtr_ptr + 1) & LOOP_MSK; +/*jb*/ ec_data.rx_count++; sim_debug(DEBUG_DETAIL, &ec_dev, - "ec_srv received bytes %d count=%08x conf %x\n", - len, ec_data.rx_count, ec_data.conf[9]); + "ec_srv received bytes %d (0x%x) rx_count=%08x conf %02x SNS %08x\n", + len, len, ec_data.rx_count, ec_data.conf[9], uptr->SNS); if (pirq) - chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + /* diag want incorrect length error */ +//jb chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_PCHK); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|STATUS_LENGTH); else chan_end(chsa, SNS_CHNEND|SNS_DEVEND); break; @@ -1094,6 +1236,7 @@ wr_end: ch = 0; /* First 5 words are always zero since these errors are not supported */ uptr->CMD &= LMASK; /* remove old status bits & cmd */ + sim_debug(DEBUG_DETAIL, dptr, "ec_srv stats drop_count %08x\n", ec_data.drop_cnt); for (i = 0; i < STAT_LEN * 2; i++) { if (i == 6) ch = (ec_data.drop_cnt >> 8) & 0xff; @@ -1161,10 +1304,8 @@ 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; +//jb len = ec_data.rec_buff[ec_data.xtr_ptr].len; + len = uptr->SNS & 0xffff; 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; @@ -1193,7 +1334,7 @@ wr_end: break; } uptr->SNS &= ~(SNS_CMDREJ|SNS_EQUCHK); /* clear old status */ -/*JB*/ uptr->SNS &= 0xffff0000; /* clear last count */ +/*jb*/ uptr->SNS &= 0xffff0000; /* clear last count */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ break; @@ -1251,6 +1392,7 @@ void ec_ini(UNIT *uptr, t_bool f) uptr->CMD &= LMASK; /* remove old status bits & cmd */ uptr->SNS = 0; /* save mode value */ +// uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ memset(&ec_data.conf[0], 0, sizeof(ec_data.conf)); ec_data.macs_n = 0; ec_data.tx_count = 0; @@ -1273,6 +1415,7 @@ void ec_ini(UNIT *uptr, t_bool f) } } +/* handle reset controller cmds for Ethernet */ uint16 ec_rsctrl(UNIT *uptr) { DEVICE *dptr = get_dev(uptr); uint16 chsa = GET_UADDR(uptr->CMD); @@ -1284,6 +1427,23 @@ uint16 ec_rsctrl(UNIT *uptr) { ec_data.tx_count = 0; ec_data.rx_count = 0; ec_data.drop_cnt = 0; + ec_data.rec_ptr = 0; /* clear queue */ + ec_data.xtr_ptr = 0; /* clear queue */ +// uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ + return SCPE_OK; +} + +/* handle reset channel cmds for Ethernet */ +uint16 ec_rschnlio(UNIT *uptr) { + DEVICE *dptr = get_dev(uptr); + uint16 chsa = GET_UADDR(uptr->CMD); + int cmd = uptr->CMD & EC_CMDMSK; + + sim_debug(DEBUG_EXP, dptr, + "ec_rschnl chsa %04x cmd = %02x\n", chsa, cmd); + ec_ini(uptr, 0); /* reset the unit */ +// uptr->SNS = SNS_RCV_RDY; /* status is online & ready */ + /* the interrupt level will be reset in sel32_chan.c code */ return SCPE_OK; } @@ -1583,7 +1743,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 */ +//JBstatus = 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/taptools/README.md b/SEL32/taptools/README.md index 6bce0e1..f76a679 100644 --- a/SEL32/taptools/README.md +++ b/SEL32/taptools/README.md @@ -40,6 +40,15 @@ diskload - This program reads an MPX load module and stores it into - diskfile - simulated system disk output - modified system disk +eomtap - This program reads a tape assigned as input device. It + copies files until two EOFs are read and then makes sure + two EOFs are written followed by an EOM. This program + makes sure a .tap tape is readable without errors. + + command: eomtap mt00 filename + input - mag tape device or file being read + output - disk file containing tape file contents + filelist - This program scans a metadata .tap file and prints the file count and sizes. Used to determine the file format contained in the metadata .tap file. @@ -160,6 +169,15 @@ tapdump - This program reads a metadata .tap file and prints a side input - stdin > $JOBFILE -cat $TMPFILE >> $JOBFILE - -echo "CMD=\"brctl addbr br0\"" >> $JOBFILE -## echo "CMD=\"ip tuntap add mode tun name br0\"" >> $JOBFILE -cat $TMPFILE >> $JOBFILE - -N=0 -while test $N -lt $NrTaps -do - echo "CMD=\"tunctl -t tap${N} -u ${SimhUser}\"" >> $JOBFILE - ## echo "CMD=\"ip tuntap add mode tap name tap${N} user ${SimhUser} dev br0\"" >> $JOBFILE +case $OS in + "Linux") + echo "CMD=\"brctl addbr br0\"" >> $JOBFILE cat $TMPFILE >> $JOBFILE - N=`expr $N + 1` -done + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"tunctl -t tap${N} -u ${SimhUser}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE -echo "CMD=\"brctl addif br0 ${ACT_IF}\"" >> $JOBFILE -cat $TMPFILE >> $JOBFILE + N=`expr $N + 1` + done -echo "CMD=\"brctl setfd br0 0\"" >> $JOBFILE -cat $TMPFILE >> $JOBFILE - -if ! test "$IPNR" = "not configured" -then - echo "CMD=\"ip addr del ${IPNR} dev ${ACT_IF}\"" >> $JOBFILE - cat $TMPFILE >> $JOBFILE -fi - -echo "CMD=\"ip link set ${ACT_IF} up\"" >> $JOBFILE -cat $TMPFILE >> $JOBFILE - -if ! test "$IPNR" = "not configured" -then - echo "CMD=\"ip addr add ${IPNR} dev br0\"" >> $JOBFILE - cat $TMPFILE >> $JOBFILE -fi - -echo "CMD=\"ip link set br0 up\"" >> $JOBFILE -cat $TMPFILE >> $JOBFILE - -if test ! "x$DEFRT" = "x" -then - ## echo "CMD=\"ip route del default via ${DEFRT} dev ${ACT_IF}\"" >> $JOBFILE - ## cat $TMPFILE >> $JOBFILE - - echo "CMD=\"ip route add default via ${DEFRT} dev br0\"" >> $JOBFILE - cat $TMPFILE >> $JOBFILE -fi - -ipfwd=`cat /proc/sys/net/ipv4/ip_forward` -if test $IPFWD -ne $ipfwd -then - echo "CMD=\"echo ${IPFWD} > /proc/sys/net/ipv4/ip_forward\"" >> $JOBFILE - cat $TMPFILE >> $JOBFILE -fi - -N=0 -while test $N -lt $NrTaps -do - echo "CMD=\"brctl addif br0 tap${N}\"" >> $JOBFILE + echo "CMD=\"brctl addif br0 ${ACT_IF}\"" >> $JOBFILE cat $TMPFILE >> $JOBFILE - echo "CMD=\"ip link set tap${N} up\"" >> $JOBFILE + echo "CMD=\"brctl setfd br0 0\"" >> $JOBFILE cat $TMPFILE >> $JOBFILE - N=`expr $N + 1` -done + echo "CMD=\"ip link set ${ACT_IF} down\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE -cat - >> $JOBFILE <> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + if ! test "$IPNR" = "not configured" + then + ## if test ! "x$DEFRT" = "x" + ## then + ## echo "CMD=\"ip route del default via ${DEFRT} dev ${ACT_IF}\"" >> $JOBFILE + ## cat $TMPFILE >> $JOBFILE + ## fi + echo "CMD=\"ip addr del ${IPNR} dev ${ACT_IF}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + echo "CMD=\"ip link set ${ACT_IF} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ip link set br0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + + if test ! "x$DEFRT" = "x" + then + echo "CMD=\"ip route add default via ${DEFRT} dev br0\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + ipfwd=`cat /proc/sys/net/ipv4/ip_forward` + if test $IPFWD -ne $ipfwd + then + echo "CMD=\"echo ${IPFWD} > /proc/sys/net/ipv4/ip_forward\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + fi + + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"brctl addif br0 tap${N}\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ip link set tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + BRIDGE="br0" + EXAMPLE="tap:tap0" + + ;; + "FreeBSD") + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"ifconfig tap${N} create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"sysctl net.link.tap.up_on_open=1\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig bridge0 create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + case $NrTaps in + 1 ) + echo "CMD=\"ifconfig bridge0 addm ${ACT_IF} addm tap0\"" >> $JOBFILE + ;; + 2 ) + echo "CMD=\"ifconfig bridge0 addm ${ACT_IF} addm tap0 addm tap1\"" >> $JOBFILE + ;; + 3 ) + echo "CMD=\"ifconfig bridge0 addm ${ACT_IF} addm tap0 addm tap1 addm tap2\"" >> $JOBFILE + ;; + 4 ) + echo "CMD=\"ifconfig bridge0 addm ${ACT_IF} addm tap0 addm tap1 addm tap2 addm tap3\"" >> $JOBFILE + ;; + * ) + echo "Sorry too many taps..." + exit + esac + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig bridge0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + BRIDGE="bridge0" + EXAMPLE="tap:tap0" + ;; + "OpenBSD") + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"ifconfig tap${N} create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"ifconfig bridge0 create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig bridge0 fwddelay 4\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + case $NrTaps in + 1 ) + echo "CMD=\"ifconfig bridge0 add ${ACT_IF} add tap0\"" >> $JOBFILE + ;; + 2 ) + echo "CMD=\"ifconfig bridge0 add ${ACT_IF} add tap0 add tap1\"" >> $JOBFILE + ;; + 3 ) + echo "CMD=\"ifconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2\"" >> $JOBFILE + ;; + 4 ) + echo "CMD=\"ifconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2 add tap3\"" >> $JOBFILE + ;; + * ) + echo "Sorry too many taps..." + exit + esac + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig bridge0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + BRIDGE="bridge0" + EXAMPLE="tap:tap0" + ;; + "NetBSD") + N=0 + while test $N -lt $NrTaps + do + echo "CMD=\"ifconfig tap${N} create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig tap${N} up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + N=`expr $N + 1` + done + + echo "CMD=\"ifconfig bridge0 create\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"brconfig bridge0 fwddelay 1\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + case $NrTaps in + 1 ) + echo "CMD=\"brconfig bridge0 add ${ACT_IF} add tap0\"" >> $JOBFILE + ;; + 2 ) + echo "CMD=\"brconfig bridge0 add ${ACT_IF} add tap0 add tap1\"" >> $JOBFILE + ;; + 3 ) + echo "CMD=\"brconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2\"" >> $JOBFILE + ;; + 4 ) + echo "CMD=\"brconfig bridge0 add ${ACT_IF} add tap0 add tap1 add tap2 add tap3\"" >> $JOBFILE + ;; + * ) + echo "Sorry too many taps..." + exit + esac + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"brconfig bridge0 up\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + echo "CMD=\"ifconfig bridge0 create\"" >> $JOBFILE + echo "CMD=\"brconfig bridge0 fwddelay 1\"" >> $JOBFILE + cat $TMPFILE >> $JOBFILE + + BRIDGE="bridge0" + EXAMPLE="tap:tap0" + ;; +esac + + cat - >> $JOBFILE <