
***********************************************************
*
  PureBasic Library SDK V1.1
*
***********


  Introduction:
  -------------

  The PureBasic is mainly based on its third libraries which
  allow it to handle differents objects very easely. These libs
  have to be written in pure 680x0 or PowerPC assembler for
  maximum speed and compactness. To achieve this, a set of
  macros and constants have been designed to make the coder
  life easier.

  Only the 680x0 package is available, as the PPC support is still
  not finished. The macro file is designed for PhxAss, a very good
  assembler which is located in the 'PureBasic:Compiler/' directory.

  You can create a library for 68000, 68020+ or any other processors
  of the 680x0 family. You are free to use the FPU or not. BUT if a
  library isn't compatible with the 'small' 68000, please tell it
  in the documentation of your library.

  The libraries you made are under your copyright, if you are a regular
  PureBasic user. So you can spread in any forms (freeware, shareware..).


  The library structure:
  ----------------------

  PureBasic libraries aren't standard Amiga linkable object,
  so you can't reuse the code with another compiler. They are their
  own structure to allow to split the library into little parts and
  link only the needed one to the final executable. So you can
  build a 100 Kb library with tons of functions, and if the
  program use only a function, only this function will be linked.

  This suppose one thing: the code of each function MUST be relocatable
  and fixed jump AREN'T allowed (or only if the part is inside the function).

  Each library has 2 parts:

    + The code, with functions
    + The base of the library. This base is an area of memory you can
    define to feed your need and which all functions could access later.
    It's very handy to store some variables which could be used by
    other functions. The access to this base memory will be done
    trough the register 'a5'

  Example:

  ...Code part...

   base
     Dc.l 0  ; First shared variable
     Dc.l 0  ; Second one


   To access the first variable in a function, just use:

   MOVE.l  (a5),<your reg>  ; Read the content of first variable
   MOVE.l 4(a5),<your reg>  ; Read the content of second variable

   To write in these variables, use:

   MOVE.l xx,(a5)
   MOVE.l xx,4(a5)

   Note: the base is always linked in the executable, so please,
         don't do huge base !



  General rules:
  --------------

  * You can't detroy the registers: a2/a3/a4/a7. Always preserve them.
  * Always use continus registers (ie: d0, d1 and d2). Don't use the
    registers in any orders if not needed (ie: d0, d5 and d7).
  * The return value (if any) must be LONG typed ! So you want to
    return a BYTE or WORD, use 'EXT' ASM keyword before returning.
  * Never use absolute jump from one function to another.
  * You're allowed to create a 'dc' zone for each function, so use
    it ! Example:

        debugger 1

      Example:
        MOVE.l $4,a6
        LEA    Label1(pc),a0
        RTS

      Label1:
        DC.b "Hello...",0

        endfunc 1


  Global routines:
  ----------------

  * ReAllocGlobalBank:

  Useful for bank object allocation and dynamic reallocation. This
  means than the old bank can 'grow' (the content of the old bank
  is copied into the new allocated one.

  It's safe to pass a null pointer for memory addr -> a standard
  empty memory bank will be created (first call).

  Call:

  a0: Old memory bank addr
  d0: New size for the new bank
  MOVE.l 68(a4),a0
  JSR    (a0)


  The macros:
  -----------

  Here is a quick description of the macro availables to build a library.
  ALL the macros are needed ! None are optionals.

  ** name   "FunctionName", "QuickHelp"

  ** flags Flags

    Possible flags:

    'StringResult' or 'LongResult' or 'ByteResult' : Type of result for the function (default is 'word')
    'NoBase' : If set, the function don't need to access the global base
    'InLine' : If set, the function can be inlined and follow the inline rules

    Flags can be OR'ed together if needed

    ex: flags LongResult | NoBase | InLine

  ** amigalibs LibName, RegName, ...

    Possible LibName: _ExecBase, _IntuitionBase, _DosBase, _GraphicsBase
    Possible RegName: d0 to d7, a0,a1,a6. Other are strictly forbidden !


    Example: amigalibs _DosBase, a6

    Before the function call, the a6 register will be loaded with the
    dos.library pointer.


  ** params Reg_Type, ...

    The registers name and type with will contain the parameters:
    d0_b : load a 'Byte' value into d0
    d0_w : load a 'Word' value into d0
    d0_l : load a 'Long' value into d0
    d0_s : load a 'string address' into d0

    Note: You can't use the a2,a3,a4,a5,a6 registers !

    Ex: params d0_l, d1_l, a0_s ; a 3 parameters function


  ** debugger Id_Function, LabelDebugger

  ** endfunc Id_Function

    The code of the functions must be between the 'debugger' and 'endfunc'
    keywords. The 'Id_Function' must be the different for each function.


  ** base

    declare the start of the base memory area


  ** endlib

    finish the library


  ** startdebugger

    Declare the debugger zone, with all debugger function within.


  ** enddebugger

    Finish the debugger zone.




  Just open the 'TagList.asm' example and look, it's not so hard !

            Good luck :-)


  PS: the commandline to compile the source under PhxAss:

  PhxAss TagList.asm TO Ram:TagList OPT 3
