;****************************************************************
;Up/Down Counter for Bikes.  Started 30/4/2010	for R Cermak
;Up sw on RA2   Down on RA3
;Port B drives 7 segment display
;Down for 1 then up for 2,3,4,5,6
;or if up is pressed at the beginning, display shows 2
;   16F628.asm

;****************************************************************

	list P = 16F628		;microcontroller 
	include <P16F628.inc>	;registers for F628


	__Config 	_cp_off & _lvp_off & _pwrte_on & _wdt_off & _intRC_osc_noclkout & _mclre_off
	
;code protection - off
;low-voltage programming - off
;power-up timer -  on
;watchdog timer - off
;use internal RC for 4MHz - all pins for in-out


;****************************************************************
; variables - names and files
;****************************************************************


		;Files for F628 start at 20h 
 
						 			
temp1		equ 20h	;for delay
temp2		equ 21h	;for delay
temp3		equ 22h	;for delay
SwUp		equ	23h	;
SwDwn		equ	24h	;
count		equ	25h	;
Sw_Flag		equ	26h	;


;****************************************************************
;Equates
;****************************************************************
status		equ	0x03
cmcon		equ	0x1F
rp1			equ	0x06
rp0			equ	0x05
portA		equ 0x05
portB		equ 0x06

;****************************************************************
;Beginning of program
;****************************************************************
Start	org		00				;reset vector address	
		goto	SetUp			;goto SetUp
			

table	addwf   PCL,F           ;02h,1  add W to program counter 
        retlw   b'00111111'     ; "0"   -|F|E|D|C|B|A
        retlw   b'00000110'     ; "1"   -|-|-|-|C|B|-
        retlw   b'01011011'     ; "2"   G|-|E|D|-|B|A
        retlw   b'01001111'     ; "3"   G|-|-|D|C|B|A 
        retlw   b'01100110'     ; "4"   G|F|-|-|C|B|-
        retlw   b'01101101'     ; "5"   G|F|-|D|C|-|A
        retlw   b'01111101'     ; "6"   G|F|E|D|C|-|A
       

;****************************************************************
;* port A and B initialisation					*
;****************************************************************

SetUp	bsf		status,rp0	
		movlw	b'00001111'		;Make RA0,1,2,3 in
		movwf	05h			
		clrf	06h				;Make all RB output
		bcf		status,rp0		;select programming area - bank0 
		movlw	b'10000000'		;Turn off T0CKI, prescale for TMR0 = 1:
		movwf	option_reg		
		clrf 	portB			;Clear Port B of junk 
		clrf	count			;zero the count file		
		clrf	Sw_Flag
		movlw	07h				;turn comparators off and enable
		movwf	cmcon			;    pins for I/O functions						
		goto 	Pre				;shows 0,1,2,3,4,5,6,0  at 2Hz and stops on "0"	
					


;****************************************************************
;* Delay 10mS 		10 x 1,000uS			*
;****************************************************************

D_10mS	movlw	0Ah
		movwf	temp2
D_a		nop
		decfsz temp1,1
		goto 	D_a
		decfsz temp2,1
		goto 	D_a	
		retlw 	00
		
			
	;Delay 0.51 sec

D_500mS	movlw 	02h
		movwf 	temp3	
DelX	decfsz 	temp1,1	
		goto 	DelX	
		decfsz 	temp2,1		
		goto 	DelX
		decfsz 	temp3,1
		goto 	DelX
		retlw 	00
		
			
Up		btfsc	Sw_Flag,1
		goto	M1
		bsf		Sw_Flag,1
		movlw	06h			;put 6 into w
		xorwf	count,0		;compare count file with 6
		btfsc	03,2		;zero flag in status file. Will be set if count is 6
		goto	M1
		incf	count,f		;increment display
		goto	M1			;
		
		
Down	btfsc	Sw_Flag,1
		goto	M1
		bsf		Sw_Flag,1
		movlw	01h			;put 1 into w
		xorwf	count,0		;compare units file with 1
		btfsc	03,2		;zero flag in status file. Will be set if count is 1
		goto	M1
		movlw	00h			;put 0 into w
		xorwf	count,0		;compare count file with 1
		btfsc	03,2		;zero flag in status file. Will be set if count is 0
		goto	M1		
		decf	count,f		;decrement display
		goto	M1			;
		
		
		;Reset ONLY produces 0
		
Reset	clrf	count     ; "0" 
		call	table		
		movwf	portB
		goto	Pre	
		
		
dim		clrf	portB			
		call	D_10mS					
		goto	Main	
		
		;Pre	shows 0,1,2,3,4,5,6,0  at 2Hz and stops on "0"
		
		
Pre		movlw	b'00111111'	;show 0
		movwf	portB
		call	D_500mS
		movlw	b'00000110' ;show 1
		movwf	portB
		call	D_500mS
		movlw	b'01011011' ;show 2
		movwf	portB
		call	D_500mS
		movlw	b'01001111' ;show 3
		movwf	portB
		call	D_500mS
		movlw	b'01100110'	;show 4
		movwf	portB
		call	D_500mS
		movlw	b'01101101' ;show 5
		movwf	portB
		call	D_500mS
		movlw	b'01111101'	;show 6
		movwf	portB
		call	D_500mS
		clrf	count
		call	table
		movwf	portB
		goto	M_First
		
							
		
;****************************************************************
;* Main 							*
;****************************************************************

M_First	btfss	portA,1			;test switch-press for reset
		goto	Reset			;reset pushed
		btfss	portA,2			;test switch-press for up
		goto	$+5				;
		btfsc	portA,3			;test switch-press for down
		goto	M_First
		incf	count,1			;show 1 if down pressed at start
		goto	Main	
		incf	count,1			;show 2 if Up pressed at start				
		goto	Main
		
		
		

		
		
Main	btfss	portA,1			;test switch-press for RESET
		goto	Reset
		btfss	portA,2			;test switch-press for UP
		call	Up				;UP switch pressed
		btfss	portA,3			;test switch-press for Down
		call	Down			;Down switch pressed			
		movf	count,w			;copy count value into w
		call	table			;unit display value will return in w
		movwf	portB			;output count value
		call	D_10mS			;call delay		
		btfsc	portA,2			;bit will be zero when sw is pressed
		bcf		Sw_Flag,1
		btfsc	portA,3			;bit will be zero when sw is pressed
		bcf		Sw_Flag,1
		btfss	portA,0			;test switch for dim = HIGH input
		goto	dim						
M1		goto	Main				
		
		
		
		
		
		
				
		
		END
	
	
	
