-
Notifications
You must be signed in to change notification settings - Fork 3
/
light5.asm
307 lines (251 loc) · 8 KB
/
light5.asm
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
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
;;; page 111 start complete; LIGHTS page 1
;************************************************************
;; MODS :
; LIGHT3.asm
; Add test to light counter so that if the oscillator
; fails, the system will ignore light sensor and keep running.
;
; Light4
; When goes to complete dark and hits the 'Dark_sleep' level
; and stays there until the reff level updates, at that point
; we send Furby to sleep.
;
; Light5 (used in F-RELS2 )
; Change detection of light threshold to prevent false or continuous trigger.
;************************************************************
Bright EQU 15 ;light sensor trigger > reff level (Hon)
Dim EQU 15 ;Light sensor trigger < reff level (Hon)
Shift_reff EQU 10 ;max count to set or clear prev done flag
Dark_sleep EQU B0h ;when timer A hi =0f and timer A low
; is = to this EQU then send him to sleep
; The CDS light sensor generates a square wave of 500hz to 24khz based on
; light brightness. We can loop on the sense line and count time for the
; lo period to determine if light has changed and compare it to previous
; samples. This also determines going lighter or darker. We also set a timer
; so that if someone holds their hand over the sensor and we announce it,
; if the change isnt stable for 10 second, we ignore the change back to the
; previous state. If it does exist for > 10 seconds, then it becomes the
; new sample to compare against on the next cycle.
; In order to announce light change, the system must have a consistent
; count > 'Shift_reff'.
; If a previous reff has been set then the 'Up_light' bit is set to
; look for counts greater than the reff. The system passes through the
; light routine 'Shift_reff' times. If it is consistently greater than
; the reff level, we get a speech trigger. If any single pass is less
; than the reff, the counter is set back to zero. This scenario also
; is obeyed when the trigger goes away, ie remove your hand, and the system
; counts down to zero.('Up_light' bit is cleared ) If during this time any
; trigger greater than reff occurs, the count is set back to max.
; This should prevent false triggers.
Get_light: ;alt entry for diagnostics
; This uses timer A to get a count from the lo period of the clk
SEI ;interrupts off
LDA #0C0H ;disable timer, clock, ext ints,
STA Interrupts ; & watchdog; select IRQ int.
LDA #000H ;set timer A for timer mode
STA TMA_CON ;
;;; page 111 end
;;; page 112 start complete; LIGHTS page 2
LDA #000H ;re-start timer A
STA TMA_LSB ;
LDA #000H ;now CPUCLK; was #010H = CPUCLK/4 (Hon)
STA TMA_MSB ;
Ck_lght2:
LDA TMA_MSB ;test for dead light osc
AND #0Fh ;get timer
CMP #0Fh ;ck for > 0E
BNE Ck_lt2a ;jump if not
LDA TMA_LSB ;get lo byte
CLC
SBC #E0h ;ck for > (msb+lsb =0FE0)
BCC Ck_lt2a ;jump if not
JMP Light_fail ;bail out if >
Ck_lt2a:
LDA Port_D ;get I/O
AND #Light_in ;ck light clk is hi
BEQ Ck_lght2 ;wait for it to go hi
LDA #000H ;re-start timer A
STA TMA_LSB ;
LDA #000H ;now CPUCLK; was #010H = CPUCLK/4 (Hon)
STA TMA_MSB ;
Ck_lght3:
LDA TMA_MSB ;test for dead light osc
AND #0Fh ;get timer
CMP #0Fh ;ck for > 0E
BNE Ck_lt3a ;jump if not
LDA TMA_LSB ;get lo byte
CLC
SBC #E0h ;ck for > (msb+lsb =0FE0)
BCS Light_fail ;bail out if >
Ck_lt3a:
LDA Port_D ;get I/O
AND #Light_in ;ck light clk is lo
BNE Ck_lght3 ;wait for it to go lo to insure the clk edge
Ck_lght4:
LDA #000H ;re-start timer A
STA TMA_LSB ;
LDA #000H ;now CPUCLK/ was #010H = CPUCLK/4 (Hon)
STA TMA_MSB ;
Ck_lght4a:
LDA Port_D ;get I/O
AND #Light_in ;ck if still lo
BEQ Ck_lght4a ;loop till hi
; Timer A holds count for lo period of clk
Lght4cmp:
LDA TMA_MSB ;get timer high byte
AND #00FH ; mask out high nybble
STA TEMP2 ; and save it
LDA TMA_LSB ;get timer low byte
STA TEMP1 ; and save it
LDA TMA_MSB ;get timer A high byte again
;;; page 112 end
;;; page 113 start complete; LIGHTS page 3
AND #00FH ; mask out high nybble
CMP TEMP2 ; and compare it with last reading
BNE Lght4cmp ;loop until they're equal
; take 12 bit timer (2 bytes) and move to one byte and trash lo nible
; of low byte. End up with hi 8 bits out of 12.
LDX #04 ;loop counter
Light_byte:
ROR TEMP2 ;get lo bit into carry
ROR TEMP1 ;shuffle down and get carry from TEMP2
DEX ;-1
BNE Light_byte ;loop till done
Ck_lght4b:
LDA #Intt_dflt ;Initialize timers, etc.
STA Interrupts ;re-establish normal system
CLI ;re-enable interrupt
JSR Kick_IRQ ;wait for motor R/C to start working again
CLC ;clear
;---now have new count in 'TEMP1'
LDA Light_reff ;get previous sample
SBC TEMP1 ;ck against current sample
BCC Ck_lght5 ;jump if negative
CLC
SBC #Bright ;ck if difference > reff
BCS Lght_brt ;go do speech
JMP Kill_ltrf ;bail out if not
Ck_lght5:
CLC
LDA TEMP1 ;try the reverse subtraction
SBC Light_reff ; prev
BCC Kill_ltrf ;quit if negative
CLC
SBC #Dim ;is diff < reff
BCC Kill_ltrf ;bail out if not
Lght_dim:
LDA Stat_3 ;system
AND #Nt_lght_stat ;clear bit to indicate dark table
STA Stat_3 ;update system
JMP Do_lght ;go fini
Lght_brt:
LDA Stat_3 ;system
ORA #Lght_stat ;set bit to indicate light table
STA Stat_3 ;update system
JMP Do_lght ;
Light_fail:
LDA #FFh ;force lo number so no conflicts
STA TEMP1
LDA #Intt_dflt ;Initialize timers, etc.
STA Interrupts ;re-establish normal system
CLI ;re-enable interrupt
JSR Kick_IRQ ;wait for motor R/C to start working again
JMP Kill_shift ;ret with no req
;------------------------------------------------------------
Do_lght:
;;; page 113 end
;;; page 114 start complete; LIGHTS page 4
LDA Stat_1 ;system
AND #Up_light ;ck if incrmnt mode
BNE Rst_shftup ;jump if incrmnt mode
LDA #Shift_reff ;set to max
STA Light_shift ;
JMP No_lt_todo ;
Rst_shftup:
INC Light_shift ;+1
LDA Light_shift ;get counter
CLC
SBC #Shift_reff ;ck if > max reff count
BCC No_lt_todo ;jump if < max count
LDA #Shift_reff ;reset to max
STA Light_shift ;
LDA Stat_0 ;system
AND #Lt_prev_dn ;check if previously done
BNE New_ltreff ;jump if was
LDA Stat_0 ;system
ORA #Lt_prev_dn ;set previously done
STA Stat_0 ;update
; LDA Stat_1 ;system
; AND #EFh :set sytem to shift decrmnt mode
; STA Stat_1 ;update
LDA #Light_reload ;reset for next trigger
STA Light_timer ;set it
JMP Do_ltchg ;go announce it
New_ltreff:
LDA Light_timer ;get current
BNE No_lt_todo ;nothing to do
LDA TEMP1 ;get new count
STA Light_reff ;update system
LDA Stat_1 ;system
AND #EFh ;set sytem to shift decrmnt mode
STA Stat_1 ;update
LDA TEMP1 ;get current value
CLC
SBC #Dark_sleep ;ck if > sleep level
BCS Ck_drk ;jump if >
LDA Stat_0 ;system
AND #7Fh ;kill prev done
STA Stat_0 ;update
JMP Kill_ltrf ;
Ck_drk:
LDA Stat_0 ;system
AND #Dark_sleep_prev ;ck if this was already done
BNE Kill_ltrf ;jump if was
LDA Stat_0 ;system
ORA #REQ_dark_sleep ;set it
ORA #Dark_sleep_prev ;set also
STA Stat_0 ;update
Kill_ltrf:
;;; page 114 end
;;; page 115 start XXX; LIGHTS page 5
; LDA Stat_0 ;system
; AND #Lt_prev_dn ;check if previously done
; BEQ No_lt_todo ;jump if clear
LDA Light_shift ;get shift counter
BEQ Kill_shift ;jump if went zero last time
LDA Stat_1 ;system
AND #Up_light ;ck if incrmnt mode
BEQ Rst_shftdn ;jump if decrmnt mode
LDA #00 ;set to min
STA Light_shift ;
JMP No_lt_todo ;
Rst_shftdn:
DEC Light_shift ;-1
JMP No_lt_todo ;done
Kill_shift:
LDA Stat_0 ;system
AND #FDh ;clears Lt_prev_dn
STA Stat_0 ;update
LDA Stat_1 ;system
ORA #Up_light ;prepare to incrmnt 'Light_shift'
STA Stat_1 ;update
No_lt_todo:
SEC ;carry set indicates no light change
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;****** alert system to start speech
Do_ltchg:
LDA Stat_3 ;system
AND #Lght_stat ;ck if went light or dark
BNE LT_ref_brt ;went brighter if set
LDA Stat_4 ;get system
ORA #Do_lght_dim ;set indicating change < reff level
JMP Ltref_egg ;
LT_ref_brt:
LDA Stat_4 ;
ORA #Do_lght_brt ;set indicating change > reff level
Ltref_egg:
STA Stat_4 ;update egg info
CLC ;carry clear indicates light > reff
RTS ;done
;;; page 115 end