;************************************************************************
;                                                                       *
;   Filename:      BA_L6-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 10 ms delay)       *
;                                                                       *
;************************************************************************
;                                                                       *
;   Description:    Lesson 6, example 2                                 *
;                   Reaction Timer game.                                *
;                                                                       *
;   Demonstrates use of arithmetic expressions, constants and           *
;   text substitution definitions.                                      *
;                                                                       *
;   User must attempt to press button within defined reaction time      *
;   after "start" LED lights.  Success is indicated by "success" LED.   *
;                                                                       *
;       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                         *
;                                                                       *
;************************************************************************

    list        p=12F509  
    #include    <p12F509.inc>

    radix       dec


;***** EXTERNAL LABELS
    EXTERN      delay10_R           ; W x 10 ms delay


;***** CONFIGURATION
                ; int reset, no code protect, no watchdog, 4 MHz int clock
    __CONFIG    _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC

; pin assignments
    #define START       GPIO,2      ; LEDs
    #define SUCCESS     GPIO,1

    #define BUTTON      GPIO,3      ; switches


;***** CONSTANTS
    constant MAXRT=200              ; Maximum reaction time in ms


;***** 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 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
        ;
        movlw   2000/10             ; delay 2s 
        pagesel delay10
        call    delay10       
        pagesel $
        bsf     START               ; turn on start LED
        ; wait for button press
        banksel cnt8ms              ; clear 8ms counter
        clrf    cnt8ms 
wait1s  clrf    TMR0                ; clear timer0         
w_tmr0  btfss   BUTTON              ; check for button press (low)
        goto    btn_dn
        movf    TMR0,w
        xorlw   8000/32             ; wait for 8ms (32us/tick)
        btfss   STATUS,Z
        goto    w_tmr0
        incf    cnt8ms,f            ; increment 8ms counter
        movlw   1000/8              ; continue to wait for 1s (8ms/count)
        xorwf   cnt8ms,w
        btfss   STATUS,Z
        goto    wait1s
        ; check elapsed time       
btn_dn  movlw   MAXRT/8             ; if time < max reaction time (8ms/count)
        subwf   cnt8ms,w
        btfss   STATUS,C
        bsf     SUCCESS             ;   turn on success LED
        ; 
        movlw   1000/10             ; delay 1s  
        pagesel delay10
        call    delay10        
        pagesel $

        ; repeat forever
        goto    loop           


        END

