|
Using 3 States - HexDump exampleOk, so you have a computer on your wrist. What better way to show it off than by having a hex dump utility to trapes through memory. This is a major overhaul of a previous version of the hexdump application that I have posted. I have turned it into a real application instead of a simple test program. It also uses the .ZSM file format to allow you to use it with ASM6805. You can download it here ;Name: Hex Dump ;Version: HEXDUMP ;Description: Hex Dumper - by John A. Toebes, VIII ;This Hex dump routine is a simple thing to test out dumping hex bytes... ; ; 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 ; ; ; (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_BYTE: timex6 " BYTE " 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 ; ; (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_BYTE-START ; Put ' BYTE ' 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 CURRENT_LOC EQU *+1 ; Self modifying code... Point to what we want to modify lda $4000,X ; 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 has a few notable sections.
|