;****************************************************************
;*     Started 18/6/2009	
;2 Digit UP / Down Counter with FastCount after 2secs
;Buttons "Up" and "Down" recognised when at instant project turned on.
;Button A goes to DICE
;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
temp3		equ 22h	;for delay
SwUp		equ	23h	;
SwDwn		equ	24h	;
units		equ	25h	;
tens		equ	26h	;
Sw_Flag		equ	27h	;
FastCount	equ	28h	;

;****************************************************************
;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	
;Button Up  and Button Down recognised when project turned on.				*
;****************************************************************

SetUp	bsf		status,rp0	
		movlw	b'00001100'		;Make RA0,1 out RA2 in(Up),RA3 in(Down)
		movwf	05h				;trisA
		clrf	06h				;trisB   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	
		btfss	portA,2	
		goto	AAA				;Button A detected (detects LOW)
		;btfss	portA,3	
		;goto	Random			;Button B detected (see next program)
		goto 	Main						
					
AAA		call	D_250mS
		btfsc	portA,2	
		goto	Dice
		movlw	b'00000010'		;Make RA1 HIGH for left display 	
		movwf	portA
		movlw	b'01011110'		; "d"   G|-|E|D|C|B|-
		movwf	portB
		call 	D_250mS
		movlw	b'00000110'		; "I"   -|-|-|-|C|B|-
		movwf	portB
		call 	D_250mS
		movlw	b'00111001'		; "C"   -|F|E|D|-|-|A
		movwf	portB
		call 	D_250mS
		movlw	b'01111001'		; "E"   G|F|E|D|-|-|A
		movwf	portB
		call 	D_250mS
		clrf	portB
		goto	AAA


;****************************************************************
;* 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
		
		
		
D_100mS	movlw	d'100'
		movwf	temp2
D_b		nop
		decfsz 	temp1,1
		goto 	D_b
		decfsz 	temp2,1
		goto 	D_b	
		retlw 	00	
		
D_250mS	movlw	d'250'
		movwf	temp2
D_c		nop
		decfsz 	temp1,1
		goto 	D_c
		decfsz 	temp2,1
		goto 	D_c	
		retlw 	00			
		
		
D_3Sec	movlw	d'15'
		movwf	temp3		
D_d		nop
		decfsz 	temp1,1
		goto 	D_d
		decfsz 	temp2,1
		goto 	D_d	
		decfsz 	temp3,1
		goto 	D_d	
		retlw 	00			
		
		
		
FastUp	btfss	Sw_Flag,2	;First time through loop?
		goto	FU_2		;yes
		btfsc	Sw_Flag,7	;Has 5Hz bit been set?
		goto	FU_3
FU_1	incfsz	FastCount,1	;Increment FastCount
		movlw	d'100'
		xorwf	FastCount,0
		btfss	status,2	;reached 100 loops?
		retlw	00
		clrf	FastCount
		bsf		Sw_Flag,7	;set bit for 5Hz incrementing		
				
		

FU_2	bsf		Sw_Flag,2	;Up button has been pressed				
		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
		
		
FU_3	incfsz	FastCount,1	;Increment FastCount
		movlw	d'5'
		xorwf	FastCount,0
		btfss	status,2	;reached 5 loops?
		retlw	00
		clrf	FastCount		
		goto	FU_2		
			
		
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	
		
			
;****************************************************************
;* Dice 	Produces a random number from 1 to 6 on display
;  The display flashes before settling on a number - called attract mode.
;Program detects timing of button-push to generate number		*
;****************************************************************

Dice	incf	units,f
		btfss	portA,2		;look for button-push			
		goto	Start		;button A pushed
		movf	units,w
		xorlw	06
		btfss	status,2		
		goto	Dice
		clrf	units
		goto	Dice
		
Start	movlw	08
		movwf	temp3
		call	Attract
		decfsz	temp3,f
		goto	$-2		
		goto	Show		;
		
		
Attract	movlw	b'00000001'	;Make RA0 HIGH for right-hand display 	
		movwf	portA
		movlw	b'00001000'	;	
		movwf	portB				
		call	D_100mS		
		
		movlw	b'01000000'	;	
		movwf	portB				
		call	D_100mS
		
		movlw	b'00001000'	;	
		movwf	portB				
		call	D_100mS
		movlw	b'00000001'	;	
		movwf	portB				
		call	D_100mS
		
		retlw	00
		
Show	movf	units,w		
		call	table
		movwf	portB
Show1	call	D_250mS
		btfss	portA,2		;look for button not pushed		
		goto	Show1
		goto	Dice
					
		
;****************************************************************
;* Main 							*
;****************************************************************

Main	btfss	portA,2			;test switch-press for UP
		call	FastUp			;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,3			;bit will be zero when sw is pressed
		bcf		Sw_Flag,3		;button not pressed. Clear down flag		
		btfss	portA,2			;bit will be zero when sw is pressed
		goto	Main
		bcf		Sw_Flag,2		;button not pressed. Clear Up flag
		bcf		Sw_Flag,7		;Clear Up repeat flag
		clrf	FastCount
		goto	Main		
		
		END
	
	
	