[comp.lang.c] interrupt type in Turbo C

murphy@pur-phy (William J. Murphy) (07/29/89)

I am woking on a program to interface with a DataTranslation board
from my Zenith PC 386.  I came across a type of variable which I know
nothing about.  The program was written in Turbo C and TC uses a type
interrupt.  I looked at the manual for TC and found that this is specific
to TC, so my question is how would I implement this in MicroSoft C 5.1?
I have little experience programming interrupts, in fact this is 
my first time in MS-DOS.


/* Function Prototypes */
void interrupt DTintHandler(unsigned bp, unsigned di, unsigned si,
			    unsigned ds, unsigned es, unsigned dx,
			    unsigned cx, unsigned bx, unsigned ax);
void InitInt( int vector, void interrupt (*haddr) ());


void interrupt DTintHandler(unsigned bp, unsigned di, unsigned si,
			    unsigned ds, unsigned es, unsigned dx,
			    unsigned cx, unsigned bx, unsigned ax);
{
	if (( inport(ADSCR) & BIT15) == BIT15)
		aderror = TRUE;
	if(( inport(SUPSCR) & BIT15) == BIT15)
	{
		done = TRUE;
		outport(SUPSCR, BIT13);
	}
	outport(MASTER, EOI);
	outport(SLAVE, EOI);
}	
void InitInt( int vector, void interrupt (*haddr) ());
{
	unsigned regvalue;
	setvect(vector, haddr);
	disable();
	regvalue = inport(MSTRMASKREG);
	outport(MSTRMASKREG, regvalue & 0xFB);
	regvalue = inport(SLVMASKREG);
	outport(SLVMASKREG, regvalue & !IRQ15);
	enable();
}

Well, there are the two functions, I believe the  inport and outport
would be equivalent to MSC's inpw, and outpw.  setvect must be taking the
address which is passed and shoving it into the appropriate interrupt 
register.  inthis case what gets passed is the following
  InitInt(VECTNUM, DTintHandler)
where VECTNUM = 0x77. Lastly I assume that enable() and disable() perform
on the enabling/disabling of interrupts.  

Since I don't own Turbo C, I would rather get this translated to MSC. 
Does anyone have experience with this?  
Please e-mail any ideas (can you really e-mail and idea) or thoughts
on this subject.  I am not a regular reader of comp.lang.c or comp.sys.ibm.pc.
Thanks,
Bill Murphy
murphy@newton.physics.purdue.edu

blanier@mips.COM (Brian Lanier) (07/29/89)

In article <2388@pur-phy> murphy@pur-phy (William J. Murphy) writes:
>I came across a type of variable which I know
>nothing about.  The program was written in Turbo C and TC uses a type
>interrupt.  I looked at the manual for TC and found that this is specific
>to TC, so my question is how would I implement this in MicroSoft C 5.1?

From what I have read, the way to accomplish this in MSC is to use the
-S switch to generate the source listing and change "ret" to "iret". Of
course,  you then have to assemble/link that code in with the C.
Alternately, you could use debug, find the address of the ret instruction
and change it that way. (This is a real pain in the tuckus) (see note)
To install the interrupt, use Function 35h to get the current vector (for
later chaining, of course) and use Function 25h to set the new vector.
This takes the place of Turbo C's getvect() and setvect().  (I thinks MSC
5.0 added dos_getvect and dos_setvect, but I'm not sure).  

I hope that's what you were asking for. 

Brian Lanier
blanier@mips.com
blanier@scueng.scu.edu

note: if you feel you have to use the debug method (maybe you don't have a
good assembler), the coding for ret is :

		  11000011                        return within a segment
		  11000000 data-low data-high     return within a segment
										   with a pop value
          11001011                        intersegment return
		  11001010 data-low data-high     intersegment return with a 
										   pop value

I would be suprised if there was a pop value (if there is you have to code
it out as iret won't let you have one.)  The coding for iret is :
  
		  11001111

Just replace the right bit pattern. Use the u in debug to find the ret.

abcscnuk@csuna.csun.edu (Naoto Kimura) (07/30/89)

The "interrupt" keyword is should be available with MSC 5.1, as this
was available on MSC 5.0 (but was never mentioned anywhere in the
manual except for the phrase "make sure that you declare the function
as an interrupt" -- for each of the functions that manipulated the
system interrupt table).   Another thing to watch out is to make sure
that you declare all functions that are declared as "interrupt" that
you make also make it "far" or you may have problems in linking (this
one was another thing that made me scratch my head for nearly 3 days).
If you are using hardware interrupts, you probably want the header to
look something like:

    void far interrupt intserver()	/* note lack of args */

I don't recall if the compiler generated the code to push all the
registers or not.   You might want to use the appropriate flags to
generate assembly language output and check to make sure that it does.
If it doesn't then you should use some inline assembly (I don't recall
if MSC had it or not) or write the interrupt service routine in
assembly.

                //-n-\\			 Naoto Kimura
        _____---=======---_____		 (abcscnuk@csuna.csun.edu)
    ====____\   /.. ..\   /____====
  //         ---\__O__/---         \\	Enterprise... Surrender or we'll
  \_\                             /_/	send back your *&^$% tribbles !!

t-davidw@microsoft.UUCP (David Weigant) (07/31/89)

In article <24259@abbott.mips.COM> blanier@mips.COM (Brian Lanier) writes:
>In article <2388@pur-phy> murphy@pur-phy (William J. Murphy) writes:
>>I looked at the manual for TC and found that this is specific
>>to TC, so my question is how would I implement this in MicroSoft C 5.1?
>
>From what I have read, the way to accomplish this in MSC is to use the
>-S switch to generate the source listing and change "ret" to "iret". Of
>course,  you then have to assemble/link that code in with the C.

The interrupt keyword is supported by both MSC and QC, so it is not
necessary to hack the generated source listing or modify the .exe with
debug.  You can find information on using the interrupt keyword in the
readme.doc that comes with MSC 5.x or you can query on 'interrupt' inside
QC 2.00.

For getting and setting interrupt vectors, the functions _dos_getvect
and _dos_setvect can be used.  They map to DOS functions 0x35 and 0x25
respectively.

Hope this helps
David Weigant

bmarsh@cod.NOSC.MIL (William C. Marsh) (08/01/89)

In article <2388@pur-phy>, murphy@pur-phy (William J. Murphy) writes:
> I am woking on a program to interface with a DataTranslation board
> from my Zenith PC 386.  I came across a type of variable which I know
> nothing about.  The program was written in Turbo C and TC uses a type
> interrupt.  I looked at the manual for TC and found that this is specific
> to TC, so my question is how would I implement this in MicroSoft C 5.1?
> I have little experience programming interrupts, in fact this is 
> my first time in MS-DOS.
> 
> 
> /* Function Prototypes */
> void interrupt DTintHandler(unsigned bp, unsigned di, unsigned si,
> 			    unsigned ds, unsigned es, unsigned dx,
> 			    unsigned cx, unsigned bx, unsigned ax);
> void InitInt( int vector, void interrupt (*haddr) ());
> 
> 
> void interrupt DTintHandler(unsigned bp, unsigned di, unsigned si,
> 			    unsigned ds, unsigned es, unsigned dx,
> 			    unsigned cx, unsigned bx, unsigned ax);

'interrupt' functions are supported by MSC 5.1, however, the only
documentation is in the 'readme' file on the setup disk...  The only
difference between Turbo C and MSC is that in Turbo the function is
automatically made 'far', which is smart (MSC you *have* to say far),
and the register contents are placed on the stack in a different order.
(Here MSC is better, if you tell it to make 186 or 286 code, it can do
a pusha/popa)

Here is an example of the beginning of a critical error handler I wrote
in C (both...)

static void interrupt far
#ifdef	__TURBOC__
crit_error(bp, di, si, ds, es, dx, cx, bx, ax)
unsigned bp, di, si, ds, es, dx, cx, bx, ax;
#else
crit_error(es, ds, di, si, bp, sp, bx, dx, cx, ax, ip, cs, flags)
unsigned es, ds, di, si, bp, sp, bx, dx, cx, ax, ip, cs, flags;
#endif
{

Hope this helps!

Bill
--------

Bill Marsh, Naval Ocean Systems Center, San Diego, CA
{arpa,mil}net: bmarsh@cod.nosc.mil
uucp: {ihnp4,akgua,decvax,dcdwest,ucbvax}!sdcsvax!nosc!bmarsh

"If everything seems to be coming your way, you're probably in the wrong lane."

cb@cci632.UUCP (Just another hired gun (n2hkd)) (08/01/89)

SInce I don't like to reinvent the wheel, I cheat or buy :-)...
This problem is also analgous (gawd awful spelling :-( ), to the
TSR problem. Hence buying one of those TSR libraries seems like
a neat way to go... try "resident_C" by essential or some
such program. They even tell what needs to be protected when you're
trying to something real with dos, actually they handle that stuff
really well (like the ^break int etc...)

Hope this helps....

-- 
I volunteered for the rights in America, and now I'm losing them, AAARGHH 
email:   cb@cci632  or !rochester!kodak!n2hkd!curtis   Fight for your RIGHTS!
Curtis Braun, N2HKD, Computronics, PO Box 1002 Fairport NY, 14450