; *************************************************************************** ; 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_GUIAPP_ASM #define AQH_AVR_GUI2_GUIAPP_ASM ; *************************************************************************** ; defines ; GuiApp in flash .equ GUIAPP_OFFS_GUIAPP = OBJECT_SIZE .equ GUIAPP_OFFS_SDRAM_LO = GUIAPP_OFFS_GUIAPP+0 .equ GUIAPP_OFFS_SDRAM_HI = GUIAPP_OFFS_GUIAPP+1 .equ GUIAPP_OFFS_ROOTWIDGET_LO = GUIAPP_OFFS_GUIAPP+2 .equ GUIAPP_OFFS_ROOTWIDGET_HI = GUIAPP_OFFS_GUIAPP+3 .equ GUIAPP_OFFS_SCREENSAVER_LO = GUIAPP_OFFS_GUIAPP+4 .equ GUIAPP_OFFS_SCREENSAVER_HI = GUIAPP_OFFS_GUIAPP+5 .equ GUIAPP_SIZE = GUIAPP_OFFS_GUIAPP+6 ; signals .equ GUIAPP_SIGNAL_RAISE = OBJECT_SIGNAL_NEXTFREE+0 ; app->cntrl: X=WIDGET to raise .equ GUIAPP_SIGNAL_SHOW = OBJECT_SIGNAL_NEXTFREE+1 ; cntrl->app .equ GUIAPP_SIGNAL_HIDE = OBJECT_SIGNAL_NEXTFREE+2 ; cntrl->app .equ GUIAPP_SIGNAL_DEBUG = OBJECT_SIGNAL_NEXTFREE+3 .equ GUIAPP_SIGNAL_NEXTFREE = OBJECT_SIGNAL_NEXTFREE+4 ; SDRAM data for guiapp .equ GUIAPP_SD_OFFS_FLAGS = 0 .equ GUIAPP_SD_OFFS_DRAWTIMER = 1 .equ GUIAPP_SD_OFFS_CURRENTWIDGET_LO = 2 .equ GUIAPP_SD_OFFS_CURRENTWIDGET_HI = 3 .equ GUIAPP_SD_OFFS_TOUCHWIDGET_LO = 4 .equ GUIAPP_SD_OFFS_TOUCHWIDGET_HI = 5 .equ GUIAPP_SD_SIZE = 6 .equ GUIAPP_DRAWTIMER = 2 ; *************************************************************************** ; data .dseg guiapp_touch_event: .byte WIDGET_DATA_TOUCH_SIZE ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine GuiApp_Init ; ; @param Z byte address of guiapp object (for LPM!) GuiApp_Init: ldi r16, OBJECT_SIGNAL_CREATE clr r17 bigcall OBJ_HandleSignal rcall GuiApp_ShowFirstView ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_Every100ms @global ; ; @param Z byte address of guiapp object (for LPM!) GuiApp_Every100ms: ldi r16, OBJECT_SIGNAL_TIMER clr r17 bigcall OBJ_HandleSignal ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_MsgReceived @global ; ; @param Z byte address of guiapp object (for LPM!) GuiApp_MsgReceived: ldi r16, OBJECT_SIGNAL_RECVMSG clr r17 bigcall OBJ_HandleSignal ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_OnTimer ; ; @param Z byte address of guiapp object (for LPM!) GuiApp_OnTimer: ; check for touch event rcall guiAppCheckTouch ; send timer signal to all accepting widgets push zl push zh adiw zh:zl, GUIAPP_OFFS_ROOTWIDGET_LO lpm r16, Z+ lpm zh, Z mov zl, r16 or r17, zh breq GuiApp_OnTimer_l1 bigcall Widget_Tree_SendTimerSignal GuiApp_OnTimer_l1: pop zh pop zl ; possibly draw widgets rcall GuiApp_GetSdramPtr ldd r16, Y+GUIAPP_SD_OFFS_DRAWTIMER tst r16 breq GuiApp_OnTimer_ret dec r16 brne GuiApp_OnTimer_writeDrawTimer push yl push yh rcall guiAppDrawWidgets pop yh pop yl ldi r16, GUIAPP_DRAWTIMER GuiApp_OnTimer_writeDrawTimer: std Y+GUIAPP_SD_OFFS_DRAWTIMER, r16 GuiApp_OnTimer_ret: sec ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_OnTouch ; ; @param Z byte address of guiapp object (for LPM!) ; @param X pointer to touch event in SDRAM GuiApp_OnTouch: push zl push zh rcall GuiApp_GetSdramPtr ldd r18, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO ldd r19, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI mov r16, r18 or r16, r19 breq GuiApp_OnTouch_sendToAll mov zl, r18 mov zh, r19 ldi r16, WIDGET_SIGNAL_TOUCH clr r17 bigcall OBJ_HandleSignal rjmp GuiApp_OnTouch_done GuiApp_OnTouch_sendToAll: rcall GuiApp_GetRootWidgetToZ brcc GuiApp_OnTouch_done ; send touch signal bigcall Widget_Tree_SendTouchSignal GuiApp_OnTouch_done: pop zh pop zl ; send keepAlive to screensaver (if not active!) rcall guiAppSendKeepAliveIfScreenSaverInactive sec ret ; @end ; --------------------------------------------------------------------------- ; @routine guiAppSendKeepAliveIfScreenSaverInactive ; ; @param Z byte address of guiapp object (for LPM!) ; @clobbers any guiAppSendKeepAliveIfScreenSaverInactive: push zl push zh rcall GuiApp_GetSdramPtr adiw zh:zl, GUIAPP_OFFS_SCREENSAVER_LO lpm r20, Z+ lpm r21, Z sbiw zh:zl, GUIAPP_OFFS_SCREENSAVER_LO+1 ldd r16, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO cp r16, r20 brne guiAppSendKeepAliveIfScreenSaverInactive_send ldd r16, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI cp r16, r21 breq guiAppSendKeepAliveIfScreenSaverInactive_end guiAppSendKeepAliveIfScreenSaverInactive_send: mov zl, r20 mov zh, r21 bigcall ScreenSaver_KeepAlive guiAppSendKeepAliveIfScreenSaverInactive_end: pop zh pop zl ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_OnMsgReceived @global ; ; @param Z byte address of guiapp object (for LPM!) ; @param X pointer to message received in SDRAM GuiApp_OnMsgReceived: push zl push zh rcall GuiApp_GetRootWidgetToZ brcc GuiApp_OnMsgReceived_done bigcall Widget_Tree_SendMsgRecvSignal GuiApp_OnMsgReceived_done: pop zh pop zl sec ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_OnCreate @global ; ; @param Z byte address of object (for LPM!) ; @return CFLAG set if signal handled ; @clobbers any, !Z GuiApp_OnCreate: ; init sdram data rcall GuiApp_GetSdramPtr ldi r17, GUIAPP_SD_SIZE clr r16 push yl push yh GuiApp_OnCreate_loop: st Y+, r16 dec r17 brne GuiApp_OnCreate_loop pop yh pop yl clr r16 std Y+GUIAPP_SD_OFFS_FLAGS, r16 ldi r16, GUIAPP_DRAWTIMER std Y+GUIAPP_SD_OFFS_DRAWTIMER, r16 rcall guiAppInitWidgets sec ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_GetSdramPtr @global ; ; @param Z byte address of object (for LPM!) ; @return Y pointer to SDRAM data for widget ; @clobbers none GuiApp_GetSdramPtr: adiw zh:zl, GUIAPP_OFFS_SDRAM_LO lpm yl, Z+ lpm yh, Z sbiw zh:zl, GUIAPP_OFFS_SDRAM_LO+1 ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_GetRootWidgetToZ @global ; ; @param Z byte address of object (for LPM!) ; @return CFLAG set if there is a root widget, cleared otherwise ; @return Z byte address pointer to root widget (for LPM!), if CFLAG set, garbage otherwise ; @clobbers none GuiApp_GetRootWidgetToZ: rcall OBJ_IsObject brcc GuiApp_GetRootWidgetToZ_ret adiw zh:zl, GUIAPP_OFFS_ROOTWIDGET_LO lpm r16, Z+ lpm zh, Z mov zl, r16 rcall OBJ_IsObject GuiApp_GetRootWidgetToZ_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_ShowFirstView @global ; ; @param Z byte address of guiapp object (for LPM!) GuiApp_ShowFirstView: push zl push zh rcall GuiApp_GetRootWidgetToZ brcc GuiApp_ShowFirstView_error bigcall OBJ_GetFirstChild brcc GuiApp_ShowFirstView_error mov xl, r18 mov xh, r19 pop zh pop zl rcall GuiApp_ShowView rjmp GuiApp_ShowFirstView_ret GuiApp_ShowFirstView_error: pop zh pop zl GuiApp_ShowFirstView_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_ShowView @global ; ; @param Z byte address of object (for LPM!) ; @param X byte address of object to show (for LPM!) ; @return CFLAG set if signal handled ; @clobbers any, !Z GuiApp_ShowView: rcall GuiApp_GetSdramPtr ; Y=SDRAM ldd r18, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO ldd r19, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI eor r18, xl ; 0 if same eor r19, xh ; 0 if same or r18, r19 ; 0 if r19:r18==X breq GuiApp_ShowView_ret ; same, no change push yl push yh rcall guiAppHideCurrent ; (any, !X, !Z) pop yh pop yl ; store new view std Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO, xl std Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI, xh ; show new (if any) rcall guiAppShowCurrent GuiApp_ShowView_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_GetCurrentView @global ; ; @param Z byte address of object (for LPM!) ; @return X byte address of current view object (for LPM!) ; @clobbers Y GuiApp_GetCurrentView: rcall GuiApp_GetSdramPtr ; Y=SDRAM ldd xl, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO ldd xh, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_GrabTouchEvents ; ; @param Z byte address of gui app object (for LPM!) ; @param X byte address of widget grabbing touch events ; @return CFLAG set if grabbed, cleared otherwise ; @clobbers R16, R17, Y GuiApp_GrabTouchEvents: rcall OBJ_IsObject ; (none) brcc GuiApp_GrabTouchEvents_ret rcall GuiApp_GetSdramPtr ; (none) ldd r16, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO ldd r17, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI or r16, r17 clc brne GuiApp_GrabTouchEvents_ret ; only grab if not already grabbed! std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO, xl std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI, xh sec GuiApp_GrabTouchEvents_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine GuiApp_UngrabTouchEvents ; ; @param Z byte address of gui app object (for LPM!) ; @param X byte address of widget ungrabbing touch events ; @return CFLAG set if ungrabbed, cleared otherwise ; @clobbers R16, R17 GuiApp_UngrabTouchEvents: rcall OBJ_IsObject ; (none) brcc GuiApp_UngrabTouchEvents_ret rcall GuiApp_GetSdramPtr ; (none) ldd r16, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO ldd r17, Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI eor r16, xl eor r17, xh or r16, r17 clc brne GuiApp_UngrabTouchEvents_ret ; only ungrab same widget! clr r16 std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_LO, r16 std Y+GUIAPP_SD_OFFS_TOUCHWIDGET_HI, r16 sec GuiApp_UngrabTouchEvents_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine guiAppHideCurrent ; ; @param Z byte address of gui app object (for LPM!) ; @clobbers any, !X, !Z guiAppHideCurrent: push zl push zh rcall GuiApp_GetSdramPtr ; Y=SDRAM ldd zl, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_LO ldd zh, Y+GUIAPP_SD_OFFS_CURRENTWIDGET_HI mov r16, zl or r16, zh breq guiAppHideCurrent_done ldi r16, WIDGET_SIGNAL_HIDE clr r17 bigcall OBJ_HandleSignal ; (any, !X, !Y. !Z) ldi r16, (1<