From 3fde270ca37be925b38810a12cafd033c4f33b3d Mon Sep 17 00:00:00 2001 From: "James C. Bevier" Date: Wed, 17 Jul 2019 21:39:18 -0400 Subject: [PATCH] SEL32: Correct carriage control operations --- SEL32/sel32_lpr.c | 613 ++++++++++++++++++++++++---------------------- 1 file changed, 320 insertions(+), 293 deletions(-) diff --git a/SEL32/sel32_lpr.c b/SEL32/sel32_lpr.c index 6407d08..601b8e8 100644 --- a/SEL32/sel32_lpr.c +++ b/SEL32/sel32_lpr.c @@ -75,391 +75,418 @@ P00070 20 DATAB C' ' 0x20 FORMS CONTROL FO */ #ifdef NUM_DEVS_LPR -#define UNIT_LPR UNIT_ATTABLE | UNIT_DISABLE +#define UNIT_LPR UNIT_ATTABLE | UNIT_DISABLE -extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc); -extern t_stat show_dev_addr(FILE *st, UNIT * uptr, int32 v, CONST void *desc); -extern void chan_end(uint16 chan, uint8 flags); -extern int chan_read_byte(uint16 chan, uint8 *data); -extern int chan_write_byte(uint16 chan, uint8 *data); -extern void set_devattn(uint16 addr, uint8 flags); +extern t_stat set_dev_addr(UNIT *uptr, int32 val, CONST char *cptr, void *desc); +extern t_stat show_dev_addr(FILE *st, UNIT * uptr, int32 v, CONST void *desc); +extern void chan_end(uint16 chan, uint8 flags); +extern int chan_read_byte(uint16 chan, uint8 *data); +extern int chan_write_byte(uint16 chan, uint8 *data); +extern void set_devattn(uint16 addr, uint8 flags); /* u3 hold command and status information */ -#define LPR_INCH 0x00 /* INCH command */ +#define LPR_INCH 0x00 /* INCH command */ /* print buffer then CC commands */ -#define LPR_PBNCC 0x01 /* print only, no forms control */ -#define LPR_PBC 0x05 /* print buffer, then */ -#define LPR_PBL 0x15 /* print buffer, then */ -#define LPR_PBLL 0x25 /* print buffer, then */ -#define LPR_PBLLL 0x35 /* print buffer, then */ -#define LPR_PBF 0x45 /* print buffer, then */ -#define LPR_PBCCB 0x85 /* print buffer, then */ - /* Do CC then print commands then CC */ -#define LPR_CPBC 0x0d /* print buffer */ -#define LPR_LPBC 0x1d /* print buffer */ -#define LPR_LLPBC 0x2d /* print buffer */ -#define LPR_LLLPBC 0x3d /* print buffer */ -#define LPR_FPBC 0x4d /* print buffer */ - /* Do CC only, no print */ -#define LPR_NPC 0x03 /* */ -#define LPR_NPL 0x17 /* */ -#define LPR_NPLL 0x27 /* */ -#define LPR_NPLLL 0x37 /* */ -#define LPR_NPF 0x47 /* */ +#define LPR_PBNCC 0x01 /* print only, no forms control */ +#define LPR_PBC 0x05 /* print buffer, then */ +#define LPR_PBL 0x15 /* print buffer, then */ +#define LPR_PBLL 0x25 /* print buffer, then */ +#define LPR_PBLLL 0x35 /* print buffer, then */ +#define LPR_PBF 0x45 /* print buffer, then */ +#define LPR_PBCCB 0x85 /* print buffer, then */ + /* Do CC then print commands then CC */ +#define LPR_CPBC 0x0d /* print buffer */ +#define LPR_LPBC 0x1d /* print buffer */ +#define LPR_LLPBC 0x2d /* print buffer */ +#define LPR_LLLPBC 0x3d /* print buffer */ +#define LPR_FPBC 0x4d /* print buffer */ + /* Do CC only, no print */ +#define LPR_NPC 0x03 /* */ +#define LPR_NPL 0x17 /* */ +#define LPR_NPLL 0x27 /* */ +#define LPR_NPLLL 0x37 /* */ +#define LPR_NPF 0x47 /* */ -#define LPR_SNS 0x04 /* Sense command */ -#define LPR_CMDMSK 0xff /* Mask command part. */ -#define LPR_FULL 0x100 /* Buffer full (BOF) */ -#define LPR_PRE 0x200 /* Apply pre CC */ -#define LPR_POST 0x400 /* Apply post CC */ +#define LPR_SNS 0x04 /* Sense command */ +#define LPR_CMDMSK 0xff /* Mask command part. */ +#define LPR_FULL 0x100 /* Buffer full (BOF) */ +#define LPR_PRE 0x200 /* Apply pre CC */ +#define LPR_POST 0x400 /* Apply post CC */ /* u4 holds current line */ /* in u5 packs sense byte 0,1 and 3 */ /* Sense byte 0 */ -#define SNS_CMDREJ 0x80 /* Command reject */ -#define SNS_INTVENT 0x40 /* Unit intervention required */ -#define SNS_BUSCHK 0x20 /* Parity error on bus */ -#define SNS_EQUCHK 0x10 /* Equipment check */ -#define SNS_DATCHK 0x08 /* Data Check */ -#define SNS_OVRRUN 0x04 /* Data overrun */ -#define SNS_SEQUENCE 0x02 /* Unusual sequence */ -#define SNS_BOF 0x01 /* BOF on printer */ +#define SNS_CMDREJ 0x80 /* Command reject */ +#define SNS_INTVENT 0x40 /* Unit intervention required */ +#define SNS_BUSCHK 0x20 /* Parity error on bus */ +#define SNS_EQUCHK 0x10 /* Equipment check */ +#define SNS_DATCHK 0x08 /* Data Check */ +#define SNS_OVRRUN 0x04 /* Data overrun */ +#define SNS_SEQUENCE 0x02 /* Unusual sequence */ +#define SNS_BOF 0x01 /* BOF on printer */ /* u6 hold buffer position */ /* std devices. data structures - lpr_dev Line Printer device descriptor - lpr_unit Line Printer unit descriptor - lpr_reg Line Printer register list - lpr_mod Line Printer modifiers list + lpr_dev Line Printer device descriptor + lpr_unit Line Printer unit descriptor + lpr_reg Line Printer register list + lpr_mod Line Printer modifiers list */ struct _lpr_data { - uint8 lbuff[160]; /* Output line buffer */ + uint8 lbuff[160]; /* Output line buffer */ } lpr_data[NUM_DEVS_LPR]; -uint8 lpr_startcmd(UNIT *, uint16, uint8); -void lpr_ini(UNIT *, t_bool); -t_stat lpr_srv(UNIT *); -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 *); +uint8 lpr_startcmd(UNIT *, uint16, uint8); +void lpr_ini(UNIT *, t_bool); +t_stat lpr_srv(UNIT *); +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 *); /* channel program information */ -CHANP lpr_chp[NUM_DEVS_LPR] = {0}; +CHANP lpr_chp[NUM_DEVS_LPR] = {0}; -MTAB lpr_mod[] = { - {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE", - &lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"}, - {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, - &show_dev_addr, NULL}, - {0} +MTAB lpr_mod[] = { + {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "LINESPERPAGE", "LINESPERPAGE", + &lpr_setlpp, &lpr_getlpp, NULL, "Number of lines per page"}, + {MTAB_XTD|MTAB_VUN|MTAB_VALR, 0, "DEV", "DEV", &set_dev_addr, + &show_dev_addr, NULL}, + {0} }; -UNIT lpr_unit[] = { - {UDATA(lpr_srv, UNIT_LPR, 55), 300, UNIT_ADDR(0x7EF8)}, /* A */ +UNIT lpr_unit[] = { + {UDATA(lpr_srv, UNIT_LPR, 66), 300, UNIT_ADDR(0x7EF8)}, /* A */ #if NUM_DEVS_LPR > 1 - {UDATA(lpr_srv, UNIT_LPR, 55), 300, UNIT_ADDR(0x7EF9)}, /* B */ + {UDATA(lpr_srv, UNIT_LPR, 66), 300, UNIT_ADDR(0x7EF9)}, /* B */ #endif }; /* Device Information Block */ //DIB lpr_dib = {NULL, lpr_startcmd, NULL, NULL, lpr_ini, lpr_unit, lpr_chp, NUM_DEVS_LPR, 0xff, 0x7e00, 0, 0, 0}; -DIB lpr_dib = { - NULL, /* uint8 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */ - lpr_startcmd, /* uint8 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start a command */ - NULL, /* uint8 (*halt_io)(UNIT *uptr) */ /* Stop I/O */ - NULL, /* uint8 (*test_io)(UNIT *uptr) */ /* Test I/O */ - NULL, /* uint8 (*post_io)(UNIT *uptr) */ /* Post I/O */ - lpr_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ - lpr_unit, /* UNIT* units */ /* Pointer to units structure */ - lpr_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ - NUM_DEVS_LPR, /* uint8 numunits */ /* number of units defined */ - 0xff, /* uint8 mask */ /* 2 devices - device mask */ - 0x7e00, /* uint16 chan_addr */ /* parent channel address */ - 0, /* uint32 chan_fifo_in */ /* fifo input index */ - 0, /* uint32 chan_fifo_out */ /* fifo output index */ - 0, /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ +DIB lpr_dib = { + NULL, /* uint8 (*pre_io)(UNIT *uptr, uint16 chan)*/ /* Start I/O */ + lpr_startcmd, /* uint8 (*start_cmd)(UNIT *uptr, uint16 chan, uint8 cmd)*/ /* Start a command */ + NULL, /* uint8 (*halt_io)(UNIT *uptr) */ /* Stop I/O */ + NULL, /* uint8 (*test_io)(UNIT *uptr) */ /* Test I/O */ + NULL, /* uint8 (*post_io)(UNIT *uptr) */ /* Post I/O */ + lpr_ini, /* void (*dev_ini)(UNIT *, t_bool) */ /* init function */ + lpr_unit, /* UNIT* units */ /* Pointer to units structure */ + lpr_chp, /* CHANP* chan_prg */ /* Pointer to chan_prg structure */ + NUM_DEVS_LPR, /* uint8 numunits */ /* number of units defined */ + 0xff, /* uint8 mask */ /* 2 devices - device mask */ + 0x7e00, /* uint16 chan_addr */ /* parent channel address */ + 0, /* uint32 chan_fifo_in */ /* fifo input index */ + 0, /* uint32 chan_fifo_out */ /* fifo output index */ + 0, /* uint32 chan_fifo[FIFO_SIZE] */ /* interrupt status fifo for channel */ }; -DEVICE lpr_dev = { - "LPR", lpr_unit, NULL, lpr_mod, - NUM_DEVS_LPR, 8, 15, 1, 8, 8, - NULL, NULL, NULL, NULL, &lpr_attach, &lpr_detach, - &lpr_dib, DEV_UADDR | DEV_DISABLE | DEV_DEBUG, 0, dev_debug +DEVICE lpr_dev = { + "LPR", lpr_unit, NULL, lpr_mod, + NUM_DEVS_LPR, 8, 15, 1, 8, 8, + NULL, NULL, NULL, NULL, &lpr_attach, &lpr_detach, + &lpr_dib, DEV_UADDR | DEV_DISABLE | DEV_DEBUG, 0, dev_debug }; /* initialize the line printer */ void lpr_ini(UNIT *uptr, t_bool f) { - /* do nothing for now */ + /* do nothing for now */ } /* start an I/O operation */ uint8 lpr_startcmd(UNIT *uptr, uint16 chan, uint8 cmd) { - uint8 ch; + uint8 ch; - if ((uptr->u3 & LPR_CMDMSK) != 0) { /* unit busy */ - return SNS_BSY; /* yes, busy (already tested) */ - } + if ((uptr->u3 & LPR_CMDMSK) != 0) { /* unit busy */ + return SNS_BSY; /* yes, busy (already tested) */ + } - uptr->u3 &= ~(LPR_POST|LPR_PRE); /* set no CC */ - if (((cmd & 0x03) == 0x03) || (cmd & 0x0d) == 0x0d) { - uptr->u3 |= LPR_PRE; /* apply pre CC */ - } - if (((cmd & 0x05) == 0x05) || (cmd & 0x0d) == 0x0d) { - uptr->u3 |= LPR_POST; /* apply post CC */ - } - sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd Cmd %02x\n", cmd); + uptr->u3 &= ~(LPR_POST|LPR_PRE); /* set no CC */ + if (((cmd & 0x03) == 0x03) || (cmd & 0x0f) == 0x0d) { + uptr->u3 |= LPR_PRE; /* apply pre CC */ + } + if (((cmd & 0x0f) == 0x05) || (cmd & 0x0f) == 0x0d) { + uptr->u3 |= LPR_POST; /* apply post CC */ + } + sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd Cmd %02x\n", cmd); - /* process the command */ - switch (cmd & LPR_CMDMSK) { - case 0x00: /* INCH command */ - sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd INCH\n", chan); - return SNS_CHNEND|SNS_DEVEND; /* all is well */ - break; + /* process the command */ + switch (cmd & LPR_CMDMSK) { + case 0x00: /* INCH command */ + sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd INCH\n", chan); + return SNS_CHNEND|SNS_DEVEND; /* all is well */ + break; - /* No CC */ - case 0x01: /* print only, no forms control */ - /* print buffer then CC commands */ - case 0x05: /* print buffer, then */ - case 0x15: /* print buffer, then */ - case 0x25: /* print buffer, then */ - case 0x35: /* print buffer, then */ - case 0x45: /* print buffer, then */ - case 0x85: /* print buffer, then */ - /* Do CC then print commands then CC */ - case 0x0d: /* print buffer */ - case 0x1d: /* print buffer */ - case 0x2d: /* print buffer */ - case 0x3d: /* print buffer */ - case 0x4d: /* print buffer */ - /* Do CC only, no print */ - case 0x03: /* */ - case 0x17: /* */ - case 0x27: /* */ - case 0x37: /* */ - case 0x47: /* */ - /* process the command */ - sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd %x print\n", chan, cmd&LPR_CMDMSK); - uptr->u3 &= ~(LPR_CMDMSK); /* zero cmd */ - uptr->u3 |= (cmd & LPR_CMDMSK); /* save new command in u3 */ - sim_activate(uptr, 10); /* Start unit off */ - uptr->u5 = 0; /* no status */ - uptr->u6 = 0; /* start of buffer */ - return 0; /* we are good to go */ + /* No CC */ + case 0x01: /* print only, no forms control */ + /* print buffer then CC commands */ + case 0x05: /* print buffer, then */ + case 0x15: /* print buffer, then */ + case 0x25: /* print buffer, then */ + case 0x35: /* print buffer, then */ + case 0x45: /* print buffer, then */ + case 0x85: /* print buffer, then */ + /* Do CC then print commands then CC */ + case 0x0d: /* print buffer */ + case 0x1d: /* print buffer */ + case 0x2d: /* print buffer */ + case 0x3d: /* print buffer */ + case 0x4d: /* print buffer */ + /* Do CC only, no print */ + case 0x03: /* */ + case 0x17: /* */ + case 0x27: /* */ + case 0x37: /* */ + case 0x47: /* */ + /* process the command */ + sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd %x print\n", chan, cmd&LPR_CMDMSK); + uptr->u3 &= ~(LPR_CMDMSK); /* zero cmd */ + uptr->u3 |= (cmd & LPR_CMDMSK); /* save new command in u3 */ + sim_activate(uptr, 100); /* Start unit off */ + uptr->u5 = 0; /* no status */ + uptr->u6 = 0; /* start of buffer */ + return 0; /* we are good to go */ - case 0x4: /* Sense Status */ - sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd %x sense\n", chan, cmd&LPR_CMDMSK); - uptr->u3 &= ~(LPR_CMDMSK); /* zero cmd */ - uptr->u3 |= (cmd & LPR_CMDMSK); /* save new command in u3 */ - sim_activate(uptr, 10); /* Start unit off */ - uptr->u5 = 0; /* no status */ - uptr->u6 = 0; /* start of buffer */ - return 0; /* we are good to go */ + case 0x4: /* Sense Status */ + sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd %x sense\n", chan, cmd&LPR_CMDMSK); + uptr->u3 &= ~(LPR_CMDMSK); /* zero cmd */ + uptr->u3 |= (cmd & LPR_CMDMSK); /* save new command in u3 */ + sim_activate(uptr, 100); /* Start unit off */ + uptr->u5 = 0; /* no status */ + uptr->u6 = 0; /* start of buffer */ + return 0; /* we are good to go */ - default: /* invalid command */ - sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd %x INVALID \r\n", chan, cmd&LPR_CMDMSK); - uptr->u5 |= SNS_CMDREJ; - break; - } - if (uptr->u5 & 0xff) - return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; - return SNS_CHNEND|SNS_DEVEND; + default: /* invalid command */ + sim_debug(DEBUG_CMD, &lpr_dev, "lpr_startcmd %x: Cmd %x INVALID \r\n", chan, cmd&LPR_CMDMSK); + uptr->u5 |= SNS_CMDREJ; + break; + } + if (uptr->u5 & 0xff) + return SNS_CHNEND|SNS_DEVEND|SNS_UNITCHK; + return SNS_CHNEND|SNS_DEVEND; } /* Handle transfer of data for printer */ t_stat lpr_srv(UNIT *uptr) { - int chsa = GET_UADDR(uptr->u3); - int u = (uptr - lpr_unit); - int cmd = (uptr->u3 & 0xff); + int chsa = GET_UADDR(uptr->u3); + int u = (uptr - lpr_unit); + int cmd = (uptr->u3 & 0xff); - sim_debug(DEBUG_CMD, &lpr_dev, "lpr_srv called chsa %x cmd %x u3 %x cnt %x\r\n", chsa, cmd, uptr->u3, uptr->u6); + sim_debug(DEBUG_CMD, &lpr_dev, "lpr_srv called chsa %x cmd %x u3 %x cnt %x\r\n", chsa, cmd, uptr->u3, uptr->u6); - /* FIXME, need IOP lp status bit assignments */ - if (cmd == 0x04) { /* sense? */ - uint8 ch = uptr->u5; /* get current status */ - uptr->u3 &= ~(LPR_CMDMSK); /* clear command */ - chan_write_byte(chsa, &ch); /* write the status to memory */ - uptr->u6 = 0; /* reset to beginning of buffer */ - chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */ - return SCPE_OK; - } + /* FIXME, need IOP lp status bit assignments */ + if (cmd == 0x04) { /* sense? */ + uint8 ch = uptr->u5; /* get current status */ + uptr->u3 &= ~(LPR_CMDMSK); /* clear command */ + chan_write_byte(chsa, &ch); /* write the status to memory */ + uptr->u6 = 0; /* reset to beginning of buffer */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */ + return SCPE_OK; + } - /* process any CC before printing buffer */ - if ((uptr->u3 & LPR_PRE) && (((cmd & 0x03) == 0x03) || (cmd & 0x0d) == 0x0d)) { - uptr->u3 &= ~LPR_PRE; /* remove pre flag */ - /* we have CC to do */ - switch ((cmd & 0xf0) >> 4) { - case 0: /* (0x0d) */ - lpr_data[u].lbuff[uptr->u6++] = 0x0d; - break; - case 3: /* */ - lpr_data[u].lbuff[uptr->u6++] = 0x0a; - uptr->u4++; /* increment the line count */ - /* drop thru */ - case 2: /* */ - lpr_data[u].lbuff[uptr->u6++] = 0x0a; - uptr->u4++; /* increment the line count */ - /* drop thru */ - case 1: /* (0x0a) */ - lpr_data[u].lbuff[uptr->u6++] = 0x0a; - uptr->u4++; /* increment the line count */ - break; - case 4: /* (0x0c) */ - lpr_data[u].lbuff[uptr->u6++] = 0x0c; - uptr->u4 = 0; /* restart line count */ - break; - } - } + /* process any CC before printing buffer */ + if ((uptr->u3 & LPR_PRE) && (((cmd & 0x03) == 0x03) || (cmd & 0x0f) == 0x0d)) { + uptr->u3 &= ~LPR_PRE; /* remove pre flag */ + /* we have CC to do */ + switch ((cmd & 0xf0) >> 4) { + case 0: /* (0x0d) */ + lpr_data[u].lbuff[uptr->u6++] = 0x0d; + break; + case 3: /* */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; + uptr->u4++; /* increment the line count */ + /* drop thru */ + case 2: /* */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; + uptr->u4++; /* increment the line count */ + /* drop thru */ + case 1: /* (0x0a) */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; + uptr->u4++; /* increment the line count */ + break; + case 4: /* (0x0c) */ + lpr_data[u].lbuff[uptr->u6++] = 0x0d; /* add C/R */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; /* add L/F */ + lpr_data[u].lbuff[uptr->u6++] = 0x0c; /* add FF */ + uptr->u4 = 0; /* restart line count */ + break; + } + } - /* Copy next byte from users buffer */ - if ((uptr->u3 & LPR_FULL) == 0) { /* copy in a char if not full */ - if(chan_read_byte(chsa, &lpr_data[u].lbuff[uptr->u6])) { - uptr->u3 |= LPR_FULL; /* end of buffer or error */ - } else { - sim_activate(uptr, 20); /* got a char, wait for a while */ - uptr->u6++; /* next buffer loc */ - return SCPE_OK; /* done til next char */ - } - } +#ifdef OLDWAY + /* Copy next byte from users buffer */ + if ((uptr->u3 & LPR_FULL) == 0) { /* copy in a char if not full */ + if(chan_read_byte(chsa, &lpr_data[u].lbuff[uptr->u6])) { + uptr->u3 |= LPR_FULL; /* end of buffer or error */ + } else { + sim_activate(uptr, 20); /* got a char, wait for a while */ + uptr->u6++; /* next buffer loc */ + return SCPE_OK; /* done til next char */ + } + } +#else + /* Copy next byte from users buffer */ + while ((uptr->u3 & LPR_FULL) == 0) { /* copy in a char if not full */ + if(chan_read_byte(chsa, &lpr_data[u].lbuff[uptr->u6])) { + uptr->u3 |= LPR_FULL; /* end of buffer or error */ + break; /* done reading */ + } else { + uptr->u6++; /* next buffer loc */ + } + } +#endif - /* process any CC after printing buffer */ - if ((uptr->u3 & LPR_FULL) && (uptr->u3 & LPR_POST) && ((cmd & 0x0d) == 0x0d)) { - /* we have CC to do */ - uptr->u3 &= ~LPR_POST; /* remove post flag */ - lpr_data[u].lbuff[uptr->u6++] = 0x0d; /* just a */ - } + /* process any CC after printing buffer */ + if ((uptr->u3 & LPR_FULL) && (uptr->u3 & LPR_POST) && ((cmd & 0x0f) == 0x0d)) { + /* we have CC to do */ + uptr->u3 &= ~LPR_POST; /* remove post flag */ + lpr_data[u].lbuff[uptr->u6++] = 0x0d; /* just a */ + } - /* process any CC after printing buffer */ - if ((uptr->u3 & LPR_FULL) && (uptr->u3 & LPR_POST) && ((cmd & 0x05) == 0x05)) { - /* we have CC to do */ - uptr->u3 &= ~LPR_POST; /* remove post flag */ - switch ((cmd & 0xf0) >> 4) { - case 0: /* (0x0d) */ - lpr_data[u].lbuff[uptr->u6++] = 0x0d; - break; - case 3: /* */ - lpr_data[u].lbuff[uptr->u6++] = 0x0a; - /* drop thru */ - case 2: /* */ - lpr_data[u].lbuff[uptr->u6++] = 0x0a; - /* drop thru */ - case 1: /* (0x0a) */ - lpr_data[u].lbuff[uptr->u6++] = 0x0a; - break; - case 4: /* (0x0c) */ - lpr_data[u].lbuff[uptr->u6++] = 0x0c; - uptr->u4 = 0; /* restart line count */ - break; - } - } + /* process any CC after printing buffer */ + if ((uptr->u3 & LPR_FULL) && (uptr->u3 & LPR_POST) && ((cmd & 0x0f) == 0x05)) { + /* we have CC to do */ + uptr->u3 &= ~LPR_POST; /* remove post flag */ + switch ((cmd & 0xf0) >> 4) { + case 0: /* (0x0d) */ + lpr_data[u].lbuff[uptr->u6++] = 0x0d; + break; + case 3: /* */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; + uptr->u4++; /* increment the line count */ + /* drop thru */ + case 2: /* */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; + uptr->u4++; /* increment the line count */ + /* drop thru */ + case 1: /* (0x0a) */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; + uptr->u4++; /* increment the line count */ + break; + case 4: /* (0x0c) */ + lpr_data[u].lbuff[uptr->u6++] = 0x0d; /* add C/R */ + lpr_data[u].lbuff[uptr->u6++] = 0x0a; /* add L/F */ + lpr_data[u].lbuff[uptr->u6++] = 0x0c; /* add FF */ + uptr->u4 = 0; /* restart line count */ + break; + } + } - /* print the line if buffer is full */ - if (uptr->u3 & LPR_FULL || uptr->u6 >= 156) { - lpr_data[u].lbuff[uptr->u6] = 0x00; /* NULL terminate */ - sim_fwrite(&lpr_data[u].lbuff, 1, uptr->u6, uptr->fileref); /* Print our buffer */ - sim_debug(DEBUG_DETAIL, &lpr_dev, "LPR %s", &lpr_data[u].lbuff); - uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK); /* clear old status */ - uptr->u6 = 0; /* start at beginning of buffer */ - uptr->u4++; /* increment the line count */ - if (uptr->u4 > uptr->capac) { /* see if at max lines/page */ - uptr->u4 = 0; /* yes, restart count */ - chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */ - } else - chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */ - sim_activate(uptr, 3000); /* wait a long time for next look */ - return SCPE_OK; - } + /* print the line if buffer is full */ + if (uptr->u3 & LPR_FULL || uptr->u6 >= 156) { + lpr_data[u].lbuff[uptr->u6] = 0x00; /* NULL terminate */ + sim_fwrite(&lpr_data[u].lbuff, 1, uptr->u6, uptr->fileref); /* Print our buffer */ + sim_debug(DEBUG_DETAIL, &lpr_dev, "LPR %s", &lpr_data[u].lbuff); + uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK); /* clear old status */ + uptr->u6 = 0; /* start at beginning of buffer */ + uptr->u4++; /* increment the line count */ + if (uptr->u4 > uptr->capac) { /* see if at max lines/page */ + uptr->u4 = 0; /* yes, restart count */ + chan_end(chsa, SNS_DEVEND|SNS_CHNEND|SNS_UNITEXP); /* we are done */ + } else + chan_end(chsa, SNS_DEVEND|SNS_CHNEND); /* we are done */ +#if 0 /* done, so no time out */ +#ifdef OLDWAY + sim_activate(uptr, 3000); /* wait a long time for next look */ +#else + /* 600 lpm lp does 10 lines / sec, so 100ms wait*/ + sim_activate(uptr, 100); /* wait a time for next look */ +#endif +#endif + return SCPE_OK; + } - sim_activate(uptr, 20); /* got a char, wait for a while */ - return SCPE_OK; + /* should not get here */ + sim_activate(uptr, 20); /* got a char, wait for a while */ + return SCPE_OK; } /* print a line to the "printer" */ void print_line(UNIT *uptr) { - char out[150]; /* Temp conversion buffer */ - int i; - int u = (uptr - lpr_unit); + char out[150]; /* Temp conversion buffer */ + int i; + int u = (uptr - lpr_unit); - /* Try to convert to text */ - memset(out, ' ', sizeof(out)); + /* Try to convert to text */ + memset(out, ' ', sizeof(out)); - /* Scan each column */ - for (i = 0; i < uptr->u6; i++) { - int ch = lpr_data[u].lbuff[i]; + /* Scan each column */ + for (i = 0; i < uptr->u6; i++) { + int ch = lpr_data[u].lbuff[i]; - if (!isprint(ch)) /* make sure char is printable */ - ch = '.'; /* not printable, make it a '.' */ - out[i] = ch; /* save to buffer */ - } + if (!isprint(ch)) /* make sure char is printable */ + ch = '.'; /* not printable, make it a '.' */ + out[i] = ch; /* save to buffer */ + } - for (--i; i > 0 && out[i] == ' '; i--) /* Trim trailing spaces */ - ; - out[++i] = '\r'; /* output CR, LF. NULL */ - out[++i] = '\n'; - out[++i] = '\0'; + for (--i; i > 0 && out[i] == ' '; i--) /* Trim trailing spaces */ + ; + out[++i] = '\r'; /* output CR, LF. NULL */ + out[++i] = '\n'; + out[++i] = '\0'; - sim_fwrite(&out, 1, i, uptr->fileref); /* Print our buffer */ - sim_debug(DEBUG_DETAIL, &lpr_dev, "%s", out); + sim_fwrite(&out, 1, i, uptr->fileref); /* Print our buffer */ + sim_debug(DEBUG_DETAIL, &lpr_dev, "%s", out); - memset(&lpr_data[u].lbuff[0], 0, 144); /* clear the output buffer */ + memset(&lpr_data[u].lbuff[0], 0, 144); /* clear the output buffer */ } /* Set the number of lines per page on printer */ 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; + 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; } /* display the number of lines per page */ 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; + if (uptr == NULL) + return SCPE_IERR; + fprintf(st, "linesperpage=%d", uptr->capac); + return SCPE_OK; } /* attach a file to the line printer device */ t_stat lpr_attach(UNIT * uptr, CONST char *file) { - t_stat r; + t_stat r; - if ((r = attach_unit(uptr, file)) != SCPE_OK) - return r; - uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK); - uptr->u4 = 0; - uptr->u5 = 0; - return SCPE_OK; + if ((r = attach_unit(uptr, file)) != SCPE_OK) + return r; + uptr->u3 &= ~(LPR_FULL|LPR_CMDMSK); + uptr->u4 = 0; + uptr->u5 = 0; + return SCPE_OK; } /* detach a file from the line printer */ t_stat lpr_detach(UNIT * uptr) { - if (uptr->u3 & LPR_FULL) - print_line(uptr); - return detach_unit(uptr); + if (uptr->u3 & LPR_FULL) + print_line(uptr); + return detach_unit(uptr); } #endif