;Name: Tip Calculator ;Version: TIPCALC1 ;Description: The tip calculator - by John A. Toebes, VIII ; ;Press the set button to enter the amount. When in set mode, press the MODE button to switch between dollars and cents mode. ;Press the set button to go back to the display mode. The tip amount will scroll across the bottom of the screen as 15%, 20% and then 10% in sequence. ; ;When in display mode, pressing the prev or next buttons will enter the set mode automatically on the dollars amount. ; ;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" ; ; TIPCALC ; ; Copyright (c) 1997 by John A. Toebes, VIII. 207 Livingstone Drive, Cary, NC 27513 USA. All Rights Reserved ; ; Permission is granted to use this program for personal use. It may not be sold or licenced for any reason ; except with explicit permission of the Author. ; ;---------------------------------------------------------------------------------------------- ; ; Local variables ; CENTS_ONES EQU $60 CENTS_TENS EQU $61 DOLLAR_ONES EQU $62 DOLLAR_TENS EQU $63 WHICH_DIGIT EQU $64 ; Used to choose which digit we are setting AMT_CENTS EQU $65 AMT_DOLLAR EQU $66 BUF_POS EQU $67 START EQU * ENT0110: jmp MAIN ENT0113: rts nop nop ENT0116: rts nop nop ENT0119: rts nop nop ENT011C: rts nop nop GETSTATE: LDA STATETAB,X RTS ENTSTATE0: jmp HANDLE_STATE0 db STATETAB-STATETAB ENTSTATE1: jmp HANDLE_STATE1 db STATETAB1-STATETAB S6_TIP timex6 " TIP " S6_CALC timex6 " CALC " S6_AMOUNT timex6 "AMOUNT" S8_TIPCALC timex "TIP CALC" S8_TOEBES timex "J.TOEBES" SCALE_AMT db 0 CALC_0: db 0 CALC_1: db 0 CALC_CENT_ONES: db 0 CALC_CENT_TENS: db 0 CALC_DOLLAR_ONES: db 0 CALC_DOLLAR_TENS: db 0 CALC_PADD db 0 db 0 STATETAB: db 0 db EVT_RESUME,TIM_ONCE,0 db EVT_ENTER,TIM_LONG,0 db EVT_TIMER2,TIM_ONCE,0 db EVT_MODE,TIM_ONCE,$ff db EVT_DNANY4,TIM_ONCE,0 db EVT_USER0,TIM_ONCE,1 db EVT_USER1,TIM_ONCE,$ff db EVT_END STATETAB1: db 1 ; Enter state 2 if none of the items match db EVT_USER0,TIM_ONCE,1 db EVT_DNANY4,TIM_ONCE,1 db EVT_UPANY4,TIM_ONCE,1 db EVT_USER2,TIM_ONCE,0 db EVT_END HANDLE_STATE0 lda BTNSTATE cmp #EVT_ENTER beq HANDLE_ENTER cmp #EVT_DNANY4 beq FIRST_DOWN bra REFRESH_BOTH FIRST_DOWN lda #EVT_USER0 jmp POSTEVENT HANDLE_ENTER: lda USER04a1 beq L01e6 clra sta USER04a1 lda #EVT_USER1 jsr POSTEVENT rts L01e6: jsr CLEARALL lda #S6_TIP-START jsr PUT6TOP lda #S6_CALC-START jsr PUT6MID lda #S8_TOEBES-START jmp BANNER8 ; ; Refreshes the display ; REFRESH_AMT jsr FMTSPACE ; Blank the right side of the middle line jsr PUTMID56 ldx AMT_DOLLAR ; Get the dollar amount jsr FMTXLEAD0 ; Format it into digits lda DATDIGIT1 ; Save away the tens digit sta DOLLAR_TENS bne NOFIXTENS ; Was it less than $10? lda #C6_SPACE ; Yes, replace the 0 with a space sta DATDIGIT1 NOFIXTENS lda DATDIGIT2 ; Store away the ones digit sta DOLLAR_ONES jsr PUTMID12 lda #$36 ; Turn on the decimal point sta DISP_ROW bset 2,DISP_COL ldx AMT_CENTS ; Format the cents amount jsr FMTXLEAD0 lda DATDIGIT1 ; Save away the tens digit sta CENTS_TENS lda DATDIGIT2 sta CENTS_ONES ; Save away the ones digit jmp PUTMID34 REFRESH_BOTH jsr CLEARALL lda #S6_TIP-START jsr PUT6TOP bsr REFRESH_AMT clrx lda #15 bsr APPEND_PCT lda #20 bsr APPEND_PCT lda #10 bsr APPEND_PCT lda #SEPARATOR ; Wipe out the final space sta MSGBUF-1,X jsr PUTSCROLLMSG jmp SCROLLMSG ; ; Parameters: ; A - Amount to multiply by (0-25%) ; X - buffer position ; APPEND_PCT sta SCALE_AMT ; Save the amount we will be scaling by stx BUF_POS ; as well as where we are in the buffer tax ; Get the amount to scale jsr FMTXLEAD0 ; And convert to the decimal digits ldx BUF_POS ; Get the current buffer position lda DATDIGIT1 ; And put the two digits in it bsr DO_APPEND lda DATDIGIT2 bsr DO_APPEND lda #$29 ; Followed by a % bsr DO_APPEND lda #$37 ; = bsr DO_APPEND ; lda #$28 ; $ ; bsr DO_APPEND stx BUF_POS ; Remember where we are in the buffer ; ; This takes the four digits and does a BCD multiply by the scale amount ; lda CENTS_ONES ldx SCALE_AMT mul sta CALC_0 lda CENTS_TENS ldx SCALE_AMT mul add #5 sta CALC_1 lda DOLLAR_ONES ldx SCALE_AMT mul sta CALC_CENT_ONES lda DOLLAR_TENS ldx SCALE_AMT mul sta CALC_CENT_TENS clra sta CALC_DOLLAR_ONES sta CALC_DOLLAR_TENS sta CALC_PADD ; ; We now have 4 bytes of the scaled values followed by three zeros ; the largest value in any one should be 9*20 = 180 (although we support up to 28%) ; ; Now we need to propagate any values over. This is as simple as subtracting 10 from each ; digit until we hit zero and adding 1 to the next digit. ; clrx AGAIN lda CALC_0,X ; Get the current digit DOFIX sub #10 ; See if we can take away 10 safely blo NEXT_DIGIT ; Went under? Forget about doing this digit, it is already fine sta CALC_0,X ; We had 10 to take away, save the changed value lda CALC_0+1,X ; and increment the next digit. Note that we can't increment it straight inca ; in memory because it is not in the first page of memory sta CALC_0+1,X bra AGAIN ; ; ; Parameters: ; A - Byte to be stored in the buffer ; X - Current position in the buffer ; Notes: ; We need to have a little locality... This is a convenient place to ensure that ; it is reachable by lots of code. This routine take ; DO_APPEND sta MSGBUF,X incx rts NEXT_DIGIT incx ; Finished with this digit, move to the next cpx #6 ; Have we finished doing all 6? blo AGAIN ; No, go back and do the next one ; ; We are done! Let's append the results ; ldx BUF_POS ; Remember where we are in the output buffer lda CALC_DOLLAR_TENS; Get the tens digit beq NOTENOUT ; If not more than ten, just skip it bsr DO_APPEND ; Output the tens digit NOTENOUT lda CALC_DOLLAR_ONES; Output the ones digit bsr DO_APPEND lda #$32 ; Put a decimal point after it bsr DO_APPEND lda CALC_CENT_TENS ; Output the tens digit bsr DO_APPEND lda CALC_CENT_ONES ; Output the ones digit bsr DO_APPEND lda #C_SPACE ; Put in a trailing space bra DO_APPEND ;-------------------------------------------------------------------- MAIN: clra sta AMT_CENTS lda #15 ; Give them a default amount of $15.00 sta AMT_DOLLAR bset 7,WRISTAPP_FLAGS ; Tell the system that we want to be active rts ;--------------------------------------------------------------------- HANDLE_STATE1 bset 1,APP_FLAGS ; Allow our application to be suspended while idle. lda BTNSTATE cmp #EVT_USER0 ; Is this the initial entry? beq INIT_UPDN cmp #EVT_DNANY4 ; Did they press any of the buttons while in set mode? beq BUTTON_DOWN ; ; They released the button, so start a blink ; REPEAT_UP: bset 1,SYSFLAGS ; Show the current digit bra SET_DISPLAY ; ; They pressed a button, so start the update routine ; BUTTON_DOWN lda BTN_PRESSED cmp #EVT_SET bne TESTUPDN lda #EVT_USER2 ; Get us back to state 0 jmp POSTEVENT INIT_UPDN clr WHICH_DIGIT lda #S6_AMOUNT-START jsr PUT6TOP lda #S8_TIPCALC-START jsr BANNER8 TESTUPDN lda BTN_PRESSED cmp #EVT_NEXT beq GO_UP cmp #EVT_PREV beq GO_DOWN cmp #EVT_MODE beq SWITCH_DIGIT rts ; They must have hit the mode button SWITCH_DIGIT: lda WHICH_DIGIT inca and #1 sta WHICH_DIGIT bclr 1,SYSFLAGS ; Clear the current digit SET_DISPLAY jsr REFRESH_AMT lda #S6_AMOUNT-START jsr PUT6TOP lda #S8_TIPCALC-START jsr BANNER8 bsr BEGIN_BLINKING ; Make the blink routine display it bset 2,BTNFLAGS ; Mark a blink routine as pending rts GO_DOWN bclr 0,SYSFLAGS ; Mark update direction as down bra L0395 GO_UP bset 0,SYSFLAGS ; Mark update direction as up L0395: clra sta UPDATE_MIN lda #99 sta UPDATE_MAX lda WHICH_DIGIT beq L03a8 ldx #AMT_CENTS lda #UPD_MID34 bra L03b1 L03a8: ldx #AMT_DOLLAR lda #UPD_MID12 L03b1: jsr START_UPDATEP bset 4,BTNFLAGS rts BEGIN_BLINKING: lda WHICH_DIGIT beq L03e3 ldx #AMT_CENTS lda #BLINK_MID34 bra L03e7 L03e3: ldx #AMT_DOLLAR lda #BLINK_MID12 L03e7: jmp START_BLINKP