summaryrefslogtreecommitdiffstats
path: root/from_toebes
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2019-05-28 12:09:03 +0100
committerfishsoupisgood <github@madingley.org>2019-05-28 12:09:03 +0100
commitee33718ab57c5a041b55c70c0ae7e046b3d1592b (patch)
tree118fa6880cb9f8d592516c5b40325f9b7448d0af /from_toebes
parent8110dec1577d9a9002119c15467d71d8a1f51bc8 (diff)
downloadwristapps-ee33718ab57c5a041b55c70c0ae7e046b3d1592b.tar.gz
wristapps-ee33718ab57c5a041b55c70c0ae7e046b3d1592b.tar.bz2
wristapps-ee33718ab57c5a041b55c70c0ae7e046b3d1592b.zip
general tidy up add all the timex apps and the toebes apps and numpad
Diffstat (limited to 'from_toebes')
l---------from_toebes/3ball/3ball.asm1
l---------from_toebes/3ball/3ball.known_good1
-rw-r--r--from_toebes/3ball/3ball.zap29
-rw-r--r--from_toebes/3ball/3ball.zsm148
-rw-r--r--from_toebes/Makefile46
-rw-r--r--from_toebes/datahid2/Data Hider App Beta.txt43
-rw-r--r--from_toebes/datahid2/datahid2.zap33
-rw-r--r--from_toebes/dayfind/dayfind.asm384
l---------from_toebes/dayfind/dayfind.known_good1
-rw-r--r--from_toebes/dayfind/dayfind.zap31
-rw-r--r--from_toebes/dayfind/dayfind.zsm375
l---------from_toebes/endoff/endoff.asm1
l---------from_toebes/endoff/endoff.known_good1
-rw-r--r--from_toebes/endoff/endoff.zap25
-rw-r--r--from_toebes/endoff/endoff.zsm145
l---------from_toebes/flash/flash.asm1
l---------from_toebes/flash/flash.known_good1
-rw-r--r--from_toebes/flash/flash.zap25
-rw-r--r--from_toebes/flash/flash.zsm135
l---------from_toebes/hello/hello.asm1
l---------from_toebes/hello/hello.known_good1
-rw-r--r--from_toebes/hello/hello.zap25
-rw-r--r--from_toebes/hello/hello.zsm83
l---------from_toebes/hexdump/hexdump.asm1
l---------from_toebes/hexdump/hexdump.known_good1
-rw-r--r--from_toebes/hexdump/hexdump.zap33
-rw-r--r--from_toebes/hexdump/hexdump.zsm322
l---------from_toebes/number/number.asm1
-rw-r--r--from_toebes/number/number.known_goodbin0 -> 147 bytes
-rw-r--r--from_toebes/number/number.zsm117
-rw-r--r--from_toebes/passwd/passwd.asm237
-rw-r--r--from_toebes/passwd/passwd.known_goodbin0 -> 337 bytes
-rw-r--r--from_toebes/passwd/passwd.zap25
-rw-r--r--from_toebes/passwd/passwd.zsm232
l---------from_toebes/pick6/pick6.asm1
l---------from_toebes/pick6/pick6.known_good1
-rw-r--r--from_toebes/pick6/pick6.zap33
-rw-r--r--from_toebes/pick6/pick6.zsm335
-rw-r--r--from_toebes/promdump/promdump.asm336
l---------from_toebes/promdump/promdump.known_good1
-rw-r--r--from_toebes/promdump/promdump.zap33
-rw-r--r--from_toebes/promdump/promdump.zsm336
-rw-r--r--from_toebes/shipbell/shipbell.asm176
l---------from_toebes/shipbell/shipbell.known_good1
-rw-r--r--from_toebes/shipbell/shipbell.zap27
-rw-r--r--from_toebes/shipbell/shipbell.zsm176
l---------from_toebes/sound1/sound1.asm1
-rw-r--r--from_toebes/sound1/sound1.known_goodbin0 -> 46 bytes
-rw-r--r--from_toebes/sound1/sound1.spcbin0 -> 50 bytes
-rw-r--r--from_toebes/sound1/sound1.zsm83
l---------from_toebes/spend0/spend0.asm1
l---------from_toebes/spend0/spend0.known_good1
-rw-r--r--from_toebes/spend0/spend0.zap37
-rw-r--r--from_toebes/spend0/spend0.zsm656
-rw-r--r--from_toebes/spend0/spendset.exebin0 -> 28160 bytes
-rw-r--r--from_toebes/testsnd/testsnd.asm155
l---------from_toebes/testsnd/testsnd.known_good1
-rw-r--r--from_toebes/testsnd/testsnd.zap26
-rw-r--r--from_toebes/testsnd/testsnd.zsm154
-rw-r--r--from_toebes/tipcalc/tipcalc1.zap35
l---------from_toebes/update/update.asm1
l---------from_toebes/update/update.known_good1
-rw-r--r--from_toebes/update/update.zap25
-rw-r--r--from_toebes/update/update.zsm133
64 files changed, 5271 insertions, 0 deletions
diff --git a/from_toebes/3ball/3ball.asm b/from_toebes/3ball/3ball.asm
new file mode 120000
index 0000000..c89f401
--- /dev/null
+++ b/from_toebes/3ball/3ball.asm
@@ -0,0 +1 @@
+3ball.zsm \ No newline at end of file
diff --git a/from_toebes/3ball/3ball.known_good b/from_toebes/3ball/3ball.known_good
new file mode 120000
index 0000000..81bd3de
--- /dev/null
+++ b/from_toebes/3ball/3ball.known_good
@@ -0,0 +1 @@
+3ball.zap.app \ No newline at end of file
diff --git a/from_toebes/3ball/3ball.zap b/from_toebes/3ball/3ball.zap
new file mode 100644
index 0000000..4dc2511
--- /dev/null
+++ b/from_toebes/3ball/3ball.zap
@@ -0,0 +1,29 @@
+TDL0831972¬
+3BALL¬
+3BALL¬
+An executive decision maker that will give a yes/no/maybe answer. Pressing Next will generate another answer and beep (since it will be the same answer sometimes).
+
+(c) 1997 Wayne Buttles (timex@fdisk.com). Compiled using tools and knowledge published by John A. Toebes, VIII and Michael Polymenakos (mpoly@panix.com).
+ Some enhancements by John Toebes...
+watchapp.hlp¬
+100¬
+none¬
+Timex Data Link 150 Watch¬
+CC01B2139081CC0188139081819D9DD6014D81CC015E00031D0B0A1313140A1B0B0E1D1B0E051D1D15001D1D1D1F001F1D1D1D2C2D2C2B2A2B22261D22001B85001AFF008085001FFF0001FFFF1D128F1390B691A1802737A11B2733A11A2706AD33A403B761BE61D60149CD587EA617CD58A8A648CC584CC604C1A1082684AE05B662CD6B0DB76297D60143CC587E3F62129020D9B660AE5542AB19B76049494981A6C0B796B627B76081¬
+22325¬
+0¬
+3BALL¬
+3BALL¬
+An executive decision maker that will give a yes/no/maybe answer. Pressing Next will generate another answer and beep (since it will be the same answer sometimes).
+
+(c) 1997 Wayne Buttles (timex@fdisk.com). Compiled using tools and knowledge published by John A. Toebes, VIII and Michael Polymenakos (mpoly@panix.com).
+ Some enhancements by John Toebes...
+watchapp.hlp¬
+100¬
+none¬
+Timex Data Link 150s Watch¬
+CC01B2139081CC0188139081819D9DD6014D81CC015E00031D0B0A1313140A1B0B0E1D1B0E051D1D15001D1D1D1F001F1D1D1D2C2D2C2B2A2B22261D22001B85001AFF008085001FFF0001FFFF1D128F1390B691A1802737A11B2733A11A2706AD33A403B761BE61D60149CD577FA617CD57A9A648CC574DC604C1A1082684AE05B662CD6B16B76297D60143CC577F3F62129020D9B660AE5542AB19B76049494981A6C0B796B627B76081¬
+52185¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/3ball/3ball.zsm b/from_toebes/3ball/3ball.zsm
new file mode 100644
index 0000000..e98b2d8
--- /dev/null
+++ b/from_toebes/3ball/3ball.zsm
@@ -0,0 +1,148 @@
+;Name: 3BALL
+;Version: 3BALL
+;Description: An executive decision maker that will give a yes/no/maybe answer. Pressing Next will generate another answer and beep (since it will be the same answer sometimes).
+;
+;(c) 1997 Wayne Buttles (timex@fdisk.com). Compiled using tools and knowledge published by John A. Toebes, VIII and Michael Polymenakos (mpoly@panix.com).
+; Some enhancements by John Toebes...
+;
+;HelpFile: watchapp.hlp
+;HelpTopic: 100
+;
+; (1) Program specific constants
+;
+ INCLUDE "WRISTAPP.I"
+;
+; Program specific constants
+;
+CURRENT_TIC EQU $27 ; Current system clock tic (Timer)
+LAST_ANS EQU $61
+RAND_SEED EQU $60
+MARQ_POS EQU $62
+START EQU *
+;
+; (2) System entry point vectors
+;
+L0110: jmp MAIN ; The main entry point - WRIST_MAIN
+L0113: bclr 1,BTNFLAGS ; Called when we are suspended for any reason - WRIST_SUSPEND
+ rts
+L0116: jmp FLASH ; Called to handle any timers or time events - WRIST_DOTIC
+L0119: bclr 1,BTNFLAGS ; Called when the COMM app starts and we have timers pending - WRIST_INCOMM
+ rts
+L011c: rts ; Called when the COMM app loads new data - WRIST_NEWDATA
+ nop
+ nop
+
+L011f: lda STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+;
+S6_MSG timex6 "3 BALL"
+S6_MAYBE timex6 "MAYBE"
+S6_YES timex6 " YES"
+S6_NO timex6 " NO"
+S6_MARQ timex6 " +O+ "
+
+MARQ_SEL
+ DB S6_MARQ+2-START
+ DB S6_MARQ+3-START
+ DB S6_MARQ+2-START
+ DB S6_MARQ+1-START
+ DB S6_MARQ-START
+ DB S6_MARQ+1-START
+
+MSG_SEL DB S6_YES-START
+ DB S6_NO-START
+ DB S6_MAYBE-START
+ DB S6_YES-START
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM2_16TIC,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_DNNEXT,TIM2_16TIC,0 ; Next button
+ db EVT_TIMER2,TIM_ONCE,0 ; Timer
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER, RESUME, TIMER2 and NEXT events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ bclr 1,BTNFLAGS
+ lda BTNSTATE
+ cmp #EVT_DNNEXT ; Did they press the next button?
+ beq DOITAGAIN
+ cmp #EVT_ENTER ; Or did we start out
+ beq DOITAGAIN
+ cmp #EVT_RESUME
+ beq REFRESH
+;
+; (6) Select a random answer
+;
+SHOWIT
+ bsr RAND
+ and #3 ; go to a 1 in 4 chance
+ sta LAST_ANS
+;
+; (7) Display the currently selected random number
+;
+REFRESH
+ ldx LAST_ANS ; Get the last answer we had, and use it as an index
+ lda MSG_SEL,X ; And get the message to display
+ jsr PUT6TOP ; Put that on the top
+BANNER
+ lda #S6_MSG-START
+ jsr PUT6MID
+ lda #SYS8_MODE ; And show the mode on the bottom
+ jmp PUTMSGBOT
+;
+; (8) This flashes the text on the screen
+;
+FLASH
+ lda CURRENT_APP ; See which app is currently running
+ cmp #APP_WRIST ; Is it us?
+ bne L0113 ; No, so just turn off the tic timer since we don't need it
+ ldx #5
+ lda MARQ_POS
+ jsr INCA_WRAPX
+ sta MARQ_POS
+ tax
+ lda MARQ_SEL,X
+ jmp PUT6TOP
+;
+; (9) They want us to do it again
+;
+DOITAGAIN ; Tell them we are going to do it again
+ clr MARQ_POS
+ bset 1,BTNFLAGS
+ bra BANNER
+;
+; (10) Here is a simple random number generator
+;
+RAND
+ lda RAND_SEED
+ ldx #85
+ mul
+ add #25
+ sta RAND_SEED
+ rola
+ rola
+ rola
+ rts
+;
+; (11) 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
+ lda CURRENT_TIC
+ sta RAND_SEED
+ rts
diff --git a/from_toebes/Makefile b/from_toebes/Makefile
new file mode 100644
index 0000000..93ce6f1
--- /dev/null
+++ b/from_toebes/Makefile
@@ -0,0 +1,46 @@
+TUTORIALS=hello number update flash passwd dayfind testsnd endoff hexdump promdump spend0 sound1 3ball shipbell pick6
+ZAPS=${wildcard */*.zap}
+#tipcalc
+#datahid2
+
+STAMPS=${foreach appdir,${TUTORIALS},${appdir}/${appdir}.stamp}
+APPS=${STAMPS:%.stamp=%.app}
+PS=${APPS:%.app=%.p}
+LSTS=${APPS:%.app=%.lst}
+HEX=${APPS:%.app=%.app.hex} ${APPS:%.app=%.known_good.hex}
+ZAPAPPS=${ZAPS:%.zap=%.zap.app}
+
+
+CROSS=../../asl/
+
+ZAP2APP=../tools/zap2app
+
+AFLAGS=-i ../include/dl150 -cpu datalink
+AS=${CROSS}asl ${AFLAGS}
+
+P2BIN=${CROSS}p2bin
+
+default:${STAMPS} ${APPS} ${ZAPAPPS}
+
+%.stamp:%.app.hex %.known_good.hex
+ diff -uN ${@:%.stamp=%.app.hex} ${@:%.stamp=%.known_good.hex} && touch $@
+
+
+${HEX}:${ZAPAPPS}
+
+%.hex:%
+ yes '' | dd bs=272 count=1 | cat - $< | hexdump -C > $@ || /bin/rm -f $@
+
+%.zap.app:%.zap
+ ${ZAP2APP} $< $@
+
+.PRECIOUS:${APPS}
+
+%.app:%.p
+ ${P2BIN} $< $@ -r 0x110-\$$
+
+%.p:%.asm
+ ${AS} -L ${@:%.p=%.lst} -o $@ $<
+
+clean:
+ /bin/rm -f ${APPS} ${PS} ${LSTS} ${HEX} ${STAMPS} ${ZAPAPPS}
diff --git a/from_toebes/datahid2/Data Hider App Beta.txt b/from_toebes/datahid2/Data Hider App Beta.txt
new file mode 100644
index 0000000..66a5bc5
--- /dev/null
+++ b/from_toebes/datahid2/Data Hider App Beta.txt
@@ -0,0 +1,43 @@
+From: John Toebes
+Sent: Saturday, April 12, 1997 2:23 PM
+To: 'datalink-developers@listproc.wsu.edu'
+Subject: Data Hider App Beta
+
+Hi all,
+ Here's another useful app which I am nearly finished with, but wanted
+people to have a chance to comment on it. What it does is allow you to
+protect the entries in your watch so that they can't be seen unless
+someone enters a password. The way it works is pretty simple:
+ Switch to the app. If the data is currently hidden, it says:
+ DATA
+ HIDDEN
+ J. TOEBES
+ Otherwise if you can actually see the phone numbers and list entries it
+says:
+ DATA
+ HIDER
+ J. TOEBES
+
+To hide the data on your watch, press the next button. Once you exit
+the app, you can't see any of the phone or list entries if they have
+been hidden. To get them back, just go back to the Data Hider app and
+press the SET button to enter the password. What password? Oh, the
+default one is 1234. Once you have entered the password, the note
+symbol will once again appear and allow you to unlock the entries. If
+the note symbol is visible, you can change the password to anything else
+by just pressing the SET button.
+
+Note that if you forget the password, there is no way to retrieve it (downloading another app will destroy where the password is stored!) or your entries.
+
+Possible enhancements:
+ 1) Add an automatic timeout to lock the watch after 1 minute
+ 2) Allow you to set the password before you download it to the watch
+ 3) Consider hiding the appointments and anniversaries. This has an
+unfortunate side effect that they won't go off (or at least I haven't
+figured out a way to trick the app into skipping them but still have
+them go off).
+
+
+---- John A. Toebes, VIII ---- toebes@southpeakcom
+Vice President Research and Development
+SouthPeak Interactive
diff --git a/from_toebes/datahid2/datahid2.zap b/from_toebes/datahid2/datahid2.zap
new file mode 100644
index 0000000..19a623c
--- /dev/null
+++ b/from_toebes/datahid2/datahid2.zap
@@ -0,0 +1,33 @@
+TDL0724962¬ Applet file header
+Data Hider¬ Applet friendly name
+DATAHID2¬ Applet version #
+Data Hider - by John A. Toebes, VIII
+
+To enter/set the password, press the set button.
+If the password has been entered, pressing the NEXT button will toggle between hidden and non-hidden mode.
+HINT: When the password is valid, the NOTE symbol will appear.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC01F5819D9D819D9D819D9DCC01F5D6015D81CC017F00CC01FE141D0D0A180A1D11010D0D0E1511010D0E171D0E15180E171D0C110A15100E190A1C1C20181B0D13321D180E0B0E1C00000C22001AFF001BFF0001FFFF02FF0100FF0038FFFF1D011AFF0186FF01A6FF0139FF001DB691A11B2735A10026453F613F620060171060C60109C70159C6010AC7015A4FC70109C7010A20270560241160C60159C70109C6015AC7010A20140160021560C604A1270A4FC704A1A638CD4E8981CD579FA61BCD587EA60EB71D016003056004181E2002191EA627016002A621CD58A8A641CC58451E963F613F623F6081128FB691A1862704129F2048C604C3A1022629046017B661C1015B261AB662C1015C2613146001600EAD60200AB661C7015BB662C7015CA639CC4E89C604C3A100274CA1032744A101270181B660A802B760139FCD579FCD595CCD5930BE61CD593ECD5910BE62CD593ECD5920A62D05600CC6015BB761C6015CB762A633CD587EA639CD5845AD25149081119F2002109F4FC704F4A663C704F5036006AE62A6072004AE61A605CD57C7189081036006AE62A6092004AE61A607CC55BF¬
+35029¬
+0¬ No data
+Data Hider¬ Applet friendly name
+DATAHID2¬ Applet version #
+Data Hider - by John A. Toebes, VIII
+
+To enter/set the password, press the set button.
+If the password has been entered, pressing the NEXT button will toggle between hidden and non-hidden mode.
+HINT: When the password is valid, the NOTE symbol will appear.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC01F5819D9D819D9D819D9DCC01F5D6015D81CC017F00CC01FE141D0D0A180A1D11010D0D0E1511010D0E171D0E15180E171D0C110A15100E190A1C1C20181B0D13321D180E0B0E1C00000C22001AFF001BFF0001FFFF02FF0100FF0038FFFF1D011AFF0186FF01A6FF0139FF001DB691A11B2735A10026453F613F620060171060C60109C70159C6010AC7015A4FC70109C7010A20270560241160C60159C70109C6015AC7010A20140160021560C604A1270A4FC704A1A638CD4E7881CD5ACBA61BCD577FA60EB71D016003056004181E2002191EA627016002A621CD57A9A641CC57461E963F613F623F6081128FB691A1862704129F2048C604C3A1022629046017B661C1015B261AB662C1015C2613146001600EAD60200AB661C7015BB662C7015CA639CC4E78C604C3A100274CA1032744A101270181B660A802B760139FCD5ACBCD585DCD5831BE61CD583FCD5811BE62CD583FCD5821A62D05600CC6015BB761C6015CB762A633CD577FA639CD5746AD25149081119F2002109F4FC704F4A663C704F5036006AE62A6072004AE61A605CD56C8189081036006AE62A6092004AE61A607CC55AE¬
+13022¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/dayfind/dayfind.asm b/from_toebes/dayfind/dayfind.asm
new file mode 100644
index 0000000..0cc1fcd
--- /dev/null
+++ b/from_toebes/dayfind/dayfind.asm
@@ -0,0 +1,384 @@
+;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<<COL_TD23)
+ lda #ROW_TD23
+; We want to blink the DASH after the day of week sta UPDATE_POS
+; Store the ROW for it in UPDATE_POS lda #(1<<COL_TD23)
+; Get the mask for the column sta UPDATE_VAL
+; And store that in UPDATE_VAL lda #BLINK_SEGMENT
+; We want a BLINK_SEGMENT function bra SETUP_BLINK
+; and get to it.
+
+ ; JMM this is missing from the published listing
+ sta UPDATE_POS
+ lda #2
+ sta UPDATE_VAL
+ lda #10
+ bra SETUP_BLINK
+ ; JMM end missing section
+
+DO_BLINK_MONTH ; 1: Month
+; (15) Calling BLINK_HMONTH, BLINK_HDAY
+; These are the normal boring cases of calling the blink routine. They simply need the
+; address of the byte holding the value to blink and the function to blink them with.
+; UPDATE_PARM - Points to the month
+ lda #BLINK_HMONTH ; We want a BLINK HALF-MONTH function
+ ldx #SCAN_MONTH ; to blink our month
+ bra SETUP_BLINK ; and do it
+
+DO_BLINK_DAY ; 2: Day
+; UPDATE_PARM - Points to the day
+ lda #BLINK_HDAY ; We want a BLINK HALF-DAY function
+ ldx #SCAN_DAY ; to blink our day
+
+SETUP_BLINK
+ jsr START_BLINKP ; Request the blink function
+ lda digsel ; Figure out which one we are blinking
+ lsla ; *2
+ lsla ; *4
+ lsla ; *8
+ add #S8_WEEK-START ; And use that to index the banner to put on the bottom
+ jsr BANNER8
+ bset 2,BTNFLAGS ; Mark a blink routine as pending
+ 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 FLAGBYTE ; start with a clean slate
+ rts
diff --git a/from_toebes/dayfind/dayfind.known_good b/from_toebes/dayfind/dayfind.known_good
new file mode 120000
index 0000000..c4cb2d1
--- /dev/null
+++ b/from_toebes/dayfind/dayfind.known_good
@@ -0,0 +1 @@
+dayfind.zap.app \ No newline at end of file
diff --git a/from_toebes/dayfind/dayfind.zap b/from_toebes/dayfind/dayfind.zap
new file mode 100644
index 0000000..d783fc3
--- /dev/null
+++ b/from_toebes/dayfind/dayfind.zap
@@ -0,0 +1,31 @@
+TDL0724962¬ Applet file header
+Day Find¬ Applet friendly name
+dayfind1¬ Applet version #
+This will allow you to determine the date for a given day of the week and vice-versa.
+
+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!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC02FE819D9D819D9D819D9D819D9DD6016581CC019600CC02001D0D0A1B1D1D1D0F01150D13321D180E0B0E1C0D0A22240F12170D3C24200E0E14243D3C1618171D11243D3C240D0A2224243D3C24220E0A1B243D001B03001EFF001AFF0001FFFF02FF01808300838300A6FF001F80001D011AFF0186FF01A6FF0139FF003A83011F80011D128FB691A180273FA1832742A11F2734A11B2641CD68E8AEB2CD690E2402AEBBF6B77AE601B77BE602B77CCD68F211613F62CD579FA61BCD587EA61FCD58A8A625CC58450361071261CD43B920141361CD43F4200D0061051061CD577AA62DCD5845CD7439BE7CCC59D9128FB691A11F272FA13A2601811561A1A62603CC02A6A1862703CC02A9C604C3A1032711A1002709A1012773A639CC4E89109F2002119FB662271DA102253B2749019F09AE63B67CCD6B0D2007B67C4A2A02A663B77C2015A607B765019F05CD43B92003CD43F43A653D6526EF0461071461A63ACD4E89CC01F8A601C704F4A60CC704F5A602AE7A200FA601C704F4CD43E0C704F5A604AE7BCD57C7189081B6624CA403B762006105CD577A10613F90A636B71D131ECD01F8B662271AA10225232727BE7CCD6B52B763BE7CCD6B5AB764AE63A6012017A636C704F3A602B7A6A60A200AA604AE7A2004A606AE7BCD55BFB662484848AB35CD5845149081A6C0B7963F6181¬
+22720¬
+0¬ No data
+Day Find¬ Applet friendly name
+dayfind2¬ Applet version #
+This will allow you to determine the date for a given day of the week and vice-versa.
+
+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!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC02FE819D9D819D9D819D9D819D9DD6016581CC019600CC02001D0D0A1B1D1D1D0F01150D13321D180E0B0E1C0D0A22240F12170D3C24200E0E14243D3C1618171D11243D3C240D0A2224243D3C24220E0A1B243D001B03001EFF001AFF0001FFFF02FF01808300838300A6FF001F80001D011AFF0186FF01A6FF0139FF003A83011F80011D128FB691A180273FA1832742A11F2734A11B2641CD68F1AEB2CD69172402AEBBF6B77AE601B77BE602B77CCD68FB11613F62CD5ACBA61BCD577FA61FCD57A9A625CC57460361071261CD43A820141361CD43E3200D0061051061CD5AA0A62DCD5746CD7442BE7CCC58DA128FB691A11F272FA13A2601811561A1A62603CC02A6A1862703CC02A9C604C3A1032711A1002709A1012773A639CC4E78109F2002119FB662271DA102253B2749019F09AE63B67CCD6B162007B67C4A2A02A663B77C2015A607B765019F05CD43A82003CD43E33A653D6526EF0461071461A63ACD4E78CC01F8A601C704F4A60CC704F5A602AE7A200FA601C704F4CD43CFC704F5A604AE7BCD56C8189081B6624CA403B762006105CD5AA010613F90A634B71D131ECD01F8B662271AA10225232727BE7CCD6B5BB763BE7CCD6B63B764AE63A6012017A634C704F3A602B7A6A60A200AA604AE7A2004A606AE7BCD55AEB662484848AB35CD5746149081A6C0B7963F6181¬
+63729¬
+0¬ No data \ No newline at end of file
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<<COL_TD23)
+ lda #ROW_TD23
+; We want to blink the DASH after the day of week sta UPDATE_POS
+; Store the ROW for it in UPDATE_POS lda #(1<<COL_TD23)
+; Get the mask for the column sta UPDATE_VAL
+; And store that in UPDATE_VAL lda #BLINK_SEGMENT
+; We want a BLINK_SEGMENT function bra SETUP_BLINK
+; and get to it.
+DO_BLINK_MONTH ; 1: Month
+; (15) Calling BLINK_HMONTH, BLINK_HDAY
+; These are the normal boring cases of calling the blink routine. They simply need the
+; address of the byte holding the value to blink and the function to blink them with.
+; UPDATE_PARM - Points to the month
+ lda #BLINK_HMONTH ; We want a BLINK HALF-MONTH function
+ ldx #SCAN_MONTH ; to blink our month
+ bra SETUP_BLINK ; and do it
+
+DO_BLINK_DAY ; 2: Day
+; UPDATE_PARM - Points to the day
+ lda #BLINK_HDAY ; We want a BLINK HALF-DAY function
+ ldx #SCAN_DAY ; to blink our day
+
+SETUP_BLINK
+ jsr START_BLINKP ; Request the blink function
+ lda digsel ; Figure out which one we are blinking
+ lsla ; *2
+ lsla ; *4
+ lsla ; *8
+ add #S8_WEEK-START ; And use that to index the banner to put on the bottom
+ jsr BANNER8
+ bset 2,BTNFLAGS ; Mark a blink routine as pending
+ 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 FLAGBYTE ; start with a clean slate
+ rts
diff --git a/from_toebes/endoff/endoff.asm b/from_toebes/endoff/endoff.asm
new file mode 120000
index 0000000..89a74ed
--- /dev/null
+++ b/from_toebes/endoff/endoff.asm
@@ -0,0 +1 @@
+endoff.zsm \ No newline at end of file
diff --git a/from_toebes/endoff/endoff.known_good b/from_toebes/endoff/endoff.known_good
new file mode 120000
index 0000000..534c7c5
--- /dev/null
+++ b/from_toebes/endoff/endoff.known_good
@@ -0,0 +1 @@
+endoff.zap.app \ No newline at end of file
diff --git a/from_toebes/endoff/endoff.zap b/from_toebes/endoff/endoff.zap
new file mode 100644
index 0000000..31409f0
--- /dev/null
+++ b/from_toebes/endoff/endoff.zap
@@ -0,0 +1,25 @@
+TDL0724962¬ Applet file header
+Week End Off¬ Applet friendly name
+ENDOFF1¬ Applet version #
+This application turns off all alarms on the weekend.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC0169819D9DCC016FCC0182CC016FD6013B81CC0146001D1A0E0E111D0E150D000F0F13321D180E0B0E1C001B84001AFF0001FFFF1D128FCD577AA617CD587EA61DCD58A8A61CB71D131EA620B71D121ECD016FA623CC58451E96A6C8B796CD68E8B6B8CD690E2402B6C1CD68F2A1052413AE04E669444444A401EA69A407E7695A2AF081AE04E669A401484848EA69A40EE7695A2AF081¬
+42704¬
+0¬ No data
+Week End Off¬ Applet friendly name
+ENDOFF2¬ Applet version #
+This application turns off all alarms on the weekend.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC0169819D9DCC016FCC0182CC016FD6013B81CC0146001D1A0E0E111D0E150D000F0F13321D180E0B0E1C001B84001AFF0001FFFF1D128FCD5AA0A617CD577FA61DCD57A9A61AB71D131EA61EB71D121ECD016FA623CC57461E96A6C8B796CD68F1B6B8CD69172402B6C1CD68FBA1052413AE04E669444444A401EA69A407E7695A2AF081AE04E669A401484848EA69A40EE7695A2AF081¬
+9447¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/endoff/endoff.zsm b/from_toebes/endoff/endoff.zsm
new file mode 100644
index 0000000..8caba23
--- /dev/null
+++ b/from_toebes/endoff/endoff.zsm
@@ -0,0 +1,145 @@
+;Name: Week End Off
+;Version: ENDOFF
+;Description: Week End Off - by John A. Toebes, VIII
+;This application turns off all alarms on the weekend.
+;
+;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
+;
+START EQU *
+;
+; (2) System entry point vectors
+;
+L0110: jmp MAIN ; The main entry point - WRIST_MAIN
+L0113: rts ; Called when we are suspended for any reason - WRIST_SUSPEND
+ nop
+ nop
+L0116: jmp CHECKSTATE ; Called to handle any timers or time events - WRIST_DOTIC
+L0119: jmp ENABLE_ALL ; Called when the COMM app starts and we have timers pending - WRIST_INCOMM
+L011c: jmp CHECKSTATE ; Called when the COMM app loads new data - WRIST_NEWDATA
+
+L011f: lda STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+;
+S6_WEEK: timex6 " WEEH "
+S6_ENDOFF: timex6 "ENDOFF"
+S8_TOEBES: timex "J.TOEBES"
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM_LONG,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER and RESUME events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Allow us to be suspended
+ jsr CLEARALL ; Clear the display
+ lda #S6_WEEK-START ; Put ' WEEK ' on the top line
+ jsr PUT6TOP
+ lda #S6_ENDOFF-START ; Put 'ENDOFF' on the second line
+ jsr PUT6MID
+;
+; (6) Faking a letter K
+;
+;
+; We have We want it to look like:
+; | | |
+; | | | |
+; | | | |
+; |=====| |=====
+; | | | |
+; | | | |
+; | | | |
+; This means turning off T5B and turning on T5H
+ lda #ROW_T5B
+ sta DISP_ROW
+ bclr COL_T5B,DISP_COL
+ lda #ROW_T5H
+ sta DISP_ROW
+ bset COL_T5H,DISP_COL
+ jsr CHECKSTATE ; Just for fun, check the alarm state
+ lda #S8_TOEBES-START
+ jmp BANNER8
+;
+; (7) This is the main initialization routine which is called when we first get the app into memory
+;
+MAIN:
+ bset 7,WRISTAPP_FLAGS ; Tell them that we are a live application
+ lda #$C8 ; Bit3 = wristapp wants a call once a day when it changes (WRIST_DOTIC) (SET=CALL)
+ ; Bit6 = Uses system rules for button beep decisions (SET=SYSTEM RULES)
+ ; Bit7 = Wristapp has been loaded (SET=LOADED)
+ sta WRISTAPP_FLAGS
+ ; Fall into CHECKSTATE
+;
+; (8) Determining the day of the week
+;
+CHECKSTATE
+ jsr ACQUIRE ; Lock so that it doesn't change under us
+ lda TZ1_DOW ; Assume that we are using the first timezone
+ jsr CHECK_TZ ; See which one we are really using
+ bcc GOT_TZ1 ; If we were right, just skip on to do the work
+ lda TZ2_DOW ; Wrong guess, just load up the second time zone
+GOT_TZ1
+ jsr RELEASE ; Unlock so the rest of the system is happy
+ cmp #5 ; Time zone day of week is 0=Monday...6=Sunday
+ bhs DISABLE_ALL ; Saturday, Sunday - disable them all
+ ; Fall into ENABLE_ALL
+;---------------------------------------------------------------
+; Routine:
+; (9) ENABLE_ALL/DISABLE_ALL
+; Parameters:
+; NONE
+; Purpose:
+; These routines enable/disable all of the alarms. It hides the disabled status of
+; the alarm by storing it in bit 3 of the alarm flags.
+; Bit0 = Alarm is enabled (SET=ENABLED)
+; Bit1 = Alarm is masked (SET=MASKED)
+; Bit2 = Current alarm is in 12 hour mode and is in the afternoon (SET=AFTERNOON)
+; Bit3 = Alarm was enabled, but we are hiding it (SET=HIDDEN)
+; It is safe to call these routine multiple times.
+;---------------------------------------------------------------
+ENABLE_ALL
+ ldx #4 ; We have 5 alarms to go through
+ENABLE_NEXT
+ lda ALARM_STATUS,X ; Get the flags for this alarm
+ lsra ; Shift right 3 to get our hidden bit into place
+ lsra
+ lsra
+ and #1 ; Mask out everything except the hidden bit (now in the enabled position
+ ora ALARM_STATUS,X ; Or it back into the flags
+ and #7 ; and clear out our hidden bit
+ sta ALARM_STATUS,X ; then save it out again.
+ decx ; Count down the number of alarms
+ bpl ENABLE_NEXT ; And go back for the next one
+ rts
+
+DISABLE_ALL
+ ldx #4 ; We have 5 alarms to go through
+DISABLE_NEXT
+ lda ALARM_STATUS,X ; Get the flags for this alarm
+ and #1 ; And extract our enabled bit
+ lsla ; Shift left 3 to save as our hidden bit
+ lsla
+ lsla
+ ora ALARM_STATUS,X ; Or it back into the flags
+ and #$0e ; and clear out the enabled bit
+ sta ALARM_STATUS,X ; then save it out again.
+ decx ; Count down the number of alarms
+ bpl DISABLE_NEXT ; And go back for the next one
+ rts
diff --git a/from_toebes/flash/flash.asm b/from_toebes/flash/flash.asm
new file mode 120000
index 0000000..ac2ecb7
--- /dev/null
+++ b/from_toebes/flash/flash.asm
@@ -0,0 +1 @@
+flash.zsm \ No newline at end of file
diff --git a/from_toebes/flash/flash.known_good b/from_toebes/flash/flash.known_good
new file mode 120000
index 0000000..69e7579
--- /dev/null
+++ b/from_toebes/flash/flash.known_good
@@ -0,0 +1 @@
+flash.zap.app \ No newline at end of file
diff --git a/from_toebes/flash/flash.zap b/from_toebes/flash/flash.zap
new file mode 100644
index 0000000..22642f7
--- /dev/null
+++ b/from_toebes/flash/flash.zap
@@ -0,0 +1,25 @@
+TDL0724962¬ Applet file header
+Update/Flash Sample¬ Applet friendly name
+blink1¬ Applet version #
+This is a simple number blink/update program
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC01AB819D9D819D9D819D9D819D9DD6013381CC0147000F130A05111D050A1416130E001B83001FFF001AFF0001FFFF86FF00A6FF001D128FB691A186260FC604C3A1032724A100271CA1022737A11B26381361CD579FA617CD587EA61DCD58A8A648CC584C109F2002119F4FC704F4A663C704F5AE62A607CD57C718901361A650CC584C3F62026105CD577A12611F90AE62A609CD55BF149081A6C0B7963F613F6281¬
+52411¬
+0¬ No data
+Update/Flash Sample¬ Applet friendly name
+blink2¬ Applet version #
+This is a simple number blink/update program
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC01AB819D9D819D9D819D9D819D9DD6013381CC0147000F130A05111D050A1416130E001B83001FFF001AFF0001FFFF86FF00A6FF001D128FB691A186260FC604C3A1032724A100271CA1022737A11B26381361CD5ACBA617CD577FA61DCD57A9A648CC574D109F2002119F4FC704F4A663C704F5AE62A607CD56C818901361A650CC574D3F62026105CD5AA012611F90AE62A609CD55AE149081A6C0B7963F613F6281¬
+36065¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/flash/flash.zsm b/from_toebes/flash/flash.zsm
new file mode 100644
index 0000000..33208b7
--- /dev/null
+++ b/from_toebes/flash/flash.zsm
@@ -0,0 +1,135 @@
+;Name: Flash
+;Version: FLASH
+;Description: by John A. Toebes, VIII
+;This is a simple number update/flash program
+;
+;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 1 indicates that we need to clear the display first
+;
+CURVAL EQU $62 ; The current value we are displaying
+;
+; (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 STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+S6_FLASH: timex6 "FLASH "
+S6_SAMPLE: timex6 "SAMPLE"
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM_2_8TIC,0 ; Initial state
+ db EVT_TIMER2,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_DNANY4,TIM_ONCE,0 ; NEXT, PREV, SET, MODE button pressed
+ db EVT_UPANY4,TIM_ONCE,0 ; NEXT, PREV, SET, MODE button released
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER, TIMER2, RESUME, DNANY4 and UPANY4 events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_DNANY4 ; Did they press a button?
+ bne CHKENTER ; No, pass on to see what else there might be
+ 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_SET ; Perhaps the SET button
+ beq DO_SET ; If so, handle it
+ ; In reality, we can't reach here since we handled all three buttons
+ ; in the above code (the MODE button is handled before we get here and the
+ ; GLOW button doesn't send in an event for this). We can just fall through
+ ; and take whatever we get from it.
+CHKENTER
+ cmp #EVT_ENTER ; Is this our initial entry?
+ bne REFRESH
+;
+; This is the initial event for starting us
+;
+DO_ENTER
+ bclr 1,FLAGBYTE ; Indicate that we need to clear the display
+ jsr CLEARSYM ; Clear the display
+ lda #S6_FLASH-START
+ jsr PUT6TOP
+ lda #S6_SAMPLE-START
+ jsr PUT6MID
+ lda #SYS8_MODE
+ jmp PUTMSGBOT
+;
+; (6) Our real working code...
+
+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 #99
+ sta UPDATE_MAX ; and the high end is 99 (the max since this is a 2 digit value)
+ ldx #CURVAL ; Point to our value to be updated
+ lda #UPD_MID34 ; Request updating in the middle of the display
+ jsr START_UPDATEP ; And prepare the update routine
+ bset 4,BTNFLAGS ; Mark that the update is now pending
+ bclr 1,FLAGBYTE
+ lda #SYS8_SET_MODE
+ jmp PUTMSGBOT
+
+DO_SET
+ clr CURVAL ; When they hit the set button, we just clear to zero
+SHOWVAL
+ brset 1,FLAGBYTE,NOCLEAR ; Do we need to clear the display first?
+REFRESH
+ jsr CLEARALL ; Yes, clear everything before we start
+ bset 1,FLAGBYTE ; And remember that we have already done that
+NOCLEAR
+ bclr 7,BTNFLAGS ; Turn off any update routine that might be pending
+ ldx #CURVAL
+ lda #BLINK_MID34
+ jsr START_BLINKP
+ bset 2,BTNFLAGS ; Mark a blink routine as pending
+ rts
+;
+; (7) 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 FLAGBYTE ; start with a clean slate
+ clr CURVAL
+ rts
diff --git a/from_toebes/hello/hello.asm b/from_toebes/hello/hello.asm
new file mode 120000
index 0000000..759fddf
--- /dev/null
+++ b/from_toebes/hello/hello.asm
@@ -0,0 +1 @@
+hello.zsm \ No newline at end of file
diff --git a/from_toebes/hello/hello.known_good b/from_toebes/hello/hello.known_good
new file mode 120000
index 0000000..c74403e
--- /dev/null
+++ b/from_toebes/hello/hello.known_good
@@ -0,0 +1 @@
+hello.zap.app \ No newline at end of file
diff --git a/from_toebes/hello/hello.zap b/from_toebes/hello/hello.zap
new file mode 100644
index 0000000..f1fbea3
--- /dev/null
+++ b/from_toebes/hello/hello.zap
@@ -0,0 +1,25 @@
+TDL0724962¬ Applet file header
+Hello World¬ Applet friendly name
+HELLO1¬ Applet version #
+This Hex dump routine is a simple thing to test out dumping hex bytes...
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC016A819D9D819D9D819D9D819D9DD6013381CC014100110E1313001D1A0017130D1D001BFF001AFF0080FF0001FFFF1D128FB691A180271A1161016103CC5776CD577AA617CD587EA61DCD58A8A648CC584C0061E3106120E1A6C0B7963F6181¬
+28942¬
+0¬ No data
+Hello World¬ Applet friendly name
+HELLO2¬ Applet version #
+This Hex dump routine is a simple thing to test out dumping hex bytes...
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC016A819D9D819D9D819D9D819D9DD6013381CC014100110E1313001D1A0017130D1D001BFF001AFF0080FF0001FFFF1D128FB691A180271A1161016103CC5A9CCD5AA0A617CD577FA61DCD57A9A648CC574D0061E3106120E1A6C0B7963F6181¬
+16378¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/hello/hello.zsm b/from_toebes/hello/hello.zsm
new file mode 100644
index 0000000..93d4d40
--- /dev/null
+++ b/from_toebes/hello/hello.zsm
@@ -0,0 +1,83 @@
+;Name: Hello World
+;Version: HELLO
+;Description: This is a simple Hello Program
+;by John A. Toebes, VIII
+;
+;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 that we want to show the segments instead of the message
+;
+START EQU *
+;
+; (2) System entry point vectors
+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 STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+S6_HELLO: timex6 "HELLO "
+S6_WORLD: timex6 "WORLD "
+;
+; (4) State Table
+; (4) State Table
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM_ONCE,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_DNNEXT,TIM_ONCE,0 ; Next button
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events. We only see ENTER, RESUME, and DNNEXT events
+;
+HANDLE_STATE0:
+ bset 1,$8f ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_DNNEXT ; Did they press the next button?
+ beq DOTOGGLE ; Yes, toggle what we are displaying
+CLEARIT bclr 0,FLAGBYTE ; Start us in the show display state
+REFRESH brclr 0,FLAGBYTE,SHOWDISP ; Do we want to see the main display?
+ jmp SETALL ; No, just turn on all segments
+SHOWDISP jsr CLEARALL ; Clear the display
+ lda #S6_HELLO-START ; Get the offset for the first string
+ jsr PUT6TOP ; And send it to the top line
+ lda #S6_WORLD-START ; Get the offset for the second string
+ jsr PUT6MID ; and put it on the middle line
+ lda #SYS8_MODE ; Get the system offset for the 'MODE' string
+ jmp PUTMSGBOT ; and put it on the bottom line
+;
+; (6) Our only real piece of working code...
+DOTOGGLE brset 0,FLAGBYTE,CLEARIT ; If it is set, just jump to clear it like normal
+ bset 0,FLAGBYTE ; Already clear, so set it
+ bra REFRESH ; and let the refresh code handle it
+;
+; (7) 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 $96
+ clr FLAGBYTE ; start with a clean slate
+ rts
diff --git a/from_toebes/hexdump/hexdump.asm b/from_toebes/hexdump/hexdump.asm
new file mode 120000
index 0000000..a0e08a7
--- /dev/null
+++ b/from_toebes/hexdump/hexdump.asm
@@ -0,0 +1 @@
+hexdump.zsm \ No newline at end of file
diff --git a/from_toebes/hexdump/hexdump.known_good b/from_toebes/hexdump/hexdump.known_good
new file mode 120000
index 0000000..7d565b2
--- /dev/null
+++ b/from_toebes/hexdump/hexdump.known_good
@@ -0,0 +1 @@
+hexdump.zap.app \ No newline at end of file
diff --git a/from_toebes/hexdump/hexdump.zap b/from_toebes/hexdump/hexdump.zap
new file mode 100644
index 0000000..f445e28
--- /dev/null
+++ b/from_toebes/hexdump/hexdump.zap
@@ -0,0 +1,33 @@
+TDL0706972¬
+Hex Dump¬
+HEXDUMP¬
+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!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150 Watch¬
+CC029E819D9D819D9D819D9D819D9DD6014381CC017300CC01A01ACC0223221D0B1B180E1D0D1914160E170A0A0A0A24242424001B84001AFF001FFF0080830183830101FFFF02FF0237FFFF1D00A5FF001F80011D021AFF0286FF02A6FF0239FF001D128FB691A11B2658CD577AA61FCD587EA625CD58A8A648CC584CD7013BA40FD7013CD6013B44444444D7013B81B691A11F27081161A18326021061016112C60213A006C70213C60212A200C702122010A606CB0213C70213C60212A900C70212CD579F5FAD38CD58E0AE01AD31CD58F0AE02AD2ACD5900AE03AD23CD5910AE04AD1CCD5920AE05AD15CD5930C602125FAD88C60213AE02AD81A62BCC5845D64000B7A344444444B7A2B6A3A40FB7A381128FB691A1A6273AA186264CC604C3A1032713A100270BA1012720AD93A639CC4E89109F2002119F4FC704F4A60FC704F5AD3FA608CD57C7189081B6624CA403B762B66348484848BB64C70212B66548484848BB66C702131F90CD01D3AE045AD6013BE7635D26F7AD08A60BCD55BF149081B662C704F3AB639781A6C0B7963F6281¬
+27941¬
+0¬
+Hex Dump¬
+HEXDUMP¬
+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!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150s Watch¬
+CC029E819D9D819D9D819D9D819D9DD6014381CC017300CC01A01ACC0223221D0B1B180E1D0D1914160E170A0A0A0A24242424001B84001AFF001FFF0080830183830101FFFF02FF0237FFFF1D00A5FF001F80011D021AFF0286FF02A6FF0239FF001D128FB691A11B2658CD5AA0A61FCD577FA625CD57A9A648CC574DD7013BA40FD7013CD6013B44444444D7013B81B691A11F27081161A18326021061016112C60213A006C70213C60212A200C702122010A606CB0213C70213C60212A900C70212CD5ACB5FAD38CD57E1AE01AD31CD57F1AE02AD2ACD5801AE03AD23CD5811AE04AD1CCD5821AE05AD15CD5831C602125FAD88C60213AE02AD81A62BCC5746D64000B7A344444444B7A2B6A3A40FB7A381128FB691A1A6273AA186264CC604C3A1032713A100270BA1012720AD93A639CC4E78109F2002119F4FC704F4A60FC704F5AD3FA608CD56C8189081B6624CA403B762B66348484848BB64C70212B66548484848BB66C702131F90CD01D3AE045AD6013BE7635D26F7AD08A60BCD55AE149081B662C704F3AB639781A6C0B7963F6281¬
+35880¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/hexdump/hexdump.zsm b/from_toebes/hexdump/hexdump.zsm
new file mode 100644
index 0000000..cf243d3
--- /dev/null
+++ b/from_toebes/hexdump/hexdump.zsm
@@ -0,0 +1,322 @@
+;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
diff --git a/from_toebes/number/number.asm b/from_toebes/number/number.asm
new file mode 120000
index 0000000..7adff04
--- /dev/null
+++ b/from_toebes/number/number.asm
@@ -0,0 +1 @@
+number.zsm \ No newline at end of file
diff --git a/from_toebes/number/number.known_good b/from_toebes/number/number.known_good
new file mode 100644
index 0000000..10b989e
--- /dev/null
+++ b/from_toebes/number/number.known_good
Binary files differ
diff --git a/from_toebes/number/number.zsm b/from_toebes/number/number.zsm
new file mode 100644
index 0000000..a779467
--- /dev/null
+++ b/from_toebes/number/number.zsm
@@ -0,0 +1,117 @@
+;Name: Numbers
+;Version: NUMBER
+;Description: This is a simple number count program
+;by John A. Toebes, VIII
+;
+;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 that we want to show the segments instead of the message
+;
+CURVAL EQU $62 ; The current value we are displaying
+START EQU *
+;
+; (2) System entry point vectors
+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 STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+S6_NUMBER: timex6 "NUMBER"
+S6_COUNT: timex6 "COUNT "
+;
+; (4) State Table
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM2_8TIC,0 ; Initial state
+ db EVT_TIMER2,TIM_ONCE,0 ; The timer from the enter event
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_DNNEXT,TIM_ONCE,0 ; Next button
+ db EVT_DNPREV,TIM_ONCE,0 ; Prev button
+ db EVT_DNSET,TIM_ONCE,0 ; Set button
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events. We will see ENTER, RESUME, DNNEXT, DNPREV, DNSET, and TIMER2
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_DNNEXT ; Did they press the next button?
+ beq DO_NEXT ; Yes, increment the counter
+ cmp #EVT_DNPREV ; How about the PREV button
+ beq DO_PREV ; handle it
+ cmp #EVT_DNSET ; Maybe the set button?
+ beq DO_SET ; Deal with it!
+ cmp #EVT_ENTER ; Is this our initial entry?
+ bne REFRESH
+;
+; This is the initial event for starting us
+;
+DO_ENTER
+ bclr 1,FLAGBYTE ; Indicate that we need to clear the display
+ jsr CLEARSYM ; Clear the display
+ lda #S6_NUMBER-START
+ jsr PUT6TOP
+ lda #S6_COUNT-START
+ jsr PUT6MID
+ lda #SYS8_MODE
+ jmp PUTMSGBOT
+;
+; (6) Our only real working code...
+DO_NEXT
+ inc CURVAL
+ lda CURVAL
+ cmp #100
+ bne SHOWVAL
+DO_SET
+ clr CURVAL
+SHOWVAL
+ brset 1,FLAGBYTE,NOCLEAR
+REFRESH
+ jsr CLEARALL
+ bset 1,FLAGBYTE
+NOCLEAR
+ ldx CURVAL
+ jsr FMTXLEAD0
+ jmp PUTMID34
+DO_PREV
+ lda CURVAL
+ beq WRAPUP
+ dec CURVAL
+ bra SHOWVAL
+WRAPUP
+ lda #99
+ sta CURVAL
+ bra SHOWVAL
+;
+; (7) 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 FLAGBYTE ; start with a clean slate
+ clr CURVAL
+ rts
diff --git a/from_toebes/passwd/passwd.asm b/from_toebes/passwd/passwd.asm
new file mode 100644
index 0000000..26ea9bf
--- /dev/null
+++ b/from_toebes/passwd/passwd.asm
@@ -0,0 +1,237 @@
+;Name: Password
+;Version: PASSWD
+;Description: This is a simple number update/passwd program
+;by John A. Toebes, VIII
+;
+;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 which digit we are working on (SET=SECOND DIGIT)
+; Bit 1 indicates that we need to clear the display first
+;
+DIGIT0 EQU $62 ; The first digit to enter
+DIGIT1 EQU $63 ; The second digit to enter
+;SYSTEMP0 EQU $A0
+;SYSTEMP1 EQU $A1
+;
+; (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_TOEBES: timex6 "TOEBES"
+S6_SAMPLE: timex6 "SAMPLE"
+S6_PRESS: timex6 "PRESS "
+S8_PASSWORD: timex "PASSWORD"
+SX_MESSAGE timex "BY JOHN A. TOEBES, VIII"
+ db SEPARATOR
+;
+; (4) State Table
+;
+STATETAB0:
+ db 0
+ db EVT_ENTER,TIM_2_8TIC,0 ; Initial state
+ db EVT_TIMER2,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_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_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_ENTER ; Is this our initial entry?
+ bne REFRESH0
+;
+; This is the initial event for starting us
+;
+DO_ENTER
+ bclr 1,FLAGBYTE ; Indicate that we need to clear the display
+ jsr CLEARSYM ; Clear the display
+ lda #S6_TOEBES-START
+ jsr PUT6TOP
+ lda #S6_SAMPLE-START
+ jsr PUT6MID
+ ; JMM the original had
+ ; lda #S8_PASSWORD
+ ; JMM this doesn't work on my hardware and I think it's a bug,
+ ; JMM instead
+ lda #S8_PASSWORD-START
+ ; JMM WFM
+ jmp BANNER8
+;
+; We come here for a RESUME or TIMER2 event. For this we want to reset the display
+;
+REFRESH0
+ brset 1,FLAGBYTE,NOCLEAR0 ; Do we need to clear the display first?
+ bset 1,FLAGBYTE
+ jsr CLEARSYM
+NOCLEAR0
+ lda #S6_PRESS-START
+ jsr PUT6TOP
+ lda #SYS6_SET
+ jsr PUTMSG2
+ lda #SX_MESSAGE-START
+ jmp SETUP_SCROLL
+;
+; (6) State Table 1 Handler
+; This is called to process the state events.
+; We see SET, RESUME, DNANY4, and UPANY4 events
+;
+HANDLE_STATE1:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_UPANY4
+ beq REFRESH
+ 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
+ lda #EVT_USER2
+ jmp POSTEVENT
+;
+; (7) Our real working code...
+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 #99
+ sta UPDATE_MAX ; and the high end is 99 (the max since this is a 2 digit value)
+ brset 0,FLAGBYTE,UPD1
+ ldx DIGIT1
+ jsr FMTXLEAD0
+ jsr PUTMID34
+ ldx #DIGIT0 ; Point to our value to be updated
+ lda #UPD_MID12 ; Request updating in the middle of the display
+ bra UPD2
+UPD1
+ ldx DIGIT0
+ jsr FMTXLEAD0
+ jsr PUTMID12
+ ldx #DIGIT1
+ lda #UPD_MID34
+UPD2
+ jsr START_UPDATEP ; And prepare the update routine
+ bset 4,BTNFLAGS ; Mark that the update is now pending
+ bclr 1,FLAGBYTE
+ lda #SYS8_SET_MODE
+ jmp PUTMSGBOT
+
+DO_MODE
+ lda FLAGBYTE
+ eor #1
+ sta FLAGBYTE
+
+REFRESH
+ brset 1,FLAGBYTE,NOCLEAR ; Do we need to clear the display first?
+FORCEFRESH
+ jsr CLEARALL ; Yes, clear everything before we start
+ bset 1,FLAGBYTE ; And remember that we have already done that
+NOCLEAR
+ bclr 7,BTNFLAGS ; Turn off any update routine that might be pending
+ brset 0,FLAGBYTE,SET1
+ ldx DIGIT1
+ jsr FMTXLEAD0
+ jsr PUTMID34
+ ldx #DIGIT0
+ lda #BLINK_MID12
+ bra SET2
+SET1
+ ldx DIGIT0
+ jsr FMTXLEAD0
+ jsr PUTMID12
+ ldx #DIGIT1
+ lda #BLINK_MID34
+SET2
+ jsr START_BLINKP
+ bset 2,BTNFLAGS ; Mark a blink routine as pending
+ rts
+;
+; (8) 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 FLAGBYTE ; start with a clean slate
+ clr DIGIT0
+ clr DIGIT1
+ rts
+;
+; (9) This subroutine is useful for getting a scrolling string on the screen
+;
+;----------------------------------------------------------------------
+; Routine:
+; SETUP_SCROLL
+; Parameters:
+; X - Offset from Start to the string
+; Returns:
+; MSGBUF - contains copied string
+; Purpose
+; This copies the current string into MSGBUF and calls the appropriate routines
+; to start it scrolling on the bottom line.
+;----------------------------------------------------------------------
+SETUP_SCROLL:
+ clr SYSTEMP0
+ sta SYSTEMP1
+DO_COPY:
+ ldx SYSTEMP1 ; Get the pointer to the source character
+ lda START,X ; Get the character that we are copying
+ ldx SYSTEMP0 ; Get the pointer to the output buffer
+ sta MSGBUF,X ; and store the character away
+ inc SYSTEMP0 ; Increment our count
+ inc SYSTEMP1 ; As well as the pointer to the character
+ cmp #SEPARATOR ; Did we get a terminator character
+ bne DO_COPY ; No, go back for more
+ ;
+ ; The string is now in a buffer terminated by a separator character
+ ;
+ jsr PUTSCROLLMSG ; Initialize the scrolling support
+ jmp SCROLLMSG ; And tell it to actually start scrolling
diff --git a/from_toebes/passwd/passwd.known_good b/from_toebes/passwd/passwd.known_good
new file mode 100644
index 0000000..b332361
--- /dev/null
+++ b/from_toebes/passwd/passwd.known_good
Binary files differ
diff --git a/from_toebes/passwd/passwd.zap b/from_toebes/passwd/passwd.zap
new file mode 100644
index 0000000..9150e9d
--- /dev/null
+++ b/from_toebes/passwd/passwd.zap
@@ -0,0 +1,25 @@
+TDL0724962¬ Applet file header
+Password Test¬ Applet friendly name
+Passwd1¬ Applet version #
+This simple program shows how you might enter a password (or other 4 digit number).
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC023A819D9D819D9D819D9D819D9DD6015D81CC017C00CC01AF1118000E0B0E05050A1416130E16170E05051D190A1C1C20181B0D0B222413181117240A32241D180E0B0E1C30241F1212123F001B83001FFF001AFF0001FFFF02FF011D011AFF0186FF01A6FF0139FF001D128FB691A11B26141361CD579FA61BCD587EA621CD58A8A63DCC58450261051261CD579FA627CD587EA600CD58ACA635CC0245128FB691A1A62756A1862655C604C3A1032711A1002709A101273DA639CC4E89109F2002119F4FC704F4A663C704F500610EBE63CD593ECD5920AE62A605200CBE62CD593ECD5910AE63A607CD57C718901361A650CC584CB661A801B761026105CD577A12611F9000610EBE63CD593ECD5920AE62A607200CBE62CD593ECD5910AE63A609CD55BF149081A6C0B7963F613F623F63813FA0B7A1BEA1D60110BEA0D704D23CA03CA1A13F26EECD5522CC5545¬
+17336¬
+0¬ No data
+Password Test¬ Applet friendly name
+Passwd2¬ Applet version #
+This simple program shows how you might enter a password (or other 4 digit number).
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC023A819D9D819D9D819D9D819D9DD6015D81CC017C00CC01AF1118000E0B0E05050A1416130E16170E05051D190A1C1C20181B0D0B222413181117240A32241D180E0B0E1C30241F1212123F001B83001FFF001AFF0001FFFF02FF011D011AFF0186FF01A6FF0139FF001D128FB691A11B26141361CD5ACBA61BCD577FA621CD57A9A63DCC57460261051261CD5ACBA627CD577FA600CD57ADA635CC0245128FB691A1A62756A1862655C604C3A1032711A1002709A101273DA639CC4E78109F2002119F4FC704F4A663C704F500610EBE63CD583FCD5821AE62A605200CBE62CD583FCD5811AE63A607CD56C818901361A650CC574DB661A801B761026105CD5AA012611F9000610EBE63CD583FCD5821AE62A607200CBE62CD583FCD5811AE63A609CD55AE149081A6C0B7963F613F623F63813FA0B7A1BEA1D60110BEA0D704D23CA03CA1A13F26EECD5511CC5534¬
+44579¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/passwd/passwd.zsm b/from_toebes/passwd/passwd.zsm
new file mode 100644
index 0000000..dd26499
--- /dev/null
+++ b/from_toebes/passwd/passwd.zsm
@@ -0,0 +1,232 @@
+;Name: Password
+;Version: PASSWD
+;Description: This is a simple number update/passwd program
+;by John A. Toebes, VIII
+;
+;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 which digit we are working on (SET=SECOND DIGIT)
+; Bit 1 indicates that we need to clear the display first
+;
+DIGIT0 EQU $62 ; The first digit to enter
+DIGIT1 EQU $63 ; The second digit to enter
+SYSTEMP0 EQU $A0
+SYSTEMP1 EQU $A1
+;
+; (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_TOEBES: timex6 "TOEBES"
+S6_SAMPLE: timex6 "SAMPLE"
+S6_PRESS: timex6 "PRESS "
+S8_PASSWORD: timex "PASSWORD"
+SX_MESSAGE timex "BY JOHN A. TOEBES, VIII"
+ db SEPARATOR
+;
+; (4) State Table
+;
+STATETAB0:
+ db 0
+ db EVT_ENTER,TIM_2_8TIC,0 ; Initial state
+ db EVT_TIMER2,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_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_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_ENTER ; Is this our initial entry?
+ bne REFRESH0
+;
+; This is the initial event for starting us
+;
+DO_ENTER
+ bclr 1,FLAGBYTE ; Indicate that we need to clear the display
+ jsr CLEARSYM ; Clear the display
+ lda #S6_TOEBES-START
+ jsr PUT6TOP
+ lda #S6_SAMPLE-START
+ jsr PUT6MID
+ lda #S8_PASSWORD
+ jmp BANNER8
+;
+; We come here for a RESUME or TIMER2 event. For this we want to reset the display
+;
+REFRESH0
+ brset 1,FLAGBYTE,NOCLEAR0 ; Do we need to clear the display first?
+ bset 1,FLAGBYTE
+ jsr CLEARSYM
+NOCLEAR0
+ lda #S6_PRESS-START
+ jsr PUT6TOP
+ lda #SYS6_SET
+ jsr PUTMSG2
+ lda #SX_MESSAGE-START
+ jmp SETUP_SCROLL
+;
+; (6) State Table 1 Handler
+; This is called to process the state events.
+; We see SET, RESUME, DNANY4, and UPANY4 events
+;
+HANDLE_STATE1:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_UPANY4
+ beq REFRESH
+ 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
+ lda #EVT_USER2
+ jmp POSTEVENT
+;
+; (7) Our real working code...
+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 #99
+ sta UPDATE_MAX ; and the high end is 99 (the max since this is a 2 digit value)
+ brset 0,FLAGBYTE,UPD1
+ ldx DIGIT1
+ jsr FMTXLEAD0
+ jsr PUTMID34
+ ldx #DIGIT0 ; Point to our value to be updated
+ lda #UPD_MID12 ; Request updating in the middle of the display
+ bra UPD2
+UPD1
+ ldx DIGIT0
+ jsr FMTXLEAD0
+ jsr PUTMID12
+ ldx #DIGIT1
+ lda #UPD_MID34
+UPD2
+ jsr START_UPDATEP ; And prepare the update routine
+ bset 4,BTNFLAGS ; Mark that the update is now pending
+ bclr 1,FLAGBYTE
+ lda #SYS8_SET_MODE
+ jmp PUTMSGBOT
+
+DO_MODE
+ lda FLAGBYTE
+ eor #1
+ sta FLAGBYTE
+
+REFRESH
+ brset 1,FLAGBYTE,NOCLEAR ; Do we need to clear the display first?
+FORCEFRESH
+ jsr CLEARALL ; Yes, clear everything before we start
+ bset 1,FLAGBYTE ; And remember that we have already done that
+NOCLEAR
+ bclr 7,BTNFLAGS ; Turn off any update routine that might be pending
+ brset 0,FLAGBYTE,SET1
+ ldx DIGIT1
+ jsr FMTXLEAD0
+ jsr PUTMID34
+ ldx #DIGIT0
+ lda #BLINK_MID12
+ bra SET2
+SET1
+ ldx DIGIT0
+ jsr FMTXLEAD0
+ jsr PUTMID12
+ ldx #DIGIT1
+ lda #BLINK_MID34
+SET2
+ jsr START_BLINKP
+ bset 2,BTNFLAGS ; Mark a blink routine as pending
+ rts
+;
+; (8) 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 FLAGBYTE ; start with a clean slate
+ clr DIGIT0
+ clr DIGIT1
+ rts
+;
+; (9) This subroutine is useful for getting a scrolling string on the screen
+;
+;----------------------------------------------------------------------
+; Routine:
+; SETUP_SCROLL
+; Parameters:
+; X - Offset from Start to the string
+; Returns:
+; MSGBUF - contains copied string
+; Purpose
+; This copies the current string into MSGBUF and calls the appropriate routines
+; to start it scrolling on the bottom line.
+;----------------------------------------------------------------------
+SETUP_SCROLL:
+ clr SYSTEMP0
+ sta SYSTEMP1
+DO_COPY:
+ ldx SYSTEMP1 ; Get the pointer to the source character
+ lda START,X ; Get the character that we are copying
+ ldx SYSTEMP0 ; Get the pointer to the output buffer
+ sta MSGBUF,X ; and store the character away
+ inc SYSTEMP0 ; Increment our count
+ inc SYSTEMP1 ; As well as the pointer to the character
+ cmp #SEPARATOR ; Did we get a terminator character
+ bne DO_COPY ; No, go back for more
+ ;
+ ; The string is now in a buffer terminated by a separator character
+ ;
+ jsr PUTSCROLLMSG ; Initialize the scrolling support
+ jmp SCROLLMSG ; And tell it to actually start scrolling
diff --git a/from_toebes/pick6/pick6.asm b/from_toebes/pick6/pick6.asm
new file mode 120000
index 0000000..7e60eb8
--- /dev/null
+++ b/from_toebes/pick6/pick6.asm
@@ -0,0 +1 @@
+pick6.zsm \ No newline at end of file
diff --git a/from_toebes/pick6/pick6.known_good b/from_toebes/pick6/pick6.known_good
new file mode 120000
index 0000000..670787d
--- /dev/null
+++ b/from_toebes/pick6/pick6.known_good
@@ -0,0 +1 @@
+pick6.zap.app \ No newline at end of file
diff --git a/from_toebes/pick6/pick6.zap b/from_toebes/pick6/pick6.zap
new file mode 100644
index 0000000..21ec223
--- /dev/null
+++ b/from_toebes/pick6/pick6.zap
@@ -0,0 +1,33 @@
+TDL1024972¬
+PICK6¬
+PICK6¬
+A sample lottery number picker to pick 6 numbers out of a pool of 49 numbers (no duplicates allowed).
+ To use it, just select it as the current app and it will pick a set of 6 numbers for you. To get another set,
+ just press the next button. This is for amusement only (but if you win anything because of it, I would welcome
+ anything that you send me).
+
+by John A. Toebes, VIII
+watchapp.hlp¬
+100¬
+none¬
+Timex Data Link 150 Watch¬
+CC0275139081CC0157139081819D9DD6013E81CC0180001D1D1D1F001F1D1D1D2419120C14310624191A19181718001B85001AFF008085001FFF0001FFFF1D00000000000000FFC604C1A10826B5AE05B665CD6B0DB76597D60138CD58A8BE65D60138CC587E3F651290CD577ACC0225128F1390B691A18027ECA11B27E8A11A274B4FAE06D7014E5A26FA3F65CD022DA43FB766A630B065B16625F1B666AD0A3C65B665A10626E520234CAE505C6DFE2603E7FE81E1FE25034C20F1B766E6FEB767B666E7FEB6675C4D26F081CE014FAD48CD58E0CE0150AD40CD58F0CE0151AD38CD5900CE0152AD30CD5910CE0153AD28CD5920CE0154AD20CD5930A636B71D141EA624B71D141EA636B71D101EA624B71D101EA620CC5845CC5951B663BE5042BB61B7619FB962B7624FB767A900B766B663BE46AD1DB664BE50AD17B664BE61BF63BE62BF64BE4642BB66B7619FB967B7628142BB62B7629FB966B7664FB967B76781A6C0B796B627B763B764B761A43FB76281¬
+42817¬
+0¬
+PICK6¬
+PICK6¬
+A sample lottery number picker to pick 6 numbers out of a pool of 49 numbers (no duplicates allowed).
+ To use it, just select it as the current app and it will pick a set of 6 numbers for you. To get another set,
+ just press the next button. This is for amusement only (but if you win anything because of it, I would welcome
+ anything that you send me).
+
+by John A. Toebes, VIII
+watchapp.hlp¬
+100¬
+none¬
+Timex Data Link 150s Watch¬
+CC0275139081CC0157139081819D9DD6013E81CC0180001D1D1D1F001F1D1D1D2419120C14310624191A19181718001B85001AFF008085001FFF0001FFFF1D00000000000000FFC604C1A10826B5AE05B665CD6B16B76597D60138CD57A9BE65D60138CC577F3F651290CD5AA0CC0225128F1390B691A18027ECA11B27E8A11A274B4FAE06D7014E5A26FA3F65CD022DA43FB766A630B065B16625F1B666AD0A3C65B665A10626E520234CAE505C6DFE2603E7FE81E1FE25034C20F1B766E6FEB767B666E7FEB6675C4D26F081CE014FAD48CD57E1CE0150AD40CD57F1CE0151AD38CD5801CE0152AD30CD5811CE0153AD28CD5821CE0154AD20CD5831A634B71D141EA622B71D141EA634B71D101EA622B71D101EA620CC5746CC5852B663BE5042BB61B7619FB962B7624FB767A900B766B663BE46AD1DB664BE50AD17B664BE61BF63BE62BF64BE4642BB66B7619FB967B7628142BB62B7629FB966B7664FB967B76781A6C0B796B627B763B764B761A43FB76281¬
+62244¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/pick6/pick6.zsm b/from_toebes/pick6/pick6.zsm
new file mode 100644
index 0000000..515dd8c
--- /dev/null
+++ b/from_toebes/pick6/pick6.zsm
@@ -0,0 +1,335 @@
+;Name: PICK6
+;Version: PICK6
+;Description: A sample lottery number picker to pick 6 numbers out of a pool of 49 numbers (no duplicates allowed).
+; To use it, just select it as the current app and it will pick a set of 6 numbers for you. To get another set,
+; just press the next button. This is for amusement only (but if you win anything because of it, I would welcome
+; anything that you send me).
+;
+;by John A. Toebes, VIII
+;
+;HelpFile: watchapp.hlp
+;HelpTopic: 100
+;****************************************************************************************
+;* Copyright (C) 1997 John A. Toebes, VIII *
+;* All Rights Reserved *
+;* This program may not be distributed in any form without the permission of the author *
+;* jtoebes@geocities.com *
+;****************************************************************************************
+; (1) Program specific constants
+;
+ INCLUDE "WRISTAPP.I"
+;
+; Program specific constants
+;
+RAND_RANGE EQU 48 ; This is the number of items to select from (1 to RAND_RANGE+1)
+CURRENT_TIC EQU $27 ; Current system clock tic (Timer)
+RAND_WCL EQU $61
+RAND_WCH EQU $62
+RAND_WNL EQU $63
+RAND_WNH EQU $64
+THIS_PICK EQU $65 ; We can share this with MARQ_POS since we don't do both at the same time
+MARQ_POS EQU $65
+TEMPL EQU $66
+TEMPH EQU $67
+START EQU *
+BASE_TAB EQU $FE
+;
+; (2) System entry point vectors
+;
+L0110: jmp MAIN ; The main entry point - WRIST_MAIN
+L0113: bclr 1,BTNFLAGS ; Called when we are suspended for any reason - WRIST_SUSPEND
+ rts
+L0116: jmp FLASH ; Called to handle any timers or time events - WRIST_DOTIC
+L0119: bclr 1,BTNFLAGS ; Called when the COMM app starts and we have timers pending - WRIST_INCOMM
+ rts
+L011c: rts ; Called when the COMM app loads new data - WRIST_NEWDATA
+ nop
+ nop
+
+L011f: lda STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+;
+S6_MARQ timex6 " +O+ "
+S8_TITLE timex " PICK-6 "
+
+MARQ_SEL
+ DB S6_MARQ+2-START
+ DB S6_MARQ+3-START
+ DB S6_MARQ+2-START
+ DB S6_MARQ+1-START
+ DB S6_MARQ-START
+ DB S6_MARQ+1-START
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM2_16TIC,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_DNNEXT,TIM2_16TIC,0 ; Next button
+ db EVT_TIMER2,TIM_ONCE,0 ; Timer
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+
+PICK_VALS db 0,0,0,0,0,0,0,$FF
+;
+; (5) This flashes the text on the screen
+;
+FLASH
+ lda CURRENT_APP ; See which app is currently running
+ cmp #APP_WRIST ; Is it us?
+ bne L0113 ; No, so just turn off the tic timer since we don't need it
+ ldx #5
+ lda MARQ_POS
+ jsr INCA_WRAPX
+ sta MARQ_POS
+ tax
+ lda MARQ_SEL,X
+ jsr PUT6MID
+ ldx MARQ_POS
+ lda MARQ_SEL,X
+ jmp PUT6TOP
+;
+; (6) They want us to do it again
+;
+DOITAGAIN ; Tell them we are going to do it again
+ clr MARQ_POS
+ bset 1,BTNFLAGS
+ jsr CLEARALL
+ jmp BANNER
+;
+; (7) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER, RESUME, TIMER2 and NEXT events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ bclr 1,BTNFLAGS
+ lda BTNSTATE
+ cmp #EVT_DNNEXT ; Did they press the next button?
+ beq DOITAGAIN
+ cmp #EVT_ENTER ; Or did we start out
+ beq DOITAGAIN
+ cmp #EVT_RESUME
+ beq REFRESH
+;
+; (8) Select a random answer
+;
+SHOWIT
+ clra
+ ldx #6
+CLEARIT
+ sta PICK_VALS-1,X
+ decx
+ bne CLEARIT
+;
+; We want to pick 6 random numbers. The first needs to be in the range 1 ... RAND_RANGE
+; The second should be in the range 1 ... (RAND_RANGE-1)
+; The third should be in the range 1 ... (RAND_RANGE-2)
+; The fourth should be in the range 1 ... (RAND_RANGE-3)
+; The fifth should be in the range 1 ... (RAND_RANGE-4)
+; The sixth should be in the range 1 ... (RAND_RANGE-5)
+;
+ clr THIS_PICK
+ONE_MORE_PICK
+
+REPICK
+ jsr RAND16
+ and #63
+ sta TEMPL
+ lda #RAND_RANGE
+ sub THIS_PICK
+ cmp TEMPL
+ blo REPICK
+ lda TEMPL
+ bsr INSERT_NUM
+
+ inc THIS_PICK
+ lda THIS_PICK
+ cmp #6
+ bne ONE_MORE_PICK
+ bra REFRESH
+;
+; (9) Insert a number in the list
+;
+INSERT_NUM
+ inca
+ ldx #(PICK_VALS-1)-BASE_TAB ; Index so that we can use the short addressing mode
+TRY_NEXT
+ incx ; Advance to the next number
+ tst BASE_TAB,X ; Is it an empty slot?
+ bne NOT_END ; No, try some more
+ sta BASE_TAB,X ; Yes, just toss it in there
+ rts ; And return
+NOT_END
+ cmp BASE_TAB,X ; Non-empty slot, are we less than it?
+ blo PUT_HERE ; Yes, so we go here
+ inca ; No, Greater than or equal, we need to increment one and try again
+ bra TRY_NEXT
+PUT_HERE
+ sta TEMPL
+ lda BASE_TAB,X
+ sta TEMPH
+ lda TEMPL
+ sta BASE_TAB,X
+ lda TEMPH
+ incx
+ tsta
+ bne PUT_HERE
+ rts
+;
+; (10) Display the currently selected random numbers
+;
+REFRESH
+ ldx PICK_VALS
+ bsr GOFMTX
+ jsr PUTTOP12
+
+ ldx PICK_VALS+1
+ bsr GOFMTX
+ jsr PUTTOP34
+
+ ldx PICK_VALS+2
+ bsr GOFMTX
+ jsr PUTTOP56
+
+ ldx PICK_VALS+3
+ bsr GOFMTX
+ jsr PUTMID12
+
+ ldx PICK_VALS+4
+ bsr GOFMTX
+ jsr PUTMID34
+
+ ldx PICK_VALS+5
+ bsr GOFMTX
+ jsr PUTMID56
+
+ lda #ROW_MP23
+ sta DISP_ROW
+ bset COL_MP23,DISP_COL
+
+ lda #ROW_MP45
+ sta DISP_ROW
+ bset COL_MP45,DISP_COL
+
+ lda #ROW_TP23
+ sta DISP_ROW
+ bset COL_TP23,DISP_COL
+
+ lda #ROW_TP45
+ sta DISP_ROW
+ bset COL_TP45,DISP_COL
+BANNER
+ lda #S8_TITLE-START ; And show the mode on the bottom
+ jmp BANNER8
+
+GOFMTX JMP FMTX
+; (11) Here is an excellent random number generator
+; it comes courtesy of Alan Beale <biljir@pobox.com>
+; The following C code gives a good MWC (multiply-with-carry)
+; generator. This type is generally superior to linear
+; congruential generators. As a bonus, there is no particular advantage to using the high-order
+; rather than the low-order bits.
+; The algorithm was developed and analyzed by George
+; Marsaglia, a very well-known scholar of random number lore.
+;
+; The code assumes 16 bit shorts and 32 bit longs (hardly surprising).
+;
+;static unsigned short wn,wc; /* random number and carry */
+;
+;unsigned short rand() {
+; unsigned long temp;
+; temp = 18000*wn + wc;
+; wc = temp >> 16;
+; wn = temp & 0xffff;
+; return wn;
+;}
+;
+;To seed, set wn to anything you like, and wc to anything between 0 and 17999.
+;
+; Translating this into assembler is
+;nHnL*0x4650 + RAND_WCHcL
+;
+; unsigned long temp;
+; temp = 18000*wn + wc;
+; wc = temp >> 16;
+; wn = temp & 0xffff;
+; return wn;
+; temp = 0x4650 * n + c
+; temp = 0x4650 * nHnL + cHcL
+; temp = (0x4600 + 0x50) * (nH00 + nL) + cHcL
+; temp = 0x4600*nH00 + 0x4600*nL + 0x50*nH00 + 0x50*nL + cHcL
+; temp = 0x46*nH*0x10000 + 0x46*nL*0x100 + 0x50*nH*0x1000 + 0x50*nL + cHcL
+; We construct the 32bit result into tH tL cH cL and then swap the 16 bit values
+; once we have no more need of the original numbers in the calculation
+;
+RAND_MULT EQU 18000 ; This is for the random number generator
+RAND_MULTH EQU RAND_MULT/256
+RAND_MULTL EQU RAND_MULT&255
+
+RAND16
+ lda RAND_WNL ; A=nL
+ ldx RAND_MULTL ; X=0x50
+ mul ; X:A = 0x50*nL
+ add RAND_WCL ; A=Low(0x50nL)+cL
+ sta RAND_WCL ; cL=Low(0x50nL)+cL
+ txa ; A=High(0x50nL)
+ adc RAND_WCH ; A=High(0x50nL)+cH
+ sta RAND_WCH ; cH=High(0x50nL)+cH
+ clra ; A=0
+ sta TEMPH ; tH=0
+ adc #0 ; A=Carry(0x50nL)+cH
+ sta TEMPL ; tL=Carry(0x50nL)+cH
+
+ lda RAND_WNL ; A=nL
+ ldx RAND_MULTH ; X=0x46
+ bsr RAND_SUB ; tL:cH += 0x46*nL tH=carry(0x46*nL)
+
+ lda RAND_WNH ; A=nH
+ ldx RAND_MULTL ; X=0x50
+ bsr RAND_SUB ; tL:cH += 0x50*nH tH=carry(0x50*nH)
+
+ lda RAND_WNH ; A=nH
+ ldx RAND_WCL ; X=cL
+ stx RAND_WNL ; nL=cL
+ ldx RAND_WCH ; X=cH
+ stx RAND_WNH ; hH=cH
+ ldx RAND_MULTH ; X=0x46
+ mul ; X:A=0x46*nH
+ add TEMPL ; A=Low(0x46*nH)+tL
+ sta RAND_WCL ; nL=Low(0x46*nH)+tL
+ txa ; A=High(0x46*nH)
+ adc TEMPH ; A=High(0x46*nH)+tH
+ sta RAND_WCH ; nH=High(0x46*nH)+tH
+ rts
+
+RAND_SUB
+ mul ; Compute the values
+ add RAND_WCH ; A=LOW(result)+cH
+ sta RAND_WCH ; cH=Low(result)+cH
+ txa ; X=High(result)
+ adc TEMPL ; X=High(result)+tL+Carry(low(result)+cH)
+ sta TEMPL ; tL=High(result)+tL+Carry(low(result)+cH)
+ clra ; A=0
+ adc TEMPH ; A=carry(High(result)+tL+Carry(low(result)+cH))+tH
+ sta TEMPH ; tH=carry(High(result)+tL+Carry(low(result)+cH))+tH
+ rts
+;
+; (12) 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
+ lda CURRENT_TIC
+ sta RAND_WNL
+ sta RAND_WNH
+ sta RAND_WCL
+ and #$3f
+ sta RAND_WCH
+ rts
diff --git a/from_toebes/promdump/promdump.asm b/from_toebes/promdump/promdump.asm
new file mode 100644
index 0000000..91d66c2
--- /dev/null
+++ b/from_toebes/promdump/promdump.asm
@@ -0,0 +1,336 @@
+;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
diff --git a/from_toebes/promdump/promdump.known_good b/from_toebes/promdump/promdump.known_good
new file mode 120000
index 0000000..850cce5
--- /dev/null
+++ b/from_toebes/promdump/promdump.known_good
@@ -0,0 +1 @@
+promdump.zap.app \ No newline at end of file
diff --git a/from_toebes/promdump/promdump.zap b/from_toebes/promdump/promdump.zap
new file mode 100644
index 0000000..d4548a2
--- /dev/null
+++ b/from_toebes/promdump/promdump.zap
@@ -0,0 +1,33 @@
+TDL0707972¬
+Prom Dump¬
+promdump¬
+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!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150 Watch¬
+CC02B1819D9D819D9D819D9D819D9DD6014381CC017500CC01A21ACC0236220E0E161700140D1914160E170A0A0A0A24242424001B84001AFF001FFF0080830183830101FFFF02FF0237FFFF1D00A5FF001F80011D021AFF0286FF02A6FF0239FF001D0000128FB691A11B2658CD577AA61FCD587EA625CD58A8A648CC584CD7013BA40FD7013CD6013B44444444D7013B81B691A11F27081161A18326021061016112C60174A006C70174C60173A200C701732010A606CB0174C70174C60173A900C70173CD579F5FAD38CD58E0AE01AD31CD58F0AE02AD2ACD5900AE03AD23CD5910AE04AD1CCD5920AE05AD15CD5930C601735FAD88C60174AE02AD81A62BCC58459FCB0174C70438C60173A900C704371C9ECD50EBB7A344444444B7A2B6A3A40FB7A381128FB691A1A6273AA186264CC604C3A1032713A100270BA1012720AD82A639CC4E89109F2002119F4FC704F4A60FC704F5AD3FA608CD57C7189081B6624CA403B762B66348484848BB64C70173B66548484848BB66C701741F90CD01D5AE045AD6013BE7635D26F7AD08A60BCD55BF149081B662C704F3AB639781A6C0B7963F6281¬
+32695¬
+0¬
+Prom Dump¬
+promdump¬
+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!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150s Watch¬
+CC02B1819D9D819D9D819D9D819D9DD6014381CC017500CC01A21ACC0236220E0E161700140D1914160E170A0A0A0A24242424001B84001AFF001FFF0080830183830101FFFF02FF0237FFFF1D00A5FF001F80011D021AFF0286FF02A6FF0239FF001D0000128FB691A11B2658CD5AA0A61FCD577FA625CD57A9A648CC574DD7013BA40FD7013CD6013B44444444D7013B81B691A11F27081161A18326021061016112C60174A006C70174C60173A200C701732010A606CB0174C70174C60173A900C70173CD5ACB5FAD38CD57E1AE01AD31CD57F1AE02AD2ACD5801AE03AD23CD5811AE04AD1CCD5821AE05AD15CD5831C601735FAD88C60174AE02AD81A62BCC57469FCB0174C70438C60173A900C704371C9ECD50DAB7A344444444B7A2B6A3A40FB7A381128FB691A1A6273AA186264CC604C3A1032713A100270BA1012720AD82A639CC4E78109F2002119F4FC704F4A60FC704F5AD3FA608CD56C8189081B6624CA403B762B66348484848BB64C70173B66548484848BB66C701741F90CD01D5AE045AD6013BE7635D26F7AD08A60BCD55AE149081B662C704F3AB639781A6C0B7963F6281¬
+41871¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/promdump/promdump.zsm b/from_toebes/promdump/promdump.zsm
new file mode 100644
index 0000000..e050804
--- /dev/null
+++ b/from_toebes/promdump/promdump.zsm
@@ -0,0 +1,336 @@
+;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
diff --git a/from_toebes/shipbell/shipbell.asm b/from_toebes/shipbell/shipbell.asm
new file mode 100644
index 0000000..6d9f11b
--- /dev/null
+++ b/from_toebes/shipbell/shipbell.asm
@@ -0,0 +1,176 @@
+;Name: Ships Bells
+;Version: SHIPBELL
+;Description: Ships bells - by John A. Toebes, VIII
+;This application turns makes the hour chime with nautical bells.
+;
+;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
+;
+START EQU *
+CHANGE_FLAGS EQU $92 ; System Flags
+SND_POS EQU $61
+SND_REMAIN EQU $62
+SND_NOTE EQU $63
+
+NOTE_PAUSE EQU (TONE_PAUSE/16)
+NOTE_BELL EQU (TONE_MID_C/16)
+;
+; (2) System entry point vectors
+;
+L0110: jmp MAIN ; The main entry point - WRIST_MAIN
+L0113: rts ; Called when we are suspended for any reason - WRIST_SUSPEND
+ nop
+ nop
+L0116: jmp CHECKSTATE ; Called to handle any timers or time events - WRIST_DOTIC
+L0119: jmp STOPIT ; Called when the COMM app starts and we have timers pending - WRIST_INCOMM
+L011c: rts
+ nop
+ nop ; Called when the COMM app loads new data - WRIST_NEWDATA
+
+L011f: lda STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+;
+S6_SHIPS: timex6 "SHIPS"
+S6_BELLS: timex6 " BELLS"
+S8_TOEBES: timex "J.TOEBES"
+;
+; Here is the pattern for the ships bells. We want to have a short bell followed by a very short silence
+; followed by a longer bell. We use 3 tics for the short bell, 1 tic for the silence and 6 tics for the longer
+; bell. The last bell is 7 ticks.
+; We then have to byte swap each of these because the BRSET instruction numbers from bottom to top.
+;
+; The string looks like:
+; 111 0 111111 000000 111 0 111111 000000 111 0 111111 000000 111 0 111111 000000
+; Taking this into clumps of 4 bytes, we get
+; 1110 1111 1100 0000 1110 1111 1100 0000 1110 1111 1100 0000 1110 1111 1100 0000 1111 1110
+;
+Pattern DB $F7 ;1110 1111 ; 8 start here
+ DB $03 ;1100 0000
+P67 DB $F7 ;1110 1111 ; 6, 7 start here
+ DB $03 ;1100 0000
+P45 DB $F7 ;1110 1111 ; 4, 5 start here
+ DB $03 ;1100 0000
+P23 DB $F7 ;1110 1111 ; 2, 3 start here
+ DB $03 ;1100 0000
+P1 DB $7F ;1111 1110 ; 1 starts here
+;
+; This table indexes where we start playing the tone from
+;
+STARTS
+ DB (Pattern-Pattern)*8 ; 0 (8 AM, 4PM, Midnight)
+ DB (P1-Pattern)*8 ; 1 (1 AM, 9AM, 5PM)
+ DB (P23-Pattern)*8 ; 2 (2 AM, 10AM, 6PM)
+ DB (P23-Pattern)*8 ; 3 (3 AM, 11AM, 7PM)
+ DB (P45-Pattern)*8 ; 4 (4 AM, NOON, 8PM)
+ DB (P45-Pattern)*8 ; 5 (5 AM, 1PM, 9PM)
+ DB (P67-Pattern)*8 ; 6 (6 AM, 2PM, 10PM)
+ DB (P67-Pattern)*8 ; 7 (7 AM, 3PM, 11PM)
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM_LONG,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER and RESUME events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Allow us to be suspended
+ jsr CLEARALL ; Clear the display
+ lda #S6_SHIPS-START ; Put 'SHIPS ' on the top line
+ jsr PUT6TOP
+ lda #S6_BELLS-START ; Put ' BELLS' on the second line
+ jsr PUT6MID
+ bsr FORCESTATE ; Just for fun, check the alarm state
+ lda #S8_TOEBES-START
+ jmp BANNER8
+;
+; (6) This is the main initialization routine which is called when we first get the app into memory
+;
+MAIN:
+ lda #$C4 ; Bit2 = wristapp wants a call once an hour when it changes (WRIST_DOTIC) (SET=CALL)
+ ; Bit6 = Uses system rules for button beep decisions (SET=SYSTEM RULES)
+ ; Bit7 = Wristapp has been loaded (SET=LOADED)
+ sta WRISTAPP_FLAGS
+ bclr 2,MODE_FLAGS ; Turn off the hourly chimes
+ clr SND_REMAIN
+;
+; (7) Determining the current hour
+;
+CHECKSTATE
+ brclr 5,CHANGE_FLAGS,NO_HOUR ; Have we hit the hour mark?
+FORCESTATE
+ bclr 3,MAIN_FLAGS ; Make sure we don't play the system hourly chimes
+ jsr ACQUIRE ; Lock so that it doesn't change under us
+ lda TZ1_HOUR ; Assume that we are using the first timezone
+ jsr CHECK_TZ ; See which one we are really using
+ bcc GOT_TZ1 ; If we were right, just skip on to do the work
+ lda TZ2_HOUR ; Wrong guess, just load up the second time zone
+GOT_TZ1
+;
+; 12 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12
+; 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18
+; deca FF 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17
+; anda 07 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
+ and #7 ; Convert the hour to the number of bells
+ tax ; Save away as an index into the start position table
+ bne NOTEIGHT ; Is it midnight (or a multiple of 8)
+ lda #8 ; Yes, so that is 8 bells, not zero
+NOTEIGHT
+ lsla ; Multiple the number of bells by 8 to get the length
+ lsla
+ lsla
+ sta SND_REMAIN ; Save away the number of bells left to play
+ lda STARTS,X ; Point to the pattern of the first bell
+ sta SND_POS
+ bset 1,BTNFLAGS ; Turn on the tic timer
+ JMP RELEASE ; And release our lock on the time
+;
+; (8) Playing the next note piece
+;
+NO_HOUR
+ lda SND_REMAIN ; Do we have any more notes to play?
+ bne _DO_SOUND ; No, skip out
+STOPIT
+ lda #TONE_PAUSE ; End of the line, shut up the sound hardware
+ sta $28
+ clr SND_REMAIN ; Force us to quit looking at sound
+ bclr 1,BTNFLAGS ; and turn off the tic timer
+ rts
+
+_DO_SOUND
+ deca ; Yes, note that we used one up
+ sta SND_REMAIN
+ lda SND_POS ; See where we are in the sound
+ lsra ; Divide by 8 to get the byte pointer
+ lsra
+ lsra
+ tax ; and make it an index
+ lda Pattern,X ; Get the current pattern byte
+ sta SND_NOTE ; And save it where we can test it
+ lda SND_POS ; Get the pointer to where we are in the sound
+ inc SND_POS ; Advance to the next byte
+ and #7 ; and hack off the high bytes to leave the bit index
+ lsla ; Convert that to a BRSET instruction
+ sta TSTNOTE ; And self modify our code so we can play
+TSTNOTE brset 0,SND_NOTE,PLAYIT ; If the note is not set, skip out
+ lda #TONE_PAUSE ; Not playing, we want to have silence
+ brskip2
+PLAYIT lda #NOTE_BELL ; Playing, select the bell tone
+ sta $28 ; And make it play
+NO_SOUND
+ rts
diff --git a/from_toebes/shipbell/shipbell.known_good b/from_toebes/shipbell/shipbell.known_good
new file mode 120000
index 0000000..35fe6a8
--- /dev/null
+++ b/from_toebes/shipbell/shipbell.known_good
@@ -0,0 +1 @@
+shipbell.zap.app \ No newline at end of file
diff --git a/from_toebes/shipbell/shipbell.zap b/from_toebes/shipbell/shipbell.zap
new file mode 100644
index 0000000..3c03502
--- /dev/null
+++ b/from_toebes/shipbell/shipbell.zap
@@ -0,0 +1,27 @@
+TDL0831972¬
+Ships Bells¬
+SHIPBELL¬
+Ships bells - by John A. Toebes, VIII
+This application turns makes the hour chime with nautical bells.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150 Watch¬
+CC016C819D9DCC0174CC019F819D9DD6014B81CC01560005110116051D0B0E13130513321D180E0B0E1CF703F703F703F7037F0040303020201010001B84001AFF0001FFFF1D128FCD577AA617CD587EA61CCD58A8AD10A622CC5845A6C4B79615683F620B92241795CD68E8B6B0CD690E2402B6B9A407972602A608484848B762D60143B7611290CC68F2B6622609A6F0B7283F621390814AB762B66144444497D6013AB763B6613C61A40748C701C0006303A6F0C5A603B72881¬
+13690¬
+0¬
+Ships Bells¬
+SHIPBELL¬
+Ships bells - by John A. Toebes, VIII
+This application turns makes the hour chime with nautical bells.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150s Watch¬
+CC016C819D9DCC0174CC019F819D9DD6014B81CC01560005110116051D0B0E13130513321D180E0B0E1CF703F703F703F7037F0040303020201010001B84001AFF0001FFFF1D128FCD5AA0A617CD577FA61CCD57A9AD10A622CC5746A6C4B79615683F620B92241795CD68F1B6B0CD69172402B6B9A407972602A608484848B762D60143B7611290CC68FBB6622609A6F0B7283F621390814AB762B66144444497D6013AB763B6613C61A40748C701C0006303A6F0C5A603B72881¬
+41038¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/shipbell/shipbell.zsm b/from_toebes/shipbell/shipbell.zsm
new file mode 100644
index 0000000..b81652a
--- /dev/null
+++ b/from_toebes/shipbell/shipbell.zsm
@@ -0,0 +1,176 @@
+;Name: Ships Bells
+;Version: SHIPBELL
+;Description: Ships bells - by John A. Toebes, VIII
+;This application turns makes the hour chime with nautical bells.
+;
+;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
+;
+START EQU *
+CHANGE_FLAGS EQU $92 ; System Flags
+SND_POS EQU $61
+SND_REMAIN EQU $62
+SND_NOTE EQU $63
+
+NOTE_PAUSE EQU (TONE_PAUSE/16)
+NOTE_BELL EQU (TONE_MID_C/16)
+;
+; (2) System entry point vectors
+;
+L0110: jmp MAIN ; The main entry point - WRIST_MAIN
+L0113: rts ; Called when we are suspended for any reason - WRIST_SUSPEND
+ nop
+ nop
+L0116: jmp CHECKSTATE ; Called to handle any timers or time events - WRIST_DOTIC
+L0119: jmp STOPIT ; Called when the COMM app starts and we have timers pending - WRIST_INCOMM
+L011c: rts
+ nop
+ nop ; Called when the COMM app loads new data - WRIST_NEWDATA
+
+L011f: lda STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+;
+S6_SHIPS: timex6 "SHIPS"
+S6_BELLS: timex6 " BELLS"
+S8_TOEBES: timex "J.TOEBES"
+;
+; Here is the pattern for the ships bells. We want to have a short bell followed by a very short silence
+; followed by a longer bell. We use 3 tics for the short bell, 1 tic for the silence and 6 tics for the longer
+; bell. The last bell is 7 ticks.
+; We then have to byte swap each of these because the BRSET instruction numbers from bottom to top.
+;
+; The string looks like:
+; 111 0 111111 000000 111 0 111111 000000 111 0 111111 000000 111 0 111111 000000
+; Taking this into clumps of 4 bytes, we get
+; 1110 1111 1100 0000 1110 1111 1100 0000 1110 1111 1100 0000 1110 1111 1100 0000 1111 1110
+;
+Pattern DB $F7 ;1110 1111 ; 8 start here
+ DB $03 ;1100 0000
+P67 DB $F7 ;1110 1111 ; 6, 7 start here
+ DB $03 ;1100 0000
+P45 DB $F7 ;1110 1111 ; 4, 5 start here
+ DB $03 ;1100 0000
+P23 DB $F7 ;1110 1111 ; 2, 3 start here
+ DB $03 ;1100 0000
+P1 DB $7F ;1111 1110 ; 1 starts here
+;
+; This table indexes where we start playing the tone from
+;
+STARTS
+ DB (Pattern-Pattern)*8 ; 0 (8 AM, 4PM, Midnight)
+ DB (P1-Pattern)*8 ; 1 (1 AM, 9AM, 5PM)
+ DB (P23-Pattern)*8 ; 2 (2 AM, 10AM, 6PM)
+ DB (P23-Pattern)*8 ; 3 (3 AM, 11AM, 7PM)
+ DB (P45-Pattern)*8 ; 4 (4 AM, NOON, 8PM)
+ DB (P45-Pattern)*8 ; 5 (5 AM, 1PM, 9PM)
+ DB (P67-Pattern)*8 ; 6 (6 AM, 2PM, 10PM)
+ DB (P67-Pattern)*8 ; 7 (7 AM, 3PM, 11PM)
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM_LONG,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER and RESUME events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Allow us to be suspended
+ jsr CLEARALL ; Clear the display
+ lda #S6_SHIPS-START ; Put 'SHIPS ' on the top line
+ jsr PUT6TOP
+ lda #S6_BELLS-START ; Put ' BELLS' on the second line
+ jsr PUT6MID
+ bsr FORCESTATE ; Just for fun, check the alarm state
+ lda #S8_TOEBES-START
+ jmp BANNER8
+;
+; (6) This is the main initialization routine which is called when we first get the app into memory
+;
+MAIN:
+ lda #$C4 ; Bit2 = wristapp wants a call once an hour when it changes (WRIST_DOTIC) (SET=CALL)
+ ; Bit6 = Uses system rules for button beep decisions (SET=SYSTEM RULES)
+ ; Bit7 = Wristapp has been loaded (SET=LOADED)
+ sta WRISTAPP_FLAGS
+ bclr 2,MODE_FLAGS ; Turn off the hourly chimes
+ clr SND_REMAIN
+;
+; (7) Determining the current hour
+;
+CHECKSTATE
+ brclr 5,CHANGE_FLAGS,NO_HOUR ; Have we hit the hour mark?
+FORCESTATE
+ bclr 3,MAIN_FLAGS ; Make sure we don't play the system hourly chimes
+ jsr ACQUIRE ; Lock so that it doesn't change under us
+ lda TZ1_HOUR ; Assume that we are using the first timezone
+ jsr CHECK_TZ ; See which one we are really using
+ bcc GOT_TZ1 ; If we were right, just skip on to do the work
+ lda TZ2_HOUR ; Wrong guess, just load up the second time zone
+GOT_TZ1
+;
+; 12 1 2 3 4 5 6 7 8 9 10 11 12 1 2 3 4 5 6 7 8 9 10 11 12
+; 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18
+; deca FF 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17
+; anda 07 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07 00 01 02 03 04 05 06 07
+ and #7 ; Convert the hour to the number of bells
+ tax ; Save away as an index into the start position table
+ bne NOTEIGHT ; Is it midnight (or a multiple of 8)
+ lda #8 ; Yes, so that is 8 bells, not zero
+NOTEIGHT
+ lsla ; Multiple the number of bells by 8 to get the length
+ lsla
+ lsla
+ sta SND_REMAIN ; Save away the number of bells left to play
+ lda STARTS,X ; Point to the pattern of the first bell
+ sta SND_POS
+ bset 1,BTNFLAGS ; Turn on the tic timer
+ JMP RELEASE ; And release our lock on the time
+;
+; (8) Playing the next note piece
+;
+NO_HOUR
+ lda SND_REMAIN ; Do we have any more notes to play?
+ bne DO_SOUND ; No, skip out
+STOPIT
+ lda #TONE_PAUSE ; End of the line, shut up the sound hardware
+ sta $28
+ clr SND_REMAIN ; Force us to quit looking at sound
+ bclr 1,BTNFLAGS ; and turn off the tic timer
+ rts
+
+DO_SOUND
+ deca ; Yes, note that we used one up
+ sta SND_REMAIN
+ lda SND_POS ; See where we are in the sound
+ lsra ; Divide by 8 to get the byte pointer
+ lsra
+ lsra
+ tax ; and make it an index
+ lda Pattern,X ; Get the current pattern byte
+ sta SND_NOTE ; And save it where we can test it
+ lda SND_POS ; Get the pointer to where we are in the sound
+ inc SND_POS ; Advance to the next byte
+ and #7 ; and hack off the high bytes to leave the bit index
+ lsla ; Convert that to a BRSET instruction
+ sta TSTNOTE ; And self modify our code so we can play
+TSTNOTE brset 0,SND_NOTE,PLAYIT ; If the note is not set, skip out
+ lda #TONE_PAUSE ; Not playing, we want to have silence
+ brskip2
+PLAYIT lda #NOTE_BELL ; Playing, select the bell tone
+ sta $28 ; And make it play
+NO_SOUND
+ rts \ No newline at end of file
diff --git a/from_toebes/sound1/sound1.asm b/from_toebes/sound1/sound1.asm
new file mode 120000
index 0000000..473c21a
--- /dev/null
+++ b/from_toebes/sound1/sound1.asm
@@ -0,0 +1 @@
+sound1.zsm \ No newline at end of file
diff --git a/from_toebes/sound1/sound1.known_good b/from_toebes/sound1/sound1.known_good
new file mode 100644
index 0000000..5668f3f
--- /dev/null
+++ b/from_toebes/sound1/sound1.known_good
Binary files differ
diff --git a/from_toebes/sound1/sound1.spc b/from_toebes/sound1/sound1.spc
new file mode 100644
index 0000000..7b008c8
--- /dev/null
+++ b/from_toebes/sound1/sound1.spc
Binary files differ
diff --git a/from_toebes/sound1/sound1.zsm b/from_toebes/sound1/sound1.zsm
new file mode 100644
index 0000000..36c08fc
--- /dev/null
+++ b/from_toebes/sound1/sound1.zsm
@@ -0,0 +1,83 @@
+;Sound: Datalink Default
+;Version: Sound1
+;
+; This sample corresponds to the default sounds that you get when you reset a datalink
+; watch to its default state.
+;
+;****************************************************************************************
+;* Copyright (C) 1997 John A. Toebes, VIII *
+;* All Rights Reserved *
+;* This program may not be distributed in any form without the permission of the author *
+;* jtoebes@geocities.com *
+;****************************************************************************************
+;
+ INCLUDE "WRISTAPP.I"
+;
+; This is the default sound table
+;
+DEF_SOUNDS
+ db SP_1-SD_1 ; 0000: 08
+
+ db SD_1-DEF_SOUNDS ; 0001: 0b BUTTON BEEP
+ db SD_2-DEF_SOUNDS ; 0002: 0c RETURN TO TIME
+ db SD_3-DEF_SOUNDS ; 0003: 0d HOURLY CHIME
+ db SD_4-DEF_SOUNDS ; 0004: 0e CONFIRMATION
+ db SD_5-DEF_SOUNDS ; 0005: 0f APPOINTMENT BEEP
+ db SD_5-DEF_SOUNDS ; 0006: 0f ALARM BEEP
+ db SD_5-DEF_SOUNDS ; 0007: 0f PROGRAM DOWNLOAD
+ db SD_5-DEF_SOUNDS ; 0008: 0f EXTRA
+ db SD_6-DEF_SOUNDS ; 0009: 11 COMM ERROR
+ db SD_7-DEF_SOUNDS ; 000a: 12 COMM DONE
+;
+; This is the soundlet count table which contains the duration
+; counts for the individual soundlets
+;
+SD_1 db SND_END+1 ; 000b: 81
+SD_2 db SND_END+1 ; 000c: 81
+SD_3 db SND_END+2 ; 000d: 82
+SD_4 db SND_END+4 ; 000e: 84
+SD_5 db 10,SND_END+40 ; 000f: 0a a8
+SD_6 db SND_END+10 ; 0011: 8a
+SD_7 db SND_END+32 ; 0012: a0
+;
+; This is the soundlet pointer table which contains the pointers to the soundlets
+;
+SP_1 db SL_2-DEF_SOUNDS ; 0013: 1d
+SP_2 db SL_1-DEF_SOUNDS ; 0014: 1b
+SP_3 db SL_3-DEF_SOUNDS ; 0015: 1f
+SP_4 db SL_2-DEF_SOUNDS ; 0016: 1d
+SP_5 db SL_4-DEF_SOUNDS ; 0017: 22
+ db SL_5-DEF_SOUNDS ; 0018: 27
+SP_6 db SL_6-DEF_SOUNDS ; 0019: 2a
+SP_7 db SL_2-DEF_SOUNDS ; 001a: 1d
+;
+; These are the soundlets themselves. The +1 or other number
+; indicates the duration for the sound.
+;
+SL_1 db TONE_HI_GSHARP+1 ; 001b: 91
+ db TONE_END ; 001c: 00
+
+SL_2 db TONE_MID_C+1 ; 001d: 31
+ db TONE_END ; 001e: 00
+
+SL_3 db TONE_MID_C+2 ; 001f: 32
+ db TONE_PAUSE+2 ; 0020: f2
+ db TONE_END ; 0021: 00
+
+SL_4 db TONE_HI_C+2 ; 0022: 22
+ db TONE_PAUSE+2 ; 0023: f2
+ db TONE_HI_C+2 ; 0024: 22
+ db TONE_PAUSE+10 ; 0025: fa
+ db TONE_END ; 0026: 00
+
+SL_5 db TONE_HI_C+2 ; 0027: 22
+ db TONE_PAUSE+2 ; 0028: f2
+ db TONE_END ; 0029: 00
+
+SL_6 db TONE_HI_C+3 ; 002a: 23
+ db TONE_MID_C+3 ; 002b: 33
+ db TONE_END ; 002c: 00
+;
+; This is the tone that the comm app plays for each record
+;
+ db TONE_MID_C/16 ; 002d: 03
diff --git a/from_toebes/spend0/spend0.asm b/from_toebes/spend0/spend0.asm
new file mode 120000
index 0000000..c3e782c
--- /dev/null
+++ b/from_toebes/spend0/spend0.asm
@@ -0,0 +1 @@
+spend0.zsm \ No newline at end of file
diff --git a/from_toebes/spend0/spend0.known_good b/from_toebes/spend0/spend0.known_good
new file mode 120000
index 0000000..37d8946
--- /dev/null
+++ b/from_toebes/spend0/spend0.known_good
@@ -0,0 +1 @@
+spend0.zap.app \ No newline at end of file
diff --git a/from_toebes/spend0/spend0.zap b/from_toebes/spend0/spend0.zap
new file mode 100644
index 0000000..17bafbb
--- /dev/null
+++ b/from_toebes/spend0/spend0.zap
@@ -0,0 +1,37 @@
+TDL0801972¬
+spend watch¬
+spend0¬
+spend watch - by John A. Toebes, VIII
+This keeps track of how much is in one of 7 categories
+
+ Press the NEXT/PREV buttons to advance/backup through the categories
+ Press the SET button to add/subtract/set/clear the amounts in the categories
+ If you press the set button while the action is blinking, it will be carried out, otherwise
+ you can cancel the operation.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+watchapp.hlp¬
+106¬
+SpendSet¬
+Timex Data Link 150 Watch¬
+CC03B0819D9DCC0276819D9D819D9DD601BD81CC023600CC0236140A0D0D1C1E0B1C0E1D0C151B1D181D0A152424240C0A1D01242424240C0A1D02242424240C0A1D03242424240C0A1D04242424240C0A1D05242424240C0A1D06242424240C0A1D0724242424000000000000000000000000000000000000000000000000050E130E0C180A14001915180A0C1801001505160E150D1D1A0A180C117F8585858B9100013EC7CACDD00709010C001B84001AFF001FFF0001FFFF02FF0186FF001D011AFF0186FF01A6FF0139FF001D4FB763CD03D3CD577AA691CD587EA696CD58A83F61A605B762A648CC584C006105CD577A1061A624B71D141EBE64CD594DCD5910BE65CD59513D642705BE65CD593ECD5920BE66CD593ECD5930B663484848AB27CC5845128FB691A11B27A1A186270A1390A10226023F62203BC604C32720A1022567221DB662A1042609CD0338CD03B4CD4E7A1161A605B762A639CC4E89109FC5119FB6622704A1052614AE63A607AD05CD03D3204A7C009F027A7AF4F781A103230CB6632739AE67A603ADE92031276F5FCF04F4AE63CF04F5AB6397B6624A48AB05CD57C7189081B662AE04CD6B0DB762A104260A3F673D632604A603B767CD01FDBE62D601ACCD587EBE622730A304222C029029260CAE3DA61DCD56D5B662BB6797DE01B1E664B75CE665B75DE666B75EBE62D601B8AE5CCD55BF149081AE60029009A608F7129020057A817D26FBA663AE66009F067A2AA5F720A27CF12A9E7F209BAD6DB6672720A102275625143F643F653F663D63264AAE174FD701775A2AFA81306430653066B666EBF2B766B665EBF1B765B664EBF0B764AE663D67271EAD08AD06B6642BC62018F62A06AB64F75A7A815A81F6A0642BF9F75A7C81ADF5ADF3AD0DB664E7F0B665E7F1B666E7F281B663AE0342AB879781A6C0B796B663B75F3F673F63AE02AD90A607B760B660AD0BCD03383A6026F5B65FB763ADD4E6F0B764E6F1B765E6F2B76681¬
+25663¬
+0¬
+spend watch¬
+spend0¬
+spend watch - by John A. Toebes, VIII
+This keeps track of how much is in one of 7 categories
+
+ Press the NEXT/PREV buttons to advance/backup through the categories
+ Press the SET button to add/subtract/set/clear the amounts in the categories
+ If you press the set button while the action is blinking, it will be carried out, otherwise
+ you can cancel the operation.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+watchapp.hlp¬
+106¬
+SpendSet¬
+Timex Data Link 150s Watch¬
+CC03B0819D9DCC0276819D9D819D9DD601BD81CC023600CC0236140A0D0D1C1E0B1C0E1D0C151B1D181D0A152424240C0A1D01242424240C0A1D02242424240C0A1D03242424240C0A1D04242424240C0A1D05242424240C0A1D06242424240C0A1D0724242424000000000000000000000000000000000000000000000000050E130E0C180A14001915180A0C1801001505160E150D1D1A0A180C117F8585858B9100013EC7CACDD00709010C001B84001AFF001FFF0001FFFF02FF0186FF001D011AFF0186FF01A6FF0139FF001D4FB763CD03D3CD5AA0A691CD577FA696CD57A93F61A605B762A648CC574D006105CD5AA01061A622B71D141EBE64CD584ECD5811BE65CD58523D642705BE65CD583FCD5821BE66CD583FCD5831B663484848AB27CC5746128FB691A11B27A1A186270A1390A10226023F62203BC604C32720A1022567221DB662A1042609CD0338CD03B4CD4E691161A605B762A639CC4E78109FC5119FB6622704A1052614AE63A607AD05CD03D3204A7C009F027A7AF4F781A103230CB6632739AE67A603ADE92031276F5FCF04F4AE63CF04F5AB6397B6624A48AB05CD56C8189081B662AE04CD6B16B762A104260A3F673D632604A603B767CD01FDBE62D601ACCD577FBE622730A304222C029029260CAE3DA631CD59E7B662BB6797DE01B1E664B75CE665B75DE666B75EBE62D601B8AE5CCD55AE149081AE60029009A608F7129020057A817D26FBA663AE66009F067A2AA5F720A27CF12A9E7F209BAD6DB6672720A102275625143F643F653F663D63264AAE174FD701775A2AFA81306430653066B666EBF2B766B665EBF1B765B664EBF0B764AE663D67271EAD08AD06B6642BC62018F62A06AB64F75A7A815A81F6A0642BF9F75A7C81ADF5ADF3AD0DB664E7F0B665E7F1B666E7F281B663AE0342AB879781A6C0B796B663B75F3F673F63AE02AD90A607B760B660AD0BCD03383A6026F5B65FB763ADD4E6F0B764E6F1B765E6F2B76681¬
+30206¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/spend0/spend0.zsm b/from_toebes/spend0/spend0.zsm
new file mode 100644
index 0000000..70488cb
--- /dev/null
+++ b/from_toebes/spend0/spend0.zsm
@@ -0,0 +1,656 @@
+;Name: spend watch
+;Version: spend0
+;Description: spend watch - by John A. Toebes, VIII
+;This keeps track of how much is in one of 7 categories
+;
+; Press the NEXT/PREV buttons to advance/backup through the categories
+; Press the SET button to add/subtract/set/clear the amounts in the categories
+; If you press the set button while the action is blinking, it will be carried out, otherwise
+; you can cancel the operation.
+;
+;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
+;Parent: SpendSet
+;****************************************************************************************
+;* Copyright (C) 1997 John A. Toebes, VIII *
+;* All Rights Reserved *
+;* This program may not be distributed in any form without the permission of the author *
+;* jtoebes@geocities.com *
+;****************************************************************************************
+;
+; History:
+; 31 July 96 - Corrected problem with totals not being recalculated when you reenter
+; the wristapp.
+;
+ INCLUDE "WRISTAPP.I"
+;
+; (1) Program specific constants
+;
+; We use a few extra bytes here in low memory. Since we can't possibly
+; be running while the COMM app is running, we have no chance of
+; conflicting with it's use of this memory.
+;
+BLINK_BUF EQU $5C ; 3 Byte Buffer for the blink routine
+; EQU $5D
+; EQU $5E
+CAT_SAVE EQU $5F ; Temporary counter variable
+COUNTER EQU $60 ; Temporary variable to hold the
+FLAGBYTE EQU $61
+; Bit 0 indicates that the display does not need to be cleared
+; The other bits are not used
+
+CURRENT_MODE EQU $62 ; The current mode that we are in
+MODE_SELECT EQU 0 ; Set mode, selecting which category to modify
+MODE_HUNDREDS EQU 1 ; Set mode, changing the hundreds of dollars digits
+MODE_DOLLARS EQU 2 ; Set mode, changing the dollars digits
+MODE_CENTS EQU 3 ; Set mode, changing the cents
+MODE_ACTION EQU 4 ; Set mode, changing the action
+MODE_VIEW EQU 5 ; Normal display mode
+
+CATEGORY EQU $63 ; Current category
+;
+; These three bytes need to be contiguous. The represent the current
+; value that is being operated on
+;
+HUNDREDS EQU $64
+DOLLARS EQU $65
+CENTS EQU $66
+
+ACTION EQU $67 ; Selector for the current action
+ACT_ADD EQU 0
+ACT_SUB EQU 1
+ACT_SET EQU 2
+ACT_CLEAR EQU 3
+AMT_BASE EQU $F0
+;
+;
+; (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: jmp DO_UPD ; Called to handle any timers or time events - WRIST_DOTIC
+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_STATE
+ db STATETAB0-STATETAB0
+L0127: jmp HANDLE_STATE
+ db STATETAB1-STATETAB0
+;
+; (3) Program strings
+;
+; These strings represent the 4 possible actions. They need to be early on in the data segment so that
+; then can be pointed to by using 8-bit offset addressing. They are exactly 3 bytes long and are
+; displayed by using the BLINK_TZONE routine
+;
+S3_MODE:
+S3_ADD timex "ADD"
+S3_SUB timex "SUB"
+S3_SET timex "SET"
+S3_CLR timex "CLR"
+;
+; These are the categories that the end user has configured. They are set by using the SPENDSET program
+; which searches for the first string "TOTAL ". These strings must be exactly 8 bytes each in order with
+; total being the first one.
+;
+S8_TOTAL: timex "TOTAL "
+S8_CAT1: timex "CAT1 "
+S8_CAT2: timex "CAT2 "
+S8_CAT3: timex "CAT3 "
+S8_CAT4: timex "CAT4 "
+S8_CAT5: timex "CAT5 "
+S8_CAT6: timex "CAT6 "
+S8_CAT7: timex "CAT7 "
+;
+; These are the running amounts for each category. Note that you can actually
+; initialize them with some default and the code will run properly
+;
+AMT_TOTAL: db 0,0,0
+AMT_CAT1: db 0,0,0
+AMT_CAT2: db 0,0,0
+AMT_CAT3: db 0,0,0
+AMT_CAT4: db 0,0,0
+AMT_CAT5: db 0,0,0
+AMT_CAT6: db 0,0,0
+AMT_CAT7: db 0,0,0
+;
+; These strings prompt for the current mode that we are in. They are displayed on the top line of
+; the display.
+;
+S6_SELECT timex6 "SELECT"
+S6_AMOUNT timex6 "AMOUNT"
+S6_ACTION timex6 "ACTION"
+S6_SPEND: timex6 "SPEND" ; save a byte by leaching off the space on the start of the next string
+S6_WATCH: timex6 " WATCH"
+;
+; This table selects which string is to be displayed. It is directly indexed by the current mode
+;
+MSG_TAB db S6_SELECT-START ; 0 - MODE_SELECT
+ db S6_AMOUNT-START ; 1 - MODE_HUNDREDS
+ db S6_AMOUNT-START ; 2 - MODE_DOLLARS
+ db S6_AMOUNT-START ; 3 - MODE_CENTS
+ db S6_ACTION-START ; 4 - MODE_ACTION
+ db S6_SPEND-START ; 5 - MODE_VIEW
+;
+; This is one of the magic tricks for providing the source for the blink routine.
+; These are base pointers (offset from HUNDREDS) that we use to copy three bytes into
+; BLINK_BUF. The interesting one here is the MODE_CENTS entry which points to DATDIGIT1
+; This works because the last number that we format happens to be the cents amount,
+; and the blink routine expects the two characters instead of the actual value.
+;
+DATASRC db HUNDREDS-HUNDREDS ; 1 - MODE_HUNDREDS
+ db DOLLARS-HUNDREDS ; 2 - MODE_DOLLARS
+ db DATDIGIT1-HUNDREDS ; 3 - MODE_CENTS
+ db S3_ADD-HUNDREDS ; 4 - MODE_ACTION 0 - ACT_ADD
+ db S3_SUB-HUNDREDS ; 4 - MODE_ACTION 1 - ACT_SUB
+ db S3_SET-HUNDREDS ; 4 - MODE_ACTION 2 - ACT_SET
+ db S3_CLR-HUNDREDS ; 4 - MODE_ACTION 3 - ACT_CLR
+;
+; This is the parameter to select which blink routine we want to use
+;
+BLINK_PARM db BLINK_MID12 ; 1 - MODE_HUNDREDS
+ db BLINK_MID34 ; 2 - MODE_DOLLARS
+ db BLINK_SECONDS ; 3 - MODE_CENTS
+ db BLINK_TZONE ; 4 - MODE_ACTION
+;
+; (4) State Tables
+;
+; This set of state tables is a little special since we actually use the
+; same state processing routine for both states. This saves us a lot of
+; memory but still allows us to let the state table make it easy to exit
+; the app with the MODE button
+;
+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_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_SET,TIM_ONCE,1 ; Set button
+ db EVT_DNANY4,TIM_ONCE,0 ; NEXT, PREV, SET, MODE 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 ; Return to state 0
+ db EVT_END ; End of table
+;
+; (5) Put up the initial banner screen
+;
+HANDLE_ENTER
+ clra
+ sta CATEGORY ; We start out displaying the totals
+ jsr FETCH_CATEGORY
+ jsr CLEARALL ; Clear the display
+ lda #S6_SPEND-START ; Put 'SPEND ' on the top line
+ jsr PUT6TOP
+ lda #S6_WATCH-START ; Put ' WATCH' on the second line
+ jsr PUT6MID
+ clr FLAGBYTE ; Force us to clear the display
+ lda #MODE_VIEW ; Start out in the VIEW mode
+ sta CURRENT_MODE
+ lda #SYS8_MODE ; Put MODE on the bottom line
+ jmp PUTMSGBOT
+;
+; (6) This is the main screen update routine.
+;---------------------------------------------------------------
+; Routine:
+; SHOWCURRENT
+; Parameters:
+; HUNDREDS,DOLLARS,CENTS - Current value to be displayed
+; 0,FLAGBYTE - Screen state (CLR=Must clear it first)
+; CATEGORY - the current category to be displayed
+; Returns:
+; DATDIGIT1,DATDIGIT2 - 2 digit characters for the cents value
+; Purpose:
+; This routine shows the current selected category and value for the category
+;---------------------------------------------------------------
+SHOWCURRENT
+ brset 0,FLAGBYTE,NOCLEAR ; If we don't need to clear the display, skip it
+ jsr CLEARALL ; Clear the display
+ bset 0,FLAGBYTE ; And remember that we did it
+NOCLEAR
+ lda #ROW_MP45 ; Turn on the decimal point
+ sta DISP_ROW
+ bset COL_MP45,DISP_COL
+ ldx HUNDREDS ; Get the Hundreds
+ jsr FMTBLANK0 ; Format it
+ jsr PUTMID12 ; and display it
+ ;
+ ; We want to output the dollars, but if there were no hundreds, we want to let the
+ ; first digit be a blank. To do this, we simply let it be a blank and set it to a zero
+ ; if there was actually anything in the hundreds field
+ ;
+ ldx DOLLARS ; Get the Dollars
+ jsr FMTX ; Format it
+ tst HUNDREDS ; Do we need to have a leading zero?
+ beq NOBLANKIT ; No, so it is fine
+ ldx DOLLARS ; Yes, Get the Dollars again
+ jsr FMTXLEAD0 ; And format it with a leading zero
+NOBLANKIT
+ jsr PUTMID34 ; Display the Dollars
+ ldx CENTS ; Get the Cents
+ jsr FMTXLEAD0 ; Format it (and leave it around for later)
+ jsr PUTMID56 ; and display it.
+ lda CATEGORY ; Get which category we want
+ lsla ; *2
+ lsla ; *4
+ lsla ; *8
+ add #S8_TOTAL-START ; *8+the start of the string
+ jmp BANNER8 ; and display the right string
+;
+; (7) State Table 0 and 1 Handler
+; This is called to process the state events.
+; We see SET, RESUME, DNANY4, and UPANY4 events
+;
+HANDLE_STATE:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_ENTER ; Is this the initial state?
+ beq HANDLE_ENTER
+ cmp #EVT_DNANY4 ; How about a button pressed?
+ beq HANDLE_DNANY
+ bclr 1,BTNFLAGS ; Turn off the repeat counter
+ cmp #EVT_SET ; Did they press the set button
+ bne SKIP2 ; No
+ clr CURRENT_MODE ; Yes, Go to MODE_SELECT
+SKIP2 bra GOREFRESH
+;
+; (8) They pressed a button, so handle it
+;
+HANDLE_DNANY
+ lda BTN_PRESSED ; Let's see what the button they pressed was
+ beq DO_NEXT ; MODE=1, and NEXT=0, so if it is less, it must be the next button
+ cmp #EVT_SET ; MODE=1 SET=2 PREV=3, test all at once
+ blo DO_MODE ; <2 = 1 so we have a EVT_MODE
+ bhi DO_PREV ; >2 = 3 so we have a EVT_PREV
+ ;
+ ; They pressed the set button, so we want to carry out the operation IF they have
+ ; one currently selected.
+ ;
+DO_SETOUT
+ lda CURRENT_MODE ; See what mode we were in
+ cmp #MODE_ACTION ; Is it the ACTION mode?
+ bne NO_ACTION ; No, so just cancel the operation
+ jsr DO_OPERATION ; Do what they requested
+ jsr DO_TOTAL ; And total up everything
+ jsr PLAYCONF ; Plus tell them that we did it
+NO_ACTION
+ bclr 0,FLAGBYTE ; We need to clear the display
+ lda #MODE_VIEW ; And switch back to VIEW mode
+ sta CURRENT_MODE
+ lda #EVT_USER2 ; And go back to state 0
+ jmp POSTEVENT
+;
+; (9) This handles the update routine to change a digit...
+;
+DO_NEXT
+ bset 0,SYSFLAGS ; Mark our update direction as up
+ BRSKIP2 ; and skip over the next instruction
+DO_PREV
+ bclr 0,SYSFLAGS ; Mark our update direction as down
+DO_UPD
+ lda CURRENT_MODE ; Which mode are we in?
+ beq CHANGE_CATEGORY ; 0=MODE_SELECT, so change the category
+ cmp #MODE_VIEW ; 5=MODE_VIEW, so we also change the category
+ bne TRYOTHERS
+CHANGE_CATEGORY
+; (10) updating the category
+ ldx #CATEGORY ; Point to the category variable
+ lda #7 ; get our range of values
+ bsr ADJUST_PX_ANDA ; And let the routine do the adjust for us
+ jsr FETCH_CATEGORY ; Update the current amount from the new category
+GOREFRESH
+ bra REFRESH
+;
+; (11) ADJUST_PX_ANDA - a routine to adjust a value based on the direction
+;---------------------------------------------------------------
+; Routine:
+; ADJUST_PX_ANDA
+; Parameters:
+; A - Binary range to limit value within ((2**x)-1)
+; 0,SYSFLAGS - Direction to adjust, SET=UP
+; X - Pointer to value to be adjusted
+; Returns:
+; Value pointed to by X is adjusted
+; Purpose:
+; This routine adjusts a value up or down based on the current direction, wrapping
+; it to the binary range indicated by the value in A. Note that this value must
+; be a power of 2-1 (e.g. 1, 3, 7, 15, 31, 63, or 127)
+;---------------------------------------------------------------
+ADJUST_PX_ANDA
+ inc ,X
+ brset 0,SYSFLAGS,NODEC
+ dec ,X
+ dec ,X
+NODEC and ,X
+ sta ,X
+ rts
+;
+; (12) Try updating one of the other modes
+; We have already handled MODE_SELECT and MODE_VIEW. This code handles
+; MODE_HUNDREDS, MODE_DOLLARS, MODE_CENTS, and MODE_ACTION
+;
+TRYOTHERS
+ cmp #MODE_CENTS ; 3=MODE_CENTS
+ bls TRYMORE ; If it is <=, then we leave only MODE_ACTION
+; (13) updating the Action
+ lda CATEGORY ; Which category is it?
+ beq REFRESH ; If we are displaying the total, you can't change the action
+ ldx #ACTION ; Point to the current action
+ lda #3 ; and the range of actions
+ bsr ADJUST_PX_ANDA ; and let our simple routine handle it for us
+ bra REFRESH
+TRYMORE
+ beq DOCENTS ; If it is MODE_CENTS, go handle it
+; (14) Update MODE_HUNDREDS=1 and MODE_DOLLARS=2
+ clrx ; Set the lower limit =0
+ stx UPDATE_MIN
+ ldx #99 ; And the upper limit= 99
+ stx UPDATE_MAX
+ add #HUNDREDS-1 ; Point to the right byte to update
+ tax ; And put it in X as the parameter
+ lda CURRENT_MODE ; MODE=1 MODE=2
+ deca ; 0 1
+ lsla ; 0 2
+ add #UPD_MID12 ; 5=UPD_MID12 7=UPD_MID34
+ jsr START_UPDATEP ; And prepare the update routine
+ bset 4,BTNFLAGS ; Mark that the update is now pending
+ rts
+;
+; (15) This is where we switch which digit we are changing...
+;
+DO_MODE
+ lda CURRENT_MODE ; Get the mode
+ ldx #MODE_ACTION ; Limit it to the first 5 modes
+ jsr INCA_WRAPX ; And let the system increment it for us
+ sta CURRENT_MODE ; Save it back
+ ; When we switch to the ACTION mode and we have the Totals category showing,
+ ; we need to limit them to the single action of CLEAR
+ ;
+ cmp #MODE_ACTION ; Did we go to action mode?
+ bne REFRESH ; No, nothing to do
+ clr ACTION ; Reset the action to be add
+ tst CATEGORY ; Are we displaying the totals
+ bne REFRESH ; No, nothing more to do
+ lda #ACT_CLEAR ; Yes, switch them to CLEAR
+ sta ACTION
+;
+; (16) Refresh the screen and start blinking the current digit...
+;
+REFRESH
+ ; 0 - SELECT <Category>
+ ; 1 - AMOUNT (Blink hundreds)
+ ; 2 - AMOUNT (Blink dollars)
+ ; 3 - AMOUNT (Blink cents)
+ ; 4 - ACTION
+ jsr SHOWCURRENT ; Format the screen
+ ldx CURRENT_MODE ; Get the mode
+ lda MSG_TAB,X ; So that we can get the message for it
+ jsr PUT6TOP ; And put that on the top of the display
+ ;
+ ; Now we need to make the right thing blink
+ ;
+ ldx CURRENT_MODE ; Are we in Select mode?
+ beq NOBLINK2 ; Yes, don't blink anything
+ cpx #MODE_ACTION ; How about ACTION MODE?
+ bhi NOBLINK2 ; >ACTION is VIEW mode, so if so, don't blink either
+ ; 1 -> BLINK_MID12 PARM=&HUNDREDS
+ ; 2 -> BLINK_MID34 PARM=&DOLLARS
+ ; 3 -> BLINK_SECONDS PARM=&2Characters
+ ; 4 -> BLINK_TZONE PARM=&3Characters
+ brset 1,BTNFLAGS,NOBLINK2 ; Also, we don't want to be blinking if we are in an update routine
+ bne SETUP_BLINK ; If we were not in action mode, we have the right data source
+ ; Put a > on the display
+ ldx #C_RIGHTARR ; Put a > sign right in front of the action
+ lda #POSL3_5
+ jsr PUTLINE3
+ lda CURRENT_MODE ; Get the mode
+ add ACTION ; And add in the action
+ tax ; To compute our data source pointer
+SETUP_BLINK
+;
+; (17) Set up the parameters for and call the blink routine
+;
+ ldx DATASRC-1,X ; Get the offsetted pointer to the right data
+ lda HUNDREDS,X ; And copy the 3 bytes to our blink buffer
+ sta BLINK_BUF
+ lda HUNDREDS+1,X
+ sta BLINK_BUF+1
+ lda HUNDREDS+2,X
+ sta BLINK_BUF+2
+ ldx CURRENT_MODE ; Get our mode again
+ lda BLINK_PARM-1,X ; and use it to pick up which parameter we are passing
+ ldx #BLINK_BUF ; Point to the common blink buffer
+ jsr START_BLINKP ; And do it
+ bset 2,BTNFLAGS ; Mark a blink routine as pending
+NOBLINK2
+ rts
+;
+; (18) Update MODE_CENTS
+; This is a special case since we don't have a system routine that allows updating
+; the right most digits on the middle line. Fortunately we can fake it by turning
+; on the tic timer and waiting until 8 tics have passed before going into a repeat
+; loop. The code has been carefully constructed so that the tic timer can just go
+; straight to the DO_UPD code to work.
+DOCENTS
+ ldx #COUNTER ; Point to the counter (saves code size)
+ brset 1,BTNFLAGS,NOSTART ; Are we already in an update loop?
+ lda #8 ; No, we need to wait 8 tics
+ sta ,X ; X->COUNTER ; Save the value
+ BSET 1,BTNFLAGS ; and start the timer
+ bra DOIT ; But still do it once right now
+;
+DEC_DELAY
+ dec ,X ; X->COUNTER ; We haven't hit the limit, decrement it and try again
+ rts
+NOSTART
+ tst ,X ; X->COUNTER ; We are in the loop, have we hit the limit?
+ bne DEC_DELAY ; no, go off and delay once more
+DOIT
+ lda #99 ; Our upper limit is 99
+ ldx #CENTS ; Point to the cents variable (saves code size)
+ brset 0,SYSFLAGS,UPCENTS ; Are we in an up mode?
+ dec ,X ; X->CENTS ; Down, decrement the value
+ bpl REFRESH ; If we didn't wrap, just go display it
+ sta ,X ; X->CENTS ; We wrapped, save the upper limit
+ bra REFRESH ; and go display it
+UPCENTS
+ inc ,X ; X->CENTS ; Up, increment the value
+ cmp ,X ; X->CENTS ; Did we hit the limit?
+ bpl REFRESH ; No, go display it
+ clr ,X ; X->CENTS ; Yes, wrap to the bottom
+ bra REFRESH ; and display it
+;
+; (19) DO_OPERATION - Perform the requested operation
+;---------------------------------------------------------------
+; Routine:
+; DO_OPERATION
+; Parameters:
+; HUNDREDS,DOLLARS,CENTS - Amount to be added/subtracted/set
+; CATEGORY - Item to be updated
+; ACTION - 0 = ACT_ADD
+; 1 = ACT_SUB
+; 2 = ACT_SET
+; 3 = ACT_CLEAR
+; Purpose:
+; Adjusts the corresponding category by the given amount
+;---------------------------------------------------------------
+DO_OPERATION
+ bsr COMPUTE_CATEGORY_BASE ; Point to the data for our category
+ lda ACTION ; Which action is it?
+ beq DO_ADD ; 0=ADD, go do it
+ cmp #ACT_SET ; 3 way compare here... (code trick)
+ beq DO_SET ; 2=SET, go do it
+ blo DO_SUB ; <2=1 (SUB), go do it
+DO_CLR ; >2 = 3 (CLEAR)
+ clr HUNDREDS ; Clear out the current values
+ clr DOLLARS
+ clr CENTS
+ tst CATEGORY ; Were we clearing the total?
+ bne DO_SET ; No, just handle it
+ ;
+ ; They want to clear everything
+ ;
+ ldx #(3*8)-1 ; Total number of categories
+CLEAR_TOTALS
+; Mini Routine here X=number of bytes to clear
+ clra
+CLR_MORE
+ sta AMT_TOTAL,X ; Clear out the next byte
+ decx ; Decrement the number to do
+ bpl CLR_MORE ; And go for more
+ rts
+;
+; (20) Handle Subtracting a value
+;
+DO_SUB
+ neg HUNDREDS ; Just negate the value to be added
+ neg DOLLARS
+ neg CENTS ; And fall into the add code
+;
+; (21) Handle Adding a value
+;
+DO_ADD
+ lda CENTS ; Add the cents
+ add AMT_BASE+2,X
+ sta CENTS
+ lda DOLLARS ; Add the dollars
+ add AMT_BASE+1,X
+ sta DOLLARS
+ lda HUNDREDS ; Add the hundreds
+ add AMT_BASE,X
+ sta HUNDREDS
+ ldx #CENTS ; Point to the cents as it will be the first one we fix up
+ tst ACTION ; See what type of operation we just did
+ beq FIXUP_ADD ; Was it an ADD? If so, do do it
+ bsr TRYDEC ; Decrement, fix up the Cents
+ bsr TRYDEC ; Then fix up the dollars
+ lda HUNDREDS ; Did the hundreds underflow as a result?
+ bmi DO_CLR ; Yes, so just set everything to zero
+ bra DO_SET ; No, so copy over the values to the current entry
+TRYDEC
+ lda ,X ; Get the current byte to check
+ bpl RETDEC ; If it didn't underflow, then skip to the next byte
+ add #100 ; Add back the 100 that it underflowed
+ sta ,X ; And save that away
+ decx ; Back up to the next most significant byte
+ dec ,X ; and borrow the one
+ rts
+RETDEC decx ; No need to do anything, so skip to the next byte
+ rts
+TRYADD
+ lda ,X ; Get the current byte to check
+ sub #100 ; See if it was less than 100
+ bmi RETDEC ; If so, then it was already normalized so skip out
+ sta ,X ; It was an overflow, so save the fixed value
+ decx ; Skip to the next byte
+ inc ,X ; And add in the overflow
+ rts
+
+FIXUP_ADD
+ bsr TRYADD ; Fix up the cents
+ bsr TRYADD ; and then fix up the dollars
+;
+; (22) Handle setting a value
+;
+DO_SET
+ bsr COMPUTE_CATEGORY_BASE ; Point to the data for our category
+ lda HUNDREDS ; Copy over the values to the current category
+ sta AMT_BASE,X
+ lda DOLLARS
+ sta AMT_BASE+1,X
+ lda CENTS
+ sta AMT_BASE+2,X
+ rts
+;
+; (23) COMPUTE_BASE - Computes an offset pointer to get to the total amounts
+; This is a trick to save us a few bytes in the instructions.
+;---------------------------------------------------------------
+; Routine:
+; COMPUTE_CATEGORY_BASE, COMPUTE_BASE
+; Parameters:
+; A - Offset into total
+; Returns:
+; X - Pointer relative to AMT_BASE to use
+; Purpose:
+; Computes an offset pointer to get to the total amounts
+;---------------------------------------------------------------
+COMPUTE_CATEGORY_BASE
+ lda CATEGORY ; Get our category
+COMPUTE_BASE
+ ldx #3
+ mul
+ add #AMT_TOTAL-AMT_BASE
+ tax
+ rts
+;
+; (24) 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
+ ; Fall into DO_TOTAL
+;
+; (25) DO_TOTAL - Recomputes the current total
+;---------------------------------------------------------------
+; Routine:
+; DO_TOTAL
+; Parameters:
+; NONE
+; Purpose:
+; Recomputes the current total
+;---------------------------------------------------------------
+DO_TOTAL
+ lda CATEGORY ; Remember our category
+ sta CAT_SAVE
+ clr ACTION ; Say that we want to add 0=ACT_ADD
+ clr CATEGORY ; To the total category
+ ldx #2 ; But we need to clear it first
+ bsr CLEAR_TOTALS
+ lda #7 ; And iterate over the 7 categories
+ sta COUNTER
+TOT_LOOP
+ lda COUNTER ; Get our current category
+ bsr FETCH_CATEGORY ; And fetch the data
+ jsr DO_OPERATION ; Then add it to the total
+ dec COUNTER ; Go to the next category
+ bne TOT_LOOP ; Until we are done
+ lda CAT_SAVE ; Restore the category
+ sta CATEGORY
+ ; fall into FETCH_CATEGORY
+; (26) FETCH_CATEGORY - Retrieves the value of the total amount for the selected category
+;---------------------------------------------------------------
+; Routine:
+; FETCH_CATEGORY
+; Parameters:
+; A - Category to be fetched
+; Returns:
+; HUNDREDS,DOLLARS,CENTS - Current value of selected category
+; Purpose:
+; Retrieves the value of the total amount for the selected category
+;---------------------------------------------------------------
+FETCH_CATEGORY
+ bsr COMPUTE_BASE ; Get the pointer to the base
+ lda AMT_BASE,X ; And retrieve the data
+ sta HUNDREDS
+ lda AMT_BASE+1,X
+ sta DOLLARS
+ lda AMT_BASE+2,X
+ sta CENTS
+ rts
+;--------------------END OF CODE---------------------------------------------------
diff --git a/from_toebes/spend0/spendset.exe b/from_toebes/spend0/spendset.exe
new file mode 100644
index 0000000..859875a
--- /dev/null
+++ b/from_toebes/spend0/spendset.exe
Binary files differ
diff --git a/from_toebes/testsnd/testsnd.asm b/from_toebes/testsnd/testsnd.asm
new file mode 100644
index 0000000..949b2dc
--- /dev/null
+++ b/from_toebes/testsnd/testsnd.asm
@@ -0,0 +1,155 @@
+;Name: Test Sound
+;Version: TESTSND
+;Description: This routine tests the various sound capabilities of the datalink.
+;by John A. Toebes, VIII
+;
+;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
+;
+CURRENT_VAL EQU $61
+;
+; (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 DOEVENT0
+ db TABLE0-TABLE0
+L0127: jmp DOEVENT1
+ db TABLE1-TABLE0
+;
+; (3) Program strings
+S6_SOUND: timex6 "SOUND "
+S6_TEST: timex6 " TEST "
+S8_TOEBES: timex "J.TOEBES"
+;
+; (4) State Table
+;
+STATETAB0:
+TABLE0:
+ db 0
+ db EVT_ENTER,TIM_LONG,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_TIMER2,TIM_ONCE,0 ;
+ db EVT_DNNEXT,TIM_ONCE,1 ; Next button
+ db EVT_DNPREV,TIM_ONCE,1 ; Prev button
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_DNSET,TIM_ONCE,0 ; Set button
+ db EVT_UPSET,TIM_ONCE,0 ;
+ db EVT_END
+
+TABLE1:
+ db 1
+ db EVT_UPNEXT,TIM_ONCE,1 ; Releasing the next button
+ db EVT_UPPREV,TIM_ONCE,1 ; Releasing the prev button
+ db EVT_USER0,TIM_ONCE,0 ; Return to the main state table
+ 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
+;
+DOEVENT0:
+ bset 1,APP_FLAGS ; Allow us to be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_RESUME ; Did another app get called in the meantime?
+ beq REFRESH ; We will refresh the display in this case
+ cmp #EVT_TIMER2 ; Did the initial timer expire?
+ beq REFRESH ; Yes, clean up the screen
+ cmp #EVT_ENTER ; Is this the initial state?
+ beq INITBANNER ; Yes, put up the banner
+ cmp #EVT_DNSET ; Did they hit the set button
+ beq PLAYIT
+ cmp #EVT_UPSET
+ beq SILENCE
+ rts
+;
+; (6) Sound playing code. Note that we go straight to the hardware here for this one
+;
+PLAYIT:
+ lda #ROW_NOTE ; Turn on the little note symbol
+ sta DISP_ROW
+ bset COL_NOTE,DISP_COL
+ lda CURRENT_VAL
+ sta $28
+ rts
+
+SILENCE:
+ lda #ROW_NOTE ; Turn off the little note symbol
+ sta DISP_ROW
+ bclr COL_NOTE,DISP_COL
+ lda #15
+ sta $28
+ rts
+
+REFRESH:
+ jsr CLEARALL ; Clear the display
+ lda #S6_SOUND-START ; Put "SOUND" on the top of the display
+ jsr PUT6TOP
+ ldx CURRENT_VAL
+ jsr FMTX
+ jsr PUTMID34
+ bra JBANNER
+
+INITBANNER:
+ jsr CLEARALL ; Clear the display
+ lda #S6_SOUND-START ; Put 'SOUND ' on the top line
+ jsr PUT6TOP
+ lda #S6_TEST-START ; Put ' TEST ' on the second line
+ jsr PUT6MID
+JBANNER
+ lda #S8_TOEBES-START
+ jmp BANNER8
+;
+; (7) This is the main initialization routine which is called when we first get the app into memory
+;
+MAIN:
+ bset 7,WRISTAPP_FLAGS ; Tell them that we are a live application
+ clr CURRENT_VAL
+ rts
+;
+; (8) State Table 1 Handler
+;
+; This is called when we press the prev/next button or when the timer fires during that event
+;
+DOEVENT1:
+ lda BTNSTATE
+ cmp #EVT_DNPREV
+ beq GO_DOWN
+ cmp #EVT_DNNEXT
+ beq GO_UP
+ lda #EVT_USER0
+ jmp POSTEVENT
+
+GO_DOWN bclr 0,SYSFLAGS ; Mark update direction as down
+ bra DOUPDN
+GO_UP bset 0,SYSFLAGS ; Mark update direction as up
+DOUPDN clra
+ jsr CLEARMID
+ sta UPDATE_MIN
+ lda #99
+ sta UPDATE_MAX
+ ldx #CURRENT_VAL
+ lda #UPD_MID34
+ jsr START_UPDATEP
+ bset 4,BTNFLAGS
+ rts
diff --git a/from_toebes/testsnd/testsnd.known_good b/from_toebes/testsnd/testsnd.known_good
new file mode 120000
index 0000000..1ef9b2c
--- /dev/null
+++ b/from_toebes/testsnd/testsnd.known_good
@@ -0,0 +1 @@
+testsnd.zap.app \ No newline at end of file
diff --git a/from_toebes/testsnd/testsnd.zap b/from_toebes/testsnd/testsnd.zap
new file mode 100644
index 0000000..165ef1f
--- /dev/null
+++ b/from_toebes/testsnd/testsnd.zap
@@ -0,0 +1,26 @@
+TDL0724962¬ Applet file header
+Test Sound¬ Applet friendly name
+testsnd1¬ Applet version #
+This routine tests the various sound capabilities of the datalink.
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC01B7819D9D819D9D819D9D819D9DD6013F81CC016400CC01BC1A050019150D1D1D180E05181D13321D180E0B0E1C001B84001AFF001FFF0080FF0183FF0101FFFF82FF00A2FF001D01A0FF01A3FF0137FF001D128FB691A11A2727A11F2723A11B2731A1822705A1A2270C81A60EB71D181EB661B72881A60EB71D191EA60FB72881CD577AA61BCD587EBE61CD5951CD5920200DCD577AA61BCD587EA621CD58A8A627CC58451E963F6181B691A1832709A1802709A637CC4E89119F2002109F4FCD58D8C704F4A663C704F5AE61A607CD57C7189081¬
+33981¬
+0¬ No data
+Test Sound¬ Applet friendly name
+testsnd2¬ Applet version #
+This routine tests the various sound capabilities of the datalink.
+
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC01B7819D9D819D9D819D9D819D9DD6013F81CC016400CC01BC1A050019150D1D1D180E05181D13321D180E0B0E1C001B84001AFF001FFF0080FF0183FF0101FFFF82FF00A2FF001D01A0FF01A3FF0137FF001D128FB691A11A2727A11F2723A11B2731A1822705A1A2270C81A60CB71D181EB661B72881A60CB71D191EA60FB72881CD5AA0A61BCD577FBE61CD5852CD5821200DCD5AA0A61BCD577FA621CD57A9A627CC57461E963F6181B691A1832709A1802709A637CC4E78119F2002109F4FCD57D9C704F4A663C704F5AE61A607CD56C8189081¬
+59850¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/testsnd/testsnd.zsm b/from_toebes/testsnd/testsnd.zsm
new file mode 100644
index 0000000..f81b602
--- /dev/null
+++ b/from_toebes/testsnd/testsnd.zsm
@@ -0,0 +1,154 @@
+;Name: Test Sound
+;Version: TESTSND
+;Description: This routine tests the various sound capabilities of the datalink.
+;by John A. Toebes, VIII
+;
+;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
+;
+CURRENT_VAL EQU $61
+;
+; (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 DOEVENT0
+ db TABLE0-TABLE0
+L0127: jmp DOEVENT1
+ db TABLE1-TABLE0
+;
+; (3) Program strings
+S6_SOUND: timex6 "SOUND "
+S6_TEST: timex6 " TEST "
+S8_TOEBES: timex "J.TOEBES"
+;
+; (4) State Table
+;
+TABLE0:
+ db 0
+ db EVT_ENTER,TIM_LONG,0 ; Initial state
+ db EVT_RESUME,TIM_ONCE,0 ; Resume from a nested app
+ db EVT_TIMER2,TIM_ONCE,0 ;
+ db EVT_DNNEXT,TIM_ONCE,1 ; Next button
+ db EVT_DNPREV,TIM_ONCE,1 ; Prev button
+ db EVT_MODE,TIM_ONCE,$FF ; Mode button
+ db EVT_DNSET,TIM_ONCE,0 ; Set button
+ db EVT_UPSET,TIM_ONCE,0 ;
+ db EVT_END
+
+TABLE1:
+ db 1
+ db EVT_UPNEXT,TIM_ONCE,1 ; Releasing the next button
+ db EVT_UPPREV,TIM_ONCE,1 ; Releasing the prev button
+ db EVT_USER0,TIM_ONCE,0 ; Return to the main state table
+ 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
+;
+DOEVENT0:
+ bset 1,APP_FLAGS ; Allow us to be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_RESUME ; Did another app get called in the meantime?
+ beq REFRESH ; We will refresh the display in this case
+ cmp #EVT_TIMER2 ; Did the initial timer expire?
+ beq REFRESH ; Yes, clean up the screen
+ cmp #EVT_ENTER ; Is this the initial state?
+ beq INITBANNER ; Yes, put up the banner
+ cmp #EVT_DNSET ; Did they hit the set button
+ beq PLAYIT
+ cmp #EVT_UPSET
+ beq SILENCE
+ rts
+;
+; (6) Sound playing code. Note that we go straight to the hardware here for this one
+;
+PLAYIT:
+ lda #ROW_NOTE ; Turn on the little note symbol
+ sta DISP_ROW
+ bset COL_NOTE,DISP_COL
+ lda CURRENT_VAL
+ sta $28
+ rts
+
+SILENCE:
+ lda #ROW_NOTE ; Turn off the little note symbol
+ sta DISP_ROW
+ bclr COL_NOTE,DISP_COL
+ lda #15
+ sta $28
+ rts
+
+REFRESH:
+ jsr CLEARALL ; Clear the display
+ lda #S6_SOUND-START ; Put "SOUND" on the top of the display
+ jsr PUT6TOP
+ ldx CURRENT_VAL
+ jsr FMTX
+ jsr PUTMID34
+ bra JBANNER
+
+INITBANNER:
+ jsr CLEARALL ; Clear the display
+ lda #S6_SOUND-START ; Put 'SOUND ' on the top line
+ jsr PUT6TOP
+ lda #S6_TEST-START ; Put ' TEST ' on the second line
+ jsr PUT6MID
+JBANNER
+ lda #S8_TOEBES-START
+ jmp BANNER8
+;
+; (7) This is the main initialization routine which is called when we first get the app into memory
+;
+MAIN:
+ bset 7,WRISTAPP_FLAGS ; Tell them that we are a live application
+ clr CURRENT_VAL
+ rts
+;
+; (8) State Table 1 Handler
+;
+; This is called when we press the prev/next button or when the timer fires during that event
+;
+DOEVENT1:
+ lda BTNSTATE
+ cmp #EVT_DNPREV
+ beq GO_DOWN
+ cmp #EVT_DNNEXT
+ beq GO_UP
+ lda #EVT_USER0
+ jmp POSTEVENT
+
+GO_DOWN bclr 0,SYSFLAGS ; Mark update direction as down
+ bra DOUPDN
+GO_UP bset 0,SYSFLAGS ; Mark update direction as up
+DOUPDN clra
+ jsr CLEARMID
+ sta UPDATE_MIN
+ lda #99
+ sta UPDATE_MAX
+ ldx #CURRENT_VAL
+ lda #UPD_MID34
+ jsr START_UPDATEP
+ bset 4,BTNFLAGS
+ rts
diff --git a/from_toebes/tipcalc/tipcalc1.zap b/from_toebes/tipcalc/tipcalc1.zap
new file mode 100644
index 0000000..1c75866
--- /dev/null
+++ b/from_toebes/tipcalc/tipcalc1.zap
@@ -0,0 +1,35 @@
+TDL0702972¬
+Tip Calculator¬
+TIPCALC1¬
+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!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150 Watch¬
+CC028C819D9D819D9D819D9D819D9DD6015681CC017B00CC0296171D1801161D1D1D0C0A130C1D0A14001915181D1219240C0A150C13321D180E0B0E1C000000000000000000001AFF001B84001FFF0001FFFF86FF0037FF0138FFFF1D0137FF0186FF01A6FF0139FF001DB691A11B270BA18627022058A637CC4E89C604A1270A4FC704A1A638CD4E8981CD577AA61BCD587EA621CD58A8A635CC5845CD595CCD5930BE66CD593EB6A2B7632604A61DB7A2B6A3B762CD5910A636B71D141EBE65CD593EB6A2B761B6A3B760CC5920CD577AA61BCD587EADC45FA60FAD13A614AD0FA60AAD0BA63FD704D1CD5522CC5545C7014DBF6797CD593EBE67B6A2AD52B6A3AD4EA629AD4AA637AD46BF67B660CE014D42C7014EB661CE014D42AB05C7014FB662CE014D42C70150B663CE014D42C701514FC70152C70153C701545FD6014EA00A2511D7014ED6014F4CD7014F20EDD704D25C815CA30625E3BE67C601532702ADEDC60152ADE8A632ADE4C60151ADDFC60150ADDAA62420D64FB765A60FB7661E00811200B691A1372714A1862704129F2031C604C3A1022611A639CC4E893F64A627CD587EA62DCD5845C604C3A1002728A1032720A101270181B6644CA401B764139FCD01ADA627CD587EA62DCD5845AD26149081119F2002109F4FC704F4A663C704F5B6642706AE65A6072004AE66A605CD57C7189081B6642706AE65A6092004AE66A607CC55BF¬
+53298¬
+0¬
+Tip Calculator¬
+TIPCALC1¬
+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!¬
+watchapp.hlp¬
+106¬
+none¬
+Timex Data Link 150s Watch¬
+CC028C819D9D819D9D819D9D819D9DD6015681CC017B00CC0296171D1801161D1D1D0C0A130C1D0A14001915181D1219240C0A150C13321D180E0B0E1C000000000000000000001AFF001B84001FFF0001FFFF86FF0037FF0138FFFF1D0137FF0186FF01A6FF0139FF001DB691A11B270BA18627022058A637CC4E78C604A1270A4FC704A1A638CD4E7881CD5AA0A61BCD577FA621CD57A9A635CC5746CD585DCD5831BE66CD583FB6A2B7632604A61DB7A2B6A3B762CD5811A636B71D141EBE65CD583FB6A2B761B6A3B760CC5821CD5AA0A61BCD577FADC45FA60FAD13A614AD0FA60AAD0BA63FD704D1CD5511CC5534C7014DBF6797CD583FBE67B6A2AD52B6A3AD4EA629AD4AA637AD46BF67B660CE014D42C7014EB661CE014D42AB05C7014FB662CE014D42C70150B663CE014D42C701514FC70152C70153C701545FD6014EA00A2511D7014ED6014F4CD7014F20EDD704D25C815CA30625E3BE67C601532702ADEDC60152ADE8A632ADE4C60151ADDFC60150ADDAA62420D64FB765A60FB7661E00811200B691A1372714A1862704129F2031C604C3A1022611A639CC4E783F64A627CD577FA62DCD5746C604C3A1002728A1032720A101270181B6644CA401B764139FCD01ADA627CD577FA62DCD5746AD26149081119F2002109F4FC704F4A663C704F5B6642706AE65A6072004AE66A605CD56C8189081B6642706AE65A6092004AE66A607CC55AE¬
+33831¬
+0¬ \ No newline at end of file
diff --git a/from_toebes/update/update.asm b/from_toebes/update/update.asm
new file mode 120000
index 0000000..85759e6
--- /dev/null
+++ b/from_toebes/update/update.asm
@@ -0,0 +1 @@
+update.zsm \ No newline at end of file
diff --git a/from_toebes/update/update.known_good b/from_toebes/update/update.known_good
new file mode 120000
index 0000000..9462f83
--- /dev/null
+++ b/from_toebes/update/update.known_good
@@ -0,0 +1 @@
+update.zap.app \ No newline at end of file
diff --git a/from_toebes/update/update.zap b/from_toebes/update/update.zap
new file mode 100644
index 0000000..9a1903a
--- /dev/null
+++ b/from_toebes/update/update.zap
@@ -0,0 +1,25 @@
+TDL0724962¬ Applet file header
+Update Sample¬ Applet friendly name
+Update1¬ Applet version #
+This is a simple number update program
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150 Watch¬
+CC01A9819D9D819D9D819D9D819D9DD6013381CC01470019160D0A180E050A1416130E001B83001FFF001AFF0001FFFF86FF00A6FF001D128FB691A186260FC604C3A1032724A100271CA1022737A11B26381361CD579FA617CD587EA61DCD58A8A648CC584C109F2002119F4FC704F4A663C704F5AE62A607CD57C718901361A650CC584C3F62026105CD577A12611F90BE62CD593ECC5920A6C0B7963F613F6281¬
+25714¬
+0¬ No data
+Update Sample¬ Applet friendly name
+Update2¬ Applet version #
+This is a simple number update program
+
+TIP: Download your watch faster: Download a WristApp once, then do not send it again. It stays in the watch!¬
+WATCHAPP.HLP¬ Applet help filename
+106¬
+none¬ Applet's parent's app name (if it exists - 'none' if it doesn't)
+Timex Data Link 150s Watch¬
+CC01A9819D9D819D9D819D9D819D9DD6013381CC01470019160D0A180E050A1416130E001B83001FFF001AFF0001FFFF86FF00A6FF001D128FB691A186260FC604C3A1032724A100271CA1022737A11B26381361CD5ACBA617CD577FA61DCD57A9A648CC574D109F2002119F4FC704F4A663C704F5AE62A607CD56C818901361A650CC574D3F62026105CD5AA012611F90BE62CD583FCC5821A6C0B7963F613F6281¬
+3478¬
+0¬ No data \ No newline at end of file
diff --git a/from_toebes/update/update.zsm b/from_toebes/update/update.zsm
new file mode 100644
index 0000000..bbbc0ba
--- /dev/null
+++ b/from_toebes/update/update.zsm
@@ -0,0 +1,133 @@
+;Name: Update
+;Version: UPDATE
+;Description: This is a simple number update program
+;by John A. Toebes, VIII
+;
+;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 1 indicates that we need to clear the display first
+;
+CURVAL EQU $62 ; The current value we are displaying
+;
+; (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 STATETAB,X ; The state table get routine - WRIST_GETSTATE
+ rts
+
+L0123: jmp HANDLE_STATE0
+ db STATETAB-STATETAB
+;
+; (3) Program strings
+S6_UPDATE: timex6 "UPDATE"
+S6_SAMPLE: timex6 "SAMPLE"
+;
+; (4) State Table
+;
+STATETAB:
+ db 0
+ db EVT_ENTER,TIM_2_8TIC,0 ; Initial state
+ db EVT_TIMER2,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_DNANY4,TIM_ONCE,0 ; NEXT, PREV, SET, MODE button pressed
+ db EVT_UPANY4,TIM_ONCE,0 ; NEXT, PREV, SET, MODE button released
+ db EVT_END
+;
+; (5) State Table 0 Handler
+; This is called to process the state events.
+; We see ENTER, TIMER2, RESUME, DNANY4 and UPANY4 events
+;
+HANDLE_STATE0:
+ bset 1,APP_FLAGS ; Indicate that we can be suspended
+ lda BTNSTATE ; Get the event
+ cmp #EVT_DNANY4 ; Did they press a button?
+ bne CHKENTER ; No, pass on to see what else there might be
+ 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_SET ; Perhaps the SET button
+ beq DO_SET ; If so, handle it
+ ; In reality, we can't reach here since we handled all three buttons
+ ; in the above code (the MODE button is handled before we get here and the
+ ; GLOW button doesn't send in an event for this). We can just fall through
+ ; and take whatever we get from it.
+CHKENTER
+ cmp #EVT_ENTER ; Is this our initial entry?
+ bne REFRESH
+;
+; This is the initial event for starting us
+;
+DO_ENTER
+ bclr 1,FLAGBYTE ; Indicate that we need to clear the display
+ jsr CLEARSYM ; Clear the display
+ lda #S6_UPDATE-START
+ jsr PUT6TOP
+ lda #S6_SAMPLE-START
+ jsr PUT6MID
+ lda #SYS8_MODE
+ jmp PUTMSGBOT
+;
+; (6) Our real working code...
+
+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 #99
+ sta UPDATE_MAX ; and the high end is 99 (the max since this is a 2 digit value)
+ ldx #CURVAL ; Point to our value to be updated
+ lda #UPD_MID34 ; Request updating in the middle of the display
+ jsr START_UPDATEP ; And prepare the update routine
+ bset 4,BTNFLAGS ; Mark that the update is now pending
+ bclr 1,FLAGBYTE
+ lda #SYS8_SET_MODE
+ jmp PUTMSGBOT
+
+DO_SET
+ clr CURVAL ; When they hit the set button, we just clear to zero
+SHOWVAL
+ brset 1,FLAGBYTE,NOCLEAR ; Do we need to clear the display first?
+REFRESH
+ jsr CLEARALL ; Yes, clear everything before we start
+ bset 1,FLAGBYTE ; And remember that we have already done that
+NOCLEAR
+ bclr 7,BTNFLAGS ; Turn off any update routine that might be pending
+ ldx CURVAL ; Get the current value
+ jsr FMTXLEAD0 ; Convert it to the two ascii digits
+ jmp PUTMID34 ; And put it on the screen in the right place
+;
+; (7) 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 FLAGBYTE ; start with a clean slate
+ clr CURVAL
+ rts