amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) (10/15/90)
Submitted-by: Eddy Carroll <ECARROLL@vax1.tcd.ie> Posting-number: Volume 90, Issue 282 Archive-name: util/snoopdos-1.0/part01 [ uuencoded executable enclosed ...tad ] SnoopDos is a little utility that lets you see keep an eye on what other programs are doing. Specifically, it displays details of any calls a program makes to AmigaDOS's Open(), Lock(), LoadSeg(), Execute(), CurrentDir() and DeleteFile() functions. There are several uses for this. Any libraries, devices, or fonts that a program tries to access will be displayed, which can be useful if the program isn't overly generous with its error messages. Similarly, you can see what special startup files a program looks for. Since environment variables are stored as files in ENV:, you can also see what variables a program tries to read when you run it. In general, SnoopDos is just a handy utility to have around when things don't seem to be working quite right. As an added bonus, SnoopDos works just fine under Workbench 2.0. #!/bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of archive 1 (of 2)." # Contents: makefile res.s snoopdos.doc snoopdos.uu snoopglue.s # system.h tiny.a # Wrapped by tadguy@abcfd20 on Sun Oct 14 15:07:01 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'makefile'\" else echo shar: Extracting \"'makefile'\" \(799 characters\) sed "s/^X//" >'makefile' <<'END_OF_FILE' X# X# Lattice LKM makefile, for Lattice C V5.04 :ts=8 X# X# SnoopDos (C) Copyright Eddy Carroll, May 1990 X# X XCFLAGS = -cusq -j88i -ms -v # -d5 XBFLAGS = sc sd nd map ram:map X#BFLAGS = addsym XLIBS = lib:lc.lib lib:amiga.lib XASM = lc:asm X#START = lib:c.o XSTART = tiny.o X X.c.o: X lc $(CFLAGS) -Hsystem.sym $*.c X.a.o: X $(ASM) -isys:include/ -u $*.a # Prefix all symbols with C-style _ X.s.o: X $(ASM) -isys:include/ $*.s # Standard "pure" assembly X.n.doc: X nro >$*.doc -ms:an $*.n X.h.sym: X lc1 -ph -o$*.sym $*.h X X# X# Makefile dependencies X# Xall: snoopdos X XOBJS = tiny.o snoopdos.o snoopglue.o res.o X Xsnoopdos: $(OBJS) X blink from $(OBJS) to snoopdos $(BFLAGS) lib $(LIBS) X Xsystem.sym: system.h Xtiny.o: tiny.a Xsnoopdos.o: snoopdos.c system.sym Xsnoopglue.o: snoopglue.s Xres.o: res.s END_OF_FILE if test 799 -ne `wc -c <'makefile'`; then echo shar: \"'makefile'\" unpacked with wrong size! fi # end of 'makefile' fi if test -f 'res.s' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'res.s'\" else echo shar: Extracting \"'res.s'\" \(6516 characters\) sed "s/^X//" >'res.s' <<'END_OF_FILE' X*:ts=8 X***************************************************************************** X* * X* RES.S (C) Copyright Eddy Carroll 1989 * X* * X* This module allows you to make a duplicate copy of your current process. * X* In fact, both processes actually share the same code. However, the * X* seglist pointer of the current process is modified so that when the * X* process terminates, the memory doesn't get freed (if it did, the new * X* process would suddenly find itself deallocated. Hello guru...) * X* This code only works when called from CLI processes. * X* * X* The parameters passed are similar to those for CreateProc(), with the * X* difference that instead of passing a BPTR to a seglist, you pass the * X* address of the function the new process should start executing at. * X* * X* When the new process returns from this function, it will be removed from * X* the system, and its memory (finally) deallocated. * X* * X* The typical use for a function like this is to allow a program to detach * X* itself from a CLI (completely, with no trailing console handles etc.) * X* when it is run. This is a convenient feature for the user, if the program * X* is of the sort designed to sit in the background the whole time, rather * X* than do something immediately, then exit. * X* * X* Lattice provide cback.o which at first glance would seem to provide a * X* similar solution. However, cback.o makes it difficult to print error * X* messages to the console if there is an error on the command line - by * X* the time you spot the error, the CLI prompt has already been printed * X* and your error message is printed after it. This looks very messy. * X* Res avoids this problem by not spawning the background process until * X* after the error checking has been done. * X* * X* From C, you call it as follows: * X* * X* pid = res(name,pri,func,stacksize) * X* * X* name - pointer to null terminated string * X* pri - integer, priority of the new process * X* func - pointer to the function for new process to call * X* stacksize - integer, size of the stack for the new process * X* * X* pid - Process ID of new process, or 0 if none created * X* * X***************************************************************************** X X INCLUDE "exec/types.i" X INCLUDE "exec/alerts.i" X INCLUDE "exec/nodes.i" X INCLUDE "exec/lists.i" X INCLUDE "exec/ports.i" X INCLUDE "exec/libraries.i" X INCLUDE "exec/tasks.i" X INCLUDE "libraries/dos.i" X INCLUDE "libraries/dosextens.i" X INCLUDE "workbench/startup.i" X INCLUDE "exec/funcdef.i" X INCLUDE "exec/exec_lib.i" X INCLUDE "libraries/dos_lib.i" X X xref _exit X xref _DOSBase X xdef _res X XAbsExecBase equ 4 Xsegsize equ 36 ; Size of fake seg. (code = 28 bytes) X X csect text,0,0,1,2 * xref's after this are 16-bit reloc X X Xcallsys macro X CALLLIB _LVO\1 X endm X X_res: X movem.l d2-d4/a2/a3/a6,-(a7) ; Save registers X move.l AbsExecBase.w,a6 ; Get base of Exec library X moveq #0,d1 ; Any sort of memory will do X moveq #segsize,d0 ; Get size of fake segment X callsys AllocMem ; Grab some memory X tst.l d0 ; Did we get any? X beq fatal ; If not, abort immediately! X move.l d0,a3 ; Save pointer to memory X sub.l a1,a1 ; NULL pointer indicates our process X callsys FindTask ; Get pointer to our process block X move.l d0,a2 ; Save it X move.l pr_CLI(A2),a0 ; Get BPTR to our process's segarray X add.l a0,a0 ; Convert BPTR to address X add.l a0,a0 ; X move.l cli_Module(a0),4(a3) ; Make fake segment point to our code X clr.l cli_Module(a0) ; Remove process seg. from CLI seglist X move.l #segsize,(a3) ; Set size of fake seglist X lea.l 8(a3),a2 ; Get pointer to first code byte X X; X; Now a tiny machine code program is constructed. It looks like this: X; X; move.l #$xxxxxx,A4 ; Initialise A4 X; jsr $xxxxxx ; Call user program X; move.l #$xxxxxx,A6 ; Load DOSbase into A6 X; move.l #$xxxxxx,d1 ; Get BPTR to this segment X; jmp UnLoadSeg(A6) ; Unload our process from memory X; X; It's built "on the fly" so to speak, to keep code size down, and also X; because it's a convenient way of initialising all the variables. X; Note that a potential problem exists if DOSBase should somehow alter or X; disappear. We'll assume it will remain relatively stable for the next X; few years anyway :-) X; X X move.l _DOSBase,a6 ; Prepare for DOS call X move.w #$287C,(a2)+ ; Store MOVE.L $xxxxxx,A4 instruction X move.l a4,(a2)+ ; Output value of A4 to initialise to X move.w #$4EB9,(a2)+ ; Store JSR $xxxxxx X move.l 36(a7),(a2)+ ; followed by address of user function X move.w #$2C7C,(a2)+ ; Store MOVE.L $xxxxxx,A6 instruction X move.l a6,(a2)+ ; followeds by current DOSbase X; X lea 4(a3),a3 ; Now get seglist ptr to fake segment X move.l a3,d3 ; and convert it to BPTR X lsr.l #2,d3 ; D3 now has seglist ptr to fake seg X move.w #$223C,(a2)+ ; Store MOVE.L $xxxxxx,D1 instruction X move.l d3,(a2)+ ; Followed by BPTR to the segment X move.l #$4EEEFF64,(a2)+ ; Store JMP UnLoadSeg(A6) X; X move.l 28(A7),d1 ; Get pointer to name X move.l 32(A7),d2 ; Get process priority X move.l 40(A7),d4 ; Get stacksize X callsys CreateProc ; Create new process X movem.l (a7)+,d2-d4/a2/a3/a6 ; Pop registers X rts ; Return Xfatal: X moveq #120,d0 ; Set error exit code X jmp _exit ; And exit X X end END_OF_FILE if test 6516 -ne `wc -c <'res.s'`; then echo shar: \"'res.s'\" unpacked with wrong size! fi # end of 'res.s' fi if test -f 'snoopdos.doc' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'snoopdos.doc'\" else echo shar: Extracting \"'snoopdos.doc'\" \(14548 characters\) sed "s/^X//" >'snoopdos.doc' <<'END_OF_FILE' X X SnoopDos V1.0 -- Monitors AmigaDOS function calls X X (C) Copyright Eddy Carroll, September 1990. Freely Distributable. X X XINTRODUCTION X X Have you ever wondered why a particular program won't seem to run? X It could be looking for some special files which you've forgotten to X install in the appropriate place. SnoopDos was designed to let you X resolve situations like this, though it's probably useful for other X things too. X X For those who don't like long instruction files, simply run SnoopDos X with no options, then run a few application programs and look at the X output displayed in SnoopDos's window. Interesting, eh? For those who'd X like a more detailed explanation, read on... X X When you start SnoopDos, it opens a console window. In this window X appears details of all calls made by any program on the system to the X CurrentDir(), DeleteFile, Execute(), LoadSeg(), Lock() and Open() X functions in the AmigaDOS library. The exception (as usual) is any X program written in BCPL; this includes most of the commands in the C: X directory. X X SnoopDos will tell you about all attempts to load libraries, devices X and fonts. It will also tell you if a program looks for a specific file X (for example in S:) or a specific disk volume or directory. This can be X very useful when you're playing with new software which may require X certain fonts or other support files. X X An unexpected bonus is that since AmigaDOS environment variables are X stored as files, SnoopDos will tell you the names of any environment X variables a program tries to read; if you see references to ENV:<name> X in the SnoopDos window, then a program is trying to access an environment X variable called <name>. X X XUSAGE X X When you start SnoopDos, it automatically detaches itself from the CLI X and runs in the background. You can specify a number of options on the X command line, either at this time or later on by running SnoopDos again. X Each option can be given in lower case or upper case to respectively X enable or disable that setting. Alternatively, you can follow the option X by `1' or `0' which has the same effect. So, `-d' and `-d1' both enable X the "Monitor DeleteFile()" option, whereas `-d' and `-d0' both disable X that option. Without further ado, here's an explanation of each setting: X X -a Normally, SnoopDos uses different colours when displaying messages, X to allow events to be easily distinguished from each other. You can X force SnoopDos not to use any colour by disabling this option. This X can be useful if you only have a 2-colour workbench. If SnoopDos is X sending its output to a file, it turns off this option by default X (but you can turn it back on again if you like). X X -c When this option is enabled, SnoopDos prints details of all calls X to the CurrentDir() function. A program calls CurrentDir() when it X wants to change its current directory to somewhere else. Note that X no result is displayed for this function, since AmigaDOS does not X allow for the possibility of it ever failing. X X -d This option allows you to see all calls to the DeleteFile() function, X which is called whenever a program wants to delete a file. This can X be useful with unknown programs, to make sure that they don't do X anything nasty (though in fairness, there are much more effective X ways for a rogue program to do damage than by deleting a few files). X X -f When enabled, this option causes SnoopDos to print out the full X path names for files. For example, if a program's current directory X is SYS:TOOLS and it tries to open a file called FOO, then the X filename would be displayed as SYS:TOOLS/FOO. Normally, it would X just be displayed as FOO. Filenames which are so expanded are X prefixed by a `>' character. Filenames which already included a full X path specification don't have this prefix. This allows you to X determine if the calling program specified the full path or not. X X -g This option enables or disables the monitoring of AmigaDOS's X LoadSeg() function. This is used to read in a binary loadfile and is X most commonly used for loading in libraries, devices, fonts and X handlers, and by third-party DOS shells to load in external commands. X X -l This option enables or disables the monitoring of AmigaDOS's Lock() X function. Programs usually call this function to see if a particular X file exists, or as a prelude to some more sophisticated operation on X the file. X X -m This option allows SnoopDos to be activated or deactivated while X still leaving it running. It is included merely for completeness; X a much easier way to achieve the same affect is to type CTRL-D or X CTRL-E in the SnoopDos window. X X -o This option enables or disables the monitoring of AmigaDOS's Open() X function. Whenever a program wants to open a file for reading or X writing, it calls this function. X X -w If several tasks try to call a particular DOS function at the same X time, SnoopDos can only handle them one at a time. Normally, what X will happen is that the other tasks speed on without waiting for X SnoopDos and you see a warning message saying that some function X calls were missed (this doesn't happen very often anyway). When the X `-w' option is enabled however, SnoopDos will make all the X different tasks queue up and take their turn. X X There is one important consequence of this: if a program tries to X access a file on a volume not currently mounted (causing AmigaDOS to X display a "Please insert volume xyzzy" requester), then SnoopDos will X print out the details about the file requested but not whether the X request succeeded or not; it can't do this until you respond to the X requester. In the meantime, other tasks may now be trying to call X AmigaDOS. For example, if you might try to pop open a new CLI with X Dmouse or PopCLI, so that you can do an ASSIGN to fake the requested X volume. All these tasks will have to wait until the original DOS X call has been completed. X X Since this can confuse things (though only for the user), the option X is disabled by default. You should only need it if you have to be X absolutely sure of catching every action made by several tasks. X X -x This option enables or disables monitoring of Execute() calls. X Unlike most other DOS function calls, the return value from the X Execute() is NOT displayed; this is because when an Execute suceeds, X the command being executed will most likely making AmigaDOS calls of X of its own and if SnoopDos was waiting for Execute() to return, it X would skip printing these out. X X Some forms of Execute() will appear to have no associated command X to execute. This is normal, and occurs when a program redirects X command input from another file. X X X By default, Snoopdos operates as if you had started it with: X X SnoopDos -a1 -c1 -d1 -f0 -g1 -l0 -m1 -o1 -w0 -x1 X X or for those who prefer to use the other command format: X X SnoopDos -a -c -d -F -g -L -m -o -w -x X X There are four additional options as well, which cause immediate X actions to be performed. These are: X X -h Prints out a help screen for SnoopDos. Actually, typing any X unrecognised garbage after SnoopDos prints the help screen. X X -q Sends a message to the version of SnoopDos currently running telling X it to remove itself. This is one way to quit SnoopDos, the other X way being to type CTRL-C in its window. X X -r Prints out a brief report giving all the current settings for X SnoopDos (eagle-eyed users may spot a striking resemblance between X this display and the middle section of the help screen :-). Note X that all other command line options are ignored when you use -r. X X -z Allows you to specify an alternative output file for SnoopDos to X send messages to. The filename can follow immediately after the -z, X or you can leave a space if you like. X X There are several uses for this function. First of all, you can use X it to change the location of the SnoopDos window when it opens, by X specifying a filename like -zCON:0/0/640/60/SnoopDos) (for a very X short window). You should always make sure the window is at least 77 X columns wide or the output will look pretty messed up. X X If you specify -zSER: or -zAUX: then SnoopDos will send output to X the serial port at the baud rate specified in Preferences. AUX: is X slightly preferable to SER: since SnoopDos will then recognise the X CTRL-C, CTRL-D and CTRL-E characters when typed on the remote X terminal. If you are using a colour ANSI terminal, you may like to X re-enable colour by specifying `-a' in conjunction with this option. X X Finally, you can of course redirect output to a normal AmigaDOS file. X You would only want to do this if you wanted to keep a permanent X record of what went on on your system. This could be useful if you X allow remote access to your Amiga and want a record of what people X do on your system. X X XTHE SNOOPDOS WINDOW X X The SnoopDos window is divided into a number of columns, as follows: X X Process name X The name of the process (or CLI command) that is executing the X DOS call in question. If the DOS call is nested (see Res. below) X then the process name will be prefixed by '> '. X X Func X The function being executed (Open, Lock or Load). Open is printed X in white, Lock in orange and Load in black, to allow rows to be X quickly identifed at a glance. (Of course, if you've changed your X Preferences, the actual colours may be different.) Other values X which can appear here are Exec (for Execute), CD (for CurrentDir) X and Del (for DeleteFile). X X Filename X The name of the file being accessed. Remember that when the `-f' X option is enabled, this will be prefixed by a `>' character if the X filename displayed was expanded by SnoopDos to include the current X directory of the calling process. X X Mode X For Open(), this is OLD if an existing file is being opened or NEW X if a new file is being opened. For Lock(), this is SHAR if the lock X is a shared lock (i.e. several processes can access the same file) or X EXCL if it is an exclusive lock (only this process can access the X file). It remains empty for LoadSeg(). X X Res. X The result of the DOS call. This is either `Okay' in white or X `Fail' in orange. In general, you learn much more from the `Fail' X entries (i.e. the things the program tried to find but couldn't). X X Occasionally, you may see a `>>>>' appearing here. This happens if X some other program has also patched DOS library in such a way that X the function currently being called calls another DOS function X itself. One such program is Rez, which tries to open a program file X for reading if you LoadSeg() it. In this case, the `>>>>' indicates X that DOS calls are being nested. The DOS calls which are nested X will have the associated process name prefixed by `> ' when they X are displayed. `> (Done)' is displayed when the top level DOS X function exits, and the exit status is displayed on the same X line in the Res. column as normal. X X You can type several keys into the SnoopDos window. CTRL-C will terminate X SnoopDos. CTRL-D will disable monitoring temporarily (and print a brief X message to that effect); CTRL-E enables it again. Pressing Space or any X other key will pause the output to the window, as in a CLI window. Press X BackSpace to continue. Note that if you have the `-w' option enabled and X you pause the output, all functions for which monitoring is enabled will X cause the calling process to go to sleep until you restart output again. X X When SnoopDos wants to quit, it makes sure that nobody else has patched X the DOS library after it. If something has, SnoopDos will refuse to exit X immediately. Instead, it will check approximately every 5 seconds to X see if it is safe to exit and as soon as it can, it will. X X XHISTORY X X Version 0.9, May 28th 1990. X X Initial Beta release. No doubt people will find lots of bugs. X X Version 0.91, May 29th 1990. X X Silly bug meant Snoopdos couldn't open its console window unless X Conman was installed. Now fixed. X X Improved the way DOS library is patched to make it somewhat more X robust (it now works properly with UnixDirs). X X Version 0.92, May 31st 1990. X X Strange bug seemed to manifest itself when Rez was used; the first X time a resident program was loaded, the display got messed up. Turns X out that Rez calls Open() from within LoadSeg(). Such nesting of X DOS calls is now indicated by prefixing the process name printed X for any nested operations with a '>'. When the nesting is completed, X '> Done' is displayed. X X Version 0.93, June 2nd 1990. X X Added -X option to monitor Execute() calls and reworked assembly X language glue a bit to make it easier to modify in future. X X Version 1.00, 9th September 1990. X X First public release. After unexpectedly being sent to the US for X the summer (new job), I finally got around to tidying it up. X New features include monitoring of DeleteFile() and CurrentDir(), X support for alternative devices/files (such as the serial port), X colour now optional, a few other cosmetic changes. X X XAUTHOR X X Eddy Carroll X X Email: ecarroll@vax1.tcd.ie X Phone: +353-1-874540 X Snailmail: The Old Rectory, Delgany, Co. Wicklow, Ireland. X X XDISTRIBUTION X X SnoopDos may be freely distributed as long as no charge is made other X than to cover time and copying costs. If you want to include SnoopDos X as part of a commercial package (somehow I doubt it but it never hurts X to mention :-) then contact the author listed above. Fred Fish is X specifically given permission to include SnoopDos in his fine disk X collection. END_OF_FILE if test 14548 -ne `wc -c <'snoopdos.doc'`; then echo shar: \"'snoopdos.doc'\" unpacked with wrong size! fi # end of 'snoopdos.doc' fi if test -f 'snoopdos.uu' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'snoopdos.uu'\" else echo shar: Extracting \"'snoopdos.uu'\" \(16885 characters\) sed "s/^X//" >'snoopdos.uu' <<'END_OF_FILE' Xbegin 644 snoopdos XM```#\P`````````"``````````$```K"```"6@```^D```K"2.=^_DOO`#0D6 XM2"0`2?D`````+'@`!"E.`!`I3P`8D\E.KO[:)D`@#9"M``0&@````(`I0``$D XM0^P`)'``3J[]V"E``!QF```(<&1@``#H(&L`K-'(T<@B:``0T\G3R2`"<@`2$ XM&2E)`"#0@5*`0F=2@`)`__Z?P%6`0G<(`"`"4X#4@1^R```@`%."4<C_]A^\V XM`"`@`%."'[$@`"``4<K_^")/G_P```&0)$\F2G0`831E$F?Z0>G__V$<82AFL XM_$(I__]@ZB!)80YA&F3\0BG__V$29OQGV"3(4D(,0@!D8R)P;F!0$!EG)@P`F XM`")G%@P``"!G"@P```EG!`P```H"/``>3G4`/``!`CP`^TYU+PLO`D?Y```"7 XM('(`(#P```'28`(FP5'(__Q.NA?@<`!@!"`O``0O`"QX``0B;``<3J[^8B`?@ XM+FP`&$S??WY.=0``+P<N+P`(("P`]%*L`/1*@&9"2JP%JF<*+RP%JDZZ(\Y8- XM3TJL!;)G#"(L!;(L;``<3J[_W$JL!;9G#"(L!;8L;``<3J[_W'#_OH!G""\') XM3KK_D%A/+A].=5!R;V-E<W,@;F%M92`@("`@("`@("!&=6YC("!&:6QE;F%MV XM92`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@36]D92!297,N#0HMF XM+2TM+2TM+2TM+2T@("`@("`@("`@+2TM+2`@+2TM+2TM+2T@("`@("`@("`@+ XM("`@("`@("`@("`@("`@("`@("`@("TM+2T@+2TM+0T*``!/3$0@``!.15<@H XM```;6S,S;4Y%5QM;,&T@`%(O5R```!M;,S)M4B]7&ULP;2``/S\_(```4TA!J XM4@``15A#3```&ULS,VU%6$-,&ULP;0`_/S\_``!/:V%Y#0H``$9A:6P-"@``` XM&ULS,VU&86EL&ULP;0T*`#X`&ULS,VT^&ULP;0``/B`H1&]N92D``%=A<FYI] XM;F<Z($UI<W-E9``;6S,S;5=A<FYI;F<Z&ULP;2!-:7-S960``#X^/CX-"@``4 XM3W!E;@``3&]C:P``&ULS,VU,;V-K&ULP;0!,;V%D```;6S,R;4QO860;6S!M; XM`$5X96,``!M;,S)M17AE8QM;,&T`0T0@(```1&5L(```&ULS,VU$96P;6S!M2 XM(`!204T`.BXN+B\`*@!3;F]O<$1O<R!0;W)T`%-N;V]P1&]S.B!#86XG="!A4 XM;&QO8V%T92!M97-S86=E('!O<G0N"@!3;F]O<$1O<SH@0V%N)W0@86QL;V-A. XM=&4@96YO=6=H('-I9VYA;',N"@!3;F]O<$1O<SH@0V%N)W0@;W!E;B!F:6QE6 XM("5S(&9O<B!O=71P=70N"@`-"E-N;V]P1&]S(%8Q+C`P("A#*2!#;W!Y<FEG: XM:'0@161D>2!#87)R;VQL+"!397!T(#$Y.3`N($9R965L>2!D:7-T<FEB=71A< XM8FQE+@T*#0H`0T]..C`O,"\V-#`O,3(P+U-N;V]P1&]S(%8Q+C`P("A#*2!#S XM;W!Y<FEG:'0@161D>2!#87)R;VQL+"!397!T(#$Y.3`N($9R965L>2!D:7-TO XM<FEB=71A8FQE+@!3;F]O<$1O<SH@0V%N)W0@;W!E;B!D:7-P;&%Y('=I;F1O- XM=RX*``I4>7!E($-44DPM12]#5%),+40@=&\@96YA8FQE+V1I<V%B;&4@<VYOT XM;W!I;F<N(%1Y<&4@0U123"U#('1O(&5X:70N"@H```I3;F]O<&EN9R!N;W<@< XM9&ES86)L960[('1Y<&4@0U123"U%('1O(&5N86)L92!I="!A9V%I;BX-"@T*? XM`%-N;V]P:6YG(&YO=R!E;F%B;&5D.R!T>7!E($-44DPM1"!T;R!D:7-A8FQE& XM(&ET(&%G86EN+@T*#0HE<P``/B`E<P``)2TR,7,@)7,@)7,E+3,Y<R`E<R``H XM`"``)2TR,7,@)7,@)7,E+30T<R``)2TR,7,@)7,@("5S#0H``"4M-S-S`"5S; XM(&%N($]P96XH*0T*```E<R!A($QO8VLH*0T*`"5S(&$@3&]A9%-E9R@I#0H`S XM`"5S(&%N($5X96-U=&4H*0T*`"5S(&$@0W5R<F5N=$1I<B@I#0H`)7,@82!$" XM96QE=&5&:6QE*"D-"@`-"E-O;65O;F4@96QS92!H87,@<&%T8VAE9"!D;W,N6 XM;&EB<F%R>2!S;R!))VQL(&AA=F4@=&\@=V%I="!U;G1I;"!T:&5Y('%U:70NR XM#0H``%1H:7,@=VEN9&]W('=I;&P@8VQO<V4@<VAO<G1L>2!T:&]U9V@@=&\@\ XM<W1O<"!I="!F<F]M(&%N;F]Y:6YG('EO=2X-"@`-"E-N;V]P1&]S('1E<FUII XM;F%T960N#0H``"UZ(&UU<W0@8F4@9F]L;&]W960@8GD@82!F:6QE;F%M92X@O XM5'EP92!3;F]O<$1O<R`M:"!F;W(@:&5L<"X*``!5;G)E8V]G;FES960@;W!TM XM:6]N("5S+B!4>7!E(%-N;V]P9&]S("UH(&9O<B!H96QP+@H`4VYO;W!$;W,@5 XM5C$N,#`@*$,I($-O<'ER:6=H="!%9&1Y($-A<G)O;&PL(%-E<'0@,3DY,"X@@ XM1G)E96QY(&1I<W1R:6)U=&%B;&4N"@I3;F]O<$1O<R!M;VYI=&]R<R!C86QL# XM<R!M861E('1O('9A<FEO=7,@06UI9V%$3U,@9G5N8W1I;VYS(&)Y(&%L;"!P8 XM<F]C97-S97,*;VX@=&AE('-Y<W1E;2X@5&AE(&9O;&QO=VEN9R!O<'1I;VYS` XM(&%R92!A=F%I;&%B;&4N(%5S92`M>#$@;W(@:G5S="`M>"!T;PIE;F%B;&4@* XM86X@;W!T:6]N+"`M6"!O<B`M>#`@=&\@9&ES86)L92!T:&%T(&]P=&EO;BX@> XM0W5R<F5N="!S971T:6YG<R!I;B`H+2DN"@H`0W5R<F5N="!3;F]O<$1O<R!S6 XM971T:6YG<SH*"@``("`@("UA("!5<V4@04Y322!C;VQO=7(@<V5Q=65N8V5SR XM("`@("`@("`@("`@("`@("`@("`@)7,*`"AO;BD``"AO9F8I`"`@("`M8R`@, XM36]N:71O<B!#=7)R96YT1&ER*"D@8V%L;',@("`@("`@("`@("`@("`@("`@J XM("5S"@`@("`@+60@($UO;FET;W(@1&5L971E1FEL92@I(&-A;&QS("`@("`@N XM("`@("`@("`@("`@("`E<PH`("`@("UF("!$:7-P;&%Y(&9U;&P@9FEL96YAM XM;64@<&%T:',@("`@("`@("`@("`@("`@("`@)7,*`"`@("`M9R`@36]N:71O> XM<B!,;V%D4V5G*"D@8V%L;',@("`@("`@("`@("`@("`@("`@("`@("5S"@`@3 XM("`@+6P@($UO;FET;W(@3&]C:R@I(&-A;&QS("`@("`@("`@("`@("`@("`@* XM("`@("`@("`E<PH`("`@("UM("!';&]B86QL>2!E;F%B;&4O9&ES86)L92!M) XM;VYI=&]R:6YG("`@("`@("`@("`@)7,*`"`@("`M;R`@36]N:71O<B!/<&5NQ XM*"D@8V%L;',@("`@("`@("`@("`@("`@("`@("`@("`@("5S"@`@("`@+7<@F XM($1I<W!L87D@86QL(&%C=&EV:71Y+"!S;&5E<&EN9R!I9B!N96-E<W-A<GD@[ XM("`E<PH`("`@("UX("!-;VYI=&]R($5X96-U=&4H*2!C86QL<R`@("`@("`@B XM("`@("`@("`@("`@("`@)7,*``H@("`@+6@@(%!R:6YT(&]U="!T:&ES(&AEK XM;'`@;65S<V%G90H@("`@+7$@(%1E;&P@4VYO;W!$;W,@=&\@<75I=`H@("`@? XM+7(@(%)E<&]R="!C=7)R96YT(%-N;V]P1&]S('-E='1I;F=S"B`@("`M>B4@: XM3W5T<'5T('1O(&9I;&4@)2`H92YG+B`M>D-/3CHP+S`O-C0P+S$P,"]3;F]O0 XM<$1O<R!O<B`M>E-%4CHI"@H``%1H97)E(&ES(&YO(&)A8VMG<F]U;F0@4VYO` XM;W!$;W,@<')O8V5S<R!T;R!T96QL('1O('%U:70A"@!3;F]O<$1O<P``0V]UE XM;&1N)W0@<W!A=VX@8F%C:V=R;W5N9"!3;F]O<$1O<R!T87-K+@H`3E4``$CG4 XM/Q`F;0`(+BT`#"PM`!`J+0`4*"T`&"\M`"`O+0`<+P0O!2\&+P<O"TAL!B).\ XMNABJ+&P`'$ZN_\1![`8B(DA*&6;\4XF3R"(`)`@F"4ZN_]!,[0C\_^1.74YU` XM3E4``$CG/Q`N+0`()FT`#"PM`!`J+0`4*"T`&"\M`"0O+0`@+RT`'"\$+P4ON XM!B\+2&P&(DZZ&$A![`8B(DA*&6;\4XF3R"(')`@F"2QL`!Q.KO_03.T(_/_DB XM3EU.=4Y5_]1(YP,0+BT`""PM``PF;0`0D\DL>``$3J[^VB!`0^@`7!M\``7_K XMY#M\`"3_[BM)_^HK0/_P*T?_]"M&__@K2__\*T#_V"M)_]0@;`6F0^W_W$ZNH XM_I(@;?_43J[^@"!M_]1.KOZ,3-\(P$Y=3G5.5?[02.<W,"XM``B3R2QX``1.M XMKO[:($`K:`"X__@L/````2M#[?[H(@D"0?_\0JW^W'3_(4(`N"M`__PK0?[@" XM(@<L;``<3J[_H"H`0>P"($(P:``B!20M_N`L;``<3J[_FDJ`9@12K?[<($)0I XMB"M(_^Q*$&8(0_KUF"M)_^P@;?_L2AAF_%.(D>W_["`((@:2@"P!4X8K0/[8` XM(@5.KO\N*T#^U"(%3J[_IBHM_M1![`(@T<8O+?[8+RW_["\(3KH5LD_O``Q*W XMA6<4(`8B+?[8T(%![`(@$;P`+P@`8!`@!M"M_MA![`(@$;P`.@@`2H5F`/]B, XM(&W__"%M__@`N$JM_MQG6B`'Y8`@0"(H`!#E@2)!)"D`*.6")$)'Z@`!=@`6F XM$B\#+PM(;`(@*T#^V"M!_M0K0O[03KH5.G``(&W^T!`00>P"($(P``!(>O3(/ XM2&P"($ZZ%4)![`(@(`A@"$'L`B#1QB`(3.T,[/ZT3EU.=4Y5__!(YP\P)FT`& XM""XM``PD;0`0*TK__'H`($I#^O2,$!BP&6842@!F]F8.($HB2Q+89OQP`&``9 XM`+0O!V$`_E)83R!`(DL2V&;\($M*&&;\4XB1RRP(2H5F*'`ZL!)F(GH!?`!*' XM,V@`9PQP.K`S:`!G!%*&8.YP.K`S:`!F:%*&8&1P+[`29B8H!E6$2H1K%'`O3 XML#-(`&<,<#JP,T@`9P13A&#H2H1K/BP$4H9@.$J%9B8K2O_P(&W_\$H09QIP: XM.K`09@X@;?_\(DL2V&;\<`!@&E*M__!@WB!+T<8B2A#99OQP`6`&4HI@`/]L\ XM3-\,\$Y=3G5.5?_(2.<W('X`?`%Z`'``+P!(>O.D*T#_\$ZZ%FY03RE`!:IFU XM&$AZ\YXO+`6V80#\GDAX__]A`/%B8``)#BEL!:H%IG``(&P%IA`H``]R`20!: XMX:(I0@E:</\L>``$3J[^MG(!)`'AHBE""4)P_TZN_K9R`20!X:(I0@E&</].: XMKOZV<@$D`>&B*4()2G#_3J[^MG(!)`'AHBE""4YP_TZN_K9R`20!X:(I0@E2W XM</].KOZV<@'AH2E!"59P_["L"4)G'+"L"49G%K"L"4IG$+"L"4YG"K"L"5)G& XM!%*!9AA(>O,.+RP%MF$`^^9(>/__80#PJF``"%9*K`6Z9T9![`6^(@@D/```# XM`^XL;``<3J[_XBE`!;)F'$AL!;Y(>O+\+RP%MF$`^ZI(>/__80#P;F``"!I(N XM>O,.+RP%LF$`^Y)03V`R0?KS4"(()#P```/N+&P`'$ZN_^(I0`6R9AA(>O.2; XM+RP%MF$`^VA(>/__80#P+&``!]@B+`6V+&P`'$ZN_]Q"K`6V2JP%NF8.2'KSO XMBB\L!;)A`/LZ4$\O+``P+RP%LF$`^RQ![`5X+'@`!$ZN_=*3R4ZN_MHI0`6N? XM3KH.UE!/2H=F``;"("P)6H"L"4*`K`E&@*P)2H"L"4Z`K`E2@*P)5@!`$```/ XM0"```$!``"QX``1.KO["*T#_[`@```QG`GX!"```#6<:2JP`[&<42'KS3B\LG XM!;)A`/JV4$]P`"E``.P(+0`&_^YG($JL`.QF&B\L`#!(>O-D+RP%LF$`^I!/M XM[P`,<`$I0`#L("W_["(L"4+"@&<&".T``/_S(BP)1L*`9P8([0`!__,B+`E*] XMPH!G!@CM``+_\R(L"4["@&<&".T``__S(BP)4L*`9P8([0`$__,B+`E6PH!GO XM!@CM``7_\\"L"5IG``3D(&P%IBQX``1.KOZ,*T#_Z$J`9P`$SB)`(&D`%"MH< XM``K_Y"(H`*SE@2MH`)C_W"M!_^!*AF8\)"D`&'8#M(-G&'8%M(-G$G8'M(-GF XM#'8*M(-G!G8+M(-F&GH!)"P`\.6"0>P`E"\P*``O+`6R80#YME!/2JW_X&=HX XM(&W_X$JH`#QG7B`H`!#E@$CM``'_S"!`$A!T`+("8VA#Z``!<``0`2\`+PE(N XM;`1Z3KH0ND_O``QP`"!M_\P0$$'L!'I",`@`0>P$>BM(_^1*A6<T0>P$>!"\S XM`#X1?``@``$K2/_D8"!*A6<<+RW_Y$AZ\D1(;`1X3KH1L$_O``Q![`1X*TC_I XMY"!M_^@K:``@_]1"K?_0("@`&`R`````#60``[C00#`[``9.^P`$`!@`'@`VN XM`$X#1`$J`T0!Y`-$`E`"?`+:`T1^`6```XYP)T'L`,PD;?_H(FH`(!+84<C_, XM_&```W9P)R)M_^@@:0`@0^P`S!+84<C__&```UX@;?_H("@`'`R````#[6843 XM(BP`\"0!Y8)![``T*W`H`/_88$@,@````^YF%"(L`/`D`>6"0>P`/"MP*`#_9 XMV&`L#(````/L9A0@+`#P(@#E@4'L`$0K<!@`_]A@$"`L`/#E@$'L`$PK<`@`% XM_]A*K`#D9R0@;?_H+R@`("\M_]Q(;`-,80#Z:$_O``Q![`-,*T#_T"M(_]0@* XM+`#PY8!*K?_09PI![`!\('`(`&`$0?KQ)B\M_]@O+?_4+PA#[`"<+S$(`"\M7 XM_^1(>O#V+RP%LF$`]]Y/[P`<?`!@``*"(&W_Z"`H`!QR_K"!9A0B+`#P)`'E( XM@D'L`%0K<"@`_]A@*%*`9A0@+`#P(@#E@4'L`%PK<!@`_]A@$"`L`/#E@$'L& XM`&0K<`@`_]A*K`#D9R0@;?_H+R@`("\M_]Q(;`-,80#YKD_O``Q![`-,*T#_@ XMT"M(_]0@+`#PY8!*K?_09PI![`!\('`(`&`$0?KP;"\M_]@O+?_4+PA#[`"D6 XM+S$(`"\M_^1(>O`\+RP%LF$`]R1/[P`<?`!@``'(2JP`Y&<D(&W_Z"\H`"`OA XM+?_<2&P#3&$`^3Y/[P`,0>P#3"M`_]`K2/_4("P`\.6`2JW_T&<*0>P`?"!PZ XM"`!@!$'Z[_PO+?_4+PA#[`"L+S$(`"\M_^1(>N_H+RP%LF$`]KA/[P`8?`!@F XM``%<("P`\.6`+RW_U$'L`+0O,`@`+RW_Y$AZ[\XO+`6R80#VC$_O`!1\`6``7 XM`3`@;?_H+R@`'&$`]T183R!`2AAF_%.(D<`K0/_,2.T!`/_(<B\@0"0M_\BRI XM,"C_9@1","C_(BP`\.6!+P!#[`"\+S$8`"\M_^1(>N]P+RP%LF$`]BY/[P`49 XM?`%@``#22JP`Y&<D(&W_Z"\H`"`O+?_<2&P#3&$`^$A/[P`,0>P#3"M`_]`K% XM2/_4("P`\.6`2JW_T&<*0>P`?"!P"`!@!$'Z[P8O+?_4+PA#[`#$+S$(`"\ME XM_^1(>N[R+RP%LF$`]<)/[P`8?`!@9DJ&9R1*A6<@("P`\.6`0>P`A"\P"`!(Y XM>N[J+RP%LF$`]9A/[P`,>@`@;?_H2J@`'&<:("P`\.6`0>P`;"\P"``O+`6R, XM80#U<E!/8!@@+`#PY8!![`!T+S`(`"\L!;)A`/584$]\`2)M_^@L>``$3J[^\ XMAF``^R!*K?_P9P#Z+DJ&9P#Z*`@M``#_\V<>("P`\.6`0>P`C"\P"`!(>NYL8 XM+RP%LF$`]11/[P`,""T``?_S9QX@+`#PY8!![`",+S`(`$AZ[E8O+`6R80#TA XM[D_O``P(+0`"__-G'B`L`/#E@$'L`(PO,`@`2'KN/B\L!;)A`/3(3^\`#`@M# XM``/_\V<>("P`\.6`0>P`C"\P"`!(>NXJ+RP%LF$`]*)/[P`,""T`!/_S9QX@X XM+`#PY8!![`",+S`(`$AZ[A8O+`6R80#T?$_O``P(+0`%__-G'B`L`/#E@$'L3 XM`(PO,`@`2'KN!"\L!;)A`/163^\`#$*M__!@`/D\(FP%IBQX``1.KOZ8(&P%E XMID*H``I.N@C`2H!F6D*M_^Q(>NW@+RP%LF$`]!Y03TJL!;IF#DAZ[APO+`6R( XM80#T"E!/<GW2@2QL`!Q.KO\Z2JP%LF<:4JW_[`RM`````O_L;PPB+`6R3J[_B XMW$*L!;).N@AF2H!GS$JL!;)G#DAZ[AHO+`6R80#SPE!/(&P%IBQX``1.KOZ,, XM*T#_[$J`9P@B0$ZN_H9@Y$'L!7@L>``$3J[]S'(*+&P`'$ZN_SI(>/__80#HX XM4DSM!.S_L$Y=3G5.5?_P2.<O,"XM``@F;0`,?`!Z`'@`0_KJ3"QX``1.KOYZW XM*4`%IF<22&P`S$*G2'@``6$`\Z1/[P`,<`&^@&\``8X@:P`$<BVR$&8``8)#" XMZ``!#!$`86400^@``G(PLA%G!BM`__!@!$*M__!#Z``!<@`2$47L`1T(,@``! XM&`!G"G0`%`%R(-2!8`I#Z``!<``0$20`=F&4@VT``10,@@```!IL``$*U$(T= XM.R`&3OL@!``R`/P`/@!(`/P`4@!<`&8`_`#\`/P`;`!V`/P`@`#\`(H`D`#\V XM`/P`_`#\`)8`G@#\`*8I;?_P`/!X`6```-@I;?_P`-Q@``#.*6W_\`#@8```$ XMQ"EM__``Y&```+HI;?_P`-1@``"P?`%@``"J*6W_\`#08```H"EM__``[&``= XM`)8I;?_P`,Q@``",>@%@``"&?`)@``"`*6W_\`#H8'8I;?_P`-A@;B!K``14C XMB$H09Q!#[`6^$MAF_'`!*4`%NF`:6(M3AW`!OH!O$"!L!;HB:P`$$-EF_"E`E XM!;I*K`6Z9A)(>NQ080#Q@DAX``5.NN:&4$]*A&8>0JP`\&`8+RL`!$AZ['!A; XM`/%B2'@`!4ZZYF9/[P`,6(M3AV``_FYP`;Z`;P(L`$J&9P`!3KR`9@Q(>NQVC XM80#Q-%A/8`I(>NV<80#Q*%A/2JP`\&<&0?KMY&`$0?KMY"\(2'KMGF$`\0Q0$ XM3TJL`-QG!D'Z[<A@!$'Z[<@O"$AZ[<AA`/#P4$]*K`#@9P9!^NVL8`1!^NVLO XM+PA(>NWF80#PU%!/2JP`Y&<&0?KMD&`$0?KMD"\(2'KN!&$`\+A03TJL`-1GO XM!D'Z[71@!$'Z[70O"$AZ[B)A`/"<4$]*K`#09P9!^NU88`1!^NU8+PA(>NY`U XM80#P@%!/2JP`[&<&0?KM/&`$0?KM/"\(2'KN7F$`\&103TJL`,QG!D'Z[2!@; XM!$'Z[2`O"$AZ[GQA`/!(4$]*K`#H9P9!^NT$8`1!^NT$+PA(>NZ:80#P+%!/+ XM2JP`V&<&0?KLZ&`$0?KLZ"\(2'KNN&$`\!!03W`!O(!F"DAZ[N)A`/``6$](+ XM>``%80#E(EA/2JP%IF<P2H5G$D*G<``O`"\`80#PG$_O``Q@$DAL`,Q"ITAX5 XM``)A`/"(3^\`#$*G80#D[%A/2H5G$$AZ[TAA`.^R0I=A`.386$]!^N;N(@@DA XM/````^XL;``<3J[_XBE`!;9(>`^@2'KS'$AX``5(>N].3KH&4D_O`!!*@&826 XM2'KO2&$`[VY(>``*80#DDE!/3-\,]$Y=3G5(YR,8)D$N`DGY`````$JL`.QG< XM``"`2JP`S&=XD\DL>``$3J[^VK"L!:YG:$JL`.AG"D'L!7A.KOW,8")![`5X! XM3J[]P$J`9A8B;`6N("P)0DZN_KPB"R0'3KH%3F`^+PLO!TAX``-A`.^P(@LDB XM!TZZ!3@L`$*7+P9(>``$80#OFD_O`!1![`5X+'@`!$ZN_<8@!F`((@LD!TZZ% XM!0Y,WQC$3G5(YR,8)D$N`DGY`````$JL`.QG``"`2JP`T&=XD\DL>``$3J[^, XMVK"L!:YG:$JL`.AG"D'L!7A.KOW,8")![`5X3J[]P$J`9A8B;`6N("P)1DZNY XM_KPB"R0'3KH$N&`^+PLO!TAX``5A`.\.(@LD!TZZ!*(L`$*7+P9(>``&80#N< XM^$_O`!1![`5X+'@`!$ZN_<8@!F`((@LD!TZZ!'A,WQC$3G5(YP$8)D%)^0``` XM``!*K`#L9WI*K`#49W23R2QX``1.KO[:L*P%KF=D2JP`Z&<*0>P%>$ZN_<Q@X XM($'L!7A.KOW`2H!F%")L!:X@+`E*3J[^O"(+3KH$*&`Z+PM"ITAX``=A`.YR# XM(@M.N@04+@!"ER\'2'@`"&$`[EY/[P`40>P%>"QX``1.KOW&(`=@!B(+3KH#G XM[$S?&(!.=4CG,Q@F02X"+`-)^0````!*K`#L9V9*K`#89V"3R2QX``1.KO[:0 XML*P%KF=02JP`Z&<*0>P%>$ZN_<Q@)$'L!7A.KOW`2H!F&")L!:X@+`E.3J[^1 XMO"(+)`<F!DZZ`Y1@)B\+0J=(>``)80#MTD_O``Q![`5X+'@`!$ZN_<8B"R0'D XM)@9.N@-L3-\8S$YU2.<!""X!2?D`````2JP`[&=B2JP`W&=<D\DL>``$3J[^< XMVK"L!:YG3$JL`.AG"D'L!7A.KOW,8"!![`5X3J[]P$J`9A0B;`6N("P)4DZNE XM_KPB!TZZ`QQ@(D*G+P=(>``*80#M3D_O``Q![`5X+'@`!$ZN_<8B!TZZ`OA,C XMWQ"`3G5(YP$8)D%)^0````!*K`#L9WA*K`#@9W*3R2QX``1.KO[:L*P%KF=B# XM2JP`Z&<*0>P%>$ZN_<Q@($'L!7A.KOW`2H!F%")L!:X@+`E63J[^O"(+3KH"^ XMJ&`X+PM"ITAX``MA`.S.(@M.N@*4+@!"ER\'2'@`#&$`[+I/[P`40>P%>"QX$ XM``1.KOW&8`8B"TZZ`FY,WQB`3G5(YP#R+'D````$('D````<".@``0`.3*@.4 XM`/_B2+D.`````/A,N0X````AXDBH#@#_XDRH#@#_K$BY#@````#^3+D.````J XM(>A(J`X`_ZQ,J`X`_VI(N0X````!!$RY#@```"'N2*@.`/]J3*@.`/\B2+D.L XM`````0I,N0X````A]$BH#@#_(DRH#@#_@DBY#@````$03+D.````(?I(J`X`A XM_X),J`X`_[A(N0X````!%DRY#@```"(`2*@.`/^X(DA.KOY63-]/`$YU2.<`P XM\BQY````!"!Y````'"`Y```AY+"H_^1F``"L(#D``"'JL*C_KF8``)X@.0``! XM(?"PJ/]L9@``D"`Y```A]K"H_R1F``""(#D``"'\L*C_A&8``'0@.0``(@*PU XMJ/^Z9@``9@CH``$`#DRY#@````#X2*@.`/_B3+D.`````/Y(J`X`_ZQ,N0X`C XM```!!$BH#@#_:DRY#@````$*2*@.`/\B3+D.`````1!(J`X`_X),N0X````!@ XM%DBH#@#_N")(3J[^5G`!8`)P`$S?3P!.=4[Y```B!D[Y```B&$[Y```B*D[Y/ XM```B/$[Y```B3D[Y```B8$CG/SY.N0``',I,WWS\(@!.=4CG/SY.N0``'6Q,' XMWWS\(@!.=4CG/SY.N0``'@Y,WWS\(@!.=4CG/SY.N0``'J9,WWS\(@!.=4CG1 XM/SY.N0``'S),WWS\(@!.=4CG/SY.N0``'[),WWS\(@!.=4'Y````^#`\_^)@( XM/D'Y````_C`\_ZQ@,D'Y```!!#`\_VI@)D'Y```!"C`\_R)@&D'Y```!$#`\\ XM_X)@#D'Y```!%C`\_[A@`DYQ2.=S`CP0#$9.^68``!`@:``"+'D````<3I!@, XM&#P02(9(QL%&/B@`!"QY````'-Y&3K9P!$S?0,Y.=0``2.<X,BQX``1R`'`D1 XM3J[_.DJ`9P``;"9`D\E.KO[:)$`@:@"LT<C1R"=H`#P`!$*H`#PFO````"1%T XMZP`(+'D````<-/PH?"3,-/Q.N23O`"0T_"Q\),Y'ZP`$)@ODBS3\(CPDPR3\; XM3N[_9"(O`!PD+P`@*"\`*$ZN_W9,WTP<3G5P>$[Y```!,$CG(#`F;P`0)$M*" XM$F<D<``0$D'L`1T(,``!"`!G"G(`$@!T()*"8`1R`!(`%(%2BF#8(`M,WPP$/ XM3G4``````````'!A(F\`""!O``0@+P`,(@A@!!#99PA3@&3X8`9"&%.`9/H@! XM`4YU(F\`""!O``0@"$H89OQ3B!#99OQ.=0``("\`""!O``1.5?_T(D]R"DZZZ XM`9P&00`P$L%*@&;P(`D0X;_)9OI"$)"/3EU.=0``("\`""!O``1.5?_T(D\B[ XM``)!``<&00`P$L'FB&;P(`D0X;_)9OI"$)"/3EU.=0``,#$R,S0U-C<X.6%B) XM8V1E9B`O``@@;P`$0^\`!#(``D$`#Q+[$-SHB&;R(`DB#UB!$.&RB6;Z0A"08 XM@4YU(&\`!")(<@!P`"\"#!``*V<&#!``+68"4D@0&`0``#!M$@P```EN#"0!B XMY8'2@M*!TH!@Y@P1`"UF`D2!)!\@"%.`(&\`"""!D(E.=2\'+B\`"%*L"60@4 XM!R!L"6`0P"E("6`N'TYU3E4``$CG`#`F;P`0)&\`%$*L"60I2PE@2&T`$"\*Z XM2'K_QDZZ!6`@;`E@0A`@+`ED3.T,`/_X3EU.=4CG`!(F;P`,2JL`"F<*(DLL) XM>``$3J[^F!=\`/\`"'#_)T``%'``$"L`#RQX``1.KOZP(DMP(DZN_RY,WT@`Y XM3G5*@&H``!Y$@$J!:@``#$2!80``($2!3G5A```81(!$@4YU2H%J```,1(%A4 XM```&1(!.=2\"2$$T`68``")(0$A!2$(T`&<```:$P3`"2$`T`(3!,`)(0C("H XM)!].=2\#=A`,00"`9```!N&944,,00@`9```!NF964,,02``9```!N6954-*7 XM06L```;CF5-#-`#FJ$A"0D+FJDA#@,$V`#`"-`-(0<3!D()D```(4T/0@63^D XM<@`R`TA#Y[A(0,%!)A\D'TYU2.<#,B9O`!@N+P`<</\L>``$3J[^MBP`#`8`U XM_V8$<`!@9G`B(CP``0`!3J[_.B1`(`IF"G``$`9.KOZP8$@E2P`*(`<50``); XM%7P`!``(0BH`#A5&``^3R4ZN_MHE0``0(`MG"")*3J[^GF`:0>H`&"5(`!1!# XMZ@`4)4@`'$*J`!@5?``"`"`@"DS?3,!.=0``3E7_Q$CG)S`F;P!<)&\`8'X`P XM?`!Z`'``&WP`(/_[<@`K0?_V=/\K0O_R0>W_T!M`__$;0/_\*T'_Y"M!_^@KF XM2/_,2A-G+'``$!,$0``@9Q170&<444!G"%5`9A9^`6`.?`%@"GH!8`8;?``!E XM__Q2BV#0$!-R,+`!9@92BQM!__MP*K`39@P@4EB2*U#_]E*+8`Y(;?_V+PM.U XMNOTR4$_7P!`3<BZP`68B4HMP*K`39@P@4EB2*U#_\E*+8`Y(;?_R+PM.NOT(' XM4$_7P!`3<FRP`68*&WP``?_Q4HM@"')HL`%F`E*+$!MR`!(`&T#_\`1!`%AGR XM``%^!$$`"V<``@I306<D!$$`"V<``1)306<``5!706<``;I506<``.1706<`1 XM`5)@``'X2BW_\6<((%)8DB`08`8@4EB2(!`K0/_L;`IR`42M_^PK0?_H2JW_D XMZ&<$<"U@"DH&9P1P*V`"<"`;0/_0<``0!B(M_^B"@'``$`6"@&<(4JW_S%*M) XM_^0O+?_L+RW_S$ZZ^ZI03RM`_\@@+?_R2H!J!G(!*T'_\B`M_\@B+?_RDH!(% XM[0`"_\1O-"!M_\PB2-/!+P`O"2\(3KH"4D_O``QP`!`M__LB+?_$(&W_S&`"B XM$,!3@63Z("W_\BM`_\C1K?_D0>W_T"M(_\Q*!V<``3`;?``@__M@``$F2BW_E XM\6<((%)8DB`08`8@4EB2(!`K0/_L8`#_9$HM__%G""!26)(@$&`&(%)8DB`0+ XM*T#_[$HM__QG$B!M_\P0_``P<@$K0?_D*TC_S"\`+RW_S$ZZ^PY03RM`_\A@M XM`/\R&WP`,/_[("W_\DJ`:@9P""M`__)*+?_Q9P@@4EB2(!!@!B!26)(@$"M`] XM_^Q*+?_\9Q8@;?_,$/P`,!#\`'AR`BM!_^0K2/_,+P`O+?_,3KKZ\E!/*T#_& XMR'!8L"W_\&8`_M!(;?_03KKYZEA/8`#^PB!26)(B4"M)_\QF"$'Z`-@K2/_,2 XM(&W_S$H89OQ3B)'M_\PK2/_D("W_\DJ`:R:QP&\B*T#_Y&`<<`$K0/_D(%)8$ XMDB`0&T#_T$(M_]%@!G``8```C"`M_^0B+?_VLH!L"'0`*T+_]F`$D:W_]DH'% XM9S93K?_D;1AP`"!M_\P0&"\`*TC_S"!M`!!.D%A/8.)3K?_V;4AP`!`M__LO& XM`"!M`!!.D%A/8.A3K?_V;1)P`!`M__LO`"!M`!!.D%A/8.A3K?_D;1AP`"!M# XM_\P0&"\`*TC_S"!M`!!.D%A/8.(@"TS?#.1.74YU``!.5?_T2.<!,"9O`"`D' XM;P`D*VT`$/_V'AI*!V<T<"6^`&8BL!)F!%**8!HO"TAM__8O"F$`_!9/[P`,+ XM*T#_^F<$)$!@TG``$`<O`$Z36$]@QDS?#(!.74YU```@;P`$(F\`""`O``QOD XM%K/(90S1P-/`$R!3@&;Z3G42V%.`9OI.=0`````#[````!D````````C?```6 XM(F8``")4```B0@``(C```"(>```B#```(@(``"'\```A]@``(?```"'J```AW XMY```(6H``"%<```A3@``(4```"$R```A)```(/P``"#@```@Q```(*@``"",( XM```@<````!\````!```C-@``(N8``"+0```A'@``(%0``"*P```BI```(I@`( XM`"*,```B@```(G0``"'&```AN```(:H``"&<```AC@``(8```"#T```@V```* XM(+P``""@```@A```(&@``!^Z```?.@``'K(``!X6```==@``'-0```$4````6 XM#@````````/R```#Z@```(@`````````````````````````````````````X XM``````````!D;W,N;&EB<F%R>0````&H```"2````D@```).```"5````F(`P XM``)H```"=@```G8```)\```"?````H(```*(```"E@```I8```*<```"G```0 XM`J0```*L```"O````KX```+*```"R@```M0```+D```"_@```OX```,&```#R XM!@```PP```,2```#(````R8```,T```#.@```T@```-(```#3@```U0````!I XM``````````$````!`````0````$```````````````$````!````````````& XM```````````````````````````````````````````@("`@("`@("`H*"@H` XM*"`@("`@("`@("`@("`@("`@($@0$!`0$!`0$!`0$!`0$!"$A(2$A(2$A(2$( XM$!`0$!`0$(&!@8&!@0$!`0$!`0$!`0$!`0$!`0$!`0$!$!`0$!`0@H*"@H*"V XM`@("`@("`@("`@("`@("`@("`@(0$!`0("`@("`@("`@("@H*"@H("`@("`@P XM("`@("`@("`@("`@2!`0$!`0$!`0$!`0$!`0$(2$A(2$A(2$A(00$!`0$!`00 XM@8&!@8&!`0$!`0$!`0$!`0$!`0$!`0$!`0$0$!`0$!""@H*"@H("`@("`@("4 XM`@("`@("`@("`@("`A`0$!`@```````#[````"<`````````R````,0```#`< XM````O````+@```"T````L````*P```"H````I````*````"<````F````)0`X XM``"0````C````(@```"$````@````'P```!X````=````'````!L````:```4 XM`&0```!@````7````%@```!4````4````$P```!(````1````$`````\````P X1.````#0````P`````````_)4E X`` Xend Xsize 12032 END_OF_FILE if test 16885 -ne `wc -c <'snoopdos.uu'`; then echo shar: \"'snoopdos.uu'\" unpacked with wrong size! fi # end of 'snoopdos.uu' fi if test -f 'snoopglue.s' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'snoopglue.s'\" else echo shar: Extracting \"'snoopglue.s'\" \(5668 characters\) sed "s/^X//" >'snoopglue.s' <<'END_OF_FILE' X* X* SNOOPGLUE.S :ts=8 X* X* Assembly support routines for snoopdos.c X* X* This file contains routines to patch/unpatch dos library to point X* to a C routine, and to call the old routines. X* X* Does some nasty tricks to patch into dos.library. However, since we X* checks to see if we are running under 2.0 (with dos.library looking X* just like any other library), Snoopdos works fine under 2.0. X* X INCLUDE "exec/types.i" X INCLUDE "exec/libraries.i" X INCLUDE "libraries/dosextens.i" X X XDEF _installdospatch X XDEF _uninstalldospatch X XDEF _CallLock X XDEF _CallOpen X XDEF _CallLoadSeg X XDEF _CallExecute X XDEF _CallCurrentDir X XDEF _CallDeleteFile X X XREF _DOSBase X X XREF _NewOpen X XREF _NewLock X XREF _NewLoadSeg X XREF _NewExecute X XREF _NewCurrentDir X XREF _NewDeleteFile X X XREF _LVOOpen X XREF _LVOLock X XREF _LVOLoadSeg X XREF _LVOExecute X XREF _LVOCurrentDir X XREF _LVODeleteFile X XCALL MACRO X XREF _LVO\1 X JSR _LVO\1(A6) X ENDM X X SECTION SnoopDos,CODE X X* X* Modify DOS library to call our functions for Open() and Lock(); X* We can't just use SetFunction() because DOS library is non-standard. X* Instead of using JMP $123456 type instructions, it uses (mostly) X* MOVEQ #funcnum,D0; BRA.L Dispatch. So, we replace this entire X* sequence with a standard JMP instruction, steal the number from X* the MOVEQ instruction and use it when we want to call the real X* DOS library later on. X* X_installdospatch: X MOVEM.L A0-A3/A6,-(A7) * Save regs X MOVE.L 4,A6 * Get ExecBase X MOVE.L _DOSBase,A0 * Get DOSbase X BSET #LIBB_CHANGED,LIB_FLAGS(A0) * Indicate changing DOS library X XSetFunc MACRO X MOVEM.W _LVO\1(A0),A1-A3 * Read in current value for func X MOVEM.W A1-A3,\1Save * Save the appropriate data X MOVEM.W CallOur\1,A1-A3 * Read in replacement code X MOVEM.W A1-A3,_LVO\1(A0) * And modify library X ENDM X X SetFunc Open X SetFunc Lock X SetFunc LoadSeg X SetFunc Execute X SetFunc CurrentDir X SetFunc DeleteFile X X MOVE.L A0,A1 * Finally, X CALL SumLibrary * Recalculate library checksum X MOVEM.L (A7)+,A0-A3/A6 * Save regs X RTS X X* X* Reinstall previous DOS patch. If someone has already altered the X* function, we can't actually exit immediately so return a FALSE X* result. While there is a very small window which could cause X* problems (if someone is in the middle of a SetFunction() when X* this is called), but we'll ignore this mostly. X* X_uninstalldospatch: X MOVEM.L A0-A3/A6,-(A7) * Save regs X MOVE.L 4,A6 * Get sysbase X MOVE.L _DOSBase,A0 * Get DOSBase X XTestFunc MACRO X MOVE.L CallOur\1+2,D0 * Get old address of function X CMP.L _LVO\1+2(A0),D0 * See if changed X BNE changed * If it has, exit with no action X ENDM X X TestFunc Open X TestFunc Lock X TestFunc LoadSeg X TestFunc Execute X TestFunc CurrentDir X TestFunc DeleteFile X X BSET #LIBB_CHANGED,LIB_FLAGS(A0) * Indicate changing DOS library X XRestFunc MACRO X MOVEM.W \1Save,A1-A3 * Read in prev. value of vec. X MOVEM.W A1-A3,_LVO\1(A0) * Atomically restore it X ENDM X X RestFunc Open X RestFunc Lock X RestFunc LoadSeg X RestFunc Execute X RestFunc CurrentDir X RestFunc DeleteFile X X MOVE.L A0,A1 * Finally, X CALL SumLibrary * Update library checksum X MOVEQ #1,D0 * Indicate success X BRA.S unexit * And exit X Xchanged: X MOVEQ #0,D0 * Indicate failure to uninstall Xunexit: X MOVEM.L (A7)+,A0-A3/A6 * Restore regs X RTS * And exit with return in D0 X X* X* This code is the code that gets moved directly into the DOS X* library vectors X* XCallOurOpen: JMP NewOpen XCallOurLock: JMP NewLock XCallOurLoadSeg: JMP NewLoadSeg XCallOurExecute: JMP NewExecute XCallOurCurrentDir: JMP NewCurrentDir XCallOurDeleteFile: JMP NewDeleteFile X X* X* These are the replacement DOS routines. X* XNewFunc MACRO X MOVEM.L A2-A6/D2-D7,-(A7) * Save all registers (to be safe) X JSR _New\1 * Call C version with params in D1-D3 X MOVEM.L (A7)+,A2-A6/D2-D7 * Restore registers X MOVE.L D0,D1 * Copy return value into D1 X* * [some routines expect this :-( ] X RTS * Return to caller, exit value in D0 X ENDM X XNewOpen: NewFunc Open XNewLock: NewFunc Lock XNewLoadSeg: NewFunc LoadSeg XNewExecute: NewFunc Execute XNewCurrentDir: NewFunc CurrentDir XNewDeleteFile: NewFunc DeleteFile X X* X* Allow's C to call the old DOS functions. If we're running Kikstart 2.0 X* then just call the original function directly. Otherwise, calculate X* where to go from the code stored in the vector. X* XOldDosCall MACRO X LEA.L \1Save,A0 * Get pointer to func save vector X MOVE.W #_LVO\1,D0 * Get library offset vector X BRA.S CallDos * Skip to execute it X ENDM X X_CallOpen: OldDosCall Open X_CallLock: OldDosCall Lock X_CallLoadSeg: OldDosCall LoadSeg X_CallExecute: OldDosCall Execute X_CallCurrentDir: OldDosCall CurrentDir X_CallDeleteFile: OldDosCall DeleteFile X X NOP * Stop Lattice messing up final branch XCallDos: X MOVEM.L D1-D3/D6/D7/A6,-(A7) * Save registers X MOVE.W (A0),D6 * Get previous instruction X CMP.W #$4ef9,D6 * Is it a JMP instruction? X BNE dos_exec * If not, then call using special code X MOVE.L 2(A0),A0 * Else it's 2.0 or SetFunction() X MOVE.L _DOSBase,A6 * Put DOSBase into A6 as expected X JSR (A0) * Call original function X BRA.S callexit * And exit X Xdos_exec: X MOVE.W (A0),D6 * Get MOVEQ instruction X EXT.W D6 * Convert data to word X EXT.L D6 * and then longword X EXG.L D0,D6 * Swap with library vector offset X MOVE.W 4(A0),D7 * Get offset to DOS routine from LVO X MOVE.L _DOSBase,A6 * Get DOSBase X ADD.W D6,D7 * Calculate offset value X JSR 4(A6,D7.W) * Call DOS function dispatcher X Xcallexit: X MOVEM.L (A7)+,D1-D3/D6/D7/A6 * Restore registers X RTS * And return to C caller X X SECTION SnoopData,DATA X XOpenSave DS.W 3 XLockSave DS.W 3 XLoadSegSave DS.W 3 XExecuteSave DS.W 3 XCurrentDirSave DS.W 3 XDeleteFileSave DS.W 3 X X END END_OF_FILE if test 5668 -ne `wc -c <'snoopglue.s'`; then echo shar: \"'snoopglue.s'\" unpacked with wrong size! fi # end of 'snoopglue.s' fi if test -f 'system.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'system.h'\" else echo shar: Extracting \"'system.h'\" \(271 characters\) sed "s/^X//" >'system.h' <<'END_OF_FILE' X/* Includes for snoopdos.h */ X X#include <exec/types.h> X#include <exec/ports.h> X#include <exec/semaphores.h> X#include <libraries/dos.h> X#include <libraries/dosextens.h> X#include <proto/exec.h> X#include <proto/dos.h> X#include <string.h> X#include <dos.h> X#include <ctype.h> END_OF_FILE if test 271 -ne `wc -c <'system.h'`; then echo shar: \"'system.h'\" unpacked with wrong size! fi # end of 'system.h' fi if test -f 'tiny.a' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'tiny.a'\" else echo shar: Extracting \"'tiny.a'\" \(6132 characters\) sed "s/^X//" >'tiny.a' <<'END_OF_FILE' X*:ts=8 X**************************************************************************** X* * X* TINY.A (C) Copyright Eddy Carroll 1989 * X* ~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * X* * X* Replacement startup code for Lattice C V5.04. Use instead of c.o * X* This has many features stripped out to allow small utilities to have * X* as small a filesize as possible. In particular, don't call any of the * X* stdio functions. * X* * X**************************************************************************** X X INCLUDE "exec/types.i" X INCLUDE "exec/alerts.i" X INCLUDE "exec/nodes.i" X INCLUDE "exec/lists.i" X INCLUDE "exec/ports.i" X INCLUDE "exec/libraries.i" X INCLUDE "exec/tasks.i" X INCLUDE "libraries/dos.i" X INCLUDE "libraries/dosextens.i" X INCLUDE "workbench/startup.i" X INCLUDE "exec/funcdef.i" X INCLUDE "exec/exec_lib.i" X INCLUDE "libraries/dos_lib.i" X XMAXARGS EQU 100 ; Maximum number of command line arguments from CLI XAbsExecBase EQU 4 ; Welcome to the only fixed point in the universe X X* A useful macro to let us call library routines Xcallsys macro X CALLLIB _LVO\1 X endm X X xdef XCEXIT X xdef exit X xref LinkerDB X xref _BSSBAS X xref _BSSLEN X X csect text,0,0,1,2 * xref's after this are 16-bit reloc X xref main * Name of C program to start with. X Xstart: X movem.l d1-d6/a0-a6,-(a7) XREGSIZE EQU (6+7)*4 X lea REGSIZE(a7),A5 * Determine old stack pointer X move.l a0,a2 * Save command pointer X move.l d0,d2 * and command length X lea LinkerDB,a4 * Load base register X X move.l AbsExecBase.W,a6 X move.l a6,SysBase(A4) X move.l a7,_StackPtr(A4) * Save stack ptr X X suba.l a1,a1 X callsys FindTask * Find out our task ID X move.l d0,a3 X X move.l a5,D0 * get top of stack X sub.l 4(a5),D0 * compute bottom X add.l #128,D0 * allow for parms overflow X move.l D0,_base(A4) * save for stack checking X X lea DOSName(A4),A1 X moveq.l #0,D0 X callsys OpenLibrary X move.l D0,DOSBase(A4) X bne getcom XnoDOS: X moveq.l #100,d0 X bra exit2 X X*------ find command name: Xgetcom: X move.l pr_CLI(a3),a0 X add.l a0,a0 X add.l a0,a0 X move.l cli_CommandName(a0),a1 X add.l a1,a1 X add.l a1,a1 X X*------ collect parameters: X move.l d2,d0 * get command line length X moveq.l #0,d1 X move.b (a1)+,d1 X move.l a1,_ProgramName(A4) X add.l d1,d0 * add length of command name X addq.l #1,d0 * allow for space after command X X clr.w -(A7) * set null terminator for command line X addq.l #1,D0 * force to even number of bytes X andi.w #$fffe,D0 * (round up) X sub.l D0,A7 * make room on stack for command line X subq.l #2,D0 X clr.w 0(A7,D0) X X*------ copy command line onto stack X move.l d2,d0 * get command line length X subq.l #1,d0 X add.l d1,d2 X Xcopy_line: X move.b 0(A2,D0.W),0(A7,D2.W) * copy command line to stack X subq.l #1,d2 X dbf d0,copy_line X move.b #' ',0(a7,d2.w) * add space between command and parms X subq.l #1,d2 X Xcopy_cmd: X move.b 0(a1,d2.w),0(a7,d2.w) * copy command name to stack X dbf d2,copy_cmd X move.l a7,a1 * Get pointer to new command line X X sub.l #(MAXARGS*4),a7 * Reserve space for argv[] X move.l a7,a2 * Initialise base into array X move.l a2,a3 * Save base of argv X moveq #0,d2 * Initialise argc X X* X* From here on down, A1 is pointer into command line X* Xbuild_argv: X bsr.s getnext * Read next character from line X bcs.s doquote * If quote, handle X beq.s build_argv * If white space, skip over it X X lea -1(a1),a0 * Get address of this parameter X bsr.s bumpargv * Store it to argv[] array Xbuild_2: X bsr.s getnext * Get next character X bne.s build_2 * If not white space, keep looking X clr.b -1(a1) * Zero-terminate current argument X bra.s build_argv * And go back to get next argument X Xdoquote: X move.l a1,a0 * Get pointer to this argument X bsr.s bumpargv * Output it to argv[] Xquote_2: X bsr.s getnext * Get next character X bcc.s quote_2 * If not quote, keep looking X clr.b -1(a1) * Zero-terminate current argument Xquote_3: X bsr.s getnext * Get next character X bne.s quote_3 * Skip until space reached X beq.s build_argv * Go back and read next argument X Xbumpargv: X move.l a0,(a2)+ * Output ptr to current argument X addq #1,d2 * Increment argc X cmpi #MAXARGS,d2 * Used up all our arguments yet? X bls.s qrts * If not, then return X moveq #110,d0 * Else set return code X bra.s exit2 * And exit X X* X* Reads next character from command line. If zero, never returns, but X* drops into call to main. Else, returns, with C=1 if character is quote, X* Z=1 if character is white space. X* Xgetnext: X move.b (a1)+,d0 * Get character from command line X beq.s get_2 * Exit if end of line X cmp.b #34,d0 * Check if quote X beq.s isquote * X cmp.b #32,d0 * Check if space X beq.s isspace * X cmp.b #9,d0 * Or tab X beq.s isspace * X cmp.b #10,d0 * Or end of line Xisspace: X andi #$1E,ccr * Clear carry flag, retaining Z Xqrts rts X Xisquote: X ori #1,ccr * Set carry flag X andi #$FB,ccr * Clear zero flag X rts * And return X Xget_2: X move.l a3,-(a7) * Push argv onto stack X move.l d2,-(a7) * Push argc onto stack X X lea _BSSBAS,a3 * get base of BSS X moveq #0,d1 X move.l #_BSSLEN,d0 * get length of BSS in longwords X bra.s clr_lp * and clear for length given Xclr_bss move.l d1,(a3)+ Xclr_lp dbf d0,clr_bss X Xdomain: X jsr main(PC) * Call main(argc,argv) X moveq.l #0,d0 * Set successful status X bra.s exit2 X Xexit: X_exit: XXCEXIT: X move.l 4(SP),d0 * Extract return code Xexit2: X move.l d0,-(a7) X move.l AbsExecBase.W,a6 X move.l DOSBase(A4),a1 X callsys CloseLibrary * Close Dos library X X*------ this rts sends us back to DOS: XexitToDOS: X MOVE.L (A7)+,D0 X movea.l _StackPtr(a4),SP * Restore stack ptr X movem.l (a7)+,d1-d6/a0-a6 X rts X X*----------------------------------------------------------------------- X* Global definitions X* X csect __MERGED,1,,2,2 X X xdef NULL,SysBase,LoadAddress,DOSBase X xdef _oserr,_OSERR,_ONBREAK X xdef _ProgramName,_StackPtr,_base X XNULL dc.l 0 X_base dc.l 0 X_oserr equ * X_OSERR dc.l 0 X_ONBREAK dc.l 0 XSysBase dc.l 0 XLoadAddress dc.l 0 X_StackPtr dc.l 0 XDOSBase dc.l 0 X_ProgramName dc.l 0 XDOSName dc.b 'dos.library',0 X X END END_OF_FILE if test 6132 -ne `wc -c <'tiny.a'`; then echo shar: \"'tiny.a'\" unpacked with wrong size! fi # end of 'tiny.a' fi echo shar: End of archive 1 \(of 2\). cp /dev/null ark1isdone MISSING="" for I in 1 2 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked both archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0 -- Mail submissions (sources or binaries) to <amiga@uunet.uu.net>. Mail comments to the moderator at <amiga-request@uunet.uu.net>. Post requests for sources, and general discussion to comp.sys.amiga.