[comp.os.msdos.programmer] Calling MSDOS services inside interupt Service Routines?

heintze@fmcsse.enet.dec.com (Siegfried Heintze) (11/27/90)

There are some things I would like to perform asynchronously.  For example, it
would
be nice to set a timer whereby a certain routine would execute at a specified
time.  It would
also be nice to have ansynchronous processing on behalf of the mouse (via INT
0x33 FUNC 0x0c).

I have been successful in getting quite a few things to work (such as vprintf
and INT 0x10 to write text to the VGA) from within the routine specified
by INT 0x33 FUNC 0x0c.  Using ZORTECH C++  v2.0 I could call exit (unfortunatly,
there were a lot
of other problems).  However, using TURBO C++ V2.0 I cannot call exit but I can
do the other
things like access the VGA display and make beeps on the speaker.

It is interesting that this worked in ZORTECH C++ and not TURBO C++.  I don't
know why.

After messing with the situation for some time (and experiment with calling INT
0x21 FUNC 0x4c
instead of _exit and using setjmp) I think the problem has to do with being
(indirectly) inside an
interrupt. I would suspect you would have the same kind of problem if you had a
timer interupt and tried to call exit from that.  (Has anybody tired this?) It
would not do any good to perform a setjmp to the main routine because you would
still be in the interupt context.

So I think the solution is to fiddle with the stack.  I think what the interrupt
routine should do
is adjust the stack so that when the IRET instruction executes,  control is
transfered to the
desired code that calls the MSDOS INTs.  When this finishes, it does a RET and
the original
code that was executing can continue.

Now I realize that application code interupted could already be inside an INT
0x21 which should
not be interrupted.  So you would want to check for this and adjust the
application stack, not
the internal stack that MSDOS uses.

So the obvious question is:  Where does MSDOS keep the stack segment and stack
pointer
for the application program when you do an INT 0x21?

This would be nice to know, but we may not be able to find out.  (Perhaps one of
those high priced dissassemblers would help - has anyone tried them?)  However,
all the INTs vector
thru the table in low memory so we could substitue our own dummy routine for INT
21 that
calls the real INT 21.  I think you do this with a SETVECT or something like
that.   Our dummy routine can then save the SS and the SP in a known location. 
Any ISRs that execute this can
then push the desired routines on the application stack and imediatly IRET so
that the 
stuff won't execute until the real INT 21 finishes (if one was in progress).

QUESTION:  Has anyone done this?  Can you send or reference me to an example?

I have seen examples of replacing the CLOCK isr  with a dummy ISR that will
accomodate
the fact that you have changed the rate at which the CLOCK interrupts so the
clock in your AT will still be in synch with the clock on your wall.  But they
did not fiddle with the stack.  (These examples have been graciously provided by
VNEWS readers on behalf of previous and related
queries).

                                     Sieg