From chrisf@vonl.comWed Mar 27 15:50:12 1996
Date: Sun, 24 Mar 1996 15:56:16 -0600
From: Chris Friedersdorf <chrisf@vonl.com>
To: Jannes Faber <J.A.Faber@fys.ruu.nl>
Subject: TSR demonstrating EXEC function

The program was created for Microsoft's MASM 4.0.  This older version
does not support modern directives like .MODEL, and so to obtain a 
.COM version of the executable, I had to first assemble, then link,
then convert the .EXE file using EXE2BIN:

   1.  MASM SAVSCRN  (no special command line switches required)
   2.  LINK SAVSCRN  (no special command line switches, libraries,
                      or external subprograms required)
   3.  EXE2BIN SAVSCRN.EXE SAVSCRN.COM
   4.  DEL SAVSCRN.EXE  (must not try to execute the .EXE version)

You could probably easily convert the code to run as a .EXE file, but
I have not done this.

Usage of the program is pretty simple.  From the DOS prompt, simply
type  SAVSCRN /[PATH]:FILENAME.EXT.  For example, if the file
MYPROG.EXE resides in the C:\UTIL directory, simply type:

          SAVSCRN /C:\UTIL\MYPROG.EXE

This will install a resident portion of the program SAVSCRN.COM,
which hooks several interrupts.  The program will monitor the system
timer and keyboard, looking for the situation where a certain amount
of time has elapsed without a keypress (this is defined by MAXTICK,
which is set to 1092 in the version I am sending, ie. about 60
seconds at 18.2 ticks/second).  When this situation occurs, the
resident TSR will try to start the program MYPROG.EXE, which will
execute until its normal termination returns control to the system,
at which time the TSR returns control to the interrupted application.

Since some DOS programs are bad about memory management, ie. they
consume all available memory until they terminate, I have reserved
a block of 2000H paragraphs (about 130 k bytes) inside the TSR, so
that there will always be room for a program that needs < 130 k 
bytes to start.  This is not very efficient, and could be made a
lot more sophisticated if I can get the basic concept to work
correctly (must take things one step at a time).

The general structure of the program puts the resident part first
and the installation portion next, so that the installation part
can be discarded after installation is complete (installation 
part begins at the BEGIN: label).  Many of the subroutines in the
installation part are just standard routines to parse the command
line, handle errors, print messages on the screen, sound a beep,
etc.  These seem to work OK and should not be critical to the
execution phase of the program.  In the resident part, the main
action occurs in the Interrupt Handlers for Interrupts 08h, 09h,
and 28h.  These handlers combine to determine when and how to
start the program.  The actual launching of the "child" process
is accomplished by subroutine EXEPRG.  The problems I am having
are likely to lie in these interrupt handlers, EXEPRG, or 
perhaps the screen saving and restoring subroutines.

When the TSR determines that it is safe to launch the "child"
process, EXEPRG is called.  The old screen is saved in a buffer, as
are the cursor location and other important screen information.
When the program ends and returns control to EXEPRG, the original
screen is restored, and control is returned (hopefully) to the
program which was interrupted.  The screen saving and storing
routines currently work only with text mode screens, so currently
only interrupted programs using text screens are supported.

As I mentioned above, the installation portion reserved 2000H
paragraphs of memory for the child process.  When subroutine EXEPRG
is executing, it first releases that reserved memory block, then
starts the program.  After the program terminates and returns 
control to EXEPRG, the memory block is reserved again so that this
process may be repeated later as needed.

The big problem with SAVSCRN is that IT CRASHES A LOT!!!  It seems
to crash everytime that it starts from within DOS (ie. the keyboard
is left inactive with the DOS prompt displayed).  From within some
other programs, it seems to work fine, while others cause it to
crash.  If you can figure any of this out, please let me know what
you find.  If some of the code is hard to understand, just ask!!

Thanks and good luck.

Chris Friedersdorf
chrisf@vonl.com
