; *************************************************************************** ; 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_WIN_OBJECT_H #define AQH_AVR_WIN_OBJECT_H .cseg ; --------------------------------------------------------------------------- ; @routine OBJ_Init @global ; ; Generally every object only reports its signals to a single other object ; (called the target). However, every object can receive signals from multiple ; sender objects. To allow this the target assigns its own id (called idForTarget) ; to the new object in order to determine who sent the signal and to act accordingly. ; There are system signals which don't use idForTarget (like OBJ_SIGNAL_DESTROY). ; ; @param Y pointer to object in SRAM ; @param r18 options ; @clobbers r16, r17, X OBJ_Init: mov xl, yl mov xh, yh clr r16 ldi r17, OBJ_OFFS_SIZE bigcall Utils_FillSram ; (R17, X) bigcall Tree_InitObject ; (R16) std Y+OBJ_OFFS_OPTIONS, r18 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_SetTarget @global ; ; @param r19 srcIdForTarget ; @param X pointer to target ; @clobbers none OBJ_SetTarget: std Y+OBJ_OFFS_TARGET_LO, xl std Y+OBJ_OFFS_TARGET_HI, xh std Y+OBJ_OFFS_IDFORTARGET, r19 ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_SetHandler @global ; ; @param Y pointer to object SRAM ; @param Z pointer to handler function (word address) ; @clobbers none 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 ; --------------------------------------------------------------------------- ; @routine OBJ_DefaultHandler @global ; ; This is a default signal handler which does nothing. ; ; @param Y pointer to object SRAM ; @param r18 signal ; @param r19 srcIdForTarget ; @param R20 1st param ; @param R21 2nd param ; @param X 3rd param ; @clobbers any OBJ_DefaultHandler: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_Fini @global ; ; This routine calls OBJ_Fini on every child object, Then it sends the signal ; OBJ_SIGNAL_DESTROY to this object allowing it to release all its ressources ; (including memory space if using heap or other dynamic ressources). ; ; @param Y pointer to object in SRAM ; @clobbers any, !Y OBJ_Fini: ; fini children push yl push yh bigcall Tree_GetFirstChildObject ; (none) OBJ_Fini_loop: mov r16, xl or r16, xh breq OBJ_Fini_loopEnd mov yl, xl mov yh, xh bigcall Tree_GetNextSibling push xl ; next push xh ; next rcall OBJ_Fini pop xh ; next pop xl ; next rjmp OBJ_Fini_loop OBJ_Fini_loopEnd: pop yh pop yl bigcall Tree_UnlinkObject ; (r16, r17, x) push yl push yh ldi r18, OBJ_SIGNAL_DESTROY clr r19 rcall OBJ_Handler pop yh ; probably no longer usable pointer, pop yl ; especially if using heap! ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_Handler @global ; ; Signal handler for an object. A signal can have up to 3 parameters ; conveyed in registers R20, R21 and X. ; ; @param Y pointer to object SRAM ; @param r18 signal ; @param r19 srcIdForTarget ; @param R20 1st param ; @param R21 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 @global ; ; 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 r18 signal ; @param R20 1st param ; @param R21 2nd param ; @param X 3rd param ; @clobbers any, !r18, !r20, !r21, !Y OBJ_ForwardSignalToChildren: push yl push yh bigcall Tree_GetFirstChildObject ; (none) OBJ_ForwardSignalToChildren_loop: clc mov r17, xl or r17, xh breq OBJ_ForwardSignalToChildren_loopEnd mov yl, xl mov yh, xh push r18 push r20 push r21 push xl push xh push yl push yh clr r19 ; srcId for target set to 0 (this is a direct call to the handler) rcall OBJ_Handler pop yh pop yl pop xh pop xl pop r21 pop r20 pop r18 rcall Tree_GetNextSibling rjmp OBJ_ForwardSignalToChildren_loop OBJ_ForwardSignalToChildren_loopEnd: pop yh pop yl ret ; @end ; --------------------------------------------------------------------------- ; @routine OBJ_EmitSignal @global ; ; @param Y pointer to object SRAM ; @param r18 signal ; @param R20 1st param ; @param R21 2nd param ; @param X 3rd param ; @clobbers any, !Y OBJ_EmitSignal: push yl push yh ldd r16, Y+OBJ_OFFS_TARGET_LO ldd r17, Y+OBJ_OFFS_TARGET_HI ldd r19, Y+OBJ_OFFS_IDFORTARGET mov yl, r16 mov yh, r17 or r16, r17 breq OBJ_EmitSignal_end rcall OBJ_Handler OBJ_EmitSignal_end: pop yh pop yl ret ; @end #endif ; AQH_AVR_WIN_OBJECT_H