• R/O
  • HTTP
  • SSH
  • HTTPS

コミット

よく使われているワード(クリックで追加)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

およそ20年前に、68HC05 の開発の練習に書いた車のブレイクライト・方向指示器コントローラです。


コミットメタ情報

リビジョン770232dd4179d7fecd156d30e95eb3bab098b7ac (tree)
日時2013-07-08 21:35:39
作者Joel Matthew Rees <reiisi@user...>
コミッターJoel Matthew Rees

ログメッセージ

Shift from asynchronous queued debounce to synchronous debounce, no queue.

変更サマリ

  • delete: TURNSIGQ.AS2 => TURNSIG.AS3

差分

--- a/TURNSIGQ.AS2
+++ b/TURNSIG.AS3
@@ -15,7 +15,7 @@
1515 * of
1616 * South Salt Lake City
1717 * Utah
18-*
18+*
1919
2020
2121
@@ -107,7 +107,7 @@
107107 * | |
108108 * +---5V_ZENER---GND +---CENTER_BRK_LGHT---GND
109109
110-* PA2<---+---160K_OHM---ENG_ON_SW---12V
110+* PA2<---+---160K_OHM---ENGINE_ON_SW---12V
111111 * |
112112 * +---5V_ZENER---GND
113113
@@ -231,6 +231,13 @@
231231 * K-series MCUs, RESET should probably be tied high. However, I suppose
232232 * it could make a good manual cancel-all input, if such is necessary.
233233
234+* This assembler appears not to have a bit not function for
235+* operand expressions. So, I have in several places resorted to the
236+* rather obtuse expedient of exclusive-orring bits to be reset with $FF,
237+* ergo, AND #{$FF ^ F_OPC ^ F_MNC}
238+* instead of AND #~(F_OPC | F_MNC)
239+* which I think is clearer.
240+
234241 SUBHEADER 'Obligatory Mnemonics'
235242 PAGE
236243 $base $0A
@@ -250,8 +257,8 @@ R_RDRV equ B4
250257 R_RDRV_ equ B4_
251258 BRK_SW equ B3
252259 BRK_SW_ equ B3_
253-ENG_SW equ B2
254-ENG_SW_ equ B2_
260+NGN_SW equ B2 ; engine (ENG and EMG could be confusing)
261+NGN_SW_ equ B2_
255262 DRVDRV equ B1
256263 DRVDRV_ equ B1_
257264 CAN_BT equ B0
@@ -265,7 +272,7 @@ RGT_BT_ equ B0_
265272
266273
267274 * logical input definitions for debounce and states
268-* bits are remapped for debounce and queue speed
275+* bits are remapped for debounce and speed
269276 * six bits of physical input, high two bits used for cancel logic
270277 F_LFT equ LFT_BT
271278 F_LFT_ equ LFT_BT_
@@ -273,8 +280,8 @@ F_RGT equ RGT_BT
273280 F_RGT_ equ RGT_BT_
274281 F_BRK equ {BRK_SW < 2} ; physical output bit
275282 F_BRK_ equ {BRK_SW_ + 2}
276-F_ENG equ {ENG_SW < 2} ; physical output bit
277-F_ENG_ equ {ENG_SW_ + 2}
283+F_NGN equ {NGN_SW < 2} ; physical output bit
284+F_NGN_ equ {NGN_SW_ + 2}
278285 F_EMG equ {DRVDRV < 2} ; fold onto output bit
279286 F_EMG_ equ {DRVDRV_ + 2}
280287 F_CAN equ {CAN_BT < 2}
@@ -282,12 +289,6 @@ F_CAN_ equ {CAN_BT_ + 2}
282289 F_OPC equ $40 ; opposite direction cancel record
283290 F_MNC equ $80 ; manual cancel record
284291
285-* Event queue constants
286-* We only have 6 bit events and only record 4 in the queue.
287-* Event scan algorithm wired to highest event bit in bit 3.
288-
289-MAXEVENTS equ 6 ; more than max bit changes in "time slice"
290-
291292 SUBHEADER 'Resource Definitions'
292293 PAGE
293294
@@ -306,30 +307,24 @@ FLASH1 equ {32*XTAL/RTIRATE/2} ; about 1/2 second
306307 org RAMBEG
307308 DEBO rmb 3 ; the debounce record chain
308309 STABLE rmb 1 ; temporary record of stable bits
309-TOGGLQ equ STABLE ; temporary record of queue events
310310 TOGGLE rmb 1 ; record of toggles
311311 ISTATE rmb 1 ; record of the current input state
312-QIN rmb 1 ; queue input point
313-QOUT rmb 1 ; queue output point
314-EVENTQ rmb MAXEVENTS ; no need to initialize this
315312 STATES rmb 1 ; current controller states
316-ENG_TIM rmb 2 ; engine time out timer
313+NGN_TIM rmb 2 ; engine time out timer
317314 FLASH rmb 1 ; flash timer
318315 FLTIME rmb 1 ; flash flash time to load
319-CANCEL rmb 1 ; debounce for cancel button
320-RETURN rmb 1 ; debounce for return logic
321316
322317
323318 * ROM definitions follow:
324319 org ROMBEG
325320
326- SUBHEADER 'Timer Service Code -- debounce'
321+ SUBHEADER 'Timer Service Code'
327322 PAGE
328323
329-* The timer service routine has five functions: debouncing the
330-* inputs, directly setting the brake lights, loading the flasher event
331-* queue, and maintaining two software clocks. Interrupts occur on timer
332-* overflow (1024 CPU cycles).
324+* The timer service routine has these functions: debouncing the
325+* inputs, directly setting the brake lights, flagging changes in TOGGLE,
326+* adjusting STATES to match the inputs, and maintaining two software
327+* clocks. Interrupts occur on timer overflow (1024 CPU cycles).
333328
334329 * The debounce routine translates the physical inputs to logical
335330 * inputs, maintains a record of the last three logical states sensed in
@@ -343,20 +338,36 @@ RETURN rmb 1 ; debounce for return logic
343338 * happening to the inputs between timer overflows, and because there is
344339 * no mechanism for noise coincident and rythmic with timer overflow.
345340
346-* The cancel TOGGLE bit is suppresed on same-direction rotation.
341+* The cancel TOGGLE bit is suppressed on same-direction rotation.
347342 * Trailing edge TOGGLEs are filtered out for all but brake and engine-on.
348-* Cancel direction and manual cancel TOGGLEs are always filtered out.
343+* Opposite direction cancel (F_OPC) and manual cancel (F_MNC) ISTATE
344+* auxiliary flags are maintained to provide information on the source of
345+* the F_CAN bit, and are always filtered out of TOGGLE.
346+
347+* After adding an event queue and checking the timing results, two
348+* things became clear: there is plenty of time to handle all the changes
349+* to STATES without a queue, and TOGGLE makes a sort of horizontal queue
350+* anyway. In other words, there is no reason to make the adjustments to
351+* STATES asynchronous when there is plenty of headroom for synchronous
352+* adjustments. Moreover, the adjustments take less time than organizing
353+* the button events in a queue. (Darn! I was kind of proud of that six
354+* byte queue, and the shift technique for storing events into it.)
355+
356+ SUBHEADER 'Timer Service Code -- Debounce and Toggle Filter'
357+ PAGE
349358
350359 $CYCLE_ADDER_ON
351360 TIMSRV bset TOFR_,TSCR
352- lda DEBO+1 ; move the debounce chain
361+
362+* move the debounce chain
363+ lda DEBO+1
353364 sta DEBO+2
354365 lda DEBO
355366 sta DEBO+1
356367
357-* read the inputs, converting physical to logical
368+* read the static inputs, converting physical to logical
358369 lda PORTA
359- and #{BRK_SW | ENG_SW | CAN_BT } ; clears F_EMG
370+ and #{BRK_SW | NGN_SW | CAN_BT} ; clears DRV_DRV
360371 bih TMMEMG ; invert EMG and fold it in
361372 ora #F_EMG
362373 TMMEMG lsra ; remap
@@ -366,14 +377,15 @@ TMMEMG lsra ; remap
366377 ora DEBO
367378 sta DEBO
368379
369-* check for turn signal return and cancel
380+* read the turn signal return and manual cancel auxiliary flags
381+* (F_CAN & turn_sig_on) <=> read auxiliary flags
370382 bit #F_CAN ; nothing at all without cancel
371383 beq TMSTGL
372- lda DDRB ; meaningless when no turn signal
384+ ldx DDRB ; meaningless if not waiting for cancel
373385 beq TMSTGL
374386 $CYCLE_ADDER_OFF
375387 $CYCLE_ADDER_ON
376- tax
388+ txa
377389 eor #{LFT_BT | RGT_BT} ; strobe other side
378390 sta PORTB ; set output state first
379391 sta DDRB ; handy output state, huh?
@@ -390,9 +402,10 @@ TM0001 rora
390402 $CYCLE_ADDER_OFF
391403 $CYCLE_ADDER_ON
392404
393-* debounce inputs, set flags in TOGGLE
394-TMSTGL lda DEBO
395- eor DEBO+1
405+* debounce inputs, set flags in TOGGLE and ISTATE
406+* STABLE = ~((DEBO[0] ^ DEBO[1]) | (DEBO[1] ^ DEBO[2]))
407+*
408+TMSTGL eor DEBO+1
396409 sta TOGGLE ; re-use TOGGLE, TOGGLE not valid
397410 lda DEBO+1
398411 eor DEBO+2
@@ -404,7 +417,7 @@ TMSTGL lda DEBO
404417 txa
405418 and ISTATE ; look only at bits that are stable
406419 eor STABLE ; flag bits that toggled
407- sta TOGGLE ; TOGGLE valid, but not filtered
420+ sta TOGGLE ; true TOGGLEs, but not yet filtered
408421 coma ; mask of non-toggles
409422 and ISTATE ; old state of non-toggles
410423 sta ISTATE ; (toggled bits cleared)
@@ -413,113 +426,80 @@ TMSTGL lda DEBO
413426 ora ISTATE
414427 sta ISTATE ; ISTATE now has current debounced inputs
415428
416-* filter TOGGLE F_CAN if same direction
429+* filter out TOGGLE F_CAN if same direction
417430 bit #{F_OPC | F_MNC} ; opposite direction or manual?
418431 bne TMFFAL
419432 bclr F_CAN_,TOGGLE ; same direction
420433
421-* filter falling edge of F_LFT, F_RGT, F_EMG, F_CAN in TOGGLE
434+* filter out trailing edge of F_LFT, F_RGT, F_EMG, F_CAN in TOGGLE
435+* also filter out auxiliary TOGGLEs in passing
422436 * assumes ISTATE still in A
423-TMFFAL ora #{F_ENG | F_BRK} ; not filtered
424- and TOGGLE ; filter any other fall(en) edge
425- and #{$FF ^ F_OPC ^ F_MNC} ; these should never TOGGLE
437+TMFFAL ora #{F_NGN | F_BRK} ; not filtered
438+ and TOGGLE ; filter any other (logical) fall(en) edge
439+ and #{$FF ^ F_OPC ^ F_MNC} ; auxiliaries should never TOGGLE
426440 sta TOGGLE
427441
428- SUBHEADER 'Timer Service Code -- brake lights'
442+ SUBHEADER 'Timer Service Code -- Adjust STATES'
429443 PAGE
430444
431-* Brake lights are the highest priority function, depending only
432-* on the ISTATE F_BRK. The STATES F_BRK is returned as a flag to other
433-* routines.
434-
435- brclr F_BRK_,ISTATE,TMBRK0
445+* move brake bit from ISTATE to STATES
446+TMBRKMV bclr F_BRK_,STATES
447+ brclr F_BRK_,ISTATE,TMEMGMV
436448 bset F_BRK_,STATES
437- bclr R_LDRV_,PORTA ; brake lights on
438- bclr R_RDRV_,PORTA
439-* high center brake light connects directly to brake switch.
440- bra TMBRKDUN
441-TMBRK0 bclr F_BRK_,STATES
442- bset R_LDRV_,PORTA ; brake lights off
443- bset R_RDRV_,PORTA ; (flashers can turn them back on)
444-TMBRKDUN
445-
446- SUBHEADER 'Timer Service Code -- fill event queue'
447- PAGE
448449
449-* General debounce complete; now put signal events in queue:
450-* Brake and engine-on are handled in TIMSRV, as synchronous events, and
451-* so are not queued. Turn signal and emergency inputs are positive edge
452-* sensitive, falling edges are ignored.
450+* toggle STATES F_EMG if TOGGLE F_EMG
451+TMEMGMV brclr F_EMG_,TOGGLE,TMEMGM0
452+ lda STATES
453+ eor #F_EMG
454+TMEMG0 sta STATES
453455
454-* Queue is post-inc push and pull; QIN == QOUT is empty queue;
455-* queue overflow causes the oldest event to be discarded, but should
456-* never occur.
456+* turn on STATES turn signal if TOGGLE turn signal
457+ lda TOGGLE
458+ and #{F_LFT | F_RGT}
459+ ora STATES
457460
458- lda TOGGLE ; F_BRK & F_ENG are not queued!
459- and #{$FF ^ F_BRK ^ F_ENG} ; KICS assembler has no bit not?
460- sta TOGGLQ
461- beq TMCLOCK ; save time
462- ldx QIN
463- lda #$10 ; start with bit 3!
464-* cycles to this point, plus interrupt response (19 cycles)
461+* cancel STATES turn signal if TOGGLE F_CAN is not filtered out
462+ brclr F_CAN_,TOGGLE,TMCAN0
463+ and #{$FF ^ F_LFT ^ F_RGT} ; STATES still in A
464+TMCAN0 sta STATES
465465
466-$CYCLE_ADDER_OFF
467-$CYCLE_ADDER_ON
468-TMQSCAN lsra ; scan TOGGLE
469- beq TMQDUN
470- bit TOGGLQ
471- beq TMQSCAN
472-* 12 cycles minimum time in loop
473-$CYCLE_ADDER_OFF
474-$CYCLE_ADDER_ON
475- sta ,x
476- incx
477- cpx #EVENTQ+MAXEVENTS
478- blo TMQNWRP
479- ldx #EVENTQ ; 2 cycles
480-TMQNWRP cpx QOUT
481- bne TMQSCAN
482- inc QOUT ; 5 cycles
483-TMQNBMP bra TMQSCAN ; 3 cycles
484-* 40 cycles maximum time in loop, (40 - 2 - 5 - 3) == 30 typical max;
485-* Minimum queue time is 12 * 3 + 30 == 66 (no wrap, no bump);
486-* max is 30 * 3 + 40 == 130 (one wrap, one bump max)
487-$CYCLE_ADDER_OFF
488-$CYCLE_ADDER_ON
489-TMQDUN stx QIN
466+* Engine time out state is handled within the software timer
467+* routines.
490468
491- SUBHEADER 'Timer Service Code -- engine time out and flasher timers'
469+ SUBHEADER 'Timer Service Code -- Engine Time Out and Flasher Timers'
492470 PAGE
471+
493472 * Although the Real Time Interrupt is masked, the software clocks
494-* use the RTI flag. Selecting the fastest RTI rate gives the software
495-* clocks a resolution of eight timer overflows (8192 CPU cycles).
473+* use the RTI flag. See RTIPOW for the RTI flag rate
496474
497475 TMCLOCK
498476 brclr RTIF_,TSCR,TIMDUN
499477 bset RTIFR_,TSCR
500478
501-* The engine time-out counter resets if the engine toggles on. It
502-* runs only when the ISTATE F_ENG bit is low and the emergency flashers
503-* (STATES F_EMG) are off. It does not underfow. The timer flags
504-* timeout in STATES F_ENG.
479+* The engine time-out counter resets if engine on toggles. It
480+* runs only when the ISTATE F_NGN bit is low and the emergency flashers
481+* and brakes (STATES F_EMG and F_BRK) are off. It does not underfow.
482+* The timer flags timeout in STATES F_NGN.
505483
506- brclr F_ENG_,TOGGLE,TMENG0
507- lda #{TIMOUT & $FF } ; reset the clock
508- sta ENG_TIM+1
484+ brclr F_NGN_,TOGGLE,TMNGN0 ; reset on toggle off (and on)
485+ lda #{TIMOUT & $FF } ; reset value low byte
486+ sta NGN_TIM+1
509487 lda #{TIMOUT / $100 + 1} ; borrow on 0, not -1
510- sta ENG_TIM
488+ sta NGN_TIM
511489 bra TMFLASH
512490
513-TMENG0
514- brset F_ENG_,ISTATE,TMFLASH
515- brset F_EMG_,STATES,TMFLASH
516- brclr F_ENG_,STATES,TMFLASH ; do not underflow!
517- dec ENG_TIM+1
491+TMNGN0
492+ lda STATES
493+ and #{F_NGN | F_EMG | F_BRK} ; brakes or emg flashers?
494+ eor #F_NGN ; no underflow
495+ bne TMFLASH
496+ brset F_NGN_,ISTATE,TMFLASH
497+ dec NGN_TIM+1
518498 bne TIMFLH ; initial count is adjusted to make this work
519- dec ENG_TIM
499+ dec NGN_TIM
520500 bne TIMFLH
521- bclr F_ENG_,STATES ; signal timed out
522- bset F_ENG_,TOGGLE ; communicate with MAINLOOP
501+ bclr F_NGN_,STATES ; signal timed out
502+ bset F_NGN_,TOGGLE ; communicate with MAINLOOP
523503
524504 * flasher counter
525505 TMFLASH lda #{F_EMG | F_LFT | F_RGT}
@@ -532,18 +512,18 @@ TMFLASH lda #{F_EMG | F_LFT | F_RGT}
532512
533513 TIMDUN rti
534514 $CYCLE_ADDER_OFF
535-* Keep the maximum clock cycles in TIMSRV below half of TOFR period.
536-* It is probably physically impossible to operate the switches fast
537-* enough to overflow the queue that way.
538515
539516 SUBHEADER 'Initializations'
540517 PAGE
518+
541519 * waking up simply resets the MCU
542520 * if SWI occurs, the machine is not in a defined state, and must reset
543521 IRQSRV
544-SWISRV rsp ; now falls through to RSTSRV
522+SWISRV
545523 clra
546524 sta COPR
525+ rsp ; now falls through to RSTSRV
526+
547527 * general inits
548528 RSTSRV lda #{F_LDRV | F_RDRV | R_LDRV | R_RDRV}
549529 sta PORTA ; initial output values
@@ -563,199 +543,93 @@ RSTSRV lda #{F_LDRV | F_RDRV | R_LDRV | R_RDRV}
563543 clra
564544 sta COPR ; b0 clear, about to change timer rate
565545 lda #{TOIE | RTIPOW} ; only timer overflow interrupts
566- sta TSCR
546+ sta TSCR ; RTIPOW has the timer rate
567547 ora #{TOFR|RTIFR} ; clear the flags
568548 sta TSCR
569549 * set up specific variables
570550 clr DEBO ; start debounce chain clear
571551 clr DEBO+1 ; DEBO+2 is thrown out on first timer interrupt
572- lda #{F_ENG}
573- sta ISTATE ; force TIMOUT to be set
574- sta TOGGLE
575- sta STATES ; we think the engine is on
576- ldx #EVENTQ ; empty QUEUE
577- stx QIN
578- stx QOUT
552+ clr STATES ; no unknown states
553+ clr ISTATE
554+* because F_NGN may not be on, and we don't depend on timer reset quirks:
555+ lda #{TIMOUT & $FF } ; reset value low byte
556+ sta NGN_TIM+1
557+ lda #{TIMOUT / $100 + 1} ; borrow on 0, not -1
558+ sta NGN_TIM
579559
580-* Falls through to MAINLOOP
560+* Falls through to DOSTATES
581561
582- SUBHEADER 'Dequeue Events and Modify STATES, also STOP'
562+ SUBHEADER 'DOSTATES: Interpret States'
583563 PAGE
584564
585-MAINLOOP
565+DOSTATES:
586566 cli ; leave interrupts enabled as much as possible
587567 clra
588568 sta COPR ; tell COP we're in control
589-* check for STOP, dequeue flasher events, wait if necessary
590- sei
591- brclr F_ENG_,STATES,MNSTOP
592- ldx QOUT
593- cpx QIN ; QUEUE empty?
594- bne MNDEQUEUE
595- lda STATES ; can we save power for a bit?
596- and #{F_LFT | F_RGT | F_BRK | F_EMG}
597- bne MNDRVWT
598- bclr DRVDRV_,PORTA
599-MNDRVWT wait ; enable interrupts, wait for timer
600- tst TOGGLE
601- beq MNDRVWT ; nothing changed, nothing to respond to
602-* with no activity, COP periodically resets the MCU system
603-* this is not generally good engineering practice.
604- bset DRVDRV_,PORTA ; IRQSRV might have driven the brake lights
605- bra MAINLOOP ; check STOP and QUEUE again
606-
607-* go to power conserving state
608-MNSTOP lda #{F_LDRV | F_RDRV | R_LDRV | R_RDRV}
609- sta PORTA ; shut everything down, organized!
610- lda #{F_LDRV | F_RDRV | R_LDRV | R_RDRV | DRVDRV}
611- sta DDRA ; set up directions
612- sta PDRA ; pull downs only on inputs
613- clr PORTB ; initial outputs (do port B just in case)
614- clr DDRB ; B initially input
615- clr PDRB ; with pull downs set
616-* make sure EPROM programming stuff is out of the way
617- clr EPROG
618- clr PESCR
619-* enable external interrupts
620- bset IRQE_,ISCR ; DO NOT clear the flag (IRQ won't return)
621- stop ; also shuts timer down
622- jmp SWISRV ; should never come here (resets stack pointer)
623-
624-MNDEQUEUE
625- lda ,x
626- incx
627- cpx #EVENTQ+MAXEVENTS
628- blo MNQNWRP
629- ldx #EVENTQ
630-MNQNWRP stx QOUT
631- cmp #F_EMG
632- bne MNCAN
633- eor STATES ; toggle STATES F_EMG emergency flashers bit
634- sta STATES
635- bra MNDOSTATES
636-
637-MNQCAN cmp #F_CAN
638- bne MNQLFT
639- ldx #7
640-
641- lda STATES
642- and #{F_LFT | F_RGT}
643- beq MNDOSTATES
644- eor #{F_LFT | F_RGT}
645- sta TMPTURN
646- sta PORTB
647-MNQCANL sta DDRB
648- brclr CAN_BT_,PORTA,MNQCANM ; opposite direction?
649- incx
650-MNQCANM clr DDRB ; all outputs pulled down
651- brclr CAN_BT_,PORTA,MDQCANT ; manual cancel?
652- incx
653- dec something
654- bne MNQCANL
655-
656-
657-MNQLFT cmp #F_LFT
658- bne MNQRGT
659- bset F_LFT_,STATES
660- bclr F_RGT_,STATES
661- bra MNDOSTATES
662-
663-MNQRGT cmp #F_RGT
664- bne MNQDEF
665- bset F_RGT_,STATES
666- bclr F_LFT_,STATES
667- bra MNDOSTATES
668-
669-MNQDEF jmp SWISRV ; nothing else should be queued
670-
671-* then make the output mirror the state
672-
673-
674-DOSTATE
675- brset F_BRK_,STATES,MAINLOOP ; if brakes set, do nothing else
676- brset F_EMG_,STATES,DOEMERG ; if emergency flash, skip engine
677- brset F_ENG_,STATES,DOTURN ; no turn signals if engine off
678-* engine off and timed out, no brakes, no emergency flashers
679- lda
680-
681-
682-* Emergency flasher filter simply toggles F_EMG bit of STATES
683-* when emergency flasher button is pressed. Release is ignored.
684-
685-INFEMG cli ; allow interrupts
686- sei ; critical: not seamless access
687- brclr F_EMG_,TOGGLE,INFTRN
688- bclr F_EMG_,TOGGLE
689- brclr F_EMG_,ISTATE,INFTRN ; no action when button released
690- lda STATES
691- eor #F_EMG
692- sta STATES
693-* fall through
694569
570+* State machine for STATES
571+* Brake, eNgine, emerGency, Left, and Right
695572 *
696-
697-INFTRN cli ; allow interrupts
698- sei ; critical: not seamless access
699- lda STATES
700- and ISTATE
701- and #{F_LFT | F_RGT} ; mask
702- eor #{F_LFT | F_RGT} ; ignore if already on
703- and TOGGLE
704- beq FNENG
705- tax
706- and ISTATE ; too late at night, all my work this aft is gone
707-* check here for turning
708-FNENG
709-
710-* support on and off states on signal timer.
711-
712-* if engine is off and timed out, shut down.
713-* else if brakes on, set break lights, let front and turn signals flash
714-* else if emergency set, flash all
715-* else run turn signals
716-
717-
718-* this should be discarded:
719-
720-* Four major state machines are implemented and maintained:
721-* ENGINE state, BRAKE state, EMERGENCY flasher state,
722-* and TURN_SIGNAL state.
723-
724-* If brake lights and emergency flashers are independent, EMERGENCY and
725-* BRAKE states should be the only pieces of code that need modifying.
726-
727-
728-* The ENGINE state machine has three states:
729-* ENG_OFF (MCU in STOP state)
730-* ENG_ON (MCU running, time out counter reset)
731-* ENG_TO (MCU running, time out counter counting)
732-
733-* The BRAKE state machine has two states:
734-* BRK_ON (F_BRK in ISTATE high, brake lights forced on)
735-* BRK_OFF (F_BRK in ISTATE low)
736-
737-* The EMERGENCY state machine has two states:
738-* EMG_ON (F_EMG in STATES high, flasher counters running)
739-* EMG_OFF (F_EMG in STATES low)
740-* -- consider flasher rates, turnsignal vs emergency
741-
742-* The TURN_SIGNAL state machine has two state machines:
743-
744-* BRK_OFF (F_BRK==1)---> BRK_ON { possibly interrupting }
745-* BRK_OFF <---(F_BRK==0) BRK_ON
746-
747-* ENG_OFF (F_ENG==1)---> ENG_ON { usually interrupting }
748-* ENG_TMO <---(F_ENG==0) ENG_ON
749-* ENG_TMO (F_ENG==1)---> ENG_ON
750-* ENG_OFF <---(F_ENG==0 && 5 Minutes delay) ENG_TMO
751-* (Change the XTAL constant if a 1 MHz crystal is not used!)
752-
753-* EMG_NO (F_EMG==1 && EMG_FL==0)---> EMG_FL
573+* B N G L R | output
574+* ----------|------
575+* 1 x x x x | Brake lights!
576+* 0 x 1 x x | Emergency flashers!
577+* 0 0 0 x x | Power Down
578+* 0 1 0 0 0 | No outputs
579+* 0 1 0 0 1 | Right turn signal
580+* 0 1 0 1 0 | Left turn signal
581+* 0 1 0 1 1 | NONE, clear turn signal states
754582 *
583+* Cancel is entirely handled within TIMSRV
584+
585+ sei ; is this necessary?
586+ brset F_BRK_,STATES,STBRK
587+ brset F_EMG_,STATES,STEMG
588+ brclr F_EMG_,STATES,STNG0
589+
590+****** put turn signal code in here
591+
592+STBRK
593+ bra DOSTATES
594+
595+STEMG
596+ bra DOSTATES
597+
598+STNG0
599+
600+* had some power conserving in here
601+* lda STATES ; can we save power for a bit?
602+* and #{F_LFT | F_RGT | F_BRK | F_EMG}
603+* bne MNDRVWT
604+* bclr DRVDRV_,PORTA
605+*MNDRVWT wait ; enable interrupts, wait for timer
606+* tst TOGGLE
607+* beq MNDRVWT ; nothing changed, nothing to respond to
608+** with no activity, COP periodically resets the MCU system
609+** this is not generally good engineering practice.
610+* bset DRVDRV_,PORTA ; IRQSRV might have driven the brake lights
611+* bra MAINLOOP ; check STOP and QUEUE again
612+*
613+** go to power conserving state
614+*MNSTOP lda #{F_LDRV | F_RDRV | R_LDRV | R_RDRV}
615+* sta PORTA ; shut everything down, organized!
616+* lda #{F_LDRV | F_RDRV | R_LDRV | R_RDRV | DRVDRV}
617+* sta DDRA ; set up directions
618+* sta PDRA ; pull downs only on inputs
619+* clr PORTB ; initial outputs (do port B just in case)
620+* clr DDRB ; B initially input
621+* clr PDRB ; with pull downs set
622+** make sure EPROM programming stuff is out of the way
623+* clr EPROG
624+* clr PESCR
625+** enable external interrupts
626+* bset IRQE_,ISCR ; DO NOT clear the flag (IRQ won't return)
627+* stop ; also shuts timer down
628+* jmp SWISRV ; should never come here (resets stack pointer)
629+
630+ bra DOSTATES
755631
756632
757- bra MAINLOOP
758-
759633
760634 org VECTORS
761635 fdb TIMSRV