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.