;************************************************************************************
;e2promint.asm	Exemplo de interrupcao no ATmega88
;				Este exemplo usa uma rotina de interrupção de fim de escrita na e2prom
;				(vetor em 0x16) para sinalizar ao programa principal (via bit T) 
;				que um byte acabou de ser gravado; ao detetar o fim da gravacao 
;				o programa principal comanda a escrita de mais um byte e fica num laco
;				de espera "busy wait" pelo termino da gravacao e assim por diante ate 
;				gravar cerca de 26 bytes (letras 'A' ate' 'Z');
;				o simulador nao reflete corretamente o valor do contador de 16 bits 
;				colocado dentro deste laco e que deveria atingir alguns milhares 
;				correspondendo ao tempo de escrita de um byte,  ~3.5 ms
;				MC 404E 1º Sem 2008 - Prof Celio Guimaraes
;				Atualizado em 18/04/2008

;*************************************************************************************
.nolist
.include "m88def.inc"
.list

start:
	rjmp	RESET	;reset handle
.org		0x16	
	rjmp e2promready
    ; . . .					; possivelmente outros vetores de interrupcao aqui

;*************************************************************************************
e2promready:			; rotina de interrupcao:fim de gravacao de um byte na EEPROM
	set					; liga o bit T para sinalizar o programa principal
	reti				; retorna com interruocoes habilitadas
;*************************************************************************************
RESET:					; Obs: no reset o ATmega88 inicializa o stack pointer para
						; o fim da RAM, por isto nao o fizemos aqui; noutros modelos
						; como no ATtiny2313 isto não é verdade:é preciso inicializar
						; a pilha para suportar interrupcoes e subrotinas

	clr r25					; vamos gravar no enderco 0 da EEPROM
	clr r24
	movw x, r25:r24			; vamos contar em X o "tempo" de espera pela gravacao
	ldi r16, 'A'			; 1o byte a ser gravado
	sei                     ; pois apos RESET interrupcoes estao desaabilitadas
    ; importante: apos o RESET todos os bits do registrador EECR sao inicializados com
	; 0; por isto nao inicializaremos os bits EEPM1 e EEPM0 com 0 (apaga e escreve)
l0:
	out EEARH, r25            ;Set up address (r25:r24) in address register
	out EEARL, r24
	out EEDR,r16               ; Write data (r16) to Data Register
	sbi EECR,EERIE				;habilita interrupcao de fim de gravacao
	sbi EECR,EEMPE             ; Write logical one to EEMPE
	sbi EECR,EEPE              ; Start eeprom write by setting EEPE
l1:								; laço de espera pelo término da gravação
	adiw x,1					; incrementa contador de espera da gravacao de um byte
	brtc	l1					; se T=0 volta a esperar término da escrita na EEPROM
	clt							; desliga o bit T p/ esperar pela proxima interrupcao,
	clr xh						; e zera o contador do laco "busy wait"
	clr xl
	adiw r25:r24,1				; ajusta endereco do proximo byte a ser gravado
	inc r16						; proxima letra a ser gravada na E2PROM
	cpi r16, 'Z'+1				; gravaremos ate a letra Z inclusive
	brne l0						; volta p/ gravar a proxima letra
	
	rjmp PC						; fim...
