blob: 5edd6c25200b2cc1a5ea640a8f006865e008a40e [file] [log] [blame]
kthacker6de67752006-04-17 15:02:26 +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. The name of the author may not be used to endorse or promote
14 * 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 *
31 * $Id: uip_arch.c,v 1.1 2006/04/17 15:02:43 kthacker Exp $
32 *
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#define IP_PROTO_UDP 17
42
43/*-----------------------------------------------------------------------------------*/
44/*#pragma optimize(push, off) */
45void
46uip_add32(u8_t *op32, u16_t op16)
47{
48#if 0
49 asm("ldy #3");
50 asm("jsr ldaxysp");
51 asm("sta ptr1");
52 asm("stx ptr1+1");
53 asm("ldy #0");
54 asm("lda (sp),y");
55 asm("ldy #3");
56 asm("clc");
57 asm("adc (ptr1),y");
58 asm("sta _uip_acc32+3");
59 asm("dey");
60 asm("lda (ptr1),y");
61 asm("ldy #1");
62 asm("adc (sp),y");
63 asm("sta _uip_acc32+2");
64 asm("ldy #1");
65 asm("lda (ptr1),y");
66 asm("adc #0");
67 asm("sta _uip_acc32+1");
68 asm("dey");
69 asm("lda (ptr1),y");
70 asm("adc #0");
71 asm("sta _uip_acc32+0");
72#endif
73}
74/*#pragma optimize(pop)*/
75/*-----------------------------------------------------------------------------------*/
76static u16_t chksum_ptr, chksum_len, chksum_tmp;
77static u8_t chksum_protocol;
78static u16_t chksum(void);
79/*-----------------------------------------------------------------------------------*/
80/*#pragma optimize(push, off) */
81u16_t
82chksum(void) {
83
84#if 0
85 asm("lda #0");
86 asm("sta tmp1");
87 asm("sta tmp1+1");
88 asm("lda _chksum_ptr");
89 asm("sta ptr1");
90 asm("lda _chksum_ptr+1");
91 asm("sta ptr1+1");
92
93
94 asm("lda _chksum_len+1");
95 asm("beq chksumlast");
96
97
98 /* If checksum is > 256, do the first runs. */
99 asm("ldy #0");
100 asm("clc");
101 asm("chksumloop_256:");
102 asm("lda (ptr1),y");
103 asm("adc tmp1");
104 asm("sta tmp1");
105 asm("iny");
106 asm("lda (ptr1),y");
107 asm("adc tmp1+1");
108 asm("sta tmp1+1");
109 asm("iny");
110 asm("bne chksumloop_256");
111 asm("inc ptr1+1");
112 asm("dec _chksum_len+1");
113 asm("bne chksumloop_256");
114
115 asm("chksum_endloop_256:");
116 asm("lda tmp1");
117 asm("adc #0");
118 asm("sta tmp1");
119 asm("lda tmp1+1");
120 asm("adc #0");
121 asm("sta tmp1+1");
122 asm("bcs chksum_endloop_256");
123
124 asm("chksumlast:");
125 asm("lda _chksum_len");
126 asm("lsr");
127 asm("bcc chksum_noodd");
128 asm("ldy _chksum_len");
129 asm("dey");
130 asm("lda (ptr1),y");
131 asm("clc");
132 asm("adc tmp1");
133 asm("sta tmp1");
134 asm("bcc noinc1");
135 asm("inc tmp1+1");
136 asm("bne noinc1");
137 asm("inc tmp1");
138 asm("noinc1:");
139 asm("dec _chksum_len");
140
141 asm("chksum_noodd:");
142 asm("clc");
143 asm("php");
144 asm("ldy _chksum_len");
145 asm("chksum_loop1:");
146 asm("cpy #0");
147 asm("beq chksum_loop1_end");
148 asm("plp");
149 asm("dey");
150 asm("dey");
151 asm("lda (ptr1),y");
152 asm("adc tmp1");
153 asm("sta tmp1");
154 asm("iny");
155 asm("lda (ptr1),y");
156 asm("adc tmp1+1");
157 asm("sta tmp1+1");
158 asm("dey");
159 asm("php");
160 asm("jmp chksum_loop1");
161 asm("chksum_loop1_end:");
162 asm("plp");
163
164 asm("chksum_endloop:");
165 asm("lda tmp1");
166 asm("adc #0");
167 asm("sta tmp1");
168 asm("lda tmp1+1");
169 asm("adc #0");
170 asm("sta tmp1+1");
171 asm("bcs chksum_endloop");
172
173 asm("lda tmp1");
174 asm("ldx tmp1+1");
175#endif
176}
177/*#pragma optimize(pop)*/
178/*-----------------------------------------------------------------------------------*/
179u16_t
180uip_chksum(u16_t *buf, u16_t len)
181{
182 /* unsigned long sum;
183
184 sum = 0;
185
186 chksum_ptr = (u16_t)buf;
187 while(len >= 256) {
188 chksum_len = 256;
189 sum += chksum();
190 len -= 256;
191 chksum_ptr += 256;
192 }
193
194 if(len < 256) {
195 chksum_len = len;
196 sum += chksum();
197 }
198
199 while((sum >> 16) != 0) {
200 sum = (sum >> 16) + (sum & 0xffff);
201 }
202
203 return sum;*/
204
205 chksum_len = len;
206 chksum_ptr = (u16_t)buf;
207 return chksum();
208}
209/*-----------------------------------------------------------------------------------*/
210u16_t
211uip_ipchksum(void)
212{
213 chksum_ptr = (u16_t)uip_buf + UIP_LLH_LEN;
214 chksum_len = 20;
215 return chksum();
216}
217/*-----------------------------------------------------------------------------------*/
218/*#pragma optimize(push, off) */
219static u16_t
220transport_chksum(u8_t protocol)
221{
222 chksum_protocol = protocol;
223 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
224 chksum_len = 20;
225 chksum_tmp = chksum();
226
227 chksum_ptr = (u16_t)uip_appdata;
228
229#if 0
230 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
231 asm("sec");
232 asm("sbc #40");
233 asm("sta _chksum_len");
234 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
235 asm("sbc #0");
236 asm("sta _chksum_len+1");
237
238 asm("jsr %v", chksum);
239
240 asm("clc");
241 asm("adc _chksum_tmp");
242 asm("sta _chksum_tmp");
243 asm("txa");
244 asm("adc _chksum_tmp+1");
245 asm("sta _chksum_tmp+1");
246
247 /* Fold carry */
248 /* asm("bcc noinc");
249 asm("inc _chksum_tmp");
250 asm("noinc:");*/
251
252 asm("tcpchksum_loop1:");
253 asm("lda _chksum_tmp");
254 asm("adc #0");
255 asm("sta _chksum_tmp");
256 asm("lda _chksum_tmp+1");
257 asm("adc #0");
258 asm("sta _chksum_tmp+1");
259 asm("bcs tcpchksum_loop1");
260
261
262 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
263 asm("sec");
264 asm("sbc #20");
265 asm("sta _chksum_len");
266 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
267 asm("sbc #0");
268 asm("sta _chksum_len+1");
269
270
271 asm("ldy #$0c");
272 asm("clc");
273 asm("php");
274 asm("tcpchksum_loop2:");
275 asm("plp");
276 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
277 asm("adc _chksum_tmp");
278 asm("sta _chksum_tmp");
279 asm("iny");
280 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
281 asm("adc _chksum_tmp+1");
282 asm("sta _chksum_tmp+1");
283 asm("iny");
284 asm("php");
285 asm("cpy #$14");
286 asm("bne tcpchksum_loop2");
287
288 asm("plp");
289
290 asm("lda _chksum_tmp");
291 asm("adc #0");
292 asm("sta _chksum_tmp");
293 asm("lda _chksum_tmp+1");
294 asm("adc %v", chksum_protocol);
295 asm("sta _chksum_tmp+1");
296
297
298 asm("lda _chksum_tmp");
299 asm("adc _chksum_len+1");
300 asm("sta _chksum_tmp");
301 asm("lda _chksum_tmp+1");
302 asm("adc _chksum_len");
303 asm("sta _chksum_tmp+1");
304
305
306
307 asm("tcpchksum_loop3:");
308 asm("lda _chksum_tmp");
309 asm("adc #0");
310 asm("sta _chksum_tmp");
311 asm("lda _chksum_tmp+1");
312 asm("adc #0");
313 asm("sta _chksum_tmp+1");
314 asm("bcs tcpchksum_loop3");
315#endif
316
317 return chksum_tmp;
318}
319/*#pragma optimize(pop)*/
320
321/*-----------------------------------------------------------------------------------*/
322u16_t
323uip_tcpchksum(void)
324{
325 return transport_chksum(IP_PROTO_TCP);
326#if 0
327 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
328 chksum_len = 20;
329 chksum_tmp = chksum();
330
331 chksum_ptr = (u16_t)uip_appdata;
332 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
333 asm("sec");
334 asm("sbc #40");
335 asm("sta _chksum_len");
336 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
337 asm("sbc #0");
338 asm("sta _chksum_len+1");
339
340 asm("jsr %v", chksum);
341
342 asm("clc");
343 asm("adc _chksum_tmp");
344 asm("sta _chksum_tmp");
345 asm("txa");
346 asm("adc _chksum_tmp+1");
347 asm("sta _chksum_tmp+1");
348
349 /* Fold carry */
350 /* asm("bcc noinc");
351 asm("inc _chksum_tmp");
352 asm("noinc:");*/
353
354 asm("tcpchksum_loop1:");
355 asm("lda _chksum_tmp");
356 asm("adc #0");
357 asm("sta _chksum_tmp");
358 asm("lda _chksum_tmp+1");
359 asm("adc #0");
360 asm("sta _chksum_tmp+1");
361 asm("bcs tcpchksum_loop1");
362
363
364 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
365 asm("sec");
366 asm("sbc #20");
367 asm("sta _chksum_len");
368 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
369 asm("sbc #0");
370 asm("sta _chksum_len+1");
371
372
373 asm("ldy #$0c");
374 asm("clc");
375 asm("php");
376 asm("tcpchksum_loop2:");
377 asm("plp");
378 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
379 asm("adc _chksum_tmp");
380 asm("sta _chksum_tmp");
381 asm("iny");
382 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
383 asm("adc _chksum_tmp+1");
384 asm("sta _chksum_tmp+1");
385 asm("iny");
386 asm("php");
387 asm("cpy #$14");
388 asm("bne tcpchksum_loop2");
389
390 asm("plp");
391
392 asm("lda _chksum_tmp");
393 asm("adc #0");
394 asm("sta _chksum_tmp");
395 asm("lda _chksum_tmp+1");
396 asm("adc #6"); /* IP_PROTO_TCP */
397 asm("sta _chksum_tmp+1");
398
399
400 asm("lda _chksum_tmp");
401 asm("adc _chksum_len+1");
402 asm("sta _chksum_tmp");
403 asm("lda _chksum_tmp+1");
404 asm("adc _chksum_len");
405 asm("sta _chksum_tmp+1");
406
407
408
409 asm("tcpchksum_loop3:");
410 asm("lda _chksum_tmp");
411 asm("adc #0");
412 asm("sta _chksum_tmp");
413 asm("lda _chksum_tmp+1");
414 asm("adc #0");
415 asm("sta _chksum_tmp+1");
416 asm("bcs tcpchksum_loop3");
417
418
419 return chksum_tmp;
420#endif
421}
422
423/*-----------------------------------------------------------------------------------*/
424#if UIP_UDP_CHECKSUMS
425u16_t
426uip_udpchksum(void)
427{
428 return transport_chksum(IP_PROTO_UDP);
429#if 0
430 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
431 chksum_len = 20;
432 chksum_tmp = chksum();
433
434 chksum_ptr = (u16_t)uip_appdata;
435 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
436 asm("sec");
437 asm("sbc #40");
438 asm("sta _chksum_len");
439 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
440 asm("sbc #0");
441 asm("sta _chksum_len+1");
442
443 asm("jsr %v", chksum);
444
445 asm("clc");
446 asm("adc _chksum_tmp");
447 asm("sta _chksum_tmp");
448 asm("txa");
449 asm("adc _chksum_tmp+1");
450 asm("sta _chksum_tmp+1");
451
452 /* Fold carry */
453 /* asm("bcc noinc");
454 asm("inc _chksum_tmp");
455 asm("noinc:");*/
456
457 asm("tcpchksum_loop1:");
458 asm("lda _chksum_tmp");
459 asm("adc #0");
460 asm("sta _chksum_tmp");
461 asm("lda _chksum_tmp+1");
462 asm("adc #0");
463 asm("sta _chksum_tmp+1");
464 asm("bcs tcpchksum_loop1");
465
466
467 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
468 asm("sec");
469 asm("sbc #20");
470 asm("sta _chksum_len");
471 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
472 asm("sbc #0");
473 asm("sta _chksum_len+1");
474
475
476 asm("ldy #$0c");
477 asm("clc");
478 asm("php");
479 asm("tcpchksum_loop2:");
480 asm("plp");
481 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
482 asm("adc _chksum_tmp");
483 asm("sta _chksum_tmp");
484 asm("iny");
485 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
486 asm("adc _chksum_tmp+1");
487 asm("sta _chksum_tmp+1");
488 asm("iny");
489 asm("php");
490 asm("cpy #$14");
491 asm("bne tcpchksum_loop2");
492
493 asm("plp");
494
495 asm("lda _chksum_tmp");
496 asm("adc #0");
497 asm("sta _chksum_tmp");
498 asm("lda _chksum_tmp+1");
499 asm("adc #17"); /* IP_PROTO_UDP */
500 asm("sta _chksum_tmp+1");
501
502
503 asm("lda _chksum_tmp");
504 asm("adc _chksum_len+1");
505 asm("sta _chksum_tmp");
506 asm("lda _chksum_tmp+1");
507 asm("adc _chksum_len");
508 asm("sta _chksum_tmp+1");
509
510
511
512 asm("tcpchksum_loop3:");
513 asm("lda _chksum_tmp");
514 asm("adc #0");
515 asm("sta _chksum_tmp");
516 asm("lda _chksum_tmp+1");
517 asm("adc #0");
518 asm("sta _chksum_tmp+1");
519 asm("bcs tcpchksum_loop3");
520
521
522 return chksum_tmp;
523#endif
524}
525#endif /* UIP_UDP_CHECKSUMS */
526/*-----------------------------------------------------------------------------------*/