From ee33718ab57c5a041b55c70c0ae7e046b3d1592b Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Tue, 28 May 2019 12:09:03 +0100 Subject: general tidy up add all the timex apps and the toebes apps and numpad --- from_toebes/dayfind/dayfind.zsm | 375 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 375 insertions(+) create mode 100644 from_toebes/dayfind/dayfind.zsm (limited to 'from_toebes/dayfind/dayfind.zsm') diff --git a/from_toebes/dayfind/dayfind.zsm b/from_toebes/dayfind/dayfind.zsm new file mode 100644 index 0000000..8aaf43b --- /dev/null +++ b/from_toebes/dayfind/dayfind.zsm @@ -0,0 +1,375 @@ +;Name: Day Finder +;Version: DAYFIND +;Description: This will allow you to determine the date for a given day of the week and vice-versa. +;by John A. Toebes, VIII +; +;Press the prev/next buttons to advance by a single day. Press SET to access the ability to advance/backup by +;weeks, months, days, and years. The MODE button advances through those different states +; +;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 +B_CLEAR EQU 0 ; Bit 0 indicates that we need to clear the display first +B_SCANUP EQU 1 ; Bit 1 indicates that we are scanning up +B_SCANNING EQU 2 ; Bit 2 indicates that we are in a fake scanning mode +DIGSEL EQU $62 ; Indicates which digit we are working on + ; 0 = DAY OF WEEK + ; 1 = Month + ; 2 = Day + ; 3 = Year +YEAR_DIG1 EQU $63 ; This is the first digit of the year to blink (the tens digit) +YEAR_DIG2 EQU $64 ; This is the second digit of the year to blink (the ones digit) +COUNTER EQU $65 ; A convenient counter for us to advance a week at a time +; +; +; (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 +; +; (3) Program strings +S6_DAY timex6 "DAY " +S6_FIND timex6 " FIND" +S8_TOEBES timex "J.TOEBES" +S8_DAYFIND timex "DAY FIND" +S8_WEEK db C_LEFTARR + timex " WEEK " + db C_RIGHTARR +S8_MONTH db C_LEFTARR + timex "MONTH " + db C_RIGHTARR +S8_DAY db C_LEFTARR + timex " DAY " + db C_RIGHTARR +S8_YEAR db C_LEFTARR + timex " YEAR " + db C_RIGHTARR +; +; (4) State Table +; +STATETAB0: + db 0 + db EVT_ENTER,TIM1_4TIC,0 ; Initial state + db EVT_TIMER1,TIM_ONCE,0 ; The timer from the enter event + db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app + db EVT_MODE,TIM_ONCE,$FF ; Mode button + db EVT_SET,TIM_ONCE,1 ; SET button pressed + db EVT_DNNEXT,TIM2_8TIC,0 ; NEXT button pressed + db EVT_DNPREV,TIM2_8TIC,0 ; PREV button pressed + db EVT_UPANY4,TIM_ONCE,0 ; The + db EVT_TIMER2,TIM2_TIC,0 ; The timer for the next/prev button pressed + db EVT_END + +STATETAB1: + db 1 + db EVT_RESUME,TIM_ONCE,1 ; Resume from a nested app + db EVT_DNANY4,TIM_ONCE,1 ; NEXT, PREV, SET, MODE button pressed + db EVT_UPANY4,TIM_ONCE,1 ; NEXT, PREV, SET, MODE button released + db EVT_USER2,TIM_ONCE,0 + db EVT_USER3,TIM2_8TIC,1 ; + db EVT_TIMER2,TIM2_TIC,1 ; + db EVT_END +; +; (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_DNNEXT + beq DO_NEXT0 + cmp #EVT_DNPREV + beq DO_PREV0 + cmp #EVT_TIMER2 + beq DO_SCAN + cmp #EVT_ENTER ; Is this our initial entry? + bne REFRESH0 +; +; This is the initial event for starting us up +; +DO_ENTER +; +; (6) This code gets the current date from the system + + jsr ACQUIRE ; Lock so that it doesn't change under us + ldx #TZ1_MONTH ; Assume that we are using the first timezone + jsr CHECK_TZ ; See which one we are really using + bcc COPY_TZ1 ; If we were right, just skip on to do the work + ldx #TZ2_MONTH ; Wrong guess, just load up the second time zone +COPY_TZ1 + lda 0,x ; Copy out the month + sta SCAN_MONTH + lda 1,x ; Day + sta SCAN_DAY + lda 2,x ; and year + sta SCAN_YEAR + jsr RELEASE ; Unlock so the rest of the system is happy + + bclr B_CLEAR,FLAGBYTE ; Indicate that we need to clear the display + clr DIGSEL ; Start us off on the week advance + jsr CLEARSYM ; Clear the display + lda #S6_DAY-START + jsr PUT6TOP + lda #S6_FIND-START + jsr PUT6MID + lda #S8_TOEBES-START + jmp BANNER8 + +DO_SCAN + brclr B_SCANUP,FLAGBYTE,DO_PREV0 ; Were we scanning up or down? +DO_NEXT0 + bset B_SCANUP,FLAGBYTE ; We are now scanning up + jsr INCREMENT_SCAN_DATE ; Advance to the next date + bra SHOW_DATE ; Comment this out and use the next one if you want + ; jmp APPT_SHOW_SCAN ; to put the text 'SCAN' on the bottom when we are in scan mode + +DO_PREV0 + bclr B_SCANUP,FLAGBYTE ; We are now scanning down + jsr DECREMENT_SCAN_DATE ; Back up to the previous date + bra SHOW_DATE ; Show the date on the screen. + ; jmp APPT_SHOW_SCAN ; Use this if you want 'SCAN' on the bottom of the display +; +; We come here for a RESUME or TIMER2 event. For this we want to reset the display +; +REFRESH0 + brset B_CLEAR,FLAGBYTE,NOCLEAR0 ; Do we need to clear the display first? + bset B_CLEAR,FLAGBYTE ; Mark that the display has been cleared + jsr CLEARALL ; and do the work of clearing +NOCLEAR0 + lda #S8_DAYFIND-START ; Put up the name of the app on the display + jsr BANNER8 +SHOW_DATE + jsr APPT_SHOW_DATE ; Show the date on the screen + ldx SCAN_YEAR ; as well as the year + jmp PUTYEARMID +;-------------------------------------------------------------------------------- +; (7) State Table 1 Handler +; This is called to process the state events. +; We see SET, RESUME, USER3, TIMER2, DNANY4, and UPANY4 events +; We use the USER3 to trigger a delay which fires off a TIMER2 sequence of events. +; This allows us to have the PREV/NEXT buttons repeat for advancing the WEEK and YEAR +; since we can't use the UPDATE routines for them. +; +HANDLE_STATE1: + bset 1,APP_FLAGS ; Indicate that we can be suspended + lda BTNSTATE ; Get the event + cmp #EVT_TIMER2 ; Was it a timer for a repeat operation? + beq DO_UPD ; Yes, go handle it + cmp #EVT_USER3 ; Was it the USER3 event fired from the PREV/NEXT buttons? + bne TRY_UP ; No, try again + rts ; Yes, just ignore it, it will cause a timer to go off later +TRY_UP + bclr B_SCANNING,FLAGBYTE ; We can't be scanning any more, so turn it off + cmp #EVT_UPANY4 ; Was it any button being released? + bne TRY_DN ; No, try again + jmp REFRESH ; Yes, go refresh the screen (note that the branch is out of range) +TRY_DN + cmp #EVT_DNANY4 ; Is this our initial entry? + beq GET_DN ; No, try again + jmp FORCEFRESH ; Yes, go setup the screen (note that the branch is out of range) +GET_DN + 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 + lda #EVT_USER2 + jmp POSTEVENT +; +; (8) Our real working code... +; We come here when they press the next/prev buttons. if we are in a timer repeat +; situation (triggered when they press prev/next for the WEEK/YEAR) then we skip right +; to processing based on the button that was previously pressed +; +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 + lda DIGSEL ; Which digit mode are we in? + beq DO_UPD_DOW ; 0 - Handle the WEEK + cmp #2 + blo DO_UPD_MONTH ; <2 = 1 - Handle the MONTH + beq DO_UPD_DAY ; 2 - Handle the Day +DO_UPD_YEAR ; >2 = 3 - Handle the YEAR + brclr 0,SYSFLAGS,LASTYEAR ; Were we in the down direction? + ldx #99 ; Going up, let the WRAPX routine handle it for us + lda SCAN_YEAR + jsr INCA_WRAPX + bra SAVEYEAR +LASTYEAR + lda SCAN_YEAR ; Going down, get the year + deca ; Decrement it + bpl SAVEYEAR ; and see if we hit the lower end + lda #99 ; Yes, 2000 wraps down to 1999 +SAVEYEAR + sta SCAN_YEAR ; Save away the new year + bra SETUP_LAG ; And fire off an event to allow for repeating + +DO_UPD_DOW ; 0 - Day of week + lda #7 ; We want to iterate 7 times advancing by one day. + sta COUNTER ; (this makes it much easier to handle all the fringe cases) +WEEKLOOP + brclr 0,SYSFLAGS,LASTWEEK ; Are we going backwards? + jsr INCREMENT_SCAN_DATE ; Going forwards, advance by one day + bra WEEKLOOPCHK ; And continue the loop +LASTWEEK + jsr DECREMENT_SCAN_DATE ; Going backwards, retreat by one day +WEEKLOOPCHK + dec COUNTER ; Count down + tst COUNTER ; See if we hit the limit + bne WEEKLOOP ; and go back for more +; (9) Fake repeater +; This code is used for the Day of week and year modes where we want to have a +; repeating button, but the system routines won't handle it for us +; It works by posting a USER3 event which has a timer of about 1/2 second. +; After that timer expires, we get a timer2 event which then repeats every tic. +; The only thing that we have to worry about here is to not go through this +; every time so that it takes 1/2 second for every repeat. +SETUP_LAG + brset B_SCANNING,FLAGBYTE,INLAG ; If we were already scanning, skip out + bset B_SCANNING,FLAGBYTE ; Indicate that we are scanning + lda #EVT_USER3 ; and post the event to start it off + jsr POSTEVENT +INLAG + jmp SHOW_DATE ; Put the date up on the display +; (10) Update routine usage +DO_UPD_MONTH ; 1 - Handle the month + lda #MONTH_JAN ; The bottom end is January + sta UPDATE_MIN + lda #MONTH_DEC ; and the top end is December (INCLUSIVE) + sta UPDATE_MAX + lda #UPD_HMONTH ; We want the HALF-MONTH udpate function + ldx #SCAN_MONTH ; To update the SCAN_MONTH variable + bra SEL_UPD ; Go do it +DO_UPD_DAY ; 2 - Handle the day + lda #1 ; 1 is the first day of the month + sta UPDATE_MIN + jsr GET_SCAN_MONTHLEN ; Figure out how long the month is + sta UPDATE_MAX ; and make that the limit + lda #UPD_HDAY ; We want the HALF-DAY update function + ldx #SCAN_DAY ; to update the SCAN_DAY variable +SEL_UPD + jsr START_UPDATEP ; And prepare the update routine + bset 4,BTNFLAGS ; Mark that the update is now pending + rts +; (11) Making the mode button work +; when they press the mode button, we want to cycle through the various choices +; on the display. +DO_MODE + lda DIGSEL ; Figure out where we are in the cycle + inca ; advance to the next one + and #3 ; and wrap at 4 to zero + sta DIGSEL +REFRESH + brset B_CLEAR,FLAGBYTE,NOCLEAR ; Do we need to clear the display first? +FORCEFRESH + jsr CLEARALL ; Yes, clear everything before we start + bset B_CLEAR,FLAGBYTE ; And remember that we have already done that +NOCLEAR + clr BTNFLAGS ; Turn off any scrolling banners + lda #ROW_TD23 ; Turn off the dash from the week blink + sta DISP_ROW + bclr COL_TD23,DISP_COL + jsr SHOW_DATE ; Display the date +; (12) Establishing a blink routine +; This makes the appropriate section of the display blink based on what we are changing + lda DIGSEL ; Get the digit we are on + beq DO_BLINK_DOW ; 0 -> Update Day of week + cmp #2 + blo DO_BLINK_MONTH ; <2 = 1 -> Update month + beq DO_BLINK_DAY ; 2 - Update day of month + +DO_BLINK_YEAR ; 3: Year +; (13) Calling BLINK_SECOND +; For BLINK_SECONDS, the UPDATE_PARM points to the 2 character format for the year. + ldx SCAN_YEAR ; Get our year + jsr GETBCDHI ; And extract out the high digit of it + sta YEAR_DIG1 ; Save that away + ldx SCAN_YEAR ; Do it again + jsr GETBCDLOW ; to get the low digit + sta YEAR_DIG2 ; and save that away + ldx #YEAR_DIG1 ; the parm points to the first digit + lda #BLINK_SECONDS ; and we want a BLINK_SECONDS function + bra SETUP_BLINK ; so do it already + +DO_BLINK_DOW ; 0: Day of week: +; (14) Calling BLINK_SEGMENT +; Unfortunately, there is no blink routine to blink the upper two letters on the display. +; To get around this, I have chosen to blink a single segment on the display (the dash +; after the day of the week). This routine was designed to blink the AM/PM or other +; symbols, but it works quite fine for our purposed. You need to set UPDATE_POS to have +; the row to be updated and UPDATE_VAL holds the mask for the COLUMS to be XORed. +; In this way, you might have more than one segment blinking, but there are few segments +; on the same row which would achieve a reasonable effect. +; UPDATE_POS ROW_TD23 +; UPDATE_VAL (1<