summaryrefslogtreecommitdiffstats
path: root/from_toebes/shipbell/shipbell.asm
blob: 6d9f11b24e9a44fa9b2ce6161d89c92a4d6da6e8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
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