#include "p16F883.inc"

	__CONFIG _CONFIG1, (_FOSC_INTRC_NOCLKOUT & _DEBUG_OFF & _LVP_OFF & _WDTE_OFF & _MCLRE_OFF & _PWRTE_OFF & _BOREN_OFF & _CP_OFF & _CPD_OFF & _IESO_OFF & _FCMEN_OFF);
	__CONFIG _CONFIG2, (_WRT_OFF & _BOR4V_BOR40V);
    
    errorlevel    -302    


;******************************************************************
;****************** P R O M E N N E *******************************
;******************************************************************
    ;BANK 0
    cblock 0x20
;{		
	w_temp	
	status_temp	
	pclath_temp	
	del1			;registry pro cekaci subrutiny
	del2
	del3
	tens
	ones
	tmpWord:.2		;16bit cislo	
	hiByte
	loByte
	i2c_byte
	i2c_tmp				
	i2c_tmpByte
	i2c_i				
	numSecs
	numMilis
	i
	j
	k
	x				;Top5 enter name
	y
	tmpChar			;Top5
	copyFrom		;Top5 kopirovani
	copyTo		
	positionTop5	;Pozice v Top5 pri prekonani nektereho rekordu	
	ssd1306_X		;Souradnice X
	ssd1306_X_max	;Souradnice max X (definice vyrezu)
	ssd1306_Y		;Souradnice Y
	ssd1306_Y_max	;Souradnice max Y (defince vyrezu)
	ssd1306_X_save	;Uloz souradnice posledniho leveho horniho rohu znaku
	ssd1306_Y_save	;Y
	ssd1306_char	;Tisk znaku
	textPointer:.2	;Ukazatel do textu
	fontPointer:.2	;Ukazatel do dat fontu	
	charWidth		;Sirka pismene (proporcionalni tisk)
	charHeight		;Vyska pismene (v pages, 1 page = radek (0-8 = 64px)
	asciiHex:.2		;bin2hex	
	asciiTmp		;bin2hex
	putCharOnly		;number or text
	difficulty		;obtiznost
	tmp
	eeprom_addr:.3	;24bit adresa pro read
	eeprom_tx
	eeprom_rx
	eeprom_i		;read more bytes
	eeprom_j		;
	tmp24bit:.3		;pocitani 24bit
	tmp16bit:.2		;pocitani 16bit
	RNDval:.2		;nahodna hodnota
	RNDtmp			;tmp pro random hodnoty	
	RNDret
	poradi_kolik	;kolik rozsviceni bude
	poradi_i		;iterator
	poradi_tmp		;preved 0->1,1->2,2->4,3->8,4->16
	util_NumH		;16bit to ASCII 5 digits
	util_NumL
	util_TenK
	util_Thou
	util_Hund
	util_Tens
	util_Ones
	game_Score:.2
	scoreChanged	;flag
	threeCounter	;Pocitadlo 0,1,2,0,1,2,0,1,2....
	game_Level
	game_Lives
	game_Timer
	game_Leds		;Pocet LED bliknuti k zopakovani
	timer1_counter	;sekundove odpocitavani
	timer1_copy		
	redrawTimer     ;flag indikujici 1 sec (kvuli zmenam na displeji)
	timeUp			;flag indikujici konec odpoctu
	timerON			;odpocitavani bezi

	;Detekce stiskù buttonù
	timer0_counter	;interrupt counter - cteni portu kazdych 10ms
	timer0_copy		;kopie interrupt counteru
	porta_save		;nacteni stavu buttonu
	evalButtons		;nastal cas vyhodnotit buttony?
	buttonPressed	;mame kompletni stisk nektereho buttonu
	whichButton		;ktery button by stisknut bit <4:0> = <button5:button1>	
	expState		;ocekavany stav (0x01-log 1, 0x02-log 1, 0x04-log 0)
	EEPROM_addr		;PIC EEPROM	(nutne mit na adrese >0x70)
	EEPROM_value	
	wt588d_i
	wt588d_tmp		
    endc
;}

	;BANK1
	cblock 0x0A0
		_w_temp			;ISR backup, nemazat!
		poradi:.20	;poradi sviceni ledek, bajty s hodnotou 0-4
	endc
	
	;BANK2
	cblock 0x120
		EEPROM_Top5:.25
	endc

;******************************************************************
;****************** K O N S T A N T Y *****************************
;******************************************************************
; Konstanty
;{
	
INIT_NUM_LIVES				equ .3	;pocet zivotu
INIT_PORADI_KOLIK			equ .3	;zaciname na 3 bliknutich

FALSE						equ 0x00
TRUE						equ 0x01
DUMMY_BYTE					equ 0x00	

TOP5_TABLE_ADDR				equ 0x20 ;v BANK2 (25 bytes)

NUM_INTRS_TMR0				equ .80  ;80x128us = 10ms delay mezi ctenimi stavu BUTTONU (Timer0)
NUM_INTRS_TMR1				equ .31  ;30 preruseni po 32768us + 1 preruseni 16960us

;SSD1306
I2C_ADDR			equ 0x78	;bin 0111 1000
I2C_CTRL_BYTE_C		equ 0x00	;bin 0000 0000 control byte: cmd
I2C_CTRL_BYTE_D		equ 0x40	;bin 0100 0000 control byte: data

;128x32 size
SSD1306_COLS_NUM			equ .128
SSD1306_PAGES_NUM			equ .8

SSD1306_SETCONTRAST			equ 0x81
SSD1306_DISPLAYALLON_RESUME equ	0xA4
SSD1306_DISPLAYALLON 		equ 0xA5
SSD1306_NORMALDISPLAY 		equ 0xA6
SSD1306_INVERTDISPLAY 		equ 0xA7
SSD1306_DISPLAYOFF 			equ 0xAE
SSD1306_DISPLAYON 			equ 0xAF
SSD1306_SETDISPLAYOFFSET 	equ 0xD3
SSD1306_SETCOMPINS 			equ 0xDA
SSD1306_SETVCOMDETECT 		equ 0xDB
SSD1306_SETDISPLAYCLOCKDIV 	equ 0xD5
SSD1306_SETPRECHARGE 		equ 0xD9
SSD1306_SETMULTIPLEX 		equ 0xA8
SSD1306_SETLOWCOLUMN 		equ 0x00
SSD1306_SETHIGHCOLUMN 		equ 0x10
SSD1306_SETSTARTLINE 		equ 0x40
SSD1306_MEMORYMODE 			equ 0x20
SSD1306_COLUMNADDR 			equ 0x21
SSD1306_PAGEADDR   			equ 0x22
SSD1306_COMSCANINC 			equ 0xC0
SSD1306_COMSCANDEC 			equ 0xC8
SSD1306_SEGREMAP 			equ 0xA0
SSD1306_CHARGEPUMP 			equ 0x8D
SSD1306_EXTERNALVCC 		equ 0x01
SSD1306_SWITCHCAPVCC 		equ 0x02
SSD1306_DEACTIVATE_SCROLL 	equ 0x2E

;Jaky stav stisku buttonu je ocekavan
EXP_READ					equ 0x01 ;ocekavam log.1 - uvodni rising edge
EXP_DEBOUNCE				equ 0x02 ;ocekavam log.1 - test na debounce
EXP_RELEASE					equ 0x04 ;ocekavam log.0 - uvolneni tlacitka


;WT588D
SOUND_00_INTRO				equ 0x00
SOUND_01_MEZI_OBRAZOVKAMI	equ 0x01
SOUND_02_CINK_GET_READY		equ 0x02
SOUND_03_TICKING			equ 0x03
SOUND_04_BUZZER_TIME_UP		equ 0x04
SOUND_05_LEVEL_FAILED		equ 0x05
SOUND_06_LEVEL_COMPLETED	equ 0x06
SOUND_07_CORRECT			equ 0x07
SOUND_08_INCORRECT			equ 0x08
SOUND_09_GAME_OVER			equ 0x09
SOUND_0A_FANFARE_TOP5		equ 0x0A
SOUND_0B_TOP5_PISMENO_ZMENA	equ 0x0B
SOUND_0C_TOP5_PISMENO_ENTER equ 0x0C
SOUND_0D_TOP5_NAME_HOTOVO	equ 0x0D
SOUND_0E_HALL_OF_FAME		equ 0x0E

;}
;******************************************************************
;****************** D E F I N I C E *******************************
;******************************************************************
; Definice
;{   
;SSD1306
#define DISP_SDA		PORTB, RB0;		(OUTPUT)
#define DISP_SCL		PORTC, RC7;		(OUTPUT)

;SPI EEPROM
#define EEPROM_SDI		PORTC, RC4;		SPI SDI (INPUT)
#define EEPROM_SDO		PORTC, RC5;		SPI SDO (OUTPUT)
#define EEPROM_SCK		PORTC, RC3;		SPI SCK (OUTPUT)
#define EEPROM_CS		PORTC, RC6;		SPI CS  (OUTPUT)

;BUTTONY
#define B_GREEN			PORTA, RA0;		(INPUT)
#define B_BLUE			PORTA, RA1;		(INPUT)
#define B_RED			PORTA, RA2;		(INPUT)
#define B_YELLOW		PORTA, RA3;		(INPUT)
#define B_WHITE			PORTA, RA4;		(INPUT)

;LEDky
#define LED_1			PORTA, RA7;		(OUTPUT)
#define LED_2			PORTA, RA6;		(OUTPUT)
#define LED_3			PORTC, RC0;		(OUTPUT)
#define LED_4			PORTC, RC1;		(OUTPUT)
#define LED_5			PORTC, RC2;		(OUTPUT)

;WT588D   
#define WT588D_SCK		PORTB, RB5;
#define WT588D_CS		PORTB, RB6;
#define WT588D_SDA		PORTB, RB7;

;}

;******************************************************************
;****************** M A K R A *************************************
;******************************************************************
; Makra
;{
BANK0 macro
    bcf STATUS, RP0 ;Select memory bank 0
    bcf STATUS, RP1 
    endm
    
BANK1 macro
    bsf STATUS, RP0 ;Select memory bank 1
    bcf STATUS, RP1 
    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   

;****************************************************************
;Random16 - 16bit Pseudo Sequence Random Number Generator (RNG).
;Based on Microchip's MATH routine found in AN544 and modified to
;fit all picchips including the tiny 12bit versions. This version
;uses 10 program words, making it slightly faster, but it needs a
;temp scratch pad to work.
;This RNG is based on linear shift register feedback. Sequence is
;generated by (`). Make sure the initial
;RandomV is not ZERO (AN544 suggests 3045h as a good choice).
;enter:	RandomV=16bit, temp=8bit
;exit:	w and temp are modified. RandomV updated to new value.
RandomM	macro	RandomV,temp
	rrf	RandomV,w		;Wreg = Q12
	xorwf RandomV+1,w	;Wreg = xor(Q12,Q3)
	movwf temp			;temp(bit3) = xor(Q12,Q3)
	swapf temp,f		;temp(bit7) = xor(Q12,Q3)
	rlf	RandomV,f		;Wreg = Q14
	xorwf RandomV,f		;Wreg = xor(Q15,Q14)
	xorwf temp,f		;temp(bit7) = xor(Q15,Q14,Q12,Q3)
	rlf	temp,w			;cflag = xor(Q15,Q14,Q12,Q3)
	rlf	RandomV+1,f		;move bit7 to new bit0 and then..
	rlf	RandomV,f		;..rotate RNG value to the left
	endm
;****************************************************************
        
;}
    
;******************************************************************    
;*************************** S T A R T ****************************
;******************************************************************
    
				org 0x00
				goto MAIN
	
; ******************************************************************
; *********************** I N T E R R U P T ************************
; ******************************************************************

				org 0x04
INTERRUPT
;{	
	movwf w_temp 		;copy W to temp register, 0x20 nebo 0xA0
	swapf STATUS, w		;swap status to be saved into W	
	BANK0
	movwf status_temp 	
	
    movf PCLATH, w      ;move pclath register into w register
    movwf pclath_temp   ;save off contents of PCLATH register    
    clrf PCLATH	
    
checkTMR0
	btfss INTCON, T0IF	;TMR0 interrupt?
	goto checkTMR1
	bcf INTCON, T0IF    ;vycisti TMR0 Interrupt flag
	decfsz timer0_counter, f
	goto checkTMR1	
	movf timer0_copy, w
	movwf timer0_counter
	movf PORTA, w
	movwf porta_save
	movlw TRUE
	movwf evalButtons	;muzeme vyhodnotit stav buttonu

checkTMR1
	btfss PIR1, TMR1IF	;TMR1 interrupt = timer (1secs)
	goto skip
	bcf PIR1, TMR1IF	;vycisti TMR1 Interrupt flag
	decfsz timer1_counter, f
	goto skip

    movf game_Timer, f        ;mame konec odpoctu?
    btfss STATUS, Z        
    goto timerNotZero
    movlw TRUE
    movwf timeUp        	 ;nastav flag, ze mame konec
	goto TMR1common    
timerNotZero
    decf game_Timer, f
	movlw TRUE
	movwf redrawTimer
TMR1common
	;init Timer1 - bez call (kvuli stack overflow)
	movlw 0x7B
	movwf TMR1H
	movlw 0x80
	movwf TMR1L
	
	movf timer1_copy, w
	movwf timer1_counter			
skip
    movf  pclath_temp, w ;retrieve copy of PCLATH register
    movwf PCLATH         ;restore pre-isr PCLATH register contents
	swapf status_temp, w ;swap status_temp register into W, sets bank to original state
	movwf STATUS 		 ;move W into STATUS register
	swapf w_temp, f 	 ;swap w_temp
	swapf w_temp, w 	 ;swap w_temp into W	
	retfie
;}
; ******************************************************************
; ************************** M A I N *******************************
; ******************************************************************

MAIN
;{		
	
	clrwdt
	nop
	
	movlw	030h		;initialize random routine....
	movwf	RNDval+0
	movlw	047h
	movwf	RNDval+1

	BANK1
	;movlw b'01100100'	;4MHz internal
	movlw b'01110100'	;8MHz internal
	movwf OSCCON
	movlw b'11001000'
	movwf OPTION_REG

	;***********************
	;*** PORTA NASTAVENI ***
	;***********************

	BANK1	
	movlw b'00111111'	;RA0-RA5 = BUTTONy, RA7-LED1, RA6-LED2
	movwf TRISA

	BANK3
	clrf ANSEL
	clrf ANSELH
	clrf CM1CON0
	clrf CM2CON0

	BANK0 		
	clrf PORTA

	;***********************
	;*** PORTB NASTAVENI ***
	;***********************
	
	BANK1
	clrf IOCB		 	;Interrupt onChange disabled
	clrf WPUB	
	clrf TRISB			;Vse output
	
	BANK0
	clrf CCP1CON 		; Turn CCP module off
	clrf PORTB   
	
	;Inicializace Timer0
	clrf INTCON	

	;***********************
	;*** PORTC NASTAVENI ***
	;***********************
	
	BANK1
	movlw b'00010000';	RC4-SDI FLASH
	movwf TRISC
	
	BANK0
	clrf PORTC

	;EEPROM INIT
	bsf  EEPROM_CS		
	clrf SSPCON  		; Inicializace MSSP modulu
	movlw b'00110000'	; 00, SSPEN=1,CKP=1, 0001 SPI Master Mode = FOSC/4
	movwf SSPCON
	BANK1
	clrf SSPSTAT
  	movlw 0x80			; set up spi port, SPI master,
	movwf SSPSTAT		; CKE = 0 (mode 1,1)
	BANK0
	
	;WT588D				;Nastav SCK a CS na log. 1
	bsf WT588D_SCK		;Pro WT588D
	bsf WT588D_CS	
;}				

;*******************************************************************
;******************* M A I N   L O O P *****************************
;*******************************************************************

	call EEPROM_readTop5
	
	call ssd1306_init
	
GAME_START
;{
	call game_Init				;Level 1, Score 0, Lives 3
	
	call playIntroSound

goShowSplashScreen

	call show_SplashScreen

	call wait3SecsForAnyButton
	xorlw .1
	btfsc STATUS, Z				;Z set = byl stisk
	goto goShowInstructions

	call show_HallOfFame

	call wait3SecsForAnyButton
	xorlw .1
	btfss STATUS, Z				
	goto goShowSplashScreen

	call playMeziObrazovkami

goShowInstructions

	;Zadny button nesmi byt stisknuty, jinak preskoci Instrukce
	btfsc B_GREEN					
	goto goShowInstructions
	btfsc B_BLUE
	goto goShowInstructions
	btfsc B_RED
	goto goShowInstructions	
	btfsc B_YELLOW
	goto goShowInstructions	
	btfsc B_WHITE
	goto goShowInstructions	
		
	call show_Instructions
	
	call waitAnyKey

	call playMeziObrazovkami
	
	call show_Difficulty
		
	call readDifficulty
	
	call playMeziObrazovkami

	call ssd1306_clearDisplay

GAME_LOOP
	call zhasniVse				;LEDky off
		
	call show_Lives				;Musim takto rozepsat, kvuli malemu stacku
	call show_Score

	call show_Level
	call show_Timer
	call show_EmptyTimer
	call show_Leds
	call show_Leds_Number
	
	call show_LevelPressKey
	call show_Level_Number
	call waitAnyKey	

	call show_GetReady
	call playGetReadyCink
	call wait1s
	call wait1s
	
	call nastavPoradi			;Nastav poradi blikancu LED
	call prehrajPoradi			;A zablikej vygenerovane poradi

	call setTimer				;Nastav pocet sekund pro zopakovani

	call show_NowRepeat
	movlw .250					;0.75 sekundy pockej
	call waitMilis
	movlw .250
	call waitMilis
	movlw .250
	call waitMilis
	call playClockTicking	
	call show_EmptyBox
	call show_Timer_Number
	call show_EmptyCircle
	
	call enableInterrupts
LEVEL_LOOP
	call evalButtonPress
	btfsc timeUp, 0
	goto levelTimeUp
	btfss buttonPressed, 0
	goto noButtonPress		  ;Nic nevyhodnocuj, nebylo-li nic stisknuto
	;call show_ExpectedActual  ;DEBUG
	call checkButtonPress	  ;Vraci ZERO, pokud byl stisk spatne
	btfsc STATUS, Z
	goto levelFailed		  ;Chybny stisk
	call show_Correct		  ;Dobry stisk
	call playCorrect
	movlw .50
	call waitMilis
	call playClockTicking	  
	call game_DecLeds		  ;Sniz pocet stisku
	call show_Leds_Number
	call checkLevelCompleted  ;Mame tolik OK stiskù, kolik je poradi_kolik?
	btfsc STATUS, Z
	goto levelCompleted
noButtonPress
	call show_EmptyCircle	  
	btfsc redrawTimer, 0
	call show_Timer_Number
	btfsc scoreChanged, 0
	call show_Score
	
	goto LEVEL_LOOP

;Neuspesny level, chybny stisk	
levelFailed
	call disableInterrupts
	call show_Incorrect		;Krizek
	call playIncorrect
	call wait500ms
	call zhasniVse	
	goto levelLifeLost

;Uspesne dokonceni levelu - pred casomirou zopakovana vsechny bliknuti
levelCompleted
	call disableInterrupts
	call zhasniVse
	call show_Score
	call show_LevelCompleted
	call playLevelCompleted
	call show_Level_Number
	call wait1s
	call game_IncLevel
	call show_Level
	goto levelCommon

;Casomira konec - TODO zkontroluj, jestli jsme zopakovali vsechna 
;bliknuti - tj. stihli jsme to?
levelTimeUp
	call disableInterrupts	
	call zhasniVse
	call show_TimeIsUp
	call playBuzzerTimesUp
levelLifeLost
	call wait1s
	call show_1LifeLost
	call playLevelFailed
	call wait1s
	call game_DecLives		;TODO REMOVE	
	btfsc STATUS, Z
	goto GAME_OVER
	call show_Lives
levelCommon
	movf poradi_kolik, w
	movwf game_Leds
	goto GAME_LOOP
	
GAME_OVER
	call show_Lives
	call show_GameOver
	call playGameOver
	call wait1s
	call wait1s
	
	call checkScore			;Hall of fame record?	
	btfss STATUS, C
	goto notInTop5
	movwf positionTop5		;Jsme v Top5, uloz pozici rekordu
	
	call show_YouMadeItToTop5
	call playTop5Fanfare
	call wait1s
	call wait1s
	
	call adjustTop5			;Proved nutne presuny v Top5
	
	call storeScoreToTop5
	
	call show_HallOfFame	;Ukaz svetu Top5
	
	call enterTop5Name
	
	movlw .250				;Aby dohral zvuk ENTER name
	call waitMilis
	
	call playTop5NameHotovo
	
	call EEPROM_saveTop5	;Uloz Top5 do EEPROM
		
	call wait1s
	call wait1s
	call wait1s
	call wait1s
	
	goto GAME_START
	
notInTop5
	call waitAnyKey
	call wait1s
	goto GAME_START
;}
;

; *******************************************************************
; ************ H E R N I    R U T I N Y *****************************
; *******************************************************************

;v positionTop5 je pozice 1-5, kam vkladam
enterTop5Name
;{

		;250ms mezi blikanimi vkladaneho pismene
		clrf timerON			;prepinac
		movlw .250
		movwf timer0_counter	
		movwf timer0_copy
				
		bsf STATUS, IRP

		call getTop5PositionOffset	;Spocitej offset v EEPROM_Top5
		movwf tmp
		
		movlw low(EEPROM_Top5)
		addwf tmp, w
		movwf FSR				;Jsme na spravne pozici v EEPROM_Top5
		
		movlw 'A'
		movwf tmpChar
		
		movlw .0
		movwf i					;0,1,2 - ktery znak inicial vkladam
		
		movlw .37
		movwf x					;X-pozice prvniho znaku inicial
		
		decf positionTop5, f	;1-5 => 0-4
		movlw .3
		addwf positionTop5, w	;0-4 => 3-7	
		movwf y
		
enterTop5Loop
		call getTop5Key			;1,2,4 = GREEN, WHITE, START ve W-REG
		movwf tmp
		btfss tmp, 0			;GREEN?
		goto notGreen
		call playTop5PismenoZmena
		decf tmpChar, f			;O znak nize
		movlw '@'
		subwf tmpChar, w
		btfss STATUS, Z			;Jsme pod 'A'?
		goto enterTopPrint		;Ne, tiskni znak
		movlw 'Z'				;Ano, roll-over na 'Z'
		movwf tmpChar
		goto enterTopPrint		
notGreen
		btfss tmp, 1			;WHITE?
		goto notWhite
		call playTop5PismenoZmena
		incf tmpChar, f			;O znak vyse
		movlw '['
		subwf tmpChar, w
		btfss STATUS, Z			;Jsme za 'Z'?
		goto enterTopPrint		;Ne, tiskni znak
		movlw 'A'				;Ano, roll-over na 'A'
		movwf tmpChar
		goto enterTopPrint
notWhite						;Mame START, zjisti, jestli uz nemame
		btfss tmp, 2			;vsechny 3 inicialy vlozene?
		goto enterNoPress		
		movf tmpChar, w
		movwf INDF
		incf FSR, f
		
		;Zobraz vybrany znak (pri blikani mohla byt zrovna videt ' '
		call setTop5PositionXY
		movf tmpChar, w
		call ssd1306_printChar
		
		call playTop5PismenoEnter		
		
		movlw .6				;sirka pismene 6
		addwf x, f				;posun x-ovou o sirku pismene
		
		incf i, f				
		movlw .3				
		subwf i, w				
		btfsc STATUS, Z			;mame 3?	
		return					;hotovo, vlozeno
		
		movlw 'A'				;dalsi pozice inicial, od 'A'
		movwf tmpChar
		goto enterTopPrint			
		
enterNoPress
		movlw .1
		call waitMilis
		decfsz timer0_counter, f
		goto enterTop5Loop
		movf timer0_copy, w
		movwf timer0_counter
		movlw ' '				
		btfss timerON, 0		;Vypis na pozici mezeru nebo tmpChar		
		movf tmpChar, w
		movwf poradi_tmp
		call setTop5PositionXY
		movf poradi_tmp, w
		call ssd1306_printChar
	
enterNopressFinish
		movlw .1				;0->1, 1->0
		xorwf timerON, f
		goto enterTop5Loop

enterTopPrint
		call setTop5PositionXY
		movf tmpChar, w
		call ssd1306_printChar
		
		movlw .100				;Chvili pockej
		call waitMilis
		
		goto enterTop5Loop
		
enterTop5Finish
		bcf STATUS, IRP
		return
;}		
		
;Nastav X,Y pro tisk znaku inicialy		
setTop5PositionXY
;{
		movf x, w	
		movwf ssd1306_X
		movlw .90
		movwf ssd1306_X_max
		
		movf y, w
		movwf ssd1306_Y
		movwf ssd1306_Y_max		;zustavame na stejnem radku

		goto ssd1306_setXY
;}
		
		
;Cekej na stisk tlacitka GREEN, WHITE a nebo START
;GREEN = <	(posun na predchozi pismeno)
;YELLOW = >  (posun na dalsi pismeno)
;WHITE = potvrd pismeno a posun na dalsi nebo konec vkladani
;Vrat 1,2,4 = GREEN, YELLOW, WHITE ve W-REG, 0=NIC
getTop5Key
;{		

getTop5KeyLoop
		btfsc B_GREEN
		goto haveGreen
		btfsc B_YELLOW
		goto haveYellow
		btfsc B_WHITE
		goto haveWhite
		retlw .0

haveGreen
		movlw .10
		call waitMilis
		btfss B_GREEN
		retlw .0
haveGreenL
		btfsc B_GREEN
		goto haveGreenL
		retlw .1
haveYellow
		movlw .10
		call waitMilis
		btfss B_YELLOW
		retlw .0
haveYellowL
		btfsc B_YELLOW
		goto haveYellowL
		retlw .2
haveWhite
		movlw .10
		call waitMilis
		btfss B_WHITE
		retlw .0
haveWhiteL
		btfsc B_WHITE
		goto haveWhiteL
		retlw .4
;}
		
;Na pozici positionTop5 v Top5 uloz nove jmeno a score
storeScoreToTop5
;{
	call getTop5PositionOffset
	movwf tmp
	
	bsf STATUS, IRP
	movlw low(EEPROM_Top5)
	addwf tmp, w		;Nastav se na spravnou pozici v Top5
	movwf FSR
	movlw 'A'			;Vypln pozici 'A  ' <game_Score>
	movwf INDF
	incf FSR, f
	movlw ' '
	movwf INDF
	incf FSR, f
	movlw ' '
	movwf INDF
	incf FSR, f
	movf game_Score+0, w
	movwf INDF
	incf FSR, f
	movf game_Score+1, w
	movwf INDF			
	
	bcf STATUS, IRP
	
	return
;}
	
;1=0,2=5;3=10,4=15,5=20
getTop5PositionOffset
;{
	movf positionTop5, w
	movwf tmp
getPos1
	decfsz tmp, f
	goto getPos2
	retlw .0
getPos2
	decfsz tmp, f
	goto getPos3
	retlw .5
getPos3
	decfsz tmp, f
	goto getPos4
	retlw .10
getPos4
	decfsz tmp, f
	goto getPos5
	retlw .15
getPos5
	retlw .20
;}
	
;Proved posuny radku v Top5 (odsun pozice nize)
adjustTop5
;{

	;Kopirujeme v poradi 4->5, 3->4, 2->3, 1->2
	;podle ukladane pozice do Top5

	bsf STATUS, IRP			;Pracujeme s FSR v BANK2
	
	movlw low(EEPROM_Top5)+.15	;na 4. pozici v Top5
	movwf copyFrom			;uloz FSR 
	
	movlw low(EEPROM_Top5)+.20	;5. pozice
	movwf copyTo

	movlw .5		
	movwf i				;i = 5
	movf positionTop5, w
	subwf i, f			;i = 5 - pozice
adjustTop5Loop
	movf i, f			;i==0?
	btfsc STATUS, Z
	goto adjustTop5Finish	;Hotovo
	
	call copyTop5Line
	
	decf i, f
	goto adjustTop5Loop
	
adjustTop5Finish
	bcf STATUS, IRP
	return
;}

;Kopiruj lajnu copyFrom -> copyTo
copyTop5Line
;{
	movlw .5
	movwf j
copyTop5Loop
	movf copyFrom, w
	movwf FSR
	movf INDF, w
	movwf tmp
	movf copyTo, w
	movwf FSR
	movf tmp, w
	movwf INDF
	incf copyFrom, f
	incf copyTo, f
	decfsz j, f
	goto copyTop5Loop
	movlw .10
	subwf copyFrom, f		;Posun o pozici v Top5 zaznamech vyse
	subwf copyTo, f
	return
;}
		
;Zjisti, jestli neni score na zapis do Top5
;Vrat carry, pokud ano a ve W-REG je cislo pozice v Top5
checkScore
;{
	movlw .5
	movwf j				;maximalne 5 cyklu 

	movlw .6			;v i bude ulozene 1-5, pokud mame rekord,
	movwf i				;nebo 6, pokud neni score v top5

	bsf STATUS, IRP		;FSR v BANK2
	movlw low(EEPROM_Top5)+.25-.2
	movwf FSR
	
checkScoreLoop			;jedeme v top5 odspodu
	movf INDF, w	
	movwf tmp16bit+0	;hiByte
	incf FSR, f
	movf INDF, w
	movwf tmp16bit+1	;loByte
	
	call isScoreGreater ;porovnej tmp16bit a game_Score
	btfss STATUS, C		;game_Score > tmp16bit
	goto checkScoreFinish
	decf i, f			;posun v top5
	movlw .6
	subwf FSR, f		;posun v tabulce na predchozi zaznam v top5
	decfsz j, f
	goto checkScoreLoop	
	
checkScoreFinish		;Nastav carry, pokud jsme <6
	bcf STATUS, IRP
	movlw .6
	subwf i, w
	bsf STATUS, C		;Nastav carry, kdyz tak ho shodim
	btfsc STATUS, Z
	bcf STATUS, C		;jsme 6, nejsme v top5
	movf i, w			;Nemeni carry, vrat Wreg s pozici v top5 pri carry	
	return
;}
	
;Vrat CARRY, pokud je game_Score > tmp16bit
isScoreGreater
;{
	movf tmp16bit+0, w		;vyssi byte
	subwf game_Score+0, w
	btfss STATUS, C			;je game_Score+0 >= ?
	return					;Vrat se se shozenym CARRY
	;Jestli je vyssi byte ostre vetsi, uz dale netestuj a nahod CARRY
	btfss STATUS, Z			;pri rovnosti testuj dale
	return
	movf tmp16bit+1, w
	subwf game_Score+1, w	;nizsi byte
	btfss STATUS, C			;nizsi byte mensi, konec
	return
	;pokud je nastavene ZERO, mame rovnost, tzn. game_Score neni
	;ostre vetsi => nenastavim CARRY
	btfsc STATUS, Z
	bcf STATUS, C			;game_Score = tmp16bit
	return
;}
	
;Nastav casomiru a dobu, do ktere je potreba zopakovat sled
;Zatim je to (2 x pocetBlinkuti) sekund
setTimer
;{
	bcf STATUS, C
	rlf poradi_kolik, w
	movwf game_Timer
	return
;}

;Zkontroluj, jestli uz nemame tolik stisku buttonu, kolik mel
;hrac zopakovat a vrat ZERO, pokud ano
checkLevelCompleted
;{
		movf poradi_i, w
		subwf poradi_kolik, w
		return
;}

;Zkontroluj, zda prave stisknuty button (whichButton) je spravny
checkButtonPress
;{
	
		;preved cislo poradi a nastav odpovidajici bit zprava
		movlw .1
		movwf poradi_tmp
		
		movf INDF, w
		movwf i					;v i je poradi
checkLoop
		movf i, f
		btfsc STATUS, Z
		goto checkButtonNext
		decf i, f
		bcf STATUS, C
		rlf poradi_tmp, f
		goto checkLoop

checkButtonNext
		incf poradi_i, f		;Jdi na dalsi pozici v poradi
		incf FSR, f	
		clrf buttonPressed
		
		movf whichButton, w
		andwf poradi_tmp, w		;ZERO=chybny stisk
		btfss STATUS, Z
		goto handleScore 
		return
handleScore
		call game_IncScore		;Dobry stisk, zvys score
		movlw TRUE
		movwf scoreChanged		;Prekresli score
		bcf STATUS, Z
		return
;}

;Kazdych 10ms vyhodnot stav buttonu	
evalButtonPress
;{
		btfss evalButtons, 0 ;pokracuj, pokud preruseni naplnilo porta_save
		return
			
		btfsc expState, 0	;cekame na uvodni log 1?
		goto expRead
		btfsc expState, 1   ;cekame na debounce log 1
		goto expDebounce
		btfsc expState, 2   ;cekame na pusteni buttonu, log 0
		goto expRelease
		
expRead	
		clrf whichButton	
		btfsc porta_save, 0
		bsf whichButton, 0
		btfsc porta_save, 1
		bsf whichButton, 1
		btfsc porta_save, 2
		bsf whichButton, 2
		btfsc porta_save, 3
		bsf whichButton, 3
		btfsc porta_save, 4
		bsf whichButton, 4
		;whichButton == 0, zadny stisk, !=0 nektery button stisknut

		movf whichButton, f	;Mame nejaky stisk?
		btfsc STATUS, Z
		goto evalFinish		;Nic nebylo, cekame dal na nejaky stisk
		
		movlw EXP_DEBOUNCE	;Jinak prejdi na dalsi stav
		movwf expState
		goto evalFinish

expDebounce
		;Ve whichButton <4:0> mam 1 na pozici buttonu 5-1
		;Zkontroluj porta_save s whichButton, mam-li na stejnem buttonu
		;log 1
		
		movf porta_save, w
		andlw b'00011111'	;zajima nas 5 nejnizsich bitu
		movwf porta_save
		movf whichButton, w
		andwf porta_save, w
		btfsc STATUS, Z
		goto debounceFail
		
		movlw EXP_RELEASE	;cekame na release buttonu
		movwf expState
		goto evalFinish
		
debounceFail				;Na danem buttonu nebyla log 1
		movlw EXP_READ
		movwf expState
		goto evalFinish
		
expRelease
		movf porta_save, w
		andlw b'00011111'	;zajima nas 5 nejnizsich bitu
		movwf porta_save
		movf whichButton, w
		andwf porta_save, w
		btfss STATUS, Z
		goto evalFinish		;tlacitko porad stiskle, cekej dal
		
		;Vycisti predchozi svitici LEDky
		bcf LED_1
		bcf LED_2
		bcf LED_3
		bcf LED_4
		bcf LED_5
		
		;zapni LEDku podle which Button
		btfsc whichButton, 0
		goto lightLED1
		btfsc whichButton, 1
		goto lightLED2
		btfsc whichButton, 2
		goto lightLED3
		btfsc whichButton, 3
		goto lightLED4
		btfsc whichButton, 4
		goto lightLED5
lightLED1	
		bsf LED_1
		goto releaseFinish
lightLED2	
		bsf LED_2
		goto releaseFinish
lightLED3
		bsf LED_3
		goto releaseFinish
lightLED4
		bsf LED_4
		goto releaseFinish
lightLED5
		bsf LED_5
				
releaseFinish
		movlw TRUE
		movwf buttonPressed	;Muzem uz kontrolovat spravnost
		movlw EXP_READ		;Inicializuj stav pro dalsi stisky
		movwf expState
				
evalFinish
		clrf evalButtons	;Cekej na dalsich 10ms a vyhodnot
		clrf porta_save		;Vycisti ulozeny stav buttonu
		return				
;}


;Cekej na stisk tlacitka
waitAnyKey
;{
		btfsc B_GREEN		;Pri stisku vyskoc
		goto waitEnd
		btfsc B_BLUE
		goto waitEnd
		btfsc B_RED
		goto waitEnd
		btfsc B_YELLOW
		goto waitEnd
		btfsc B_WHITE
		goto waitEnd
		goto waitAnyKey
waitEnd						;Pockej na konec stisku
		movf PORTA, w
		andlw b'00011111'
		btfss STATUS, Z
		goto waitEnd
		return
;}
	
game_Init
;{
		movlw INIT_NUM_LIVES
		movwf game_Lives
		movlw INIT_PORADI_KOLIK
		movwf poradi_kolik
		movwf game_Leds

	    clrf game_Level
		
		movlw .3				;Kolik LEDek zablika
		movwf poradi_kolik		
		
		clrf threeCounter
	
		clrf game_Score+0
		clrf game_Score+1		
		clrf scoreChanged
		return
;}

;Pricti 10bodu ke score
game_IncScore
;{
		movlw .10
		addwf game_Score+1, f
		btfss STATUS, C
		return
		incf game_Score+0, f
		return
;}

game_IncLevel
;{
		incf game_Level, f

		;Zajisti, ze se zvysuje pocet bliknuti kazde 3 levely,
		;tj. 3,3,3,4,4,4,5,5,5,6,6,6....		

		incf threeCounter, f
		movlw .3
		subwf threeCounter, w

		btfss STATUS, Z
		return
		incf poradi_kolik, f

		clrf threeCounter

		movf poradi_kolik, w
		movwf game_Leds
		return
		
;}


game_DecLeds
;{
		decf game_Leds, f
		return
;}

game_DecLives
;{
		decf game_Lives, f
		return
;}

;Nacti obtiznost (1-Green, 2-Blue, 3-Red, 4-Yellow, 5-white button)
readDifficulty
;{
		call getDiffButtonPress
		movwf difficulty		
		return
;}

;Pro button 1 (Green) vrat 5
;...
;Pro button 5 (White) vrat 1
;Vracene hodnoty budou slouzit jako nasobky pro pauzy, proto opacne
;poradi
getDiffButtonPress
;{
		btfsc B_GREEN		;Pri stisku vyskoc
		retlw .5
		btfsc B_BLUE
		retlw .4
		btfsc B_RED
		retlw .3
		btfsc B_YELLOW
		retlw .2
		btfsc B_WHITE
		retlw .1
		goto getDiffButtonPress
;}

nastavPoradi
;{
		movf poradi_kolik, w
		movwf k
				
		movlw poradi		
		movwf FSR			;Budeme postupne ukladat nahodna cisla
nastavP call generateRandomNumber
		movf RNDret, w			;Nahodne cislo vraceno v RNDret
		movwf INDF
		incf FSR, f
		decfsz k, f
		goto nastavP
		return
;}

prehrajPoradi
;{
		movf poradi_kolik, w
		movwf k

		movlw poradi
		movwf FSR

prehraj movf INDF, w			;Ziskej cislo LEDky

		movwf i					;Uloz, budeme potrebovat pro zhasnuti
		call rozsvitCislo
		call prehrajPauza
		
		movf i, w
		call zhasniCislo		;Zhasni rozsvicenou LEDku
		call prehrajPauza

		incf FSR, f
		decfsz k, f
		goto prehraj
				
		movlw poradi			;Zopakuj inicializaci pro kontrolu ve hre
		movwf FSR
		
		clrf poradi_i			;Inicializuj iterator pro pruchod poradim
		
		return
;}

;Pauza podle difficulty
;1 = 5x200ms
;2 = 4x200ms
;3 = 3x200ms
;4 = 2x200ms
;5 = 1x200ms
prehrajPauza
;{
		movf difficulty, w
		movwf j					;cekej difficulty * 300ms
prehrajWait
		call waitDifficulty
		decfsz j, f
		goto prehrajWait
		return
;}

;ve WREG je 0-4 cislo LEDky, kterou rozsvitit na 1 sec
rozsvitCislo
;{
		movwf tmp
rozsvit5
		movlw .252
		addwf tmp, w
		btfss STATUS, C
		goto rozsvit4
		bsf LED_5
		return
rozsvit4
		movlw .253
		addwf tmp, w
		btfss STATUS, C
		goto rozsvit3
		bsf LED_4
		return
rozsvit3
		movlw .254
		addwf tmp, w
		btfss STATUS, C
		goto rozsvit2
		bsf LED_3
		return
rozsvit2
		movlw .255
		addwf tmp, w
		btfss STATUS, C
		goto rozsvit1
		bsf LED_2
		return
rozsvit1
		bsf LED_1
		return
;}

zhasniCislo
;{
		movwf tmp
zhasni5
		movlw .252
		addwf tmp, w
		btfss STATUS, C
		goto zhasni4
		bcf LED_5
		return
zhasni4
		movlw .253
		addwf tmp, w
		btfss STATUS, C
		goto zhasni3
		bcf LED_4
		return
zhasni3
		movlw .254
		addwf tmp, w
		btfss STATUS, C
		goto zhasni2
		bcf LED_3
		return
zhasni2
		movlw .255
		addwf tmp, w
		btfss STATUS, C
		goto zhasni1
		bcf LED_2
		return
zhasni1
		bcf LED_1
		return
;}

zhasniVse
;{
		;Vycisti predchozi svitici LEDky
		bcf LED_1
		bcf LED_2
		bcf LED_3
		bcf LED_4
		bcf LED_5
		return
;}
;routine example if you call RandomNumber many times in your code
;returns random number 0-4 in WREG
generateRandomNumber
;{
		RandomM	RNDval,RNDtmp	;Zavolej makro
		movf TMR0, w
		xorwf RNDval, w
		movwf RNDtmp

		;0-50		= 0
		;51-100		= 1
		;101-150	= 2		
		;151-200	= 3
		;201-255	= 4
		
		movlw .4	;zaciname od nejvyssi hranice
		movwf RNDret	;vracime j
		bcf STATUS, C
		movlw .55		;201-255
		addwf RNDtmp, w
		btfsc STATUS, C	;preskocili jsme 255?
		return			;j = 4
		decf RNDret, f
		movlw .105
		addwf RNDtmp, w
		btfsc STATUS, C
		return			;j = 3
		decf RNDret, f
		movlw .155
		addwf RNDtmp, w
		btfsc STATUS, C
		return			;j = 2
		decf RNDret, f
		movlw .205
		addwf RNDtmp, w
		btfsc STATUS, C
		return			;j = 1
		decf RNDret, f
		return			;j = 0
;}



;*******************************************************************
;******************* WT588D - prehravani zvuku cislo numSound ******
;*******************************************************************	

playIntroSound
;{
	movlw SOUND_00_INTRO
	goto doSoundFX
;}

playMeziObrazovkami
;{
	movlw SOUND_01_MEZI_OBRAZOVKAMI
	goto doSoundFX
;}
	
playGetReadyCink
;{
	movlw SOUND_02_CINK_GET_READY
	goto doSoundFX
;}

playClockTicking
;{
	movlw SOUND_03_TICKING
	call doSoundFX
	movlw .10
	call waitMilis
	movlw 0xF2			;loop aktualne prehravaneho zvuku
	goto doSoundFX	
;}
	
playBuzzerTimesUp
;{
	movlw SOUND_04_BUZZER_TIME_UP
	goto doSoundFX
;}

playLevelFailed
;{
	movlw SOUND_05_LEVEL_FAILED
	goto doSoundFX
;}
	
playLevelCompleted
;{
	movlw SOUND_06_LEVEL_COMPLETED
	goto doSoundFX
;}

playCorrect
;{
	movlw SOUND_07_CORRECT
	goto doSoundFX
;}

playIncorrect
;{
	movlw SOUND_08_INCORRECT
	goto doSoundFX
;}

playGameOver
;{
	movlw SOUND_09_GAME_OVER
	goto doSoundFX
;}

playTop5Fanfare
;{
	movlw SOUND_0A_FANFARE_TOP5
	goto doSoundFX
;}

playTop5PismenoZmena
;{
	movlw SOUND_0B_TOP5_PISMENO_ZMENA
	goto doSoundFX
;}

playTop5PismenoEnter
;{
	movlw SOUND_0C_TOP5_PISMENO_ENTER
	goto doSoundFX
;}

playTop5NameHotovo
;{
	movlw SOUND_0D_TOP5_NAME_HOTOVO
	goto doSoundFX
;}

doSoundFX
;{
		movwf wt588d_tmp
	
		;Nastav SCK a CS na log. 1
		movlw b'01100000'		;SCK log. 1, CS log. 1
		movwf PORTB
		
		movlw .17
		call waitMilis
		
		movlw b'00100000'		;SCK log. 1, CS log. 0
		movwf PORTB				;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 wt588d_i
		
cycle	bcf WT588D_SCK		;Clock na log. 0, zaciname prenos dat			

		btfss wt588d_tmp, 0;  bit 0 nastaven?
		goto btNotSet
		bsf WT588D_SDA		 ; ano, posli log 1
		goto tsted
btNotSet bcf WT588D_SDA		; ne, posli log 0 na vystup
tsted	call wait30us

		bsf WT588D_SCK		;Clock na log. 1, skoncili jsme prenos 1 bitu	
		call wait30us

		rrf wt588d_tmp, f
		decfsz wt588d_i, f
		goto cycle

		movlw b'01100000'	;SDA log. 0, CS log. 1, SCK log. 1
		movwf PORTB			;Slave Select = HI

		return
;}


;*******************************************************************
;******************* ZAPINANI/VYPINANI TIMERU1 pro odpocet *********
;*******************************************************************	
	
; *** START TIMER1
startTimer1
;{
	BANK1
	bsf PIE1, TMR1IE
	BANK0
	
	movlw NUM_INTRS_TMR1
	movwf timer1_counter
	movwf timer1_copy

	; *** INIT TIMER1 - nastav na 48576		
	movlw 0x7B
	movwf TMR1H
	movlw 0x80
	movwf TMR1L

	bsf INTCON, PEIE		;Peripheral interrupt pro Timer1	

	movlw b'00000101'		;Prescaler 1:1, internal, Timer1 ON
	movwf T1CON

	movlw TRUE
	movwf timerON
	return
;}
	
; *** STOP TIMER1
stopTimer1
;{

	movlw b'00000100'		;Prescaler 1:1, internal, Timer1 OFF
	movwf T1CON
	
	movlw FALSE
	movwf timerON

	bcf INTCON, PEIE		;Peripheral interrupt pro Timer1 - OFF

	BANK1
	bcf PIE1, TMR1IE
	BANK0
	return
;}

;*******************************************************************
;******************* ZAPINANI/VYPINANI PRERUSENI *******************
;*******************************************************************

disableInterrupts
;{
	call stopTimer1			;Zakaz Timer1 preruseni
	bcf INTCON, T0IE    	;Zakaz Timer0 interrupt
	bcf INTCON, GIE	    	;Zakaz vsechna preruseni
	clrf TMR0
	clrf T2CON				;Nepouzivej Timer2
	BANK1
	bcf PIE1, TMR2IE
	BANK0
	return
;}

enableInterrupts
;{
	;stavy buttonu, ocekavame log 1 na kteremkoliv buttonu
	clrf whichButton
	clrf buttonPressed
	clrf evalButtons
	movlw EXP_READ
	movwf expState
			
	clrf timeUp
	clrf redrawTimer
	clrf evalButtons
	clrf porta_save
	
	call startTimer1		;Povol Timer1 preruseni - odpocet
	
	movlw NUM_INTRS_TMR0
	movwf timer0_counter	;80 * 128us = 10240us =~ 10ms
	movwf timer0_copy
	bsf INTCON, T0IE    	;Povol Timer0 interrupt
	clrf TMR0
	bcf INTCON, T0IF		;Workaround, aby se hned TMR0IF nenastavil
	bsf INTCON, GIE	    	;Povol vsechna preruseni
	return
;}

;*******************************************************************
;******************* E E P R O M   R U T I N Y *********************
;*******************************************************************

eeprom_setAddr
;{
	;Send read sequence (READ 0x03), read address 0x55
	;Read potrebuje 24bit adresu (3 bytes)
	;v eeprom_i je pocet bajtu
	bcf EEPROM_CS			; Zacatek read operace

	movlw 0x03              ; Load READ sequence
	call eeprom_output      ; Call the SPI output routine	

	movf eeprom_addr+0, w   ; Load high address byte	
	call eeprom_output      ; Call the SPI output routine
	movf eeprom_addr+1, w   ; Load high address byte	
	call eeprom_output		; Call the SPI output routine
	movf eeprom_addr+2, w	; Load low address byte
	call eeprom_output		; Call the SPI output routine
	return

eeprom_read
	movlw DUMMY_BYTE		; Prijem byte, posli dummy hodnotu	
	call eeprom_output		; Call output to read 1 byte
	return

eeprom_end
	bsf EEPROM_CS			; Konec readu
	return		
 
eeprom_output 
	movwf SSPBUF			; Place data in send buffer
	BANK1
ee_loop
    btfss SSPSTAT, BF		; Has data been received?
	;nop
	goto ee_loop			; Loop if not received yet
	BANK0
    movf SSPBUF, w			; Empty the receive buffer
  	movwf eeprom_rx			; Put received byte into rxdata
  	return
;}                       

; ******************************************************************
; ******************** SSD1306 I2C DISPLAY DRIVER ******************
; ******************************************************************		
ssd1306_init	
;{		
			call wait1s

			movlw SSD1306_DISPLAYOFF			;0xAE
			call i2c_sendCmd

			movlw SSD1306_SETDISPLAYCLOCKDIV 	;0xD5
			call i2c_sendCmd
			movlw 0x80				
			call i2c_sendCmd

			movlw SSD1306_SETMULTIPLEX			;0xA8
			call i2c_sendCmd
			;movlw 0x1F		;128x32
			movlw 0x3F		;128x64
			call i2c_sendCmd
			
			movlw SSD1306_SETDISPLAYOFFSET		;0xD3
			call i2c_sendCmd
			movlw 0x00
			call i2c_sendCmd

			movlw SSD1306_SETSTARTLINE			;0x40
			call i2c_sendCmd

			movlw SSD1306_CHARGEPUMP			;0x8D
			call i2c_sendCmd
			movlw 0x14
			call i2c_sendCmd

			movlw SSD1306_MEMORYMODE			;0x20
			call i2c_sendCmd
			movlw 0x00			;horizontal addressing
			call i2c_sendCmd
			
			movlw SSD1306_SEGREMAP | 0x01		;0xA1			
			call i2c_sendCmd	;rotate screen 180

			movlw SSD1306_COMSCANDEC			;0xC8
			call i2c_sendCmd

			movlw SSD1306_SETCOMPINS			;0xDA
			call i2c_sendCmd
			movlw 0x12		;128x64		
			;movlw 0x02		;128x32
			call i2c_sendCmd			

			movlw SSD1306_SETCONTRAST			;0x81
			call i2c_sendCmd
			movlw 0x8F
			call i2c_sendCmd

			movlw SSD1306_SETPRECHARGE			;0xD9
			call i2c_sendCmd
			movlw 0xF1
			call i2c_sendCmd

			movlw SSD1306_SETVCOMDETECT			;0xDB
			call i2c_sendCmd
			movlw 0x40
			call i2c_sendCmd

			movlw SSD1306_DISPLAYALLON_RESUME	;0xA4
			call i2c_sendCmd

			movlw SSD1306_NORMALDISPLAY			;0xA6
			call i2c_sendCmd

			movlw SSD1306_DEACTIVATE_SCROLL 	;0x2E
			call i2c_sendCmd

			movlw SSD1306_DISPLAYON				;0xAF
			call i2c_sendCmd

			call ssd1306_clearDisplay

			goto ssd1306_setHome				;pos 0,0
;}


ssd1306_setHome
;{
			movlw SSD1306_COLUMNADDR
			call i2c_sendCmd
			movlw 0x00						;X - pos 0
			call i2c_sendCmd
			movlw SSD1306_COLS_NUM-1		;X - pos max
			call i2c_sendCmd

			movlw SSD1306_PAGEADDR
			call i2c_sendCmd
			movlw 0x00						;Y - pos 0
			call i2c_sendCmd
			movlw SSD1306_PAGES_NUM-1		;Y - pos MAX
			goto i2c_sendCmd
;}

ssd1306_setXY
;{
			movlw SSD1306_COLUMNADDR
			call i2c_sendCmd
			movf ssd1306_X, w				
			call i2c_sendCmd
			movf ssd1306_X_max, w			;X - pos max
			call i2c_sendCmd

			movlw SSD1306_PAGEADDR
			call i2c_sendCmd
			movf ssd1306_Y, w
			call i2c_sendCmd
			movf ssd1306_Y_max, w			;Y - pos MAX
			goto i2c_sendCmd
;}




;Po zavolani setXY nastavi rezim posilani dat
ssd1306_setXY2
;{
			call ssd1306_setXY

			call i2c_startCond

			call i2c_sendAddr

			movlw I2C_CTRL_BYTE_D
			goto i2c_sendByte2
;}

ssd1306_clearDisplay
;{
			call ssd1306_setHome
	
			call i2c_startCond

			call i2c_sendAddr

			movlw I2C_CTRL_BYTE_D
			call i2c_sendByte2

			movlw SSD1306_PAGES_NUM 
			movwf i

ssd1306_i	movlw SSD1306_COLS_NUM		
			movwf j

ssd1306_j	clrw				
			call i2c_sendByte2
			
			
			decfsz j, f
			goto ssd1306_j
		
			decfsz i, f
			goto ssd1306_i

			goto i2c_stopCond
;}



; ***** OLED: I2C: SEND START CONDITION


; ******************************************************************
; ************** Z O B R A Z   T E X T Y ***************************
; ******************************************************************

;HEX OFFSET: 0x0, OFFSET: 0, FILE SIZE: 1342, FILE: 0-Proportional font(16height).bin
;HEX OFFSET: 0x53E, OFFSET: 1342, FILE SIZE: 1024, FILE: 1-AlzGamer_Splash(128x64).txt.bin
;HEX OFFSET: 0x93E, OFFSET: 2366, FILE SIZE: 256, FILE: 2-Alzgamer_HallOfFame(128x16).txt.bin
;HEX OFFSET: 0xA3E, OFFSET: 2622, FILE SIZE: 1024, FILE: 3-AlzGamer_Instructions(128x64).txt.bin
;HEX OFFSET: 0xE3E, OFFSET: 3646, FILE SIZE: 1024, FILE: 4-AlzGamer_Difficulty(128x64).txt.bin
;HEX OFFSET: 0x123E, OFFSET: 4670, FILE SIZE: 512, FILE: 5-AlzGamer_GetReady(128x32).txt.bin
;HEX OFFSET: 0x143E, OFFSET: 5182, FILE SIZE: 512, FILE: 6-AlzGamer_NowRepeat(128x32).txt.bin
;HEX OFFSET: 0x163E, OFFSET: 5694, FILE SIZE: 512, FILE: 7-AlzGamer_1LifeLost(128x32).txt.bin
;HEX OFFSET: 0x183E, OFFSET: 6206, FILE SIZE: 512, FILE: 8-AlzGamer_TimesUp(128x32).txt.bin
;HEX OFFSET: 0x1A3E, OFFSET: 6718, FILE SIZE: 512, FILE: 9-AlzGamer_GameOver(128x32).txt.bin
;HEX OFFSET: 0x1C3E, OFFSET: 7230, FILE SIZE: 108, FILE: A-AlzGamer_Fajfka.txt.bin
;HEX OFFSET: 0x1CAA, OFFSET: 7338, FILE SIZE: 108, FILE: B-AlzGamer_Krizek.txt.bin
;HEX OFFSET: 0x1D16, OFFSET: 7446, FILE SIZE: 512, FILE: C-AlzGamer_EmptyBox.txt.bin
;HEX OFFSET: 0x1F16, OFFSET: 7958, FILE SIZE: 108, FILE: D-AlzGamer_EmptyCircle.txt.bin
;HEX OFFSET: 0x1F82, OFFSET: 8066, FILE SIZE: 512, FILE: E-AlzGamer_EnterName.txt.bin
;HEX OFFSET: 0x2182, OFFSET: 8578, FILE SIZE: 512, FILE: F-AlzGamer_LevelComplete.txt.bin
;HEX OFFSET: 0x2382, OFFSET: 9090, FILE SIZE: 512, FILE: G-AlzGamer_LevelPressStart.txt.bin
;HEX OFFSET: 0x2582, OFFSET: 9602, FILE SIZE: 512, FILE: H-AlzGamer_NewRecord.txt.bin


show_SplashScreen
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x05
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x64
;}

show_HallOfFame		
;{
		call ssd1306_clearDisplay

		;128x16
		movlw .0	
		movwf ssd1306_X
		movlw SSD1306_COLS_NUM-1
		movwf ssd1306_X_max

		movlw .0
		movwf ssd1306_Y
		movlw .1				
		movwf ssd1306_Y_max

		movlw 0x00
		movwf eeprom_addr
		movlw 0x09
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		call ssd1306_drawBitmap

		goto show_Top5
;}

show_Top5
;{
		bsf STATUS, IRP		;BANK2 FSR
		movlw TOP5_TABLE_ADDR
		movwf FSR

		movlw .5				;Top 5
		movwf i

		movlw TRUE				;Sazime znak po znaku
		movwf putCharOnly

		movlw .37	
		movwf ssd1306_X
		movlw .90
		movwf ssd1306_X_max

		movlw .3
		movwf ssd1306_Y
		movlw .7
		movwf ssd1306_Y_max

		call ssd1306_setXY

		call i2c_startCond		;Posilej dal jen znaky
		call i2c_sendAddr

		movlw I2C_CTRL_BYTE_D
		call i2c_sendByte2

show_Tloop

		;3 znaky inicialy
		movf INDF, w
		call ssd1306_putChar
		incf FSR, f
		movf INDF, w
		call ssd1306_putChar
		incf FSR, f
		movf INDF, w
		call ssd1306_putChar
		incf FSR, f
	
		;mezera
		movlw ' '
		call ssd1306_putChar

		;body (5 znaku)
		movf INDF, w
		movwf util_NumH
		incf FSR, f
		movf INDF, w
		movwf util_NumL
		incf FSR, f
		call bin16_to_ascii

		movf util_TenK, w
		call ssd1306_putChar
		movf util_Thou, w
		call ssd1306_putChar
		movf util_Hund, w
		call ssd1306_putChar
		movf util_Tens, w
		call ssd1306_putChar
		movf util_Ones, w
		call ssd1306_putChar

		decfsz i, f
		goto show_Tloop

		call i2c_stopCond

		movlw FALSE			;Vrat zpet, pokud jsme nahodou vnoreni
		movwf putCharOnly

		bcf STATUS, IRP		;BANK0/1 FSR
		return
;}

show_Instructions
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x0A
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x64
;}


show_Difficulty
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x0E
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x64
;}


show_GetReady
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x12
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32
;}

show_NowRepeat
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x14
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32
;}

show_1LifeLost
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x16
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32
;}

show_TimeIsUp
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x18
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32
;}


show_GameOver
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x1A
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32
;}

show_Common27x32
;{
		;27x32
		movlw .50
		movwf ssd1306_X
		movlw .50+.27-.1
		movwf ssd1306_X_max

		movlw .4
		movwf ssd1306_Y
		movlw SSD1306_PAGES_NUM-1
		movwf ssd1306_Y_max
		
		goto ssd1306_drawBitmap
;}

show_Common128x32
;{
		;128x32
		movlw .0
		movwf ssd1306_X
		movlw SSD1306_COLS_NUM-1
		movwf ssd1306_X_max

		movlw .4
		movwf ssd1306_Y
		movlw SSD1306_PAGES_NUM-1
		movwf ssd1306_Y_max
		
		goto ssd1306_drawBitmap
;}

show_Common128x64
;{
		;128x64
		movlw .0	
		movwf ssd1306_X
		movlw SSD1306_COLS_NUM-1
		movwf ssd1306_X_max

		movlw .0
		movwf ssd1306_Y
		movlw SSD1306_PAGES_NUM-1
		movwf ssd1306_Y_max
		
		goto ssd1306_drawBitmap
;}

show_Correct
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x1C
		movwf eeprom_addr+1		;high byte offset
		movlw 0x3E
		movwf eeprom_addr+2		;low byte offset

		goto show_Common27x32
;}


show_Incorrect
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x1C
		movwf eeprom_addr+1		;high byte offset
		movlw 0xAA
		movwf eeprom_addr+2		;low byte offset

		goto show_Common27x32
;}

show_EmptyCircle
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x1F
		movwf eeprom_addr+1		;high byte offset
		movlw 0x16
		movwf eeprom_addr+2		;low byte offset

		goto show_Common27x32
;}

show_EmptyBox
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x1D
		movwf eeprom_addr+1		;high byte offset
		movlw 0x16
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32
;}




show_EnterName
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x1F
		movwf eeprom_addr+1		;high byte offset
		movlw 0x82
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32	
;}

show_LevelCompleted
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x21
		movwf eeprom_addr+1		;high byte offset
		movlw 0x82
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32	
;}

show_LevelPressKey
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x23
		movwf eeprom_addr+1		;high byte offset
		movlw 0x82
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32	
;}

show_YouMadeItToTop5
;{
		movlw 0x00
		movwf eeprom_addr
		movlw 0x25
		movwf eeprom_addr+1		;high byte offset
		movlw 0x82
		movwf eeprom_addr+2		;low byte offset

		goto show_Common128x32	
;}

ssd1306_drawBitmap
;{
;		call ssd1306_clearDisplay

		call ssd1306_setXY

		call i2c_startCond
		call i2c_sendAddr

		movlw I2C_CTRL_BYTE_D
		call i2c_sendByte2

		call eeprom_setAddr

		;Spocitej spravny pocet radku
		movf ssd1306_Y, w
		subwf ssd1306_Y_max, w	;MAX_Y - Y
		addlw .1				;inc W-REG
		movwf eeprom_i

		;Spravny pocet sloupcu
		movf ssd1306_X, w
		subwf ssd1306_X_max, w
		addlw .1
		movwf k

ssd1306_drLoop
		movf k, w
		movwf eeprom_j
ssd1306_drLoop2
		call eeprom_read		;Nacti bajt z eeprom a posun adresu		
		call i2c_sendByte2		;Odesli nacteny byte do SSD1306

		decfsz eeprom_j, f
		goto ssd1306_drLoop2
				
		decfsz eeprom_i, f
		goto ssd1306_drLoop
		
		call eeprom_end			;Ukonci prenos bajtu

		goto i2c_stopCond		;Ukonci prenos na displej
;}

;5x8 font monospace
ssd1306_write_t1
;{	
		movlw	.0	
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.2
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max

		call	ssd1306_setXY
		
		movlw	HIGH text_Lives
		movwf	textPointer+1
		movlw	LOW text_Lives
		movwf	textPointer+0
		goto	ssd1306_printText
;}

;Xx16 font proporcionalni
ssd1306_write_t1_prop
;{
		movlw	.0	
		movwf	ssd1306_X
		movlw	.4
		movwf	ssd1306_Y		

		movlw	HIGH text_Lives
		movwf	textPointer+1
		movlw	LOW text_Lives
		movwf	textPointer+0
		call	ssd1306_printTextProp
		return
	
;}

show_Lives
;{
		movlw	.0	
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.0
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY		

		movlw	HIGH text_Lives
		movwf	textPointer+1
		movlw	LOW text_Lives
		movwf	textPointer+0
		call	ssd1306_printText
		movf	game_Lives, w
		addlw	'0'
		call	ssd1306_printChar
		return
;}

show_ExpectedActual
;{				
		movlw	.0	
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.1
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY
		
		call 	getPosition			;whichButton
		addlw	'0'
		call	ssd1306_printChar
		movf	INDF, w	   			;expectedButton
		addlw	'1'					;0-4 -> 1-5
		call	ssd1306_printChar		
		return
;}

getPosition
;{
		btfsc whichButton, 0
		retlw .1
		btfsc whichButton, 1
		retlw .2
		btfsc whichButton, 2
		retlw .3
		btfsc whichButton, 3
		retlw .4
		btfsc whichButton, 4
		retlw .5
		return
;}

show_Score
;{
		movlw	.62	
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.0
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max		
		call	ssd1306_setXY
	
		movlw	HIGH text_Score
		movwf	textPointer+1
		movlw	LOW text_Score
		movwf	textPointer+0
		call	ssd1306_printText

		movf	game_Score+0, w
		movwf	util_NumH
		movf	game_Score+1, w
		movwf	util_NumL
		call	bin16_to_ascii	
		movf	util_TenK, w
		call	ssd1306_printChar
		movf	util_Thou, w
		call	ssd1306_printChar
		movf	util_Hund, w
		call	ssd1306_printChar
		movf	util_Tens, w
		call	ssd1306_printChar
		movf	util_Ones, w
		call	ssd1306_printChar		
		return
;}
show_Level
;{
		movlw	.37	
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.1
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY		

		movlw	HIGH text_Level
		movwf	textPointer+1
		movlw	LOW text_Level
		movwf	textPointer+0
		call	ssd1306_printText

show_Level2
		movf	game_Level, w
		addlw	.1					;Od 1
		call	bin2ascii
		movlw	'0'
		call	ssd1306_printChar
		movf	tens, w
		call	ssd1306_printChar
		movf	ones, w
		goto	ssd1306_printChar
;}


show_Level_Number
;{
		movlw	.73
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.5
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY		

		goto 	show_Level2
;}

show_Timer
;{
		movlw	.0	
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.2
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY		

		movlw	HIGH text_Timer
		movwf	textPointer+1
		movlw	LOW text_Timer
		movwf	textPointer+0
		goto	ssd1306_printTextProp
;}

show_Timer_Number
;{
		movlw	.40
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.2
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY		

		movf	game_Timer, w
		call	bin2ascii
		movf	tens, w
		call	ssd1306_printCharProp
		movf	ones, w
		call	ssd1306_printCharProp
		movlw	' '						;1 mezera, pro pripad
		call	ssd1306_printCharProp
		
		movlw	FALSE					;Updatuj 1x za sekundu
		movwf	redrawTimer
		return
;}

show_EmptyTimer
;{
		movlw	.40
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.2
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY		

		movlw	' '
		call	ssd1306_printCharProp
		movlw	' '
		call	ssd1306_printCharProp
		movlw	' '
		call	ssd1306_printCharProp
		movlw	' '	
		goto	ssd1306_printCharProp		
;}


show_Leds
;{
		movlw	.73
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.2
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY

		movlw	HIGH text_Leds
		movwf	textPointer+1
		movlw	LOW text_Leds
		movwf	textPointer+0
		goto	ssd1306_printTextProp
;}

show_Leds_Number
;{
		movlw	.110
		movwf	ssd1306_X
		movlw	SSD1306_COLS_NUM-1
		movwf 	ssd1306_X_max
		movlw	.2
		movwf	ssd1306_Y
		movlw	SSD1306_PAGES_NUM-1
		movwf	ssd1306_Y_max
		call	ssd1306_setXY
				
		movf	game_Leds, w
		call	bin2ascii
		movf	tens, w
		call	ssd1306_printCharProp
		movf	ones, w
		call	ssd1306_printCharProp
		movlw	' '						;1 mezera, pro pripad
		goto	ssd1306_printCharProp		
;}
		
; *******************************************************************
; **************  SSD1306 print rutiny ******************************
; *******************************************************************

ssd1306_printNumber
;{
		movlw TRUE				;sazime cislo
		movwf putCharOnly

		call i2c_startCond
		call i2c_sendAddr

		movlw I2C_CTRL_BYTE_D
		call i2c_sendByte2

		movf asciiHex, w		;vyssi byte (hex)
		call ssd1306_putChar
		movf asciiHex+1, w		;nizsi byte (hex)
		call ssd1306_putChar

		call i2c_stopCond

		movlw FALSE				;Vrat zpet, pokud jsme nahodou vnoreni
		movwf putCharOnly

		return
;}

ssd1306_printChar
;{
		movwf ssd1306_char

		movlw TRUE				;sazime cislo
		movwf putCharOnly

		call i2c_startCond
		call i2c_sendAddr

		movlw I2C_CTRL_BYTE_D
		call i2c_sendByte2

		movf ssd1306_char, w
		call ssd1306_putChar

		call i2c_stopCond

		movlw FALSE				;Vrat zpet, pokud jsme nahodou vnoreni
		movwf putCharOnly

		return
;}

ssd1306_printCharProp
;{
		movwf ssd1306_char

		movlw TRUE				;sazime cislo
		movwf putCharOnly

		call i2c_startCond
		call i2c_sendAddr

		movlw I2C_CTRL_BYTE_D
		call i2c_sendByte2

		movf ssd1306_char, w
		call ssd1306_putCharProp

		call i2c_stopCond

		movlw FALSE				;Vrat zpet, pokud jsme nahodou vnoreni
		movwf putCharOnly

		return
;}

ssd1306_printText
;{
		movlw FALSE
		movwf putCharOnly

		call i2c_startCond
		call i2c_sendAddr

		movlw I2C_CTRL_BYTE_D
		call i2c_sendByte2

		call ssd1306_drawText

		goto i2c_stopCond

;}

ssd1306_printTextProp
;{
		movlw FALSE
		movwf putCharOnly

		goto ssd1306_drawTextProp
;}

ssd1306_drawText
;{
		call getNextChar
		iorlw 0x00 
		btfsc STATUS, Z
		return
ssd1306_putChar
		movwf tmp
		movlw .32
		subwf tmp, f			;x 1		
		movlw HIGH font_5x8_data
		movwf fontPointer+1
		movlw LOW font_5x8_data
		movwf fontPointer+0		;k fontPointer musime pricit 5x base
		bcf STATUS, C			;vynuluj Carry
		rlf tmp, w				;x 2
		movwf fontPointer+0		;uloz primo, nemuze pretect (max znak = 90 * 2 = 180)
		addwf fontPointer+0, f	;x 4
		btfsc STATUS, C
		incf fontPointer+1, f
		incf tmp, w				;x 5 + 1 (1=posun tabulky o 1B)
		addwf fontPointer+0, f	
		btfsc STATUS, C
		incf fontPointer+1, f		
		call getNextFontByte
		call i2c_sendByte2
		call getNextFontByte
		call i2c_sendByte2
		call getNextFontByte
		call i2c_sendByte2
		call getNextFontByte
		call i2c_sendByte2
		call getNextFontByte
		call i2c_sendByte2
		clrw					;Mezera mezi pismeny
		call i2c_sendByte2
		btfsc putCharOnly, 0	;Code reuse :-), po 1 znaku vyskoc
		return
		goto ssd1306_drawText

getNextChar
		call getNextChar2 		;To je patch kvuli strankovani
		clrf PCLATH
		;movwf tmp
		;movlw HIGH getNextChar	;Nastav PCLATH do stranky, kde momentalne jsme
		;movwf PCLATH
		;movf tmp, w
		incfsz textPointer+0, f ;Inkrementuj pointer
		goto $+2
		incf textPointer+1, f
		return 					;Vrat hodnotu (je stale ve W)
getNextChar2
		;Zde se pouze skoci na dvoubajtovou adresu v textPointer
		movf textPointer+1,w 	;Zkopiruj HI byte do PCLATHu
		movwf PCLATH
		movf textPointer+0,w 	;Dej LO byte do PCL
		movwf PCL 				;Skoci na adresu, kam ukazuje textPointer
		
getNextFontByte
		call getNextFontByte2 	;To je patch kvuli strankovani
		movwf tmp				;Posunu byte doleva, posune pismeno smerem dolu o 1px
		clrf PCLATH
		;movlw HIGH getNextFontByte
		;movwf PCLATH			;Nastav PCLATH do stranky, kde momentalne jsme
		bcf STATUS, C			;Nuluj carry, at nam neco neprirotuje zprava
		rlf tmp, w
		incfsz fontPointer+0,f 	;Inkrementuj pointer
		goto $+2
		incf fontPointer+1,f
		return 					;Vrat hodnotu (je stale ve W)

getNextFontByteProp
		call getNextFontByte2 	;To je patch kvuli strankovani
		clrf PCLATH
		incfsz fontPointer+0,f 	;Inkrementuj pointer
		goto $+2
		incf fontPointer+1,f
		return 					;Vrat hodnotu (je stale ve W)

getNextFontByte2:
		;Zde se pouze skoci na dvoubajtovou adresu v fontPointer
		movf fontPointer+1,w 	;Zkopiruj HI byte do PCLATHu
		movwf PCLATH
		movf fontPointer+0,w 	;Dej LO byte do PCL
		movwf PCL 				;Skoci na adresu, kam ukazuje fontPointer		
;}



ssd1306_drawTextProp		;Vypis text proporcionalnim fontem
;{
		call getNextChar
		iorlw 0x00 
		btfsc STATUS, Z
		return
ssd1306_putCharProp
		movwf tmp
		movlw .32
		subwf tmp, f			;x 1		
		movlw HIGH font_proportional
		movwf fontPointer+1
		movf tmp, w		
		movwf fontPointer+0		;LOW byte bude na zacatku 0, protoze
		;info data proporcionalniho fontu zacinaji na vzdy xXY00 adrese

		bcf STATUS, C			;vynuluj Carry
		rlf tmp, w				;x 2
		addwf fontPointer+0, f
		btfsc STATUS, C
		incf fontPointer+1, f
	
		call getNextFontByteProp	;Mame sirku pismene		
		movwf charWidth
		movlw PROP_FONT_HEIGHT	;v bytech / v radcich displeje
		movwf charHeight
		
		;Jelikoz je offset max. 16bit, nejvyssi byte eeprom addr = 0
		clrf eeprom_addr

		call getNextFontByteProp
		movwf eeprom_addr+1		;high byte offset

		call getNextFontByteProp
		movwf eeprom_addr+2		;low byte offset

		;Nastav pro ssd1306 meze vykreslovane oblasti, kam pujde znak
		movf ssd1306_X, w			
		movwf ssd1306_X_save	;X
		movwf ssd1306_X_max
		movf charWidth, w		
		
		addlw .255
		addwf ssd1306_X_max, f  ;X + charWidth - 1
		
		movf ssd1306_Y, w
		movwf ssd1306_Y_save
		movwf ssd1306_Y_max
		movf charHeight, w
		addlw .255
		addwf ssd1306_Y_max, f ;Y + charHeight - 1
		
		call ssd1306_setXY2	   ;Nastav pozici pro vykresleni znaku, nastav meze
		
		;Nacti bitmapova data pro znak z eeprom
		call eeprom_setAddr
		
ssd1306_aloop					;Opakuj (charWidth*charHeight)-krat
		movf charWidth, w
		movwf eeprom_i
ssd1306_bloop		
		call eeprom_read		;Nacti bajt z eeprom a posun adresu

		call i2c_sendByte2		;Odesli nacteny byte do SSD1306
		decfsz eeprom_i, f
		goto ssd1306_bloop
		
		decfsz charHeight, f
		goto ssd1306_aloop
		
		call eeprom_end			;Ukonci prenos bajtu

		call i2c_stopCond		;Ukonci tisk jednoho znaku
		
		;Posun adresu na displeji, kam pujde dalsi znak
		movf charWidth, w			;X = X + charWidth
		addwf ssd1306_X_save, w
		movwf ssd1306_X
		movf ssd1306_Y_save, w		;Y = puvodni
		movwf ssd1306_Y

		btfsc putCharOnly, 0	;Code reuse :-), po 1 znaku vyskoc
		return
		goto ssd1306_drawTextProp
		
;}
i2c_startCond
;{		
			bsf DISP_SDA
			goto $+1		;Kratsi zapis nez 2x nop
			goto $+1
			goto $+1
			goto $+1
			goto $+1	
			bsf DISP_SCL
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			bcf DISP_SDA
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1	
			bcf DISP_SCL
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1
			goto $+1	
			return
;}
				
; ***** OLED: I2C: SEND STOP CONDITION

i2c_stopCond
;{		
			bcf DISP_SDA
			goto $+1
			goto $+1
			nop			
			bsf DISP_SCL
			goto $+1
			goto $+1
			nop
			goto $+1
			goto $+1
			nop
			bsf DISP_SDA
			goto $+1
			goto $+1
			nop
			goto $+1
			goto $+1
			nop			
			return
;}

; ***** OLED: I2C: SEND ADDRESS
i2c_sendAddr
;{		
			movlw I2C_ADDR
			goto i2c_sendByte2
;}

; ***** OLED: I2C: SEND BYTE

i2c_sendCmd
;{		
			movwf i2c_byte

			call i2c_startCond

			call i2c_sendAddr

			movlw I2C_CTRL_BYTE_C				
			call i2c_sendByte2

			call i2c_sendByte

			goto i2c_stopCond
;}


i2c_sendData
;{		
			movwf i2c_byte

			call i2c_startCond

			call i2c_sendAddr

			movlw I2C_CTRL_BYTE_D
			call i2c_sendByte2

			call i2c_sendByte

			goto i2c_stopCond		;stack overflow goto

;}


; ***** OLED: I2C: SEND
i2c_sendByte		
;{
					movf i2c_byte, w
i2c_sendByte2		movwf i2c_tmp

					movlw .8
					movwf i2c_i
		
i2c_cycle			btfss i2c_tmp, 7		
					goto i2c_bitNotSet
					bcf DISP_SCL ;Abych mel hrany co nejbliz u sebe
					bsf DISP_SDA		
					goto i2c_tested
i2c_bitNotSet 		bcf DISP_SCL
					bcf DISP_SDA	

i2c_tested			bsf DISP_SCL		                  

					rlf i2c_tmp, f
					decfsz i2c_i, f
					goto i2c_cycle

					;ACK BIT
					bcf DISP_SCL
					bcf DISP_SDA					
					bsf DISP_SCL
					bcf DISP_SCL
					return	
;}
		
; *******************************************************************
; ************ C E K A C I    S M Y C K Y ***************************
; *******************************************************************

; Cekej 3secs a ihned vyskoc, je-li stisk nektereho z buttonu
; Vrat 1, pokud byl stisk buttonu, jinak 0
wait3SecsForAnyButton
;{
		movlw .3			; 3x 1sec
		movwf j
wait3S_l1
		movlw .250			; 1sec = 250 x 4ms
		movwf i
wait3S_l2
		btfsc B_GREEN		;Pri stisku vyskoc
		retlw .1
		btfsc B_BLUE
		retlw .1
		btfsc B_RED
		retlw .1
		btfsc B_YELLOW
		retlw .1
		btfsc B_WHITE
		retlw .1
		
		movlw .4			; 4ms
		call waitMilis
		decfsz i, f
		goto wait3S_l2	

		decfsz j, f
		goto wait3S_l1

		retlw 0
;}

waitSecs
;{
		movwf numSecs
waitS	call wait1s
		decfsz numSecs, f
		goto waitS
		return
;}

waitMilis
;{
		movwf numMilis
waitM	call wait1ms
		decfsz numMilis, f
		goto waitM
		return
;}

waitDifficulty
;{
		movlw .200
		goto waitMilis
;}
		
		
wait30us	
;{			
			nop
			movlw .18
			movwf j
wait30l		decfsz j, f
			goto wait30l																			

			return;			ta je za 2 cykly
;}


; Delay = 0.01 seconds
; Clock frequency = 4 MHz
wait10ms
;{
			;9993 cycles
	movlw	0xCE
	movwf	del1
	movlw	0x08
	movwf	del2
wait10ms_0
	decfsz	del1, f
	goto	$+2
	decfsz	del2, f
	goto	wait10ms_0

			;3 cycles
	goto	$+1
	nop

			;4 cycles (including call)
	return
;}	

wait500ms
;{
	movlw .250
	call waitMilis
	movlw .250
	call waitMilis
	return
;}
; Delay = 0.001 seconds
; Clock frequency = 8 MHz
wait1ms
;{
			;1993 cycles
	movlw	0x8E
	movwf	del1
	movlw	0x02
	movwf	del2
wait1ms_0
	decfsz	del1, f
	goto	$+2
	decfsz	del2, f
	goto	wait1ms_0

			;3 cycles
	goto	$+1
	nop

			;4 cycles (including call)
	return
;}


; Delay = 1 seconds
; Clock frequency = 8 MHz
wait1s
;{
			;1999996 cycles
	movlw	0x11
	movwf	del1
	movlw	0x5D
	movwf	del2
	movlw	0x05
	movwf	del3
wait1s_0
	decfsz	del1, f
	goto	$+2
	decfsz	del2, f
	goto	$+2
	decfsz	del3, f
	goto	wait1s_0

			;4 cycles (including call)
	return
;}



	

; *** SUBRUTINA pro prevod 8bit binary to 2 chars hex ********************************	
	
bin2hex	
;{
		movwf	asciiTmp
		CLRF	asciiHex	;Clear output registers
		CLRF	asciiHex+1
		SWAPF	asciiTmp,W	;Get upper nibble
		ANDLW	0x0F		;Mask off unwanted bits
		MOVWF	asciiHex	;Save
		MOVLW 	.10			;For BCD lower nibble only (lower 4 bits)
		SUBWF 	asciiHex,W
		MOVLW 	0x30		;If numerical add ascii value (-10)
		BTFSC 	STATUS,C
		MOVLW 	0x37		;If alphabetical, then add a different ascii value (-10)
		ADDWF 	asciiHex,1	;save in output reg
		MOVF	asciiTmp,W	;get lower nibble of input byte
		ANDLW	0x0F		;mask off unwanted data
		MOVWF	asciiHex+1
		MOVLW 	.10		
		SUBWF 	asciiHex+1,W
		MOVLW 	0x30
		BTFSC 	STATUS,C
		MOVLW 	0x37
		ADDWF 	asciiHex+1,1	;and save in output reg
		retlw   .0
;}

; *** SUBRUTINA pro prevod 6bit binary to BCD ********************************	

bin2ascii
;{
	clrf tens
	addlw .256 - .100
digit100
	addlw .20
	btfss STATUS,C
	goto  digit40
	bsf   tens,3
	addlw .256 - .20
	goto digit10
digit40
	addlw .40
	btfss STATUS,C
	goto  $+3
	bsf   tens,2
	addlw .256 - .40
	addlw .20
	btfss STATUS,C
	goto  $+3
	bsf   tens,1
	addlw .256 - .20
digit10
	addlw .10
	btfss STATUS,C
	goto  $+3
	bsf   tens,0
	addlw .256 - .10
	
	addlw .10
	movwf ones

	;convert to ascii digits
	movlw '0'
	addwf tens, f
	addwf ones, f
	return
;}


bin16_to_ascii
;{
		swapf	util_NumH,w	
        andlw   0x0F     
        addlw   0xF0	
        movwf   util_Thou	
        addwf   util_Thou,f	
        addlw   .226	
        movwf   util_Hund	
        addlw   .50	
        movwf   util_Ones	

        movf    util_NumH,w
        andlw   0x0F
        addwf   util_Hund,f
        addwf   util_Hund,f
        addwf   util_Ones,f
        addlw   .233
        movwf   util_Tens
        addwf   util_Tens,f
        addwf   util_Tens,f

        swapf   util_NumL,w
        andlw   0x0F
        addwf   util_Tens,f
        addwf   util_Ones,f

        rlf     util_Tens,f
        rlf     util_Ones,f
        comf    util_Ones,f

        rlf     util_Ones,f

        movf    util_NumL,w
        andlw   0x0F
        addwf   util_Ones,f
        rlf     util_Thou,f

        movlw   0x07
        movwf   util_TenK

        movlw   .10
Lb1			
        addwf   util_Ones,f
        decf    util_Tens,f
        btfss   3,0
	;skip no carry
         goto   Lb1
	;jmp carry
Lb2			
        addwf   util_Tens,f
        decf    util_Hund,f
        btfss   3,0
         goto   Lb2
Lb3			
        addwf   util_Hund,f
        decf    util_Thou,f
        btfss   3,0
        goto   Lb3
Lb4
        addwf   util_Thou,f
        decf    util_TenK,f
        btfss   3,0
        goto   Lb4

		;Preved decimal cislice -> ascii hodnoty
		movlw '0'
		addwf util_TenK, f
		addwf util_Thou, f
		addwf util_Hund, f
		addwf util_Tens, f
		addwf util_Ones, f
		
        return

;}


; *****************************************************************
; ********************** E E P R O M   R U T I N Y ****************
; *****************************************************************

;Uloz TOP5 do EEPROM PIC
EEPROM_saveTop5
;{
		;Adresa zacatku dat pro zapis do EEPROM data
		bsf STATUS, IRP		;BANK2 FSR
		movlw low(EEPROM_Top5)
		movwf FSR

		clrf EEPROM_addr			     ;Od addresy 0
		movlw EEPROM_Top5_init_table_len ;Zapiseme 25 bajtu
		movwf i
EEPROM_iLoop
		movf INDF, w
		movwf EEPROM_value
		call EEPROM_writeByte

		incf EEPROM_addr, f			;Adresa+1
		
		incf FSR, f	

		decfsz i, f
		goto EEPROM_iLoop

		bcf STATUS, IRP		;FSR v BANK0 a BANK1

		return
;}

;EEPROM_readTop5
;Nacte z PIC EEPROM TOP5 do BANK2 od adresy 0x20
EEPROM_readTop5
;{
		clrf EEPROM_addr	; Cteme od addresy 0

		movlw EEPROM_Top5_init_table_len	;Nacteme Top5
		movwf i

		bsf STATUS, IRP		;BANK2 FSR
		movlw TOP5_TABLE_ADDR
		movwf FSR

EEPROM_rLoop	
		movf EEPROM_addr, w	
		BANK2
		movwf EEADR 		; Address to read
		BANK3		
		bcf EECON1, EEPGD 	; Point to Data memory
		bsf EECON1, RD 		; EE Read
		BANK2		
		movf EEDATA, w 		; W = EEDATA
		BANK0
		movwf INDF
		incf FSR, f

		incf EEPROM_addr, f
		decfsz i, f
		goto EEPROM_rLoop

		bcf STATUS, IRP		;FSR v BANK0 a BANK1
		return
;}

;EEPROM_writeByte
;Vstup: EEPROM_addr	- pozice v EEPROM
;		EEPROM_value - byte k zapisu
EEPROM_writeByte
;{
		BANK2	
		movf	EEPROM_addr, w	
		movwf 	EEADR				;Address to write
		movf 	EEPROM_value, w		;Data Memory Value to write
		movwf 	EEDATA 
		BANK3		
		bcf 	EECON1,EEPGD	 	;Point to DATA memory
		bsf 	EECON1,WREN 		;Enable writes
		bcf 	INTCON,GIE 			;Disable INTs.
		movlw 	0x55 
		movwf 	EECON2 				;Write 55h
		movlw 	0xAA
		movwf 	EECON2 				;Write AAh
		bsf 	EECON1,WR 			;Set WR bit to begin write
		bsf 	INTCON,GIE 			;Enable INTs.
		bcf 	EECON1,WREN 		;Disable writes
		btfsc	EECON1,WR 			;Wait for write to complete
		GOTO 	$-1 
		BANK0
		return
;}

EE_getNextByte
;{
		call EE_getNextByte2 	;To je patch kvuli strankovani
		clrf PCLATH
		incfsz textPointer+1, f ;Inkrementuj pointer
		goto $+2
		incf textPointer+0, f
		return 					;Vrat hodnotu (je stale ve W)
;}
EE_getNextByte2
;{
		;Zde se pouze skoci na dvoubajtovou adresu v textPointer
		movf textPointer+0,w 	;Zkopiruj HI byte do PCLATHu
		movwf PCLATH
		movf textPointer+1,w 	;Dej LO byte do PCL
		movwf PCL 				;Skoci na adresu, kam ukazuje textPointer
;}

; *****************************************************************	
; ********************** F O N T  D A T A *************************
; *****************************************************************

			org 0x0800
			nop		;musi byt kvuli zarovnani na 255 bytes
font_5x8_data
;{
		dt 0x00, 0x00, 0x00, 0x00, 0x00; space (32dec)
		dt 0x00, 0x00, 0x2f, 0x00, 0x00; !
		dt 0x00, 0x07, 0x00, 0x07, 0x00; "
		dt 0x14, 0x7f, 0x14, 0x7f, 0x14; #
		dt 0x24, 0x2a, 0x7f, 0x2a, 0x12; $
		dt 0xc4, 0xc8, 0x10, 0x26, 0x46; %
		dt 0x36, 0x49, 0x55, 0x22, 0x50; &
		dt 0x00, 0x05, 0x03, 0x00, 0x00; '
		dt 0x00, 0x1c, 0x22, 0x41, 0x00; (
		dt 0x00, 0x41, 0x22, 0x1c, 0x00; )
		dt 0x14, 0x08, 0x3E, 0x08, 0x14; *
		dt 0x08, 0x08, 0x3E, 0x08, 0x08; +
		dt 0x00, 0x00, 0x50, 0x30, 0x00; ,
		dt 0x10, 0x10, 0x10, 0x10, 0x10; -
		dt 0x00, 0x60, 0x60, 0x00, 0x00; .
		dt 0x20, 0x10, 0x08, 0x04, 0x02; /
		dt 0x3E, 0x51, 0x49, 0x45, 0x3E; 0
		dt 0x00, 0x42, 0x7F, 0x40, 0x00; 1
		dt 0x42, 0x61, 0x51, 0x49, 0x46; 2
		dt 0x21, 0x41, 0x45, 0x4B, 0x31; 3
		dt 0x18, 0x14, 0x12, 0x7F, 0x10; 4
		dt 0x27, 0x45, 0x45, 0x45, 0x39; 5
		dt 0x3C, 0x4A, 0x49, 0x49, 0x30; 6
		dt 0x01, 0x71, 0x09, 0x05, 0x03; 7
		dt 0x36, 0x49, 0x49, 0x49, 0x36; 8
		dt 0x06, 0x49, 0x49, 0x29, 0x1E; 9
		dt 0x00, 0x36, 0x36, 0x00, 0x00; :
		dt 0x00, 0x56, 0x36, 0x00, 0x00; ;
		dt 0x08, 0x14, 0x22, 0x41, 0x00; <
		dt 0x14, 0x14, 0x14, 0x14, 0x14; =
		dt 0x00, 0x41, 0x22, 0x14, 0x08; >
		dt 0x02, 0x01, 0x51, 0x09, 0x06; ?
		dt 0x32, 0x49, 0x59, 0x51, 0x3E; @
		dt 0x7E, 0x11, 0x11, 0x11, 0x7E; A
		dt 0x7F, 0x49, 0x49, 0x49, 0x36; B
		dt 0x3E, 0x41, 0x41, 0x41, 0x22; C
		dt 0x7F, 0x41, 0x41, 0x22, 0x1C; D
		dt 0x7F, 0x49, 0x49, 0x49, 0x41; E
		dt 0x7F, 0x09, 0x09, 0x09, 0x01; F
		dt 0x3E, 0x41, 0x49, 0x49, 0x7A; G
		dt 0x7F, 0x08, 0x08, 0x08, 0x7F; H
		dt 0x00, 0x41, 0x7F, 0x41, 0x00; I
		dt 0x20, 0x40, 0x41, 0x3F, 0x01; J
		dt 0x7F, 0x08, 0x14, 0x22, 0x41; K
		dt 0x7F, 0x40, 0x40, 0x40, 0x40; L
		dt 0x7F, 0x02, 0x0C, 0x02, 0x7F; M
		dt 0x7F, 0x04, 0x08, 0x10, 0x7F; N
		dt 0x3E, 0x41, 0x41, 0x41, 0x3E; O
		dt 0x7F, 0x09, 0x09, 0x09, 0x06; P
		dt 0x3E, 0x41, 0x51, 0x21, 0x5E; Q
		dt 0x7F, 0x09, 0x19, 0x29, 0x46; R
		dt 0x46, 0x49, 0x49, 0x49, 0x31; S
		dt 0x01, 0x01, 0x7F, 0x01, 0x01; T
		dt 0x3F, 0x40, 0x40, 0x40, 0x3F; U
		dt 0x1F, 0x20, 0x40, 0x20, 0x1F; V
		dt 0x3F, 0x40, 0x38, 0x40, 0x3F; W
		dt 0x63, 0x14, 0x08, 0x14, 0x63; X
		dt 0x07, 0x08, 0x70, 0x08, 0x07; Y
		dt 0x61, 0x51, 0x49, 0x45, 0x43; Z
		dt 0x00, 0x7F, 0x41, 0x41, 0x00; [
		dt 0x55, 0x2A, 0x55, 0x2A, 0x55; "Yen"
		dt 0x00, 0x41, 0x41, 0x7F, 0x00; ]
		dt 0x04, 0x02, 0x01, 0x02, 0x04; ^
		dt 0x40, 0x40, 0x40, 0x40, 0x40; _
		dt 0x00, 0x01, 0x02, 0x04, 0x00; '
		dt 0x20, 0x54, 0x54, 0x54, 0x78; a
		dt 0x7F, 0x48, 0x44, 0x44, 0x38; b
		dt 0x38, 0x44, 0x44, 0x44, 0x20; c
		dt 0x38, 0x44, 0x44, 0x48, 0x7F; d
		dt 0x38, 0x54, 0x54, 0x54, 0x18; e
		dt 0x08, 0x7E, 0x09, 0x01, 0x02; f
		dt 0x0C, 0x52, 0x52, 0x52, 0x3E; g
		dt 0x7F, 0x08, 0x04, 0x04, 0x78; h
		dt 0x00, 0x44, 0x7D, 0x40, 0x00; i
		dt 0x20, 0x40, 0x44, 0x3D, 0x00; j
		dt 0x7F, 0x10, 0x28, 0x44, 0x00; k
		dt 0x00, 0x41, 0x7F, 0x40, 0x00; l
		dt 0x7C, 0x04, 0x18, 0x04, 0x78; m
		dt 0x7C, 0x08, 0x04, 0x04, 0x78; n
		dt 0x38, 0x44, 0x44, 0x44, 0x38; o
		dt 0x7C, 0x14, 0x14, 0x14, 0x08; p
		dt 0x08, 0x14, 0x14, 0x18, 0x7C; q
		dt 0x7C, 0x08, 0x04, 0x04, 0x08; r
		dt 0x48, 0x54, 0x54, 0x54, 0x20; s
		dt 0x04, 0x3F, 0x44, 0x40, 0x20; t
		dt 0x3C, 0x40, 0x40, 0x20, 0x7C; u
		dt 0x1C, 0x20, 0x40, 0x20, 0x1C; v
		dt 0x3C, 0x40, 0x30, 0x40, 0x3C; w
		dt 0x44, 0x28, 0x10, 0x28, 0x44; x
		dt 0x0C, 0x50, 0x50, 0x50, 0x3C; y
		dt 0x44, 0x64, 0x54, 0x4C, 0x44; z
;}
	


				org 0xB00
font_proportional
;{
;Data fontu vysky 16 pixelu, proporcionalni
PROP_FONT_HEIGHT		equ 0x02		;Vyska v bajtech
PROP_FONT_BASE_ADDR		equ 0x000000	;Pozice fontu v EEPROM
		 ;  sirka v pixelech, offset of zacatku font dat

		 dt .5, 0x00, 0x00		;   (offset: 0)
		 dt .2, 0x00, 0x0a		; ! (offset: 10)
		 dt .4, 0x00, 0x0e		; " (offset: 14)
		 dt .8, 0x00, 0x16		; # (offset: 22)
		 dt .7, 0x00, 0x26		; $ (offset: 38)
		 dt .12, 0x00, 0x34		; % (offset: 52)
		 dt .10, 0x00, 0x4c		; & (offset: 76)
		 dt .2, 0x00, 0x60		; ' (offset: 96)
		 dt .3, 0x00, 0x64		; ( (offset: 100)
		 dt .3, 0x00, 0x6a		; ) (offset: 106)
		 dt .6, 0x00, 0x70		; * (offset: 112)
		 dt .8, 0x00, 0x7c		; + (offset: 124)
		 dt .3, 0x00, 0x8c		; , (offset: 140)
		 dt .4, 0x00, 0x92		; - (offset: 146)
		 dt .2, 0x00, 0x9a		; . (offset: 154)
		 dt .5, 0x00, 0x9e		; / (offset: 158)
		 dt .8, 0x00, 0xa8		; 0 (offset: 168)
		 dt .6, 0x00, 0xb8		; 1 (offset: 184)
		 dt .7, 0x00, 0xc4		; 2 (offset: 196)
		 dt .8, 0x00, 0xd2		; 3 (offset: 210)
		 dt .8, 0x00, 0xe2		; 4 (offset: 226)
		 dt .8, 0x00, 0xf2		; 5 (offset: 242)
		 dt .8, 0x01, 0x02		; 6 (offset: 258)
		 dt .8, 0x01, 0x12		; 7 (offset: 274)
		 dt .8, 0x01, 0x22		; 8 (offset: 290)
		 dt .8, 0x01, 0x32		; 9 (offset: 306)
		 dt .2, 0x01, 0x42		; : (offset: 322)
		 dt .3, 0x01, 0x46		; ; (offset: 326)
		 dt .7, 0x01, 0x4c		; < (offset: 332)
		 dt .7, 0x01, 0x5a		; = (offset: 346)
		 dt .7, 0x01, 0x68		; > (offset: 360)
		 dt .7, 0x01, 0x76		; ? (offset: 374)
		 dt .12, 0x01, 0x84		; @ (offset: 388)
		 dt .10, 0x01, 0x9c		; A (offset: 412)
		 dt .9, 0x01, 0xb0		; B (offset: 432)
		 dt .9, 0x01, 0xc2		; C (offset: 450)
		 dt .9, 0x01, 0xd4		; D (offset: 468)
		 dt .9, 0x01, 0xe6		; E (offset: 486)
		 dt .9, 0x01, 0xf8		; F (offset: 504)
		 dt .9, 0x02, 0x0a		; G (offset: 522)
		 dt .9, 0x02, 0x1c		; H (offset: 540)
		 dt .4, 0x02, 0x2e		; I (offset: 558)
		 dt .8, 0x02, 0x36		; J (offset: 566)
		 dt .9, 0x02, 0x46		; K (offset: 582)
		 dt .8, 0x02, 0x58		; L (offset: 600)
		 dt .12, 0x02, 0x68		; M (offset: 616)
		 dt .9, 0x02, 0x80		; N (offset: 640)
		 dt .9, 0x02, 0x92		; O (offset: 658)
		 dt .9, 0x02, 0xa4		; P (offset: 676)
		 dt .8, 0x02, 0xb6		; Q (offset: 694)
		 dt .8, 0x02, 0xc6		; R (offset: 710)
		 dt .8, 0x02, 0xd6		; S (offset: 726)
		 dt .10, 0x02, 0xe6		; T (offset: 742)
		 dt .10, 0x02, 0xfa		; U (offset: 762)
		 dt .10, 0x03, 0x0e		; V (offset: 782)
		 dt .13, 0x03, 0x22		; W (offset: 802)
		 dt .10, 0x03, 0x3c		; X (offset: 828)
		 dt .8, 0x03, 0x50		; Y (offset: 848)
		 dt .9, 0x03, 0x60		; Z (offset: 864)
		 dt .3, 0x03, 0x72		; [ (offset: 882)
		 dt .5, 0x03, 0x78		; \ (offset: 888)
		 dt .3, 0x03, 0x82		; ] (offset: 898)
		 dt .6, 0x03, 0x88		; ^ (offset: 904)
		 dt .8, 0x03, 0x94		; _ (offset: 916)
		 dt .4, 0x03, 0xa4		; ` (offset: 932)
		 dt .8, 0x03, 0xac		; a (offset: 940)
		 dt .7, 0x03, 0xbc		; b (offset: 956)
		 dt .6, 0x03, 0xca		; c (offset: 970)
		 dt .7, 0x03, 0xd6		; d (offset: 982)
		 dt .7, 0x03, 0xe4		; e (offset: 996)
		 dt .6, 0x03, 0xf2		; f (offset: 1010)
		 dt .7, 0x03, 0xfe		; g (offset: 1022)
		 dt .8, 0x04, 0x0c		; h (offset: 1036)
		 dt .4, 0x04, 0x1c		; i (offset: 1052)
		 dt .5, 0x04, 0x24		; j (offset: 1060)
		 dt .9, 0x04, 0x2e		; k (offset: 1070)
		 dt .4, 0x04, 0x40		; l (offset: 1088)
		 dt .12, 0x04, 0x48		; m (offset: 1096)
		 dt .8, 0x04, 0x60		; n (offset: 1120)
		 dt .6, 0x04, 0x70		; o (offset: 1136)
		 dt .7, 0x04, 0x7c		; p (offset: 1148)
		 dt .6, 0x04, 0x8a		; q (offset: 1162)
		 dt .6, 0x04, 0x96		; r (offset: 1174)
		 dt .6, 0x04, 0xa2		; s (offset: 1186)
		 dt .5, 0x04, 0xae		; t (offset: 1198)
		 dt .8, 0x04, 0xb8		; u (offset: 1208)
		 dt .8, 0x04, 0xc8		; v (offset: 1224)
		 dt .11, 0x04, 0xd8		; w (offset: 1240)
		 dt .8, 0x04, 0xee		; x (offset: 1262)
		 dt .8, 0x04, 0xfe		; y (offset: 1278)
		 dt .7, 0x05, 0x0e		; z (offset: 1294)
		 dt .4, 0x05, 0x1c		; { (offset: 1308)
		 dt .2, 0x05, 0x24		; | (offset: 1316)
		 dt .4, 0x05, 0x28		; } (offset: 1320)
		 dt .7, 0x05, 0x30		; ~ (offset: 1328)
;}

; *****************************************************************	
; ********************** T E X T  D A T A *************************
; *****************************************************************
				org 0xD00

text_table
;{
text_Lives		dt "LIVES ", 0x00
text_Score		dt "SCORE ", 0x00
text_Level		dt "LEVEL ", 0x00
text_Timer		dt "TIME ", 0x00
text_Leds		dt "LEDs ", 0x00
;}


		org 0x2100
EEPROM_Top5_init_table
;{
;		de "VIT", 0x00, 0x32	
;		de "VIT", 0x00, 0x28	
;		de "VIT", 0x00, 0x1E	
;		de "VIT", 0x00, 0x14	
;		de "VIT", 0x00, 0x0A	
	
		de "VIT", 0x01, 0xF4	;00500
		de "VIT", 0x01, 0x90	;00400
		de "VIT", 0x00, 0xFA	;00250
		de "VIT", 0x00, 0x64	;00100
		de "VIT", 0x00, 0x32	;00050
EEPROM_Top5_init_table_end
EEPROM_Top5_init_table_len	equ EEPROM_Top5_init_table_end - EEPROM_Top5_init_table

; *** KONEC SOUBORU *************************************************	
	end