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
[This Page] 3 - Better Input
4 - Showing Selection
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

Better Input - Update

Pressing the button for each time you want to increment or decrement a number can be very tedious.  Fortunately, the Datalink has a series of update routines that you can call to handle this automatically.  The update routine takes a few parameters.  First is the type of update to do.  The function limits

;Name: Update

;Version: UPDATE

;Description: This is a simple number update 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 1 indicates that we need to clear the display first

;

CURVAL  EQU   $62  	; The current value we are displaying

;

; (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     STATETAB,X ; The state table get routine - WRIST_GETSTATE

        rts



L0123:  jmp     HANDLE_STATE0

        db      STATETAB-STATETAB

;

; (3) Program strings

S6_UPDATE:      timex6  "UPDATE"

S6_SAMPLE:      timex6  "SAMPLE"

;

; (4) State Table

;

STATETAB:

        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_DNANY4,TIM_ONCE,0           ; NEXT, PREV, SET, MODE button pressed

        db      EVT_UPANY4,TIM_ONCE,0           ; NEXT, PREV, SET, MODE button released

        db      EVT_END

;

; (5) State Table 0 Handler

; This is called to process the state events.

; We see ENTER, TIMER2, RESUME, DNANY4 and UPANY4 events

;

HANDLE_STATE0:

        bset    1,APP_FLAGS	                  ; Indicate that we can be suspended

        lda     BTNSTATE                        ; Get the event

        cmp     #EVT_DNANY4                     ; Did they press a button?

        bne     CHKENTER                        ; No, pass on to see what else there might be

        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_SET                        ; Perhaps the SET button

        beq     DO_SET                          ; If so, handle it

        ; In reality, we can't reach here since we handled all three buttons

        ; in the above code (the MODE button is handled before we get here and the

        ; GLOW button doesn't send in an event for this).  We can just fall through

        ; and take whatever we get from it.

CHKENTER

        cmp     #EVT_ENTER                      ; Is this our initial entry?

        bne     REFRESH

;

; 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_UPDATE-START

        jsr     PUT6TOP

        lda     #S6_SAMPLE-START

        jsr     PUT6MID

        lda     #SYS8_MODE

        jmp     PUTMSGBOT

;

; (6) 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)

        ldx     #CURVAL         ; Point to our value to be updated

        lda     #UPD_MID34      ; Request updating in the middle of the display

        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_SET

        clr     CURVAL          ; When they hit the set button, we just clear to zero

SHOWVAL

        brset   1,FLAGBYTE,NOCLEAR ; Do we need to clear the display first?

REFRESH

        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

        ldx     CURVAL          ; Get the current value

        jsr     FMTXLEAD0       ; Convert it to the two ascii digits

        jmp     PUTMID34        ; And put it on the screen in the right place

;

; (7) 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     CURVAL

        rts

Now all of that code needs a little explaination.  As you can see from the numbers, we have 7 basic sections

  1. Program specific constants - This is where you declare everything that you want to use.  As a Wristapp, you have only a limited amount of Ram (7 bytes to be specific) that you can store your stuff with, so be careful here.  
  2. System entry point vectors - These are fixed and mandated for any Wristapp.  If there is more than one state, the JMP and db sequence is repeated for each state.  We haven't started getting fancy so we still have only one state table.
  3. Program strings - In order to provide addressability to the strings, you need to put them immediately after the entry point vectors.  Our only strings are the two banner strings.
  4. State Table(s) - This really tells the watch how we want to operate and what events we want to handle.  See The State Table for a more complete explaination of this.  We accept the normal RESUME, ENTER, and TIMER2 events for getting us running.  We also handle the MODE button by allowing it to jus tbounce us out of the application and into the next.  It is important that this event be in the table before the EVT_DNANY4 which allows for the NEXT, PREV, SET, and MODE buttons (it ignores the INDIGLO button).  If you press the mode button, it will be handled by the first entry and the application terminated cleanly.  Otherwise, we have to sort out which of the three buttons was pressed.  This is easy to do since BTN_PRESSED holds the actual code assoicated with the button that was selected.
  5. State Table Handler(s) - These are called to process the events for a particular state.  Typically this is a LDA  BTNSTATE followed by a lot of CMP/Bcc instructions.  You also need to do the BSET 1,$8f at the start to allow the Wristapp to be suspendable.  In this case we introduce the use of the EVT_DNANY4 in the basic state table logic testing.  When we see the EVT_DNANY4 or EVT_UPANY4, we look at BTN_PRESSED to identify what the user pressed.
  6. Program Specific Code - The actual meat of the program.  Again, the code is very simple.  We have to handle making sure that the screen is cleared at the appropriate times, but other than that, the majority of the work is picking a direction and setting 0.SYSFLAGS appropriately before letting the system handle the Update for us.  Once we are set up, we set 4,BTNFLAGS and the system roms will handle updating the number for us.
  7. Main Initialization routine - This is called once when the wristapp is first loaded.  We need to make sure that we set the appropriate bits in WRISTAPP_FLAGS.

This has gotten a bit better for input, now you need to show them what they have selected with: Showing Selection - Blink