blob: 2bb289811089748af702416c4c9b010527a30c52 [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 *
adamdunkels503df8d2004-07-04 20:01:15 +000031 * $Id: uip_arch.c,v 1.2 2004/07/04 20:01:31 adamdunkels 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/*-----------------------------------------------------------------------------------*/
43#if UIP_BUFSIZE > 255
44/*-----------------------------------------------------------------------------------*/
45void
46uip_add32(u8_t *op32, u16_t op16)
47{
48 asm("ldy #3");
49 asm("jsr ldaxysp");
50 asm("sta ptr1");
51 asm("stx ptr1+1");
52 asm("ldy #0");
53 asm("lda (sp),y");
54 asm("ldy #3");
55 asm("clc");
56 asm("adc (ptr1),y");
57 asm("sta _uip_acc32+3");
58 asm("dey");
59 asm("lda (ptr1),y");
60 asm("ldy #1");
61 asm("adc (sp),y");
62 asm("sta _uip_acc32+2");
63 asm("ldy #1");
64 asm("lda (ptr1),y");
65 asm("adc #0");
66 asm("sta _uip_acc32+1");
67 asm("dey");
68 asm("lda (ptr1),y");
69 asm("adc #0");
70 asm("sta _uip_acc32+0");
71}
72/*-----------------------------------------------------------------------------------*/
adamdunkels4fa940f2003-04-11 20:30:14 +000073#else /* UIP_BUFSIZE > 255 */
74/*-----------------------------------------------------------------------------------*/
75void
76uip_add32(u8_t *op32, u8_t op8)
77{
78 asm("ldy #2");
79 asm("jsr ldaxysp");
80 asm("sta ptr1");
81 asm("stx ptr1+1");
82 asm("ldy #0");
83 asm("lda (sp),y");
84 asm("ldy #3");
85 asm("clc");
86 asm("adc (ptr1),y");
87 asm("sta _uip_acc32+3");
88 asm("dey");
89 asm("lda (ptr1),y");
90 asm("adc #0");
91 asm("sta _uip_acc32+2");
92 asm("dey");
93 asm("lda (ptr1),y");
94 asm("adc #0");
95 asm("sta _uip_acc32+1");
96 asm("dey");
97 asm("lda (ptr1),y");
98 asm("adc #0");
99 asm("sta _uip_acc32+0");
100}
101/*-----------------------------------------------------------------------------------*/
adamdunkels4fa940f2003-04-11 20:30:14 +0000102#endif /* UIP_BUFSIZE > 255 */
103
104static u16_t chksum_ptr, chksum_len, chksum_tmp;
105static u16_t chksum(void);
106/*-----------------------------------------------------------------------------------*/
107u16_t
108chksum(void) {
109
110 asm("lda #0");
111 asm("sta tmp1");
112 asm("sta tmp1+1");
113 asm("lda _chksum_ptr");
114 asm("sta ptr1");
115 asm("lda _chksum_ptr+1");
116 asm("sta ptr1+1");
117
118
119 asm("lda _chksum_len+1");
120 asm("beq chksumlast");
121
122
123 /* If checksum is > 256, do the first runs. */
124 asm("ldy #0");
125 asm("clc");
126 asm("chksumloop_256:");
127 asm("lda (ptr1),y");
128 asm("adc tmp1");
129 asm("sta tmp1");
130 asm("iny");
131 asm("lda (ptr1),y");
132 asm("adc tmp1+1");
133 asm("sta tmp1+1");
134 asm("iny");
135 asm("bne chksumloop_256");
136 asm("inc ptr1+1");
137 asm("dec _chksum_len+1");
138 asm("bne chksumloop_256");
139
140 asm("chksum_endloop_256:");
141 asm("lda tmp1");
142 asm("adc #0");
143 asm("sta tmp1");
144 asm("lda tmp1+1");
145 asm("adc #0");
146 asm("sta tmp1+1");
147 asm("bcs chksum_endloop_256");
148
149 asm("chksumlast:");
150 asm("lda _chksum_len");
151 asm("lsr");
152 asm("bcc chksum_noodd");
153 asm("ldy _chksum_len");
154 asm("dey");
155 asm("lda (ptr1),y");
156 asm("clc");
157 asm("adc tmp1");
158 asm("sta tmp1");
159 asm("bcc noinc1");
160 asm("inc tmp1+1");
161 asm("bne noinc1");
162 asm("inc tmp1");
163 asm("noinc1:");
164 asm("dec _chksum_len");
165
166 asm("chksum_noodd:");
167 asm("clc");
168 asm("php");
169 asm("ldy _chksum_len");
170 asm("chksum_loop1:");
171 asm("cpy #0");
172 asm("beq chksum_loop1_end");
173 asm("plp");
174 asm("dey");
175 asm("dey");
176 asm("lda (ptr1),y");
177 asm("adc tmp1");
178 asm("sta tmp1");
179 asm("iny");
180 asm("lda (ptr1),y");
181 asm("adc tmp1+1");
182 asm("sta tmp1+1");
183 asm("dey");
184 asm("php");
185 asm("jmp chksum_loop1");
186 asm("chksum_loop1_end:");
187 asm("plp");
188
189 asm("chksum_endloop:");
190 asm("lda tmp1");
191 asm("adc #0");
192 asm("sta tmp1");
193 asm("lda tmp1+1");
194 asm("adc #0");
195 asm("sta tmp1+1");
196 asm("bcs chksum_endloop");
197
198 asm("lda tmp1");
199 asm("ldx tmp1+1");
200}
201/*-----------------------------------------------------------------------------------*/
202u16_t
203uip_chksum(u16_t *buf, u16_t len)
204{
205 /* unsigned long sum;
206
207 sum = 0;
208
209 chksum_ptr = (u16_t)buf;
210 while(len >= 256) {
211 chksum_len = 256;
212 sum += chksum();
213 len -= 256;
214 chksum_ptr += 256;
215 }
216
217 if(len < 256) {
218 chksum_len = len;
219 sum += chksum();
220 }
221
222 while((sum >> 16) != 0) {
223 sum = (sum >> 16) + (sum & 0xffff);
224 }
225
226 return sum;*/
227
228 chksum_len = len;
229 chksum_ptr = (u16_t)buf;
230 return chksum();
231}
232/*-----------------------------------------------------------------------------------*/
233u16_t
234uip_ipchksum(void)
235{
236 chksum_ptr = (u16_t)uip_buf + UIP_LLH_LEN;
237 chksum_len = 20;
238 return chksum();
239}
240/*-----------------------------------------------------------------------------------*/
241u16_t
242uip_tcpchksum(void)
243{
244 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
245 chksum_len = 20;
246 chksum_tmp = chksum();
247
248 chksum_ptr = (u16_t)uip_appdata;
249#ifdef WITH_TFE
250 asm("lda _uip_buf+3+14");
251#else /* WITH_TFE */
252 asm("lda _uip_buf+3");
253#endif /* WITH_TFE */
254 asm("sec");
255 asm("sbc #40");
256 asm("sta _chksum_len");
257#ifdef WITH_TFE
258 asm("lda _uip_buf+2+14");
259#else /* WITH_TFE */
260 asm("lda _uip_buf+2");
261#endif /* WITH_TFE */
262 asm("sbc #0");
263 asm("sta _chksum_len+1");
264
265 asm("jsr %v", chksum);
266
267 asm("clc");
268 asm("adc _chksum_tmp");
269 asm("sta _chksum_tmp");
270 asm("txa");
271 asm("adc _chksum_tmp+1");
272 asm("sta _chksum_tmp+1");
273
274 /* Fold carry */
275 /* asm("bcc noinc");
276 asm("inc _chksum_tmp");
277 asm("noinc:");*/
278
279 asm("tcpchksum_loop1:");
280 asm("lda _chksum_tmp");
281 asm("adc #0");
282 asm("sta _chksum_tmp");
283 asm("lda _chksum_tmp+1");
284 asm("adc #0");
285 asm("sta _chksum_tmp+1");
286 asm("bcs tcpchksum_loop1");
287
288
289#ifdef WITH_TFE
290 asm("lda _uip_buf+3+14");
291#else /* WITH_TFE */
292 asm("lda _uip_buf+3");
293#endif /* WITH_TFE */
294 asm("sec");
295 asm("sbc #20");
296 asm("sta _chksum_len");
297#ifdef WITH_TFE
298 asm("lda _uip_buf+2+14");
299#else /* WITH_TFE */
300 asm("lda _uip_buf+2");
301#endif /* WITH_TFE */
302 asm("sbc #0");
303 asm("sta _chksum_len+1");
304
305
306 asm("ldy #$0c");
307 asm("clc");
308 asm("php");
309 asm("tcpchksum_loop2:");
310 asm("plp");
311#ifdef WITH_TFE
312 asm("lda _uip_buf+14,y");
313#else /* WITH_TFE */
314 asm("lda _uip_buf,y");
315#endif /* WITH_TFE */
316 asm("adc _chksum_tmp");
317 asm("sta _chksum_tmp");
318 asm("iny");
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+1");
325 asm("sta _chksum_tmp+1");
326 asm("iny");
327 asm("php");
328 asm("cpy #$14");
329 asm("bne tcpchksum_loop2");
330
331 asm("plp");
332
333 asm("lda _chksum_tmp");
334 asm("adc #0");
335 asm("sta _chksum_tmp");
336 asm("lda _chksum_tmp+1");
337 asm("adc #6"); /* IP_PROTO_TCP */
338 asm("sta _chksum_tmp+1");
339
340
341 asm("lda _chksum_tmp");
342 asm("adc _chksum_len+1");
343 asm("sta _chksum_tmp");
344 asm("lda _chksum_tmp+1");
345 asm("adc _chksum_len");
346 asm("sta _chksum_tmp+1");
347
348
349
350 asm("tcpchksum_loop3:");
351 asm("lda _chksum_tmp");
352 asm("adc #0");
353 asm("sta _chksum_tmp");
354 asm("lda _chksum_tmp+1");
355 asm("adc #0");
356 asm("sta _chksum_tmp+1");
357 asm("bcs tcpchksum_loop3");
358
359
360 return chksum_tmp;
361}
362/*-----------------------------------------------------------------------------------*/