home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 377a.lha / libraries / exec / interrupts / timersoftint.c next >
Encoding:
C/C++ Source or Header  |  1980-02-04  |  6.9 KB  |  217 lines

  1. ;/* timersoftint.c - Execute me to compile me with Lattice 5.04
  2. LC -b1 -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. */
  6.  
  7. /*
  8.  * TimerSoftInt.c - timer.device software interrupt example
  9.  *
  10.  * Copyright (c) 1990 Commodore-Amiga, Inc.
  11.  *
  12.  * This example is provided in electronic form by Commodore-Amiga, Inc. for
  13.  * use with the 1.3 revisions of the Addison-Wesley Amiga reference manuals. 
  14.  * The 1.3 Addison-Wesley Amiga Reference Manual series contains additional
  15.  * information on the correct usage of the techniques and operating system
  16.  * functions presented in this example.  The source and executable code of
  17.  * this example may only be distributed in free electronic form, via bulletin
  18.  * board or as part of a fully non-commercial and freely redistributable
  19.  * diskette.  Both the source and executable code (including comments) must
  20.  * be included, without modification, in any copy.  This example may not be
  21.  * published in printed form or distributed with any commercial product.
  22.  * However, the programming techniques and support routines set forth in
  23.  * this example may be used in the development of original executable
  24.  * software products for Commodore Amiga computers.
  25.  * All other rights reserved.
  26.  * This example is provided "as-is" and is subject to change; no warranties
  27.  * are made.  All use is at your own risk.  No liability or responsibility
  28.  * is assumed.
  29.  */
  30.  
  31. #include <exec/types.h>
  32. #include <exec/interrupts.h>
  33. #include <exec/memory.h>
  34. #include <devices/timer.h>
  35. #include <libraries/dos.h>
  36. #ifdef LATTICE
  37. #include <proto/all.h>
  38. #include <stdlib.h>
  39. #include <stdio.h>
  40. #include <string.h>
  41. int CXBRK(void) { return(0); }        /* Disable Lattice CTRL-C handling */
  42. int chkabort(void) { return(0); }    /* really */
  43. #endif
  44.  
  45. #define MIC_DELAY  1000
  46.  
  47. /* our functions */
  48. void *tsoftcode(void);  /* our timer softint code */
  49. void cleanexit(UBYTE *, LONG);
  50. void cleanup(void);
  51. void begintr(struct timerequest *);
  52.  
  53. /* Opens and allocations we must clean up.
  54.  * Note - casts of timerequest pointers to (struct IOStdReq *)
  55.  * in this example are to eliminate compiler warnings.
  56.  * A timerequest starts with but is larger than an IOStdReq.
  57.  */ 
  58. struct Interrupt    *tint = NULL;
  59. struct timerequest  *treq = NULL;
  60. struct MsgPort      *tport = NULL;
  61. BOOL OpenedTimer = FALSE;
  62.  
  63. /* Global variables shared with the softint code
  64.  * If our tsoftcode was in assembler, we could use is_Data
  65.  * pointer instead to tell softint code where shared data is
  66.  */
  67. #define OFF 0
  68. #define ON  1
  69. #define STOPPED 2
  70. BOOL SFlag=OFF;
  71. ULONG counter;
  72.  
  73. char tportname[] = "RKM_timersoftint";
  74.  
  75. void main(int argc, char **argv)
  76.    {
  77.    ULONG endcount;
  78.  
  79.    if(!argc)  exit(RETURN_FAIL);  /* CLI only example...Uses printf */
  80.  
  81.    /* Allocate our MsgPort and Interrupt structures
  82.     * Since we can't use CreatePort, we'll build the port ourselves.
  83.     * Create Port creates a PA_SIGNAL and allocs a signal.
  84.     * We want a PA_SOFTINT port;
  85.     */
  86.  
  87.    if(!(tport = (struct MsgPort *)
  88.        AllocMem(sizeof(struct MsgPort),MEMF_PUBLIC|MEMF_CLEAR)))
  89.            cleanexit("Can't allocmem msgport\n",RETURN_FAIL);
  90.  
  91.    if(!(tint = (struct Interrupt *)
  92.        AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC|MEMF_CLEAR)))
  93.            cleanexit("Can't allocmem interrupt\n",RETURN_FAIL);
  94.  
  95.  
  96.    /* Set up the (software) interrupt structure.
  97.     * Note that we are priority 0.  Software interrupts may only be
  98.     * priority -32, -16, 0, +16, or +32.  Also note that the
  99.     * correct node type for a software interrupt is NT_INTERRUPT.
  100.     * (NT_SOFTINT is an internal flag of Exec's)
  101.     * This is the same setup as that for a software interrupt
  102.     * which you Cause().  If our interrupt code was in assembler,
  103.     * you could initialize is_Data here to contain a pointer
  104.     * to shared data structures.  An assembler software interrupt
  105.     * routine would receive the is_Data pointer in A1.
  106.     */
  107.    tint->is_Code = (VOID (*)())tsoftcode;  /* Our softint routine */
  108.    tint->is_Node.ln_Type = NT_INTERRUPT;
  109.    tint->is_Node.ln_Pri = 0;
  110.  
  111.  
  112.    /* Set up the PA_SOFTINT msgport */
  113.    tport->mp_Node.ln_Type = NT_MSGPORT;
  114.    tport->mp_Node.ln_Name = (char *)tportname;
  115.    tport->mp_Flags = PA_SOFTINT;
  116.    tport->mp_SigTask = (struct Task *)tint;  /* Ptr to interrupt struct */
  117.  
  118.    /* Not using CreatePort, so we must add the port ourselves */
  119.    AddPort(tport);
  120.  
  121.    /* Now Create the IO request */
  122.    if(!(treq=(struct timerequest *)
  123.       CreateExtIO(tport,sizeof(struct timerequest))))
  124.          cleanexit("Can't create ioreq\n", RETURN_FAIL);
  125.  
  126.    /* Open the timer device - Note 0 return means success */
  127.    if(OpenDevice("timer.device",UNIT_MICROHZ,(struct IOStdReq *)treq,0))
  128.       cleanexit("Can't open timer device\n",RETURN_FAIL);
  129.  
  130.    OpenedTimer = TRUE;    /* Flag for closing in cleanup */
  131.  
  132.    /* Now, let's do something with it */
  133.    counter = 0L;
  134.    SFlag = ON;
  135.    begintr(treq);         /* Prime the pump with first timer request */
  136.  
  137.    printf("Timer softint is counting milliseconds. Press CTRL-C to exit...");
  138.    Wait(SIGBREAKF_CTRL_C);
  139.  
  140.    endcount = counter;
  141.    printf("\n\nSoftint counted %ld milliseconds\n",endcount);
  142.    printf("Stopping timer and exiting\n");
  143.  
  144.    SFlag = OFF;
  145.    while(SFlag != STOPPED)  Delay(10);
  146.  
  147.    cleanup();
  148.    exit(RETURN_OK);
  149.    }
  150.  
  151.  
  152. /* Routine called as software interrupt */
  153. VOID *tsoftcode()
  154.    {
  155.    struct timerequest *tr;
  156.  
  157.    /* Remove our message from our port */
  158.    tr = (struct timerequest *)GetMsg(tport);
  159.  
  160.    /* If main hasn't flagged us to stop, keep the ball rolling */
  161.    if((tr)&&(SFlag==ON))
  162.       {
  163.       /* Increment the counter and send the timer request out again.
  164.        *
  165.        * IMPORTANT: This self-perpetuating technique of calling
  166.        * BeginIO during a software interrupt may only be used with
  167.        * the audio and timer device.
  168.        */
  169.       counter++;
  170.       begintr(tr);
  171.       }
  172.    /* Else flag main we have indeed stopped */
  173.    else(SFlag=STOPPED);
  174.    return(0);
  175.    }
  176.  
  177.  
  178. /* begintr(tr)
  179.  * Sets up and sends off timer request.
  180.  * IMPORTANT: Do not BeginIO to any device other than timer or audio
  181.  * from within a software or hardware interrupt.  The BeginIO code
  182.  * of other devices may allocate memory, wait, or perform other
  183.  * functions which are illegal or dangerous during interrupts.
  184.  */
  185. void begintr(struct timerequest *tr)
  186.    {
  187.    /* Set up the timer command */
  188.    tr->tr_node.io_Command = TR_ADDREQUEST;
  189.    tr->tr_time.tv_secs = 0;    /* secs must be cleared each time */
  190.    tr->tr_time.tv_micro = MIC_DELAY;
  191.    BeginIO((struct IOStdReq *)tr);
  192.    }
  193.  
  194. /* Prints message if any, cleans up, and exits */
  195. void cleanexit(UBYTE *s, LONG n)
  196.    {
  197.    if(*s)  printf(s);
  198.    cleanup();
  199.    exit(n);
  200.    }
  201.  
  202. /* Close/deallocate everything opened/allocated */
  203. void cleanup()
  204.    {
  205.    if(OpenedTimer)  CloseDevice((struct IOStdReq *)treq);
  206.    if(treq)         DeleteExtIO((struct IOStdReq *)treq);
  207.    if(tport)
  208.       {
  209.       RemPort(tport);
  210.       FreeMem(tport,sizeof(struct timerequest));
  211.       }
  212.    if(tint)  FreeMem(tint, sizeof(struct Interrupt));
  213.    }
  214.  
  215.  
  216.  
  217.