--- /dev/null
+/**/
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include <sys/ioctl.h>
+#include <linux/ppdev.h>
+
+#define COLUMNS 7
+#define ROWS 8
+
+static const void badusage(const char *what) {
+ fprintf(stderr,"bad usage: %s\n"
+ "usage: train-pic-prog-select [-p/dev/parport] picno|range...\n"
+ "ranges are picno-picno (inclusive)\n",
+ what);
+ exit(126);
+}
+
+typedef unsigned char yesno;
+
+const char *parport= "/dev/parport0";
+
+static union {
+ yesno rect[COLUMNS][ROWS];
+ yesno lin[COLUMNS*ROWS];
+} yesses;
+
+static int fd;
+
+static void doioctl(int ioctlnum, void *vp, unsigned long vpv) {
+ int r;
+ errno=0;
+ r= ioctl(fd, ioctlnum, vp);
+ if (r) {
+ fprintf(stderr,"ioctl #%d 0x%lx gave %d %s\n",
+ ioctlnum, vpv, r, strerror(errno));
+ exit(127);
+ }
+}
+
+static void wpause(int ioctlnum, unsigned char value) {
+ printf(" %s%02x",
+ ioctlnum == PPWCONTROL ? "C" :
+ ioctlnum == PPWDATA ? "" : 0,
+ value);
+ doioctl(ioctlnum, &value, value);
+ usleep(5000);
+}
+
+int main(int argc, const char *const *argv) {
+ long first, last;
+ int row, col, v;
+ char *ep;
+ const char *arg;
+
+ if (!*argv++) badusage("need argv[0]");
+ while ((arg= *argv) && arg[0]=='-') {
+ argv++;
+ if (arg[1]=='p') {
+ parport= arg+2;
+ } else {
+ badusage("unknown option");
+ }
+ }
+ if (!*argv) badusage("need to specify pics");
+ while ((arg= *argv++)) {
+ first= last= strtol(arg,&ep,10);
+ if (ep==arg) badusage("syntactically incorrect pic number");
+ if (*ep == '-') {
+ last= strtol((arg=ep+1),&ep,10);
+ if (ep==arg) badusage("syntactically incorrect range");
+ }
+ if (*ep) badusage("syntactically incorrect picno or range");
+ if (first<0 || last>COLUMNS*ROWS-1 || first<last)
+ badusage("picno or range out of permissible range");
+ for (; first<=last; first++) {
+ if (yesses.lin[first]) badusage("one pic specified more than once");
+ yesses.lin[first]= 1;
+ }
+ }
+ fd= open(parport, O_RDWR);
+ if (fd<0) { perror(parport); exit(-1); }
+
+ setvbuf(stdout,0,_IONBF,0);
+
+ doioctl(PPCLAIM,0,0);
+ wpause(PPWCONTROL, 0x02 /* !ENGAGE_VPP, !PC, !PDW */);
+
+ for (row=0; row<ROWS; row++) {
+ v= 0;
+ for (col=0; col<COLUMNS; col++)
+ v |= yesses.rect[col][row] ? (1<<col) : 0;
+ wpause(PPWDATA, v | 0x80);
+ wpause(PPWDATA, v); /* SEL_CLK ~|_ shifts */
+ }
+ wpause(PPWDATA, 0xff); /* SEL_CLK _|~ deploys */
+ putchar('\n');
+ return 0;
+}