;Control box for the Hewlwett-Packard 8496G Attenuator /0 - 11 dB / 0 -110 dB
;ASM code written by SM6PGP - Hannes Illipe - 20120203
;Attenuator counts 4 + 4 + 2 + 1 = 11, 8 dB = "1100",  11 dB = "1111"

#include	<p16F690.inc> 
		__config (_INTRC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _BOR_OFF & _IESO_OFF & _FCMEN_OFF)
		

ByteAddr	set 0x20		 ;user RAM starts here

BYTE	    MACRO	ByteName
ByteName	EQU		ByteAddr
ByteAddr	SET		ByteAddr+1
			ENDM


		BYTE	TMP1		;temporary register no 1
		BYTE 	TMP2 		;temporary register no 2
        BYTE	ATTEN		;attenuator value
							;
	   ;Reset vector
		org		0x0000
		goto    Start
							;
TABLE	addwf 	PCL,1		;W = offset
		retlw	0xCF		;Table for output to LED display on portC
		retlw	0x03		;Bit0 = seg C
		retlw	0xD6		;Bit1 = seg B
		retlw	0x97		;Bit2 = seg A
		retlw	0x1B		;Bit3 = seg F
		retlw	0x9D		;Bit4 = seg G
		retlw	0xD9		;Bit5 = seg B & C ( "1" on next digit)
		retlw	0x07		;Bit6 = seg E
		retlw	0x10		;Bit7 = seg D
		retlw	0x10
		retlw	0x10
		retlw	0x10
		retlw	0xDF
		retlw	0x1F
		retlw	0xEF
		retlw	0x23
Start						;initialize port A
		bcf		STATUS,RP0	;bank 0
		bcf		STATUS,RP1	;	
		clrf	PORTA		;init port A
		bsf		STATUS,RP1	;bank 2
	    clrf	ANSEL		;digital i/o
		bsf		STATUS,RP0	;bank 1
		bcf		STATUS,RP1	;
		movlw	0x3F		;set RA0,RA1,RA2,RA3,RA4 and RA5 as inputs 
		movwf	TRISA		;
		bcf		STATUS, RP0 ;bank 0
;---------------------------------------------------------------
							;Initialize port B
		clrf	PORTB		;init port B
		bsf		STATUS,RP0	;bank 1
		movlw	00h			;set RB4,RB5,RB6,RB7 as outputs
		movwf	TRISB
		bcf	 	STATUS,RP0	;bank 0
;---------------------------------------------------------------
							;initialize port C
		clrf	PORTC		;init port C
		bsf		STATUS,RP1	;bank 2
		clrf	ANSEL		;digital i/o
		bsf	 	STATUS,RP0	;bank 1
		bcf		STATUS,RP1	;
		movlw	00h			;set RC0-R7 as outputs - controlling the 7 segment LED display
		movwf	TRISC		;
		bcf		STATUS,RP0	;bank 0

;----------------------------------------------------------------
		movlw	0Fh			; preset ATTEN to max attenuation
		movwf	ATTEN
		swapf	ATTEN,0		; write to portB
		movwf	PORTB		; attenuator should now be initialized to max atten.
		goto	Loop
;
;sub----1ms delay -----------------------------------------------
;
del_1k	movwf	TMP1
del_1	movlw	0xFF		;if loaded with FF gives approx 1ms delay with current clock setup
		movwf	TMP2
del_2	nop
		decfsz	TMP2		;inner loop
		goto	del_2
		decfsz	TMP1		;outer loop
		goto	del_1
		return
;
;sub----UP-button-----------------------------------------------------------------
;
upbttn	movlw	0x0F
		call	del_1k		;wait 16 ms
		btfsc	PORTA,5
		goto	upbttn		;button still pressed, wait until release
		movlw	0x0F
		call 	del_1k
		btfsc	PORTA,5
		goto	upbttn
;
		incf	ATTEN,1		;new atten-value
		btfsc	ATTEN,4		;check if we have overflow - if bit 4 is set then dec back to 00001111		
		decf	ATTEN,1 
		btfsc	ATTEN,3	    ;if bit 3 is set then set bit 2, 4 + 4 dB attenuation to get 8 dB
		bsf		ATTEN,2
		swapf	ATTEN,0		;prepare writing to portB - put data in high nibble
		movwf	PORTB		;write to portB	
		return
;
;sub----DWN-button----------------------------------------------------------------
;
loadatt	movlw	0x07
		movwf	ATTEN
		return
;---------------------------------------------------------------------------------
dwnbttn	movlw	0x0F
		call	del_1k		;wait 16 ms
		btfsc	PORTA,4
		goto	dwnbttn		;button still pressed, wait until release
		movlw	0x0F
		call 	del_1k
		btfsc	PORTA,4
		goto	dwnbttn
;	
		decf 	ATTEN,1		;new atten-value
		btfsc	ATTEN,4		;check if we have underflow (1111 1111) - if bit 4 is set then inc back to 00000000		
		incf	ATTEN,1 
		movlw	0x0B		; load W with 00001011 to find this combination
		subwf	ATTEN,0
		btfsc	STATUS,2	;check if zero - then load ATTEN with 00000111
		call	loadatt
		swapf	ATTEN,0		;prepare writing to portB - put data in high nibble
		movwf	PORTB		;write to portB
		return
;
;-------------------------------------------------------------------------------------------
;
Loop	movf	ATTEN,0	 	
		call 	TABLE
	 	movwf 	PORTC		;write table value coresponding to portA data into portC
		btfsc	PORTA,5		;is up-button pressed ?
		call	upbttn		;jump to up-button subroutine
		btfsc	PORTA,4		;is dwn-button pressed ?
		call	dwnbttn		;jump to dwn-button subroutine
		goto	Loop		;repeat forever
		end
;
;-------------------------------------------------------------------------------------------