pic-count / count.asm
; Copyright (c) 2002, TundraWare Inc.
; Loosely based on David Tait's LED 'WALK.ASM' Test Program
; Uses same hardware setup but counts in binary, flashing at
; full count.

;;; Generally speaking, UPPER-CASE symbols in the code below are
;;; defined in the standard MPLAB include file.  My code is in
;;; lower-case.
        list            p=16F84A
	#include	<P16F84A.INC>

        errorlevel      -302    ;suppress bank selection messages
        __config        3ff5h   ;xt osc, watchdog
        __idlocs        1234
;;; Device Constants

pre1	equ	08h		; prescaler constants
pre2	equ	09h
pre4	equ	0ah
pre8	equ	0bh
pre16	equ	0ch
pre32	equ	0dh
pre64	equ	0eh
pre128	equ	0fh	

;;; Program Constants
blinkcnt	equ	05h     ; number of times to blink
bcount		equ     0dh     ; register to hold blink count
maxcnt		equ	0fh     ; maximum count to display
preblink	equ	pre32	; prescaler value for blinking
precount	equ	pre16	; prescaler value for counting

; Main program logic

begin	call	portb_w		; setup PORTB for writing
	movlw   precount	; set prescaler for slow disply
	call	wdt_pre
	movlw	maxcnt		; number of counts
        clrf    PORTB           ; all leds off
count   sleep			; display current count for a while
	incf	PORTB,F		; next value to display
	movf	PORTB,W		; see if we're displaying 'maxcnt'
	andlw	0fh		; mask hi nibble - no LEDs there
	xorlw	maxcnt		; subtract 'maxcnt' from w
	btfss	STATUS,Z
	goto	count		; nope, continue counting
	call	blink
	goto begin

;;; End of main logic


; Supporting Subroutines

; Set PORTB To Write
; Returns with Bank 0 selected

portb_w	bsf	STATUS,RP0      ; select register bank 1   
        clrf    TRISB           ; set PORTB to all outputs
        bcf     STATUS,RP0      ; select register bank 0

;;; End of 'portb_w'

; Set the WDT Prescaler
; Value required must be passed in w
; Returns with Bank 0 selected

wdt_pre	bsf     STATUS,RP0      ; select register bank 1
	bcf	STATUS,RP0      ; bank0 so PORTB is addressable

;;; End of 'wdt_pre'

; Blink The Lights
blink   movlw   preblink	; set prescaler for fast blink
	call	wdt_pre
	movlw   blinkcnt	; number of times to blink
	movwf   bcount
bcycle	sleep			; display on from caller
	clrf	PORTB		; display off
	decfsz  bcount,F	; if zero, we've done 'blinkcnt' repetitions
	goto	again		; we're not done yet
	return			; all done
again	movlw   maxcnt  	; blink again - display on
	movwf	PORTB
	goto	bcycle
;;; End of 'blink'

; EEPROM Contents
        org     2100h
        DE      "$Id: count.asm,v 1.9 2002/03/10 15:43:56 tundra Exp tundra $"