diff --git a/SEL32/sel32_chan.c b/SEL32/sel32_chan.c index 4d9806b..134353b 100644 --- a/SEL32/sel32_chan.c +++ b/SEL32/sel32_chan.c @@ -215,9 +215,11 @@ int32 RDYQ_Put(uint32 entry) RDYQIN += 1; /* next entry */ RDYQIN %= RDYQ_SIZE; /* modulo RDYQ size */ irq_pend = 1; /* do a scan */ +#ifdef USE_RDYQ // waitrdyq = 5; //25waitrdyq = 2; waitrdyq = 1; /* wait at least 1 instruction */ +#endif return 0; /* all OK */ } @@ -339,6 +341,11 @@ uint32 find_int_icb(uint16 chsa) 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 */ + sim_debug(DEBUG_EXP, &cpu_dev, + "find_int_icb ERR chsa %04x icba %02x\n", chsa, icba); + return 0; /* not found */ + } sim_debug(DEBUG_IRQ, &cpu_dev, "find_int_icb icba %06x SPADC %08x chsa %04x lev %02x SPADI %08x INTS %08x\n", icba, spadent, chsa, inta, SPAD[inta+0x80], INTS[inta]); @@ -1255,27 +1262,32 @@ missing: #ifndef NOTHERE /* check for a Command or data chain operation in progresss */ if ((chp->chan_byte & BUFF_BUSY) && chp->chan_byte != BUFF_POST) { - uint16 tstat, tcnt; + 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, "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); -#ifdef OLDWAY - *status = CC4BIT|CC3BIT; /* busy, so CC3&CC4 */ -#else - *status = CC1BIT; /* CCs = 1, SIO accepted & queued, no echo status */ - /* handle an Ethernet controller busy by sending interrupt/status */ - tstat = chp->chan_status; /* save status */ - tcnt = chp->ccw_count; /* save count */ - chp->chan_status = STATUS_BUSY|STATUS_CEND|STATUS_DEND; /* set busy 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_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); -#endif + /* ethernet controller wants an interrupt for busy status */ + if (DEV_TYPE(dptr) == DEV_ETHER) { + *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 */ + store_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); + } else { + /* everyone else just gets a busy return */ + *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); + } #ifdef DO_DYNAMIC_DEBUG /* start debugging */ if (chsa == 0x0c00) @@ -1428,6 +1440,10 @@ t_stat testxio(uint16 chsa, uint32 *status) { /* test XIO */ /* the channel is not busy, see if any status to post */ if (post_csw(chp, 0)) { +#ifdef DO_DYNAMIC_DEBUG + /* start debugging */ + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_TRAP | DEBUG_EXP | DEBUG_IRQ); +#endif *status = CC2BIT; /* status stored from SIO, so CC2 */ sim_debug(DEBUG_XIO, &cpu_dev, "testxio END status stored incha %06x chsa %04x sw1 %08x sw2 %08x\n", @@ -1876,9 +1892,9 @@ uint32 cont_chan(uint16 chsa) int32 stat; /* return status 0/1 from loadccw */ CHANP *chp = find_chanp_ptr(chsa); /* channel program */ - sim_debug(DEBUG_EXP, &cpu_dev, - "cont_chan entry chp %p chan_byte %02x chsa %04x addr %06x\n", - chp, chp->chan_byte, chsa, chp->ccw_addr); + sim_debug(DEBUG_EXP, &cpu_dev, + "cont_chan entry chp %p chan_byte %02x chsa %04x addr %06x\n", + chp, chp->chan_byte, chsa, chp->ccw_addr); /* we have entries, continue channel program */ if (chp->chan_byte != BUFF_NEXT) { /* channel program terminated already, ignore entry */ @@ -2139,6 +2155,17 @@ sim_debug(DEBUG_EXP, &cpu_dev, "scan_chanx BUFF_DONE chp %p chan_byte %04x\n", c *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 */ + /* this is a fix for MPX1X restart 092220 */ + sim_debug(DEBUG_IRQ, &cpu_dev, + "scan_chan highest int has no stat irq %02x SPAD %08x INTS %08x\n", + 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 */ } } } @@ -2148,7 +2175,7 @@ tryme: //25irq_pend = 0; /* not pending anymore */ #ifndef TEST_082520 if (RDYQ_Num()) { -#ifndef NOTNOW +#ifdef USE_RDYQ if (waitrdyq > 0) { waitrdyq--; irq_pend = 1; /* still pending */ diff --git a/SEL32/sel32_con.c b/SEL32/sel32_con.c index af80c35..56acf83 100644 --- a/SEL32/sel32_con.c +++ b/SEL32/sel32_con.c @@ -115,7 +115,7 @@ UNIT con_unit[] = { {UDATA(&con_srvo, UNIT_CON, 0), 0, UNIT_ADDR(0x7EFD)}, /* Output */ }; -//DIB con_dib = {NULL, con_startcmd, NULL, NULL, NULL, con_ini, con_unit, con_chp, NUM_UNITS_CON, 0xf, 0x7e00, 0, 0, 0}; +//DIB con_dib = {NULL,con_startcmd,NULL,NULL,NULL,con_ini,con_unit,con_chp,NUM_UNITS_CON,0xf,0x7e00,0,0,0}; DIB con_dib = { con_preio, /* uint16 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */ con_startcmd, /* uint16 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start command */ @@ -282,82 +282,93 @@ t_stat con_srvo(UNIT *uptr) { int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */ int cmd = uptr->CMD & CON_MSK; CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + int len = chp->ccw_count; /* INCH command count */ + uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ + uint32 tstart; + int cnt = 0; uint8 ch; sim_debug(DEBUG_CMD, &con_dev, "con_srvo enter CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); - /* if input tried from output device, error */ - if ((cmd == CON_RD) || (cmd == CON_ECHO) || (cmd == 0xC0)) { /* check for output */ - /* CON_RD: 0x02 */ /* Read command */ - /* CON_ECHO: 0x0a */ /* Read command w/ECHO */ - /* if input requested for output device, give error */ - if (unit == 1) { - uptr->SNS |= SNS_CMDREJ; /* command rejected */ - uptr->CMD &= LMASK; /* nothing left, command complete */ - sim_debug(DEBUG_CMD, &con_dev, - "con_srvo Read to output device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); - chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */ - return SCPE_OK; - } - } + switch (cmd) { - if ((cmd == CON_NOP) || (cmd == CON_INCH2)) { /* NOP has to do nothing */ + /* if input tried from output device, error */ + case CON_RD: /* 0x02 */ /* Read command */ + case CON_ECHO: /* 0x0a */ /* Read command w/ECHO */ + case 0x0C: /* 0x0C */ /* Unknown command */ + /* if input requested for output device, give error */ + uptr->SNS |= SNS_CMDREJ; /* command rejected */ uptr->CMD &= LMASK; /* nothing left, command complete */ sim_debug(DEBUG_CMD, &con_dev, - "con_srvo INCH/NOP unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + "con_srvo Read to output device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */ + break; + + case CON_INCH2: /* 0xf0 */ /* INCH command */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvo INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); - if (cmd == CON_INCH2) { /* Channel end only for INCH */ - int len = chp->ccw_count; /* INCH command count */ - uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ - //FIXME - test error return for error -// int i = set_inch(uptr, mema); /* new address */ - set_inch(uptr, mema); /* new address */ + /* now call set_inch() function to write and test inch buffer addresses */ + tstart = set_inch(uptr, mema); /* new address */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; sim_debug(DEBUG_CMD, &con_dev, - "con_srvo INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema); - chan_end(chsa, SNS_CHNEND); /* INCH done */ - } else { - sim_debug(DEBUG_CMD, &con_dev, - "con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); - chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ + "con_srvo INCH Error unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; } - return SCPE_OK; - } + sim_debug(DEBUG_CMD, &con_dev, + "con_srvo INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema); + chan_end(chsa, SNS_CHNEND); /* return OK */ + break; - if ((cmd == CON_WR) || (cmd == CON_RWD)) { - int cnt = 0; + case CON_NOP: /* 0x03 */ /* NOP has do nothing */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvo NOP unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + sim_debug(DEBUG_CMD, &con_dev, + "con_srvo NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + + case CON_RWD: /* 0x37 */ /* TOF and write line */ + case CON_WR: /* 0x01 */ /* Write command */ /* see if write complete */ if (uptr->CMD & CON_OUTPUT) { /* write is complete, post status */ sim_debug(DEBUG_CMD, &con_dev, "con_srvo write CMD %08x chsa %04x cmd %02x complete\n", uptr->CMD, chsa, cmd); - uptr->CMD &= LMASK; /* nothing left, command complete */ -/*RTC*/ outbusy = 0; /* output done */ - + uptr->CMD &= LMASK; /* nothing left, command complete */ +/*RTC*/ outbusy = 0; /* output done */ chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ - return SCPE_OK; + break; } //Comment out clock flag 072020 -/*RTC*/ outbusy = 1; /* tell clock output waiting */ +/*RTC*/ outbusy = 1; /* tell clock output waiting */ /* Write to device */ while (chan_read_byte(chsa, &ch) == SCPE_OK) { /* get byte from memory */ /* HACK HACK HACK */ - ch &= 0x7f; /* make 7 bit w/o parity */ - sim_putchar(ch); /* output next char to device */ - cnt++; /* count chars output */ + ch &= 0x7f; /* make 7 bit w/o parity */ + sim_putchar(ch); /* output next char to device */ + cnt++; /* count chars output */ } - uptr->CMD |= CON_OUTPUT; /* output command complete */ + uptr->CMD |= CON_OUTPUT; /* output command complete */ sim_debug(DEBUG_CMD, &con_dev, "con_srvo write wait %03x CMD %08x chsa %04x cmd %02x to complete\n", // 41*cnt+47, uptr->CMD, chsa, cmd); 19*cnt+23, uptr->CMD, chsa, cmd); -fflush(sim_deb); -// sim_activate(uptr, 19*cnt+23); /* wait for a while */ -// sim_activate(uptr, 31*cnt+47); /* wait for a while */ -/*719*/ sim_activate(uptr, 41*cnt+47); /* wait for a while */ -//719 sim_activate(uptr, 81*cnt+87); /* wait for a while */ +// sim_activate(uptr, 19*cnt+23); /* wait for a while */ +// sim_activate(uptr, 31*cnt+47); /* wait for a while */ +/*719*/ sim_activate(uptr, 41*cnt+47); /* wait for a while */ +//719 sim_activate(uptr, 81*cnt+87); /* wait for a while */ + break; } return SCPE_OK; } @@ -368,6 +379,9 @@ t_stat con_srvi(UNIT *uptr) { int unit = (uptr - con_unit); /* unit 0 is read, unit 1 is write */ int cmd = uptr->CMD & CON_MSK; CHANP *chp = find_chanp_ptr(chsa); /* find the chanp pointer */ + int len = chp->ccw_count; /* INCH command count */ + uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ + uint32 tstart; uint8 ch; t_stat r; @@ -378,46 +392,55 @@ t_stat con_srvi(UNIT *uptr) { "con_srvi enter CMD %08x chsa %04x cmd %02x incnt %02x u4 %02x\n", uptr->CMD, chsa, cmd, con_data[unit].incnt, uptr->u4); - /* if output tried to input device, error */ - if ((cmd == CON_RWD) || (cmd == CON_WR) || (cmd == 0x0C)) { /* check for output */ - /* CON_RWD: 0x37 */ /* TOF and write line */ - /* CON_WR: 0x01 */ /* Write command */ - /* if input requested for output device, give error */ - if (unit == 0) { - uptr->SNS |= SNS_CMDREJ; /* command rejected */ - uptr->CMD &= LMASK; /* nothing left, command complete */ - sim_debug(DEBUG_CMD, &con_dev, - "con_srvi Write to input device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); - chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */ - // fall thru return SCPE_OK; - } - } + switch (cmd) { - if ((cmd == CON_NOP) || (cmd == CON_INCH2)) { /* NOP is do nothing */ + /* if output tried to input device, error */ + case CON_RWD: /* 0x37 */ /* TOF and write line */ + case CON_WR: /* 0x01 */ /* Write command */ + case 0x0C: /* 0x0C */ /* Unknown command */ + /* if input requested for output device, give error */ + uptr->SNS |= SNS_CMDREJ; /* command rejected */ uptr->CMD &= LMASK; /* nothing left, command complete */ sim_debug(DEBUG_CMD, &con_dev, - "con_srvi INCH/NOP unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + "con_srvi Write to input device CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_UNITCHK); /* unit check */ + break; + + case CON_INCH2: /* 0xf0 */ /* INCH command */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvi INCH unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); - if (cmd == CON_INCH2) { /* Channel end only for INCH */ - int len = chp->ccw_count; /* INCH command count */ - uint32 mema = chp->ccw_addr; /* get inch or buffer addr */ - //FIXME add code to test return from set_inch - set_inch(uptr, mema); /* new address */ - con_data[unit].incnt = 0; /* buffer empty */ - uptr->u4 = 0; /* no I/O yet */ + /* now call set_inch() function to write and test inch buffer addresses */ + tstart = set_inch(uptr, mema); /* new address */ + if ((tstart == SCPE_MEM) || (tstart == SCPE_ARG)) { /* any error */ + /* we have error, bail out */ + uptr->SNS |= SNS_CMDREJ; sim_debug(DEBUG_CMD, &con_dev, - "con_srvi INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema); - chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* done */ - } else { - sim_debug(DEBUG_CMD, &con_dev, - "con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); - chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* NOP done */ + "con_srvi INCH Error unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; } + con_data[unit].incnt = 0; /* buffer empty */ + uptr->u4 = 0; /* no I/O yet */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvi INCH CMD %08x chsa %04x len %02x inch %06x\n", uptr->CMD, chsa, len, mema); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ /* drop through to poll input */ - } + break; - switch (cmd) { + case CON_NOP: /* 0x03 */ /* NOP has do nothing */ + uptr->CMD &= LMASK; /* nothing left, command complete */ + sim_debug(DEBUG_CMD, &con_dev, + "con_srvi NOP unit %02x: CMD %08x cmd %02x incnt %02x u4 %02x\n", + unit, uptr->CMD, cmd, con_data[unit].incnt, uptr->u4); + sim_debug(DEBUG_CMD, &con_dev, + "con_srvi NOP CMD %08x chsa %04x cmd = %02x\n", uptr->CMD, chsa, cmd); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + /* drop through to poll input */ + break; case CON_RD: /* 0x02 */ /* read from device */ case CON_ECHO: /* 0x0a */ /* read from device w/ECHO */ @@ -432,6 +455,12 @@ t_stat con_srvi(UNIT *uptr) { /* process any characters */ if (uptr->u4 != con_data[unit].incnt) { /* input available */ ch = con_data[unit].ibuff[uptr->u4]; /* get char from read buffer */ +#ifndef ECHO_ON_READ_092220 + /* this fixes mpx1x time entry on startup */ + if (uptr->CMD & CON_EKO) /* ECHO requested */ + sim_putchar(ch); /* ECHO the char */ +#endif + if (chan_write_byte(chsa, &ch)) { /* write byte to memory */ /* write error */ cmd = 0; /* no cmd now */ @@ -503,8 +532,11 @@ t_stat con_srvi(UNIT *uptr) { "con_srvi handle readch unit %02x: CMD %08x read %02x u4 %02x incnt %02x\n", unit, uptr->CMD, ch, uptr->u4, con_data[unit].incnt); +#ifdef ECHO_ON_READ_092220 + /* this fixes mpx1x time entry on startup */ if (uptr->CMD & CON_EKO) /* ECHO requested */ sim_putchar(ch); /* ECHO the char */ +#endif /* put char in buffer */ con_data[unit].ibuff[con_data[unit].incnt++] = ch; diff --git a/SEL32/sel32_cpu.c b/SEL32/sel32_cpu.c index 88dd528..7a9949a 100644 --- a/SEL32/sel32_cpu.c +++ b/SEL32/sel32_cpu.c @@ -1981,7 +1981,9 @@ wait_loop: sim_debug(DEBUG_IRQ, &cpu_dev, "Load Skipinstr %1x set loading PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", skipinstr, PSD1, PSD2, CPUSTATUS); +#ifdef NO_SKIP_HERE skipinstr = 1; /* skip next interrupt test only once */ +#endif goto skipi; /* skip int test */ } /* process any channel programs that are queued */ @@ -1989,7 +1991,7 @@ wait_loop: uint32 chsa; /* channel/sub adddress */ int32 stat; /* return status 0/1 from loadccw */ -#ifdef NOT_NOW +#ifdef USE_RDYQ if (waitrdyq > 0) { waitrdyq--; } else @@ -2093,12 +2095,15 @@ wait_loop: "<|>Int2 %02x ICBA %06x IOCLA %06x STAT %08x SW1 %08x SW2 %08x\n", il, int_icb, RMW(int_icb+16), RMW(int_icb+20), RMW(bc), RMW(bc+4)); wait4int = 0; /* wait is over for int */ +/*917*/ drop_nop = 0; /* no nop skipping */ #ifdef NOTNOW sim_debug(DEBUG_IRQ, &cpu_dev, "<|> Skipinstr %1x set intr %02x PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", skipinstr, il, PSD1, PSD2, CPUSTATUS); #endif +#ifdef NO_SKIP_HERE skipinstr = 1; /* skip next inter test after this instr */ +#endif goto skipi; /* skip int test */ } } @@ -2106,7 +2111,7 @@ wait_loop: /*25*/ irq_pend = 0; /* not pending anymore */ if (RDYQ_Num()) { uint32 chsa; /* channel/sub adddress */ -#ifndef NOTNOW +#ifdef USE_RDYQ if (waitrdyq > 0) { waitrdyq--; irq_pend = 1; /* still pending */ @@ -2145,7 +2150,9 @@ wait_loop: "Skipinstr %1x set @ attn int PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", skipinstr, PSD1, PSD2, CPUSTATUS); #endif +#ifdef NO_SKIP_HERE skipinstr = 1; /* skip next interrupt test only once */ +#endif goto newpsd; /* got process trap */ } @@ -3838,7 +3845,9 @@ skipit: "<|>IntX deactivate level %02x at CALM PSD1 %08x\n", irq_auto, PSD1); /*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ +#ifdef NO_SKIP_HERE /*051920*/ skipinstr = 1; /* skip interrupt test */ +#endif } } } @@ -5456,7 +5465,9 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS); "<|>IntX deactivate level %02x at SVC #%2x PSD1 %08x\n", irq_auto, temp2, PSD1); /*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ +#ifdef NO_SKIP_HERE /*051920*/ skipinstr = 1; /* skip interrupt test */ +#endif } } } @@ -6019,7 +6030,6 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS); TRAPSTATUS |= BIT18; /* set bit 18 of trap status */ goto newpsd; /* memory read error or map fault */ } -//bad /* 723 */ temp &= ~0x02000000; /* reset base reg bit 6 */ bc = CPUSTATUS; /* save the CPU STATUS */ TPSD[0] = PSD1; /* save the PSD for the instruction */ TPSD[1] = PSD2; @@ -6027,6 +6037,11 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS); ix = SPAD[0xf5]; /* save the current PSD2 */ reg = irq_pend; /* save intr status */ +#ifdef DO_DYNAMIC_DEBUG + /* start debugging */ + if (PC == 0x1e59c) + cpu_dev.dctrl |= (DEBUG_INST | DEBUG_TRAP | DEBUG_EXP | DEBUG_IRQ); +#endif if (opr & 0x0200) { /* Was it LPSDCM? */ if ((TRAPME = Mem_read(addr+4, &temp2))) { /* get PSD2 from memory */ if ((CPU_MODEL == MODEL_97) || (CPU_MODEL == MODEL_V9)) { @@ -6056,6 +6071,7 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS); modes = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ CPUSTATUS |= modes; /* now insert into CPUSTATUS */ +#ifdef NOTNEEDED /* set new arithmetic trap state in CPUSTATUS */ if (PSD1 & AEXPBIT) { CPUSTATUS |= AEXPBIT; /* set bit 7 of cpu status */ @@ -6068,6 +6084,7 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS); modes |= EXTDBIT; /* set extended mode */ } else CPUSTATUS &= ~EXTDBIT; /* reset bit 5 of cpu status */ +#endif /* set new map mode and interrupt blocking state in CPUSTATUS */ if (PSD2 & MAPBIT) { CPUSTATUS |= 0x00800000; /* set bit 8 of cpu status */ @@ -6087,7 +6104,9 @@ temp2, IR&0xFFF, PSD1, PSD2, CPUSTATUS); sim_debug(DEBUG_IRQ, &cpu_dev, "<|>IntX deactivate level %02x at LPSD(CM) %08x\n", irq_auto, PSD1); /*AIR*/ irq_auto = 0; /* show done processing in blocked mode */ +#ifdef NO_SKIP_HERE skipinstr = 1; /* skip interrupt test */ +#endif } } } @@ -6366,7 +6385,7 @@ TPSD[0], TPSD[1], PSD1, PSD2, TRAPME); INTS[prior] &= ~INTS_ACT; /* deactivate specified int level */ SPAD[prior+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ irq_pend = 1; /* start scanning interrupts again */ - /* instruction following a DAI cn not be interrupted */ + /* instruction following a DAI can not be interrupted */ /* skip tests for interrupts if this is the case */ #ifdef NOTNOW sim_debug(DEBUG_IRQ, &cpu_dev, @@ -6688,6 +6707,10 @@ mcheck: } } #endif + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "DCI INT %02x is NOT set chan %04x suba %04x status %08x\n", + ix, chan, suba, rstatus); /* SPAD entries for interrupts begin at 0x80 */ INTS[ix] &= ~INTS_ENAB; /* disable specified int level */ SPAD[ix+0x80] &= ~SINT_ENAB; /* disable in SPAD too */ @@ -6704,10 +6727,16 @@ mcheck: if ((TRAPME = checkxio(rchsa, &rstatus))) goto newpsd; /* error returned, trap cpu */ + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "ACI INT %02x is NOT set chan %04x suba %04x status %08x\n", + ix, chan, suba, rstatus); /* SPAD entries for interrupts begin at 0x80 */ INTS[ix] |= INTS_ACT; /* activate specified int level */ SPAD[ix+0x80] |= SINT_ACT; /* enable in SPAD too */ -//WAS INTS[ix] &= ~INTS_REQ; /* clears any requests also */ +//WAS NOT DONE INTS[ix] &= ~INTS_REQ; /* clears any requests also */ +/*917*/ /* tech manual says to remove any request */ +/*917*/ INTS[ix] &= ~INTS_REQ; /* clears any requests also */ PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ break; @@ -6720,18 +6749,15 @@ mcheck: if ((TRAPME = checkxio(rchsa, &rstatus))) goto newpsd; /* error returned, trap cpu */ - sim_debug(DEBUG_XIO, &cpu_dev, - "DACI after checkxio chan %04x suba %04x status %08x\n", chan, suba, rstatus); + if ((INTS[ix] & INTS_ACT) == 0) + sim_debug(DEBUG_XIO, &cpu_dev, + "DACI INT %02x is NOT set chan %04x suba %04x status %08x\n", + ix, chan, suba, rstatus); /* SPAD entries for interrupts begin at 0x80 */ INTS[ix] &= ~INTS_ACT; /* deactivate specified int level */ SPAD[ix+0x80] &= ~SINT_ACT; /* deactivate in SPAD too */ irq_pend = 1; /* start scanning interrupts again */ skipinstr = 1; /* skip interrupt test */ -#ifdef NOTNOW - sim_debug(DEBUG_XIO, &cpu_dev, - "DACI INTS[%02x] %08x Skipinstr %1x set PSD1 %08x PSD2 %08x CPUSTATUS %08x\n", - ix, INTS[ix], skipinstr, PSD1, PSD2, CPUSTATUS); -#endif PSD1 = ((PSD1 & 0x87fffffe) | (rstatus & 0x78000000)); /* insert status */ break; } /* end of XIO switch */ @@ -7078,6 +7104,20 @@ newpsd: modes = PSD1 & 0x87000000; /* extract bits 0, 5, 6, 7 from PSD 1 */ CPUSTATUS &= ~0x87000000; /* reset bits in CPUSTATUS */ CPUSTATUS |= modes; /* not insert into CPUSTATUS */ +#ifdef NOTNEEDED + /* set new arithmetic trap state in CPUSTATUS */ +/*917*/ if (PSD1 & AEXPBIT) { + CPUSTATUS |= AEXPBIT; /* set bit 7 of cpu status */ + modes |= AEXPBIT; /* set arithmetic exception mode */ + } else + CPUSTATUS &= ~AEXPBIT; /* reset bit 7 of cpu status */ +/*917*/ /* set new extended state in CPUSTATUS */ + if (PSD1 & EXTDBIT) { + CPUSTATUS |= EXTDBIT; /* set bit 5 of cpu status */ + modes |= EXTDBIT; /* set extended mode */ + } else + CPUSTATUS &= ~EXTDBIT; /* reset bit 5 of cpu status */ +#endif /* set new map mode and interrupt blocking state in CPUSTATUS */ if (PSD2 & MAPBIT) { CPUSTATUS |= 0x00800000; /* set bit 8 of cpu status */ diff --git a/SEL32/sel32_disk.c b/SEL32/sel32_disk.c index 69f844a..9a69fb8 100644 --- a/SEL32/sel32_disk.c +++ b/SEL32/sel32_disk.c @@ -98,30 +98,44 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option /* 26 words of scratchpad */ /* 4 words of label buffer registers */ -/* track label / sector label definations */ +/************************************/ +/* track label definations 34 bytes */ + /* for track 0, write max cyl/head/sec values in 0-3 */ + /* otherwise write current values */ /* - short lcyl; cylinder - char ltkn; track - char lid; sector id - char lflg1; track/sector status flags - bit 0 good - 1 alternate - 2 spare - 3 reserved - 4 flaw +0 short lcyl; cylinder +2 char ltkn; head or track number +3 char lid; track label id (0xff means last track) +4 char lflg1; track status flags + bit 0 good trk + 1 alternate trk + 2 spare trk + 3 reserved trk + 4 defective trk 5 last track - 6 start of alternate - char lflg2; - short lspar1; - short lspar2; - short ldef1; - int ldeallp; DMAP block number trk0 - int lumapp; UMAP block number sec1 - short ladef3; - short laltcyl; - char lalttk; sectors per track - char ldscnt; number of heads - char ldatrflg; device attributes + 6-7 n/u = 0 +5 char lflg2; + bit 0 write lock + 1 write protected + 2-7 n/u = 0 +6 short lspar1; n/u = 0 +8 short lspar2; n/u = 0 +10 short ldef1; defect #1 sec and byte position + * for track 0 write DMAP + * write sector number of cyl-4, hds-2, sec 0 value in 12-15 + * otherwise write current values +12 short ldef2; defect #2 sec and byte position +14 short ldef3; defect #3 sec and byte position + * for track 0 write UMAP which is DMAP - 2 * SPT + * write sector number of cyl-4, hds-4, sec 0 value in 16-19 + * otherwise write current values +16 short ladef1; defect #1 abs position +18 short ladef2; defect #2 abs position +20 short ladef3; defect #3 abs position +22 short laltcyl; alternate cylinder number or return cyl num +24 char lalttk; alrernate track number or return track num +25 char ldscnt; data sector count 16/20 +26 char ldatrflg; device attributes bit 0 n/u 1 disk is mhd 2 n/u @@ -131,9 +145,58 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option 6/7 00 768 bytes/blk 01 1024 bytes/blk 10 2048 bytes/blk - char ldatrscnt; sectors per track (again) - char ldatrmhdc; MHD head count - char ldatrfhdc; FHD head count +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count +30 uint32 lcrc; Label CRC-32 value + */ + +/*************************************/ +/* sector label definations 34 bytes */ +/* +0 short lcyl; cylinder number +2 char lhd; head number +3 char lsec; sec # 0-15 or 0-19 for 16/20 format +4 char lflg1; track/sector status flags + bit 0 good sec + 1 alternate sec + 2 spare sec + 3 reserved sec + 4 defective sec + 5 last sec + 6-7 n/u = 0 +5 char lflg2; + bit 0 write lock + 1 write protected + 2-7 n/u = 0 +6 short lspar1; n/u = 0 +8 short lspar2; n/u = 0 +10 short ldef1; defect #1 sec and byte position +12 short ldef2; defect #2 sec and byte position +14 short ldef3; defect #3 sec and byte position + * for track 0 write UMAP which is DMAP - 2 * SPT + * write sector number of cyl-4, hds-4, sec 0 value in 16-19 + * otherwise write zeros +16 short lspar3; n/u = 0 +18 short lspar4; n/u = 0 +20 short lspar5; n/u = 0 +22 short laltcyl; alternate cylinder number or return cyl num +24 char lalttk; alrernate track number or return track num +25 char ldscnt; data sector count 16/20 +26 char ldatrflg; device attributes + bit 0 n/u + 1 disk is mhd + 2 n/u + 3 n/u + 4 n/u + 5 dual ported + 6/7 00 768 bytes/blk + 01 1024 bytes/blk + 10 2048 bytes/blk +27 char ldatrscnt; sectors per track (again) +28 char ldatrmhdc; MHD head count +29 char ldatrfhdc; FHD head count +30 uint32 lcrc; Label CRC-32 value */ #define CMD u3 @@ -220,7 +283,7 @@ bits 24-31 - FHD head count (number of heads on FHD or number head on FHD option #define SNS_DADE 0x40 /* Disc addressing or seek error */ #define SNS_BUCK 0x20 /* Buffer check */ #define SNS_ECCS 0x10 /* ECC error in sector label */ -#define SNS_ECCD 0x08 /* ECC error iin data */ +#define SNS_ECCD 0x08 /* ECC error in data */ #define SNS_ECCT 0x04 /* ECC error in track label */ #define SNS_RTAE 0x02 /* Reserve track access error */ #define SNS_UESS 0x01 /* Uncorrectable ECC error */ @@ -292,11 +355,19 @@ disk_type[] = { /* Class F Disc Devices */ /* For MPX */ +#ifndef NOTFORMPX1X {"MH040", 5, 192, 20, 407, 411, 0x40}, /* 0 411 40M XXXX */ {"MH080", 5, 192, 20, 819, 823, 0x40}, /* 1 823 80M 8138 */ {"MH160", 10, 192, 20, 819, 823, 0x40}, /* 2 823 160M 8148 */ {"MH300", 19, 192, 20, 819, 823, 0x40}, /* 3 823 300M 8127 */ {"MH600", 40, 192, 20, 839, 843, 0x40}, /* 4 843 600M 8155 */ +#else + {"MH040", 5, 192, 20, 400, 411, 0x40}, /* 0 411 40M XXXX */ + {"MH080", 5, 192, 20, 800, 823, 0x40}, /* 1 823 80M 8138 */ + {"MH160", 10, 192, 20, 800, 823, 0x40}, /* 2 823 160M 8148 */ + {"MH300", 19, 192, 20, 800, 823, 0x40}, /* 3 823 300M 8127 */ + {"MH600", 40, 192, 20, 800, 843, 0x40}, /* 4 843 600M 8155 */ +#endif /* For UTX */ {"9342", 5, 256, 16, 819, 823, 0x41}, /* 5 823 80M XXXX */ {"8148", 10, 256, 16, 819, 823, 0x41}, /* 6 823 160M 8148 */ @@ -968,7 +1039,7 @@ t_stat disk_srv(UNIT *uptr) // sim_activate(uptr, 20); /* start things off */ sim_activate(uptr, 15); /* start things off */ #else - sim_activate(uptr, 150); + sim_activate(uptr, 150); /* start things off */ #endif break; } @@ -1600,7 +1671,8 @@ t_stat disk_srv(UNIT *uptr) buf[0] = (cyl >> 8) & 0xff; /* lcyl cyl upper 8 bits */ buf[1] = cyl & 0xff; /* lcyl cyl lower 8 bits */ buf[2] = trk & 0xff; /* ltkn trk */ - buf[3] = sec & 0xff; /* lid sector ID */ +// buf[3] = sec & 0xff; /* lid sector ID */ + buf[3] = 0xff; /* lid show as track label */ buf[4] = 0x80; /* show good sector */ sim_debug(DEBUG_DETAIL, dptr, @@ -1682,7 +1754,8 @@ t_stat disk_srv(UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "\n"); /* leave STAR "unnormalized" for diags */ - uptr->CHS += 0x10; /* bump to next track */ + if (uptr->CHS != 0) /* only incr address if not trk 0 */ + uptr->CHS += 0x10; /* bump to next track */ /* command done */ uptr->CMD &= LMASK; /* remove old status bits & cmd */ diff --git a/SEL32/sel32_hsdp.c b/SEL32/sel32_hsdp.c index c88793e..065fb75 100644 --- a/SEL32/sel32_hsdp.c +++ b/SEL32/sel32_hsdp.c @@ -23,6 +23,11 @@ #include "sel32_defs.h" +/* uncomment to use fast sim_activate times when running UTX */ +/* UTX gets an ioi error for dm0801 if slow times are used */ +/* dm0801 is not even a valid unit number for UDP controller */ +#define FAST_FOR_UTX + #if NUM_DEVS_HSDP > 0 #define UNIT_HSDP UNIT_ATTABLE | UNIT_IDLE | UNIT_DISABLE @@ -246,20 +251,20 @@ Byte 1 bits 7-15 #define SNS_DIAGMOD 0x08000000 /* Diagnostic Mode ECC Code generation and checking */ #define SNS_RSVTRK 0x04000000 /* Reserve Track mode: 1=OK to write, 0=read only */ #define SNS_FHDOPT 0x02000000 /* FHD or FHD option = 1 */ -#define SNS_RESERV 0x01000000 /* Reserved */ +#define SNS_RES1 0x01000000 /* Reserved */ /* Sense byte 1 */ #define SNS_CMDREJ 0x800000 /* Command reject */ #define SNS_INTVENT 0x400000 /* Unit intervention required */ -#define SNS_SPARE1 0x200000 /* Spare */ +#define SNS_USELE 0x200000 /* Unit Select Error */ #define SNS_EQUCHK 0x100000 /* Equipment check */ -#define SNS_DATCHK 0x080000 /* Data Check */ -#define SNS_OVRRUN 0x040000 /* Data overrun/underrun */ +#define SNS_RES2 0x080000 /* Reserved */ +#define SNS_RES3 0x040000 /* Reserved */ #define SNS_DSKFERR 0x020000 /* Disk format error */ #define SNS_DEFTRK 0x010000 /* Defective track encountered */ /* Sense byte 2 */ -#define SNS_LAST 0x8000 /* Last track flag encountered */ +#define SNS_RES4 0x8000 /* Reserved */ #define SNS_AATT 0x4000 /* At Alternate track */ #define SNS_WPER 0x2000 /* Write protection error */ #define SNS_WRL 0x1000 /* Write lock error */ @@ -271,11 +276,11 @@ Byte 1 bits 7-15 /* Sense byte 3 */ #define SNS_REVL 0x80 /* Revolution lost */ #define SNS_DADE 0x40 /* Disc addressing or seek error */ -#define SNS_BUCK 0x20 /* Buffer check */ -#define SNS_ECCS 0x10 /* ECC error in sector label */ -#define SNS_ECCD 0x08 /* ECC error iin data */ -#define SNS_ECCT 0x04 /* ECC error in track label */ -#define SNS_RTAE 0x02 /* Reserve track access error */ +#define SNS_RES5 0x20 /* Reserved */ +#define SNS_RES6 0x10 /* Reserved */ +#define SNS_ECCD 0x08 /* ECC error in data */ +#define SNS_RES7 0x04 /* Reserved */ +#define SNS_RES8 0x02 /* Reserved */ #define SNS_UESS 0x01 /* Uncorrectable ECC error */ #define SNS2 us9 @@ -345,17 +350,20 @@ hsdp_type[] = /* Class F Disc Devices */ /* For MPX */ {"MH040", 5, 192, 20, 407, 411, 0x40}, /* 0 411 40M XXXX */ - {"MH080", 5, 192, 20, 819, 823, 0x40}, /* 1 823 80M 8138 */ +// {"MH080", 5, 192, 20, 819, 823, 0x40}, /* 1 823 80M 8138 */ + {"MH080", 5, 192, 22, 819, 823, 0x40}, /* 1 823 80M 8138 */ {"MH160", 10, 192, 20, 819, 823, 0x40}, /* 2 823 160M 8148 */ {"MH300", 19, 192, 20, 819, 823, 0x40}, /* 3 823 300M 9346 */ {"MH600", 40, 192, 20, 839, 843, 0x40}, /* 4 843 600M 8155 */ + {"MH689", 16, 192, 54, 861, 865, 0x40}, /* 5 823 674M 8888 DP689 */ /* For UTX */ - {"9342", 5, 256, 16, 819, 823, 0x41}, /* 5 823 80M 9342 MH080 */ - {"8148", 10, 256, 16, 819, 823, 0x41}, /* 6 823 160M 8146 MH160 */ - {"9346", 19, 256, 16, 819, 823, 0x41}, /* 7 823 300M 9344 MH300 */ - {"8858", 24, 256, 16, 707, 711, 0x41}, /* 8 711 340M 8858 DC340 */ - {"8887", 10, 256, 35, 819, 823, 0x41}, /* 9 823 337M 8887 DP337 */ - {"8155", 40, 256, 16, 839, 843, 0x41}, /* 10 843 600M 8155 MH600 */ + {"9342", 5, 256, 16, 819, 823, 0x41}, /* 6 823 80M 9342 MH080 */ + {"8148", 10, 256, 16, 819, 823, 0x41}, /* 7 823 160M 8146 MH160 */ + {"9346", 19, 256, 16, 819, 823, 0x41}, /* 8 823 300M 9344 MH300 */ + {"8858", 24, 256, 16, 707, 711, 0x41}, /* 9 711 340M 8858 DC340 */ + {"8887", 10, 256, 35, 819, 823, 0x41}, /* 10 823 337M 8887 DP337 */ + {"8155", 40, 256, 16, 839, 843, 0x41}, /* 11 843 600M 8155 MH600 */ + {"8888", 16, 256, 43, 861, 865, 0x41}, /* 12 823 674M 8888 DP689 */ {NULL, 0} }; @@ -386,15 +394,15 @@ MTAB hsdp_mod[] = { UNIT dpa_unit[] = { /* SET_TYPE(3) DM300 */ -/* SET_TYPE(8) 8887 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x800)}, /* 0 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x802)}, /* 1 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x804)}, /* 2 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x806)}, /* 3 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x808)}, /* 4 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x80A)}, /* 5 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x80C)}, /* 6 */ - {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(8), 0), 0, UNIT_ADDR(0x80E)}, /* 7 */ +/* SET_TYPE(10) 8887 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x800)}, /* 0 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x802)}, /* 1 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x804)}, /* 2 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x806)}, /* 3 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x808)}, /* 4 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x80A)}, /* 5 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x80C)}, /* 6 */ + {UDATA(&hsdp_srv, UNIT_HSDP|SET_TYPE(10), 0), 0, UNIT_ADDR(0x80E)}, /* 7 */ }; DIB dpa_dib = { @@ -530,16 +538,27 @@ uint16 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) uptr->SNS &= ~SNS_CMDREJ; /* not rejected yet */ uptr->CMD |= DSK_INCH2; /* use 0xF0 for inch, just need int */ - sim_activate(uptr, 20); /* start things off */ +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 20); /* start things off */ + sim_activate(uptr, 30); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +#endif return SCPE_OK; /* good to go */ break; case DSK_NOP: /* NOP 0x03 */ +#ifdef NOT4HSDP if ((cmd == DSK_NOP) && (chp->chan_info & INFO_SIOCD)) { /* is NOP 1st IOCD? */ chp->chan_caw -= 8; /* backup iocd address for diags */ break; /* yes, can't be 1st */ } +#endif + case DSK_INC: /* 0xFF Initialize controller */ + if ((cmd == DSK_INC) && + (chp->ccw_count != 0x20)) /* count must be 32 to be valid */ + break; case DSK_SCK: /* Seek command 0x07 */ case DSK_XEZ: /* Rezero & Read IPL record 0x1f */ case DSK_WD: /* Write command 0x01 */ @@ -558,7 +577,12 @@ uint16 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd starting disk cmd %02x chsa %04x\n", cmd, chsa); - sim_activate(uptr, 20); /* start things off */ +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 20); /* start things off */ + sim_activate(uptr, 30); /* start things off */ +#else + sim_activate(uptr, 250); /* start things off */ +#endif return SCPE_OK; /* good to go */ break; @@ -567,6 +591,8 @@ uint16 hsdp_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) sim_debug(DEBUG_CMD, dptr, "hsdp_startcmd done with hsdp_startcmd %02x chsa %04x SNS %08x\n", cmd, chsa, uptr->SNS); + /* diags want the chan addr to point at bad command?? */ + chp->chan_caw -= 8; /* backup iocd address for diags */ uptr->SNS |= SNS_CMDREJ; /* cmd rejected */ return SNS_CHNEND|SNS_DEVEND|STATUS_PCHK; /* return error */ } @@ -645,6 +671,49 @@ t_stat hsdp_srv(UNIT *uptr) case 0: /* No command, stop disk */ break; + case DSK_INC: /* 0xFF Initialize controller */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + len = chp->ccw_count; /* INCH command count */ + mema = chp->ccw_addr; /* get inch or buffer addr */ + sim_debug(DEBUG_CMD, dptr, + "disk_srv cmd CONT INC %06x chsa %04x addr %06x count %04x completed\n", + chp->chan_inch_addr, chsa, mema, chp->ccw_count); + /* to use this inch method, byte count must be 0x20 */ + if (len != 0x20) { + /* we have invalid count, error, bail out */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + /* read all 32 bytes, stopping every 4 bytes to make words */ + /* the 8 words have drive data for each unit */ + /* WARNING 8 drives must be defined for this controller */ + /* so we will not have a map fault */ + for (i=0; i < 32; i++) { + if (chan_read_byte(chsa, &buf[i])) { + if (chp->chan_status & STATUS_PCHK) /* test for memory error */ + uptr->SNS |= SNS_INAD; /* invalid address */ + /* we have error, bail out */ + uptr->CMD &= LMASK; /* remove old status bits & cmd */ + uptr->SNS |= SNS_CMDREJ; + chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); + break; + } + if (((i+1)%4) == 0) { /* see if we have a word yet */ + /* drive attribute registers */ + /* may want to use this later */ + /* clear warning errors */ + tstart = (buf[i-3]<<24) | (buf[i-2]<<16) + | (buf[i-1]<<8) | (buf[i]); + } + } + uptr->CMD &= LMASK; /* remove old cmd */ + sim_debug(DEBUG_CMD, dptr, + "hsdp_srv cmd INC chsa %04x chsa %06x count %04x completed\n", + chsa, mema, chp->ccw_count); + chan_end(chsa, SNS_CHNEND|SNS_DEVEND); /* return OK */ + break; + case DSK_INCH2: /* use 0xF0 for inch, just need int */ len = chp->ccw_count; /* INCH command count */ mema = chp->ccw_addr; /* get inch or buffer addr */ @@ -970,7 +1039,12 @@ t_stat hsdp_srv(UNIT *uptr) sim_debug(DEBUG_CMD, dptr, "hsdp_srv seek over on cylinder unit=%02x %04x %04x\n", unit, uptr->STAR >> 16, uptr->CHS >> 16); uptr->CHS = uptr->STAR; /* we are there */ - sim_activate(uptr, 15); +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 15); + sim_activate(uptr, 20); /* start things off */ +#else + sim_activate(uptr, 150); /* start things off */ +#endif break; } } @@ -1092,8 +1166,14 @@ t_stat hsdp_srv(UNIT *uptr) sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv seek unit=%02x cyl %04x trk %02x sec %02x\n", unit, cyl, trk, buf[3]); - sim_activate(uptr, 20); /* start us off */ +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 15); + sim_activate(uptr, 20); /* start things off */ // sim_activate(uptr, 20+diff); /* start us off */ +#else +// sim_activate(uptr, 150); /* start things off */ + sim_activate(uptr, 200+diff); /* start us off */ +#endif } else { /* we are on cylinder/track/sector, so go on */ sim_debug(DEBUG_DETAIL, dptr, @@ -1236,9 +1316,6 @@ t_stat hsdp_srv(UNIT *uptr) break; } - /* get sector offset */ - tstart = STAR2SEC(uptr->CHS, SPT(type), SPC(type)); - /* see of over end of disk */ if (tstart >= (uint32)CAP(type)) { /* EOM reached, abort */ @@ -1264,7 +1341,13 @@ t_stat hsdp_srv(UNIT *uptr) sim_debug(DEBUG_DATA, dptr, "HSDP sector read complete, %x bytes to go from diskfile /%04x/%02x/%02x\n", chp->ccw_count, STAR2CYL(uptr->CHS), ((uptr->CHS) >> 8)&0xff, (uptr->CHS&0xff)); - sim_activate(uptr, 10); /* wait to read next sector */ +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 10); /* wait to read next sector */ +// sim_activate(uptr, 15); /* wait to read next sector */ + sim_activate(uptr, 20); /* wait to read next sector */ +#else + sim_activate(uptr, 150); /* wait to read next sector */ +#endif break; } uptr->CMD &= LMASK; /* remove old status bits & cmd */ @@ -1358,7 +1441,12 @@ t_stat hsdp_srv(UNIT *uptr) chan_end(chsa, SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK); break; } - sim_activate(uptr, 10); /* keep writing */ +#ifdef FAST_FOR_UTX +// sim_activate(uptr, 10); /* keep writing */ + sim_activate(uptr, 15); /* keep writing */ +#else + sim_activate(uptr, 150); /* wait to read next sector */ +#endif break; } uptr->CMD &= LMASK; /* remove old status bits & cmd */ @@ -1642,11 +1730,12 @@ t_stat hsdp_srv(UNIT *uptr) sim_debug(DEBUG_CMD, dptr, "invalid command %02x unit %02x\n", cmd, unit); uptr->SNS |= SNS_CMDREJ; uptr->CMD &= LMASK; /* remove old status bits & cmd */ - return SNS_CHNEND|STATUS_PCHK; + chan_end(chsa, SNS_CHNEND|STATUS_PCHK); /* return prog check */ break; } - sim_debug(DEBUG_DETAIL, dptr, "hsdp_srv done cmd=%02x chsa %04x count %04x\n", - cmd, chsa, chp->ccw_count); + sim_debug(DEBUG_DETAIL, dptr, + "hsdp_srv done cmd %02x chsa %04x chs %04x/%02x/%02x\n", + cmd, chsa, ((uptr->CHS)>>16)&0xffff, ((uptr->CHS)>>8)&0xff, (uptr->CHS)&0xff); return SCPE_OK; }