diff --git a/I7000/i7000_cdp.c b/I7000/i7000_cdp.c index c1e2cc0a..f4c63a75 100644 --- a/I7000/i7000_cdp.c +++ b/I7000/i7000_cdp.c @@ -40,6 +40,12 @@ /* Flags for punch and reader. */ #define ATTENA (1 << (UNIT_V_UF+7)) #define ATTENB (1 << (UNIT_V_UF+14)) +#define INPUT_V (UNIT_V_UF+7) +#define INPUT_FULL (1 << INPUT_V) +#define INPUT_EMPTY (2 << INPUT_V) +#define INPUT_DECK (3 << INPUT_V) +#define INPUT_BLANK (4 << INPUT_V) +#define INPUT_MASK (7 << INPUT_V) /* std devices. data structures @@ -56,6 +62,8 @@ t_stat cdp_srv(UNIT *); t_stat cdp_reset(DEVICE *); t_stat cdp_attach(UNIT *, CONST char *); t_stat cdp_detach(UNIT *); +t_stat cdp_get_input(FILE *, UNIT *, int32, CONST void *); +t_stat cdp_set_input(UNIT *, int32, CONST char *, void *); t_stat cdp_help(FILE *, DEVICE *, UNIT *, int32, const char *); const char *cdp_description(DEVICE *dptr); t_stat stk_help(FILE *, DEVICE *, UNIT *, int32, const char *); @@ -68,6 +76,13 @@ UNIT cdp_unit[] = { #endif }; +UNIT cdp_input_unit[] = { + {UDATA(NULL, UNIT_ATTABLE | INPUT_FULL | UNIT_RO, 0), 600}, /* A */ +#if NUM_DEVS_CDP > 1 + {UDATA(NULL, UNIT_ATTABLE | INPUT_FULL | UNIT_RO, 0), 600}, /* B */ +#endif +}; + MTAB cdp_mod[] = { {MTAB_XTD | MTAB_VUN, 0, "FORMAT", "FORMAT", &sim_card_set_fmt, &sim_card_show_fmt, NULL, "Set card format"}, @@ -80,17 +95,27 @@ MTAB cdp_mod[] = { {MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan, &get_chan, NULL, "Set device channel"}, #endif + {MTAB_XTD | MTAB_VUN | MTAB_VALR | MTAB_NC, 0, "INPUT", "INPUT", &cdp_set_input, &cdp_get_input, + NULL, "Set input to card punch"}, {0} }; DEVICE cdp_dev = { "CDP", cdp_unit, NULL, cdp_mod, NUM_DEVS_CDP, 8, 15, 1, 8, 8, - NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach, + NULL, NULL, &cdp_reset, NULL, &cdp_attach, &cdp_detach, &cdp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug, NULL, NULL, &cdp_help, NULL, NULL, &cdp_description }; +DEVICE cdp_input_dev = { + "INPUT", cdp_input_unit, NULL, NULL, + NUM_DEVS_CDP, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, NULL, NULL, + NULL, DEV_DISABLE | DEV_DIS, 0, NULL, + NULL, NULL, NULL, NULL, NULL, NULL +}; + #ifdef STACK_DEV UNIT stack_unit[] = { { UDATA (NULL, UNIT_SEQ+UNIT_ATTABLE, 0) }, @@ -140,10 +165,15 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev) int chan = UNIT_G_CHAN(uptr->flags); int u = (uptr - cdp_unit); int stk = dev & 017; + UNIT *iuptr = &cdp_input_unit[u]; + uint16 *image = (uint16 *)(uptr->up7); + int i; /* Are we currently tranfering? */ - if (uptr->u5 & URCSTA_WRITE) + if (uptr->u5 & URCSTA_WRITE) { + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Busy\n", u); return SCPE_BUSY; + } if (stk == 10) stk = 0; @@ -173,6 +203,37 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 |= stk << 16; #endif sim_debug(DEBUG_CMD, &cdp_dev, "%d: Cmd WRS\n", u); + + switch((iuptr->flags & INPUT_MASK) >> INPUT_V) { + case INPUT_EMPTY >> INPUT_V: + case INPUT_BLANK >> INPUT_V: + if (iuptr->u3 == 0) { + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Empty\n", u); + return SCPE_IOERR; + } + iuptr->u3--; + /* Fall through */ + + case INPUT_FULL >> INPUT_V: + for (i = 0; i < 80; image[i++] = 0); + break; + case INPUT_DECK >> INPUT_V: + switch(sim_read_card(iuptr, image)) { + case CDSE_ERROR: + uptr->u5 |= URCSTA_ERR; + /* Fall through */ + + case CDSE_EOF: + case CDSE_EMPTY: + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: Empty deck\n", u); + return SCPE_IOERR; + case CDSE_OK: + sim_debug(DEBUG_DETAIL, &cdp_dev, "%d: left %d\n", u, + sim_card_input_hopper_count(iuptr)); + break; + } + break; + } chan_set_sel(chan, 1); uptr->u5 |= URCSTA_WRITE; uptr->u4 = 0; @@ -180,7 +241,6 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev) sim_activate(uptr, 50); return SCPE_OK; } - chan_set_attn(chan); return SCPE_IOERR; } @@ -257,9 +317,12 @@ cdp_srv(UNIT *uptr) { ch = 020; else if (ch == 020) ch = 0; - sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch); - image[uptr->u4++] = sim_bcd_to_hol(ch); - if (uptr->u4 == 80) { + image[uptr->u4] |= sim_bcd_to_hol(ch); + if (sim_hol_to_bcd(image[uptr->u4]) == 0x7f) { + chan_set_eof(chan); + } + sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o %04o\n", u, ch, image[uptr->u4]); + if (++uptr->u4 == 80) { chan_set(chan, DEV_REOR); uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL; uptr->u5 &= ~URCSTA_WRITE; @@ -271,6 +334,10 @@ cdp_srv(UNIT *uptr) { return SCPE_OK; } +t_stat +cdp_reset(DEVICE *dptr) { + return sim_register_internal_device (&cdp_input_dev); +} void cdp_ini(UNIT *uptr, t_bool f) { @@ -285,7 +352,7 @@ cdp_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; if (uptr->up7 == 0) { - uptr->up7 = calloc(80, sizeof(uint16)); + uptr->up7 = calloc(80, sizeof(uint16)); uptr->u5 = 0; } return SCPE_OK; @@ -306,12 +373,119 @@ cdp_detach(UNIT * uptr) sim_punch_card(uptr, image); #endif } - if (uptr->up7 == 0) + if (uptr->up7 == 0) free(uptr->up7); uptr->up7 = 0; return sim_card_detach(uptr); } +t_stat +cdp_set_input(UNIT *uptr, int32 val, CONST char *cptr, void *desc) +{ + int nflag = 1; + int num = 0; + char gbuf[30]; + char *p; + int u = (uptr - cdp_unit); + UNIT *iuptr = &cdp_input_unit[u]; + t_stat r = SCPE_ARG; + + if (cptr == NULL) + return SCPE_ARG; + if (uptr == NULL) + return SCPE_IERR; + + /* Clear existing input */ + sim_card_detach(iuptr); + iuptr->u3 = 0; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_EMPTY; + + /* Get first argument */ + cptr = get_glyph(cptr, gbuf, ';'); + + /* Check if it is a number */ + for (p = gbuf; *p != '\0'; p++) { + if (*p < '0' || *p > '9') { + nflag = 0; + break; + } + num = (num * 10) + (*p) - '0'; + } + + /* If valid number, set to number of blank cards */ + if (nflag) { + iuptr->u3 = num; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_BLANK; + return SCPE_OK; + } + + /* Check for given format */ + if (sim_strcasecmp(gbuf, "EMPTY") == 0) { + iuptr->u3 = 0; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_EMPTY; + return SCPE_OK; + } + + if (sim_strcasecmp(gbuf, "FULL") == 0) { + iuptr->u3 = 0; + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_FULL; + return SCPE_OK; + } + + /* If deck attach it to input */ + if (sim_strcasecmp(gbuf, "DECK") == 0) { + int32 saved_switches = sim_switches; + + sim_switches = SWMASK('E') | SWMASK('R'); + if ((saved_switches & SWMASK('F')) != 0) { + cptr = get_glyph(cptr, gbuf, ';'); + sim_card_set_fmt(iuptr, 0, gbuf, NULL); + } + r = sim_card_attach(iuptr, cptr); + if (r == SCPE_OK) { + iuptr->flags &= ~INPUT_MASK; + iuptr->flags |= INPUT_DECK; + } + sim_switches = saved_switches; + } + /* Error, set to empty */ + return r; +} + +t_stat +cdp_get_input(FILE *st, UNIT *uptr, int32 v, CONST void *desc) +{ + int u = (uptr - cdp_unit); + UNIT *iuptr = &cdp_input_unit[u]; + int i; + + if (uptr == NULL) + return SCPE_IERR; + + i = (iuptr->flags & INPUT_MASK) >> INPUT_V; + switch((iuptr->flags & INPUT_MASK) >> INPUT_V) { + case INPUT_BLANK >> INPUT_V: + fprintf(st, "%d blanks", iuptr->u3); + break; + case INPUT_FULL >> INPUT_V: + fprintf(st, "full"); + break; + case INPUT_EMPTY >> INPUT_V: + fprintf(st, "empty"); + break; + case INPUT_DECK >> INPUT_V: + fprintf(st, "deck %s", iuptr->filename); + break; + } + return SCPE_OK; +} + + + #ifdef STACK_DEV t_stat stk_help(FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag, const char *cptr) diff --git a/I7000/i7000_cdr.c b/I7000/i7000_cdr.c index 39c355f2..2c4923df 100644 --- a/I7000/i7000_cdr.c +++ b/I7000/i7000_cdr.c @@ -122,8 +122,10 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev) uptr->u5 &= ~0xF0000; uptr->u5 |= stk << 16; #endif - if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR)) + if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR)) { + uptr->u5 &= ~(URCSTA_EOF|URCSTA_ERR); return SCPE_IOERR; + } /* Process commands */ switch(cmd) { @@ -141,15 +143,19 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev) #endif break; default: + sim_debug(DEBUG_CMD, &cdr_dev, "%d: CMD none %02o\n", u, cmd); chan_set_attn(chan); return SCPE_IOERR; } /* If at eof, just return EOF */ - if (uptr->u5 & URCSTA_EOF) { + if (sim_card_eof(uptr)) { + uint16 *image = (uint16 *)(uptr->up7); chan_set_eof(chan); chan_set_attn(chan); - return SCPE_OK; + uptr->u5 &= ~(URCSTA_EOF|URCSTA_ERR); + (void)sim_read_card(uptr, image); + return SCPE_IOERR; } uptr->u5 |= URCSTA_READ; @@ -256,6 +262,10 @@ cdr_srv(UNIT *uptr) { #endif ch = sim_hol_to_bcd(image[uptr->u4]); + /* Handle 7-9 to generate 20 */ + if (ch == 012 && image[uptr->u4] == 0202) { + ch = 020; + } /* Handle invalid punch */ if (ch == 0x7f) { @@ -288,7 +298,7 @@ cdr_srv(UNIT *uptr) { uptr->u4++; break; } - sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %02o\n", u, ch); + sim_debug(DEBUG_DATA, &cdr_dev, "%d: Char > %04o %02o\n", u, image[uptr->u4-1], ch); sim_activate(uptr, 10); } return SCPE_OK; diff --git a/I7000/i7000_mt.c b/I7000/i7000_mt.c index 28e20351..ab62bf94 100644 --- a/I7000/i7000_mt.c +++ b/I7000/i7000_mt.c @@ -78,6 +78,8 @@ #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 */ +#define MT_LWR 020000 /* Last command was a write */ +#define MT_CLRIND 040000 /* On I7010 flag for SKR to clear indicator */ /* u6 holds the current buffer position */ @@ -90,8 +92,8 @@ #define IPS 75 /* Inches per second 75 or 112 */ #define HS_IPS 500 /* High speed rewind Inches per second */ -#define LD 200 -#define HD 555 +#define LD 300 +#define HD 150 #define LT_GAP_LEN ((3 * LD)/ 4) /* Gap length for low density */ #define HT_GAP_LEN ((3 * HD)/ 4) /* Gap length for high density */ @@ -238,9 +240,9 @@ UNIT mta_unit[] = { }; MTAB mt_mod[] = { - { MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED", + { MTAB_XTD|MTAB_VUN, 0, "write enabled", "WRITEENABLED", &set_writelock, &show_writelock, NULL, "Write ring in place" }, - { MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED", + { MTAB_XTD|MTAB_VUN, 1, NULL, "LOCKED", &set_writelock, NULL, NULL, "no Write ring in place" }, {MTUF_LDN, 0, "high density", "HIGH", &mt_tape_density, NULL, NULL, "556 BPI"}, @@ -393,7 +395,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)) { - sim_printf("Attempt to access offline unit %s%d\n\r", dptr->name, unit); + sim_messagef(SCPE_OK, "Attempt to access offline unit %s%d\n\r", dptr->name, unit); return SCPE_IOERR; } /* Check if drive is ready to recieve a command */ @@ -798,6 +800,7 @@ t_stat mt_srv(UNIT * uptr) switch (cmd) { case 0: /* No command, stop tape */ uptr->u5 |= MT_RDY; /* Ready since command is done */ + mt_chan[chan] &= ~MTC_BSY; sim_debug(DEBUG_DETAIL, dptr, "Idle unit=%d\n", unit); return SCPE_OK; @@ -820,6 +823,7 @@ t_stat mt_srv(UNIT * uptr) /* Fall through */ case MT_RDSB: + uptr->u5 &= ~MT_LWR; /* Not write command */ /* Post EOR */ if (uptr->u5 & MT_EOR) { sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit); @@ -900,13 +904,14 @@ t_stat mt_srv(UNIT * uptr) uptr->u3++; /* Do BCD translation */ if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) { + sim_debug(DEBUG_DETAIL, dptr, "%s parity error %d %03o\n", + (cmd == MT_RDS) ? "BCD" : "Binary", uptr->u3-1, ch); #ifdef I7010 if (astmode) ch = 054; -#else - chan_set_attn(chan); #endif chan_set_error(chan); + } #if I7090 | I704 | I701 /* Not needed on decimal machines */ @@ -972,6 +977,7 @@ t_stat mt_srv(UNIT * uptr) mode = 0100; /* fall through */ case MT_WRSB: + uptr->u5 |= MT_LWR; /* write command */ if (uptr->u5 & MT_EGAP) { sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit); uptr->u5 &= ~MT_EGAP; @@ -984,6 +990,8 @@ t_stat mt_srv(UNIT * uptr) (uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) { case TIME_ERROR: #if I7090 | I701 | I704 + uptr->u5 &= ~MT_CMDMSK; + uptr->u5 |= MT_SKIP; /* If no data was written, simulate a write gap */ if (uptr->u6 == 0) { r = sim_tape_wrgap(uptr, 35); @@ -993,7 +1001,6 @@ t_stat mt_srv(UNIT * uptr) } } #endif - chan_set_attn(chan); /* fall through */ case END_RECORD: @@ -1034,6 +1041,7 @@ t_stat mt_srv(UNIT * uptr) return SCPE_OK; case MT_RDB: + uptr->u5 &= ~MT_LWR; /* not write command */ /* 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); @@ -1116,6 +1124,7 @@ t_stat mt_srv(UNIT * uptr) return SCPE_OK; case MT_WEF: + uptr->u5 &= ~MT_LWR; /* not write command */ if (uptr->u5 & MT_EGAP) { sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit); uptr->u5 &= ~MT_EGAP; @@ -1137,8 +1146,17 @@ t_stat mt_srv(UNIT * uptr) case MT_BSR: sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit); + /* If last command was a write, put extended gap on tape */ + if (uptr->u5 & MT_LWR) { + sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d bsr\n", unit); + r = sim_tape_wrgap(uptr, 35); + uptr->u5 &= ~MT_LWR; + sim_activate(uptr, 10*T3_us); + return SCPE_OK; + } + /* Clear tape mark, command, idle since we will need to change dir */ - uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY); + uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY | MT_LWR); r = sim_tape_sprecr(uptr, &reclen); if (r != MTSE_BOT) uptr->u3 -= GAP_LEN; @@ -1146,8 +1164,6 @@ t_stat mt_srv(UNIT * uptr) if (r == MTSE_TMK) { #ifdef I7080 chan_set_eof(chan); -#else - /* We don't set EOF on BSR */ #endif sim_debug(DEBUG_DETAIL, dptr, "MARK\n"); sim_activate(uptr, T2_us); @@ -1159,7 +1175,7 @@ t_stat mt_srv(UNIT * uptr) return SCPE_OK; case MT_BSF: - uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT); + uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT | MT_LWR); r = sim_tape_sprecr(uptr, &reclen); if (r != MTSE_BOT) uptr->u3 -= GAP_LEN; @@ -1171,45 +1187,54 @@ t_stat mt_srv(UNIT * uptr) sim_activate(uptr, T2_us); } else { uptr->u3 -= reclen; + sim_debug(DEBUG_DETAIL, dptr, "Backspace file record unit=%d\n", unit); sim_activate(uptr, T2_us + (reclen * T1_us)); } return SCPE_OK; 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); - uptr->u5 |= (MT_RDY | MT_IDLE); + if (uptr->u5 & MT_CLRIND) { + sim_debug(DEBUG_DETAIL, dptr, "clear ind\n"); +#if I7010 + if ((uptr->u5 & MT_MARK) == 0) { + chan_clear(chan, STA_PEND); + } +#endif + chan_clear(chan, STA_TWAIT); + uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_LWR | MT_MARK | MT_CLRIND); + uptr->u5 |= (MT_RDY | MT_IDLE); + mt_chan[chan] &= ~MTC_BSY; + sim_activate(uptr, (uptr->u6 * T1_us) + T2_us); + return SCPE_OK; + } + uptr->u5 |= (MT_CLRIND); r = sim_tape_sprecf(uptr, &reclen); uptr->u3 += GAP_LEN; - mt_chan[chan] &= ~MTC_BSY; -#if I7010 | I7080 + uptr->u6 = reclen; +#if I7080 chan_clear(chan, STA_TWAIT); #endif #ifdef I7010 chan_set(chan, STA_PEND); -#else +#endif /* We are like read that transfers nothing */ chan_set(chan, DEV_REOR); -#endif /* We don't set EOF on SKR */ if (r == MTSE_TMK) { sim_debug(DEBUG_DETAIL, dptr, "MARK\n"); - sim_activate(uptr, T1_us); + uptr->u5 |= MT_MARK; + uptr->u6 = 1; + sim_activate(uptr, 2*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; - sim_activate(uptr, (reclen * T1_us)); + sim_activate(uptr, 2*T1_us); break; case MT_ERG: sim_debug(DEBUG_DETAIL, dptr, "Erase unit=%d\n", unit); - uptr->u5 &= ~(MT_CMDMSK|MT_MARK); + uptr->u5 &= ~(MT_CMDMSK|MT_MARK|MT_LWR); uptr->u5 |= (MT_RDY | MT_IDLE); #if I7010 | I7080 chan_clear(chan, STA_TWAIT); @@ -1223,7 +1248,7 @@ t_stat mt_srv(UNIT * uptr) case MT_REW: sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d %d %d\n", unit, uptr->u3, uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200); - uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY); + uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY | MT_LWR); if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) { uptr->u5 |= MT_HREW; sim_activate(uptr, us_to_ticks(5000000)); @@ -1236,7 +1261,7 @@ t_stat mt_srv(UNIT * uptr) case MT_RUN: sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit); - uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY); + uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY | MT_LWR); uptr->u5 |= MT_UNLOAD; if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) { uptr->u5 |= MT_HREW; @@ -1348,6 +1373,7 @@ mt_attach(UNIT * uptr, CONST char *file) if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK) return r; + sim_tape_set_dens(uptr, (uptr->flags == MTUF_LDN) ? MT_DENS_200 : MT_DENS_556, NULL, NULL); uptr->u3 = 0; uptr->u5 |= MT_RDY; uptr->flags |= MTUF_ONLINE; diff --git a/I7000/i7010_chan.c b/I7000/i7010_chan.c index 4b936adf..6b75cf29 100644 --- a/I7000/i7010_chan.c +++ b/I7000/i7010_chan.c @@ -371,33 +371,30 @@ chan_proc() /* If device put up EOR, terminate transfer. */ if (chan_flags[chan] & DEV_REOR) { + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d EOR %02o Check\n", + chan, chan_io_status[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 { + } else if ((chan_flags[chan] & (CTL_READ|CTL_WRITE)) != 0) { 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]++; - } - } + uint8 ch = M[caddr[chan]++]; + if (ch != (WM|077)) { + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d WRL\n", chan); + chan_io_status[chan] |= IO_CHS_WRL; } - } 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]++; - } + } + 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] &= ~(STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR); chan_io_status[chan] |= IO_CHS_DONE; @@ -460,6 +457,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) /* Unit is busy doing something, wait */ if (chan_flags[chan] & (DEV_SEL|DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE)) return SCPE_BUSY; + sim_debug(DEBUG_CMD, &chan_dev, "chan %d %o cmd %02o %d\n", chan, dev, dcmd, addr); /* Ok, try and find the unit */ caddr[chan] = addr; assembly[chan] = 0; @@ -509,6 +507,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) chan_flags[chan] |= STA_ACTIVE; return r; } + /* Handle com device special also */ if ((com_dib.mask & dev) == (com_dib.addr & com_dib.mask)) { switch(dcmd) { case IO_RDS: chan_flags[chan] |= CTL_READ; break; @@ -525,6 +524,12 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) } r = chan_issue_cmd(chan, dcmd, dev); + switch(dcmd) { + case IO_RDS: chan_flags[chan] |= CTL_READ; break; + case IO_WRS: chan_flags[chan] |= CTL_WRITE; break; + case IO_TRS: chan_flags[chan] |= CTL_SNS; break; + case IO_CTL: chan_flags[chan] |= CTL_CNTL; break; + } /* Activate channel if select raised */ if (chan_flags[chan] & DEV_SEL) { chan_flags[chan] |= STA_ACTIVE; @@ -560,11 +565,11 @@ 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); + sim_debug(DEBUG_DATA, &chan_dev, "write chan %d char %o %d %o %o %o\n", chan, + *data, caddr[chan], M[caddr[chan]], chan_io_status[chan], flags); if (chan_flags[chan] & STA_WAIT) { - sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWR %d %o\n", chan, + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWRL %d %o\n", chan, caddr[chan], chan_io_status[chan]); chan_io_status[chan] |= IO_CHS_WRL; return END_RECORD; @@ -586,8 +591,7 @@ 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] |= IO_CHS_DONE; - caddr[chan]++; + chan_io_status[chan] |= IO_CHS_DONE|IO_CHS_WRL; 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); @@ -630,6 +634,8 @@ int chan_read_char(int chan, uint8 * data, int flags) { + sim_debug(DEBUG_DATA, &chan_dev, "read chan %d char %o %d %o %o\n", chan, + M[caddr[chan]], caddr[chan], chan_io_status[chan], flags); /* Return END_RECORD if requested */ if (flags & DEV_WEOR) { chan_flags[chan] &= ~(DEV_WEOR); @@ -656,11 +662,11 @@ chan_read_char(int chan, uint8 * data, int flags) *data = assembly[chan]; cmd[chan] &= ~CHAN_WM; } else { - if (!MEM_ADDR_OK(caddr[chan]+1)) { + if (!MEM_ADDR_OK(caddr[chan])) { chan_flags[chan] &= ~STA_ACTIVE; if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_DISCO; - caddr[chan]++; + chan_io_status[chan] |= IO_CHS_DONE; return END_RECORD; } assembly[chan] = M[caddr[chan]++]; @@ -670,6 +676,7 @@ chan_read_char(int chan, uint8 * data, int flags) if (chan_flags[chan] & DEV_SEL) chan_flags[chan] |= DEV_DISCO; chan_io_status[chan] |= IO_CHS_DONE; + sim_debug(DEBUG_DATA, &chan_dev, "read return EOR %d\n", chan); return END_RECORD; } if (cmd[chan] & CHAN_LOAD && @@ -691,6 +698,7 @@ chan_read_char(int chan, uint8 * data, int flags) chan_flags[chan] |= DEV_DISCO; chan_io_status[chan] |= IO_CHS_DONE; chan_flags[chan] |= DEV_REOR; + sim_debug(DEBUG_DATA, &chan_dev, "read return EOR2 %d\n", chan); return END_RECORD; } else chan_flags[chan] |= DEV_WRITE; diff --git a/I7000/i7010_cpu.c b/I7000/i7010_cpu.c index e4aaf027..8f0c2f8b 100644 --- a/I7000/i7010_cpu.c +++ b/I7000/i7010_cpu.c @@ -409,6 +409,10 @@ void WriteP(uint32 MA, uint8 v) { if (fault) return; + + if (MA == 275) { + int x = v+1; + } if (reloc && (MA & BBIT) == 0 && MAR > 100) { if (low_addr > 0) { MAR += low_addr; @@ -596,7 +600,7 @@ sim_instr(void) if (hst_lnt) /* History enabled? */ hst[hst_p].bend = BAR; } - chan_io_status[chwait & 07] &= ~0100; + chan_io_status[chwait & 07] &= ~IO_CHS_DONE; chwait = 0; } } @@ -1198,7 +1202,7 @@ sim_instr(void) case OP_IO4: /* Not in protected mode */ if (prot_enb || reloc) { - reason = STOP_PROG; + reason = STOP_IOCHECK; break; } case OP_STS: @@ -1242,10 +1246,6 @@ sim_instr(void) break; case OP_UC: /* Not in protected mode */ - if (prot_enb || reloc) { - reason = STOP_PROG; - break; - } /* Valid forms */ /* Op xxx mod */ @@ -1323,8 +1323,10 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PRIO && (pri_enb || timer_enable)) { 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] & (IO_CHS_OVER|IO_CHS_DONE)) + == (IO_CHS_OVER|IO_CHS_DONE) && chan_irq_enb[i]) irq = 1; if (chan_test(i, SNS_ATTN1)) @@ -1333,7 +1335,6 @@ sim_instr(void) irq = 1; } - if (irq || (timer_enable && timer_irq == 1)) { /* Check if we can interupt this opcode */ switch(op) { @@ -1387,24 +1388,25 @@ 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) { + sim_debug(DEBUG_PRIO, &cpu_dev, "Irq=%d\n",IAR); IAR = temp; AAR = 101; op = OP_PRI; - op_mod = CHR_X; /* X */ + op_mod = CHR_X; if (hst_lnt) { /* History enabled? */ hst[hst_p].inst[0] = op; hst[hst_p].inst[1] = op_mod; hst[hst_p].inst[2] = WM; } } else if (timer_enable && timer_irq == 1) { + sim_debug(DEBUG_PRIO, &cpu_dev, "Tim=%d\n",IAR); IAR = temp; AAR = 301; timer_irq = 2; op = OP_PRI; - op_mod = CHR_X; /* X */ + op_mod = CHR_X; if (hst_lnt) { /* History enabled? */ hst[hst_p].inst[0] = op; hst[hst_p].inst[1] = op_mod; @@ -1980,20 +1982,16 @@ sim_instr(void) case CHR_STAR: /* * Inq req ch 2 */ break; case CHR_1: /* 1 Overlap in Proc Ch 1 */ - jump = ((chan_io_status[1] & 0300) == 0200) && - chan_active(1); + jump = chan_active(1); break; case CHR_2: /* 2 Overlap in Proc Ch 2 */ - jump = ((chan_io_status[2] & 0300) == 0200) && - chan_active(2); + jump = chan_active(2); break; case CHR_4: /* 4 Channel 3 */ - jump = ((chan_io_status[3] & 0300) == 0200) && - chan_active(3); + jump = chan_active(3); break; case CHR_RPARN: /* ) Channel 4 */ - jump = ((chan_io_status[4] & 0300) == 0200) && - chan_active(4); + jump = chan_active(4); break; case CHR_9: /* 9 Carriage 9 CH1 */ /* 1401 same */ jump = lpr_chan9[1]; @@ -2250,15 +2248,19 @@ sim_instr(void) 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; + chan_io_status[ch & 07] |= IO_CHS_BUSY; break; case SCPE_NODEV: +fprintf(stderr, "No device %d %d\n\r", ch, temp); + /* Fall through */ case SCPE_IOERR: - chan_io_status[ch & 07] = IO_CHS_NORDY; + chan_io_status[ch & 07] |= IO_CHS_NORDY; break; } - if (CPU_MODEL == 1) + if (CPU_MODEL == 1) { chan_io_status[ch & 07] &= 0177; + chwait = (ch & 07) | 040; + } break; case OP_CC1: @@ -2274,13 +2276,17 @@ sim_instr(void) chan_irq_enb[ch & 7] = 0; break; case SCPE_BUSY: - chan_io_status[ch & 07] = IO_CHS_BUSY; + chan_io_status[ch & 07] |= IO_CHS_BUSY; break; case SCPE_NODEV: case SCPE_IOERR: - chan_io_status[ch & 07] = IO_CHS_NORDY; + chan_io_status[ch & 07] |= IO_CHS_NORDY; break; } + sim_debug(DEBUG_CMD, &cpu_dev, + "%d CC1 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 OP_CC2: @@ -2350,12 +2356,13 @@ sim_instr(void) switch (chan_cmd(temp, t, 0)) { case SCPE_OK: chan_io_status[ch & 07] = 0000; + chan_irq_enb[ch & 7] = 0; 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] = 1; } - chan_irq_enb[ch & 7] = 0; sim_debug(DEBUG_CMD, &cpu_dev, "%d UC on %o %o %s %c %o\n", IAR, ch & 07, temp, (ch & 010)?"": "overlap", @@ -2370,8 +2377,9 @@ sim_instr(void) chan_io_status[ch & 07] = IO_CHS_NORDY; break; } - if (CPU_MODEL == 1) + if (CPU_MODEL == 1) { chan_io_status[ch & 07] &= 0177; + } sim_interval -= 100; break; @@ -2380,12 +2388,19 @@ sim_instr(void) ch = 1; checkchan: chan_proc(); + /* If channel is active, wait for it to finish */ + if (chan_active(ch)) { + chwait = (ch & 07) | 040; + IAR = temp-6; /* Still holds the start of the instruction.*/ + break; + } + if (chan_io_status[ch] & op_mod) { jump = 1; } - 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]); + if (pri_enb == 0) { + chan_io_status[ch] &= 077; + } break; case OP_IO2: @@ -2732,6 +2747,7 @@ sim_instr(void) break; case CHR_M: /* M - Floating mul */ + CAR = AAR; temp = oind; oind = 0; reason = do_addsub(0); @@ -2746,16 +2762,18 @@ sim_instr(void) eoind = 1; break; } - CAR = AAR; - DAR = 279; + /* Scan for A word mark */ - qsign = 1; + zind = 1; + ix = 0; + AAR = CAR - 2; ar = ReadP(AAR); DownReg(AAR); + qsign = ((ar & 060) == 040); while (1) { if ((ar & 017) != 10) - qsign = 0; - ClrBit(DAR--, WM); /* Clear word marks */ + zind = 0; + ix++; if (ar & WM || AAR == 0) break; ar = ReadP(AAR); @@ -2763,64 +2781,117 @@ sim_instr(void) sim_interval -= 4; }; - ClrBit(DAR--, WM); /* Extra zero */ - if (qsign) + if (zind) goto zerofacc; + DAR = 279 - ix; + BAR = 297; + + br = ReadP(BAR--); + + /* Compute sign of product */ + qsign ^= ((br & 060) == 040); + qsign = (qsign)?040:060; /* Scan for B word mark */ zind = 1; - br = ReadP(BAR--); + WriteP(DAR--, WM); + temp = DAR; + + /* Copy B over */ while (1) { + WriteP(DAR--, CHR_0 | qsign); + qsign = 0; if ((br & 017) != 10) zind = 0; - WriteP(DAR--, br); if (br & WM || BAR == 279) break; br = ReadP(BAR--); sim_interval -= 2; }; + SetBit(DAR+1, WM); /* If B zero, scan to A word mark and set B zero */ - if (zind || qsign) + if (zind) goto zerofacc; - temp = BAR; /* Save for later */ - BAR = 279; - AAR = CAR; - reason = do_mult(); - if (reason != SCPE_OK) - break; + qsign = ReadP(temp) & 060; + DAR = 297; + br = ReadP(DAR); + BAR = temp = 279; + WriteP(BAR--, CHR_0 | qsign); + for (;ix > 0; ix--) { + WriteP(BAR--, CHR_0); + } + WriteP(BAR--, CHR_0); + zind = 1; + /* Do multiple loop until B word mark */ + while(1) { + uint8 bx; + /* Interloop, multiply one digit */ + ch = bcd_bin[br & 0xf]; + + while (ch != 0) { + WriteP(DAR, bin_bcd[ch - 1] | (br & WM)); + BAR = temp; + bx = ReadP(BAR); + cy = 0; + AAR = CAR-2; + ar = ReadP(AAR); + DownReg(AAR); + while(1) { + ch = bcd_bin[bx & 0xf]; + ch = bcd_bin[ar & 0xf] + ch + cy; + if (ch != 0) /* Clear zero */ + zind = 0; + cy = ch > 9; /* Update carry */ + WriteP(BAR--, bin_bcd[ch] | (bx & 0160)); + bx = ReadP(BAR); + if (ar & WM) + break; + ar = ReadP(AAR); + DownReg(AAR); + sim_interval -= 4; + } + /* Add carry to next digit */ + ch = bcd_bin[bx & 0xf] + cy; + if (ch != 0) /* Clear zero */ + zind = 0; + sim_interval -= 2; + WriteP(BAR--, bin_bcd[ch] | (bx & WM)); + br = ReadP(DAR); + ch = bcd_bin[br & 0xf]; + } + if (br & WM) + break; + temp--; + DAR--; + br = ReadP(DAR); + } /* Count number of leading zeros */ - ix = 0; - BAR++; /* Skip first zero */ + ix = -1; while (BAR != 280) { - br = ReadP(++BAR); + br = ReadP(BAR); if ((br & 017) != 10) break; + BAR++; ix++; } + + /* Find end of result */ + + /* Copy result */ + br = ReadP(BAR++) | WM; + while(DAR != 297) { + WriteP(DAR++, br); + br = ReadP(BAR++); + } + WriteP(DAR, br | qsign); + BAR = 299; if (ix != 0) { - DAR = BAR; - BAR = 299; if(do_addint(-ix)) goto undfacc; - BAR = DAR; } - /* Find end of result */ - CAR = 297; - ar = ReadP(CAR--); - while((ar & WM) == 0) - ar = ReadP(CAR--); - br = (ReadP(BAR) & 017) | WM; - /* Copy result */ - while(CAR != 297 && BAR != 279) { - WriteP(++CAR, br); - br = ReadP(++BAR) & 017; - } - while(CAR != 297) /* Zero fill rest */ - WriteP(++CAR, 10); - SetBit(297, ReadP(279) & 060); /* Copy sign */ break; case CHR_D: /* D - Floating div */ @@ -2857,8 +2928,10 @@ sim_instr(void) }; /* Are fractions same size? */ - if ((br & WM) && (ar & WM) == 0) + if ((br & WM) && (ar & WM) == 0) { + dind = 1; goto zerofacc; + } /* Is A zero? */ if (qsign) { @@ -2912,13 +2985,15 @@ sim_instr(void) goto zerofacc; } + /* Check if exponent went to small */ if (sign) { eoind = 1; break; } - if (ch) + if (ch) { goto undfacc; + } AAR = CAR; /* Do actual divide */ @@ -3096,20 +3171,16 @@ sim_instr(void) urec_irq[2] = 0; break; case CHR_1: /* 1 branch if ch 1 overlap priority */ - if (chan_irq_enb[1]) - jump = (chan_io_status[1] & 0300) == 0300; + jump = (chan_io_status[1] & 0200) == 0200; break; case CHR_2: /* 2 branch if ch 2 overlap priority */ - if (chan_irq_enb[2]) - jump = (chan_io_status[2] & 0300) == 0300; + jump = (chan_io_status[2] & 0200) == 0200; break; case CHR_3: /* 3 branch if ch 3 overlap priority */ - if (chan_irq_enb[3]) - jump = (chan_io_status[3] & 0300) == 0300; + jump = (chan_io_status[3] & 0300) == 0300; break; case CHR_4: /* 4 branch if ch 4 overlap priority */ - if (chan_irq_enb[4]) - jump = (chan_io_status[4] & 0300) == 0300; + jump = (chan_io_status[4] & 0300) == 0300; break; case CHR_Q: /* Q branch if inquiry ch 1 */ jump = inquiry; @@ -3138,12 +3209,12 @@ sim_instr(void) break; case CHR_X: /* X branch and exit */ pri_enb = 0; - sim_debug(DEBUG_PRIO, &cpu_dev, "dis irq\n"); + 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"); + sim_debug(DEBUG_PRIO, &cpu_dev, "enb irq\n"); jump = 1; break; case CHR_A: /* A branch if ch1 attention */ @@ -3182,19 +3253,17 @@ sim_instr(void) "Leave Protect mode %d %d %d\n", AAR & AMASK, prot_enb, reloc); /* If in protect mode, abort */ - if ((prot_enb /*|| reloc*/) /*&& (AAR & BBIT) == 0*/) { - reason = STOP_PROG; + if (prot_enb) { + jump = 1; + prot_enb = 0; + prot_fault |= 2; } else { /* Test protect mode */ - if (reloc && (AAR & BBIT) == 0) { - reason = STOP_PROG; - } else { - jump = 1; - prot_enb = 0; - reloc = 0; - high_addr = -1; - low_addr = -1; - } + jump = 0; + prot_enb = 0; + reloc = 0; + high_addr = -1; + low_addr = -1; } } break; @@ -3218,7 +3287,7 @@ sim_instr(void) if (cpu_unit.flags & OPTION_PROT) { sim_debug(DEBUG_DETAIL, &cpu_dev, "Check prog fault %d %d\n", - AAR, prot_fault&2); + AAR, prot_fault); /* If in protect mode, abort */ if (prot_enb) { reason = STOP_PROG; @@ -3266,29 +3335,24 @@ sim_instr(void) sim_debug(DEBUG_DETAIL, &cpu_dev, "Enable relocation + prot %d\n", AAR & AMASK); - if (prot_enb) { - reason = STOP_PROG; - } else { - prot_enb = 1; - reloc = 1; - prot_fault = 0; - BAR = IAR; - IAR = AAR; - if ((IAR & BBIT) == 0 && low_addr >= 0) { - if (IAR < low_addr) - IAR += 100000 - low_addr; - else - IAR -= low_addr; - } - /* Fix BAR for correct return address */ - if ((BAR & BBIT) == 0 && low_addr >= 0) { - if (BAR < low_addr) - BAR += 100000 - low_addr; - else - BAR -= low_addr; - } - AAR = BAR; + reloc = 1; + prot_fault = 0; + BAR = IAR; + IAR = AAR; + if ((IAR & BBIT) == 0 && low_addr >= 0) { + if (IAR < low_addr) + IAR += 100000 - low_addr; + else + IAR -= low_addr; } + /* Fix BAR for correct return address */ + if ((BAR & BBIT) == 0 && low_addr >= 0) { + if (BAR < low_addr) + BAR += 100000 - low_addr; + else + BAR -= low_addr; + } + AAR = BAR; } break; @@ -3404,6 +3468,7 @@ check_prot: "IAR = %d Prog check AAR=%d BAR=%d low=%d high=%d\n", IAR, AAR, BAR, low_addr, high_addr); prot_fault |= 2; + prot_enb = 0; reason = 0; break; case STOP_PROT: @@ -3411,6 +3476,7 @@ check_prot: "IAR = %d Prot check AAR=%d BAR=%d low=%d high=%d\n", IAR, AAR, BAR, low_addr, high_addr); prot_fault |= 1; + prot_enb = 0; reason = 0; break; default: /* Anything else halt sim */ diff --git a/I7000/i7080_chan.c b/I7000/i7080_chan.c index 531ae7d7..f94b714d 100644 --- a/I7000/i7080_chan.c +++ b/I7000/i7080_chan.c @@ -190,7 +190,6 @@ chan_reset(DEVICE * dptr) /* Clear channel assignment */ for (i = 0; i < NUM_CHAN; i++) { - chan_flags[i] = 0; caddr[i] = 0; cmd[i] = 0; bcnt[i] = 0; @@ -361,7 +360,8 @@ int chan_zero_reccnt(int chan) { /* Return next channel data address, advance address by 5 if channel */ uint32 chan_next_addr(int chan) { - int unit = 0; + uint32 unit = 0; + uint32 s_unit = 0; uint32 addr = 0; switch(CHAN_G_TYPE(chan_unit[chan].flags)) { case CHAN_754: @@ -375,8 +375,9 @@ uint32 chan_next_addr(int chan) { unit = 8 + 1024 + chan_unit[chan].u3 * 32; break; } - addr = load_addr(unit); - store_addr(addr + 5, unit); + s_unit = unit; + addr = load_addr(&unit); + store_addr(addr + 5, &s_unit); return addr; } @@ -831,11 +832,19 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) switch(CHAN_G_TYPE(chan_unit[chan].flags)) { case CHAN_754: case CHAN_UREC: + if (M[caddr[chan]] == CHR_GM) { + return SCPE_OK; + } cmd[chan] |= CHAN_NOREC; break; case CHAN_7621: dcmd &= ~ CHAN_ZERO; switch(dcmd & 0xf) { + case 0: + if (M[caddr[chan]] == CHR_GM) { + return SCPE_OK; + } + break; case 1: cmd[chan] |= CHAN_NOREC; break; case 2: unit = 512 + chan_unit[chan].u3 * 32; @@ -901,6 +910,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) chan_flags[chan] &= ~(CHS_EOF|CHS_ERR|CHS_ATTN); /* Activate channel if select raised */ if (r == SCPE_OK && chan_flags[chan] & DEV_SEL) { + uint32 t_unit; chan_flags[chan] |= STA_ACTIVE; irqdev[chan] = dev; irqflags &= ~(1 << chan); @@ -920,13 +930,17 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr) unit = 512 + chan_unit[chan].u3 * 32; AC[unit+16+5] = 10; /* Set digit next to 0 */ AC[unit+24+5] = 10; - store_addr(caddr[chan], 8 + unit); + sim_debug(DEBUG_DETAIL, &chan_dev, + "chan %d set addr %d\n", chan, caddr[chan]); + t_unit = 8 + unit; + store_addr(caddr[chan], &t_unit); if (cmd[chan] & CHAN_RECCNT && chan_zero_reccnt(chan)) { cmd[chan] &= ~CHAN_RECCNT; } break; case CHAN_7908: - store_addr(caddr[chan], 8+1024 + chan_unit[chan].u3 * 32); + t_unit = 8+1024+chan_unit[chan].u3 * 32; + store_addr(caddr[chan], &t_unit); break; } } diff --git a/I7000/i7080_cpu.c b/I7000/i7080_cpu.c index 69fa0cc5..fe7fe23e 100644 --- a/I7000/i7080_cpu.c +++ b/I7000/i7080_cpu.c @@ -74,6 +74,10 @@ #define EMULATE2 (2 << UNIT_EMU) #define UNIT_V_NONSTOP (UNIT_EMU + 2) #define NONSTOP (1 << UNIT_V_NONSTOP) +#define UNIT_V_IOIRQ (UNIT_V_NONSTOP + 1) +#define IOIRQ (1 << UNIT_V_IOIRQ) +#define UNIT_V_40K (UNIT_V_IOIRQ + 1) +#define EMU40K (1 << UNIT_V_40K) #define CPU_702 0x0 #define CPU_705 0x1 @@ -116,8 +120,8 @@ const char *cpu_description (DEVICE *dptr); uint32 read_addr(uint8 *reg, uint8 *zone); void write_addr(uint32 addr, uint8 reg, uint8 zone); -uint32 load_addr(int loc); -void store_addr(uint32 addr, int loc); +uint32 load_addr(uint32 *loc); +void store_addr(uint32 addr, uint32 *loc); void store_cpu(uint32 addr, int full); void load_cpu(uint32 addr, int full); uint16 get_acstart(uint8 reg); @@ -197,7 +201,7 @@ uint8 cmp_order[0100] = { #define SIGN (ASIGN|BSIGN) #define ZERO (AZERO|BZERO) -#define IRQFLAGS (INSTFLAG|MCHCHK|IOCHK|RECCHK|ACOFLAG|SGNFLAG) +#define IRQFLAGS (ANYFLAG) uint8 M[MAXMEMSIZE] = { 0 }; /* memory */ uint32 EMEMSIZE; /* Physical memory size */ @@ -298,6 +302,10 @@ MTAB cpu_mod[] = { {EMULATE3, EMULATE3, "EMU7053", "EMU7053", NULL, NULL, NULL}, {NONSTOP, 0, "PROGRAM", "PROGRAM", NULL, NULL, NULL}, {NONSTOP, NONSTOP, "NONSTOP", "NONSTOP", NULL, NULL, NULL}, + {IOIRQ, 0, "NOIOIRQ", "NOIOIRQ", NULL, NULL, NULL}, + {IOIRQ, IOIRQ, "IOIRQ", "IOIRQ", NULL, NULL, NULL}, + {EMU40K, 0, "NOEMU40K", "NOEMU40K", NULL, NULL, NULL}, + {EMU40K, EMU40K, "EMU40K", "EMU40K", NULL, NULL, NULL}, {MTAB_XTD | MTAB_VDV | MTAB_NMO | MTAB_SHP, 0, "HISTORY", "HISTORY", &cpu_set_hist, &cpu_show_hist}, {0} @@ -318,7 +326,7 @@ uint16 prev_addr[6 * 256]; /* Previous storage location */ uint16 next_half[6 * 256]; /* Forward half loop locations */ /*#define ReadP(addr) M[(addr) % EMEMSIZE] */ -#define WriteP(addr, data) M[(addr) % EMEMSIZE] = data +/*#define WriteP(addr, data) M[(addr) % EMEMSIZE] = data */ #define Next(reg) if (reg == 0) reg = EMEMSIZE; reg-- #define Prev5(reg) reg += 5; if (reg > EMEMSIZE) reg -= EMEMSIZE @@ -328,7 +336,11 @@ uint16 next_half[6 * 256]; /* Forward half loop locations */ /* Read 1 character from memory, checking for reducancy error. */ uint8 ReadP(uint32 addr, uint16 flag) { uint8 value; - value = M[(addr) % EMEMSIZE]; + addr %= EMEMSIZE; + if ((flags & EMU40K) != 0) { + addr %= 40000; + } + value = M[addr]; if (value & 0100) { if (flag == 0) return value; @@ -336,7 +348,7 @@ uint8 ReadP(uint32 addr, uint16 flag) { } else if (value == 0) { flags |= flag|ANYFLAG; } - return value & 077; + return value; } /* Read 5 characters from memory starting at addr */ @@ -351,6 +363,15 @@ uint32 Read5(uint32 addr, uint16 flag) { return value; } +/* Write 1 character to memory. */ +void WriteP(uint32 addr, uint8 value) { + addr %= EMEMSIZE; + if ((flags & EMU40K) != 0) { + addr %= 40000; + } + M[addr] = value; +} + /* Write 5 characters from memory starting at addr */ void Write5(uint32 addr, uint32 value) { WriteP(addr-4, 077 & (value >> (4 * 6))); @@ -453,11 +474,6 @@ stop_cpu: if ((cpu_unit.flags & NONSTOP) && (intprog == 0) && intmode != 0 && selreg2 == 0 && (IRQFLAGS & flags)) { /* Process as interrupt */ - Next(IC); /* Back up to start of instruction */ - Next(IC); - Next(IC); - Next(IC); - Next(IC); store_cpu(0x3E0, 1); load_cpu(0x2A0, 0); intprog = 1; @@ -495,41 +511,8 @@ stop_cpu: flags &= ~(SGNFLAG|ANYFLAG); break; } - } else if (cpu_unit.flags & NONSTOP && intprog && (IRQFLAGS & flags)) { - /* Issue sim halt */ - if (flags & INSTFLAG) { - reason = STOP_UUO; - flags &= ~ (INSTFLAG|ANYFLAG); - break; - } - if (flags & MCHCHK) { - reason = STOP_MMTRP; - flags &= ~(MCHCHK|ANYFLAG); - break; - } - if (flags & IOCHK) { - reason = STOP_IOCHECK; - flags &= ~(IOCHK|ANYFLAG); - break; - } - if (flags & RECCHK) { - reason = STOP_RECCHK; - flags &= ~(RECCHK|ANYFLAG); - break; - } - if (flags & ACOFLAG) { - reason = STOP_ACOFL; - flags &= ~(ACOFLAG|ANYFLAG); - break; - } - if (flags & SGNFLAG) { - reason = STOP_SIGN; - flags &= ~(SGNFLAG|ANYFLAG); - break; - } } - /* If we are waiting on I/O, don't fetch */ if (!chwait) { if (!iowait) { @@ -763,6 +746,12 @@ stop_cpu: default: break; } + if (CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && reg < 4 && + (flags & EIGHTMODE) == 0) { + flags |= INSTFLAG|ANYFLAG; + t = 0; + } } else { switch((selreg >> 8) & 0xff) { case 20: /* Tape DS */ @@ -824,6 +813,15 @@ stop_cpu: default: /* Drum */ break; } + if (CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0) { + temp = (selreg >> 8) & 0xff; + if (temp != 9 && temp != 5) { + flags |= INSTFLAG|ANYFLAG; + t = 0; + } + } } if (t) { IC = MAC; @@ -962,8 +960,10 @@ stop_cpu: cr2 &= 060; cr2 |= 012; } - if ((cr2 & 060) == 040 || (cr2 & 060) == 020) + if ((cr2 & 060) == 040 || (cr2 & 060) == 020) { cr2 |= 0100; + flags |= MCHCHK|ANYFLAG; + } } WriteP(MA, cr2); Next(MA); @@ -1045,6 +1045,9 @@ stop_cpu: AC[addr] = 10; } else if (AC[addr] != 10) flags &= ~(ZERO & fmsk); /* No zero, adjust flag */ + if (AC[addr] & 0100) { + flags |= MCHCHK|ANYFLAG; + } MAC--; addr = next_addr[addr]; sim_interval --; /* count down */ @@ -1405,6 +1408,12 @@ stop_cpu: chan_chr_13(); memset(ioflags, 0, sizeof(ioflags)); flags &= ~(IRQFLAGS); + if (CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0 && + ((selreg >> 8) & 0xff) != 5) { + flags |= ANYFLAG|INSTFLAG; + } break; case 14: /* EEM */ @@ -1521,6 +1530,12 @@ stop_cpu: break; } } + if (iowait == 0 && CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0 && + ((selreg >> 8) & 0xff) != 5) { + flags |= ANYFLAG|INSTFLAG; + } break; case OP_RD: /* READ */ @@ -1538,6 +1553,12 @@ stop_cpu: flags |= ANYFLAG|INSTFLAG; break; } + if (iowait == 0 && CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0 && + ((selreg >> 8) & 0xff) != 5) { + flags |= ANYFLAG|INSTFLAG; + } break; case OP_WR: /* WRITE */ @@ -1555,6 +1576,12 @@ stop_cpu: flags |= ANYFLAG|INSTFLAG; break; } + if (iowait == 0 && CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0 && + ((selreg >> 8) & 0xff) != 5) { + flags |= ANYFLAG|INSTFLAG; + } break; case OP_WRE: /* WR ER */ @@ -1572,11 +1599,25 @@ stop_cpu: flags |= ANYFLAG|INSTFLAG; break; } + if (iowait == 0 && CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0 && + ((selreg >> 8) & 0xff) != 5) { + flags |= ANYFLAG|INSTFLAG; + } break; case OP_RWW: /* RWW 705 only */ MAC2 = MAC; - selreg2 = selreg | 0x8000; + if (CPU_MODEL == CPU_7080 && + (cpu_unit.flags & IOIRQ) != 0 && + (flags & EIGHTMODE) == 0 && + ((selreg >> 8) & 0xff) != 5) { + flags |= ANYFLAG|INSTFLAG; + selreg2 = selreg; + } else { + selreg2 = selreg | 0x8000; + } break; /* 7080 opcodes */ @@ -1786,7 +1827,7 @@ stop_cpu: case 14: /* SMT */ write_addr(MAC2, 0, 0); WriteP(MA, 10); /* Finish with zero */ - store_addr(MAC2, addr); + store_addr(MAC2, &addr); sim_interval -= 10; break; } @@ -2186,8 +2227,6 @@ stop_cpu: break; } t = ReadP(MA, 0); - if (t & 0100) - flags |= MCHCHK|ANYFLAG; sim_interval --; /* count down */ switch(reg) { case 0: /* Nop */ @@ -2198,12 +2237,20 @@ stop_cpu: case 4: /* 8 */ case 5: /* A */ case 6: /* B */ + if (t & 0100) + flags |= MCHCHK|ANYFLAG; t &= ~(1<<(reg-1)); + t &= 077; break; case 7: /* Reverse A */ + if (t & 0100) + flags |= MCHCHK|ANYFLAG; t ^= 020; + t &= 077; break; case 8: /* Reverse C */ + if (t & 0100) + flags |= MCHCHK; t = M[MA % EMEMSIZE] ^ 0100; break; case 9: /* 1 */ @@ -2212,7 +2259,10 @@ stop_cpu: case 12: /* 8 */ case 13: /* A */ case 14: /* B */ + if (t & 0100) + flags |= MCHCHK|ANYFLAG; t |= 1<<(reg-9); + t &= 077; break; } WriteP(MA, t); @@ -2224,7 +2274,7 @@ stop_cpu: } if (hst_lnt) { /* history enabled? */ hst[hst_p].flags = flags; - addr = get_acstart(reg); + addr = spc; for (t = 0; t < 254; t++) { hst[hst_p].store[t] = AC[addr]; addr = next_addr[addr]; @@ -2356,7 +2406,7 @@ void write_addr(uint32 addr, uint8 reg, uint8 zone) { } /* Store converted address in storage */ -void store_addr(uint32 addr, int loc) { +void store_addr(uint32 addr, uint32 *loc) { uint8 value[4]; int i; @@ -2386,7 +2436,7 @@ void store_addr(uint32 addr, int loc) { if ((cpu_unit.flags & EMULATE2)) value[3] |= (addr & 0xc) << 2; else /* 20k */ - value[3] |= (addr & 0x8) << 2; + value[3] |= (addr & 0xc) << 2; break; case CPU_702: /* 702 */ break; @@ -2398,32 +2448,37 @@ void store_addr(uint32 addr, int loc) { value[i] &= 0360; if (value[i] == 0) value[i] = 10; - AC[loc] = value[i]; - loc = next_addr[loc]; + AC[*loc] = value[i]; + *loc = next_addr[*loc]; } } /* Read address from storage */ -uint32 load_addr(int loc) { +uint32 load_addr(uint32 *loc) { uint8 t; + uint8 f; uint8 zone; uint32 addr; - t = AC[loc]; /* First digit */ - loc = next_addr[loc]; + t = AC[*loc]; /* First digit */ + f = t; zone = (t & 060) >> 2; addr = bcd_bin[t & 0xf]; - t = AC[loc]; /* Second digit */ - loc = next_addr[loc]; + *loc = next_addr[*loc]; + t = AC[*loc]; /* Second digit */ + f |= t; addr += dig2[bcd_bin[t & 0xf]]; - t = AC[loc]; /* Read third digit */ - loc = next_addr[loc]; + *loc = next_addr[*loc]; + t = AC[*loc]; /* Read third digit */ + f |= t; addr += dig3[bcd_bin[t & 0xf]]; - t = AC[loc]; /* Save High order address */ - loc = next_addr[loc]; + *loc = next_addr[*loc]; + t = AC[*loc]; /* Save High order address */ + f |= t; zone |= (t & 060) >> 4; addr += dig4[bcd_bin[t & 0xf]]; + *loc = next_addr[*loc]; switch (cpu_type) { case CPU_7080: /* 7080 */ break; @@ -2432,50 +2487,65 @@ uint32 load_addr(int loc) { if (cpu_unit.flags & EMULATE2) zone &= 3; /* 40k */ else - zone &= 013; /* 80k */ + zone &= 7; /* 80k */ break; case CPU_705: /* 705 */ if (cpu_unit.flags & EMULATE2) zone &= 3; /* 40K */ else - zone &= 1; /* 20k */ + zone &= 3; /* 20k */ break; case CPU_702: /* 702 */ zone = 0; /* 10k Memory */ break; } addr += dig_zone[zone]; + /* Set Machine Check if got redundant data */ + if (f & 0100) { + flags |= MCHCHK|ANYFLAG; + } return addr; } /* Store converted hex address in storage */ -void store_hex(uint32 addr, int loc) { +void store_hex(uint32 addr, uint32 *loc) { /* Convert address into BCD first */ - AC[loc] = bin_bcd[addr & 0xf]; - loc = next_addr[loc]; - AC[loc] = bin_bcd[(addr >> 4) & 0xf]; - loc = next_addr[loc]; - AC[loc] = bin_bcd[(addr >> 8) & 0xf]; - loc = next_addr[loc]; - AC[loc] = bin_bcd[(addr >> 12) & 0xf]; + AC[*loc] = bin_bcd[addr & 0xf]; + *loc = next_addr[*loc]; + AC[*loc] = bin_bcd[(addr >> 4) & 0xf]; + *loc = next_addr[*loc]; + AC[*loc] = bin_bcd[(addr >> 8) & 0xf]; + *loc = next_addr[*loc]; + AC[*loc] = bin_bcd[(addr >> 12) & 0xf]; + *loc = next_addr[*loc]; } /* Read hex address from storage */ -uint32 load_hex(int loc) { +uint32 load_hex(uint32 *loc) { uint8 t; + uint8 f; uint32 addr; - t = AC[loc]; /* First digit */ + t = AC[*loc]; /* First digit */ + f = t; addr = bcd_bin[t & 0xf]; - loc = next_addr[loc]; - t = AC[loc]; /* Second digit */ + *loc = next_addr[*loc]; + t = AC[*loc]; /* Second digit */ + f |= t; addr += bcd_bin[t & 0xf] << 4; - loc = next_addr[loc]; - t = AC[loc]; /* Read third digit */ + *loc = next_addr[*loc]; + t = AC[*loc]; /* Read third digit */ + f |= t; addr += bcd_bin[t & 0xf] << 8; - loc = next_addr[loc]; - t = AC[loc]; /* Save High order address */ + *loc = next_addr[*loc]; + t = AC[*loc]; /* Save High order address */ + f |= t; addr += bcd_bin[t & 0xf] << 12; + *loc = next_addr[*loc]; + /* Set Machine Check if got redundant data */ + if (f & 0100) { + flags |= MCHCHK|ANYFLAG; + } return addr; } @@ -2497,89 +2567,137 @@ uint16 get_acstart(uint8 reg) { /* Store CPU state in CASU 15 */ void store_cpu(uint32 addr, int full) { - uint8 t; + uint8 t; - store_addr(IC, addr); - addr = next_addr[addr]; - addr = next_addr[addr]; - addr = next_addr[addr]; - addr = next_addr[addr]; + store_addr(IC, &addr); /* Save status characters */ - t = flags & 0xf; - AC[addr] = 040 | ((t + 8) & 027); - addr = next_addr[addr]; - t = (flags >> 4) & 0xf; - AC[addr] = 040 | ((t + 8) & 027); - addr = next_addr[addr]; - t = (flags >> 8) & 0xf; - AC[addr] = 040 | ((t + 8) & 027); - addr = next_addr[addr]; - t = (flags >> 12) & 0x3; - AC[addr] = 040 | t; - if (full) { - addr = next_addr[addr]; - AC[addr] = bin_bcd[spc & 7]; - addr = next_addr[addr]; - AC[addr] = bin_bcd[(spc >> 3) & 3]; - addr = next_addr[addr]; - AC[addr] = bin_bcd[(spc >> 5) & 7]; - addr = next_addr[addr]; - AC[addr] = bin_bcd[(spc >> 8) & 7]; - addr = next_addr[addr]; - for(; addr < 0x3F8; addr++) - AC[addr] = 10; - for(; addr < 0x400; addr++) - AC[addr] = 0; - store_addr(MAC2, 0x3F0); - store_hex(selreg, 0x3F8); - } + t = flags & 0xf; + AC[addr] = 040 | ((t + 8) & 027); + addr = next_addr[addr]; + t = (flags >> 4) & 0xf; + AC[addr] = 040 | ((t + 8) & 027); + addr = next_addr[addr]; + t = (flags >> 8) & 0xf; + AC[addr] = 040 | ((t + 8) & 027); + addr = next_addr[addr]; + t = (flags >> 12) & 0x3; + AC[addr] = 040 | t; + if (full) { + addr = next_addr[addr]; + AC[addr] = bin_bcd[spc & 7]; + addr = next_addr[addr]; + AC[addr] = bin_bcd[(spc >> 3) & 3]; + addr = next_addr[addr]; + AC[addr] = bin_bcd[(spc >> 5) & 7]; + addr = next_addr[addr]; + AC[addr] = bin_bcd[(spc >> 8) & 7]; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + store_addr(MAC2, &addr); + AC[addr] = 10; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + AC[addr] = 10; + addr = next_addr[addr]; + store_hex(selreg, &addr); + AC[addr] = 0; + addr = next_addr[addr]; + AC[addr] = 0; + addr = next_addr[addr]; + AC[addr] = 0; + addr = next_addr[addr]; + AC[addr] = 0; + } } /* Load CPU State from storage */ void load_cpu(uint32 addr, int full) { uint8 t; + uint8 f; - IC = load_addr(addr); - addr = next_addr[addr]; - addr = next_addr[addr]; - addr = next_addr[addr]; - addr = next_addr[addr]; flags = 0; - t = AC[addr++]; + IC = load_addr(&addr); + t = AC[addr]; + addr = next_addr[addr]; + f = t; flags |= (t & 0x7) | ((t >> 1) & 0x8); - t = AC[addr++]; + t = AC[addr]; + addr = next_addr[addr]; + f |= t; flags |= ((t & 0x7) | ((t >> 1) & 0x8)) << 4; - t = AC[addr++]; + t = AC[addr]; + addr = next_addr[addr]; + f |= t; flags |= ((t & 0x7) | ((t >> 1) & 0x8)) << 8; - t = AC[addr++]; + t = AC[addr]; + addr = next_addr[addr]; + f |= t; flags |= (t & 0x3) << 12; - /* Adjust Max memory if mode changed */ - EMEMSIZE = MEMSIZE; - if (flags & EIGHTMODE) { - cpu_type = CPU_7080; - } else { - cpu_type = (cpu_unit.flags & EMULATE3)? CPU_7053:CPU_705; - EMEMSIZE = MEMSIZE; - if (cpu_unit.flags & EMULATE2 && EMEMSIZE > 40000) - EMEMSIZE = 40000; - if (cpu_type == CPU_705 && (cpu_unit.flags & EMULATE2) == 0 - && EMEMSIZE > 20000) - EMEMSIZE = 20000; - if (EMEMSIZE > 80000) - EMEMSIZE = 80000; + /* Update emulation mode */ + if (CPU_MODEL == CPU_7080) { + if (flags & EIGHTMODE) { + EMEMSIZE = MEMSIZE; + cpu_type = CPU_7080; + } else { + cpu_type = (cpu_unit.flags & EMULATE3)? CPU_7053:CPU_705; + EMEMSIZE = MEMSIZE; + if (cpu_unit.flags & EMULATE2 && EMEMSIZE > 40000) + EMEMSIZE = 40000; + if (cpu_type == CPU_705 && (cpu_unit.flags & EMULATE2) == 0 && + EMEMSIZE > 20000) + EMEMSIZE = 20000; + if (EMEMSIZE > 80000) + EMEMSIZE = 80000; + } } if (full) { - spc = bcd_bin[AC[addr++]] & 07; /* Units digit */ + int i; + t = AC[addr]; + addr = next_addr[addr]; + f |= t; + spc = bcd_bin[t & 0xf] & 07; /* Units digit */ /* One of words */ - spc += (bcd_bin[AC[addr++]] & 3) << 3; /* Tens digit */ + t = AC[addr]; + addr = next_addr[addr]; + f |= t; + spc += (bcd_bin[t & 0xf] & 3) << 3; /* Tens digit */ /* One of four word sets */ - spc += (bcd_bin[AC[addr++]] & 7) << 5; /* Hundreds */ + t = AC[addr]; + addr = next_addr[addr]; + f |= t; + spc += (bcd_bin[t & 0xf] & 7) << 5; /* Hundreds */ /* Bank */ - spc += (bcd_bin[AC[addr++]] & 7) << 8; /* Thousands */ - addr += 4; - MAC2 = load_addr(addr); - addr += 8; - selreg = load_hex(addr); + t = AC[addr]; + addr = next_addr[addr]; + f |= t; + spc += (bcd_bin[t & 0xf] & 7) << 8; /* Thousands */ + for (i = 0; i < 4; i++) { + f |= AC[addr]; + addr = next_addr[addr]; + } + MAC2 = load_addr(&addr); + for (i = 0; i < 4; i++) { + f |= AC[addr]; + addr = next_addr[addr]; + } + selreg = load_hex(&addr); + for (i = 0; i < 4; i++) { + f |= AC[addr]; + addr = next_addr[addr]; + } + } + if (f & 0100) { + flags |= MCHCHK | ANYFLAG; } } @@ -2825,6 +2943,7 @@ do_divide(int reg, uint16 fmsk) int remtrig; int carry; int dzt; + int over; /* Step I, put storage mark before start of AC */ at = 0; @@ -2833,6 +2952,7 @@ do_divide(int reg, uint16 fmsk) smt = 1; carry = 0; msign = 0; + over = 0; /* Step II, step address until we find storage mark */ step2: @@ -2947,6 +3067,8 @@ step6: tsac = tspc; if (t >= 10) { flags |= ACOFLAG|ANYFLAG; + msign = 0; + over = 1; at = 1; goto step2; } @@ -2967,6 +3089,8 @@ step6: at = 1; if (t >= 10) { flags |= ACOFLAG|ANYFLAG; + msign = 0; + over = 1; goto step2; } dzt = 0; @@ -3065,7 +3189,9 @@ done: /* Update sign and zero */ flags ^= msign; - flags &= ~(((flags & ZERO) >> 2) & fmsk); + if (over == 0) { + flags &= ~(((flags & ZERO) >> 2) & fmsk); + } return SCPE_OK; } @@ -3380,8 +3506,12 @@ cpu_show_hist(FILE * st, UNIT * uptr, int32 val, CONST void *desc) (h->flags & LOWFLAG)? 'l' : ((h->flags & HIGHFLAG) ? 'h' : 'e')); - for(len--; len >= 0; len--) + for(len--; len >= 0; len--) { fputc(mem_to_ascii[h->store[len] & 077], st); + if (h->store[len] & 0100) { + fputc('|', st); + } + } fputc('@', st); if (h->flags & 0x7f0) { int i; diff --git a/I7000/i7080_defs.h b/I7000/i7080_defs.h index ea91ead0..81701310 100644 --- a/I7000/i7080_defs.h +++ b/I7000/i7080_defs.h @@ -36,8 +36,8 @@ int chan_cmd(uint16 dev, uint16 cmd, uint32 addr); int chan_mapdev(uint16 dev); /* Process the CHR 3 13 command and abort all channel activity */ void chan_chr_13(); -uint32 load_addr(int loc); -void store_addr(uint32 addr, int loc); +uint32 load_addr(uint32 *loc); +void store_addr(uint32 addr, uint32 *loc); /* Opcode definitions. */ #define OP_TR CHR_1 diff --git a/I7000/i7090_cdr.c b/I7000/i7090_cdr.c index a72f1506..e075646c 100644 --- a/I7000/i7090_cdr.c +++ b/I7000/i7090_cdr.c @@ -109,8 +109,12 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev) } return SCPE_BUSY; } - chan_set_attn(chan); - return SCPE_NODEV; + uptr->wait = 0; + uptr->u5 |= URCSTA_READ | URCSTA_CMD | (24 << CDRPOSSHIFT); + chan_set_sel(chan, 0); + chan_clear_status(chan); + sim_activate(uptr, us_to_ticks(1000)); /* activate */ + return SCPE_OK; } t_stat cdr_srv(UNIT * uptr) diff --git a/I7000/i7090_chan.c b/I7000/i7090_chan.c index c2ef53cd..8d9639f0 100644 --- a/I7000/i7090_chan.c +++ b/I7000/i7090_chan.c @@ -376,11 +376,10 @@ chan_proc() if ((chan_flags[chan] & DEV_SEL) == 0 && (chan_flags[chan] & STA_TWAIT)) { if (chan_dev.dctrl & cmask) - sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap\n", - chan); + sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap IC=%06o\n", + chan, IC); iotraps |= 1 << chan; - chan_flags[chan] &= - ~(STA_START | STA_ACTIVE | STA_WAIT | STA_TWAIT); + chan_flags[chan] &= ~(STA_START | STA_ACTIVE | STA_WAIT | STA_TWAIT); chan_info[chan] = 0; continue; } @@ -441,7 +440,7 @@ chan_proc() /* Device has given us a dataword */ case DEV_FULL: /* If we are not waiting EOR save it in memory */ - if ((cmd[chan] & 1) == 0) { + if (/*(chan_flags[chan] & CHS_ERR) == 0 &&*/ (cmd[chan] & 1) == 0) { if (chan_dev.dctrl & cmask) sim_debug(DEBUG_DATA, &chan_dev, "chan %d data < %012llo\n", chan, assembly[chan]); @@ -1569,6 +1568,7 @@ chan_write_char(int chan, uint8 * data, int flags) } else { int cnt = --bcnt[chan]; t_uint64 wd; + if (CHAN_G_TYPE(chan_unit[chan].flags) == CHAN_PIO) wd = MQ; else diff --git a/I7000/i7090_cpu.c b/I7000/i7090_cpu.c index ca71b5f7..669d1589 100644 --- a/I7000/i7090_cpu.c +++ b/I7000/i7090_cpu.c @@ -815,6 +815,8 @@ sim_instr(void) MA = 012; f = 0; + sim_debug(DEBUG_TRAP, &cpu_dev, + "Checking trap chan IC=%06o %06o\n", IC, iotraps); for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) { /* CRC *//* Trap *//* EOF */ /* Wait until channel stops to trigger interupts */ @@ -828,10 +830,12 @@ sim_instr(void) iotraps &= ~(1 << shiftcnt); } } - if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR)) + if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR)) { f |= 2; /* We have device error */ + } /* check if we need to perform a trap */ if (f) { +// iotraps &= ~(1 << (shiftcnt + 18)); /* HTR/HPR behave like wait if protected */ if (hltinst) temp = (((t_uint64) bcore & 3) << 31) | @@ -854,8 +858,8 @@ sim_instr(void) sim_interval = sim_interval - 1; /* count down */ SR = ReadP(MA); sim_debug(DEBUG_TRAP, &cpu_dev, - "Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o\n", - shiftcnt + 'A' - 1, f, temp, MA, SR, IC); + "Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o %06o\n", + shiftcnt + 'A' - 1, f, temp, MA, SR, IC, iotraps); if (hst_lnt) { /* history enabled? */ hst_p = (hst_p + 1); /* next entry */ if (hst_p >= hst_lnt) @@ -1329,10 +1333,12 @@ prottrap: if ((bcore & 4) || STM) goto seltrap; itrap = 1; +// iotraps &= ~(AMASK & (ioflags << 1)); if (CPU_MODEL == CPU_709) ihold = 1; else ihold = 2; + sim_debug(DEBUG_TRAP, &cpu_dev, "rxt %06o\n", iotraps); } break; case OP_LMTM: @@ -1481,7 +1487,7 @@ prottrap: hltinst = 1; ihold = 0; /* Kill any hold on traps now */ if (opcode == OP_HTR) { - fptemp = IC-1; + fptemp = IC; IC = MA; } else fptemp = IC; @@ -3339,14 +3345,16 @@ prottrap: itrap = 1; else itrap = 0; - sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo\n", ioflags); - ihold = 1; + sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo %06o\n", ioflags, iotraps); /* * IBSYS can't have an trap right after ENB or it will hang * on a TTR * in IBNUC. */ - if (CPU_MODEL >= CPU_7090) + if (CPU_MODEL >= CPU_7090) { + ihold = 1; break; + } +#if 0 temp = 00000001000001LL; for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) { @@ -3360,6 +3368,7 @@ prottrap: ihold = 0; temp <<= 1; } +#endif break; #endif @@ -3393,15 +3402,21 @@ prottrap: switch (chan_cmd(MA, opcode)) { case SCPE_BUSY: iowait = 1; /* Channel is active, hold */ + ihold = 1; /* Hold interupts for one cycle */ break; case SCPE_OK: - if (((MA >> 9) & 017) == 0) { - if (opcode==IO_RDS) - MQ = 0; - chan_clear(0, CHS_EOF|CHS_EOT|DEV_REOR); + { uint16 temp16; + temp16 = (MA >> 9) & 017; + if (temp16 == 0) { + if (opcode==IO_RDS) + MQ = 0; + chan_clear(0, CHS_EOF|CHS_EOT|DEV_REOR); + } else { + iotraps &= ~(1 << temp16); + chan_clear(temp16, CHS_EOF|CHS_EOT|DEV_REOR); + } } ihold = 1; /* Hold interupts for one cycle */ - iotraps &= ~(1 << ((MA >> 9) & 017)); break; case SCPE_IOERR: iocheck = 1; @@ -4183,7 +4198,7 @@ cpu_reset(DEVICE * dptr) interval_irq = dcheck = acoflag = mqoflag = iocheck = 0; sim_brk_types = sim_brk_dflt = SWMASK('E'); limitaddr = 077777; - memmask = MEMMASK; + memmask = MEMSIZE-1; if (cpu_unit.flags & OPTION_TIMER) { sim_rtcn_init_unit (&cpu_unit, cpu_unit.wait, TMR_RTC); sim_activate(&cpu_unit, cpu_unit.wait);