www.riscos.com Technical Support: |
|
There are two basic aspects of time dealt with in this chapter: passive aspects such as reading various clock settings; and active ones, where an event occurs when a given time is reached. In this chapter, a clock is a place where a stored value is incremented on a regular basis. The time is the name of the value as it is read or written.
There are several clocks that increment every 1/100th of a second (centisecond). One of them cannot be changed except by a hard reset. This is useful for time-stamping events, such as mouse moves. Another can be changed by a program, so is useful for elapsed time calculations.
The real-time clock keeps the real-world time, and represents time in centiseconds since 00:00:00 on January 1 1900. There are calls to present this information in a number of ways. The real-time can be converted to a string with complete program control over its format.
A variety of timer events can be set up. There are SWIs that will call your application after a given delay has passed or every time that delay has elapsed. You can set up a routine to sit on the ticker vector, to enable it to be called every centisecond.
A specialised form of timer event is one that will occur every time the screen driving hardware reaches the bottom of the screen. This event is useful for flicker-free redrawing. See the chapter entitled VDU Drivers for further details.
A monotonic timer cannot be written, except by a hard reset or when the machine is turned on. OS_ReadMonotonicTime allows you to read this value. It is useful for time-stamping within an application, such as event times. Because it can never be changed, the order of events cannot be confused.
It is stored as a 4-byte value with least significant byte first. It is incremented every centisecond, which means that it would take nearly 500 days for it to wrap around.
The real-time clock is stored as a 5-byte value in the CMOS clock chip and reflects the normal usage of the word clock. That is, it stores the elapsed number of centiseconds since 00:00:00 on January 1 1900. You can set it using the Alarm application on the desktop.
Under RISC OS 2 the real-time clock is assumed to be set to local time. Under later versions, the real-time clock is assumed to be set to UTC, or Universal Time Coordinated. (This used to be called GMT, or Greenwich Mean Time.) Territory modules provide the necessary information for the kernel to convert the real-time clock value to a local time in a suitable format.
A soft copy of the real time clock is also kept by RISC OS and is used by the filing system to date-stamp files. This soft copy is updated from the CMOS clock chip following a hard reset.
*Time displays the local time and date as a string. It calls OS_Word 14,0 to do so. The format of the string depends on the territory which the computer is set to use. (It is fixed in RISC OS 2, which does not support territories.) For example:
Tue,28 Mar 1989.13:25:54
The real-time clock can be read in the standard 5-byte format using OS_Word 14,3. This, or any, 5-byte time can be converted into a string using OS_ConvertStandardDateAndTime or OS_ConvertDateAndTime.
The real-time clock's time of day can be altered with OS_Word 15,8, its date with OS_Word 15,15, or both with OS_Word 15,24. These calls all use the time in a string format (see above).
For most of the above calls the time string is passed or returned in a fixed, call-dependent format. However, for some calls you can customise the way that the time and date is presented by supplying a format string. The string is copied character for character to the output buffer unless a '%' is found. If this character is followed by any of the following codes - which may be in upper or lower case - then the appropriate value is copied to the output buffer:
Name | Value | Examples (UK) |
---|---|---|
CS | Centiseconds | 99 |
SE | Seconds | 59 |
MI | Minutes | 05 |
12 | Hours in 12 hour format | 07 |
24 | Hours in 24 hour format | 23 |
AM | AM or PM indicator (in local language) | PM |
PM | AM or PM indicator (in local language) | AM |
WE | Weekday - full (in local language) | Thursday |
W3 | Weekday - short (in local language) | Thu |
WN | Weekday - number | 5 |
DY | Day of the month (in local language) | 01 |
ST | Ordinal pre/suffix (in local language) | st nd rd th |
MO | Month name - full (in local language) | September |
M3 | Month name - short (in local language) | Sep |
MN | Month - number | 09 |
CE | Century | 19 |
YR | Year within century | 87 |
WK | Week of year (using local start of week) | 52 |
DN | Day of the year | 364 |
TZ | Timezone | BST |
0 | Insert an ASCII 0 zero byte | |
% | Insert a '%' |
You must not make any assumptions about the nature or length of any fields that use the local language. For example: short forms of the weekday or month are three characters long in the UK territory, but may have a different length in other territories; the day of the month may not be numeric; ordinals may be null; and so on. However, you can find out the maximum length of fields for your territory by calling Territory_ReadCalendarInformation.
To cause leading zeros to be omitted, prefix the field with the letter 'Z'. For example, '%zmn' means the month number without leading zeros. '%0' may be used to split the output into several zero-terminated strings.
As an example, this format string:
would produce this time string in the UK territory:
OS_ConvertDateAndTime will convert a 5-byte time into a string using a supplied format string.
The CMOS clock chip stores the time internally in a Binary Coded Decimal (BCD) format. OS_Word 14,1 will read the time as a 7-byte BCD block. OS_Word 14,2 will convert this BCD block into a string. These calls are provided for compatibility only, and you should not use them.
There are three different causes of timer events: the interval timer, the timer chain and the VSync timer. You should not use these under the Wimp, as you cannot guarantee that your task will be paged in at the time of the event.
The interval timer is a 5-byte clock that increments every centisecond. If enabled by OS_Byte 14, an event will occur when the counter reaches zero. Thus to wait for a given time, the interval timer must be set to the negative of it using OS_Word 4. OS_Word 3 can read the current setting of the interval timer.
For example, to wait 10 seconds, -1000 must be passed to OS_Word 4.
The interval timer is kept for compatibility with earlier Acorn operating systems. Its use should be avoided if possible. It is especially important that this is not used under the Wimp, since it cannot cope with more than one program using it at once.
An easier to use and more sophisticated way for an application to be called at a given time is the timer chain. These are independent of event routines, but are used in a similar manner. OS_CallAfter can be used to get a given address to be called after a certain time has elapsed. OS_CallEvery is like this, but automatically reloads the counter when it has expired. OS_RemoveTickerEvent will cancel either OS_CallAfter before it occurs or OS_CallEvery to stop it repeating forever.
OS_CallAfter and OS_CallEvery are passed an address to call, the delay to wait and an identification word to return in R12. Thus, many timers can be running concurrently.
These are stored in a list which can be any size up to the machine memory limit.
The screen is refreshed at a mode-dependent rate: typically from 50Hz (standard monitor type modes) to 70Hz or more (particularly with VGA or Super VGA monitor modes). From the time that the bottom of the screen is complete till the top of the screen commences again is a delay called the Vertical sync period. This allows the electron beam to go to this start position. The Vertical sync event coincides with the vertical sync beginning. You can use OS_Byte 14 to enable this event, so that flicker-free re-drawing can be done while the VDU is not being written to.
OS_Byte 176 provides access to a one byte counter that decrements at the rate of the Vertical sync event. Because the rate of this timer varies, you should not use it for running timing loops for games, music, etc.
OS_Byte 243 reads a temporary location used by the timer software. It is kept for compatibility with earlier Acorn operating systems and must not be used.
Read/write 50Hz counter
R0 = 176
R1 = 0 to read or new value to write
R2 = 255 to read or 0 to write
R0 preserved
R1 = value before being overwritten
R2 corrupted
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
The value stored is changed by being masked with R2 and then exclusive ORd with R1: ie ((value AND R2) XOR R1). This means that R2 controls which bits are changed and R1 supplies the new bits.
This call reads or writes a one-byte counter which is decremented at the rate of the Vertical sync interrupt. This rate is mode and monitor dependent, typically in the range 50 - 70Hz, Consequently you should not use this timer for precise timing loops.
None
ByteV
Read timer switch state
R0 = 243
R1 = 0
R2 = 255
R0 preserved
R1 = switch state
R2 corrupted
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
In order to protect the centisecond clock against corruption during reset, the OS keeps two copies. One of them is the one which will be read or written when one of the OS_Words is called, the other is the one which will be updated during the next 100Hz interrupt. When the update has been performed correctly, the values are swapped. This OS_Byte enables you to read the byte which indicates which copy is being used. Its only practical use is as a location which changes 100 times a second.
This call is obsolete and should not be used.
ByteV
R0 = 1
R1 = pointer to five byte block
R0, R1 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On exit, the parameter block contains the value of the system clock at the instant of the call.
The clock is incremented every centisecond. The value of the clock is preserved over a soft break and set to zero after a hard break.
WordV
R0 = 2
R1 = pointer to five byte block with centisecond clock value in it
R0, R1 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On entry, the parameter block contains the value to set the system clock.
This allows the clock to be set to a specified value.
WordV
R0 = 3
R1 = pointer to five byte block
R0, R1 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On exit, the parameter block contains the value of the interval timer at the instant of the call.
WordV
R0 = 4
R1 = pointer to five byte block
R0, R1 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On entry, the parameter block contains the value to set the interval timer.
This call resets the interval timer to a specified value.
Like the system clock, the interval timer is incremented 100 times a second. The interval timer can be made to cause an event when its value reaches zero. To do this, it must be set to minus the number of centiseconds that are to elapse before the event takes place.
To produce repeated events, the routine servicing the timer event should reload the timer with the appropriate number. For example, to produce an event every 10 seconds, reload it with -1000 (&FFFFFFFC18). An alternative is to use the special ticker event, described in the Events.
Note that you must use OS_Byte 14 to enable the interval timer event.
WordV
Read soft copy of the real-time clock as a string, converting to local time
R0 = 14
R1 = pointer to parameter block
R0, R1 preserved
Interrupts are enabled (in RISC OS 2, the interrupt status is not altered)
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On exit, the parameter block contains the local time as a string terminated by a Return character (ASCII 13). The format of the string depends on the territory which the computer is set to use. (It is fixed in RISC OS 2, which does not support territories.)
This time string comes from the soft copy of the real-time clock maintained by RISC OS, rather than from the CMOS clock chip itself.
This call is equivalent to the *Time command.
WordV
Read time in Binary Coded Decimal (BCD) format, converting to local time
R0 = 14
R1 = pointer to parameter block
R0, R1 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On exit, the parameter block contains a seven-byte BCD clock value:
R1 + 0 = year | (00 - 99) |
R1 + 1 = month | (01 - 12; 01 = January etc) |
R1 + 2 = day of month | (01 - 31) |
R1 + 3 = day of week | (01 - 07; 01 = Sunday etc) |
R1 + 4 = hours | (00 - 23) |
R1 + 5 = minutes | (00 - 59) |
R1 + 6 = seconds | (00 - 59) |
Under RISC OS 2 the clock value is read directly from the CMOS real time clock chip, which is assumed to be set to local time, and so the value is not further converted. Under later versions of RISC OS the clock is read from a soft copy of the real time, which is assumed to be set to UTC, and so the value is then converted to local time.
WordV
R0 = 14
R1 = pointer to parameter block
R1 + 0 = 2 | reason code |
R1 + 1 = year | (00 - 99) |
R1 + 2 = month | (01 - 12; 01 = January etc) |
R1 + 3 = day of month | (01 - 31) |
R1 + 4 = day of week | (01 - 07; 01 = Sunday etc) |
R1 + 5 = hours | (00 - 23) |
R1 + 6 = minutes | (00 - 59) |
R1 + 7 = seconds | (00 - 59) |
R0, R1 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On entry, the parameter block contains a 7-byte BCD clock value:
On exit, the parameter block contains a string terminated by a Return character (ASCII 13), representing the same time. The format of the string depends on the territory which the computer is set to use. (It is fixed in RISC OS 2, which does not support territories.)
WordV
R0 = 14
R1 = pointer to parameter block
R0 preserved
R1 preserved:
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
On exit the parameter block contains the 5-byte real time read directly from the soft copy of the real-time clock. This number gives the elapsed number of centiseconds since 00:00:00 on January 1 1900. Under RISC OS 2 the real-time clock is assumed to be set to local time; under later versions the real-time clock is assumed to be set to UTC.
This 5-byte real-time is used for time/date stamping by the filing system. It is also useful for utilities which are used for building consistent systems, eg 'Make'.
WordV
Writes the time of day to both the CMOS clock and its soft copy
R0 = 15
R1 = pointer to parameter block
R0, R1 preserved.
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call writes the time of day to both the CMOS clock and its soft copy.
On entry, the parameter block contains the local time of day as a string; the format this string must have depends on the territory which the computer is set to use. (It is fixed in RISC OS 2, which does not support territories.)
The format for the UK territory (and for RISC OS 2) is:
HH:MM:SS eg 17:35:04
WordV
Writes the date to both the CMOS clock and its soft copy
R0 = 15
R1 = pointer to parameter block
R0, R1 preserved
The C flag will be set on exit, if the parameter block contained a format error
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call writes the date to both the CMOS clock and its soft copy.
On entry, the parameter block contains the local date as a string; the format this string must have depends on the territory which the computer is set to use. (It is fixed in RISC OS 2, which does not support territories.)
The format for the UK territory (and for RISC OS 2) is:
Day,DD MMM YYYY eg Mon,17 Feb 1992
WordV
Writes the time of day and date to both the CMOS clock and its soft copy
R0 = 15
R1 = pointer to parameter block
R0, R1 preserved
The C flag will be set on exit, if the parameter block contained a format error.
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
Not defined
This call writes the time of day and date to both the CMOS clock and its soft copy.
On entry, the parameter block contains the local time of day and date as a string; the format this string must have depends on the territory which the computer is set to use. (It is fixed in RISC OS 2, which does not support territories.)
The format for the UK territory (and for RISC OS 2) is:
Day,DD MMMYYYY.HH:MM:SS eg Mon,17 Feb 1992.17:35:04
R0 = time in centiseconds
R1 = address to call
R2 = value of R12 to call code with
R0 - R2 preserved
Interrupts are disabled
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
OS_CallAfter calls the code pointed to by R1 after the delay specified in R0. The code is called in SVC mode with interrupts disabled. It must preserve all registers, and return using the instruction MOV R15, R14.
OS_RemoveTickerEvent can be used to cancel a pending OS_CallAfter
In RISC OS 2 this call may return incorrect error pointers. An invalid value of R0 now generates the error message 'Invalid time interval', rather than the null string generated by RISC OS 2.
None
Call a specified address every time a delay elapses
R0 = (delay in centiseconds) - 1
R1 = address to call
R2 = value of R12 to call code with
R0 - R2 preserved
Interrupts are disabled
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
OS_CallEvery calls the code pointed to by R1 every (R0+1) centiseconds, until OS_RemoveTickerEvent is executed or Break is pressed. The code is called in SVC mode with interrupts disabled. It must preserve all registers, and return using the instruction MOV R15, R14.
The minimum value for R0 is 1, which means the minimum possible delay is 2 centiseconds. If you wish to be called every centisecond, you must instead claim TickerV.
In RISC OS 2 this call may return incorrect error pointers. An invalid value of R0 now generates the error message 'Invalid time interval', rather than the null string generated by RISC OS 2.
None
Remove a given call address and R12 value from the ticker event list
R0 = call address
R1 = value of R12 used in OS_CallEvery or OS_CallAfter
R0, R1 preserved
Interrupts are disabled
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
OS_RemoveTickerEvent takes R0 as the address and R1 as the R12 value of the event to find and remove from its list.
It is used to stop an event set up by a call to OS_CallAfter or OS_CallEvery. The parameters passed must match those originally passed to OS_CallEvery or OS_CallAfter for it to remove the correct event.
Note: You cannot use this call to remove a ticker event from within that event's own code. Instead, your ticker event must call OS_AddCallBack to add a transient CallBack that makes the call to OS_RemoveTickerEvent.
--
R0 = time in centiseconds
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
OS_ReadMonotonicTime returns the number of centiseconds since the last hard reset, or switching on of the machine. 'Monotonic' refers to the fact that this timer is guaranteed to change with time (increasing until it wraps around). It is used, for example, to time-stamp mouse events.
None
None
R0 = pointer to 5-byte time block
R1 = pointer to buffer for resulting string
R2 = size of buffer
R0 = pointer to buffer (R1 on entry)
R1 = pointer to terminating zero in buffer
R2 = number of free bytes in buffer
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
OS_ConvertStandardDateAndTime converts a five-byte value representing the number of centiseconds since 00:00:00 on January 1st 1900 into a string. It converts it using a standard format string stored in the system variable 'Sys$DateFormat' and places it in a buffer (which should be at least 20 bytes).
For details of the format field names see the chapter entitled Format field names.
From RISC OS 3 onwards this SWI simply calls Territory_ConvertStandardDateAndTime, which you should use instead.
None
Convert 5-byte time into a string using a supplied format string
R0 = pointer to 5-byte time block
R1 = pointer to buffer for resulting string
R2 = size of buffer
R3 = pointer to format string (null terminated)
R0 = pointer to buffer (R1 on entry)
R1 = pointer to terminating zero in buffer
R2 = number of free bytes in buffer
R3 preserved
Interrupt status is not altered
Fast interrupts are enabled
Processor is in SVC mode
SWI is re-entrant
OS_ConvertDateAndTime converts a five byte value representing the number of centiseconds since 00:00:00 on January 1st 1900 into a string. It converts it using the format string supplied.
Apart from the following exception, the format string is copied directly into the result buffer. However, whenever '%' appears in the format string, the next one or two characters are treated as a special field name which is replaced by a component of the current time.
For details of the format field names see the chapter entitled Format field names.
From RISC OS 3 onwards this SWI simply calls Territory_ConvertDateAndTime, which you should use instead.
None
*Time displays the day, date and time of day. It is displayed in the same format as OS_Word 14,0.
None
OS_Word 14,0, OS_Word 15, OS_ConvertStandardDateAndTime,
OS_ConvertDateAndTime, Territory_ConvertDateAndTime, Territory_ConvertStandardDateAndTime