1 |
/* Copyright (c) 2002, Marek Michalkiewicz <marekm@amelek.gda.pl> |
2 |
All rights reserved. |
3 |
|
4 |
Redistribution and use in source and binary forms, with or without |
5 |
modification, are permitted provided that the following conditions are met: |
6 |
|
7 |
* Redistributions of source code must retain the above copyright |
8 |
notice, this list of conditions and the following disclaimer. |
9 |
* Redistributions in binary form must reproduce the above copyright |
10 |
notice, this list of conditions and the following disclaimer in |
11 |
the documentation and/or other materials provided with the |
12 |
distribution. |
13 |
|
14 |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
15 |
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
16 |
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
17 |
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
18 |
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
19 |
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
20 |
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
21 |
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
22 |
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
23 |
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
24 |
POSSIBILITY OF SUCH DAMAGE. */ |
25 |
|
26 |
#if (__GNUC__ < 3) || (__GNUC__ == 3 && __GNUC_MINOR__ < 3) |
27 |
#error "GCC version >= 3.3 required" |
28 |
#endif |
29 |
|
30 |
#include "macros.inc" |
31 |
|
32 |
.macro vector name |
33 |
.if (. - __vectors < _VECTORS_SIZE) |
34 |
.weak \name |
35 |
.set \name, __bad_interrupt |
36 |
XJMP \name |
37 |
.endif |
38 |
.endm |
39 |
|
40 |
.section .vectors,"ax",@progbits |
41 |
.global __vectors |
42 |
.func __vectors |
43 |
__vectors: |
44 |
XJMP __init |
45 |
vector __vector_1 |
46 |
vector __vector_2 |
47 |
vector __vector_3 |
48 |
vector __vector_4 |
49 |
vector __vector_5 |
50 |
vector __vector_6 |
51 |
vector __vector_7 |
52 |
vector __vector_8 |
53 |
vector __vector_9 |
54 |
vector __vector_10 |
55 |
vector __vector_11 |
56 |
vector __vector_12 |
57 |
vector __vector_13 |
58 |
vector __vector_14 |
59 |
vector __vector_15 |
60 |
vector __vector_16 |
61 |
vector __vector_17 |
62 |
vector __vector_18 |
63 |
vector __vector_19 |
64 |
vector __vector_20 |
65 |
vector __vector_21 |
66 |
vector __vector_22 |
67 |
vector __vector_23 |
68 |
vector __vector_24 |
69 |
vector __vector_25 |
70 |
vector __vector_26 |
71 |
vector __vector_27 |
72 |
vector __vector_28 |
73 |
vector __vector_29 |
74 |
vector __vector_30 |
75 |
vector __vector_31 |
76 |
vector __vector_32 |
77 |
vector __vector_33 |
78 |
vector __vector_34 |
79 |
vector __vector_35 |
80 |
vector __vector_36 |
81 |
vector __vector_37 |
82 |
vector __vector_38 |
83 |
vector __vector_39 |
84 |
.endfunc |
85 |
|
86 |
/* Handle unexpected interrupts (enabled and no handler), which |
87 |
usually indicate a bug. Jump to the __vector_default function |
88 |
if defined by the user, otherwise jump to the reset address. |
89 |
|
90 |
This must be in a different section, otherwise the assembler |
91 |
will resolve "rjmp" offsets and there will be no relocs. */ |
92 |
|
93 |
.text |
94 |
.global __bad_interrupt |
95 |
.func __bad_interrupt |
96 |
__bad_interrupt: |
97 |
.weak __vector_default |
98 |
.set __vector_default, __vectors |
99 |
XJMP __vector_default |
100 |
.endfunc |
101 |
|
102 |
.section .init0,"ax",@progbits |
103 |
.weak __init |
104 |
; .func __init |
105 |
__init: |
106 |
|
107 |
#ifndef __AVR_ASM_ONLY__ |
108 |
.weak __stack |
109 |
.set __stack, RAMEND |
110 |
|
111 |
/* By default, malloc() uses the current value of the stack pointer |
112 |
minus __malloc_margin as the highest available address. |
113 |
|
114 |
In some applications with external SRAM, the stack can be below |
115 |
the data section (in the internal SRAM - faster), and __heap_end |
116 |
should be set to the highest address available for malloc(). */ |
117 |
.weak __heap_end |
118 |
.set __heap_end, 0 |
119 |
|
120 |
.section .init2,"ax",@progbits |
121 |
clr __zero_reg__ |
122 |
out _SFR_IO_ADDR(SREG), __zero_reg__ |
123 |
ldi r28,lo8(__stack) |
124 |
#ifdef SPH |
125 |
ldi r29,hi8(__stack) |
126 |
out _SFR_IO_ADDR(SPH), r29 |
127 |
#endif |
128 |
out _SFR_IO_ADDR(SPL), r28 |
129 |
|
130 |
#if BIG_CODE |
131 |
/* Only for >64K devices with RAMPZ, replaces the default code |
132 |
provided by libgcc.S which is only linked in if necessary. */ |
133 |
|
134 |
.section .init4,"ax",@progbits |
135 |
.global __do_copy_data |
136 |
__do_copy_data: |
137 |
ldi r17, hi8(__data_end) |
138 |
ldi r26, lo8(__data_start) |
139 |
ldi r27, hi8(__data_start) |
140 |
ldi r30, lo8(__data_load_start) |
141 |
ldi r31, hi8(__data_load_start) |
142 |
|
143 |
/* On the enhanced core, "elpm" with post-increment updates RAMPZ |
144 |
automatically. Otherwise we have to handle it ourselves. */ |
145 |
|
146 |
#ifdef __AVR_ENHANCED__ |
147 |
ldi r16, hh8(__data_load_start) |
148 |
#else |
149 |
ldi r16, hh8(__data_load_start - 0x10000) |
150 |
.__do_copy_data_carry: |
151 |
inc r16 |
152 |
#endif |
153 |
out _SFR_IO_ADDR(RAMPZ), r16 |
154 |
rjmp .__do_copy_data_start |
155 |
.__do_copy_data_loop: |
156 |
#ifdef __AVR_ENHANCED__ |
157 |
elpm r0, Z+ |
158 |
#else |
159 |
lpm |
160 |
#endif |
161 |
st X+, r0 |
162 |
#ifndef __AVR_ENHANCED__ |
163 |
adiw r30, 1 |
164 |
brcs .__do_copy_data_carry |
165 |
#endif |
166 |
.__do_copy_data_start: |
167 |
cpi r26, lo8(__data_end) |
168 |
cpc r27, r17 |
169 |
brne .__do_copy_data_loop |
170 |
#endif /* BIG_CODE */ |
171 |
|
172 |
#endif /* !__AVR_ASM_ONLY__ */ |
173 |
|
174 |
.section .init9,"ax",@progbits |
175 |
XJMP main |
176 |
; .endfunc |
177 |
|