Path: utzoo!utgpu!news-server.csri.toronto.edu!bonnie.concordia.ca!uunet!comp.vuw.ac.nz!actrix!Roger.Sheppard From: Roger.Sheppard@actrix.gen.nz (Roger Sheppard) Newsgroups: comp.sys.atari.st.tech Subject: Re: How to use the VDI from the Autofolder Message-ID: <1991May25.152208.2925@actrix.gen.nz> Date: 25 May 91 15:22:08 GMT References: <1991May24.184249.21414@imada.ou.dk> Organization: Actrix Networks Lines: 475 This came from a File that I found some time back on Genie, it could be of help to otheres, with the Trap #2 problems. ------------ Category 2, Topic 19 Message 108 Sun Nov 13, 1988 C.F.JOHNSON at 16:19 PST Steve, Stealing trap #2 is not quite as easy as Dan made it seem; you can use his method (except for the "magic cookie"...more on that later) with all the other trap vectors (1, 13, and 14), but intercepting trap #2 is uniquely difficult because the operating system keeps replacing its own address in the vector! TOS seems to reset $88 (trap #2) every time you runa .TOS or .TTP program, or show a file from the desktop. (And maybe at other times too...) After lots of thrashing around for methods to solve this thorny problem, Bob Breum (Easel ST), Wayne Buckholdt (Turbo ST), John Eidsvoog (fellow CodeHead), and I came up with a method of intercepting trap #2 "safely"...in other words, so that the system can't de-install you while you aren't looking, and so that other programs which use the same method can coexist peacefully. The method is not exactly obvious....and that's why there are a lot of programs (e.g. FSEL60) which don't get along with other programs that need to steal trap #2. Some programmers, in order to keep their software working, resorted to desperate measures...like checking the trap #2 vector every vertical blank interrupt and just replacing their address if it ever changed. This method does work, as long as your program is the only one that steals trap #2 --- which is a ridiculous assumption to make, with more trap #2 thieving programs appearing every day. We decided (all of the folks listed above) to publicize thisinformation as widely as possible, in the hope that everybody's "GEM fixer-upper" programs will be able to get along. The following section of assembly code illustrates the process, with lots of comments: ********************************** * * * Intercept the trap #2 vector * * * * Code by Charles F. Johnson * * * ********************************** * Last revision: 06/26/88 12:13:32 * In order to steal trap #2 permanently, it's necessary to watch for a * certain BIOS call from the operating system - a setexec() call for the * critical error vector. TOS issues this call after running a .TOS/.TTP * program, and immediately after changing the trap #2 vector at $88. So * when this call comes through, you know it's time to re-steal trap #2. * Good luck, Jim. We're all counting on you. .text * ------------------------ * Program initialization * ------------------------ move.l #prog_end,d6 ; Get address of end of this program sub.l 4(sp),d6 ; Subtract start of basepage - save in d6 move.l #not_auto,addrin ; Try to call form_alert move #1,intin move.l #f_alrt,aespb move.l #aespb,d1 move #$C8,d0 trap #2 tst intout ; If intout is zero, we're in \AUTO beq.s .start1 cmp #1,intout ; Did we click on "Install"? beq.s .0 ; Yes, continue clr -(sp) ; Pterm0 trap #1 ; outta here .0: pea prg_start(pc) ; Steal trap 2 right away if run from desktop move #38,-(sp) ; Supexec trap #14 addq #6,sp move #1,prgflg ; Set flag indicating desktop load bra.s .start2 .start1: pea title ; Print title message move #9,-(sp) trap #1 addq #6,sp .start2: pea set_bios(pc) ; Appropriate the Trap 13 vector move #38,-(sp) trap #14 addq.l #6,sp clr.w -(sp) ; Terminate and Stay Resident move.l d6,-(sp) ; Number of bytes to keep move #$31,-(sp) ; That's all folks! trap #1 ; We are now happily resident in RAM * ------------------------------- * Desktop vector initialization * ------------------------------- prg_start: move.l $88,t2_vec ; Set my fall through addresses move.l $88,aesvec move.l #my_trap2,$88 ; Steal trap #2 (GEM) rts * ----------------------- * Steal the BIOS vector * ----------------------- set_bios: move.l $B4,t13adr ; Set BIOS fall through address move.l #my_t13,$B4 ; Steal trap #13 (BIOS) rts * ------------------------ * Trap #13 wedge routine * ------------------------ my_t13: btst #5,(sp) ; Super or user mode? beq.s t13_ex ; If user mode, let's forget the whole thing cmp.l #$050101,6(sp) ; Setexec call for critical error vector? bne.s t13_ex ; Nope, let the call fall through tst prgflg ; Run from the desktop? Vectors set already? beq.s first_time ; No, skip ahead do_crit: move.l #my_trap2,$88 ; Pilfer trap #2 move.l $404,d0 ; Get current critical error vector move.l 10(sp),d1 ; Get address we're setting it to bmi.s t13_x1 ; If minus, return old vector in d0 move.l d1,$404 ; Set that vector t13_x1: rte ; Not a through street first_time: tst.l 10(sp) ; Reading the vector? bmi.s t13_ex ; Yes, let the system take care of it cmp.l #$FC0000,10(sp) ; Is this address below the ROMs? blo.s t13_ex ; Yes, bail out move #1,prgflg ; Set the 'first-time'/'desktop' flag move.l 2(sp),retsav ; Save return address move.l #t13_2,2(sp) ; Replace it with my own t13_ex: jmp $DEADBEEF ; Go to the Bios t13adr = t13_ex+2 t13_2: bsr prg_start ; Grab the trap #2 vector move.l retsav,-(sp) ; And return to the caller rts retsav: dc.l 0 not_auto: dc.b '[3][ Test alert box | ][ Install |Cancel]',0 --------------------------------------------------------------------- (Whew! This is turning out to be a lengthy message!) Anyway, one really important point to remember when you steal _any_ of the ST's trap vectors -- once you steal it, NEVER reset it to what it was when you grabbed it. To disable yourself, use a flag and jump past your code, or some other method...if you actually replace the vector itself, you'll be cutting out any other programs that have installed themselves in the chain. Stealing an ST vector is like grabbing a tiger by the tail - once you've got it, you'd better not let go! (Note that the operating system itself is guilty of this crime.BIG sigh.) Now on to the "magic cookie" method Dan proposed...in a word, DON'T! We just went through a real headache trying to make MultiDesk compatible with Atari's Diablo emulator for their laser printer. The reason? The Diablo program used a "magic cookie." The Diablo emulator comes in two parts, a program that runs in the AUTO folder and an accessory that is used to set up the emulator. The accessory looks for a certain magic number right before thetrap #13 vector, in order to tell whether the AUTO program is installed or not. Works fine, again, as long as no one else steals the trap #13 vector between the accessory and the AUTO program. The trouble is, a LOT of programs and accessories (including MultiDesk) steal trap #13. Result? A big mess. A better method than the magic hockey puck is to issue an OS call with an undefined function number, like BIOS #73, or AES #1200, and have your program return a pre-defined value somehow, indicating that it's installed. For example, this is the method that G+PLUS uses to let other programs know that it's installed. The program does a trap #2 call with $472B in register D1. If G+PLUS is present, it returns from the call after setting D1 to the address of its "backdoor" structure....so if D1 is unchanged after the trap, G+PLUS isn't there. Well, that's enough technical talk for one message. Feel free to ask if you have any questions about the source code I included above. - Charles ------------ Well I do hope that line noise did not corrupt this data, have only a dumb upload option.. -- Roger W. Sheppard 85 Donovan Rd, Kapiti New Zealand...