avr: simplify handling of object tree

- set CFLAG if pointer valid, cleared otherwise
- check for inbound NULL pointer
This commit is contained in:
Martin Preuss
2026-01-15 17:26:54 +01:00
parent 37689fbc1d
commit 55292bddf1

View File

@@ -57,14 +57,30 @@
; @routine OBJ_GetParent @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers none
OBJ_GetParent:
tst zh
brne OBJ_GetParent_get
tst zl
brne OBJ_GetParent_get
clc
rjmp OBJ_GetParent_ret
OBJ_GetParent_get:
adiw zh:zl, OBJECT_OFFS_PARENT_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, (OBJECT_OFFS_PARENT_LO+1)
tst r18
brne OBJ_GetParent_secRet
tst r19
clc
breq OBJ_GetParent_ret
OBJ_GetParent_secRet:
sec
OBJ_GetParent_ret:
ret
; @end
@@ -74,14 +90,30 @@ OBJ_GetParent:
; @routine OBJ_GetFirstChild @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers none
OBJ_GetFirstChild:
tst zh
brne OBJ_GetFirstChild_get
tst zl
brne OBJ_GetFirstChild_get
clc
rjmp OBJ_GetFirstChild_ret
OBJ_GetFirstChild_get:
adiw zh:zl, OBJECT_OFFS_CHILD_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, OBJECT_OFFS_CHILD_LO+1
tst r18
brne OBJ_GetFirstChild_secRet
tst r19
clc
breq OBJ_GetFirstChild_ret
OBJ_GetFirstChild_secRet:
sec
OBJ_GetFirstChild_ret:
ret
; @end
@@ -91,14 +123,30 @@ OBJ_GetFirstChild:
; @routine OBJ_GetNext @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers none
OBJ_GetNext:
tst zh
brne OBJ_GetNext_get
tst zl
brne OBJ_GetNext_get
clc
rjmp OBJ_GetNext_ret
OBJ_GetNext_get:
adiw zh:zl, OBJECT_OFFS_NEXT_LO
lpm r18, Z+
lpm r19, Z
sbiw zh:zl, OBJECT_OFFS_NEXT_LO+1
tst r18
brne OBJ_GetNext_secRet
tst r19
clc
breq OBJ_GetNext_ret
OBJ_GetNext_secRet:
sec
OBJ_GetNext_ret:
ret
; @end
@@ -108,38 +156,30 @@ OBJ_GetNext:
; @routine OBJ_GetBelow @global
;
; @param Z byte address of object (for LPM!)
; @return CFLAG set, if found, cleared otherwise
; @return r19:r18 resulting object (byte address for LPM!), NULL otherwise
; @clobbers r16
OBJ_GetBelow:
; check first child
tst zh
brne OBJ_GetBelow_get
tst zl
breq OBJ_GetBelow_ret
OBJ_GetBelow_get:
rcall OBJ_GetFirstChild
mov r16, r18
or r16, r19
sec
brne OBJ_GetBelow_ret
; check neighbour
brcs OBJ_GetBelow_ret ; jmp if found
rcall OBJ_GetNext
mov r16, r18
or r16, r19
sec
brne OBJ_GetBelow_ret
brcs OBJ_GetBelow_ret ; jmp if found
OBJ_GetBelow_loop:
rcall OBJ_GetParent
mov r16, r18
or r16, r19
clc
breq OBJ_GetBelow_ret
brcc OBJ_GetBelow_ret ; jmp if no parent
; use parent
mov zl, r18
mov zh, r19
; don't check for first child here, we came from there!
rcall OBJ_GetNext
mov r16, r18
or r16, r19
sec
brne OBJ_GetBelow_ret
brcs OBJ_GetBelow_ret
rjmp OBJ_GetBelow_loop
OBJ_GetBelow_ret:
ret