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