[net.micro.atari16] Sorry, but these guys....

jdg@elmgate.uucp (Jeff Gortatowsky) (05/21/86)

>  You got *that* right, too.  I'm kind to animals, give to the charities
>of my choice, and even signal lane-changes.  Incidentally, I haven't
>noticed your comments before outside of net.micro.amiga; you wouldn't
>by any chance have some *valid* reason for flaming in the Atari newsgroup,
>would you?

Don't suppose it ever occured to you that I might use/own *BOTH* an Atari ST
*AND* an Amiga, huh?  No I guess not.  And if it had been an Atari official
voiceing his opinion , I'd have supportted his right to do so also.
I'm 'company blind'. So long as they don't output downright advertisements
here, I don't mind.  It gives me a chance to communicate  
with people I might never get to meet, and could only read about
3 monthes later in a magazine. 

Anyways you feel your way and I'll feel mine.

But your right, back to something useful.

********** A little help please *******

Here's a short routine written in the release version of MegaMax C
It bombs miserably (address errors). I'm typing it from memory, so forgive
me if it's not perfect, however the routine DOES compile and link without
errors at home on my machine.

Now it seems to load and start running, because there is a definite
delay between the 'here we go' and the 3 bombs.
Makes me think it's either a stack overflow or something trashed in the
Xbtimer call or after the loop exits.  I hate these problems as they
always turn out to be simple.  But I'm at a loss.  Any Ideas?

BTW, I have seen Russ W.'s code example for the 50hz GEM timer interrupt,
where he saves A4.  He says otherwise it gets trashed. I don't think
that applies here. I'm not passing control to any GEM function so I don't
think A4 can get trashed.  Indeed looking at bios for Xbtimer shows
that it simply moves my vector into $134 which is the 13th MFP vector. So
only my routine should get control at the interrupt. Right? Wrong?
PS. Whats the clock rate for the MFP and the MFP timers? They can be
clocked separatly. Are they?

Thanks for the help in advance
/***********************************
        My Time Int.
************************************/

#include <stdio.h>

extern int my_timer_code ();

asm {
      my_timer_code:
          addq.l	#1,D7          /* Just count interrupts */
          move.b	#0xDF,0xFFFA0F /* Clear ISRA Timer A bit */
          rte
    }


main()
{
	register long count = 0;     /* Count of interrupts */
	register int i;
    int (*my_interrupt_handler) ();
 
	my_interrupt_handler = my_timer_code; /* point to my interrupt */

	Xbtimer (0,1,100,my_interrupt_handler);  /* Enable timer A, prescale 4
                                                for 100 counts (100us ?) */ 

    for (i = 0; i < 30000; i++)
		;

	Xbtimer (0,0,0,0L);
    
	printf ("Timer timed out %d times.\n");
}


-- 
Jeff Gortatowsky       {allegra,seismo}!rochester!kodak!elmgate!jdg
Eastman Kodak Company  

<Kodak won't be responsible for the above comments, only those below>
 

eric@megamax (05/27/86)

Your program would work fine in a system with no other interrupts, however
that is not the case on the ST.  There are a number of interrupts that occur
on a regular basis (vertical retrace, keyboard etc.)  It is quite likely that
your timer will go off while one of these routines is being serviced.  It is
also quite likely that one of these routines is using D7.

What you need to do is establish a different mechanism for communicating
between the interrupt routine and the main program.  The easiest method is 
to declare some space in the interrupt procedure, preceeding it with a label,
and use PC relative addressing to access it.  If you save A4 in the space
then you can directly access C global variables from your interrupt procedure.

The following listing includes these modifications to your original program.
========================================================
#include <stdio.h>
#include <osbind.h>

extern int my_timer_code ();
long count;

asm {
    my_timer_code:
        move.l  A4, -(A7)   
        move.l  save_a4(PC), A4     /* Restore A4 */
        addq.l  #1, count(A4)       /* Just count interrupts */
        move.b  #0xDF,0xFFFA0F      /* Clear ISRA Timer A bit */
        move.l  (A7)+, A4
        rte

    save_a4:
        dc.l    0
    }


main()
{
    register int i;
    int (*my_interrupt_handler) ();
 
    asm {   /* Save A4 for use in interrupt routine */
        lea     save_a4(PC), A0
        move.l  A4, (A0)
    }
    my_interrupt_handler = my_timer_code; /* point to my interrupt */

    Xbtimer (0,1,100,my_interrupt_handler);  /* Enable timer A, prescale 4
                                                for 100 counts (100us ?) */ 

    for (i = 0; i < 30000; i++)
        ;

    Xbtimer (0,0,0,0L);
    
    printf ("Timer timed out %ld times.\n", count); 
}