;************************************************************************
;                                                                       *
;   Filename:      BA_L5-Reaction_timer.asm                             *
;   Date:          16/9/07                                              *
;   File Version:  1.1                                                  *
;                                                                       *
;   Author:        David Meiklejohn                                     *
;   Company:       Gooligum Electronics                                 *
;                                                                       *
;************************************************************************
;                                                                       *
;   Architecture:  Baseline PIC                                         *
;   Processor:     12F508/509                                           *
;                                                                       *
;************************************************************************
;                                                                       *
;   Files required: delay10.asm        (provides W x 10ms delay)        *
;                                                                       *
;************************************************************************
;                                                                       *
;   Description:    Lesson 5, example 1                                 *    
;                   Reaction Timer game.                                *
;                                                                       *
;   Demonstrates use of timer0 to time real-world events                *
;                                                                       *
;   User must attempt to press button within 200ms of "start" LED       *
;   lighting.  If and only if successful, "success" LED is lit.         *
;                                                                       *
;       Starts with both LEDs unlit.                                    *
;       2 sec delay before lighting "start"                             *
;       Waits up to 1 sec for button press                              *
;       (only) on button press, lights "success"                        *
;       1 sec delay before repeating from start                         *
;                                                                       *
;************************************************************************
;                                                                       *
;   Pin assignments:                                                    *
;       GP1 - success LED                                               *
;       GP2 - start LED                                                 *
;       GP3 - pushbutton                                                *
;                                                                       *
;************************************************************************

    list        p=12F509   
    #include    <p12F509.inc>

                ; int reset, no code protect, no watchdog, 4MHz int clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC


;***** EXTERNAL LABELS
        EXTERN  delay10_R       ; W x 10ms delay


;***** VARIABLE DEFINITIONS
        UDATA
cnt8ms  res 1                   ; 8ms counter (incremented every 8ms)


;************************************************************************
RESET   CODE    0x000           ; effective reset vector
        movwf   OSCCAL          ; update OSCCAL with factory cal value
        pagesel start
        goto    start           ; jump to main code

;***** Subroutine vectors
delay10                         ; delay W x 10ms
        pagesel delay10_R
        goto    delay10_R       


;***** MAIN PROGRAM
MAIN    CODE

;***** Initialisation
start
        movlw   b'111001'       ; configure GP1 and GP2 (only) as outputs
        tris    GPIO
        movlw   b'11010100'     ; configure Timer0:
                ; --0-----          timer mode (T0CS = 0)
                ; ----0---          prescaler assigned to Timer0 (PSA = 0)
                ; -----100          prescale = 32 (PS = 100)            
        option                  ;   -> increment every 32 us

;***** Main loop
loop    clrf    GPIO            ; start with all LEDs off
        ; delay 2s
        movlw   .200
        pagesel delay10
        call    delay10         
        pagesel $
        bsf     GPIO,2          ; turn on start LED
        ; wait for button press
        banksel cnt8ms          ; clear 8ms counter
        clrf    cnt8ms 
wait1s  clrf    TMR0            ; clear timer0         
w_tmr0  btfss   GPIO,3          ; check for button press (GP3 low)
        goto    btn_dn
        movf    TMR0,w
        xorlw   .250            ; wait for 8ms (250x32us)
        btfss   STATUS,Z
        goto    w_tmr0
        incf    cnt8ms,f        ; increment 8ms counter
        movlw   .125            ; continue to wait for 1s (125x8ms)
        xorwf   cnt8ms,w
        btfss   STATUS,Z
        goto    wait1s
        ; check elapsed time       
btn_dn  movlw   .25             ; if time < 200ms (25x8ms)
        subwf   cnt8ms,w
        btfss   STATUS,C
        bsf     GPIO,1          ;   turn on success LED
        ; delay 1s
        movlw   .100           
        pagesel delay10
        call    delay10        
        pagesel $

        ; repeat forever
        goto    loop           


        END

