@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ÅÙÔÁ×@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@åÖÓñÁÔÃ@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@æÈÄÙñ@ÄÁãÁ@@@@@@@@@@@@@@@ðøð@ðñððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ðñððñ@ÄÄÙñ@ÄÁãÁðù@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñð@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁññ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñò@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñó@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñô@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñõ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñö@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñ÷@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñø@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁñù@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòð@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòñ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòò@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòó@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòô@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòõ@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ÄÄÙñ@ÄÁãÁòö@@@@@@@@@@@@@ðøð@÷ôððñ@÷óðòö@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@÷ôððñ@ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååSCRIBBLEGBLj SCRIBBLECRL.ALLOC CRLAUXIL C N !"#ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååAME 20 /* length of a file name */ #endif #ifdef UNIX #define BUFFRECS 1024 /* I/O buffer size in bytes */ #define BUFFSIZL2 C º»¼½CHARIO C ¾¿ÀÁLC SUBÂåååååååååååååååååååååååååååååååå /* -------------------------------------------------- */ /* program constants */ #define MAXLINES 100 /* max # of linAUXILTOOC I$%&'()*+,-COMMANDSC C./0123456COMMTOO C ^789:;<=>?@ABINPUT CRL%CDEFGååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååE 1024 /* I/O buffer size in bytes */ #define RECSIZE 1 /* I/O record size */ #define LENFILENAME 30 /* length of a file naååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååes/page */ #define MAXTOKENS 50 /* max # of tokens/line */ #define MAXMESSAGE 150 /* max # of chars in error message */ #deOUTPUT CRLBHIJKLMNOPSC SUBQCRAYON H JRSTUVWXYZ[CRAYON C f\]^_`abcdefghååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååme */ #endif /* -------------------------------------------------- */ /* programming conventions */ #define repeat whååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååfine STACKSIZE 2048 /* amount of stack space to reserve */ #ifdef CPM #define BUFFRECS 8 /* i/o buffer size in records */ PRINTER C {ijklmnopqrstuvwxDRIVER C vyz{|}~€�‚ƒ„…†‡QUEUE CRL ˆ‰PENCIL C >Š‹Œ�Ž��‘/* SCRIBBLE.GBL -- Global Definitions for Scribble written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååile (TRUE) #define TRUE 1 #define FALSE 0 #define NULL 0 #define MICA unsigned #define FLAG char #define STRING charåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå#define BUFFSIZE (128*8) /* i/o buffer size in bytes */ #define RECSIZE 128 /* i/o record size in bytes */ #define LENFILENCC SUB’DIFF C H“”•–—˜™š›L2 COMlœ�žŸ ¡¢£¤¥¦§¨©L2 C €ª«¬­®¯°±²³´µ¶·¸¹the Unicorn */ /* compilation flags */ #define CPM /* CP/M only */ /* #define UNIX */ /* UNIX only */ #define LARGE #define LINEHEIGHT dev.stdvert #define CHARRES dev.micahoriz #define CHARWIDTH dev.stdhoriz /* ASCII characters */ #de'@' #define HEADERCENTER 0203 /* ~^C */ #define HEADERRIGHT 0222 /* ~^R */ #define HEADERLINE 0214 /* ~^L */ /* optioF 0364 /* ~t */ #define EXITON 0330 /* ~X eXit unusual attributes */ #define EXITOFF 0370 /* ~x */ #define JUSTIFY /* right margin */ MICA lspace; /* line spacing */ FLAG howjustify; /* how is the line justified? */ MICA column; /*define UNNBOFF 0365 /* ~u */ #define UNALLON 0301 /* ~A underscore everything */ #define UNALLOFF 0341 /* ~a */ #defineed)48000) /* largest legal mica mesurment */ #endif /* -------------------------------------------------- */ /* allocatorfine NUL 0 #define BELL '\7' #define BS '\8' #define TAB '\t' #define LF '\12' #define FF '\14' #define CR '\15' #define ns for argument routines */ #define ARGFLUSH 'f' #define RETURN 'r' #define PRINT 'p' #define HOLD 'h' #define SAM 0212 /* ~^J */ #define HORIZSPACE 0210 /* ~^H */ #define VERTSPACE 0226 /* ~^V */ #define TOKBREAK 0240 /* ~SP */ column that you were in */ struct buftok { /* for each token, its length and a */ MICA length; /* ptr to it */ ST UNANON 0316 /* ~N underscore alphanumeric */ #define UNANOFF 0356 /* ~n */ #define ITALON 0311 /* ~I italics */ #def */ int *Acap, *Abegin, *Aend, Asize; #define SPACE int SPACE *PageSpace, *EndSpace, *DefSpace; /* -------------------SP ' ' #define DEL '\177' #define NL '\n' #define EOF '\32' /* -------------------------------------------------- */ /*PLE 'd' /* measurement */ #define INCH 2540 /* 2540 mica/inch (2540 = 2 x 2 x 5 x 127) */ #define HALFINCH 1270 /* 1/* -------------------------------------------------- */ /* token types */ #define EOFT '\32' #define WHITESPACE ' ' RING *line; } toks[MAXTOKENS]; } lin, linsave; struct { /* page information */ MICA ptop; /* margins */ MICA pline ITALOFF 0351 /* ~i */ #define BITALON 0320 /* ~P bold italics */ #define BITALOFF 0360 /* ~p */ #define SUPERON 03------------------------------- */ /* line structures */ #define LINEDATA struct linestruct struct linestruct { /* buf output file description */ #define SENTENCEBREAK 0177 /* ^? */ #define BOLDON 0302 /* ~B */ #define BOLDOFF 0342 //2" */ #define CENTIMETER 1000 /* 1000 mica/cm */ #define PICA 423 /* 1/3 */ /* 1/6" */ #define POINT 35 /* 5/18 */ /* 1/1#define NEWLINE '\n' #define TOKEN 'A' #define TOKENBREAK 'B' #define FLUSH 'F' #define DELIM '(' #define COMMAND eft; MICA pright; MICA pbottom; LINEDATA *page[MAXLINES];/* each line */ MICA vertical[MAXLINES]; /* its height */ int23 /* ~S superscripts */ #define SUPEROFF 0363 /* ~s */ #define SUBON 0324 /* ~T subscripts (why not?) */ #define SUBOFfered line and ancillary info. */ int numtoks; /* number of token used */ MICA lleft; /* left margin */ MICA lright; * ~b */ #define ROMANON 0322 /* ~R */ #define ROMANOFF 0362 /* ~r */ #define UNNBON 0325 /* ~U underscore tokens */ #2 pica or 1/72" */ #ifdef CPM #define MAXMICA 48000 /* largest possible mica measurement */ #else #define MAXMICA ((unsign numlines; /* number of lines */ MICA cumvert; /* how much space we've used up */ int footerline; /* where footnotes st;/* where tabs are */ MICA headerspace; /* vertical space to leave after header */ MICA footerspace; /* and before footer fileprev; } file; char inputbuffer[BUFFSIZE]; #ifdef CPM char tokentype; /* type of the current token */ char typearrahe output device */ char dname[16]; /* name of the device */ MICA dwidth; /* width of the printing surface */ MICA dheimber of characters in the buffer */ char ibuffer[MAXINPLEN+1]; } inp, inpsave[MAXINPNUM]; #define TOKMAXLEN 100 struct {top; /* margins */ MICA sleft; MICA sright; MICA sbottom; MICA above; /* space to leave before an environment */ Mart */ MICA footerplace; /* where on the page footnotes starts */ int endline; /* where the footer starts */ FLAG isfoo*/ char prefjust; /* preferred justification style 'b' both or 'l' left */ char footstyle; /* where footnotes gy[256]; /* types for each character */ #else int tokentype; /* type of the current token */ int typearray[256]; /* typeght; /* height of the print surface */ MICA micahoriz; /* size of smallest horizontal increment */ MICA micavert; /* si /* current input token */ int tbuflen; char tbuffer[TOKMAXLEN+1]; } tok; #define INBUFFER struct inbuffer INBUFICA below; /* space to leave after an environment */ FLAG levindent; /* do nested Level environments indent? */ FLAG levhtnote; /* in footnote mode? */ LINEDATA **lastline; /* ptr to the last line loaded */ int lastindex; /* index of the lasto: 'i' inline, 'b' bottom, 'e' end */ MICA indent; /* amount to indent paragraphs */ MICA spread; /* number of s for each character */ #endif FLAG unget; /* TRUE if you are ungetting */ /* ------------------------------------------ze of smallest vertical incrment */ FLAG isprop; /* does it have a proportial width font? */ char fontnum; /* if isprop,FER { /* input buffer descriptor */ int fd; /* file descriptor or -1 for string */ char *curchar; /* ptr to current chang; /* are Level paragraphs outdented? */ int endsize; /* amount to leave for end space */ } sty; /* --------------- line loaded */ } pag; /* -------------------------------------------------- */ /* input tokenizer stuff */ #define Mlines between paragraphs */ MICA spacing; /* line spacing */ FLAG footpush; /* are refs superscripts or bracketed? */ -------- */ /* defaults and personal style */ #define MAXTABS 32 /* max # of tabs */ struct { MICA tabcolumns[MAXTABS] which width table to use */ MICA stdhoriz; /* width of a canonical character */ MICA stdvert; /* height of a single spaaracter */ unsigned blocknum; unsigned linenum; char filedesc[LENFILENAME]; /* descriptive name of thingie */ INBUFFER *----------------------------------- */ /* device structures */ #define SSPACE 128-54 struct printdesc { /* describes tAXINPLEN 300 #define MAXINPNUM 2 char inpnum; /* stack ptr */ struct { /* input token buffer */ int ibuflen; /* nu FLAG scriptpush; /* do sub and superscripts get extra space? */ FLAG ischapter; /* does @chapter command exist? */ MICA sced line */ FLAG isfile; /* do plain file output? */ char prtcode; /* printer type code for crayon */ MICA paperoffsetreleft; /* left margin for middle of paragraph */ MICA eleft; /* one of the two previous */ MICA eright; /* right marg /* output goes: c=console, p=printer, f=file */ FLAG outnotinited; /* output file needs initilization */ int outfd; charG *entname; TITLELIST *entnextptr; } *titlehead, *titletail; /* variables */ #define VALLIST struct vallist struct va finistr, /* ... clean up after */ donewline, /* ... do a newline */ boldon, /* ... turn on boldface */ bolr closechar; /* character to append for in-line environ.s */ ENVIRON *envprev; /* previous environment */ } env; /* ---; /* height paper is assumed to start at */ FLAG backspace; /* Does backspace work */ FLAG barecr; /* does bare CR work in */ MICA linespacing; /* height of the line */ FLAG isfill; /* do we fill lines? */ FLAG iswrap; /* do we wrap long *outchar; /* ptr to current character */ char outputbuffer[BUFFSIZE]; /* -----------------------------------------------llist { STRING *valname; /* ptr to name of variable */ char valtype; /* type: 's' string, 'n' number */ int value; Vdoff, /* turn off boldface */ italon, /* turn on italiacs */ italoff; /* turn off italiacs */ char strspc[SSPACE----------------------------------------------- */ /* list structures */ /* titles for Table of Contents */ #define TIT*/ FLAG formfeed; /* does form feed work */ char synctype; /* Type of waiting to do: NONE, ETX/ACK, ^S^Q */ FLAG needt lines? */ char justifytype; /* 'b', 'l', 'r', or 'c' */ FLAG iswhiteintact; /* do we pass whitespace through unscathed? *--- */ /* environment */ #define ENVIRON struct envrn struct envrn { char *name; /* name of current enviornment */ ALLIST *valnextptr; } *valhead, *valtail; /* end notes */ #define NOTELIST struct notelist struct notelist { int not]; /* where strings are stored */ } dev; FLAG devinited; /* have the -dev, -p, or -c options been used? */ MICA widthtaLELIST struct titlelist struct titlelist { char enttype; /* type: 'c' chap, 's' sec, 'b' subsec, 'a' appendix, 'n' appenran; /* Do character translation on output? */ char trannum; /* Translation table number */ struct comstr { /* Various / int (*paraproc)(); /* procedure to execute on paragraph break */ int (*closeproc)(); /* procedure to execute on exit frochar howclose; /* how to close it {),],},>, or 'e') */ MICA preveleft; /* left margin of enclosing environment */ MICA cuenum; /* the note number */ STRING *noteptr; /* the text of the note */ NOTELIST *notenextptr; } *notehead, *notetail; ble[128]; /* size of each char. non-printing=0 */ /* -------------------------------------------------- */ char whereto; dix section, 'p' paragraph */ int entpage; /* page number */ int entnum; /* the section, chapter, etc. number */ STRINstrings to send */ char idx; /* index into space */ char len; /* length */ } initstr, /* ... set things up */m environ. */ int itemlevel; /* nesting depth for @itemize */ int enumcount; /* paragraph number for @enumerate */ cha /* index entries */ #define INDLIST struct indlist struct indlist { STRING *indname; /* the name of the entry */ int UTMAXLEN]; } put; int minpage; /* minimum room left (for accumulating statistics) */ int pagesize; /* sizes of the spe argument is terminated */ char saveclose; /* saves GetArg's state */ FLAG curscript; /* NUL=neither, `p`=in super, `b`=in ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååitle, *subtitle, *paratitle, *apptitle, *asectitle; VALLIST *pagevar; /* current page number */ int pagenum; FLAG headeråååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå indpage; /* the page number */ INDLIST *indnextptr; } *indhead; /* -------------------------------------------------- *ace */ #define LEVELMAX 10 int level[LEVELMAX]; #ifdef UNIX #define isupper(tchar) (tchar>='A' && tchar<='Z') #define isub */ FLAG issuper; /* superscript on line? */ FLAG issub; /* subscript on line? */ STRING *headeven; /* headers */ ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååmode; /* are we accumulating a header? */ MICA heacumlen; /* its accumulated length */ int heacumnum; /* its accumulated nåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå/ /* storage and scratch struct */ FLAG newl; /* was the last thing a Newline? */ FLAG nofootnotes; /* no footnotes onslower(tchar) (tchar>='a' && tchar<='z') #define isdigit(tchar) (tchar>='0' && tchar<='9') #define isalpha(tchar) (isupper(tchSTRING *headodd; STRING *footeven; STRING *footodd; /* used for accumulating a literal string to insert in the output file MAIÎNUMINIÔbSCRIBBLÅ SATSIGÎ; PUTINIÔß PUÔPUTCHÒOPUTNU;PUTSTÒ6PUTFINɦSINIÔ÷SCCOMÐÿSCOMÐqSCOMPGÔ£SCOMPTOÃoSCTOÓ¡umber of entries */ FLAG openneeded; /* are we waiting for an open delimiter to begin an environment? */ FLAG argquoteåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå this page yet */ int footnum; /* current footnote number */ int blankpages; /* number of blank pages to leave */ /ar) || islower(tchar)) #define tolower(tchar) (isupper(tchar)?tchar-'A'+'a':tchar) #define toupper(tchar) (islower(tchar)?tcha*/ #define PUTMAXLEN 200 struct { int plevel; /* for deciding when to write the buffer */ char *pptr; char pbuffer[PSFREÅ SLENGTÈ3SNTOÃ]SNTOÓüSSTOÃRSSTOÎgSPARTOκEINIÔmEFINÉ{EPOÐÕEPUSÈnMEMGEÔÇMEMFREŲMEMSPACÅÞ€ôd; /* was the argument in quotes? */ FLAG getarginitialized; /* in the middle of an argument? */ char getargclose; /* how thåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå* sectioning variables */ VALLIST *chapter, *section, *subsection, *paragraph, *appendix, *asection; VALLIST *chaptitle, *sectr-'a'+'A':tchar) #endif /* END OF SCRIBBLE.GBL */ etArg's state */ FLAG curscript; /* NUL=neither, `p`=in super, `b`=in "t›!"v›"x›!"z›"|›!"~›>2¢›>2§›>2©›>2«›>2¬›!"·›!"‡œ"™œ>2�›!"‚›!"„›!" ›!å!nå!›åÍÑÑÑ"ž›!å!nå! åÍÑÑQÍTÍWÍZë!9ùëÁÉScribble Version 1.3 Copyright (C) 1981 by Mark of the Unicorn Inc. Usage is: scribble {-dev 2€›*X›åÍnÑ}»Âª*i›å!¦å!9~#foéÑíÍ$Ã`is{2€›Í'ÃÍ*ÃÍ-ÃÍ0ÃÍn}þ.Í�ÊõÍn}þ?Í�ÊõÍn}þ!Í�ë`is>!ÍÒ%! ^#Vr+s!jå!måÍ�~#foåÍÑÑÑ|µÊ! cs`isÃ"!på!såÍ�~#foåÍÑÑÑ|µÊ-! ps`isÃ"!våÍ�~#foåÍÑÑ|µÊ‡Í�IGETTOËIGETTYPÅDOSENÔBREAKTOËLPUTWHIÔLGETLENÇLGETCOÌBREAKLIÎPPUTVERÔFLUSHWHÉLNEWLINÅIAPPTOËSATSIGÎLHDRCENÔLHDRRIGÈLHDRLINÅINEXTTÑ"†›!å!nå!¨åÍÑÑÑ"ˆ›!å!nå!°åÍÑÑÑ"Š›!å!nå!»åÍÑÑÑ"Œ›!å!nå!ÅåÍÑÑÑ"Ž›!å!nå!ÎåÍÑÑÑ"�›!ÞåÍÑå!så!ßåÍ>} {-c | -t | -l | -p | -o } -t-c-l-p-oNo file specified for -o. Using default file. -devNo device specified for 2€›Í$Ã`is{2€›Í$ÃÍ3ÃGë!9ùëÁÉIHNTZ`flrx~„Š�–œ¢¨®´·ºÂÊÍÔÜßìðöú  $,/6>LT ÍÒ|`i6f! ^#Vr+së~#foë! s#r! ^#Vr+sÄ!yåÍÑÃ"!©åÍ�~#foåÍÑÑ|µÊãÍ� ÍÒØ! 6n! ^#Vr+së~#foë!OË"Ã6ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÅ!ÿÿ9ùDM`is{2€›Í>½ÂV>¼Ê¹> ½Âb>¼Ê¼> ½Ân>¼Êü>(½Âz>¼Ê‚>½‰›TINIÔTPUTÓEXIÔAINIÔSINIÔMULCOMÐSCCOMÐIINIÔDINIÔASUBSPAÃASPACÅOINIÔPINIÔLINIÔEINIÔENVINIÔNUMINIÔHEADERIÎSCRIBBLÅBREAKLIÎPRINÑÑÑ"’›!ìåÍÑå!så!íåÍÑÑÑ"”›!úåÍÑå!så!ûåÍÑÑÑ"–›! åÍÑå!så! åÍÑÑÑ"˜›!åÍÑå!så!åÍÑÑÑ"š›!*åÍÑå!så!+å-dev. Using default device. Unknown option '' No input file specified. Jfim{~‚†�—ÍÜàíõ +.;BOW_f€Œ“š¨«®º½ÀÃÆÉÌÏÒÜßéìÿIGETTOËINEXTTOËIGETTYPÅIUNGEÔIAPPTOËSCOMMANÄUÃÃÃÃÃÃÃÅ s#r! ^#Vr+sÃà!®åÍÑÃ"Í�~#fon}þ-Â!äåÍÑÍ�~#foåÍÑ!õåÍÑÃ"Í�~#foë! s#rûÍ�|µÂ>!øåÍÑ!åÍ ÑÍ�åÍ@½Â†>¼Ê°>ƒ½Â’>¼Ê¿>’½Âž>¼ÊÅ>Œ½Âª>¼ÊË>B½Â¶>¼ÊÑÃÃ`in}·ÊÏ*c›}·ÊÏÍ `i6Í *f›}·ÊùÍå*]›ÑÍúåÍåÍÑÑåÍÑÃTNOÔPRINTINÄTABLEOFÃEFINÉIFINÉDFINÉLFINÉPFINÉOFINÉTFINÉÃ]ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÍÑÑÑ"œ›ÁÉpagechaptersectionsubsectionparagraphappendixappendixsectionchaptertitlesectiontitlesubsectiontitleparaz}�…ˆ•œ©ÖÙÝáðó÷ #,/3;DUbnz”™œŸ¢¥¨«®±´·º½ÀÃÆÉÌÏSETVAÒSCTOÓ@à ÃÃÅ!"r›ÍÍ >½Â(>¼Ê7>@½Â4>¼Ê=ÃCÍ ÃSÍÃS>2§›ÍåÍÑÃSÁÉ &,258;>AIMQ Å*·›#"·›+ÍÚ»›ë"¹›*¹›6ÑÍ�å! n&åÍÑÑ*Í•å*‰åÍÑÑ" ‰*‰åÍ!Ñ"…œ`in}·ÂˆÍ�ë! s#rÍ�å`in&åÍ$ÑÑÍ'Í*Í-Í0Í3Í6Í9Í<Í?ÍBÍEÍ<ÍHÍKÍNÍ`in}·Ê*c›}·ÊÍ `i6Í *€›}·ÊN*c›}·ÊN*g›|µÊNÍ*¸•åÍÑ*g›å!Jå!9~#foéÑÍ*c›}·ÂsÍ!*g›|µÊs*g›å!rå!9~#foéÑ*€›}·Í�ÃÃÃÃÃÃÃÅ!øÿ9ùDMÍ!ÚåÍÑÍ� ÍÚˆ!åÍÑÍ !åÍ Ñ"‰" ‰Í`is! s! s#r! s#r! s#r! ^#Vr+sgraphtitleappendixtitleappendixsectiontitle'swˆŒ�¡²¶ÇËÜàñõþ %)26?CLPY]fjsw€„�‘ÁÉPUTINIÔPUTCHÒPUTFINÉ(à ÃÃÃÅ!9ùDMÍ! n&åÍÑÍ ÁÉ $TINTERRÏZÃÃÅ!9ùDM*¹›å!‚œÑÍóÒ.!FåÍÑ*¹ÒEÃÃÅ*p›|µÊ!!#å*V›å!2åÍÑÑÑÁÉ' environment.Exiting but in a ' TINTERRÏMOVMEÍMEMFREÅqà ÃÃÃÅ!þÿ9ùD^#Vr+së6-Í�Íúë! s#rÍ� ÍÒ`Í�åÍ� ëÍËåÍÑÑë! s#r! ^#Vr+sÕÍ� ëÍ0ëásÍ�6Í�ÁÉÁÉ@TMEMGÅ!9ùDMÍ�åÍ�åÍÑÑ&ÁÉÁÉTOUPPEÒªÃÃÅ!9ùDMÍ�|µÂ!&ÁÉÍ�|µÂ.!&ÁÉÍ�n}·ÊŸÍ�n}·ÊŸÍ�n&åÍÑåÍ�åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå›Îÿ"¹›*¹›#"¹›+å! nëás*¹›6ÁÉPut buffer overflow!PUTINIÔPUTSTÒSNTOÃPUTFINÉLÃÃÃÃÃÅ!öÿ9ùDMÍÍ�åÍÑ`iåM*p›|µÂ'!TåÍÑÃK*p›ë`is#r!å!V›å*p›åÍÑÑÑÍ�åÍ Ñë!9ùëÁÉPopping the base environment!%=HMEMGEÔMOVMEÍBà EÔSNTOÃ>à ÃÃÅ!þÿ9ùDM!åÍÑë`is#rÍ�åÍ�åÍÑÑÍ�Ã5ë!9ùëÁÉ*3Å!9ùDMÍ�ÁÉÁÉSPARTOÎ?ÃÃÅ!9ùDMÍn&åÍÑÑÍåʆÍ�n&åÍÑåÍ�n&åÍÑÑÍÍ©&ÁÉ! ^#Vr+s! ^#Vr+sÃ.Í�n&ÁÉÁÉ %6@KX`kx�SCCOMÐ#ÃÃÅ!ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÍ�åÍ ÑÑ`iåÍÑÍ�åÍÑÍ ë! 9ùëÁÉ ,4=APUTINIÔPUTCHÒPUTFINÉIà ÃÃÃÅ!9ùDMÍ�|µÂÁÉÍÍ�n}·ÊD! ^#VÃÃÅ!þÿ9ùDM!åÍÑë`is#r!åÍ�å!V›åÍÑÑÑÍ�"p›ë!9ùëÁÉ-AALLOÃTINTERRÏTPUTÓIFINÉOFINÉEXIÔ©ÃÃÃÃÃÃÃ�n}þ-Â-!åÍ�#åÍÑÑÍúÁÉ!åÍ�åÍÑÑÁÉÁÉ$7ISDIGIÔTERROÒSPARTOΊà ÃÃÃÅ!9ùDMÍ�n}·Â$Í�ÁÉÍ�n&åͽ‰›PUTÓ@ÃÃÅ!åÍÑÁÉCopyright (c) 1981 by Mark of the Unicorn Inc. TOPOFMEÍENDEXÔMOVMEÍŠÃ ÃÃÃÅ!þÿ9ùDMÍ9ùDMÍ�åÍ�åÍÑÑ&ÁÉÁÉMEMGEÔSTRLEÎSTRCPÙHà ÃÃÃÅ!þÿ9ùDMÍ�åÍÑ#åÍÑë`is#rÍ�åÍ�åÍ ÑÑÍ�Ã?ë!9ùëÁÉCOPYRIGÈAINIÔTASUBSPAÃAALLOþAFREÅX_ACOALEÓ_AFINDNűALEÎòASPACÅAPRTWRLÄ _APRNÔN _ACHË= _AERROÒÒ €ü r+sën&åÍÑÃ"Í ÁÉ *>BEIUSÅSCRIBBLÅ6à ÃÃÅ*·›+"·›ÍÚ0!"·›!2å!»›åÍÑÑÍÁÉput!).ÅÁÉTÅ!þÿ9ùDMÍ�å* ‰åÍÑÑë`is#rÍ�|µÂo!åÍÑ* ‰å*‰ÑÍåÍ�ÂY!ŽÃ\!œåÍ ÑÍ Í!åÍÑÍ�Ãvë!9ùëÁÉOut of memory.in pageÑ|µÂN!våÍ�å!yåÍÑÑÑÍ�ÁÉÍ� Í?åÍ�nѯgÐÿåÍ�#åÍ ÑÑÁÉÁÉ'.Invalid number '-36?Cn Å!"p›ÁÉTERRO"‰"‰ÍåÍÑÍúöÿåÍ�ÑÍúë͉"‰*‰å*‰Ñ)"‰*‰6#6*‰å*‰Íúëás#r!åÍå!‰åÍ ÑÑÑÍÃ�ë!9ùëÁÉ"&n 4=MEMFREÅÃÃÅ!9ùDMÍ�åÍÑÁÉSTRLEÎÃÃÅ!9ùDMÍ�åÍÑÁÉÁÉSNTOÃ�ÃÃÅ!9ùDMÍ�|·ò5! OLOWEÒ\ÃÃÅ!9ùDMÍ�n&åÍÑåÍ�n&åÍÑÑÍåÊ5!&ÁÉ! ^#Vr+s! ^#Vr+sën}·Â!&ÁÉÁÉ$,QSCCOMÐ#Ãà spacein end space'8;?QTWZ^beltAFREÅÃÃÅ!9ùDMÍ�å* ‰åÍÑÑÁÉÅ!9ùDMÍ�" ‰ÁÉv|AALLOÃMOVME͚à ÃÃÅ!þÿ9ùDMÍ�##åÍ�åÍÑÑë`is#rz³Â7!ÑÍ�ëÍË"‰Í�"‰"‰*‰å*‰Ñ)"‰*‰6#6*ûåÍÑ*‰åÍÑ!åÍÑ*‰åÍÑ!åÍÑ*‰åÍÑÍ ! s#r`is#r*‰ë! s#rÍ�å*‰ÑÍìÒI!åÍÑÍ�åÍÑ!åÍÑÍ�~#foåÍ ·òü*‰åÍ�ÑÍóÚô*‰å*‰~#foÑ)ÍúåÍ�ÑÍóÚü!&à Í�"‰!&à ë!9ùëÁÉ'<Ra{𣍷ºÆÕòú Å!9ùDMÍ�åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÍ�åÍÑÑÑÍ�å*‰ÑÍìÚBÍ�å*‰ÑÍóÒL!‘åÍÑÁÉ! ^#Vr+sÍ�åÍ�~#foÍúëás#r*‰|µÂ�Í�"‰!åÍ�å!‰åÍÑÑÑÁÉBad ptr¬ºÀÇËÜö"%;GVY]vz}��”˜§«¯ÆÉÍìðABÓ_AERROÒvà ÃÃÅ*‰å*‰ÑÍìÚP*‰å*‰ÑÍóÚP*‰å*‰~#foåÍщå*‰Íúëás#r!åÍ�å!‰åÍÑÑÑÍ�Ñë!9ùëÁÉ"/5…�MOVMEÍ_AERROÒ_ACOALEÓ_AFINDNÅNÃÃÃÃÃÅ!þÿ9ùDM!å!‰åÍ�ÑÍ?åÍÑ!"åÍÑÍ�~#fo|·òÂ!fÃÅ!aåÍÑÍ Í�~#foÍÒø`iå~#foåÍ�~#foÑëás#rÃ'Í�~#fo|·ò$! å~#foåÍ�~#foÍúÑ++~#fo+Í?ÁÉÁÉMOVMEÍABÓ_AERROÒÛà ÃÃÃÅ!üÿ9ùDM!å!‰åÍ�åÍÑÑÑ`i¯w#w*‰ë! s#rÍ�å*‰ÑÍåÊ·Í�å*‰ÑÍóÚcÍ�åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå freed1@CGsŠ_ACHË€ÃÃÅ!üÿ9ùDM*‰~#foë`is#r*‰å*‰~#foÑ)Íú~#foë! s#rz·ò_*‰å~#foåÍ�Ñëás#rÍ|µÂ\Ã_ÃÑ)å*‰ÑÍóÚP*‰~#fo|µÂ_!håÍÑ!&ÁÉ!&ÁÉÁÉMemory Bashed$3BNQUTINTERRÏÃÃÅ!9ùDMÍ�åÍÑÁÉåÍÑÑÑ*‰|µÂ8!Ã7*‰~#fo|·úL!@åÍÑ*‰ë`is#rÍ�###ë͉ë! s#r*‰~#foÍúåÍ�ÑÍìÒ³Í |µÂ°Í�åÍ Ñ|µÂ°!åÍ�å!ëás#rÃ'ÃI! å~#foåÍ�~#foåÍ ÑÑ)ëás#rÃgÍ�å*‰ÑÍåÊ|!'åÍÑÍ�å*‰ÑÍúë!͉åÍÑÍ !CåÍÑÍ�Í?åÍÑ!GåÍÑ~#fo|µÂn!ÍåÍ ÑÕÍ�~#fo|·ò•`iå~#foåÍ�~#foÍúÑëás#r! å~#foåÍ�~#foåÍÑÑ)ëás#rÃ8Í�Í?ÃÄë!9ùëÁÉMemory mungeåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå*‰~#foåÍ�ÑÍåÍ£&Ãwë!9ùëÁÉ;RWZ]uABÓ_ACHËà ÃÃÅ!þÿ9ùDM*‰ë`is#r*‰å*‰~#foåÍÑÑ)"‰*‰å*‰ÑÍåÂD*‰"‰åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå‰åÍÑÑÑ!Ã7Ãk*‰ë`is#rÍ�~#foÍúåÍ�ÑÍåÊù*‰åÍ�Ñ)"‰åÍ�åÍ�~#foÑëás#rà Í�åÍ Ñ|µÂ !"‰Í�åÍ�ëás#r!åÍ�Í�Í?åÍÑ!TåÍÑÍ�åÍ�Ñå*‰ÑÍåÊò![åÍÑÍ�åÍ�Ñå*‰ÑÍúÍ?åÍÑÍ ë!9ùëÁÉAbegin = , Aend = , Acap = d "ETadhly©µÂMOVMEÍ#ÃÃÅ!9ùDM!å!‰åÍ�åÍÑÑÑÁÉTPUTÓTPUTÎTNÌABÓTPUÔrÃÃÃÃÃÃÅ!úÿ9ùDM!åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå*‰~#foÍÒ¼*‰åÍ�ÑÍóÚ}*‰å*‰~#foÑ)åÍ�ÑÍóÚ¼*‰å*‰~#foÑ)"‰*‰å*‰ÑÍå¢*‰"‰Í|µÂ¹Í�"‰!&à ÃD*‰~#fo|ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå!‰åÍÑÑÑÍ�##Ã7ë!9ùëÁÉCorrupt Space%06BEI‚‡�•¥®±Ñ÷ÿ)5MOVMEÍ_AERROÒŸÃ ÃÃÅ!9ùDM!å!‰at , , ** Last obj ends on Aend + -- allocated, free -- ** total = Asize + 2'+/7;?GKtw{„ˆŒ™¤¨/* AUXIL.C -- Scribble auxilliary routines written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of the Unic/ char *cmd; { if (getarginited && GetArg(ARGFLUSH)) TError("Extra arguments to '",cmd,"'."); getarginited=FALSE; } SFree(token); return; } if (token) SFree(token); } INextTok(); } } FLAG ArgOn(cmd) /* start uIGetType()==EOFT) { IUnGet(); getarginted=FALSE; } token=IGetBuf(); if (what==ARGFLUSH) SFree(token); IPopBuf(); oc=CloseStan; env.enumcount=1; env.itemlevel=0; env.closechar=NUL; } /* ---------------------------------------------e == *IGetTok()) { getarginited=FALSE; return(NULL); } if (what==SAMPLE) return(*IGetTok()); argquoted=TRUE; orn Inc. */ #include "scribble.gbl" #ifndef CPM STRING *GetArg(); unsigned GetNumArg(); char MulComp(); FLAG Test();STRING * GetArg(what) /* return an argument, token by token */ char what; /* FLUSH, RETURN, SAMPLE (return delim) */ { p a GetArg */ char *cmd; { char *IGetTok(); if (getarginited) TIntError("ArgOnned"); INextTok(); if (IGetType()==EO return(token); } PushArg() /* save GetArg's state */ { saveclose=getargclose; getarginited=FALSE; } PopArg()----- */ /* Argument routines */ FlushArg(name) /* get rid of the argument */ char *name; { char *IGetTok(); STR IUnGet(); token=GetOneArg(what); INextTok(); return(token); } else if (what==SAMPLE) return(NUL); IPushBuf(); #endif EnvInit() /* initialize environment */ { int ParaStan(), CloseStan(); env.name="text"; env.howclose=NULchar *IGetTok(); STRING *token; if (!getarginited) return(NULL); argquoted=FALSE; while (IsType(WHITESPACE,NEWLINE,HFT) { IUnGet(); return(FALSE); } if ((getargclose=MatchOpen(*IGetTok()))==NUL) { TError("Missing argument to '",cm /* restore the state */ { getargclose=saveclose; getarginited=TRUE; } #ifdef LARGE MICA GetDimArg() /* processING *token; INextTok(); repeat { while (IGetType()!=COMMAND) if (IGetType()==EOFT) { IUnGet(); return; while (IsType(TOKEN,COMMAND,DELIM,NUL) || (IGetType()==TOKENBREAK && !MulComp(IGetTok(),"=",",") && !MulComp(IGetTok(),"/"; env.preveleft=pag.pleft; env.eleft=env.cureleft=pag.pleft; env.eright=pag.pright; env.linespacing=sty.spacing; env.iEADERCENTER,HEADERRIGHT,HEADERLINE, NUL) || MulComp(IGetTok(),"=",",") || MulComp(IGetTok(),"/",";")) { INextTok(); } d,"'."); return(FALSE); } getarginited=TRUE; INextTok(); return(TRUE); } ArgOff(cmd) /* finish up a GetArg * a dimensioned, numeric argument */ { unsigned n; MICA m; STRING *token; n=GetNumArg(); if (!(token=GetArg(RETURN)) } else INextTok(); INextTok(); if (SCComp(IGetTok(),"end")) { if (SCompToC(token=GetOneArg(RETURN),name)) { ,";"))) { if (IGetType()==DELIM && *IGetTok()==getargclose) break; if (what==RETURN) IAppTok(); INextTok(); } if (sfill=TRUE; env.iswrap=TRUE; env.justifytype=sty.prefjust; env.iswhiteintact=FALSE; env.paraproc=ParaStan; env.closepr if (IGetType()==EOFT) { IUnGet(); getarginited=FALSE; return(NULL); } if (IGetType()==DELIM) { if (getargclos) { TError("Missing dimension.",NULL,NULL); return(0); } switch (Index(token,"in inch inches cm mm point points pica TError("Missing single argument.",NULL,NULL); return(SCToS(IGetTok())); } if (arg==RETURN || arg==PRINT) IPushBuf(); ImArg() /* process a number in the argument */ { unsigned n; STRING *token; if (token=GetArg(RETURN)) { n=SSToN(to return(TRUE); } FLAG InLine(token,trialname,onchar,offchar) /* do an inline environment */ char *token; char *trialnC(token),"'."); m=0; } m*=n; SFree(token); return(m); } #endif #ifdef LARGE FLAG GetFlagArg() /* process NT) { /* print it on the console */ token=IGetBuf(); IPopBuf(); TPuts(SSToC(token)); SFree(token); } return(TRUpicas em ems char chars character characters line lines micas ")) { case 0: case 1: case 2: m=INCH; break; case 3: NextTok(); newl=FALSE; while (IGetType()!=EOFT && (IGetType()!=DELIM || *IGetTok()!=howend)) { if (IGetType()==NEWLINE) {ken); SFree(token); return(n); } else { TError("Missing numeric argument.",NULL,NULL); return(0); } } #ename; char onchar, offchar; { int CloseInLine(); if (SCComp(token,trialname)) { Put(onchar); EPush(); env.name=an "Yes" or "No" argument */ { STRING *token; FLAG arg; token=GetArg(RETURN); if (token && SCompToC(token,"yes")) argE); } /* -------------------------------------------------- */ /* standard environment routines */ FLAG GetOpen() m=CENTIMETER; break; case 4: m=CENTIMETER/10; break; case 5: case 6: m=POINT; break; case 7: case 8: m if (newl) { TError("Warning: Argument terminated by paragraph break.", NULL,NULL); break; } newl=Tdif STRING * GetOneArg(arg) /* return the argument as a single token */ char arg; /* HOLD, PRINT, RETURN, ARGFLUSH *trialname; env.closeproc=CloseInLine; env.closechar=offchar; if (!GetOpen()) Put(offchar); return(TRUE); } retu=TRUE; else if (token && SCompToC(token,"no")) arg=FALSE; else { TError("'Yes' or 'No' argument required. '",SSToC(token) /* pick up the opening delimiter */ { char *IGetTok(); openneeded=FALSE; INextTok(); if (IGetType()!=DELIM || (env.=PICA; break; case 9: case 10: m=Width('m'); break; case 11: case 12: case 13: case 14: m=CHARWIDTH; break; RUE; } else newl=FALSE; if (arg!=ARGFLUSH) IAppTok(); INextTok(); } newl=FALSE; if (IGetType()==EOFT) IUnGet/ { char howend; char *IGetTok(); STRING *token; INextTok(); howend=MatchOpen(*IGetTok()); if (howend==NUL) { rn(FALSE); } char MulComp(token,name1,name2) /* do a compare on more than one thing */ char *token; char *name1, *name, "' was given."); arg=FALSE; } if (token) SFree(token); return(arg); } #endif #ifdef LARGE unsigned GetNuhowclose=MatchOpen(*IGetTok()))==NUL) { TError("Bad opening character '",IGetTok(),"'."); EPop(); return(FALSE); } case 15: case 16: m=LINEHEIGHT; break; case 17: m=1; break; default: TError("Unknown unit of measure '",SSTo(); if (arg==RETURN) { /* return the argument */ token=IGetBuf(); IPopBuf(); return(token); } else if (arg==PRI2; { if (SCComp(token,name1)) return(1); else if (SCComp(token,name2)) return(2); return(NUL); } char MulTest(tokenItem() /* itemize paragraph */ { char chr; env.eleft=env.preveleft; chr= env.itemlevel&1 ? '-' : '*'; Put(chr); l'; env.paraproc=NULL; env.closeproc=CloseStan; env.preveleft=env.eleft; return(TRUE); } return(FALSE); } ef LARGE CloseLevel() /* Level environment closer */ { int *indx; for (indx= &level[0]; *indx; ++indx); if (indx> &oc=ParaStan; } StartEnv() /* start an environment */ { if (openneeded && !GetOpen()) return; BreakLine(); PPutVersty.indent); } /* -------------------------------------------------- */ /* Routines that close out environments */ Cl,name1,name2) /* do a Test on more than one thing */ char *token; char *name1, *name2; { if (Test(token,name1)) return(1)BreakTok(); LPutWhite(env.cureleft-(env.preveleft+Width(chr))); } #ifdef LARGE ParaLevel() /* Level environment */ {/* -------------------------------------------------- */ /* routines to handle paragraph breaks */ ParaEnum() /* enumerlevel[0]) *(--indx)=NULL; CloseStan(); } #endif CloseSec() /* sectioning environment closer */ { Put(env.closechart(sty.above); if (env.paraproc) (*env.paraproc)(); if (env.isfill) FlushWhite(); } FLAG Test(token,trialname) /* testoseCase() /* close out a Case statement */ { INextTok(); PopArg(); while (GetArg(ARGFLUSH)); EPop(); } CloseFoo; else if (Test(token,name2)) return(2); return(NUL); } NormalEnv(tname,whitep,fillp,just) /* set up a "normal" environ int *indx; ParaOut(); for (indx= &level[0]; *(indx+1); ++indx) PutNum(NULL,(*indx)-1,"."); PutNum(NULL,(*indx)++,".")ate paragraphs */ { MICA amt; char nums[10]; env.eleft=env.preveleft; SNToC(env.enumcount++,nums); strcat(nums,".")); BreakLine(); PPutVert(2*LINEHEIGHT); EPop(); } CloseStan() /* standard environment closer */ { BreakLine(); for an environment and do some set up */ char *token; char *trialname; { int CloseStan(); if (SCComp(token,trialnamets() /* close footnote environments */ { if (sty.footstyle=='i') Put(']'); else { BreakLine(); PNoFootnote(); Iment */ char *tname, just; FLAG whitep, fillp; { int ParaStan(); EPush(); env.name=tname; env.howclose=NUL; env; BreakTok(); LPutWhite(2*CHARWIDTH); if (sty.levhang) env.cureleft=LGetCol(); } #endif ParaOut() /* outdented p; PutStr(nums); amt=LGetLength(nums,env.preveleft); BreakTok(); LPutWhite(env.cureleft-(env.preveleft+amt)); } Para PPutVert(sty.below); EPop(); } /* END OF AUXIL.C */  ParaStan() /* standard paragraph breaker */ { LPutWhite()) { EPush(); env.name=trialname; env.iswhiteintact=FALSE; env.isfill=TRUE; env.iswrap=TRUE; env.justifytype='PopBuf(); } EPop(); } CloseInLine() /* in-line environment closer */ { Put(env.closechar); EPop(); } #ifd.iswhiteintact=whitep; env.isfill=fillp; env.iswrap=TRUE; env.justifytype=just; env.linespacing=LINEHEIGHT; env.parapraragraphs */ { env.eleft=env.preveleft; LPutWhite(0); } ParaStan() /* standard paragraph breaker */ { LPutWhite(åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå while (indhead) { PutInit(); if (indhead->indname) { BreakLine(); PutStr(SSToC(indhead->indname)); Put(SP)ToC(notehead->noteptr),"endnotes"); Scribble(); BreakLine(); notehead=notehead->notenextptr; } BreakLine(); EPop case 'b': LPutWhite(6*CHARWIDTH); subsection->value=titlehead->entnum; break; case 'p': LPutWhite(9*CHARWIDteven=SCToS("\203- @Value(Page) -\222\214"); footodd=SCToS("\203- @Value(Page) -\222\214"); } PrintNotes() /* print an-INCH; PutStr("Table of Contents"); BreakLine(); PPutVert(2*LINEHEIGHT); env.justifytype='l'; oldtype='c'; whileåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå; } else Put(','); PutNum(" ",indhead->indpage,NULL); PutFini(); indhead=indhead->indnextptr; } BreakLine()(); } #ifdef LARGE PrintIndex() /* print the index */ { int ParaStan(); if (!indhead) return; TPuts("\n\nIndTH); paragraph->value=titlehead->entnum; break; case 'a': PutStr("Appendix "); appendix->value=titlehead->enty trailing footnotes */ { int ParaStan(); if (!notehead) return; NormalEnv("notes",FALSE,TRUE,sty.prefjust); env.pr (titlehead) { type=titlehead->enttype; if (oldtype!=type || type=='c' || type=='a') { BreakLine(); PPutVert(LINEH/* AUXILTOO.C -- More Scribble auxilliary routines written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of ; EPop(); } #endif TableOfContents() /* generate the table of contents */ { char type, oldtype; MICA LGetCol(); ex\n\n "); PNewPage(); PPutVert(4*LINEHEIGHT); NormalEnv("index",TRUE,FALSE,'c'); env.preveleft=env.cureleft=envnum; break; case 'n': LPutWhite(3*CHARWIDTH); asection->value=titlehead->entnum; } SecStart(type); Tempeveleft=env.eleft=env.cureleft=pag.pleft; env.eright=pag.pright; BreakLine(); PPutVert(LINEHEIGHT); LPutToken(SCToS("-EIGHT); } oldtype=type; env.eleft=env.preveleft; switch(type) { case 'c': PutStr("Chapter "); chapter-the Unicorn Inc. */ #include "scribble.gbl" #ifdef UNIX MICA Width(); char MatchOpen(); FLAG IsNum(), IsType(); #end if (!titlehead) return; TPuts("\n\nTable of Contents\n\n "); PNewPage(); PPutVert(4*LINEHEIGHT); NormalEnv(.eleft=pag.pleft; env.eright=pag.pright; PutStr("Index"); BreakLine(); PPutVert(2*LINEHEIGHT); env.justifytype='l'; late(type); BreakTok(); PutStr(SSToC(titlehead->entname)); BreakTok(); if (LGetCol()>env.eright-HALFINCH) BreakLine(---------")); BreakLine(); while (notehead) { PPutVert(LINEHEIGHT); PutNum(NULL,notehead->notenum,". "); IUse(SS>value=titlehead->entnum; break; case 's': LPutWhite(3*CHARWIDTH); section->value=titlehead->entnum; break; if HeaderInit() /* initialize pageheadings */ { headeven=SCToS("\203\222\214"); headodd=SCToS("\203\222\214"); foo"contents",FALSE,FALSE,'c'); env.preveleft=env.eleft=pag.pleft; env.cureleft=env.preveleft+3*INCH/2; env.eright=pag.pright); LPutWhite(env.eright+HALFINCH-LGetCol()); env.iswrap=FALSE; PutNum(NULL,titlehead->entpage,NULL); BreakLine(); n(SSToN(vptr->value)); return(vptr->value); } int Index(token,str) /* look up token in str */ STRING *token; char SComp(ptr->valname,name); ptr=ptr->valnextptr); return(ptr); } FlushWhite() /* flush whitespace after paragraph breakse name */ char *name, *suffix; FLAG force; { char *indx; for (indx=name; *indx && *indx!='.'; ++indx); if (force) *ok(); LBreakLine(); } BreakTok() /* process a token break */ { STRING *token; char *SSToC(); if (*SSToC(tokenare we any of these? */ int args; { int *argp; for (argp= &args; *argp; ++argp) if (*argp==IGetType()) return(TRUE); env.iswrap=TRUE; titlehead=titlehead->entnextptr; } EPop(); } /* -------------------------------------------------*str; { int indx; char *cptr; indx=0; while (*str--) { cptr=SSToC(token)-1; do { ++str; ++cptr; } w */ { do { INextTok(); } while (IsType(WHITESPACE,NEWLINE,NUL)); IUnGet(); } int GetNumVal(name) /* return aindx=NUL; if (*indx==NUL) strcat(name,suffix); } SecStart(level) /* initialize the sectioning counters */ char level;=IGetBuf())!=NUL) { IClearBuf(); LPutToken(token); } else SFree(token); } DoSent() /* Process an sentence brreturn(FALSE); } char MatchOpen(a) /* return the matching close character */ char a; { switch (a) { case '(': - */ TITLELIST * AddToC() /* add a Table of Contents entry */ { TITLELIST *tptr; MemSpace(EndSpace); tptr=MemGhile (tolower(*str)==tolower(*cptr)); if (*str==SP && !*cptr) break; while (*str++ != SP); ++indx; } return(indx); numeric value or zero */ STRING *name; { VALLIST *vptr; if (!(vptr=FindVar(name))) return(0); if (vptr->valtype=='s' { if (level=='p') return; paragraph->value=0; SetVar("paragraphtitle",'s',SCToS("")); if (level=='b') return; subseceak if desired */ { STRING *token; char *SSToC(); if (islower(*SSToC(token=IGetBuf()))) Put(SENTENCEBREAK); SFree(tok return(')'); case '[': return(']'); case '{': return('}'); case '<': return('>'); case '"': return('"'); et(sizeof(*tptr)); if (!titlehead) titletail=titlehead=tptr; else { titletail->entnextptr=tptr; titletail=tptr; } } FLAG IsNum(str) /* does the string look like a number? */ STRING *str; { char *cptr; cptr=SSToC(str); if && !IsNum(vptr->value)) { TError("Non-numeric value '",SSToC(name),"'."); return(0); } if (vptr->valtype=='s') returtion->value=0; SetVar("subsectiontitle",'s',SCToS("")); if (level=='s' || level=='n') return; asection->value=0; SetVar(en); } VALLIST * FindVar(name) /* find a variable */ STRING *name; { VALLIST *ptr; for (ptr=valhead; ptr && ! case '`': case '\'': return('\''); default: return(NUL); } } ProcessSuffix(name,suffix,force) /* munge a fil tptr->entnextptr=NULL; tptr->entname=GetOneArg(RETURN); MemSpace(PageSpace); return(tptr); } BreakLine() { BreakT (*cptr=='+' || *cptr=='-') cptr++; while (*cptr && isdigit(*cptr)) cptr++; return(!*cptr); } FLAG IsType(args) /* "appendixsectiontitle",'s',SCToS("")); section->value=0; SetVar("sectiontitle",'s',SCToS("")); } VALLIST * SetVar(name----------------------------- */ TBell() /* ring the bell */ { TPut(BELL); } TError(a,b,c) /* print an error mes (what=='n') PutNum(tmp,asection->value,NULL); if (what=='s' || what=='b' || what=='p') PutNum(tmp,section->value,NULL); if TPut(*str++); } /* end of AUXILTOO.C */ "); if (a) TPuts(a); if (b) TPuts(b); if (c) TPuts(c); TPuts("\nerror wa; vptr->value=val; return(vptr); } MICA TabWidth(col) /* return the width of a Tab */ MICA col; { int i; /* print an internal error message */ char *msg; { TPuts("\nInternal Error: "); TPuts(msg); TPuts("\nerror was on lin,type,val) /* set a variable to a value, creating */ char *name; /* it if necessary */ char type; int val; { VALLIsage */ char *a, *b, *c; { TPuts("\nError: "); if (a) TPuts(a); if (b) TPuts(b); if (c) TPuts(c); TPuts("\nerror wa(what=='b' || what=='p') PutNum(".",subsection->value,NULL); if (what=='p') PutNum(".",paragraph->value,NULL); PutFini(); ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååfor (i=0; i=MAXTABS) ? dev.stdhoriz : (sty.tabcolumns[i]-col)); } Tee "); TPutn(IGetLine()); TPuts(" of "); TPuts(IGetFile()); TNL(); } TNL() /* send a Newline */ { putchar('\n'ST *vptr; STRING *token; token=SCToS(name); if (!(vptr=FindVar(token))) { vptr=MemGet(sizeof(*vptr)); if (!valheads on line "); TPutn(IGetLine()); TPuts(" of "); TPuts(IGetFile()); TNL(); } TFini() /* finish up writing things } MICA Width(chr) /* return the width of the character */ char chr; /* chr cannot be a Tab */ { if (chr>=SP && ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååmplate(what) /* outputs a section number */ char what; { char *tmp; PutInit(); if (sty.ischapter) { if (what==); } TPut(chr) /* put a character */ char chr; { putchar(chr); } TPutn(n) /* print n on the terminal */ u) valtail=valhead=vptr; else { valtail->valnextptr=vptr; valtail=vptr; } vptr->valnextptr=NULL; vptr->valna*/ { } char TGetChr() /* get a character */ { char chr; #ifdef CPM chr=bios(3); #endif #ifdef UNIX chr=getchr<=DEL) if (dev.isprop) return(widthtable[chr]); else return(dev.stdhoriz); return(0); } /* ---------------------åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå'a' || what=='n') Put('A'-1+appendix->value); else PutNum(NULL,chapter->value,NULL); tmp="."; } else tmp=NULL; ifnsigned n; { if (n>9) TPutn(n/10); putchar(n%10+'0'); } TPuts(str) /* put a string */ char *str; { while (*str)me=token; } else { if (vptr->valtype=='s' && vptr->value) SFree(vptr->value); SFree(token); } vptr->valtype=typechar(); #endif if (chr==3) exit(1); return(chr); } TInit() /* initialize the terminal */ { } TIntError(msg) åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå TError("Incorrect Environment Closing. Tried to end a '", SSToC(token),"' environment."); TPuts("A '"); TPutsONMENTS */ if (CheckEnv(tkn)) return; /* BEGIN and END */ if (SCComp(tkn,"begin")) { token=GetOneArg(RETURN); ile(); return; } if (SCComp(tkn,"device")) { DSetType('n',SSToC(token=GetOneArg(RETURN))); SFree(token); return;icorn Inc. */ #include "scribble.gbl" #ifdef UNIX FLAG CheckVar(), CheckEnv(), CheckSec(); #endif SCommand(tkn) return; if (InLine(tkn,"t",ROMANON,ROMANOFF)) return; if (InLine(tkn,"u",UNNBON,UNNBOFF)) return; if (InLine(tkn,"ux",UNALåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå(env.name); TPuts("' environment is open, and it should be closed with '"); if (env.howclose=='e') TPuts("@end"); ef (SCompToC(token,"comment")) { SFree(token); FlushArg("comment"); return; } openneeded=FALSE; if (CheckEn } if (SCComp(tkn,"message")) { TNL(); GetOneArg(PRINT); return; } /* HEADINGS, FOOTINGS, and FOOTNOTES */ /* process a command */ char *tkn; { STRING *token, *token2; char which; INDLIST *iptr, *iptr2, *iptrold; NOTELIST *nLON,UNALLOFF)) return; if (InLine(tkn,"un",UNANON,UNANOFF)) return; /* I/O Commands */ if (SCComp(tkn,"comment")) { åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååålse TPut(env.howclose); TPuts("'.\n"); } SFree(token); return; } /* INLINE Environment */ if (InLine(tknv(token)) env.howclose='e'; else TError("Unknown environment '",SSToC(token),"'."); SFree(token); return; } if (SC if (which=MulComp(tkn,"pageheading","pagefooting")) { DoHeading(which); return; } if (SCComp(tkn,"note") || (sty.fptr; MICA LGetCol(), amt; int CloseFoots(); if (SCComp(tkn,"\\")) { if (SCComp(env.name,"description")) { BreakToGetOneArg(ARGFLUSH); return; } if (SCComp(tkn,"include")) { token=GetOneArg(RETURN); IInclude(SSToC(token)); SFåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå,"+",SUPERON,SUPEROFF)) return; if (InLine(tkn,"-",SUBON,SUBOFF)) return; if (InLine(tkn,"b",BOLDON,BOLDOFF)) return; if (Comp(tkn,"end")) { token=GetOneArg(RETURN); if (env.howclose=='e' && SCComp(env.name,token)) (*env.closeproc)(); else {ootstyle=='e' && SCComp(tkn,"foot"))) { if (sty.footpush) { PutInit(); Put(SUPERON); PutNum(NULL,++footnum,NULL);k(); if (LGetCol()>=env.cureleft) BreakLine(); else LPutWhite(env.cureleft-LGetCol()); } return; } /* ENVIRree(token); if (!MulComp(token,"con:","tty:")) { TPuts("\nIncluding "); TPuts(IGetFile()); TNL(); } Scribb/* COMMANDS.C -- Scribble command interpeter written January 1981 by Craig A. Finseth Copyright (c) 1981 by Mark of the UnInLine(tkn,"i",ITALON,ITALOFF)) return; if (InLine(tkn,"p",BITALON,BITALOFF)) return; if (InLine(tkn,"r",ROMANON,ROMANOFF)) Put(SUPEROFF); PutFini(); } else PutNum("[",++footnum,"]"); MemSpace(EndSpace); nptr=MemGet(sizeof(*nptr)) } while (iptr && !iptr->indname); } if (iptr==indhead) { iptr2->indnextptr=indhead; indhead=iptr2; } (SCComp(tkn,"index")) { MemSpace(EndSpace); iptr2=MemGet(sizeof(*iptr)); iptr2->indpage=(pagenum==0)? 1 : pagenum; FOUND */ TError("Unknown command '",tkn,"'."); openneeded=FALSE; IAppTok(); } FLAG CheckVar(tkn) /* do the var } else PutNum("[",++footnum,"]"); IPushBuf(); PFootnote(); NormalEnv("footnote",FALSE,TRUE,sty.prefjust); env. /* WHITESPACE COMMANDS */ if (SCComp(tkn,"newpage")) { BreakLine(); PNewPage(); return; } #ifdef LARGE if ; if (!notehead) notetail=notehead=nptr; else notetail->notenextptr=nptr; notetail=nptr; nptr->notenum=footnum; n else { iptr2->indnextptr=iptrold->indnextptr; iptrold->indnextptr=iptr2; } } iptr2->indname=token; token=GetOneArg(RETURN); if (!indhead) { indhead=iptr2; iptr2->indnextptr=NULL; } else { iptr=iptrold=iniable processing commands */ char *tkn; { STRING *token, *token2, *sptr; char which, *secstr, *SSToC(); int oldval, valcloseproc= &CloseFoots; env.preveleft=env.eleft=env.cureleft=pag.pleft; env.eright=pag.pright; if (nofootnotes) { (SCComp(tkn,"blankpage")) { ArgOn("@BlankPage"); blankpages+=GetNumArg(); ArgOff("@BlankPage"); return; } #endifptr->noteptr=GetOneArg(RETURN); nptr->notenextptr=NULL; MemSpace(PageSpace); return; } if (SCComp(tkn,"foot")) { MemSpace(PageSpace); return; } #endif /* CHAPTERS, SECTIONS, and SUBSECTIONS */ if (CheckSec(tkn)) return; /* Vdhead; while (iptr && SCompGT(token,iptr->indname)) { iptrold=iptr; iptr=iptr->indnextptr; } if (iptr && ; VALLIST *vptr; if (SCComp(tkn,"string")) { token=NULL; if (!ArgOn("@String") || !(token=GetArg(RETURN)) || !( nofootnotes=FALSE; PPutVert(LINEHEIGHT); LPutToken(SCToS("----------")); BreakLine(); } PPutVert(LINEHEIGHT) #ifdef LARGE if (SCComp(tkn,"blankspace")) { BreakLine(); ArgOn("@BlankSpace"); amt=GetDimArg(); ArgOff("@BlankS if (sty.footstyle=='i') { EPush(); env.closeproc= &CloseFoots; env.name="footnote"; Put('['); return; ARIABLE STORING AND PRINTING */ if (CheckVar(tkn)) return; /* CASE */ #ifdef LARGE if (SCComp(tkn,"case")) { DoCaSComp(token,iptr->indname)) { SFree(token); token=NULL; do { iptrold=iptr; iptr=iptr->indnextptr; token2=GetArg(RETURN))) { if (token) SFree(token); TError("@String requires two arguments.",NULL,NULL); return(TRUE); PutNum(NULL,footnum,". "); if (!GetOpen()) { PNoFootnote(); IPopBuf(); } return; } #ifdef LARGE ifpace"); PPutVert(amt); return; } #endif if (SCComp(tkn,"w")) { GetOneArg(HOLD); return; } /* COMMAND NOT} if (sty.footpush) { PutInit(); Put(SUPERON); PutNum(NULL,++footnum,NULL); Put(SUPEROFF); PutFini(); se(); return; } #endif /* STYLE */ #ifdef LARGE if (SCComp(tkn,"style")) { DoStyle(); return; } #endif ; } if (argquoted) sptr=token2; else { if (!(vptr=FindVar(token2))) { TError("@String: Variable not found '",ltype=='n') PutNum(NULL,vptr->value,NULL); else TError("@Ref: '",SSToC(token), "' does not contain a number."); } (token2); oldval=GetNumVal(token); if (which=='+') oldval+=val; else if (which=='-') oldval-=val; else oldval=val;ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååL,vptr->value,NULL); SFree(token); return(TRUE); } if (SCComp(tkn,"set")) { token=NULL; if (!ArgOn("@Set") || !(vptr) PutStr(vptr->value); SFree(token); return; } } /* END OF COMMANDS.C */  secstr="chapter section subsectSSToC(token2),"'."); sptr=token2; } else { SFree(token2); if (vptr->valtype=='s') sptr=SCToS(SSToC(vptr- else Template("csbpan"[val]); SFree(token); return(TRUE); } if (SCComp(tkn,"title")) { vptr=NULL; switch (Ind SetVar(SSToC(token),'n',oldval); SFree(token); ArgOff("@Set"); return(TRUE); } secstr="chapter section subsectåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå(token=GetArg(RETURN)) || !(token2=GetArg(RETURN))) { if (token) SFree(token); TError("@Set requires two arguments.åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå>value)); else sptr=SNToS(vptr->value); } } SetVar(SSToC(token),'s',sptr); SFree(token); ArgOff("@String"ex((token=GetOneArg(RETURN)),secstr)) { case 0: vptr=chaptitle; break; case 1: vptr=sectitle; break; ion paragraph appendix appendixsection "; if (SCComp(tkn,"ref")) { val=Index((token=GetOneArg(RETURN)),secstr); if (val>/* COMMTOO.C -- Scribble command interpeter, continued written March 1981 by Craig A. Finseth Copyright (c) 1981 by Mark o",NULL,NULL); return(TRUE); } which= *SSToC(token2); if (which=='+' || which=='-') { sptr=SCToS(SSToC(token2)+åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå); return(TRUE); } if (SCComp(tkn,"value")) { token=GetOneArg(RETURN); vptr=FindVar(token); if (!vptr) TError("case 2: vptr=subtitle; break; case 3: vptr=paratitle; break; case 4: vptr=apptitle; break; case5) { vptr=FindVar(token); if (!vptr) TError("@Ref: Variable not found '", SSToC(token),"'."); else if (vptr->vaf the Unicorn Inc. */ #include "scribble.gbl" FLAG CheckEnv(tkn) /* deal with environments */ char *tkn; { char 1); SFree(token2); token2=sptr; } if (IsNum(token2)) val=SSToN(token2); else val=GetNumVal(token2); SFreeåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå@Value: Variable not found '",SSToC(token),"'."); else if (vptr->valtype=='s') PutStr(SSToC(vptr->value)); else PutNum(NUL 5: vptr=asectitle; break; default: TError("@Title: Unknown option '",SSToC(token),"'."); break; } if which; int *indx; int ParaOut(), ParaEnum(), ParaItem(), ParaStan(), CloseSec(); #ifdef LARGE int ParaLevel(), CloseLevelaraproc=ParaItem; env.itemlevel++; StartEnv(); return(TRUE); } #ifdef LARGE if (Test(tkn,"level")) { for (indxv.cureleft+2*CHARWIDTH; env.eleft=env.cureleft+=6*CHARWIDTH; env.justifytype=sty.prefjust; env.enumcount=1; env.para,"unnumbered","majorheading")) || Test(tkn,"heading")) { env.isfill=FALSE; env.justifytype='c'; env.closeproc=Closeion","undent")) { if (which==1) { env.eleft=env.cureleft+=(env.eright-env.cureleft)/4; env.linespacing=LINEHEIGHT; pe=sty.prefjust; env.paraproc=ParaStan; StartEnv(); return(TRUE); } if (Test(tkn,"text")) { env.justifytype=sty(); #endif if ((which=MulTest(tkn,"address","flushleft")) || Test(tkn,"closing")) { env.isfill=FALSE; env.iswrap=FALS= &level[0]; *indx; ++indx); if (sty.levindent && indx> &level[0]) { if (env.cureleft==env.preveleft) env.cureleft+=HALFIproc=ParaEnum; StartEnv(); return(TRUE); } if (MulTest(tkn,"format","verbatim")) { env.linespacing=LINEHEIGHT; Sec; env.closechar=BOLDOFF; BreakLine(); if (which==1) PNewPage(); StartEnv(); PPutVert((which ? 6 : 4)*LINEHEIGH } else env.eleft=env.cureleft+=sty.indent; env.justifytype=sty.prefjust; env.paraproc=ParaOut; StartEnv(); retu.prefjust; env.paraproc=ParaStan; env.linespacing=sty.spacing; StartEnv(); return(TRUE); } if (Test(tkn,"verse"E; env.iswhiteintact=TRUE; if (which!=2) env.preveleft=env.eleft=env.cureleft= (pag.pright+pag.pleft)/2; StartEnv()NCH; env.preveleft=env.eleft=env.cureleft; } env.justifytype=sty.prefjust; env.paraproc=ParaStan; *indx=1; *env.isfill=FALSE; env.iswrap=FALSE; env.iswhiteintact=TRUE; StartEnv(); return(TRUE); } if (Test(tkn,"itemize")T); Put(BOLDON); return(TRUE); } if (MulTest(tkn,"prefacesection","subheading")) { env.isfill=FALSE; env.closeprn(TRUE); } if (MulTest(tkn,"display","example")) { env.eleft=env.cureleft+=HALFINCH; env.eright-=HALFINCH/2; env.)) { env.eleft=env.preveleft+=3*CHARWIDTH; env.cureleft=env.preveleft+2*CHARWIDTH; env.eright-=10*CHARWIDTH; env.lin; return(TRUE); } if (which=MulTest(tkn,"center","flushright")) { env.isfill=FALSE; env.iswrap=FALSE; env.iswhi(indx+1)=NULL; env.paraproc=ParaLevel; env.closeproc=CloseLevel; StartEnv(); return(TRUE); } #endif if (Test(t) { env.preveleft=env.cureleft+2*CHARWIDTH; env.eleft=env.cureleft+=5*CHARWIDTH; env.justifytype=sty.prefjust; env.proc=CloseSec; env.closechar=UNALLOFF; StartEnv(); PPutVert(4*LINEHEIGHT); Put(UNALLON); return(TRUE); } retuisfill=FALSE; env.iswhiteintact=TRUE; StartEnv(); return(TRUE); } if (Test(tkn,"enumerate")) { env.preveleft=enespacing=LINEHEIGHT; env.isfill=FALSE; env.paraproc=ParaOut; StartEnv(); return(TRUE); } if ((which=MulTest(tknteintact=TRUE; env.justifytype= (which==1)? 'c' : 'r'; StartEnv(); return(TRUE); } if (which=MulTest(tkn,"descriptkn,"quotation")) { env.eleft=env.cureleft+=HALFINCH; env.eright-=HALFINCH; env.linespacing=LINEHEIGHT; env.justifytyrn(FALSE); } FLAG CheckSec(tkn) /* deal with sectioning commands */ char *tkn; { TITLELIST *tptr; STRING *token; BreakLine(); PPutVert(4*LINEHEIGHT); EPush(); env.isfill=FALSE; env.justifytype='l'; PutInit(); Put(UNALLON)name)); Put(BOLDOFF); PutFini(); BreakLine(); PPutVert(3*LINEHEIGHT); EPop(); return(TRUE); } if (which=Mptr->entpage=pagenum; PPutVert(LINEHEIGHT); EPop(); return(TRUE); } return(FALSE); } #ifdef LARGE DoCase()e); BreakLine(); PNewPage(); PPutVert(6*LINEHEIGHT); tptr->entpage=pagenum; TPuts(" ("); if (which==1) T'; tptr->entnum= ++(subsection->value); SetVar("subsectiontitle",'s',SCToS(SSToC(tptr->entname))); paragraph->value= char which; if (which=MulComp(tkn,"chapter","appendix")) { if (!sty.ischapter) { TError("@Chapter and @Appendix ha; Template((which==1) ? 's' : 'n'); Put(SP); PutStr(SSToC(tptr->entname)); Put(UNALLOFF); PutFini(); BreakLineulComp(tkn,"section","appendixsection")) { tptr=AddToC(); if (which==1) { tptr->enttype='s'; tptr->entnum= ++(sect /* process the @Case command */ { STRING *token; VALLIST *vptr; char dlm; int CloseCase(); if (!ArgOn("@Case"))Putn(chapter->value); else TPut('A'-1+appendix->value); TPut(')'); EPush(); env.isfill=FALSE; env.justifytype='0; } else { tptr->enttype='p'; tptr->entnum= ++(paragraph->value); SetVar("paragraphtitle",'s',SCToS(SSToC(tpve been disabled.",NULL,NULL); return(TRUE); } tptr=AddToC(); if (which==1) { tptr->enttype='c'; tptr->e(); tptr->entpage=pagenum; TPuts(" ("); if (which==1) TPutn(chapter->value); else TPut('A'-1+appendix->value); ion->value); SetVar("sectiontitle",'s',SCToS(SSToC(tptr->entname))); } else { tptr->enttype='n'; tptr->entnum return; vptr=FindVar(token=GetArg(RETURN)); if (!vptr || vptr->valtype!='s') { TError("Undefined or non-string selector c'; PutInit(); Put(BOLDON); if (which==1) { PutStr("Chapter "); Template('c'); } else { PutStr("Appetr->entname))); } BreakLine(); PPutVert(2*LINEHEIGHT); EPush(); env.isfill=FALSE; env.justifytype='l'; Pntnum= ++(chapter->value); SetVar("chaptertitle",'s',SCToS(SSToC(tptr->entname))); } else { tptr->enttype='a'; TPut('.'); TPutn((which==1) ? section->value : asection->value); TPut(')'); PPutVert(2*LINEHEIGHT); EPop(); r= ++(asection->value); SetVar("appendixsectiontitle",'s',SCToS(SSToC(tptr->entname))); } SecStart(tptr->enttype); variable for @Case '", SSToC(token),"'."); SFree(token); ArgOff("@Case"); return; } SFree(token); while (tokndix "); Template('a'); } PutFini(); BreakLine(); PPutVert(LINEHEIGHT); PutInit(); PutStr(SSToC(tptr->entutInit(); Template((which==1) ? 'b' : 'p'); Put(SP); PutStr(SSToC(tptr->entname)); PutFini(); BreakLine(); t tptr->entnum= ++(appendix->value); SetVar("appendixtitle",'s',SCToS(SSToC(tptr->entname))); } SecStart(tptr->enttypeturn(TRUE); } if (which=MulComp(tkn,"subsection","paragraph")) { tptr=AddToC(); if (which==1) { tptr->enttype='ben=GetArg(RETURN)) { if ((SCompToC(vptr->value,"") && SCompToC(token,"null")) || SComp(token,vptr->value) || SCompToC(to case 9: /* justification */ env.justifytype=sty.prefjust=(GetFlagArg() ? 'b' : 'l'); break; case 10: /* lsty.below=GetDimArg(); break; case 2: /* bottom margin */ pag.pbottom=dev.dheight-(sty.sbottom=GetDimArg()); .dwidth-(sty.sright=GetDimArg()); break; case 18: /* script push */ sty.scriptpush=GetFlagArg(); break; ca} } #endif #ifdef LARGE DoStyle() /* process the @Style command */ { STRING *token, *token2; ArgOn("@Style"); case 1: sty.footstyle='b'; break; case 2: sty.footstyle='i'; break; default: TError("Unknown vken,"else")) { SFree(token); if (dlm=GetArg(SAMPLE)) { PushArg(); EPush(); env.name="case"; env.howceft margin */ env.preveleft=env.eleft=env.cureleft=pag.pleft=GetDimArg(); break; case 11: /* level hang */ stbreak; case 3: /* chapter */ sty.ischapter=GetFlagArg(); break; case 4: /* footer spacing */ sty.footese 19: /* spacing */ env.linespacing=sty.spacing=GetDimArg(); break; case 20: /* spread */ sty.spread=Get while (token=GetArg(RETURN)) { switch (Index(token,"above below bottommargin chapters footerspacing footpush headerspacing ialue for Note clause of @Style '", SSToC(token2),"'."); break; } SFree(token2); break; case 15: /lose=MatchOpen(dlm); env.closeproc=CloseCase; return; } else { if (!(token=GetArg(RETURN))) { TErry.levhang=GetFlagArg(); break; case 12: /* level indent */ sty.levindent=GetFlagArg(); break; case 13: rspace=GetDimArg(); break; case 5: /* foot push */ sty.footpush=GetFlagArg(); break; case 6: /* headerDimArg(); break; case 21: /* top margin */ pag.ptop=GetDimArg(); break; default: TError("Unknown argumndent indentation justification leftmargin levelhang levelindent linewidth notes paperlength paperwidth rightmargin scriptpush s* paper length */ pag.pbottom=(dev.dheight=GetDimArg())-sty.sbottom; break; case 16: /* paper width */ env.eror("Unexpected end of @Case argument",NULL,NULL); return; } while (GetArg(ARGFLUSH)); IUse(SSToC(token),"c /* line width */ env.eright=pag.pright=pag.pleft+GetDimArg(); break; case 14: /* notes */ if (!(token2=GetAr spacing */ sty.headerspace=GetDimArg(); break; case 7: case 8: /* indent */ sty.indent=GetDimArg(); break;ent to @Style '",SSToC(token),"'."); ArgOff("@Style"); break; } SFree(token); } } #endif DoHeading(whichpacing spread topmargin ")) { case 0: /* above */ sty.above=GetDimArg(); break; case 1: /* below */ ight=pag.pright=(dev.dwidth=GetDimArg())-sty.sright; break; case 17: /* right margin */ env.eright=pag.pright=devase"); Scribble(); SFree(token); return; } } else if (!GetArg(ARGFLUSH)) return; SFree(token); g(RETURN))) break; switch (Index(token2,"endnote footnote inline ")) { case 0: sty.footstyle='e'; break; ) /* process a page heading command */ char which; { STRING *token, *lhead, *chead, *rhead, *nhead, *ptrs; char where, *urn; } /* END OF COMMTOO.C */  case 5: where='o'; break; default: TError("Unknown argument to @PageHeadi(ptr,"\214"); strcat(ptr,SSToC(nhead)); SFree(lhead); SFree(chead); SFree(rhead); SFree(nhead); if (which==1) { ÃÃÅ!ýÿ9ùDMÍ�ë`is#rÍ�åÍëás{þÊ;Í�å! ~#foåÍ� +ÑÑÍìÚWÍÃ$Í�n}þʃþʃþ Ê·þ ÊÊþÊÊþÊßþÊßÃ"Í�åÍ� case 4: where='e'; break; case 5: where='o'; break; default: TError("Unknown argument to @PageHeadiptr; where='b'; lhead=SCToS(""); rhead=SCToS(""); chead=SCToS(""); nhead=SCToS(""); ArgOn(which==1 ? "@PageHeadingåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå if (where=='b' || where=='e') { SFree(headeven); headeven=SCToS(ptr); } if (where=='b' || where=='o') { SFÑÍóÒœ`i^#Vr+s!åÍ Ñ! åÍ Ñ!åÍ ÑÃ8`i^#Vr+së6 Í Ã8Í Í�6Í�åÍÑÃ8Í�åÍ�ÑÍóÒÍ�+n}þ Ê`i^#Vr+s!åÍ Ñng or @PageFooting '", SSToC(token),"'."); SFree(token); ArgOff(which==1 ? "@PageHeading" : "@PageFooting"); br" : "@PageFooting"); while (token=GetArg(RETURN)) { switch (Index(token,"left line right center even odd ")) { case ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååree(headodd); headodd=SCToS(ptr); } } else { if (where=='b' || where=='e') { SFree(footeven); footeven=S! åÍ Ñ!åÍ ÑÃßÃ8`i^#Vr+sën&åÍ ÑÃ8Ã$Í ë!9ùëÁÉ#*3ORU`ejoty~�‘¡©±µÅÈËÙÝíù  269eak; } SFree(token); } ptr=MemGet(SLength(lhead)+SLength(chead)+SLength(rhead)+SLength(nhead)+ (3+1)); strcpy½‰›PUTÓ@ÃÃÅ!åÍÑÁÉCopyright (c) 1981 by Mark of the Unicorn Inc. TINTERRÏSTRCAÔUà ÃÃÅ*\Œå*é�Ñ"\Œ+Íù0: SFree(lhead); lhead=GetArg(RETURN); break; case 1: SFree(nhead); nhead=GetArg(RETURN); break; cCOPYRIGÈIAPPTOËTICLEARBÕÆICONSINÐÙIFINɃIGETBUÆIIGETFILÅjIGETLINÅwIGETTOË„IGETTYPÅ‘IINCLUDÅ IINIÔªISETTYPÅÑINEXTCHCToS(ptr); } if (where=='b' || where=='o') { SFree(footodd); footodd=SCToS(ptr); } } MemFree(ptr); ret<CLOSÅTINTERRÏ Ã ÃÃÅ!þÿ9ùDM*P�|·ú!*P�åÍÑ*l�|µÊr!{åÍÑ*l�ë`is#rÍ�|µÊrÍ�~#fo|·ú]Í�~#foåÍÑÍ�~#foë`is(ptr,SSToC(lhead)); strcat(ptr,"\203"); strcat(ptr,SSToC(chead)); strcat(ptr,"\222"); strcat(ptr,SSToC(rhead)); strcatÚ/!>åÍÑ!ú"\ŒÁÉ!ë�å!^ŒåÍÑÑÁÉInput buffer overflow. $8Å!"\Œ>2^ŒÁÉTGETCHÒTBELÌTPUÔTNÌTPUTÓGÃÃÃÃase 2: SFree(rhead); rhead=GetArg(RETURN); break; case 3: SFree(chead); chead=GetArg(RETURN); break; Á! INEXTTOËå IPOPBUÆ IPUSHBUÆR IUNGEÔ« IUSŸ DINIÔM DFINÉŽ DSETTYPÅ– DREAÄ~€P#rÃ:ë!9ùëÁÉExiting from include file or string. '*.ANZpSCTOÓÃÃÅ!^ŒåÍÑÁÉÁÉ Å!X�ÁÉÁÉÅ*V�ÁÉ!Æ*V�#"V�ÍÆÍÆ*é�ë�6ë!9ùëÁÉCurrent token overflow.#&.CFI`ejorz‚Ž•¬ÁÞõ".15?TWnå!”åÍÑÑÑÍ�ÍùÒzÍ�€Í?n�6n�ë"R�*T�"T�ë!9ùëÁÉFile read error.,;ITXhINEXTCHÁCLOSÅSEEËREAÄMOVMEÍ#Vr+sÃ*ë•å*å•ÑÍóÚ`>2½•Í�¤åÍÑë!*9ùëÁÉCONFIG.DATA:CONFIG.DATCan't find the configuration file, CONFIG.DAT header reco‡�—š¢¯ÁÌÕÜéóöý #5>ICLEARBÕISETTYPÅIINCLUDÅúà ÃÃÃÅ!9ùDMÍ!"é�>2ë�>2[Œ!Få!å!åÍÑÑÑ!B!å!}åÍÑÑë!¤ s#rz·òo!ŠåÍÑ!åÍ Ñ!¹å!å!å`iåÍ�¤åÍ ÑÑÑÑÑ!. n}·Ê !. n}þp¯Í�ë!¦ s#rÃ^!. n}þcÂÉÍ�ë!¦ sÁÉÅ!ë�ÁÉÁÉ Å*n”&ÁÉÁÉMEMGEÔMOVMEÍSCOMPTOÃSTRCPÙICONSINÐPROCESSÓOPEÎTERROÒSTRCAÔINEXTCHÁINEXTTOË�Ã$ÃÃÃÃÃÃq{~�„MOVMEÍ7ÃÃÅ*[Œ&ÍÒ5!/å!\Œå![Œ5n&/Ík‹�åÍÑÑÑÁÉ0MOVMEÍICLEARBÕ>à ÃÃÅ*[Œ&ÍùÒ9!/å!MEMFREÅTINTERRϰÃÃÃÃÃÃÃÃÅ!þÿ9ùDM*o•}·Ê0>2o•Ã�*R�n&o”n}2n”}þFÂKÍÃ0*R�n}2ë�!"é�*n”}þÊtþAÊ!þ Ê!þ rddevice descriptions Device '' not found, using default device descriptionDefault or console device not defined. spacing å!ÿå! åÍÑÑÑ!Aå!zå!aåÍÑÑÑ!Aå!Zå!AåÍÑÑÑ!Aå!9å!0åÍÑÑÑ{2‰”{2o”> 2y” {2�”{2x”({2Ï”{2–”{2‘”({2˜”{2—”({2­”{2«#rÃ^Í�ë!¦ s#rÍ�¦åÍ�ÑÍúÒ(!Çå!åÍ�¦å!Ï•åÍ�¤åÍ ÑÑÑÑÑ!Ï•å̓0åÍÑÑ|µÊÃ(!¦ ^#Vr+sÃÕÍ�¦åÍ�ÑÍúÚ^!ÛåÍÑ̓0ÃÃÃÃÃÅ!êÿ9ùDM*l�+|µÂI!"l�!"V�>2X�Ãs!åÍÑë! s#r!åÍ�å!P�åÍÑÑÑÍ�"l�!IåÍ�åÍ ÑÑ|µÂ™!NåÍ�åÍ Ñ[Œ~4o&/Ík‹�å!\ŒåÍÑÑÑÍÁÉ4:Å>2o•ÁÉMEMGEÔMOVMEÍSTRCPÙINEXTTOËlÃÃÃÃÃÅ!þÿ9ùDM!åÍÑë`is#r!åÍ�ÊsÀ*l�|µÊ*P�|·úú*P�}ÍùÒ˜*P�åÍÑ*l�ë`is#rÍ�~#fo|·òÃÍ�~#foë`is#rá!åÍ�~#foåÍ�~#foåÍ ÑÑÑ!å!n�åÍ�tableScribble parameters1&)04CJN]`dlp„“ž­¸Çãæü&69=GKOeh~†‰�•ž¡ÅÍãø"KYfSE”>@2¯”({2Ì”{2Ê”({2ì”{2ê”>ƒ2ò”>’2•>Œ2û”>2o•!"l�Í�åÍ ÑÁÉ4FXj|õGÅ!þÿ9ùDMÍ�ë`is#rÍ�åÍ�ÑÍúÚ>Í�o”åÍåÍÑ!ååÍÑÍ�ë!¦ s#rÍ�¦|µÊˆ!å!åÍ�¦å!Ï•åÍ�¤åÍ ÑÑÑÑÑØ!åÍÑ!åÍ Ñ*ç•}·ÊÌ!<å!åÍ�å*蕯gÍ?Ñå!P–åÍ�¤åÑ|µÊÃ!Så!X�åÍ ÑÑ!å!n�åÍÑÑ!}"P�n�ë"R�Ã7Í�å`iåÍ ÑÑ!å!aå`iåÍÑÑÑ!å`iåÍÑÑ"P�|·ò!få`iå!iåÍÑÑÑ*R�6Ã@!{å!å!P�åÍÑÑÑÍ�"l�Í�"R�Í�å!X�åÍ ÑÑ!"V�!ÿÿ"P�Í ë!9ùëÁÉ3PaDSETTYPÅ0ÃÃÅ!9ùDM>2O–Í�å! n&åÍÑÑ!~#foåÍ ÑÑÑ*l�ë`is#r!å!P�å*l�åÍÑÑÑÍ�åÍÑÆÍ*é�dÍùÚA!˜åÍÑ!2"é�Ãp*R�n&o”nå*n”Ñ}»ÊYÃp*é�#"é�+ë�å*R�nëásÃEËREAÄTPUTÓEXIÔ¦ÃÃÃÃÃÅ!9ùDM!åÍ�åÍ�åÍÑÑÑ|·úQÍ� åÍ�åÍ�åÍÑÑÑåÍ� ÑÍúÒr!tåÍ ÑÍ� åÍ Ñ!‹åÍ Ñ!å� ëás`i^#Vr+sÃë!9ùëÁÉ <REAÄTERROҥà ÃÃÅ!þÿ9ùDM*R�#"R�*P�|·ú‹*R�å!m”ÑÍóÒ‹!å!n�å*P�åÍÑÑÑë`is#rz·ò]!å!Í ÑÑÑÑÑ!Jå!å!å!ª åÍ�¤åÍ ÑÑÑÑÑ!_å!p•å!ª åÍÑÑÑ*º•å*ë•ÑÍk ë͉"º•!¨ 6#6Í�¨|·úMÍ�¨)p•å~#foå*é•ÑÍkëás#r!¨ ^X�åÍ ÑÑ`iå!X�åÍÑÑn”ë"R�!øÿ"T�Í!"V�Í!ë!9ùëÁÉcon:tty:console input.mss'.Can't open file 'file 3GNgt}„ n}2O–ÁÉ!ÅÁÉOPEÎTPUTÓEXIÔDREAÄSCCOMÐMOVMEÍCLOSÅ^ÃÃÃÃÃÃÃÃÅ!Öþ9ùDM*O–}·Ê+Ãi!å!råÍÑÑë!¤ s#rz·òoÍ ÑÁÉFatal: Unable to read from configuration file. &.@ORV_cgo ÃÃÃÅ*¢›}·ÂÁÉÍÍå*¸ŠÑÍìÒX*¥›))‰å*¸ŠåÍÑÍúëás#r*‰å*¸ŠåÍÑÍúÑ"‰Í ÁÉ&7LYPUÔBREAKLIÎEPOÐ"ÃÅÍÁÉNORMALEÎLSTARTLÉPUÔ`à ÃÃÃÅ>2¢›!ÿÿ"¥›!"£›!lå!å!å!YåÍÑÑÑÑ*¶Š"[›"]›"Y›*¸Š"_›>2d›Í!ØåÍ ÑÁÉhe!úÿ9ùDM*‰|µÂ(Í*‰åÍ� åÍ ÑåÍÑÑë`is#r*d›}·Êq*‰åÍ�Ñå*‰å*ã•ë͉ÑÑÍóÒqÍ Í*‰1ÍùÚ‹!¯åÍÑ!"‰*‰))‰ë!«LNEWLINÅjLSTARTLɵLGETLINÅüLPUTTOKŽLPUTWHIÔ÷ PINIÔ¸ PFINÉ PFOOTNOÔL PFREÅt PNEWPAGÅ0PNOFOOTÎŒPPUTIÔ´PPUTLINźPPUTVER`iå~#foåÍ�n}þ Í£ÊlÍ�n&åÍÑÃuÍ�åÍÑÑëás#rÃ5Í�åÍ�ÑÍúÃ�ë!9ùëÁÉ E[fjr}ŽLSTARTLÉPPUTLINÅ,à ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååà ÃÃÃÅ!øåÍÑÍÍ >2¢›ÁÉMOVMEÍ!ÃÃÅ!Óå!á‰å!‰åÍÑÑÑ!"‰ÁÉMOVMEÍÃÃÅ!Óå!‰å!á‰åÍÑÑÑÁÉader+/MTBREAKTOËLPUTWHIÔ.à ÃÃÅ*¢›}·ÂÁÉÍ!åÍÑ*‰"£›*‰+"¥›ÁÉBREAKTOËLGETCOÌLPUTWHIÔßà ÃÃà s#r*‰ÍùÚÍ�++++##~#fo|µÂÍ�øÿ##~#fo|µÊÍ�++++~#foå! åÍÑÑÍåÂ*‰+"‰! ^#V{Ö_zÞWr+sÍ�åÍ�ëás#rÍ�#ÔxOINIÔ<OFINÉ1OPUTPAGÅzOPUTLINÅàOCNTBRË OPUTVERÔ‰OPUTHORÉ_OPUÔGOPUTÓ0OPUTCOÍsWPUÔïWFLUSÈ2 €é ÃÃÅ*‰€»ÍòÒÍ*‰}þbÂ'>l2‰ÍÁÉ (BÅ!"‰*]›"‰*]›"‰*_›"‰*e›}2‰*a›"‰*¬›}þpÍ�}2­›*¬›}þbÍ�}2®›ÁÉMEMGååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååLNEWLINÅÃÃÅ*‰ÍÒÍÁÉSFREÅMEMFREńà ÃÃÅ!þÿ9ùDMÍ� åÍ�~#fo+))Ñë`is#rÍ�åÍ� ÑÍìÚrÅ!úÿ9ùDM*¢›}·ÂÃÖÍ*£›åÍÑë͉ë! s#r*¸Šå*¶ŠÑë͉ë! s#rÍ�åÍ�ÑÍìÒÁÍ�åÍ�ÑÍúå*ã•ë͉Ñë`is#r`iå~#fo#åÍ� ëás#r*‰#"‰*‰åÍ�å! åÍÑÑÑ"‰Í� åÍ Ñë! s#rÍ�n}·Ê¦! ^#Vr+sën}þÓÊ�þÔÊŽþóÊ›þôÊ›ã>2­›>p2¬›Ã£>2®›>b2EÔMOVMEÍLGETCOÌLSTARTLÉ‘ÃÃÃÃÃÅ!üÿ9ùDM*‰|µÂ%!È*‰2ÍúÍ?ÓÍúë! s#rÍ�åÍÑë`is#rÍ�åÍ�å!‰åÍÑÑååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÍ�##~#fo|µÊ_Í�##~#foåÍÑ`i^#V{Ö_zÞWr+sÃ-Í�åÍÑë!9ùëÁÉ?N\pxWIDTÈEÃÃÅ*‰ÍÒ>*‰+))‰##~#fo|µÊåÍ�å*ã•ÑÍ)ÑÍúëás#r*¥›))‰åÍ�ëás#r*‰åÍ�Ñ"‰!åÍ Ñ*‰"£›*‰+"¥›ë!9ùëÁÉ '`ÆLGETCOÌBREAKTOËBREAKLIÎ]ì›Ã£>2¬›Ã£ÃQë!9ùëÁÉToo many tokens for a single line#&27Gilo{~‚¦¹Ìàè6FYmrw|Œ™¡¤LSTARTLÉL½‰›PUTÓ@ÃÃÅ!åÍÑÁÉCopyright (c) 1981 by Mark of the Unicorn Inc. Å!"‰!�»"‰{2­›{2®›ÁÉLBREAKLÉ ÃÑÍ� åÍ ëás#r*[›"]›Í Í�Èë!9ùëÁÉ#Jbq†LSTARTLÉLGETLENÇSSTOÃPPUTLINÅTINTERRÏWIDTÈÑÃÃÃÃÃÃÃÅCOPYRIGÈLINIÔTLFINÉrLSTARTHÅ�LHDRCENÔLHDRRIGÈ\LHDRLINÅeLENDHEAÄîLFOOTNOÔ,LNOFOOTÎ\LBREAKLɆLFREűLGETCOÌRLGETLENÇ>*‰å! åÍÑÑÍúÁÉÃC*‰ÁÉÁÉ&1<WIDTÈTABWIDTșà ÃÃÅ!þÿ9ùDMÍ�|µÂ !Ã�! ^#Vr+sÍ�ë`is#r! ^#Vr+sën}·ÊGETCOÌTINTERRÏ—Ã ÃÃÃÅ!9ùDM*‰|µÂÍÍ"‰*‰1ÍùÚ?!uåÍ Ñ!"‰*‰))‰åÍ�ëás#r*‰#"‰+))‰##¯w#w*‰åÍ�Ñå*TŒ+ÑÍúÒÍ�)¼ŠåÍ�#)¼Š~#foëás#rÍ�)„‹åÍ�#)„‹~#foëás#r`i^#Vr+sï*TŒ+"YŒ)¼Š"WŒ*WŒåÍ�ëás#r*TŒ+)„‹åÍ�ëás#ÑÑÍ$Í'!"WŒ*°•åÍÑ>2VŒ!"WŒ*²•åÍÑ* ›|¢g}£o|µÊ7*µ›Ã:*³›ë`is#rÍ�åÍÑÍÒnÍ!·åÍ�åÍ!ÑåÍÑÑÍ$Í'>2VŒ*PŒŒÑÍúÒ‡Í�åÍ Ñ`i^#Vr+sÃc*RŒå*NŒÑÍúåÍ Ñ*PŒë`is#rÍ�dÍùÒÃÍ�åÍ Ñ`i^#Vr+sá*P—}þfÂß*í•}·Âß! åÍÑÃð*á•å*ºŠÑÍúÅ!þÿ9ùDM*LŒ+)¼Šë`is#rÍ�å!¼ŠÑÍìÚSÍ�~#fo|µÊFÍ�~#foåÍÑ`i^#Vr+sÃ*PŒ)¼Šë`is#rÍ�å!„‹ÑÍìÒ—Í�~#fo|µÊŠÍ�~#fåÍ�ÑÍúÑ"NŒÃ Í�å!åÍÑÑë!9ùëÁÉ BEd�œSTRCPÙPROCESSÓCREAÔTPUTÓEXIÔ¼ÃÃÃÃÃÃÅ!ìÿ9ùDM>2Q—! n}"‰ÁÉToo many tokens for a single line /26\Å*¿•"´Š*Á•"¶Š*ß•å*ÕÑÍú"¸Š*á•å*Å•ÑÍú"ºŠ!"LŒ!€»"NŒ!d"PŒ*ºŠ"RŒ!dr*RŒåÍ�ÑÍú"RŒÃ†*LŒ"YŒ)¼Š"WŒ*WŒåÍ�ëás#r*LŒ#"LŒ+)„‹åÍ�ëás#r*NŒåÍ�Ñ"NŒë!9ùëÁÉToo many linesWarning: Footnote pag"TŒ>2�›!"WŒ*„›+"„›#ÍÒ˜Í*!"„›! n}2VŒë!9ùëÁÉheaderfooter!HQbeh€ˆ®ÀÆ×áäçðõúý /5FPSVåÍ Ñë!9ùëÁÉScribble intermediate output for: &.15=EMUpx…•¬´ÁÊÒÙÝíOPUTVERÔOPUTHORÉOPUÔWIDTÈOCNTBRËoåÍÑ`i^#Vr+sÃaë!9ùëÁÉ *7CQn{‡•MIÎASPACÅOPUTPAGÅPFREÅTPUÔTPUTÎPPUTVERÔSLENGTÈLSTARTHÅIUSÅSSTOÃSCRIBBLÅLENDHEAÄPþcÊ5! n}þpÂA! n}2P—Ñ>f2P—Í�å`iåÍÑÑ! n}·Í�å!šå`iåÍÑÑÑ`iåÍ Ñ"R—|·òŠ!ŸåÍ Ñ!åÍÑV—ë"T—ë!9ùëÁÉ.finUnable"TŒ>2VŒ!"WŒ!ÿ"ƒœÁÉMIÎASPACÅOPUTPAGÅPFREÅTPUTÓTPUTÎäÃÃÃÃÃÃÃÅ*‰åÍÑå*ƒœåÍÑÑ"ƒœ*LŒÍÒ=Í Í !žåÍe wrap not handled properly[^bf{ƒŽ’˜ ½EPPUTVERÔPPUTIÔLGETLINÅ�à ÃÃÃÅ!ýÿ9ùDM*ë•ë͉ë`is#r*å•åÍ�Ñ_dil“–LNOFOOTÎÃÃÅÍ>2VŒ!"WŒÁÉTINTERRÏPNEWPAGÅTERROÒÏà ÃÃÃÅ!þÿ9ùDM! å~#foå*å•ë͉Ñëás#r! OPUTÓSSTOÃOPUTCOÍÃÃÃÃÃÃÃÃÃÅ!îÿ9ùDMÍ�)¼Š~#foë! s#rÍ� |µÂVÍ�)„‹~#foåÍÑÃvÍ�)„‹~#foå*ë•ÑÍúNEWPAGžÃ-ÃÃÃÃÃÃÃÃÃÃÃÃÃÃÅ!ýÿ9ùDM*VŒë! s>2VŒ*‰åÍÑå*ƒœåÍÑÑ"ƒœ*LŒÍÒjÍ Í *ž›###^#Vr+ to open output file. (3?O_fox{‡WPUÔWFLUSÈCLOSÅ+à ÃÃÃÅ*P—}þfÂ)!åÍÑÍ*R—åÍ ÑÁÉ&OPUTÓOÑ*…œå*ƒœÑÍúåÍÑ!²åÍÑ*…œåÍÑ!»åÍÑ*Í•å* ‰åÍÑÑÍúåÍÑ!ÓåÍÑ*Í•åÍÑ!ÜåÍÑÁÉ Largest page used out of bytes. EÍóÒ<*å•ë`is#r*­›}·ÊU*½•}·ÊUÍ�åÍÑ*®›ë! s*‰åÍ åÍÑÑ! n}·Ê†*½•}·Ê†Í�åÍÑë!9ùëÁÉ 1BJRcgs{ƒPPUTIÔ©å~#foåÍ�å*å•ÑÍ)ÑÍúëás#r*PŒå*LŒÑÍÚh!�åÍÑÍ*NŒåÍ�Ñå*RŒÑÍìÚš*VŒ}·Ê—!å!å!žåÍ ÑÑÑÍ*VŒ}·ÊG*PŒ+"PŒë`is#rÍ�åÍÑÍ� ##~#foåÍÑ! 6 Í� n}þcÊ¢þrÊÏþbÊõÜÍ� ~#foåÍ�  ~#foÑÍúë͉åÍÑÜÍ� ~#foåÍ�  ~#foÑÍúsë" ›! åÍÑ* ›åÍÑ!"LŒ"NŒ!d"PŒ"TŒ*ºŠ"RŒ!"WŒ*´ŠåÍÑ* ›|¢g}£o|µÊÈ*±›ÃË*¯›ë`is#rÍ�åÍÑÍÒÿÍ!°åÍ�åÍ!ÑåÍPUÔOPUTLINÅOPUTVERÔÃÃÃÃÃÅ!þÿ9ùDM*Q—}·Ê]*P—}þfÂ]*í•}·Â]!ùåÍÑ!Ï•åÍÑ! åÍÑ! åÍÑ!åÍÑ>2Q—`i¯w#wÍ�å*Lnd space used out of bytes.$58;>BSW[cgkw�…‰‘•™LFOOTNOÔÃÃÅ>2VŒÍ!"WŒÁÉ LFREÅ ÃÃÃÃÅ!þÿ9ùDM*WŒ|µÊ’*WŒ~#fo|µÂ’*YŒ)„‹~#foë`is#rÍ�åÍ�ÑÍóÒGà*NŒåÍ�ÑåÍ�ÑÍúå*RŒÑÍìÒ’*YŒ)„‹åÍ�ëás#r*NŒåÍ�åÍÑÜ*P—}þfÂ|*í•}·Â|Í�  ~#foåÍ� ~#foÑÍóÚy!ŠåÍ ÑÍ� ~#foåÍ�  ~#foÑÍúë`is#rÍ�ÍååÍ ÑÍ�ÿ|¢g} 6 *P—}þcÂ`! n&ÍÚ`!å! n&åÍÑÑú*P—}þpÂ�! n&ÍÚ�!å! n&åÍÑÑú*P—}þfº*í•}·Ê®! n&ÍÚº*F]dOPUÔ±ÃÃÅ!þÿ9ùDMÍ�€»ÍòÚ$Í�|µÂ'è*P—}þfÂd*í•}·Âd!–åÍÑÍ�ÍååÍÑÍ�ÿ|¢g}£oåÍÑèÍ�å*ë•ëåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå�å! åÍ ÑÑÍ?åÍÑ! n}·Â«Í�åÍ�ÑÍúÒ«Í�åÍ� ÑÍÒÕ! n}·ÊÝÍ�åÍ� ÑÍÒÕÍ�åÍ�ÑÍúÒÝ! åÍ Ñ! ^#Vr+sÃÍåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå£oåÍ Ñ! 6 Ã™! 6Í� ~#foåÍ�  ~#foÑÍóÒÉÍ� ~#foåÍ�  ~#foÑÍúë`is#rÃÏ`i¯w#wÍ�å! åÍ ÑëÍËÑå! åÍ ! n&åÍÑÁÉ"+:JY^gw†‹”œ¬·OPUÔ2ÃÃÅ!9ùDMÍ�n}·Ê0! ^#Vr+sën&åÍÑÃÁÉ*.OPUÔkÃÃ͉Ñå*ë•Ñ͉ë`is#rÍ�|µÊ¨! åÍÑ! åÍÑ`i^#Vr+sÃë!9ùëÁÉ"%.6=L^bŠ‘™¦OPUÔWIDTȾà ÃÃÅ!üÿ9ùDMÍ�åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå�  åÍ�))Ñ~#foåÍÑ! ^#Vr+sìÍ�  åÍ� ~#fo+))Ñ##~#foë! s#rz³ÊJÍ�åÍÑåÍÑ*P—}þfÊ[*í•}·Ên! åÍ Ñ! åÍ ÑÃååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÑÑ͉ë! s#rÍ� åÍÑë! s#rÍ� ë! s#rÍ�Í?ÿ|¢g}£oåÍ�ÑÍë! s#rÍ�åÍ�åÍ�ÑÍÑë! s#rÍ� åÍ�ÑÍúͯë! Å!üÿ9ùDMÍ�n&–ë`is#rÍ�nåÍ�#nѯgW–ë! s#rÍ�åÍ�ÑÍìÒb`i^#Vr+sën&åÍÑÃ<ë!9ùëÁÉJ\`WFLUSÈ2ÃÃÅ!€»ÍòÚ'Í�|µÂ*õ*P—}þfÂg*í•}·Âg!ˆåÍÑÍ�ÍååÍÑÍ�ÿ|¢g}£oåÍÑõ! åÍÑë! s#rÍ�åÍ�ë͉ÑåÍ�Ñ͉ë`icc auxil.c -e8900 cc auxiltoo.c -e8900 cc commands.c -e8900 cc commtoo.c -e8900 l2 scribble auxil auxiltoo commands commtoo v!û•åÍÑë!9ùëÁÉ<?PTn}“˜� ÉÍïóü$+^pz ÇÙëš¿çïôÿ'2O\eiu~‰™©³ÃÓÚé:BGåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååås! å~#foåÍ�ÑÍëás#rÍ�åÍ�ÑÍËë! s#rÜ! ¯w#w! ¯w#wÍ�åÍ� ~#fo+ÑÍúÒÍ�  åÍ�))Ñ##~#foë! s#rÍ�|µÊëÍ�9ùDM*T—#"T—+å! nëás*T—å!U›ÑÍóÒ0ÍÁÉ+.WRITÅTERROҙà ÃÃÅ!þÿ9ùDM*T—å!V—ÑÍåÂ"Ãw*T—å!V—ÑÍú€ëÍËë`is#rÍs#rÍ�|µÊµ! åÍÑ`i^#Vr+sØë!9ùëÁÉ%(19@OaelŸ¦³PUTÃWPUԼà ÃÃÅ!9ùDM! n}þÂ3*í•}·Â-*P—}þfÊ3!input output -l alloc  character string that turns it on; otherwise,å!ÅWÃXof characters, and that you wish to use for text iQY`hlsoÅ!üÿ9ùDMÍ�~#fo+ë! s#rÍ�ë`is#rÍ�|·ú_Í� åÍ�))Ñ##~#fo|µÂS! ^#Vr+s`i^#Vr+sÃ#Í�Ãfë!9ùëÁÉåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååÍÑåÍÑ! n}·Ê*Í�  åÍ�#))Ñ##~#fo|µÊ*! n&åÍ Ñ! n}·ÂèÍ�  åÍ�#))Ñ##~#fo|µÊkÍ�#å! åÍ ÑÑÍ?åÍÑÃ�Í�å!V—å*R—åÍÑÑÑåÍ�ÑÍúÒp!å!å!€åÍÑÑÑV—ë"T—ë!9ùëÁÉOutput file write error. M\gkååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååTALL 0x1A /* ^Z */ #define EXIT 0x3 /* ^C */ #define FLAG char #define MICA unsigned #define repeat while (1) * ^F */ #define BEL 0x7 /* ^G */ #define BS 0x8 /* ^H */ #define TAB 0x9 /* ^I */ #define LF 0xA /* ^J */ #defix */ #define JUSTIFY '\212' /* ~^J */ #define HORIZSPACE '\210' /* ~^H */ #define VERTSPACE '\226' /* ~^V */ #define åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå */ #define UNANON '\316' /* ~N underscore alphanumeric */ #define UNANOFF '\356' /* ~n */ #define ITALON '\311' /* ~I iåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå#define ENDLIST (-1) #define INPUT 0 #define ABSOLUTE 0 #define DEFAULT 0 /* Special command characters */ #dene FF 0xC /* ^L */ #define CR 0xD /* ^M */ #define SO 0xE /* ^N */ #define SI 0xF /* ^O */ #define DC1 0x11 /MAXMICA 48000 /* largest possible mica measurement */ /* Printing options */ FLAG pausep; /* pause for page changes? */* CRAYON.H Global declarations for CRAYON.C and drivers Copyright (C) 1981 by Mark of the Unicorn, Inc. Created 81.3.12 talics */ #define ITALOFF '\351' /* ~i */ #define BITALON '\320' /* ~P bold italics */ #define BITALOFF '\360' /* ~p */ #ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååfine SENTENCEBREAK '\177' /* ^? */ #define TOKENBREAK '\240' /* ~ */ #define BOLDON '\302' /* ~B */ #define BOLDOFF '\* ^Q */ #define DC3 0x13 /* ^S */ #define ESC 0x1B /* ESC */ #define RS 0x1E /* ^^ */ #define US 0x1F /* ^_ */ / FLAG quietp; /* turns off user interaction */ int startpage, /* page to start printing on */ curpage; /* cuGyro This file contains the global declarations for the Scribble printer driver. */ #define TRUE (-1) #define FALdefine SUPERON '\323' /* ~S superscripts */ #define SUPEROFF '\363' /* ~s */ #define SUBON '\324' /* ~T subscripts (why noåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå342' /* ~b */ #define ROMANON '\322' /* ~R */ #define ROMANOFF '\362' /* ~r */ #define UNNBON '\325' /* ~U underscore tok#define DEL 0x7F /* DEL */ #define EOF 0x1A /* CP/M end of text marker */ #define ABORTFILE 0x7 /* ^G */ #define ABORrrent page */ /* For communication with driver */ #define BOLD 'B' #define UNDERSCORE 'U' #define ITALIC 'I' #defiSE 0 #define NULL 0 #define ERROR (-1) #define NUL 0x0 /* ^@ */ #define ETX 0x3 /* ^C */ #define ACK 0x6 /t?) */ #define SUBOFF '\364' /* ~t */ #define EXITON '\330' /* ~X eXit unusual attributes */ #define EXITOFF '\370' /* ~ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååens */ #define UNNBOFF '\365' /* ~u */ #define UNALLON '\301' /* ~A underscore everything */ #define UNALLOFF '\341' /* ~ane HORIZONTAL 'H' #define VERTICAL 'V' #define OVP 'O' #define BIDIREC 'D' #define CENTCHAR 'C' /* Input line bufACKWARD (-1) FLAG warned; /* you have been warned */ /* Underline map */ struct { int ulon, uloff; } ulmap[128]; /* .. two columns right */ #define BUFBLKS 64 /* 4K input buffer */ struct fbuf { char fname[20]; int fchan, fnleprinter type of the console */ /* Character width tables */ int fmicro; /* the first micro-spacing table record */ int int inchars, intokens; FLAG forcetok; /* force new token on next char? */ FLAG superp, subp; /* super- or sub-script? le output port */ int prtinp; /* Printer input(??) port */ int prtoutp; /* printer output port */ int modinp; /* modfer */ #define ILINEMAX 256 /* chars in input line buffer */ #define ITOKENMAX 128 /* tokens in input line */ char iline[ int nuls; FLAG ulonp; FLAG boldp, italicp, ulitalp; /* Output line buffer */ struct { char ochar; int ohpos; FLAG ft; char *fnextp, fbuff[BUFBLKS][128]; } inputbuf; char *title, *portname; /**************** Printer globals ***** maxmicro; /* the number of micro spacing records */ /* Character translation tables */ int ftran; /* the first transl*/ #define ATTRMAX 16 /* max depth of attribute stack */ struct token attrstack[ATTRMAX]; int attrsp; /* stack pointeem input port */ int modoutp; /* modem output port */ /* Terminal type descriptions */ int fterm; /* first terminal ILINEMAX]; struct token { int tokbegin; /* index in line */ int tokwidth; /* width of token */ int toklead; /* lobold, oital; } outline[200]; int olen; /**************** Device globals ****************/ int datfd; /* CONFIG.DA***********/ int phpos, pvpos; /* current position */ int pageh, pagev; /* page size */ int charh, linev; /* std cation record */ /* The size of the data file */ int hmax; /* number of records including header */ int cpuspeed; r */ struct justdesc { int jlefttok; /* token on which justification begins */ int jspace; /* amount of whitespacerecord */ int ourterm; /* the default terminal type */ int simterm; /* terminal type to simulate */ /* Printer descreading whitespace */ char tokscript; /* normal, super, or sub */ char tokuscore; /* underscored? */ FLAG tokbold; /T header and data records */ #define PORT 2 #define MICRO 3 #define PRINT 4 struct header { /* Input/output poharacter cell */ int spaceh; /* width of ' ' */ FLAG hackdone; /* paper hack done? */ #define FORWARD 1 #define B/* cpu speed in 100KHz */ } hdr; #define SSPACE 128-54 struct printdesc { /* describes the output device */ char dnam to add */ int jnbrk; /* number of token breaks */ } just; /* this will have to be a list to get .. */ FLAG justp; iptions */ int fprint; /* first printer record */ int ourprint; /* the default printer type */ int conprint; /* the * boldface? */ FLAG tokital; /* italic? */ char tokjust; /* justify on left of this token? */ } itokens[ITOKENMAX]; rt descriptions */ int fport; /* the first port record */ int coninp; /* console input port */ int conoutp; /* consoe[16]; /* name of the device */ MICA dwidth; /* width of the printing surface */ MICA dheight; /* height of the print sine VANILLA 1 /* no microspacing, standard controls */ #define DIABLO 2 /* 1620 & anything compatible */ #define EPSON p after */ donewline, /* ... do a newline */ boldon, /* ... turn on boldface */ boldoff, /* turn off boldface *Synchronization control */ #define NOSYNC 1 #define ETX_ACK 2 #define XON_XOFF 3 #define SYNCBUFSIZE 60 #define SEQSTART 0d to start at */ FLAG backspace; /* Does backspace work */ FLAG barecr; /* does bare CR work */ FLAG formfeed; /* doeataport; /* Data port, or bios call number */ char datamask; /* Mask to AND data with */ FLAG sbiosp; /* Use the bios urface */ MICA micahoriz; /* size of smallest horizontal increment */ MICA micavert; /* size of smallest vertical increme3 /* MX-80 (microvert) */ #define IDS460 4 /* IDS 460 proportional */ #define SPINWRITER 5 /* Spinwriter & friends */ #/ italon, /* turn on italics */ italoff; /* turn off italics */ char strspc[SSPACE]; /* where strings are stored *x100 #define SEQEND (SEQSTART + 0x20) FLAG syncok; /* for XON/XOFF: OK to send character? */ int synccnt; /* for Es form feed work */ char synctype; /* Type of waiting to do: NONE, ETX/ACK, ^S^Q */ FLAG needtran; /* Do character transcall numbered by the status port if non-zero */ char statport; /* Status port, or bios cnt */ FLAG isprop; /* does it have a proportional width font? */ char fontnum; /* if isprop, which width table to use */define CUSTOM 6 /* user custom subroutines */ #define QUME 7 /* Qume & friends */ #define CEN737 8 /* Centronics 737 / } dev; MICA widtab[128]; /* Character width table */ char trantbl[128]; /* Character translation table */ chaTX/ACK: no of chars sent so far */ int syncnbufs; /* for ETX/ACK: no of buffers sent */ /**************** Globals for lation on output? */ char trannum; /* Translation table number */ struct str { /* Various strings to send */ char idxall number */ char readymask; /* Mask to AND status with */ char polarity; /* (Status AND mask == ) if ready */ } MICA stdhoriz; /* width of a canonical character */ MICA stdvert; /* height of a single spaced line */ FLAG isfile; */ /**************** Output globals ****************/ struct portdesc { char pname[16]; /* Zero terminated port namr tsect[128]; int dhpos, dvpos; int dbold, dital; #define NOCHAR (-1) int dbufchar; /* Control code types */ #defprinter drivers ****************/ #define UNINITIALIZED 0x8000 int drvhpos, drvvpos; /* current horizontal, vertical pos; /* index into space */ char len; /* length */ } initstr, /* ... set things up */ finistr, /* ... clean u iport, oport; /* Output queue */ #define QUEUE_SIZE 192 /* Size of output queue */ int oqueue [QUEUE_SIZE + 4]; /* /* do plain file output? */ char prtcode; /* printer type code for crayon */ MICA paperoffset; /* height paper is assumee */ FLAG dbiosp; /* Use the bios call numbered by the data port if non-zero */ char dition */ int drvhpitch, drvvpitch; /* current pitch of printer */ int drvdirec; /* current print direction */ FLAGe = 1; for (iarg = 1; iarg < argc; ++iarg) { if (*argv[iarg] == '-') { optname = argv[iarg] + 1; if (isdigit (*optns code interprets the command line and the Scribble output file, and calls the low-level abstraction to do the printing. */ break; } Fatal (fmt, a1, a2, a3, a4, a5) /* lose, lose */ char *fmt; int a1, a2, a3, a4, a5; { printf (fmt, a1, a2ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååoptname, "Quiet")) quietp = TRUE; else if (match (optname, "Title") || match (optname, "T")) { title = argv[+ drvshiftp; /* is printer shifted? */ /* End of CRAYON.H -- globals for Scribble print program */ us port, or bios came)) ntimes = atoi (optname); else if (match (optname, "Page")) { startpage = atoi (argv[++iarg]); if (!quietp) p #include "crayon.h" main (argc, argv) int argc; char **argv; { int ntimes, itime, iarg; char *optname; struct, a3, a4, a5); exit (1); } PrintFile (fname, ntimes) char *fname; int ntimes; { char devname[80], i, c, tfname[2åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå+iarg]; if (!quietp) printf ("Title string is '%s'.\n", title); } else printf ("Unknown command line option: '%s'\åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååårintf ("Starting at page %d.\n", startpage); } else if (match (optname, "Pause")) { pausep = TRUE; puts ("Pau { char *fname; int fntimes; } files[20]; int nfiles; puts ("Crayon Version 1.3, Copyright (C) 1981 by Mark of t0]; FLAG done; strcpy (&tfname, fname); dfltext (&tfname, "FIN"); if (IOpen (&tfname, INPUT) < 0) { printf ("Can'tåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååån", argv[iarg]); } else { files[nfiles].fname = argv[iarg]; files[nfiles].fntimes = ntimes; ++nfilesååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååsing for manual insertion of each page.\n"); } else if (match (optname, "Port")) { portname = argv[++iarg]; ihe Unicorn Inc.\n"); ntimes = 1; nfiles = 0; pausep = FALSE; title = ""; portname = NULL; quietp = FALSE; startpag open input file '%s'.\n", &tfname); return; } for (i = 32; i; --i) INext(); if (IChar() != ':') Fatal ("I only un/* CRAYON.C Top level of Scribble print driver Copyright (C) 1981 by Mark of the Unicorn Inc. Created 81.3.12 Gyro Thi; } } for (iarg = 0; iarg < nfiles; ++iarg) if (PrintFile (files[iarg].fname, files[iarg].fntimes) == ABORTALL) ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååf (!quietp) printf ("Using the '%s' port(s).\n", portname); } else if (match (optname, "Q") || match (derstand Scribble intermediate output files."); INext(); for (i=0; INext() != EOF; ++i) devname[i] = IChar(); devname[i-2] input line */ { if (ReadLine()) { PrintLine(); return (TRUE); } return (FALSE); } ReadLine () /* read t inch; inch = PUnMica (2540, HORIZONTAL); PMoveH (inch); PPrtStr (IName ()); PMoveH (inch / 2); PPrtStr (title); ase BOLDON: attrtok = AttrPush(); attrtok->tokbold = TRUE; ForceTok(); break; case ROMANON: attrtok = AttAttrInit(); while (!done && DoLine()) if (TKbRdy()) switch (c = TGetKb()) { case ABORTFILE: puts ("Aborti(curpage >= startpage) PMoveV (tdist); break; default: done = TRUE; break; } if (!done) INext(); } do = NUL; INext(); if (!quietp) { if (ntimes == 1) printf ("Printing '%s' on device '%s' -- OK? ", &tfname, &dehe line and build data structure */ { FLAG done; FLAG sbrkprev; /* was previous char a SENTENCEBREAK? */ char inchar, PCR(); PMoveV (PLineV()); PMoveH (inch * 2); PPrtStr ("Crayon version 1.2"); /* vsn of this prog. */ PCR(); } NexrPush(); attrtok->tokbold = FALSE; attrtok->tokital = FALSE; ForceTok(); break; case UNNBON: case UNALLON:ng this file.\n"); done = c; break; case ABORTALL: puts ("Aborting all files.\n"); done = c; break;ne = sbrkprev = FALSE; repeat { PSendChk(); inchar = IChar(); switch (inchar) { case CR: INext(); case vname); else printf ("Printing %d copies of '%s' on device '%s' -- OK? ", ntimes, &tfname, &devname); if (!Ask (""brklevel, IChar(); struct token *temptok, *attrtok; int tdist; inchars = intokens = 0; superp = subp = FALSE; justptPage() /* process page boundary */ { ++curpage; if (curpage < startpage && !quietp) printf (" [%d]", curpage); else case UNANON: attrtok = AttrPush(); attrtok->tokuscore = inchar; ForceTok(); break; case ITALON: attrt case EXIT: exit (1); default: break; } IRew(); while (INext() != EOF); /* skip file header */ LF: case FF: done = TRUE; break; case EOF: return (FALSE); break; case VERTSPACE: done = TRUE; )) { puts (" -- skipping file.\n\n"); return (ABORTFILE); } } PInit (&devname, portname, !pausep); if (PVPos( = FALSE; ForceTok(); done = FALSE; while (!done) { PSendChk(); switch (IChar()) { case LF: if (curpage > { if (!quietp) printf (" %d", curpage); PNewPage(); if (pausep) PagePause(); } } DoLine() /* process anok = AttrPush(); attrtok->tokital = TRUE; ForceTok(); break; case BITALON: attrtok = AttrPush(); attrtok- INext(); PNewPage(); } PFini(); IClose (); return (done); } FileHeader() /* print file header */ { intbreak; case HORIZSPACE: ForceTok(); temptok = GetTok(); temptok->toklead += GetDist (HORIZONTAL); break; c) != 0) { FileHeader(); PFF(); } done = FALSE; while (ntimes-- > 0 && !done) { curpage = 0; NextPage(); = startpage) PLF(); break; case FF: NextPage(); break; case VERTSPACE: tdist = GetDist (VERTICAL); if >tokbold = TRUE; attrtok->tokital = TRUE; ForceTok(); break; case SUPERON: superp = TRUE; attrtok = AttrPs], sizeof(attrstack[0])); itokens[intokens].tokbegin = inchars; itokens[intokens].tokwidth = 0; itokens[intokenk; default: temptok = GetTok(); iline[inchars++] = inchar; temptok->tokwidth += PWidChar (inchar); break; sert fresh page; type any character when ready --> "); getchar(); putchar ('\n'); } PrintLine() /* output the accu case UNNBOFF: case ROMANOFF: case BOLDOFF: case EXITOFF: AttrPop(); ForceTok(); break; case JUSTIFY: rstack[0].tokital = attrstack[0].tokjust = FALSE; } AttrPush() /* push attribute stack */ { if (attrsp >= ATTush(); attrtok->tokscript = inchar; ForceTok(); break; case SUBON: subp = TRUE; attrtok = AttrPush(); s].toklead = 0; ++intokens; forcetok = FALSE; } return (&itokens[intokens-1]); } GetDist (direc) /* get a di } if (done) break; sbrkprev = inchar == SENTENCEBREAK; INext(); } if (sbrkprev && justp) just.jspace += PWidSenmulated line */ { int tvert; if (curpage < startpage) return; if (justp) JustLine(); tvert = max (1, PLineV() / 2); justp = TRUE; just.jlefttok = intokens; just.jspace = GetDist (HORIZONTAL); just.jnbrk = 0; break; case TRMAX) Fatal ("Character attributes nested too deeply.\n"); else { movmem (&attrstack[attrsp], &attrstack[attrsp+1], attrtok->tokscript = inchar; ForceTok(); break; case EXITON: attrtok = AttrPush(); attrtok->tokscript = FALSstance from the input stream */ int direc; { unsigned tdist; tdist = (INext() << 8) + INext(); if (tdist > MAXMICA) t(); itokens[intokens].tokbegin = inchars; return (TRUE); } ForceTok() /* break current token */ { forcetok = T if (superp) { PMoveV (-tvert); PrintScript (SUPERON); PCR(); PMoveV (tvert); } PrintScript (FALSE); PCR(); OKENBREAK: ForceTok(); temptok = GetTok(); temptok->tokjust = TRUE; temptok->toklead += PWidChar (' '); ++ju sizeof(attrstack[0])); ++attrsp; } return (&attrstack[attrsp]); } AttrPop() { if (attrsp <= 0) Fatal ("AttrE; attrtok->tokuscore = FALSE; attrtok->tokbold = FALSE; attrtok->tokital = FALSE; attrtok->tokjust = FALSE; Fatal ("Invalid mica value in intermediate file.\n"); return (PUnMica (tdist, direc)); } AttrInit() /* initializeRUE; } GetTok() /* make a new token if needed */ { if (forcetok) { movmem (&attrstack[attrsp], &itokens[intoken if (subp) { PMoveV (tvert); PrintScript (SUBON); PCR(); PMoveV (-tvert); } } PrintScript (script) /* prst.jnbrk; break; case SENTENCEBREAK: ForceTok(); temptok = GetTok(); temptok->toklead += PWidSent(); breaPop: stack underflow\n"); --attrsp; } PagePause() /* pause, get fresh page from user */ { PForce(); puts ("\nIn ForceTok(); break; case SUBOFF: case SUPEROFF: case BITALOFF: case ITALOFF: case UNANOFF: case UNALLOFF: the attribute stack */ { attrsp = 0; attrstack[0].tokscript = attrstack[0].tokuscore = attrstack[0].tokbold = attint all of super, normal, or subscripts */ char script; { int thmove, itok; thmove = 0; for (itok=0; itok < intokensdChk(); } /* Buffered file input routines */ IOpen (name, mode) /* open file in */ char *name; int((just.jspace * 17) & 0x7FFF) % njust; /* random num */ oddcnt = totspace % njust; PSendChk(); for (itok = just.jlefttok; buf = &inputbuf; if (!buf || !buf->fchan) return; seek (buf->fchan, 0, ABSOLUTE); buf->fnleft = 0; INext (buf); tr (UNDERSCORE, itokens[itok].tokuscore); PSetAttr (BOLD, itokens[itok].tokbold); PSetAttr (ITALIC, itokens[itok].tokital); utbuf; if (!buf->fchan) return (ERROR); ++(buf->fnextp); if (--(buf->fnleft) <= 0) { nread = read (buf->fchan, &buf->fb; ++itok) { if (itokens[itok].tokscript == script) { PMoveH (thmove); PrintTok (itok, script); PSendChk(); th mode; { int tfd; struct fbuf *buf; buf = &inputbuf; /* someday this might allocate */ tfd = open (name, mode); itok < intokens; ++itok) if (itokens[itok].tokjust) itokens[itok].toklead += evenspace; PSendChk(); for (itok = just.jl} IClose() /* close the file */ { struct fbuf *buf; buf = &inputbuf; if (!buf || !buf->fchan) return (ERROR for (ichar = itokens[itok].tokbegin; ichar < itokens[itok+1].tokbegin; ++ichar) PPrtChar (iline[ichar]); PSetAuff, BUFBLKS); if (nread < 0) { IClose(); return (ERROR); } buf->fnleft = nread * 128; buf->fnextp = &buf->move = 0; } else thmove += itokens[itok].tokwidth + itokens[itok].toklead; } } PrintTok (itok, script) /* prinif (tfd < 0) return (ERROR); buf->fchan = tfd; strcpy (&buf->fname, name); buf->fnleft = 0; INext (buf); return (buf);efttok; oddstart > 0; ++itok) if (itokens[itok].tokjust) --oddstart; PSendChk(); for (; oddcnt > 0; ++itok) { if (itok); close (buf->fchan); buf->fchan = NULL; } match (s1, s2) /* case-independent string equality */ char *s1, *s2;ttr (UNDERSCORE, FALSE); } JustLine() /* justify the line */ { int totspace, njust; int itok, evenspace, oddstartfbuff; } return (*(buf->fnextp)); } IName() /* return file name */ { struct fbuf *buf; buf = &inputbuf; t a token */ int itok; char script; { int ichar; if (itok != 0 && !script && itokens[itok-1].tokuscore == UN } IChar() /* return current char */ { struct fbuf *buf; buf = &inputbuf; if (!buf->fchan) return (ERROR); >= intokens) itok = just.jlefttok; if (itokens[itok].tokjust) { --oddcnt; ++itokens[itok].toklead; } } PSen { while (TRUE) { if (toupper (*s1) != toupper (*s2)) return (FALSE); if (!*s1++ || !*s2++) return (TRUE); } } , oddcnt; totspace = just.jspace; njust = just.jnbrk; if (!njust) return; evenspace = totspace / njust; oddstart = if (!buf || !buf->fchan) return (""); return (&buf->fname); } IRew() /* rewind file */ { struct fbuf *buf; ALLON && itokens[itok].tokuscore == UNALLON) PSetAttr (UNDERSCORE, UNALLON); PMoveH (itokens[itok].toklead); PSetAt return (*(buf->fnextp)); } INext() /* get next char & return */ { struct fbuf *buf; int nread; buf = &inp Ask (q) /* ask a yes/no question */ char *q; { puts (q); repeat { switch (toupper (TGetKb())) { case ' ':olen = 0; warned = FALSE; } PFini() /* turn things off */ { PCR(); PNewPage(); if (hackdone) PMoveV (PUnMicao This code implements a generalized printer abstraction for use by Crayon or Pencil. */ #include "crayon.h" FLA(c >= ' ' && c <= '~') return (DWidChar (c)); else if (c & 0x80) return (1 + PWidChar (c & 0x7F)); else return (1 + PWi of CRAYON.C -- Scribble print driver top level */ uf *buf; buf = &inputbuf; if (!buf || !buf->fchan) return (ERROR if (c != ' ') { outline[olen].ochar = c; outline[olen].ohpos = phpos; outline[olen].obold = boldp; outline[o case 'Y': puts ("Yes\n"); return (TRUE); case DEL: case BS: case BEL: case 'N': puts ("No\n"); r (dev.paperoffset, VERTICAL)); PForce(); DFini(); } PPrtChar (c) /* print a character */ char c; { FLAG ulreaG PInit (device, portname, hackp) /* initialize printer */ char *device, *portname; FLAG hackp; /* do paper hack? */ { dChar (c ^ 0x40)); } PPrtStr (s) /* print a NUL-term string */ char *s; { while (*s) PPrtChar (*s++); } PWåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååålen].oital = italicp && !ulitalp; ++olen; } phpos += PWidChar (c); } else if (c & 0x80) { PPrtChar ('~'); /*eturn (FALSE); default: puts ("\nAnswer 'Y' or 'N' --> "); break; } } } dfltext (fn, ext) /* default lly; if ((ulonp || italicp) && (ulonp == UNALLON || ((ulonp == UNNBON || (italicp && ulitalp)) && c != DInit (device, portname, hackp); phpos = 0; if (hackp) pvpos = PUnMica (dev.paperoffset, VERTICAL); else pvpos = 0; haidStr (s) /* width of string */ char *s; { int wid; for (wid = 0; *s; ++s) wid += PWidChar (*s); return (wid); åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå not supporting full meta convention */ PPrtChar (c & 0x7F); } else { PPrtChar ('^'); PPrtChar (c ^ 0x40); } fn's extension to ext */ char *fn, *ext; { while (*fn) if (*fn++ == '.') return; *fn++ = '.'; strcpy (fn, ext); } ' ') || (ulonp == UNANON && (isalpha (c) || isdigit (c))))) { ulreally = TRUE; /* underscore italics for now */ ckdone = hackp; ulonp = FALSE; nuls = 0; ulmap[0].uloff = -1; boldp = italicp = FALSE; ulitalp = !DrvInfo (ITALIC); } PWidSent() /* width of end-of-sentence */ { return (DWidChar (DEL)); } PMoveH (dh) /* create horizontal w/* PRINTER.C Printer abstraction and support routines Copyright (C) 1981 by Mark of the Unicorn, Inc. Created 81.3.18 Gyrif (ulreally) ulmap[nuls].uloff = phpos; PSendChk(); } PWidChar (c) /* width of c when printed */ char c; { if /* "Terminal abstraction" */ TKbRdy() { return (bios (2)); } TGetKb() { return (bios (3)); } /* End if (phpos != ulmap[nuls].uloff) ulmap[++nuls].ulon = phpos; } else ulreally = FALSE; if (c >= ' ' && c <= '~') {hitespace */ int dh; { if (ulonp == UNALLON && ulmap[nuls].uloff != phpos) ulmap[++nuls].ulon = phpos; phpos += dh; D: if (dev.boldon.len || DrvInfo (OVP)) boldp = state; else PWarnOnce(); break; case ITALIC: if (dev.italon.len )) >> 5; return (temp); } if (direc == HORIZONTAL) tstd = dev.micahoriz; else if (direc == VERTICAL) tstd = dev.micaverned) return; puts ("This device, as currently defined, cannot overprint.\n"); warned = TRUE; } PFlush() /* outputemp >> 7; /* mica * 6 / 127 */ temp = (temp + (temp & 8)) >> 4; return (temp); } if (dev.micavert == 53 && dire where are we? */ { return (pvpos % pagev); } PCharH() /* width of canonical char */ { return (charh); } if (ulonp == UNALLON) ulmap[nuls].uloff = phpos; } PMoveV (dv) /* vertical move */ int dv; { PFlush(); pvpos || DrvInfo (OVP)) italicp = state; else PWarnOnce(); break; default: Fatal ("PSetAttr: unknown attribute\n"); brrt; else Fatal ("PUnMica: bad direc?"); if (mica > 32767) temp = mica / (tstd >> 1); else temp = (mica << 1) / tstd; rett line, with underline and bold */ { int iul, i, starti, uswidth, direc; if (!olen) return; DSetV (pvpos); pvpos %= c == VERTICAL) { temp = mica + (mica >> 2) /* 1/48 in */ - (mica >> 5) /* mica * 12 / 635 */ - (mica >> 7) PLineV() /* height of line */ { return (linev); } PPageH() /* width of page */ { return (pageh); } += dv; } PForce() /* actually get the carriage there */ { PFlush(); DSetH (phpos); DSetV (pvpos); pvpos %= peak; } } PCR() /* do carriage return */ { PFlush(); phpos = 0; } PLF() /* do a line feed */ { Purn ((temp >> 1) + (temp & 1)); } PSetAttr (attr, state) /* turn on or off a character attribute */ char attr; FLAG pagev; direc = PPickDirec (outline[0].ohpos, outline[olen-1].ohpos); starti = (direc == FORWARD) ? 0 : olen - 1; for (i = - (mica >> 9); temp = (temp + (temp & 32)) >> 6; return (temp); } if (dev.micavert == 35 && direc == VERTICAL)PPageV() /* height of page */ { return (pagev); } PSendChk() /* maybe send output character */ { if (OStKnowagev; DForce(); } int PUnMica (mica, direc) /* convert mica to internal units */ unsigned mica, direc; { unsigneMoveV (linev); } PFF() /* do a form feed */ { PMoveV (pagev - (pvpos % pagev)); } PNewPage() /* FF if nostate; { switch (attr) { case UNDERSCORE: if (DrvInfo (OVP)) ulonp = state; else PWarnOnce(); break; case BOLstarti; i >= 0 && i < olen; i += direc) { DSetH (outline[i].ohpos); DSetAttr (BOLD, outline[i].obold); DSetAttr (ITAL { temp = mica - (mica >> 4) /* 1/72 in. (Epson) */ - (mica >> 5) + (mica >> 10); temp = (temp + (temp & 16n()) OSendChk(); } /******** Internal calls ********/ PWarnOnce() /* warn user about losing device */ { if (wad tstd, temp; if (dev.micahoriz == 21 && direc == HORIZONTAL) { temp = mica - (mica >> 2); /* 1/120 in */ temp += t at TOF */ { if (pvpos % pagev) PFF(); } PHPos() /* where are we? */ { return (phpos); } PVPos() /*IC, outline[i].oital); DPrtChar (outline[i].ochar); if (outline[i].obold && !DrvInfo (BOLD) && DrvInfo (CENTCHAR)) { ; DPrtChar ('_'); if (direc == FORWARD) { if (ulpos >= ulend) break; ulpos += min (uswidth, ulend - ulpos); } } PUnderScr() /* do underscores for the current line */ { int i, starti, uswidth, ulstart, ulend, ulpos, direc; v.needtran) { ReadRec (hdr.ftran + dev.trannum); movmem (&tsect, &trantbl, 128); } OInit (portname); close (datfd);d via reprint */ { int bstart, bend, starti, i, direc; for (bstart = 0; bstart < olen; ++bstart) if (outline[bstart]."); movmem (&tsect, &hdr, sizeof(hdr)); if (device == DEFAULT) DfltPrt(); else if (!FindRec (PRINT, device)) { printf ( DMoveH (direc); /* bold with small offset */ DPrtChar (outline[i].ochar); } PSendChk(); } if (!DrvInfo (BOLD } else { if (ulpos <= ulstart) break; ulpos -= min (uswidth, ulpos - ulstart); } PSendChk(); } direc = PPickDirec (ulmap[1].ulon, ulmap[nuls].uloff); starti = (direc == FORWARD) ? 1 : nuls; uswidth = DWidChar ('_') charh = PUnMica (dev.stdhoriz, HORIZONTAL); linev = PUnMica (dev.stdvert, VERTICAL); pageh = PUnMica (dev.dwidth, HORIZONobold) break; if (bstart >= olen) return; for (bend = olen; !outline[bend-1].obold; --bend); direc = PPickDirec (outline[b"Can't find device '%s'; using default.\n", device); DfltPrt(); } movmem (&tsect, &dev, sizeof (dev)); if (dev.isprop)) && !DrvInfo (CENTCHAR)) PReBold(); PUnderScr(); olen = nuls = 0; } int PPickDirec (leftend, rightend) /* pick op} nuls = 0; } /**************** Generalized Device driver code ****************/ DInit (device, portname, hackp) ; for (i = starti; i >= 1 && i <= nuls; i += direc) { ulstart = ulmap[i].ulon; ulend = ulmap[i].uloff - uswidth; ulTAL); pagev = PUnMica (dev.dheight, VERTICAL); spaceh = DWidChar (' '); if (hackp) dvpos = PUnMica (dev.paperoffset, VERTIstart].ohpos, outline[bend-1].ohpos); starti = (direc == FORWARD) ? bstart : bend - 1; for (i = starti; i >= bstart && i < sizeof(attrstack[0])); ++attrsp; } return (&attrstack[attrsp]); } AttrPop() { if (attrsp <= 0) Fatal ("Attrtimal direction */ int leftend, rightend; { if (DrvInfo (BIDIREC) && abs (DHPos() - rightend) < abs (DHPos() - lefte char *device, *portname; FLAG hackp; { int i; if (((datfd = open ("config.dat", INPUT)) < 0 && (datfd = open ("pos = (direc == FORWARD) ? ulstart : ulend; if (ulstart > ulend) ulpos = (ulstart + ulend) / 2; repeat { DSetH (ulpos)CAL); else dvpos = 0; dhpos = 0; DrvInit (dvpos); dbufchar = NOCHAR; } DFini() { DForce(); DrvFini(); OFin bend; i += direc) if (outline[i].obold) { DSetH (outline[i].ohpos); DPrtChar (outline[i].ochar); PSendChk(); movmem (&tsect, &widtab[64], 128); for (i = 0; i < 128; ++i) widtab[i] = PUnMica (widtab[i], HORIZONTAL); } if (dend)) return (BACKWARD); /* nb: that's -1 */ else return (FORWARD); /* and that's +1 */ } PReBold() /* bola:config.dat", INPUT)) < 0) || read (datfd, &tsect, 1) < 1) Fatal ("Can't open the system database file (CONFIG.DAT)\ni(); } DSetH (hpos) /* move to hpos (absolute) */ int hpos; { dhpos = hpos; } DSetV (vpos) /* move to ortname; { char tport[20]; if (portname != DEFAULT) { if (!FindRec (PORT, portname)) { sprintf (&tport, "%s Out",val ? &dev.boldon : &dev.boldoff); } dbold = val; break; case ITALIC: if (dital != val && dev.italon.len) { &oqueue); } OPutNum (n) /* send a number in ASCII */ int n; { if (n >= 10) OPutNum (n / 10); OPutChar (n % 10 a character */ char c; { int offset; offset = DrvInfo (CENTCHAR) ? DWidChar (c) / 2 : 0; DMoveH (offset); DFlush( (hdr.prtinp); else Fatal ("No default input port defined (one is required for synchronization).\n"); movmem (&tsect, &ipovpos (absolute) */ int vpos; { DMoveV (vpos - (dvpos % pagev)); } DMoveH (delh) /* move by delh (relative) */ i portname); if (!FindRec (PORT, &tport)) Fatal ("Can't find port '%s' or '%s'.", portname, &tport); } } else DFlush(); OPutCmd (val ? &dev.italon : &dev.italoff); } dital = val; break; } } DForce() { DFlush();+ '0'); } OPutCmd (cmd) /* output a control string */ struct str *cmd; { char *chr, *endchr; int i; chr = &); DMoveH (-offset); dbufchar = dev.needtran ? trantbl[c] : c; } int DWidChar (c) /* width of c when printed */ rt, sizeof (iport)); } IQInit (&oqueue, QUEUE_SIZE); syncok = TRUE; synccnt = 0; syncnbufs = 0; } OFini() { nt delh; { dhpos += delh; } DMoveV (delv) /* move by delv (relative) */ int delv; { if (delv < 0) Fatal ("DMovif (hdr.prtoutp) ReadRec (hdr.prtoutp); else Fatal ("No default output port defined!\n"); movmem (&tsect, &oport, sizeof (op OFlush(); } DFlush() /* flush buffer */ { DrvPrtMove (dbufchar, dhpos, dvpos); dvpos %= pagev; dbufchar = Ndev.strspc[cmd->idx]; endchr = &dev.strspc[cmd->idx + cmd->len]; OUnInter (cmd->len); while (chr < endchr) OPutChar (*chr+ char c; { return (dev.isprop ? widtab[c] : charh); } DSetAttr (attr, val) /* set innate attribute if possible */ i OFlush(); } OFlush() /* flush output buffer */ { while (!IQEmpty (&oqueue)) OSendChk(); } OPutChar (c) eV: can't move up!\n"); dvpos += delv; } int DHPos() /* return current horizontal location */ { return (dhpos);ort)); if (dev.synctype != NOSYNC) { if (portname != DEFAULT) { sprintf (&tport, "%s In", portname); if (!FindRec (OCHAR; } /**************** Output queue maintainer and port drivers ****************/ OInit (portname) char *p+); } OPutSeq (list) /* send an uninterruptible sequence */ int list; { int *argptr, nargs; argptr = &list; nt attr; FLAG val; { switch (attr) { case BOLD: if (dbold != val && dev.boldon.len) { DFlush(); OPutCmd (/* output a character */ char c; { while (IQFull (&oqueue)) OSendChk(); OSendChk(); /* at least once */ IQShove (c, } int DVPos() /* return current vertical location */ { return (dvpos % pagev); } DPrtChar (c) /* printPORT, &tport)) Fatal ("Can't find port '%s', required for synchronization.", &tport); } else if (hdr.prtinp) ReadRec for (nargs = 0; *argptr++ != ENDLIST; ++nargs); OUnInter (nargs); argptr = &list; while (nargs--) OPutChar (*argptr++); ; return (((iport.sbiosp ? bios (iport.statport) : inp (iport.statport)) & iport.readymask) == iport.polarity); } ++syncnbufs; synccnt = 0; } if (PIRdy() && PIGet() == ACK && syncnbufs > 0) --syncnbufs; return (syncnbufs < lrec; ++frec) { ReadRec (frec); if (match (name, &tsect)) return (TRUE); } return (FALSE); } ReadRec (rec) output status known? */ { return (!(oport.sbiosp && !oport.statport)); } FLAG OReady (c) /* ready for this char, c); else outp (oport.dataport, c); } /******** Utility routines for reading database ********/ FLAG FindRec ( } OUnInter (seqlen) /* guarantee nchars uninterrupted */ int seqlen; { if (seqlen < 0 || seqlen >= 32) Fatal (" char PIGet() /* get char from printer */ { return ((iport.dbiosp ? bios (iport.dataport) : inp (iport.dataport)) < 2 && PORdy()); default: Fatal ("Invalid synchronization code: '%d'", dev.synctype); break; } } OSend (c) /* read a CONFIG.DAT record */ int rec; { if (seek (datfd, rec, ABSOLUTE) < 0 || read (datfd, &tsect, 1) < 1) Facter? */ int c; { int seqlen; if (c >= SEQSTART && c < SEQEND) seqlen = c - SEQSTART; else seqlen = 1; switch (type,name) /* Locate a record by class and name */ int type; /* returns success flag */ char *name; { int frec, lrecOUnInter: %d chars is too many!\n", seqlen); while (IQFull (&oqueue)) OSendChk(); IQShove (SEQSTART + seqlen, &oqueue); } & iport.datamask); } FLAG PORdy() /* printer ready for character */ { if (oport.sbiosp && !oport.statport) ret /* send a character */ int c; { if (c >= SEQSTART && c < SEQEND) return; /* ignore seq codes */ POPut (c); ++synccnatal ("Read error in system database file (CONFIG.DAT)\n"); } DfltPrt() /* read definition of default printer */ { dev.synctype) { case NOSYNC: return (PORdy()); case XON_XOFF: if (PIRdy()) syncok = (PIGet() != DC3); return (sy; switch (type) { case PORT: frec = hdr.fport; lrec = hdr.fterm; break; case PRINT: frec = hdr.fprint; OSendChk() /* send a command if ready */ { while (!IQEmpty (&oqueue) && OReady (IQPeek (&oqueue))) { OSend (IQGrurn (TRUE); return (((oport.sbiosp ? bios (oport.statport) : inp (oport.statport)) & oport.readymask) == oport.polarityt; } FLAG PIRdy() /* char available from printer input? */ { if (iport.sbiosp && !iport.statport) return (TRUE) if (hdr.ourprint == 0) Fatal ("No default printer defined!\n"); ReadRec (hdr.ourprint); if (!tsect[0]) Fatal ("Invalid defancok && PORdy()); case ETX_ACK: if (synccnt + seqlen > SYNCBUFSIZ) { if (!PORdy()) return (FALSE); POPut (ETX); lrec = hdr.fmicro; break; default: Fatal ("FindRec: Invalid record type."); return (FALSE); } for (frec=0; frec ab (&oqueue)); if (!OStKnown()) break; } /* break if we don't really know status */ } FLAG OStKnown() /* is); } POPut (c) /* send char to printer */ char c; { c &= oport.datamask; if (oport.dbiosp) bios (oport.dataportult printer definition (record deleted).\n"); } /* End of PRINTER.C -- vanilla printer driver */  FLAG FindRec ( case CUSTOM: CusFini(); break; case QUME: QmFini(); break; */ case CEN737: CenFini(); break; } OPutCm EPSON: EpInit (vpos); break; case IDS460: IDSInit (vpos); break; case SPINWRITER: SpInit (vpos); break; ME: return (QmInfo (what)); break; */ case CEN737: return (CenInfo (what)); break; } } /**************** ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååos, vpos); break; */ case CEN737: CenPrtMove (c, hpos, vpos); break; } } FLAG DrvInfo (what) /* ask abouååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååd (dev.finistr); } DrvPrtMove (c, hpos, vpos) /* print c and move to hpos, vpos */ int c, hpos, vpos; { switch (dev/* case CUSTOM: CusInit (vpos); break; case QUME: QmInit (vpos); break; */ case CEN737: CenInit (vpos); breVanilla driver ****************/ VInit (vpos) int vpos; { if (dev.barecr) OPutChar (CR); drvhpos = 0; drvvpos = vpos/* DRIVER.C Specialized printer drivers Copyright 1981 by Mark of the Unicorn, Inc. Created 81.6.1 Gyro This file contt printer */ int what; { switch (dev.prtcode) { case VANILLA: return (VInfo (what)); break; case DIABLO: reåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå.prtcode) { case VANILLA: VPrtMove (c, hpos, vpos); break; case DIABLO: DbPrtMove (c, hpos, vpos); break; cak; } } DrvFini() { switch (dev.prtcode) { case VANILLA: VFini(); break; case DIABLO: DbFini(); ; } VFini() { } VPrtMove (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPuains the drivers for various kinds of printers. */ #include "crayon.h" DrvInit (vpos) int vpos; { OPutCmd (&dev.inturn (DbInfo (what)); break; case EPSON: return (EpInfo (what)); break; case IDS460: return (IDSInfo (what)); ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååase EPSON: EpPrtMove (c, hpos, vpos); break; case IDS460: IDSPrtMove (c, hpos, vpos); break; case SPINWRITER: break; case EPSON: EpFini(); break; case IDS460: IDSFini(); break; case SPINWRITER: SpFini(); break; /*tChar (c); drvhpos += DWidChar (c); } delh = hpos - drvhpos; delv = vpos - drvvpos; if (delh < 0) { if (delv) { itstr); switch (dev.prtcode) { case VANILLA: VInit (vpos); break; case DIABLO: DbInit (vpos); break; case break; case SPINWRITER: return (SpInfo (what)); break; /* case CUSTOM: return (CusInfo (what)); break; case QUåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå SpPrtMove (c, hpos, vpos); break; /* case CUSTOM: CusPrtMove (c, hpos, vpos); break; case QUME: QmPrtMove (c, hp OPutCmd (&dev.donewline); delv -= linev; delh = hpos; } else if (dev.barecr && (!dev.backspace vpos; { int delh; delh = hpos - drvhpos; if (c != NOCHAR) { if ((!DbSpcOk (delh) && !DbTabOk (hpos) && abs (del request\n"); } } /**************** Diablo driver ****************/ DbInit (vpos) int vpos; { drvvpos = vpospcOk (delh) /* can we move this far by spaces? */ int delh; { return (drvhpitch != 0 && abs (delh) % drvhpitch == pagev; } FLAG VInfo (what) /* ask about printer */ int what; { switch (what) { case OVP: /* can it ovee (delh) if (delh * drvdirec > 0) { OPutChar (' '); delh -= drvhpitch * drvdirec; } else { OPutChar || -delh > hpos + 1)) { OPutChar (CR); delh = hpos; } else if (dev.backspace) while (delh < 0) { OPutChar h) <= 125) || (abs (delh) == spaceh && !dev.isprop)) DbSHPitch (abs (delh)); DbSDirec ((delh < 0) ? BACKWARD : ; OPutChar (CR); drvhpos = 0; drvhpitch = drvvpitch = drvdirec = UNINITIALIZED; drvshiftp = TRUE; DbSHPitch (spaceh); 0 && abs (delh) / drvhpitch < 7); } DbTabOk (hpos) /* can we get here with abs horiz tab? */ int hpos; { rprint? */ return (dev.barecr || dev.backspace); case CENTCHAR: /* does it center characters? */ case BIDIREC: /*(BS); delh += drvhpitch * drvdirec; } return; } if (abs (delh) > 125 || DbTabOk (hpos)) { if (drvhpitch =(BS); delh += spaceh; } } if (dev.formfeed) /* reconstruct form feeds */ while (delv > (vpos % pagev)) { /*FORWARD); DbSShift ((c & 128) ? TRUE : FALSE); OPutChar (c & 127); drvhpos += drvhpitch * drvdirec; } DbMoveH (hpo DbSVPitch (linev); DbSDirec (FORWARD); DbSShift (FALSE); } DbFini() { DbSHPitch (spaceh); DbSVPitch (linev); return (drvhpitch != 0 && hpos % drvhpitch == 0 && hpos / drvhpitch <= 125); } DbMoveV (vpos) /* vertica does it need explicit bidirection? */ return (FALSE); case BOLD: /* can it boldface innately? */ return (dev.boldon.= 0 || hpos / drvhpitch > 125) DbSHPitch ((hpos / spaceh <= 125) ? spaceh : 13); DbHTab (hpos / drvhpitch); delh = h believe it or not! */ OPutChar (FF); delv -= pagev - (vpos - delv) % pagev; } while ((delv -= linev) >= 0) { Os); DbMoveV (vpos); } DbMoveH (hpos) /* horizontal move */ int hpos; { int delh; delh = hpos - drvhpos; DbSDirec (FORWARD); DbSShift (FALSE); } DbPrtMove (c, hpos, vpos) /* print c and move to hpos, vpos */ int c, hpos, l move */ int vpos; { int delv; delv = vpos - drvvpos; if (!delv) return; drvvpos = vpos % pagev; while (delv) {len != 0); case ITALIC: /* can it italic innately? */ return (dev.italon.len != 0); default: Fatal ("VInfo: unknownpos % drvhpitch; } if (delh) { DbSHPitch (abs (delh)); OPutChar ((delh * drvdirec < 0) ? BS : ' '); } } DbSPutCmd (&dev.donewline); delh=hpos; } while ((delh -= spaceh) >= 0) OPutChar (' '); drvhpos = hpos; drvvpos = vpos %if (!delh) return; drvhpos = hpos; if (DbSpcOk (delh) && (abs (delh) / drvhpitch < 4 || !DbTabOk (hpos))) { whil DbSVPitch (min (delv, 125)); OPutChar (LF); delv -= drvvpitch; } } DbSHPitch (hpitch) /* set horizontal pi; drvhpos += DWidChar (c); } delh = hpos - drvhpos; delv = vpos - drvvpos; if (delh < 0 && !delv) { OPutChar (Ce innately? */ return (dev.boldon.len != 0); case ITALIC: /* can it italic innately? */ return (dev.italon.len != 0);os; drvhpos = 0; drvvpitch = UNINITIALIZED; OPutChar (CR); } IDSFini() { IDSSVPitch (linev); } IDSPrtMoveo pos */ int pos; { OPutSeq (ESC, TAB, pos + 1, ENDLIST); } DbSShift (shiftp) /* shift on or off (only for NEC 551e OVP: /* can it overprint? */ return (TRUE); case CENTCHAR: /* does it center characters? */ case BIDIREC: /* tch */ int hpitch; { if (hpitch == drvhpitch) return; OPutSeq (ESC, US, hpitch + 1, ENDLIST); drvhpitch = hpitch; } R); delh = hpos; } while (delv) { EpSVPitch (min (delv, 85)); OPutCmd (&dev.donewline); delv -= drvvpitch; d default: Fatal ("DbInfo: unknown request\n"); } } /**************** Epson driver ****************/ EpInit (vp (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPutChar (c); drvhpos += DWidChar (c); 5/25) */ FLAG shiftp; { if (drvshiftp == shiftp) return; OPutChar (shiftp ? SO : SI); drvshiftp = shiftp; } FLAGdoes it need explicit bidirection? */ return (FALSE); case BOLD: /* can it boldface innately? */ return (dev.boldon.l DbSVPitch (vpitch) /* set vertical pitch */ int vpitch; { if (vpitch == drvvpitch) return; OPutSeq (ESC, RS, vpitchelh = hpos; } while ((delh -= spaceh) >= 0) OPutChar (' '); drvhpos = hpos; drvvpos = vpos % pagev; } EpSVPitch os) int vpos; { OPutChar (CR); drvhpos = 0; drvvpos = vpos; drvvpitch = UNINITIALIZED; } EpFini() { EpSVPit } delh = hpos - drvhpos; delv = vpos - drvvpos; while (delv) { IDSSVPitch (min (delv, 255)); OPutCmd (&dev.donewl DbInfo (what) int what; { switch (what) { case OVP: /* can it overprint? */ case CENTCHAR: /* does it centeen != 0); case ITALIC: /* can it italic innately? */ return (dev.italon.len != 0); default: Fatal ("EpInfo: unknown + 1, ENDLIST); drvvpitch = vpitch; } DbSDirec (direc) /* set print direction */ int direc; { if (direc == drvdi(vpitch) /* set vertical pitch */ int vpitch; { if (drvvpitch == vpitch) return; OPutSeq (ESC, 'A', vpitch, ESC, '2', Ech (linev); } EpPrtMove (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPutChar (c)ine); delv -= drvvpitch; delh = hpos; } if (delh < 0) { OPutChar (CR); delh = hpos; } if (delh % spaceh) {r characters? */ case BIDIREC: /* does it need explicit bidirection? */ return (TRUE); case BOLD: /* can it boldfac request\n"); } } /**************** IDS 460 driver ****************/ IDSInit (vpos) int vpos; { drvvpos = vprec) return; OPutSeq (ESC, (direc == FORWARD) ? '5' : '6', ENDLIST); drvdirec = direc; } DbHTab (pos) /* abs tab tNDLIST); drvvpitch = vpitch; } FLAG EpInfo (what) /* ask about printer */ int what; { switch (what) { cas IDSHTab (hpos); delh = 0; } while (delh >= spaceh) { OPutChar (' '); delh -= spaceh; } drvhpos = hpos; && !dev.isprop)) SpSHPitch (abs (delh)); SpSDirec ((delh < 0) ? BACKWARD : FORWARD); SpSShift ((c & 128) ? TRUE : FAch = drvvpitch = drvdirec = UNINITIALIZED; drvshiftp = TRUE; SpSHPitch (spaceh); SpSVPitch (linev); SpSDirec (FORWARD); hpos; { return (hpos % (dev.isprop ? 10 : charh) == 0); } SpMoveV (vpos) /* vertical move */ int vpos; { int d/ return (TRUE); case CENTCHAR: /* does it center characters? */ case BIDIREC: /* does it need explicit bidirection } return; } if (abs (delh) > 15 || SpTabOk (hpos)) { SpHTab (hpos / (dev.isprop ? 10 : charh)); delh = hpos % drvvpos = vpos % pagev; } IDSSVPitch (vpitch) int vpitch; { if (drvvpitch != vpitch) { OUnInter (6); OPutChar LSE); OPutChar (c & 127); drvhpos += drvhpitch * drvdirec; } SpMoveH (hpos); SpMoveV (vpos); } SpMoveH (hpos SpSShift (FALSE); } SpFini() { SpSHPitch (spaceh); SpSVPitch (linev); SpSDirec (FORWARD); SpSShift (FALSE); elv; delv = vpos - drvvpos; if (!delv) return; drvvpos = vpos % pagev; /* this ought to do abs vertical tab ??? */ ? */ return (FALSE); case BOLD: /* can it boldface innately? */ return (dev.boldon.len != 0); case ITALIC: /* ca(dev.isprop ? 10 : charh); } if (delh) { SpSHPitch (abs (delh)); OPutChar ((delh * drvdirec < 0) ? BS : ' '); } (ESC); OPutChar ('B'); OPutNum (vpitch); OPutChar (CR); drvvpitch = vpitch; } } IDSHTab (pos) /* abs ho) /* horizontal move */ int hpos; { int delh; delh = hpos - drvhpos; if (!delh) return; drvhpos = hpos; if (S} SpPrtMove (c, hpos, vpos) /* print c and move to hpos, vpos */ int c, hpos, vpos; { int delh; delh = hpos - drvwhile (delv) { SpSVPitch (min (delv, 16)); OPutChar (LF); delv -= drvvpitch; } } SpSHPitch (hpitch) /* set n it italic innately? */ return (dev.italon.len != 0); default: Fatal ("IDSInfo: unknown request\n"); } } /*} SpSpcOk (delh) /* can we move this far by spaces? */ int delh; { return (drvhpitch != 0 && abs (delh) % drrizontal tab to */ int pos; { OUnInter (7); OPutChar (ESC); OPutChar ('G'); OPutNum (pos); OPutChar (CR); }pSpcOk (delh) && (abs (delh) / drvhpitch < 4 || !SpTabOk (hpos))) { while (delh) if (delh * drvdirec > 0) { hpos; if (c != NOCHAR) { if ((!SpSpcOk (delh) && !SpTabOk (hpos) && abs (delh) <= 15) || (abs (delh) == spaceh horizontal pitch */ int hpitch; { if (hpitch == drvhpitch) return; OPutSeq (ESC, ']', hpitch + '@', ENDLIST); drvhpitch*************** Spinwriter driver ****************/ SpInit (vpos) int vpos; { drvvpos = vpos; drvhpos = 0; drvhpitvhpitch == 0 && abs (delh) / drvhpitch < 10); } SpTabOk (hpos) /* can we get here with abs horiz tab? */ int FLAG IDSInfo (what) /* ask about printer */ int what; { switch (what) { case OVP: /* can it overprint? * OPutChar (' '); delh -= drvhpitch * drvdirec; } else { OPutChar (BS); delh += drvhpitch * drvdirec; = hpitch; } SpSVPitch (vpitch) /* set vertical pitch */ int vpitch; { if (vpitch == drvvpitch) return; OPutSeq while (delh >= spaceh) { OPutChar (' '); delh -= spaceh; } while (delh > 0) { OPutSeq (ESC, min (delh, 6), ENDLI******/ CenInit (vpos) int vpos; { OPutChar (CR); drvhpos = 0; drvvpos = vpos; } CenFini() { } CenPrtIQINIÔIQGRAÂbIQSHOVÅÂIQEMPTÙ(IQFULÌSIQPEEËÄCQINIÔCQGRAÂqCQSHOVÅÎCQEMPTÙ1CQFULÌ\CQPEEËÌ€ } FLAG SpInfo (what) int what; { switch (what) { case OVP: /* can it overprint? */ case CENTCHAR: /*n.len != 0); default: Fatal ("CenInfo: unknown request\n"); } } /* End of DRIVER.C -- specialized printer drive(ESC, ']', vpitch + 'O', ENDLIST); drvvpitch = vpitch; } SpSDirec (direc) /* set print direction */ int direc; { ST); delh -= min (delh, 6); } drvhpos = hpos; drvvpos = vpos % pagev; } FLAG CenInfo (what) /* ask about prMove (c, hpos, vpos) int c, hpos, vpos; { int delh, delv; if (c != NOCHAR) { OPutChar (c); drvhpos += DWidChar ( does it center characters? */ case BIDIREC: /* does it need explicit bidirection? */ return (TRUE); case BOLD: /* rs */  delh = hpos - drvhpos; delv = vpos - drvvpos; while (delv >= linev) { OPutChar (LF); delv -= linev; } if (direc == drvdirec) return; OPutSeq (ESC, (direc == FORWARD) ? '>' : '<', ENDLIST); drvdirec = direc; } SpHTab (pinter */ int what; { switch (what) { case OVP: /* can it overprint? */ return (TRUE); case CENTCHAR: /* doc); } delh = hpos - drvhpos; delv = vpos - drvvpos; while (delv >= linev) { OPutChar (LF); delv -= linev; } can it boldface innately? */ return (dev.boldon.len != 0); case ITALIC: /* can it italic innately? */ return (dev.itaååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååos) /* abs tab to pos */ int pos; { OPutSeq (ESC, pos / 32 + 'P', pos % 32 + '@', ENDLIST); } SpSShift (shiftp) es it center characters? */ case BIDIREC: /* does it need explicit bidirection? */ return (FALSE); case BOLD: /* caif (delv == linev / 2) OPutSeq (ESC, 28, ENDLIST);/* half line feed */ if (delh < 0) { OPutChar (CR); delh = hpos; } lon.len != 0); default: Fatal ("SpInfo: unknown request\n"); } } /**************** Centronics driver **********åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå /* shift on or off */ FLAG shiftp; { if (drvshiftp == shiftp) return; OPutChar (shiftp ? SO : SI); drvshiftp = shiftp;n it boldface innately? */ return (dev.boldon.len != 0); case ITALIC: /* can it italic innately? */ return (dev.italoXÅ!9ùDMÍ�åÍ�##åÍ�åÍ�ëás#rás#rás#rÍ�åÍ�~#foåÍ�Ñ)++ëás#rÁÉWÅ!9ùDMÍ�~#foåÍ�~#rogram prints an ASCII file using the definitions in CONFIG.DAT. */ #include "crayon.h" #define MAXTABS 32 /* max #åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååår *devname; /* device to print on */ int headingp; /* print heading on each page? */ int leftmar, rightmar; /* text mar~#foåÍ�~#foÑÍìÚAÍ�åÍ�~#foëás#rën&ÃNÍ�^#Vr+sën&ÁÉÁÉ"?ZÅ!9ùDMÍ�##~#foåÍ�~#foÑÍìÚBÍ�##åÍ�eferences */ FLAG scriptpush; /* do supper/sub scripts get more space */ FLAG ischapter; /* does @chapter command exist */foÑÍìÚBÍ�åÍ�~#foëás#rë~#foÃSÍ�^#Vr+së~#foÁÉÁÉ"@]Å!9ùDMÍ�##~#foåÍ�~#foÑÍìÚBÍ�##åÍ�~#foëá of tabs */ struct { MICA tabcolumns[MAXTABS];/* where tabs are */ MICA headerspace; /* vertical space to leave after headåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååågins */ int cleftmar, crightmar; /* margins as entered from command line */ int perfskip; /* amount to skip around page pe~#foëás#rëÃPÍ�##^#Vr+sëåÍ�ëásÁÉ$@&Å!9ùDMÍ�~#foåÍ�##~#foÑÍåÍ�ÁÉÁÉgÅ!9ùDMÍ�##~#fo#åÍ�~#foÑÍåÍ MICA stop; /* margins */ MICA sleft; MICA sright; MICA sbottom; MICA above; /* space to leave before an environmes#rëÃQÍ�##^#Vr+sëåÍ�ëás#rÁÉ$@&Å!9ùDMÍ�~#foåÍ�##~#foÑÍåÍ�ÁÉÁÉhÅ!9ùDMÍ�##~#fo##åÍ�~#foÑÍåÍ�ÊdÍ�er */ MICA footerspace; /* and before footer */ char prefjust; /* preferred justification style 'b' both or 'l'åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååårfs */ main (argc, argv) int argc; char **argv; { int ntimes, itab, iarg, tabwidth; char *optname; struct { �ÊcÍ�##~#foåÍ�~#foÑÍåÍ�ÂcÍ�~#foåÍ�~#foÑÍåÍ�ÁÉÁÉ$EFÅ!9ùDMÍ�~#foåÍ�~#foÑÍåÂ6Í�~#fonnt */ MICA below; /* space to leave after an environment */ FLAG levindent; /* do nested Level environments indent? */ ##~#foåÍ�~#foÑÍåÍ�ÂdÍ�~#foåÍ�~#foÑÍåÍ�ÁÉÁÉ%FIÅ!9ùDMÍ�~#foåÍ�~#foÑÍåÂ7Í�~#fo~#foÃEÍ� left */ char footstyle; /* where footnotes go: 'i' inline, 'b' bottom, 'e' end */ MICA indent; /* amount to ind/* PENCIL.C Generalized random-file printer Copyright (C) 1981 by Mark of the Unicorn Inc. Created 81.7.31 Gyro This p char *fname; int fntimes; } files[20]; int nfiles; puts ("Pencil Version 1.3, Copyright (C) 1981 by Mark of the Un&Ã@Í�~#fo#n&ÁÉÁÉ"4FLAG levhang; /* are Level paragraphs outdented? */ int endsize; /* space to reserve for enddata */ } scribrec; cha~#fo##~#foÁÉÁÉ"5VÅ!9ùDMÍ�åÍ�##åÍ�åÍ�ëás#rás#rás#rÍ�åÍ�~#foåÍ�Ñ+ëás#rÁÉTÅ!9ùDMÍ�ent paragraphs */ MICA spread; /* number of lines between paragraphs */ MICA linespacing; FLAG footpush; /* footnote ricorn Inc.\n"); ntimes = 1; nfiles = 0; pausep = FALSE; title = ""; portname = DEFAULT; devname = DEFAULT; quietp ghtmar = atoi (argv[++iarg]); if (!quietp) printf ("Right margin set to %d characters.\n", crightmar); } else if ((!quietp) printf ("Starting at page %d.\n", startpage); } else if (match (optname, "Pause")) { pausep = TRUE; me, files[iarg].fntimes) == ABORTALL) break; } PrintFile (fname, ntimes) char *fname; int ntimes; { char c; ; if (!quietp) printf("Left margin set to %d characters.\n", cleftmar); } else if (match (optname, "NH") = ntimes; ++nfiles; } } if (((datfd = open ("config.dat", INPUT)) < 0 && (datfd = open ("a:config.dat", INPUT= FALSE; startpage = 1; headingp = TRUE; cleftmar = crightmar = -1; perfskip = 3; tabwidth = DEFAULT; for (iarg = 1;match (optname, "Tab") || match (optname, "Tabs")) { tabwidth = atoi (argv[++iarg]); if (!quietp) printf ("T puts ("Pausing for manual insertion of each page.\n"); } else if (match (optname, "Port")) { portname = argv[++iaFLAG done; if (IOpen (fname, INPUT) < 0) { printf ("Can't open input file '%s'.\n", fname); return; } if (!quiet || match (optname, "NoHeading")) { if (!quietp) puts ("Not printing page headings.\n"); headingp = FALSE; )) < 0)) Fatal ("Can't open the system database file (CONFIG.DAT)\n"); seek (datfd, 2, ABSOLUTE); read (datfd, tsect, 1); iarg < argc; ++iarg) { if (*argv[iarg] == '-') { optname = argv[iarg] + 1; if (isdigit (*optname)) ntimes = atoi (opab stops set every %d characters.\n", tabwidth); } else if (match (optname, "T") || match (optname, "Title"))rg]; if (!quietp) printf ("Using the '%s' port(s).\n", portname); } else if (match (optname, "Q") p) { if (ntimes == 1) printf ("Printing '%s' -- OK? ", fname); else printf ("Printing %d copies of '%s' -- OK? ", ntim } else if (match (optname, "NS") || match (optname, "NoSkip")) { if (!quietp) puts ("Not skipping page per movmem (tsect, scribrec, sizeof (scribrec)); close (datfd); if (tabwidth != DEFAULT) for (itab = 0; itab < MAXTABS; ++tname); else if (match (optname, "Dev")) { devname = argv[++iarg]; if (!quietp) printf ("Using the '%s' device.\n" { title = argv[++iarg]; if (!quietp) printf ("Title string is '%s'.\n", title); } else printf ("Unknown comm|| match (optname, "Quiet")) quietp = TRUE; else if (match (optname, "R") || match (optname, "Right")) { cries, fname); if (!Ask ("")) { puts (" -- skipping file.\n\n"); return (ABORTFILE); } } PInit (devname, portnaforations.\n"); perfskip = 0; } else if (match (optname, "Page")) { startpage = atoi (argv[++iarg]); if itab) scribrec.tabcolumns[itab] = itab * tabwidth; for (iarg = 0; iarg < nfiles; ++iarg) if (PrintFile (files[iarg].fna, devname); } else if (match (optname, "L") || match (optname, "Left")) { cleftmar = atoi (argv[++iarg])and line option: '%s'\n", argv[iarg]); } else { files[nfiles].fname = argv[iarg]; files[nfiles].fntimes me, !pausep); if (cleftmar == -1) leftmar = PUnMica (scribrec.sleft, HORIZONTAL); else leftmar = cleftmar * PCharH(); if (f (scribrec.tabcolumns[itab] * PCharH() + leftmar > PHPos()) { PMoveH (scribrec.tabcolumns[itab] * PCharH() + lefts page boundary */ { int prevh; ++curpage; if (!quietp) printf (" %d", curpage); prevh = PHPos(); PCR(); PNewPagåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå done = c; break; case EXIT: exit (1); default: break; } INext(); } IRew(); PNewPa PMoveH (leftmar); PSetAttr (UNDERSCORE, UNNBON); sprintf (str, "File: %s", IName()); PPrtStr (str); PMoveH ((PPageHcrightmar == -1) rightmar = PUnMica (scribrec.sright, HORIZONTAL); else rightmar = crightmar * PCharH(); if (PVPos() != 0) {mar - PHPos()); break; } if (itab >= MAXTABS) PMoveH (PCharH()); break; case FF: PFF(); NextPage(); be(); if (pausep) PagePause(); if (headingp && perfskip > 0) { if (perfskip >= 3) PLF(); PageHeader(); } PMoveV ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååge(); } PFini(); IClose(); return (done); } FileHeader() /* print file header */ { int inch; inch = P() - PWidStr (title) - rightmar + leftmar) / 2 - PHPos()); PPrtStr (title); sprintf (str, "Page: %d", curpage); PMoveH (PP FileHeader(); PFF(); } done = FALSE; while (ntimes-- > 0 && !done) { curpage = 0; NextPage(); DoChar (Creak; case CR: PCR(); PMoveH (leftmar); break; case LF: PLF(); if (PVPos() >= PPageV() - perfskip * PLineV())(perfskip * PLineV() - PVPos()); PMoveH (prevh); } DoChar (ochar) /* process a char */ char ochar; { int itab; cc crayon.c -e6100 cc printer.c -e6100 cc driver.c -e6100 l2 crayon printer driver -l queue cc pencil.c -e6100 l2 pencil prUnMica (2540, HORIZONTAL); PMoveH (inch); PPrtStr (IName ()); PMoveH (inch / 2); PPrtStr (title); PCR(); PMoveV (PLiageH() - PWidStr (str) - rightmar - PHPos()); PPrtStr (str); PSetAttr (UNDERSCORE, FALSE); PCR(); } /* End of PENCIR); while (!done && IChar() != EOF) { DoChar (IChar()); if (TKbRdy()) switch (c = TGetKb()) { case ABORTFI NextPage(); break; default: if (PHPos() + PWidChar (ochar) > PPageH() - rightmar) { DoChar (CR); DoChar (LF); switch (ochar) { case BS: PMoveH (-PCharH()); break; case TAB: for (itab = 0; itab < MAXTABS; ++itab) iinter driver -l crayon queue WÃÔWSome printers require a synchronization protocol in orderåÍ”6ë!9ùë|µÊìW!&ÃHcÃ4c!å!E’åneV()); PMoveH (inch * 2); PPrtStr ("Pencil version 1.2"); /* vsn of this prog. */ PCR(); } NextPage() /* procesL.C -- print a standard ASCII file */ leftmar > PHPos()) { PMoveH (scribrec.tabcolumns[itab] * PCharH() + leftLE: puts ("\nAborting this file.\n"); done = c; break; case ABORTALL: puts ("\nAborting all files.\n"); } PPrtChar (ochar); break; } } PageHeader() /* print the page header */ { char str[80], *c; int len; ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååecial set of defines that provide an interesting, and perhaps more readable, control structure. The program is included in thne one line at a time untill a region of difference is encountered and then an exaustive search is done for the smallest regio input files */ /* Forward function declarations */ char *FMore(); FLAG FEOF(), FMatch(); /* The program */ main(argcåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå variables */ #define BUFFSIZ 8192 #define MAXLINES 50 char iobuff[BUFSIZ], *ofd; /* Declarations for C buffered output */ ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååe Scribble package as an interesting and perhaps usefull "bonus". */ #include "bdscio.h" /* Universal defines */ #defin of difference that ends in two lines which are the same. The size of regions of matching is printed, the entire contents o,argv) /* Source commpare program */ int argc; char *argv[]; { printf("DIFF Version 1.1 Copyright (c) 1981 by Mark of th/* DIFF.C - Source compare by lines (Differences) Copyright (c) 1981 by Mark of the Unicorn Inc. Created by Jason T. Linha struct fbuff { /* The file buffer structure */ int fd; /* C I/O package file descriptor */ char *eptr, *mptr; /* poååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååne TRUE (-1) #define FALSE 0 #define NULL 0 #define NUL '\0' #define CR '\r' #define LF '\n' #define EOF '\32' #definf both versions of regions of difference is printed. The program also accepts "-p" on the command line to direct the output toe Unicorn Inc.\n"); /* argument decoding */ if argc==3 then ofd=1; elseif argc==4 && !strcmp("-P",argv[3]) then rt 4/29/81 Updated to version 1.1 7/19/80 JTL This program is a simple source compare program that works by lines. Twinters into buff */ char buff[BUFFSIZ]; /* Character buffering */ struct lbuff { /* Line buffering */ char *lptr; /*ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååe FLAG char #define loop WHILE (1) { #define endloop } #define if IF ( #define then ) { #define elseif } ELSE IF ( the CP/M list device and "-o " to direct the output to the named file. The program is written in BDS-C using a sp ofd=2; elseif argc==5 && !strcmp("-O",argv[3]) then ofd=iobuff; if fcreat(argv[4],ofd)<0 then Fatal("Unable to openo input files, specified on the command line, are commpared one line at a time for regions of difference. The comparison is do Location of line in memory */ int lhash; /* Hash of line's contents */ } line[MAXLINES]; } f1, f2; /* Allow for twoåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå #define else } ELSE { #define endif } #define while IF (!( #define until IF (( #define remain )) BREAK /* Global output file."); endif else Fatal("Usage: 'diff file_one file_two (-p | -o file)'"); endif /* Initialize input **************\n"); tmp=0; loop while tmp<=depth remain; FPrint(0,tmp); ++tmp; endloop fprintf(ofd,"**********\n")FMatch(depth+1,level+1) remain; if level=MAXLINES-1 then Fatal("Files differ by more than %d{ struct fbuff *fdesc; int thash; char *cptr; /* This function fills in amt more lines in the line table,d %d lines.\n",depth); endif if FEOF() then return; endif /* For every line in each file, compare it and the /* Open the input files, checking for possible errors, initialize the buffer pointers and fill the initial region of difference */ loop while !FEOF() remain; DoRgn(); endloop /* Close files, finish up output */ FFinit(depth,level); } /* The File abstraction */ /* The 'F' or File abstraction maintains a buffer of two input fi lines.",MAXLINES); endif /* Make tmp be the length in the first file */ if FMatch(level,depth) && FMatch(level+1,dep lines are read from the file buffer and their hash values stored in the line table. */ fdesc=(file==0)? &f1 :next line with every previous line in the other file, looking for a two line match */ depth=level=0; loop line table. */ if (f1.fd=open(name1,0))<0 then Fatal("Unable to open '%s'.",name1); endif if (f2.fd=open(name2,0))<0 th(); fprintf(ofd,"Comparison complete.\n"); if ofd>3 then putc(EOF,ofd); fflush(ofd); fclose(ofd); endif; } Dles with special line hash values to allow for very fast line comparisons. An array of MAXLINES lines of informationth+1) then tmp=level; level=depth; depth=tmp; endif /* Print the region of difference */ fprintf(ofd,"****** &f2; loop while amt>0 remain; fdesc->line[MAXLINES-amt].lptr=cptr=fdesc->eptr; /* Check for end of file */ if cp while depthline[MAXLINES-amt].lhash=0; else /* Calculate hash value */ thash=0; loop /* Wtr-128*ramt); } FNext(amt1,amt2) /* Move down amt line in each file */ int amt1, amt2; { /* The routine moves th>line; elin = &fdesc->line[last]; dist = fdesc->line[0].lptr - fdesc->buff; /* Now fix up the existing line pointers { /* Returns TRUE if you are at the end of file on both input files */ return(f1.line[0].lptr==NULL && f2.linsc->eptr=cptr; --amt; endloop } char * FMore(fdesc,last) /* Read in more of a file */ struct fbuff *fdesc; int l? &f1 : &f2; if fdesc->line[lev].lptr==NULL then fprintf(ofd,"%d> EOF\n",file+1); else fprintf(ofd,"%d> %s\n",file+1,fatch out for using up the buffer */ if cptr >= fdesc->mptr then cptr=FMore(fdesc,MAXLINES-amt); endif whilee files up amt1 and amt2 lines, moves up the existing lines to replace old lines and then read in new li*/ loop while slin<=elin remain; slin->lptr-=dist; ++slin; endloop /* Calculate amount more to be read */ size[0].lptr==NULL); } FFini() /* Close the files */ { close(f1.fd); close(f2.fd); } Fatal(mesg,arg) /* Print a ast; { struct lbuff *slin, *elin; int size, dist, ramt; /* This routine reads more text into the data buffdesc->line[lev].lptr); endif } FLAG FMatch(lev1,lev2) /* compare two lines for a match */ int lev1, lev2; { / *cptr!=EOF remain; while *cptr!=CR || *(cptr+1)!=LF remain; thash += *cptr++; endloop /* Put nulls at thnes to replace them. */ movmem(&f1.line[amt1],&f1.line[0],sizeof(f1.line[0])*(MAXLINES-amt1)); FFill(0,amt1); movmem(&f2.le = (BUFFSIZ-size)/128; ramt=read(fdesc->fd,fdesc->mptr-dist,size); if ramt<0 then Fatal("File read error"); endif fdesc->fatal error message */ char *mesg, *arg; { printf("Fatal: "); printf(mesg,arg); printf("\n"); exit(1); } /* END er, preserving the text pointed to by lines that are in use. */ size=fdesc->mptr - fdesc->line[0].lptr; /* Firs* Returns TRUE if the two lines are the same Uses the line hash to speed comarison */ return(f1.line[lev1].lhash==f2.le end of the line so they will print correctly */ if *cptr==EOF then *cptr=NUL; cptr=NULL; else *ine[amt2],&f2.line[0],sizeof(f2.line[0])*(MAXLINES-amt2)); FFill(1,amt2); } FPrint(file,lev) /* print a line */ int fimptr+=ramt*128-dist; /* Check for end of file condition */ if ramtmptr=EOF; endif return(fdesc->mpOF DIFF.C - source commpare program */  /* Prints a specified line, prints 'EOF' on end of file */ fdesc=(file==0)t move text to be saved to the begining of the buffer */ movmem(fdesc->line[0].lptr,fdesc->buff,size); slin = fdesc-ine[lev2].lhash && !strcmp(f1.line[lev1].lptr,f2.line[lev2].lptr)); } FLAG FEOF() /* Check for double end of file */cptr++ = NUL; ++cptr; endif /* Save the hash value */ fdesc->line[MAXLINES-amt].lhash=thash; endif fdele, lev; { struct fbuff *fdesc; /* Prints a specified line, prints 'EOF' on end of file */ fdesc=(file==0)*ùÍKÍžÃ+8ž½6OPÃ'Ã+ÃFÃŽÃrÃÃû Í– þ8Ê{ æÄ‚yæ0°Ãø Í2͵ Ãá^#V#å*~#foÉá^#å*~#foÉá^#V#å*nÉá^#å*ÿ Å!9ùDM!ãåÍT(ÑÍ�åÍ�åÍÑÑÍ´ ÍG*8++|µÂÓÍ©ÃÖÍÔ*K}·ÊáÍmÁÉMark of the Unicorn Linker foÃÆ÷’Âùè»ùÈøÉÇ»ù2úøÃ÷ùéÂý/ÃÆ÷›ùã¾øÆ–úcÂùãºù Û›÷ùêÂù ÈùãÉÅù Ç»ù2ÃÆ÷ùëÂø Ç»ù2ÃÆ÷ùì»ù ÈùãÉÅùÇ»ù2ÃÆ9KåÍâ#ÑÑÑ€ÍùÒ !  åÍÂ!Ñ*3Kë`is#rÍ�~#foë! s#rÍ�€ÿå*3K€å!9KåÍâ#ÑÑÑ*%KåÍ�Ñ"%K!9KåÍÖ"ÑÃx *%Kå"%Ká6Ãë!9ùëÁ"“!@"‘!"• ÍæÊžÍ!€ßF#x·Â±Ã~#±¯!ßb¯2r~#þ ÊÈ·Êþ"ÂÞ2rÃß+}|~#·ÊÅG:r·xÁÊþ"Âæ¯2r ~#foå`i^#Vr+së)Ñ~#foå! KåÍ€(ÑÑÃD ! ~#foåÍ�)Ñ~#foå!‹ åÍW)ÑÑí Í�|µÊ€ ! ~#foåÍ�)Ñ~#foå*H#"H+ÍkHåÍ€(ÑÑí nÉá^#V#åë ~#foÉá^#åë& ~#foÉ!È+É!È#É!Ø+É!Ø#É!ð+É!ø+ÉÈÉÈÉØÉØÉðÉøÉ}»À|ºÉëz¼À{½Éë|ºÀ}»Éë|ªòìzr BDS C, vsn. 2.1 Å!9ùDM{2 K{2 K{2K{2K{2K>2K!"H!"H!™å! KåÍ€(ÑÑ!"-KÍ�åÍ�åÍžÑÑÍÜ3"3KÍà3ü"5K͹ !"F! K÷’Âùã¸øªøÃùìÂý0Ç»ù2ÃÆ÷“›÷’Âùí»ù ÈùãÉÅùúøÃùëÂø Ç»ù2ÃÆ÷ùëÂø Ç»ù2ÃÆ÷œ÷œÆúd²ùãÃÆœ�ücÆúeœ÷’Âùã¸øÃùìÂýÉCM.CCCC.CCCCan't open C.CCC C.CCC: read error! Å!úÿ9ùDM`i¯w#wÍ�å*HÑÍúÒë !ô åÍ�ÍkHåÍóÑÑÍ�ÍkHå!9KåÍ"Ñ+w#þ Âæ+6#ÃÈÕ!×6#¯2w2x*sé!ÿÿÉ>õÍrÚ<o&åÍFáñ=þÂ-ÃÍ`Í ÍrÚ'~æÊhåÍÅÍëÍÁá6þÿ!À+ÉÍ`WÖØþ?ØÕ_! ~#foåÍ�)Ñ~#foå*H#"H+ÍkÚIåÍ€(ÑÑ`i^#Vr+sÃÛ*K}·ÊÎ !Hå! KåÍ€(ÑÑ* K}·ÊÜ !¡ Ãß !§ å*H#"H+ÍkÚIåÍ€(ÑÑ* K}·Ê ·ð7Éë|ªòó|·ð7ɯ2qÍZëÍZëÍ)z·ð|/g}/o#É|µÈÕå͉ÑÍk|/g}/o#Ñɯ2qÍZëÍZÍk:qÐ|/g}/o#É|·ð/g}/o#:q<2qÉÅÍqÁÉDM!x±ÈxGyOÒåÍJÑ!"8*-K"/K!"1KÁÉMAINÅ!üÿ9ùDMÍ�ÍùÒË!+ åÍT(Ñ!6 åÍT(Ñ!åÍï!Ñ! 6ÿ#6ÿ`i6#6Í�åÍ�ÑÍúÒ¹ ! ~#foåÍ�)Ñ~#fon1Ç»ù2ÃÆ÷’ÂùÃËë5DŠ4„ #?ë5??ë5@o6ͼ2)¼26TþÉ“D Øð bb“Š4Î“Ý ääë5 ?ë5ë5@o6ͼ2‘óÕ†ë5h†‡6Ñ|·ò! Í�ÍkHå!ø åÍW)ÑÑÃß Í�ÍkHå!åÍW)ÑÑÍ�|µÍ�åÍãÑF! s#rÍ�n}þ€Ê× Í�åÍJÑë! s#r! åͱ ÑÍ� n}!×~æ7ÑzÈ?ÉÍ`ÅÍ åþ:>ªÍÖ@w#ÍÆþ.¶ÍÆ66ÑÁÉÅþ*>?ÊéÍñÚçw#ÂÏÁÍñØÃÞ> w#ÂçÁÉÍþ.7Èþ:7Èþ7È!¬ à !³ å*H#"H+ÍkÚIåÍ€(ÑÑë!9ùëÁÉUsage is: l2 {program files} -l {library files} [-w] -L-W-WA-WS-M-m argumentƒë)ëÃv|µÈÅÍ”`iÁÉ|·ú )ÖëxõÍÝÚ·Õz/W{/_ѯzW{_ñ=ÈõyOxGæ¯2qÍZëÍZë͉ÃM|ºØÀ}»Éëȯ|g}oÃæëÈ)Ãô|/g}/o}þ-ÂG !d å! ~#foåÍ�)Ñ~#foåÍÈ(ÑÑ|µÂ4 ! ¯w#wÃD !g å! ~#foåÍ�)Ñ~#foåÍÈ(ÑÑ|µÂ_ >ÿ2KÃD !j å! ~#foåÍ�)Ñ~#foåÍÈ(ÑÑ|µÂÄ3óÜÕ†6DŠ4Š4ë5h‡6¸2ÁØ6 +ÁØÁØë5Tå ë5(ÂØë5Ñ1-"Æ(Î 7ÉÙ1ë5¨Éµµ�‚Q†OÀzÉ!@·Â¤ *7KåÍ�~#foÑûýåÍ�åÍÑÑÃÈ *8+++|µÊÈ !åÍT(ÑÍ�åÍT(Ñ!7åÍT(Ñ! ^#Vr+sÃQ !9KåÍÖ"Ñ`i^#Vr+sàë!9ùëÁÉCRLCan't opþ!ÉþaØþ{ÐÖ Éþ Ê þ Ê ÉÅÍ`·OÂE×!·æyÂ6ÁÉÕ$Ñ Â-7ÁÉÍrÚBÖo&))T])))ë!·yÁÉÕÅõå€ÍáñÁÑÉ missing. Unknown option: '%s' DEFFMDEFFDEFF2MDEFF2Å!üÿ9ùDM*3K"%K*K}·Âj * K}·ÊÝ !� Ãà !ˆ å!9KåÍ"ÑÑ|·ò÷ !Ž åÍÂ!Ñ!€å*3Kå!#Éz/W{/_É!9~#foÉ!à !à ! à ! à !à !à Ÿ!9Å~#ÂAÁÉá"s!`å*"³!è"µ!ÜY"—>Û2­>Ó2°>É2¯2²!Ì"�!� ÿ{2K{2KÃD !n å! ~#foåÍ�)Ñ~#foåÍÈ(ÑÑ|µÂ¿ ÿ{2K{2KÃD !r å! ~#foåÍ�)Ñ~#foåÍÈ(ÑÑ|µÂ& `i^#Vr+sÕÍ�ÑÍúÚÿ !u åÍÂ!Ñ!en %s << Loading %s >> Duplicate program function '', not linked. Å!þÿ9ùDM`i¯w#wÍ�å*HÑÍúÒyÍ�åÍ6Ñ`i^#Vr+sÃUÍ|µÊ«ad error! Å!üÿ9ùDM! åͱ Ñ! ^#Vr+së~#foë`is#r! åͱ ÑÍ�~#foåÍ�ÑÍúë! s#r!åÍ�å!9KåÍí"ÑÑÑ|·òø! åÍÂ!ÑÍ�åÍæKÑÍìÚ�!åÍÂ!Ñ*%K"7KÍ�å*7Kå!9KåÍâ#ÑÑÑåÍ�ÑÍìÒ½!&åÍÂ!ÑÁÉ ** Out of memory -- switching to disk mode ** Disk write error!¯w#w*F#"FÍ�Ãë!9ùëÁÉMAINÅ!þÿ9ùDMF`is#rÍ�n}þ€ÊaÍ�åÍ�åÍRÑÑ|µÂWÍ�Ãg`iåÍpÑÃ1!Ãgë!9ùëÁÉÅ!9ùDMÍ�åͱ ÐåÍÂ!Ñ!¿KåÍÖ"Ñ!åÍ�Ñë!9ùëÁÉ **** Beginning second disk pass **** COMOVLDisk write error! Å!ùÿ9ùDM!å!Få!9KåÍâ#ÑÑÑëás#r*8+++|µÊ*1KåÍ�Ñ"1K*8++|µÊ<Í� å*%KåÍ�åÍ4ÑÑÑ*%KåÍ� Ñ"%Kë!9ùëÁÉÅ!úÿ9ùDMÍ� +|µÂgÃAÍ� åÍ� Ñ+ë`is#rÍ�#~#!×åÍT(Ñ*HÍkÚIåÍå3Ñ*H#"H+åÍ6ÑÃy*%Kå*3KÑÍúå*/KÑ")K*'K|µÂÎ*)K"'Kë!9ùëÁÉEnter the name of a file to be searched: Ñë!9ùëÁÉ -- read error!Å!îÿ9ùDMÍ� 6*8+++|µÊ†*%Kå*3KÑÍúå*/KÑë! s#r*8+|µÂqÍ�åÍ� ~#foåÍ�ÑÑÍ� åÍ�ëá Module won't fit in memory at all! -- read error! Å!üÿ9ùDM!TåÍ�ÍkÚIåÍóÑÑÍ�ÍkÚIå!9KåÍ"ÑÑ|·òŽÍ�ÍkÚIÑÍ�^#Vr+sÁÉÅ!þÿ9ùDMÍ�|µÊËÍ�~#foë`is#rÍ�åÍ�ëás#rÍ�ë! s#r×ë!9ùëÁÉÅÍw*K}·Âð!\å!HåÍóÑÑÃý!`å!HåÍóÑÑ!HÍùÒ!ÖåÍÂ!Ñ*8+|µÂr! n}·Êr!å`iå!9KåÍâ#ÑÑÑ!å! å!9KåÍâ#ÑÑÑ!å!+Kå!9KåÍâ#ÑÑÑ`in}·ÊiÍ�"'KÃo!"'KÄ!å!å!9KåÍífoåÍ�ÑÍìÚ±Í�#å~#foåÍ�åÍ�ÑÍúÑëás#rÃAÍ�#~#foåÍ� Ñë! s#rÍ�n}þ*ÂåÍ�6!! ^#Vr+sÍ�#~#foë! s#rÍ�#åÍ�Å!üÿ9ùDM! ¯w#w`i¯w#wÍ�å*FÑÍúÒÍ� Ík8 n}·ÂsÍ�|µÂO!�åÍT(ÑÍ� Ík8åÍT(Ñ!§åÍT(Ñ! 6ÿ#6ÿ`i^#Vr+sÃÍs#rÚÍ� ~#foë! s#rÍ�åÍ�åÍ|)ÑÑ###ë! s#rÍ�åÍ�n}·ÊÊ!ÃÍ!ÑÕÍkÑë! s#rÍ�ë`is#rÍ�n}·Ê"Í�#åÍ�åÍJå!XåÍW)ÑÑÃKÍ�ÍkÚIå!gåÍW)ÑÑ!å!Få!9KåÍâ#ÑÑÑÍùÒÉ!{åÍÂ!Ñ`i¯w#wÍ�å*FÑÍúÒCÍ� Ík8 n}·Â7Í� Íkå!¿KåÍŠ"ÑÑ|µÍ�|·úB*%Kå*3KÑÍúå*3Kå!¿KåÍ&ÑÑÑ#|µÊB!¿KåÍã'Ñ|·òJ!dåÍÂ!Ñ!¿KåÍÖ"Ñ!åÍ�ÑÁÉCOMOVLDisk write error! Å!üÿ9ùDM*"ÑÑÑF! s#rÍ�n}þ€Ê¥! åÍpÑÃŽ! ^#Vr+sÍ�~#foûýë! s#rÍ�åÍæÑë!9ùëÁÉ-- read error! Å!9ùDM*8++|µÊ *%KåÍ� ~#foëás#rÍ� n}·ÂA*8+|µÂAÍ� åÍ�#åÍ�ÑÍúëás#rë!9ùëÁÉÅ!þÿ9ùDMÍ�n}þ�Âh!ë! s#r*F+ Ík8ë`is#rÍ��Æë!9ùëÁÉ*** Missing functions: Å!þÿ9ùDM`i¯w#wÍ�å*FÑÍúÒÿÍ� Ík8 n}þÂóÍ� Ík8 6`i^#Vr+s÷!Ñëás#r! ^#Vå!ëár+s`iåͱ ÑÃé`i^#Vr+sÍ�~#foë! s#rÍ�ë! s#rÍ�åÍ� Ñë`is#r`i^#Vr+së~#foë! s#rÍ�åÍ�ÑÍúë8åÍ!Ñë! s#rz³Ê7Í�åÍ‹Ñ*7KåÍ� Ík8åÍÑÑ`i^#Vr+sÃÏ!9KåÍÖ"Ñë!9ùëÁÉCRLCan't open %s << Scanning %s >> -- Re3Kë`is#r! KåÍJÑë! s#r*K}·ÂM* K}·ÂîÍ�6*Í�#6#6`i^#Vå!ëár+së6ù*3Kë`is#rÍ�#åÍ� ~#foëás#r*3Kë`is#r`i^#VÑå*5KÑÍìÚ�*8+|µÂ$!¿åÍT(Ñ!"8*8+++|µÂX*%Kå*3KÑÍúå*3Kå!¿KåÍ&ÑÑÑ#|µÂX!ïåÍÂ!Ñ*/Kå*%Kå*3KÑÍúÑ"/K*3K"%K*%KåÍ�Ñå*5å!8ÑÍìÚµÍ�åÍ�åÍRÑÑ|µÂ¢õ`i^#V{Ö _zÞWr+sÃ|Í�å!8ÑÍìÒ *F Ík8ë`is#rÍ�åÍ�åÍO ÑÑÍ�åÍÜ ÑÍ� 6Í� "8*-K"/K! åÍT(Ñ*K}·Â+!Èå!HåÍóÑÑÃ8!Ìå!HåÍóÑÑ!Hå!¿KåÍŠ"ÑÑ͹ ÍwÍ´ ÍG*%Kå*3KÑÍúå*3Kå!¿KåÍ&ÑÑÑ#|µÊ!¿KåÍã'Ñ|·ò‡!! s#rÍ�å*%KÑÍúë! s#r*8++|µÊî! ^#Vr+sz³ÊîÍ� åÍ�åÍ�åÍ�åÍ�å`i^#Vr+së~#foåÍRÑÑÑÑÑÑæ! å~#foåÍ�ÑÍúr+sÕ*'Këás#r`i^#Vr+s`i^#Vr+sÕ*)Këás#r`i^#Vr+sÕ*'Kå*+KÑëás#rÃdÍ�#åÍ� ~#foëás#rë!9ùëÁÉÅ!üÿ9ùDM!Uå! å*FåÍ� ÍÒ”!!7×!!0Ñëás#rÍ� åÍ�åÍf+ÑÑ`i^#Vr+sÃJ!ë!9ùëÁÉÅ!9ùDMÍ� åÍ�åÍ�åÍ�åÍW)ÑÑÑÑ!åÍï!ÑÁÉÅ!9ùDMÍ�+|µÂ P&€|¢g}£oåÍ�n}·Í�Ñ|²g}³o}2MP*LP&€|¢g}£oåÍ�n}·Í�Ñ|²g}³o}2NP*KP&|¢g}£o}2KPå*LP&|¢g}£o}2LPѯgWÍúÒú!ÿÿÁÉ*KPå*LrÍ�åÍ�ÑÃ&ë! 9ùëÁÉÅ!úÿ9ùDMÍ� Ã-&!ÿÿÃÚ'Í� ~#fo|µÊÒ&Í� ~#fo€ÍúåÍ�åÍ-(ÑÑë! s#rÍ�åÍ� åÍ� ~#foÑÉÅ!þÿ9ùDM!;åÍ�åÍg.ÑÑ*Få!OåÍ�åÍg.ÑÑÑ*)Kå!jåÍ�åÍg.ÑÑÑ*'Kå!€åÍ�åÍg.ÑÑÑ*'Kå*+KÑå!œåÍ�åÍg.ÑÑÑ*1Kå!¶åÍ�åÍg.ÑÑÑ*5Kë#fo€ÍúåÍ�åÍ-(ÑÑë`is#rÍ�åÍ�åÍ�åÍ�~#foÑåÍ4ÑÑÑ! å~#foåÍ�ÑÍúëás#rÍ�å~#foåÍ�Ñëás#r! å~#foåÍ�å!8å͹)ÑÑÑÑ!å!HåÍóÑÑ!ELå!HåÍ+ÑÑ|·ò³!åÍÂ!Ñ`i¯w#wÍ�å*FÑÍúÒr!ELåÍ� Ík8 ~#foåÍ;!ÑÑ!ELå! åÍf+ÑÑ!ELåÍ� "!"åÍc4Ñ!åÍx4ÑÁÉa:$$$.subÅ!9ùDMÍ�å!åÍ�åÍœ4ÑÑëás#rÍ�~#fo#|µÂP"!ÿÿÁÉ!åÍ�åÍ�~#foåÍà4ÑÑÑÍ�##¯w#wÍ�¯wPѯgWÍÚ *NP}·Ê *MP}·Â !ÁÉ*MP}·Ê5 *NP}·Â5 !ÿÿÁÉ*MP}·ÊJ *NP}·ÊJ !ÁÉÃZÁÉÅ!9ùDMÍ�åÍ�nëásÍ�#n}·Â† Í�ån&€|²g}³oåÍ� åÍ4ÑÑÑÍ� å~#foåÍ�Ñëás#r! å~#foåÍ�ÑÍúëás#r! å~#foåÍ�Ñëás#rÍ� ~#fo€ÍåÂ+'Í� ##^#Vr+sÍ� ¯w#w`is#r*8+|µÂ2Í�å*%KÑÍúë͉å!ÖåÍ�åÍg.ÑÑÑë!9ùëÁÉ Link statistics: Number of functions: %d Code ends at: 0x%x Ñëás#rÍ�€ë͉ë! s#rÍ�|µÊ0%Í�åÍ�åÍ�~#foåÍà4ÑÑÑë! s#rÍ�#|µÂ×$Í�Ã&Í�##å~#foåÍ�Ñëás#rÍ�åÍ�ÑÍúÒ%Í�Ík8åÍ—,ÑÑÍ�ëÍ+++|µÂ0!ELå!5åÍ—,ÑÑÃfÍ� Ík8åÍ|)ÑÍùÒY!ELå! åÍf+ÑÑ!ELå! åÍf+ÑÑ`i^#Vr+sùÍ�ëÍ|µÊ#wÍ�ÁÉÁÉÅ!9ùDMÍ�åÍ�åÍV5Ñëás#rÍ�~#fo#|µÂ¸"!ÿÿÁÉÍ�##¯w#wÍ�¯w#wÍ�ÁÉÁÉÅ!9ùDMÍ�~#foåÍ~5ÑÁÉÅ!þÿ9ùDMÍ�Ã#!ÿÿÃëásï ! ^#Vr+s! ^#Vr+sën&€|¢g}£o|µÊW ÁÉÅ!9ùDMÍ�^#Vr+sën&€|¢g}£o|µÂÚ Ã¹ ÁÉÅ!9ùDMÍ�n&€|¢g}£o|µÂ!Í�n}·!åÍ� åÍ� ~#foåÍæ5ÑÑÑÍùÒ+'!ÿÿÃÚ'Í�€ë͉ë! s#rÍ�|µÊr'Í�åÍ� åÍ� ~#foåÍæ5ÑÑÑåÍ�ÑÍìÒr'!ÿÿÃÚ'! å~#fo€ëÍ Externals begin at: 0x%x Externals end at: 0x%x Jump table bytes saved: 0x%x Link space remaining: %dK Å!9ùDMÍ�nåÍ�€Í?ÑÃ&! å~#foåÍ�€Í?Ñëás#rÃ8%! ¯w#wÍ�~#fo€Íå¼%!åÍ�åÍ�~#foåÍà4ÑÑÑë! s#rÍ�#|µÂ‚%Í�Ã�!ELå!7åÍ—,ÑÑ*K}·ÊŸ!ELåÍ�Ñ!ELå!åÍf+ÑÑ!ELåÍû,Ñ!ELåÍ<.Ñ*K}·Ê!9å!HåÍóÑÑ!ELå!HåÍ+ÑÑ|·òë!=åÍÂ!Ñ!ELåÍ�Ñ!ELå!åÍf+ÑÑÙ#Í� +|µÂ<#! å~#foåÍ�##~#fo€Í?åÍ�~#foÑÑëás#rÍ�€ë͉ë`is#rÍ�åÍ�##~#foÑÍåÊ©#!åÍ�åÍ�~#foåÍ�5ÑÑÑ#|µÊ£Â!ÁÉ! ^#Vr+sÃä Í�åÍ�n&|¢g}£oëás! ^#Vr+së6ÁÉÅ!üÿ9ùDM`i6#6Í�|·ú¹!Í�åÍ�Í?ÑÍä|¢g}£oë! s#r! å~#fo)ëás#rÍ�åÍ� åÍ� åÍ�€ÍkÑåÍ4ÑÑÑÍ� å~#foåÍ�Ñëás#rÍ�€ÍkåÍ�ÑÃÚ'ë!9ùëÁÉÅ!9ùDMÍ�~#fo|µÊ&(!å}·Ê2Í�n}þ.Ê2Í�åÍ�n&åÍ•.Ñëás! ^#Vr+sÃû! ^#Vr+së6.Í�åÍ�åÍ€(ÑÑÁÉÅ!9ùDM! ^#Vr+sën}2KP! ^#Vr+sën}2LP*K&Í�##^#Vr+sÍ�¯w#wÍ�ÍùÒ¼%Í�åÍ�€Í?ÑÃ&Í�€ëÍ)ë! s#rÍ�åÍ�åÍ�åÍ4ÑÑÑÍ�å~#foåÍ�Ñëás#!ELåÍû,Ñ!ELåÍ<.Ñë!9ùëÁÉSYMCan't create .SYM file LNKCan't create .LNK file Å!9ùDMÍ� ~#foåÍ� ~#foÑÍóÍ©ÁÉÁ#!åÍ�åÍ�~#foåÍà4ÑÑÑ#|µÂ©#!ÿÿÃÙ#Í�åÍ�€ëÍ)ëás#rÍ�##åÍ�ëás#rÍ�ÃÙ#ë!9ùëÁÉÅ!öÿ9ùDMÍ�Ã÷#!ÿÿÃ&Í�~Í�åÍ�~#foåÍæ5ÑÑÑÍùÒ&(!ÿÿÁÉ!ÁÉÁÉÅ!9ùDMÍ�åÍ�ÑÍìÒL(Í�ÃP(Í�ÁÉÁÉÅ!9ùDMÍ�n}·Ê~(! ^#Vr+sën&åÍN6ÑÃ\(ÁÉå`iåÍ—,ÑÑÃŒ.ë!‡9ùëÁÉÅ!9ùDM! n&åÍ}2Ñ|µÊ¼.! n&àÿÃÁ.! n&ÁÉÁÉÅ!hÿ9ùDM!ž ^#Vr+së~#foë! s#rÍ�žë!– s#r! ^#Vr+#Vr+sÕ! nëásë&ÁÉÁÉÅ!ÿÿ9ùDM! ^#Vr+sënë`is{·Êì,`in}þ ÂÍ,Í�å! åÍf+ÑÑÍ�å`in&åÍf+ÑÑ#|µÂé,!ÿÿÃò,ß,!Ãò,ë!9ùëÁÉÅ!þÿ9åÍ�åÍ� Ñ͉åÍ�åͬ2ÑÑÑë`isÍ� åÍ�åÍ� ÑÍ)åÍ�åͬ2ÑÑÑ`in&#&ÃG3ë!9ùëÁÉÅ!9ùDM! n&0ÍùͯÚ{3! n&9ÍͯÁÉÁÉÅÑå!�*å!9~#foéÑÑÑÍÚŸ*ÃÝ*Í� åÍ�ÑåÍ�åÍ�ÑåÍ�åÍ'2ÑÑÑ! å~#foåÍ�ÑÍúëás#rÃ]*`iå~#foåÍ�Ñëás#rÃ7*! å~#foë1!� ^#Vr+sÕ! ^#Vr+sënëás!” ^#Vr+s!’ ^#Vr+sÃî0Í��6! ë!� s#r!� n}·Â�1!’ ^#Vr+s!ÍÒ�1!œ ^#Vr+sÕ!‘ n}·Ê†1Å!þÿ9ùDMÍ�ë`is#r! ^#Vr+sÕ! ^#Vr+sënëás{·Ê¸(Ã’(Í�ÿ(ë!9ùëÁÉÅ!þÿ9ùDM`i¯w#w! ~#foåÍ�Ñnå! ~#foåÍ�ÑnÑ}»Â")!sënë`is{·Ê2`in}þ%Â2! ë!� s#r!” 6#6!‘ s!� s!� sÍ�n}þ-ÂW/! ^#Vr+s!� 4Í�n}þ0Âg/!‘ 4Í�n&åÍP3Ñ}·Ê„/! åÍ3ùDMÍ�ÍëÒ-!Ã3.Í�##~#foÍåÂ/-!Ã3.Í�##~#fo€ëÍËÍúë`is#rÍ�åÍ�åÍ�~#foåÍæ5ÑÑÑåÍ�ÑÍåÊ|-!ÿÿÃ3.Í�!þÿ9ùDM`i¯w#wÍ�~#fon&åÍP3Ñ}·ÊÌ3Í� Í?åÍ�^#Vr+sënѯgÐÿë`is#rÃ�3Í�ÃÓ3ë!9ùëÁÉ*É*+ÉÍ Å6ÿ ëÕÕÕÍ Íá#F#Ñ͉ëás#rÃé)ë!9ùëÁÉÅ!9ùDMÍ�åÍ�åÍV5Ñëás#rz·ò9+!ÿÿÁÉÍ�åÍ�ëás#rÍ�##6#6Í�~#foÁÉÁÉÅ!9ùDMÍ�+|µÂ†+! n&åhorizontal pitch */ int hpitch; { if (hpitch == drvhpitch) return; OPutSeq (ESC, ']', hpitch + '@', ENDLIST); drvhpitch ~#foå`i^#Vr+sëÑn}·Â)!ÃN)ÃÖ(! ~#foåÍ�Ñnå! ~#foåÍ�ÑnѯgWÍúÃN)ë!9ùëÁÉÅ!yÿ9ùDM!‹ å`iåÍÇ.ÑÑ`iåÍT(Ñë!‡9ùëÁÉÅ!þÿÑÇ/!ë!’ s#r! ^#Vr+sënë`is{þ.ÂÏ/! åÍ3Ñë!” s#r!� 4! ^#Vr+sënë`is`in&åÍ•.Ñ}þDÊû/þUÊ70þXÊ@0þOÊI0þCÊ�0þSÊÀ0Ãì1Í�–~+€Í?ë`is#rÍ�##~#fo|µÊ .!€åÍ�åÍ�åÍ�ÑåÍ4ÑÑÑÍ�##å~#foåÍ�Ñëás#rÍ�å~#foåÍ�ÑÍúëás#r!å!ÿÿåÍ�~#x·Ê 4~#Ã4¯áÁÉÍ7*£|µÈÅDM*¡ë*ŸÍ]4ÚA4><ê54í°ÁÉ~# x±Â54ÁÉ ë ë><êQ4í¸ÁÉ~+ x±ÂQ4ÁÉ|ºÀ}»ÉÍ Åë!\Í&Í!ÁÉÍ7Å*+ÍN6ÑÁÉÍ�++|µÂ¤+! n&å!åÍ„6ÑÑÁÉÍ�+++|µÂÃ+! n&å!åÍ„6ÑÑÁÉÍ�++++|µÂû+! n}þ Âè+! å!åÍ„6ÑÑ! n&å!åÍ„6ÑÑÁÉÍ�#2!œ ^#Vr+sÕ`inëásÃö.Í�œ6ë!˜9ùëÁÉÅ!ÿÿ9ùDM! ^#Vr+sz³Êt2Í�në`is! ^#Vr+sÕÍ� nëás! ^#Vr+sÕ`inëásÃ/2ë!9ùëÁÉÅ!9ùDM`i¯w#w! ^#Vr+sën}·Ê©)`i^#Vr+sÊ)Í�ð)ë!9ùëÁÉÅ!òÿ9ùDMÍ�åÍ�ÑÍkë! s#rÍ�ë͉ë! s#rÍ�|µÊ +Í�åÍ�ÑÍkë#fo|·ò70!� ^#Vr+së6-Í�–åÍ�–~#foÍúëás#r!’ ^#Vr+s! 6 ÃO0! 6ÃO0! 6!’ å~#foå! n&å!– ^#Vr+së~#foå!� åͬ2ÑÑÑfoåÍ�5ÑÑÑÃ3.Í�##6#6Í�åÍ�ëás#r!Ã3.ë!9ùëÁÉÅ!9ùDMÍ�ÍëÒV.!ÁÉÍ�~#foåÍ~5ÑÁÉÁÉÅ!yÿ9ùDM!� å`iåÍÇ.ÑÑÍ�‹++:ŸG‡€_å*¡DM!—4ãéo&ÁÉÍ7¯Í,Ú2që*ŸëÅÍ&ÍþÿÁÊ:qÍ):¡·ÊØ4=ÊØ4=Âr:qo&ÉÍ7:ŸÍ)Ú~æÊÅ:ŸÍ,"s!"#^#Vr+sz³Ê,,Í�^#Vr+sÕ! nëásë&ÁÉ!åÍ�åÍ�~#foåÍæ5ÑÑÑÍåÊV,!ÿÿÁÉÍ�##6ÿ#6Í�åÍ�ëás#rÍ�^9ùDM! n&aÍùͯÚ¨2! n&zÍͯÁÉÁÉÅ!ÿÿ9ùDMÍ�åÍ� ÑÍìÒü2Í�^#Vr+sÕÍ� ÍëÒé2Í�0Ãñ2Í�7ëás!&ÃG3Í� ! s#rÍ�åÍ�Ñë! s#rÍ�åÍ�Ñë! s#rÍ� ë`is#rÍ�åÍ�ÑÍóÚó*Í�åÍ� ÑÍúë! s#rÍ�|·úÝ*Í�åÍ� åÍ�ÑåÍ�åÍ�ѯgÍúëás#rÃ81!� ^#Vr+sÕ!– ^#Vr+së~#foëás!’ ^#Vr+sÃ81!� n}·ÂÓ0!” 6È#6!– ^#Vr+së~#foë! s#rÍ�n}·Ê81Í�”|µÊ8u*£|µÊ65*¡ëÍ*sëÕÍÑþÁÊÅþÂ;5! ~þ€Â656*uÁÉ*£+"£*¡€"¡*u#"uÃ5Í7*ŸÅåÍc4Ñ\ÍþÿÁÊ!å*ŸåÍœ4ÑÑÉÃ# this only slightly confuses SID. [81.4.27] "-wa" appends link stats to the .sym file; "-ws" inker for BDS C CRL format. It eliminates the jump table at the beginning of each function in the object code, thus saving upor MARC cross-linker version */*/ #include "bdscio.h" /* for i/o buffer defs */ #define NUL 0 #define FLAG char #dååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååut -m after the -ovl), and replaces c.ccc with a jump to that function. Also note tÍ7:ŸÍ,ÚÅå*ŸåÍ—6Ñë:£*¡·Ê£5}|æ2qã å¾ÊÔ5ãëÕÍÑáþÿÂÊ5ÑÁÃ:qwÕÍÑþÿÊÅ5! Ñ{æwëÁÉÍ7:ŸÍ)Ú~æÊÅ:ŸÍ," writes them to a separate file; "-w" does neither. "Version 2.1" message. [81.4.27] Overlay capabi to 10% or so in code space with a slight improvement in speed. [81.4.13] Switches automatically to two-pass, windowing efine repeat while (1) #define STDOUT 1 /* Phase control */ #define INMEM 1 /* while everything still fits */ #definååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååhat the base symbols are loaded at the very beginning, so name conflicts are always s!"u€Í*£|µ*uÊL6*¡€€~#Â#6"¡*sëÍ·*uÂL6#"u*£+"£Ã6ÁÉÍ Åþ Âh6 Í ÍÃl6_Í ÍæÂx6ÁÉÍþÊlity now exists. It works a bit differently from CLINK: the option -ovl link if it runs out of memory. [81.4.13] Symbol table is now in the order that the e DISK1 2 /* overflow; finish building table */ #define DISK2 3 /* use table to do window link */ int phase; /* functååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååresolved in favor of the base. */ /**************** Globals ****************/ /* #define SDOS ÁÉÍ7Å:ŸO*¡ëÍo`ÁÉÍ Í,ÚÅ FN¯xg>G�oy ò»6$ÁÉsub’Âù“Ã÷÷›÷÷÷÷ù–»ùÈù“ÉÇý%ÃÆ÷’Âù—»ù0ÇùÈù“ÉúøÃ›÷ù˜ causes symbols to be read from .sym and produces a segment linked at . It functions occur in memory; this seems more useful. Also, link stats are added on the end; ion table */ struct funct { char fname[9]; FLAG flinkedp; /* in memory already? */ char *faddr; /* address of first r/* L2.C New linker for BDS C Written 1980 by Scott W. Layson This code is in the public domain. This is an improved l /* comment this out for CP/M */*/ /* #define OVERLAYS /* comment this out for shorter version */*/ /* #define MARC /* fåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå also defaults the name of the overlay function to that of the first .crl file (to override, pef link if not linked */ } ftab [300]; int nfuncts; /* no. of functions in table */ #define LINKED 1 /* (flinkedp) ff next char in buffer */ char buff [128]; } ibuf, obuf; /* BDS C i/o buffer */ char symbuf[BUFSIZ]; /* seek opcodes *t of externals */ union ptr acodend; /* actual code-end address */ unsigned extspc; /* size of externals */ unsigned origfunct); phase = INMEM; buforg = origin; jtsaved = 0; } cmdline (argc, argv) /* process command line */ int argc;ses CM.CCC */ char mainfunct[10]; FLAG ovlp; /* make overlay? */ char symsfile [15]; /* file to load symbols from (for oprog(); linklibs(); if (phase == DISK1) rescan(); else wrtcom(); if (symsp) wrtsyms(); } setup (argc, argv) /* unction really here */ #define EXTERNAL 2 /* function defined in separate symbol table */ char fdir [512]; /* CRL file fu/ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define TRUE (-1) #define FALSE 0 #define NULL 0 /* 8080 inin; /* origin of code */ unsigned buforg; /* origin of code buffer */ unsigned jtsaved; /* bytes of jump table saved */ char **argv; { int i, progp; if (argc < 1) { puts ("Usage is:\n"); puts (" l2 {program files} -l {library filesverlays) */ /* useful things to have defined */ struct inst { char opcode; char *address; }; union ptr { unsignedinitialize function table, etc. */ int argc; char **argv; { symsp = appstatsp = sepstatsp = maxmemp = marcp = FALSE; ovnction directory */ /* command line parameters etc. */ int nprogs, nlibs; char progfiles [30] [15]; /* program file names *structions */ #define LHLD 0x2A #define LXIH 0x21 #define SPHL 0xF9 #define JMP 0xC3 #define CALL 0xCD /* strcmp7 local char *lspace; /* space to link in */ char *lspcend; /* end of link area */ char *lodstart; /* beginning of current } [-w]\n"); exit (1); } progp = TRUE; for (i=1; i < argc; ++i) { if (argv[i][0] == '-') { if (!strcmp (argv[i], u; /* an int */ unsigned *w; /* a word ptr */ char *b; /* a byte ptr */ struct inst *i; /* an instruction ptr */ lp = FALSE; nprogs = 0; nlibs = 0; strcpy (&mainfunct, "MAIN"); origin = 0x100; cmdline (argc, argv); lspace = endex/ char libfiles [20] [15]; /* library file names */ FLAG symsp, /* write symbols to .sym file? */ appstatsp, /* appends, made global for speed */ char _c1, _c2, _end1, _end2; /**************** End of Globals ****************/ main (argfile */ /* i/o buffer */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index o "-L")) progp = FALSE; else if (!strcmp (argv[i], "-W")) symsp = TRUE; else if (!strcmp (argv[i], "-WA")) symsp = appsta }; /* Link control variables */ union ptr codend; /* last used byte of code buffer + 1 */ union ptr exts; /* start(); lspcend = topofmem() - 1024; loadccc(); nfuncts = 0; #ifdef OVERLAYS if (ovlp) loadsyms(); #endif intern (&main stats to .sym file? */ sepstatsp; /* write stats to .lnk file? */ FLAG maxmemp, /* punt MARC shell? */ marcp; /* uc, argv) int argc; char **argv; { puts ("Mark of the Unicorn Linker for BDS C, vsn. 2.1\n"); setup (argc, argv); linktsp = TRUE; else if (!strcmp (argv[i], "-WS")) symsp = sepstatsp = TRUE; else if (!strcmp (argv[i], "-M")) { if (++open %s\n", progfiles[i]); continue; } printf ("\n<< Loading %s >>\n", &progfiles[i]); readprog (i==0); for (di128) < 128) /* read a sector */ Fatal ("C.CCC: read error!\n"); temp.b = lspace + 0x17; len = *temp.w; /* how lonfname); puts ("\n"); foundp = TRUE; } return (foundp); } rescan() /* perform second disk phase */ { strcpy (&progfiles[nprogs++], argv[i]); else strcpy (&libfiles[nlibs++], argv[i]); } } if (ovlp) strcpy (&mainfunctfile= argc) Fatal ("-m argument missing.\n"); strcpy (&mainfunct, argv[++i]); } #ifdef OVERLAYS else if (!strcmp (rtmp.b=&fdir; *dirtmp.b != 0x80;) { fnct = intern (dirtmp.b); /* for each module */ skip7 (&dirtmp); /* in directog is it? */ cread (&ibuf, lspace + 128, len - 128); /* read rest */ codend.b += len; cclose (&ibuf); } else codendint i; for (i=0; i < nfuncts; ++i) if (ftab[i].flinkedp == LINKED) ftab[i].flinkedp = FALSE; phase = DISK2; buforg =, &progfiles[0]); strcpy (&libfiles[nlibs++], marcp ? "DEFFM" : "DEFF"); strcpy (&libfiles[nlibs++], marcp ? "DEFF2M" : "DEFbfiles[nlibs]); scanlib (nlibs++); } acodend.b = codend.b - lspace + buforg; /* save that number! */ if (!exts.b) extargv[i], "-OVL")) { ovlp = TRUE; if (i + 2 >= argc) Fatal ("-ovl argument missing.\n"); strcpy (&symsfile, argv[+ry */ if (!fnct->flinkedp) linkmod (fnct, lodstart + *dirtmp.w - 0x205); else if (phase != DISK2) { puts ("Dup.i++->opcode = JMP; } linkprog() /* link in all program files */ { int i; union ptr dirtmp; struct funct *fnct; origin; puts ("\n\n**** Beginning second disk pass ****\n"); if (!ovlp) makeext (&progfiles[0], "COM"); else makeext (&prF2"); } loadccc() /* load C.CCC (runtime library) */ { union ptr temp; unsigned len; codend.b = lspace; ifs.b = acodend.b; } missingp() /* are any functions missing? print them out */ { int i, foundp; foundp = FALSE;+i]); sscanf (argv[++i], "%x", &origin); } #endif #ifdef MARC else if (!strcmp (argv[i], "-MARC")) { maxmemlicate program function '"); puts (&fnct->fname); puts ("', not linked.\n"); } dirtmp.w++; } /* in for (i=0; i= lspcend) Fatal ("Module won't fit in memory at all!\n">faddr = finalloc.b; } else finalloc.b = fnct->faddr; body.b = modstart.b + strlen(modstart.b) + 3; /* loc. of function dir.b=&fdir; *dir.b != 0x80; nextd (&dir)); /* find end of dir */ ++dir.b; len = *dir.w - 0x205; readobj (len); } rt) /* link in a module */ struct funct *fnct; union ptr modstart; /* loc. of module in memory */ { union ptr temp; } readprog (mainp) /* read in a program file */ FLAG mainp; { char extp; /* was -e used? */ char *extsnctions */ if (!ftab[i].flinkedp && (dirtmp.b = dirsearch (&ftab[i].fname))) { readfunct (dirtmp.b); linkmod (); } lodstart = codend.b; if (cread (&ibuf, lodstart, len) < len) Fatal ("-- read error!\n"); } scanlib (ifile) body */ jump.i = body.i + (*modstart.b ? 1 : 0); for (temp.b = modstart.b; *temp.b; skip7(&temp)) { jump.i->address = inteadobj (len) /* read in an object (program or lib funct) */ unsigned len; { if (phase == DISK1 || codend.b + len >= ls, jump, /* jump table temp */ body, /* loc. of function in memory */ code, /* loc. of code proper in memtmp; union ptr dir; unsigned len; if (cread (&ibuf, &fdir, 512) < 512) /* read directory */ Fatal ("-- read error!\&ftab[i], lodstart); } } cclose (&ibuf); } readfunct (direntry) /* read a function (from a library) */ unionint ifile; { int i; union ptr dirtmp; makeext (&libfiles[ifile], "CRL"); if (copen (&ibuf, libfiles[ifile]) < 0) { ern (temp.b); ++jump.i; } ++temp.b; flen = *temp.w; code.b = jump.b; temp.b = body.b + flen; /* loc. of reloc ppcend) { if (phase == INMEM) { puts ("\n** Out of memory -- switching to disk mode **\n"); phase = DISK1; } if. */ finalloc; /* runtime loc. of function */ unsigned flen, nrelocs, jtsiz, offset; fnct->flinkedp = LINKED; ifn"); if (phase == INMEM && mainp) { cread (&ibuf, &extp, 1); cread (&ibuf, &extstmp, 2); cread (&ibuf, &extspc, 2); ptr direntry; { unsigned start, len; skip7 (&direntry); start = *direntry.w++; skip7 (&direntry); len = *direntry. printf ("Can't open %s\n", libfiles[ifile]); return; } printf ("\n<< Scanning %s >>\n", &libfiles[ifile]); if (cread arameters */ nrelocs = *temp.w++; jtsiz = code.b - body.b; offset = code.b - codend.b; if (phase != DISK1) while (nre (phase == DISK2) { if (cwrite (&obuf, lspace, codend.b - lspace) == -1) Fatal ("Disk write error!\n"); } buforg (phase != DISK2) { finalloc.b = codend.b - lspace + buforg; if (phase == INMEM) chase (fnct->faddr, finalloc.b); fnct- if (extp) exts.b = extstmp; else exts.b = 0; /* will be set later */ } else cseek (&ibuf, 5, RELATIVE); for (w - start; if (cseek (&ibuf, start, ABSOLUTE) < 0) Fatal (" -- read error!"); readobj (len); } linkmod (fnct, modstarlocs--) relocate (*temp.w++, body.b, jtsiz, finalloc.b, offset, flen); flen -= jtsiz; if (phase != DISK2) jtsaved(ptrp) /* move this pointer to the next dir entry */ union ptr *ptrp; { skip7 (ptrp); ++(*ptrp).w; } chase (heab[nfuncts-1]; fptr >= ftab; --fptr) if (!strcmp7 (name, fptr->fname)) break; if (fptr < ftab) { fptr = &ftab[nfuncts]; ++ = exts.u + extspc; } else temp.i->address = fptr->faddr; /* that's a JMP */ #ifdef MARC if (maxmemp) { temp.b = lla case */ else { ref.b = instr.i->address + body.u; if (instr.i->opcode == LHLD) { instr.i->opcode = LXIH; --ren"); cclose (&obuf); stats (STDOUT); } hackccc() /* store various goodies in C.CCC code */ { union ptr temp; += jtsiz; if (phase != DISK1) movmem (code.b, codend.b, flen); codend.b += flen; } relocate (param, body, jtsiz, basd, loc) /* chase chain of refs to function */ union ptr head; unsigned loc; { union ptr temp; while (head.w) { t strcpy7 (fptr->fname, name); str7tont (fptr->fname); fptr->flinkedp = FALSE; fptr->faddr = NULL; ++nfuncts; } space + 0x258; temp.i->opcode = CALL; temp.i->address = 0x50; } #endif } wrtsyms() /* write out symbol tablf.b; } fnct = ref.i->address; instr.i->address = fnct->faddr; /* link in */ if (!fnct->flinkedp && phase == INME struct funct *fptr; temp.b = lspace; fptr = intern (&mainfunct); if (!ovlp) { if (!marcp) { temp.i->opcode = LHLe, offset, flen) /* do a relocation!! */ unsigned param, jtsiz, base, offset, flen; union ptr body; { union ptr instr, emp.w = *head.w; *head.w = loc; head.u = temp.u; } } wrtcom() /* write out com file (from in-mem link) */ { return (fptr); } dirsearch (name) /* search directory for a function */ char *name; { union ptr temp; for (te */ { int i, fd, compar(); qsort (&ftab, nfuncts, sizeof(*ftab), &compar); makeext (&progfiles[0], "SYM"); if (fcreM) fnct->faddr = instr.b + 1 - offset; /* new list head */ } } intern (name) /* intern a function name in the tD; temp.i->address = 6; (++temp.i)->opcode = SPHL; temp.b = lspace + 0xF; /* main function address */ temp.i-> /* instruction involved */ ref; /* jump table link */ struct funct *fnct; if (param == 1) return; /* don't r hackccc(); if (!ovlp) makeext (&progfiles[0], "COM"); else makeext (&progfiles[0], "OVL"); if (!ccreat (&obuf, &progfilemp.b = &fdir; *temp.b != 0x80; nextd (&temp)) if (!strcmp7 (name, temp.b)) return (temp.b); return (NULL); } nextd at (&progfiles[0], &symbuf) < 0) Fatal ("Can't create .SYM file\n"); for (i=0; i < nfuncts; ++i) { puthex (ftab[i].faddrable */ char *name; { struct funct *fptr; if (*name == 0x9D) name = "MAIN"; /* Why, Leor, WHY??? */ for (fptr = &ftaaddress = fptr->faddr; } temp.b = lspace + 0x15; *temp.w++ = exts.u; ++temp.w; *temp.w++ = acodend.u; *temp.weloc jt skip */ instr.b = body.b + param - 1; if (instr.i->address >= jtsiz) instr.i->address += base - jtsiz; /* vaniles[0]) < 0 || cwrite (&obuf, lspace, codend.b - lspace) == -1 || cflush (&obuf) < 0) Fatal ("Disk write error!\, &symbuf); putc (' ', &symbuf); fputs (&ftab[i].fname, &symbuf); if (i % 4 == 3) fputs ("\n", &symbuf); else { Link statistics:\n"); fprintf (chan, " Number of functions: %d\n", nfuncts); fprintf (chan, " Code ends at: 0x%x\n", acode"%x%s\t%x%s\t%x%s\t%x%s\n", &(ftab[nfuncts].faddr), &(ftab[nfuncts].fname), &(ftab[nfuncts+1].faddr), &(ftab[nfunc (_end1 && _end2) return (0); } } strcpy7 (s1, s2) /* copy s2 into s1 */ char *s1, *s2; { do { *s1 = *s2; ble entries by name */ struct funct *f1, *f2; { /* return (strcmp (&f1->fname, &f2->fname)); alphabetical order */ return } *fname++ = '.'; strcpy (fname, ext); } strcmp7 (s1, s2) /* compare two bit-7-terminated strings */ char *s1,if (strlen (&ftab[i].fname) < 3) putc ('\t', &symbuf); putc ('\t', &symbuf); } } if (i % 4) fputs ("\n", &symbuf); nd.u); fprintf (chan, " Externals begin at: 0x%x\n", exts.u); fprintf (chan, " Externals end at: 0x%x\n", exts.u + extspc)ts+1].fname), &(ftab[nfuncts+2].faddr), &(ftab[nfuncts+2].fname), &(ftab[nfuncts+3].faddr), &(ftab[nfuncts+3].fnam if (!*(s2+1)) { /* works even if */ *s1 |= 0x80; /* s2 is null-term */ break; } ++s1; } while (!(*s2+(f1->faddr > f2->faddr); /* memory order */ } #ifdef OVERLAYS loadsyms() /* load base symbol table (for overlay) */ *s2; /* also works for non-null NUL-term strings */ { /* char c1, c2, end1, end2; (These are now global for speed) */ if (appstatsp) stats (&symbuf); putc (CPMEOF, &symbuf); fflush (&symbuf); fclose (&symbuf); if (sepstatsp) { makee; fprintf (chan, " Jump table bytes saved: 0x%x\n", jtsaved); temp = lspcend; if (phase == INMEM) fprintf (chan, e)); nread /= 2; if (nread < 4) done = TRUE; while (nread-- > 0) ftab[nfuncts++].flinkedp = EXTERNAL; } fclose (&s+ & 0x80)); } skip7 (ptr7) /* move this pointer past a string */ char **ptr7; { while (!(*(*ptr7)++ & 0x80)); } { /* symbol table must be empty! */ int nread; FLAG done; char *c; makeext (&symsfile, "SYM"); if (fopen (&srepeat { _c1 = *s1++; _c2 = *s2++; _end1 = (_c1 & 0x80) | !*s1; _end2 = (_c2 & 0x80) | !*s2; if ((_c1 &= 0x7F) _c2 || (_end2 && !_end1)) return (1); if (_end1 && !_end2) return (-1); if); putc (CPMEOF, &symbuf); fflush (&symbuf); fclose (&symbuf); } } compar (f1, f2) /* compare two symbol ta/ char *fname, *ext; { while (*fname && (*fname != '.')) { *fname = toupper (*fname); /* upcase as well */ ++fname; s++; } *s = *s & 0x7F; *++s = NUL; } puthex (n, obuf) /* output a hex word, with leading 0s */ unsigned n; nes deal with reading and writing large blocks of characters, when they do not fit neatly in sectors. At the moment, only seqååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååaracter (input only!) */ struct iobuf *buf; unsigned nbytes, code; { int newsect; if (buf < 0) return (-1); if (codEND OF L2.C */ { /* works even if */ *s1 |= 0x80; /* s2 is null-term */ break; } ++s1; } while (!(*s2+en (fname, INPUT); if (buf->fd == -1) return (-1); read (buf->fd, &buf->buff, 1); buf->isect = 0; buf->nextc = 0; retu char *obuf; { int i, nyb; for (i = 3; i >= 0; --i) { nyb = (n >> (i * 4)) & 0xF; nyb += (nyb > 9) ? 'A' - 10 : 'uential output is supported; input is fully random. */ #define TRUE (-1) #define FALSE 0 #define NULL 0 /* i/o buffeååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååe == RELATIVE) nbytes += buf->isect * 128 + buf->nextc; newsect = nbytes / 128; if (newsect != buf->isect && (seek (buåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååårn (buf); } ccreat (buf, fname) /* create a file for char output */ struct iobuf *buf; char *fname; { buf->fd = 0'; putc (nyb, obuf); } } Fatal (arg1, arg2, arg3, arg4) /* lose, lose */ char *arg1, *arg2, *arg3, *arg4; { pr */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index of next char in buffer */ ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååf->fd, newsect, ABSOLUTE) == -1 || read (buf->fd, &buf->buff, 1) == -1)) return (-1); buf->nextc = nbytes % 128; buf->ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååcreat (fname); if (buf->fd == -1) return (-1); buf->isect = 0; buf->nextc = 0; return (buf); } cclose (buf) /*rintf (arg1, arg2, arg3, arg4); exit (1); } exit (status) /* exit the program */ int status; { if (status == 1) char buff [128]; }; /* seek opcodes */ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define OUTPUT 1 #d/* CHARIO.C Character-oriented file I/O Written 1980 by Scott W. Layson This code is in the public domain. These routiisect = newsect; return (nbytes); } cread (buf, dest, nbytes) /* read some bytes into dest */ struct iobuf *buf; chåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå close the file assoc. with buf */ struct iobuf *buf; { close (buf->fd); } cseek (buf, nbytes, code) /* seek to a ch { #ifdef SDOS unlink ("a:$$$$.cmd"); #else unlink ("a:$$$.sub"); #endif } bios (1); /* bye! */ } /* efine UPDATE 2 copen (buf, fname) /* open a file for char input */ struct iobuf *buf; char *fname; { buf->fd = opar *dest; unsigned nbytes; { int navail, nsects, nleft, nread1, nread2; if (buf < 0) return (-1); navail = umin (nbytite (buf->fd, &buf->buff, 1) < 1) return (-1); return (1); } umin (a, b) /* unsigned min */ unsigned a, b; { = nfill; nbytes -= nfill; source += nfill; } if (buf->nextc == 128) { ++(buf->isect); buf->nextc = 0; if (wråååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå buf->nextc = 0; if (nread2 < 1) return (navail + nread1 * 128); } nleft = nbytes % 128; movmem (&buf->buff, dest, ncc l2.c -e3800 cc chario.c l2 l2 chario -wa ChaòÖIChaò×TKbRdùØTGetKâÙexiôÚINexôÛIRe÷ÜPNewPagåÝPFinéÞIClosåßFileHeaes, 128 - buf->nextc); movmem (&buf->buff[buf->nextc], dest, navail); nbytes -= navail; buf->nextc += navail; dest += na return ((a < b) ? a : b); } /* End of CHARIO.C -- Character oriented file I/O */ s) /* write some bytes from source ite (buf->fd, &buf->buff, 1) < 1) return (-1); } nsects = nbytes / 128; if (nsects && write (buf->fd, source, nsects) <ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååleft); buf->nextc += nleft; return (navail + nbytes); } cwrite (buf, source, nbytes) /* write some bytes from source ååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååvail; nsects = nbytes / 128; if (nsects) { nread1 = read (buf->fd, dest, nsects); if (nread1 == -1) return (navail); åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå nsects) return (-1); nbytes %= 128; movmem (source + nsects * 128, &buf->buff, nbytes); buf->nextc += nbytes; returnåååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå*/ struct iobuf *buf; char *source; unsigned nbytes; { unsigned nleft, nfill, nsects; if (buf < 0) return (-1); åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå buf->isect += nread1; if (nread1 < nsects) return (navail + nread1 * 128); dest += nread1 * 128; } else nread1 = 0;åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå (nsects * 128 + nbytes); } cflush (buf) /* flush an output buffer */ struct iobuf *buf; { if (buf->nextc && wrååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååif (buf->nextc) { nfill = umin (nbytes, 128 - buf->nextc); movmem (source, &buf->buff[buf->nextc], nfill); buf->nextc +åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå if (buf->nextc == 128) { nread2 = read (buf->fd, &buf->buff, 1); if (nread2 == -1) return (navail); ++(buf->isect); åååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååå