;****************************************************************
;* 2 Digit UP / Down Counter    Started 17/6/2009	
;Port B drives 7 segment display
;Up sw on RA2   Down on RA3
;Units drive on RA0   Tens drive on RA1					*
;* 								*
;****************************************************************

	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
SwUp		equ 22h	;
SwDwn		equ	23h	;
units		equ	24h	;
tens		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
;****************************************************************
reset	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
        retlw   b'00000111'     ; "7"   -|-|-|-|C|B|A
        retlw   b'01111111'     ; "8"   G|F|E|D|C|B|A
        retlw   b'01101111'     ; "9"   G|F|-|D|C|B|A


;****************************************************************
;* port A and B initialisation					*
;****************************************************************

SetUp	bsf		status,rp0	
		movlw	b'00001100'		;Make RA0,1 out   RA2,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	units			;zero the units file		
		clrf	tens			;zero the tens file		
		clrf	Sw_Flag
		movlw	07h				;turn comparators off and enable
		movwf	cmcon			;    pins for I/O functions						
		goto 	Main						
					


;****************************************************************
;* 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
		
		
Up		btfsc	Sw_Flag,2
		retlw	00
		bsf		Sw_Flag,2
		incf	units,1
		movlw	0Ah			;put 10 into w
		xorwf	units,0		;compare units file with 10
		btfss	status,2	;zero flag in status file. Will be set if units is 10
		retlw	00
		clrf	units
		incf	tens,1
		movlw	0Ah			;put 10 into w
		xorwf	tens,0		;compare units file with 10
		btfsc	status,2	;zero flag in status file. Will be set if tens is 10
		clrf	tens				
		retlw	00			;display passes 99 but not below 0
		
		
		
Dwn		btfsc	Sw_Flag,3
		retlw	00
		bsf		Sw_Flag,3
		decf	units,1
		movlw	0FFh		;put FFh into w
		xorwf	units,0		;compare units file with FFh
		btfss	status,2	;zero flag in status file. Will be set if units is 10
		retlw	00
		movlw	09
		movwf	units		;put 9 into units file
		decf	tens,1
		movlw	0FFh		;put 0FFh into w
		xorwf	tens,0		;compare tens file with 0FFh
		btfsc	status,2	;zero flag in status file. Will be set if tens is 0FFh
		goto	$+2			;tens file is 0FFh
		retlw	00						
		clrf	tens
		clrf	units
		retlw	00			;display  not below 0		
							
		
;****************************************************************
;* Main 							*
;****************************************************************

Main	btfss	portA,2			;test switch-press for UP
		call	Up				;UP switch pressed
		btfss	portA,3			;test switch-press for Down
		call	Dwn				;Down switch pressed
		movlw	b'00000001'		;Make RA0 HIGH for units drive 	
		movwf	portA	
		movf	units,0			;copy unit value into w
		call	table			;unit display value will return in w
		movwf	portB			;output units value
		call	D_10mS			;call delay
		clrf	portB			;clear display
		movlw	b'00000010'		;Make RA1 HIGH for tens drive 	
		movwf	portA			
		movf	tens,0			;copy tens value into w		
		call	table			;tens display value will return in w
		movwf	portB			;output tens value
		call	D_10mS			;call delay
		clrf	portB			;clear display
		btfsc	portA,2			;bit will be zero when sw is pressed
		bcf		Sw_Flag,2
		btfsc	portA,3			;bit will be zero when sw is pressed
		bcf		Sw_Flag,3				
		goto	Main		
		
		END
	
	
	