avr: started working on prerequisites for a window gui system.

This commit is contained in:
Martin Preuss
2025-05-22 23:19:33 +02:00
parent 7d233136eb
commit fa5acddcbe
5 changed files with 422 additions and 1 deletions

View File

@@ -22,6 +22,8 @@
utils_wait_fixed.asm
utils_wait_pin.asm
watchdog.asm
list.asm
tree.asm
</extradist>
</gwbuild>

166
avr/common/list.asm Normal file
View File

@@ -0,0 +1,166 @@
; ***************************************************************************
; 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_COMMON_LIST_H
#define AQH_AVR_COMMON_LIST_H
; ---------------------------------------------------------------------------
; This code implements a simple single-linked list.
; It assumes that the first 2 bytes of an object managed by this code contain
; a 2 byte pointer to the next object.
; ---------------------------------------------------------------------------
; ***************************************************************************
; defs
.equ LIST_OFFS_NEXT_LO = 0
.equ LIST_OFFS_NEXT_HI = 1
.equ LIST_SIZE = 2
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine List_InitObject @global
;
; Reset list object fields.
; @param Y pointer to object
; @clobbers r16
List_InitObject:
clr r16 ; set this->NEXT to NULL
std Y+LIST_OFFS_NEXT_LO, r16
std Y+LIST_OFFS_NEXT_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine List_GetNextObject @global
; @param Y pointer to object
; @return X pointer to parent object
; @clobbers none
List_GetNextObject:
ldd xl, Y+LIST_OFFS_NEXT_LO
ldd xh, Y+LIST_OFFS_NEXT_HI
ret
; @end
; ---------------------------------------------------------------------------
; @routine List_GetLastObject
; @param X pointer to one object in a list
; @return X pointer to last object which has an empty NEXT pointer
; @clobbers r16, r17, X, Y
List_GetLastObject:
clr yl
clr yh
rjmp List_GetPredecessorFor
; @end
; ---------------------------------------------------------------------------
; @routine List_GetPredecessorFor
; @param Y pointer to this object
; @param X pointer to first object in a list
; @return X pointer to object whose NEXT pointer points to the given object (or NULL)
; @clobbers r16, r17, X
List_GetPredecessorFor:
mov r16, xl
or r16, xh
breq List_GetPredecessorFor_ret
ld r16, X+
ld r17, X+
cp r16, yl
brne List_GetPredecessorFor_next
cp r17, yh
breq List_GetLastObject_haveIt
List_GetPredecessorFor_next:
mov xl, r16
mov xh, r17
rjmp List_GetPredecessorFor
List_GetPredecessorFor_haveIt:
sbiw xh:xl, 1
List_GetPredecessorFor_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine List_AddObject
; @param X pointer to first object in a list
; @param Y pointer to object to add
; @clobbers r16, r17, x
List_AddObject:
push yl
push yh
rcall List_GetLastObject ; (r16, r17, X, Y)
pop yh
pop yl
st X+, yl ; WID_OFFS_WNEXT_LO
st X+, yh ; WID_OFFS_WNEXT_HI
ret
; @end
; ---------------------------------------------------------------------------
; @routine List_UnlinkObject
; @param X pointer to first object in a list
; @param Y pointer to object to remove
; @clobbers r16, r17, x
List_UnlinkObject:
push yl
push yh
rcall List_GetPredecessorFor ; (r16, r17, X)
pop yh
pop yl
mov r16, xl
or r16, xh
breq List_UnlinkObject_ret
ldd r16, Y+LIST_OFFS_NEXT_LO ; get this->NEXT
ldd r17, Y+LIST_OFFS_NEXT_HI
st X+, r16 ; store as NEXT in predecessor
st X, r17
clr r16 ; set this->NEXT to NULL
std Y+LIST_OFFS_NEXT_LO, r16
std Y+LIST_OFFS_NEXT_HI, r16
List_UnlinkObject_ret:
ret
; @end
#endif ; AQH_AVR_COMMON_LIST_H

192
avr/common/tree.asm Normal file
View File

@@ -0,0 +1,192 @@
; ***************************************************************************
; 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_COMMON_TREE_H
#define AQH_AVR_COMMON_TREE_H
; ***************************************************************************
; defs
.equ TREE_OFFS_LIST = 0
.equ TREE_OFFS_WPARENT_LO = TREE_OFFS_LIST+LIST_SIZE
.equ TREE_OFFS_WPARENT_HI = TREE_OFFS_LIST+LIST_SIZE+1
.equ TREE_OFFS_WCHILD_LO = TREE_OFFS_LIST+LIST_SIZE+2
.equ TREE_OFFS_WCHILD_HI = TREE_OFFS_LIST+LIST_SIZE+3
.equ TREE_SIZE = TREE_OFFS_LIST+LIST_SIZE+4
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine Tree_InitObject @global
; @param Y pointer to object to add
; @clobbers r16
Tree_InitObject:
rcall List_InitObject ; (R16)
clr r16 ; clear this->TREE data
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_LO, r16
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_HI, r16
std Y+TREE_OFFS_LIST+TREE_OFFS_WCHILD_LO, r16
std Y+TREE_OFFS_LIST+TREE_OFFS_WCHILD_HI, r16
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tree_GetParentObject @global
; @param Y pointer to object
; @return X pointer to parent object
; @clobbers none
Tree_GetParentObject:
ldd xl, Y+TREE_OFFS_WPARENT_LO
ldd xh, Y+TREE_OFFS_WPARENT_HI
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tree_GetFirstChildObject @global
; @param Y pointer to object
; @return X pointer to first child object
; @clobbers none
Tree_GetFirstChildObject:
ldd xl, Y+TREE_OFFS_WCHILD_LO
ldd xh, Y+TREE_OFFS_WCHILD_HI
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tree_GetObjectBelow @global
; @param Y pointer to object
; @return X pointer to object below (or NULL)
; @clobbers r16
Tree_GetObjectBelow:
push yl
push yh
rcall treeGetObjectBelow
pop yh
pop yl
ret
treeGetObjectBelow:
rcall Tree_GetFirstChildObject
mov r16, xl
or r16, xh
brne treeGetObjectBelow_ret ; got one
rcall List_GetNextObject
mov r16, xl
or r16, xh
brne treeGetObjectBelow_ret ; got one
rcall Tree_GetParentObject
mov r16, xl
or r16, xh
breq treeGetObjectBelow_ret ; no parent
mov yl, xl
mov yh, xh
rjmp treeGetObjectBelow ; try with parent
treeGetObjectBelow_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine Tree_AddChildObject @global
; @param X pointer to parent to add to
; @param Y pointer to object to add
; @clobbers r16, r17, r18, x
Tree_AddChildObject:
std Y+TREE_OFFS_WPARENT_LO, xl ; immediately store parent pointer
std Y+TREE_OFFS_WPARENT_HI, xh
adiw xh:xl, TREE_OFFS_WCHILD_LO
ld r16, X+
ld r17, X
mov r18, r16
or r18, r17
brne Tree_AddChildObject_addToChildList
st X, yh ; no child, set THIS as first
st -X, yl
sbiw xh:xl, WID_OFFS_TREE+TREE_OFFS_WCHILD_LO
ret
Tree_AddChildObject_addToChildList:
mov xl, r16
mov xh, r17
rjmp List_AddObject
; @end
; ---------------------------------------------------------------------------
; @routine Tree_UnlinkObject @global
; @param Y pointer to object to remove
; @clobbers r16, r17, x
Tree_UnlinkObject:
ldd xl, Y+TREE_OFFS_WPARENT_LO
ldd xh, Y+TREE_OFFS_WPARENT_HI
mov r16, xl
or r16, xh
breq Tree_UnlinkObject_ret ; not part of a tree
adiw xh:xl, TREE_OFFS_WCHILD_LO ; get parent's first child to R17:R16
ld r16, X+
ld r17, X
cp r16, yl ; same as THIS?
brne Tree_UnlinkObject_inList ; nope, need to check childList
cp r17, yh
brne Tree_UnlinkObject_inList ; nope, need to check childList
ldd r16, Y+TREE_OFFS_LIST+LIST_OFFS_NEXT_HI ; is first child, set this->NEXT as new first child
st X, r16
ldd r16, Y+TREE_OFFS_LIST+LIST_OFFS_NEXT_LO
st -X, r16
rjmp Tree_UnlinkObject_clrParentAndSibling
Tree_UnlinkObject_inList:
mov xl, r16
mov xh, r17
rcall List_UnlinkObject ; (R16, R17, X)
Tree_UnlinkObject_clrParentAndSibling:
clr r16 ; clear this->PARENT
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_LO, r16
std Y+TREE_OFFS_LIST+TREE_OFFS_WPARENT_HI, r16
std Y+LIST_OFFS_NEXT_LO, r16
std Y+LIST_OFFS_NEXT_HI, r16 ; clear this->NEXT
Tree_UnlinkObject_ret:
ret
; @end
#endif ; AQH_AVR_COMMON_TREE_H

View File

@@ -334,4 +334,3 @@ ili9341BitBlitStretchNWriteLine_loop2:

View File

@@ -0,0 +1,62 @@
; ***************************************************************************
; 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_H
#define AQH_AVR_WIN_H
; tree/list info
.equ WID_OFFS_TREE = 0
; signal handler
.equ WID_OFFS_HANDLERFN_LO = WID_OFFS_TREE+TREE_SIZE
.equ WID_OFFS_HANDLERFN_HI = WID_OFFS_HANDLERFN_LO+1
; widget description
.equ WID_OFFS_WIDGET_INFO = WID_OFFS_HANDLERFN_HI+1
.equ WID_OFFS_OPTIONS1 = WID_OFFS_WIDGET_INFO+0
.equ WID_OFFS_OPTIONS2 = WID_OFFS_WIDGET_INFO+1
.equ WID_OFFS_ABS_X_LO = WID_OFFS_WIDGET_INFO+2
.equ WID_OFFS_ABS_X_HI = WID_OFFS_WIDGET_INFO+3
.equ WID_OFFS_ABS_Y_LO = WID_OFFS_WIDGET_INFO+4
.equ WID_OFFS_ABS_Y_HI = WID_OFFS_WIDGET_INFO+5
.equ WID_OFFS_REL_X_LO = WID_OFFS_WIDGET_INFO+6
.equ WID_OFFS_REL_X_HI = WID_OFFS_WIDGET_INFO+7
.equ WID_OFFS_REL_Y_LO = WID_OFFS_WIDGET_INFO+8
.equ WID_OFFS_REL_Y_HI = WID_OFFS_WIDGET_INFO+9
.equ WID_OFFS_WIDTH_LO = WID_OFFS_WIDGET_INFO+10
.equ WID_OFFS_WIDTH_HI = WID_OFFS_WIDGET_INFO+11
.equ WID_OFFS_HEIGHT_LO = WID_OFFS_WIDGET_INFO+12
.equ WID_OFFS_HEIGHT_HI = WID_OFFS_WIDGET_INFO+13
.equ WID_OFFS_BG_COL_LO = WID_OFFS_WIDGET_INFO+14
.equ WID_OFFS_BG_COL_HI = WID_OFFS_WIDGET_INFO+15
.equ WID_OFFS_FG_COL_LO = WID_OFFS_WIDGET_INFO+16
.equ WID_OFFS_FG_COL_HI = WID_OFFS_WIDGET_INFO+17
.equ WID_OFFS_FONT_LO = WID_OFFS_WIDGET_INFO+18
.equ WID_OFFS_FONT_HI = WID_OFFS_WIDGET_INFO+19
.equ WID_SIZE = WID_OFFS_WIDGET_INFO+20
.equ WID_OPTIONS1_BIT_DIRTY = 0
.equ WID_OPTIONS1_BIT_LAYOUT = 1
.equ WID_OPTIONS1_BIT_STRETCH_X = 2
.equ WID_OPTIONS1_BIT_STRETCH_Y = 3
.equ WID_OPTIONS1_BIT_ALIGN_LEFT = 4
.equ WID_OPTIONS1_BIT_ALIGN_RIGHT = 5
.equ WID_OPTIONS1_BIT_ALIGN_TOP = 6
.equ WID_OPTIONS1_BIT_ALIGN_BOTTOM = 7
#endif ; AQH_AVR_WIN_H