[Contents] [Index] [Help] [Retrace] [Browse <] [Browse >]

To call a function in an Amiga system library, an assembler application
must put the library's base address in register A6 and JSR to the
function's LVO relative to A6.  For example to call the Intuition function
DisplayBeep():


;***********************************************************************
        xref    _LVODisplayBeep
;...
        move.l  A6, -(sp)               ;save the current contents of A6
;---- intuition.library must already be opened
;---- and IntuitionBase must contain its base address
        move.l  IntuitionBase, A6       ;put intuition base pointer in A6
        jsr     _LVODisplayBeep(A6)     ;call DisplayBeep()
        move.l  (SP)+, A6               ;restore A6 to its original value


IntuitionBase contains a pointer to the Intuition library's library base
and _LVODisplayBeep is the LVO for the DisplayBeep() function.  The
external reference (xref) to _LVODisplayBeep is resolved from the linker
library, amiga.lib.  This linker library contains the LVO's for all of the
standard Amiga libraries.  Each LVO label starts with "_LVO" followed by
the name of the library function.

    System Functions Do Not Preserve D0, D1, A0 and A1.
    ---------------------------------------------------
    If you need to preserve D0, D1, A0, or A1 between calls to system
    functions, you will have to save and restore these values yourself.
    Amiga system functions use these registers as scratch registers and
    may write over the values your program left in these registers.  The
    system functions preserve the values of all other registers.  The
    result of a system function, if any, is returned in D0.


      Some Task             LVO Table                  LibFuncY()
      ---------         __________________             ----------
                       |                  |
                       |        ·         |
      main()           |        ·         |
         ·             | JMP to LibFuncZ  |       {
         ·             |- - - - - - - - - |         blah = openblah();
         x=       ____\| JMP to LibFuncY  |____\    dosomething();
      LibFuncY()      /|- - - - - - - - - |    /    closeblah(blah);
         ·             | JMP to LibFuncX  |       }
         ·             |        ·         |
                       |        ·         |
                       |__________________|
                       |                  |
                       |   Library Base   |
                       |__________________|

   A task calls a        which calls the          which JMP's to the
  library function...  functions JMP vector...  actual library function.


                 Figure 17-2: Calling a Library Function


The example above is the actual assembly code generated by the macro named
LINKLIB, which is defined in <exec/libraries.i>.  The following fragment
performs the same function as the fragment above:

    LINKLIB _LVODisplayBeep, IntuitionBase

The amiga.lib linker library also contains small functions called stubs
for each function in the Amiga OS.  These stubs are normally for use with
C code.

Function parameters in C are normally pushed on the stack when a program
calls a function.  This presents a bit of a problem for the C programmer
when calling Amiga OS functions because the Amiga OS functions expect
their parameters to be in specific CPU registers. Stubs solve this problem
by copying the parameters from the stack to the appropriate register.

For example, the Autodoc for the Intuition library function MoveWindow()
shows which registers MoveWindow() expects its parameters to be:

    MoveWindow(window, deltaX, deltaY);
                 A0      D0      D1

The stub for MoveWindow() in amiga.lib has to copy window to register A0,
deltaX to register D0, and deltaY to register D1.

The stub also copies Intuition library base into A6 and does an
address-relative JSR to MoveWindow()'s LVO (relative to A6).  The stub
gets the library base from a global variable in your code called
IntuitionBase.  If you are using the stubs in amiga.lib to call Intuition
library functions, you must declare a global variable called
IntuitionBase.  It must be called IntuitionBase because amiga.lib is
specifically looking for the label IntuitionBase.

    /* This global declaration is here so amiga.lib can find
       the intuition.library base pointer.
    */
    struct Library *IntuitionBase;
            ...

    void main(void)
    {
            ...

            /* initialize IntuitionBase */
            if (IntuitionBase = OpenLibrary("intuition.library", 33L))
            {
                    ...

                    /* When this code gets linked with amiga.lib, the
                       linker extracts the DisplayBeep() stub routine from
                       from amiga.lib and copies it into the executable.
                       The stub copies whatever is in the variable
                       IntuitionBase into A6, and JSRs to
                       _LVODisplayBeep(A6).
                    */
                    DisplayBeep();
                    ...

                    CloseLibrary(IntuitionBase);
            }
            ...
    }

There is a specific label in amiga.lib for the library base of every
library in the Amiga operating system.  The chart below lists the names of
the library base pointer amiga.lib associates with each Amiga OS library.
The labels for library bases are also in the "Function Offsets Reference"
list in the Amiga ROM Kernel Reference Manual: Includes and Autodocs.


                Table 17-1: Amiga.lib Library Base Labels
       _________________________________________________________
      |                                                         |
      |   Library Name                Library Base Pointer Name |
      |---------------------------------------------------------|
      |   asl.library                 AslBase                   |
      |   commodities.library         CxBase                    |
      |   diskfont.library            DiskfontBase              |
      | * dos.library                 DOSBase                   |
      | * exec.library                SysBase                   |
      |   expansion.library           ExpansionBase             |
      |   gadtools.library            GadToolsBase              |
      |   graphics.library            GfxBase                   |
      |   icon.library                IconBase                  |
      |   iffparse.library            IFFParseBase              |
      |   intuition.library           IntuitionBase             |
      |   keymap.library              KeyMapBase                |
      |   layers.library              LayersBase                |
      |   mathffp.library             MathBase                  |
      |   mathieeedoubbas.library     MathIeeeDoubBasBase       |
      |   mathieeedoubtrans.library   MathIeeeDoubTransBase     |
      |   mathieeesingbas.library     MathIeeeSingBasBase       |
      |   mathieeesingtrans.library   MathIeeeSingTransBase     |
      |   mathtrans.library           MathTransBase             |
      |   rexxsys.library             RexxSysBase               |
      |   rexxsupport.library         RexxSupBase               |
      |   translator.library          TranslatorBase            |
      |   utility.library             UtilityBase               |
      |   version .library             (system private)          |
      |   workbench.library           WorkbenchBase             |
      |   Library Name                Library Base Pointer Name |
      |---------------------------------------------------------|
      | * Automatically opened by the standard C startup module |
      |_________________________________________________________|


The chart mentions that SysBase and DOSBase are already set up by the
standard C startup module.  For more information on the startup module,

    You May Not Need amiga.lib.
    ---------------------------
    Many C compilers provide ways of using pragmas or registerized
    parameters, so that a C program does not have to link with an
    amiga.lib stub to access a library function.  See your compiler
    documentation for more details.