////program k Atmegam 1-4: segmenty terce///
///Atmega 1 konkrétně je modrý segment na terči
///zjistí program z Atmegy5
///při výstřelu se zjistí poloha diody registry osmickar (PORTD) a osmickas (PORTC)
///přímo už v decimálním čísle, zároveň se provede zjisteni indexu diody (1-64) do registru index
/// podle registru index se vyhodnoti pocet impulsu poslanych na Atmegu 5

.include "m8def.inc"

.def index = R25
.def sloupec = R24
.def radek = R23
.def osmickar = R22
.def osmickas = R21
 
.org 0x00
 	rjmp zac // skok na začátek programu
.org 0x18
	rjmp timer // skok na obsluhu přerušení
.org 0x100

timer: 	
		
		 reti

////////////////////////////////////////////////////////////
//hlavni program
//////////////////////////////////////////////////////////

zac:  	ldi R16, HIGH(RAMEND) // inicializace STACK POINTERu
		out SPH, R16
		ldi R16, LOW(RAMEND)
		out SPL, R16

		ldi 	R16, 	0xFF	//B vystupni (na zacatku)
		out 	DDRB, 	R16
		ldi 	R16, 	0b11011111	//C I/O - C0 - výstupní -  posílá signály do Atmegy5, 
		out 	DDRC, 	R16				//C5 - vstupní, příjímá signály od Atmegy5
		ldi 	R16, 	0xFF	//D vystupni
		out 	DDRD, 	R16

		out    PORTC, R16
		
////vytvoreni tabulky pro počet zasahu konkretni diody////

		ldi R16, 9
		sts 0x0101, R16
		sts 0x0102, R16

		ldi R16, 8
		sts 0x0103, R16
		sts 0x0104, R16
		sts 0x0105, R16

		ldi R16, 7
		sts 0x0106, R16
		sts 0x0107, R16
		sts 0x0108, R16
		sts 0x0109, R16
		sts 0x010A, R16

		ldi R16, 6
		sts 0x010B, R16
		sts 0x010C, R16
		sts 0x010D, R16
		sts 0x010E, R16
		sts 0x010F, R16
		sts 0x0110, R16

		ldi R16, 5
		sts 0x0111, R16
		sts 0x0112, R16
		sts 0x0113, R16
		sts 0x0114, R16
		sts 0x0115, R16
		sts 0x0116, R16
		sts 0x0117, R16
		sts 0x0118, R16

		ldi R16, 4
		sts 0x0119, R16
		sts 0x011A, R16
		sts 0x011B, R16
		sts 0x011C, R16
		sts 0x011D, R16
		sts 0x011E, R16
		sts 0x011F, R16
		sts 0x0120, R16	
		sts 0x0121, R16



		ldi R16, 3
		sts 0x0122, R16		//dioda č. 34 je mimo schema terce
		sts 0x0123, R16
		sts 0x0124, R16
		sts 0x0125, R16
		sts 0x0126, R16
		sts 0x0127, R16
		sts 0x0128, R16
		sts 0x0129, R16	
		sts 0x012A, R16
		sts 0x012B, R16
		sts 0x012C, R16
		
		ldi R16, 2
		sts 0x012D, R16
		sts 0x012E, R16
		sts 0x012F, R16
		sts 0x0130, R16
		sts 0x0131, R16
		sts 0x0132, R16
		sts 0x0133, R16	
		sts 0x0134, R16
		sts 0x0135, R16
		sts 0x0136, R16
			
		ldi R16, 1
		sts 0x0137, R16
		sts 0x0138, R16
		sts 0x0139, R16
		sts 0x013A, R16
		sts 0x013B, R16
		sts 0x013C, R16
		sts 0x013D, R16	
		sts 0x013E, R16
		sts 0x013F, R16
		sts 0x0140, R16
		
		rjmp posli
				
///nulovani registrů
		
		ldi R16, 0
		ldi R17, 0
		ldi R18, 0
		ldi R19, 0
		ldi R20, 0
		ldi R21, 0
		ldi R22, 0
		ldi R23, 0
		ldi R24, 0
		ldi R25, 0
	
		//rcall cekej1

//////////////////////////////////////////////////////////////////////////////////////////
///////////////ted ceka na impuls programu od Atmegy5//////////////////////////
///////////////////////////////////////////////////////////////////////
impuls:			sei
				in 		R16, 	PINC
				andi 	R16, 	0b00100000	//ceka na horni hranu impulsu od atmegy5
				cpi 	R16, 	0b00100000
				brne impuls
				rcall cekejkontrola
				in 		R16, 	PINC
				andi 	R16, 	0b00100000
				cpi 	R16, 	0b00100000	//overi, jestli impuls trva aspoň 
				brne impuls					//60 mikrosekund

plus:			inc R19			//za každý impuls se přičte 1
				ldi R18, 0			//pocitani, jestli uz dlouho nebyl impuls		
plusceka:		in 		R16, 	PINC		
				andi 	R16, 	0b00100000
				cpi 	R16, 	0b00000000	//overi, že impuls ustal
				brne plusceka
				rcall cekejkontrola
				in 		R16, 	PINC		
				andi 	R16, 	0b00100000
				cpi 	R16, 	0b00000000	//pro jistotku 2x
				brne plusceka
plus_uz:		inc R18			//timto pocitadlem se zjisti jestli uz neuplynulo
				cpi R18, 150		//vice nez 1ms od posledniho impulsu a tedy 
				breq program	//by bylo na case ukoncit prenost a spustit dany program
				in 		R16, 	PINC		
				andi 	R16, 	0b00100000	//
				cpi 	R16, 	0b00100000
				brne plus_uz
				rcall cekejkontrola
				in 		R16, 	PINC		
				andi 	R16, 	0b00100000
				cpi 	R16, 	0b00100000	//pro jistotu dvakrát kvůli šumu
				brne plus_uz
				rjmp plus
//program zjištěn, čekáme na start impuls
	
				
program:		sts 0x0200, R19	//uložení informace o probihajicim programu
				cpi R19, 1		//podle toho kolik impulsu přišlo
				breq p1			//z řidici atmegy5	
				cpi R19, 2		//se vybere příslušný program 
				breq p1
				cpi R19, 3		
				breq p1
				cpi R19, 4
				breq p2
				cpi R19, 5
				breq p1
				cpi R19, 6
				breq p1
				cpi R19, 7
				breq p1
				cpi R19, 8
				breq p1

				rjmp impuls

p1: rjmp normal
p2: rjmp biatlon

////////////////////////////////////////////////////////////////////////////
///////////příprava na biatlon (rozvícení prstence 6)///////////////////////
////////////////////////////////////////////////////////////////////////////

biatlon:



/////////////////////////////////////////////////////////////////////////////
///////////teď si už v klidku zjišťuje, která dioda byla trefena////////////
////////////////////////////////////////////////////////////////////////////

normal:		ldi radek, 0
			ldi sloupec, 0
			ldi osmickas, 8

start:  	ldi R16, 0xFF		
			out DDRB, R16
			out PORTB, R16
			//rcall cekej10
			ldi R16, 0		
			out DDRB, R16		//nabití diod, a přepnutí na vstupni port
			out PORTB, R16		//

			ldi osmickar, 8

radecek:	ldi ZH, high(radky<<1)
			ldi ZL,  low(radky<<1)
			add ZL, osmickar		
			
			lpm radek, Z
			out PORTD, radek		//nahrani indexu radku do PD
			
			ldi R16, 0xFF			//nabití, diod
			out DDRB, R16			
			out PORTB, R16
			//rcall cekej10
			ldi R16, 0		
			out DDRB, R16
			out PORTB, R16			//přepnutí na vstup a maskování ostatních pinů

			out PORTD, radek		//konkrétní pin má nulu - zjištění
			com radek				//ostatní piny jsou jako vstup - nejde z nich 
			out DDRD, radek	
			nop 
			nop 
			nop 
			nop
			nop 
			nop 
			nop 
			nop
			nop
			nop	
			nop 
			nop 
			nop 
			nop
			nop 
			nop 
			nop 
			nop
			nop
			nop 
			//rcall cekej200					//proud který by testovanou diodu znovu nabíjel

sloupecek:	in R16, PINB			//přečtení 1 nebo 0
			ldi ZH, high(radky<<1)
			ldi ZL,  low(radky<<1)
			add ZL, osmickas		//indexování konrétní diody
			lpm radek, Z			
			or R16,radek			//maskování 

			cp R16, radek
			breq vybito				//pokud je na konkrétním pinu 0
									//skočí na vybito
			dec osmickas
			cpi osmickas, 0			//pokud ne, odečte počítadlo sloupců
			brne sloupecek			//a jede znovu
			ldi osmickas,8

			dec osmickar			//atd... pokud obě počítadla jsou na nule, začíná znovu
			cpi osmickar,0
			breq start	

			rjmp radecek			//toto je pruchod jednim celým sloupcem
			

vybito: ldi 	R16, 	0xFF	//B vystupni (na zacatku)
		out 	DDRB, 	R16
		out 	DDRD, 	R16		//musím udělat oba porty výstupní
		out 	PORTB,	radek	// v radku už je rovnou to co potřebuji
	

			ldi ZH, high(radky<<1)
			ldi ZL,  low(radky<<1)
			add ZL, osmickar
			lpm R17, Z
			com	R17
			out PORTD, R17			//do sloupce to musím narvat

			rcall nasobeni
			rcall zasah
			rcall posli
			
			rcall cekej1		//rozsvícení trefené diody



			rjmp normal			//back to start :)


/////////////////////////////////////////////////////////////////
////podprogramy///////////////////////////////////////////
//////////////////////////////////////////////////////////////úú

nasobeni:	ldi index, 0
			ldi R18, 8		//to budu přičítat za každý průchod řádků
			mov R16, osmickar	//přesuny do pracovních registrů
			mov R17, osmickas
radkynas:	dec R16
			cpi R16, 0			//pokud je v R16 už nula, přičtu sloupce a jdu
			breq sloupcenas		//pokud není příčtu 8 a dekrementuji
			add index, R18
			rjmp radkynas
sloupcenas:	add index, R17		//ted mam v indexu čislo od 1 do 64, které jasne indexuje konkretni diodu
			ret

///////////////////////////////////////////////////////////////////////////////
zasah:		ldi ZH, 1
			ldi ZL, 0
			add ZL, index
			ld R19, Z			//ted mam v R16 hodnotu zasahu a můžu jí poslat do Atmegy5
								// ve formě 400us impulsu
			ret
///////////////////////////////////////////////////////////////////////////////////
posli:		ldi R17, 0b00000001		//poslání impulsů do atmegy5!!!
			in R16, PINC			//maska C portu
			or R17, R16				//0bxxxxxxx1 - R17
			andi R16, 0b11111110	//0bxxxxxxx0 - R16
			
						
smycka1:	out PORTC, R17		//smycka jednoho 400us impulsu
			rcall cekej04
			out PORTC, R16
			rcall cekej04
			dec R19				//zaridi akuratni pocet impulsicku
			cpi R19, 0
			brne smycka1
			rcall cekej1
			ret
//////////////////////////////////////////////////////////////////////////////////////		



/////////////////////////////////////////////////////////////////////////////
///zpozdeni////////////////////////////////////////
//////////////////////////////////////////////////////////////

cekej1:
			ldi R17, 1		//cca 1s (R17 5)
	d1:		ldi R18, 0
	d2:		ldi R19, 0
	d3:		dec R19
		
			brne d3
			dec R18
			brne d2
			dec R17
			brne d1
	
				ret

cekej200:	sei
			ldi R20, 1			//cca 200ms (R17 1)
	b1:		ldi R18, 120
	b2:		ldi R19, 0
	b3:		dec R19
		
			brne b3
			dec R18
			brne b2
			dec R20
			brne b1
			cli
				ret

cekej24:
			 						//cca 24mss (R17 neni)
			ldi R18, 60
	c1:		ldi R19, 0
	c2:		dec R19
		
			brne c2
			dec R18
			brne c1
			
		
	
				ret

cekej10:
			 						
			ldi R18, 1
	g1:		ldi R19, 10
	g2:		dec R19
		
			brne g2
			dec R18
			brne g1
			
		
	
				ret

cekej04:		//cca 400us (R19 = 132)
			ldi R20, 132
	w1:		dec R20
			brne w1
			ret





cekej01:
			 						
			ldi R18, 20
	f1:		ldi R19, 1
	f2:		dec R19
		
			brne f2
			dec R18
			brne f1
			ret

cekejkontrola:
			 						//cca 54us (R19 = 18)
			ldi R20, 18
	v1:		dec R20
			brne v1
			ret



nop 
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop //nopy jsou tu proto, že mi přetekal registr 
nop	// ZL na čteni z paměti programu, proto takhle 
nop	// tabulky radky a sloupce posunu o par mist dal
nop
nop
nop
nop
nop
nop
nop		


radky:
//.db 0b00000001,0b00000010,0b00000100,0b00001000,0b00010000,0b00100000,0b01000000,0b10000000
.db 0,0b11111110,0b11111101,0b11111011,0b11110111,0b11101111,0b11011111,0b10111111,0b01111111
sloupce:
.db 0,0b11111110,0b11111101,0b11111011,0b11110111,0b11101111,0b11011111,0b10111111,0b01111111

matice:
.db 1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,3,3,3,3,3,3,3,4,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7,8,8,8,8,8,9,9,9,9,9,9,9,10,10,10,10,10,10,10
