;*******************************************************************************
; Director - ListMacros - This file holds macro definitions for linked lists
;
; Copyright (C) 2002, Nick Craig-Wood and the RISC OS Director Developers
;
;This program is free software; you can redistribute it and/or modify it under
;the terms of the GNU General Public License as published by the Free Software
;Foundation; either version 2 of the License, or (at your option) any later
;version.
;
;This program is distributed in the hope that it will be useful, but WITHOUT ANY
;WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
;PARTICULAR PURPOSE. See the GNU General Public License for more details.
;
;You should have received a copy of the GNU General Public License along with
;this program; if not, write to the Free Software Foundation, Inc., 59 Temple
;Place - Suite 330, Boston, MA 02111-1307, USA
;
;*******************************************************************************
;----h- Director.h.ListMacros
; Name
;   ListMacros
;
; Purpose
;   ListMacros
;------
;*******************************************************************************

		TTL > ListMacros - This file holds macro definitions for linked lists

;*******************************************************************************
;This walks down a linked list
;Entry	$current = points to the link field of the current item
;Exit	$current = pointer to new item (or 0 for end)
;	$previous = pointer to previous item
;	Z => end of list
;*******************************************************************************

		MACRO
$label		ListWalk	$current, $previous

$label		MOVS	$previous,$current	;if link was 0 then return a 0
		LDRNE	$current,[$previous]	;link on to next
		CMPNE	$current,#0

		MEND

;*******************************************************************************
;This walks down a linked list
;You may destroy the blocks if you want and the macro will be
;careful not to reference any deleted blocks
;
;Entry
;	$current  list anchor
;Exit
;	$current  current item (or 0 for end)
;	$previous  previous item
;	$next  next item
;	Z => end of list
;Exit
;	Z => end of list
;
;Usage
;
;loop	ListWalkForDestruction	r0,r1,r2
;	BEQ	end
;	SomeTestOrOther
;	UnLink	r0,r1,lr,NE
;	MOVEQ	r1,r0		;update previous
;	BL	free
;	B	loop
;end
;*******************************************************************************

		MACRO
$label		ListWalkForDestruction	$current, $previous, $next
		ASSERT	"$label" <> ""	;Must supply a label for the loop
		MOV	$previous,$current	;anchor of list
		LDR	$next,[$previous]	;first block
$label
		MOVS	$current,$next		;pointer to next block
		LDRNE	$next,[$current]	;link on to next for later

		MEND

;*******************************************************************************
;This walks down a linked list to the end
;Entry	$current = points to the link field of the current item
;Exit	$current = pointer to last item
;	$temp    = destroyed
;	Z => end of list
;*******************************************************************************

		MACRO
$label		ListEnd	$current, $temp

$label
00
		ListWalk $current, $temp
		BNE	%BT00
		MOV	$current,$temp

		MEND

;*******************************************************************************
;This links a new item in front of the one pointed to
;Entry	$item = pointer to item to link in
;	$prev = points to the link field of the item to link into
;*******************************************************************************

		MACRO
$label		Link	$item, $prev, $temp

$label		LDR	$temp,[$prev]	;get onward link
		STR	$temp,[$item]	;store it in new link
		STR	$item,[$prev]	;store new pointer in old

		MEND

;*******************************************************************************
;This unlinks the item pointed
;Entry	$item points to the item to unlink
;	$prev points to the link field previous item
;*******************************************************************************

		MACRO
$label		UnLink	$item, $prev, $temp

$label		LDR	$temp,[$item]	;get onward link
		STR	$temp,[$prev]	;store it in prev link

		MEND

;*******************************************************************************
		END
