Date: Sun, 14 Mar 93 11:28:14 -0600 From: rcharif AT math DOT utexas DOT edu Posted-Date: Sun, 14 Mar 93 11:28:14 -0600 To: karna AT pobox DOT upenn DOT edu Cc: djgpp AT sun DOT soe DOT clarkson DOT edu Subject: Interrupt Handlers (again) and GO32 Reply-To: rcharif AT math DOT utexas DOT edu My impression is that, if I want to write an interrupt handler routine for use in a DJGPP program, one method is to write it as a real-mode handler (using, say, Borland C++) and add it to GO32. Can anyone give me some pointers as to . . . well . . . how? I know how to write an interrupt handler for real mode, but I'm not sure about where to add it to GO32's source, what to watch for, and all that. Hook it in the file exphdlr.c. There is a function with a switch ... case construct that gets called when an interrupt occurs in protected mode. You will need to modify it so that go32 doesn't abort when it receives your interrupt. The easiest thing would be to install your handler as a real mode interrupt handler so that it gets called when an interrupt occurs in real mode and put an int86x(...) call in exphdlr.c so that it gets called when switched from protected mode. This next question goes off the deep end, I know . . . Is it possible using the above method (or, heck, any method) for my interrupt handler to call a protected mode routine written using DJGPP (or even GAS)? This is more difficult. You need to add a callback system to go32, modify the protected mode interrupt table (IDT). The idea is as follows : 1- Interrupt received while in protected mode : Just modify the protected mode (PM) IDT so that your PM handler gets called 2- Interrupt received while in real mode (2 ways to do it) : A- Your handler is not critical and can wait for the system call to finish executing : - Use the function push32 to push the current EIP, CS, EFLAGS on the PM stack (Look at file control.c). - set EIP = your PM handler - Resume execution When go32 will switch back to PM, it will start executing your handler. When it encounters an IRET instruction it will switch back where it was before (Look at the 386 reference in order to know in what order to push the arguments on the stack). B- Your handler is critical and needs to be called immediately : - Create a function like the one in mswitch.asm, but instead of jumping to a_tss after you switch to PM, issue an INT call. switch to PM call PM handler, using INT # switch back to real mode return and resume execution You need to be careful in your PM handler not to issue any system call. Go32 is not reentrant, and system calls that communicate data between PM and RM use a unique buffer. You either need to save it each time or make sure you don't use any call that modifies the data in that buffer. Failing to do so will make you end up with trah in your buffer or fail your system call when you resume execution in RM. You will need to create tables to keep track of what to call, when it is running so you don't call your handler twice,... This is a simplified version of what DPMI does. A complete implementation might allocate a fixed number of descriptors (callbacks) in the GDT (16 for the DPMI I think). These callback switch you between modes when you receive interrupts. Perhaps it will be much easier to write interrupt handlers as standalone resident programs the way the async library is written. At least it will continue to work and might keep a log of interrupts you receive when you shell out of go32 to execute a dos program. In that way you will not loose data or interrupts, you will just need to process the log. Otherwise expect huge difficulties while debugging (ie nightmares), and the gratitude of many persons if manage to make it work. You might also want to read the Intel 386 programmer's reference manual before starting. Good luck, Regards, Rami