diff --git a/I7000/i7000_cdp.c b/I7000/i7000_cdp.c index 470398c..e471cce 100644 --- a/I7000/i7000_cdp.c +++ b/I7000/i7000_cdp.c @@ -245,20 +245,24 @@ cdp_srv(UNIT *uptr) { data = (struct _card_data *)uptr->up7; -#ifdef I7080 switch(chan_read_char(chan, &ch, 0)) { -#else - switch(chan_read_char(chan, &ch, - (uptr->u4 == 79)? DEV_REOR: 0)) { -#endif case TIME_ERROR: case END_RECORD: uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL; uptr->u5 &= ~URCSTA_WRITE; break; case DATA_OK: + if (ch == 0) + ch = 020; + else if (ch == 020) + ch = 0; sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch); data->image[uptr->u4++] = sim_bcd_to_hol(ch); + if (uptr->u4 == 80) { + chan_set(chan, DEV_REOR); + uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL; + uptr->u5 &= ~URCSTA_WRITE; + } break; } sim_activate(uptr, 10); diff --git a/I7000/i7000_cdr.c b/I7000/i7000_cdr.c index 02479c5..0e39b73 100644 --- a/I7000/i7000_cdr.c +++ b/I7000/i7000_cdr.c @@ -123,6 +123,9 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 &= ~0xF0000; uptr->u5 |= stk << 16; #endif + if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR)) + return SCPE_IOERR; + /* Process commands */ switch(cmd) { case IO_RDS: @@ -204,11 +207,12 @@ cdr_srv(UNIT *uptr) { chan_set_eof(chan); chan_set_attn(chan); chan_clear(chan, DEV_SEL); - uptr->u5 &= ~URCSTA_BUSY; + uptr->u5 |= URCSTA_EOF; + uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ); return SCPE_OK; case SCPE_IOERR: uptr->u5 |= URCSTA_ERR; - uptr->u5 &= ~URCSTA_BUSY; + uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ); chan_set_attn(chan); chan_clear(chan, DEV_SEL); return SCPE_OK; diff --git a/I7000/i7000_defs.h b/I7000/i7000_defs.h index 9f0b727..78bd285 100644 --- a/I7000/i7000_defs.h +++ b/I7000/i7000_defs.h @@ -228,6 +228,7 @@ typedef struct dib DIB; #define DEBUG_EXP 0x0000040 /* Show error conditions */ #define DEBUG_SNS 0x0000080 /* Shows sense data for 7909 devs */ #define DEBUG_CTSS 0x0000100 /* Shows CTSS specail instructions */ +#define DEBUG_PRIO 0x0000100 /* Debug Priority mode on 7010 */ #define DEBUG_PROT 0x0000200 /* Protection traps */ extern DEBTAB dev_debug[]; diff --git a/I7000/i7000_mt.c b/I7000/i7000_mt.c index f89b465..138d3e0 100644 --- a/I7000/i7000_mt.c +++ b/I7000/i7000_mt.c @@ -119,8 +119,10 @@ void mt_ini(UNIT *, t_bool); t_stat mt_reset(DEVICE *); t_stat mt_attach(UNIT *, CONST char *); t_stat mt_detach(UNIT *); -t_stat mt_rew(UNIT * uptr, int32 val, CONST char *cptr, void *desc); -t_stat mt_tape_density(UNIT * uptr, int32 val, CONST char *cptr, void *desc); +t_stat mt_rew(UNIT * uptr, int32 val, CONST char *cptr, + void *desc); +t_stat mt_tape_density(UNIT * uptr, int32 val, CONST char *cptr, + void *desc); t_stat mt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr); const char *mt_description (DEVICE *dptr); @@ -388,8 +390,9 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) /* Check status of the drive */ /* Can't do nothing if controller is busy */ - if (mt_chan[chan] & MTC_BSY) + if (mt_chan[chan] & MTC_BSY) { return SCPE_BUSY; + } /* If drive is offline or not attached return not ready */ if ((uptr->flags & (UNIT_ATT | MTUF_ONLINE)) != (UNIT_ATT | MTUF_ONLINE)) { @@ -402,8 +405,9 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) /* Return indication if not ready and doing TRS */ if (cmd == IO_TRS) { return SCPE_IOERR; - } else + } else { return SCPE_BUSY; + } } uptr->u5 &= ~(MT_CMDMSK | MT_RDY); time = us_to_ticks(12000); @@ -428,8 +432,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) #endif chan_set_sel(chan, 0); chan_clear_status(chan); - mt_chan[chan] &= MTC_BSY; - mt_chan[chan] |= MTC_SEL | unit; + mt_chan[chan] = 0; + mt_chan[chan] |= MTC_BSY | MTC_SEL | unit; uptr->u5 &= ~(MT_RM|MT_EOR|MT_EGAP); uptr->u6 = -1; uptr->hwmark = -1; @@ -467,8 +471,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->hwmark = 0; chan_set_sel(chan, 1); chan_clear_status(chan); - mt_chan[chan] &= MTC_BSY; - mt_chan[chan] |= MTC_SEL | unit; + mt_chan[chan] = 0; + mt_chan[chan] |= MTC_BSY | MTC_SEL | unit; uptr->u5 &= ~(MT_MARK | MT_EOT); #if I7010 | I7080 chan_set(chan, STA_TWAIT); @@ -487,8 +491,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 |= MT_RDB; chan_set_sel(chan, 0); chan_clear_status(chan); - mt_chan[chan] &= MTC_BSY; - mt_chan[chan] |= MTC_SEL | unit; + mt_chan[chan] = 0; + mt_chan[chan] |= MTC_BSY | MTC_SEL | unit; uptr->u5 &= ~(MT_RM|MT_EOR|MT_EGAP); uptr->u6 = -1; uptr->hwmark = -1; @@ -511,6 +515,10 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 |= MT_WEF; mt_chan[chan] |= MTC_BSY; #if I7010 | I7080 + chan_set_sel(chan, 1); + chan_clear_status(chan); + mt_chan[chan] = 0; + mt_chan[chan] |= MTC_BSY | MTC_SEL | unit; chan_set(chan, STA_TWAIT); #endif sim_debug(DEBUG_CMD, dptr, "WEF unit=%d\n", unit); @@ -527,7 +535,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) return SCPE_OK; } uptr->u5 |= MT_BSR; - mt_chan[chan] |= MTC_BSY; + mt_chan[chan] = MTC_BSY; sim_debug(DEBUG_CMD, dptr, "BSR unit=%d\n", unit); break; @@ -542,7 +550,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) return SCPE_OK; } uptr->u5 |= MT_BSF; - mt_chan[chan] |= MTC_BSY; + mt_chan[chan] = MTC_BSY; sim_debug(DEBUG_CMD, dptr, "BSF unit=%d\n", unit); break; @@ -551,7 +559,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) time = us_to_ticks(21000); uptr->u5 &= ~(MT_MARK|MT_EGAP); uptr->u5 |= MT_SKR; - mt_chan[chan] |= MTC_BSY; + mt_chan[chan] = MTC_BSY; sim_debug(DEBUG_CMD, dptr, "SKR unit=%d\n", unit); break; @@ -560,7 +568,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) #ifdef I7080 uptr->u5 &= ~(MT_MARK); uptr->u5 |= MT_ERG; - mt_chan[chan] |= MTC_BSY; + mt_chan[chan] = MTC_BSY; chan_set(chan, STA_TWAIT); break; #else @@ -579,7 +587,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) } time = 1000; uptr->u5 |= MT_REW; - mt_chan[chan] |= MTC_BSY; + mt_chan[chan] = MTC_BSY; sim_debug(DEBUG_CMD, dptr, "REW unit=%d\n", unit); sim_cancel(uptr); sim_activate(uptr, time); @@ -589,7 +597,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 &= ~(MT_EOT|MT_MARK|MT_EGAP); chan_clear_status(chan); uptr->u5 |= MT_RUN; - mt_chan[chan] |= MTC_BSY; + mt_chan[chan] = MTC_BSY; time = 1000; sim_debug(DEBUG_CMD, dptr, "RUN unit=%d\n", unit); sim_cancel(uptr); @@ -709,6 +717,9 @@ t_stat mt_error(UNIT * uptr, int chan, t_stat r, DEVICE * dptr) case MTSE_EOM: /* end of medium */ uptr->u5 |= MT_EOT; sim_debug(DEBUG_EXP, dptr, "EOT "); +#ifdef I7010 + chan_set_attn(chan); /* Set error */ +#endif break; } return SCPE_OK; @@ -735,37 +746,32 @@ t_stat mt_srv(UNIT * uptr) /* Channel has disconnected, abort current read. */ if ((mt_chan[chan] & 037) == (MTC_SEL | unit) && - chan_stat(chan, DEV_DISCO)) { + chan_stat(chan, DEV_DISCO)) { uptr->u5 &= ~MT_CMDMSK; -#ifdef I7010 - if ((cmd == MT_WRS || cmd == MT_WRSB) && uptr->u6 > 0) { - reclen = uptr->hwmark; -#else if (cmd == MT_WRS || cmd == MT_WRSB) { if (uptr->u6 > 0) { reclen = uptr->hwmark; -#endif uptr->u3 += GAP_LEN; sim_debug(DEBUG_DETAIL, dptr, - "Write flush unit=%d %s Block %d chars %d\n", - unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3); + "Write flush unit=%d %s Block %d chars\n", + unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen); r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen); mt_error(uptr, chan, r, dptr); /* Record errors */ -#ifndef I7010 } -#endif } else if (cmd == MT_RDS || cmd == MT_RDSB) { sim_debug(DEBUG_DETAIL, dptr, - "Read flush unit=%d %s Block %d chars %d\n", - unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen, uptr->u3); + "Read flush unit=%d %s Block %d chars\n", + unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen); /* Keep moving until end of block */ if (uptr->u6 < (int32)uptr->hwmark ) { - uptr->u3 += uptr->hwmark-uptr->u6; + reclen -= uptr->u6; + uptr->u3 += reclen; uptr->u5 |= MT_SKIP|MT_IDLE; uptr->u6 = 0; uptr->hwmark = 0; chan_clear(chan, DEV_DISCO | DEV_WEOR); - sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us); + sim_activate(uptr, reclen * T1_us); + mt_chan[chan] = 0; return SCPE_OK; } else { #ifndef I7010 @@ -780,12 +786,13 @@ t_stat mt_srv(UNIT * uptr) #endif } } - sim_activate(uptr, T2_us); + /* Allow time for tape to be restarted, before stop */ + sim_activate(uptr, us_to_ticks(500)); uptr->u6 = 0; uptr->hwmark = 0; sim_debug(DEBUG_CHAN, dptr, "Disconnect unit=%d\n", unit); uptr->u5 |= MT_IDLE|MT_RDY; - mt_chan[chan] &= MTC_BSY; + mt_chan[chan] = 0; chan_clear(chan, DEV_DISCO | DEV_WEOR | DEV_SEL); #if I7010 | I7080 chan_clear(chan, STA_TWAIT); @@ -808,9 +815,10 @@ t_stat mt_srv(UNIT * uptr) #else chan_clear(chan, DEV_SEL|STA_TWAIT); #endif - mt_chan[chan] &= MTC_BSY; /* Clear all but busy */ - sim_debug(DEBUG_DETAIL, dptr, "Skip unit=%d %d\n", unit, uptr->u3); - sim_activate(uptr, T2_us); + mt_chan[chan] = 0; + sim_debug(DEBUG_DETAIL, dptr, "Skip unit=%d\n", unit); + /* Allow time for tape to be restarted, before stop */ + sim_activate(uptr, us_to_ticks(500)); return SCPE_OK; case MT_RDS: @@ -818,7 +826,6 @@ t_stat mt_srv(UNIT * uptr) /* Fall through */ case MT_RDSB: -#ifndef I7010 /* Post EOR */ if (uptr->u5 & MT_EOR) { sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit); @@ -827,7 +834,7 @@ t_stat mt_srv(UNIT * uptr) sim_activate(uptr, T1_us); return SCPE_OK; } -#endif + /* If tape mark pending, return it */ if (chan_test(chan, DEV_FULL) == 0 && uptr->u5 & MT_MARK) { sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post ", unit); @@ -849,7 +856,7 @@ t_stat mt_srv(UNIT * uptr) } /* If at end of record, fill buffer */ if (uptr->u6 == uptr->hwmark) { - sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d %d", unit,uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d ", unit); uptr->u3 += GAP_LEN; if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen, BUFFSIZE)) != MTSE_OK) { @@ -865,15 +872,16 @@ t_stat mt_srv(UNIT * uptr) if (r == MTSE_TMK && astmode) { sim_debug(DEBUG_DETAIL, dptr, "Read TM "); ch = mode?017:054; - chan_write_char(chan, &ch, DEV_REOR); - chan_set_eof(chan); + chan_write_char(chan, &ch, 0); + chan_set_attn(chan); + chan_set(chan, DEV_REOR); chan_clear(chan, STA_TWAIT); if (mode) { sim_activate(uptr, T1_us); return SCPE_OK; } + chan_set_error(chan); } - chan_set_error(chan); #else chan_set_attn(chan); #endif @@ -901,9 +909,9 @@ t_stat mt_srv(UNIT * uptr) if (astmode) ch = 054; #else - chan_set_error(chan); chan_set_attn(chan); #endif + chan_set_error(chan); } #if I7090 | I704 | I701 /* Not needed on decimal machines */ @@ -921,6 +929,12 @@ t_stat mt_srv(UNIT * uptr) } } } +#endif +#ifdef I7010 + if (mode) { + if (ch == 0120) + ch = 0; + } #endif ch &= 077; @@ -941,14 +955,9 @@ t_stat mt_srv(UNIT * uptr) case DATA_OK: sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %02o\n", unit, uptr->u6, ch); - if (uptr->u6 >= (int32)uptr->hwmark) { /* In IRG */ + if (uptr->u6 >= (int32)uptr->hwmark) /* In IRG */ uptr->u5 |= MT_EOR; -#ifdef I7010 - (void)chan_write_char(chan, &ch, DEV_WEOR); -#endif - sim_activate(uptr, T1_us); - } else - sim_activate(uptr, T1_us); + sim_activate(uptr, T1_us); break; case TIME_ERROR: @@ -969,7 +978,7 @@ t_stat mt_srv(UNIT * uptr) /* fall through */ case MT_WRSB: if (uptr->u5 & MT_EGAP) { - sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d %d\n", unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit); uptr->u5 &= ~MT_EGAP; r = sim_tape_wrgap(uptr, 35); sim_activate(uptr, 10*T3_us); @@ -979,7 +988,7 @@ t_stat mt_srv(UNIT * uptr) switch (chan_read_char(chan, &ch, (uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) { case TIME_ERROR: -#ifdef I7010 +#if I7090 | I701 | I704 /* If no data was written, simulate a write gap */ if (uptr->u6 == 0) { r = sim_tape_wrgap(uptr, 35); @@ -992,8 +1001,8 @@ t_stat mt_srv(UNIT * uptr) if (uptr->u6 > 0) { /* Only if data in record */ reclen = uptr->hwmark; sim_debug(DEBUG_DETAIL, dptr, - "Write unit=%d %s Block %d chars %d\n", - unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3); + "Write unit=%d %s Block %d chars\n", + unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen); r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen); uptr->u3 += GAP_LEN; uptr->u6 = 0; @@ -1108,13 +1117,13 @@ t_stat mt_srv(UNIT * uptr) case MT_WEF: if (uptr->u5 & MT_EGAP) { - sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d %d\n", unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit); uptr->u5 &= ~MT_EGAP; r = sim_tape_wrgap(uptr, 35); sim_activate(uptr, 10*T3_us); return SCPE_OK; } - sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d %d\n", unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit); uptr->u5 &= ~(MT_CMDMSK|MT_MARK); uptr->u5 |= (MT_RDY); r = sim_tape_wrtmk(uptr); @@ -1122,12 +1131,12 @@ t_stat mt_srv(UNIT * uptr) mt_chan[chan] &= ~MTC_BSY; sim_activate(uptr, T2_us); #if I7010 | I7080 - chan_clear(chan, STA_TWAIT); + chan_set(chan, DEV_REOR); #endif break; case MT_BSR: - sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d %d ", unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit); /* Clear tape mark, command, idle since we will need to change dir */ uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY); r = sim_tape_sprecr(uptr, &reclen); @@ -1156,8 +1165,7 @@ t_stat mt_srv(UNIT * uptr) uptr->u3 -= GAP_LEN; /* If we hit mark or end of tape */ if (r == MTSE_TMK || r == MTSE_BOT) { - sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d %d\n", - unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d\n", unit); uptr->u5 &= ~MT_CMDMSK; mt_chan[chan] &= ~MTC_BSY; sim_activate(uptr, T2_us); @@ -1241,7 +1249,7 @@ t_stat mt_srv(UNIT * uptr) return SCPE_OK; case MT_HREW: - sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d HS %d\n", unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d HS\n", unit); if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) { uptr->u3 -= (uptr->flags & MTUF_LDN) ? 1666 :4625; sim_activate(uptr, us_to_ticks(16000)); @@ -1253,7 +1261,7 @@ t_stat mt_srv(UNIT * uptr) return SCPE_OK; case MT_LREW: - sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d LS %d\n", unit, uptr->u3); + sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d LS\n", unit); if (uptr->u3 > 0) { uptr->u3 -= (uptr->flags & MTUF_LDN) ? 373 :1036; sim_activate(uptr, us_to_ticks(16000)); @@ -1291,7 +1299,8 @@ mt_boot(int32 unit_num, DEVICE * dptr) return STOP_IONRDY; #if I7090 | I704 | I701 - r = sim_tape_rdrecf(uptr, &mt_buffer[GET_DEV_BUF(dptr->flags)][0], &reclen, BUFFSIZE); + r = sim_tape_rdrecf(uptr, &mt_buffer[GET_DEV_BUF(dptr->flags)][0], &reclen, + BUFFSIZE); if (r != SCPE_OK) return r; uptr->u6 = 0; diff --git a/I7000/i7010_chan.c b/I7000/i7010_chan.c index 1a4a6be..763c854 100644 --- a/I7000/i7010_chan.c +++ b/I7000/i7010_chan.c @@ -289,6 +289,7 @@ chan_proc() /* Scan channels looking for work */ for (chan = 0; chan < NUM_CHAN; chan++) { + /* Skip if channel is disabled */ if (chan_unit[chan].flags & UNIT_DIS) continue; @@ -299,12 +300,12 @@ chan_proc() continue; if (chan_flags[chan] & CHS_EOF) { - chan_io_status[chan] |= 010; + chan_io_status[chan] |= IO_CHS_COND; chan_flags[chan] &= ~CHS_EOF; } if (chan_flags[chan] & CHS_ERR) { - chan_io_status[chan] |= 004; + chan_io_status[chan] |= IO_CHS_CHECK; chan_flags[chan] &= ~CHS_ERR; } @@ -340,7 +341,7 @@ chan_proc() chan_flags[chan] &= ~(CTL_END); else chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END); - chan_io_status[chan] |= 0100; + chan_io_status[chan] |= IO_CHS_DONE; } continue; } @@ -360,27 +361,52 @@ chan_proc() (chan_flags[chan] & (CTL_END|SNS_UEND))) { if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_WEOR|DEV_DISCO; - chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END|CTL_READ|CTL_WRITE); + chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END|CTL_READ + |CTL_WRITE); if (chan_dev.dctrl & cmask) sim_debug(DEBUG_CHAN, &chan_dev, "chan %d end\n", chan); cmd[chan] &= ~CHAN_DSK_SEEK; - chan_io_status[chan] |= 0100; + chan_io_status[chan] |= IO_CHS_DONE; } /* If device put up EOR, terminate transfer. */ if (chan_flags[chan] & DEV_REOR) { - if (chan_dev.dctrl & cmask) - sim_debug(DEBUG_EXP, &chan_dev, "chan %d EOR\n", chan); if (chan_flags[chan] & DEV_WRITE) { if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD)) M[caddr[chan]++] = 035; caddr[chan]++; + } else { + if ((cmd[chan] & CHAN_NOREC) == 0 && + (chan_flags[chan] & STA_WAIT) == 0) { + if (MEM_ADDR_OK(caddr[chan])) { + if (M[caddr[chan]++] != (WM|077)) { + if (MEM_ADDR_OK(caddr[chan])) { + chan_io_status[chan] |= IO_CHS_WRL; + if (!MEM_ADDR_OK(caddr[chan]+1)) { + caddr[chan]++; + } + } + } + } else { + chan_io_status[chan] |= IO_CHS_WRL; + } + } + if ((cmd[chan] & CHAN_NOREC) && MEM_ADDR_OK(caddr[chan])) { + chan_io_status[chan] |= IO_CHS_WRL; + if (!MEM_ADDR_OK(caddr[chan]+1)) { + chan_io_status[chan] &= ~IO_CHS_WRL; + } + caddr[chan]++; + } } - chan_flags[chan] &= ~(CHS_ATTN|STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR); - chan_io_status[chan] |= 0100; + chan_flags[chan] &= ~(STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR); + chan_io_status[chan] |= IO_CHS_DONE; /* Disconnect if selected */ if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= (DEV_DISCO); + if (chan_dev.dctrl & cmask) + sim_debug(DEBUG_EXP, &chan_dev, "chan %d EOR %d %o\n", chan, + caddr[chan], chan_io_status[chan]); continue; } @@ -392,14 +418,14 @@ chan_proc() /* If device requested attention, abort current command */ if (chan_flags[chan] & CHS_ATTN) { - if (chan_dev.dctrl & cmask) - sim_debug(DEBUG_EXP, &chan_dev, "chan %d Attn\n", - chan); chan_flags[chan] &= ~(CHS_ATTN|STA_ACTIVE|STA_WAIT); - chan_io_status[chan] |= 0110; + chan_io_status[chan] |= IO_CHS_DONE|IO_CHS_COND; /* Disconnect if selected */ if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= (DEV_DISCO); + if (chan_dev.dctrl & cmask) + sim_debug(DEBUG_EXP, &chan_dev, "chan %d Attn %o\n", + chan, chan_io_status[chan]); continue; } } @@ -432,7 +458,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) if (chan_unit[chan].flags & UNIT_DIS) return SCPE_IOERR; /* Unit is busy doing something, wait */ - if (chan_flags[chan] & (DEV_SEL| DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE)) + if (chan_flags[chan] & (DEV_SEL|DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE)) return SCPE_BUSY; /* Ok, try and find the unit */ caddr[chan] = addr; @@ -442,11 +468,12 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) cmd[chan] |= CHAN_NOREC; if (dcmd & 0200) /* Opcode L */ cmd[chan] |= CHAN_LOAD; - if ((dev >> 12) & 010) /* Check overlap operation */ - cmd[chan] |= CHAN_OVLP; + else + cmd[chan] |= CHAN_WM; /* Force first char to have word mark set */ dcmd = (dcmd >> 8) & 0x7f; chunit[chan] = dev; - chan_flags[chan] &= ~(CTL_CNTL|CTL_READ|CTL_WRITE|SNS_UEND|CTL_WRITE|CTL_SNS|STA_PEND); + chan_flags[chan] &= ~(CTL_CNTL|CTL_READ|CTL_WRITE|SNS_UEND|CTL_WRITE + |CTL_SNS|STA_PEND); /* Handle disk device special */ if ((dsk_dib.mask & dev) == (dsk_dib.addr & dsk_dib.mask)) { uint16 dsk_cmd = 0; @@ -533,44 +560,25 @@ chan_write_char(int chan, uint8 * data, int flags) { uint8 ch = *data; + sim_debug(DEBUG_DATA, &chan_dev, "chan %d char %o %d %o %o\n", chan, + *data, caddr[chan], chan_io_status[chan], flags); - /* If Writing end of record, abort */ - if (flags & DEV_WEOR) { - sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d WEor %d %o ->", chan, caddr[chan], - chan_io_status[chan]); - if (chan_flags[chan] & DEV_REOR) - chan_io_status[chan] |= 0040; - else if (MEM_ADDR_OK(caddr[chan])) { - sim_debug(DEBUG_DETAIL, &chan_dev, "memok %02o %02o ", M[caddr[chan]], M[caddr[chan]+1]); - if ((cmd[chan] & CHAN_NOREC) == 0 && M[caddr[chan]] != (WM|077)) { - sim_debug(DEBUG_DETAIL, &chan_dev, "nogm "); - if (MEM_ADDR_OK(caddr[chan]+1)) - chan_io_status[chan] |= 0040; - } - caddr[chan]++; - } - else - chan_io_status[chan] |= 0040; - - chan_flags[chan] |= DEV_REOR; - if (chan_flags[chan] & DEV_SEL) - chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0100; - chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE); - chan_flags[chan] &= ~(DEV_WEOR); - sim_debug(DEBUG_DETAIL, &chan_dev, "%d %o\n", caddr[chan], chan_io_status[chan]); + if (chan_flags[chan] & STA_WAIT) { + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWR %d %o\n", chan, + caddr[chan], chan_io_status[chan]); + chan_io_status[chan] |= IO_CHS_WRL; return END_RECORD; } /* Check if end of data */ - if ((chan_flags[chan] & DEV_REOR) == 0 && - (cmd[chan] & CHAN_NOREC) == 0 && - M[caddr[chan]] == (WM|077)) { - chan_flags[chan] |= DEV_REOR; + if ((chan_flags[chan] & STA_WAIT) == 0 && (cmd[chan] & CHAN_NOREC) == 0 && + M[caddr[chan]] == (WM|077)) { + chan_flags[chan] |= STA_WAIT; /* Saw group mark */ + chan_io_status[chan] |= IO_CHS_WRL; caddr[chan]++; - sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d GEor %d %o\n", chan, caddr[chan], - chan_io_status[chan]); - return DATA_OK; + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d GEor %d %o\n", chan, + caddr[chan], chan_io_status[chan]); + return END_RECORD; } /* If over size of memory, terminate */ @@ -578,10 +586,10 @@ chan_write_char(int chan, uint8 * data, int flags) chan_flags[chan] |= DEV_REOR; if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0100; + chan_io_status[chan] |= IO_CHS_DONE; caddr[chan]++; - sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan, caddr[chan], - chan_io_status[chan]); + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan, + caddr[chan], chan_io_status[chan]); chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE); return DATA_OK; } @@ -598,25 +606,16 @@ chan_write_char(int chan, uint8 * data, int flags) if ((cmd[chan] & CHAN_LOAD) == 0) ch |= M[caddr[chan]] & WM; if ((chan_flags[chan] & DEV_REOR) == 0) - M[caddr[chan]] = ch; + M[caddr[chan]] = ch; caddr[chan]++; } - chan_io_status[chan] &= ~020; + /* If device gave us an end, terminate transfer */ if (flags & DEV_REOR) { chan_flags[chan] |= DEV_REOR; - if (chan_flags[chan] & DEV_SEL) - chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0100; - chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE); - if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD)) - M[caddr[chan]++] = 035; - caddr[chan]++; - if ((cmd[chan] & CHAN_NOREC) == 0 && M[caddr[chan]+1] != (WM|077)) - chan_io_status[chan] |= 040; - sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d Eor %d %o %x\n", chan, caddr[chan], - chan_io_status[chan], chan_flags[chan]); + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d Eor %d %o %x\n", chan, + caddr[chan], chan_io_status[chan], chan_flags[chan]); return END_RECORD; } @@ -630,10 +629,11 @@ chan_write_char(int chan, uint8 * data, int flags) int chan_read_char(int chan, uint8 * data, int flags) { + /* Return END_RECORD if requested */ if (flags & DEV_WEOR) { chan_flags[chan] &= ~(DEV_WEOR); - chan_io_status[chan] |= 0100; + chan_io_status[chan] |= IO_CHS_DONE; return END_RECORD; } @@ -648,7 +648,6 @@ chan_read_char(int chan, uint8 * data, int flags) return END_RECORD; *data &= 077; caddr[chan]++; - chan_io_status[chan] &= ~020; return DATA_OK; } @@ -665,13 +664,12 @@ chan_read_char(int chan, uint8 * data, int flags) return END_RECORD; } assembly[chan] = M[caddr[chan]++]; - chan_io_status[chan] &= ~020; /* Handle end of record */ if ((cmd[chan] & CHAN_NOREC) == 0 && assembly[chan] == (WM|077)) { chan_flags[chan] &= ~STA_ACTIVE; if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0100; + chan_io_status[chan] |= IO_CHS_DONE; return END_RECORD; } if (cmd[chan] & CHAN_LOAD && @@ -691,7 +689,7 @@ chan_read_char(int chan, uint8 * data, int flags) chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE); if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0100; + chan_io_status[chan] |= IO_CHS_DONE; chan_flags[chan] |= DEV_REOR; return END_RECORD; } else diff --git a/I7000/i7010_cpu.c b/I7000/i7010_cpu.c index 2bc31a6..106ac5e 100644 --- a/I7000/i7010_cpu.c +++ b/I7000/i7010_cpu.c @@ -107,7 +107,7 @@ t_stat do_divide(); /* Interval timer option */ t_stat rtc_srv(UNIT * uptr); t_stat rtc_reset(DEVICE * dptr); - +int32 rtc_tps = 200; /* General registers */ @@ -134,6 +134,7 @@ uint8 urec_irq[NUM_CHAN]; /* Unit record IRQ pending */ uint8 astmode = 1; /* Astrisk mode */ uint8 chan_io_status[NUM_CHAN]; /* Channel status */ uint8 chan_seek_done[NUM_CHAN]; /* Channel seek finished */ +uint8 chan_irq_enb[NUM_CHAN]; /* IRQ type opcode */ uint8 lpr_chan9[NUM_CHAN]; /* Line printer at channel 9 */ uint8 lpr_chan12[NUM_CHAN]; /* Line printer at channel 12 */ extern uint32 caddr[NUM_CHAN]; /* Channel addresses */ @@ -145,10 +146,11 @@ uint8 prot_enb = 0; /* Protection enables */ uint8 relo_flags = 0; /* Relocation flags */ uint8 timer_irq = 0; /* Interval timer interrupt */ uint8 timer_enable = 0; /* Interval timer enable */ -uint8 timer_interval = 0; /* Interval timer interval */ +int timer_interval = 0; /* Interval timer interval */ int chwait = 0; /* Wait for channel to finish */ int io_flags = 0; /* Io flags for 1401 */ int cycle_time = 28; /* Cycle time in 100ns */ +uint8 time_digs[] = {0, 2, 3, 5, 7, 8}; /* History information */ int32 hst_p = 0; /* History pointer */ @@ -156,6 +158,16 @@ int32 hst_lnt = 0; /* History length */ struct InstHistory *hst = NULL; /* History stack */ extern UNIT chan_unit[]; +/* Simulator debug controls */ +DEBTAB cpu_debug[] = { + {"CHANNEL", DEBUG_CHAN}, + {"TRAP", DEBUG_TRAP}, + {"CMD", DEBUG_CMD}, + {"DETAIL", DEBUG_DETAIL}, + {"EXP", DEBUG_EXP}, + {"PRI", DEBUG_PRIO}, + {0, 0} +}; @@ -227,7 +239,7 @@ DEVICE cpu_dev = { "CPU", &cpu_unit, cpu_reg, cpu_mod, 1, 10, 18, 1, 8, 8, &cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL, - NULL, DEV_DEBUG, 0, dev_debug, + NULL, DEV_DEBUG, 0, cpu_debug, NULL, NULL, &cpu_help, NULL, NULL, &cpu_description }; @@ -547,8 +559,6 @@ void ClrBit(uint32 MA, uint8 v) { t_stat sim_instr(void) { - time_t curtim; - struct tm *tptr; t_stat reason; uint16 t; int temp; @@ -1315,7 +1325,8 @@ sim_instr(void) int irq = inquiry; int ok_irq = 0; for(i = 1; i < NUM_CHAN; i++ ) { - if ((chan_io_status[i] & 0300) == 0300) + if ((chan_io_status[i] & 0300) == 0300 && + chan_irq_enb[i]) irq = 1; if (chan_test(i, SNS_ATTN1)) irq = 1; @@ -1377,6 +1388,7 @@ sim_instr(void) } if (ok_irq) { + sim_debug(DEBUG_PRIO, &cpu_dev, "Irq IAR=%d\n",IAR); prot_enb = reloc = 0; if (pri_enb && irq) { IAR = temp; @@ -1511,17 +1523,20 @@ sim_instr(void) case CHR_G: temp = caddr[3]; break; /* G */ case CHR_H: temp = caddr[4]; break; /* H */ case CHR_T: /* T */ - curtim = time(NULL); /* get time */ - tptr = localtime(&curtim); /* decompose */ - if (tptr == NULL) - break; /* error? */ + { + time_t curtim; + struct tm *tptr; - /* Convert minutes to 100th hour */ - temp = tptr->tm_min * 1000; - temp /= 60; - temp += 5; /* Round */ - temp /= 10; /* Truncate low digit */ - temp += tptr->tm_hour * 100; + temp = 99999; + curtim = time(NULL); /* get time */ + tptr = localtime(&curtim); /* decompose */ + if (tptr != NULL && tptr->tm_sec != 59) { + /* Convert minutes to 100th hour */ + temp = time_digs[tptr->tm_min % 6]; + temp += 10 * (tptr->tm_min / 6); + temp += 100 * tptr->tm_hour; + } + } break; default: temp = 0; break; } @@ -1954,7 +1969,7 @@ sim_instr(void) jump = 1; tind = 0; } else { - for(i = 1; i <= NUM_CHAN && jump == 0; i++) + for(i = 1; i <= NUM_CHAN && jump == 0; i++) jump = chan_stat(i, STA_PEND); if (jump) sim_debug(DEBUG_CMD, &cpu_dev, "Tape Ind\n"); @@ -1966,13 +1981,20 @@ sim_instr(void) case CHR_STAR: /* * Inq req ch 2 */ break; case CHR_1: /* 1 Overlap in Proc Ch 1 */ - jump = chan_active(1); + jump = ((chan_io_status[1] & 0300) == 0200) && + chan_active(1); break; case CHR_2: /* 2 Overlap in Proc Ch 2 */ - jump = chan_active(2); + jump = ((chan_io_status[2] & 0300) == 0200) && + chan_active(2); + break; + case CHR_4: /* 4 Channel 3 */ + jump = ((chan_io_status[3] & 0300) == 0200) && + chan_active(3); break; case CHR_RPARN: /* ) Channel 4 */ - jump = chan_active(4); + jump = ((chan_io_status[4] & 0300) == 0200) && + chan_active(4); break; case CHR_9: /* 9 Carriage 9 CH1 */ /* 1401 same */ jump = lpr_chan9[1]; @@ -2126,9 +2148,6 @@ sim_instr(void) case OP_RD: case OP_RDW: - /* Check if over the top */ - ValidAddr(BAR); - /* Decode operands */ /* X1 digit 1 == channel 034 % non-overlap */ /* 2 == channel 074 sq non-overlap */ @@ -2146,7 +2165,7 @@ sim_instr(void) /* F == Disk 066 */ /* K == Com 042 */ /* X3 digit device option or unit number */ - /* op_mod R == Read 051 */ + /* op_mod R == Read 051 */ /* $ == Read 053 ignore word/group */ /* W == Write 026 */ /* X == Write 027 ignore word/group */ @@ -2167,10 +2186,6 @@ sim_instr(void) } temp = ch << 12; - if (chan_io_status[ch & 07] & 0200) { - reason = STOP_IOCHECK; - break; - } if ((XR & 07700) == 06200) { if ((XR & 017) != 10) temp |= XR & 017; @@ -2183,13 +2198,6 @@ sim_instr(void) temp |= XR & 07777; } - while (chan_active(ch & 07) && reason == 0) { - sim_interval = 0; - reason = sim_process_event(); - chan_proc(); - } - if (reason != 0) - break; switch(op_mod) { case CHR_R: t = (IO_RDS << 8); break; /* R */ @@ -2207,6 +2215,14 @@ sim_instr(void) if (reason != 0) break; + while (chan_active(ch & 07) && reason == 0) { + sim_interval = 0; + reason = sim_process_event(); + chan_proc(); + } + if (reason != 0) + break; + if (op == OP_RDW) t |= 0200; if ((ch & 010) == 0) @@ -2215,23 +2231,33 @@ sim_instr(void) /* Try to start command */ switch (chan_cmd(temp, t, BAR & AMASK)) { case SCPE_OK: - chan_io_status[ch & 07] = 0220; + if (ch & 010) { + chan_io_status[ch & 07] = 0; + chwait = ch & 07; + chan_irq_enb[ch & 7] = 0; + } else { + chan_io_status[ch & 07] = IO_CHS_OVER; + chan_irq_enb[ch & 7] = 1; + } sim_debug(DEBUG_CMD, &cpu_dev, - "%d %c on %o %s %c\n", IAR, sim_six_to_ascii[op], ch & 07, - (ch & 010)?"":"overlap", sim_six_to_ascii[op_mod]); - + "%d %c on %o %o %s %c\n", IAR, sim_six_to_ascii[op], + ch & 07, temp, + (ch & 010)?"":"overlap", + sim_six_to_ascii[op_mod]); break; case SCPE_BUSY: - chan_io_status[ch & 07] = 0002; + sim_debug(DEBUG_CMD, &cpu_dev, + "%d %c Busy on %o %s %c %o\n", IAR, + sim_six_to_ascii[op], ch & 07, + (ch & 010)?"": "overlap", + sim_six_to_ascii[op_mod], chan_io_status[ch & 07]); + chan_io_status[ch & 07] = IO_CHS_BUSY; break; case SCPE_NODEV: case SCPE_IOERR: - chan_io_status[ch & 07] = 0001; + chan_io_status[ch & 07] = IO_CHS_NORDY; break; } - /* Handle waiting */ - if ((ch & 010) && (chan_io_status[ch & 07] & 3) == 0) - chwait = ch & 07; if (CPU_MODEL == 1) chan_io_status[ch & 07] &= 0177; break; @@ -2243,16 +2269,17 @@ sim_instr(void) chan_io: switch (chan_cmd(temp, t, 0)) { case SCPE_OK: - chan_io_status[ch & 07] = 0020; + chan_io_status[ch & 07] = 0000; if (ch & 010) chwait = (ch & 07) | 040; + chan_irq_enb[ch & 7] = 0; break; case SCPE_BUSY: - chan_io_status[ch & 07] = 0002; + chan_io_status[ch & 07] = IO_CHS_BUSY; break; case SCPE_NODEV: case SCPE_IOERR: - chan_io_status[ch & 07] = 0001; + chan_io_status[ch & 07] = IO_CHS_NORDY; break; } break; @@ -2299,19 +2326,22 @@ sim_instr(void) temp |= 02400; t = 0; switch(op_mod) { - case CHR_B: t = (IO_BSR << 8); ch &= 07; break; - case CHR_A: t = (IO_SKR << 8); ch &= 07; break; - case CHR_R: t = (IO_REW << 8); ch &= 07; break; - case CHR_GT: t = (IO_RUN << 8); ch &= 07; break; - case CHR_E: t = (IO_ERG << 8); ch &= 07; break; + case CHR_B: t = (IO_BSR << 8); ch |= 010; break; + case CHR_A: t = (IO_SKR << 8); ch |= 010; break; + case CHR_R: t = (IO_REW << 8); ch |= 010; break; + case CHR_GT: t = (IO_RUN << 8); ch |= 010; break; + case CHR_E: t = (IO_ERG << 8); ch |= 010; break; case CHR_M: t = (IO_WEF << 8); break; default: t = 0; reason = STOP_UUO; break; } - if (chan_io_status[ch & 07] & 0200) { - reason = STOP_IOCHECK; - break; + while (chan_active(ch & 07) && reason == 0) { + sim_interval = 0; + reason = sim_process_event(); + chan_proc(); } + if (reason != 0) + break; /* For nop, set command done */ if (t == 0) { chan_io_status[ch & 07] = 0000; @@ -2323,24 +2353,27 @@ sim_instr(void) chan_io_status[ch & 07] = 0000; if (ch & 010) { chwait = (ch & 07) | 040; + } else if (op_mod == CHR_M) { + chan_io_status[ch & 07] = IO_CHS_OVER; } + chan_irq_enb[ch & 7] = 0; sim_debug(DEBUG_CMD, &cpu_dev, - "%d UC on %o %s %c\n", IAR, ch & 07, - (ch & 010)?"": "overlap", sim_six_to_ascii[op_mod]); + "%d UC on %o %o %s %c %o\n", IAR, ch & 07, temp, + (ch & 010)?"": "overlap", + sim_six_to_ascii[op_mod], chan_io_status[ch & 07]); break; case SCPE_BUSY: - sim_debug(DEBUG_CMD, &cpu_dev, - "%d UC on %o %c Busy\n", IAR, ch & 07, sim_six_to_ascii[op_mod]); - chan_io_status[ch & 07] = 0002; + chan_io_status[ch & 07] = IO_CHS_BUSY; break; case SCPE_NODEV: case SCPE_IOERR: - chan_io_status[ch & 07] = 0001; + chan_io_status[ch & 07] = IO_CHS_NORDY; break; } if (CPU_MODEL == 1) chan_io_status[ch & 07] &= 0177; + sim_interval -= 100; break; case OP_IO1: @@ -2351,7 +2384,9 @@ sim_instr(void) if (chan_io_status[ch] & op_mod) { jump = 1; } - chan_io_status[ch] &= 077; /* Clear interlock */ + chan_io_status[ch] &= 077; + sim_debug(DEBUG_CMD, &cpu_dev, "Check chan %d %o %x\n", ch, + chan_io_status[ch], chan_flags[ch]); break; case OP_IO2: @@ -3051,6 +3086,7 @@ sim_instr(void) /* Priority mode operations */ case OP_PRI: + jump = 0; switch(op_mod) { case CHR_U: /* U branch if ch 1 i-o unit priority */ jump = urec_irq[1]; @@ -3061,16 +3097,20 @@ sim_instr(void) urec_irq[2] = 0; break; case CHR_1: /* 1 branch if ch 1 overlap priority */ - jump = chan_io_status[1] & 0100; + if (chan_irq_enb[1]) + jump = (chan_io_status[1] & 0300) == 0300; break; case CHR_2: /* 2 branch if ch 2 overlap priority */ - jump = chan_io_status[2] & 0100; + if (chan_irq_enb[2]) + jump = (chan_io_status[2] & 0300) == 0300; break; case CHR_3: /* 3 branch if ch 3 overlap priority */ - jump = chan_io_status[3] & 0100; + if (chan_irq_enb[3]) + jump = (chan_io_status[3] & 0300) == 0300; break; case CHR_4: /* 4 branch if ch 4 overlap priority */ - jump = chan_io_status[4] & 0100; + if (chan_irq_enb[4]) + jump = (chan_io_status[4] & 0300) == 0300; break; case CHR_Q: /* Q branch if inquiry ch 1 */ jump = inquiry; @@ -3099,10 +3139,12 @@ sim_instr(void) break; case CHR_X: /* X branch and exit */ pri_enb = 0; + sim_debug(DEBUG_PRIO, &cpu_dev, "dis irq\n"); jump = 1; break; case CHR_E: /* E branch and enter */ pri_enb = 1; + sim_debug(DEBUG_PRIO, &cpu_dev, "enb irq\n"); jump = 1; break; case CHR_A: /* A branch if ch1 attention */ @@ -3269,7 +3311,7 @@ sim_instr(void) case CHR_QUOT: /* ' Turn on 20ms timer */ if (cpu_unit.flags & OPTION_PROT) { timer_enable = 1; - timer_interval = 20; + timer_interval = 10; timer_irq = 0; sim_debug(DEBUG_DETAIL, &cpu_dev, "Timer start\n"); } @@ -3717,13 +3759,17 @@ do_divide() t_stat rtc_srv(UNIT * uptr) { + int32 t; + + t = sim_rtcn_calb (rtc_tps, TMR_RTC); + sim_activate_after(uptr, 1000000/rtc_tps); + if (timer_enable) { if (--timer_interval == 0) { timer_irq |= 1; - timer_interval = 20; + timer_interval = 10; } } - sim_activate(&cpu_unit, sim_rtcn_calb(uptr->wait, TMR_RTC)); return SCPE_OK; } diff --git a/I7000/i7010_defs.h b/I7000/i7010_defs.h index 4caa6d0..231935c 100644 --- a/I7000/i7010_defs.h +++ b/I7000/i7010_defs.h @@ -121,3 +121,13 @@ int chan_cmd(uint16 dev, uint16 cmd, uint32 addr); /* S - Floating sub */ /* M - Floating mul */ /* D - Floating div */ + +/* Flags for chan_io_status. */ +#define IO_CHS_NORDY 0001 /* Unit not Ready */ +#define IO_CHS_BUSY 0002 /* Unit or channel Busy */ +#define IO_CHS_CHECK 0004 /* Data check */ +#define IO_CHS_COND 0010 /* Condition */ +#define IO_CHS_NOTR 0020 /* No transfer */ +#define IO_CHS_WRL 0040 /* Wrong length */ +#define IO_CHS_DONE 0100 /* Device done */ +#define IO_CHS_OVER 0200 /* Channel busy on overlap processing */ diff --git a/I7000/i7010_sys.c b/I7000/i7010_sys.c index fc4e453..f899558 100644 --- a/I7000/i7010_sys.c +++ b/I7000/i7010_sys.c @@ -101,16 +101,16 @@ DIB lpr_dib = { CH_TYP_UREC, 1, 00200, 07700, &lpr_cmd, &lpr_ini }; DIB con_dib = { CH_TYP_UREC, 1, 02300, 07700, &con_cmd, &con_ini }; #endif #ifdef NUM_DEVS_MT -DIB mt_dib = { CH_TYP_76XX|CH_TYP_UREC, NUM_UNITS_MT, 02400, 07700, &mt_cmd, &mt_ini }; +DIB mt_dib = { CH_TYP_UREC, NUM_UNITS_MT, 02400, 07700, &mt_cmd, &mt_ini }; #endif #ifdef NUM_DEVS_CHRON -DIB chron_dib = { CH_TYP_76XX|CH_TYP_UREC, 1, 02400, 07700, &chron_cmd, NULL }; +DIB chron_dib = { CH_TYP_UREC, 1, 02400, 07700, &chron_cmd, NULL }; #endif #ifdef NUM_DEVS_DSK -DIB dsk_dib = { CH_TYP_79XX, 0, 06600, 07700, &dsk_cmd, &dsk_ini }; +DIB dsk_dib = { CH_TYP_79XX|CH_TYP_UREC, 0, 06600, 07700, &dsk_cmd, &dsk_ini }; #endif #ifdef NUM_DEVS_COM -DIB com_dib = { CH_TYP_79XX, 0, 04200, 07700, &com_cmd, NULL }; +DIB com_dib = { CH_TYP_79XX|CH_TYP_UREC, 0, 04200, 07700, &com_cmd, NULL }; #endif @@ -336,8 +336,8 @@ t_opcode base_ops[] = { {OP_IO2|MOD(002), "BCB2", TYPE_B}, {OP_IO2|MOD(004), "BER2", TYPE_B}, {OP_IO2|MOD(010), "BEF2", TYPE_B}, - {OP_IO2|MOD(020), "BWL2", TYPE_B}, - {OP_IO2|MOD(040), "BNT2", TYPE_B}, + {OP_IO2|MOD(020), "BNT2", TYPE_B}, + {OP_IO2|MOD(040), "BWL2", TYPE_B}, {OP_IO2|MOD(000), "BEX2", TYPE_B}, {OP_IO2|MOD(000), "BEX2", TYPE_BE}, {OP_IO3|MOD(077), "BA3", TYPE_B}, @@ -345,8 +345,8 @@ t_opcode base_ops[] = { {OP_IO3|MOD(002), "BCB3", TYPE_B}, {OP_IO3|MOD(004), "BER3", TYPE_B}, {OP_IO3|MOD(010), "BEF3", TYPE_B}, - {OP_IO3|MOD(020), "BWL3", TYPE_B}, - {OP_IO3|MOD(040), "BNT3", TYPE_B}, + {OP_IO3|MOD(020), "BNT3", TYPE_B}, + {OP_IO3|MOD(040), "BWL3", TYPE_B}, {OP_IO3|MOD(000), "BEX3", TYPE_B}, {OP_IO3|MOD(000), "BEX3", TYPE_BE}, {OP_IO4|MOD(077), "BA4", TYPE_B}, @@ -354,8 +354,8 @@ t_opcode base_ops[] = { {OP_IO4|MOD(002), "BCB4", TYPE_B}, {OP_IO4|MOD(004), "BER4", TYPE_B}, {OP_IO4|MOD(010), "BEF4", TYPE_B}, - {OP_IO4|MOD(020), "BWL4", TYPE_B}, - {OP_IO4|MOD(040), "BNT4", TYPE_B}, + {OP_IO4|MOD(020), "BNT4", TYPE_B}, + {OP_IO4|MOD(040), "BWL4", TYPE_B}, {OP_IO4|MOD(000), "BEX4", TYPE_B}, {OP_IO4|MOD(000), "BEX4", TYPE_BE}, {OP_A, "A", TYPE_2},