;----------------------------------------------------------------------;
; SWCNT4M.ASM  Counts presses of a pushbutton on RB4, 4 MHz oscillator ;
;----------------------------------------------------------------------;

;                            .-----------.
;                           -|RA2     RA1|-       V+ = 4.5 or 5 Volts
;                           -|RA3     RA0|-       X = 4 MHz cer. res.
;                           -|RA4    OSC1|--|X|___ gnd
;   -{r}- = 470 ohm    V+ ---|MCLR   OSC2|--|X|  
;   -|<- = LED        gnd ---|Vss     Vdd|--- V+
;            gnd ---|<--{r}--|RB0     RB7|-         
;            gnd ---|<--{r}--|RB1     RB6|-         
;            gnd ---|<--{r}--|RB2     RB5|-       
;            gnd ---|<--{r}--|RB3     RB4|---[PB]--- gnd        
;                            '-----------'         
;                               PIC16F84      -[PB]- pushbutton

        LIST P=16F84           ;  tells which processor is used
        INCLUDE "p16f84.inc"   ;  defines various registers etc. Look
        ERRORLEVEL -224        ;  supress annoying message from tris
        __CONFIG _PWRTE_ON & _XT_OSC & _WDT_OFF   ;  config. switches


        #DEFINE pushbutton PORTB, 4      ; RB4 is pushbutton to ground
 
;----------------------------------------------------------------------;
;    Here we set up our own registers start at the 1st free address    ;
;----------------------------------------------------------------------;
           CBLOCK H'0C'
               cntmsec        ;  counter used in millisecond delays
           ENDC

           ORG 0              ;  start a program memory location zero

;----------------------------------------------------------------------;
;        First we set up all bits of PORT A and B as outputs           ;
;----------------------------------------------------------------------;
         movlw B'00000000'    ;  all bits outputs
         tris PORTA           ;  on PORT A 
         movlw B'00010000'    ;  RB4 input, all others outputs 
         tris PORTB           ;  and PORT B
         movlw 0              ;  set bit 7 of OPTION = 0 ....
         option               ;  port B pullups activated

;----------------------------------------------------------------------;
;                       This is the main program                       ;
;----------------------------------------------------------------------;
         clrf PORTB           ;  start with zero,  ( all LEDs off )
loop:
         btfsc pushbutton     ;  switch closed, (gives 0)?
         goto loop            ;  not yet, continue to wait
                              ;  switch has been detected closed
         incf PORTB, f        ;  add 1 to port B
                              ;  wait a while to make sure switch has 
                              ;  settled  (debounce closure)
         movlw D'10'          ;  wait about 10 msec
         call nmsec           ;  may be bounce on closure
                              ;  now wait for release 
         btfss pushbutton     ;  will be high (1) when released
         goto $ -1            ;  still low
                              ;  must wait, make sure bouncing stopped
         movlw D'10'          ;  10 milliseconds
         call nmsec           ;  release bounce less, but still there
                              ;  and check again
         btfss pushbutton     ;  if set, still released
         goto $ -5            ;  still low start release wait all over

         goto loop            ;  loop forever

;----------------------------------------------------------------------;
;                        time delay routines                           ;
;----------------------------------------------------------------------;
micro4      addlw H'FF'                ;  subtract 1 from 'W'
            btfss STATUS,Z             ;  skip when you reach zero
            goto micro4                ;  more loops
            return                     

                ;*** N millisecond delay routine ***
nmsec:      movwf cntmsec              ;  delay for N (in W) millisec
msecloop:   movlw D'248'               ;  1 usec for load
            call micro4                ;  this instruction is 995 usec
            nop                        ;  1 usec 
            decfsz cntmsec,f           ;  1 usec, (2 if skip taken)
            goto msecloop              ;  2 usec, loop = 995+5 = 1 msec
            return 
 
         end                  ; end of program