About the Datalink
What is it?
Download Protocol
Display Segments
Memory Map
150 vs 150s
EEProms

Wristapp Programming
Reference
Creating Wristapps
Wristapp Format
The State Table
Wristapp Routines
Wristapps

Wristapp Programming
Tutorials
1 - Hello World
2 - Getting Input
3 - Better Input
4 - Showing Selection
[This Page] 5 - PassWord
6 - Day Find
7 - Playing with Sound
8 - Using Callbacks
9 - Hex Dump
10 - EEPROM Dumper
11 - Spend Watch
12 - Sound Schemes
13 - Random Numbers
14 - Hourly Chimes
15 - Lottery Picker

Sound Schemes
Sound Hardware
Sound Scheme Format

Home Send Mail

Entering Digits - PASSWD sample

This program is a bit more sophisticated to show off how you might go toward creating a complex app.  I have not made any attempts at optimizing the code here in order to be a bit more clear about how to go about writing this type of app.  There are a few new features with this code:

  • We have two different display screens.  When you first enter the app, it puts up one display.  After it times out, it puts up a different display which also has a scrolling message across the bottom.
  • The set button brings you into a set mode where the mode button switches between digits to set.
  • This app uses two state tables instead of one.  It shows how to switch between the two states.
;Name: Password
;Version: PASSWD
;Description: This is a simple number update/passwd program
;by John A. Toebes, VIII
;
;TIP:  Download your watch faster:  Download a WristApp once, then do not send it again.  It stays in the watch!
;HelpFile: watchapp.hlp
;HelpTopic: 106
            INCLUDE "WRISTAPP.I"
;
; (1) Program specific constants
;
FLAGBYTE        EQU  	$61
;   Bit 0 indicates which digit we are working on (SET=SECOND DIGIT)
;   Bit 1 indicates that we need to clear the display first
;
DIGIT0  EQU     $62     ; The first digit to enter
DIGIT1  EQU     $63     ; The second digit to enter
SYSTEMP0	EQU	$A0
SYSTEMP1	EQU	$A1
;
; (2) System entry point vectors
;
START   EQU     *
L0110:  jmp     MAIN	; The main entry point - WRIST_MAIN
L0113:  rts             ; Called when we are suspended for any reason - WRIST_SUSPEND
        nop
        nop
L0116:  rts             ; Called to handle any timers or time events - WRIST_DOTIC
        nop
        nop
L0119:  rts             ; Called when the COMM app starts and we have timers pending - WRIST_INCOMM
        nop
        nop
L011c:  rts             ; Called when the COMM app loads new data - WRIST_NEWDATA
        nop
        nop

L011f:  lda     STATETAB0,X ; The state table get routine - WRIST_GETSTATE
        rts

L0123:  jmp     HANDLE_STATE0
        db      STATETAB0-STATETAB0
L0127:  jmp     HANDLE_STATE1
        db      STATETAB1-STATETAB0
;
; (3) Program strings
S6_TOEBES:      timex6  "TOEBES"
S6_SAMPLE:      timex6  "SAMPLE"
S6_PRESS:       timex6  "PRESS "
S8_PASSWORD:    timex   "PASSWORD"
SX_MESSAGE      timex   "BY JOHN A. TOEBES, VIII"
                db      SEPARATOR
;
; (4) State Table
;
STATETAB0:
        db      0
        db      EVT_ENTER,TIM_2_8TIC,0          ; Initial state
        db      EVT_TIMER2,TIM_ONCE,0           ; The timer from the enter event
        db      EVT_RESUME,TIM_ONCE,0           ; Resume from a nested app
        db      EVT_MODE,TIM_ONCE,$FF           ; Mode button
        db      EVT_SET,TIM_ONCE,1              ; SET button pressed
        db      EVT_END

STATETAB1:
        db      1
        db      EVT_RESUME,TIM_ONCE,1           ; Resume from a nested app
        db      EVT_DNANY4,TIM_ONCE,1           ; NEXT, PREV, SET, MODE button pressed
        db      EVT_UPANY4,TIM_ONCE,1           ; NEXT, PREV, SET, MODE button released
        db      EVT_USER2,TIM_ONCE,0
        db      EVT_END
;
; (5) State Table 0 Handler
; This is called to process the state events.
; We see ENTER, TIMER2, and RESUME events
;
HANDLE_STATE0:
        bset    1,APP_FLAGS	                ; Indicate that we can be suspended
        lda     BTNSTATE                        ; Get the event
        cmp     #EVT_ENTER                      ; Is this our initial entry?
        bne     REFRESH0
;
; This is the initial event for starting us
;
DO_ENTER    
        bclr    1,FLAGBYTE                      ; Indicate that we need to clear the display
        jsr     CLEARSYM                        ; Clear the display
        lda     #S6_TOEBES-START
        jsr     PUT6TOP
        lda     #S6_SAMPLE-START
        jsr     PUT6MID
        lda     #S8_PASSWORD
        jmp     BANNER8
;
; We come here for a RESUME or TIMER2 event.  For this we want to reset the display
;
REFRESH0
        brset   1,FLAGBYTE,NOCLEAR0             ; Do we need to clear the display first?
        bset    1,FLAGBYTE
        jsr     CLEARSYM
NOCLEAR0
        lda     #S6_PRESS-START
        jsr     PUT6TOP
        lda     #SYS6_SET
        jsr     PUTMSG2
        lda     #SX_MESSAGE-START
        jmp     SETUP_SCROLL
;
; (6) State Table 1 Handler
; This is called to process the state events.
; We see SET, RESUME, DNANY4, and UPANY4 events
;
HANDLE_STATE1:
        bset    1,APP_FLAGS	                ; Indicate that we can be suspended
        lda     BTNSTATE                        ; Get the event
        cmp     #EVT_UPANY4
        beq     REFRESH
        cmp     #EVT_DNANY4                     ; Is this our initial entry?
        bne     FORCEFRESH
        lda     BTN_PRESSED                     ; Let's see what the button they pressed was
        cmp     #EVT_PREV                       ; How about the PREV button
        beq     DO_PREV                         ; handle it
        cmp     #EVT_NEXT                       ; Maybe the NEXT button?
        beq     DO_NEXT                         ; Deal with it!
        cmp     #EVT_MODE                       ; Perhaps the MODE button
        beq     DO_MODE                         ; If so, handle it
        ; It must be the set button, so take us out of this state
        lda     #EVT_USER2
        jmp     POSTEVENT
;
; (7) Our real working code...
DO_NEXT
        bset    0,SYSFLAGS                      ; Mark our update direction as up
        bra     DO_UPD
DO_PREV
        bclr    0,SYSFLAGS                      ; Mark our update direction as down
DO_UPD
        clra
        sta     UPDATE_MIN                      ; Our low end is 0
        lda     #99
        sta     UPDATE_MAX                      ; and the high end is 99 (the max since this is a 2 digit value)
        brset   0,FLAGBYTE,UPD1
        ldx     DIGIT1
        jsr     FMTXLEAD0
        jsr     PUTMID34
        ldx     #DIGIT0                         ; Point to our value to be updated
        lda     #UPD_MID12                      ; Request updating in the middle of the display
        bra     UPD2
UPD1
        ldx     DIGIT0
        jsr     FMTXLEAD0
        jsr     PUTMID12
        ldx     #DIGIT1
        lda     #UPD_MID34
UPD2
        jsr     START_UPDATEP   ; And prepare the update routine
        bset    4,BTNFLAGS      ; Mark that the update is now pending
        bclr    1,FLAGBYTE
        lda     #SYS8_SET_MODE
        jmp     PUTMSGBOT

DO_MODE
        lda     FLAGBYTE
        eor     #1
        sta     FLAGBYTE

REFRESH
        brset   1,FLAGBYTE,NOCLEAR ; Do we need to clear the display first?
FORCEFRESH
        jsr     CLEARALL        ; Yes, clear everything before we start
        bset    1,FLAGBYTE      ; And remember that we have already done that
NOCLEAR
        bclr    7,BTNFLAGS      ; Turn off any update routine that might be pending
        brset   0,FLAGBYTE,SET1
        ldx     DIGIT1
        jsr     FMTXLEAD0
        jsr     PUTMID34
        ldx     #DIGIT0
        lda     #BLINK_MID12
        bra     SET2
SET1
        ldx     DIGIT0
        jsr     FMTXLEAD0
        jsr     PUTMID12
        ldx     #DIGIT1
        lda     #BLINK_MID34
SET2
        jsr     START_BLINKP
        bset    2,BTNFLAGS      ; Mark a blink routine as pending
        rts
;
; (8) This is the main initialization routine which is called when we first get the app into memory
;
MAIN:
        lda     #$c0	                        ; We want button beeps and to indicate that we have been loaded
        sta     WRISTAPP_FLAGS
        clr     FLAGBYTE                        ; start with a clean slate
        clr     DIGIT0
        clr     DIGIT1
        rts
;
; (9) This subroutine is useful for getting a scrolling string on the screen
;
;----------------------------------------------------------------------
; Routine:
;   SETUP_SCROLL
; Parameters:
;   X - Offset from Start to the string
; Returns:
;   MSGBUF - contains copied string
; Purpose
;   This copies the current string into MSGBUF and calls the appropriate routines
;   to start it scrolling on the bottom line.
;----------------------------------------------------------------------
SETUP_SCROLL:
        clr     SYSTEMP0
        sta     SYSTEMP1
DO_COPY:
        ldx     SYSTEMP1        ; Get the pointer to the source character
        lda     START,X         ; Get the character that we are copying
        ldx     SYSTEMP0        ; Get the pointer to the output buffer
        sta     MSGBUF,X        ; and store the character away
        inc     SYSTEMP0        ; Increment our count
        inc     SYSTEMP1        ; As well as the pointer to the character
        cmp     #SEPARATOR      ; Did we get a terminator character
        bne     DO_COPY         ; No, go back for more
        ;
        ; The string is now in a buffer terminated by a separator character
        ;
        jsr     PUTSCROLLMSG        ; Initialize the scrolling support
        jmp     SCROLLMSG           ; And tell it to actually start scrolling

This is code is built on the Update and Blink samples with a few changes and additions.

  1. Program specific constants - We now have two digits to care about. 
  2. System entry point vectors - Because we have gone to two state tables, we now have the extra jump vector.
  3. Program strings - Gee, we changed the strings.  Plus we have a longer string which we pass to our SETUP_SCROLL routine.
  4. State Table(s) - We now have two state tables.  State table0 is pretty simple and is used only for when we are in the normal state.  State table 1 is usef when we are in the set mode.  See The State Table for a more complete explaination of this.
  5. State Table Handler0 - For state0, we only really need to handle the initial enter where we put up the banner.  After a while we time out and put up the 'PRESS SET' message with my name scrolling across the bottom.
  6. State Table Handler1 - This handler is used for when we are in the SET state for changing the numbers.
  7. Program Specific Code - We use the same UPDATE and BLINK functions from the Blink sample.  The only extra work here is that we cause the display to update the other digit when we are setting one.
  8. Main Initialization routine - No changes here. This is called once when the wristapp is first loaded.  We need to make sure that we set the appropriate bits in WRISTAPP_FLAGS.
  9. SETUP_SCROLL subroutine - This is a useful routine that you may wish to copy for another wristapp.