avr: work on simple GUI module to be used by node c02.

This commit is contained in:
Martin Preuss
2025-11-03 17:23:40 +01:00
parent b4fee78ad8
commit e58e9b846c
38 changed files with 1951 additions and 2422 deletions

View File

@@ -7,6 +7,9 @@
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
#ifndef AQH_AVR_WIN_OBJECT_H
#define AQH_AVR_WIN_OBJECT_H
.cseg
@@ -15,20 +18,24 @@
; ---------------------------------------------------------------------------
; @routine OBJ_Init @global
;
; @param Y pointer to object SRAM
; @param r17 options
; @clobbers X
; 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:
push r17
mov xl, yl
mov xh, yh
clr r16
ldi r17, OBJ_OFFS_SIZE
bigcall Utils_FillSram ; (R17, X)
bigcall Tree_InitObject ; (R16)
pop r17
std Y+OBJ_OFFS_OPTIONS, r17
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)
@@ -38,12 +45,28 @@ OBJ_Init:
; ---------------------------------------------------------------------------
; @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 X
; @clobbers none
OBJ_SetHandler:
std Y+OBJ_OFFS_HANDLERFN_LO, zl
@@ -68,55 +91,20 @@ OBJ_GetHandler:
OBJ_DefaultHandler:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_free @global
; @routine OBJ_DefaultHandler @global
;
; @param Y pointer to object in SRAM
; 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_free:
; free children
push yl
push yh
rcall Tree_GetFirstChildObject ; (none)
OBJ_free_loop:
mov r16, xl
or r16, xh
breq OBJ_free_loopEnd
mov yl, xl
mov yh, xh
rcall Tree_GetNextSibling
push xl ; next
push xh ; next
rcall OBJ_free
pop xh ; next
pop xl ; next
rjmp OBJ_free_loop
OBJ_free_loopEnd:
pop yh
pop yl
rcall Tree_UnlinkObject ; (r16, r17, x)
push yl
push yh
ldi r16, OBJ_SIGNAL_DESTROY
rcall OBJ_Handler
pop yh
pop yl
rcall objFreeLinks
rcall objFreeTimers
mov xl, yl
mov xh, yh
rcall Heap_free
OBJ_DefaultHandler:
clc
ret
; @end
@@ -124,15 +112,62 @@ OBJ_free_loopEnd:
; ---------------------------------------------------------------------------
; @routine OBJ_Handler
; @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 R18, R19 and X.
; conveyed in registers R20, R21 and X.
;
; @param Y pointer to object SRAM
; @param r16 signal
; @param R18 1st param
; @param R19 2nd param
; @param r18 signal
; @param r19 srcIdForTarget
; @param R20 1st param
; @param R21 2nd param
; @param X 3rd param
OBJ_Handler:
@@ -146,22 +181,22 @@ OBJ_Handler:
; ---------------------------------------------------------------------------
; @routine OBJ_ForwardSignalToChildren
; @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 r16 signal
; @param R18 1st param
; @param R19 2nd param
; @param r18 signal
; @param R20 1st param
; @param R21 2nd param
; @param X 3rd param
; @clobbers any, !r16, !r18, !r19, !Y
; @clobbers any, !r18, !r20, !r21, !Y
OBJ_ForwardSignalToChildren:
push yl
push yh
rcall Tree_GetFirstChildObject ; (none)
bigcall Tree_GetFirstChildObject ; (none)
OBJ_ForwardSignalToChildren_loop:
clc
mov r17, xl
@@ -169,21 +204,22 @@ OBJ_ForwardSignalToChildren_loop:
breq OBJ_ForwardSignalToChildren_loopEnd
mov yl, xl
mov yh, xh
push r16
push r18
push r19
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 r19
pop r18
pop r16
pop r21
pop r20
pop r18
rcall Tree_GetNextSibling
rjmp OBJ_ForwardSignalToChildren_loop
OBJ_ForwardSignalToChildren_loopEnd:
@@ -195,246 +231,27 @@ OBJ_ForwardSignalToChildren_loopEnd:
; ---------------------------------------------------------------------------
; @routine OBJ_EmitSignal
; @routine OBJ_EmitSignal @global
;
; @param Y pointer to object SRAM
; @param r16 signal to emit
; @param R18 1st param
; @param R19 2nd param
; @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 r17, Y+OBJ_OFFS_LINKS_LO
ldd yh, Y+OBJ_OFFS_LINKS_HI
mov yl, r17
OBJ_EmitSignal_loop:
push r16
rcall objCheckEmitSignalForLink ; (any, !X, !Y, !R18, !R19)
pop r16
push xl
push xh
rcall List_GetNextObject ; (none)
mov yl, xl
mov yh, xh
pop xh
pop xl
mov r17, yl
or r17, yh
brne OBJ_EmitSignal_loop
OBJ_EmitSignal_popRet:
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_AddLink @global
;
; @param Y pointer to object SRAM
; @param X pointer to link
; @clobbers R16, R17
OBJ_AddLink:
ldd r16, Y+OBJ_OFFS_LINKS_LO
ldd r17, Y+OBJ_OFFS_LINKS_HI
tst r16
brne OBJ_AddLink_addToExisting
tst r17
brne OBJ_AddLink_addToExisting
; empty list, new link is first
std Y+OBJ_OFFS_LINKS_LO, xl
std Y+OBJ_OFFS_LINKS_HI, xh
rjmp OBJ_AddLink_end
OBJ_AddLink_addToExisting:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, xh
mov xl, r16
mov xh, r17
rcall List_AddObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_AddLink_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_RemoveLink @global
;
; @param Y pointer to object SRAM
; @param X pointer to link
; @clobbers R16, R17
OBJ_RemoveLink:
ldd r16, Y+OBJ_OFFS_LINKS_LO
ldd r17, Y+OBJ_OFFS_LINKS_HI
cp r16, xl
brne OBJ_RemoveLink_notFirst
cp r17, xh
brne OBJ_RemoveLink_notFirst
clr r16
std Y+OBJ_OFFS_LINKS_LO, r16
std Y+OBJ_OFFS_LINKS_HI, r16
rjmp OBJ_RemoveLink_end
OBJ_RemoveLink_notFirst:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, r17
mov xl, r16
mov xh, r17
rcall List_UnlinkObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_RemoveLink_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_AddTimer @global
;
; @param Y pointer to object SRAM
; @param X pointer to timer
; @clobbers R16, R17
OBJ_AddTimer:
ldd r16, Y+OBJ_OFFS_TIMERS_LO
ldd r17, Y+OBJ_OFFS_TIMERS_HI
tst r16
brne OBJ_AddTimer_addToExisting
tst r17
brne OBJ_AddTimer_addToExisting
; empty list, new timer is first
std Y+OBJ_OFFS_TIMERS_LO, xl
std Y+OBJ_OFFS_TIMERS_HI, xh
rjmp OBJ_AddTimer_end
OBJ_AddTimer_addToExisting:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, xh
mov xl, r16
mov xh, r17
rcall List_AddObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_AddTimer_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_RemoveTimer @global
;
; @param Y pointer to object SRAM
; @param X pointer to timer
; @clobbers R16, R17
OBJ_RemoveTimer:
ldd r16, Y+OBJ_OFFS_TIMERS_LO
ldd r17, Y+OBJ_OFFS_TIMERS_HI
cp r16, xl
brne OBJ_RemoveTimer_notFirst
cp r17, xh
brne OBJ_RemoveTimer_notFirst
clr r16
std Y+OBJ_OFFS_TIMERS_LO, r16
std Y+OBJ_OFFS_TIMERS_HI, r16
rjmp OBJ_RemoveTimer_end
OBJ_RemoveTimer_notFirst:
push xl
push xh
push yl
push yh
mov yl, xl
mov yh, r17
mov xl, r16
mov xh, r17
rcall List_UnlinkObject ; (r16, r17, x)
pop yh
pop yl
pop xh
pop xl
OBJ_RemoveTimer_end:
ret
; @end
; ---------------------------------------------------------------------------
; @param r16 signal
; @param Y link
; @clobbers any, !X, !Y, !R18, !R19
objCheckEmitSignalForLink:
ldd r17, Y+OBJ_LINK_OFFS_SIGNAL
cp r16, r17
brne objCheckEmitSignalForLink_ret
push yl
push yh
push xl
push xh
push r18
push r19
ldd r16, Y+OBJ_LINK_OFFS_SLOT
ldd r17, Y+OBJ_LINK_OFFS_TARGET_LO
ldd yh, Y+OBJ_LINK_OFFS_TARGET_HI
mov yl, r17
rcall OBJ_Handler
pop r19
pop r18
pop xh
pop xl
pop yh
pop yl
objCheckEmitSignalForLink_ret:
ret
; @end
; ---------------------------------------------------------------------------
; @routine objFreeLinks
;
; @clobbers r16, r17, r18, r19, r24, r25, X
objFreeLinks:
push yl
push yh
ldd r16, Y+OBJ_OFFS_LINKS_LO
ldd r17, Y+OBJ_OFFS_LINKS_HI
clr r18
std Y+OBJ_OFFS_LINKS_LO, r18
std Y+OBJ_OFFS_LINKS_HI, r18
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
ldi zl, LOW(Obj_Link_free)
ldi zh, HIGH(Obj_Link_free)
rcall List_ForEveryObject ; (r16, r17, r18, r19, r24, r25, X, Y)
or r16, r17
breq OBJ_EmitSignal_end
rcall OBJ_Handler
OBJ_EmitSignal_end:
pop yh
pop yl
ret
@@ -442,115 +259,5 @@ objFreeLinks:
; ---------------------------------------------------------------------------
; @routine objFreeTimers
;
; @clobbers r16, r17, r18, r19, r24, r25, X
objFreeTimers:
push yl
push yh
ldd r16, Y+OBJ_OFFS_TIMERS_LO
ldd r17, Y+OBJ_OFFS_TIMERS_HI
clr r18
std Y+OBJ_OFFS_TIMERS_LO, r18
std Y+OBJ_OFFS_TIMERS_HI, r18
mov yl, r16
mov yh, r17
ldi zl, LOW(Obj_Timer_free)
ldi zh, HIGH(Obj_Timer_free)
rcall List_ForEveryObject ; (r16, r17, r18, r19, r24, r25, X, Y)
pop yh
pop yl
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Link_new @global
;
; @return CF set if okay, cleared on error
; @return Y pointer to SRAM for link
; @clobbers r16, r17, X
OBJ_Link_new:
ldi r24, LOW(OBJ_LINK_SIZE)
ldi r25, HIGH(OBJ_LINK_SIZE)
bigcall Heap_Alloc
brcc OBJ_Link_new_end
mov yl, xl
mov yh, xh
clr r16
ldi r17, OBJ_LINK_SIZE
bigcall Utils_FillSram ; (R17, X)
rcall List_InitObject ; (R16)
sec
OBJ_Link_new_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Link_free @global
;
; @param Y pointer to SRAM for link
; @clobbers r16, r17, r24, r25, X
OBJ_Link_free:
rcall List_FiniObject ; (R16)
mov xl, yl
mov xh, yh
rcall Heap_free ; (r16, r17, r24, r25, X)
clc
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Timer_new @global
;
; @return CF set if okay, cleared on error
; @return Y pointer to SRAM for timer
; @clobbers r16, r17, X
OBJ_Timer_new:
ldi r24, LOW(TIMER_SIZE)
ldi r25, HIGH(TIMER_SIZE)
bigcall Heap_Alloc
brcc OBJ_Timer_new_end
mov yl, xl
mov yh, xh
clr r16
ldi r17, TIMER_SIZE
bigcall Utils_FillSram ; (R17, X)
rcall List_InitObject ; (R16)
sec
OBJ_Timer_new_end:
ret
; @end
; ---------------------------------------------------------------------------
; @routine OBJ_Timer_free @global
;
; @param Y pointer to SRAM for timer
; @clobbers r16, r17, r24, r25, X
OBJ_Timer_free:
rcall List_FiniObject ; (R16)
mov xl, yl
mov xh, yh
bigcall Heap_free ; (r16, r17, r24, r25, X)
clc
ret
; @end
#endif ; AQH_AVR_WIN_OBJECT_H