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
[This Page] 1 - Hello World
2 - Getting Input
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

A First Wristapp - Hello World

To illustrate, let us take our favorite C Program and figure out how to put it on the Datalink.  The first step in creating a wristapp is to decide on what the user interface will be.  You would think that with only 5 buttons, this would be an easy task, but in reality this can make or break a good application. For our application, we will have it so that when you first enter the app, it puts "HELLO WORLD MODE" on the screen.  If you press the PREV button, it will toggle to turning on all segments.  Pressing the PREV button will switch back to the "HELLO WORLD MODE".  The Next button will take you out of the app and the SET/NEXT buttons will not do anything.  Pressing the GLOW button will activate the indiglo light as expected.  Here's what the code would look like:

;Name: Hello World

;Version: HELLO

;Description: This is a simple Hello 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 that we want to show the segments instead of the message

;

START	EQU   *

;

; (2) System entry point vectors

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_HELLO:   timex6  "HELLO "

S6_WORLD:   timex6  "WORLD "

;

; (4) State Table

; (4) State Table

STATETAB:

        	db  	0

		db	EVT_ENTER,TIM_ONCE,0 	; Initial state

 	        db  	EVT_RESUME,TIM_ONCE,0   ; Resume from a nested app

        	db  	EVT_DNNEXT,TIM_ONCE,0	; Next button

        	db  	EVT_MODE,TIM_ONCE,$FF	; Mode button

        	db  	EVT_END

;

; (5) State Table 0 Handler

; This is called to process the state events.  We only see ENTER, RESUME, and DNNEXT events

;

HANDLE_STATE0:

 	  	bset	1,$8f			; Indicate that we can be suspended

         	lda	BTNSTATE		; Get the event

	    	cmp 	#EVT_DNNEXT             ; Did they press the next button?

		beq	DOTOGGLE		; Yes, toggle what we are displaying

CLEARIT         bclr    0,FLAGBYTE		; Start us in the show display state

REFRESH         brclr   0,FLAGBYTE,SHOWDISP	; Do we want to see the main display?

		jmp	SETALL			; No, just turn on all segments

SHOWDISP	jsr	CLEARALL		; Clear the display

		lda	#S6_HELLO-START         ; Get the offset for the first string

		jsr	PUT6TOP                 ; And send it to the top line

		lda	#S6_WORLD-START         ; Get the offset for the second string

		jsr	PUT6MID                 ; and put it on the middle line

		lda	#SYS8_MODE              ; Get the system offset for the 'MODE' string

		jmp	PUTMSGBOT               ; and put it on the bottom line

;

; (6) Our only real piece of working code...

DOTOGGLE	brset   0,FLAGBYTE,CLEARIT      ; If it is set, just jump to clear it like normal

		bset	0,FLAGBYTE              ; Already clear, so set it

		bra	REFRESH                 ; and let the refresh code handle it

;

; (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	$96

	    	clr  	FLAGBYTE		; start with a clean slate

	    	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.
  3. Program strings - In order to provide addressability to the strings, you need to put them immediately after the entry point vectors.
  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.
  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.
  6. Program Specific Code - The actual meat of the program.  In our case, we simply have to toggle a value.
  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.

Now that we have a basic program working.  Next Up:  Getting Input - Numbers