[comp.sys.ibm.pc] Use DOS interrupt 1C

ariola@gsg.UUCP (09/03/87)

System:		IBM PC/AT compatible
Sofware:	running DOS 3.20, MSC vresion 4.0
Problem:        use type 1C timer interrupt from a C program.

I tried to modify interrupt service routine of type 1C from my main
program (see main.c below) to be function 'ciao' which is written in
assembly (see file ciao.asm below).  I thought I followed all the
instructions among 5 different DOS reference books but I was not able
to make it working properly.  What happened was: the control is
transferred to ciao but the segment registers are all screwed up and
the machine halts.  Can someone points out what's wrong with it?
Thanks in advance...  (BTW, I was using codeview to debug this.)
 
The following is the source code for assembly routine ciao.asm and
its calling C program int.c:
----------------------------------------------------------------------
;	Static Name Aliases
;
	TITLE   ciao1
;	NAME    ciao1.C

	.287
_TEXT	SEGMENT  BYTE PUBLIC 'CODE'
_TEXT	ENDS
_DATA	SEGMENT  WORD PUBLIC 'DATA'
_DATA	ENDS
CONST	SEGMENT  WORD PUBLIC 'CONST'
CONST	ENDS
_BSS	SEGMENT  WORD PUBLIC 'BSS'
_BSS	ENDS
DGROUP	GROUP	CONST,	_BSS,	_DATA
	ASSUME  CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
_TEXT      SEGMENT

	PUBLIC	_ciao
_ciao	PROC NEAR
	;	Do nothing, just return from interrupt
	iret	

_ciao	ENDP
_TEXT	ENDS
END
----------------------------------------------------------------------
#include	<dos.h>

extern ciao();

main ()
{
	union	REGS	irg, org;	/* input, output registers */
	struct	SREGS	srg;		/* segment registers */
	struct	{
		unsigned int	seg;
		unsigned int	off;
	} c;
	char far *p;

	p = ( char *)((long)ciao);
	segread(&srg);

	c.off = FP_OFF(p);  c.seg = srg.cs;
	srg.ds = c.seg;  irg.x.dx = c.off;  irg.h.ah = 0x25;  irg.h.al = 0x1c;
	intdosx(&irg, &org, &srg); 	/* set 1C interrupt to: ciao */
	for (;;)
		printf ("wait...");
}

hamby@uahcs1.UUCP (Jason N. Hamby) (09/05/87)

Hello,
  If the driver at 1C is replaced by your own, the last thing YOUR code
  should do is to REENABLE Interrupts (STI) and then call the old interrupt
  handler. If the old interrupt handler is not called, the system crashes
  as soon as control is returned back to command.com after running your
  program. Also, an interrupt driver of that type MUST be disabled before 
  your program exits (or load your driver as a TSR) or your interrupt driver
  will not remain in memory... but the system will keep calling... CRASH.
			Jason Hamby

P.S. The above information was not conveinently located correctly in many
   texts I have at my disposal. As with most pc tech stuff, the school of
   hard knocks provided an answer. If any of this information is incorrect,
   someone please post a rebuttal. Flames will be mv \dev\null...