; *************************************************************************** ; copyright : (C) 2026 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_GUI2_OBJECT_ASM #define AQH_AVR_GUI2_OBJECT_ASM ; *************************************************************************** ; @module OBJECT ; ; Central to this module is the signal handler (@ref OBJ_HandleSignal). ; ; Inputs: ; - Y: Pointer to the object to handle a signal ; - R16: Signal number (e.g. @ref OBJECT_SIGNAL_DESTROY) ; - R17: Selector ; Normally this comes from the object var OBJECT_OFFS_SELECTOR but it can ; have different meanings for different signals. ; For signals WIDGET_SIGNAL_SETVALUE and WIDGET_SIGNAL_GETVALUE from the ; @ref WIDGET module this contains the id of the value to reference, e.g. ; to set the X position of a widget R17 has the value WIDGET_VALUE_X. ; - X: Parameter for the signal (either as 16-bit value or as two 8-bit values ; in xl and xh). E.g. for signal WIDGET_SIGNAL_SETVALUE this would contain ; the value to assign ; ; Outputs: ; - CFLAG: Set if signal handled. ; - R19:R18: Response from the signal handler. Most signals do not have return values, but ; especially the signal WIDGET_SIGNAL_GETVALUE is expected to return a result. ; ; *************************************************************************** ; defines ; Object in flash .equ OBJECT_OFFS_NEXT_LO = 0 .equ OBJECT_OFFS_NEXT_HI = 1 .equ OBJECT_OFFS_PARENT_LO = 2 .equ OBJECT_OFFS_PARENT_HI = 3 .equ OBJECT_OFFS_CHILD_LO = 4 .equ OBJECT_OFFS_CHILD_HI = 5 .equ OBJECT_OFFS_FLAGS = 6 .equ OBJECT_OFFS_SELECTOR = 7 .equ OBJECT_OFFS_TARGET_LO = 8 .equ OBJECT_OFFS_TARGET_HI = 9 .equ OBJECT_OFFS_OPTS_LO = 10 .equ OBJECT_OFFS_OPTS_HI = 11 .equ OBJECT_OFFS_SIGNALMAP_LO = 12 ; byte address (for LPM!) .equ OBJECT_OFFS_SIGNALMAP_HI = 13 .equ OBJECT_SIZE = 14 ; object opts_lo .equ OBJECT_OPTSLO_TIMER_BIT = 7 .equ OBJECT_OPTSLO_MSGRECV_BIT = 6 ; SignalMap entries .equ OBJECT_SIGNALMAP_OFFS_HEADER = 0 .equ OBJECT_SIGNALMAP_OFFS_ENTRIES = 2 .equ OBJECT_SIGNALMAPENTRY_OFFS_SELECTOR = 0 .equ OBJECT_SIGNALMAPENTRY_OFFS_SIGNAL = 1 ; end if 0 .equ OBJECT_SIGNALMAPENTRY_OFFS_HANDLER_LO = 2 .equ OBJECT_SIGNALMAPENTRY_OFFS_HANDLER_HI = 3 ; signals .equ OBJECT_SIGNAL_NONE = 0 .equ OBJECT_SIGNAL_DESTROY = 1 .equ OBJECT_SIGNAL_TIMER = 2 .equ OBJECT_SIGNAL_RECVMSG = 3 ; X=msg .equ OBJECT_SIGNAL_NEXTFREE = 4 ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine Object_Alloc @global ; ; @return CFLAG set if object created, cleared otherwise ; @return Y address of created object in SDRAM (if CFLAG set) ; @param r25:r24 size of object to allocate ; @clobbers !r16, !r17, !X Object_Alloc: push xl push xh push r16 push r17 bigcall Heap_Alloc ; X=mem allocated (r16, r17, r18, r19, r24, r25, X) pop r17 pop r16 brcc Object_Alloc_ret mov yl, xl mov yh, xh sec Object_Alloc_ret: pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_Init @global ; ; @param Y address of object in SDRAM ; @param r16 value for OBJECT_OFFS_OPTS_LO ; @param r17 value for OBJECT_OFFS_OPTS_HI ; @clobbers r16, r17, X OBJ_Init: push r16 push r17 mov xl, yl mov xh, yh clr r16 ldi r17, OBJECT_SIZE bigcall Utils_FillSram ; (r17, X) pop r17 pop r16 ; set opts std Y+OBJECT_OFFS_OPTS_LO, r16 std Y+OBJECT_OFFS_OPTS_HI, r17 ; set default signal map ldi r16, LOW(Object_DefaultSignalmap*2) std Y+OBJECT_OFFS_SIGNALMAP_LO, r16 ldi r16, HIGH(Object_DefaultSignalmap*2) std Y+OBJECT_OFFS_SIGNALMAP_HI, r16 ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_Fini @global ; ; @param Y address of object in SDRAM ; @clobbers none OBJ_Fini: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_Free @global ; ; Sends a OBJECT_SIGNAL_DESTROY signal to all children and to the given ; object which frees all objects from the Heap. ; CAVEAT: Y is invalid after return! ; ; @param Y address of object in SDRAM ; @clobbers none OBJ_Free: tst yl brne OBJ_Free_notNull tst yh brne OBJ_Free_notNull rjmp OBJ_Free_ret OBJ_Free_notNull: ldi r16, OBJECT_SIGNAL_DESTROY clr r17 rcall OBJ_TreeHandleSignalChildenFirst ; (any, !R16, !R17, !X, !Y) OBJ_Free_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_OnDestroy @global ; ; Releases given object from heap. ; CAVEAT: Y is invalid after return! ; ; @param Y address of object in SDRAM ; @return CFLAG set if signal handled ; @clobbers r16, r17, r18, r19, r20, r21, r24, r25, X OBJ_OnDestroy: rcall OBJ_Unlink ; (r16, r17, r18, r19, r20, r21, X) mov xl, yl mov xh, yh bigcall Heap_Free ; (r16, r17, r24, r25, X) sec ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_GetNext @global ; ; @param Y address of object ; @return CFLAG set, if found, cleared otherwise ; @return r19:r18 resulting object ; @clobbers none OBJ_GetNext: tst yl brne OBJ_GetNext_notNull tst yh brne OBJ_GetNext_notNull rjmp OBJ_GetNext_clcRet OBJ_GetNext_notNull: ldd r18, Y+OBJECT_OFFS_NEXT_LO ldd r19, Y+OBJECT_OFFS_NEXT_HI tst r18 brne OBJ_GetNext_secRet tst r19 brne OBJ_GetNext_secRet OBJ_GetNext_clcRet: clc rjmp OBJ_GetNext_ret OBJ_GetNext_secRet: sec OBJ_GetNext_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_GetParent @global ; ; @param Y address of object ; @return CFLAG set, if found, cleared otherwise ; @return r19:r18 resulting object ; @clobbers none OBJ_GetParent: tst yl brne OBJ_GetParent_notNull tst yh brne OBJ_GetParent_notNull rjmp OBJ_GetParent_clcRet OBJ_GetParent_notNull: ldd r18, Y+OBJECT_OFFS_PARENT_LO ldd r19, Y+OBJECT_OFFS_PARENT_HI tst r18 brne OBJ_GetParent_secRet tst r19 brne OBJ_GetParent_secRet OBJ_GetParent_clcRet: clc rjmp OBJ_GetParent_ret OBJ_GetParent_secRet: sec OBJ_GetParent_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_GetFirstChild @global ; ; @param Y address of object ; @return CFLAG set, if found, cleared otherwise ; @return r19:r18 resulting object ; @clobbers none OBJ_GetFirstChild: tst yl brne OBJ_GetFirstChild_notNull tst yh brne OBJ_GetFirstChild_notNull rjmp OBJ_GetFirstChild_clcRet OBJ_GetFirstChild_notNull: ldd r18, Y+OBJECT_OFFS_PARENT_LO ldd r19, Y+OBJECT_OFFS_PARENT_HI tst r18 brne OBJ_GetFirstChild_secRet tst r19 brne OBJ_GetFirstChild_secRet OBJ_GetFirstChild_clcRet: clc rjmp OBJ_GetFirstChild_ret OBJ_GetFirstChild_secRet: sec OBJ_GetFirstChild_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_GetLastChild @global ; ; @param Y address of object ; @return CFLAG set, if found, cleared otherwise ; @return r19:r18 resulting object ; @clobbers none OBJ_GetLastChild: push yl push yh rcall OBJ_GetFirstChild ; R19:R18=obj (none) brcc OBJ_GetLastChild_ret OBJ_GetLastChild_loop: mov yl, r18 mov yh, r19 rcall OBJ_GetNext ; R19:R18=obj (none) brcs OBJ_GetLastChild_loop mov r18, yl mov r19, yh sec OBJ_GetLastChild_ret: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_GetChildAt @global ; ; @param Y address of object ; @param R16 idx of child to get (starting at 0) ; @return CFLAG set, if found, cleared otherwise ; @return r19:r18 resulting object ; @clobbers none OBJ_GetChildAt: push yl push yh rcall OBJ_GetFirstChild ; R19:R18=obj (none) brcc OBJ_GetChildAt_ret OBJ_GetChildAt_loop: tst r16 breq OBJ_GetChildAt_secRet mov yl, r18 mov yh, r19 rcall OBJ_GetNext ; R19:R18=obj (none) brcs OBJ_GetChildAt_loop rjmp OBJ_GetChildAt_ret ; idx too high, not found OBJ_GetChildAt_secRet: sec OBJ_GetChildAt_ret: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_AddChild @global ; ; @param Y object to add ; @param X object to add to ; @clobbers r18, r19 OBJ_AddChild: mov r18, yl ; switch X/Y mov yl, xl mov xl, r18 mov r18, yh mov yh, xh mov xh, r18 rcall objAddObjXAsChildToY mov r18, yl ; switch X/Y mov yl, xl mov xl, r18 mov r18, yh mov yh, xh mov xh, r18 ret ; @end ; --------------------------------------------------------------------------- ; @routine objAddObjXAsChildToY ; ; @param Y object to add to ; @param X object to add ; @clobbers r18, r19 objAddObjXAsChildToY: rcall OBJ_GetLastChild ; r19:r18=last child (r18, r19) brcc objAddObjXAsChildToY_setAsFirstChild ; append to last child push yl push yh mov yl, r18 mov yh, r19 std Y+OBJECT_OFFS_NEXT_LO, xl std Y+OBJECT_OFFS_NEXT_HI, xh pop yh pop yl rjmp objAddObjXAsChildToY_setParent objAddObjXAsChildToY_setAsFirstChild: std Y+OBJECT_OFFS_CHILD_LO, xl std Y+OBJECT_OFFS_CHILD_HI, xh objAddObjXAsChildToY_setParent: adiw xh:xl, OBJECT_OFFS_PARENT_LO st X+, yl st X, yh sbiw xh:xl, (OBJECT_OFFS_PARENT_LO+1) ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_Unlink @global ; ; @param Y object to unlink ; @clobbers r16, r17, r18, r19, r20, r21, X OBJ_Unlink: mov xl, yl mov xh, yh adiw xh:xl, OBJECT_OFFS_NEXT_LO ; r21:r20=next ld r20, X+ ld r21, X sbiw xh:xl, (OBJECT_OFFS_NEXT_LO+1) push yl push yh rcall objGetPredecessor ; Y=predecessor (r16, r17, Y) brcc OBJ_Unlink_l1 ; unlink from predecessor std Y+OBJECT_OFFS_NEXT_LO, r20 ; copy NEXT to predecessor std Y+OBJECT_OFFS_NEXT_HI, r21 rjmp OBJ_Unlink_l2 OBJ_Unlink_l1: ; no predecessor, unlink from parent pop yh pop yl rcall OBJ_GetParent brcc OBJ_Unlink_clearTreePtrs push yl push yh mov yl, r18 mov yh, r19 std Y+OBJECT_OFFS_CHILD_LO, r20 std Y+OBJECT_OFFS_CHILD_HI, r21 OBJ_Unlink_l2: pop yh pop yl OBJ_Unlink_clearTreePtrs: clr r16 std Y+OBJECT_OFFS_NEXT_LO, r16 std Y+OBJECT_OFFS_NEXT_HI, r16 std Y+OBJECT_OFFS_PARENT_LO, r16 std Y+OBJECT_OFFS_PARENT_HI, r16 OBJ_Unlink_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_GetRootToY @global ; ; @param Y address of object ; @return Y address pointer to root object ; @clobbers r18, r19 OBJ_GetRootToY: OBJ_GetRootToY_loop: rcall OBJ_GetParent ; (none) brcc OBJ_GetRootToY_found ; no parent, return current Y mov yl, r18 mov yh, r19 rjmp OBJ_GetRootToY_loop OBJ_GetRootToY_found: sec OBJ_GetRootToY_end: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_EmitSignal @global ; ; @param Z byte address of object (for LPM!) ; @param R16 signal number ; @param xl param1 ; @param xh param2 ; @clobbers any, !Y OBJ_EmitSignal: push yl push yh ldd r17, Y+OBJECT_OFFS_SELECTOR ldd r23, Y+OBJECT_OFFS_TARGET_LO ldd yh, Y+OBJECT_OFFS_TARGET_HI mov yl, r23 rcall OBJ_HandleSignal ; (any, !Y) pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_HandleSignal @global ; ; @param Y address of object ; @param R16 signal number ; @param R17 selector ; @param xl param1 ; @param xh param2 ; @return CFLAG set if handled, cleared otherwise ; @return r19:r18 return value from signal handler ; @clobbers any, !Y OBJ_HandleSignal: ; check pointer mov r18, yl or r18, yh clc breq OBJ_HandleSignal_ret ; start with objects signal map ldd zl, Y+OBJECT_OFFS_SIGNALMAP_LO ldd zh, Y+OBJECT_OFFS_SIGNALMAP_HI OBJ_HandleSignal_loop: ; test table validity mov r18, zl or r18, zh clc breq OBJ_HandleSignal_ret ; try this table push zl push zh rcall objHandleSignalWithMap ; (any, !Y) pop zh pop zl brcs OBJ_HandleSignal_ret ; get next table lpm r18, Z+ lpm zh, Z mov zl, r18 rjmp OBJ_HandleSignal_loop ; try next table OBJ_HandleSignal_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_TreeHandleSignal @global @recursive ; ; @param Y address of object ; @param R16 signal number ; @param R17 selector ; @param xl param1 ; @param xh param2 ; @return CFLAG set if handled, cleared otherwise ; @clobbers any, !R16, !R17, !X, !Y OBJ_TreeHandleSignal: push yl push yh ; call signal handler push r16 push r17 push xl push xh rcall OBJ_HandleSignal ; (any, !Y) pop xh pop xl pop r17 pop r16 ; handle children rcall OBJ_GetFirstChild ; r19:r18=object (none) OBJ_TreeHandleSignal_loop: brcc OBJ_TreeHandleSignal_done mov yl, r18 mov yh, r19 rcall OBJ_TreeHandleSignal ; recursion! rcall OBJ_GetNext ; r19:r18=object (none) rjmp OBJ_TreeHandleSignal_loop OBJ_TreeHandleSignal_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_TreeHandleSignalIfMatchingOptsLo @global @recursive ; ; @param Y address of object ; @param R16 signal number ; @param R17 selector ; @param xl param1 ; @param xh param2 ; @param r20 mask for OBJECT_OFFS_OPTS_LO ; @param r21 value for OBJECT_OFFS_OPTS_LO to match ; @return CFLAG set if handled, cleared otherwise ; @clobbers any, !R16, !R17, !X, !Y OBJ_TreeHandleSignalIfMatchingOpts: push yl push yh ; call signal handler push r16 push r17 push xl push xh ldd r18, Y+OBJECT_OFFS_OPTS_LO eor r18, r21 and r18, r20 brne OBJ_TreeHandleSignalIfMatchingOpts_l1 push r20 push r21 rcall OBJ_HandleSignal ; (any, !Y) pop r21 pop r20 OBJ_TreeHandleSignalIfMatchingOpts_l1: pop xh pop xl pop r17 pop r16 ; handle children rcall OBJ_GetFirstChild ; r19:r18=object (none) OBJ_TreeHandleSignalIfMatchingOpts_loop: brcc OBJ_TreeHandleSignalIfMatchingOpts_done mov yl, r18 mov yh, r19 rcall OBJ_TreeHandleSignalIfMatchingOpts ; recursion! rcall OBJ_GetNext ; r19:r18=object (none) rjmp OBJ_TreeHandleSignalIfMatchingOpts_loop OBJ_TreeHandleSignalIfMatchingOpts_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_TreeHandleSignalChildenFirst @global @recursive ; ; Sends a given signal to a tree of objects, handling children first. ; After sending a signal to a child object that object is no longer accessed ; from within this routine, so it can be used to send a DESTROY signal which ; frees the object from the memory heap. ; ; @param Y address of object ; @param R16 signal number ; @param R17 selector ; @param xl param1 ; @param xh param2 ; @return CFLAG set if handled, cleared otherwise ; @clobbers any, !R16, !R17, !X, !Y OBJ_TreeHandleSignalChildenFirst: push yl push yh ; handle children first rcall OBJ_GetFirstChild ; r19:r18=object (none) brcc OBJ_TreeHandleSignalChildenFirst_done OBJ_TreeHandleSignalChildenFirst_loop: mov yl, r18 mov yh, r19 rcall OBJ_GetNext ; r19:r18=object (none) ldi r20, 0 sbci r20, 0 push r18 push r19 push r20 rcall OBJ_TreeHandleSignalChildenFirst ; recursion! pop r20 pop r19 pop r18 tst r20 ; result of OBJ_GetNext (0=no next) brne OBJ_TreeHandleSignalChildenFirst_loop OBJ_TreeHandleSignalChildenFirst_done: pop yh pop yl ; call signal handler on self push r16 push r17 push xl push xh rcall OBJ_HandleSignal ; (any, !Y) pop xh pop xl pop r17 pop r16 ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_AddFlagsDown @global ; ; @param Y address of object ; @param R16 flags to add ; @clobbers r17, r18, r19 OBJ_AddFlagsDown: push yl push yh ldd r17, Y+OBJECT_OFFS_FLAGS or r17, r16 std Y+OBJECT_OFFS_FLAGS, r17 ; handle children rcall OBJ_GetFirstChild ; r19:r18=object (none) OBJ_AddFlagsDown_loop: brcc OBJ_AddFlagsDown_done mov yl, r18 mov yh, r19 rcall OBJ_AddFlagsDown ; recursion! rcall OBJ_GetNext ; r19:r18=object (none) rjmp OBJ_AddFlagsDown_loop OBJ_AddFlagsDown_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_SubFlagsDown @global ; ; @param Y address of object ; @param R16 flags to subtract ; @clobbers r17, r18, r19 OBJ_SubFlagsDown: push yl push yh ldd r17, Y+OBJECT_OFFS_FLAGS com r16 and r17, r16 com r16 std Y+OBJECT_OFFS_FLAGS, r17 ; handle children rcall OBJ_GetFirstChild ; r19:r18=object (none) OBJ_SubFlagsDown_loop: brcc OBJ_SubFlagsDown_done mov yl, r18 mov yh, r19 rcall OBJ_SubFlagsDown ; recursion! rcall OBJ_GetNext ; r19:r18=object (none) rjmp OBJ_SubFlagsDown_loop OBJ_SubFlagsDown_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_AddFlagsUp @global @recursive ; ; @param Y address of object ; @param R16 flags to add ; @clobbers r17, r18, r19 OBJ_AddFlagsUp: push yl push yh ldd r17, Y+OBJECT_OFFS_FLAGS or r17, r16 std Y+OBJECT_OFFS_FLAGS, r17 ; handle parents OBJ_AddFlagsUp_loop: rcall OBJ_GetParent ; r19:r18=object (none) brcc OBJ_AddFlagsUp_done mov yl, r18 mov yh, r19 rcall OBJ_AddFlagsUp ; recursion! rjmp OBJ_AddFlagsUp_loop OBJ_AddFlagsUp_done: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine objHandleSignalWithMap ; ; @param Y byte address of object (for LPM!) ; @param Z signal map to use ; @param R16 signal number ; @param R17 selector ; @param xl param1 ; @param xh param2 ; @return CFLAG set if handled, cleared otherwise ; @return r19:r18 return value from signal handler ; @clobbers any, !Y objHandleSignalWithMap: push yl push yh rcall objGetHandlerFromSignalMap ; r19:r18=handler (r22, r23, Z) brcc objHandleSignalWithMap_done rcall objHandleSignalWithMap_jmpR19R18 objHandleSignalWithMap_done: pop yh pop yl ret objHandleSignalWithMap_jmpR19R18: ; jmp to r19:r18 via stack push r18 push r19 ret ; @end ; --------------------------------------------------------------------------- ; @routine objGetHandlerFromSignalMap ; ; @param Y address of object ; @param Z signal map to use (byte address for LPM!) ; @param R16 signal number ; @param R17 selector ; @param xl param1 ; @param xh param2 ; @return CFLAG set if found, cleared otherwise ; @return R19:R18 handler found ; @clobbers r22, r23, Z objGetHandlerFromSignalMap: mov r23, zl or r23, zh clc breq objGetHandlerFromSignalMap_done adiw zh:zl, OBJECT_SIGNALMAP_OFFS_ENTRIES ; go straight to entries objGetHandlerFromSignalMap_loop: lpm r22, Z+ ; selector lpm r23, Z+ ; signal (0=end of table) lpm r18, Z+ ; handler LOW lpm r19, Z+ ; handler HIGH tst r23 ; end of table? clc breq objGetHandlerFromSignalMap_done ; yes, jmp cp r16, r23 ; signal match? brne objGetHandlerFromSignalMap_next ; no, next tst r22 breq objGetHandlerFromSignalMap_checkHandler ; accept any selector if it is 0 in table cp r17, r22 ; selector match? brne objGetHandlerFromSignalMap_next ; no, next objGetHandlerFromSignalMap_checkHandler: mov r23, r18 ; handler==NULL? or r23, r19 clc breq objGetHandlerFromSignalMap_done ; yes, done sec ; found handler, return in r19:r18 rjmp objGetHandlerFromSignalMap_done objGetHandlerFromSignalMap_next: rjmp objGetHandlerFromSignalMap_loop objGetHandlerFromSignalMap_done: ret ; @end ; --------------------------------------------------------------------------- ; @routine objGetPredecessor ; ; @param Y address of object whose predecessor is to be found ; @return CFLAG set if predecessor found, cleared otherwise ; @return Y pointer to predecessor (if CFLAG set) ; @clobbers r16, r17, Y objGetPredecessor: rcall OBJ_GetParent brcc objGetPredecessor_ret mov r16, yl mov r17, yh rcall OBJ_GetFirstChild ; R19:R18=obj brcc objGetPredecessor_ret mov yl, r18 mov yh, r19 objGetPredecessor_loop: rcall OBJ_GetNext brcc objGetPredecessor_ret cp r18, r16 brne objGetPredecessor_next cp r19, r17 brne objGetPredecessor_next sec rjmp objGetPredecessor_ret objGetPredecessor_next: mov yl, r18 mov yh, r19 rjmp objGetPredecessor_loop objGetPredecessor_ret: ret ; @end ; *************************************************************************** ; data in FLASH Object_DefaultSignalmap: ; header .dw 0 ; next table to use (none here) ; entries .db 0, OBJECT_SIGNAL_DESTROY, LOW(OBJ_OnDestroy), HIGH(OBJ_OnDestroy) .db 0, 0, 0, 0 ; end of table ; @endmodule #endif