////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 - 8 katod - vstupní/výstupní
		out 	DDRB, 	R16
		
		ldi 	R16, 	0b11011111	//C0-3 - 4 katody, C4 - společná anoda 
		out 	DDRC, 	R16
		com 	R16				//C5 - vstupní, výstupní - signály od/do Atmegy5
		out		PORTC,	R16   //pull up rezistor na začátku pin C5
		 
		ldi 	R16, 	0xFF	//D - 8 katod
		out 	DDRD, 	R16

				
////vytvoreni tabulky pro počet zasahu konkretni diody////

		/*ldi R16, 11			//9
		sts 0x0101, R16
		sts 0x0102, R16

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

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

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

		ldi R16, 7
		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, 6
		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, 5
		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, 4
		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, 3
		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
		

	*/
		ldi R16, 3 			//3 = +1 na pocistadle
		sts 0x0100, R16 //B0
		sts 0x0107, R16 //B7
		sts 0x0108, R16 //C0
		sts 0x010B, R16 //C3
		sts 0x010C,	R16 //D0
		sts 0x0113,	R16 // D7			


///nulovani registrů a pameti

				
		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
		
			ldi R17, 200
			ldi ZH, 02
			ldi ZL, 00
nulovani:	st Z+, R16
			dec R17
			brne nulovani
			ldi R17, 0		//všechno vynulováno

				rcall cekej1

		rjmp normal	//testovani

	

//////////////////////////////////////////////////////////////////////////////////////////
///////////////ted ceka na impuls programu od Atmegy5//////////////////////////
///////////////////////////////////////////////////////////////////////
impuls:		
				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:		rcall cekej200

start:  	ldi R16, 0xFF		
			out DDRB, R16
			out PORTB, R16
			out DDRD, R16
			out PORTD, R16
			ldi R16, 0b00011111		//na DDRC bacha nemuže být C5 - 1
			out DDRC, R16
			ldi R16, 0b00001111		//0 do anody(C4) - nabití všech diod
			out PORTC, R16			//jednička do všech katod

			ldi R16, 0
			out DDRB, R16
			out PORTB, R16
			out DDRD, R16
			out PORTD, R16
			ldi R17, 0b00010000		//C4  musí zůstav výstupní nula, C5 vstupní (neutralní)
			out DDRC, R17
			out PORTC, R16			//0	všechny katody nastavené jako vstupní
				
			ldi R20, 2	///pokus
			ldi R19, 0xFF			//asi 1,4ms (R19 = 100)
			rjmp piny
		
			
/////////////////////////////////////////////////////////////////////////////////////////
/////////kontrola vybití diody (na všech portech)///////////////////////////////
////////////////////////////////////////////////////////////////////////////////

Piny:		in R16, PINB			//tady je velmi šikovně nastavená priorita
			in R17, PIND			//nejdříve se zahlasi pin, ktery byl vybit nejdrive
			in R18, PINC			//takze by zjistovani mělo byt presnejsi
			cpi R16, 0b11111111
			brne sloupecekB
			cpi R17, 0b11111111
			brne sloupecekD
			andi R18, 0b00001111
			cpi R18, 0b00001111
			brne sloupecekC			//skoci jenom pokud zjisti, ze se nejaky pin vybil
									//a az pak teprve zjistuje ktery to byl
			in R18, PINC
			andi R18, 	0b00100000
			cpi R18, 	0b00100000	//kdyby už vystrelil nekdo jiny, je to smutne ale 
			breq nekdo_vystrelil		//musim to zaregistrovat a zapsat


			dec R19					//delku zjistovani urcuje cislo v R19
			brne dal_jen_dal	//pokus
			dec R20				//pokus
			breq start			//pokus

dal_jen_dal:rjmp piny

nekdo_vystrelil:	rjmp fakt_ze_jo


sloupecekB:	ldi R19, 1				//index ze bylo zasazeno neco na b, R19= 1
			ldi osmickas, 8
sb:			mov R17, R16				//musim cislo z pinu nechat v nejakem registru 
			ldi ZH, high(radky<<1)	//jinak bych si ho porad prepisoval
			ldi ZL,  low(radky<<1)
			add ZL, osmickas		//indexování konrétní diody
			lpm radek, Z			
			or R17,radek			//maskování pinu

			cp R17, 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
			brne sb					//a jede znovu
			rjmp piny				//pokud nezjisti nic, skoci zpet na piny

sloupecekD:	ldi osmickas, 8
			ldi R19, 3			//bylo zasazeno d, R19= 3
sd:			mov R16, R17
			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í pinu

			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
			brne sd				//a jede znovu
	

			rjmp piny		///pokud nezjisti nic, skoci zpet na piny

sloupecekC: ldi osmickas, 4
			ldi R19, 2			//zasazeno c R19 = 2
sc:   		mov R16, R18
			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í pinu
			andi radek, 0b00001111	//poze katodove piny
			andi R16, 0b00001111
			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
			brne sc					//a jede znovu
			ldi osmickas,8

			rjmp piny


///////////////////////////////////////////////////////////////////////////////
/////konec kontroly, navrat do nabijeni////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

			

vybito: ldi 	R16, 	0xFF	//všechny piny výstupní, anoda katoda budou svítit, 
		out 	DDRB, 	R16		//komunikace bude ven, ale ješte to nezapínám
		out 	DDRD, 	R16
		ldi 	R16,	0b00011111
		out 	DDRC, 	R16
		in 		R16, PINC
		ldi 	R17, 	0b00010000
		or		R16, 	R17	//na anode 1 - je připravena svítit	
		out 	PORTC,  R16

		cpi R19, 1			//rozsviti diodu podle toho, kde byla zasazena
		breq zasahB
		cpi R19, 3
		breq zasahD
		cpi R19, 2
		breq zasahC

zasahB:			out PORTB, radek
				ldi R16, 0xFF		//ostatni porty taky nebudou svitit ze?
				out PORTD, R16
				ldi R16, 0b00011111
				out PORTC, R16
				ldi ZH, 0x02		//pozice 0x0200
				ldi ZL, 0x00
				ld	R16, Z
				cpi R16, 0			//pokud tam neni nic napsane, napise to tam
				breq zapis_strely_B	// (index - B/C/D a radek strely)

zabranob:		inc ZL				//pokud tam uz byla zapsana strela
				inc ZL				//prejdu o dve pole dal a zapisu to tam
				ld R16, Z			//kdyz tam neco jde jdu o dalsi dve pole
				
				cpi R16, 0
				brne zabranob
				
zapis_strely_B:	cpi ZL, 200
				breq dal3 

				ldi R16, 1		//index béčka - 1
				st Z+, R16			//
				st Z, radek		//radek do vedlejsiho registru pameti
				
dal3:			rjmp dale			//jedem dal						

 		

zasahC:			andi radek, 0b00001111
				ori radek, 0b00010000		//porad musi byt zapnuta 
				out PORTC, radek	
				ldi R16, 0xFF
				out PORTB, R16		//ostatni porty taky nebudou svitit ze?
				out PORTD, R16
				ldi ZH, 0x02		//pozice 0x0200
				ldi ZL, 0x00
				ld	R16, Z
				cpi R16, 0			//pokud tam neni nic napsane, napise to tam
				breq zapis_strely_C	// (index - B/C/D a radek strely)

zabranoc:		inc ZL				//pokud tam uz byla zapsana strela
				inc ZL				//prejdu o dve pole dal a zapisu to tam
				ld R16, Z			//kdyz tam neco jde jdu o dalsi dve pole
				
				cpi R16, 0
				brne zabranoc
				
zapis_strely_C:	cpi ZL, 200
				breq dal2 

				ldi R16, 2		//index cecka - 2
				st Z+, R16			//
				st Z, radek		//radek do vedlejsiho registru pameti
				
dal2:			rjmp dale			//jedem dal	



zasahD:			out PORTD, radek
				ldi R16, 0xFF		//ostatni porty taky nebudou svitit ze?
				out PORTB, R16
				ldi R16, 0b00011111
				out PORTC, R16
				ldi ZH, 0x02		//pozice 0x0200
				ldi ZL, 0x00
				ld	R16, Z
				cpi R16, 0			//pokud tam neni nic napsane, napise to tam
				breq zapis_strely_D	// (index - B/C/D a radek strely)

zabranod:		inc ZL				//pokud tam uz byla zapsana strela
				inc ZL				//prejdu o dve pole dal a zapisu to tam
				ld R16, Z			//kdyz tam neco jde jdu o dalsi dve pole
				
				cpi R16, 0
				brne zabranod
				
zapis_strely_D:	cpi ZL, 200
				breq dale 		//pokud bych už se dostal na pozici 0x0300 tak tam dal nezapisuju

				ldi R16, 3		//index decka - 2
				st Z+, R16			//
				st Z, radek		//radek do vedlejsiho registru pameti
				
				rjmp dale			//jedem dal	
			

////////////////tady jsem ještě neopravoval///////////////

dale:	//	rcall indexik
		//	rcall zasah
		//	rcall posli
			
		//	rcall cekej1		//rozsvícení trefené diody

		 rcall cekej200 

			rjmp normal			//back to start :)


/////////////////////////////////////////////////////////////////
////podprogramy///////////////////////////////////////////
//////////////////////////////////////////////////////////////
//toto neni uplne podprogram////////////////////////////////////////
///zarizuje, zapis strely, kdyz byl zasazeny jiný segment terce/////
/////////////////////////////////////////////////////////////////////

fakt_ze_jo:		ldi R17, 0			//toto bude index strely
				ldi ZH, 0x02		//pozice 0x0100
				ldi ZL, 0x00
				ld	R16, Z
				cpi R16, 0			//pokud tam neni nic napsane, napise to tam
				breq zapis_strely	// (index - B/C/D a radek strely)

zabrano:		inc ZL				//pokud tam uz byla zapsana strela
				inc ZL				//prejdu o dve pole dal a zapisu to tam
				ld R16, Z			//kdyz tam neco jde jdu o dalsi dve pole
				
				cpi R16, 0
				brne zabrano
				
zapis_strely:	cpi ZH, 3
				breq zpet

				ldi R16, 0xFF
				st Z, R16			//terc zasahlo neco jineho, neindexuji nic
				inc ZL
				st Z, R16		//ani strela nema index
				
				rcall cekej200
zpet:				
				rjmp start			//pocka 200ms na ustaleni a strilime dal			

/////////////////////////////////////////////////////////////////////////////////////
/////////////na miste 02xx přibyla dalši "prazdna strela"////////////////////
/////////////////////////////////////////////////////////////////////////////


indexik:	cpi R19, 1	//B
			breq i1
			cpi R19, 2
			breq i2
			cpi R19, 3
			breq i3

i1:			ldi R16, 0
			add index, R16
			rjmp i4
i2:			ldi R16, 8
			add index, R16
			rjmp i4
i3:			ldi R16, 16
			add index, R16
		//	rjmp i4
i4:			add index, osmickas		//ted mam v indexu presne identifikovanou trefenou diodu (1-20)
			ret						//pomoci zasah zjistim jake cislo jsem trefil


	
///////////////////////////////////////////////////////////////////////////////
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 R16, 0b00111111
			out PORTC, R16			//odesila signál- je vystupni
			ldi R17, 0b00100000		//poslání impulsů do atmegy5!!!
			in R16, PINC			//maska C portu
			or R17, R16				//0bxx1xxxxx - R17
			andi R16, 0b11011111	//0bxx0xxxxx - R16
			ldi R16, 0b00011111
			out DDRC, R16			//bez toho nemuzu posilat impuly
						
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

			ldi R16, 0b00011111
			out PORTC, R16			//dokonceno odesilani, C5 opět vstupni

			rcall cekej1
			ret
//////////////////////////////////////////////////////////////////////////////////////		



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

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

cekej200:	ldi R20, 1			//cca 200ms (R17 1)
	b1:		ldi R18, 120
	b2:		ldi R21, 0
	b3:		dec R21
		
			brne b3
			dec R18
			brne b2
			dec R20
			brne b1
				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
