Notes on building a DJGPP TSR

The DPMI provider will be forced to stay resident after a TSR exits.  Since
DPMI providers may use 200Kb of DOS memory, you need a really big image for
this to make sense.

You shouldn't run a TSR image under a debugger unless you are willing to 
kill the window (or reboot the machine) to clean up the DPMI mess.  Do
not attempt to TSR a child (nested) program.

There is no way to remove a TSR under DPMI once installed.  The DPMI
specification says you cannot exit from an interrupt or real mode callback,
and that's the only way to get back into your code once you TSR.

This example was tested under DOS, Windows 95, Windows 98, Windows 2000
and worked in all cases.  Under Windows 2000 you may have to force the
video mode so you can see the frame buffer (and the color change).
The TSR is specific to a single window, and timer interrupts may not be
sent to the TSR if the window isn't active.

You can control the amount of DOS memory kept by the image (minimum of the
PSP, but typically would also include the transfer buffer).  You cannot
control the protected mode DPMI memory - all will be saved and be part
of the TSR.  If you want to decrease the protected mode memory footprint, 
set _stklen (in the image and in the stub) and be careful what you malloc.

Any interrupt routines or real mode callbacks need to have all memory 
locked.  Since a TSR is useless without those procedures, it probably makes
sense to lock all memory using:
 int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY;

You should be able to hook a protected mode interrupt and call code in
your TSR from a DPMI image.

You should make sure the TSR has not hooked exception handling (you can't
let it exit).  Since DJGPP exception handling hooks the keyboard interrupt 
for CTRL-C, CTRL-\ and CTRL-Break handling - you should toggle exceptions
before you install your own keyboard handler if desired.

The example shows a way to eliminate lots of code which exists in a 
standard DJGPP image which you don't typically need in a TSR type 
program.  This decreases the footprint but can cause build issues as the
DJGPP version changes.  See the makefile for tinytsr.exe if interested.

If you write your own TSR, the only pieces you need are:
 1) toggle exceptions off
 2) hook your interrupts (lock the memory they touch)
 3) call keep()

Have fun.

sandmann@clio.rice.edu
