00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "net/uip.h"
00037 #include "net/uip_arch.h"
00038
00039 #define BUF ((uip_tcpip_hdr *)&uip_buf[UIP_LLH_LEN])
00040 #define IP_PROTO_TCP 6
00041 #define IP_PROTO_UDP 17
00042
00043
00044 #pragma optimize(push, off)
00045 void
00046 uip_add32(u8_t *op32, u16_t op16)
00047 {
00048 asm("ldy #3");
00049 asm("jsr ldaxysp");
00050 asm("sta ptr1");
00051 asm("stx ptr1+1");
00052 asm("ldy #0");
00053 asm("lda (sp),y");
00054 asm("ldy #3");
00055 asm("clc");
00056 asm("adc (ptr1),y");
00057 asm("sta _uip_acc32+3");
00058 asm("dey");
00059 asm("lda (ptr1),y");
00060 asm("ldy #1");
00061 asm("adc (sp),y");
00062 asm("sta _uip_acc32+2");
00063 asm("ldy #1");
00064 asm("lda (ptr1),y");
00065 asm("adc #0");
00066 asm("sta _uip_acc32+1");
00067 asm("dey");
00068 asm("lda (ptr1),y");
00069 asm("adc #0");
00070 asm("sta _uip_acc32+0");
00071 }
00072 #pragma optimize(pop)
00073
00074 static u16_t chksum_ptr, chksum_len, chksum_tmp;
00075 static u8_t chksum_protocol;
00076 static u16_t chksum(void);
00077
00078 #pragma optimize(push, off)
00079 u16_t
00080 chksum(void) {
00081
00082 asm("lda #0");
00083 asm("sta tmp1");
00084 asm("sta tmp1+1");
00085 asm("lda _chksum_ptr");
00086 asm("sta ptr1");
00087 asm("lda _chksum_ptr+1");
00088 asm("sta ptr1+1");
00089
00090
00091 asm("lda _chksum_len+1");
00092 asm("beq chksumlast");
00093
00094
00095
00096 asm("ldy #0");
00097 asm("clc");
00098 asm("chksumloop_256:");
00099 asm("lda (ptr1),y");
00100 asm("adc tmp1");
00101 asm("sta tmp1");
00102 asm("iny");
00103 asm("lda (ptr1),y");
00104 asm("adc tmp1+1");
00105 asm("sta tmp1+1");
00106 asm("iny");
00107 asm("bne chksumloop_256");
00108 asm("inc ptr1+1");
00109 asm("dec _chksum_len+1");
00110 asm("bne chksumloop_256");
00111
00112 asm("chksum_endloop_256:");
00113 asm("lda tmp1");
00114 asm("adc #0");
00115 asm("sta tmp1");
00116 asm("lda tmp1+1");
00117 asm("adc #0");
00118 asm("sta tmp1+1");
00119 asm("bcs chksum_endloop_256");
00120
00121 asm("chksumlast:");
00122 asm("lda _chksum_len");
00123 asm("lsr");
00124 asm("bcc chksum_noodd");
00125 asm("ldy _chksum_len");
00126 asm("dey");
00127 asm("lda (ptr1),y");
00128 asm("clc");
00129 asm("adc tmp1");
00130 asm("sta tmp1");
00131 asm("bcc noinc1");
00132 asm("inc tmp1+1");
00133 asm("bne noinc1");
00134 asm("inc tmp1");
00135 asm("noinc1:");
00136 asm("dec _chksum_len");
00137
00138 asm("chksum_noodd:");
00139 asm("clc");
00140 asm("php");
00141 asm("ldy _chksum_len");
00142 asm("chksum_loop1:");
00143 asm("cpy #0");
00144 asm("beq chksum_loop1_end");
00145 asm("plp");
00146 asm("dey");
00147 asm("dey");
00148 asm("lda (ptr1),y");
00149 asm("adc tmp1");
00150 asm("sta tmp1");
00151 asm("iny");
00152 asm("lda (ptr1),y");
00153 asm("adc tmp1+1");
00154 asm("sta tmp1+1");
00155 asm("dey");
00156 asm("php");
00157 asm("jmp chksum_loop1");
00158 asm("chksum_loop1_end:");
00159 asm("plp");
00160
00161 asm("chksum_endloop:");
00162 asm("lda tmp1");
00163 asm("adc #0");
00164 asm("sta tmp1");
00165 asm("lda tmp1+1");
00166 asm("adc #0");
00167 asm("sta tmp1+1");
00168 asm("bcs chksum_endloop");
00169
00170 asm("lda tmp1");
00171 asm("ldx tmp1+1");
00172 }
00173 #pragma optimize(pop)
00174
00175 u16_t
00176 uip_chksum(u16_t *buf, u16_t len)
00177 {
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201 chksum_len = len;
00202 chksum_ptr = (u16_t)buf;
00203 return chksum();
00204 }
00205
00206 u16_t
00207 uip_ipchksum(void)
00208 {
00209 chksum_ptr = (u16_t)uip_buf + UIP_LLH_LEN;
00210 chksum_len = UIP_IPH_LEN;
00211 return chksum();
00212 }
00213
00214 #pragma optimize(push, off)
00215 static u16_t
00216 transport_chksum(u8_t protocol)
00217 {
00218 chksum_protocol = protocol;
00219 chksum_ptr = (u16_t)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN];
00220 chksum_len = UIP_TCPH_LEN;
00221 chksum_tmp = chksum();
00222
00223 chksum_ptr = (u16_t)uip_appdata;
00224 asm("lda _uip_aligned_buf+3+%b", UIP_LLH_LEN);
00225 asm("sec");
00226 asm("sbc #%b", UIP_IPTCPH_LEN);
00227 asm("sta _chksum_len");
00228 asm("lda _uip_aligned_buf+2+%b", UIP_LLH_LEN);
00229 asm("sbc #0");
00230 asm("sta _chksum_len+1");
00231
00232 asm("jsr %v", chksum);
00233
00234 asm("clc");
00235 asm("adc _chksum_tmp");
00236 asm("sta _chksum_tmp");
00237 asm("txa");
00238 asm("adc _chksum_tmp+1");
00239 asm("sta _chksum_tmp+1");
00240
00241
00242
00243
00244
00245
00246 asm("tcpchksum_loop1:");
00247 asm("lda _chksum_tmp");
00248 asm("adc #0");
00249 asm("sta _chksum_tmp");
00250 asm("lda _chksum_tmp+1");
00251 asm("adc #0");
00252 asm("sta _chksum_tmp+1");
00253 asm("bcs tcpchksum_loop1");
00254
00255
00256 asm("lda _uip_aligned_buf+3+%b", UIP_LLH_LEN);
00257 asm("sec");
00258 asm("sbc #%b", UIP_IPH_LEN);
00259 asm("sta _chksum_len");
00260 asm("lda _uip_aligned_buf+2+%b", UIP_LLH_LEN);
00261 asm("sbc #0");
00262 asm("sta _chksum_len+1");
00263
00264
00265 asm("ldy #$0c");
00266 asm("clc");
00267 asm("php");
00268 asm("tcpchksum_loop2:");
00269 asm("plp");
00270 asm("lda _uip_aligned_buf+%b,y", UIP_LLH_LEN);
00271 asm("adc _chksum_tmp");
00272 asm("sta _chksum_tmp");
00273 asm("iny");
00274 asm("lda _uip_aligned_buf+%b,y", UIP_LLH_LEN);
00275 asm("adc _chksum_tmp+1");
00276 asm("sta _chksum_tmp+1");
00277 asm("iny");
00278 asm("php");
00279 asm("cpy #$14");
00280 asm("bne tcpchksum_loop2");
00281
00282 asm("plp");
00283
00284 asm("lda _chksum_tmp");
00285 asm("adc #0");
00286 asm("sta _chksum_tmp");
00287 asm("lda _chksum_tmp+1");
00288 asm("adc %v", chksum_protocol);
00289 asm("sta _chksum_tmp+1");
00290
00291
00292 asm("lda _chksum_tmp");
00293 asm("adc _chksum_len+1");
00294 asm("sta _chksum_tmp");
00295 asm("lda _chksum_tmp+1");
00296 asm("adc _chksum_len");
00297 asm("sta _chksum_tmp+1");
00298
00299
00300
00301 asm("tcpchksum_loop3:");
00302 asm("lda _chksum_tmp");
00303 asm("adc #0");
00304 asm("sta _chksum_tmp");
00305 asm("lda _chksum_tmp+1");
00306 asm("adc #0");
00307 asm("sta _chksum_tmp+1");
00308 asm("bcs tcpchksum_loop3");
00309
00310
00311 return chksum_tmp;
00312 }
00313 #pragma optimize(pop)
00314
00315
00316 u16_t
00317 uip_tcpchksum(void)
00318 {
00319 return transport_chksum(IP_PROTO_TCP);
00320 #if 0
00321 chksum_ptr = (u16_t)&uip_buf[UIP_LLH_LEN + UIP_IPH_LEN];
00322 chksum_len = UIP_TCPH_LEN;
00323 chksum_tmp = chksum();
00324
00325 chksum_ptr = (u16_t)uip_appdata;
00326 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
00327 asm("sec");
00328 asm("sbc #%b", UIP_IPTCPH_LEN);
00329 asm("sta _chksum_len");
00330 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
00331 asm("sbc #0");
00332 asm("sta _chksum_len+1");
00333
00334 asm("jsr %v", chksum);
00335
00336 asm("clc");
00337 asm("adc _chksum_tmp");
00338 asm("sta _chksum_tmp");
00339 asm("txa");
00340 asm("adc _chksum_tmp+1");
00341 asm("sta _chksum_tmp+1");
00342
00343
00344
00345
00346
00347
00348 asm("tcpchksum_loop1:");
00349 asm("lda _chksum_tmp");
00350 asm("adc #0");
00351 asm("sta _chksum_tmp");
00352 asm("lda _chksum_tmp+1");
00353 asm("adc #0");
00354 asm("sta _chksum_tmp+1");
00355 asm("bcs tcpchksum_loop1");
00356
00357
00358 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
00359 asm("sec");
00360 asm("sbc #%b", UIP_IPH_LEN);
00361 asm("sta _chksum_len");
00362 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
00363 asm("sbc #0");
00364 asm("sta _chksum_len+1");
00365
00366
00367 asm("ldy #$0c");
00368 asm("clc");
00369 asm("php");
00370 asm("tcpchksum_loop2:");
00371 asm("plp");
00372 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
00373 asm("adc _chksum_tmp");
00374 asm("sta _chksum_tmp");
00375 asm("iny");
00376 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
00377 asm("adc _chksum_tmp+1");
00378 asm("sta _chksum_tmp+1");
00379 asm("iny");
00380 asm("php");
00381 asm("cpy #$14");
00382 asm("bne tcpchksum_loop2");
00383
00384 asm("plp");
00385
00386 asm("lda _chksum_tmp");
00387 asm("adc #0");
00388 asm("sta _chksum_tmp");
00389 asm("lda _chksum_tmp+1");
00390 asm("adc #6");
00391 asm("sta _chksum_tmp+1");
00392
00393
00394 asm("lda _chksum_tmp");
00395 asm("adc _chksum_len+1");
00396 asm("sta _chksum_tmp");
00397 asm("lda _chksum_tmp+1");
00398 asm("adc _chksum_len");
00399 asm("sta _chksum_tmp+1");
00400
00401
00402
00403 asm("tcpchksum_loop3:");
00404 asm("lda _chksum_tmp");
00405 asm("adc #0");
00406 asm("sta _chksum_tmp");
00407 asm("lda _chksum_tmp+1");
00408 asm("adc #0");
00409 asm("sta _chksum_tmp+1");
00410 asm("bcs tcpchksum_loop3");
00411
00412
00413 return chksum_tmp;
00414 #endif
00415 }
00416
00417
00418 #if UIP_UDP_CHECKSUMS
00419 u16_t
00420 uip_udpchksum(void)
00421 {
00422 return transport_chksum(IP_PROTO_UDP);
00423 #if 0
00424 chksum_ptr = (u16_t)&uip_buf[20 + UIP_LLH_LEN];
00425 chksum_len = 20;
00426 chksum_tmp = chksum();
00427
00428 chksum_ptr = (u16_t)uip_appdata;
00429 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
00430 asm("sec");
00431 asm("sbc #40");
00432 asm("sta _chksum_len");
00433 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
00434 asm("sbc #0");
00435 asm("sta _chksum_len+1");
00436
00437 asm("jsr %v", chksum);
00438
00439 asm("clc");
00440 asm("adc _chksum_tmp");
00441 asm("sta _chksum_tmp");
00442 asm("txa");
00443 asm("adc _chksum_tmp+1");
00444 asm("sta _chksum_tmp+1");
00445
00446
00447
00448
00449
00450
00451 asm("tcpchksum_loop1:");
00452 asm("lda _chksum_tmp");
00453 asm("adc #0");
00454 asm("sta _chksum_tmp");
00455 asm("lda _chksum_tmp+1");
00456 asm("adc #0");
00457 asm("sta _chksum_tmp+1");
00458 asm("bcs tcpchksum_loop1");
00459
00460
00461 asm("lda _uip_buf+3+%b", UIP_LLH_LEN);
00462 asm("sec");
00463 asm("sbc #20");
00464 asm("sta _chksum_len");
00465 asm("lda _uip_buf+2+%b", UIP_LLH_LEN);
00466 asm("sbc #0");
00467 asm("sta _chksum_len+1");
00468
00469
00470 asm("ldy #$0c");
00471 asm("clc");
00472 asm("php");
00473 asm("tcpchksum_loop2:");
00474 asm("plp");
00475 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
00476 asm("adc _chksum_tmp");
00477 asm("sta _chksum_tmp");
00478 asm("iny");
00479 asm("lda _uip_buf+%b,y", UIP_LLH_LEN);
00480 asm("adc _chksum_tmp+1");
00481 asm("sta _chksum_tmp+1");
00482 asm("iny");
00483 asm("php");
00484 asm("cpy #$14");
00485 asm("bne tcpchksum_loop2");
00486
00487 asm("plp");
00488
00489 asm("lda _chksum_tmp");
00490 asm("adc #0");
00491 asm("sta _chksum_tmp");
00492 asm("lda _chksum_tmp+1");
00493 asm("adc #17");
00494 asm("sta _chksum_tmp+1");
00495
00496
00497 asm("lda _chksum_tmp");
00498 asm("adc _chksum_len+1");
00499 asm("sta _chksum_tmp");
00500 asm("lda _chksum_tmp+1");
00501 asm("adc _chksum_len");
00502 asm("sta _chksum_tmp+1");
00503
00504
00505
00506 asm("tcpchksum_loop3:");
00507 asm("lda _chksum_tmp");
00508 asm("adc #0");
00509 asm("sta _chksum_tmp");
00510 asm("lda _chksum_tmp+1");
00511 asm("adc #0");
00512 asm("sta _chksum_tmp+1");
00513 asm("bcs tcpchksum_loop3");
00514
00515
00516 return chksum_tmp;
00517 #endif
00518 }
00519 #endif
00520