Mercurial > public > hwos_code
view src/menu_processor.asm @ 628:cd58f7fc86db
3.05 stable work
author | heinrichsweikamp |
---|---|
date | Thu, 19 Sep 2019 12:01:29 +0200 |
parents | c40025d8e750 |
children | 185ba2f91f59 |
line wrap: on
line source
;============================================================================= ; ; File menu_processor.asm combined next generation V3.03.2 ; ; Routines to handle all hwOS graphic/text menus. ; ; Copyright (c) 2011, JD Gascuel, HeinrichsWeikamp, all right reserved. ;============================================================================= ; HISTORY ; 2012-11-02 : [jDG] Cleanup for hwOS: removed icons. Added scrolling. ; But need a font with lower/upper alpha chars... #include "hwos.inc" #include "convert.inc" #include "strings.inc" #include "tft.inc" #include "varargs.inc" #include "start.inc" #include "surfmode.inc" #include "divemode.inc" #include "tft_outputs.inc" #include "eeprom_rs232.inc" #include "adc_lightsensor.inc" #include "i2c.inc" #include "rtc.inc" #include "wait.inc" ; NOTE: needs to be identical in .inc and .asm ! #define MENU_LINES_MAX .7 ; maximum number of lines per screen #define MENU_TITLE_FONT WIN_STD ; font needs to contain lower and UPPER chars #define MENU_LINE_FONT WIN_SMALL ; font needs to contain lower and UPPER chars #define MENU_LEFT .20 ; position of first menu item #define MENU_HEIGHT .27 ; spacing between menu lines #define MENU_VCENTER .125 ; position on screen #define MENU_LINE_MAX_LENGTH .20 ; length in characters #define option_item proc_item extern aa_wordprocessor extern option_inc extern option_draw extern TFT_clear_divemode_menu extern TFT_divemask_color extern rtc_set_rtc extern divemode_option0_return extern TFT_fillup_with_spaces menu_proc CODE ;============================================================================= ; menu handler ; ; Input: TBLPTR = addr of menu block global menu_processor menu_processor: ; btfss divemode ; in dive mode? ; call request_speed_fastest ; NO - request CPU speed change to fastest speed ;---- Read menu block ------------------------------------------------ VARARGS_BEGIN ; read inline PROM data clrf STKPTR ; never return from here VARARGS_GET8 item_max ; get number of items VARARGS_GET8 menu_flags ; get flags VARARGS_GET24 menu_title ; get pointer to menu title VARARGS_GET8 menu_center ; vertical position movff TBLPTRL, menu_block+0 ; save base address for menu_read_item movff TBLPTRH, menu_block+1 ; ... movff TBLPTRU, menu_block+2 ; ... btfss divemode ; in dive mode? bra menu_processor0 ; NO ; Required for menus with less entries than the calling menu but not so nice when setting up gas 6.... mH movlw .1 cpfsgt menu_pos_cur ; only if menu_pos_cur = 1... call TFT_clear_divemode_menu ; ... clear the menu! ; Draw one frame around the dive mode menu call TFT_divemask_color WIN_FRAME_COLOR16 dm_menu_row, dm_menu_lower, dm_menu_left ,dm_menu_right ; top, bottom, left, right call TFT_standard_color bra menu_processor1 ; skip next code segment in dive mode menu_processor0: ;---- draw menu title ------------------------------------------------ clrf CCP1CON ; stop PWM bcf PORTC,2 ; pull PWM out to GND call TFT_ClearScreen rcall menu_processor_title rcall menu_processor_bottom_line menu_processor1: WIN_FONT FT_SMALL ;---- Select menu type ----------------------------------------------- bra menu_vertical ;============================================================================= ; draw menu bottom line ; menu_processor_bottom_line: ;---- Draw bottom line ----------------------------------------------- TEXT_TINY .5, .240-.16, tNext TEXT_TINY .160-.6*.6, .240-.16, tEnter goto TFT_standard_color ; ...and return ;============================================================================= ; (re-)draw menu title ; menu_processor_title: WIN_BOX_BLACK .2,.23,.0,.159 ; clear menu title MENU_TITLE_FONT .0, .2 ; menu title positioning btfss menu_flags,0 ; static or dynamic title? bra menu_processor_static_title ; static title rcall menu_processor_call_title ; dynamic title - add gas, detail and color bra menu_processor_title_1 menu_processor_static_title: movff menu_title+0,FSR1L ; just copy string movff menu_title+1,FSR1H call strcpy_text menu_processor_title_1: WIN_COLOR color_greenish movf FSR2L,W ; get title length mullw .9 ; convert to half pixels bcf STATUS,C ; clear carry rrcf PRODL ; /2 movf PRODL,W ; back to WREG sublw .80 ; 80 - width movwf win_leftx2 ; aligned to center movlw .0 ; string termination code movff WREG,buffer+.17 ; limit to 17 chars (std font max.) call aa_wordprocessor call TFT_standard_color return ;============================================================================= ; Call dynamic proc for menu title: menu_processor_call_title: movff menu_title+2,PCLATU ; execute computed goto movff menu_title+1,PCLATH movf menu_title+0,W movwf PCL ;============================================================================= ; Restart with first icon/line selected ; global menu_processor_reset menu_processor_reset: clrf menustack ; clear first stack position clrf menustack_pointer ; set stack pointer to first stack position clrf selected_item ; set last menu item to first item return global menu_processor_double_pop global menu_processor_pop menu_processor_double_pop: decf menustack_pointer,F ; decrement stack pointer menu_processor_pop: decf menustack_pointer,F ; decrement stack pointer btfsc menustack_pointer,7 ; did the stack pointer under-run? clrf menustack_pointer ; YES - reset stack pointer to first stack position movf menustack_pointer,W ; load stack pointer into WREG lfsr FSR2,menustack ; load base address of menu stack movff PLUSW2,selected_item ; retrieve menu item from stack return ; done menu_processor_push: lfsr FSR2,menustack ; load base address of menu stack movf menustack_pointer,W ; load stack pointer into WREG movff selected_item,PLUSW2 ; save menu item to stack incf menustack_pointer,W ; increment stack pointer, park result in WREG btfss WREG,3 ; result < 8 ? movwf menustack_pointer ; YES - update stack pointer clrf selected_item ; set to first item in new menu return ; done ;---- Execute menu selection ------------------------------------------------- do_menu_item: bcf switch_right ; clear left-over button event movf selected_item,W ; reread proc address from table rcall menu_read_item ; (destroys PROD) movff selected_item,PRODL ; pass along selected line rcall menu_processor_push ; remember where we got from (clears selected_item) movff proc_item+2,PCLATU ; then execute computed goto movff proc_item+1,PCLATH movf proc_item+0,W movwf PCL ;============================================================================= ; Get current item from table. ; ; Input : Item number in WREG, menu_block. ; Output : icon_large, text_item, proc_item 16bits pointers. ; Trashed: PROD, WREG ; menu_read_item: mullw .10 ; 10 bytes per item movf PRODL,W ; then do a 24 bits add addwf menu_block+0,W ; with menu_block, and movwf TBLPTRL ; setup TBLPTR movf PRODH,W addwfc menu_block+1,W movwf TBLPTRH movlw 0 addwfc menu_block+2,W movwf TBLPTRU VARARGS_GET8 value_type ; read 10 bytes of item data VARARGS_GET24 dynamic_item VARARGS_GET24 proc_item VARARGS_GET8 WREG ; skip dummy byte VARARGS_GET16 text_item return ;============================================================================= ; Vertical menu - set of line/value to choose from, ; entry point to update lines already shown ; global menu_vertical menu_vertical: rcall menu_draw_lines ; always re-draw whole menu movlw CCP1CON_VALUE ; see hwos.inc btfss divemode ; in dive mode? movwf CCP1CON ; NO - power-on backlight menu_vertical_1: movf selected_item,W ; copy current menu item selection to WREG rcall menu_read_item ; get current menu item data movf proc_item+0,W ; check if proc address is NULL iorwf proc_item+1,W bz next_line_menu ; YES - not selectable btfss divemode ; in dive mode? rcall menu_draw_selected_line ; NO btfss imprint_time_date ; currently imprinting the current time & date? bra menu_line_loop_pre1 ; NO btfss switch_right ; YES - right button pressed, i.e. time or date changed? bra menu_line_loop_pre1 ; NO call TFT_show_time_date_menu_fast ; YES - show a fast response on the screen (may momentarily show an illegal day/month combination) call rtc_set_rtc ; - update time and date on RTC module (corrects illegal day/month combinations) menu_line_loop_pre1: btfsc imprint_color_schemes ; in the color scheme menu? call TFT_show_color_schemes ; YES - update the color schemes menu_line_loop_pre2: bcf switch_right ; clear left-over right button event bcf switch_left ; clear left-over left button event menu_line_loop_pre3: btfsc divemode ; in dive mode? goto divemode_option0_return ; YES - return to it ;bra menu_line_loop_surface ; - proceed to surface mode dispatcher ; dispatcher for surface mode menus menu_line_loop_surface: call reset_timeout_surfmode ; reset timeout menu_line_loop: call housekeeping ; handle data imprinting, screen dump request, timeout and entering dive mode btfsc switch_right ; right button pressed? bra do_line_menu ; YES - type dependent btfsc switch_left ; left button pressed? bra next_line_menu ; YES - goto next item bra menu_line_loop ; NO to both - loop ;---- Move to menu's next line next_line_menu: bcf switch_left ; clear button event incf selected_item,F ; select next item movf selected_item,W ; copy item number to WREG cpfseq item_max ; item number == max ? bra menu_vertical_1 ; NO - redraw cursor clrf selected_item ; YES - wrap-around to first item bra menu_vertical_1 ; then redraw cursor global do_line_menu do_line_menu: decf menu_pos_cur,W ; menu_processor needs 0-5 btfsc divemode ; in dive mode? movwf selected_item ; YES - set selected item from WREG movf selected_item,W ; read selected descriptor rcall menu_read_item movf value_type,W ; switch on data type bz menu_do_line_call ; CALL dcfsnz WREG bra menu_do_line_call ; STRING: do as call dcfsnz WREG bra menu_do_line_option ; OPTION dcfsnz WREG bra menu_do_line_call ; DYNAMIC: do as call bra menu_line_loop_pre3 ; else do nothing ;---- CALL menu_do_line_call: rcall do_menu_item ; same as icon menu: calculated goto rcall menu_processor_pop ; back to same line, bra menu_vertical ; then continue into menu... ;---- Call option specific increment subroutine menu_do_line_option: movff option_item+0,FSR0L ; get option handle movff option_item+1,FSR0H call option_inc ; increment movff selected_item,PRODL ; pass selection to callback rcall menu_text_call bra menu_vertical ; redraw all lines ;----------------------------------------------------------------------------- global menu_draw_lines_divemode ; entry point for re-drawing of the menu to update color-coding of gases menu_draw_lines_divemode: movlw dm_menu_item1_row movff WREG,win_top movlw dm_menu_item1_column movff WREG,win_leftx2 clrf start_item movff item_max,menu_pos_max ; copy item_max for dive mode cursor routine bra menu_draw_lines_2 menu_draw_lines: btfsc divemode ; in dive mode? bra menu_draw_lines_divemode ; YES btfsc menu_flags,0 ; Dynamic title? rcall menu_processor_title ; YES - redraw it then MENU_LINE_FONT MENU_LEFT, 0 ; initialize start position/font movff menu_center,win_top ; computed in menu block. ; Does the menu have more than 6 lines ? movf item_max,W addlw -(MENU_LINES_MAX+1) ; bnn menu_draw_long_menu ; bra if >= 7 clrf start_item bra menu_draw_lines_2 menu_draw_long_menu: movf selected_item,W ; start at selected-6 addlw -(MENU_LINES_MAX-1) btfsc STATUS,N ; is this < 0 ? clrf WREG ; YES - start from top instead movwf start_item menu_draw_lines_2: movff start_item, menu_item WIN_FONT FT_SMALL ; set font size menu_draw_lines_1: call TFT_standard_color ; set default text color movf menu_item,W rcall menu_read_item movf value_type,W ; switch on data type bz menu_draw_line_call dcfsnz WREG bra menu_draw_line_string dcfsnz WREG bra menu_draw_line_option dcfsnz WREG bra menu_draw_line_dynamic bra menu_draw_line_none menu_draw_line_string: movff text_item+0,TBLPTRL ; read not-translated string from PROM movff text_item+1,TBLPTRH call strcpy_prom ; copy in buffer bra menu_draw_line_none menu_draw_line_call: movff text_item+0,FSR1L ; read string from PROM movff text_item+1,FSR1H call strcpy_text ; copy in buffer bra menu_draw_line_none menu_draw_line_option: movff text_item+0,FSR1L ; read string from PROM movff text_item+1,FSR1H call strcpy_text ; copy in buffer movff option_item+0,FSR0L ; retrieve option handle movff option_item+1,FSR0H btfss block_option_value ; display of option value suspended? call option_draw ; NO - draw option (do not do it when setting time or date) bra menu_draw_line_none menu_draw_line_dynamic: lfsr FSR2,buffer movff menu_item,PRODL ; pass item to callback rcall menu_text_call ; push return address bra menu_draw_line_none ; Computed goto to pointer inside dynamic_item: menu_text_call: movf dynamic_item+0,W ; check if callback is NULL iorwf dynamic_item+1,W iorwf dynamic_item+2,W btfsc STATUS,Z return ; YES - don't call it movff dynamic_item+2,PCLATU ; prepare... movff dynamic_item+1,PCLATH movf dynamic_item+0,W movwf PCL ; ...and jump menu_draw_line_none: btfsc divemode ; in dive mode? bra menu_draw_line_none_divemode ; YES movlw MENU_LINE_MAX_LENGTH call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) clrf WREG movff WREG,buffer+MENU_LINE_MAX_LENGTH ; NO - make sure won't be longer than MENU_LINE_MAX_LENGTH ch call aa_wordprocessor bcf win_invert ; clear flag for inverted output by default movlw MENU_HEIGHT ; NO - move to next line addwf win_top,F incf menu_item,F ; inc loop counter movf start_item,W ; first line (scrolled) subwf menu_item,W ; current - first xorlw MENU_LINES_MAX ; get max number of lines btfsc STATUS,Z ; already done max number of lines? return ; YES menu_draw_line_none2: movf menu_item,W ; done item_max lines? xorwf item_max,W btfss STATUS,Z bra menu_draw_lines_1 ; NO - loop... return menu_draw_line_none_divemode: movlw .10 call TFT_fillup_with_spaces ; fill up FSR2 with spaces (total string length in #WREG) clrf WREG movff WREG,buffer+.10 call aa_wordprocessor ; draw the line bcf win_invert ; reset invert flag movlw .24 ; dive mode menu spacing addwf win_top,F incf menu_item,F ; inc loop counter movlw .3 cpfseq menu_item ; at position 4? bra menu_draw_line_none2 ; NO movlw dm_menu_item4_row movff WREG,win_top ; reset row movlw dm_menu_item4_column movff WREG,win_leftx2 ; new column bra menu_draw_line_none2 ; done ;----------------------------------------------------------------------------- ; draw cursor menu_draw_selected_line: WIN_BOX_BLACK .34,.221,MENU_LEFT-8,MENU_LEFT-2 ; clear left column call TFT_standard_color WIN_SMALL MENU_LEFT-8, 0 ; arrow symbol only in small font movf start_item,W ; first line (scrolled) subwf selected_item,W ; selected - first mullw MENU_HEIGHT ; 30 pixel by line movf PRODL,W ; result addwf menu_center,W ; added to first line movwf win_top ; and stored to position STRCPY_PRINT "\xb7" ; print cursor return END