blob: 57ca78532d658a6f8b9bb0ef5c8e24b8c91a7e4c [file] [log] [blame]
sannyxaf36c702003-04-12 00:30:57 +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.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Adam Dunkels.
16 * 4. The name of the author may not be used to endorse or promote
17 * products derived from this software without specific prior
18 * written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
26 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 * This file is part of the uIP TCP/IP stack.
33 *
oliverschmidt3a25f292005-02-24 22:03:15 +000034 * $Id: uip_arch.c,v 1.4 2005/02/24 22:03:15 oliverschmidt Exp $
sannyxaf36c702003-04-12 00:30:57 +000035 *
36 */
37
38
39#include "uip.h"
40#include "uip_arch.h"
41
42#define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
43#define IP_PROTO_TCP 6
44
45/*-----------------------------------------------------------------------------------*/
oliverschmidt8d5a1162004-07-18 13:18:58 +000046#pragma optimize(push, off)
sannyxaf36c702003-04-12 00:30:57 +000047void
48uip_add32(u8_t *op32, u16_t op16)
49{
50 asm("ldy #3");
51 asm("jsr ldaxysp");
52 asm("sta ptr1");
53 asm("stx ptr1+1");
54 asm("ldy #0");
55 asm("lda (sp),y");
56 asm("ldy #3");
57 asm("clc");
58 asm("adc (ptr1),y");
59 asm("sta _uip_acc32+3");
60 asm("dey");
61 asm("lda (ptr1),y");
62 asm("ldy #1");
63 asm("adc (sp),y");
64 asm("sta _uip_acc32+2");
65 asm("ldy #1");
66 asm("lda (ptr1),y");
67 asm("adc #0");
68 asm("sta _uip_acc32+1");
69 asm("dey");
70 asm("lda (ptr1),y");
71 asm("adc #0");
72 asm("sta _uip_acc32+0");
73}
oliverschmidt8d5a1162004-07-18 13:18:58 +000074#pragma optimize(pop)
sannyxaf36c702003-04-12 00:30:57 +000075/*-----------------------------------------------------------------------------------*/
76void
77uip_add_rcv_nxt(u16_t n) {
78 uip_add32(uip_conn->rcv_nxt, n);
79 uip_conn->rcv_nxt[0] = uip_acc32[0];
80 uip_conn->rcv_nxt[1] = uip_acc32[1];
81 uip_conn->rcv_nxt[2] = uip_acc32[2];
82 uip_conn->rcv_nxt[3] = uip_acc32[3];
83 /* asm("pha");
84 asm("lda _uip_conn");
85 asm("sta ptr1");
86 asm("lda _uip_conn+1");
87 asm("sta ptr1+1");
88 asm("pla");
89 asm("clc");
90 asm("ldy #3");
91 asm("adc (ptr1),y");
92 asm("sta (ptr1),y");
93 asm("dey");
94 asm("txa");
95 asm("adc (ptr1),y");
96 asm("sta (ptr1),y");
97 asm("dey");
98 asm("lda #0");
99 asm("adc (ptr1),y");
100 asm("sta (ptr1),y");
101 asm("dey");
102 asm("lda #0");
103 asm("adc (ptr1),y");
104 asm("sta (ptr1),y");
105
106 n=n;*/
107}
108/*-----------------------------------------------------------------------------------*/
sannyxaf36c702003-04-12 00:30:57 +0000109static u16_t chksum_ptr, chksum_len, chksum_tmp;
110static u16_t chksum(void);
111/*-----------------------------------------------------------------------------------*/
oliverschmidt8d5a1162004-07-18 13:18:58 +0000112#pragma optimize(push, off)
sannyxaf36c702003-04-12 00:30:57 +0000113u16_t
114chksum(void) {
115
116 asm("lda #0");
117 asm("sta tmp1");
118 asm("sta tmp1+1");
119 asm("lda _chksum_ptr");
120 asm("sta ptr1");
121 asm("lda _chksum_ptr+1");
122 asm("sta ptr1+1");
123
124
125 asm("lda _chksum_len+1");
126 asm("beq chksumlast");
127
128
129 /* If checksum is > 256, do the first runs. */
130 asm("ldy #0");
131 asm("clc");
132 asm("chksumloop_256:");
133 asm("lda (ptr1),y");
134 asm("adc tmp1");
135 asm("sta tmp1");
136 asm("iny");
137 asm("lda (ptr1),y");
138 asm("adc tmp1+1");
139 asm("sta tmp1+1");
140 asm("iny");
141 asm("bne chksumloop_256");
142 asm("inc ptr1+1");
143 asm("dec _chksum_len+1");
144 asm("bne chksumloop_256");
145
146 asm("chksum_endloop_256:");
147 asm("lda tmp1");
148 asm("adc #0");
149 asm("sta tmp1");
150 asm("lda tmp1+1");
151 asm("adc #0");
152 asm("sta tmp1+1");
153 asm("bcs chksum_endloop_256");
154
155 asm("chksumlast:");
156 asm("lda _chksum_len");
157 asm("lsr");
158 asm("bcc chksum_noodd");
159 asm("ldy _chksum_len");
160 asm("dey");
161 asm("lda (ptr1),y");
162 asm("clc");
163 asm("adc tmp1");
164 asm("sta tmp1");
165 asm("bcc noinc1");
166 asm("inc tmp1+1");
167 asm("bne noinc1");
168 asm("inc tmp1");
169 asm("noinc1:");
170 asm("dec _chksum_len");
171
172 asm("chksum_noodd:");
173 asm("clc");
174 asm("php");
175 asm("ldy _chksum_len");
176 asm("chksum_loop1:");
177 asm("cpy #0");
178 asm("beq chksum_loop1_end");
179 asm("plp");
180 asm("dey");
181 asm("dey");
182 asm("lda (ptr1),y");
183 asm("adc tmp1");
184 asm("sta tmp1");
185 asm("iny");
186 asm("lda (ptr1),y");
187 asm("adc tmp1+1");
188 asm("sta tmp1+1");
189 asm("dey");
190 asm("php");
191 asm("jmp chksum_loop1");
192 asm("chksum_loop1_end:");
193 asm("plp");
194
195 asm("chksum_endloop:");
196 asm("lda tmp1");
197 asm("adc #0");
198 asm("sta tmp1");
199 asm("lda tmp1+1");
200 asm("adc #0");
201 asm("sta tmp1+1");
202 asm("bcs chksum_endloop");
203
204 asm("lda tmp1");
205 asm("ldx tmp1+1");
206}
oliverschmidt8d5a1162004-07-18 13:18:58 +0000207#pragma optimize(pop)
sannyxaf36c702003-04-12 00:30:57 +0000208/*-----------------------------------------------------------------------------------*/
209u16_t
210uip_chksum(u16_t *buf, u16_t len)
211{
212 /* unsigned long sum;
213
214 sum = 0;
215
216 chksum_ptr = (u16_t)buf;
217 while(len >= 256) {
218 chksum_len = 256;
219 sum += chksum();
220 len -= 256;
221 chksum_ptr += 256;
222 }
223
224 if(len < 256) {
225 chksum_len = len;
226 sum += chksum();
227 }
228
229 while((sum >> 16) != 0) {
230 sum = (sum >> 16) + (sum & 0xffff);
231 }
232
233 return sum;*/
234
235 chksum_len = len;
236 chksum_ptr = (u16_t)buf;
237 return chksum();
238}
239/*-----------------------------------------------------------------------------------*/
240u16_t
241uip_ipchksum(void)
242{
243 chksum_ptr = (u16_t)uip_buf + UIP_LLH_LEN;
oliverschmidt3a25f292005-02-24 22:03:15 +0000244 chksum_len = UIP_IPH_LEN;
sannyxaf36c702003-04-12 00:30:57 +0000245 return chksum();
246}
247/*-----------------------------------------------------------------------------------*/
oliverschmidt8d5a1162004-07-18 13:18:58 +0000248#pragma optimize(push, off)
sannyxaf36c702003-04-12 00:30:57 +0000249u16_t
250uip_tcpchksum(void)
251{
252 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
253 chksum_len = 20;
254 chksum_tmp = chksum();
255
256 chksum_ptr = (u16_t)uip_appdata;
257#ifdef WITH_TFE
258 asm("lda _uip_buf+3+14");
259#else /* WITH_TFE */
260 asm("lda _uip_buf+3");
261#endif /* WITH_TFE */
262 asm("sec");
263 asm("sbc #40");
264 asm("sta _chksum_len");
265#ifdef WITH_TFE
266 asm("lda _uip_buf+2+14");
267#else /* WITH_TFE */
268 asm("lda _uip_buf+2");
269#endif /* WITH_TFE */
270 asm("sbc #0");
271 asm("sta _chksum_len+1");
272
273 asm("jsr %v", chksum);
274
275 asm("clc");
276 asm("adc _chksum_tmp");
277 asm("sta _chksum_tmp");
278 asm("txa");
279 asm("adc _chksum_tmp+1");
280 asm("sta _chksum_tmp+1");
281
282 /* Fold carry */
283 /* asm("bcc noinc");
284 asm("inc _chksum_tmp");
285 asm("noinc:");*/
286
287 asm("tcpchksum_loop1:");
288 asm("lda _chksum_tmp");
289 asm("adc #0");
290 asm("sta _chksum_tmp");
291 asm("lda _chksum_tmp+1");
292 asm("adc #0");
293 asm("sta _chksum_tmp+1");
294 asm("bcs tcpchksum_loop1");
295
296
297#ifdef WITH_TFE
298 asm("lda _uip_buf+3+14");
299#else /* WITH_TFE */
300 asm("lda _uip_buf+3");
301#endif /* WITH_TFE */
302 asm("sec");
303 asm("sbc #20");
304 asm("sta _chksum_len");
305#ifdef WITH_TFE
306 asm("lda _uip_buf+2+14");
307#else /* WITH_TFE */
308 asm("lda _uip_buf+2");
309#endif /* WITH_TFE */
310 asm("sbc #0");
311 asm("sta _chksum_len+1");
312
313
314 asm("ldy #$0c");
315 asm("clc");
316 asm("php");
317 asm("tcpchksum_loop2:");
318 asm("plp");
319#ifdef WITH_TFE
320 asm("lda _uip_buf+14,y");
321#else /* WITH_TFE */
322 asm("lda _uip_buf,y");
323#endif /* WITH_TFE */
324 asm("adc _chksum_tmp");
325 asm("sta _chksum_tmp");
326 asm("iny");
327#ifdef WITH_TFE
328 asm("lda _uip_buf+14,y");
329#else /* WITH_TFE */
330 asm("lda _uip_buf,y");
331#endif /* WITH_TFE */
332 asm("adc _chksum_tmp+1");
333 asm("sta _chksum_tmp+1");
334 asm("iny");
335 asm("php");
336 asm("cpy #$14");
337 asm("bne tcpchksum_loop2");
338
339 asm("plp");
340
341 asm("lda _chksum_tmp");
342 asm("adc #0");
343 asm("sta _chksum_tmp");
344 asm("lda _chksum_tmp+1");
345 asm("adc #6"); /* IP_PROTO_TCP */
346 asm("sta _chksum_tmp+1");
347
348
349 asm("lda _chksum_tmp");
350 asm("adc _chksum_len+1");
351 asm("sta _chksum_tmp");
352 asm("lda _chksum_tmp+1");
353 asm("adc _chksum_len");
354 asm("sta _chksum_tmp+1");
355
356
357
358 asm("tcpchksum_loop3:");
359 asm("lda _chksum_tmp");
360 asm("adc #0");
361 asm("sta _chksum_tmp");
362 asm("lda _chksum_tmp+1");
363 asm("adc #0");
364 asm("sta _chksum_tmp+1");
365 asm("bcs tcpchksum_loop3");
366
367
368 return chksum_tmp;
369}
oliverschmidt8d5a1162004-07-18 13:18:58 +0000370#pragma optimize(pop)
sannyxaf36c702003-04-12 00:30:57 +0000371/*-----------------------------------------------------------------------------------*/