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.