	LIST P=16f877, ;F=INHX8M
;	ERRORLEVEL  2
	__CONFIG _CP_OFF & _WDT_OFF &_PWRTE_ON & _XT_OSC 

;=============================================================================
; This is program for control preamplifire on SSM2163 and SSM2160 by PIC16F877
; with 4 butons (POWER, SELECT, PLUS and MINUS) and LCD display.
; I START IT FROM LCD ROUTINE , WHICH GET FROM Internet, all other writen by
; myself. Dmitry Khartsy. february 2003
;
; Fosc		= 4MHz
; Cycle_time	= 1/Fosc / 4
;		= 1/(4*10^6) / 4
;		= 1uSec
;=============================================================================

	include <D:\Program Files\MPLAB IDE\MCHIP_Tools\P16f877.inc>
	;include <C:\Program Files\MPLAB IDE\MCHIP_Tools\P16f877.inc>

;=============================================================================
; Equates, I/O, vars
;=============================================================================
RESET_V		EQU	0x0000		; Address of RESET Vector
ISR_V		EQU	0x0004		; Address of Interrupt Vector
OSC_FREQ	EQU	D'4000000'	; Oscillator Frequency is 4 MHz
;=============================================================================
LCD_DATA		EQU	PORTD	; LCD data lines interface
LCD_DATA_TRIS	EQU	TRISD	;
LCD_CTRL		EQU	PORTA	; LCD control lines interface
SPI_CTRL		EQU	PORTC	; SPI interface
SPI_CTRL_TRIS	EQU	TRISC	;
SPI_DATA		EQU	SSPBUF	; SPI data bufer

; PORTA bits
SEL_BTN			EQU 5		; Input for SELECT buton pin 7
PLUS_BTN		EQU 4		; Input for PLUS buton pin 6
MINS_BTN		EQU 3		; Input for MINUS buton pin 5
LCD_E			EQU	2		; LCD Enable control line pin 4
LCD_RW			EQU	1		; LCD Read/Write control line pin 3
LCD_RS			EQU	0		; LCD Register-Select control line pin 2

; PORTC bits
WR_2163			EQU	7		; SSM2163 SELECT PIN pin 26
LCD_BCKLGHT		EQU	6		; LCD backlight enable pin 17
SPI_DTO			EQU	5		; SPI DATA OUT pin 24
WR_2160			EQU	4		; SSM2160 SELECT PIN pin 23
SPI_CK			EQU	3		; SPI CLOCK OUT pin 18
ANALOG_PWR		EQU	2		; Analog power suply control pin 25

; misc.
;=========== its all temporary and service used RAM ==========================
LCD_TEMP		EQU	0x020	; LCD subroutines internal use
TMP_VALUE		EQU 0x021	; Temporary value for ANALOG control
HUNDREDS		EQU 0x022	; Register used for decimal hundreds display
DEC_ONES		EQU 0x023	; Register used for decimal tens and ones display
DELAY			equ	0x024	; Used in DELAYxxx routines
X_DELAY			equ	0x025	; Used in X_DELAYxxx routines
MODE_REG		EQU 0x026	; value - parameter what to control
TMP_SPI_CTRL	EQU 0x027	; value - what chip to ctrl SSM2163(1) or SSM2160(0)
PLUS_PRESD		EQU 0x028	; Was pressed button PLUS (1) or not (0)
MNS_PRESD		EQU 0x029	; Was pressed button MINUS (1) or not (0)
SPI_FIRST_BYTE	EQU 0x02A	; First Byte to send to SPI port
SPI_SECOND_BYTE	EQU 0x02B	; Second Byte to send to SPI port
PWR_STATE		EQU	0x02C	; Power for analog ON (1) or not (0)
LCDPOS			EQU	0x02D	; Position of character on LCD string
EE_ADR			EQU 0x02E	; Temporary store adress for EEPROM read/write
EE_DATA			EQU 0x02F	; Temporary store data for EEPROM read/write
;============its registers store values of settings for analog part  =========
VOLUME			EQU 0x030	; Value of VOLUME level
TEMBR_BASS		EQU 0x031	; Value of BASS level
TEMBR_MID		EQU 0x032	; Value of MIDDLE level
TEMBR_HI		EQU 0x033	; Value of HIGH level
INPUT			EQU 0x034	; Value (number)of SELECTED INPUT (1~4)
INP_MODE1		EQU 0x035	; Value equal of mode (Stereo/Mono/etc.) for INPUT 1
INP_MODE2		EQU 0x036	; Value equal of mode (Stereo/Mono/etc.) for INPUT 2
INP_MODE3		EQU 0x037	; Value equal of mode (Stereo/Mono/etc.) for INPUT 3
INP_MODE4		EQU 0x038	; Value equal of mode (Stereo/Mono/etc.) for INPUT 4
INPUT_LVL1		EQU 0x039	; Value of attenuator level for INPUT 1
INPUT_LVL2		EQU 0x03A	; Value of attenuator level for INPUT 2
INPUT_LVL3		EQU 0x03B	; Value of attenuator level for INPUT 3
INPUT_LVL4		EQU 0x03C	; Value of attenuator level for INPUT 4
TEMP_MODE		EQU 0x03D	;
TEMP_LVL		EQU 0x03E	;
;=============================================================================
; Program start
;=============================================================================
	ORG	RESET_V			; RESET vector location
RESET	
		CALL	PORT_INIT
		CALL	LCDINIT
		GOTO	GO_TO_SLEEP

;=============================================================================
; This is the Periperal Interrupt routine. Should NOT get here
;=============================================================================
	ORG	ISR_V			; Interrupt vector location
INTERRUPT	
		NOP
		CALL	BANK_0
		CLRF	INTCON
		MOVF	PWR_STATE,F
		BTFSC	STATUS,Z 
		GOTO	WRITE_AND_SLEEP
		GOTO    START
;=============================================================================
; Initialize processor registers
;=============================================================================
START							; Amplifire start (MASTER POWER ON)
		CALL	BCLGHT_10SEC
		CLRF	PWR_STATE
;=============================================================================
; Switch ON power suply for analog part of amplifire
;=============================================================================
		BSF		PORTC,ANALOG_PWR
		MOVLW	D'30'
		MOVWF	TMP_VALUE		; 
		CLRF	VOLUME			; 
ON_DELAY
		CALL	VOLUME_SET		; 
		CALL	DELAYMAX		; 
		DECFSZ	TMP_VALUE, F	; 
		GOTO	ON_DELAY		; 

;=============================================================================		
; FROM  HERE WE START INITIALISATION OF ANALOG RART OF AMPLIFIRE. First, we 
; seting master volume of SSM2160 to -127 dB (master volume value 0x00h)FOR 
; MUTE OUTPUT OF AMPLIFIRE  UNTILL ALL PARAMETERS WILL SET. Then we loading
; from EEPROM all values, stored at last switching off,  then set values to 
; analog chips, and at last - setting correct volume.
;=============================================================================
		CALL	SPI_WRITE_BIT_1	; Set to "HIGH" bits WRITE of SPI ports
		CALL	READ_EEPROM	; read from EEPROM all values
		CALL	BASS_SET	; 	  Setting
		CALL	MIDDLE_SET	;	  values of
		CALL	HIGH_SET	;	  tone controls
		CALL	INPUT_SET	; Setting selected input, mode and attenuation
		CALL	VOLUME_SET	; Setting correct volume
;		CALL	BCLGHT_10SEC;
;=============================================================================
; Here main loop of program. We are checking condition of three pins of 
; Port A to which connected three buttons - SELECT, PLUS, MINUS. 
;=============================================================================
RET_FROM_MODE_CHECK
		MOVLW	0x01		; Inital value of MODE_REG (ctrl Volume) 
		MOVWF	MODE_REG	;
		CALL	DISPLAY_STBY
		CLRW
LOOP
		CALL	X_DELAY500
		BTFSS	LCD_CTRL, SEL_BTN
		GOTO	SEL_PRESSED
		BTFSS	LCD_CTRL, PLUS_BTN
		GOTO	PLUS_PRESSED
		BTFSS	LCD_CTRL, MINS_BTN
		GOTO	MNS_PRESSED	;
		BTFSC	PIR1,TMR1IF	;
		CALL	BCLGHT_OFF	;
		CLRF	LCD_CTRL	; 
		GOTO	LOOP		; Stay here forever

;*****************************************************************************
; LCD Module Subroutines
;*****************************************************************************
PORT_INIT
		CLRF	STATUS		; Do initialization, Select bank 0
		CLRF	INTCON		; Clear int-flags, Disable interrupts
		CLRF	PCLATH		; Keep in lower 2KByte
		CLRF	PORTA		; ALL PORT output should output Low.
		CLRF	PORTB
		CLRF	PORTC
		CLRF	PORTD
		CLRF	PORTE
		BCF		ADCON0,ADON
		CALL	BANK_1		; Select bank 1
		MOVLW	0x06
		MOVWF	ADCON1
		MOVLW	0x038		; RA2-0 outputs, RA4-3 inputs
		MOVWF	TRISA
		MOVLW	b'00001001'	; RB7-4,2,1 outputs, RB3,RB0 - inputs
		MOVWF	TRISB
		CLRF	TRISC
		CLRF	TRISD
		CLRF	TRISE
		MOVLW	B'11110111'	;
		MOVWF	OPTION_REG	; Disable PORTB pull-ups
		CALL	BANK_0		; Select bank 0	
		CALL	SPI_ENABLE	; SPI port enabling routine
		RETURN
;=============================================================================
; What to do if pressed SELECT buton
;=============================================================================
SEL_PRESSED
		CALL	BCLGHT_10SEC
		RLF		MODE_REG,F
		GOTO	MODE_CHECK
;=============================================================================
; What to do if pressed PLUS buton
;=============================================================================
PLUS_PRESSED
		CALL	BCLGHT_10SEC
		MOVLW	0x001		;
		MOVWF	PLUS_PRESD	; Writin 1 to 
		GOTO	MODE_CHECK	;
;=============================================================================
; What to do if pressed MINUS buton
;=============================================================================
MNS_PRESSED
		CALL	BCLGHT_10SEC
		MOVLW	0x001
		MOVWF	MNS_PRESD
		GOTO	MODE_CHECK
;=============================================================================
; This procedure checking what value we will controll, display and send to
; SSM216x chips trought SPI port
;=============================================================================
MODE_CHECK
		BCF		STATUS,Z
		MOVF	MODE_REG,W
		XORLW	0x01
		BTFSC   STATUS,Z
		GOTO 	VOLUME_CTRL
		MOVF 	MODE_REG,W 
		XORLW	0x02
		BTFSC   STATUS,Z
		GOTO 	INPUT_SELECT
		MOVF 	MODE_REG,W 
		XORLW	0x04
		BTFSC   STATUS,Z
		GOTO 	BASS_CTRL
		MOVF 	MODE_REG,W
		XORLW	0x08
		BTFSC   STATUS,Z
		GOTO 	MIDLE_CTRL
		MOVF 	MODE_REG,W
		XORLW	0x10
		BTFSC   STATUS,Z
		GOTO 	HIGH_CTRL
		MOVF 	MODE_REG,W
		XORLW	0x20
		BTFSC   STATUS,Z
		GOTO 	INPUT_LEVEL
		MOVF 	MODE_REG,W
		XORLW	0x40
		BTFSC   STATUS,Z
		GOTO 	INPUT_MODE
		MOVF 	MODE_REG,W
		XORLW	0x80
		BTFSC   STATUS, Z
		GOTO 	RET_FROM_MODE_CHECK
 		RETURN
;=============================================================================
; Switch on LCD backlight lamp and start 10 sec countdown in Timer 1
;=============================================================================
; Using timer 1 for making 10 second (realy I used external
; qartz 32768 kHz, and get 16 second) pause
;=============================================================================
BCLGHT_10SEC
		CALL	BANK_0
		BSF		SPI_CTRL, LCD_BCKLGHT	;Swith ON LCD backlight
		CLRF	INTCON			; 
		CLRF	TMR1L			; Clear lower byte Timer1
		CLRF	TMR1H			; Clear higher byte Timer1
		MOVLW	B'00111111'		; Select prescaler (11) source, and start Timer1
		MOVWF	T1CON			;
		BCF		PIR1,TMR1IF		; Clear flags of interupt TMR1 in PIE1
		CALL	BANK_1
		BSF		PIE1,TMR1IE		; Enable Timer1 interupt
		CALL	BANK_0
		RETURN
;=============================================================================
; SWITCHING OFF backlight for LCD and show on LCD standby reading
;=============================================================================
BCLGHT_OFF
		CALL	BANK_0
		CLRF	T1CON			; Clear T1CON (stops and switch OFF Timer1)
		BCF		PIR1,TMR1IF		; Clear Timer1 interupt flag
		CALL	BANK_1
		BCF		PIE1,TMR1IE		; Disable Timer1 interupt
		CALL	BANK_0
		MOVLW	B'10010000'		; Enabling GIE and INTE (external interupt)
		MOVWF	INTCON			; 
		BCF		SPI_CTRL, LCD_BCKLGHT
		GOTO	RET_FROM_MODE_CHECK
;=============================================================================
; LCD Module Subroutines
;=============================================================================
;
;=============================================================================
; LCDINIT
; Initilize LC-Display Module
; Should be modified to your needs (i.e. display type, cursor on/off, etc.)
; OK
;=============================================================================
LCDINIT
		CLRF	LCD_CTRL			; ALL PORT output should output Low.
		MOVLW	0x03C				; 8-bit-interface, 2-lines
		BSF		LCD_CTRL, LCD_E		; LCD E-line High
		NOP
		BCF		LCD_CTRL, LCD_E		; LCD E-line Low
;----------------------------------------------------------------------		
		MOVLW	0x03C				; Константа для задержки
		CALL	X_DELAY500			; 30 * 0.5mS = 15mS
;----------------------------------------------------------------------
		MOVLW	0x03C				; 8-bit-interface, 2-lines
		BCF		LCD_CTRL, LCD_RW	; Set LCD in read mode
		BCF		LCD_CTRL, LCD_RS	; Set LCD in command mode
		BSF		LCD_CTRL, LCD_E		; LCD E-line High
		NOP
		BCF		LCD_CTRL, LCD_E		; LCD E-line Low
;-----------------------------------------------------------------------------	
		MOVLW	0x03C			; 8-bit-interface, 2-lines
		CALL	LCDPUTCMD
		MOVLW	0x00C			; disp.off, curs.off, no-blink
		CALL	LCDPUTCMD
		CALL	LCDCLEAR
		MOVLW	0x004			; disp.on, curs.off
		CALL	LCDPUTCMD
		MOVLW	0x006			; auto-inc (shift-cursor)
		CALL	LCDPUTCMD
		RETURN
;=============================================================================
; LCDBUSY Returns when LCD busy-flag is inactive (LOW)
;=============================================================================
LCDBUSY
		CALL	BANK_1			; Select Register page 1
		MOVLW	0x0FF			; Set PORTD for input
		MOVWF	TRISD
		CALL	BANK_0			; Select Register page 0
		BCF	LCD_CTRL, LCD_RS	; Set LCD for command mode
		BSF	LCD_CTRL, LCD_RW	; Setup to read busy flag
		BSF	LCD_CTRL, LCD_E		; LCD E-line High
		MOVF	LCD_DATA,0		; Read busy flag + DDram address
		BCF	LCD_CTRL, LCD_E		; LCD E-line Low
		ANDLW	0x80			; Check Busy flag, High = Busy
		BTFSS	STATUS, Z
		GOTO	LCDBUSY
LCDNOTBUSY	BCF	LCD_CTRL, LCD_RW
		CALL	BANK_1			; Select Register page 1
		CLRF	LCD_DATA_TRIS	; Set PORTB for output
		CALL	BANK_0			; Select Register page 0
		RETURN
;=============================================================================
; LCDCLEAR
; Clears display and returns cursor to home position (upper-left corner).
;=============================================================================
LCDCLEAR
		CLRF	LCDPOS
		CALL	LCDBUSY				; Wait for LCD to be ready
		MOVLW	0x001
		MOVWF	LCD_DATA			; Send data to LCD
		BCF		LCD_CTRL, LCD_RW	; Set LCD in read mode
		BCF		LCD_CTRL, LCD_RS	; Set LCD in command mode
		BSF		LCD_CTRL, LCD_E		; LCD E-line High
		NOP
		BCF		LCD_CTRL, LCD_E		; LCD E-line Low
		RETURN
;=============================================================================
; LCDPUTCHAR
; Sends character to LCD
; Required character must be in W
; OK
;=============================================================================
LCDPUTCHAR
		MOVWF	LCD_TEMP		; Character to be sent is in W
		MOVF	LCDPOS,W		; This checkng nessesery because of using LCD
		XORLW	0x008			; module 16 symbol X 1 line. This LCD has 
		BTFSC	STATUS,Z		; adress of 9-th symbol is 28h, and we need
		CALL	SECOND_HALF		; to switch on it manualy.
		MOVF	LCDPOS,W		;
		XORLW	0x010			;
		BTFSC	STATUS,Z		;
		CALL	LCDCLEAR		;
		CALL	LCDBUSY			; Wait for LCD to be ready
		nop
		BCF	LCD_CTRL, LCD_RW	; Set LCD in read mode
		BSF	LCD_CTRL, LCD_RS	; Set LCD in data mode
		BSF	LCD_CTRL, LCD_E		; LCD E-line High
		NOP
		MOVF	LCD_TEMP, W
		MOVWF	LCD_DATA		; Send data to LCD
		nop
		BCF	LCD_CTRL, LCD_E		; LCD E-line Low
		INCF	LCDPOS,f		; 
		RETURN
;=============================================================================
; Switch to second half of display line
;=============================================================================
SECOND_HALF
		CALL	LCDBUSY				; Wait for LCD to be ready
		MOVLW	0x0A8
		MOVWF	LCD_DATA			; Send data to LCD
		BCF		LCD_CTRL, LCD_RW	; Set LCD in read mode
		BCF		LCD_CTRL, LCD_RS	; Set LCD in command mode
		BSF		LCD_CTRL, LCD_E		; LCD E-line High
		NOP
		BCF		LCD_CTRL, LCD_E		; LCD E-line Low
		RETURN
;=============================================================================
; LCDPUTCMD
; Sends command to LCD
; Required command must be in W
; OK
;=============================================================================
LCDPUTCMD
		MOVWF	LCD_TEMP	; Command to be sent is in W
		CALL	LCDBUSY		; Wait for LCD to be ready
		BCF	LCD_CTRL, LCD_RW; Set LCD in read mode
		BCF	LCD_CTRL, LCD_RS; Set LCD in command mode
		BSF	LCD_CTRL, LCD_E	; LCD E-line High
		MOVF	LCD_TEMP, W
		MOVWF	LCD_DATA	; Send data to LCD
		NOP
		BCF	LCD_CTRL, LCD_E	; LCD E-line Low
		RETURN
;=============================================================================
; 
;
;=============================================================================
; Procedure of Volume Control (incr, decr, check for MAX and MIN values
; sending to SPI port, convert to decimal, and display to LCD
;=============================================================================
VOLUME_CTRL
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		INCF	VOLUME,F		; Inctreasing Volume
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		DECF 	VOLUME,F		; Descreasing Volume
		MOVLW 	0x0FF			;
		XORWF	VOLUME,0		; Check - is VOLUME  0
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	VOLUME			; set Volume 0
		MOVLW 	0x080			;
		XORWF	VOLUME,0		; Check - is VOLUME 128
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	VOL_MAX
		CALL	VOLUME_SET
		CALL	DISPLAY_VOLUME
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
		CALL	DELAYMAX		;
		GOTO	LOOP			; Return to main loop
VOL_MAX		
		MOVLW 	0x07F			; Seting Volume 127
		MOVWF	VOLUME
		RETURN
;=============================================================================
; Procedure of INPUT Control 
;=============================================================================
INPUT_SELECT
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		INCF	INPUT,1			; Inctreasing Input number
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		DECF 	INPUT,1			; Descreasing Input number
		MOVLW 	0x004			;
		XORWF	INPUT,0			; Check - is INPUT NUMBER 4 (more than 3)
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	INPUT			; switch to 0 (Input 1)
		MOVLW 	0x0FF			;
		XORWF	INPUT,0			; Check - is INPUT NUMBER FF (less than 0)
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	INP_SWITCH		;
		CALL	DISPLAY_INPUT	; Call routine for display selected input
		CALL	INPUT_SET		; Call routine for setting selected input
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
		CALL	DELAYMAX		; Delay
		GOTO	LOOP			; Return to main loop
INP_SWITCH
		MOVLW 	0x003			; Setting Input 4
		MOVWF	INPUT
		RETURN
;=============================================================================
; Procedure of BASS TONE Control 
;=============================================================================
BASS_CTRL
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		DECF	TEMBR_BASS,1	; Inctreasing BASS
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		INCF 	TEMBR_BASS,1	; Descreasing BASS
		MOVLW 	0x0FF			;
		XORWF	TEMBR_BASS,0	; Check - is BASS  0
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	TEMBR_BASS		; set Bass 0
		MOVLW 	0x020			;
		XORWF	TEMBR_BASS,0	; Check - is BASS 32
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	BASS_MAX
		CALL	BASS_SET
		CALL	DISPLAY_BASS
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
BASS_MAX		
		MOVLW 	0x01F			; Seting BASS 31
		MOVWF	TEMBR_BASS
		RETURN
;=============================================================================
; Procedure of HIGH TONE Control 
;=============================================================================
HIGH_CTRL
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		DECF	TEMBR_HI,1		; Inctreasing BASS
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		INCF 	TEMBR_HI,1		; Descreasing BASS
		MOVLW 	0x0FF			;
		XORWF	TEMBR_HI,0		; Check - is HIGH 0
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	TEMBR_HI		; set Tembr_High 0
		MOVLW 	0x020			;
		XORWF	TEMBR_HI,0		; Check - is BASS 32
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	HIGH_MAX
		CALL	HIGH_SET
		CALL	DISPLAY_HIGH
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
HIGH_MAX		
		MOVLW 	0x01F			; Seting BASS 31
		MOVWF	TEMBR_HI
		RETURN
;=============================================================================
; Procedure of MIDDLE TONE Control 
;=============================================================================
MIDLE_CTRL
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		DECF	TEMBR_MID,1		; Inctreasing BASS
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		INCF 	TEMBR_MID,1		; Descreasing BASS
		MOVLW 	0x0FF			;
		XORWF	TEMBR_MID,0		; Check - is BASS  0
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	TEMBR_MID		; set Volume 0
		MOVLW 	0x020			;
		XORWF	TEMBR_MID,0		; Check - is BASS 32
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	MID_MAX
		CALL	MIDDLE_SET
		CALL	DISPLAY_MIDDLE
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
MID_MAX		
		MOVLW 	0x01F			; Seting BASS 31
		MOVWF	TEMBR_MID
		RETURN
;=============================================================================
; Procedure of INPUT LEVEL Control 
;=============================================================================
INPUT_LEVEL
		CALL	INPUT_DETERMINE
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		INCF	TEMP_LVL,F		; Inctreasing Attenuator
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		DECF 	TEMP_LVL,F		; Descreasing Attenuator
		MOVLW 	0x0FF			;
		XORWF	TEMP_LVL,0		; Check - is Attenuator lower than 0
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	TEMP_LVL		; set Attenuator to 0
		MOVLW 	0x040			;
		XORWF	TEMP_LVL,0		; Check - is Attenuator 64
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	ATT_MAX
		CALL	DISPLAY_ATTENUATOR
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
;=============================================================================
; HERE we need write back value of mode from temporary location to register
; corresponding to selected input
;=============================================================================
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x00			; is it input 1 ?
		BTFSC	STATUS,Z
		GOTO	ATT_01
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x01			; is it input 2 ?
		BTFSC	STATUS,Z
		GOTO	ATT_02
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x02			; is it input 3 ?
		BTFSC	STATUS,Z
		GOTO	ATT_03
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x03			; is it input 4 ?
		BTFSC	STATUS,Z
		GOTO	ATT_04
ATT_01
		MOVF	TEMP_LVL,W
		MOVWF	INPUT_LVL1
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
ATT_02
		MOVF	TEMP_LVL,W
		MOVWF	INPUT_LVL2
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
ATT_03
		MOVF	TEMP_LVL,W
		MOVWF	INPUT_LVL3
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
ATT_04		
		MOVF	TEMP_LVL,W
		MOVWF	INPUT_LVL4
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX	;
		GOTO	LOOP			; Return to main loop
ATT_MAX		
		MOVLW 	0x03F			; Seting Attenuator 63
		MOVWF	TEMP_LVL
		RETURN
;=============================================================================
INPUT_DETERMINE
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x00			; is it input 1 ?
		BTFSC	STATUS,Z
		GOTO	ATT_1
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x01			; is it input 2 ?
		BTFSC	STATUS,Z
		GOTO	ATT_2
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x02			; is it input 3 ?
		BTFSC	STATUS,Z
		GOTO	ATT_3
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x03			; is it input 4 ?
		BTFSC	STATUS,Z
		GOTO	ATT_4
ATT_1
		MOVF	INPUT_LVL1,W
		MOVWF	TEMP_LVL
		MOVF	INP_MODE1,W
		MOVWF	TEMP_MODE
		RETURN
ATT_2
		MOVF	INPUT_LVL2,W
		MOVWF	TEMP_LVL
		MOVF	INP_MODE2,W
		MOVWF	TEMP_MODE
		RETURN
ATT_3
		MOVF	INPUT_LVL3,W
		MOVWF	TEMP_LVL
		MOVF	INP_MODE3,W
		MOVWF	TEMP_MODE
		RETURN
ATT_4		
		MOVF	INPUT_LVL4,W
		MOVWF	TEMP_LVL
		MOVF	INP_MODE4,W
		MOVWF	TEMP_MODE
		RETURN
;=============================================================================
; Procedure of INPUT MODE Control. Values of Input mode for each inpus stored
; in different RAM registers. For Input mode coresponding values is:
; 00 - Stereo
; 01 - Mono (both cannels)
; 02 - Left (mono - on both outputs coming signal from left input)
; 03 - Right (mono - on both outputs coming signal from right input)
;=============================================================================
; First, we checking, which input is selected, and writing value of mode from
; corresponding register to temporary location
;=============================================================================
INPUT_MODE
		CALL	INPUT_DETERMINE
		MOVLW 	0x001			;
		XORWF	PLUS_PRESD,0	; Check - is Plus pressed
		BTFSC   STATUS, Z		; trought Zero flag
		INCF	TEMP_MODE,1		; Inctreasing MODE number
		MOVLW 	0x001			;
		XORWF	MNS_PRESD,0		; Check - is Minus Preased
		BTFSC   STATUS, Z		; trought Zero flag
		DECF 	TEMP_MODE,1		; Descreasing MODE number
		MOVLW 	0x004			;
		XORWF	TEMP_MODE,0		; Check - is INPUT MODE 4 (more than 03)
		BTFSC   STATUS, Z		; trought Zero flag
		CLRF	TEMP_MODE		; switch to 0 (Input mode 01)
		MOVLW 	0x0FF			;
		XORWF	TEMP_MODE,0		; Check - is INPUT MODE FF (less than 0)
		BTFSC   STATUS, Z		; trought Zero flag
		CALL	MODE_CYCLE		;
		CALL	DISPLAY_MODE	; Call routine for display selected input
		CLRF	PLUS_PRESD		; Writin 0 to 
		CLRF	MNS_PRESD		; Writin 0 to 
;=============================================================================
; HERE we need write back value of mode from temporary location to register
; corresponding to selected input
;=============================================================================
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x00			; is it input 1 ?
		BTFSC	STATUS,Z
		GOTO	MODE_01
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x01			; is it input 2 ?
		BTFSC	STATUS,Z
		GOTO	MODE_02
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x02			; is it input 3 ?
		BTFSC	STATUS,Z
		GOTO	MODE_03
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x03			; is it input 4 ?
		BTFSC	STATUS,Z
		GOTO	MODE_04
MODE_01
		MOVF	TEMP_MODE,W
		MOVWF	INP_MODE1
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX		;
		GOTO	LOOP			; Return to main loop
MODE_02
		MOVF	TEMP_MODE,W
		MOVWF	INP_MODE2
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX		;
		GOTO	LOOP			; Return to main loop
MODE_03
		MOVF	TEMP_MODE,W
		MOVWF	INP_MODE3
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX		;
		GOTO	LOOP			; Return to main loop
MODE_04		
		MOVF	TEMP_MODE,W
		MOVWF	INP_MODE4
		CALL	INPUT_SET_SHORT	; Call routine for setting selected input
		CALL	DELAYMAX		;
		GOTO	LOOP			; Return to main loop
		
MODE_CYCLE
		MOVLW 	0x003			; Setting Input MODE 03
		MOVWF	TEMP_MODE
		RETURN
;=============================================================================
; There are display messages for different modes. Some of them collected from
; part of other.  This routines include (when nessesery) procedure of decimal
; convert. 
;=============================================================================
; Send to LCD "hello"
;=============================================================================
HELLO
		CALL	LCDCLEAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x0A8		; Symbol "P"
		CALL	LCDPUTCHAR
		MOVLW	0x050		; Symbol "R"
		CALL	LCDPUTCHAR
		MOVLW	0x0A5		; Symbol "I"
		CALL	LCDPUTCHAR
		MOVLW	'B'			; Symbol "V"
		CALL	LCDPUTCHAR
		MOVLW	0x045		; Symbol "e"
		CALL	LCDPUTCHAR
		MOVLW	0x054		; Symbol "T"
		CALL	LCDPUTCHAR
		RETURN
;============================================================================
; Send to LCD "Gromkostj -XXXdB"
;============================================================================
DISPLAY_VOLUME
		CALL	LCDCLEAR
		CALL	GROMK_SHOW
		MOVLW	0x06F		; Symbol "o"
		CALL	LCDPUTCHAR
		MOVLW	0x063		; Symbol "s"
		CALL	LCDPUTCHAR
		MOVLW	0x0BF		; Symbol "t"
		CALL	LCDPUTCHAR
		MOVLW	0x0C4		; Symbol "j"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	MINUS_SHOW
		CALL	VOLUME_SHOW
		CALL	DB_SHOW
		RETURN		
;=============================================================================
; Dislay number of selected input
;=============================================================================		
DISPLAY_INPUT		
		CALL	LCDCLEAR
		CALL	VHOD_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	INP_NUMBER_SHOW
		RETURN
;=============================================================================
; Dislay value of BASS tone
;=============================================================================		
DISPLAY_BASS		
		CALL	LCDCLEAR
		CALL	TEMBR_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x048		; Symbol "N"
		CALL	LCDPUTCHAR
		MOVLW	0x0AB		; Symbol "ch"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVF	TEMBR_BASS,W; 
		CALL	TEMBR_CONVERT
		CALL	DIGIT_DISPLAY
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	DB_SHOW	
		RETURN

;=============================================================================
; Dislay value of HIGH tone
;=============================================================================		
DISPLAY_HIGH		
		CALL	LCDCLEAR
		CALL	TEMBR_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x042		; Symbol "B"
		CALL	LCDPUTCHAR
		MOVLW	0x0AB		; Symbol "ch"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVF	TEMBR_HI,W; 
		CALL	TEMBR_CONVERT
		CALL	DIGIT_DISPLAY
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	DB_SHOW	
		RETURN
;=============================================================================
; Dislay value of MIDDLE tone
;=============================================================================		
DISPLAY_MIDDLE		
		CALL	LCDCLEAR
		CALL	TEMBR_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x043		; Symbol "C"
		CALL	LCDPUTCHAR
		MOVLW	0x0AB		; Symbol "ch"
		CALL	LCDPUTCHAR
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVF	TEMBR_MID,W	; 
		CALL	TEMBR_CONVERT
		CALL	DIGIT_DISPLAY
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	DB_SHOW	
		RETURN
;=============================================================================
; Dislay selected mode (Stereo, Mono, Left, Right)
;=============================================================================		
DISPLAY_MODE
		CALL	LCDCLEAR
		CALL	VHOD_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	INP_NUMBER_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	MINUS_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVF	TEMP_MODE,W
		XORLW	0x00
		BTFSC	STATUS,Z
		CALL	STEREO_SHOW
		MOVF	TEMP_MODE,W
		XORLW	0x01
		BTFSC	STATUS,Z
		CALL	MONO_SHOW
		MOVF	TEMP_MODE,W
		XORLW	0x02
		BTFSC	STATUS,Z
		CALL	LEFT_SHOW
		MOVF	TEMP_MODE,W
		XORLW	0x03
		BTFSC	STATUS,Z
		CALL	RIGHT_SHOW
		RETURN		
;=============================================================================
; Dislay value of attenuator for selected input
;=============================================================================		
DISPLAY_ATTENUATOR
		CALL	LCDCLEAR
		MOVLW	'O'
		CALL	LCDPUTCHAR
		MOVLW	'c'
		CALL	LCDPUTCHAR
		MOVLW	0x0BB
		CALL	LCDPUTCHAR
		MOVLW	'a'
		CALL	LCDPUTCHAR
		MOVLW	0x0B2
		CALL	LCDPUTCHAR
		MOVLW	0x0BB
		CALL	LCDPUTCHAR
		CALL	DOT_SHOW
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	MINUS_SHOW		
		MOVF	TEMP_LVL,W
		MOVWF	TMP_VALUE	;
		CALL	DIGIT_DISPLAY
		MOVLW	0x020		; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	DB_SHOW
		RETURN		
;=============================================================================
; This is STBY display: "Vhod 1 Gromk.-xxx"
;=============================================================================
DISPLAY_STBY
		CALL	LCDCLEAR
		MOVLW	'B'				; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	'x'				; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	DOT_SHOW
		CALL	INP_NUMBER_SHOW
		MOVLW	0x020			; Symbol "Space"
		CALL	LCDPUTCHAR
		MOVLW	0x020			; Symbol "Space"
		CALL	LCDPUTCHAR
		CALL	GROMK_SHOW
		CALL	DOT_SHOW
		CALL	MINUS_SHOW
		CALL	VOLUME_SHOW
		RETURN
;==========================================================================
;
;==========================================================================
DB_SHOW
		MOVLW	0x0E3		; Symbol "d"
		CALL	LCDPUTCHAR
		MOVLW	0x0A0		; Symbol "B"
		CALL	LCDPUTCHAR
		RETURN
TEMBR_SHOW
		MOVLW	0x054		; Symbol "T"
		CALL	LCDPUTCHAR
		MOVLW	0x065		; Symbol "e"
		CALL	LCDPUTCHAR
		MOVLW	0x0BC		; Symbol "m"
		CALL	LCDPUTCHAR
		MOVLW	0x0B2		; Symbol "b"
		CALL	LCDPUTCHAR
		MOVLW	0x070		; Symbol "r"
		CALL	LCDPUTCHAR
		RETURN
STEREO_SHOW
		MOVLW	'C'			; Symbol "S"
		CALL	LCDPUTCHAR
		MOVLW	'T'			; Symbol "T"
		CALL	LCDPUTCHAR
		MOVLW	'E'			; Symbol "E"
		CALL	LCDPUTCHAR
		MOVLW	'P'			; Symbol "R"
		CALL	LCDPUTCHAR
		MOVLW	'E'			; Symbol "E"
		CALL	LCDPUTCHAR
		MOVLW	'O'			; Symbol "O"
		CALL	LCDPUTCHAR
		RETURN
MONO_SHOW
		MOVLW	'M'			; Symbol "M"
		CALL	LCDPUTCHAR
		MOVLW	'O'			; Symbol "O"
		CALL	LCDPUTCHAR
		MOVLW	'H'			; Symbol "N"
		CALL	LCDPUTCHAR
		MOVLW	'O'			; Symbol "O"
		CALL	LCDPUTCHAR
		RETURN
LEFT_SHOW
		MOVLW	0xA7		; Symbol "L"
		CALL	LCDPUTCHAR
		MOVLW	'E'			; Symbol "E"
		CALL	LCDPUTCHAR
		MOVLW	'B'			; Symbol "V"
		CALL	LCDPUTCHAR
		MOVLW	0xAE		; Symbol "Y"
		CALL	LCDPUTCHAR
		MOVLW	0xA6		; Symbol "J"
		CALL	LCDPUTCHAR
		RETURN
RIGHT_SHOW
		MOVLW	0xA8		; Symbol "P"
		CALL	LCDPUTCHAR
		MOVLW	'P'			; Symbol "R"
		CALL	LCDPUTCHAR
		MOVLW	'A'			; Symbol "A"
		CALL	LCDPUTCHAR
		MOVLW	'B'			; Symbol "V"
		CALL	LCDPUTCHAR
		MOVLW	0xAE		; Symbol "Y"
		CALL	LCDPUTCHAR
		MOVLW	0xA6		; Symbol "J"
		CALL	LCDPUTCHAR
		RETURN

INP_NUMBER_SHOW
		MOVF	INPUT,W		; Takin from RAM number OF Selected Input
		ADDLW	0x001		; Change range 0~3 to 1~4
		ADDLW	0x030		; Shift digit to number on LCD codepage
		CALL LCDPUTCHAR		; calling routine for output digit to LCD
		RETURN
MINUS_SHOW
		MOVLW	0x02D		; Symbol "-"
		CALL	LCDPUTCHAR
		RETURN
PLUS_SHOW
		MOVLW	0x02B		; Symbol "+"
		CALL	LCDPUTCHAR
		RETURN
DOT_SHOW	
		MOVLW	0x02E		; Symbol "."
		CALL	LCDPUTCHAR
		RETURN
VHOD_SHOW
		MOVLW	0x042		; Symbol "V"
		CALL	LCDPUTCHAR
		MOVLW	'x'			; Symbol "h"
		CALL	LCDPUTCHAR
		MOVLW	0x06F		; Symbol "o"
		CALL	LCDPUTCHAR
		MOVLW	0x0E3		; Symbol "d"
		CALL	LCDPUTCHAR
		RETURN
VOLUME_SHOW
		MOVF	VOLUME,W
		XORLW	0X0FF		;  convert 0 => 127 127=>0
		ANDLW	B'01111111'	;
		MOVWF	TMP_VALUE	;
		CALL	DIGIT_DISPLAY
		RETURN
GROMK_SHOW
		MOVLW	0x0A1		; Symbol "G"
		CALL	LCDPUTCHAR
		MOVLW	0x070		; Symbol "r"
		CALL	LCDPUTCHAR
		MOVLW	0x06F		; Symbol "o"
		CALL	LCDPUTCHAR
		MOVLW	0x0BC		; Symbol "m"
		CALL	LCDPUTCHAR
		MOVLW	0x0BA		; Symbol "k"
		CALL	LCDPUTCHAR
		RETURN
;=============================================================================
; Converting tembr value from 0~32 to -15 ~ +15 and show "+" or "-"
;=============================================================================		
TEMBR_CONVERT
		BCF		STATUS,C
		BCF		STATUS,DC
		ADDLW	0x0EF
		BTFSS	STATUS,C
		GOTO	LOWER_ZERRO
		BTFSC	STATUS,DC
		ADDLW	0x001
		ANDLW	B'00011111'
		MOVWF	TMP_VALUE
		CALL	MINUS_SHOW
		RETURN
LOWER_ZERRO		
		XORLW	0X0FF
		ANDLW	B'00011111'
		MOVWF	TMP_VALUE
		CALL	PLUS_SHOW
		RETURN
;==========================================================================
; Output decimal digits to LCD with all left "0" skiping
;==========================================================================
DIGIT_DISPLAY
		CALL	BCD_CONVERT	; Conwerting placed in W digit from HEX to decimal
		MOVF	HUNDREDS,0	; Copy HUNDREDS to W
		BTFSC	STATUS, Z	; If in W not 0, skip next string
		GOTO 	DECIMAL
		ADDLW	0x030		; Shift digit to number on LCD codepage
		CALL LCDPUTCHAR		; calling routine for output digit to LCD
		GOTO	DEC_X0X
DECIMAL
		CLRW				; Clear W
		SWAPF	DEC_ONES,0	; Swap halfbytes of DEC_ONES and put it in W
		ANDLW	B'00001111'	; Clear first halfbyte of W
		BTFSC	STATUS, Z	; If in W not 0, skip next string
		GOTO ONES
DEC_X0X		
		SWAPF	DEC_ONES,0	; Swap halfbytes of DEC_ONES and put it in W
		ANDLW	B'00001111'	; Clear first halfbyte of W
		ADDLW	0x030		; Shift digit to number on LCD codepage
		CALL LCDPUTCHAR		; calling routine for output digit to LCD
ONES	CLRW				; Clear W
		ADDWF	DEC_ONES,0	; Copy DEC_ONES to W
		ANDLW	B'00001111'	; Clear first halfbyte of W
		ADDLW	0x030		; Shift digit to number on LCD codepage
		CALL LCDPUTCHAR		; calling routine for output digit to LCD
		RETURN
;==============================================================================
; Procedure to go to sleep
;==============================================================================
WRITE_AND_SLEEP
		CALL	EEPROM_WRITE
GO_TO_SLEEP
		CALL	BCLGHT_10SEC
		CALL	HELLO
;=============================================================================
; Switch OFF power suply for analog
;=============================================================================
		BCF		SPI_CTRL, ANALOG_PWR	; Clear to 0 analog power control pin
		CLRF	VOLUME			; 
		CALL	VOLUME_SET		; 
		BTFSS	PIR1,TMR1IF	;
		GOTO	$-1	;
		CLRF	INTCON
		CLRF	PORTC		; Clear port C
		CALL	BANK_1
		CLRF	PIE1		; Disable all peripherial interupts
		CALL	BANK_0
		MOVLW	B'11010000'	; Enabling GIE and INTE (external interupt)
		MOVWF	INTCON		; 
		MOVLW	0x001
		MOVWF	PWR_STATE	; Setting mark of power state of system
		SLEEP
		NOP
;=============================================================================
; Here two procedures for read all settings from EEPROM at switch ON system
; and write all settings to EEPROM when system switch OFF
;=============================================================================
; This routine reads all settings saved at EEPROM to RAM
;=============================================================================
READ_EEPROM
	MOVLW	0x00		; Seting adress 00 of first byte of EEPROM
	CALL	READING
	MOVWF	VOLUME		; Writing data to RAM
;====================================== INPUT ================================
	MOVLW	0x01		; Seting adress 01 of second byte of EEPROM
	CALL	READING
	MOVWF	INPUT		; Writing data to RAM
;======================================= BASS ================================
	MOVLW	0x02		; Seting adress 02 of third byte of EEPROM
	CALL	READING
	MOVWF	TEMBR_BASS	; Writing data to RAM
;======================================= MIDDLE===============================
	MOVLW	0x03		; Seting adress 03 of fourth byte of EEPROM
	CALL	READING
	MOVWF	TEMBR_MID	; Writing data to RAM
;========================================= HIGH ==============================
	MOVLW	0x04		; Seting adress 04 of fifth byte of EEPROM
	CALL	READING
	MOVWF	TEMBR_HI	; Writing data to RAM
;======================================= INPUT LEVEL 1 =======================
	MOVLW	0x05		; Seting adress 05 of SIXTH byte of EEPROM
	CALL	READING
	MOVWF	INPUT_LVL1	; Writing data to RAM
;======================================= INPUT LEVEL 2 =======================
	MOVLW	0x06		; Seting adress 06 of seventh byte of EEPROM
	CALL	READING
	MOVWF	INPUT_LVL2	; Writing data to RAM
;======================================= INPUT LEVEL 3 =======================
	MOVLW	0x07		; Seting adress 07 of eighth byte of EEPROM
	CALL	READING
	MOVWF	INPUT_LVL3	; Writing data to RAM
;======================================= INPUT LEVEL 4========================
	MOVLW	0x08		; Seting adress 08 of ninth byte of EEPROM
	CALL	READING
	MOVWF	INPUT_LVL4	; Writing data to RAM
;======================================= INPUT MODE 1 ========================
	MOVLW	0x09		; Seting adress 09 of tenth byte of EEPROM
	CALL	READING
	MOVWF	INP_MODE1	; Writing data to RAM
;======================================= INPUT MODE 2 ========================
	MOVLW	0x0A		; Seting adress 0A of eleven byte of EEPROM
	CALL	READING
	MOVWF	INP_MODE2	; Writing data to RAM
;======================================= INPUT MODE 3 ========================
	MOVLW	0x0B		; Seting adress 0B of twelwe byte of EEPROM
	CALL	READING
	MOVWF	INP_MODE3	; Writing data to RAM
;======================================= INPUT MODE 4 ========================
	MOVLW	0x0C		; Seting adress 0C of thirteen byte of EEPROM
	CALL	READING
	MOVWF	INP_MODE4	; Writing data to RAM
						; We are finished
	RETURN
	
READING
	CALL 	BANK_2		; 
	MOVWF	EEADR		; Move adress of EEPROM byte to register EEADR
	CALL	BANK_3		;
	BCF	EECON1, EEPGD	; Selecting EEPROM from EEPROM or PROGRAM DATA
	BSF	EECON1, RD		; Enabling reading data from EEPROM at selected adres
	CALL	BANK_2		;
	MOVF	EEDATA, 0	; Reading byte from EEDATA register to W
	CALL	BANK_0		;
	RETURN
;=============================================================================
; This routine writes all settings from RAM to EEPROM
;=============================================================================
EEPROM_WRITE
	CALL	BANK_0
	MOVF	VOLUME,W
	MOVWF	EE_DATA
	MOVLW	0x00
	MOVWF	EE_ADR
	CALL	WRITING
;====================================== INPUT ================================
	MOVF	INPUT,W
	MOVWF	EE_DATA
	MOVLW	0x01
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= BASS ================================
	MOVF	TEMBR_BASS,W
	MOVWF	EE_DATA
	MOVLW	0x02
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= MIDDLE ==============================
	MOVF	TEMBR_MID,W
	MOVWF	EE_DATA
	MOVLW	0x03
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= HIGH ================================
	MOVF	TEMBR_HI,W
	MOVWF	EE_DATA
	MOVLW	0x04
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT LEVEL 1 =======================
	MOVF	INPUT_LVL1,W
	MOVWF	EE_DATA
	MOVLW	0x05
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT LEVEL 2 =======================
	MOVF	INPUT_LVL2,W
	MOVWF	EE_DATA
	MOVLW	0x06
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT LEVEL 3 =======================
	MOVF	INPUT_LVL3,W
	MOVWF	EE_DATA
	MOVLW	0x07
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT LEVEL 4 =======================
	MOVF	INPUT_LVL4,W
	MOVWF	EE_DATA
	MOVLW	0x08
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT MODE 1 ========================
	MOVF	INP_MODE1,W
	MOVWF	EE_DATA
	MOVLW	0x09
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT MODE 2 ========================
	MOVF	INP_MODE2,W
	MOVWF	EE_DATA
	MOVLW	0x0A
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT MODE 3 ========================
	MOVF	INP_MODE3,W
	MOVWF	EE_DATA
	MOVLW	0x0B
	MOVWF	EE_ADR
	CALL	WRITING
;======================================= INPUT MODE 4 ========================
	MOVF	INP_MODE4,W
	MOVWF	EE_DATA
	MOVLW	0x0C
	MOVWF	EE_ADR
	CALL	WRITING
	RETURN				; We are finished
		
WRITING	
	CALL	BANK_0		; 
	CLRF	INTCON		; 
	CALL 	BANK_3		; 
	BTFSC	EECON1,WR	; 
	GOTO	$-1			; 
	CALL	BANK_0
	MOVF	EE_ADR,W	; Seting adress of EEPROM write 
	CALL	BANK_2		; 
	MOVWF	EEADR		; Move adress of EEPROM byte to register EEADR
	CALL	BANK_0		; 
	MOVF	EE_DATA,W	; Writing data from RAM to W
	CALL	BANK_2		; 
	MOVWF	EEDATA		; 
	CALL	BANK_3		; 
	BCF	EECON1, EEPGD	; Selecting EEPROM from EEPROM or PROGRAM DATA
	BSF	EECON1, WREN	; Enabling writing data to EEPROM at selected adres
	MOVLW	0x55		; 
	MOVWF	EECON2		; 
	MOVLW	0xAA		; 
	MOVWF	EECON2		; 
	BSF		EECON1,WR	; 
	BCF		EECON1,WREN	; 
	CALL	BANK_0		; 
	RETURN
;=============================================================================
; This routines for common use when need to control chips via SPI port
;=============================================================================
;=============================================================================
; Enable SPI port
;=============================================================================
SPI_ENABLE
		CALL	BANK_1		; Select Register page 1
		MOVLW	B'10000000'	; Init value for SSPSTAT register
		MOVWF	SSPSTAT		; Move it to SSPSTAT register
		CALL	BANK_0		; Select Register page 0
		MOVLW	B'00100010'	; Init value for SSPCON register
		MOVWF	SSPCON		; Move it to SSPCON register
		CALL	BANK_1
		BSF		PIE1,SSPIE
		CALL	BANK_0
		RETURN
;=============================================================================
; Send two bytes of data (adress & command) to SPI port
;=============================================================================
SPI_SEND
;		CALL	SPI_ENABLE			; SPI port enabling routine
		BCF		PIR1, SSPIF			; CLEAR SSP interupt bit
		CALL	SPI_WRITE_BIT_0		; 
		MOVF	SPI_FIRST_BYTE,0	; Reading first byte to W
		MOVWF	SSPBUF				; Send byte to buffer SPI
		BTFSS	PIR1, SSPIF			; Waiting for SPI interupt
		GOTO	$-1					; Retun to previous step
		BCF		PIR1, SSPIF			; CLEAR SSP interupt bit
		CALL	SPI_WRITE_BIT_1
		NOP
		CALL	SPI_WRITE_BIT_0
		MOVF	SPI_SECOND_BYTE,0	; Reading sec byte to W
		MOVWF	SSPBUF				; Send byte to buffer SPI
		BTFSS	PIR1, SSPIF			; Waiting for SPI interupt
		GOTO	$-1					; Retun to previous step
		BCF	PIR1, SSPIF				; CLEAR SSP interupt bit
SPI_WRITE_BIT_1		
		BSF		SPI_CTRL, WR_2163	; Set to 1 WRITE pin SSM2163
		BSF		SPI_CTRL, WR_2160	; Set to 1 WRITE pin SSM2160
		RETURN
;=============================================================================
; Seting 0 at coresponding SPI WRITE BIT
;=============================================================================
SPI_WRITE_BIT_0
		MOVF	TMP_SPI_CTRL,F	; Check - is 1 in reg (control for SSM2163)
		BTFSC   STATUS, Z		; trought Zero flag (IF "1" - NEXT COMMAND)
		GOTO	SET_2160
		CALL	BANK_1
		BSF		SSPSTAT,CKE
		CALL	BANK_0
		BCF		SPI_CTRL,WR_2163	;
		NOP
MARK_1
		RETURN
SET_2160
		CALL	BANK_1
		BCF		SSPSTAT,CKE
		CALL	BANK_0
		BCF		SPI_CTRL,WR_2160	;
		GOTO	MARK_1
;=============================================================================
; This routine for sending control commands to SSM 2160
;=============================================================================
;
;=====================setting Volume value from VOLUME reg ==================-
VOLUME_SET
		MOVLW	0x000			; "0" in TMP_SPI_CTRL mind that we will
		MOVWF	TMP_SPI_CTRL	; control SSM2160
		MOVLW	0x080			; Adres for master Volume of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	VOLUME, 0		; Taking value of VOLUME from RAM
		ANDLW	B'01111111'		; Clearing MSB to "0"
		MOVWF	SPI_SECOND_BYTE	; MSB of second byte must be 0 
		MOVLW	0x000			; "0" in TMP_SPI_CTRL mind that we will
		MOVWF	TMP_SPI_CTRL	; control SSM2160
		CALL	SPI_SEND		; calling routine sending via SPI port
		RETURN
;=====================setting Bass level value from TEMBR_BASS reg ===========
BASS_SET
		MOVLW	0x000			; "0" in TMP_SPI_CTRL mind that we will
		MOVWF	TMP_SPI_CTRL	; control SSM2160
		MOVLW	0x081			; Adres for Channel DAC 1 of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	TEMBR_BASS, 0	; Taking value of BASS from RAM
		ANDLW	B'01111111'		; Clearing bit 7 to "0"
		IORLW	B'01000000'		; Seting bit 6 to "1"
		MOVWF	SPI_SECOND_BYTE	; 
		CALL	SPI_SEND		; calling routine sending via SPI port
		MOVLW	0x082			; Adres for Channel DAC 2 of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	TEMBR_BASS, 0	; Taking value of BASS from RAM
		ANDLW	B'01111111'		; Clearing bit 7 to "0"
		IORLW	B'01000000'		; Seting bit 6 to "1"
		MOVWF	SPI_SECOND_BYTE	; MSB of second byte must be 0 
		CALL	SPI_SEND		; calling routine sending via SPI port
		RETURN
;=====================setting middle level value from TEMBR_MID reg ===========
MIDDLE_SET
		MOVLW	0x000			; "0" in TMP_SPI_CTRL mind that we will
		MOVWF	TMP_SPI_CTRL	; control SSM2160
		MOVLW	0x083			; Adres for Channel DAC 3 of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	TEMBR_MID, 0	; Taking value of MIDDLE LEVEL from RAM
		ANDLW	B'01111111'		; Clearing bit 7 to "0"
		IORLW	B'01000000'		; Seting bit 6 to "1"
		MOVWF	SPI_SECOND_BYTE	; 
		CALL	SPI_SEND		; calling routine sending via SPI port
		MOVLW	0x084			; Adres for Channel DAC 4 of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	TEMBR_MID, 0	; Taking value of MIDDLE LEVEL from RAM
		ANDLW	B'01111111'		; Clearing bit 7 to "0"
		IORLW	B'01000000'		; Seting bit 6 to "1"
		MOVWF	SPI_SECOND_BYTE	; MSB of second byte must be 0 
		CALL	SPI_SEND		; calling routine sending via SPI port
		RETURN
;=====================setting high level value from TEMBR_HI reg ===========
HIGH_SET
		MOVLW	0x000			; "0" in TMP_SPI_CTRL mind that we will
		MOVWF	TMP_SPI_CTRL	; control SSM2160
		MOVLW	0x085			; Adres for Channel DAC 5 of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	TEMBR_HI, 0		; Taking value of HIGH LEVEL from RAM
		ANDLW	B'01111111'		; Clearing bit 7 to "0"
		IORLW	B'01000000'		; Seting bit 6 to "1"
		MOVWF	SPI_SECOND_BYTE	; 
		CALL	SPI_SEND		; calling routine sending via SPI port
		MOVLW	0x086			; Adres for Channel DAC 6 of SSM2160, put it
		MOVWF	SPI_FIRST_BYTE	; to first byte, which will sent to chip
		MOVF	TEMBR_HI, 0		; Taking value of HIGH LEVEL from RAM
		ANDLW	B'01111111'		; Clearing bit 7 to "0"
		IORLW	B'01000000'		; Seting bit 6 to "1"
		MOVWF	SPI_SECOND_BYTE	; MSB of second byte must be 0 
		CALL	SPI_SEND		; calling routine sending via SPI port
		RETURN
;=============================================================================
; This routine for sending control commands to SSM 2163 
;=============================================================================
INPUT_SET
	CALL	BANK_0
;=================FIRST PART - switching OFF all inputs ======================	
	MOVLW	0x001			; Select, that we will control SSM2163
	MOVWF	TMP_SPI_CTRL	;
	CLRF	SPI_SECOND_BYTE	; setting attenuator 0 dB
	MOVLW	0x80
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x81
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x82
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x83
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x84
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x85
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x86
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
	MOVLW	0x87
	MOVWF	SPI_FIRST_BYTE	;
	CALL	SPI_SEND		;
;==	SECOND PART - switsh ON selected input and seting attenuator value =======
INPUT_SET_SHORT
	CALL	INPUT_DETERMINE
	MOVLW	0x001			; Select, that we will control SSM2163
	MOVWF	TMP_SPI_CTRL	;
	MOVF	TEMP_LVL,0
	ANDLW	B'00111111'
	MOVWF	SPI_SECOND_BYTE		; setting attenuator value for 1 input
	MOVF	TEMP_MODE,W
	XORLW	0x00
	BTFSC	STATUS,Z
	CALL	LEFT_STEREO
	MOVF	TEMP_MODE,W
	XORLW	0x01
	BTFSC	STATUS,Z
	CALL	LEFT_MONO
	MOVF	TEMP_MODE,W
	XORLW	0x02
	BTFSC	STATUS,Z
	CALL	LEFT_LEFT
	MOVF	TEMP_MODE,W
	XORLW	0x03
	BTFSC	STATUS,Z
	CALL	LEFT_RIGHT
;=============================================================================	
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x00			; is it input 1 ?
		BTFSC	STATUS,Z
		CALL	LEFT_INP1
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x01			; is it input 2 ?
		BTFSC	STATUS,Z
		CALL	LEFT_INP2
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x02			; is it input 3 ?
		BTFSC	STATUS,Z
		CALL	LEFT_INP3
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x03			; is it input 4 ?
		BTFSC	STATUS,Z
		CALL	LEFT_INP4
		CALL	SPI_SEND			;
;=============================================================================
		MOVF	TEMP_MODE,W
		XORLW	0x00
		BTFSC	STATUS,Z
		CALL	RIGHT_STEREO
		MOVF	TEMP_MODE,W
		XORLW	0x01
		BTFSC	STATUS,Z
		CALL	RIGHT_MONO
		MOVF	TEMP_MODE,W
		XORLW	0x02
		BTFSC	STATUS,Z
		CALL	RIGHT_LEFT
		MOVF	TEMP_MODE,W
		XORLW	0x03
		BTFSC	STATUS,Z
		CALL	RIGHT_RIGHT
;=============================================================================	
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x00			; is it input 1 ?
		BTFSC	STATUS,Z
		CALL	RIGHT_INP1
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x01			; is it input 2 ?
		BTFSC	STATUS,Z
		CALL	RIGHT_INP2
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x02			; is it input 3 ?
		BTFSC	STATUS,Z
		CALL	RIGHT_INP3
		MOVF	INPUT,0			; reading curent input number
		XORLW	0x03			; is it input 4 ?
		BTFSC	STATUS,Z
		CALL	RIGHT_INP4
		CALL	SPI_SEND			;
		RETURN

;=============================================================================
; Those tables for convert input number to adress & command for SSM 2163
;=============================================================================
LEFT_STEREO
	MOVLW	B'10010000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
LEFT_MONO	
	MOVLW	B'10011000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
LEFT_LEFT	
	MOVLW	B'10011000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
LEFT_RIGHT	
	MOVLW	B'10000000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
;=============================================================================
RIGHT_STEREO
	MOVLW	B'10001000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
RIGHT_MONO
	MOVLW	B'10011000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
RIGHT_LEFT
	MOVLW	B'10000000'
	MOVWF	SPI_FIRST_BYTE
	RETURN
RIGHT_RIGHT
	MOVLW	B'10011000'
	MOVWF	SPI_FIRST_BYTE
	RETURN

LEFT_INP1
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x00
	MOVWF	SPI_FIRST_BYTE
	RETURN
LEFT_INP2	
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x02
	MOVWF	SPI_FIRST_BYTE
	RETURN
LEFT_INP3	
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x04
	MOVWF	SPI_FIRST_BYTE
	RETURN
LEFT_INP4
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x06
	MOVWF	SPI_FIRST_BYTE
	RETURN
;=============================================================================
RIGHT_INP1
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x01
	MOVWF	SPI_FIRST_BYTE
	RETURN
RIGHT_INP2
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x03
	MOVWF	SPI_FIRST_BYTE
	RETURN
RIGHT_INP3
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x05
	MOVWF	SPI_FIRST_BYTE
	RETURN
RIGHT_INP4
	MOVF	SPI_FIRST_BYTE,W
	ADDLW	0x07
	MOVWF	SPI_FIRST_BYTE
	RETURN
;=============================================================================
; Common routines. It include bank of memory switching, enabling and disabling
; interupts, delays, and procedure fo hex digit  to  decimal  convert, which I  
; took from NET.
;=============================================================================
; Banks of memory switching (just call it when I need to switch banks)
;=============================================================================
BANK_0
	BCF	STATUS, RP0
	BCF	STATUS, RP1
	RETURN
BANK_1
	BSF	STATUS, RP0
	BCF	STATUS, RP1
	RETURN
BANK_2
	BCF	STATUS, RP0
	BSF	STATUS, RP1
	RETURN
BANK_3
	BSF	STATUS, RP0
	BSF	STATUS, RP1
	RETURN
;=============================================================================
; Delay_time	= ((DELAY_value * 3) + 4) * Cycle_time
; DELAY_value	= (Delay_time - (4 * Cycle_time)) / (3 * Cycle_time)
; i.e. (@ 4MHz crystal)
; Delay_time	= ((32 * 3) + 4) * 1uSec
;		= 100uSec
; DELAY_value	= (500uSec - 4) / 3
;		= 165.33
;		= 165
;=============================================================================
DELAY500	MOVLW	D'165'			; +1		1 cycle
			MOVWF	DELAY			; +2		1 cycle
DELAY500_LOOP	DECFSZ	DELAY, F	; step 1	1 cycle
			GOTO	DELAY500_LOOP	; step 2	2 cycles
			RETURN					; +3		2 cycles
;
;
DELAYMAX	
		MOVLW	0x0FF
		MOVWF	DELAY
		MOVWF	X_DELAY			; +1		1 cycle
DELAYMAX_LOOP	CALL	DELAY500	; step1		wait 500uSec
		DECFSZ	X_DELAY, F			; step2		1 cycle
		GOTO	DELAYMAX_LOOP		; step3		2 cycles
		RETURN						; +2		2 cycles
;
;
X_DELAY500	MOVWF	X_DELAY			; +1		1 cycle
X_DELAY500_LOOP	CALL	DELAY500	; step1		wait 500uSec
		DECFSZ	X_DELAY, F			; step2		1 cycle
		GOTO	X_DELAY500_LOOP		; step3		2 cycles
X_DELAY500_END	RETURN				; +2		2 cycles
;=============================================================================
; Binary to decimal convert I don't know, how it work, I took it from Internet
;=============================================================================
BCD_CONVERT
		CLRF	HUNDREDS
		SWAPF	TMP_VALUE,W
		ADDWF	TMP_VALUE, W
		ANDLW	B'00001111'
		SKPNDC	
		ADDLW	0X16
		SKPNDC
		ADDLW	0X06
		ADDLW	0X06
		SKPDC
		ADDLW	-0X06
		BTFSC	TMP_VALUE,4
		ADDLW	0X16-1+0X6
		SKPDC
		ADDLW	-0X06
		BTFSC	TMP_VALUE,5
		ADDLW	0X30
		BTFSC	TMP_VALUE,6
		ADDLW	0X60
		BTFSC	TMP_VALUE,7
		ADDLW	0X20
		ADDLW	0X60
		RLF		HUNDREDS,F
		BTFSS	HUNDREDS,0
		ADDLW	-0X60
		MOVWF	DEC_ONES
		BTFSC	TMP_VALUE,7
		INCF	HUNDREDS,F
		RETURN
;=============================================================================
;	BTFSC REGISTER,BIT	; Waiting for "0" in selected bit of register
;	GOTO	$-1		; loop back untill 
;=============================================================================
;	BTFSS REGISTER,BIT	; Waiting for "1" in selected bit of register
;	GOTO	$-1		; loop back untill 
;=============================================================================
	END				; End of program


