braner@batcomputer.tn.cornell.edu (braner) (11/08/86)
[] I'd like to share with y'all some thoughts and experiences concerning the topic of writing memory-resident utilities for the ST. By a "memory-resident utility" I mean a program that is installed in RAM when you "run" (double-click) it, and is later called upon to do something under certain conditions. "Desk accessories" fit that definition, but I am NOT referring to those here, but rather to programs that are intended to be invisible, such as printer drivers, my recent "killer.prg", keyboard translation tables, etc. Such utilities are invoked via an altered exception vector, system variable, and the like. Since I wrote a few of these recently, I got to think about some protocol for their installation. Of course, there might be an official protocol already in existence, but I have not heard of any. Here is my suggested protocol: The part of the program that is to be resident is compiled/assembled as near the beginning of the program as possible, to save memory. For most compilers/assemblers this is done simply by putting that part of the code at the beginning of the source file. When "run", the program installs the needed vectors, then does a "terminate and stay resident" GEMDOS call (Ptermres()) to exit, asking GEMDOS to save only the parts that are really necessary (i.e. the installation part is discarded). Let's define the "utility address" (UA) to mean the address that is pointed to by the vector/variable/etc - usually the address called to execute the utility. This address is easy to find later by examining the vector. I use the 8 bytes PRECEDING the UA to help manage multiple utilities: During installation, the program saves the former contents of the vector (i.e. the former UA) in the 4 bytes preceding the (new) UA. In the 4 bytes before that (i.e. at -8(UA) in AL jargon) a magic number resides, a number that lets you identify the utility. (I use a mnemonic string of 4 ASCII codes.) The magic number and the old vector are useful for many purposes: The installation procedure may check the vector before altering it, and warn the user that this (or another) utility has already been installed. Programs that want to bypass a utility can do so by looking- up the former vector and using it instead. It makes it easy to write programs that deactivate utilities. Also, in theory one could write a program to unload such utilities, freeing up the RAM. Now some important classified information: If you want to use OS calls (traps) inside an interrupt handler (something that is necessary but officially verboten), make sure the interrupted routine was not in supervisor mode. This will ensure that, in particular, you are not calling a TRAP within a TRAP. (Thanks to whoever posted "WATCHER" here recently - that is where I took this idea from.) The way to check that is to examine the CPU status which was saved on the stack as part of the exception processing. In AL simply do: UA: BTST #5,(A7) * zero if user mode BNE ... * do NOT call any traps ... * action with traps here That works when the code is at the same "stack level" as the RTE, i.e. may safely end with an RTE. That is the case when it is called directly by the exception vector or is JMPed to. But look out for the cases where UA is called as a subroutine, so more stuff has been put on the stack since the exception happened. For example: WARNING: The following info is unofficial and will probably change in future versions of the TOS ROMs. Do NOT use this info in a program you expect others to use after such revisions. In the current ROM TOS version of the Alt-Help screen dump, the UA stored at $502 is called to actually do the screen dump. You may install your own UA there. But the exception handler saves all registers except A7 (15 registers) on the stack, then calls a subroutine which in turn calls ($502) as a subroutine. What it all adds up to is that the needed check is now: BTST #5,68(A7) (Note that you do NOT need to save any registers you use inside your screen dump code.) Any comments/suggestions would be appreciated. - Moshe Braner
dyer@atari.UUcp (Landon Dyer) (11/12/86)
> In the current ROM TOS version of the Alt-Help screen dump, > the UA stored at $502 is called to actually do the screen dump. You > may install your own UA there. But the exception handler saves > all registers except A7 (15 registers) on the stack, then calls a > subroutine which in turn calls ($502) as a subroutine. What it all > adds up to is that the needed check is now: > > BTST #5,68(A7) > > Any comments/suggestions would be appreciated. Yes. Don't do it. -- -Landon Dyer, Atari Corp. {sun,lll-lcc,imagen}!atari!dyer /-----------------------------------------------\ | The views represented here do not necessarily | "If Business is War, then | reflect those of Atari Corp., or even my own. | I'm a Prisoner of Business!" \-----------------------------------------------/