Path: utzoo!attcan!uunet!lll-winken!elroy.jpl.nasa.gov!abcfd20.larc.nasa.gov!amiga-request From: amiga-request@abcfd20.larc.nasa.gov (Amiga Sources/Binaries Moderator) Newsgroups: comp.sources.amiga Subject: v90i282: SnoopDos 1.00 - Monitors calls to AmigaDOS functions, Part01/02 Message-ID: Date: 14 Oct 90 19:07:04 GMT Reply-To: Eddy Carroll Lines: 1332 Approved: tadguy@uunet.UU.NET (Tad Guy) X-Mail-Submissions-To: amiga@uunet.uu.net X-Post-Discussions-To: comp.sys.amiga Submitted-by: Eddy Carroll 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 '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: X in the SnoopDos window, then a program is trying to access an environment X variable called . 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```@`%."4G__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``+P2!#87)R;VQL+"!397!T(#$Y.3`N($9R965L>2!D:7-T2!#87)R;VQL+"!397!T(#$Y.3`N($9R965L>2!D:7-TO XM7!E($-44DPM12]#5%),+40@=&\@96YA8FQE+V1I7!E($-44DPM1"!T;R!D:7-A8FQE& XM(&ET(&%G86EN+@T*#0HE2!S;R!))VQL(&AA=F4@=&\@=V%I="!U;G1I;"!T:&5Y('%U:70NR XM#0H``%1H:7,@=VEN9&]W('=I;&P@8VQO2!T:&]U9V@@=&\@\ XM7!E(%-N;V]P9&]S("UH(&9O#$@;W(@:G5S="`M>"!T;PIE;F%B;&4@* XM86X@;W!T:6]N+"`M6"!O#`@=&\@9&ES86)L92!T:&%T(&]P=&EO;BX@> XM0W5R XM2!E;F%B;&4O9&ES86)L92!M) XM;VYI=&]R:6YG("`@("`@("`@("`@)7,*`"`@("`M;R`@36]N:71OB4@: XM3W5T<'5T('1O(&9I;&4@)2`H92YG+B`M>D-/3CHP+S`O-C0P+S$P,"]3;F]O0 XM<$1OE-%4CHI"@H``%1H97)E(&ES(&YO(&)A8VMG``$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.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.O.D*T#_\$ZZ%FY03RE`!:IFU XM&$AZ\YXO+`6V80#\GDAX__]A`/%B8``)#BEL!:H%IG``(&P%IA`H``]R`20!: XMX:(I0@E:``$3J[^MG(!)`'AHBE""4)P_TZN_K9R`20!X:(I0@E&&B*4()2G#_3J[^MG(!)`'AHBE""4YP_TZN_K9R`20!X:(I0@E2W XMO,.+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*A6P$>!"\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`(!+846"0>P`/"MP*`#_9 XMV&`L#(````/L9A0@+`#P(@#E@4'L`$0KO#V+RP%LF$`]]Y/[P`O`\+RP%LF$`]R1/[P`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!`/_(N]P+RP%LF$`]BY/[P`49 XM?`%@``#22JP`Y&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``$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!/``$3J[]S'(*+&P`'$ZN_SI(>/__80#HX XM4DSM!.S_L$Y=3G5.5?_P2.@%@``"&?`)@``"`*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[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`^@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_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_``)80#MTD_O``Q![`5X+'@`!$ZN_<8B"R0'D XM)@9.N@-L3-\8S$YU2.``$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_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.$[Y```!,$CG(#`F;P`0)$M*" XM$F``$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`<``$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!`3W_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.```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;&EB0````&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 X#include X#include X#include X#include X#include X#include X#include X#include X#include 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 . Mail comments to the moderator at . Post requests for sources, and general discussion to comp.sys.amiga.