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