@database "exec"
@master "Work:RKM/Includes&Autodocs/doc/exec.doc"

@Node Main "exec.doc"
@toc "2.0Includes_Autodocs/Autodocs"

@{" AbortIO() " Link "AbortIO()"}           @{" Debug() " Link "Debug()"}                  @{" PutMsg() " Link "PutMsg()"}
@{" AddDevice() " Link "AddDevice()"}         @{" DeleteIORequest() " Link "DeleteIORequest()"}        @{" RawDoFmt() " Link "RawDoFmt()"}
@{" AddHead() " Link "AddHead()"}           @{" DeleteMsgPort() " Link "DeleteMsgPort()"}          @{" ReleaseSemaphore() " Link "ReleaseSemaphore()"}
@{" AddIntServer() " Link "AddIntServer()"}      @{" Disable() " Link "Disable()"}                @{" ReleaseSemaphoreList() " Link "ReleaseSemaphoreList()"}
@{" AddLibrary() " Link "AddLibrary()"}        @{" DoIO() " Link "DoIO()"}                   @{" RemDevice() " Link "RemDevice()"}
@{" AddMemList() " Link "AddMemList()"}        @{" Enable() " Link "Enable()"}                 @{" RemHead() " Link "RemHead()"}
@{" AddPort() " Link "AddPort()"}           @{" Enqueue() " Link "Enqueue()"}                @{" RemIntServer() " Link "RemIntServer()"}
@{" AddResource() " Link "AddResource()"}       @{" FindName() " Link "FindName()"}               @{" RemLibrary() " Link "RemLibrary()"}
@{" AddSemaphore() " Link "AddSemaphore()"}      @{" FindPort() " Link "FindPort()"}               @{" Remove() " Link "Remove()"}
@{" AddTail() " Link "AddTail()"}           @{" FindResident() " Link "FindResident()"}           @{" RemPort() " Link "RemPort()"}
@{" AddTask() " Link "AddTask()"}           @{" FindSemaphore() " Link "FindSemaphore()"}          @{" RemResource() " Link "RemResource()"}
@{" Alert() " Link "Alert()"}             @{" FindTask() " Link "FindTask()"}               @{" RemSemaphore() " Link "RemSemaphore()"}
@{" AllocAbs() " Link "AllocAbs()"}          @{" Forbid() " Link "Forbid()"}                 @{" RemTail() " Link "RemTail()"}
@{" Allocate() " Link "Allocate()"}          @{" FreeEntry() " Link "FreeEntry()"}              @{" RemTask() " Link "RemTask()"}
@{" AllocEntry() " Link "AllocEntry()"}        @{" FreeMem() " Link "FreeMem()"}                @{" ReplyMsg() " Link "ReplyMsg()"}
@{" AllocMem() " Link "AllocMem()"}          @{" FreeSignal() " Link "FreeSignal()"}             @{" SendIO() " Link "SendIO()"}
@{" AllocSignal() " Link "AllocSignal()"}       @{" FreeTrap() " Link "FreeTrap()"}               @{" SetExcept() " Link "SetExcept()"}
@{" AllocTrap() " Link "AllocTrap()"}         @{" FreeVec() " Link "FreeVec()"}                @{" SetFunction() " Link "SetFunction()"}
@{" AllocVec() " Link "AllocVec()"}          @{" GetCC() " Link "GetCC()"}                  @{" SetIntVector() " Link "SetIntVector()"}
@{" AttemptSemaphore() " Link "AttemptSemaphore()"}  @{" GetMsg() " Link "GetMsg()"}                 @{" SetSignal() " Link "SetSignal()"}
@{" AvailMem() " Link "AvailMem()"}          @{" InitCode() " Link "InitCode()"}               @{" SetSR() " Link "SetSR()"}
@{" CacheClearE() " Link "CacheClearE()"}       @{" InitResident() " Link "InitResident()"}           @{" SetTaskPri() " Link "SetTaskPri()"}
@{" CacheClearU() " Link "CacheClearU()"}       @{" InitSemaphore() " Link "InitSemaphore()"}          @{" Signal() " Link "Signal()"}
@{" CacheControl() " Link "CacheControl()"}      @{" InitStruct() " Link "InitStruct()"}             @{" StackSwap() " Link "StackSwap()"}
@{" CachePostDMA() " Link "CachePostDMA()"}      @{" Insert() " Link "Insert()"}                 @{" SumKickData() " Link "SumKickData()"}
@{" CachePreDMA() " Link "CachePreDMA()"}       @{" MakeFunctions() " Link "MakeFunctions()"}          @{" SumLibrary() " Link "SumLibrary()"}
@{" Cause() " Link "Cause()"}             @{" MakeLibrary() " Link "MakeLibrary()"}            @{" SuperState() " Link "SuperState()"}
@{" CheckIO() " Link "CheckIO()"}           @{" ObtainSemaphore() " Link "ObtainSemaphore()"}        @{" Supervisor() " Link "Supervisor()"}
@{" CloseDevice() " Link "CloseDevice()"}       @{" ObtainSemaphoreList() " Link "ObtainSemaphoreList()"}    @{" TypeOfMem() " Link "TypeOfMem()"}
@{" CloseLibrary() " Link "CloseLibrary()"}      @{" ObtainSemaphoreShared() " Link "ObtainSemaphoreShared()"}  @{" UserState() " Link "UserState()"}
@{" ColdReboot() " Link "ColdReboot()"}        @{" OldOpenLibrary() " Link "OldOpenLibrary()"}         @{" Vacate() " Link "Vacate()"}
@{" CopyMem() " Link "CopyMem()"}           @{" OpenDevice() " Link "OpenDevice()"}             @{" Wait() " Link "Wait()"}
@{" CopyMemQuick() " Link "CopyMemQuick()"}      @{" OpenLibrary() " Link "OpenLibrary()"}            @{" WaitIO() " Link "WaitIO()"}
@{" CreateIORequest() " Link "CreateIORequest()"}   @{" OpenResource() " Link "OpenResource()"}           @{" WaitPort() " Link "WaitPort()"}
@{" CreateMsgPort() " Link "CreateMsgPort()"}     @{" Permit() " Link "Permit()"}
@{" Deallocate() " Link "Deallocate()"}        @{" Procure() " Link "Procure()"}

@EndNode

@Node "AbortIO()" "exec.library/AbortIO"

NAME
    AbortIO - attempt to abort an in-progress I/O request

SYNOPSIS
    AbortIO(iORequest)
            A1

    VOID AbortIO(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    Ask a device to abort a previously started @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}.  This is done
    by calling the device's ABORTIO vector, with your given @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}.


    AbortIO is a command the device that may or may not grant.  If
    successful, the device will stop processing the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}, and
    reply to it earlier than it would otherwise have done.

NOTE
    AbortIO() does NOT @{"Remove()" Link "Remove()"} the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} from your ReplyPort, OR
    wait for it to complete.  After an AbortIO() you must wait normally
    for the reply message before actually reusing the request.

    If a request has already completed when AbortIO() is called, no
    action is taken.

EXAMPLE
        AbortIO(timer_request);
        WaitIO(timer_request);
        /* @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} is free to be reused */

INPUTS
    iORequest - pointer to an I/O request block (must have been used
            at least once.  May be active or finished).

SEE ALSO
    @{"WaitIO" link "WaitIO()"}, @{"DoIO" link "DoIO()"}, @{"SendIO" link "SendIO()"}, @{"CheckIO" link "CheckIO()"}

@EndNode

@Node "AddDevice()" "exec.library/AddDevice"

NAME
    AddDevice -- add a device to the system

SYNOPSIS
    AddDevice(device)
              A1

    void AddDevice(struct @{"Device" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 25} *);

FUNCTION
    This function adds a new device to the system device list, making
    it available to other programs.  The device must be ready to be
    opened at this time.

INPUTS
    device - pointer to a properly initialized device node

SEE ALSO
    @{"RemDevice" link "RemDevice()"}, @{"OpenDevice" Link "OpenDevice()"}, @{"CloseDevice" Link "serial/CloseDevice()"}, @{"MakeLibrary" link "MakeLibrary()"}

@EndNode

@Node "AddHead()" "exec.library/AddHead"

NAME
    AddHead -- insert node at the head of a list

SYNOPSIS
    AddHead(list, node)
            A0    A1

    void AddHead(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *, struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *)

FUNCTION
    Add a node to the head of a doubly linked list. Assembly
    programmers may prefer to use the ADDHEAD macro from
    "exec/lists.i".

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    list - a pointer to the target list header
    node - the node to insert at head

SEE ALSO
    @{"AddTail" link "AddTail()"}, @{"Enqueue" link "Enqueue()"}, Insert, Remove, @{"RemHead" link "RemHead()"}, @{"RemTail" link "RemTail()"}

@EndNode

@Node "AddIntServer()" "exec.library/AddIntServer"

NAME
    AddIntServer -- add an interrupt server to a system server chain

SYNOPSIS
    AddIntServer(intNum, interrupt)
                 D0-0:4  A1

    void AddIntServer(ULONG, struct @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} *);

FUNCTION
    This function adds a new interrupt server to a given server chain.
    The node is located on the chain in a priority dependent position.
    If this is the first server on a particular chain, interrupts will
    be enabled for that chain.

    Each link in the chain will be called in priority order until the
    chain ends or one of the servers returns with the 68000's Z condition
    code clear (indicating non-zero).  Servers on the chain should return
    with the Z flag clear if the interrupt was specifically for that
    server, and no one else.  VERTB servers should always return Z set.
    (Take care with High Level Language servers, the language may not
    have a mechanism for reliably setting the Z flag on exit).

    Servers are called with the following register conventions:

        D0 - scratch
        D1 - scratch

        A0 - scratch
        A1 - server is_Data pointer (scratch)

        A5 - jump vector register (scratch)
        A6 - scratch

        all other registers must be preserved

INPUTS
    intNum - the Paula interrupt bit number (0 through 14). Processor
             level seven interrupts (NMI) are encoded as intNum 15.
             The PORTS, COPER, VERTB, EXTER and NMI interrupts are
             set up as server chains.
    interrupt - pointer to an @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} structure.
             By convention, the LN_NAME of the interrupt structure must
             point a descriptive string so that other users may
             identify who currently has control of the interrupt.

WARNING
    Some compilers or assemblers may optimize code in unexpected ways,
    affecting the conditions codes returned from the function.  Watch
    out for a "MOVEM" instruction (which does not affect the condition
    codes) turning into "MOVE" (which does).

BUGS
    The graphics library's VBLANK server, and some user code, currently
    assume that address register A0 will contain a pointer to the custom
    chips. If you add a server at a priority of 10 or greater, you must
    compensate for this by providing the expected value ($DFF000).

SEE ALSO
    @{"RemIntServer" link "RemIntServer()"}, @{"SetIntVector" link "SetIntVector()"}, hardware/intbits.i,exec/interrupts.i

@EndNode

@Node "AddLibrary()" "exec.library/AddLibrary"

NAME
    AddLibrary -- add a library to the system

SYNOPSIS
    AddLibrary(library)
               A1

    void AddLibrary(struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *);

FUNCTION
    This function adds a new library to the system, making it available
    to other programs.  The library should be ready to be opened at
    this time.  It will be added to the system library name list, and
    the checksum on the library entries will be calculated.

INPUTS
    library - pointer to a properly initialized library structure

SEE ALSO
    @{"RemLibrary" link "RemLibrary()"}, @{"CloseLibrary" link "CloseLibrary()"}, @{"OpenLibrary" link "OpenLibrary()"}, @{"MakeLibrary" link "MakeLibrary()"}

@EndNode

@Node "AddMemList()" "exec.library/AddMemList"

NAME
    AddMemList - add memory to the system free pool

SYNOPSIS
    AddMemList( size, attributes, pri, base, name )
                 D0      D1        D2   A0    A1

    void AddMemList(ULONG, ULONG, LONG, APTR, STRPTR);

FUNCTION
    Add a new region of memory to the system free pool.  The first few
    bytes will be used to hold the @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} structure.  The remainder
    will be made available to the rest of the world.

INPUTS
    size - the size (in bytes) of the memory area
    attributes - the attributes word that the memory pool will have
    pri  - the priority for this memory.  CHIP memory has a pri of -10,
           16 bit expansion memory has a priority of 0.  The higher the
           priority, the closer to the head of the memory list it will
           be placed.
    base - the base of the new memory area
    name - the name that will be used in the memory header, or NULL
           if no name is to be provided.  This name is not copied, so it
           must remain valid for as long as the memory header is in the
           system.

SEE ALSO
    @{"AllocMem" link "AllocMem()"}, @{"exec/memory.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 0}

@EndNode

@Node "AddPort()" "exec.library/AddPort"

NAME
    AddPort -- add a public message port to the system

SYNOPSIS
    AddPort(port)
            A1

    void AddPort(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *);

FUNCTION
    This function attaches a message port structure to the system's
    public message port list, where it can be found by the @{"FindPort()" Link "FindPort()"}
    function.  The name and priority fields of the port structure must
    be initialized prior to calling this function.  If the user does
    not require the priority field, it should be initialized to zero.

    Only ports that will be searched for with @{"FindPort()" Link "FindPort()"} need to
    be added to the system list.  In addition, adding ports is often
    useful during debugging.  If the port will be searched for,
    the priority field should be at least 1 (to avoid the large number
    of inactive ports at priority zero).  If the port will be searched
    for often, set the proritiry in the 50-100 range (so it will be
    before other less used ports).

    Once a port has been added to the naming list, you must be careful
    to remove the port from the list (via RemPort) before deallocating
    its memory.

NOTE
    A point of confusion is that clearing a @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} structure to all
    zeros is not enough to prepare it for use.  As mentioned in the
    Exec chapter of the ROM Kernel Manual, the @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} for the @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29}
    must be initialized.  This is automatically handled by AddPort(),
    and @{"amiga.lib/CreatePort" Link "amiga_lib/CreatePort()"}.  This initialization can be done manually
    with @{"amiga.lib/NewList" Link "amiga_lib/NewList()"} or the assembly NEWLIST macro.

    Do not AddPort an active port.

INPUTS
    port - pointer to a message port

SEE ALSO
    @{"RemPort" link "RemPort()"}, @{"FindPort" link "FindPort()"}, @{"amiga.lib/CreatePort" Link "amiga_lib/CreatePort()"}, @{"amiga.lib/NewList" Link "amiga_lib/NewList()"}

@EndNode

@Node "AddResource()" "exec.library/AddResource"

NAME
    AddResource -- add a resource to the system

SYNOPSIS
    AddResource(resource)
                A1

    void AddResource(APTR);

FUNCTION
    This function adds a new resource to the system and makes it
    available to other users.  The resource must be ready to be called
    at this time.

    Resources currently have no system-imposed structure, however they
    must start with a standard named node (LN_SIZE), and should with
    a standard @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} node (LIB_SIZE).

INPUTS
    resource - pointer an initialized resource node

SEE ALSO
    @{"RemResource" link "RemResource()"}, @{"OpenResource" link "OpenResource()"}, @{"MakeLibrary" link "MakeLibrary()"}

@EndNode

@Node "AddSemaphore()" "exec.library/AddSemaphore"

NAME
    AddSemaphore -- initialize then add a signal semaphore to the system

SYNOPSIS
    AddSemaphore(signalSemaphore)
                 A1

    void AddSemaphore(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    This function attaches a signal semaphore structure to the system's
    public signal semaphore list.  The name and priority fields of the
    semaphore structure must be initialized prior to calling this
    function.  If you do not want to let others rendezvous with this
    semaphore, use @{"InitSemaphore()" Link "InitSemaphore()"} instead.

    If a semaphore has been added to the naming list, you must be
    careful to remove the semaphore from the list (via RemSemaphore)
    before deallocating its memory.

    Semaphores that are linked together in an allocation list (which
    @{"ObtainSemaphoreList()" Link "ObtainSemaphoreList()"} would use) may not be added to the system
    naming list, because the facilities use the link field of the
    signal semaphore in incompatible ways

INPUTS
   signalSemaphore -- an signal semaphore structure

BUGS
    Does not work in Exec <V36.  Instead use this code:

        #include @{"<exec/execbase.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 0}
        #include @{"<exec/nodes.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 0}
        extern struct @{"ExecBase" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 35} *SysBase;
            ...
        void LocalAddSemaphore(s)
        struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *s;
        {
            s->ss_Link.ln_Type=NT_SIGNALSEM;
            InitSemaphore(s);
            Forbid();
            Enqueue(&SysBase->SemaphoreList,s);
            Permit();
        }

SEE ALSO
    @{"RemSemaphore" link "RemSemaphore()"}, @{"FindSemaphore" link "FindSemaphore()"}, @{"InitSemaphore" link "InitSemaphore()"}

@EndNode

@Node "AddTail()" "exec.library/AddTail"

NAME
    AddTail -- append node to tail of a list

SYNOPSIS
    AddTail(list, node)
            A0    A1

    void AddTail(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *, struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *);

FUNCTION
    Add a node to the tail of a doubly linked list.  Assembly
    programmers may prefer to use the ADDTAIL macro from
    "exec/lists.i".

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    list - a pointer to the target list header
    node - a pointer to the node to insert at tail of the list

SEE ALSO
    @{"AddHead" link "AddHead()"}, @{"Enqueue" link "Enqueue()"}, Insert, Remove, @{"RemHead" link "RemHead()"}, @{"RemTail" link "RemTail()"}

@EndNode

@Node "AddTask()" "exec.library/AddTask"

NAME
    AddTask -- add a task to the system

SYNOPSIS
    AddTask(task, initialPC, finalPC)
            A1    A2         A3

    APTR AddTask(struct @{"Task" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 25} *, APTR, APTR);

FUNCTION
    Add a task to the system.  A reschedule will be run; the task with
    the highest priority in the system will start to execute (this may
    or may not be the new task).

    Certain fields of the task control block must be initialized and a
    stack allocated prior to calling this function.  The absolute
    smallest stack that is allowable is something in the range of 100
    bytes, but in general the stack size is dependent on what
    subsystems are called. In general 256 bytes is sufficient if only
    Exec is called, and 4K will do if anything in the system is called.
    DO NOT UNDERESTIMATE.  If you use a stack sniffing utility,
    leave a healthy pad above the minimum value.  The system guarantees
    that its stack operations will leave the stack longword aligned.

    This function will temporarily use space from the new task's stack
    for the task's initial set of registers.  This space is allocated
    starting at the SPREG location specified in the task control block
    (not from SPUPPER).  This means that a task's stack may contain
    static data put there prior to its execution.  This is useful for
    providing initialized global variables or some tasks may want to
    use this space for passing the task its initial arguments.

    A task's initial registers are set to zero (except the PC).

    The TC_MEMENTRY field of the task structure may be extended by
    the user to hold additional MemLists (as returned by @{"AllocEntry()" Link "AllocEntry()"}).
    These will be automatically be deallocated at @{"RemTask()" Link "RemTask()"} time.
    If the code you have used to start the task has already added
    something to the MEMENTRY list, simply use @{"AddHead" link "AddHead()"} to add your
    new MemLists in.  If no initialization has been done, a @{"NewList" Link "amiga_lib/NewList()"} will
    need to be performed.

INPUTS
    task  - pointer to the task control block (TCB).  All unset fields
            must be zero.
    initialPC - the initial entry point's address
    finalPC - the finalization code entry point's address.  If zero,
              the system will use a general finalizer. This pointer is
              placed on the stack as if it were the outermost return
              address.

RESULTS
    For V36, AddTask returns either a NULL or the address of the new
    task.  Old code need not check this.

WARNING
    Tasks are a low-level building block, and are unable to call
    dos.library, or any system function that might call dos.library.
    See the AmigaDOS @{"CreateProc()" Link "dos/CreateProc()"} for information on Processes.

SEE ALSO
    @{"RemTask" link "RemTask()"}, @{"FindTask" link "FindTask()"}, @{"amiga.lib/CreateTask" Link "amiga_lib/CreateTask()"}, @{"dos/CreateProc" Link "dos/CreateProc()"},
    @{"amiga.lib/NewList" Link "amiga_lib/NewList()"}

@EndNode

@Node "Alert()" "exec.library/Alert"

NAME
    Alert -- alert the user of an error

SYNOPSIS
    Alert(alertNum)
          D7

    void Alert(ULONG);

FUNCTION
    Alerts the user of a serious system problem.  This function will
    bring the system to a grinding halt, and do whatever is necessary
    to present the user with a message stating what happened.
    Interrupts are disabled, and an attempt to post the alert is made.
    If that fails, the system is reset.  When the system comes up
    again, Exec notices the cause of the failure and tries again to
    post the alert.

    If the Alert is a recoverable type, this call MAY return.

    This call may be made at any time, including interrupts.

POST-MORTEM DIAGNOSIS
    There are several options for determining the cause of a crash.
    Descriptions of each alert number can be found in the "alerts.h"
    include file.  Low numbers not mentioned in the include file
    represent 68000 exceptions, see a 68000 manual for details.  The
    most common numbers are:
                    $00000003 - Address Error
                    $00000004 - Illegal Instruction

    A remote terminal can be attached to the Amiga's first built-in
    serial port.  Set the communication parameters to 9600 baud, 8 bits,
    no parity.  Before resetting the machine, the Alert function will
    blink the power LED 10 times.  While the power indicator is flashing,
    pressing DELETE on the remote terminal will invoke the ROMWack
    debugger.

    For Alerts caused by a 68000 exception, all registers are copied
    to a magic low memory location (currently 16 longwords at $180).

INPUT
    alertNum   - a number indicating the particular alert.  -1 is
            not a valid input.

NOTE
    Much more needs to be said about this function and its implications.

SEE ALSO
    @{"exec/alerts.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/alerts.h/Main" 0}

@EndNode

@Node "AllocAbs()" "exec.library/AllocAbs"

NAME
    AllocAbs -- allocate at a given location

SYNOPSIS
    memoryBlock = AllocAbs(byteSize, location)
    D0                     D0        A1

    void *AllocAbs(ULONG, APTR);

FUNCTION
    This function attempts to allocate memory at a given absolute
    memory location.  Often this is used by boot-surviving entities
    such as recoverable ram-disks.  If the memory is already being
    used, or if there is not enough memory to satisfy the request,
    AllocAbs will return NULL.

    This block may not be exactly the same as the requested block
    because of rounding, but if the return value is non-zero, the block
    is guaranteed to contain the requested range.

INPUTS
    byteSize - the size of the desired block in bytes
               This number is rounded up to the next larger
               block size for the actual allocation.
    location - the address where the memory MUST be.


RESULT
    memoryBlock - a pointer to the newly allocated memory block, or
                  NULL if failed.

NOTE
    If the free list is corrupt, the system will panic with alert
    AN_MemCorrupt, $01000005.

    The 8 bytes past the end of an AllocAbs will be changed by Exec
    relinking the next block of memory.  Generally you can't trust
    the first 8 bytes of anything you AllocAbs.

SEE ALSO
    @{"AllocMem" link "AllocMem()"}, @{"FreeMem" link "FreeMem()"}

@EndNode

@Node "Allocate()" "exec.library/Allocate"

NAME
    Allocate - allocate a block of memory

SYNOPSIS
    memoryBlock=Allocate(memHeader, byteSize)
    D0                   A0         D0

    void *Allocate(struct @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} *, ULONG);

FUNCTION
    This function is used to allocate blocks of memory from a given
    private free memory pool (as specified by a @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} and its
    memory chunk list).  Allocate will return the first free block that
    is greater than or equal to the requested size.

    All blocks, whether free or allocated, will be block aligned;
    hence, all allocation sizes are rounded up to the next block even
    value (e.g. the minimum allocation resolution is currently 8
    bytes.  A request for 8 bytes will use up exactly 8 bytes.  A
    request for 7 bytes will also use up exactly 8 bytes.).

    This function can be used to manage an application's internal data
    memory.  Note that no arbitration of the @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} and associated
    free chunk list is done.  You must be the owner before calling
    Allocate.

INPUTS
    memHeader - points to the local memory list header.
    byteSize - the size of the desired block in bytes.

RESULT
    memoryBlock - a pointer to the just allocated free block.
           If there are no free regions large enough to satisfy the
           request, return zero.

EXAMPLE
    #include @{"<exec/types.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/types.h/Main" 0}
    #include @{"<exec/memory.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 0}
    void *AllocMem();
    #define BLOCKSIZE 4096L /* Or whatever you want */

    void main()
    {
    struct @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} *mh;
    struct @{"MemChunk" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 21}  *mc;
    APTR   block1;
    APTR   block2;

        /* Get the @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} needed to keep track of our new block */
        mh = (struct @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} *)
             AllocMem((long)sizeof(struct MemHeader), MEMF_CLEAR );
        if( !mh )
            exit(10);

        /* Get the actual block the above @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} will manage */
        mc = (struct @{"MemChunk" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 21} *)AllocMem( BLOCKSIZE, 0L );
        if( !mc )
            {
            FreeMem( mh, (long)sizeof(struct MemHeader) ); exit(10);
            }

        mh->mh_Node.ln_Type = NT_MEMORY;
        mh->mh_Node.ln_Name = "myname";
        mh->mh_First = mc;
        mh->mh_Lower = (APTR) mc;
        mh->mh_Upper = (APTR) ( BLOCKSIZE + (ULONG) mc );
        mh->mh_Free  = BLOCKSIZE;

        /* Set up first chunk in the freelist */
        mc->mc_Next  = NULL;
        mc->mc_Bytes = BLOCKSIZE;

        block1 = (APTR) Allocate( mh, 20L );
        block2 = (APTR) Allocate( mh, 314L );
        printf("mh=$%lx mc=$%lx\n",mh,mc);
        printf("Block1=$%lx, Block2=$%lx\n",block1,block2);

        FreeMem( mh, (long)sizeof(struct MemHeader) );
        FreeMem( mc, BLOCKSIZE );
    }

NOTE
    If the free list is corrupt, the system will panic with alert
    AN_MemCorrupt, $01000005.

SEE ALSO
    Deallocate, @{"exec/memory.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 0}

@EndNode

@Node "AllocEntry()" "exec.library/AllocEntry"

NAME
    AllocEntry -- allocate many regions of memory

SYNOPSIS
    memList = AllocEntry(memList)
    D0                   A0

    struct @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} *AllocEntry(struct @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} *);

FUNCTION
    This function takes a memList structure and allocates enough memory
    to hold the required memory as well as a @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} structure to keep
    track of it.

    These @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} structures may be linked together in a task control
    block to keep track of the total memory usage of this task. (See
    the description of TC_MEMENTRY under RemTask).

INPUTS
    memList -- A @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} structure filled in with @{"MemEntry" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 41} structures.

RESULTS
    memList -- A different @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} filled in with the actual memory
        allocated in the me_Addr field, and their sizes in me_Length.
        If enough memory cannot be obtained, then the requirements of
        the allocation that failed is returned and bit 31 is set.

        WARNING: The result is unusual!  Bit 31 indicates faulure.

EXAMPLES
    The user wants five regions of 2, 4, 8, 16, and 32 bytes in size
    with requirements of MEMF_CLEAR, MEMF_PUBLIC, MEMF_CHIP!MEMF_CLEAR,
    MEMF_CLEAR, and MEMF_PUBLIC!MEMF_CLEAR respectively.  The
    following code fragment would do that:

        MemListDecl:
            DS.B    LN_SIZE             * reserve space for list node
            DC.W    5                   * number of entries
            DC.L    MEMF_CLEAR                  * entry #0
            DC.L    2
            DC.L    MEMF_PUBLIC                 * entry #1
            DC.L    4
            DC.L    MEMF_CHIP!MEMF_CLEAR        * entry #2
            DC.L    8
            DC.L    MEMF_CLEAR                  * entry #3
            DC.L    16
            DC.L    MEMF_PUBLIC!MEMF_CLEAR      * entry #4
            DC.L    32

        start:
            LEA.L   MemListDecl(PC),A0
            JSR     _LVOAllocEntry(a6)
            BCLR.L  #31,D0
            BEQ.S   success

            ------- Type of memory that we failed on is in D0

BUGS
    If any one of the allocations fails, this function fails to back
    out fully.  This is fixed by the "SetPatch" program on V1.3
    Workbench disks.

SEE ALSO
    @{"exec/memory.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 0}

@EndNode

@Node "AllocMem()" "exec.library/AllocMem"

NAME
    AllocMem -- allocate memory given certain requirements

SYNOPSIS
    memoryBlock = AllocMem(byteSize, attributes)
    D0                     D0        D1

    void *AllocMem(ULONG, ULONG);

FUNCTION
    This is the memory allocator to be used by system code and
    applications.  It provides a means of specifying that the allocation
    should be made in a memory area accessible to the chips, or
    accessible to shared system code.

    Memory is allocated based on requirements and options.  Any
    "requirement" must be met by a memory allocation, any "option" will
    be applied to the block regardless.  AllocMem will try all memory
    spaces until one is found with the proper requirements and room for
    the memory request.

INPUTS
    byteSize - the size of the desired block in bytes.  (The operating
            system will automatically round this number to a multiple of
            the system memory chunk size)

    attributes -
        requirements

            If no flags are set, the system will return the best
            available memory block.  For expanded systems, the fast
            memory pool is searched first.

            MEMF_CHIP:      If the requested memory will be used by
                            the Amiga custom chips, this flag *must*
                            be set.

                            Only certain parts of memory are reachable
                            by the special chip sets' DMA circuitry.
                            Chip DMA includes screen memory, images that
                            are blitted, audio data, copper lists, sprites
                            and Pre-V36 trackdisk.device buffers.


            MEMF_FAST:      This is non-chip memory.  If no flag is set
                            MEMF_FAST is taken as the default.

                            DO NOT SPECIFY MEMF_FAST unless you know
                            exactly what you are doing!  If MEMF_FAST is
                            set, AllocMem() will fail on machines that
                            only have chip memory!  This flag may not
                            be set when MEMF_CHIP is set.


            MEMF_PUBLIC:    Memory that must not be mapped, swapped,
                            or otherwise made non-addressable. ALL
                            MEMORY THAT IS REFERENCED VIA INTERRUPTS
                            AND/OR BY OTHER TASKS MUST BE EITHER PUBLIC
                            OR LOCKED INTO MEMORY! This includes both
                            code and data.


            MEMF_LOCAL:     This is memory that will not go away
                            after the CPU RESET instruction.  Normally,
                            autoconfig memory boards become unavailable
                            after RESET while motherboard memory
                            may still be available.  This memory type
                            is now automatically set in V36.  Pre-V36
                            systems may not have this memory type
                            and AllocMem() will then fail.


            MEMF_24BITDMA:  This is memory that is within the address
                            range of 24-bit DMA devices.  (Zorro-II)
                            This is required if you run a Zorro-II
                            DMA device on a machine that has memory
                            beyond the 24-bit addressing limit of
                            Zorro-II.  This memory type
                            is now automatically set in V36.  Pre-V36
                            systems may not have this memory type
                            and AllocMem() will then fail.


        options

            MEMF_CLEAR:     The memory will be initialized to all
                            zeros.


            MEMF_REVERSE:   This allocates memory from the top of
                            the memory pool.  It searches the pools
                            in the same order, such that FAST memory
                            will be found first.  However, the
                            memory will be allocated from the highest
                            address available in the pool.  This
                            option is new as of V36.


RESULT
    memoryBlock - a pointer to the newly allocated memory block.
            If there are no free memory regions large enough to satisfy
            the request, zero will be returned.  The pointer must be
            checked for zero before the memory block may be used!

WARNING
    The result of any memory allocation MUST be checked, and a viable
    error handling path taken.  ANY allocation may fail if memory has
    been filled.

EXAMPLES
    AllocMem(64,0L)         - Allocate the best available memory
    AllocMem(25,MEMF_CLEAR) - Allocate the best available memory, and
                              clear it before returning.
    AllocMem(128,MEMF_CHIP) - Allocate chip memory
    AllocMem(128,MEMF_CHIP|MEMF_CLEAR) - Allocate cleared chip memory
    AllocMem(821,MEMF_CHIP|MEMF_PUBLIC|MEMF_CLEAR) - Allocate cleared,
            public, chip memory.

NOTE
    If the free list is corrupt, the system will panic with alert
    AN_MemCorrupt, $01000005.

    This function may not be called from interrupts.

    A DOS process will have its pr_Result2 field set to
    ERROR_NO_FREE_STORE if the memory allocation fails.

SEE ALSO
    @{"FreeMem" link "FreeMem()"}

@EndNode

@Node "AllocSignal()" "exec.library/AllocSignal"

NAME
    AllocSignal -- allocate a signal bit

SYNOPSIS
    signalNum = AllocSignal(signalNum)
    D0                      D0

    BYTE AllocSignal(BYTE);

FUNCTION
    Allocate a signal bit from the current tasks' pool.  Either a
    particular bit, or the next free bit may be allocated.  The signal
    associated with the bit will be properly initialized (cleared).  At
    least 16 user signals are available per task.  Signals should be
    deallocated before the task exits.

    If the signal is already in use (or no free signals are available)
    a -1 is returned.

    Allocated signals are only valid for use with the task that
    allocated them.


WARNING
    Signals may not be allocated or freed from exception handling code.

INPUTS
    signalNum - the desired signal number {of 0..31} or -1 for no
                preference.

RESULTS
    signalNum - the signal bit number allocated {0..31}. If no signals
                are available, this function returns -1.

SEE ALSO
    @{"FreeSignal" link "FreeSignal()"}

@EndNode

@Node "AllocTrap()" "exec.library/AllocTrap"

NAME
    AllocTrap -- allocate a processor trap vector

SYNOPSIS
    trapNum = AllocTrap(trapNum)
    D0                  D0

    LONG AllocTrap(LONG);

FUNCTION
    Allocate a trap number from the current task's pool.  These trap
    numbers are those associated with the 68000 TRAP type instructions.
    Either a particular number, or the next free number may be
    allocated.

    If the trap is already in use (or no free traps are available) a -1
    is returned.

    This function only affects the currently running task.

    Traps are sent to the trap handler pointed at by tc_TrapCode.
    Unless changed by user code, this points to a standard trap
    handler.  The stack frame of the exception handler will be:

            0(SP) = Exception vector number.  This will be in the
                    range of 32 to 47 (corresponding to the
                    Trap #1...Trap #15 instructions).
            4(SP) = 68000/68010/68020/68030, etc. exception frame

    tc_TrapData is not used.


WARNING
    Traps may not be allocated or freed from exception handling code.
    You are not allowed to write to the exception table yourself.  In
    fact, on some machines you will have trouble finding it - the VBR
    register may be used to remap its location.

INPUTS
    trapNum - the desired trap number {of 0..15} or -1
              for no preference.

RESULTS
    trapNum - the trap number allocated {of 0..15}.  If no traps are
              available, this function returns -1.  Instructions of the
              form "Trap #trapNum" will be sent to the task's trap
              handler.

SEE ALSO
    @{"FreeTrap" link "FreeTrap()"}

@EndNode

@Node "AllocVec()" "exec.library/AllocVec"

NAME
    AllocVec -- allocate memory and keep track of the size  (V36)

SYNOPSIS
    memoryBlock = AllocVec(byteSize, attributes)
    D0                     D0        D1

    void *AllocVec(ULONG, ULONG);

FUNCTION
    This function works identically to @{"AllocMem()" Link "AllocMem()"}, but tracks the size
    of the allocation.

    See the @{"AllocMem()" Link "AllocMem()"} documentation for details.

WARNING
    The result of any memory allocation MUST be checked, and a viable
    error handling path taken.  ANY allocation may fail if memory has
    been filled.

SEE ALSO
    @{"FreeVec" link "FreeVec()"}, @{"AllocMem" link "AllocMem()"}

@EndNode

@Node "AttemptSemaphore()" "exec.library/AttemptSemaphore"

NAME
    AttemptSemaphore -- try to obtain without blocking

SYNOPSIS
    success = AttemptSemaphore(signalSemaphore)
    D0                         A0

    LONG AttemptSemaphore(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    This call is similar to @{"ObtainSemaphore()" Link "ObtainSemaphore()"}, except that it will not
    block if the semaphore could not be locked.

INPUT
   signalSemaphore -- an initialized signal semaphore structure

RESULT
    success -- TRUE if the semaphore was locked, false if some
        other task already possessed the semaphore.

NOTE
    This call does NOT preserve registers.

SEE ALSO
    @{"ObtainSemaphore()" Link "ObtainSemaphore()"} @{"ObtainSemaphoreShared()" Link "ObtainSemaphoreShared()"}, @{"ReleaseSemaphore()" Link "ReleaseSemaphore()"},
    @{"exec/semaphores.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 0}

@EndNode

@Node "AvailMem()" "exec.library/AvailMem"

NAME
    AvailMem -- memory available given certain requirements

SYNOPSIS
    size = AvailMem(attributes)
    D0              D1

    ULONG AvailMem(ULONG);

FUNCTION
    This function returns the amount of free memory given certain
    attributes.

    To find out what the largest block of a particular type is, add
    MEMF_LARGEST into the requirements argument.  Returning the largest
    block is a slow operation.

WARNING
    Due to the effect of multitasking, the value returned may not
    actually be the amount of free memory available at that instant.

INPUTS
    requirements - a requirements mask as specified in @{"AllocMem" link "AllocMem()"}.  Any
                   of the @{"AllocMem" link "AllocMem()"} bits are valid, as is MEMF_LARGEST
                   which returns the size of the largest block matching
                   the requirements.

RESULT
    size - total free space remaining (or the largest free block).

NOTE
    For V36 Exec, AvailMem(MEMF_LARGEST) does a consistency check on
    the memory list.  Alert AN_MemoryInsane will be pulled if any mismatch
    is noted.

EXAMPLE
    AvailMem(MEMF_CHIP|MEMF_LARGEST);
    /* return size of largest available chip memory chunk */

SEE ALSO
    @{"exec/memory.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 0}

@EndNode

@Node "CacheClearE()" "exec.library/CacheClearE"

NAME
    CacheClearE - Cache clearing with extended control (V37)

SYNOPSIS
    CacheClearE(address,length,caches)
                a0      d0     d1

    void CacheClearE(APTR,ULONG,ULONG);

FUNCTION
    Flush out the contents of the CPU instruction and/or data caches.
    If dirty data cache lines are present, push them to memory first.

    Motorola CPUs have separate instruction and data caches.  A data
    write does not update the instruction cache.  If an instruction is
    written to memory or modified, the old instruction may still exist
    in the cache.  Before attempting to execute the code, a flush of
    the instruction cache is required.

    For most systems, the data cache is not updated by Direct Memory
    Access (DMA), or if some external factor changes shared memory.

    Caches must be cleared after *any* operation that could cause
    invalid or stale data.  The most common cases are DMA and modifying
    instructions using the processor.

    Some examples:
                    Self modifying code
                    Building Jump tables
                    Run-time code patches
                    Relocating code for use at different addresses.
                    Loading code from disk

INPUTS
    address - Address to start the operation.  This may be rounded
              due to hardware granularity.
    length  - Length of area to be cleared, or $FFFFFFFF to indicate all
              addresses should be cleared.
    caches  - Bit flags to indicate what caches to affect.  The current
              supported flags are:
                    CACRF_ClearI    ;Clear instruction cache
                    CACRF_ClearD    ;Clear data cache
              All other bits are reserved for future definition.

NOTES
    On systems with a copyback mode cache, any dirty data is pushed
    to memory as a part of this operation.

    Regardless of the length given, the function will determine the most
    efficient way to implement the operation.  For some cache systems,
    including the 68030, the overhead partially clearing a cache is often
    too great.  The entire cache may be cleared.

    For all current Amiga models, Chip memory is set with Instruction
    caching enabled, data caching disabled.  This prevents coherency
    conflicts with the blitter or other custom chip DMA.  @{"Custom" Link "ADCD_v1.2:Inc&AD2.0/Includes/hardware/custom.h/Main" 26} chip
    registers are marked as non-cacheable by the hardware.

    The system takes care of appropriately flushing the caches for normal
    operations.  The instruction cache is cleared by all calls that
    modify instructions, including @{"LoadSeg()" Link "dos/LoadSeg()"}, @{"MakeLibrary()" Link "MakeLibrary()"} and
    @{"SetFunction()" Link "SetFunction()"}.

SEE ALSO
    exec/execbase.i, @{"CacheControl" link "CacheControl()"}, @{"CacheClearU" link "CacheClearU()"}

@EndNode

@Node "CacheClearU()" "exec.library/CacheClearU"

NAME
    CacheClearU - User callable simple cache clearing (V37)

SYNOPSIS
    CacheClearU()

    void CacheClearU(void);

FUNCTION
    Flush out the contents of any CPU instruction and data caches.
    If dirty data cache lines are present, push them to memory first.

    Caches must be cleared after *any* operation that could cause
    invalid or stale data.  The most common cases are DMA and modifying
    instructions using the processor.  See the @{"CacheClearE()" Link "CacheClearE()"} autodoc
    for a more complete description.

    Some examples of when the cache needs clearing:
                    Self modifying code
                    Building Jump tables
                    Run-time code patches
                    Relocating code for use at different addresses.
                    Loading code from disk

SEE ALSO
    exec/execbase.i, @{"CacheControl" link "CacheControl()"}, @{"CacheClearE" link "CacheClearE()"}

@EndNode

@Node "CacheControl()" "exec.library/CacheControl"

NAME
    CacheControl - Instruction & data cache control

SYNOPSIS
    oldBits = CacheControl(cacheBits,cacheMask)
    D0                     D0        D1

    ULONG CacheControl(ULONG,ULONG);

FUNCTION
    This function provides global control of any instruction or data
    caches that may be connected to the system.  All settings are
    global -- per task control is not provided.

    The action taken by this function will depend on the type of
    CPU installed.  This function may be patched to support external
    caches, or different cache architectures.  In all cases the function
    will attempt to best emulate the provided settings.  Use of this
    function may save state specific to the caches involved.

    The list of supported settings is provided in the exec/execbase.i
    include file.  The bits currently defined map directly to the Motorola
    68030 CPU CACR register.  Alternate cache solutions may patch into
    the Exec cache functions.  Where possible, bits will be interpreted to
    have the same meaning on the installed cache.

INPUTS
    cacheBits - new values for the bits specified in cacheMask.

    cacheMask - a mask with ones for all bits to be changed.

RESULT
    oldBits   - the complete prior values for all settings.

NOTE
    As a side effect, this function clears all caches.

SEE ALSO
    exec/execbase.i, @{"CacheClearU" link "CacheClearU()"}, @{"CacheClearE" link "CacheClearE()"}

@EndNode

@Node "CachePostDMA()" "exec.library/CachePostDMA"

NAME
    CachePostDMA - Take actions after to hardware DMA  (V37)

SYNOPSIS
    CachePostDMA(vaddress,&length,flags)
                 a0       a1      d0

    CachePostDMA(APTR,LONG *,ULONG);

FUNCTION
    Take all appropriate steps after Direct Memory Access (DMA).  This
    function is primarily intended for writers of DMA device drivers.  The
    action will depend on the CPU type installed, caching modes, and the
    state of any Memory Management @{"Unit" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 32} (MMU) activity.

    As implemented
            68000 - Do nothing
            68010 - Do nothing
            68020 - Do nothing
            68030 - Flush the data cache
            68040 - Flush matching areas of the data cache
            ????? - External cache boards, Virtual Memory Systems, or
                    future hardware may patch this vector to best emulate
                    the intended behavior.
                    With a Bus-Snooping CPU, this function my end up
                    doing nothing.

INPUTS
    address - Same as initially passed to @{"CachePreDMA" link "CachePreDMA()"}
    length  - Same as initially passed to @{"CachePreDMA" link "CachePreDMA()"}
    flags   - Values:
                    DMA_NoModify - If the area was not modified (and
                    thus there is no reason to flush the cache) set
                    this bit.

SEE ALSO
    exec/execbase.i, @{"CachePreDMA" link "CachePreDMA()"}, @{"CacheClearU" link "CacheClearU()"}, @{"CacheClearE" link "CacheClearE()"}

@EndNode

@Node "CachePreDMA()" "exec.library/CachePreDMA"

NAME
    CachePreDMA - Take actions prior to hardware DMA  (V37)

SYNOPSIS
    paddress = CachePreDMA(vaddress,&length,flags)
    d0                     a0       a1      d0

    APTR CachePreDMA(APTR,LONG *,ULONG);

FUNCTION
    Take all appropriate steps before Direct Memory Access (DMA).  This
    function is primarily intended for writers of DMA device drivers.  The
    action will depend on the CPU type installed, caching modes, and the
    state of any Memory Management @{"Unit" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 32} (MMU) activity.

    This function supports advanced cache architectures that have
    "copyback" modes.  With copyback, write data may be cached, but not
    actually flushed out to memory.  If the CPU has unflushed data at the
    time of DMA, data may be lost.

    As implemented
            68000 - Do nothing
            68010 - Do nothing
            68020 - Do nothing
            68030 - Do nothing
            68040 - Write any matching dirty cache lines back to memory.
                    As a side effect of the 68040's design, matching data
                    cache lines are also invalidated -- future CPUs may
                    be different.
            ????? - External cache boards, Virtual Memory Systems, or
                    future hardware may patch this vector to best emulate
                    the intended behavior.
                    With a Bus-Snooping CPU, this function my end up
                    doing nothing.

INPUTS
    address - Base address to start the action.
    length  - Pointer to a longword with a length.
    flags   - Values:
                    DMA_Continue - Indicates this call is to complete
                    a prior request that was broken up.

RESULTS
    paddress- Physical address that coresponds to the input virtual
              address.
    &length - This length value will be updated to reflect the contiguous
              length of physical memory present at paddress.  This may
              be smaller than the requested length.  To get the mapping
              for the next chunk of memory, call the function again with
              a new address, length, and the DMA_Continue flag.

NOTE
    Due to processor granularity, areas outside of the address range
    may be affected by the cache flushing actions.  Care has been taken
    to ensure that no harm is done outside the range, and that activities
    on overlapping cache lines won't harm data.

SEE ALSO
    exec/execbase.i, @{"CachePostDMA" link "CachePostDMA()"}, @{"CacheClearU" link "CacheClearU()"}, @{"CacheClearE" link "CacheClearE()"}

@EndNode

@Node "Cause()" "exec.library/Cause"

NAME
   Cause -- cause a software interrupt

SYNOPSIS
   Cause(interrupt)
         A1

   void Cause(struct @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} *);

FUNCTION
    This function causes a software interrupt to occur.  If it is
    called from user mode (and processor level 0), the software
    interrupt will preempt the current task.  This call is often used
    by high-level hardware interrupts to defer medium-length processing
    down to a lower interrupt level.  Note that a software interrupt is
    still a real interrupt, and must obey the same restrictions on what
    system function it may call.

    Currently only 5 software interrupt priorities are implemented:
    -32, -16, 0, +16, and +32.  Priorities in between are truncated,
    values outside the -32/+32 range are not allowed.

NOTE
    When setting up the @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} structure, set the node type to
    NT_INTERRUPT, or NT_UNKOWN.

IMPLEMENTATION
    1> Checks if the node type is NT_SOFTINT.  If so does nothing since
       the softint is already pending.  No nest count is maintained.
    2> Sets the node type to NT_SOFTINT.
    3> Links into one of the 5 priority queues.
    4> Pokes the hardware interrupt bit used for softints.

    The node type returns to NT_INTERRUPT after removal from the list.

INPUTS
    interrupt - pointer to a properly initialized interrupt node

BUGS
    Unlike other Interrupts, SoftInts must preserve the value of A6.

@EndNode

@Node "CheckIO()" "exec.library/CheckIO"

NAME
    CheckIO -- get the status of an @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}

SYNOPSIS
    result = CheckIO(iORequest)
    D0               A1

    BOOL CheckIO(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    This function determines the current state of an I/O request and
    returns FALSE if the I/O has not yet completed.  This function
    effectively hides the internals of the I/O completion mechanism.

    CheckIO() will NOT remove the returned @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} from the reply port.
    This is best performed with @{"WaitIO()" Link "WaitIO()"}. If the request has already
    completed, @{"WaitIO()" Link "WaitIO()"} will return quickly. Use of the @{"Remove()" Link "Remove()"}
    function is dangerous, since other tasks may still be adding things
    to your message port; a @{"Disable()" Link "Disable()"} would be required.

    This function should NOT be used to busy loop (looping until IO is
    complete).  @{"WaitIO()" Link "WaitIO()"} is provided for that purpose.

INPUTS
    iORequest - pointer to an I/O request block

RESULTS
    result - NULL if I/O is still in progress.  Otherwise
             D0 points to the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} block.

NOTE
    CheckIO can hang if called on an @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} that has never been used.
    This occurs if LN_TYPE of the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} is set to "NT_MESSAGE".
    Instead simply set LN_TYPE to 0.

SEE ALSO
    @{"DoIO" link "DoIO()"}, @{"SendIO" link "SendIO()"}, @{"WaitIO" link "WaitIO()"}, @{"AbortIO" Link "timer/AbortIO()"}

@EndNode

@Node "CloseDevice()" "exec.library/CloseDevice"

NAME
    CloseDevice -- conclude access to a device

SYNOPSIS
    CloseDevice(iORequest)
                A1

    void CloseDevice(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    This function informs the device that access to a device/unit
    previously opened has been concluded.  The device may perform
    certain house-cleaning operations.

    The user must ensure that all outstanding IORequests have been
    returned before closing the device.  The @{"AbortIO" Link "timer/AbortIO()"} function can kill
    any stragglers.

    After a close, the I/O request structure is free to be reused.
    Starting with V36 exec it is safe to CloseDevice() with an
    @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} that is either cleared to zeros, or failed to
    open.

INPUTS
    iORequest - pointer to an I/O request structure

SEE ALSO
    @{"OpenDevice" Link "OpenDevice()"}

@EndNode

@Node "CloseLibrary()" "exec.library/CloseLibrary"

NAME
    CloseLibrary -- conclude access to a library

SYNOPSIS
    CloseLibrary(library)
                 A1

    void CloseLibrary(struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *);

FUNCTION
    This function informs the system that access to the given library
    has been concluded.  The user must not reference the library or any
    function in the library after this close.

    Starting with V36, it is safe to pass a NULL instead of
    a library pointer.

INPUTS
    library - pointer to a library node

NOTE
    @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} writers must pass a SegList pointer or NULL back from their
    open point.  This value is used by the system, and not visible as
    a return code from CloseLibrary.

SEE ALSO
    @{"OpenLibrary" link "OpenLibrary()"}

@EndNode

@Node "ColdReboot()" "exec.library/ColdReboot"

NAME
    ColdReboot - reboot the Amiga (V36)

SYNOPSIS
    ColdReboot()

    void ColdReboot(void);

FUNCTION
    Reboot the machine.  All external memory and periperals will be
    RESET, and the machine will start its power up diagnostics.

    This function never returns.

INPUT
    A chaotic pile of disoriented bits.

RESULTS
    An altogether totally integrated living system.

@EndNode

@Node "CopyMem()" "exec.library/CopyMem"

NAME
    CopyMem - general purpose memory copy function

SYNOPSIS
    CopyMem( source, dest, size )
             A0      A1    D0

    void CopyMem(APTR,APTR,ULONG);

FUNCTION
    CopyMem is a general purpose, fast memory copy function.  It can
    deal with arbitrary lengths, with its pointers on arbitrary
    alignments.  It attempts to optimize larger copies with more
    efficient copies, it uses byte copies for small moves, parts of
    larger copies, or the entire copy if the source and destination are
    misaligned with respect to each other.

    Arbitrary overlapping copies are not supported.

    The internal implementation of this function will change from
    system to system, and may be implemented via hardware DMA.

INPUTS
    source - a pointer to the source data region
    dest  - a pointer to the destination data region
    size  - the size (in bytes) of the memory area.  Zero copies
            zero bytes

SEE ALSO
    @{"CopyMemQuick" link "CopyMemQuick()"}

@EndNode

@Node "CopyMemQuick()" "exec.library/CopyMemQuick"

NAME
    CopyMemQuick - optimized memory copy function

SYNOPSIS
    CopyMemQuick( source, dest, size )
                  A0      A1    D0

    void CopyMemQuick(ULONG *,ULONG *,ULONG);

FUNCTION
    CopyMemQuick is a highly optimized memory copy function, with
    restrictions on the size and alignment of its arguments. Both the
    source and destination pointers must be longword aligned.  In
    addition, the size must be an integral number of longwords (e.g.
    the size must be evenly divisible by four).

    Arbitrary overlapping copies are not supported.

    The internal implementation of this function will change from system
    to system, and may be implemented via hardware DMA.

INPUTS
    source - a pointer to the source data region, long aligned
    dest -  a pointer to the destination data region, long aligned
    size -  the size (in bytes) of the memory area.  Zero copies
            zero bytes.

SEE ALSO
    @{"CopyMem" link "CopyMem()"}

@EndNode

@Node "CreateIORequest()" "exec.library/CreateIORequest"

NAME
    CreateIORequest() -- create an @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} structure  (V36)

SYNOPSIS
    ioReq = CreateIORequest( ioReplyPort, size );
                             A0           D0

    struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *CreateIORequest(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *, ULONG);

FUNCTION
    Allocates memory for and initializes a new IO request block
    of a user-specified number of bytes.  The number of bytes
    must be at least as large as a "struct Message".

INPUTS
    ioReplyPort - Pointer to a port for replies (an initialized message
            port, as created by @{"CreateMsgPort()" Link "CreateMsgPort()"} ).  If NULL, this
            function fails.
    size - the size of the IO request to be created.

RESULT
    ioReq - A pointer to the new @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} block, or NULL.

SEE ALSO
    @{"DeleteIORequest" link "DeleteIORequest()"}, @{"CreateMsgPort()" Link "CreateMsgPort()"}, @{"amiga.lib/CreateExtIO()" Link "amiga_lib/CreateExtIO()"}

@EndNode

@Node "CreateMsgPort()" "exec.library/CreateMsgPort"

NAME
    CreateMsgPort - Allocate and initialize a new message port  (V36)

SYNOPSIS
    CreateMsgPort()

    struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} * CreateMsgPort(void);

FUNCTION
    Allocates and initializes a new message port.  The message list
    of the new port will be prepared for use (via NewList).  A signal
    bit will be allocated, and the port will be set to signal your
    task when a message arrives (PA_SIGNAL).

    You *must* use @{"DeleteMsgPort()" Link "DeleteMsgPort()"} to delete ports created with
    CreateMsgPort()!

RESULT
    @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} - A new @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} structure ready for use, or NULL if out of
            memory or signals.  If you wish to add this port to the public
            port list, fill in the ln_Name and ln_Pri fields, then call
            @{"AddPort()" Link "AddPort()"}.  Don't forget RemPort()!

SEE ALSO
    @{"DeleteMsgPort()" Link "DeleteMsgPort()"}, @{"exec/AddPort()" Link "AddPort()"}, @{"exec/ports.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 0}, @{"amiga.lib/CreatePort()" Link "amiga_lib/CreatePort()"}

@EndNode

@Node "Deallocate()" "exec.library/Deallocate"

NAME
    Deallocate -- deallocate a block of memory

SYNOPSIS
    Deallocate(memHeader, memoryBlock, byteSize)
               A0         A1           D0

    void Deallocate(struct @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29} *,APTR,ULONG);

FUNCTION
    This function deallocates memory by returning it to the appropriate
    private free memory pool.  This function can be used to free an
    entire block allocated with the above function, or it can be used
    to free a sub-block of a previously allocated block.  Sub-blocks
    must be an even multiple of the memory chunk size (currently 8
    bytes).

    This function can even be used to add a new free region to an
    existing @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29}, however the extent pointers in the @{"MemHeader" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 29}
    will no longer be valid.

    If memoryBlock is not on a block boundary (MEM_BLOCKSIZE) then it
    will be rounded down in a manner compatible with @{"Allocate()" Link "Allocate()"}.  Note
    that this will work correctly with all the memory allocation
    functions, but may cause surprises if one is freeing only part of a
    region.  The size of the block will be rounded up, so the freed
    block will fill to an even memory block boundary.

INPUTS
    memHeader - points to the memory header this block is part of.
    memoryBlock - address of memory block to free.
    byteSize - the size of the block in bytes. If NULL, nothing
               happens.

SEE ALSO
    Allocate, @{"exec/memory.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 0}

@EndNode

@Node "Debug()" "exec.library/Debug"

NAME
    Debug -- run the system debugger

SYNOPSIS
    Debug(flags)
          D0

    void Debug(ULONG);

FUNCTION
    This function calls the system debugger.  By default this debugger
    is "ROM-WACK".  Other debuggers are encouraged to take over this
    entry point (via @{"SetFunction()" Link "SetFunction()"}) so that when an application calls
    Debug(), the alternative debugger will get control.  Currently a
    zero is passed to allow future expansion.

NOTE
    The Debug() call may be made when the system is in a questionable
    state; if you have a @{"SetFunction()" Link "SetFunction()"} patch, make few assumptions, be
    prepared for @{"Supervisor" link "Supervisor()"} mode, and be aware of differences in the
    Motorola stack frames on the 68000,'10,'20, and '30.

SEE ALSO
    @{"SetFunction" link "SetFunction()"}
    your favorite debugger's manual
    the ROM-WACK chapter of the ROM Kernel Manual

@EndNode

@Node "DeleteIORequest()" "exec.library/DeleteIORequest"

NAME
    DeleteIORequest() - Free a request made by @{"CreateIORequest()" Link "CreateIORequest()"}  (V36)

SYNOPSIS
    DeleteIORequest( ioReq );
                     a0

    void DeleteIORequest(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    Frees up an IO request as allocated by @{"CreateIORequest()" Link "CreateIORequest()"}.

INPUTS
    ioReq - A pointer to the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} block to be freed, or NULL.
            This function uses the mn_Length field to determine how
            much memory to free.

SEE ALSO
    @{"CreateIORequest()" Link "CreateIORequest()"}, @{"amiga.lib/DeleteExtIO()" Link "amiga_lib/DeleteExtIO()"}

@EndNode

@Node "DeleteMsgPort()" "exec.library/DeleteMsgPort"

NAME
    DeleteMsgPort - Free a message port created by @{"CreateMsgPort" link "CreateMsgPort()"}  (V36)

SYNOPSIS
    DeleteMsgPort(msgPort)
                  a0

    void DeleteMsgPort(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *);

FUNCTION
    Frees a message port created by @{"CreateMsgPort()" Link "CreateMsgPort()"}.  All messages that
    may have been attached to this port must have already been
    replied to.

INPUTS
    msgPort - A message port.  NULL for no action.

SEE ALSO
    @{"CreateMsgPort()" Link "CreateMsgPort()"}, @{"amiga.lib/DeletePort()" Link "amiga_lib/DeletePort()"}

@EndNode

@Node "Disable()" "exec.library/Disable"

NAME
    Disable -- disable interrupt processing.

SYNOPSIS
    Disable();

    void Disable(void);

FUNCTION
    Prevents interrupts from being handled by the system, until a
    matching @{"Enable()" Link "Enable()"} is executed.  Disable() implies @{"Forbid()" Link "Forbid()"}.

    DO NOT USE THIS CALL WITHOUT GOOD JUSTIFICATION.  THIS CALL IS
    VERY DANGEROUS!

RESULTS
    All interrupt processing is deferred until the task executing makes
    a call to @{"Enable()" Link "Enable()"} or is placed in a wait state.  Normal task
    rescheduling does not occur while interrupts are disabled.  In order
    to restore normal interrupt processing, the programmer must execute
    exactly one call to @{"Enable()" Link "Enable()"} for every call to Disable().

    IMPORTANT REMINDER:

    It is important to remember that there is a danger in using
    disabled sections.  Disabling interrupts for more than ~250
    microseconds will prevent vital system functions (especially serial
    I/0) from operating in a normal fashion.

    Think twice before using Disable(), then think once more.
    After all that, think again.  With enough thought, the need
    for a Disable() can often be eliminated.  For the user of many
    device drivers, a write to disable *only* the particular interrupt
    of interest can replace a Disable().  For example:
                    MOVE.W  #INTF_PORTS,_intena
    Do not use a macro for Disable(), insist on the real thing.

    This call may be made from interrupts, it will have the effect
    of locking out all higher-level interrupts (lower-level interrupts
    are automatically disabled by the CPU).

    Note: In the event of a task entering a @{"Wait()" Link "Wait()"} after disabling
          interrupts, the system "breaks" the disabled state and runs
          normally until the task which called Disable() is rescheduled.

NOTE
    This call is guaranteed to preserve all registers.

SEE ALSO
    Forbid, Permit, Enable

@EndNode

@Node "DoIO()" "exec.library/DoIO"

NAME
    DoIO -- perform an I/O command and wait for completion

SYNOPSIS
    error = DoIO(iORequest)
    D0           A1

    BYTE DoIO(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    This function requests a device driver to perform the I/O command
    specified in the I/O request.  This function will always wait until
    the I/O request is fully complete.

    DoIO() handles all the details, including Quick I/O, waiting for
    the request, and removing the reply message, etc..

IMPLEMENTATION
    This function first tries to complete the IO via the "Quick I/O"
    mechanism.  The io_Flags field is always set to IOF_QUICK (0x01)
    before the internal device call.

    The LN_TYPE field is used internally to flag completion.  Active
    requests have type NT_MESSAGE.  Requests that have been replied
    have type NT_REPLYMSG.  It is illegal to start IO using a
    still active @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}, or a request with type NT_REPLYMSG.

INPUTS
    iORequest - pointer to an @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} initialized by @{"OpenDevice()" Link "OpenDevice()"}

RESULTS
    error - a sign-extended copy of the io_Error field of the
            @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}.  Most device commands require that the error
            return be checked.

SEE ALSO
    @{"SendIO" link "SendIO()"}, @{"CheckIO" link "CheckIO()"}, @{"WaitIO" link "WaitIO()"}, @{"AbortIO" Link "timer/AbortIO()"}, @{"amiga.lib/BeginIO" Link "serial/BeginIO()"}

@EndNode

@Node "Enable()" "exec.library/Enable"

NAME
    Enable -- permit system interrupts to resume.

SYNOPSIS
    Enable();

    void Enable(void);

FUNCTION
    Allow system interrupts to again occur normally, after a matching
    @{"Disable()" Link "Disable()"} has been executed.

RESULTS
    @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} processing is restored to normal operation. The
    programmer must execute exactly one call to Enable() for every call
    to @{"Disable()" Link "Disable()"}.

NOTE
    This call is guaranteed to preserve all registers.

SEE ALSO
    Forbid, Permit, Disable


@EndNode

@Node "Enqueue()" "exec.library/Enqueue"

NAME
    Enqueue -- insert or append node to a system queue

SYNOPSIS
    Enqueue(list, node)
            A0    A1

    void Enqueue(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *, struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *);

FUNCTION
    Insert or append a node into a system queue.  The insert is
    performed based on the node priority -- it will keep the list
    properly sorted.  New nodes will be inserted in front of the first
    node with a lower priority.   Hence a FIFO queue for nodes of equal
    priority

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    list - a pointer to the system queue header
    node - the node to enqueue.  This must be a full featured list
           with type, priority and name fields.

SEE ALSO
    @{"AddHead" link "AddHead()"}, @{"AddTail" link "AddTail()"}, Insert, Remove, @{"RemHead" link "RemHead()"}, @{"RemTail" link "RemTail()"}

@EndNode

@Node "FindName()" "exec.library/FindName"

NAME
    FindName -- find a system list node with a given name

SYNOPSIS
    node = FindName(start, name)
    D0,Z            A0     A1

    struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *FindName(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *, STRPTR);

FUNCTION
    Traverse a system list until a node with the given name is found.
    To find multiple occurrences of a string, this function may be
    called with a node starting point.

    No arbitration is done for access to the list!  If multiple tasks
    access the same list, an arbitration mechanism such as
    SignalSemaphores must be used.

INPUTS
    start - a list header or a list node to start the search
            (if node, this one is skipped)
    name - a pointer to a name string terminated with NULL

RESULTS
    node - a pointer to the node with the same name else
        zero to indicate that the string was not found.

@EndNode

@Node "FindPort()" "exec.library/FindPort"

NAME
    FindPort -- find a given system message port

SYNOPSIS
    port = FindPort(name)
    D0              A1

    struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *FindPort(STRPTR);

FUNCTION
    This function will search the system message port list for a port
    with the given name.  The first port matching this name will be
    returned.  No arbitration of the port list is done.  This function
    MUST be protected with A @{"Forbid()/Permit()" Link "Permit()"} pair!

EXAMPLE
    #include @{"<exec/types.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/types.h/Main" 0}
    struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *FindPort();

    ULONG SafePutToPort(message, portname)
    struct @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} *message;
    STRPTR          portname;
    {
    struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *port;

        Forbid();
            port = FindPort(portname);
            if (port)
                PutMsg(port,message);
        Permit();
        return((ULONG)port); /* If zero, the port has gone away */
    }

INPUT
    name - name of the port to find

RETURN
    port - a pointer to the message port, or zero if
            not found.


@EndNode

@Node "FindResident()" "exec.library/FindResident"

NAME
    FindResident - find a resident module by name

SYNOPSIS
    resident = FindResident(name)
    D0                      A1

    struct @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} *FindResident(STRPTR);

FUNCTION
    Search the system resident tag list for a resident tag ("ROMTag") with
    the given name.  If found return a pointer to the resident tag
    structure, else return zero.

    @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} modules are used by the system to pull all its parts
    together at startup.  @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} tags are also found in disk based
    devices and libraries.

INPUTS
    name - pointer to name string

RESULT
    resident - pointer to the resident tag structure or
            zero if none found.

SEE ALSO
    @{"exec/resident.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 0}, @{"InitResident" link "InitResident()"}

@EndNode

@Node "FindSemaphore()" "exec.library/FindSemaphore"

NAME
    FindSemaphore -- find a given system signal semaphore

SYNOPSIS
    signalSemaphore = FindSemaphore(name)
    D0                              A1

    struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *FindSemaphore(STRPTR);

FUNCTION
    This function will search the system signal semaphore list for a
    semaphore with the given name.  The first semaphore matching this
    name will be returned.

    This function does not arbitrate for access to the semaphore list,
    surround the call with a @{"Forbid()/Permit()" Link "Permit()"} pair.

INPUT
    name - name of the semaphore to find

RESULT
    semaphore - a pointer to the signal semaphore, or zero if not
                found.

@EndNode

@Node "FindTask()" "exec.library/FindTask"

NAME
    FindTask -- find a task with the given name or find oneself

SYNOPSIS
    task = FindTask(name)
    D0              A1

    struct @{"Task" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 25} *FindTask(STRPTR);

FUNCTION
    This function will check all task queues for a task with the given
    name, and return a pointer to its task control block.  If a NULL
    name pointer is given a pointer to the current task will be
    returned.

    Finding oneself with a NULL for the name is very quick.  Finding a
    task by name is very system expensive, and will disable interrupts
    for a long time.  Since a task may remove itself at any time,
    a @{"Forbid()/Permit()" Link "Permit()"} pair may be needed to ensure the pointer
    returned by FindTask() is still valid when used.

INPUT
    name - pointer to a name string

RESULT
    task - pointer to the task (or Process)

@EndNode

@Node "Forbid()" "exec.library/Forbid"

NAME
    Forbid -- forbid task rescheduling.

SYNOPSIS
    Forbid()

    void Forbid(void);

FUNCTION
    Prevents other tasks from being scheduled to run by the dispatcher,
    until a matching @{"Permit()" Link "Permit()"} is executed, or this task is scheduled to
    @{"Wait()" Link "Wait()"}.  Interrupts are NOT disabled.

    DO NOT USE THIS CALL WITHOUT GOOD JUSTIFICATION.  THIS CALL IS
    DANGEROUS!

RESULTS
    The current task will not be rescheduled as long as it is ready to
    run.  In the event that the current task enters a wait state, other
    tasks may be scheduled.  Upon return from the wait state, the original
    task will continue to run without disturbing the Forbid().

    Calls to Forbid() nest. In order to restore normal task rescheduling,
    the programmer must execute exactly one call to @{"Permit()" Link "Permit()"} for every
    call to Forbid().

WARNING
    In the event of a task entering a @{"Wait()" Link "Wait()"} after a Forbid(), the system
    "breaks" the forbidden state and runs normally until the task which
    called Forbid() is rescheduled.  If caution is not taken, this can
    cause subtle bugs, since any device or DOS call will (in effect)
    cause your task to wait.

    Forbid() is not useful or safe from within interrupt code
    (All interrupts are always higher priority than tasks, and
    interrupts are allowed to break a Forbid()).

NOTE
    This call is guaranteed to preserve all registers.

SEE ALSO
    Permit, Disable, @{"ObtainSemaphore" link "ObtainSemaphore()"}, @{"ObtainSemaphoreShared" link "ObtainSemaphoreShared()"}

@EndNode

@Node "FreeEntry()" "exec.library/FreeEntry"

NAME
    FreeEntry -- free many regions of memory

SYNOPSIS
    FreeEntry(memList)
              A0
    void FreeEntry(struct @{"MemList" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 57} *);

FUNCTION
    This function takes a memList structure (as returned by AllocEntry)
    and frees all the entries.

INPUTS
    memList -- pointer to structure filled in with @{"MemEntry" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 41}
               structures

SEE ALSO
    @{"AllocEntry" link "AllocEntry()"}

@EndNode

@Node "FreeMem()" "exec.library/FreeMem"

NAME
    FreeMem -- deallocate with knowledge

SYNOPSIS
    FreeMem(memoryBlock, byteSize)
            A1           D0

    void FreeMem(void *,ULONG);

FUNCTION
    Free a region of memory, returning it to the system pool from which
    it came.  Freeing partial blocks back into the system pool is
    unwise.

NOTE
    If a block of memory is freed twice, the system will Guru. The
    Alert is AN_FreeTwice ($01000009).   If you pass the wrong pointer,
    you will probably see AN_MemCorrupt $01000005.  Future versions may
    add more sanity checks to the memory lists.

INPUTS
    memoryBlock - pointer to the memory block to free
    byteSize - the size of the desired block in bytes.  (The operating
            system will automatically round this number to a multiple of
            the system memory chunk size)

SEE ALSO
    @{"AllocMem" link "AllocMem()"}

@EndNode

@Node "FreeSignal()" "exec.library/FreeSignal"

NAME
    FreeSignal -- free a signal bit

SYNOPSIS
    FreeSignal(signalNum)
               D0

    void FreeSignal(BYTE);

FUNCTION
    This function frees a previously allocated signal bit for reuse.
    This call must be performed while running in the same task in which
    the signal was allocated.

WARNING
    Signals may not be allocated or freed from exception handling code.

NOTE
    Starting with V37, an attempt to free signal -1 is harmless.

INPUTS
    signalNum - the signal number to free {0..31}.

@EndNode

@Node "FreeTrap()" "exec.library/FreeTrap"

NAME
    FreeTrap -- free a processor trap

SYNOPSIS
    FreeTrap(trapNum)
             D0

    void FreeTrap(ULONG);

FUNCTION
    This function frees a previously allocated trap number for reuse.
    This call must be performed while running in the same task in which
    the trap was allocated.

WARNING
    Traps may not be allocated or freed from exception handling code.

INPUTS
    trapNum - the trap number to free {of 0..15}

@EndNode

@Node "FreeVec()" "exec.library/FreeVec"

NAME
    FreeVec -- return @{"AllocVec()" Link "AllocVec()"} memory to the system  (V36)

SYNOPSIS
    FreeVec(memoryBlock)
            A1

    void FreeVec(void *);

FUNCTION
    Free an allocation made by the @{"AllocVec()" Link "AllocVec()"} call.  The memory will
    be returned to the system pool from which it came.

NOTE
    If a block of memory is freed twice, the system will Guru. The
    Alert is AN_FreeTwice ($01000009).   If you pass the wrong pointer,
    you will probably see AN_MemCorrupt $01000005.  Future versions may
    add more sanity checks to the memory lists.

INPUTS
    memoryBlock - pointer to the memory block to free, or NULL.

SEE ALSO
    @{"AllocVec" link "AllocVec()"}

@EndNode

@Node "GetCC()" "exec.library/GetCC"

NAME
    GetCC -- get condition codes in a 68010 compatible way.

SYNOPSIS
    conditions = GetCC()
      D0

    UWORD GetCC(void);

FUNCTION
    The 68000 processor has a "MOVE SR,<ea>" instruction which gets a
    copy of the processor condition codes.

    On the 68010,20 and 30 CPUs, "MOVE SR,<ea>" is privileged.  User
    code will trap if it is attempted.  These processors need to use
    the "MOVE CCR,<ea>" instruction instead.

    This function provides a means of obtaining the CPU condition codes
    in a manner that will make upgrades transparent.  This function is
    VERY short and quick.

RESULTS
    conditions - the 680XX condition codes

NOTE
    This call is guaranteed to preserve all registers.  This function
    may be implemented as code right in the jump table.

@EndNode

@Node "GetMsg()" "exec.library/GetMsg"

NAME
    GetMsg -- get next message from a message port

SYNOPSIS
    message = GetMsg(port)
    D0               A0

    struct @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} *GetMsg(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *);

FUNCTION
    This function receives a message from a given message port. It
    provides a fast, non-copying message receiving mechanism. The
    received message is removed from the message port.

    This function will not wait.  If a message is not present this
    function will return zero.  If a program must wait for a message,
    it can @{"Wait()" Link "Wait()"} on the signal specified for the port or use the
    @{"WaitPort()" Link "WaitPort()"} function.  There can only be one task waiting for any
    given port.

    Getting a message does not imply to the sender that the message is
    free to be reused by the sender.  When the receiver is finished
    with the message, it may @{"ReplyMsg()" Link "ReplyMsg()"} it back to the sender.


    Getting a signal does NOT always imply a message is ready.  More
    than one message may arrive per signal, and signals may show up
    without messages.  Typically you must loop to GetMsg() until it
    returns zero, then @{"Wait()" Link "Wait()"} or @{"WaitPort()" Link "WaitPort()"}.

INPUT
    port - a pointer to the receiver message port

RESULT
    message - a pointer to the first message available.  If
              there are no messages, return zero.
              Callers must be prepared for zero at any time.

SEE ALSO
    @{"PutMsg" link "PutMsg()"}, @{"ReplyMsg" link "ReplyMsg()"}, @{"WaitPort" link "WaitPort()"}, Wait, @{"exec/ports.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 0}

@EndNode

@Node "InitCode()" "exec.library/InitCode"

NAME
    InitCode - initialize resident code modules (internal function)

SYNOPSIS
    InitCode(startClass, version)
             D0          D1

    void InitCode(ULONG,ULONG);

FUNCTION
    (This function may be ignored by application programmers)

    Call @{"InitResident()" Link "InitResident()"} for all resident modules in the ResModules array
    with the given startClass and with versions equal or greater than
    that specified.  The segList parameter is passed as zero.

    @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} modules are used by the system to pull all its parts
    together at startup.  Modules are initialized in a prioritized order.

    Modules that do not have a startclass should be of priority -120.
    RTF_AFTERDOS modues should start at -100 (working down).

INPUTS
    startClass - the class of code to be initialized:
            BITDEF RT,COLDSTART,0
            BITDEF RT,SINGLETASK,1  ;ExecBase->ThisTask==0 (V36 only)
            BITDEF RT,AFTERDOS,2    ;(V36 only)
    version - a major version number

SEE ALSO
    ResidentTag (RT) structure definition (resident.h)

@EndNode

@Node "InitResident()" "exec.library/InitResident"

NAME
    InitResident - initialize resident module

SYNOPSIS
    object = InitResident(resident, segList)
    D0                     A1        D1

    APTR InitResident(struct @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} *,ULONG);

FUNCTION
    Initialize a ROMTag.  ROMTags are used to link system modules
    together.  Each disk based device or library must contain a
    ROMTag structure in the first code hunk.

    Once the validity of the ROMTag is verified, the RT_INIT pointer
    is jumped to  with the following registers:
            D0 = 0
            A0 = segList
            A6 = @{"ExecBase" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 35}

INPUTS
    resident - Pointer to a ROMTag
    segList  - SegList of the loaded object, if loaded from disk.
               Libraries & Devices will cache this value for later
               return at close or expunge time.  Pass NULL for ROM
               modules.

RESULTS
    object  - Return value from the init code, usually the library
              or device base.  NULL for failure.

AUTOINIT FEATURE
    An automatic method of library/device base and vector table
    initialization is also provided by InitResident().  The initial code
    hunk of the library or device should contain "MOVEQ #-1,d0; RTS;".
    Following that must be an initialized @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} structure with
    RTF_AUTOINIT set in rt_Flags, and an rt_Init pointer which points
    to four longwords.  These four longwords will be used in a call
    to MakeLibrary();

        - The size of your library/device base structure including initial
          @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} or @{"Device" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 25} structure.

        - A pointer to a longword table of standard, then library
          specific function offsets, terminated with -1L.
          (short format offsets are also acceptable)

        - Pointer to data table in @{"exec/InitStruct" link "InitStruct()"} format for
          initialization of @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} or @{"Device" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 25} structure.

        - Pointer to library initialization function, or NULL.
            Calling sequence:
                    D0 = library base
                    A0 = segList
                    A6 = @{"ExecBase" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 35}
          This function must return in D0 the library/device base to be
          linked into the library/device list.  If the initialization
          function fails, the device memory must be manually deallocated,
          then NULL returned in D0.

SEE ALSO
    exec/resident.i, @{"FindResident" link "FindResident()"}

@EndNode

@Node "InitSemaphore()" "exec.library/InitSemaphore"

NAME
    InitSemaphore -- initialize a signal semaphore

SYNOPSIS
    InitSemaphore(signalSemaphore)
                  A0

    void InitSemaphore(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    This function initializes a signal semaphore and prepares it for
    use.  It does not allocate anything, but does initialize list
    pointers and the semaphore counters.

    Semaphores are often used to protect critical data structures
    or hardware that can only be accessed by one task at a time.
    After initialization, the address of the @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} may be
    made available to any number of tasks.  Typically a task will
    try to @{"ObtainSemaphore()" Link "ObtainSemaphore()"}, passing this address in.  If no other
    task owns the semaphore, then the call will lock and return
    quickly.  If more tasks try to @{"ObtainSemaphore()" Link "ObtainSemaphore()"}, they will
    be put to sleep.  When the owner of the semaphore releases
    it, the next waiter in turn will be woken up.

    Semaphores are often preferable to the old-style @{"Forbid()/Permit()" Link "Permit()"}
    type arbitration.  With @{"Forbid()/Permit()" Link "Permit()"} *all* other tasks are
    prevented from running.  With semaphores, only those tasks that
    need access to whatever the semaphore protects are subject
    to waiting.

INPUT
    signalSemaphore -- a signal semaphore structure (with all fields
                       set to zero before the call)

SEE ALSO
    @{"ObtainSemaphore()" Link "ObtainSemaphore()"}, @{"ObtainSemaphoreShared()" Link "ObtainSemaphoreShared()"}, @{"AttemptSemaphore()" Link "AttemptSemaphore()"},
    @{"ReleaseSemaphore()" Link "ReleaseSemaphore()"}, @{"exec/semaphores.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 0}

@EndNode

@Node "InitStruct()" "exec.library/InitStruct"

NAME
    InitStruct - initialize memory from a table

SYNOPSIS
    InitStruct(initTable, memory, size);
               A1         A2      D0

    void InitStruct(struct InitStruct *, APTR, ULONG);

FUNCTION
    Clear a memory area, then set up default values according to
    the data and offset values in the initTable.  Typically only assembly
    programs take advantage of this function, and only with the macros
    defined in "exec/initializers.i".

    The initialization table has byte commands to

         |a    ||byte|      |given||byte|         |once         |
    load |count||word| into |next ||rptr| offset, |repetitively |
                |long|

    Not all combinations are supported.  The offset, when specified, is
    relative to the memory pointer provided (Memory), and is initially
    zero.  The initialization data (InitTable) contains byte commands
    whose 8 bits are interpreted as follows:

    ddssnnnn
        dd  the destination type (and size):
            00  no offset, use next destination, nnnn is count
            01  no offset, use next destination, nnnn is repeat
            10  destination offset is in the next byte, nnnn is count
            11  destination offset is in the next 24-bits, nnnn is count
        ss  the size and location of the source:
            00  long, from the next two aligned words
            01  word, from the next aligned word
            10  byte, from the next byte
            11  ERROR - will cause an ALERT (see below)
      nnnn  the count or repeat:
         count  the (number+1) of source items to copy
        repeat  the source is copied (number+1) times.

    initTable commands are always read from the next even byte. Given
    destination offsets are always relative to the memory pointer (A2).

    The command %00000000 ends the InitTable stream: use %00010001 if you
    really want to copy one longword without a new offset.

    24 bit APTR not supported for 68020 compatibility -- use long.

INPUTS
    initTable - the beginning of the commands and data to init
            Memory with.  Must be on an even boundary unless only
            byte initialization is done.  End table with "dc.b 0"
            or "dc.w 0".
    memory - the beginning of the memory to initialize.  Must be
            on an even boundary if size is specified.
    size - the size of memory, which is used to clear it before
            initializing it via the initTable.  If Size is zero,
            memory is not cleared before initializing.

            size must be an even number.

SEE ALSO
    exec/initializers.i

@EndNode

@Node "Insert()" "exec.library/Insert"

NAME
    Insert -- insert a node into a list

SYNOPSIS
    Insert(list, node, listNode)
           A0    A1    A2

    void Insert(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *, struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *, struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *);

FUNCTION
    Insert a node into a doubly linked list AFTER a given node
    position.  Insertion at the head of a list is possible by passing a
    zero value for listNode, though the @{"AddHead" link "AddHead()"} function is slightly
    faster for that special case.

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    list - a pointer to the target list header
    node - the node to insert
    listNode - the node after which to insert

SEE ALSO
    @{"AddHead" link "AddHead()"}, @{"AddTail" link "AddTail()"}, @{"Enqueue" link "Enqueue()"}, @{"RemHead" link "RemHead()"}, Remove, @{"RemTail" link "RemTail()"}

@EndNode

@Node "MakeFunctions()" "exec.library/MakeFunctions"

NAME
    MakeFunctions -- construct a function jump table

SYNOPSIS
    tableSize = MakeFunctions(target, functionArray, funcDispBase)
    D0                        A0      A1             A2

    ULONG MakeFunctions(APTR,APTR,APTR);

FUNCTION
    A low level function used by @{"MakeLibrary" link "MakeLibrary()"} to build jump tables of
    the type used by libraries, devices and resources.  It allows the
    table to be built anywhere in memory, and can be used both for
    initialization and replacement. This function also supports function
    pointer compression by expanding relative displacements into absolute
    pointers.

    The processor instruction cache is cleared after the table building.

INPUT
    destination - the target address for the high memory end of the
            function jump table.  Typically this will be the library
            base pointer.

    functionArray - pointer to an array of function pointers or
            function displacements.  If funcDispBase is zero, the array
            is assumed to contain absolute pointers to functions. If
            funcDispBase is not zero, then the array is assumed to
            contain word displacements to functions.  In both cases,
            the array is terminated by a -1 (of the same size as the
            actual entry.

    funcDispBase - pointer to the base about which all function
            displacements are relative.  If zero, then the function
            array contains absolute pointers.

RESULT
    tableSize - size of the new table in bytes (for LIB_NEGSIZE).

SEE ALSO
    @{"exec/MakeLibrary" link "MakeLibrary()"}

@EndNode

@Node "MakeLibrary()" "exec.library/MakeLibrary"

NAME
    MakeLibrary -- construct a library

SYNOPSIS
    library = MakeLibrary(vectors, structure, init, dSize, segList)
    D0                    A0       A1         A2    D0     D1

    struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *MakeLibrary
                          (APTR,struct @{"InitStruct" link "InitStruct()"} *,APTR,ULONG,BPTR);

FUNCTION
    This function is used for constructing a library vector and data
    area.  The same call is used to make devices.  Space for the library
    is allocated from the system's free memory pool.  The data portion of
    the library is initialized.  init may point to a library specific
    entry point.

NOTE
    Starting with V36, the library base is longword adjusted.  The
    lib_PosSize and lib_NegSize fields of the library structure are
    adjusted to match.

INPUTS
    vectors - pointer to an array of function pointers or function
            displacements.  If the first word of the array is -1, then
            the array contains relative word displacements (based off
            of vectors); otherwise, the array contains absolute
            function pointers. The vector list is terminated by a -1
            (of the same size as the pointers).

    structure - points to an "InitStruct" data region.  If NULL,
            then it will not be used.

    init -  If non-NULL, an entry point that will be called before adding
            the library to the system.  Registers are as follows:
                    d0 = libAddr    ;Your @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} Address
                    a0 = segList    ;Your AmigaDOS segment list
                    a6 = @{"ExecBase" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 35}  ;Address of exec.library
            The result of the init function must be the library address,
            or NULL for failure.   If NULL, the init point must manually
            deallocate the library base memory (based on the sizes stored
            in lib_PosSize and lib_NegSize).

    dSize - the size of the library data area, including the
            standard library node data.  This must be at leas
            sizeof(struct Library).

   segList - pointer to an AmigaDOS SegList (segment list).
             This is passed to a library's init code, and is used later
             for removing the library from memory.

RESULT
    library - the reference address of the library.  This is the
              address used in references to the library, not the
              beginning of the memory area allocated.  If the library
              vector table require more system memory than is
              available, this function will return NULL.

SEE ALSO
    @{"InitStruct" link "InitStruct()"}, @{"InitResident" link "InitResident()"}, exec/initializers.i

@EndNode

@Node "ObtainSemaphore()" "exec.library/ObtainSemaphore"

NAME
    ObtainSemaphore -- gain exclusive access to a semaphore

SYNOPSIS
    ObtainSemaphore(signalSemaphore)
                    A0

    void ObtainSemaphore(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    @{"Signal" link "Signal()"} semaphores are used to gain exclusive access to an object.
    ObtainSemaphore is the call used to gain this access.  If another
    user currently has the semaphore locked the call will block until
    the object is available.

    If the current task already has locked the semaphore and attempts to
    lock it again the call will still succeed.  A "nesting count" is
    incremented each time the current owning task of the semaphore calls
    ObtainSemaphore().  This counter is decremented each time
    @{"ReleaseSemaphore()" Link "ReleaseSemaphore()"} is called.  When the counter returns to zero the
    semaphore is actually released, and the next waiting task is called.

    A queue of waiting tasks is maintained on the stacks of the waiting
    tasks.  Each will be called in turn as soon as the current task
    releases the semaphore.

    @{"Signal" link "Signal()"} Semaphores are different than @{"Procure()/Vacate()" Link "Vacate()"} semaphores.
    The former requires less CPU time, especially if the semaphore is
    not currently locked.  They require very little set up and user
    thought.  The latter flavor of semaphore make no assumptions about
    how they are used -- they are completely general.  Unfortunately
    they are not as efficient as signal semaphores, and require the
    locker to have done some setup before doing the call.

INPUT
   signalSemaphore -- an initialized signal semaphore structure

NOTE
    This function preserves all registers (see BUGS).

BUGS
    Until V37, this function could destroy A0.

SEE ALSO
    @{"ObtainSemaphoreShared()" Link "ObtainSemaphoreShared()"}, @{"InitSemaphore()" Link "InitSemaphore()"}, @{"ReleaseSemaphore()" Link "ReleaseSemaphore()"},
    @{"AttemptSemaphore()" Link "AttemptSemaphore()"}, @{"ObtainSemaphoreList()" Link "ObtainSemaphoreList()"}

@EndNode

@Node "ObtainSemaphoreList()" "exec.library/ObtainSemaphoreList"

NAME
    ObtainSemaphoreList -- get a list of semaphores.

SYNOPSIS
    ObtainSemaphoreList(list)
                        A0

    void ObtainSemaphoreList(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *);

FUNCTION
    @{"Signal" link "Signal()"} semaphores may be linked together into a list. This function
    takes a list of these semaphores and attempts to lock all of them at
    once. This call is preferable to applying @{"ObtainSemaphore()" Link "ObtainSemaphore()"} to each
    element in the list because it attempts to lock all the elements
    simultaneously, and won't deadlock if someone is attempting to lock
    in some other order.

    This function assumes that only one task at a time will attempt to
    lock the entire list of semaphores.  In other words, there needs to
    be a higher level lock (perhaps another signal semaphore...) that is
    used before someone attempts to lock the semaphore list via
    ObtainSemaphoreList().

    Note that deadlocks may result if this call is used AND someone
    attempts to use @{"ObtainSemaphore()" Link "ObtainSemaphore()"} to lock more than one semaphore on
    the list.  If you wish to lock more than semaphore (but not all of
    them) then you should obtain the higher level lock (see above)

INPUT
   list -- a list of signal semaphores

SEE ALSO
    @{"InitSemaphore()" Link "InitSemaphore()"}, @{"ReleaseSemaphoreList()" Link "ReleaseSemaphoreList()"}

@EndNode

@Node "ObtainSemaphoreShared()" "exec.library/ObtainSemaphoreShared"

NAME
    ObtainSemaphoreShared -- gain shared access to a semaphore (V36)

SYNOPSIS
    ObtainSemaphoreShared(signalSemaphore)
                          a0

    void ObtainSemaphoreShared(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    A lock on a signal semaphore may either be exclusive, or shared.
    Exclusive locks are granted by the @{"ObtainSemaphore()" Link "ObtainSemaphore()"} and
    @{"AttemptSemaphore()" Link "AttemptSemaphore()"} functions.  Shared locks are granted by
    ObtainSemaphoreShared().  Calls may be nested.

    Any number of tasks may simultaneously hold a shared lock on a
    semaphore.  Only one task may hold an exclusive lock.  A typical
    application is a list that is often read, but only occasionally
    written to.

    Any exlusive locker will be held off until all shared lockers
    release the semaphore.  Likewise, if an exlusive lock is held,
    all potential shared lockers will block until the exclusive lock
    is released.  All shared lockers are restarted at the same time.

EXAMPLE
            ObtainSemaphoreShared(ss);
            /* read data */
            ReleaseSemaohore(ss);

            ObtainSemaphore(ss);
            /* modify data */
            ReleaseSemaohore(ss);

NOTES
    While this function was added for V36, the feature magically works
    with all older semaphore structures.

    A task owning a shared lock must not attempt to get an exclusive
    lock on the same semaphore.

INPUT
    signalSemaphore -- an initialized signal semaphore structure

NOTE
    This call is guaranteed to preserve all registers, starting with
    V37 exec.

RESULT

SEE ALSO
    @{"InitSemaphore()" Link "InitSemaphore()"}, @{"ReleaseSemaphore()" Link "ReleaseSemaphore()"}

@EndNode

@Node "OldOpenLibrary()" "exec.library/OldOpenLibrary"

NAME
    OldOpenLibrary -- obsolete @{"OpenLibrary" link "OpenLibrary()"}

SYNOPSIS
    library = OldOpenLibrary(libName)
    D0                       A1

    struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *OldOpenLibrary(APTR);

FUNCTION
    The 1.0 release of the Amiga system had an incorrect version of
    @{"OpenLibrary" link "OpenLibrary()"} that did not check the version number during the
    library open.  This obsolete function is provided so that object
    code compiled using a 1.0 system will still run.

    This exactly the same as "OpenLibrary(libName,0L);"

INPUTS
    libName - the name of the library to open

RESULTS
    library - a library pointer for a successful open, else zero

SEE ALSO
    @{"CloseLibrary" link "CloseLibrary()"}

@EndNode

@Node "OpenDevice()" "exec.library/OpenDevice"

NAME
    OpenDevice -- gain access to a device

SYNOPSIS
    error = OpenDevice(devName, unitNumber, iORequest, flags)
    D0                 A0       D0          A1         D1

    BYTE OpenDevice(STRPTR,ULONG,struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *,ULONG);

FUNCTION
    This function opens the named device/unit and initializes the given
    I/O request block.  Specific documentation on opening procedures
    may come with certain devices.

    The device may exist in memory, or on disk; this is transparent to
    the OpenDevice caller.

    A full path name for the device name is legitimate.  For example
    "test:devs/fred.device".  This allows the use of custom devices
    without requiring the user to copy the device into the system's
    DEVS: directory.

NOTES
    All calls to OpenDevice should have matching calls to CloseDevice!

    Devices on disk cannot be opened until after DOS has been
    started.

    As of V36 tasks can safely call OpenDevice, though DOS may open
    system requesters (e.g., asking the user to insert the Workbench
    disk if DEVS: is not online).  You must call this function from a
    DOS @{"Process" Link "ADCD_v1.2:Inc&AD2.0/Includes/dos/dosextens.h/Main" 38} if you want to turn off DOS requesters.

INPUTS
    devName - requested device name

    unitNumber - the unit number to open on that device.  The format of
            the unit number is device specific.  If the device does
            not have separate units, send a zero.

    iORequest - the I/O request block to be returned with
            appropriate fields initialized.

    flags - additional driver specific information.  This is sometimes
            used to request opening a device with exclusive access.

RESULTS
    error - Returns a sign-extended copy of the io_Error field
            of the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}.  Zero if successful, else an error code
            is returned.

BUGS
    AmigaDOS file names are not case sensitive, but Exec lists are.  If
    the library name is specified in a different case than it exists on
    disk, unexpected results may occur.

    Prior to V36, tasks could not make OpenDevice calls requiring disk
    access (since tasks are not allowed to make dos.library calls).
    Now OpenDevice is protected from tasks.

SEE ALSO
    @{"CloseDevice" Link "serial/CloseDevice()"}, @{"DoIO" link "DoIO()"}, @{"SendIO" link "SendIO()"}, @{"CheckIO" link "CheckIO()"}, @{"AbortIO" Link "timer/AbortIO()"}, @{"WaitIO" link "WaitIO()"}

@EndNode

@Node "OpenLibrary()" "exec.library/OpenLibrary"

NAME
    OpenLibrary -- gain access to a library

SYNOPSIS
    library = OpenLibrary(libName, version)
    D0                    A1       D0

    struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *OpenLibrary(STRPTR, ULONG);

FUNCTION
    This function returns a pointer to a library that was previously
    installed into the system.  If the requested library is exists, and
    if the library version is greater than or equal to the requested
    version, then the open will succeed.

    The device may exist in memory, or on disk; this is transparent to
    the @{"OpenDevice" Link "OpenDevice()"} caller.  Only Processes are allowed to call
    OpenLibrary (since OpenLibrary may in turn call dos.library).

    A full path name for the library name is legitimate.  For example
    "wp:libs/wp.library".  This allows the use of custom libraries
    without requiring the user to copy the library into the system's
    LIBS: directory.

NOTES
    All calls to OpenLibrary should have matching calls to CloseLibrary!

    Libraries on disk cannot be opened until after DOS has been
    started.

    As of V36 tasks can safely call OpenLibrary, though DOS may open
    system requesters (e.g., asking the user to insert the Workbench
    disk if LIBS: is not online).  You must call this function from a
    DOS @{"Process" Link "ADCD_v1.2:Inc&AD2.0/Includes/dos/dosextens.h/Main" 38} if you want to turn off DOS requesters.

INPUTS
    libName - the name of the library to open

    version - the version of the library required.

RESULTS
    library - a library pointer for a successful open, else zero

BUGS
    AmigaDOS file names are not case sensitive, but Exec lists are. If
    the library name is specified in a different case than it exists on
    disk, unexpected results may occur.

    Prior to V36, tasks could not make OpenLibrary calls requiring disk
    access (since tasks are not allowed to make dos.library calls).
    Now OpenLibrary is protected from tasks.

    The version number of the resident tag in disk based library must
    match the version number of the library, or V36 may fail to load it.

SEE ALSO
    @{"CloseLibrary" link "CloseLibrary()"}

@EndNode

@Node "OpenResource()" "exec.library/OpenResource"

NAME
    OpenResource -- gain access to a resource

SYNOPSIS
    resource = OpenResource(resName)
    D0                      A1

    APTR OpenResource(STRPTR);

FUNCTION
    This function returns a pointer to a resource that was previously
    installed into the system.

    There is no CloseResource() function.

INPUTS
   resName - the name of the resource requested.

RESULTS
    resource - if successful, a resource pointer, else NULL

@EndNode

@Node "Permit()" "exec.library/Permit"

NAME
    Permit -- permit task rescheduling.

SYNOPSIS
    Permit()

    void Permit(void);

FUNCTION
    Allow other tasks to be scheduled to run by the dispatcher, after a
    matching @{"Forbid()" Link "Forbid()"} has been executed.

RESULTS
    Other tasks will be rescheduled as they are ready to run. In order
    to restore normal task rescheduling, the programmer must execute
    exactly one call to Permit() for every call to @{"Forbid()" Link "Forbid()"}.

NOTE
    This call is guaranteed to preserve all registers.

SEE ALSO
    Forbid, Disable, Enable

@EndNode

@Node "Procure()" "exec.library/Procure"

NAME
    Procure -- bid for a message lock (semaphore)

SYNOPSIS
    result = Procure(semaphore, bidMessage)
    D0               A0         A1

    BYTE Procure(struct @{"Semaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 53} *, struct @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} *);

FUNCTION
    This function is used to obtain a message based semaphore lock.  If
    the lock is immediate, Procure() returns a true result, and the
    bidMessage is not used.   If the semaphore is already locked,
    Procure() returns false, and the task must wait for the bidMessage
    to arrive at its reply port.

    Straight "Semaphores" use the message system.  They are therefore
    queueable, and users may wait on several of them at the same time.
    This makes them more powerful than "Signal Semaphores"

INPUT
    semaphore - a semaphore message port.  This port is used to queue
    all pending lockers.  This port should be initialized with the
    PA_IGNORE option, as the MP_SigTask field is used for a pointer to
    the current locker message (not a task). New semaphore ports must
    also have the SM_BIDS word initialized to -1.  If the semaphore is
    public, it should be named, its priority set, and the added with
    @{"AddPort" link "AddPort()"}. @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} port priority is often used for anti-deadlock
    locking conventions.

RESULT
    result - true when the semaphore is free.  In such cases no waiting
    needs to be done.  If false, then the task should wait at its
    bidMessage reply port.

BUGS
    Procure() and @{"Vacate()" Link "Vacate()"} do not have proven reliability.

SEE ALSO
    @{"Vacate()" Link "Vacate()"}

@EndNode

@Node "PutMsg()" "exec.library/PutMsg"

NAME
    PutMsg -- put a message to a message port

SYNOPSIS
    PutMsg(port, message)
           A0    A1

    void PutMsg(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *, struct @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} *);

FUNCTION
    This function attaches a message to the end of a given message port.
    It provides a fast, non-copying message sending mechanism.

    Messages can be attached to only one port at a time.  The message
    body can be of any size or form.  Because messages are not copied,
    cooperating tasks share the same message memory.  The sender task
    must not recycle the message until it has been replied by the
    receiver.  Of course this depends on the message handling conventions
    setup by the involved tasks.  If the ReplyPort field is non-zero,
    when the message is replied by the receiver, it will be sent back to
    that port.

    Any one of the following actions can be set to occur when a message
    is put:

            1. no special action
            2. signal a given task (specified by MP_SIGTASK)
            3. cause a software interrupt (specified by MP_SIGTASK)

    The action is selected depending on the value found in the MP_FLAGS
    of the destination port.

IMPLEMENTATION
    1.  Sets the LN_TYPE field to "NT_MESSAGE".
    2.  Attaches the message to the destination port.
    3.  Performs the specified arrival action at the destination.

INPUT
    port - pointer to a message port
    message - pointer to a message

SEE ALSO
    @{"GetMsg" link "GetMsg()"}, @{"ReplyMsg" link "ReplyMsg()"}, @{"exec/ports.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 0}

@EndNode

@Node "RawDoFmt()" "exec.library/RawDoFmt"

NAME
    RawDoFmt -- format data into a character stream.

SYNOPSIS
    NextData = RawDoFmt(FormatString, DataStream, PutChProc, PutChData);
   d0                  a0            a1          a2         a3

    APTR RawDoFmt(STRPTR,APTR,void (*)(),APTR);

FUNCTION
    perform "C"-language-like formatting of a data stream, outputting
    the result a character at a time.  Where % formatting commands are
    found in the FormatString, they will be replaced with the
    corresponding element in the DataStream.  %% must be used in the
    string if a % is desired in the output.

    Under V36, RawDoFmt() returns a pointer to the end of the DataStream
    (The next argument that would have been processed).  This allows
    multiple formatting passes to be made using the same data.

INPUTS
    FormatString - a "C"-language-like NULL terminated format string,
    with the following supported % options:

     %[flags][width.limit][length]type

    flags  - only one allowed. '-' specifies left justification.
    width  - field width.  If the first character is a '0', the
             field will be padded with leading 0's.
      .    - must follow the field width, if specified
    limit  - maximum number of characters to output from a string.
             (only valid for %s).
    length - size of input data defaults to WORD for types d, x,
             and c, 'l' changes this to long (32-bit).
    type   - supported types are:
                    b - BSTR, data is 32-bit BPTR to byte count followed
                        by a byte string, or NULL terminated byte string.
                        A NULL BPTR is treated as an empty string.
                        (Added in V36 exec)
                    d - decimal
                    u - unsigned decimal (Added in V37 exec)
                    x - hexadecimal
                    s - string, a 32-bit pointer to a NULL terminated
                        byte string.  In V36, a NULL pointer is treated
                        as an empty string
                    c - character

    DataStream - a stream of data that is interpreted according to
             the format string.  Often this is a pointer into
             the task's stack.
    PutChProc  - the procedure to call with each character to be
             output, called as:

    PutChProc(Char,  PutChData);
              D0-0:8 A3

            the procedure is called with a NULL Char at the end of
            the format string.

    PutChData - a value that is passed through to the PutChProc
            procedure.  This is untouched by RawDoFmt, and may be
            modified by the PutChProc.

EXAMPLE
    ;
    ; Simple version of the C "sprintf" function.  Assumes C-style
    ; stack-based function conventions.
    ;
    ;   long eyecount;
    ;   eyecount=2;
    ;   sprintf(string,"%s have %ld eyes.","Fish",eyecount);
    ;
    ; would produce "Fish have 2 eyes." in the string buffer.
    ;
            XDEF _sprintf
            XREF _AbsExecBase
            XREF _LVORawDoFmt
    _sprintf:       ; ( ostring, format, {values} )
            movem.l a2/a3/a6,-(sp)

            move.l  4*4(sp),a3       ;Get the output string pointer
            move.l  5*4(sp),a0       ;Get the FormatString pointer
            lea.l   6*4(sp),a1       ;Get the pointer to the DataStream
            lea.l   stuffChar(pc),a2
            move.l  _AbsExecBase,a6
            jsr     _LVORawDoFmt(a6)

            movem.l (sp)+,a2/a3/a6
            rts

    ;------ PutChProc function used by RawDoFmt -----------
    stuffChar:
            move.b  d0,(a3)+        ;Put data to output string
            rts

WARNING
    This Amiga ROM function formats word values in the data stream.  If
    your compiler defaults to longs, you must add an "l" to your
    % specifications.  This can get strange for characters, which might
    look like "%lc".

    The result of RawDoFmt() is *ONLY* valid in V36 and later releases
    of EXEC.  Pre-V36 versions of EXEC have "random" return values.

SEE ALSO
    Documentation on the C language "printf" call in any C language
    reference book.

@EndNode

@Node "ReleaseSemaphore()" "exec.library/ReleaseSemaphore"

NAME
    ReleaseSemaphore -- make signal semaphore available to others

SYNOPSIS
    ReleaseSemaphore(signalSemaphore)
                     A0

    void ReleaseSemaphore(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    ReleaseSemaphore() is the inverse of @{"ObtainSemaphore()" Link "ObtainSemaphore()"}. It makes
    the semaphore lockable to other users.  If tasks are waiting for
    the semaphore and this this task is done with the semaphore then
    the next waiting task is signalled.

    Each @{"ObtainSemaphore()" Link "ObtainSemaphore()"} call must be balanced by exactly one
    ReleaseSemaphore() call.  This is because there is a nesting count
    maintained in the semaphore of the number of times that the current
    task has locked the semaphore. The semaphore is not released to
    other tasks until the number of releases matches the number of
    obtains.

    Needless to say, havoc breaks out if the task releases more times
    than it has obtained.

INPUT
   signalSemaphore -- an initialized signal semaphore structure

NOTE
    This call is guaranteed to preserve all registers.

SEE ALSO
    @{"InitSemaphore()" Link "InitSemaphore()"}, @{"ObtainSemaphore()" Link "ObtainSemaphore()"}, @{"ObtainSemaphoreShared()" Link "ObtainSemaphoreShared()"}

@EndNode

@Node "ReleaseSemaphoreList()" "exec.library/ReleaseSemaphoreList"

NAME
    ReleaseSemaphoreList -- make a list of semaphores available

SYNOPSIS
    ReleaseSemaphoreList(list)
                         A0

    void ReleaseSemaphoreList(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *);

FUNCTION
    ReleaseSemaphoreList() is the inverse of @{"ObtainSemaphoreList()" Link "ObtainSemaphoreList()"}. It
    releases each element in the semaphore list.

    Needless to say, havoc breaks out if the task releases more times
    than it has obtained.

INPUT
   list -- a list of signal semaphores

SEE ALSO
    @{"ObtainSemaphoreList()" Link "ObtainSemaphoreList()"}

@EndNode

@Node "RemDevice()" "exec.library/RemDevice"

NAME
    RemDevice -- remove a device from the system

SYNOPSIS
    RemDevice(device)
              A1

    void RemDevice(struct @{"Device" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 25} *);

FUNCTION
    This function calls the device's EXPUNGE vector, which requests
    that a device delete itself.  The device may refuse to do this if
    it is busy or currently open. This is not typically called by user
    code.

    There are certain, limited circumstances where it may be
    appropriate to attempt to specifically flush a certain device.
    Example:

     /* Attempts to flush the named device out of memory. */
     #include @{"<exec/types.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/types.h/Main" 0}
     #include @{"<exec/execbase.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 0}

     void FlushDevice(name)
     STRPTR name;
     {
     struct @{"Device" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 25} *result;

        Forbid();
        if(result=(struct @{"Device" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/devices.h/Main" 25} *)FindName(&SysBase->DeviceList,name))
            RemDevice(result);
        Permit();
     }

INPUTS
    device - pointer to a device node

SEE ALSO
    @{"AddLibrary" link "AddLibrary()"}

@EndNode

@Node "RemHead()" "exec.library/RemHead"

NAME
    RemHead -- remove the head node from a list

SYNOPSIS
    node = RemHead(list)
    D0             A0

    struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *RemHead(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *);

FUNCTION
    Get a pointer to the head node and remove it from the list.
    Assembly programmers may prefer to use the REMHEAD macro from
    "exec/lists.i".

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    list - a pointer to the target list header

RESULT
    node - the node removed or zero when empty list

SEE ALSO
    @{"AddHead" link "AddHead()"}, @{"AddTail" link "AddTail()"}, @{"Enqueue" link "Enqueue()"}, Insert, Remove, @{"RemTail" link "RemTail()"}

@EndNode

@Node "RemIntServer()" "exec.library/RemIntServer"

NAME
    RemIntServer -- remove an interrupt server from a server chain

SYNOPSIS
    RemIntServer(intNum, interrupt)
                 D0      A1

    void RemIntServer(ULONG,struct @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} *);

FUNCTION
    This function removes an interrupt server node from the given
    server chain.

    If this server was the last one on this chain, interrupts for this
    chain are disabled.

INPUTS
    intNum - the Paula interrupt bit (0..14)
    interrupt - pointer to an interrupt server node

BUGS
    Before V36 Kickstart, the feature that disables the interrupt
    would not function.  For most server chains this does not
    cause a problem.

SEE ALSO
    @{"AddIntServer" link "AddIntServer()"}, @{"hardware/intbits.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/hardware/intbits.h/Main" 0}

@EndNode

@Node "RemLibrary()" "exec.library/RemLibrary"

NAME
    RemLibrary -- remove a library from the system

SYNOPSIS
    RemLibrary(library)
               A1

    void RemLibrary(struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *);

FUNCTION
    This function calls the library's EXPUNGE vector, which requests
    that a library delete itself.  The library may refuse to do this if
    it is busy or currently open. This is not typically called by user
    code.

    There are certain, limited circumstances where it may be
    appropriate to attempt to specifically flush a certain @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34}.
    Example:

     /* Attempts to flush the named library out of memory. */
     #include @{"<exec/types.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/types.h/Main" 0}
     #include @{"<exec/execbase.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 0}

     void FlushLibrary(name)
     STRPTR name;
     {
     struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *result;

        Forbid();
        if(result=(struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *)FindName(&SysBase->LibList,name))
            RemLibrary(result);
        Permit();
     }

INPUTS
    library - pointer to a library node structure

@EndNode

@Node "Remove()" "exec.library/Remove"

NAME
    Remove -- remove a node from a list

SYNOPSIS
    Remove(node)
           A1

    void Remove(struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *);

FUNCTION
    Unlink a node from whatever list it is in.  Nodes that are not part
    of a list must not be passed to this funcion!  Assembly programmers
    may prefer to use the REMOVE macro from "exec/lists.i".

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    node - the node to remove

SEE ALSO
    @{"AddHead" link "AddHead()"}, @{"AddTail" link "AddTail()"}, @{"Enqueue" link "Enqueue()"}, Insert, @{"RemHead" link "RemHead()"}, @{"RemTail" link "RemTail()"}

@EndNode

@Node "RemPort()" "exec.library/RemPort"

NAME
    RemPort -- remove a message port from the system

SYNOPSIS
    RemPort(port)
            A1

    void RemPort(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *);

FUNCTION
    This function removes a message port structure from the system's
    message port list.  Subsequent attempts to rendezvous by name with
    this port will fail.

INPUTS
    port - pointer to a message port

SEE ALSO
    @{"AddPort" link "AddPort()"}, @{"FindPort" link "FindPort()"}

@EndNode

@Node "RemResource()" "exec.library/RemResource"

NAME
    RemResource -- remove a resource from the system

SYNOPSIS
    RemResource(resource)
               A1

    void RemResource(APTR);

FUNCTION
    This function removes an existing resource from the system resource
    list.  There must be no outstanding users of the resource.

INPUTS
    resource - pointer to a resource node

SEE ALSO
    @{"AddResource" link "AddResource()"}

@EndNode

@Node "RemSemaphore()" "exec.library/RemSemaphore"

NAME
    RemSemaphore -- remove a signal semaphore from the system

SYNOPSIS
    RemSemaphore(signalSemaphore)
                 A1

    void RemSemaphore(struct @{"SignalSemaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 40} *);

FUNCTION
    This function removes a signal semaphore structure from the
    system's signal semaphore list.  Subsequent attempts to
    rendezvous by name with this semaphore will fail.

INPUTS
   signalSemaphore -- an initialized signal semaphore structure

SEE ALSO
    @{"AddSemaphore" link "AddSemaphore()"}, @{"FindSemaphore" link "FindSemaphore()"}


@EndNode

@Node "RemTail()" "exec.library/RemTail"

NAME
    RemTail -- remove the tail node from a list

SYNOPSIS
    node = RemTail(list)
    D0             A0

    struct @{"Node" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/nodes.h/Main" 23} *RemTail(struct @{"List" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/lists.h/Main" 21} *);

FUNCTION
    Remove the last node from a list, and return a pointer to it. If
    the list is empty, return zero. Assembly programmers may prefer to
    use the REMTAIL macro from "exec/lists.i".

WARNING
    This function does not arbitrate for access to the list.  The
    calling task must be the owner of the involved list.

INPUTS
    list - a pointer to the target list header

RESULT
    node - the node removed or zero when empty list

SEE ALSO
    @{"AddHead" link "AddHead()"}, @{"AddTail" link "AddTail()"}, @{"Enqueue" link "Enqueue()"}, Insert, Remove, @{"RemHead" link "RemHead()"}, RemTail

@EndNode

@Node "RemTask()" "exec.library/RemTask"

NAME
    RemTask -- remove a task from the system

SYNOPSIS
    RemTask(task)
            A1

    void RemTask(struct @{"Task" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 25} *);

FUNCTION
    This function removes a task from the system.  Deallocation of
    resources should have been performed prior to calling this
    function.  Removing some other task is very dangerous.  Generally
    is is best to arrange for tasks to call RemTask(0L) on themselves.

    RemTask will automagically free any memory lists attached to the
    task's TC_MEMENTRY list.

INPUTS
    task - pointer to the task node representing the task to be
           removed.  A zero value indicates self removal, and will
           cause the next ready task to begin execution.

BUGS
    Before V36 if RemTask() was called on a task other than the current
    task, and that task was created with @{"amiga.lib/CreateTask" Link "amiga_lib/CreateTask()"}, there was
    a slight chance of a crash.  The problem can be hidden by bracketing
    RemTask() with @{"Forbid()/Permit()" Link "Permit()"}.

SEE ALSO
    @{"AddTask" link "AddTask()"}, @{"exec/AllocEntry" link "AllocEntry()"}, @{"amiga.lib/DeleteTask" Link "amiga_lib/DeleteTask()"}

@EndNode

@Node "ReplyMsg()" "exec.library/ReplyMsg"

NAME
    ReplyMsg -- put a message to its reply port

SYNOPSIS
    ReplyMsg(message)
             A1

    void ReplyMsg(struct @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} *);

FUNCTION
    This function sends a message to its reply port.  This is usually
    done when the receiver of a message has finished and wants to
    return it to the sender (so that it can be re-used or deallocated,
    whatever).

    This call may be made from interrupts.

INPUT
    message - a pointer to the message

IMPLEMENTATION
    1> Places "NT_REPLYMSG" into LN_TYPE.
    2> Puts the message to the port specified by MN_REPLYPORT
       If there is no replyport, sets LN_TYPE to "NT_FREEMSG" (use this
       feature only with extreeme care).

SEE ALSO
    @{"GetMsg" link "GetMsg()"}, @{"PutMsg" link "PutMsg()"}, @{"exec/ports.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 0}

@EndNode

@Node "SendIO()" "exec.library/SendIO"

NAME
    SendIO -- initiate an I/O command

SYNOPSIS
    SendIO(iORequest)
           A1

    void SendIO(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    This function requests the device driver start processing the given
    I/O request.  The device will return control without waiting for
    the I/O to complete.

    The io_Flags field of the @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} will be set to zero before the
    request is sent.  See @{"BeginIO()" Link "serial/BeginIO()"} for more details.

INPUTS
    iORequest - pointer to an I/O request, or a device specific
                extended @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19}.

SEE ALSO
    @{"DoIO" link "DoIO()"}, @{"CheckIO" link "CheckIO()"}, @{"WaitIO" link "WaitIO()"}, @{"AbortIO" Link "timer/AbortIO()"}

@EndNode

@Node "SetExcept()" "exec.library/SetExcept"

NAME
    SetExcept -- define certain signals to cause exceptions

SYNOPSIS
    oldSignals = SetExcept(newSignals, signalMask)
    D0                     D0          D1

    ULONG SetExcept(ULONG,ULONG);

FUNCTION
    This function defines which of the task's signals will cause a
    private task exception.  When any of the signals occurs the task's
    exception handler will be dispatched.  If the signal occurred prior
    to calling SetExcept, the exception will happen immediately.

    The user function pointed to by the task's tc_ExceptCode gets
    called as:

        newExcptSet = <exceptCode>(signals, exceptData),SysBase
        D0                         D0       A1          A6

        signals - The set of signals that caused this exception.  These
            Signals have been disabled from the current set of signals
            that can cause an exception.

        exceptData - A copy of the task structure tc_ExceptData field.

        newExcptSet - The set of signals in NewExceptSet will be re-
            enabled for exception generation.  Usually this will be the
            same as the Signals that caused the exception.

INPUTS
    newSignals - the new values for the signals specified in
            signalMask.
    signalMask - the set of signals to be effected

RESULTS
    oldSignals - the prior exception signals

EXAMPLE
    Get the current state of all exception signals:
        SetExcept(0,0)
    Change a few exception signals:
        SetExcept($1374,$1074)

SEE ALSO
    @{"Signal" link "Signal()"}, @{"SetSignal" link "SetSignal()"}

@EndNode

@Node "SetFunction()" "exec.library/SetFunction"

NAME
    SetFunction -- change a function vector in a library

SYNOPSIS
    oldFunc = SetFunction(library, funcOffset, funcEntry)
    D0                    A1       A0.W        D0

    APTR SetFunction(struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *,LONG,APTR);

FUNCTION
    SetFunction is a functional way of changing where vectors in a
    library point.  They are changed in such a way that the
    checksumming process will never falsely declare a library to be
    invalid.

WARNING
    If you use SetFunction on a function that can be called from
    interrupts, you are obligated to provide your own arbitration.

NOTE
    SetFunction cannot be used on non-standard libraries like pre-V36
    dos.library.  Here you must manually @{"Forbid()" Link "Forbid()"}, preserve all 6
    original bytes, set the new vector, @{"SumLibrary()" Link "SumLibrary()"}, then @{"Permit()" Link "Permit()"}.

INPUTS
    library    - a pointer to the library to be changed
    funcOffset - the offset of the function to be replaced
    funcEntry  - pointer to new function

RESULTS
    oldFunc    - pointer to the old function that was just replaced

@EndNode

@Node "SetIntVector()" "exec.library/SetIntVector"

NAME
    SetIntVector -- set a new handler for a system interrupt vector

SYNOPSIS
    oldInterrupt = SetIntVector(intNumber, interrupt)
    D0                          D0         A1

    struct @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} *SetIntVector(ULONG, struct @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} *);

FUNCTION
    This function provides a mechanism for setting the system interrupt
    vectors.  These are non-sharable; setting a new interrupt handler
    disconnects the old one.  Installed handlers are responsible for
    processing, enabling and clearing the interrupt.  Note that interrupts
    may have been left in any state by the previous code.

    The IS_CODE and IS_DATA pointers of the @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} structure will
    be copied into a private place by Exec.  A pointer to the previously
    installed @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} structure is returned.

    When the system calls the specified interrupt code, the registers are
    setup as follows:

        D0 - scratch
        D1 - scratch (on entry: active
                      interrupts -> equals INTENA & INTREQ)

        A0 - scratch (on entry: pointer to base of custom chips
                      for fast indexing)
        A1 - scratch (on entry: Interrupt's IS_DATA pointer)

        A5 - jump vector register (scratch on call)
        A6 - Exec library base pointer (scratch on call)

        all other registers must be preserved

INPUTS
    intNum - the Paula interrupt bit number (0..14).  Only non-chained
             interrupts should be set.  Use @{"AddIntServer()" Link "AddIntServer()"} for server
             chains.
    interrupt - a pointer to an @{"Interrupt" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/interrupts.h/Main" 23} structure containing the
             handler's entry point and data segment pointer.  A NULL
             interrupt pointer will remove the current interrupt and
             set illegal values for IS_CODE and IS_DATA.

             By convention, the LN_NAME of the interrupt structure must
             point a descriptive string so that other users may
             identify who currently has control of the interrupt.

RESULT
    A pointer to the prior interrupt structure which had control
    of this interrupt.

SEE ALSO
    @{"AddIntServer()" Link "AddIntServer()"},exec/interrupts.i,hardware/intbits.i

@EndNode

@Node "SetSignal()" "exec.library/SetSignal"

NAME
    SetSignal -- define the state of this task's signals

SYNOPSIS
    oldSignals = SetSignal(newSignals, signalMask)
    D0                     D0          D1

    ULONG SetSignal(ULONG,ULONG);

FUNCTION
    This function can query or modify the state of the current task's
    received signal mask.  Setting the state of signals is considered
    dangerous.  Reading the state of signals is safe.

INPUTS
    newSignals - the new values for the signals specified in
                 signalSet.
    signalMask - the set of signals to be affected.

RESULTS
    oldSignals - the prior values for all signals

EXAMPLES
    Get the current state of all signals:
        SetSignal(0L,0L);
    Clear the CTRL-C signal:
        SetSignal(0L,SIGBREAKF_CTRL_C);


    Check if the CTRL-C signal was pressed:

        #include @{"<libraries/dos.h>" Link "ADCD_v1.2:Inc&AD2.0/Includes/libraries/dos.h/Main" 0}

        /* Check & clear CTRL_C signal */
        if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C)
            {
            printf("CTRL-C pressed!\n");
            }

SEE ALSO
    @{"Signal" link "Signal()"}, Wait

@EndNode

@Node "SetSR()" "exec.library/SetSR"

NAME
    SetSR -- get and/or set processor status register

SYNOPSIS
    oldSR = SetSR(newSR, mask)
    D0            D0     D1

    ULONG SetSR(ULONG, ULONG);

FUNCTION
    This function provides a means of modifying the CPU status register
    in a "safe" way (well, how safe can a function like this be
    anyway?).  This function will only affect the status register bits
    specified in the mask parameter.  The prior content of the entire
    status register is returned.

INPUTS
    newSR - new values for bits specified in the mask.
        All other bits are not effected.
    mask - bits to be changed

RESULTS
    oldSR - the entire status register before new bits

EXAMPLES
    To get the current SR:
        currentSR = SetSR(0,0);
    To change the processor interrupt level to 3:
        oldSR = SetSR($0300,$0700);
    Set processor interrupts back to prior level:
        SetSR(oldSR,$0700);

@EndNode

@Node "SetTaskPri()" "exec.library/SetTaskPri"

NAME
    SetTaskPri -- get and set the priority of a task

SYNOPSIS
    oldPriority = SetTaskPri(task, priority)
    D0-0:8                   A1    D0-0:8

    BYTE SetTaskPri(struct @{"Task" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 25} *,LONG);

FUNCTION
    This function changes the priority of a task regardless of its
    state.  The old priority of the task is returned.  A reschedule is
    performed, and a context switch may result.

    To change the priority of the currently running task, pass the
    result of FindTask(0); as the task pointer.

INPUTS
    task - task to be affected
    priority - the new priority for the task

RESULT
    oldPriority - the tasks previous priority

@EndNode

@Node "Signal()" "exec.library/Signal"

NAME
    Signal -- signal a task

SYNOPSIS
    Signal(task, signals)
           A1    D0

    void Signal(struct @{"Task" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 25} *,ULONG);

FUNCTION
    This function signals a task with the given signals.  If the task
    is currently waiting for one or more of these signals, it will be
    made ready and a reschedule will occur. If the task is not waiting
    for any of these signals, the signals will be posted to the task
    for possible later use. A signal may be sent to a task regardless
    of whether its running, ready, or waiting.

    This function is considered "low level".  Its main purpose is to
    support multiple higher level functions like @{"PutMsg" link "PutMsg()"}.

    This function is safe to call from interrupts.

INPUT
    task - the task to be signalled
    signals - the signals to be sent

SEE ALSO
    Wait, @{"SetSignal" link "SetSignal()"}

@EndNode

@Node "StackSwap()" "exec.library/StackSwap"

NAME
    StackSwap - EXEC supported method of replacing task's stack      (V37)

SYNOPSIS
    StackSwap(newStack)
              A0

    VOID StackSwap(struct @{"StackSwapStruct" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 53} *);

FUNCTION
    This function will, in an EXEC supported manner, swap the
    stack of your task with the given values in StackSwap.
    The @{"StackSwapStruct" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 53} structure will then contain the values
    of the old stack such that the old stack can be restored.
    This function is new in V37.

NOTE
    If you do a stack swap, only the new stack is set up.
    This function does not copy the stack or do anything else
    other than set up the new stack for the task.  It is
    generally required that you restore your stack before
    exiting.

INPUTS
    newStack - A structure that contains the values for the
            new upper and lower stack bounds and the new stack
            pointer.  This structure will have its values
            replaced by those in you task such that you can
            restore the stack later.

RESULTS
    newStack - The structure will now contain the old stack.
            This means that StackSwap(foo); StackSwap(foo);
            will effectively do nothing.

SEE ALSO
    @{"AddTask" link "AddTask()"}, @{"RemTask" link "RemTask()"}, @{"exec/tasks.h" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/tasks.h/Main" 0}

@EndNode

@Node "SumKickData()" "exec.library/SumKickData"

NAME
    SumKickData -- compute the checksum for the Kickstart delta list

SYNOPSIS
    checksum = SumKickData()
    D0

    ULONG SumKickData(void);

FUNCTION
    The Amiga system has some ROM (or Kickstart) resident code that
    provides the basic functions for the machine.  This code is
    unchangeable by the system software.  This function is part of a
    support system to modify parts of the ROM.

    The ROM code is linked together at run time via ROMTags (also known
    as @{"Resident" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 19} structures, defined in @{"exec/resident.h)" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/resident.h/Main" 0}.  These tags tell
    Exec's low level boot code what subsystems exist in which regions of
    memory.  The current list of ROMTags is contained in the ResModules
    field of @{"ExecBase" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 35}.  By default this list contains any ROMTags found
    in the address ranges $F80000-$FFFFFF and $F00000-$F7FFFF.

    There is also a facility to selectively add or replace modules to the
    ROMTag list.  These modules can exist in RAM, and the memory they
    occupy will be deleted from the memory free list during the boot
    process.  SumKickData() plays an important role in this run-time
    modification of the ROMTag array.

    Three variables in @{"ExecBase" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/execbase.h/Main" 35} are used in changing the ROMTag array:
    KickMemPtr, KickTagPtr, and KickCheckSum. KickMemPtr points to a
    linked list of @{"MemEntry" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 41} structures. The memory that these @{"MemEntry" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 41}
    structures reference will be allocated (via AllocAbs) at boot time.
    The @{"MemEntry" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 41} structure itself must also be in the list.

    KickTagPtr points to a long-word array of the same format as the
    ResModules array.  The array has a series of pointers to ROMTag
    structures.  The array is either NULL terminated, or will have an
    entry with the most significant bit (bit 31) set.  The most
    significant bit being set says that this is a link to another
    long-word array of ROMTag entries.  This new array's address can be
    found by clearing bit 31.

    KickCheckSum has the result of SumKickData().  It is the checksum of
    both the KickMemPtr structure and the KickTagPtr arrays.  If the
    checksum does not compute correctly then both KickMemPtr and
    KickTagPtr will be ignored.

    If all the memory referenced by KickMemPtr can't be allocated then
    KickTagPtr will be ignored.

    There is one more important caveat about adding ROMTags. All this
    ROMTag magic is run very early on in the system -- before expansion
    memory is added to the system. Therefore any memory in this
    additional ROMTag area must be addressable at this time. This means
    that your ROMTag code, @{"MemEntry" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/memory.h/Main" 41} structures, and resident arrays
    cannot be in expansion memory.  There are two regions of memory that
    are acceptable:  one is chip memory, and the other is "Ranger" memory
    (memory in the range between $C00000-$D80000).

    @{"Remember" Link "ADCD_v1.2:Inc&AD2.0/Includes/intuition/intuition.h/Main" 1233} that changing an existing ROMTag entry falls into the
    "heavy magic" category -- be very careful when doing it.  The odd are
    that you will blow yourself out of the water.

NOTE
    SumKickData was introduced in the 1.2 release

RESULT
    Value to be stuffed into ExecBase->KickCheckSum.

WARNING
    After writing to KickCheckSum, you should push the data cache.
    This prevents potential problems with large copyback style caches.
    A call to @{"CacheClearU" link "CacheClearU()"} will do fine.

SEE ALSO
    @{"InitResident" link "InitResident()"}, @{"FindResident" link "FindResident()"}

@EndNode

@Node "SumLibrary()" "exec.library/SumLibrary"

NAME
    SumLibrary -- compute and check the checksum on a library

SYNOPSIS
    SumLibrary(library)
               A1

    void SumLibrary(struct @{"Library" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/libraries.h/Main" 34} *);

FUNCTION
    SumLibrary computes a new checksum on a library.  It can also be
    used to check an old checksum.  If an old checksum does not match,
    and the library has not been marked as changed, then the system
    will call @{"Alert()" Link "Alert()"}.

    This call could also be periodically made by some future
    system-checking task.

INPUTS
    library - a pointer to the library to be changed

NOTE
    An alert will occur if the checksum fails.

SEE ALSO
    @{"SetFunction" link "SetFunction()"}

@EndNode

@Node "SuperState()" "exec.library/SuperState"

NAME
    SuperState -- enter supervisor state with user stack

SYNOPSIS
    oldSysStack = SuperState()
    D0

    APTR SuperState(void);

FUNCTION
    Enter supervisor mode while running on the user's stack. The user
    still has access to user stack variables.  Be careful though, the
    user stack must be large enough to accommodate space for all
    interrupt data -- this includes all possible nesting of interrupts.
    This function does nothing when called from supervisor state.

RESULTS
    oldSysStack - system stack pointer; save this.  It will come in
                  handy when you return to user state.  If the system
                  is already in supervisor mode, oldSysStack is zero.

SEE ALSO
    @{"UserState/Supervisor" link "Supervisor()"}


@EndNode

@Node "Supervisor()" "exec.library/Supervisor"

NAME
    Supervisor -- trap to a short supervisor mode function

SYNOPSIS
    result = Supervisor(userFunc)
    Rx                   A5

    ULONG Supervisor(void *);

FUNCTION
    Allow a normal user-mode program to execute a short assembly language
    function in the supervisor mode of the processor.  Supervisor() does
    not modify or save registers; the user function has full access to the
    register set.   All rules that apply to interrupt code must be
    followed.  In addition, no system calls are permitted.  The function
    must end with an RTE instruction.

EXAMPLE
            ;Obtain the Exception Vector base.  68010 or greater only!
            MOVECtrap:      movec.l VBR,d0  ;$4e7a,$0801
                            rte

INPUTS
    userFunc - A pointer to a short assembly language function ending
               in RTE.  The function has full access to the register set.

RESULTS
    result   - Whatever values the userFunc left in the registers.

SEE ALSO
    @{"SuperState" link "SuperState()"},@{"UserState" link "UserState()"}

@EndNode

@Node "TypeOfMem()" "exec.library/TypeOfMem"

NAME
    TypeOfMem -- determine attributes of a given memory address

SYNOPSIS
    attributes = TypeOfMem(address)
    D0                     A1

    ULONG TypeOfMem(void *);

FUNCTION
    Given a RAM memory address, search the system memory lists and
    return its memory attributes.  The memory attributes are similar to
    those specified when the memory was first allocated: (eg. MEMF_CHIP
    and MEMF_FAST).

    This function is usually used to determine if a particular block of
    memory is within CHIP space.

    If the address is not in known-space, a zero will be returned.
    (Anything that is not RAM, like the ROM or expansion area, will
    return zero.  Also the first few bytes of a memory area are used up
    by the MemHeader.)

INPUT
    address - a memory address

RESULT
    attributes - a long word of memory attribute flags.
    If the address is not in known RAM, zero is returned.

SEE ALSO
    @{"AllocMem()" Link "AllocMem()"}

@EndNode

@Node "UserState()" "exec.library/UserState"

NAME
    UserState -- return to user state with user stack

SYNOPSIS
    UserState(sysStack)
              D0

    void UserState(APTR);

FUNCTION
    Return to user state with user stack, from supervisor state with
    user stack.  This function is normally used in conjunction with the
    @{"SuperState" link "SuperState()"} function above.

    This function must not be called from the user state.

INPUT
    sysStack - supervisor stack pointer

BUGS
    This function is broken in V33/34 Kickstart.  Fixed in V1.31 setpatch.

SEE ALSO
    @{"SuperState/Supervisor" link "Supervisor()"}

@EndNode

@Node "Vacate()" "exec.library/Vacate"

NAME
    Vacate -- release a message lock (semaphore)

SYNOPSIS
    Vacate(semaphore)
           A0

    void Vacate(struct @{"Semaphore" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/semaphores.h/Main" 53} *);

FUNCTION
    This function releases a previously locked semaphore (see
    the @{"Procure()" Link "Procure()"} function).
    If another task is waiting for the semaphore, its bidMessage
    will be sent to its reply port.

INPUT
    semaphore - the semaport message port representing the
    semaphore to be freed.

BUGS
    @{"Procure()" Link "Procure()"} and Vacate() do not have proven reliability.

SEE ALSO
    @{"Procure" link "Procure()"}

@EndNode

@Node "Wait()" "exec.library/Wait"

NAME
    Wait -- wait for one or more signals

SYNOPSIS
    signals = Wait(signalSet)
    D0             D0

    ULONG Wait(ULONG);

FUNCTION
    This function will cause the current task to suspend waiting for
    one or more signals.  When one or more of the specified signals
    occurs, the task will return to the ready state, and those signals
    will be cleared.

    If a signal occurred prior to calling Wait(), the wait condition will
    be immediately satisfied, and the task will continue to run without
    delay.

CAUTION
    This function cannot be called while in supervisor mode or
    interrupts!  This function will break the action of a @{"Forbid()" Link "Forbid()"} or
    @{"Disable()" Link "Disable()"} call.

INPUT
    signalSet - The set of signals for which to wait.
                Each bit represents a particular signal.

RESULTS
    signals - the set of signals that were active

@EndNode

@Node "WaitIO()" "exec.library/WaitIO"

NAME
    WaitIO -- wait for completion of an I/O request

SYNOPSIS
    error = WaitIO(iORequest)
    D0             A1

    BYTE WaitIO(struct @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} *);

FUNCTION
    This function waits for the specified I/O request to complete, then
    removes it from the replyport.  If the I/O has already completed,
    this function will return immediately.

    This function should be used with care, as it does not return until
    the I/O request completes; if the I/O never completes, this
    function will never return, and your task will hang.  If this
    situation is a possibility, it is safer to use the @{"Wait()" Link "Wait()"} function.
    @{"Wait()" Link "Wait()"} will return return when any of a specified set of signal is
    received.  This is how I/O timeouts can be properly handled.

WARNING
    If this @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} was "Quick" or otherwise finished BEFORE this
    call, this function drops though immediately, with no call to
    @{"Wait()" Link "Wait()"}.  A side effect is that the signal bit related the port may
    remain set.  Expect this.

    When removing a known complete @{"IORequest" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/io.h/Main" 19} from a port, WaitIO() is the
    preferred method.  A simple @{"Remove()" Link "Remove()"} would require a Disable/Enable
    pair!

INPUTS
    iORequest - pointer to an I/O request block

RESULTS
    error - zero if successful, else an error is returned
            (a sign extended copy of io_Error).

SEE ALSO
    @{"DoIO" link "DoIO()"}, @{"SendIO" link "SendIO()"}, @{"CheckIO" link "CheckIO()"}, @{"AbortIO" Link "timer/AbortIO()"}

@EndNode

@Node "WaitPort()" "exec.library/WaitPort"

NAME
    WaitPort -- wait for a given port to be non-empty

SYNOPSIS
    message = WaitPort(port)
    D0                 A0

    struct @{"Message" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 48} *WaitPort(struct @{"MsgPort" Link "ADCD_v1.2:Inc&AD2.0/Includes/exec/ports.h/Main" 29} *);

FUNCTION
    This function waits for the given port to become non-empty.  If
    necessary, the @{"Wait()" Link "Wait()"} function will be called to wait for the port
    signal.  If a message is already present at the port, this function
    will return immediately.  The return value is always a pointer to
    the first message queued (but it is not removed from the queue).

CAUTION
    More than one message may be at the port when this returns.  It is
    proper to call the @{"GetMsg()" Link "GetMsg()"} function in a loop until all messages
    have been handled, then wait for more to arrive.

    To wait for more than one port, combine the signal bits from each
    port into one call to the @{"Wait()" Link "Wait()"} function, then use a @{"GetMsg()" Link "GetMsg()"} loop
    to collect any and all messages.  It is possible to get a signal
    for a port WITHOUT a message showing up.  Plan for this.

INPUT
    port - a pointer to the message port

RETURN
    message - a pointer to the first available message

SEE ALSO
    @{"GetMsg" link "GetMsg()"}

@EndNode

