Small-C tcpp $tccom $tcc $swext/s$swcrt $stdio/h$start/s$srload $sh $rm $Read/meToptab $mnemtab$mkdfs $mkall $Manual Tlocal/h$loadsh $ld $InstallText/s $Errors Tenter/s$ctype/h$crt $as65 $Appdx_3TAppdx_2TAppdx_1T!boot $ ð2mªMÎSùJ ìCÿ@í MâCý h…, µ@ÿ ²í³AÿRgͱ C ͯM¼0w0M~úzCÿ03ÍFAý Ø CAÿ à BCÿ0ÂÍ@Cÿ€\M=CÿÀé8cŒÙMÿÀ¬L ŒÍCÿû„ÌÌZÆCÿÀwõÌÀAÿ0]ë ·Aÿ  ³AÿRl̲Aÿ·L±CýÐ*ˆ*̆`-XCÿÀéŒ ŒJCÿÀé 'Œ"CÿÀéJŒCÿÀƒ!L*| See Install for instructions. *| See Install for instructions. Small-C System Library Functions -------------------------------- BBC MOS Interface ----------------- Release 0.7 ----------- A.J.Travis 01-May-89 -------------------- Documentation: J.G.Harston 01-Jul-90 ------------------------------------ -------------------------------------------------------------------------- NAME exit SYNOPSIS exit(status) int status; /* exit value */ DESCRIPTION Exits from user program. The exit status is passed to osbyte 1. -------------------------------------------------------------------------- NAME open SYNOPSIS FILE *open(name, rwmode) char *name; /* filename */ int rwmode; /* mode of opening */ DESCRIPTION Attempts to open the named file using osfind, first checking that it exists. The method of opening is controlled by rwmode: rwmode = 0 /* open for input */ rwmode = 1 /* open for output (deletes old file) */ rwmode = 2 /* open for input and output */ Returns -1 if the file doesn't exist, otherwise the file descriptor is returned. -------------------------------------------------------------------------- NAME creat SYNOPSIS FILE *creat(name, pmode) char *name; /* filename */ int pmode; /* ignored in v0.70 */ DESCRIPTION Attempts to create a file for output using osfind &C0, and returns the file decriptor, or -1 if the attempt was unsuccessful. -------------------------------------------------------------------------- NAME close SYNOPSIS close(fd) FILE *fd; /* file decriptor */ DESCRIPTION Closes the file pointed to by fd using osfind 0. -------------------------------------------------------------------------- NAME unlink SYNOPSIS unlink(name) char *name; /* filename */ DESCRIPTION Deletes the named file using osfile 6. -------------------------------------------------------------------------- NAME stat SYNOPSIS int stat(name, fcb) char *name; /* filename */ int *fcb; /* file control block */ DESCRIPTION Uses osfile 5 to get information on the named file. Returns -1 if no file exists, and 0 if one does. The file control block is filled with the following data: fcb[0] & 0xFF file type: 1=file, 2=directory, 255=run only fcb[1] load address low 2 bytes fcb[2] load address high 2 bytes fcb[3] execute address low 2 bytes fcb[4] execute address high 2 bytes fcb[5] length low 2 bytes fcb[6] length high 2 bytes fcb[7] & 0xFF access byte fcb[7] & 0x1F00 day of month file created fcb[7] & 0xE000 (year-1981) bits 6 to 4 fcb[8] & 0x0F month file created fcb[8] & 0xF0 (year-1981) bits 3 to 0 fcb[8] & 0xFF00 undefined -------------------------------------------------------------------------- NAME system SYNOPSIS int system(string) char *string; /* command string */ DESCRIPTION Passes a string to the system oscli routine. The return value in osbyte 1 is returned. NOTE This doesn't spawn a subprocess, just passes on control. If the command is a language initialisation or a Small-C program, there won't be a return. Also, be careful with the *compact and *backup commands as they use the main memory as workspace, and will so write over the executing program, if it is not a ROM-based one. -------------------------------------------------------------------------- NAME read SYNOPSIS int read(fd, buf, count) FILE *fd; /* file descriptor */ char *buf; /* address of buffer */ int count; /* number of bytes to read */ DESCRIPTION Reads in data into memory pointed to by buf, using osgbpb 4. Before transfering anything, tests the status of the file, and returns 0 if it is at EOF. Otherwise, it returns the number of bytes actually transfered. If this is less than the number requested, then the end of the file has been hit. The data is read from the current PTR value. NOTES Version 0.7 does not have the ability to read from stdin with this call. -------------------------------------------------------------------------- NAME write SYNOPSIS int write(fd, buf, count) FILE *fd; /* file descriptor */ char *buf; /* address of buffer */ int count; /* number of bytes to write */ DESCRIPTION Writes data out from memory pointed to by buf, using osgbpb 2, or to the standard output or error output. Returns the number of bytes transfered. NOTES If writing to stdout or stderr, then '\n' is converted to "\r\n". This can cause problems when sending a "\n\r" sequence to a file which gets converted to "\r\n\r", but has no visual effect. Returns the number of bytes transfered. -------------------------------------------------------------------------- NAME getc SYNOPSIS int getc(fd) FILE *fd; /* file descriptor */ DESCRIPTION Reads a byte from the file, or stdin, returning -1 if EOF occured. NOTES Version 0.7 sign extends the character received. This makes character 255 into -1, exactly the same as EOF. When reading from stdin, the characters are echoed to the screen. -------------------------------------------------------------------------- NAME putc SYNOPSIS putc(c, fd) char c; /* character */ FILE *fd; /* file descriptor */ DESCRIPTION Writes a character out to a file or the standard output or error output. NOTES When writing to stdout or stderr, '\n' is converted to "\r\n". This means that a "\n\r" sequence becomes "\r\n\r". -------------------------------------------------------------------------- NAME vdu SYNOPSIS vdu(c) char c; /* character */ DESCRIPTION Sends a character to the oswrch vdu output. The character is sent 'pure', no modifications are performed on it as with putc(). -------------------------------------------------------------------------- NAME osbyte SYNOPSIS int osbyte(type, XYparam) int type; /* A register parameter */ int XYparam; /* X and Y register parameter */ DESCRIPTION Calls osbyte with A=type, X=XYparam mod 256, Y=XYparam div 256. Returns X+256*Y, ie the value held in XY. NOTES It is not osbyte(A,X,Y). It is osbyte(A,X+Y*256) with only two parameters. -------------------------------------------------------------------------- NAME osword SYNOPSIS osword(type, address) int type; /* A register parameter */ int *address; /* integer parameter block */ or char *address; /* character parameter block */ DESCRIPTION Calls osword with A=type, X=address mod 256, Y=address div 256, ie XY points to the parameter block. NOTES Can return XY after the call, but this is usually the same as the calling value, except with osword 0 - read a line. In general, you should not rely on XY values returned from osword calls. When working on the second processor, the Tube OS only transfers enough of the parameter block that it thinks will be suffient. Bear this in mind when writing and/or using extra osword calls. The lengths are: osword 0 Special case - read a line. oswords 1 to 20 Varying, enough for the standard osword calls and the NFS osword primitives. However, some systems don't allow enough for osword 14 - read real time clock, reading only 16 bytes instead of 25. oswords 21 to 127 16 bytes. oswords 128 to 255 Determined by parameter entries. XY+0 holds the 'send' block length and XY+1 holds the 'receive' block length. -------------------------------------------------------------------------- NAME osfile SYNOPSIS int osfile(name, fcb, type) char *name; /* filename */ int *fcb; /* file control block */ int type; /* osfile command */ DESCRIPTION Calls osfile with A=type and XY=fcb. Returns the same value as stat(). stat(name, fcb) is the same as osfile(name, fcb, 5). -------------------------------------------------------------------------- Small-C System Library Functions -------------------------------- BBC MOS Interface ----------------- Release 0.7 ----------- Small-C Standard Library Functions ---------------------------------- Release 0.7 ----------- A.J.Travis 01-May-89 -------------------- Documentation: J.G.Harston 01-Jul-90 ------------------------------------ Standard functions. Contained in lib/c -------------------------------------------------------------------------- NAME strcat SYNOPSIS char *strcat(s1, s2) char *s1; char *s2; DESCRIPTION Appends string s2 onto the end of string s1. No checks are made for the resulting string being too long for it's memory, so make sure you reserve enough room. Returns the concatenated string s1. -------------------------------------------------------------------------- NAME strcmp SYNOPSIS int strcmp(s1, s2) char *s1; char *s2; DESCRIPTION Compares string s1 and s2. Returns a positive number if s1 > s2, a negative number if s1 < s2 and zero if s1 == s2. -------------------------------------------------------------------------- NAME strcpy SYNOPSIS char *strcpy(s1, s2) char *s1; char *s2; DESCRIPTION Copies string s2 into string s1, and returns the string s1. -------------------------------------------------------------------------- NAME strlen SYNOPSIS int strlen(s) char *s; DESCRIPTION Returns the length of the string s. -------------------------------------------------------------------------- NAME strncat SYNOPSIS char *strncat(s1, s2, n) char *s1; char *s2; int n; DESCRIPTION Appends n characters from s2 onto the end of string s1. If the length of string s2 is less than n, then only those characters will be appended. Returns the concatenated string s1. -------------------------------------------------------------------------- NAME strncmp SYNOPSIS int strncmp(s1, s2, n) char *s1; char *s2; int n; DESCRIPTION Compares the first n characters of strings s1 and s2. Returns a negative number if s1 < s2, a positive number if s2 < s1 and zero if they are the same. -------------------------------------------------------------------------- NAME strncpy SYNOPSIS strncpy(s1, s2, n) char *s1; char *s2; int n; DESCRIPTION Copies n characters from s2 into s1. If s2 has less than n characters, then the rest of s1 is filled with nulls, effectively making a s1 a string of strlen(s2) length. If s2 has more than n characters, then only the first n characters are copied, making s1 a string of n length. --------------------------------------------------------------------------- NAME fclose SYNOPSIS fclose(fp) FILE *fp; /* (pseudo) i/o stream pointer */ DESCRIPTION Closes the file pointed to by fp. -------------------------------------------------------------------------- NAME fopen SYNOPSIS FILE *fopen(name, mode) char *name; char *mode; DESCRIPTION Attempts to open a file. If mode is "w", the file is first deleted, if it exists, then opened for writing. If mode is "r", the file is opened for reading. If the file could not be opened, then NULL is returned. Otherwise, the file descriptor is returned. -------------------------------------------------------------------------- NAME fgets SYNOPSIS char *fgets(s, n, fp) char *s; int n; /* maximum number of characters */ FILE *fp; DESCRIPTION Reads in characters from the file pointed to by fp, up to a maximum of n into the string s. Entry is terminated by either a '\n' character, a '\r' character or n characters being read in. DELETE (character 127) deletes the previous character, if not at the begining of the string. Returns the read string, or NULL if EOF was encountered before anything else. NOTES With version 0.7, DELETE does not decrease the count of characters read in, so if 10 characters are asked for, and five characters are entered, then five DELETE characters, the function terminates. Also, when the routine terminates on overflow, the end marker is a bit dodgy. -------------------------------------------------------------------------- NAME fputs SYNOPSIS fputs(s, fp) char *s; FILE *fp; DESCRIPTION Outputs the string s to the file pointed to by fp. If the output is to stdout or stdout, then any '\n' characters are converted to '\r' characters. -------------------------------------------------------------------------- NAME gets SYNOPSIS char *gets(s) char *s; DESCRIPTION Reads in a string from stdin into the string s. Input is terminated by either a NULL (character 0) or a '\n' (character 10). No length checking is done, so make sure that s has enough space researved for it for the longest string that you expect. -------------------------------------------------------------------------- NAME puts SYNOPSIS puts(s) char *s; DESCRIPTION Puts the string s out to stdout, followed by a '\n'. -------------------------------------------------------------------------- NAME printf SYNOPSIS printf(fmt, arg) char *fmt; /* output format */ int arg; /* argument list */ DESCRIPTION Sends output to stdout by calling fprintf. See below. -------------------------------------------------------------------------- NAME fprintf SYNOPSIS fprintf(fp, fmt, arg) FILE *fp; /* output stream */ char *fmt; /* output format */ int arg; /* argument list */ DESCRIPTION Sends output to a file. See _doprint(). -------------------------------------------------------------------------- NAME sprintf SYNOPSIS char *sprintf(s, fmt, arg) char *s; /* output string */ char *fmt; /* output format */ int arg; /* argument list */ DESCRIPTION Writes output into a string. Returns the output string. See _doprint(). -------------------------------------------------------------------------- NAME _doprint SYNOPSIS _doprint(buf, fmt, arg) char *buf; /* output buffer */ char *fmt; /* output format */ int *arg[]; /* argument list */ DESCRIPTION The internal function called by the printf functions. The character exceptions recognised are: %d print decimal %x print lower case hex %X print upper case hex %d, %x and %X can be padded with n counts of character c using %ncx, for example, %02x. %s print string %c print character \n newline character (10) \r return character (13) \t tab character (9) \0 null character (0) \0nnn character 0nnn (where 0nnn is an octal number) NOTES For more detailed descriptions of the printf functions, see a good C reference book (eg Kernighan & Ritchie). -------------------------------------------------------------------------- NAME itoa SYNOPSIS int itoa(n, s, base) unsigned n; /* input value */ char *s; /* output buffer */ int base; /* conversion base */ DESCRIPTION Converts the supplied number to a string in s, using the supplied conversion base. The function returns the number of digits in the converted string. -------------------------------------------------------------------------- NAME scanf SYNOPSIS scanf(fmt, arg) char *fmt; int arg; DESCRIPTION Reads input from stdin by calling fscanf(). See _doscan() below. -------------------------------------------------------------------------- NAME fscanf SYNOPSIS fscanf(fp, fmt, arg) FILE *fp; char *fmt; int arg; DESCRIPTION Reads input from a file. See _doscan() below. -------------------------------------------------------------------------- NAME sscanf SYNOPSIS sscanf(s, fmt, arg) char *s; char *fmt; int arg; DESCRIPTION Reads input in from a supplied string. See _doscan() below. -------------------------------------------------------------------------- NAME _doscan SYNOPSIS _doscan(fp, buf, fmt, arg) FILE *fp; /* input stream */ char *buf; /* i/o buffer */ char *fmt; /* conversion format */ int *arg[]; /* argument list */ DESCRIPTION The internal function called by the scanf functions. The character exceptions recognised are: %d read a decimal number %x read a hex number %c read a character %s read a string NOTES For a more detailed description of the scanf functions, see a good C reference book, (eg Kernighan & Ritchie). -------------------------------------------------------------------------- NAME atoi SYNOPSIS int atoi(s) char *s; /* The string to convert */ DESCRIPTION Converts the string s into an integer. Converts in decimal, unless the string starts with 0x (eg 0xff20) where hexadecimal is used, ignoring the case of any letters, or 0 (eg 0377) where octal is used. This means than decimal numbers should not have any preceding zeros. -------------------------------------------------------------------------- NAME _cmdinit SYNOPSIS _cmdinit(enter) unsigned enter; /* entry point (should be int *()) */ DESCRIPTION Extracts the command line arguments from the invocation text and stores them in memory. The routine then calls the enter entry point with argc and argv as parameters. The entry point is usually main(). NOTES Because of a bug in the compiler, the array of string pointers (char *argv[];) is treated as an array of integers (int argv[];). This means that each offset contains two characters. This is not a problem if you just compare the strings to other strings, but if you want to check an individual character, like the '-' preceding command options, you need to mask out the top with if ((argv[n] & 0xff) == '-') Where this occurs in the source programs it is marked /* BUG in compiler */ -------------------------------------------------------------------------- Standard C functions contained in sys/s: NAME isupper, etc. SYNOPSIS -------------------------------------------------------------------------- NAME toupper, tolower, toascii SYNOPSIS char toupper(c); char c; char tolower(c); char c; char toascii(c); char c; DESCRIPTION Standard C functions, normally defined as macros, but this implementation defines them as built-in functions for speed and compactness. -------------------------------------------------------------------------- Small-C Standard Library Functions ---------------------------------- Release 0.7 ----------- A.J.Travis 01-May-89 -------------------- Documentation: J.G.Harston 01-Jul-90 ---------------------- Hints, Tips and Notes ===================== Changing Mode ------------- You normally can't change mode during a program, as the data stack is put at the top of user memory, just underneath the screen. However, if you change mode to a mode that uses the same amount of memory, or less, then the data stack will not be overwritten. The definition of mode() below does just that, using osbytes 130, 132 and 133 to check the memory configuation. The if statement is read as: if not on the tube and Himem for the new mode is less then current Himem Subtracting is used instead of directly comparing because integers are 16-bit, so the 0x8000 returned by a shadow screen will be treated as a very large negative number which would always be smaller then the current Himem. mode(a) int a; /* mode */ { if (osbyte(130,0) < 0 & osbyte(133,a | 0x80)-osbyte(132,0)<0) { printf("Restart in mode %d.\n",a); exit(1); /* No memory, so stop */ } vdu(22); vdu(a | 0x80); } Returning from main() --------------------- Using return() to return a result from main() does not work correctly. main() should therefore finish with exit(0); Escape ------ The Escape function works in the Small-C programs by trapping the event vector and responding to event 6, the escape event, and generating an 'escape' error. This means that you can press escape in the middle of something, like a disk access, and not allow it to tidy up before leaving. With 'escape sensitive' parts of a program, you could use osbyte(13,6) to disable escape and osbyte(14,6) to re-enable escape to ensure that the escape is only responded to when it is safe to do so. Another side effect from using the escape event is that if you enter another language from the shell, eg Basic, then press escape, the escape event tries to execute. However, the shell rom has been paged out, and so you get a garbage error message. To avoid this, prefix commands to exit the shell with '*', which will disable the escape event until the shell is re-entered. Implementation --------------------- Integer size: 16 bits (2 bytes) Maximum symbol length: 7 characters (ie nameone and nameone2 are the same) Compatibility ------------- I have successfully tested Small-C on BBCs and Masters and on DFS, ADFS and NFS. Some early versions of HADFS doesn't like the OPENUP/CLOSE/ DELETE/OPENOUT sequence that tcc uses to create a new output file. I may change tcc to use the sequence STAT/DELETE/OPENOUT instead. Changes History --------------- v0.72 23-Jun-2005 J.G.Harston: String buffer used by printf() and scanf() functions increased to 256 bytes. v0.71 25-Jul-1991 J.G.Harston: Version 0.70 had problems operating in shadow screen modes due to the destination of a loop within the shell being one byte out. ~restart is pushed onto the machine stack instead of ~restart-1. The programmer forgot that the 6502 increments the machine return address pulled with RTS before continuing, so this caused an osbyte call to be made without the registers being set up. The source code for v0.71 has been fixed to prevent this, and the distributed shell corrected. The v0.70 shell can be patched by changing the byte in the file "sh" at offset &26B from &5B to &5A or, preferably, to &19 to ensure escape checking is re-enabled. Uses '/' as the filename seperator instead of '_'. This is consistant with the treatment of file extensions by all other Acorn systems. Hints, Tips and Notes ===================== Changing Mode ------------- You normally can't change mod©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª© ]ƒ¢ ŽTsŒUs¢ ŽVsŒWs¢_ CŽ:qŒ;q¢ ŽZsŒ[s ¼‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐLz¢e C ˆƒ Á‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLîZs¬[s %ƒŽZsŒ[s 4ƒLV¢h C ˆƒ Á‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLS ·‚ ƒ ˆƒ¢  Û…ÐL —LP ¼‚ ƒ ˆƒ¢  რ„ ƒŽ:qŒ;q ·‚ ˆƒ ƒ 4ƒ é‚ ¼‚ ˆƒ ƒ *ƒ é‚ ;ƒLV — ·‚ ˆƒ ƒ 4ƒ é‚ ¼‚ ˆƒ ƒ *ƒ é‚ ;ƒLG ·‚ ƒ ˆƒ¢  Û…ÐL’ —¢k C ˆƒ®:q¬;q ˆƒ × ¸ƒŽVsŒWs ˆƒ¢   …ÐLê®:q¬;q ˆƒ¢m C ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ ˆ= »ƒ¢* J ˆƒ¢ ' „Ž D ˆƒ × ¸ƒ é‚ ˆƒ¢   …ÐLK ²‚ ˆƒ¢F D ˆƒ¢H D ˆƒ × ¸ƒ é‚ ˆƒ¢   …ÐLK ¢P D ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ ˆ= »ƒ ¼‚ ˆƒ¢  é‚ ¼‚ ƒ ˆƒ¢8  Û…ÐL! ²‚ ƒ ˆƒ¢P  ˆƒ Ë‚ ˆƒ ®Ž µƒ¢V Ò‚ ˆƒ Æ‚ é‚¢V Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ˆƒ¢   «…ÐLÀ L— ¢V Ò‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Þ‚¢² F ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢   0„ „ ˆƒ Æ‚ ˆƒ ©> ¸ƒLX ²‚ ƒ ˆƒ Ç »ƒ ·‚ ˆƒ¢  ˆƒ¢j D ˆƒ x† ¸ƒ é‚ ˆƒ¢  ‹…  …ÐL”! ·‚ ˆƒ¢  ˆƒ¢p D ˆƒ x† ¸ƒ é‚ ˆƒ¢  ‹…  …ÐL”!¢v D ˆƒ¢  ˆƒ `’ ¸ƒ ·‚ ƒ ˆƒ¢  ‹… «…ÐLt"¢V Ò‚ ˆƒ¢² F é‚ ¼‚ ˆƒ¢  ˆƒ¢Z Ò‚ ƒ ˆƒ Æ‚ ƒ ˆƒ '‡ µƒ é‚ ˆƒ¢  «…ÐL"¢V Ò‚ ˆƒ¢X Ò‚ ƒ ˆƒ Æ‚ ƒ „ é‚L»!¢V Ò‚ ƒ ˆƒ¢² F „ ˆƒ¢8  ˆƒ¢   0„ $†ÐLe"¢Ž D ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ ˆ= »ƒ ·‚ ƒ ˆƒ Æ »ƒ®@q¬AqŽ>qŒ?q©X Eƒ`®\s¬]s ˆƒ¢   …ÐLŸ" £"` ^#`© ]ƒ ²‚ ˆƒ¢Ú I ˆƒ ï? »ƒ é‚ ˆƒ¢   …ÐL#¢=  ˆƒ ^; »ƒ ™…ÐLý" 3 ˆƒ¢Ú I ˆƒ ©> ¸ƒ¢  »ƒ`®Dq¬Eq ˆƒ¢Ú I ˆƒ ©> ¸ƒ¢  »ƒ` ²‚ ƒ ˆƒ®>q¬?q $†ÐLI# ²‚ ƒ ˆƒ ‘$ »ƒ¢  »ƒ`¢¨ D ˆƒ "= »ƒ¢  »ƒ`© ]ƒ ²‚ ˆƒ¢Ú I ˆƒ ï? »ƒ é‚ ˆƒ®>q¬?q †ÐLð#¢=  ˆƒ ^; »ƒ ™…ÐLÆ# 3 ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ @ ¸ƒ¢  »ƒ`®Dq¬Eq ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ @ ¸ƒ¢  »ƒ` ²‚ ƒ ˆƒ ‘$ »ƒ¢  »ƒ`© ]ƒ ²‚ ˆƒ®Bq¬Cq é‚¢Ú I ˆƒ û9 »ƒ ˆƒ¢   …ÐL?$¢  ¸ƒ` ·‚ ˆƒ¢Ú I ˆƒ ï? »ƒ é‚ ˆƒ®>q¬?q $†ÐL}$ ·‚ ƒ ˆƒ ‘$ »ƒ¢  ¸ƒ` ²‚ ƒŽBqŒCq¢  ¸ƒ`© ]ƒ ·‚ ˆƒ Á‚ ƒ ˆƒ¢  „ ˆƒ £@ »ƒ é‚¢b F ˆƒ¢  „ ˆƒ ¼‚ ƒ ˆƒ¢  „ ú‚ Þ‚ ˆƒ¢  ‹… «…ÐLÿ$¢ Ž^sŒ_s ¸ƒ`¢b F ˆƒ¢  „ ˆƒ ¼‚ ƒ ˆƒ¢   „ ú‚ Þ‚ ˆƒ¢  ‹… «…ÐL?% , ¸ƒ` ²‚ ˆƒ Ø% é‚¢b F ˆƒ¢  „ ˆƒ ¼‚ ƒ ˆƒ ¼‚ ƒ „ ú‚ Þ‚ ˆƒ¢  ‹… «…ÐLŠ% ¸ƒ` ²‚ ƒ ˆƒ ¼‚ ƒ ˆƒ ë& ¸ƒ ™…ÐL®% ¸ƒ`®\s¬]s ˆƒ¢   …ÐLÇ% ¸ƒ`¢¸ D ˆƒ "= »ƒ ¸ƒ`© ]ƒ¢#  ˆƒ ^; »ƒ ™…ÐLù% *( »ƒ`¢(  ˆƒ ^; »ƒ ™…ÐL& Z( »ƒ`®Bq¬Cq ú‚ ˆƒ¢a   … ˆƒ®Bq¬Cq ˆƒ¢  „ ú‚ ˆƒ îˆ »ƒ ˆƒ¢   … Q… ™…ÐLc& /* »ƒ` ²‚ ˆƒ 3 é‚¢,  ˆƒ ^; »ƒ ™…ÐL—& ²‚ ƒ ˆƒ >* »ƒ »ƒ` ²‚ ƒ ˆƒ¢  Ð… ˆƒ ·‚ ƒ ˆƒ¢  Û… Q… ™…ÐLØ& ²‚ ƒ ˆƒ , »ƒ »ƒ` ²‚ ƒ ˆƒ 9, »ƒ »ƒ` ·‚ ƒ ˆƒ¢   …ÐL' ²‚ ƒ ˆƒ :' »ƒ` ·‚ ƒ ˆƒ¢   …ÐL5' ²‚ ƒ ˆƒ ²' »ƒ`¢ ` ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  ‹…  …ÐLd'¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢  „ ú‚ Þ‚¢b F ˆƒ¢  „ ˆƒ¢  Þ‚¢ ` ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  ‹…  …ÐLÜ'¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢  „ ú‚ Þ‚¢b F ˆƒ¢  „ ˆƒ¢  Þ‚¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ 3 ˆƒ¢ÿ  Q… Þ‚¢ `© ]ƒ¢ Ž^sŒ_s ²‚ ˆƒ 3 é‚¢,  ˆƒ ^; »ƒ ™…ÐL( ²‚ ƒ ˆƒ Ö( »ƒ »ƒ`¢)  ˆƒ ^; »ƒ ™…ÐLÅ( ²‚ ƒ ˆƒ W) »ƒ »ƒ`¢Í D ˆƒ "= »ƒ »ƒ`¢x  ˆƒ ^; »ƒ ˆƒ¢   …ÐL)¢Ú D ˆƒ "= »ƒLW)¢)  ˆƒ ^; »ƒ ˆƒ¢   …ÐL.)¢ç D ˆƒ "= »ƒLW)¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢  `¢,  ˆƒ ^; »ƒ ˆƒ¢   …ÐLƒ) ²‚ ƒ ˆƒ Ø) »ƒ`¢y  ˆƒ ^; »ƒ ˆƒ¢   …ÐL¯)¢ô D ˆƒ "= »ƒLØ)¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢  `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢  ]… Þ‚¢  `¢ Ž^sŒ_s¢ `¢x  ˆƒ ^; »ƒ ™…ÐLc* ²‚ ƒ ˆƒ –* »ƒ`¢y  ˆƒ ^; »ƒ ™…ÐLˆ* ²‚ ƒ ˆƒ N+ »ƒ`¢ E ˆƒ "= »ƒ` ²‚ ƒ ˆƒ¢  ¶… ˆƒ ·‚ ƒ ˆƒ¢  Û… Q… ™…ÐL÷*¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢  ]… Þ‚¢ ` ²‚ ƒ ˆƒ¢  ¶… ˆƒ ·‚ ƒ ˆƒ¢  Û… Q… ™…ÐL¯+¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢  ]… Þ‚¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢ `¢ Ž^sŒ_s¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ ˆƒ¢  ]… Þ‚¢ `© ]ƒ¢ Ž^sŒ_s ²‚ ˆƒ 3 ˆƒ®Dq¬Eq „ ˆƒ¢  „ é‚ ²‚ ƒ ˆƒ¢€  ‹… Û… ˆƒ ·‚ ƒ ˆƒ¢  ¶… 9… ™…ÐL$-®\s¬]s ˆƒ¢   …ÐL- ²‚ ˆƒ¢  é‚L$-¢ E ˆƒ "= »ƒ¢b F ˆƒ¢  „ ˆƒ ·‚ ƒ Þ‚¢   »ƒ`¢=  ˆƒ ^; »ƒ ˆƒ¢   …ÐLr-¢) E ˆƒ "= »ƒLÉ- ;®Bq¬Cq ú‚ ˆƒ¢*   …ÐL“- Ê-LÉ- 3ŽDqŒEq®bs¬cs %ƒŽbsŒcs 4ƒ ˆƒ¢   …ÐLÉ-®Dq¬EqŽFqŒGq`© ]ƒ ²‚ ˆƒ®Dq¬Eq é‚ 3ŽDqŒEq®\s¬]s ˆƒ¢   …ÐL8. ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®Dq¬Eq $†ÐL8.®Vs¬Ws ˆƒ¢  ˆƒ æ‡ ¸ƒLü- »ƒ`¢ Ž^sŒ_s¢Ú I ˆƒ û9 »ƒ ˆƒ¢   …ÐLr.¢6 E ˆƒ "= »ƒL|/¢I E ˆƒ¢Ú I ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL›. }/L|/¢N E ˆƒ¢Ú I ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLÄ. î/L|/¢T E ˆƒ¢Ú I ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLô.¢ ŽXsŒYsL|/¢X E ˆƒ¢Ú I ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL/ ¨0L|/¢] E ˆƒ¢Ú I ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLF/ b1L|/¢b E ˆƒ¢Ú I ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLo/ 02L|/¢g E ˆƒ "= »ƒ`¢ Ž^sŒ_s®^s¬_s ˆƒ¢P  Û…ÐLí/¢b F ˆƒ®^s¬_s %ƒŽ^sŒ_s 4ƒ „ ˆƒ 3 ˆƒ¢ÿ  Q… Þ‚¢,  ˆƒ ^; »ƒ ˆƒ¢   …ÐLê/Lí/L‡/`© ]ƒ¢ Ž^sŒ_s ²‚ ˆƒ 3 é‚®^s¬_s ˆƒ¢P  Û…ÐL¤0¢b F ˆƒ®^s¬_s %ƒŽ^sŒ_s 4ƒ „ ˆƒ ·‚ ƒ ˆƒ¢  ]… Þ‚¢b F ˆƒ®^s¬_s %ƒŽ^sŒ_s 4ƒ „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢,  ˆƒ ^; »ƒ ˆƒ¢   …ÐL¡0L¤0L 0 »ƒ`© ]ƒ¢ Ž^sŒ_s ²‚ ˆƒ 3 é‚®^s¬_s ˆƒ¢P  Û…ÐL^1¢b F ˆƒ®^s¬_s %ƒŽ^sŒ_s 4ƒ „ ˆƒ ·‚ ƒ ˆƒ¢ÿ  Q… Þ‚¢b F ˆƒ®^s¬_s %ƒŽ^sŒ_s 4ƒ „ ˆƒ ·‚ ƒ ˆƒ¢  ]… Þ‚¢,  ˆƒ ^; »ƒ ˆƒ¢   …ÐL[1L^1LÃ0 »ƒ`© ]ƒ ; ²‚ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ Þ‚¢ Ž^sŒ_s®^s¬_s ˆƒ¢P  Û… ˆƒ®Bq¬Cq ú‚ ˆƒ ¼‚ ú‚ «… Q… ˆƒ®Bq¬Cq ú‚ ˆƒ¢   «… Q… ™…ÐL2¢b F ˆƒ®^s¬_s %ƒŽ^sŒ_s 4ƒ „ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ Þ‚L’1®Bq¬Cq %ƒŽBqŒCq 4ƒ© Eƒ`© ]ƒ®Ts¬Us ˆƒ Ç »ƒ ; ²‚ ˆƒ¢Ú I é‚®Bq¬Cq ú‚ ˆƒ¢   «… ˆƒ®Bq¬Cq ú‚ ˆƒ¢   «… Q… ™…ÐL¸2 ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ Þ‚LT2 ²‚ ƒ ˆƒ¢  Þ‚¢y E ˆƒ¢Ú I ˆƒ × ¸ƒŽTsŒUs ˆƒ¢   …ÐL3¢Ú I ˆƒ¢{ E ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ ˆ= »ƒ »ƒ`¢<  ˆƒ ^; »ƒ ™…ÐLC3 j3 ˆƒ¢ÿ  Q…`¢>  ˆƒ ^; »ƒ ™…ÐLf3 j3 ˆƒ¢  ]…` j3`© ]ƒ ²‚ ˆƒ \4 é‚®Bq¬Cq ú‚ ™…ÐLR4¢+  ˆƒ ^; »ƒ ™…ÐL¼3 ²‚ ˆƒ ·‚ ƒ ˆƒ \4 „ é‚LO4¢-  ˆƒ ^; »ƒ ™…ÐLì3 ²‚ ˆƒ ·‚ ƒ ˆƒ \4 „ é‚LO4¢*  ˆƒ ^; »ƒ ™…ÐL4 ²‚ ˆƒ ·‚ ƒ ˆƒ \4 0„ é‚LO4¢/  ˆƒ ^; »ƒ ™…ÐLL4 ²‚ ˆƒ ·‚ ƒ ˆƒ \4 d„ é‚LO4LR4L{3 ²‚ ƒ »ƒ`©P ]ƒ ²‚ ˆƒ û9 »ƒ ™…ÐL‡4 ²‚ ˆƒ ]5 »ƒ©P Eƒ`¢$  ˆƒ ^; »ƒ ™…ÐL¥4 6©P Eƒ`¢@  ˆƒ ^; »ƒ ™…ÐLÃ4 8©P Eƒ`¢%  ˆƒ ^; »ƒ ™…ÐLá4 Ò8©P Eƒ`¢'  ˆƒ ^; »ƒ ™…ÐLÿ4 ¢9©P Eƒ`¢*  ˆƒ ^; »ƒ ™…ÐL 5®Dq¬Eq©P Eƒ`®Bq¬Cq ú‚ ˆƒ ®ˆ »ƒ ™…ÐLC5 _7©P Eƒ`¢ E ˆƒ "= »ƒ¢  ‹…©P Eƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ ï? »ƒ é‚®\s¬]s ˆƒ¢   …ÐLØ5 ²‚ ƒ ˆƒ¢   …ÐL´5¢£ E ˆƒ "= »ƒLØ5 ²‚ ƒ ˆƒ®>q¬?q $†ÐLØ5¢´ E ˆƒ "= »ƒ ²‚ ƒ ˆƒ¢   …ÐLõ5¢ê ê »ƒ` ²‚ ƒ ˆƒ¢  „ ˆƒ £@ »ƒ »ƒ`© ]ƒ®Bq¬Cq ú‚ ˆƒ ¾ˆ »ƒ ˆƒ¢   …ÐLC6¢  ‹… »ƒ` ²‚ ˆƒ¢  é‚®Bq¬Cq ú‚ ˆƒ ¾ˆ »ƒ ™…ÐLª6 ²‚ ˆƒ ·‚ ƒ ˆƒ¢  0„ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ ˆƒ ´6 »ƒ „ é‚LP6 ²‚ ƒ »ƒ` ²‚ ú‚ ˆƒ ®ˆ »ƒ ™…ÐLÜ6 ²‚ ú‚ ˆƒ¢0  „` ²‚ ú‚ ˆƒ ¾ˆ »ƒ ™…ÐLW7 ²‚ ú‚ ˆƒ Žˆ »ƒ ™…ÐL%7 ²‚ ú‚ ˆƒ¢A  „ ˆƒ¢   „` ²‚ ú‚ ˆƒ žˆ »ƒ ™…ÐLW7 ²‚ ú‚ ˆƒ¢a  „ ˆƒ¢   „`¢  ‹…`© ]ƒ®Bq¬Cq ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐL7¢  ‹… »ƒ` ²‚ ˆƒ¢  é‚®Bq¬Cq ú‚ ˆƒ ®ˆ »ƒ ™…ÐLø7 ²‚ ˆƒ ·‚ ƒ ˆƒ¢   0„ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ „ ˆƒ¢0  „ é‚L7 ²‚ ƒ »ƒ`© ]ƒ®Bq¬Cq ú‚ ˆƒ¢0  Û… ˆƒ®Bq¬Cq ú‚ ˆƒ¢7  ¶… 9… ™…ÐLF8¢  ‹… »ƒ` ²‚ ˆƒ¢  é‚®Bq¬Cq ú‚ ˆƒ¢0  Ð… ˆƒ®Bq¬Cq ú‚ ˆƒ¢7  Ã… Q… ™…ÐLÈ8 ²‚ ˆƒ ·‚ ƒ ˆƒ¢  0„ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ „ ˆƒ¢0  „ é‚LS8 ²‚ ƒ »ƒ`© ]ƒ®Bq¬Cq ú‚ ˆƒ¢0  «… ˆƒ®Bq¬Cq ú‚ ˆƒ¢1  «… Q… ™…ÐL9¢  ‹… »ƒ` ²‚ ˆƒ¢  é‚®Bq¬Cq ú‚ ˆƒ¢0   … ˆƒ®Bq¬Cq ú‚ ˆƒ¢1   … 9… ™…ÐL˜9 ²‚ ˆƒ ·‚ ƒ ˆƒ¢  0„ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ „ ˆƒ¢0  „ é‚L#9 ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ Þ‚®Bq¬Cq ú‚ ˆƒ¢'   …ÐLï9®Bq¬Cq %ƒŽBqŒCq 4ƒ ²‚ ú‚© Eƒ`© ]ƒ ; ²‚ ˆƒ ¼‚ ƒ é‚®Bq¬Cq ú‚ ˆƒ ~ˆ »ƒ ˆƒ®Bq¬Cq ú‚ ˆƒ¢_   … 9… ˆƒ®Bq¬Cq ú‚ ˆƒ¢~   … 9… ™…ÐLþ: ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ Þ‚®Bq¬Cq ú‚ ˆƒ îˆ »ƒ ˆƒ®Bq¬Cq ú‚ ˆƒ¢_   … 9… ™…ÐLî: ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®Bq¬Cq %ƒŽBqŒCq 4ƒ ú‚ Þ‚L‹: ²‚ ƒ ˆƒ¢  Þ‚ ²‚ ƒ ˆƒ ¼‚ ƒ „ »ƒ`®Bq¬Cq ú‚ ˆƒ¢    … ˆƒ®Bq¬Cq ú‚ ˆƒ¢    … 9… ™…ÐL];®Bq¬Cq %ƒŽBqŒCq 4ƒL;` ;®Bq¬Cq ú‚ ˆƒ ·‚ ú‚ «…ÐL€;¢ `®Bq¬Cq %ƒŽBqŒCq 4ƒ¢ `© ]ƒ®Zs¬[s ™…ÐLÀ< ·‚ ˆƒ¢  é‚ ¼‚ ƒ ˆƒ ¼‚ ƒ „ ˆƒ¢Ã E ˆƒ ’ ¸ƒ ²‚ ˆƒ¢  é‚ ²‚ ƒ ˆƒ¢  Û…ÐLp< ·‚ ƒ ˆƒ®^s¬_s Û…ÐLN<¢b F ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ „ ú‚ ˆƒ¢ÿ  Q… ˆƒ¢Ê E ˆƒ ’ ¸ƒL[<¢Ð E ˆƒ ’ »ƒ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒLæ; ·‚ ƒ ˆƒ¢  Û…ÐLœ<¢Š I ˆƒ¢Ô E ˆƒ ’ ¸ƒL©<¢Ø E ˆƒ ’ »ƒ ·‚ ƒ ˆƒ®^s¬_s Û…ðL·; ·‚ ˆƒ¢  é‚ ·‚ ƒ ˆƒ®^s¬_s Û…ÐL=®Vs¬Ws ˆƒ¢b F ˆƒ Á‚ ƒ „ ú‚ ˆƒ æ‡ ¸ƒ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒLÍ< ¸ƒ`¢Š I ˆƒ¢Ú E ˆƒ ’ ¸ƒ ²‚ ƒ ˆƒ¢å E ˆƒ ’ ¸ƒ®`s¬as %ƒŽ`sŒas ˆƒ¢  ¶…ÐL‡=¢ð E ˆƒ ’ »ƒ¢  ‹… ˆƒ ˆ= »ƒ`®Ts¬Us ˆƒ¢  «…ÐL¬=®Ts¬Us ˆƒ Ç »ƒ®Vs¬Ws ˆƒ¢  «…ÐLÐ=®Vs¬Ws ˆƒ Ç »ƒ ²‚ ƒLo†`© ]ƒ¢* JŽ@qŒAq ²‚ ˆƒ¢  é‚ ²‚ ƒ ˆƒ¢  Û…ÐL7>¢R q ˆƒ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ˆƒ¢  é‚Lö= »ƒ`© ]ƒ ²‚ ˆƒ¢  é‚ ·‚ ƒ ú‚ ™…ÐLŸ> ²‚ ˆƒ¢  ˆƒ ¼‚ ƒ 0„ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ „ ˆƒ¢  À„ é‚LM> ²‚ ƒ »ƒ`© ]ƒ ¼‚ ˆƒ Æ‚ ƒ ˆƒ +‹ »ƒ ˆƒ¢  „ é‚®@q¬Aq ˆƒ Á‚ ƒ „ ˆƒ® »ƒ é‚ ²‚ ˆƒ®@q¬Aq é‚¢R q ˆƒ ¼‚ ƒ რ„ ƒ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ @ ¸ƒ¢R q ˆƒ ¼‚ ƒ რ„ ˆƒ ·‚ ƒ é‚ Æ‚ ƒ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ @ ¸ƒ Á‚ ƒ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ ÕŠ ¸ƒ ²‚ ƒ ˆƒ Á‚ ƒ „Ž@qŒAq µƒ`© ]ƒ ²‚ ˆƒ¢R q ˆƒ Á‚ ƒ ˆƒ ;> »ƒ რ„ ƒ é‚ ²‚ ƒ ™…ÐL†@ ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLa@L†@Lƒ@ ²‚ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ £@ »ƒ é‚L@ ²‚ ƒ »ƒ` ²‚ ƒ ˆƒ ¼‚ ƒ é‚` ²‚ ƒ ƒ`© ]ƒ®@q¬Aq ˆƒ®>q¬?q  …ÐLÍ@ ¸ƒ` ²‚ ˆƒ¢, F ˆƒ¢. F ˆƒ × ¸ƒ é‚ ˆƒ¢   …ÐLA¢4 F ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ ˆ= »ƒ ·‚ ˆƒ®>q¬?q é‚ ·‚ ƒ ˆƒ®@q¬Aq $†ÐL1B ·‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢~  «…ÐL¬A ·‚ ƒ ˆƒ¢  „ ˆƒ £@ »ƒ ˆƒ ¼‚ ƒ ˆƒ¢  „ ˆƒ¢L F ˆƒ Á‚ ƒ ˆƒ `’© Eƒ®Zs¬[s ™…ÐLöA ·‚ ƒ ˆƒ¢  „ ˆƒ £@ »ƒ ˆƒ ¼‚ ƒ ˆƒ¢  „ ˆƒ¢W F ˆƒ ’ µƒ ·‚ ˆƒ ¼‚ ƒ ˆƒ Á‚ ƒ ˆƒ¢  „ ˆƒ +‹ »ƒ „ ˆƒ¢  „ é‚L,A ²‚ ƒ ˆƒ Ç »ƒ ¸ƒ`© ]ƒ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚¢  ˆƒ ·‚ ˆƒ¢ Ò‚ ƒ ˆƒ Hˆ µƒ© Eƒ`o/out-l-owas65: can't open %s rcan't open %s ~eot~eod~eot~eod%u = %u+%u (0x%04X, 0x%04X, 0x%04X) as65: %d errors usage: as65 [-l] [-o outfile] file1 ... [filen] %ssymbol/pseudo-op requiredrmnemtabrmnemtabas65: can't open mnemtab optaboptabas65: can't open optab as65: illegal optab size label redefinedillegal address modesyntax error'x' expected')' expected'y' expected'x' or 'y' expectedbranch out of range'=' expectedpseudo-op expectedbytedbyteendwordtextfileillegal pseudo-opras65: can't open %s illegal expressionsymbol undefinedillegal symbol%04X %02X %s *****: %serror: %s as65: too many errors, assembly aborted symbol table full wg/outas65: can't open g/out %s =$%04X %s =$%04X ©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª© ]ƒ¢ ŽTsŒUs¢ ŽVsŒWs¢_ CŽ:qŒ;q¢ ŽZsŒ[s ¼‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐLz¢e C ˆƒ Á‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ­!H­ H hªh¨© Ž Œ!¢Lôÿغ†~©„ ôÿ†|„}¢H © ¢Š C L[A…†p„q çÿ º †½¼ª †¦p¤q †¦t¤u †¦x¤y †¦|¤} † ±|ªÈ±|¨ †¥¦p¤q`˜ ”Š ”© îÿ`HJJJJ ¡h ¡`)É 0ii0Lîÿ ÿ` `¦|¤}`¢L×¢L×¢L×¢L×¢ L×¢  Še|ª˜e}¨` ¨ Š‘tL¯ ¨„q Š‘tÈ¥q‘t¨`†p„q ±pªL¯†p„q ±pªÈ±p¨` ±|…xȱ|…y ÀlxèÐÈ`Šiª˜i¨`ÊàÿЈ`8Šéª˜é¨`e|…|©e}…}`e|…|¥e}…}`…x8¥|åx…|¥}é…}`…x8¥|åx…|¥}å…}`Цt…t˜¤u…u`8¥|é…|¥}é…}„q˜ ‘|ˆŠ‘|¤q`„q ±|…tȱ|…u¤qLÀ À À¥|i…|¥}i…}`„q ±|…pŠ‘|ȱ|ª¥q‘|Ѝ¦p`©…x†r„s „p„q p&q&r&s ¥xep…p©eq…qˆÐæ¦p¤q` ¨Šetª˜eu¨` ¨†p„q8¥tåpª¥uåq¨` ¨†r„s „p„q p&q&r&s¥tep…p¥ueq…q©er…rˆÐà¦p¤q` ¨˜EuH˜ $u 0 Šh ` ¨ †x„y¥t…p¥u…q „t„u¢p&q&t&u8¥tåx¨¥uåy„t…u&p&qÊÐå¦p¤q` ¨˜H $u 0 ãh ` ¨ †x„y „p„q¢t&u&p&q8¥påx¨¥qåy„p…q&t&uÊÐå¦p¤q`ŠÐ˜Ðdivision by zero`8©åt…t©åu…u` ¨Štª˜u¨` ¨ŠEtª˜Eu¨` ¨Š%tª˜%u¨` ¨¥u…q¥tàðFqjÊÐúª¤q` ¨¥t…p¥uàðp*ÊÐú¨¦p`ŠIÿiª˜Iÿi¨`àÐÀ` ëð¢`¢` ëТ`¢` ëð¢`¢` ëð¢`¢` ë°¢`¢` ë¢`¢` ¨†p˜ I€…q¥uI€ÅqÐ¥tÅp` 4ð¢`¢` 4ð¢`¢` 4°¢`¢` 4¢`¢` ¨†p„q ¥uÅqÐ¥tÅp`ÉÐ'© ¢ ôÿ©~ ôÿ©  Îÿ©² ¢ÿ ôÿ escape`© ôÿ¦~š` ©…€©…©¢€  ÝÿÉð ±|ijjj¢  Îÿªð `¢ÿ ÿ` ©€¢  Îÿªð `¢ÿ ÿ` ±|¨© Îÿ` ©…€©…©¢€  Ýÿ`©LQ ¢  ÷ÿ©¢ ôÿ `©¢€  Úÿ¦€¤` ±|…pȱ|…q ±p™ðÈÐö© ™` ±|ª© ôÿŠð¢ `©HL… ±|Éð Éð©HL… ±|…pȱ|…qȱ|…xȱ|ª ¥xÐàðÊÆx±p ÈÐíæqLl` ±|…€ ±|…ȱ|…‚©…ƒ…„ȱ|……ȱ|…†©…‡…ˆh¢€  Ñÿ8 ±|兪ȱ|冨` ±|ð¨ ×ÿ°ªL¯¢ÿ ÿ` àÿÉ Ð îÿ© îÿªL¯ ±|ª ±|Éð É𨊠Ôÿ`ŠÉ ð îÿ`© îÿ© îÿ` ±| îÿ` ±|ªÈ±|… ±|¤ ôÿ` ±|ªÈ±|… ±|¤ ñÿ˜ªh)¨` ±|H  ±|…xȱ|…y ©‘xÈ©‘xh¦x¤y ÝÿÉТÿ ÿ`¢ ‘x` ±|ª½^ )ªð¢` ±|ª½^ )ªð¢` ±|ª½^ )ªð¢` ±|ª½^ )ªð¢` ±|ª½^ )Dªð¢` ±|ª½^ )ªð¢` ±|ª½^ )ªð¢` ±|ª½^ )ªð¢` ±|ª½^ )ªð¢` ±|ª½^ ) ªð¢` ±|)€I€ªð¢` ±|ª½^ )ð8Šé ª` ±|ª½^ )ðŠi ª` ±|)ª`  AAAAAABBBBBB © b ·  Á  î ¼   * î 9 ÿ žÐL!Lò ¼   9 î ¼   * î 9  Æ   * î 9 ÿ ã žÐLY!L!! ·  À` ·  ÿ  Á   * î 9 ÿ ¥ÐL¸! ·   * î 9 ÿ ¢  ¥ÐLµ!¢ `Lc! ·  ÿ  Á   9 î ÿ "`© b ·  Á  î ¼   * î 9  Æ   * î 9 ÿ ã žÐL&"Lî! ·  À`© b · ¢  î ¼   * î 9 ÿ žÐLt" ·   * î 9LB" ·  À`© b ·  Á  î ¼   * î 9 ÿ žÐL²"L’" ¼   9 î ¼   * î 9  Æ   * î 9 ÿ ã žÐL3# Æ   9 î ¢  àÐL0# ¼   9 î ¢  ãL3#LÁ" ·  À` Á   9 î ¢  Õ  ¼  ÿ  Æ   * î 9 ÿ ¥ V žÐL´# ·   * î 9 ÿ ¢  ¥ÐL±#¢ `L=# Á  ¢  àÐLÎ#¢ ` ·  ÿ  Á   9 î ÿ "`© b ·  Æ  î ¼ ¢  î ¼   Ð  àÐLÂ$ Á   * î 9  Ë   * î 9 ÿ ã ¢  ¥ÐL­$ ¼   * î  Ð  àÐL£$ Á   * î 9 ¢  ãLd$ ·  ½` ¼   * î 9L$ ·  ½` ·   È À`© b Á  ÿ ¢w  ¥ÐLj% · ¢   Æ   } ½ î ¢   °ÐLH% ·   È À ¼   Ó À · ¢   Æ   ± ½ îL‰% · ¢   Æ   } ½ î ·  ¢   ¥ÐL©%¢  À` ·  À`© b ·  Æ  î Æ   9 î ¢  »  Á  Õ   à À î ¢   ° V žÐL¯& ¼  ¢  ¥ÐLZ& ·   9 î  Æ  )ÐLW& ·  Æ  îLÇ% ¼  ¢   ¥ÐL|& ¼ ¢   î ·   * î 9  Á  ã ¢   ¥ÐL¬&L¯&LÇ% ·  ¢  ã ¼  ¢   ¥  ¼   Ë  ¥ V žÐLú&¢  ½` Á  ½`© b Ë  ¢  °  Ð  ¢  ° V  Ð  ¢  ° V žÐL§' Á  Ë  î Á  ÿ žÐL§' Á  ÿ ¢   ¥ÐL•' Á  ¢   ã Á   * îL\' ·  Ë   * î 9 ÿ î žÐLñ' ¼  Ð   Á   ë ½ îL§' ¼  º`© b ·  Æ  î ¼ ¢   à À î ¢   °  Á  ¢  Õ V žÐLn( ·   * î 9  Á  ãL( ¼  ¢  à  ¼   Ë  ¥ V žÐL¦(¢  ½` ·  ¢  ã Á  ½`© b ·  Á   * î 9 ÿ î žÐL)¢   ¼   ë ½LÅ(¢  ¢    ë ½ À`©…© r¢  Ù ¢  Ù   Á  Ó) º¢   ¼  ' ½©…© V`©…© r¢  Ù ¢  Ù   Á  Ó) º¢  Ù   ¼  ' ½©…© V` Á  Á   Á   Ó) º`© b Ë ¢ ×  î¢ ×  ÿ žÐLÊ1 Ð  Ð  î¢ ×  ÿ ¢%  °ÐLW* Ë   * î 9 ¢ ×   * î 9 ÿ ãLé)¢ ×   * î ÿ ¢-  ¥ÐLŸ*¢ × ¢ ×   * î 9 ÿ ãL®*¢ × ¢   ã¢ ×  ÿ ¢0  ¥ÐL+¢ × ÿ ¢-  ¥ÐLù*¢ ×   * î 9 ÿL+¢ × ¢ ×   * î 9 ÿ ã ¼ ¢  î¢ ×  ÿ  ³ À žÐL‡+ ¼  Á  ¢   5 ¢ ×   * î 9 ÿ  ¢0  " îL(+¢ ×  ÿ ¢.  °ÐL´+ · ¢   îL\,¢ ×   * î ÿ  ³ À ¢  ¥ÐLð+ · ¢  îL\, · ¢  î¢ ×  ÿ  ³ À žÐL\, ·  ¼  ¢   5 ¢ ×   * î 9 ÿ  ¢0  " îLý+ Æ ¢ ×   * î 9 ÿ ã ¢d  ¥ÐLC-¢ ×   ¢ € V žÐL- Ë   * î 9 ¢-  ã Ë  Ð  ¢   ¢ ×  ¢ ×     à1 º  îL@- Ë  Ð  ¢   ¢ ×  ¢ ×    à1 º  îLü/ Æ ÿ ¢o  ¥ÐL–- Ë  Ð  ¢  ¢ ×  ¢ ×    à1 º  îLü/ Æ ÿ ¢u  ¥ÐLé- Ë  Ð  ¢   ¢ ×  ¢ ×    à1 º  îLü/ Æ ÿ ¢x  ¥ÐL<. Ë  Ð  ¢  ¢ ×  ¢ ×    à1 º  îLü/ Æ ÿ ¢X  ¥ÐL’. Ë  Ð  ¢   ¢ ×  ¢ ×    à1 º  îLü/ Æ ÿ ¢c  ¥ÐLÝ. Ë   * î 9 ¢ ×   ã Ë  ¢  ãLü/ Æ ÿ ¢s  ¥ÐLÎ/ Á ¢ ×   î Ë   9 î ·  ¢  àÐLb/ Ë   * î  Æ   * î 9 ÿ ã žÐL_/L*/LË/ Ë   * î  Æ   * î 9 ÿ ã žÐLË/ ·   9 î * ¢  ¥ÐLÈ/ Ë  ¢  ãLË/Lb/Lü/ Ë   * î 9  Ë ÿ ã Ë  ¢  ã ¼  Á   Õ  ¢ ×  " " î ¢  »ÐL³1¢ × ÿ ¢-  ¥ÐLž0 ¼   9 î * ¢  »ÐL‹0 Ë   * î 9 ¢   ãLK0 Ë  ¢  ãL³1 Æ ÿ ¢d  ¥  Õ  ÿ ¢-  ¥ V ¢ × ÿ ¢0  ¥ V žÐLù0 Ð   * î 9 Ë   Õ  ÐL@1 Ë   Á    Ð   9 î * ÿ ãLù0 ¼   9 î * ¢  »ÐL„1 Ð   * î 9 ¢ × ÿ ãL@1 Ë   * î 9 ÿ žÐL¤1L„1 Ë   9 î¢ ×   / î @Lé) Ë  ¢  ã© J`© b Ð  ¢  ÕÐL2 ¼ ¢a  ¢   " îL=2 Ð  Õ   î ¼ ¢A  ¢   " î ·  Ð  î Æ  ¢  ¥ÐL€2 ·   * î 9 ¢0  ãL/3 Æ  žÐL/3 Á  Ë  ¢ ×  à î ¢   àÐLå2 ·   * î 9  Æ  ¢0   ãL3 ·   * î 9  Æ   Æ   ã Æ  Ë  ¢ ×  ‡ îL€2 Æ  ¼   Õ  " î ·   9 î * ¢  ã Ë   ¼  )ÐLÑ3 Á  Ð  ÿ î Ë   * î 9  ¼  ÿ ã ·   9 î *  Æ  ãLf3 Æ  º`©…© r¢  Ù ¢  Ù   Á ¢   Š4© J©…© V`©…© r¢  Ù ¢  Ù   Á ¢  Ù   Š4© J©…© V` Á  Á   Á  ¢    Š4© J`© b¢ ×  ¢   °ÐL»4¢ ×  ¢  ã¢ × ¢ ×  î · ¢  î¢ ×  ÿ žÐL"@¢ × ÿ ¢%  ° ¢ × ÿ ¢  ¥ > žÐLî7¢ × ¢ ×   * î 9 ÿ ã  Ó À žÐLV5L 5 Õ ¢ ×   * î 9 ÿ ã  Ó À žÐLŠ5LV5¢ × ÿ ¢  ¥ÐL¤5Lî7¢ ×  ¢   °ÐL7 Õ ÿ ¢  ¥ÐL7¢ × ¢ ×  î Æ ¢  î Æ  ¢  àÐLð6 Õ ¢ ×   à À ã ¢   ¥ÐL76Lð6 Õ ÿ ¢  ¥ÐL†6¢ ×   9 î ¢ ×  )ÐLƒ6¢ × ¢ ×  îLó5¢ ×   * î 9 ¢ × ÿ ã Õ ÿ ¢   ¥ ¢ × ÿ ¢   ¥ > žÐLÛ6Lð6 Æ   * î 9Ló5¢ ×  ¢  ã Õ ÿ ¢   ¥ ¢ ×  ¢ ×  ¥ V žÐLF7¢  © J`¢ × ¢ ×  î Õ ¢ ×   * î 9 ÿ ã  Ó À žÐL7LY7L¾5¢ × ÿ ¢  ° ¢ × ÿ ¢ × ÿ ° V ¢ × ÿ ¢%  ° V žÐLë7¢  © J`Lî4¢ × ÿ ¢  ¥ÐL8L"@¢ × ¢ ×   * î 9 ÿ ã ¼ ¢ × ÿ ¢*  ° î ¢  ¥ÐLv8¢ × ¢ ×   * î 9 ÿ ã¢ × ÿ  ³ À ¢  ¥ÐL¦8 Ð ¢  îL9 Ð ¢  î Ð  Õ  ¢   5 ¢ × ÿ  ¢0  " î¢ × ¢ ×   * î 9 ÿ ã  ³ À žðL³8 Æ ¢  î¢ × ÿ ¢d  ¥ÐLÃ: Ë ¢  î Õ ÿ ¢+  ¥ÐL9 Õ ¢ ×   * î 9 ÿ ã Ð   9 îLã9 Õ ÿ ¢-  ¥ÐLã9 Õ ¢ ×   * î 9 ÿ ã Ë ¢   î Ð   9 î Õ ÿ  ³ À ¢  ¥ÐL:¢  © J` Õ ÿ  ³ À ¢  °  Õ   9 î * ¢  » V žÐL¥: Æ  Ë  ¢   5 ¢ × ÿ  ¢0  " î Õ ¢ ×   * î 9 ÿ ãL: Æ  Ë   Õ  5 îL¬?¢ × ÿ ¢o  ¥ÐLÀ; Õ ÿ ¢0  à ¢ × ÿ ¢7  » > žÐL;¢  © J` Õ ÿ ¢0  Õ ¢ × ÿ ¢7  È V  Õ   9 î * ¢  » V žÐL½; Æ  Ë  ¢  5 ¢ × ÿ  ¢0  " î Õ ¢ ×   * î 9 ÿ ãL;L¬?¢ × ÿ ¢x  ¥ ¢ × ÿ ¢X  ¥ > žÐLÓ= Õ ÿ ¢0  ¥ÐLj< Õ ¢ ×   * î 9 ÿ ã ¢ × ÿ ¥ÐL]< Õ ¢ ×   * î 9 ÿ ãLj<¢  © J` Õ ÿ  à À ¢  ¥ÐL•<¢  © J` Õ ÿ  à À ¢  °  Õ   9 î * ¢  » V žÐLÐ= Õ ÿ  ³ À žÐL = Á ¢ × ÿ ¢0  " îLˆ= Õ ÿ  “ À žÐLL= Á ¢ × ÿ ¢A  " ¢    îLˆ= Õ ÿ  £ À žÐLˆ= Á ¢ × ÿ ¢a  " ¢    î Æ  Ë  ¢  5  Ë   î Õ ¢ ×   * î 9 ÿ ãL•¢ × ¢ ×   Á   * î 9 æ   î Õ ÿ ¢  °  Õ   9 î * ¢  » V žÐL¼>¢ ×   * î 9 ¢ × ÿ ã Õ ¢ ×   * î 9 ÿ ã  Ó À žÐL¹>L¼>L)>¢ ×  ¢  ãLB? Õ ÿ ¢  °  Õ   9 î * ¢  » V žÐLB? Õ ¢ ×   * î 9 ÿ ã  Ó À žÐL??LB?LÑ>L¬?¢ × ÿ ¢c  ¥ÐLŸ? Æ ¢ × ÿ î Õ ¢ ×   * î 9 ÿ ã Ð   9 îL¬?¢  © J` ¼  ¢  ° ¢ × ÿ ¢s  ° V žÐL@¢ ×   ¼   * î 9 æ    Ë  î¢ ×   9 îLÛ4 · © J`© b Á ¢  î ¼ ¢  î ·  Ë   * î 9 ÿ î ¢+  ¥ÐL›@ ·  Ë   * î 9 ÿ îLÞ@ ·  ¢-  ¥ÐLÞ@ ·  Ë   * î 9 ÿ î ¼ ¢   î ·   ³ À žÐLEA Á  Æ  ¢   5  Á   ¢0  " î ·  Ë   * î 9 ÿ îLÞ@ Á   Á  5 º`©…©F r¢D  Ù   î¢B  Ù  ¼  Ù ¢  æ  ¢D  Ù  î¢B  Ù   * î 9 ¢  ã¢@  Ù ¢  î¢D  Ù  ÿ ¢   °ÐLPC¢D  Ù  ÿ ¢   ¥ ¢F  Ù  ÿ ¢   ¥ > žÐLJB¢D  Ù   * î 9LõA¢D  Ù  ÿ ¢   °ÐLœB¢  Ù ¢B  Ù   * î 9 æ  ¢D  Ù  î¢D  Ù  ÿ ¢   ° ¢F  Ù  ÿ ¢   ° V ¢F  Ù  ÿ ¢   ° V žÐL-C¢B  Ù   * î 9 ¢F  Ù   * î 9 ÿ ãLœB¢B  Ù   * î 9 ¢  ãLÙA¢F  Ù  ¢  Ù Î ¢D  Ù  Î   ½©…©F V`­!H­ H hªh¨© Ž Œ!¢Lôÿغ†~©„ ôÿ†|„}¢H © ¢Š C L[A…†p„q çÿ º †½¼ª †¦p¤q †¦t¤u †¦x¤y †¦|¤} † ±|ªÈ±/* dummy header file */ /* dummy header file */ Lôÿغ†~©„ ôÿ†|„}¢H © ¢Š C L[A…†p„q çÿ º †½¼ª †¦p¤q †¦t¤u †¦x¤y †¦|¤} † ±|ªÈ±|¨ †¥¦p¤q`˜ ”Š ”© îÿ`HJJJJ ¡h ¡`)É 0ii0Lîÿ ÿ` `¦|¤}`¢L×¢L×¢L×¢L×¢ L×¢  Še|ª˜e}¨` ¨ Š‘; enter.s 11-Apr-89 A.J.Travis ; ; patch a jump to main from user entry point ; *=__enter ; jmp _main ; ; enter.s 11-Apr-89 A.J.Travis ; ; patch a jump to main from user entry point ; *=__enter ; jmp _main ; ¤} † ±|ªÈ±|¨ †¥¦p¤q`˜ ”Š ”© îÿ`HJerrors 15-Nov-88 A.J. Travis ------------------------------ tcc compiler error messages 1. Illegal function or declaration 2. Already defined 3. Missing opening parenthesis 4. Illegal argument name 5. Missing closing parenthesis 6. Wrong number of arguments 7. Illegal symbol name 8. Argument name expected 9. Comma expected 10. 'while' expected 11. Illegal 'goto' label 12. L-value required 13. Illegal address 14. Can't subscript constant 15. Can't subscript variable 16. Illegal expression 17. delimeter expected 18. Illegal symbol name 19. Global symbol table full 20. Local symbol table full 21. Too many active whiles 22. No active whiles 23. Illegal character constant 24. Constant required 25. Negative size illegal 26. Missing semicolon 27. Missing bracket errors 15-Nov-88 A.J. Travis ------------------------------ tcc compiler error messages 1. Illegal function or declaration 2. Already defined 3. Missing opening parenthesis 4. Illegal argument name 5. Missing closing parenthesis 6. Wrongpr =$0070 sr =$0074 tr =$0078 sp =$007C rsp =$007E asave =$007F param =$0080 osrom =$00F4 userv =$0200 brkv =$0202 irq1v =$0204 irq2v =$0206 cliv =$0208 bytev =$020A wordv =$020C wrchv =$020E rdchv =$0210 filev =$0212 argsv =$0214 bgetv =$0216 bputv =$0218 gbpbv =$021A findv =$021C fscv =$021E evntv =$0220 uptv =$0222 netv =$0224 vduv =$0226 keyv =$0228 insv =$022A remv =$022C cnpv =$022E ind1v =$0230 ind2v =$0232 ind3v =$0234 gsbuf =$0400 osurom =$8000 osrdrm =$FFB9 oseven =$FFBF gsinit =$FFC2 gsread =$FFC5 nvwrch =$FFC8 nvrdch =$FFCB osfind =$FFCE osgbpb =$FFD1 osbput =$FFD4 osbget =$FFD7 osargs =$FFDA osfile =$FFDD osrdch =$FFE0 osasci =$FFE3 osnewl =$FFE7 oswrch =$FFEE osword =$FFF1 osbyte =$FFF4 oscli =$FFF7 start =$1902 __trace =$193E ext =$19AF addr =$19B7 addr_1 =$19BC addr_2 =$19C1 addr_3 =$19C6 addr_4 =$19CB addr_5 =$19D0 addr_6 =$19D5 addr_b =$19D7 addr_w =$19D9 sind_b =$19E3 sind_w =$19EE lind_b =$19FF lind_w =$1A0B scall =$1A19 inc1 =$1A2A inc2 =$1A2F dec1 =$1A39 dec2 =$1A40 sinc_b =$1A4A sinc_w =$1A56 sdec_b =$1A62 sdec_w =$1A72 swap =$1A82 push =$1A8D pop =$1AA8 drop3 =$1ABA drop2 =$1ABD drop =$1AC0 xchange =$1ACE scale2 =$1AE6 scale =$1AE8 add =$1B15 sub =$1B22 mult =$1B35 div =$1B69 udiv =$1B87 mod =$1BC5 umod =$1BE0 or =$1C3E xor =$1C4A cand =$1C56 casr =$1C62 casl =$1C79 neg =$1C90 nz =$1C9E eq =$1CA5 ne =$1CB0 gt =$1CBB le =$1CC8 ge =$1CD5 lt =$1CE0 ugt =$1D04 ule =$1D11 uge =$1D1E ult =$1D29 escape =$1D48 _exit =$1D74 _open =$1D7D _creat =$1DB1 _close =$1DC8 _unlink =$1DD3 _stat =$1DE8 _system =$1DED __cmdlin =$1E01 _read =$1E2C _write =$1E44 _getc =$1EC3 _putc =$1EEB _vdu =$1F16 _osbyte =$1F1E _osword =$1F32 _osfile =$1F4D _isalpha =$1F83 _isupper =$1F93 _islower =$1FA3 _isdigit =$1FB3 _isxdigi =$1FC3 _isspace =$1FD3 _ispunct =$1FE3 _isalnum =$1FF3 _isprint =$2003 _iscntrl =$2013 _isascii =$2023 _toupper =$2031 _tolower =$2043 _toascii =$2055 _ctype_ =$205E _strcat =$20DE _strcmp =$2163 _strcpy =$21DA _strlen =$2230 _strncat =$227E _strncmp =$233D _strncpy =$23F0 _fclose =$24CC _fopen =$24DC _fgets =$25B3 _fputs =$2704 _gets =$27FB _puts =$28C0 _printf =$291C _fprintf =$2965 _sprintf =$29B4 __doprin =$29D3 _itoa =$31E0 _scanf =$33DB _fscanf =$341A _sscanf =$345F __doscan =$348A _atoi =$402E __cmdini =$415B __enter =$438A pr =$0070 sr =$0074 t Small-C v0.72 by A.J.Travis --------------------------- Installation Instructions by J.G.Harston ---------------------------------------- The programs supplied on this disk are all compiled to run Small-C from the current directory. They will need to be recompiled to run on your system. The following instructions may help you to install Small-C. 1: Ensure your distribution disk is write protected and copy it to your destination medium, such as to another floppy disk, to a hard drive or to a network server. Put the original in a safe place, and use the copy from now on. 2: Decide where the programs are going to go. The distribution disks are supplied in a recommended structure. With DFS there is little flexibility, and it is recommended you should use the supplied structure. With non-DFS systems, all the files are within $.Library.CLib. 3: If compiling on a DFS disk, you should remove the documentation in directory T to create enough space. 4: Edit the local/h file to specify what directories you are using. There are comments that give guidance and suggestions. 5: Load and enter the C shell by doing *exec loadsh 6: With the shell loaded and running, recompile the compiler programs for your system. With DFS, do: *dir :0.$ *exec mkdfs With all other systems, do: *dir $.Library.CLib.source *exec mkall This will take some time - about 30 to 40 minutes. 7: If you received no errors, then everything should be ready for use. Good Luck with your programming. Small-C©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª¢  ‹…ŽbŒc¢  ‹…ŽdŒe ²‚ ƒ ˆƒ¢  Û…ÐLL g¢ù Ž\Œ]¢ Ž^Œ_¢ Ž`Œa ·‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐL³¢ÿ  ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL@ ²‚ ƒ ˆƒ¢  Û…ÐLì gL= ·‚ ƒ ˆƒ¢  რ„ ƒŽ\Œ] ²‚ ˆƒ ·‚ ƒ ˆƒ¢  „ é‚ ·‚ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ é‚L°¢  ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL­¢ €Ž^Œ_¢ €Ž`Œa ²‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒL° gLj ²‚ ƒ ˆƒ¢  Û…ÐLË g¢  ˆƒ®\¬] ˆƒ ¬† ¸ƒŽdŒe ˆƒ¢  ‹…  …ÐL&®\¬] ˆƒ¢  ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ Œ »ƒ ²‚ ˆƒ ƒ 4ƒ é‚ ™…ÐL0¢  ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ x† ¸ƒŽbŒc ˆƒ¢  ‹…  …ÐL¸ ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ¢  ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ Œ »ƒ¢  ˆƒ¢\  ˆƒ®b¬c ˆƒ '‡ µƒŽfŒg ˆƒ¢  ¶…ÐL ®f¬g ˆƒ¢\  ˆƒ®d¬e ˆƒ ?‡ µƒL¸®b¬c ˆƒ Æ »ƒ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒL&®d¬e ˆƒ Æ »ƒ®`¬a ˆƒ®^¬_ ˆƒ®\¬] ˆƒ Þ µƒ¢ Lo†¢-  ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ Œ »ƒ`®b¬c ˆƒ¢  ¶…ÐL°®b¬c ˆƒ Æ »ƒ®d¬e ˆƒ¢  ¶…ÐLÔ®d¬e ˆƒ Æ »ƒ ²‚ ƒLo†`© ]ƒ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ¢  რ„ ˆƒ¢  é‚¢  ˆƒ ·‚ ˆƒ¢ Ò‚ ƒ ˆƒ Hˆ µƒ© Eƒ`a/out-o-Rld: can't create %s ld: can't open %s usage: ld [-o outfile] [-R] file1 ... [filen] ©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª¢  ‹…ŽbŒc¢  ‹…ŽdŒe ²‚ ƒ ˆƒ¢  Û…ÐLL g¢ù Ž\Œ]¢ Ž^Œ_¢ Ž`Œa ·‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐL³¢ÿ  ˆƒ ¼‚ *| Start C Shell *| Add rom number if needed: *| *srload () () (nitialise) (un) (

ause) */srload sh i *sh *| Start C Shell *| Add rom number if needed: *| *srload () () (nitialise) (un) (

ause) */srload s/* local.h - installation-dependant pathnames, etc. */ #ifndef __local_h #define __local_h /* Change the #defines in this file to specify where the Small-C compiler * system is installed. If the path "%" is available, pointing to the * library directory, then put the CLib directory in the library. If "%" * is not available, CLib should be put in the $ directory. */ /* as65 pathnames */ /* Suggested values: * DFS: * MNEMTAB ":0.$.mnemtab" * OPTAB ":0.$.optab" * If "%" is available: * MNEMTAB "%.CLib.mnemtab" * OPTAB "%.CLib.optab" * If "%" is not available * MNEMTAB ":.Library.CLib.mnemtab" * OPTAB ":.Library.CLib.optab" */ #define MNEMTAB "mnemtab" /* opcode mnemonics */ #define OPTAB "optab" /* opcode table */ /* tcc commands */ /* Suggested value: * DFS: * TCPP "tcpp" * TCCOM "tccom" * TCCOMC "tccom -C" * AS65 "as65 -o" * RM "rm -f" * LD "ld -o" * SWLD "ld -R -o" * If "%" is available: * TCPP "%.CLib.tcpp" * TCCOM "%.CLib.tccom" * TCCOMC "%.CLib.tccom -C" * AS65 "%.CLib.as65 -o" * RM "%.CLib.rm -f" * LD "%.CLib.ld -o" * SWLD "%.CLib.ld -R -o" * If "%" is not available * TCPP ":.Library.CLib.tcpp" * TCCOM ":.Library.CLib.tccom" * TCCOMC ":.Library.CLib.tccom -C" * AS65 ":.Library.CLib.as65 -o" * RM ":.Library.CLib.rm -f" * LD ":.Library.CLib.ld -o" * SWLD ":.Library.CLib.ld -R -o" */ #define TCPP "tcpp" #define TCCOM "tccom" #define TCCOMC "tccom -C" #define AS65 "as65 -o" #define RM "rm -f" #define LD "ld -o" #define SWLD "ld -R -o" /* tcc pathnames */ /* Suggested values: * DFS: * EXT ":0.$.ext/s :0.$.enter/s" * CRT ":0.$.crt" * SWEXT ":0.$.swext/s :0.$.enter/s" * SWCRT ":0.$.swcrt" * SCEXT ":0.$.swext/s :0.$.start/s" * COMP "compile" * EXEC "*exec compile" * If "%" is available: * EXT "%.CLib.ext/s %.CLib.enter/s" * CRT "%.CLib.crt" * SWEXT "%.CLib.swext/s %.CLib.enter/s" * SWCRT "%.CLib.swcrt" * SCEXT "%.CLib.swext/s %.CLib.start/s" * COMP "compile" * EXEC "*exec compile" * If "%" is not available: * EXT ":.Library.CLib.ext/s :.Library.CLib.enter/s" * CRT ":.Library.CLib.crt" * SWEXT ":.Library.CLib.swext/s :.Library.CLib.enter/s" * SWCRT ":.Library.CLib.swcrt" * SCEXT ":.Library.CLib.swext/s :.Library.CLib.start/s" * COMP "compile" * EXEC "*exec compile" */ #define EXT "ext/s enter/s" #define CRT "crt" #define SWEXT "swext/s enter/s" #define SWCRT "swcrt" #define SCEXT "swext/s start/s" #define COMP "compile" #define EXEC "*exec compile" /* tcpp pathnames */ /* Suggested values: * DFS: * INCLUDE ":0." * If "%" is available: * INCLUDE "%.CLib." * If "%" is not available * INCLUDE ":.Library.CLib." */ #define INCLUDE "" #endif /* local.h - installation-dependant pathnames, etc. */ #ifndef __local_h #define __local_h /* Change the #defines in this file to specify where the Small-C compiler * system is Small-C 'C' Compiler Tools -------------------------- Release 0.7 ----------- A.J.Travis 01-May-89 -------------------- -------------------------------------------------------------------------------- INDEX as65 cmp crt ctype demo diff errors get, put install ld lib lpr makefile [mktcc] rm sfa sh shar stdio sys tcc tccom tcpp unpack -------------------------------------------------------------------------------- NAME as65 SYNOPSIS as65 [-l] [-o outfile] file1 ... [filen] DESCRIPTION Assembler for the 6502 processor. This is a two pass assembler that processes the concatenation of source files given as command-line arguments. Local symbols are prefixed by tilde '~' and are not written to the global symbol output file. Mnemonics are lower-case, and are reserved symbols. Underline '_' is accepted as an alpha character in symbols. Assembly language routines may be called from Small-C programs, provided the Small-C parameter passing conventions are observed. In this implementation, parameters are always promoted to 16-bits with sign extension to the left and pushed on the data stack in 'reverse' order. In addition, the compiler prepends an underline '_' to the name of the Small-C function used to call the assembly language routine. The external symbols referring to code in the run-time support module, and BBC MOS are passed to the assembler by means of equate directives in the external symbol file 'ext/s' or 'swext/s'. If the Small-C 'end' symbols ~eot (end of text) and ~eod (end of data) are present, the size of the text and data segments are printed in decimal, followed by the assembly origin, ~eot, and ~eod values in hex. The assembler follows MOS Technology/Rockwell conventions. Consult the manufacturer's 6502 assembly language reference manual for more details. Options: -l produce assembly language listing -o name specify name of output file Note: The assembler can be used without an "optab" file in order to generate "optab" itself from .BYTE assembler pseudo-ops. In this situation a warning is issued, but the assembly continues. BUGS JMP expects a 16-bit destination, and JMP's into page zero are wrongly flagged as errors. This arises when the assembler origin is not set. Optab is needed because there is no simple way of initialising static data in the current version of tcc. Mnemtab is needed to pre-hash the mnemonics into the symbol table. FILES as65.c optab/s source code to generate optab :0.$.optab 6502 opcode table :0.$.mnemtab 6502 mnemonics o/out default output file g/out global symbol file -------------------------------------------------------------------------------- NAME cmp SYNOPSIS cmp file1 file2 DESCRIPTION Simple byte by byte file comparison. FILES cmp.c -------------------------------------------------------------------------------- NAME crt SYNOPSIS Stand-alone Small-C run-time support DESCRIPTION Large programs such as the compiler "tccom" require the Small-C language ROM/RAM image to be present, but smaller programs can be made 'stand-alone' using the -A option of "tcc". This loads the run-time support and compiler library in the default text area at $1900 in the i/o processor memory area, the usual MOS high water mark with just DFS fitted. The default load address is set to $1902 in order to avoid error messages from the BASIC language ROM which initialises the first two bytes of this area. BUGS The entire run-time support is loaded, even though a large part of it may never be referenced by the user program. A link editor is required. FILES mkcrt *exec file to assemble crt oshdr/s MOS entry points, and Small-C workspace definitions crt0/s stand-alone start-up code crt1/s JSR threaded code interpreter sys/s operating system interface lib/s part of the 'standard' C library patch/s control flow patch ext/s external symbol file used to link user programs enter/s entry point patch for user program -------------------------------------------------------------------------------- NAME ctype SYNOPSIS #include DESCRIPTION This is a dummy file in release 0.7 - the character classification table is defined in sys/s, and character classification routines are written in assembly language. BUGS Should be done with pre-processor macros ... FILES :0.$.ctype.h sys/s -------------------------------------------------------------------------------- NAME demo SYNOPSIS tcc -o bm bm/c tcc -o fahr fahr/c tcc -o hanoi hanoi/c tcc -o plot plot/c tcc -o sieve sieve/c DESCRIPTION Small-C demonstration programs: bm PCW Benchmarks fahr K & R tutorial example hanoi Towers of Hanoi (uses VDU mode 2) plot Recursive squares (uses VDU mode 2) sieve Sieve of Eratosthenes FILES :2.bm/c :2.fahr/c :2.hanoi/c :2.plot/c :2.sieve/c -------------------------------------------------------------------------------- NAME diff SYNOPSIS diff file1 file2 DESCRIPTION Line by line file comparison. BUGS Not really diff (as in Unix), but still useful. FILES diff.c -------------------------------------------------------------------------------- NAME errors SYNOPSIS Compiler error codes DESCRIPTION Brief explanation of compiler error codes. These have been deleted from the compiler to save space. BUGS There are errors in the errors ... FILES :0.$.errors list of error codes tccom.c source shows where errors are detected -------------------------------------------------------------------------------- NAME get, put SYNOPSIS *kermit take get *kermit take put DESCRIPTION Kermit 'take' files to download/upload "tcc" system from MSDOS host. Get "get" onto the BBC Micro first, then download the rest of the files automatically using the Kermit take command. The take files assume that the MSDOS kermit is in server mode, and the BBC Micro kermit is the 'local' kermit. BUGS DFS/ADFS attributes need to be set using "install" FILES get Kermit takefile install *exec file to set file attributes -------------------------------------------------------------------------------- NAME getshar SYNOPSIS *kermit take getshar DESCRIPTION Kermit 'take' file to download "tcc" system from remote host. Get "getshar" onto the BBC Micro first, then download the rest of the files automatically using the Kermit take command. The take files assume that the MSDOS kermit is in server mode, and the BBC Micro kermit is the 'local' kermit. The shell archives are unpacked using the "unpack" command. BUGS "getshar" assumes that two disk drives are available. FILES getshar Kermit takefile unpack *exec file to unpack shell archives -------------------------------------------------------------------------------- NAME install SYNOPSIS exec install DESCRIPTION Utility to set file attributes after downloading binaries with Kermit from MSDOS host. BUGS Language ROM/RAM image must already be loaded. FILES sfa executable binary of utility to set file attributes swcrt Language ROM/RAM image -------------------------------------------------------------------------------- NAME ld SYNOPSIS ld [-o outfile] [-R] file1 ... [filen] DESCRIPTION Simple loader for stand-alone binaries, and ROM images of Small-C programs. No link editing is done: the loader simply concatenates the binaries given as arguments with the appropriate run-time support. All external references are resolved by the assembler, using the external symbol file "ext/s" or "swext/s". Options: -o outfile specify name of output file -R load sideways ROM/RAM image BUGS The order of files in the argument list is critical, and relocation is impossible because the assembler produces absolute binary modules. FILES a/out default output file crt stand-alone run-time support swcrt sideways ROM/RAM run-time support -------------------------------------------------------------------------------- NAME lib SYNOPSIS tcc -S lib.c exec mkcrt exec mkswcrt DESCRIPTION Small-C compiler library. A few of the 'standard' C library routines have been implemented: atoi(s) fclose(fp) fgets(s, n, fp) fopen(name, mode) fprintf(fp, fmt, arg) fputs(s, fp) fscanf(fp, fmt, arg) gets(s) itoa(s, radix) printf(fmt, arg) puts(s) scanf(fmt, arg) sscanf(s, fmt, arg) sprintf(s, fmt, arg) strcat(s1, s2) strcmp(s1, s2) strcpy(s1, s2) strlen(s) strncat(s1, s2, n) strncmp(s1, s2, n) strncpy(s1, s2, n) BUGS There are lots more functions to implement ... FILES lib/c Small-C source lib/s assembly language file used to create "crt" and "swcrt" -------------------------------------------------------------------------------- NAME lpr SYNOPSIS lpr [-p] file DESCRIPTION Expands tabs into spaces (for printers that can't handle tabs), and paginates output if required. Output is directed to the screen and printer simultaneously using the MOS VDU driver to enable the printer. Options: -p paginate output, and print header at top of page. BUGS It's not a spooler - you have to wait until the printer stops. FILES lpr.c -------------------------------------------------------------------------------- NAME makefile [mktcc] SYNOPSIS make host make DESCRIPTION Zorland 'C' makefile for the MSDOS version of the "tcc" compiler. The "host" target generates *.exe files for the MSDOS host system, and the default target generates 6502 binaries to be downloaded onto a BBC Micro using Kermit. BUGS There is no Small-C make utility. FILES makefile -------------------------------------------------------------------------------- NAME rm SYNOPSIS rm [-f] file1 [... filen] DESCRIPTION Remove the list of files given as arguments. Options: -f force removal, even if file is locked, and don't complain about non-existent files BUGS Wild cards are not expanded. FILES rm.c -------------------------------------------------------------------------------- NAME sfa SYNOPSIS sfa file DESCRIPTION Set file attributes. The load and execute addresses are both set to $1902. BUGS Can't specify load and exec addresses as arguments. The file access attributes are correct for ADFS, but set the "lock" attribute in DFS. FILES sfa.c -------------------------------------------------------------------------------- NAME sh SYNOPSIS *sh DESCRIPTION Small-C command "shell". This is the Small-C Language ROM/RAM image that must be present in order to use the "tcc" compiler. The *sh entry into the Small-C Language ROM/RAM allows control to fall through to code immediately after the run-time support. This entry is patched to main() in the command shell by the -R option of "tcc": tcc -o sh -R sh/c The '*' in "*sh" is used by Basic to pass a command line to the MOS OSCLI (operating system command line interpreter). This is necessary when invoking Small-C from Basic or View, but is not required when programs or operating system commands are invoked from the Small-C command shell. The shell implements a 'mode' command to change mode. Shadow screen modes are always selected if possible. Additionally, if a command if prefixed by '*' then the 'C' escape handler is temporarily disabled for the execution of the command. This is the correct way to exit the shell - use, for example, '*basic' or '*word', not 'basic' or 'word'. On return to the shell any return value is osbyte 1 set by an executed command is displayed. BUGS Global variables should not be used in programs produced with the -R option because the compiler places data immediately after the program text in what would then be read-only memory. FILES swcrt Sideways ROM/RAM run-time support sh.c Small-C command shell -------------------------------------------------------------------------------- NAME shar SYNOPSIS shar [-a] [-x] archive file1 [... filen] DESCRIPTION Unix style shell archiver for e-mail distribution of tcc system. The "archive" argument specifies the name of the archive file to be used. Note: only text files can be archived with shar. Options: -a create archive and add files -x extract file from archive BUGS Individual files cannot be extracted from an archive. The entire contents of an archive are extracted. FILES shar.c -------------------------------------------------------------------------------- NAME stdio SYNOPSIS #include DESCRIPTION 'Standard' i/o header file. Contains standard i/o channel definitions, and the macro definitions of putchar() and getchar(). #define BUFSIZ 256 /* size of disk i/o buffer */ #define NULL 0 /* null pointer of any type */ #define EOF (-1) /* end-of-file 'value' */ #define stdin 0 /* standard (console) input stream */ #define stdout 1 /* standard (console) output stream */ #define stderr 2 /* standard (console) error stream */ #define FILE int /* no structures in Small-C ... */ #define unsigned char * /* no unsigned type in Small-C ... */ #define getchar() getc(stdin) #define putchar(x) putc(x, stdout) BUGS The FILE typedef cannot be implemented properly in Small-C, but the i/o streams are used as if they are implemented as (FILE *) to make Small-C a legal subset of full 'C'. This is ok if no reference is made to the FILE structure other than its use to identify a stream in the 'f' i/o library (eg. fprintf()). FILES :0.$.stdio/h -------------------------------------------------------------------------------- NAME sys SYNOPSIS Operating system interface DESCRIPTION The interface between Small-C and the underlying BBC Micro Machine Operating System (MOS) is written in assembly language. The entry points for low-level file i/o are modelled on their Unix counterparts, and the character classification routines are written in assembly language to increase their speed of execution. Interfaces are also provided to the MOS osbyte 'fx' (effects), osword and osfile calls. Entry points: Assembler Small_C _open fd = open(name, rwmode); _creat fd = creat(name, pmode); _close status = close(fd); _unlink status = unlink(name); _stat stat(name, fcb); _system system(string); __cmdlin address = _cmdline() _read nread = read(fd, buf, count); _write nwritten = write(fd, buf, count); _getc c = getc(fp); _putc putc(c, fp); _vdu vdu(c); _osbyte osbyte(type, parameters); _osword osword(type, address); _osfile osfile(name, fcb, type); _isalpha t = isalpha(c); _isupper t = isupper(c); _islower t = islower(c); _isdigit t = isdigit(c); _isxdigi t = isxdigit(c); _isspace t = isspace(c); _ispunct t = ispunct(c); _isalnum t = isalnum(c); _isprint t = isprint(c); _iscntrl t = iscntrl(c); _isascii t = isascii(c); _toupper c2 = toupper(c1); _tolower c2 = tolower(c1); _toascii c2 = toascii(c1); _ctype_ char ctype_[127]; BUGS File descriptors (fd) are used instead of (FILE *) for getc(), and putc() as in the rest of Small-C. Pmode is ignored by creat(), and the system has no record of which files were opened by the user. This means that programs must explicitly close files that they open (full 'C' will normally close files opened by the user on exit). The character classification routines should be macros that use conditional expressions. "System" doesn't spawn a new process, it just passes the line to the MOS command line interpreter (CLI). FILES sys/s ext/s stand-alone entry points swext/s sideways ROM/RAM entry points -------------------------------------------------------------------------------- NAME tcc SYNOPSIS tcc [-o outfile] [-n] [-E] [-S] [-c] [-g] [-R] [-A] [-C] file DESCRIPTION This is the Small-C compilation sequencer. It arranges the various phases of the preprocessor "tcpp", compiler "tccom", assembler "as65" and loader "ld" according to a list of command-line arguments. The sequencer generates a *exec file on the BBC, or a *.bat file in the MSDOS version, which is then executed to carry out the compilation. By default, the compiler produces ROM-dependant code which makes external references into the Small-C language ROM. Options: -o outfile specify name of output file (default a/out) -n don't execute *exec (*.bat) file -E run preprocessor only (no compilation) -S generate an assembly language output file -c suppress load phase -g keep the global symbol output file "g/out" -R produce ROMable code -A produce 'stand-alone' code -C insert 'C' source as comments BUGS The technique of generating a *exec file is a crude alternative to the creation of child processes to carry out the compilation tasks. This could be done in the MSDOS version, but requires much more effort under the Acorn MOS. For simplicity, I have used the same technique in both. Only one source file can be processed in this version, but the #include preprocessor directive can be used to combine several *.c files. FILES tcc/c tcpp Small-C preprocessor tccom Small-C compiler as65 6502 assembler rm file remover ld Small-C loader :0.$.crt Stand-alone run-time support, and compiler library :0.$.swcrt Sideways ROM/RAM run-time support, and compiler library :0.$.ext/s Stand-alone external references :0.$.swext/s Sideways ROM/RAM external references :0.$.start/s ROM-dependant startup code :0.$.enter/s Control-flow patch to main() from user entry point compile *exec file produced by sequencer -------------------------------------------------------------------------------- NAME tccom SYNOPSIS tccom [-C] infile [outfile] DESCRIPTION Tiny 'C' compiler for the MOS Technology 6502 microprocessor, based on "RatC", Berry and Meeking's version of the original Small-C compiler for the Intel 8080 by Ron Cain. The main difference between RatC and Ron Cain's Small-C is the use of a generic processor model with two working registers instead of 8080 architecture. Otherwise, the two compilers are almost identical. The compiler (tccom) is normally invoked by a compilation sequencer (tcc), which arranges the various phases of the pre-processor, compiler, assembler amd loader. The language features supported by "tccom" are essentially the same as those supported by "RatC", with more complete flow-control, and character escape sequences implemented. Code generation is 'optimised' for the 6502 in a 'small' machine environment on the BBC Micro. The basic strategy is to generate code for a JSR threaded code interpreter, but whenever possible the contents of the 'C' primary register are kept in the 6502 X and Y registers. Two stacks are used: the 6502 hardware stack is used as the 'C' return stack and is used by the JSR threaded code interpreter, but the 'C' data stack is implemented in high memory using page-zero locations as a stack pointer. This allows 'C' function stack-frames to be realistically large (the 6502 hardware stack is limited to 256 bytes in page 1). As with other implementations of Small-C, the language features supported are a (severely) restricted subset of full 'C' but I have made an effort to implement a legal subset that can be compiled with little or no modification by a full 'C' compiler. Consult the "Small-C Handbook" by James.E.Hendrix for a more complete description of the language. Briefly, the features implemented in "tcc" are: Options: -C output source code as assembler comments Types: char 8-bit (signed) promoted to int in expressions char[n] 8-bit (signed) promoted to int in expressions char * 16-bit (unsigned) int 16-bit (signed) int[n] 16-bit (signed) int * 16-bit (unsigned) extern accepted, but ignored by compiler int function() int *function() char function() char *function() Operators: = assignment (low precedence) | bitwise OR ^ bitwise XOR & bitwise AND == relational equal != relational not equal <= relational less-than or equal >= relational greater-than or equal >> bitwise right shift << bitwise left shift + arithmetic add - arithmetic subtract * arithmetic multiply / arithmetic divide (integer) % arithmetic remainder (integer) - arithmetic negation * pointer indirection & address of object ++ arithmetic increment -- arithmetic decrement f() function call a[] array subscript (high precedence) Function calls: direct: function(args); indirect: char *address; address = &function; address(args); Control-flow: goto label ... label: if (expression) { ... } else { ... } while (expression) { ... } do { ... } while (expression); for (expression; expression; expression) { ... } Literal numbers: ddddd decimal (where d is 0...9) 0ddd octal (where d is 0...7) 0xdddd hexadecimal (where d is 0...F or 0...f) Character escapes: \n newline \t tab \b backspace \r return \f form feed \\ backslash \0 NULL \ddd octal character code \c any other character (where c is the character) BUGS Arrays of character pointers are (incorrectly) treated as arrays of integers. This leads to problems recovering command line options prefixed by '-'. The fix is to AND with 0xFF, and various programs are commented "BUG in compiler" where this is a problem. The code to implement "for" fails on the commonly used construct "for (;;)" which is used in 'endless' loops, and the code generated to implement "for" needs the entire expression on one line of the input stream. The same is true for function calls, where the entire argument list must be on one line. The analysis of the "for" construct is clumsy, and needs re-writing to jump round the end loop action, rather than deferring code generation which is used at present. The "switch" construct has not yet been implemented. FILES tccom.c -------------------------------------------------------------------------------- NAME tcpp SYNOPSIS tcpp [-Dname] infile outfile DESCRIPTION Small-C preprocessor, with file inclusion and conditional compilation directives. The #asm ... #endasm directive found on other Small-C preprocessors is deliberately omitted because it leads to non-portable code. Assembly language routines are incorporated in Small-C programs by combining them with the assembler source generated by the compiler, during assembly of the program. This allows machine dependencies to be hidden from an applications program. The preprocessor implements a subset of the Unix 'C' preprocessor "cpp": File inclusion: #include file in 'standard' directory #include "file" file in current directory Macro replacement: #define name #define name(args) Conditional text inclusion: #if constant test for non-zero constant ... #else ... #endif #ifdef name test for defined macro name ... #else ... #endif #ifndef name test for undefined macro name ... #else ... #endif Options: -Dname #define name on command line BUGS Constant expressions cannot be used (as in #if expression), and the newline escape '\' is not implemented in macro definitions which must, therefore, be confined to a single line of text. FILES tcpp/c :0.$ 'standard' directory for #include :0.$.stdio/h 'standard' i/o #include file :0.$.ctype/h dummy character classification #include file -------------------------------------------------------------------------------- NAME unpack SYNOPSIS exec unpack DESCRIPTION The BBC Micro version of tcc is distributed over e-mail or BBSs as a collection of Unix 'shell' archives. This is a convenient format for packaging up several files, and protecting them from e-mail systems that occasionally interpret parts of unprotected files as message headers. This may cause the file to be corrupted, or it may fail to arrive. The archive files should be downloaded onto a BBC Micro as indicated in the FILES section below. An example kermit take file is provided, or the files can be downloaded individually. The unpack utility assumes that you have a two-drive system. The 6502 binaries of the Small-C Language ROM and "shar" program must first be de-hexed and the "sh" file loaded into sideways RAM. The unpack script uses the "shar" program to extract the other hexfiles from tcc1 and tcc2. These are dehexed, and the remaining source files are extracted. The resulting disk contains the complete tcc source distribution. Make a copy of the disk before attempting to use the compiler, and delete some of the source files to make room for temporary files created by the compiler. BUGS It takes a l o n g time to extract the files. FILES :0.getshar kermit take file to download shell archives :0.mkboot *exec file to dehex Small-C boot files :0.sh/x 6502 hex file of Small-C Language ROM/RAM image :0.dehex/x 6502 hex file of Intel hex decoder :0.shar/x 6502 hex file of shell archive program :1.unpack *exec file to unpack archives :1.tcc1 shell archive #1 :1.tcc2 shell archive #2 :3.tcc3 shell archive #3 :3.tcc4 shell archive #4 :2.READ/ME tcc documentation -------------------------------------------------------------------------------- Small-C 'C' Compiler Tools -------------------------- Release 0.7 ----------- A.J.Travis 01-May-89 -------------------- -------------------------| > mkall | Recompile all compiler programs | Start in source directory | | Select small memory screen mode mode 7 | Set library Lib ^ | Compile programs tcc -o Nas65 as65/c tcc -o Ntcc tcc/c tcc -o Ntcpp tcpp/c | Tidy up delete compile | Delete old programs access ^.tcpp delete ^.tcpp access ^.tcc delete ^.tcc access ^.as65 delete ^.as65 | Rename newly compiled programs rename Nas65 ^.as65 rename Ntcc ^.tcc rename Ntcpp ^.tcpp | Reset library Lib $.Library | Put a copy of tcc in the system library | non-ADFS syntax: copy ^.tcc $.Library.tcc | ADFS syntax: copy ^.tcc $.Library | All done. | > mkall | Recompile all compiler programs | Start in source directory | | Select small memory screen mode mode 7 | Set library Lib ^ | Compile programs tcc -o Nas| Recompile compiler programs on DFS disk | Start in :0.$ directory | | Select small memory screen mode mode 7 | Compile programs tcc -o Ntcpp :2.tcpp/c tcc -o Ntcc :2.tcc/c tcc -o Nas65 :2.as65/c | Tidy up delete compile | Delete old programs access tcpp delete tcpp access tcc delete tcc access as65 delete as65 | Rename newly compiled programs access Ntcc rename Ntcc tcc access Ntcpp rename Ntcpp tcpp access Nas65 rename Nas65 as65 | All done. | Recompile compiler programs on DFS disk | Start in :0.$ direadc and asl bcc bcs beq bit bmi bne bpl brk bvc bvs clc cld cli clv cmp cpx cpy dec dex dey eor inc inx iny jmp jsr lda ldx ldy lsr nop ora pha php pla plp rol ror rti rts sbc sec sed sei sta stx sty tax tay tsx txa txs tya adc and asl bcc bcs beq bit bmi ÿÿieuÿm}yaqÿÿÿÿ)%5ÿ-=9!1ÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ°ÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿ$ÿÿ,ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0ÿÿÿÿÿÿÿÿÿÿÿÿÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿPÿÿÿÿÿÿÿÿÿÿÿÿpÿÿÿÿÿÿÿÿÿÿÿÿÿØÿÿÿÿÿÿÿÿÿÿÿÿXÿÿÿÿÿÿÿÿÿÿÿÿ¸ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÅÕÿÍÝÙÁÑÿÿÿÿàäÿÿìÿÿÿÿÿÿÿÿÀÄÿÿÌÿÿÿÿÿÿÿÿÿÆÖÿÎÞÿÿÿÿÿÊÿÿÿÿÿÿÿÿÿÿÿÿˆÿÿÿÿÿÿÿÿÿÿÿÿÿÿIEUÿM]YAQÿÿÿÿÿæöÿîþÿÿÿÿÿèÿÿÿÿÿÿÿÿÿÿÿÿÈÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿLÿÿÿÿÿlÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿ©¥µÿ­½¹¡±ÿÿÿÿ¢¦ÿ¶®ÿ¾ÿÿÿÿÿÿ ¤´ÿ¬¼ÿÿÿÿÿÿJÿFVÿN^ÿÿÿÿÿêÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿ ÿÿHÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿhÿÿÿÿÿÿÿÿÿÿÿÿ(ÿÿÿÿÿÿÿÿÿÿÿÿÿ*ÿ&6ÿ.>ÿÿÿÿÿÿjÿfvÿn~ÿÿÿÿÿ@ÿÿÿÿÿÿÿÿÿÿÿÿ`ÿÿÿÿÿÿÿÿÿÿÿÿÿÿéåõÿíýùáñÿÿ8ÿÿÿÿÿÿÿÿÿÿÿÿøÿÿÿÿÿÿÿÿÿÿÿÿxÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ…•ÿ™‘ÿÿÿÿÿ†ÿ–Žÿÿÿÿÿÿÿÿÿ„”ÿŒÿÿÿÿÿÿªÿÿÿÿÿÿÿÿÿÿÿÿ¨ÿÿÿÿÿÿÿÿÿÿÿÿºÿÿÿÿÿÿÿÿÿÿÿÿŠÿÿÿÿÿÿÿÿÿÿÿÿšÿÿÿÿÿÿÿÿÿÿÿÿ˜ÿÿÿÿÿÿÿÿÿÿÿÿÿÿieuÿm}yaqÿÿÿÿ)%5ÿ-=9!1ÿÿÿ ÿÿÿÿÿÿÿÿ Small-C compiler for the BBC Micro Release 0.71 A.J.Travis 01-May-89 INTRODUCTION Small-C is a subset of the C programming language for which a number of public-domain compilers have been written. The original compiler was written by Ron Cain and appeared in the May 1980 issue of Dr.Dobb's Journal. More recently, James E.Hendrix has improved and extended the original Small-C compiler and published "The Small-C Handbook", ISBN 0-8359-7012-4 (1984). Both compilers produce 8080 assembly language, which is the most popular implementation of Small-C to-date. My 6502 Small-C compiler for the BBC Micro is based on "RatC", a version of the original Ron Cain compiler described by R.E.Berry and B.A.Meekings in "A Book on C", ISBN 0-333-36821-5 (1984). The 6502 compiler is written in Small-C and was bootstrapped using Zorland C on an Amstrad PC1512 under MSDOS 3.2, then transferred onto a BBC Micro using Kermit. The compiler can be used to cross-compile 6502 code from an MSDOS host, or as a 'resident' Small-C compiler on a BBC Micro. DEVELOPMENT I started to implement a Small-C compiler for the BBC Micro in 1985 because I wanted an alternative to assembly language or Forth for writing 6502 image processing software. I was very impressed by the performance and portability of Forth, but found the language difficult to use. I was aware that a sub-set of Pascal had been implemented in Forth, and I set about developing my own version. However, I quickly realised that the virtues of using a threaded-code interpreted language (TIL) could be exploited just as easily by generating code for an interpreter conventionally, instead of using Forth itself to generate a 'target' vocabulary. I began to use 'C' and Unix on a DEC pdp11 at the time and I decided to implement a sub-set of C, instead of Pascal, on the BBC Micro after reading "The Small-C Handbook" by Hendrix and "A Book on C" by Berry and Meekings. I began by implementing "Rat-C" under Unix on the pdp11. The Rat-C compiler is much smaller than the Hendrix compiler, and it also produces 'generic' assembly code. I wrote a translator for the generic code output by RatC, which generated 'JSR-threaded' code for the 6502. A JSR-threaded code interpreter is a form of TIL that uses the hardware call-return mechanism of the processor as the low-level interpreter and is the most efficient way of implimenting a TIL. The code generated was too verbose to produce a resident Small-C on the BBC Micro with only 29K of usable memory in mode 7, but I was able to develop the run-time support for the threaded-code interpreter and code generation model for the 6502. Because of the severe memory constraints of a 'standard' BBC Micro, I decided to translate Rat-C into BBC BASIC in order to produce a resident Small-C compiler that would run in 29K. This 'tiny' C compiler ("tcc") in BBC BASIC was intended to be a 'bootstrap' for a Small-C version of the 6502 compiler, and I began distributing copies of the Small-C to friends and colleagues. Eventually, I sent a copy of the compiler to Chris Adie at Edinburgh University Micro Support Unit, and later to Alan Philips at the Lancaster University Micros Software Distribution Service. After several more releases of the "tcc" compiler, I was approached by John Evans of Mijas software for permission to sell the Small-C as part of his 6502 assembly language development system. I was pleased to give Mijas permission to use my code, which they have adapted for use with the Mijas 6502 symbolic debugger. I continued to develop the 6502 Small-C by optimising the code-generator for the 'small-machine' environment of the BBC Micro and, during this development, I replaced my earlier BBC BASIC programs with Small-C versions. Finally, I have produced a resident Small-C for the BBC Micro that can also be used as a cross compiler for the 6502 on an MSDOS host. RELEASES 0.10 Jan-1986 Original version 0.20 Apr-1986 Limited distribution 0.30 Jul-1986 Sent to Chris Adie at ERCC 0.40 Oct-1986 First version sent to 0.41 Oct-1986 Bug-fix release 0.50 Dec-1986 First version used by Mijas 0.51 Apr-1987 Limited distribution 0.60 Jul-1988 First DOS cross-compiler 0.61 Dec-1988 BBC Micro/Master language ROM 0.70 Apr-1989 Current release 0.71 Jul-1990 Bug in shell ROM fixed 0.72 Jun-2005 String buffer increased in printf() family CHANGES FROM RELEASE 0.5 Release 0.6 of the 6502 Small-C compiler was cross-compiled on an MSDOS host and has been modified to avoid major incompatibilities with full 'C'. Previous BASIC programs, including the compiler itself, have been re-written in Small-C. The Zorland C compiler objects to many of the 'liberties' I have taken with full 'C' usage, but compiles the Small-C programs correctly. An MSDOS distribution is also available containing executable binaries of the Small-C compiler and 6502 assembler. Release 0.61 was a bug-fix release with corrected sideways ROM startup code and corrections to the "shar" program for extracting shell archives. The formatted input functions atoi(), scanf(), fscanf() and sscanf() have been added to the compiler library in this release, and I have fixed a bug in "as65" which failed to detect certain illegal expressions in opcode operands. The Small-C release 0.70 language ROM works correctly on a BBC Master, and several minor bugs have been fixed in the run-time library. Version 0.70 is the first version in which the Small-C command shell is used to compile and run C programs. I have also adopted lower-case mnemonics for the 6502 assembler, and extended the range of pre-processor directives supported by "tcpp". ACKNOWLEDGEMENTS I am grateful to Jon Welch, and Dave Prosser from the Department of Electronic Engineering at Bradford University who weeded out many of the bugs in release 0.41 of the compiler. I am also grateful to Alan Philips at Lancaster University, and Rob McRon at Edinburgh University for their help in distributing the compiler over electronic mail networks. A version of this compiler is distributed, with my permission, by Mijas Software as part of a 6502 assembly language development system for the BBC Micro. I would like to thank John Evans of Mijas for his interest in the compiler which he has extended and adapted for use with the Mijas 6502 symbolic debugger. COPYRIGHT The programs in this distribution remain copyright (c) 1989 A.J.Travis, and should not be used for any commercial purpose without prior consent in writing. The programs may be copied and further distributed for non-commercial use without restriction, provided a copy of this notice is also included. REQUIREMENTS The "tcc" Small-C compiler requires a 'standard' BBC Micro or BBC Master and a twin double sided 80-track disk drive in order to recompile itself. The run-time support routines and compiler library are contained in a Small-C language ROM/RAM image that must be present in order to use the compiler, but stand-alone versions of programs are readily produced using a compiler option. Source programs are edited using Acornsoft VIEW or a similar editor, and any machine code monitor/debugger can be used on the object programs produced. INSTALLATION The following installation instructions are superceed by those in the file Install. They have been kept within the documentation as part of the original distribution. [JGH] ------------------------------------------------------------------------ AVAILABILITY Send an SAE and Acorn DFS formatted, double-sided 80 track 5.25" floppy (or 360K DOS formatted, 5.25" floppy for the MSDOS version). Alternatively, mail me as for an e-mail version. Home address: Work address: 1 St. Nathalan Crescent, Rowett Research Institute, Banchory, Greenburn Road, Kincardineshire. Bucksburn, AB3 3YU Aberdeen. AB2 9SB tel. Banchory 2392 tel. Aberdeen 712751 x134 DOWNLOADING SHELL ARCHIVES Several people have reported difficulty in downloading the BBC Micro Small-C as Unix 'shell' archives. These are simply a convenient way of distributing programs over e-mail networks and BBSs. The "unpack" utility is intended to simplify the task of unpacking the archives after downloading them onto BBC Micro disks. Two blank formatted 80-track disks are required to download and unpack the archives. First, download the kermit takefile "getshar" onto drive 0: and use it to download the shell archives: > ; BASIC prompt > *xoff ; disable ARIES B32 shadow RAM > ; press break key > *rload kermit 13 ; load kermit ROM image in slot 13 > ; initialise ROM > *kermit ; invoke kermit BBC> ; kermit prompt BBC> set file type ascii cr ; setup for ascii transfer BBC> get getshar getshar ; transfer kermit take file "getshar" BBC> take getshar ; transfer shell archives BBC> *basic ; return to BASIC > ; BASIC prompt UNPACKING SHELL ARCHIVES After downloading the shell archives, the Small-C ROM must be bootstrapped, and the compiler programs must be 'unpacked' before they can be used: > ; BASIC prompt > *exec mkboot ; dehex Small-C ROM, and utils > *rload sh 14 ; load Small-C ROM image in slot 14 > ; initialise ROM > *sh ; invoke tcc command shell $ ; Small-C prompt $ exec :1.unpack ; unpack shell archives $ access *.* L ; lock all files for safety DOWNLOADING TCC FROM AN IBM-PC HOST The MSDOS version of the compiler is distributed via e-mail as 'boo' encoded archives which must be downloaded onto an IBM-PC or compatible micro. The files are then unpacked using the 'deboo' and 'arc' utilities (available from Lancaster PDSoft distribution service). The MSDOS version of the compiler can then be used to cross-compile code for a BBC Micro. The DFS version of the compiler was cross-compiled on an Amstrad PC-1512, then transferred to a BBC Micro fitted with an Aries B32 RAM board using the following commands: > ; BASIC prompt > *xoff ; disable ARIES B32 shadow RAM > ; press break key > *rload kermit 13 ; load kermit ROM image in slot 13 > ; initialise ROM > *kermit ; invoke kermit BBC> ; kermit prompt BBC> set file type ascii cr ; setup for ascii transfer BBC> get get get ; transfer kermit take file "get" BBC> take get ; transfer tcc files BBC> *basic ; return to BASIC > ; BASIC prompt DFS INSTALLATION After downloading a copy of the DFS distribution disk from an MSDOS host, the compiler programs must be 'installed' before they can be used: > ; BASIC prompt > *rload sh 14 ; load Small-C ROM image in slot 14 > ; initialise ROM > *sh ; invoke tcc command shell $ ; Small-C prompt $ mode 7 ; set vdu mode 7 $ exec install ; set executable file attributes $ access *.* L ; lock all files for safety INITIAL SETUP The system is distributed in DFS format, for use on a 'standard' BBC Micro, but can be used under ADFS without modification. Source programs are edited (using VIEW or whatever editor you have), and saved to disk. The restricted number of files in the DFS catalogue means that sources are normally saved in ":2.*/c", and the distributed sources can be found on side 2 of the disk. The distribution disk is FULL, and needs to be reorganised in order to use the compiler. Side 0 of the disk contains the executable binaries, #include and Small-C language ROM/RAM image. These files must always be present in drive 0. The files on side 2 must be copied to other disks in order to recompile the programs. The compiler program "tccom", in particular, needs a disk to itself in order to recompile ... Error recovery is virtually non-existent, and DFS "can't extend" problems should be avoided by periodically *compacting the disks. EXAMPLE PROGRAM The "Towers of Hanoi" example can be compiled using the distribution disk in BBC drive 1/3, and a blank formatted working disk in drive 0/2 as follows: > ; BASIC prompt > *drive 0 ; select drive 0 on distrib. disk > *xoff ; disable ARIES B32 shadow RAM > *rload sh 14 ; load Small-C ROM image in slot 14 > ; initialise ROM > *sh ; invoke tcc command shell $ copy 1 0 *.* ; copy 'system' files onto working disk $ copy 3 2 hanoi/c ; copy example source file $ drive 2 ; select drive 2 on working disk $ mode 7 ; set vdu mode 7 $ tcc -o hanoi hanoi/c ; compile example $ mode 2 ; set vdu mode for "hanoi" $ hanoi ; run program $ mode 7 ; reset vdu mode $ basic ; return to BASIC > ; BASIC prompt See the description of each utility program for a detailed explanation of how to use them. The Small-C sources are intended to be examples of how to use the language - if you need more help than this, consult the excellent "Small-C Handbook" by James E. Hendrix. There are also numerous Small-C programs available from the CP/M user group. Small-C compiler for the BBC Micro Release 0.71 A.J.Travis 01-May-89 INTRODUCTION Small-C is a subset of the C programming language for which a number of public-domain compil©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª ²‚ ƒ ˆƒ¢   …ÐL?¢  ‹… ˆƒ V »ƒ¢ ŽŒ ·‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐLù¢t  ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLÅ®¬ %ƒŽŒ 4ƒLÕ¢  ‹… ˆƒ V »ƒ ²‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒLI ²‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  ¶…ÐL{®¬ ™…ÐLG ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ‚ »ƒLf ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ / »ƒ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒLù¢ Lo†¢ü  ˆƒ ·‚ ƒ ˆƒ ㆠ¸ƒ ˆƒ¢   …ÐL.¢ü  ˆƒ¢  რ„ ƒ ˆƒ¢  Q… ™…ÐL.¢ü  ˆƒ¢  რ„ ˆƒ¢ü  ˆƒ¢  რ„ ƒ ˆƒ¢w  Q… é‚¢  ˆƒ¢ü  ˆƒ ¼‚ ƒ ˆƒ Hˆ µƒ ²‚ ƒ ˆƒ Ά »ƒ`¢ü  ˆƒ ·‚ ƒ ˆƒ ㆠ¸ƒ ˆƒ¢  «…ÐLt ²‚ ƒ ˆƒ¢w  ˆƒ¢  ˆƒ `’ µƒLU¢ü  ˆƒ¢  რ„ ƒ ˆƒ¢  Q… ™…ÐLò¢ü  ˆƒ¢  რ„ ƒ ˆƒ¢ˆ  Q… ™…ÐLà ²‚ ƒ ˆƒ¢‰  ˆƒ¢  ˆƒ `’ µƒLï ²‚ ƒ ˆƒ Ά »ƒLU¢ü  ˆƒ¢  რ„ ƒ ˆƒ¢  Q… ™…ÐL8 ²‚ ƒ ˆƒ¢£  ˆƒ¢  ˆƒ `’ µƒLU ²‚ ƒ ˆƒ¢Â  ˆƒ¢  ˆƒ `’ µƒ`¢Ú  ˆƒ¢  ˆƒ `’ ¸ƒ ²‚ ƒLo†`-frm: %s not found rm: %s permission denied rm: can't remove directory %s rm: %s file type error usage: rm [-f] file1 ... [filen] ©ü¢ ÿLÄLÂ#Small-C0.72 (23 Jun 1991)(C)1989 A.J.TravisNAME sh - Small-C command shell SYNOPSIS *sh DESCRIPTION Sideways ROM/RAM version of Small-C run-time support, and tcc library. *sh invokes an interactive shell. AUTHOR A.J.Travis H˜HŠHº½ÉÐ"¢½j€ÑòðI ÑòÐ É ðÈèLL¾©Ž¦ôLôÿÉ Ðò çÿ±òÉ Ð@¢½ €ð îÿèLE© îÿ¢½€ð É ð îÿèLX çÿ© îÿ îÿ¢½j€ ãÿèÉ ÐõL¾¢½j€É ðÑòðI ÑòÐ(ÈèL… ©7…x©€…y±xð ãÿæxÐõæyL¥ çÿº©hªh¨h`©¨¢ ÿ ôÿ†x„y ©&‘xÈ©‚‘xÈ¥ô‘x 0©C‘xÈ©†‘xÈ¥ô‘x©©ÿ©0 ©ÿ!©¢ ôÿXØ¢ÿš©H©ÃHº†~©„ ôÿ†|„}L…¬ ±ýð îÿÈL(‚ çÿLÄ…†p„q çÿ º ‚½¼ª ‚¦p¤q ‚¦t¤u ‚¦x¤y ‚¦|¤} ‚ ±|ªÈ±|¨ ‚¥¦p¤q`˜ ‚Š ‚© îÿ`HJJJJ œ‚h œ‚`)É 0ii0Lîÿ ÿ` `¦|¤}`¢LÒ‚¢LÒ‚¢LÒ‚¢LÒ‚¢ LÒ‚¢  Še|ª˜e}¨` £ƒ Š‘tLª‚ £ƒ„q Š‘tÈ¥q‘t¨`†p„q ±pªLª‚†p„q ±pªÈ±p¨` ±|…xȱ|…y »ƒlxèÐÈ`Šiª˜i¨`ÊàÿЈ`8Šéª˜é¨`e|…|©e}…}`e|…|¥e}…}`…x8¥|åx…|¥}é…}`…x8¥|åx…|¥}å…}`Цt…t˜¤u…u`8¥|é…|¥}é…}„q˜ ‘|ˆŠ‘|¤q`„q ±|…tȱ|…u¤qL»ƒ »ƒ »ƒ¥|i…|¥}i…}`„q ±|…pŠ‘|ȱ|ª¥q‘|Ѝ¦p`©…x†r„s „p„q p&q&r&s ¥xep…p©eq…qˆÐæ¦p¤q` £ƒŠetª˜eu¨` £ƒ†p„q8¥tåpª¥uåq¨` £ƒ†r„s „p„q p&q&r&s¥tep…p¥ueq…q©er…rˆÐà¦p¤q` £ƒ˜EuH˜ ‹…$u +… …„h ‹…` £ƒ …†x„y¥t…p¥u…q „t„u¢p&q&t&u8¥tåx¨¥uåy„t…u&p&qÊÐå¦p¤q` £ƒ˜H ‹…$u +… Þ„h ‹…` £ƒ …†x„y „p„q¢t&u&p&q8¥påx¨¥qåy„p…q&t&uÊÐå¦p¤q`ŠÐ˜Ðdivision by zero`8©åt…t©åu…u` £ƒŠtª˜u¨` £ƒŠEtª˜Eu¨` £ƒŠ%tª˜%u¨` £ƒ¥u…q¥tàðFqjÊÐúª¤q` £ƒ¥t…p¥uàðp*ÊÐú¨¦p`ŠIÿiª˜Iÿi¨`àÐÀ` æ…ð¢`¢` æ…Т`¢` æ…ð¢`¢` æ…ð¢`¢` æ…°¢`¢` æ…¢`¢` £ƒ†p˜ I€…q¥uI€ÅqÐ¥tÅp` /†ð¢`¢` /†ð¢`¢` /†°¢`¢` /†¢`¢` £ƒ†p„q ¥uÅqÐ¥tÅp`ÉÐ'© ¢ ôÿ©~ ôÿ©  Îÿ©² ¢ÿ ôÿ escape`© ôÿ¦~š` ‡©…€©…©¢€  ÝÿÉð ±|ijjj¢  Îÿªð `¢ÿ ÿ` ‡©€¢  Îÿªð `¢ÿ ÿ` ±|¨© Îÿ` ‡©…€©…©¢€  Ýÿ`©LLˆ ‡¢  ÷ÿ©¢ ôÿ `©¢€  Úÿ¦€¤` ±|…pȱ|…q ±p™ðÈÐö© ™` ±|ª© ôÿŠð¢ `©HL€‡ ±|Éð Éð©HL€‡ ±|…pȱ|…qȱ|…xȱ|ª ¥xÐàðÊÆx±p þ‡ÈÐíæqLg‡` ±|…€ ±|…ȱ|…‚©…ƒ…„ȱ|……ȱ|…†©…‡…ˆh¢€  Ñÿ8 ±|兪ȱ|冨` ±|ð¨ ×ÿ°ªLª‚¢ÿ ÿ` àÿÉ Ð îÿ© îÿªLª‚ ±|ª ±|Éð É𨊠Ôÿ`ŠÉ ð îÿ`© îÿ© îÿ` ±| îÿ` ±|ªÈ±|… ±|¤ ôÿ` ±|ªÈ±|… ±|¤ ñÿ˜ªh)¨` ±|H ‡ ±|…xȱ|…y ©‘xÈ©‘xh¦x¤y ÝÿÉТÿ ÿ`¢ ‘x` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)Dªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰) ªð¢` ±|)€I€ªð¢` ±|ª½Y‰)ð8Šé ª` ±|ª½Y‰)ðŠi ª` ±|)ª`  AAAAAABBBBBB © ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐL ŠLí‰ ·‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐLTŠLŠ ²‚ ƒ »ƒ` ²‚ ƒ ú‚ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚  …ÐL³Š ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ˆƒ¢   …ÐL°Š¢ `L^Š ²‚ ƒ ú‚ ˆƒ ¼‚ ˆƒ ƒ 4ƒ é‚ ú‚ „`© ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐL!‹LéŠ ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ¢  é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐLo‹ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒL=‹ ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐL­‹L‹ ·‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐL.Œ Á‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Û…ÐL+Œ ·‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Þ‚L.ŒL¼‹ ²‚ ƒ »ƒ` ¼‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Ð… ˆƒ ·‚ ƒ ú‚ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚  … Q… ™…ÐL¯Œ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ˆƒ¢   …ÐL¬Œ¢ `L8Œ ¼‚ ƒ ˆƒ¢  Û…ÐLÉŒ¢ ` ²‚ ƒ ú‚ ˆƒ ¼‚ ˆƒ ƒ 4ƒ é‚ ú‚ „`© ]ƒ ²‚ ˆƒ Á‚ ƒ é‚ ·‚ ˆƒ¢  é‚ ·‚ ƒ ˆƒ Ë‚ ƒ Û…ÐL½ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢   …ÐL¨ ·‚ ˆƒ ƒ %ƒ é‚ ˆƒ Ë‚ ƒ Û…ÐLž ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚L_ ²‚ ƒ ¸ƒ` ·‚ ˆƒ ƒ %ƒ é‚ 4ƒL ²‚ ƒ ¸ƒ` ²‚ ƒ ˆƒ Æ »ƒ`© ]ƒ ¼‚ ƒ ú‚ ˆƒ¢w   …ÐLeŽ ²‚ ˆƒ¢  ˆƒ Á‚ ƒ ˆƒ x† ¸ƒ é‚ ˆƒ¢  ‹… «…ÐLCŽ ²‚ ƒ ˆƒ Æ »ƒ ·‚ ƒ ˆƒ Ά »ƒ ²‚ ˆƒ¢  ˆƒ Á‚ ƒ ˆƒ ¬† ¸ƒ é‚L„Ž ²‚ ˆƒ¢  ˆƒ Á‚ ƒ ˆƒ x† ¸ƒ é‚ ²‚ ƒ ˆƒ¢  ‹…  …ÐL¤Ž¢  »ƒ` ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ Á‚ ƒ é‚ Á‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  ¶… ˆƒ ¼‚ ˆƒ Ђ ƒ ˆƒ ¾‡ »ƒ é‚ ˆƒ¢  ‹… «… Q… ™…ÐLª ·‚ ƒ ˆƒ¢   …ÐLU ²‚ ˆƒ ƒ 4ƒ é‚ ˆƒ Á‚ ƒ $†ÐLR ²‚ ˆƒ Á‚ ƒ é‚LÂŽ ·‚ ƒ ˆƒ¢    …ÐLw ·‚ ˆƒ¢   é‚ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ¼‚ ƒ Þ‚ ˆƒ¢    …ÐL§LªLÂŽ ²‚ ƒ ˆƒ¢  Þ‚ ·‚ ƒ ˆƒ¢  ‹…  … ˆƒ ·‚ ƒ ˆƒ Æ‚ ƒ  … Q… ™…ÐLõ¢  ¸ƒ` ¼‚ ƒ ¸ƒ`© ]ƒ Æ‚ ƒ ˆƒ¢  «… ˆƒ Ë‚ ƒ ˆƒ¢  «… Q… ˆƒ Ë‚ ƒ ˆƒ¢  «… Q… ™…ÐL¢ ¼‚ ˆƒ Æ‚ ƒ é‚ ¼‚ ƒ ú‚ ™…ÐL¢ ¼‚ ƒ ú‚ ˆƒ¢    …ÐL ¼‚ ƒ ˆƒ¢   Þ‚ ¼‚ ˆƒ ƒ %ƒ é‚LW ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ™…ÐLì ·‚ ˆƒ Ë‚ ƒ ˆƒ ¼‚ ƒ ˆƒ æ‡ ¸ƒ é‚L¢ ·‚ ƒ µƒ`© ]ƒ ²‚ ˆƒ Á‚ ƒ é‚ ·‚ ˆƒ¢  ˆƒ ¾‡ »ƒ é‚ ˆƒ¢   «… ˆƒ ¼‚ ƒ ˆƒ¢  Ð… Q… ™…ÐLi‘ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ¼‚ ƒ Þ‚L ‘ ·‚ ƒ ˆƒ¢  Û… ˆƒ ·‚ ƒ ˆƒ Æ‚ ƒ  … Q… ™…ÐL¡‘¢  ¸ƒ` ²‚ ƒ ˆƒ¢  Þ‚ ¼‚ ƒ ¸ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ™…ÐLÿ‘¢  ˆƒ ·‚ ƒ ˆƒ æ‡ ¸ƒLÀ‘¢  ˆƒ¢   ˆƒ æ‡ ¸ƒ »ƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ Î’ µƒ¢  ˆƒ ·‚ ˆƒ ÿ ¸ƒ©…© Qƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ Î’ µƒ¢  Ô‚ ƒ ˆƒ ·‚ ˆƒ ÿ ¸ƒ©…© Qƒ` ¼‚ ˆƒ ¼‚ ƒ ˆƒ ¼‚ ƒ ˆƒ Î’ µƒ`© ]ƒ Æ‚ ˆƒ¢ Ò‚ ƒ é‚¢ Ò‚ ƒ ú‚ ™…ÐLÅš Ë‚ ˆƒ Ë‚ ƒ é‚¢ Ò‚ ƒ ú‚ ˆƒ¢%  «…ÐLR“ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚Lä’¢ Ò‚ ˆƒ ƒ %ƒ é‚ ú‚ ˆƒ¢-   …ÐLš“¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L©“¢ Ò‚ ˆƒ¢   Þ‚¢ Ò‚ ƒ ú‚ ˆƒ¢0   …ÐL”¢ Ò‚ ú‚ ˆƒ¢-   …ÐLô“¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚L”¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ·‚ ˆƒ¢  é‚¢ Ò‚ ƒ ú‚ ˆƒ ®ˆ »ƒ ™…ÐL‚” ·‚ ˆƒ ¼‚ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ „ ˆƒ¢0  „ é‚L#”¢ Ò‚ ƒ ú‚ ˆƒ¢.  «…ÐL¯” ²‚ ˆƒ¢  ‹… é‚LW•¢ Ò‚ ˆƒ ƒ %ƒ é‚ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐLë” ²‚ ˆƒ¢  é‚LW• ²‚ ˆƒ¢  é‚¢ Ò‚ ƒ ú‚ ˆƒ ®ˆ »ƒ ™…ÐLW• ²‚ ˆƒ ·‚ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ „ ˆƒ¢0  „ é‚Lø” Á‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢d   …ÐL>–¢ Ò‚ ƒ ƒ ˆƒ¢ € Q… ™…ÐL– Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢-  Þ‚ Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢   ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ‹… ˆƒ Ûš µƒ „ é‚L;– Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢   ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢o   …ÐL‘– Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢  ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢u   …ÐLä– Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢   ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢x   …ÐL7— Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢  ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢X   …ÐL— Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢  ‹… ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢c   …ÐLØ— Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ƒ ƒ Þ‚ Æ‚ ƒ ˆƒ¢  Þ‚L÷˜ Á‚ ú‚ ˆƒ¢s   …ÐLɘ ¼‚ ˆƒ¢ Ò‚ ƒ ƒ é‚ Æ‚ ˆƒ ƒ 4ƒ é‚ ²‚ ƒ ˆƒ¢  Û…ÐL]˜ Æ‚ ˆƒ ƒ %ƒ é‚ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐLZ˜L%˜LƘ Æ‚ ˆƒ ƒ %ƒ é‚ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐLƘ ²‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢   …ÐLØ Æ‚ ƒ ˆƒ¢  Þ‚LƘL]˜L÷˜ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Æ‚ ú‚ Þ‚ Æ‚ ƒ ˆƒ¢  Þ‚ ·‚ ˆƒ ¼‚ ƒ ˆƒ Ђ ƒ ˆƒ¢ Ò‚ ƒ „ „ é‚ ˆƒ¢  ¶…ÐL®š¢ Ò‚ ú‚ ˆƒ¢-   …ÐL™™ ·‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶…ÐL†™ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢   Þ‚LF™ Æ‚ ƒ ˆƒ¢  Þ‚L®š Á‚ ú‚ ˆƒ¢d   … ˆƒ Ђ ƒ ú‚ ˆƒ¢-   … Q… ˆƒ¢ Ò‚ ú‚ ˆƒ¢0   … Q… ™…ÐLô™ Ë‚ ˆƒ ƒ %ƒ é‚ 4ƒ Æ‚ ƒ ˆƒ Ђ ƒ †ÐL;š Æ‚ ƒ ˆƒ ¼‚ ƒ „ ˆƒ Ë‚ ˆƒ ƒ 4ƒ é‚ %ƒ ú‚ Þ‚Lô™ ·‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶…ÐLš Ë‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ú‚ Þ‚L;š Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐLŸšLš Æ‚ ˆƒ ƒ 4ƒ é‚¢ Ò‚ ˆƒ ƒ *ƒ é‚ ;ƒLä’ Æ‚ ƒ ˆƒ¢  Þ‚© Eƒ`© ]ƒ Ë‚ ƒ ˆƒ¢  Ð…ÐL› ·‚ ˆƒ¢a  ˆƒ¢   „ é‚L8› Ë‚ ˆƒ Ђ ƒ ‹… é‚ ·‚ ˆƒ¢A  ˆƒ¢   „ é‚ ²‚ ˆƒ Ë‚ ƒ é‚ Á‚ ƒ ˆƒ¢   …ÐL{› ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢0  Þ‚L*œ Á‚ ƒ ™…ÐL*œ ¼‚ ˆƒ Æ‚ ƒ ˆƒ¢ Ò‚ ƒ Û„ é‚ ˆƒ¢   Û…ÐLà› ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ƒ ˆƒ¢0  „ Þ‚L œ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ƒ ˆƒ Á‚ ƒ „ Þ‚ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢ Ò‚ ƒ ‚„ é‚L{› Á‚ ˆƒ ·‚ ƒ ˆƒ Ђ ƒ „ é‚ ²‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  Þ‚ Æ‚ ƒ ˆƒ ·‚ ƒ $†ÐLÌœ ¼‚ ˆƒ Ë‚ ƒ ú‚ é‚ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ·‚ ƒ ú‚ Þ‚ ²‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ Á‚ ƒ Þ‚Laœ Á‚ ƒ µƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ¢  ˆƒ …© Eƒ©…© Qƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ¢  Ô‚ ƒ ˆƒ …© Eƒ©…© Qƒ` ¼‚ ˆƒ ¼‚ ƒ ˆƒ ¼‚ ƒ ˆƒ¢  ‹… ˆƒ …© Eƒ`© ]ƒ¢ Ò‚ ƒ ˆƒ¢  ‹… «…ÐL¶¢ Ò‚ ƒ ˆƒ¢  Þ‚¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ¢  é‚¢ Ò‚ ƒ ú‚ ™…ÐL©¢ Ò‚ ú‚ ˆƒ¢%  «… ˆƒ¢ Ò‚ ú‚ ˆƒ¢   … 9… ™…ÐLé ¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐLQžLž Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐL…žLQž¢ Ò‚ ú‚ ˆƒ¢   …ÐLŸžLé ¢ Ò‚ ƒ ˆƒ¢  ‹… «…ÐL‹  Ђ ú‚ ˆƒ¢   …ÐL‹ ¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ Á‚ ˆƒ¢  é‚ Á‚ ƒ ˆƒ¢  Û…ÐLëŸ Ð‚ ˆƒ¢ Ò‚ ƒ ˆƒ ¾‡ »ƒ Þ‚ ˆƒ¢  ‹…  …ÐL2ŸLëŸ Ð‚ ú‚ ˆƒ¢   …ÐLŸ¢ Ò‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢ Ò‚ ƒ $†ÐL~Ÿ¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚L Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ú‚ Þ‚ Ђ ú‚ ˆƒ¢    … ˆƒ¢ Ò‚ ú‚ ˆƒ¢    … 9… ™…ÐLÖŸLëŸ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒL Ò‚ ƒ ˆƒ¢  Þ‚ Ђ ú‚ ˆƒ¢  ‹…  … ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ  … Q… ™…ÐLA ¢  ‹…© Eƒ`¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐLˆ LT L¹ž¢ Ò‚ ú‚ ˆƒ¢  «… ˆƒ¢ Ò‚ ú‚ ˆƒ¢ Ò‚ ú‚ «… Q… ˆƒ¢ Ò‚ ú‚ ˆƒ¢%  «… Q… ™…ÐLæ ¢  ‹…© Eƒ`Lé¢ Ò‚ ú‚ ˆƒ¢   …ÐL¡L©¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ·‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢*  «… é‚ ˆƒ¢   …ÐLq¡¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚¢ Ò‚ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐL¡¡ Ë‚ ˆƒ¢  é‚L¢ Ë‚ ˆƒ¢  é‚ Ë‚ ˆƒ Ђ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ú‚ „ ˆƒ¢0  „ é‚¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ ®ˆ »ƒ ™…ðL®¡ Á‚ ˆƒ¢  é‚¢ Ò‚ ú‚ ˆƒ¢d   …ÐL¾£ Æ‚ ˆƒ¢  é‚ Ð‚ ú‚ ˆƒ¢+   …ÐLŠ¢ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ Ë‚ ˆƒ ƒ 4ƒ é‚LÞ¢ Ђ ú‚ ˆƒ¢-   …ÐLÞ¢ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ Æ‚ ˆƒ¢  ‹… é‚ Ë‚ ˆƒ ƒ 4ƒ é‚ Ð‚ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐL £¢  ‹…© Eƒ` Ђ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL £ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ú‚ „ ˆƒ¢0  „ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L £ Á‚ ˆƒ Æ‚ ƒ ˆƒ Ђ ƒ 0„ é‚L§¨¢ Ò‚ ú‚ ˆƒ¢o   …ÐL»¤ Ђ ú‚ ˆƒ¢0  Û… ˆƒ¢ Ò‚ ú‚ ˆƒ¢7  ¶… 9… ™…ÐL¤¢  ‹…© Eƒ` Ђ ú‚ ˆƒ¢0  Ð… ˆƒ¢ Ò‚ ú‚ ˆƒ¢7  Ã… Q… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL¸¤ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢  0„ ˆƒ¢ Ò‚ ú‚ „ ˆƒ¢0  „ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L¤L§¨¢ Ò‚ ú‚ ˆƒ¢x   … ˆƒ¢ Ò‚ ú‚ ˆƒ¢X   … 9… ™…ÐLΦ Ђ ú‚ ˆƒ¢0   …ÐLe¥ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢ Ò‚ ú‚  …ÐLX¥ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚Le¥¢  ‹…© Eƒ` Ђ ú‚ ˆƒ ¾ˆ »ƒ ˆƒ¢   …ÐL¥¢  ‹…© Eƒ` Ђ ú‚ ˆƒ ¾ˆ »ƒ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL˦ Ђ ú‚ ˆƒ ®ˆ »ƒ ™…ÐL¦ ¼‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢0  „ é‚Lƒ¦ Ђ ú‚ ˆƒ Žˆ »ƒ ™…ÐLG¦ ¼‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢A  „ ˆƒ¢   „ é‚Lƒ¦ Ђ ú‚ ˆƒ žˆ »ƒ ™…ÐLƒ¦ ¼‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢a  „ ˆƒ¢   „ é‚ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢  0„ ˆƒ Æ‚ ƒ „ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L¥L§¨¢ Ò‚ ú‚ ˆƒ¢s   …ÐL@¨ ·‚ ƒ ™…ÐĻ¢ Ò‚ ˆƒ¢ Ò‚ ƒ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ƒ é‚ Ð‚ ú‚ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL·§¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ú‚ Þ‚ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐL´§L·§L$§¢ Ò‚ ƒ ˆƒ¢  Þ‚L=¨ Ђ ú‚ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL=¨ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐL:¨L=¨ĻL§¨¢ Ò‚ ú‚ ˆƒ¢c   …ÐLš¨ Á‚ ˆƒ¢ Ò‚ ú‚ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ Ë‚ ˆƒ ƒ 4ƒ é‚L§¨¢  ‹…© Eƒ` ·‚ ƒ ˆƒ¢  «… ˆƒ¢ Ò‚ ú‚ ˆƒ¢s  «… Q… ™…ÐL ©¢ Ò‚ ƒ ˆƒ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ƒ ˆƒ Æ‚ ƒ é‚¢ Ò‚ ˆƒ ƒ 4ƒ é‚LÖ ²‚ ƒ© Eƒ`© ]ƒ ¼‚ ˆƒ¢  é‚ ·‚ ˆƒ¢  é‚ ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ˆƒ¢+   …ÐL–© ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚LÙ© ²‚ ƒ ˆƒ¢-   …ÐLÙ© ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ·‚ ˆƒ¢  ‹… é‚ ²‚ ƒ ˆƒ ®ˆ »ƒ ™…ÐL@ª ¼‚ ˆƒ Á‚ ƒ ˆƒ¢   0„ ˆƒ ¼‚ ƒ „ ˆƒ¢0  „ é‚ ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚LÙ© ¼‚ ƒ ˆƒ ¼‚ ƒ 0„ µƒ`©…©F mƒ¢D  Ô‚ ˆƒ ü† é‚¢B  Ô‚ ˆƒ ·‚ é‚¢  Ô‚ ˆƒ¢  რ„ ˆƒ¢D  Ô‚ ƒ é‚¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚¢@  Ô‚ ˆƒ¢  é‚¢D  Ô‚ ƒ ú‚ ˆƒ¢   «…ÐLK¬¢D  Ô‚ ƒ ú‚ ˆƒ¢    … ˆƒ¢F  Ô‚ ƒ ú‚ ˆƒ¢    … 9… ™…ÐLE«¢D  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒLðª¢D  Ô‚ ƒ ú‚ ˆƒ¢   «…ÐL—«¢  Ô‚ ˆƒ¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ˆƒ¢D  Ô‚ ƒ é‚¢D  Ô‚ ƒ ú‚ ˆƒ¢   «… ˆƒ¢F  Ô‚ ƒ ú‚ ˆƒ¢   «… Q… ˆƒ¢F  Ô‚ ƒ ú‚ ˆƒ¢   «… Q… ™…ÐL(¬¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢F  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L—«¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚LÔª¢F  Ô‚ ƒ ˆƒ¢  Ô‚ Ƀ ˆƒ¢D  Ô‚ ƒ Ƀ ˆƒ ƒ ¸ƒ©…©F Qƒ`Lˆ¬©ˆ ]ƒ¢€ Ò‚ ˆƒ¢  ˆƒ¢  ˆƒ ˆ ¸ƒ ˆƒ¢ÿ  Q… é‚ ™…ÐLÖ¬¢€ Ò‚ ƒ ˆƒ¢ô ¯ ˆƒ ’ ¸ƒ¢€ Ò‚ ˆƒ¢  é‚¢  ˆƒ¢~  ˆƒ ˆ ¸ƒ¢  ˆƒ¢  ° ˆƒ ÿ ¸ƒ¢† Ò‚ ˆƒ¢† Ò‚ ˆƒ¢  ˆƒ¢  ˆƒ Æ‚ ˆƒ ®Ž µƒ é‚ é‚¢€ Ò‚ ˆƒ¢ ÿ ˆƒ¢Æ  ˆƒ ˆ ¸ƒ ˆƒ¢ÿ  Q… é‚ ™…ÐL¥­¢€ Ò‚ ƒ ˆƒ¢  ˆƒ ˆ ¸ƒ ˆƒ¢ÿ  Q… ™…ÐL¥­¢  ° ˆƒ è† »ƒ¢„ Ò‚ ƒ ú‚ ˆƒ¢    …ÐLÓ­¢„ Ò‚ ˆƒ ƒ %ƒ é‚L¥­¢† Ò‚ ƒ ˆƒ¢† Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐL:®¢† Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ˆƒ¢    …ÐL7®¢† Ò‚ ˆƒ ƒ 4ƒ é‚LÓ­¢  ˆƒ¢ ° ˆƒ ¼‚ ˆƒ 8Œ µƒ ˆƒ¢   …ÐL¯¢† Ò‚ ˆƒ ·‚ ˆƒ¢  „ é‚¢† Ò‚ ƒ ú‚ ˆƒ¢    …ÐL©®¢† Ò‚ ˆƒ ƒ %ƒ é‚L{®¢† Ò‚ ƒ ú‚ ˆƒ ®ˆ »ƒ ™…ÐL¯¢‚ Ò‚ ˆƒ¢ˆ Ò‚ ƒ ú‚ ˆƒ¢0  „ é‚¢  ˆƒ ˆ »ƒ¢‚ Ò‚ ƒ ˆƒ¢€  9… ˆƒ ˆ »ƒ¢ ©ˆ EƒLo† ²‚ ú‚ ˆƒ¢   …ÐLE¯¢€ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒLѯ ²‚ ú‚ ˆƒ¢*   …ÐL½¯¢  ˆƒ¢   ˆƒ ˆ ¸ƒ¢† Ò‚ ˆƒ¢ ÿ é‚¢† Ò‚ ƒ ú‚ ˆƒ¢`  «…ÐL«¯¢† Ò‚ ˆƒ ƒ %ƒ é‚L}¯¢   ˆƒ¢ˆ Ò‚ ƒ é‚ ²‚ ˆƒ è† »ƒ©ˆ EƒLo†¢€ Ò‚ ƒ ˆƒ¢   …ðL嬢 ©ˆ EƒLo†Return value: &%02X. $ execmodeLÄLÂ#Small-C0.72 (23 Jun 1991)(C)1989 A.J.TravisNAME sh - Small-C command shell SYNOPSIS *sh DESCRIPTION Sideways ROM/RAM version of Small-C run-time support, and tcc library. *sh invokes an interactive sPress SPACE to loadÜSyntax: SRLoad () (I) (R) (P) (Q)© ¢¨ Úÿ¥¨…ò¥©…ó Âÿð¹ Åÿû±òÈÉ ðùÉ ðAÉ0¥É:,ÉA)ßÉG ÉRðÉQðÛÉPðÉIЇi)ª½§ x x ÐÃé)w ©€Ðí¥ôH,x 0 B w ­x J ¹ ð îÿÈÐõ àÿ çÿ¥¨y ¥©z ¢y  ©ÿ Ýÿ­w 8  „¨„ª©0…©©€…«±¨‘ªÈÐùæ©æ«¥«ÉÀÐï­x )ð&¢¬€¹€Ý> ЈÊô®w ­€¡­x )ð©ŽLôÿh…ô0þ`(C) ¢Š 8 ˜ð½¡Ð­€î€Í€ð΀Š`ÊáˆÜþNo RAM found0ÿÿ1.03Press SPACE to loadÜSyntax: SRLoad () (I) (R) (P) (Q)© ¢¨ Úÿ¥¨…ò¥©…ó Âÿð¹ Åÿû±òÈÉ ðùÉ ðAÉ0¥É:; start.s 11-Apr-89 A.J.Travis ; ; start-up ROM-dependant Small-C program ; *=$1902 ; start lda #252 ;read current language ROM number ldx #$00 ;EOR X ldy #$ff ;AND Y jsr osbyte stx osrom ;Small-C ROM # returned in X stx $fe30 ;ROM select latch ldx #<_main ;user entry point ldy #>_main jsr push ;on tcc data stack jmp __cmdini ;_cmdinit(&main) ; start.s 11-Apr-89 A.J.Travis ; ; start-up ROM-dependant Small-C program ; *=$1902 ; start lda #252 ;read current language ROM number ldx #$00 ;EO/* stdio.h - 11 Feb 88 A.J.Travis */ /* * tcc 'standard' i/o header file */ #ifndef STDIO #define STDIO /* avoid multiple includes */ #define BUFSIZ 256 #define NULL 0 #define EOF (-1) #define stdin 0 #define stdout 1 #define stderr 2 #define FILE int #define unsigned char * #define getchar() getc(stdin) #define putchar(x) putc(x, stdout) #define os_file(a,n,b) osfile(n,b,a) #define os_byte(a,xy) os_byte(a,xy) #define os_word(a,xy) os_word(a,xy) #define os_wrch(a) vdu(a) #endif /* stdio.h - 11 FebLÄLÂ#Small-C0.72 (23 Jun 1991)(C)1989 A.J.TravisNAME sh - Small-C command shell SYNOPSIS *sh DESCRIPTION Sideways ROM/RAM version of Small-C run-time support, and tcc library. *sh invokes an interactive shell. AUTHOR A.J.Travis H˜HŠHº½ÉÐ"¢½j€ÑòðI ÑòÐ É ðÈèLL¾©Ž¦ôLôÿÉ Ðò çÿ±òÉ Ð@¢½ €ð îÿèLE© îÿ¢½€ð É ð îÿèLX çÿ© îÿ îÿ¢½j€ ãÿèÉ ÐõL¾¢½j€É ðÑòðI ÑòÐ(ÈèL… ©7…x©€…y±xð ãÿæxÐõæyL¥ çÿº©hªh¨h`©¨¢ ÿ ôÿ†x„y ©&‘xÈ©‚‘xÈ¥ô‘x 0©C‘xÈ©†‘xÈ¥ô‘x©©ÿ©0 ©ÿ!©¢ ôÿXØ¢ÿš©H©ÃHº†~©„ ôÿ†|„}L…¬ ±ýð îÿÈL(‚ çÿLÄ…†p„q çÿ º ‚½¼ª ‚¦p¤q ‚¦t¤u ‚¦x¤y ‚¦|¤} ‚ ±|ªÈ±|¨ ‚¥¦p¤q`˜ ‚Š ‚© îÿ`HJJJJ œ‚h œ‚`)É 0ii0Lîÿ ÿ` `¦|¤}`¢LÒ‚¢LÒ‚¢LÒ‚¢LÒ‚¢ LÒ‚¢  Še|ª˜e}¨` £ƒ Š‘tLª‚ £ƒ„q Š‘tÈ¥q‘t¨`†p„q ±pªLª‚†p„q ±pªÈ±p¨` ±|…xȱ|…y »ƒlxèÐÈ`Šiª˜i¨`ÊàÿЈ`8Šéª˜é¨`e|…|©e}…}`e|…|¥e}…}`…x8¥|åx…|¥}é…}`…x8¥|åx…|¥}å…}`Цt…t˜¤u…u`8¥|é…|¥}é…}„q˜ ‘|ˆŠ‘|¤q`„q ±|…tȱ|…u¤qL»ƒ »ƒ »ƒ¥|i…|¥}i…}`„q ±|…pŠ‘|ȱ|ª¥q‘|Ѝ¦p`©…x†r„s „p„q p&q&r&s ¥xep…p©eq…qˆÐæ¦p¤q` £ƒŠetª˜eu¨` £ƒ†p„q8¥tåpª¥uåq¨` £ƒ†r„s „p„q p&q&r&s¥tep…p¥ueq…q©er…rˆÐà¦p¤q` £ƒ˜EuH˜ ‹…$u +… …„h ‹…` £ƒ …†x„y¥t…p¥u…q „t„u¢p&q&t&u8¥tåx¨¥uåy„t…u&p&qÊÐå¦p¤q` £ƒ˜H ‹…$u +… Þ„h ‹…` £ƒ …†x„y „p„q¢t&u&p&q8¥påx¨¥qåy„p…q&t&uÊÐå¦p¤q`ŠÐ˜Ðdivision by zero`8©åt…t©åu…u` £ƒŠtª˜u¨` £ƒŠEtª˜Eu¨` £ƒŠ%tª˜%u¨` £ƒ¥u…q¥tàðFqjÊÐúª¤q` £ƒ¥t…p¥uàðp*ÊÐú¨¦p`ŠIÿiª˜Iÿi¨`àÐÀ` æ…ð¢`¢` æ…Т`¢` æ…ð¢`¢` æ…ð¢`¢` æ…°¢`¢` æ…¢`¢` £ƒ†p˜ I€…q¥uI€ÅqÐ¥tÅp` /†ð¢`¢` /†ð¢`¢` /†°¢`¢` /†¢`¢` £ƒ†p„q ¥uÅqÐ¥tÅp`ÉÐ'© ¢ ôÿ©~ ôÿ©  Îÿ©² ¢ÿ ôÿ escape`© ôÿ¦~š` ‡©…€©…©¢€  ÝÿÉð ±|ijjj¢  Îÿªð `¢ÿ ÿ` ‡©€¢  Îÿªð `¢ÿ ÿ` ±|¨© Îÿ` ‡©…€©…©¢€  Ýÿ`©LLˆ ‡¢  ÷ÿ©¢ ôÿ `©¢€  Úÿ¦€¤` ±|…pȱ|…q ±p™ðÈÐö© ™` ±|ª© ôÿŠð¢ `©HL€‡ ±|Éð Éð©HL€‡ ±|…pȱ|…qȱ|…xȱ|ª ¥xÐàðÊÆx±p þ‡ÈÐíæqLg‡` ±|…€ ±|…ȱ|…‚©…ƒ…„ȱ|……ȱ|…†©…‡…ˆh¢€  Ñÿ8 ±|兪ȱ|冨` ±|ð¨ ×ÿ°ªLª‚¢ÿ ÿ` àÿÉ Ð îÿ© îÿªLª‚ ±|ª ±|Éð É𨊠Ôÿ`ŠÉ ð îÿ`© îÿ© îÿ` ±| îÿ` ±|ªÈ±|… ±|¤ ôÿ` ±|ªÈ±|… ±|¤ ñÿ˜ªh)¨` ±|H ‡ ±|…xȱ|…y ©‘xÈ©‘xh¦x¤y ÝÿÉТÿ ÿ`¢ ‘x` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)Dªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰)ªð¢` ±|ª½Y‰) ªð¢` ±|)€I€ªð¢` ±|ª½Y‰)ð8Šé ª` ±|ª½Y‰)ðŠi ª` ±|)ª`  AAAAAABBBBBB © ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐL ŠLí‰ ·‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐLTŠLŠ ²‚ ƒ »ƒ` ²‚ ƒ ú‚ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚  …ÐL³Š ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ˆƒ¢   …ÐL°Š¢ `L^Š ²‚ ƒ ú‚ ˆƒ ¼‚ ˆƒ ƒ 4ƒ é‚ ú‚ „`© ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐL!‹LéŠ ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ¢  é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐLo‹ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒL=‹ ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐL­‹L‹ ·‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐL.Œ Á‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Û…ÐL+Œ ·‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Þ‚L.ŒL¼‹ ²‚ ƒ »ƒ` ¼‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  Ð… ˆƒ ·‚ ƒ ú‚ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚  … Q… ™…ÐL¯Œ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ˆƒ¢   …ÐL¬Œ¢ `L8Œ ¼‚ ƒ ˆƒ¢  Û…ÐLÉŒ¢ ` ²‚ ƒ ú‚ ˆƒ ¼‚ ˆƒ ƒ 4ƒ é‚ ú‚ „`© ]ƒ ²‚ ˆƒ Á‚ ƒ é‚ ·‚ ˆƒ¢  é‚ ·‚ ƒ ˆƒ Ë‚ ƒ Û…ÐL½ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢   …ÐL¨ ·‚ ˆƒ ƒ %ƒ é‚ ˆƒ Ë‚ ƒ Û…ÐLž ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚L_ ²‚ ƒ ¸ƒ` ·‚ ˆƒ ƒ %ƒ é‚ 4ƒL ²‚ ƒ ¸ƒ` ²‚ ƒ ˆƒ Æ »ƒ`© ]ƒ ¼‚ ƒ ú‚ ˆƒ¢w   …ÐLeŽ ²‚ ˆƒ¢  ˆƒ Á‚ ƒ ˆƒ x† ¸ƒ é‚ ˆƒ¢  ‹… «…ÐLCŽ ²‚ ƒ ˆƒ Æ »ƒ ·‚ ƒ ˆƒ Ά »ƒ ²‚ ˆƒ¢  ˆƒ Á‚ ƒ ˆƒ ¬† ¸ƒ é‚L„Ž ²‚ ˆƒ¢  ˆƒ Á‚ ƒ ˆƒ x† ¸ƒ é‚ ²‚ ƒ ˆƒ¢  ‹…  …ÐL¤Ž¢  »ƒ` ²‚ ƒ »ƒ`© ]ƒ ²‚ ˆƒ Á‚ ƒ é‚ Á‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢  ¶… ˆƒ ¼‚ ˆƒ Ђ ƒ ˆƒ ¾‡ »ƒ é‚ ˆƒ¢  ‹… «… Q… ™…ÐLª ·‚ ƒ ˆƒ¢   …ÐLU ²‚ ˆƒ ƒ 4ƒ é‚ ˆƒ Á‚ ƒ $†ÐLR ²‚ ˆƒ Á‚ ƒ é‚LÂŽ ·‚ ƒ ˆƒ¢    …ÐLw ·‚ ˆƒ¢   é‚ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ¼‚ ƒ Þ‚ ˆƒ¢    …ÐL§LªLÂŽ ²‚ ƒ ˆƒ¢  Þ‚ ·‚ ƒ ˆƒ¢  ‹…  … ˆƒ ·‚ ƒ ˆƒ Æ‚ ƒ  … Q… ™…ÐLõ¢  ¸ƒ` ¼‚ ƒ ¸ƒ`© ]ƒ Æ‚ ƒ ˆƒ¢  «… ˆƒ Ë‚ ƒ ˆƒ¢  «… Q… ˆƒ Ë‚ ƒ ˆƒ¢  «… Q… ™…ÐL¢ ¼‚ ˆƒ Æ‚ ƒ é‚ ¼‚ ƒ ú‚ ™…ÐL¢ ¼‚ ƒ ú‚ ˆƒ¢    …ÐL ¼‚ ƒ ˆƒ¢   Þ‚ ¼‚ ˆƒ ƒ %ƒ é‚LW ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ™…ÐLì ·‚ ˆƒ Ë‚ ƒ ˆƒ ¼‚ ƒ ˆƒ æ‡ ¸ƒ é‚L¢ ·‚ ƒ µƒ`© ]ƒ ²‚ ˆƒ Á‚ ƒ é‚ ·‚ ˆƒ¢  ˆƒ ¾‡ »ƒ é‚ ˆƒ¢   «… ˆƒ ¼‚ ƒ ˆƒ¢  Ð… Q… ™…ÐLi‘ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ¼‚ ƒ Þ‚L ‘ ·‚ ƒ ˆƒ¢  Û… ˆƒ ·‚ ƒ ˆƒ Æ‚ ƒ  … Q… ™…ÐL¡‘¢  ¸ƒ` ²‚ ƒ ˆƒ¢  Þ‚ ¼‚ ƒ ¸ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ™…ÐLÿ‘¢  ˆƒ ·‚ ƒ ˆƒ æ‡ ¸ƒLÀ‘¢  ˆƒ¢   ˆƒ æ‡ ¸ƒ »ƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ Î’ µƒ¢  ˆƒ ·‚ ˆƒ ÿ ¸ƒ©…© Qƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ Î’ µƒ¢  Ô‚ ƒ ˆƒ ·‚ ˆƒ ÿ ¸ƒ©…© Qƒ` ¼‚ ˆƒ ¼‚ ƒ ˆƒ ¼‚ ƒ ˆƒ Î’ µƒ`© ]ƒ Æ‚ ˆƒ¢ Ò‚ ƒ é‚¢ Ò‚ ƒ ú‚ ™…ÐLÅš Ë‚ ˆƒ Ë‚ ƒ é‚¢ Ò‚ ƒ ú‚ ˆƒ¢%  «…ÐLR“ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚Lä’¢ Ò‚ ˆƒ ƒ %ƒ é‚ ú‚ ˆƒ¢-   …ÐLš“¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L©“¢ Ò‚ ˆƒ¢   Þ‚¢ Ò‚ ƒ ú‚ ˆƒ¢0   …ÐL”¢ Ò‚ ú‚ ˆƒ¢-   …ÐLô“¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚L”¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ·‚ ˆƒ¢  é‚¢ Ò‚ ƒ ú‚ ˆƒ ®ˆ »ƒ ™…ÐL‚” ·‚ ˆƒ ¼‚ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ „ ˆƒ¢0  „ é‚L#”¢ Ò‚ ƒ ú‚ ˆƒ¢.  «…ÐL¯” ²‚ ˆƒ¢  ‹… é‚LW•¢ Ò‚ ˆƒ ƒ %ƒ é‚ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐLë” ²‚ ˆƒ¢  é‚LW• ²‚ ˆƒ¢  é‚¢ Ò‚ ƒ ú‚ ˆƒ ®ˆ »ƒ ™…ÐLW• ²‚ ˆƒ ·‚ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ „ ˆƒ¢0  „ é‚Lø” Á‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢d   …ÐL>–¢ Ò‚ ƒ ƒ ˆƒ¢ € Q… ™…ÐL– Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢-  Þ‚ Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢   ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ‹… ˆƒ Ûš µƒ „ é‚L;– Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢   ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢o   …ÐL‘– Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢  ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢u   …ÐLä– Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢   ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢x   …ÐL7— Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢  ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢X   …ÐL— Æ‚ ˆƒ Ë‚ ƒ ˆƒ¢  ‹… ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ƒ ˆƒ Ûš µƒ „ é‚L÷˜ Á‚ ú‚ ˆƒ¢c   …ÐLØ— Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ƒ ƒ Þ‚ Æ‚ ƒ ˆƒ¢  Þ‚L÷˜ Á‚ ú‚ ˆƒ¢s   …ÐLɘ ¼‚ ˆƒ¢ Ò‚ ƒ ƒ é‚ Æ‚ ˆƒ ƒ 4ƒ é‚ ²‚ ƒ ˆƒ¢  Û…ÐL]˜ Æ‚ ˆƒ ƒ %ƒ é‚ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐLZ˜L%˜LƘ Æ‚ ˆƒ ƒ %ƒ é‚ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ™…ÐLƘ ²‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢   …ÐLØ Æ‚ ƒ ˆƒ¢  Þ‚LƘL]˜L÷˜ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Æ‚ ú‚ Þ‚ Æ‚ ƒ ˆƒ¢  Þ‚ ·‚ ˆƒ ¼‚ ƒ ˆƒ Ђ ƒ ˆƒ¢ Ò‚ ƒ „ „ é‚ ˆƒ¢  ¶…ÐL®š¢ Ò‚ ú‚ ˆƒ¢-   …ÐL™™ ·‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶…ÐL†™ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢   Þ‚LF™ Æ‚ ƒ ˆƒ¢  Þ‚L®š Á‚ ú‚ ˆƒ¢d   … ˆƒ Ђ ƒ ú‚ ˆƒ¢-   … Q… ˆƒ¢ Ò‚ ú‚ ˆƒ¢0   … Q… ™…ÐLô™ Ë‚ ˆƒ ƒ %ƒ é‚ 4ƒ Æ‚ ƒ ˆƒ Ђ ƒ †ÐL;š Æ‚ ƒ ˆƒ ¼‚ ƒ „ ˆƒ Ë‚ ˆƒ ƒ 4ƒ é‚ %ƒ ú‚ Þ‚Lô™ ·‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶…ÐLš Ë‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ú‚ Þ‚L;š Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ ™…ÐLŸšLš Æ‚ ˆƒ ƒ 4ƒ é‚¢ Ò‚ ˆƒ ƒ *ƒ é‚ ;ƒLä’ Æ‚ ƒ ˆƒ¢  Þ‚© Eƒ`© ]ƒ Ë‚ ƒ ˆƒ¢  Ð…ÐL› ·‚ ˆƒ¢a  ˆƒ¢   „ é‚L8› Ë‚ ˆƒ Ђ ƒ ‹… é‚ ·‚ ˆƒ¢A  ˆƒ¢   „ é‚ ²‚ ˆƒ Ë‚ ƒ é‚ Á‚ ƒ ˆƒ¢   …ÐL{› ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢0  Þ‚L*œ Á‚ ƒ ™…ÐL*œ ¼‚ ˆƒ Æ‚ ƒ ˆƒ¢ Ò‚ ƒ Û„ é‚ ˆƒ¢   Û…ÐLà› ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ƒ ˆƒ¢0  „ Þ‚L œ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ Á‚ ƒ ˆƒ Á‚ ƒ „ Þ‚ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢ Ò‚ ƒ ‚„ é‚L{› Á‚ ˆƒ ·‚ ƒ ˆƒ Ђ ƒ „ é‚ ²‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  Þ‚ Æ‚ ƒ ˆƒ ·‚ ƒ $†ÐLÌœ ¼‚ ˆƒ Ë‚ ƒ ú‚ é‚ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ·‚ ƒ ú‚ Þ‚ ²‚ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ Á‚ ƒ Þ‚Laœ Á‚ ƒ µƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ¢  ˆƒ …© Eƒ©…© Qƒ`©…© mƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ¢  Ô‚ ƒ ˆƒ …© Eƒ©…© Qƒ` ¼‚ ˆƒ ¼‚ ƒ ˆƒ ¼‚ ƒ ˆƒ¢  ‹… ˆƒ …© Eƒ`© ]ƒ¢ Ò‚ ƒ ˆƒ¢  ‹… «…ÐL¶¢ Ò‚ ƒ ˆƒ¢  Þ‚¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ¢  é‚¢ Ò‚ ƒ ú‚ ™…ÐL©¢ Ò‚ ú‚ ˆƒ¢%  «… ˆƒ¢ Ò‚ ú‚ ˆƒ¢   … 9… ™…ÐLé ¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐLQžLž Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐL…žLQž¢ Ò‚ ú‚ ˆƒ¢   …ÐLŸžLé ¢ Ò‚ ƒ ˆƒ¢  ‹… «…ÐL‹  Ђ ú‚ ˆƒ¢   …ÐL‹ ¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ Á‚ ˆƒ¢  é‚ Á‚ ƒ ˆƒ¢  Û…ÐLëŸ Ð‚ ˆƒ¢ Ò‚ ƒ ˆƒ ¾‡ »ƒ Þ‚ ˆƒ¢  ‹…  …ÐL2ŸLëŸ Ð‚ ú‚ ˆƒ¢   …ÐLŸ¢ Ò‚ ˆƒ ƒ 4ƒ é‚ ˆƒ¢ Ò‚ ƒ $†ÐL~Ÿ¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚L Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ú‚ Þ‚ Ђ ú‚ ˆƒ¢    … ˆƒ¢ Ò‚ ú‚ ˆƒ¢    … 9… ™…ÐLÖŸLëŸ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒL Ò‚ ƒ ˆƒ¢  Þ‚ Ђ ú‚ ˆƒ¢  ‹…  … ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ  … Q… ™…ÐLA ¢  ‹…© Eƒ`¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐLˆ LT L¹ž¢ Ò‚ ú‚ ˆƒ¢  «… ˆƒ¢ Ò‚ ú‚ ˆƒ¢ Ò‚ ú‚ «… Q… ˆƒ¢ Ò‚ ú‚ ˆƒ¢%  «… Q… ™…ÐLæ ¢  ‹…© Eƒ`Lé¢ Ò‚ ú‚ ˆƒ¢   …ÐL¡L©¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ·‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢*  «… é‚ ˆƒ¢   …ÐLq¡¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚¢ Ò‚ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐL¡¡ Ë‚ ˆƒ¢  é‚L¢ Ë‚ ˆƒ¢  é‚ Ë‚ ˆƒ Ђ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ú‚ „ ˆƒ¢0  „ é‚¢ Ò‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ ®ˆ »ƒ ™…ðL®¡ Á‚ ˆƒ¢  é‚¢ Ò‚ ú‚ ˆƒ¢d   …ÐL¾£ Æ‚ ˆƒ¢  é‚ Ð‚ ú‚ ˆƒ¢+   …ÐLŠ¢ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ Ë‚ ˆƒ ƒ 4ƒ é‚LÞ¢ Ђ ú‚ ˆƒ¢-   …ÐLÞ¢ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ Æ‚ ˆƒ¢  ‹… é‚ Ë‚ ˆƒ ƒ 4ƒ é‚ Ð‚ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐL £¢  ‹…© Eƒ` Ђ ú‚ ˆƒ ®ˆ »ƒ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL £ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢   0„ ˆƒ¢ Ò‚ ú‚ „ ˆƒ¢0  „ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L £ Á‚ ˆƒ Æ‚ ƒ ˆƒ Ђ ƒ 0„ é‚L§¨¢ Ò‚ ú‚ ˆƒ¢o   …ÐL»¤ Ђ ú‚ ˆƒ¢0  Û… ˆƒ¢ Ò‚ ú‚ ˆƒ¢7  ¶… 9… ™…ÐL¤¢  ‹…© Eƒ` Ђ ú‚ ˆƒ¢0  Ð… ˆƒ¢ Ò‚ ú‚ ˆƒ¢7  Ã… Q… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL¸¤ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢  0„ ˆƒ¢ Ò‚ ú‚ „ ˆƒ¢0  „ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L¤L§¨¢ Ò‚ ú‚ ˆƒ¢x   … ˆƒ¢ Ò‚ ú‚ ˆƒ¢X   … 9… ™…ÐLΦ Ђ ú‚ ˆƒ¢0   …ÐLe¥ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢ Ò‚ ú‚  …ÐLX¥ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚Le¥¢  ‹…© Eƒ` Ђ ú‚ ˆƒ ¾ˆ »ƒ ˆƒ¢   …ÐL¥¢  ‹…© Eƒ` Ђ ú‚ ˆƒ ¾ˆ »ƒ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL˦ Ђ ú‚ ˆƒ ®ˆ »ƒ ™…ÐL¦ ¼‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢0  „ é‚Lƒ¦ Ђ ú‚ ˆƒ Žˆ »ƒ ™…ÐLG¦ ¼‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢A  „ ˆƒ¢   „ é‚Lƒ¦ Ђ ú‚ ˆƒ žˆ »ƒ ™…ÐLƒ¦ ¼‚ ˆƒ¢ Ò‚ ú‚ ˆƒ¢a  „ ˆƒ¢   „ é‚ Á‚ ˆƒ Æ‚ ƒ ˆƒ¢  0„ ˆƒ Æ‚ ƒ „ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L¥L§¨¢ Ò‚ ú‚ ˆƒ¢s   …ÐL@¨ ·‚ ƒ ™…ÐĻ¢ Ò‚ ˆƒ¢ Ò‚ ƒ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ƒ é‚ Ð‚ ú‚ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL·§¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢ Ò‚ ú‚ Þ‚ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐL´§L·§L$§¢ Ò‚ ƒ ˆƒ¢  Þ‚L=¨ Ђ ú‚ ˆƒ¢  «… ˆƒ Ђ ˆƒ ƒ 4ƒ é‚ %ƒ ˆƒ¢  ¶… Q… ™…ÐL=¨ Ђ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ Έ »ƒ ™…ÐL:¨L=¨ĻL§¨¢ Ò‚ ú‚ ˆƒ¢c   …ÐLš¨ Á‚ ˆƒ¢ Ò‚ ú‚ é‚ Ð‚ ˆƒ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ Ë‚ ˆƒ ƒ 4ƒ é‚L§¨¢  ‹…© Eƒ` ·‚ ƒ ˆƒ¢  «… ˆƒ¢ Ò‚ ú‚ ˆƒ¢s  «… Q… ™…ÐL ©¢ Ò‚ ƒ ˆƒ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ƒ ˆƒ Æ‚ ƒ é‚¢ Ò‚ ˆƒ ƒ 4ƒ é‚LÖ ²‚ ƒ© Eƒ`© ]ƒ ¼‚ ˆƒ¢  é‚ ·‚ ˆƒ¢  é‚ ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ˆƒ¢+   …ÐL–© ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚LÙ© ²‚ ƒ ˆƒ¢-   …ÐLÙ© ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚ ·‚ ˆƒ¢  ‹… é‚ ²‚ ƒ ˆƒ ®ˆ »ƒ ™…ÐL@ª ¼‚ ˆƒ Á‚ ƒ ˆƒ¢   0„ ˆƒ ¼‚ ƒ „ ˆƒ¢0  „ é‚ ²‚ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ é‚LÙ© ¼‚ ƒ ˆƒ ¼‚ ƒ 0„ µƒ`©…©F mƒ¢D  Ô‚ ˆƒ ü† é‚¢B  Ô‚ ˆƒ ·‚ é‚¢  Ô‚ ˆƒ¢  რ„ ˆƒ¢D  Ô‚ ƒ é‚¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚¢@  Ô‚ ˆƒ¢  é‚¢D  Ô‚ ƒ ú‚ ˆƒ¢   «…ÐLK¬¢D  Ô‚ ƒ ú‚ ˆƒ¢    … ˆƒ¢F  Ô‚ ƒ ú‚ ˆƒ¢    … 9… ™…ÐLE«¢D  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒLðª¢D  Ô‚ ƒ ú‚ ˆƒ¢   «…ÐL—«¢  Ô‚ ˆƒ¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ˆƒ¢D  Ô‚ ƒ é‚¢D  Ô‚ ƒ ú‚ ˆƒ¢   «… ˆƒ¢F  Ô‚ ƒ ú‚ ˆƒ¢   «… Q… ˆƒ¢F  Ô‚ ƒ ú‚ ˆƒ¢   «… Q… ™…ÐL(¬¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢F  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚L—«¢B  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚LÔª¢F  Ô‚ ƒ ˆƒ¢  Ô‚ Ƀ ˆƒ¢D  Ô‚ ƒ Ƀ ˆƒ ƒ ¸ƒ©…©F Qƒ`LÄLÂ#Small-C0.72 (23 Jun 1991)(C)1989 A.J.TravisNAME sh - Small-C command shell SYNOPSIS *sh DESCRIPTION pr =$0070 sr =$0074 tr =$0078 sp =$007C rsp =$007E asave =$007F param =$0080 osrom =$00F4 userv =$0200 brkv =$0202 irq1v =$0204 irq2v =$0206 cliv =$0208 bytev =$020A wordv =$020C wrchv =$020E rdchv =$0210 filev =$0212 argsv =$0214 bgetv =$0216 bputv =$0218 gbpbv =$021A findv =$021C fscv =$021E evntv =$0220 uptv =$0222 netv =$0224 vduv =$0226 keyv =$0228 insv =$022A remv =$022C cnpv =$022E ind1v =$0230 ind2v =$0232 ind3v =$0234 gsbuf =$0400 osurom =$8000 osrdrm =$FFB9 oseven =$FFBF gsinit =$FFC2 gsread =$FFC5 nvwrch =$FFC8 nvrdch =$FFCB osfind =$FFCE osgbpb =$FFD1 osbput =$FFD4 osbget =$FFD7 osargs =$FFDA osfile =$FFDD osrdch =$FFE0 osasci =$FFE3 osnewl =$FFE7 oswrch =$FFEE osword =$FFF1 osbyte =$FFF4 oscli =$FFF7 evs =$0078 ebrkv =$FF03 eevntv =$FF30 break =$8226 __trace =$8239 ext =$82AA addr =$82B2 addr_1 =$82B7 addr_2 =$82BC addr_3 =$82C1 addr_4 =$82C6 addr_5 =$82CB addr_6 =$82D0 addr_b =$82D2 addr_w =$82D4 sind_b =$82DE sind_w =$82E9 lind_b =$82FA lind_w =$8306 scall =$8314 inc1 =$8325 inc2 =$832A dec1 =$8334 dec2 =$833B sinc_b =$8345 sinc_w =$8351 sdec_b =$835D sdec_w =$836D swap =$837D push =$8388 pop =$83A3 drop3 =$83B5 drop2 =$83B8 drop =$83BB xchange =$83C9 scale2 =$83E1 scale =$83E3 add =$8410 sub =$841D mult =$8430 div =$8464 udiv =$8482 mod =$84C0 umod =$84DB or =$8539 xor =$8545 cand =$8551 casr =$855D casl =$8574 neg =$858B nz =$8599 eq =$85A0 ne =$85AB gt =$85B6 le =$85C3 ge =$85D0 lt =$85DB ugt =$85FF ule =$860C uge =$8619 ult =$8624 escape =$8643 _exit =$866F _open =$8678 _creat =$86AC _close =$86C3 _unlink =$86CE _stat =$86E3 _system =$86E8 __cmdlin =$86FC _read =$8727 _write =$873F _getc =$87BE _putc =$87E6 _vdu =$8811 _osbyte =$8819 _osword =$882D _osfile =$8848 _isalpha =$887E _isupper =$888E _islower =$889E _isdigit =$88AE _isxdigi =$88BE _isspace =$88CE _ispunct =$88DE _isalnum =$88EE _isprint =$88FE _iscntrl =$890E _isascii =$891E _toupper =$892C _tolower =$893E _toascii =$8950 _ctype_ =$8959 _strcat =$89D9 _strcmp =$8A5E _strcpy =$8AD5 _strlen =$8B2B _strncat =$8B79 _strncmp =$8C38 _strncpy =$8CEB _fclose =$8DC7 _fopen =$8DD7 _fgets =$8EAE _fputs =$8FFF _gets =$90F6 _puts =$91BB _printf =$9217 _fprintf =$9260 _sprintf =$92AF __doprin =$92CE _itoa =$9ADB _scanf =$9CD6 _fscanf =$9D15 _sscanf =$9D5A __doscan =$9D85 _atoi =$A929 __cmdini =$AA56 __enter =$AC85 pr =$0070 sr =$0074 tr =$0078 sp =$007C rsp =$007E asave =$007F param =$0080 osrom =$00F4 userv =$0200 brkv =$0202 irq1v =$0204 irq2v =$0206 cliv =$0208 bytev =$020A wordv =$020C wrchv =$020E rdchv =$0210 filev =$0212 argsv =$0214 bgetv =$©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª¢ Žg(Œh(¢ Ži(Œj( ²‚ ƒ ˆƒ¢  Û…ÐLF ý"¢ Žk(Œl(¢ Žm(Œn(¢ Žo(Œp(¢ Žq(Œr(¢ Žs(Œt(¢ˆ #ŽS(ŒT(¢ #ŽU(ŒV(¢“ #ŽW(ŒX(¢› #Ž[(Œ\(¢ ŽY(ŒZ(¢ Ž_(Œ`(¢¡ #Ž](Œ^(¢± #Ža(Œb(¢¹ #Žc(Œd(¢¿ #Že(Œf(¢Ç #ŽQ(ŒR(¢ Žu(Œv( ·‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐL<¢Õ # ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL² ²‚ ƒ ˆƒ¢  Û…ÐLr ý"L¯ ·‚ ƒ ˆƒ¢  რ„ ƒŽc(Œd( ²‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒL¢Ø # ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLù®k(¬l( 4ƒŽk(Œl(L¢Û # ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLO®m(¬n( 4ƒŽm(Œn(®o(¬p( 4ƒŽo(Œp(L¢Þ # ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL–®o(¬p( 4ƒŽo(Œp(L¢á # ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLÝ®q(¬r( 4ƒŽq(Œr(L¢ä # ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL3¢ç #ŽY(ŒZ(¢ð #Ž](Œ^(¢ $Ž_(Œ`(L¢ $ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL‰¢  $ŽY(ŒZ(¢ $Ž](Œ^(¢ $Ž_(Œ`(L¢! $ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLË¢$ $ŽU(ŒV(L¢- $ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL®s(¬t( %ƒŽs(Œt( 4ƒL ý" ²‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒL𠲂 ƒ ˆƒ¢  Û…ÐLT ý" ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ¢L ' ˆƒ ÕŠ ¸ƒ¢L 'ŽM(ŒN(®M(¬N( %ƒŽM(ŒN( 4ƒ ú‚ ™…ÐL¤L„®M(¬N( 4ƒŽM(ŒN( ˆƒ¢L ' «…ÐLï®M(¬N( ú‚ ˆƒ¢.   …ÐLì®M(¬N( %ƒŽM(ŒN(LïL¤¢Ì 'ŽO(ŒP(®O(¬P( ˆƒ®M(¬N( %ƒŽM(ŒN( 4ƒ ú‚ Þ‚ ˆƒ¢  «…ÐL;®O(¬P( %ƒŽO(ŒP(Lù®O(¬P( 4ƒŽO(ŒP( ú‚ŽL(®O(¬P( 4ƒŽO(ŒP( ˆƒ¢  Þ‚®L( ª‚ ˆƒ¢c  «…ÐL©¢L ' ˆƒ¢0 $ ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ 6# »ƒ¢I $ ˆƒ¢L ' ˆƒ × ¸ƒŽg(Œh( ˆƒ¢   …ÐLý¢L ' ˆƒ¢K $ ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ 6# »ƒ®g(¬h( ˆƒ Ç »ƒ¢ Žg(Œh(¢  ˆƒ¢Æ  ˆƒ ˆ ¸ƒ ˆƒ¢ÿ  Q…Žu(Œv(¢_ $ ˆƒ®e(¬f( ˆƒ × ¸ƒŽi(Œj( ˆƒ¢   …ÐL’®e(¬f( ˆƒ¢a $ ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ 6# »ƒ¢Ì ' ˆƒ¢u $ ˆƒ¢L % ˆƒ ¯’ µƒ¢Ì ' ˆƒ¢z $ ˆƒ¢Ì % ˆƒ ¯’ µƒ¢Ì ' ˆƒ¢ $ ˆƒ¢L & ˆƒ ¯’ µƒ¢„ $ ˆƒ¢Ì & ˆƒ ¯’ ¸ƒ®Y(¬Z( ˆƒ¢   …ÐL8 ®c(¬d( ˆƒ¢L & ˆƒ ÕŠ ¸ƒ¢Š $ ˆƒ®c(¬d( ˆƒ ÕŠ ¸ƒ¢Ì & ˆƒ¢L & ˆƒ¢Ì % ˆƒ¢L % ˆƒ®[(¬\( ˆƒ¢‹ $ ˆƒ®i(¬j( ˆƒ `’© Eƒ®c(¬d( ˆƒ®a(¬b( ˆƒ¢› $ ˆƒ®i(¬j( ˆƒ `’© Eƒ¢L % ˆƒ¢L ' ˆƒ®S(¬T( ˆƒ¢¢ $ ˆƒ®i(¬j( ˆƒ `’© Eƒ®m(¬n( ™…ÐL  «… Q… ™…ÐL / ¼‚ ƒ µƒ`®­v ª‚ ˆƒ¢<   … ˆƒ®­v ª‚ ˆƒ¢>   … 9… ™…ÐLB/ ¼‚ ƒ µƒ` ¼‚ ƒ ™…ÐL_/ Á‚ ƒ ˆƒ ãX »ƒ¢  ™…ÐLî0¢ž i ˆƒ ¶R »ƒ ™…ÐL»/ cc ²‚ ˆƒ î0 »ƒ ™…ÐL£/ ²‚ ˆƒ ãX »ƒ ²‚ ˆƒ Æ‚ ƒ ˆƒ ðg ¸ƒLë0¢¡ i ˆƒ ¶R »ƒ ™…ÐL 0 cc ²‚ ˆƒ î0 »ƒ ™…ÐLó/ ²‚ ˆƒ ãX »ƒ ²‚ ˆƒ Æ‚ ƒ ˆƒ lh ¸ƒLë0®¬v ª‚ ˆƒ¢<   … ˆƒ®­v ª‚ ˆƒ¢<  «… Q… ™…ÐLw0 ¤U cc ²‚ ˆƒ î0 »ƒ ™…ÐL_0 ²‚ ˆƒ ãX »ƒ ²‚ ˆƒ Æ‚ ƒ ˆƒ ²g ¸ƒLë0®¬v ª‚ ˆƒ¢>   … ˆƒ®­v ª‚ ˆƒ¢>  «… Q… ™…ÐLã0 ¤U cc ²‚ ˆƒ î0 »ƒ ™…ÐLË0 ²‚ ˆƒ ãX »ƒ ²‚ ˆƒ Æ‚ ƒ ˆƒ .h ¸ƒLë0¢  µƒ`L_/© ]ƒ ¼‚ ˆƒ Æ‚ ƒ ˆƒ .2 »ƒ é‚ òT®¬v ª‚ ˆƒ¢>  «… ˆƒ®¬v ª‚ ˆƒ¢<  «… Q… ™…ÐLF1 ¼‚ ƒ µƒ`®­v ª‚ ˆƒ¢>  «… ˆƒ®­v ª‚ ˆƒ¢<  «… Q… ™…ÐL~1 ¼‚ ƒ µƒ` ¼‚ ƒ ™…ÐL›1 Á‚ ƒ ˆƒ ãX »ƒ¢  ™…ÐL.2¢¤ i ˆƒ ¶R »ƒ ™…ÐLå1 cc ²‚ ˆƒ .2 »ƒ ™…ÐLß1 ²‚ ˆƒ ãX »ƒ RfL+2¢§ i ˆƒ ¶R »ƒ ™…ÐL#2 cc ²‚ ˆƒ .2 »ƒ ™…ÐL2 ²‚ ˆƒ ãX »ƒ `fL+2¢  µƒ`L›1© ]ƒ ¼‚ ˆƒ Æ‚ ƒ ˆƒ N3 »ƒ é‚ òT®¬v ª‚ ˆƒ¢+  «… ˆƒ®¬v ª‚ ˆƒ¢-  «… Q… ™…ÐL†2 ¼‚ ƒ µƒ` ¼‚ ƒ ™…ÐL£2 Á‚ ƒ ˆƒ ãX »ƒ¢  ™…ÐLN3¢+  ˆƒ R »ƒ ™…ÐLù2 cc ²‚ ˆƒ N3 »ƒ ™…ÐLç2 ²‚ ˆƒ ãX »ƒ Á‚ ƒ ˆƒ vd »ƒLK3¢-  ˆƒ R »ƒ ™…ÐLC3 cc ²‚ ˆƒ N3 »ƒ ™…ÐL13 ²‚ ˆƒ ãX »ƒ Á‚ ƒ ˆƒ –d »ƒLK3¢  µƒ`L£2© ]ƒ ¼‚ ˆƒ Æ‚ ƒ ˆƒ Î4 »ƒ é‚ òT®¬v ª‚ ˆƒ¢*  «… ˆƒ®¬v ª‚ ˆƒ¢/  «… Q… ˆƒ®¬v ª‚ ˆƒ¢%  «… Q… ™…ÐL¼3 ¼‚ ƒ µƒ` ¼‚ ƒ ™…ÐLÙ3 Á‚ ƒ ˆƒ ãX »ƒ¢  ™…ÐLÎ4¢*  ˆƒ R »ƒ ™…ÐL#4 cc ²‚ ˆƒ N3 »ƒ ™…ÐL4 ²‚ ˆƒ ãX »ƒ ¶dLË4¢/  ˆƒ R »ƒ ™…ÐLs4 cc ²‚ ˆƒ Î4 »ƒ ™…ÐL[4 ²‚ ˆƒ ãX »ƒ ²‚ ˆƒ Æ‚ ƒ ˆƒ ¬e ¸ƒLË4¢%  ˆƒ R »ƒ ™…ÐLÃ4 cc ²‚ ˆƒ Î4 »ƒ ™…ÐL«4 ²‚ ˆƒ ãX »ƒ ²‚ ˆƒ Æ‚ ƒ ˆƒ êe ¸ƒLË4¢  µƒ`LÙ3© ]ƒ¢ª i ˆƒ ¶R »ƒ ™…ÐLr5 ·‚ ˆƒ Á‚ ƒ ˆƒ Î4 »ƒ é‚ ˆƒ¢   …ÐL5¢   ˆƒ ¸V »ƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ™…ÐL=5 cc ¼‚ ƒ ˆƒ ãX »ƒ ¼‚ ƒ ˆƒ |f »ƒ ¼‚ ƒ ˆƒ ‰X »ƒ¢  ¸ƒ`¢­ i ˆƒ ¶R »ƒ ™…ÐL6 ·‚ ˆƒ Á‚ ƒ ˆƒ Î4 »ƒ é‚ ˆƒ¢   …ÐL»5¢   ˆƒ ¸V »ƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ™…ÐLÜ5 cc ¼‚ ƒ ˆƒ ãX »ƒ ¼‚ ƒ ˆƒ g »ƒ ¼‚ ƒ ˆƒ ‰X »ƒ¢  ¸ƒ`¢-  ˆƒ R »ƒ ™…ÐLg6 ·‚ ˆƒ Á‚ ƒ ˆƒ Î4 »ƒ é‚ ˆƒ¢  «…ÐL\6 ¼‚ ƒ ˆƒ ãX »ƒ nf¢  ¸ƒ`¢*  ˆƒ R »ƒ ™…ÐLN7 ·‚ ˆƒ Á‚ ƒ ˆƒ Î4 »ƒ é‚ ˆƒ¢  «…ÐL²6 ¼‚ ƒ ˆƒ ãX »ƒ ¼‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚ ²‚ ˆƒ Á‚ ƒ ˆƒ¢  რ„ ƒ é‚ ˆƒ¢  «…ÐL)7 ¼‚ ƒ ˆƒ¢  რ„ ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ é‚ ¼‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚¢  ¸ƒ`¢&  ˆƒ R »ƒ ™…ÐL8 ·‚ ˆƒ Á‚ ƒ ˆƒ Î4 »ƒ é‚ ˆƒ¢   …ÐLš7¢   ˆƒ ¸V »ƒL8 ¼‚ ƒ ˆƒ¢  რ„ ƒ ™…ÐLÀ7¢  ¸ƒ` ²‚ ˆƒ Á‚ ƒ ˆƒ¢  რ„ ƒ é‚ ˆƒ Ýb »ƒ ¼‚ ƒ ˆƒ¢  რ„ ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ é‚¢  ¸ƒ` ·‚ ˆƒ Á‚ ƒ ˆƒ v9 »ƒ é‚¢° i ˆƒ ¶R »ƒ ™…ÐLÐ8 ·‚ ƒ ˆƒ¢   …ÐLk8¢   ˆƒ ¸V »ƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ™…ÐLŒ8 cc ¼‚ ƒ ˆƒ ãX »ƒ ¼‚ ƒ ˆƒ |f »ƒ ¼‚ ƒ ˆƒ ‰X »ƒ ¼‚ ƒ ˆƒ g »ƒ¢  ¸ƒ`¢³ i ˆƒ ¶R »ƒ ™…ÐLl9 ·‚ ƒ ˆƒ¢   …ÐL9¢   ˆƒ ¸V »ƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ™…ÐL(9 cc ¼‚ ƒ ˆƒ ãX »ƒ ¼‚ ƒ ˆƒ g »ƒ ¼‚ ƒ ˆƒ ‰X »ƒ ¼‚ ƒ ˆƒ |f »ƒ¢  ¸ƒ` ·‚ ƒ ¸ƒ`© ]ƒ ·‚ ˆƒ Á‚ ƒ ˆƒ -< »ƒ é‚ ²‚ ˆƒ Á‚ ƒ ˆƒ¢  რ„ ƒ é‚ òT®¬v ª‚ ˆƒ¢[   … ˆƒ®¬v ª‚ ˆƒ¢(   … 9… ™…ÐLË;¢  ™…ÐLË;¢[  ˆƒ R »ƒ ™…ÐL; ²‚ ƒ ˆƒ¢   …ÐL):¢  ˆƒ ¸V »ƒLŒ: ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   …ÐL]: ¼‚ ƒ ˆƒ ãX »ƒLŒ: ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  «…ÐLŒ:¢  ˆƒ ¸V »ƒ cc \*¢]  ˆƒ ÃT »ƒ ¼‚ ƒ ˆƒ vd »ƒ ¼‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚ ¼‚ ƒ ˆƒ¢  რ„ ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ é‚ ·‚ ˆƒ¢  é‚LÈ;¢(  ˆƒ R »ƒ ™…ÐL¾; ²‚ ƒ ˆƒ¢   …ÐLA;¢  ˆƒ ]? »ƒL‘; ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   …ÐLu; ²‚ ƒ ˆƒ ]? »ƒL‘; ¼‚ ƒ ˆƒ ãX »ƒ¢  ˆƒ ]? »ƒ ¼‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚ ·‚ ˆƒ¢  é‚LÈ; ·‚ ƒ ¸ƒ`Lã9 ²‚ ƒ ˆƒ¢   …ÐLê; ·‚ ƒ ¸ƒ` ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   …ÐL#< ²‚ ƒ ˆƒ Ýb »ƒ¢  ¸ƒ` ·‚ ƒ ¸ƒ`© ]ƒ¢(  ˆƒ R »ƒ ™…ÐLz< Ђ ˆƒ¢ Ò‚ ƒ ˆƒ Â* »ƒ é‚¢)  ˆƒ ÃT »ƒ Ђ ƒ© Eƒ` ²‚ ˆƒ ;K »ƒ ™…ÐLö> Æ‚ ˆƒ ·‚ ˆƒ ¬I »ƒ é‚ ˆƒ¢  «…ÐL‡= Æ‚ ƒ ˆƒ ‘] »ƒ¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ Ë‚ ƒ é‚¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ Ë‚ ƒ ˆƒ¢   „ ú‚ é‚ Æ‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   …ÐLQ=¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚ Æ‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   …ÐL}=¢ © Eƒ`¢ © Eƒ` Æ‚ ˆƒ ·‚ ˆƒ H »ƒ é‚ ˆƒ¢  «…ÐL€> Æ‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  «…ÐL€>¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ Ë‚ ƒ é‚¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚ Æ‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  «…ÐL9>¢ © Eƒ` Æ‚ ƒ ˆƒ Ýb »ƒ¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ Ë‚ ƒ ˆƒ¢   „ ú‚ é‚¢ © Eƒ` Æ‚ ˆƒ¢  ˆƒ¢  ˆƒ¢  ˆƒ Æ‚ ˆƒ ÔF© Eƒ é‚¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ Ë‚ ƒ é‚¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚¢ © Eƒ` Ë‚ ˆƒ O »ƒ ™…ÐLJ?¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ¢ Ò‚ ƒ ˆƒ¢  რ„ ˆƒ¢  é‚ é‚© Eƒ`¢  ˆƒ ¸V »ƒ© Eƒ`© ]ƒ òT ·‚ ˆƒ®¨v¬©v é‚®¬v ª‚ ˆƒ¢)  «…ÐL@®¬v ª‚ ˆƒ¢"   …ÐL®?¢"  ˆƒ /B »ƒL @®¬v ª‚ ˆƒ¢'   …ÐLÓ?¢'  ˆƒ /B »ƒL @®¬v ª‚ ˆƒ¢(   …ÐLî? „BL @®¬v ª‚ ˆƒ¢   …ÐL @L@L @ rULt?¢)  ˆƒ ÃT »ƒ ²‚ ˆƒ®¨v¬©v é‚ ·‚ ƒŽ¨vŒ©v òT Á‚ ƒ ˆƒ¢   …ÐLR@ cc ¼‚ ˆƒ¢  ˆƒ Ë‚ ƒ ˆƒ È@ ¸ƒ é‚ Á‚ ƒ ™…ÐL‘@ Á‚ ƒ ˆƒ î_ »ƒL”@ `®²v¬³v ˆƒ Á‚ ƒ „ ˆƒ ` »ƒŽ²vŒ³v ²‚ ƒŽ¨vŒ©v òT µƒ`© ]ƒ ²‚ ˆƒ®¨v¬©v é‚ hA ™…ÐLA ¼‚ ˆƒ Á‚ ƒ ˆƒ Á‚ ƒ ˆƒ È@ ¸ƒ é‚ ²‚ ƒŽ¨vŒ©v òT®¬v ª‚ ˆƒ¢)   …ÐL6A ¼‚ ƒ »ƒ` \* ·‚ ƒ ˆƒ¢   …ÐLQA žc cc ¼‚ ƒ ˆƒ¢  „ »ƒ`© ]ƒ òT®¬v ª‚ ˆƒ¢,  «… ˆƒ®¬v ª‚ ˆƒ¢)  «… Q… ™…ÐL B®¬v ª‚ ˆƒ¢"   …ÐLÃA¢"  ˆƒ /B »ƒLB®¬v ª‚ ˆƒ¢'   …ÐLèA¢'  ˆƒ /B »ƒLB®¬v ª‚ ˆƒ¢(   …ÐLB „BLB rULpA ²‚ ˆƒ®¬v ª‚ é‚ rU ²‚ ƒ ˆƒ¢,   … »ƒ` rU ˆƒ ·‚ ú‚ «…ÐL€B®¬v ª‚ ˆƒ¢\   …ÐL[B rU®¬v ª‚ ˆƒ¢   …ÐL}B¢  ˆƒ ¸V »ƒL/B rU`© ]ƒ ²‚ ˆƒ¢  é‚ rU ˆƒ¢(   …ÐLºB ²‚ ˆƒ ƒ %ƒ é‚LÞB®¬v ª‚ ˆƒ¢)   …ÐLÞB ²‚ ˆƒ ƒ 4ƒ é‚ ²‚ ƒ ˆƒ¢  ¶… ˆƒ®¬v ª‚ ˆƒ¢)  «… Q… ™…ðL–B rU »ƒ`© ]ƒ ™T ™…ÐL)C© Eƒ` Ë‚ ˆƒ¢  é‚¢*  ˆƒ R »ƒ ™…ÐL[C Ђ ˆƒ¢  é‚LhC Ђ ˆƒ¢  é‚ ²‚ ˆƒ ;K »ƒ ˆƒ¢   …ÐLC¢  ˆƒ ¸V »ƒ Æ‚ ˆƒ ·‚ ˆƒ H »ƒ é‚ ˆƒ¢  «…ÐL D Æ‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  «… ˆƒ Ë‚ ƒ ˆƒ¢   „ ú‚ ˆƒ¢   … 9… ™…ÐL D¢  ˆƒ ¸V »ƒ¢[  ˆƒ R »ƒ ™…ÐLYD Ë‚ ˆƒ ìS é‚ ˆƒ¢   …ÐLID Ђ ˆƒ¢  é‚LVD Ђ ˆƒ¢  é‚LD¢(  ˆƒ R »ƒ ™…ÐLD Ë‚ ˆƒ ·‚ ˆƒ { »ƒ é‚ Ð‚ ˆƒ¢  é‚ Ë‚ ƒ ˆƒ¢ Ò‚ ƒ ˆƒ¢ Ò‚ ƒ ˆƒ Á‚ ˆƒ ÔF© Eƒ Ђ ƒ ˆƒ¢   … ˆƒ Ђ ƒ ˆƒ¢   … Q… ™…ÐLñD© Eƒ`¢,  ˆƒ R »ƒ ™…ðLC oT© Eƒ`© ]ƒ ™T ™…ÐL%E© Eƒ`¢*  ˆƒ R »ƒ ™…ÐLJE Æ‚ ˆƒ¢  é‚LWE Æ‚ ˆƒ¢  é‚ ²‚ ˆƒ ;K »ƒ ˆƒ¢   …ÐLE¢  ˆƒ ¸V »ƒ ²‚ ˆƒ ¬I »ƒ ™…ÐL E¢  ˆƒ ¸V »ƒ¢[  ˆƒ R »ƒ ™…ÐL+F Ë‚ ˆƒ ìS é‚ ˆƒ¢   …ÐLíE Æ‚ ˆƒ¢  é‚ Ë‚ ˆƒ¢  é‚L(F Æ‚ ˆƒ¢  é‚ Ð‚ ƒ ˆƒ¢   …ÐL(F Ë‚ ˆƒ Ђ ƒ ˆƒ¢  0„ é‚LvF Ђ ƒ ˆƒ¢   … ˆƒ Ë‚ ƒ ˆƒ¢  «… Q… ™…ÐLiF Ë‚ ˆƒ¢  é‚LvF Ë‚ ˆƒ¢  é‚®´v¬µv ˆƒ Ђ ƒ „Ž´vŒµv®´v¬µv ˆƒ¢ Ò‚ ƒ ˆƒ Ђ ƒ ˆƒ Á‚ ˆƒ H© Eƒ¢,  ˆƒ R »ƒ ™…ðLE© Eƒ`© ]ƒ ·‚ ƒ ˆƒ H »ƒŽÊvŒËv ˆƒ¢  «…ÐLG®Êv¬Ëv »ƒ`®0v¬1v ˆƒ¢Ð l ˆƒ¢p  „ †ÐL3G¢  ˆƒ ¸V »ƒ ²‚ ˆƒ®0v¬1v 邎ÊvŒËv ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢  «…ÐL‡GLHG®Êv¬Ëv ˆƒ¢  „ ˆƒ Á‚ ú‚ Þ‚®Êv¬Ëv ˆƒ¢   „ ˆƒ Æ‚ ú‚ Þ‚ Æ‚ ƒ ˆƒ®Êv¬Ëv ˆƒ¢   „ ˆƒ ›V ¸ƒ®0v¬1v ˆƒ¢   „Ž0vŒ1v®Êv¬Ëv »ƒ`© ]ƒ ²‚ ˆƒ¢Ð l é‚ ²‚ ƒ ˆƒ®0v¬1v «…ÐLwH ²‚ ƒ ˆƒ ¼‚ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL[H ²‚ ƒ »ƒ` ²‚ ˆƒ ·‚ ƒ ˆƒ¢   „ é‚LH¢  »ƒ`© ]ƒ ·‚ ƒ ˆƒ ¬I »ƒŽÊvŒËv ˆƒ¢  «…ÐL²H®Êv¬Ëv »ƒ`®2v¬3v ˆƒ¢Ð l ˆƒ¢T  „ †ÐLÞH¢  ˆƒ ¸V »ƒ ²‚ ˆƒ®2v¬3v 邎ÊvŒËv ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚ ˆƒ¢  «…ÐL2ILóH®Êv¬Ëv ˆƒ¢  „ ˆƒ Á‚ ú‚ Þ‚®Êv¬Ëv ˆƒ¢   „ ˆƒ Æ‚ ú‚ Þ‚ Æ‚ ƒ ˆƒ®Êv¬Ëv ˆƒ¢   „ ˆƒ ›V ¸ƒ®2v¬3v ˆƒ¢   „Ž2vŒ3v®Êv¬Ëv »ƒ`© ]ƒ ²‚ ˆƒ¢Ð l ˆƒ¢|  „ é‚ ²‚ ƒ ˆƒ®2v¬3v «…ÐL,J ²‚ ƒ ˆƒ ¼‚ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLJ ²‚ ƒ »ƒ` ²‚ ˆƒ ·‚ ƒ ˆƒ¢   „ é‚LÈI¢  »ƒ`© ]ƒ®Tv¬Uv ˆƒ¢4 v ˆƒ¢   რ„ ÿ…ÐLhJ¢  ˆƒ ¸V »ƒ ²‚ ˆƒ¢  é‚ ²‚ ƒ ˆƒ¢  Û…ÐLÉJ®Tv¬Uv *ƒŽTvŒUv ;ƒ ˆƒ ¼‚ ƒ ˆƒ ¼‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ƒ é‚LuJ »ƒ` òJ ™…ÐLñJ®Tv¬Uv ˆƒ¢  რ„ŽTvŒUv`®Tv¬Uv ˆƒ¢4 v  …ÐLK¢  ˆƒ ¸V »ƒL+K®Tv¬Uv ˆƒ¢  რ„`®®v¬¯v %ƒŽ®vŒ¯v`© ]ƒ òT®¬v ª‚ ˆƒ ~ˆ »ƒ ˆƒ¢   … ˆƒ®¬v ª‚ ˆƒ¢_  «… Q… ™…ÐL‚K¢  »ƒ` ²‚ ˆƒ¢  é‚®¬v ª‚ ˆƒ îˆ »ƒ ˆƒ®¬v ª‚ ˆƒ¢_   … 9… ™…ÐLL ²‚ ƒ ˆƒ¢  Û…ÐLûK ·‚ ƒ ˆƒ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ „ ˆƒ®¬v ª‚ Þ‚ rULK ·‚ ƒ ˆƒ ·‚ ƒ „ ˆƒ¢  Þ‚¢  »ƒ`© ]ƒ ·‚ ˆƒ ·‚ ˆƒ¢  é‚ é‚ ·‚ ƒ ™…ÐL´L ·‚ ˆƒ¢  é‚¢+  ˆƒ R »ƒ ™…ÐL}L ·‚ ˆƒ¢  é‚¢-  ˆƒ R »ƒ ™…ÐL±L ²‚ ˆƒ ·‚ ƒ ‹… é‚ ·‚ ˆƒ¢  é‚L@L®¬v ª‚ ˆƒ ®ˆ »ƒ ˆƒ¢   …ÐLåL ¼‚ ƒ ˆƒ yO »ƒ ¸ƒ`¢0  ˆƒ R »ƒ ™…ÐLŸM¢x  ˆƒ R »ƒ ™…ÐLWM®¬v ª‚ ˆƒ ¾ˆ »ƒ ™…ÐLTM ·‚ ˆƒ ¼‚ ƒ ˆƒ¢  0„ ˆƒ WV ˆƒ %N »ƒ „ é‚LMLœM®¬v ª‚ ˆƒ çN »ƒ ™…ÐLœM ·‚ ˆƒ ¼‚ ƒ ˆƒ¢  0„ ˆƒ WV ˆƒ %N »ƒ „ é‚LWMLäM®¬v ª‚ ˆƒ ®ˆ »ƒ ™…ÐLäM ·‚ ˆƒ ¼‚ ƒ ˆƒ¢   0„ ˆƒ WV ˆƒ %N »ƒ „ é‚LŸM ²‚ ƒ ˆƒ¢  Û…ÐL N ·‚ ˆƒ ¼‚ ƒ ‹… é‚ ¼‚ ƒ ˆƒ ¼‚ ƒ é‚¢  ¸ƒ` ²‚ ú‚ ˆƒ ®ˆ »ƒ ™…ÐLMN ²‚ ú‚ ˆƒ¢0  „` ²‚ ú‚ ˆƒ¢A  Ð… ˆƒ ·‚ ú‚ ˆƒ¢F  Ã… Q… ™…ÐL–N¢   ˆƒ ·‚ ú‚ „ ˆƒ¢A  „` ²‚ ú‚ ˆƒ¢a  Ð… ˆƒ ·‚ ú‚ ˆƒ¢f  Ã… Q… ™…ÐLßN¢   ˆƒ ·‚ ú‚ „ ˆƒ¢a  „`¢  ‹…` ²‚ ú‚ ˆƒ¢0  Ð… ˆƒ ·‚ ú‚ ˆƒ¢8  Ã… Q…` ²‚ ƒ ˆƒ %L »ƒ ™…ÐL:O ²‚ ƒ ƒ ˆƒ °b »ƒLtO ²‚ ƒ ˆƒ ”Q »ƒ ™…ÐLoO ²‚ ƒ ƒ ˆƒ®°v¬±v ˆƒ c ¸ƒLtO¢ `¢ `© ]ƒ¢'  ˆƒ R »ƒ ˆƒ¢   …ÐL¤O¢ © Eƒ`®¬v ª‚ ˆƒ¢\   …ÐLÈO ²‚ ˆƒ P Þ‚LÔO ²‚ ˆƒ WV Þ‚®¬v ª‚ ˆƒ¢'  «…ÐLöO¢  ˆƒ ¸V »ƒ WV¢ Ò‚ ƒ ˆƒ ·‚ ú‚ é‚¢ © Eƒ`© ]ƒ WV®¬v ª‚ ˆƒ¢n   …ÐLDP ²‚ ˆƒ¢   é‚L‡Q®¬v ª‚ ˆƒ¢t   …ÐLiP ²‚ ˆƒ¢   é‚L‡Q®¬v ª‚ ˆƒ¢b   …ÐLŽP ²‚ ˆƒ¢  é‚L‡Q®¬v ª‚ ˆƒ¢r   …ÐL³P ²‚ ˆƒ¢   é‚L‡Q®¬v ª‚ ˆƒ¢f   …ÐLØP ²‚ ˆƒ¢   é‚L‡Q®¬v ª‚ ˆƒ¢\   …ÐLýP ²‚ ˆƒ¢\  é‚L‡Q®¬v ª‚ ˆƒ çN »ƒ ™…ÐLxQ ²‚ ˆƒ WV ˆƒ %N »ƒ é‚®¬v ª‚ ˆƒ çN »ƒ ™…ÐLnQ ²‚ ˆƒ ·‚ ƒ ˆƒ¢  0„ ˆƒ WV ˆƒ %N »ƒ „ é‚L)Q ²‚ ƒ »ƒ` ²‚ ˆƒ®¬v ª‚ é‚ WV ²‚ ƒ »ƒ`© ]ƒ¢"  ˆƒ R »ƒ ˆƒ¢   …ÐL¿Q¢ © Eƒ`¢ Ò‚ ƒ ˆƒ®Vv¬Wv é‚®¬v ª‚ ˆƒ¢"  «…ÐL]R®¬v ª‚ ˆƒ¢   …ÐLRL]RL3R®¬v ª‚ ˆƒ¢\   …ÐL'R ²‚ ˆƒ P Þ‚L3R ²‚ ˆƒ WV Þ‚®¼v¬½v ˆƒ ·‚ ú‚ ˆƒ æ‡ ¸ƒ®Vv¬Wv %ƒŽVvŒWvLÓQ WV®¼v¬½v ˆƒ¢  ˆƒ æ‡ ¸ƒ®Vv¬Wv %ƒŽVvŒWv¢ © Eƒ` òT®¬v ª‚ ˆƒ ·‚ ú‚ «…ÐL®R¢ ` rU¢ `© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ +‹ »ƒ é‚ òT ²‚ ƒ ˆƒ ¼‚ ƒ ˆƒ®¨v¬©v ˆƒ 8Œ µƒ ˆƒ¢  «…ÐLS¢  »ƒ`®¨v¬©v ˆƒ ·‚ ƒ „ލvŒ©v®¨v¬©v ú‚ެv¢  »ƒ`© ]ƒ òT ²‚ ˆƒ ¼‚ ƒ ˆƒ +‹ »ƒ é‚ ²‚ ƒ ˆƒ ¼‚ ƒ ˆƒ®¨v¬©v ˆƒ 8Œ µƒ ˆƒ¢  «…ÐL’S¢  »ƒ`®¨v¬©v ˆƒ ·‚ ƒ „ ú‚ ˆƒ îˆ »ƒ ™…ÐLÀS¢  »ƒ`®¨v¬©v ˆƒ ·‚ ƒ „ލvŒ©v®¨v¬©v ú‚ެv¢  »ƒ`© ]ƒ¢]  ˆƒ R »ƒ ™…ÐLT¢  »ƒ` ²‚ ˆƒ %L »ƒ ˆƒ¢   …ÐL6T¢  ˆƒ ¸V »ƒ ²‚ ƒ ˆƒ¢  Û…ÐLXT¢  ˆƒ ¸V »ƒ¢]  ˆƒ ÃT »ƒ ²‚ ƒ »ƒ`¢;  ˆƒ R »ƒ ˆƒ¢   …ÐL˜T¢  ˆƒ ¸V »ƒ` òT®¬v ª‚ ˆƒ¢;   … ˆƒ®¬v ª‚ ˆƒ¢   … 9…` òT ²‚ ú‚ ˆƒ R »ƒ ˆƒ¢   …ÐLñT¢  ˆƒ ¸V »ƒ`®¨v¬©v ú‚ ˆƒ Έ »ƒ ˆƒ®¨v¬©v ú‚ ˆƒ¢   … 9… ™…ÐLOU®¨v¬©v %ƒŽ¨vŒ©v 4ƒ ú‚ ˆƒ¢   …ÐLLU ÙULòT®¨v¬©v ú‚ެv®¨v¬©v ˆƒ¢  „ ú‚Ž­v`®¨v¬©v %ƒŽ¨vŒ©v ú‚ެv®¨v¬©v ˆƒ¢  „ ú‚Ž­v®¬v ª‚`®¨v¬©v ú‚ ˆƒ¢   …ÐLÕU®ºv¬»v ™…ÐLÏU¢ ` ÙUL¤U WV`®¾v¬¿v ˆƒ¢P  ˆƒ¢X v ˆƒ ®Ž µƒŽ¨vŒ©v ˆƒ¢   …ÐLV¢ ŽºvŒ»vL5V®Èv¬Év ™…ÐL5V®¨v¬©v ˆƒ µ[ »ƒ`¢X vލvŒ©v®¨v¬©v ˆƒ¢  Þ‚Ž­vެv`© ]ƒ®¨v¬©v ú‚ ˆƒ¢   …ÐL|V¢  »ƒ` ²‚ ˆƒ®¨v¬©v ú‚ é‚ rU ²‚ ƒ »ƒ` ²‚ ƒ ˆƒ ¼‚ ƒ é‚` ²‚ ƒ ƒ`© ]ƒ¢X v ˆƒ¢¶ i ˆƒ¢  ˆƒ `’ µƒ ²‚ ˆƒ¢X v é‚ ²‚ ƒ ˆƒ®¨v¬©v $†ÐLQW ²‚ ƒ ú‚ ˆƒ¢    …ÐL+W¢º i ˆƒ¢  ˆƒ `’ ¸ƒL?W¢¼ i ˆƒ¢  ˆƒ `’ ¸ƒ ²‚ ˆƒ ƒ %ƒ é‚LåV ·‚ ƒ ˆƒ¢¾ i ˆƒ¢  ˆƒ `’ µƒ¢  ‹… »ƒLo† »ƒ` ²‚ ƒ ˆƒ¢Ë i ˆƒ¢  ˆƒ `’ µƒ¢  ‹…Lo†`¢(  ˆƒ ÃT »ƒ \*¢)  ˆƒ ÃT »ƒ®Äv¬Åv ˆƒ¢   …ÐLëW ²‚ ƒ ˆƒ A` »ƒLúW ²‚ ƒ ˆƒ o` »ƒ` \*®Äv¬Åv ˆƒ¢   …ÐL%X ²‚ ƒ ˆƒ A` »ƒL4X ²‚ ƒ ˆƒ o` »ƒ`¢(  ˆƒ ÃT »ƒ \*¢)  ˆƒ ÃT »ƒ®Äv¬Åv ˆƒ¢   …ÐLyX ²‚ ƒ ˆƒ X` »ƒLˆX ²‚ ƒ ˆƒ †` »ƒ` ²‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ¢   …ÐLÀX ²‚ ƒ ˆƒ ì^ »ƒLâX ‡c ²‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ ˆ_ »ƒ` ²‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ¢  «… ˆƒ ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ¢   … Q… ™…ÐLCY ²‚ ƒ ˆƒ å\ »ƒLbY ²‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ »_ »ƒ`© ]ƒ®Vv¬Wv ™…ÐLZ®°v¬±v ˆƒ Î\ »ƒ®¼v¬½v ˆƒ Ç »ƒ¢á i ˆƒ¢ä i ˆƒ × ¸ƒŽ¼vŒ½v ˆƒ¢   …ÐLÊY¢ì i ˆƒ W »ƒ ·‚ ˆƒ¢  é‚ ·‚ ƒ ˆƒ®Vv¬Wv Û…ÐLZ®¼v¬½v ˆƒ ¾‡ »ƒ ˆƒ ªh »ƒ ·‚ ˆƒ ƒ %ƒ é‚L×Y¢ô i ˆƒ®Àv¬Áv ˆƒ `’ ¸ƒ ¸ƒ`© ]ƒ ²‚ ˆƒ¢  é‚¢ú i ˆƒ®Àv¬Áv ˆƒ `’ ¸ƒ¢Ð lŽÊvŒËv®Êv¬Ëv ˆƒ®0v¬1v $†ÐL’[®Êv¬Ëv ˆƒ¢  „ ú‚ ˆƒ¢  «…ÐLy[®Êv¬Ëv ˆƒ¢ j ˆƒ®Àv¬Áv ˆƒ `’ µƒ ·‚ ˆƒ®Êv¬Ëv ˆƒ¢   „ ˆƒ ®V »ƒ é‚®Êv¬Ëv ˆƒ¢   „ ú‚ ˆƒ¢   … ˆƒ®Êv¬Ëv ˆƒ¢  „ ú‚ ˆƒ¢   … 9… ™…ÐL?[ ·‚ ˆƒ ¼‚ ƒ ˆƒ¢  0„ é‚ ²‚ ƒ ˆƒ¢  j ˆƒ®Àv¬Áv ˆƒ `’ µƒ ²‚ ˆƒ ·‚ ƒ ˆƒ Á‚ ƒ „ é‚®Êv¬Ëv ˆƒ¢   „ŽÊvŒËvLdZ ²‚ ƒ ˆƒ¢ j ˆƒ®Àv¬Áv ˆƒ `’ µƒ ¸ƒ` ²‚ ƒ ˆƒ¢' j ˆƒ®Àv¬Áv ˆƒ `’ µƒ` ²‚ ƒ ˆƒ¢, j ˆƒ®Àv¬Áv ˆƒ `’ µƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ®Àv¬Áv ˆƒ `’ µƒ¢ ŽÄvŒÅv` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ®Àv¬Áv ˆƒ `’ µƒ¢ ŽÄvŒÅv` ‡c ²‚ ƒ ˆƒ `\ »ƒ` ²‚ ƒ ˆƒ¢1 j ˆƒ®Àv¬Áv ˆƒ `’ µƒ¢ ŽÄvŒÅv` ‡c ²‚ ƒ ˆƒ¢: j ˆƒ®Àv¬Áv ˆƒ `’ µƒ¢ ŽÄvŒÅv` ²‚ ƒ ˆƒ¢C j ˆƒ !\ ¸ƒ` ²‚ ƒ ˆƒ¢H j ˆƒ õ[ ¸ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ é‚ ²‚ ƒ ˆƒ¢M j ˆƒ !\ ¸ƒ ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢  «… ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ ˆƒ¢   … Q… ™…ÐLw]¢W j ˆƒ `\ »ƒL] ²‚ ƒ ˆƒ¢[ j ˆƒ !\ ¸ƒ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ¢   „ ˆƒ ®V »ƒ é‚ ²‚ ƒ ˆƒ¢ € Q… ™…ÐLö] ²‚ ˆƒ ·‚ ƒ ˆƒ¢ÿ ÿ E… ˆƒ¢  „ ‹… é‚ ²‚ ˆƒ ·‚ ƒ ˆƒ®²v¬³v „ é‚ ²‚ ƒ ˆƒ¢   …ÐL6^¢g j ˆƒ `\ »ƒLè^ ²‚ ƒ ˆƒ¢  Û…ÐLÌ^ ²‚ ƒ ˆƒ¢   Ã… ˆƒ ·‚ ƒ ˆƒ¢  À„ ˆƒ¢   … Q… ™…ÐL¦^ ²‚ ƒ ˆƒ¢  d„ ˆƒ¢l j ˆƒ õ[ ¸ƒLÉ^ ²‚ ƒ ˆƒ¢z j ˆƒ õ[ ¸ƒ¢„ j ˆƒ `\ »ƒLè^ ²‚ ƒ ˆƒ °b »ƒ¢‹ j ˆƒ `\ »ƒ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ é‚ ²‚ ƒ ˆƒ¢’ j ˆƒ !\ ¸ƒ ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   … ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ ˆƒ¢  «… 9… ™…ÐL„_ ²‚ ƒ ˆƒ¢œ j ˆƒ !\ ¸ƒ »ƒ` ²‚ ú‚ ˆƒ¢   …ÐL­_¢¨ j ˆƒ `\ »ƒLº_¢¯ j ˆƒ `\ »ƒ` ²‚ ú‚ ˆƒ¢   …ÐLà_¢¶ j ˆƒ `\ »ƒLí_¢½ j ˆƒ `\ »ƒ` ²‚ ƒ ˆƒ¢Ä j ˆƒ !\ ¸ƒ`¢Î j ˆƒ M\ »ƒ` ²‚ ƒ ˆƒ¢Ô j ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢Þ j ˆƒ !\ ¸ƒ` ²‚ ƒ ˆƒ¢è j ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢û j ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢ k ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢) k ˆƒ õ[ ¸ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ®²v¬³v „ é‚ ²‚ ƒ ˆƒ¢   …ÐLÜ` ·‚ ƒ »ƒ` ²‚ ƒ ˆƒ¢  Û…ÐLa ²‚ ƒ ˆƒ a »ƒLa ²‚ ƒ ˆƒ ²a »ƒ ·‚ ƒ »ƒ` ²‚ ˆƒ ·‚ ƒ ˆƒ¢ÿ ÿ Q… ˆƒ¢ÿ ÿ E… ˆƒ¢  „ é‚ ˆƒ¢ÿ  Û…ÐLqa ²‚ ƒ ˆƒ¢D k ˆƒ õ[ ¸ƒL±a ²‚ ƒ ˆƒ¢  ]… ˆƒ¢Z k ˆƒ õ[ ¸ƒ ²‚ ƒ ˆƒ¢ÿ  Q… ˆƒ¢o k ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢ÿ  Û…ÐLVb ²‚ ƒ ˆƒ¢   …ÐLìa¢… k ˆƒ `\ »ƒLSb ²‚ ƒ ˆƒ¢   … ˆƒ ·‚ ƒ ˆƒ¢   … 9… ™…ÐL=b ²‚ ƒ ˆƒ¢  ]… ˆƒ¢Š k ˆƒ õ[ ¸ƒLSb ²‚ ƒ ˆƒ¢— k ˆƒ õ[ ¸ƒL–b ²‚ ƒ ˆƒ¢  ]… ˆƒ¢­ k ˆƒ õ[ ¸ƒ ²‚ ƒ ˆƒ¢ÿ  Q… ˆƒ¢Â k ˆƒ õ[ ¸ƒ`¢ ŽÄvŒÅv`¢Ø k ˆƒ `\ »ƒ` ²‚ ƒ ˆƒ¢Ý k ˆƒ õ[ ¸ƒ ²‚ ƒ ˆƒ¢è k ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢ó k ˆƒ !\ ¸ƒ ²‚ ƒ ˆƒ¢ÿ k ˆƒ !\ ¸ƒ` ²‚ ƒ ˆƒ¢  l ˆƒ õ[ ¸ƒ ·‚ ƒ ˆƒ¢ l ˆƒ õ[ ¸ƒ ²‚ ƒ ˆƒ¢ l ˆƒ õ[ ¸ƒ ·‚ ƒ ˆƒ¢' l ˆƒ õ[ ¸ƒ`¢+ l ˆƒ `\ »ƒ®²v¬³v ˆƒ¢  „޲vŒ³v`®²v¬³v ˆƒ¢  „޲vŒ³v`¢0 l ˆƒ `\ »ƒ`¢8 l ˆƒ Õ[ »ƒ`¢< l ˆƒ Õ[ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ é‚ ˆƒ¢  «…ÐLrd ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   … ˆƒ ·‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   … 9… ™…ÐLrd ²‚ ƒ ˆƒ¢   „ ú‚ ˆƒ¢   …ÐLrd¢F l ˆƒ `\ »ƒ »ƒ` ‡c ²‚ ƒ ˆƒ Èc »ƒ¢M l ˆƒ `\ »ƒ` ‡c ²‚ ƒ ˆƒ Èc »ƒ¢Q l ˆƒ `\ »ƒ` ‡c¢U l ˆƒ `\ »ƒ`© ]ƒ Á‚ ˆƒ Ë‚ ƒ ˆƒ¢  რ„ ƒ é‚ ˆƒ¢  «…ÐLe ·‚ ˆƒ Æ‚ ƒ ˆƒ¢  „ ú‚ é‚L&e ·‚ ˆƒ¢  é‚ ¼‚ ˆƒ Ђ ƒ ˆƒ¢  რ„ ƒ é‚ ˆƒ¢  «…ÐLse ²‚ ˆƒ Á‚ ƒ ˆƒ¢  „ ú‚ é‚L€e ²‚ ˆƒ¢  é‚ ·‚ ƒ ˆƒ¢   … ˆƒ ·‚ ƒ ˆƒ¢   … 9…© Eƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ Çd ¸ƒ ™…ÐLÜe¢Z l ˆƒ M\ »ƒLée¢_ l ˆƒ M\ »ƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ Çd ¸ƒ ™…ÐLf¢c l ˆƒ M\ »ƒL'f¢h l ˆƒ M\ »ƒ`¢l l ˆƒ M\ »ƒ`¢o l ˆƒ M\ »ƒ`¢s l ˆƒ M\ »ƒ`¢x l ˆƒ M\ »ƒ`¢} l ˆƒ M\ »ƒ`¢‚ l ˆƒ `\ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ é‚ ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   … ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ ˆƒ¢   … Q… ™…ÐLøf¢† l ˆƒ `\ »ƒLg¢‹ l ˆƒ `\ »ƒ »ƒ`© ]ƒ ²‚ ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ é‚ ²‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢   … ˆƒ ·‚ ƒ ˆƒ¢   „ ú‚ ˆƒ¢   … Q… ™…ÐL…g¢ l ˆƒ `\ »ƒL’g¢• l ˆƒ `\ »ƒ »ƒ`¢š l ˆƒ Š\ »ƒ`¢ l ˆƒ Š\ »ƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ Çd ¸ƒ ™…ÐLâg¢  l ˆƒ Š\ »ƒLïg¢¤ l ˆƒ Š\ »ƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ Çd ¸ƒ ™…ÐL h¢§ l ˆƒ Š\ »ƒL-h¢« l ˆƒ Š\ »ƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ Çd ¸ƒ ™…ÐL^h¢® l ˆƒ Š\ »ƒLkh¢² l ˆƒ Š\ »ƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ Çd ¸ƒ ™…ÐLœh¢µ l ˆƒ Š\ »ƒL©h¢¹ l ˆƒ Š\ »ƒ` ²‚ ú‚ ˆƒ¢¼ l ˆƒ õ[ ¸ƒ` ²‚ ƒ ˆƒ¢Ç l ˆƒ õ[ ¸ƒ`¢ ŽÄvŒÅv`-Cwblitfilelitfilerwusage: tccom [-C] infile [outfile] charintextern%s maincharintcharintifwhilefordogotoreturnbreakcontinueexitelsewhilenull expression ==!=<=>=>><<++--++-- %s ^ error: %d tccom: can't open %s rblitfilelitfile~eot ~data =~eot _%s =~data+%u ~eod =~data+%u ; %s %s jsr %s jsr %s _%s ~%d ldx _%s ext ldy _%s+1 addr jsr addr_%d ldx #%d addr_baddr_w stx _%s sty _%s+1 sind_bsind_wlind_blind_w jsr _%s scall jmp ~%d jmp _%s bne *+5 jmp ~%d beq *+5 jmp ~%d jsr nz bne *+5 jmp ~%d jsr nz beq *+5 jmp ~%d lda #%d jsr sdec_b lda #%d sta asave lda #%d jsr sdec_w drop jsr drop%d lda #%d jsr sinc_b lda #%d sta asave lda #%d jsr sinc_w swap ldx #<%u ldy #>%u ldx #<_%s ldy #>_%s ldx #<~%d+%u ldy #>~%d+%u pushxchangertsjmp _exitscale2addsubmultudivdivumodmodorxorcandcasrcaslneginc2inc1dec2dec1eqneultltuleleugtgtugege .byte %d *=*+%u ©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª¢ ŽÈvŒÉv ·‚ ƒ ˆƒ¢  ჩü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª¢ Ž]Œ]¢ Ž]Œ]¢ Ž]Œ]¢ Ž]Œ]¢° < ˆƒ¢   „ŽRLŒSL¢T L ˆƒ¢   „Žö[Œ÷[ È ·‚ ƒ ˆƒ¢  რ„ ƒ ƒ ˆƒ¢ÿ  Q… ˆƒ¢-   …ÐLƒ ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ¢  „ެ9Œ­9®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ ˆƒ¢D   …ÐL}¢0 < ˆƒ 0$ »ƒ ˆƒ¢   …ÐL £®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ ˆƒ¢=   …ÐLE®¬9¬­9 ˆƒ¢0 < ˆƒ ©/ ¸ƒLY¢I 6 ˆƒ¢0 < ˆƒ ©/ ¸ƒ ²‚ ˆƒ ƒ 4ƒ é‚ ·‚ ˆƒ ƒ *ƒ é‚ ;ƒL€ £Lm ²‚ ƒ ˆƒ¢  Û… ˆƒ ·‚ ƒ ˆƒ¢  ¶… 9… ™…ÐL´ £¢J 6 ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ × ¸ƒŽ]Œ] ˆƒ¢   …ÐL ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ þ5 »ƒ ²‚ ƒ ˆƒ¢   …ÐL0¢ Ž]Œ]LŠ¢L 6 ˆƒ ¼‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ × ¸ƒŽ]Œ] ˆƒ¢   …ÐLŠ ·‚ ƒ ˆƒ¢  რ„ ƒ ˆƒ þ5 »ƒ ±®]¬] ˆƒ Ç »ƒ¢ Lo†¢N 6 ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ _ »ƒ`© ]ƒ¢T LŽô[Œõ[¢° <ŽPLŒQL ²‚ ˆƒ¢  é‚ ²‚ ƒ ˆƒ¢  Û…ÐL/¢ ] ˆƒ ·‚ ˆƒ ƒ %ƒ é‚ 4ƒ რ„ ˆƒ¢  é‚Lî »ƒ`¢® 9 ˆƒ¢{ 6 ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ _ »ƒ`®]¬] ˆƒ¢  «…ÐLƒ®]¬] ˆƒ Ç »ƒ®]¬] ˆƒ¢  «…ÐL§®]¬] ˆƒ Ç »ƒ ²‚ ƒLo†`®]¬] ™…ÐLu ,"¢  ˆƒ¢ 6 ˆƒ Û ¸ƒ ™…ÐLä ,Lr¢  ˆƒ¢† 6 ˆƒ Û ¸ƒ ™…ÐL ù,Lr¢  ˆƒ¢Ž 6 ˆƒ Û ¸ƒ ™…ÐL(LuLr¢  ˆƒ¢” 6 ˆƒ Û ¸ƒ ™…ÐLJLuLr¢  ˆƒ¢› 6 ˆƒ Û ¸ƒ ™…ÐLl +Lr # vL±`¢® 9ެ9Œ­9¢  ˆƒ¢£ 6 ˆƒ Û ¸ƒ ™…ÐL¢ wLÚ¢  ˆƒ¢¬ 6 ˆƒ Û ¸ƒ ™…ÐLÄ ì-LÚ®]¬] ˆƒ¢® 9 ˆƒ ÿ ¸ƒ` ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ®¬9¬­9 ˆƒ 8Œ µƒ ˆƒ¢  «…ÐL¢ `®¬9¬­9 ˆƒ ¼‚ ƒ „ެ9Œ­9¢ `®¬9¬­9 ú‚ ˆƒ¢    … ˆƒ®¬9¬­9 ú‚ ˆƒ¢    … 9… ™…ÐLv®¬9¬­9 %ƒŽ¬9Œ­9 4ƒL-`© ]ƒ®]¬] ˆƒ¢  Ð…ÐLµ¢± 6 ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ _ »ƒ -¢€ Ò‚ ˆƒ®¬9¬­9 ú‚ Þ‚¢€ Ò‚ ú‚ ˆƒ¢"  «… ˆƒ¢‚ Ò‚ ú‚ ˆƒ¢<  «… Q… ™…ÐL+®¬9¬­9 ˆƒ¢Ð 6 ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ _ »ƒ¢ø \ ˆƒ®]¬] %ƒŽ]Œ] 4ƒ რ„ ˆƒ®]¬] é‚¢è 6 ˆƒ¢0 < ˆƒ  »ƒ ˆƒ × ¸ƒŽ]Œ] ˆƒ¢   …ÐL ¢€ Ò‚ ú‚ ˆƒ¢<   …ÐLó¢ê 6 ˆƒ ·‚ ˆƒ ÕŠ ¸ƒ¢0 < ˆƒ ·‚ ˆƒ Ù‰ ¸ƒ¢ë 6 ˆƒ ·‚ ˆƒ × ¸ƒŽ]Œ] ˆƒ¢  «…ÐLó© Eƒ`¢€ Ò‚ ú‚ ˆƒ¢0 < ˆƒ ñ ¸ƒ© Eƒ`© ]ƒ¢ Ò‚ ˆƒ¢ Ò‚ ƒ é‚ ²‚ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚ ²‚ ú‚ ˆƒ¢<   …ÐLi ²‚ ˆƒ¢>  Þ‚®¬9¬­9 ú‚ ˆƒ ·‚ ú‚ «… ˆƒ®¬9¬­9 ú‚ ˆƒ¢   «… Q… ™…ÐLÑ ¢ Ò‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚Li ¢ Ò‚ ƒ ˆƒ¢  Þ‚¢ Ò‚ ƒ© Eƒ`©‚ ]ƒ¢€ Ò‚ ˆƒ¢„ Ò‚ ƒ é‚¢€ Ò‚ ƒ ú‚ ™…ÐL0!¢€ Ò‚ ˆƒ ƒ %ƒ é‚L !¢€ Ò‚ ƒ ˆƒ¢  „ ú‚ ˆƒ¢.   …ÐLp!¢€ Ò‚ ƒ ˆƒ¢  „ ˆƒ¢/  Þ‚¢í 6 ˆƒ¢„ Ò‚ ƒ ˆƒ × ¸ƒŽ]Œ] ˆƒ¢   …ÐL&"¢„ Ò‚ ú‚ ˆƒ¢"   …ÐLÈ!¢‚ Ò‚ ƒ ˆƒ þ5 »ƒL&"¢ï 6 ˆƒ ·‚ ˆƒ ÕŠ ¸ƒ¢‚ Ò‚ ƒ ˆƒ ·‚ ˆƒ Ù‰ ¸ƒ¢ð 6 ˆƒ ·‚ ˆƒ × ¸ƒŽ]Œ] ˆƒ¢   …ÐL&" ²‚ ˆƒ þ5 »ƒ©‚ Eƒ`®]¬] ™…ÐLë"®]¬] ˆƒ¢  ˆƒ¢¬ 8 ˆƒ ®Ž µƒ ™…ÐLe"Lë"Lè"¢¬ 8 ˆƒ¢  „ ˆƒ¢   Þ‚¢¬ 8 ˆƒ¢  „ ˆƒ¢  Þ‚®]¬] ˆƒ Ç »ƒ®]¬] 4ƒŽ]Œ] ˆƒ¢   …ÐLÌ"¢ Ž]Œ]¢ø \ ˆƒ®]¬] რ„ ƒŽ]Œ]L,"¢® 9Ž®:Œ¯:¢¬ 8ެ9Œ­9`®¬9¬­9 ú‚ ˆƒ¢   «…ÐL$¢0 < ˆƒ 0$ »ƒ ™…ÐL=#¢0 < ˆƒ Í$ »ƒL$®¬9¬­9 ú‚ ˆƒ¢"   … ˆƒ®¬9¬­9 ú‚ ˆƒ¢'   … 9… ™…ÐLw# ¸)L$¢  ˆƒ¢ò 6 ˆƒ Û ¸ƒ ™…ÐL™# Þ*L$®¬9¬­9 ú‚ ˆƒ¢    … ˆƒ®¬9¬­9 ú‚ ˆƒ¢    … 9… ™…ÐLÓ# 7+L$®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚L#®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ¢   Þ‚®®:¬¯: ˆƒ¢  Þ‚`© ]ƒ ²‚ ˆƒ ¼‚ ƒ é‚®¬9¬­9 ú‚ ˆƒ îˆ »ƒ ˆƒ®¬9¬­9 ú‚ ˆƒ¢_   … 9… ™…ÐL§$ ²‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚LD$ ²‚ ƒ ˆƒ¢  Þ‚ ²‚ ƒ ˆƒ ¼‚ ƒ „ »ƒ`© ]ƒ ²‚ ˆƒ¢  é‚ ·‚ ˆƒ¢  é‚ Æ‚ ˆƒ Ђ ƒ ˆƒ ]5 »ƒ é‚ ˆƒ¢  «…ÐLÈ& Á‚ ˆƒ Ë‚ ƒ ˆƒ¢  „ ˆƒ ?6 »ƒ é‚®¬9¬­9 ú‚ ˆƒ¢(   …ÐLY% ·‚ ˆƒ ' é‚ ¼‚ ˆƒ®®:¬¯: é‚ Á‚ ƒ ú‚ ™…ÐLX& Á‚ ƒ ú‚ ˆƒ ¼‚ ƒ Ã…ÐL(&¢Ž _ ˆƒ Æ‚ ƒ ú‚ ˆƒ¢  „ რ„ ƒ ˆƒ®®:¬¯: ˆƒ ÕŠ ¸ƒ®®:¬¯: ˆƒ¢Ž _ ˆƒ Ë‚ ƒ ú‚ ˆƒ¢  „ რ„ ƒ ˆƒ +‹ »ƒ „Ž®:Œ¯: Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ²‚ ˆƒ¢  é‚LU&®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ Æ‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚Lh% ²‚ ƒ ˆƒ¢   …ÐLÅ&®¬9¬­9 ˆƒ®®:¬¯: ˆƒ ÕŠ ¸ƒ¢® 9 ˆƒ¢¬ 8 ˆƒ ÕŠ ¸ƒ ¼‚ ƒŽ®:Œ¯:¢¬ 8 ˆƒ®®:¬¯: ˆƒ¢® 9 „ „ެ9Œ­9L ' Ë‚ ƒ ú‚ ™…ÐL '®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ Ђ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚LÈ&© Eƒ`©…© mƒ¢  Ô‚ ˆƒ¢  _ é‚¢ ŽÎ_ŒÏ_¢  Ô‚ ˆƒ¢  é‚®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ -®¬9¬­9 ú‚ ˆƒ¢)  «…ÐL–)¢  Ô‚ ˆƒ ·‚ é‚¢  Ô‚ ƒ ˆƒ¢  ¶… ˆƒ®¬9¬­9 ú‚ ˆƒ¢,  «… ˆƒ®¬9¬­9 ú‚ ˆƒ¢)  «… Q… 9… ™…ÐLŽ(®¬9¬­9 ú‚ ˆƒ¢(   …ÐLý'¢  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ®¬9¬­9 ú‚ ˆƒ¢)   …ÐL+(¢  Ô‚ ˆƒ ƒ 4ƒ é‚ %ƒ®¬9¬­9 ú‚ ˆƒ¢    …ÐLZ(¢õ 6 ˆƒ¢  ˆƒ `’ ¸ƒ 3¢  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚L'¢  Ô‚ ƒ ˆƒ¢  Þ‚¢Ž _ ˆƒ®Î_¬Ï_ %ƒŽÎ_ŒÏ_ 4ƒ რ„ ˆƒ¢  Ô‚ ƒ é‚ ²‚ ˆƒ¢  Ô‚ ƒ ˆƒ ÕŠ ¸ƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ¢  Ô‚ ƒ ˆƒ +‹ »ƒ „ é‚¢  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚®Î_¬Ï_ ˆƒ¢   ¶…ÐLf)¢ 7 ˆƒ¢  ˆƒ `’ ¸ƒ 3®¬9¬­9 ú‚ ˆƒ¢)  «…ÐL)®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ -LY'®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ®Î_¬Ï_©…© Qƒ`© ]ƒ ²‚ ˆƒ®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚ Þ‚®¬9¬­9 ú‚ ˆƒ ·‚ ú‚ «…ÐL«*®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ®¬9¬­9 ú‚ Þ‚ ˆƒ¢   …ÐLW*¢* 7 ˆƒ¢  ˆƒ `’ ¸ƒ 3L¨*®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ ˆƒ¢\   …ÐL¨*®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚Ló)®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚© Eƒ`®]¬] ˆƒ¢   …ÐL'+ ÷. ˆƒ¢*   … ˆƒ®¬9¬­9 ú‚ ˆƒ¢/   … Q… ™…ÐL$+L'+LÞ*®¬9¬­9 %ƒŽ¬9Œ­9`®®:¬¯: %ƒŽ®:Œ¯: 4ƒ ˆƒ¢   Þ‚®¬9¬­9 ú‚ ˆƒ¢    … ˆƒ®¬9¬­9 ú‚ ˆƒ¢    … 9… ™…ÐLœ+®¬9¬­9 %ƒŽ¬9Œ­9 4ƒLS+`© ]ƒ -¢° ; ˆƒ 0$ »ƒ ˆƒ¢   …ÐLÛ+¢C 7 ˆƒ¢  ˆƒ `’ ¸ƒ 3L , #¢® 9ެ9Œ­9¢° : ˆƒ è1 »ƒ¢° : ˆƒ¢° ; ˆƒ ©/ ¸ƒ »ƒ` -¢0 < ˆƒ 0$ »ƒ ˆƒ¢   …ÐLC,¢^ 7 ˆƒ¢  ˆƒ `’ ¸ƒ 3¢0 < ˆƒ ]5 »ƒ ™…ÐL­, ±¢¬ 8ެ9Œ­9¢  ˆƒ¢~ 7 ˆƒ Û ¸ƒ ™…ÐLª,¢  ˆƒ¢„ 7 ˆƒ Û ¸ƒ ˆƒ¢   …ÐLª, ,"L,Lø,¢  ˆƒ¢‹ 7 ˆƒ Û ¸ƒ ˆƒ¢   …ÐLø,¢  ˆƒ¢’ 7 ˆƒ Û ¸ƒ ™…ÐLò, ±Lø, ,"L­,` -¢0 < ˆƒ 0$ »ƒ ˆƒ¢   …ÐL/-¢˜ 7 ˆƒ¢  ˆƒ `’ ¸ƒ 3¢0 < ˆƒ ]5 »ƒ ˆƒ¢   …ÐL - ±¢¬ 8ެ9Œ­9¢  ˆƒ¢¹ 7 ˆƒ Û ¸ƒ ™…ÐL-¢  ˆƒ¢¿ 7 ˆƒ Û ¸ƒ ˆƒ¢   …ÐL- ,"Lt-Lë-¢  ˆƒ¢Æ 7 ˆƒ Û ¸ƒ ˆƒ¢   …ÐLë-¢  ˆƒ¢Í 7 ˆƒ Û ¸ƒ ™…ÐLå- ±Lë- ,"L -`© ]ƒ -®¬9¬­9 ú‚ ˆƒ îˆ »ƒ ˆƒ¢   …ÐL,.¢Ó 7 ˆƒ¢  ˆƒ `’ ¸ƒ 3 ²‚ ˆƒ®¬9¬­9 ˆƒ )© »ƒ é‚ ˆƒ¢  «…ÐL¨. ±¢¬ 8ެ9Œ­9¢  ˆƒ¢ð 7 ˆƒ Û ¸ƒ ™…ÐL¥.¢  ˆƒ¢ö 7 ˆƒ Û ¸ƒ ˆƒ¢   …ÐL¥. ,"L|.Ló.¢  ˆƒ¢ý 7 ˆƒ Û ¸ƒ ˆƒ¢   …ÐLó.¢  ˆƒ¢ 8 ˆƒ Û ¸ƒ ™…ÐLí. ±Ló. ,"L¨. »ƒ`®¬9¬­9 ú‚ ˆƒ¢   …ÐL/ ,"®]¬] ™…ÐL%/¢ `®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚`© ]ƒ ²‚ ˆƒ¢  é‚ ·‚ ƒ ú‚ ™…ÐLŸ/ ²‚ ˆƒ¢  ˆƒ ¼‚ ƒ 0„ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ „ ˆƒ¢  À„ é‚LM/ ²‚ ƒ »ƒ`© ]ƒ ·‚ ˆƒ Ë‚ ƒ ˆƒ +‹ »ƒ ˆƒ¢  „ é‚®ô[¬õ[ ˆƒ ¼‚ ƒ „ ˆƒ®ö[¬÷[ ÿ…ÐL0¢  8 ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ _ »ƒ®PL¬QL ˆƒ Ђ ƒ ˆƒ +‹ »ƒ „ ˆƒ®RL¬SL ÿ…ÐLg0¢# 8 ˆƒ¢  ˆƒ `’ ¸ƒ¢  ‹… ˆƒ _ »ƒ Æ‚ ƒ ˆƒ ]5 »ƒ ˆƒ¢  «…ÐL›0 Æ‚ ƒ ˆƒ¢F 8 ˆƒ ’ ¸ƒ ²‚ ˆƒ Ë‚ ƒ ˆƒ ;/ »ƒ é‚ Á‚ ˆƒ®ô[¬õ[ é‚¢ ] ˆƒ ·‚ ƒ რ„ ƒ ˆƒ Æ‚ ƒ ˆƒ¢  „ ˆƒ ,6 ¸ƒ¢ ] ˆƒ ·‚ ƒ რ„ ˆƒ Æ‚ ƒ é‚®PL¬QL ˆƒ Æ‚ ƒ ˆƒ¢  „ ˆƒ ,6 ¸ƒ ¼‚ ˆƒ Ђ ƒ é‚ ¼‚ ƒ ú‚ ˆƒ¢  «…ÐLŒ1®PL¬QL %ƒŽPLŒQL 4ƒ ˆƒ Á‚ ˆƒ ƒ %ƒ é‚ 4ƒ ú‚ Þ‚LD1®PL¬QL %ƒŽPLŒQL 4ƒ ˆƒ¢  Þ‚ Æ‚ ƒ ˆƒ Æ‚ ƒ ˆƒ¢  „ ˆƒ ÕŠ ¸ƒ Á‚ ƒ ˆƒ ¼‚ ƒ „Žô[Œõ[© Eƒ`©…© mƒ¢ ŽÎ_ŒÏ_®¬9¬­9 ú‚ ˆƒ¢(   …ÐL2 Ï3 -®¬9¬­9 ú‚ ˆƒ¢   «…ÐL±3 ²‚ ˆƒ 0$ »ƒ ˆƒ¢   …ÐL€2¢  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ ú‚ Þ‚L®3¢  Ô‚ ˆƒ¢  é‚¢  Ô‚ ˆƒ¢  é‚¢  Ô‚ ƒ ˆƒ®Î_¬Ï_ Û…ÐLL3 ²‚ ˆƒ¢Ž _ ˆƒ¢  Ô‚ ƒ რ„ ƒ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐL63¢  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Ô‚ ƒ ˆƒ¢  „ Þ‚¢  Ô‚ ˆƒ¢  é‚¢  Ô‚ ˆƒ ƒ %ƒ é‚L¢2¢  Ô‚ ƒ ˆƒ¢   …ÐL®3 ²‚ ˆƒ¢  Ô‚ ƒ ˆƒ ÕŠ ¸ƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ¢  Ô‚ ƒ ˆƒ +‹ »ƒ „ é‚L2¢  Ô‚ ƒ ˆƒ¢  Þ‚©…© Qƒ`©…© mƒ¢  Ô‚ ˆƒ¢  _ é‚®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ -®¬9¬­9 ú‚ ˆƒ¢)  «…ÐLA5 ²‚ ˆƒ 0$ »ƒ ˆƒ¢   …ÐLQ4®¬9¬­9 ˆƒ¢` 8 ˆƒ¢  ˆƒ `’ µƒ 3¢Ž _ ˆƒ®Î_¬Ï_ %ƒŽÎ_ŒÏ_ 4ƒ რ„ ˆƒ¢  Ô‚ ƒ é‚ ²‚ ˆƒ¢  Ô‚ ƒ ˆƒ ÕŠ ¸ƒ¢  Ô‚ ˆƒ¢  Ô‚ ƒ ˆƒ ¼‚ ˆƒ +‹ »ƒ „ é‚¢  Ô‚ ˆƒ ƒ %ƒ é‚ 4ƒ ˆƒ¢  Þ‚®Î_¬Ï_ ˆƒ¢   ¶…ÐL5¢| 8 ˆƒ¢  ˆƒ `’ ¸ƒ 3 -®¬9¬­9 ú‚ ˆƒ¢,   …ÐL>5®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ -Lþ3®¬9¬­9 %ƒŽ¬9Œ­9 4ƒ©…© Qƒ`© ]ƒ ²‚ ˆƒ¢ ] ˆƒ Á‚ ƒ ˆƒ ;/ »ƒ რ„ ƒ é‚ ²‚ ƒ ™…ÐLô5 ·‚ ƒ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ ^Š ¸ƒ ˆƒ¢   …ÐLÏ5Lô5Lñ5 ²‚ ˆƒ ·‚ ƒ ˆƒ¢  „ ˆƒ ?6 »ƒ é‚LŠ5 ²‚ ƒ »ƒ` ²‚ ƒ ˆƒ¢— 8 ˆƒ¢  ˆƒ `’ µƒ¢  ‹… ˆƒ _ »ƒ` ²‚ ƒ ˆƒ ¼‚ ƒ é‚` ²‚ ƒ ƒ`rwusage: tcpp [-Dname[=def]] infile [outfile] %s#ifdef#ifndef#else#endif#define#include#if tcpp: too many #include files tcpp: can't include %s rrrr/*tcpp: unexpected newline tcpp: too many parameters tcpp: delimeter missing tcpp: illegal symbol name tcpp: '#ifdef symbol' expected #else#endif#endif#elsetcpp: '#ifndef symbol' expected #else#endif#endif#elsetcpp: '#if symbol' expected #else#endif#endif#elsetcpp: symbol table full tcpp: macro definition table full tcpp: macro %s redefined tcpp: illegal parameter %s tcpp: too many parameters tcpp: can't open %s ©ü¢ ÿ ôÿ†ôŽ0þ¢  ˆƒLVª¢ Ž]Œ]¢ Ž]Œ]¢ Ž]Œ]¢ Ž]Œ]¢° < ˆƒ¢   „ŽRLŒSL¢TååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååååSmall-C tcpp/c $tccom/c$tcc/c $sys/s $swcrt/s$sieve/c$shar/c $sh/c $sfa/c $rm/c $plot/c $patch/s$oshdr/s$optab/s$mktcc $mkswcrt$mksh $mkcrt $lpr/c $lib/c $ld/c $hex/c $hanoi/c$fahr/c $diff/c $dehex/c$crt1/s $crt0/s $cmp/c $bm/c $as65/c $ ø]Cÿ ªà,Ž0Cÿpߌ £Cÿ ÀÍŽ@ÿà Á( eAÿà²×MT@ÿÝ4MQAÿõ}Í;Cÿ ’N 3@ÿ×Í/Cÿ ’E $Cÿçã@ÿàôVMAÿàÎïÍAÿpi9 ÍCÿÌðCÿ0ëÌïCÿÿ5ŒîCÿ0ÁÌíAÿC‘ äCÿ0{l- ¶Cÿ0{µ ¬AÿCA ¦OÿóQU ŸAÿÓúŒœOÿ\N  —Aÿ× ‹Aÿpk" hAÿp·JÌd@ÿ‡ìŒ`Aÿ­i OCÿ0{.L /* as65.c - MOS Technology 6502 assembler */ /* 11-Apr-1989 v0.70 - A.J.Travis */ /* 22-Jun-1991 v0.71 - J.G.Harston * system-specifics removed to local.h * uses '/' instead of '_' in filenames * main() ends with exit(0); */ #include #include /* * configuration options */ #define FORCE_CASE 0 /* 1 = force lower case on input */ /* * implementation dependant pathnames, and i/o modes */ #ifdef MSDOS #define MNEMTAB "mnemtab" /* opcode mnemonics */ #define OPTAB "optab" /* opcode table */ #define IO_W "wb" /* binary write mode */ /* #define ILLEGAL 0xFF */ /* needed in 'old' Zorland C */ #define ILLEGAL -1 /* 0xFF is sign extended to -1 */ #else #define __BBC__ 1 /* Acorn/BBC System */ #include "local.h" /* Fetch local dependancies */ #define IO_W "w" /* write mode */ #define W_CAT 1 /* write catalogue info */ #define RW 3 /* read/write attributes */ #define ILLEGAL -1 /* 0xFF is sign extended to -1 */ #endif /* * boolean constants */ #define TRUE 1 #define FALSE 0 #define ERROR -1 #define SAME 0 /* * symbol table parameters */ #define LINESIZE 80 #define HASHSIZE 257 #define SYMSIZE 10000 #define NEXTPTR 0 #define VALUE 2 #define NAME 4 #define BYTE 256 /* * 6502 addressing modes */ #define IMPLIED 0 #define ACCUM 1 #define IMMED 2 #define DIRECT 3 #define DIRECT_X 4 #define DIRECT_Y 5 #define ABS 6 #define ABS_X 7 #define ABS_Y 8 #define IND_X 9 #define IND_Y 10 #define REL 11 #define INDIRECT 12 #define NMODES 13 #define NCODES 56 /* * function types */ char *inline(); char *hashfind(); /* * global variables */ char obj[LINESIZE]; /* object code output buffer */ char op[728]; /* opcode table (NCODES * NMODES) */ char ibuf[LINESIZE]; /* input buffer */ char sbuf[LINESIZE]; /* symbol buffer */ char symtab[SYMSIZE]; /* symbol table */ char *ofile; /* output file */ char *endsym; /* end of symbol table */ char *start; /* start of symbol table */ char *freeptr; /* next free location in hash chain */ char *ip; /* input buffer pointer */ unsigned loc; /* location counter */ unsigned origin; /* assembly origin */ unsigned _text; /* start of text segment */ unsigned _data; /* start of data segment */ unsigned _end; /* end of program */ unsigned textsz; /* size of text segment */ unsigned datasz; /* size of data segment */ int hashtab[HASHSIZE]; /* hash table */ FILE *in; /* input stream */ FILE *out; /* output stream */ int endflag; /* .end pseudo-op flag */ int list; /* produce assembler listing */ int pass; /* pass 1/2 */ int nbytes; /* number of bytes in obj[] */ int errcnt; /* error count */ int nset; /* number of setloc pseudo-ops */ int main(argc, argv) int argc; char *argv[]; { int file; /* source file no. */ in = NULL; out = NULL; ofile = "o/out"; /* default output file name */ list = FALSE; /* default no listing */ while ((*argv[1] & 0xFF) == '-') { /* BUG in compiler */ if (strcmp(argv[1], "-l") == SAME) list++; else if (strcmp(argv[1], "-o") == SAME) { if (argc < 3) usage(); else { ofile = argv[2]; --argc; argv++; } } else usage(); --argc; argv++; } if (argc < 2) usage(); if ((out = fopen(ofile, IO_W)) == NULL) { fprintf(stderr, "as65: can't open %s\n", ofile); fatal(-1); } endsym = symtab + SYMSIZE; inithash(); prehash(); for (pass = 1; pass < 3; pass++) { errcnt = 0; nset = 0; loc = 0; origin = 0; endflag = FALSE; for (file = 1; file < argc; file++) { if ((in = fopen(argv[file], "r")) == NULL) { fprintf(stderr, "can't open %s\n", argv[file]); fatal(-1); } doasm(); fclose(in); } } fclose(out); dumpsym(); /* print size of text and data areas if C 'segment' symbols present */ if ((hashfind("~eot") != NULL) & (hashfind("~eod") != NULL)) { _text = origin; _data = lookup("~eot"); _end = lookup("~eod"); textsz = _data - _text; datasz = _end - _data; printf("%u = %u+%u ", textsz + datasz, textsz, datasz); printf("(0x%04X, 0x%04X, 0x%04X)\n", _text, _data, _end); } #ifdef __BBC__ attributes(ofile, origin, origin); #endif if (errcnt) fprintf(stderr, "as65: %d errors\n", errcnt); exit(0); } /* * report correct usage and exit */ usage() { fprintf(stderr, "usage: as65 [-l] [-o outfile] file1 ... [filen]\n"); fatal(-1); } /* * assemble one pass */ doasm() { int mem; *ibuf = '\0'; while (inline() != NULL) { mem = loc; nbytes = 0; assem(); if (pass == 2) output(mem); loc = loc + nbytes; if (endflag) break; } } /* * input line * ---------- * ignore full line comments and empty lines */ char *inline() { int c; char *p; while ((p = fgets(ibuf, LINESIZE, in)) != NULL) { if (*p == ';') { if (pass == 1 | list == FALSE) continue; else printf(" %s", p); } else if (*p == '\n') continue; else break; } ip = p; #if FORCE_CASE /* force lower case */ while (c = tolower(*p)) { if (c == ';') break; else if (c == '"' | c == '\'') { while (*++p) if (*p == c) break; } else *p++ = c; } #endif return(ip); } /* * assemble one line */ assem() { if (sym(sbuf)) { if (qlabel()) return; else if (qmnem()) return; } if (*ip == '\n') return; else if (match('.')) pseudo(); else if (match('*')) setloc(); else if (match(';')) return; else error("symbol/pseudo-op required"); } /* * prehash mnemonics into symbol table * ----------------------------------- * check current directory first for data files */ prehash() { char *p, mnem[LINESIZE]; int n, optab; FILE *mnemtab; if ((mnemtab = fopen("mnemtab", "r")) == NULL) { if ((mnemtab = fopen(MNEMTAB, "r")) == NULL) { fprintf(stderr, "as65: can't open mnemtab\n"); fatal(-1); } } n = 0; while (n < NCODES) { fgets(mnem, LINESIZE, mnemtab); p = mnem; while (*p++ != '\n') ; *--p = '\0'; install(mnem, op + n++ * NMODES); } fclose(mnemtab); if ((optab = open("optab", 0)) == -1) { if ((optab = open(OPTAB, 0)) == -1) fprintf(stderr, "as65: can't open optab\n"); } if (optab != -1) { p = op; while ((n = read(optab, p, BUFSIZ)) != 0) p = p + n; if (p - op < NCODES * NMODES) { fprintf(stderr, "as65: illegal optab size\n"); fatal(-1); } close(optab); } start = freeptr; } /* * check for labelled statement * ---------------------------- * Exit status indicates whether * processing of line is complete */ qlabel() { if (pass == 1) return(putlab()); else return(getlab()); } /* * put new label in symbol table * ----------------------------- * 6502 Mnemonics are reserved symbols. * Exit status indicates whether * processing of line is complete */ putlab() { char *tag; if ((tag = hashfind(sbuf)) == NULL) { if (match('=')) { install(sbuf, exp()); return(TRUE); } else { install(sbuf, loc); return(FALSE); } } else if (tag < start) { mnem(tag); return(TRUE); } else { error("label redefined"); return(FALSE); } } /* * update labels on second pass * ---------------------------- * Exit status indicates that * processing of line is complete */ getlab() { char *tag; if ((tag = hashfind(sbuf)) >= start) { if (match('=')) { mputw(tag + VALUE, exp()); return(TRUE); } else { mputw(tag + VALUE, loc); return(FALSE); } } else { mnem(tag); return(TRUE); } } /* * Check for mnemonic * ------------------ * Exit status indicates whether * processing of line is complete */ qmnem() { char *tag, *savp; savp = ip; if (sym(sbuf) == 0) return(FALSE); else if ((tag = hashfind(sbuf)) < start) { mnem(tag); return(TRUE); } else { ip = savp; return(FALSE); } } /* * process mnemonic */ mnem(tag) char *tag; { char *p; int mode; p = mgetw(tag + VALUE); if ((obj[0] = p[IMPLIED]) != ILLEGAL) { nbytes = 1; return; } else { if ((obj[0] = p[REL]) != ILLEGAL) { relative(); return; } else { mode = getmode(); if ((obj[0] = p[mode]) != ILLEGAL) return; else if (tryfix(p, mode)) return; else if (pass == 1) return; else error("illegal address mode"); } } } /* * get address mode of opcode */ getmode() { int oper; if (match('#')) return(immediate()); else if (match('(')) return(indirect()); else if (*ip == 'a' & isalnum(ip[1]) == 0) return(accum()); else oper = exp(); if (match(',')) return(indexed(oper)); else if (oper >= 0 & oper < BYTE) return(direct(oper)); else return(absolute(oper)); } /* * try to 'fix' illegal address modes */ tryfix(p, mode) char *p; int mode; { if (mode == DIRECT_X) return(fix_x(p)); else if (mode == DIRECT_Y) return(fix_y(p)); else return(FALSE); } /* * substitute absolute,X for direct,X */ fix_x(p) char *p; { if (p[ABS_X] == ILLEGAL) return(FALSE); else { nbytes = 3; obj[0] = p[ABS_X]; obj[2] = 0; return(TRUE); } } /* * substitute absolute,Y for direct,Y */ fix_y(p) char *p; { if (p[ABS_Y] == ILLEGAL) return(FALSE); else { nbytes = 3; obj[0] = p[ABS_Y]; obj[2] = 0; return(TRUE); } } /* * data immediately after opcode */ immediate() { nbytes = 2; obj[1] = exp() & 0xFF; return(IMMED); } /* * address data indirectly */ indirect() { int oper; nbytes = 2; oper = exp(); if (match(',')) return(preind(oper)); else if (match(')')) return(postind(oper)); else error("syntax error"); } /* * pre-indexed indirect */ preind(oper) int oper; { if (match('x') == FALSE) error("'x' expected"); else if (match(')') == FALSE) error("')' expected"); else { obj[1] = oper & 0xFF; return(IND_X); } } /* * post-indexed indirect */ postind(oper) int oper; { if (match(',') == FALSE) return(ind(oper)); else if (match('y') == FALSE) error("'y' expected"); else { obj[1] = oper & 0xFF; return(IND_Y); } } /* * absolute indirect */ ind(oper) int oper; { nbytes = 3; obj[1] = oper & 0xFF; obj[2] = oper >> 8; return(INDIRECT); } /* * data in accumulator */ accum() { nbytes = 1; return(ACCUM); } /* * register indexed address modes */ indexed(oper) int oper; { if (match('x')) return(xindex(oper)); else if (match('y')) return(yindex(oper)); else error("'x' or 'y' expected"); } /* * index register X */ xindex(oper) int oper; { if (oper > 0 & oper < BYTE) { nbytes = 2; obj[1] = oper & 0xFF; return(DIRECT_X); } else { nbytes = 3; obj[1] = oper & 0xFF; obj[2] = oper >> 8; return(ABS_X); } } /* * index register Y */ yindex(oper) int oper; { if (oper > 0 & oper < BYTE) { nbytes = 2; obj[1] = oper & 0xFF; return(DIRECT_Y); } else { nbytes = 3; obj[1] = oper & 0xFF; obj[2] = oper >> 8; return(ABS_Y); } } /* * direct (zero page) address */ direct(oper) int oper; { nbytes = 2; obj[1] = oper & 0xFF; return(DIRECT); } /* * 16-bit absolute address */ absolute(oper) int oper; { nbytes = 3; obj[1] = oper & 0xFF; obj[2] = oper >> 8; return(ABS); } /* * program counter relative */ relative() { int offset; nbytes = 2; offset = exp() - loc - 2; if (offset < -128 | offset > 127) { if (pass == 1) offset = 0; else error("branch out of range"); } obj[1] = offset; return(REL); } /* * set location counter pseudo-op */ setloc() { if (match('=') == FALSE) error("'=' expected"); else { skip(); if (*ip == '*') reserve(); else { loc = exp(); if (nset++ == 0) origin = loc; } } } /* * memory reserve pseudo-op */ reserve() { int oldloc; oldloc = loc; loc = exp(); if (pass == 2) { while (oldloc++ < loc) putc('\0', out); } } /* * explicit pseudo-ops */ pseudo() { nbytes = 0; if (sym(sbuf) == FALSE) error("pseudo-op expected"); else if (strcmp(sbuf, "byte") == SAME) byte(); else if (strcmp(sbuf, "dbyte") == SAME) dbyte(); else if (strcmp(sbuf, "end") == SAME) endflag = TRUE; else if (strcmp(sbuf, "word") == SAME) word(); else if (strcmp(sbuf, "text") == SAME) text(); else if (strcmp(sbuf, "file") == SAME) file(); else error("illegal pseudo-op"); } /* * initialise memory byte */ byte() { nbytes = 0; while(nbytes < LINESIZE) { obj[nbytes++] = exp() & 0xFF; if (match(',') == 0) break; } } /* * initialise memory word, high byte first */ dbyte() { int word; nbytes = 0; word = exp(); while(nbytes < LINESIZE) { obj[nbytes++] = word >> 8; obj[nbytes++] = word & 0xFF; if (match(',') == 0) break; } } /* * initialise memory word, low byte first */ word() { int word; nbytes = 0; word = exp(); while(nbytes < LINESIZE) { obj[nbytes++] = word & 0xFF; obj[nbytes++] = word >> 8; if (match(',') == 0) break; } } /* * enter ASCII text */ text() { char delim; /* string delimeter */ skip(); delim = *ip++; /* first non-blank is delimeter */ nbytes = 0; while(nbytes < LINESIZE & *ip != delim & *ip != '\n') obj[nbytes++] = *ip++; ip++; /* skip trailing delimeter */ } /* * switch input to new source file */ file() { char *bp; fclose(in); skip(); bp = sbuf; while (*ip != ' ' & *ip != '\n') *bp++ = *ip++; *bp = '\0'; if ((in = fopen(sbuf, "r")) == NULL) { fprintf(stderr, "as65: can't open %s\n", sbuf); fatal(-1); } } /* * evaluate expression * ------------------- * '<' returns low byte of expression * '>' returns high byte */ exp() { if (match('<')) return(expression() & 0xFF); else if (match('>')) return(expression() >> 8); else return(expression()); } /* * evaluate infix expression * ------------------------- * operator precedence is left to right */ expression() { int n; n = operand(); while (*ip) { if (match('+')) n = n + operand(); else if (match('-')) n = n - operand(); else if (match('*')) n = n * operand(); else if (match('/')) n = n / operand(); else break; } return(n); } /* * return arithmetic operand */ operand() { char symbol[LINESIZE]; if (sym(symbol)) return(lookup(symbol)); else if (match('$')) return(hexnum()); else if (match('@')) return(octal()); else if (match('%')) return(binary()); else if (match('\'')) return(character()); else if (match('*')) return(loc); else if (isdigit(*ip)) return(decimal()); else { error("illegal expression"); return(ILLEGAL); } } /* * look up name in symbol table */ lookup(name) char *name; { char *tag; tag = hashfind(name); if (pass == 2) { if (tag == 0) error("symbol undefined"); else if (tag < start) error("illegal symbol"); } if (tag == 0) return(0xEAEA); else return(mgetw(tag + VALUE)); } /* * hexadecimal constant $n */ hexnum() { int n; if (isxdigit(*ip) == 0) return(ERROR); else { n = 0; while (isxdigit(*ip)) n = n * 16 + toint(*ip++); return(n); } } /* * convert char to 'weight' of hex digit */ toint(c) char c; { if (isdigit(c)) return(c - '0'); else if (isxdigit(c)) { if (isupper(c)) return(c - 'A' + 10); if (islower(c)) return(c - 'a' + 10); } else return(ERROR); } /* * decimal constant n */ decimal() { int n; if (isdigit(*ip) == 0) return(ERROR); else { n = 0; while (isdigit(*ip)) n = n * 10 + *ip++ - '0'; return(n); } } /* * octal constant @n */ octal() { int n; if (*ip < '0' | *ip > '7') return(ERROR); else { n = 0; while (*ip >= '0' & *ip <= '7') n = n * 8 + *ip++ - '0'; return(n); } } /* * binary constant %n */ binary() { int n; if (*ip != '0' & *ip != '1') return(ERROR); else { n = 0; while (*ip == '0' | *ip == '1') n = n * 2 + *ip++ - '0'; return(n); } } /* * character constant 'c' */ character() { char c; c = *ip++; if (*ip == '\'') ip++; /* discard optional trailing ' */ return(c); } /* * get next symbol * --------------- * copy alpha prefixed alphanumeric string from input buffer * accepts underline and tilde as alpha prefix * returns length of string */ sym(p) char *p; { char *bp; skip(); bp = p; if (isalpha(*ip) | *ip == '_' | *ip == '~') { *bp++ = *ip++; while (isalnum(*ip) | *ip == '_') *bp++ = *ip++; *bp = '\0'; } return(bp - p); } /* * skip white space on input */ skip() { while (*ip == ' ' | *ip == '\t') ip++; } /* * match literal with input buffer */ match(c) char c; { skip(); if (*ip != c) return(FALSE); else { ip++; return(TRUE); } } /* * output assembly listing and object code */ output(mem) int mem; { int n, byte; if (list) { n = 0; do { printf("%04X ", mem + n); for (byte = 0; byte < 3; byte++) { if (n < nbytes) printf("%02X ", obj[n++] & 0xFF); else printf(" "); } if (n < 4) printf(" %s", ibuf); else printf("\n"); } while (n < nbytes); } for (n = 0; n < nbytes; n++) putc(obj[n], out); } /* * print error message * ------------------- * use stdout, so errors appear in listing */ error(message) char *message; { printf("\n*****: %s", ibuf); printf("error: %s\n", message); if (++errcnt > 5) { printf("as65: too many errors, assembly aborted\n"); fatal(-1); } } /* * tidy up files and exit on fatal error */ fatal(stat) int stat; /* exit status */ { if (in != NULL) fclose(in); if (out != NULL) fclose(out); exit(stat); } /* * initialise empty hash table */ inithash() { int i; freeptr = symtab; i = 0; while (i < HASHSIZE) hashtab[i++] = NULL; } /* * hashing algorithm * ----------------- * returns value in range 0 to HASHSIZE - 1 * for best results HASHSIZE should be a prime */ hash(name) char *name; { int h; h = 0; while (*name) h = (3 * h + *name++) % HASHSIZE; return(h); } /* * install new symbol */ install(name, val) char *name; int val; { int len, h; char *p; len = strlen(name) + 5; if (freeptr + len > endsym) { fprintf(stderr, "symbol table full\n"); fatal(-1); } h = hash(name); p = freeptr; mputw(p + NEXTPTR, hashtab[h]); hashtab[h] = p; mputw(p + VALUE, val); strcpy(p + NAME, name); freeptr = p + len; } /* * find symbol using hash + chain */ char *hashfind(name) char *name; { char *tag; tag = hashtab[hash(name)]; while (tag) { if (strcmp(tag + NAME, name) == SAME) break; else tag = mgetw(tag + NEXTPTR); } return(tag); } /* * put word into memory */ mputw(p, val) int *p; int val; { *p = val; } /* * get word from memory */ mgetw(p) int *p; { return(*p); } /* * dump symbol table * ----------------- * symbols prefixed by tilde are local, and * are not written to the global symbol file */ dumpsym() { char *p; FILE *out; if (freeptr == start) return; if ((out = fopen("g/out", "w")) == NULL) { fprintf(stderr, "as65: can't open g/out\n"); fatal(-1); } p = start; while (p < freeptr) { if (*(p + NAME) != '~') fprintf(out, "%s =$%04X\n", p + NAME, mgetw(p + VALUE)); if (list) printf("%s =$%04X\n", p + NAME, mgetw(p + VALUE)); p = p + strlen(p + NAME) + 5; } fclose(out); } #ifdef __BBC__ /* * set load and execution attributes on object file */ attributes(file, load, exec) char *file; /* filename to set attributes on */ int load; /* load address */ int exec; /* execution address */ { int fcb[9]; /* file control block */ fcb[0] = 0; fcb[1] = load; fcb[2] = 0; fcb[3] = exec; fcb[4] = 0; fcb[5] = 0; fcb[6] = 0; fcb[7] = RW; fcb[8] = 0; return(osfile(file, fcb, W_CAT)); } #endif /* as65.c - MOS Technology 6502 assembler */ /* 11-Apr-1989 v0.70 - A.J.Travis */ /* 22-Jun-1991 v0.71 - J.G.Harston * system-specifics removed to local.h * uses '/' instead of '_' in filenames * /* bm.c 01-May-89 A.J.Travis */ /* * Small-C Benchmarks * * Based on Chris Sadler's Pascal Benchmarks in PCW Oct 1986 * and the 'tak' benchmark from Acorn User, Jun 86, pp179 */ #include int matrix[11]; int j, k, l, x; int test[16]; int n; int main() { /* set up test vectors */ test[1] = magnifier; test[2] = forloop; test[3] = whileloop; test[4] = doloop; test[5] = literalassign; test[6] = memoryaccess; test[7] = arithmetic; test[8] = algebra; test[9] = vector; test[10] = equalif; test[11] = unequalif; test[12] = noparameter; test[13] = value; test[14] = reference; test[15] = dotak; /* select benchmarks */ do { printf("\fSmall-C Benchmarks:\n\n"); printf("magnifier = 10,000 iterations\n\n"); printf(" 0: quit\n"); printf(" 1: magnifier\n"); printf(" 2: forloop\n"); printf(" 3: whileloop\n"); printf(" 4: doloop\n"); printf(" 5: literalassign\n"); printf(" 6: memoryaccess\n"); printf(" 7: arithmetic\n"); printf(" 8: algebra\n"); printf(" 9: vector\n"); printf("10: equalif\n"); printf("11: unequalif\n"); printf("12: noparameter\n"); printf("13: value\n"); printf("14: reference\n"); printf("15: tak\nn"); printf("test? "); scanf("%d", &n); if (n > 0 & n < 15) test[n](); } while (n); exit(0); } /* * 'for' loop magnifier */ magnifier() { printf("start\n"); for (k = 0; k < 10000; k++) ; printf("finish\007\n"); } /* * 'for' loop benchmark */ forloop() { printf("start\n"); for (k = 0; k < 10000; k++) for (j = 0; j < 10; j++) ; printf("finish\007\n"); } /* * 'while' loop benchmark */ whileloop() { printf("start\n"); for (k = 0; k < 10000; k++) { j = 1; while (j <= 10) j = j + 1; } printf("finish\007\n"); } /* * 'do' loop benchmark */ doloop() { printf("start\n"); for (k = 0; k < 10000; k++) { j = 1; do { j = j + 1; } while (j <= 10); } printf("finish\007\n"); } /* * 'literalassign' benchmark */ literalassign() { printf("start\n"); for (k = 0; k < 10000; k++) for (j = 0; j < 10; j++) l = 0; printf("finish\007\n"); } /* * 'memoryaccess' loop benchmark */ memoryaccess() { printf("start\n"); for (k = 0; k < 10000; k++) for (j = 0; j < 10; j++) l = j; printf("finish\007\n"); } /* * 'arithmetic' benchmark */ arithmetic() { printf("start\n"); for (k = 0; k < 10000; k++) x = k / 2 * 3 + 4 - 5; printf("finish\007\n"); } /* * 'algebra' benchmark */ algebra() { printf("start\n"); for (k = 1; k < 10001; k++) x = k / k * k + k - k; printf("finish\007\n"); } /* * 'vector' benchmark */ vector() { printf("start\n"); matrix[0] = 0; for (k = 0; k < 10000; k++) for (j = 0; j < 10; j++) matrix[j] = matrix[j - 1]; printf("finish\007\n"); } /* * 'equalif' benchmark */ equalif() { printf("start\n"); for (k = 0; k < 10000; k++) for (j = 0; j < 10; j++) if (j < 6) l = 1; else l = 0; printf("finish\007\n"); } /* * 'unequalif' benchmark */ unequalif() { printf("start\n"); for (k = 0; k < 10000; k++) for (j = 0; j < 10; j++) if (j < 2) l = 1; else l = 0; printf("finish\007\n"); } /* * 'noparameter' benchmark */ noparameter() { printf("start\n"); j = 0; for (k = 0; k < 10000; k++) none1(); printf("finish\007\n"); } none1() { none2(); } none2() { none3(); } none3() { none4(); } none4() { none5(); } none5() { j = 1; } /* * 'value' benchmark */ value() { printf("start\n"); j = 0; for (k = 0; k < 10000; k++) value1(j); printf("finish\007\n"); } value1(i) int i; { value2(); } value2(i) int i; { value3(); } value3(i) int i; { value4(); } value4(i) int i; { value5(); } value5(i) int i; { j = 1; } /* * 'reference' benchmark */ reference() { printf("start\n"); j = 0; for (k = 0; k < 10000; k++) refer1(&j); printf("finish\007\n"); } refer1(i) int *i; { refer2(i); } refer2(i) int *i; { refer3(i); } refer3(i) int *i; { refer4(i); } refer4(i) int *i; { refer5(i); } refer5(i) int *i; { j = 1; } /* * 'tak' benchmark */ dotak() { printf("tak = %d\n", tak(18, 12, 6)); } tak(x, y, z) int x, y, z; { if (y < x) return(tak(tak(x-1, y, z), tak(y-1, z, x), tak(z-1, x, y))); else return(z); } /* bm.c 01-May-89 A.J.Travis */ /* * Small-C Benchmarks * * Based on Chris Sadler's Pascal Benchmarks in PCW Oct 1986 * and the 'tak' benchmark /* cmp.c - 19 Apr 88 A.J.Travis */ /* * Simple file comparison */ #include char buf1[BUFSIZ]; char buf2[BUFSIZ]; char *bp1, *bp2; int c1, c2; int fd1, fd2; int n1, n2; int n; int main(argc, argv) int argc; char *argv[]; { if (argc != 3) { fprintf(stderr, "usage: cmp file1 file2\n"); exit(-1); } if ((fd1 = open(argv[1], 0)) == -1) { fprintf(stderr, "cmp: can't open %s\n", argv[1]); exit(-1); } if ((fd2 = open(argv[2], 0)) == -1) { fprintf(stderr, "cmp: can't open %s\n", argv[2]); close(fd1); exit(-1); } n = 0; do { n1 = read(fd1, buf1, BUFSIZ); n2 = read(fd2, buf2, BUFSIZ); bp1 = buf1; bp2 = buf2; while ((bp1 < buf1 + n1) & (bp2 < buf2 + n2)) { if ((c1 = *bp1++ & 0xFF) != (c2 = *bp2++ & 0xFF)) printf("%4X: %02X %02X\n", n, c1, c2); n++; } if (n1 < n2) printf("cmp: end of file on %s\n", argv[1]); if (n1 > n2) printf("cmp: end of file on %s\n", argv[2]); } while (n1 > 0 & n1 == n2); close(fd1); close(fd2); exit(0); } /* cmp.c - 19 Apr 88; crt0.s 26-Jan-89 A.J.Travis ; ; startup code for tcc run-time support in default text area ; above primary operating system high water mark at $1900 ; ; 20-Jun-1991 v0.71 - J.G.Harston ; escape event disabled after exit ; *=$1902 ; ; initialise sp (data stack pointer) ; and enter user program ; start lda evntv+1 pha lda evntv pha jsr ~start2 pla ;restore event vector tax pla tay lda #13 ;disable escape event ~settrap stx evntv sty evntv+1 ldx #6 jmp osbyte ~start2 cld tsx ;save stack position stx rsp lda #132 ;read bottom of display ram jsr osbyte stx sp ;initialise data stack sty sp+1 ldx #escape lda #14 ;enable escape event jsr ~settrap ldx #<__enter ;user entry point ldy #>__enter jsr push ;on tcc data stack jmp __cmdini ;enter _cmdinit(&_enter) ; crt0.s 26-Jan-89 A.J.Travis ; ; startup code for tcc run-time support in default text area ; above primary operating system high water mark at $1900 ; ; 20-Jun-1991 v0.71 - J.G; crt1.s 04-Apr-89 A.J.Travis ; ; Run-time support for tcc under Acorn/BBC MOS ; ; ; _trace() - trace/debug trap ; --------------------------- ; print contents of 6502 regs, and tcc pseudo-regs in hex ; __trace sta asave ;save 6502 regs stx pr sty pr+1 jsr osnewl ;start of reg display ldy #1 ;6502 stack hi tsx ;6502 stack lo jsr ~hex2 lda $101,x ;return addr lo ldy $102,x ;return addr hi tax jsr ~hex2 ldx pr ;primary reg lo ldy pr+1 ;primary reg hi jsr ~hex2 ldx sr ;secondary reg lo ldy sr+1 ;secondary reg hi jsr ~hex2 ldx tr ;tertiary reg lo ldy tr+1 ;tertiary reg hi jsr ~hex2 ldx sp ;data stack pointer lo ldy sp+1 ;data stack pointer hi jsr ~hex2 ldy #0 lda (sp),y ;top stack item lo tax iny lda (sp),y ;top stack item hi tay jsr ~hex2 lda asave ;restore 6502 regs ldx pr ldy pr+1 rts ; ; output hex number followed by a blank ; ~hex2 tya jsr ~hex ~hex1 txa jsr ~hex lda #' ' jsr oswrch rts ; ; output a as 2 hex digits ; ~hex pha lsr a lsr a lsr a lsr a jsr ~ahex pla jsr ~ahex rts ; ; output bits 0-3 of a as hex digit ; ~ahex and #$0f cmp #$0a clc bmi ~ahex1 adc #$07 ~ahex1 adc #$30 jmp oswrch ;use mos rts ; ; sign extend char in xy ; ---------------------- ; sign bit in status reg on entry ; ext bpl ~ext1 ldy #$ff ;negative rts ~ext1 ldy #0 ;positive rts ; ; convert sp offset to address ; ------------------------------- ; addr if offset = 0 ; addr_1 if offset = 2 ; addr_2 if offset = 4 ; ... ; addr_6 if offset = 12 ; addr_b if offset < 256 ; addr_w if offset >= 256 ; addr ldx sp ldy sp+1 rts addr_1 ldx #2 jmp addr_b addr_2 ldx #4 jmp addr_b addr_3 ldx #6 jmp addr_b addr_4 ldx #8 jmp addr_b addr_5 ldx #10 jmp addr_b addr_6 ldx #12 addr_b ldy #0 addr_w clc txa adc sp tax tya adc sp+1 tay rts ; ; store indirect byte in x at addr on stack ; ----------------------------------------- ; leaves signed char in xy as result ; sind_b jsr pop ldy #0 txa sta (sr),y jmp ext ; ; store indirect word in xy at addr on stack ; sind_w jsr pop sty pr+1 ldy #0 txa sta (sr),y iny lda pr+1 sta (sr),y tay rts ; ; load indirect byte from addr in xy ; lind_b stx pr sty pr+1 ldy #0 lda (pr),y tax jmp ext ; ; load indirect word from addr in xy ; lind_w stx pr sty pr+1 ldy #0 lda (pr),y ;word lo tax iny lda (pr),y ;word hi tay rts ; ; call subroutine on data stack ; ----------------------------- ; return addr is on 6502 return stack ; scall ldy #0 lda (sp),y ;addr lo sta tr iny lda (sp),y ;addr hi sta tr+1 jsr drop ;adjust data stack jmp (tr) ;return via rts ; ; xy = xy + 1 ; inc1 inx bne ~inc11 iny ~inc11 rts ; ; xy = xy + 2 ; inc2 clc txa adc #2 tax tya adc #0 tay rts ; ; xy = xy - 1 ; dec1 dex cpx #$ff bne ~dec11 dey ~dec11 rts ; ; xy = xy - 2 ; dec2 sec txa sbc #2 tax tya sbc #0 tay rts ; ; increment sp by byte in a ; sinc_b clc adc sp sta sp lda #0 adc sp+1 sta sp+1 rts ; ; increment sp by word in a + asave ; sinc_w clc adc sp sta sp lda asave adc sp+1 sta sp+1 rts ; ; decrement sp by byte in a ; sdec_b sta tr sec lda sp sbc tr sta sp lda sp+1 sbc #0 sta sp+1 rts ; ; decrement sp by word in a + asave ; sdec_w sta tr sec lda sp sbc tr sta sp lda sp+1 sbc asave sta sp+1 rts ; ; swap xy and sr ; swap txa ldx sr sta sr tya ldy sr+1 sta sr+1 rts ; ; push xy to data stack ; push sec ;sp = sp - 2 lda sp sbc #2 sta sp lda sp+1 sbc #0 sta sp+1 sty pr+1 ;save y tya ldy #1 sta (sp),y ;old y in stack item hi dey txa sta (sp),y ;old x in stack item lo ldy pr+1 ;restore y rts ; ; pop data stack to sr ; pop sty pr+1 ;save y ldy #0 lda (sp),y sta sr iny lda (sp),y sta sr+1 ldy pr+1 ;restore y jmp drop ; ; drop top three stack items ; drop3 jsr drop ; ; drop top two stack items ; drop2 jsr drop drop clc ;drop top stack item lda sp adc #2 sta sp lda sp+1 adc #0 sta sp+1 rts ; ; exchange xy and top stack item ; xchange sty pr+1 ;save y ldy #0 lda (sp),y ;save stack item lo sta pr txa sta (sp),y ;old x in stack item lo iny lda (sp),y ;save stack item hi in x tax lda pr+1 sta (sp),y ;old y in stack item hi txa tay ;old stack item hi in y ldx pr ;old stack item lo in x rts ; ; xy = xy * 2 ; scale2 lda #2 ; ; xy = xy * a ; scale sta tr stx pr+2 sty pr+3 ldy #0 sty pr sty pr+1 ldy #16 ~scale1 asl pr rol pr+1 rol pr+2 rol pr+3 bcc ~scale2 clc lda tr adc pr sta pr lda #0 adc pr+1 sta pr+1 ~scale2 dey bne ~scale1 ldx pr ldy pr+1 rts ; ; xy = top stack item + xy ; add jsr pop clc txa adc sr tax tya adc sr+1 tay rts ; ; xy = top stack item - xy ; sub jsr pop stx pr sty pr+1 sec lda sr sbc pr tax lda sr+1 sbc pr+1 tay rts ; ; xy = top stack item * xy ; mult jsr pop stx pr+2 sty pr+3 ldy #0 sty pr sty pr+1 ldy #16 ~mult1 asl pr rol pr+1 rol pr+2 rol pr+3 bcc ~mult2 clc lda sr adc pr sta pr lda sr+1 adc pr+1 sta pr+1 lda #0 adc pr+2 sta pr+2 ~mult2 dey bne ~mult1 ldx pr ldy pr+1 rts ; ; xy = top stack item / xy (16-bit signed) ; div jsr pop ;divisor in sr tya ;dividend sign eor sr+1 pha ;sign of quotient tya ;test sign of xy bpl ~div1 jsr neg ~div1 bit sr+1 ;test sign of sr bpl ~div2 jsr ~negsr ~div2 jsr ~udiv ;unsigned divide pla ;sign of quotient bpl ~div3 jsr neg ;quotient in xy ~div3 rts ; ; xy = top stack item / xy (16-bit unsigned) ; udiv jsr pop ; ; xy = xy / sr (16-bit unsigned) ; ~udiv jsr ~ztrap ;trap division by zero stx tr sty tr+1 lda sr sta pr lda sr+1 sta pr+1 ldy #0 sty sr sty sr+1 ldx #16 asl pr rol pr+1 ~udiv2 rol sr rol sr+1 sec lda sr sbc tr tay lda sr+1 sbc tr+1 bcc ~udiv3 sty sr sta sr+1 ~udiv3 rol pr rol pr+1 dex bne ~udiv2 ldx pr ldy pr+1 rts ; ; xy = top stack item % xy (16-bit signed) ; mod jsr pop ;divisor in sr tya ;dividend sign pha ;save sign bpl ~mod1 jsr neg ~mod1 bit sr+1 ;test sign of sr bpl ~mod2 jsr ~negsr ~mod2 jsr ~umod ;unsigned remainder pla ;sign of result bpl ~mod3 jsr neg ~mod3 rts ; ; xy = top stack item % xy (16-bit unsigned) ; umod jsr pop ; ; xy = sr % xy (16-bit unsigned) ; ~umod jsr ~ztrap ;trap division by zero stx tr sty tr+1 ldy #0 ;clear pr sty pr sty pr+1 ldx #16 ;bit count asl sr rol sr+1 ~umod1 rol pr rol pr+1 sec lda pr sbc tr tay lda pr+1 sbc tr+1 bcc ~umod2 sty pr sta pr+1 ~umod2 rol sr rol sr+1 dex bne ~umod1 ldx pr ldy pr+1 rts ; ; division by zero trap ; ~ztrap txa bne ~ztrap1 tya bne ~ztrap1 brk .byte 0 .text "division by zero" .byte 0 ~ztrap1 rts ; ; negate sr ; ~negsr sec lda #0 sbc sr sta sr lda #0 sbc sr+1 sta sr+1 rts ; ; xy = top stack item | xy ; or jsr pop txa ora sr tax tya ora sr+1 tay rts ; ; xy = top stack item ^ xy ; xor jsr pop txa eor sr tax tya eor sr+1 tay rts ; ; xy = top stack item & xy ; cand jsr pop txa and sr tax tya and sr+1 tay rts ; ; right shift top stack item xy bits ; casr jsr pop lda sr+1 sta pr+1 lda sr cpx #0 beq ~asr2 ~asr1 lsr pr+1 ror a dex bne ~asr1 ~asr2 tax ldy pr+1 rts ; ; left shift top stack item xy bits ; casl jsr pop lda sr sta pr lda sr+1 cpx #0 beq ~asl2 ~asl1 asl pr rol a dex bne ~asl1 ~asl2 tay ldx pr rts ; ; negate xy ; neg clc txa eor #$ff adc #1 tax tya eor #$ff adc #0 tay rts ; ; relational operators return status in 6502 'z' flag ; --------------------------------------------------- ; xy != 0 ; nz cpx #0 bne ~nz1 cpy #0 ~nz1 rts ; ; signed top stack item == xy ; eq jsr ~cmp beq ~eq1 ldx #0 rts ~eq1 ldx #1 rts ; ; signed top stack item != xy ; ne jsr ~cmp bne ~ne1 ldx #0 rts ~ne1 ldx #1 rts ; ; signed top stack item > xy ; gt jsr ~cmp beq ~gt1 bcc ~gt1 ldx #1 rts ~gt1 ldx #0 rts ; ; signed top stack item <= xy ; le jsr ~cmp beq ~le1 bcc ~le1 ldx #0 rts ~le1 ldx #1 rts ; ; signed top stack item >= xy ; ge jsr ~cmp bcs ~ge1 ldx #0 rts ~ge1 ldx #1 rts ; ; signed top stack item < xy ; lt jsr ~cmp bcc ~lt1 ldx #0 rts ~lt1 ldx #1 rts ; ; signed compare top stack item and xy ; ~cmp jsr pop stx pr tya ldy #0 ;result hi eor #$80 sta pr+1 lda sr+1 eor #$80 cmp pr+1 bne ~cmp1 lda sr cmp pr ~cmp1 rts ; ; unsigned top stack item > xy ; ugt jsr ~ucmp beq ~ugt1 bcc ~ugt1 ldx #1 rts ~ugt1 ldx #0 rts ; ; unsigned top stack item <= xy ; ule jsr ~ucmp beq ~ule1 bcc ~ule1 ldx #0 rts ~ule1 ldx #1 rts ; ; unsigned top stack item >= xy ; uge jsr ~ucmp bcs ~uge1 ldx #0 rts ~uge1 ldx #1 rts ; ; unsigned top stack item < xy ; ult jsr ~ucmp bcc ~ult1 ldx #0 rts ~ult1 ldx #1 rts ; ; unsigned compare top stack item and xy ; ~ucmp jsr pop stx pr sty pr+1 ldy #0 ;result hi lda sr+1 cmp pr+1 bne ~ucmp1 lda sr cmp pr ~ucmp1 rts ; ; crt1.s 04-Apr-89 A.J.Travis ; ; Run-time support for tcc under Acorn/BBC MOS ; ; ; _trace() - trace/debug trap ; --------------------------- ; /* dehex.c 30-Apr-89 A.J.Travis */ /* * based on Alan Philips hex to binary converter for * binaries in the Lancaster BBC Micro kermit distribution */ #include #define TRUE 1 #define FALSE 0 #define SAME 0 /* strcmp == */ #if MSDOS #define DFS 0 #else #define DFS 1 #define W_CAT 1 /* write MOS catalogue info */ #define RW 3 /* read/write attributes */ #endif FILE *in; FILE *out; int type; int c; char sum; int len; int rec; int base; int addr; int q; int i; int verbose; /* print details of each record extracted */ int main(argc, argv) int argc; char *argv[]; { in = NULL; out = NULL; if (argc < 3) { fprintf(stderr, "usage: dehex [-v] infile outfile\n"); fatal(-1); } if (strcmp(argv[1], "-v") == SAME) { verbose = TRUE; --argc; ++argv; } else verbose = FALSE; if ((in = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "Input file does not exist\n"); fatal(-1); } if ((out = fopen(argv[2], "wb")) == NULL) { fprintf(stderr, "Can't open output file\n"); fatal(-1); } rec = 1; while (record()) ++rec; fclose(in); fclose(out); #if DFS attributes(argv[2], base, base); #endif exit(0); } /* * close files, and exit on fatal error */ fatal(stat) int stat; { if (in) fclose(in); if (out) fclose(out); exit(stat); } /* * read one record */ record() { while ((c = getc(in)) != ':') { if (c == EOF) return 0; } sum = 0; len = getb(); addr = getw(); if (rec == 1) base = addr; if ((type = getb()) == 0) { unhex(len); return 1; } else if (type == 1) { if (verbose) printf("+++ End-of-file record detected\n"); return 0; } else { fprintf(stderr, "*** Unknown record type %d detected\n", type); fatal(-1); } if (sum != 0) { fprintf(stderr, "*** Checksum error (%04X)\n", sum); fatal(-1); } } /* * get hex byte from input */ getb() { int val; val = toint(getc(in)) << 4; val = val + toint(getc(in)); sum = sum + val; return val; } /* * get hex word from input */ getw() { int val; val = getb() << 8; val = val + getb(); return val; } /* * convert hex char to int */ toint(c) int c; { if (c >= 'A') return c - 'A' + 10; else return c - '0'; } /* * extract hex record */ unhex(len) int len; { if (verbose) printf("Record %4d: Size %2d, address $%04X\n", rec, len, addr); addr = addr + len; while (len--) putc(getb(), out); } #if DFS /* * set MOS load and execution attributes on object file */ attributes(file, load, exec) char *file; /* filename to set attributes on */ unsigned load; /* load address */ unsigned exec; /* execution address */ { int *fcb[9]; /* file control block */ fcb[0] = 0; fcb[1] = load; fcb[2] = 0; fcb[3] = exec; fcb[4] = 0; fcb[5] = 0; fcb[6] = 0; fcb[7] = RW; fcb[8] = 0; return(osfile(file, fcb, W_CAT)); } #endif /* dehex.c 30-Apr-89 A.J.Travis */ /* * based on Alan Philips hex to binary converter for * binaries in the Lancaster BBC Micro kermit distribution */ #include #define TRUE 1 #define FALSE 0 #define SAME 0 /* strcmp == */* diff.c 09-Jan-89 A.J.Travis */ /* * 'line by line' file comparison */ #include #define SAME 0 FILE *fp1, *fp2; char *bp1, *bp2; int c1, c2; int eof1, eof2; int n; char buf1[BUFSIZ]; char buf2[BUFSIZ]; int main(argc, argv) int argc; char *argv[]; { if (argc != 3) { fprintf(stderr, "usage: diff file1 file2\n"); exit(-1); } if ((fp1 = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "diff: can't open %s\n", argv[1]); exit(-1); } if ((fp2 = fopen(argv[2], "r")) == NULL) { fprintf(stderr, "diff: can't open %s\n", argv[2]); fclose(fp1); exit(-1); } n = 0; while (++n) { eof1 = (fgets(buf1, BUFSIZ, fp1) == NULL); eof2 = (fgets(buf2, BUFSIZ, fp2) == NULL); if (eof1 & eof2) break; if (eof1 & (eof2 == 0)) { printf("diff: end of file on %s\n", argv[1]); break; } if (eof2 & (eof1 == 0)) { printf("diff: end of file on %s\n", argv[2]); break; } if (strcmp(buf1, buf2) != SAME) printf("%d:\n< %s> %s", n, buf1, buf2); } fclose(fp1); fclose(fp2); exit(0); } /* diff.c 09-Jan-89 A.J.Travis */ /* * 'line by line' file comparison */ #include #define SAME 0 FILE *fp1, *fp2; char *bp1, *bp2; int c1, c2; int eof1, eof2; int n; char buf1[BUFSIZ]; char buf2[BUFSIZ]; int main(argc, argv) in/* fahr.c 17-Dec-88 A.J.Travis */ /* * print Fahrenheit-Celsius table * ------------------------------ * Adapted from the tutorial example in Kernighan and Ritchie * to show how fixed-point arithmetic can be used in Small-C. */ #include #define SCALE 10 /* fixed-point scale */ int main() { int lower, upper, step; int fahr, celsius; int integer, fraction; lower = 0; /* lower limit of temperature table */ upper = 300; /* upper limit */ step = 20; /* step size */ fahr = lower; while (fahr <= upper) { celsius = (SCALE * 5 * (fahr - 32)) / 9; integer = celsius / SCALE; if ((fraction = celsius % SCALE) < 0) fraction = -fraction; printf("%4d %4d.%1d\n", fahr, integer, fraction); fahr = fahr + step; } exit(0); } /* fah/* hanoi.c 19-Nov-88 Modified by A.J.Travis */ /* * Towers of Hanoi in Small-C by Jon Welch * --------------------------------------- * The program should be run in mode 2, and * shows the disks in 7 different colours. * mode() added J.G.Harston, 01-Jul-90. */ #include int j, n; int one, two, three; int main() { mode(2); printf("\f\nHeight (0-12): "); scanf("%d", &n); if (n > 12) n = 12; j = n; while (j > 0) { box((j % 7) + 1, 200, (n - j + 1) * 40, j * 16); j = j - 1; } one = n * 40; two = 0; three = 0; hanoi(n, 1, 2, 3); exit(0); } up(x) int x; { if (x == 1) one = one + 40; else if (x == 2) two = two + 40; else three = three + 40; } down(x) int x; { if (x == 1) one = one - 40; else if (x == 2) two = two - 40; else three = three - 40; } height(x) int x; { if (x == 1) return(one); else if (x == 2) return(two); else return(three); } bytes(x) int x; { vdu(x); vdu(x >> 8); } box(col, x, y, size) int col, x, y, size; { vdu(18); vdu(0); vdu(col + 128); vdu(24); bytes(x - size); bytes(y); bytes(x + size); bytes(y + 20); vdu(16); } move(n, s, e) int n, s, e ; { box(0, s * 400 - 200, height(s), n * 16); down(s); up(e); box((n % 7) + 1, e * 400 - 200, height(e), n * 16); } hanoi(a, b, c, d) int a, b, c, d; { if (a != 0) { hanoi(a - 1, b, d, c); move(a, b, c); hanoi(a - 1, d, c, b); } } mode(a) int a; { if (osbyte(130,0) < 0 & osbyte(133,a | 0x80)-osbyte(132,0) < 0) { printf("Restart in mode %d.\n",a); exit(1); /* If not in tube, and no memory for mode change, stop */ } vdu(22); vdu(a | 0x80); } /* hanoi.c 19-Nov-88 Modified by A.J.Travis */ /* * Towers of Hanoi in Small-C by Jon Welch * --------------------------------------- * The program should be run in /* hex.c 26-Jan-89 A.J.Travis */ /* * based on Alan Philips binary to hex converter for * binaries in the Lancaster BBC Micro kermit distribution */ #include #if MSDOS #define EOL '\n' #else #define EOL '\r' #endif #define TRUE 1 #define FALSE 0 #define SAME 0 #define END ":00000001FF%c" char ibuf[32]; int in; FILE *out; unsigned addr; int i, j; int cksum; int rflag; int main(argc, argv) int argc; char *argv[]; { if (argc < 3) { fprintf(stderr, "usage: hex [-R] infile outfile\n"); exit(-1); } rflag = 0; if (strcmp(argv[1], "-R") == SAME) { rflag++; --argc; argv++; } if ((in = open(argv[1], 0)) == -1) { fprintf(stderr, "Input file does not exist\n"); exit(-1); } if ((out = fopen(argv[2], "w")) == NULL) { fprintf(stderr, "Can't open output file\n"); exit(-1); } addr = loadaddress(); while (record()) ; fprintf(out, END, EOL); close(in); fclose(out); exit(0); } record() { cksum = 0; if ((i = read(in, ibuf, 32)) == 0) return(FALSE); putc(':', out); hex(i); hex(addr / 256); hex(addr % 256); hex(0); for (j = 0; j < i; j++) hex(ibuf[j]); hex(-cksum); putc(EOL, out); addr = addr + i; return(TRUE); } hex(byte) int byte; { cksum = (cksum + byte); fprintf(out, "%02X", byte & 0xFF); } loadaddress() { if (rflag) return(0x8000); else return(0x1902); } /* hex.c 26-Jan-89 A.J.Travis */ /* * based on Alan Philips binary to hex converter for * binaries in the Lancaster BBC Micro kermit distribution */ #include #if MSDOS #def/* ld.c - rudimentary loader for Small-C run-time support and compiler library */ /* 26-Jan-1989 v0.70 - A.J.Travis * 22-Jun-1991 v0.71 - J.G.Harston * uses '/' instead of '_' in filenames * main() ends with exit(0); */ #include #ifdef MSDOS #define __BBC__ 0 #else #define __BBC__ 1 #endif #define SAME 0 /* strcmp() equal */ #define UNDEFINED -1 /* file status */ #define W_CAT 1 /* write catalogue info */ #define RW 3 /* read/write attributes */ char buf[BUFSIZ]; /* i/o buffer */ char *ofile; /* output filename */ unsigned laddr; /* load address */ unsigned eaddr; /* execution address */ int in, out; /* file descriptors */ int count; /* number of bytes read/written */ int main(argc, argv) int argc; char *argv[]; { in = UNDEFINED; out = UNDEFINED; if (argc < 2) usage(); ofile = "a/out"; /* default output file */ laddr = 0x1902; /* default load address */ eaddr = 0x1902; /* default exec address */ while ((*argv[1] & 0xFF) == '-') { /* BUG in compiler */ if (strcmp(argv[1], "-o") == SAME) { if (argc < 3) usage(); else { ofile = argv[2]; argc = argc - 2; argv = argv + 2; } } else if (strcmp(argv[1], "-R") == SAME) { laddr = 0x8000; eaddr = 0x8000; --argc; argv++; } else usage(); } if (argc < 2) usage(); if ((out = creat(ofile, RW)) == -1) { fprintf(stderr, "ld: can't create %s\n", ofile); fatal(-1); } while (--argc) { if ((in = open(argv[1], 0)) == -1) { fprintf(stderr, "ld: can't open %s\n", argv[1]); fatal(-1); } while ((count = read(in, buf, BUFSIZ)) > 0) write(out, buf, count); close(in); argv++; } close(out); #ifdef __BBC__ attributes(ofile, laddr, eaddr); #endif exit(0); } /* * report correct usage and exit */ usage() { fprintf(stderr, "usage: ld [-o outfile] [-R] file1 ... [filen]\n"); fatal(-1); } /* * close files and exit */ fatal(stat) int stat; /* exit status */ { if (in > 0) close(in); if (out > 0) close(out); exit(stat); } #ifdef __BBC__ /* * set load and execution attributes on object file */ attributes(file, load, exec) char *file; /* filename to set attributes on */ unsigned load; /* load address */ unsigned exec; /* execution address */ { int *fcb[9]; /* file control block */ fcb[0] = 0; fcb[1] = load; fcb[2] = 0; fcb[3] = exec; fcb[4] = 0; fcb[5] = 0; fcb[6] = 0; fcb[7] = RW; fcb[8] = 0; return(osfile(file, fcb, W_CAT)); } #endif /* ld.c - rudimentary loader for Small-C run-time support and compile/* lib.c 09-Apr-89 A.J.Travis */ /* * Part of the 'standard' C library */ /* JGH: Increase LINESIZE from 81 to 256 */ #include #define _MAXARG 32 /* max no. of command arguments */ #define _IOSTRG -1 /* string input mode for _doscan() */ #define LINESIZE 256 /* length of output line + 1 */ #define EOL '\r' /* MOS end of line */ #define DELETE '\177' /* i/o delete char */ #define SAME 0 /* strcmp() strings equal */ #define TRUE 1 #define FALSE 0 #define ERROR -1 /* * append string s2 to string s1 */ strcat(s1, s2) char *s1; char *s2; { char *os1; os1 = s1; while (*s1++) ; --s1; while (*s1++ = *s2++) ; return(os1); } /* * compare strings s1 and s2 */ strcmp(s1, s2) char *s1; char *s2; { while (*s1 == *s2++) { if (*s1++ == '\0') return(0); } return(*s1 - *--s2); } /* * copy string s2 to string s1 */ strcpy(s1, s2) char *s1; char *s2; { char *os1; os1 = s1; while (*s1++ = *s2++) ; return(os1); } /* * length of string */ strlen(s) char *s; { int n; n = 0; while (*s++) n++; return(n); } /* * concatenate up to n chars of s2 onto the end of s1 */ strncat(s1, s2, n) char *s1; char *s2; int n; { char *os1; os1 = s1; while (*s1++) ; --s1; while (*s1++ = *s2++) if (--n < 0) { *--s1 = '\0'; break; } return(os1); } /* * compare up to n chars of s1 and s2 */ strncmp(s1, s2, n) char *s1; char *s2; int n; { while (--n >= 0 & *s1 == *s2++) if (*s1++ == '\0') return(0); if (n < 0) return(0); else return(*s1 - *--s2); } /* * copy n chars from s2 to s1, truncating or null padding if necessary */ strncpy(s1, s2, n) char *s1; char *s2; int n; { int i; char *os1; os1 = s1; for (i = 0; i < n; i++) if ((*s1++ = *s2++) == '\0') { while (++i < n) *s1++ = '\0'; return(os1); } return(os1); } /* * close i/o stream */ fclose(fp) FILE *fp; /* (pseudo) i/o stream pointer */ { return(close(fp)); } /* * open file by pathname */ fopen(name, mode) char *name; char *mode; { int fd; /* file descriptor for low level i/o */ if (*mode == 'w') { /* need to zap existing file under DFS/ADFS */ if ((fd = open(name, 2)) != -1) { close(fd); unlink(name); } /* create file (pmode ignored in this version ...) */ fd = creat(name, 0); } else /* anything else is assumed to be 'r' */ fd = open(name, 0); if (fd == -1) return(NULL); /* no file pointers in Small-C */ return(fd); } /* * a version of fgets that permits '\r' in lieu of * '\n' as end of line and allows character deletion */ fgets(s, n, fp) char *s; int n; FILE *fp; { int c; char *cs; cs = s; while (--n > 0 & (c = getc(fp)) != EOF) { if (c == DELETE) { if (--cs < s) cs = s; continue; } if (c == '\r') c = '\n'; if ((*cs++ = c) == '\n') break; } *cs = '\0'; if (c == EOF & cs == s) return(NULL); else return(s); } /* * Put null terminated string to output stream * ------------------------------------------- * map '\n' to '\r' for BBC Micro environment */ fputs(s, fp) char *s; FILE *fp; { char *p; int r; int c; if ((fp != stdin) & (fp != stdout) & (fp != stderr)) { for (p = s; *p; ++p) { if (*p == '\n') *p = '\r'; } } while (c = *s++) r = putc(c, fp); return(r); } gets(s) char *s; { int c; char *cs; cs = s; while ((c = getchar()) != '\n' & c >= 0) *cs++ = c; if (c < 0 & cs == s) return(NULL); else { *cs = '\0'; return(s); } } puts(s) char *s; { int c; while (c = *s++) putchar(c); return(putchar('\n')); } /* * formatted output */ printf(fmt, arg) char *fmt; /* output format */ int arg; /* argument list */ { char _iobuf[LINESIZE]; _doprint(_iobuf, fmt, &arg); fputs(_iobuf, stdout); } /* * formatted output to file */ fprintf(fp, fmt, arg) FILE *fp; /* output stream */ char *fmt; /* output format */ int arg; /* argument list */ { char _iobuf[LINESIZE]; _doprint(_iobuf, fmt, &arg); fputs(_iobuf, fp); } /* * formatted output to string */ sprintf(s, fmt, arg) char *s; /* output string */ char *fmt; /* output format */ int arg; /* argument list */ { _doprint(s, fmt, &arg); } /* * output format conversion */ _doprint(buf, fmt, arg) char *buf; /* output buffer */ char *fmt; /* output format */ int *arg[]; /* argument list */ { char *cp; /* pointer to start of conversion buffer */ char *bp; /* buffer pointer */ char pad; /* padding character */ char c; /* conversion character */ char *s; /* string pointer */ int width; /* minimum field width */ int precision; /* number of digits to print */ bp = buf; while (*fmt) { cp = bp; if (*fmt != '%') { *bp++ = *fmt++; continue; } if (*++fmt == '-') pad = *fmt++; else pad = ' '; if (*fmt == '0') { if (pad == '-') *fmt++; else pad = *fmt++; } width = 0; while (isdigit(*fmt)) width = width * 10 + *fmt++ - '0'; if (*fmt != '.') precision = -1; else { if (isdigit(*++fmt) == 0) precision = 1; else { precision = 0; while (isdigit(*fmt)) precision = precision * 10 + *fmt++ - '0'; } } if ((c = *fmt++) == 'd') { if (*arg & 0x8000) { *bp++ = '-'; bp = bp + itoa(-*arg, bp, 10); } else bp = bp + itoa(*arg, bp, 10); } else if (c == 'o') bp = bp + itoa(*arg, bp, 8); else if (c == 'u') bp = bp + itoa(*arg, bp, 10); else if (c == 'x') bp = bp + itoa(*arg, bp, 16); else if (c == 'X') bp = bp + itoa(*arg, bp, -16); else if (c == 'c') { *bp++ = *arg; *bp = '\0'; } else if (c == 's') { s = *arg; --bp; if (precision < 0) while (*++bp = *s++) ; else { while (*++bp = *s++) { if (precision-- == 0) { *bp = '\0'; break; } } } } else { *bp++ = c; *bp = '\0'; } if ((width = width - (bp - cp)) > 0) { if (pad == '-') { while (width-- > 0) *bp++ = ' '; *bp = '\0'; } else { if ((c == 'd') & (*cp == '-') & (pad == '0')) cp++; while (bp >= cp) *(bp + width) = *bp--; while (width-- > 0) *cp++ = pad; while (*bp++) ; --bp; } } arg++; } *bp = '\0'; } /* * convert unsigned 16-bit number to ASCII string * ---------------------------------------------- * returns number of digits in output string */ itoa(n, s, base) unsigned n; /* input value */ char *s; /* output buffer */ int base; /* conversion base */ { int d; /* current digit */ int xset; /* extended character set */ char *p; /* buffer pointer */ if (base >= 0) /* default is lower-case hex */ xset = 'a' - 10; else { /* 'negative' base used to force upper-case hex */ base = -base; xset = 'A' - 10; } /* generate string least significant digit first */ p = s; if (n == 0) *p++ = '0'; else { while (n) { if ((d = n % base) < 10) *p++ = d + '0'; else *p++ = d + xset; n = n / base; } } n = p - s; /* reverse digit string in-situ */ *p-- = '\0'; while (s < p) { d = *s; *s++ = *p; *p-- = d; } return(n); } /* * formatted input */ scanf(fmt, arg) char *fmt; int arg; { char _iobuf[LINESIZE]; return(_doscan(stdin, _iobuf, fmt, &arg)); } /* * formatted input from file */ fscanf(fp, fmt, arg) FILE *fp; char *fmt; int arg; { char _iobuf[LINESIZE]; return(_doscan(fp, _iobuf, fmt, &arg)); } /* * formatted input from string */ sscanf(s, fmt, arg) char *s; char *fmt; int arg; { return(_doscan(_IOSTRG, s, fmt, &arg)); } /* * input format conversion */ _doscan(fp, buf, fmt, arg) FILE *fp; /* input stream */ char *buf; /* i/o buffer */ char *fmt; /* conversion format */ int *arg[]; /* argument list */ { char *bp; /* conversion buffer pointer */ char *ip; /* i/o buffer pointer */ char fc; /* current format string character */ char ic; /* input character */ int width; /* input field width */ int sign; /* sign of decimal number */ int n; /* number input */ int digit; /* hex digit */ int assign; /* if using '*' suppression character */ int nmatch; /* number of successful conversions */ /* start with empty buffer if reading from file */ if (fp != _IOSTRG) *buf = '\0'; ip = buf; nmatch = 0; while (*fmt) { while ((fc != '%') | (ic == '\0')) { while (isspace(fc = *fmt++)) ; while (isspace(ic = *ip++)) ; if (fc == '\0') break; /* fill buffer unless input from string */ if (fp != _IOSTRG) { while (ic == '\0') { ip = buf; for (n = 0; n < LINESIZE; n++) { if ((ic = getc(fp)) == EOF) break; if (ic == DELETE) { if (--ip < buf) ip = buf; continue; } *ip++ = ic; if ((ic == EOL) | (ic == '\n')) break; } *ip = '\0'; if ((ic == EOF) & (ip == buf)) return(EOF); ip = buf; while (isspace(ic = *ip++)) ; } } if ((fc != '\0') & (fc != ic) & (fc != '%')) return(EOF); } if (fc == '\0') break; fc = *fmt++; if ((assign = (fc != '*')) == FALSE) fc = *fmt++; if (isdigit(fc) == 0) width = LINESIZE; else { width = 0; do { width = (width * 10 + fc - '0'); } while (isdigit(fc = *fmt++)); } n = 0; if (fc == 'd') { sign = 1; if (ic == '+') { ic = *ip++; --width; } else if (ic == '-') { ic = *ip++; sign = -1; --width; } if (isdigit(ic) == 0) return(EOF); while ((isdigit(ic) != 0) & (width-- > 0)) { n = n * 10 + ic - '0'; ic = *ip++; } n = n * sign; } else if (fc == 'o') { if ((ic < '0') | (ic > '7')) return(EOF); while ((ic >= '0') & (ic <= '7') & (width-- > 0)) { n = n * 8 + ic - '0'; ic = *ip++; } } else if (fc == 'x' | fc == 'X') { if (ic == '0') { if ((ic = *ip++) == fc) ic = *ip++; else return(EOF); } if (isxdigit(ic) == 0) return(EOF); while ((isxdigit(ic) != 0) & (width-- > 0)) { if (isdigit(ic)) digit = ic - '0'; else if (isupper(ic)) digit = ic - 'A' + 10; else if (islower(ic)) digit = ic - 'a' + 10; n = n * 16 + digit; ic = *ip++; } } else if (fc == 's') { if (assign) { bp = arg[nmatch++]; while ((ic != '\0') & (width-- > 0)) { *bp++ = ic; if (isspace(ic = *ip++)) break; } *bp = '\0'; } else { while ((ic != '\0') & (width-- > 0)) if (isspace(ic = *ip++)) break; } } else if (fc == 'c') { n = ic; ic = *ip++; --width; } else return(EOF); if ((assign != 0) & (fc != 's')) *(arg[nmatch++]) = n; --ip; } return(nmatch); } /* * convert string to integer */ atoi(s) char *s; { int n; int sign; int c; n = 0; sign = 1; /* no sign == positive */ if ((c = *s++) == '+') c = *s++; else if (c == '-') { c = *s++; sign = -1; } while (isdigit(c)) { n = n * 10 + c - '0'; c = *s++; } return(n * sign); } /* * extract command line arguments */ _cmdinit(enter) unsigned enter; /* entry point (should be int *()) */ { char *lp; /* pointer to command line */ char *bp; /* buffer pointer */ int argc; /* argument count */ int *argv[_MAXARG]; /* BUG - should be char *argv[32] */ char _argbuf[LINESIZE]; /* argument buffer */ lp = _cmdline(); /* get address of MOS command line */ bp = _argbuf; argv[0] = bp; /* argv[0] is name of invocation */ *bp++ = '\0'; /* argv[0] not accessible to MOS */ argc = 1; /* null argv[0] 'always' present */ while (*lp != EOL) { while (*lp == ' ' | *lp == '\t') lp++; if (*lp != EOL) argv[argc++] = bp; while (*lp != ' ' & *lp != '\t' & *lp != EOL) *bp++ = *lp++; *bp++ = '\0'; } enter(argc, argv); } /* lib.c 09-Apr-89 A.J.Travis */ /* * Part of the 'standard' C library */ /* JGH: Increase LINESIZE from 81 to 256 */ #include #de/* lpr.c 26-Jan-89 A.J.Travis */ /* * print files, with tabs expanded into spaces */ #include #define TRUE 1 #define FALSE 0 #define SAME 0 #if MSDOS #define DFS 0 #define EOL '\n' /* end of line */ #else #define DFS 1 #define ENABLE 2 /* enable printer */ #define DISABLE 3 /* disable printer */ #define EOL '\r' /* end of line */ #endif #define TABSIZ 8 /* tab width */ #define LINESIZ 81 /* line length + 1 */ #define LINEMAX 80 /* line length */ #define PAGESIZ 56 /* printed lines per page */ #define HALFPAGE ((PAGESIZ + 10) / 2) /* lines per half-page */ #define PRINTER stdout /* printer channel */ FILE *in; /* input file */ char buf[LINESIZ]; /* i/o buffer */ char *bp; /* buffer pointer */ int c; /* ASCII character */ int col; /* print column */ int line; /* print line */ int page; /* print page */ int paginate; /* paginate output */ int main(argc, argv) int argc; char *argv[]; { if (argc < 2) usage(); paginate = FALSE; /* default is no pagination */ while ((*argv[1] & 0xFF) == '-') { if (strcmp(argv[1], "-p") == SAME) { paginate++; --argc; argv++; } else usage(); } if (argc < 2) usage(); if ((in = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "lpr: can't open %s\n", argv[1]); exit(-1); } col = 1; line = 1; page = 1; bp = buf; #if DFS putc(ENABLE, PRINTER); #endif if (paginate == FALSE) putc('\f', PRINTER); while ((c = getc(in)) != EOF) { if (c == '\t') { do { *bp++ = ' '; } while (++col % TABSIZ != 1 & col < LINESIZ); } else if (c == EOL | col == LINEMAX) { if (col == LINEMAX) *bp++ = c; if (line++ % PAGESIZ == 1 & paginate == TRUE) { fprintf(PRINTER, "\f\n\n%-70s", argv[1]); fprintf(PRINTER, "page %d\n\n\n", page++); } *bp = '\0'; fprintf(PRINTER, "%s\n", buf); col = 1; bp = buf; } else { *bp++ = c; col++; } } fprintf(PRINTER, "\f***** page alignment *****"); for (c = 0; c < HALFPAGE; c++) putc('\n', PRINTER); #if DFS putc(DISABLE, PRINTER); #endif close(in); exit(0); } /* * report correct usage and exit */ usage() { fprintf(stderr, "usage: lpr [-p] file\n"); exit(-1); } /* lpr.c 26-Jan-89 A.J.Travis */ /* * print files, with tabs expanded into spaces */ #include |> mkcrt | Assemble stand-alone 'C' run-time code and external references | tcc -o lib/s -S lib/c as65 -o crt oshdr/s crt0/s crt1/s sys/s lib/s patch/s rename g/out ext/s | crt and ext/s made. |> mkcrt | Assemble stand-alone 'C' run-time code and external | > mksh | Build shell ROM image | tcc -o sh -R sh/c | > mksh | Build shell ROM image | tcc -o sh -R sh/c external references | tcc -o lib/s -S lib/c as65 -o crt oshdr/s crt0/s crt1/s sys/s lib/s patch/s rename g/out ext/s | crt and ext/s made. '\n' /*|> mkswcrt | Assemble ROM-resident 'C' run-time code and external references | tcc -o lib/s -S lib/c as65 -o swcrt oshdr/s swcrt/s crt1/s sys/s lib/s patch/s access swext/s delete swext/s rename g/out swext/s | swcrt and swext/s made. |> mkswcrt | Assemble# Makefile 01-May-89 A.J.Travis # # Make 6502 Small-C system for BBC Micro using Zortech C on MSDOS 3.2 host # # # 'old' Zorland C # # CC = zc # LIB = _main.obj # # 'new' Zortech C # CC = ztc LIB = _mains.obj CFLAGS = -p DEFINE = -DMSDOS=1 default : resident XFILES1 = dehex/x sh/x shar/x XFILES2 = crt/x swcrt/x as65/x cmp/x diff/x hex/x ld/x lpr/x optab/x XFILES3 = rm/x sfa/x tcc/x tccom/x tcpp/x SHARS = tcc1.sha tcc2.sha tcc3.sha tcc4.sha SHAR1 = $(XFILES2) SHAR2 = $(XFILES3) ctype/h enter/s errors ext/s get install mnemtab put \ start/s stdio/h swext/s SHAR3 = as65/c crt0/s crt1/s lib/c mkcrt mkswcrt mktcc optab/s oshdr/s \ patch/s sh/c swcrt/s sys/s SHAR4 = bm/c cmp/c dehex/c diff/c fahr/c hanoi/c hex/c ld/c lpr/c plot/c rm/c ! sfa/c shar/c sieve/c tcc/c tccom/c tcpp/c # # 8086/88 Binaries for MSDOS host # host : as65.exe optab hex.exe rm.exe shar.exe tcpp.exe tccom.exe tcc.exe ld.exe as65.exe : as65.c $(CC) $(CFLAGS) $(DEFINE) as65.c optab : optab/s as65 optab/s +rm optab +ren o/out optab hex.exe : hex.c $(CC) $(CFLAGS) $(DEFINE) hex.c rm.exe : rm.c $(CC) $(CFLAGS) $(DEFINE) rm.c $(LIB) shar.exe : shar.c $(CC) $(CFLAGS) $(DEFINE) shar.c $(LIB) tcpp.exe : tcpp.c $(CC) $(CFLAGS) $(DEFINE) tcpp.c tccom.exe : tccom.c $(CC) $(CFLAGS) $(DEFINE) tccom.c tcc.exe : tcc.c $(CC) $(CFLAGS) $(DEFINE) tcc.c ld.exe : ld.c $(CC) $(CFLAGS) $(DEFINE) ld.c # # resident 6502 binaries for Acorn DFS/MOS # resident : host crt swcrt as65 bm cmp dehex diff fahr hanoi hex ld lpr plot \ rm sfa sh shar sieve tcc tccom tcpp crt : oshdr/s crt0/s crt1/s sys/s lib/s patch/s +rm ext/s +as65 -o crt oshdr/s crt0/s crt1/s sys/s lib/s patch/s ren g/out ext/s swcrt : oshdr/s swcrt/s crt1/s sys/s lib/s patch/s +rm swext/s +as65 -o swcrt oshdr/s swcrt/s crt1/s sys/s lib/s patch/s ren g/out swext/s lib/s : lib.c tcc -S lib.c as65 : as65.c start/s swcrt tcc -o as65 as65.c bm : bm.c start/s swcrt tcc -o bm bm.c cmp : cmp.c start/s swcrt tcc -o cmp cmp.c dehex : dehex.c start/s swcrt tcc -o dehex dehex.c diff : diff.c start/s swcrt tcc -o diff diff.c fahr : fahr.c start/s swcrt tcc -o fahr fahr.c hanoi : hanoi.c start/s swcrt tcc -o hanoi hanoi.c hex : hex.c start/s swcrt tcc -o hex hex.c ld : ld.c start/s swcrt tcc -o ld ld.c lpr : lpr.c start/s swcrt tcc -o lpr lpr.c plot : plot.c start/s swcrt tcc -o plot plot.c rm : rm.c start/s swcrt tcc -o rm rm.c sfa : sfa.c start/s swcrt tcc -o sfa sfa.c sh : sh.c start/s swcrt tcc -R -o sh sh.c shar : shar.c start/s swcrt tcc -o shar shar.c sieve : sieve.c start/s swcrt tcc -o sieve sieve.c tcc : tcc.c start/s swcrt tcc -o tcc tcc.c tccom : tccom.c start/s swcrt tcc -o tccom tccom.c tcpp : tcpp.c start/s swcrt tcc -o tcpp tcpp.c # # Shell archive distribution # distrib : resident $(XFILES1) $(XFILES2) $(XFILES3) dfsname $(SHARS) dosname as65/x : as65 hex as65 as65/x bm/x : bm hex bm bm/x cmp/x : cmp hex cmp cmp/x crt/x : crt hex crt crt/x dehex/x : dehex hex dehex dehex/x diff/x : diff hex diff diff/x fahr/x : fahr hex fahr fahr/x hanoi/x : hanoi hex hanoi hanoi/x hex/x : hex hex hex hex/x ld/x : ld hex ld ld/x lpr/x : lpr hex lpr lpr/x plot/x : plot hex plot plot/x optab/x : optab hex optab optab/x rm/x : rm hex rm rm/x sfa/x : sfa hex sfa sfa/x sh/x : sh hex -R sh sh/x shar/x : shar hex shar shar/x sieve/x : sieve hex sieve sieve/x swcrt/x : swcrt hex swcrt swcrt/x tcc/x : tcc hex tcc tcc/x tccom/x : tccom hex tccom tccom/x tcpp/x : tcpp hex tcpp tcpp/x dfsname : ren ctype.h ctype/h ren stdio.h stdio/h ren makefile mktcc ren as65.c as65/c ren bm.c bm/c ren cmp.c cmp/c ren dehex.c dehex/c ren diff.c diff/c ren fahr.c fahr/c ren hanoi.c hanoi/c ren hex.c hex/c ren ld.c ld/c ren lib.c lib/c ren lpr.c lpr/c ren plot.c plot/c ren rm.c rm/c ren sfa.c sfa/c ren sh.c sh/c ren shar.c shar/c ren sieve.c sieve/c ren tcc.c tcc/c ren tccom.c tccom/c ren tcpp.c tcpp/c dosname : ren ctype/h ctype.h ren stdio/h stdio.h ren mktcc makefile ren as65/c as65.c ren bm/c bm.c ren cmp/c cmp.c ren dehex/c dehex.c ren diff/c diff.c ren fahr/c fahr.c ren hanoi/c hanoi.c ren hex/c hex.c ren ld/c ld.c ren lib/c lib.c ren lpr/c lpr.c ren plot/c plot.c ren rm/c rm.c ren sfa/c sfa.c ren sh/c sh.c ren shar/c shar.c ren sieve/c sieve.c ren tcc/c tcc.c ren tccom/c tccom.c ren tcpp/c tcpp.c tcc1.sha : $(SHAR1) shar -a tcc1.sha $(SHAR1) tcc2.sha : $(SHAR2) shar -a tcc2.sha $(SHAR2) tcc3.sha : $(SHAR3) shar -a tcc3.sha $(SHAR3) tcc4.sha : $(SHAR4) shar -a tcc4.sha $(SHAR4) clean : +rm compile.bat litfile a/out g/out +rm $(XFILES1) +rm $(XFILES2) +rm $(XFILES3) +rm *.obj *.map *.sha clobber : +rm ext/s swext/s lib/s crt swcrt optab as65 bm cmp dehex diff fahr +rm hanoi hex ld lpr plot rm sfa sh shar tcc tccom tcpp +rm *.exe # Makefile 01-May-89 A.J.Travis # # Make 6502 Small-C system for BBC Micro using Zortech C on MSDOS 3.2 host # # # 'old' Zorland C # # CC = zc # LIB = _main.obj # # 'new' Zortech C # CC = ztc LIB = _mains.obj CFLAGS = -p DEFINE = -DMS; optab.s 11-Apr-89 A.J.Travis ; ; opcode table for as65 (6502) assembler ; .byte $ff,$ff,$69,$65,$75,$ff,$6d,$7d,$79,$61,$71,$ff,$ff .byte $ff,$ff,$29,$25,$35,$ff,$2d,$3d,$39,$21,$31,$ff,$ff .byte $ff,$0a,$ff,$06,$16,$ff,$0e,$1e,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$90,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$b0,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$f0,$ff .byte $ff,$ff,$ff,$24,$ff,$ff,$2c,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$30,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$d0,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$10,$ff .byte $00,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$50,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$70,$ff .byte $18,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $d8,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $58,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $b8,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$c9,$c5,$d5,$ff,$cd,$dd,$d9,$c1,$d1,$ff,$ff .byte $ff,$ff,$e0,$e4,$ff,$ff,$ec,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$c0,$c4,$ff,$ff,$cc,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$c6,$d6,$ff,$ce,$de,$ff,$ff,$ff,$ff,$ff .byte $ca,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $88,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$49,$45,$55,$ff,$4d,$5d,$59,$41,$51,$ff,$ff .byte $ff,$ff,$ff,$e6,$f6,$ff,$ee,$fe,$ff,$ff,$ff,$ff,$ff .byte $e8,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $c8,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$ff,$ff,$ff,$4c,$ff,$ff,$ff,$ff,$ff,$6c .byte $ff,$ff,$ff,$ff,$ff,$ff,$20,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$a9,$a5,$b5,$ff,$ad,$bd,$b9,$a1,$b1,$ff,$ff .byte $ff,$ff,$a2,$a6,$ff,$b6,$ae,$ff,$be,$ff,$ff,$ff,$ff .byte $ff,$ff,$a0,$a4,$b4,$ff,$ac,$bc,$ff,$ff,$ff,$ff,$ff .byte $ff,$4a,$ff,$46,$56,$ff,$4e,$5e,$ff,$ff,$ff,$ff,$ff .byte $ea,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$09,$05,$15,$ff,$0d,$1d,$19,$01,$11,$ff,$ff .byte $48,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $08,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $68,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $28,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$2a,$ff,$26,$36,$ff,$2e,$3e,$ff,$ff,$ff,$ff,$ff .byte $ff,$6a,$ff,$66,$76,$ff,$6e,$7e,$ff,$ff,$ff,$ff,$ff .byte $40,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $60,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$e9,$e5,$f5,$ff,$ed,$fd,$f9,$e1,$f1,$ff,$ff .byte $38,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $f8,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $78,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$85,$95,$ff,$8d,$9d,$99,$81,$91,$ff,$ff .byte $ff,$ff,$ff,$86,$ff,$96,$8e,$ff,$ff,$ff,$ff,$ff,$ff .byte $ff,$ff,$ff,$84,$94,$ff,$8c,$ff,$ff,$ff,$ff,$ff,$ff .byte $aa,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $a8,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $ba,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $8a,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $9a,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff .byte $98,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff ; optab.s 11-Apr-89 A.J.Travis ; ; opcode table for as65 (6502) assembler ; .byte $ff,$ff,$69,$65,$75,$ff,$6d,$7d,$79,$61,$71,$ff,$ff .byte $ff,$ff,$29,$25,$35,$ff,$2d,$3d,$39,$21,$31,$ff,$ff ; oshdr.s 26-Jan-89 A.J.Travis ; ; operating system header file for tcc run-time support ; ; ; pseudo regs in page zero ; ; 2 lsb of primary are kept in the ; x and y registers whenever possible ; pr =$70 ;primary reg (32-bits) sr =$74 ;secondary reg (32-bits) tr =$78 ;tertiary reg (32-bits) sp =$7c ;data stack pointer (16-bits) ; ; page zero workspace ; rsp =$7e ;return stack pointer asave =$7f ;temp for a param =$80 ;page zero parameter block ; ; MOS variables ; osrom =$f4 ;number of sideways ROM being executed ; ; MOS vectors ; userv =$200 ;user vector brkv =$202 ;brk vector irq1v =$204 ;primary interrupt vector irq2v =$206 ;unrecognised irq vector cliv =$208 ;command line interpreter bytev =$20a ;*fx/osbyte call wordv =$20c ;osword call wrchv =$20e ;write character rdchv =$210 ;read character filev =$212 ;load/save file argsv =$214 ;load/save file data bgetv =$216 ;get byte from file bputv =$218 ;put byte in file gbpbv =$21a ;multiple bput/bget findv =$21c ;open or close file fscv =$21e ;file system control entry evntv =$220 ;event vector uptv =$222 ;user print routine netv =$224 ;econet vector vduv =$226 ;unrecognised vdu commands keyv =$228 ;keyboard vector insv =$22a ;insert into buffer vector remv =$22c ;remove from buffer vector cnpv =$22e ;count/purge buffer vector ind1v =$230 ;spare vector ind2v =$232 ;spare vector ind3v =$234 ;spare vector ; ; page 4 workspace ; gsbuf =$0400 ;general string input buffer ; ; MOS interface ; osurom =$8000 ;user paged ROM/RAM area osrdrm =$ffb9 ;read byte from paged ROM oseven =$ffbf ;generate an event gsinit =$ffc2 ;string input initialise gsread =$ffc5 ;read char from string nvwrch =$ffc8 ;non-vectored write char nvrdch =$ffcb ;non-vectored read char osfind =$ffce ;open/close file osgbpb =$ffd1 ;group get/put bytes osbput =$ffd4 ;put byte to file osbget =$ffd7 ;get byte from file osargs =$ffda ;load/save file data osfile =$ffdd ;load/save complete file osrdch =$ffe0 ;read char (key/RS423) osasci =$ffe3 ;write ascii char (vdu/RS423) osnewl =$ffe7 ;write lf,cr (vdu/RS423) oswrch =$ffee ;write char (vdu/RS423) osword =$fff1 ;MOS word call (control block) osbyte =$fff4 ;MOS byte/*fx call oscli =$fff7 ;command line interpreter ; ; oshdr.s 26-Jan; patch.s 20-Apr-87 A.J.Travis ; ; patch a jump here from startup code ; __enter ; ; patch.s 20-Apr-87 A.J.Travis ; ; patch a jump here from startup code ; __enter ; pport ; ; ; pseudo regs in page zero ; ; 2 lsb of primary are kept in the ; x and y/* plot.c 19-Nov-88 Modified by A.J.Travis */ /* * recursive boxes in Small-C by Jon Welch * --------------------------------------- * The plot program should be run in graphics mode 1. * mode() added by J.G.Harston 01-Jul-90 */ #include #define N 6 #define H0 1024 int h,x0,y0,x,y,loop; int main() { init(); mode(1); for (loop=1;loop<=N;loop++) { vdu(18); vdu(0); vdu(loop % 3+1); xyset(); sides(loop,0); } exit(0); } mode(a) int a; { if (osbyte(130,0) < 0 & osbyte(133,a | 0x80)-osbyte(132,0) <0 ) { printf("Restart in mode %d.\n",a); exit(1); /* If not in tube, and no memory for mode change, stop */ } vdu(22); vdu(a | 0x80); } plot(k,x,y) int k,x,y; { vdu(25); vdu(k); vdu(x); vdu(x >> 8); vdu(y); vdu(y >> 8); } addx() { x=x+h; plot(5,x,y); } subx() { x=x-h; plot(5,x,y); } addy() { y=y+h; plot(5,x,y); } suby() { y=y-h; plot(5,x,y); } or1(a) int a; { sides(a,3); subx(); sides(a,0); suby(); sides(a,0); addx(); sides(a,1); } or2(a) int a; { sides(a,2); addy(); sides(a,1); addx(); sides(a,1); suby(); sides(a,0); } or3(a) int a; { sides(a,1); addx(); sides(a,2); addy(); sides(a,2); subx(); sides(a,3); } or4(a) int a; { sides(a,0); suby(); sides(a,3); subx(); sides(a,3); addy(); sides(a,2); } sides(a,b) int a,b; { if (a != 0) { a=a-1; if (b==0) or1(a); else if (b==1) or2(a); else if (b==2) or3(a); else or4(a); } } init() { h=H0; x0=h / 2; y0=h / 2; } xyset() { h=h / 2; x0=x0+h / 2; y0=y0+h / 2; x=x0; y=y0; plot(4,x,y); } /* plot.c 19-Nov-88 Modifie/* rm.c - Remove files */ /* 07-Apr-1989 v0.70 - A.J.Travis */ /* 22-Jun-1991 v0.71 - J.G.Harston * main() ends with exit(0); */ #include #ifdef MSDOS #include #define PLAIN 0x21 /* plain file [read-only] [archive] */ #define CFLAG 1 /* 8086 carry flag */ #else #define W_CAT 1 /* write MOS catalogue info */ #define MODE 0 /* file mode */ #define ATTRIB 7 /* file attributes */ #define LOCKED 0x88 /* owner + other delete locks */ #define UNLOCK 0x77 /* permit owner + other delete */ #define EXISTS 0 /* file exists */ #define PLAIN 1 /* plain file */ #define DIRECTORY 2 /* directory file */ int fcb[9]; /* file control block */ #endif #define ERROR -1 #define OK 0 #define SAME 0 /* strcmp() strings equal */ int force; /* force removal of locked files */ int main(argc, argv) int argc; char *argv[]; { if (argc == 1) usage(-1); force = 0; while ((*argv[1] & 0xFF) == '-') { /* BUG in compiler */ if (strcmp(argv[1], "-f") == SAME) force++; else usage(-1); --argc; argv++; } while (--argc > 0) { if (force) kill(argv[1]); else delete(argv[1]); argv++; } exit(0); } /* * kill file * --------- * delete even if locked, and don't complain about non-existent files */ kill(file) char *file; /* name of file to delete */ { #ifdef MSDOS union REGS reg; reg.h.ah = 0x43; /* MSDOS chmod function */ reg.h.al = 0x01; /* set attribute mode */ reg.x.cx = 0x00; /* 'normal' attributes */ reg.x.dx = file; /* address of filename */ /* Carry set indicates an error */ if ((intdos(®, ®) & CFLAG) == OK) unlink(file); #else if (stat(file, fcb) == EXISTS) { if (fcb[MODE] & PLAIN) { fcb[ATTRIB] = fcb[ATTRIB] & UNLOCK; osfile(file, fcb, W_CAT); /* unlock file */ unlink(file); } } #endif } /* * delete file */ delete(file) char *file; /* name of file to delete */ { #ifdef MSDOS if (findfirst(file, PLAIN) == NULL) fprintf(stderr, "rm: %s not found\n", file); else if (unlink(file) == ERROR) fprintf(stderr, "rm: %s permission denied\n", file); #else if (stat(file, fcb) != EXISTS) fprintf(stderr, "rm: %s not found\n", file); else if (fcb[MODE] & PLAIN) { if (fcb[ATTRIB] & LOCKED) fprintf(stderr, "rm: %s permission denied\n", file); else unlink(file); } else if (fcb[MODE] & DIRECTORY) fprintf(stderr, "rm: can't remove directory %s\n", file); else fprintf(stderr, "rm: %s file type error\n", file); #endif } /* * report correct usage, and exit */ usage(stat) int stat; /* exit status */ { fprintf(stderr, "usage: rm [-f] file1 ... [filen]\n"); exit(stat); } /* rm.c - Remove files */ /* 07-Apr-1989 v0.70 - A.J.Travis */ /* 22-Jun-1991 v0.71 - J.G.Harston * main() ends with exit(0); */ #include #ifdef MSDOS #include #define W_CAT 1 /* write MOS catalogue info */ #define RW 3 /* read/write attributes */ #define LOAD 0x1902 /* default load address */ #define EXEC 0x1902 /* default exec address */ int main(argc, argv) int argc; char *argv[]; { int *fcb[9]; /* file control block */ if (argc != 2) usage(); if (stat(argv[1], fcb) == -1) { fprintf(stderr, "sfa: %s not found\n", argv[1]); exit(-1); } fcb[0] = 0; fcb[1] = LOAD; fcb[2] = 0; fcb[3] = EXEC; fcb[4] = 0; fcb[5] = 0; fcb[6] = 0; fcb[7] = RW; fcb[8] = 0; osfile(argv[1], fcb, W_CAT); exit(0); } /* * report correct usage and exit */ usage() { fprintf(stderr, "usage: sfa file\n"); exit(-1); } /* sfa.c - 11 Apr 88 A.J.Travis */ /* * Set File Attributes for BBC Micro DFS/ADFS binaries */ #include #define W_CAT 1 /* write MOS catalogue info */ #define RW 3 /* read/write attributes */ #define LOAD 0x/* sh.c - Small-C command shell * ----------------------------- */ /* 01-Dec-1988 0.70 - A.J.Travis * 22-Jun-1991 0.71 - J.G.Harston * Checks any exec file after reading line, closes it if at EOF. * Allows last line of exec file to delete itself to tidy up. * mode forces mode+128, '*' disables escape event, passes return * value from system() to exit(), prints return value from FX1. */ #include #define SAME 0 /* strcmp() strings equal */ #define LINESIZE 128 /* length of command line + '\0' */ #define LINEMAX 127 /* length of command line */ #define SH_EOF '\004' /* i/o end of file char */ main() { char *p1, *p2; /* line pointers */ int mode; /* VDU mode */ int eof; /* end of file */ char line[LINESIZE]; /* command line */ if (eof = (osbyte(1, 0) & 0xFF)) /* get return value */ printf("Return value: &%02X.\n", eof); eof = 0; do { osbyte(126, 0); /* clear any escapes */ fputs("$ ", stdout); /* prompt */ p1 = p2 = fgets(line, LINEMAX, stdin); /* Close exec file if at end - allows it to delete itself */ if (eof = (osbyte(198, 0xFF00) & 0xFF)) if (osbyte(127, eof) & 0xFF) system("exec"); /* clean up command line */ while (*p2 == ' ') ++p2; while (*p1 = *p2++) { if (*p1++ == '\n') --p1; } if (strncmp(line, "mode", 4) == SAME) { p1 = line + 4; while (*p1 == ' ') ++p1; if (isdigit(*p1)) { mode = *p1 - '0'; vdu(22); vdu(mode | 0x80); exit(0); /* resets tcc data stack */ } } /* exit on ^D */ if (*line == SH_EOF) eof++; else { if (*line == '*') { osbyte(13,6); /* disable escape event */ p1=0xFF00; /* look for an RTS */ while (*p1 != 0x60) ++p1; *(0x0220)=p1; /* remove event vector */ } exit(system(line)); /* reinstall escape handler */ } } while (eof == 0); exit(0); } /* sh.c - Small-C command shell * ----------------------------- */ /* 01-Dec-1988 0.70 - A.J.Travis * 22-Jun-1991 0.71 - J.G.Harston * Checks any exec file after readin/* shar.c 11-Apr-89 A.J.Travis */ /* * Unix style 'shell' archiver */ #include #if MSDOS #include #define EOL '\n' struct FIND *files; #else #define EOL '\r' #endif #define UNDEFINED NULL /* i/o stream status */ #define ERRTERM "shar: parse error - \"<<\" expected\n" #define ERRTO "shar: parse error - \">\" expected\n" #define ESCRIPT "shar: sed script not recognised\n" #define ELINE "shar: error extracting %s\n", path #define TRUE 1 #define FALSE 0 #define SAME 0 /* strncmp() strings equal */ #define LINESIZE BUFSIZ FILE *in; /* input file */ FILE *out; /* output file */ char line[LINESIZE]; /* i/o buffer */ char path[80]; /* pathname */ char cmd[80]; /* sed or cat command string */ char script[80]; /* sed edit script */ char term[80]; /* 'here' << document terminator */ int skip; /* length of shar prefix to skip */ int terml; /* length of terminator */ int sed; /* sed or cat command */ int cflag; /* create archive */ int xflag; /* extract files */ int main(argc, argv) int argc; char *argv[]; { in = UNDEFINED; /* default input stream */ out = UNDEFINED; /* default output stream */ cflag = FALSE; xflag = FALSE; /* first argument is mandatory flag */ if (argc < 3) usage(); if (strcmp(argv[1], "-a") == SAME) cflag++; else if (strcmp(argv[1], "-x") == SAME) xflag++; else usage(); --argc; argv++; /* next argument is name of archive */ if (xflag) { if ((in = fopen(argv[1], "rb")) == NULL) cant(argv[1]); /* for simplicity, just extract the lot */ extract(); } else { if ((out = fopen(argv[1], "w")) == NULL) cant(argv[1]); --argc; argv++; /* remaining arguments are files to archive */ while (--argc) { archive(argv[1]); argv++; } } exit(0); } /* * report correct usage, and exit */ usage() { fprintf(stderr, "usage: shar [-a] [-x] archive file1 ... [filen]\n"); exit(-1); } /* * print file access error, and exit */ cant(name) char *name; /* name of problem file */ { fprintf(stderr, "shar: can't open %s\n", name); if (in != UNDEFINED) close(in); if (out != UNDEFINED & out != stdout) close(out); exit(-1); } /* * create shell archive */ archive(name) char *name; /* name of file to archive */ { char *bp; /* buffer pointer */ if ((in = fopen(name, "r")) == NULL) cant(name); fprintf(out, "sed 's/^X//' << 'SHAR_EOF' > %s%c", name, EOL); while (fgets(line, LINESIZE, in) != NULL) { bp = line; while (*bp) { if ((*bp == '\r') | (*bp == '\n')) break; else bp++; } *bp++ = EOL; *bp = '\0'; fprintf(out, "X%s", line); } fprintf(out, "SHAR_EOF%c", EOL); fclose(in); } /* * extract files from shell archive */ extract() { int filen; char *p; char *dp; filen = 0; while (fgets(line, LINESIZE, in) != NULL) { /* strip shell escape chars and quotes */ p = line; dp = cmd; while (*p) { if ((*p == '\\') | (*p == '\'')) p++; else *dp++ = *p++; } *--dp = '\0'; #if MSDOS /* check for sub-directory tree */ if (strncmp(cmd, "cd", 2) == SAME) { printf("%s\n", cmd); p = cmd + 2; dp = path; while (isspace(*p)) p++; while (isspace(*dp++ = *p++) == FALSE) ; *--dp = '\0'; if ((files = findfirst(path, 0x10)) == NULL) { printf("mkdir %s\n", path); mkdir(path); } if (chdir(path) == -1) { fprintf(stderr, "shar: %s not found\n", path); exit(-1); } continue; } #endif /* parse 'sed' command */ if (strncmp(cmd, "sed", 3) == SAME) { sed = TRUE; printf("%s\n", cmd); /* extract 'sed' script */ p = cmd + 3; dp = script; while (isspace(*p)) p++; if (strncmp(p, "s/", 2) != SAME) { fprintf(stderr, ESCRIPT); exit(-1); } p = p + 2; if (*p == '^') p++; for (skip = 0; *p != '/'; skip++) { if ((*dp++ = *p++) == '\0') { fprintf(stderr, ESCRIPT); exit(-1); } } *dp = '\0'; } /* parse 'cat' command */ else if (strncmp(cmd, "cat", 3) == SAME) { sed = FALSE; printf("%s\n", cmd); p = cmd + 3; } else continue; /* look for "<< terminator" in command line */ p = cmd; dp = term; while (*p++ != '<') ; if (*p++ != '<') { fprintf(stderr, ERRTERM); exit(-1); } while (isspace(*p)) p++; while (isspace(*dp++ = *p++) == FALSE) ; *--dp = '\0'; terml = strlen(term); /* look for "> pathname" in command line */ p = cmd; dp = path; while (*p != '>') { if (*p++ == '\0') { fprintf(stderr, ERRTO); exit(-1); } } while (isspace(*++p)) ; while (isspace(*dp++ = *p++) == FALSE) ; *--dp = '\0'; #if MSDOS /* check for illegal DOS filenames */ if (strncmp(path, "aux", 3) == SAME) { printf("filename conflicts with AUX:, ", path); sprintf(path, "xxx%d", filen++); printf("renamed %s\n", path); } #endif while ((out = fopen(path, "wb")) == NULL) { printf("can't open %s, ", path); sprintf(path, "xxx%d", filen++); printf("renamed %s\n", path); } /* extract file contents according to sed/cat format */ while (fgets(line, LINESIZE, in)) { if (sed) { if (strncmp(line, script, skip) == SAME) fputs(line + skip, out); else if (strncmp(line, term, terml) == SAME) { fclose(out); break; } else { fprintf(stderr, ELINE); break; } } else { if (strncmp(line, term, terml) == SAME) { fclose(out); break; } fputs(line, out); } } } fclose(in); } /* shar.c 11-Apr-89 A.J.Travis */ /* * Unix style 'shell' archiver */ #include #if MSDOS #include #define /* Eratosthenes Sieve benchmark */ #define true 1 #define false 0 #define size 8190 #define sizepl 8191 char flags[sizepl]; int main() { int i, prime, k, count, iter; printf("10 iterations\n"); iter = 1; while (iter <= 10) { count = 0; i = 0; while (i <= size) { flags[i] = true; i++; } i = 0; while (i <= size) { if (flags[i]) { prime = i + i + 3; k = i + prime; while (k <= size) { flags[k] = false; k = k + prime; } count++; } i++; } iter++; } printf("\n%d primes\n", count); exit(0); } /* Eratosthenes Sieve benchmark */ #define true 1 #define false 0 #define size 8190 #define sizepl 8191 char flags[sizepl]; int main() { int i, prime, k, count, iter; printf("10 iterations\n"); it; swcrt.s 22-Apr-89 A.J.Travis ; ; startup code for tcc run-time support ; in user sideways ROM/RAM area above $8000 ; ; 23-Jun-1991 v0.71 - J.G.Harston ; ~restart-1 pushed onto machine stack instead of ~restart ; prints with osasci instead of oswrch *=osurom ; evs = tr ;pointer to extended vector space ebrkv = $ff03 ;extended break vector eevntv = $ff30 ;extended event vector ; ; language entry ; jmp ~lang ; ; service entry ; jmp ~serv ; ; ROM type (service and language entry) ; .byte %11000010 ; ; copyright offset pointer ; .byte ~cpmess - osurom - 1 ; ; binary version number ; .byte 07 ; ; title string ; ~title .text "Small-C" .byte 0 ; ; version string ; ~version .text "0.72" .text " (23 Jun 1991)" .byte 0 ; ; copyright message ; ~cpmess .text "(C)1989 A.J.Travis" .byte 0 ; ; Small-C command shell help ; ~helpmess .text "NAME" .byte $0d .text " sh - Small-C command shell" .byte $0d,$0d .text "SYNOPSIS" .byte $0d .text " *" ; ; Small-C command shell name ~shell .text "sh" .byte $0d,$0d .text "DESCRIPTION" .byte $0d .text " Sideways ROM/RAM version of Small-C" .byte $0d .text " run-time support, and tcc library." .byte $0d .text " *sh invokes an interactive shell." .byte $0d,$0d .text "AUTHOR" .byte $0d .text " A.J.Travis" .byte $0d,$00 ; ; check service call ; ~serv pha ;save registers tya pha txa pha ; tsx lda $103,x ;service type requested cmp #$04 ;unrecognised command? bne ~qhelp ; ; scan MOS command line for name of Small-C command shell ; ------------------------------------------------------- ; exit with registers preserved if not selected ; ~qshell ldx #$00 ~scan2 lda ~shell,x cmp ($f2),y beq ~scan3 eor #$20 cmp ($f2),y bne ~notme ~scan3 cmp #$0d beq ~startup iny inx jmp ~scan2 ~notme jmp ~out ; ; start up language ; ~startup lda #$8e ;start language ldx osrom ;current ROM id jmp osbyte ; ; check for *help [sh] ; ~qhelp cmp #$09 ;*help request? bne ~notme jsr osnewl lda ($f2),y ;*help ? cmp #$0d bne ~morehelp ldx #0 ~help1 lda ~title,x ;print ROM title beq ~help2 jsr oswrch inx jmp ~help1 ~help2 lda #$20 ;space jsr oswrch ldx #0 ~help3 lda ~version,x ;print ROM version beq ~help4 cmp #$20 beq ~help4 jsr oswrch inx jmp ~help3 ~help4 jsr osnewl lda #$20 ;space jsr oswrch jsr oswrch ldx #0 ~help5 lda ~shell,x ;print help prompt jsr osasci inx cmp #$0d bne ~help5 jmp ~out ; ; expand Small-C command shell help if requested ; ~morehelp ldx #0 ~scan4 lda ~shell,x cmp #$0d beq ~dohelp cmp ($f2),y beq ~scan5 eor #$20 cmp ($f2),y bne ~out ~scan5 iny inx jmp ~scan4 ~dohelp ldy #0 lda #<~helpmess sta tr lda #>~helpmess sta tr + 1 ~help7 lda (tr),y beq ~help8 jsr osasci inc tr bne ~help7 inc tr + 1 jmp ~help7 ~help8 jsr osnewl ~complete tsx lda #0 ;stop further processing sta $103,x ;clobber service request ~out pla ;restore registers and exit tax pla tay pla rts ; ; language entry point ; -------------------- ; initialise sp (data stack pointer) ; and enter command shell ; ~lang ~restart lda #$a8 ;get extended vector space ldx #$00 ldy #$ff jsr osbyte ;returns evs in xy stx evs sty evs + 1 ; ldy #3 ;brkv = vector #1 * 3 lda #break sta (evs),y iny lda osrom ;current ROM id sta (evs),y ; ldy #48 ;evntv = vector #16 * 3 lda #escape sta (evs),y iny lda osrom ;current ROM id sta (evs),y ; lda #ebrkv sta brkv+1 lda #eevntv sta evntv+1 ; ; warm start ; ; was ~restart lda #14 ;enable escape event ldx #6 jsr osbyte cli ;enable interrupts cld ldx #$ff ;initialise return stack txs lda #>~restart-1 ;place return addr on stack pha lda #<~restart-1 pha tsx stx rsp ;save value of return stack pointer lda #$84 ;read bottom of display RAM jsr osbyte stx sp sty sp+1 jmp __enter ;user entry point ; ; BRK handler ; break ldy #1 ;offset to start of message ~break1 lda ($fd),y ;error message pointer = $fd,$fe beq ~break2 ;null terminated message jsr oswrch iny jmp ~break1 ~break2 jsr osnewl jmp ~lang ;cold start ; ; swcrt.s 22-Apr-89 A.J.Travis ; ; sta; sys.s 07-Apr-88 A.J.Travis ; ; Operating system interface for tcc under Acorn/BBC MOS ; ; 20-Jun-1991 v0.71 - J.G.Harston ; system/exit pass return value via osbyte 1 ; ; escape trap ; escape cmp #6 ;escape event? bne ~escape1 lda #13 ;disable escape event ldx #6 ;event no. jsr osbyte lda #$7e ;acknowledge escape condition jsr osbyte lda #0 ;close all open files ldy #0 jsr osfind lda #$b2 ;write keyboard semaphore ldy #$00 ;and y ldx #$ff ;eor x (enable keyboard interrupts) jsr osbyte brk .byte $11 ;escape 'error' code .byte $0a,$0d ;lf/cr .text "escape" .byte 0 ~escape1 rts ; ; exit() ; ------ ; exit from user program ; _exit lda #1 ; return value is in xy jsr osbyte ; set return value ldx rsp ; get stored SP txs ; restore stack rts ; and return ; ; open(name, rwmode) ; ------------------ ; exit with error status if file does not exist ; new files are opened with creat() ; MOS modes: read=$40, write=$80, r/w=$c0 ; _open jsr ~gsconv ;convert filename lda #gsbuf sta param+1 lda #5 ;read catalogue information ldx #param jsr osfile cmp #0 beq ~openerr ;if zero, file does not exist ; ldy #2 lda (sp),y ;rwmode lo clc adc #1 ;convert to MOS format ror a ror a ror a ldx #gsbuf jsr osfind tax ;return fd in xy beq ~openerr ;unless zero file handle ; ldy #0 rts ~openerr ldx #$ff ;return -1 on error ldy #$ff rts ; ; creat(name, pmode) ; ------------------ ; pmode ignored in this version ... ; _creat jsr ~gsconv lda #$80 ;open in write mode ldx #gsbuf jsr osfind tax ;return fd in xy beq ~createrr ;unless zero file handle ; ldy #0 rts ~createrr ldx #$ff ;return -1 on error ldy #$ff rts ; ; close(fd) ; _close ldy #0 lda (sp),y ;fd lo tay ;MOS fd parameter lda #0 ;close file operation jsr osfind rts ; ; unlink(name) ; _unlink jsr ~gsconv lda #gsbuf sta param+1 lda #6 ;delete file ldx #param jsr osfile rts ; ; stat(name, fcb) ; _stat lda #5 ;read catalogue information jmp ~osfile ; ; system(string) ; -------------- ; execute MOS command ; _system jsr ~gsconv ; convert to MOS format ldx #gsbuf jsr oscli lda #1 ; recover return value ldx #0 ; clear it once read jsr osbyte ; read return value into x ldy #0 ; clear y rts ; return return value in xy ; ; export address of MOS command line to C environment ; __cmdlin lda #1 ;get address of MOS command line ldx #param ;4 byte parameter block ldy #0 ;no file descriptor involved jsr osargs ldx param ;return address of '\r' terminated line ldy param+1 rts ; ; convert string from C to MOS format ; ----------------------------------- ; string is null terminated in c, $0d terminated in MOS ; use pr to copy filename from addr pointed to by ; top stack item into MOS general string input buffer ; ~gsconv ldy #0 lda (sp),y ;name lo sta pr iny lda (sp),y ;name hi sta pr+1 ldy #0 ~conv lda (pr),y sta gsbuf,y ;parameter block for call beq ~term iny bne ~conv ;max length = 255 chars ~term lda #13 ;replaces C '\0' sta gsbuf,y rts ; ; read(fd, buf, count) ; -------------------- ; checks eof on fd before attempting to read ; _read ldy #0 lda (sp),y ;fd tax ;MOS fd in x lda #127 ;check eof operation jsr osbyte txa ;exit status in x beq ~doread ;x=$ff is eof ldx #0 ;return 0 ldy #0 rts ~doread lda #4 pha jmp ~access ; ; write(fd, buf, count) ; _write ldy #0 lda (sp),y ;fd cmp #1 ;fd 1 is stdout beq ~sput cmp #2 ;fd 2 is stderr beq ~sput lda #2 pha jmp ~access ; ; string output on stdout or stderr ; ~sput ldy #2 lda (sp),y ;buf lo sta pr iny lda (sp),y ;buf hi sta pr+1 iny lda (sp),y ;count lo sta tr iny lda (sp),y ;count hi tax ldy #0 ~sput1 lda tr bne ~sput2 cpx #0 beq ~sput3 dex ~sput2 dec tr lda (pr),y jsr ~aput iny bne ~sput1 inc pr+1 jmp ~sput1 ~sput3 rts ; ; MOS file access interface to tcc ; -------------------------------- ; on entry: ; a=2: write, ignoring new file ptr ; a=4: read, ignoring new file ptr ; ; high order buffer address is zero, so the 6502 second processor ; accesses the 'correct' buffer in second processor memory. ; ~access ldy #0 lda (sp),y ;fd lo sta param ldy #2 lda (sp),y ;buf addr lo sta param+1 iny lda (sp),y ;buf addr hi sta param+2 lda #0 ;hi order buf addr bytes sta param+3 sta param+4 iny lda (sp),y ;count lo sta param+5 iny lda (sp),y ;count hi sta param+6 lda #0 sta param+7 ;zero high order count sta param+8 pla ;get access mode ldx #param jsr osgbpb sec ;calc no. transfers ldy #4 lda (sp),y ;count lo sbc param+5 ;resid lo tax ;ntransfers lo iny lda (sp),y ;count hi sbc param+6 ;resid hi tay ;ntransfers hi rts ; ; getc(fd) ; _getc ldy #0 lda (sp),y ;fd lo beq ~getchar ;fd 0 is stdin tay ;MOS fd in y jsr osbget bcs ~geof ;c indicates eof on fd tax jmp ext ;sign extend char ~geof ldx #$ff ;return -1 on eof ldy #$ff rts ; ; input char from keyboard/rs423 ; ~getchar jsr osrdch cmp #$0d ;\r bne ~echo jsr oswrch ;echo \r on input lda #$0a ;map \r to \n on input ~echo jsr oswrch ;echo chars on input tax jmp ext ;sign extend char ; ; putc(c, fd) ; _putc ldy #0 lda (sp),y ;char to put tax ;save in x for now ldy #2 lda (sp),y ;fd cmp #1 ;fd 1 is stdout beq ~xput cmp #2 ;fd 2 is stderr beq ~xput tay ;MOS fd in y txa ;MOS char in a jsr osbput rts ; ; output x to screen/rs423 ; ~xput txa ; ; output a to screen/rs423 ; ~aput cmp #$0a ;\n beq ~mapn jsr oswrch rts ; ; map \n to \r\n on output ; ~mapn lda #$0d ;\r jsr oswrch lda #$0a ;\n jsr oswrch rts ; ; vdu(c) ; ------ ; output char to keyboard/rs423 without \n to \r\n transformation ; _vdu ldy #0 lda (sp),y jsr oswrch rts ; ; osbyte(type, parameters) ; ------------------------ ; MOS "osbyte" interface ; a is type of call ; x and y are parameters ; _osbyte ldy #2 lda (sp),y ;x parameter tax iny lda (sp),y ;y parameter sta asave ;save it ldy #0 lda (sp),y ;type of call ldy asave jsr osbyte rts ;return val in xy ; ; osword(type, address) ; --------------------- ; MOS "osword" interface ; a is type of call ; (x + y << 8) is address of parameter block ; _osword ldy #2 lda (sp),y ;address lo tax iny lda (sp),y ;address hi sta asave ;save it ldy #0 lda (sp),y ;type of call ldy asave jsr osword tya tax ;return y in low byte php pla and #$01 tay ;return carry in high byte rts ;return val in xy ; ; osfile(name, fcb, type) ; ----------------------- ; MOS osfile interface ; _osfile ldy #4 lda (sp),y ;osfile type ~osfile pha ;save type jsr ~gsconv ;convert name to MOS format ldy #2 lda (sp),y ;fcb address lo sta tr iny lda (sp),y ;fcb address hi sta tr+1 ldy #0 lda #gsbuf sta (tr),y ;fcb address hi pla ;osfile type ldx tr ;addr of fcb ldy tr+1 jsr osfile cmp #0 ;check MOS exit status, 0 = no file bne ~osfile1 ldx #$ff ;return -1 if no file found ldy #$ff rts ~osfile1 ldx #0 ;return 0 otherwise ldy #0 sta (tr),y ;leave MOS file type in fcb rts ; ; isalpha(c) ; _isalpha ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$03 ;_U | _L tax beq ~isalpha1 ldx #$01 ;return true ~isalpha1 rts ;result in x ; ; isupper(c) ; _isupper ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$01 ;_U tax beq ~isupper1 ldx #$01 ;return true ~isupper1 rts ;result in x ; ; islower(c) ; _islower ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$02 ;_L tax beq ~islower1 ldx #$01 ;return true ~islower1 rts ;result in x ; ; isdigit(c) ; _isdigit ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$04 ;_N tax beq ~isdigit1 ldx #$01 ;return true ~isdigit1 rts ;result in x ; ; isxdigit(c) ; _isxdigi ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$44 ;_N | _X tax beq ~isxdigit1 ldx #$01 ;return true ~isxdigit1 rts ;result in x ; ; isspace(c) ; _isspace ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$08 ;_S tax beq ~isspace1 ldx #$01 ;return true ~isspace1 rts ;result in x ; ; ispunct(c) ; _ispunct ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$10 ;_P tax beq ~ispunct1 ldx #$01 ;return true ~ispunct1 rts ;result in x ; ; isalnum(c) ; _isalnum ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$07 ;_U | _L | _N tax beq ~isalnum1 ldx #$01 ;return true ~isalnum1 rts ;result in x ; ; isprint(c) ; _isprint ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$17 ;_P | _U | _L | _N tax beq ~isprint1 ldx #$01 ;return true ~isprint1 rts ;result in x ; ; iscntrl(c) ; _iscntrl ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$20 ;_C tax beq ~iscntrl1 ldx #$01 ;return true ~iscntrl1 rts ;result in x ; ; isascii(c) ; _isascii ldy #0 lda (sp),y ;low byte of c and #$80 ;0 if <= 127 eor #$80 ;invert tax beq ~isascii1 ldx #$01 ;return true ~isascii1 rts ;result in x ; ; toupper(c) ; _toupper ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$02 ;_L beq ~toupper1 ;skip if not lower-case sec txa ;original char sbc #'a' - 'A' ;force upper case tax ~toupper1 rts ;result in x ; ; tolower(c) ; _tolower ldy #0 lda (sp),y ;low byte of c tax lda _ctype_,x and #$01 ;_U beq ~tolower1 ;skip if not upper-case clc txa ;original char adc #'a' - 'A' ;force lower case tax ~tolower1 rts ;result in x ; ; toascii(c) ; _toascii ldy #0 lda (sp),y ;low byte of c and #$7f tax rts ;result in x ; ; character classification table ; .byte $00 ;EOF 'subscript' is -1 _ctype_ .byte $20,$20,$20,$20,$20,$20,$20,$20 .byte $20,$08,$08,$08,$08,$08,$20,$20 .byte $20,$20,$20,$20,$20,$20,$20,$20 .byte $20,$20,$20,$20,$20,$20,$20,$20 .byte $18,$10,$10,$10,$10,$10,$10,$10 .byte $10,$10,$10,$10,$10,$10,$10,$10 .byte $04,$04,$04,$04,$04,$04,$04,$04 .byte $04,$04,$10,$10,$10,$10,$10,$10 .byte $10,$41,$41,$41,$41,$41,$41,$01 .byte $01,$01,$01,$01,$01,$01,$01,$01 .byte $01,$01,$01,$01,$01,$01,$01,$01 .byte $01,$01,$01,$10,$10,$10,$10,$10 .byte $10,$42,$42,$42,$42,$42,$42,$02 .byte $02,$02,$02,$02,$02,$02,$02,$02 .byte $02,$02,$02,$02,$02,$02,$02,$02 .byte $02,$02,$02,$10,$10,$10,$10,$20 ; ; sys.s 07-Apr-88 A.J.Travis ; ; Operating system interface /* tcc.c - Small-C compilation sequencer * ------------------------------------- * Generate *exec (*.bat) file to compile Small-C programs */ /* 26-Jan-1989 v0.70 - A.J.Travis * 27-Jun-1991 v0.71 - J.G.Harston * gets system paths from include.h * uses '/' instead of '_' in filenames * 'stacks' execfiles for chained batchfiles * if not chaining multiple batchfiles, deletes "compile" at end * main() ends with exit(0);, paths increased from 80 to 128 chars */ #include #ifdef MSDOS #define TCPP "tcpp" #define TCCOM "tccom" #define TCCOMC "tccom -C" #define AS65 "as65 -o" #define RM "rm -f" #define LD "ld -o" #define SWLD "ld -R -o" #define PATHSEP '\\' #define EXT "ext_s enter_s" #define CRT "crt" #define SWEXT "swext_s enter_s" #define SWCRT "swcrt" #define SCEXT "swext_s start_s" #define COMP "compile.bat" #define EXEC "compile" #else #include "local.h" #define PATHSEP '.' #endif #define LIT "litfile" #define OFILE "a/out" #define TRUE 1 #define FALSE 0 #define SAME 0 /* strcmp() equal */ #define UNDEFINED NULL /* file status */ #define RW 3 /* MOS read/write mode */ char tmp1[128]; /* compiler temporaries */ char tmp2[128]; char tmp3[128]; char tmp4[128]; char pathname[128]; /* pathname of source file */ char basename[128]; /* pathname with suffix removed */ char suffix; /* file type 'c' suffix */ char *pp; /* pathname pointer */ char *bp; /* basename pointer */ char *exec; /* invocation mantra */ char *tcpp; /* Small-C preprocessor */ char *tccom; /* Small-C compiler */ char *as65; /* 6502 assember */ char *ld; /* 6502 loader */ char *rm; /* file remover */ char *ext; /* external references */ char *crt; /* Small-C run-time support module */ char *lit; /* compiler literal pool */ char *ofile; /* output object file */ char *comp; /* exec file */ FILE *in, *out; /* input/output files */ int doexec; /* execute *exec file */ int docom; /* compiler phase */ int doasm; /* assembly phase */ int doload; /* load phase */ int keepsym; /* preserve global symbol file */ int exhdl; /* JGH: exec file handle */ int main(argc, argv) int argc; char *argv[]; { in = UNDEFINED; out = UNDEFINED; if (argc < 2) usage(); doexec = TRUE; docom = TRUE; doasm = TRUE; doload = TRUE; keepsym = FALSE; tcpp = TCPP; tccom = TCCOM; as65 = AS65; rm = RM; ld = NULL; crt = NULL; ext = SCEXT; lit = LIT; ofile = OFILE; comp = COMP; exec = EXEC; exhdl=0; while ((*argv[1] & 0xFF) == '-') { /* BUG in compiler */ if (strcmp(argv[1], "-o") == SAME) { if (argc < 3) usage(); else { ofile = argv[2]; --argc; argv++; } } else if (strcmp(argv[1], "-n") == SAME) --doexec; else if (strcmp(argv[1], "-E") == SAME) { --docom; --doasm; } else if (strcmp(argv[1], "-S") == SAME) --doasm; else if (strcmp(argv[1], "-c") == SAME) --doload; else if (strcmp(argv[1], "-R") == SAME) { ld = SWLD; ext = SWEXT; crt = SWCRT; } else if (strcmp(argv[1], "-A") == SAME) { ld = LD; ext = EXT; crt = CRT; } else if (strcmp(argv[1], "-C") == SAME) tccom = TCCOMC; else if (strcmp(argv[1], "-g") == SAME) keepsym++; else usage(); --argc; argv++; } if (argc < 2) usage(); strcpy(pathname, argv[1]); pp = pathname; while (*pp++) ; while (--pp != pathname) { if (*pp == PATHSEP) { ++pp; break; } } bp = basename; while ((*bp = *pp++) != '\0') ++bp; suffix = *--bp; *--bp = '\0'; if (suffix != 'c') { fprintf(stderr, "tcc: can't compile '%s'\n", pathname); fatal(-1); } if ((in = fopen(pathname, "r")) == NULL) { fprintf(stderr, "tcc: can't open %s\n", pathname); fatal(-1); } fclose(in); in = UNDEFINED; exhdl=(osbyte(198, 0) & 0xFF); /* Find current exec handle and disconnect input */ if ((out = fopen(comp, "w")) == NULL) { fprintf(stderr, "tcc: can't open %s\n", comp); fatal(-1); } sprintf(tmp1, "%s/i", basename); sprintf(tmp2, "%s/s", basename); sprintf(tmp3, "%s/o", basename); sprintf(tmp4, "g/out"); if (ld == NULL) { strcpy(tmp3, ofile); strcpy(ofile, ""); } fprintf(out, "%s %s %s %s %s ", rm, tmp1, tmp2, tmp3, tmp4); fprintf(out, "%s %s\n", lit, ofile); fprintf(out, "%s %s %s\n", tcpp, pathname, tmp1); if (docom) { fprintf(out, "%s %s %s\n", tccom, tmp1, tmp2); fprintf(out, "%s %s %s\n", rm, tmp1, lit); } if (doasm) { fprintf(out, "%s %s %s %s\n", as65, tmp3, ext, tmp2); if (keepsym) fprintf(out, "%s %s\n", rm, tmp2); else fprintf(out, "%s %s %s\n", rm, tmp2, tmp4); if ((ld != NULL) & doload) { fprintf(out, "%s %s %s %s\n", ld, ofile, crt, tmp3); fprintf(out, "%s %s\n", rm, tmp3); } } if (exhdl) fprintf(out, "*fx 198,%d\n", exhdl); /* Reconnect to exec */ else fprintf(out, "%s %s\n", rm, comp); /* Remove compile batchfile */ fclose(out); if (doexec) system(exec); exit(0); } /* * report usage and exit */ usage() { fprintf(stderr, "usage: tcc [-o outfile] [-n] [-E] [-S] [-c] [-g]"); fprintf(stderr, " [-R] [-A] [-C] file\n"); fatal(-1); } /* * close files and exit */ fatal(stat) int stat; /* exit status */ { if (in != NULL) fclose(in); if (out != NULL) fclose(out); exit(stat); } /* tcc.c - Small-C compilation sequencer * ------------------------------------- * Generate *exec (*.bat) file to compile Sma/* tccom.c - 'Tiny' C compiler for the 6502 */ /* 11-Apr-1989 v0.70 - A.J.Travis */ /* 22-Jun-1991 v0.71 - J.G.Harston * main() ends with exit(0); */ #include /* * Boolean flags */ #define TRUE 1 #define FALSE 0 #define ERROR -1 #define UNDEFINED NULL #define SAME 0 /* * Implementation dependent definitions */ #define INTWIDTH 2 /* integer size */ #define CHARWIDTH 1 /* char size */ /* * symbol length */ #define NAMESIZE 8 #define NAMEMAX 7 /* NAMESIZE - 1 */ /* * symbol table entry format */ #define NAME 0 /* null terminated string */ #define IDENT 8 /* NAMESIZE */ #define TYPE 9 /* IDENT + 1 */ #define OFFSET 10 /* TYPE + 1 */ /* * symbol table parameters */ #define SYMSIZ 12 /* NAMESIZE + 4 */ #define NUMGLBS 180 #define NUMLOCS 20 #define SYMTBSZ 2400 /* (NUMGLBS + NUMLOCS) * SYMSIZ */ #define STARTGLB symtab #define ENDGLB symtab + 2160 /* NUMGLBS * SYMSIZ */ #define STARTLOC symtab + 2172 /* (NUMGLBS * SYMSIZ) + SYMSIZ */ #define ENDLOC symtab + 2388 /* SYMTBSZ - SYMSIZ */ /* * symbol "IDENT" */ #define VARIABLE 1 #define ARRAY 2 #define POINTER 3 #define FUNCTION 4 /* * symbol "TYPE" */ #define CCHAR 1 #define CINT 2 /* * L-value definition */ #define LSIZE 2 /* size of L-value structure */ #define SYMBOL 0 /* lval[0] symbol table address (0 for constant) */ #define CTYPE 1 /* lval[1] type of indirect object (0 for static) */ /* * "while" statement queue */ #define WQTABSZ 16 #define WQSIZ 4 #define WQMAX wq + 12 /* WQTABSZ - WQSIZ */ /* * entry offsets in while queue */ #define WQSYM 0 #define WQSP 1 #define WQLOOP 2 #define WQLAB 3 /* * input line */ #define LINESIZE 80 #define LINEMAX LINESIZE - 1 /* * statement types (tokens) */ #define STIF 1 #define STWHILE 2 #define STRETURN 3 #define STBREAK 4 #define STCONT 5 #define STGOTO 6 #define STEXP 7 #define STEXIT 8 /* * expression type */ #define ARITH 0 #define REL 1 /* * error codes */ #define E_DECL 1 /* Illegal function or declaration */ #define E_DEF 2 /* Already defined */ #define E_LPAREN 3 /* Missing opening parenthesis */ #define E_ARGNAME 4 /* Illegal argument name */ #define E_RPAREN 5 /* Missing closing parenthesis */ #define E_ARGNUM 6 /* Wrong number of arguments */ #define E_NAME1 7 /* Illegal symbol name */ #define E_ARG 8 /* Argument name expected */ #define E_COMMA 9 /* Comma expected */ #define E_WHILE 10 /* 'while' expected */ #define E_LABEL 11 /* Illegal 'goto' label */ #define E_LVAL 12 /* L-value required */ #define E_ADDRESS 13 /* Illegal address */ #define E_CONSTANT 14 /* Can't subscript constant */ #define E_VARIABLE 15 /* Can't subscript variable */ #define E_EXPR 16 /* Illegal expression */ #define E_DELIM 17 /* delimeter expected */ #define E_NAME2 18 /* Illegal symbol name */ #define E_GFULL 19 /* Global symbol table full */ #define E_LFULL 20 /* Local symbol table full */ #define E_XWHILE 21 /* Too many active whiles */ #define E_NOWHILE 22 /* No active whiles */ #define E_CCONST 23 /* Illegal character constant */ #define E_NEEDCONST 24 /* Constant required */ #define E_SIZE 25 /* Negative size illegal */ #define E_SEMI 26 /* Missing semicolon */ #define E_BRACKET 27 /* Missing bracket */ /* * function types */ char *addglb(); char *findglb(); char *addloc(); char *findloc(); int *readwhile(); /* * global variables */ char symtab[SYMTBSZ]; /* symbol table */ char *glbp; /* global symbol pointer */ char *locp; /* local symbol pointer */ int wq[WQTABSZ]; /* while queue */ int *wqp; /* while queue pointer */ int litp; /* literal pointer */ char ibuf[LINESIZE]; /* input buffer */ char *ip; char *ipmax; char c1, c2; /* input characters */ int nxtlab; /* next available label # */ int litlab; /* label assigned to literal pool */ int sp; /* stack pointer */ int csp; /* current stack pointer */ int argstk; /* function argument sp */ int ncmp; /* # open compound statements */ int eof; /* non-zero on final input eof */ FILE *lf; /* fp for literal file */ FILE *in; /* fp for input file */ FILE *out; /* fp for output file */ int lastst; /* last executed statement type */ int lastop; /* last executed operator type */ int hasmain; /* does this file have main() */ int ctext; /* show C source as assembler comments */ char *cp; /* work ptr to any char buffer */ int main(argc, argv) int argc; char *argv[]; { ctext = FALSE; while ((*argv[1] & 0xFF) == '-') { /* BUG in compiler */ if (strcmp(argv[1], "-C") == SAME) ctext = TRUE; else usage(); --argc; argv++; } in = out = UNDEFINED; if ((argc < 2) | (argc > 3)) usage(); if ((lf = fopen("litfile", "wb")) == NULL) cant("litfile"); if ((in = fopen(argv[1], "r")) == NULL) cant(argv[1]); if (argc == 2) out = stdout; else { if ((out = fopen(argv[2], "w")) == NULL) cant(argv[2]); } glbp = STARTGLB; locp = STARTLOC; wqp = wq; sp = eof = ncmp = lastst = litp = 0; nxtlab = 1; litlab = getlabel(); reset(); header(); parse(); dumplits(); dumpglbs(); trailer(); fclose(lf); fclose(in); if (out != stdout) fclose(out); exit(0); } /* * report correct usage, and exit */ usage() { fprintf(stderr, "usage: tccom [-C] infile [outfile]\n"); exit(-1); } /* * Process all input text * ---------------------- * At this level, only static declarations and function definitions are legal */ parse() { while (eof == FALSE) { if (token("char")) declglb(CCHAR); else if (token("int")) declglb(CINT); else if (token("extern")) /* ignore extern */ skipto(';'); else /* assume function returning int */ declglb(CINT); skip(); } } /* * New function definition */ newfunc(name) char *name; /* function name */ { int argtop; char n[NAMESIZE]; locp = STARTLOC; argstk = 0; while (match(')') == FALSE) { if (symname(n) == FALSE) error(E_ARGNAME); else { if (findloc(n)) error(E_DEF); else { addloc(n, 0, 0, argstk); argstk = argstk + INTWIDTH; } } skip(); if (c1 != ')') { if (match(',') == FALSE) error(E_RPAREN); } if (needstend()) break; } /* return NULL if this is function declaration */ skip(); if (c1 == ';') return NULL; /* print name of each function as it is processed */ printf("%s\n", name); hasmain = (strcmp(name, "main") == SAME); label(name); #ifdef DEBUG trace(); #endif sp = 0; argtop = argstk; while (argstk) { if (token("char")) { getarg(CCHAR, argtop); needsemi(); } else if (token("int")) { getarg(CINT, argtop); needsemi(); } else error(E_ARGNUM); } statement(); if (hasmain == FALSE & lastst != STRETURN) { modstk(0); ret(); } else if (hasmain == TRUE & lastst != STEXIT) { modstk(0); c_exit(); } sp = 0; locp = STARTLOC; return FUNCTION; } /* * Get function arguments */ getarg(t, argtop) int t, argtop; { int j, address; char *argp, n[NAMESIZE]; while(TRUE) { if (argstk == 0) return; if (match('*')) j = POINTER; else j = VARIABLE; if (symname(n) == FALSE) error(E_NAME1); if (match('[')) { while (inbyte() != ']') if (needstend()) break; if ((t == CCHAR) & (j == POINTER)) t = CINT; j = POINTER; } if ((argp = findloc(n)) == 0) error(E_ARG); argp[IDENT] = j; argp[TYPE] = t; argstk = argstk - INTWIDTH; if (needstend()) return; if (match(',') == FALSE) error(E_COMMA); } } /* * Process a statement */ statement() { lastst = UNDEFINED; csp = sp; while (TRUE) { if (token("char")) { declloc(CCHAR); needsemi(); } else if (token("int")) { declloc(CINT); needsemi(); } else break; } sp = modstk(csp); if (match('{')) compound(); else if (token("if")) doif(); else if (token("while")) dowhile(); else if (token("for")) dofor(); else if (token("do")) { dodo(); needsemi(); } else if (token("goto")) { dogoto(); needsemi(); } else if (dolab()) return; else if (token("return")) { doreturn(); needsemi(); lastst = STRETURN; } else if (token("break")) { dobreak(); needsemi(); } else if (token("continue")) { docont(); needsemi(); } else if (token("exit")) { doexit(); needsemi(); lastst = STEXIT; } else { expression(); needsemi(); } } /* * Process compound statement */ compound() { ++ncmp; while (match('}') == FALSE) { if (eof) return; statement(); } --ncmp; } /* * Process IF statement */ doif() { char *flev; int fsp, flab1, flab2; flev = locp; fsp = sp; flab1 = getlabel(); test(flab1); statement(); sp = modstk(fsp); locp = flev; if (token("else") == FALSE) { outlab(flab1); return; } if (lastst == STRETURN) { outlab(flab1); statement(); sp = modstk(fsp); locp = flev; return; } jump(flab2 = getlabel()); outlab(flab1); statement(); sp = modstk(fsp); locp = flev; outlab(flab2); } /* * Process WHILE statement */ dowhile() { int wq[4]; *wq = locp; wq[WQSP] = sp; wq[WQLOOP] = getlabel(); wq[WQLAB] = getlabel(); addwhile(wq); outlab(wq[WQLOOP]); test(wq[WQLAB]); statement(); jump(wq[WQLOOP]); outlab(wq[WQLAB]); locp = *wq; sp = modstk(wq[WQSP]); delwhile(); } dofor() { int wq[4]; char control[LINESIZE]; /* loop control string */ char trail[LINESIZE]; /* trailing text after ')' */ *wq = locp; wq[WQSP] = sp; wq[WQLOOP] = getlabel(); wq[WQLAB] = getlabel(); addwhile(wq); needbrack('('); expression(); needsemi(); outlab(wq[WQLOOP]); fortest(wq[WQLAB]); needsemi(); strcpy(control, ip); skipto(')'); statement(); strcpy(trail, ip); strcpy(ibuf, control); ip = ibuf; expression(); needbrack(')'); jump(wq[WQLOOP]); outlab(wq[WQLAB]); locp = *wq; sp = modstk(wq[WQSP]); delwhile(); strcpy(ibuf, trail); ip = ibuf; } dodo() { int wq[4]; *wq = locp; wq[WQSP] = sp; wq[WQLOOP] = getlabel(); wq[WQLAB] = getlabel(); addwhile(wq); outlab(wq[WQLOOP]); statement(); if (token("while") == FALSE) error(E_WHILE); dotest(wq[WQLOOP]); outlab(wq[WQLAB]); locp = *wq; sp = modstk(wq[WQSP]); delwhile(); } dogoto() { char s[LINESIZE]; if (symname(s) == FALSE) error(E_LABEL); sjump(s); } /* * Process RETURN statement */ doreturn() { if (needstend() == FALSE) expression(); modstk(0); ret(); } /* * Process BREAK statement */ dobreak() { int *p; if ((p = readwhile()) == 0) return; modstk(p[WQSP]); jump(p[WQLAB]); } /* * Process CONTINUE statement */ docont() { int *p; if ((p = readwhile()) == 0) return; modstk(p[WQSP]); jump(p[WQLOOP]); } dolab() { char *savech; /* saved position of ip */ char n[LINESIZE]; /* label name */ savech = ip; if (symname(n) == FALSE) return FALSE; if (match(':') == FALSE) { ip = savech; return FALSE; } label(n); return TRUE; } doexit() { if (needstend() == FALSE) expression(); modstk(0); c_exit(); } /* * Expression evaluation by recursive descent */ expression() { int lval[LSIZE]; lastop = 0; if (c1 == ';') { if (ctext) comment("null expression\n"); } else if (hier1(lval)) rvalue(lval); } hier1(lval) int *lval; { int k; int lval2[LSIZE]; k = hier2(lval); if (match('=')) { if (k == 0) error(E_LVAL); if (lval[CTYPE]) push(); if (hier1(lval2)) rvalue(lval2); store(lval); return 0; } else return k; } hier2(lval) int *lval; { int k; int lval2[LSIZE]; k = hier3(lval); skip(); if (c1 != '|') return k; if (k) rvalue(lval); while(TRUE) { if (match('|')) { push(); if (hier3(lval2)) rvalue(lval2); or(); } else return 0; } } hier3(lval) int *lval; { int k; int lval2[LSIZE]; k = hier4(lval); skip(); if (c1 != '^') return k; if (k) rvalue(lval); while(TRUE) { if (match('^')) { push(); if (hier4(lval2)) rvalue(lval2); xor(); } else return 0; } } hier4(lval) int *lval; { int k; int lval2[LSIZE]; k = hier5(lval); skip(); if (c1 != '&') return k; if (k) rvalue(lval); while(TRUE) { if (match('&')) { push(); if (hier5(lval2)) rvalue(lval2); and(); } else return 0; } } /* * check for == and != */ hier5(lval) int *lval; { int k; int lval2[LSIZE]; k = hier6(lval); skip(); if (c2 != '=') return k; if ((c1 != '=') & (c1 != '!')) return k; if (k) rvalue(lval); while(TRUE) { if (amatch("==")) { push(); if (hier6(lval2)) rvalue(lval2); eq(); } else if (amatch("!=")) { push(); if (hier6(lval2)) rvalue(lval2); ne(); } else return 0; } } /* * wish to identify >, <, >=, <=, but reject >>, << */ hier6(lval) int *lval; { int k; int lval2[LSIZE]; k = hier7(lval); skip(); if ((c1 != '<') & (c1 != '>')) return k; if ((c2 == '<') | (c2 == '>')) return k; if (k) rvalue(lval); while(TRUE) { if (amatch("<=")) { push(); if (hier7(lval2)) rvalue(lval2); le(lval, lval2); } else if (amatch(">=")) { push(); if (hier7(lval2)) rvalue(lval2); ge(lval, lval2); } else if ((c1 == '<') & (c2 != '<')) { inbyte(); push(); if (hier7(lval2)) rvalue(lval2); lt(lval, lval2); } else if ((c1 == '>') & (c2 != '>')) { inbyte(); push(); if (hier7(lval2)) rvalue(lval2); gt(lval, lval2); } else return 0; } } hier7(lval) int *lval; { int k; int lval2[LSIZE]; k = hier8(lval); skip(); if ((c1 != '>') & (c1 != '<')) return k; if ((c2 != '>') & (c2 != '<')) return k; if (k) rvalue(lval); while(TRUE) { if (amatch(">>")) { push(); if (hier8(lval2)) rvalue(lval2); asr(); } else if (amatch("<<")) { push(); if (hier8(lval2)) rvalue(lval2); asl(); } else return 0; } } hier8(lval) int *lval; { int k; int lval2[LSIZE]; k = hier9(lval); skip(); if ((c1 != '+') & (c1 != '-')) return k; if (k) rvalue(lval); while(TRUE) { if (match('+')) { push(); if (hier9(lval2)) rvalue(lval2); add(lval); } else if (match('-')) { push(); if (hier9(lval2)) rvalue(lval2); sub(lval); } else return 0; } } hier9(lval) int *lval; { int k; int lval2[LSIZE]; k = hier10(lval); skip(); if ((c1 != '*') & (c1 != '/') & (c1 != '%')) return k; if (k) rvalue(lval); while(TRUE) { if (match('*')) { push(); if (hier9(lval2)) rvalue(lval2); mult(); } else if (match('/')) { push(); if (hier10(lval2)) rvalue(lval2); div(lval, lval2); } else if (match('%')) { push(); if (hier10(lval2)) rvalue(lval2); mod(lval, lval2); } else return 0; } } hier10(lval) int *lval; { int k; char *p; if (amatch("++")) { if ((k = hier10(lval)) == 0) error(E_LVAL); if (lval[CTYPE]) push(); rvalue(lval); inc(lval); store(lval); return 0; } else if (amatch("--")) { if ((k = hier10(lval)) == 0) error(E_LVAL); if (lval[CTYPE]) push(); rvalue(lval); dec(lval); store(lval); return 0; } else if (match('-')) { if ((k = hier10(lval)) != NULL) rvalue(lval); neg(); return 0; } else if (match('*')) { if ((k = hier10(lval)) != NULL) rvalue(lval); lval[CTYPE] = CINT; if ((p = lval[SYMBOL]) != NULL) lval[CTYPE] = p[TYPE]; lval[SYMBOL] = 0; return 1; } else if (match('&')) { if ((k = hier10(lval)) == 0) error(E_ADDRESS); else if (lval[CTYPE]) return 0; else { immediate(p = lval[SYMBOL]); lval[CTYPE] = p[TYPE]; return 0; } } else { k = hier11(lval); if (amatch("++")) { if (k == 0) error(E_LVAL); if (lval[CTYPE]) push(); rvalue(lval); inc(lval); store(lval); dec(lval); return 0; } else if (amatch("--")) { if (k == 0) error(E_LVAL); if (lval[CTYPE]) push(); rvalue(lval); dec(lval); store(lval); inc(lval); return 0; } else return k; } } hier11(lval) int *lval; { int k; char *p; k = primary(lval); p = lval[SYMBOL]; skip(); if ((c1 == '[') | (c1 == '(')) while (TRUE) { if (match('[')) { if (p == NULL) error(E_CONSTANT); else if (p[IDENT] == POINTER) rvalue(lval); else if (p[IDENT] != ARRAY) error(E_VARIABLE); push(); expression(); needbrack(']'); add(lval); lval[SYMBOL] = NULL; lval[CTYPE] = p[TYPE]; k = 1; } else if (match('(')) { if (p == NULL) callfunction(NULL); else if (p[IDENT] == FUNCTION) callfunction(p); else { rvalue(lval); callfunction(NULL); } lval[SYMBOL] = NULL; k = 0; } else return k; } if (p == NULL) return k; if (p[IDENT] == FUNCTION) { immediate(p); return 0; } return k; } primary(lval) int *lval; { int k; int num[1]; char *p, sname[NAMESIZE]; /* check for parenthesised expression */ if (match('(')) { k = hier1(lval); needbrack(')'); return k; } if (symname(sname)) { if ((p = findloc(sname)) != NULL) { getloc(p); lval[SYMBOL] = p; lval[CTYPE] = p[TYPE]; if (p[IDENT] == POINTER) lval[CTYPE] = CINT; if (p[IDENT] == ARRAY) return 0; else return 1; } if ((p = findglb(sname)) != NULL) if (p[IDENT] != FUNCTION) { lval[SYMBOL] = p; lval[CTYPE] = 0; if (p[IDENT] != ARRAY) return 1; immediate(p); lval[CTYPE] = p[TYPE]; return 0; } p = addglb(sname, FUNCTION, CINT, 0); lval[SYMBOL] = p; lval[CTYPE] = 0; return 0; } if (constant(num)) return lval[SYMBOL] = lval[CTYPE] = 0; else error(E_EXPR); } /* * Process function call */ callfunction(name) char *name; { int nas; char *p1, *p2; skip(); p1 = ip; while (c1 != ')') { if (c1 == '"') skipto('"'); else if (c1 == '\'') skipto('\''); else if (c1 == '(') parscan(); else if (c1 == '\0') break; else bump(); } needbrack(')'); p2 = ip; ip = p1; skip(); if (name == NULL) { push(); } nas = arglist(name, 0); if (name) call(name); else callstk(); sp = modstk(sp + nas); ip = p2; skip(); } /* * recursively extract argument list */ arglist(n, nas) char *n; /* name of calling function (NULL if indirect call) */ int nas; /* number of arguments */ { char *p; p = ip; if (argq()) nas = arglist(n, nas); ip = p; skip(); if (c1 == ')') return nas; expression(); if (n == NULL) swapstk(); push(); return nas + INTWIDTH; } /* * extract one argument from queue */ argq() { int c; skip(); while ((c1 != ',') & (c1 != ')')) { if (c1 == '"') skipto('"'); else if (c1 == '\'') skipto('\''); else if (c1 == '(') parscan(); else bump(); } c = c1; bump(); return c == ','; } skipto(delim) char delim; { while ((bump()) != delim) { if (c1 == '\\') bump(); if (c1 == '\0') error(E_DELIM); } bump(); } parscan() { int nest; nest = 1; do { if ((bump()) == '(') ++nest; else if (c1 == ')') --nest; } while ((nest > 0) & (c1 != ')')); bump(); } /* * Declare a static variable * ------------------------- * makes an entry in the symbol table so that subsequent * reference can call symbol by name */ declglb(typ) int typ; { int j, k; char *p; char sname[NAMESIZE]; do { if (needstend()) return; k = 1; if (match('*')) j = POINTER; else j = VARIABLE; if (symname(sname) == FALSE) error(E_NAME2); if ((p = findglb(sname)) != NULL) { if ((p[IDENT] != FUNCTION) | (p[OFFSET] == FUNCTION)) error(E_DEF); } if (match('[')) { if ((k = needsub()) == 0) j = POINTER; else j = ARRAY; } else if (match('(')) { k = newfunc(sname); j = FUNCTION; } addglb(sname, j, typ, k); if ((j == FUNCTION) & (k == FUNCTION)) return; } while (match(',')); needsemi(); } /* * Declare local variables */ declloc(typ) int typ; { int k, j; char sname[NAMESIZE]; do { if (needstend()) return; if (match('*')) j = POINTER; else j = VARIABLE; if (symname(sname) == FALSE) error(E_NAME2); if (findloc(sname)) error(E_DEF); if (match('[')) { if ((k = needsub()) == 0) { j = POINTER; k = INTWIDTH; } else { j = ARRAY; if (typ == CINT) k = k * INTWIDTH; } } else if ((typ == CCHAR) & (j != POINTER)) k = CHARWIDTH; else k = INTWIDTH; csp = csp - k; addloc(sname, j, typ, csp); } while (match(',')); } /* * Insert new global symbol name */ char *addglb(sname, id, typ, value) char *sname, id, typ; int value; { char *p; if ((cp = findglb(sname)) != NULL) return cp; if (glbp >= ENDGLB) error(E_GFULL); cp = p = glbp; while ((*p++ = *sname++) != '\0') ; cp[IDENT] = id; cp[TYPE] = typ; mputw(cp + OFFSET, value); glbp = glbp + SYMSIZ; return cp; } /* * Find a global symbol name */ char *findglb(sname) char *sname; { char *p; p = STARTGLB; while (p != glbp) { if (strcmp(sname, p) == SAME) return p; p = p + SYMSIZ; } return NULL; } /* * Insert new local symbol name */ char *addloc(sname, id, typ, value) char *sname, id, typ; int value; { char *p; if ((cp = findloc(sname)) != NULL) return cp; if (locp >= ENDLOC) error(E_LFULL); cp = p = locp; while ((*p++ = *sname++) != '\0') ; cp[IDENT] = id; cp[TYPE] = typ; mputw(cp + OFFSET, value); locp = locp + SYMSIZ; return cp; } /* * Find a local symbol name */ char *findloc(sname) char *sname; { char *p; p = STARTLOC; while (p != locp) { if (strcmp(sname, p) == SAME) return p; p = p + SYMSIZ; } return NULL; } /* * WHILE table manipulation */ addwhile(p) int *p; { int k; if (wqp > WQMAX) error(E_XWHILE); k = 0; while (k < WQSIZ) *wqp++ = p[k++]; } delwhile() { if (readwhile()) wqp = wqp - WQSIZ; } int *readwhile() { if (wqp == wq) error(E_NOWHILE); else return wqp - WQSIZ; } /* * Generate next label */ getlabel() { return ++nxtlab; } /* * Read symbol name */ symname(sname) char *sname; { int k; skip(); if ((isalpha(c1) == FALSE) & (c1 != '_')) return FALSE; k = 0; while (isalnum(c1) | c1 == '_') { if (k < NAMEMAX) sname[k++] = c1; bump(); } sname[k] = '\0'; return TRUE; } /* * Check for a number in input */ number(val) int *val; { int k, sign; k = sign = 1; while (k) { k = 0; if (match('+')) k = 1; if (match('-')) { sign = (-sign); k = 1; } } if (isdigit(c1) == FALSE) return getqchar(val); if (match('0')) { if (match('x')) { while (isxdigit(c1)) k = k * 16 + toint(gch()); } else { while (isodigit(c1)) k = k * 8 + toint(gch()); } } else { while (isdigit(c1)) k = k * 10 + toint(gch()); } if (sign < 0) k = (-k); *val = k; return TRUE; } /* * convert hex char to integer */ toint(c) char c; { if (isdigit(c)) return c - '0'; if ((c >= 'A') & (c <= 'F')) return 10 + c - 'A'; if ((c >= 'a') & (c <= 'f')) return 10 + c - 'a'; return -1; } /* * check for octal digits */ isodigit(c) char c; { return (c >= '0') & (c <= '8'); } /* * Load a (positive) constant */ constant(val) int *val; { if (number(val)) immed(*val); else if (getqstring(val)) literal(litlab, *val); else return FALSE; return TRUE; } /* * Get one or two characters from input stream */ getqchar(val) int *val; { char c; if (match('\'') == FALSE) return FALSE; if (c1 == '\\') c = cesc(); else c = gch(); if (c1 != '\'') error(E_CCONST); gch(); *val = c; return TRUE; } cesc() { int c; gch(); if (c1 == 'n') c = '\n'; /* newline */ else if (c1 == 't') c = '\t'; /* tab */ else if (c1 == 'b') c = '\b'; /* backspace */ else if (c1 == 'r') c = '\r'; /* return */ else if (c1 == 'f') c = '\f'; /* form feed */ else if (c1 == '\\') c = '\\'; /* backslash */ else if (isodigit(c1)) { c = toint(gch()); while (isodigit(c1)) c = c * 8 + toint(gch()); return c; } else c = c1; /* any other char */ gch(); return c; } /* * Get string from input stream */ getqstring(val) int *val; { char c; if (match('"') == FALSE) return FALSE; *val = litp; while (c1 != '"') { if (c1 == '\0') break; else if (c1 == '\\') c = cesc(); else c = gch(); putc(c, lf); ++litp; } gch(); putc('\0', lf); ++litp; return TRUE; } /* * Compare literal with line buffer contents * ----------------------------------------- * advances buffer pointer if literal matches */ match(lit) char lit; { skip(); if (c1 != lit) return FALSE; else { bump(); return TRUE; } } /* * match n chars with input buffer */ amatch(lit) char *lit; { int len; len = strlen(lit); skip(); if (strncmp(ip, lit, len) != SAME) return FALSE; else { ip = ip + len; c1 = *ip; return TRUE; } } /* * match token with input buffer */ token(lit) char *lit; { int len; skip(); len = strlen(lit); if (strncmp(ip, lit, len) != SAME) return FALSE; else if (isalnum(ip[len])) return FALSE; else { ip = ip + len; c1 = *ip; return TRUE; } } /* * Get array bounds */ needsub() { int num[1]; if (match(']')) return 0; if (number(num) == 0) error(E_NEEDCONST); if (*num < 0) error(E_SIZE); needbrack(']'); return *num; } /* * Check for semicolon */ needsemi() { if (match(';') == FALSE) error(E_SEMI); } /* * Check for end of statement */ needstend() { skip(); return (c1 == ';') | (c1 == '\0'); } needbrack(c) char c; { skip(); if (match(c) == FALSE) error(E_BRACKET); } /* * Skip white space in input */ skip() { while (isspace(*ip) | *ip == '\0') { if (*ip++ == '\0') inline(); } c1 = *ip; c2 = *(ip + 1); } /* * bump lexical input */ bump() { c1 = *++ip; c2 = *(ip + 1); return c1; } /* * Get a character * --------------- * reads in a line if necessary */ inbyte() { while(*ip == '\0') { if (eof) return '\0'; inline(); } return gch(); } /* * Read in a line */ inline() { if ((ip = fgets(ibuf, LINESIZE, in)) == NULL) eof = TRUE; else if (ctext) comment(ip); } /* * Reset input Buffer */ reset() { ip = ibuf; c1 = c2 = *ip = '\0'; } /* * Get next input character */ gch() { int c; if (*ip == '\0') return '\0'; else { c = *ip; bump(); return c; } } /* * put 16-bit integer into memory word */ mputw(p, val) int *p; /* (int *) cast of char *p */ int val; { *p = val; } /* * get 16-bit integer word from memory */ mgetw(p) int *p; /* (int *) cast of char *p */ { return *p; } /* * Report type and position of an error in the source line */ error(n) int n; { char *p; #if MSDOS fflush(stdout); #endif fprintf(stderr, "\n%s", ibuf); p = ibuf; while (p < ip) { if (*p == '\t') fprintf(stderr, "\t"); else fprintf(stderr, " "); ++p; } fprintf(stderr, "^\nerror: %d\n", n); exit(-1); } /* * can't open ... */ cant(s) char *s; /* filename */ { fprintf(stderr, "tccom: can't open %s\n", s); exit(-1); } /* * Evaluate condition */ test(label) int label; { needbrack('('); expression(); needbrack(')'); if (lastop == REL) testjump(label); else testnz(label); } fortest(label) int label; { expression(); if (lastop == REL) testjump(label); else testnz(label); } dotest(label) int label; { needbrack('('); expression(); needbrack(')'); if (lastop == REL) dotestjump(label); else dotestnz(label); } /* * Store a value in memory */ store(lval) int *lval; { if (lval[CTYPE] == 0) putmem(lval); else { pop(); putstk(lval[CTYPE]); } } /* * Get a value from memory */ rvalue(lval) int *lval; { if ((lval[SYMBOL] != NULL) & (lval[CTYPE] == 0)) getmem(lval); else indirect(lval[CTYPE]); } /* * Dump the literal pool * --------------------- * if nothing there, exit */ dumplits() { int k, c; if (litp) { outlab(litlab); fclose(lf); if ((lf = fopen("litfile", "rb")) == NULL) cant("litfile"); for (k = 0; k < litp; ++k) defbyte(getc(lf)); } fprintf(out, "~eot\n"); } /* * Dump all static variables */ dumpglbs() { int sz; int dp; dp = 0; fprintf(out, "~data =~eot\n"); cp = STARTGLB; while (cp < glbp) { if (cp[IDENT] != FUNCTION) { fprintf(out, "_%s", cp); sz = mgetw(cp + OFFSET); if ((cp[TYPE] == CINT) | (cp[IDENT] == POINTER)) sz = sz * INTWIDTH; fprintf(out, " =~data+%u\n", dp); dp = dp + sz; } cp = cp + SYMSIZ; } fprintf(out, "~eod =~data+%u\n", dp); } /* * output assembler comment */ comment(s) char *s; { fprintf(out, "; %s", s); } /* * output line of code */ outline(s) char *s; { fprintf(out, "\t%s\n", s); } /* * output line of code with integer value */ outval(s, n) char *s; int n; { fprintf(out, s, n); lastop = ARITH; } /* * output line of code with string value */ outstr(s1, s2) char *s1; char *s2; { fprintf(out, s1, s2); lastop = ARITH; } /* * pop secondary, and output line of JSR threaded code */ popcode(s) char *s; { pop(); outcode(s); } /* * output line of JSR threaded code (arithmetic) */ outcode(s) char *s; { fprintf(out, "\tjsr %s\n", s); lastop = ARITH; } /* * output line of JSR threaded code (relational) */ relcode(s) char *s; { pop(); fprintf(out, "\tjsr %s\n", s); lastop = REL; } #ifdef DEBUG /* * output trace/debug call */ trace() { outcode("__trace"); } #endif /* * output global label by symbol table entry */ label(name) char *name; { outstr("_%s\n", name); } /* * output compiler generated label */ outlab(label) int label; { outval("~%d\n", label); } /* * Load direct 8 or 16 bits into primary register */ getmem(lval) int *lval; { char *sym; sym = lval[SYMBOL]; outstr("\tldx _%s\n", sym); if ((sym[IDENT] != POINTER) & (sym[TYPE] == CCHAR)) outcode("ext"); else outstr("\tldy _%s+1\n", sym); } /* * Given offset from SP, get address into primary register */ getloc(sym) char *sym; { int n; n = mgetw(sym + OFFSET); if (n & 0x8000) n = -((n ^ 0xFFFF) + 1); n = n - sp; if (n == 0) outcode("addr"); else if (n < 256) { if ((n <= 12) & (n % 2 == 0)) outval("\tjsr addr_%d\n", n / 2); else { outval("\tldx #%d\n", n); outcode("addr_b"); } } else { immed(n); outcode("addr_w"); } } /* * Store direct 8 or 16 bits from primary register */ putmem(lval) int *lval; { char *sym; sym = lval[SYMBOL]; outstr("\tstx _%s\n", sym); if ((sym[IDENT] == POINTER) | (sym[TYPE] != CCHAR)) outstr("\tsty _%s+1\n", sym); } /* * Store indirect 8 or 16 bits at address on top of stack */ putstk(typeobj) char typeobj; { if (typeobj == CCHAR) outcode("sind_b"); else outcode("sind_w"); } /* * Load indirect 8 or 16 bits at address in primary reg into primary register */ indirect(typeobj) char typeobj; { if (typeobj == CCHAR) outcode("lind_b"); else outcode("lind_w"); } /* * Call subroutine */ call(sname) char *sname; { outstr("\tjsr _%s\n", sname); } /* * Subroutine call to address on top of stack, return address left on stack */ callstk() { popcode("scall"); } /* * Jump to specified internal label number */ jump(label) int label; { outval("\tjmp ~%d\n", label); } sjump(s) char *s; { outstr("\tjmp _%s\n", s); } /* * Jump to specified label if primary reg is false (zero) */ testjump(label) int label; { outval("\tbne *+5\n\tjmp ~%d\n", label); } dotestjump(label) int label; { outval("\tbeq *+5\n\tjmp ~%d\n", label); } testnz(label) int label; { outval("\tjsr nz\n\tbne *+5\n\tjmp ~%d\n", label); } dotestnz(label) int label; { outval("\tjsr nz\n\tbeq *+5\n\tjmp ~%d\n", label); } /* * Modify stack pointer to new value indicated */ modstk(newsp) int newsp; { int k; k = newsp - sp; if (k == 0) return newsp; if (k < 0) decstk(k); else incstk(k); return newsp; } decstk(n) int n; { if ((n = (n & 0xFFFF ^ 0xFFFF) + 1) < 0xFF) outval("\tlda #%d\n\tjsr sdec_b\n", n); else { outval("\tlda #%d\n\tsta asave\n", n >> 8); outval("\tlda #%d\n\tjsr sdec_w\n", n & 0xFF); } } incstk(n) int n; { if (n < 0xFF) { if (n == 2) outcode("drop"); else if (n == 4 | n == 6) outval("\tjsr drop%d\n", n >> 1); else outval("\tlda #%d\n\tjsr sinc_b\n", n); } else { outval("\tlda #%d\n\tsta asave\n", n >> 8); outval("\tlda #%d\n\tjsr sinc_w\n", n & 0xFF); } } /* * (dummy) start to main segment */ header() { lastop = 0; } /* * swap primary and secondary */ swap() { outcode("swap"); } /* * load immediate by value */ immed(val) int val; { outval("\tldx #<%u\n", val); outval("\tldy #>%u\n", val); } /* * load immediate by name */ immediate(name) char *name; { outstr("\tldx #<_%s\n", name); outstr("\tldy #>_%s\n", name); } /* * load address of literal */ literal(lab, offset) int lab; int offset; { outval("\tldx #<~%d+", lab); outval("%u\n", offset); outval("\tldy #>~%d+", lab); outval("%u\n", offset); } /* * push primary onto stack */ push() { outcode("push"); sp = sp - INTWIDTH; } /* * pop (compiler) stack */ pop() { sp = sp + INTWIDTH; } /* * swap primary and top of stack */ swapstk() { outcode("xchange"); } /* * return from function */ ret() { outline("rts"); } /* * exit from program at arbitrary depth of function call nesting */ c_exit() { outline("jmp _exit"); } /* * scale primary by INTWIDTH */ scale(lval) int *lval; { char *p; if ((p = lval[SYMBOL]) != NULL) { if ((p[IDENT] == POINTER) | (p[IDENT] == ARRAY)) { if (p[TYPE] == CINT) outcode("scale2"); } } } /* * add primary and top stack item */ add(lval) int *lval; { pop(); scale(lval); outcode("add"); } /* * subtract primary from top stack item */ sub(lval) int *lval; { pop(); scale(lval); outcode("sub"); } /* * multiply primary and top stack item */ mult() { pop(); outcode("mult"); } /* * check 'usual' binary conversions */ uconv(lval1, lval2) int *lval1, *lval2; { char *p1, *p2; int t1, t2; if ((p1 = lval1[SYMBOL]) != NULL) t1 = p1[IDENT]; else t1 = NULL; if ((p2 = lval2[SYMBOL]) != NULL) t2 = p2[IDENT]; else t2 = NULL; return (t1 == POINTER) | (t2 == POINTER); } /* * divide top stack item by primary * -------------------------------- * quotient in primary, rem in secondary */ div(lval1, lval2) int *lval1, *lval2; { if (uconv(lval1, lval2)) popcode("udiv"); else popcode("div"); } /* * mod of top stack item divided by primary * ---------------------------------------- * rem in primary, quotient in secondary */ mod(lval1, lval2) int *lval1, *lval2; { if (uconv(lval1, lval2)) popcode("umod"); else popcode("mod"); } /* * inclusive or of primary and top stack item */ or() { popcode("or"); } /* * exclusive or of primary and top stack item */ xor() { popcode("xor"); } /* * logical and of primary and top stack item */ and() { popcode("cand"); } /* * arithmetic shift right of top stack item * ---------------------------------------- * number of shifts in primary */ asr() { popcode("casr"); } /* * arithmetic shift left */ asl() { popcode("casl"); } /* * twos complement of primary */ neg() { outcode("neg"); } /* * increment primary by n */ inc(lval) int *lval; { char *p; p = lval[SYMBOL]; if ((p[IDENT] == POINTER) & (p[TYPE] == CINT)) outcode("inc2"); else outcode("inc1"); } /* * decrement primary */ dec(lval) int *lval; { char *p; p = lval[SYMBOL]; if ((p[IDENT] == POINTER) & (p[TYPE] == CINT)) outcode("dec2"); else outcode("dec1"); } /* * Conditional instructions * ------------------------ * compare top stack item against primary, put 1 in primary if true, otherwise 0 */ /* * == (equal) */ eq() { relcode("eq"); } /* * != (not equal) */ ne() { relcode("ne"); } /* * < (less than) */ lt(lval1, lval2) int *lval1, *lval2; { if (uconv(lval1, lval2)) relcode("ult"); else relcode("lt"); } /* * <= (less than or equal) */ le(lval1, lval2) int *lval1, *lval2; { if (uconv(lval1, lval2)) relcode("ule"); else relcode("le"); } /* * > (greater than) */ gt(lval1, lval2) int *lval1, *lval2; { if (uconv(lval1, lval2)) relcode("ugt"); else relcode("gt"); } /* * >= (signed) */ ge(lval1, lval2) int *lval1, *lval2; { if (uconv(lval1, lval2)) relcode("uge"); else relcode("ge"); } /* * literal definitions */ defbyte(c) char c; { outval("\t.byte %d\n", c); } defstorage(n) int n; { outval("\t*=*+%u\n", n); } /* * (dummy) end of assembly */ trailer() { lastop = 0; } /* tccom.c - 'Tiny' C compiler /* tcpp.c - Small-C Preprocessor * ----------------------------- */ /* 25-Jan-1989 v0.70 - A.J.Travis * 28-Jul-1991 v0.71 - J.G.Harston * system-specifics removed to local.h * filenames use '/' instead of '_' * main() ends with exit(0);, linesize incresed from 81 to 128 */ #include #include /* * boolean constants */ #define TRUE 1 #define FALSE 0 #define ERROR -1 #define UNDEFINED NULL #define SAME 0 /* * symbol table parameters */ #define HASHSIZE 257 #define DEFSIZE 4000 #define SYMSIZE 4000 #define PARMSIZE 132 #define NEXTPTR 0 #define BODYPTR 2 #define NAME 4 #define MAXPARMS 32 #define LINESIZE 128 /* max length of line + '\0' */ /* * directory containing 'standard' #include files */ #ifdef MSDOS #define INCLUDE "/include/" #else #include "local.h" #endif /* * function types */ char *filename(); char *hashfind(); /* * global variables */ char ibuf[BUFSIZ]; char *ip; char obuf[BUFSIZ]; char *op; char mac[BUFSIZ]; char name[LINESIZE]; char sbuf[LINESIZE]; char deftab[DEFSIZE]; char *defptr; char *maxdef; char symtab[SYMSIZE]; char *freeptr; char *maxsym; char infile[LINESIZE]; char outfile[LINESIZE]; FILE *file[4]; int filen; int eof; FILE *in; FILE *out; int hashtab[HASHSIZE]; char params[PARMSIZE]; int par[MAXPARMS]; int np; int main(argc, argv) int argc; char *argv[]; { in = UNDEFINED; out = UNDEFINED; filen = 1; eof = FALSE; maxdef = deftab + DEFSIZE; maxsym = symtab + SYMSIZE; inithash(); while ((*argv[1] & 0xFF) == '-') { /* BUG in compiler */ ip = argv[1] + 1; if (*ip++ == 'D') { if (sym(sbuf) == FALSE) usage(); if (*ip++ == '=') install(sbuf, ip); else install(sbuf, ""); --argc; argv++; } else usage(); } if (argc < 2 | argc > 3) usage(); if ((in = fopen(argv[1], "r")) == NULL) cant(argv[1]); if (argc == 2) out = stdout; else { if ((out = fopen(argv[2], "w")) == NULL) cant(argv[2]); } parse(); fclose(out); exit(0); } /* * print correct usage, and exit */ usage() { fprintf(stderr, "usage: tcpp [-Dname[=def]] infile [outfile]\n"); fatal(-1); } /* * initialise empty hash table */ inithash() { int i; freeptr = symtab; defptr = deftab; i = 0; while (i < HASHSIZE) hashtab[i++] = 0; } /* * print offending line, and exit */ error() { fprintf(stderr, "\n%s", obuf); fatal(-1); } /* * tidy up and exit on fatal error */ fatal(stat) int stat; { if (in != NULL) fclose(in); if (out != NULL) fclose(out); exit(stat); } /* * parse input text */ parse() { while (filen) { inline(); if (amatch("#ifdef", 6)) ifdef(); else if (amatch("#ifndef", 7)) ifndef(); else if (amatch("#else", 5)) break; else if (amatch("#endif", 6)) break; else if (amatch("#define", 7)) addmac(); else { process(); rescan(); } } } /* * rescan processed line looking for preprocessor #directives */ rescan() { ip = obuf; if (amatch("#include", 8)) openincl(); else if (amatch("#if ", 4)) doif(); else fputs(obuf, out); } /* * match n chars with input buffer */ amatch(s, n) char *s; int n; { if (strncmp(ip, s, n) != SAME) return(FALSE); else { ip = ip + n; return(TRUE); } } /* * skip 'white space' on input */ skip() { while(*ip == ' ' | *ip == '\t') ip++; } /* * open nested #include file * ------------------------- * Tries to open file in current directory first, then tries * 'standard' path if #include was used. */ openincl() { char delim; /* filename delimeter */ char path[LINESIZE]; /* used to prepend 'standard' path */ if (filen >= 3) { fprintf(stderr, "tcpp: too many #include files\n"); fatal(-1); } skip(); delim = *ip; if (delim != '"' & delim != '<') { fprintf(stderr, "tcpp: can't include %s\n", ip); fatal(-1); } file[filen++] = in; if ((in = fopen(filename(sbuf), "r")) == NULL) { if (delim == '<') { strcpy(path, INCLUDE); strcat(path, sbuf); if ((in = fopen(path, "r")) != NULL) return; } fixname(sbuf, delim); } } /* * get name of #include file */ char *filename(buf) char *buf; { char *bp; /* buffer pointer */ char delim; /* filename delimeter */ bp = buf; delim = *ip++; if (delim == '<') delim = '>'; while (*ip != delim & *ip != '\n') *bp++ = *ip++; *bp = '\0'; return(buf); } /* * try to find #include file by fiddling with filename */ fixname(s, delim) char *s; char delim; { char *p; /* filename pointer */ char path[LINESIZE]; /* used to prepend 'standard' path */ /* fix BBC Micro filename suffix */ for (p = s; *p; ++p) ; if (*(p - 2) == '.') *(p - 2) = '/'; /* now try to open the file again */ if ((in = fopen(s, "r")) == NULL) { if (delim == '"') cant(s); else { strcpy(path, INCLUDE); strcat(path, s); if ((in = fopen(path, "r")) == NULL) cant(path); } } } /* * input line */ inline() { while (filen) { if (fgets(ibuf, BUFSIZ, in)) break; else { ibuf[0] = '\n'; ibuf[1] = '\0'; fclose(in); if (--filen == 0) eof = TRUE; in = file[filen]; } } op = obuf; ip = ibuf; } /* * process line of text */ process() { while (*ip != '\n') { if (sym(sbuf)) expand(sbuf); else if (*ip == '"' | *ip == '\'') qtext(); else if (amatch("/*", 2)) comment(); else if (*ip == ' ' | *ip == '\t') keepsp(); else *op++ = *ip++; } *op++ = '\n'; *op = '\0'; } /* * get next symbol * --------------- * copy alpha prefixed alphanumeric string from input buffer, * and return length of string */ sym(p) char *p; { char *bp; bp = p; while (isalnum(*ip) | *ip == '_') *bp++ = *ip++; *bp = '\0'; return(bp - p); } /* * expand macro definition or copy symbol */ expand(name) char *name; { char *tag; char *p; char *to; int np; int flag; flag = 0; np = 0; if ((tag = hashfind(name)) != NULL) { p = mgetw(tag + BODYPTR); if (*ip == '(') np = parms1(); to = op; while (*p) { if (*p <= np) { strcpy(op, par[*p - 1]); op = op + strlen(par[*p - 1]); p++; flag = 1; } else *op++ = *p++; } if (flag == 1) { strcpy(op, ip); strcpy(ibuf, obuf); op = to; ip = ibuf + (op - obuf); } } else while (*name) *op++ = *name++; } /* * get parameters for macro */ parms1() { int nb; char *s; char *p; char tbuf[BUFSIZ]; p = params; np = 0; nb = 0; ip++; skip(); while (*ip != ')') { s = tbuf; while ((nb > 0) | (*ip != ',' & *ip != ')')) { if (*ip == '(') nb++; if (*ip == ')') nb--; if (*ip == '\n') { fprintf(stderr, "tcpp: unexpected newline\n"); error(); } *s++ = *ip++; } *s = '\0'; par[np++] = p; strcpy(p, tbuf); p = p + strlen(p); *p++ = '\0'; if (np > MAXPARMS) { fprintf(stderr, "tcpp: too many parameters\n"); error(); } if (*ip != ')') ip++; skip(); } ip++; return(np); } /* * copy quoted text * ---------------- * delimeter is current input char * \ character escapes are preserved */ qtext() { char delim; delim = *op++ = *ip++; while (*ip != delim) { if ((*op++ = *ip) == '\0') { fprintf(stderr, "tcpp: delimeter missing\n"); error(); } else if (*ip++ == '\\') *op++ = *ip++; } *op++ = *ip++; return; } /* * skip comment */ comment() { while (eof == FALSE) { if ((inchar() == '*') & (*ip == '/')) break; } ++ip; } /* * keep one space between tokens */ keepsp() { *op++ = ' '; while (*ip == ' ' | *ip == '\t') ip++; } /* * add new macro to symbol table */ addmac() { char *p; skip(); if (sym(name) == 0) { fprintf(stderr, "tcpp: illegal symbol name\n"); error(); } else { process(); ip = obuf; macdef(mac); install(name, mac); } } /* * #ifdef ... #endif */ ifdef() { skip(); if (sym(sbuf) == 0) { fprintf(stderr, "tcpp: '#ifdef symbol' expected\n"); error(); } if (hashfind(sbuf)) { parse(); ip = ibuf; if (amatch("#else", 5)) { while (amatch("#endif", 6) == FALSE) inline(); } } else { while (amatch("#endif", 6) == FALSE) { if (amatch("#else", 5)) { parse(); break; } inline(); } } } /* * #ifndef ... #endif */ ifndef() { skip(); if (sym(sbuf) == 0) { fprintf(stderr, "tcpp: '#ifndef symbol' expected\n"); error(); } if (hashfind(sbuf) == FALSE) { parse(); ip = ibuf; if (amatch("#else", 5)) { while (amatch("#endif", 6) == FALSE) inline(); } } else { while (amatch("#endif", 6) == FALSE) { if (amatch("#else", 5)) { parse(); break; } inline(); } } } /* * #if ... #endif */ doif() { int n; skip(); if (isalnum(*ip) == FALSE) { fprintf(stderr, "tcpp: '#if symbol' expected\n"); error(); } if ((n = atoi(ip)) != 0) { parse(); ip = ibuf; if (amatch("#else", 5)) { while (amatch("#endif", 6) == FALSE) inline(); } } else { while (amatch("#endif", 6) == FALSE) { if (amatch("#else", 5)) { parse(); break; } inline(); } } } /* * read char from input buffer * --------------------------- * input new line if necessary */ inchar() { if (*ip == '\0') inline(); if (eof) return(0); else return(*ip++); } /* * hashing algorithm * ----------------- * returns value in range 0 to HASHSIZE - 1 * for best results HASHSIZE should be a prime */ hash(name) char *name; { int h; h = 0; while (*name) h = (3 * h + *name++) % HASHSIZE; return(h); } /* * install new macro */ install(name, mac) char *name; char *mac; { char *p; char *m; int len; int h; len = strlen(name) + 5; if (freeptr + len > maxsym) { fprintf(stderr, "tcpp: symbol table full\n"); fatal(-1); } if (defptr + strlen(mac) > maxdef) { fprintf(stderr, "tcpp: macro definition table full\n"); fatal(-1); } if (hashfind(name) != NULL) printf("tcpp: macro %s redefined\n", name); h = hash(name); p = freeptr; mputw(p + NEXTPTR, hashtab[h]); hashtab[h] = p; mputw(p + BODYPTR, defptr); m = mac; while (*m != '\0') *defptr++ = *m++; *defptr++ = '\0'; strcpy(p + NAME, name); freeptr = p + len; } /* * get macro definition */ macdef(m) char *m; { int flag; int i; char tbuf[BUFSIZ]; np = 0; if (*ip == '(') parms(); skip(); while (*ip != '\n') { if (sym(tbuf) == 0) *m++ = *ip++; else { flag = 1; for (i = 0; i < np; ++i) { if (strcmp(par[i], tbuf) == SAME) { *m++ = i + 1; flag = 0; } } if (flag == 1) { strcpy(m, tbuf); m = m + strlen(m); } } } *m = '\0'; } /* * get parameters for macro */ parms() { char *p; char tbuf[BUFSIZ]; p = params; ip++; skip(); while (*ip != ')') { if (sym(tbuf) == 0) { fprintf(stderr, "tcpp: illegal parameter %s\n", ip); error(); } par[np++] = p; strcpy(p, tbuf); p = p + strlen(tbuf); *p++ = '\0'; if (np > MAXPARMS) { fprintf(stderr, "tcpp: too many parameters\n"); error(); } skip(); if (*ip == ',') { ip++; skip(); } } ip++; } /* * find symbol using hash + chain */ char *hashfind(name) char *name; { char *tag; tag = hashtab[hash(name)]; while (tag) { if (strcmp(tag + NAME, name) == SAME) break; else tag = mgetw(tag + NEXTPTR); } return(tag); } /* * print can't open ... and exit */ cant(s) char *s; { fprintf(stderr, "tcpp: can't open %s\n", s); fatal(-1); } /* * put word into memory low byte first */ mputw(p, val) int *p; int *val; { *p = val; } /* * get word from memory low byte first */ mgetw(p) int *p; { return(*p); } /* tcpp.c - Small-C Preprocessor