559 lines
13 KiB
NASM
559 lines
13 KiB
NASM
; ***************************************************************************
|
|
; 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_GUI_WINDOW_ASM
|
|
#define AQH_AVR_GUI_WINDOW_ASM
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_Init @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @clobbers R16, R17, X
|
|
|
|
Window_Init:
|
|
mov xl, yl
|
|
mov xh, yh
|
|
ldi r17, WIN_SIZE
|
|
clr r16
|
|
bigcall Utils_FillSram ; (R17, X)
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_Clear @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @clobbers any, !Y
|
|
|
|
Window_Clear:
|
|
ldd r2, Y+WIN_OFFS_BG_COL_LO ; background color low
|
|
ldd r3, Y+WIN_OFFS_BG_COL_HI ; background color high
|
|
ldd r4, Y+WIN_OFFS_X_LO ; X low
|
|
ldd r5, Y+WIN_OFFS_X_HI ; X high
|
|
ldd r6, Y+WIN_OFFS_Y_LO ; Y low
|
|
ldd r7, Y+WIN_OFFS_Y_HI ; Y high
|
|
ldd r8, Y+WIN_OFFS_WIDTH_LO ; width low
|
|
ldd r9, Y+WIN_OFFS_WIDTH_HI ; width high
|
|
ldd r10, Y+WIN_OFFS_HEIGHT_LO ; height low
|
|
ldd r11, Y+WIN_OFFS_HEIGHT_HI ; height high
|
|
bigcall Display_FillRect
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_FillRect @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param r3:r2 color
|
|
; @param r5:r4 X0
|
|
; @param r7:r6 Y0
|
|
; @param r9:r8 X1/W
|
|
; @param r11:r10 Y1/H
|
|
; @clobbers any, !Y
|
|
|
|
Window_FillRect:
|
|
ldd r16, Y+WIN_OFFS_X_LO ; make absolute coords
|
|
ldd r17, Y+WIN_OFFS_X_HI
|
|
add r4, r16
|
|
adc r5, r17
|
|
ldd r16, Y+WIN_OFFS_Y_LO
|
|
ldd r17, Y+WIN_OFFS_Y_HI
|
|
add r6, r16
|
|
adc r7, r17
|
|
bigcall Display_FillRect ; directly call graphics function
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_IsPointInRect @global
|
|
;
|
|
; @param Z pointer WINRECT object in FLASH (see @ref WINRECT_OFFS_X_LO)
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @clobbers r16, r17, r18, r19, r20, r21, Z
|
|
|
|
Window_IsPointInRect:
|
|
; check X
|
|
lpm r16, Z+ ; X
|
|
lpm r17, Z+
|
|
mov r18, r4 ; X
|
|
mov r19, r5
|
|
sub r18, r16
|
|
sbc r19, r17 ; r19:r18=X pos relative to rectangle
|
|
brcs Window_IsPointInRect_clcRet
|
|
; check Y
|
|
lpm r16, Z+ ; Y
|
|
lpm r17, Z+
|
|
mov r20, r6 ; Y
|
|
mov r21, r7
|
|
sub r20, r16
|
|
sbc r21, r17 ; r21:r20=Y pos relative to rectangle
|
|
brcs Window_IsPointInRect_clcRet
|
|
; check width
|
|
lpm r16, Z+ ; width
|
|
lpm r17, Z+
|
|
cp r18, r16 ; width > rel X?
|
|
cpc r19, r17
|
|
brcc Window_IsPointInRect_ret
|
|
; check height
|
|
lpm r16, Z+ ; height
|
|
lpm r17, Z+
|
|
cp r20, r16 ; height > rel Y?
|
|
cpc r21, r17
|
|
rjmp Window_IsPointInRect_ret ; CF set if inside rect
|
|
Window_IsPointInRect_clcRet:
|
|
clc
|
|
Window_IsPointInRect_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_DrawTextFlash @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return R5:R4 X pos behind string
|
|
|
|
; @clobbers any, !Y, !R6, !R7
|
|
|
|
Window_DrawTextFlash:
|
|
ldd r0, Y+WIN_OFFS_BG_COL_LO
|
|
ldd r1, Y+WIN_OFFS_BG_COL_HI
|
|
ldd r2, Y+WIN_OFFS_FG_COL_LO
|
|
ldd r3, Y+WIN_OFFS_FG_COL_HI
|
|
|
|
rjmp Window_DrawColorTextFlash
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_DrawColorTextFlash @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param Z pointer to null-terminated string
|
|
; @param R1:R0 background color
|
|
; @param R3:R2 foreground color
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return R5:R4 X pos behind string
|
|
|
|
; @clobbers any, !Y, !R6, !R7
|
|
|
|
Window_DrawColorTextFlash:
|
|
rcall winCalcAbsPosAndBorders ; (R18, R19)
|
|
Window_DrawColorTextFlash_loop:
|
|
lpm r16, Z
|
|
tst r16
|
|
breq Window_DrawColorTextFlash_loopEnd
|
|
rcall winDrawChar
|
|
brcc Window_DrawColorTextFlash_loopEnd
|
|
adiw zh:zl, 1 ; next char
|
|
rjmp Window_DrawColorTextFlash_loop
|
|
Window_DrawColorTextFlash_loopEnd:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_DrawCharAt @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R16 char to write
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return R5:R4 X pos behind char
|
|
; @clobbers any, !Y
|
|
|
|
Window_DrawCharAt:
|
|
rcall winCalcAbsPosAndBorders
|
|
|
|
ldd r0, Y+WIN_OFFS_BG_COL_LO
|
|
ldd r1, Y+WIN_OFFS_BG_COL_HI
|
|
ldd r2, Y+WIN_OFFS_FG_COL_LO
|
|
ldd r3, Y+WIN_OFFS_FG_COL_HI
|
|
|
|
rjmp winDrawChar
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine winCalcAbsPosAndBorders
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R5:R4 X relative to window
|
|
; @param R7:R6 Y relative to window
|
|
; @return R9:R8 first X pos right of windows
|
|
; @return R5:R4 X relative to screen
|
|
; @return R7:R6 Y relative to screen
|
|
; @return R9:R8 first X pos right of window (abs)
|
|
; @return R11:R10 first Y pos below window (abs)
|
|
; @clobbers r18, r19
|
|
|
|
winCalcAbsPosAndBorders:
|
|
; calc abs X pos
|
|
ldd r18, Y+WIN_OFFS_X_LO
|
|
ldd r19, Y+WIN_OFFS_X_HI
|
|
add r4, r18 ; add X of window
|
|
adc r5, r19
|
|
|
|
; calc first X pos behind window
|
|
ldd r8, Y+WIN_OFFS_WIDTH_LO
|
|
ldd r9, Y+WIN_OFFS_WIDTH_HI
|
|
add r8, r18
|
|
adc r9, r19
|
|
|
|
; calc abs Y pos
|
|
ldd r18, Y+WIN_OFFS_Y_LO
|
|
ldd r19, Y+WIN_OFFS_Y_HI
|
|
add r6, r18 ; add Y of window
|
|
adc r7, r19
|
|
|
|
; calc first Y pos behind window
|
|
ldd r10, Y+WIN_OFFS_HEIGHT_LO
|
|
ldd r11, Y+WIN_OFFS_HEIGHT_HI
|
|
add r10, r18
|
|
adc r11, r19
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine winDrawChar
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R16 char to write
|
|
; @param R5:R4 absolute X on screen
|
|
; @param R7:R6 absolute Y on screen
|
|
; @param R9:R8 first X pos right of windows
|
|
; @return R5:R4 X pos behind char
|
|
; @clobbers any, !Y, !R6, !R7, !R8, !R9, !R10, !R11
|
|
|
|
winDrawChar:
|
|
push zl
|
|
push zh
|
|
mov r12, r16
|
|
ldd zl, Y+WIN_OFFS_FONT_LO
|
|
ldd zh, Y+WIN_OFFS_FONT_HI
|
|
|
|
; check whether the char fits inside window
|
|
bigcall FONT_GetCharWidth ; r16=char width
|
|
|
|
clr r17
|
|
add r16, r4 ; char width+X
|
|
adc r17, r5
|
|
sub r16, r8 ; check against window width
|
|
sbc r17, r9
|
|
brcc winDrawChar_ret ; not fit, jmp
|
|
|
|
; actually draw char
|
|
mov r16, r12
|
|
push r8
|
|
push r9
|
|
push r10
|
|
push r11
|
|
bigcall Display_DrawChar
|
|
pop r11
|
|
pop r10
|
|
pop r9
|
|
pop r8
|
|
clr r16
|
|
add r4, r18 ; increment X
|
|
adc r5, r16
|
|
sec ; write succeeded
|
|
winDrawChar_ret:
|
|
pop zh
|
|
pop zl
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_WriteHexWordAt @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R17:R16 word to write
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return R5:R4 X pos behind string
|
|
; @clobbers any, !Y
|
|
|
|
Window_WriteHexWordAt:
|
|
push r16
|
|
mov r16, r17
|
|
rcall Window_WriteHexByteAt
|
|
pop r16
|
|
rcall Window_WriteHexByteAt
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_WriteHexByteAt @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R16 byte to write
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return R5:R4 X pos behind string
|
|
; @clobbers any, !Y
|
|
|
|
Window_WriteHexByteAt:
|
|
push r16
|
|
swap r16
|
|
rcall winWriteNibble
|
|
pop r16
|
|
rcall winWriteNibble
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
winWriteNibble:
|
|
push r4
|
|
push r5
|
|
push r6
|
|
push r7
|
|
rcall winNibbleToAscii ; write high nibble (r16, r17)
|
|
rcall Window_DrawCharAt ; draw
|
|
pop r7
|
|
pop r6
|
|
pop r5
|
|
pop r4
|
|
clr r17
|
|
add r4, r18
|
|
adc r5, r17
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine winNibbleToAscii
|
|
;
|
|
; Convert a nibble to an ASCII char.
|
|
; @return R16 ASCII representation of that nibble (e.g. '0' for 0)
|
|
; @param R16 byte (in bits 0-3)
|
|
; @clobbers r16, r17
|
|
|
|
winNibbleToAscii:
|
|
andi r16, 0xf
|
|
cpi r16, 10
|
|
brcs winNibbleToAscii_l1
|
|
ldi r17, 7
|
|
add r16, r17
|
|
winNibbleToAscii_l1:
|
|
ldi r17, '0'
|
|
add r16, r17
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
; ---------------------------------------------------------------------------
|
|
; @routine Window_DrawTextFlash @global
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return R5:R4 X pos behind string
|
|
; @return R7:R6 Y pos behind string
|
|
; @clobbers any, !Y
|
|
|
|
Window_DrawTextFlash:
|
|
; calc abs X pos
|
|
ldd r18, Y+WIN_OFFS_X_LO
|
|
ldd r19, Y+WIN_OFFS_X_HI
|
|
add r4, r18 ; add X of window
|
|
adc r5, r19
|
|
|
|
; calc first X pos behind window
|
|
ldd r8, Y+WIN_OFFS_WIDTH_LO
|
|
ldd r9, Y+WIN_OFFS_WIDTH_HI
|
|
add r8, r18
|
|
adc r9, r19
|
|
|
|
; calc abs Y pos
|
|
ldd r18, Y+WIN_OFFS_Y_LO
|
|
ldd r19, Y+WIN_OFFS_Y_HI
|
|
add r6, r18 ; add Y of window
|
|
adc r7, r19
|
|
|
|
; calc first Y pos behind window
|
|
ldd r10, Y+WIN_OFFS_HEIGHT_LO
|
|
ldd r11, Y+WIN_OFFS_HEIGHT_HI
|
|
add r10, r18
|
|
adc r11, r19
|
|
|
|
Window_DrawTextFlash_loop:
|
|
push zl
|
|
push zh
|
|
rcall winCalcLengthWordFlash
|
|
pop zh
|
|
pop zl
|
|
mov r18, r4
|
|
mov r19, r5
|
|
add r18, r12
|
|
adc r19, r13
|
|
sub r18, r8
|
|
sbc r19, r9
|
|
brcs Window_DrawTextFlash_xOkay
|
|
; we need to go to the beginning of the next line
|
|
rcall Window_DrawTextFlash_nextLine
|
|
brcc Window_DrawTextFlash_loopEnd ; outside the window, jmp
|
|
Window_DrawTextFlash_xOkay:
|
|
rcall winDrawWordFlash ; Z points at blank/0 byte after call
|
|
lpm r16, Z+
|
|
tst r16 ; end of string?
|
|
breq Window_DrawTextFlash_loopEnd
|
|
cpi r16, 13
|
|
breq Window_DrawTextFlash_handle13
|
|
; insert other handled chars here
|
|
; write blank char
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIN_OFFS_FONT_LO
|
|
ldd zh, Y+WIN_OFFS_FONT_HI
|
|
ldi r16, 32 ; space
|
|
bigcall Display_DrawChar
|
|
pop zh
|
|
pop zl
|
|
add r4, r8 ; increment X
|
|
adc r5, r9
|
|
|
|
|
|
rjmp Window_DrawTextFlash_loopNext
|
|
Window_DrawTextFlash_handle13:
|
|
rcall Window_DrawTextFlash_nextLine
|
|
Window_DrawTextFlash_loopNext:
|
|
rjmp Window_DrawTextFlash_loop
|
|
Window_DrawTextFlash_nextLine:
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIN_OFFS_FONT_LO
|
|
ldd zh, Y+WIN_OFFS_FONT_HI
|
|
bigcall FONT_GetCharWidth ; r16=char width
|
|
pop zh
|
|
pop zl
|
|
ldd r4, Y+WIN_OFFS_X_LO ; X=left border
|
|
ldd r5, Y+WIN_OFFS_X_HI
|
|
clr r17
|
|
add r6, r16 ; increment Y by font height
|
|
adc r7, r17
|
|
mov r16, r6 ; check against lower border of window
|
|
mov r17, r7
|
|
sub r16, r10
|
|
sbc r17, r11 ; CF set if inside window, cleared otherwise
|
|
ret
|
|
Window_DrawTextFlash_loopEnd:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine winDrawWordFlash
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param Z pointer to string in FLASH
|
|
; @param R1:R0 background color
|
|
; @param R3:R2 foreground color
|
|
; @param R5:R4 X (dest)
|
|
; @param R7:R6 Y (dest)
|
|
; @return r5:r4 next X pos
|
|
; @return Z pointer to next char behind current word
|
|
; @clobbers any, !Y, !r1-r15
|
|
|
|
winDrawWordFlash:
|
|
winDrawWordFlash_loop:
|
|
lpm r16, Z
|
|
cpi r16, 33
|
|
brcs winDrawWordFlash_ret
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIN_OFFS_FONT_LO
|
|
ldd zh, Y+WIN_OFFS_FONT_HI
|
|
bigcall Display_DrawChar
|
|
pop zh
|
|
pop zl
|
|
clr r16
|
|
add r4, r18 ; increment X
|
|
adc r5, r16
|
|
adiw zh:zl, 1
|
|
rjmp winDrawWordFlash_loop
|
|
winDrawWordFlash_ret:
|
|
ret
|
|
; @end
|
|
|
|
|
|
|
|
; ---------------------------------------------------------------------------
|
|
; @routine winCalcLengthWordFlash
|
|
;
|
|
; @param Y pointer to screen object in SDRAM
|
|
; @param Z pointer to string in FLASH
|
|
; @return r13:r12 width of next word in pixels
|
|
; @return Z pointer to next char behind current word
|
|
; @clobbers any, !Y, !r1-r11, !r14, !r15
|
|
|
|
winCalcLengthWordFlash:
|
|
clr r12
|
|
clr r13
|
|
winCalcLengthWordFlash_loop:
|
|
lpm r16, Z
|
|
cpi r16, 33
|
|
brcs winCalcLengthWordFlash_ret
|
|
push zl
|
|
push zh
|
|
ldd zl, Y+WIN_OFFS_FONT_LO
|
|
ldd zh, Y+WIN_OFFS_FONT_HI
|
|
bigcall FONT_GetCharWidth ; r16=char width
|
|
clr r17
|
|
add r12, r16
|
|
adc r13, r17
|
|
pop zh
|
|
pop zl
|
|
brcs winCalcLengthWordFlash_error
|
|
adiw zh:zl, 1 ; next char
|
|
rjmp winCalcLengthWordFlash_loop
|
|
winCalcLengthWordFlash_error:
|
|
ldi r12, 0xff
|
|
ldi r13, 0xff
|
|
winCalcLengthWordFlash_ret:
|
|
ret
|
|
; @end
|
|
|
|
#endif ; if 0
|
|
|
|
|
|
|
|
#endif
|
|
|