193 lines
5.0 KiB
NASM
193 lines
5.0 KiB
NASM
; ***************************************************************************
|
|
; copyright : (C) 2025 by Martin Preuss
|
|
; email : martin@libchipcard.de
|
|
;
|
|
; ***************************************************************************
|
|
; * This file is part of the project "AqHome". *
|
|
; * Please see toplevel file COPYING of that project for license details. *
|
|
; ***************************************************************************
|
|
|
|
#ifndef AQH_AVR_COMMON_TREE_H
|
|
#define AQH_AVR_COMMON_TREE_H
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; defs
|
|
|
|
.equ TREE_OFFS_LIST = 0
|
|
.equ TREE_OFFS_WPARENT_LO = TREE_OFFS_LIST+LIST_SIZE
|
|
.equ TREE_OFFS_WPARENT_HI = TREE_OFFS_LIST+LIST_SIZE+1
|
|
.equ TREE_OFFS_WCHILD_LO = TREE_OFFS_LIST+LIST_SIZE+2
|
|
.equ TREE_OFFS_WCHILD_HI = TREE_OFFS_LIST+LIST_SIZE+3
|
|
.equ TREE_SIZE = TREE_OFFS_LIST+LIST_SIZE+4
|
|
|
|
|
|
|
|
|
|
; ***************************************************************************
|
|
; code
|
|
|
|
.cseg
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Tree_InitObject @global
|
|
|
|
; @param Y pointer to object to add
|
|
; @clobbers r16
|
|
|
|
Tree_InitObject:
|
|
rcall List_InitObject ; (R16)
|
|
clr r16 ; clear this->TREE data
|
|
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_LO, r16
|
|
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_HI, r16
|
|
std Y+TREE_OFFS_LIST+TREE_OFFS_WCHILD_LO, r16
|
|
std Y+TREE_OFFS_LIST+TREE_OFFS_WCHILD_HI, r16
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Tree_GetParentObject @global
|
|
|
|
; @param Y pointer to object
|
|
; @return X pointer to parent object
|
|
; @clobbers none
|
|
|
|
Tree_GetParentObject:
|
|
ldd xl, Y+TREE_OFFS_WPARENT_LO
|
|
ldd xh, Y+TREE_OFFS_WPARENT_HI
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Tree_GetFirstChildObject @global
|
|
|
|
; @param Y pointer to object
|
|
; @return X pointer to first child object
|
|
; @clobbers none
|
|
|
|
Tree_GetFirstChildObject:
|
|
ldd xl, Y+TREE_OFFS_WCHILD_LO
|
|
ldd xh, Y+TREE_OFFS_WCHILD_HI
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Tree_GetObjectBelow @global
|
|
|
|
; @param Y pointer to object
|
|
; @return X pointer to object below (or NULL)
|
|
; @clobbers r16
|
|
|
|
Tree_GetObjectBelow:
|
|
push yl
|
|
push yh
|
|
rcall treeGetObjectBelow
|
|
pop yh
|
|
pop yl
|
|
ret
|
|
|
|
treeGetObjectBelow:
|
|
rcall Tree_GetFirstChildObject
|
|
mov r16, xl
|
|
or r16, xh
|
|
brne treeGetObjectBelow_ret ; got one
|
|
rcall List_GetNextObject
|
|
mov r16, xl
|
|
or r16, xh
|
|
brne treeGetObjectBelow_ret ; got one
|
|
rcall Tree_GetParentObject
|
|
mov r16, xl
|
|
or r16, xh
|
|
breq treeGetObjectBelow_ret ; no parent
|
|
mov yl, xl
|
|
mov yh, xh
|
|
rjmp treeGetObjectBelow ; try with parent
|
|
treeGetObjectBelow_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Tree_AddChildObject @global
|
|
|
|
; @param X pointer to parent to add to
|
|
; @param Y pointer to object to add
|
|
; @clobbers r16, r17, r18, x
|
|
|
|
Tree_AddChildObject:
|
|
std Y+TREE_OFFS_WPARENT_LO, xl ; immediately store parent pointer
|
|
std Y+TREE_OFFS_WPARENT_HI, xh
|
|
adiw xh:xl, TREE_OFFS_WCHILD_LO
|
|
ld r16, X+
|
|
ld r17, X
|
|
mov r18, r16
|
|
or r18, r17
|
|
brne Tree_AddChildObject_addToChildList
|
|
st X, yh ; no child, set THIS as first
|
|
st -X, yl
|
|
sbiw xh:xl, WID_OFFS_TREE+TREE_OFFS_WCHILD_LO
|
|
ret
|
|
Tree_AddChildObject_addToChildList:
|
|
mov xl, r16
|
|
mov xh, r17
|
|
rjmp List_AddObject
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Tree_UnlinkObject @global
|
|
|
|
; @param Y pointer to object to remove
|
|
; @clobbers r16, r17, x
|
|
|
|
Tree_UnlinkObject:
|
|
ldd xl, Y+TREE_OFFS_WPARENT_LO
|
|
ldd xh, Y+TREE_OFFS_WPARENT_HI
|
|
mov r16, xl
|
|
or r16, xh
|
|
breq Tree_UnlinkObject_ret ; not part of a tree
|
|
adiw xh:xl, TREE_OFFS_WCHILD_LO ; get parent's first child to R17:R16
|
|
ld r16, X+
|
|
ld r17, X
|
|
cp r16, yl ; same as THIS?
|
|
brne Tree_UnlinkObject_inList ; nope, need to check childList
|
|
cp r17, yh
|
|
brne Tree_UnlinkObject_inList ; nope, need to check childList
|
|
ldd r16, Y+TREE_OFFS_LIST+LIST_OFFS_NEXT_HI ; is first child, set this->NEXT as new first child
|
|
st X, r16
|
|
ldd r16, Y+TREE_OFFS_LIST+LIST_OFFS_NEXT_LO
|
|
st -X, r16
|
|
rjmp Tree_UnlinkObject_clrParentAndSibling
|
|
Tree_UnlinkObject_inList:
|
|
mov xl, r16
|
|
mov xh, r17
|
|
rcall List_UnlinkObject ; (R16, R17, X)
|
|
Tree_UnlinkObject_clrParentAndSibling:
|
|
clr r16 ; clear this->PARENT
|
|
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_LO, r16
|
|
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_HI, r16
|
|
std Y+LIST_OFFS_NEXT_LO, r16
|
|
std Y+LIST_OFFS_NEXT_HI, r16 ; clear this->NEXT
|
|
Tree_UnlinkObject_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
#endif ; AQH_AVR_COMMON_TREE_H
|
|
|