;----------------------------------------------------------------------;
; BINCNT4M.ASM  Counts in binary on LEDs (RB0 - RB4)  4 MHz oscillator ;
;----------------------------------------------------------------------;

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

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

        CBLOCK H'0C'           ;  set up general registers starting at
                               ;  address 12
          counter              ;  a general counting register
        ENDC                   ;  end of register definitions

          ORG 0                ;  start at program memory location zero

;----------------------------------------------------------------------;
;         First we set up all bits of PORT A and B as outputs          ;
;         and set bits in the OPTION register concerning TMR0          ;
;----------------------------------------------------------------------;
         movlw B'00000000'    ;  all bits low in W
         tris PORTA           ;  make all bit of PORT A outputs ...
         tris PORTB           ;  and all bits of PORT B also
         movlw B'00000101'    ;  TMR0 assigned to incr. on internal clk
                              ;  prescalar assigned to TMR0 and set 1:64
                              ;  bit 5 set means timer runs off RA4
         option               ;  W inserted into OPTION register
                              ;  check OPTION register in data sheet

;----------------------------------------------------------------------;
;                      This is the main program                        ;
;----------------------------------------------------------------------;
         clrf PORTB           ;  start with zero in port B
                              ;  all LEDs off 
again:   movlw D'61'          ;  set up a counter to count down from 61
         movwf counter
         incf PORTB, f        ;  add 1 to port B, (next binary byte)

; The instructions from loop to goto loop are executed about 61 times
; a second.   The majority of this time is taken up in the 2 instruction
; loop made up by the next two instructions.  This simply waits for the 
; timer zero interrupt flag to be set which happens after timer zero 
; overflows.  TMR0 overflows after going from 255 to 0.  TMR0 normally
; runs at a rate of crystal freq/4 but we have added a 1:64 prescalar 
; which make the increment every 64 microseconds or a overflow after
; 256 * 64 = 16384 usec.  61 of these gives 999424 usec.

loop:    btfss INTCON, T0IF   ;  wait on T0IF set, skip next when set
         goto $ -1            ;  T0IF not set yet continue to loop
         bcf INTCON, T0IF     ;  clear interrupt flag, timer runs always
         decfsz counter, f    ;  decrement counter, skip if zero
         goto loop            ;  if counter not zero, wait on T0IF again

;  once 61 cycles of waiting for T0IF have happened we go back and
;  reset the counter to 61 and bump the binary number displayed by one

         goto again

         end                   ; end of program