IMD 1.16: 8/06/2007 8:22:23 UTILVI LBR UTILVI LBR !UTILVI LBR"#$%&'()*+,-./01UTILVI LBR23456789:;<=>?@AUTILVI LBR BCDEFGHIJKLMNOPQUTILVI LBR RSTUVWXYZ[\]^_`aUTILVI LBR SbcdefghijklmnoUTOOL-01LBRpqrstuvwxyUTOOL-02LBRz{|}~UTOOL-02LBR UTOOL-03LBRUTOOL-03LBR9UTOOL-04LBRUTOOL-04LBR-PUBDOM 067 READ ME 1CDB DOC eCHARIO C qC%CDB2 C eCDB C &BUILD C -PATBREAK C FBREAK C "|COMMAND C 1!0PARSE C K]PRINT C AUTIL C  TARGET C RCDB1 H CDB2 H $'CDB H Cp4CDB SUB`LCDB2 SUBa6CDB2 SUBcCDB COMe`CDB2 OVLkODASM CRLQxL2 C WL2 DOCyTELED C SORT C 8ERCONVERT C }-CC0T C )MAKOVL C &TABIFY C :CASM SUBK]CIO CSMN*OTHELLO C xSzlSIEVE C - Note: The following files were placed on this disk by BD Software as overflow from the main BDS C v1.50 distribution disk, and have nothing whatsoever to do with the Debugger package: TELED.C SORT.C CONVERT.C CC0T.C MAKOVL.C TABIFY.C OTHELLO.C SIEVE.C CIO.CSM  CDB: A Debugger for BDS C page 1 CDB: A Debugger for BDS C Version 1.2 4 November 1982 David Kirkland 5915 Yale Station New Haven, Connecticut 06520 (203) 787-9764 Copyright (c) 1982n contains a transcript of a debugging session to demonstrate the use of CDB. The target program, which is contained in the file TARGET.C, is as follows: /* * /.C David Kirkland, 20 October 1982 * * This is a short submit program. It is designed to be used * when the user wants to batch a few commands, but it's too * much trouble to edit a SUB file to do the work. It can be * used in two forms: * * B>/ command line 1; command line 2; ... command line n * * or * * B>/ * }command 1 * }command 2 * . * . * }command n * } * * In the first form, the / command is entered with arguments. * group of characters delimited by a semicolon (or the end of * the line) is treated as a separate command. * CDB: A Debugger for BDS C page 3 * In the second form, / is en by David Kirkland This document is a continuation of the CDB Appendix from the BDS C User's Guide. It is supplied on disk instead of on paper because of the large number of characters that are unprintable on the daisy wheel currently being used to run off the User's Guide. Note that all really useful reference material is in the CDB Appendix of the User's Guide; the main items given here are a file listing and a sample CDB session. Files Supplied The following CDB-related files are supplied on the CDB distribution disk: L2.C | source code for L2 linker CHARIO.C | L2.COM executable form of L2 linker CDB.DOC this file CDB.H header file for CDB.COM and CDB2.OVL CDB.COM prepared for BDOS at or above D000 CDB1.H tered without arguments. * / then prompts with a "}", and the user enters commands, one * per line. A null line terminates command entry. * (To enter a null line, enter a singe ^ on the line.) * * In either form, control characters can be entered either * directly or via a sequence beginning with a "^" and followed * by a letter or one of the characters: [ \ ] ^ _ * */ #include #define OPEN 15 /* BDOS function codes */ #define CLOSE 16 #define DELETE 19 #define CREATE 22 #define SET_DMA 26 #define RAND_WRITE 34 #define COMPUTE_SIZE 35 struct fcb { /* define fcb format */ char drivecode; char fname[8]; char ftype[3]; char extent; char pad[2]; char rc; int blk[8]; char cr; int rand_rec; char overflow;  | CDB.C | source code for CDB.COM BUILD.C | CDB2.OVL prepared for BDOS at or above D300 CDB: A Debugger for BDS C page 2 CDB2.H | CDB2.C | ATBREAK.C | BREAK.C | source code for CDB2.OVL COMMAND.C | PRINT.C | PARSE.C | UTIL.C | DASM.CSM | DASM.CRL CRL version of DASM.CSM CDB.SUB command file to simplify compilation and linkage of CDB.COM CDB2.SUB command file to simplify compilation of CDB2 components LCDB2.SUB command file to simplify linkage of CDB2.OVL An Example -- A CDB Debugging Session This sectio }; #define CPMEOF 0x1a #define MAXBLK 256 #define SUBNAME "A:$$$.SUB" struct fcb ffcb; /* the way a record from the $$$.SUB */ struct subrec { /* file looks: */ char reclen; /* number of characters in command */ char aline[127]; /* command line */ } ; struct subrec out[128]; storeline(block,line) int block; char *line; { /* storeline takes the line pointed to by "line" and * converts it to $$$.SUB representation and stores * it in out[block]. CDB: A Debugger for BDS C page 4 * This routine handles control characters (the ^ * escape sequence). * */ char *p; struct subrec *b; int i, len; b = out[block];e (*b && *b!=';') b++; done = !*b; *b = 0; storeline(block++, p+1); } } setfcb(ffcb,SUBNAME); if (255==bdos(OPEN,ffcb) && 255==bdos(CREATE,ffcb)) { printf("Can't create %s\n",SUBNAME); exit(); } /* find end of $$$.SUB so submits can nest */ bdos(COMPUTE_SIZE,ffcb); /* write blocks in REVERSE order for CCP */ for(--block; block >= 0; block--) { bdos(SET_DMA, out[block]); bdos(RAND_WRITE, ffcb); ffcb.rand_rec++; } /* all done! */ if (255==bdos(CLOSE,ffcb)) printf("Could not close %s\n",SUBNAME); } The debugging session follows. Text typed by the user is in boldface. ----- Start of Session ----- B> /* copy line into out.aline, processing control chars */ for (p = b->aline; *p = *line; p++, line++) if (*line=='^') if ('@' <= toupper(*++line) && toupper(*line) <= '_') *p = 0x1f&*line; else if (*p = *line) break; /* set up length byte */ b->reclen = len = strlen(b->aline); if (len>127) { printf("Line %d is too long (%d > %d)\n",block,len,127); bdos(DELETE,ffcb); exit(); } /* pad block with CPMEOFs (not needed?) */ for (i=len+2;i<128;i++) *++p = CPMEOF; } main (argc, argv) int argc; char *argv[]; { char *p, /* points to ; that ended current command */  B>cc target.c -k BD Software C Compiler v1.50 (part I) 35K Unused BD Software C Compiler v1.50 (part II) 32K to spare B>l2 target -d Mark of the Unicorn Linker ver. 2.2.2 Loading TARGET.CRL Scanning A:DEFF.CRL Scanning A:DEFF2.CRL Link statistics: Number of functions: 17 Code ends at: 0x133B CDB: A Debugger for BDS C page 6 Externals begin at: 0x133B Externals end at: 0x535F End of current TPA: 0xE406 Jump table bytes saved: 0x5D Link space remaining: 26K B>cdb target c debugger ver 1.2 top of target stack is 8C94, cdb2 is at 9000 globals use 0160 bytes, locals use 00D9 bytes break at MAIN 0 [0A54] >list map STORELIN 08A1 MAIN 0A51 TOUPPER 0CDA STRLEN 0D11 PRINTF 0D51 ISSPACE 0D79 ISLOWER 0DAF _SPR2 0DDE PUTS 113E _USPR 116A ISDIGIT 120C _GV2  *b, /* current character in command */ done; /* loop control */ char line[256], *gets(); int block; /* index into out array */ block = 0; if (argc<2) /* prompt user format */ while (1) { putchar('}'); if (!*gets(line)) break; storeline(block++, line); } else { /* scan command line in low memory */ CDB: A Debugger for BDS C page 5 b = p = 0x80; for (done=0; !done; p = b) { /* skip leading whitespace */ while (isspace(*++b)) p = b; whil 123B BDOS 1298 EXIT 12AC GETS 12B2 PUTCHAR 12E6 SETFCB 1318 >list args argc [8C90] = 0001 = 1 '..' argv [8C92] = 0863 >break storeline >l breaks MAIN -1 STORELIN 0 >go }dir a: break at STORELIN 0 [08A4] >list args block [8B81] = 0000 = 0 '..' line [8B83] = 8B8A >d *line string 8B8A (len 6): "dir a:" >trace 5 trace: STORELIN 15 [08AF] trace: STORELIN 18 [08CE] trace: STORELIN 18.1 [08DC] trace: STORELIN 19 [08F1] break at STORELIN 27 [096D] >break 28 >go break at STORELIN 28 [09A6] >dump *b a struct subrec reclen [135F] = 06 = '.' aline a 127 element array of char 1360 [ 0] 64 69 72 20 61 3a 00 00 00 00 00 00 00 00 00 00 'dir a:..........' 1370 [ 16] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' 1380 [ 32] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0sion ----- /* CHARIO.C Character-oriented file I/O Written 1980 by Scott W. Layson This code is in the public domain. These routines deal with reading and writing large blocks of characters, when they do not fit neatly in sectors. At the moment, only sequential output is supported; input is fully random. */ #define TRUE (-1) #define FALSE 0 #define NULL 0 /* i/o buffer */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index of next char in buffer */ char buff [128]; }; /* seek opcodes */ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define OUTPUT 1 #define UPDATE 2 copen (buf, fname) /* open a file for char input */ struct iobuf *buf; char *fname; { buf->fd = open (fname, INPUT); if (buf->fd == -1) return (-1); read (buf->fd, &buf->buff, 1); buf->isect = 0; buf->nextc = 0; retu0 00 '................' CDB: A Debugger for BDS C page 7 1390 [ 48] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' 13A0 [ 64] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' 13B0 [ 80] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' 13C0 [ 96] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '................' 13D0 [112] 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 '...............' >d len [8B7B] = 0006 = 6 '..' >,b->reclen [135F] = 06 = '.' >b setfcb >go } break at SETFCB 0 [131B] >list args first argument address is 8B81 [1] = 133B = 4923, [2] = 0C97 = 3223, [3] =01FE = 510 [4] = 22Ca = 8906, [5] = 0030 = 48, [6] = 7269 = 29289 >t break at MAIN 33 [0BA1] >dump ffcb a struct fcb drivecod [133B] = 01 = '.' fname a 8 element array of char 133C [ 0] 24 24 24 20 20 rn (buf); } ccreat (buf, fname) /* create a file for char output */ struct iobuf *buf; char *fname; { buf->fd = creat (fname); if (buf->fd == -1) return (-1); buf->isect = 0; buf->nextc = 0; return (buf); } cclose (buf) /* close the file assoc. with buf */ struct iobuf *buf; { close (buf->fd); } cseek (buf, nbytes, code) /* seek to a character (input only!) */ struct iobuf *buf; unsigned nbytes, code; { int newsect; if (buf < 0) return (-1); if (code == RELATIVE) nbytes += buf->isect * 128 + buf->nextc; newsect = nbytes / 128; if (newsect != buf->isect && (seek (buf->fd, newsect, ABSOLUTE) == -1 || read (buf->fd, &buf->buff, 1) == -1)) return (-1); buf->nextc = nbytes % 128; buf->isect = newsect; return (nbytes); } cread (buf, dest, nbytes) /* read some bytes into dest */ struct iobuf *buf; char *dest; unsigned nbytes; { int navail, nsects, nleft, nread1, nread2; if (buf < 0) return (-1); navail = umin (nbyt20 20 20 '$$$ ' ftype a 3 element array of char 1344 [ 0] 53 55 42 'SUB' extent [1347] = 00 = '.' pad a 2 element array of char 1348 [ 0] 00 00 '..' rc [134A] = 00 = '.' blk a 8 element array of int 134B [ 0] 0000 0000 0000 0000 = 0 0 0 0 '........' 1353 [ 4] 0000 0000 0000 0000 = 0 0 0 0 '........' cr [135B] = 00 = '.' rand_rec [135C] = 0000 = 0 '..' overflow [135E] = 00 = '.' >t 5 trace: BDOS 0 [129B] trace: BDOS returning 00FF = 255 = '..' trace: BDOS 0 [129B] trace: BDOS returning 0001 = 1 = '..' break at MAIN 39 [0BE6] >t break at BDOS 0 [129B] >t BDOS returning 00FF = 255 = '..' >t CDB: A Debugger for BDS C page 8 break at MAIN 42 [0BF6] >go MAIN returning FF02 = -254 = '..' >quit B> ----- End of Seses, 128 - buf->nextc); movmem (&buf->buff[buf->nextc], dest, navail); nbytes -= navail; buf->nextc += navail; dest += navail; nsects = nbytes / 128; if (nsects) { nread1 = read (buf->fd, dest, nsects); if (nread1 == -1) return (navail); buf->isect += nread1; if (nread1 < nsects) return (navail + nread1 * 128); dest += nread1 * 128; } else nread1 = 0; if (buf->nextc == 128) { nread2 = read (buf->fd, &buf->buff, 1); if (nread2 == -1) return (navail); ++(buf->isect); buf->nextc = 0; if (nread2 < 1) return (navail + nread1 * 128); } nleft = nbytes % 128; movmem (&buf->buff, dest, nleft); buf->nextc += nleft; return (navail + nbytes); } cwrite (buf, source, nbytes) /* write some bytes from source */ struct iobuf *buf; char *source; unsigned nbytes; { unsigned nleft, nfill, nsects; if (buf < 0) return (-1); if (buf->nextc) { nfill = umin (nbytes, 128 - buf->nextc); movmem (source, &buf->buff[buf->nextc], nfill); buf->nextc + call (ORIGIN + 0x0100); /* take off */ } #include "cdb1.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ ucase (s) char *s; { while (*s = toupper(*s)) s++; } makeext (fname, ext) char *fname, *ext; { /* uppercase filename and force extension to ext */ while (*fname && (*fname != '.')) { *fname = toupper (*fname); ++fname; } *fname++ = '.'; strcpy (fname, ext); } buildfnt (addr, name) struct fntentry *addr; char *name; { FILE sym; char afntname[4][20]; char *afntaddr[4]; struct fntentry *p; int i, n; strcpy(afntname, name); makeext(afntname,"SYM"); if (ERROR==fopen(afntname,sym)) { printf("Can't open %s\n",afntname); return ERROR; } p = addr; (--p)->fntaddr = 0x0000; fntab = p; strcpy(p->fntname, "C.CCC"); while (1) { n = fscanf(sym,"%x %s\t%x %s\t%x %s\t%x %s\n", &afntaddr[0], afntname[0], &afntaddr[1], afntname[1], &afntad= nfill; nbytes -= nfill; source += nfill; } if (buf->nextc == 128) { ++(buf->isect); buf->nextc = 0; if (write (buf->fd, &buf->buff, 1) < 1) return (-1); } nsects = nbytes / 128; if (nsects && write (buf->fd, source, nsects) < nsects) return (-1); nbytes %= 128; movmem (source + nsects * 128, &buf->buff, nbytes); buf->nextc += nbytes; return (nsects * 128 + nbytes); } cflush (buf) /* flush an output buffer */ struct iobuf *buf; { if (buf->nextc && write (buf->fd, &buf->buff, 1) < 1) return (-1); return (1); } umin (a, b) /* unsigned min */ unsigned a, b; { return ((a < b) ? a : b); } /* End of CHARIO.C -- Character oriented file I/O */ s) /* write some bytes from source #include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ /* cdb2 is the routine that initializes the package that is coresident in * memory with the target program. * "name" is the complete name of the COM file to be loaded. * "globdr[2], afntname[2], &afntaddr[3], afntname[3]); n /= 2; for (i=0; ifntaddr = afntaddr[i]; strcpy(p->fntname, afntname[i]); p->fntbreakindex = NOBREAK; p->fntst = NIL; p->fntfsize = -1; } if (n<4) break; } (--p)->fntaddr = 0xffff; strcpy(p->fntname, "NEVER"); return p; } doargs(i, ac, av, arg) int i, ac; char **av; struct argb *arg; { char line[80]; strcpy(av[i], &av[i][2]); for (arg->nfiles = 0; i < ac; i++) if (*av[i]=='-') { i--; break; } else if (0==strcmp(av[i],"0")) { arg->nfiles = -1; break; } else if (*av[i]) { strcpy (arg->files[arg->nfiles], av[i]); makeext(arg->files[arg->nfiles++], CSYMEXT); } if (arg->nfiles==0) { printf("Enter %s symbol files, one per line (null line to end)\n*", (arg==locals) ? "local" : "global" ); for (; arg->nfilesfiles[arg->nfiles], line); makeext(arg->files[arg->nfiles++], CSYMEXT" is a pointer to the first global symbol table entry. * "loc" is a pointer to the first local symbol table entry. */ cdb2 (name, glob, loc) char *name, *glob, *loc; { char fcb[40], *p; int *q, i; COPYRIGHT; /* set up table pointers */ localp = loc; globalp = fntabend = glob; fntab = CDB2ADDR; fntab--; trace_full = 0; /* empty trace table */ ntraces = 0; curfnt = fntab; cursn = 0; walkcount = 1; /* will cause a break at first RST */ #ifdef DEBUG debug = 0; #endif q = ORIGIN + 0x0006; /* get BDOS address for top of */ i = *q; /* debug stack */ q = i+1; initrst(*q); clearbreaks(); /* load target file */ if (ERROR==setfcb(fcb,name) || 255==bdos(15,fcb) ) { printf("no target file on disk\n"); exit(); } for (p=ORIGIN + 0x0100; ; p+=128) { bdos(26,p); if (bdos(20,fcb)) break; } globbase = externs(); p = CCC_KHACK; /* disable CCC's khack mechanism, which */ *p = 0xc9; /* sets the RST vector to a return */ ); putchar('*'); } if (arg->nfiles==NFILES) printf("Error: too many files\n"); else if (arg->nfiles==0) arg->nfiles = -1; } return i; } validdrive (d) char *d; { if (isdigit(*d)) if ((isdigit(*++d) && *++d=='/') || *d=='/') d++; else return 0; return !*d || (isalpha(*d) && !*++d); } processargc(argc, argv, drive) int argc; char **argv, **drive; { int i; locals.nfiles = globals.nfiles = 0; strcpy (globals.files[0], argv[1]); makeext(globals.files[0], CSYMEXT); strcpy (locals.files[0], globals.files[0]); *drive = CDB2_DRIVE; for (i=2; i=argc) printf("-d operand omitted\n"); else *drive = argv[i]; if (**drive && !validdrinbufp = CDB2ADDR; if (*fn) { if (ERROR==(fd=open(fn,0))) { printf("can't open %s\n",fn); return ERROR; } if (1!=read(fd,inbufp,1)) { printf("read error on %s\n",fn); return ERROR; } } num = *inbufp++; num += *inbufp++<<8; i = (num-2+127)/128 - 1; if (num > (max=topofmem()-CDB2ADDR-1000) ) { printf("%s is too large (%d bytes); max is %d bytes\n", fn, num, max); return ERROR; } if (*fn && i && i!=read(fd,inbufp+126,i)) { printf("read error on %s\n",fn); return ERROR; } return num; } struct fstentry *getst(s) char *s; { char i, name[8]; for (i=8; i<16; i++) s[i] = *inbufp++; for (i=0; i<8; i++) s[i] = *inbufp++; return inbufp - 16; } str70cpy(d,s) char *d, *s; { while (0 == ((*d = *s++) &0x80)) d++; *d = 0x7f & *d; *++d = 0; } str7cmp (s1, s2) char *s1, *s2; { /* compare two strings, either bit-7-terminated or null-terminated */ char end1, end2; for (; *s1 == *s2; s1++, s2++) ive(*drive)){ printf("Invalid -d option %s\n",*drive); *drive = CDB2_DRIVE; } } else printf("invalid argument %s\n",argv[i]); else printf("invalid argument %s\n",argv[i]); if (isalpha(**drive)) strcat(*drive,":"); } cpmtinker(p) char *p; { int i, *a; movmem(ORIGIN + 0x0005, p-3, 3); /* fix BDOS jumps so 0x0006 has */ a = ORIGIN + 0x0006; /* a good stack pointer */ *a = p-3; p = ORIGIN + 0x0080; /* patch the arguments to the target */ i = *p++; while (--i && *++p!='%') ; /* find 'em */ if (i>1) movmem(p+1,ORIGIN + 0x0082,i); else if (i==0) poke(ORIGIN + 0x0081,0); else { printf("Enter command line args: "); i = 1 + getline(ORIGIN + 0x0082,126); ucase(ORIGIN + 0x0082); } poke(ORIGIN + 0x0080,i); } statusmsg(p, glob, loc) char *p, *glob, *loc; { printf("top of target stack is %04x, cdb2 is at %04x\n",p-3,CDB2ADDR); printf("globals use %04x bytes, locals use %04x bytes\n", glob-loc, loc-p); } m if ( (0x80 & *s1) || !*s1) return 0; if ((0x7F & *s1) < (0x7F & *s2)) return -1; if ((0x7F & *s1) > (0x7F & *s2)) return 1; end1 = (*s1 & 0x80) || !*(s1+1); end2 = (*s2 & 0x80) || !*(s2+1); if (end2 && !end1) return 1; if (end1 && !end2) return -1; /* if (end1 && end2) */ return 0; } struct fntentry *name2fnt(name) char *name; { struct fntentry *f; char n[9]; movmem(name,n,8); n[8] = 0; ucase(n); for (f = fntab; f->fntaddr != 0xffff; f--) if (!strcmp(n,f->fntname)) return f; return ERROR; } symb (s,e) char *s; struct stentry *e; { struct stentry *p; /* * printf("%02x %02x %02x %02x %02x %02x %02x %02x\n", s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]); * */ for (p = globalp; p>=e; p--) { /* * printf("%02x %02x %02x %02x %02x %02x %02x %02x ", p->stname[0], p->stname[1], p->stname[2], p->stname[3], p->stname[4], p->stname[5], p->stname[6], p->stname[7]); printf("%s\n",p->stname); * */ if (0==str7cain (argc, argv) int argc; char **argv; { int i; char (*f)(), *p, *drive, name[20], ovlname[20]; COPYRIGHT; printf("c debugger ver 1.2\n"); if (argc<2) { printf("usage: cdb target_name [-g [global_fns | 0]] [-l [local_fns | 0] ]\n"); printf(" [-d [usr/][drive] ] [ %% [target arguments] ]\n"); exit(); } strcpy(name,argv[1]); if (ERROR==(p = buildfnt(CDB2ADDR, name))) exit(); processargs(argc, argv, &drive); if (ERROR==(p = buildglob(p))) exit(); if (ERROR==(p = buildloc(p))) exit(); cpmtinker(p); statusmsg(p, globalp+1, localp+1); strcpy(ovlname,drive); strcat(ovlname,CDB2_FILE); if (ERROR==swapin(ovlname,CDB2ADDR)) { printf("Couldn't swapin %s\n",ovlname); exit(); } makeext(name,"COM"); f = CDB2ADDR; (*f)(name,globalp,localp,p); } #include "cdb1.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ openit (fn) char *fn; { unsigned num, i, max; mp(s,p->stname)) return p; } return ERROR; } addst(p,s,f) struct stentry *p, *s; struct fstentry *f; { struct fstentry *q; /* * char name[10]; str70cpy(name, s->stname); printf("%-8s %4d %5d %5d %4d %4d %4d %04x %04x %04x\n",name, TYPE(*s), STELT(*s), FORML(*s), WHAT(*s), LIND(*s), CLEV(*s), s->stadrs, s->stsize, s->stdimsz); * */ s->stb2 = (LIND(*s)<<6) + ((CLEV(*s)!=0)<<1); movmem (s, --p, 16); if (WHAT(*s)==STRUCTDEF) { f->fstn1 = 0xff; f->fstp = p; } return p; } deffn(p,s,size) char *p; struct stentry *s; unsigned size; { char name[10]; struct fntentry *fnt; unsigned *u; *--p = 0xff; u = p -= 2; *u = size; str70cpy(name, s->stname); /* * printf("function %s, frame size %d\n",name,s->stadrs); * */ if (ERROR!=(fnt = name2fnt(name))) { fnt->fntst = p - sizeof *s; fnt->fntfsize = s->stadrs; } return p; } char *build1glob(p,num) struct stentry *p; unsigned num; { struct stentry s, *b; struct fum=openit(globals.files[i]))) return ERROR; p = build1glob(p, num); close(fd); } return p; } char *buildloc(p) struct stentry *p; { int i, num; char *q; localp = p-1; for (i=0; ibfnt && cursn > isb_q->bsn) isb_q++; /* did we find one? if so, decrement bcount and check for zero */ if (curfnt!=isb_q->bfnt || cursn!=isstentry *f; unsigned i; /* */ char name[10]; /* */ num /= 16; b = p; for (i=0; i=p; --b) if (WHAT(*b)==VARIABLE && TYPE(*b)==STRUCT) { f = CDB2ADDR+2; b->stsize = (f + b->stsize)->fstp; b->stb2 |= 1; /* * str70cpy(name, b->stname); printf("%-8s %4d %5d %5d %4d %4d %4d %04x %04x %04x ** new **\n",name, TYPE(*b), STELT(*b), FORML(*b), WHAT(*b), LIND(*b), CLEV(*b), b->stadrs, b->stsize, b->stdimsz); * */ } return p; } fakes(s) struct stentry *s; { s->stname[0] = 0; s->stb1 = 0x01; s->stb2 = 0x3f; } char *build1loc(p,num) struct stentry *p; unsigned num; { struct stentry s, *b, *q, *t; struct fstentry *f; char stpflag; unsigned i, size; /* */ char name[10]; /* */ num /= 16; b = p; for (i=0; i<=num; i++) { if (i==num) fakes(s); else f = getst(s); if (WHAT(s) == Fb_q->bsn || --(isb_q->bcount) ) return 0; else { isb_q->bcount = 1; return 1; } } atbreak (sp) struct savearea *sp; { /* the assembly package calls atbreak whenever a RST is encountered. * A pointer to the savearea is passed */ unsigned sn, *resume, atret(); if (0==(sn = *(resume = sp->statement++))) { /* sn == 0 means entry to a new function; stack on tracetab */ if (ntraces>=MAXTRACES) { if (!trace_full) { printf("fn trace table full (size is %d);", MAXTRACES); printf(" fn tracing inactive\n"); trace_full = 1; } } else { tracetab[ntraces].taddr = sp->caller_return; tracetab[ntraces++].tsn = cursn; sp->caller_return = atret; } curbreak = (curfnt = addr2fnt(resume))->fntbreakindex; curargs = (sp+1); } cursn = sn; if (trace_display && walkcount!=1) { printf(" trace: %s ",curfnt->fntname); printasn(sn); printf(" [%04x]\n",sp->statement); } if ((walkcount && !--walkcouUNCDEF) { for (q = --b; q>=p; --q) if (WHAT(*q)==VARIABLE && TYPE(*q)==STRUCT) { f = CDB2ADDR+2; stpflag = 1; if ((f + q->stsize)->fstn1 == 0xff) q->stsize = (f + q->stsize)->fstp; else if (ERROR!=(t= symb(&(f + q->stsize)->fstn1,p))) q->stsize = t; else { q->stsize = (f + q->stsize)->fstsize; stpflag = 0; } q->stb2 |= stpflag; /* * str70cpy(name, q->stname); printf("%-8s %4d %5d %5d %4d %4d %4d %04x %04x %04x ** new **\n",name, TYPE(*q), STELT(*q), FORML(*q), WHAT(*q), LIND(*q), CLEV(*q), q->stadrs, q->stsize, q->stdimsz); * */ } p = deffn(p,s,size); size = s.stadrs; b = p; } else if (CLEV(s) && (WHAT(s) == VARIABLE || WHAT(s)==STRUCTDEF)) p = addst(p,s,f); } return p; } char *buildglob(p) struct stentry *p; { int i, num; globalp = p-1; for (i=0; ifntname); printasn(sn); printf(" [%04x]\n",sp->statement); cursave = sp; command(); } resumeit(sp); } atreturn (h) int h; { /* when a function returns, it returns here because atbreak() changed * the stacked return address. atreturn() checks for a breakpoint * at sn == -1 (i.e., function return) and acts accordingly. */ char *t, stop; if (trace_full) { printf("fn tracing now restored.\n"); trace_full = 0; } cursn = -1; if ( (stop = (curbreak!=NOBREAK && isbreak()) || (walkcount && !--walkcount) || kbhit() ) || trace_display ) { printf(stop ? "\n" : " trace: "); printf("%s returning %04x = %d = '",curfnt->fntname,h,h); interprete(h>>8); interprete(h&255); printf("'\n"); if (stop) command(); } t = tracetab[--ntraces].taddr; curbreak = (curfnt = addr2fnt(t) * */ if (fnt->fntbreakindex!=NOBREAK) i = fnt->fntbreakindex; else i = 0; for ( q = breaktab[i]; ibfnt, q->bfnt->fntname); * */ if (fnt < q->bfnt || (fnt==q->bfnt && sn <= q->bsn)) break; } if (fnt!=q->bfnt || sn!=q->bsn) { printf("%s %d is not a breakpoint\n", fnt->fntname, sn); return ERROR; } /* * printf("before movmem: nbreaks = %d, i = %d\n", nbreaks, i); * */ movmem( q+1, q, (sizeof *q) * (nbreaks-- - i) ); if (fnt->fntbreakindex==i && q->bfnt!=fnt) fnt->fntbreakindex = NOBREAK; for (f = fntab; f->fntaddr != 0xffff; f--) if (f->fntbreakindex!=NOBREAK && f->fntbreakindex > i) f->fntbreakindex--; breaktab[nbreaks].bfnt = 0xffff; curbreak = curfnt->fntbreakindex; return 0; } zapbreaks () { /* eliminate all breakpoints. */ struct fntentry *f; nbreaks = 0; breaktab[0].bfnt = 0xffff; for (f = fntab; f->fntaddr != 0xffff; f--) f->fntbre)->fntbreakindex; curargs = NIL; return t; } #include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ insertbreak(fnt,sn,count) struct fntentry *fnt; unsigned sn, count; { /* insert a breakpoint at the function referenced by fnt and the * statment number "sn". Set the bcount of the breakpoint to count. * N.B.: this routine must update curbreak and all the breakindex * bytes in the fn table. * Return 0 or ERROR. */ struct breakentry *q; struct fntentry *f; int i; /* * printf("insertbreak (%04x = %s, %04x)\n",fnt, fnt->fntname,sn); * */ if (nbreaks>=MAXBREAKS) { printf("too many breakpoints (maximum is %d)\n",MAXBREAKS); return ERROR; } if (fnt->fntbreakindex!=NOBREAK) i = fnt->fntbreakindex; else i = 0; for ( q = breaktab[i]; ibfnt, q->bfnt->fntname); * */ if (fnt < q->bfnt || (fntakindex = NOBREAK; } clearbreaks () { /* eliminate all breakpoints except MAIN -1 */ struct fntentry *f; zapbreaks(); if (ERROR != (f = name2fnt("MAIN"))) insertbreak(f,-1,1); } #include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ help() { printf("debugger commands are:\n"); printf(" b[reak] [fn] [sn [count]]\n"); printf(" clear all breakpoints\n"); printf(" , d[ump] p[rint] contents of memory\n"); printf(" g[o]\n"); printf(" l[ist]\n"); printf(" l[ist] a[rgs]\n"); printf(" l[ist] b[reaks]\n"); printf(" l[ist] g[lobals]\n"); printf(" l[ist] l[ocals]\n"); printf(" l[ist] m[ap]\n"); printf(" l[ist] t[raceback]\n"); printf(" quit exit to CP/M\n"); printf(" r[eset] [fn] [sn] a breakpoint\n"); printf(" run start execution, debugger off\n"); printf(" s[et] var val [c] a variable\n"); printf(" t[race] [num] execute nu==q->bfnt && sn <= q->bsn)) break; } if (fnt!=q->bfnt || sn != q->bsn) { /* * printf("before movmem: nbreaks = %d, i = %d\n", nbreaks, i); * */ movmem( q, q+1, (sizeof *q) * (nbreaks++ - i) ); } q->bfnt = fnt; q->bsn = sn; q->bcount = count; for (f = fntab; f->fntaddr != 0xffff; f--) if (f->fntbreakindex!=NOBREAK && f->fntbreakindex >= i) f->fntbreakindex++; if (fnt->fntbreakindex==NOBREAK || fnt->fntbreakindex>i) fnt->fntbreakindex = i; breaktab[nbreaks].bfnt = 0xffff; curbreak = curfnt->fntbreakindex; return 0; } deletebreak(fnt,sn) struct fntentry *fnt; unsigned sn; { /* delete the breakpoint at the function referenced by fnt and the * statment number "sn", if it exists. * N.B.: this routine must update curbreak and all the breakindex * bytes in the fn table. * Return 0 or ERROR. */ struct breakentry *q; struct fntentry *f; int i; /* * printf("deletebreak (%04x = %s,%d)\n",fnt, fnt->fntname,sn); m statements, displaying sn's\n"); printf(" u[ntrace] [num] execute num statements, silently\n"); } printasn(n) unsigned n; { /* print a statement number. If 4 high order bits are on, then * use decimal format (low order 12 bits . high order 4). */ if (n==0xffff) printf("-1"); else { printf("%d",n&0x0fff); if (n&0xf000) printf(".%d",n>>12); } } listbreaks () { int i; for (i=0; ifntname); printasn(breaktab[i].bsn); if (breaktab[i].bcount!=1) printf(" (%d)\n",breaktab[i].bcount); else putchar('\n'); } } listit(l) char *l; { /* process a list command */ char subcmd[10], *garbage; get_token(&l, subcmd, garbage); switch (tolower(*subcmd)) { case 0: printf("current location: %s ",curfnt->fntname); printasn(cursn); putchar('\n'); break; case 'a': if (curfnt->fntst!=NIL) printargs(); else if (curargs == NIL) printf("can't list args ; return ERROR; } if (INTEGER != get_token(l, name, sn)) *sn = 0; } if ('.' == **l) { (*l)++; if (INTEGER != get_token(l, name, &high)) { printf("invalid statement number %d.%s\n",*sn,name); return ERROR; } *sn |= high<<12; } } setbreak(l) char *l; { unsigned sn, count; struct fntentry *fnt; char name[20]; if (ERROR!=breakargs(&l,&fnt,&sn)) { if (INTEGER != get_token(&l, name, &count)) count = 1; insertbreak(fnt,sn,count); } } resetbreak(l) char *l; { unsigned sn; struct fntentry *fnt; if (ERROR!=breakargs(&l,&fnt,&sn)) deletebreak(fnt,sn); } map() { /* print a load module map of the target program. */ struct fntentry *q; int i; for (i = 0, q = fntab-1; (q-1) > fntabend; q--, i++) { if (!(i&3)) putchar('\n'); printf("%-8s %04x ", q->fntname, q->fntaddr); } putchar('\n'); } command() { /* get and process commands. */ char *l, line[128], cmd[10]; int garbage; walkcount to %s because it has called a function\n", curfnt->fntname); else { printf("first argument address is %04x\n",curargs); printf("[1] = %04x = %d, [2] = %04x = %d, [3] = %04x = %d\n", *curargs, *curargs, *(curargs+1), *(curargs+1), *(curargs+2), *(curargs+2) ); printf("[4] = %04x = %d, [5] = %04x = %d, [6] = %04x = %d\n", *(curargs+3), *(curargs+3), *(curargs+4), *(curargs+4), *(curargs+5), *(curargs+5) ); } break; case 'g': printlg(globalp); break; case 'l': if (curfnt->fntst!=NIL) printlg(curfnt->fntst); else printf("local symbols not available\n"); break; case 'm': map(); break; case 't': trace(); break; case 'b': listbreaks(); break; default: printf("illegal list subcommand\n"); } } trace () { int i; for (i=1; ifntname= trace_display = 0; while (1) { cancel_char = 0; putchar('>'); l = gets(line); get_token(&l, cmd, &garbage); switch (tolower(*cmd)) { case 'b': setbreak(l); break; case 'c': if (compare(cmd,"clear")) clearbreaks(); else goto wrong; break; case 'l': listit(l); break; case 'q': if (compare(cmd,"quit")) exit(); else goto wrong; break; case 'r': if (!compare(cmd,"run")) { resetbreak(l); break; } movmem("\341\043\043\351",8*RST_NUM,4); /* POP H INX H x2 PCHL */ zapbreaks(); /* fall through */ case 'g': return; break; case 't': trace_display = 1; /* fall through */ case 'w': case 'u': if (INTEGER!=get_token(&l, cmd, &walkcount)) walkcount = 1; return; break; case 's': set(l); break; case '?': case 'h': help(); break; case ',); printasn(tracetab[i].tsn); printf(" called\n"); } else printf("%s called\n", addr2fnt(tracetab[i].taddr)->fntname); printf("%s\n",curfnt->fntname ); } compare(s, pat) char *s, *pat; { while (*pat && tolower(*s++) == tolower(*pat)) pat++; return !*pat; } breakargs(l, fnt, sn) char **l; struct fntentry **fnt; unsigned *sn; { /* Process arguments to break and reset commands. Determines * function (and sets fnt) and statement number (sets sn). * l is pointer to pointer to input line * * syntax: * [function name] [line[.statement within line]] * if function name is ommitted, current function assumed. * if line ommitted, zero (i.e., function entry) assumed. */ char name[10], class; int high; if (0 == (class = get_token(l, name, sn))) { printf("arguments missing\n"); return ERROR; } else if (class==INTEGER) *fnt = curfnt; else { if (ERROR == (*fnt = name2fnt(name))) { printf("%s does not exist\n",name)': case 'd': case 'p': print(l); break; #ifdef DEBUG case 'z': debug = !debug; printf("debug %s\n", debug ? "on" : "off"); break; #endif wrong: default: printf("illegal command\n"); } } } #include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ union valun { int intval; int *ptrval; }; ishex(c) char c; { return isdigit(c) || ('a'<=c&&c<='f') || ('A'<=c&&c<='F'); } struct stentry *findsym (symbol) char *symbol; { /* Look up a symbol in the symbol table. The null-terminated string * "symbol" is searched for in the table. If it is present, findsym * returns a pointer to the correct symbol table entry; else, a * diagnostic is printed and ERROR is returned. * Normally, first the local symbols for the current function are * searched, followed by the globals; but if t *t = 0; /* * if (debug) printf("get_token returning class = %c, token = <%s>, value = %d\n", class, tt, *valp); * */ *sp = s; return class; } invalid(t) char t; { if (t>=0x20 && t<0x80) printf("'%c'",t); else printf("'\\%o'",t); } sizeelt(type) struct sttype *type; { /* compute the size, in bytes, of a single element of * the object described by "type". */ if (type->tlind!=0 || type->tptfnf) return 2; else if (type->ttype==STRUCT) if (type->tsptr) return type->tsize.p->stsize; else return type->tsize.u; else if (type->ttype==CHAR) return 1; else return 2; } sizeary(s) struct stentry *s; { /* Compute the size, in bytes, of the array with the symbol table entry * pointed to by s. * Method: find the variable that follows this variable, and compute * the difference in adrs fields. Special cases occur when the * array in question is (i) the last element in a structure, * (ii) the last local variable in a functhe symbol is preceeded * by a backslash, only the global symbols are searched. */ char s[8], t[9], globflag; struct stentry *p; globflag = '\\' == *symbol; movmem(&symbol[globflag],t,8); t[8] = 0; str07cpy(s,t); if ((!globflag) && NIL!=(p=curfnt->fntst)) for (; p->stname[7]!=0xff; p--) { if (str7eq(s,p->stname)) return p; } for (p=globalp; p>localp; p--) { if (str7eq(s,p->stname)) return p; } printf("no symbol %s\n",symbol); return ERROR; } char get_token(sp,t,valp) char **sp, *t; int *valp; { /* get_token isolates the next token on the input line. * sp is a pointer to a pointer to an array of characters forming the * line to be scanned. *sp is updated to point to the next unprocessed * character once get_token has gotten its token. * The token scanned is copied into t; valp is set to the integer value * of the token iff the token is an integer. * get_token returns the "class" of the token, which can be * (i) INTEGER (ion, or (iii) the last * global variable. (This is the order in which we treat them below.) */ struct stentry *next; unsigned naddr, *up; next = s-1; if (STELT(*s)) if (STELT(*next)) naddr = next->stadrs; else { for (next = s; WHAT(*++next)!=2; ) ; naddr = next->stsize; } else { while (next->stname[7]!=0xff && (WHAT(*next)!=0 || STELT(*next)) ) next--; if (next->stname[7] == 0xff) if (LOCAL(*s)) { up = &(next->stname[5]); naddr = *up; #ifdef DEBUG if (debug) printf(" local sfsize = %04x\n", naddr); #endif } else naddr = endext() - externs(); else naddr = next->stadrs; } return naddr - s->stadrs; } gettt(s,t) struct stentry *s; struct sttype *t; { /* Copy information from a symbol table entry into a sttype structure. * Most of this is done solely to make it easier to change the data * so copied when exp or primary needs to do so. */ t->tptfnf = PTFNF(*s); t->ttype =a decimal or hex integer), (ii) ID (a sequence of * _, alpha, or digits that doesn't start with a digit), (iii) POINT * (the sequence "->"), or (iv) any special character. * */ char class, *s, *tt; tt = t; s = *sp; while(isspace(*s)) ++s; if (isalpha(*s) || *s=='_' || *s=='\\') { /* identifier */ class = ID; do if (t-tt<=8) *t++ = *s; while (isdigit(*++s) || isalpha(*s) || *s == '_'); } else if (isdigit(*s) || ((*s=='-' || *s=='+') && isdigit(*(s+1)) ) ) { class = INTEGER; do if ('x' == tolower(*s)) { class = HEX; t = tt; } else if (t-tt<=8) *t++ = *s; else if (class!=BAD) { printf("integer too long\n"); class = BAD; } while (ishex(*++s) || *s == 'x'); *t = 0; if (class!=BAD) { sscanf(tt,(class==INTEGER) ? "%d" : "%x",valp); class = INTEGER; } } else { if (class = *s) s++; if (class == '-' && *s == '>') { class = POINT; ++s; } *t++ = class; }  TYPE(*s); t->tsptr = SPTR(*s); t->tlind = LIND(*s); t->tforml = FORML(*s); t->tadrs = s->stadrs; t->tsize.u = s->stsize; t->tdimsz = s->stdimsz; if (t->tdimsz && !t->tforml) t->tmul = sizeary(s)/sizeelt(t); else t->tmul = 1; } exp (s, term, type) char **s, term; struct sttype *type; { /* exp() processes expressions. * expression := *expression * primary * * s is the command line pointer-to-pointer; term is the character * that marks the end of the expression; it is usually either * '\0', ']', or ')'. * exp returns the value computed for the expression (i.e., the * address defined by the symbolic reference or the actual value * of the integer entered), and sets *type as appropriate. */ char token[10], class, *ss; union valun aval; #ifdef DEBUG if (debug) printf("exp( %s, '%c')\n",*s,term); #endif ss = *s; class = get_token(s, token, aval); if (class=='*') { aval.intval = exp(s,term,type); aval.intval = *aval.ptrval;rocessed * primary. aval and type contain the address and other information * derived from the primary; do_index updates all this information * to take the indexing into account. * s is pointer-to-pointer to input line. */ union valun bval; struct sttype type2; char token[10]; int i, scale; if (type->tforml) aval->intval = *aval->ptrval; bval.intval = exp(s,']', type2 ); if (type2.ttype==BAD) { type->ttype = BAD; return; } get_token(s, token, aval); i = (type2.ttype==VALUE) ? bval.intval : *bval.ptrval; if (type2.tlind==0 && type2.ttype==CHAR) i &= 0xff; scale = sizeelt(type); #ifdef DEBUG if (debug) printf(" scale = %d, i = %d, dimsz = %04x\n",scale,i,type->tdimsz); #endif if (type->tdimsz!=0xff00) { scale *= type->tdimsz; type->tmul = type->tdimsz; type->tdimsz = 0xff00; #ifdef DEBUG if (debug) printf(" new scale = %d, mul = %04x\n",scale,type->tmul); #endif } else { type->tmul = 1; type->tdimsz = 0; }  if (type->tlind) type->tlind--; else if (type->tdimsz!=0xff00) { if (type->ttype==CHAR) aval.intval &= 0xff; type->ttype = INT; } #ifdef DEBUG if (debug) printf("exp [*] returning %04x = %d\n",aval.intval,aval.intval); #endif return aval.intval; } else if (class==term) { printf("empty expression at "); invalid(term); putchar('\n'); type->ttype = ERROR; return; } else if (class==BAD) { type->ttype = ERROR; return; } *s = ss; return primary(s,term,type); } /* unsigned baseaddr(stab) struct stentry *stab; { unsigned result; if (LOCAL(*stab)) { if (cursn==0) { result = &(cursave->caller_return); result -= curfnt->fntfsize + 2; } else result = cursave->bc; if (FORML(*stab)) result += 4 + curfnt->fntfsize; } else { #ifdef DEBUG if (debug) printf("globbase = %04x\n",globbase); #endif result = globbase; } return result; } */ unsigned do_stentry(stab,type) struct stentry  aval->intval += scale * i; } do_struct(class, s, aval, type) char class; char **s; union valun *aval; struct sttype *type; { /* do_struct processes a structure reference to an already-processed * primary. aval and type contain the address and other information * derived from the primary; do_struct updates all this information * to take the structure reference into account. * class contains either '.' or POINT and tells do_struct whether * aval contains the address of the structure or the address of a * pointer to the structure. * s is pointer-to-pointer to input line. */ char token[10]; union valun bval; struct stentry *stab; if (class==POINT) aval->intval = *aval->ptrval; get_token(s, token, bval); if (ERROR==(stab = findsym(token))) type->ttype = BAD; else if (!STELT(*stab)) { printf("%s is not a structure element\n", token); type->ttype = BAD; } else { aval->intval += stab->stadrs; gettt(stab,type); } } primary (s*stab; struct sttype *type; { unsigned base; gettt(stab,type); if (STELT(*stab)) base = 0; else if (LOCAL(*stab)) { if (cursn==0) { base = &(cursave->caller_return); base -= curfnt->fntfsize + 2; } else base = cursave->bc; if (FORML(*stab)) base += 4 + curfnt->fntfsize; } else base = globbase; #ifdef DEBUG if (debug) printf("adrs = %04x, base = %04x\n",type->tadrs,base); #endif return base + type->tadrs; } do_id (ident, type) char *ident; struct sttype *type; { /* do_id processes an identifier by looking up the symbol given * in "ident" in the symbol table and computing the absolute * memory address of that symbol. This address is returned, and * type is set. */ struct stentry *stab; if (ERROR==(stab = findsym(ident))) type->ttype = BAD; else return do_stentry(stab,type); } do_index(s, aval, type) char **s; union valun *aval; struct sttype *type; { /* do_index processes a single subscript to an already-p, term, type) char **s, term; struct sttype *type; { /* primary() processes primaries. * primary := (expression) * primary[expression] * primary->indentifier * primary.indentifier * * s is the command line pointer-to-pointer; term is the character * that marks the end of the expression; it is usually either * '\0', ']', or ')'. * primary returns the value computed for the expression (i.e., the * address defined by the symbolic reference or the actual value * of the integer entered), and sets *type as appropriate. */ char token[10], class, *ss; union valun aval, bval; #ifdef DEBUG if (debug) printf("primary( %s, '%c' )\n", *s, term); #endif class = get_token(s, token, aval); if (class=='(') { aval.intval = exp(s,')',type); get_token(s, token, aval); } else if (class==ID) aval.intval = do_id(token,type); else if (class==INTEGER) { type->ttype = VALUE; type->tdimsz = 0; type->tmul = 1; type->tptfnf = 0; type->tlise '\\': puts("\\\\"); break; default: printf("\\%o",*s); break; } else putchar(*s); } prints(s) char *s; { printf("%04x (len %d): \"", s, strlen(s)); sprint(s); printf("\"\n"); } printca(array, len) char array[][16]; int len; { int i, j, m, n; n = (len+15)/16; for (i=0; ittype = BAD; } ss = *s; while (type->ttype!=BAD && term != (class=get_token(s, token, bval))) { if (class=='[') do_index(s, aval, type); else if (class==POINT || class=='.') do_struct(class, s, aval, type); else if (class==INTEGER || class=='\'' || class==ID) break; else { if (class!=BAD) { printf("invalid primary at token "); invalid(class); putchar('\n'); } type->ttype = BAD; } ss = *s; } *s = ss; #ifdef DEBUG if (debug) printf("primary returning type = %d, value = %04x = %d\n", type->ttype, aval.intval, aval.intval); if (debug) printf(" lind = %d, size = %d, mul = %04x, dimsz = %04x\n", type->tlind, type->tsize, type->tmul, type->tdimsz); #endif return aval.intval; }  (i) printf(" "); printf("'"); for (j=0; j<4; j++) { if (i+j>=mul) break; interprete(array[i+j]&255); interprete(array[i+j]>>8); } printf("'\n"); } } printpa(array, mul) int array[]; int mul; { int i, j, m, n; for (i=0; i=mul) break; interprete(array[i+j]&255); interprete(array[i+j]>>8); } printf("'\n"); } } printvar (s, sbase) struct stentry *s; unsigned sbase; { struct sttype vartype; char pa[9], *addr; str70cpy(pa,s->stname); printf("%-11s",pa); addr = do_stentry(s,vartype); printexp(sbase+addr,vartype,0,0); } printstruct (addr, type, mul) char *addr; struct sttype *type; int mul; { /* print "mul" occurrences of structures #include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ interprete(c) char c; { if (c<' ' || c>127) putchar('.'); else putchar(c); } printp(p) char **p; { printf("[%04x] = ", p); if (*p==NIL) printf("NIL\n"); else printf("%04x\n",*p); } printc(p) char *p; { printf("[%04x] = %02x = '", p,*p); interprete(*p); printf("'\n"); } printw(p) int *p; { printf("[%04x] = %04x = %6d '", p,*p,*p); interprete(*p&255); interprete(*p>>8); printf("'\n"); } /* printu(p) unsigned *p; { printf("[%04x] = %04x = %6u '", p,*p,*p); interprete(*p&255); interprete(*p>>8); printf("'\n"); } */ cancelhit() { if (kbhit()) cancel_char = bdos(6,0xff); return cancel_char; } sprint (s) char *s; { for (; *s; s++) if (cancelhit()) break; else if (*s<' ' || *s>127 || *s == '\\') switch (*s) { case '\n': puts("\\n"); break; case '\r': puts("\\r"); break; case '\t': puts("\\t"); break; cadescribed by "type" * starting at address "addr". * If possible, we go through the symbol table and print each element * of the structure in the proper format. */ struct stentry *s; unsigned i, size; size = sizeelt(type); for (i=0; i1) printf("[%u]",i); putchar('\n'); if (type->tsptr) { s = type->tsize.p; while( (--s)->stname[7]!=0xff && STELT(*s)) printvar(s, addr); } else printca(addr,type->tsize.u); } } printlg(s) struct stentry *s; { for (; s->stname[7]!=0xff; s--) { cancel_char = 0; if (WHAT(*s)==VARIABLE && !STELT(*s) ) printvar(s, 0); cancelhit(); if (cancel_char && cancel_char!=NEXTKEY) break; } } printargs() { struct stentry *s; s = curfnt->fntst; for (; s->stname[7]!=0xff && FORML(*s) && !cancelhit(); s--) if (!STELT(*s)) printvar(s, 0); } printtype(type) struct sttype *type; { char pa[9], i; if (type->tptfnf (mul == 0) mul = type->tmul; switch (tolower(option)) { case 'p': if (mul>1) printpa(addr,mul); else printp(addr); break; case 'c': if (mul>1) printca(addr,mul); else printc(addr); break; case 's': prints(addr); break; case 't': printstruct(addr,type,mul); break; case 'i': case 'w': default: if (mul>1) printwa(addr,mul); else printw(addr); break; } } print(l) char *l; { char *addr, aonly, option, token[10], *ll, c; int mul, value; struct sttype type; ll = l; if (!(aonly = (c = get_token(&l, token, &value)) == '&')) if (c==BAD) return; else l = ll; addr = exp(&l, 0, type); if (type.ttype == BAD) return; if (aonly) { printf(" %04x\n", addr); return; } mul = 0; option = 0; while (c = get_token(&l, token, &value)) if (c==ID) option = *token; else if (c==INTEGER) mul = value; printexp(addr,type,mul,option); } set(lf) printf("pointer to a function returning "); for (i=0; itlind; i++) putchar('*'); switch (type->ttype) { case INT: printf("int"); break; case CHAR: printf("char"); break; case UNSIGNED: printf("unsigned"); break; case STRUCT: if (type->tsptr) { str70cpy(pa,type->tsize.p->stname); printf("struct %s",pa); } else printf("(%d byte structure)",type->tsize.u); break; } } printexp(addr,type,mul,option) char *addr; struct sttype *type; int mul; char option; { /* Print "mul" occurences of an item with address "addr" described * by "type". If option == 0, printexp decides the proper print * format based on *type; for non-zero options, the specified option * is used (p for pointer, c for char, w for word, s for string). * Also, if mul is specified as zero, *type is used to provide the * correct number of elements to print. */ unsigned i, nrows, ncols, scale; if (mul==0 && option==0 && type->tdimsz &) char *l; { /* set processes the set command, which sets a byte or a word * in memory to the value specified by the user. l is a * pointer to the input command line, which contains * an expression (which determines the address of the item to * be set) and a value (either an integer or a single quoted * character). An optional c operand flag is allowed, which * specifies that only a single byte is to be stored; if * this option is not specified, set() determines the length of * the target item by determining its type. */ char token[10], c; int i, value, *addr; struct sttype type; addr = exp(&l, 0, type); if (type.ttype==BAD) return; c = get_token(&l, token, &i); if (c=='\'') { c = get_token(&l, token, &i); value = *token; get_token(&l, token, &i); } else if (c==INTEGER) value = i; else { printf("invalid new value"); return; } if ( (type.tlind == 0 && type.ttype == CHAR && !type.tptfnf) || (get_token(&l, token, && !type->tforml) if (type->tdimsz == 0xff00) { printf("a %d element array of ",type->tmul); printtype(type); putchar('\n'); printsexp(addr,type,mul,option); } else { ncols = type->tdimsz; nrows = type->tmul/ncols; printf("a %d x %d array of ",nrows, ncols); printtype(type); putchar('\n'); scale = type->tdimsz*sizeelt(type); for (i=0; ittype==STRUCT && !type->tlind) { printf("a "); printtype(type); } printsexp(addr,type,mul,option); } } printsexp(addr,type,mul,option) char *addr; struct sttype *type; int mul; char option; { if (type->ttype == BAD) return; if (option == 0) if (type->tlind) option = 'p'; else if (type->ttype==CHAR) option = 'c'; else if (type->ttype==STRUCT) option = 't'; else option = 'w'; ii) && tolower(*token) == 'c') ) poke(addr, value); else *addr = value; } #include "cdb2.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ putchar(c) char c; { return putch(c); } ucase (s) char *s; { /* convert a null-terminated string to upper case */ while (*s = toupper(*s)) s++; } str70cpy(d,s) char *d, *s; { /* copy s, a 7-terminated string, to d, a null-terminated string */ while (0 == ((*d = *s++) &0x80)) d++; *d = 0x7f & *d; *++d = 0; } str7eq (s1, s2) char *s1, *s2; { /* test two bit-7-terminated strings for equality */ for (; *s1 == *s2; s2++) if (0x80 & *s1++) return 1; return 0; } str07cpy(d,s) char *d, *s; { /* copy s, a null-terminated string, to d, a 7-terminated string */ while (*s) *d++ = *s++; *--d |= 0x80; } struct fntentry *addr2fnt (addr) char *addr; { /* given an address, addr, find which function the address is * within and return the addrtype[3]; char extent; char pad[2]; char rc; int blk[8]; char cr; int rand_rec; char overflow; }; #define CPMEOF 0x1a #define MAXBLK 256 #define SUBNAME "A:$$$.SUB" struct fcb ffcb; /* the way a record from the $$$.SUB */ struct subrec { /* file looks: */ char reclen; /* number of characters in command */ char aline[127]; /* command line */ } ; struct subrec out[128]; storeline(block,line) int block; char *line; { /* storeline takes the line pointed to by "line" and * converts it to $$$.SUB representation and stores * it in out[block]. * This routine handles control characters (the ^ * escape sequence). * */ char *p; struct subrec *b; int i, len; b = out[block]; /* copy line into out.aline, processing control chars */ for (p = b->aline; *p = *line; p++, line++) if (*line=='^') if ('@' <= toupper(*++line) && toupper(*line) <= '_') *p = 0x1f&*line; else if (*p = *line) bress of the proper fn table entry. */ /* struct fntentry *a2f_p; /* now global for speed */ char *a2f_addr; */ a2f_p = fntab; a2f_addr = addr; while ( a2f_addr > (a2f_p--)->fntaddr ) ; return a2f_p + 2; } struct fntentry *name2fnt(name) char *name; { /* find the fn table entry for the function with name "name" (a null- * terminated string). ERROR returned if no such function exists. */ struct fntentry *f; char n[9]; movmem(name,n,8); /* truncate to 8 chars, upper case */ n[8] = 0; ucase(n); for (f = fntab; f->fntaddr != 0xffff; f--) if (!strcmp(n,f->fntname)) return f; return ERROR; }  /* //.C David Kirkland, 20 October 1982 This is a short submit program. It is designed to be used when the user wants to batch a few commands, but it's too much trouble to edit a SUB file to do the work. It can be useeak; /* set up length byte */ b->reclen = len = strlen(b->aline); if (len>127) { printf("Line %d is too long (%d > %d)\n",block,len,127); bdos(DELETE,ffcb); exit(); } /* pad block with CPMEOFs (not needed?) */ for (i=len+2;i<128;i++) *++p = CPMEOF; } main (argc, argv) int argc; char *argv[]; { char *p, /* points to ; that ended current command */ *b, /* current character in command */ done; /* loop control */ char line[256], *gets(); int block; /* index into out array */ block = 0; if (argc<2) /* prompt user format */ while (1) { putchar('}'); if (!*gets(line)) break; storeline(block++, line); } else { /* scan command line in low memory */ b = p = 0x80; for (done=0; !done; p = b) { /* skip leading whitespace */ while (isspace(*++b)) p = b; while (*b && *b!=';') b++; done = !*b; *b = 0; storeline(block++, p+1); } } setfcb(ffcb,SUBNAME); if (255==bdosd in two forms: B>// command line 1; command line 2; ... command line n or B>// }command 1 }command 2 . . }command n } In the first form, the // command is entered with arguments. group of characters delimited by a semicolon (or the end of the line) is treated as a separate command. In the second form, // is entered without arguments. // then prompts with a "}", and the user enters commands, one per line. A null line terminates command entry. (To enter a null line, enter a singe ^ on the line.) In either form, control characters can be entered either directly or via a sequence beginning with a "^" and followed by a letter or one of [\]^_ */ #include #define OPEN 15 /* BDOS function codes */ #define CLOSE 16 #define DELETE 19 #define CREATE 22 #define SET_DMA 26 #define RAND_WRITE 34 #define COMPUTE_SIZE 35 struct fcb { /* define fcb format */ char drivecode; char fname[8]; char f(OPEN,ffcb) && 255==bdos(CREATE,ffcb)) { printf("Can't create %s\n",SUBNAME); exit(); } /* find end of $$$.SUB so submits can nest */ bdos(COMPUTE_SIZE,ffcb); /* write blocks in REVERSE order for CCP */ for(--block; block >= 0; block--) { bdos(SET_DMA, out[block]); bdos(RAND_WRITE, ffcb); ffcb.rand_rec++; } /* all done! */ if (255==bdos(CLOSE,ffcb)) printf("Could not close %s\n",SUBNAME); } #include "cdb.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ #define CSYMEXT "CDB" /* extent for debug symbol tables */ #define NFILES 16 /* max number of files for -l or -g options */ /* argb structures are used to define the files specified to -l or -g * options */ struct argb { int nfiles; char files[NFILES][16]; }; struct argb locals, globals; struct fntentry *fntab; /* function table */ struct stentry *globalp; /* -> first global st entry */ struct stentry *lo char *caller_return; /* iff the RST was one l2 put in at the start * of a function, this is the return address * that the called function will return to */ } ; /* The breaktable "breaktab" records all breakpoints * The table is sorted by bfnt (address of function table entry) and bsn * (statement number). Both sorts are ascending. */ struct breakentry { struct fntentry *bfnt; unsigned bsn; unsigned bcount; /* each time through a breakpoint, decrement * this count; only stop when count == 0 */ int bpad; }; #define MAXBREAKS 40 int nbreaks; struct breakentry breaktab[MAXBREAKS]; struct savearea *cursave; /* points to current save area */ struct fntentry *curfnt; /* fntab entry of current function */ int *curargs; /* address of first arg to most recently invoked fn */ char curbreak; /* curfnt->fntbreakindex; 0xff means no breaks in cur * function, else index of first break in this fn */ unsigned cursn; /* current statement number */ unsigned calp; /* -> first local st entry */ /* fstentry is like stentry, but in the order it appears in the CDB file */ struct fstentry { /* while processing the in-memory CDB file, * build replaces the name field in the * entry with other information IFF the entry * is a structure definition */ char fstn1; /* if struct def && struct is in cdb2 symbol * table, byte is 0xff */ struct stentry *fstp; /* if fstn1 == 0xff, fstp points to cdb2 symbol * table entry for the struct def */ char fstname[5]; /* pad */ char fstb1, fstb2; /* see stentry ..... */ int fstadrs; int fstsize; unsigned fstdimsz; }; int fd; /* stuff for build */ char *inbufp; /* #define TYPE(s) (((s).stb1&0x70)>>4) #define STELT(s) (((s).stb1&0x08)>>3) /* is it a structure element ? */ #define FORML(s) (((s).stb1&0x04)>>2) /* is it a formal parameter ? */ #define WHAT(s) (((s).stb1&0x03)) #define LIND(s) (((s).stb2&0xc0)>>6) /* levels of indirection */ #define CLEV(s) (((walkcount; /* if !=0, decrement at each RST and break when zero */ char trace_display; /* if !=0, display current location at each RST */ struct fntentry *fntab; /* address of function table */ struct fntentry *fntabend; /* address of last entry in function table */ struct stentry *globalp; /* address of first global symbol table entry */ struct stentry *localp; /* address of first local symbol table entry */ int globbase; /* pointer to start of externs [ externs()] */ struct fntentry *a2f_p; /* used in addr2fnt; now global for speed */ char *a2f_addr; struct breakentry *isb_q; /* now global for speed */ /* these defines are for the "class" returned by get_token */ #define ID 'a' #define INTEGER '0' #define HEX 'x' #define POINT '>' /* "->" operand */ /* an sttype structure is used by the symbol/expression parsing routines * to keep track of the current attributes of the expression. It is based * upon the stentry for the base symbo, as modified by indirection, indexis).stb2&0x3f)) /* "defining block" -- only before * build has processed the entry */ /* after symbol table is built, CLEV is replaced by : */ #define LOCAL(s) (((s).stb2&0x02)>>1) /* is it local ? */ /* only applies if a structure ref: */ #define SPTR(s) (((s).stb2&0x01)) /* TRUE -> stsize is a pointer to * structure definition * FALSE -> stsize is size, in bytes, * of structure */ */ #include "cdb.h" /* Copyright (c) 1982 by J. David Kirkland, Jr. */ #define CCC_KHACK 0x013e #define NEXTKEY ('M'&0x1f) /* used by printlg to skip to next variable */ char cancel_char; /* the restart-trapping routine pushes the registers at time of restart * and passes a pointer to the block of registers to atbreak. The * registers end up as follows: */ struct savearea { int psw; int bc; int de; int hl; unsigned *statement; /* -> the statement number after the RST */ng, * etc. */ struct sttype { char tptfnf; /* ptr to fnunction flag */ char ttype; /* same type codes as stentry */ char tsptr; /* same meaning as stentry for next items */ char tlind; char tforml; unsigned tadrs; union { unsigned u; struct stentry *p; } tsize; unsigned tdimsz; unsigned tmul; /* "multiplicity"--how many occurrences of * the item in question are in this array * (if it is an array) */ }; /* types in addition to those listed in cdb.h */ #define VALUE 8 /* the returned value is the actual result, * not the address of the desired result */ #define BAD 255 /* invalid in some way */ /* * #define DEBUG 0 char debug; * */ /* To allow breakpoints at the return point from a function, atbreak changes * the actual return address on the target stack. The trace table "tracetab" * keeps track of where all the active functions really need to return. */ struct traceentry { char *taddr; /* return add table, except: * the name is the LAST 8 bytes, not the first * the "stsize" field has been massaged to some extent * The name is last to enable cdb2, when searching for a local symbol, * to scan through the symbol table until a symbol with a name ending with * an 0xff byte is found (this marks the end of the locals for a given * function); because the symbol table is built down from the end of the * fn table, and I wanted to avoid wasting a whole record at the end * of each function, the name had to be at the end. (unclear, but * think for a while). */ struct stentry { char stb1, stb2; /* descriptor bytes */ unsigned stadrs; /* relative address of variable */ unsigned stsize; /* if struct def: size of struct * if struct ref: -> struct def */ unsigned stdimsz; /* 2d dimension of array, or 0xff00 if 1 dim */ char stname[8]; /* str7 */ }; /* macros to extract information for descriptor bytes */ #define PTFNF(s) ((s).stb1&0x80) #define TYPE(s) ress */ unsigned tsn; /* statment number within caller -- used only by * list trace command */ }; char trace_full; /* true iff we're more than MAXTRACES deep into * subroutine nesting and tracing is turned off */ int ntraces; #define MAXTRACES 512 struct traceentry tracetab[MAXTRACES]; #include /* Copyright (c) 1982 by J. David Kirkland, Jr. */ #define CDB2ADDR 0x7f00 /* where cdb2.ovl code sits; run-time tables * grow down from here */ #define RST_NUM 6 /* restart number for debugger breaks */ #define CDB2_FILE "CDB2.OVL" /* name of CDB2 overlay file */ #define CDB2_DRIVE "" /* default drive for CDB2.OVL */ #define NOBREAK 255 #define COPYRIGHT "Copyright (c) 1982 by J. David Kirkland, Jr." /* each function in the target program has an entry in the function * name table. The primary source of this information is the .SYM file * produced by l2. Each entry  (((s).stb1&0x70)>>4) #define CHAR 0 #define INT 1 #define UNSIGNED 2 #define LONG 3 #define FLOAT 4 #define DOUBLE 5 #define STRUCT 6 #define FUNCTION 7 #define STELT(s) (((s).stb1&0x08)) /* 3 is it a structure element ? */ #define FORML(s) (((s).stb1&0x04)) /* 2 is it a formal parameter ? */ #define WHAT(s) (((s).stb1&0x03)) #define VARIABLE 0 #define FUNCDEF 1 #define STRUCTDEF 2 #define FUNCREF 3 #define LIND(s) (((s).stb2&0xc0)>>6) /* levels of indirection */ #define CLEV(s) (((s).stb2&0x3f)) /* "defining block" -- only before * build has processed the entry */ /* after symbol table is built, CLEV is replaced by : */ #define LOCAL(s) (((s).stb2&0x02)) /* 1 is it local ? */ /* only applies if a structure ref: */ #define SPTR(s) (((s).stb2&0x01)) /* TRUE -> stsize is a pointer to * structure definition * FALSE -> stsize is size, in bytes, * of structure */ in the table is a struct fntentry. * */ struct fntentry { char *fntaddr; /* -> first code byte (the RST n 0x0000) * in the function */ char fntname[9]; /* function name, null terminated */ char fntbreakindex; /* index into the breaktab array; * if any breakpoints are set in this function, * breaktab[fntbreakindex] is the first break- * point; if none, value is NOBREAK */ struct stentry *fntst; /* -> first symbol table entry for local symbols * of this function or NIL if none */ unsigned fntfsize; /* number of bytes in stack frame */ }; #define ORIGIN BASE /* CP/M base page */ #define NIL 0 /* NIL pointer */ /* #define TYPE 0x70 #define STELT 0x08 #define FORML 0x04 #define WHAT 0x03 #define LIND 0xc0 #define CLEV 0x3f */ /* every symbol table entry corresponds to either a variable (be it a local, * a global, a formal parameter, or a structure element) or a structure. * The format is basically that of the CC1 produced symbol cc cdb.c -e3200 cc build.c -e3200 l2 cdb build ;usage: A>submit lcdb2 (where is CDB2ADDR from CDB.H) l2 cdb2 dasm atbreak command break print parse util -ovl null $1 -wa ;usage: A>submit cc2 [d:] (see "constructing CDB2") cc $2cdb2.c -e$1 -x cc $2atbreak.c -e$1 -x cc $2break.c -e$1 -x cc $2command.c -e$1 -x cc $2print.c -e$1 -x cc $2parse.c -e$1 -x cc $2util.c -e$1 -x * b{204w{ÖüH!K]jU 2͵ ^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2hZZk:h|/g}/o#|/g}/o#:h<2hqDM!xxGyO_##ͧ ̓_ 6̓_ w#w̓_6#6!a ^#Vr+s0 ̓c| !_ ^#V{_zWr+s6#6!> ̓_##ͧ ̓_ !e9SYMCan't open %s C.CCC%x %s %x %s %x %s %x %s NEVER!9DM!X ~#fo͐T)~#fo##!X ~#fo͐T)~#foͧ ͐Zw#w͐T͐Vo !X ~#fo͐T)~#fon}- !T ^#Vr+so a !O !X ~#fo͐T)~#fo͊!| ͐Z6#6o a !X ~#fo͐T)~#fon}a !X ~#fo͐T)~#fo͐Z##͐Z~#fo))))ͧ !Q ͐Z##͐Z^#Vr+s))))!T ^#Vr+sÅ ͐Z~#fo|? ͐Z!2‘ !U Ô ![ !b 9!͐Z~#fo| !F`iͰ.| `i͐Z##͐Z~#fo))))ͧ ! ͐Z##͐Z^#Vr+s))))!*.Þ ͐Z~#fo|) ! 9!? ͐Z~#fo|? ͐Z6#6͐TF !P90CDBlocalglobalEnter %s symbol files, one per line (null line to end) *CDBError: too many files !9DM͐n&"|! ^#Vr+sn&"| ! ^#Vr+sn}/͐n}/! ^#Vr+s!͐n}͝M͐n&H"|ͣM! ^#Vr+sn}͝!9DM!"3"2! ~#fo##~#fo! 3ͧ !! )v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2hZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! P!9~#A!9"w**w"j!z*"d!"f!Y"H>2^>2a>2`2c>2s2t>2r>2v!"@!"D!@"B!"F !F#x:~#!|2i~# :" 2i +}|~#:G:ix."2i+w# +6#!6#@A2n2?*j**|+`!#"0!#"2!>ڌo&͖=}  w~2ʸͼ56!+W ?_!~7z?ͧ:>͞@w#5.ww#w#w#w*>?@͌>w#͌5> w#@ͧ͵g 2q&0OxG͵j/ʆSx\͞.7:77!a{  ʨ ʨ0:?ŷO !y$ 7o&))T])))!y 2p_ :p3! 3!2ͧ ͐ !s#r`i6#6͐͐Ҁ! ~#fo͐)~#fon}%Àt! ~#fo͐)~#fon}-V! ~#fo͐)~#fo#n}L3!2͐͐͐D `is#rS! ~#fo͐)~#fo#n}Gr!3͐͐͐D `is#rS! ~#fo͐)~#fo#n}D5͐ ! ~#fo͐)~#fo##s#rn}`i^#Vr+s͐!9!͐ ! ~#fo͐)~#fos#r͐ ~#fon}2͐ ~#foͷ |2͐ ~#fo!9!͐ !s#rS! ~#fo͐)~#fo!9!t! ~#fo͐)~#fo!9!`i^#Vr+sè͐ ~#fon&H"|ʧ!͐ ~#foy"!9CDB0/C:-d operand omitted Invalid -d option %s 0/C:invalid argument %s invalid argument %s :!9DM!͐+++!/! 6#6͐͐+++s#r! 6#6! ^#Vr+sn`is#6`i^#Vr+szʎ! ^#Vr+sn}%ʎj͐|ڳ͐!͐#/͐|!!l/! 9!!~!Ͱ.`is#r!͸͐!l/!9Enter command line args: !9DM!͐+++!l9!͐͐͐͐!9!top of target stack }o|ͣ͐#n}͝! s! n}`in}!9`in}3! n}3!9!9!9,6<U} !+17MOVMEUCASSTRCM !9DM!! ͐! 6! * 4`is#r͐~#fo#|~͐##! |k͐Ä`i^#V{_zWr+s@!Ä! 9 #4L[bi|STR7CMh!9DM* 4`is#r͐͐Y͐͐|F͐_`i^#V{_zWr+s!_!9%6=DW]MOVME!9DM͐#͐#n&|g}o͐#n&?|g}o|ͣ)s!! ^#V{_zWr+s͐͐n&!9DM͐͐n&s s{! ^#Vr+s!9DM͐n}( ͐n}.( ͐͐n&s s! ^#Vr+s! ^#Vr+s6.͐͐ͧ !9DM̓k! ͧ ! ! `i! #|• ! ! 9!! ̓i!_ s#r!_ ^#V{_zWr+sw#w̓_" 4! ̓_##ͧ !C !] !/ ![ ! !Y ! !W !% `iQ!!9!c s#r!c ~#fos#r!a w#w̓a̓cҾ !_ ^#V{_zWr+s̓a)!W ~#fos#r̓ak! ̓ is %04x, cdb2 is at %04x globals use %04x bytes, locals use %04x bytes !9DM!,!Y9!͐4|!m9!!9!w/!6 ~#fo##~#fo! ͧ ! !H ! s#rz4w/! ͐6͐4Q͐,! s#rzcw/͐! s#rz}w/͐*4* 4͐$͐! ͧ !! y"!! "#|! !9!w/!! ! 6#6͐͐*4* 4! !! 9~#fo!09Copyright (c) 1982 by J. David Kirkland, Jr.c debugger ver 1.2 usage: cdb target_name [-g [global_fns | 0]] [-l [local_fns | 0] ] [-d [usr/][drive] ] [ %% [target arguments] ] CDB2.OVLCouldn't swapin %s COM!9DM!"4͐ n}t!͐ z/"4#|H͐ !W9!!N!*4*4/+|t͐ !f9!!N*4#"4+n`is#6`i~#fo*4#"4+n&s#r͐++͉+! s#r͐͋0! s#r͐͐͐ !x9!!N͐ n}G͐|G͐͐*4~*4/G͐ !9!!N͐N!9can't open %s read error on %s %s is to͐`i͐+k!+ s#r͐! s#r͐+! s#r! n&?|g}o|`in&|g}o|`in&|g}o++|͐`i͐+!+ s#r! ^#Vr+s͐+#!'9!9DM͐" 4`iw#w͐*3e͐|µ*3|µ͐)))) 3! s#rzŠ!ü͐͐ ! s#r*4͚0`i^#Vr+sE͐ü!9!9DM͐ "4`iw#w͐*2͐|c *2|c *3| *2| >22͐))))2! s#rz8 !j ͐͐ ͤ! s#r*4͚0`i^#Vr+s͐ j !9!9DM! n&C#|ʚ ! n&á ! n&&!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{ ù ͐ !9!9DM͐!͐z/s#rz!!͐##w#w͐6͐~#fo!9DM!.! r#!j9DM͐`iK'|q!!Á!! `i?(Á!!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}!! ~#fo`i^#Vr+sn}!!"Ø!! ~#fo͐n! ~#fo͐nѯgW"!9!9DM! n&|ͯD"! n&|ͩ!9DM! n&K+|ͣu"! n&C#|ͣ!9Do large (%d bytes); max is %d bytes read error on %s !9DM`i6`in&|! ~#fo`in&*4#"4+ns`i4`i6`in&|)! ~#fo`in&*4#"4+ns`i4*43! 9!9DM͐! ^#Vr+sns!|g}o|x! ^#Vr+sD͐͐ng|g}os! ^#Vr+s6!9DM͐n͐n}͐ng|g}o|͐n}!! ^#Vr+s! ^#Vr+sè͐ng|g}o͐ng|g}o%!͐ng|g}o͐ng|g}oS!͐n&|g}o|ͣv͐#n}͝`is͐n&|g}o|ͣ͐#n}͝! s! n}ʻ`in}»!`in}! n}!!!9!9DM!! ͐/! 6! ͸* 4`is#r͐~#fo#|T͐##! ͊!|A͐Z`i^#V{_zWr+s!Z! 9!9DM* 4`is#r͐͐ڶ͐͐͠|£͐ü`i^#V{_zWr+st!ü!9!9DM͐#͐#n&|g}o͐#n&?|g}o|ͣ)s!! ^#V{_zWr+s͐/͐n&|g}o++|[͐ 6͐ #͐s#r͐b!9!9DM! ^#Vr+s6M͐`is#r͐n}ʣ"! ^#Vr+sË"! ^#Vr+s͐ns! ^#Vr+sn}£"͐"!9!9DM!͐z/`is#rz#!:#!͐͐/|+#͚͐0!:#͚͐0!:#!9!9DM! n&|ͯn#! n&|ͩ!Y9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{B'`in}%'! ! s#r! 6#6! s! s! s͐n}-$! ^#Vr+s! 4͐n}0$! 4͐n&"}/$! ,2$!! s#r! ^#Vr+sn`is{.z$! ,! s#r! 4! ^#Vr+sn`is`in&s }Dʦ$U$X$O$C:%Sk%&͐~#fo|$! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 $! 6$! 6! ~#fo! n&! ^#Vr+s~#fo! z+ѯgs#r%! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s%! n}~%! 6#6! ^#Vr+s~#fo! s#r͐n}%͐|%! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+sÙ%͐6! ! s#r! n}Q&! ^#Vr+s!|Q&͐͐! n}.&!01&! !?&!9~#fo#|N&!B'%͐n}ʕ&͐͐! ^#Vr+sn&!&!9~#! ~#fo++s#r! s#r͐ ͐s#r͐`i<`i! s#rz͐  ͐s#r͐ ͐##~#fos#r͐!9!9DM!& ~#fo͉s#r͐$! s#r! w#w͐͐&`iͷ! s#r! n&?|g}o|²`in&|g}o|ʗ`in&|g}o++|²͐`i͐$!$ s#r! ^#Vr+s;! ^#V{_zWr+s͐͐$s͐n&|g}o|^͐n&p|g}o|^! 6#6͐͐͐~#fo))))#~#fos#r͐#n&|g}os! ^#V{_zWr+s͐$z! 9!9DM͐6͐6͐#6?!9DM!- ~#fo͉s#r͐+! s#r! w#w͐͐-͐͐-`i̓`iͷ! s#r`in&|g}o+|¶! ^#V{_zWr+s! s#r͐͐+ڀ͐n&|g}o|k͐n&p|g}o|k! 6#6! 6͐͐~#fo))))n}͐͐͐~#fo))))#~#fos#rQ͐+͐͐~#fo))))c! s#rz͐͐s#rQ͐͐͐~#fo)))) ~#fos#r! 6͐#n! nѯgW|g}os! ^#V{_zWr+s; fo#|’&!B'Q&! n}&! ^#Vr+s!|&͐͐! !&!9~#fo#|&!B'ß&'͐͐`in&!'!9~#fo#|'!B'?'͐͐`in&!0'!9~#fo#|?'!B'á#!9!9DM`i6#6͐ ! s#r͐ y,! s#r!|ʊ'͐#|'!6(! ^#Vr+s͐s{ '͐͐ #'͐++n} '! ^#Vr+s6 (`i^#Vr+sz (͐ y,! s#rz (͐|'͐|)(͐ ͐E-͐6͐ 6(!9!9DM! ^#Vr+s~#fo! s#r͐! s#r! 6! ^#Vr+sn! s{8+! n&ͳ-|ʡ(t(! n}%(! n! -(! n&B+(! ^#Vr+s!+! 6#6! 6 `i6! ^#Vr+sn! s{*#)`i4! ^#Vr+sn! s! n&s }XQ)OZ)Dc)Uʉ)S*Cʨ**! 6É)! 6É)! -|‰)! 6#6! ^#Vr+s! w#w! n&! -&.#|¸)! n&B+! n&! ^#Vr+sn&&.! s{*͐ ! nѯg?! nѯg! s#rø)! ^#Vr+s*! -͐ ~#fo! s#r! ^#Vr+sn! s{ʆ*! n͐n}f*! ^#Vr+sÆ*`in}ƒ*! ^#Vr+s! n91'*O&))) "c*K*c~#foӀ*P*c##~#foӀ*c"cà*K*c~#fo *P*c##~#fo *c^#Vr+sz!%*c6#6!!9DM͐^#Vr+s! s#r~#fo`is#rz*f|ډ*e}†!!`!؂`>2e΁*f))h͐ ~#fos#r*f#"f+))h##*Ps#r͐ !s#r͐͡"K n}2O͐ "M͐"P*T}4*R+|4*K##!`͐͐~#fo!`*R|H*R+"R|a|a*O}ʤ͐|ʤ!"R>2T*K##!`͐͐~#fo!`͐"Iڎ͐`!9fn trace table full (size is %d); fn tracing inactive trace: %s [%04x] break at %s [%04x] !9DM*e}9!6`>2e!"P*O}ͣV͐|ͣx*R|ͣp*R+"R|͝x|ͣ! s{‹*T}! n}ʛ!PÞ!R`͐͐*K##!]`͐͵͐|g}o͵!x`! n}ڎ*f+"f))h~#fo`is#r͐͡"K n}2O!"M͐-!9fn tracing now restored. trace: %s returning %04x = %d = '' !s.*`in}¥*! 4͐6! ^#Vr+st(`in}*͐n&! ^#Vr+s~#fol/! 4! ^#Vr+st(! n&B+`in}!+! ^#Vr+s~#fo͐ ͐?s#r! 4͐n}5+! n&B+t(! n&B+!9!9DM! n&|ͯv+! n&|ͩ!9DM͐͐ +͐^#Vr+s͐ڵ+͐0ý+͐7s!&,͐ ͐͐ ͉͐z+`is͐ ͐͐ )͐z+`in&#&,!9!9DM`iw#w͐~#fon&"}i,͐ ?͐^#Vr+snѯg`is#r*,͐p,!9!9DM͐|,͝0<-͐+++|§,!0<-͐##^#Vr+s|%-!͐͐~#fo/`is#r!|,͐##^#Vr+s<-͐##͐?+s#r͐͐s#r͐^#Vr+sn&<-!9!9DM͐|d-! n&0͐҂-͐##~#fo|‡-!͐^#Vr+s! ns͐##^#Vr+s!!9DM! n} ͝-! n} ͝-! n} ͝!9DM͐~#fon`isͳ-|.͐^#Vr+s-`in&.!9!9DM! n&s ! sH"|^.! n&sÆ.! n&"}ʁ.! n&sÆ`!&`!B`!g`!`!`!`!`!`!ԅ`!`!`! `!,`!N`!`!`!ކ`debugger commands are: b[reak] [fn] [sn [count]] clear all breakpoints , d[ump] p[rint] contents of memory g[o] l[ist] l[ist] a[rgs] l[ist] b[reaks] l[ist] g[lobals] l[ist] l[ocals] l[ist] m[ap] l[ist] t[raceback] quit exit to CP/M r[eset] [fn] [sn] a breakpoint run start execution, debugger off s[et] var val [c] a variable t[race] [num] execute num statements, displaying sn's u[ntrace] [num] execute num statements, silently !9DM͐#|1!p`n͐|g}o!s`͐|g}o|n͐ !v`-1%d.%d!9DM`iw#w͐*͐))) ~#fo##!`͐))) ##~#fo͐))) ~#fo+|͐))) ~#fo!"` ! R`i^#Vr+sÈ!9%s (%d) !9DM͐ `i! `in&x>\>ʧ>ah>Ɉ>gt>ʩ>l€>ʴ.!! n! n&+ҥ.!î.! n&O  9q  #F#Hx.~#.i&  / > _ / 7*T|DM*R*PJ/><>/~# x>/ > 2h*P/:q2> /:h):R/=/=> /:qw#w#w:ho&552?7:P)V>څ0z>ʅ0z2:P,"j!"l*T|*l05*R*j!ѷN02?H0H0!0*l0*T+"T*R"R*l#"l*j! N#Fp+qx 0##6>2?02?*:+#:noʬ02n& !o 0 . &7:PO*R:no2n&!9DM!͐6"[͐4"W"Y!"U*U"U>2e!"f*U"K!"P!"R!* 6#6͐*~#fo!, s#r͐,#!* s#r͐*~#fohu͐2`i͹#|ʪ`i!|µ!H`!( 6#6͐(!`i!|!( ~#fos#rþ"]!( 6>#6͐(6!!.9Copyright (c) 1982 by J. David Kirkland, Jr.no target file on disk "!{"1>20! >mŒ>>t˜>>b¤>*K##!`*P! R*K ~#fo|߈Пæ*M|*K##!`æ*M!S`*M####~#fo*M####~#fo*M##~#fo*M##~#fo*M~#fo*M~#fo!s`!9*M ~#fo*M ~#fo*M~#fo*M~#fo*M~#fo*M~#fo!`!9*YJ*K ~#fo|׉*K ~#foJ߉!ي`7z!`! 9current location: %s can't list args to %s because it has called a function first argument address is %04x [1] = %04x = %d, [2] = %04x = %d, [3] = %04x = %d [4] = %04x = %d, [5] = %04x = %d, [6] = %04x = %d local symbols not available illegal list subcommand !9DM`i6#6͐*fҭ͐))h##~#fo#|ʂ͐))h~#fo͡##!ŋ`͐))h##~#fo!ɋ`á͐))h~#fo͡##!ҋ``i^#Vr+s*K##!݋`!9%s called %s called %s !9DM͐n}*! ^#Vr+sn&x͐n&x*! ^#Vr+s͐n}͝!9DM͐`i͐! s{o!R`!I׌! n}0Š͐*6*U! s#r͐~#fo#|ߔ͐ n}ʔ͐ n͐ʔ͐ 5! ^#V{_zWr+sÍ*))) 6#6*K n}2O!!9%s %d is not a breakpoint !9DM!"!" *U`is#r͐~#fo#|l͐ 6`i^#V{_zWr+sA!9!9DM$!߷`is#rzʧ!!͐!9MAIN!9DM! n&|ݕ! n&|!.R! n&R!9DM͐!8`͐~#fo|$!B`6͐~#fo!G`[%04x] = NIL %04x !9DM͐n&͐!`͐n&͵!`[%04x] = %02x = '' !9DM͐~#fo͐~#fo͐!`͐~#fo|g}o͵͐~#fo͵! `[%04x] = %04x = %6d '' |(!!}2*&!9DM͐n}|Q͐n&||͐n&||͐n}\ܗ͐n} ʙ ʤ ʯ\ʺŗ!ͬٗ!ͬٗ!ͬٗ!ͬٗ͐n&!`ٗ͐n&R! ^#Vr+s9\n\r\t\\\%o!9DM͐ظ͐!<`͐1!M`%04x (len %d): "" !9DM͐! s#r`iw#w͐͐Ks#r׌͐`i߷s#rz³`i!e`!I͐`i͐|׌͐w#w͐~#fon}.I͐^#Vr+s! `i͐|)`i͐~#fo!x`!I͐~#fo͐  |g}os#r! 9arguments missing %s does not exist invalid statement number %d.%s !9DM`i! ! 8#|! ! ! |! 6#6͐͐͐!9!9DM`i! ! 8#|.͐͐+!9!9DM! w#w*U`is#r͐*Wҹ͐|g}o|! R͐~#fo͐##!ʎ``i^#V{_zWr+s! ^#Vr+sT! R!9%-8s %04x !r9DM{2T&"R>2!>R! %`is#r! ! `i! n&x>b5>>cA>>lM> >qY>>re>6>gq>j>t}>p>w‰>u>u•>u>s¡>ʜ>?­>ʨ>h¹>ʨ>,ŏ>ʮ>dя>ʮ>pݏ>ʮú͐͘!ΐ! |uú͐+!Ԑ! |03ú!ِ! |U͐!!0!ݐV$Ր>2T!R! `iǙ|ʐǙ͐))))! ~#fo͐))))!Й`͐͐))))!! s#r! w#w͐|c͐|g}o| ! R͐͐D! ~#fo͐))))͐n&!ۙ`U͐|U!`! ^#Vr+s!`! w#w͐͐ҳ! ~#fo͐))))͐n&͵! ^#Vr+ss!``i^#Vr+su!9%04x [%3d]%02x '' !9DM`iw#w͐͐Л|Л͐! ~#fo͐)!ٛ`! w#w͐|Ҧ͐͐͐҇! ~#fo͐͐)~#fo!`Ø͐|ʘ!`! ^#Vr+s;!`! w#w͐|!͐͐͐! ~#fo͐͐)~#fo!`͐|!`! ^#Vr+sö!`! w#w͐|ҵ͐͐͐Xõ! ~#fo͐͐)~#fo|g}o͵! ~#fo͐͐)~#fo͵! ^#Vr+s1!``i~#fo####s#r!9%04x [%3d] %04x = %6d '' !9DM`iw#w͐͐Ҝ|/Ü͐! ~#fo͐)!`! w#w͐|͐͐͐Μ! ~|ʖ!"RՐ͐O{͐!`!9clearquitrun##illegal command !9DM*|!(!`!͐  n}>͐  n! s#6F! w#w͐))) `is#r͐*đ͐ ͐~#foڤ͐ ͐~#fo§͐ ͐##~#foڧđ`i^#V!r+s! ^#Vr+sW͐ ͐~#fo͐ ͐##~#fo*#"+͐)))͐͐V͐͐ s#r͐##͐ s#r͐͐s#r*U! s#r͐~#fo#|ʥ͐ n}ʐ͐ n͐ڐ͐ 4! ^#V{_zWr+sS͐  n}˒͐  n͐ے͐  ͐s*))) 6#6*K n}2O!!9too many breakpoints (maximum is %d) !9DM͐  n}W͐  n! s#6_! w#w͐))) `is#r͐*ݓ͐ ͐~#foڽ͐ ͐~#fo͐ ͐##~#foݓ`i^#V!r+s! ^#Vr+sp͐ ͐~#fo͐ ͐##~#fo#͐ ͐ ##! `!*+"#͐)))͐͐V͐  n͐‚͐~#fo͐ ʂ͐   #fo͐͐)~#fo|¦!`˜! ~#fo͐͐)~#fo!`ߜ͐|ߜ!`! ^#Vr+sW!Ý`! w#w͐|ҁ͐͐͐$Á! ~#fo͐͐)~#fo|g}o͵! ~#fo͐͐)~#fo͵! ^#Vr+s!ŝ``i~#fo####s#r!9%04x [%3d] NIL %04x '' !9DM͐! ͛! !-``i͐̀! s#r!!`i͐͐͆!9%-11s!9DM͐ ܫ! s#r! w#w͐͐<|t*}w<͐|ڒ͐!E`! R͐ ##n}͐ ~#fo`is#r`i^#V{_zWr+sn}͐n&|g}o|͐ ͐ȝø͐ ~#fo͐ P! ^#Vr+s! ~#fo͐s#rT!9[%u]!9DM͐n}Ο>2͐n&|g}o|¢͐n&|g}o|¢!͐ȝ*}ʹ*} ʹΟ! ^#V{_zWr+sR!9DM*K ~#fo`is#r͐n}O͐n&|g}o|O|O͐n&|g}o|2`i6>! ^#Vr+s! ^#Vr+s`ins͐ 6͐ ͐s#r`in&a!9integer too long %d%x!9DM! n&|ھ! n&|Ҿ! n&!ѫ`ϫ! n&!֫`'%c''\%o'!9DM͐###n}͐n}!]͐#n}E͐##n}4͐~#fo~#foB͐~#fo]͐#n}X!]!!9DM͐ `is#r͐ n&|###nѯgWҠ!*R! 4x͐#n}ʾɠԠߠ,!V`,!Z`,!_`,͐##n}͐~#fo`i͛`i!h`)͐~#fo!r`,! 9pointer to a function returning intcharunsignedstruct %s(%d byte structure)!9DM͐| ! n} ͐ ~#fo| ͐n} ͐ ~#fo|͐ ~#fo!d`͐X! R! n&͐͐͐ ͐͟ ~#fo! s#r͐ ~#fo͉͐! s#r͐͐!{`͐X! R͐ ~#fo͐ܫk! s#r`iw#w͐͐|»*}ʾ͐!`! n&͐͐͐ ͐͐k͟`i^#Vr+sÛ[! n}=͐#n}=͐###n}=!`͐X! n&͐͐͐ ͟!9a %d element array of a %d x %d array of row [ %u ] a !9DM͐#n}µ! n}͐###n}գ! 6p͐#n}! 6c͐#n}! 6t! 6w͐|!͐ ~#fo! s#r! n&x>p9>x>cE>ʣ>sQ>Τ>t]>ڤ>ii>>wu>͐g}o|͐n&|g}o|ʴ͐##~#fo! s#r͐ `is#r`i^#V!r+sn&|g}o++|þ͐~#fo! s#rĭ͐n}K͐n&|g}o|8͐n&|g}o|K`i^#V{_zWr+s͐n}²͐ #n&|g}o|ʛ͐! s#r͐~#fo! s#rïͲ! s#rĭ͐##~#fo! s#r͐͐ ##~#foۭ!9!9DM͐͐n&|g}os͐#͐n&p|g}os͐##͐#n&|g}os͐###͐#n&|g}os͐͐n&|g}os͐͐##~#fos#r͐͐~#fos#r͐ ͐~#fos#r͐ ~#fo|͐n}͐ ͐_͐ܫs#r͐ 6#6!9DM͐~#fo! s#r! `i͐! s! n}*͐! n&͐! s#r͐ ~#fo! s#r͐###n}ʢ͐###5͐ ~#fo|͐#n}ٯ! ~#fo|g}os#r͐#6͐ b9! n! n}$!k`! n&͂! R͐#6b9! n}9͐#6b͐͐ s#r͐! n&͐b!9empty expression at |ڗ͐͐à͐͐|¤͐͐Pˤ͐M͐͐͐͐3͐|͐͐͐͗!9DM͐&! s#r! ! !& ! s{&͝! s}}! n}q?}͐!& s#r! !!& `is#r! n}¥?! n}͐!H`?! w#w! 6! ! !& ! s{!! n}a! n! s! n}0͐! s#rΥ! n&͐! ͐͆!"9 %04x !9DM! !!" ! s#r! n}n! `i!" ! s! n}'! `i!" ! s`in! s#6! `i!" ! n}0͐ ! s#r!w`n! n}#! n}#! n}N! `i!" |``in&x|`͐ ͐ͧn͐͐ s#r!9invalid new value!9DM! n&<|ͣ! ng|ͯ˧! n&|ͩ! ng|ͯ! n&|ͩ!9DM͐n}\͝! s!! ! ~#fo! n&V! 6! `iP! n}§*K ~#fo! s#rzʧ͐n}ʧ͐`i !9DM͐͐͐n&|g}o|ʵ`iw#wP͐#n&|g}o|G*P|*I `is#r`i~#fo*K~#fo##s#r*I##~#fo`is#r͐n&|g}o|D`i~#fo*K~#fos#rP*]`is#r͐͐~#fof!9!9DM͐`is#rz–͐#6è͐͐̀è!9!9DM͐%n}ݱ͐#͐#~#fo~#fos#r! !]͐!`is#r! n} ͐%#6͐#! ͐!! n}3͐;͐~#fo! s#r! n}n! n}n! ~#fo|g}os#r͐%ܫ! s#r͐% ~#fo|ݲ! ~#fo͐% ~#foks#r͐% ͐% ~#fos#r͐% 6#6͐% 6#6͐% w#w͐#~#fo͐͐?s#r!9!9DM! n}>F͐͐~#fo~#fos#r! `i͐`i! s#rzx͐#6ͳ͐ n&|g}o|£`i!ֳ`͐#6ͳ͐~#fo͐ ##~#fos#r͐͐ !9%s is not a structure element !9DM! `i͐! s! n}(S͐!)͐! s#r! `i͐ٴ! n}av͐`io! s#rٴ! n}0³! ^#Vr+s~#fos! ^#Vr+s! n}¹! 6#6! ^#Vr+s~#fo! s#r͐n}͐|! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+sԼ͐6! ! s#r! n}Œ! ^#Vr+s!|ڌ͐͐! n}i!0l! !z!9~#fo#|‰!}:͐n}н͐͐! ^#Vr+sn&!!9~#fo#|ͽ!}Ì! n}! ^#Vr+s!|͐͐! ! !9~#fo#|!}ڽK͐͐`in&!S! n}.t͐! ͐! n&ɵ! n}0ʕ! n}'ʕ! n}a›ܵɵ! n}µ!8`! n&͂! R͐#6͐~#fo! s#r͐͐ s#r͐ !9invalid primary at token %s, identifier or integer expected invalid primary at token !9DM! n&Ͷ!9DM͐͐n&s{ʙ! ^#Vr+sr!9DM͐! ^#Vr+sns!|g}o|׶! ^#Vr+sã͐͐ng|g}os! ^#Vr+s6!9DM͐n͐n}I! ^#Vr+sng|g}o|;!! ^#Vr+s!!9DM͐n}ʃ! ^#Vr+s! ^#Vr+snsX! ^#Vr+sn&|g}os!9DM*U"_͐"a*a*_"_~#foԷö*_ !9DM!! ͐V! 6! j*U`is#r͐~#fo#|Q͐##! |>͐W`i^#V{_zWr+s!W! 9!9DM!R! ͭ!9DMs{ʬ͐ ! nѯg?! nѯg! s#r]! ^#Vr+sÓ! ͐ ~#fo! s#r! ^#Vr+sn! s{+! n͐n} ! ^#Vr+s+`in}(! ^#Vr+s! ns`in}J! 4͐6! ^#Vr+s`in}{͐n&! ^#Vr+s~#foͧ! 4! ^#Vr+s! n&`in}! ^#Vr+s~#fo͐ ͐?s#r! 4͐n}! n&! n&!9!9DM͐͐ >͐^#Vr+s͐+͐03͐7s!&É͐ ͐͐ ͉͐`is͐ ͐͐ )͐`in&#&É!9!9DM`iw#w͐~#fon&<}͐ ?͐^#Vr+snѯg`is#rà͐!9!9DM͐~#fon`isk|͐^#Vr+s`in&&!9!9DM! n&! s͞|g! n&sÏ! n&<}ʊ! n&sÏ!! n! n&+Ү!÷! n&7*R~# +*P&!7:PO*R *7*X*VDM:R! *P*T:n&o !, !j96  #F#xQ~#Dį7*T|DM*R*Pڅ><~+ x•|}7*P:Rw* _   RESUMEIINITRSATRENkITAL RESEARCH SID VERS 1.4$10 !~=W!xe ~#Xbxʇ {z~#o}o҃i.g> >کÝ!p+q*DM͡:͆ ͆:_2:`!!:*& N͆!4!6JÃO$+q+p+qy͏ , $  ͌ 9!z6 # L!zw͌j# X:z 0 ͘=N#Fy}80*z{¯#z+++ ¥ z#½# · 9!`͠ y9!rͷATBREA(""!"1>20!91 &ATRETUR !Eͷ~P !ͷ’P͌Q!ͷªP}QxQ!ͷ͓G@Q! ͷ y͓Gþ!ͷ ͓Q!ͷ/* ******** * L2.C * New linker for BDS C ******** Written 1980 by Scott W. Layson Modified 1982 by David Kirklfuncts; /* no. of functions in table */ int maxfuncts; /* table size */ #define LINKED 1 /* (flinkedp) function really here */ #define EXTERNAL 2 /* function defined in separate symbol table */ char fdir [512]; /* CRL file function directory */ /* command line parameters etc. */ int nprogs, nlibs; char progfiles [30] [15]; /* program file names */ char libfiles [20] [15]; /* library file names */ int deflibindex; /* index of first default (DEFF*) library */ FLAG symsp, /* write symbols to .sym file? */ appstatsp, /* append stats to .sym file? */ sepstatsp; /* write stats to .lnk file? */ #ifdef MARC FLAG maxmemp, /* punt MARC shell? */ marcp; /* uses CM.CCC */ #endif char mainfunct[10]; FLAG ovlp; /* make overlay? */ char symsfile [15]; /* file to load symbols from (for overlays) */ /* C debugger variables */ FLAG Dflag; FLAG SysStat; /* TRUE if "-s" option given & now active */ int SysNum; /* index into libfiles of "-s", or -1 if none */ FLAGand This code is in the public domain. This is an improved linker for BDS C CRL format. It supports the c debugger. Compilation instructions: cc l2.c -e4C00 (use -e4900 if linking with L2.COM) cc chario.c clink l2 chario -ns (or) l2 l2 chario -ns */ /**************** Globals ****************/ /* The DEF_DRIVE macro is used to define the drive from which L2 will * load C.CCC, DEFF.CRL, DEFF2.CRL, and DEFF3.CRL (if it exists). The * macro takes as an argument the filename and extension, and "returns" * the name with whatever drive designator is needed. The macro also * encloses the name in quotes; thus, the argument when the macro is * invoked must NOT be within quotes. * That is, to open C.CCC on the proper drive, we use the C code * if (ERROR==fopen(DEF_DRIVE(C.CCC), iobuf)) ..... */ #define DEF_DRIVE(fn) "fn" /* Make this "0/A:fn" for, say, user 0 on A */ #define SUB_FILE "$$$.SUB" /* submit file to delete on error exit... * if yo Tflag; /* TRUE if "-t" option given */ unsigned Tval; /* arg to "-t", if present */ /* useful things to have defined */ struct inst { char opcode; char *address; }; union ptr { unsigned u; /* an int */ unsigned *w; /* a word ptr */ char *b; /* a byte ptr */ struct inst *i; /* an instruction ptr */ }; /* Link control variables */ union ptr codend; /* last used byte of code buffer + 1 */ union ptr exts; /* start of externals */ union ptr acodend; /* actual code-end address */ unsigned extspc; /* size of externals */ unsigned origin; /* origin of code */ unsigned buforg; /* origin of code buffer */ unsigned jtsaved; /* bytes of jump table saved */ char *lspace; /* space to link in */ char *lspcend; /* end of link area */ char *lodstart; /* beginning of current file */ /* i/o buffer */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index of next char in buffer */ char buff [128]; } ibuf, obuf; /u use SDOS, use "a:$$$$.sub"; if you've * hacked your CCP, you may need to change the * drive designator letter */ #define RST_NUM 6 /* C debugger RST number. Should be identical to the RSTNUM symbol in CCC.ASM */ #define OVERLAYS /* comment this out for shorter version */ /* #define MARC /* for MARC cross-linker version (enables the "-marc" option) */ */ #include /* for i/o buffer defs */ #define NUL 0 #define FLAG char #define repeat while (1) #define STDOUT 1 /* Phase control */ #define INMEM 1 /* while everything still fits */ #define DISK1 2 /* overflow; finish building table */ #define DISK2 3 /* use table to do window link */ int phase; /* function table */ struct funct { char fname[9]; FLAG flinkedp; /* in memory already? */ FLAG fdebug; /* TRUE unless this routine required only by a lib function after -s */ char *faddr; /* address of first ref link if not linked */ } *ftab; int n * BDS C i/o buffer */ char symbuf[BUFSIZ]; /* seek opcodes */ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define TRUE (-1) #define FALSE 0 #define NULL 0 /* 8080 instructions */ #define LHLD 0x2A #define LXISP 0x31 #define LXIH 0x21 #define SPHL 0xF9 #define JMP 0xC3 #define CALL 0xCD /* strcmp7 locals, made global for speed */ char _c1, _c2, _end1, _end2; /**************** End of Globals ****************/ main (argc, argv) int argc; char **argv; { puts ("Mark of the Unicorn Linker ver. 2.2.2\n"); setup (argc, argv); linkprog(); linklibs(); if (phase == DISK1) rescan(); else wrtcom(); if (symsp) wrtsyms(); } setup (argc, argv) /* initialize function table, etc. */ int argc; char **argv; { symsp = appstatsp = sepstatsp = FALSE; /* default options */ #ifdef MARC marcp = maxmemp = FALSE; #endif ovlp = FALSE; nprogs = 0; nlibs = 0; strcpy (&mainfunct, "MAIN"); /* default top-level function */ origin = 0x100; /* defaulrgc) Fatal ("-ovl argument missing.\n"); strcpy (&symsfile, argv[++i]); sscanf (argv[++i], "%x", &origin); } #endif else if (!strcmp (argv[i], "-D")) Dflag = TRUE; else if (!strcmp (argv[i], "-W")) symsp = TRUE; else if (!strcmp (argv[i], "-WA")) symsp = appstatsp = TRUE; else if (!strcmp (argv[i], "-WS")) symsp = sepstatsp = TRUE; else if (!strcmp (argv[i], "-NS")) syslib = FALSE; else printf ("Unknown option: '%s'\n", argv[i]); } else { if (progp) strcpy (&progfiles[nprogs++], argv[i]); else strcpy (&libfiles[nlibs++], argv[i]); } } if (ovlp) strcpy(&mainfunct, &progfiles[0][2*(progfiles[0][1]==':')] ); if (Dflag || !syslib || SysNum!=-1) Dflag = symsp = TRUE; if (syslib && SysNum == -1) SysNum = nlibs; #define NDEFF 3 deflibindex = nlibs; #ifdef MARC strcpy (&libfiles[nlibs++], marcp ? "DEFFM" : "DEFF"); strcpy (&libfiles[nlibs++], marcp ? "DEFF2M" : "DEFF2"); strcpy (&libfiles[nlibs++], marcp ? "DEFFt origin */ maxfuncts = 200; /* default function table size */ Tflag = FALSE; /* no "-t" given yet */ SysStat = FALSE; SysNum = -1; Dflag = FALSE; cmdline (argc, argv); ftab = endext(); lspace = ftab + maxfuncts; lspcend = topofmem() - (1024 + 2100); if (lspace > lspcend) Fatal ("Insufficient memory to do anything at all!\n"); loadccc(); nfuncts = 0; #ifdef OVERLAYS if (ovlp) loadsyms(); #endif intern (&mainfunct); phase = INMEM; buforg = origin; jtsaved = 0; } cmdline (argc, argv) /* process command line */ int argc; char **argv; { int i, progp, syslib; if (argc == 1) { puts ("Usage is:\n"); puts (" l2 {program files} [-l {library files} ] "); puts ("[-s {library files} ]\n"); puts ("\t[-m ] [-f ] [-org ]"); puts (" [-t ]\n"); puts ("\t[-d] [-ns] [-w | -wa | -ws]\n"); #ifdef OVERLAYS puts ("\t[-ovl ]"); #endif #ifdef MARC puts ("\t[-marc]"); #endif lexit (1); } 3M" : "DEFF3"); #else strcpy (&libfiles[nlibs++], DEF_DRIVE(DEFF) ); strcpy (&libfiles[nlibs++], DEF_DRIVE(DEFF2) ); strcpy (&libfiles[nlibs++], DEF_DRIVE(DEFF3) ); #endif } loadccc() /* load C.CCC (runtime library) */ { union ptr temp; unsigned len; codend.b = lspace; if (!ovlp) { #ifdef MARC if (copen (&ibuf, marcp ? "CM.CCC" : "C.CCC") < 0) #else if (copen (&ibuf, DEF_DRIVE(C.CCC) ) < 0) #endif Fatal ("Can't open %s\n",DEF_DRIVE(C.CCC)); if (cread (&ibuf, lspace, 128) < 128) /* read a sector */ Fatal ("%s: read error!\n",DEF_DRIVE(C.CCC)); temp.b = lspace + 0x17; len = *temp.w; /* how long is it? */ cread (&ibuf, lspace + 128, len - 128); /* read rest */ codend.b += len; cclose (&ibuf); } else codend.i++->opcode = JMP; } linkprog() /* link in all program files */ { int i; union ptr dirtmp; struct funct *fnct; for (i=0; i=argc) Fatal ("-f argument missing.\n"); sscanf (argv[i], "%d", &maxfuncts); } else if (!strcmp (argv[i], "-L")) progp = FALSE; else if (!strcmp (argv[i], "-S")) { progp = FALSE; SysNum = nlibs; } else if (!strcmp (argv[i], "-M")) { if (++i>=argc) Fatal ("-m argument missing.\n"); strcpy (&mainfunct, argv[i]); } #ifdef MARC else if (!strcmp (argv[i], "-MARC")) { maxmemp = TRUE; marcp = TRUE; } #endif else if (!strcmp (argv[i], "-ORG")) { if (++i>=argc) Fatal ("-org argument missing.\n"); sscanf (argv[i], "%x", &origin); } else if (!strcmp (argv[i], "-T")) { if (++i >= argc) Fatal ("-t argument missing.\n"); Tflag = TRUE; sscanf (argv[i], "%x", &Tval); } #ifdef OVERLAYS else if (!strcmp (argv[i], "-OVL")) { ovlp = TRUE; if (i + 2 >= a printf ("Can't open %s\n", progfiles[i]); continue; } printf ("Loading %s\n", &progfiles[i]); readprog (i==0); for (dirtmp.b=&fdir; *dirtmp.b != 0x80;) { fnct = intern (dirtmp.b); /* for each module */ skip7 (&dirtmp); /* in directory */ if (!fnct->flinkedp) linkmod (fnct, lodstart + *dirtmp.w - 0x205); else if (phase != DISK2) { puts ("Duplicate program function '"); puts (&fnct->fname); puts ("', not linked.\n"); } dirtmp.w++; } /* intern & link it */ cclose (&ibuf); } } linklibs() /* link in library files */ { int ifile; for (ifile=0; ifile= lspcend) Fatal ("Module won't fit in memory at all!\n"); } lodstart = codend.b; if (cread (&ibuf, lodstart, len) < len) Fatal ("-- read error!\n"); } scanlib (ifile) int ifile; { int i; union ptr dirtmp; makeext (&libfiles[ifile], "CRL"); if (copen (&ibuf, libfiles[ifile]) < 0) { if (ifile != deflibindex + (NDEFF-1)) printf ("Can't open %s\n", libfiles[ifile]); return; } printf ("Scanning %s\n", &libfiles[ifile]); if (cread (&ibuf, &fdir, 512) < 512) /* read directory */ Fatal ("-- Read error!\n"); for (i=0; iflinkedp = LINKED; if (phase != DISK2) { finalloc.b = codend.b - lspace + buforg; if (phase == INMEM) chase (fnct->faddr, finalloc.b); fnct->faddr = finalloc.b; } else finalloc.b = fnct->faddr; body.b = modstart.b + strlen(modstart.b) + 3; /* loc. of fn body */ jump.i = body.i + (*modstart.b ? 1 : 0); for (temp.b = modstart.b; *temp.b; skip7(&temp)) { jump.i->address = intern (temp.b); ++jump.i; } ++temp.b; flen = *temp.w; code.b = jump.b; temp.b = body.b + flen; /* loc. of reloc parameters */ nrelocs g (mainp) /* read in a program file */ FLAG mainp; { char extp; /* was -e used? */ char *extstmp; union ptr dir; unsigned len; if (cread (&ibuf, &fdir, 512) < 512) /* read directory */ Fatal ("-- read error!\n"); if (phase == INMEM && mainp) { cread (&ibuf, &extp, 1); cread (&ibuf, &extstmp, 2); cread (&ibuf, &extspc, 2); if (extp) exts.b = extstmp; else exts.b = 0; /* will be set later */ } else cseek (&ibuf, 5, RELATIVE); for (dir.b=&fdir; *dir.b != 0x80; nextd (&dir)); /* find end of dir */ ++dir.b; len = *dir.w - 0x205; readobj (len); } readobj (len) /* read in an object (program or lib funct) */ unsigned len; { if (phase == DISK1 || codend.b + len >= lspcend) { if (phase == INMEM) { puts("\n** Out of memory--switching to disk mode **\n"); phase = DISK1; } if (phase == DISK2) { if (cwrite (&obuf, lspace, codend.b - lspace) == -1) Fatal ("Disk write error!\n"); } buforg += codend.b - lspace; coden = *temp.w++; jtsiz = code.b - body.b; if (Dflag && fnct->fdebug) { if (phase!=DISK1) { codend.i->opcode = (0307 + (8*RST_NUM)); codend.i->address = 0; finalloc.b += 3; } codend.b += 3; } offset = code.b - codend.b; if (phase != DISK1) while (nrelocs--) relocate (*temp.w++, body.b, jtsiz, finalloc.b, offset, flen); flen -= jtsiz; if (phase != DISK2) jtsaved += jtsiz; if (phase != DISK1) movmem (code.b, codend.b, flen); codend.b += flen; } relocate (param, body, jtsiz, base, offset, flen) /* do a relocation!! */ unsigned param, jtsiz, base, offset, flen; union ptr body; { union ptr instr, /* instruction involved */ ref; /* jump table link */ struct funct *fnct; /* if (param == 1) return; /* don't reloc jt skip */*/ instr.b = body.b + param - 1; if (instr.i->address >= jtsiz) instr.i->address += base - jtsiz; /* vanilla case */ else { ref.b = instr.i->address + body.u; if (instr.i->opcode == LHLD) { instr.i- } else { temp.i->opcode = LXISP; temp.i->address = Tval; } temp.b = lspace + 0xF; /* main function address */ temp.i->address = fptr->faddr; #ifdef MARC } #endif temp.b = lspace + 0x15; *temp.w++ = exts.u; ++temp.w; *temp.w++ = acodend.u; *temp.w++ = exts.u + extspc; } else temp.i->address = fptr->faddr; /* that's a JMP */ #ifdef MARC if (maxmemp) { temp.b = lspace + 0x258; temp.i->opcode = CALL; temp.i->address = 0x50; } #endif } wrtsyms() /* write out symbol table */ { int i, fd, compar(); qsort (ftab, nfuncts, sizeof(*ftab), &compar); makeext (&progfiles[0], "SYM"); if (fcreat (&progfiles[0], &symbuf) < 0) Fatal ("Can't create .SYM file\n"); for (i=0; i < nfuncts; ++i) { puthex (ftab[i].faddr, &symbuf); putc (' ', &symbuf); fputs (&ftab[i].fname, &symbuf); if (i % 4 == 3) fputs ("\n", &symbuf); else { if (strlen (&ftab[i].fname) < 3) putc ('\t', &symbuf); putc ('\t', &symbuf); >opcode = LXIH; --ref.b; } fnct = ref.i->address; instr.i->address = fnct->faddr; /* link in */ if (!fnct->flinkedp && phase == INMEM) fnct->faddr = instr.b + 1 - offset; /* new list head */ } } intern (name) /* intern a function name in the table */ char *name; { struct funct *fptr; if (*name == 0x9D) name = "MAIN"; /* Why, Leor, WHY??? */ for (fptr = &ftab[nfuncts-1]; fptr >= ftab; --fptr) if (!strcmp7 (name, fptr->fname)) break; if (fptr < ftab) { if (nfuncts >= maxfuncts) Fatal("Too many functions (limit is %d)!\n", maxfuncts); fptr = &ftab[nfuncts]; strcpy7 (fptr->fname, name); str7tont (fptr->fname); fptr->flinkedp = FALSE; fptr->faddr = NULL; fptr->fdebug = !SysStat; ++nfuncts; } return (fptr); } dirsearch (name) /* search directory for a function */ char *name; { union ptr temp; for (temp.b = &fdir; *temp.b != 0x80; nextd (&temp)) if (!strcmp7 (name, temp.b)) return (temp.b); return (NULL);  } } if (i % 4) fputs ("\n", &symbuf); if (appstatsp) stats (&symbuf); putc (CPMEOF, &symbuf); fflush (&symbuf); fclose (&symbuf); if (sepstatsp) { makeext (&progfiles[0], "LNK"); if (fcreat (&progfiles[0], &symbuf) < 0) Fatal ("Can't create .LNK file\n"); stats (&symbuf); putc (CPMEOF, &symbuf); fflush (&symbuf); fclose (&symbuf); } } compar (f1, f2) /* compare two symbol table entries by name */ struct funct *f1, *f2; { /* return (strcmp (&f1->fname, &f2->fname)); alphabetical order */ return (f1->faddr > f2->faddr); /* memory order */ } #ifdef OVERLAYS loadsyms() /* load base symbol table (for overlay) */ { /* symbol table must be empty! */ int nread; FLAG done; char *c; makeext (&symsfile, "SYM"); if (fopen (&symsfile, &symbuf) < 0) Fatal ("Can't open %s.\n", &symsfile); done = FALSE; while (!done) { nread = fscanf (&symbuf, "%x %s\t%x %s\t%x %s\t%x %s\n", &(ftab[nfuncts].faddr), &(ftab[nfu } nextd (ptrp) /* move this pointer to the next dir entry */ union ptr *ptrp; { skip7 (ptrp); ++(*ptrp).w; } chase (head, loc) /* chase chain of refs to function */ union ptr head; unsigned loc; { union ptr temp; while (head.w) { temp.w = *head.w; *head.w = loc; head.u = temp.u; } } wrtcom() /* write out com file (from in-mem link) */ { hackccc(); if (!ovlp) makeext (&progfiles[0], "COM"); else makeext (&progfiles[0], "OVL"); if (!ccreat (&obuf, &progfiles[0]) < 0 || cwrite (&obuf, lspace, codend.b - lspace) == -1 || cflush (&obuf) < 0) Fatal ("Disk write error!\n"); cclose (&obuf); stats (STDOUT); } hackccc() /* store various goodies in C.CCC code */ { union ptr temp; struct funct *fptr; temp.b = lspace; fptr = intern (&mainfunct); if (!ovlp) { #ifdef MARC if (!marcp) { #endif if (!Tflag) { temp.i->opcode = LHLD; temp.i->address = origin - 0x100 + 6; (++temp.i)->opcode = SPHL; ncts].fname), &(ftab[nfuncts+1].faddr), &(ftab[nfuncts+1].fname), &(ftab[nfuncts+2].faddr), &(ftab[nfuncts+2].fname), &(ftab[nfuncts+3].faddr), &(ftab[nfuncts+3].fname)); nread /= 2; if (nread < 4) done = TRUE; while (nread-- > 0) ftab[nfuncts++].flinkedp = EXTERNAL; } fclose (&symbuf); } #endif stats (chan) /* print statistics on chan */ int chan; { unsigned temp, *tptr; tptr = 6; fprintf (chan, "\n\nLink statistics:\n"); fprintf (chan, " Number of functions: %d\n", nfuncts); fprintf (chan, " Code ends at: 0x%x\n", acodend.u); fprintf (chan, " Externals begin at: 0x%x\n", exts.u); fprintf (chan, " Externals end at: 0x%x\n", exts.u + extspc); fprintf (chan, " End of current TPA: 0x%x\n", *tptr); fprintf (chan, " Jump table bytes saved: 0x%x\n", jtsaved); temp = lspcend; if (phase == INMEM) fprintf (chan, " Link space remaining: %dK\n", (temp - codend.u) / 1024); } makeext (fname, ext) /* force a file extension to inker and Docs by Scott W. Layson, Mark of the Unicorn L2 is an alternative to CLINK for linking BDS C programs. A program linked with CLINK will have a jump table at the beginning of each function; calls to other functions are made indirectly through the table. L2 eliminates these jump tables, and adjusts indirect calls through them to go directly to the target function. Besides making the code imperceptibly faster, this has two real advantages: one, it makes the code smaller by 4% to 10% (the latter has been observed in a program containing many small functions which do little besides call a few other functions), and it allows SID to display the name of the target function of a call, simplifying debugging. L2 seems to be complete enough to replace CLINK entirely. Its biggest advantage is that it's written in C, so that if you need some feature it doesn't have, you can just hack it in. However, its user interface anext */ char *fname, *ext; { while (*fname && (*fname != '.')) { *fname = toupper (*fname); /* upcase as well */ ++fname; } *fname++ = '.'; strcpy (fname, ext); } strcmp7 (s1, s2) char *s1, *s2; { /* compare two strings, either bit-7-terminated or null-terminated */ for (; (_c1 = *s1) == *s2; s1++, s2++) if ( (0x80 & _c1) || !_c1) return 0; if ((_c1 &= 0x7F) < (_c2 = 0x7F & *s2)) return -1; if (_c1 > _c2) return 1; _end1 = (*s1 & 0x80) || !*(s1+1); _end2 = (*s2 & 0x80) || !*(s2+1); if (_end2 && !_end1) return 1; if (_end1 && !_end2) return -1; /* if (_end1 && _end2) */ return 0; } strcpy7 (s1, s2) /* copy s2 into s1 */ char *s1, *s2; { do { *s1 = *s2; if (!*(s2+1)) { /* works even if */ *s1 |= 0x80; /* s2 is null-term */ break; } ++s1; } while (!(*s2++ & 0x80)); } skip7 (ptr7) /* move this pointer past a string */ char **ptr7; { while (!(*(*ptr7)++ & 0x80)); } str7tont (s) /* add nuld certain aspects of its behavior are rather different. The most important difference is the distinction it makes between "program" and "library" CRL files. Program files are loaded in their entirety; each function in a program file is linked in, whether or not it has been referenced by the time it is encountered (unless another function with the same name has already been loaded). Library files are scanned for needed functions; only those that have been referenced by another function are included in the object code. CLINK treats all CRL files as libraries in this sense (except see the -f option for v1.4). A typical command line is l2 foo bar -l bletch grotz -wa Given this command, L2 will load all the functions in FOO.CRL and BAR.CRL (the program files). Then it will scan the libraries BLETCH.CRL, GROTZ.CRL, DEFF.CRL, and DEFF2.CRL (in that order) for functions that have been referenced but not linked. If there remain unsatisfied rl at end */ char *s; { while (!(*s & 0x80)) { if (!*s) return; /* already nul term! */ s++; } *s = *s & 0x7F; *++s = NUL; } puthex (n, obuf) /* output a hex word, with leading 0s */ unsigned n; char *obuf; { int i, nyb; for (i = 3; i >= 0; --i) { nyb = (n >> (i * 4)) & 0xF; nyb += (nyb > 9) ? 'A' - 10 : '0'; putc (nyb, obuf); } } Fatal (arg1, arg2, arg3, arg4) /* lose, lose */ char *arg1, *arg2, *arg3, *arg4; { printf (arg1, arg2, arg3, arg4); lexit (1); } lexit (status) /* exit the program */ int status; { if (status == 1) unlink (SUB_FILE); exit(); /* bye! */ } /* END OF L2.C */  L2 (C Linker) v2.1 1 7 Dec 81 The Mark of the Unicorn Linker For BDS C v2.1 7 Dec 81 Leferences, L2 will display a list of the needed functions and prompt for the name of a CRL file to scan; it will L2 (C Linker) v2.1 2 7 Dec 81 repeat this process until all references are satisfied (just like CLINK). Then it will write the resulting code to FOO.COM, display the link statistics, and write a symbol table (with the link stats appended) to FOO.SYM. In more detail, then: here is a list of the available command-line options. Options consist of a dash followed by a (possibly one-letter) word, preceded and followed by a space. Unlike CLINK's, L2's options may not be combined; "-l -w", for example, may not be abbreviated "-lw"; and "-m fubar" may not be written "-mfubar". -f Reserves enough table size for functions. ( is in decimal.) The default is 200. If you often link programs with more than 200 e code, not of RAM; the default is, of course, 0x100. (To link a program L2 (C Linker) v2.1 3 7 Dec 81 for a nonstandard CP/M, you need a C.CCC, DEFF.CRL, and DEFF2.CRL which have been assembled for that address. If you are running L2 on a nonstandard CP/M, you should change the default origin in setup() to 0x4300.) If you are using this option to generate code for ROM, be sure to use the "-t" option also (see below). -t Works just like the CLINK "-t" option: sets the stack pointer to the given address at the start of the run-time package. This option MUST ALWAYS BE USED when "-org" is used to generate code for ROM. IF "-t" is NOT used, then the first two  functions, you may wish to change the default -- it's in setup() in L2.C. -l CRL file names before the first "-l" on the command line will be treated as program files; CRL files after the first "-l" are treated as libraries. Subsequent "-l"s have no effect. -m becomes the top-level function. This is the function initially called when the .COM file is run; by default, of course, it is "main". Note that, unlike with CLINK, the top-level function need not be the first function in the first CRL file; it can be anywhere. -m also works with -ovl (see below). -ovl An overlay segment will be built instead of a root segment; the overlay will be linked to run at base address (entered in instructions of the resulting COM file will be: lhld origin-100h+6 sphl (where "origin" is normally 0x100 or 0x4300) while using "-t" causes the first two instructions to be: lxi sp, nop -w A SID-compatible symbol table is written to .SYM, where is the name of the first CRL file listed in the command line. This table is normally produced in address order, not alphabetical order like CLINK's; see below for how to change this. -wa A variation on -w. The link statistics, which are always displayed on the console at the end of linking, are also appended to the .SYM file. If the resulting .SYM file is read into SID, SID will  hex). is the name of the root segment for which the overlay is being built; .SYM, a symbol table produced with either L2 or CLINK, will be read in *before* the CRL files, to allow overlay functions to call root functions. The name of the top-level function in the overlay -- i.e., the one that gets invoked by a call to the overlay base address -- is by default not "main", but rather , the name of the first CRL file in the L2 command line. The overlay segment is written to .OVL. (See example below.) -org This option is used to produce a root segment with base address , e.g., for use in generating code for ROMming. is entered in hex, and is the starting address of th complain by issuing its typical verbose error message "?", but then will work correctly. The big advantage of putting the stats at the end of the .SYM file is that one can subsequently look at that file to see exactly how long the code was and where the externals started. -ws Another variation on -w. This one writes the symbol table to .SYM and the link statistics to .LNK. Because L2 is so large, it cannot always link large programs in a single pass. If it runs out of memory during linking, it will switch automatically to (very slow) two-pass mode. (If it says "Module won't fit in memory at all", you probably have a very large program file. Split it up or make it a library. If this doesn't L2 (C Linker) v2.1 4 7 Dec 81 work, you do ... ... (an entry for each overlay in the file) Overlay segments are of length bytes, of which the last bytes holds a list of relocation offsets. This is a null-terminated string of byte values giving the difference between successive addresses to be relocated; a value of 255 means to add 255 to the next byte value to get the offset. The first offset is relative to -1 (so that we can relocate the first word of the overlay). At the beginning of the overlay is a table of addresses of top-level functions, one address for each function listed for that overlay in the descriptor file. The -l option works as for L2: CRL files listed before L2 (Cn't have enough memory to use L2.) L2 is built from the source files L2.C, SCOTT.C, and CHARIO.C. A typical compilation is cc l2.c -e4D00 (use 4900 instead of 4D00 if L2.COM is handy) cc scott.c cc chario.c followed by either clink l2 chario scott or l2 l2 chario -l scott depending on whether an L2.COM is handy. If you want a slightly shorter version, comment out the "#define OVERLAYS" statement near the beginning of L2.C. You can then compile with -e4500; the resulting L2 will not accept the "-ovl" option. If you have a pre-release of MARC and want a MARC cross-linker, uncomment the "#define MARC". Then, when you use the "-marc" option, L2 will look for CM.CCC, DEFFM.CRL, and DEFF2M.CRL, which should be the MARC versions of these files. L2 will produce a .COM file which must be MFTPed to MARC, then converted to load format. L2 itself does not yet run under MARC; if anyone has the energy to conv Linker) v2.1 6 7 Dec 81 the -l are loaded in entirety; those after are just scanned for needed functions. Any functions specified in the default search list in the overlay descriptor file are also scanned, unless the -nd (no default) option is given. The overlay, once created, is written into .OVL, at address * . Here is an example of a .DES file, with comments in brackets: 1024 128 [1K overlay slots; 128 relocation bytes] lib1 lib2 lib3 [default CRL libraries] OvlOne 0 [overlay name, slot number] Func11 [callable functions in the overlay] Func12 Func13 OvlTwo 1 [another overlay name & slot] Func21 Func22 Func23 Here is some code to load and execute the generated oert it, let me know! L2 (C Linker) v2.1 5 7 Dec 81 Relocatable Overlay Manager MAKOVL is a variation on L2. It builds relocatable overlays and stores them in fixed-size slots in a single overlay file. Here is the (rather terse) documentation from the beginning of MAKOVL.C: Command format: makovl { [-l {}] [-nd]} Overlay descriptor file, .DES, contains: ... (default search list) ... (more default search list) ... (an entry for each top-level function in the overlay) verlays: /* Overlay manager */ int curovl, ovlfd; #define OVLSIZE 1024 /* overlay space size in bytes */ #define RELOCSIZE 128 /* size of relocation info */ char overlay[OVLSIZE]; OvlInit() /* start overlay manager */ { curovl = -1; if ((ovlfd = open ("FUBAR.OVL", INPUT)) < 0) { puts ("Can't find the overlay file, FUBAR.OVL\n"); exit (1); } } OvlFini() /* clean up overlay manager */ { close (ovlfd); } L2 (C Linker) v2.1 7 7 Dec 81 OvlCall (ovlno, fun, arg1, arg2) /* call function in overlay */ int ovlno, fun, arg1, arg2; /* with args (, ) */ { int *ovltab, (*ovlfunct)(); /* note C bug: "int (**ovltab)()" doesn't work */  using Ward Christensen's "MODEM" File Transfer Protocol. Modified by Nigel Harrison and Leor Zolman from XMODEM.C, which was written by: Jack M. Wierda, modified by Roderick W. Hart and William D. Earnest Note that the Modem port interfaces are defined in BDSCIO.H, which must be configured with the correct values for your system. TELED now knows distinguishes between several different modes of operation: "terminal" mode (full duplex), "host" mode, and "half-duplex" mode, as follows (designed by Stephen Stuvner): ---------------------------------------------------------------- TERMINAL MODE: keyboard(char) ---> MoDem MoDem(char) ---> CRT ---------------------------------------------------------------- ECHO (HOST) MODE: keyboard(char) ---> MoDem `---> CRT If (char == CR).... LF ---> MoDem `---> CRT MoDem(char) ---> CRT `---> MoDem If (char == CR).... LF ---> CRT `---> MoDem ------------------------------ OvlLoad (ovlno); ovltab = overlay; ovlfunct = ovltab[fun]; return (*ovlfunct) (arg1, arg2); } OvlLoad (ovlno) /* load overlay */ int ovlno; { char reloc[RELOCSIZE]; if (ovlno == curovl) return; if (seek (ovlfd, ovlno * ((OVLSIZE + RELOCSIZE) / 128), ABSOLUTE) < 0 || read (ovlfd, overlay, (OVLSIZE / 128)) < 0 || read (ovlfd, reloc, (RELOCSIZE / 128)) < 0) { puts ("Read error in the overlay file, FUBAR.OVL\n"); exit (1); } OvlReloc (overlay, reloc); curovl = ovlno; } OvlReloc (code, rels) /* relocate an overlay */ char *code, *rels; { int *itemp; char *btemp; btemp = code - 1; while (*rels) { btemp += *rels; if (*rels++ == 255) btemp += *rels++; ---------------------------------- 1/2 DUPLEX MODE: keyboard(char) ---> MoDem `---> CRT If (char == CR).... LF ---> CRT MoDem(char) ---> CRT ---------------------------------------------------------------- */ #include #include /* The following three defines must be customized by the user: */ #define HC "\33H*" /* Home cursor and print a "*" */ #define SPECIAL '^'-0x40 /* Gets out of terminal mode */ #define CPUCLK 4 /* CPU clock rate, in MHz */ #define BELL 7 /* ASCII bell */ /* The rest of the defines need not be modified */ #define SOH 1 #define EOT 4 #define ACK 6 #define ERRORMAX 10 #define RETRYMAX 10 #define LF 10 #define CR 13 #define SPS 1500 /*loops per second */ #define NAK 21 #define TIMEOUT -1 #define TBFSIZ NSECTS*SECSIZ #define ML 1000 /* maximum source lines */ #define SEARCH_FIRST 17 /* BDOS calls */ #define SEARCH_NEXT 18 char linebuf[MAXLINE]; /* string buffer */ char fnamb itemp = btemp; *itemp += code; } } To call these functions: L2 (C Linker) v2.1 8 7 Dec 81 #define FUNC11 0, 0 #define FUNC12 0, 1 #define FUNC13 0, 2 ... OvlCall (FUNC11, arg1, arg2); ... To make a MAKOVL.COM: cc makovl.c -e4100 cc chario.c (if necessary) cc scott.c (if necessary) l2 makovl chario -l scott Good luck Scott W. Layson Mark of the Unicorn P.O. Box 423 Arlington, MA 02174 /* TELEDIT.C v1.3 (see TELEDIT.DOC) Modified for BDS C v1.50 by Leor Zolman, 10/82, 2/83 A telecommunications programuf[50]; /* name of file for text collection */ int nlines, nl; /* number of lines */ int linect; /* current line */ char fflg; /* text collection file flag */ char halfdup; /* half-duplex mode */ char hostflg; /* true in host mode */ char sflg; /* transmit flag */ int kbhit() /* test for console character available: */ { return bios(2); } int getch() /* get char from console raw, no echo */ { while (!kbhit()); return bios(3) & 0x7f; } int getchar() /* get console char with echo, expand CR to CRLF locally: */ { char c; putchar(c = getch()); if (c == '\r') putchar('\n'); return c; } putchar(c) /* write char to console, expand LF to CRLF: */ { if (c == '\n') putchar('\r'); bios(4,c); } send(data) /* send char to modem */ char data; { while(!MOD_TBE) ; MOD_TDATA(data); } main(argc,argv) char **argv; { int i, j, k, l; /* scratch integers */ char *lineptr[ML]; /* allow ML source lines */ char *inl[ML]; /* inserted ection already in effect (filename '%s')\n", fnambuf); else { puts("Collection text filename = "); getname(fnambuf); puts("Wait..."); if (fopen(fnambuf,buf) == ERROR) /* if it already exists, */ goto newfile; /* go create it */ else /* else query further */ { printf("\nFile already exists; do you want to "); if(ask("overwrite it")) { newfile: if (fcreat(fnambuf, buf) == ERROR) /* Make new version */ { printf("\nCan't create %s", fnambuf); goto wait; } } else if (ask("Do you want to append to it")) /* append to it */ { if (fappend(fnambuf,buf) == ERROR) { printf("\nCan't append for some reason\n"); goto wait; } } else { printf("File operations aborted.\n"); goto wait; } } fflg = TRUE; } printf("\nReady\n"); while(1) { if(MOD_RDA) { putchar (in = MOD_RDATA & 0x7F); if (hostflg) { send(in); if (in == '\r') { send('\n'); putchar(line pointers */ char *p; /* scratch pointer */ char buf[BUFSIZ]; /* i/o buffer */ int in; /* collect characters at in */ char *alloc(); /* storage allocator */ char *getm(); /* memory procuror */ int baudrate; _allocp = NULL; /* initialize alligator */ linect = nlines = i = 0; fflg = hostflg = halfdup = FALSE; lineptr[i] = NULL; baudrate = 0; /* unknown baud rate */ while(1) { puts(CLEARS); printf("Teledit ver 1.3 \n\n"); printf("T: Terminal mode - no text collection\n"); printf("X: terminal mode with teXt collection\n"); printf(" In terminal mode:\n"); printf(" SPECIAL (control-^): return to menu\n"); printf(" control-E: enter editor\n"); printf("H: toggle Host mode (for user-user typing) (currently: %s)\n", hostflg ? "ENABLED" : "disabled"); printf("G: toGgle half-duplex system mode (currently: %s duplex)\n", halfdup ? "HALF" : "full"); printf("E: Edit collected text\n"); printf("F: Flush text buffer to text'\n'); } } if(in >= ' ') linebuf[i++] = in; else { if(in == '\n') continue; if(in == CR) { linebuf[i++] = '\n'; linebuf[i] = NULL; p = getm(linebuf); if(p == NULL) continue; lineptr[nlines++] = p; lineptr[nlines] = NULL; if(nlines > 500) putchar(BELL); i = 0; } else if(in == '\t' || in == '\f') linebuf[i++] = in; else continue; } } if(kbhit()) { in = getch(); if(in == SPECIAL) break; else if (in == ('E' & 037)) { ed(lineptr); printf("Terminal mode:\n\n"); } else send(in); if (hostflg || halfdup) { putchar(in); if (in == '\r') { putchar('\n'); if (hostflg) send('\n'); } } } } break; case 'S': case 'R': printf("File to %s = ", (in == 'S') ? "send" : "receive"); getname(linebuf); if(in == 'R') readfile(linebuf); else { if(fopen(linebuf, buf) == ERROR) { print collection file\n"); printf("C: flush and Close text collection file\n"); printf("U: select cp/m User area\n"); printf("V: select cp/m driVe\n"); printf("D: print Directory for current drive and user area\n"); printf("S: Send a file, MODEM protocol\n"); printf("R: Receive a file, MODEM protocol\n"); printf("B: select Baud rate (currently "); if (baudrate) printf("running at %d baud",baudrate); else printf("unchanged from last usage"); puts(")\n"); printf("Q: quit\n"); printf("SPECIAL: send SPECIAL char to modem\n"); printf("\nCommand: "); in = toupper(getchar()); putchar('\n'); switch(in) { case 'U': printf("Switch to user area: "); bdos(32,atoi(gets(linebuf))); break; case 'V': printf("Switch to drive: "); bdos(14,toupper(getchar()) - 'A'); break; case 'D': dodir(); goto wait; case SPECIAL: send(SPECIAL); break; case 'T': terminal(); break; case 'X': if (fflg) printf("Text collf("Can't open %s\n", linebuf); goto wait; } sendfile(linebuf); } putchar(BELL); /* beep when done */ goto wait; case 'E': ed(lineptr); break; case 'D': dump(lineptr, buf); goto wait; case 'G': if (halfdup = !halfdup) { puts("Going into half duplex mode\n"); if (hostflg) { puts("(HOST mode is being automatically disabled)\n"); hostflg = FALSE; } goto wait; } goto Hterm; case 'H': if (hostflg = !hostflg) { puts("Going into HOST (user-user communication) mode\n"); if (halfdup) { puts("(HALF DUPLEX mode is being automatically disabled)\n"); halfdup = FALSE; } goto wait; } Hterm: puts("Going back to normal terminal mode\n"); goto wait; case 'B': /**** This section is left for the user to configure **** * 1) ask the user what baudrate to switch to, * * 2) make the "baudrate" variable equal the new rate * * 3) actually set the baudrate in whichever way is * * appropria i++) { if (source[i] == ' ') break; dest[j++] = source[i]; } dest[j] = '\0'; return dest; } dump(lineptr, buf) /* dump text buffer */ char **lineptr, *buf; { int i; for(i = 0; lineptr[i] != NULL; i++) if(fputs(lineptr[i], buf) == ERROR) printf("\n\7Error writing txt, disk full?\n"); lineptr[0] = linect = nlines = _allocp = 0; } ed(lineptr) /* editor */ char **lineptr; { char in, *inl[ML], *p, buf[BUFSIZ]; int i, j, k, l; char *getm(), *alloc(); if(!fflg) { printf("\n\7No text buffer to edit.\n"); return; } printf("\nedit\n*"); nl = 22; while (in = getchar()) switch (tolower(in)) { case 'a': puts("Filename to yank = "); if(fopen(getname(linebuf), buf) == ERROR) { printf ("\r Cannot open %s.\r*", linebuf); continue; } for(i = 0; fgets(linebuf, buf); i++) { inl[i] = getm(linebuf); if(inl[i] == NULL) break; } inl[i] = NULL; iblock(lineptr, inl, linect); show (lineptr, linect, nl)te to your hardware. * * Note that the "baudrate" variable comes up equal to * * 0 to indicate that no explicit baud rate has been * * selected by the user (i.e., the baudrate is in what- * * ever state it was in before TELED was invoked) * *********************************************************/ puts("Baudrate selection is left for the user to configure.\n"); goto wait; case 'Q': if (fflg) { printf("\nSave file \"%s\" to ",fnambuf); if (ask("disk")) { dump(lineptr, buf); putc(CPMEOF, buf); fclose(buf); } } exit(0); case 'C': if (fflg) { printf("Closing %s...",fnambuf); dump(lineptr, buf); putc(CPMEOF, buf); fclose(buf); fflg = FALSE; } else puts("No currently active text collection file\n"); wait: puts("\n\nHit any key to return to menu: "); getchar(); } } } dodir() { char dmapos; /* value returned by search calls */ char first_time; /* used in search routine */ char tmpfn[20]; /* temp fi; continue; case 'b': linect = 0; show (lineptr, linect, nl); continue; case 'q': printf(CLEARS); return; case 'f': gets(linebuf); if((i = find(lineptr, linect)) >= 0) { linect = i; show (lineptr, linect, nl); } else if((i = find(lineptr, 0)) >= 0) { linect = i; show (lineptr, linect, nl); } else { printf(HC); printf(" not found\r*"); } continue; case 'i': j = min(linect, 5); if(j == 0) printf(CLEARS); else { show(lineptr, (linect - j), j); j++; printf("\b "); for(; j; j--) putchar('\n'); } while(1) { gets(linebuf); for(i = 0; linebuf[i]; i++) if(linebuf[i] == CPMEOF) break; if(linebuf[i] == CPMEOF) break; linebuf[i++] = '\n'; linebuf[i] = NULL; inl[j++] = getm(linebuf); } inl[j] = NULL; iblock(lineptr, inl, linect); show (lineptr, linect, nl); continue; case 'k': putchar('\n'); shlename buffer */ char fcb[36]; int colno; /* column count */ int i; char name[15]; int drive; bdos(26,BASE+0x80); /* ensure default DMA after read/write */ printf("\nFiles = "); if (getline(name,15) < 2) setfcb(fcb,"*.*"); else setfcb(fcb,name); drive= (fcb[0]==0 ? bdos(25) : fcb[0]-1 ) ; puts(CLEARS); printf("Directory for Drive %c, user area %d:\n\n", drive+'A', bdos(32,0xff)); colno = 1; first_time = TRUE; while (1) { dmapos = bdos(first_time ? SEARCH_FIRST : SEARCH_NEXT,fcb); if (dmapos == 255) break; first_time = FALSE; hackname(tmpfn,(BASE + 0x80 + dmapos * 32)); puts(tmpfn); for (i = strlen(tmpfn); i < 15; i++) putchar(' '); if ((colno += 15) > 65) { putchar('\n'); colno =1; } } } hackname(dest,source) char *dest, *source; { int i,j; j = 0; for (i = 1; i < 9; i++) { if (source[i] == ' ') break; dest[j++] = source[i]; } if (source[9] != ' ') dest[j++] = '.'; for (i = 9; i < 12;ow1(lineptr, linect); kill(lineptr, linect, 1); continue; case 'l': gets(linebuf); if((i = lfind(lineptr, linect)) >= 0) { linect = i; show(lineptr, linect, nl); } else if((i = lfind(lineptr, 0)) >= 0) { linect = i; show(lineptr, linect, nl); } else { printf(HC); printf(" not found\r*"); } continue; case 'o': putchar('\n'); i = linect; while(gets(linebuf)) { for(j = 0; linebuf[j]; j++) if(linebuf[j] == CPMEOF) break; if(linebuf[j] == CPMEOF) break; linebuf[j++] = '\n'; linebuf[j] = NULL; if(lineptr[i]) free(lineptr[i]); lineptr[i++] = getm(linebuf); if(i > nlines) lineptr[++nlines] = NULL; } show (lineptr, linect, nl); continue; case 'p': linect = min((linect + nl), nlines); show (lineptr, linect, nl); continue; case 's': gets(linebuf); nl = max((atoi(linebuf)), 1); show (lineptr, linect, nl); continue; case 'z': linect = nle(file) char *file; { int j, firstchar, sectnum, sectcurr, sectcomp, errors; int toterr,checksum; int errorflag, fd; int bufctr; char buffer[BUFSIZ]; sflg = FALSE; fd = creat(file); if(fd == -1) { printf("Teledit: cannot create %s\n", file); return; } printf("\nReady to receive %s\n", file); sectnum = 0; errors = 0; toterr = 0; bufctr = 0; purgeline(); shocrt(0,0,0); do { errorflag = FALSE; do firstchar = receive (10); while(firstchar != SOH && firstchar != EOT && firstchar != TIMEOUT); if(firstchar == TIMEOUT) errorflag = TRUE; if(firstchar == SOH) { sectcurr = receive (1); sectcomp = receive (1); if((sectcurr + sectcomp) == 255) { if(sectcurr == ((sectnum + 1) & 0xFF)) { checksum = 0; for(j = bufctr;j < (bufctr + SECSIZ);j++) { bufferlines; show(lineptr, linect, nl); continue; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '-': linebuf[0] = in; for (i = 1; (isdigit(in = getchar())); i++) linebuf[i] = in; linebuf[i] = NULL; i = atoi(linebuf); if (i < 0) j = max((linect + i), 0); else j = min((linect + i), nlines); in = tolower(in); if(j > linect && in == 'k') kill(lineptr, linect, (j - linect)); else linect = j; if (in == 'p') linect = max((linect-nl), 0); show (lineptr, linect, nl); continue; case '#': printf (" of lines: %d\r*", nlines); continue; case '\n': if (lineptr[linect] != NULL) { show1(lineptr, linect); linect++; } else printf (HC); continue; case ' ': if(linect) linect--; show(lineptr, linect, nl); continue; case ('E'&037): send(in); printf("\n^E sent\n"); return; default: printf(" ?\r*"); } } shocrt(se[j] = receive (1); checksum = (checksum + buffer[j]) & 0xff; } if(checksum == receive (1)) { errors = 0; sectnum = sectcurr; bufctr = bufctr + SECSIZ; if(bufctr == TBFSIZ) { bufctr = 0; write(fd, buffer, NSECTS); } shocrt(sectnum,errors,toterr); send(ACK); } else errorflag = TRUE; } else if(sectcurr == sectnum) { do; while(receive (1) != TIMEOUT) ; send(ACK); } else c,try,tot) int sec,try,tot; { if(sflg) printf("Sending #%d (Try=%d Errs=%d) \r", sec, try, tot); else printf("Awaiting #%d (Try=%d, Errs=%d) \r", sec, try, tot); if(try && tot) putchar('\n'); } receive(seconds) int seconds; { char data; int lpc,seccnt; for (lpc = 0; lpc < CPUCLK; lpc++) { seccnt = seconds * SPS; while (!MOD_RDA && seccnt--); if(seccnt >= 0) { data = MOD_RDATA; return(data); } } return(TIMEOUT); } char *getname(linbuf) /* get a reasonable filename from user */ char *linbuf; { int i; char c; while (1) { gets(linbuf); if (!*linbuf) /* reject null filename */ goto reject; for (i = 0; c = linbuf[i]; i++) { if (c < ' ' || c > 0x7F) goto reject; } break; reject: puts("\nFilename = "); continue; } return linbuf; } purgeline() { while (MOD_RDA) MOD_RDATA; /* purge the receive register */ } readfi errorflag = TRUE; } else errorflag = TRUE; } if(errorflag == TRUE) { errors++; if(sectnum) toterr++; while(receive (1) != TIMEOUT); shocrt(sectnum,errors,toterr); send(NAK); } } while(firstchar != EOT && errors != ERRORMAX); if((firstchar == EOT) && (errors < ERRORMAX)) { send(ACK); bufctr = (bufctr + SECSIZ - 1) / SECSIZ; write(fd, buffer, bufctr); close(fd); printf("\nDone -- returning to menu:\n"); } else printf("\n\7Aborting\n\n"); } sendfile(file) char *file; { char *npnt; int j, sectnum, sectors, attempts; int toterr,checksum; int bufctr, fd; char buffer[BUFSIZ]; sflg = TRUE; fd = open(file,0); if(fd == -1) { printf("\nTeledit: %s not found\n", file); return; } else printf("\nFile is %d sectors long.\n",cfsize(fd)); purlower(getchar()); if(c == 'y') { puts("es\n"); return 1; } else if(c == 'n') puts("o\n"); else { printf(" \7Yes or no, please...\n"); goto again; } return 0; } find(lineptr, linect) /*Find a line having the pattern in linebuf */ char *lineptr[]; int linect; { int i; for(i = linect; lineptr[i] != NULL; i++) if(pat(lineptr[i], linebuf) >= 0) return(i); return(-1); } kill(lineptr, linect, nl) /* erase lines */ char *lineptr[]; int linect, nl; { int i, j; for (i = linect; lineptr[i] != NULL && nl > 0; i++, nl--) { free(lineptr[i]); nlines--; } lineptr[linect] = NULL; if(lineptr[i] != NULL) { j = (nlines - linect) * 2; movmem(&lineptr[i], &lineptr[linect], j + 2); } } lfind(lineptr, linect) /* find pattern at beginning of a line */ char *lineptr[]; int linect; { int i, j; char line[MAXLINE]; j = strlen(linebuf); for (i = linect; lineptr[i] != NULL; i++) { strcpy(line, lineptr[i]); line[j] = NULL;geline(); attempts=0; toterr = 0; shocrt(0,0,0); while((receive (10) != NAK) && (attempts != 8)) { attempts++; shocrt(0,attempts,0); } if (attempts == 8) { printf("\nTimed out awaiting initial NAK\n"); return; } attempts = 0; sectnum = 1; while((sectors = read(fd, buffer, NSECTS)) && (attempts != RETRYMAX)) { if(sectors == -1) { printf("\nFile read error.\n"); break; } else { bufctr = 0; do { attempts = 0; do { shocrt(sectnum,attempts,toterr); send(SOH); send(sectnum); send(-sectnum-1); checksum = 0; for(j = bufctr;j < (bufctr + SECSIZ);j++) { send(buffer[j]); checksum = (checksum + buffer[j]) & 0xff; } send(checksum); p if(strcmp(line, linebuf) == 0) return i; } return -1; } pat(s, t) /* pattern match..*/ char s[], t[]; { int i, j, k; for(i = 0; s[i] != '\0'; i++) { for(j = i, k=0; t[k] != '\0' && s[j] == t[k]; j++, k++) ; if(t[k] == '\0') return(i); } return(-1); } show (lineptr, linect, nl) /* screen current frame */ char *lineptr[]; int linect, nl; { int i; printf (CLEARS); putchar('\n'); for (i = linect; i < (linect+nl) && lineptr[i] != NULL; i++) printf("%s", lineptr[i]); printf (HC); return(i); } show1(lineptr, linect) char **lineptr; int linect; { int i; for(i = 0; i < nl; i++) putchar('\n'); if((linect + nl) >= nlines) putchar('\n'); else printf("%s", lineptr[linect+nl]); printf(HC); for(i = 0; i < 78; i++) putchar(' '); printf("\r*"); } terminal() /* terminal mode, no text */ { int in; while(1) { if(MOD_RDA) { putchar(in = MOD_RDATA); if (hostflg) { send(in); urgeline(); attempts++; toterr++; } while((receive (10) != ACK) && (attempts != RETRYMAX)); bufctr = bufctr + SECSIZ; sectnum++; sectors--; toterr--; } while((sectors != 0) && (attempts != RETRYMAX)); } } if(attempts == RETRYMAX) printf("\nNo ACK on sector, aborting\n"); else { attempts = 0; do { send(EOT); purgeline(); attempts++; } while((receive (10) != ACK) && (attempts != RETRYMAX)); if(attempts == RETRYMAX) printf("\nNo ACK on EOT, aborting\n"); } close(fd); printf("\nDone -- Returning to menu:\n"); } ask(s) char *s; { char c; again: printf("%s (y/n)? ", s); c = to if (in == '\r') { send('\n'); putchar('\n'); } } } if(kbhit()) { in = getch(); if (in == SPECIAL) return; else send(in); if (hostflg || halfdup) { putchar(in); if (in == '\r') { putchar('\n'); if (hostflg) send('\n'); } } } } } char *getm(line) /* get memory for line, store it, return pointer */ char line[]; { char *p, *alloc(); if ((p = alloc(strlen(line) + 1)) != NULL) strcpy(p, line); return(p); } iblock(rb, ib, cl) /* insert block ib into rb at cl */ char *rb[], *ib[]; int cl; { int i, j; j = 0; if (rb[cl]) { for (i = 0; ib[i]; i++) ; j = (nlines - cl) * 2; movmem (&rb[cl], &rb[cl+i], j + 2); } for (i = 0; ib[i]; i++, cl++) rb[cl] = ib[i]; if(!j) rb[cl] = NULL; nlines += i; return cl; /* return new current line */ } n(argv[1], infile) == ERROR) { puts("Can't open "); puts(argv[1]); exit(-1); } #if VERBOSE fputs("Beginning initial formation run\n",stderr); #endif high = 0; /* Initial formation of runs: */ do { t = gtext(infile); quick(nlines); high++; makfil(high,tmpfile); ptext(tmpfile); fclout(tmpfile); } while (t != NULL); fclose(infile); /* free up the input file buffer */ #if VERBOSE fputs("Beginning merge operation\n",stderr); #endif for (low = 1; low < high; low += MERGEORDER) /* merge */ { lim = min(low + MERGEORDER - 1, high); gopen(low, lim); /* open files */ high++; makfil(high, tmpfile); merge(lim - low + 1, tmpfile); fclout(tmpfile); /* terminate, flush and close file */ gremov(low, lim); } /* Now write the sorted output file: */ fputs("Merge complete.\n",stderr); gname(high, name); /* create name of result file */ infile = buffers[0]; unlink(argv[2]); /* remove any old copy of result file */ if (rename(na/* Sort/Merge from Software Tools Last Modified : 6 October 1982 Converted from Software Tools RATFOR to BDS C by Leor Zolman Sep 2, 1982 Usage: sort Main variables have been made external; this is pretty much in line with the RATFOR call-by-name convention anyway. Requires lots of disk space, up to around three times the length of the file file being sorted. This program is intended for files bigger than memory; simpler, faster sorts can be implemented for really short files (like ALPH.C) -leor Compile & Link: A>cc sort.c -e2800 -o A>l2 sort (or...) A>cc sort.c -e2900 -o A>clink sort */ #include #define VERBOSE 1 /* give running account of file activity */ #define MAXLINE 200 /* longest line we want to deal with */ #define NBUFS 7 /* Max number of open buffered files */ #define MAXPTR 3000 /* Max number of lines (set for dict) */ #define MERGEORDER (NBUFS-1) /* Max # of intermediate files to merge */ #dme,argv[2]) == ERROR) { puts("An error occurred in renaming the output file from "); puts(name); puts(" to "); puts(argv[2]); } } fclout(obuf) FILE *obuf; { putc(CPMEOF,obuf); fflush(obuf); fclose(obuf); } /* * Quick: Quicksort for character lines */ quick(nlines) unsigned nlines; { unsigned i,j, lv[LOGPTR + 1], p, pivlin, uv[LOGPTR + 1]; int compar(); lv[1] = 1; uv[1] = nlines; p = 1; while (p > 0) if (lv[p] >= uv[p]) /* only 1 element in this subset */ p--; /* pop stack */ else { i = lv[p] - 1; j = uv[p]; pivlin = linptr[j]; /* pivot line */ while (i < j) { for (i++; compar(linptr[i],pivlin) < 0; i++) ; for (j--; j > i; j--) if (compar(linptr[j], pivlin) <= 0) break; if (i < j) /* out of order pair */ { temp = linptr[i]; linptr[i] = linptr[j]; linptr[j] = temp; } } j = uv[p]; /* move pivot to position 1 */ temp = linptr[i]; linptr[i] = efine NAMESIZE 20 /* Max Filename size */ #define LOGPTR 13 /* smallest value >= log (base 2) of MAXPTR */ #define EOS '\0' /* string termination character */ #define FILE struct _buf #define stderr 4 #define fputc putc char name[NAMESIZE], name2[NAMESIZE + 10]; FILE buffers[NBUFS + 1]; /* up to NBUFS general-purp. buffered files */ FILE *infil[MERGEORDER + 1]; /* tmp file ptrs for sort operation */ unsigned linptr[MAXPTR + 1], nlines; int temp; unsigned maxtext; /* max # of chars in main text buffer */ char *linbuf; /* text area starts after this variable */ main(argc,argv) char **argv; { FILE *infile, *outfile; /* main input and output streams */ FILE *tmpfile; int makfil(), min(), gopen(), gremov(); int gtext(); unsigned high, lim, low, t; linbuf = endext(); /* start of text buffer area */ maxtext = topofmem() - endext() - 500; tmpfile = buffers[0]; if (argc != 3) exit(puts("Usage: sort \n")); infile = buffers[1]; if (fopelinptr[j]; linptr[j] = temp; if ( (i - lv[p]) < (uv[p] - i)) { lv[p + 1] = lv[p]; uv[p + 1] = i - 1; lv[p] = i + 1; } else { lv[p + 1] = i + 1; uv[p + 1] = uv[p]; uv[p] = i - 1; } p++; } return; } /* * Compar: Compare two strings; return 0 if equal, -1 if first is * lexically smaller, or 1 if first is bigger */ int compar(lp1, lp2) unsigned lp1, lp2; { unsigned i, j; for (i = lp1, j = lp2; linbuf[i] == linbuf[j]; i++,j++) { if (linbuf[i] == EOS) return 0; } return (linbuf[i] < linbuf[j]) ? -1 : 1; } /* * Ptext: output text lines from linbuf onto the buffered output file given */ ptext(outfil) FILE *outfil; { int i; for (i = 1; i <= nlines; i++) { if (fputs(&linbuf[linptr[i]], outfil) == ERROR) { fputs("Error writing output file..disk full?\n", stderr); exit(-1); } } return 0; } /* * Gtext: Get text lines from the buffered input file provided, and * (stderr,"Removing temp files %d-%d\n",low,lim); #endif for (i = 1; i <= (lim - low + 1); i++) { fabort(infil[i]->_fd); /* forget about the file */ gname(low + i - 1, name); unlink(name); /* and physically remove it */ } } /* * Fputs: special version that aborts on output error: */ fputs(s,iobuf) char *s; FILE *iobuf; { char c; while (c = *s++) { if (c == '\n') putc('\r',iobuf); if (putc(c,iobuf) == ERROR) { fputs("Error on file output\n",stderr); exit(ERROR); } } return OK; } /* * Merge: merge infil[1]...infil[nfiles] onto outfil */ merge(nfiles, outfil) FILE *outfil; { char *fgets(); int i, inf, lbp, lp1, nf; lbp = 1; nf = 0; for (i = 1; i <= nfiles; i++) /* get one line from each file */ if (fgets(&linbuf[lbp], infil[i]) != NULL) { nf++; linptr[nf] = lbp; lbp += MAXLINE; /* leave room for largest line */ } quick(nf); /* make initial heap */ while (nf > 0) { lp1 = linptr[1]; fputs(&l place them into linbuf */ int gtext(infile) FILE *infile; { unsigned lbp, len; nlines = 0; lbp = 1; do { if ( (len = fgets(&linbuf[lbp], infile)) == NULL) break; len = strlen(&linbuf[lbp]); nlines++; linptr[nlines] = lbp; lbp += len + 1; } while ( lbp < (maxtext - MAXLINE) && nlines < MAXPTR); return len; /* return 0 if done with file */ } /* * Makfil: Make a temporary file having suffix 'n' and open it for * output via the supplied buffer */ FILE *makfil(n,obuf) /* make temp file having suffix 'n' */ int n; FILE *obuf; { FILE *fp; char name[20]; gname(n,name); if (fcreat(name,obuf) == ERROR) { puts("Can't create "); puts(name); exit(-1); } return 0; } /* * Gname: Make temporary filename having suffix 'n' */ char *gname(n,name) char *name; int n; { char tmptext[10]; strcpy(name,"TEMP"); /* create "TEMPn.$$$" */ strcat(name,itoa(tmptext,n)); strcat(name,".$$$"); return name; /* return a pointer to iinbuf[lp1], outfil); inf = lp1 / MAXLINE + 1; /* compute file index */ if (fgets(&linbuf[lp1],infil[inf]) == NULL) { linptr[1] = linptr[nf]; nf--; } reheap(nf); } return; } /* * Reheap: propogate linbuf[linptr[1]] to proper place in heap */ reheap(nf) unsigned nf; { unsigned i,j; for (i = 1; (i + i) <= nf; i = j) { j = i + i; if (j < nf && compar(linptr[j], linptr[j + 1]) > 0) j++; if (compar(linptr[i], linptr[j]) <= 0) break; temp = linptr[i]; linptr[i] = linptr[j]; linptr[j] = temp; } return; }  /* "CONVERT" WRITTEN BY LEOR ZOLMAN THIS PROGRAM CONVERTS REGULAR C SOURCE FILES INTO A FORMAT SUITABLE FOR EDITING ON THE TRS-80 (OR ANY UPPER-CASE-ONLY SYSTEM.) SINCE THERE ARE QUITE A FEW ASCII CHARACTERS THAT NEED TO BE REPRESENTED EVEN THOUGH THEY DON'T SHOW UP ON UPPER-CASE-ONLY SYSTEMS, A SPECIAL NOTATION HAS BEEN CREATED FOR REPRESENTING THESE CHARAt */ } /* * Itoa: convert integer value n into ASCII representation at strptr, * and return a pointer to it */ char *itoa(strptr,n) char *strptr; int n; { int length; if (n < 0) { *strptr++ = '-'; strptr++; n = -n; } if (n < 10) { *strptr++ = (n + '0'); *strptr = '\0'; return strptr - 1; } else { length = strlen(itoa(strptr, n/10)); itoa(&strptr[length], n % 10); return strptr; } } /* * Gopen: open group of files low...lim */ gopen(low, lim) int lim, low; { int i; #if VERBOSE fprintf(stderr,"Opening temp files %d-%d\n",low,lim); #endif for (i = 1; i <= (lim - low + 1); i++) { gname(low + i - 1, name); if (fopen(name, buffers[i]) == ERROR) { puts("Can't open: "); puts(name); exit(-1);; } infil[i] = &buffers[i]; } } /* * Remove group of files low...lim * (should use "close" instead of "fabort" for MP/M II) */ gremov(low, lim) int lim, low; { int i; #if VERBOSE fprintfCTERS. THE POUND SIGN IS USED AS A SORT OF 'SHIFT' KEY, WITH THE LETTER FOLLOWING THE POUND SIGN DENOTING THE SPECIAL CHARACTER NEEDED. NOTE THAT THE C COMPILER DOES NOT RECOGNIZE THIS SPECIAL SCHEME, AND BEFORE YOU CAN COMPILE A SOURCE FILE CONTAINING THE SPECIAL CODES YOU MUST PREPROCESS THE FILE USING THE "CC0T" COMMAND. THE SPECIAL CODES AND THE CHARACTERS THEY REPRESENT ARE: #L LEFT BRACKET (FOR SUBSCRIPTING) (5B HEX) #R RIGHT BRACKET (5D HEX) #C CIRCUMFLEX (BITWISE "NOT") (7E HEX) #H UP-ARROW (EXCLUSIVE "OR" OPERATOR) (5E HEX) #V VERTICAL VAR (LOGICAL AND BITWISE "OR") (7C HEX) #B BACKSLASH (FOR ESCAPE SEQUENCES)(5C HEX) #U UNDERSCORE (5F HEX) FOR EXAMPLE, THE COMMAND A>CONVERT FOO.C BAR.CT WILL EXPECT FOO.C TO BE A NORMAL C SOURCE FILE ON DISK, AND WILL CONVERT IT INTO A FILE NAMED BAR.CT. THE FILE BAR.CT MAY THEN BE EDITED TO YOUR TASTE, BUT REMEMBER TO PREPROCESS IT WITH "CC0T" BEFORE APPLYING THE C COMPILER. AS YOU MAY HAVE GATHEG THE SPECIAL "POUND SIGN" ENCODING FOR CHARACTERS WHICH ARE UNPRINTABLE (AND UNENTERABLE) ON THE EARLY MODEL TRS-80 COMPUTERS. WHEREVER CC0T FINDS A SEQUENCE #X IN THE INPUT FILE, WHERE "X" IS ONE OF THE SPECIAL CHARACTERS AS OUTLINED IN THE SOURCE FOR CONVERT.C, THEN THE TWO-CHARACTER SEQUENCE IS CONVERTED TO A SINGLE CHARACTER AS REQUIRED BY THE BDS C COMPILER. THE RESULTANT FILE MAY THEN BE COMPILED WITH CC1, CC2, ETC. */ #INCLUDE "BDSCIO.H" #DEFINE POUND 0X23 #DEFINE LEFTBRACK 0X5B #DEFINE BACKSLASH 0X5C #DEFINE RIGHTBRACK 0X5D #DEFINE CIRCUM 0X7E #DEFINE VERTIBAR 0X7C #DEFINE UNDERSCORE 0X5F #DEFINE UPARROW 0X5E CHAR IBUF[BUFSIZ], OBUF[BUFSIZ]; MAIN(ARGC,ARGV) INT ARGC; CHAR *ARGV[]; BEGIN INT FD1, FD2; CHAR C; IF (ARGC != 3) BEGIN PRINTF("USAGE: CC0T OLD NEW \N"); EXIT(); END FD1 = FOPEN(ARGV[1],IBUF); IF (FD1 == ERROR) BEGIN PRINTF("CANNOT OPEN INPUT FILE.\N"); EXIT(); END FD2 = FCREAT(ARGV[2],OBUF); IF (RED FROM ALL THIS, THE LANGUAGE "C" WAS NEVER INTENDED TO BE IMPLEMENTED ON A SYSTEM HAVING UPPER-CASE ONLY; NEVERTHELESS, HERE IS A WAY FOR IT TO BE DONE. THIS PROGRAM IS RATHER SIMPLE, AND THUS IT WILL NOT RECOGNIZE THAT SPECIAL CHARACTERS IN QUOTES ARE NOT SUPPOSED TO BE CONVERTED. */ #INCLUDE "BDSCIO.H" #DEFINE LEFTCURLY 0X7B #DEFINE RIGHTCURLY 0X7D #DEFINE LEFTBRACK 0X5B #DEFINE RIGHTBRACK 0X5D #DEFINE CIRCUM 0X7E #DEFINE UPARROW 0X5E #DEFINE VERTIBAR 0X7C #DEFINE BACKSLASH 0X5C #DEFINE UNDERSCORE 0X5F CHAR IBUF[BUFSIZ], OBUF[BUFSIZ]; MAIN(ARGC,ARGV) INT ARGC; CHAR *ARGV[]; BEGIN INT FD1, FD2; CHAR C; IF (ARGC != 3) BEGIN PRINTF("USAGE: CONVERT OLD NEW \N"); EXIT(); END FD1 = FOPEN(ARGV[1],IBUF); IF (FD1 == ERROR) BEGIN PRINTF("NO SOURCE FILE.\N"); EXIT(); END FD2 = FCREAT(ARGV[2],OBUF); IF (FD2 == ERROR) BEGIN PRINTF("CAN'T OPEN OUTPUT FILE.\N"); EXIT(); END WHILE ((( C = GETC(IBUF)) != CPMEOF) && C != 255) BEGIN SWFD2 == ERROR) BEGIN PRINTF("CANNOT OPEN OUTPUT FILE.\N"); EXIT(); END WHILE ((( C = GETC(IBUF)) != CPMEOF) && C != 255) BEGIN IF (C != POUND) PUTC2(C); ELSE SWITCH(C = GETC(IBUF)) BEGIN CASE 'B': PUTC2(BACKSLASH); BREAK; CASE 'L': PUTC2(LEFTBRACK); BREAK; CASE 'R': PUTC2(RIGHTBRACK); BREAK; CASE 'C': PUTC2(CIRCUM); BREAK; CASE 'V': PUTC2(VERTIBAR); BREAK; CASE 'U': PUTC2(UNDERSCORE); BREAK; CASE 'H': PUTC2(UPARROW); BREAK; DEFAULT: PUTC2(POUND); PUTC2(C); END END IF (C == 255) C = CPMEOF; PUTC2(C); FFLUSH(OBUF); FCLOSE(OBUF); FCLOSE(IBUF); END PUTC2(C) CHAR C; BEGIN IF (PUTC(C,OBUF) < 0) BEGIN PRINTF("OUTPUT WRITE ERROR (DISK FULL?)\N"); EXIT(); END END /* MAKOVL.C Overlay builder/manager This code is in the public domain. Created from L2.C 81.10.29 Gyro This is a variatITCH (C) BEGIN CASE LEFTCURLY: PUTST(" BEGIN "); BREAK; CASE RIGHTCURLY: PUTST(" END "); BREAK; CASE LEFTBRACK: PUTSPEC('L'); BREAK; CASE RIGHTBRACK: PUTSPEC('R'); BREAK; CASE CIRCUM: PUTSPEC('C'); BREAK; CASE UPARROW: PUTSPEC('U'); BREAK; CASE VERTIBAR: PUTSPEC('V'); BREAK; CASE BACKSLASH: PUTSPEC('B'); BREAK; CASE UNDERSCORE: PUTSPEC('U'); BREAK; DEFAULT: PUTC2(TOUPPER(C)); END END IF (C==255) C = CPMEOF; /* DIGITAL RESEARCH....WOW. */ PUTC2(C); FFLUSH(OBUF); FCLOSE(OBUF); FCLOSE(IBUF); END PUTST(STRING) CHAR *STRING; BEGIN WHILE (*STRING) PUTC2(*STRING++); END PUTSPEC(C) CHAR C; BEGIN PUTC2('#'); PUTC2(C); END PUTC2(C) CHAR C; BEGIN IF (PUTC(C,OBUF) < 0) BEGIN PRINTF("OUTPUT WRITE ERROR (DISK FULL?)\N"); EXIT(); END END  /* CC0T.C -- TRS-80 C PREPROCESSOR WRITTEN BY LEOR ZOLMAN THIS PROGRAM TAKES, AS INPUT, A C SOURCE FILE WRITTEN USINion on L2.C that creates relocatable overlays according to an overlay descriptor file. Command format: makovl {} [-l {}] [-nd] Overlay descriptor file, .DES, contains: ... (default search list) ... (more default search list) ... (an entry for each top-level function in the overlay) ... ... (an entry for each overlay in the file) Overlay segments are of length bytes, of which the last bytes holds a list of relocation offsets. This is a null-terminated string of byte values giving the difference between successive addresses to be relocated; a value of 255 means to addchar *reladdr; /* last address relocated */ /* useful things to have defined */ struct inst { char opcode; char *address; }; union ptr { unsigned u; /* an int */ unsigned *w; /* a word ptr */ char *b; /* a byte ptr */ struct inst *i; /* an instruction ptr */ }; /* Link control variables */ union ptr codend; /* last used byte of code buffer + 1 */ union ptr acodend; /* actual code-end address */ unsigned origin; /* origin of code */ unsigned buforg; /* origin of code buffer */ char *lspace; /* space to link in */ char *lspcend; /* end of link area */ char *lodstart; /* beginning of current file */ /* i/o buffer */ struct iobuf { int fd; int isect; /* currently buffered sector */ int nextc; /* index of next char in buffer */ char buff [128]; } ibuf, obuf; /* BDS C i/o buffer */ char bdsbuf[BUFSIZ]; /* seek opcodes */ #define ABSOLUTE 0 #define RELATIVE 1 #define INPUT 0 #define UPDATE 2 #define TRUE (-1) #de 255 to the next byte value to get the offset. The first offset is relative to -1 (so that we can relocate the first word of the overlay). At the beginning of the overlay is a table of addresses of top-level functions, one address for each function listed for that overlay in the descriptor file. The -l option works as for L2: CRL files listed before the -l are loaded in entirety; those after are just scanned for needed functions. Any functions specified in the default search list in the overlay descriptor file are also scanned, unless the -nd (no default) option is given. The overlay, once created, is written into .OVL, at address * . */ /**************** Globals ****************/ #define SDOS /* comment this out for CP/M */ #include "bdscio.h" /* for i/o buffer defs */ #define NUL 0 #define FLAG char #define repeat while (1) #define STDOUT 1 /* function table */ struct funct { char fname[9]; FLAG flinkedp; fine FALSE 0 #define NULL 0 /* 8080 instructions */ #define LHLD 0x2A #define LXIH 0x21 #define SPHL 0xF9 #define JMP 0xC3 #define CALL 0xCD /* strcmp7 locals, made global for speed */ char _c1, _c2, _end1, _end2; /**************** End of Globals ****************/ main (argc, argv) int argc; char **argv; { puts ("Mark of the Unicorn Overlay Builder, vsn. 1.0\n"); setup (argc, argv); linkprog(); linklibs(); listfuns(); wrtovl(); } setup (argc, argv) /* initialize function table, etc. */ int argc; char **argv; { nprogs = 0; nlibs = 0; origin = buforg = 0; nfuncts = 0; srchdefs = TRUE; cmdline (argc, argv); lspace = endext(); lspcend = topofmem() - 1024; getdesc(); loadsyms(); } cmdline (argc, argv) /* process command line */ int argc; char **argv; { int i, progp; if (argc <= 2) { puts ("Usage is:\n"); puts (" makovl {} [-l {}]"); exit (1); } strcpy (&rootnam /* in memory already? */ char *faddr; /* address of first ref link if not linked */ } ftab [300]; int nfuncts; /* no. of functions in table */ #define LINKED 255 /* (flinkedp) function really here */ #define EXTERNAL 254 /* function defined in separate symbol table */ char fdir [512]; /* CRL file function directory */ /* command line parameters etc. */ char rootname[15]; /* name of root program */ char ovlname[40]; /* name of overlay to be built */ int nprogs, nlibs; char progfiles [20] [15]; /* program file names */ char libfiles [30] [15]; /* library file names */ FLAG srchdefs; /* search default libraries? */ /* overlay description */ int ovlsize, relsize; /* size of overlay slot & of relocation info */ int ovlslot; /* slot # to put overlay in */ char topfuncts[10][32]; /* names of top level functions */ int ntops; /* number of top level functions */ char *relstart; /* beginning of relocation info */ char *relnext; /* next relocation value */ e, argv[1]); strcpy (&ovlname, argv[2]); progp = TRUE; for (i = 3; i < argc; ++i) { if (argv[i][0] == '-') { if (!strcmp (argv[i], "-L")) progp = FALSE; else if (match (argv[i], "-ND")) srchdefs = FALSE; else printf ("Unknown option: '%s'\n", argv[i]); } else { if (progp) strcpy (&progfiles[nprogs++], argv[i]); else strcpy (&libfiles[nlibs++], argv[i]); } } } getdesc() /* get & process overlay description */ { makeext (&rootname, "DES"); if (fopen (&rootname, &bdsbuf) < 0) Fatal ("Can't open overlay descriptor file '%s'.\n", &rootname); if (fscanf (&bdsbuf, "%d%d", &ovlsize, &relsize) < 2 || ovlsize <= relsize) { Fatal ("Error in descriptor file: bad overlay/relocation sizes.\n"); } getlibs(); findovl(); readfuns(); fclose (&bdsbuf); } getlibs() /* get default search list */ { char line[MAXLINE], *cp, *dest; repeat { if (!fgets (&line, &bdsbuf) || !line[0]) break; if (!srchdefs) continue; cp = &l */ cclose (&ibuf); } } linklibs() /* link in library files */ { int ifile; for (ifile = 0; ifile < nlibs; ++ifile) scanlib (ifile); while (missingp()) { puts ("Enter the name of a file to be searched: "); gets (&libfiles[nlibs]); upcase (&libfiles[nlibs]); scanlib (nlibs++); } acodend.b = codend.b - lspace + buforg; /* save that number! */ } missingp() /* are any functions missing? print them out */ { int i, foundp; foundp = FALSE; for (i=0; i= 0) { if (nread) { if (!skipping) { if (match (&tname, &ovlname)) found = TRUE; else skipping = TRUE; } } else skipping = FALSE; } if (!found) Fatal ("Can't find description of overlay '%s'.\n", &ovlname); if (nread < 2) Fatal ("No slot number present for overlay '%s'.\n", &tname); printf ("Building overlay %s, for slot %d.\n", &tname, ovlslot); } readfuns() { char tname[40]; struct funct *fnct; ntops = 0; RelInit(); codend.b = lspace; /* build table of functions */ puts ("Functions included:\n"); while (fscanf (&bdsbuf, "%s", &tname) > &dir)); /* find end of dir */ ++dir.b; len = *dir.w - 0x205; readobj (len); } readobj (len) /* read in an object (program or lib funct) */ unsigned len; { if (codend.b + len >= lspcend) Fatal ("-- out of memory!\n"); lodstart = codend.b; if (cread (&ibuf, lodstart, len) < len) Fatal ("-- read error (read 0x%x)!\n", len); } scanlib (ifile) int ifile; { int i; union ptr dirtmp; makeext (&libfiles[ifile], "CRL"); if (copen (&ibuf, libfiles[ifile]) < 0) { printf ("Can't open %s\n", libfiles[ifile]); return; } printf ("Scanning %s\n", &libfiles[ifile]); if (cread (&ibuf, &fdir, 512) < 512) /* read directory */ Fatal ("-- Read error (directory)!\n"); for (i=0; ifaddr; /* link in reference */ RelAccum (codend.w); /* relocate this address */ fnct->faddr = codend.w++; ntops++; } puts ("\n\n"); } linkprog() /* link in all program files */ { int i; union ptr dirtmp; struct funct *fnct; for (i=0; iflinkedp) linkmod (fnct, lodstart + *dirtmp.w - 0x205); else { puts (" Duplicate program function '"); puts (&fnct->fname); puts ("', not linked.\n"); } dirtmp.w++; } /* intern & link ittr direntry; { unsigned start, len; skip7 (&direntry); start = *direntry.w++; skip7 (&direntry); len = *direntry.w - start; if (cseek (&ibuf, start, ABSOLUTE) < 0) Fatal (" -- read error (seek 0x%x)!", start); readobj (len); } linkmod (fnct, modstart) /* link in a module */ struct funct *fnct; union ptr modstart; /* loc. of module in memory */ { union ptr temp, jump, /* jump table temp */ body, /* loc. of function in memory */ code, /* loc. of code proper in mem. */ finalloc; /* runtime loc. of function */ unsigned flen, nrelocs, jtsiz, offset; fnct->flinkedp = LINKED; finalloc.b = codend.b - lspace + buforg; chase (fnct->faddr, finalloc.b); fnct->faddr = finalloc.b; body.b = modstart.b + strlen(modstart.b) + 3; /* loc. of function body */ jump.i = body.i + (*modstart.b ? 1 : 0); for (temp.b = modstart.b; *temp.b; skip7(&temp)) { jump.i->address = intern (temp.b); ++jump.i; } ++temp.b; flen = *temp.w; counsigned loc; { union ptr temp; while (head.w) { temp.w = *head.w; *head.w = loc; head.u = temp.u; } } RelInit() /* initialize relocation accumulator */ { relstart = relnext = lspace; lspace += relsize; /* allocate some memory for relocs */ reladdr = lspace - 1; } RelAccum (addr) /* note another relocation */ char *addr; { unsigned delta; if (relnext - relstart >= relsize) { Deadly ("Out of relocation bytes (limit is %d)\n", relsize); relnext = relstart; } delta = addr - reladdr; if (delta >= 255) { *relnext++ = 255; *relnext++ = delta - 255; } else *relnext++ = delta; reladdr = addr; } RelFini() /* end of relocations */ { printf ("Relocation bytes used: %d (limit is %d)\n", relnext - relstart, relsize); *relnext = NUL; } wrtovl() /* write overlay into slot */ { int ovlfd; RelFini(); if (codend.b > lspace + ovlsize - relsize) Deadly ("Code too long!\n"); movmem (relstart, lspacde.b = jump.b; temp.b = body.b + flen; /* loc. of reloc parameters */ nrelocs = *temp.w++; jtsiz = code.b - body.b; offset = code.b - codend.b; while (nrelocs--) relocate (*temp.w++, body.b, jtsiz, finalloc.b, offset, flen); flen -= jtsiz; movmem (code.b, codend.b, flen); codend.b += flen; } relocate (param, body, jtsiz, base, offset, flen) /* do a relocation!! */ unsigned param, jtsiz, base, offset, flen; union ptr body; { union ptr instr, /* instruction involved */ ref; /* jump table link */ struct funct *fnct; if (param == 1 && jtsiz) return; /* don't reloc jt skip */ instr.b = body.b + param - 1; if (instr.i->address >= jtsiz) { instr.i->address += base - jtsiz; RelAccum (body.b + param - offset); } else { ref.b = instr.i->address + body.u; if (instr.i->opcode == LHLD) { instr.i->opcode = LXIH; --ref.b; } fnct = ref.i->address; instr.i->address = fnct->faddr; /* link in */ if (!fnct->flinkedp) fe + ovlsize - relsize, relsize); makeext (&rootname, "OVL"); if ((ovlfd = open (&rootname, UPDATE)) < 0) Fatal ("Can't open overlay file '%s'.\n", rootname); if (seek (ovlfd, ovlslot * ovlsize / 128, ABSOLUTE) == -1 || write (ovlfd, lspace, ovlsize / 128) == -1) Fatal ("Disk write error. Check slot # and size of .OVL file.\n"); close (ovlfd); } listfuns() /* list functions linked */ { int i, compar(); for (i = 0; i < ntops; ++i) ftab[i].flinkedp = i; while (i < nfuncts && ftab[i].flinkedp == EXTERNAL) i++; arydel (&ftab, nfuncts, sizeof(*ftab), ntops, i); nfuncts -= i - ntops; qsort (&ftab, nfuncts, sizeof(*ftab), &compar); ftab[nfuncts].faddr = acodend.b; puts ("\nContents of overlay:\n"); puts ("Entry no. Name Start Length\n"); for (i = 0; i < nfuncts; ++i) { if (ftab[i].flinkedp < 255) printf ("%8d", ftab[i].flinkedp); else puts (" "); printf (" %-8s 0x%4x 0x%4x\n", ftab[i].fname, ftab[i].faddr, ftnct->faddr = instr.b + 1 - offset; /* new list head */ if (fnct->flinkedp != EXTERNAL) RelAccum (instr.b + 1 - offset); } } intern (name) /* intern a function name in the table */ char *name; { struct funct *fptr; if (*name == 0x9D) name = "MAIN"; /* Why, Leor, WHY??? */ for (fptr = &ftab[nfuncts-1]; fptr >= ftab; --fptr) if (!strcmp7 (name, fptr->fname)) break; if (fptr < ftab) { fptr = &ftab[nfuncts]; strcpy7 (fptr->fname, name); str7tont (fptr->fname); fptr->flinkedp = FALSE; fptr->faddr = NULL; ++nfuncts; } return (fptr); } dirsearch (name) /* search directory for a function */ char *name; { union ptr temp; for (temp.b = &fdir; *temp.b != 0x80; nextd (&temp)) if (!strcmp7 (name, temp.b)) return (temp.b); return (NULL); } nextd (ptrp) /* move this pointer to the next dir entry */ union ptr *ptrp; { skip7 (ptrp); ++(*ptrp).w; } chase (head, loc) /* chase chain of refs to function */ union ptr head; ab[i+1].faddr - ftab[i].faddr); } printf ("End address: 0x%x\n", acodend.u); i = ovlsize - relsize - acodend.u; printf ("Code bytes remaining: 0x%x = %d.\n\n", i, i); } compar (f1, f2) /* compare two symbol table entries by name */ struct funct *f1, *f2; { /* return (strcmp (&f1->fname, &f2->fname)); alphabetical order */ return (f1->faddr > f2->faddr); /* memory order */ } loadsyms() /* load base symbol table (for overlay) */ { /* symbol table must be empty! */ int nread; FLAG done; char *c; makeext (&rootname, "SYM"); if (fopen (&rootname, &bdsbuf) < 0) Fatal ("Can't open %s.\n", &rootname); done = FALSE; while (!done) { nread = fscanf (&bdsbuf, "%x%s%x%s%x%s%x%s", &(ftab[nfuncts].faddr), &(ftab[nfuncts].fname), &(ftab[nfuncts+1].faddr), &(ftab[nfuncts+1].fname), &(ftab[nfuncts+2].faddr), &(ftab[nfuncts+2].fname), &(ftab[nfuncts+3].faddr), &(ftab[nfuncts+3].fname)); nread /= 2; if (nread < 4) done = TRUE; ink ("a:$$$$.cmd"); #else unlink ("a:$$$.sub"); #endif } bios (1); /* bye! */ } /* End of MAKOVL.C -- link and store relocatable overlay */ ("a:$$$.sub"); #endif } bios (1); /* bye! */ } /* End of MAKOVL.C -- lin /* Tabify.c written by Leor Zolman This filter takes sequences of spaces in a file and turns them, whenever possible, into tabs. Usage: A>tabify oldfile newfile Quoted strings are not processed, but there should NOT be any `lone' double quotes within the file being tabified. */ #include int scount, column, ifd, ofd, i; int c; char ibuf[BUFSIZ], obuf[BUFSIZ]; main(argc,argv) char **argv; { if (argc < 2 || argc > 3) { printf("usage: tabify oldfile [newfile]\n"); exit(); } ifd = fopen(argv[1],ibuf); if (argc == 2) argv[2] = "tabify.tmp"; ofd = fcreat(argv[2],obuf); if (ifd == ERROR || ofd == ERROR) { printf("Can't open file(s)\n"); exit(); } scount = column = 0; do { cwhile (nread-- > 0) ftab[nfuncts++].flinkedp = EXTERNAL; } fclose (&bdsbuf); } makeext (fname, ext) /* force a file extension to ext */ char *fname, *ext; { while (*fname && (*fname != '.')) { *fname = toupper (*fname); /* upcase as well */ ++fname; } *fname++ = '.'; strcpy (fname, ext); } strcmp7 (s1, s2) /* compare two bit-7-terminated strings */ char *s1, *s2; /* also works for non-null NUL-term strings */ { /* char c1, c2, end1, end2; (These are now global for speed) */ repeat { _c1 = *s1++; _c2 = *s2++; _end1 = (_c1 & 0x80) | !*s1; _end2 = (_c2 & 0x80) | !*s2; if ((_c1 &= 0x7F) < (_c2 &= 0x7F)) return (-1); if (_c1 > _c2 || (_end2 && !_end1)) return (1); if (_end1 && !_end2) return (-1); if (_end1 && _end2) return (0); } } strcpy7 (s1, s2) /* copy s2 into s1 */ char *s1, *s2; { do { *s1 = *s2; if (!*(s2+1)) { /* works even if */ *s1 |= 0x80; /* s2 is null-term */ break; } ++s1; = getc(ibuf); if (c == ERROR) { putc(CPMEOF,obuf); break; } switch(c) { case '\r': putc1(c,obuf); scount = column = 0; break; case '\n': putc1(c,obuf); scount = 0; putchar('*'); break; case ' ': column++; scount++; if (!(column%8)) { if (scount > 1) putc1('\t',obuf); else putc1(' ',obuf); scount = 0; } break; case '\t': scount = 0; column += (8-column%8); putc1('\t',obuf); break; case '"': for (i = 0; i < scount; i++) putc1(' ',obuf); putc1('"',obuf); do { c = getc(ibuf); if (c == ERROR) { printf("Quote error.\n"); exit(); } putc1(c,obuf); } while (c != '"'); do { c = getc(ibuf); putc1(c,obuf); } while (c != '\n'); column = scount = 0; break; case CPMEOF: putc(CPMEOF,obuf); break; default: for (i=0; i= 0; --i) { nyb = (n >> (i * 4)) & 0xF; nyb += (nyb > 9) ? 'A' - 10 : '0'; putc (nyb, obuf); } } Fatal (arg1, arg2, arg3, arg4) /* lose, lose */ char *arg1, *arg2, *arg3, *arg4; { printf (arg1, arg2, arg3, arg4); exit (1); } Deadly (arg1, arg2, arg3, arg4) /* partially-recoverable error */ char *arg1, *arg2, *arg3, *arg4; { printf (arg1, arg2, arg3, arg4); puts (" -- overlay being generated anyway, for debugging.\n"); } exit (status) /* exit the program */ int status; { if (status == 1) { #ifdef SDOS unl 0; column++; putc1 (c,obuf); } } while (c != CPMEOF); fclose(ibuf); fclose(obuf); if (argc == 2) { unlink(argv[1]); rename(argv[2],argv[1]); } } putc1(c,buf) char c; { if (putc(c,buf) < 0) { printf("Write error (out of disk space?)\n"); exit(); } } casm $1 asm $1.aaz ;The "aa" should be changed to the proper disk for your system ddt $1.hex g0 era $1.asm era $1.hex ; now say "SAVE nn $1.crl", where nn is the decimal equivalent of the ; hex value printed out next to the "S" error in the above assembly... ; ; Mode-driven console I/O package ; Adapted from Steve Ward's CIO.C ; 9/82 by Leor Zolman ; ; This package provides a mode-driven direct console interface for applications ; where the standard library versions of "getchar", "putchar", etc., ; do  call arghak ;get arg1 = operation code, arg2 = arg push b again: call istat ;check input status jz brk ;any input? if not, go away mov c,a ;yes... put in C lda mode ;save current mode mov b,a ;save mode in B ani strip ;stripping parity? mov a,c jz rawio0 ani 7fh ;if so, strip parity rawio0: mov c,a ;and save for now. mov a,b ;get mode again ani swap ;swapping CR and LF? jz rawio1 mov a,c ;is it CR? cpi CR mvi c,LF jz rawio1 ;if so, turn into LF cpi LF ;is it LF? mvi c,CR jz rawio1 ;if so, turn into CR mov c,a ;otherwise leave it alone rawio1: mov a,b ;look at mode ani quit ;allowing quit characters? jz rawio2 ;if not, don't check for quitc ; ; Check for quits: ; lda quitc ;else do... cmp c ;char a quit char? jz exit ;if so, get out of here! rawio2: mov a,b ;look at mode ani flow ;recognizing flow control? jz rawio5 ; ; Handle Flow Control: ; mov a,c ;look at char cpi 'S'-64 ;control-S? jnz rawio4 rawio3: sta freeze ;if sonot provide enough control. The console I/O mode is set by calling the ; funciton "ttymode", where each bit of the argument controls a specific ; feature of the I/O mechanism, as follows: ; -------------------------------------------------------------- ;BIT: |7, 6 | 5 | 4 | 3 | 2 | 1 | 0 | ; | | swap CR &| LF --> |strip | x-on/ | quit | echo | ; USE: |not | and LF | CR-LF |bit 7 | x-off | char | mode | ; | used| (input) | (output) |(input)|(output)|(input)|(input)| ; -------------------------------------------------------------- ; ; Most features are self-explanatory; the "quit char" bit, if on, means ; that if the user types the standard system "Quit" character (set to ; control-C by default in the run-time package, and changeable by poking ; into the appropriate location), then program execution will be terminated ; and control will return to command level. ; ; Functions in this source file: ; ; putchar getchar kbhit ttymode ; ; "putchar", freeze things jmp brk rawio4: cpi 'Q'-64 ;control-Q? jnz rawio5 xra a ;if so, turn off freeze jmp rawio3 ; ; Save the char and echo if echo mode is on: ; rawio5: lda pending ora a ;any chars already stacked up? jnz brk ;if so, ignore new character inr a ;set pending flag sta pending mov a,c ;get the char sta pendch ;save it mov a,b ;echo mode? ani echo cnz putraw ;if so, put out the character brk: lda arg1 ;look at control code ora a ;null op? jz done ;if so, go return dcr a ;putchar? jnz brk3 lda freeze ;if frozen, ora a jnz again ;don't try to write till we get ^Q ; ; Put out a character to console: ; lda arg2 ;get the arg to putchar mov c,a ;write it to console call putraw ; ; Check for newline expansion: ; cpi NL ;'\n'? jnz brk2 lda mode ani expand ;expanding newlines? jz brk2 mvi c,CR call putraw ;put out CR if so brk2: lhld arg2 ;return the arg done: pop b ;restore BC ret brk3: dcr a ;getchar? jnz , "getchar" and "kbhit" have the same calling format as the standard ; library versions. "ttymode" takes a new mode byte based on the diagram above, ; and returns the previous mode byte. ; INCLUDE NL: equ 10 CR: equ 0dh ; ; putchar(c) ; FUNCTION putchar EXTERNAL rawio call ma1toh ;get C in HL push h ;pass to rawio lxi h,1 ;pass "putchar" code to rawio push h call rawio ;put out the char pop d pop d ret ENDFUNC ; ; int getchar() ; FUNCTION getchar EXTERNAL rawio lxi h,2 push h ;pass "getchar" code to rawio call rawio pop d ret ENDFUNC ; ; int kbhit() ; FUNCTION kbhit EXTERNAL rawio lxi h,3 push h ;pass "kbhit" code to rawio call rawio pop d ret ENDFUNC ; ; int ttymode(newmode) ; FUNCTION ttymode EXTERNAL rawio call ma1toh ;get mode value push h ;pass to rawio lxi h,4 push h ;pass "ttymode" code to rawio call rawio pop d pop d ret ENDFUNC FUNCTION rawio EXTERNAL exitbrk4 ;yes. lda pending ;any pending input? ora a jz again ;if not, go poll input xra a ;else clear pending input flag sta pending lda pendch ;and return the char brk3a: mov l,a mvi h,0 pop b ret brk4: dcr a ;kbhit? jnz brk5 lda pending ;yes. return pending status. jmp brk3a brk5: dcr a ;set I/O mode? jnz done ;if not, don't do nuthin at all lda mode ;get mode mov l,a ;save old mode in L lda arg2 ;get new mode sta mode ;set it ani flow ;check if flow control is enabled jnz brk6 ;if it is, don't touch state sta freeze ;else make sure we're thawed by clearing freeze brk6: mvi h,0 ;clear HL pop b ret istat: mvi c,dconio ;prepare for direct console I/O BDOS call mvi e,0FFh ;interrogate console status call bdos ora a ;set Z if no char ready ret putraw: push b push d push psw mov e,c ;put char in E mvi c,dconio call bdos pop psw pop d pop b ret ch: ds 1 oldmode: ds 1 ENDFUNC end */ int h[4][2]; /* handicap position table */ char mine, his; /* who has black (*) and white (@) in current game */ char mefirst; /* true if computer goes first in current game */ main(argc,argv) int argc; char **argv; { char b[8][8]; int i; h[0][0] = h[0][1] = h[2][0] = h[3][1] = 0; h[1][0] = h[1][1] = h[2][1] = h[3][0] = 7; printf("\nWelcome to the BDS C OTHELLO program!\n"); printf("\nNote: `*' always goes first...Good luck!!!\n\n"); srand1("Do you want to go first? "); if (toupper(getchar()) == 'Y') mefirst = 0; else mefirst = 1; printf("\n\n"); do { clrbrd(b); prtbrd(b); i = game(b,4); mefirst = !mefirst; if (i==4) break; if (i=='Q') continue; printf("\n"); i = prtscr(b); if (i>0) printf(" You won by %d\n",i); else if (i<0) printf(" You lost by %d\n",-i); else printf(" A draw\n"); } while (ask("Another game? ")=='Y'); } game(b,n) char b[8][8]; int n; { char c; int ff; int i,j; handicap = 0; selfplay = ' ';  /* OTHELLO -- The Game of Dramatic Reversals written by Bert Halstead modified for BDS C by Leor Zolman This program is a good example of: a) structured, heirarchical function organization b) arrays as formal parameters c) use of the "qsort" library function Object of the game is for two players to alternate placing their marker someplace on an 8 by 8 grid, so that at least one of the opponent's pieces becomes surrounded by the moving player's peices -- causing the flanked pieces to flip 'color' and belong to the moving player. After 60 moves have been played (or if no player has a legal move left), the player with the most of his own pieces on the board wins. The playing pieces are '*' and '@'. You may choose to play either '*' or '@' for the first game; thereafter, you and the computer will alternate going first for each game. Whoever goes first always plays `*'. You enter a move as a two digit number, each digit being from 1 to 8, first digit representing  ff=0; if (mefirst) { mine = BLACK; his = WHITE; printf("\nI go first:\n\n"); } else { mine = WHITE; his = BLACK; printf("\nYou go first:\n\n"); } while(1) { if (cntbrd(b,EMPTY)==0) return 'D'; if (cntbrd(b,EMPTY)==60 && mine == BLACK) goto Istart; if (chkmvs(b,his)==0) { printf(!mefirst ? "Forfeit" : " ...Forfeit\n"); ff |= 1; } else switch (c = getmov(&i,&j)) { case 'B': prtbrd(b); continue; case 'S': i= prtscr(b); if (i>0) printf(" You're winning\n"); else if (i<0)printf(" You're losing!\n"); else putchar('\n'); continue; case 'Q': case 4: return c; case 'H': if (n>abs(handicap)+4) printf("Illegal!\n"); else for (j=0; i!=0; j++) { b[h[j][0]][h[j][1]]= i>0?BLACK:WHITE; handicap += i>0 ? 1 : -1; ++n; i += i>0 ? -1 : 1; } prtbrd(b); continue; case 'A': analyze(b,his,mine,EMPTY); continue; case 'G': my_mov(b,his,mine,EMPTY,&i,&j); case 'M': if (chkmov(b,his,i,j)>0) { printf(!row and second representing column. For example: if playing '*', your first move might be '46', meaning 4th row down, 6th position across. As an alternative to entering a move, one of the following commands may be typed: g causes computer to play both sides until game is over a causes computer to print out an analysis of each of your possible moves. A letter from A to Z will appear at each of your legal move positions, where A is the machine's opinion of an excellant move and Z is a real loser. hn sets handicap. n is 1,2,3, or 4. If n is positive, gives n free pieces to the computer. If n is negative, gives YOU the free peices. f forfeit the current move. This happens automatically if you have no legal moves. q quit the current game. b prints out board again. s prints out the score, and tells who is winning. */ #define BLACK '*' #define WHITE '@' #define EMPTY '-' int handicap; char selfplay; /* true if computer playing with itself mefirst ? "%1d-%1d" : " ...%1d-%1d\n", i+1,j+1); putmov(b,his,i,j); } else { printf("Illegal!\n"); continue; } break; case 'F': if (n>abs(handicap)+4) { printf ("Illegal!\n"); continue; } else printf(!mefirst ? "Forfeit" : " ...Forfeit\n"); } Istart: if (cntbrd(b,EMPTY) == 0) return 'D'; if (chkmvs(b,mine)==0) { printf(!mefirst ? "...Forfeit\n": "Forfeit...\n"); ff |=2; } else { my_mov(b,mine,his,EMPTY,&i,&j); printf(!mefirst ? "...%1d-%1d\n" : "%1d-%1d...\n", i+1,j+1); putmov(b,mine,i,j); ++n; } if (ff==3 || n>64) return 'D'; if (!(ff & 1)) prtbrd(b); ff = 0; } } prtscr(b) char *b; { int i,j; printf("%1d-%1d",i = cntbrd(b,his), j=cntbrd(b,mine)); return i-j; } char getmov(i,j) int *i, *j; { char a,c; int n; char *p; char skipbl(); if (selfplay == 'G') { if (!kbhit()) return 'G'; selfplay = ' '; getchar(); } printf("Move: "); while(1) switurn !(c1==o && c2==e || c1==e && c2==o); } notak2(b,p,o,e,x,y,m,n) char b[8][8],p,o,e; int x,y,m,n; { x += m; y +=n; if (x>=0 && x<=7 && y>=0 && y<=7) while(b[x][y] == 0) { x += m; y+=n; if (x<0 || x>7 || y<0 || y>7 || b[x][y]==e) return o; } while (x>=0 && x<=7 && y>=0 && y<=7 && b[x][y]==p) { x +=m; y+=n; } if (x<0 || x>7 || y<0 || y>7) return p; return b[x][y]; } putmov(b,p,x,y) char b[8][8]; char p; int x,y; { int i,j; b[x][y] = p; for (i= -1; i<=1; i++) for (j= -1; j<=1; j++) { if ((i != 0 || j!=0)&&chkmv1(b,p,x,y,i,j)>0) putmv1(b,p,x,y,i,j); } } putmv1(b,p,x,y,m,n) char b[8][8]; char p; int x,y,m,n; { while ((x += m) >= 0 && x<8 && (y += n)>=0 && y<8) { if (b[x][y] == EMPTY || b[x][y] == p) return; b[x][y] = p; } } struct mt { int x; int y; int c; int s; }; my_mov(b,p,o,e,m,n) char b[8][8],p; int *m, *n; { struct mt t[64]; int i,k; int cmpmov(); k = fillmt(b,p,o,e,t); if (!k) rtch (c=skipbl()) { case '\n': printf("Move? "); continue; case 'G': if ((c = skipbl()) != '\n') goto flush; selfplay='G'; return 'G'; case 'B': case 'S': case 'Q': case 'F': case 'A': a=c; if (( c = skipbl()) != '\n') goto flush; return a; case 'H': if ((a=c=skipbl()) == EMPTY) c=getchar(); if (c<'1' || c>'4' || skipbl() !='\n') goto flush; *i = a==EMPTY? -(c-'0') : (c-'0'); return 'H'; case 4: return c; default: if (c<'1' || c>'8') goto flush; *i = c-'1'; c = skipbl(); if (c<'1' || c>'8') goto flush; *j = c- '1'; if ((c=skipbl()) == '\n') return 'M'; flush: while (c != '\n' && c != 4) c=getchar(); if (c==4) return c; printf ("Huh?? "); } } char ask(s) char *s; { char a,c; printf ("%s ",s); a=skipbl(); while (c != '\n' && c != 4) c= getchar(); return a; } char skipbl() { char c; while ((c = toupper(getchar())) == ' ' || c=='\t'); return c; } chkmvs(b,p) char b[8][8eturn 0; qsort (&t, k, 8, &cmpmov); for (i=1; i= 0 && x < 8 && (y += n) >= 0 && y<8) { if (b[x][y]==EMPTY) return 0; if (b[x][y]== p ) return k; if (x==0 || x==7 || y==0 || y==7) k += 10; else k++; } return 0; } notake(b,p,o,e,x,y) char b[8][8]; char p,o,e; int x,y; { return notak1(b,p,o,e,x,y,0,1)&& notak1(b,p,o,e,x,y,1,1)&& notak1(b,p,o,e,x,y,1,0)&& notak1(b,p,o,e,x,y,1,-1); } notak1(b,p,o,e,x,y,m,n) char b[8][8],p,o,e; int x,y,m,n; { int c1,c2; c1 = notak2(b,p,o,e,x,y,m,n); c2 = notak2(b,p,o,e,x,y,-m,-n); remov(a,o,k,l); if (c==0) continue; dkl = 1; if (k==0 || k==7) { dkl+=2; oside|=4;} if (l==0 || l==7) {dkl+=2; oside|=4; } if (dkl==5) {dkl = 10; oside |= 16; } else if (!notake(a,o,p,e,k,l)) continue; oside |= 1; s -= dkl; if (c>=10) { s -= 4; oside |= 8; } } if (s< -oside) s= -oside; if (side>0) return s+side-7+10*ok; if (i==1 || i==6) {s--; side++;} if (j==1 || j==6) {s--; side++;} if (side>0) return s; if (i==2 || i==5) s++; if (j==2 || j==5) s++; return s; } cmpmov(a,b) struct mt *a, *b; { if ((*a).s > (*b).s) return -1; if ((*a).s < (*b).s) return 1; if ((*a).c > (*b).c) return -1; if ((*a).c < (*b).c) return 1; return 0; } clrbrd(b) char b[8][8]; { int i,j; for (i=0; i<8; i++) for (j=0; j<8; j++) b[i][j]= EMPTY; b[3][3] = b[4][4] = BLACK; b[3][4] = b[4][3] = WHITE; } prtbrd(b) char b[8][8]; { int i,j; printf(" 1 2 3 4 5 6 7 8\n"); for (i=0; i<8; i++) { printf("%2d",i+1); for (j=0; j<8; j++) { putchar(' '); putchar(b[i][j]); } putchar('\n'); } putchar('\n'); } cpybrd(a,b) char *a, *b; { int i; i=64; while (i--) *a++ = *b++; } cntbrd(b,p) char *b, p; { int i,j; i= 64; j=0; while (i--) if (*b++ == p) ++j; return (j); } /* Sieve of Eratosthenes benchmark from BYTE, Sep. '81, pg. 186. Compile by: A>cc sieve.c -e1000 All variables have been made external to speed them up; other than that one change, the program is identical to the one used in the BYTE benchmark....while they got an execution time of 49.5 seconds and a size of 3932 bytes using v1.32 of the compiler, ******** v1.45 clocks in at * 15.2 * seconds with a size of 3718 bytes! ******** */ #define TRUE 1 #define FALSE 0 #define SIZE 8190 #define SIZEPL 8191 char flags[SIZEPL]; int i,prime,k,count,iter; main() { printf("Hit return to do 10 i !!CRREADME UQ UTKWIC DQT UTKWIC OQTUTOOL DQC)%UTOOL MQNNF!!!! n&!R!!!! n&!Rv/README.UT5 o !"#$%&'()*+,-./01234$z"+!]o:$r~f:DH8.Ӵ$7 1̧W_% lOW\7B"+D 8@"!pJ{B000ڹas?ftn&[Qc=D&8_U [HT)-H8.Ӵ*Iad/00zU vL"4{bxڡ 7=0; eC>I;$nz" m p\i?y`5>BS-8!մCAanITyx(.t_9ح.0wav eC^a!H;$n*5q\iǝGqj|0Z\qC.i`²:7/U=H*`A-  UoF!1$4sw6av/S ˆٜ@=liK:M [p(#m p\i?|~}Cm|E0<6% me 0䲚V gH$aterations: "); getchar(); for (iter = 1; iter <= 10; iter++) { count = 0; for (i = 0; i <= SIZE; i++) flags[i] = TRUE; for (i = 0; i <= SIZE; i++) { if (flags[i]) { prime = i + i + 3; k = i + prime; while (k <= SIZE) { flags[k] = FALSE; k += prime; } count++; } } } printf("\7\n%d primes.\n",count); } /* Sieve of Eratosthenes benchmark from BYTE, Sep. '81, pg. 186. Compile by: A>cc sieve.c -e1000 All variables have been made external to speed them up; other than that one change, the program is identical to the one used in the BYTE benchmark....while they got an execution time of 49.5 seconds and a size of 3932 bytes using v1.32 of the compiler, ******** v1.45 clocks in at * 15.2 * seconds with a size of 3718 bytes! ******** */ #define TRUE 1 #define FALSE 0 #define SIZE 8190 #define SIZEPL 8191 char flags[SIZEPL]; int i,prime,k,count,iter; main() { printf("Hit return to do 10 iJW܏n&ÉR!9!@Co|g}o|¬RÓR!Co!9DM!@Co|g}o|S!!|SDP`is{R`in}v/UTKWIC.DAT$  !"#os/qD#f̧4^(`9J%#_j>xyȗ8"}ϓc}F_ Gmχ'c}>kŹZȗ8"}oŃ3VUv<8bn%'%HoQku*(y|#s$|=kn9|#_1xK%#_41-̓g%Hok՛VUvKgxZ|fG7۪x~#_M)2OKd`7|znN혜-KZOƫ'%~?fvUTKWIC.OUT@ o !"#$%&'()*+,-./0123456789:;<=>?훯{]* {OqDr+ywV 6)H_~!6oشb5B>˕ۮYV}D>˕ۮdgvz#k)H_vywŦMk>|#җ+JvZrG9b,Vɼ_>ӧJG|^}S%|#|FrM{e>@>˕7Gcq/}|#җ+hɎ{1Z>A>˕y{ |#җ+/)H_~37{@>˕/U;˪O˕߾b+wE7{@>˕ۯ˝6_ՍS.Wn6_^hel S.Wn?;s2hsG vrubgvzwUg˕wv0ȧ}:k6H_ܮN!27Z7O1zWul\isG c8"]vuvklr/Z7S\Sklr/Z7S\} ;mzN|#N/=')HoinzLoygސO]S/WnC+:;4+f\}v;|hv)H_{]*!S\?f_Κ#l"cx9hի}C>ur싌 wUg˕6Cd o}m!c8"}rebgvzC>wUg˕wv0~;ij}[C=L|#җ+?fشbi͇OqDr嶷JvZrG>iU2/zrUCXȧ8"cJ^/Wn{+h%O1zWul.Wn{{e>OqDr̽$|#җ+_^cː{^W|#җ+<;m>xξ6hի}C>]YqDr嶷;;mܫ=')Ho+͗v27|y='B>r6_^ޠ͗9s./S.Wn?;;rnȧ8"]ܾym%v^gPeArC+C]YqDz\ ڼQbӊ5B>uiny6vh1Ds^W|׻_Ί|׻f/VܑOqD#ƂU2/zr1;vXNX{F+ G/Wn_>7vXV}D>˕7lˋ#Ұi˕HvXݳD|#җ+Z;Yoȧ}:k6H_ںYݳސO1zWuXqDr{9sE|׻Ú#җ+m>xξ6kjrߐO1zWuXqDrc+h%O1zWuXqDz\1;v2!X{F+ G/WnQ}n,>C|#җ+/bdc|,#l Hi˕7VܑOiU2/zrhOib,+?Fb1Tȧ4_>c\^kKrȧΊ|׻f#җ+1;GŽ$| H_%;>5hXF>G/Wn{gc\}gg}1!cʍmv#)}:k6H_~l"cx9hի}C>wUg˕OZ6G+y| >f_Κ#+i^ݠD>65]*6 5]*60!A]vUTOOL.DOC _ !"#$%&'()*+,-.rQ /0123456789:;<=> oS?@ABCDEFGHIJKLMNOP, QRSTUVWXYZ[\]^_`abcdefghijklmnoVEA>=<32pqrstuvwxyz{|}~u[N'L60<_;32^|6(?Xx;Of.V)n8;/ѤgFغ k2[Og~ϯtf-T/fx4~t{lZ_#;M8]g3|h:%ozƦl^/V3#җ+{y=Cv)8"}rscgY\]TYodm"cxC>G/Wn?N7~XlZ1شCȧ2^2z5oȧ;iZVqh%1!#ܾxrvjg2B>G/W cx9hի}C>]Yiny6v| ]~J9ZɣdS|̾U5.Wn?i/wv|W7zNSpDz\͗v27|y='B>G˕^[9To9ZɣdSpDz\Gcq/} VܑOqDU2/zr∱ሱ>OqDr嶿;s2hsGȧ8"]ܾxm%vx=CFr!vx=Cv)H_-y>F2)H_~%;>5cG/Wn>U2)HCrc)vO|#|1˕3;}dS&yrc)vO|#31˕OUYo G/Wn_ḿmvy!vrFΊF&ސOqDrLjYNX{F+27S\}gg}A|׻fzDO6C1}m!c.Wn{;;Cȧ8"}rsdUz,wS戱X%K^ܾwa}1!c8"}r^kp/} ʍ#b爱^@>4ݻa/27S|̾U5퇼wvB>˕_>C*G|^mv#O./Hi˕/|ya'cx͗9s6OqDz\=C_ϡ|cgG/WnbuzUl !3;M8V.8)בMAglA4Q 1j}˗Liiw߻G)6]>D|GAʥq>e)u"f>O#nW~|:)8)Jl8Y4Z~hgCv-u1iɭ7۫G޾~tS\qRxɭ7+ ~uiR}+v)O8֥I7D=cWY^7DMOzG^id~ӦӈG~M_sh}=]#p9gCغXs.GO#ág FzKW x;7xyw3?r%눧qw|X$0#~)ގD=+֑WXMhؕ>7xyw3·C+Mj#qٟQy_ˇx _/Z|Kӡ4-.Yz`S6=g3VR7+.M!lxgj}.1SW޾1xӏa~bcgQ.r?7~3Rn8_c2\ ui r?͈b^.fM=C|B/uX+·ϗ'Dk%Fm 'Nv:ގG|))}7lב?wnwb4cbb=q>̏_Ù?3,Y9_.~Z#FSqt3sۯ0?~t6~SUKYs=:|6a~bJ܉&o['V,a]]O|J3œ å+﫢IXyB6^rvLԳCiZ3JlzFn^ (Rnf>|vP\];<]R&~xyyRwr]<~O0+](uc+<|Qfx@n\>_чOg_iu݈߰j9N򤇜ƙܸd}0sڮW\ܕuåvF!idW8S㤋M#Cn\ffng3E:<Ȯ9Z٨?|Xe7w/];q.{ʮtQ_ē%#Nn\iZʮtQ_ē%O'^J;qʦi+E><~Of^VvܸdeӴH]I/4XDi+t[tvcnlu_r2[9~fk3?ߖxժht/Yz=+.s·wr3vxѸ/-zp.Glٯ;qpf_zv5UTOOL.MANg o !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOͮt]i1 &=:R>J7xq>xgv35No4+}$zS/LXq&C·c+~<~Gd Qn+]a?~ˌvF/v 2 F֥I7D=u?ǜ5Y7K(U<BĮtQxӏֻҵ71?-}gKnȭ7[_wQSjzS\ImdåzϺE\GI|NĮtQxӏRwk??᷺hg^Mٌxɭ7+Iy݋~L9jnbQ|FĪ%׏no߽/>(,a>'}~x48m1U O#T=>Wxg2q>̏_8$6TN}nF"=C·C.J5}5svXq~O?' +]ׇ\,gd[r3|]lUg,~JݞvP{Jv]i/^q>lC.J5}5svXq~O?' +]ׇ\,gd[rxf3/k/<]:8_+]xf;sb]J)k+<;.cr>D=QYb^idrPGM/KxD=cJ~<~Gd +]?>ٕ_J/a>'k6rx7m??PQRSTUVWXYZ[\]^_`abcdef/a-rq7ϟ~e(e:ϧ 324,}d_,7sXOˋŁOPre6ĥN|z弙˥Ne!|7nzɷ2|7{cZR\]]o[o,u֘O\\r]o,?~xˏ.wzcge_{Jx[o,'7v9Dxu{c9׍W7O~[o,|byRq15${jjr:}ĤQ5zcyRc.ټ(#E F_2gW'co,OrQ>jn5f$<Q[g5ڕ09sz{yKX+~]c-V]ͼzc9u:=_Eo,QfK\ė?xXΛ\Kc7YkuƸ!n3\]wnp:T͖O2+Z3v9tו.z7s:kg`:_L.f䛚jeo,oL=kqĥXe*5ͽ([o,'7v94S'^<}Xu'[o/{~ rq7ϟ~b[lMAfCzc9u:=_Eo,QfK\[?zc9orG|=lfFo3lL/ џsvx@_d;x!u1m9f;|!T]mY]ݶp)G=du$f xoߓUl[S]DP,lxӏRw /|OU+cY'q(n[lbywS%NXmU]pw1ãi9Es6q7ˇyo4_Ny|'y*czy;r>lZ~<_~yGbGeRe %k\7n|95X޸?\cjM3l)˕(3]o,otA12_+XGZ25ͽbuy^{FX\GJz,zք A7`=uyoXAX{cXGX~ fR'$nIjNz=Ll)zcy[Zڳ46ldOͭNܮ:]w|CYߛe~ۏtWzcyxwvvLJ[kYc[lMA]4zcy>ֳٛݎƜgojԉ:GcgX^a5z,So,oiȃ<;&}o,olg=7W(#>̔Bޮ_z=\\vږI<ˡ:!J왽'cqo,]6e<@o,N'ԡe^]?urh7sXOˋŁOPre6ĥN_?~zc9ork-v9t.{cy%Z7s:k'n=)oJ{:6W1۽ve3Ll S୻zc9gl7>.f.(w>\7n|^<}MoZ;rG&5.ș|xW7O<}c{rfdhx v9}o,_]1$]W:x.z{yKX'V..xg3r.$W:r.tiy{8IXΣf=}>{c9׭|2ra_ o<~Gه}1Q'Nr7]Y~+o7Y3G23k*bsi7svnqo,voz՚Op[̮N\TJH6yI2iÛl'm{cC=sŎ{.6wۇ;7Ybo]ԉ$g}]FfCݘ^^v:rq7ϟ~wk\'Swyddh>rKy]17L(uczχzc9u:=_Eo,QfK\ėt[rR':3v9gu]ùNÌ]qގ/#_UoYc>Ŏ]{F} W6ۭ&2$z-S5zcyrMvxw*v{z]jgJJl4ώu!rf3k˓I/4E+Mri6i]Q!6yPQ'.c-,}"zcyra-Z}%iRNfu)㮷XZvnqo,nyz{yKHV..x =n1%<"Mݘ bdf\aCso:xZ^/|R7(Y%.u޺~z弙˥N,oۑ ^7ro˓y;|ˡXۑÌ]q/7^oYc>A\=h`dhf]ve3nJ\ˡ(WbW'ۍkڕ0YWۏzcvSs^ƌ޷YcP8yw7svnqo,vp+_fCsoZ;o7fC3eQnJpnJoXޮG9s/rsYԉ/_?^Vo7sԉu2.zcv|k˓3vuzV=yI7}̸Dc|m\'.FՃXۍO,or:;ro7>n>^^v]rq7ϟ~7{3X]ܾt;z\6>"|q:Gz,q_~zc9orybk{-xp8-r[go7fdh1#k l)X޾kW6Lx1#C3W1o-@x1#C3>+9Q\G))Ko,O."6Wfvunݸ7'+lۍY&LqU3.{cyrvu˨X,2Xe*5֫mr19cW7O7sx xu7rj'7\϶m#'ۍ#C5\2fB&Ž-{cyց+2՚f2[SY޸*^l)(AqI12_+XGZ25ͽbuz~={so,o卫H7YeBښгX1=uPo,o}XLe&Q7b}bYe*52Ͻuy3wWuu]7ӤX5Swl'`[lMqۚײ՞Xg#CwuyO'n7_~vW+v>}۲>[nr˓4m5k]f,}䣋zcy-Oo^-)cgsnI&rJ=>QlM<1xyuҾz{yK8Ň ^y_)Ye7YkŊbaov94z\6>"|q:Gz,qo]z弙˥N,obv9tO<ˡGz 'v+pm |{f/twGݘek(#⪼ɱϦA: Ş#c193GNcqo,oek(&ͦQdl7YAsAļ4i+Co,Onߺq+yeG>7'?q+`Aa? ʩnJ뗸<̇ ^y߮BqyqaxobGx%ޛ{c90Sb(r.tiy{8IXΣf= xzc9or.3X<\/xO[o,u֘OpryvBqy`=iFX\Px/^p8;~dXU=#CÌ^hz`cs7}{~򥏘b:6W1x/[q8zcOM3.);kGY˨z{yKpqX??)Ì2`dhСXecN<-/r>Cy٬:㗮?xXΛ\.9zc9׭|\=hqe;e(qX~qqve3[zc9gl7>|˹nī_魷׽]ao?߮7yuqPbO+СXecN<-/r>Cy٬:q}7f.:%~QAxCr[g(ۭb+u]1[eOݱ7svyǽۍOyJPoZrPbOxC95|To,o-v9áXbv9t[r/ݳˡ]fˡ{2X5v9Hkuz :]o3Xި!U.Xu'95X޸?pUާ2ۍ˓f!f3up[o/{~I:+~ĞulڳˡXecN<-/r>Cy٬:qx{弙˥N,odw9[o,'7^<}Xu'95X]f,}+G7'Gv9Z 9dc9ozcy2 :6W^ԭ]Szcyҡ^^v{ao?/Ќ+ۍyOo>ӞbvS zc9&֖ {7iqְ7{7sXOˋŁOPre6ĥN?^_[o,\.ubyga.\'s[{圱ƫ|˹ny^^v+~^)gvʰzc9u:=_Eo,QfK\rR'7S[c;q1b˗җzcy2rXu1b\2۽ve3w<jb[.^Kb ۲EY*mԁ3\{cys(h•m҇Xz׮lٕ1뮷zc9gl7>;ro7>)Úz՚O,oNW=egMGRS7'w;\ J$6qUˌX~QF\mfJ{RM񢌍ޮ_vrq7ϟ~5^h2}!n3ֱg\lf_Wv94rvxV=[M zc9u:=_Eo,QfK\[߹zc9or![a_W.׭9Q'<}qQ^#:X3%L*f ն7w9ĭut|G |^^j~:ޮ_rq7ϟ~f*1bTVk{\6>"|q:Gz,qo_[o,\.ubyXx+?W(ncKYw *Yl512tO|`^CzM3.yؘг7'x;|wĥeS+sLz圱ƫ|˹nyzc9Gw\WTkf*qX>=j|Tazcyrg#Cw|jn]ۇ7o˪;>]41w|:]w|+w|5n?{&gìk1Xe4+=o2O+eRo,_kKw䎽f3Nք%52c1|Y݌=We+uAo3lc`ٔI\VX(Ye"fߖUa2fX5Sw̛Ho,_]e`VֲEaθ"cvUf=7fl\yuƇX~,>#\Qaxo&yZ)gٽ<Y|buk٦`4<سzuo/a<䰦1e۲*~7\'k.yf6yW82zci3.˕KpArXԍr.tiy{8IXΣf=ԉ{\'Xa;ikFe=R7nGֺ rR'd>D~ƻb7svnqo,vozuo/aSao?1UX{g2r઼q{zYk }zc9u:=_Eo,QfK\rR'{+frou2;ƻ7sv;ro7>_ z{yKxao?dNoz\6>"|q:Gz,q_oy3KXx//YV`C35X7Ӥ0)_7's{/kbk]`L|!97's=^V(cˡAPo3XXU=#Coro7>n>XQ.fΚsTVk`CQtWm?YZ=Wœq9z,SY7_,~-Ӟ=uNb=4ޮ_bގao?592ƛۑ`ov9t7sXOˋŁOPre6ĥN<^?{[rR'7^ۑf]Y7'/H3 ֍i6ZLݡɋy;Ҍw۽,v9]:רo7fX#4kbܿZuL}˓v&֍3lZ|[o,u֘O00oGT5ۍڙm˓1vM_nݘ)/f[&divSbˣ_nݘٖɽ<&`ގ4^1ѯQ7n̔G-{圱ƫ|˹nyzc9Gّݘ!.35ƛ|N}8v\ycP7n˓{:!רo7YxvC %u#C ťQ7n̳:}}˓xgسרo7Yp>p>ɗcLس CAL COMSCAT COMU?CH COMeCMP COMDCOMM COM=JCRCKLISTCRC*K͞+n*n*3'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2rרo7YxvC 1 JY3FK_nݘg9uñ7':ΎiĞ>cd5ۍyc #C<;;A=k|]}vcŎ]{F} W6ۭ&2$z-S5zcyrMvxw*v{z]jgJt7sXOˋŁOPre6ĥN<^?{[rR'7^ۑf]Y7'/H3 ֍i6ZLݡɋy;Ҍw۽,v9]:רo7fX#4kbܿZuL}˓v&֍3lZ|[o,u֘O00oGT5ۍڙm˓1vM_nݘ)/f[&divSbˣ_nݘٖɽ<&`ގ4^1ѯQ7n̔G-{圱ƫ|˹nyzc9Gّݘ!.35ƛ|N}8v\ycP7n˓{:!רo7YxvC %u#C ťQ7n̳:}}˓xgسרo7Yp>p>ɗcLس+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ÿHßdZ *!L9DM̓! ͡! s#r! s#r! s#r! s#r̓##~#f ~#fo! ^#Vr+sn&|'!! ~#fo! ^#Vr+sn&|Q!! ~#fo! ^#Vr+sn}/u!! ~#fo! ^#Vr+sn&|Ÿ!! ~#fo! ^#Vr+sn&|!! ~#fo! ^#Vr+sn}/!! ~#fo! ^#Vr+sn&|!! ~#fo! ^#Vr+sn&|A!!]i&l&í!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fow}! ~#fo͐)~#fon}<|+M>dò! ~#fo͐)~#fo#n};*! ~#fo͐)~#fo#K#|‹! ~#fo͐)~#fo#!!NQ*6!! ~#fo͐)~#foT|*n&|g}os*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}J! ~#fo͐)!s#r! ~#fo͐)* s#rd*n&|g}os! ~#fo͐)~#fo#n}!!NQ! ~#fo͐)~#fo#W*! ~#fo͐)~#fo#Z#|! ~#fo͐)~#fo#!!NQ*on}-`̓##~#fon&ͤ|`! w#w! ! ^#Vr+s~#foͧ#|R! ͪ! ^#Vr+si! 6#6! ^#Vr+s!| ! ^#Vr+s~#fon}- ! ~#fo~#fo#! s#r͐n} ͐n}EGLR ! 6#6 ! 6#6 ! 6#6 ! 6#6 ! ͪ! ^#Vr+sêi`i! ^#Vr+s~#foͭ#|D ! ͪ͐|ʒ ! ̓~#foͭ#|o !! ͪ͐|Š ͐|Š ͐|ʒ !4 ͪ͐|¿ ͐|¿ ͐|¿ ͐|¿ ! 6#6͐| !! Ͱ ! ! Ͱ| ! ! ͳ| ÿ  ! ! ͭ͐|? `i! Ͷ|? !! ͹͐|l `i! Ͷ|l !! ͹͐|ʕ `i! Ͷ|ҕ !! ͹͐| `i! Ͷ| ! ! Ͷ| !! ͹ÿ ͼ!9cal: can't open filecal: invalid optioncal: invalid date1cal: invalid date2cal: no other options allowed with -rc {d!9DM! ~#fon! s! ~#fo#n! s! ~#fo###n! s! ~#fon! s! ~#fon! s! ~#fon! s! s! s! s! ] `is#r! ] !4w}‰͐! s#r͐͐ ~#foc! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s͐ ^#Vr+s`i^#Vr+s* ^#Vr+sï͐ ͐s#r! ~#fo͐ ~#fo)w#wý! ^#Vr+s`i^#Vr+s!9Can't open %s ͐! ns*! n&>#|!E!ADw&|g}o|;! G|!G+++|D! n} s#r! ] ! s#r͐|9 ! ~#fos#rK ! ~#fols#r͐|e ͐|k ! ͐|څ ͐|ڋ ! ͐>› >" >§ >" >³ >" >¿ >" > >" > >" > >" > >8 > >8 >  >8 >  >8 > >N í ͐|5 ! õ ͐|K ! õ ͐|— ͐d|~ ͐|— ͐|ڑ ! õ í ͐|ڪ ! õ ! ` ͐͐s#r͐##͐s#r͐͐s#r! !9in convdate -- can't happen(%;b&Z ß!9DM!͐! s#rzQ!!͐++! s#r͐! s#r͐! s#r͐͐ ͐͐|!! ! ~#fo͐! 6`i! "#|! ͐%!! ^#Vr+sÆ!!9/!9DM͐~#fo͐~#foG!͐~#fo͐~#fol!͐##~#fo͐##~#foҍ!͐##~#fo͐##~#foҮ!͐~#fo͐~#fo!͐~#fo͐~#fo!!ß!9DM! ͐n} ! !G! n&!G͐! ns!9File output error; disk full? pi&*!9DM!͐g!!gmj !9DM! n&|ͯ! n&|ͩ]'!9DM͐!͐s#rz!͐##w#w͐~#foóË !9DM`i6#6͐ ! s#r͐ ! s#r!|\͐#|b!! ^#Vr+s͐s{ ¬͐͐ #ҩ͐++n} ©! ^#Vr+s6 `i^#Vr+sz͐ ! s#rz͐|b͐|͐ ͐͐6͐ !94!9DM! ^#Vr+sn`is{l`in} M͐! ͐`in&#|i!r!r!9Áß!9DM`iw#w! 6#6͐ n! s{ ʴ! n} ! ^#Vr+sØ! n}-! 6#6! ^#Vr+s! ^#Vr+sn! s~|"͐ ?! nѯg`is#r͐͐?2!9!9DM͐͐Z͐^͐!9DM`iw#w! ^#Vr+sn}ʏ`i^#Vr+sp͐Ö!9!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{ñ͐!9 !y9DM! `i n}0$! ^#Vr+s!|0$! ^#Vr+s6 $F$! ^#Vr+s`ins\$! ^#Vr+s`ins=!͐6!9t$n$!9DM͐͐ $͐^#Vr+s͐گ$͐0÷$͐7s!& %͐ ͐͐ ͉͐q$`is͐ ͐͐ )͐q$`in&#& %!9%ß!9DM`iw#w͐~#fon&%}i%͐ ?͐^#Vr+snѯg`is#r*%͐p%!9%ó%!9DM! n&|%|ʦ%! n&í%! n&&!9DM! n&|ͯ%! n&|ͩ7**%!ɾ%#~&*%%7*|DM**G&><;&~# x;& >c>ʊ>o>ʘ>{>ʫ>‡>ʾ! n&7! n&!:! n&!:! n} ! !:! n&!:͐##^#Vr+s|H!͐͐~#fo=|'!͐##6#6͐͐s#r͐^#Vr+s! ns&t'&=(!9DM͐ڍ!ê͐##~#fo|¦!ê͐##~#fo`is#r͐͐͐~#fok͐!ê͐+?`is#r͐##~#fo|ʃ!͐͐͐n͐##~#fo͐s#r͐~#fo͐s#r!!͐~#foqê͐##6#6͐͐s#r!ê!9ÿJL'è(!9DM͐|Ͷ ͐+++|!͹ ͐##^#Vr+s|k|*u;(*~#("*s*u;(#"u*+"'C(H*7:,*@(:*e(}|2q ʖ(Œ(:qwʇ(! {w7:)~:,"s!"u*|(**s)! ~(6*u*+"*"*u#"u(:wo2w&7*!9& 6C#6O#6M\)*|r)!\&Ä)!\&*|„)!!l&!9~#foʴ)> +*#~¢)##Ö)xS)) W)EXECL: Too much text $!p*!*w#)*:1** *! *!a{ ѷ! , FNxg>Goyl*$*K͞+6 6 ('+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO !͐͐~#foͼ`is#r!|> ͐##^#Vr+s ͐##͐?+s#r͐͐s#r͐^#Vr+sn& !9Ñ )!9DM͐|° ! n&͎ ͐ ͐##~#fo| !͐^#Vr+s! ns͐##^#Vr+s!!n$ß%y%!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{_$`in}%I$! ! s#r! 6#6! s! s! s͐n}-ž!! ^#Vr+s! 4͐n}0®!! 4͐n&!}!! !!!! s#r! ^#Vr+sn`is{."! !! s#r! 4! ^#Vr+sn`is`in& !}DB"U~"Xʇ"Oʐ"C"S#3$͐~#fo|~"! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 Ö"! 6Ö"! 6! ~#fo! n&! ^#Vr+s~#fo! !ѯgs#r#! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s#! n}#! 6#6! ^#Vr+s~#fo! s#r͐n}#͐|#! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s5#͐6! ! s#r! n}#! ^#Vr+s!|#! ^#Vr+s! n}#!0#! sÛ#͐! ^#Vr+sns{#! ^#Vr+s#!)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>mpin.$$$tempin.$$$tempout.$$$>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-üþø wÚ úë Q!9DM̓! ͤ!  w#w! ^#Vr+s!|i! ^#Vr+s~#fon}-i! ~#fo~#fo#! s#r̓n}f̓n}W7C!  6#6X! !ͧͭͪ! ^#Vr+s̓|҃!  6#6Ë!  w#w̓ |Ͱ! s#rz̓ |̓͡&ͳ̓ͳÕ̓ |ƒ ! ^#Vr+s!|ڃ `i! ^#Vr+s~#foͶ#|2 ̓~#fo! !ͧͭͪ`i͹! s#rzʀ ̓|ʀ ̓ |s ̓͡&ͳ} ̓ͳ2 ͭ!9cat: invalid option cat: can't open %s w)zø!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo9 w}` 9 ! ~#fo͐)~#fon}<ʍ |A 7! ~#fo͐n! ~#fo͐nѯgWï!9þ%!9DM͐͐ͻs#rz!͐͐s#r͐##6#6͐~#foV!9DM͐.!͐~#foKëZY!9DM͐͐>n>ʕ>z>ʣ>†>ʶ>’>! n&B! n&!E! n&!E! n} ! !E! n&!E͐##^#Vr+s|S!͐͐~#foH|2!͐##6#6͐͐s#r͐^#Vr+s! ns&Y!9DM͐ژ!õ͐##~#fo|±!õ͐##~#fo`is#r͐͐͐~#fov͐!õ͐+?`is#r͐##~#fo|ʎ!͐͐͐y͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo|õ͐##6#6͐͐s#r!õ!9!9DM`iw#w! ^#Vr+sn}`i^#Vr+s͐!9 |ë!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{[`in}%E! ! s#r! 6#6! s! s! s+ʽ > " ! ~#fo͐)~#fo#n}« *! ~#fo͐)~#fo#ͻ #| ! ~#fo͐)~#fo#!B !; *6!Q ! ~#fo͐)~#fo |> *n&|g}osq *4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}ʺ ! ~#fo͐)!] s#r! ~#fo͐)* s#r *n&|g}os! ~#fo͐)~#fo#n} !j !; ! ~#fo͐)~#fo# *! ~#fo͐)~#fo# #|i ! ~#fo͐)~#fo#! !; *4w} ͐! s#r͐͐ ~#fo ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+sÆ ͐ ^#Vr+s`i^#Vr+s* ^#Vr+s ͐ ͐s#r! ~#fo͐ ~#fo)w#w- ! ^#Vr+s`i^#Vr+s@ !9Can't open %s UzXʃOʌCS/͐~#fo|z! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 Ò! 6Ò! 6! ~#fo! n&! ^#Vr+s~#fo! ѯgs#r{! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s{! n}! 6#6! ^#Vr+s~#fo! s#r͐n}{͐|{! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s1͐6! ! s#r! n}! ^#Vr+s!|! ^#Vr+s! n}!0! s×͐! ^#Vr+sns{! ^#Vr+s! n},! ^#Vr+s!|,! ^#Vr+s6 B! ^#Vr+s`insX! ^#Vr+s`ins9͐6!9p?!9DM! ^#Vr+sn`is{`in} ¦͐! m͐`in&m#|!x!!9!9DM͐͐ (͐^#Vr+s͐͐0͐7s!&s͐ ͐͐ ͉͐`is͐ ͐͐ )͐`in&#&s!9!#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)9DM! n&|ͯڧ! n&|ͩñ|!9DM`iw#w͐~#fon&ͮ}͐ ?͐^#Vr+snѯg`is#rÿ͐!9H!9DM! n&|;! n&B! n&&!9DM! n&|ͯs! n&|ͩ  !\&!7*!&*!&!&="&! BL<"e=L=}7*^#V#zx2(+V+^+ *:(o&9! !j96  #F#xU~#H7:O*7,2q*&:q):ʧ=ʧ=r:qo&7:)~:,"s!"u*|**s ! ~6*u*+"*"*u#"u.zk7*(\!*+#7:)~:,"s!"u*|*uʿ*~#–"*s*u¿#"u*+"Ã7*|DM**><~# x ><~+ x|}Ø7:,*:*:}|2q ka:qw\! {w7?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ù6 à R" !9DM̓"!  ̓͡ |!ͤ!" ^#Vr+s~#fo! ͧ! ! ͪ|!ͤ̓ ++|4! 6P!" ^#Vr+s~#fo! ͧ! ! ͭ|l!ͤ!`iͰ|ʓ! ! `iͳlͶ!9ch: missing patternch: illegal 'from' patternch: illegal 'to' string !9DM͐!!͐|ͯ"  )!!9DM! 6#6`iw#w! ~#fo͐n} !͐ ͐͐  ! s#r͐|ڰ ͐͐ʰ ͐͐͐͐  ͐! s#r͐| ͐͐ ! ~#fo͐n& `i^#Vr+s ͐`is#r9 !9 Õ!9DM! w#w͐ `is#r! ~#fo͐n! n}ʷ ! ~#fo͐n}ʷ ! ~#fo͐n}&ˆ !! ͐! ë !! ͐`i͐  `i^#Vr+s% ! ~#fo͐n! n} ! !! ͐! | ! *!9& 6C#6O#6M¬*|!\&!\&*|!!l&!9~#fo> +e#~##xS. çEXECL: Too much text $!pn!*w#:*:1T*]!]!a{ ѷ! , FNxg>Goy$!9DM! n&|g}os! n}! n} ! n}  ! n&4 ! n&|! ! n}+ ! &4 ! n&&*K͞+%3%3;'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o ͐ !9 )!!9DM`iw#w! ~#fo͐n}ʺ ! ~#fo͐n}— ͐ ! s#r͐͐ +ڔ ! ~#fo͐n& ! ^#Vr+s^ î ! ~#fo͐n& `i^#Vr+s' !9 O#.!9DM!͐ !!  ù#!9DM`i6#6͐n}ʑ ͐n}#: ͐|͝`is#rÀ ͐|b ! ^#Vr+s͐n& sÀ ͐|€ ! ^#Vr+s͐ns! ^#Vr+sn ͐6!9æ !9DM͐!!͐ͣ |ͯ o !9DM! w#w͐! s#r͐|…! ~#fo͐n}ʅ! ~#fo͐n}*-! ~#fo͐͐ s#r͐`is#r͐|ž ! ~#fo͐n}ʞ ͐͐`i͐ |› ! 6#6V ! w#w͐|͐͐͐͐͐ ͐͐͐ ! s#r͐| ! 6#6`i^#Vr+sæ ͐! s#r! 6#6Â͐͐! ͐ |b! 6#6! 6#6Â! ~#fo͐͐ s#r ͐Ì!9!9DM͐~#fo͐ ڹ!! ~#fo͐~#fo! ns͐^#Vr+s!!9DM! ~#fo͐~#fo͐ ͐͐!]`! ~#fo͐͐ ~#fo͐+s! ~#fo͐~#fon}]͝_!9nÕ!9DM͐ ~#fo+`is#r͐͐ ͐#! s#r!! ͐! ~#fo͐n&k`i^#Vr+sÅ͐ ~#fo#s#r! ~#fo͐ 6*!9!9DM͐ ! ~#fo͐ nѯg`is#r͐͐ g! n! ~#fo͐n}[!md`i^#Vr+s&!m!9ÂÕø!9DM! ~#fo͐ ~#fon! n}ʯ! ~#fo͐ ~#fon}ʯ! ~#fo͐ ~#fon}\͐͐͐ ͐ ͐y&|á! ~#fo͐ ~#fon}-R͐͐͐ ! ~#fo͐ ~#fon&|á͐~#fo|}! ~#fo͐ ~#fo#n}š͐͐͐ !-|á! ~#fo͐ ~#fo+n&|ʇ! ~#fo͐ ~#fo#n&|ʇ! ~#fo͐ ~#fo+n! ~#fo͐ ~#fo#nѯgWڇ! ~#fo͐ ~#fo+n&#`is#r͐! ~#fo͐ ~#fo#nѯgy͐͐͐ ͐|`i^#Vr+s/͐ ^#Vr+sá͐͐͐ !-|͐ ^#Vr+sÊ!9!9DM! n&|! n&|!! n&| ! n&n}\!! ~#fo͐~#fon&! ~#fo͐~#fo#n}B!\&͐^#Vr+s! ~#fo͐~#fon}nʁ! ~#fo͐~#fon}Nˆ! &! ~#fo͐~#fon}tʼ! ~#fo͐~#fon}T! &! ~#fo͐~#fon}b! ~#fo͐~#fon}B!&! ~#fo͐~#fon}r2! ~#fo͐~#fon}R9! &! ~#fo͐~#fon}fm! ~#fo͐~#fon}Ft! &! ~#fo͐~#fon}pʨ! ~#fo͐~#fon}P¯!#&! ~#fo͐~#fon}q! ~#fo͐~#fon}Q!"&! ~#fo͐~#fon&ÕZh!9DM! w#w͐`is#r! w#w! w#w͐||! ~#fo͐n! n}|! ~#fo͐n}|͐! s#r! ~#fo͐n}?µ!! ͐!?[! ~#fo͐n}%͐͐!! ͐!%[! ~#fo͐n}$F! ~#fo͐#n! n}F!! ͐!$[! ~#fo͐n}[…! ͐`i͐ |͝! s#r[! ~#fo͐n}*͐͐͐! s#r! ~#fo͐n}%! ~#fo͐n}$! ~#fo͐n}*! 6#| !! n&|/! n&|/!!K#9$.p$.$!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#foҷw}÷! ~#fo͐)~#fon}< |ʿ+;>Rà! ~#fo͐)~#fo#n})m*! ~#fo͐)~#fo#9#|y! ~#fo͐)~#fo#!!<?*6!! ~#fo͐)~#foB|¼*n&|g}os*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}8! ~#fo͐)!s#r! ~#fo͐)* s#rR*n&|g}os! ~#fo͐)~#fo#n}}!!<?! ~#fo͐)~#fo#E*! ~#fo͐)~#fo#H#|! ~#fo͐)~#fo#!!<?*4w}w͐! s#r͐͐ ~#foQ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s͐ ^#Vr+s`i^#Vr+s* ^#Vr+sÝ͐ ͐s#r! ~#fo͐ ~#fo)w#wë! ^#Vr+s`i^#Vr+sþ!9Can't open %s *A #*6*A *6 *^#Vr+sn`is#6͐|!! !͐|!`i6 #6͐ !!98!Æ%9$.ò/!9DM!2"`is#rw}!! n} y!͐n} y!*! ,!͐! ns*! n&,!#|±!!3"!/!2!w&|g}o|!)"! 5!|!!5!+++|!2!! n} "͐n} "! !5!! n&!5!͐! ns!9File output error; disk full? ["()!9DM`i6#6͐ ! s#r͐ U"! s#r!|ʚ"͐#| "!F#! ^#Vr+s͐s{ "͐͐ #"͐++n} "! ^#Vr+s6 #`i^#Vr+sz#͐ U͐~#fo|<+! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 T+! 6T+! 6! ~#fo! n&! ^#Vr+s~#fo! )ѯgs#r=,! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s=,! n}+! 6#6! ^#Vr+s~#fo! s#r͐n}=,͐|=,! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s+͐6! ! s#r! n}”,! ^#Vr+s!|ڔ,! ^#Vr+s! n}ʋ,!0Î,! sY,͐! ^#Vr+sns{ʽ,! ^#Vr+sÔ,! n},! ^#Vr+s!|,! ^#Vr+s6 ,-! ^#Vr+s`ins-! ^#Vr+s`ins)͐6!92-,-!9DM͐͐ Ҁ-͐^#Vr+s͐m-͐0u-͐7s!&-͐ ͐͐ ͉͐/-`is͐ ͐͐ )͐/-`in&#&-!9!9DM! n&|ͯ-! n&|ͩ .-!9DM`iw#w͐~#fon&.}V.͐ ?͐^#Vr+snѯg`is#r.͐].!9l.à.!9DM! n&i.|ʓ.! n&Ú.! n&&!9DM! n&|ͯ.! n&|ͩ  !\&!7*!/&*!!/&"! s#rz#͐| "͐|9#͐ ͐X"͐6͐ F#!9U#Æ%!9DM! ^#Vr+sn`is{ʪ#`in} ‹#͐! R#͐`in&R##|§#!ð#]#!ð#!9ÿ#Î)!9DM! n&ͼ#|#! n& #! n&&#/!9DM͐!͐#s#rz#$!͐##w#w͐~#foB$ý)O#!y9DM! `i<$͐`i?$g$!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}$! ~#fo`i^#Vr+sn}$!$~$! ~#fo͐n! ~#fo͐nѯgW$!9%0!9DM͐͐%s#rz*%!͐͐s#r͐##6#6͐~#fo]%80!9DM͐u%!͐~#foZ%Ò%)!ò/;0!9DM͐;&͐>µ%>%>%>%>%>%>%>&;&! n&͉%! n&!͌%! n&!͌%! n} (&! !͌%! n&!͌%͐##^#Vr+s|š&!͐͐~#fo͏%|y&!͐##6#6͐͐s#r͐^#Vr+s! ns&&;0ã00!9DM͐&!'͐##~#fo|&!'͐##~#/!&="&! BL<"e=L=L/17*^#V#zT/x2/+V+^+c/*I/:/o&9! !j96  #F#xʭ/~#à/7:O*7,2q*&:q):/=/=r:qo&0./7* 0\!* 0#7:)~:,"s!"u*|*uʡ0*~#x0"*s*u¡0#"u*+"e07*|DM**0><0~# x0 ><0~+ x0|}027:,*0:*1}|2q M1C1:qw>1! {w7:)~:,"s!"u*|ʵ1**sº1! ~µ16*u*+"*"*u#"uÁ1:wo2w&7*!9& 6C#6O#6M2*|)2!\&;2!\&*|;2!!l&!9~#fok2> +2#~Y2##M2xSڕ2}2 2EXECL: Too much text $!p2!*w#¡2*:1»2*2!2!a{ ѷ!fo`is#r͐͐͐~#foͽ&͐E'!'͐+?`is#r͐##~#fo|'!͐͐͐&͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo&'͐##6#6͐͐s#r!'!9(8 ò/_1!9DM͐|((((͐+++|?(! ((͐##^#Vr+s|½(!͐͐~#fo(`is#r!|Ґ(͐##^#Vr+s(͐##͐?+s#r͐͐s#r͐^#Vr+sn&(!9!9DM`iw#w! ^#Vr+sn} )`i^#Vr+s(͐)!9 )1!9DM͐|?)! n&)͐])͐##~#fo|b)!͐^#Vr+s! ns͐##^#Vr+s!!9DM! n&|ͯڹ)! n&|ͩ),--.f.!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{-`in}%-! ! s#r! 6#6! s! s! s͐n}-\*! ^#Vr+s! 4͐n}0l*! 4͐n&)}ʉ*! )Ì*!! s#r! ^#Vr+sn`is{.*! )! s#r! 4! ^#Vr+sn`is`in&)}D+U<+XE+ON+Cʔ+S+, , FNxg>Goy#3$*K͞+"";+'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_~#fo͐)!Ts#r! ~#fo͐)* s#r *n&|g}os! ~#fo͐)~#fo#n} !a!͵ ͸ ! ~#fo͐)~#fo#; *! ~#fo͐)~#fo# #|` ! ~#fo͐)~#fo#!!͵ ͸ *4w} ͐! s#r͐͐ ~#fo ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s} ͐ ^#Vr+s`i^#Vr+s* ^#Vr+s͐ ͐s#r! ~#fo͐ ~#fo)w#w$! ^#Vr+s`i^#Vr+s7 !9Can't open %s ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ùï  @ È Ñ!9DM̓( !& ̓͡& >>>>$}! 6#6! !( ~#fo##~#foͤ#|!!o ͧÅ! w#w`i!( ~#fo##~#foͤ#|Q! ͧ! !( ~#fo~#foͤ#|z! ͧÅ! |’`i6 #6͐Ù!9ñæ?"!9DM!`is#rw}A! n} ͐n} *! ͥ͐! ns*! n&ͥ#|*!!ͨͫw&|g}o|Aâ! ͮ|a!ͮ+++|aͫ! n} „͐n} ʄ! !ͮ! n&!ͮ͐! ns!9File output error; disk full? 3!9DM͐!͐s#rz!͐##w#w͐~#forÇ!9DM`i6#6͐ ! s#r͐ ! s#r!|Y͐#|_!! ^#Vr+s͐s{ ©͐͐ #Ҧ͐++n} ¦! ^#Vr+s6 `i^#Vr+sz͐ ! s#rz͐|_͐|͐ ͐͐6͐ !9j!y9DM! `i`i!9B!9DM! ^#Vr+sn`is{ʗ`in} x͐! ?͐`in&?#|”!ÝJ!Ý!9ï<!y9DM! `iͩ͐`iͬ!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}7! ~#fo`i^#Vr+sn}4!c! ~#fo͐n! ~#fo͐nѯgWc!9rw!9DM͐ͧ! w#w̓ |ʨ!!  ͪõ`i!  ͪ! s#r! ! ͪ! s#r̓ |̓ |( ! ^#Vr+s! !  ͭ|% ! !  ̓ ! ͰÍ̓ |G ̓ |G ! ͳc ̓ |c ̓ |c ! ͳͶ!" 9cmp: can't open filecmp: can't open file 1cmp: can't open file 2usage: cmp file1 file2 or STDIN file%d %s%scmp: eof on file 1cmp: eof on file 2 <?Ñ!9DM!͐ !!>   !9DM͐n͐n} ͐n}h !! ^#Vr+s! ^#Vr+sH !Î æ!9DM͐! !͋ %s æ?Bl!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo0w}W 0! ~#fo͐)~#fon}<ʄ |8 +ʴ > ! ~#fo͐)~#fo#n}¢ *! ~#fo͐)~#fo#Ͳ #| ! ~#fo͐)~#fo#!9!͵ ͸ *6!H! ~#fo͐)~#foͻ |5 *n&|g}osh *4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}ʱ ! os#rzҗ!͐͐s#r͐##6#6͐~#foè!9DM͐!͐~#foâ"ë!9DM͐ڨ͐>">I>.>W>:>j>F>}è! n&! n&!! n&!! n} •! !! n&!͐##^#Vr+s|!͐͐~#fo|!͐##6#6͐͐s#r͐^#Vr+s! ns&3ë d !9DM͐L!i͐##~#fo|e!i͐##~#fo`is#r͐͐͐~#fo*͐ʲ!i͐+?`is#r͐##~#fo|B!͐͐͐-͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo0i͐##6#6͐͐s#r!i!9~ñ" !9DM͐|•uA͐+++|¬!xA͐##^#Vr+s|*!͐͐~#fo{`is#r!|͐##^#Vr+sA͐##͐?+s#r͐͐s#r͐^#Vr+sn&A!9!9DM`iw#w! ^#Vr+sn}w`i^#Vr+sX͐~!:*ʌ }|2q ʽ ³ :qwʮ ! {w7:)~:,"s!"u*|%!**s*!! ~%!6*u*+"*"*u#"u :wo2w&7*!9& 6C#6O#6Mƒ!*|™!!\&ë!!\&*|«!!!l&!9~#fo!> +<"#~!##ý!xS"! ~!EXECL: Too much text $!pE"!*w#"*:1+"*4"!4"!a{ ѷ! , FNxg>Goy"$*K͞+%%L.'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO9ÍE!!9DM͐|¬! n&͊͐͐##~#fo|!͐^#Vr+s! ns͐##^#Vr+s! ÜDs!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{[`in}%E! ! s#r! 6#6! s! s! s͐n}-š! ^#Vr+s! 4͐n}0ª! 4͐n&}! !! s#r! ^#Vr+sn`is{.! ! s#r! 4! ^#Vr+sn`is`in&}D>UzXʃOʌCS/͐~#fo|z! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 Ò! 6Ò! 6! ~#fo! n&! ^#Vr+s~#fo! ѯgs#r{! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s{! n}! 6#6! ^#Vr+s~#fo! s#r͐n}{͐|{! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s1͐6! ! s#r! n}! ^#Vr+s!|! ^#Vr+s! n}!0! s×͐! ^#Vr+sns{! ^#Vr+s! n},! ^#Vr+s!|,! ^#Vr+s6 B! ^#Vr+s`insX! ^#Vr+s`ins9͐6!9pâ!9DM͐n})v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>! ^#Vr+sn&mxâÜ!9DM͐͐ ͐^#Vr+s͐͐0͐7s!&;͐ ͐͐ ͉͐͟`is͐ ͐͐ )͐͟`in&#&;!9!9DM! n&|ͯo! n&|ͩyD!9DM`iw#w͐~#fon&v}͐ ?͐^#Vr+snѯg`is#rÇ͐!9!9DM! n&|! n& ! n&&!9DM! n&|ͯ;! n&|ͩ  !\&!7*!&*!&!&="&! BL<"e=L=üT!7*^#V#zx2+V+^+*͹:o&9! !j96  #F#x~#7:O*7,2q*&:q):o=o=r:qo&ÀB37*z\!*}#7:)~:,"s!"u*|*u *~#"*s*u #"u*+"7*|DM**B ><6 ~# x6 >>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ö ò OL] !9DM̓0 !. ͡! s#r! s#r! s#r!. ^#Vr+s!|چ!0 ^#Vr+s~#fon}-†!0 ~#fo~#fo#! s#r͐n}ʃ͐n}1I2U3am! 6#6u! 6#6u! 6#6u! ͤ! ^#Vr+s'͐|¹͐|¹͐|¹! s#r! s#r! s#r̓. >>>> \ `i6#6! ̓0 ~#foͧ#| ! ͤd `iw#w! !0 ^#Vr+s~#foͧ#|7 ! ͤ! ̓0 ~#foͧ#|Y ! ͤd !0 ͤ! ! ͪ! s#r͐|ʕ !! ͪä ! ! ͪ! s#r͐|ʾ ͐ |  ! ! ͭ! s#r͐ |$ ͐| ͐͐͐!! Ͱ! ! ͪ! s#r ͐ |ڎ ͐|Z ͐͐͐!! Ͱ͐|t !! ͪà ! ! ͪw\ \ #|¦!!tempin.$$$tempin.$$$tempin.$$$tempout.$$$¯ > >» > > > ` !! ~#fo͐c h ͐ | !!q c !! ~#fo͐c h ͐ |. !! c ͐ |D !! c !! ~#fo͐c h ! f !9 prntcol: can't happenþ P!!9DM!͐͵ !! ͵ ͻ ͸  xP!LS!ï!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#! ~#fo`i^#Vr+sn}£!Z! ~#fo͐n! ~#fo͐nѯgW!9!9DM! n} ͝ ! n} ͝ ! n} ͝6!9DM! ^#Vr+sn`is{i`in} J͐! ͐`in&#|f!o!o!9Á>!y9DM! `i{͐`i~æ!9õÈ"!9DM͐͐Ͳs#rz!͐͐s#r͐##6#6͐~#fo ù"!9DM͐%!͐~#fo B3"ü"!9DM͐͐>e>ʌ>q>ʚ>}>ʭ>‰>! n&9! n&!<! n&!<! n} ! !<! n&!<͐##^#Vr+s|J!͐͐~#fo?|)!͐##6#6͐͐s#r͐^#Vr+s! ns&vü"$#u#!9DM͐ڏ!ì͐##~#fo|¨!ì͐##~#fo`is#r͐͐͐~#fom͐!ì͐+?`is#r͐##~#fo|ʅ!͐͐͐p͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fosfonw}ʕn! ~#fo͐)~#fon}<|v+> W! ~#fo͐)~#fo#n}$*! ~#fo͐)~#fo# #|0! ~#fo͐)~#fo#!w! *6!! ~#fo͐)~#fo |s*n&|g}osæ*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}! ~#fo͐)!s#r! ~#fo͐)* s#r *n&|g}os! ~#fo͐)~#fo#n}4!! ! ~#fo͐)~#fo# *! ~#fo͐)~#fo# #|ž! ~#fo͐)~#fo#!! *4w}.͐! s#r͐͐ ~#fo! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+sû͐ ^#Vr+s`i^#Vr+s* ^#Vr+sT͐ ͐s#r! ~#fo͐ ~#fo)w#wb! ^#Vr+s`i^#Vr+su!9Can't open %s FILE: FIND .COM CRC = E9 95 --> FILE: HCAT .COM CRC = 33 08 --> FILE: INCL .COM CRC = AE A9 --> FILE: KWIC .COM CRC = 07 8A --> FILE: LPR .COM CRC = B8 6D --> FILE: PREP .COM CRC = 56 94 ---------------------> SUM OF CRCS = 58 48 |ʾ! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+st͐6! ! s#r! n}! ^#Vr+s!|! ^#Vr+s! n} !0! s͐! ^#Vr+sns{>! ^#Vr+s! n}o! ^#Vr+s!|o! ^#Vr+s6 HÅ! ^#Vr+s`insÛ! ^#Vr+s`ins|͐6!9óí!9DM͐͐  ͐^#Vr+s͐͐0͐7s!&L ͐ ͐͐ ͉͐Ͱ`is͐ ͐͐ )͐Ͱ`in&#&L !9!9DM! n&|ͯڀ ! n&|ͩÊ U !9DM`iw#w͐~#fon&͇ } ͐ ?͐^#Vr+snѯg`is#rØ ͐ !9 !!!9DM! n& |!! n&!! n&&!9DM! n&|ͯL!! n&|ͩ  !\&!7*!!&*!!&!!&="&! BL<"e=L=!e$7*^#V#z!x2"+V+^+!*!:"o&9! !j96  #F#x."~#!"7:O*7,2q*&:q):ʀ"=ʀ"= !!CRCRT COMDFIND COMFgHCAT COMHINCL COMDp!!!! n&!,R!!!! n&!R!!!! n&!R*K͞+""\+'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2rr:qo&Ñ"S!D"7*͋"\!*͎"#7:)~:,"s!"u*|*u"#*~#""*s*u"##"u*+""7*|DM**S#> +M%#~$##$xS%$ Ï$EXECL: Too much text $!pV%!*w#"%*:1<%*E%!E%!a{ ѷ! , FNxg>Goy%$ --> FILE: -FOG/UTL.027 CRC = 00 00 --> FILE: COMM .COM CRC = FA B1 --> FILE: CRT .COM CRC = CB 5B --> FI+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ÿ "9|>"ùí !e9DM̓! ͡! w#w! 6#6! 6#6! ^#Vr+s!͐!9fþí!9DM!`is#rw}ʯ! n} `͐n} `*! ͐! ns*! n&#|˜!!w&|g}o|¯! |!+++|! n} ͐n} ! !! n&!͐! ns!9File output error; disk full? ?á!9DM͐!͐<s#rzi!͐##w#w͐~#foÈý!9DM`i6#6͐ ! s#r͐ ͂! s#r!|͐#|!s! ^#Vr+s͐s{ ͐͐ #͐++n} ! ^#Vr+s6 J`i^#Vr+szJ͐ ͂! s#rzJ͐|͐|f͐ ͐͐ͅ6͐ s!9!9DM`iw#w! ^#Vr+sn}ʩ`i^#Vr+sÊ͐ð!91!y9DM! `iͼ`iͿ!9!9DM͐n}! ^#Vr+sn&"1à!y9DM! `i͐`iG!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}ª! ~#fo`i^#Vr+sn}§!^! ~#fo͐n! ~#fo͐nѯgW!9!9DM͐͐s#r|q! ^#Vr+s~#fon}-q! ~#fo~#fo#! s#r̓n}n̓n}NLX! 6#6`! ͤ! ^#Vr+s2̓>‚>ʑ>Ž>ʝ! 6#6! w#w`i̓~#foͧ#|! ͤ! ͤ̓|!! ͪ`i! ͪ|ʾ ! ͭ! s#r! w#w̓̓X ̓! ̓! n&Ͱs! ^#Vr+s ̓|x ! ^#Vr+s! ͳ! Ͷ! ^#Vr+s!|Ҙ !͹|¸ ! 6#6û þ ͼ!9usage: crt -n file or STDINcrt: can't open fileusage: crt -n file or STDIN%4d: 2 9þP!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#foҞ w} Þ ! ~#fo͐)~#fon}< |ʦ +" >9 Ç ! ~#fo͐)~#fo#n} T *! ~#fo͐)~#fo# #|` ! ~#fo͐)~#fo#! !# & *6! ! ~#fo͐)~#fo) |£ *n&|g}os *4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n} ! ~#fo͐)! z !͐͐s#r͐##6#6͐~#fo=!9DM͐U!͐~#fo:rí!9DM͐͐>•>ʼ>¡>>­>>¹>! n&i! n&!l! n&!l! n} ! !l! n&!l͐##^#Vr+s|z!͐͐~#foo|Y!͐##6#6͐͐s#r͐^#Vr+s! ns&æÁ!9DM͐ڿ!͐##~#fo|!͐##~#fo`is#r͐͐͐~#fo͐͝%!͐+?`is#r͐##~#fo|ʵ!͐͐͐͐͠##~#fo͐s#r͐~#fo͐s#r!!͐~#foͣ͐##6#6͐͐s#r!!9í= !9DM͐|ô͐+++|!ô͐##^#Vr+s|!͐͐~#fo`is#r!|p͐##^#Vr+sô͐##͐?+s#r͐͐s#r͐^#Vr+sn&ô!9ó !9DM͐|! n&͐͐##~#fo|s#r! ~#fo͐)* s#r9 *n&|g}os! ~#fo͐)~#fo#n}d ! !# & ! ~#fo͐)~#fo#, *! ~#fo͐)~#fo#/ #| ! ~#fo͐)~#fo#! !# & *4w}^ ͐! s#r͐͐ ~#fo8 ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s ͐ ^#Vr+s`i^#Vr+s* ^#Vr+sÄ ͐ ͐s#r! ~#fo͐ ~#fo)w#wÒ ! ^#Vr+s`i^#Vr+så !9Can't open %s 2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)!9 !9DM͐͐ ^͐^#Vr+s͐K͐0S͐7s!&é͐ ͐͐ ͉͐ `is͐ ͐͐ )͐ `in&#&é!9!9DM! n&|ͯ! n&|ͩò!9DM`iw#w͐~#fon&}4͐ ?͐^#Vr+snѯg`is#r͐;!9J~!9DM! n&G|q! n&x! n&&!9DM! n&|ͯک! n&|ͩ7:O*  !\&!7*!&*!&!&="&! BL<"e=L=; 7*^#V#zCx2o+V+^+R*8:oo&9! !j96  #F#xʜ~#Ï7,2q*&:q):==r:qo&á7*\!*#7:)~:,"s!"u*|*u*~#V"*s*u#"u*+"C7*|DM**ڰ><~# x¤ ><~+ x|}!7:,*:*}|#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ÿh Äÿ "a?#M <$J!9DM̓! ͡`iw#w! s#r! s#r! s#r! s#r! s#r! s#r! s#r! ^#Vr+s!|! ^#Vr+s~#fon}-! ~#fo~#fo#! s#r͐n}͐n}AʁNʍXʙCʥFʱý! 6#6! 6#6! 6#6! 6#6! 6#6! ͤ! ^#Vr+sU̓|! ͤ̓|ڒ ! ^#Vr+s!| ! ͤ! ^#Vr+s~#fo! ͧ͐|[ ! !" ͪ!" ! ͭ͐+k! ! Ͱ|„ ! ͤ! ^#Vr+s!! ͳ|ʀ `i^#Vr+s͐| ! !" ͪ ! !" ͭ͐͐! !" Ͷ| ! 6#62q + ! :qw ! {w7:)~:,"s!"u*|ʓ **s˜ ! ~“ 6*u*+"*"*u#"u_ :wo2w&7*!9& 6C#6O#6M *|!!\&!!\&*|!!!l&!9~#foI!> +ͪ!#~7!##+!xSs![!  EXECL: Too much text $!p!!*w#!*:1™!*â!!¢!!a{ ѷ! , FNxg>Goy"$"àþ !9DM!͐"!!<"" " " !9DM! n&|g}os! n}z"! n} z"! n} †"! n&ô"! n&|ڡ"! n}«"! &ô"! n&&*K͞+r4r4='+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z ! w#w͐|& ͐ |͝! s#r͐ |` ͐ |` ͐|O ͐! ͹! ! ͹} ͐ |} ͐ |} ! ^#Vr+sÒ ͐ |ʗ ͐! ͹ͼ!9find: invalid optionfind: missing patternfind: too many patternsfind: illegal pattern%d: %s%d matched  j$!9DM! ^#Vr+s! ^#Vr+sn& s{K  S !9DM! w#w͐͐  ! ~#fo͐k͐P `is#r͐|´ ͐|ʴ ! ͐| ͐| ! ! ^#Vr+sc ͐ !9 Ñ!9DM! 6#6`iw#w! ~#fo͐n}S ͐|S !͐ ͐͐ ! s#r`i^#Vr+s ͐|ͯ_ !9} ä$$0!%0ð%!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fow} ! ~#fo͐)~#fon}<= | +m>ʄ! ~#fo͐)~#fo#n}[ ß*! ~#fo͐)~#fo#k #|« ! ~#fo͐)~#fo#!!n q *6!! ~#fo͐)~#fot | *n&|g}os!*4! ~#f ͗|#! 6#6! 6#6C! ~#fo͔͐͐s#rù͐M!9eì ã!9DM! w#w͐`is#r! w#w! w#w͐|! ~#fo͐n! n}! ~#fo͐n}͐! s#r! ~#fo͐n}?!! ͐!?Yí! ~#fo͐n}%I͐͐I!! ͐!%Yí! ~#fo͐n}$˜! ~#fo͐#n! n}˜!! ͐!$Yí! ~#fo͐n}[! ͐`i͐\|͝! s#rí! ~#fo͐n}*o͐͐o͐! s#r! ~#fo͐n}%K! ~#fo͐n}$K! ~#fo͐n}*W! 6#6l͐! ͐_í!! ͐!cY!! ͐`i͐b&Y͐! s#r͐|`i^#Vr+sÏ͐|! ~#fo͐n! n}!**!! ͐!Y|#!**͐*! 99Ä!9DM! ~#fo͐n}cx%}$}?}[ʂ^ʂ*ʙÞ!!! ~#fo͐#n&##!!6in patsize: can't happenÄ!9DM`i6#6! ~#fo͐ ~#fon}! w#wR! o͐)~#fo#* s#r! ~#fo͐)~#fo#n}j! ~#fo͐)! s#r! ~#fo͐)* s#rÄ*n&|g}os! ~#fo͐)~#fo#n}¯!!n q ! ~#fo͐)~#fo#w *! ~#fo͐)~#fo#z #|! ~#fo͐)~#fo#!9!n q *4w}©͐! s#r͐͐ ~#fo҃! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s6͐ ^#Vr+s`i^#Vr+s* ^#Vr+s͐ ͐s#r! ~#fo͐ ~#fo)w#w! ^#Vr+s`i^#Vr+s !9Can't open %s !! ~#fo͐ ~#fo#n}[!͐͐͐ !-= b"! ~#fo͐ ~#fo+n&@ |H"! ~#fo͐ ~#fo#n&@ |H"! ~#fo͐ ~#fo+n! ~#fo͐ ~#fo#nѯgWH"! ~#fo͐ ~#fo+n&#`is#r͐! ~#fo͐)͐`in&)#|#*!,*)!,*!9;*ó.!9DM! n&8*|b*! n& i*! n&&u*"3!9DM͐|”*! n&r*͐Ҳ*͐##~#fo|·*!͐^#Vr+s! ns͐##^#Vr+s!*.Ê/ù/j$!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{C.`in}%-.! ! s#r! 6#6! s! s! s͐n}-‚+! ^#Vr+s! 4͐n}0’+! 4͐n&*}ʯ+! *ò+!! s#r! ^#Vr+sn`is{.+! *! s#r! 4! ^#Vr+sn`is`in&*}D&,Ub,Xk,Ot,Cʺ,S,.͐~#fo|b,! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 z,! 6z,! 6! ~#fo! n&! ^#Vr+s~#fo! *ѯgs#rc-! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+sc-! n},! 6#6! ^#Vr+s~#fo! s#r͐n}c-͐|c-! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s-͐6! ! s#r! n}º-! ^#Vr+s!|ں-! ^#Vr+s! n}ʱ-!0ô-! s-͐! ^#Vr+sns{-! ^#Vr+sú-! n}.! ^#Vr+s!| ~#fo#nѯg:"͐͐͐ ͐= `i^#Vr+s!͐ ^#Vr+sb"͐͐͐ !-= ͐ ^#Vr+sK !9!9DM! n&|ڦ"! n&|Ҧ"!! n&|"! n&|"!! n&|"! n&|"!!!9DM͐`is#r! ^#Vr+s! ^#Vr+sns{/# #͐6#!9H#ö(o*!9DM`i6#6͐ ! s#r͐ B#! s#r!|ʇ#͐#|#!3$! ^#Vr+s͐s{ #͐͐ ##͐++n} #! ^#Vr+s6 $`i^#Vr+sz $͐ B#! s#rz $͐|#͐|&$͐ ͐E#͐6͐ 3$!9E$*R.!y9DM! `i?$`iB$!9p$Ä.!9DM! n&m$|ʗ$! n&Þ$! n&&ê$1!9DM͐!͐ͧ$s#rz$!͐##w#w͐~#fo$*)!y9DM! `i$͐`i$%!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}{%! ~#fo`i^#Vr+sn}x%!ç%/%! ~#fo͐n! ~#fo͐nѯgWç%!9ö%T1!9DM͐͐ͳ%s#rz%!͐͐s#r͐##6#6͐.! ^#Vr+s6 -*.! ^#Vr+s`ins@.! ^#Vr+s`ins!+͐6!9X.[!9DM͐n}ʂ.! ^#Vr+sn&U.`.!9DM! n&|ͯگ.! n&|ͩ!9DM! n&|ͯ.! n&|ͩ..!9DM͐͐ 6/͐^#Vr+s͐#/͐0+/͐7s!&Á/͐ ͐͐ ͉͐.`is͐ ͐͐ )͐.`in&#&Á/!9!9DM! n&|ͯڵ/! n&|ͩÿ/Ê/!9DM`iw#w͐~#fon&ͼ/} 0͐ ?͐^#Vr+snѯg`is#r/͐0!9  !\&!7*!^0&*!n0&^0!&="&! BL<"e=L=Ù0137*^#V#z¡0x20+V+^+°0*͖0:0o&9! !j96  #F#x0~#07:O*7,2q*&:q):L1=L1=r:qo&]1017*W1\!*Z1#7:)~:,"s!"u*|*u1*~#1"*s*u1#"u*+"ò17*|DM*~#fo&Å1!9DM͐&&!͐~#fo &C&[0È1!9DM͐&͐>f&>ʍ&>r&>ʛ&>~&>ʮ&>Š&>&&! n&:&! n&!=&! n&!=&! n} &! !=&! n&!=&͐##^#Vr+s|K'!͐͐~#fo@&|*'!͐##6#6͐͐s#r͐^#Vr+s! ns&w'È11A2!9DM͐ڐ'!í(͐##~#fo|©'!í(͐##~#fo`is#r͐͐͐~#fon'͐'!í(͐+?`is#r͐##~#fo|ʆ(!͐͐͐q'͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fot'í(͐##6#6͐͐s#r!í(!9(j0ì2!9DM͐|(͹(Å)͐+++|(!ͼ(Å)͐##^#Vr+s|n)!͐͐~#foͿ(`is#r!|A)͐##^#Vr+sÅ)͐##͐?+s#r͐͐s#r͐^#Vr+sn&Å)!9!9DM`iw#w! ^#Vr+sn}ʻ)`i^#Vr+sÜ)͐)!9)7&!9DM! ^#Vr+sn`is{&*`in} *͐!  *2><2~# x2 > +4#~¦3##Ú3xS33 [3EXECL: Too much text $!p"4!*w#3*:14*4!4!a{ ѷ! , FNxg>Goyp4$*K͞+$$h-'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO: can't open file!9DM`iw#w͐͐ ! ~#fo͐k~#fo| ! `i^#Vr+sà ! !9!9DM`iw#w͐ +! s#r͐͐+o ! ~#fo͐n} o ! ~#fo͐! ~#fo͐ns`i^#Vr+s! ^#Vr+s !9!9DM͐ +++`is#r͐|ڻ ! ~#fo͐n} ʯ û `i^#Vr+sÍ ! ~#fo`i^#Vr+s6 ! ~#fo`i^#Vr+s6!9 ~l !9DM!͐ !!+ B l o î!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#foҮw} î! ~#fo͐)~#fon}< |ʶ +2>I×! ~#fo͐)~#fo#n} d*! ~#fo͐)~#fo#0 #|p ! ~#fo͐)~#fo#!!3 6 *6!! ~#fo͐)~#fo9 |³ *n&|g}os*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}/! ~#fo͐)!s#r! ~#fo͐)* s#rI*n&|g}os! ~#fo͐)~#fo#n}t!!3 6 ! ~#fo͐)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>)~#fo#< *! ~#fo͐)~#fo#? #|! ~#fo͐)~#fo#!!3 6 *4w}n͐! s#r͐͐ ~#foH! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s͐ ^#Vr+s`i^#Vr+s* ^#Vr+sÔ͐ ͐s#r! ~#fo͐ ~#fo)w#wâ! ^#Vr+s`i^#Vr+sõ !9Can't open %s >7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-- I Ò OO x L!9DM̓! ̓͡|!G ͤ`iw#w͐̓͐|:͐k! 6#6{͐k! ! ^#Vr+s~#foͧs#r!|{!b ͤ͐k! ! ^#Vr+s~#foͪ#|±!| ͤ͐k! w#w`i^#Vr+s͐! s#r͐! ͭ|; `iw#w͐͐} ͐k! ~#fo|q ͐k! ͐k! Ͱ|q ͐k! 6#6`i^#Vr+s! !! ͳ`iw#w͐͐ ͐k! ~#fo| !! ͐k! ~#fo͐k! Ͷ`i^#Vr+sÖ ͐! ͭ|8 !! ͹! ͼͿ!9hcat: too many input fileshcat: bad column argumenthcat!! n&##|¨!*!&)w&|g}o|¿ ! ,|!,+++|)! n} ͐n} ! !,! n&!,͐! ns!9File output error; disk full? O!9DM`iw#w! 6#6͐ n! s{ ʂ! n} ! ^#Vr+sf! n}-¯! 6#6! ^#Vr+s! ^#Vr+sn! sL|͐ ?! nѯg`is#rï͐͐?!9`!!9DM͐!͐ s#rz9!͐##w#w͐~#foXô!9DM`i6#6͐ ! s#r͐ R! s#r!|ʗ͐#|!C! ^#Vr+s͐s{ ͐͐ #͐++n} ! ^#Vr+s6 `i^#Vr+sz͐ R! s#rz͐|͐|6͐ ͐U͐6͐ C!9R !9DM͐n}|! ^#Vr+sn&OZÄ5!9DM! ^#Vr+sn`is{`in} º͐! ́͐`in&́#|!Ì!!9l~!y9DM! `i͐`i!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}y! ~#fo`i^#Vr+sn}v!å-! ~#fs!|ڝ! ^#Vr+s6 vó! ^#Vr+s`ins! ^#Vr+s`insê͐6!9!9DM͐͐ /͐^#Vr+s͐͐0$͐7s!&z͐ ͐͐ ͉͐`is͐ ͐͐ )͐`in&#&z!9É!9DM`iw#w͐~#fon&͆}͐ ?͐^#Vr+snѯg`is#r×͐!9 !9DM! n&| ! n& ! n&&!9DM! n&|ͯK ! n&|ͩ7**:Ozg q#_  !\&!7*! &*! & !&="&! BL<"e=L= Á#7*^#V#z x2!+V+^+!* :!o&9! !j96  #F#xJ!~#=!7:O*7,2q*&:q):ʜ!=ʜ!=r:qo&í!o `!7*ͧ!\!*ͪ!#7:)~:,"s!"u*|*u>"*~#""*s*u>"#"u*+""7*|DM**o"><"~o͐n! ~#fo͐nѯgWå!9ôä!!9DM͐͐ͱs#rz!͐͐s#r͐##6#6͐~#fo !!9DM͐$!͐~#fo A O!!!9DM͐͐>d>ʋ>p>ʙ>|>ʬ>ˆ>ʿ! n&8! n&!;! n&!;! n} ! !;! n&!;͐##^#Vr+s|I!͐͐~#fo>|(!͐##6#6͐͐s#r͐^#Vr+s! ns&u!@"Ñ"!9DM͐ڎ!ë͐##~#fo|§!ë͐##~#fo`is#r͐͐͐~#fol͐!ë͐+?`is#r͐##~#fo|ʄ!͐͐͐o͐##~#fo͐s#r͐~#fo͐s#r!!͐~#forë͐##6#6͐͐s#r!ë!9/O!"!9DM͐|ͷÃ͐+++|!ͺÃ͐##^#Vr+s|l!͐͐~#foͽ`is#r!|?͐##^#Vr+sÃ͐##͐?+s#r͐͐s#r͐^#Vr+sn&+ x"|}×"Ü$7:,*͔":*ʹ"}|2q "":qw"! {w7:)~:,"s!"u*|R#**sW#! ~R#6*u*+"*"*u#"u#:wo2w&7*!9& 6C#6O#6M°#*|#!\&#!\&*|#!!l&!9~#fo$> +i$#~####xS2$$ ë#EXECL: Too much text $!pr$!*w#>$*:1X$*a$!a$!a{ ѷ! , FNxg>Goy$$*K͞+""b+'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyOÃ!9!9DM`iw#w! ^#Vr+sn}ʹ`i^#Vr+sÚ͐!9!9DM! n&|ͯ! n&|ͩr#!9DM͐|! n&͐;͐##~#fo|@!͐^#Vr+s! ns͐##^#Vr+s!{Ã!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{`in}%¶! ! s#r! 6#6! s! s! s͐n}- ! ^#Vr+s! 4͐n}0! 4͐n&r}8! u;!! s#r! ^#Vr+sn`is{.ƒ! u! s#r! 4! ^#Vr+sn`is`in&x}DʯUXOCCStà͐~#fo|! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 ! 6! 6! ~#fo! n&! ^#Vr+s~#fo! oѯgs#r! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s! n}‡! 6#6! ^#Vr+s~#fo! s#r͐n}͐|! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+sâ͐6! ! s#r! n}C! ^#Vr+s!|C! ^#Vr+s! n}:!0=! s͐! ^#Vr+sns{l! ^#Vr+sC! n}ʝ! ^#Vr+!)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>sË !9Can't open %s >7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ó efX!9DM̓!  ̓͡ +|`i6#6(`iw#w! ! ^#Vr+s~#foͤ#|(̓~#fo!C!ͧͭͪ͐! Ͱͭ!9incl: can't open %s |Ü û ÙefX@!9DM̓|ʟ!! [ï̓! [|ʰ ! !! ^! s#r! ! a|!! dí ! ̓! ^! s#r! g+! 6! w#w̓! gl ̓! ̓#! ns! ^#Vr+s, `i! j#|š ! ! !msp!`iv`iyÄ!9#includeincl: can't open %s o!9DM! ~#fo͐n& | ! ^#Vr+s `iw#w! ~#fo͐n& || ! ~#fo͐n}| ! ~#fo`i^#Vr+s! ~#fo! ^#Vr+sns ! ͐`ikÓ!9åO!9DM`i6#6͐ ! s#r͐ ͟! s#r!|͐#|!Ð! ^#Vr+s͐s{ 4͐͐ #1͐++n} 1! ^#Vr+s6 g`i^#Vr+szg͐ ͟! s#rzg͐|͐|ƒ͐ ͐͐͢6͐ Ð!9ßÉ!9DM! ^#Vr+sn`is{`in} ͐! ͐͜`in&͜#|!ç!!9!9DM`iw#w! ^#Vr+sn}0`i^#Vr+s͐7!9FÞ!9DM͐^!͐~#foC!9DM! n} ͝ʞ! n} ͝ʞ! n} ͝!9DM`iw#w! ~#fo͐n! ~#fo͐n}! ~#fo`i^#Vr+sn}!(ð! ~#fo͐n! ~#fo͐nѯgW(!97á!9DM͐͐4s#rz\!͐͐s#r͐##6#6͐~#foÕI!9DM͐>͐>¸>>>>>>>>! n&͌! n&!͏! n&!͏! n} +! !͏! n&!͏͐##^#Vr+s|!͐͐~#fo͒||!͐~#fo͐6! ~#fo͐n}« !ò ò ͐ò !9!9DM͐n͐n} ͐n} !! ^#Vr+s! ^#Vr+s ! efâi1!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo҄w}ʫ Ä! ~#fo͐)~#fon}< |ʌ + > m! ~#fo͐)~#fo#n} : *! ~#fo͐)~#fo# #|F ! ~#fo͐)~#fo#!! *6!! ~#fo͐)~#fo |‰ *n&|g}osü *4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n} ! ~#fo͐)!s#r! ~#fo͐)* s#r *n&|g}os! ~#fo͐)~#fo#n}J !! ! ~#fo͐)~#fo# *! ~#fo͐)~#fo# #|´ ! ~#fo͐)~#fo#!! *4w}D͐! s#r͐͐ ~#fo! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s ͐ ^#Vr+s`i^#Vr+s* ^#Vr+sj͐ ͐s#r! ~#fo͐ ~#fo)w#wx! ^#Vr+s`i^#Vr+"##6#6͐͐s#r͐^#Vr+s! ns&: Ë !9DM͐!͐##~#fo|!͐##~#fo`is#r͐͐͐~#fo͐H!͐+?`is#r͐##~#fo|!͐͐͐͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo͐##6#6͐͐s#r!!9I !9DM͐|+ ͐+++|B!͐##^#Vr+s|!͐͐~#fo`is#r!|ғ͐##^#Vr+s͐##͐?+s#r͐͐s#r͐^#Vr+sn&!9kÚ!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{@`in}%*! ! s#r! 6#6! s! s! s͐n}-! ^#Vr+s! 4͐n}0! 4͐n&}ʬ! ï!! s#r! ^#Vr+sn`is{.! ! s#r! 4! ^#Vr+sn`is`in&}D#U_XhOqCʷS͐~#fo|_! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 w! 6w! 6! ~#fo! , FNxg>Goy"$! n&! ^#Vr+s~#fo! ѯgs#r`! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s`! n}! 6#6! ^#Vr+s~#fo! s#r͐n}`͐|`! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+s͐6! ! s#r! n}·! ^#Vr+s!|ڷ! ^#Vr+s! n}ʮ!0ñ! s|͐! ^#Vr+sns{! ^#Vr+s÷! n}! ^#Vr+s!|! ^#Vr+s6 '! ^#Vr+s`ins=! ^#Vr+s`ins͐6!9Ul!!9DM͐|t! n&R͐Ғ͐##~#fo|—!͐^#Vr+s! ns͐##^#Vr+s!!9DM͐͐ ͐^#Vr+s͐͐0 ͐7s!&b͐ ͐͐ ͉͐`is͐ ͐͐ )͐`in&#&b!9!9DM! n&|ͯږ! n&|ͩàk!9DM`iw#w͐~#fon&͝}͐ ?͐^#Vr+snѯg`is#rî͐!97!9DM! n&|*! n&1! n&&!9DM! n&|ͯb! n&|ͩ  !\&!7 !!CRKWIC COMALPR COMDDPREP COMNCRCKLISTCRCREADME UTSSORT COMXSPLIT COMHH!vpͫ *** Out error *** !Xq!!Z!q!q!q!w&s!rw&*K͞+k!k!*'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!*!&*!&!&="&! BL<"e=L={!7*^#V#zx2+V+^+*:o&9! !j96  #F#xD~#77:O*7,2q*&:q):ʖ=ʖ=r:qo&#êiZ7*ͤ\!*ͧ7:)~:,"s!"u*|*u8 *~# "*s*u8 #"u*+"7*|DM**i ><] ~# x] > +c"#~!##!xS,"" å!EXECL: Too much text $!pl"!*w#8"*:1R"*["!["!a{ ѷ""!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ79DM!x`is#rw}! n} ¿͐n} ʿ*! r͐! ns*! n&r#|!y!uxw&|g}o|o! {|.!{+++|.x! n} Q͐n} Q! !{! n&!{͐! ns!9File output error; disk full? á%!9DM`i6#6͐ ! s#r͐ ͛! s#r!|͐#|!Ì! ^#Vr+s͐s{ 0͐͐ #-͐++n} -! ^#Vr+s6 c`i^#Vr+szc͐ ͛! s#rzc͐|͐|͐ ͐͐͞6͐ Ì!9ÞÙ!9DM! n&͘|ͣ! n&͛|ͣ!9DM! n&|ͯ! n&|ͩ !9DM͐!͐s#rz.!͐##w#w͐~#foMf!y9DM! `iG͐`iJr!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}! ~#fo`i^#Vr+sn}!É! ~#fo͐n! ~#fo͐nѯgW!9M!9DM͐͐ s#rz5!͐͐s#r͐##6#6͐~#foh~!9DM͐ڀ!>G>)7[%#͔+:*ͅ-í| Ø^ !y9DM͐! ͡!`iͤ|`iͧͪ!9Õ!9DM`iw#w! ~#fo͐n} ! ~#fo͐n}! ~#fo͐n&|h! ~#fo͐n&|͐͐`i^#Vr+s! ~#fo͐n&|¸! ~#fo͐n&|`i^#Vr+sÀ`i^#Vr+s!9o!9DM͐`is#r! ~#fo͐n} * ! ~#fo͐n&`i^#Vr+s!$`iw#w͐͐k ! ~#fo͐n&`i^#Vr+s8 ! !9Ñ D{ !9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo w}$ ! ~#fo͐)~#fon}ʘ ! ~#fo͐)~#fo#n}o ó *! ~#fo͐)~#fo# #|¿ ! ~#fo͐)~#fo#! !͂ ͅ *6! ! ~#fo͐)~#fo͈ | *n&|g}os5 *4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}~ ! ~#fo͐)!! s#r! ~#fo͐)* s#rØ͐~#foeÝoÁ!9DM͐F͐>>>>>>>>F! n&͔! n&!͗! n&!͗! n} 3! !͗! n&!͗͐##^#Vr+s|¥!͐͐~#fo͚|ʄ!͐##6#6͐͐s#r͐^#Vr+s! ns&Á:!9DM͐!͐##~#fo|!͐##~#fo`is#r͐͐͐~#fo͐P!͐+?`is#r͐##~#fo|!͐͐͐͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo͐##6#6͐͐s#r!!9~å!9DM͐|3͐+++|J!͐##^#Vr+s|!͐͐~#fo`is#r!|қ͐##^#Vr+s͐##͐?+s#r͐͐s#r͐^#Vr+sn&!9!9DM`iw#w! ^#Vr+sn}`i^#Vr+s͐!9+ !9DM͐|J! n&(͐h͐##~#fo|m!͐^#Vr+s! *n&|g}os! ~#fo͐)~#fo#n} !. !͂ ͅ ! ~#fo͐)~#fo#͋ *! ~#fo͐)~#fo#͎ #|- ! ~#fo͐)~#fo#!M !͂ ͅ *4w}½ ͐! s#r͐͐ ~#foҗ ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+sJ ͐ ^#Vr+s`i^#Vr+s* ^#Vr+s ͐ ͐s#r! ~#fo͐ ~#fo)w#w ! ^#Vr+s`i^#Vr+s !9Can't open %s ! ^#Vr+s`insT! ^#Vr+s`ins5͐6!9lÑ!9DM! ^#Vr+s#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)n`is{`in} ¢͐! i͐`in&i#|¾!t!!9!9DM͐͐ $͐^#Vr+s͐͐0͐7s!&o͐ ͐͐ ͉͐`is͐ ͐͐ )͐`in&#&o!9~!9DM`iw#w͐~#fon&{}͐ ?͐^#Vr+snѯg`is#rÌ͐!9!9DM! n&|! n&! n&&  !\&!7*!W&*!g&W!&="&! BL<"e=L=Ò* 7*^#V#zšx2+V+^+©*͏:o&9! !j96  #F#x~#7:O*7,2q*&:q):E=E=r:qo&V 7*P\!*S#7:)~:,"s!"u*|*u*~#¾"*s*u#"u*+"ë7*|DM**>< ~# x  ><(~+ x(|}@E!7:,*=:*b}|2q ʓ?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-öQ  m-*A3!i9DM͐! ͡! s#r! s#r`is#r! 6#6! 62#6! ^#Vr+s!|ړ! ^#Vr+s~#fon}-“! ~#fo~#fo#! s#r͐n}ʐ͐n}LXNbPnz`i6#6Â! 6#6Â! 6#6Â! ͤ! ^#Vr+s6͐|! ^#Vr+s~#foͧ! s#rz! ͤ͐|͐~#foͧ! s#r!|! ͤ! 6#6!! ͪ|ʮ ! w#w͐ ͐G !! ͭ! ^#Vr+s !! ͭ! ^#Vr+s͐r  ë !! ͭ! 6#6͐|ʫ !Ͱ|¨  ë î  ͐ | !! ͭͳ!9lpr: invalid optionlpr: left margin < 0lpr: page size < 1 " *R3!9DM!͐ !!O    f ÔRUà!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo w} ! ~#f‰:qwʄ! {w7:)~:,"s!"u*|**s ! ~6*u*+"*"*u#"u:wo2w&7*!9& 6C#6O#6MY *|o !\&Á !\&*| !!l&!9~#foʱ > +!#~Ÿ ##Ó xS   T EXECL: Too much text $!p!!*w# *:1!* !! !!a{ ѷ! , FNxg>Goyi!$ *K͞+""=+'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#o͐)~#fon}<& | +V >m û ! ~#fo͐)~#fo#n}D È *! ~#fo͐)~#fo#T #|” ! ~#fo͐)~#fo#! !W Z *6! ! ~#fo͐)~#fo] | *n&|g}os *4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}S ! ~#fo͐)! s#r! ~#fo͐)* s#rm *n&|g}os! ~#fo͐)~#fo#n}˜ !!W Z ! ~#fo͐)~#fo#` *! ~#fo͐)~#fo#c #| ! ~#fo͐)~#fo#!"!W Z *4w}’ ͐! s#r͐͐ ~#fol ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s ͐ ^#Vr+s`i^#Vr+s* ^#Vr+sø ͐ ͐s#r! ~#fo͐ ~#fo)w#w ! ^#Vr+s`i^#Vr+s !9Can't open %s V>}>b>ʋ>n>ʞ>z>ʱ! n&*! n&!-! n&!-! n} ! !-! n&!-͐##^#Vr+s|;!͐͐~#fo0|!͐##6#6͐͐s#r͐^#Vr+s! ns&gí f !9DM͐ڀ!Ý͐##~#fo|™!Ý͐##~#fo`is#r͐͐͐~#fo^͐!Ý͐+?`is#r͐##~#f$ !j96  #F#x0~##7,2q*&:q):q=q=r:qo&ÂU57*|\!*#7:)~:,"s!"u*|*u *~#"*s*u #"u*+"7*|DM**D ><8 ~# x8 > +>"#~!##ÿ!xS"! À!EXECL: Too much text $!pG"!*w#"*:1-"*6"!6"!a{ ѷ! , FNxg>Goy"$F͐!" !Ͱ! ͭ|> ͐|> ! !* !Ͱ ͐|ʧ ! ͭ|z ͐|z ! ͐!. !Ͱ! ͭ|ʤ ͐|¤ ! !6 !Ͱ ͐| ! ͐!: !Ͱ ! !B !Ͱͳ!9prep: invalid optionprep: can't use both -o and -i%d: %s %s %d: %s %s %d: %s %s ^ I#Ái!m9DM! ̓L #|„ ! O *vw#w! !  R |3 Mv|ڹ ! O !  U +!  6!  U #`is#r͐I ! s#rz ! O !  ̓X *v^#Vr+s)*̓s#rÏ Mv|I ! O ! 6#6͐MvҬ ͐)*~#fo͐+)*~#fo[ |ڞ !* O ! ^#Vr+sR !9prep: can't open list fileprep: too many lines in list fileprep: too many chars on list fileprep: empty list fileprep: list isn't sorted or has duplicatesc 0IÃz#!9DM`iw#wW ! s#rzˆ !Ô ! ~#fo|g}os#r͐Z |ʰ ó q ! ~#fo`i^#Vr+s͐] sW ! s#rz ͐` Q ! ~#fo|*K͞+''H8'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77g}os#r͐Z |+ ͐|+ Q N ! ~#fo`i^#Vr+s͐] s ! ~#fo͐+n}'} ! ~#fo͐+6Î ! ~#fo͐6!Ô !9ã i!9DM`iw#wMv+! s#r͐͐Z͐͐! s#r͐)*~#fo͐ ͠ |͐+! s#rW͐)*~#fo͐ ͠ |Q͐#`is#rW!`ÿ !`!9oý!9DM͐n}͐n&l͐n&l͐n&l͐n&l! ^#Vr+s! ^#Vr+sw͐n}!!É#!9DM!͐!!, CÁJÉ#aÌ#!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#foүw}ï! ~#fo͐)~#fon}<|ʷ+3>JØ! ~#fo͐)~#fo#n}!e*! ~#fo͐)~#fo#1#|q! ~#fo͐)~#fo#!!47*6!! ~#fo͐)~#fo:|´*n&|g}os*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}0! ~!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ö.F T Ý J!o9DM͐! ͡! s#r! s#r`is#r! w#w! ^#Vr+s!|ډ! ^#Vr+s~#fon}-‰! ~#fo~#fo#! s#r͐n}ʆ͐n}ONIXDdp`i6#6x! 6#6x! 6#6x! ͤ! ^#Vr+s,͐|ʣ͐|ʣ! ͤ͐|µ͐|͐~#foͧ! ͪ| ! ^#Vr+s͐|A ! ͭ| ͐| ! $#fo͐)!s#r! ~#fo͐)* s#rJ*n&|g}os! ~#fo͐)~#fo#n}u!!47! ~#fo͐)~#fo#=*! ~#fo͐)~#fo#@#|! ~#fo͐)~#fo#!!47*4w}o͐! s#r͐͐ ~#foI! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s͐ ^#Vr+s`i^#Vr+s* ^#Vr+sÕ͐ ͐s#r! ~#fo͐ ~#fo)w#wã! ^#Vr+s`i^#Vr+sö!9Can't open %s ¦>>²>>¾>>>,! n&z! n&!}! n&!}! n} ! !}! n&!}͐##^#Vr+s|‹!͐͐~#fò|j!͐##6#6͐͐s#r͐^#Vr+s! ns&÷$]%î%!9DM͐!͐##~#fo|!͐##~#fo`is#r͐͐͐~#foͮ͐6!͐+?`is#r͐##~#fo|!͐͐͐ͱ͐##~#fo͐s#r͐~#fo͐s#r!!͐~#foʹ͐##6#6͐͐s#r!!90l$%~:,"s!"u*|*u[%*~#2%"*s*u[%#"u*+"%7*|DM**ڌ%><%~# x€% ><%~+ xœ%|}ô%ê'7:,*ͱ%:*%}|2q &%:qw%! {w7:)~:,"s!"u*|o&**st&! ~o&6*u*+"*"*u#"u;&7*!9& 6C#6O#6M¾&*|&!\&&!\&*|&!!l&!9~#fo'> +w'#~'##&xS@'(' ù&EXECL: Too much text $!p'!*w#L'*:1f'*o'!o'!a{ ѷ! , FNxg>Goy'$ --> FILE: -FOG/UTL.028 CRC = 00 00 --> FILE: DISK .DOC CRC = 74 7E --> FILE: SORT .COM CRC = CE 11 --> FILE: SPLIT .COM CRC = 52 2D --> FILE: TABS .COM CRC = C1 04 --> FILE: TAIL .COM CRC = 1A E9 --> FILE: TEEmethod, while others reflect the second -- you've been warned. Also, you may have to change the drive designation in the #include lines to correspond to your compile procedure. 5. The utdir tool needs wildexp.c which comes with the BDS C distribution package. 6. spltscan.c contains a set of character handling functions. Only two of them (I think) are used by a UTOOL (vsplit). Documentation for these functions is on spltscan.doc. Forgive the few gotos -- this was some of the first C code I wrote. 7. There are two tools here that I didn't include in the set of .com files I submitted to foglib -- lline and makdoc. 8. I haven't experimented with the compiler options to optimize space or time. That might be a useful thing for someone to try. That's all that I can think of that you need to know. Please forgive any omissions.  .COM CRC = 4B BC --> FILE: TR .COM CRC = 55 2A --> FILE: UNIQ .COM CRC = 1C 23 --> FILE: UNROT .COM CRC = 82 0F ---------------------> SUM OF CRCS = AF C1 file: readme.uts date: 9/10/83 author: David H. Wolen This disk contains the source for the UTOOLS -- a set of utility programs I recently submitted to the foglib. See the appropriate foglib disks for user oriented documentation. The programs are written in C, using version 1.46 of the BDS compiler. The following notes about bringing up the UTOOLS on your own are disorganized and probably incomplete -- that should be fair warning. Also, note that you'll need some files from the BDS C distribution package to complete this package. I'm not including them because I'm not sure if the source for them is public domain. 1. I've enabled alloc and free by making the appropriate change to bdscio.h and recompiling the indicated libraries. *K͞+,,;E'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77See the instructions in bdscio.h. Alloc and free are only (I think) used by the tail tool. The other tools that do storage allocation don't need to free it so they use sbrk instead (reducing memory requirements and the size of the .com file). 2. I've enabled console buffering by making the appropriate change to dio.h. See the instructions in dio.h. 3. Just about all the UTOOLS use something from mylib3.c. I've made it my deff3.crl. There are probably some routines on mylib3.c that aren't used by the UTOOLS. Note -- there's a bug in 1.46 that prevents deff3.crl from being picked up automatically if you compile with source on b and b as the logged drive. 4. Before my upgrade to double density, I kept dio.h and dio.crl on the same drive as the source. With double density, I keep everything but the source on A and compile with A as the logged drive. Some of the "linkage" comments in the source code reflect the first %!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-ùf*F(H y A {!9DM͐! ͡! s#r! s#r! s#r! s#r! s#r! ^#Vr+s!|! ^#Vr+s~#fon}-! ~#fo~#fo#! s#r͐n}͐n}FcKoR{NʇUʓß! 6#6ý! 6#6ý! 6#6ý! 6#6ý! 6#6ý͐n&! !ͤͪͧ! ^#Vr+s7͐ |͐|! !ͤͪͧ͐ | ͐! ~#fo͐n&! s͐|@! ~#fo͐n&R! ~#fo͐n&! s! n! n}! n! nѯgWß! ^#Vr+s`i^#Vr+sÐ!ß!9îã!9DM͐n}D͐ |͐n&ͫ͐n&`is͐ |͐n&ͫ͐n&! s`in! n}+`in! nѯgW]! ^#Vr+s! ^#Vr+sö͐n}W!]]!]!9{*F(#z(ò!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fow}! ~#fo͐)~#fon}<;|+k>ʂ! ~#fo͐)~#fo#n}YÝ*! ~#fo͐)~#fo#i#|©! ~#fo͐)~#fo#!!lo*6!! ~#fo͐)~#for|*n&|g}os*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}h! ~#fo͐)! s#r! ~#fo͐)* s#rÂ*n&|g}os! ~#fo͐)~#fo#n}­!!lo! ~#fo͐)~#fo#u*! ~#fo͐)~#fo#x#|! ~#fo͐)| ! !ͤͪͧ͐| ͐|G !' !ͤͪͧ͐|n ! !; !ͤͪͧ! w#w͐|ҥ ͐)*6#6! ^#Vr+sv ! w#w͐͐ ͐! ^#Vr+s~#foͭ! s#rz ͐!T !ͤͪͧ! ^#Vr+sí Ͱ`is#rz: ͐!m !ͤͪͧ͐|X ! !ͤͪͧ͐! !ͤ͐ ͐ ͐͐͐*ͳ͐ ͐ ͐͐͐͐Ͷͪ!9sort: invalid option %c sort: -n and -k don't go together sort: -n and -f don't go together sort: missing keys sort: more than %d keys sort: error in dokey %d sort: too much input. Lines(-1) or char(-2): %d sort: empty input file sort: %d input lines Â!9DM! `i͐ #| !p ͐ )*`i^#Vr+ss#r͐ )*! ^#Vr+ss#r͐|a ͐|a ͐y|a ͐y|j !p p !p !9È I(a^Û!s9DM! w#w!!  |1 ͐/|ھ !8 ! ͂ +! 6! ͂ #`is#r͐| ! s#rz !8 !~#fo#!7!lo*4w}§͐! s#r͐͐ ~#foҁ! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+s4͐ ^#Vr+s`i^#Vr+s* ^#Vr+s͐ ͐s#r! ~#fo͐ ~#fo)w#w! ^#Vr+s`i^#Vr+s!9Can't open %s '`is͐ ͐͐ )͐>'`in&#&'!9'&!9DM`iw#w͐~#fon&'}6(͐ ?͐^#Vr+snѯg`is#r'͐=(!9  *o(+*|/g}/o#9s(o(#"z{ !\&!7*!(&*!(&(!&="&! BL<"e=L=(Ì+7*^#V͐ n! s{ ! n} *! ^#Vr+s! n}-I! 6#6! ^#Vr+s! ^#Vr+sn! s|ʊ͐ ?! nѯg`is#rI͐͐?Ú!9é '!9DM! n&ͦ|! n&! n&&k)!9DM͐!͐s#rz !͐##w#w͐~#fo!9DM`iw#w! ~#fo͐n! ~#fo͐n}}! ~#fo`i^#Vr+sn}z!é1! ~#fo͐n! ~#fo͐nѯgWé!9øï)!9DM͐͐͵s#rz!͐͐s#r͐##6#6͐~#fo)!9DM͐(!͐~#fo EYZ))!9DM͐͐>h>ʏ>t>ʝ>€>ʰ>Œ>! n&<! n&!?! n&!?! n} ! !?! n&!?͐##^#Vr+s|M !͐͐~#foB|, !͐##6#6͐͐s#r͐^#Vr+s! ns&y )K*Ü*!9DM͐ڒ !ï!͐##~#fo|« !ï!͐##~#fo`is#r͐͐͐~#fop ͐ !ï!͐+#z(x2()+V+^+ )*(:()o&9! !j96  #F#xU)~#H)7:O*7,2q*&:q):ʧ)=ʧ)=r:qo&ø)z(k)7*Ͳ)\!*͵)#7:)~:,"s!"u*|*uI**~# *"*s*uI*#"u*+" *7*|DM**z*><*~+ xŠ*|}â*ç,7:,*͟*:**}|2q **:qw*! {w7:)~:,"s!"u*|]+**sb+! ~]+6*u*+"*"*u#"u)+:wo2w&7*!9& 6C#6O#6M»+*|+!\&+!\&*|+!!l&!9~#fo,> +t,#~,##+xS=,%, ö+EXECL: Too much text $!p},!*w#I,*:1c,*l,!l,!a{ ѷ! , FNxg>Goy,$?`is#r͐##~#fo|ʈ!!͐͐͐s ͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fov ï!͐##6#6͐͐s#r!ï!!9!hZ)+!9DM͐|!ͻ!Ç"͐+++|!!;!Ç"͐##^#Vr+s|p"!͐͐~#fo!`is#r!|C"͐##^#Vr+sÇ"͐##͐?+s#r͐͐s#r͐^#Vr+sn&Ç"!9ß";'&'ã!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{%`in}%%! ! s#r! 6#6! s! s! s͐n}-/#! ^#Vr+s! 4͐n}0?#! 4͐n&͖"}\#! ͙"_#!! s#r! ^#Vr+sn`is{.§#! ͙"! s#r! 4! ^#Vr+sn`is`in&͜"}D#U$X$O!$Cg$Sʘ$%͐~#fo|$! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 '$! 6'$! 6! ~#fo! n&! ^#Vr+s~#fo! ͓"ѯgs#r%! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s%! n}«$! 6#6! ^#Vr+s~#fo! s#r͐n}%͐|%! ^#Vr+s! ^#Vr+sns! ^#Vr&*K͞+$$J-'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!M! ~#fo͐)~#fo |: *n&|g}osm*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}ʶ ! ~#fo͐)!Ys#r! ~#fo͐)* s#r *n&|g}os! ~#fo͐)~#fo#n} !f!ͺ ͽ ! ~#fo͐)~#fo# *! ~#fo͐)~#fo# #|e! ~#fo͐)~#fo#!!ͺ ͽ *4w}͐! s#r͐͐ ~#fo! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+sÂ͐ ^#Vr+s`i^#Vr+s* ^#Vr+s͐ ͐s#r! ~#fo͐ ~#fo)w#w)! ^#Vr+s`i^#Vr+s< !9Can't open %s $:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7>G>)7[%#͔+:*ͅ-öô C > Ö!9DM͐2!0 ͡!0 ^#Vr+s!2 ^#Vr+s͐0|`i6d#6!V ! ͤ͐0+|^!2 ~#fo~#fon}-^͐2~#foͧ`is#r͐|M![ ͪ!~ ! ͤ͐0+|˜!2 ~#fo~#fon}-ʘ`i6d#6͐2~#fo! ͤ͐0++|͐2~#foͧ`is#r͐|! ͪ!2 ^#Vr+s~#fo! ͤ! ͪ! w#w͐pMn}X**s#rͼ*Ϳ#*6*Ϳ*6 *^#Vr+sn`is#6͐|ƒ!Þ͐|—`i6 #6͐Þ!9öN 1!!9DM!`is#rw}F! n} ͐n} *! ͪ͐! ns*! n&ͪ#|/!!ͭͰw&|g}o|Fç! ͳ|f!ͳ+++|fͰ! n} ‰͐n} ʉ! !ͳ! n&!ͳ͐! ns!9File output error; disk full? !9DM͐`is#r! ^#Vr+s! ^#Vr+sns{͐!9!9DM`iw#w! 6#6͐ n! s{ Q! n} _! ^#Vr+s5! n}-~! 6#6! ^#Vr+s! ^#Vr+sn! s|ʿ͐ ?! nѯg`is#r~͐͐?!9!9DM͐`is#r͐n}! ^#Vr+s! ^#Vr+s͐ns! ^#Vr+sn}͐1!9@B!!9DM͐͐=s#rze!͐͐s#r͐##6#6͐~#foÛó!9DM`i6#6͐ ! s#r͐ ͕! s#r!|͐#|!Æ! ^#Vr+s͐s{ *͐|J ! ͐! ͭ͐! ͐Ͱ|< J ! ^#Vr+sͳ!,9tempsplit: bad lines per file argumenttempsplit: bad lines per file argumentusage: split [-n] [outname] !9DM!# ! s#r͐ ͐ `i6.! ~#fo͐ n! s! 6`i͐ !9abcdefghijklmnopqrstuvwxyzP :C ÒÏ~ !o9DM! ̓A #|v !# D ! w#w̓̓ !`iG ! s#r|­ ! `iJ ! ^#Vr+s~ ̓| ̓| !`iG ! s#rz ! `iJ ! M ̓ !9split: can't create output fileO ÏN Ö!9DM!͐F !!| F L I Ê -x!9DM͐!́ ͐̈́ ͇͐ çN $Q :!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo5w}\ 5! ~#fo͐)~#fon}<ʉ |= +ʹ > ! ~#fo͐)~#fo#n}§ *! ~#fo͐)~#fo#ͷ #| ! ~#fo͐)~#fo#!>!ͺ ͽ *6' #'͐++n} '! ^#Vr+s6 ]`i^#Vr+sz]͐ ͕! s#rz]͐|͐|y͐ ͐͐͘6͐ Æ!9Õ!9DM! ^#Vr+sn`is{`in} ͐! ͒͐`in&͒#|!Ý!!9ç1!s!!9DM͐ڮ͐>(>O>4>]>@>p>L>ʃî! n&! n&!! n&!! n} ›! !! n&!͐##^#Vr+s| !͐͐~#fo|!͐##6#6͐͐s#r͐^#Vr+s! ns&9s!!,"!9DM͐R!o͐##~#fo|k!o͐##~#fo`is#r͐͐͐~#fo0͐ʸ!o͐+?`is#r͐##~#fo|H!͐͐͐3͐##~#fo͐s#r͐~#fo͐s#r!!͐~#fo6o͐##6#6͐͐s#r!o!9~×"!9DM͐ږ!͐~#fo{íÚ"!9DM͐!͐ͪs#rz!͐##w#w͐~#fokÏ!y9DM! !j96  #F#x,!~#!7:O*K!Q Ú"7*E!\!*H!7:)~:,"s!"u*|*u!*~#°!"*s*u!#"u*+"Ý!7*|DM** "><"~+ x"|}2"~$7:,*/":*T"}|2q ʅ"{":qwv"! {w#7,2q*&:q):"="=r:qo&7:)~:,"s!"u*|4#**s9#! ~4#6*u*+"*"*u#"u#:wo2w&7*!9& 6C#6O#6M’#*|¨#!\&ú#!\&*|º#!!l&!9~#fo#> +K$#~####xS$# Í#EXECL: Too much text $!pT$!*w# $*:1:$*C$!C$!a{ ѷ! , FNxg>Goy$$  `i͐`i!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}~! ~#fo`i^#Vr+sn}{!ê2! ~#fo͐n! ~#fo͐nѯgWê!9ÿö1!"!9DM͐|ͶÂ͐+++|!͹Â͐##^#Vr+s|k!͐͐~#foͼ`is#r!|>͐##^#Vr+sÂ͐##͐?+s#r͐͐s#r͐^#Vr+sn&Â!9!9DM`iw#w! ^#Vr+sn}ʸ`i^#Vr+sÙ͐ÿ!9!9DM! n&|ͯ! n&|ͩT#!9DM͐|! n&͐:͐##~#fo|?!͐^#Vr+s! ns͐##^#Vr+s!zÂ!h9DM! ^#Vr+s~#fo! s#r͐! s#r! ^#Vr+sn`is{`in}%µ! ! s#r! 6#6! s! s! s͐n}- ! ^#Vr+s! 4͐n}0! 4͐n&q}7! t:!! s#r! ^#Vr+sn`is{.‚! t! s#r! 4! ^#Vr+sn`is`in&w}DʮUXOCBSsß͐~#fo|! ^#Vr+s6-͐͐~#fos#r! ^#Vr+s! 6 ! 6!  TABS COMFTAIL COMIKTEE COMETR COMOUNIQ COM(BUNROT COMjCUTDIR COMPVSPLIT COMGWC COMD<O*K͞+##-'+FÎr ͖ 8{ Ăw#w#w^#V#*~#fo^#*~#fo^#V#*n^#*n^#V# ~#fo^#& ~#fo!+!#!+!#!+!+}|z{|}|z7||7zZZ)|/g}/o#|͉k|/g}/o#ɯ2qZZk:q|/g}/o#|/g}/o#:q<2qqDM!xxGyO҃)v|͔`i|)Öxڷz/W{/_ѯzW{_=yOxGæ2qZZ͉M|}ȯ|g}o)|/g}/o#z/W{/_!9~#fo! ! ! ! ! ! !9~#A"s!`*"!"!Y">2>2>22!"!6! ~#fo! n&! ^#Vr+s~#fo! nѯgs#r! ^#Vr+s! ^#Vr+s~#fos! ^#Vr+s! n}†! 6#6! ^#Vr+s~#fo! s#r͐n}͐|! ^#Vr+s! ^#Vr+sns! ^#Vr+s! ^#Vr+sá͐6! ! s#r! n}B! ^#Vr+s!|B! ^#Vr+s! n}9!0<! s͐! ^#Vr+sns{k! ^#Vr+sB! n}ʜ! ^#Vr+s!|ڜ! ^#Vr+s6 uò! ^#Vr+s`ins! ^#Vr+s`insé͐6!9!9DM͐͐ .͐^#Vr+s͐͐0#͐7s!&y͐ ͐͐ ͉͐`is͐ ͐͐ )͐`in&#&y!9È!9DM`iw#w͐~#fon&ͅ}͐ ?͐^#Vr+snѯg`is#rÖ͐!9 !9DM! n&| ! n& ! n&&!9DM! n&|ͯJ ! n&|ͩ  !\&!7*! &*! & !&="&! BL<"e=L= c#7*^#V#z x2 +V+^+ * : o&9!'"!@"!" ʞ!F#x±~#±!b2r~# "2r+}|~#G:rx"2r+w# +6#!6#2w2x*s!>r<o&F=-` r'~h6!+`W?_!~7z?` :>ª@w#G.¶ww#?*>?w#> w#.7:77!a{   `OE!y6$ -7rBo&))T])))!y':7?h#D/6:?>$:?$:)?$l,:>#)Ÿ#>67:+?7#*+?|°#2ͩ7#>67:+?7>#7>67:,?7#*+?"?)#>7:+?7>s7>@2?#2ͩ7#)$:"?=2"?))$>s7#͎)5$2:>/$2ͩ7#3ͩ7#* ?"?*+?"?:)?ʟ$:>€$)s$>>7:+?72ͩ7#2ͩ72?#)s$>7:+?7>{72ͩ7#)¸$:)?‘$>}72v$:)?1.͎)$>&773v$:)?$l,Ä#:?$u-l,$:)?>%>7l,>7>@2)?$* ?"?R3ͩ7:?2?"?|O%}@%3ͩ7V%C%4ͩ7! *4w}͐! s#r͐͐ ~#fo! ~#fo͐)! ~#fo͐#)~#fos#r! ^#Vr+sì͐ ^#Vr+s`i^#Vr+s* ^#Vr+sE͐ ͐s#r! ~#fo͐ ~#fo)w#wS! ^#Vr+s`i^#Vr+sf !9Can't open %s G>)7[%#͔+:*ͅ-ó ã ) Ô !9DM͐ ! ͡! s#r`is#r! ^#Vr+s!|f! ^#Vr+s~#fon}-f! ~#fo~#fo#! s#r͐n}c͐n}D7EAM`i6#6U! 6#6U!ͤ! ^#Vr+s͐|x͐|ʊ͐|ʒ͐|ʒ!ͤ͐ ͐ ͧ#|¯! ͤ͐|ʾͪ͐|ͭͰ!9tabs: invalid option. Use -d or -etabs: must give -d or -etabs: bad tab argument2 ú!9DM`iw#w͐y|l ͐)*w#w`i^#Vr+s@ ͐ | `i6#6͐y|Ҿ ͐)*͐|͝s#r`i^#Vr+sÀ ! ! w#w! w#w! ^#Vr+s!| ! ~#fo~#fon}& ! ~#fo~#fo6 ! 6#6͐~#fo, ! s#r͐|; ! !͐/ ! s#r͐|ʸ ͐#`is#r͐y|ү ͐)*͐͐͐|͝s#r`i^#Vr+se ! ͐)*6#6͐! s#r! ^#Vr+s ! !9 o !9DM! 6#6 `is#rzʋ ͐|S ! ! ^#Vr+s͐ |/ È ͐|t ! ! 6#6È ͐ !+++|! n} ³͐n} ʳ! !! n&!͐! ns!9File output error; disk full? r!9DM`iw#w! 6#6͐ n! s{ 3! n} A! ^#Vr+s! n}-`! 6#6! ^#Vr+s! ^#Vr+sn! s|ʡ͐ ?! nѯg`is#r`͐͐?ñ!9!9DM͐͐͐͐!9DM! ^#Vr+sn`is{<`in} ͐! ͐`in&#|9!B!B!9Qx !9DM͐!͐Ns#rz{!͐##w#w͐~#foÚá!y9DM! `i͔͐`i͗ÿ!9!9DM`iw#w! ~#fo͐n! ~#fo͐n}"! ~#fo`i^#Vr+sn}!N! ~#fo͐n! ~#fo͐nѯgWN!9]ü !9DM͐͐Zs#rz҂!͐͐s#r͐##6#6͐~#foõ !9DM͐!͐~#foͲg !9DM͐ړ͐> >4>>B>%>U>1>hÓ! n&! n&!! n&!! n} €! ! ^#Vr+s !9à o !9DM! 6#6͐! s#r͗ `is#r!| ! ^#Vr+s͚͐ | ! ͝ ͐! s#rý ͐͐% ! ͝ ! ^#Vr+s ͐#|\ ͐͝ ͐|Q ! 6#6\ ! ^#Vr+s͐#|± !9!9DM͐y|ڌ !á ͐)*~#foï Ä!9DM!͐ͦ !! ͦ ͬ ͩ KÑÄÇW!9DM*s*s*s! ~#fo͐ ~#fo)* s#r*6**s#r! 6#6`i6#6͐͐ ~#fo_w}ʆ _! ~#fo͐)~#fon}<ʳ |g+>H! ~#fo͐)~#fo#n} *! ~#fo͐)~#fo# #|!! ~#fo͐)~#fo#!h! *6!w! ~#fo͐)~#fo |d*n&|g}os×*4! ~#fo͐)~#fo#* s#r! ~#fo͐)~#fo#n}! ~#fo͐)!s#r! ~#fo͐)* s#r*n&|g}os! ~#fo͐)~#fo#n}%!! ! ~#fo͐)~#fo# *! ~#fo͐)~#fo# #|! ~#fo͐)~#fo#!