* Cat Simulator for Versatec
#define SETSTATE (('v'<<8)|1)
int pltmode
[] = {0200, 0, 0};
#define DISPATCHSIZE 256 /* must be a power of two */
#define CHARMASK (DISPATCHSIZE-1)
#define DSIZ ((sizeof *dispatch)*DISPATCHSIZE)
#define LOCAL_RAILMAG ".railmag"
#define GLOBAL_RAILMAG "/usr/lib/vfont/railmag"
#define CONVERT(n) (n*(200./432.))
#define RECONVERT(n) (n*(432./200.))
#define RASTER_LENGTH 7040
#define BYTES_PER_LINE (RASTER_LENGTH/8)
#define BUFFER_SIZE (NLINES*BYTES_PER_LINE)
char buffer
[BUFFER_SIZE
]; /* Big line buffers */
char *buf0p
= &buffer
[0]; /* Zero origin in circular buffer */
struct passwd
*getpwuid();
struct dispatch
*dispatch
;
/* Accounting assumes roll paper */
#define ACCTFILE "/usr/adm/vpacct"
int vc
; /* versatec output file descriptor */
int esc
, lead
, back
, verd
, mcase
, railmag
;
'\07', /*bell system sign*/
'\002', /*improper superset*/
'\003', /*proportional to*/
'\014', /*terminal sigma*/
'\015', /*integral sign*/
'y', /*partial derivative*/
'\016', /*slash (longer)*/
'\034', /*cap (intersection)*/
'\023', /*right ceiling (rt of ")*/
'\024', /*left top (of big curly)*/
'\017', /*bold vertical*/
'\030', /*left center of big curly bracket*/
'\031', /*right center of big curly bracket*/
'\021', /*right floor (rb of ")*/
'\020', /*left floor (left bot of big sq bract)*/
'\022', /*left ceiling (lt of ")*/
'0', /*identically equal*/
signal(SIGTERM
, SIG_IGN
);
if (signal(SIGINT
, SIG_IGN
) == SIG_DFL
) {
signal(SIGPIPE
, SIG_IGN
);
if (signal(SIGTERM
, SIG_IGN
) == SIG_DFL
)
while (argc
> 0 && argv
[0][0] == '-') {
write(3, argv
[1], strlen(argv
[1]));
write(3, ctime(&tim
), 26);
fprintf(stderr
, "usage: vcat [ -t ] [ -w ] [ file... ]\n");
/* directly to versatec */
if ((vc
= open("/dev/vp0", 1)) >= 0)
if (errno
!= EIO
&& errno
!= ENXIO
)
fprintf(stderr
, "Versatec off line\n");
fprintf(stderr
, "Versatec in use\n");
fprintf(stderr
, "Versatec not available\n");
ioctl(vc
, SETSTATE
, pltmode
);
if (freopen(argv
[0], "r", stdin
) == NULL
) {
if ((rmfd
= open(LOCAL_RAILMAG
, 0)) < 0)
if ((rmfd
= open(GLOBAL_RAILMAG
, 0)) < 0) {
fprintf(stderr
, "No railmag file\n");
for (i
= 0; i
< 4; i
++) {
while (read(rmfd
, &c
, 1) == 1 && c
!= '\n')
while ((c
= getchar()) != EOF
) {
if ((c
& 0377) < 0100) /* Purely for efficiency */
for (c
= 0; c
< sizeof buffer
; c
++)
if (loadfont(railmag
, cpsize
) < 0)
fprintf(stderr
, "Can't load inital font\n");
case 0101: /* lower rail */
case 0102: /* upper rail */
case 0103: /* upper mag */
case 0104: /* lower mag */
case 0105: /* lower case */
case 0106: /* upper case */
case 0107: /* escape forward */
case 0110: /* escape backwards */
case 0112: /* lead forward */
case 0113: /* undefined */
case 0114: /* lead backward */
case 0115: /* undefined */
if ((c
& 0340) == 0140) /* leading */ {
row
+= lead
*3; /* Lead is 3 units */
if ((c
& 0360) == 0120) /* size change */ {
loadfont(railmag
, findsize(c
& 017));
register struct point_sizes
*psp
;
while (psp
->real_code
!= 0) {
if ((psp
->stupid_code
& 017) == code
)
if (!(last_ssize
& 0200) && (psp
->stupid_code
& 0200))
else if ((last_ssize
& 0200) && !(psp
->stupid_code
& 0200))
last_ssize
= psp
->stupid_code
;
register struct passwd
*p
;
a
= fopen(ACCTFILE
, "a");
fprintf(stderr
, "Who are you?\n");
fprintf(a
, "t%6.2f\t%s\n", (lines
/ 200.0) / 12.0, p
->pw_name
);
if (fontwanted
&& psize
!= npsize
)
if (fnum
== cfnum
&& size
== cpsize
)
for (i
= 0; i
< NFONTS
; i
++)
if (fontdes
[i
].fnum
== fnum
&& fontdes
[i
].psize
== size
) {
cpsize
= fontdes
[i
].psize
;
dispatch
= &fontdes
[i
].disp
[0];
if (fnum
< 0 || fnum
>= MAXF
) {
fprintf(stderr
, "Internal error: illegal font\n");
register int fnum
, size
, font
;
sprintf(cbuf
, "%s.%d", fontname
[fnum
], size
);
if (read(font
, &header
, sizeof header
)!=sizeof header
|| header
.magic
!=0436)
fprintf(stderr
, "%s: Bad font file", cbuf
);
if (((bits
=nalloc(header
.size
+DSIZ
+1,1))== NULL
)
&& ((bits
=allpanic(header
.size
+DSIZ
+1))== NULL
)) {
fprintf(stderr
, "%s: ran out of memory\n", cbuf
);
* have allocated one chunk of mem for font, dispatch.
* get the dispatch addr, align to word boundary.
d
= (int) bits
+header
.size
;
if (read(font
, d
, DSIZ
)!=DSIZ
|| read(font
, bits
, header
.size
)!=header
.size
)
fprintf(stderr
, "bad font header");
cfnum
= fontdes
[cfont
].fnum
= fnum
;
cpsize
= fontdes
[cfont
].psize
= size
;
fontdes
[cfont
].bits
= bits
;
fontdes
[cfont
].disp
= (struct dispatch
*) d
;
dispatch
= &fontdes
[cfont
].disp
[0];
* optimization for special font. since we think that usually
* there is only one character at a time from any special math
* font, make it the candidate for removal.
if (fontdes
[cfont
].fnum
!= SPECIALFONT
|| fontdes
[cfont
].bits
==0)
if ((int)fontdes
[newfont
].bits
!= -1 && fontdes
[newfont
].bits
!= 0) {
/* fprintf(stderr, "freeing position %d\n", newfont); */
nfree(fontdes
[newfont
].bits
);
/* fprintf(stderr, "taking without freeing position %d\n", newfont); */
fontdes
[newfont
].bits
= 0;
for (i
= 0; i
<= NFONTS
; i
++)
if (fontdes
[i
].bits
!= -1 && fontdes
[i
].bits
!= 0)
for (i
= 0; i
<= NFONTS
; i
++) {
fontdes
[i
].fnum
= fontdes
[i
].psize
= -1;
return(nalloc(nbytes
,1));
int M
[] = { 0xffffffff, 0xfefefefe, 0xfcfcfcfc, 0xf8f8f8f8,
0xf0f0f0f0, 0xe0e0e0e0, 0xc0c0c0c0, 0x80808080, 0x0 };
int N
[] = { 0x00000000, 0x01010101, 0x03030303, 0x07070707,
0x0f0f0f0f, 0x1f1f1f1f, 0x3f3f3f3f, 0x7f7f7f7f, 0xffffffff };
int strim
[] = { 0xffffffff, 0xffffff00, 0xffff0000, 0xff000000, 0 };
char c
; /* character to print */
register struct dispatch
*d
; /* ptr to character font record */
register char *addr
; /* addr of font data */
int llen
; /* length of each font line */
int nlines
; /* number of font lines */
register char *scanp
; /* ptr to output buffer */
int scanp_inc
; /* increment to start of next buffer */
int offset
; /* bit offset to start of font data */
int i
; /* loop counter */
register int count
; /* font data ptr */
register unsigned fontdata
; /* font data temporary */
register int off8
; /* offset + 8 */
if (railmag
== SPECIALFONT
) {
if ((c
= spectab
[code
]) < 0)
} else if ((c
= asctab
[code
]) < 0)
llen
= (d
->left
+d
->right
+7)/8;
if (xpos
+d
->down
>= NLINES
)
slop_lines(xpos
+d
->down
-NLINES
+1);
scanp
= ((xpos
-d
->up
-1)*BYTES_PER_LINE
+(ypos
-d
->left
)/8)+buf0p
;
scanp_inc
= BYTES_PER_LINE
-llen
;
offset
= -((ypos
-d
->left
)&07);
for (i
= 0; i
< nlines
; i
++) {
if (scanp
>= &buffer
[BUFFER_SIZE
])
if (scanp
+ count
<= &buffer
[BUFFER_SIZE
])
fontdata
= *(unsigned *)addr
;
fontdata
&= ~strim
[count
];
*(unsigned *)scanp
|= (fontdata
<< offset
) &~ M
[off8
];
*(unsigned *)scanp
|= (fontdata
<< off8
) &~ N
[off8
];
scanp
+= scanp_inc
+count
;
rlines
= (&buffer
[BUFFER_SIZE
] - buf0p
) / BYTES_PER_LINE
;
write(vc
, buf0p
, BYTES_PER_LINE
* rlines
);
clear(buf0p
, rlines
* BYTES_PER_LINE
);
row
-= RECONVERT(rlines
);
write(vc
, buf0p
, BYTES_PER_LINE
* nlines
);
clear(buf0p
, BYTES_PER_LINE
* nlines
);
buf0p
+= BYTES_PER_LINE
* nlines
;
if (buf0p
>= &buffer
[BUFFER_SIZE
])
row
-= RECONVERT(nlines
);
ioctl(vc
, SETSTATE
, pltmode
);
asm("movc5 $0,(sp),$0,8(ap),*4(ap)");
/* fprintf(stderr, "allocated %d bytes at %x\n", i * j, cp); */
/* fprintf(stderr, "freeing at %x\n", cp); */