Today I present to you the Silver Reed EB-50. Made in 1985, this thing has a bit of an identity crisis. It’s a printer, a plotter and a typewriter all in one. The reason I got it was because it uses the same tiny ball-point pens that the Commodore 1520 printer/plotter uses. However, this prints on normal 8.5″ wide paper. It’s also very portable, has a lid that covers the keyboard and a flip out handle. It can run on batteries (5 x D cells OMG heavy) or on DC 7.5V power (center negative in case you want to know). For $9.99 it was a bargain curiosity that I couldn’t pass up.
In normal typewriter mode, you press a key and it will “draw” that character in one of 3 sizes, styles or directions in one of 4 colors. You can position the print head anywhere you’d like to print text. In addition, there are function keys to create graphs, right on the typewriter. Pie charts, bar graphs and line graphs are simple– select the type, enter the data points and it prints a graph at the print head position. Pretty clever for something that works sans computer.
Switch it to printer mode and now a computer takes over via the parallel port. This is where things got weird. I found reference to someone that wrote a program to convert HPGL plotter files to ones that printed on this one. This was key since there was no manual and I ran out of internets. But the file was locked up in a “drivers” ad supported nightmare of a website that had me install some bullshit driver manager on Windows to “install” a C code source file. What-fucking-ever. It’s included below in you want it.
A quick Processing sketch later and I’ve produced some output on it from my Mac using an old PowerPrint serial to parallel adapter via a KeySpan USB to serial adapter. Lots of adaptation, but what do you expect from a nearly 26 year old printer.
# hp2eb50.c #include <stdio.h> #define SCAL(x) (((x)+halfscale)/scale) #define NUMV(x) ((x)=='-' || ((x) <= '9' && (x) >= '0')) #define SP ('S'<<8)+'P' #define PU ('P'<<8)+'U' #define PD ('P'<<8)+'D' #define PA ('P'<<8)+'A' #define IW ('I'<<8)+'W' #define SC ('S'<<8)+'C' #define LB ('L'<<8)+'B' FILE *source, *plotter; short c,i,j,pen,scale,x1,x2,y1,y2,hx,hy,halfscale; short befehl,ende,rot, colour[] = {0,1,2,3,0,1,2,3}; char param[100], *output; void upcase(s) char *s; { register char c; register int i=0; while ((c = *(s++)) && i<99) { param[i++] = (c>='a' && c<='z')? c-'a'+'A' : c; } param[i] = 0; } short get_num() { register short c,x=0; short s; if (ende) return(0); else { while(((c = getc(source)) & 0x1ff) <= ' '); if (c == '-') { s=-1; c = getc(source); } else s=1; while (c >= '0' && c <= '9') { x = x*10+c-'0'; while(((c = getc(source)) & 0x1ff) <= ' '); } if (c == ';') ende = -1; return(x*s); } } void rotate() { register short h; if (rot) { y2 = y1; h = x1; x1 = y1; y1 = -h; } } main(argc,argv) int argc; char *argv[]; { if (argc<2) { printf("Usage: %s <hpgl-file> [SCALE <scale>] [ROT] [COLOUR <n1..n8>] [TO <output filename>]n",argv[0]); exit(0); } rot = 0; output = "par:"; for (i=2;i<argc;i++) { upcase(argv[i]); if (!strcmp(param,"ROT")) rot=1; if (!strcmp(param,"SCALE") && i<argc-1) { scale = atol(argv[++i]); if (scale == 0) scale = 1; } if (!strcmp(param,"TO") && i<argc-1) output = argv[++i]; if (!strcmp(param,"COLOUR") && i<argc-1) { for (i++,j=0;j<8;j++) colour[j]=(argv[i][j]-'0') & 0x03; } } halfscale = scale/2; if (!(source = fopen(argv[1],"r"))) { puts("Sorry - Can't open file!"); exit(0); } if (!(plotter = fopen(output,"w"))) { puts("Sorry - Can't open output file"); fclose(source); exit(0); } pen = 0; fputc(18,plotter); puts(" Command no.:"); j = 1; do { i = ende = 0; do { c = getc(source); } while (((c < 'A') || (c > 'Z')) && (c != -1)); befehl = (c==-1)? 0 : (c & 0xff)<<8 | (getc(source) & 0xff); printf("2331A23313C %5dn",j++); switch(befehl) { case SP : { x1 = get_num(); if (x1) fprintf(plotter,"C%d;n",colour[(x1-1)&7]); break; } case PU : { pen = 0; break; } case PD : { pen = 1; break; } case PA : { while (!ende) { x1 = SCAL(get_num()); if (!ende) { y1 = SCAL(get_num()); rotate(); if (pen==1) fprintf(plotter,"D%d,%d;n",x1,y1); else fprintf(plotter,"M%d,%d;n",x1,y1); } } break; } case LB : { fputc('P',plotter); while((c = getc(source)) >= 32) putc(c,plotter); putc(13,plotter); putc(10,plotter); break; } case SC : { x1 = get_num(); if (ende) break; x2 = get_num(); y1 = get_num(); y2 = get_num(); } case IW : { if (befehl==IW) { x1 = get_num(); y1 = get_num(); y2 = get_num(); y2 = get_num(); } hx = (x2-x1+999)/1000; hy = (y2-y1+999)/1000; hx = (hx>hy)? hx : hy; if (scale<hx) { scale = hx; halfscale = scale/2; printf("New scale: %dn2331A",scale); } rotate(); fprintf(plotter,"M%d,%d;nI;n",SCAL(-x1),SCAL(-y2)); } } } while (c!=-1); fputc(17,plotter); fclose(source); fclose(plotter); puts("nReady.n"); }