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