Initial commit.
[amiga/xmodule.git] / Autodocs / xmodule
1 @DATABASE "xmodule"
2 @MASTER   "Work:SC/XM/Autodocs/xmodule.doc"
3 @REMARK   This file was created by ADtoHT 2.1 on 08-Apr-97 12:17:15
4 @REMARK   Do not edit
5 @REMARK   ADtoHT is © 1993-1995 Christian Stieber
6
7 @NODE MAIN "xmodule.doc"
8
9                                    @{b}xmodule@{ub}
10
11 @{"background" LINK "background"}
12
13 @{"xmActivateSong()" LINK "xmActivateSong"}    @{"xmAddHook()" LINK "xmAddHook"}          @{"xmAddHookA()" LINK "xmAddHook"}
14 @{"xmAddInstrument()" LINK "xmAddInstrumentA"}   @{"xmAddInstrumentA()" LINK "xmAddInstrumentA"}   @{"xmAddPattern()" LINK "xmAddPatternA"}
15 @{"xmAddPatternA()" LINK "xmAddPatternA"}     @{"xmAddSong()" LINK "xmAddSongA"}          @{"xmAddSongA()" LINK "xmAddSongA"}
16 @{"xmCreateSong()" LINK "xmCreateSong"}      @{"xmCreateSongA()" LINK "xmCreateSong"}      @{"xmDeleteSong()" LINK "xmDeleteSong"}
17 @{"xmDisplayMessage()" LINK "xmDisplayMessage"}  @{"xmDisplayMessageA()" LINK "xmDisplayMessage"}  @{"xmDisplayProgress()" LINK "xmDisplayProgress"}
18 @{"xmIdentifyModule()" LINK "xmIdentifyModule"}  @{"xmLoadModule()" LINK "xmLoadModuleA"}       @{"xmLoadModuleA()" LINK "xmLoadModuleA"}
19 @{"xmLockActiveSong()" LINK "xmLockActiveSong"}  @{"xmProcessSong()" LINK "xmProcessSongA"}      @{"xmProcessSongA()" LINK "xmProcessSongA"}
20 @{"xmRemHook()" LINK "xmRemHook"}         @{"xmRemHookA()" LINK "xmRemHook"}         @{"xmRemInstrument()" LINK "xmRemInstrument"}
21 @{"xmRemPattern()" LINK "xmRemPattern"}      @{"xmRemSong()" LINK "xmRemSong"}          @{"xmSaveModule()" LINK "xmSaveModuleA"}
22 @{"xmSaveModuleA()" LINK "xmSaveModuleA"}     @{"xmSetInstrument()" LINK "xmSetInstrumentA"}    @{"xmSetInstrumentA()" LINK "xmSetInstrumentA"}
23 @{"xmSetPattern()" LINK "xmSetPatternA"}      @{"xmSetPatternA()" LINK "xmSetPatternA"}      @{"xmSetSongLen()" LINK "xmSetSongLen"}
24
25 @ENDNODE
26 @NODE "background" "xmodule/background (information)"
27
28
29     INTRODUCTION
30         The xmodule.library is an API that provides access to the XModule
31         song management engine, as well as other general pourpose
32         services.  Hooks and external applications can use this library
33         to create, load, save and modify songs.
34
35         The xmodule.library does not exist as a stand alone shared libray.
36         Instead, it's code is contained inside the main XModule executable
37         (altrough it's logically independant from the rest of the XModule
38         code).
39
40         XModule adds the xmodule.library to the exec libray list at
41         startup time, unless it finds one already in the list (this might
42         happen when multiple copies of XModule are running at the same
43         time).
44
45     PUBLIC SONGS
46         The xmodule.library maintains a list of public songs which can be
47         used by all applications which opened the library.  Each song in
48         the list is protected from multiple task access by a
49         SignalSemaphore, and whole list is also protected by another
50         semaphore.  The locking mechanism is very simple: before you can
51         access a song you must obtain its semaphore, and you must release
52         it as soon as you are done with it.  If you are locking a song to
53         just to read some information (i.e.: you don't want to modify
54         anything), you should obtain a shared lock instead of an exclusive
55         one.  The list must be locked whenever you want to add or remove
56         a song, or when you scan it in any way.
57
58         Since public songs could be modified or even deleted by other
59         tasks, do not make your songs public unless your code is smart
60         enough to handle all possible situations.
61
62
63     HOOKS
64         Actually, most modular programs call them `modules', but it would
65         have created a lot of confusion with a program like XModule :-).
66
67         Hooks are programs that add some kind of functionality
68         to XModule.  External hook files are standard shared libraries
69         which will open the xmodule.library when they are loaded and
70         call @{"xmAddHookA()" LINK "xmodule/xmAddHook"} to add themselves to a list of hooks maintained
71         by the library.
72
73         Currently, XModule supports two kinds of hooks: loaders and
74         savers.  Loader hooks can also provide a function which
75         identifies a particular module format.
76
77         An external hook libray may also contain several hooks.
78         Putting a loader and a saver for one particolar format together
79         in one libray is generally a good idea, while making a hook
80         with hundereds of loaders and savers isn't a good move because
81         it makes the whole concept of external hooks quite useless.
82         Grouping different versions or variants of one format together
83         in one external hook is acceptable.
84
85     SEE ALSO
86         songclass/--background--, exec/ObtainSemaphore()
87
88 @ENDNODE
89 @NODE "xmActivateSong" "xmodule/xmActivateSong()"
90 @{b}
91
92     NAME@{ub}
93         xmActivateSong -- Makes a song the active one@{b}
94
95     SYNOPSIS@{ub}
96         success = xmActivateSong(songInfo);
97         D0                       A0
98
99         ULONG xmActivateSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *);@{b}
100
101     FUNCTION@{ub}
102         Makes the passed song the currently active one.  It's pointer
103         will be stored in the public song list and most actions
104         will happen on this song by default.@{b}
105
106     INPUTS@{ub}
107         songInfo - song to be activated. If NULL, this function will
108             take no action.@{b}
109
110     RESULT@{ub}
111         success - Will be 0 for failure, in which case the song will
112             not be removed from the song list. Currently,
113             xmActivateSong() will never fail.@{b}
114
115     NOTE@{ub}
116         In order to activate a song, you must own a shared lock
117         on it.  Please do not hog this lock for a long time when
118         xmActivateSong() returns, because most internal routines
119         try to lock the current song before taking any action.@{b}
120
121     SEE ALSO@{ub}
122
123 @ENDNODE
124 @NODE "xmAddHook" "xmodule/xmAddHook()"
125 @{b}
126
127     NAME@{ub}
128         xmAddHookA -- Creates a new XModule Hook
129         xmAddHook -- Varargs stub for xmAddHookA@{b}
130
131     SYNOPSIS@{ub}
132         hook = xmAddHookA(tagList)
133         D0                A0
134
135         @{"struct XMHook" LINK "xmodule.h/File" 92} *xmAddHookA(struct TagItem *);
136
137
138         hook = xmAddHook(Tag1,...)
139
140         @{"struct XMHook" LINK "xmodule.h/File" 92} *xmAddHook(ULONG,...);@{b}
141
142     FUNCTION@{ub}
143         Creates a new XMHook structure and fills it in with data supplied
144         with the TagList. Adds the newly created Hook to the appropriate
145         list.@{b}
146
147     INPUTS@{ub}
148         tagList - pointer to a tag list specifying how to initialize the
149             XMHook structure.@{b}
150
151     TAGS@{ub}
152         @{"XMHOOK_Type" LINK "xmodule.h/File" 235} - (ULONG) Defines the pourpose of this hook. Possible
153             values are currently @{"NT_XMLOADER" LINK "xmodule.h/File" 138} and @{"NT_XMSAVER" LINK "xmodule.h/File" 139}. (This
154             tag is REQUIRED).
155
156         @{"XMHOOK_Name" LINK "xmodule.h/File" 236} - (STRPTR) ti_Data contains a short name for the
157             hook (e.g: "SoundTracker").  This name will appear in the
158             Savers list if this hook is a saver and will be passed as an
159             argument for some ARexx commands, so please use a single
160             word name.  (This tag is REQUIRED).
161
162         @{"XMHOOK_Priority" LINK "xmodule.h/File" 237} - (BYTE) Priority to give to this hook.  Hooks
163             with higher priorities will be used before lower priority
164             ones and will come first in lists shown to the user. Valid
165             range is -128..+127, but please restrict to a -20..+20
166             interval for normal cases. (Defaults to 0).
167
168         @{"XMHOOK_Descr" LINK "xmodule.h/File" 238} - (STRPTR) Verbose description of the hook
169             (without newlines). (Defaults to NULL).
170
171         @{"XMHOOK_Author" LINK "xmodule.h/File" 239} - (STRPTR) Author's name.  Please, just put
172             your full name here; no greetings, copyright notices,
173             etc. (Defaults to NULL).
174
175         @{"XMHOOK_ID" LINK "xmodule.h/File" 240} - (ULONG) This is a unique, IFF-style identifier for
176             the format.  If the format is an IFF format, it must be the
177             same of the FORM ID. (Defaults to 0, this tag is required
178             for IFF loaders and savers).
179
180         @{"XMHOOK_Flags" LINK "xmodule.h/File" 241} - (ULONG) Sets miscellaneous flags for this hook.
181             See xmodule.h for possible flags.
182
183         @{"XMHOOK_LibraryBase" LINK "xmodule.h/File" 243} - (struct Library *) Pointer to the library
184             base for external hooks.  This pointer will be used to open
185             the library when the hook is created and to close it when
186             the hook is deleted.  If you do not pass this tag, you must
187             find some other way to keep your code in memory until one
188             or more of your hooks are active.  XModule will close your
189             library just after calling the SetupXMHook() function.
190             (Defaults to NULL).
191
192         @{"XMHOOK_UserData" LINK "xmodule.h/File" 242} - (APTR) ti_Data will be stored in the
193             xmh_UserData field of the XMHook structure. This field can
194             come andy to store private data. (Defaults to NULL).
195
196         XMHOOK_RemoveHookFunc - (APTR) Pointer to a function which will be
197             called upon removing the hook.  This function can be used to
198             free any private resources allocated by the hook when it was
199             created. The template for the function is:
200
201                 void RemoveHookFunc (@{"struct XMHook" LINK "xmodule.h/File" 92} *hook);
202                                      A0
203
204         @{"XMHOOK_LoadModFunc" LINK "xmodule.h/File" 245} - (APTR) Pointer to the hook function which
205             loads a module. The template for the function is:
206
207                 LONG LoadModFunc (BPTR fileHandle, @{"struct SongInfo" LINK "songclass.h/File" 284} *song,
208                                   D0               A0
209                     @{"struct XMHook" LINK "xmodule.h/File" 92} *loader);
210                     A1
211
212             `fileHandle' is an open file to load the module from. The
213             caller will take care to close it for you. The loader should
214             return RETURN_OK for success, or any other AmigaDOS error
215             code to mean failure.  In particular, RETURN_WARN indicates
216             that something went wrong, but the song is ok.  The special
217             error code @{"ERROR_IOERR" LINK "xmodule.h/File" 194} can be used when some dos.library
218             call (e.g.: Read()) failed.  In the latter case, the
219             AmigaDOS IoErr value should be set to explain the specific
220             cause of the problem.
221             (This tag is required by all @{"NT_XMLOADER" LINK "xmodule.h/File" 138} type hooks).
222
223         @{"XMHOOK_SaveModFunc" LINK "xmodule.h/File" 246} - (APTR) Pointer to the hook function which
224             saves a module. The template for the function is:
225
226                 LONG SaveModFunc (BPTR fileHandle, @{"struct SongInfo" LINK "songclass.h/File" 284} *song,
227                                   D0               A0
228                     @{"struct XMHook" LINK "xmodule.h/File" 92} *saver);
229                     A1
230
231             fileHandle is an open file to save the module to. The caller
232             will take care to close it for you. The saver should return
233             RETURN_OK for success, or any other AmigaDOS error code to
234             mean failure.  In particular, RETURN_WARN indicates that
235             something went wrong, but the song is ok.  The special
236             error code @{"ERROR_IOERR" LINK "xmodule.h/File" 194} can be used when some dos.library
237             call (e.g.: Read()) failed.  In the latter case, the
238             AmigaDOS IoErr value should be set to explain the specific
239             cause of the problem.
240             (This tag is required by all @{"NT_XMSAVER" LINK "xmodule.h/File" 139} type hooks).
241
242
243         @{"XMHOOK_IdentifyModFunc" LINK "xmodule.h/File" 247} - (APTR) Pointer to the hook function
244             which identifies a module format. The template for the
245             function is:
246
247                 @{"struct XMHook" LINK "xmodule.h/File" 92} *IdentifyModFunc (BPTR fileHandle,
248                                                 D0
249                     @{"struct XMHook" LINK "xmodule.h/File" 92} *hook,struct TagItem *tagList);
250                     A0                  A1
251
252             fileHandle is an open file to try the identification on. The
253             caller will take care to close it. NOTE: Do not make assumptions
254             on the initial file position (e.g: seek yourself to position 0
255             if you need to). This funtion should return a pointer to a valid
256             loader (usually the one passed in) if the format is recognized,
257             NULL otherwhise.  (This tag is required by all @{"NT_XMLOADER" LINK "xmodule.h/File" 138} type
258             hooks).@{b}
259
260     RESULT@{ub}
261         hook - Pointer to the newly allocated XMHook structure, or
262             NULL for failure.@{b}
263
264     SEE ALSO@{ub}
265         @{"xmRemHook()" LINK "xmRemHook"}, @{"xmIdentifyModule()" LINK "xmIdentifyModule"}, xmLoadSong(), xmSaveSong()
266
267 @ENDNODE
268 @NODE "xmAddInstrumentA" "xmodule/xmAddInstrumentA()"
269 @{b}
270
271     NAME@{ub}
272         xmAddInstrumentA -- Adds a instrument to a song
273         xmAddInstrument -- Varargs stub for xmAddInstrumentA@{b}
274
275     SYNOPSIS@{ub}
276         instrument = xmAddInstrumentA(si, instrNum, tagList)
277         D0                            A0  D0        A1
278
279         @{"struct Instrument" LINK "songclass.h/File" 183} *xmAddInstrumentA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,
280             struct TagItem *);
281
282
283         instrument = xmAddInstrument(si,instrNum,tag1,...)
284
285         @{"struct Instrument" LINK "songclass.h/File" 183} *xmAddInstrument(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,LONG,...);@{b}
286
287     FUNCTION@{ub}
288         Adds an instrument to a song by calling the @{"SNGM_ADDINSTRUMENT" LINK "songclass.h/File" 32} method .@{b}
289
290     INPUTS@{ub}
291         si - pointer to the song to which the instrument should be added.
292         tagList - optional TagList.  See @{"SNGM_ADDINSTRUMENT" LINK "songclass.h/File" 32} for possible tags .@{b}
293
294     RESULT@{ub}
295         Pointer to the new instrument or NULL for failure.@{b}
296
297     NOTE@{ub}
298         In order to add instruments, you should have exclusive access to
299         the song.  Always obtain a lock before you call this function on
300         public songs.@{b}
301
302     SEE ALSO@{ub}
303         @{"xmRemInstrument()" LINK "xmRemInstrument"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_REMINSTRUMENT
304
305 @ENDNODE
306 @NODE "xmAddPatternA" "xmodule/xmAddPatternA()"
307 @{b}
308
309     NAME@{ub}
310         xmAddPatternA -- Adds a pattern to a song
311         xmAddPattern -- Varargs stub for xmAddPatternA@{b}
312
313     SYNOPSIS@{ub}
314         pattern = xmAddPatternA(si, tagList)
315         D0                      A0  A1
316
317         @{"struct Pattern" LINK "songclass.h/File" 229} *xmAddPatternA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,struct TagItem *);
318
319
320         pattern = xmAddPattern (si,tag1,...)
321
322         @{"struct Pattern" LINK "songclass.h/File" 229} *xmAddPattern(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG Tag1,...);@{b}
323
324     FUNCTION@{ub}
325         Adds a pattern to a song by calling the @{"SNGM_ADDPATTERN" LINK "songclass.h/File" 29} method.@{b}
326
327     INPUTS@{ub}
328         si - pointer to the song to which the pattern should be added.
329         tagList - optional TagList.  See @{"SNGM_ADDPATTERN" LINK "songclass.h/File" 29} for possible tags.@{b}
330
331     RESULT@{ub}
332         Pointer to the new pattern or NULL for failure.@{b}
333
334     NOTE@{ub}
335         In order to add patterns, you should have exclusive access to
336         the song.  Always obtain a lock before you call this function on
337         public songs.@{b}
338
339     SEE ALSO@{ub}
340         @{"xmRemPattern()" LINK "xmRemPattern"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_ADDPATTERN
341
342 @ENDNODE
343 @NODE "xmAddSongA" "xmodule/xmAddSongA()"
344 @{b}
345
346     NAME@{ub}
347         xmAddSongA -- Add a song to the song list
348         xmAddSong -- Varargs stub for xmAddSongA@{b}
349
350     SYNOPSIS@{ub}
351         success = xmAddSongA(songInfo,position,tagList);
352         D0                   A0       A1       A2
353
354         ULONG xmAddSongA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,@{"struct SongInfo" LINK "songclass.h/File" 284} *,
355             struct TagItem *);
356
357
358         success = xmAddSong(songInfo,position,tag1,...);
359
360         ULONG xmAddSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *,@{"struct SongInfo" LINK "songclass.h/File" 284} *,
361             LONG,...);@{b}
362
363     FUNCTION@{ub}
364         Adds a song to the public song list. Trying to add a song
365         twice is harmless.@{b}
366
367     INPUTS@{ub}
368         songInfo - song to be added.  Passing a NULL pointer is safe.
369         position - Position to add the song in.  Passing NULL adds the
370             song in the head of the list, while ~0 adds it in the tail.
371             passing a pointer to a SongInfo already in the list inserts
372             the first song _after_ the other one.
373         tagList - pointer to a TagList for more arguments.@{b}
374
375     TAGS@{ub}
376         @{"XMSNG_Active" LINK "xmodule.h/File" 209} - (BOOL) Makes this song the active one. The
377             default is to just add the song without activating it.@{b}
378
379     RESULT@{ub}
380         success - Will be 0 for failure, in which case the song will
381             not be added to the songs list. Currently, xmAddSongA()
382             will never fail.@{b}
383
384     NOTE@{ub}
385         The song list is protected from multiple tasks access by a
386         SignalSemaphore in XModuleBase. This call will wait if the
387         song list has been locked by another task. Beware of deadlock
388         conditions!@{b}
389
390     SEE ALSO@{ub}
391         @{"xmRemSong()" LINK "xmRemSong"}
392
393 @ENDNODE
394 @NODE "xmCreateSong" "xmodule/xmCreateSong()"
395 @{b}
396
397     NAME@{ub}
398         xmCreateSongA -- Create and initialize a new SongInfo structure
399         xmCreateSong -- Varargs stub for xmCreateSongA@{b}
400
401     SYNOPSIS@{ub}
402         songInfo = xmCreateSongA(tagList);
403         D0                      A0
404
405         @{"struct SongInfo" LINK "songclass.h/File" 284} *xmCreateSongA(struct TagItem *);
406
407
408         songInfo = xmCreateSong(Tag1,...);
409
410         @{"struct SongInfo" LINK "songclass.h/File" 284} *xmCreateSong(ULONG,...);@{b}
411
412     FUNCTION@{ub}
413         Allocates and initializes a new SongInfo structure.  The song
414         can then be added to the song list via @{"xmAddSongA()" LINK "xmAddSongA"}, in which
415         case, it is no longer required to free it with @{"xmDeleteSong()" LINK "xmDeleteSong"}.@{b}
416
417     INPUTS@{ub}
418         tagList - pointer to an optional tag list specifying how to
419             initialize the SongInfo structure.@{b}
420
421     TAGS@{ub}
422         @{"SNGA_DefaultTracks" LINK "songclass.h/File" 121} - Sets the default number of pattern tracks for
423             the song. Defaults to 4.
424
425         @{"SNGA_DefaultPattLen" LINK "songclass.h/File" 122} - Sets the default number of pattern lines for
426             the song. Defaults to 64.
427
428         @{"SNGA_ReadyToUse" LINK "songclass.h/File" 127} - Adds one pattern and one position to the song.
429             Defaults to FALSE.
430
431         @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) Add the song to the song list.
432             When a song is being added to the list, a shared lock is
433             obtained on it to prevent other tasks from modifying (or even
434             remove) the song before you can do your job on it. IT IS YOUR
435             DUTY TO UNLOCK THE SONG as soon as you are done modifying it.
436             Passing NULL adds the song on the head of the list, while -1
437             (~0) will add it to the end of the SongList. Passing in a
438             pointer to another song which is already in the list, will
439             add the new song _after_ the latter.
440             (Default is not adding the song).
441
442         @{"XMSNG_Active" LINK "xmodule.h/File" 209} - (BOOL) Makes this song the active one. This tag is
443             considered only if the @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} tag is also passed.@{b}
444
445     RESULT@{ub}
446         songInfo - pointer to the newly allocated SongInfo structure, or
447             NULL for failure.@{b}
448
449     SEE ALSO@{ub}
450         @{"xmDeleteSong()" LINK "xmDeleteSong"}, @{"xmAddSongA()" LINK "xmAddSongA"}
451
452 @ENDNODE
453 @NODE "xmDeleteSong" "xmodule/xmDeleteSong()"
454 @{b}
455
456     NAME@{ub}
457         xmDeleteSong -- Deletes a song@{b}
458
459     SYNOPSIS@{ub}
460         xmDeleteSong(songInfo)
461                      A0
462
463         void xmDeleteSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *);@{b}
464
465     FUNCTION@{ub}
466         Deletes a song and all the items attached to it (patterns,
467         instruments, etc.).  This call will also remove the song from
468         the song list if it had been added to it.@{b}
469
470     INPUTS@{ub}
471         songInfo - pointer to the SongInfo structure to be deleted.
472             Passing a NULL pointer is harmless.@{b}
473
474     NOTE@{ub}
475         In order to delete a song which has been added to the public
476         song list, you must first obtain an exclusive lock on it to
477         prevent other tasks from walking on it while you are freeing
478         it's data structures.  The semaphore does NOT need to be
479         relinquished, because the SongInfo structure won't exist any
480         more when this call returns.@{b}
481
482     SEE ALSO@{ub}
483         @{"xmCreateSong()" LINK "xmCreateSong"}, @{"xmRemSong()" LINK "xmRemSong"}
484
485 @ENDNODE
486 @NODE "xmDisplayMessage" "xmodule/xmDisplayMessage()"
487 @{b}
488
489     NAME@{ub}
490         xmDisplayMessageA -- Displays a message to the user
491         xmDisplayMessage -- Varargs stub for xmDisplayMessageA()@{b}
492
493     SYNOPSIS@{ub}
494         xmDisplayMessageA(level, message, args)
495                           DO     A0       A1
496
497         void xmDisplayMessageA(ULONG,APTR,LONG *);
498
499
500         xmDisplayMessage(level, message, ...)
501
502         void xmDisplayMessage(ULONG,APTR,...);@{b}
503
504     FUNCTION@{ub}
505         Outputs a string in the XModule log window or in the 'action' field
506         of the progress indicator.  The string is printf-formatted before
507         being output.@{b}
508
509     INPUTS@{ub}
510         level - a number from 0 to 7 which indicates the importance of the
511             message.  7 is used for very annoying messages (eg: debug output) ,
512             0 for very important things (eg: disaster).
513             If you set the @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187} bit in the level parameter, you
514             can pass a catalog string number instead of a pointer to a string .
515             Specifying @{"XMDMF_ACTION" LINK "xmodule.h/File" 185}, the message will be put in the 'action'
516             field of the progress indicator.
517             If the flag @{"XMDMF_DOSFAULT" LINK "xmodule.h/File" 184} is specified, a Fault() output is
518             formatted using the message as an header.  In this case, the
519             level parameter takes another meaing: The lower word can contain
520             an AmigaDOS error code. If it is 0, IoErr() will be used to get
521             the error code.
522         message - pointer to a string or catalog message number,
523             when the @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187} flag is set.
524         args - arguments for formatting.@{b}
525
526     EXAMPLES@{ub}
527         xmDisplayMessage (@{"XMDMF_ALERT" LINK "xmodule.h/File" 173},
528             "The application `%s' fucked up Windoze95 because %s.",
529             "(unknown name)", "an error occurred");
530
531         xmDisplayMessage (XMDMF_USE_CATALOG | @{"XMDMF_COMMENT" LINK "xmodule.h/File" 179},
532             MSG_LIFE_UNIVERSE_AND_ALLTHAT, 42, "Fortytwo", "For tea too");
533
534         xmDisplayMessageA (@{"XMDMF_ACTION" LINK "xmodule.h/File" 185} | @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187},
535             MSG_READING_COMICS, NULL);
536
537         xmDisplayMessage (@{"XMDMF_DOSFAULT" LINK "xmodule.h/File" 184} | @{"XMDMF_USECATALOG" LINK "xmodule.h/File" 187},
538             MSG_CANT_LOAD_MODULE, ModuleName);@{b}
539
540     SEE ALSO@{ub}
541         @{"xmDisplayProgress()" LINK "xmDisplayProgress"}
542
543 @ENDNODE
544 @NODE "xmDisplayProgress" "xmodule/xmDisplayProgress()"
545 @{b}
546
547     NAME@{ub}
548         xmDisplayProgress -- Uptdates the progress bar indicator@{b}
549
550     SYNOPSIS@{ub}
551         abort = xmDisplayProgress(done, total)
552                                   D0    D1
553
554         LONG @{"xmDisplayMessageA" LINK "xmDisplayMessage"}(ULONG,ULONG);@{b}
555
556     FUNCTION@{ub}
557         Updates the position of the fuel gauge in the progress window to
558         show the progress of an operation.  Additionally, it checks for
559         user abort.@{b}
560
561     INPUTS@{ub}
562         done - a number which indicates how much of the work has
563             been already completed
564         total - Total number of operations to do.@{b}
565
566     RESULT@{ub}
567         0 for success, ERROR_BREAK if user abort was detected.  You should
568         always check this return code to abort what you were doing.
569
570 @ENDNODE
571 @NODE "xmIdentifyModule" "xmodule/xmIdentifyModule()"
572 @{b}
573
574     NAME@{ub}
575         xmIdentifyModule -- Returns the type of a module@{b}
576
577     SYNOPSIS@{ub}
578         loader = xmIdentifyModule(fh, tagList)
579         D0                        D0  A0
580
581         @{"struct XMHook" LINK "xmodule.h/File" 92} *xmIdentifyModule(BPTR,struct TagItem *);@{b}
582
583     FUNCTION@{ub}
584         Finds out a loader which is able to read the given module.@{b}
585
586     INPUTS@{ub}
587         fh - AmigaDOS FileHandle to examine.
588         tagList - Additional parameters. Leave it NULL for now.@{b}
589
590     RESULT@{ub}
591         loader - Pointer to the first loader which knows how to load this
592             module, or NULL otherwise.@{b}
593
594     NOTE@{ub}
595         Before you call this function, you must first obtain a lock on the
596         loaders list to protect yourself from other tasks which might remove
597         the returned loader before you can actually use it.@{b}
598
599     SEE ALSO@{ub}
600
601 @ENDNODE
602 @NODE "xmLoadModuleA" "xmodule/xmLoadModuleA()"
603 @{b}
604
605     NAME@{ub}
606         xmLoadModuleA -- Loads a module and converts it in XModule format
607         xmLoadModule -- Varargs stub for xmLoadModuleA@{b}
608
609     SYNOPSIS@{ub}
610         songInfo = xmLoadModuleA(fileName,tagList)
611         D0                       A0       A1
612
613         @{"struct SongInfo" LINK "songclass.h/File" 284} *xmLoadModuleA(STRPTR,struct TagItem *);
614
615
616         songInfo = xmLoadModule(fileName,tag,...)
617
618         @{"struct SongInfo" LINK "songclass.h/File" 284} *xmLoadModule(STRPTR,LONG,...);@{b}
619
620     FUNCTION@{ub}
621         Loads fileName using the correct module loader.@{b}
622
623     INPUTS@{ub}
624         fileName - File to read. Can be NULL if the @{"XMSNG_FileHandle" LINK "xmodule.h/File" 208}
625             tag is passed.
626         tagList - Additional parameters (see below).  Can be NULL.@{b}
627
628     TAGS@{ub}
629         @{"XMSNG_OldSong" LINK "xmodule.h/File" 206} - ti_Data is the pointer to a SongInfo which will be
630             freed as soon as the module format has been determined.  This
631             is useful when the user wants to replace a song with another
632             one.  Passing NULL uses the currently active song.
633
634         @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) Add the song to the song list.
635             When a song is being added to the list, a shared lock is
636             obtained on it to prevent other tasks from modifying (or even
637             remove) the song before you can do your job on it. IT IS YOUR
638             DUTY TO UNLOCK THE SONG as soon as you are done modifying it.
639             Passing NULL adds the song on the head of the list, while -1
640             (~0) will add it to the end of the SongList. Passing in a
641             pointer to another song which is already in the list, will
642             add the new song _after_ the latter.
643             (Default is not adding the song).
644
645         @{"XMSNG_Loader" LINK "xmodule.h/File" 207} - (@{"struct XMHook" LINK "xmodule.h/File" 92} *) Disables automatic format
646             checking and forces loading the module with the given
647             loader. (Defaults to NULL).
648
649         @{"XMSNG_FileHandle" LINK "xmodule.h/File" 208} - (BPTR) pointer to an open AmigaDOS
650             FileHandle to read the module from.  The file must
651             already be positioned over the beginning of the module data.
652             NOTE: Even if this tag is passed, the fileName parameter is
653                 still used to fill in the SongName field in case it is
654                 missing inside the module AND the filesystem does not
655                 support the ACTION_EXAMINE_FH packet.
656             NOTE: Some loaders may require a fully seekable file, so be
657                 careful when using pipes.
658             NOTE: automatic data decompression is not possible when
659                 @{"XMSNG_FileHandle" LINK "xmodule.h/File" 208} is passed.
660             (Defaults to NULL).
661
662         XMSNG_IFFHandle - (BPTR) pointer to an already initialized
663             IFFHandle to read the module from.  The IFF must
664             already be positioned over the beginning of the module FORM.
665             Even if this tag is passed, the fileName parameter is still
666             used to fill in the SongName field in case it is missing
667             inside the module.
668             NOTE: The iffparse.library can deal with non-seekable files,
669                 but some loaders may require a fully seekable file, so be
670                 careful when using pipes.
671             NOTE: automatic file decompression is not possible when
672                 XMSNG_IFFHandle is passed.
673             (Defaults to NULL).
674
675         @{"XMSNG_Active" LINK "xmodule.h/File" 209} - (BOOL) Makes this song the active one. This tag is
676             considered only if the @{"XMSNG_AddToList" LINK "xmodule.h/File" 205} tag is also passed.@{b}
677
678     RESULT@{ub}
679         songInfo - Pointer to the newly allocated SongInfo structure, or
680             NULL for failure.  This function will not fail if the module is
681             partially corrupted. Anyway, the returned SongInfo will always
682             be valid. You can check IoErr() to know if there were problems.@{b}
683
684     EXAMPLE@{ub}
685         /* Load a song and add it to the SongList */
686         si = xmLoadSongTags (file, NULL,
687             @{"XMSNG_AddToList" LINK "xmodule.h/File" 205}, (@{"struct SongInfo" LINK "songclass.h/File" 284} *)~0,
688             TAG_DONE);
689
690         /* Check for errors even if si is not NULL */
691         error = IoErr();
692
693         /* Release Semaphore got by xmLoadSong() */
694         if (si) ReleaseSemaphore (&si->Lock);@{b}
695
696     SEE ALSO@{ub}
697         @{"xmAddSongA()" LINK "xmAddSongA"}, @{"xmIdentifyModule()" LINK "xmIdentifyModule"}
698
699 @ENDNODE
700 @NODE "xmLockActiveSong" "xmodule/xmLockActiveSong()"
701 @{b}
702
703     NAME@{ub}
704         xmLockActiveSong -- Obtains an lock on the active song@{b}
705
706     SYNOPSIS@{ub}
707         song = xmLockActiveSong(mode);
708         D0                        D0:16
709
710         @{"struct SongInfo" LINK "songclass.h/File" 284} *@{"xmActivateSong" LINK "xmActivateSong"}(UWORD);@{b}
711
712     FUNCTION@{ub}
713         Obtains an exclusive or shared lock on the active song,
714         waiting if needed.  This call is a shortcut to:
715
716             ObtainSemaphoreShared (&XModuleBase->xm_BaseLock);
717             ObtainSemaphore[Shared] (&XModuleBase->xm_CurrentSong.Lock);
718             ReleaseSemaphore (&XModuleBase->xm_BaseLock);
719
720         To unlock a song obtained in this way, you just need to
721         ReleaseSemaphore() it.
722
723         You MUST always lock a song before you even think to
724         read from -or write to- its data!@{b}
725
726     INPUTS@{ub}
727         mode - one of SM_SHARED or SM_EXCLUSIVE.@{b}
728
729     RESULT@{ub}
730         song - Pointer to the song which *was* active at the time
731             you called xmLockActiveSong().  The song will be
732             locked for you.  The result will be NULL if no song
733             is active.@{b}
734
735     NOTE@{ub}
736         Please be careful if you call this function while holding
737         locks on other songs.  Doing so, you run the risk of causing
738         deadlock condition.
739         This function does only lock the song; it is NOT guaranteed
740         that it will remain the active one.@{b}
741
742     SEE ALSO@{ub}
743
744 @ENDNODE
745 @NODE "xmProcessSongA" "xmodule/xmProcessSongA()"
746 @{b}
747
748     NAME@{ub}
749         xmProcessSongA -- Performs complex processing on a song
750         xmProcessSong -- Varargs stub for xmProcessSongA()@{b}
751
752     SYNOPSIS@{ub}
753         result = xmProcessSongA(si, reserved, tagList)
754                                 A0  A1,       A2
755
756         LONG xmProcessSongA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,void *,struct TagItem *);
757
758
759         result = xmProcessSong(si, reserved, tag1, ...)
760
761         LONG xmProcessSongA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,void *,LONG,...);@{b}
762
763     FUNCTION@{ub}
764         Performs complex processing operations on a song.@{b}
765
766     INPUTS@{ub}
767         si - pointer to the song to be processed.
768         reserved - Reserved for future use.
769         tagList - List of arguments.  See below for possible tags.@{b}
770
771     RESULT@{ub}
772         The result depends on the kind of operation done.  For most
773         operations, it's value will be 0 to indicate success and
774         an AmigaDOS error code which indicates the cause for failure.@{b}
775
776     TAGS@{ub}
777         @{"XMSNG_Optimize" LINK "xmodule.h/File" 213} - (LONG).  Tries to reduce the song size by removing
778             all unused data.  Possible optimizations are:
779                 - @{"XMOF_REM_UNUSED_PATTERNS" LINK "xmodule.h/File" 221}
780                 - @{"XMOF_REM_DUP_PATTERNS" LINK "xmodule.h/File" 222}
781                 - @{"XMOF_CUT_PATTERNS" LINK "xmodule.h/File" 227}
782                 - @{"XMOF_REM_UNUSED_INSTRS" LINK "xmodule.h/File" 223}
783                 - @{"XMOF_CUT_INSTR_LOOPS" LINK "xmodule.h/File" 225}
784                 - @{"XMOF_CUT_INSTR_TAILS" LINK "xmodule.h/File" 226}
785                 - @{"XMOF_DEFAULT" LINK "xmodule.h/File" 220}
786             @{"XMOF_DEFAULT" LINK "xmodule.h/File" 220} will select all the optimizations choosen by
787             the user in addition to the ones specified with the other flags.
788
789         @{"XMSNG_RemapInstruments" LINK "xmodule.h/File" 214} - (BOOL) Performs instruments remapping.
790
791         @{"XMSNG_LimitPatterns" LINK "xmodule.h/File" 215} - (UWORD,UWORD) Limits the length all the
792             patterns inside a minimum and maximum value.  The upper 16bits
793             of the argument are the minimum value, the lower ones are
794             the maximum value.  Patterns outside this limits will be grown
795             or split as appropriate.
796
797         @{"XMSNG_Join" LINK "xmodule.h/File" 216} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) - Joins the song with another one.
798
799         @{"XMSNG_Merge" LINK "xmodule.h/File" 217} - (@{"struct SongInfo" LINK "songclass.h/File" 284} *) - Merges the song with another one.@{b}
800
801     NOTE@{ub}
802         In order to process a song, you should have exclusive access to
803         it.  Always obtain a lock before you call this function on
804         public songs.
805
806 @ENDNODE
807 @NODE "xmRemHook" "xmodule/xmRemHook()"
808 @{b}
809
810     NAME@{ub}
811         xmRemHook -- Removes an XModule Hook@{b}
812
813     SYNOPSIS@{ub}
814         xmRemHookA(xmHook)
815                    A0
816
817         void xmRemHook(@{"struct XMHook" LINK "xmodule.h/File" 92} *);@{b}
818
819     FUNCTION@{ub}
820         Removes an XModule Hook, calls its RemoveHookFunc() and then
821         frees its memory.@{b}
822
823     INPUTS@{ub}
824         xmHook - pointer to the hook to be removed.@{b}
825
826     SEE ALSO@{ub}
827         @{"xmAddHook()" LINK "xmAddHook"}
828
829 @ENDNODE
830 @NODE "xmRemInstrument" "xmodule/xmRemInstrument()"
831 @{b}
832
833     NAME@{ub}
834         xmRemInstrument -- Removes an instrument from a song@{b}
835
836     SYNOPSIS@{ub}
837         xmRemInstrument(si, instrNum)
838                         A0  D0
839
840         void xmRemInstrument(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG);@{b}
841
842     FUNCTION@{ub}
843         Removes an instrument from a song by calling the @{"SNGM_REMINSTRUMENT" LINK "songclass.h/File" 34}
844         method.@{b}
845
846     INPUTS@{ub}
847         si - pointer to the song to which the instrument should be removed.
848         mum - Number of the instrument to be removed.@{b}
849
850     NOTE@{ub}
851         In order to remove instruments, you should have exclusive access to
852         the song.  Always obtain a lock before you call this function on
853         public songs.@{b}
854
855     SEE ALSO@{ub}
856         @{"xmAddInstrumentA()" LINK "xmAddInstrumentA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_REMINSTRUMENT
857
858 @ENDNODE
859 @NODE "xmRemPattern" "xmodule/xmRemPattern()"
860 @{b}
861
862     NAME@{ub}
863         xmRemPattern -- Removes a pattern from a song@{b}
864
865     SYNOPSIS@{ub}
866         xmRemPattern(si, pattNum, replaceWith)
867                      A0  D0,      D1
868
869         void xmRemPattern(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,LONG);@{b}
870
871     FUNCTION@{ub}
872         Removes a pattern from a song by calling the @{"SNGM_REMPATTERN" LINK "songclass.h/File" 31} method.@{b}
873
874     INPUTS@{ub}
875         si - pointer to the song to which the pattern should be removed.
876         mum - Number of the pattern to be removed.
877         replaceWith - What to put in the song sequence in place of the
878             deleted pattern.@{b}
879
880     NOTE@{ub}
881         In order to remove patterns, you should have exclusive access to
882         the song.  Always obtain a lock before you call this function on
883         public songs.@{b}
884
885     SEE ALSO@{ub}
886         @{"xmAddPatternA()" LINK "xmAddPatternA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_REMPATTERN
887
888 @ENDNODE
889 @NODE "xmRemSong" "xmodule/xmRemSong()"
890 @{b}
891
892     NAME@{ub}
893         xmRemSong -- Remove a song from the song list@{b}
894
895     SYNOPSIS@{ub}
896         success = xmRemSong(songInfo);
897         D0                  A0
898
899         ULONG xmRemSong(@{"struct SongInfo" LINK "songclass.h/File" 284} *);@{b}
900
901     FUNCTION@{ub}
902         Removes a song from the public song list. It is safe to call this
903         function even if the song has not been added to the song list. If
904         the passed SongInfo is the active one, another song will be
905         selected automatically.@{b}
906
907     INPUTS@{ub}
908         songInfo - song to be removed. If NULL, this function will take
909             no action.@{b}
910
911     RESULT@{ub}
912         success - Will be 0 for failure, in which case the song will
913             not be removed from the song list. Currently,
914             xmRemSong() will never fail.@{b}
915
916     NOTE@{ub}
917         In order to remove a song, you must first obtain an exclusive
918         lock on it.
919
920         The song list is also protected from multiple task access by
921         a SignalSemaphore. This call will wait if the song list has
922         been locked by another task. Beware of deadlock conditions!@{b}
923
924     SEE ALSO@{ub}
925         @{"xmAddSongA()" LINK "xmAddSongA"}
926
927 @ENDNODE
928 @NODE "xmSaveModuleA" "xmodule/xmSaveModuleA()"
929 @{b}
930
931     NAME@{ub}
932         xmSaveModuleA -- Saves a module to the specified file format
933         xmSaveModule -- Varargs stub for xmSaveModuleA@{b}
934
935     SYNOPSIS@{ub}
936         error = xmSaveModuleA(songInfo, fileName, saver, tagList)
937         D0                    A0        A1        A2     A3
938
939         LONG xmSaveModuleA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,STRPTR,@{"struct XMHook" LINK "xmodule.h/File" 92} *,
940             struct TagItem *);
941
942
943         error = xmSaveModule(songInfo, fileName, saver, tag1,...)
944
945         LONG xmSaveModule(@{"struct SongInfo" LINK "songclass.h/File" 284} *,STRPTR,@{"struct XMHook" LINK "xmodule.h/File" 92} *,
946             LONG,...);@{b}
947
948     FUNCTION@{ub}
949         Saves songInfo to fileName using the specified saver.@{b}
950
951     INPUTS@{ub}
952         songInfo - Song to save.
953         fileName - AmigaDOS filename to write the song to.
954         saver - Pointer to the saver to use.  Pass NULL to use
955             the default saver.@{b}
956
957     TAGS@{ub}
958         No tags are defined for this call.@{b}
959
960     RESULT@{ub}
961         error - RETURN_OK for success, or any other AmigaDOS error code
962             to mean failure.  In particular, RETURN_WARN indicates that
963             something went wrong, but the song is still ok. The special
964             error code @{"ERROR_IOERR" LINK "xmodule.h/File" 194} means that some dos.library
965             call (e.g.: Read()) failed.  In the latter case, the
966             AmigaDOS IoErr() value will be set to explain the specific
967             cause of the problem.@{b}
968
969     SEE ALSO@{ub}
970
971 @ENDNODE
972 @NODE "xmSetInstrumentA" "xmodule/xmSetInstrumentA()"
973 @{b}
974
975     NAME@{ub}
976         xmSetInstrumentA -- Sets an instrument's attributes
977         xmSetInstrument -- Varargs stub for xmSetInstrumentA@{b}
978
979     SYNOPSIS@{ub}
980         success = xmSetInstrumentA(si, instrNum, tagList)
981         D0                         A0  D0        A1
982
983         ULONG xmSetInstrumentA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,
984             struct TagItem *);
985
986
987         success = xmSetInstrument(si,instrNum,tag1,...)
988
989         ULONG xmSetInstrument(@{"struct SongInfo" LINK "songclass.h/File" 284} *,LONG,LONG,...);@{b}
990
991     FUNCTION@{ub}
992         Sets an instrument's attributes by calling the @{"SNGM_SETINSTRUMENT" LINK "songclass.h/File" 33}
993         method.@{b}
994
995     INPUTS@{ub}
996         si - pointer to the song which contains the instrument to be set.
997         tagList - instrument attributes to set.  See @{"SNGM_SETINSTRUMENT" LINK "songclass.h/File" 33}
998             for possible tags.@{b}
999
1000     RESULT@{ub}
1001         non zero for success.@{b}
1002
1003     NOTE@{ub}
1004         In order to set instruments' attributes, you should have
1005         exclusive access to the song.  Always obtain a lock before
1006         you call this function on public songs.@{b}
1007
1008     SEE ALSO@{ub}
1009         @{"xmAddInstrument()" LINK "xmAddInstrumentA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_SETINSTRUMENT
1010
1011 @ENDNODE
1012 @NODE "xmSetPatternA" "xmodule/xmSetPatternA()"
1013 @{b}
1014
1015     NAME@{ub}
1016         xmSetPatternA -- Sets pattern attributes
1017         xmSetPattern -- Varargs stub for xmSetPatternA@{b}
1018
1019     SYNOPSIS@{ub}
1020         success = xmSetPatternA(si, pattNum, tagList)
1021         D0                      A0  D0       A1
1022
1023         ULONG xmSetPatternA(@{"struct SongInfo" LINK "songclass.h/File" 284} *,ULONG,struct TagItem *);
1024
1025
1026         success = xmSetPattern (si,pattNum,tag1,...)
1027
1028         ULONG xmSetPattern(@{"struct SongInfo" LINK "songclass.h/File" 284} *,ULONG,LONG Tag1,...);@{b}
1029
1030     FUNCTION@{ub}
1031         Sets attributes of a pattern by calling the @{"SNGM_SETPATTERN" LINK "songclass.h/File" 30} method.@{b}
1032
1033     INPUTS@{ub}
1034         si - pointer to the song which contains the pattern to be set.
1035         tagList - list of attributes to set.  See @{"SNGM_SETPATTERN" LINK "songclass.h/File" 30} for
1036             possible tags.@{b}
1037
1038     RESULT@{ub}
1039         Non zero for success@{b}
1040
1041     NOTE@{ub}
1042         In order to set patterns attributes, you should have exclusive
1043         access to the song.  Always obtain a lock before you call this
1044         function on public songs.@{b}
1045
1046     SEE ALSO@{ub}
1047         @{"xmAddPattern()" LINK "xmAddPatternA"}, @{"songclass" LINK "songclass/MAIN"}/SNGM_SETPATTERN
1048
1049 @ENDNODE
1050 @NODE "xmSetSongLen" "xmodule/xmSetSongLen()"
1051 @{b}
1052
1053     NAME@{ub}
1054         xmSetSongLen -- Set the number of song positions@{b}
1055
1056     SYNOPSIS@{ub}
1057         sequence = xmSetSongLen(songInfo, length)
1058         D0                      A0        D0:16
1059
1060         UWORD *xmSetSongLen(@{"struct SongInfo" LINK "songclass.h/File" 284} *, UWORD);@{b}
1061
1062     FUNCTION@{ub}
1063         Allocates space in the song for a sequence table of the given
1064         length. If no sequence exists yet, a new one is allocated.
1065         Increasing the song length may require the sequence table to be
1066         expanded, in which case it will be re-allocated and the old sequence
1067         entries will be copied. Decreasing the song length could also cause
1068         a reallocation of the sequence table if the size drops down enough.
1069         Setting the song length to 0 will free the sequence table and return
1070         NULL.@{b}
1071
1072     INPUTS@{ub}
1073         songInfo - pointer to a SongInfo structure.
1074         length - new length of song sequence table.@{b}
1075
1076     NOTE@{ub}
1077         This function will also adjust the CurrentPos field if it is found
1078         beyond the song end@{b}
1079
1080     BUGS@{ub}
1081         This funtion is quite useless because all it does is setting the
1082         @{"SNGA_Length" LINK "songclass.h/File" 88} attribute in the song object.  Setting the @{"SNGA_Length" LINK "songclass.h/File" 88}
1083         attribute yourself is easier and faster if you are already setting
1084         other attributes in the same song.@{b}
1085
1086    RESULT@{ub}
1087         Pointer to the newly allocated sequence table or NULL for failure,
1088         in which case the previous sequence table is left untouched.
1089
1090 @ENDNODE