Source file: /~heha/enas/STS Multiplex/firmware.zip/startup.S

#define __SFR_OFFSET 0
#include <avr/io.h>
.section .vectors						// Kode für die Adresse 0
.global main,__vector_25,__vector_26,__vector_28,__vector_29	// Sprungziele im C++-Programm
.global DioReport						// Daten im C++-Programm
.global __data_load_start,__data_start,__bss_start,__bss_end	// Linker-Symbole
reset:				;Marke nur für hübscheres Listing
// Viele Interrupts werden nicht benötigt, daher Initialisierunskode
// in der Interrupttabelle anordnen (lassen)
// Die sonst üblichen Dummy-Interruptvektoren sind nur etwas für Angsthasen.
	clr	r1		;Stapelzeigerregister ist beim ATmega16U4 bereits initialisiert
	ldi	r17,hi8(__bss_start)
	ldi	XL,lo8(__data_start)	// Adresse im RAM (ATmega16U4: 0x100)
	ldi	XH,hi8(__data_start)
 	ldi	ZL,lo8(__data_load_start)	// Adresse im Flash (hinter dem Kode)
	ldi	ZH,hi8(__data_load_start)
 	rjmp	2f
1:	lpm	r0,Z+			// von Flash in RAM kopieren
	st	X+, r0
2:	cpi	XL,lo8(__bss_start)	// Annahme: __bss_start == __data_end
	cpc	XH,r17
	brne	1b
 	ldi	r17,hi8(__bss_end)
	rjmp	2f
1:	st	X+,r1			// statische, nicht-vorinitialisierte Daten löschen
2:	cpi	XL,lo8(__bss_end)
	cpc	XH,r17
	brne	1b
	rjmp	main		;JMP benutzen wenn main hinter der 8-KByte-Grenze liegt
.org 0x28	// USB-Interrupts nur zum Aufwecken
	reti			;USB allgemein
.org 0x2C
	reti			;USB Endpoint
__vector_28:	// ISR für Analogvergleicher: Schnellabschaltung der Digitalausgänge bei Überstrom
	push	r0
	in	r0,SREG
	push	r16
	 in	r16,PORTB
	 andi	r16,0xE0
	 out	PORTB,r16	;PORTB&=0xE0
	 in	r16,PORTD
	 andi	r16,0xEC
	 out	PORTD,r16	;PORTD&=0xEC
	 clr	r16
	 sts	DioReport+1,r16	;DioReport.DigitalOut=0
	pop	r16
	out	SREG,r0
	pop	r0
	reti
.org 0x64	// USART-Interrupts benötigen Behandlung: Leider kein „sei“ am Anfang möglich
	rjmp	__vector_25	;USART1-Datenempfang
.org 0x66
	rjmp	__vector_26	;USART1-Senderegister leer
.org 0x70	// Diese zwei Interrupts mit sofortiger Interruptfreigabe
	sei			;Analogvergleicher
	rjmp	__vector_28
	sei			;A/D-Wandler
	rjmp	__vector_29
.org 0x84	// Diese drei Interrupts direkt und ohne Interruptfreigabe: Software-PWM
	sbi	PORTE,2		;Timer3 CompareB
	reti
	sbi	PORTD,4		;Timer3 CompareC
	reti
	sbic	GPIOR0,6	;Timer3 Überlauf
	 cbi	PORTE,2
	sbic	GPIOR0,7
	 cbi	PORTD,4
	reti
Detected encoding: UTF-80