DRUID Development Docs: gmode.inc

Gadget Sourcecode: gmode.inc

; Justice Unlimited Gadget Microcode
; (C) 2004 Nathan (Acorn) Pooley 
;
; gmode.inc
;
;@DOC@ code to handle and switch between modes
;


;############################################
;############### SPIN CODE ##################
;############################################

    ;
    ; spinner changed - update TEXT mode
    ;
spin_text:
    BREAKPOINT  bp_input

    ;
    ; draw line 1
    ;
    movff   v_mode_str_hi, v_str_addrhi
    movff   v_mode_str_lo, v_str_addrlo
    clrf    v_putl_linenum
    decf    v_spinval,w
    rcall   string_add
    rcall   putl_addr

    ;
    ; fall thru to common text-menu code
    ;

    ;
    ; spinner changed - update MENU mode
    ;

    SKIP_BREAKPOINT
spin_menu:
    BREAKPOINT  bp_input

spin_common:

    bcf     b_spinchange


    ;
    ; draw line 2
    ;
    movff   v_mode_str_hi, v_str_addrhi
    movff   v_mode_str_lo, v_str_addrlo
    setf    v_putl_linenum
    movf    v_spinval,w
    rcall   string_add
    rcall   putl_addr

    bra     spin_done_keepchange


    ;
    ; spinner changed - update ENTRY mode
    ;
spin_entry:
    BREAKPOINT  bp_input

    ;
    ; move to line 2
    ;
    movlw   20
    rcall   put_position

#if USE_ENTMASK
    ;
    ; what is the new character?
    ;
    lfsr    FSR0, BUF_ENTCHARS-1
    movf    v_spinval,w
    addwf   FSR0L,f
    movff   INDF0, TABLAT       ; store temorarily into TABLAT
#endif

    ;
    ; draw entry so far
    ;
    lfsr    FSR0, BUF_ENTRY     ; address the entry buffer
    movf    v_entry_ptr,w
    clrf    PLUSW0              ; clear last byte
    addlw   -12                 ; start 12 bytes from end
    btfsc   STATUS,N
    clrf    WREG                ; ... or at beginning if <=12 total
    movwf   FSR0L
    bra     spin_entry_start

spin_entry_loop:
    rcall   putc_raw
spin_entry_start:
    movf    POSTINC0,w          ; get character
    bnz     spin_entry_loop     ; not 0 - show it

#if USE_ENTMASK
    ;
    ; what is the new character?
    ;
    movf    TABLAT,w
    bnn     spin_entry_finish       ; regular character?

    ;
    ; special character
    ;   0x80 = delete/exit
    ;   0x81 = enter/exit
    ;   0x82 = exit
    ;
    addlw   LOW str_entry_del-0x80

    movf    v_entry_ptr,f       ; if first character then is exit
    btfsc   STATUS,Z
    movlw   str_entry_exit

    rcall   puts
    bra     spin_done

#else
    ;
    ; what is the new character?
    ;
    ;  1      = enter    (exit if first char)
    ;  2...27 = a...z
    ; 28...37 = 0...9
    ; 38      = <space>
    ; 39      = <del>    (exit if first char)
    ; 40      = <enter2> (exit if first char)
    ; 41      = <exit>
    ;
    movf    v_spinval,w
    addlw   LOW -1
    bz      spin_entry_special  ; enter?
    addlw   LOW -27
    bn      spin_entry_alpha    ; alpha character?
    addlw   LOW -10
    bn      spin_entry_num      ; numeric digit?
    bz      spin_entry_space    ; space?

spin_entry_special:
    ;
    ; exit
    ;
    ;
    ; it is either:
    ;     enter     (was  1, now  0)
    ;     del       (was 39, now  1)
    ;     enter2    (was 40, now  2)
    ;     exit      (was 41, now  3)
    ;
    addlw   str_entry_enter

    movf    v_entry_ptr,f       ; if first character then is exit
    btfsc   STATUS,Z
    movlw   str_entry_exit

    rcall   puts
    bra     spin_done


spin_entry_space:
    movlw   ' '-'0'-10              ; space

    ;
    ; -10...-1 = 0...9
    ;
spin_entry_num:
    addlw   '0'+10-'A'-26           ; digit

    ;
    ; -26...-1 = a...z
    ;
spin_entry_alpha:
    addlw   'A'+26                  ; alpha letter
#endif


    ;
    ; put new character in buffer and draw it
    ;
spin_entry_finish:
    decf    FSR0L,f
    movwf   INDF0                   ; store 
    rcall   putc_raw                ; draw
    movlw   str_entry_spc
    rcall   puts                    ; erase following characters
    
    ; fall through to spin_done

    ;
    ; finish spin function
    ;

    SKIP_BREAKPOINT
spin_ignore:
    BREAKPOINT  bp_input


spin_done:
    bcf     b_spinchange
spin_done_keepchange:
    BREAKPOINT  bp_sim_input
    return

;############################################
;############### CLICK CODE #################
;############################################

#if USE_ENTMASK
    ;
    ; ENTRY Mode click
    ;
click_entry:
    BREAKPOINT  bp_input

    ;
    ; what character was selected?
    ;
    lfsr    FSR0, BUF_ENTCHARS-1
    movf    v_spinval,w
    addwf   FSR0L,f
    movf    INDF0,w

    bnn     click_entry_char

    ;
    ; special character
    ; if first char then exit (no questions asked)
    ;
    movf    v_entry_ptr,f
    bnz     click_entry_special     ; not 1st char?

    ;
    ; first char & exited
    ;
    bra     pop_mode

click_entry_special:
    ;
    ; special character
    ;   0x80 = delete
    ;   0x81 = enter
    ;   0x82 = exit
    ;
    addlw   LOW -0x81
    bz      click_entry_enter       ; was 0x81
    bn      click_entry_del         ; was 0x80

    ;
    ; fall thru to click_entry_exit
    ;

    ;
    ; <exit> - are we really done?
    ;
click_entry_exit:
    movlw   mode_entryabort
    bra     push_mode

    ;
    ; <enter> clicked! jump to function pointer
    ;
click_entry_enter:
    movf    v_mode_action,w     ; function to call
    bra     main_jump
    
    ;
    ; <del> (backspace) clicked
    ;
click_entry_del:
    decf    v_entry_ptr,f           ; delete character
    bra     spin_entry              ; go here to redisplay

    ;
    ; got a character - increment ptr and check overflow
    ;
click_entry_char:
    incf    v_entry_ptr,f           ; add character
    btfsc   STATUS,N
    decf    v_entry_ptr,f           ; overflow? - remove char
    bra     spin_entry              ; go here to redisplay

#else
    ;
    ; ENTRY Mode (type=0x80)
    ;
    ;  1      = enter  (exit if first char)
    ;  2...27 = a...z
    ; 28...37 = 0...9
    ; 38      = <space>
    ; 39      = <del>  (exit if first char)
    ; 40      = <enter2>  (exit if first char)
    ; 41      = <exit>
    ;
click_entry:
    movf    v_spinval,w
    addlw   LOW -1              ; enter?
    bz      click_entry_enter
    addlw   LOW -38
    bn      click_entry_char    ; valid character
    bz      click_entry_del     ; <del> clicked
    dcfsnz  WREG,f
    bra     click_entry_enter   ; enter2

click_entry_exit:
    movlw   mode_entryabort     ; ABORT - return to main menu
    bra     set_mode

    ;
    ; <enter> clicked! jump to function pointer
    ;
click_entry_enter:
    movf    v_entry_ptr,f
    bz      click_entry_exit    ; quit if first char

    movf    v_mode_choice,w     ; function to call
    movf    v_entry_ptr,f
    bz      set_default_mode1   ; if no data entered, do default

    bra     main_jump
    
    ;
    ; <del> (backspace) clicked
    ;
click_entry_del:
    movf    v_entry_ptr,f
    bz      click_entry_exit        ; quit if first char

    decf    v_entry_ptr,f           ; delete character
    btfsc   STATUS,N
    clrf    v_entry_ptr             ; at start of buffer? - stay there
    bra     spin_entry              ; go here to redisplay

    ;
    ; got a character - increment ptr and check overflow
    ;
click_entry_char:
    incf    v_entry_ptr,f           ; add character
    btfsc   STATUS,N
    decf    v_entry_ptr,f           ; overflow? - remove char
    bra     spin_entry              ; go here to redisplay
#endif
    

    ;
    ; text click just changes to new mode
    ;
click_text:
    BREAKPOINT  bp_input

    ;
    ; special case if current mode is welcome mode
    ;
    movf    v_mode,w
    bz      init_to_main_menu

    ;
    ; get next mode
    ;
    movf    v_mode_action,w
#if 0
    bra     click_setmode
#endif

    bz      pop_mode        ; 00 - pop
    bra     set_mode


    ;
    ; menu click - lookup new mode
    ;
click_menu:
    BREAKPOINT  bp_input

    lfsr    FSR0, BUF_MODE-1
    movf    v_spinval,w
    addwf   FSR0L,f
    movf    INDF0,w             ; action


    bz      pop_mode        ; 00 - pop
    bra     push_mode
#if 0

click_setmode:
    ; mode  ACTION
    ; 00    pop
    ; 80    init mode (pop everything)
    ; >0    push mode
    ; <0    set mode & 0x7f
    ;
    bz      pop_mode        ; 00 - pop
    bnn     push_mode       ; >0 - push
    andlw   0x7f
    bnz     set_mode        ; <0 - set
    rcall   init_mode       ; 80 - init
    bra     load_mode

#endif


;############################################
;############### MODE FUNCS #################
;############################################

    ; TODO: finish these
fn_save_name:
    movlw   mode_gotname
    bra     set_mode

fn_switch_light:
    rcall   light_toggle
    bra     pop_mode

fn_switch_off:
    rcall   init_mode
    bsf     b_sleep
    bsf     b_turn_off
    return

fn_irlook_end:
    DISABLE_IR  
    bra     pop_mode

fn_pop3:
    rcall   pop_mode_noload
fn_pop2:
    rcall   pop_mode_noload
fn_pop:
    bra     pop_mode
    
    ;
    ; set paremeter0 as curent mode
    ;
fn_setmode:
    movf    v_str_addrhi,w
    bra     set_mode


;############################################
;############### INIT MODE ##################
;############################################

    ;
    ; initialize mode related variables
    ;
init_mode:
    movlw   LOW BUF_MODESTACK_END
    movwf   v_modestack_ptr
    movlw   mode_welcome
#if 1
    bra     set_mode_noload
#else
    bra     set_mode
#endif

    ;
    ; init to main menu
    ;
init_to_main_menu:
    movlw   LOW BUF_MODESTACK_END
    movwf   v_modestack_ptr
    movlw   mode_main_menu
    bra     set_mode_noload

;############################################
;############### PUSH/POP MODE ##############
;############################################
;
; mode stack frame:
;
;  +0  mode index
;  +1  v_spinval
;

pop_mode_err
    bra     error_stackpop
push_mode_err
    bra     error_stackpush

    ;
    ; pop mode off stack - do not load resulting mode
    ;
pop_mode_noload:
    lfsr    FSR0,BUF_MODESTACK
    movf    v_modestack_ptr,w
    bn      pop_mode_err                ; popped off end of stack
    movwf   FSR0L
    movff   PREINC0,v_spinval           ; get old spinval
    movff   PREINC0,v_mode              ; get old mode
    movff   FSR0L,v_modestack_ptr
    return

    ;
    ; push mode onto stack - do not load resulting mode
    ;
push_mode_noload:
    movwf   v_tmp
    lfsr    FSR0,BUF_MODESTACK
    movf    v_modestack_ptr,w
    bz      push_mode_err
    movwf   FSR0L
    movff   v_mode,POSTDEC0             ; save old mode
    movff   v_spinval,POSTDEC0          ; save old spinval
    movff   FSR0L,v_modestack_ptr
    movf    v_tmp,w

set_mode_noload:
    movwf   v_mode
    movlw   1
    movwf   v_spinval
    movf    v_mode,w                    ; keep mode in w
    bcf     b_popping
    return

    ;
    ; pop mode off stack
    ;
pop_mode:
    rcall   pop_mode_noload
    ;
    ; fall thru to redraw mode
    ;

    ;
    ; redraw current mode from scratch
    ;
redraw_mode:
    bsf     b_popping                   ; we are doing a pop!
    bra     load_mode

    ;
    ; push current mode onto stack & set new mode
    ;
push_mode:
    rcall   push_mode_noload

    ;
    ; fall thru to set_mode
    ;

;############################################
;############### SET NEW MODE ###############
;############################################

    ;
    ; set new mode (replaces current mode)
    ; w = index of new mode
    ;
set_mode:
    rcall   set_mode_noload

    ;
    ; fall thru to load_mode
    ;

;############################################
;############### FIND AND SETUP MODE ########
;############################################

    ;
    ; find mode (from v_mode) and load into mode buffer
    ;
load_mode:
    BREAKPOINT  bp_load_mode
    bsf     disab_spinner           ; save power by disabling spin

#if 1
    ;
    ; clear screen (TODO: is this needed?)
    ;
    rcall   putc_clr                ; clear screen
#endif

    rcall   setup_progread          ; prepare to read flash mem

    movlw   LOW modes               ; point to mode table (in flash mem)
    movwf   TBLPTRL
    movlw   HIGH modes
    movwf   TBLPTRH

    incf    v_mode,w                ; mode
    movwf   v_tmp

    bra     load_mode_start

load_mode_loop:
    tblrd*                          ; get byte-len of mode
    movf    TABLAT,w
    addwf   TBLPTRL,f               ; add to pointer
    clrf    WREG
    addwfc  TBLPTRH,f

load_mode_start:
    decfsz  v_tmp,f
    bra     load_mode_loop


    ;
    ; load mode
    ;
    lfsr    FSR0,BUF_MODE
    tblrd*+                         ; read length of mode

    ;
    ; read type of mode and count
    ;
    tblrd*+

    movf    TABLAT,w
    andlw   0x3f
    movwf   v_mode_cnt      ; # items in menu/text or mask for entry
    movwf   v_spinmax
    movwf   v_tmp

    movf    TABLAT,w
    andlw   0xc0            ; what type of mode?
    movwf   v_mode_type

    ;
    ; read first string address
    ;
    tblrd*+
    movf    TABLAT,w
    movwf   v_mode_str_hi
    movwf   v_str_addrhi
    tblrd*+
    movf    TABLAT,w
    movwf   v_mode_str_lo
    movwf   v_str_addrlo

    ;
    ; read action
    ;
    tblrd*+
    movf    TABLAT,w
    movwf   v_mode_action
    movwf   POSTINC0

    ;
    ; entry or function call mode?
    ;
    BREAKPOINT  bp_load_mode2
    movf    v_mode_type,w
    bn      load_func_or_entry

load_text_or_menu:
    ;
    ; menu?
    ;
    btfsc   v_mode_type,6
    bra     load_menu_text_com

load_menu:
    ;
    ; load each action in menu
    ;
    tblrd*+
    movf    TABLAT,w
    movwf   POSTINC0

    decfsz  v_tmp
    bra     load_menu

    ;
    ; draw initial string (menu only)
    ;
    clrf    v_putl_linenum
    rcall   putl_addr

load_menu_text_com:
    ;
    ; init & begin accepting input
    ;
    rcall   input_enable

    ;
    ; set click function
    ;
    movlw   func_click_text
    btfss   v_mode_type,6
    movlw   func_click_menu
    movwf   v_func_btn0_click       ; button click func
    
    ;
    ; set spin function
    ;
    movlw   func_spin_text
    btfss   v_mode_type,6
    movlw   func_spin_menu
    movwf   v_func_spinchange       ; spin change func

    ;
    ; run spinchange function to draw 2nd line
    ;
    bra     main_jump


load_func_or_entry:
    addlw   LOW -MTYPE_FUNC
    bz      load_func

load_entry:
    ;
    ; load character set
    ;
    movlw   0x81                ; add <enter> special character
    movwf   POSTINC0

    movlw   26                  ; add uppercase characters
    movwf   v_tmp
    movlw   'A'
    btfsc   b_entmsk_upper
    rcall   load_entry_addc

    movlw   26                  ; add lowercase characters
    movwf   v_tmp
    movlw   'a'
    btfsc   b_entmsk_lower
    rcall   load_entry_addc

    movlw   10                  ; add digits
    movwf   v_tmp
    movlw   '0'
    btfsc   b_entmsk_digit
    rcall   load_entry_addc

    movlw   ' '                 ; add space
    btfsc   b_entmsk_space
    movwf   POSTINC0

    ; special character
    ;   0x80 = delete/exit
    ;   0x81 = enter/exit
    ;   0x82 = exit
    ;
    movlw   3                   ; add special characters
    movwf   v_tmp
    movlw   0x80
    rcall   load_entry_addc

    ;
    ; how many characters total?
    ;
    movf    FSR0L,w
    addlw   LOW -BUF_ENTCHARS
    movwf   v_spinmax

    ;
    ; draw initial string
    ;
    clrf    v_putl_linenum
    rcall   putl_addr

    ;
    ; empty entry buffer (unless popping)
    ;
    btfss   b_popping
    clrf    v_entry_ptr             ; clear entry pointer
    lfsr    FSR0, BUF_ENTRY
    movff   v_entry_ptr,FSR0L
    clrf    INDF0                   ; zero last char in buffer

    ;
    ; init & begin accepting input
    ;
    rcall   input_enable

    ;
    ; load function pointers
    ;
    movlw   func_click_entry
    movwf   v_func_btn0_click       ; click func
    movlw   func_spin_entry
    movwf   v_func_spinchange       ; spin change func

    ;
    ; run spinchange function to draw 2nd line
    ;
    bra     main_jump


    ;
    ; add characters to character buffer
    ;   w = 1st character to add
    ;   v_tmp = # of characters to add
    ;
load_entry_addc:
    movwf   POSTINC0
    incf    WREG,w
    decfsz  v_tmp,f
    bra     load_entry_addc
    return
    

load_func:
    ;
    ; call function
    ;  Parameters (if any) are in v_str_addrhi, v_str_addrlo
    ;
    movf    v_mode_cnt,w                    ; function id
    bra     main_jump

This file Copyright (C) 2004 by Nathan (Acorn) Pooley
Go to DRUID Development page
Go to DRUID page
Go to JU Gadgets page
Go to Justice Unlimited homepage
Go to Acorn's personal webpage
Contact Acorn
See comments from others
Post your own comments
File created by do_doc at Wed Aug 4 17:54:36 2004