; *************************************************************************** ; 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_STATICGUI_WINDOW_ASM #define AQH_AVR_STATICGUI_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_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 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 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 ; AQH_AVR_STATICGUI_WINDOW_ASM