home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: DFÜ und Kommunikation / SOS-DFUE.ISO / programm / dos / utility / pccp076 / xmcrc16s.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-20  |  6.7 KB  |  367 lines

  1. /*    Copyright (C) 1992,1993 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<sys\types.h>
  10. #include<sys\stat.h>
  11. #include<signal.h>
  12. #include"port.h"
  13.  
  14. #define NAK 21
  15. #define ACK 6
  16. #define SOH 1
  17. #define STX 2
  18. #define HI6 0xb6 /* 0x80 + '6'; the dreaded 16k packet introducer */
  19. #define EOT 4
  20. #define CAN 24
  21.  
  22. unsigned long tick;
  23.  
  24. void (interrupt far *oldtick)();
  25.  
  26. void interrupt far tickhndl()
  27.     {
  28.     tick++;
  29.     }
  30.  
  31. sendchar(c)
  32.     unsigned char c;
  33.     {
  34.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  35.         if(_bios_keybrd(_KEYBRD_READY))
  36.             if((_bios_keybrd(_KEYBRD_READ)&0xff)==0x03)
  37.                 quit();
  38.     outp(basereg, c);
  39.     }
  40.  
  41. int follow;
  42.  
  43. int rcharto(ticks)
  44.     int ticks;
  45.     {
  46.     int c;
  47.     tick=0L;
  48.     while(1)
  49.         {
  50.         if(_bios_keybrd(_KEYBRD_READY))
  51.             if((_bios_keybrd(_KEYBRD_READ)&0xff)==0x03)
  52.                 quit();
  53.         if(tick>ticks)
  54.             return(-1); /* NOTE: This is an INT!!! */
  55.         if(follow!=index)
  56.             {
  57.             c=buf[follow++];
  58.             if(follow>=TBUFSIZ)
  59.                 follow=0;
  60.             return(c);
  61.             }
  62.         }
  63.     }
  64.  
  65. int calccrc(ptr, count)
  66.     char *ptr;
  67.     int count;
  68.     {
  69.     int crc, i;
  70.     crc = 0;
  71.     while(--count >= 0)
  72.         {
  73.         crc = crc ^ (int)*ptr++ << 8;
  74.         for(i = 0; i < 8; ++i)
  75.             if(crc & 0x8000)
  76.                 crc = crc << 1 ^ 0x1021;
  77.             else
  78.                 crc = crc << 1;
  79.         }
  80.     return (crc & 0xFFFF);
  81.     }
  82.  
  83. unsigned char bigblock[16384];
  84.  
  85. sbigblock(blockn)
  86.     int blockn;
  87.     {
  88.     unsigned char c;
  89.     unsigned short crc, rcrc;
  90.     int i;
  91.     crc=calccrc(bigblock, 16384);
  92.     sendchar(HI6);
  93.     sendchar(blockn);
  94.     sendchar((blockn^0xff)&0xff);
  95.     for(i=0;i<16384;++i)
  96.         sendchar(bigblock[i]);
  97.     sendchar((crc>>8)&0xff);
  98.     sendchar(crc&0xff);
  99.     }
  100.  
  101. unsigned char block[1024];
  102.  
  103. sblock(blockn)
  104.     int blockn;
  105.     {
  106.     unsigned char c;
  107.     unsigned short crc, rcrc;
  108.     int i;
  109.     crc=calccrc(block, 1024);
  110.     sendchar(STX);
  111.     sendchar(blockn);
  112.     sendchar((blockn^0xff)&0xff);
  113.     for(i=0;i<1024;++i)
  114.         sendchar(block[i]);
  115.     sendchar((crc>>8)&0xff);
  116.     sendchar(crc&0xff);
  117.     }
  118.  
  119. unsigned char shortblock[128];
  120.  
  121. ssblock(blockn)
  122.     int blockn;
  123.     {
  124.     unsigned char c;
  125.     unsigned short crc, rcrc;
  126.     int i;
  127.     crc=calccrc(shortblock, 128);
  128.     sendchar(SOH);
  129.     sendchar(blockn);
  130.     sendchar((blockn^0xff)&0xff);
  131.     for(i=0;i<128;++i)
  132.         sendchar(shortblock[i]);
  133.     sendchar((crc>>8)&0xff);
  134.     sendchar(crc&0xff);
  135.     }
  136.  
  137. quit()
  138.     {
  139.     cleanup(0);
  140.     _dos_setvect(0x1c, oldtick);
  141.     exit(99);
  142.     }
  143.  
  144. main(argc, argv)
  145.     int argc;
  146.     char **argv;
  147.     {
  148.     int i, j, k, l, infd, ok, c, nnacks;
  149.     unsigned char *blkptr;
  150.     unsigned char blocknum;
  151.     long nbytes;
  152.     index=follow=0;
  153.     printf("Copyright (C) 1992,1993 Peter Edward Cann, all rights reserved.\n");
  154.     printf("xmodem crc 16k send of %s.\n", argv[4]);
  155.     if(argc!=5)
  156.         {
  157.         printf("USAGE: xmodemr <comnum> <bps> <stopbits> <file pathname>\n");
  158.         exit(1);
  159.         }
  160.     if((infd=open(argv[4], O_RDONLY|O_BINARY))==-1)
  161.         {
  162.         printf("Error opening file %s.\n", argv[4]);
  163.         exit(2);
  164.         }
  165.     comnum=atoi(argv[1])-1;
  166.     speed=atoi(argv[2]);
  167.     databits='8';
  168.     parity='n';
  169.     stopbits=argv[3][0];
  170.     setport();
  171.     readset();
  172.     oldtick=_dos_getvect(0x1c);
  173.     signal(SIGINT, quit);
  174.     _dos_setvect(0x1c, tickhndl);
  175.     setup();
  176.     nbytes=0;
  177.     for(i=0;;++i)
  178.         {
  179.         if((c=rcharto(100))==CAN)
  180.             {
  181.             c=rcharto(100);
  182.             if(c==CAN)
  183.                 {
  184.                 printf("Received two consecutive CANcel codes (^X).\n");
  185.                 cleanup(0);
  186.                 _dos_setvect(0x1c, oldtick);
  187.                 exit(40);
  188.                 }
  189.             }
  190.         if(c=='C')
  191.             break;
  192.         if(i>=20)
  193.             {
  194.             printf("No C in 20 five-second tries.\n");
  195.             cleanup(0);
  196.             _dos_setvect(0x1c, oldtick);
  197.             exit(10);
  198.             }
  199.         }
  200.     blocknum=1;
  201.     while(1)
  202.         {
  203.         if((j=read(infd, bigblock, 16384))==0)
  204.             {
  205.             printf("\nEnd of file.\n");
  206.             sendchar(EOT);
  207.             do
  208.                 {
  209.                 c=rcharto(300);
  210.                 printf("%02x ", c);
  211.                 if(c==CAN)
  212.                     {
  213.                     c=rcharto(300);
  214.                     printf("%02x ", c);
  215.                     }
  216.                 }
  217.             while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  218.             if(c==-1)
  219.                 {
  220.                 printf("\nTimeout.\n");
  221.                 cleanup(0);
  222.                 _dos_setvect(0x1c, oldtick);
  223.                 exit(30);
  224.                 }
  225.             else if(c==NAK)
  226.                 {
  227.                 printf("\nEOT NAKed.\n");
  228.                 cleanup(0);
  229.                 _dos_setvect(0x1c, oldtick);
  230.                 exit(13);
  231.                 }
  232.             else if(c==CAN)
  233.                 {
  234.                 printf("\nReceived two consecutive CANcel codes (^X).\n");
  235.                 cleanup(0);
  236.                 _dos_setvect(0x1c, oldtick);
  237.                 exit(31);
  238.                 }
  239.             else
  240.                 {
  241.                 printf("\nSuccessful.\n");
  242.                 cleanup(0);
  243.                 _dos_setvect(0x1c, oldtick);
  244.                 exit(0);    
  245.                 }
  246.             }
  247.         for(c=j;c<16384;c++)
  248.             bigblock[c]=26;
  249.         if(j>(16384-128))
  250.             {
  251.             nnacks=0;
  252.             do
  253.                 {
  254.                 printf("\nSending block %d. ", blocknum);
  255.                 sbigblock(blocknum);
  256.                 do
  257.                     {
  258.                     c=rcharto(200);
  259.                     printf("%02x ", c);
  260.                     if(c==CAN)
  261.                         {
  262.                         c=rcharto(200);
  263.                         printf("%02x ", c);
  264.                         }
  265.                     }
  266.                 while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  267.                 }
  268.             while((c==NAK)&&(nnacks++<10));
  269.             if(c==ACK)
  270.                 {
  271.                 blocknum++;
  272.                 nbytes+=16384;
  273.                 printf("Successful. Bytes so far: %ld", nbytes);
  274.                 }
  275.             }
  276.         else 
  277.             {
  278.             for(i=0,k=0;i<(j+128-1024);i+=1024)
  279.                 {
  280.                 for(k=i,l=0;l<1024;k++,l++)
  281.                     block[l]=bigblock[k];
  282.                 nnacks=0;
  283.                 do
  284.                     {
  285.                     printf("\nSending block %d. ", blocknum);
  286.                     sblock(blocknum);
  287.                     do
  288.                         {
  289.                         c=rcharto(200);
  290.                         printf("%02x ", c);
  291.                         if(c==CAN)
  292.                             {
  293.                             c=rcharto(200);
  294.                             printf("%02x ", c);
  295.                             }
  296.                         }
  297.                     while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  298.                     }
  299.                 while((c==NAK)&&(nnacks++<10));
  300.                 if(c==ACK)
  301.                     {
  302.                     blocknum++;
  303.                     nbytes+=1024;
  304.                     printf("Successful. Bytes so far: %ld", nbytes);
  305.                     }
  306.                 }
  307.             for(l=k;l<j;l+=128)
  308.                 {
  309.                 for(i=0;i<128;++i)
  310.                     shortblock[i]=bigblock[l+i];
  311.                 nnacks=0;
  312.                 do
  313.                     {
  314.                     printf("\nSending block %d. ", blocknum);
  315.                     ssblock(blocknum);
  316.                     do
  317.                         {
  318.                         c=rcharto(200);
  319.                         printf("%02x ", c);
  320.                         if(c==CAN)
  321.                             {
  322.                             c=rcharto(200);
  323.                             printf("%02x ", c);
  324.                             }
  325.                         }
  326.                     while((c!=ACK)&&(c!=NAK)&&(c!=CAN)&&(c!=-1));
  327.                     }
  328.                 while((c==NAK)&&(nnacks++<10));
  329.                 if(c!=ACK)
  330.                     break;
  331.                 else
  332.                     {
  333.                     blocknum++;
  334.                     nbytes+=128;
  335.                     printf("Successful. Bytes so far: %ld", nbytes);
  336.                     }
  337.                 }
  338.             }
  339.         if(c!=ACK)
  340.             if(c==NAK)
  341.                 {
  342.                 printf("\nRetry limit exceeded.\n");
  343.                 cleanup(0);
  344.                 _dos_setvect(0x1c, oldtick);
  345.                 exit(14);
  346.                 }
  347.             else if(c==-1)
  348.                 {
  349.                 printf("\nTimeout.\n");
  350.                 cleanup(0);
  351.                 _dos_setvect(0x1c, oldtick);
  352.                 exit(33);
  353.                 }
  354.             else
  355.                 {
  356.                 printf("\nReceived two consecutive CANcel codes (^X).\n");
  357.                 cleanup(0);
  358.                 _dos_setvect(0x1c, oldtick);
  359.                 exit(11);
  360.                 }
  361.         }
  362.     printf("Programming error; fell through end; see code.\n");
  363.     cleanup(0);
  364.     _dos_setvect(0x1c, oldtick);
  365.     exit(12);
  366.     }
  367.