diff --git a/I7000/README.md b/I7000/README.md index 16a901ff..60841c2a 100644 --- a/I7000/README.md +++ b/I7000/README.md @@ -6,7 +6,7 @@ Latest status for I7000 Cpus: ## i704 * SAP works. - * Fort2 unfinished. + * Fort2 working. ## i7010 * PR155 works. diff --git a/I7000/i7000_cdp.c b/I7000/i7000_cdp.c index e471ccea..b664360e 100644 --- a/I7000/i7000_cdp.c +++ b/I7000/i7000_cdp.c @@ -87,7 +87,7 @@ 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, - &cdp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, + &cdp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug, NULL, NULL, &cdp_help, NULL, NULL, &cdp_description }; @@ -189,6 +189,8 @@ t_stat cdp_srv(UNIT *uptr) { int chan = UNIT_G_CHAN(uptr->flags); int u = (uptr - cdp_unit); + uint16 *image = (uint16 *)(uptr->up7); + /* Waiting for disconnect */ if (uptr->u5 & URCSTA_WDISCO) { if (chan_stat(chan, DEV_DISCO)) { @@ -208,20 +210,22 @@ cdp_srv(UNIT *uptr) { /* Done waiting, punch card */ if (uptr->u5 & URCSTA_FULL) { #ifdef STACK_DEV - switch(sim_punch_card(uptr, - &stack_unit[(u * 10) + ((uptr->u5 >> 16) & 0xf)])) { + UNIT *sptr = &stack_unit[(u * 10) + ((uptr->u5 >> 16) & 0xf)]; + if ((uptr->flags & UNIT_ATT) != 0 || (sptr->flags & UNIT_ATT) == 0) + sptr = uptr; + switch(sim_punch_card(sptr, image)) { #else - switch(sim_punch_card(uptr, NULL)) { + switch(sim_punch_card(uptr, image)) { #endif - case SCPE_EOF: - case SCPE_UNATT: + case CDSE_EOF: + case CDSE_EMPTY: chan_set_eof(chan); break; /* If we get here, something is wrong */ - case SCPE_IOERR: + case CDSE_ERROR: chan_set_error(chan); break; - case SCPE_OK: + case CDSE_OK: break; } uptr->u5 &= ~URCSTA_FULL; @@ -240,11 +244,8 @@ cdp_srv(UNIT *uptr) { /* Copy next column over */ if (uptr->u5 & URCSTA_WRITE && uptr->u4 < 80) { - struct _card_data *data; uint8 ch = 0; - data = (struct _card_data *)uptr->up7; - switch(chan_read_char(chan, &ch, 0)) { case TIME_ERROR: case END_RECORD: @@ -257,7 +258,7 @@ cdp_srv(UNIT *uptr) { 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); + 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; @@ -278,24 +279,35 @@ cdp_ini(UNIT *uptr, t_bool f) { t_stat cdp_attach(UNIT * uptr, CONST char *file) { - t_stat r; + t_stat r; if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u5 = 0; + if (uptr->up7 == 0) { + uptr->up7 = calloc(80, sizeof(uint16)); + uptr->u5 = 0; + } return SCPE_OK; } t_stat cdp_detach(UNIT * uptr) { - if (uptr->u5 & URCSTA_FULL) + uint16 *image = (uint16 *)(uptr->up7); + + if (uptr->u5 & URCSTA_FULL) { #ifdef STACK_DEV - sim_punch_card(uptr, &stack_unit[ - ((uptr - cdp_unit) * 10) + ((uptr->u5 >> 16) & 0xf)]); + UNIT *sptr = &stack_unit[((uptr - cdp_unit) * 10) + ((uptr->u5 >> 16) & 0xf)]; + if ((uptr->flags & UNIT_ATT) != 0 || (sptr->flags & UNIT_ATT) == 0) + sptr = uptr; + sim_punch_card(sptr, image); #else - sim_punch_card(uptr, NULL); + sim_punch_card(uptr, image); #endif + } + if (uptr->up7 == 0) + free(uptr->up7); + uptr->up7 = 0; return sim_card_detach(uptr); } diff --git a/I7000/i7000_cdr.c b/I7000/i7000_cdr.c index a7d5f966..39c355f2 100644 --- a/I7000/i7000_cdr.c +++ b/I7000/i7000_cdr.c @@ -90,8 +90,8 @@ MTAB cdr_mod[] = { DEVICE cdr_dev = { "CDR", cdr_unit, NULL, cdr_mod, NUM_DEVS_CDR, 8, 15, 1, 8, 8, - NULL, NULL, NULL, &cdr_boot, &cdr_attach, &sim_card_detach, - &cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, + NULL, NULL, NULL, &cdr_boot, &cdr_attach, &cdr_detach, + &cdr_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug, NULL, NULL, &cdr_help, NULL, NULL, &cdr_description }; @@ -168,9 +168,7 @@ t_stat cdr_srv(UNIT *uptr) { int chan = UNIT_G_CHAN(uptr->flags); int u = (uptr - cdr_unit); - struct _card_data *data; - - data = (struct _card_data *)uptr->up7; + uint16 *image = (uint16 *)(uptr->up7); /* Waiting for disconnect */ if (uptr->u5 & URCSTA_WDISCO) { @@ -200,26 +198,26 @@ cdr_srv(UNIT *uptr) { /* Check if new card requested. */ if (uptr->u4 == 0 && uptr->u5 & URCSTA_READ && (uptr->u5 & URCSTA_CARD) == 0) { - switch(sim_read_card(uptr)) { - case SCPE_EOF: + switch(sim_read_card(uptr, image)) { + case CDSE_EOF: sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: EOF\n", u); /* Fall through */ - case SCPE_UNATT: + case CDSE_EMPTY: chan_set_eof(chan); chan_set_attn(chan); chan_clear(chan, DEV_SEL); uptr->u5 |= URCSTA_EOF; uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ); return SCPE_OK; - case SCPE_IOERR: + case CDSE_ERROR: sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: ERF\n", u); uptr->u5 |= URCSTA_ERR; uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ); chan_set_attn(chan); chan_clear(chan, DEV_SEL); return SCPE_OK; - case SCPE_OK: + case CDSE_OK: uptr->u5 |= URCSTA_CARD; #ifdef I7010 chan_set_attn_urec(chan, cdr_dib.addr); @@ -228,7 +226,7 @@ cdr_srv(UNIT *uptr) { } #ifdef I7070 /* Check if load card. */ - if (uptr->capac && (data->image[uptr->capac-1] & 0x800)) { + if (uptr->capac && (image[uptr->capac-1] & 0x800)) { uptr->u5 |= URCSTA_LOAD; chan_set_load_mode(chan); } else { @@ -248,7 +246,7 @@ cdr_srv(UNIT *uptr) { #ifdef I7080 /* Detect RSU */ - if (data->image[uptr->u4] == 0x924) { + if (image[uptr->u4] == 0x924) { uptr->u5 &= ~URCSTA_READ; uptr->u5 |= URCSTA_WDISCO; chan_set(chan, DEV_REOR); @@ -257,7 +255,7 @@ cdr_srv(UNIT *uptr) { } #endif - ch = sim_hol_to_bcd(data->image[uptr->u4]); + ch = sim_hol_to_bcd(image[uptr->u4]); /* Handle invalid punch */ if (ch == 0x7f) { @@ -320,14 +318,31 @@ cdr_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u5 &= URCSTA_BUSY|URCSTA_WDISCO; - uptr->u4 = 0; - uptr->u6 = 0; + if (uptr->up7 == 0) { + uptr->up7 = malloc(sizeof(uint16)*80); + uptr->u5 &= URCSTA_BUSY|URCSTA_WDISCO; + uptr->u4 = 0; + uptr->u6 = 0; + } #ifdef I7010 chan_set_attn_urec(UNIT_G_CHAN(uptr->flags), cdr_dib.addr); #endif return SCPE_OK; } + +t_stat +cdr_detach(UNIT * uptr) +{ + t_stat r; + + if ((r = sim_card_detach(uptr)) != SCPE_OK) + return r; + if (uptr->up7 != 0) + free(uptr->up7); + uptr->up7 = 0; + return SCPE_OK; +} + #ifdef I7070 t_stat cdr_setload(UNIT *uptr, int32 val, CONST char *cptr, void *desc) diff --git a/I7000/i7000_ht.c b/I7000/i7000_ht.c index 69743ed0..7e3cd0cf 100644 --- a/I7000/i7000_ht.c +++ b/I7000/i7000_ht.c @@ -202,7 +202,7 @@ DEVICE hta_dev = { "HTA", hta_unit, NULL, ht_mod, NUM_UNITS_HT + 1, 8, 15, 1, 8, 8, NULL, NULL, &ht_reset, &ht_boot, &ht_attach, &ht_detach, - &ht_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &ht_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &ht_help, NULL, NULL, &ht_description }; @@ -211,7 +211,7 @@ DEVICE htb_dev = { "HTB", &hta_unit[NUM_UNITS_HT + 1], NULL, ht_mod, NUM_UNITS_HT + 1, 8, 15, 1, 8, 8, NULL, NULL, &ht_reset, &ht_boot, &ht_attach, &ht_detach, - &ht_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &ht_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &ht_help, NULL, NULL, &ht_description }; #endif @@ -959,7 +959,7 @@ ht_attach(UNIT * uptr, CONST char *file) { t_stat r; - if ((r = sim_tape_attach(uptr, file)) != SCPE_OK) + if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK) return r; uptr->u5 = HT_BOT /*|HT_ATTN */ ; return SCPE_OK; diff --git a/I7000/i7000_mt.c b/I7000/i7000_mt.c index a9f4244a..d35ca979 100644 --- a/I7000/i7000_mt.c +++ b/I7000/i7000_mt.c @@ -273,7 +273,7 @@ DEVICE mtz_dev = { "MT", &mta_unit[NUM_DEVS_MT * 10], NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(NUM_DEVS_MT) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(NUM_DEVS_MT) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; #endif @@ -283,7 +283,7 @@ DEVICE mta_dev = { "MTA", mta_unit, NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(0) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; @@ -292,7 +292,7 @@ DEVICE mtb_dev = { "MTB", &mta_unit[10], NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(1) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; @@ -301,7 +301,7 @@ DEVICE mtc_dev = { "MTC", &mta_unit[20], NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(2) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(2) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; @@ -310,7 +310,7 @@ DEVICE mtd_dev = { "MTD", &mta_unit[30], NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 36, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(3) | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(3) | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; @@ -319,7 +319,7 @@ DEVICE mte_dev = { "MTE", &mta_unit[40], NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(4) | DEV_DIS | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(4) | DEV_DIS | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; @@ -328,7 +328,7 @@ DEVICE mtf_dev = { "MTF", &mta_unit[50], NULL, mt_mod, NUM_UNITS_MT, 8, 15, 1, 8, 8, NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, - &mt_dib, DEV_BUF_NUM(5) | DEV_DIS | DEV_DISABLE | DEV_DEBUG, 0, dev_debug, + &mt_dib, DEV_BUF_NUM(5) | DEV_DIS | DEV_DISABLE | DEV_DEBUG | DEV_TAPE, 0, dev_debug, NULL, NULL, &mt_help, NULL, NULL, &mt_description }; #endif @@ -510,7 +510,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev) return SCPE_IOERR; } uptr->u5 |= MT_WEF; -#if I7010 +#if I7010 chan_set_sel(chan, 1); chan_clear_status(chan); mt_chan[chan] = MTC_BSY | MTC_SEL | unit; @@ -743,7 +743,7 @@ 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_test(chan, DEV_DISCO)) { uptr->u5 &= ~MT_CMDMSK; reclen = uptr->hwmark; if (cmd == MT_WRS || cmd == MT_WRSB) { @@ -757,16 +757,16 @@ t_stat mt_srv(UNIT * uptr) } } else if (cmd == MT_RDS || cmd == MT_RDSB) { sim_debug(DEBUG_DETAIL, dptr, - "Read flush unit=%d %s Block %d chars\n", - unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen); + "Read flush unit=%d %s at %d Block %d chars\n", + unit, (cmd == MT_RDS) ? "BCD" : "Binary", uptr->u6, reclen); /* Keep moving until end of block */ - if (uptr->u6 < (int32)uptr->hwmark ) { + if (uptr->u6 < (int32)reclen ) { 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); + chan_clear(chan, DEV_WEOR ); sim_activate(uptr, reclen * T1_us); return SCPE_OK; } else { @@ -811,7 +811,7 @@ t_stat mt_srv(UNIT * uptr) #else chan_clear(chan, DEV_SEL|STA_TWAIT); #endif - mt_chan[chan] = 0; + 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)); @@ -879,6 +879,7 @@ t_stat mt_srv(UNIT * uptr) chan_set_error(chan); } #else + chan_set(chan, DEV_REOR); chan_set_attn(chan); #endif } @@ -891,7 +892,7 @@ t_stat mt_srv(UNIT * uptr) 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) + if (mode && mt_buffer[bufnum][0] == 017) chan_set_eof(chan); #endif @@ -944,7 +945,7 @@ t_stat mt_srv(UNIT * uptr) sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us); uptr->u3 += (uptr->hwmark - uptr->u6); uptr->u6 = uptr->hwmark; /* Force read next record */ - } + } sim_activate(uptr, T1_us); break; @@ -1057,6 +1058,7 @@ t_stat mt_srv(UNIT * uptr) r = MTSE_OK; } else { sim_debug(DEBUG_DETAIL, dptr, "error=%d\n", r); + uptr->u6 = uptr->hwmark; uptr->u5 &= ~MT_CMDMSK; chan_set_attn(chan); chan_clear(chan, DEV_SEL); @@ -1354,7 +1356,7 @@ mt_attach(UNIT * uptr, CONST char *file) { t_stat r; - if ((r = sim_tape_attach(uptr, file)) != SCPE_OK) + if ((r = sim_tape_attach_ex(uptr, file, 0, 0)) != SCPE_OK) return r; uptr->u3 = 0; uptr->u5 |= MT_RDY; diff --git a/I7000/i7080_chan.c b/I7000/i7080_chan.c index 71504542..e60baff1 100644 --- a/I7000/i7080_chan.c +++ b/I7000/i7080_chan.c @@ -57,7 +57,7 @@ extern uint16 iotraps; extern uint8 iocheck; extern UNIT cpu_unit; extern uint16 IC; -extern uint8 AC[5 * 512]; +extern uint8 AC[6 * 512]; extern int chwait; extern uint16 selreg; extern uint16 selreg2; diff --git a/I7000/i7090_cdp.c b/I7000/i7090_cdp.c index 86826723..c0cae9f9 100644 --- a/I7000/i7090_cdp.c +++ b/I7000/i7090_cdp.c @@ -77,7 +77,7 @@ DEVICE cdp_dev = { "CDP", cdp_unit, NULL, cdp_mod, NUM_DEVS_CDP, 8, 15, 1, 8, 36, NULL, NULL, &cdp_reset, NULL, &cdp_attach, &cdp_detach, - &cdp_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, + &cdp_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug, NULL, NULL, &cdp_help, NULL, NULL, &cdp_description }; @@ -121,19 +121,19 @@ t_stat cdp_srv(UNIT * uptr) { int chan = UNIT_G_CHAN(uptr->flags); int u = (uptr - cdp_unit); + uint16 *image = (uint16 *)(uptr->up7); int pos; t_uint64 wd; int bit; t_uint64 mask; int b; int col; - struct _card_data *data; /* Channel has disconnected, abort current card. */ if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) { if ((uptr->u5 & CDPSTA_POSMASK) != 0) { sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n"); - sim_punch_card(uptr, NULL); + sim_punch_card(uptr, image); uptr->u5 &= ~CDPSTA_PUNCH; } uptr->u5 &= ~(URCSTA_WRITE | URCSTA_CMD | CDPSTA_POSMASK); @@ -189,7 +189,7 @@ t_stat cdp_srv(UNIT * uptr) sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u); } sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card full\n"); - sim_punch_card(uptr, NULL); + sim_punch_card(uptr, image); uptr->u5 |= URCSTA_IDLE; uptr->u5 &= ~(URCSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH); uptr->wait = 85; @@ -201,7 +201,6 @@ t_stat cdp_srv(UNIT * uptr) sim_debug(DEBUG_DATA, &cdp_dev, "unit=%d write column %d ", u, pos); wd = 0; - data = (struct _card_data *)uptr->up7; switch (chan_read(chan, &wd, 0)) { case DATA_OK: sim_debug(DEBUG_DATA, &cdp_dev, " %012llo\n", wd); @@ -212,7 +211,7 @@ t_stat cdp_srv(UNIT * uptr) for (col = 35; col >= 0; mask <<= 1, col--) { if (wd & mask) - data->image[col + b] |= bit; + image[col + b] |= bit; } pos++; uptr->wait = 0; @@ -258,13 +257,19 @@ cdp_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u5 = CDPSTA_POSMASK; + if (uptr->up7 == 0) { + uptr->up7 = calloc(80, sizeof(uint16)); + uptr->u5 = CDPSTA_POSMASK; + } return SCPE_OK; } t_stat cdp_detach(UNIT * uptr) { + if (uptr->up7 != 0) + free(uptr->up7); + uptr->up7 = 0; return sim_card_detach(uptr); } diff --git a/I7000/i7090_cdr.c b/I7000/i7090_cdr.c index 493b5d83..a72f1506 100644 --- a/I7000/i7090_cdr.c +++ b/I7000/i7090_cdr.c @@ -81,7 +81,7 @@ DEVICE cdr_dev = { "CDR", cdr_unit, NULL, cdr_mod, NUM_DEVS_CDR, 8, 15, 1, 8, 36, NULL, NULL, &cdr_reset, &cdr_boot, &cdr_attach, &cdr_detach, - &cdr_dib, DEV_DISABLE | DEV_DEBUG, 0, crd_debug, + &cdr_dib, DEV_DISABLE | DEV_DEBUG | DEV_CARD, 0, crd_debug, NULL, NULL, &cdr_help, NULL, NULL, &cdr_description }; @@ -118,9 +118,9 @@ t_stat cdr_srv(UNIT * uptr) int chan = UNIT_G_CHAN(uptr->flags); int u = (uptr - cdr_unit); int pos, col, b; + uint16 *image = (uint16 *)(uptr->up7); uint16 bit; t_uint64 mask, wd; - struct _card_data *data; /* Channel has disconnected, abort current read. */ if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) { @@ -163,23 +163,23 @@ t_stat cdr_srv(UNIT * uptr) pos = (uptr->u5 & CDRPOSMASK) >> CDRPOSSHIFT; if (pos == (CDRPOSMASK >> CDRPOSSHIFT)) { - switch (sim_read_card(uptr)) { - case SCPE_UNATT: - case SCPE_IOERR: + switch (sim_read_card(uptr, image)) { + case CDSE_EMPTY: + case CDSE_ERROR: sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d Setting ATTN\n", u); chan_set_error(chan); chan_set_attn(chan); uptr->u5 &= ~URCSTA_READ; sim_activate(uptr, us_to_ticks(1000)); return SCPE_OK; - case SCPE_EOF: + case CDSE_EOF: sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d EOF\n", u); chan_set_eof(chan); chan_set_attn(chan); uptr->u5 &= ~URCSTA_READ; sim_activate(uptr, us_to_ticks(1000)); return SCPE_OK; - case SCPE_OK: + case CDSE_OK: break; } pos = 0; @@ -196,7 +196,6 @@ t_stat cdr_srv(UNIT * uptr) return SCPE_OK; } - data = (struct _card_data *)uptr->up7; /* Bit flip into read buffer */ bit = 1 << (pos / 2); mask = 1; @@ -204,7 +203,7 @@ t_stat cdr_srv(UNIT * uptr) b = (pos & 1)?36:0; for (col = 35; col >= 0; mask <<= 1) { - if (data->image[col-- + b] & bit) + if (image[col-- + b] & bit) wd |= mask; } @@ -246,7 +245,7 @@ cdr_boot(int32 unit_num, DEVICE * dptr) int chan = UNIT_G_CHAN(uptr->flags); t_stat r; int pos; - struct _card_data *data; + uint16 *image = (uint16 *)(uptr->up7); if ((uptr->flags & UNIT_ATT) == 0) return SCPE_UNATT; /* attached? */ @@ -254,12 +253,11 @@ cdr_boot(int32 unit_num, DEVICE * dptr) /* Init for a read */ if (cdr_cmd(uptr, IO_RDS, cdr_dib.addr) != SCPE_OK) return STOP_IONRDY; - r = sim_read_card(uptr); + r = sim_read_card(uptr, image); if (r != SCPE_OK) return r; /* Copy first three records. */ - data = (struct _card_data *)uptr->up7; uptr->u5 &= ~CDRPOSMASK; for(pos = 0; pos <3; pos++) { uint16 bit = 1 << (pos / 2); @@ -271,7 +269,7 @@ cdr_boot(int32 unit_num, DEVICE * dptr) break; M[pos] = 0; for (col = 35; col >= 0; mask <<= 1) { - if (data->image[col-- + b] & bit) + if (image[col-- + b] & bit) M[pos] |= mask; } sim_debug(DEBUG_DATA, &cdr_dev, "boot read row %d %012llo\n", @@ -295,14 +293,20 @@ cdr_attach(UNIT * uptr, CONST char *file) if ((r = sim_card_attach(uptr, file)) != SCPE_OK) return r; - uptr->u5 = 0; - uptr->u4 = 0; + if (uptr->up7 == 0) { + uptr->up7 = malloc(sizeof(uint16)*80); + uptr->u5 = 0; + uptr->u4 = 0; + } return SCPE_OK; } t_stat cdr_detach(UNIT * uptr) { + if (uptr->up7 != 0) + free(uptr->up7); + uptr->up7 = 0; return sim_card_detach(uptr); } diff --git a/I7000/i7090_chan.c b/I7000/i7090_chan.c index 3daf25ea..575188c2 100644 --- a/I7000/i7090_chan.c +++ b/I7000/i7090_chan.c @@ -55,7 +55,7 @@ extern UNIT cpu_unit; extern uint16 IC; extern t_uint64 MQ; extern uint32 drum_addr; -extern uint32 hsdrm_addr; +extern t_uint64 hsdrm_addr; t_stat chan_reset(DEVICE * dptr); void chan_fetch(int chan); @@ -344,10 +344,6 @@ chan_proc() cmask = 0x0100 << chan; switch (CHAN_G_TYPE(chan_unit[chan].flags)) { case CHAN_PIO: - if (chan_flags[chan] & CHS_ATTN) { - chan_flags[chan] &= - ~(CHS_ATTN | STA_START | STA_ACTIVE | STA_WAIT); - } if ((chan_flags[chan] & (DEV_REOR|DEV_SEL|DEV_FULL)) == (DEV_SEL|DEV_REOR)) { sim_debug(DEBUG_DETAIL, &chan_dev, "chan got EOR\n"); @@ -360,10 +356,10 @@ chan_proc() /* On first command, copy it to drum address and load another */ if ((chan_info[chan] & (CHAINF_RUN | CHAINF_START)) == CHAINF_START) { - hsdrm_addr = (int)M[location[chan] - 1]; + hsdrm_addr = M[location[chan] - 1]; chan_info[chan] |= CHAINF_RUN; if (chan_dev.dctrl & cmask) - sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d HDaddr %06o\n", + sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d HDaddr %012llo\n", chan, hsdrm_addr); chan_fetch(chan); continue; @@ -399,7 +395,6 @@ chan_proc() iotraps |= 1 << chan; break; } - iotraps |= 1LL << (chan + 18); if (chan_dev.dctrl & cmask) sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d attn< %o\n", chan, cmd[chan] & 070); @@ -500,9 +495,8 @@ chan_proc() chan_flags[chan] |= DEV_DISCO | DEV_WEOR; chan_flags[chan] &= ~(STA_START | STA_ACTIVE | STA_PEND); - if (CHAN_G_TYPE(chan_unit[chan].flags) == - CHAN_7289) { - iotraps |= 1 << chan; + if (CHAN_G_TYPE(chan_unit[chan].flags) == CHAN_7289) { + iotraps |= 1 << chan; sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap\n", chan); } @@ -845,8 +839,8 @@ chan_proc() case SCPE_NODEV: chan9_set_error(chan, SNS_IOCHECK); iotraps |= 1 << chan; - chan_flags[chan] &= - ~(CTL_PREAD|CTL_PWRITE|CTL_SNS|CTL_CNTL|STA_ACTIVE); + chan_flags[chan] &= ~(CTL_PREAD|CTL_PWRITE|CTL_SNS| + CTL_CNTL|STA_ACTIVE); continue; case SCPE_BUSY: /* Device not ready yet, wait */ continue; @@ -1266,8 +1260,10 @@ chan_cmd(uint16 dev, uint16 dcmd) if ((chan_flags[chan] & (DEV_FULL|DEV_WRITE)) == (DEV_FULL|DEV_WRITE)) return SCPE_BUSY; /* Yes, disconnect device and tell it to write a EOR */ - chan_flags[chan] |= DEV_DISCO | DEV_WEOR; - return SCPE_BUSY; + if ((chan_flags[chan] & (DEV_WRITE)) == (DEV_WRITE) || + (chan_flags[chan] & (DEV_FULL)) == (DEV_FULL)) + chan_flags[chan] |= DEV_DISCO | DEV_WEOR; + return SCPE_BUSY; } /* Unit is busy doing something, wait */ if (chan_flags[chan] & (DEV_SEL | DEV_DISCO | STA_TWAIT | STA_WAIT)) diff --git a/I7000/i7090_cpu.c b/I7000/i7090_cpu.c index 615c5ea6..e47547a4 100644 --- a/I7000/i7090_cpu.c +++ b/I7000/i7090_cpu.c @@ -187,7 +187,7 @@ #define HIST_INT 2 /* interrupt cycle */ #define HIST_TRP 3 /* trap cycle */ #define HIST_MIN 64 -#define HIST_MAX 10000 +#define HIST_MAX 1000000 #define HIST_NOEA 0x40000000 #define HIST_PC 0x10000 @@ -299,8 +299,13 @@ extern uint32 drum_addr; */ UNIT cpu_unit = +#ifdef I7090 { UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_7090) | MEMAMOUNT(4), MAXMEMSIZE/2 ), 120 }; +#else + { UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_704) | MEMAMOUNT(4), + MAXMEMSIZE/2 ), 120 }; +#endif REG cpu_reg[] = { {ORDATAD(IC, IC, 15, "Instruction Counter"), REG_FIT}, @@ -724,7 +729,6 @@ sim_instr(void) int xeccnt = 15; int shiftcnt; int stopnext = 0; - int first_rdwr = 0; int instr_count = 0; /* Number of instructions to execute */ if (sim_step != 0) { @@ -734,7 +738,7 @@ sim_instr(void) /* Set cycle time for delays */ switch(CPU_MODEL) { - case CPU_704: + case CPU_704: cycle_time = 50; break; /* Needed to allow SAP to work */ case CPU_709: cycle_time = 120; break; /* 83,333 cycles per second */ default: case CPU_7090: cycle_time = 22; break; /* 454,545 cycles per second */ @@ -758,6 +762,7 @@ sim_instr(void) tbase |= CORE_B; iowait = 0; + ihold = 0; while (reason == 0) { /* loop until halted */ if (exe_KEYS) { @@ -767,9 +772,7 @@ sim_instr(void) goto next_xec; } -#ifdef I7090 /* I704 did not have interrupts */ hltloop: -#endif /* If doing fast I/O don't sit in idle loop */ if (iowait && (cpu_unit.flags & UNIT_FASTIO)) sim_interval = 0; @@ -799,7 +802,6 @@ sim_instr(void) } #endif - if (iowait == 0 && sim_brk_summ && sim_brk_test(((bcore & 2)? CORE_B:0)|IC, SWMASK('E'))) { reason = STOP_IBKPT; @@ -808,7 +810,7 @@ sim_instr(void) /* Check if we need to take any traps */ #ifdef I7090 /* I704 did not have interrupts */ - if (itrap && ihold == 0 && iowait == 0 && ioflags != 0) { + if (CPU_MODEL != CPU_704 && itrap && ihold == 0 && iowait == 0 && ioflags != 0 && instr_count == 0) { t_uint64 mask = 00000001000001LL; MA = 012; @@ -832,9 +834,13 @@ sim_instr(void) /* check if we need to perform a trap */ if (f) { /* HTR/HPR behave like wait if protected */ + if (hltinst) + temp = (((t_uint64) bcore & 3) << 31) | + (((t_uint64) f) << 18) | (fptemp & memmask); + else + temp = (((t_uint64) bcore & 3) << 31) | + (((t_uint64) f) << 18) | (IC & memmask); hltinst = 0; - temp = (((t_uint64) bcore & 3) << 31) | - (((t_uint64) f) << 18) | (IC & memmask); sim_interval = sim_interval - 1; /* count down */ WriteP(MA, temp); if (nmode) { @@ -849,8 +855,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\n", - shiftcnt + 'A' - 1, f, temp, MA, SR); + "Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o\n", + shiftcnt + 'A' - 1, f, temp, MA, SR, IC); if (hst_lnt) { /* history enabled? */ hst_p = (hst_p + 1); /* next entry */ if (hst_p >= hst_lnt) @@ -875,9 +881,13 @@ sim_instr(void) /* Interval timer has lower priority then I/O traps */ if (interval_irq && (ioflags & 0400000)) { /* HTR/HPR behave like wait if protected */ + if (hltinst) + temp = (((t_uint64) bcore & 3) << 31) | + (fptemp & memmask) | (relo_mode << 21); + else + temp = (((t_uint64) bcore & 3) << 31) | + (IC & memmask) | (relo_mode << 21); hltinst = 0; - temp = (((t_uint64) bcore & 3) << 31) | (IC & memmask) | - (relo_mode << 21); sim_interval = sim_interval - 1; /* count down */ MA = 6; WriteP(MA, temp); @@ -915,27 +925,20 @@ sim_instr(void) if (hltinst) { t_uint64 mask = 00000001000001LL; - if (CPU_MODEL == CPU_704) { - reason = STOP_HALT; - break; - } /* Hold out until all channels have idled out */ - sim_interval = 0; - (void)sim_process_event(); + sim_interval = sim_interval - 1; /* count down */ chan_proc(); f = chan_active(0); - for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) { - f |= chan_active(shiftcnt); + for (shiftcnt = 1; f == 0 && shiftcnt < NUM_CHAN; shiftcnt++) { + f = chan_active(shiftcnt); /* CRC *//* Trap *//* EOF */ - /* Wait until channel stops to trigger interupts */ - if (ioflags & mask) { - if (mask & AMASK & ioflags) { - if (chan_stat(shiftcnt, CHS_EOF)) - f = 1; /* We have a EOF */ - if (iotraps & (1 << shiftcnt)) - f = 1; /* We have a IOCT/IORT/IOST */ - } - if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR)) + /* Wait until channel stops to trigger interrupts */ + if (itrap) { + /* Check for EOF or IOCT/IORT/IOST */ + if (mask & AMASK & ioflags && + (chan_test(shiftcnt, CHS_EOF) || iotraps & (1 << shiftcnt))) + f = 1; + if (mask & DMASK & ioflags && chan_test(shiftcnt, CHS_ERR)) f = 1; /* We have device error */ } } @@ -949,6 +952,10 @@ sim_instr(void) } #else /* Handle halt on 704 */ if (hltinst) { + sim_interval = sim_interval - 1; /* count down */ + chan_proc(); + if (chan_active(0)) + goto hltloop; reason = STOP_HALT; break; } @@ -989,6 +996,8 @@ sim_instr(void) relo_pend = 0; prot_pend = 0; } + + next_xec: opcode = (uint16)(SR >> 24); IR = opcode; @@ -1314,9 +1323,9 @@ prottrap: break; #ifdef I7090 /* Not on 704 */ case OP_RCT: - if (bcore & 4) - goto prottrap; if (CPU_MODEL != CPU_704) { + if (bcore & 4) + goto prottrap; sim_debug(DEBUG_TRAP, &cpu_dev, "RCT %012llo\n", ioflags); if ((bcore & 4) || STM) goto seltrap; @@ -1471,8 +1480,12 @@ prottrap: case OP_HPR: halt: hltinst = 1; - if (opcode == OP_HTR) + ihold = 0; /* Kill any hold on traps now */ + if (opcode == OP_HTR) { + fptemp = IC-1; IC = MA; + } else + fptemp = IC; break; case OP_XEC: opcode = (uint16)(SR >> 24); @@ -3246,10 +3259,9 @@ prottrap: case OP_LDA: if (chan_select(0)) { extern DEVICE drm_dev; - drum_addr = (uint32)(MQ = SR); + drum_addr = (uint32)(SR); sim_debug(DEBUG_DETAIL, &drm_dev, "set address %06o\n", drum_addr); - MQ <<= 1; chan_clear(0, DEV_FULL); /* In case we read something before we got here */ } else @@ -3324,49 +3336,38 @@ prottrap: /* Input/Output Instuctions */ case OP_ENB: ioflags = SR; - itrap = 1; + if (SR) + itrap = 1; + else + itrap = 0; + sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo\n", ioflags); ihold = 1; - /* * IBSYS can't have an trap right after ENB or it will hang * on a TTR * in IBNUC. */ if (CPU_MODEL >= CPU_7090) break; - - /* Don't wait if EOF or Error is pending but hold if trap */ temp = 00000001000001LL; + for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) { - if (chan_active(shiftcnt) == 0) { - if (temp & ioflags & AMASK && - iotraps & 1 << shiftcnt) - break; - if ((temp & ioflags & AMASK && - chan_test(shiftcnt, CHS_EOF)) || - (temp & ioflags & DMASK && - chan_test(shiftcnt, CHS_ERR))) { - ihold = 0; - break; - } - } + if ((temp & ioflags & DMASK) == 0) + chan_clear(shiftcnt, CHS_ERR); + else if (chan_test(shiftcnt,CHS_ERR)) + ihold = 0; + if ((temp & ioflags & AMASK) == 0) + chan_clear(shiftcnt, CHS_EOF); + else if (chan_test(shiftcnt,CHS_EOF)) + ihold = 0; temp <<= 1; } break; #endif case OP_RDS: /* Read select */ - if (CPU_MODEL == CPU_704) - MQ = 0; - else if (first_rdwr == 0) { - iotraps &= ~(1 << ((MA >> 9) & 017)); - first_rdwr = 1; - } opcode = IO_RDS; goto docmd; case OP_WRS: /* Write select */ - if (CPU_MODEL != CPU_704 && first_rdwr == 0) { - first_rdwr = 1; - } opcode = IO_WRS; goto docmd; case OP_WEF: /* Write EOF */ @@ -3395,12 +3396,16 @@ prottrap: iowait = 1; /* Channel is active, hold */ break; case SCPE_OK: + if (((MA >> 9) & 017) == 0) { + if (opcode==IO_RDS) + MQ = 0; + chan_clear(0, CHS_EOF|CHS_EOT|DEV_REOR); + } ihold = 1; /* Hold interupts for one cycle */ - first_rdwr = 0; + iotraps &= ~(1 << ((MA >> 9) & 017)); break; case SCPE_IOERR: iocheck = 1; - first_rdwr = 0; break; case SCPE_NODEV: reason = STOP_IOCHECK; @@ -3426,6 +3431,7 @@ prottrap: #ifdef I7090 /* Not on 704 */ case OP_TRCA: /* Transfer on Redundancy check */ + ihold = 2; if ((1LL << 18) & ioflags) break; f = chan_stat(1, CHS_ERR); @@ -3468,6 +3474,7 @@ prottrap: #endif case OP_TEFA: /* Transfer on channel EOF */ + ihold = 2; if ((1LL << 0) & ioflags) break; f = chan_stat(1, CHS_EOF); diff --git a/I7000/i7090_drum.c b/I7000/i7090_drum.c index a80a972e..3af9d85b 100644 --- a/I7000/i7090_drum.c +++ b/I7000/i7090_drum.c @@ -109,7 +109,7 @@ uint32 drm_cmd(UNIT * uptr, uint16 cmd, uint16 dev) /* Choose which part to use */ uptr->u5 |= u << DRMSTA_UNITSHIFT; drum_addr = 0; /* Set drum address */ - chan_clear(chan, CHS_ATTN); /* Clear attentions */ + chan_clear_status(chan); /* Make sure drum is spinning */ sim_activate(uptr, us_to_ticks(100)); return SCPE_OK; diff --git a/I7000/i7090_sys.c b/I7000/i7090_sys.c index 41a2b07c..76b82078 100644 --- a/I7000/i7090_sys.c +++ b/I7000/i7090_sys.c @@ -110,7 +110,7 @@ DEVICE *sim_devices[] = { /* Device addressing words */ #ifdef NUM_DEVS_DR -DIB drm_dib = { CH_TYP_PIO, 1, 0301, 0740, &drm_cmd, &drm_ini }; +DIB drm_dib = { CH_TYP_PIO, 1, 0301, 0760, &drm_cmd, &drm_ini }; #endif #ifdef NUM_DEVS_CDP DIB cdp_dib = { CH_TYP_PIO|CH_TYP_76XX, 1, 0341, 0777, &cdp_cmd, &cdp_ini }; diff --git a/doc/i7010_doc.doc b/doc/i7010_doc.doc index 00c9c22b..9ab417dc 100644 Binary files a/doc/i7010_doc.doc and b/doc/i7010_doc.doc differ diff --git a/doc/i701_doc.doc b/doc/i701_doc.doc index 0790bd41..999d15bb 100644 Binary files a/doc/i701_doc.doc and b/doc/i701_doc.doc differ diff --git a/doc/i7070_doc.doc b/doc/i7070_doc.doc index a3508aff..be482102 100644 Binary files a/doc/i7070_doc.doc and b/doc/i7070_doc.doc differ diff --git a/doc/i7080_doc.doc b/doc/i7080_doc.doc index 564e0b61..5f4d309b 100644 Binary files a/doc/i7080_doc.doc and b/doc/i7080_doc.doc differ diff --git a/doc/i7090_doc.doc b/doc/i7090_doc.doc index d4559257..75c4ff05 100644 Binary files a/doc/i7090_doc.doc and b/doc/i7090_doc.doc differ