1
0
mirror of https://github.com/rcornwell/sims.git synced 2026-03-27 02:14:49 +00:00

I7000: Major cleanup to pass diagnostics. And to support Front Panel.

This commit is contained in:
Richard Cornwell
2017-08-30 23:54:40 -04:00
parent 92fddad227
commit 2aa118cdbd
13 changed files with 565 additions and 486 deletions

View File

@@ -50,21 +50,6 @@
cdp_mod Card Punch modifiers list
*/
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_CARD 0004 /* Unit has card in buffer */
#define URCSTA_FULL 0004 /* Unit has full buffer */
#define URCSTA_BUSY 0010 /* Device is busy */
#define URCSTA_WDISCO 0020 /* Device is wait for disconnect */
#define URCSTA_READ 0040 /* Device is reading channel */
#define URCSTA_WRITE 0100 /* Device is reading channel */
#define URCSTA_INPUT 0200 /* Console fill buffer from keyboard */
#define URCSTA_WMKS 0400 /* Printer print WM as 1 */
#define URCSTA_SKIPAFT 01000 /* Skip to line after printing next line */
#define URCSTA_NOXFER 01000 /* Don't set up to transfer after feed */
#define URCSTA_LOAD 01000 /* Load flag for 7070 card reader */
uint32 cdp_cmd(UNIT *, uint16, uint16);
void cdp_ini(UNIT *, t_bool);
t_stat cdp_srv(UNIT *);

View File

@@ -50,21 +50,6 @@
cdr_mod Card Reader modifiers list
*/
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_CARD 0004 /* Unit has card in buffer */
#define URCSTA_FULL 0004 /* Unit has full buffer */
#define URCSTA_BUSY 0010 /* Device is busy */
#define URCSTA_WDISCO 0020 /* Device is wait for disconnect */
#define URCSTA_READ 0040 /* Device is reading channel */
#define URCSTA_WRITE 0100 /* Device is reading channel */
#define URCSTA_INPUT 0200 /* Console fill buffer from keyboard */
#define URCSTA_WMKS 0400 /* Printer print WM as 1 */
#define URCSTA_SKIPAFT 01000 /* Skip to line after printing next line */
#define URCSTA_NOXFER 01000 /* Don't set up to transfer after feed */
#define URCSTA_LOAD 01000 /* Load flag for 7070 card reader */
uint32 cdr_cmd(UNIT *, uint16, uint16);
t_stat cdr_boot(int32, DEVICE *);
t_stat cdr_srv(UNIT *);

View File

@@ -320,6 +320,23 @@ extern uint8 lpr_chan12[NUM_CHAN];
#define DEV_DISCO 0x40000000 /* Channel is done with device */
#define DEV_WEOR 0x80000000 /* Channel wants EOR written */
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_CARD 0004 /* Unit has card in buffer */
#define URCSTA_FULL 0004 /* Unit has full buffer */
#define URCSTA_BUSY 0010 /* Device is busy */
#define URCSTA_WDISCO 0020 /* Device is wait for disconnect */
#define URCSTA_READ 0040 /* Device is reading channel */
#define URCSTA_WRITE 0100 /* Device is reading channel */
#define URCSTA_INPUT 0200 /* Console fill buffer from keyboard */
#define URCSTA_ON 0200 /* 7090 Unit is on */
#define URCSTA_IDLE 0400 /* 7090 Unit is idle */
#define URCSTA_WMKS 0400 /* Printer print WM as 1 */
#define URCSTA_SKIPAFT 01000 /* Skip to line after printing next line */
#define URCSTA_NOXFER 01000 /* Don't set up to transfer after feed */
#define URCSTA_LOAD 01000 /* Load flag for 7070 card reader */
#define URCSTA_CMD 01000 /* 7090 Command recieved */
/* Boot from given device */
t_stat chan_boot(int32 unit_num, DEVICE *dptr);

View File

@@ -57,21 +57,6 @@
lpr_mod Line Printer modifiers list
*/
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define URCSTA_CARD 0004 /* Unit has card in buffer */
#define URCSTA_FULL 0004 /* Unit has full buffer */
#define URCSTA_BUSY 0010 /* Device is busy */
#define URCSTA_WDISCO 0020 /* Device is wait for disconnect */
#define URCSTA_READ 0040 /* Device is reading channel */
#define URCSTA_WRITE 0100 /* Device is reading channel */
#define URCSTA_INPUT 0200 /* Console fill buffer from keyboard */
#define URCSTA_WMKS 0400 /* Printer print WM as 1 */
#define URCSTA_SKIPAFT 01000 /* Skip to line after printing next line */
#define URCSTA_NOXFER 01000 /* Don't set up to transfer after feed */
#define URCSTA_LOAD 01000 /* Load flag for 7070 card reader */
struct _lpr_data
{

View File

@@ -48,12 +48,10 @@
UNIT_S_CHAN(x)
#define MTUF_LDN (1 << MTUF_V_UF)
#define MTUF_ONLINE (1 << UNIT_V_UF_31)
#define LT 66 /* Time per char low density */
#define HT 16 /* Time per char high density */
/* in u3 is device address */
/* in u4 is current buffer position */
/* in u5 */
/* in u3 is current frame of tape */
/* in u5 holds the commands */
#define MT_RDS 1
#define MT_RDSB 2
#define MT_WRS 3
@@ -69,18 +67,49 @@
#define MT_SKR 13
#define MT_ERG 14
#define MT_RDB 15
#define MT_CMDMSK 000017 /* Command being run */
#define MT_RDY 000020 /* Device is ready for command */
#define MT_IDLE 000040 /* Tape still in motion */
#define MT_MARK 000100 /* Hit tape mark */
#define MT_EOT 000200 /* At End Of Tape */
#define MT_RM 000400 /* Hit a record mark character */
#define MT_EOR 001000 /* Set EOR on next record */
#define MT_LREW 16 /* Low speed rewind */
#define MT_HREW 17 /* High speed rewind */
#define MT_CMDMSK 000037 /* Command being run */
#define MT_RDY 000040 /* Device is ready for command */
#define MT_IDLE 000100 /* Tape still in motion */
#define MT_MARK 000200 /* Hit tape mark */
#define MT_EOT 000400 /* At End Of Tape */
#define MT_RM 001000 /* Hit a record mark character */
#define MT_EOR 002000 /* Set EOR on next record */
#define MT_UNLOAD 004000 /* Unload when rewind done */
/* u6 holds the current buffer position */
/* Flags for mt_chan */
#define MTC_SEL 0020 /* Controller executing read/write */
#define MTC_BSY 0040 /* Controller is busy - executing cmd */
#define MTC_UNIT 0017 /* device Channel is on */
/* Timing for tape */
#define IPS 75 /* Inches per second 75 or 112 */
#define HS_IPS 500 /* High speed rewind Inches per second */
#define LD 200
#define HD 555
#define LT_GAP_LEN ((3 * LD)/ 4) /* Gap length for low density */
#define HT_GAP_LEN ((3 * HD)/ 4) /* Gap length for high density */
#define LT (1000000/(LD * IPS)) /* Time per char low density */
#define HT (1000000/(HD * IPS)) /* Time per char high density */
#define LT_GAP_TIM (LT_GAP_LEN * LT) /* Time per char low density */
#define HT_GAP_TIM (HT_GAP_LEN * HT) /* Time per char high density */
/* Normal frame time */
#define T1 ((uptr->flags & MTUF_LDN) ?LT:HT)
#define T1_us us_to_ticks(T1)
/* Gap time */
#define T2 ((uptr->flags & MTUF_LDN) ?LT_GAP_TIM:HT_GAP_TIM)
#define T2_us us_to_ticks(T2)
/* Start time */
#define T3 (((uptr->flags & MTUF_LDN) ?LT_GAP_TIM:HT_GAP_TIM) + 500)
#define T3_us us_to_ticks(T3)
#define GAP_LEN ((uptr->flags & MTUF_LDN) ?LT_GAP_LEN:HT_GAP_LEN)
/* Definitions */
uint32 mt_cmd(UNIT *, uint16, uint16);
t_stat mt_srv(UNIT *);
t_stat mt_boot(int32, DEVICE *);
@@ -375,8 +404,13 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
return SCPE_BUSY;
}
uptr->u5 &= ~(MT_CMDMSK | MT_RDY);
time = us_to_ticks(12000);
if ((uptr->u5 & MT_IDLE) == 0)
time = us_to_ticks(15000);
switch (cmd) {
case IO_RDS:
if (sim_tape_bot(uptr))
time = us_to_ticks(21000);
if (mt_chan[chan] & MTC_SEL) {
uptr->u5 |= MT_RDY;
return SCPE_BUSY;
@@ -390,11 +424,6 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
else
uptr->u5 |= MT_RDS;
#endif
time = us_to_ticks(3000);
if ((uptr->u5 & MT_IDLE) == 0)
time = us_to_ticks(4500);
if (sim_tape_bot(uptr))
time = us_to_ticks(21000);
chan_set_sel(chan, 0);
chan_clear_status(chan);
mt_chan[chan] &= MTC_BSY;
@@ -411,6 +440,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
unit, dev);
break;
case IO_WRS:
if (sim_tape_bot(uptr))
time = us_to_ticks(40000);
if (mt_chan[chan] & MTC_SEL) {
uptr->u5 |= MT_RDY;
return SCPE_BUSY;
@@ -429,6 +460,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
else
uptr->u5 |= MT_WRS;
#endif
time += T2_us;
uptr->u6 = 0;
uptr->hwmark = 0;
chan_set_sel(chan, 1);
@@ -436,11 +468,6 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
mt_chan[chan] &= MTC_BSY;
mt_chan[chan] |= MTC_SEL | unit;
uptr->u5 &= ~(MT_MARK | MT_EOT);
time = us_to_ticks(6500);
if ((uptr->u5 & MT_IDLE) == 0)
time = us_to_ticks(10000);
if (sim_tape_bot(uptr))
time = us_to_ticks(41000);
sim_debug(DEBUG_CMD, dptr, "WRS %s unit=%d %d\n",
((uptr->u5 & MT_CMDMSK) == MT_WRS) ? "BCD" : "Binary",
unit, dev);
@@ -452,11 +479,6 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
}
uptr->u5 |= MT_RDB;
time = us_to_ticks(3000);
if ((uptr->u5 & MT_IDLE) == 0)
time = us_to_ticks(4500);
if (sim_tape_bot(uptr))
time = us_to_ticks(20000);
chan_set_sel(chan, 0);
chan_clear_status(chan);
mt_chan[chan] &= MTC_BSY;
@@ -468,6 +490,8 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
break;
case IO_WEF:
if (sim_tape_bot(uptr))
time = us_to_ticks(40000);
uptr->u5 &= ~(MT_EOT|MT_MARK);
if (sim_tape_wrp(uptr)) {
sim_debug(DEBUG_EXP, dptr,
@@ -475,8 +499,6 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
uptr->u5 |= MT_RDY;
return SCPE_IOERR;
}
if ((uptr->u5 & MT_IDLE) == 0)
time = us_to_ticks(2700);
uptr->u5 |= MT_WEF;
mt_chan[chan] |= MTC_BSY;
sim_debug(DEBUG_CMD, dptr, "WEF unit=%d\n", unit);
@@ -488,6 +510,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
if (sim_tape_bot(uptr)) {
sim_debug(DEBUG_CMD, dptr, "BSR unit=%d at BOT\n", unit);
uptr->u5 |= MT_RDY;
uptr->u3 = 0;
chan_set(chan, CHS_BOT);
return SCPE_OK;
}
@@ -501,6 +524,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
if (sim_tape_bot(uptr)) {
sim_debug(DEBUG_CMD, dptr, "BSF unit=%d at BOT\n", unit);
uptr->u5 |= MT_RDY;
uptr->u3 = 0;
chan_set(chan, CHS_BOT);
return SCPE_OK;
}
@@ -528,11 +552,13 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
if (sim_tape_bot(uptr)) {
sim_debug(DEBUG_CMD, dptr, "REW unit=%d at BOT\n", unit);
uptr->u5 |= MT_RDY;
uptr->u3 = 0;
#ifdef I7010
chan_set(chan, CHS_BOT);
#endif
return SCPE_OK;
}
time = us_to_ticks(10000);
uptr->u5 |= MT_REW;
mt_chan[chan] |= MTC_BSY;
sim_debug(DEBUG_CMD, dptr, "REW unit=%d\n", unit);
@@ -542,6 +568,7 @@ uint32 mt_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
chan_clear_status(chan);
uptr->u5 |= MT_RUN;
mt_chan[chan] |= MTC_BSY;
time = us_to_ticks(10000);
sim_debug(DEBUG_CMD, dptr, "RUN unit=%d\n", unit);
break;
case IO_SDL:
@@ -696,24 +723,31 @@ t_stat mt_srv(UNIT * uptr)
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\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen);
"Write flush unit=%d %s Block %d chars %d\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
mt_error(uptr, chan, r, dptr); /* Record errors */
#ifndef I7010
}
#endif
sim_activate(uptr, us_to_ticks(6000));
sim_activate(uptr, us_to_ticks(T2));
mt_chan[chan] &= MTC_BSY;
uptr->u5 |= MT_RDY;
} else if (cmd == MT_RDS || cmd == MT_RDSB) {
sim_debug(DEBUG_DETAIL, dptr,
"Read flush unit=%d %s Block %d chars %d\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3);
/* Keep moving until end of block */
if (uptr->u6 < (int32)uptr->hwmark ) {
int i = (uptr->hwmark-uptr->u6) *
((uptr->flags & MTUF_LDN) ?LT:HT);
uptr->u5 |= MT_SKIP;
sim_activate(uptr, us_to_ticks(i));
uptr->u3 += uptr->hwmark-uptr->u6;
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);
return SCPE_OK;
} else {
#ifndef I7010
if (uptr->u5 & MT_MARK) {
@@ -722,14 +756,15 @@ t_stat mt_srv(UNIT * uptr)
/* This is due to SIMH returning mark after read */
(void) sim_tape_sprecr(uptr, &reclen);
uptr->u5 &= ~MT_MARK;
uptr->u3 -= GAP_LEN + reclen;
}
#endif
sim_activate(uptr, us_to_ticks(6000));
sim_activate(uptr, us_to_ticks(T2));
uptr->u5 |= MT_RDY;
mt_chan[chan] &= MTC_BSY;
}
} else {
sim_activate(uptr, us_to_ticks(100));
sim_activate(uptr, us_to_ticks(T2));
#ifndef I7010
uptr->u5 |= MT_RDY;
#endif
@@ -746,9 +781,9 @@ t_stat mt_srv(UNIT * uptr)
return SCPE_OK;
}
uptr->u5 &= ~MT_IDLE;
switch (cmd) {
case 0: /* No command, stop tape */
uptr->u5 &= ~MT_IDLE;
uptr->u5 |= MT_RDY; /* Ready since command is done */
#ifdef I7080
chan_clear(chan, STA_TWAIT);
@@ -769,9 +804,8 @@ t_stat mt_srv(UNIT * uptr)
chan_clear(chan, DEV_SEL);
#endif /* TEST */
mt_chan[chan] &= MTC_BSY; /* Clear all but busy */
sim_debug(DEBUG_DETAIL, dptr, "Skip unit=%d\n", unit);
sim_activate(uptr,
(uptr->flags & MTUF_LDN) ? us_to_ticks(2500): us_to_ticks(4250));
sim_debug(DEBUG_DETAIL, dptr, "Skip unit=%d %d\n", unit, uptr->u3);
sim_activate(uptr, T2_us);
return SCPE_OK;
case MT_RDS:
@@ -785,8 +819,7 @@ t_stat mt_srv(UNIT * uptr)
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d post EOR\n", unit);
chan_set(chan, DEV_REOR);
uptr->u5 &= ~ MT_EOR;
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250): us_to_ticks(2500));
sim_activate(uptr, T1_us);
return SCPE_OK;
}
#endif
@@ -811,14 +844,13 @@ 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 ", unit);
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d %d", unit,uptr->u3);
uptr->u3 += GAP_LEN;
if ((r = sim_tape_rdrecf(uptr, &mt_buffer[bufnum][0], &reclen,
BUFFSIZE)) != MTSE_OK) {
sim_activate(uptr, us_to_ticks(100));
if (r == MTSE_TMK && uptr->u6 != -1) {
sim_debug(DEBUG_DETAIL, dptr, "pend TM\n");
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250): us_to_ticks(2500));
// sim_activate(uptr, T1_us);
uptr->u5 |= MT_MARK;
r = MTSE_OK;
} else {
@@ -839,6 +871,7 @@ t_stat mt_srv(UNIT * uptr)
#endif
chan_set_attn(chan);
}
sim_activate(uptr, T1_us);
return mt_error(uptr, chan, r, dptr);
}
uptr->u6 = 0;
@@ -849,6 +882,7 @@ t_stat mt_srv(UNIT * uptr)
}
ch = mt_buffer[bufnum][uptr->u6++];
uptr->u3++;
/* Do BCD translation */
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
#ifdef I7010
@@ -878,68 +912,56 @@ t_stat mt_srv(UNIT * uptr)
ch &= 077;
/* Convert one word. */
switch (chan_write_char(chan, &ch,
switch (chan_write_char(chan, &ch,
#ifdef I7010
(uptr->u6 >= (int32)uptr->hwmark) ? DEV_REOR : 0
(uptr->u6 >= (int32)uptr->hwmark) ? DEV_REOR : 0
#else
0
0
#endif
)) {
case END_RECORD:
sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n", unit);
/* If not read whole record, skip till end */
)) {
case END_RECORD:
sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n", unit);
/* If not read whole record, skip till end */
#ifndef I7010
uptr->u5 |= MT_EOR;
#endif
if (uptr->u6 < (int32)uptr->hwmark) {
sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us);
#ifdef I7010
chan_set(chan, DEV_REOR);
#endif
uptr->u3 += (uptr->hwmark - uptr->u6);
uptr->u6 = uptr->hwmark; /* Force read next record */
#ifdef I7010
break;
}
#else
} else
sim_activate(uptr, T1_us);
break;
#endif
case DATA_OK:
sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %02o\n",
unit, uptr->u6, ch);
if (uptr->u6 >= (int32)uptr->hwmark) { /* In IRG */
#ifndef I7010
uptr->u5 |= MT_EOR;
#endif
if (uptr->u6 < (int32)uptr->hwmark) {
#ifdef I7010
sim_activate(uptr, (uptr->hwmark-uptr->u6) * 20);
#else
int i = (uptr->hwmark-uptr->u6) *
((uptr->flags & MTUF_LDN) ?LT:HT);
i += (uptr->flags & MTUF_LDN) ? 100 : 50;
sim_activate(uptr, us_to_ticks(i));
#endif
#ifdef I7010
chan_set(chan, DEV_REOR);
#endif
uptr->u6 = uptr->hwmark; /* Force read next record */
#ifdef I7010
break;
}
#else
} else
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(150): us_to_ticks(100));
break;
#endif
sim_activate(uptr, T1_us);
} else
sim_activate(uptr, T1_us);
break;
case DATA_OK:
sim_debug(DEBUG_DATA, dptr, "Read data unit=%d %d %02o\n",
unit, uptr->u6, ch);
if (uptr->u6 >= (int32)uptr->hwmark) { /* In IRG */
#ifndef I7010
uptr->u5 |= MT_EOR;
#endif
sim_activate(uptr,
(uptr->flags & MTUF_LDN) ?
us_to_ticks(150): us_to_ticks(100));
} else
sim_activate(uptr,
(uptr->flags & MTUF_LDN) ?
us_to_ticks(LT): us_to_ticks(HT));
break;
case TIME_ERROR:
uptr->u5 &= ~MT_CMDMSK;
uptr->u5 |= MT_SKIP;
sim_activate(uptr,
us_to_ticks(((uptr->flags & MTUF_LDN) ?4250:2500) +
((uptr->hwmark-uptr->u6) *
((uptr->flags & MTUF_LDN) ?LT:HT))));
uptr->u6 = uptr->hwmark; /* Force read next record */
break;
}
case TIME_ERROR:
sim_debug(DEBUG_DATA, dptr, "Read unit=%d timeout\n", unit);
uptr->u3 += (uptr->hwmark - uptr->u6);
uptr->u5 &= ~MT_CMDMSK;
uptr->u5 |= MT_SKIP;
sim_activate(uptr, ((uptr->hwmark - uptr->u6) * T1_us) + T2_us);
uptr->u6 = uptr->hwmark; /* Force read next record */
break;
}
return SCPE_OK;
@@ -964,16 +986,16 @@ 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\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen);
"Write unit=%d %s Block %d chars %d\n",
unit, (cmd == MT_WRS) ? "BCD" : "Binary", reclen, uptr->u3);
r = sim_tape_wrrecf(uptr, &mt_buffer[bufnum][0], reclen);
uptr->u3 += GAP_LEN;
uptr->u6 = 0;
uptr->hwmark = 0;
mt_error(uptr, chan, r, dptr); /* Record errors */
}
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250): us_to_ticks(2500));
break;
sim_activate(uptr, T2_us);
return SCPE_OK;
case DATA_OK:
/* Copy data to buffer */
ch &= 077;
@@ -988,13 +1010,13 @@ t_stat mt_srv(UNIT * uptr)
#endif
ch |= mode ^ parity_table[ch] ^ 0100;
mt_buffer[bufnum][uptr->u6++] = ch;
uptr->u3++;
sim_debug(DEBUG_DATA, dptr, "Write data unit=%d %d %02o\n",
unit, uptr->u6, ch);
uptr->hwmark = uptr->u6;
break;
}
sim_activate(uptr,
(uptr->flags & MTUF_LDN) ? us_to_ticks(LT): us_to_ticks(HT));
sim_activate(uptr, T1_us);
return SCPE_OK;
case MT_RDB:
@@ -1012,7 +1034,8 @@ t_stat mt_srv(UNIT * uptr)
sim_debug(DEBUG_DETAIL, dptr, "Read unit=%d ", unit);
if ((r = sim_tape_rdrecr(uptr, &mt_buffer[bufnum][0], &reclen,
BUFFSIZE)) != MTSE_OK) {
sim_activate(uptr, us_to_ticks(100));
uptr->u3 -= GAP_LEN;
sim_activate(uptr, T2_us);
if (r == MTSE_TMK && uptr->u6 != -1) {
sim_debug(DEBUG_DETAIL, dptr, "pend TM\n");
uptr->u5 |= MT_MARK;
@@ -1033,6 +1056,7 @@ t_stat mt_srv(UNIT * uptr)
}
ch = mt_buffer[bufnum][uptr->u6++];
uptr->u3--;
/* Do BCD translation */
if ((parity_table[ch & 077] ^ (ch & 0100) ^ mode) == 0) {
chan_set_error(chan);
@@ -1042,64 +1066,61 @@ t_stat mt_srv(UNIT * uptr)
ch &= 077;
/* Convert one word. */
switch (chan_write_char(chan, &ch,
(uptr->u6 >= (int32)uptr->hwmark) ? DEV_REOR : 0)) {
case END_RECORD:
sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n", unit);
if (uptr->u6 >= (int32)uptr->hwmark) {
uptr->u5 &= ~MT_CMDMSK;
uptr->u5 |= MT_SKIP;
sim_activate(uptr,
us_to_ticks(((uptr->hwmark-uptr->u6) *
((uptr->flags & MTUF_LDN) ?LT:HT))));
chan_set(chan, DEV_REOR);
uptr->u6 = uptr->hwmark; /* Force read next record */
break;
}
/* fall through */
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 */
sim_activate(uptr,
(uptr->flags & MTUF_LDN) ?
us_to_ticks(4250): us_to_ticks(2500));
} else
sim_activate(uptr,
(uptr->flags & MTUF_LDN) ?
us_to_ticks(LT): us_to_ticks(HT));
break;
case TIME_ERROR:
switch (chan_write_char(chan, &ch,
(uptr->u6 >= (int32)uptr->hwmark) ? DEV_REOR : 0)) {
case END_RECORD:
sim_debug(DEBUG_DATA, dptr, "Read unit=%d EOR\n", unit);
if (uptr->u6 >= (int32)uptr->hwmark) {
uptr->u5 &= ~MT_CMDMSK;
uptr->u5 |= MT_SKIP;
sim_activate(uptr,
us_to_ticks(((uptr->hwmark-uptr->u6) *
((uptr->flags & MTUF_LDN) ?LT:HT))));
uptr->u6 = uptr->hwmark; /* Force read next record */
uptr->u3 -= (uptr->hwmark-uptr->u6);
sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us);
chan_set(chan, DEV_REOR);
uptr->u6 = uptr->hwmark; /* Force read next record */
break;
}
/* fall through */
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 */
uptr->u3 -= (uptr->hwmark-uptr->u6);
sim_activate(uptr, T2_us);
} else
sim_activate(uptr, T1_us);
break;
case TIME_ERROR:
uptr->u5 &= ~MT_CMDMSK;
uptr->u5 |= MT_SKIP;
uptr->u3 -= (uptr->hwmark-uptr->u6);
sim_activate(uptr, (uptr->hwmark-uptr->u6) * T1_us);
uptr->u6 = uptr->hwmark; /* Force read next record */
break;
}
return SCPE_OK;
case MT_WEF:
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d\n", unit);
sim_debug(DEBUG_DETAIL, dptr, "Write Mark unit=%d %d\n", unit, uptr->u3);
uptr->u5 &= ~(MT_CMDMSK|MT_MARK);
uptr->u5 |= (MT_RDY | MT_IDLE);
uptr->u5 |= (MT_RDY);
r = sim_tape_wrtmk(uptr);
uptr->u3 += GAP_LEN;
mt_chan[chan] &= ~MTC_BSY;
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(5000): us_to_ticks(3000));
sim_activate(uptr, T2_us);
#ifdef I7080
chan_clear(chan, STA_TWAIT);
#endif
break;
case MT_BSR:
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d ", unit);
sim_debug(DEBUG_DETAIL, dptr, "Backspace rec unit=%d %d ", unit, uptr->u3);
/* Clear tape mark, command, idle since we will need to change dir */
uptr->u5 &= ~(MT_CMDMSK | MT_EOT | MT_IDLE | MT_RDY);
r = sim_tape_sprecr(uptr, &reclen);
if (r != MTSE_BOT)
uptr->u3 -= GAP_LEN;
mt_chan[chan] &= ~MTC_BSY;
#ifdef I7080
chan_clear(chan, STA_TWAIT);
@@ -1111,14 +1132,12 @@ t_stat mt_srv(UNIT * uptr)
/* We don't set EOF on BSR */
#endif
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250):us_to_ticks(2500));
sim_activate(uptr, T2_us);
return SCPE_OK;
}
sim_debug(DEBUG_DETAIL, dptr, "%d \n", reclen);
sim_activate(uptr,
us_to_ticks(((uptr->flags & MTUF_LDN) ?4250:2500) +
(reclen * ((uptr->flags & MTUF_LDN) ?LT:HT))));
uptr->u3 -= reclen;
sim_activate(uptr, T2_us + (reclen * T1_us));
#ifdef I7010
break;
#else /* TEST */
@@ -1128,21 +1147,21 @@ t_stat mt_srv(UNIT * uptr)
case MT_BSF:
uptr->u5 &= ~(MT_IDLE | MT_RDY | MT_EOT);
r = sim_tape_sprecr(uptr, &reclen);
if (r != MTSE_BOT)
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\n",
unit);
sim_debug(DEBUG_DETAIL, dptr, "Backspace file unit=%d %d\n",
unit, uptr->u3);
uptr->u5 &= ~MT_CMDMSK;
mt_chan[chan] &= ~MTC_BSY;
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250):us_to_ticks(2500));
sim_activate(uptr, T2_us);
#ifdef I7080
chan_clear(chan, STA_TWAIT);
#endif
} else {
sim_activate(uptr,
us_to_ticks(((uptr->flags & MTUF_LDN) ?4250:2500) +
(reclen * ((uptr->flags & MTUF_LDN) ?LT:HT))));
uptr->u3 -= reclen;
sim_activate(uptr, T2_us + (reclen * T1_us));
}
#ifdef I7010
break;
@@ -1158,6 +1177,7 @@ t_stat mt_srv(UNIT * uptr)
uptr->u5 |= MT_SKIP;
#endif /* TEST */
r = sim_tape_sprecf(uptr, &reclen);
uptr->u3 += GAP_LEN;
#ifdef I7010
mt_chan[chan] &= ~MTC_BSY;
#else
@@ -1167,16 +1187,12 @@ t_stat mt_srv(UNIT * uptr)
/* We don't set EOF on SKR */
if (r == MTSE_TMK) {
sim_debug(DEBUG_DETAIL, dptr, "MARK\n");
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250):us_to_ticks(2500));
sim_activate(uptr, 100);
return SCPE_OK;
}
if (r != MTSE_OK)
reclen = 10;
sim_debug(DEBUG_DETAIL, dptr, "%d\n", reclen);
sim_activate(uptr,
us_to_ticks(((uptr->flags & MTUF_LDN) ?4250:2500) +
(reclen * ((uptr->flags & MTUF_LDN) ?LT:HT))));
uptr->u3 += reclen;
sim_activate(uptr, (reclen * T1_us));
break;
case MT_ERG:
@@ -1188,35 +1204,77 @@ t_stat mt_srv(UNIT * uptr)
uptr->u5 |= MT_SKIP;
#endif
r = sim_tape_wrgap(uptr, 35);
uptr->u3 += GAP_LEN;
mt_chan[chan] &= ~MTC_BSY;
sim_activate(uptr, (uptr->flags & MTUF_LDN) ?
us_to_ticks(4250):us_to_ticks(2500));
sim_activate(uptr, T2_us);
break;
case MT_REW:
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d\n", unit);
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d %d %d\n", unit, uptr->u3,
uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200);
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY);
r = sim_tape_rewind(uptr);
sim_activate(uptr, 30000);
mt_chan[chan] &= ~MTC_BSY;
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
uptr->u5 |= MT_HREW;
sim_activate(uptr, us_to_ticks(5000000));
} else {
uptr->u5 |= MT_LREW;
sim_activate(uptr, 300);
}
#ifdef I7080
chan_clear(chan, STA_TWAIT);
#endif
mt_chan[chan] &= ~MTC_BSY;
break;
case MT_RUN:
sim_debug(DEBUG_DETAIL, dptr, "Unload unit=%d\n", unit);
uptr->u5 &= ~(MT_CMDMSK | MT_IDLE | MT_RDY);
uptr->u5 |= MT_UNLOAD;
if ((uptr->u3 / ((uptr->flags & MTUF_LDN) ? 200 : 555) / 1200) > 2) {
uptr->u5 |= MT_HREW;
sim_activate(uptr, us_to_ticks(5000000));
} else {
uptr->u5 |= MT_LREW;
sim_activate(uptr, 300);
}
#ifdef I7010
chan_clear(chan, STA_TWAIT);
#endif
r = sim_tape_detach(uptr);
mt_chan[chan] &= ~MTC_BSY;
#ifdef I7080
chan_clear(chan, STA_TWAIT);
#endif
break;
mt_chan[chan] &= ~MTC_BSY;
return SCPE_OK;
case MT_HREW:
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d HS %d\n", unit, uptr->u3);
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));
} else {
uptr->u5 &= ~(MT_CMDMSK);
uptr->u5 |= MT_LREW;
sim_activate(uptr, us_to_ticks(5000000));
}
return SCPE_OK;
case MT_LREW:
sim_debug(DEBUG_DETAIL, dptr, "Rewind unit=%d LS %d\n", unit, uptr->u3);
if (uptr->u3 > 0) {
uptr->u3 -= (uptr->flags & MTUF_LDN) ? 373 :1036;
sim_activate(uptr, us_to_ticks(16000));
} else {
if(uptr->u5 & MT_UNLOAD)
r = sim_tape_detach(uptr);
else
r = sim_tape_rewind(uptr);
uptr->u5 &= ~(MT_CMDMSK|MT_UNLOAD);
uptr->u5 |= MT_IDLE;
uptr->u3 = 0;
sim_activate(uptr, us_to_ticks(3000));
return mt_error(uptr, chan, r, dptr);
}
return SCPE_OK;
}
return mt_error(uptr, chan, r, dptr);
}
@@ -1265,6 +1323,7 @@ mt_ini(UNIT * uptr, t_bool f)
uptr->u5 = MT_RDY;
else
uptr->u5 = 0;
uptr->u3 = 0;
mt_chan[chan] = 0;
}
@@ -1295,6 +1354,7 @@ mt_attach(UNIT * uptr, CONST char *file)
if ((r = sim_tape_attach(uptr, file)) != SCPE_OK)
return r;
uptr->u3 = 0;
uptr->u5 |= MT_RDY;
uptr->flags |= MTUF_ONLINE;
uptr->dynflags = MT_200_VALID | MT_556_VALID |
@@ -1305,6 +1365,7 @@ mt_attach(UNIT * uptr, CONST char *file)
t_stat
mt_detach(UNIT * uptr)
{
uptr->u3 = 0;
uptr->u5 = 0;
uptr->flags &= ~MTUF_ONLINE;
return sim_tape_detach(uptr);

View File

@@ -37,14 +37,10 @@
chan_mod Channel modifiers list
*/
#define CDPSTA_READ 000010 /* Unit is in read */
#define CDPSTA_WRITE 000020 /* Unit is in write */
#define CDPSTA_ON 000004 /* Unit is running */
#define CDPSTA_IDLE 000040 /* Unit between operation */
#define CDPSTA_CMD 000100 /* Unit has recieved a cmd */
#define CDPSTA_PUNCH 000200 /* Punch strobe during run */
#define CDPSTA_POSMASK 077000
#define CDPSTA_POSSHIFT 9
/* Device status information stored in u5 */
#define CDPSTA_PUNCH 0004000 /* Punch strobe during run */
#define CDPSTA_POSMASK 0770000
#define CDPSTA_POSSHIFT 12
t_stat cdp_srv(UNIT *);
t_stat cdp_reset(DEVICE *);
@@ -100,15 +96,15 @@ uint32 cdp_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
if ((uptr->flags & UNIT_ATT) != 0 && cmd == IO_WRS) {
/* Start device */
if (!(uptr->u5 & CDPSTA_CMD)) {
if (!(uptr->u5 & URCSTA_CMD)) {
dev_pulse[chan] &= ~PUNCH_M;
uptr->u5 &= ~CDPSTA_PUNCH;
if ((uptr->u5 & CDPSTA_ON) == 0) {
if ((uptr->u5 & URCSTA_ON) == 0) {
uptr->wait = 330; /* Startup delay */
} else if (uptr->u5 & CDPSTA_IDLE && uptr->wait <= 30) {
} else if (uptr->u5 & URCSTA_IDLE && uptr->wait <= 30) {
uptr->wait += 85; /* Wait for next latch point */
}
uptr->u5 |= (CDPSTA_WRITE | CDPSTA_CMD);
uptr->u5 |= (URCSTA_WRITE | URCSTA_CMD);
uptr->u5 &= ~CDPSTA_POSMASK;
chan_set_sel(chan, 1);
chan_clear_status(chan);
@@ -134,13 +130,13 @@ t_stat cdp_srv(UNIT * uptr)
struct _card_data *data;
/* Channel has disconnected, abort current card. */
if (uptr->u5 & CDPSTA_CMD && chan_stat(chan, DEV_DISCO)) {
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);
uptr->u5 &= ~CDPSTA_PUNCH;
}
uptr->u5 &= ~(CDPSTA_WRITE | CDPSTA_CMD | CDPSTA_POSMASK);
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_CMD | CDPSTA_POSMASK);
chan_clear(chan, DEV_WEOR | DEV_SEL);
sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d disconnect\n", u);
}
@@ -150,11 +146,11 @@ t_stat cdp_srv(UNIT * uptr)
uptr->wait--;
/* If at end of record and channel is still active, do another read */
if (
((uptr->u5 & (CDPSTA_CMD | CDPSTA_IDLE | CDPSTA_WRITE | CDPSTA_ON))
== (CDPSTA_CMD | CDPSTA_IDLE | CDPSTA_ON)) && uptr->wait > 30
((uptr->u5 & (URCSTA_CMD | URCSTA_IDLE | URCSTA_WRITE | URCSTA_ON))
== (URCSTA_CMD | URCSTA_IDLE | URCSTA_ON)) && uptr->wait > 30
&& chan_test(chan, STA_ACTIVE)) {
uptr->u5 |= CDPSTA_WRITE;
uptr->u5 &= ~CDPSTA_IDLE;
uptr->u5 |= URCSTA_WRITE;
uptr->u5 &= ~URCSTA_IDLE;
chan_set(chan, DEV_WRITE);
chan_clear(chan, DEV_WEOR);
sim_debug(DEBUG_CHAN, &cdp_dev, "unit=%d restarting\n", u);
@@ -164,21 +160,21 @@ t_stat cdp_srv(UNIT * uptr)
}
/* If no write request, go to idle mode */
if ((uptr->u5 & CDPSTA_WRITE) == 0) {
if ((uptr->u5 & (CDPSTA_IDLE | CDPSTA_ON)) ==
(CDPSTA_IDLE | CDPSTA_ON)) {
if ((uptr->u5 & URCSTA_WRITE) == 0) {
if ((uptr->u5 & (URCSTA_IDLE | URCSTA_ON)) ==
(URCSTA_IDLE | URCSTA_ON)) {
uptr->wait = 85; /* Delay 85ms */
uptr->u5 &= ~CDPSTA_IDLE; /* Not running */
uptr->u5 &= ~URCSTA_IDLE; /* Not running */
sim_activate(uptr, us_to_ticks(1000));
} else {
uptr->u5 &= ~CDPSTA_ON; /* Turn motor off */
uptr->u5 &= ~URCSTA_ON; /* Turn motor off */
}
return SCPE_OK;
}
/* Motor is up to speed now */
uptr->u5 |= CDPSTA_ON;
uptr->u5 &= ~CDPSTA_IDLE; /* Not running */
uptr->u5 |= URCSTA_ON;
uptr->u5 &= ~URCSTA_IDLE; /* Not running */
if (dev_pulse[chan] & PUNCH_M)
uptr->u5 |= CDPSTA_PUNCH;
@@ -194,8 +190,8 @@ t_stat cdp_srv(UNIT * uptr)
}
sim_debug(DEBUG_DETAIL, &cdp_dev, "punch card\n");
sim_punch_card(uptr, NULL);
uptr->u5 |= CDPSTA_IDLE;
uptr->u5 &= ~(CDPSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH);
uptr->u5 |= URCSTA_IDLE;
uptr->u5 &= ~(URCSTA_WRITE | CDPSTA_POSMASK | CDPSTA_PUNCH);
uptr->wait = 85;
sim_activate(uptr, us_to_ticks(1000));
return SCPE_OK;

View File

@@ -41,15 +41,9 @@
*/
/* Device status information stored in u5 */
#define URCSTA_EOF 0001 /* Hit end of file */
#define URCSTA_ERR 0002 /* Error reading record */
#define CDRSTA_READ 000010 /* Unit is in read */
#define CDRSTA_ON 000004 /* Unit is running */
#define CDRSTA_EOR 000020 /* Hit end of record */
#define CDRSTA_IDLE 000040 /* Unit between operation */
#define CDRSTA_CMD 000100 /* Unit has recieved a cmd */
#define CDRPOSMASK 077000 /* Bit Mask to retrive drum position */
#define CDRPOSSHIFT 9
#define CDRSTA_EOR 002000 /* Hit end of record */
#define CDRPOSMASK 0770000 /* Bit Mask to retrive drum position */
#define CDRPOSSHIFT 12
t_stat cdr_srv(UNIT *);
@@ -101,13 +95,13 @@ uint32 cdr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
int u = (uptr - cdr_unit);
/* Start device */
if ((uptr->u5 & CDRSTA_CMD) == 0) {
if ((uptr->u5 & (CDRSTA_ON | CDRSTA_IDLE)) ==
(CDRSTA_ON | CDRSTA_IDLE) && (uptr->wait <= 60)) {
if ((uptr->u5 & URCSTA_CMD) == 0) {
if ((uptr->u5 & (URCSTA_ON | URCSTA_IDLE)) ==
(URCSTA_ON | URCSTA_IDLE) && (uptr->wait <= 60)) {
uptr->wait += 100; /* Wait for next latch point */
} else
uptr->wait = 75; /* Startup delay */
uptr->u5 |= CDRSTA_READ | CDRSTA_CMD | CDRPOSMASK;
uptr->u5 |= URCSTA_READ | URCSTA_CMD | CDRPOSMASK;
chan_set_sel(chan, 0);
chan_clear_status(chan);
sim_activate(uptr, us_to_ticks(1000)); /* activate */
@@ -130,8 +124,8 @@ t_stat cdr_srv(UNIT * uptr)
struct _card_data *data;
/* Channel has disconnected, abort current read. */
if (uptr->u5 & CDRSTA_CMD && chan_stat(chan, DEV_DISCO)) {
uptr->u5 &= ~(CDRSTA_READ | CDRSTA_CMD);
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) {
uptr->u5 &= ~(URCSTA_READ | URCSTA_CMD);
uptr->u5 |= CDRPOSMASK;
chan_clear(chan, DEV_WEOR | DEV_SEL);
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d disconnecting\n", u);
@@ -141,10 +135,10 @@ t_stat cdr_srv(UNIT * uptr)
if (uptr->wait != 0) {
/* If at end of record and channel is still active, do another read */
if (uptr->wait == 30
&& ((uptr->u5 & (CDRSTA_CMD|CDRSTA_IDLE|CDRSTA_READ|CDRSTA_ON))
== (CDRSTA_CMD | CDRSTA_IDLE | CDRSTA_ON))
&& ((uptr->u5 & (URCSTA_CMD|URCSTA_IDLE|URCSTA_READ|URCSTA_ON))
== (URCSTA_CMD | URCSTA_IDLE | URCSTA_ON))
&& chan_test(chan, STA_ACTIVE)) {
uptr->u5 |= CDRSTA_READ;
uptr->u5 |= URCSTA_READ;
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d restarting\n", u);
}
uptr->wait--;
@@ -153,20 +147,20 @@ t_stat cdr_srv(UNIT * uptr)
}
/* If no read request, go to idle mode */
if ((uptr->u5 & CDRSTA_READ) == 0) {
if ((uptr->u5 & URCSTA_EOF) || (uptr->u5 & CDRSTA_IDLE)) {
uptr->u5 &= ~(CDRSTA_ON | CDRSTA_IDLE); /* Turn motor off */
if ((uptr->u5 & URCSTA_READ) == 0) {
if ((uptr->u5 & URCSTA_EOF) || (uptr->u5 & URCSTA_IDLE)) {
uptr->u5 &= ~(URCSTA_ON | URCSTA_IDLE); /* Turn motor off */
} else {
uptr->wait = 85; /* Delay 85ms */
uptr->u5 |= CDRSTA_IDLE; /* Go idle */
uptr->u5 |= URCSTA_IDLE; /* Go idle */
sim_activate(uptr, us_to_ticks(1000));
}
return SCPE_OK;
}
/* Motor is up to speed now */
uptr->u5 |= CDRSTA_ON;
uptr->u5 &= ~CDRSTA_IDLE;
uptr->u5 |= URCSTA_ON;
uptr->u5 &= ~URCSTA_IDLE;
pos = (uptr->u5 & CDRPOSMASK) >> CDRPOSSHIFT;
if (pos == (CDRPOSMASK >> CDRPOSSHIFT)) {
@@ -176,14 +170,14 @@ t_stat cdr_srv(UNIT * uptr)
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d Setting ATTN\n", u);
chan_set_error(chan);
chan_set_attn(chan);
uptr->u5 &= ~CDRSTA_READ;
uptr->u5 &= ~URCSTA_READ;
sim_activate(uptr, us_to_ticks(1000));
return SCPE_OK;
case SCPE_EOF:
sim_debug(DEBUG_EXP, &cdr_dev, "unit=%d EOF\n", u);
chan_set_eof(chan);
chan_set_attn(chan);
uptr->u5 &= ~CDRSTA_READ;
uptr->u5 &= ~URCSTA_READ;
sim_activate(uptr, us_to_ticks(1000));
return SCPE_OK;
case SCPE_OK:
@@ -196,7 +190,7 @@ t_stat cdr_srv(UNIT * uptr)
if (pos == 24) {
sim_debug(DEBUG_CHAN, &cdr_dev, "unit=%d set EOR\n", u);
chan_set(chan, DEV_REOR);
uptr->u5 &= ~CDRSTA_READ;
uptr->u5 &= ~URCSTA_READ;
uptr->u5 |= CDRSTA_EOR | CDRPOSMASK;
uptr->wait = 86;
sim_activate(uptr, us_to_ticks(1000));

View File

@@ -444,14 +444,12 @@ chan_proc()
/* If we are not waiting EOR save it in memory */
if ((cmd[chan] & 1) == 0) {
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_DATA, &chan_dev,
"chan %d data < %012llo\n",
sim_debug(DEBUG_DATA, &chan_dev, "chan %d data < %012llo\n",
chan, assembly[chan]);
M[caddr[chan]] = assembly[chan];
} else {
if (chan_dev.dctrl & cmask)
sim_debug(DEBUG_DATA, &chan_dev,
"chan %d data * %012llo\n",
sim_debug(DEBUG_DATA, &chan_dev, "chan %d data * %012llo\n",
chan, assembly[chan]);
}
nxt_chan_addr(chan);
@@ -641,10 +639,10 @@ chan_proc()
sim_debug(DEBUG_DATA, &chan_dev,
"chan %d data > %012llo\n", chan,
assembly[chan]);
nxt_chan_addr(chan);
bcnt[chan] = 6;
wcount[chan]--;
}
nxt_chan_addr(chan);
bcnt[chan] = 6;
wcount[chan]--;
chan_flags[chan] |= DEV_FULL;
continue; /* Don't start next command until data taken */
}
@@ -1294,6 +1292,9 @@ chan_cmd(uint16 dev, uint16 dcmd)
r = dibp->cmd(uptr, dcmd, dev);
if (r != SCPE_NODEV) {
bcnt[chan] = 6;
cmd[chan] = 0;
caddr[chan] = 0;
location[chan] = 0;
return r;
}
}
@@ -1304,6 +1305,9 @@ chan_cmd(uint16 dev, uint16 dcmd)
r = dibp->cmd(uptr, dcmd, dev);
if (r != SCPE_NODEV) {
bcnt[chan] = 6;
cmd[chan] = 0;
caddr[chan] = 0;
location[chan] = 0;
return r;
}
}
@@ -1344,7 +1348,7 @@ chan_start(int chan, uint16 addr)
/* Fetch next command */
location[chan] = addr;
chan_fetch(chan);
chan_flags[chan] &= ~(STA_PEND|STA_TWAIT|STA_WAIT|DEV_WEOR);
chan_flags[chan] &= ~(STA_PEND|STA_TWAIT|STA_WAIT|DEV_WEOR|DEV_FULL);
chan_flags[chan] |= STA_START | STA_ACTIVE;
chan_info[chan] |= CHAINF_START;
return SCPE_OK;

View File

@@ -827,9 +827,8 @@ sim_instr(void)
iotraps &= ~(1 << shiftcnt);
}
}
if (mask & DMASK & ioflags
&& chan_stat(shiftcnt, CHS_ERR))
f |= 2; /* We have device error */
if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR))
f |= 2; /* We have device error */
/* check if we need to perform a trap */
if (f) {
/* HTR/HPR behave like wait if protected */
@@ -933,8 +932,10 @@ sim_instr(void)
if (mask & AMASK & ioflags) {
if (chan_stat(shiftcnt, CHS_EOF))
f = 1; /* We have a EOF */
#if 0
if (iotraps & (1 << shiftcnt))
f = 1; /* We have a IOCT/IORT/IOST */
#endif
}
if (mask & DMASK & ioflags && chan_stat(shiftcnt, CHS_ERR))
f = 1; /* We have device error */
@@ -3569,6 +3570,7 @@ prottrap:
iowait = 1;
break;
case SCPE_OK:
ihold = 1;
break;
}
break;
@@ -3607,7 +3609,6 @@ prottrap:
case SCPE_BUSY:
iowait = 1;
case SCPE_OK:
ihold = 1;
break;
}
break;
@@ -4016,6 +4017,7 @@ prottrap:
if ((cpu_unit.flags & OPTION_EFP) == 0)
break;
AC = ((SR & MSIGN) << 2) | (SR & PMASK);
MA = memmask & (MA + 1);
ReadMem(0, MQ);
break;

View File

@@ -82,20 +82,21 @@ int chan_read(int chan, t_uint64 *data, int flags);
void chan_proc();
extern uint16 dev_pulse[NUM_CHAN]; /* Device pulse */
#define PUNCH_1 00001
#define PUNCH_2 00002
#define PUNCH_M 00003
#define PRINT_I 00004
#define PRINT_1 00010
#define PRINT_2 00020
#define PRINT_3 00040
#define PRINT_4 00100
#define PRINT_5 00200
#define PRINT_6 00400
#define PRINT_7 01000
#define PRINT_8 02000
#define PRINT_9 04000
#define PRINT_M 07770
#define PUNCH_1 000001
#define PUNCH_2 000002
#define PUNCH_M 000003
#define PRINT_I 000004
#define PRINT_1 000010
#define PRINT_2 000020
#define PRINT_3 000040
#define PRINT_4 000100
#define PRINT_5 000200
#define PRINT_6 000400
#define PRINT_7 001000
#define PRINT_8 002000
#define PRINT_9 004000
#define PRINT_10 010000
#define PRINT_M 017770
/* Opcodes */
#define OP_TXI 1

View File

@@ -210,7 +210,7 @@ a number: A=1, B=2, C=3, D=4, E=5, F=6, G=7, H=8.
SET CHn FIXED Fixes channel to specific type.
SET CHn AUTO Defualt, channel configures based on devices on it.
Generally there is no need to worry about channel configurations, in
Generally there is no need to worry about channel configurations, in
auto mode they will configure to correct type to support devices attached
to them. Or you will get an error when you attempt to run the simulation
if there is a conflict.

View File

@@ -128,7 +128,7 @@ t_stat drm_srv(UNIT * uptr)
/* Channel has disconnected, abort current read. */
if (uptr->u5 & DRMSTA_CMD && chan_stat(chan, DEV_DISCO)) {
uptr->u5 = 0;
chan_clear(chan, DEV_WEOR | DEV_SEL);
chan_clear(chan, DEV_WEOR | DEV_SEL | STA_ACTIVE);
sim_debug(DEBUG_CHAN, &drm_dev, "Disconnect\n");
}
@@ -162,13 +162,14 @@ t_stat drm_srv(UNIT * uptr)
case TIME_ERROR:
/* If no data, disconnect */
sim_debug(DEBUG_DATA, &drm_dev, "loc %6o missed\n", addr);
chan_clear(chan, STA_ACTIVE | DEV_SEL);
uptr->u5 = DRMSTA_CMD;
break;
}
}
/* Increase delay for index time */
if (uptr->u6 == 0)
sim_activate(uptr, us_to_ticks(200));
sim_activate(uptr, us_to_ticks(120));
else
sim_activate(uptr, DRMWORDTIME);
return SCPE_OK;

View File

@@ -52,26 +52,24 @@
chan_mod Channel modifiers list
*/
#define LPRSTA_READ 0x00000001 /* Unit is in read */
#define LPRSTA_WRITE 0x00000002 /* Unit is in write */
#define LPRSTA_ON 0x00000004 /* Unit is running */
#define LPRSTA_EOF 0x00000008 /* Hit end of file */
#define LPRSTA_EOR 0x00000010 /* Hit end of record */
#define LPRSTA_IDLE 0x00000020 /* Unit between operation */
#define LPRSTA_CMD 0x00000040 /* Unit has recieved a cmd */
#define LPRSTA_RCMD 0x00000080 /* Restart with read */
#define LPRSTA_WCMD 0x00000100 /* Restart with write */
#define LPRSTA_POSMASK 0x0007f000 /* Postion data */
#define LPRSTA_POSSHIFT 12
#define LPRSTA_BINMODE 0x00000200 /* Line printer started in bin mode */
#define LPRSTA_CHANGE 0x00000400 /* Turn DEV_WRITE on */
#define LPRSTA_COLMASK 0xff000000 /* Mask to last column printed */
#define LPRSTA_COLSHIFT 24
/* Output selection is stored in u3 */
/* Line count is stored in u4 */
/* Device status information stored in u5 */
/* Position is stored in u6 */
#define LPRSTA_RCMD 002000 /* Read command */
#define LPRSTA_WCMD 004000 /* Write command */
#define LPRSTA_EOR 010000 /* Hit end of record */
#define LPRSTA_BINMODE 020000 /* Line printer started in bin mode */
#define LPRSTA_CHANGE 040000 /* Turn DEV_WRITE on */
#define LPRSTA_COL72 0100000 /* Mask to last column printed */
#define LPRSTA_IMAGE 0200000 /* Image to print */
struct _lpr_data
{
t_uint64 wbuff[24]; /* Line buffer */
char lbuff[144]; /* Output line buffer */
char lbuff[74]; /* Output line buffer */
}
lpr_data[NUM_DEVS_LPR];
@@ -81,6 +79,8 @@ void lpr_ini(UNIT *, t_bool);
t_stat lpr_reset(DEVICE *);
t_stat lpr_attach(UNIT *, CONST char *);
t_stat lpr_detach(UNIT *);
t_stat lpr_setlpp(UNIT *, int32, CONST char *, void *);
t_stat lpr_getlpp(FILE *, UNIT *, int32, CONST void *);
t_stat lpr_help (FILE *st, DEVICE *dptr, UNIT *uptr, int32 flag,
const char *cptr);
const char *lpr_description (DEVICE *dptr);
@@ -89,20 +89,22 @@ extern char six_to_ascii[64];
UNIT lpr_unit[] = {
#if NUM_DEVS_LPR > 1
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_A) | UNIT_LPR | ECHO, 0)}, /* A */
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_A) | UNIT_LPR | ECHO, 55)}, /* A */
#endif
#if NUM_DEVS_LPR > 2
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_C) | UNIT_LPR, 0)}, /* B */
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_C) | UNIT_LPR, 55)}, /* B */
#endif
#if NUM_DEVS_LPR > 3
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_E) | UNIT_LPR | UNIT_DIS, 0)}, /* C */
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_E) | UNIT_LPR | UNIT_DIS, 55)}, /* C */
#endif
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_CHPIO) | UNIT_LPR, 0)}, /* 704 */
{UDATA(&lpr_srv, UNIT_S_CHAN(CHAN_CHPIO) | UNIT_LPR, 55)}, /* 704 */
};
MTAB lpr_mod[] = {
{ECHO, 0, NULL, "NOECHO", NULL, NULL, NULL, "Done echo to console"},
{ECHO, ECHO, "ECHO", "ECHO", NULL, NULL, NULL, "Echo output to console"},
{MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE",
&lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"},
#if NUM_CHAN != 1
{MTAB_XTD | MTAB_VUN | MTAB_VALR, 0, "CHAN", "CHAN", &set_chan,
&get_chan, NULL},
@@ -121,6 +123,40 @@ DEVICE lpr_dev = {
/* Line printer routines
*/
/*
* Line printer routines
*/
t_stat
lpr_setlpp(UNIT *uptr, int32 val, CONST char *cptr, void *desc)
{
int i;
if (cptr == NULL)
return SCPE_ARG;
if (uptr == NULL)
return SCPE_IERR;
i = 0;
while(*cptr != '\0') {
if (*cptr < '0' || *cptr > '9')
return SCPE_ARG;
i = (i * 10) + (*cptr++) - '0';
}
if (i < 20 || i > 100)
return SCPE_ARG;
uptr->capac = i;
uptr->u4 = 0;
return SCPE_OK;
}
t_stat
lpr_getlpp(FILE *st, UNIT *uptr, int32 v, CONST void *desc)
{
if (uptr == NULL)
return SCPE_IERR;
fprintf(st, "linesperpage=%d", uptr->capac);
return SCPE_OK;
}
t_stat
print_line(UNIT * uptr, int chan, int unit)
{
@@ -130,12 +166,39 @@ print_line(UNIT * uptr, int chan, int unit)
/* Else if binary or not convertable, dump as image */
uint16 buff[80]; /* Temp conversion buffer */
int i;
int i, j;
int outsel = uptr->u3;
int prt_flg = 1;
if ((uptr->flags & (UNIT_ATT | ECHO)) == 0)
return SCPE_UNATT; /* attached? */
if (outsel & PRINT_3) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n\r", 1, 4, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
}
uptr->u5 &= ~LPRSTA_COL72;
uptr->u4++;
}
if (outsel & PRINT_4) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n\r\n\r", 1, 6, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
sim_putchar('\n');
sim_putchar('\r');
}
uptr->u5 &= ~LPRSTA_COL72;
uptr->u4++;
uptr->u4++;
}
/* Try to convert to text */
memset(buff, 0, sizeof(buff));
/* Bit flip into temp buffer */
@@ -154,100 +217,95 @@ print_line(UNIT * uptr, int chan, int unit)
lpr_data[unit].wbuff[i] = 0;
}
/* Space printer */
if (outsel == 0 || outsel & PRINT_2) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n", 1, 1, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
}
}
/* Space out printer based on last output */
if ((outsel & PRINT_9)) {
/* Trim trailing spaces */
for (j = 72; j > 0 && lpr_data[unit].lbuff[j] == ' '; j--) ;
j++;
if ((uptr->u5 & LPRSTA_COL72) == 0)
j = 0;
if (outsel & PRINT_1) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\f\n", 1, 2, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\f');
sim_putchar('\n');
sim_putchar('\r');
for (i = j; i < 72; i++) {
if (uptr->flags & UNIT_ATT)
sim_fwrite(" ", 1, 1, uptr->fileref);
if (uptr->flags & ECHO)
sim_putchar(' ');
}
}
if (outsel & PRINT_3) {
} else {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n\n", 1, 2, uptr->fileref);
sim_fwrite("\n\r", 1, 2, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
sim_putchar('\n');
}
}
if (outsel & PRINT_4) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n\n\n", 1, 3, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
sim_putchar('\n');
sim_putchar('\n');
}
uptr->u4++;
uptr->u5 &= ~LPRSTA_COL72;
}
/* Scan each column */
for (i = 0; i < 72;) {
for (i = 0; i < 72; i++) {
int bcd = sim_hol_to_bcd(buff[i]);
if (bcd == 0x7f)
lpr_data[unit].lbuff[i++] = 0x7f;
lpr_data[unit].lbuff[i] = '{';
else {
if (bcd == 020)
bcd = 10;
if (uptr->u5 & LPRSTA_BINMODE) {
char ch = (buff[i] != 0) ? '1' : ' ';
lpr_data[unit].lbuff[i++] = ch;
lpr_data[unit].lbuff[i] = ch;
} else
lpr_data[unit].lbuff[i++] = sim_six_to_ascii[bcd];
lpr_data[unit].lbuff[i] = sim_six_to_ascii[bcd];
}
}
sim_debug(DEBUG_DETAIL, &lpr_dev, "WRS unit=%d %3o [%72s]\n", unit,
outsel >> 3, &lpr_data[unit].lbuff[0]);
/* Trim trailing spaces */
for (--i; i > 0 && lpr_data[unit].lbuff[i] == ' '; i--) ;
/* Put output to column where we left off */
if (outsel & PRINT_9) {
int j =
(uptr->u5 & LPRSTA_COLMASK) >> LPRSTA_COLSHIFT;
uptr->u5 &= ~LPRSTA_COLMASK;
if (j < 71) {
if (uptr->flags & UNIT_ATT) {
char buffer[73];
memset(buffer, ' ', 72);
sim_fwrite(buffer, 1, 71 - j, uptr->fileref);
}
if (uptr->flags & ECHO) {
while (j++ < 71)
sim_putchar(' ');
}
}
} else {
uptr->u5 &= ~LPRSTA_COLMASK;
uptr->u5 |= (i << LPRSTA_COLSHIFT) & LPRSTA_COLMASK;
}
for (j = 71; j > 0 && lpr_data[unit].lbuff[j] == ' '; j--) ;
/* Print out buffer */
if (uptr->flags & UNIT_ATT)
sim_fwrite(lpr_data[unit].lbuff, 1, i + 1, uptr->fileref);
sim_fwrite(lpr_data[unit].lbuff, 1, j+1, uptr->fileref);
if (uptr->flags & ECHO) {
int j = 0;
while (j <= i)
sim_putchar(lpr_data[unit].lbuff[j++]);
for(i = 0; i <= j; i++)
sim_putchar(lpr_data[unit].lbuff[i]);
}
uptr->u5 |= LPRSTA_COL72;
/* Put output to column where we left off */
if (outsel != 0) {
uptr->u5 &= ~LPRSTA_COL72;
}
/* Space printer */
if (outsel & PRINT_2) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n\r", 1, 2, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
}
uptr->u4++;
}
if (outsel & PRINT_1) {
while (uptr->u4 < uptr->capac) {
if (uptr->flags & UNIT_ATT)
sim_fwrite("\n\r", 1, 2, uptr->fileref);
if (uptr->flags & ECHO) {
sim_putchar('\n');
sim_putchar('\r');
}
uptr->u4++;
}
}
if (uptr->u4 >= uptr->capac) {
uptr->u4 -= uptr->capac;
dev_pulse[chan] |= PRINT_I;
}
return SCPE_OK;
}
@@ -260,34 +318,36 @@ uint32 lpr_cmd(UNIT * uptr, uint16 cmd, uint16 dev)
/* Check if valid */
if ((dev & 03) == 0 || (dev & 03) == 3)
return SCPE_NODEV;
/* Check if still active */
if (uptr->u5 & LPRSTA_CMD)
return SCPE_BUSY;
/* Check if attached */
if ((uptr->flags & (UNIT_ATT | ECHO)) == 0) {
chan_set_error(chan);
sim_debug(DEBUG_EXP, &lpr_dev, "unit=%d not ready\n", u);
return SCPE_IOERR;
}
/* Check if still active */
if (uptr->u5 & URCSTA_CMD) {
sim_debug(DEBUG_EXP, &lpr_dev, "unit=%d busy\n", u);
return SCPE_BUSY;
}
/* Ok, issue command if correct */
if (cmd == IO_WRS || cmd == IO_RDS) {
/* Start device */
if (((uptr->u5 & (LPRSTA_ON | LPRSTA_IDLE)) ==
(LPRSTA_ON | LPRSTA_IDLE)) && uptr->wait <= 30) {
if (((uptr->u5 & (URCSTA_ON | URCSTA_IDLE)) ==
(URCSTA_ON | URCSTA_IDLE)) && uptr->wait <= 30) {
uptr->wait += 85; /* Wait for next latch point */
} else
uptr->wait = 330; /* Startup delay */
for (i = 0; i < 24; lpr_data[u].wbuff[i++] = 0) ;
uptr->u5 &=
~(LPRSTA_RCMD | LPRSTA_WCMD | LPRSTA_POSMASK | LPRSTA_WRITE |
LPRSTA_READ);
uptr->u6 = 0;
uptr->u5 &= ~(LPRSTA_WCMD | LPRSTA_RCMD | URCSTA_WRITE | URCSTA_READ);
uptr->u3 = 0;
dev_pulse[chan] = 0;
if (cmd == IO_WRS) {
sim_debug(DEBUG_CMD, &lpr_dev, "WRS %o unit=%d\n", dev, u);
uptr->u5 |= LPRSTA_WCMD | LPRSTA_CMD | LPRSTA_WRITE;
sim_debug(DEBUG_CMD, &lpr_dev, "WRS %o unit=%d %d\n", dev, u, uptr->wait);
uptr->u5 |= LPRSTA_WCMD | URCSTA_CMD | URCSTA_WRITE;
} else {
sim_debug(DEBUG_CMD, &lpr_dev, "RDS %o unit=%d\n", dev, u);
uptr->u5 |= LPRSTA_RCMD | LPRSTA_CMD | LPRSTA_READ;
sim_debug(DEBUG_CMD, &lpr_dev, "RDS %o unit=%d %d\n", dev, u, uptr->wait);
uptr->u5 |= LPRSTA_RCMD | URCSTA_CMD | URCSTA_READ;
}
if ((dev & 03) == 2)
uptr->u5 |= LPRSTA_BINMODE;
@@ -310,13 +370,12 @@ t_stat lpr_srv(UNIT * uptr)
int pos;
int r;
int eor = 0;
int action = 0;
/* Channel has disconnected, abort current line. */
if (uptr->u5 & LPRSTA_CMD && chan_stat(chan, DEV_DISCO)) {
if ((uptr->u5 & LPRSTA_POSMASK) != 0)
print_line(uptr, chan, u);
uptr->u5 &= ~(LPRSTA_WRITE | LPRSTA_READ | LPRSTA_CMD | LPRSTA_POSMASK);
if (uptr->u5 & URCSTA_CMD && chan_stat(chan, DEV_DISCO)) {
print_line(uptr, chan, u);
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_READ | URCSTA_CMD | LPRSTA_EOR);
uptr->u6 = 0;
chan_clear(chan, DEV_WEOR | DEV_SEL);
sim_debug(DEBUG_CHAN, &lpr_dev, "unit=%d disconnect\n", u);
}
@@ -343,12 +402,12 @@ t_stat lpr_srv(UNIT * uptr)
if (uptr->wait != 0) {
uptr->wait--;
/* If at end of record and channel is still active, do another print */
if (((uptr->u5 & (LPRSTA_IDLE|LPRSTA_CMD|LPRSTA_WRITE|LPRSTA_READ|
LPRSTA_ON)) == (LPRSTA_IDLE|LPRSTA_CMD|LPRSTA_ON))
&& uptr->wait > 30 && chan_test(chan, STA_ACTIVE)) {
if (((uptr->u5 & (URCSTA_IDLE|URCSTA_CMD|URCSTA_WRITE|URCSTA_READ|
URCSTA_ON)) == (URCSTA_IDLE|URCSTA_CMD|URCSTA_ON))
&& uptr->wait == 1 && chan_test(chan, STA_ACTIVE)) {
/* Restart same command */
uptr->u5 |= (LPRSTA_WRITE | LPRSTA_READ) & (uptr->u5 >> 7);
uptr->u5 &= ~(LPRSTA_POSMASK);
uptr->u5 |= (URCSTA_WRITE | URCSTA_READ) & (uptr->u5 >> 5);
uptr->u6 = 0;
chan_set(chan, DEV_WRITE);
sim_debug(DEBUG_CHAN, &lpr_dev, "unit=%d restarting\n", u);
}
@@ -357,33 +416,30 @@ t_stat lpr_srv(UNIT * uptr)
}
/* If no request, go to idle mode */
if ((uptr->u5 & (LPRSTA_READ | LPRSTA_WRITE)) == 0) {
if ((uptr->u5 & (LPRSTA_IDLE | LPRSTA_ON)) ==
(LPRSTA_IDLE | LPRSTA_ON)) {
if ((uptr->u5 & (URCSTA_READ | URCSTA_WRITE)) == 0) {
if ((uptr->u5 & (URCSTA_IDLE | URCSTA_ON)) == (URCSTA_IDLE | URCSTA_ON)) {
uptr->wait = 85; /* Delay 85ms */
uptr->u5 &= ~LPRSTA_IDLE; /* Not running */
uptr->u5 &= ~URCSTA_IDLE; /* Not running */
sim_activate(uptr, us_to_ticks(1000));
} else {
uptr->wait = 330; /* Delay 330ms */
uptr->u5 &= ~LPRSTA_ON; /* Turn motor off */
uptr->u5 &= ~URCSTA_ON; /* Turn motor off */
}
return SCPE_OK;
}
/* Motor is on and up to speed */
uptr->u5 |= LPRSTA_ON;
uptr->u5 &= ~LPRSTA_IDLE;
pos = (uptr->u5 & LPRSTA_POSMASK) >> LPRSTA_POSSHIFT;
uptr->u5 |= URCSTA_ON;
uptr->u5 &= ~URCSTA_IDLE;
pos = uptr->u6;
uptr->u3 |= dev_pulse[chan] & PRINT_M;
dev_pulse[chan] &= ~PRINT_M;
if (uptr->u3 != 0)
dev_pulse[chan] |= PRINT_I;
/* Check if he write out last data */
if (uptr->u5 & LPRSTA_READ) {
if (uptr->u5 & URCSTA_READ) {
int wrow = pos;
t_uint64 wd = 0;
int action = 0;
/* Case 0: Read word from MF memory, DEV_WRITE=1 */
/* Case 1: Read word from MF memory, write echo back */
@@ -392,90 +448,73 @@ t_stat lpr_srv(UNIT * uptr)
/* Case 4: No update, DEV_WRITE=1 */
eor = (uptr->u5 & LPRSTA_BINMODE) ? 1 : 0;
switch (pos) {
case 46:
print_line(uptr, chan, u);
pos = 0;
/* Fall through */
case 0:
case 1: /* Row 9 */
case 1: /* Row 9 */
case 2:
case 3: /* Row 8 */
case 3: /* Row 8 */
case 4:
case 5: /* Row 7 */
case 5: /* Row 7 */
case 6:
case 7: /* Row 6 */
case 7: /* Row 6 */
case 8:
case 9: /* Row 5 */
case 9: /* Row 5 */
case 10:
case 11: /* Row 4 */
case 12:
case 13: /* Row 3 */
case 14:
case 15: /* Row 2 */
case 16: /* Row 1 */
case 16: /* Row 1R */
break;
case 17: /* Row 1L and start Echo */
action = 1;
break;
case 18: /* Echo 8-4 R */
/* I'm not sure how these are computed */
#if 0 /* Should be correct, but force to zero works */
wd = lpr_data[u].wbuff[2];
wd -= lpr_data[u].wbuff[10];
#endif
/* But forcing to zero works */
wd = 0;
wd &= lpr_data[u].wbuff[10];
action = 2;
break;
case 19: /* Echo 8-4 L */
/* I'm not sure how these are computed */
#if 0 /* Should be correct, but force to zero works */
wd = lpr_data[u].wbuff[3];
wd -= lpr_data[u].wbuff[11];
#endif
/* But forcing to zero works */
wd = 0;
wd &= lpr_data[u].wbuff[11];
action = 3;
break;
case 20: /* Row 10 R */
wrow = 18;
action = 0;
break;
case 21: /* Row 10 L */
wrow = 19;
action = 1;
break;
case 22: /* Echo 8-3 */
/* I'm not sure how these are computed */
/* Fill for echo back */
#if 0
wd = lpr_data[u].wbuff[2];
wd -= lpr_data[u].wbuff[12];
#endif
/* But forcing to zero works */
wd = 0;
wd = lpr_data[u].wbuff[12];
wd &= lpr_data[u].wbuff[2];
action = 2;
break;
case 23:
#if 0
wd = lpr_data[u].wbuff[3];
wd -= lpr_data[u].wbuff[13];
#endif
/* I'm not sure how these are computed */
/* But forcing to zero works */
wd = 0;
wd = lpr_data[u].wbuff[13];
wd &= lpr_data[u].wbuff[3];
action = 3;
break;
case 24:
case 24: /* Row 11 R */
wrow = 20;
break;
case 25: /* Row 11 */
case 25: /* Row 11 L */
wrow = 21;
action = 1;
break;
case 26: /* Echo 9 */
action = 2;
wd = lpr_data[u].wbuff[0];
action = 2;
break;
case 27:
action = 3;
wd = lpr_data[u].wbuff[1];
action = 3;
break;
case 28:
wrow = 22;
@@ -512,57 +551,63 @@ t_stat lpr_srv(UNIT * uptr)
if (action == 0 || action == 1) {
/* If reading grab next word */
r = chan_read(chan, &lpr_data[u].wbuff[wrow], 0);
sim_debug(DEBUG_DATA, &lpr_dev, "print read row < %d %d %012llo eor=%d\n", pos, wrow,
lpr_data[u].wbuff[wrow], 0);
if (action == 1)
chan_clear(chan, DEV_WRITE);
} else { /* action == 2 || action == 3 */
/* Place echo data in buffer */
sim_debug(DEBUG_DATA, &lpr_dev, "print read row > %d %d %012llo eor=%d\n", pos, wrow,
wd, eor);
r = chan_write(chan, &wd, 0);
/* Change back to reading */
if (action == 3) {
uptr->wait = 650;
uptr->u5 &= ~(LPRSTA_POSMASK | LPRSTA_EOR);
uptr->u5 |= (++pos << LPRSTA_POSSHIFT) & LPRSTA_POSMASK;
uptr->u6 = ++pos;
uptr->u5 &= ~(LPRSTA_EOR);
uptr->u5 |= LPRSTA_CHANGE;
sim_activate(uptr, us_to_ticks(100));
return SCPE_OK;
}
}
} else {
eor = (pos == 23 || uptr->u5 & LPRSTA_BINMODE) ? 1 : 0;
eor = (pos == 23 || (uptr->u5 & LPRSTA_BINMODE && pos == 1)) ? 1 : 0;
if (pos == 24 || (uptr->u5 & LPRSTA_BINMODE && pos == 2)) {
print_line(uptr, chan, u);
pos = 0;
}
r = chan_read(chan, &lpr_data[u].wbuff[pos], 0);
sim_debug(DEBUG_DATA, &lpr_dev, "print row %d %012llo %d\n", pos,
lpr_data[u].wbuff[pos], eor);
}
uptr->u6 = pos + 1;
switch (r) {
case END_RECORD:
if (pos != 0)
print_line(uptr, chan, u);
uptr->wait = 85; /* Print wheel gap */
uptr->u5 |= LPRSTA_EOR | LPRSTA_IDLE;
uptr->u5 &= ~(LPRSTA_WRITE | LPRSTA_READ | LPRSTA_POSMASK);
uptr->wait = 100; /* Print wheel gap */
uptr->u5 |= LPRSTA_EOR | URCSTA_IDLE;
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_READ);
chan_set(chan, DEV_REOR);
break;
case DATA_OK:
pos++;
if (eor) {
print_line(uptr, chan, u);
uptr->wait = 85; /* Print wheel gap */
uptr->u5 |= LPRSTA_EOR | LPRSTA_IDLE;
uptr->u5 &= ~(LPRSTA_WRITE | LPRSTA_READ | LPRSTA_POSMASK);
uptr->wait = 100; /* Print wheel gap */
uptr->u5 |= LPRSTA_EOR | URCSTA_IDLE;
uptr->u5 &= ~(URCSTA_WRITE | URCSTA_READ);
chan_set(chan, DEV_REOR);
} else {
uptr->wait = 0;
uptr->u5 &= ~(LPRSTA_POSMASK | LPRSTA_EOR);
uptr->u5 |= (pos << LPRSTA_POSSHIFT) & LPRSTA_POSMASK;
sim_activate(uptr, (pos & 1) ? us_to_ticks(300) : us_to_ticks(13000));
uptr->u5 &= ~(LPRSTA_EOR);
sim_activate(uptr, (pos & 1) ? us_to_ticks(500) : us_to_ticks(16000));
return SCPE_OK;
}
break;
case TIME_ERROR:
if (pos != 0)
print_line(uptr, chan, u);
chan_set_attn(chan);
chan_set(chan, DEV_REOR);
uptr->wait = 13 * (12 - (pos / 2)) + 85;
uptr->u5 &= ~(LPRSTA_READ | LPRSTA_WRITE | LPRSTA_POSMASK);
uptr->u5 |= LPRSTA_IDLE;
uptr->u5 &= ~(URCSTA_READ | URCSTA_WRITE);
uptr->u5 |= URCSTA_IDLE;
break;
}
@@ -576,9 +621,10 @@ lpr_ini(UNIT * uptr, t_bool f)
int u = (uptr - lpr_unit);
int i;
uptr->u3 = 0;
uptr->u4 = 0;
uptr->u5 = 0;
for (i = 0; i < 140; i++)
lpr_data[u].lbuff[i] = ' ';
memset(&lpr_data[u].lbuff, ' ', sizeof(lpr_data[u].lbuff));
}
t_stat
@@ -601,6 +647,8 @@ lpr_attach(UNIT * uptr, CONST char *file)
t_stat
lpr_detach(UNIT * uptr)
{
int u = (uptr - lpr_unit);
return detach_unit(uptr);
}