[comp.sys.atari.st] Need help with Xbtimer

morrison@renoir.Berkeley.EDU (Scott Morrison) (11/11/88)

I am having trouble getting a timer interrupt routine to work.  Can anybody
tell me why the following piece of code doesn't work (it's written in
Mark Williams C):

#include <bios.h>
#include <xbios.h>

int tick=0;		/* clock counter */

clock_vector()
{
  tick++;
}

main()
{
  int control, data;
  
  /*  have the user enter values for control and data */
  printf("Enter timer A control register value: "); scanf("%d",&control);
  printf("Enter timer A data register value: "); scanf("%d",&data);
  /* Next install the interrupt handler for timer A */
  Xbtimer(0, control, data, clock_vector);
  /* Enable Timer A interrupts */
  Jenabint(MFP_TIMA);
  /* loop until a key is pressed printing the timer tick value */
  while(!Cconis())
    printf("tick = %d\n",tick);
  Cconin();
  Jdisint(MFP_TIMA);
}

I have read the section of the Abacus Atari Internals book about what
values should go into the timer control register, but when I set control
to a value which I think should correctly start the timer, my program
bombs with from 2 to 4 bombs, and the system always hangs.  
Can anyone tell me what magic values should be passed to Xbtimer, or if
that is not the problem, what am I doing wrong?
			-- Scott Morrison
			morrison@berkeley.edu

apratt@atari.UUCP (Allan Pratt) (11/12/88)

In article <26751@ucbvax.BERKELEY.EDU> morrison@renoir.Berkeley.EDU 
(Scott Morrison) writes:
> I am having trouble getting a timer interrupt routine to work.

Xbtimer takes four arguments: the timer to set up, the control and data
values for the timer, and a pointer to an interrupt handler.  You are
passing a pointer to a C procedure, which is not the same thing: C
procedures end with RTS, while interrupt handlers end with RTE.  I don't
know if MWC has a function you can call which causes your procedure to
end with RTE (some compilers do), but this is definitely your problem. 

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt

soohoo@cory.Berkeley.EDU (Ken Soohoo) (11/13/88)

In article <1227@atari.UUCP> apratt@atari.UUCP (Allan Pratt) writes:
>In article <26751@ucbvax.BERKELEY.EDU> morrison@renoir.Berkeley.EDU 
>(Scott Morrison) writes:
>> I am having trouble getting a timer interrupt routine to work.
>
>Xbtimer takes four arguments: the timer to set up, the control and data
>values for the timer, and a pointer to an interrupt handler.  You are
>passing a pointer to a C procedure, which is not the same thing: C
>procedures end with RTS, while interrupt handlers end with RTE.  I don't
>know if MWC has a function you can call which causes your procedure to
>end with RTE (some compilers do), but this is definitely your problem. 
>

Allan's right!
I've used MWC and Xbtimer, and _my_ solution was to write a little
assembly language routine that does the timer interrupt handling:
1) Don't forget to save the registers you use before processing,
   and restore them after (use movem.l).
2) You'll have to handle clearing the interrupt pending, enable,
   and in-service bytes:

	0xFFFa07	enable A
	0xFFFa0b	pending A
	0xFFFa0f	in-service A
	
   I believe bit 0 determines if its active or not, don't disturb
   the other bits when you clear one..
   (You only have to clear the in-service, the system clears 
    the pending one by itself).

3) rte at the end of your routine.


Hope this helps.
--Kenneth Soohoo	(soohoo@cory.Berkeley.Edu)
  Atari 400/800/600xl/800xl/1200/130xe/65xe, 1040ST hacker
  Sometime Berkeley Student, othertimes...
  My opinions are my OWN, not necessarily Atari's