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:
@@ -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 *);
|
||||
|
||||
@@ -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 *);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
417
I7000/i7000_mt.c
417
I7000/i7000_mt.c
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user