;int0.asm			simula a interrupção externa INT0 (PD2, pino 4 da CPU)
;					estando a CPU no modo sleep power down
;					a interrupção deve ser configurada para um sinal de nivel baixo  no pino 4
;					a rotina de interrupção liga um led conectado em PD0 (pino 2 da CPU)
;					no simulador o nivel alto inicial requerido em PIND2 é colocado 
;					clicando no bit PIND2 do registrador PIND
;					o pedido de interruoção é simulado clicando no bit PIND2
;					e  desligado clicando novamente em PIND2
;					MC404 Maio 2008    Prof Célio Guimarães
;*************************************************************************************
.nolist
.include "m88def.inc"
.list
.def intcount = r1
.def toggle= r16
.def one = r17
.org 0
	rjmp	RESET		;reset handle
	rjmp    EXT_INT0	;vetor de interrupção INT0 em 0x01


;*************************************************************************************
EXT_INT0:
        cbi portd,pd2				; rotina de interrupcao INT0
        sbi PIND,pd2
	inc intcount		; contador de interrupções
	eor toggle,one		; vira o toggle,
	breq ledon			; se  era 1 acende led,
	cbi PORTD, 0		; senão, desliga led
	reti
ledon:
	sbi PORTD,0			; liga led conectado no pino 2
	reti				; retorna com interrupções 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

	cbi ddrd,pd2		; configura p/ entrada no pino 4 (int0)
	sbi ddrd,pd0		; saída: vamos ligar um led no pino 2 da CPU (pd0)
	cbi portd,pd2		; ativa resistor de pull up; deveria colocar o bit PD2 de PIND em 1
        sbi PIND, pd2		; queremos interromper com nivel baixo em PD2
	ldi r16,0
	sts EICRA, r16		; queremos interromper 2= na descida do sinal 0=no nivel baixo do sinal em pd2 (p. 84 datasheet)
	sbi eimsk,int0		; habilita interrupção INT0
	ldi r16,5			; sleep power down(SM1=1) & sleep enable SE=1(p 37 datasheet)
	out SMCR,r16		; do it 
	ldi toggle,1		;	toggle para ligar/desligar led
	ldi one,1
	sei					; habilita interrupções globalmente 
loop:
	sleep				; "dorme" no modo power down: só acorda via interrupção externa
	rjmp loop			; volta a "dormir" após serviço da interrupção

