jmbj@grebyn.com (Jim Bittman) (03/23/91)
I learned something quite interesting from Microsoft Tech Support today. It turns out that "outport(PORTID,PORTVALUE)" is not a "nice" function. They said it must access the BIOS or DOS or something which makes it non re-entrant (i.e. unavailable for interrupt routines). Excuse me? Shouldn't this just translate to: mov dx,PORTID mov ax,PORTVALUE out dx,ax Not to mention the fact that for a hardware interrupt, an outport(20,20) needs to be executed to "EOI" the 8259. Anyway, this was their excuse for the fact that hardware ints don't seem to work properly. I'm sorry that I haven't verified this yet, but I do know that a very simple program works just fine with Borland, but dies miserably with Microsoft. I hope this saves someone else the many, many, many, frustrating hours I have spent dealing with this problem. Jim Bittman, jmbj@grebyn.com
gag@marlin.NOSC.MIL (Gary A. Gilbreath) (03/23/91)
From article <1991Mar23.021231.21131@grebyn.com>, by jmbj@grebyn.com (Jim Bittman): > I learned something quite interesting from Microsoft Tech Support today. > It turns out that "outport(PORTID,PORTVALUE)" is not a "nice" function. > They said it must access the BIOS or DOS or something which makes it > non re-entrant (i.e. unavailable for interrupt routines). > Excuse me? Shouldn't this just translate to: > mov dx,PORTID > mov ax,PORTVALUE > out dx,ax I have found just the opposite. Both MSC 5.1 and 6.00A library routines for inp(), inpw(), outp(), and outpw() are re-entrant. If you want in-line routines you can either enable intrinsics with a command line option, or put "#pragma intrinsic(inp, inpw, outp, outpw)" in the source file. > Not to mention the fact that for a hardware interrupt, an outport(20,20) > needs to be executed to "EOI" the 8259. Anyway, this was their excuse > for the fact that hardware ints don't seem to work properly. I have just completed a program that uses both DMA and interrupts without a single line of assembly. You do have to remember to turn off run-time stack overflow checking and be very careful about which library routines (if any) you call while in the interrupt routine, but it does work. Gary Gilbreath, Naval Ocean Systems Center, San Diego, CA Internet: gag@manta.nosc.mil uucp: {ihnp4,akgua,decvax,dcdwest,ucbvax}!sdcsvax!nosc!gag
tabu6@CCVAX.IASTATE.EDU (Adam Goldberg) (03/25/91)
In article <1991Mar23.021231.21131@grebyn.com>, jmbj@grebyn.com (Jim Bittman) writes: >I learned something quite interesting from Microsoft Tech Support today. >It turns out that "outport(PORTID,PORTVALUE)" is not a "nice" function. >They said it must access the BIOS or DOS or something which makes it >non re-entrant (i.e. unavailable for interrupt routines). >Excuse me? Shouldn't this just translate to: > mov dx,PORTID > mov ax,PORTVALUE > out dx,ax Yeah for Microsoft. TurboC's outportb() function turns out to actually be a macro (well, if you #undef it, it's a function), that does compile to exactly the above code. > >Not to mention the fact that for a hardware interrupt, an outport(20,20) >needs to be executed to "EOI" the 8259. Anyway, this was their excuse >for the fact that hardware ints don't seem to work properly. I'm sorry >that I haven't verified this yet, but I do know that a very simple >program works just fine with Borland, but dies miserably with Microsoft. > >I hope this saves someone else the many, many, many, frustrating hours >I have spent dealing with this problem. > >Jim Bittman, jmbj@grebyn.com I'm not sure how you can do this (or if) with Microsoft C, but with TurboC, you can use the command-line version of the compiler and do: tcc -S mysource.c and it will create MYSOURCE.ASM, an MASM-compatible assembly listing of your code with original source line numbers included as comments (I sure would like the actual C source as comments, but you take what you can get). Looking at this code, a function of type INTERRUPT does something like this: 1 - save all registers 2 - change to a local stack 3 - your code goes here (careful you don't use long-running DOS/BIOS calls--also realize that your interrupt routine MAY GET CONTROL DURING a DOS/BIOS routine, therefore you may be violating the non-reentrancy of DOS/BIOS) 4 - change back to previous stack 5 - pop all registers 6 - IRET Maybe Microsoft C will let you look at the code it compiles for you, and maybe this will give you some light as to what the H*ll it's doing. +----------------------------------------------------------------------------+ + Adam Goldberg Bitnet: tabu6@ISUVAX.BITNET + + Iowa State University Internet: tabu6@CCVAX.IASTATE.EDU + + H: (515) 233-5135 + "It's simple! Even a Pascal programmer could do it!" + +----------------------------------------------------------------------------+
jmbj@grebyn.com (Jim Bittman) (03/25/91)
I'm kind of embarrassed to point out that the *entire* problem was due to not turning off run-time stack checking. I can use the exact same code as Borland, but compile with /Gs, and it works! But: - Why isn't outp (MicroSoft) a "nice" function? - We checked the MS documentation and several other books, but nothing mentioned the /Gs switch (in relation to HW ints), any reasons why? I must thank the net, because that is where the answer came from! Jim Bittman, jmbj@grebyn.com
rkl@cbnewsh.att.com (kevin.laux) (03/25/91)
In article <1991Mar25.005251.12943@grebyn.com>, jmbj@grebyn.com (Jim Bittman) writes: > I'm kind of embarrassed to point out that the *entire* problem was due > to not turning off run-time stack checking. I can use the exact same > code as Borland, but compile with /Gs, and it works! > > But: > - Why isn't outp (MicroSoft) a "nice" function? > - We checked the MS documentation and several other books, but > nothing mentioned the /Gs switch (in relation to HW ints), > any reasons why? The outp () function is a nice function. *Any* function with arguments could have caused the stack problem because arguments are (normally, except for fastcall) pushed onto the stack. Interrupts occur asynchronously and the ISR gets whatever stack is in effect. When you use the interrupt keyword all the registers are pushed onto the current stack and it's up to the ISR to provide it's own stack if necessary. It's not a failing (per se) on the MSC documentation, because writing an ISR is an advanced topic dealing with the system and not any particular C compiler. Actually, getting caught with the run-time stack checking is a fairly common occurence when writing ISR's; common enough that MS should say a few words about it in their Advanced Programming Techniques manual. Alas, stuff like this tends to fall into the cracks and one has to find out the hard way. :-( -- ________________________________________________________________________________ R. Kevin Laux Email: rkl1@hound.att.com AT&T Bell Labs Voice: (908) 949-1160 Holmdel, NJ 07733 Fax: (908) 949-0959