Files
aqhomecontrol/avr/modules/lcd2/win/object.asm
2025-06-12 23:30:36 +02:00

557 lines
11 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. *
; ***************************************************************************
.cseg
; ---------------------------------------------------------------------------
; @routine OBJ_Init @global
;
; @param Y pointer to object SRAM
; @param r17 options
; @clobbers X
OBJ_Init:
push r17
mov xl, yl
mov xh, yh
clr r16
ldi r17, OBJ_OFFS_SIZE
rcall Utils_FillSram ; (R17, X)
rcall Tree_InitObject ; (R16)
pop r17
std Y+OBJ_OFFS_OPTIONS, r17
ldi r16, LOW(OBJ_DefaultHandler)
std Y+OBJ_OFFS_HANDLERFN_LO, r16
ldi r16, HIGH(OBJ_DefaultHandler)
std Y+OBJ_OFFS_HANDLERFN_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_SetHandler @global
;
; @param Y pointer to object SRAM
; @param Z pointer to handler function (word address)
; @clobbers X
OBJ_SetHandler:
std Y+OBJ_OFFS_HANDLERFN_LO, zl
std Y+OBJ_OFFS_HANDLERFN_HI, zh
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_GetHandler @global
;
; @param Y pointer to object SRAM
; @return Z pointer to handler function (word address)
; @clobbers none
OBJ_GetHandler:
ldd zl, Y+OBJ_OFFS_HANDLERFN_LO
ldd zh, Y+OBJ_OFFS_HANDLERFN_HI
ret
; @end
OBJ_DefaultHandler:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_free @global
;
; @param Y pointer to object in SRAM
; @clobbers any
OBJ_free:
; free children
push yl
push yh
rcall Tree_GetFirstChildObject ; (none)
OBJ_free_loop:
mov r16, xl
or r16, xh
breq OBJ_free_loopEnd
mov yl, xl
mov yh, xh
rcall Tree_GetNextSibling
push xl ; next
push xh ; next
rcall OBJ_free
pop xh ; next
pop xl ; next
rjmp OBJ_free_loop
OBJ_free_loopEnd:
pop yh
pop yl
rcall Tree_UnlinkObject ; (r16, r17, x)
push yl
push yh
ldi r16, OBJ_SIGNAL_DESTROY
rcall OBJ_Handler
pop yh
pop yl
rcall objFreeLinks
rcall objFreeTimers
mov xl, yl
mov xh, yh
rcall Heap_free
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Handler
;
; Signal handler for an object. A signal can have up to 3 parameters
; conveyed in registers R18, R19 and X.
;
; @param Y pointer to object SRAM
; @param r16 signal
; @param R18 1st param
; @param R19 2nd param
; @param X 3rd param
OBJ_Handler:
ldd r17, Y+OBJ_OFFS_HANDLERFN_LO
push r17
ldd r17, Y+OBJ_OFFS_HANDLERFN_HI
push r17
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_ForwardSignalToChildren
;
; Signal handler for an object. A signal can have up to 3 parameters
; conveyed in registers R18, R19 and X.
;
; @param Y pointer to object SRAM
; @param r16 signal
; @param R18 1st param
; @param R19 2nd param
; @param X 3rd param
; @clobbers any, !r16, !r18, !r19, !Y
OBJ_ForwardSignalToChildren:
push yl
push yh
rcall Tree_GetFirstChildObject ; (none)
OBJ_ForwardSignalToChildren_loop:
clc
mov r17, xl
or r17, xh
breq OBJ_ForwardSignalToChildren_loopEnd
mov yl, xl
mov yh, xh
push r16
push r18
push r19
push xl
push xh
push yl
push yh
rcall OBJ_Handler
pop yh
pop yl
pop xh
pop xl
pop r19
pop r18
pop r16
rcall Tree_GetNextSibling
rjmp OBJ_ForwardSignalToChildren_loop
OBJ_ForwardSignalToChildren_loopEnd:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_EmitSignal
;
; @param Y pointer to object SRAM
; @param r16 signal to emit
; @param R18 1st param
; @param R19 2nd param
; @param X 3rd param
OBJ_EmitSignal:
push yl
push yh
ldd r17, Y+OBJ_OFFS_LINKS_LO
ldd yh, Y+OBJ_OFFS_LINKS_HI
mov yl, r17
OBJ_EmitSignal_loop:
push r16
rcall objCheckEmitSignalForLink ; (any, !X, !Y, !R18, !R19)
pop r16
push xl
push xh
rcall List_GetNextObject ; (none)
mov yl, xl
mov yh, xh
pop xh
pop xl
mov r17, yl
or r17, yh
brne OBJ_EmitSignal_loop
OBJ_EmitSignal_popRet:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_AddLink @global
;
; @param Y pointer to object SRAM
; @param X pointer to link
; @clobbers R16, R17
OBJ_AddLink:
ldd r16, Y+OBJ_OFFS_LINKS_LO
ldd r17, Y+OBJ_OFFS_LINKS_HI
tst r16
brne OBJ_AddLink_addToExisting
tst r17
brne OBJ_AddLink_addToExisting
; empty list, new link is first
std Y+OBJ_OFFS_LINKS_LO, xl
std Y+OBJ_OFFS_LINKS_HI, xh
rjmp OBJ_AddLink_end
OBJ_AddLink_addToExisting:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, xh
mov xl, r16
mov xh, r17
rcall List_AddObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_AddLink_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_RemoveLink @global
;
; @param Y pointer to object SRAM
; @param X pointer to link
; @clobbers R16, R17
OBJ_RemoveLink:
ldd r16, Y+OBJ_OFFS_LINKS_LO
ldd r17, Y+OBJ_OFFS_LINKS_HI
cp r16, xl
brne OBJ_RemoveLink_notFirst
cp r17, xh
brne OBJ_RemoveLink_notFirst
clr r16
std Y+OBJ_OFFS_LINKS_LO, r16
std Y+OBJ_OFFS_LINKS_HI, r16
rjmp OBJ_RemoveLink_end
OBJ_RemoveLink_notFirst:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, r17
mov xl, r16
mov xh, r17
rcall List_UnlinkObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_RemoveLink_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_AddTimer @global
;
; @param Y pointer to object SRAM
; @param X pointer to timer
; @clobbers R16, R17
OBJ_AddTimer:
ldd r16, Y+OBJ_OFFS_TIMERS_LO
ldd r17, Y+OBJ_OFFS_TIMERS_HI
tst r16
brne OBJ_AddTimer_addToExisting
tst r17
brne OBJ_AddTimer_addToExisting
; empty list, new timer is first
std Y+OBJ_OFFS_TIMERS_LO, xl
std Y+OBJ_OFFS_TIMERS_HI, xh
rjmp OBJ_AddTimer_end
OBJ_AddTimer_addToExisting:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, xh
mov xl, r16
mov xh, r17
rcall List_AddObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_AddTimer_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_RemoveTimer @global
;
; @param Y pointer to object SRAM
; @param X pointer to timer
; @clobbers R16, R17
OBJ_RemoveTimer:
ldd r16, Y+OBJ_OFFS_TIMERS_LO
ldd r17, Y+OBJ_OFFS_TIMERS_HI
cp r16, xl
brne OBJ_RemoveTimer_notFirst
cp r17, xh
brne OBJ_RemoveTimer_notFirst
clr r16
std Y+OBJ_OFFS_TIMERS_LO, r16
std Y+OBJ_OFFS_TIMERS_HI, r16
rjmp OBJ_RemoveTimer_end
OBJ_RemoveTimer_notFirst:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, r17
mov xl, r16
mov xh, r17
rcall List_UnlinkObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_RemoveTimer_end:
ret
; @end
; ---------------------------------------------------------------------------
; @param r16 signal
; @param Y link
; @clobbers any, !X, !Y, !R18, !R19
objCheckEmitSignalForLink:
ldd r17, Y+OBJ_LINK_OFFS_SIGNAL
cp r16, r17
brne objCheckEmitSignalForLink_ret
push yl
push yh
push xl
push xh
push r18
push r19
ldd r16, Y+OBJ_LINK_OFFS_SLOT
ldd r17, Y+OBJ_LINK_OFFS_TARGET_LO
ldd yh, Y+OBJ_LINK_OFFS_TARGET_HI
mov yl, r17
rcall OBJ_Handler
pop r19
pop r18
pop xh
pop xl
pop yh
pop yl
objCheckEmitSignalForLink_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine objFreeLinks
;
; @clobbers r16, r17, r18, r19, r24, r25, X
objFreeLinks:
push yl
push yh
ldd r16, Y+OBJ_OFFS_LINKS_LO
ldd r17, Y+OBJ_OFFS_LINKS_HI
clr r18
std Y+OBJ_OFFS_LINKS_LO, r18
std Y+OBJ_OFFS_LINKS_HI, r18
mov yl, r16
mov yh, r17
ldi zl, LOW(Obj_Link_free)
ldi zh, HIGH(Obj_Link_free)
rcall List_ForEveryObject ; (r16, r17, r18, r19, r24, r25, X, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine objFreeTimers
;
; @clobbers r16, r17, r18, r19, r24, r25, X
objFreeTimers:
push yl
push yh
ldd r16, Y+OBJ_OFFS_TIMERS_LO
ldd r17, Y+OBJ_OFFS_TIMERS_HI
clr r18
std Y+OBJ_OFFS_TIMERS_LO, r18
std Y+OBJ_OFFS_TIMERS_HI, r18
mov yl, r16
mov yh, r17
ldi zl, LOW(Obj_Timer_free)
ldi zh, HIGH(Obj_Timer_free)
rcall List_ForEveryObject ; (r16, r17, r18, r19, r24, r25, X, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Link_new @global
;
; @return CF set if okay, cleared on error
; @return Y pointer to SRAM for link
; @clobbers r16, r17, X
OBJ_Link_new:
ldi r24, LOW(OBJ_LINK_SIZE)
ldi r25, HIGH(OBJ_LINK_SIZE)
rcall Heap_Alloc
brcc OBJ_Link_new_end
mov yl, xl
mov yh, xh
clr r16
ldi r17, OBJ_LINK_SIZE
bigcall Utils_FillSram ; (R17, X)
rcall List_InitObject ; (R16)
sec
OBJ_Link_new_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Link_free @global
;
; @param Y pointer to SRAM for link
; @clobbers r16, r17, r24, r25, X
OBJ_Link_free:
rcall List_FiniObject ; (R16)
mov xl, yl
mov xh, yh
rcall Heap_free ; (r16, r17, r24, r25, X)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Timer_new @global
;
; @return CF set if okay, cleared on error
; @return Y pointer to SRAM for timer
; @clobbers r16, r17, X
OBJ_Timer_new:
ldi r24, LOW(TIMER_SIZE)
ldi r25, HIGH(TIMER_SIZE)
rcall Heap_Alloc
brcc OBJ_Timer_new_end
mov yl, xl
mov yh, xh
clr r16
ldi r17, TIMER_SIZE
bigcall Utils_FillSram ; (R17, X)
rcall List_InitObject ; (R16)
sec
OBJ_Timer_new_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Timer_free @global
;
; @param Y pointer to SRAM for timer
; @clobbers r16, r17, r24, r25, X
OBJ_Timer_free:
rcall List_FiniObject ; (R16)
mov xl, yl
mov xh, yh
rcall Heap_free ; (r16, r17, r24, r25, X)
clc
ret
; @end