;Atmega8-intr-teszt-1.asm											2018.03.02.
;------------------------------------------------------------------------------
;ATMEL,  AVR Studio 4   esetén kell megadni:
	.device ATmega8a			;ATmega8, CPU konfigurációs fájl
	.include "m8def.inc"		;assembler mnemonik lista
;==============================================================================
.list
;==============================================================================
;						*** Általámos MACRO-k eleje ***
;-----------------------------------------------------------------------------
;------------------------------------------------------------------------------
.macro TtoPort		; TtoPort PortX, PortBitCt
					; pl: TtoPort PortB, B4
					; PortB B4-es bitjébe írja a Tbit-et
		brts TtoPort1
			cbi @0,@1	;Ha Tbe=0, LED sötét
			rjmp TtoPort2
	TtoPort1:
			sbi @0,@1	;Ha Tbe=1, LED világít
	TtoPort2:		; Tbit változatlan marad
.endmacro
;------------------------------------------------------------------------------
.macro Tinv		;SREG T bit invertálása 		(régebben: ".macro TBI")
;.macro TBI
				;hívás: Tinv (nincs paraméter)
				;használt BIT változó: T bit (SREG-ben bit akkumulátor!)
		brts T_H	;ugrik, ha T=H
		set			;T:=1
		rjmp T_L
	T_H:clt			;T:=0
	T_L:
.endmacro
;------------------------------------------------------------------------------
.macro WaitCiklus 	; pl: WaitCiklus 10000		; max 65535 ciklus késleltetés
	push XL
	push XH
		ldi XL,low(@0)
		ldi XH,high(@0)
	WaitCiklus_1:	
		sbiw XL,1
		brne WaitCiklus_1
	pop XH
	pop XL
.endmacro
;------------------------------------------------------------------------------
;							*** Cimkék, konstansok ***
;------------------------------------------------------------------------------
; Bit címkék:
		.equ B0 = 0
		.equ B1 = 1
		.equ B2 = 2
		.equ B3 = 3
		.equ B4 = 4
		.equ B5 = 5
		.equ B6 = 6
		.equ B7 = 7
;------------------------------------------------------------------------------
.DSEG
;Stack beállítása a RAM alsó címtartományába:
	StackMeret:	.BYTE 63	;31	; 32 bájt lefoglalása a stack részére (0x0060...+31db)
	StackTop:	.BYTE 1		; stack pointer kezdő értéke a stack tetejére mutasson
							; Stack pointer (SP, SH) kezdőérték beállítása a
							; főprogram (.CSEG) elején, inicializálásnál!
	UresBajtok:	.BYTE 2		; leellenőrizni, hogy kell-e ennyit kihagyni a 
							; stack felett?!?
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Rendszeróra paraméterek:
;------------------------------------------------------------------------------
;Előosztó (Timer0 előtt) osztás beállítása: TCCR0 : B2,B1,B0
;		 (a többi bit mindig =0 !!!)
; Prescaler beállító kódok és a hozzárendelt funkciók:
;		cimke		kód			funkció (osztás)
	.equ clk_no  = 0b00000000	;no clk source
	.equ clk_1   = 0b00000001	;Clk/1
	.equ clk_8   = 0b00000010	;Clk/8
	.equ clk_64  = 0b00000011	;Clk/64
	.equ clk_256 = 0b00000100	;Clk/256
	.equ clk_1024= 0b00000101	;Clk/1024
	.equ clk_10  = 0b00000110	;Ext T0 pin 1->0 él -> Timer0 számlálja
	.equ clk_01  = 0b00000111	;Ext T0 pin 0->1 él -> Timer0 számlálja
;--------------------------------
;Timer0 osztásának számítása:
; CPU oszcillátor = 15 MHz				;;előtte: 14,3 MHz
	.equ Prescaler 	= 0b00000011	;Clk/64, előosztó osztása (=64)
; Timer0 osztó aut. számítása:
;	.set Tim0oszt  	=  CPU_Clk * IntrTime  / Prescaler
		; Tim0oszt 	=  14.3 * 500 / 64 = 112	;lefelé(!) számláláshoz
; Az osztó beállított értéke:
	.set Tim0oszt  = 112 	; Timer0 megszakítások: 500 usec-onként,
							; 	 periódusidő: 2 * 500 us = 1 ms
;--------------------------------
; Rendszeridő bitek a RAM-ban:
	TFlags:	.BYTE 1		; Aktuális TFlags (órabit) bájt, B0...B7 bitek [1B]
						; az időbiteket a Timer0 megszakítási rutin billegeti
; Időbitek a TFlags bájtban:
	.equ T_1ms = B0			; TFlags regiszter 1ms-os bitje
;------------------------------------------------------------------------------
;Timer2 teszt
	KapuIdoSz:	.BYTE 1		; Timer2 Kapuidő számláló
;------------------------------------------------------------------------------
; *****************************************************************************


;==============================================================================
.CSEG		;.ORG $0000		; ua eredmény...
;------------------------------------------------------------------------------
;					***	RESET and INTERRUPT VECTORS (ATmega8) ***
    rjmp Start	;Reset vektor1	RESET\
    reti 		;Int vector 2 	INT0
	reti		;Int vector 3	INT1
   	reti		;Int vector 4	TIMER2 COMP
   	rjmp TIMER2_OVF		;Int vector 5	TIMER2_OVF
    reti		;Int vector 6	TIMER1
    reti		;Int vector 7	TIMER1
    reti		;Int vector 8	TIMER1
    reti		;Int vector 9	TIMER1_OVF
    rjmp TIMER0_OVF ;Int vector 10	TIMER0_OVF (Timint0, sysclock)
    reti		;Int vector 11	SPI,STC
    reti		;Int vector 12	USART
    reti		;Int vector 13	USART
    reti		;Int vector 14	USART
    reti;rjmp ADCMux	;Int vector 15	ADC conversion complete
   	reti		;Int vector 16
   	reti		;Int vector 17
	reti;rjmp TWI_Handler	;Int vector 18	TWEN bit, TWI Serial Interface Handler
   	reti		;Int vector 19
   	reti;rjmp Timint0;Int vector 20	Timer0_Comp
   	reti		;Int vector 21
;==============================================================================
;		Interrupt rutinok 
;------------------------------------------------------------------------------
;Hívja: Int vector 10	TIMER0_OVF   (régebben:  Timint0)
TIMER0_OVF:		;Timer0 Overflow megszakítás kezelése
				; Timer0 az osztó alsó (Oszt_Lo) bájtot számlálja
				; ha lefutott, akkor túlcsordulás miatt megszakítás, ide ugrik
				; Timer0 megszakítás ciklusidő
				; Timer0: 8 bites felfelé számláló 'Normal' üzemmódban
				; a Timer 0-ba a 'Tim0_Oszt' -> 2' komplemensét kell betölteni
				; 2' komplemenstől számol felfelé, túlcsorduláskor megszakítás:
				; 			OVF0=1 -> 'TIMER0_OVF' vektorra ugrik
			; Használt macro-k: -
	push r16
	in r16,SREG		;save the content of the SREG flag register
	push r16		;save the content of the SREG flag register
	push r17
	push ZL			; LongJumpNE --> ijmp miatt
	push ZH
;-----------------------
;*cli
	ldi r16,Tim0oszt	;Timer0 kezdőértéke újratöltése (ez az alsó bájt)
	neg r16				;2' komplemens (a maradékot számolja le!)
	out TCNT0,r16		;a betöltött kezdőértéktől számol felfelé $FF-ig
;-----------------------
; Flag-ek billegésének periódusideje = pozitív élek közötti idő
;------------------------------------
; Timer0 megszakítások közötti idő: 0,5 ms
;------------------------------------
;1msec bit billegetése:
	lds r16, TFlags		; TFlags beolvasása a RAM-ból (órajel biteket tároló)
		;---
		;regiszterben bit invertálása:
			set
		sbrc r16,T_1ms		; T_1ms Flag beolvasása T-be
			clt
		bld r16,T_1ms		; T_1ms Flag mentése (invertált)
		;---
	sts TFlags, r16
	;		____		  ________          ________          ________                            
	;			|________|        |________|	    |________|        |____
	;                           1msec                                               
	;			         |<--------------->|                                           
	;
;1ms billegés
TtoPort PortB,B1		;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;--------------------------------------------------------------------
;*sei
	pop ZH
	pop ZL
	pop r17
	pop r16			; SREG kiolvasás a stack-ból
	out SREG,r16		; SREG visszaállítása
	pop r16			; r16 reg visszaállítása

reti 				;Return from interrupt
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
TIMER2_OVF:			; Timer2 lefutott, =>0 OVF miatt ide ugrik	|||
	;Kapuidő számláló: [Prescaler2 + Timer2 + 1B sw számláló]:
	push r16
	in r16, SREG
	push R16
	;---
	;TCCR2, Kapuidő számláló Timer2 leállítása: Prescaler2 Órajel 0-ra állításával:
		;in r16, TCCR2
		ldi r16,0	;T2Clk_STOP 	; TCCR2 bitek: [CS22, CS21, CS20]:=0
		out TCCR2, r16			; Timer2 órajel leállítva (és minden más bit =0)
set
 TtoPort PortB, B2	; LED villogtatása					<<<<<<<<<<<<<<<<<<<<<<<<<<<
;--- Teszt
		lds r16, KapuIdoSz		; sw számláló, MSB (Timer2 OVF lépteti)
		dec r16					; léptetés le
		sts KapuIdoSz, r16 		; mentés
		brne NemTeltLe
			;idő letelt
			ldi r16, 5;100		; sw Sz (MSB) újratöltése -> kezdő érték
			sts KapuIdoSz, r16	; mentés
		NemTeltLe:
;szkóp miatt késl. hurok:
WaitCiklus 100	;20	; [XL:XH], intr futásidő növelése: 1000 -> 0,23ms

clt
 TtoPort PortB, B2	; LED villogtatása					<<<<<<<<<<<<<<<<<<<<<<<<<<<
;--- Teszt
	;TCCR2, Timer2 órajel kiválasztása és Timer2 léptetés indítása:
		ldi r16, T2Clk_1024	; T2Clk_Start:= T2Clk_1024,	Prescaler osztó beállítása, Clk indítása,
								; minden más bit =0
		out TCCR2, r16			; kapuidő elindítva
;*sei
	;---
	pop r16
	out SREG,r16
	pop r16
reti
;------------------------------------------------------------------------------
; *****************************************************************************


;------------------------------------------------------------------------------
;				*** Főprogram inicializálás,  kezdeti feltételek ***
;------------------------------------------------------------------------------
;								||||||||||||
;------------------------------------------------------------------------------
Start:					; bekapcsolás, reset után ide ugrik
;==============================================================================
	cli			; minden megszakítás tiltott
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
; Stack teteje beállítása (FONTOS! -> .DSEG adatok, sub működések sérülnek!!!)
	ldi r16,low(StackTop)
	out SPL,r16
	ldi r16,high(StackTop)
	out SPH,r16
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Timer0 üzemmód, TCNT0  (ATmega8535, ATmega8)		||||
;TCNT0, Timer0 kezdeti érték betöltése --> SysClock hw számlálója:
		ldi r17, Tim0Oszt	; 0-tól 'Tim0_Oszt'-ig számolt órajelek
		neg	r17				; 2'komplemenstől túlcsordulásig számol az OVF miatt
		out TCNT0, r17		; betöltés Timer0-ba
;TCCR0, Timer0 üzemmód kiválasztás: Prescaler, Clk forrás
	ldi	r16, Prescaler		; prescaler clk source select, minden más bit=0
	out	TCCR0, r16			;control reg: Clk forrás:=Clk/64, PWM=tiltott	 
;*SFIOR, Prescaler10 reset tiltása: 																; közös!!!
	in r16, SFIOR			;
	;ldi r16, (0<<PSR10)	; PSR10=B0 bit:=0, Prescaler reset nincs
	andi r16,0b1111_1110
	out SFIOR, r16			;
;*TIMSK, Timer interrupt mask reg									; közös!!!
	in r16, TIMSK
	;ldi r16, (1<<TOIE0)	; TOIE0 =B0, bit =1 -> Túlcsordulásról megszak enged
	ori r16,0b0000_0001
	out	TIMSK, r16 			; Timer Interrupt Mask Register
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;Timer2 üzemmód, TCNT2
	;Timer2 órajel kiválasztása:
	;TCCR2	 (CS22,CS21,CS20), Prescaler2 mux kiválasztó kódok:
	.equ T2Clk_1024 =7	; Clk_io/1024  -> Timer2
	;-------------------------------------------
	;TCCR2, Timer2 órajel kiválasztása és Timer2 léptetés indítása:
		ldi r16, T2Clk_1024	; Prescaler beállítása, Clk indítása, minden más bit =0
		out TCCR2, r16			; kapuidő elindítva
	;Timer2 sw számláló bájt kezdeti értéke (lefelé számol):
		ldi r16, 20			; 1sec: 57
		sts KapuIdoSz,r16
	;TIMSK, TOIE2: TCNT2 OVF Enable
		in r16, TIMSK
		ldi r16, (1<<TOIE2)	; TOIE2 = B6, bit=1 -> TCNT2-ről OVF megszakítás engedélyezése
		;ori r16, 0b0100_0000	; TOIE2 = B6, bit:=1 -> TCNT2-ről OVF megszakítás engedélyezése
		;andi r16,0b1011_1111	; TOIE2 = B6, bit:=0 -> TCNT2-ről OVF megszakítás tiltása
	out TIMSK, r16
;------------------------------------------------------------------------------
;------------------------------------------------------------------------------
;PORTB kezdeti állapot:
	ldi r16,0b0000_0111		; B2, B1, B0: :=1 -> kimenetek, a többi bemenet
	out DDRB,r16
	ldi r16,0b0011_1000		; portbitek alapállapota
	out PORTB,r16			;
;------------------------------------------------------------------------------
	sei			; minden megszakítás engedélyezése
;==============================================================================


;==============================================================================
;						*** Ciklikus főprogram eleje ***
;------------------------------------------------------------------------------
FoprgCik:
nop
nop
nop
nop
nop
rjmp FoprgCik
;==============================================================================
