 LIST P=PIC16F684, R=DEC
 INCLUDE "p16f684.inc"

 __CONFIG _FCMEN_OFF & _IESO_OFF & _BOD_OFF & _CPD_OFF & _CP_OFF & _MCLRE_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT

#define	ENA PORTC,2
#define	SDA	PORTC,3
#define	SCK PORTC,4

; data segment
 CBLOCK 0x20                   
 del  							; variable used for delay
 tmp							; local temp variable	
 temp:2, dat:2					; storage for temperature		
 cnt
 ENDC

; code segment
 ORG 0                      	; start program at the beginning of mem
	bcf		STATUS, RP0			; activate BANK 0
	clrf	PORTA				; initialize PORT A
	clrf	PORTC				; initialize PORT C
	bsf		ENA
	movlw	0x07
	movwf	CMCON0				; comparators OFF
	bsf    	STATUS, RP0      	; switch to BANK 1

 	; ADC and PWM configuration
	movlw	b'00001011'
	movwf	TRISA ^ 0x80		; enable input on pins RA3, AN0, Vref
	movlw	b'00000011'
	movwf	ANSEL ^ 0x80		; configure AN0, AN1 as analog inputs
	movlw 	b'00010000' 		; set ADC clock as FOSC/8
	movwf 	ADCON1 ^ 0x80
	clrf	TRISC ^ 0x80		; enable outputs on PORTC
	movlw	b'01100001'
	movwf	OSCCON ^ 0x80		; oscillator freq = 4 MHZ
	bcf    	STATUS, RP0        	; back to BANK 0

	movlw	b'11000001'
	movwf 	ADCON0 				; Right justify, Ext. Vref, AN3, On	

	call	init_MAX6950		; initialize the LED driver
	clrf	cnt 

loop
	movlw	250
	movwf	del
	call	delay				; 0.25 sec delay

	bsf		ADCON0, GO			; start ADC operation
	btfsc	ADCON0, GO			; and wait for its completion	
	 goto 	$-1

	bsf		STATUS, RP0			; switch to BANK 1
	movf	ADRESL ^ 0x80, w	; get lower 8 bits of ADC
	bcf		STATUS, RP0			; back to BANK 0
	movwf	temp
	movf	ADRESH, w			; get 8 higher bits of ADC
	movwf	temp+1

	call	display
  	goto 	loop				; endless loop


; procedures
init_MAX6950
	movlw	1
	movwf	dat+1				; decode register
	movlw	b'00001111'			; enable decoding for all digits
	movwf	dat
	call	write_MAX6950
 
	movlw	2
	movwf	dat+1				; intensity register
	movlw	1
	movwf	dat					; initial intensity 1/16
	call	write_MAX6950

	movlw	3
	movwf	dat+1				; scan limit register
	movlw	3
	movwf	dat					; scan 4 digits
	call	write_MAX6950
	
	movlw	4
	movwf	dat+1				; config register
	movlw	b'00100001'			; no blinking, normal mode, reset
	movwf	dat					
	call	write_MAX6950
	return

write_MAX6950					; write a 16-bit word; first byte is reg address
	movlw	16					; bits counter
	bcf		SCK					; make sure that SCK=0
	bcf		ENA					; enable the device

write_loop	
	rlf		dat, f
	rlf		dat+1, f			; shift out MSB to 
	btfsc	STATUS, C
	 bsf	SDA
	btfss	STATUS, C
	 bcf	SDA					; the data line is set up now
	bsf		SCK					; clock up
	nop							; short delay
	bcf		SCK					; ... and down	
	addlw	-1
	btfss	STATUS, Z			; all bits sent?
	 goto	write_loop			; not yet

	bsf		ENA					; yes - latch in the data and exit
	return	

display							; display ADC data in HEX
	movf	temp+1, w
	movwf	dat		
	swapf	dat, f
	bcf		dat, 7
	movlw	0x63				; digit 3 address
	movwf	dat+1
	call	write_MAX6950

	movf	temp+1, w
	movwf	dat	
	bcf		dat, 7	
	movlw	0x62				; digit 2 address
	movwf	dat+1
	call	write_MAX6950

	movf	temp, w
	movwf	dat		
	swapf	dat, f
	bcf		dat, 7
	movlw	0x61				; digit 1 address
	movwf	dat+1
	call	write_MAX6950

	movf	temp, w
	movwf	dat	
	bcf		dat, 7	
	movlw	0x60				; digit 0 address
	movwf	dat+1
	call	write_MAX6950
	return

delay							; a delay for del milliseconds
	movlw 	200
	
	sublw	1					; this loop takes 5us*200 = 1ms
	sublw	0					; for PIC12F675 @ 4 Mhz
	btfss	STATUS, Z
	 goto 	$-3

	decfsz	del, f
	 goto 	delay
	return

 END