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