.include <m8def.inc>

.equ PAGESIZEB = 64
.def loophi =r25
.def looplo =r24

.dseg
.org 0x60	srampage: .BYTE 64    ;32word(64byte) pagesize for spm instruction


.cseg
.org 0x00 rjmp RESET

RESET:
	ldi r16,high(RAMEND)
	out SPH,r16
	ldi r16,low(RAMEND)
	out SPL,r16			;stack inic
;--page feltoltese
	ldi XH,high(srampage)
	ldi XL,low(srampage)
	ldi r16,160	;srampage vegso cim
	ldi r17,0x33		;tetszoleges kinstans
do_loop:
	st X+,r17
	cp XL,r16
	brne do_loop
	;Y-reg cimenek megadasa
	;Z-reg
	lds r16,0x04;adress ; Z reg beallitasa
	lds r17,0x04; BYTE2(adress)
;	lsr r16	;>>
;	lsr r17 ;>>
	mov r31,r17
	mov r30,r16
;	movw r31:r30,r17:r16	;atmasolas Z1:z0 HELYETT
	ldi r16,low(srampage)
	ldi r17,high(srampage)
;	movw r29:r28,r17:r16
	mov r29,r17
	mov r28,r16
	ldi looplo, low(PAGESIZEB)
	rcall Write_page
	rjmp endloop

endloop: rjmp endloop

ERROR_: rjmp ERROR_



;---subroutines
Write_page:	; page erase
	ldi r20, (1<<PGERS) | (1<<SPMEN)	;ERASE
	rcall Do_spm
;	nop; re-enable the RWW section
	ldi r20, (1<<RWWSRE) | (1<<SPMEN)
	rcall Do_spm		;itt a hiba
	; transfer data from RAM to Flash page buffer
	ldi looplo, low(PAGESIZEB) ;init loop variable
;	ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256
Wrloop:
	ld r0, Y+
	ld r1, Y+
	ldi r20, (1<<SPMEN)
	rcall Do_spm
	adiw ZH:ZL, 2
	subi looplo,2;sbiw loophi:looplo, 2 ;use subi for PAGESIZEB<=256
	brne Wrloop
	; execute page write
	subi ZL, low(PAGESIZEB) ;restore pointer
;	sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256
	ldi r20, (1<<PGWRT) | (1<<SPMEN)
	rcall Do_spm
	; re-enable the RWW section
	ldi r20, (1<<RWWSRE) | (1<<SPMEN)
	rcall Do_spm
	; read back and check, optional
	ldi looplo, low(PAGESIZEB) ;init loop variable
;	ldi loophi, high(PAGESIZEB) ;not required for PAGESIZEB<=256
	subi YL, low(PAGESIZEB) ;restore pointer
	sbci YH, high(PAGESIZEB)
Rdloop:
	lpm r0, Z+
	ld r1, Y+
	cpse r0, r1
	rjmp ERROR_		;VALAMI ERRORRA LEP LI
	subi looplo,1;sbiw loophi:looplo, 1 ;use subi for PAGESIZEB<=256
	brne Rdloop
; return to RWW section
; verify that RWW section is safe to read
Return:
	in r16, SPMCR
	sbrs r16, RWWSB ; If RWWSB is set, the RWW section is not ready yet
	ret
; re-enable the RWW section
	ldi r20, (1<<RWWSRE) | (1<<SPMEN)
	rcall Do_spm
	rjmp Return


Do_spm:
; check for previous SPM complete
Wait_spm:
	in r16, SPMCR
	sbrc r16, SPMEN
	rjmp Wait_spm
	; input: spmcrval determines SPM action
	; disable interrupts if enabled, store status
	in r17, SREG
	cli
	; check that no EEPROM write access is present
	Wait_ee:
	sbic EECR, EEWE
	rjmp Wait_ee
	; SPM timed sequence
	out SPMCR, r20;spmcrval
	spm
	sei; restore SREG (to enable interrupts if originally enabled)
	out SREG, r17
	ret
