blob: 188da29eaae6309cce55a46a7fd9f379480aabcb [file] [log] [blame]
adamdunkels4fa940f2003-04-11 20:30:14 +00001/*
2 * Copyright (c) 2001, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
adamdunkels503df8d2004-07-04 20:01:15 +000013 * 3. The name of the author may not be used to endorse or promote
adamdunkels4fa940f2003-04-11 20:30:14 +000014 * products derived from this software without specific prior
15 * written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
26 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * This file is part of the uIP TCP/IP stack.
30 *
oliverschmidt14be9d22005-01-26 23:36:37 +000031 * $Id: uip_arch.c,v 1.4 2005/01/26 23:36:37 oliverschmidt Exp $
adamdunkels4fa940f2003-04-11 20:30:14 +000032 *
33 */
34
35
36#include "uip.h"
37#include "uip_arch.h"
38
39#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
40#define IP_PROTO_TCP 6
41
42/*-----------------------------------------------------------------------------------*/
oliverschmidta5b57db2004-07-18 13:23:28 +000043#pragma optimize(push, off)
adamdunkels4fa940f2003-04-11 20:30:14 +000044void
45uip_add32(u8_t *op32, u16_t op16)
46{
47 asm("ldy #3");
48 asm("jsr ldaxysp");
49 asm("sta ptr1");
50 asm("stx ptr1+1");
51 asm("ldy #0");
52 asm("lda (sp),y");
53 asm("ldy #3");
54 asm("clc");
55 asm("adc (ptr1),y");
56 asm("sta _uip_acc32+3");
57 asm("dey");
58 asm("lda (ptr1),y");
59 asm("ldy #1");
60 asm("adc (sp),y");
61 asm("sta _uip_acc32+2");
62 asm("ldy #1");
63 asm("lda (ptr1),y");
64 asm("adc #0");
65 asm("sta _uip_acc32+1");
66 asm("dey");
67 asm("lda (ptr1),y");
68 asm("adc #0");
69 asm("sta _uip_acc32+0");
70}
oliverschmidta5b57db2004-07-18 13:23:28 +000071#pragma optimize(pop)
adamdunkels4fa940f2003-04-11 20:30:14 +000072/*-----------------------------------------------------------------------------------*/
adamdunkels4fa940f2003-04-11 20:30:14 +000073static u16_t chksum_ptr, chksum_len, chksum_tmp;
74static u16_t chksum(void);
75/*-----------------------------------------------------------------------------------*/
oliverschmidta5b57db2004-07-18 13:23:28 +000076#pragma optimize(push, off)
adamdunkels4fa940f2003-04-11 20:30:14 +000077u16_t
78chksum(void) {
79
80 asm("lda #0");
81 asm("sta tmp1");
82 asm("sta tmp1+1");
83 asm("lda _chksum_ptr");
84 asm("sta ptr1");
85 asm("lda _chksum_ptr+1");
86 asm("sta ptr1+1");
87
88
89 asm("lda _chksum_len+1");
90 asm("beq chksumlast");
91
92
93 /* If checksum is > 256, do the first runs. */
94 asm("ldy #0");
95 asm("clc");
96 asm("chksumloop_256:");
97 asm("lda (ptr1),y");
98 asm("adc tmp1");
99 asm("sta tmp1");
100 asm("iny");
101 asm("lda (ptr1),y");
102 asm("adc tmp1+1");
103 asm("sta tmp1+1");
104 asm("iny");
105 asm("bne chksumloop_256");
106 asm("inc ptr1+1");
107 asm("dec _chksum_len+1");
108 asm("bne chksumloop_256");
109
110 asm("chksum_endloop_256:");
111 asm("lda tmp1");
112 asm("adc #0");
113 asm("sta tmp1");
114 asm("lda tmp1+1");
115 asm("adc #0");
116 asm("sta tmp1+1");
117 asm("bcs chksum_endloop_256");
118
119 asm("chksumlast:");
120 asm("lda _chksum_len");
121 asm("lsr");
122 asm("bcc chksum_noodd");
123 asm("ldy _chksum_len");
124 asm("dey");
125 asm("lda (ptr1),y");
126 asm("clc");
127 asm("adc tmp1");
128 asm("sta tmp1");
129 asm("bcc noinc1");
130 asm("inc tmp1+1");
131 asm("bne noinc1");
132 asm("inc tmp1");
133 asm("noinc1:");
134 asm("dec _chksum_len");
135
136 asm("chksum_noodd:");
137 asm("clc");
138 asm("php");
139 asm("ldy _chksum_len");
140 asm("chksum_loop1:");
141 asm("cpy #0");
142 asm("beq chksum_loop1_end");
143 asm("plp");
144 asm("dey");
145 asm("dey");
146 asm("lda (ptr1),y");
147 asm("adc tmp1");
148 asm("sta tmp1");
149 asm("iny");
150 asm("lda (ptr1),y");
151 asm("adc tmp1+1");
152 asm("sta tmp1+1");
153 asm("dey");
154 asm("php");
155 asm("jmp chksum_loop1");
156 asm("chksum_loop1_end:");
157 asm("plp");
158
159 asm("chksum_endloop:");
160 asm("lda tmp1");
161 asm("adc #0");
162 asm("sta tmp1");
163 asm("lda tmp1+1");
164 asm("adc #0");
165 asm("sta tmp1+1");
166 asm("bcs chksum_endloop");
167
168 asm("lda tmp1");
169 asm("ldx tmp1+1");
170}
oliverschmidta5b57db2004-07-18 13:23:28 +0000171#pragma optimize(pop)
adamdunkels4fa940f2003-04-11 20:30:14 +0000172/*-----------------------------------------------------------------------------------*/
173u16_t
174uip_chksum(u16_t *buf, u16_t len)
175{
176 /* unsigned long sum;
177
178 sum = 0;
179
180 chksum_ptr = (u16_t)buf;
181 while(len >= 256) {
182 chksum_len = 256;
183 sum += chksum();
184 len -= 256;
185 chksum_ptr += 256;
186 }
187
188 if(len < 256) {
189 chksum_len = len;
190 sum += chksum();
191 }
192
193 while((sum >> 16) != 0) {
194 sum = (sum >> 16) + (sum & 0xffff);
195 }
196
197 return sum;*/
198
199 chksum_len = len;
200 chksum_ptr = (u16_t)buf;
201 return chksum();
202}
203/*-----------------------------------------------------------------------------------*/
204u16_t
205uip_ipchksum(void)
206{
207 chksum_ptr = (u16_t)uip_buf + UIP_LLH_LEN;
208 chksum_len = 20;
209 return chksum();
210}
211/*-----------------------------------------------------------------------------------*/
oliverschmidta5b57db2004-07-18 13:23:28 +0000212#pragma optimize(push, off)
adamdunkels4fa940f2003-04-11 20:30:14 +0000213u16_t
214uip_tcpchksum(void)
215{
216 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
217 chksum_len = 20;
218 chksum_tmp = chksum();
219
220 chksum_ptr = (u16_t)uip_appdata;
221#ifdef WITH_TFE
222 asm("lda _uip_buf+3+14");
223#else /* WITH_TFE */
224 asm("lda _uip_buf+3");
225#endif /* WITH_TFE */
226 asm("sec");
227 asm("sbc #40");
228 asm("sta _chksum_len");
229#ifdef WITH_TFE
230 asm("lda _uip_buf+2+14");
231#else /* WITH_TFE */
232 asm("lda _uip_buf+2");
233#endif /* WITH_TFE */
234 asm("sbc #0");
235 asm("sta _chksum_len+1");
236
237 asm("jsr %v", chksum);
238
239 asm("clc");
240 asm("adc _chksum_tmp");
241 asm("sta _chksum_tmp");
242 asm("txa");
243 asm("adc _chksum_tmp+1");
244 asm("sta _chksum_tmp+1");
245
246 /* Fold carry */
247 /* asm("bcc noinc");
248 asm("inc _chksum_tmp");
249 asm("noinc:");*/
250
251 asm("tcpchksum_loop1:");
252 asm("lda _chksum_tmp");
253 asm("adc #0");
254 asm("sta _chksum_tmp");
255 asm("lda _chksum_tmp+1");
256 asm("adc #0");
257 asm("sta _chksum_tmp+1");
258 asm("bcs tcpchksum_loop1");
259
260
261#ifdef WITH_TFE
262 asm("lda _uip_buf+3+14");
263#else /* WITH_TFE */
264 asm("lda _uip_buf+3");
265#endif /* WITH_TFE */
266 asm("sec");
267 asm("sbc #20");
268 asm("sta _chksum_len");
269#ifdef WITH_TFE
270 asm("lda _uip_buf+2+14");
271#else /* WITH_TFE */
272 asm("lda _uip_buf+2");
273#endif /* WITH_TFE */
274 asm("sbc #0");
275 asm("sta _chksum_len+1");
276
277
278 asm("ldy #$0c");
279 asm("clc");
280 asm("php");
281 asm("tcpchksum_loop2:");
282 asm("plp");
283#ifdef WITH_TFE
284 asm("lda _uip_buf+14,y");
285#else /* WITH_TFE */
286 asm("lda _uip_buf,y");
287#endif /* WITH_TFE */
288 asm("adc _chksum_tmp");
289 asm("sta _chksum_tmp");
290 asm("iny");
291#ifdef WITH_TFE
292 asm("lda _uip_buf+14,y");
293#else /* WITH_TFE */
294 asm("lda _uip_buf,y");
295#endif /* WITH_TFE */
296 asm("adc _chksum_tmp+1");
297 asm("sta _chksum_tmp+1");
298 asm("iny");
299 asm("php");
300 asm("cpy #$14");
301 asm("bne tcpchksum_loop2");
302
303 asm("plp");
304
305 asm("lda _chksum_tmp");
306 asm("adc #0");
307 asm("sta _chksum_tmp");
308 asm("lda _chksum_tmp+1");
309 asm("adc #6"); /* IP_PROTO_TCP */
310 asm("sta _chksum_tmp+1");
311
312
313 asm("lda _chksum_tmp");
314 asm("adc _chksum_len+1");
315 asm("sta _chksum_tmp");
316 asm("lda _chksum_tmp+1");
317 asm("adc _chksum_len");
318 asm("sta _chksum_tmp+1");
319
320
321
322 asm("tcpchksum_loop3:");
323 asm("lda _chksum_tmp");
324 asm("adc #0");
325 asm("sta _chksum_tmp");
326 asm("lda _chksum_tmp+1");
327 asm("adc #0");
328 asm("sta _chksum_tmp+1");
329 asm("bcs tcpchksum_loop3");
330
331
332 return chksum_tmp;
333}
oliverschmidta5b57db2004-07-18 13:23:28 +0000334#pragma optimize(pop)
adamdunkels4fa940f2003-04-11 20:30:14 +0000335/*-----------------------------------------------------------------------------------*/