home *** CD-ROM | disk | FTP | other *** search
- /*
- *
- * DISCLAIMER:
- *
- * This program is provided as a service to the programmer
- * community to demonstrate one or more features of the Amiga
- * personal computer. These code samples may be freely used
- * for commercial or noncommercial purposes.
- *
- * Commodore Electronics, Ltd ("Commodore") makes no
- * warranties, either expressed or implied, with respect
- * to the program described herein, its quality, performance,
- * merchantability, or fitness for any particular purpose.
- * This program is provided "as is" and the entire risk
- * as to its quality and performance is with the user.
- * Should the program prove defective following its
- * purchase, the user (and not the creator of the program,
- * Commodore, their distributors or their retailers)
- * assumes the entire cost of all necessary damages. In
- * no event will Commodore be liable for direct, indirect,
- * incidental or consequential damages resulting from any
- * defect in the program even if it has been advised of the
- * possibility of such damages. Some laws do not allow
- * the exclusion or limitation of implied warranties or
- * liabilities for incidental or consequential damages,
- * so the above limitation or exclusion may not apply.
- *
- */
-
- /* SIMPLE TIMER EXAMPLE PROGRAM:
- *
- * Includes dynamic allocation of data structures needed to communicate
- * with the timer device as well as the actual device IO
- *
- * Author: Rob Peck, 12/1/85 */
-
- #include "exec/types.h"
- #include "exec/nodes.h"
- #include "exec/lists.h"
- #include "exec/memory.h"
- #include "exec/interrupts.h"
- #include "exec/ports.h"
- #include "exec/libraries.h"
- #include "exec/io.h"
- #include "exec/tasks.h"
- #include "exec/execbase.h"
- #include "exec/devices.h"
- #include "devices/timer.h"
-
- long TimerBase; /* to get at the time comparison functions */
-
- main()
- {
- LONG error;
- LONG days, minutes,seconds;
- struct timeval mytimeval;
- struct timeval oldtimeval; /* save what system thinks is
- * the time.... we'll advance it
- * temporarily
- */
- printf("\ntimer test");
-
- TimeDelay(2,0,0);
- printf("\nAfter 2 seconds delay");
-
- TimeDelay(4,0,0);
- printf("\nAfter 4 seconds delay");
-
- TimeDelay(0,500000,0); /* 500,000 seconds = 1/2 second */
- printf("\nAfter 1/2 second delay");
-
- printf("\n\n");
- error = Execute("date",0,0); /* normal system startup file
- * opens dos.library, so it is
- * ok in such cases to use dos calls */
-
- GetSysTime(&oldtimeval);
- printf("\nCurrent system time is %ld current seconds",
- oldtimeval.tv_secs);
-
- printf("\nSetting a new system time");
-
- days = 1000 + oldtimeval.tv_secs / (24*60*60);
- minutes = (oldtimeval.tv_secs % (24*60*60)) / 60;
- seconds = (oldtimeval.tv_secs % (24*60*60)) % 60;
-
- SetNewTime(days, minutes, seconds);
- /* (if user executes the AmigaDOS DATE command now, he will
- * see that the time has advanced something over 1000 days */
-
- printf("\n\n");
- error = Execute("date",0,0); /* normal system startup file
- * opens dos.library, so it is
- * ok in such cases to use dos calls */
- GetSysTime(&mytimeval);
- printf("\nCurrent system time is %ld.%06ld",
- mytimeval.tv_secs,mytimeval.tv_micro);
-
- GetSysTime(&mytimeval);
- printf("\nCurrent system time is %ld.%06ld",
- mytimeval.tv_secs,mytimeval.tv_micro);
-
- GetSysTime(&mytimeval);
- printf("\nCurrent system time is %ld.%06ld",
- mytimeval.tv_secs,mytimeval.tv_micro);
-
- /* added the microseconds part to show that time keeps
- * increasing even though you ask many times in a row */
-
- printf("\nResetting to former time");
-
- days = oldtimeval.tv_secs / (24*60*60);
- minutes = (oldtimeval.tv_secs % (24*60*60)) / 60;
- seconds = (oldtimeval.tv_secs % (24*60*60)) % 60;
-
- SetNewTime(days, minutes, seconds);
-
- GetSysTime(&mytimeval);
- printf("\nCurrent system time is %ld.%06ld",
- mytimeval.tv_secs,mytimeval.tv_micro);
-
- TimerBase = GetTimerBase();
- /* just shows how to set up for using
- * the timer functions, does not demonstrate
- * the functions themselves. (TimerBase must
- * have a legal value before AddTime, SubTime or CmpTime
- * are performed.
- */
- }
-
- /* *********************************************************************** */
- /* Timer function - timedelay(seconds,microseconds)
-
- Your task is put to sleep for the specified time interval.
-
- If seconds > 0, then UNIT_VBLANK is used, delay is in multiples of
- 60ths of a second. If seconds < 0, then UNIT_MICROHZ is used for
- more precision.
-
- Returns value of 0 if no errors, nonzero (and no task sleeping)
-
- Notice that since this is a multi-tasking system, the delays
- shown here must be considered to be only approximate.
-
- Also note that this function is used primarily to show how
- a timer device is accessed, including the creation of the
- message port and a message structure (IOStdReq). Note that
- there is a Delay(interval) function already in the DOS.library.
- (See the DOS developer's manual for details).
-
- */
- /* *********************************************************************** */
-
- extern struct MsgPort *CreatePort();
- extern struct IORequest *CreateExtIO();
-
- struct timerequest
- *PrepareTimer(precision)
- SHORT precision;
- {
- /* return a pointer to a time request. If any problem, return NULL */
-
- int error;
- SHORT whichunit;
-
- struct MsgPort *timerport;
- struct timerequest *timermsg;
-
- timerport = CreatePort(0,0);
- if (timerport == NULL)
- return(NULL); /* Error during CreatePort */
-
- timermsg = (struct timerequest *)CreateExtIO(
- timerport,sizeof(struct timerequest));
- if (timermsg == NULL)
- {
- DeletePort(timerport);
- return(NULL); /* Error during CreateExtIO */
- }
-
- if(precision) /* if true, use precision timer ( under 1 second ) */
- whichunit = UNIT_MICROHZ;
- else
- whichunit = UNIT_VBLANK;
-
- error = OpenDevice(TIMERNAME, whichunit, timermsg, 0);
- if (error != 0)
- {
- DeleteExtIO(timermsg,sizeof(struct timerequest));
- DeletePort(timerport);
- return(NULL); /* Error during OpenDevice */
- }
- return(timermsg);
- }
-
- int
- GetTimerBase()
- {
- int tbase;
- struct timerequest *tr;
- tr = PrepareTimer();
- tbase = (int)tr->tr_node.io_Device;
- DeleteTimer(tr);
- return(tbase);
- }
-
- int
- TimeDelay(seconds,microseconds,precision)
- /* more precise timer than AmigaDOS Delay() */
- ULONG seconds,microseconds;
- int precision;
- {
- int precise;
- struct timerequest *tr;
- if(seconds < 0 || precision != 0)
- /* do delay in terms of microseconds */
- precise = TRUE; /* yes, use the precision timer. */
- else
- precise = FALSE; /* no, not necessary */
-
- tr = PrepareTimer(precise);
- /* get a pointer to an initialized
- * timer request block */
- if(tr == NULL) return(-1); /* any nonzero return says timedelay
- * routine didn't work. */
- WaitForTimer(tr,seconds,microseconds);
-
- DeleteTimer(tr); /* deallocate temporary structures */
- return(0);
- } /* end of timedelay */
-
-
- int
- WaitForTimer(tr,seconds,microseconds)
- ULONG seconds,microseconds;
- struct timerequest *tr;
- {
- tr->tr_node.io_Command = TR_ADDREQUEST; /* add a new timer request */
- tr->tr_time.tv_secs = seconds; /* seconds */
- tr->tr_time.tv_micro = microseconds; /* microseconds */
- DoIO( tr ); /* post request to the timer */
- /* goes to sleep till done */
- return(0);
- }
-
- int
- SetNewTime(day,min,sec)
- LONG day, min,sec; /* days since 1 Jan 78 plus minutes */
- {
- struct timerequest *tr;
- tr = PrepareTimer(TRUE); /* MUST use Precise timer for this */
- if(tr == 0) return(-1); /* non zero return says error */
-
- tr->tr_node.io_Command = TR_SETSYSTIME;
- tr->tr_time.tv_secs = (24 * 60 * 60 * day) + (60 * min) + sec;
- tr->tr_time.tv_micro = 0;
- DoIO( tr );
-
- DeleteTimer(tr);
- return(0);
- }
-
-
- int
- GetSysTime(tv)
- struct timeval *tv;
- {
- struct timerequest *tr;
- tr = PrepareTimer(TRUE); /* MUST use Precise timer for this */
- if(tr == 0) return(-1); /* non zero return says error */
-
- tr->tr_node.io_Command = TR_GETSYSTIME;
- DoIO( tr );
-
- tv->tv_secs = tr->tr_time.tv_secs;
- tv->tv_micro = tr->tr_time.tv_micro;
-
- DeleteTimer(tr);
- return(0);
-
- }
-
- int
- DeleteTimer(tr)
- struct timerequest *tr;
- {
- struct MsgPort *tp;
-
- tp = tr->tr_node.io_Message.mn_ReplyPort;
- if(tr != 0)
- {
- CloseDevice(tr);
- DeleteExtIO(tr,sizeof(struct timerequest));
- }
- if(tp != 0)
- DeletePort(tp);
- return(0);
- }
-
-
-
- /***********************************************************************
- *
- * Exec Support Function -- Extended IO Request
- *
- ***********************************************************************/
-
- extern APTR AllocMem();
-
- /****** exec_support/CreateExtIO **************************************
- *
- * NAME
- * CreateExtIO() -- create an Extended IO request
- *
- * SYNOPSIS
- * ioReq = CreateExtIO(ioReplyPort,size);
- *
- * FUNCTION
- * Allocates memory for and initializes a new IO request block
- * of a user-specified number of bytes.
- *
- * INPUTS
- * ioReplyPort - a pointer to an already initialized
- * message port to be used for this IO request's reply port.
- *
- * RESULT
- * Returns a pointer to the new block. Pointer is of the type
- * struct IORequest.
- *
- * 0 indicates inability to allocate enough memory for the request block
- * or not enough signals available.
- *
- * EXAMPLE
- * struct IORequest *myBlock;
- * if( (myBlock = CreateExtIO(myPort,sizeof(struct IOExtTD)) == NULL)
- * exit(NO_MEM_OR_SIGNALS);
- *
- * example used to allocate space for IOExtTD (trackdisk driver
- * IO Request block for extended IO operations).
- *
- * SEE ALSO
- * DeleteExtIO
- *
- ***********************************************************************/
-
- struct IORequest *CreateExtIO(ioReplyPort,size)
- struct MsgPort *ioReplyPort;
- LONG size;
- {
- struct IORequest *ioReq;
-
- if (ioReplyPort == 0)
- return ((struct IORequest *) 0);
-
- ioReq = (struct IORequest *)AllocMem (size, MEMF_CLEAR | MEMF_PUBLIC);
-
- if (ioReq == 0)
- return ((struct IORequest *) 0);
-
- ioReq -> io_Message.mn_Node.ln_Type = NT_MESSAGE;
- ioReq -> io_Message.mn_Node.ln_Pri = 0;
-
- ioReq -> io_Message.mn_ReplyPort = ioReplyPort;
-
- return (ioReq);
- }
-
- /****** exec_support/DeleteExtIO **************************************
- *
- * NAME
- * DeleteExtIO() - return memory allocated for extended IO request
- *
- * SYNOPSIS
- * DeleteExtIO(ioReq,size);
- *
- * FUNCTION
- * See summary line at NAME. Also frees the signal bit which
- * had been allocated by the call to CreateExtIO.
- *
- * INPUTS
- * A pointer to the IORequest block whose resources are to be freed.
- *
- * RESULT
- * Frees the memory. Returns (no error conditions shown)
- *
- * EXAMPLE
- * struct IORequest *myBlock;
- * DeleteExtIO(myBlock,(sizeof(struct IOExtTD)));
- *
- * example shows that CreateExtIO had been used to create a trackdisk
- * (extended) IO Request block.
- *
- * SEE ALSO
- * CreateExtIO
- *
- **************************************************************************/
-
- DeleteExtIO(ioExt,size)
- struct IORequest *ioExt;
- LONG size;
- {
- ioExt -> io_Message.mn_Node.ln_Type = 0xff;
- ioExt -> io_Device = (struct Device *) -1;
- ioExt -> io_Unit = (struct Unit *) -1;
-
- FreeMem (ioExt, size);
- }
-