bammi@cwruecmp.UUCP (Jwahar R. Bammi) (07/21/86)
Here is the Xbtimer sample program promised in an earlier message.
Packed in shar format.
-----
#!/bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #!/bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
# xbtimer.c
# This archive created: Mon Jul 21 01:22:10 1986
# By: Jwahar R. Bammi ()
export PATH; PATH=/bin:$PATH
echo shar: extracting "'xbtimer.c'" '(4181 characters)'
if test -f 'xbtimer.c'
then
echo shar: over-writing existing file "'xbtimer.c'"
fi
sed 's/^X//' << \SHAR_EOF > 'xbtimer.c'
X#include <osbind.h>
X#include <stdio.h>
X
X#define VOID int
X
X
X/*
X * Xbtimer.c
X * Sample code that demonstrates the use of TIMER A on the 68901 MFP
X * Also demonstrates how to take over the process terminate interrupt.
X *
X * WHAT:
X *
X * The program begins by installing the address of the function
X * 'terminate' into the exception vector 0x102 (Process terminate
X * exception, saving its old pointer. It then starts up Timer A on
X * the MFP, configured to interrupt the function 'count' at 48Hz. The
X * main loop continuously displays the value of a counter, that the
X * function 'count' increments. On hitting CTRL-C, the 'terminate' function
X * is called to handle the termination. It stops Timer A, then
X * restores the origonal process terminate vector and
X * returns (to the default system Interrupt Service Routine).
X *
X * HOW:
X * The timers on the MFP are controlled by a 2.4576 Mhz xtal (Yes the
X * Atari Internals book is once again wrong!). Using
X * timer 'a' in the delay mode with a prescale set at 200 (ie. by
X * setting the timer 'a' control register to 7)
X * gives you a 12288 Hz counter (2457600/200). Using a count
X * of 256 (ie. by loading the timer 'a' data register with 0)
X * you get an interrupt frequency of 48 Hz (12288/256). For other
X * values for the control & data registers see the 68901 manual
X * available for free by calling Motorola, or see the Atari Internals
X * book.
X *
X * The timer interrupt is handled by the function 'count'. This function
X * increments the long counter, then clears Bit 5 of the ISRA (In
X * Service Register A), and then returns from the exception by doing
X * an RTE. NOTES: In the ST the 68901 always operates in the
X * Software End of Interrupt Mode (ie. bit 3 of the Vector Register VR
X * is always set). In this mode the ISR bit of the ISRA is automatically
X * set when an interrupt occurs and the processor requests the interrupt
X * vector. (The ISR bit corresponding to the Timer A interrupt is bit 5
X * of the ISRA). As long as the bit is set, that interrupt and any other
X * interrupts of lower priority cannot occur. Once the bit is cleared
X * the same interrupt or any lower priority interrupts can once again
X * occur. This is why it is important to clear BIT 5 of the ISRA before
X * performing the RTE. The address of the ISRA register is 0xfffA0F
X *
X *
X * Compile and link with gemstart.o, osbind.o, gemlib, libf
X *
X *
X * Author:
X * Comments/Questions etc to
X * Jwahar R. Bammi
X * .....!decvax!cwruecmp!bammi
X * bammi@case.CSNET
X * bammi%case@csnet-relay.ARPA
X *
X */
X
X/* Static globals */
X
X/* Internal software ticks counter */
Xlong counter = 0L;
X
X/* Saved Process terminate vector */
XVOID (*t_handle)();
X
X/* My process terminate handler */
XVOID terminate()
X{
X VOID count();
X
X /* Shut of Timer - by writing 0 to the control register of Timer A */
X Xbtimer(0, 0, 0, count);
X /* Clear bit 5 of ISRA just in case it was set */
X asm("bclr.b #5,$fffa0f");
X
X /* Restore the old process terminate vector */
X Setexc(0x0102, t_handle);
X
X /*
X * by doing an RTS here we return to the systems default
X * Interrupt service routine that dispatched the ^C interrupt
X * to this routine. It will take care of doing the RTE
X */
X
X /*
X * Note that we could have done an unlk R4 to restore the stack frame
X * and then jumped to the origonal handler too. (saved in t_handle)
X *
X */
X}
X
X/* MFP Timer A interrupt handler */
XVOID count()
X{
X /* Increment counter */
X counter++;
X
X /* Restore stack frame */
X asm("unlk R14");
X
X /* clear bit 5 of ISRA on the MFP */
X asm("bclr.b #5,$fffa0f");
X
X /* Return from exception */
X asm("rte");
X}
X
X
X/* Main */
Xmain()
X{
X char *save_ssp; /* Saved System Stack Pointer */
X
X /* Get into Supervisor mode */
X save_ssp = Super(0L);
X
X /* Get current Process Terminate vector */
X t_handle = Setexc(0x0102, -1L);
X
X /* Set up our own Process Terminate Handler */
X Setexc(0x0102, terminate);
X
X /* Start the timer */
X Xbtimer(0, 7, 0, count);
X
X /* Get out of Supervisor mode */
X Super(save_ssp);
X
X /* Continuously display counter */
X
X while(1 == 1)
X {
X char buf[12];
X
X sprintf(buf,"%09ld\r",counter);
X Cconws(buf);
X }
X
X /* If it gets here .. */
X Cconws("\r\nHeh! How did I end up here?\r\n");
X}
SHAR_EOF
if test 4181 -ne "`wc -c 'xbtimer.c'`"
then
echo shar: error transmitting "'xbtimer.c'" '(should have been 4181 characters)'
fi
# End of shell archive
exit 0
--
Jwahar R. Bammi
Usenet: .....!decvax!cwruecmp!bammi
CSnet: bammi@case
Arpa: bammi%case@csnet-relay
CompuServe: 71515,155