; 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
	w_temp
	status_temp
	pclath_temp
	d1			;registry pro cekaci subrutiny
	d2
	d3
	hiByte
	loByte
	i2c_i
	i2c_tmp
	tmp				;writeByte
	tmpByte
	nonZeroByte
	numSecs
	numMilis
	index
	i				;writeByte	
	j				;LCD_draw_*
	tens			;desitky - bin2ascii
	ones			;jednotky - bin2ascii
	number			;vypisovana cislice
	textPointer:2	;Ukazatel do textu
	fontPointer:2	;Ukazatel do dat fontu
	X
	X_copy
	Y
	Y_copy
	cislo
	cislo_tajne
	cislo_aktualni
	pokusy
	guessed			;T/F - uhodl?
	game_over		;T/F
	putCharOnly		;T/F
	RNDval:.2		;nahodna hodnota
	RNDtmp			;tmp pro random hodnoty	
	RNDret
	randPortA		;nahodne stavy z PortA
	
	lastCLK			;rotary encoder
	stateDT
	stateCLK
	counterLeft		;rotary encoder generuje 2 pulzy, musim delit 2
	counterRight
    endc

;******************************************************************
;****************** K O N S T A N T Y *****************************
;******************************************************************

FALSE				equ 0x00
TRUE				equ 0x01

HI					equ 0x01
LO					equ 0x00

;LCD NOKIA 5110
LCD_BYTES			equ .504 ;(84 x 6 = 84 x 48px)

;******************************************************************
;****************** D E F I N I C E *******************************
;******************************************************************
   
;Rotary encoder KY-040
#define	R_CLK		PORTA, RA1;
#define R_DT		PORTA, RA0;
#define R_SW		PORTA, RA7;

#define BIT_CLK		RA1
#define BIT_DT		RA0

;Nokia 5110 LCD display SPI
#define LCD_RESET	PORTB, RB3;
#define LCD_SCLK	PORTB, RB0;
#define LCD_SDIN	PORTB, RB1;
#define LCD_DC		PORTB, RB2;

;******************************************************************
;****************** M A K R A *************************************
;******************************************************************
 
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
	
	org 0x04
	goto interrupt

; ******************************************************************
; *********************** I N T E R R U P T ************************
; ******************************************************************

interrupt
	movwf w_temp 		;copy W to temp register, could be in either bank
	swapf STATUS,w 		;swap status to be saved into W	
	movwf status_temp 	;save status to bank 0 register


skip
	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	045h
	movwf	RNDval+1

	BANK1
	movlw b'11001000'
	movwf OPTION_REG

	;*** PORTA NASTAVENI - rotary encoder ***
	BANK0
	movf PORTA, w		;nahodna hodnota na vstupech
	movwf randPortA
		
	clrf PORTA
	movlw 0x07
	movwf CMCON	;All pins I/O
		
	BANK1
	clrf VRCON
	movlw b'10000011'; RA1-CLK, RA0-DT, RA7-SW
	movwf TRISA
	
	;*** PORTB NASTAVENI - Nokia LCD 5110 ***	
	BANK1
	clrf TRISB	
	BANK0
	clrf PORTB   
	clrf CCP1CON 		; Turn CCP module off

	BANK0
	;Inicializace Timer0
	clrf INTCON
			
;*******************************************************************
;******************* M A I N   L O O P *****************************
;*******************************************************************

	movlw .100
	call waitMilis

	call LCD_init

	call LCD_clear

	call LCD_write_t4
	call LCD_write_t5
	call LCD_write_t6
	
;Toto je uvodni obrazovka s cekanim na stisk tlacitka. Potrebuji
;pred hrou vygenerovat opravdu nahodne cislo, proto volam v cyklu
;generovani. 

PRE_START

	call GAME_generateRandomNumber
	
	btfsc R_SW
	goto PRE_START
		
GAME_START

	;Osetri game over
	btfss R_SW
	goto GAME_START
	
	call ROTARY_getCLK
	movwf lastCLK	
	
	clrf counterLeft
	clrf counterRight

	call INIT_GAME

	call LCD_clear
	
	call LCD_write_t1
	call LCD_write_t2
	call LCD_write_t3
	
	call LCD_showActual

GAME_LOOP

	;Handle rotary encoder state
	call ROTARY_getCLK
	movwf stateCLK
	
	movf lastCLK, w			;lastCLK != stateCLK ?
	xorwf stateCLK, w
	btfsc STATUS, Z
	goto GAME_checkSwitch	;No, check button switch
	
	call ROTARY_getDT
	movwf stateDT
	xorwf stateCLK, w		;stateDT != stateCLK? => rotace doprava
	btfsc STATUS, Z
	goto GAME_rotateLeft

GAME_rotateRight
	
	clrf counterLeft
	
	movlw .2
	incf counterRight, f
	xorwf counterRight, w
	btfss STATUS, Z			;counterRight == 2? Pak inkrementuj.
	goto GAME_handleCommon
	clrf counterRight	
	call GAME_incAktualni
	goto GAME_handleCommon	
	
GAME_rotateLeft

	clrf counterRight
	
	movlw .2
	incf counterLeft, f
	xorwf counterLeft, w
	btfss STATUS, Z			;counterLeft == 2? Pak inkrementuj.
	goto GAME_handleCommon
	clrf counterLeft	
	call GAME_decAktualni
	goto GAME_handleCommon
	
GAME_handleCommon
	call LCD_showActual

GAME_checkSwitch

	movf stateCLK, w
	movwf lastCLK
	
	btfsc R_SW
	goto GAME_NEXT
	
	movlw .5
	call waitMilis	
	
	btfsc R_SW
	goto GAME_NEXT
	
GAME_handleSwitch				;Pockej na uvolneni stisku
	btfss R_SW
	goto GAME_handleSwitch

	call GAME_check

GAME_NEXT
	
	btfss game_over, 0
	goto GAME_LOOP
	
GAME_OVER

	btfss guessed, 0			;Uhadl? Pokud ano, zobraz kod jen 3s.
	goto GAME_WAIT_KEY			;Ne, pockej na stisk.
	
	call wait1s
	call wait1s
	call wait1s
	goto GAME_START
	
GAME_WAIT_KEY
	btfss R_SW
	goto GAME_START
	
	goto GAME_WAIT_KEY

;*******************************************************************
;******************* R O T A R Y   E N C O D E R *******************
;*******************************************************************

ROTARY_getCLK
	
	movf PORTA, w
	movwf tmp
	
	movlw HI
	btfss tmp, BIT_CLK
	movlw LO
	return
	
ROTARY_getDT
	
	movf PORTA, w
	movwf tmp
	
	movlw HI
	btfss tmp, BIT_DT
	movlw LO
	return
	
;*******************************************************************
;******************* I N I T   G A M E *****************************
;*******************************************************************

INIT_GAME
	movlw .50
	movwf cislo_aktualni
	
	movf TMR0, w
	xorwf randPortA, w		;zkus nahodny-pocet-krat zopakovat generovani
	movwf i
INIT_RND_loop	
	call GAME_generateRandomNumber
	decfsz i, f
	goto INIT_RND_loop
	
	movlw .6
	movwf pokusy
	movlw FALSE
	movwf game_over
	movwf guessed		;konec hry uhodnutim? Pak zobraz kod jen 3s.
	return

GAME_generateRandomNumber
	RandomM	RNDval,RNDtmp	;Zavolej makro
	movf TMR0, w
	xorwf RNDval, w
	movwf RNDtmp
	
	movf RNDval, w
	andlw b'00111111'	;63
	movwf cislo_tajne
	
	movf RNDval+.1, w
	andlw b'00011111'  ;31
	addwf cislo_tajne, w
	
	addlw .3		  ;63 + 31 + 3 = 97
	movwf cislo_tajne

	btfsc TMR0, 0		;+ nahodna 1
	bsf cislo_tajne, 0		
	return


GAME_incAktualni
	incf cislo_aktualni, f
	movlw .100
	subwf cislo_aktualni, w	; ==100?
	btfss STATUS, Z	
	return
	movlw .1
	movwf cislo_aktualni
	return

GAME_decAktualni
	decf cislo_aktualni, f
	movf cislo_aktualni, f ; ==0?
	btfss STATUS, Z	
	return
	movlw .99
	movwf cislo_aktualni
	return

;Porovnej cislo_aktualni a cislo_tajne 
;A vypis odpovidajici hlasku
GAME_check

	;1) Shoda?
	movf cislo_aktualni, w
	subwf cislo_tajne, w
	btfss STATUS, Z
	goto GAME_check_next
	
	movlw TRUE
	movwf game_over
	movwf guessed
	call LCD_write_empty
	call LCD_write_t_uhadl
	call LCD_showCode
	call LCD_showSecret
	return
		
GAME_check_next

	decf pokusy, f
	movf pokusy, f
	btfss STATUS, Z
	goto GAME_check_not_equal
	
	movlw TRUE
	movwf game_over
	call LCD_write_t_konec
	
GAME_check_not_equal

	;2) Mensi nebo vetsi?
	bcf STATUS, C
	movf cislo_aktualni, w
	subwf cislo_tajne, w
	btfss STATUS, C
	goto GAME_check_lower
	
	call LCD_write_t_vetsi
	goto GAME_check_common
	
GAME_check_lower
	call LCD_write_t_mensi
	
GAME_check_common

	;Jestli uz bylo 6 pokusu, nezobrazuj pokusy
	btfsc game_over, 0
	goto GAME_check_finish
	call LCD_showPokusy
	return
	
GAME_check_finish
	call LCD_showSecret
	return	

	
;*******************************************************************
;*************** LCD - INICIALIZACE DISPLEJE ***********************
;*******************************************************************
	
LCD_init

	nop
	nop
	nop
	nop
	bcf LCD_RESET	
	movlw .250
	call waitMilis
	movlw .250
	call waitMilis
		
	bsf LCD_RESET
	

	; Tohle ma Arduino 5510
	movlw 0x21			; Extended instruction set, H=1, V=0, PD=0
	call LCD_sendCmd
	movlw 0xC4			; Set LCD Vop (Contrast)
	call LCD_sendCmd
	movlw 0x06			; Set Temp coefficient
	call LCD_sendCmd
	movlw 0x13			; LCD Bias system (1:48)
	call LCD_sendCmd
	movlw b'00100000'	;0x20, basic instruction set, H=0, V=0, PD=0
	call LCD_sendCmd
	movlw b'00001100'	;0x0C, normal mode, D=1, E=0
	call LCD_sendCmd
	
	return


;*******************************************************************
;******************* LCD - POSILANI COMMANDU ***********************
;*******************************************************************

LCD_sendCmd
	bcf LCD_DC	
	call LCD_writeByte
	return

;*******************************************************************
;******************* LCD - POSILANI OBRAZOVYCH DAT *****************
;*******************************************************************

LCD_sendData
	bsf LCD_DC
	call LCD_writeByte
	return

;*******************************************************************
;******************* LCD - SPI WRITE BYTE **************************
;*******************************************************************

LCD_writeByte
		movwf i2c_tmp	;uschovej posilany byte

		movlw .8
		movwf i2c_i
		
LCD_wc	bcf LCD_SCLK	 ;clock na log. 0, zaciname prenos data			
		btfss i2c_tmp, 7 ;bit 0 nastaven?
		goto bitNotSet
		bsf LCD_SDIN	;ano, posli log 1
		goto bitChecked
bitNotSet 
		bcf LCD_SDIN	;ne, posli log 0 na vystup
bitChecked			
		bsf LCD_SCLK	;clock na log. 1, skoncili jsme prenos 1 bitu

		rlf i2c_tmp, f
		decfsz i2c_i, f
		goto LCD_wc

		bcf LCD_SCLK
		return


;******************************************************************
;********************* LCD - CLEAR SCREEN *************************
;******************************************************************

LCD_clear
		movlw LOW LCD_BYTES
		movwf loByte
		movlw HIGH LCD_BYTES
		movwf hiByte
LCD_c1	clrw
		call LCD_sendData		
		call decHL
		btfss STATUS, Z
		goto LCD_c1
		return

;******************************************************************
;********************* LCD - BLACK SCREEN *************************
;******************************************************************

LCD_black
		movlw LOW LCD_BYTES
		movwf loByte
		movlw HIGH LCD_BYTES
		movwf hiByte
LCD_b1	movlw 0xFF
		call LCD_sendData		
		call decHL
		btfss STATUS, Z
		goto LCD_b1
		return

;******************************************************************
;********************* LCD - SET X,Y ******************************
;******************************************************************

LCD_setXY
		movf X, w			;Nastav souradnice
		iorlw b'10000000'	;X = 1X6X5X4X3X2X1X0
		call LCD_sendCmd
		movf Y, w
		iorlw b'01000000'	;Y = 0100Y3Y2Y1Y0
		call LCD_sendCmd
		return
	
;******************************************************************
;************ LCD - VYKRESLOVANI TEXTOVYCH RETEZCU ****************
;******************************************************************		

;Najdi X
LCD_write_t1		
		clrf X
		clrf Y
		call LCD_setXY
		movlw HIGH t1
		movwf textPointer+1
		movlw LOW t1
		movwf textPointer+0
		goto LCD_drawText

LCD_write_empty
		clrf X
		clrf Y
		call LCD_setXY
		movlw HIGH t_empty
		movwf textPointer+1
		movlw LOW t_empty
		movwf textPointer+0
		call LCD_drawText
		clrf X
		movlw .1
		movwf Y
		call LCD_setXY
		movlw HIGH t_empty
		movwf textPointer+1
		movlw LOW t_empty
		movwf textPointer+0
		goto LCD_drawText		
			
;X>0 a X<100
LCD_write_t2		
		clrf X
		movlw .1
		movwf Y
		call LCD_setXY
		movlw HIGH t2
		movwf textPointer+1
		movlw LOW t2
		movwf textPointer+0
		goto LCD_drawText
		
;Mas 6 pokusu
LCD_write_t3
		clrf X
		movlw .2
		movwf Y
		call LCD_setXY
		movlw HIGH t3
		movwf textPointer+1
		movlw LOW t3
		movwf textPointer+0
		goto LCD_drawText
		
		
;Minihra c. 4
LCD_write_t4		
		clrf X
		clrf Y
		call LCD_setXY
		movlw HIGH t4
		movwf textPointer+1
		movlw LOW t4
		movwf textPointer+0
		goto LCD_drawText
		
;-------------
LCD_write_t5		
		clrf X
		movlw .1
		movwf Y
		call LCD_setXY
		movlw HIGH t5
		movwf textPointer+1
		movlw LOW t5
		movwf textPointer+0
		goto LCD_drawText		
		
;Stiskni tlac.
LCD_write_t6		
		clrf X
		movlw .3
		movwf Y
		call LCD_setXY
		movlw HIGH t6
		movwf textPointer+1
		movlw LOW t6
		movwf textPointer+0
		goto LCD_drawText										
		
;X je vetsi
LCD_write_t_vetsi
		clrf X
		movlw .5
		movwf Y
		call LCD_setXY
		movlw HIGH t_vetsi
		movwf textPointer+1
		movlw LOW t_vetsi
		movwf textPointer+0
		goto LCD_drawText
		
;X je mensi
LCD_write_t_mensi
		clrf X
		movlw .5
		movwf Y
		call LCD_setXY
		movlw HIGH t_mensi
		movwf textPointer+1
		movlw LOW t_mensi
		movwf textPointer+0
		goto LCD_drawText		
		
;Neuhadl jsi.
LCD_write_t_konec
		clrf X
		movlw .2
		movwf Y
		call LCD_setXY
		movlw HIGH t_konec
		movwf textPointer+1
		movlw LOW t_konec
		movwf textPointer+0
		goto LCD_drawText
		
;Spravne! Kod:
LCD_write_t_uhadl
		clrf X
		movlw .2
		movwf Y
		call LCD_setXY
		movlw HIGH t_uhadl
		movwf textPointer+1
		movlw LOW t_uhadl
		movwf textPointer+0
		goto LCD_drawText
						
LCD_showPokusy
		movlw TRUE
		movwf putCharOnly
		
		movlw .30
		movwf X
		
		movlw .2
		movwf Y
		call LCD_setXY
		
		movf pokusy, w
		addlw '0'
		call LCD_drawChar
		
		movlw FALSE
		movwf putCharOnly		
		return

;Zobraz tajne cislo		
LCD_showSecret

		clrf X
		movlw .5
		movwf Y
		call LCD_setXY
		movlw HIGH t_bylo1
		movwf textPointer+1
		movlw LOW t_bylo1
		movwf textPointer+0
		call LCD_drawText

		movf cislo_tajne, w
		call bin2ascii
	
		movlw TRUE
		movwf putCharOnly
					
		movf tens, w
		call LCD_drawChar
		
		movf ones, w
		call LCD_drawChar
		
		movlw HIGH t_bylo2
		movwf textPointer+1
		movlw LOW t_bylo2
		movwf textPointer+0
		goto LCD_drawText		
			
LCD_showActual
		movlw .34
		movwf X
		movlw .3
		movwf Y
		call LCD_setXY
		
		movf cislo_aktualni, w
		call bin2ascii
		
		movf tens, w
		call LCD_drawCislo
		
		movlw .34 + .8
		movwf X
		movlw .3
		movwf Y
		call LCD_setXY		
		
		movf ones, w
		goto LCD_drawCislo
		
LCD_showCode
		movlw .26
		movwf X
		movlw .3
		movwf Y
		call LCD_setXY		
		movlw '7'
		call LCD_drawCislo
		
		movlw .34
		movwf X
		movlw .3
		movwf Y
		call LCD_setXY		
		movlw '6'
		call LCD_drawCislo		
		
		movlw .42
		movwf X
		movlw .3
		movwf Y
		call LCD_setXY				
		movlw '0'
		goto LCD_drawCislo		
		
; **************************************************************************************
; **************  LCD_drawCislo *********************************************************
; **************************************************************************************

LCD_drawCislo

		movwf cislo

		movf X, w
		movwf X_copy
		movf Y, w
		movwf Y_copy
		
		movlw '0'
		subwf cislo, f
		movlw HIGH font_digits_8x16
		movwf fontPointer+1
		movlw LOW font_digits_8x16
		movwf fontPointer+0		;k fontPointer musime pricit 16x base
		
		bcf STATUS, C			;vynuluj Carry
		rlf cislo, f			;x 2
		rlf cislo, f			;x 4
		rlf cislo, f			;x 8		
		rlf cislo, w			;x 16				
		addwf fontPointer+0, f 	;vlezem se do 256

		movlw .8
		movwf i
LCD_dcF
		call getNextFontByte
		call LCD_sendData
		decfsz i, f
		goto LCD_dcF

		;Posun se o 8px nize
		movf X_copy, w
		movwf X
		incf Y_copy, w
		movwf Y
		call LCD_setXY			
		
		movlw .8
		movwf i
LCD_dcS
		call getNextFontByte
		call LCD_sendData
		decfsz i, f
		goto LCD_dcS
				
		return
		
; **************************************************************************************
; **************  LCD_drawText *********************************************************
; **************************************************************************************
		
LCD_drawText

		movlw FALSE
		movwf putCharOnly
		
LCD_dt1	call getNextChar

LCD_drawChar
		iorlw 0x00 
		btfsc STATUS, Z
		return
		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 LCD_sendData
		call getNextFontByte
		call LCD_sendData
		call getNextFontByte
		call LCD_sendData
		call getNextFontByte
		call LCD_sendData
		call getNextFontByte
		call LCD_sendData
		clrw					;Mezera mezi pismeny
		call LCD_sendData
		btfsc putCharOnly, 0
		return
		goto LCD_dt1

getNextChar:
		call getNextChar2 		;To je patch kvuli strankovani
		clrf PCLATH
		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
		;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)
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

; *** SUBRUTINA, CEKEJ nuMilis milisekund ***************************

; *** 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	
;}


; *** SUBRUTINY pro 16bitovy counter ********************************	
; *** Nastavi Zero, pokud jsme na nule

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
	
; *** 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
	
	movlw '0'
	addwf tens, f
	addwf ones, f
	return	

; *****************************************************************	
; ********************** F O N T  D A T A *************************
; *****************************************************************
			org 0x0400
text_table
t1		dt "Uhadni cislo X",  0x00
t2		dt "  X>0 a X<100 ",  0x00
t3		dt " Mas 6 pokusu ",  0x00
t4		dt " Minihra c. 4 ",  0x00
t5		dt " ------------ ",  0x00
t6		dt " Stiskni tlac.",  0x00
t_vetsi	dt ">>X je vetsi<<",  0x00
t_mensi	dt ">>X je mensi<<",  0x00
t_konec dt " Neuhadl jsi. ",  0x00
t_uhadl dt "SPRAVNE!  KOD: ", 0x00
t_bylo1 dt ">>X bylo "     ,  0x00
t_bylo2 dt ".<<"           ,  0x00
t_empty dt "              ",  0x00

			org 0x0500
			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 0x0700
		
font_digits_8x16		                                                          
	dt 0x00, 0xFC, 0xFF, 0xC3, 0xF3, 0xFF, 0xFC, 0x00, 0x00, 0x0F, 0x3F, 0x33, 0x30, 0x3F, 0x0F, 0x00; // Code for char 0	    
	dt 0x00, 0x00, 0x0C, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x3F, 0x3F, 0x30, 0x30, 0x00; // Code for char 1
	dt 0x00, 0x0C, 0x0F, 0xC3, 0xC3, 0xFF, 0x3C, 0x00, 0x00, 0x3C, 0x3F, 0x33, 0x30, 0x3C, 0x3C, 0x00; // Code for char 2
	dt 0x00, 0x0C, 0x0F, 0xC3, 0xC3, 0xFF, 0x3C, 0x00, 0x00, 0x0C, 0x3C, 0x30, 0x30, 0x3F, 0x0F, 0x00; // Code for char 3
	dt 0xC0, 0xF0, 0x3C, 0x0F, 0xFF, 0xFF, 0x00, 0x00, 0x03, 0x03, 0x03, 0x33, 0x3F, 0x3F, 0x33, 0x00; // Code for char 4
	dt 0x00, 0x3F, 0x3F, 0x33, 0x33, 0xF3, 0xC3, 0x00, 0x00, 0x0C, 0x3C, 0x30, 0x30, 0x3F, 0x0F, 0x00; // Code for char 5
	dt 0x00, 0xF0, 0xFC, 0xCF, 0xC3, 0xC3, 0x00, 0x00, 0x00, 0x0F, 0x3F, 0x30, 0x30, 0x3F, 0x0F, 0x00; // Code for char 6
	dt 0x00, 0x0F, 0x0F, 0x03, 0xC3, 0xFF, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00; // Code for char 7
	dt 0x00, 0x3C, 0xFF, 0xC3, 0xC3, 0xFF, 0x3C, 0x00, 0x00, 0x0F, 0x3F, 0x30, 0x30, 0x3F, 0x0F, 0x00; // Code for char 8
	dt 0x00, 0x3C, 0xFF, 0xC3, 0xC3, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x30, 0x30, 0x3C, 0x0F, 0x03, 0x00; // Code for char 9
	dt 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00; // Code for char : (space)

; *** KONEC SOUBORU *************************************************	
	end