How would I do this?
How would I do this?
what do you mean? do you mean like calling the interrupts yourself rather than using int86()?
If that is what u mean....use the asm keyword. ex:
mov ah, 00 //this code will wait for a keypress
#define INTR 0x10
void far (*ISR)()=0;
unsigned int ISROffset;
unsigned int ISRSegment;
void far *GetINTRPointer(void);
(void far *)ISR=GetINTRPointer();
//Test to see if we are pointing at the handler
//Call the function just like any other C function
printf("In mode 13h\n");
void far *GetINTRPointer(void)
return (void far *)MK_FP(ISRSegment,ISROffset);
This will work, but will cause major problems. We are hooking into the interrupt chain w/o telling DOS. We have underhandedly hooked into the chain but nobody else will know because we did not notify DOS that we did. DOS does a couple of things when you hook interrupts that allows everyone to get along in the system. W/o using DOS, you are asking for chaos. Turbo C++ 1.01 crashed back to Windows doing this. In the early days your program was not the only one using DOS so you had to follow the rules. Now, since most of those drivers aren't there anymore and DOS is basically vacant - you might get away with this for a little bit longer than before. But, it will come crashing down eventually.
The problem here is that the interrupt 10 handler assumes it is being invoked via an interrupt. So, instead of doing a RET (return from procedure) it does an IRET (for 16-bit - return from interrupt). But, we haven't invoked the handler by an INT so the IRET will most likely crash the system. We have directly called the handler via a far call, but it has no way of knowing that. The handler and the CPU both are expecting an IRET - after an INT you must do an IRET so as not to cause instability in the system. Actually there is a way it could see the far call, but I guarantee that is not in the handler since it is not good practice to call ISRs, hook INTs, and unhook INTs w/o some intervention from DOS. He should know about everything that's going on - after all he is trying to run the system and keep it stable. Also it is a good chance that the int 10 handler is throwing an EOI to the PIC so the video card stops pulling the INT. If there has been no INT, then this will often times crash the system as well since the PIC never knew about the interrupt so all of it's lines are low instead of high. But, the handler is saying to the PIC - ok, the int is done so you can go low on your lines and stop the INT cuz we are done with it. Shortly thereafter it will issue an IRET to leave the ISR.
I did get it to work fine in Borland C++, but a lot of it had to be in asm so I could save the system state and attempt to restore it after the call. This method is slower than using an INT, although I still do not know why. Even with all of my precautions the system was still very unstable.
The pseduocode for an IRET and RET are different. Several things happen in an IRET that do not happen in a RET and vice versa.
I cannot post the pseudo here as it's very long.
Intel does say that an IRET will reverse both a CALL and an INT, but there's gotta be a reason for them putting two distinct opcodes for IRET and RET. Either way, the PIC will still be confused even if the CPU isn't.