[alt.msdos.programmer] Need info on 286/386 exceptions and int handling under DOS

stever@Octopus.COM (Steve Resnick ) (10/11/90)

In article <1990Oct10.134728.20403@hellgate.utah.edu> msmith%peruvian.utah.edu@cs.utah.edu (Matthew Smith) writes:
>In article <1990Oct10.163006.8081@Octopus.COM> stever@octopus.COM (Steve Resnick ) writes:
>>Heres's a good question for you PC guru types ...
>>
>>On 80286 and 80386 processors, int 12 is designated as a stack fault exception.
>>So far so good. Also on PC's in general, IRQ4 is designated as the default
>>interrupt for COM1. Since IRQ int numbers are IRQ += 8, IRQ4 becomes int 12
>>also. My question is, how does the system determine what interrupt to vector
>>where and how are "separate" interrupt vectors defined? I have some serial
>>code which needs to tweek int vectors from time to time. The code is all
>>there to handle the serial interrupts, but there is no vector chaining
>>being done. I can force an int 12 by mov'ing 0 into SP and pushing AX onto
>>the stack, and I get my default "stack fault exception" message. What magic
>>is being done here?
>>
>>Thanx, in advance....
>>
>>Steve
>>
>
>There is a "vector interrupt table" somewhere in lowest memory (the exact
>location eludes me at the moment), and it contains 255 pointers each pointing
>to a piece of code that it jumps to when that particular interrupt is 
>generated.  You can change the place that a pointer points to via DOS 
>interrupt functions get/set vector (I believe 25h is set vector).  
> 
>Some languages offer those functions built in as commands.  For example, 
>TurboC has get_vector() which returns a pointer to where the interrupt points
>to, and set_vector() which takes an integer of the interrupt and a pointer
>to a function and it sets that interrupt to your function.
> 
>BTW, on INT 12, you need to enable the IMR mask for the 8259 chip to allow 
>interrupts on Com1 and Com2.  This is done by changing the 3rd and 4th bits
>of port 21h to 1 (3 for com2, 4 for com1) to enable that particular port.
> 

I got all that, so far. The interrupt vector table (in real mode) is located
at 0000:0000. IRQ12's vector should be located at 0000:0030. This is all well
and fine, but there are processor exceptions which map to hardware interrupts.
I cannot find where INT 12 is mapped to an exception. My default BIOS int 12
handler does not deal with processor exceptions, and my own int 12 handler for
dealing with serial interrupts does not either. Normally, exception 12 (stack
fault exception) will not occur in real mode, unless you have a SP of 1 and
push a word on the stack. Then SP = -1 = FFFFH which is not real good. 
What I want to know, is how that gets handled independantly of my serial
interrupts. 

Cheers!
Steve

-- 
----------------------------------------------------------------------------
steve.resnick@f105.n143.z1.FIDONET.ORG - or - apple!camphq!105!steve.resnick
Flames, grammar errors, spelling errrors >/dev/nul
----------------------------------------------------------------------------

ekalenda@cup.portal.com (Edward John Kalenda) (10/12/90)

In article <1990Oct10.163006.8081@Octopus.COM> stever@octopus.COM (Steve Resni
ck ) writes:
>Heres's a good question for you PC guru types ...
>
>On 80286 and 80386 processors, int 12 is designated as a stack fault exceptio
n.
>So far so good. Also on PC's in general, IRQ4 is designated as the default
>interrupt for COM1. Since IRQ int numbers are IRQ += 8, IRQ4 becomes int 12
>also. My question is, how does the system determine what interrupt to vector
>where and how are "separate" interrupt vectors defined? I have some serial
>code which needs to tweek int vectors from time to time. The code is all
>there to handle the serial interrupts, but there is no vector chaining
>being done. I can force an int 12 by mov'ing 0 into SP and pushing AX onto
>the stack, and I get my default "stack fault exception" message. What magic
>is being done here?
>
>Thanx, in advance....
>
>Steve

Code written for DOS generally ignores the fact that 286 and 386 hardware
exceptions vector into the same places as hardware interrupts. The most
common way I've seen this dealt with is for the non-BIOS handler (serial
port in this case) to assume that the interrupt was meant for it. If it
finds that there is no reason to have received the interrupt, pass it along
to the previous handler. By this I mean that you would look at the serial
port hardware, if there was no interrupt generating condition (output buffer
empty, character received, etc.), assume that the interrupt was an exception
and let the BIOS handler have it.

This does not always work since the interrupt may have been generated by the
processor on an exception and then the serial port hardware might receive a
character. I always assume that the exception condition will not clear itself
so when I return from my interrupt handling the exception will happen again
and then I'll pass it along. Unclean, maybe, imperfect, yes. But this is DOS
not UNIX, we will always be limited by what must be able to run on an 8088
in a box that is older then some of us (not me, of course).

Ed
ekalenda@cup.portal.com