From f71faa4b2d8c6512d9b974b2bbbd3dbd70f05bb7 Mon Sep 17 00:00:00 2001 From: Richard Cornwell Date: Sat, 9 Sep 2017 22:22:11 -0400 Subject: [PATCH] I7000: Updated I7010 sim to handle new tape controller and pass diags. PR155 has errors. --- I7000/i7000_con.c | 20 +--- I7000/i7000_lpr.c | 2 + I7000/i7000_mt.c | 225 ++++++++++++++++++++++----------------------- I7000/i7010_chan.c | 86 ++++++++++++----- I7000/i7010_cpu.c | 83 ++++++++--------- I7000/i7010_sys.c | 4 +- I7000/i7090_cpu.c | 2 - 7 files changed, 216 insertions(+), 206 deletions(-) diff --git a/I7000/i7000_con.c b/I7000/i7000_con.c index dd90806..8379078 100644 --- a/I7000/i7000_con.c +++ b/I7000/i7000_con.c @@ -45,19 +45,6 @@ */ /* Device status information stored in u5 */ -#define URCSTA_EOF 0001 /* Hit end of file */ -#define URCSTA_ERR 0002 /* Error reading record */ -#define URCSTA_CARD 0004 /* Unit has card in buffer */ -#define URCSTA_FULL 0004 /* Unit has full buffer */ -#define URCSTA_BUSY 0010 /* Device is busy */ -#define URCSTA_WDISCO 0020 /* Device is wait for disconnect */ -#define URCSTA_READ 0040 /* Device is reading channel */ -#define URCSTA_WRITE 0100 /* Device is reading channel */ -#define URCSTA_INPUT 0200 /* Console fill buffer from keyboard */ -#define URCSTA_WMKS 0400 /* Printer print WM as 1 */ -#define URCSTA_SKIPAFT 01000 /* Skip to line after printing next line */ -#define URCSTA_NOXFER 01000 /* Don't set up to transfer after feed */ -#define URCSTA_LOAD 01000 /* Load flag for 7070 card reader */ struct _con_data { @@ -144,7 +131,7 @@ con_cmd(UNIT * uptr, uint16 cmd, uint16 dev) sim_putchar(' '); } sim_debug(DEBUG_CMD, &con_dev, "%d: Cmd RDS\n", u); - chan_set_sel(chan, 1); + chan_set_sel(chan, 0); uptr->u5 |= URCSTA_READ; uptr->u3 = 0; return SCPE_OK; @@ -201,14 +188,15 @@ con_srv(UNIT *uptr) { /* Copy next column over */ if ((uptr->u5 & URCSTA_INPUT) == 0 && uptr->u5 & URCSTA_READ) { - sim_debug(DEBUG_DATA, &con_dev, "%d: Char > %02o\n", u, - con_data[u].ibuff[uptr->u3]); + sim_debug(DEBUG_DATA, &con_dev, "%d: Char > %02o %x\n", u, + con_data[u].ibuff[uptr->u3], chan_flags[chan]); switch(chan_write_char(chan, &con_data[u].ibuff[uptr->u3], ((uptr->u3+1) == con_data[u].inptr)? DEV_REOR: 0)) { case TIME_ERROR: case END_RECORD: uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY; uptr->u5 &= ~URCSTA_READ; + sim_debug(DEBUG_EXP, &con_dev, "EOR"); chan_clear_attn_inq(chan); con_data[u].inptr = 0; break; diff --git a/I7000/i7000_lpr.c b/I7000/i7000_lpr.c index a8e936a..0ecad62 100644 --- a/I7000/i7000_lpr.c +++ b/I7000/i7000_lpr.c @@ -211,10 +211,12 @@ print_line(UNIT * uptr, int chan, int unit) #ifdef I7080 } #endif + /* Trim trailing spaces */ for (--i; i > 0 && out[i] == ' '; i--) ; out[++i] = '\n'; out[++i] = '\0'; + sim_debug(DEBUG_DETAIL, &lpr_dev, "WRS unit=%d [%s]\n", unit, &out[0]); /* Print out buffer */ if (uptr->flags & UNIT_ATT) diff --git a/I7000/i7000_mt.c b/I7000/i7000_mt.c index 0674ff2..f89b465 100644 --- a/I7000/i7000_mt.c +++ b/I7000/i7000_mt.c @@ -77,6 +77,8 @@ #define MT_RM 001000 /* Hit a record mark character */ #define MT_EOR 002000 /* Set EOR on next record */ #define MT_UNLOAD 004000 /* Unload when rewind done */ +#define MT_EGAP 010000 /* Write extended gap on next write */ + /* u6 holds the current buffer position */ /* Flags for mt_chan */ @@ -391,7 +393,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) /* If drive is offline or not attached return not ready */ if ((uptr->flags & (UNIT_ATT | MTUF_ONLINE)) != (UNIT_ATT | MTUF_ONLINE)) { - fprintf(stderr, "Attempt to access offline unit %s%d\n", + fprintf(stderr, "Attempt to access offline unit %s%d\n\r", dptr->name, unit); return SCPE_IOERR; } @@ -428,17 +430,17 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) chan_clear_status(chan); mt_chan[chan] &= MTC_BSY; mt_chan[chan] |= MTC_SEL | unit; -#ifdef I7010 - uptr->u5 &= ~(MT_RM); -#else /* TEST */ - uptr->u5 &= ~(MT_RM|MT_EOR); -#endif /* TEST */ + uptr->u5 &= ~(MT_RM|MT_EOR|MT_EGAP); uptr->u6 = -1; uptr->hwmark = -1; +#if I7010 | I7080 + chan_set(chan, STA_TWAIT); +#endif sim_debug(DEBUG_CMD, dptr, "RDS %s unit=%d %d\n", ((uptr->u5 & MT_CMDMSK) == MT_RDS) ? "BCD" : "Binary", unit, dev); break; + case IO_WRS: if (sim_tape_bot(uptr)) time = us_to_ticks(40000); @@ -468,10 +470,14 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) mt_chan[chan] &= MTC_BSY; mt_chan[chan] |= MTC_SEL | unit; uptr->u5 &= ~(MT_MARK | MT_EOT); +#if I7010 | I7080 + chan_set(chan, STA_TWAIT); +#endif sim_debug(DEBUG_CMD, dptr, "WRS %s unit=%d %d\n", ((uptr->u5 & MT_CMDMSK) == MT_WRS) ? "BCD" : "Binary", unit, dev); break; + case IO_RDB: if (mt_chan[chan] & MTC_SEL) { uptr->u5 |= MT_RDY; @@ -483,9 +489,12 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) chan_clear_status(chan); mt_chan[chan] &= MTC_BSY; mt_chan[chan] |= MTC_SEL | unit; - uptr->u5 &= ~(MT_RM); + uptr->u5 &= ~(MT_RM|MT_EOR|MT_EGAP); uptr->u6 = -1; uptr->hwmark = -1; +#if I7010 | I7080 + chan_set(chan, STA_TWAIT); +#endif sim_debug(DEBUG_CMD, dptr, "RDB unit=%d %d\n", unit, dev); break; @@ -501,6 +510,9 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) } uptr->u5 |= MT_WEF; mt_chan[chan] |= MTC_BSY; +#if I7010 | I7080 + chan_set(chan, STA_TWAIT); +#endif sim_debug(DEBUG_CMD, dptr, "WEF unit=%d\n", unit); break; @@ -518,6 +530,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) mt_chan[chan] |= MTC_BSY; sim_debug(DEBUG_CMD, dptr, "BSR unit=%d\n", unit); break; + case IO_BSF: uptr->u5 &= ~(MT_MARK); /* Check if at load point, quick return if so */ @@ -532,60 +545,75 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) mt_chan[chan] |= MTC_BSY; sim_debug(DEBUG_CMD, dptr, "BSF unit=%d\n", unit); break; + case IO_SKR: - uptr->u5 &= ~(MT_MARK); + if (sim_tape_bot(uptr)) + time = us_to_ticks(21000); + uptr->u5 &= ~(MT_MARK|MT_EGAP); uptr->u5 |= MT_SKR; -#ifndef I7010 mt_chan[chan] |= MTC_BSY; -#endif sim_debug(DEBUG_CMD, dptr, "SKR unit=%d\n", unit); break; + case IO_ERG: + sim_debug(DEBUG_CMD, dptr, "ERG unit=%d\n", unit); +#ifdef I7080 uptr->u5 &= ~(MT_MARK); uptr->u5 |= MT_ERG; mt_chan[chan] |= MTC_BSY; - sim_debug(DEBUG_CMD, dptr, "ERG unit=%d\n", unit); + chan_set(chan, STA_TWAIT); break; +#else + uptr->u5 |= MT_EGAP|MT_RDY; /* Command is quick */ + return SCPE_OK; +#endif + case IO_REW: - uptr->u5 &= ~(MT_EOT|MT_MARK); + uptr->u5 &= ~(MT_EOT|MT_MARK|MT_EGAP); /* Check if at load point, quick return if so */ if (sim_tape_bot(uptr)) { sim_debug(DEBUG_CMD, dptr, "REW unit=%d at BOT\n", unit); uptr->u5 |= MT_RDY; uptr->u3 = 0; -#ifdef I7010 - chan_set(chan, CHS_BOT); -#endif return SCPE_OK; } - time = us_to_ticks(10000); + time = 1000; uptr->u5 |= MT_REW; mt_chan[chan] |= MTC_BSY; sim_debug(DEBUG_CMD, dptr, "REW unit=%d\n", unit); - break; + sim_cancel(uptr); + sim_activate(uptr, time); + return SCPE_OK; + case IO_RUN: - uptr->u5 &= ~(MT_EOT|MT_MARK); + uptr->u5 &= ~(MT_EOT|MT_MARK|MT_EGAP); chan_clear_status(chan); uptr->u5 |= MT_RUN; mt_chan[chan] |= MTC_BSY; - time = us_to_ticks(10000); + time = 1000; sim_debug(DEBUG_CMD, dptr, "RUN unit=%d\n", unit); - break; + sim_cancel(uptr); + sim_activate(uptr, time); + return SCPE_OK; + case IO_SDL: uptr->u5 |= MT_RDY; /* Command is quick */ uptr->flags |= MTUF_LDN; sim_debug(DEBUG_CMD, dptr, "SDN unit=%d low\n", unit); return SCPE_OK; + case IO_SDH: uptr->u5 |= MT_RDY; /* Command is quick */ uptr->flags &= ~MTUF_LDN; sim_debug(DEBUG_CMD, dptr, "SDN unit=%d high\n", unit); return SCPE_OK; + case IO_DRS: uptr->flags &= ~MTUF_ONLINE; uptr->u5 |= MT_RDY; /* Command is quick */ sim_debug(DEBUG_CMD, dptr, "DRS unit=%d\n", unit); return SCPE_OK; + case IO_TRS: uptr->u5 |= MT_RDY; /* Get here we are ready */ sim_debug(DEBUG_CMD, dptr, "TRS unit=%d\n", unit); @@ -593,12 +621,6 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) } sim_cancel(uptr); sim_activate(uptr, time); -#ifdef I7080 - chan_set(chan, STA_TWAIT); -#endif -#ifdef I7010 - chan_set(chan, STA_TWAIT); -#endif return SCPE_OK; } @@ -732,13 +754,10 @@ t_stat mt_srv(UNIT * uptr) #ifndef I7010 } #endif - sim_activate(uptr, us_to_ticks(T2)); - mt_chan[chan] &= MTC_BSY; - uptr->u5 |= MT_RDY; } 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_WRS) ? "BCD" : "Binary", reclen, uptr->u3); + unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen, uptr->u3); /* Keep moving until end of block */ if (uptr->u6 < (int32)uptr->hwmark ) { uptr->u3 += uptr->hwmark-uptr->u6; @@ -759,23 +778,16 @@ t_stat mt_srv(UNIT * uptr) uptr->u3 -= GAP_LEN + reclen; } #endif - sim_activate(uptr, us_to_ticks(T2)); - uptr->u5 |= MT_RDY; - mt_chan[chan] &= MTC_BSY; } - } else { - sim_activate(uptr, us_to_ticks(T2)); -#ifndef I7010 - uptr->u5 |= MT_RDY; -#endif - mt_chan[chan] &= MTC_BSY; } + sim_activate(uptr, T2_us); uptr->u6 = 0; uptr->hwmark = 0; sim_debug(DEBUG_CHAN, dptr, "Disconnect unit=%d\n", unit); - uptr->u5 |= MT_IDLE; + uptr->u5 |= MT_IDLE|MT_RDY; + mt_chan[chan] &= MTC_BSY; chan_clear(chan, DEV_DISCO | DEV_WEOR | DEV_SEL); -#ifdef I7080 +#if I7010 | I7080 chan_clear(chan, STA_TWAIT); #endif return SCPE_OK; @@ -785,24 +797,17 @@ t_stat mt_srv(UNIT * uptr) switch (cmd) { case 0: /* No command, stop tape */ uptr->u5 |= MT_RDY; /* Ready since command is done */ -#ifdef I7080 - chan_clear(chan, STA_TWAIT); -#endif -#ifdef I7010 - chan_clear(chan, STA_TWAIT); -#endif sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit); return SCPE_OK; case MT_SKIP: /* Record skip done, enable tape drive */ uptr->u5 &= ~MT_CMDMSK; uptr->u5 |= MT_RDY | MT_IDLE; -#ifdef I7080 - chan_clear(chan, STA_TWAIT); -#endif -#ifndef I7010 +#if I7090 | I704 | I701 chan_clear(chan, DEV_SEL); -#endif /* TEST */ +#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); @@ -850,7 +855,6 @@ t_stat mt_srv(UNIT * uptr) BUFFSIZE)) != MTSE_OK) { if (r == MTSE_TMK && uptr->u6 != -1) { sim_debug(DEBUG_DETAIL, dptr, "pend TM\n"); -// sim_activate(uptr, T1_us); uptr->u5 |= MT_MARK; r = MTSE_OK; } else { @@ -862,14 +866,17 @@ t_stat mt_srv(UNIT * uptr) sim_debug(DEBUG_DETAIL, dptr, "Read TM "); ch = mode?017:054; chan_write_char(chan, &ch, DEV_REOR); + chan_set_eof(chan); chan_clear(chan, STA_TWAIT); if (mode) { - sim_activate(uptr, us_to_ticks(100)); + sim_activate(uptr, T1_us); return SCPE_OK; } } -#endif + chan_set_error(chan); +#else chan_set_attn(chan); +#endif } sim_activate(uptr, T1_us); return mt_error(uptr, chan, r, dptr); @@ -879,6 +886,11 @@ t_stat mt_srv(UNIT * uptr) chan_clear(chan, CHS_EOF|CHS_ERR); sim_debug(DEBUG_DETAIL, dptr, "%s Block %d chars\n", (cmd == MT_RDS) ? "BCD" : "Binary", reclen); +#ifdef I7010 + if (mode && mt_buffer[bufnum][0] == 017) + chan_set_eof(chan); +#endif + } ch = mt_buffer[bufnum][uptr->u6++]; @@ -888,9 +900,10 @@ t_stat mt_srv(UNIT * uptr) #ifdef I7010 if (astmode) ch = 054; -#endif +#else chan_set_error(chan); chan_set_attn(chan); +#endif } #if I7090 | I704 | I701 /* Not needed on decimal machines */ @@ -912,41 +925,26 @@ t_stat mt_srv(UNIT * uptr) ch &= 077; /* Convert one word. */ - switch (chan_write_char(chan, &ch, -#ifdef I7010 - (uptr->u6 >= (int32)uptr->hwmark) ? DEV_REOR : 0 -#else - 0 -#endif - )) { + switch (chan_write_char(chan, &ch, 0)) { case END_RECORD: sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n", unit); /* If not read whole record, skip till end */ -#ifndef I7010 uptr->u5 |= MT_EOR; -#endif if (uptr->u6 < (int32)uptr->hwmark) { sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us); -#ifdef I7010 - chan_set(chan, DEV_REOR); -#endif uptr->u3 += (uptr->hwmark - uptr->u6); uptr->u6 = uptr->hwmark; /* Force read next record */ -#ifdef I7010 - break; - } -#else - } else - sim_activate(uptr, T1_us); + } + sim_activate(uptr, T1_us); break; -#endif 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 */ -#ifndef I7010 uptr->u5 |= MT_EOR; +#ifdef I7010 + (void)chan_write_char(chan, &ch, DEV_WEOR); #endif sim_activate(uptr, T1_us); } else @@ -970,6 +968,14 @@ t_stat mt_srv(UNIT * uptr) mode = 0100; /* 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); + uptr->u5 &= ~MT_EGAP; + r = sim_tape_wrgap(uptr, 35); + sim_activate(uptr, 10*T3_us); + return SCPE_OK; + } + switch (chan_read_char(chan, &ch, (uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) { case TIME_ERROR: @@ -1061,7 +1067,6 @@ t_stat mt_srv(UNIT * uptr) if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) { chan_set_error(chan); chan_set_attn(chan); - fprintf(stderr, "Parity error %d: %03o\n", uptr->u6-1, ch); } ch &= 077; @@ -1102,6 +1107,13 @@ t_stat mt_srv(UNIT * uptr) return SCPE_OK; case MT_WEF: + if (uptr->u5 & MT_EGAP) { + sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d %d\n", unit, uptr->u3); + 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); uptr->u5 &= ~(MT_CMDMSK|MT_MARK); uptr->u5 |= (MT_RDY); @@ -1109,7 +1121,7 @@ t_stat mt_srv(UNIT * uptr) uptr->u3 += GAP_LEN; mt_chan[chan] &= ~MTC_BSY; sim_activate(uptr, T2_us); -#ifdef I7080 +#if I7010 | I7080 chan_clear(chan, STA_TWAIT); #endif break; @@ -1117,14 +1129,11 @@ t_stat mt_srv(UNIT * uptr) case MT_BSR: sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d %d ", unit, uptr->u3); /* Clear tape mark, command, idle since we will need to change dir */ - uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_IDLE | MT_RDY); + uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY); r = sim_tape_sprecr(uptr, &reclen); if (r != MTSE_BOT) uptr->u3 -= GAP_LEN; mt_chan[chan] &= ~MTC_BSY; -#ifdef I7080 - chan_clear(chan, STA_TWAIT); -#endif if (r == MTSE_TMK) { #ifdef I7080 chan_set_eof(chan); @@ -1138,11 +1147,7 @@ t_stat mt_srv(UNIT * uptr) sim_debug(DEBUG_DETAIL, dptr, "%d \n", reclen); uptr->u3 -= reclen; sim_activate(uptr, T2_us + (reclen * T1_us)); -#ifdef I7010 - break; -#else /* TEST */ return SCPE_OK; -#endif /* TEST */ case MT_BSF: uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT); @@ -1156,30 +1161,25 @@ t_stat mt_srv(UNIT * uptr) uptr->u5 &= ~MT_CMDMSK; mt_chan[chan] &= ~MTC_BSY; sim_activate(uptr, T2_us); -#ifdef I7080 - chan_clear(chan, STA_TWAIT); -#endif } else { uptr->u3 -= reclen; sim_activate(uptr, T2_us + (reclen * T1_us)); } -#ifdef I7010 - break; -#else /* TEST */ return SCPE_OK; -#endif /* TEST */ case MT_SKR: sim_debug(DEBUG_DETAIL, dptr, "Skip rec unit=%d ", unit); /* Clear tape mark, command, idle since we will need to change dir */ - uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_IDLE | MT_RDY); -#ifndef I7010 - uptr->u5 |= MT_SKIP; -#endif /* TEST */ + uptr->u5 &= ~(MT_CMDMSK | MT_EOT); + uptr->u5 |= (MT_RDY | MT_IDLE); r = sim_tape_sprecf(uptr, &reclen); uptr->u3 += GAP_LEN; -#ifdef I7010 mt_chan[chan] &= ~MTC_BSY; +#if I7010 | I7080 + chan_clear(chan, STA_TWAIT); +#endif +#ifdef I7010 + chan_set(chan, STA_PEND); #else /* We are like read that transfers nothing */ chan_set(chan, DEV_REOR); @@ -1187,8 +1187,12 @@ t_stat mt_srv(UNIT * uptr) /* We don't set EOF on SKR */ if (r == MTSE_TMK) { sim_debug(DEBUG_DETAIL, dptr, "MARK\n"); - sim_activate(uptr, 100); + sim_activate(uptr, T1_us); return SCPE_OK; +#ifdef I7010 + } else if (r == MTSE_EOM) { + chan_set(chan, STA_PEND); +#endif } sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen); uptr->u3 += reclen; @@ -1198,15 +1202,14 @@ t_stat mt_srv(UNIT * uptr) case MT_ERG: sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit); uptr->u5 &= ~(MT_CMDMSK|MT_MARK); -#ifdef I7010 uptr->u5 |= (MT_RDY | MT_IDLE); -#else - uptr->u5 |= MT_SKIP; +#if I7010 | I7080 + chan_clear(chan, STA_TWAIT); #endif r = sim_tape_wrgap(uptr, 35); uptr->u3 += GAP_LEN; mt_chan[chan] &= ~MTC_BSY; - sim_activate(uptr, T2_us); + sim_activate(uptr, 10*T3_us); break; case MT_REW: @@ -1220,9 +1223,6 @@ t_stat mt_srv(UNIT * uptr) uptr->u5 |= MT_LREW; sim_activate(uptr, 300); } -#ifdef I7080 - chan_clear(chan, STA_TWAIT); -#endif mt_chan[chan] &= ~MTC_BSY; break; @@ -1237,12 +1237,6 @@ t_stat mt_srv(UNIT * uptr) uptr->u5 |= MT_LREW; sim_activate(uptr, 300); } -#ifdef I7010 - chan_clear(chan, STA_TWAIT); -#endif -#ifdef I7080 - chan_clear(chan, STA_TWAIT); -#endif mt_chan[chan] &= ~MTC_BSY; return SCPE_OK; @@ -1263,18 +1257,17 @@ t_stat mt_srv(UNIT * uptr) if (uptr->u3 > 0) { uptr->u3 -= (uptr->flags & MTUF_LDN) ? 373 :1036; sim_activate(uptr, us_to_ticks(16000)); + return SCPE_OK; } else { if(uptr->u5 & MT_UNLOAD) r = sim_tape_detach(uptr); else r = sim_tape_rewind(uptr); uptr->u5 &= ~(MT_CMDMSK|MT_UNLOAD); - uptr->u5 |= MT_IDLE; + uptr->u5 |= MT_RDY; uptr->u3 = 0; - sim_activate(uptr, us_to_ticks(3000)); - return mt_error(uptr, chan, r, dptr); } - return SCPE_OK; + break; } return mt_error(uptr, chan, r, dptr); } diff --git a/I7000/i7010_chan.c b/I7000/i7010_chan.c index 22aef40..1a4a6be 100644 --- a/I7000/i7010_chan.c +++ b/I7000/i7010_chan.c @@ -370,8 +370,7 @@ chan_proc() /* 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); + 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; @@ -447,7 +446,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) cmd[chan] |= CHAN_OVLP; dcmd = (dcmd >> 8) & 0x7f; chunit[chan] = dev; - chan_flags[chan] &= ~(CTL_CNTL|CTL_READ|CTL_WRITE|SNS_UEND|CTL_WRITE|CTL_SNS); + 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; @@ -534,16 +533,59 @@ chan_write_char(int chan, uint8 * data, int flags) { uint8 ch = *data; - /* Check if end of data */ - if ((cmd[chan] & CHAN_NOREC) == 0 && M[caddr[chan]] == (WM|077)) { - caddr[chan]+=2; + + /* 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_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE); 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]); 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; + caddr[chan]++; + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d GEor %d %o\n", chan, caddr[chan], + chan_io_status[chan]); + return DATA_OK; + } + + /* If over size of memory, terminate */ + if (!MEM_ADDR_OK(caddr[chan])) { + chan_flags[chan] |= DEV_REOR; + if (chan_flags[chan] & DEV_SEL) + chan_flags[chan] |= DEV_DISCO; + chan_io_status[chan] |= 0100; + caddr[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; + } + /* If we are in load mode and see word mark, save it */ if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == CHAN_LOAD && ch == 035) cmd[chan] |= CHAN_WM; @@ -555,8 +597,11 @@ chan_write_char(int chan, uint8 * data, int flags) cmd[chan] &= ~CHAN_WM; if ((cmd[chan] & CHAN_LOAD) == 0) ch |= M[caddr[chan]] & WM; - M[caddr[chan]++] = ch; + if ((chan_flags[chan] & DEV_REOR) == 0) + M[caddr[chan]] = ch; + caddr[chan]++; } + chan_io_status[chan] &= ~020; /* If device gave us an end, terminate transfer */ if (flags & DEV_REOR) { @@ -568,24 +613,13 @@ chan_write_char(int chan, uint8 * data, int flags) if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD)) M[caddr[chan]++] = 035; caddr[chan]++; - return END_RECORD; - /* If over size of memory, terminate */ - } else if (!MEM_ADDR_OK(caddr[chan])) { - chan_flags[chan] |= DEV_REOR; - if (chan_flags[chan] & DEV_SEL) - chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0020; - chan_io_status[chan] |= 0100; - chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE); + 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]); return END_RECORD; } - /* If Writing end of record, abort */ - if (flags & DEV_WEOR) { - chan_flags[chan] &= ~(DEV_WEOR); - chan_io_status[chan] |= 0100; - return END_RECORD; - } return DATA_OK; } @@ -614,6 +648,7 @@ chan_read_char(int chan, uint8 * data, int flags) return END_RECORD; *data &= 077; caddr[chan]++; + chan_io_status[chan] &= ~020; return DATA_OK; } @@ -622,14 +657,15 @@ chan_read_char(int chan, uint8 * data, int flags) *data = assembly[chan]; cmd[chan] &= ~CHAN_WM; } else { - if (!MEM_ADDR_OK(caddr[chan])) { + if (!MEM_ADDR_OK(caddr[chan]+1)) { chan_flags[chan] &= ~STA_ACTIVE; if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_DISCO; - chan_io_status[chan] |= 0100; + caddr[chan]++; 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; diff --git a/I7000/i7010_cpu.c b/I7000/i7010_cpu.c index 2885063..2bc31a6 100644 --- a/I7000/i7010_cpu.c +++ b/I7000/i7010_cpu.c @@ -148,7 +148,7 @@ uint8 timer_enable = 0; /* Interval timer enable */ uint8 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 = 45; /* Cycle time in 100ns */ +int cycle_time = 28; /* Cycle time in 100ns */ /* History information */ int32 hst_p = 0; /* History pointer */ @@ -1323,6 +1323,7 @@ sim_instr(void) irq = 1; } + if (irq || (timer_enable && timer_irq == 1)) { /* Check if we can interupt this opcode */ switch(op) { @@ -1953,8 +1954,10 @@ sim_instr(void) jump = 1; tind = 0; } else { - for(i = 1; i <= NUM_CHAN && jump == 0; i++) - jump = chan_stat(i, CHS_EOF|CHS_EOT); + 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"); } break; case CHR_Q: /* Q Inq req ch 1 */ @@ -2212,18 +2215,18 @@ sim_instr(void) /* Try to start command */ switch (chan_cmd(temp, t, BAR & AMASK)) { case SCPE_OK: - chan_io_status[ch & 07] = 0200; + chan_io_status[ch & 07] = 0220; sim_debug(DEBUG_CMD, &cpu_dev, - "%c on %o %s %c\n\r", sim_six_to_ascii[op], ch & 07, - (ch & 010)?"overlap":"", sim_six_to_ascii[op_mod]); + "%d %c on %o %s %c\n", IAR, sim_six_to_ascii[op], ch & 07, + (ch & 010)?"":"overlap", sim_six_to_ascii[op_mod]); break; case SCPE_BUSY: - chan_io_status[ch & 07] = 0202; + chan_io_status[ch & 07] = 0002; break; case SCPE_NODEV: case SCPE_IOERR: - chan_io_status[ch & 07] = 0201; + chan_io_status[ch & 07] = 0001; break; } /* Handle waiting */ @@ -2240,7 +2243,7 @@ sim_instr(void) chan_io: switch (chan_cmd(temp, t, 0)) { case SCPE_OK: - chan_io_status[ch & 07] = 0000; + chan_io_status[ch & 07] = 0020; if (ch & 010) chwait = (ch & 07) | 040; break; @@ -2320,21 +2323,15 @@ sim_instr(void) chan_io_status[ch & 07] = 0000; if (ch & 010) { chwait = (ch & 07) | 040; - } else { - /* If doing rewind and not at BOT */ - if (op_mod == CHR_R) - chan_clear(ch, STA_TWAIT); } - if (op_mod == CHR_A || op_mod == CHR_B) - tind = 1; - if (op_mod == CHR_M) - chan_io_status[ch & 07] = 0200; sim_debug(DEBUG_CMD, &cpu_dev, - "UC on %o %s %c\n\r", ch & 07, - (ch & 010)?"overlap":"", sim_six_to_ascii[op_mod]); + "%d UC on %o %s %c\n", IAR, ch & 07, + (ch & 010)?"": "overlap", sim_six_to_ascii[op_mod]); 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; break; case SCPE_NODEV: @@ -2350,11 +2347,7 @@ sim_instr(void) /* Wait for channel to finish before continuing */ ch = 1; checkchan: - while (chan_active(ch) && reason == 0) { - sim_interval = 0; - reason = sim_process_event(); - chan_proc(); - } + chan_proc(); if (chan_io_status[ch] & op_mod) { jump = 1; } @@ -3010,14 +3003,14 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { if (prot_enb /*|| reloc != 0*/) { /* Abort */ reason = STOP_PROG; - sim_debug(DEBUG_DETAIL, &cpu_dev, "High set in prot mode\n\r"); + sim_debug(DEBUG_DETAIL, &cpu_dev, "High set in prot mode\n"); } else { temp = bcd_bin[ReadP(BAR) & 017]; DownReg(BAR); temp += 10 * bcd_bin[ReadP(BAR) & 017]; DownReg(BAR); high_addr = 1000 * temp; - sim_debug(DEBUG_DETAIL, &cpu_dev, "High set to %d\n\r", high_addr); + sim_debug(DEBUG_DETAIL, &cpu_dev, "High set to %d\n", high_addr); } } break; @@ -3025,14 +3018,14 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { if (prot_enb || reloc != 0) { /* Abort */ reason = STOP_PROG; - sim_debug(DEBUG_DETAIL, &cpu_dev, "Low set in prot mode\n\r"); + sim_debug(DEBUG_DETAIL, &cpu_dev, "Low set in prot mode\n"); } else { temp = bcd_bin[ReadP(BAR) & 017]; DownReg(BAR); temp += 10 * bcd_bin[ReadP(BAR) & 017]; DownReg(BAR); low_addr = 1000 * temp; - sim_debug(DEBUG_DETAIL, &cpu_dev, "Low set to %d\n\r", low_addr); + sim_debug(DEBUG_DETAIL, &cpu_dev, "Low set to %d\n", low_addr); } } break; @@ -3129,7 +3122,7 @@ sim_instr(void) case CHR_QUEST: /* ? Enable protection mode */ if (cpu_unit.flags & OPTION_PROT) { sim_debug(DEBUG_DETAIL, &cpu_dev, - "Prot enter %d\n\r", AAR & AMASK); + "Prot enter %d\n", AAR & AMASK); /* If in protect mode, abort */ if (prot_enb) { reason = STOP_PROG; @@ -3145,7 +3138,7 @@ sim_instr(void) case CHR_9: /* 9 Leave Prot mode */ if (cpu_unit.flags & OPTION_PROT) { sim_debug(DEBUG_DETAIL, &cpu_dev, - "Leave Protect mode %d %d %d\n\r", + "Leave Protect mode %d %d %d\n", AAR & AMASK, prot_enb, reloc); /* If in protect mode, abort */ if ((prot_enb /*|| reloc*/) /*&& (AAR & BBIT) == 0*/) { @@ -3169,7 +3162,7 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { /* If in protect mode, abort */ sim_debug(DEBUG_DETAIL, &cpu_dev, - "Check protect fault %d %d\n\r", + "Check protect fault %d %d\n", AAR, prot_fault&1); if (prot_enb) { reason = STOP_PROG; @@ -3183,7 +3176,7 @@ sim_instr(void) case CHR_H: /* H Test for Prog faults */ if (cpu_unit.flags & OPTION_PROT) { sim_debug(DEBUG_DETAIL, &cpu_dev, - "Check prog fault %d %d\n\r", + "Check prog fault %d %d\n", AAR, prot_fault&2); /* If in protect mode, abort */ if (prot_enb) { @@ -3199,7 +3192,7 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { /* If in protect mode, abort */ sim_debug(DEBUG_DETAIL, &cpu_dev, - "Enable relocation %d\n\r", + "Enable relocation %d\n", AAR & AMASK); if (prot_enb) { reason = STOP_PROG; @@ -3230,7 +3223,7 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { /* If in protect mode, abort */ sim_debug(DEBUG_DETAIL, &cpu_dev, - "Enable relocation + prot %d\n\r", + "Enable relocation + prot %d\n", AAR & AMASK); if (prot_enb) { reason = STOP_PROG; @@ -3261,7 +3254,7 @@ sim_instr(void) case CHR_I: /* I ???? */ if (cpu_unit.flags & OPTION_PROT) { sim_debug(DEBUG_DETAIL, &cpu_dev, - "Prot opcode %02o %d\n\r", op_mod, AAR); + "Prot opcode %02o %d\n", op_mod, AAR); } break; @@ -3270,7 +3263,7 @@ sim_instr(void) jump = timer_irq; timer_irq &= 1; sim_debug(DEBUG_DETAIL, &cpu_dev, - "Timer release %d\n\r", jump); + "Timer release %d\n", jump); } break; case CHR_QUOT: /* ' Turn on 20ms timer */ @@ -3278,7 +3271,7 @@ sim_instr(void) timer_enable = 1; timer_interval = 20; timer_irq = 0; - sim_debug(DEBUG_DETAIL, &cpu_dev, "Timer start\n\r"); + sim_debug(DEBUG_DETAIL, &cpu_dev, "Timer start\n"); } jump = 1; break; @@ -3287,7 +3280,7 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { timer_enable = 0; timer_irq = 0; - sim_debug(DEBUG_DETAIL, &cpu_dev, "Timer stop\n\r"); + sim_debug(DEBUG_DETAIL, &cpu_dev, "Timer stop\n"); } break; } @@ -3337,44 +3330,44 @@ check_prot: switch(reason) { case STOP_NOWM: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d No WM AAR=%d BAR=%d\n\r", IAR, AAR, BAR); + "IAR = %d No WM AAR=%d BAR=%d\n", IAR, AAR, BAR); prot_fault |= 2; reason = 0; break; case STOP_INVADDR: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d Inv Addr AAR=%d BAR=%d\n\r", IAR, AAR, BAR); + "IAR = %d Inv Addr AAR=%d BAR=%d\n", IAR, AAR, BAR); prot_fault |= 2; reason = 0; break; case STOP_UUO: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d Inv Op AAR=%d BAR=%d\n\r", IAR, AAR, BAR); + "IAR = %d Inv Op AAR=%d BAR=%d\n", IAR, AAR, BAR); prot_fault |= 2; reason = 0; break; case STOP_INVLEN: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d Invlen Op AAR=%d BAR=%d\n\r", IAR, AAR, BAR); + "IAR = %d Invlen Op AAR=%d BAR=%d\n", IAR, AAR, BAR); prot_fault |= 2; reason = 0; break; case STOP_IOCHECK: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d I/O Check AAR=%d BAR=%d\n\r", IAR, AAR, BAR); + "IAR = %d I/O Check AAR=%d BAR=%d\n", IAR, AAR, BAR); prot_fault |= 2; reason = 0; break; case STOP_PROG: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d Prog check AAR=%d BAR=%d low=%d high=%d\n\r", + "IAR = %d Prog check AAR=%d BAR=%d low=%d high=%d\n", IAR, AAR, BAR, low_addr, high_addr); prot_fault |= 2; reason = 0; break; case STOP_PROT: sim_debug(DEBUG_DETAIL, &cpu_dev, - "IAR = %d Prot check AAR=%d BAR=%d low=%d high=%d\n\r", + "IAR = %d Prot check AAR=%d BAR=%d low=%d high=%d\n", IAR, AAR, BAR, low_addr, high_addr); prot_fault |= 1; reason = 0; diff --git a/I7000/i7010_sys.c b/I7000/i7010_sys.c index d103bcb..fc4e453 100644 --- a/I7000/i7010_sys.c +++ b/I7000/i7010_sys.c @@ -327,8 +327,8 @@ t_opcode base_ops[] = { {OP_IO1|MOD(002), "BCB1", TYPE_B}, {OP_IO1|MOD(004), "BER1", TYPE_B}, {OP_IO1|MOD(010), "BEF1", TYPE_B}, - {OP_IO1|MOD(020), "BWL1", TYPE_B}, - {OP_IO1|MOD(040), "BNT1", TYPE_B}, + {OP_IO1|MOD(020), "BNT1", TYPE_B}, + {OP_IO1|MOD(040), "BWL1", TYPE_B}, {OP_IO1|MOD(000), "BEX1", TYPE_B}, {OP_IO1|MOD(000), "BEX1", TYPE_BE}, {OP_IO2|MOD(077), "BA2", TYPE_B}, diff --git a/I7000/i7090_cpu.c b/I7000/i7090_cpu.c index 4a2543d..7774da1 100644 --- a/I7000/i7090_cpu.c +++ b/I7000/i7090_cpu.c @@ -932,10 +932,8 @@ sim_instr(void) if (mask & AMASK & ioflags) { if (chan_stat(shiftcnt, CHS_EOF)) f = 1; /* We have a EOF */ -#if 0 if (iotraps & (1 << shiftcnt)) f = 1; /* We have a IOCT/IORT/IOST */ -#endif } if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR)) f = 1; /* We have device error */