2
This file is part of the Free Pascal run time library.
4
A file in Amiga system run time library.
5
Copyright (c) 1998-2003 by Nils Sjoholm
6
member of the Amiga RTL development team.
8
See the file COPYING.FPC, included in this distribution,
9
for details about the copyright.
11
This program is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15
**********************************************************************}
20
Added functions and procedures with array of const.
21
For use with fpc 1.0.7. They are in systemvartags.
24
Added the defines use_amiga_smartlink and
25
use_auto_openlib. Implemented autoopening of the
29
Changed integer > smallint,
31
Changed startcode for unit.
34
nils.sjoholm@mailbox.swipnet.se
37
{$I useamigasmartlink.inc}
38
{$ifdef use_amiga_smartlink}
40
{$endif use_amiga_smartlink}
47
{***************************************************************************}
50
{ realtime.library's idea of time is based on a clock which emits a pulse
51
* 1200 times a second (1.2kHz). All time values maintained by realtime.library
52
* are based on this number. For example, the field RealTimeBase->rtb_Time
53
* expresses an amount of time equivalent to (RealTimeBase->rtb_Time/TICK_FREQ)
59
{***************************************************************************}
62
{ Each Conductor represents a group of applications which wish to remain
63
* synchronized together.
65
* This structure must only be allocated by realtime.library and is
69
pConductor = ^tConductor;
73
cdt_Players : tMinList; { this conductor's players }
74
cdt_ClockTime, { current time of this sequence }
75
cdt_StartTime, { start time of this sequence }
76
cdt_ExternalTime, { time from external unit }
77
cdt_MaxExternalTime, { upper limit on sync'd time }
78
cdt_Metronome : ULONG; { MetricTime highest pri node }
80
cdt_Flags : WORD; { conductor flags }
81
cdt_State : Byte; { playing or stopped }
85
{ Flag bits for Conductor.cdt_Flags }
86
CONDUCTF_EXTERNAL = 1; { clock is externally driven }
87
CONDUCTF_GOTTICK = 2; { received 1st external tick }
88
CONDUCTF_METROSET = 4; { cdt_Metronome filled in }
89
CONDUCTF_PRIVATE = 8; { conductor is private }
91
CONDUCTB_EXTERNAL = 0;
93
CONDUCTB_METROSET = 2;
96
{ constants for Conductor.cdt_State and SetConductorState() }
97
CONDSTATE_STOPPED = 0; { clock is stopped }
98
CONDSTATE_PAUSED = 1; { clock is paused }
99
CONDSTATE_LOCATE = 2; { go to 'running' when ready }
100
CONDSTATE_RUNNING = 3; { run clock NOW }
102
{ These do not actually exist as Conductor states, but are used as additional
103
* arguments to SetConductorState()
105
CONDSTATE_METRIC = -1; { ask high node to locate }
106
CONDSTATE_SHUTTLE = -2; { time changing but not running }
107
CONDSTATE_LOCATE_SET = -3; { maestro done locating }
110
{***************************************************************************}
113
{ The Player is the connection between a Conductor and an application.
115
* This structure must only be allocated by realtime.library and is
123
pl_Reserved1 : Shortint;
124
pl_Hook : pHook; { player's hook function }
125
pl_Source : pConductor; { pointer to parent context }
126
pl_Task : pTask; { task to signal for alarm }
127
pl_MetricTime : Longint; { current time in app's metric }
128
pl_AlarmTime : Longint; { time to wake up }
129
pl_UserData : Pointer; { for application use }
130
pl_PlayerID : WORD; { for application use }
131
pl_Flags : WORD; { general Player flags }
135
{ Flag bits for Player.pl_Flags }
136
PLAYERF_READY = 1; { player is ready to go! }
137
PLAYERF_ALARMSET = 2; { alarm is set }
138
PLAYERF_QUIET = 3; { a dummy player, used for sync }
139
PLAYERF_CONDUCTED = 8; { give me metered time }
140
PLAYERF_EXTSYNC = 16; { granted external sync }
143
PLAYERB_ALARMSET = 1;
145
PLAYERB_CONDUCTED = 3;
149
{***************************************************************************}
152
{ Tags for CreatePlayer(), SetPlayerAttrs(), and GetPlayerAttrs() }
153
PLAYER_Base = (TAG_USER+64) ;
154
PLAYER_Hook = (PLAYER_Base+1) ; { set address of hook function }
155
PLAYER_Name = (PLAYER_Base+2) ; { name of player }
156
PLAYER_Priority = (PLAYER_Base+3) ; { priority of player }
157
PLAYER_Conductor = (PLAYER_Base+4) ; { set conductor for player }
158
PLAYER_Ready = (PLAYER_Base+5) ; { the "ready" flag }
159
PLAYER_AlarmTime = (PLAYER_Base+12); { alarm time (sets PLAYERF_ALARMSET) }
160
PLAYER_Alarm = (PLAYER_Base+13); { sets/clears PLAYERF_ALARMSET flag }
161
PLAYER_AlarmSigTask = (PLAYER_Base+6) ; { task to signal for alarm/notify }
162
PLAYER_AlarmSigBit = (PLAYER_Base+8) ; { signal bit for alarm (or -1) }
163
PLAYER_Conducted = (PLAYER_Base+7) ; { sets/clears PLAYERF_CONDUCTED flag }
164
PLAYER_Quiet = (PLAYER_Base+9) ; { don't process time thru this }
165
PLAYER_UserData = (PLAYER_Base+10);
166
PLAYER_ID = (PLAYER_Base+11);
167
PLAYER_ExtSync = (PLAYER_Base+14); { attempt/release to ext sync }
168
PLAYER_ErrorCode = (PLAYER_Base+15); { error return value }
171
{***************************************************************************}
174
{ Method types for messages sent via a Player's hook }
181
{ used for PM_TICK, PM_POSITION and PM_SHUTTLE methods }
184
pmt_Method : ULONG; { PM_TICK, PM_POSITION, or PM_SHUTTLE }
188
{ used for the PM_STATE method }
189
ppmState = ^tpmState;
191
pms_Method : ULONG; { PM_STATE }
196
{***************************************************************************}
199
{ Possible lock types for LockRealTime() }
200
RT_CONDUCTORS = 0; { conductor list }
203
{***************************************************************************}
206
{ realtime.library error codes }
207
RTE_NOMEMORY = 801; { memory allocation failed }
208
RTE_NOCONDUCTOR = 802; { player needs a conductor }
209
RTE_NOTIMER = 803; { timer (CIA) allocation failed }
210
RTE_PLAYING = 804; { can't shuttle while playing }
213
{***************************************************************************}
216
{ OpenLibrary("realtime.library",0) returns a pointer to this structure.
217
* All fields are READ-ONLY.
220
pRealTimeBase = ^tRealTimeBase;
221
tRealTimeBase = record
222
rtb_LibNode : tLibrary;
223
rtb_Reserved0 : Array[0..1] of Byte;
225
rtb_Time, { current time }
226
rtb_TimeFrac : ULONG; { fixed-point fraction part of time }
227
rtb_Reserved1 : WORD;
228
rtb_TickErr : smallint; { nanosecond error from ideal Tick }
229
end; { length to real tick length }
231
{ Actual tick length is: 1/TICK_FREQ + rtb_TickErr/1e9 }
234
RealTime_TickErr_Min = -705;
235
RealTime_TickErr_Max = 705;
237
{*--- functions in V37 or higher (Release 2.04) ---*}
239
VAR RealTimeBase : pRealTimeBase;
242
REALTIMENAME : PChar = 'realtime.library';
244
FUNCTION CreatePlayerA(const tagList : pTagItem) : pPlayer;
245
PROCEDURE DeletePlayer(player : pPlayer);
246
FUNCTION ExternalSync(player : pPlayer; minTime : LONGINT; maxTime : LONGINT) : BOOLEAN;
247
FUNCTION FindConductor(const name : pCHAR) : pConductor;
248
FUNCTION GetPlayerAttrsA(const player : pPlayer;const tagList : pTagItem) : ULONG;
249
FUNCTION LockRealTime(lockType : ULONG) : POINTER;
250
FUNCTION NextConductor(const previousConductor : pConductor) : pConductor;
251
FUNCTION SetConductorState(player : pPlayer; state : ULONG; time : LONGINT) : LONGINT;
252
FUNCTION SetPlayerAttrsA(player : pPlayer;const tagList : pTagItem) : BOOLEAN;
253
PROCEDURE UnlockRealTime(lock : POINTER);
255
{You can remove this include and use a define instead}
256
{$I useautoopenlib.inc}
257
{$ifdef use_init_openlib}
258
procedure InitREALTIMELibrary;
259
{$endif use_init_openlib}
261
{This is a variable that knows how the unit is compiled}
263
REALTIMEIsCompiledHow : longint;
267
{$ifndef dont_use_openlib}
269
{$endif dont_use_openlib}
271
FUNCTION CreatePlayerA(const tagList : pTagItem) : pPlayer;
276
MOVEA.L RealTimeBase,A6
283
PROCEDURE DeletePlayer(player : pPlayer);
288
MOVEA.L RealTimeBase,A6
294
FUNCTION ExternalSync(player : pPlayer; minTime : LONGINT; maxTime : LONGINT) : BOOLEAN;
301
MOVEA.L RealTimeBase,A6
307
@end: MOVE.B D0,@RESULT
311
FUNCTION FindConductor(const name : pCHAR) : pConductor;
316
MOVEA.L RealTimeBase,A6
323
FUNCTION GetPlayerAttrsA(const player : pPlayer;const tagList : pTagItem) : ULONG;
329
MOVEA.L RealTimeBase,A6
336
FUNCTION LockRealTime(lockType : ULONG) : POINTER;
341
MOVEA.L RealTimeBase,A6
348
FUNCTION NextConductor(const previousConductor : pConductor) : pConductor;
352
MOVEA.L previousConductor,A0
353
MOVEA.L RealTimeBase,A6
360
FUNCTION SetConductorState(player : pPlayer; state : ULONG; time : LONGINT) : LONGINT;
367
MOVEA.L RealTimeBase,A6
374
FUNCTION SetPlayerAttrsA(player : pPlayer;const tagList : pTagItem) : BOOLEAN;
380
MOVEA.L RealTimeBase,A6
386
@end: MOVE.B D0,@RESULT
390
PROCEDURE UnlockRealTime(lock : POINTER);
395
MOVEA.L RealTimeBase,A6
402
{ Change VERSION and LIBVERSION to proper values }
404
VERSION : string[2] = '0';
405
LIBVERSION : longword = 0;
407
{$ifdef use_init_openlib}
408
{$Info Compiling initopening of realtime.library}
409
{$Info don't forget to use InitREALTIMELibrary in the beginning of your program}
412
realtime_exit : Pointer;
414
procedure CloserealtimeLibrary;
416
ExitProc := realtime_exit;
417
if RealTimeBase <> nil then begin
418
CloseLibrary(pLibrary(RealTimeBase));
423
procedure InitREALTIMELibrary;
426
RealTimeBase := pRealTimeBase(OpenLibrary(REALTIMENAME,LIBVERSION));
427
if RealTimeBase <> nil then begin
428
realtime_exit := ExitProc;
429
ExitProc := @CloserealtimeLibrary;
431
MessageBox('FPC Pascal Error',
432
'Can''t open realtime.library version ' + VERSION + #10 +
433
'Deallocating resources and closing down',
440
REALTIMEIsCompiledHow := 2;
441
{$endif use_init_openlib}
443
{$ifdef use_auto_openlib}
444
{$Info Compiling autoopening of realtime.library}
447
realtime_exit : Pointer;
449
procedure CloserealtimeLibrary;
451
ExitProc := realtime_exit;
452
if RealTimeBase <> nil then begin
453
CloseLibrary(pLibrary(RealTimeBase));
460
RealTimeBase := pRealTimeBase(OpenLibrary(REALTIMENAME,LIBVERSION));
461
if RealTimeBase <> nil then begin
462
realtime_exit := ExitProc;
463
ExitProc := @CloserealtimeLibrary;
464
REALTIMEIsCompiledHow := 1;
466
MessageBox('FPC Pascal Error',
467
'Can''t open realtime.library version ' + VERSION + #10 +
468
'Deallocating resources and closing down',
473
{$endif use_auto_openlib}
475
{$ifdef dont_use_openlib}
477
REALTIMEIsCompiledHow := 3;
478
{$Warning No autoopening of realtime.library compiled}
479
{$Warning Make sure you open realtime.library yourself}
480
{$endif dont_use_openlib}
483
END. (* UNIT REALTIME *)