;****************************************************************
;Started 18/6/2009	
;STROOP GAME - Press button according to the colour of the LED
;Buttons recognised when project turned on.
;Port A drives 3 tri-coloured LEDs
;Port B drives 7 segment display and keys
;****************************************************************

	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
count		equ	22h	;counts loops for switch
Random		equ	23h	;random number file
units		equ	24h	;
tens		equ	25h	;
Sw_Flag		equ	26h	;
_20Secs		equ	27h	;file for counting up to 20 seconds
loops		equ	28h	;loops for number display
Produce		equ	29h	;produce random number
temp3		equ	2Ah	;for 500mS

;****************************************************************
;Equates
;****************************************************************
status		equ	0x03
cmcon		equ	0x1F
rp1			equ	0x06
rp0			equ	0x05
portA 		equ 0x05
portB 		equ 0x06

z			equ	0x02


;****************************************************************
;Beginning of program
;****************************************************************


Start	org		0x00		;program starts at location 000
		goto	Stroop		;goto Stroop
		nop		
		nop					;NOPs to get past reset vector address
		org		4
		goto	isr	


SetUp	bsf		status,rp0	
		movlw	b'00000000'		;Make RA output
		movwf	05h				;trisA
		clrf	06h				;trisB   Make all RB output
		movlw	b'10000000'; 
		movwf	OPTION_REG		; x000 0000 x=1= weak pull-ups disabled						  			
		bcf		status,rp0		;select programming area - bank0 		
		movlw	b'00000000'		;6,7=0 disables all interrupts  
		movwf 	INTCON			;until we want timing to commence	
		clrf	Sw_Flag
		movlw	07h				;turn comparators off 
		movwf	cmcon		
		clrf	portA
		clrf	portB	
		clrf	units		
		clrf	tens			
		clrf	Random			;random will be 1-9 
		movlw	.39
		movwf	_20Secs
		goto 	Main					

;*************************************
;* Tables 					*
;*************************************

table1	addwf   PCL,F           ;02h,1  
		nop						;display random LED colour
        retlw   b'00000001'     ; Led A - red
        retlw   b'00000011'     ; Led A - orange
        retlw   b'00000010'     ; Led A - green
        retlw   b'00000100'     ; Led B - red
        retlw   b'00001100'     ; Led B - orange
        retlw   b'00001000'     ; Led B - green
        retlw   b'01000000'     ; Led C - red
        retlw   b'11000000'     ; Led C - orange
        retlw   b'10000000'     ; Led C - green
        
table2	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


;************************************
;* Sub routines			*
;************************************

Attract			;flash all red, orange  green then random LED							
		
		movlw	b'01000101'     ; all red				
		movwf	portA
		call	_250mS
        movlw	b'11001111'     ; all orange
		movwf	portA
		call	_250mS             
        movlw	b'10001010'     ; all green
        movwf	portA
		call	_250mS 
		clrf	portA
		call	_250mS 
		call	_250mS              
		retlw	00
					
		;produce random number
		
Create	incf	Produce,f	
		movlw	.10			;put ten into w
		xorwf	Produce,0	;compare Random file with ten
		btfss	status,2	;zero flag in status file. Will be set if Random is ten
		goto	$+3		
		clrf	Produce
		incf	Produce,f
		retlw	00					
										

	;Delays
	
_1mS	nop
		decfsz 	temp1,f
		goto 	_1mS
		retlw 	00
			

_10mS	movlw	0Ah
		movwf	temp2
_b		nop
		decfsz 	temp1,f
		goto 	_b
		decfsz 	temp2,f
		goto 	_b	
		retlw 	00
		
		
		
_100mS	movlw	.100
		movwf	temp2
_c		nop
		decfsz 	temp1,f
		goto 	_c
		decfsz 	temp2,f
		goto 	_c	
		retlw 	00
				
_250mS	movlw	.240
		movwf	temp2
_d		nop
		decfsz 	temp1,f
		goto 	_d
		decfsz 	temp2,f
		goto 	_d	
		retlw 	00	
		
_500mS	movlw	02
		movwf	temp3
		call	_250mS		
		decfsz	temp3,f		
		goto	$-2
		retlw	00
		
_3Sec	movlw	.12
		movwf	temp3
		call	_250mS		
		decfsz	temp3,f		
		goto	$-2
		retlw	00	
		
	
;interrupt service routine		

isr		nop		
		bsf		status,rp0 	;Bank 1						
		bsf		PIE1,0		;,0 1=enables TMR1 interrupt				
		bcf		status,rp0	;bank 0 		
		bcf		PIR1,0		;clear TMR1 overflow flag
		bsf		INTCON,7	;This instruction is needed HERE!!!	
		bsf		INTCON,6	;1=enable all peripheral interrupts		
		decfsz	_20Secs,f	;creates 20Sec delay for each game.
		retfie
		
		bcf		PIE1,0		;,0 0=disables TMR1 interrupt
		bcf		INTCON,6	;0=disable all peripheral interrupts
		
		decf	tens,f
		incf	tens,f
		movlw	.10
		subwf	units,f
		btfsc	status,0	;test carry bit for borrow
		goto	$-4
		movlw	.10
		addwf	units,f
		
		movlw	03
		movwf	loops
				
		movf	tens,w
		btfsc	status,z
		goto	$+.18		;If 0-9, display single digit
		call	table2
		movwf	portB
		call	_500mS
		call	_250mS
		clrf	portB
		call	_250mS		
		movf	units,w
		call	table2
		movwf	portB
		call	_500mS
		call	_250mS
		clrf	portB
		call	_500mS
		call	_500mS
		decfsz	loops,f
		goto	$-.18
		goto	SetUp
								
		movf	units,w
		call	table2
		movwf	portB
		call	_3Sec		
		goto	SetUp
		
		
		; show Stroop
		
Stroop	bsf		status,rp0	
		clrf	06h				;trisB   Make all RB output
		movlw	b'10000000'; 
		movwf	OPTION_REG		; x000 0000 x=1= weak pull-ups disabled						  			
		bcf		status,rp0		;select programming area - bank0 		
		movlw	07h				;turn comparators off 
		movwf	cmcon		
		clrf	portA		

		movlw	b'01101101'     ; "S"	
		movwf	portB
		call	_500mS
		clrf	portB
		call	_250mS
		movlw	b'01111000'     ; "t"
		movwf	portB	
		call	_500mS
		clrf	portB
		call	_250mS
		movlw	b'01010000'     ; "r"
		movwf	portB	
		call	_500mS
		clrf	portB
		call	_250mS
		movlw	b'01011100'     ; "o"
		movwf	portB	
		call	_500mS
		clrf	portB
		call	_250mS
		movlw	b'01011100'     ; "o"
		movwf	portB	
		call	_500mS
		clrf	portB
		call	_250mS
		movlw	b'01110011'     ; "P"	
		movwf	portB
		call	_500mS
		clrf	portB
		goto 	SetUp
		
				
Sw		clrf	Sw_Flag
		bsf		status,rp0			
		bcf		06h,7			;trisB   Make bit 7 output
		bcf		status,rp0
		bsf		portB,7			;make bit 7 HIGH	
		call	_1mS			;create delay to charge 100n		
		bsf		status,rp0			
		bsf		06h,7			;trisB   Make bit 7 input
		bcf		status,rp0		
		call	_10mS
		call	_10mS
		btfsc	06h,7			;if HIGH, button not pushed	
		retlw	00										
		clrf	count
		bsf		status,rp0			
		bcf		06h,7			;trisB   Make bit 7 output
		bcf		status,rp0
		bsf		portB,7			;make bit 7 HIGH	
		call	_1mS			;create delay to charge 100n		
		bsf		status,rp0			
		bsf		06h,7			;trisB   Make bit 7 input
		bcf		status,rp0					
SwA		call	_1mS
		call	_1mS
		incf	count,f
		btfsc	06h,7			;is input HIGH?				
		goto	SwA				;count exits with 1-8
		bsf		Sw_Flag,0		;button has been pushed
		decfsz	count,f
		goto	$+3
		bsf		Sw_Flag,1
		retlw	00
		decfsz	count,f
		goto	$+3
		bsf		Sw_Flag,1
		retlw	00
		decfsz	count,f
		goto	$+3
		bsf		Sw_Flag,2
		retlw	00
		decfsz	count,f
		goto	$+3
		bsf		Sw_Flag,2
		retlw	00
		decfsz	count,f
		goto	$+3
		bsf		Sw_Flag,2
		retlw	00		
		bsf		Sw_Flag,3
		retlw	00
		
		
		;switch released		
		
Sw_Rel	clrf	Sw_Flag
		bsf		status,rp0			
		bcf		06h,7			;trisB   Make bit 7 output
		bcf		status,rp0
		bsf		portB,7			;make bit 7 HIGH	
		call	_1mS			;create delay to charge 100n		
		bsf		status,rp0			
		bsf		06h,7			;trisB   Make bit 7 input
		bcf		status,rp0		
		call	_10mS
		call	_10mS
		btfsc	06h,7			;if HIGH, button not pushed	
		retlw	00				
		bsf		Sw_Flag,0
		retlw	00
		
				
;*************************************
;* Main 							*
;*************************************

							;Stroop comes on "blank" looking for button-push
Main	call	Create
		call	Sw
		btfss	Sw_Flag,0	
		goto	$-3			;no
							;button pressed and Random Number generated
							
							;Stroop goes into ATTRACT mode then stops on Random LED
		call	Attract					
							
					;Display Random LED colour, waiting for sw press
			

;****************************************************************
;* Start Timer1 to count 20 seconds in the background		*
;****************************************************************
		
		bsf		status,rp0 	;Bank 1			
		movlw	b'10000000'	; 
		movwf	OPTION_REG	; x000 0000 x=1= weak pull-ups disabled 									
		bcf		status,rp0	;bank 0 		
				
		movlw	b'11000000'	;b'11000000'
		movwf 	INTCON		;,0  1=RB port change interrupt flag
							;,1  1=RB0 interrupt occurred
		;bcf	INTCON,2	;1=TMR0 overflowed. Clear overflow flag 
		;bcf	INTCON,3	;1=enable RB port change interrupt
		;bcf	INTCON,4	;1=enable RB external interrupt				
		;bsf	INTCON,5	;1=enable TMR0 overflow (interrupt)
		;bcf	INTCON,6	;1=enable all peripheral interrupts
		;bsf	INTCON,7	;1=enable all unmasked interrupts
				
		movlw	b'00110101'	;b'00110001'			
		movwf	T1CON		;,7  not used
							;,6 0=Timer1 is ON
							;,5,4  11=8 prescale (max) 01=1:2
							;,3 bit ignored
							;,2 This MUST BE SET!!!!!!
							;,1 0=int clock 
							;,0 1=enable timer1 
							
		bsf		status,rp0 	;Bank 1	(Must use Bank1)					
		bsf		PIE1,0		;,0 1=enables TMR1 interrupt					
		bcf		status,rp0	;bank 0 
		bcf		PIR1,0		;clear TMR1 overflow flag
		
		clrf	TMR1L		;clear the Timer1 low register
		clrf	TMR1H		;clear the Timer1 high register
							;Timer0 is not used 		
							; will go to isr when overflow occurs in TMR1	
							;0.52 sec when prescaler=1:8  524,288uS									
		
		bsf		status,rp0 	;Bank 1	(Must use Bank1)					
		bsf		PIE1,0		;,0 1=enables TMR1 interrupt					
		bcf		status,rp0	;bank 0 
		
							;game has started with random LED	
							
						
Main2	movf	Produce,w					
		movwf	Random		
		call	table1
		movwf	portA		;show random number
							;program gets to here after 1 press						
		
		call	Create
		call	Sw
		btfss	Sw_Flag,0	;has button been pressed?
		goto	$-3			;no
							;button pressed							
							
		movlw	01
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,1	;random=1	Is sw = button1
		goto	release
		incf	units,f
		goto	release	
			
		movlw	02
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,2	;random=2	Is sw = button2
		goto	release
		incf	units,f
		goto	release	
		
		movlw	03
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,3	;random=3	Is sw = button3
		goto	release
		incf	units,f
		goto	release		
		
		movlw	04
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,1	;random=4	Is sw = button1
		goto	release
		incf	units,f
		goto	release		
		
		
		movlw	05
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,2	;random=5	Is sw = button2
		goto	release
		incf	units,f
		goto	release		
		
		
		movlw	06
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,3	;random=6	Is sw = button3
		goto	release
		incf	units,f
		goto	release		
		
		
		movlw	07
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,1	;random=7	Is sw = button1
		goto	release
		incf	units,f
		goto	release		
		
		
		movlw	08
		xorwf	Random,0	;yes
		btfss	status,z	;test zero bit for compare
		goto	$+5
		btfss	Sw_Flag,2	;random=8	Is sw = button2
		goto	release
		incf	units,f
		goto	release			
		
		incf	units,f
		goto	release		
		
					
release	clrf	portA
		call	_500mS			
		goto	Main2


		End	

	
	
	