	
	;Audio CRO 12F675.asm
	;Spinning LEDs with mic input
	;  19-1-2010 


	list	p=12F675
	radix	dec
	include	"p12f675.inc"
	
		errorlevel	-302	; Dont complain about BANK 1 Registers during assembly

	__CONFIG	_MCLRE_OFF & _CP_OFF & _WDT_OFF & _INTRC_OSC_NOCLKOUT  ;Internal osc.

	

;****************************************************************
; variables - names and files
;****************************************************************
	
shift	equ 	20h		;first available file
fetch	equ 	21h
loops	equ		22h

fileA	equ		23h
fileB	equ		24h
fileC	equ		25h	
temp1	equ		26h
test	equ		27h



		;		30h		;first location for storing A_D value 


		;		5Fh		;last location for A_D value
						;3 x 16 = 48 locations

status		equ	03h
option_reg	equ 81h


						; bits on GPIO
				
pin7		equ	0	;GP0  
pin6	 	equ	1	;GP1
pin5		equ	2	;GP2 and T0CkI
pin4		equ	3	;GP3 input only
pin3		equ	4	;GP4 
pin2		equ	5	;GP5 


						;bits
				
rp0		equ	5			;bit 5 of the status register



;****************************************************************
;Beginning of program
;****************************************************************
		

Start	org	0x00		;program starts at location 000
		nop
		nop
		nop
		nop		;NOPs to get past reset vector address
		nop
		nop


								
SetUp	bsf		status, rp0 	;Bank 1			
       	movlw	b'11111111'		;Set GPI0 input 
		movwf	TRISIO	   	    ;	
		clrf	vrcon			;Vref off (power off the comparator - saves power)
		movlw	b'01110001'		;111 sets internal oscillator
		movwf	ansel			;GPO = analogue - others digital		
		bcf		status, rp0		;bank 0 
		bsf		ADCON0,0		;turn A/D converter ON -  bit 0=1   
		bcf    	ADCON0,7  		;left justified Answer in ADRESH with 2 lowest missing		
		movlw   07h         	;Set up to turn off Comparator ports
        movwf   CMCON       	;must be placed in bank 0  
		clrf 	GPIO       		;Clear GPIO of junk	
		goto 	Main	
		

;*************************************
;* Tables 					*
;*************************************
		
		;Table1 for first pass for letters on display

Table1	addwf	02,1			;Add W to the Program Counter to create a jump
		retlw  	b'01000011'
		retlw  	b'01000011'		;line 1   
		retlw  	b'01101101'		;
		retlw  	b'01101101'					;"1" produces an input = LED OFF
		retlw  	b'01101101'
		retlw  	b'01101101'		;line 5
		retlw  	b'01000011'
		retlw  	b'01111111'	
		retlw  	b'01000111'
		retlw  	b'01111111'	
		retlw  	b'01111111'		;line 10
		
		retlw  	b'01111111'	
		retlw  	b'01000111'
		retlw  	b'01111111'	
		retlw  	b'01011111'
		retlw  	b'01100111'		;line 15
		retlw  	b'01100111'
		retlw  	b'01100111'	
		retlw  	b'01000001'
		retlw  	b'01111111'	
		retlw  	b'01000111'		;line 20

		retlw  	b'01111111'	
		retlw  	b'01011111'
		retlw  	b'01100111'		
		retlw  	b'01100111'
		retlw  	b'01100111'		;line 25
		retlw  	b'01011111'
		retlw  	b'01111111'	
		retlw  	b'01000011'
		retlw  	b'01000001'	
		retlw  	b'01011101'		;line 30

		retlw  	b'01011101'	
		retlw  	b'01011101'
		retlw  	b'01011001'	
		retlw  	b'01011011'
		retlw  	b'01111111'		;line 35
		retlw  	b'01000011'
		retlw  	b'01000001'	
		retlw  	b'01110101'
		retlw  	b'01100101'	
		retlw  	b'01110101'		;line 40

		retlw  	b'01000001'	
		retlw  	b'01100011'
		retlw  	b'01111111'	
		retlw  	b'01000011'
		retlw  	b'01000001'		;line 45
		retlw  	b'01011101'
		retlw  	b'01011101'	
		retlw  	b'01011101'
		retlw  	b'01000001'	
		retlw  	b'01000011'		;line 50
		
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	

			
		;Table2 for second pass for letters on display

Table2	addwf	02,1			;Add W to the Program Counter to create a jump
		retlw  	b'01000001'	
		retlw  	b'01000001'		;line 1
		retlw  	b'01111111'		;
		retlw  	b'01111111'	
		retlw  	b'01111111'
		retlw  	b'01111111'		;line 5
		retlw  	b'01000001'
		retlw  	b'01111111'			;"1" produces an input = LED OFF
		retlw  	b'01100111'
		retlw  	b'01011111'	
		retlw  	b'01011111'		;line 10
		
		retlw  	b'01011111'	
		retlw  	b'01100111'
		retlw  	b'01111111'	
		retlw  	b'01101111'
		retlw  	b'01010111'		;line 15
		retlw  	b'01010111'
		retlw  	b'01010111'	
		retlw  	b'01100001'
		retlw  	b'01111111'	
		retlw  	b'01000001'		;line 20

		retlw  	b'01111111'	
		retlw  	b'01101111'
		retlw  	b'01010111'		
		retlw  	b'01010111'
		retlw  	b'01010111'		;line 25
		retlw  	b'01101111'
		retlw  	b'01111111'	
		retlw  	b'01100001'
		retlw  	b'01000001'	
		retlw  	b'01011101'		;line 30

		retlw  	b'01011101'	
		retlw  	b'01011101'
		retlw  	b'00001001'	
		retlw  	b'01101001'
		retlw  	b'01111111'		;line 35
		retlw  	b'01000001'
		retlw  	b'01000001'	
		retlw  	b'01110101'
		retlw  	b'01110101'	
		retlw  	b'01100101'		;line 40

		retlw  	b'01110001'	
		retlw  	b'01010001'
		retlw  	b'01111111'	
		retlw  	b'01101001'
		retlw  	b'01000001'		;line 45
		retlw  	b'01011101'
		retlw  	b'01011101'	
		retlw  	b'01011101'
		retlw  	b'01000001'	
		retlw  	b'01101001'		;line 50
				
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	
		retlw  	b'01111111'	


;************************************
;* Delays			*
;************************************
			

		
;Delay 250uS

_250uS	movlw   30h		;movlw	06		;movlw 	0Ch
		movwf 	fileB	
Del250	nop
		decfsz 	fileB,1		; ,1 denotes the result of the decrement 
		goto 	Del250	
		retlw 	00		
		
				

	;Delay 0.01 sec (10mS)

_10mS	movlw 	0Ah
		movwf 	fileB	
DelY	nop
		decfsz 	fileA,1		; ,1 denotes the result of the decrement 
		goto 	DelY	
		decfsz 	fileB,1		;     is placed in the file	
		goto 	DelY
		retlw 	00
	
	
 
;************************************
;* Sub routines			*
;************************************
	
		
		;attract mode - displays Audio CRO on start-up
		
attract	
		
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11111111'	;Set GP3 input -look for inductor magnetism
		movwf	TRISIO
		bcf		status, rp0	;bank 0
		btfss	gpio,3
		goto	$-1
		
						;Produces first pass
		
		movlw	00				
		movwf	fetch		;gets value from table				
		movf	shift,w		;offset for fetch
		addwf	fetch,f		
		movf	fetch,0		;put fetch value into w		
		call	Table1		
		bsf		status, rp0 ;Bank 1	       			
		movwf	TRISIO		;Set tris input/output 
		bcf		status, rp0	;bank 0 		
		movlw	b'00000000'	;make GPIO LOW    
		movwf	GPIO
		call	_250uS		;display for short time
		call	_00percent	;all LEDs off
		call	_250uS		;gap between pixels	
		incf	fetch,f
		movlw	d'60'
		xorwf	fetch,w		;is fetch = 60?
		btfss	03,2		;test zero flag in status   z=1 when same
		goto	$-.14
		
						;Produces second  pass
		
		
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11111111'	;Set GP3 input -look for inductor magnetism
		movwf	TRISIO
		bcf		status, rp0	;bank 0
		btfss	gpio,3
		goto	$-1		
		movlw	00				
		movwf	fetch		;gets value from table				
		movf	shift,w		;offset for fetch
		addwf	fetch,f		
		movf	fetch,0		;put fetch value into w
		call	Table2		
		bsf		status, rp0 ;Bank 1	       			
		movwf	TRISIO		;Set tris input/output 
		bcf		status, rp0	;bank 0 		
		movlw	b'11111111'	;make GPIO HIGH    
		movwf	GPIO
		call	_250uS		;display for short time
		call	_00percent	;all LEDs off
		call	_250uS		;gap between pixels	
		incf	fetch,f
		movlw	d'60'
		xorwf	fetch,w		;is fetch = 60?
		btfss	03,2		;test zero flag in status   z=1 when same
		goto	$-.14
		retlw	00
		
		
convert						;converts A/D value to 4 output lines


		movwf	test		;load the A/D value into the "test" file (2F)
		movlw	d'10'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_10percent	;carry flag is SET if w is less than "test"
		
		movwf	test		;load the A/D value into the "test" file (2F)
		movlw	d'20'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_20percent	;carry flag is SET if w is less than "test"
		
		movwf	test		;load the A/D value into the "test" file (2F)
		movlw	d'30'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_30percent	;carry flag is SET if w is less than "test"
		
		movwf	test		;load the A/D value into the "test" file (2F)
		movlw	d'40'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_40percent	;carry flag is SET if w is less than "test"
		
		movwf	test		;load the A/D valaue into the "test" file (2F)
		movlw	d'50'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_50percent	;carry flag is SET if w is less than "test"
		
		movwf	test		;load the A/D value into the "test" file (2F)
		movlw	d'60'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_60percent	;carry flag is SET if w is less than "test"
		
		movwf	test		;load the A/D value into the "test" file (2F)
		movlw	d'70'		;load decimal  into w
		subwf	test,0		;subtract d'' from test
		btfss	03,0		;test the carry flag
		goto	_70percent	;carry flag is SET if w is less than "test"
		
		goto	_80percent	;carry flag is SET if w is less than "test"

			
		
_00percent					;ALL LEDS OFF
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11111111'	;Set all GP0 input    
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000000'	;no LEDs ON   
		movwf	GPIO
		retlw	00			

_10percent					
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11011111'	;Set GP0 input     GP5 as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00100000'	;make GP 5 high    
		movwf	GPIO
		retlw	00	

_20percent
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11011111'	;Set GP0 input     GP5 as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000000'	;make GP 5 low     
		movwf	GPIO
		retlw	00			
	
_30percent
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11101111'	;Set GP0 2 4 5  input     GP4 as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00010000'	;make GP 4 high     
		movwf	GPIO
		retlw	00		
		
_40percent
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11101111'	;Set GP0 2 5 input     GP4  as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000000'	;make GP 4 low       
		movwf	GPIO
		retlw	00		
		
_50percent		
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11111011'	;Set GP0 2 5 input     GP2  as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000100'	;make GP 2 high      
		movwf	GPIO
		retlw	00
						
_60percent	
		bsf		status, rp0 ;Bank 1			
       	movlw	b'1111011'	;Set GP0 input     GP2 as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000000'	;make GP 2 low     
		movwf	GPIO
		retlw	00			
		
_70percent	
		bsf		status, rp0 ;Bank 1			
       	movlw	b'1111101'	;Set GP0 input     GP1 as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000010'	; make GP 1 high    
		movwf	GPIO
		retlw	00
					
_80percent
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11111101'	;Set GP0 input     GP1 as output 
		movwf	TRISIO
		bcf		status, rp0	;bank 0 		
		movlw	b'00000000'	;make GP 1 low    
		movwf	GPIO
		retlw	00	
		
		
				
;*************************************
;* Main 							*
;*************************************
			
			;Displays "Audio CRO" 
					;called "attract mode"
			
Main	clrf	shift		;moves display to the left by adding offset to fetch
		movlw	.60
		movwf	loops		;number of loops before display starts to shift		
		call	attract	
		decfsz	loops,f
		goto	$-2			
		
						;shifts message across screen
						
		
				
		incf	shift,f
		movlw	.1 
		movwf	loops		;number of loops before display shifts
		call	attract
		movlw	d'49'			;number of shifts before exit	
		xorwf	shift,w		;is shift = 49?
		btfsc	03,2		;test zero flag in status   z=1 when same
		goto	$+4			
		decfsz	loops,f
		goto	$-6
		goto	$-.10
		
						;stores 48 values in files 30h to 5Fh

Main1	bsf		status, rp0 ;Bank 1			
       	movlw	b'11111111'	;Set GP3 input -look for inductor magnetism
		movwf	TRISIO
		bcf		status, rp0	;bank 0
		btfss	gpio,3
		goto	$-1
		movlw	30h			;first location for storing A_D value 
		movwf	04h			;put value into File Select Register		
		bsf		ADCON0,1	;Start A/D on GP0 (pin 7)
		btfsc	ADCON0,1	;has conversion finished?
		goto	$-1		
		movf	ADRESH,w	;put result of conversion into w
		movwf	00h			;move value into INDF (actually 30h+)
		incf	04h,f		;increment FSR to 31h etc
		movlw	5Fh
		xorwf	04h,w		;is file 04h = 5Fh
		btfss	03,2		;test zero flag in status   z=1 when same
		goto	$-9			;has loops reached file 5Fh?  no	
		
						;displays 48 values on screen 
			
		movlw	d'30'
		movwf	loops		;creates the 0.5sec refresh-time for viewing display		
		bsf		status, rp0 ;Bank 1			
       	movlw	b'11111111'	;Set GP3 input -look for inductor magnetism
		movwf	TRISIO
		bcf		status, rp0	;bank 0
		btfss	gpio,3
		goto	$-1		
		movlw	30h			;first location for A_D value 
		movwf	04h			;put value into File Select Register
		movf	00h,w		;move value from INDF (30h+) into w
		call	convert
		call	_250uS		;display for short time
		call	_00percent	;all LEDs off
		nop					;gap between pixels		
		incf	04h,f		;increment FSR to 31h etc
		movlw	5Fh
		xorwf	04h,w		;is file 04h = 5Fh
		btfss	03,2		;test zero flag in status   z=1 when same
		goto	$-9
		decfsz	loops,1		;loops reached file 5Fh
		goto	$-.19
		goto	Main1
		
		
			;oscillator calibration


		call 	03ffh
		movwf	OSCCAL	
		

	end
		
