; PIC16F628A Configuration Bit Settings

; Assembly source line config statements

#include "p16F628A.inc"

	__CONFIG _FOSC_INTOSCIO & _MCLRE_OFF & _WDTE_OFF & _PWRTE_OFF & _BOREN_OFF & _LVP_OFF & _CPD_OFF & _CP_OFF
	    
    errorlevel    -302    


;******************************************************************
;****************** P R O M E N N E *******************************
;******************************************************************
    
    cblock 0x20
;{
	d1			;registry pro cekaci subrutiny
	d2
	d3
	i	
	j
	k
	tmp

	;1602 LCD
	i2c_i				;i2c_send	
	i2c_k
	i2c_tmp
	i2c_byte
	lcd_backlight
	lcd_k				;text output
	lcd_data
	lcd_tmpByte
	
	znak
	
	numMilis			;Kolik cyklu wait1ms zavolat
	numSecs				;Kolik cyklu wait1s zavolat	
	
	codeIndex			;Pozice v kodu (0,1,2...14)
	codeEntered: .15
		
	dataPointer: .2
	
    FSR_save
	
	hiByte
	loByte
		
	wt588d_tmp
    endc
;}
;******************************************************************
;****************** K O N S T A N T Y *****************************
;******************************************************************

FALSE				equ 0x00
TRUE				equ 0x01

CODE_LEN			equ .15

SECRET_CHAR1		equ '4'
SECRET_CHAR2		equ '8'
SECRET_CHAR3		equ '6'


;'587386715760841' is the access code
CODE_1				equ '5'
CODE_2				equ '8'
CODE_3				equ '7'
CODE_4				equ '3'
CODE_5				equ '8'
CODE_6				equ '6'
CODE_7				equ '7'
CODE_8				equ '1'
CODE_9				equ '5'
CODE_10				equ '7'
CODE_11				equ '6'
CODE_12				equ '0'
CODE_13				equ '8'
CODE_14				equ '4'
CODE_15				equ '1'

;LCD1602 COMMANDS
LCD_ADDR_BYTE		equ b'01111110'	;0x3F Ywrobot LCM1602 IIC v1
LCD_4BIT_INIT		equ b'00110000' 
LCD_EN_MASK			equ b'00000100' ;EN (BF) bit
LCD_EN_MASK_AND		equ b'11111011' ;EN (BF) bit AND
LCD_BL_MASK			equ b'00001000' ;BL - BACKLIGHT bit
LCD_NOBL_MASK		equ b'00000000' ;BL - BACKLIGHT off
LCD_RS_MASK			equ b'00000001' ;RS - 1=DATA
LCD_NORS_MASK		equ b'00000000' ;RS - 0=COMMAND

;WT588D
SOUND_00_WRONG				equ 0x00
SOUND_01_CORRECT			equ 0x01

;******************************************************************
;****************** D E F I N I C E *******************************
;******************************************************************

;LCD1602
#define LCD_SCL		PORTA, RA1
#define LCD_SDA		PORTA, RA0 

;4x4 Matrix keyboard, A-D sloupec (C4) nezapojen
#define MATRIX_R1  	PORTB, RB7
#define MATRIX_R2  	PORTB, RB6
#define MATRIX_R3  	PORTB, RB5
#define MATRIX_R4  	PORTB, RB4

#define MATRIX_C1	PORTB, RB1
#define MATRIX_C2	PORTB, RB2
#define MATRIX_C3	PORTB, RB3

;WT588D   
#define S_SDA		PORTA, RA2;
#define S_CS		PORTA, RA3;
#define S_SCK		PORTA, RA4;

;******************************************************************
;****************** M A K R A *************************************
;******************************************************************
;{
BANK0 macro
    bcf STATUS, RP0 ;Select memory bank 0
    endm
    
BANK1 macro
    bsf STATUS, RP0 ;Select memory bank 1
    endm   
    
BANK2 macro
    bcf STATUS, RP0 ;Select memory bank 2
    bsf STATUS, RP1 
    endm   
    
BANK3 macro
    bsf STATUS, RP0 ;Select memory bank 3
    bsf STATUS, RP1 
    endm           
                         
;******************************************************************    
;*************************** S T A R T ****************************
;******************************************************************
    
			org 0x00
    		goto MAIN

; ******************************************************************
; *********************** I N T E R R U P T ************************
; ******************************************************************


; ******************************************************************
; ************************** M A I N *******************************
; ******************************************************************

MAIN
;{
	clrwdt
	
	BANK1
	movlw b'00001000'	; Weak pull-ups PORTB
	movwf OPTION_REG

	;*** PORTA NASTAVENI - LCD1602, WT588D - outputs ***
	BANK1	
	clrf TRISA

	BANK0 	
	clrf PORTA
	movlw 0x07
	movwf CMCON	;All pins I/O
	
	;*** PORTB NASTAVENI - MEMBRANOVA KLAVESNICE ***
	
	BANK1
	movlw b'00001110'   ; RB4-7 (rows 1-4) OUTPUT, RB1-3 INPUT (cols 1-3)
    movwf TRISB
	BANK0
	clrf PORTB   
	clrf CCP1CON 		; Turn CCP module off

	;Inicializace Timer0
	clrf INTCON	
	
	;WT588D				;Nastav SCK a CS na log. 1
	bsf S_SCK			;Pro WT588D
	bsf S_CS	
	
;}				
;*******************************************************************
;******************* M A I N   L O O P *****************************
;*******************************************************************

	call i2c_lcdInit
	
MAIN_START
;{	
	call matrix_initCode	;init code to all '-'
	
	movlw HIGH text1
	movwf dataPointer+0
	movlw LOW text1
	movwf dataPointer+1	
	call lcd_printText		;Zobraz 	
	
	movlw HIGH text2
	movwf dataPointer+0
	movlw LOW text2
	movwf dataPointer+1
	call lcd_printText		;Zobraz 
	
	call lcd_home
;}

MAIN_LOOP
;{
	call matrix_getKey		;returns char with pressed or '-' if none
	movwf znak				;uloz cislici pro pozdejsi testy
	movlw '-'
	xorwf znak, w	
	btfsc STATUS, Z
	goto MAIN_NEXT			;pri nestisknuti niceho dalsi kolo


MAIN_hash
	
	movlw '#'				;Backspace
	xorwf znak, w
	btfss STATUS, Z
	goto MAIN_asterisk
	
	call lcd_backspace
	goto MAIN_NEXT
		
MAIN_asterisk

	movlw '*'				;Reset
	xorwf znak, w
	btfss STATUS, Z
	goto MAIN_NORMAL
	
	call lcd_clearDisplay
	call matrix_initCode
	call lcd_printHelp
	call lcd_printCode
	
	goto MAIN_NEXT

MAIN_NORMAL
	movf codeIndex, f		;prvni stisk - zobraz placeholder pro kod
	btfss STATUS, Z
	goto MAIN_NOFIRSTPRESS
	call lcd_clearDisplay
	call lcd_printHelp
	call lcd_printCode
	;call lcd_debugCode
	call lcd_home
	
MAIN_NOFIRSTPRESS	
	;uloz cislici		
	movf znak, w				;tiskneme jen opravdove stisky	
	movwf INDF
	incf FSR, f				;uloz cislici na novou pozici v kodu
	
	movf znak, w	    
	call lcd_printChar		;zobraz
	
	;call lcd_debugCode
	
	incf codeIndex, f
	movlw CODE_LEN
	xorwf codeIndex, w		;codeIndex == CODE_LEN?
	btfss STATUS, Z
	goto MAIN_NEXT			;Ne
	
	;Zkontroluj vlozeny kod
	call matrix_checkCode
	btfss STATUS, C			;Carry == spravne
	goto MAIN_WRONG

	call WT588D_playCorrect
	
	movlw HIGH textSpravne
	movwf dataPointer+0
	movlw LOW textSpravne
	movwf dataPointer+1	
	call lcd_printText		;Zobraz		
	
	call wait1s
	call wait1s
	call wait1s
	call wait1s
	
	goto MAIN_START	
		
MAIN_WRONG

	call WT588D_playWrong
	
	call matrix_initCode    ;Zresetuj kod na "------...."

	movlw HIGH textChybne
	movwf dataPointer+0
	movlw LOW textChybne
	movwf dataPointer+1	
	call lcd_printText		;Zobraz	
						
MAIN_NEXT

	movlw .150
	call waitMilis
	
	goto MAIN_LOOP	
	
;}


WT588D_playWrong
;{
	movlw SOUND_00_WRONG
	call doSoundFX
	goto wait1s	
;}

WT588D_playCorrect
;{
	movlw SOUND_01_CORRECT
	call doSoundFX
	goto wait1s	
;}


doSoundFX
		movwf wt588d_tmp

		bsf S_SCK
		nop
		bsf S_CS
		nop	
		
		movlw .17
		call waitMilis				

		bcf	S_CS		;Slave Select = LOW (Initiating transmission)

		movlw .2
		call waitMilis

		;Ted projdu postupne bit 0, bit 1, bit 2, bit 3 a nastavuju podle toho log 1 nebo log 0

		movlw .8
		movwf i
		
cycle	bcf S_SCK		;Clock na log. 0, zaciname prenos data			

		btfss wt588d_tmp, 0;  bit 0 nastaven?
		goto btNotSet
		bsf S_SDA		 ; ano, posli log 1
		goto tsted
btNotSet bcf S_SDA		; ne, posli log 0 na vystup
tsted	call wait30us

		bsf S_SCK		;Clock na log. 1, skoncili jsme prenos 1 bitu	
		call wait30us

		rrf wt588d_tmp, f
		decfsz i, f
		goto cycle
		
		bsf S_CS		;Slave Select = HI

		return


;Na displeji nelze jednoduse udelat backspace, musi se na predchozi
;pozici umistit '-' a vypsat znovu kod od prvni az po predchozi pozici.
lcd_backspace
;{
	movf codeIndex, f		; == 0?
	btfsc STATUS, Z
	goto lcd_backAtZero
	decf codeIndex, f
	decf FSR, f	
	movlw '-'				;Uloz '-' na aktualni pozici a posun se doleva
	movwf INDF
	
	call lcd_printCode		;Vypis cely kod
	
	call lcd_home		;a od zacatku vypisuj
	
	movf codeIndex, f		; == 0? - Nevypisuj nic
	btfsc STATUS, Z
	return
	
	;Vypis kod od 0 do codeIndex
	movf FSR, w				;uloz aktualni pozici vkladani
	movwf FSR_save
	
	movlw codeEntered
	movwf FSR
	movf codeIndex, w
	movwf i
lcd_backLoop
	movf INDF, w
	call lcd_printChar
	incf FSR, f
	decfsz i, f
	goto lcd_backLoop
	
	movf FSR_save, w
	movwf FSR
	return
	
lcd_backAtZero	
	movlw '-'				;Na pozici 0, jen vycisti pozici
	movwf INDF
	call lcd_printHelp
	goto lcd_printCode
		
;}

lcd_printHelp
	movlw HIGH textHelp
	movwf dataPointer+0
	movlw LOW textHelp
	movwf dataPointer+1
	call lcd_printText		;Zobraz napovedu
	return


;Vypis aktualni stav vkladaneho kodu
lcd_printCode
;{
	call lcd_home
	
	movf FSR, w				;Uloz FSR - ukazuje na pozici v kodu
	movwf FSR_save
	
	movlw codeEntered
	movwf FSR
	movlw CODE_LEN
	movwf i

lcd_printL

	movf INDF, w
	call lcd_printChar
	incf FSR, f	
	decfsz i, f
	goto lcd_printL
	
	movlw ' '				;Vycisti pozici 16 na LCD displeji
	call lcd_printChar
	
	movf FSR_save, w	;Obnov FSR
	movwf FSR
	
	return
;}


;Nastav kod na "------------------"
matrix_initCode
;{	
	clrf codeIndex
	
	movlw codeEntered
	movwf FSR
	movlw CODE_LEN
	movwf i
	
matrix_initL

	movlw '-'
	movwf INDF
	incf FSR, f
	
	decfsz i, f
	goto matrix_initL

	movlw codeEntered	;Startovaci pozice, kam se budou ukladat stisky
	movwf FSR
	return
	
matrix_checkCode
;{
	movlw CODE_1
	xorwf codeEntered+.0, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_2
	xorwf codeEntered+.1, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_3
	xorwf codeEntered+.2, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_4
	xorwf codeEntered+.3, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_5
	xorwf codeEntered+.4, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_6
	xorwf codeEntered+.5, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_7
	xorwf codeEntered+.6, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_8
	xorwf codeEntered+.7, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_9
	xorwf codeEntered+.8, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_10
	xorwf codeEntered+.9, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_11
	xorwf codeEntered+.10, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_12
	xorwf codeEntered+.11, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_13
	xorwf codeEntered+.12, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_14
	xorwf codeEntered+.13, w
	btfss STATUS, Z
	goto matrix_codeWrong
	
	movlw CODE_15
	xorwf codeEntered+.14, w
	btfss STATUS, Z
	goto matrix_codeWrong														
	
	bsf STATUS, C			;Carry = Spravne
	return	

matrix_codeWrong
	bcf STATUS, C			;Nespravne
	return
;}	

;Vystup: Vraci ascii kod znaku, ktery se stiskl nebo "-" pokud nic
matrix_getKey
;{
	movlw b'00001110'	; All rows log.0, cols are pulled-up high
	movwf PORTB
	nop
	
	;1) Check each column for log. 0 (= press in that column)
	btfsc MATRIX_C1
	goto checkC2
	
	;2) For each row set log. 1 sequentially and check if C1 is high
	bsf MATRIX_R1			;row1
	nop
	btfsc MATRIX_C1
	retlw '1'
	bcf MATRIX_R1
	bsf MATRIX_R2			;row2
	nop
	btfsc MATRIX_C1
	retlw '4'
	bcf MATRIX_R2
	bsf MATRIX_R3			;row3
	nop
	btfsc MATRIX_C1
	retlw '7'
	bcf MATRIX_R3
	bsf MATRIX_R4			;row4
	nop
	btfsc MATRIX_C1
	retlw '*'
		
checkC2
	btfsc MATRIX_C2
	goto checkC3
	
	bsf MATRIX_R1			;row1
	nop
	btfsc MATRIX_C2
	retlw '2'
	bcf MATRIX_R1
	bsf MATRIX_R2			;row2
	nop
	btfsc MATRIX_C2
	retlw '5'
	bcf MATRIX_R2
	bsf MATRIX_R3			;row3
	nop
	btfsc MATRIX_C2
	retlw '8'
	bcf MATRIX_R3
	bsf MATRIX_R4			;row4
	nop
	btfsc MATRIX_C2
	retlw '0'	

checkC3
	btfsc MATRIX_C3
	retlw '-'
	
	bsf MATRIX_R1			;row1
	nop
	btfsc MATRIX_C3
	retlw '3'
	bcf MATRIX_R1
	bsf MATRIX_R2			;row2
	nop
	btfsc MATRIX_C3
	retlw '6'
	bcf MATRIX_R2
	bsf MATRIX_R3			;row3
	nop
	btfsc MATRIX_C3
	retlw '9'
	bcf MATRIX_R3
	bsf MATRIX_R4			;row4
	nop
	btfsc MATRIX_C3
	retlw '#'	
	
	retlw '-'				;fail safe
;}

; ********************************************************************
; *********************** LCD DISPLAY DRIVER *************************
; ********************************************************************


;Vypis binarne hodnotu na PORTB[7:0]
lcd_printPortB
;{
	call lcd_home
	
	movf PORTB, w
	movwf tmp
	
	movlw .8
	movwf i
	
lcd_printBLoop
	bcf STATUS, C
	rlf tmp, f
	movlw '0'
	btfsc STATUS, C
	movlw '1'
	call lcd_printChar
	decfsz i, f
	goto lcd_printBLoop

	return		
;}


; ***** LCD: I2C: EXPANDER RESET
; posli same nuly
;{
i2c_expanderReset
;{
		call i2c_startCond
		call i2c_sendAddr
		movlw b'00000000'
		call i2c_sendA
		call i2c_stopCond
		return
;}					
; ***** LCD: I2C: INIT LCD

i2c_lcdInit			
;{
		movlw .1
		movwf lcd_backlight		;Podsviceni default on
		
		clrf lcd_data			;Defaultne posilame commandy (=0, 1=data)

		call wait1s

		call i2c_expanderReset

		movlw .100		;Wait 100ms after reset
		call waitMilis

		movlw LCD_4BIT_INIT ;0x03
		call i2c_sendByte

		;now wait 4.5ms
		movlw .4
		call waitMilis
		call wait150us
		call wait150us	
		call wait150us
		call wait30us
		call wait30us
		
		movlw LCD_4BIT_INIT
		call i2c_sendByte

		;now wait 150us
		call wait150us

		movlw LCD_4BIT_INIT
		call i2c_sendByte

		;now wait 150us
		call wait150us
		
		movlw b'00100000'	;0x02 - 4bit mode
		call i2c_sendByte

		;now wait 150us
		call wait150us

		;function set (DL=0,N=1,F=0)
		movlw b'00100000'
		call i2c_sendByte
		movlw b'10000000'
		call i2c_sendByte

		;display control
		call lcd_blinkOff

		call lcd_clearDisplay

		;entry mode set (increment, no display shift)
		movlw b'00000000'
		call i2c_sendByte
		movlw b'01100000'
		call i2c_sendByte

		call lcd_home
		
		return
;}
; ***** LCD: I2C: CLEAR DISPLAY
lcd_clearDisplay	
;{
		clrf lcd_data
		movlw b'00000000'
		call i2c_sendByte
		movlw b'00010000'
		call i2c_sendByte
	    movlw .2
		call waitMilis
		return
;}
; ***** LCD: I2C: HOME
lcd_home		
;{
		clrf lcd_data
		movlw b'00000000'
		call i2c_sendByte
		movlw b'00100000'
		call i2c_sendByte
	    movlw .2
		call waitMilis
		return
;}

; ***** LCD: I2C: BLINK OFF
lcd_blinkOff
;{
		;display control(disp ON, cursor OFF, blink OFF)
		movlw b'00000000'
		call i2c_sendByte
		movlw b'11000000'
		call i2c_sendByte
		return

;}
; ***** LCD: I2C: BLINK ON
lcd_blinkOn
;{
		;display control(disp ON, cursor OFF, blink ON)
		movlw b'00000000'
		call i2c_sendByte
		movlw b'11010000'
		call i2c_sendByte
		return
;}
; ***** LCD: I2C: TURN ON BACKLIGHT
lcd_backlightOn
;{
		call i2c_startCond
		call i2c_sendAddr
		movlw b'00001000'
		call i2c_sendA
		call i2c_stopCond
		return
;}
; ***** LCD: I2C: TURN OFF BACKLIGHT
lcd_backlightOff
;{
		movlw b'00000000'
		call i2c_sendByte
		return
;}	
	
; ***** LCD: PRINT CHAR
;Vypis 1 znak na aktualni pozici na displeji
lcd_printChar
;{
		movwf lcd_tmpByte

		movlw TRUE
		movwf lcd_data			;ted posilam znaky = DATA

		;ted mam cely bajt s kodem znaku, musim to posilat po nibblech,
		;nejprve horni a pak dolni, vzdy v hornich 4 bitech
		movlw b'11110000'		; Vynuluju dolni 4 bity
		andwf lcd_tmpByte, w
		call i2c_sendByte
		swapf lcd_tmpByte, f	; Dolni 4 bity <-> horni 4 bity
		movlw b'11110000'
		andwf lcd_tmpByte, w
		call i2c_sendByte
		clrf lcd_data			;kdybych mezitim posilal command
		return
;}					



; ***** LCD: ZOBRAZ TEXT, pozice v dataPointer
;Vstup: dataPointer

; **** LCD: I2C: WRITE TEXT
; 1. byte - column
; 2. byte - row
; 3. byte - znak1
; 4. byte - znak2
; ...
; 0x00	  - konec stringu

lcd_printText
				movlw FALSE
				movwf lcd_data			;nejprve posli commandy
				call lcd_processText
				return	

; **** LCD: I2C: WRITE TEXT
; 1. byte - column
; 2. byte - row
; 3. byte - znak1
; 4. byte - znak2
; ...
; 0x00	  - konec stringu

lcd_processText	
				movlw TRUE
				movwf lcd_backlight
						
				call getNextByte		;ziskej column, kam pujde cursor
				call i2c_sendByte
				call getNextByte		;ziskej row
				call i2c_sendByte

				movlw TRUE
				movwf lcd_data			;ted posilam znaky = DATA

processCycle	
				call getNextByte
				movwf lcd_tmpByte		;ulozim cely kod znaku
				movf lcd_tmpByte, f		;mame konec stringu? (0x00)
				btfsc STATUS, Z
				goto processFin
				;ted mam cely bajt s kodem znaku, musim to posilat po nibblech,
				;nejprve horni a pak dolni, vzdy v hornich 4 bitech
				movlw b'11110000'		; Vynuluju dolni 4 bity
				andwf lcd_tmpByte, w
				call i2c_sendByte
				swapf lcd_tmpByte, f	; Dolni 4 bity <-> horni 4 bity
				movlw b'11110000'
				andwf lcd_tmpByte, w
				call i2c_sendByte

				goto processCycle
							
processFin		clrf lcd_data				;kdybych mezitim posilal command
				return

getNextByte
				call getNextByte2 		;To je patch kvuli strankovani
				clrf PCLATH
				incfsz dataPointer+1, f ;Inkrementuj pointer
				goto $+2
				incf dataPointer+0, f
				return 					;Vrat hodnotu (je stale ve W)
getNextByte2
				;Zde se pouze skoci na dvoubajtovou adresu v dataPointer
				movf dataPointer+0, w 	;Zkopiruj HI byte do PCLATHu
				movwf PCLATH
				movf dataPointer+1, w 	;Dej LO byte do PCL
				movwf PCL 				;Skoci na adresu, kam ukazuje textPointer

; ***** LCD: I2C: SEND START CONDITION
i2c_startCond		
;{
		bsf LCD_SDA
		call wait5us
		bsf LCD_SCL
		call wait5us
		call wait5us
		bcf LCD_SDA
		call wait5us
		call wait5us
		bcf LCD_SCL
		call wait5us
		call wait5us
		return
;}
				
; ***** LCD: I2C: SEND STOP CONDITION

i2c_stopCond		
;{
		bcf LCD_SDA
		call wait5us
		bsf LCD_SCL
		call wait5us
		call wait5us
		bsf LCD_SDA
		call wait5us
		call wait5us
		return
;}

; ***** LCD: I2C: SEND ADDRESS
i2c_sendAddr		
;{
		movlw LCD_ADDR_BYTE
		call i2c_sendA
		return
;}

; ***** LCD: I2C: SEND BYTE
; 4bit mode, posilam vsechno 2x, poprve s EN=1 a podruhe s EN=0

i2c_sendByte		
;{
		movwf i2c_byte

		movlw LCD_EN_MASK			;EN=1 (BF)
		iorwf i2c_byte, f

		movf lcd_backlight, f
		btfsc STATUS, Z
		goto noBL
		movlw LCD_BL_MASK
		iorwf i2c_byte, f			;primaskuj 0000 1000 (BL ON)

noBL	movf lcd_data, f			;0=command, 1=data
		btfsc STATUS, Z
		goto noDATA
		movlw LCD_RS_MASK			;primaskuj 0000 0001 pro data
		iorwf i2c_byte, f
noDATA				
		call i2c_startCond
		call i2c_sendAddr
		call i2c_send
		call i2c_stopCond

		movlw LCD_EN_MASK_AND		;EN=0 (BF)
		andwf i2c_byte, f

		call i2c_startCond
		call i2c_sendAddr
		call i2c_send
		call i2c_stopCond
		return					
;}

; ***** LCD: I2C: SEND

i2c_send			
;{
		movf i2c_byte, w
i2c_sendA			
		movwf i2c_tmp

		movlw .8
		movwf i2c_i

i2c_cycle	
		btfss i2c_tmp, 7		
		goto i2c_bitNotSet
		bcf LCD_SCL			;Abych mel hrany co nejbliz u sebe
		bsf LCD_SDA		
		nop
		goto i2c_tested
i2c_bitNotSet 		
		bcf LCD_SCL
		bcf LCD_SDA	
		nop
		nop	
		nop
i2c_tested
		call wait5us

		bsf LCD_SCL		
		nop
		nop                    

		rlf i2c_tmp, f
		decfsz i2c_i, f
		goto i2c_cycle

		nop
		nop
		nop
		nop

		;ACK BIT
		bcf LCD_SCL
		bcf LCD_SDA					
		call wait5us
		nop
		nop
		nop
		bsf LCD_SCL
		call wait5us
		nop
		nop
		nop
		nop
		bcf LCD_SCL
		call wait5us
		return	
;}



; *** SUBRUTINA, CEKEJ 150us 
wait150us 	
;{
	call wait30us
	call wait30us
	call wait30us
	call wait30us
	call wait30us
	return
;}

; *** SUBRUTINA, CEKEJ 30us (=30 jednotaktovych instrukci)

wait30us	
;{
			nop		;26, 2 na zacatku sezere volani call
			nop
			nop
			nop
			nop
		 	nop
			nop
			nop
			nop
			nop
wait20us	nop
			nop
			nop
			nop
			nop
		 	nop
			nop
			nop
			nop
			nop
wait10us	nop
			nop
			nop
			nop
			nop
wait5us	 	nop
			return;		ta je za 2 cykly
;}

; Delay = 1 seconds
; Clock frequency = 4 MHz

; Actual delay = 1 seconds = 1000000 cycles
; Error = 0 %

wait1s
;{
			;999990 cycles
	movlw	0x07
	movwf	d1
	movlw	0x2F
	movwf	d2
	movlw	0x03
	movwf	d3
wait1s_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	wait1s_0

	;6 cycles
	goto	$+1
	goto	$+1
	goto	$+1

			;4 cycles (including call)
	return
;}

waitMilis
;{
		movwf numMilis
waitM	call wait1ms
		decfsz numMilis, f
		goto waitM
		return
;}

; Delay = 0.001 seconds
; Clock frequency = 4 MHz

; Actual delay = 0.001 seconds = 1000 cycles
; Error = 0 %

wait1ms
;{
			;993 cycles
	movlw	0xC6
	movwf	d1
	movlw	0x01
	movwf	d2
wait1ms_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	wait1ms_0

			;3 cycles
	goto	$+1
	nop

			;4 cycles (including call)
	return	
;}


incHL
;{
	incfsz loByte, f
	return	
	incf hiByte, f
	return
;}

decHL	
;{
	movf loByte, f
	btfsc STATUS, Z ;je loByte na nule?
	goto decHL2
	decf loByte, w	;kopie pro nasledny OR (test na 0)
	decf loByte, f
	iorwf hiByte, w ;Z flag nastaven pri 0 (loByte OR hiByte)
	return
decHL2	decf loByte, f
	decf hiByte, f
	bcf STATUS, Z	;Potrebuju vynulovat Zero (aby mi pri lo/hi 0/1 predchozi decf Z nenastavil)
	return
;}



; ******************************************************************
; ******************** T A B U L K Y *******************************
; ******************************************************************

text1			dt 0x80, 0x00		;Pozice 0,0 (pocitano od 0)
				dt "Vloz kody z her "
				dt 0x00
				
text2			dt 0xC0, 0x00		;Pozice 1,0 (pocitano od 0)
				dt "1-5 za sebe.    "
				dt 0x00


textSpravne		dt 0xC0, 0x00
				dt "Spravne! Kod:"
				dt SECRET_CHAR1
				dt SECRET_CHAR2
				dt SECRET_CHAR3
				dt 0x00
				
textChybne		dt 0xC0, 0x00
				dt "Nespravny kod!  "
				dt 0x00


textHelp		dt 0xC0, 0x00
				dt "*-RESET, #-ZPET "
				dt 0x00

; *** KONEC SOUBORU *************************************************	
	end