home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / TRSICAT.LZX / CATS_CD2_TRSI / Reference_Library / lib_examples / timersoftint.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-21  |  5.6 KB  |  136 lines

  1. ;/* timersoftint.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -d0 -cfistq -v -y -j73 timersoftint.c
  3. Blink FROM LIB:c.o,timersoftint.o TO timersoftint LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit ; */
  5. /* timersoftint.c - Timer device software interrupt message port example. */
  6.  
  7. #include <exec/memory.h>
  8. #include <exec/interrupts.h>
  9. #include <devices/timer.h>
  10. #include <dos/dos.h>
  11. #include <clib/exec_protos.h>
  12. #include <clib/dos_protos.h>
  13. #include <clib/alib_protos.h>
  14. #include <stdio.h>
  15.  
  16. #ifdef LATTICE
  17. int CXBRK(void) { return(0); }  /* Disable Lattice CTRL/C handling */
  18. void chkabort(void) { return; }  /* really */
  19. #endif
  20.  
  21. #define MICRO_DELAY 1000
  22. #define OFF     0
  23. #define ON      1
  24. #define STOPPED 2
  25.  
  26. struct TSIData {
  27.     ULONG tsi_Counter;
  28.     ULONG tsi_Flag;
  29.     struct MsgPort *tsi_Port;
  30. };
  31.  
  32. struct TSIData *tsidata;
  33.  
  34. void tsoftcode(void);    /* Prototype for our software interrupt code */
  35.  
  36. void main(void)
  37. {
  38.     struct MsgPort *port;
  39.     struct Interrupt *softint;
  40.     struct timerequest *tr;
  41.  
  42.     ULONG endcount;
  43.  
  44.     /* Allocate message port, data & interrupt structures. Don't use CreatePort() */
  45.     /* or CreateMsgPort() since they allocate a signal (don't need that) for a    */
  46.     /* PA_SIGNAL type port. We need PA_SOFTINT.                                   */
  47.     if (tsidata = AllocMem(sizeof(struct TSIData), MEMF_PUBLIC|MEMF_CLEAR))
  48.     {
  49.         if(port = AllocMem(sizeof(struct MsgPort), MEMF_PUBLIC|MEMF_CLEAR))
  50.         {
  51.             NewList(&(port->mp_MsgList));                             /* Initialize message list */
  52.             if (softint = AllocMem(sizeof(struct Interrupt), MEMF_PUBLIC|MEMF_CLEAR))
  53.             {
  54.                 /* Set up the (software)interrupt structure. Note that this task runs at  */
  55.                 /* priority 0. Software interrupts may only be priority -32, -16, 0, +16, */
  56.                 /* +32. Also not that the correct node type for a software interrupt is   */
  57.                 /* NT_INTERRUPT. (NT_SOFTINT is an internal Exec flag). This is the same  */
  58.                 /* setup as that for a software interrupt which you Cause(). If our       */
  59.                 /* interrupt code was in assembler, you could initialize is_Data here to  */
  60.                 /* contain a pointer to shared data structures. An assembler software     */
  61.                 /* interrupt routine would receive the is_Data in A1.                     */
  62.  
  63.                 softint->is_Code = tsoftcode;    /* The software interrupt routine */
  64.                 softint->is_Data = tsidata;
  65.                 softint->is_Node.ln_Pri = 0;
  66.  
  67.                 port->mp_Node.ln_Type = NT_MSGPORT;       /* Set up the PA_SOFTINT message port  */
  68.                 port->mp_Flags = PA_SOFTINT;              /* (no need to make this port public). */
  69.                 port->mp_SigTask = (struct Task *)softint;     /* pointer to interrupt structure */
  70.  
  71.                 /* Allocate timerequest */
  72.                 if (tr = (struct timerequest *) CreateExtIO(port, sizeof(struct timerequest)))
  73.                 {
  74.                     /* Open timer.device. NULL is success. */
  75.                     if (!(OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest *)tr, 0)))
  76.                     {
  77.                         tsidata->tsi_Flag = ON;        /* Init data structure to share globally. */
  78.                         tsidata->tsi_Port = port;
  79.  
  80.                         /* Send of the first timerequest to start. IMPORTANT: Do NOT   */
  81.                         /* BeginIO() to any device other than audio or timer from      */
  82.                         /* within a software or hardware interrupt. The BeginIO() code */
  83.                         /* may allocate memory, wait or perform other functions which  */
  84.                         /* are illegal or dangerous during interrupts.                 */
  85.                         printf("starting softint. CTRL-C to break...\n");
  86.  
  87.  
  88.                         tr->tr_node.io_Command = TR_ADDREQUEST;    /* Initial iorequest to start */
  89.                         tr->tr_time.tv_micro = MICRO_DELAY;        /* software interrupt.        */
  90.                         BeginIO((struct IORequest *)tr);
  91.  
  92.                         Wait(SIGBREAKF_CTRL_C);
  93.                         endcount = tsidata->tsi_Counter;
  94.                         printf("timer softint counted %ld milliseconds.\n", endcount);
  95.  
  96.                         printf("Stopping timer...\n");
  97.                         tsidata->tsi_Flag = OFF;
  98.  
  99.                         while (tsidata->tsi_Flag != STOPPED) Delay(10);
  100.  
  101.                         CloseDevice((struct IORequest *)tr);
  102.                     }
  103.                     else printf("couldn't open timer.device\n");
  104.                     DeleteExtIO(tr);
  105.                 }
  106.                 else printf("couldn't create timerequest\n");
  107.                 FreeMem(softint, sizeof(struct Interrupt));
  108.             }
  109.             FreeMem(port, sizeof(struct MsgPort));
  110.         }
  111.         FreeMem(tsidata, sizeof(struct TSIData));
  112.     }
  113. }
  114.  
  115. void tsoftcode(void)
  116. {
  117.     struct timerequest *tr;
  118.  
  119.     /* Remove the message from the port. */
  120.     tr = (struct timerequest *)GetMsg(tsidata->tsi_Port);
  121.  
  122.     /* Keep on going if main() hasn't set flag to OFF. */
  123.     if ((tr) && (tsidata->tsi_Flag == ON))
  124.     {
  125.         /* increment counter and re-send timerequest--IMPORTANT: This         */
  126.         /* self-perpetuating technique of calling BeginIO() during a software */
  127.         /* interrupt may only be used with the audio and timer device.        */
  128.         tsidata->tsi_Counter++;
  129.         tr->tr_node.io_Command = TR_ADDREQUEST;
  130.         tr->tr_time.tv_micro = MICRO_DELAY;
  131.         BeginIO((struct IORequest *)tr);
  132.     }
  133.     /* Tell main() we're out of here. */
  134.     else tsidata->tsi_Flag = STOPPED;
  135. }
  136.