[comp.sources.atari.st] v01i060: nlqps -- near-letter-quality printer driver

koreth@ssyx.ucsc.edu (Steven Grimm) (06/27/88)

Submitted-by: uunet!mcvax!philmds!leo (Leo de Wit)
Posting-number: Volume 1, Issue 60
Archive-name: nlqps

Another nice program for printer owners. That is, if your printer does
not have NLQ capability, but does have double-density graphics. It is,
at least I think it is, as good as NLQ in hardware; besides you have
the possibility of proportional spacing.
    The program consists of 3 modules: newstart.c, nlqps.c and
nlqpsdat.c and a header file: nqlps.h.  It is compiled and linked with
Lattice C, but it should be easy to adapt it for other compilers. The
printer it was tested with was a Star Gemini-10X.
   Generation procedure for Lattice: compile all three .c files, then
link them, together with the C library, to form a program named
nlqps.ttp.  The correct linking procedure : create a link file,
nlqps.lnk, that contains:

INPUT newstart.bin
INPUT nlqps.bin
INPUT nlqpsdat.bin
LIBRARY clib.bin

and then give the command:
LINK.TTP -WITH NLQPS -NOLIST -PROG NLQPS.TTP

   For a manual page I refer to the first comment in nlqps.c

    L.J.M. de Wit
    Nachtegaallaan 7
    5731XP Mierlo
    Holland

    E-mail: ...!mcvax!philmds!leo

=================== SHAR ARCHIVE =========== CUT HERE =========================
: This is a shar archive.  Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
echo 'Extracting newstart.c'
sed 's/^X//' > newstart.c << '+ END-OF-FILE newstart.c'
X/*
X ******************************************************************************
X *                                                                            *
X *    newstart.c  version 1.1 of 18 Feb  1988    (C) L.J.M. de Wit 1988       *
X *                                                                            *
X * This software may be used and distributed freely if not used commercially  *
X * and the originator (me) is mentioned.                                      *
X *                                                                            *
X ******************************************************************************
X *
X * This module (the first to be linked in) may only be used when malloc and/or
X * stdio are not used.
X * Startup() is the entry point which frees memory and resets the stack.
X * Then startetc() is called which initiates argc & argv for main; they
X * could not be on start's stack because that is reset.
X * exit() is redefined to avoid linking it from the library.
X */
X
X#include <osbind.h>
X
X#define TRUE         1
X#define FALSE        0
X#define ISSPACE(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n'))
X#define ACNT 32
X
Xtypedef unsigned char bool;
X
Xchar **environ;
X
Xstatic void startup(), startetc();
Xextern int main();
Xvoid exit();
X
Xstatic void startup(base)
Xchar *base;
X{
X   int memneed;
X   static short setsp[] = { /* set stack to value supplied */
X      0x2057,      /* MOVEA.L  (SP),A0  */
X      0x2E6F, 4,   /* MOVEA.L 4(SP),SP  */
X      0x4ED0       /* JMP      (A0)     */
X   };
X   extern int _mneed;
X
X   memneed = 0x100 +            /* base page   */
X             ((int *)base)[3] + /* text length */
X             ((int *)base)[5] + /* data length */
X             ((int *)base)[7] + /* bss  length */
X             0x800 +            /* workspace   */
X             0x900;             /* for stack   */
X
X   if (_mneed > memneed) {    /* take more memory */
X      memneed = (char *)(&memneed) - base;
X      if (_mneed < memneed) { /* but nomore as requested */
X         memneed = _mneed;
X      }
X   }
X
X   Mshrink(base,memneed);              /* frees mem: takes what's needed */
X   (*(void (*)())setsp)(base+memneed); /* resets sp to base+memneed */
X   startetc(base);                     /* to also have correct frame pointer */
X}
X
Xstatic void startetc(base)
Xchar *base;
X{
X   int argc, i;
X   char *argv[ACNT], *envp[ACNT];
X   char evstr[256], *s, *t;
X   bool inarg;             /* whether in a argument */
X
X   if ((s = ((char **)base)[11]) == (char *)0) {
X      *evstr = '\0';
X   } else {
X      for (t = evstr; *t++ = *s++; ) ;
X   }
X
X   /* stack arguments */
X   argv[0] = (char *)0; inarg = FALSE;
X   for (argc = 1, i = 0; (argc < ACNT) && (i < (unsigned)base[128]); i++) {
X      if ((base[129+i] == '\0') || ISSPACE(base[129+i])) {
X         if (inarg) {
X            inarg = FALSE;
X            base[129+i] = '\0';
X         }
X      } else {
X         if (!inarg) {
X            inarg = TRUE;
X            argv[argc++] = base+129+i;
X         }
X      }
X   }
X   base[129+i] = '\0';
X
X   if (argc == ACNT) {
X      Cconws("newstart: too many arguments\r\n");
X      exit(1);
X   }
X
X   inarg = FALSE;
X   for (i = 0, s = evstr; (i < ACNT) && (*s != '\0'); s++) {
X      if (ISSPACE(*s)) {
X         if (inarg) {
X            inarg = FALSE;
X            *s = '\0';
X         }
X      } else {
X         if (!inarg) {
X            inarg = TRUE;
X            envp[i++] = s;
X         }
X      }
X   }
X   if (i == ACNT) {
X      Cconws("newstart: too many environment variables\r\n");
X      exit(1);
X   }
X
X   environ = envp;
X
X   argv[argc] = (char *)0;
X   envp[i]    = (char *)0;
X   main(argc,argv,envp);
X   exit(0);
X}
X
Xvoid exit(code)
Xint code;
X{
X   Pterm(code);
X}
+ END-OF-FILE newstart.c
chmod 'u=rw,g=r,o=' 'newstart.c'
echo 'SENT: -rw-r-----  1 leo          3688 Jun 24 12:30 newstart.c'
echo -n 'RCVD: '
/bin/ls -l newstart.c
echo 'Extracting nlqps.c'
sed 's/^X//' > nlqps.c << '+ END-OF-FILE nlqps.c'
X/*
X ******************************************************************************
X *                                                                            *
X *    nlqps.c     version 1.1 of 24 June 1988    (C) L.J.M. de Wit 1988       *
X *                                                                            *
X * This software may be used and distributed freely if not used commercially  *
X * and the originator (me) is mentioned.                                      *
X *                                                                            *
X ******************************************************************************
X *
X * NAME
X *    nlqps - print with Near Letter Quality and Proportional Spacing
X *
X * SYNTAX
X *    nlqps.ttp [-n|-N] [file ...]
X *
X * DESCRIPTION
X *    This program is meant for use with printers that have no NLQ capability.
X *    The printer SHOULD have double density graphics capability and capability
X *    of sending a LF of half a scanline high (1/144 inch). The Star Gemini-10X
X *    is an example. If the escape sequences for your printer are different,
X *    you should alter the macros LP_SMALL_LF() (1/144 inch linefeed),
X *    LP_BIG_LF() (23/144 inch linefeed) and LP_DD_GRAPH() (double density
X *    graphics) accordingly.
X *
X *    The program prints your file(s) (or standard input for pipes) in a
X *    standard NLQ fashion, i.e. the line is printed twice in graphics mode
X *    with complementary fonts and a very small linefeed inbetween. The total
X *    linefeed is still 1/144 + 23/144 = 1/6 inch, which is a standard
X *    line height.
X *
X *    A nice feature of this program is that it does proportional spacing as
X *    well; if this is not desired (e.g. when printing tables, columns, program
X *    listings) this feature can be turned off by the -n switch; n for
X *    non-proportional (-N is the same and only needed because silly uppercase
X *    conversion of the parameter line when running TTP's from the Desktop).
X *
X * BUGS/SHORTCOMINGS
X *    The program is not activated when printing files from the Desktop. The
X *    question is: Is automatic NLQ printing desired (printing without NLQ
X *    becomes harder) ?
X *
X *    The program does not yet provide for different NLQ fonts. This is however
X *    not hard (loading a file into the nlqfont struct) but only useful with
X *    an editor program for such a font.
X *
X * DECISIONS
X *    For compactness of code the module should be linked with newstart.bin
X *    instead of startup.bin (the standard first module and entry point of the
X *    program). This new startup module avoids using stdio (not needed here),
X *    resulting in a much smaller program: 4435 bytes instead of 14036! 
X *    The standard C library IS used (for the gemdos/bios interface).
X *    One should create a link file, nlqps.lnk, that contains:
X *            INPUT newstart.bin
X *            INPUT nlqps.bin
X *            INPUT nlqpsdat.bin
X *            LIBRARY clib.bin
X *    and the command to be given is:
X *    LINK.TTP -WITH NLQPS -NOLIST -PROG NLQPS.TTP
X *    The function startup() in newstart.c is used as entry point, so
X *    newstart.bin must be the first module to be linked in.
X */
X
X#include <osbind.h>
X#include <portab.h>
X#include "nlqps.h"
X
X#define BUFSIZ     512  /* from stdio.h */
X
X#define SET0         0  /* denotes set to be used in second scan */
X#define SET1         1  /* denotes set to be used in first scan */
X#define INTERSPACE   3  /* space between characters in dot columns */
X#define ESC         27  /* escape character */
X#define BUFLEN     256  /* max size of character buffer for one line */
X#define MAXSCAN    960  /* max # of dot columns per line */
X#define CHARWIDTH   12  /* width of char in dot columns if non-proportional */
X
X#define LP(c) Bconout(0,(c))
X#define LP_SMALL_LF() (LP(ESC),LP(74),LP(1))
X#define LP_BIG_LF()   (LP(ESC),LP(74),LP(23))
X#define LP_DD_GRAPH() (LP(ESC),LP('L'))
X
Xstatic void prline(), nlq();
Xstatic int lookup();
X
Xstatic int notprop;
X
Xint main(argc,argv)
Xint argc;
Xchar **argv;
X{
X   int i, fd;
X
X   i = 1;
X
X   notprop = (argc >= 2)                  /* Check argv[1] for "-n" or "-N" */
X             && (argv[i][0] == '-')
X             && ((argv[i][1] == 'n') || (argv[i][1] == 'N'));
X   if (notprop) i++;
X
X   if (i == argc) {
X      nlq(0);                             /* Nlq the standard input         */
X   } else {
X      for ( ; i < argc; i++) {
X         if ((fd = Fopen(argv[i],0)) < 0) {
X            Cconws("nlqps: "); Cconws(argv[i]); Cconws(": cannot open\r\n");
X         } else {
X            nlq(fd);                      /* Nlq the file                   */
X            Fclose(fd);
X         }
X      }
X   }
X}
X
Xstatic void nlq(fd)                       /* Print from filedescriptor fd   */
Xint fd;                                   /* in NLQ with prop. spacing      */
X{
X   char inbuf[BUFSIZ],                    /* Input buffer for reads from fd */
X        *ibp = inbuf,                     /* For reading a char from inbuf  */
X        c;
X   char buf[BUFLEN],                      /* Line to print (still ASCII)    */
X        *dummy;
X   int bufcnt = 0,                        /* # chars in buf sofar           */
X       scancnt = 0,                       /* # dot columns sofar            */
X       nread = 0;                         /* # bytes read into inbuf        */
X
X   do {
X      if (inbuf + nread == ibp) {         /* Read all chars from inbuf      */
X         if ((nread = Fread(fd,sizeof(inbuf),inbuf)) <= 0) { /* Fill inbuf  */
X            break;                        /* End-of-file                    */
X         }
X         ibp = inbuf;                     /* Pointer at buffer start        */
X      }
X      c = *ibp++;                         /* Read 1 char from inbuf         */
X      if ((c == '\n')                     /* Had newline                    */
X         || (bufcnt == BUFLEN)            /* .. or max # characters         */
X         || (scancnt > MAXSCAN - 9)) {    /* .. or max # dot columns        */
X
X         if (scancnt > 0) {               /* Do first scan                  */
X            LP_DD_GRAPH();                /* Select dd graphics             */
X            LP(scancnt & 0xff);           /* # dot columns: low byte        */
X            LP((scancnt >> 8) & 0xff);    /* # dot columns: high byte       */
X            prline(buf,bufcnt,SET1);      /* Print buf graphic with SET1    */
X         }
X         LP_SMALL_LF();                   /* Send a 1/144 inch LF           */
X         if (scancnt > 0) {               /* Do second scan                 */
X            LP_DD_GRAPH();
X            LP(scancnt & 0xff);
X            LP((scancnt >> 8) & 0xff);
X            prline(buf,bufcnt,SET0);      /* Print buf graphic with SET0    */
X         }
X         LP_BIG_LF();                     /* Send a 23/144 inch LF          */
X         bufcnt = scancnt = 0;            /* Reset buf parameters           */
X      }
X      if (c != '\n') {                    /* normal character               */
X         buf[bufcnt++] = c;               /* Put it into buf; update bufcnt */
X         scancnt += (notprop)             /* .. and scancnt:                */
X            ? CHARWIDTH                   /* constant CHARWIDTH if not prop.*/
X            : lookup(c,SET0,&dummy)       /* real character width + space   */
X              + INTERSPACE;               /* If proportional                */
X      }
X   } while (TRUE);
X}
X
Xstatic void prline(buf,bufcnt,set)        /* Print the buf (bufcnt chars)   */
Xchar *buf;                                /* with this set in graphic mode  */
Xint bufcnt, set;
X{
X   int i, j,
X       scancnt;                           /* width of char in dot columns   */
X   char *ch_start;                        /* start of char bit image (9)    */
X
X   for (i = 0; i < bufcnt; i++) {         /* For each char in buf           */
X      scancnt = lookup(buf[i],set,&ch_start);/* set width and start         */
X      for (j = 0; j < scancnt; j++) {     /* Do each dot column             */
X         LP(ch_start[j]);
X      }
X      for (j = (notprop) ? CHARWIDTH - scancnt : INTERSPACE; j > 0; --j) {
X         LP(0);                           /* Print empty column as spacing  */
X      }
X   }
X}
X
Xstatic int lookup(c,set,csp)              /* Get byte image start & # dot   */
Xchar c, **csp;                            /* columns for this char and set  */
Xint set;
X{
X   int retval;
X
X   c -= ' ';
X   if ((c >= 0) && (c < 128 - ' ')) {
X      retval = nlqfont[c].nlq_width;
X      *csp   = (set == SET0) ? nlqfont[c].nlq_set0 : nlqfont[c].nlq_set1;
X   } else {                               /* If c out of range              */
X      retval = 0;
X      *csp = "";
X   }
X   return retval;                         /* actual width of image          */
X}
+ END-OF-FILE nlqps.c
chmod 'u=rw,g=r,o=' 'nlqps.c'
echo 'SENT: -rw-r-----  1 leo          8759 Jun 24 12:41 nlqps.c'
echo -n 'RCVD: '
/bin/ls -l nlqps.c
echo 'Extracting nlqps.h'
sed 's/^X//' > nlqps.h << '+ END-OF-FILE nlqps.h'
X/*
X ******************************************************************************
X *                                                                            *
X *    nlqps.h     version 1.1 of 24 June 1988    (C) L.J.M. de Wit 1988       *
X *                                                                            *
X * This software may be used and distributed freely if not used commercially  *
X * and the originator (me) is mentioned.                                      *
X *                                                                            *
X ******************************************************************************
X *
X * nlqps.h: typedef & external declaration for nlqps
X */
X
Xtypedef struct nlqchar {
X   unsigned char nlq_width;
X   char nlq_set0[9];
X   char nlq_set1[9];
X} nlqchar;
X
Xextern nlqchar nlqfont[];
+ END-OF-FILE nlqps.h
chmod 'u=rw,g=r,o=' 'nlqps.h'
echo 'SENT: -rw-r-----  1 leo           837 Jun 24 12:28 nlqps.h'
echo -n 'RCVD: '
/bin/ls -l nlqps.h
echo 'Extracting nlqpsdat.c'
sed 's/^X//' > nlqpsdat.c << '+ END-OF-FILE nlqpsdat.c'
X/*
X ******************************************************************************
X *                                                                            *
X *    nlqpsdat.c  version 1.1 of 24 June 1988    (C) L.J.M. de Wit 1988       *
X *                                                                            *
X * This software may be used and distributed freely if not used commercially  *
X * and the originator (me) is mentioned.                                      *
X *                                                                            *
X ******************************************************************************
X *
X *    nlqpsdat.c: This file contains the (initialized) structure for the
X *                nlqps font.
X */
X
X#include "nlqps.h"
X
Xnlqchar nlqfont[] = {
X/* ' ' */ {6, 0,0,0,0,0,0,0,0,0,             0,0,0,0,0,0,0,0,0},
X/* '!' */ {1, 224,0,0,0,0,0,0,0,0,           242,0,0,0,0,0,0,0,0},
X/* '"' */ {5, 192,0,0,0,192,0,0,0,0,         224,0,0,0,224,0,0,0,0},
X/* '#' */ {9, 0,0,252,0,0,0,252,0,0,         40,40,254,40,40,40,254,40,40},
X/* '$' */ {9, 96,0,0,0,252,0,0,0,24,         32,84,84,84,254,84,84,84,8},
X/* '%' */ {9, 128,0,132,8,16,32,68,128,4,    192,194,196,8,16,32,70,134,6},
X/* '&' */ {9, 200,20,32,16,192,12,0,12,0,    76,160,146,162,74,0,4,0,10},
X/* ''' */ {3, 0,0,192,0,0,0,0,0,0,           160,160,192,0,0,0,0,0,0},
X/* '(' */ {3, 48,204,0,0,0,0,0,0,0,          56,68,130,0,0,0,0,0,0},
X/* ')' */ {3, 0,204,48,0,0,0,0,0,0,          130,68,56,0,0,0,0,0,0},
X/* '*' */ {7, 72,0,48,252,48,0,72,0,0,       68,40,16,254,16,40,68,0,0},
X/* '+' */ {9, 0,0,0,0,120,0,0,0,0,           16,16,16,16,124,16,16,16,16},
X/* ',' */ {3, 5,5,6,0,0,0,0,0,0,             6,6,7,0,0,0,0,0,0},
X/* '-' */ {9, 0,0,0,0,0,0,0,0,0,             16,16,16,16,16,16,16,16,16},
X/* '.' */ {4, 6,6,6,6,0,0,0,0,0,             2,2,2,2,0,0,0,0,0},
X/* '/' */ {7, 0,4,8,16,32,64,128,0,0,        2,4,8,16,32,64,128,0,0},
X/* '0' */ {9, 48,204,0,0,0,0,0,204,48,       56,68,130,130,130,130,130,68,56},
X/* '1' */ {5, 0,128,252,0,0,0,0,0,0,         66,66,254,2,2,0,0,0,0},
X/* '2' */ {9, 0,132,0,8,0,16,0,160,64,       66,2,134,130,138,130,146,2,98},
X/* '3' */ {9, 0,4,0,0,0,96,0,148,8,          132,128,130,130,162,130,210,128,140},
X/* '4' */ {9, 0,16,32,64,128,0,252,0,0,      8,24,40,72,136,136,254,8,8},
X/* '5' */ {9, 192,4,0,0,0,0,0,36,24,         228,160,162,162,162,162,162,128,156},
X/* '6' */ {9, 8,20,32,64,128,0,0,20,8,       12,16,50,82,146,18,18,0,12},
X/* '7' */ {9, 0,0,0,4,8,16,32,64,128,        128,128,130,132,136,144,160,192,128},
X/* '8' */ {9, 72,180,0,0,0,0,0,180,72,       108,0,146,146,146,146,146,0,108},
X/* '9' */ {9, 64,160,0,0,4,8,16,160,64,      96,0,144,144,146,148,152,16,96},
X/* ':' */ {4, 36,36,36,36,0,0,0,0,0,         54,54,54,54,0,0,0,0,0},
X/* ';' */ {4, 37,37,37,38,0,0,0,0,0,         54,54,54,55,0,0,0,0,0},
X/* '<' */ {7, 0,48,0,72,0,132,0,0,0,         16,0,40,0,68,0,130,0,0},
X/* '=' */ {9, 0,0,0,0,0,0,0,0,0,             40,40,40,40,40,40,40,40,40},
X/* '>' */ {7, 0,132,0,72,0,48,0,0,0,         130,0,68,0,40,0,16,0,0},
X/* '?' */ {9, 0,128,0,0,0,16,0,160,64,       64,0,128,128,138,138,144,0,96},
X/* '@' */ {9, 120,132,0,48,0,0,0,128,112,    124,0,130,146,170,170,170,42,114},
X/* 'A' */ {9, 28,32,64,128,0,128,64,32,28,   30,40,72,136,136,136,72,40,30},
X/* 'B' */ {9, 0,252,0,0,0,0,0,180,72,        130,254,146,146,146,146,146,0,108},
X/* 'C' */ {9, 120,132,0,0,0,0,0,132,0,       124,0,130,130,130,130,130,0,68},
X/* 'D' */ {9, 0,252,0,0,0,0,0,132,120,       130,254,130,130,130,130,130,68,56},
X/* 'E' */ {9, 252,0,0,0,0,0,0,0,0,           254,146,146,146,146,146,146,130,130},
X/* 'F' */ {9, 252,0,0,0,0,0,0,0,0,           254,144,144,144,144,144,144,128,128},
X/* 'G' */ {9, 120,132,0,0,0,0,0,4,24,        124,0,130,130,146,146,146,144,28},
X/* 'H' */ {9, 252,0,0,0,0,0,0,0,252,         254,16,16,16,16,16,16,16,254},
X/* 'I' */ {5, 0,0,252,0,0,0,0,0,0,           130,130,254,130,130,0,0,0,0},
X/* 'J' */ {8, 8,4,0,0,0,4,248,0,0,           12,0,2,130,130,128,252,128,0},
X/* 'K' */ {9, 252,0,0,48,0,72,0,132,0,       254,16,16,0,40,0,68,0,130},
X/* 'L' */ {9, 252,0,0,0,0,0,0,0,0,           254,2,2,2,2,2,2,2,2},
X/* 'M' */ {9, 252,128,64,32,0,32,64,128,252, 254,128,64,32,16,32,64,128,254},
X/* 'N' */ {9, 252,0,128,64,32,16,8,4,252,    254,128,64,32,16,8,4,2,254},
X/* 'O' */ {9, 120,132,0,0,0,0,0,132,120,     124,0,130,130,130,130,130,0,124},
X/* 'P' */ {9, 252,0,0,0,0,0,0,160,64,        254,144,144,144,144,144,144,0,96},
X/* 'Q' */ {9, 120,132,0,0,0,8,0,132,120,     124,0,130,130,138,130,134,0,126},
X/* 'R' */ {9, 252,0,0,0,0,16,8,164,64,       254,144,144,144,144,144,152,4,98},
X/* 'S' */ {9, 64,164,0,0,0,0,0,148,8,        100,0,146,146,146,146,146,0,76},
X/* 'T' */ {9, 0,0,0,0,252,0,0,0,0,           128,128,128,128,254,128,128,128,128},
X/* 'U' */ {9, 248,4,0,0,0,0,0,4,248,         252,0,2,2,2,2,2,0,252},
X/* 'V' */ {9, 224,16,8,4,0,4,8,16,224,       224,16,8,4,2,4,8,16,224},
X/* 'W' */ {9, 252,0,4,8,16,8,4,0,252,        252,2,4,8,16,8,4,2,252},
X/* 'X' */ {7, 132,72,48,0,48,72,132,0,0,     130,68,40,16,40,68,130,0,0},
X/* 'Y' */ {9, 128,64,32,16,12,16,32,64,128,  128,64,32,16,14,16,32,64,128},
X/* 'Z' */ {7, 0,4,8,16,32,64,128,0,0,        130,134,138,146,162,194,130,0,0},
X/* '[' */ {5, 252,0,0,0,0,0,0,0,0,           254,130,130,130,130,0,0,0,0},
X/* '\' */ {7, 128,64,32,16,8,4,0,0,0,        128,64,32,16,8,4,2,0,0},
X/* ']' */ {5, 0,0,0,0,252,0,0,0,0,           130,130,130,130,254,0,0,0,0},
X/* '^' */ {9, 0,64,0,128,0,128,0,64,0,       32,0,64,0,128,0,64,0,32},
X/* '_' */ {9, 1,1,1,1,1,1,1,1,1,             0,0,0,0,0,0,0,0,0},
X/* '`' */ {4, 128,64,0,0,0,0,0,0,0,          192,128,160,160,0,0,0,0,0},
X/* 'a' */ {9, 0,12,0,0,0,0,32,28,0,          4,0,42,42,42,42,10,28,2},
X/* 'b' */ {8, 252,0,0,0,0,0,36,24,0,         254,34,34,34,34,34,0,28,0},
X/* 'c' */ {8, 24,36,0,0,0,0,0,0,0,           28,0,34,34,34,34,34,34,0},
X/* 'd' */ {8, 24,36,0,0,0,0,0,252,0,         28,0,34,34,34,34,34,254,0},
X/* 'e' */ {9, 24,36,0,0,0,0,0,32,16,         28,8,42,42,42,42,42,10,24},
X/* 'f' */ {7, 0,0,0,124,128,0,0,0,0,         16,16,16,126,16,144,144,0,0},
X/* 'g' */ {8, 24,36,1,1,1,1,0,62,0,          28,0,34,34,34,34,35,62,0},
X/* 'h' */ {8, 252,0,0,0,0,0,32,28,0,         254,32,32,32,32,32,0,30,0},
X/* 'i' */ {5, 0,0,60,0,0,0,0,0,0,            34,34,190,2,2,0,0,0,0},
X/* 'j' */ {6, 1,1,1,1,0,62,0,0,0,            0,0,0,32,33,190,0,0,0},
X/* 'k' */ {7, 252,0,0,24,0,36,0,0,0,         254,8,8,0,20,0,34,0,0},
X/* 'l' */ {5, 0,0,252,0,0,0,0,0,0,           130,130,254,2,2,0,0,0,0},
X/* 'm' */ {9, 60,32,0,0,60,0,0,32,28,        62,0,32,32,62,32,32,0,30},
X/* 'n' */ {8, 60,0,0,0,0,0,32,28,0,          62,32,32,32,32,32,0,30,0},
X/* 'o' */ {9, 24,36,0,0,0,0,0,36,24,         28,0,34,34,34,34,34,0,28},
X/* 'p' */ {8, 63,0,0,0,0,0,36,24,0,          63,34,34,34,34,34,0,28,0},
X/* 'q' */ {8, 24,36,0,0,0,0,0,63,0,          28,0,34,34,34,34,34,63,0},
X/* 'r' */ {8, 60,0,32,0,0,0,0,0,0,           62,16,0,32,32,32,32,32,0},
X/* 's' */ {9, 0,48,0,0,0,0,0,12,0,           16,2,42,42,42,42,42,32,4},
X/* 't' */ {8, 0,0,248,4,0,0,0,0,0,           32,32,252,32,34,34,34,2,0},
X/* 'u' */ {9, 56,4,0,0,0,0,0,60,0,           60,0,2,2,2,2,2,60,2},
X/* 'v' */ {9, 32,16,8,4,0,4,8,16,32,         32,16,8,4,2,4,8,16,32},
X/* 'w' */ {9, 60,0,4,8,16,8,4,0,60,          60,2,4,8,16,8,4,2,60},
X/* 'x' */ {7, 0,36,24,0,24,36,0,0,0,         34,20,0,8,0,20,34,0,0},
X/* 'y' */ {9, 32,16,8,5,2,4,8,16,32,         32,16,8,5,2,4,8,16,32},
X/* 'z' */ {8, 4,0,8,0,16,0,32,0,0,           34,38,34,42,34,50,34,34,0},
X/* '{' */ {6, 0,48,72,132,0,0,0,0,0,         16,0,108,0,130,130,0,0,0},
X/* '|' */ {1, 204,0,0,0,0,0,0,0,0,           238,0,0,0,0,0,0,0,0},
X/* '}' */ {6, 0,0,132,72,48,0,0,0,0,         130,130,0,108,0,16,0,0,0},
X/* '~' */ {9, 0,128,0,128,0,64,0,64,0,       64,0,128,0,64,0,32,0,64},
X/*'DEL'*/ {9, 120,132,48,72,72,72,0,132,120, 124,0,0,0,0,0,0,0,0}
X};
+ END-OF-FILE nlqpsdat.c
chmod 'u=rw,g=r,o=' 'nlqpsdat.c'
echo 'SENT: -rw-r-----  1 leo          7848 Jun 24 12:29 nlqpsdat.c'
echo -n 'RCVD: '
/bin/ls -l nlqpsdat.c
exit 0