
;Processzor megadása 
.nolist 
.include "m16def.inc" 
.list 


;regiszterek megadása 

.def E = r2
;.def F = r3

.def carry = r3

.def seged1 = r4
.def seged2 = r5
.def seged3 = r6
.def seged4 = r7

.def timer0 = r8
.def timer1 = r9
.def timer2 = r10
.def timer3 = r11

.def cnt0 = r12
.def cnt1 = r13
.def cnt2 = r14
.def cnt3 = r15

.def A = r16
.def B = r17
.def C = r18
.def D = r19

.def temp = r20
.def temp2= r21
.def temp3= r22

.def lcdport = r23

;általános flag a méréshez.
;0. bit: mérés engedélyezés
;1. bit: mérési nagyságrend
;2. bit: fenntartva további nagyságrendekhez
;3. bit: fenntartva további nagyságrendekhez
;4. bit: L/C mérés
;5. bit: mérés/kalibrálás
;.def measflag = r24



.equ CPU_SPEED = 12		; órajel, MHz-ben értendő...


.equ hun_a1	=	8
.equ hun_e1	=	9
.equ hun_i1	=	10
.equ hun_o1	=	11
.equ hun_o2	=	12
.equ hun_o3	=	13
.equ hun_u1	=	14
.equ hun_u2	=	15


/********************************
 portA - 3:0 == D7-D4
 portA - 6   == RS    0:instruction; 1:data
 portA - 7   == EN
********************************/

.equ LCD_PORT	=	PORTA
.equ LCD_DDR	=	DDRA

.equ LCD_E	=	7
.equ LCD_RS	=	6
.equ LCD_4	=	0
.equ LCD_5	=	1
.equ LCD_6	=	2
.equ LCD_7	=	3






;a kódszegmensből áttölti a számértékeket az adatszegmensbe - #0 végű számok!
;0:forrás(.cseg);   1:cél(.dseg)
.macro load_cseg
	ldi ZH,high(2*@0)
	ldi ZL, low(2*@0)
	ldi YH,high(@1)
	ldi YL, low(@1)
	rcall load_num_fv
.endmacro


.macro write_num
	ldi ZH,high(@0)
	ldi ZL, low(@0)
	rcall write_num_fv
.endmacro


;0: ide várja az értéket(64 bites egész)   1-4: regiszter!
.macro copy_reg
	ldi ZH,high(@0)
	ldi ZL, low(@0)
	st  Z+,@1
	st  Z+,@2
	st  Z+,@3
	st  Z+,@4
	clr A
	st  Z+,A
	st  Z+,A
	st  Z+,A
	st  Z+,A
.endmacro


.macro copy_num
	ldi ZH,high(@0)
	ldi ZL, low(@0)
	ldi A,@1
	st  Z+,A
	ldi A,@2
	st  Z+,A
	ldi A,@3
	st  Z+,A
	ldi A,@4
	st  Z+,A
	clr A
	st  Z+,A
	st  Z+,A
	st  Z+,A
	st  Z+,A
.endmacro

/*
.macro load_reg
	ldi ZH,high(@0)
	ldi ZL, low(@0)
	st  Z+,@1
	st  Z+,@2
	st  Z+,@3
	st  Z+,@4
.endmacro
*/

;0: forrás,   1: cél
.macro convert
	load_cseg null_cseg,@1	;lenulláz!
	ldi XH,high(@0)
	ldi XL, low(@0)
	ldi YH,high(@1)
	ldi YL, low(@1)
	rcall convert_nums
.endmacro

.macro convertH
	load_cseg null_cseg,@1	;lenulláz!
	ldi XH,high(@0)
	ldi XL, low(@0)
	ldi YH,high(@1)
	ldi YL, low(@1)
	adiw X,4
	rcall convert_nums
.endmacro

;Két 64 bites értéket összead, eredmény a 0. tényezőben
.macro aritmetika_plusz
	ldi XH,high(@0)
	ldi XL, low(@0)
	ldi YH,high(@1)
	ldi YL, low(@1)
	rcall aritmetika_plusz_fv
.endmacro

;Két 64 bites értéket von ki, eredmény a 0. tényezőben
.macro aritmetika_minusz
	ldi XH,high(@0)
	ldi XL, low(@0)
	ldi YH,high(@1)
	ldi YL, low(@1)
	rcall aritmerika_minusz_fv
.endmacro

;64 bites értéket másol át. @0 --> @1
.macro aritmetika_copy
	ldi XH,high(@0)
	ldi XL, low(@0)
	ldi YH,high(@1)
	ldi YL, low(@1)
	rcall aritmetika_copy_fv
.endmacro


.macro aritmetika_shift_L
	ldi XH,high(@0)
	ldi XL, low(@0)
	rcall aritmetika_shift_L_fv
.endmacro

.macro aritmetika_shift_R
	ldi XH,high(@0)
	ldi XL, low(@0)
	rcall aritmetika_shift_R_fv
.endmacro

.macro aritmetika_osztas
	ldi XH, high(@0)
	ldi XL,  low(@0)
	ldi YH, high(@1)
	ldi YL,  low(@1)
	rcall aritmetika_osztas_fv
.endmacro

.macro aritmetika_szorzas
	ldi YH, high(@0)
	ldi YL,  low(@0)
	ldi ZH, high(@1)
	ldi ZL,  low(@1)
	rcall aritmetika_szorzas_fv
.endmacro


.macro gotoXY
	ldi A,@0
	ldi B,@1
	rcall lcd_cursor
.endmacro


.macro delete
	ldi XL, high(@0)
	ldi XH,  low(@0)
	rcall delete_fv
.endmacro

.macro lcd_write_XY
	ldi A, @0			;X
	ldi B, @1			;Y
	rcall lcd_cursor
	ldi ZH, high(2*@2)
	ldi ZL,  low(2*@2)	;szöveg(.cseg)
	rcall lcd_string
.endmacro


.macro _delay_ms
	ldi A,@0
	rcall delay_ms
.endmacro





.dseg

;delta_time	:	.byte 8		;eltelt idő kiszámítva

;meas_cnt	:	.byte 8		;számláló értéke
_ccal		:	.byte 8		;kalibráló kondi
_Lm			:	.byte 8		;mérő tekercs
_Cm			:	.byte 8		;mérő kondi

_4mpi2:			.byte 8		;4 millió pi négyzet
_1mrd		:	.byte 8		;1 milliárd
_null		:	.byte 8		;0 ^-^

num1:		.byte 8
num2:		.byte 8

;_1000:		.byte 8



maradek		:	.byte 8
freq		:	.byte 8
_freq0		:	.byte 8		;f0
_freqC		:	.byte 8		;fcal


;kis helytakarékosság sosem árt az adatszegmensben...
.equ		_meas_time = _freqC
.equ		_1sec_time = _ccal

numchar		:	.byte 12





; interruptok megadása - atmega16.pdf 42. oldal
.cseg 
.org $0000 ; 
	jmp RESET ; Reset Handler,  

	;reti ; INT0 handler
	;nop
	;rjmp AnalogIRQ

	ret		;***************************
	nop

	reti ; INT1_handler
	nop 
	reti ; Timer2 Compare Match Handler 
	nop
	reti ; Timer2 Overflow Handler 
	nop 
	reti ; Timer1 Capture Event Handler 
	nop 
	reti ; Timer1 Compare Match A Handler 
	nop 
	reti ; Timer1 Compare Match B Handler 
	nop 
	reti ; Timer1 Overflow Handler 
	nop 
	reti ; Timer0 Overflow Handler 
	nop 
	reti ; SPI Transfer Complete Handler 
	nop 
	reti ; UART_RX_handler
	nop
	reti ; USART0 Data Register Empty Hanlder 
	nop 
	reti ; USART0 TX Complete Handler 
	nop 
	reti ; ADC Conversion Complete Handler 
	nop 
	reti ; EEPROM Ready Hanlder 
	nop 
	reti ; Analog Comparator Handler 
	nop 
	reti ; Two-wire Serial Interface Handler 
	nop 
	reti ; INT2 Handler
	nop
	rjmp  TimerIRQ
	;reti ; Timer0 Compare Match Handler 
	;nop 
	reti ; Store Program Memory Ready Handler 
	nop 

;.org $0380
null_cseg:		.db		"00000000000",0
_001_cseg:		.db		"00000000001",0
_256_cseg:		.db		"00000000256",0
_64k_cseg:		.db		"00000065536",0
_16m_cseg:		.db		"00016777216",0

;.org $003A

lcd_lines:		.DB		0x00, 0x40, 0x14, 0x54

;á:8  é:9  í:10  ó:11  ö:12  ő:13  ú:14  ü:15
;hunchars:	.DB			0x02,0x04,0x0e,0x01,0x0f,0x11,0x0f,0x00, 0x02,0x04,0x0E,0x11,0x1f,0x10,0x0e,0x00, 0x02,0x04,0x00,0x0c,0x04,0x04,0x0e,0x00, 0x02,0x04,0x0e,0x11,0x11,0x11,0x0e,0x00, 0x0A,0x00,0x0e,0x11,0x11,0x11,0x0e,0x00, 0x05,0x0A,0x0e,0x11,0x11,0x11,0x0e,0x00, 0x02,0x04,0x11,0x11,0x11,0x13,0x0d,0x00, 0x0a,0x00,0x11,0x11,0x11,0x13,0x0d,0x00


lcd_message:	.DB		'z','o','m','b','e','e',' ','L','C','D',' ','d','r','i','v','e','r',0

lcd_kalib_message: .DB	'k','a','l','i','b','r','a','l','a','s',0,0





;************************  Főprogram  *****************************************************


RESET:

	ldi   temp,LOW(RAMEND) ;Initiate Stackpointer 
	out   SPL,temp 
	ldi   temp,HIGH(RAMEND) 
	out   SPH,temp


;******************************************************************************************

MAIN:



	rcall lcd_init
	ldi   A, 0b00001100		; 0b00001xxx <-- disp_on, curs_on, curs_blink
	rcall lcd_command_write
	rcall lcd_cls
;	rcall lcd_hun_chars
	ldi   A,50
	rcall delay_ms
	rcall lcd_cls
	ldi   A,50
	rcall delay_ms

	rcall interrupts

	ldi A,100
	rcall delay_ms



;kalibráló kondenzátor(0.9874nF), 9874 x 0.1pF
	copy_num _ccal, 0x92,0x26,0,0


;4 millió pi négyzet
	copy_num   _4mpi2, 0x91,0x64,0x5A,0x02
/*
;ezer...
	copy_num   _1000, 0xE8,0x03,0x00,0x00
*/
;egymilliárd...
	copy_num   _1mrd,  0x00,0xCA,0x9A,0x3B

;nulla... ^-^
	copy_num   _null,  0x00,0x00,0x00,0x00

	ldi temp,  0b01110000
	out DDRD,  temp
	ldi temp,  0b00001100
	out PORTD, temp


	lcd_write_XY 0,0, /*lcd_kalib_message*/ lcd_message
	rcall relay_kondi
	_delay_ms 100

	rcall lcd_cls
	lcd_write_XY 0,0, lcd_kalib_message

	_delay_ms 100
	ldi  A,0xE0
	ldi  B,0x93
	ldi  C,0x04		;300000 - 500ms
	rcall start_meas
	aritmetika_shift_L	freq
	aritmetika_copy		freq, _freq0
	aritmetika_szorzas	_freq0,freq

	rcall relay_kalib

	_delay_ms 200
	ldi  A,0xE0
	ldi  B,0x93
	ldi  C,0x04		;300000 - 500ms
	rcall start_meas
	aritmetika_shift_L	freq
	aritmetika_copy		freq, _freqC
	aritmetika_szorzas 	_freqC,freq	

	;rcall relay_kondi
	rcall relay_tekercs

	aritmetika_copy		_freq0,num1
	aritmetika_copy		_freqC,num2



	aritmetika_minusz   num1,num2
	aritmetika_szorzas  num2,_ccal
	aritmetika_osztas   num2,num1
	aritmetika_copy		num2,_Cm




	aritmetika_copy		_1mrd,_Lm
	aritmetika_szorzas	_Lm,_1mrd
	aritmetika_osztas   _Lm,_Cm
	aritmetika_osztas   _Lm,_4mpi2
	aritmetika_szorzas	_Lm,_1mrd
	aritmetika_osztas   _Lm,_freq0

	rcall lcd_cls

	copy_num  _meas_time, 0x00,0xEE,0x02,0x00		;192000 - 320ms
	copy_num  _1sec_time, 0xC0,0x27,0x09,0x00		;600000 - 1000ms




MAIN_LOOP:

	/*gotoXY 0,0
	mov    A,timer0
	rcall  lcd_data_write*/






	;mintavételező függvény. C:B:A - ban várja a mintavételi ciklus hosszát(x20 CLK)
	ldi A,0x00	;alsó
	ldi B,0xEE	;középső
	ldi C,0x02	;felső időzítő bájt - 192000 - 320ms
	clr D
	rcall start_meas

	aritmetika_szorzas	freq,_1sec_time
	aritmetika_osztas	freq,_meas_time


	
	aritmetika_copy		_Lm, num2
;	aritmetika_copy		_Cm, num2



	aritmetika_copy		_freq0,num1
	aritmetika_szorzas	num1  ,num2
	aritmetika_osztas	num1  ,freq
	aritmetika_osztas	num1  ,freq
	aritmetika_minusz	num1  ,num2
	

	convert  freq,numchar
	gotoXY 1,0
	write_num numchar



	aritmetika_copy		_null, num2
	aritmetika_minusz 	num2 , num1
	ldi ZH, high(num1)
	ldi ZL,  low(num1)
	ldi YH, high(num2)
	ldi YL,  low(num2)
	rcall aritmetika_nagyobbegyenlo
	tst carry
	breq nem_komplement
	aritmetika_copy num2, num1
nem_komplement:
	convert num1,numchar
	tst carry
	breq nem_komplement2	
	ldi ZH,high(numchar)
	ldi ZL, low(numchar)
	ldi A, '-'
	st  Z,A
nem_komplement2:
	gotoXY 1,1
	write_num numchar


	convert  _Lm,numchar
	gotoXY 8,2
	write_num numchar

	convert  _Cm,numchar
	gotoXY 8,3
	write_num numchar


	rjmp MAIN_LOOP         ;ugorj vissza az elejére 




;********************************************** FÜGGVÉNYEK **********************************************


start_meas:
	ldi  temp, 0b01000000
	out  GICR, temp

;600k - 1 másodperc

/*
ldi A,0xC0	;alsó
ldi B,0x27	;középső
ldi C,0x09	;felső időzítő bájt - 600000
*/

ldi D,255 ;túlcsordulás összehasonlító!
;időzítő számlálók értékeit betöltjük a megszakításszámlálókba
;inverz számlálás: amikor nincs interrupt, csökkentjük a számlálót
;egy interrupt sok időt emészt fel, ezért inkább akkor számlálunk, ha nem volt interrupt
mov cnt0, A
mov cnt1, B
mov cnt2, C
clr cnt3
inc cnt0

;megszakított és nem-megszakított esetben is azonos legyen az időigény: számlálófüggetlen időzítés!
;egy interrupt időigénye visszatéréssel: 2+4 CLK
;max 30 órajel időtartam összesen - jelenleg 20 órajel alatt lefut!
timer_idle:					;itt még 0 CLK
;interrupt-ellenőrzés
;akár van interrupt, akár nincs, mindkét esetre azonos időtartam!
	brid volt_interrupt		;2 v. 1 CLK
;különben ha nem volt:
;9 órajeles csökkentő mechanizmus, a brid-el együtt 10, az "rjmp timer_idle_continue" - el 12
	dec  cnt0				;1
	cp   cnt0,D				;1
	brne cnt0_nemcsordul	;2 v. 1
	dec  cnt1				;1
	cp   cnt1,D				;1
	brne cnt1_nemcsordul	;2 v. 1
	dec  cnt2				;1
	rjmp cnt1_csordul
cnt0_nemcsordul:			;ha ide jut: 5CLK
	nop
	nop
	nop
cnt1_nemcsordul:			;ha ide jut: 8CLK
	nop
	nop
cnt1_csordul:				;ha ide jut, 10CLK
	rjmp timer_idle_continue

volt_interrupt:				;IRQ igény: 6CLK; + brid: 2CLK
	sei						;1
	nop
	nop						;1 CLK-s utasítások
	nop
timer_idle_continue:		;ezidáig 12CLK telt el!

;számláló lejártának ellenőrzése: minden helyiértéken azonos időigény kell!
;ha lejárt, kilép, különben újrakezd!
	subi A,1
	brcc A_nemcsordul
	subi B,1
	brcc B_nemcsordul
	subi C,1
	brcs timer_idle_end
	rjmp timer_idle			;ezzel együtt 8 CLK
A_nemcsordul:	;idáig 3CLK
	nop
	nop
B_nemcsordul:	;idáig 5CLK
	nop
	rjmp timer_idle	;ezzel együtt 8CLK telik el!
timer_idle_end:

	ldi  temp, 0b00000000		;külső megszakítás engedélyező bitek GICR ==[int1,int0,int2,xxx,ivsel,ivce]
	out  GICR, temp				;tiltjuk. ^-^

	copy_reg freq, cnt0,cnt1,cnt2,cnt3

ret


TimerIRQ:
/*	push temp
	in   temp, SREG
	push temp
	
	inc  timer0
	brne TimerIRQ_end
	inc  timer1
	brne TimerIRQ_end
	inc  timer2
	brne TimerIRQ_end
	inc  timer3
TimerIRQ_end:
	pop  temp
	out  SREG, temp
	pop  temp*/
reti



ButtonIRQ:
	push temp
	in   temp, SREG
	push temp
	

	pop  temp
	out  SREG, temp
	pop  temp
reti





interrupts:
	cli
	push temp
	ldi  temp, 0b00001010		;lefutó él generál int0-nál és int1-nél megszakítást
	out  MCUCR, temp

	;******** NEM ENGEDÉLYEZÜNK ********
	;ldi  temp, 0b11000000		;külső megszakítás engedélyezve GICR ==[int1,int0,int2,xxx,ivsel,ivce]
	;out  GICR, temp

	ldi  temp, 0x00
	out  TCNT0,temp				;timer0 számlálója
;	ldi  temp, 186
	ldi  temp, 117
	out  OCR0, temp				;komparátor regiszter; OCR0=77; 256 osztás és OSC=12MHz mellett ~600 Hz lesz
	;00001xxx; ATMEGA16; 5:1024;    4:256;    3:64;    2:8;    1:1;
	ldi  temp, 0b00001101
	out  TCCR0,temp				;CTC mód +osztás beállítása!
	ldi  temp, 0b00000010
	out  TIMSK,temp				;Timer IT Mask regiszter - Timer2,Timer1 IT tiltva; OCIE0=1; TOIE0=0;
	pop temp
	sei							;globális IT engedélyezve
ret


	;PD2 - rezgőkör(INT0)
	;PD3 - nyomógomb(INT1)
	;PD4 - vmelyik relé - módválasztó
	;PD5 - hangszóró
	;PD6 - vmelyik relé - kalibráló

relay_kalib:
	in   temp,  PORTD
	andi temp,  0b11101111	;tekercs benne van a körben!
	ori  temp,  0b01000000	;kalibráló kondi
	out  PORTD, temp
ret


relay_kondi:
	in   temp,  PORTD
	andi temp,  0b10101111	;minden relét lekapcsol!
	out  PORTD, temp
ret


relay_tekercs:
	in   temp,  PORTD
	andi temp,  0b10111111	;kalibrálót lekapcsolja
	ori  temp,  0b00010000	;tekercs mód
	out  PORTD, temp
ret



delete_fv:
	push temp
	clr  temp
	st   X+,temp
	st   X+,temp
	st   X+,temp
	st   X+,temp
	pop  temp
ret


EEPROM_write:
; Wait for completion of previous write
sbic EECR,EEWE
rjmp EEPROM_write
; Set up address (r18:r17) in address register
out EEARH, r18
out EEARL, r17
; Write data (r16) to data register
out EEDR,r16
; Write logical one to EEMWE
sbi EECR,EEMWE
; Start eeprom write by setting EEWE
sbi EECR,EEWE
ret


EEPROM_read:
; Wait for completion of previous write
sbic EECR,EEWE
rjmp EEPROM_read
; Set up address (r18:r17) in address register
out EEARH, r18
out EEARL, r17
; Start eeprom read by writing EERE
sbi EECR,EERE
; Read data from data register
in r16,EEDR
ret






;Y:szorzandó, Z:szorzó, eredmény:X-be gyűlik(maradek), majd átteszi Y-ba
aritmetika_szorzas_fv:
	ldi  XH, high(maradek)
	ldi  XL,  low(maradek)
	clr  A
	ldi  B,8
szorzas_gyujt_csokkent:
	st   X+, A
	dec  B
	brne szorzas_gyujt_csokkent
	sbiw X,  8				;gyűjtő regiszter törlés majd mutató visszaállítás
	ldi  C,64
	ldi  B,8
aritmetika_szorzas_fv_continue:
	tst   C
	breq  aritmetika_szorzas_fv_end
	dec   C
	rcall aritmetika_szorzas_iter
	rjmp  aritmetika_szorzas_fv_continue
aritmetika_szorzas_fv_end:
	ld   A, X+
	st   Y+,A
	dec  B
	brne aritmetika_szorzas_fv_end
	sbiw X, 8
	sbiw Y, 8
ret


aritmetika_szorzas_iter:
	ld   A, Z
	andi A, 0x01
	breq aritmetika_szorzas_iter_end
	rcall aritmetika_plusz_fv			;úgyis X-ben van az eredmény, Y-ban a hozzáadandó...
aritmetika_szorzas_iter_end:
;shiftek
	push XH
	push XL
	movw X, Y
	rcall aritmetika_shift_L_fv
	movw X, Z
	rcall aritmetika_shift_R_fv
	adiw X, 7
	ld   A, X
	or   A, carry
	st   X, A
	sbiw X, 7
	pop  XL
	pop  XH
ret




;X:osztandó, Y:osztó, maradék:Z-be teszi, de nem paraméterezhető!
aritmetika_osztas_fv:
	ldi  ZH, high(maradek)
	ldi  ZL,  low(maradek)
	clr  A
	ldi  B,8
osztas_gyujt_csokkent:
	st   Z+, A
	dec  B
	brne osztas_gyujt_csokkent
	sbiw Z,  8				;maradékregiszter törlés majd mutató visszaállítás
	ldi C,64
aritmetika_osztas_fv_continue:
	tst   C
	breq  aritmetika_osztas_fv_end
	dec   C
	rcall aritmetika_osztas_iter
	rjmp  aritmetika_osztas_fv_continue
aritmetika_osztas_fv_end:
ret


aritmetika_osztas_iter:
	push  XH
	push  XL
	movW  X, Z						;maradékregiszter
	rcall aritmetika_shift_L_fv		;balra tol	
	pop   XL
	pop   XH	
	rcall aritmetika_shift_L_fv		;X-et(osztandó) balra tolja, tetejét áttolja a maradékregiszterbe
	ld    A, Z
	add   A, carry					;ha átcsordul a legfelső 1-es bit az osztandóból a maradék legaljára kerül.
	st    Z, A
atcsordulas_vege:
	rcall aritmetika_nagyobbegyenlo			; Z>=Y ?
	tst   carry
	breq  aritmetika_osztas_iter_end
	ld    A, X
	inc   A
	st    X, A
	push  XH
	push  XL
	movW  X, Z
	rcall aritmerika_minusz_fv				; X^:= X^-Y^
	pop   XL
	pop   XH
aritmetika_osztas_iter_end:
ret


; Z^ >= Y^ ?
;carry-be teszi az eredményt
aritmetika_nagyobbegyenlo:
	push A
	push B
	push C
	clr  carry
	adiw Z,8
	adiw Y,8
	ldi  C,8
aritmetika_nagyobbegyenlo_continue:
	tst  C
	breq aritmetika_nagyobbegyenlo_igaz			;ha lejárt a számlálónk, akkor egyenlőek
	dec  C
	ld   A, -Z
	ld   B, -Y
	cp   B, A
	brlo aritmetika_nagyobbegyenlo_igaz			;ha nagyobbegyenlő: igaz!
	breq aritmetika_nagyobbegyenlo_continue		;egyébként csak akkor folytat, ha egyenlőek!
	rjmp aritmetika_nagyobbegyenlo_end
aritmetika_nagyobbegyenlo_igaz:
	inc carry
	;rcall hexa ;***************************************************************************************
aritmetika_nagyobbegyenlo_end:
	tst  C
	breq aritmetika_nagyobbegyenlo_mostmartenylegvege
	dec  C
	sbiw Z,1
	sbiw Y,1
	rjmp aritmetika_nagyobbegyenlo_end
aritmetika_nagyobbegyenlo_mostmartenylegvege:
	pop  C
	pop  B
	pop  A
ret



aritmetika_copy_fv:
	ldi  C,8
aritmetika_copy_fv_iter:
	tst   C
	breq  aritmerika_copy_fv_end
	dec   C
	ld    A,  X+
	st    Y+, A
	rjmp aritmetika_copy_fv_iter
aritmerika_copy_fv_end:
ret


;2-vel beszoroz, X-ben kéri a 32 bites változót...
aritmetika_shift_L_fv:
	push C
	push A
	ldi  C,8
	clc
aritmetika_shift_L_fv_iter:
	tst   C
	breq  aritmetika_shift_L_fv_end
	dec   C
	ld    A, X
	rol   A
	st    X+, A
	rjmp aritmetika_shift_L_fv_iter
aritmetika_shift_L_fv_end:
	clr  carry
	brcc aritmetika_shift_L_fv_nincscarry
	inc  carry
aritmetika_shift_L_fv_nincscarry:
	sbiw  X,8
	pop  A
	pop  C
ret


;2-vel leoszt, X-ben kéri a 32 bites változót...
aritmetika_shift_R_fv:
	push C
	push A
	adiw X,8
	ldi  C,8
	clc
aritmetika_shift_R_fv_iter:
	tst   C
	breq  aritmetika_shift_R_fv_end
	dec   C
	ld    A, -X
	ror   A
	st    X, A
	rjmp aritmetika_shift_R_fv_iter
aritmetika_shift_R_fv_end:
	clr  carry
	;brcc aritmetika_shift_R_fv_nincscarry
	;inc  carry
	ror  carry
	;ror  carry
aritmetika_shift_R_fv_nincscarry:
	pop  A
	pop  C
ret



;az operandusok .dseg - ben vannak, és X,Y pointereken találhatók
;eredmény kiírása az X-be, ?error flag az A-ban.?
aritmerika_minusz_fv:
	push C
	push B
	push A
	ldi  C,8
	clc								;carry flag törlés!
aritmetika_minusz_fv_iter:
	tst  C							;carry-t nem bántja!
	breq aritmetika_minusz_fv_end
	dec  C							;carry-t nem bántja!
	ld   A, X
	ld   B, Y+
	sbc  A, B						;-maradék...
	st   X+,A						;letárol!
	rjmp aritmetika_minusz_fv_iter
aritmetika_minusz_fv_end:
	sbiw X,8
	sbiw Y,8
	pop  A
	pop  B
	pop  C
ret


;az operandusok .dseg - ben vannak, és X,Y pointereken találhatók
;eredmény kiírása az X-be, ?error flag az A-ban.?
aritmetika_plusz_fv:
	push C
	push B
	push A
	ldi  C,8
	clc								;carry flag törlés!
aritmetika_plusz_fv_iter:
	tst  C							;carry-t nem bántja!
	breq aritmetika_plusz_fv_end
	dec  C							;carry-t nem bántja!
	ld   A, X
	ld   B, Y+
	adc  A, B						;+maradék...
	st   X+,A						;letárol!
	rjmp aritmetika_plusz_fv_iter
aritmetika_plusz_fv_end:
	sbiw X,8
	sbiw Y,8
	pop  A
	pop  B
	pop  C
ret



;X - ben a 64 bites bináris adatot kapja(alsó 32 bitet néz), Y-ban az ember által emészthető célt adja majd vissza
convert_nums:
	push temp
	ldi  ZH,   high(2*_001_cseg)	;hozzáad  - bináris helyiérték decimálisan [001-es][256-os][64k-os][16m-es]
	ldi  ZL,    low(2*_001_cseg)	;ez is. (^-^)
	ldi  temp,4						;4 főiteráció - 4 bináris helyiérték
convert_nums_main_iter:
	tst  temp
	breq convert_nums_end
	dec  temp
convert_nums_001:
	ld   A, X+						;forrás   - bináris    helyiérték [001-es][256-os][64k-os][16m-es]
convert_nums_001_iter:
	tst   A
	breq  convert_nums_nextiter		;ha lejárt a helyiérték-számláló: továbblép!
	dec   A
	rcall convert_add
	rjmp  convert_nums_001_iter
convert_nums_nextiter:
	adiw Z,12						;következő bináris helyiérték decimálisan(kódszegmensben folytonos legyen!)
	rjmp convert_nums_main_iter
convert_nums_end:
	pop temp
ret


;csak 11 jegyű számokat ad össze!
;Z-ben várja a hozzáadnivalót(.cseg), Y-ban a célt(.dseg)
convert_add:
	adiw Z,10	;rááll az 1-es helyiértékre
	adiw Y,10
	ldi  B,10	;helyiérték-számláló
	clr  E		;maradék-regiszter
convert_add_iter:
	tst  B
	breq convert_add_end	;ha lejárt a helyiérték-számláló: kilép!
	dec  B
	lpm  C,Z	;beolvas forrást és célt
	ld   D,Y
	subi C,48	;bináris alak
	subi D,48
	add  C,D	;összeadás
	add  C,E	;előző maradék hozzáadása
	clr  E
	cpi  C,10	;van-e maradék?
	brlo convert_add_continue
	subi C,10
	inc  E		;maradék legfeljebb 1 lehet!
convert_add_continue:
	ldi  D,48
	add  C,D
	st   Y,C	;érték letárol!
	sbiw Z,1	;helyiérték növelés
	sbiw Y,1
	rjmp convert_add_iter
convert_add_end:
ret





load_num_fv:
	push temp
load_num_fv_continue:
	lpm  temp,Z+
	st   Y+,temp
	tst  temp
	brne load_num_fv_continue
	pop temp
ret


; ZH:ZL pointerben várja a 0-végű karakterlánc címét( .dseg!!! )
write_num_fv:
	push  A
write_num_fv_continue:
	ld    A,Z+
	tst   A
	breq  write_num_fv_end
	rcall lcd_data_write
	rjmp  write_num_fv_continue
write_num_fv_end:
	pop   A
ret


; ZH:ZL pointerben várja a 0-végű karakterlánc címét( .cseg!!! )
lcd_string:
	push A
lcd_string_action:
	lpm  A, Z+
	tst  A
	breq lcd_string_end
	rcall lcd_data_write
	rjmp lcd_string_action
lcd_string_end:
	pop  A
ret



lcd_write_XY_fv:
	rcall lcd_cursor
	rcall lcd_string
ret



;A,B == x,y párosban várja a koordinátákat
lcd_cursor:
	push C
	clr  C
	andi B, 0b00000011
	sbrc B, 0
	ldi  C, 0x40
	push C
	clr  C
	sbrc B, 1
	ldi  C, 0x14
	add  A, C
	pop  C
	add  A, C
	rcall lcd_set_DDRAM_addr
	pop  C
ret


lcd_toggle_E:
	push A
	push B
	push C
	ldi A, 160		;előkészítési idő(160us)
	rcall delay_us
	ldi A,1
	ldi B,LCD_E
	rcall shift_L
	mov B, lcdport
	;in  B,LCD_PORT
	or  B,A
	out LCD_PORT,B
	mov C,A
	ldi A, 250			;tartási idő(250us)
	rcall delay_us
	com C
	and B,C
	mov lcdport, B
	out LCD_PORT,B
	ldi A, 120			;elengedési idő(120us)
	rcall delay_us
	pop C
	pop B
	pop A
ret



/*lcd_hun_chars:
	push A
	push B
	ldi  A, 0
	rcall lcd_set_CGRAM_addr
	ldi ZH,high(2*hunchars)
	ldi ZL,low(2*hunchars)
	ldi B,64
lcd_hun_chars_continue:
	lpm A,Z+
	rcall lcd_data_write
	ldi A,100
	rcall delay_us
	dec B
	brne lcd_hun_chars_continue
	pop B
	pop A
ret*/


lcd_cls:
	push A
	ldi A,0x01
	rcall lcd_command_write
	ldi  A,0x00
	rcall lcd_set_DDRAM_addr
	pop  A
ret


lcd_set_DDRAM_addr:
	ori   A, 0b10000000
	rcall lcd_command_write
ret

lcd_set_CGRAM_addr:
	andi A, 0b00111111
	ori  A, 0b01000000
	rcall lcd_command_write
ret


;A tartalmát adatként írja ki...
lcd_data_write:
	push  B
	push  C
	push  D
	mov   D, A			;adat a D-be!!!
	ldi   A, 1
	ldi   B,LCD_RS
	rcall shift_L
	mov   C, A			;RS a helyén, C-ben!
	mov   A, D
	andi  A, 0xf0		;felső nibble
	ldi   B, 4
	subi  B, LCD_4
	rcall shift_R
	or    A, C
	mov   lcdport,  A
	out   lcd_port, A
	rcall LCD_TOGGLE_E
	mov   A, D
	andi  A, 0x0f		;alsó nibble
	ldi   B, LCD_4
	rcall shift_L
	or    A, C
	mov   lcdport,    A
	out   LCD_PORT, A
	rcall LCD_TOGGLE_E
	pop  D
	pop  C
	pop  B
ret


;temp tartalmát parancsként írja ki...
lcd_command_write:
	push B
	push C
	mov  C, A
	andi A, 0xf0
	ldi  B, 4
	subi B, LCD_4
	rcall shift_R
	mov   lcdport, A
	out   LCD_PORT,A
	rcall LCD_TOGGLE_E
	mov  A, C
	andi A, 0x0f
	ldi  B, LCD_4
	rcall   shift_L
	mov     lcdport,     A
	out     LCD_PORT,A
	rcall   LCD_TOGGLE_E
	pop C
	pop B
ret


lcd_init:
	push A
	push B
	push C
	ldi  A, 0xff
	out  LCD_DDR,  A
	ldi  A, 0x00
	mov  lcdport,  A
	out  LCD_PORT, A
	ldi  A,100
	rcall delay_ms
;set 8-bit operation RESET - 3x
	ldi  A, 1
	ldi  B,LCD_5
	rcall shift_L
	mov  C,A
	ldi  A, 1
	ldi  B,LCD_4
	rcall shift_L
	or  C,A
	mov lcdport,   C
	out  LCD_PORT, C
	rcall LCD_TOGGLE_E
	ldi  A,10
	rcall delay_ms
	mov lcdport,   C
	out  LCD_PORT, C
	rcall LCD_TOGGLE_E
	ldi  A,10
	rcall delay_ms
	mov lcdport,   C
	out  LCD_PORT, C
	rcall LCD_TOGGLE_E
	ldi  A,10
	rcall delay_ms
;set 4-bit operation 
	ldi   A, 1
	ldi   B,LCD_5
	rcall shift_L
	mov   C, A
	mov   lcdport,   C
	out   LCD_PORT,  C
	rcall LCD_TOGGLE_E
	ldi   A,10
	rcall delay_ms
	mov lcdport,     C
	out   LCD_PORT,  C
	rcall LCD_TOGGLE_E
;2 line mod, 5x8 fonts  
	ldi   A, 1
	ldi   B,LCD_7
	rcall shift_L
	mov   lcdport,   A
	out   LCD_PORT,  A
	rcall LCD_TOGGLE_E
;Display ctrl: display off, cursor off, blink off 
	clr   A
	mov   lcdport,   A
	out   LCD_PORT,  A
	rcall LCD_TOGGLE_E
	ldi   A, 1
	ldi   B,LCD_7
	rcall shift_L
	mov lcdport,     A
	out   LCD_PORT,  A
	rcall LCD_TOGGLE_E
	ldi   A,100
	rcall delay_us
;Clear display
	clr   A
	mov   lcdport,   A
	out   LCD_PORT,  A
	rcall LCD_TOGGLE_E
	ldi   A, 1
	ldi   B,LCD_4
	rcall shift_L
	mov   lcdport,   A
	out   LCD_PORT,  A
	rcall LCD_TOGGLE_E
	ldi   A,3
	rcall delay_ms
;increment mode,entire shift off
	clr   A
	mov   lcdport,   A
	out   LCD_PORT,  A
	rcall LCD_TOGGLE_E
	ldi  A, 1
	ldi  B,LCD_6
	rcall shift_L
	mov  C,A
	ldi  A, 1
	ldi  B,LCD_5
	rcall shift_L
	or   C,A
	mov  lcdport,    C
	out  LCD_PORT,   C
	rcall LCD_TOGGLE_E
	ldi  A,100
	rcall delay_us
	pop C
	pop B
	pop A
ret

shift_L:
shift_continueL:
	cpi  B,0
	breq shift_endL
	lsl  A
	dec  B
	rjmp shift_continueL
shift_endL:
ret

shift_R:
shift_continueR:
	cpi  B,0
	breq shift_endR
	lsr  A
	dec  B
	rjmp shift_continueR
shift_endR:
ret



delay_us:
	nop		; CPU_SPEED - 3
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	nop
	dec  A				;1 MIPS
	brne delay_us		;2 MIPS (kilépésnél 1)
delay_us_end:
	ret




delay_ms:					;temp-ből várja a várakozási időt!
	push A					;temp letárolás
	ldi A,CPU_SPEED			;ennyiszer vár 1000 MIPS-t! Ahány MHz - es az órajel!
delay_ms_continue:
	rcall delay_1000_mips
	dec A
	brne delay_ms_continue	;ha nem járt le a 12000 MIPS, visszaugrik
	pop A					;ha lejárt, visszatölti a temp-et...
	dec A					;...majd csökkenti.
	breq delay_end			;ha elérte a 0-t, akkor kilép...
	rjmp delay_ms			;egyébként rekurzívan meghívja önmagát, stacket nem terheli
delay_end:
	ret


delay_1000_mips:						;4 MIPS a meghívás!(1x)
	push A								;2 MIPS(1x)
	ldi A,246							;1 MIPS(1x)
delay_1000_mips_continue:
	nop									;1 MIPS
	dec A								;1 MIPS
	brne delay_1000_mips_continue		;2 MIPS, ha ugrik(szinte mindig)! + 1x 1 MIPS
delay_1000_mips_end:
	pop A								;2 MIPS(1x)
	ret									;4 MIPS(1x) - összesen ami 1x: 14







/*
;f=N/(T+N*T[interrupt])
;T[interrupt] kikalkulálva 22 órajelig tart!
AnalogIRQ:
	push temp				;2 clk
	in   temp, SREG			;1 clk
	push temp				;2 clk
	inc  cnt0				;1 clk
	brne AnalogIRQ_end		;nem ugrik:1; ugrik:2
	inc  cnt1				;1 clk
	brne AnalogIRQ_end		;nem ugrik:1; ugrik:2
	inc  cnt2				;1 clk
	brne AnalogIRQ_end		;nem ugrik:1; ugrik:2
	inc  cnt3				;1 clk
AnalogIRQ_end:
	pop  temp				;2 clk
	out  SREG, temp			;1 clk
	pop  temp				;2 clk
reti						;4 clk
*/






;	copy_reg num_cnt, cnt0,cnt1,cnt2,cnt3
/*
	ldi  A, 22
	clr  B
	clr  C
	clr  D
	copy_reg delta_time, A,B,C,D	;22 órajel egy AnalogIRQ!
	aritmetika_szorzas  delta_time, num_cnt
	ldi  A, CPU_SPEED
	clr  B
	clr  C
	clr  D
	copy_reg num4, A,B,C,D
	aritmetika_osztas	delta_time, num4	;mikroszekundum...
	ldi  A, 0x70
	ldi  B, 0x82
	ldi  C, 0x03
	clr  D	
	copy_reg num4, A,B,C,D					;230000 mikroszekundum!
	aritmetika_plusz	delta_time, num4

	clr  A
	ldi  B, 0x28
	ldi  C, 0x6B
	ldi  D, 0xEE
	copy_reg  freq, A,B,C,D					;4 milliárd!
	aritmetika_osztas  freq, delta_time		;4milliárd / idő(us)
	aritmetika_szorzas freq, num_cnt		;(4milliárd / idő(us)) * leütésszám == freq*4000
	ldi  A, 0xA0
	ldi  B, 0x0F
	clr  C
	clr  D	
	copy_reg num4, A,B,C,D					;4000
	aritmetika_osztas  freq, num4			;!!freq!!
*/
