Topic : TOS - The Operating System Author : Version : tos.hyp (December 19, 2008) Subject : Programmieren/Atari Nodes : 3010 Index Size : 93790 HCP-Version : 5 Compiled on : Atari @charset : atarist @lang : @default : Title @help : @options : +g -i -s +x +zz -t4 @width : 70 View Ref-File11.5.18.4 How do I write a library? TOS For this too there is a sample library SLB_DEMO, which contains all the required elements and descriptions. The best thing is to copy SLB_DEMO.C, LIBHEAD.S and SLB_DEMO.PRJ and then modify the files to suit your requirements. It is most important to ensure that bit 3 of the flag in the program header of a library is set; one can use PH_BIT3.TTP for this. LIBHEAD is the header for a shared library. The pointer to the function names can be omitted, otherwise it points to a table of pointers with the names of the library functions. The number of functions must be stated correctly, as must the table of functions and the library name, which is identical to the filename. When adding a function one has to ensure that the function number is adapted accordingly, and perhaps that the version number is increased. For publicly available shared libraries one has to ensure that documented function calls are never altered! They can either be supplemented with new parameters (the called function can inquire the number of parameters actually passed), or a new function number should be used. NULL-pointers are also permissible for the function pointers; they return a EINVFN when the function is called. The following functions for (de-)initialization are obligatory: slb_init/slb_exit These are called during loading and removal of the library respectively, and at that in supervisor-mode and in the context (process) of the library. Typically, slb_init loads a configuration file, allocates global memory for the library and opens a virtual VDI workstation. slb_exit writes back the configuration file, releases the memory again and closes the VDI workstation. If slb_init opens a file, then the handle can only be accessed again at slb_exit, as all other calls of the library run in the context of the calling application. From MagiC 6 onwards the library is passed a normal 'C' character string in the command line structure which contains the complete path of the shared library. If the shared library has to load configuration or RSC files, the path can be extracted and the filename of the configuration file assembled correspondingly. If slb_init terminates by reason of a bus error, for instance, then the caller will get EXCPT as the result of the Slbopen call. In order to intercept an unplanned termination of the library, the kernel installs an etv_term handler for the library before calling slb_init/exit. slb_open/slb_close These are called at the opening or closing of the library respectively. Once the library has been opened, the order is: slb_init slb_open slb_close slb_exit Unlike slb_init/slb_exit, slb_open/slb_close run in the context of the caller and in user-mode, with the user-stack of the caller, even if the Slbopen call was performed in supervisor-mode. The library can also allocate memory at slb_open, though this belongs to the caller and should be released again at slb_close. In order to permit allocation of this reserved memory to the caller, the library is also passed the current process descriptor at slb_open, slb_close and at every function call. Warning: Due to a bug in 5.20, the passing of the PD to slb_open and slb_close only works from MagiC 6 onwards. The kernel ensures that the open/close calls are nested correctly, i.e. a process can not open a library more than once. The kernel ensures that the open/close calls are nested correctly, i.e. a process cannot open a library more than once. Functions Functions are not obligatory, so a library can hook in system calls also via the AES or DOS that are removed again at termination, yet generally functions are made available. A function is called with the following parameters on the stack: PD *pd Process descriptor of the caller, corresponds to the associated slb_open()/close() LONG fn Function number. Practical when several functions are amalgamated (identical function pointers in LIBHEAD) WORD nargs Number of the following arguments, in WORDs. If a function has a variable number of parameters, one can ascertain the actual number. Very useful for extensions, without having to incorporate new functions. Example: If a function always expects a pointer, but optionally also a WORD, it will receive either 2 or 3 as nargs. ... The remaining parameters The functions are executed in the context of the caller and with its stack. As this call is generally made in user-mode, multitasking will not be interrupted even for longer operations. Depending on the function, the function result can be a LONG, a WORD, void etc. A function may alter registers d0-d2 and a0-a1, all other registers have to be saved if appropriate. In particular, register a2 must not be altered, so that Pure-C routines may be called.