|
|
1.1 root 1: #include <errno.h>
2: #include <signal.h>
3: #include <stdio.h>
4: #include <sgtty.h>
5: #include <pwd.h>
6: #include <sys/vcmd.h>
7: #include <vfont.h>
8:
9: /*
10: * Cat Simulator for Versatec and Varian
11: * Modified for Varian with rotated fonts: wnj 5/30/80.
12: *
13: * Takes two extra special codes defined by rvsort:
14: * 0115 - break for new page, goto (0,0)
15: * 0116 - lead 64* following byte
16: */
17:
18: int prtmode[] = {VPRINT, 0, 0};
19: int pltmode[] = {VPLOT, 0, 0};
20:
21: #define DISPATCHSIZE 256 /* must be a power of two */
22: #define CHARMASK (DISPATCHSIZE-1)
23: #define NFONTS 25
24: #define SPECIALFONT 3
25: #define DSIZ ((sizeof *dispatch)*DISPATCHSIZE)
26: #define MAXF 4
27:
28: #define LOCAL_RAILMAG ".railmag"
29: #define GLOBAL_RAILMAG "/usr/lib/vfont/railmag"
30:
31: /*
32: * Here we make up for the fact that we only have 2112
33: * bits vertically when we need 2200 (11''*200/in), by
34: * a 4% vertical size squashing.
35: */
36: #define CONVERT(n) ((n*(200./432.))*(2112./2200.))
37: #define RECONVERT(n) ((n*(432./200.))*(2200./2112.))
38:
39: #define VA_RASTER_LENGTH 2112
40:
41: #define VA_BYTES_PER_LINE (VA_RASTER_LENGTH/8)
42:
43: #define NLINES 110
44: #define VA_BUFFER_SIZE (NLINES*VA_BYTES_PER_LINE)
45:
46:
47: #define TOF_TO_BOF (83-19+2)
48: #define BAN_TO_BOF (49-19+2)
49:
50: char buffer[VA_BUFFER_SIZE]; /* Big line buffers */
51: char *buf0p = &buffer[0]; /* Zero origin in circular buffer */
52:
53: char *calloc();
54: char *nalloc();
55: char *allpanic();
56: char chrtab[][16];
57:
58: struct header header;
59: struct dispatch *dispatch;
60:
61: struct fontdes {
62: int fnum;
63: int psize;
64: struct dispatch *disp;
65: char *bits;
66: } fontdes[NFONTS] = {
67: -1,
68: -1
69: };
70:
71: struct point_sizes {
72: int stupid_code;
73: int real_code;
74: } point_sizes[] = {
75: 010, 6,
76: 0, 7,
77: 01, 8,
78: 07, 9,
79: 02, 10,
80: 03, 11,
81: 04, 12,
82: 05, 14,
83: 0211, 16,
84: 06, 18,
85: 0212, 20,
86: 0213, 22,
87: 0214, 24,
88: 0215, 28,
89: 0216, 36,
90: 0, 0
91: };
92:
93: #define VA_FFLINES 2200
94: #define VP_FFLINES 650
95: #define VP_EOTLINES 1400
96: #define VA_ACCTFILE "/usr/adm/vaacct"
97: #define VP_ACCTFILE "/usr/adm/vpacct"
98:
99: int lines;
100:
101: int vc; /* varian/versatec output file descriptor */
102: int varian; /* 0 for versatec, 1 for varian. */
103: int BYTES_PER_LINE; /* VA_BYTES_PER_LINE or VP_BYTES_PER_LINE. */
104: int BUFFER_SIZE; /* VA_BUFFER_SIZE or VP_BUFFER_SIZE. */
105: int cfnum = -1;
106: int cpsize = 10;
107: int cfont = 1;
108: char *bits;
109: int nfontnum = -1;
110: int fontwanted = 1;
111: int npsize = 10;
112: int last_ssize = 02;
113: int xpos, ypos;
114: int esc, lead, back, verd, mcase, railmag;
115: double row, col;
116: char *fontname[MAXF];
117: char fnbuf[120];
118: char *scanline;
119: int linecount;
120:
121: char asctab[128] = {
122: '\0', /*blank*/
123: 'h', /*h*/
124: 't', /*t*/
125: 'n', /*n*/
126: 'm', /*m*/
127: 'l', /*l*/
128: 'i', /*i*/
129: 'z', /*z*/
130: 's', /*s*/
131: 'd', /*d*/
132: 'b', /*b*/
133: 'x', /*x*/
134: 'f', /*f*/
135: 'j', /*j*/
136: 'u', /*u*/
137: 'k', /*k*/
138: '\0', /*blank*/
139: 'p', /*p*/
140: '\06', /*_ 3/4 em dash*/
141: ';', /*;*/
142: '\0', /*blank*/
143: 'a', /*a*/
144: '\05', /*rule*/
145: 'c', /*c*/
146: '`', /*` open*/
147: 'e', /*e*/
148: '\'', /*' close*/
149: 'o', /*o*/
150: '\021', /*1/4*/
151: 'r', /*r*/
152: '\022', /*1/2*/
153: 'v', /*v*/
154: '-', /*- hyphen*/
155: 'w', /*w*/
156: 'q', /*q*/
157: '/', /*/*/
158: '.', /*.*/
159: 'g', /*g*/
160: '\023', /*3/4*/
161: ',', /*,*/
162: '&', /*&*/
163: 'y', /*y*/
164: '\0', /*blank*/
165: '%', /*%*/
166: '\0', /*blank*/
167: 'Q', /*Q*/
168: 'T', /*T*/
169: 'O', /*O*/
170: 'H', /*H*/
171: 'N', /*N*/
172: 'M', /*M*/
173: 'L', /*L*/
174: 'R', /*R*/
175: 'G', /*G*/
176: 'I', /*I*/
177: 'P', /*P*/
178: 'C', /*C*/
179: 'V', /*V*/
180: 'E', /*E*/
181: 'Z', /*Z*/
182: 'D', /*D*/
183: 'B', /*B*/
184: 'S', /*S*/
185: 'Y', /*Y*/
186: '\0', /*blank*/
187: 'F', /*F*/
188: 'X', /*X*/
189: 'A', /*A*/
190: 'W', /*W*/
191: 'J', /*J*/
192: 'U', /*U*/
193: 'K', /*K*/
194: '0', /*0*/
195: '1', /*1*/
196: '2', /*2*/
197: '3', /*3*/
198: '4', /*4*/
199: '5', /*5*/
200: '6', /*6*/
201: '7', /*7*/
202: '8', /*8*/
203: '9', /*9*/
204: '*', /***/
205: '\04', /*minus*/
206: '\01', /*fi*/
207: '\02', /*fl*/
208: '\03', /*ff*/
209: '\020', /* cent sign */
210: '\012', /*ffl*/
211: '\011', /*ffi*/
212: '(', /*(*/
213: ')', /*)*/
214: '[', /*[*/
215: ']', /*]*/
216: '\013', /* degree */
217: '\014', /* dagger */
218: '=', /*=*/
219: '\017', /* registered */
220: ':', /*:*/
221: '+', /*+*/
222: '\0', /*blank*/
223: '!', /*!*/
224: '\07', /* bullet */
225: '?', /*?*/
226: '\015', /*foot mark*/
227: '|', /*|*/
228: '\0', /*blank*/
229: '\016', /* copyright */
230: '\010', /* square */
231: '$', /*$*/
232: '\0',
233: '\0',
234: '"', /*"*/
235: '#', /*#*/
236: '<', /*<*/
237: '>', /*>*/
238: '@', /*@*/
239: '\\', /*\\*/
240: '^', /*^*/
241: '{', /*{*/
242: '}', /*}*/
243: '~' /*~*/
244: };
245:
246: char spectab[128] = {
247: '\0', /*blank*/
248: 'w', /*psi*/
249: 'h', /*theta*/
250: 'm', /*nu*/
251: 'l', /*mu*/
252: 'k', /*lambda*/
253: 'i', /*iota*/
254: 'f', /*zeta*/
255: 'r', /*sigma*/
256: 'd', /*delta*/
257: 'b', /*beta*/
258: 'n', /*xi*/
259: 'g', /*eta*/
260: 'u', /*phi*/
261: 't', /*upsilon*/
262: 'j', /*kappa*/
263: '\0', /*blank*/
264: 'p', /*pi*/
265: '@', /*at-sign*/
266: '7', /*down arrow*/
267: '\0', /*blank*/
268: 'a', /*alpha*/
269: '|', /*or*/
270: 'v', /*chi*/
271: '"', /*"*/
272: 'e', /*epsilon*/
273: '=', /*=*/
274: 'o', /*omicron*/
275: '4', /*left arrow*/
276: 'q', /*rho*/
277: '6', /*up arrow*/
278: 's', /*tau*/
279: '_', /*underrule*/
280: '\\', /*\*/
281: 'W', /*Psi*/
282: '\07', /*bell system sign*/
283: '\001', /*infinity*/
284: 'c', /*gamma*/
285: '\002', /*improper superset*/
286: '\003', /*proportional to*/
287: '\004', /*right hand*/
288: 'x', /*omega*/
289: '\0', /*blank*/
290: '(', /*gradient*/
291: '\0', /*blank*/
292: 'U', /*Phi*/
293: 'H', /*Theta*/
294: 'X', /*Omega*/
295: '\005', /*cup (union)*/
296: '\006', /*root en*/
297: '\014', /*terminal sigma*/
298: 'K', /*Lambda*/
299: '-', /*minus*/
300: 'C', /*Gamma*/
301: '\015', /*integral sign*/
302: 'P', /*Pi*/
303: '\032', /*subset of*/
304: '\033', /*superset of*/
305: '2', /*approximates*/
306: 'y', /*partial derivative*/
307: 'D', /*Delta*/
308: '\013', /*square root*/
309: 'R', /*Sigma*/
310: '1', /*approx =*/
311: '\0', /*blank*/
312: '>', /*>*/
313: 'N', /*Xi*/
314: '<', /*<*/
315: '\016', /*slash (longer)*/
316: '\034', /*cap (intersection)*/
317: 'T', /*Upsilon*/
318: '\035', /*not*/
319: '\023', /*right ceiling (rt of ")*/
320: '\024', /*left top (of big curly)*/
321: '\017', /*bold vertical*/
322: '\030', /*left center of big curly bracket*/
323: '\025', /*left bottom*/
324: '\026', /*right top*/
325: '\031', /*right center of big curly bracket*/
326: '\027', /*right bot*/
327: '\021', /*right floor (rb of ")*/
328: '\020', /*left floor (left bot of big sq bract)*/
329: '\022', /*left ceiling (lt of ")*/
330: '*', /*multiply*/
331: '/', /*divide*/
332: '\010', /*plus-minus*/
333: '\011', /*<=*/
334: '\012', /*>=*/
335: '0', /*identically equal*/
336: '3', /*not equal*/
337: '{', /*{*/
338: '}', /*}*/
339: '\'', /*' acute accent*/
340: '\`', /*` grave accent*/
341: '^', /*^*/
342: '#', /*sharp*/
343: '\036', /*left hand*/
344: '\037', /*member of*/
345: '~', /*~*/
346: 'z', /*empty set*/
347: '\0', /*blank*/
348: 'Y', /*dbl dagger*/
349: 'Z', /*box rule*/
350: '9', /*asterisk*/
351: '[', /*improper subset*/
352: ']', /*circle*/
353: '\0', /*blank*/
354: '+', /*eqn plus*/
355: '5', /*right arrow*/
356: '8' /*section mark*/
357: };
358:
359:
360: onintr()
361: {
362: signal(SIGINT, SIG_IGN);
363: signal(SIGHUP, SIG_IGN);
364: signal(SIGTERM, SIG_IGN);
365: exit(1);
366: }
367:
368: main(argc, argv)
369: int argc;
370: char *argv[];
371: {
372: register int wait = 0;
373: char *banarg;
374:
375: if (geteuid() == 0) {
376: nice(-40); nice(20); nice(-4);
377: setuid(1); /* daemon */
378: }
379: if (signal(SIGINT, SIG_IGN) == SIG_DFL) {
380: signal(SIGPIPE, SIG_IGN);
381: signal(SIGINT, onintr);
382: signal(SIGHUP, onintr);
383: } else
384: signal(SIGHUP, SIG_IGN);
385: if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
386: signal(SIGTERM, onintr);
387: argc--, argv++;
388:
389: varian = 1; /* Assume varian unless -W. */
390: banarg = NULL;
391: BYTES_PER_LINE = VA_BYTES_PER_LINE;
392: BUFFER_SIZE = VA_BUFFER_SIZE;
393:
394: while (argc > 0 && argv[0][0] == '-') {
395: switch (argv[0][1]) {
396:
397: case 'W': /* Wide: the versatec. */
398: /*
399: varian = 0;
400: BYTES_PER_LINE = VP_BYTES_PER_LINE;
401: BUFFER_SIZE = VP_BUFFER_SIZE;
402: */
403: fprintf(stderr, "rvcat: -W not implemented\n");
404: break;
405:
406: case 't':
407: vc = 1;
408: break;
409:
410: case 'w':
411: wait = 1;
412: break;
413:
414: case '3':
415: vc = 3; /* from vpd */
416: break;
417:
418: case 'b':
419: if (argc != 1) {
420: banarg = argv[1];
421: argc--, argv++;
422: }
423: break;
424:
425: default:
426: fprintf(stderr, "usage: rvcat [ -t ] [ -w ] [ -b banner ] [ file... ]\n");
427: exit(1);
428: }
429: argc--, argv++;
430: }
431: if (vc == 0) {
432: /* directly to plotter */
433: for (;;) {
434: extern int errno;
435:
436: if ((vc = open((varian ? "/dev/va0" : "/dev/vp0"), 1)) >= 0)
437: break;
438: if (!wait)
439: break;
440: if (errno != EIO && errno != ENXIO)
441: break;
442: sleep(10);
443: }
444: }
445: ioctl(vc, VSETSTATE, prtmode);
446: banner(banarg);
447: ioctl(vc, VSETSTATE, pltmode);
448: readrm();
449: for (;;) {
450: if (argc > 0) {
451: if (freopen(argv[0], "r", stdin) == NULL) {
452: perror(argv[0]);
453: argc--, argv++;
454: continue;
455: }
456: argc--, argv++;
457: }
458: ofile();
459: if (argc <= 0)
460: break;
461: ioctl(vc, VSETSTATE, prtmode);
462: if (varian) {
463: write(vc, "\014\0", 2);
464: newlines(TOF_TO_BOF);
465: } else
466: write (vc, "\n\n\n\n\n", 5);
467: ioctl(vc, VSETSTATE, pltmode);
468: }
469: ioctl(vc, VSETSTATE, prtmode);
470: account(banarg);
471: exit(0);
472: }
473:
474: readrm()
475: {
476: register int i;
477: register char *cp;
478: register int rmfd;
479: char c;
480:
481: if ((rmfd = open(LOCAL_RAILMAG, 0)) < 0)
482: if ((rmfd = open(GLOBAL_RAILMAG, 0)) < 0) {
483: fprintf(stderr, "No railmag file\n");
484: exit(1);
485: }
486: cp = fnbuf;
487: for (i = 0; i < 4; i++) {
488: fontname[i] = cp;
489: while (read(rmfd, &c, 1) == 1 && c != '\n')
490: *cp++ = c;
491: *cp++ = '\0';
492: }
493: close(rmfd);
494: }
495:
496: ofile()
497: {
498: register int c;
499: register int i;
500: double scol;
501: static int initialized;
502:
503: lines = 0;
504: while ((c = getchar()) != EOF) {
505: if (!c)
506: continue;
507: if (c & 0200) {
508: esc += (~c) & 0177;
509: continue;
510: }
511: if (esc) {
512: if (back)
513: esc = -esc;
514: col += esc;
515: esc = 0;
516: i = CONVERT(col);
517: while (i >= NLINES) {
518: slop_lines(15);
519: i = CONVERT(col);
520: }
521: ypos = i;
522: }
523: if ((c & 0377) < 0100) /* Purely for efficiency */
524: goto normal_char;
525: switch (c) {
526:
527: case 0100:
528: esc = 0;
529: lead = 0;
530: linecount = 0;
531: verd = 0;
532: back = 0;
533: mcase = 0;
534: railmag = 0;
535: if (loadfont(railmag, cpsize) < 0)
536: fprintf(stderr, "Can't load initial font\n");
537: if (initialized)
538: goto reset;
539: initialized = 1;
540: row = 0;
541: xpos = CONVERT(row);
542: for (c = 0; c < BUFFER_SIZE; c++)
543: buffer[c] = 0;
544: col = 0;
545: ypos = 0;
546: break;
547:
548: case 0101: /* lower rail */
549: crail(railmag &= ~01);
550: break;
551:
552: case 0102: /* upper rail */
553: crail(railmag |= 01);
554: break;
555:
556: case 0103: /* upper mag */
557: crail(railmag |= 02);
558: break;
559:
560: case 0104: /* lower mag */
561: crail(railmag &= ~02);
562: break;
563:
564: case 0105: /* lower case */
565: mcase = 0;
566: break;
567:
568: case 0106: /* upper case */
569: mcase = 0100;
570: break;
571:
572: case 0107: /* escape forward */
573: back = 0;
574: break;
575:
576: case 0110: /* escape backwards */
577: back = 1;
578: break;
579:
580: case 0111: /* stop */
581: break;
582:
583: case 0112: /* lead forward */
584: verd = 0;
585: break;
586:
587: case 0113: /* undefined */
588: break;
589:
590: case 0114: /* lead backward */
591: verd = 1;
592: break;
593:
594: case 0115: /* undefined */
595: reset:
596: c = lines % 1700;
597: if (c) {
598: do {
599: c = lines % 1700;
600: if (1700 - c > NLINES)
601: slop_lines(NLINES);
602: else
603: slop_lines(1700-c);
604: } while (lines % 1700);
605: }
606: row = 0;
607: col = 0;
608: xpos = CONVERT(row);
609: ypos = 0;
610: break;
611:
612: case 0116:
613: lead = (getchar() & 0377) * 64;
614: goto leadin;
615:
616: case 0117:
617: break;
618:
619: default:
620: if ((c & 0340) == 0140) /* leading */ {
621: lead = (~c) & 037;
622: leadin:
623: if (verd)
624: lead = -lead;
625: row += lead*3; /* Lead is 3 units */
626: xpos = CONVERT(row);
627: continue;
628: }
629: if ((c & 0360) == 0120) /* size change */ {
630: loadfont(railmag, findsize(c & 017));
631: continue;
632: }
633: if (c & 0300)
634: continue;
635:
636: normal_char:
637: if (row < 0 || CONVERT(row) >= VA_RASTER_LENGTH)
638: continue;
639: c = (c & 077) | mcase;
640: outc(c);
641: }
642: }
643: out:
644: slop_lines(NLINES);
645: }
646:
647: findsize(code)
648: register int code;
649: {
650: register struct point_sizes *psp;
651:
652: psp = point_sizes;
653: while (psp->real_code != 0) {
654: if ((psp->stupid_code & 017) == code)
655: break;
656: psp++;
657: }
658: code = 0;
659: if (!(last_ssize & 0200) && (psp->stupid_code & 0200))
660: code = -55;
661: else if ((last_ssize & 0200) && !(psp->stupid_code & 0200))
662: code = 55;
663: if (back)
664: code = -code;
665: esc += code;
666: last_ssize = psp->stupid_code;
667: return (psp->real_code);
668: }
669:
670: account(who)
671: char *who;
672: {
673: register FILE *a;
674:
675: if (who == NULL)
676: return;
677: a = fopen(varian ? VA_ACCTFILE : VP_ACCTFILE, "a");
678: if (a == NULL)
679: return;
680: /*
681: * Varian accounting is done by 8.5 inch pages;
682: * Versatec accounting is by the (12 inch) foot.
683: */
684: fprintf(a, "t%6.2f\t%s\n",
685: (lines / 200.0) / (varian ? 8.5 : 12.0), who);
686: fclose(a);
687: }
688:
689: crail(nrail)
690: register int nrail;
691: {
692: register int psize;
693:
694: psize = cpsize;
695: if (fontwanted && psize != npsize)
696: psize = npsize;
697: loadfont(nrail, psize);
698: }
699:
700:
701: loadfont(fnum, size)
702: register int fnum;
703: register int size;
704: {
705: register int i;
706: char cbuf[80];
707:
708: fontwanted = 0;
709: if (fnum == cfnum && size == cpsize)
710: return(0);
711: for (i = 0; i < NFONTS; i++)
712: if (fontdes[i].fnum == fnum && fontdes[i].psize == size) {
713: cfnum = fontdes[i].fnum;
714: cpsize = fontdes[i].psize;
715: dispatch = &fontdes[i].disp[0];
716: bits = fontdes[i].bits;
717: cfont = i;
718: return (0);
719: }
720: if (fnum < 0 || fnum >= MAXF) {
721: fprintf(stderr, "Internal error: illegal font\n");
722: return(-1);
723: }
724: nfontnum = fnum;
725: npsize = size;
726: fontwanted++;
727: return (0);
728: }
729:
730:
731: getfont()
732: {
733: register int fnum, size, font;
734: int d;
735: char cbuf[BUFSIZ];
736: char *cp = cbuf;
737: char *dp;
738:
739: if (!fontwanted)
740: return(0);
741: fnum = nfontnum;
742: size = npsize;
743: sprintf(cbuf, "%s.%dr", fontname[fnum], size);
744: font = open(cbuf, 0);
745: if (font == -1) {
746: perror(cbuf);
747: fontwanted = 0;
748: return (-1);
749: }
750: if (read(font, &header, sizeof header)!=sizeof header || header.magic!=0436)
751: fprintf(stderr, "%s: Bad font file", cbuf);
752: else {
753: cfont = relfont();
754: if (((bits=nalloc(header.size+DSIZ+1,1))== NULL)
755: && ((bits=allpanic(header.size+DSIZ+1))== NULL)) {
756: fprintf(stderr, "%s: ran out of memory\n", cbuf);
757: exit(1);
758: } else {
759: /*
760: * have allocated one chunk of mem for font, dispatch.
761: * get the dispatch addr, align to word boundary.
762: */
763: d = (int) bits+header.size;
764: d += 1;
765: d &= ~1;
766: if (read(font, d, DSIZ)!=DSIZ
767: || read(font, bits, header.size)!=header.size)
768: fprintf(stderr, "bad font header");
769: else {
770: close(font);
771: cfnum = fontdes[cfont].fnum = fnum;
772: cpsize = fontdes[cfont].psize = size;
773: fontdes[cfont].bits = bits;
774: fontdes[cfont].disp = (struct dispatch *) d;
775: dispatch = &fontdes[cfont].disp[0];
776: fontwanted = 0;
777: return (0);
778: }
779: }
780: }
781: close(font);
782: fontwanted = 0;
783: return(-1);
784: }
785:
786: int lastloaded = -1;
787:
788: relfont()
789: {
790: register int newfont;
791:
792: newfont = lastloaded;
793: /*
794: * optimization for special font. since we think that usually
795: * there is only one character at a time from any special math
796: * font, make it the candidate for removal.
797: */
798: if (fontdes[cfont].fnum != SPECIALFONT || fontdes[cfont].bits==0)
799: if (++newfont>=NFONTS)
800: newfont = 0;
801: lastloaded = newfont;
802: if ((int)fontdes[newfont].bits != -1 && fontdes[newfont].bits != 0) {
803: /* fprintf(stderr, "freeing position %d\n", newfont); */
804: nfree(fontdes[newfont].bits);
805: } else
806: /* fprintf(stderr, "taking without freeing position %d\n", newfont); */
807: ;
808: fontdes[newfont].bits = 0;
809: return (newfont);
810: }
811:
812: char *
813: allpanic(nbytes)
814: int nbytes;
815: {
816: register int i;
817:
818: for (i = 0; i <= NFONTS; i++)
819: if (fontdes[i].bits != (char *)-1 && fontdes[i].bits != (char *)0)
820: nfree(fontdes[i].bits);
821: lastloaded = cfont;
822: for (i = 0; i <= NFONTS; i++) {
823: fontdes[i].fnum = fontdes[i].psize = -1;
824: fontdes[i].bits = 0;
825: cfnum = cpsize = -1;
826: }
827: return(nalloc(nbytes,1));
828: }
829:
830: int M[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
831: 0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
832: int N[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
833: 0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
834: int strim[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
835:
836: outc(code)
837: int code;
838: {
839: char c; /* character to print */
840: register struct dispatch *d; /* ptr to character font record */
841: register char *addr; /* addr of font data */
842: int llen; /* length of each font line */
843: int nlines; /* number of font lines */
844: register char *scanp; /* ptr to output buffer */
845: int scanp_inc; /* increment to start of next buffer */
846: int offset; /* bit offset to start of font data */
847: int i; /* loop counter */
848: register int count; /* font data ptr */
849: register unsigned fontdata; /* font data temporary */
850: register int off8; /* offset + 8 */
851: int b0poff; /* bit offset back towards buf0p */
852:
853: if (fontwanted)
854: getfont();
855: if (railmag == SPECIALFONT) {
856: if ((c = spectab[code]) < 0)
857: return(0);
858: } else if ((c = asctab[code]) < 0)
859: return(0);
860: d = dispatch+c;
861: if (d->nbytes) {
862: addr = bits+d->addr;
863: llen = (d->down+d->up+7)/8;
864: nlines = d->left+d->right;
865: if (ypos+d->right >= NLINES)
866: slop_lines(ypos+d->right-NLINES+6);
867: b0poff = BYTES_PER_LINE*8 - 1 - (xpos+d->down);
868: scanp = ((ypos-d->left-1)*BYTES_PER_LINE+b0poff/8)+buf0p;
869: if (scanp < &buffer[0])
870: scanp += BUFFER_SIZE;
871: scanp_inc = BYTES_PER_LINE-llen;
872: offset = -(b0poff&07);
873: off8 = offset+8;
874: for (i = 0; i < nlines; i++) {
875: if (scanp >= &buffer[BUFFER_SIZE])
876: scanp -= BUFFER_SIZE;
877: count = llen;
878: if (scanp + count <= &buffer[BUFFER_SIZE])
879: do {
880: fontdata = *(unsigned *)addr;
881: addr += 4;
882: if (count < 4)
883: fontdata &= ~strim[count];
884: *(unsigned *)scanp |= (fontdata << offset) &~ M[off8];
885: scanp++;
886: *(unsigned *)scanp |= (fontdata << off8) &~ N[off8];
887: scanp += 3;
888: count -= 4;
889: } while (count > 0);
890: scanp += scanp_inc+count;
891: addr += count;
892: }
893: return (1);
894: }
895: return (0);
896: }
897:
898: slop_lines(ncols)
899: int ncols;
900: {
901: register int i, rcols;
902:
903: lines += ncols;
904: rcols = (&buffer[BUFFER_SIZE] - buf0p) / BYTES_PER_LINE;
905: if (rcols < ncols) {
906: if (write(vc, buf0p, BYTES_PER_LINE * rcols) < 0)
907: exit(1);
908: clear(buf0p, rcols * BYTES_PER_LINE);
909: buf0p = buffer;
910: ncols -= rcols;
911: ypos -= rcols;
912: col -= RECONVERT(rcols);
913: }
914: if (write(vc, buf0p, BYTES_PER_LINE * ncols) < 0)
915: exit(1);
916: clear(buf0p, BYTES_PER_LINE * ncols);
917: buf0p += BYTES_PER_LINE * ncols;
918: if (buf0p >= &buffer[BUFFER_SIZE])
919: buf0p -= BUFFER_SIZE;
920: ypos -= ncols;
921: col -= RECONVERT(ncols);
922: }
923:
924: /*ARGSUSED*/
925: clear(lp, nbytes)
926: int *lp;
927: int nbytes;
928: {
929:
930: asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
931:
932: }
933:
934: char *
935: nalloc(i, j)
936: int i, j;
937: {
938: register char *cp;
939:
940: cp = calloc(i, j);
941: /* fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); */
942: return(cp);
943: }
944:
945: nfree(cp)
946: char *cp;
947: {
948:
949: /* fprintf(stderr, "freeing at %x\n", cp); */
950: free(cp);
951: }
952:
953: banner(s)
954: char *s;
955: {
956: long timeb;
957: register char *sp;
958: int i, j, t;
959:
960: if (!varian) { /* Versatec uses just a small banner. */
961: if (s == NULL) /* No banner, just return. */
962: return;
963: write(vc, s, strlen(s));
964: write(vc, " ", 1);
965: time(&timeb);
966: write(vc, ctime(&timeb), 26);
967: return;
968: }
969:
970: write(vc, "\014\0", 2);
971: if (s == NULL) {
972: /* Do enough newlines to get exactly to the perforation. */
973: newlines(TOF_TO_BOF);
974: return;
975: }
976: newlines(8);
977: for (i=0; i<16; i++)
978: {
979: write(vc, " ", 16);
980: for (sp=s; *sp; sp++)
981: {
982: char obuf[10];
983: char *cp = obuf;
984:
985: if (*sp<=' '|| *sp >'}')
986: continue;
987: *cp++ = ' ', *cp++ = ' ';
988: t = chrtab[*sp - ' '][i];
989: for (j=7; j>=0; j--)
990: if ((t>>j) & 01)
991: *cp++ = 'X';
992: else
993: *cp++ = ' ';
994: write(vc, obuf, 10);
995: }
996: write (vc, " \n", 2);
997: }
998: newlines(8);
999: write(vc, " ", 16);
1000: time(&timeb);
1001: write(vc, ctime(&timeb), 26);
1002: newlines(BAN_TO_BOF);
1003: }
1004:
1005: newlines(count)
1006: int count;
1007: {
1008: char buf[100];
1009: register int i;
1010:
1011: for (i = 0; i < count; i++)
1012: buf[i] = '\n';
1013: buf[i] = '\0';
1014: write(vc, buf, i+1);
1015: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.