1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-02-18 05:24:19 +00:00

I7000: Updated i7010 and related files to pass daigs and run PR155+PR108

This commit is contained in:
Richard Cornwell
2017-09-16 00:52:26 -04:00
parent 386ba2be85
commit c4dbbed1a5
8 changed files with 290 additions and 218 deletions

View File

@@ -245,20 +245,24 @@ cdp_srv(UNIT *uptr) {
data = (struct _card_data *)uptr->up7;
#ifdef I7080
switch(chan_read_char(chan, &ch, 0)) {
#else
switch(chan_read_char(chan, &ch,
(uptr->u4 == 79)? DEV_REOR: 0)) {
#endif
case TIME_ERROR:
case END_RECORD:
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
uptr->u5 &= ~URCSTA_WRITE;
break;
case DATA_OK:
if (ch == 0)
ch = 020;
else if (ch == 020)
ch = 0;
sim_debug(DEBUG_DATA, &cdp_dev, "%d: Char < %02o\n", u, ch);
data->image[uptr->u4++] = sim_bcd_to_hol(ch);
if (uptr->u4 == 80) {
chan_set(chan, DEV_REOR);
uptr->u5 |= URCSTA_WDISCO|URCSTA_BUSY|URCSTA_FULL;
uptr->u5 &= ~URCSTA_WRITE;
}
break;
}
sim_activate(uptr, 10);

View File

@@ -123,6 +123,9 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->u5 &= ~0xF0000;
uptr->u5 |= stk << 16;
#endif
if (uptr->u5 & (URCSTA_EOF|URCSTA_ERR))
return SCPE_IOERR;
/* Process commands */
switch(cmd) {
case IO_RDS:
@@ -204,11 +207,12 @@ cdr_srv(UNIT *uptr) {
chan_set_eof(chan);
chan_set_attn(chan);
chan_clear(chan, DEV_SEL);
uptr->u5 &= ~URCSTA_BUSY;
uptr->u5 |= URCSTA_EOF;
uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
return SCPE_OK;
case SCPE_IOERR:
uptr->u5 |= URCSTA_ERR;
uptr->u5 &= ~URCSTA_BUSY;
uptr->u5 &= ~(URCSTA_BUSY|URCSTA_READ);
chan_set_attn(chan);
chan_clear(chan, DEV_SEL);
return SCPE_OK;

View File

@@ -228,6 +228,7 @@ typedef struct dib DIB;
#define DEBUG_EXP 0x0000040 /* Show error conditions */
#define DEBUG_SNS 0x0000080 /* Shows sense data for 7909 devs */
#define DEBUG_CTSS 0x0000100 /* Shows CTSS specail instructions */
#define DEBUG_PRIO 0x0000100 /* Debug Priority mode on 7010 */
#define DEBUG_PROT 0x0000200 /* Protection traps */
extern DEBTAB dev_debug[];

View File

@@ -119,8 +119,10 @@ void mt_ini(UNIT *, t_bool);
t_stat mt_reset(DEVICE *);
t_stat mt_attach(UNIT *, CONST char *);
t_stat mt_detach(UNIT *);
t_stat mt_rew(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
t_stat mt_tape_density(UNIT * uptr, int32 val, CONST char *cptr, void *desc);
t_stat mt_rew(UNIT * uptr, int32 val, CONST char *cptr,
void *desc);
t_stat mt_tape_density(UNIT * uptr, int32 val, CONST char *cptr,
void *desc);
t_stat mt_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
const char *cptr);
const char *mt_description (DEVICE *dptr);
@@ -388,8 +390,9 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
/* Check status of the drive */
/* Can't do nothing if controller is busy */
if (mt_chan[chan] & MTC_BSY)
if (mt_chan[chan] & MTC_BSY) {
return SCPE_BUSY;
}
/* If drive is offline or not attached return not ready */
if ((uptr->flags & (UNIT_ATT | MTUF_ONLINE)) !=
(UNIT_ATT | MTUF_ONLINE)) {
@@ -402,8 +405,9 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
/* Return indication if not ready and doing TRS */
if (cmd == IO_TRS) {
return SCPE_IOERR;
} else
} else {
return SCPE_BUSY;
}
}
uptr->u5 &= ~(MT_CMDMSK | MT_RDY);
time = us_to_ticks(12000);
@@ -428,8 +432,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
#endif
chan_set_sel(chan, 0);
chan_clear_status(chan);
mt_chan[chan] &= MTC_BSY;
mt_chan[chan] |= MTC_SEL | unit;
mt_chan[chan] = 0;
mt_chan[chan] |= MTC_BSY | MTC_SEL | unit;
uptr->u5 &= ~(MT_RM|MT_EOR|MT_EGAP);
uptr->u6 = -1;
uptr->hwmark = -1;
@@ -467,8 +471,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->hwmark = 0;
chan_set_sel(chan, 1);
chan_clear_status(chan);
mt_chan[chan] &= MTC_BSY;
mt_chan[chan] |= MTC_SEL | unit;
mt_chan[chan] = 0;
mt_chan[chan] |= MTC_BSY | MTC_SEL | unit;
uptr->u5 &= ~(MT_MARK | MT_EOT);
#if I7010 | I7080
chan_set(chan, STA_TWAIT);
@@ -487,8 +491,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->u5 |= MT_RDB;
chan_set_sel(chan, 0);
chan_clear_status(chan);
mt_chan[chan] &= MTC_BSY;
mt_chan[chan] |= MTC_SEL | unit;
mt_chan[chan] = 0;
mt_chan[chan] |= MTC_BSY | MTC_SEL | unit;
uptr->u5 &= ~(MT_RM|MT_EOR|MT_EGAP);
uptr->u6 = -1;
uptr->hwmark = -1;
@@ -511,6 +515,10 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->u5 |= MT_WEF;
mt_chan[chan] |= MTC_BSY;
#if I7010 | I7080
chan_set_sel(chan, 1);
chan_clear_status(chan);
mt_chan[chan] = 0;
mt_chan[chan] |= MTC_BSY | MTC_SEL | unit;
chan_set(chan, STA_TWAIT);
#endif
sim_debug(DEBUG_CMD, dptr, "WEF unit=%d\n", unit);
@@ -527,7 +535,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
return SCPE_OK;
}
uptr->u5 |= MT_BSR;
mt_chan[chan] |= MTC_BSY;
mt_chan[chan] = MTC_BSY;
sim_debug(DEBUG_CMD, dptr, "BSR unit=%d\n", unit);
break;
@@ -542,7 +550,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
return SCPE_OK;
}
uptr->u5 |= MT_BSF;
mt_chan[chan] |= MTC_BSY;
mt_chan[chan] = MTC_BSY;
sim_debug(DEBUG_CMD, dptr, "BSF unit=%d\n", unit);
break;
@@ -551,7 +559,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
time = us_to_ticks(21000);
uptr->u5 &= ~(MT_MARK|MT_EGAP);
uptr->u5 |= MT_SKR;
mt_chan[chan] |= MTC_BSY;
mt_chan[chan] = MTC_BSY;
sim_debug(DEBUG_CMD, dptr, "SKR unit=%d\n", unit);
break;
@@ -560,7 +568,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
#ifdef I7080
uptr->u5 &= ~(MT_MARK);
uptr->u5 |= MT_ERG;
mt_chan[chan] |= MTC_BSY;
mt_chan[chan] = MTC_BSY;
chan_set(chan, STA_TWAIT);
break;
#else
@@ -579,7 +587,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
}
time = 1000;
uptr->u5 |= MT_REW;
mt_chan[chan] |= MTC_BSY;
mt_chan[chan] = MTC_BSY;
sim_debug(DEBUG_CMD, dptr, "REW unit=%d\n", unit);
sim_cancel(uptr);
sim_activate(uptr, time);
@@ -589,7 +597,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->u5 &= ~(MT_EOT|MT_MARK|MT_EGAP);
chan_clear_status(chan);
uptr->u5 |= MT_RUN;
mt_chan[chan] |= MTC_BSY;
mt_chan[chan] = MTC_BSY;
time = 1000;
sim_debug(DEBUG_CMD, dptr, "RUN unit=%d\n", unit);
sim_cancel(uptr);
@@ -709,6 +717,9 @@ t_stat mt_error(UNIT * uptr, int chan, t_stat r, DEVICE * dptr)
case MTSE_EOM: /* end of medium */
uptr->u5 |= MT_EOT;
sim_debug(DEBUG_EXP, dptr, "EOT ");
#ifdef I7010
chan_set_attn(chan); /* Set error */
#endif
break;
}
return SCPE_OK;
@@ -735,37 +746,32 @@ t_stat mt_srv(UNIT * uptr)
/* Channel has disconnected, abort current read. */
if ((mt_chan[chan] & 037) == (MTC_SEL | unit) &&
chan_stat(chan, DEV_DISCO)) {
chan_stat(chan, DEV_DISCO)) {
uptr->u5 &= ~MT_CMDMSK;
#ifdef I7010
if ((cmd == MT_WRS || cmd == MT_WRSB) && uptr->u6 > 0) {
reclen = uptr->hwmark;
#else
if (cmd == MT_WRS || cmd == MT_WRSB) {
if (uptr->u6 > 0) {
reclen = uptr->hwmark;
#endif
uptr->u3 += GAP_LEN;
sim_debug(DEBUG_DETAIL, dptr,
"Write flush unit=%d %s Block %d chars %d\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3);
"Write flush unit=%d %s Block %d chars\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
mt_error(uptr, chan, r, dptr); /* Record errors */
#ifndef I7010
}
#endif
} else if (cmd == MT_RDS || cmd == MT_RDSB) {
sim_debug(DEBUG_DETAIL, dptr,
"Read flush unit=%d %s Block %d chars %d\n",
unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen, uptr->u3);
"Read flush unit=%d %s Block %d chars\n",
unit, (cmd == MT_RDS) ? "BCD" : "Binary", reclen);
/* Keep moving until end of block */
if (uptr->u6 < (int32)uptr->hwmark ) {
uptr->u3 += uptr->hwmark-uptr->u6;
reclen -= uptr->u6;
uptr->u3 += reclen;
uptr->u5 |= MT_SKIP|MT_IDLE;
uptr->u6 = 0;
uptr->hwmark = 0;
chan_clear(chan, DEV_DISCO | DEV_WEOR);
sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us);
sim_activate(uptr, reclen * T1_us);
mt_chan[chan] = 0;
return SCPE_OK;
} else {
#ifndef I7010
@@ -780,12 +786,13 @@ t_stat mt_srv(UNIT * uptr)
#endif
}
}
sim_activate(uptr, T2_us);
/* Allow time for tape to be restarted, before stop */
sim_activate(uptr, us_to_ticks(500));
uptr->u6 = 0;
uptr->hwmark = 0;
sim_debug(DEBUG_CHAN, dptr, "Disconnect unit=%d\n", unit);
uptr->u5 |= MT_IDLE|MT_RDY;
mt_chan[chan] &= MTC_BSY;
mt_chan[chan] = 0;
chan_clear(chan, DEV_DISCO | DEV_WEOR | DEV_SEL);
#if I7010 | I7080
chan_clear(chan, STA_TWAIT);
@@ -808,9 +815,10 @@ t_stat mt_srv(UNIT * uptr)
#else
chan_clear(chan, DEV_SEL|STA_TWAIT);
#endif
mt_chan[chan] &= MTC_BSY; /* Clear all but busy */
sim_debug(DEBUG_DETAIL, dptr, "Skip unit=%d %d\n", unit, uptr->u3);
sim_activate(uptr, T2_us);
mt_chan[chan] = 0;
sim_debug(DEBUG_DETAIL, dptr, "Skip unit=%d\n", unit);
/* Allow time for tape to be restarted, before stop */
sim_activate(uptr, us_to_ticks(500));
return SCPE_OK;
case MT_RDS:
@@ -818,7 +826,6 @@ t_stat mt_srv(UNIT * uptr)
/* Fall through */
case MT_RDSB:
#ifndef I7010
/* Post EOR */
if (uptr->u5 & MT_EOR) {
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit);
@@ -827,7 +834,7 @@ t_stat mt_srv(UNIT * uptr)
sim_activate(uptr, T1_us);
return SCPE_OK;
}
#endif
/* If tape mark pending, return it */
if (chan_test(chan, DEV_FULL) == 0 && uptr->u5 & MT_MARK) {
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post ", unit);
@@ -849,7 +856,7 @@ t_stat mt_srv(UNIT * uptr)
}
/* If at end of record, fill buffer */
if (uptr->u6 == uptr->hwmark) {
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d %d", unit,uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d ", unit);
uptr->u3 += GAP_LEN;
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen,
BUFFSIZE)) != MTSE_OK) {
@@ -865,15 +872,16 @@ t_stat mt_srv(UNIT * uptr)
if (r == MTSE_TMK && astmode) {
sim_debug(DEBUG_DETAIL, dptr, "Read TM ");
ch = mode?017:054;
chan_write_char(chan, &ch, DEV_REOR);
chan_set_eof(chan);
chan_write_char(chan, &ch, 0);
chan_set_attn(chan);
chan_set(chan, DEV_REOR);
chan_clear(chan, STA_TWAIT);
if (mode) {
sim_activate(uptr, T1_us);
return SCPE_OK;
}
chan_set_error(chan);
}
chan_set_error(chan);
#else
chan_set_attn(chan);
#endif
@@ -901,9 +909,9 @@ t_stat mt_srv(UNIT * uptr)
if (astmode)
ch = 054;
#else
chan_set_error(chan);
chan_set_attn(chan);
#endif
chan_set_error(chan);
}
#if I7090 | I704 | I701
/* Not needed on decimal machines */
@@ -921,6 +929,12 @@ t_stat mt_srv(UNIT * uptr)
}
}
}
#endif
#ifdef I7010
if (mode) {
if (ch == 0120)
ch = 0;
}
#endif
ch &= 077;
@@ -941,14 +955,9 @@ t_stat mt_srv(UNIT * uptr)
case DATA_OK:
sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %02o\n",
unit, uptr->u6, ch);
if (uptr->u6 >= (int32)uptr->hwmark) { /* In IRG */
if (uptr->u6 >= (int32)uptr->hwmark) /* In IRG */
uptr->u5 |= MT_EOR;
#ifdef I7010
(void)chan_write_char(chan, &ch, DEV_WEOR);
#endif
sim_activate(uptr, T1_us);
} else
sim_activate(uptr, T1_us);
sim_activate(uptr, T1_us);
break;
case TIME_ERROR:
@@ -969,7 +978,7 @@ t_stat mt_srv(UNIT * uptr)
/* fall through */
case MT_WRSB:
if (uptr->u5 & MT_EGAP) {
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d %d\n", unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
uptr->u5 &= ~MT_EGAP;
r = sim_tape_wrgap(uptr, 35);
sim_activate(uptr, 10*T3_us);
@@ -979,7 +988,7 @@ t_stat mt_srv(UNIT * uptr)
switch (chan_read_char(chan, &ch,
(uptr->u6 > BUFFSIZE) ? DEV_WEOR : 0)) {
case TIME_ERROR:
#ifdef I7010
#if I7090 | I701 | I704
/* If no data was written, simulate a write gap */
if (uptr->u6 == 0) {
r = sim_tape_wrgap(uptr, 35);
@@ -992,8 +1001,8 @@ t_stat mt_srv(UNIT * uptr)
if (uptr->u6 > 0) { /* Only if data in record */
reclen = uptr->hwmark;
sim_debug(DEBUG_DETAIL, dptr,
"Write unit=%d %s Block %d chars %d\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3);
"Write unit=%d %s Block %d chars\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
uptr->u3 += GAP_LEN;
uptr->u6 = 0;
@@ -1108,13 +1117,13 @@ t_stat mt_srv(UNIT * uptr)
case MT_WEF:
if (uptr->u5 & MT_EGAP) {
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d %d\n", unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Write extended Gap unit=%d\n", unit);
uptr->u5 &= ~MT_EGAP;
r = sim_tape_wrgap(uptr, 35);
sim_activate(uptr, 10*T3_us);
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d %d\n", unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
uptr->u5 &= ~(MT_CMDMSK|MT_MARK);
uptr->u5 |= (MT_RDY);
r = sim_tape_wrtmk(uptr);
@@ -1122,12 +1131,12 @@ t_stat mt_srv(UNIT * uptr)
mt_chan[chan] &= ~MTC_BSY;
sim_activate(uptr, T2_us);
#if I7010 | I7080
chan_clear(chan, STA_TWAIT);
chan_set(chan, DEV_REOR);
#endif
break;
case MT_BSR:
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d %d ", unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
/* Clear tape mark, command, idle since we will need to change dir */
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_RDY);
r = sim_tape_sprecr(uptr, &reclen);
@@ -1156,8 +1165,7 @@ t_stat mt_srv(UNIT * uptr)
uptr->u3 -= GAP_LEN;
/* If we hit mark or end of tape */
if (r == MTSE_TMK || r == MTSE_BOT) {
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d %d\n",
unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d\n", unit);
uptr->u5 &= ~MT_CMDMSK;
mt_chan[chan] &= ~MTC_BSY;
sim_activate(uptr, T2_us);
@@ -1241,7 +1249,7 @@ t_stat mt_srv(UNIT * uptr)
return SCPE_OK;
case MT_HREW:
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d HS %d\n", unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d HS\n", unit);
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
uptr->u3 -= (uptr->flags & MTUF_LDN) ? 1666 :4625;
sim_activate(uptr, us_to_ticks(16000));
@@ -1253,7 +1261,7 @@ t_stat mt_srv(UNIT * uptr)
return SCPE_OK;
case MT_LREW:
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d LS %d\n", unit, uptr->u3);
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d LS\n", unit);
if (uptr->u3 > 0) {
uptr->u3 -= (uptr->flags & MTUF_LDN) ? 373 :1036;
sim_activate(uptr, us_to_ticks(16000));
@@ -1291,7 +1299,8 @@ mt_boot(int32 unit_num, DEVICE * dptr)
return STOP_IONRDY;
#if I7090 | I704 | I701
r = sim_tape_rdrecf(uptr, &mt_buffer[GET_DEV_BUF(dptr->flags)][0], &reclen, BUFFSIZE);
r = sim_tape_rdrecf(uptr, &mt_buffer[GET_DEV_BUF(dptr->flags)][0], &reclen,
BUFFSIZE);
if (r != SCPE_OK)
return r;
uptr->u6 = 0;

View File

@@ -289,6 +289,7 @@ chan_proc()
/* Scan channels looking for work */
for (chan = 0; chan < NUM_CHAN; chan++) {
/* Skip if channel is disabled */
if (chan_unit[chan].flags & UNIT_DIS)
continue;
@@ -299,12 +300,12 @@ chan_proc()
continue;
if (chan_flags[chan] & CHS_EOF) {
chan_io_status[chan] |= 010;
chan_io_status[chan] |= IO_CHS_COND;
chan_flags[chan] &= ~CHS_EOF;
}
if (chan_flags[chan] & CHS_ERR) {
chan_io_status[chan] |= 004;
chan_io_status[chan] |= IO_CHS_CHECK;
chan_flags[chan] &= ~CHS_ERR;
}
@@ -340,7 +341,7 @@ chan_proc()
chan_flags[chan] &= ~(CTL_END);
else
chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END);
chan_io_status[chan] |= 0100;
chan_io_status[chan] |= IO_CHS_DONE;
}
continue;
}
@@ -360,27 +361,52 @@ chan_proc()
(chan_flags[chan] & (CTL_END|SNS_UEND))) {
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= DEV_WEOR|DEV_DISCO;
chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END|CTL_READ|CTL_WRITE);
chan_flags[chan] &= ~(STA_ACTIVE|SNS_UEND|CTL_END|CTL_READ
|CTL_WRITE);
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_CHAN, &chan_dev, "chan %d end\n", chan);
cmd[chan] &= ~CHAN_DSK_SEEK;
chan_io_status[chan] |= 0100;
chan_io_status[chan] |= IO_CHS_DONE;
}
/* If device put up EOR, terminate transfer. */
if (chan_flags[chan] & DEV_REOR) {
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_EXP, &chan_dev, "chan %d EOR\n", chan);
if (chan_flags[chan] & DEV_WRITE) {
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD))
M[caddr[chan]++] = 035;
caddr[chan]++;
} else {
if ((cmd[chan] & CHAN_NOREC) == 0 &&
(chan_flags[chan] & STA_WAIT) == 0) {
if (MEM_ADDR_OK(caddr[chan])) {
if (M[caddr[chan]++] != (WM|077)) {
if (MEM_ADDR_OK(caddr[chan])) {
chan_io_status[chan] |= IO_CHS_WRL;
if (!MEM_ADDR_OK(caddr[chan]+1)) {
caddr[chan]++;
}
}
}
} else {
chan_io_status[chan] |= IO_CHS_WRL;
}
}
if ((cmd[chan] & CHAN_NOREC) && MEM_ADDR_OK(caddr[chan])) {
chan_io_status[chan] |= IO_CHS_WRL;
if (!MEM_ADDR_OK(caddr[chan]+1)) {
chan_io_status[chan] &= ~IO_CHS_WRL;
}
caddr[chan]++;
}
}
chan_flags[chan] &= ~(CHS_ATTN|STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR);
chan_io_status[chan] |= 0100;
chan_flags[chan] &= ~(STA_ACTIVE|STA_WAIT|DEV_WRITE|DEV_REOR);
chan_io_status[chan] |= IO_CHS_DONE;
/* Disconnect if selected */
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= (DEV_DISCO);
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_EXP, &chan_dev, "chan %d EOR %d %o\n", chan,
caddr[chan], chan_io_status[chan]);
continue;
}
@@ -392,14 +418,14 @@ chan_proc()
/* If device requested attention, abort current command */
if (chan_flags[chan] & CHS_ATTN) {
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_EXP, &chan_dev, "chan %d Attn\n",
chan);
chan_flags[chan] &= ~(CHS_ATTN|STA_ACTIVE|STA_WAIT);
chan_io_status[chan] |= 0110;
chan_io_status[chan] |= IO_CHS_DONE|IO_CHS_COND;
/* Disconnect if selected */
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= (DEV_DISCO);
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_EXP, &chan_dev, "chan %d Attn %o\n",
chan, chan_io_status[chan]);
continue;
}
}
@@ -432,7 +458,7 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
if (chan_unit[chan].flags & UNIT_DIS)
return SCPE_IOERR;
/* Unit is busy doing something, wait */
if (chan_flags[chan] & (DEV_SEL| DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE))
if (chan_flags[chan] & (DEV_SEL|DEV_DISCO|STA_TWAIT|STA_WAIT|STA_ACTIVE))
return SCPE_BUSY;
/* Ok, try and find the unit */
caddr[chan] = addr;
@@ -442,11 +468,12 @@ chan_cmd(uint16 dev, uint16 dcmd, uint32 addr)
cmd[chan] |= CHAN_NOREC;
if (dcmd & 0200) /* Opcode L */
cmd[chan] |= CHAN_LOAD;
if ((dev >> 12) & 010) /* Check overlap operation */
cmd[chan] |= CHAN_OVLP;
else
cmd[chan] |= CHAN_WM; /* Force first char to have word mark set */
dcmd = (dcmd >> 8) & 0x7f;
chunit[chan] = dev;
chan_flags[chan] &= ~(CTL_CNTL|CTL_READ|CTL_WRITE|SNS_UEND|CTL_WRITE|CTL_SNS|STA_PEND);
chan_flags[chan] &= ~(CTL_CNTL|CTL_READ|CTL_WRITE|SNS_UEND|CTL_WRITE
|CTL_SNS|STA_PEND);
/* Handle disk device special */
if ((dsk_dib.mask & dev) == (dsk_dib.addr & dsk_dib.mask)) {
uint16 dsk_cmd = 0;
@@ -533,44 +560,25 @@ chan_write_char(int chan, uint8 * data, int flags)
{
uint8 ch = *data;
sim_debug(DEBUG_DATA, &chan_dev, "chan %d char %o %d %o %o\n", chan,
*data, caddr[chan], chan_io_status[chan], flags);
/* If Writing end of record, abort */
if (flags & DEV_WEOR) {
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d WEor %d %o ->", chan, caddr[chan],
chan_io_status[chan]);
if (chan_flags[chan] & DEV_REOR)
chan_io_status[chan] |= 0040;
else if (MEM_ADDR_OK(caddr[chan])) {
sim_debug(DEBUG_DETAIL, &chan_dev, "memok %02o %02o ", M[caddr[chan]], M[caddr[chan]+1]);
if ((cmd[chan] & CHAN_NOREC) == 0 && M[caddr[chan]] != (WM|077)) {
sim_debug(DEBUG_DETAIL, &chan_dev, "nogm ");
if (MEM_ADDR_OK(caddr[chan]+1))
chan_io_status[chan] |= 0040;
}
caddr[chan]++;
}
else
chan_io_status[chan] |= 0040;
chan_flags[chan] |= DEV_REOR;
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= DEV_DISCO;
chan_io_status[chan] |= 0100;
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
chan_flags[chan] &= ~(DEV_WEOR);
sim_debug(DEBUG_DETAIL, &chan_dev, "%d %o\n", caddr[chan], chan_io_status[chan]);
if (chan_flags[chan] & STA_WAIT) {
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d setWR %d %o\n", chan,
caddr[chan], chan_io_status[chan]);
chan_io_status[chan] |= IO_CHS_WRL;
return END_RECORD;
}
/* Check if end of data */
if ((chan_flags[chan] & DEV_REOR) == 0 &&
(cmd[chan] & CHAN_NOREC) == 0 &&
M[caddr[chan]] == (WM|077)) {
chan_flags[chan] |= DEV_REOR;
if ((chan_flags[chan] & STA_WAIT) == 0 && (cmd[chan] & CHAN_NOREC) == 0 &&
M[caddr[chan]] == (WM|077)) {
chan_flags[chan] |= STA_WAIT; /* Saw group mark */
chan_io_status[chan] |= IO_CHS_WRL;
caddr[chan]++;
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d GEor %d %o\n", chan, caddr[chan],
chan_io_status[chan]);
return DATA_OK;
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d GEor %d %o\n", chan,
caddr[chan], chan_io_status[chan]);
return END_RECORD;
}
/* If over size of memory, terminate */
@@ -578,10 +586,10 @@ chan_write_char(int chan, uint8 * data, int flags)
chan_flags[chan] |= DEV_REOR;
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= DEV_DISCO;
chan_io_status[chan] |= 0100;
chan_io_status[chan] |= IO_CHS_DONE;
caddr[chan]++;
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan, caddr[chan],
chan_io_status[chan]);
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d past mem %d %o\n", chan,
caddr[chan], chan_io_status[chan]);
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
return DATA_OK;
}
@@ -598,25 +606,16 @@ chan_write_char(int chan, uint8 * data, int flags)
if ((cmd[chan] & CHAN_LOAD) == 0)
ch |= M[caddr[chan]] & WM;
if ((chan_flags[chan] & DEV_REOR) == 0)
M[caddr[chan]] = ch;
M[caddr[chan]] = ch;
caddr[chan]++;
}
chan_io_status[chan] &= ~020;
/* If device gave us an end, terminate transfer */
if (flags & DEV_REOR) {
chan_flags[chan] |= DEV_REOR;
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= DEV_DISCO;
chan_io_status[chan] |= 0100;
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
if ((cmd[chan] & (CHAN_LOAD|CHAN_WM)) == (CHAN_WM|CHAN_LOAD))
M[caddr[chan]++] = 035;
caddr[chan]++;
if ((cmd[chan] & CHAN_NOREC) == 0 && M[caddr[chan]+1] != (WM|077))
chan_io_status[chan] |= 040;
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d Eor %d %o %x\n", chan, caddr[chan],
chan_io_status[chan], chan_flags[chan]);
sim_debug(DEBUG_DETAIL, &chan_dev, "chan %d Eor %d %o %x\n", chan,
caddr[chan], chan_io_status[chan], chan_flags[chan]);
return END_RECORD;
}
@@ -630,10 +629,11 @@ chan_write_char(int chan, uint8 * data, int flags)
int
chan_read_char(int chan, uint8 * data, int flags)
{
/* Return END_RECORD if requested */
if (flags & DEV_WEOR) {
chan_flags[chan] &= ~(DEV_WEOR);
chan_io_status[chan] |= 0100;
chan_io_status[chan] |= IO_CHS_DONE;
return END_RECORD;
}
@@ -648,7 +648,6 @@ chan_read_char(int chan, uint8 * data, int flags)
return END_RECORD;
*data &= 077;
caddr[chan]++;
chan_io_status[chan] &= ~020;
return DATA_OK;
}
@@ -665,13 +664,12 @@ chan_read_char(int chan, uint8 * data, int flags)
return END_RECORD;
}
assembly[chan] = M[caddr[chan]++];
chan_io_status[chan] &= ~020;
/* Handle end of record */
if ((cmd[chan] & CHAN_NOREC) == 0 && assembly[chan] == (WM|077)) {
chan_flags[chan] &= ~STA_ACTIVE;
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= DEV_DISCO;
chan_io_status[chan] |= 0100;
chan_io_status[chan] |= IO_CHS_DONE;
return END_RECORD;
}
if (cmd[chan] & CHAN_LOAD &&
@@ -691,7 +689,7 @@ chan_read_char(int chan, uint8 * data, int flags)
chan_flags[chan] &= ~(DEV_WRITE|STA_ACTIVE);
if (chan_flags[chan] & DEV_SEL)
chan_flags[chan] |= DEV_DISCO;
chan_io_status[chan] |= 0100;
chan_io_status[chan] |= IO_CHS_DONE;
chan_flags[chan] |= DEV_REOR;
return END_RECORD;
} else

View File

@@ -107,7 +107,7 @@ t_stat do_divide();
/* Interval timer option */
t_stat rtc_srv(UNIT * uptr);
t_stat rtc_reset(DEVICE * dptr);
int32 rtc_tps = 200;
/* General registers */
@@ -134,6 +134,7 @@ uint8 urec_irq[NUM_CHAN]; /* Unit record IRQ pending */
uint8 astmode = 1; /* Astrisk mode */
uint8 chan_io_status[NUM_CHAN]; /* Channel status */
uint8 chan_seek_done[NUM_CHAN]; /* Channel seek finished */
uint8 chan_irq_enb[NUM_CHAN]; /* IRQ type opcode */
uint8 lpr_chan9[NUM_CHAN]; /* Line printer at channel 9 */
uint8 lpr_chan12[NUM_CHAN]; /* Line printer at channel 12 */
extern uint32 caddr[NUM_CHAN]; /* Channel addresses */
@@ -145,10 +146,11 @@ uint8 prot_enb = 0; /* Protection enables */
uint8 relo_flags = 0; /* Relocation flags */
uint8 timer_irq = 0; /* Interval timer interrupt */
uint8 timer_enable = 0; /* Interval timer enable */
uint8 timer_interval = 0; /* Interval timer interval */
int timer_interval = 0; /* Interval timer interval */
int chwait = 0; /* Wait for channel to finish */
int io_flags = 0; /* Io flags for 1401 */
int cycle_time = 28; /* Cycle time in 100ns */
uint8 time_digs[] = {0, 2, 3, 5, 7, 8};
/* History information */
int32 hst_p = 0; /* History pointer */
@@ -156,6 +158,16 @@ int32 hst_lnt = 0; /* History length */
struct InstHistory *hst = NULL; /* History stack */
extern UNIT chan_unit[];
/* Simulator debug controls */
DEBTAB cpu_debug[] = {
{"CHANNEL", DEBUG_CHAN},
{"TRAP", DEBUG_TRAP},
{"CMD", DEBUG_CMD},
{"DETAIL", DEBUG_DETAIL},
{"EXP", DEBUG_EXP},
{"PRI", DEBUG_PRIO},
{0, 0}
};
@@ -227,7 +239,7 @@ DEVICE cpu_dev = {
"CPU", &cpu_unit, cpu_reg, cpu_mod,
1, 10, 18, 1, 8, 8,
&cpu_ex, &cpu_dep, &cpu_reset, NULL, NULL, NULL,
NULL, DEV_DEBUG, 0, dev_debug,
NULL, DEV_DEBUG, 0, cpu_debug,
NULL, NULL, &cpu_help, NULL, NULL, &cpu_description
};
@@ -547,8 +559,6 @@ void ClrBit(uint32 MA, uint8 v) {
t_stat
sim_instr(void)
{
time_t curtim;
struct tm *tptr;
t_stat reason;
uint16 t;
int temp;
@@ -1315,7 +1325,8 @@ sim_instr(void)
int irq = inquiry;
int ok_irq = 0;
for(i = 1; i < NUM_CHAN; i++ ) {
if ((chan_io_status[i] & 0300) == 0300)
if ((chan_io_status[i] & 0300) == 0300 &&
chan_irq_enb[i])
irq = 1;
if (chan_test(i, SNS_ATTN1))
irq = 1;
@@ -1377,6 +1388,7 @@ sim_instr(void)
}
if (ok_irq) {
sim_debug(DEBUG_PRIO, &cpu_dev, "Irq IAR=%d\n",IAR);
prot_enb = reloc = 0;
if (pri_enb && irq) {
IAR = temp;
@@ -1511,17 +1523,20 @@ sim_instr(void)
case CHR_G: temp = caddr[3]; break; /* G */
case CHR_H: temp = caddr[4]; break; /* H */
case CHR_T: /* T */
curtim = time(NULL); /* get time */
tptr = localtime(&curtim); /* decompose */
if (tptr == NULL)
break; /* error? */
{
time_t curtim;
struct tm *tptr;
/* Convert minutes to 100th hour */
temp = tptr->tm_min * 1000;
temp /= 60;
temp += 5; /* Round */
temp /= 10; /* Truncate low digit */
temp += tptr->tm_hour * 100;
temp = 99999;
curtim = time(NULL); /* get time */
tptr = localtime(&curtim); /* decompose */
if (tptr != NULL && tptr->tm_sec != 59) {
/* Convert minutes to 100th hour */
temp = time_digs[tptr->tm_min % 6];
temp += 10 * (tptr->tm_min / 6);
temp += 100 * tptr->tm_hour;
}
}
break;
default: temp = 0; break;
}
@@ -1954,7 +1969,7 @@ sim_instr(void)
jump = 1;
tind = 0;
} else {
for(i = 1; i <= NUM_CHAN && jump == 0; i++)
for(i = 1; i <= NUM_CHAN && jump == 0; i++)
jump = chan_stat(i, STA_PEND);
if (jump)
sim_debug(DEBUG_CMD, &cpu_dev, "Tape Ind\n");
@@ -1966,13 +1981,20 @@ sim_instr(void)
case CHR_STAR: /* * Inq req ch 2 */
break;
case CHR_1: /* 1 Overlap in Proc Ch 1 */
jump = chan_active(1);
jump = ((chan_io_status[1] & 0300) == 0200) &&
chan_active(1);
break;
case CHR_2: /* 2 Overlap in Proc Ch 2 */
jump = chan_active(2);
jump = ((chan_io_status[2] & 0300) == 0200) &&
chan_active(2);
break;
case CHR_4: /* 4 Channel 3 */
jump = ((chan_io_status[3] & 0300) == 0200) &&
chan_active(3);
break;
case CHR_RPARN: /* ) Channel 4 */
jump = chan_active(4);
jump = ((chan_io_status[4] & 0300) == 0200) &&
chan_active(4);
break;
case CHR_9: /* 9 Carriage 9 CH1 */ /* 1401 same */
jump = lpr_chan9[1];
@@ -2126,9 +2148,6 @@ sim_instr(void)
case OP_RD:
case OP_RDW:
/* Check if over the top */
ValidAddr(BAR);
/* Decode operands */
/* X1 digit 1 == channel 034 % non-overlap */
/* 2 == channel 074 sq non-overlap */
@@ -2146,7 +2165,7 @@ sim_instr(void)
/* F == Disk 066 */
/* K == Com 042 */
/* X3 digit device option or unit number */
/* op_mod R == Read 051 */
/* op_mod R == Read 051 */
/* $ == Read 053 ignore word/group */
/* W == Write 026 */
/* X == Write 027 ignore word/group */
@@ -2167,10 +2186,6 @@ sim_instr(void)
}
temp = ch << 12;
if (chan_io_status[ch & 07] & 0200) {
reason = STOP_IOCHECK;
break;
}
if ((XR & 07700) == 06200) {
if ((XR & 017) != 10)
temp |= XR & 017;
@@ -2183,13 +2198,6 @@ sim_instr(void)
temp |= XR & 07777;
}
while (chan_active(ch & 07) && reason == 0) {
sim_interval = 0;
reason = sim_process_event();
chan_proc();
}
if (reason != 0)
break;
switch(op_mod) {
case CHR_R: t = (IO_RDS << 8); break; /* R */
@@ -2207,6 +2215,14 @@ sim_instr(void)
if (reason != 0)
break;
while (chan_active(ch & 07) && reason == 0) {
sim_interval = 0;
reason = sim_process_event();
chan_proc();
}
if (reason != 0)
break;
if (op == OP_RDW)
t |= 0200;
if ((ch & 010) == 0)
@@ -2215,23 +2231,33 @@ sim_instr(void)
/* Try to start command */
switch (chan_cmd(temp, t, BAR & AMASK)) {
case SCPE_OK:
chan_io_status[ch & 07] = 0220;
if (ch & 010) {
chan_io_status[ch & 07] = 0;
chwait = ch & 07;
chan_irq_enb[ch & 7] = 0;
} else {
chan_io_status[ch & 07] = IO_CHS_OVER;
chan_irq_enb[ch & 7] = 1;
}
sim_debug(DEBUG_CMD, &cpu_dev,
"%d %c on %o %s %c\n", IAR, sim_six_to_ascii[op], ch & 07,
(ch & 010)?"":"overlap", sim_six_to_ascii[op_mod]);
"%d %c on %o %o %s %c\n", IAR, sim_six_to_ascii[op],
ch & 07, temp,
(ch & 010)?"":"overlap",
sim_six_to_ascii[op_mod]);
break;
case SCPE_BUSY:
chan_io_status[ch & 07] = 0002;
sim_debug(DEBUG_CMD, &cpu_dev,
"%d %c Busy on %o %s %c %o\n", IAR,
sim_six_to_ascii[op], ch & 07,
(ch & 010)?"": "overlap",
sim_six_to_ascii[op_mod], chan_io_status[ch & 07]);
chan_io_status[ch & 07] = IO_CHS_BUSY;
break;
case SCPE_NODEV:
case SCPE_IOERR:
chan_io_status[ch & 07] = 0001;
chan_io_status[ch & 07] = IO_CHS_NORDY;
break;
}
/* Handle waiting */
if ((ch & 010) && (chan_io_status[ch & 07] & 3) == 0)
chwait = ch & 07;
if (CPU_MODEL == 1)
chan_io_status[ch & 07] &= 0177;
break;
@@ -2243,16 +2269,17 @@ sim_instr(void)
chan_io:
switch (chan_cmd(temp, t, 0)) {
case SCPE_OK:
chan_io_status[ch & 07] = 0020;
chan_io_status[ch & 07] = 0000;
if (ch & 010)
chwait = (ch & 07) | 040;
chan_irq_enb[ch & 7] = 0;
break;
case SCPE_BUSY:
chan_io_status[ch & 07] = 0002;
chan_io_status[ch & 07] = IO_CHS_BUSY;
break;
case SCPE_NODEV:
case SCPE_IOERR:
chan_io_status[ch & 07] = 0001;
chan_io_status[ch & 07] = IO_CHS_NORDY;
break;
}
break;
@@ -2299,19 +2326,22 @@ sim_instr(void)
temp |= 02400;
t = 0;
switch(op_mod) {
case CHR_B: t = (IO_BSR << 8); ch &= 07; break;
case CHR_A: t = (IO_SKR << 8); ch &= 07; break;
case CHR_R: t = (IO_REW << 8); ch &= 07; break;
case CHR_GT: t = (IO_RUN << 8); ch &= 07; break;
case CHR_E: t = (IO_ERG << 8); ch &= 07; break;
case CHR_B: t = (IO_BSR << 8); ch |= 010; break;
case CHR_A: t = (IO_SKR << 8); ch |= 010; break;
case CHR_R: t = (IO_REW << 8); ch |= 010; break;
case CHR_GT: t = (IO_RUN << 8); ch |= 010; break;
case CHR_E: t = (IO_ERG << 8); ch |= 010; break;
case CHR_M: t = (IO_WEF << 8); break;
default: t = 0; reason = STOP_UUO; break;
}
if (chan_io_status[ch & 07] & 0200) {
reason = STOP_IOCHECK;
break;
while (chan_active(ch & 07) && reason == 0) {
sim_interval = 0;
reason = sim_process_event();
chan_proc();
}
if (reason != 0)
break;
/* For nop, set command done */
if (t == 0) {
chan_io_status[ch & 07] = 0000;
@@ -2323,24 +2353,27 @@ sim_instr(void)
chan_io_status[ch & 07] = 0000;
if (ch & 010) {
chwait = (ch & 07) | 040;
} else if (op_mod == CHR_M) {
chan_io_status[ch & 07] = IO_CHS_OVER;
}
chan_irq_enb[ch & 7] = 0;
sim_debug(DEBUG_CMD, &cpu_dev,
"%d UC on %o %s %c\n", IAR, ch & 07,
(ch & 010)?"": "overlap", sim_six_to_ascii[op_mod]);
"%d UC on %o %o %s %c %o\n", IAR, ch & 07, temp,
(ch & 010)?"": "overlap",
sim_six_to_ascii[op_mod], chan_io_status[ch & 07]);
break;
case SCPE_BUSY:
sim_debug(DEBUG_CMD, &cpu_dev,
"%d UC on %o %c Busy\n", IAR, ch & 07, sim_six_to_ascii[op_mod]);
chan_io_status[ch & 07] = 0002;
chan_io_status[ch & 07] = IO_CHS_BUSY;
break;
case SCPE_NODEV:
case SCPE_IOERR:
chan_io_status[ch & 07] = 0001;
chan_io_status[ch & 07] = IO_CHS_NORDY;
break;
}
if (CPU_MODEL == 1)
chan_io_status[ch & 07] &= 0177;
sim_interval -= 100;
break;
case OP_IO1:
@@ -2351,7 +2384,9 @@ sim_instr(void)
if (chan_io_status[ch] & op_mod) {
jump = 1;
}
chan_io_status[ch] &= 077; /* Clear interlock */
chan_io_status[ch] &= 077;
sim_debug(DEBUG_CMD, &cpu_dev, "Check chan %d %o %x\n", ch,
chan_io_status[ch], chan_flags[ch]);
break;
case OP_IO2:
@@ -3051,6 +3086,7 @@ sim_instr(void)
/* Priority mode operations */
case OP_PRI:
jump = 0;
switch(op_mod) {
case CHR_U: /* U branch if ch 1 i-o unit priority */
jump = urec_irq[1];
@@ -3061,16 +3097,20 @@ sim_instr(void)
urec_irq[2] = 0;
break;
case CHR_1: /* 1 branch if ch 1 overlap priority */
jump = chan_io_status[1] & 0100;
if (chan_irq_enb[1])
jump = (chan_io_status[1] & 0300) == 0300;
break;
case CHR_2: /* 2 branch if ch 2 overlap priority */
jump = chan_io_status[2] & 0100;
if (chan_irq_enb[2])
jump = (chan_io_status[2] & 0300) == 0300;
break;
case CHR_3: /* 3 branch if ch 3 overlap priority */
jump = chan_io_status[3] & 0100;
if (chan_irq_enb[3])
jump = (chan_io_status[3] & 0300) == 0300;
break;
case CHR_4: /* 4 branch if ch 4 overlap priority */
jump = chan_io_status[4] & 0100;
if (chan_irq_enb[4])
jump = (chan_io_status[4] & 0300) == 0300;
break;
case CHR_Q: /* Q branch if inquiry ch 1 */
jump = inquiry;
@@ -3099,10 +3139,12 @@ sim_instr(void)
break;
case CHR_X: /* X branch and exit */
pri_enb = 0;
sim_debug(DEBUG_PRIO, &cpu_dev, "dis irq\n");
jump = 1;
break;
case CHR_E: /* E branch and enter */
pri_enb = 1;
sim_debug(DEBUG_PRIO, &cpu_dev, "enb irq\n");
jump = 1;
break;
case CHR_A: /* A branch if ch1 attention */
@@ -3269,7 +3311,7 @@ sim_instr(void)
case CHR_QUOT: /* ' Turn on 20ms timer */
if (cpu_unit.flags & OPTION_PROT) {
timer_enable = 1;
timer_interval = 20;
timer_interval = 10;
timer_irq = 0;
sim_debug(DEBUG_DETAIL, &cpu_dev, "Timer start\n");
}
@@ -3717,13 +3759,17 @@ do_divide()
t_stat
rtc_srv(UNIT * uptr)
{
int32 t;
t = sim_rtcn_calb (rtc_tps, TMR_RTC);
sim_activate_after(uptr, 1000000/rtc_tps);
if (timer_enable) {
if (--timer_interval == 0) {
timer_irq |= 1;
timer_interval = 20;
timer_interval = 10;
}
}
sim_activate(&cpu_unit, sim_rtcn_calb(uptr->wait, TMR_RTC));
return SCPE_OK;
}

View File

@@ -121,3 +121,13 @@ int chan_cmd(uint16 dev, uint16 cmd, uint32 addr);
/* S - Floating sub */
/* M - Floating mul */
/* D - Floating div */
/* Flags for chan_io_status. */
#define IO_CHS_NORDY 0001 /* Unit not Ready */
#define IO_CHS_BUSY 0002 /* Unit or channel Busy */
#define IO_CHS_CHECK 0004 /* Data check */
#define IO_CHS_COND 0010 /* Condition */
#define IO_CHS_NOTR 0020 /* No transfer */
#define IO_CHS_WRL 0040 /* Wrong length */
#define IO_CHS_DONE 0100 /* Device done */
#define IO_CHS_OVER 0200 /* Channel busy on overlap processing */

View File

@@ -101,16 +101,16 @@ DIB lpr_dib = { CH_TYP_UREC, 1, 00200, 07700, &lpr_cmd, &lpr_ini };
DIB con_dib = { CH_TYP_UREC, 1, 02300, 07700, &con_cmd, &con_ini };
#endif
#ifdef NUM_DEVS_MT
DIB mt_dib = { CH_TYP_76XX|CH_TYP_UREC, NUM_UNITS_MT, 02400, 07700, &mt_cmd, &mt_ini };
DIB mt_dib = { CH_TYP_UREC, NUM_UNITS_MT, 02400, 07700, &mt_cmd, &mt_ini };
#endif
#ifdef NUM_DEVS_CHRON
DIB chron_dib = { CH_TYP_76XX|CH_TYP_UREC, 1, 02400, 07700, &chron_cmd, NULL };
DIB chron_dib = { CH_TYP_UREC, 1, 02400, 07700, &chron_cmd, NULL };
#endif
#ifdef NUM_DEVS_DSK
DIB dsk_dib = { CH_TYP_79XX, 0, 06600, 07700, &dsk_cmd, &dsk_ini };
DIB dsk_dib = { CH_TYP_79XX|CH_TYP_UREC, 0, 06600, 07700, &dsk_cmd, &dsk_ini };
#endif
#ifdef NUM_DEVS_COM
DIB com_dib = { CH_TYP_79XX, 0, 04200, 07700, &com_cmd, NULL };
DIB com_dib = { CH_TYP_79XX|CH_TYP_UREC, 0, 04200, 07700, &com_cmd, NULL };
#endif
@@ -336,8 +336,8 @@ t_opcode base_ops[] = {
{OP_IO2|MOD(002), "BCB2", TYPE_B},
{OP_IO2|MOD(004), "BER2", TYPE_B},
{OP_IO2|MOD(010), "BEF2", TYPE_B},
{OP_IO2|MOD(020), "BWL2", TYPE_B},
{OP_IO2|MOD(040), "BNT2", TYPE_B},
{OP_IO2|MOD(020), "BNT2", TYPE_B},
{OP_IO2|MOD(040), "BWL2", TYPE_B},
{OP_IO2|MOD(000), "BEX2", TYPE_B},
{OP_IO2|MOD(000), "BEX2", TYPE_BE},
{OP_IO3|MOD(077), "BA3", TYPE_B},
@@ -345,8 +345,8 @@ t_opcode base_ops[] = {
{OP_IO3|MOD(002), "BCB3", TYPE_B},
{OP_IO3|MOD(004), "BER3", TYPE_B},
{OP_IO3|MOD(010), "BEF3", TYPE_B},
{OP_IO3|MOD(020), "BWL3", TYPE_B},
{OP_IO3|MOD(040), "BNT3", TYPE_B},
{OP_IO3|MOD(020), "BNT3", TYPE_B},
{OP_IO3|MOD(040), "BWL3", TYPE_B},
{OP_IO3|MOD(000), "BEX3", TYPE_B},
{OP_IO3|MOD(000), "BEX3", TYPE_BE},
{OP_IO4|MOD(077), "BA4", TYPE_B},
@@ -354,8 +354,8 @@ t_opcode base_ops[] = {
{OP_IO4|MOD(002), "BCB4", TYPE_B},
{OP_IO4|MOD(004), "BER4", TYPE_B},
{OP_IO4|MOD(010), "BEF4", TYPE_B},
{OP_IO4|MOD(020), "BWL4", TYPE_B},
{OP_IO4|MOD(040), "BNT4", TYPE_B},
{OP_IO4|MOD(020), "BNT4", TYPE_B},
{OP_IO4|MOD(040), "BWL4", TYPE_B},
{OP_IO4|MOD(000), "BEX4", TYPE_B},
{OP_IO4|MOD(000), "BEX4", TYPE_BE},
{OP_A, "A", TYPE_2},