I7000: Second release of IBM 7000 simulators.

1) Support for new sim_card interface which supports stacking
     of input decks.
  2) Changes to allow IBM 704 to properly run Fortran II and allow
     i7090 to be set to IBM 704 correctly.
  3) Changes to allow 9IOTA diagnostics to pass.
This commit is contained in:
Richard Cornwell 2018-08-05 22:45:06 -04:00
parent b4d185f3af
commit 124ca0ea0f
17 changed files with 198 additions and 157 deletions

View file

@ -6,7 +6,7 @@ Latest status for I7000 Cpus:
## i704 ## i704
* SAP works. * SAP works.
* Fort2 unfinished. * Fort2 working.
## i7010 ## i7010
* PR155 works. * PR155 works.

View file

@ -87,7 +87,7 @@ DEVICE cdp_dev = {
"CDP", cdp_unit, NULL, cdp_mod, "CDP", cdp_unit, NULL, cdp_mod,
NUM_DEVS_CDP, 8, 15, 1, 8, 8, NUM_DEVS_CDP, 8, 15, 1, 8, 8,
NULL, NULL, NULL, NULL, &cdp_attach, &cdp_detach, 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 NULL, NULL, &cdp_help, NULL, NULL, &cdp_description
}; };
@ -189,6 +189,8 @@ t_stat
cdp_srv(UNIT *uptr) { cdp_srv(UNIT *uptr) {
int chan = UNIT_G_CHAN(uptr->flags); int chan = UNIT_G_CHAN(uptr->flags);
int u = (uptr - cdp_unit); int u = (uptr - cdp_unit);
uint16 *image = (uint16 *)(uptr->up7);
/* Waiting for disconnect */ /* Waiting for disconnect */
if (uptr->u5 & URCSTA_WDISCO) { if (uptr->u5 & URCSTA_WDISCO) {
if (chan_stat(chan, DEV_DISCO)) { if (chan_stat(chan, DEV_DISCO)) {
@ -208,20 +210,22 @@ cdp_srv(UNIT *uptr) {
/* Done waiting, punch card */ /* Done waiting, punch card */
if (uptr->u5 & URCSTA_FULL) { if (uptr->u5 & URCSTA_FULL) {
#ifdef STACK_DEV #ifdef STACK_DEV
switch(sim_punch_card(uptr, UNIT *sptr = &stack_unit[(u * 10) + ((uptr->u5 >> 16) & 0xf)];
&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 #else
switch(sim_punch_card(uptr, NULL)) { switch(sim_punch_card(uptr, image)) {
#endif #endif
case SCPE_EOF: case CDSE_EOF:
case SCPE_UNATT: case CDSE_EMPTY:
chan_set_eof(chan); chan_set_eof(chan);
break; break;
/* If we get here, something is wrong */ /* If we get here, something is wrong */
case SCPE_IOERR: case CDSE_ERROR:
chan_set_error(chan); chan_set_error(chan);
break; break;
case SCPE_OK: case CDSE_OK:
break; break;
} }
uptr->u5 &= ~URCSTA_FULL; uptr->u5 &= ~URCSTA_FULL;
@ -240,11 +244,8 @@ cdp_srv(UNIT *uptr) {
/* Copy next column over */ /* Copy next column over */
if (uptr->u5 & URCSTA_WRITE && uptr->u4 < 80) { if (uptr->u5 & URCSTA_WRITE && uptr->u4 < 80) {
struct _card_data *data;
uint8 ch = 0; uint8 ch = 0;
data = (struct _card_data *)uptr->up7;
switch(chan_read_char(chan, &ch, 0)) { switch(chan_read_char(chan, &ch, 0)) {
case TIME_ERROR: case TIME_ERROR:
case END_RECORD: case END_RECORD:
@ -257,7 +258,7 @@ cdp_srv(UNIT *uptr) {
else if (ch == 020) else if (ch == 020)
ch = 0; ch = 0;
sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch); 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) { if (uptr->u4 == 80) {
chan_set(chan, DEV_REOR); chan_set(chan, DEV_REOR);
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL; uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
@ -278,24 +279,35 @@ cdp_ini(UNIT *uptr, t_bool f) {
t_stat t_stat
cdp_attach(UNIT * uptr, CONST char *file) cdp_attach(UNIT * uptr, CONST char *file)
{ {
t_stat r; t_stat r;
if ((r = sim_card_attach(uptr, file)) != SCPE_OK) if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r; return r;
uptr->u5 = 0; if (uptr->up7 == 0) {
uptr->up7 = calloc(80, sizeof(uint16));
uptr->u5 = 0;
}
return SCPE_OK; return SCPE_OK;
} }
t_stat t_stat
cdp_detach(UNIT * uptr) cdp_detach(UNIT * uptr)
{ {
if (uptr->u5 & URCSTA_FULL) uint16 *image = (uint16 *)(uptr->up7);
if (uptr->u5 & URCSTA_FULL) {
#ifdef STACK_DEV #ifdef STACK_DEV
sim_punch_card(uptr, &stack_unit[ UNIT *sptr = &stack_unit[((uptr - cdp_unit) * 10) + ((uptr->u5 >> 16) & 0xf)];
((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 #else
sim_punch_card(uptr, NULL); sim_punch_card(uptr, image);
#endif #endif
}
if (uptr->up7 == 0)
free(uptr->up7);
uptr->up7 = 0;
return sim_card_detach(uptr); return sim_card_detach(uptr);
} }

View file

@ -90,8 +90,8 @@ MTAB cdr_mod[] = {
DEVICE cdr_dev = { DEVICE cdr_dev = {
"CDR", cdr_unit, NULL, cdr_mod, "CDR", cdr_unit, NULL, cdr_mod,
NUM_DEVS_CDR, 8, 15, 1, 8, 8, NUM_DEVS_CDR, 8, 15, 1, 8, 8,
NULL, NULL, NULL, &cdr_boot, &cdr_attach, &sim_card_detach, NULL, NULL, NULL, &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 NULL, NULL, &cdr_help, NULL, NULL, &cdr_description
}; };
@ -168,9 +168,7 @@ t_stat
cdr_srv(UNIT *uptr) { cdr_srv(UNIT *uptr) {
int chan = UNIT_G_CHAN(uptr->flags); int chan = UNIT_G_CHAN(uptr->flags);
int u = (uptr - cdr_unit); int u = (uptr - cdr_unit);
struct _card_data *data; uint16 *image = (uint16 *)(uptr->up7);
data = (struct _card_data *)uptr->up7;
/* Waiting for disconnect */ /* Waiting for disconnect */
if (uptr->u5 & URCSTA_WDISCO) { if (uptr->u5 & URCSTA_WDISCO) {
@ -200,26 +198,26 @@ cdr_srv(UNIT *uptr) {
/* Check if new card requested. */ /* Check if new card requested. */
if (uptr->u4 == 0 && uptr->u5 & URCSTA_READ && if (uptr->u4 == 0 && uptr->u5 & URCSTA_READ &&
(uptr->u5 & URCSTA_CARD) == 0) { (uptr->u5 & URCSTA_CARD) == 0) {
switch(sim_read_card(uptr)) { switch(sim_read_card(uptr, image)) {
case SCPE_EOF: case CDSE_EOF:
sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: EOF\n", u); sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: EOF\n", u);
/* Fall through */ /* Fall through */
case SCPE_UNATT: case CDSE_EMPTY:
chan_set_eof(chan); chan_set_eof(chan);
chan_set_attn(chan); chan_set_attn(chan);
chan_clear(chan, DEV_SEL); chan_clear(chan, DEV_SEL);
uptr->u5 |= URCSTA_EOF; uptr->u5 |= URCSTA_EOF;
uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ); uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
return SCPE_OK; return SCPE_OK;
case SCPE_IOERR: case CDSE_ERROR:
sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: ERF\n", u); sim_debug(DEBUG_DETAIL, &cdr_dev, "%d: ERF\n", u);
uptr->u5 |= URCSTA_ERR; uptr->u5 |= URCSTA_ERR;
uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ); uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
chan_set_attn(chan); chan_set_attn(chan);
chan_clear(chan, DEV_SEL); chan_clear(chan, DEV_SEL);
return SCPE_OK; return SCPE_OK;
case SCPE_OK: case CDSE_OK:
uptr->u5 |= URCSTA_CARD; uptr->u5 |= URCSTA_CARD;
#ifdef I7010 #ifdef I7010
chan_set_attn_urec(chan, cdr_dib.addr); chan_set_attn_urec(chan, cdr_dib.addr);
@ -228,7 +226,7 @@ cdr_srv(UNIT *uptr) {
} }
#ifdef I7070 #ifdef I7070
/* Check if load card. */ /* 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; uptr->u5 |= URCSTA_LOAD;
chan_set_load_mode(chan); chan_set_load_mode(chan);
} else { } else {
@ -248,7 +246,7 @@ cdr_srv(UNIT *uptr) {
#ifdef I7080 #ifdef I7080
/* Detect RSU */ /* Detect RSU */
if (data->image[uptr->u4] == 0x924) { if (image[uptr->u4] == 0x924) {
uptr->u5 &= ~URCSTA_READ; uptr->u5 &= ~URCSTA_READ;
uptr->u5 |= URCSTA_WDISCO; uptr->u5 |= URCSTA_WDISCO;
chan_set(chan, DEV_REOR); chan_set(chan, DEV_REOR);
@ -257,7 +255,7 @@ cdr_srv(UNIT *uptr) {
} }
#endif #endif
ch = sim_hol_to_bcd(data->image[uptr->u4]); ch = sim_hol_to_bcd(image[uptr->u4]);
/* Handle invalid punch */ /* Handle invalid punch */
if (ch == 0x7f) { if (ch == 0x7f) {
@ -320,14 +318,31 @@ cdr_attach(UNIT * uptr, CONST char *file)
if ((r = sim_card_attach(uptr, file)) != SCPE_OK) if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r; return r;
uptr->u5 &= URCSTA_BUSY|URCSTA_WDISCO; if (uptr->up7 == 0) {
uptr->u4 = 0; uptr->up7 = malloc(sizeof(uint16)*80);
uptr->u6 = 0; uptr->u5 &= URCSTA_BUSY|URCSTA_WDISCO;
uptr->u4 = 0;
uptr->u6 = 0;
}
#ifdef I7010 #ifdef I7010
chan_set_attn_urec(UNIT_G_CHAN(uptr->flags), cdr_dib.addr); chan_set_attn_urec(UNIT_G_CHAN(uptr->flags), cdr_dib.addr);
#endif #endif
return SCPE_OK; 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 #ifdef I7070
t_stat t_stat
cdr_setload(UNIT *uptr, int32 val, CONST char *cptr, void *desc) cdr_setload(UNIT *uptr, int32 val, CONST char *cptr, void *desc)

View file

@ -202,7 +202,7 @@ DEVICE hta_dev = {
"HTA", hta_unit, NULL, ht_mod, "HTA", hta_unit, NULL, ht_mod,
NUM_UNITS_HT + 1, 8, 15, 1, 8, 8, NUM_UNITS_HT + 1, 8, 15, 1, 8, 8,
NULL, NULL, &ht_reset, &ht_boot, &ht_attach, &ht_detach, 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 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, "HTB", &hta_unit[NUM_UNITS_HT + 1], NULL, ht_mod,
NUM_UNITS_HT + 1, 8, 15, 1, 8, 8, NUM_UNITS_HT + 1, 8, 15, 1, 8, 8,
NULL, NULL, &ht_reset, &ht_boot, &ht_attach, &ht_detach, 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 NULL, NULL, &ht_help, NULL, NULL, &ht_description
}; };
#endif #endif
@ -959,7 +959,7 @@ ht_attach(UNIT * uptr, CONST char *file)
{ {
t_stat r; 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; return r;
uptr->u5 = HT_BOT /*|HT_ATTN */ ; uptr->u5 = HT_BOT /*|HT_ATTN */ ;
return SCPE_OK; return SCPE_OK;

View file

@ -273,7 +273,7 @@ DEVICE mtz_dev = {
"MT", &mta_unit[NUM_DEVS_MT * 10], NULL, mt_mod, "MT", &mta_unit[NUM_DEVS_MT * 10], NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 8, NUM_UNITS_MT, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
#endif #endif
@ -283,7 +283,7 @@ DEVICE mta_dev = {
"MTA", mta_unit, NULL, mt_mod, "MTA", mta_unit, NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 8, NUM_UNITS_MT, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
@ -292,7 +292,7 @@ DEVICE mtb_dev = {
"MTB", &mta_unit[10], NULL, mt_mod, "MTB", &mta_unit[10], NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 8, NUM_UNITS_MT, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
@ -301,7 +301,7 @@ DEVICE mtc_dev = {
"MTC", &mta_unit[20], NULL, mt_mod, "MTC", &mta_unit[20], NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 8, NUM_UNITS_MT, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
@ -310,7 +310,7 @@ DEVICE mtd_dev = {
"MTD", &mta_unit[30], NULL, mt_mod, "MTD", &mta_unit[30], NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 36, NUM_UNITS_MT, 8, 15, 1, 8, 36,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
@ -319,7 +319,7 @@ DEVICE mte_dev = {
"MTE", &mta_unit[40], NULL, mt_mod, "MTE", &mta_unit[40], NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 8, NUM_UNITS_MT, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
@ -328,7 +328,7 @@ DEVICE mtf_dev = {
"MTF", &mta_unit[50], NULL, mt_mod, "MTF", &mta_unit[50], NULL, mt_mod,
NUM_UNITS_MT, 8, 15, 1, 8, 8, NUM_UNITS_MT, 8, 15, 1, 8, 8,
NULL, NULL, &mt_reset, &mt_boot, &mt_attach, &mt_detach, 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 NULL, NULL, &mt_help, NULL, NULL, &mt_description
}; };
#endif #endif
@ -743,7 +743,7 @@ t_stat mt_srv(UNIT * uptr)
/* Channel has disconnected, abort current read. */ /* Channel has disconnected, abort current read. */
if ((mt_chan[chan] & 037) == (MTC_SEL | unit) && if ((mt_chan[chan] & 037) == (MTC_SEL | unit) &&
chan_stat(chan, DEV_DISCO)) { chan_test(chan, DEV_DISCO)) {
uptr->u5 &= ~MT_CMDMSK; uptr->u5 &= ~MT_CMDMSK;
reclen = uptr->hwmark; reclen = uptr->hwmark;
if (cmd == MT_WRS || cmd == MT_WRSB) { 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) { } else if (cmd == MT_RDS || cmd == MT_RDSB) {
sim_debug(DEBUG_DETAIL, dptr, sim_debug(DEBUG_DETAIL, dptr,
"Read flush unit=%d %s Block %d chars\n", "Read flush unit=%d %s at %d Block %d chars\n",
unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen); unit, (cmd == MT_RDS) ? "BCD" : "Binary", uptr->u6, reclen);
/* Keep moving until end of block */ /* Keep moving until end of block */
if (uptr->u6 < (int32)uptr->hwmark ) { if (uptr->u6 < (int32)reclen ) {
reclen -= uptr->u6; reclen -= uptr->u6;
uptr->u3 += reclen; uptr->u3 += reclen;
uptr->u5 |= MT_SKIP|MT_IDLE; uptr->u5 |= MT_SKIP|MT_IDLE;
uptr->u6 = 0; uptr->u6 = 0;
uptr->hwmark = 0; uptr->hwmark = 0;
chan_clear(chan, DEV_DISCO | DEV_WEOR); chan_clear(chan, DEV_WEOR );
sim_activate(uptr, reclen * T1_us); sim_activate(uptr, reclen * T1_us);
return SCPE_OK; return SCPE_OK;
} else { } else {
@ -879,6 +879,7 @@ t_stat mt_srv(UNIT * uptr)
chan_set_error(chan); chan_set_error(chan);
} }
#else #else
chan_set(chan, DEV_REOR);
chan_set_attn(chan); chan_set_attn(chan);
#endif #endif
} }
@ -1057,6 +1058,7 @@ t_stat mt_srv(UNIT * uptr)
r = MTSE_OK; r = MTSE_OK;
} else { } else {
sim_debug(DEBUG_DETAIL, dptr, "error=%d\n", r); sim_debug(DEBUG_DETAIL, dptr, "error=%d\n", r);
uptr->u6 = uptr->hwmark;
uptr->u5 &= ~MT_CMDMSK; uptr->u5 &= ~MT_CMDMSK;
chan_set_attn(chan); chan_set_attn(chan);
chan_clear(chan, DEV_SEL); chan_clear(chan, DEV_SEL);
@ -1354,7 +1356,7 @@ mt_attach(UNIT * uptr, CONST char *file)
{ {
t_stat r; 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; return r;
uptr->u3 = 0; uptr->u3 = 0;
uptr->u5 |= MT_RDY; uptr->u5 |= MT_RDY;

View file

@ -57,7 +57,7 @@ extern uint16 iotraps;
extern uint8 iocheck; extern uint8 iocheck;
extern UNIT cpu_unit; extern UNIT cpu_unit;
extern uint16 IC; extern uint16 IC;
extern uint8 AC[5 * 512]; extern uint8 AC[6 * 512];
extern int chwait; extern int chwait;
extern uint16 selreg; extern uint16 selreg;
extern uint16 selreg2; extern uint16 selreg2;

View file

@ -77,7 +77,7 @@ DEVICE cdp_dev = {
"CDP", cdp_unit, NULL, cdp_mod, "CDP", cdp_unit, NULL, cdp_mod,
NUM_DEVS_CDP, 8, 15, 1, 8, 36, NUM_DEVS_CDP, 8, 15, 1, 8, 36,
NULL, NULL, &cdp_reset, NULL, &cdp_attach, &cdp_detach, 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 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 chan = UNIT_G_CHAN(uptr->flags);
int u = (uptr - cdp_unit); int u = (uptr - cdp_unit);
uint16 *image = (uint16 *)(uptr->up7);
int pos; int pos;
t_uint64 wd; t_uint64 wd;
int bit; int bit;
t_uint64 mask; t_uint64 mask;
int b; int b;
int col; int col;
struct _card_data *data;
/* Channel has disconnected, abort current card. */ /* Channel has disconnected, abort current card. */
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) { if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) {
if ((uptr->u5 & CDPSTA_POSMASK) != 0) { if ((uptr->u5 & CDPSTA_POSMASK) != 0) {
sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n"); 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 &= ~CDPSTA_PUNCH;
} }
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_CMD | CDPSTA_POSMASK); 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_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
} }
sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card full\n"); 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_IDLE;
uptr->u5 &= ~(URCSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH); uptr->u5 &= ~(URCSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH);
uptr->wait = 85; 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); sim_debug(DEBUG_DATA, &cdp_dev, "unit=%d write column %d ", u, pos);
wd = 0; wd = 0;
data = (struct _card_data *)uptr->up7;
switch (chan_read(chan, &wd, 0)) { switch (chan_read(chan, &wd, 0)) {
case DATA_OK: case DATA_OK:
sim_debug(DEBUG_DATA, &cdp_dev, " %012llo\n", wd); 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--) { for (col = 35; col >= 0; mask <<= 1, col--) {
if (wd & mask) if (wd & mask)
data->image[col + b] |= bit; image[col + b] |= bit;
} }
pos++; pos++;
uptr->wait = 0; uptr->wait = 0;
@ -258,13 +257,19 @@ cdp_attach(UNIT * uptr, CONST char *file)
if ((r = sim_card_attach(uptr, file)) != SCPE_OK) if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r; return r;
uptr->u5 = CDPSTA_POSMASK; if (uptr->up7 == 0) {
uptr->up7 = calloc(80, sizeof(uint16));
uptr->u5 = CDPSTA_POSMASK;
}
return SCPE_OK; return SCPE_OK;
} }
t_stat t_stat
cdp_detach(UNIT * uptr) cdp_detach(UNIT * uptr)
{ {
if (uptr->up7 != 0)
free(uptr->up7);
uptr->up7 = 0;
return sim_card_detach(uptr); return sim_card_detach(uptr);
} }

View file

@ -81,7 +81,7 @@ DEVICE cdr_dev = {
"CDR", cdr_unit, NULL, cdr_mod, "CDR", cdr_unit, NULL, cdr_mod,
NUM_DEVS_CDR, 8, 15, 1, 8, 36, NUM_DEVS_CDR, 8, 15, 1, 8, 36,
NULL, NULL, &cdr_reset, &cdr_boot, &cdr_attach, &cdr_detach, 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 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 chan = UNIT_G_CHAN(uptr->flags);
int u = (uptr - cdr_unit); int u = (uptr - cdr_unit);
int pos, col, b; int pos, col, b;
uint16 *image = (uint16 *)(uptr->up7);
uint16 bit; uint16 bit;
t_uint64 mask, wd; t_uint64 mask, wd;
struct _card_data *data;
/* Channel has disconnected, abort current read. */ /* Channel has disconnected, abort current read. */
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) { 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; pos = (uptr->u5 & CDRPOSMASK) >> CDRPOSSHIFT;
if (pos == (CDRPOSMASK >> CDRPOSSHIFT)) { if (pos == (CDRPOSMASK >> CDRPOSSHIFT)) {
switch (sim_read_card(uptr)) { switch (sim_read_card(uptr, image)) {
case SCPE_UNATT: case CDSE_EMPTY:
case SCPE_IOERR: case CDSE_ERROR:
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d Setting ATTN\n", u); sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d Setting ATTN\n", u);
chan_set_error(chan); chan_set_error(chan);
chan_set_attn(chan); chan_set_attn(chan);
uptr->u5 &= ~URCSTA_READ; uptr->u5 &= ~URCSTA_READ;
sim_activate(uptr, us_to_ticks(1000)); sim_activate(uptr, us_to_ticks(1000));
return SCPE_OK; return SCPE_OK;
case SCPE_EOF: case CDSE_EOF:
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d EOF\n", u); sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d EOF\n", u);
chan_set_eof(chan); chan_set_eof(chan);
chan_set_attn(chan); chan_set_attn(chan);
uptr->u5 &= ~URCSTA_READ; uptr->u5 &= ~URCSTA_READ;
sim_activate(uptr, us_to_ticks(1000)); sim_activate(uptr, us_to_ticks(1000));
return SCPE_OK; return SCPE_OK;
case SCPE_OK: case CDSE_OK:
break; break;
} }
pos = 0; pos = 0;
@ -196,7 +196,6 @@ t_stat cdr_srv(UNIT * uptr)
return SCPE_OK; return SCPE_OK;
} }
data = (struct _card_data *)uptr->up7;
/* Bit flip into read buffer */ /* Bit flip into read buffer */
bit = 1 << (pos / 2); bit = 1 << (pos / 2);
mask = 1; mask = 1;
@ -204,7 +203,7 @@ t_stat cdr_srv(UNIT * uptr)
b = (pos & 1)?36:0; b = (pos & 1)?36:0;
for (col = 35; col >= 0; mask <<= 1) { for (col = 35; col >= 0; mask <<= 1) {
if (data->image[col-- + b] & bit) if (image[col-- + b] & bit)
wd |= mask; wd |= mask;
} }
@ -246,7 +245,7 @@ cdr_boot(int32 unit_num, DEVICE * dptr)
int chan = UNIT_G_CHAN(uptr->flags); int chan = UNIT_G_CHAN(uptr->flags);
t_stat r; t_stat r;
int pos; int pos;
struct _card_data *data; uint16 *image = (uint16 *)(uptr->up7);
if ((uptr->flags & UNIT_ATT) == 0) if ((uptr->flags & UNIT_ATT) == 0)
return SCPE_UNATT; /* attached? */ return SCPE_UNATT; /* attached? */
@ -254,12 +253,11 @@ cdr_boot(int32 unit_num, DEVICE * dptr)
/* Init for a read */ /* Init for a read */
if (cdr_cmd(uptr, IO_RDS, cdr_dib.addr) != SCPE_OK) if (cdr_cmd(uptr, IO_RDS, cdr_dib.addr) != SCPE_OK)
return STOP_IONRDY; return STOP_IONRDY;
r = sim_read_card(uptr); r = sim_read_card(uptr, image);
if (r != SCPE_OK) if (r != SCPE_OK)
return r; return r;
/* Copy first three records. */ /* Copy first three records. */
data = (struct _card_data *)uptr->up7;
uptr->u5 &= ~CDRPOSMASK; uptr->u5 &= ~CDRPOSMASK;
for(pos = 0; pos <3; pos++) { for(pos = 0; pos <3; pos++) {
uint16 bit = 1 << (pos / 2); uint16 bit = 1 << (pos / 2);
@ -271,7 +269,7 @@ cdr_boot(int32 unit_num, DEVICE * dptr)
break; break;
M[pos] = 0; M[pos] = 0;
for (col = 35; col >= 0; mask <<= 1) { for (col = 35; col >= 0; mask <<= 1) {
if (data->image[col-- + b] & bit) if (image[col-- + b] & bit)
M[pos] |= mask; M[pos] |= mask;
} }
sim_debug(DEBUG_DATA, &cdr_dev, "boot read row %d %012llo\n", 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) if ((r = sim_card_attach(uptr, file)) != SCPE_OK)
return r; return r;
uptr->u5 = 0; if (uptr->up7 == 0) {
uptr->u4 = 0; uptr->up7 = malloc(sizeof(uint16)*80);
uptr->u5 = 0;
uptr->u4 = 0;
}
return SCPE_OK; return SCPE_OK;
} }
t_stat t_stat
cdr_detach(UNIT * uptr) cdr_detach(UNIT * uptr)
{ {
if (uptr->up7 != 0)
free(uptr->up7);
uptr->up7 = 0;
return sim_card_detach(uptr); return sim_card_detach(uptr);
} }

View file

@ -55,7 +55,7 @@ extern UNIT cpu_unit;
extern uint16 IC; extern uint16 IC;
extern t_uint64 MQ; extern t_uint64 MQ;
extern uint32 drum_addr; extern uint32 drum_addr;
extern uint32 hsdrm_addr; extern t_uint64 hsdrm_addr;
t_stat chan_reset(DEVICE * dptr); t_stat chan_reset(DEVICE * dptr);
void chan_fetch(int chan); void chan_fetch(int chan);
@ -344,10 +344,6 @@ chan_proc()
cmask = 0x0100 << chan; cmask = 0x0100 << chan;
switch (CHAN_G_TYPE(chan_unit[chan].flags)) { switch (CHAN_G_TYPE(chan_unit[chan].flags)) {
case CHAN_PIO: 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)) == if ((chan_flags[chan] & (DEV_REOR|DEV_SEL|DEV_FULL)) ==
(DEV_SEL|DEV_REOR)) { (DEV_SEL|DEV_REOR)) {
sim_debug(DEBUG_DETAIL, &chan_dev, "chan got EOR\n"); 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 */ /* On first command, copy it to drum address and load another */
if ((chan_info[chan] & (CHAINF_RUN | CHAINF_START)) == if ((chan_info[chan] & (CHAINF_RUN | CHAINF_START)) ==
CHAINF_START) { CHAINF_START) {
hsdrm_addr = (int)M[location[chan] - 1]; hsdrm_addr = M[location[chan] - 1];
chan_info[chan] |= CHAINF_RUN; chan_info[chan] |= CHAINF_RUN;
if (chan_dev.dctrl & cmask) 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, hsdrm_addr);
chan_fetch(chan); chan_fetch(chan);
continue; continue;
@ -399,7 +395,6 @@ chan_proc()
iotraps |= 1 << chan; iotraps |= 1 << chan;
break; break;
} }
iotraps |= 1LL << (chan + 18);
if (chan_dev.dctrl & cmask) if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_DETAIL, &chan_dev, sim_debug(DEBUG_DETAIL, &chan_dev,
"chan %d attn< %o\n", chan, cmd[chan] & 070); "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] |= DEV_DISCO | DEV_WEOR;
chan_flags[chan] &= chan_flags[chan] &=
~(STA_START | STA_ACTIVE | STA_PEND); ~(STA_START | STA_ACTIVE | STA_PEND);
if (CHAN_G_TYPE(chan_unit[chan].flags) == if (CHAN_G_TYPE(chan_unit[chan].flags) == CHAN_7289) {
CHAN_7289) { iotraps |= 1 << chan;
iotraps |= 1 << chan;
sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap\n", sim_debug(DEBUG_TRAP, &chan_dev, "chan %d Trap\n",
chan); chan);
} }
@ -845,8 +839,8 @@ chan_proc()
case SCPE_NODEV: case SCPE_NODEV:
chan9_set_error(chan, SNS_IOCHECK); chan9_set_error(chan, SNS_IOCHECK);
iotraps |= 1 << chan; iotraps |= 1 << chan;
chan_flags[chan] &= chan_flags[chan] &= ~(CTL_PREAD|CTL_PWRITE|CTL_SNS|
~(CTL_PREAD|CTL_PWRITE|CTL_SNS|CTL_CNTL|STA_ACTIVE); CTL_CNTL|STA_ACTIVE);
continue; continue;
case SCPE_BUSY: /* Device not ready yet, wait */ case SCPE_BUSY: /* Device not ready yet, wait */
continue; continue;
@ -1266,8 +1260,10 @@ chan_cmd(uint16 dev, uint16 dcmd)
if ((chan_flags[chan] & (DEV_FULL|DEV_WRITE)) == (DEV_FULL|DEV_WRITE)) if ((chan_flags[chan] & (DEV_FULL|DEV_WRITE)) == (DEV_FULL|DEV_WRITE))
return SCPE_BUSY; return SCPE_BUSY;
/* Yes, disconnect device and tell it to write a EOR */ /* Yes, disconnect device and tell it to write a EOR */
chan_flags[chan] |= DEV_DISCO | DEV_WEOR; if ((chan_flags[chan] & (DEV_WRITE)) == (DEV_WRITE) ||
return SCPE_BUSY; (chan_flags[chan] & (DEV_FULL)) == (DEV_FULL))
chan_flags[chan] |= DEV_DISCO | DEV_WEOR;
return SCPE_BUSY;
} }
/* Unit is busy doing something, wait */ /* Unit is busy doing something, wait */
if (chan_flags[chan] & (DEV_SEL | DEV_DISCO | STA_TWAIT | STA_WAIT)) if (chan_flags[chan] & (DEV_SEL | DEV_DISCO | STA_TWAIT | STA_WAIT))

View file

@ -187,7 +187,7 @@
#define HIST_INT 2 /* interrupt cycle */ #define HIST_INT 2 /* interrupt cycle */
#define HIST_TRP 3 /* trap cycle */ #define HIST_TRP 3 /* trap cycle */
#define HIST_MIN 64 #define HIST_MIN 64
#define HIST_MAX 10000 #define HIST_MAX 1000000
#define HIST_NOEA 0x40000000 #define HIST_NOEA 0x40000000
#define HIST_PC 0x10000 #define HIST_PC 0x10000
@ -299,8 +299,13 @@ extern uint32 drum_addr;
*/ */
UNIT cpu_unit = UNIT cpu_unit =
#ifdef I7090
{ UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_7090) | MEMAMOUNT(4), { UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_7090) | MEMAMOUNT(4),
MAXMEMSIZE/2 ), 120 }; MAXMEMSIZE/2 ), 120 };
#else
{ UDATA(rtc_srv, UNIT_BINK | MODEL(CPU_704) | MEMAMOUNT(4),
MAXMEMSIZE/2 ), 120 };
#endif
REG cpu_reg[] = { REG cpu_reg[] = {
{ORDATAD(IC, IC, 15, "Instruction Counter"), REG_FIT}, {ORDATAD(IC, IC, 15, "Instruction Counter"), REG_FIT},
@ -724,7 +729,6 @@ sim_instr(void)
int xeccnt = 15; int xeccnt = 15;
int shiftcnt; int shiftcnt;
int stopnext = 0; int stopnext = 0;
int first_rdwr = 0;
int instr_count = 0; /* Number of instructions to execute */ int instr_count = 0; /* Number of instructions to execute */
if (sim_step != 0) { if (sim_step != 0) {
@ -734,7 +738,7 @@ sim_instr(void)
/* Set cycle time for delays */ /* Set cycle time for delays */
switch(CPU_MODEL) { 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 */ case CPU_709: cycle_time = 120; break; /* 83,333 cycles per second */
default: default:
case CPU_7090: cycle_time = 22; break; /* 454,545 cycles per second */ case CPU_7090: cycle_time = 22; break; /* 454,545 cycles per second */
@ -758,6 +762,7 @@ sim_instr(void)
tbase |= CORE_B; tbase |= CORE_B;
iowait = 0; iowait = 0;
ihold = 0;
while (reason == 0) { /* loop until halted */ while (reason == 0) { /* loop until halted */
if (exe_KEYS) { if (exe_KEYS) {
@ -767,9 +772,7 @@ sim_instr(void)
goto next_xec; goto next_xec;
} }
#ifdef I7090 /* I704 did not have interrupts */
hltloop: hltloop:
#endif
/* If doing fast I/O don't sit in idle loop */ /* If doing fast I/O don't sit in idle loop */
if (iowait && (cpu_unit.flags & UNIT_FASTIO)) if (iowait && (cpu_unit.flags & UNIT_FASTIO))
sim_interval = 0; sim_interval = 0;
@ -799,7 +802,6 @@ sim_instr(void)
} }
#endif #endif
if (iowait == 0 && sim_brk_summ && if (iowait == 0 && sim_brk_summ &&
sim_brk_test(((bcore & 2)? CORE_B:0)|IC, SWMASK('E'))) { sim_brk_test(((bcore & 2)? CORE_B:0)|IC, SWMASK('E'))) {
reason = STOP_IBKPT; reason = STOP_IBKPT;
@ -808,7 +810,7 @@ sim_instr(void)
/* Check if we need to take any traps */ /* Check if we need to take any traps */
#ifdef I7090 /* I704 did not have interrupts */ #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; t_uint64 mask = 00000001000001LL;
MA = 012; MA = 012;
@ -832,9 +834,13 @@ sim_instr(void)
/* check if we need to perform a trap */ /* check if we need to perform a trap */
if (f) { if (f) {
/* HTR/HPR behave like wait if protected */ /* 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; hltinst = 0;
temp = (((t_uint64) bcore & 3) << 31) |
(((t_uint64) f) << 18) | (IC & memmask);
sim_interval = sim_interval - 1; /* count down */ sim_interval = sim_interval - 1; /* count down */
WriteP(MA, temp); WriteP(MA, temp);
if (nmode) { if (nmode) {
@ -849,8 +855,8 @@ sim_instr(void)
sim_interval = sim_interval - 1; /* count down */ sim_interval = sim_interval - 1; /* count down */
SR = ReadP(MA); SR = ReadP(MA);
sim_debug(DEBUG_TRAP, &cpu_dev, sim_debug(DEBUG_TRAP, &cpu_dev,
"Doing trap chan %c %o >%012llo loc %o %012llo\n", "Doing trap chan %c %o >%012llo loc %o %012llo IC=%06o\n",
shiftcnt + 'A' - 1, f, temp, MA, SR); shiftcnt + 'A' - 1, f, temp, MA, SR, IC);
if (hst_lnt) { /* history enabled? */ if (hst_lnt) { /* history enabled? */
hst_p = (hst_p + 1); /* next entry */ hst_p = (hst_p + 1); /* next entry */
if (hst_p >= hst_lnt) if (hst_p >= hst_lnt)
@ -875,9 +881,13 @@ sim_instr(void)
/* Interval timer has lower priority then I/O traps */ /* Interval timer has lower priority then I/O traps */
if (interval_irq && (ioflags & 0400000)) { if (interval_irq && (ioflags & 0400000)) {
/* HTR/HPR behave like wait if protected */ /* 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; hltinst = 0;
temp = (((t_uint64) bcore & 3) << 31) | (IC & memmask) |
(relo_mode << 21);
sim_interval = sim_interval - 1; /* count down */ sim_interval = sim_interval - 1; /* count down */
MA = 6; MA = 6;
WriteP(MA, temp); WriteP(MA, temp);
@ -915,27 +925,20 @@ sim_instr(void)
if (hltinst) { if (hltinst) {
t_uint64 mask = 00000001000001LL; t_uint64 mask = 00000001000001LL;
if (CPU_MODEL == CPU_704) {
reason = STOP_HALT;
break;
}
/* Hold out until all channels have idled out */ /* Hold out until all channels have idled out */
sim_interval = 0; sim_interval = sim_interval - 1; /* count down */
(void)sim_process_event();
chan_proc(); chan_proc();
f = chan_active(0); f = chan_active(0);
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) { for (shiftcnt = 1; f == 0 && shiftcnt < NUM_CHAN; shiftcnt++) {
f |= chan_active(shiftcnt); f = chan_active(shiftcnt);
/* CRC *//* Trap *//* EOF */ /* CRC *//* Trap *//* EOF */
/* Wait until channel stops to trigger interupts */ /* Wait until channel stops to trigger interrupts */
if (ioflags & mask) { if (itrap) {
if (mask & AMASK & ioflags) { /* Check for EOF or IOCT/IORT/IOST */
if (chan_stat(shiftcnt, CHS_EOF)) if (mask & AMASK & ioflags &&
f = 1; /* We have a EOF */ (chan_test(shiftcnt, CHS_EOF) || iotraps & (1 << shiftcnt)))
if (iotraps & (1 << shiftcnt)) f = 1;
f = 1; /* We have a IOCT/IORT/IOST */ if (mask & DMASK & ioflags && chan_test(shiftcnt, CHS_ERR))
}
if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR))
f = 1; /* We have device error */ f = 1; /* We have device error */
} }
} }
@ -949,6 +952,10 @@ sim_instr(void)
} }
#else /* Handle halt on 704 */ #else /* Handle halt on 704 */
if (hltinst) { if (hltinst) {
sim_interval = sim_interval - 1; /* count down */
chan_proc();
if (chan_active(0))
goto hltloop;
reason = STOP_HALT; reason = STOP_HALT;
break; break;
} }
@ -989,6 +996,8 @@ sim_instr(void)
relo_pend = 0; relo_pend = 0;
prot_pend = 0; prot_pend = 0;
} }
next_xec: next_xec:
opcode = (uint16)(SR >> 24); opcode = (uint16)(SR >> 24);
IR = opcode; IR = opcode;
@ -1314,9 +1323,9 @@ prottrap:
break; break;
#ifdef I7090 /* Not on 704 */ #ifdef I7090 /* Not on 704 */
case OP_RCT: case OP_RCT:
if (bcore & 4)
goto prottrap;
if (CPU_MODEL != CPU_704) { if (CPU_MODEL != CPU_704) {
if (bcore & 4)
goto prottrap;
sim_debug(DEBUG_TRAP, &cpu_dev, "RCT %012llo\n", ioflags); sim_debug(DEBUG_TRAP, &cpu_dev, "RCT %012llo\n", ioflags);
if ((bcore & 4) || STM) if ((bcore & 4) || STM)
goto seltrap; goto seltrap;
@ -1471,8 +1480,12 @@ prottrap:
case OP_HPR: case OP_HPR:
halt: halt:
hltinst = 1; hltinst = 1;
if (opcode == OP_HTR) ihold = 0; /* Kill any hold on traps now */
if (opcode == OP_HTR) {
fptemp = IC-1;
IC = MA; IC = MA;
} else
fptemp = IC;
break; break;
case OP_XEC: case OP_XEC:
opcode = (uint16)(SR >> 24); opcode = (uint16)(SR >> 24);
@ -3246,10 +3259,9 @@ prottrap:
case OP_LDA: case OP_LDA:
if (chan_select(0)) { if (chan_select(0)) {
extern DEVICE drm_dev; extern DEVICE drm_dev;
drum_addr = (uint32)(MQ = SR); drum_addr = (uint32)(SR);
sim_debug(DEBUG_DETAIL, &drm_dev, sim_debug(DEBUG_DETAIL, &drm_dev,
"set address %06o\n", drum_addr); "set address %06o\n", drum_addr);
MQ <<= 1;
chan_clear(0, DEV_FULL); /* In case we read something chan_clear(0, DEV_FULL); /* In case we read something
before we got here */ before we got here */
} else } else
@ -3324,49 +3336,38 @@ prottrap:
/* Input/Output Instuctions */ /* Input/Output Instuctions */
case OP_ENB: case OP_ENB:
ioflags = SR; ioflags = SR;
itrap = 1; if (SR)
itrap = 1;
else
itrap = 0;
sim_debug(DEBUG_TRAP, &cpu_dev, "ENB %012llo\n", ioflags);
ihold = 1; ihold = 1;
/* /*
* IBSYS can't have an trap right after ENB or it will hang * IBSYS can't have an trap right after ENB or it will hang
* on a TTR * in IBNUC. * on a TTR * in IBNUC.
*/ */
if (CPU_MODEL >= CPU_7090) if (CPU_MODEL >= CPU_7090)
break; break;
/* Don't wait if EOF or Error is pending but hold if trap */
temp = 00000001000001LL; temp = 00000001000001LL;
for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) { for (shiftcnt = 1; shiftcnt < NUM_CHAN; shiftcnt++) {
if (chan_active(shiftcnt) == 0) { if ((temp & ioflags & DMASK) == 0)
if (temp & ioflags & AMASK && chan_clear(shiftcnt, CHS_ERR);
iotraps & 1 << shiftcnt) else if (chan_test(shiftcnt,CHS_ERR))
break; ihold = 0;
if ((temp & ioflags & AMASK && if ((temp & ioflags & AMASK) == 0)
chan_test(shiftcnt, CHS_EOF)) || chan_clear(shiftcnt, CHS_EOF);
(temp & ioflags & DMASK && else if (chan_test(shiftcnt,CHS_EOF))
chan_test(shiftcnt, CHS_ERR))) { ihold = 0;
ihold = 0;
break;
}
}
temp <<= 1; temp <<= 1;
} }
break; break;
#endif #endif
case OP_RDS: /* Read select */ 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; opcode = IO_RDS;
goto docmd; goto docmd;
case OP_WRS: /* Write select */ case OP_WRS: /* Write select */
if (CPU_MODEL != CPU_704 && first_rdwr == 0) {
first_rdwr = 1;
}
opcode = IO_WRS; opcode = IO_WRS;
goto docmd; goto docmd;
case OP_WEF: /* Write EOF */ case OP_WEF: /* Write EOF */
@ -3395,12 +3396,16 @@ prottrap:
iowait = 1; /* Channel is active, hold */ iowait = 1; /* Channel is active, hold */
break; break;
case SCPE_OK: 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 */ ihold = 1; /* Hold interupts for one cycle */
first_rdwr = 0; iotraps &= ~(1 << ((MA >> 9) & 017));
break; break;
case SCPE_IOERR: case SCPE_IOERR:
iocheck = 1; iocheck = 1;
first_rdwr = 0;
break; break;
case SCPE_NODEV: case SCPE_NODEV:
reason = STOP_IOCHECK; reason = STOP_IOCHECK;
@ -3426,6 +3431,7 @@ prottrap:
#ifdef I7090 /* Not on 704 */ #ifdef I7090 /* Not on 704 */
case OP_TRCA: /* Transfer on Redundancy check */ case OP_TRCA: /* Transfer on Redundancy check */
ihold = 2;
if ((1LL << 18) & ioflags) if ((1LL << 18) & ioflags)
break; break;
f = chan_stat(1, CHS_ERR); f = chan_stat(1, CHS_ERR);
@ -3468,6 +3474,7 @@ prottrap:
#endif #endif
case OP_TEFA: /* Transfer on channel EOF */ case OP_TEFA: /* Transfer on channel EOF */
ihold = 2;
if ((1LL << 0) & ioflags) if ((1LL << 0) & ioflags)
break; break;
f = chan_stat(1, CHS_EOF); f = chan_stat(1, CHS_EOF);

View file

@ -109,7 +109,7 @@ uint32 drm_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
/* Choose which part to use */ /* Choose which part to use */
uptr->u5 |= u << DRMSTA_UNITSHIFT; uptr->u5 |= u << DRMSTA_UNITSHIFT;
drum_addr = 0; /* Set drum address */ drum_addr = 0; /* Set drum address */
chan_clear(chan, CHS_ATTN); /* Clear attentions */ chan_clear_status(chan);
/* Make sure drum is spinning */ /* Make sure drum is spinning */
sim_activate(uptr, us_to_ticks(100)); sim_activate(uptr, us_to_ticks(100));
return SCPE_OK; return SCPE_OK;

View file

@ -110,7 +110,7 @@ DEVICE *sim_devices[] = {
/* Device addressing words */ /* Device addressing words */
#ifdef NUM_DEVS_DR #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 #endif
#ifdef NUM_DEVS_CDP #ifdef NUM_DEVS_CDP
DIB cdp_dib = { CH_TYP_PIO|CH_TYP_76XX, 1, 0341, 0777, &cdp_cmd, &cdp_ini }; DIB cdp_dib = { CH_TYP_PIO|CH_TYP_76XX, 1, 0341, 0777, &cdp_cmd, &cdp_ini };

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.