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
5 - PassWord
6 - Day Find
7 - Playing with Sound
8 - Using Callbacks
9 - Hex Dump
[This Page] 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

Dumping the EEPROM - promdump example

The HexDump program is great for dumping out the regular memory, but if you search and search, you will never find any of your appointments, lists, phone numbers, or anniversaries in the memory.  That is because they are stored in an EEPROM outside of the address space.  With a few simple modifications to the hexdump program, you can use the system to dump out the contents of the EEPROM.  You can download it here


;Name: Prom Dump

;Version: promdump

;Description: Prom Dumper - by John A. Toebes, VIII

;This Prom Dump routine shows you what is in the EEProm

;

; Press the NEXT/PREV buttons to advance/backup by 6 bytes of memory at a time

; Press the SET button to change the location in memory where you are dumping.

;

;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 the direction of the last button

;   The other bits are not used

CURRENT_DIGIT   EQU     $62

DIGIT0          EQU     $63

DIGIT1          EQU     $64

DIGIT2          EQU     $65

DIGIT3          EQU     $66

;

; These should have been in the Wristapp.i files, but I forgot them...

;

INST_ADDRHI     EQU     $0437

INST_ADDRLO     EQU     $0438

HW_FLAGS        EQU     $9e

;

;

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

L012b:  jmp     HANDLE_STATE2

        db      STATETAB2-STATETAB0

;

; (3) Program strings

;

S6_EEPROM:      timex6   "EEPROM"

S6_DUMPER:      timex6  "DUMPER"

S8_LOCATION     timex   "aaaa    "

;

; (4) State Table

;

STATETAB0:

        db      0

        db      EVT_ENTER,TIM2_12TIC,0          ; Initial state

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

        db      EVT_TIMER2,TIM_ONCE,0           ; This is the timer

        db      EVT_DNNEXT,TIM2_8TIC,1          ; Next button

        db      EVT_DNPREV,TIM2_8TIC,1          ; Prev button

        db      EVT_MODE,TIM_ONCE,$FF           ; Mode button

        db      EVT_SET,TIM_ONCE,2              ; Set button

        db      EVT_USER0,TIM_ONCE,$FF          ; Return to system

        db      EVT_END

        

STATETAB1:

        db      0

        db      EVT_UPANY,TIM_ONCE,0            ; Releasing the prev or next button

        db      EVT_TIMER2,TIM2_TIC,1           ; Repeat operation with a timer

        db      EVT_END                         ; End of table



STATETAB2:

        db      2

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

        db      EVT_DNANY4,TIM_ONCE,2           ; NEXT, PREV, SET, MODE button pressed

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

        db      EVT_USER2,TIM_ONCE,0            ; Return to state 0

        db      EVT_END                         ; End of table



CURRENT_LOC

        dw      $0000                           ; This is where we start in memory

;

; (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 the initial state?

        bne     SHOWDATA                        ; no, just clean up the screen

;

; (6) Put up the initial banner screen

;

        jsr     CLEARALL                        ; Clear the display

        lda     #S6_EEPROM-START                ; Put 'EEPROM' on the top line

        jsr     PUT6TOP

        lda     #S6_DUMPER-START                ; Put 'DUMPER' on the second line

        jsr     PUT6MID

        lda     #SYS8_MODE                      ; Put MODE on the bottom line

        jmp     PUTMSGBOT

; (7) FMTHEX is a routine similar to FMTX, but it handles hex values instead

;=======================================================================

; Routine: FMTHEX

; Purpose:

;   Format a byte into the buffer

; Parameters:

;   A - Byte to be formatted

;   X - Offset into Message buffer to put the byte

;=======================================================================

FMTHEX:

        sta     S8_LOCATION,X   ; Save the byte

        and     #$0f            ; Extract the bottom nibble

        sta     S8_LOCATION+1,X ; Save the hex value of the nibble

        lda     S8_LOCATION,X   ; Get the value once again

        lsra                    ; Shift right by 4 to get the high order nibble

        lsra

        lsra

        lsra



        sta     S8_LOCATION,X   ; And put it back into the buffer

        rts

;

; (8) This is called when we press the prev/next button or when the timer fires during that event

;

HANDLE_STATE1:

        lda     BTNSTATE

        cmp     #EVT_TIMER2                     ; Is this a repeat/timer event?

        beq     REPEATBTN                       ; yes, do as they asked



        bclr    0,FLAGBYTE                      ; Assume that they hit the prev button

        cmp     #EVT_DNPREV                     ; Did they hit the prev button

        bne     REPEATBTN                       ; Yes, we guessed right

        bset    0,FLAGBYTE                      ; No, they hit next.  Mark the direction.

REPEATBTN:

        brclr   0,FLAGBYTE,NEXTLOC              ; If they hit the next button, go do that operation

;

; They pressed the prev button, let's go to the previous location

;

PREVLOC:

        lda     CURRENT_LOC+1

        sub     #6

        sta     CURRENT_LOC+1

        lda     CURRENT_LOC

        sbc     #0

        sta     CURRENT_LOC

        bra     SHOWDATA

NEXTLOC:

        lda     #6

        add     CURRENT_LOC+1

        sta     CURRENT_LOC+1

        lda     CURRENT_LOC

        adc     #0

        sta     CURRENT_LOC

;

; (9) This is the main screen update routine.

; It dumps the current memory bytes based on the current address.  Note that since it updates the entire

; display, it doesn't have to clear anything

;

SHOWDATA:

        jsr     CLEARSYM



        clrx

        bsr     GETBYTE

        jsr     PUTTOP12



        ldx     #1

        bsr     GETBYTE

        jsr     PUTTOP34



        ldx     #2

        bsr     GETBYTE

        jsr     PUTTOP56



        ldx     #3

        bsr     GETBYTE

        jsr     PUTMID12



        ldx     #4

        bsr     GETBYTE

        jsr     PUTMID34



        ldx     #5

        bsr     GETBYTE

        jsr     PUTMID56



        lda     CURRENT_LOC             ; Get the high order byte of the address

        clrx

        bsr     FMTHEX          ; Put that at the start of the buffer

        lda     CURRENT_LOC+1           ; Get the low order byte of the address

        ldx     #2

        bsr     FMTHEX          ; Put that next in the buffer



        lda     #S8_LOCATION-START

        jmp     BANNER8

; (10) GETBYTE gets a byte from memory and formats it as a hex value

;=======================================================================

; Routine: GETBYTE

; Purpose:

;   Read a byte from memory and put it into DATDIGIT1/DATDIGIT2 as hex values

; Parameters:

;   X - Offset from location to read byte

;   CURRENT_LOC - Base location to read from

;=======================================================================

GETBYTE

        txa

        add     CURRENT_LOC+1

        sta     INST_ADDRLO

        lda     CURRENT_LOC

        adc     #0

        sta     INST_ADDRHI

        bset    6,HW_FLAGS                      ; Tell them that it is an EEPROM address

        jsr     GET_INST_BYTE                   ; Get the current byte

        sta     DATDIGIT2                       ; And save it away

        lsra                                    ; Extract the high nibble

        lsra

        lsra

        lsra



        sta     DATDIGIT1                       ; And save it

        lda     DATDIGIT2                       ; Get the byte again

        and     #$0f                            ; Extract the low nibble

        sta     DATDIGIT2                       ; And save it

        rts

;

; (11) State Table 2 Handler

; This is called to process the state events.

; We see SET, RESUME, DNANY4, and UPANY4 events

;

HANDLE_STATE2:

        bset    1,APP_FLAGS	                ; Indicate that we can be suspended

        lda     BTNSTATE                        ; Get the event

        cmp     #EVT_UPANY4

        beq     REFRESH2

        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

        bsr     SHOWDATA

        lda     #EVT_USER2

        jmp     POSTEVENT

;

; (12) This handles the update routine to change a digit...

;

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     #$F

        sta     UPDATE_MAX                      ; and the high end is 15 (the hes digits 0-F)

        bsr     GET_DISP_PARM

        lda     #UPD_DIGIT

        jsr     START_UPDATEP                   ; And prepare the update routine   

        bset    4,BTNFLAGS                      ; Mark that the update is now pending

        rts

;

; (13) This is where we switch which digit we are changing...

;

DO_MODE

        lda     CURRENT_DIGIT

        inca

        and     #3

        sta     CURRENT_DIGIT

;

; (14) Refresh the screen and start blinking the current digit...

;

REFRESH2

        lda     DIGIT0                          ; Get the first digit

        lsla                                    ; *16

        lsla

        lsla

        lsla

        add     DIGIT1                          ; Plus the second digit

        sta     CURRENT_LOC                     ; To make the high byte of the address

        lda     DIGIT2                          ; Get the third digit

        lsla                                    ; *16 

        lsla

        lsla

        lsla

        add     DIGIT3                          ; Plus the fourth digit

        sta     CURRENT_LOC+1                   ; To make the low byte of the address

FORCEFRESH

        bclr    7,BTNFLAGS                      ; Turn off any update routine that might be pending

        jsr     SHOWDATA                        ; Format the screen

        ldx     #4                              ; We need to copy over 4 bytes from the buffer

COPYIT

        decx                                    ; This will be one down.

        lda     S8_LOCATION,X                   ; Get the formatted byte

        sta     DIGIT0,X                        ; And store it for the update routine

        tstx                                    ; Did we copy enough bytes?

        bne     COPYIT                          ; No, go back for more

        bsr     GET_DISP_PARM                   ; Get the parm for the blink routine

        lda     #BLINK_DIGIT                    ; Request to blink a digit

        jsr     START_BLINKP                    ; And do it

        bset    2,BTNFLAGS                      ; Mark a blink routine as pending

        rts

;

; (15) This gets the parameters for an UPDATE/BLINK routine

;

GET_DISP_PARM

        lda     CURRENT_DIGIT                   ; Figure out what digit we are dumping

        sta     UPDATE_POS                      ; Store it for the BLINK/UPDATE routine

        add     #DIGIT0                         ; Point to the byte to be updated

        tax                                     ; And put it into X as needed for the parameter

        rts

;

; (16) 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     CURRENT_DIGIT                   ; Start out on the first digit

        rts

This code is virtually identical to the promdump example with a few minor changes

  1. Program specific constants - I didn't include these three important addresses in the Wristapp.i file, so you have to define them here.
  2. System entry point vectors - No change.
  3. Program strings - Of course we change the name of the application.
  4. State Tables - No change here.
  5. State Table 0 Handler - No change here.
  6. Initial banner screen - No change here.
  7. FMTHEX - No change here.
  8. PREV/NEXT Handling - No change here.
  9. Main Update - No change here.
  10. GETBYTE This is the only real change. We have to call a system routine to read the byte from memory. Before we do that, we need to store the address into the INST_ADDR:HI_INST_ADDRLO variables and set the HW_FLAGS bit to indicate that it is an EEPROM address instead of a real memory address. Note that if we clear the bit instead of setting it, this program will behave like the HEXDUMP progam.
  11. State Table 2 Handler - No change here.
  12. Changing Digits - No change here.
  13. Switching Digits - No change here.
  14. Blinking Digits - No change here.
  15. GET_DISP_PARM - No change here.
  16. Main Initialization - No change here.