RISCOS.com

www.riscos.com Technical Support:
Timecode User Guide

 

2. Acorn TimeCode Programmer's Guide


Please refer to Data Formats for an explanation of the data structures described as register parameters in this section.

Programmer's Interface

TimeShareV

TimeShareV is vector number &27.

TimeShareV entry for a recurrent schedule

R0 = b31:b8 flags, b7:b0 reason code (reason code = 0)
R1 = new time data word

Any clients interested in this call should use their interrupt schedule handle as a pointer to a word which they check for bit 30 being set. If it is, this indicates that this client is one of those who requested a vector call at this time.

Always pass this vector on.

TimeShareV entry for time modified

R0 = b31:b8 flags, b7:b0 reason code (reason code = 1)
R1 = number of requesters of this call
R2 = new time data word

Each client should decrement R1. When R1 reaches 0 the call should be claimed.

Wimp Messages

The WimpMessage number is the same as the SWI base, i.e. &4B540.

WimpMessage_TimeShare

block
+16 Message number (TimeShare_SWIBase)
+20 subreason

Subreason 0 - TimeShare system component dying/starting

+20 0
+24 flags (as R0 of service)
+28 Clock/Clock Transmitter number, or 0

(This is sent by the TimeShare module upon receipt of the service call, or with foreknowledge of its own death, to inform any applications about the change in system status. Note that TimeShare will not be an active wimp task - so this message will be sent as an unrecorded broadcast. You should not acknowledge the message, since this would stop any other interested clients receiving it).

Any programs which receive this call, and have been using the facility provided by TimeShare_ReadTimeAddress, should call TimeShare_Deregister to acknowledge that they will not read memory directly any more.

TimeShare will only die if it has no outstanding clients of the time data word's address once this wimp message and the service call have been sent.

Subreason 1 - Clock(Transmitter)Control SWI called by application

+20 1
+24 SWI number (_ClockControl or _ClockTransmitterControl)
+28 R0 of SWI
+32 R2 of SWI
+36 R3 of SWI (or 0 if R3 not used)

This message should be broadcast by any application (or module code) after calling SWI _ClockControl or SWI _ClockTransmitterControl successfully to change the timecode system configuration (if the SWI call fails due to an error then the message should not be sent). Note that it is not automatically generated by the TimeShare module.

This message is intended to allow applications which show the status of the system (e.g. !TimeShare) to update their displays - they may either take the information in the message and act on it directly, or use the message as a cue to interrogate the environment again. The message does not need to be sent for ClockControl subreason 5 - Set Clock, since any monitoring applications will see the change in the time anyway.

Wimp Pollword

Since it's possible that an application may want to have more than one pollword routine scheduled, the value stored in the nominated pollword to make it non-zero will be the interrupt schedule handle returned when it was scheduled.

SWI calls

The SWI call chunk begins at &4B540, with errors in a block starting at &80DD00.

All SWIs are marked with b7:b0 for internal use.

TimeShare_ReadCurrentClock (TimeShare_SWIBase + &00)

InR0= b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
OutR0= -1 for no current clock, or number of current clock source:
0 Internal
1 MIDI
2 (and above) reserved
R1= 0 if no current clock, or frame rate identifier giving current input fps rate (no flag bits set)

Note: This number applies to both the Clock and Clock Transmitter aspects of a given transport medium, even though both may not exist.

Errors: A Clock or Clock Transmitter has too high an identity number

TimeShare_ReadActiveClockTransmitters (TimeShare_SWIBase + &01)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
OutR0 => read-only data stucture
0 number of words following in structure
4 bit field for clock transmitters 0-31 (bit 0 = CT 0)
8 bit field for clock transmitters 32-63 (bit 0 = CT 32) etc.
A bit clear = inactive
A bit set = active

This structure may only be modified by the TimeShare module.

Errors: A Clock or Clock Transmitter has too high an identity number

TimeShare_ReadAvailableClocks (TimeShare_SWIBase + &02)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
OutR0 => read-only data structure
0 number of words following in structure
4 bit field for clocks 0-31 (bit 0 = CK 0)
8 bit field for clocks 32-63 (bit 0 = CK 32) etc
A bit clear = not present
A bit set = present

This structure may only be modified by the TimeShare module.

Errors: A Clock or Clock Transmitter has too high an identity number

TimeShare_ReadAvailableClockTransmitters (TimeShare_SWIBase + &03)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
OutR0 => read-only data structure
0 number of words following in structure
4 bit field for clocks 0-31 (bit 0 = CT 0)
8 bit field for clocks 32-63 (bit 0 = CT 32) etc
A bit clear = not present
A bit set = present

This structure may only be modified by the TimeShare module.

Errors: none

TimeShare_InterruptSchedule (TimeShare_SWIBase + &04)

InR0 = b31: set - this is a high priority interrupt
b30:b29 flags - reserved (internal use)
b28: set - this is a one-shot interrupt
b27:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1 = 0, or interrupt schedule handle to modify
R2 = interrupt rate in 0.5uS (Timer1 ticks), minimum is 0.5555ms, maximum is &FFFFFFF. 0 cancels the schedule
R3 = data word to associate with this schedule slot (see interrupt and timecodeV call specs for usage)
R4 = address to call
Out(success)
R1 = interrupt schedule handle allocated or quoted
R0 (b31:b8), R2 - R4 preserved

Errors: R0 points to error block, R1-R4 preserved

Invalid Interrupt Schedule Handle
Outside range, or not active for modification
Interrupt rate is out of range
Too fast, or too slow
Interrupt Schedule List Full

Notes: Calling with R1=0 and R2=0 is invalid, and will produce an Invalid Interrupt Schedule Handle error on the assumption that cancelling an interrupt is the intended result.

The Interrupt Schedule Handle should be regarded as a pointer to a flags word which may be interrogated under certain situations (primarily within a vector routine to check whether you are one of the clients this particular vector call is intended for). It should not be modified in any way.

This call can be used to change the rate of a running interrupt.

The high priority bit should only be set for interrupts which are to be used to update the TimeShare time data word (i.e. Clocks).

This bit is used by the interrupt scheduler to ensure that when two or more scheduled events occur together the most important one gets called first (e.g. updating the time data word before other interrupts to send it).

A one-shot interrupt will trigger once, after the interval specified as the interrupt rate and then to deactivate itself. There is no need to cancel a one-shot interrupt - the cancellation is automatic when it triggers.

TimeShare_PollWordSchedule (TimeShare_SWIBase + &05)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1: 0, or interrupt schedule handle to modify
R2: interrupt rate in 0.5uS (Timer 1 ticks), limits as above
R3: address of pollword
OutR1: interrupt handle schedule allocated or preserved

Notes:Errors and notes as above

TimeShare_TimeShareVSchedule (TimeShare_SWIBase + &06)

(To schedule a recurrent call)
InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1: 0, or interrupt schedule handle to modify
R2: interrupt rate in 0.5uS (Timer 1 ticks), limits as above

(To request a TimeShareV call on each update)
InR1: -1
R2: -1 to request, 0 to remove request
Out
(recurrent call)
R1: interrupt handle schedule allocated or preserved
(each update) R1: number of requests currently made

Notes: The call on each update facility does not provide individual identification of the originator since one call to TimeShareV is made for all requests.

Similarly, multiple recurrent schedules firing at the same time will also result in only one call - vector claimants should use their interrupt schedule handle as a pointer to a flags word to check to see whether bit 30 is set.

TimeShare_ClockTransmitterControl (TimeShare_SWIBase + &07)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R2: Frame rate identifier, or 0 to disable, or -1 to read current frame rate
R3: Clock Transmitter number
OutR2: returns frame rate identifier if R2=-1 on entry, otherwise all registers preserved unless an error is returned.

Errors: Clock Transmitter not present
Clock Transmitter does not support this frame rate
Clock Transmitter was not active

Notes: A frame rate identifier is:
bit31: set: drop frame
bit30: set: this is lowest frame rate possible
bit29: set: this is highest frame rate possible
bit28: set: this is not a rate, but fully variable from 0.5 to 1800fps
bit27:count down (Internal clock only)
bit26: Add 0.97fps (for 29.97fps)
bit25-bit11: reserved, set to 0
bit10-bit1: frame rate, max 1800, min 0.5 (with bit 0 set)
bit0 : set: add 0.5 fps

However, bits 30,29,28 may not be set when setting a frame rate.

This SWI may be used to enable, and disable a Clock Transmitter, and to read or change the frame rate of a Clock Transmitter.

TimeShare_ClockControl (TimeShare_SWIBase+&08)

In:R0: b31:b16 flags, all 0 and reserved
b15:b8 action 0: Select (automatically deselects previous)
1: Deselect
2: Set frame rate R3 = Frame rate identifier
3: Start clock
4: Stop clock
5: Set clock R3 = Time data word
6: Set speed (internal clock only) R3 = Frame rate identifier
R2: Clock number
R3: may be used, see R0
Out all preserved unless an error occurs

Errors: Clock not present
This is an external Clock which may not be adjusted in this manner
Undefined Action number

Notes: The automatic deselection when a select action is performed is achieved for the caller by the TimeShare module issuing a deselect action on the caller's behalf before acting on the select action.

Reason 6 may be used to set the Internal Clock to run at one frame rate, but to return time in another - e.g. setting a frame rate of 30fps, and setting a speed of 90 fps would result in 30fps running at 3 x real time. It is also possible to set the direction for time to run using bit 27 of the frame rate identifier. Setting a new frame rate with reason 3 cancels any effects imposed by reason 6 (i.e. the new frame rate will be running forwards at real time when the clock runs).

At first glance it may seem a little strange to use a Clock control interface to alter the time in the TimeShare system. This is done for several reasons.

  1. The individual Clock module is in the best place to know whether it can support adjustments to the time
  2. Most Clock modules have internal state to maintain, and need to know about a change
Time data word: Bits 31-26 Hours (0-23)
Bits 25-20 Minutes (0-59)
Bits 19-14 Seconds (0-59)
Bits 13-3 Frame count (0-1799)
Bits 2 Expanded format bit (set to 0 at present)
Bits 1-0 Status indication
Bit 1 0
Bit 0 0 Clock incrementing normally
Bit 0 1 Clock decrementing normally
Bit 1 0 New time
Bit 1 1 Clock Stopped (and may be a New time)

When used here bits 1 and 0 should not be set.

TimeShare_ReadTimeAddress (TimeShare_SWIBase+&09)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
OutR0: preserved
R1 -> Time data word in TimeShare module
R2: number of registered clients

Notes: This interface is provided to allow the fastest possible access for reading the time data word. It must not be modified.

The TimeShare module keeps count of the number of clients who have called this SWI for the address. When a client no longer wants to make use of the memory address it should call TimeShare_Deregister.

The TimeShare module will refuse to quit whilst this count is non-zero.

TimeShare_ReadTime (TimeShare_SWIBase+&0A)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1: 0, or frame rate identifier
OutR2: Time data word, with fps converted if R1<>0

Errors: Invalid frame rate

Notes:This may be used to either read the time data word, with no alteration or to read it after conversion to a specified frame rate. Obviously the call will return more quickly if no conversion is specified.

TimeShare_ConvertTimeToSpecified (TimeShare_SWIBase+&0B)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1: frame rate identifier
R2: time data word in 1800fps
OutR2: time data word, with fps converted to frame rate from R1

Errors: Invalid frame rate

Notes: This call is used to convert from internal 1800fps time to a specified rate. This call will be used under interrupts, and is therefore re-entrant.

TimeShare_ConvertTimeFromSpecified (TimeShare_SWIBase+&0C)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1: frame rate identifier
R2: time data word, with fps in frame rate from R1
OutR2: time data word in 1800fps

Errors: Invalid frame rate

Notes: This call is used to convert from a specified rate to internal 1800fps representation.This call will be used under interrupts, and is therefore re-entrant.

TimeShare_ReadClockInformation (TimeShare_SWIBase+&0D)

InR0 = b31 - internal use
b30:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R2: Clock number
OutR3 -> information structure

Errors: Clock Not Present

Notes: Clock/Clock Transmitter Information Structure:

0 Pointer to non word-aligned ascii name, zero terminated
4 Number of frame rate identifiers following
8 Frame rate identifier etc

(In this instance, a frame rate identifier may have the various flag bits set that are not allowed when specifying a frame rate, so allowing information about a range of settings to be expressed economically.)

For Clocks where the rate may not be changed by the computer (i.e. an external clock) the number of frame rate identifiers may be returned as zero.

TimeShare_ReadClockTransmitterInformation (TimeShare_SWIBase+&0E)

InR0 = b31 internal use
b30:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R2: Clock Transmitter number
OutR3 -> information structure

Errors: Clock Transmitter Not Present

Notes: Clock/Clock Transmitter Information Structure

0 Pointer to non word-aligned ascii name, zero terminated
4 Number of frame rate identifiers following
8 Frame rate identifier etc

(In this instance, a frame rate identifier may have the various flag bits set that are not allowed when specifying a frame rate, so allowing information about a range of settings to be expressed economically.)

TimeShare_InterpretFrameRateIdentifier (TimeShare_SWIBase+&0F)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
R1: frame rate identifier
R2 -> memory to put interpreted structure
R3: size of memory, or 0 to calculate size
OutR3: last byte used in memory if R3 <> 0 on entry
R3: number of bytes required if R3=0

Errors: Not enough space provided Illegal Frame Rate Identifier

Notes: This call has two modes of usage:

R2 - irrelevant and R3 = 0:

R3 will be returned with the size of memory needed. No data is stored anywhere.

R2 -> memory and R3 > 0:

data will be stored at R2 and R3 set to the last byte used.

This call is used to provided a localised string which may be used in building a menu or within a dialogue box.

Application developers should be cautious about simply calling this SWI for each frame rate identifier returned and then building a menu - this would be perfectly acceptable for three or four discrete frame rates, but not a range.

The strings returned will of course depend upon the locale in effect, but English ones could be:

24 fps
12.5 fps
29.97 fps
30 fps dropframe
From 20 fps to 1800 fps
From 0.5 fps to 1800 fps

As can be seen, the last three are of little use as potential menu selections. Instead, the application should provide a dialogue box allowing adjustment in 0.5fps between the low and high bounds.

TimeShare_Deregister (TimeShare_SWIBase+&10)

InR0 = b31:b8 flags - none defined, all bits reserved
b7:b0 - for internal use, set to 0
OutR0: updated count of clients of TimeShare_ReadTimeAddress

Notes: This SWI is used to tell the TimeShare module that a client which has previously read the address of the time data word will no longer need to use it.

The TimeShare module will refuse to die whilst the count of clients is non-zero, so it is important that this SWI is used!

Internal Clock Transmitter

Since the functionality of the Internal Clock Transmitter is actually presented to the user by two specialised SWIs, it does not appear as a standard Clock Transmitter when all available Clock Transmitters are interrogated.

Error messages

0x80dd00ErrSchFull: Interrupt schedule list is full
0x80dd01ErrBadHan: Bad interrupt schedule handle
0x80dd02ErrBadInt: Bad interrupt interval
0x80dd03ErrBadFrame: Invalid frame rate
0x80dd04ErrWrongSize: Not enough space provided
0x80dd05ErrTooMany: A Clock or Clock Transmitter has too high an identity number
0x80dd06ErrCNotFound: The Clock or Clock Transmitter specified is not available
0x80dd07ErrBadCC: Undefined action number
0x80dd08ErrIllCC: This is an external clock which may not be adjusted in this manner
0x80dd09ErrNotActive: This Clock Transmitter is not active
0x80dd0aErrStillInUse: The module cannot die until all clients have deregistered
0x80dd0bErrWrongClock: You must select this Clock first

Note: The localised form of these errors may still vary.

Data Formats

The following data structures are available through the API.

Clock/Clock Transmitter Information Structure

+0 wordPointer to non word-aligned ascii name, zero terminated
+4 wordNumber of frame rate identifiers following
+8 wordFrame rate identifier etc

See Frame Rate Identifiers.

The name pointer is localised - any future Clocks/Clock Transmitter which need to localise their name (as opposed to an universal name like MIDI) should use a message file of their own and look up the localised name.

Frame Rate Identifiers

This is a single word, combining numerical information about a frame rate with other information to aid expressing a range of values.
bit31: set: drop frame
bit30: set: this is lowest frame rate possible
bit29: set: this is highest frame rate possible
bit28: set: this is not a rate, but continuously variable from 0.5 to 1800fps
bit27: set: count down rather than (see SWI _ClockControl:6)
bit26: set: add 0.97fps (for 29.97fps)
bit25-bit12: reserved, set to 0
bit11-bit1: frame rate, max 1800, min 0.5 (with bit 0 set)
bit0 : set: add 0.5 fps

This word is also used to set a frame rate, but various flag bits may not be set.

Time Data Word

This is the internal time representation in 1800 fps.
Bits 31-26Hours (0-23)
Bits 25-20Minutes (0-59)
Bits 19-14Seconds (0-59)
Bits 13-3Frame count (0-1799)
Bit 2Expanded format bit (set at 0)
Bits 1-0Status indication
Bit 0 0
Bit 0 1
Bit 1 0
Bit 1 1
Clock incrementing normally
Clock decrementing normally
New time
Clock Stopped (and may be a New time)

Notes: Bit 2 is reserved for indicating the format of the time data word. While it is clear the format above is in use. Whenever it is set, some future (probably multi-word) format is in use instead - any applications which wish to act upon the structure of the time data word should check bit 2 is clear before applying their current understanding of the word's usage.

Data Structure for Available Clocks and Available/Active Clock Transmitters

This is an internal data structure within the TimeShare module, which other components in the TimeCode system may modify. It is also available through the API, but must not be directly modified.
+0 wordnumber of words following in structure
+4 wordbit field for clocks/clock transmitters 0-31 (bit 0 = CT 0)
+8 wordbit field for clocks/clock transmitters 32-63 (bit 0 = CT 32) etc

A bit set in the bit field indicates that the component concerned is active, or available, as appropriate.

NB: It should be noted that nobody should make ANY assumptions about this. Future versions of the TimeShare module may well size this dynamically.

Following Industry Conventions

Materials should start at 01:00:00:00 rather than 00:00:00:00 to allow a 'pre-roll' sequence. The convention in the film and video industry is:

hh:mm:ss:ff

00:58:00:00 black and silence
00:58:30:00 bars/tone in
00:59:30:00 bars/tone out
00:59:40:00 slate
00:59:50:00 ten second countdown
01:00:00:00 fade from black, programme start

For more details refer to 'Audio Production Techniques for Video' by D. M. Huber, Focal Press, ISBN 0-240-80148-2.

This edition Copyright © 3QD Developments Ltd 2015
Last Edit: Tue,03 Nov 2015