; *************************************************************************** ; 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_LAYOUT2_ASM #define AQH_AVR_GUI2_LAYOUT2_ASM ; *************************************************************************** ; defines .equ LAYOUT_CTX_OFFS_TOTALSIZE_LO = 0 .equ LAYOUT_CTX_OFFS_TOTALSIZE_HI = 1 .equ LAYOUT_CTX_OFFS_BORDERS = 2 .equ LAYOUT_CTX_OFFS_SPACING = 3 .equ LAYOUT_CTX_OFFS_NUMITEMS = 4 .equ LAYOUT_CTX_OFFS_ITEMS = 6 .equ LAYOUT_CTX_ITEM_OFFS_POS_LO = 0 .equ LAYOUT_CTX_ITEM_OFFS_POS_HI = 1 .equ LAYOUT_CTX_ITEM_OFFS_SIZE_LO = 2 .equ LAYOUT_CTX_ITEM_OFFS_SIZE_HI = 3 .equ LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO = 4 .equ LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI = 5 .equ LAYOUT_CTX_ITEM_OFFS_FLAGS = 6 .equ LAYOUT_CTX_ITEM_SIZE = 7 ; CAVEAT: change code in LayoutCtx_new if size changed! ; *************************************************************************** ; macros .macro M_LAYOUT_FOREVERY_CONT push yl push yh ldi zl, LOW(@0) ldi zh, HIGH(@0) rcall layoutForEveryObjectContiguous pop yh pop yl .endmacro .macro M_LAYOUT_FOREVERY_SKIPPED push yl push yh ldi zl, LOW(@0) ldi zh, HIGH(@0) rcall layoutForEveryObjectSkipped pop yh pop yl .endmacro ; *************************************************************************** ; code .cseg ; --------------------------------------------------------------------------- ; @routine LayoutCtx_new @global ; ; @param r16 number of entries to reserve ; @return X pointer to new layout context ; @clobbers r16, r17, r18, r19, r24, r25 LayoutCtx_new: push r16 clr r17 mov r24, r16 mov r25, r17 lsl r24 ; x2 rol r25 add r24, r16 adc r25, r17 ; x3 lsl r24 ; x6 rol r25 add r24, r16 adc r25, r17 ; x7 ldi r16, LOW(LAYOUT_CTX_OFFS_ITEMS) ldi r17, HIGH(LAYOUT_CTX_OFFS_ITEMS) add r24, r16 adc r25, r17 ; alloc on heap push r24 push r25 bigcall Heap_Alloc ; (r16, r17, r18, r19, r24, r25) pop r25 pop r24 pop r16 brcc LayoutCtx_new_ret ; preset with 0 push xl push xh clr r17 LayoutCtx_new_loop: st X+, r17 sbiw r25:r24, 1 brne LayoutCtx_new_loop pop xh pop xl adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS st X, r16 ; store number of items sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS sec LayoutCtx_new_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_free @global ; ; @param X pointer to layout context ; @clobbers r16, r17, r24, r25, X LayoutCtx_free: bigjmp Heap_Free ; (r16, r17, r24, r25, X) ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_LayoutExpand ; ; @param X pointer to layout context ; @clobbers r16-r25 LayoutCtx_LayoutExpand: rcall layoutCtxCalcExpandPerExpandableItem ; r17:r16=space to add to expandable items (r16-r25) rcall layoutCtxSetSizeWithExtra ; (r20, r21, r22, r24) rcall LayoutCtxSetPos ; (r16-r25) ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_LayoutSpread ; ; @param X pointer to layout context ; @clobbers r16-r25 LayoutCtx_LayoutSpread: rcall layoutCtxCalcExpandPerExpandableItem ; r17:r16=space to add to expandable items (r16-r25) rcall layoutCtxCalcSpreadValue ; r17:r16=space to add to expandable items and between (r16-r25) push r16 push r17 rcall layoutCtxSetSizeWithExtra ; expand expandable items (r20, r21, r22, r24) pop r17 pop r16 rcall layoutCtxSetPosWithExtra ; (r16-r25) ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_GetMaxDefaultSize ; ; @param X pointer to ctx ; @return r19:r18 maximum default size ; @clobbers r18, r19, r20, r21, r24 LayoutCtx_GetMaxDefaultSize: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item clr r18 clr r19 LayoutCtx_GetMaxDefaultSize_loop: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO ld r20, X+ ld r21, X sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO+1) cp r18, r20 cpc r19, r21 brcc LayoutCtx_GetMaxDefaultSize_next mov r18, r20 mov r19, r21 LayoutCtx_GetMaxDefaultSize_next: adiw xh:xl, LAYOUT_CTX_ITEM_SIZE dec r24 pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_SetFixedSize ; ; @param X pointer to ctx ; @param r19:r18 new size ; @clobbers r24 LayoutCtx_SetFixedSize: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item LayoutCtx_SetFixedSize_loop: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO st X+, r18 st X, r19 adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_SIZE_HI) dec r24 pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxSetSizeWithExtra ; ; Copy default size to size field and add extra space to expandable items. ; ; @param X pointer to layout context ; @param r17:r16 number of bytes to add to expandable items ; @clobbers r20, r21, r22, r24 layoutCtxSetSizeWithExtra: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; number of items (X now points to first item) layoutCtxSetSizeWithExtra_loop: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO ld r20, X+ ld r21, X sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO+1) adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS ld r22, X sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS andi r22, 3 cpi r22, WIDGET_PACK_FILLED brne layoutCtxSetSizeWithExtra_store add r20, r16 ; only add for expandable items adc r21, r17 layoutCtxSetSizeWithExtra_store: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO st X+, r20 st X, r21 adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_SIZE_HI) dec r24 brne layoutCtxSetSizeWithExtra_loop pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtxSetPos ; ; Layout items in their dimension according to their packing flags. ; ; @param X pointer to layout context ; @clobbers r16-r25 LayoutCtxSetPos: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS ld r18, X+ ; borders (start calculated size with one border) clr r19 ld r22, X+ ; spacing clr r23 ld r24, X+ ; number of items (X now points to first item) LayoutCtxSetPos_loop: ; r19:r18=current pos, r22=spacing, r23=border, X=1st item push r18 push r19 rcall layoutCtxPack ; (r16-r21, r25) pop r19 pop r18 adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO ld r20, X+ ld r21, X sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_SIZE_LO+1) add r18, r20 ; add current item size adc r19, r21 add r18, r22 ; add spacing adc r19, r23 adiw xh:xl, LAYOUT_CTX_ITEM_SIZE ; next item dec r24 brne LayoutCtxSetPos_loop pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxSetPosWithExtra ; ; Layout items in their dimension according to their packing flags and also add ; extra space to spacings and borders ; ; @param X pointer to layout context ; @clobbers r16-r25 layoutCtxSetPosWithExtra: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS ld r18, X+ ; borders (start calculated size with one border) clr r19 ld r22, X+ ; spacing clr r23 ld r24, X+ ; number of items (X now points to first item) add r22, r16 ; add extra space to spacing adc r23, r17 add r18, r16 ; add space to border adc r19, r17 layoutCtxSetPosWithExtra_loop: ; r19:r18=current pos, r22=spacing, r23=border, X=1st item push r18 push r19 rcall layoutCtxPack ; (r16-r21, r25) pop r19 pop r18 adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO ld r20, X+ ld r21, X sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_SIZE_LO+1) add r18, r20 ; add current item size adc r19, r21 add r18, r22 ; add spacing adc r19, r23 adiw xh:xl, LAYOUT_CTX_ITEM_SIZE ; next item dec r24 brne layoutCtxSetPosWithExtra_loop pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxPack ; ; @param X pointer to current item ; @param r19:r18 current pos ; @clobbers r16-r21, r25 layoutCtxPack: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO ld r16, X+ ; size lo ld r17, X+ ; size hi ld r20, X+ ; default size lo ld r21, X+ ; default size lo ld r25, X ; flags sbiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS sub r16, r20 ; r17:r16=(size-defaultSize) sbc r17, r21 brcs layoutCtxPack_store andi r25, 3 cpi r25, WIDGET_PACK_END breq layoutCtxPack_end cpi r25, WIDGET_PACK_CENTER breq layoutCtxPack_center cpi r25, WIDGET_PACK_FILLED breq layoutCtxPack_filled rjmp layoutCtxPack_store layoutCtxPack_end: add r18, r16 ; just add difference to pos adc r19, r17 rjmp layoutCtxPack_store layoutCtxPack_center: lsr r17 ror r16 add r18, r16 ; just add half difference to pos adc r19, r17 rjmp layoutCtxPack_store layoutCtxPack_filled: add r16, r20 ; get size back into r17:r16 adc r17, r21 adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_SIZE_LO st X+, r16 ; set item to full size st X, r17 sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_SIZE_LO+1) layoutCtxPack_store: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_POS_LO st X+, r18 st X, r19 sbiw xh:xl, (LAYOUT_CTX_ITEM_OFFS_POS_LO+1) ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxCalcExpandPerExpandableItem ; ; @param X pointer to layout context ; @clobbers r16-r25 layoutCtxCalcExpandPerExpandableItem: rcall LayoutCtx_CountExpandableItems ; r16=num (r17, r24) tst r16 breq layoutCtxCalcExpandPerExpandableItem_none ; no expandable item, nothing to expand push r16 rcall layoutCtxCalcAvailableExtraSpace ; r21:r20=available extra space (r16-r24) pop r16 brcc layoutCtxCalcExpandPerExpandableItem_none ; jmp if no extra space mov r22, r16 clr r23 bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable item rjmp layoutCtxCalcExpandPerExpandableItem_ret layoutCtxCalcExpandPerExpandableItem_none: clr r16 clr r17 layoutCtxCalcExpandPerExpandableItem_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxCalcSpreadValue ; ; @param X pointer to layout context ; @return r17:r16 value to add for borders, spacings and expandable items ; @clobbers r16-r25 layoutCtxCalcSpreadValue: rcall LayoutCtx_CountExpandableItems ; r16=num (r17, r24) adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X sbiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS add r16, r24 inc r16 tst r16 breq layoutCtxCalcSpreadValue_none ; no expandable item, nothing to expand rcall layoutCtxCalcAvailableExtraSpace ; r21:r20=available extra space (r16-r24) brcc layoutCtxCalcExpandPerExpandableItem_none ; jmp if no extra space mov r22, r16 clr r23 bigcall Utils_Divu16_16_16 ; r17:r16=space per expandable item (r25) rjmp layoutCtxCalcSpreadValue_ret layoutCtxCalcSpreadValue_none: clr r16 clr r17 layoutCtxCalcSpreadValue_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxCalcAvailableExtraSpace ; ; @param X pointer to layout context ; @return CFLAG set if there is extra space, cleared otherwise ; @return r21:r20 available extra space ; @clobbers r16-r24 layoutCtxCalcAvailableExtraSpace: rcall LayoutCtx_CalcMinimumSize ; r19:r18=size (r16, r17, r22, r23, r24) adiw xh:xl, LAYOUT_CTX_OFFS_TOTALSIZE_LO ld r20, X+ ld r21, X sbiw xh:xl, (LAYOUT_CTX_OFFS_TOTALSIZE_LO+1) sub r20, r18 sbc r21, r19 ; flip carry flag rol r16 ; rotate CF into r16 com r16 ; flip bit ror r16 ; rotate bit 0 into CF brcs layoutCtxCalcAvailableExtraSpace_ret clr r20 clr r21 clc layoutCtxCalcAvailableExtraSpace_ret: ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_CalcMinimumSize ; ; Calculate minimum size needed for the given items (containing borders and ; spacings) by using the defaultSize fields of the items. ; ; @param X pointer to layout ctx object ; @return r19:r18 calculated size (including borders and spacings) ; @clobbers r16, r17, r22, r23, r24 LayoutCtx_CalcMinimumSize: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_BORDERS ld r18, X+ ; borders (start calculated size with one border) clr r19 ld r22, X+ ; spacing clr r23 ld r24, X+ ; number of items (X now points to first item) lsl r18 ; add border at beginning and end rol r19 LayoutCtx_CalcMinimumSize_loop: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO ld r16, X+ ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO ld r17, X ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI) add r18, r16 ; add size adc r19, r17 add r18, r22 ; add spacing adc r19, r23 dec r24 brne LayoutCtx_CalcMinimumSize_loop sub r18, r22 ; sub last spacing sbc r19, r23 pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_CountExpandableItems ; ; Calculate minimum size needed for the given items (containing borders and ; spacings) by using the defaultSize fields of the items. ; ; @param X pointer to layout ctx object ; @return r16 number of expandable items ; @clobbers r17, r24 LayoutCtx_CountExpandableItems: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; number of items (X now points to first item) clr r16 LayoutCtx_CountExpandableItems_loop: adiw xh:xl, LAYOUT_CTX_ITEM_OFFS_FLAGS ld r17, X adiw xh:xl, (LAYOUT_CTX_ITEM_SIZE-LAYOUT_CTX_ITEM_OFFS_FLAGS) andi r17, 3 cpi r17, WIDGET_PACK_FILLED brne LayoutCtx_CountExpandableItems_next inc r16 LayoutCtx_CountExpandableItems_next: dec r24 brne LayoutCtx_CountExpandableItems_loop pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_ReadXDimsContiguous ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to handle ; @clobbers (r16, r18, r19, r24, Y) LayoutCtx_ReadXDimsContiguous: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyWidgetXToItem ; (r16, r18, r19, r24, Y) pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_ReadXDimsSkipped ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to skip in each round LayoutCtx_ReadXDimsSkipped: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyWidgetXToItem pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_WriteXDimsContiguous ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to handle LayoutCtx_WriteXDimsContiguous: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyItemToWidgetX pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_WriteXDimsSkipped ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to skip in each round LayoutCtx_WriteXDimsSkipped: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyItemToWidgetX pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_ReadYDimsContiguous ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to handle LayoutCtx_ReadYDimsContiguous: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyWidgetYToItem pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_ReadYDimsSkipped ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to skip in each round LayoutCtx_ReadYDimsSkipped: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyWidgetYToItem pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_WriteYDimsContiguous ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to handle LayoutCtx_WriteYDimsContiguous: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_CONT layoutCtxCbCopyItemToWidgetY pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_WriteYDimsSkipped ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to skip in each round LayoutCtx_WriteYDimsSkipped: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbCopyItemToWidgetY pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_SetDefaultWidthContiguous ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to handle LayoutCtx_SetDefaultWidthContiguous: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_CONT layoutCtxCbsetDefaultWidth pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_SetDefaultWidthSkipped ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to skip in each round LayoutCtx_SetDefaultWidthSkipped: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbsetDefaultWidth pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_SetDefaultHeightContiguous ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to handle LayoutCtx_SetDefaultHeightContiguous: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_CONT layoutCtxCbsetDefaultHeight pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine LayoutCtx_SetDefaultHeightSkipped ; ; @param X pointer to ctx ; @param Y pointer to first widget to handle ; @param r25 number of widgets to skip in each round LayoutCtx_SetDefaultHeightSkipped: push xl push xh adiw xh:xl, LAYOUT_CTX_OFFS_NUMITEMS ld r24, X+ ; X now points to first item M_LAYOUT_FOREVERY_SKIPPED layoutCtxCbsetDefaultHeight pop xh pop xl ret ; @end ; --------------------------------------------------------------------------- ; @routine layoutCtxCbCopyWidgetXToItem ; ; @param Y widget ; @param X item ; @param r24 number of items left in layout context (gets decreased) ; @clobbers r16 layoutCtxCbCopyWidgetXToItem: tst r24 sec breq layoutCtxCbCopyWidgetXToItem_ret ldd r16, Y+WIDGET_OFFS_X_LO st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_LO ldd r16, Y+WIDGET_OFFS_X_HI st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_POS_HI ldd r16, Y+WIDGET_OFFS_WIDTH_LO st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_LO ldd r16, Y+WIDGET_OFFS_WIDTH_HI st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_SIZE_HI clr r16 st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_LO st X+, r16 ; LAYOUT_CTX_ITEM_OFFS_DEFAULTSIZE_HI ldd r16, Y+WIDGET_OFFS_PACK andi r16, (1<