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

        IFND    EXEC_LISTS_I
EXEC_LISTS_I    SET     1
**
**      $Filename: exec/lists.i $
**      $Release: 2.04 Includes, V37.4 $
**      $Revision: 36.10 $
**      $Date: 91/02/19 $
**
**      Definitions and macros for use with Exec lists.  Most of the
**      macros require ownership or locking of the list before use.
**
**      (C) Copyright 1985-1999 Amiga, Inc.
**          All Rights Reserved
**

        IFND EXEC_NODES_I
        INCLUDE "exec/nodes.i"
        ENDC    ; EXEC_NODES_I


*---------------------------------------------------------------------

*
* Full featured list header
*
   STRUCTURE    LH,0
        APTR    LH_HEAD
        APTR    LH_TAIL
        APTR    LH_TAILPRED
        UBYTE   LH_TYPE
        UBYTE   LH_pad
        LABEL   LH_SIZE ;word aligned

*
* Minimal List Header - no type checking (best for most applications)
*
   STRUCTURE    MLH,0
        APTR    MLH_HEAD
        APTR    MLH_TAIL
        APTR    MLH_TAILPRED
        LABEL   MLH_SIZE ;longword aligned

*---------------------------------------------------------------------

;Prepare a list header for use
NEWLIST     MACRO   ; list
            MOVE.L  \1,LH_TAILPRED(\1)
            ADDQ.L  #4,\1       ;Get address of LH_TAIL
            CLR.L   (\1)        ;Clear LH_TAIL
            MOVE.L  \1,-(\1)    ;Address of LH_TAIL to LH_HEAD
            ENDM

;Test if list is empty (list address in register)
;This operation is safe at any time - no list arbitration needed.
TSTLIST     MACRO   ; [list]
            IFGT    NARG-1
               FAIL    !!! TSTLIST - Too many arguments !!!
            ENDC
            IFC     '\1',''
            CMP.L   LH_TAIL+LN_PRED(A0),A0
            ENDC
            IFNC    '\1',''
            CMP.L   LH_TAIL+LN_PRED(\1),\1
            ENDC
            ENDM

;Test if list is empty (from effective address of list)
;list arbitration required.
TSTLST2     MACRO    ;EA of list,=node
            MOVE.L   \1,\2
            TST.L    (\2)
            ENDM

;Get next in list
SUCC        MACRO   ; node,=succ
            MOVE.L  (\1),\2
            ENDM

;Get previous in list
PRED        MACRO   ; node,=pred
            MOVE.L  LN_PRED(\1),\2
            ENDM

;If empty, branch
IFEMPTY     MACRO   ; list,label
            CMP.L   LH_TAIL+LN_PRED(\1),\1
            BEQ     \2
            ENDM

;If not empty, branch
IFNOTEMPTY  MACRO   ; list,label
            CMP.L   LH_TAIL+LN_PRED(\1),\1
            BNE     \2
            ENDM

;Get next node, test if at end
TSTNODE     MACRO   ; node,=next
            MOVE.L  (\1),\2
            TST.L   (\2)
            ENDM

;Get next, go to exit label if at end
NEXTNODE    MACRO   ; next=next,=current,exit_label ([.s],DX,AX,DISP16)
            MOVE.L  \1,\2
            MOVE.L  (\2),\1
            IFC     '\0',''     ;Check extension
            BEQ     \3
            ENDC
            IFNC    '\0',''
            BEQ.S   \3
            ENDC
            ENDM

;Add to head of list
ADDHEAD     MACRO   ; A0-list(destroyed) A1-node D0-(destroyed)
            MOVE.L  (A0),D0
            MOVE.L  A1,(A0)
            MOVEM.L D0/A0,(A1)
            MOVE.L  D0,A0
            MOVE.L  A1,LN_PRED(A0)
            ENDM

;Add to tail of list
ADDTAIL     MACRO   ; A0-list(destroyed) A1-node D0-(destroyed)
            ADDQ.L  #LH_TAIL,A0
            MOVE.L  LN_PRED(A0),D0
            MOVE.L  A1,LN_PRED(A0)
            MOVE.L  A0,(A1)
            MOVE.L  D0,LN_PRED(A1)
            MOVE.L  D0,A0
            MOVE.L  A1,(A0)
            ENDM

;Remove node from whatever list it is in
REMOVE      MACRO   ; A0-(destroyed)  A1-node(destroyed)
            MOVE.L  (A1),A0
            MOVE.L  LN_PRED(A1),A1
            MOVE.L  A0,(A1)
            MOVE.L  A1,LN_PRED(A0)
            ENDM

;Remove node from head of list
REMHEAD     MACRO   ; A0-list A1-(destroyed) D0=node
            MOVE.L  (A0),A1
            MOVE.L  (A1),D0
            BEQ.S   REMHEAD\@
            MOVE.L  D0,(A0)
            EXG.L   D0,A1
            MOVE.L  A0,LN_PRED(A1)
REMHEAD\@
            ENDM

;Remove head quickly
;       Useful when a scratch register is available, and
;       list is known to contain at least one node.
REMHEADQ    MACRO   ; list,=node,scratchReg-(destroyed)
            MOVE.L  (\1),\2
            MOVE.L  (\2),\3
            MOVE.L  \3,(\1)
            MOVE.L  \1,LN_PRED(\3)
            ENDM

;Remove node from tail of list
REMTAIL     MACRO   ; A0-list A1-(destroyed) D0=node
            MOVE.L  LH_TAIL+LN_PRED(A0),A1
            MOVE.L  LN_PRED(A1),D0
            BEQ.S   REMTAIL\@
            MOVE.L  D0,LH_TAIL+LN_PRED(A0)
            EXG.L   D0,A1
            MOVE.L  A0,(A1)
            ADDQ.L  #4,(A1)
REMTAIL\@
            ENDM

        ENDC    ; EXEC_LISTS_I