557 lines
11 KiB
NASM
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
|
|
bigcall Utils_FillSram ; (R17, X)
|
|
bigcall 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)
|
|
bigcall 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)
|
|
bigcall 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
|
|
bigcall Heap_free ; (r16, r17, r24, r25, X)
|
|
clc
|
|
ret
|
|
; @end
|
|
|
|
|
|
|