; Calculate_samples_offset	; tmp
; Bin2Dec_0_to_255	; pracuje s number,units,tens,hundreds
; Packed_BCD2Dec	; pracuje s number,units,tens,hundreds
; Dec2Packed_BCD	; number, units, tens,hundreds
; INC_packed_BCD_with_carry	;  units,tens,hundreds



; Samples_calc	; Provede nezbytne vypocty pro urceni Vpp, frekvence a dalsich
  ; Vyuziva "find_min_max_in_samples", "find_period"
  ; Dale vyuziva: Samples_calc_period, Samples_calc_frequency,
  ;  Samples_calc_V_rms a Samples_calc_V_avg

; find_min_max_in_samples ; R0,R1,R2,R3,data,CNT,tmp ; Najde minimum a maximum
  ; ve vzorcich
; find_min_max_in_16bit_samples	; R0~R6 ; Analogie s predchozim, ale pro
  ; 16. bitova cisla

; find_period	; R0,R1,R2,R3,R4,R5,R6,data,tmp
  ; PREDTIM JE POTREBA SPUSTIT "find_min_max_in_samples" !!! Pripadne nahrat do
  ; "Samples_MAX_value_SRAM" maximalni nalezenou velikost vzorku!



; Show_float_numkMG_20	; Pracuje s registry jak float_operation.asm -> z toho
  ; plyne, ze soubor float_operation.asm by mel byt includovan drive, nebo je
  ; potreba nadefinovat dane prirazeni uz tady

  ; V pripade, ze bude tento podprogramek "na zacatku" programu, tak se musi
  ; odkomentovat  - tady zakomentovani, protoze uz definovano v graphics.asm
;.DEF units = R0
;.DEF tens = R1
;.DEF hundreds = R2



; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Calculate_samples_offset:
  ; Nejprve vypocet offsetu pro vzorky (vypocita se podle poctu vzorku)
	LDS tmp,number_of_samples_SRAM
  ; Vydelime tmp dvema
	LSR tmp
  ; A odecteme 50 (polovina bodu na displeji)
	SUBI tmp,50
  ; A vysledek ulozime do SRAM
	STS Samples_offset_SRAM,tmp

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Bin2Dec_0_to_255:
  ; prevede cislo ulozene v registru "number" na dekadicke. Dekadicka cisla
  ; budou pote ulozena do registru "units", "tens" a "hundreds"
  ; Prevadi pouze cisla z rozsahu 0~255
	PUSH number	; zazalohujeme si number

	CLR units
	CLR tens
	CLR hundreds

  ; nejdrive si zjistime stovky
Bin2Dec_0_to_255_hundreds:
	CPI number,100
	BRSH Bin2Dec_0_to_255_Add_hundred
  ; Pokud uz nezbyvaji zadne stovky, tak se pokracuje s desitkama
	RJMP Bin2Dec_0_to_255_tens	; a nyni jdeme zkontrolovat desitky

Bin2Dec_0_to_255_Add_hundred:
	INC hundreds
	SUBI number,100
	RJMP Bin2Dec_0_to_255_hundreds	; a znovu kontrola, zda tam neni jeste
  ; jedna stovka

Bin2Dec_0_to_255_tens:
	CPI number,10
	BRSH Bin2Dec_0_to_255_Add_tens

	RJMP Bin2Dec_0_to_255_units

Bin2Dec_0_to_255_Add_tens:
	INC tens
	SUBI number,10
	RJMP Bin2Dec_0_to_255_tens

Bin2Dec_0_to_255_units:
	MOV units,number

	POP number	; a obnovime puvodni cislo

	RET
; *-----------------------------------------*
Packed_BCD2Dec:
  ; Rozdeli data z "number" do "units" a "tens"
	MOV tmp,number	; zaloha number
  ; Nejdrive si ulozime treba spodni bity do "units"
  ; To udelame tak, ze smazeme prvni ctyri MSB bity
	CLT	; smazeme bit v T registru a ten pak budeme pouzivat jako
  ; mazaci bit
	BLD tmp,7
	BLD tmp,6
	BLD tmp,5
	BLD tmp,4
  ; nyni mame smazane horni 4 bity.
	MOV units,tmp	; data si zkopirujeme do registru "units", kde s nimi
  ; muzeme dal pracovat

  ; Ted tedy na horni 4 bity....
	MOV tmp,number	; opet si data zkopirujeme do tmp
	LSR tmp
	LSR tmp
	LSR tmp
	LSR tmp
  ; rotace o 4 doprava (viz treba sada instrukci)
	MOV tens,tmp	; a ulozeni do "tens"

	RET
; *-----------------------------------------*
Dec2Packed_BCD:
  ; Prevede cisla ulozena v "units" a "tens" do number
	CLR number	; smazeme registr "number"

	MOV number,units	; tim jsme si ulozili jednotky
	MOV tmp,tens	; desitky do "tmp"
  ; 4x rotace vlevo
	LSL tmp
	LSL tmp
	LSL tmp
	LSL tmp

	OR number,tmp	; a logicky soucet. Vysledek se zapise do "number"

	RET	; a zpet
; *-----------------------------------------*
INC_packed_BCD_with_carry:
  ; zvysi hodnutu jednotek ,pripadne i desitek a pripade zapise carry
	CLC	; smazani priznaku "carry"

  ; kontrola, zda se nebude zapisovat do dalsiho radu...
	MOV tmp,units	; musime z "units" presunout do "tmp", protoze CPI
  ; pracuje pouze s registry R16-R31
	CPI tmp,9	; pokud je v jednotkach 9, pak nasleduje prenos do
  ; dalsiho radu
	BRNE units_continue	; pokud neni 9, pak se skoci na
  ; "units_continue"

  ; V opacnem pripade se pokracuje tady
	CLR units	; "units" nastavime na 0 (po 9 nasleduje 0)

	MOV tmp,tens
	CPI tmp,9	; ta sama kontrola, ale pro deistky
	BRNE tens_continue	; zase to same. Pokud neni 9, pak se jen
  ; pricte 1
	CLR tens	; "tens" nastavime na 0
	SEC	; a nastavime "carry" do 1 (priznak preteceni)
	RCALL Dec2Packed_BCD	; a pro vetsi prehlednost a lepsi zpracovani
  ; dat, data si jeste prevedema data z "units" a "tens" do packed BCD
	RET


tens_continue:
	INC tens
	RCALL Dec2Packed_BCD
	RET
	
units_continue:
	INC units
	RCALL Dec2Packed_BCD
	RET

; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Samples_calc:
  ; Nastavime pocatek, od ktereho se budou "tahat" data z SRAM
	LDI XH,HIGH(Samples_begin_SRAM)
	LDI XL,LOW(Samples_begin_SRAM)

	LDS data,number_of_samples_SRAM	; Rekneme, kolik vzorku se ma "projet"

	RCALL find_min_max_in_samples	; Zjisti minimum a maximum
  ; Meri napeti spicka-spicka
	RCALL Samples_calc_V_pp


  ; Vypocet (nebo spis prepocet) Vmax
	RCALL Samples_calc_V_max



  ; Nyni se proveri velikost amplitudy. Pokud by totiz byla prilis mala, pak
  ; to znamena, ze merime sum a ne uzitecny signal. A samozrejmne takove mereni
  ; by bylo "spatne"
	LDS R1,Samples_MAX_value_SRAM	; R1=MAX
	LDS R3,Samples_MIN_value_SRAM	; R3=MIN


  ; Vypocte se hodnota spicka-spicka
	SUB R1,R3	; R1=MAX-MIN
	MOV tmp,R1
	CPI tmp,noise_level	; Porovnani s hodnotou sumu
	BRLO S_c_noise	; Pokud bude hodnota spicka-spicka mensi jak
  ; "noise_level", pak se s nejvyssi pravdepodobnosti jedna o sum. V tom	
  ; pripade nema smysl pocitat periodu a dalsi veliciny

  ; Nastavime pocatek, od ktereho se budou "tahat" data z SRAM
	LDI XH,HIGH(Samples_begin_SRAM)
	LDI XL,LOW(Samples_begin_SRAM)
	LDS data,number_of_samples_SRAM	; Rekneme, kolik vzorku se ma "projet"

	RCALL find_period	; Zjisti delku periody a jeji pocatek

  ; Nyni si overime, zda ma smysl provadet dalsi vypocty. Pokud by totiz byla
  ; vypoctena delka periody rovna nula, znamena to, ze perioda nebyla nalezeno.
  ; A prave v tomto pripade nema smysl provadet dalsi vypocty.
;	LDS tmp,Samples_PERIOD_value_SRAM
	MOV tmp,R0	; Hodnota v R0 nebyla zatim prepsana -> toho vyuzijeme
  ; V "tmp" je nyni hodnota o delce periody
	CPI tmp,0	; Porovnani s nulou
	BRNE S_c_calc_float	; Pokud nebyl vysledek nula, skoci se na
  ; "S_c_calc_float"

	RET

S_c_noise:	; Signal byl vyhodnocen jako sum -> delku periody nastavime na
  ; nula, pozici pocatku periody nastavime na $FF -> tim se pozna, ze jsme ani
  ; nezacali merit periodu. Kdybychom merili periodu a delka periody by se
  ; nedala zjistit, pak by se obe promenne vynulovaly.
	CLR tmp
	STS Samples_PERIOD_value_SRAM,tmp
	LDI tmp,$FF
	STS Samples_PERIOD_position_SRAM,tmp
  ; Postupne se pridaji i dalsi promenne

	RET

S_c_calc_float:	; Provede potrebne vypocty a vysledky ulozi do SRAM

  ; Prepocet periody
	RCALL Samples_calc_period

  ; Prepocet frekvence z periody
	RCALL Samples_calc_frequency

  ; Vypocet Vrms
	RCALL Samples_calc_V_rms

  ; Vypocet Vavg (prumer v periode)
	RCALL Samples_calc_V_avg

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
  ; Jednotlive podprogramy pro vypocty jednotlivych velicin. NEJSOU NEZAVISLE!
  ; VZDY se musi, alespon jednou provest "find_min_max_in_samples"
  ; Prave proto, ze tento algoritmus zabira celkem dost casu (muse se overit
  ; vsechny vzorky), jsou algoritmy uzpusobeny tak, aby stacilo tuto proceduru
  ; provest pouze jednou
  ; Pozor na komentare!

Samples_calc_V_pp:
  ; Vyzaduje: find_min_max_in_samples
S_c_V_pp:
  ; XH,XL a data nemusime zovnu nastavotat. Podprogramy jsou napsane tak, aby
  ; pri ukonceni nastavily tyto promenne na puvodni hodnotu

  ; Prepocita se na realnou hodnotu
	; Zjistime si rozdil maximalni a minimalni hodnoty
	LDS R1,Samples_MAX_value_SRAM	; Stahneme si maximalni nalezenou
  ; hodnotu
	LDS R3,Samples_MIN_value_SRAM	; Stahneme si minimalni nalezenou
  ; hodnotu
	MOV number,R1
	SUB number,R3	; ( number = X(max) - X(min) )


	MOV tmp,number	; Presun vysledku do tmp (Mg)
	CALL Convert_8bit_unsigned_to_float_A	; Prevede se na float, aby se
  ; s cislem dalo pracovat

  ; Zjisti se zvoleny rozsah a podle toho se jako float B nahraje dana
  ; konstanta
	CALL Load_range_LSB_to_Z	; Do ukazetele Z se ulozi hodnota LSB
  ; jednoho vzorku. Podle teto reference se vypocita skutecna hodnota
	CALL Save_Z_to_B	; Konstanta se ulozi jako B

	CALL float_A_mul_B	; A=A*B
  ; nastavi se X pointer
	LDI XH,HIGH(Samples_PEAK_value_float_SRAM)
	LDI XL,LOW(Samples_PEAK_value_float_SRAM)
	CALL Save_A_to_X	; A tam se ulozi vysledek
  ; Meri maximalni napeti
	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Samples_calc_V_max:
  ; Vyzaduje: find_min_max_in_samples
S_c_V_max:
	LDS tmp,Samples_MAX_value_SRAM	; Vezme se maximalni hodnota
  ; Osetreni proti spatnemu vypoctu - pokud by byla max.hodnota 255 -> 255-127
  ; = 128 -> tzn. 1000 000 -> bylo by algoritmem
  ; "Convert_8bit_signed_to_float_A" vyhodnoceno jako zaporne -> spatne
	CPI tmp,255
	BRNE S_c_V_max_sub	; Pokud cislo neni 255, skok
	DEC tmp	; V opacnem pripade se cislo snizi o 1

S_c_V_max_sub:
	SUBI tmp,127	; Posun o 127 -> srovnani se "skutecnou nulou"
	CALL Convert_8bit_signed_to_float_A	; Prepocte se na float A

	CALL Load_range_LSB_to_Z
	CALL Save_Z_to_B

	CALL float_A_mul_B	; A=A*B
  ; nastavi se X pointer
	LDI XH,HIGH(Samples_VMAX_value_float_SRAM)
	LDI XL,LOW(Samples_VMAX_value_float_SRAM)
	CALL Save_A_to_X	; A tam se ulozi vysledek

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Samples_calc_period:
  ; Vyzaduje: find_period (a to vyzaduje find_min_max_in_samples)
S_c_period:
  ; PERIODA
	LDS tmp,Samples_PERIOD_value_SRAM	; Zkopirovani informace o delce
  ; periody do "tmp"
	CALL Convert_8bit_unsigned_to_float_A	; Prevod na float

  ; Ted je potreba podle aktualni casove zakladny urcit "hodnotu" 1px
	CALL Load_time_base_LSB_to_Z	; Do ukazatele Z se ulozi vertikalni
  ; "hodnota" jednoho pixelu (vzorku)
	CALL Save_Z_to_B	; Konstanta se ulozi jako B

  ; Matematicka operace
	CALL float_A_mul_B	; A=A*B = delka periody
  ; nastavi se X pointer
	LDI XH,HIGH(Samples_PERIOD_value_float_SRAM)
	LDI XL,LOW(Samples_PERIOD_value_float_SRAM)
	CALL Save_A_to_X	; A tam se ulozi vysledek

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Samples_calc_frequency:
  ; Vyzaduje: Samples_calc_period (a ty dale vyzaduji: find_period,
  ; 	find_min_max_in_samples)
S_c_frequency:
  ; FREKVENCE
;	LDI XH,HIGH(Samples_PERIOD_value_float_SRAM)
;	LDI XL,LOW(Samples_PERIOD_value_float_SRAM)
;	CALL Save_X_to_A	; A tam se ulozi vysledek
  ; zakomentovano z dovodu, ze pred timto se musi stejne spustit
  ; "Samples_calc_period", takze vysledek bude v A

  ; Nyni je v "A" ulozena perioda -> prevracenim ziskame frekvenci
	CALL float_A_to_B	; B=A
	CALL float_one_div_B	; B=1/B -> B=frekvence
  ; nastavi se X pointer
	LDI XH,HIGH(Samples_FREQUENCY_value_float_SRAM)
	LDI XL,LOW(Samples_FREQUENCY_value_float_SRAM)
	CALL Save_B_to_X	; A tam se ulozi vysledek

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Samples_calc_V_rms:
  ; Vyzaduje: find_period (a to vyzaduje find_min_max_in_samples)
S_c_V_RMS:
  ; V RMS -> SQRT( ( SUM_i~T(u*u)  )/T)
	LDS R6,Samples_PERIOD_value_SRAM	; delka periody (pocet kroku)
	LDS R1,Samples_PERIOD_position_SRAM	; pocatek periody (pocatek
  ; xove souradnice)

  ; Pamet pro vysledek -> pro poradek ty same registry, ktere pote pouzivaji
    ; podprogramy na prevod do float
	CLR R2	; M1	nejnizsi bajt
	CLR R3	; M2
	CLR R4	; M3	nejvyssi bajt

	CLR R5	; Pro pripad, ze bude prenos do vyssiho radu (proste prazdny
  ; registr)

  ; Najdeme si pocatek periody
    ; Nastavime se ukazatelem na pocatek
	LDI XH,HIGH(Samples_begin_SRAM)
	LDI XL,LOW(Samples_begin_SRAM)
    ; A pricteme Samples_PERIOD_position_SRAM
	ADD XL,R1	; spodnich 8bitu
	ADC XH,R2	; 0 (R2) + C

  ; Takze nyni X ukazuje na pocatek periody

S_c_V_RMS_calc_sum:
	LD tmp,X+	; Do tmp se ulozi vrozek
	SUBI tmp,127

	MULS tmp,tmp	; R0:R1=tmp^2 (tmp*tmp) - na druhou

	ADD R2,R0	; Pricteme spodnich 8 bitu
	ADC R3,R1	; Pricte se hornich (po nasobeni) 8 bitu + Carry
	ADC R4,R5	; A pokud by doslo k preteceni registru R3 -> C se
  ; prenese do R4

	DEC R6	; Odecte "jeden krok"
	BRNE S_c_V_RMS_calc_sum	; Dokud nebude pocet kroku roven nule,
  ; pokracuje se v cyklu


  ; Pokud PC "dojde" sem, pak je vysledek ulozen v R4:R2 -> to je ten "spravny"
    ; format pro "Convert_24bit_unsigned_to_float_A"
	CALL Convert_24bit_unsigned_to_float_A
  ; Takze nyni mame v A integral, potazmo SUMU

	LDS tmp,Samples_PERIOD_value_SRAM	; Do "tmp" (Mg) si ulozime
  ; informaci o tom, jak je dlouha perioda
	CALL Convert_8bit_unsigned_to_float_B	; A prevede se to na float B
  ; Shrnuti: A = Suma (integral) ; B = T

  ; takze nyni se provede deleni
	CALL float_A_div_B


  ; takze ted uz jen zbyva ta odmocnina... Jenom...
	CALL float_SQRT_A	; A=SQRT(A)

  ; Korekce RMS
	LDI tmp,Corr_VRMS_sub	; Do tmp se nahraje korekce
	CALL Convert_8bit_unsigned_to_float_B

	CALL float_A_plus_B	; Vypocet korekce




  ; Takze ted je v A ulozena hodnota RMS. Musi se prepocitat na volty podle
  ; aktualniho rozsahu
  ; Zjisti se zvoleny rozsah a podle toho se jako float B nahraje dana
  ; konstanta
	CALL Load_range_LSB_to_Z	; Do ukazetele Z se ulozi hodnota LSB
  ; jednoho vzorku. Podle teto reference se vypocita skutecna hodnota
	CALL Save_Z_to_B	; Konstanta se ulozi jako B

	CALL float_A_mul_B	; A=A*B
  ; nastavi se X pointer
	LDI XH,HIGH(Samples_VRMS_value_float_SRAM)
	LDI XL,LOW(Samples_VRMS_value_float_SRAM)
	CALL Save_A_to_X	; A tam se ulozi vysledek

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Samples_calc_V_avg:
  ; Vyzaduje: find_period (a to vyzaduje find_min_max_in_samples)
S_c_V_AVG:
  ; V AVG -> (SUM i~T(u)/T
	LDS R6,Samples_PERIOD_value_SRAM	; delka periody (pocet kroku)
	LDS R1,Samples_PERIOD_position_SRAM	; pocatek periody (pocatek
  ; xove souradnice)

  ; Pamet pro vysledek -> pro poradek ty same registry, ktere pote pouzivaji
    ; podprogramy na prevod do float
	CLR R2	; R2 (M1)	nejnizsi bajt
	CLR R3	; R3 (M2)	nejvyssi bajt
  ; Staci pouze 2 registry (max hodnota 255 a muze se opakova max 255 krat)

	CLR R5	; Pro pripad, ze bude prenos do vyssiho radu (proste prazdny
  ; registr)

  ; Najdeme si pocatek periody
    ; Nastavime se ukazatelem na pocatek
	LDI XH,HIGH(Samples_begin_SRAM)
	LDI XL,LOW(Samples_begin_SRAM)
    ; A pricteme Samples_PERIOD_position_SRAM
	ADD XL,R1	; spodnich 8bitu
	ADC XH,R2	; 0 (R2) + C

  ; Takze nyni X ukazuje na pocatek periody

S_c_V_AVG_calc_sum:
	LD R0,X+	; Do tmp se ulozi vzorek

	ADD R2,R0	; Pricteme vzorek do LSB mezivysledku
	ADC R3,R5	; R3 = R3+R5( to je nula) + C (a o to tady jde)

	DEC R6	; Odecte se "jeden krok"
	BRNE S_c_V_AVG_calc_sum	; Dokud nebude pocet kroku roven nule,
  ; pokracuje se v cyklu

  ; Nutno podotknout, ze "skutecnou" nulu reprezentuje hodnota 127. Takze
  ; se na to nesmime zapomenout a po vydeleni periodou pridat tuto korekci.

  ; Takze nyni cislo prevedeme na float jako bezeznamenkove
	CALL Convert_16bit_unsigned_to_float_A	; Suma - A

	LDS tmp,Samples_PERIOD_value_SRAM	; pocet vzorku se taky prevede
  ; na float
	CALL Convert_8bit_unsigned_to_float_B	; Pocet vzorku v periode - B

	CALL float_A_div_B	; A=A/B -> ziskame prumer (0~255 ale realne
  ; cislo)

  ; A nyni od tohoto vysledku odecteme 127, takze se budeme pohybovat -127~127
	LDI tmp,127
	CALL Convert_8bit_unsigned_to_float_B	; B=127

	CALL float_A_minus_B	; A=prumer -127 -> ziskame znamenkovy prumer

  ; A ted uz jen podle aktualniho rozsahu prepocitat na volty

	CALL Load_range_LSB_to_Z	; Do ukazetele Z se ulozi hodnota LSB
  ; jednoho vzorku. Podle teto reference se vypocita skutecna hodnota
	CALL Save_Z_to_B	; Konstanta se ulozi jako B

	CALL float_A_mul_B	; A=A*B
  ; nastavi se X pointer
	LDI XH,HIGH(Samples_VAVG_value_float_SRAM)
	LDI XL,LOW(Samples_VAVG_value_float_SRAM)
	CALL Save_A_to_X	; A tam se ulozi vysledek

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
find_min_max_in_samples:
  ; Projde ulozene vzorky a zjisti minimum a maximum. Navratove hodnoty
  ; (souradnice) jsou pak ulozeny v:
  ; R0/Samples_MAX_position_SRAM (x max),
  ; R1/Samples_MAX_value_SRAM (y max),
  ; R2/Samples_MIN_position_SRAM (x min)
  ; a R3/Samples_MIN_value_SRAM (y min).
  ; Data v R0 udavaji xovou souradnici maxima, R1 udava velikost
  ; maxima. To same plati pro R2 a R3

  ; Pouzite registry: XH,XL - pocatek hodnot ulozenych v SRAM - proto X
  ; data - pocet vzorku (0 - zadny pocet kroku ; 1 - jeden krok atd...)
  ; ^^^^^^ - mohlo by se zadat "na pevno", ale pak by se tento algoritmus
  ; nedal vyuzivat dynamicky (napr. bychom potrebovali zjistit minimum z uplne
  ; jine pameti a uplne jinych vzorku, nebo pri zvoleni jineho poctu vzorku)

  ; CNT - pocita si vzorky. Interni promenna

  ; Zaloha Xove souradnice
	PUSH XH
	PUSH XL

	CLR CNT	; pocita kolik vzorku jsme uz prosli

	DEC data	; Ve skutecnosti musime udelat o jeden krok mene ->
  ; -> kvuli tomu, ze se pocita od nuly a taky aby to korespondovalo
  ; s promennou "number_of_samples_SRAM"

;	CLR R0
;	CLR R2
  ; ^^ lze zakomentovat - vzdy se musi najit alespon minimum, nebo maximum

	CLR R1	; Zatim nalezene maximum - aby bylo podle ceho srovnavat

	LDI tmp,255
	MOV R3,tmp	; A do R3 (y min) ulozime 255 - kvuli porovnavani

find_min_max_in_samples_for:
	CP CNT,data	; porovnani poctu pozadovanych kroku a jiz udelanych
	BRSH find_min_max_in_samples_end	; Pokud jsme dosahli jiz
  ; pozadovanych kroku, pak nasleduje vyhodnoceni

	LD tmp,X+	; aktualni vzorek se nacte do "tmp"
	CP R1,tmp	; porovnani velikosti aktualniho vzorku a posledni
  ; maximalni ulozenou hodnotou
	BRLO find_min_max_in_samples_for_new_max	; pokud byl aktualni vzorek
  ; vetsi jak posledni ulozeny, pak se zaktualizuje hodnota v R1 a R0

find_min_max_in_samples_for_min:
	CP tmp,R3	; Porovnani soucasne hodnoty s poslednim "znamym"
  ; minimem
	BRLO find_min_max_in_samples_for_new_min	; pokud je aktualni
  ; hodnota mensi jak posledni ulozena v R3 -> skok

	INC CNT	; dalsi vzorek - cislovani
	RJMP find_min_max_in_samples_for	; Jinak se posuneme o jeden
  ; vzorek dal a znova se provedou potrebne operace
; *-----------------------------------------*
find_min_max_in_samples_for_new_max:
	MOV R1,tmp	; Tim si zaktualizujeme zatim nejvyssi nalezenou
  ; hodnotu
	MOV R0,CNT	; A do R0 nahrajeme aktualni x souradnici

	RJMP find_min_max_in_samples_for_min	; nasleduje kontrola,
  ; zda toto nebylo i prvni (a treba posledni) minimum - pokud by bylo ulozeno
  ; "data" vzorku a jejich tendence by byla vzrustajici, pak by se nikdy
  ; nezapsalo minimum do pameti -> minimum by se rovnalo 255 -> FAIL
; *-----------------------------------------*
find_min_max_in_samples_for_new_min:
	MOV R3,tmp	; nova Y hodnota
	MOV R2,CNT	; nova X hodnota pro minimum
	INC CNT	; dalsi vzorek - cislovani
	RJMP find_min_max_in_samples_for
; *-----------------------------------------*
find_min_max_in_samples_end:
  ; Obnova Xove souradnice
	POP XL
	POP XH

	INC data


  ; A ulozeni vysledku do SRAM - pozdeji se bude hodit
	STS Samples_MAX_position_SRAM,R0
	STS Samples_MAX_value_SRAM,R1
	STS Samples_MIN_position_SRAM,R2
	STS Samples_MIN_value_SRAM,R3

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
find_min_max_in_16bit_samples:
  ; Projde ulozene vzorky a zjisti minimum a maximum. Protoze se jedna
  ; o 16.bitova cisla, tak prvni je hornich 8 bitu a pak nasleduje spodnich
  ; 8 bitu.
  ; Navratove hodnoty (souradnice) jsou pak ulozeny v:
  ; R0/Samples_MAX_position_SRAM (x max),
  ; R1/Samples_MAX_value_SRAM (y max hornich 8 bitu)
  ; R2/Samples_MAX_value_low_SRAM (y max spodnich 8 bitu)

  ; R3/Samples_MIN_position_SRAM (x min)
  ; R4/Samples_MIN_value_SRAM (y min hornich 8 bitu)
  ; R5/Samples_MIN_value_low_SRAM (y min spodnich 8 bitu)

  ; Data v R0 udavaji xovou souradnici maxima, R1/R2 udava velikost
  ; maxima. To same plati pro R3,R4 a R5
  ; Souradnice plati pro hornich 8 bitu! To znamena, ze se ulozi "adresa" na
  ; MSB bajt

  ; Pouzite registry: XH,XL - pocatek hodnot ulozenych v SRAM - proto X
  ; data - pocet vzorku (0 - zadny pocet kroku ; 1 - jeden krok atd...)
  ; ^^^^^^ - mohlo by se zadat "na pevno", ale pak by se tento algoritmus
  ; nedal vyuzivat dynamicky (napr. bychom potrebovali zjistit minimum z uplne
  ; jine pameti a uplne jinych vzorku, nebo pri zvoleni jineho poctu vzorku)

  ; R6 - pocita si vzorky. Interni promenna

  ; Zaloha Xove souradnice
	PUSH XH
	PUSH XL

;	CLR R6	; pocita kolik vzorku jsme uz prosli
	LDI tmp,255
	MOV R6,tmp	; Aby se zacalo pocitat od nuly

;	CLR R0
;	CLR R3
  ; ^^ lze zakomentovat - vzdy se musi najit alespon minimum a maximum

  ; Zatim nalezene maximum nastavime na 0
	CLR R1	; Max H
	CLR R2	; Max L

  ; Zatim nalezene minimum nastavime na $FF FF
	LDI tmp,$FF
	MOV R4,tmp	; Min H
	MOV R5,tmp	; Min L

  ; Tak a ted cyklycky projet vzorky
find_min_max_in_16bit_samples_for:
	INC R6
	CP R6,data	; Porovnani poctu pozadovanych kroku a jiz udelanych
	BREQ find_min_max_in_16bit_samples_end	; Pokud pocet kroku bude roven
  ; pozadavku -> vyskoci se z algoritmu

	LD tmp,X	; Nacteni MSB bajtu
	CP tmp,R1	; Porovnani vzorku s maximalni nalezenou hodnotou
	BREQ f_m_m_i_16b_s_Tst_new_max	; Pokdu bude MSB bajt shodny, pak se
  ; muze, ale nemusi jednat o nove maximum. Musi se overit i LSB bajt
	BRSH f_m_m_i_16b_s_New_max
f_m_m_i_16b_s_f_Tst_min:	; Pripadne se testuje minimum

  ; Zatim nic
	LD tmp,X+	; Nacteni MSB vzorku
	CP tmp,R4	; porovnani s MSB nejnizsi nalezenoou hodnotou
	BREQ f_m_m_i_16b_s_Tst_new_min	; Pokud jsi jsou rovny MSB
	BRLO f_m_m_i_16b_s_New_min	; Pokud je MSB mesni, pak je jasne, ze
  ; bylo nalezeno nove minimum


	ADIW XH:XL,1	; Pokud se nejednalo ani o nove minimum, pak se
  ; posuneme s X pointerem o 1. Je to proto, ze prikaz LD tmp,X+ uz jeden posuv
  ; udela

	RJMP find_min_max_in_16bit_samples_for


f_m_m_i_16b_s_Tst_new_max:
	ADIW XH:XL,1	; X pointer se posune o 1 vpred -> nacte se nasledujici
  ; vzorek
	LD tmp,X	; Nacte se dalsi vzorek
	CP R2,tmp	; Porovnani max_nalezeneho_L a aktualni hodnoty
	LD tmp,-X	; A ukazatel se opet posune na hornich 8 bajtu

	BRSH f_m_m_i_16b_s_f_Tst_min	; Pokud je nami nalezene maximum vetsi,
  ; nebo rovno jak aktualni hodnota, pak se nejedna o maximum -> test na
  ; minimum. Proto musime nastavit i ukazatel X na puvodni MSB bajt

  ; V opacnem pripade jsme nalezli nove maximum. V "tmp" je nyni MSB bajt
;	MOV R1,tmp	; Do R1 se ulozi MSB bajt	; Jsou stejne -> nemusi
  ; se preukladat :)
	ADIW XH:XL,1	; X pointer se posune o 1 vpred -> nacte se nasledujici
  ; vzorek
	LD R2,X		; Do R2 se ulozi LSB bajt

	MOV R0,R6	; A ulozi se informace o pozici
  ; Xova souradnice je tedy nastavena opet na MSB bajt, muze se zkontrolovat
  ; minimum
	LD tmp,-X	; A ukazatel se opet posune na hornich 8 bajtu

	RJMP f_m_m_i_16b_s_f_Tst_min


f_m_m_i_16b_s_New_max:	; Pokud bylo nalezeno nove maximum
	MOV R1,tmp	; Zapise se MSB bajt

	ADIW XH:XL,1	; X pointer se posune o 1 vpred -> nacte se nasledujici
  ; vzorek
	LD R2,X	; Nacte se dalsi vzorek -> Zapise se LSB bajt

	MOV R0,R6	; A ulozi se informace o pozici

	LD tmp,-X	; A ukazatek X se opet posune na MSB bajt
	RJMP f_m_m_i_16b_s_f_Tst_min

f_m_m_i_16b_s_Tst_new_min:
  ; MSB bajty jsou stejne... Musi se tedy zkontrolovat LSB bajty
	LD tmp,X+	; Nacte se LSB vzorku
	CP R5,tmp

	BRLO find_min_max_in_16bit_samples_for	; Pokud je nami nalezeny vzorek
  ; mensi, nebo roven aktualnimu, pak se nejedna o nove minimum

  ; V opacnem pripade se jedna o nove minimum :) Staci Zkopirovat informaci
  ; o LSB bajtu, protoze MSB bajty jsou uplne stejne
	MOV R5,tmp	; Presun LSB bajtu do R5

	MOV R3,R6	; presun informace o pozici

	RJMP find_min_max_in_16bit_samples_for	; A test dalsiho cisla....

f_m_m_i_16b_s_New_min:
	MOV R4,tmp	; MSB se preulozi do R4
	LD R5,X+	; A nacte se dalsi cast -> LSB bajt

	MOV R3,R6	; A preulozi se informace o pozici minima
	RJMP find_min_max_in_16bit_samples_for	; A pokracuje se na dalsim
  ; vzorku


find_min_max_in_16bit_samples_end:
  ; Obnova Xove souradnice
	POP XL
	POP XH

	INC data

    ; A vysledky se preulozi do SRAM - pozdeji se muze zpracovavat
	STS Samples_MAX_position_SRAM,R0
	STS Samples_MAX_value_SRAM,R1
	STS Samples_MAX_value_low_SRAM,R2

	STS Samples_MIN_position_SRAM,R3
	STS Samples_MIN_value_SRAM,R4
	STS Samples_MIN_value_low_SRAM,R5

	RET
; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
find_period:
  ; Zjisti delku periody. PREDTIM JE POTREBA SPUSTIT "find_min_max_in_samples"
  ; Tuto delku ulozi do:
  ;  R0/Samples_PERIOD_value_SRAM
  ; Informace o pozici pocatku periody je ulozena v:
  ;  R5/Samples_PERIOD_position_SRAM

  ; Jako vstupni parametry
  ; slouzi:
  ; ukazatel X (urcuje, od ktere adresy se maji "tahat" vzorky)

  ; "data" - zde je informace o poctu vzorku, ktere se maji projit
  ; 



  ; Zalohovani adresy pocatku vzorku
	PUSH XH
	PUSH XL

	PUSH data	; Zaloha poctu vzorku

  ; ZAKOMENTOVANO - JAK JE UVEDENO VYSE. JE POTREBA SPUSTIT
  ; "find_min_max_in_samples". Je to z duvodu uspory vypocetniho casu. Tento
  ; podprogram se musi volat tak jako tak. Je zbytecne, aby se 2x provadela
  ; temer jedna a ta sama procedura
;	RCALL find_min_max_in_samples	; Najde minimum a maximum
; 
;   ; Obnova registru
; 	POP data
; 	POP XL
; 	POP XH
;   ; Zaloha
; 	PUSH XH
; 	PUSH XL
; 	PUSH data


	LDS R1,Samples_MAX_value_SRAM	; Stahneme si jiz zjistene maximum
	LDS R0,Samples_MIN_value_SRAM	; Do R2 se ulozi zjistene minimum
  ; R1=MAX
  ; R0=MIN

  ; Nyni se vypocita optimalni "delta_max"
	MOV R2,R1	; R1,R2=MAX
	SUB R2,R0	; R2=MAX-MIN=2*delta_max
	LSR R2		; R2=(MAX-MIN)/2 (rotace vpravo - deleni 2)
  ; R2=delta_max


  ; Ted se najde "prvni" spicka. Meze jsou MAX-(delta_max) ~ MAX
	SUB R1,R2	; R1=MAX-delta_max
  ; (Hodnota maxima jiz neni dulezita, zadny vzorek nemuze byt vetsi jak MAX)


  ; ted se zjisti, jestli je signal analogovy, nebo digitalni. V pripade, ze
  ; bude analogovy, pak se pouzije jiny algoritmus, nez kdyby byl digitalni!
  ; Digitalni signal pozname tak, ze rozdil mezi nekterymi dvema vzorky bude
  ; urcite vetsi jak "delta_max" (R2)
f_p_is_digital:	; Registry R1 a R2 nesmime smazat. Ostatni se mohou pouzit
	DEC data
	BREQ f_p_analog	; Pokud se ani jednou nevyskytnou dva vzorky, u kterych
  ; by byl rozil vetsi jak delta_max (R2)

	LD R4,X+	; nacteme vzorek
	LD R5,X		; a nasledujici
  ; Zjistime, ktery je vetsi (budou se pak odecitat -> potrebujeme absolutni
  ; hodnotu
	CP R5,R4
	BRSH f_p_is_digital_R5_HS	; Pokud bude nasledujici vzorek (R5)
  ; vetsi, nebo roven predchozimu (R4)
f_p_is_digital_R5_LO:	; R5<R4
	SUB R4,R5	; R4-R5
	CP R4,R2	; porovnani rozdilu (R5) a delta_max (R2)
	BRLO f_p_is_digital	; Pokud bude rozdil mensi, jak delta_max (R2),
  ; pak se zkontroluje dalsi dvojce (resp. R5 a nasledujici vzorek)

  ; V opacnem pripade se pokracuje na "f_p_jmp_to_digital"
	RJMP f_p_jmp_to_digital


f_p_is_digital_R5_HS:	; R5>=R4
	SUB R5,R4	; rozdil vzorku se ulozi do R5
	CP R5,R2	; porovnani rozdilu (R5) a delta_max (R2)
	BRLO f_p_is_digital	; pokud je rozdil mensi, jak delta_max (R2),
  ; pak se se zkontroluje dalsi dvojce vzorku  (resp. R5 a nasledujici vzorek)

  ; V opacnem pripade se pokracuje na "f_p_jmp_to_digital"

f_p_jmp_to_digital:
	RJMP f_p_digital	; Skok na algoritmus pro digitalni signal



f_p_analog:
   ; Obnova registru
 	POP data
 	POP XL
 	POP XH
   ; Zaloha
 	PUSH XH
	PUSH XL
 	PUSH data

  ; Zmenime (MAX-delta_max). Je to zejmena kvuli sumum. Takto je cely
  ; algoritmus o neco robustnejsi
	LSR R2	; R2=delta_max/2
	LSR R2
	LDS R1,Samples_MAX_value_SRAM	; R1=MAX
	SUB R1,R2	; R1=MAX-delta_max(nove)


  ; Nyni se musime dostat POD komparacni uroven, jinak by doslo ke SPATNEMU
  ; mereni
f_p_signal_lower_than_Max_delta_max:
	DEC data	; pocet_kroku=pocet_kroku-1
	BREQ f_p_period_not_found	; Pokud "dojdou" kroky

	LD tmp,X+	; vzorek se zkopiruje do "tmp"
	CP tmp,R1	; porovnani s komapracni urovni
	BRSH f_p_signal_lower_than_Max_delta_max	; pokud je "tmp" (vzorek) vetsi, nebo
  ; roven urovni porovnavaci urovni R1, pak se posuneme o jeden vzorek dal

  ; V opacnem pripade se pokracuje tady
f_p_find_1st_extreme:
	DEC data	; pocet_kroku=pocet_kroku-1
	BREQ f_p_period_not_found	; Pokud dojdou kroky
	LD tmp,X+
	CP tmp,R1	; Porovnani aktualniho vzorku (tmp) s minimalni hranici
  ; (R1)
	BRSH f_p_find_1st_extreme_begin_found	; Pokud je nalezen vzorek,
  ; ktery je vetsi, nebo roven (MAX-delta_max), pak se provede skok
	RJMP f_p_find_1st_extreme	; V opacnem pripade se postupuje dal

f_p_find_1st_extreme_begin_found:
	CLR R0	; R0 - pocita delku periody - nastavime na nulu
	MOV R6,data	; A ulozime si aktualni hodnotu Xove souradnice do R6

	MOV R2,tmp	; Hodnotu nalezeneho vzorku si ulozime do R2

f_p_find_1st_extreme_find_begin_of_period:	; Ma za cil najit pocatek
  ; periody. Toto dosahne tak, ze bude postupne hledat maximum v rozmezi
  ; MAX-delta_max ~ MAX. Jakmile se Ynova souradnice dostane pod tuto hranici,
  ; pak se od nalezeneho maxima zacne pocitat pocatek periody. A v tomto
  ; momentu se zacne hledat dalsi extrem
	DEC data
	BREQ f_p_period_not_found	; V pripade, ze se "projedou" vsechny
  ; vzorky a nedostaneme se pod hranici, pak neni signal neni periodicky, nebo
  ; se jeho perioda "nevesla" do poctu techto vzorku

	LD tmp,X+
	INC R0
	CP R2,tmp
	BRLO f_p_find_1st_extreme_begin_found	; Pokud bylo nalezeno nove
  ; maximum, pak se skoci na dane navesti

	CP tmp,R1	; Porovnani aktualniho vzorku (tmp) s minimalni hranici
  ; (R1)
	BRLO f_p_find_2st_extreme	; Pokud jsme se dostali pod
  ; tuto hranici, pak je na case hledat dalsi extrem

	RJMP f_p_find_1st_extreme_find_begin_of_period	; V opacnem pripade
  ; se pokracuje v hledani dal




f_p_period_not_found:
  ; Obnova promennych
	POP data
	POP XL
	POP XH

	CLR R0	; Nastavi se na nula -> Specialni cislo (neni jej mozne
  ; namerit)
	CLR R5
	STS Samples_PERIOD_value_SRAM,R0
	STS Samples_PERIOD_position_SRAM,R5

	RET


  ; Pokud se SW dostane sem, pak se hleda dalsi maximum
  ; Nejprve se musi najit hranice, ktera presahne (MAX-delta_max)
f_p_find_2st_extreme:
	DEC data
	BREQ f_p_period_not_found	; Opet. Pokud jsou jiz vsechny vzorky
  ; "projety", pak se zkratka dalsi extrem nenasel a perioda nemuze byt zmerena

	INC R0	; Delka periody se zvysi o 1
	LD tmp,X+
	CP tmp,R1	; Porovnani aktualniho vzorku (tmp) s minimalni hranici
	BRLO f_p_find_2st_extreme	; Pokud neni velikost aktualniho vzorku
  ; vetsi jak pozadovana mez, pak se pokracuje v hledani...

  ; V opacnem pripade jsme nalezli pozadovanou mez
	MOV R4,tmp	; R4 - nalezeno nove maximum Y hodnota
	MOV R5,data	; R5 - nalezeno nove maximum X hodnota
	MOV R3,data	; R3=data (pocatek druheho extremu)

f_p_find_2st_extreme_begin_found:
  ; A opet "projedeme" dalsi vzorky a to tak dlouho, dokud se nedostaneme pod
  ; tuto mez, nebo doku nebude hodnota v "data" nulova (prolezeny vsechny
  ; vzorky)
	DEC data
	BREQ f_p_period_not_found	; V pripade, ze jsme dosli "na konec"

	LD tmp,X+

	CP tmp,R1	; Porovnani soucasneho vzorku a "hranice"
	BRLO f_p_period_found	; Pokud se aktualni vzorek bude pohybovat pod
  ; touto hranici, pak je jiz pozadovane maximum nalezeno

	CP R4,tmp	; Porovnani nalezeneho maxima s aktualni hodnotou
	BRLO f_p_find_2st_extreme_new_max	; Pokud je nova hodnota vetsi
  ; jak posledni nalezena -> skok
	RJMP f_p_find_2st_extreme_begin_found


f_p_find_2st_extreme_new_max:
	MOV R4,tmp	; Ulozeni noveho maxima - Y
	MOV R5,data	; Ulozeni Xove souradnice - X
	RJMP f_p_find_2st_extreme_begin_found



f_p_period_found:
	SUB R3,R5	; Vypocet, kolik se musi pricist k R0, aby se ziskala
  ; perioda (od pocatku extremu po maximum v extremu)
	ADD R0,R3	; A vypocet celkove periody

  ; Obnova registru
	POP data
	POP XL
	POP XH

	MOV R5,data	; Zkopirovani z data treba do R5
	SUB R5,R6	; Pocatek - pocatek vzorkovani -> xova souradnice
	DEC R5	; korekce

  ; Ulozeni vysledku do SRAM
	STS Samples_PERIOD_value_SRAM,R0
	STS Samples_PERIOD_position_SRAM,R5

	RET





f_p_digital_period_not_found:
  ; Obnova promennych
	POP data
	POP XL
	POP XH

	CLR R0	; Nastavi se na nula -> Specialni cislo (neni jej mozne
  ; namerit)
	CLR R5
	STS Samples_PERIOD_value_SRAM,R0
	STS Samples_PERIOD_position_SRAM,R5

	RET

  ; V pripade, ze je signal digitalni, pak se pouzije tento algoritmus
f_p_digital:
   ; Obnova registru
 	POP data
 	POP XL
 	POP XH
   ; Zaloha
 	PUSH XH
 	PUSH XL
 	PUSH data

  ; Nyni se musime dostat POD komparacni uroven, jinak by doslo ke SPATNEMU
  ; mereni
f_p_digital_signal_lower_than_Max_delta_max:
	DEC data	; pocet_kroku=pocet_kroku-1
	BREQ f_p_digital_period_not_found	; Pokud "dojdou" kroky

	LD tmp,X+	; vzorek se zkopiruje do "tmp"
	CP tmp,R1	; porovnani s komapracni urovni
	BRSH f_p_digital_signal_lower_than_Max_delta_max	; pokud je
  ; "tmp" (vzorek) vetsi, nebo roven urovni porovnavaci urovni R1, pak se
  ; posuneme o jeden vzorek dal

  ; V opacnem pripade se pokracuje tady
f_p_digital_find_1st_raising_edge:	; Musime nalezt nabeznou hranu. Tu
  ; najdeme tak, ze hodnota vzorku prekroci mez (R1)
	DEC data	; pocet_kroku=pocet_kroku-1
	BREQ f_p_digital_period_not_found	; Pokud "dojdou" kroky

	LD tmp,X+	; Nacteni vzorku
	CP tmp,R1	; porovnani s hranici
	BRLO f_p_digital_find_1st_raising_edge	; Pokud jsme stale pod hranici,
  ; pak opakovat

  ; V opacnem pripade jsme nalezli nebeznou hranu. Takze ted musime zacit
  ; pocitat vzdalenost a pri tom musime hledat sestupnou hranu
	CLR R0	; pocita T (periodu)
	MOV R6,data	; Ulozi se aktualni hodnota Xove souradnice

f_p_digital_find_1st_falling_edge:
	DEC data	; pocet_kroku=pocet_kroku-1
	BREQ f_p_digital_period_not_found	; Pokud "dojdou" kroky

	LD tmp,X+	; dalsi vzorek
	INC R0	; zvyseni delky periody o 1
	CP tmp,R1	; porovnani s hranici
	BRSH f_p_digital_find_1st_falling_edge	; Pokud bude vzorek vetsi, nebo
  ; roven hranici, pak se pokracuje v tomto cyklu

  ; V opacnem pripade pravdepodobne nastala sestupna hrana
f_p_digital_find_2nd_raising_edge:
	DEC data	; pocet_kroku=pocet_kroku-1
	BREQ f_p_digital_period_not_found	; Pokud "dojdou" kroky

	LD tmp,X+	; dalsi vzorek
	INC R0	; zvyseni delky periody o 1
	CP tmp,R1	; porovnani s hranici
	BRLO f_p_digital_find_2nd_raising_edge	; Pokud stale nenastala nabezna
  ; hrana, pak se cyklus opakuje


  ; Nasleduje obnova promennych
	POP data
	POP XL
	POP XH

	MOV R5,data	; Zkopirovani z data treba do R5
	SUB R5,R6	; Pocatek - pocatek vzorkovani -> xova souradnice

  ; Ulozeni vysledku do SRAM
	STS Samples_PERIOD_value_SRAM,R0
	STS Samples_PERIOD_position_SRAM,R5

	RET

; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*

; *-----------------------------------------*
; |                                         |
; *-----------------------------------------*
Show_float_numkMG_20:	; Ukaze float cislo ulozene v A na display
  ; Mg - pomocny registr (R16-R31)
  ; M1 - pocita jiz vypsana cisla
  ; M2 - sem se ulozi hodnota, ktera rika, kolik cisel se ma vypsat (viz.
  ;      konstanta Num_of_digits_numkMG_20)
  ; M3 - informace o koncovece 		(G, M, k, m, u, n)
  ;      odpovidaji nasledujici hodnoty: 1, 2, 3, 4, 5, 6 - 0 nic

.EQU Num_of_digits_numkMG_20 = 4	; definuje, kolik digitu se ma vypsat
  ; Algoritmus je OPTIMALIZOVAN PRO TUTO HODNOTU - pri zmene nutno upravit
  ; S_f_numkMG_20_Dp9, S_f_numkMG_20_Dp8 a S_f_numkMG_20_Dp7!
	RCALL calc_float2dec_20	; "Rozhazi" float bity do dekad

  ; Ted se musi zjisit koncovka (nano, mikro, mili....)
	LDI Mg,1
	MOV M3,Mg	; Defaultne bude koncovka G (behem hledani moznosti se
  ; meni

	CLR M1	; Pocita, kolik digitu (cislic) se jiz vykreslilo
	LDI Mg,Num_of_digits_numkMG_20
	MOV M2,Mg	; Timto se do M2 ulozi pocet digitu, ktere se maji
  ; vykreslit


  ; Ted se vyresi znamenko
	LDS Mg,Dp9	; Cislo v Dp9 se ulozi do Mg

  ; Test na znamenko minus
	BST Mg,7	; Znamenkovy bit se ulozi do T-bitu
	BRTC S_f_numkMG_20_sign_done	; pokud bude znamenko kladne -> bit byl
  ; v nule -> nemusime nic resit -> skok

  ; V opacnem pripade se musi znamenko vykreslit
	CLT	; T-bit = 0 (Jednak se nastavi barva pisma a jednak se pak bude
  ; T-bit vyuzivat pri odstraneni znamenka)
	LDI ZH,HIGH(2*Symbol_dash)
	LDI ZL,LOW(2*Symbol_dash)
	CALL write_char_from_flash

	LDS Mg,Dp9	; Cislo v Dp9 se ulozi do Mg (Musi se nacist znovu,
  ; protoze "write_char_from_flash" hodnotu Mg prepsal. Toto je nejrychlejsi
  ; reseni
	BLD Mg,7	; A informace o znamenku se v Mg odstatni - jiz neni
  ; potreba
S_f_numkMG_20_sign_done:
;					G

  ; Dp9 -> 10^9 - giga - pokud bude nenulova hodnota v tomto registru, pak bude
  ; koncovka G (jiz nastaveno vyse)
S_f_numkMG_20_test_for_Dp9:
	CPI Mg,0	; Porovnani s nulou
	BREQ S_f_numkMG_20_test_for_Dp8	; Pokud bude 0, pak se kontroluje dalsi
  ; rad
	RJMP S_f_numkMG_20_Dp9	; Pokud bude nenulove, pak se skoci

S_f_numkMG_20_test_for_Dp8:
;					Meg
	LDI Mg,2
	MOV M3,Mg	; Zmena koncovky na M (velke)
  ; V opacnem pripade se testuje dal
	LDS Mg,Dp8
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp7
	RJMP S_f_numkMG_20_Dp8
S_f_numkMG_20_test_for_Dp7:
  ; A dal...
	LDS Mg,Dp7
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp6
	RJMP S_f_numkMG_20_Dp7
S_f_numkMG_20_test_for_Dp6:
  ; A dal...
	LDS Mg,Dp6
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp5
	RJMP S_f_numkMG_20_Dp6

S_f_numkMG_20_test_for_Dp5:
;					k
	LDI Mg,3
	MOV M3,Mg
	LDS Mg,Dp5
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp4
	RJMP S_f_numkMG_20_Dp5

S_f_numkMG_20_test_for_Dp4:
	LDS Mg,Dp4
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp3
	RJMP S_f_numkMG_20_Dp4

S_f_numkMG_20_test_for_Dp3:
	LDS Mg,Dp3
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp2
	RJMP S_f_numkMG_20_Dp3

S_f_numkMG_20_test_for_Dp2:
;					- (nic)
	CLR M3
	LDS Mg,Dp2
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp1
	RJMP S_f_numkMG_20_Dp2

S_f_numkMG_20_test_for_Dp1:
	LDS Mg,Dp1
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dp0
	RJMP S_f_numkMG_20_Dp1

S_f_numkMG_20_test_for_Dp0:
	LDS Mg,Dp0
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn1
	RJMP S_f_numkMG_20_Dp0

S_f_numkMG_20_test_for_Dn1:
;					m
	LDI Mg,4
	MOV M3,Mg
	LDS Mg,Dn1
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn2
	RJMP S_f_numkMG_20_Dn1

S_f_numkMG_20_test_for_Dn2:
	LDS Mg,Dn2
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn3
	RJMP S_f_numkMG_20_Dn2

S_f_numkMG_20_test_for_Dn3:
	LDS Mg,Dn3
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn4
	RJMP S_f_numkMG_20_Dn3

S_f_numkMG_20_test_for_Dn4:
;					u
	LDI Mg,5
	MOV M3,Mg
	LDS Mg,Dn4
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn5
	RJMP S_f_numkMG_20_Dn4

S_f_numkMG_20_test_for_Dn5:
	LDS Mg,Dn5
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn6
	RJMP S_f_numkMG_20_Dn5

S_f_numkMG_20_test_for_Dn6:
	LDS Mg,Dn6
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn7
	RJMP S_f_numkMG_20_Dn6

S_f_numkMG_20_test_for_Dn7:
;					n
	LDI Mg,6
	MOV M3,Mg
	LDS Mg,Dn7
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn8
	RJMP S_f_numkMG_20_Dn7

S_f_numkMG_20_test_for_Dn8:
	LDS Mg,Dn8
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn9
	RJMP S_f_numkMG_20_Dn8

S_f_numkMG_20_test_for_Dn9:
	LDS Mg,Dn9
	CPI Mg,0
	BREQ S_f_numkMG_20_test_for_Dn10
	RJMP S_f_numkMG_20_Dn9

S_f_numkMG_20_test_for_Dn10:
  ; Ted by nastoupili stovky p -> musela by se resit dalsi jednotka, ktera by
  ; ani nebyla presna -> radsi vypiseme nulu. Ono uz ty n nebudou kdovijak
  ; presne
;	LDS Mg,Dn10
;	CPI Mg,0
;	BRNE S_f_numkMG_20_Dn10

  ; No a pokud se dostaneme sem, tak to vypada, ze nemame co zobrazit ->
  ; -> zobrazi se nula
	CLR number
	CALL Show_digit
	RJMP Show_float_numkMG_20_end	; Ani jednotky nemusime resit :D

S_f_numkMG_20_Dp9:	; Nejvyssi mozne cislo (9.999G) -> toto je "to prvni"
  ; cislo (vyssi vlastne ani nelze s timto dekadickym rozlisenim zobrazit)
	LDS number,Dp9
	CALL Show_digit
	INC M1
;	CP M1,M2	; Porovnani poct jiz vypsanych cisel tim, kolik jich ma
  ; byt vypsano - zde nema smysl. Pokud uz bylo zjisteno, ze cislo je v tomto
  ; radu, neni zde jina moznost (vyssi cislo nelze zobrazit). Je to tady pro
  ; to, aby byla videt myslenka celeho programu
;	BRNE S_f_numkMG_20_Dp8
;	RJMP Show_float_numkMG_20_Show_unit	; A pokud je jiz vypsano tolik,
  ; kolik chceme -> konec
; Z praktickeho hlediska to na tomto miste nema smysl, protoze toto je nejvyssi
; zobrazene cislo, takze je jasne, ze na displeji nemuze byt vic jak jedno
; cislo. Ale ciste pro ukazku algoritmu to tady je
	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash	; Pokud se bude pokracovat dal,
  ; vykresli se i oddelovaci carka (V tomto pripade jina moznost ani neni, ale
  ; v dalsi casti programu se toto vyuzije k tomu, aby se nezobrazovala "navic"
  ; desetinna carka. Pokud si nejste jisti, co to dela, tak si tento program
  ; dejte hned za vykresleni cisla :)

S_f_numkMG_20_Dp8:
	LDS number,Dp8
	CALL Show_digit
	INC M1
;	CP M1,M2	; Opet - pokud se zacalo vypisovat od prvniho, pak
;	BRNE S_f_numkMG_20_Dp7
;	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dp7:
	LDS number,Dp7
	CALL Show_digit
	INC M1
;	CP M1,M2
;	BRNE S_f_numkMG_20_Dp6
;	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dp6:
	LDS number,Dp6
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dp5_pre
	RJMP Show_float_numkMG_20_Show_unit
S_f_numkMG_20_Dp5_pre:
	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash

S_f_numkMG_20_Dp5:
	LDS number,Dp5
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dp4
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dp4:
	LDS number,Dp4
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dp3
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dp3:
	LDS number,Dp3
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dp2_pre
	RJMP Show_float_numkMG_20_Show_unit
S_f_numkMG_20_Dp2_pre:
	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash

S_f_numkMG_20_Dp2:
	LDS number,Dp2
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dp1
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dp1:
	LDS number,Dp1
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dp0
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dp0:
	LDS number,Dp0
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn1_pre
	RJMP Show_float_numkMG_20_Show_unit
S_f_numkMG_20_Dn1_pre:
	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash

S_f_numkMG_20_Dn1:
	LDS number,Dn1
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn2
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dn2:
	LDS number,Dn2
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn3
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dn3:
	LDS number,Dn3
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn4_pre
	RJMP Show_float_numkMG_20_Show_unit
S_f_numkMG_20_Dn4_pre:
	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash

S_f_numkMG_20_Dn4:
	LDS number,Dn4
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn5
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dn5:
	LDS number,Dn5
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn6
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dn6:
	LDS number,Dn6
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn7_pre
	RJMP Show_float_numkMG_20_Show_unit
S_f_numkMG_20_Dn7_pre:
	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash

S_f_numkMG_20_Dn7:
	LDS number,Dn7
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn8
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dn8:
	LDS number,Dn8
	CALL Show_digit
	INC M1
	CP M1,M2
	BRNE S_f_numkMG_20_Dn9
	RJMP Show_float_numkMG_20_Show_unit

S_f_numkMG_20_Dn9:
	LDS number,Dn9
	CALL Show_digit
	INC M1
	CP M1,M2
	BREQ Show_float_numkMG_20_Show_unit

	LDI ZH,HIGH(2*Symbol_point)
	LDI ZL,LOW(2*Symbol_point)
	CALL write_char_from_flash

S_f_numkMG_20_Dn10:
	LDS number,Dn10
	CALL Show_digit
;	INC M1
;	CP M1,M2
	BREQ Show_float_numkMG_20_Show_unit
  ; Pokud se dostaneme sem, pak uz jemnejsi rozliseni stejne nemame k dispozici

Show_float_numkMG_20_Show_unit:
  ; Nyni je ten spravny cas zobrazit potrebnou jednotku (G,M,k...)
	MOV Mg,M3	; Preulozeni informace do Mg -> jednodussi prace

	CPI Mg,0	; Porovnani s nulou (zadny znak)
	BREQ Show_float_numkMG_20_end	; Pokud se shoduje s nulou -> neni
  ; potreba nic vykreslovat -> rovnou skok na konec

;	CLT	; barva pisma na cernou (jiz nastaveno, neni potreba znovu)
	CPI Mg,1
	BRNE Show_float_numkMG_20_Test_Meg

	LDS Mg,Font_micro_SRAM	; Zjisti se, jestli ma byt pismo male, nebo
  ; velke
	CPI Mg,0
	BRNE Show_float_numkMG_20_Gu
	LDI ZH,HIGH(2*Big_G)
	LDI ZL,LOW(2*Big_G)
	CALL write_char_from_flash
	RET
Show_float_numkMG_20_Gu:
	LDI ZH,HIGH(2*Big_uG)
	LDI ZL,LOW(2*Big_uG)
	CALL write_char_from_flash
	RET

Show_float_numkMG_20_Test_Meg:
	CPI Mg,2
	BRNE Show_float_numkMG_20_Test_k

	LDS Mg,Font_micro_SRAM
	CPI Mg,0
	BRNE Show_float_numkMG_20_Megu
	LDI ZH,HIGH(2*Big_M)
	LDI ZL,LOW(2*Big_M)
	CALL write_char_from_flash
	RET
Show_float_numkMG_20_Megu:
	LDI ZH,HIGH(2*Big_uM)
	LDI ZL,LOW(2*Big_uM)
	CALL write_char_from_flash
	RET

Show_float_numkMG_20_Test_k:
	CPI Mg,3
	BRNE Show_float_numkMG_20_Test_m

	LDS Mg,Font_micro_SRAM
	CPI Mg,0
	BRNE Show_float_numkMG_20_ku
	LDI ZH,HIGH(2*Small_k)
	LDI ZL,LOW(2*Small_k)
	CALL write_char_from_flash
Show_float_numkMG_20_end:
	RET
Show_float_numkMG_20_ku:
	LDI ZH,HIGH(2*Small_uk)
	LDI ZL,LOW(2*Small_uk)
	CALL write_char_from_flash
	RET

Show_float_numkMG_20_Test_m:
	CPI Mg,4
	BRNE Show_float_numkMG_20_Test_u

	LDS Mg,Font_micro_SRAM
	CPI Mg,0
	BRNE Show_float_numkMG_20_mu
	LDI ZH,HIGH(2*Small_m)
	LDI ZL,LOW(2*Small_m)
	CALL write_char_from_flash
	RET
Show_float_numkMG_20_mu:
	LDI ZH,HIGH(2*Small_um)
	LDI ZL,LOW(2*Small_um)
	CALL write_char_from_flash
	RET

Show_float_numkMG_20_Test_u:
	CPI Mg,5
	BRNE Show_float_numkMG_20_Test_n

	LDS Mg,Font_micro_SRAM
	CPI Mg,0
	BRNE Show_float_numkMG_20_uu
	LDI ZH,HIGH(2*Symbol_mi)
	LDI ZL,LOW(2*Symbol_mi)
	CALL write_char_from_flash
	RET
Show_float_numkMG_20_uu:
	LDI ZH,HIGH(2*Symbol_u_mi)
	LDI ZL,LOW(2*Symbol_u_mi)
	CALL write_char_from_flash
	RET

Show_float_numkMG_20_Test_n:
  ; Jina moznost uz neni
	LDS Mg,Font_micro_SRAM
	CPI Mg,0
	BRNE Show_float_numkMG_20_nu
	LDI ZH,HIGH(2*Small_n)
	LDI ZL,LOW(2*Small_n)
	CALL write_char_from_flash
	RET
Show_float_numkMG_20_nu:
	LDI ZH,HIGH(2*Small_un)
	LDI ZL,LOW(2*Small_un)
	CALL write_char_from_flash
	RET


; *-----------------------------------------*
; |               Konstanty                 |
; *-----------------------------------------*

  ; NAPETOVE ROZSAHY - 8. bitove rozliseni
Voltage_rng_01V:	; Pro napetovy rozsah 0.1V -> hodnota jednoho bitu
.DB 0b01001001,0b00110011,0b00110011,0b00110011	; 0.6V/2^8 = 2.34375m
  ; 0.1V/div -> 0.6Vpp - 8bitove rozliseni -> vypoct hodnoty LSB

Voltage_rng_02V:
.DB 0b01001000,0b00110011,0b00110011,0b00110011	; 4.6875m

Voltage_rng_05V:
.DB 0b01000111,0b10000000,0b00000000,0b00000000	; 0.01171875

Voltage_rng_1V:
.DB 0b01000110,0b10000000,0b00000000,0b00000000	; 0.0234375

Voltage_rng_2V:
.DB 0b01000101,0b10000000,0b00000000,0b00000000	; 0.046875

Voltage_rng_5V:
.DB 0b01000100,0b11100000,0b00000000,0b00000000	; 0.1171875

  ; NAPETOVE ROZSAHY - 10. bitove rozliseni
Voltage_rng_10b_01V:	; Pro napetovy rozsah 0.1V -> hodnota jednoho bitu
.DB 0b01001011,0b00110011,0b00110011,0b00110011	; 5.859375e-4
Voltage_rng_10b_02V:
.DB 0b01001010,0b00110011,0b00110011,0b00110011	; 1.171875e-3
Voltage_rng_10b_05V:
.DB 0b01001001,0b10000000,0b00000000,0b00000000	; 2.9296875e-3
Voltage_rng_10b_1V:
.DB 0b01001000,0b10000000,0b00000000,0b00000000	; 5.859375e-3
Voltage_rng_10b_2V:
.DB 0b01000111,0b10000000,0b00000000,0b00000000	; 0.01171875
Voltage_rng_10b_5V:
.DB 0b01000110,0b11100000,0b00000000,0b00000000	; 0.029296875

  ; CASOVE ZAKLADNY
Time_base_01us:		; Casovka 0.1us -> 1 px = 10ns
.DB 0b01011011,0b01010111,0b10011000,0b11101110
Time_base_025us:	; Casovka 0.25us -> 1 px = 25ns
.DB 0b01011010,0b10101101,0b01111111,0b00101001
Time_base_05us:		; Casovka 0.5us -> 1px = 50ns
.DB 0b01011001,0b10101101,0b01111111,0b00101001
Time_base_1us:		; Casovka 1.0us -> 1px = 100ns
.DB 0b01011000,0b10101101,0b01111111,0b00101001
Time_base_2us:		; Casovka 2.0us -> 1px = 200ns
.DB 0b01010111,0b10101101,0b01111111,0b00101001
Time_base_5us:		; Casovka 5.0us -> 1px = 500ns
.DB 0b01010101,0b00001100,0b01101111,0b01111010
Time_base_10us:		; Casovka 10us -> 1px = 1us
.DB 0b01010100,0b00001100,0b01101111,0b01111010
Time_base_20us:		; Casovka 20us -> 1px = 2us
.DB 0b01010011,0b00001100,0b01101111,0b01111010
Time_base_50us:		; Casovka 50us -> 1px = 5us
.DB 0b01010010,0b01001111,0b10001011,0b01011000
Time_base_01ms:		; Casovka 0.1ms -> 1px = 10us
.DB 0b01010001,0b01001111,0b10001011,0b01011000
Time_base_02ms:		; Casovka 0.2ms -> 1px = 20us
.DB 0b01010000,0b01001111,0b10001011,0b01011000
Time_base_05ms:		; Casovka 0.5ms -> 1px = 50us
.DB 0b01001111,0b10100011,0b01101110,0b00101110
Time_base_1ms:		; Casovka 1ms -> 1px = 100us
.DB 0b01001110,0b10100011,0b01101110,0b00101110
Time_base_2ms:		; Casovka 2ms -> 1px = 200us
.DB 0b01001101,0b10100011,0b01101110,0b00101110
Time_base_5ms:		; Casovka 5ms -> 1px = 500us
.DB 0b01001011,0b00000110,0b00100100,0b11011101
Time_base_10ms:		; Casovka 10ms -> 1px = 1ms
.DB 0b01001010,0b00000110,0b00100100,0b11011101
Time_base_20ms:		; Casovka 20ms -> 1px = 2ms
.DB 0b01001001,0b00000110,0b00100100,0b11011101
Time_base_50ms:		; Casovka 50ms -> 1px = 5ms
.DB 0b01001000,0b01000111,0b10101110,0b00010100
Time_base_01s:		; Casovka 0.1s -> 1px = 10ms
.DB 0b01000111,0b01000111,0b10101110,0b00010100
Time_base_02s:		; Casovka 0.2s -> 1px = 20ms
.DB 0b01000110,0b01000111,0b10101110,0b00010100
Time_base_05s:		; Casovka 0.5s -> 1px = 50ms
.DB 0b01000101,0b10011001,0b10011001,0b10011001
Time_base_1s:		; Casovka 1s -> 1px = 0.1s
.DB 0b01000100,0b10011001,0b10011001,0b10011001
Time_base_2s:		; Casovka 2s -> 1px = 0.2s
.DB 0b01000011,0b10011001,0b10011001,0b10011001
Time_base_5s:		; Casovka 5s -> 1px = 0.5s
.DB 0b01000001,0b00000000,0b00000000,0b00000000








NULL:	; NULOVA HODNOTA - prevazne pro ladeni SW
.DB 0,0

