Function 31h Terminate Process and Stay Resident, KEEP, or TSR
entry AH 31h
AL exit code
DX program memory requirement in 16 byte paragraphs
return AX return code (retrieveable by function 4Dh Int\21f\4D)
note 1) Files opened by the application are not closed when this call is made
2) Memory can be used more efficiently if the block containing the copy of
the DOS environment is deallocated before terminating. This can be done
by loading ES with the segment contained in 2Ch of the PSP and issuing
function call Int\21f\49 (Free Allocated Memory).
3) Unlike Int/27, more than 64k may be made resident with this call
o Ref: Dr. Dobb's Journal, April 1991 Pg 117
The TSR is a kludge. It exists because the designers of DOS failed to
foresee the need for simple task-switching between concurrently resident
programs. The TSR was made possible because those same designers needed to tack
a print spooler to the single-user, single-tasking DOS. Their technique is both
fragile and ugly.
DOS is not re-entrant. If you interrupt a program while it is in the middle
of a DOS call and run another program that makes DOS calls, DOS will crash and
burn. A TSR must set an indicator that says it wants to pop up and then wait
until DOS says it is OK. DOS indicates to the system when it can be interuppted
by maintaining a flag called INDOS which is made available through
Int\21f\34. If InDos is set, DOS is already busy with another call.
In order to gain CPU service during a time that InDos is not set, the TSR
must hook into the timer interrupt Int\1C which then allows it to become
active 18.2 each second.
When the TSRs keyboard interrupt service routine sees that you have pressed
the hot key, it sets a flag. When the TSR timer interrupt service routine
executes it looks at the hot key flag. If the hot key flag is set and the InDOS
flag is not, the TSR is activated. Many TSRs also use the timer interrupt to
guard against other, ill-behaved, TSRs that may hook the keyboard interrupt
without chaining to the previous owner to pass along unused keystrokes. This is
accomplished by looking at the address stored at the Int 09h space (0000:0024)
and compairing it to the entry address of the keyboard interrupt service
routine. If it has been changed, the program may decide to change it back or
error out.
Now, think about this, how does COMMAND.COM get input from the user at the
command line? It makes a DOS call. While DOS is waiting for keystrokes InDos is
set. DOS does not want to be interrupted..... TSRs can't run? This fine example
of poor design is countered by (was there any doubt?) yet another kludge. While
DOS is looping, waiting for a keystroke, it periodically cleans itself up well
enough to handle calls above Int\21f\0C, and then calls Int\28. This
provides a "back door" for TSRs to gain CPU cycles while DOS waits for user
input. When the TSRs interrupt 28 service routine is activated, it looks at the
hot key flag and, if it is set, activates the TSR.
In Summary: A TSR attaches the keyboard interrupt to watch for the hot key,
Int\28 to watch for spare CPU time, and usually the timer interrupt to watch
everything.
The Pop UP
Before popping up, the TSR must switch context from the interrupted program
to itself. This includes:
o Changing from the interrupted program's stack to that of the TSR,
o Tricking DOS into thinking the TSR is its single task by switching its
pointer to the running program's Program Segment Prefix (PSP). Note that
the calls for getting and setting the PSP in DOS versions prior to 3.0 do
not work properly. Int\21f\50 -wrong stack Later DOS versions work just
fine Int\21f\62
o Changing the Disk Transfer Address (DTA) from that of the interrupted
program to that of the TSR's. Int\21f\2f Int\21f\1A
o Temporarily disabling DOS's critical error handler. Int\24
o Capture Ctrl-Break and Ctrl-C keypresses. Int\23 Int\09 -Ctrl-Break
Int\21f\08 -ctrl-C
o If the program is going to use the mouse, save the current mouse context.
Int\33 -Save Driver State
o Depending on what the program is going to do, the video mode will have to
be determined, saved, reset, and restored on exit. Be aware that if the
interrupted program has set the video mode by directly writing to the CRT
controllers registers, there may be no way to determine what the mode is.
(this makes it rather difficult to save the mode, or to restore it
later!) Int\10f\00
o REF PC Magazine Vol 10.7 Pg 342
When the TSR loader program is executed, it must make sure that the resident
portion of its code is not already loaded. Otherwise, multiple copies of the
same program will be competing for the hot key, memory, and cycles. To
determine if a TSR program has already made its self self resident, include a
check message consisting of any unique ASCII text in the resident portion of
the code. Then sequentially check each segment of memory to see if this check
message is located where it should be. However, before starting to search
through the segments, change the check message slightly so that a match will
not be found in a disk cache. Start the search at segment A000h and wrap around
to low memory. In this way the TSR code will be caught in the event that it has
been loaded into high memory.
o 28APR91@20:24 Why not just compare the copy of the resident code that was
loaded with the loader to each segment in memory?
o 28APR91@20:38 For that matter, why not just call int 28 with a special code
which will be ignored by the background tasks but recongized and responded to
with the resident segment address by the resident code?
file: /Techref/int/21f/31.htm, 6KB, , updated: 1999/4/21 08:55, local time: 2024/9/6 16:29,
|
| ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://linistepper.com/Techref/int/21f/31.htm"> int 21f 31</A> |
Did you find what you needed?
|