home *** CD-ROM | disk | FTP | other *** search
/ The CIA World Factbook 1992 / k3bimage.iso / sel / 02 / 0035 / jmodem_d.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-02  |  9.9 KB  |  184 lines

  1. /****************************************************************************/
  2. /*   FILE JMODEM_D.C                                                        */
  3. /*   Created 11-JAN-1990                  Richard B. Johnson                */
  4. /*                                        405 Broughton Drive               */
  5. /*                                        Beverly, Massachusetts 01915      */
  6. /*                                        BBS (508) 922-3166                */
  7. /*                                                                          */
  8. /*   disp();        (Displays a "USAGE" message)                            */
  9. /*   encode();      (Data compression routine  )                            */
  10. /*   decode();      (Data expansion routine    )                            */
  11. /*   calc_crc();    (CRC checking and setting  )                            */
  12. /*                                                                          */
  13. /****************************************************************************/
  14. #include <stdio.h>                              /* For _printf()            */
  15. #include <stdlib.h>                             /* For _rotl()              */
  16. #include <string.h>                             /* For strcpy               */
  17. #include "jmodem.h"                             /* JMODEM primatives        */
  18. /****************************************************************************/
  19. /*                          Print the 'Usage' prompt.                       */
  20. /*    Made complicated so we don't have to use the ENORMOUS _printf()       */
  21. /*    library file.  This saves a lot of space!                             */
  22. /*                                                                          */
  23. /****************************************************************************/
  24. void disp()
  25. {
  26.     unsigned short i;
  27.     static char info[] = "JMODEM R1 <filename.typ> Receive a file using COM1";
  28.     static char send[] = "Send";
  29.     puts("\nUsage:\n");
  30.     for (i=1; i < 5; i++)
  31.     {
  32.         info[8]  = (char) i + 0x30;             /* Plug in the port number  */
  33.         info[49] = (char) i + 0x30;             /* Plug in the port number  */
  34.         puts(info);                             /* Write to console         */
  35.     }
  36.     strcpy(&info[25],send);                     /* Substitute send for rec  */
  37.     strcpy(&info[29],&info[32]);                /* Copy rest of string      */
  38.     info[7] = 'S';                              /* Substitute 'S' for 'R'   */
  39.     for (i=1; i < 5; i++)
  40.     {
  41.         info[8]  = (char) i + 0x30;             /* Plug in the port number  */
  42.         info[46] = (char) i + 0x30;        /* Plug in the port number  */
  43.         puts(info);                             /* Write to console         */
  44.     }
  45.     return;
  46. }
  47. /****************************************************************************/
  48. /*                   Encode (compress) the input string.                    */
  49. /*   The routine looks for groups of identical characters and replaces them */
  50. /*   with the character  0xBB, a word denoting the number of characters to  */
  51. /*   duplicate, followed by the character to duplicate.                     */
  52. /*                                                                          */
  53. /****************************************************************************/
  54.  
  55. unsigned short encode(len, in_buffer, out_buffer)
  56. unsigned short len;                             /* Length of input string   */
  57. register unsigned char *in_buffer;              /* Pointer to input buffer  */
  58. register unsigned char *out_buffer;             /* Pointer to output buffer */
  59. {
  60.     unsigned short how_many=0;                  /* Character count          */
  61.     unsigned short count=0;                     /* Output byte count        */
  62.     unsigned char dupl;                         /* Character to replace     */
  63.  
  64.     while (len)                                 /* While bytes in buffer    */
  65.     {
  66.         if ( (*in_buffer == 0xBB)               /* If the sentinel byte     */
  67.           || (*in_buffer == *(in_buffer+1)) )   /* If two adjacent the same */
  68.         {
  69.             *out_buffer++ = 0xBB;               /* Insert , bump pointer    */
  70.             dupl = *in_buffer;                  /* Save duplicate character */
  71.             how_many = 0;                       /* Duplicate char count     */
  72.             while ( (*in_buffer++ == dupl)      /* Count duplicates         */
  73.                               && (len) )        /* While bytes still left.  */
  74.             {
  75.                 how_many++;                     /* Identical characters     */
  76.                 len --;                         /* Don't move to (while)    */
  77.             }
  78.             *out_buffer++ =
  79.                (unsigned char) how_many;       /* Character count, low byte */
  80.             *out_buffer++ =
  81.               (unsigned char) (how_many >> 8); /* Character count high byte */
  82.             *out_buffer++ = dupl;              /* The duplicate character   */
  83.             count += 4;                        /* Adjust byte count         */
  84.             in_buffer--;                       /* Non-duplicate character   */
  85.         }
  86.         else
  87.         {
  88.             *out_buffer++ = *in_buffer++;      /* Copy byte                 */
  89.             count++;                           /* Character count           */
  90.             len--;
  91.         }
  92.         if ( count > DAT_MAX )                 /* Check buffer limit        */
  93.             return JM_MAX;
  94.     }
  95.     return count;                              /* New length                */
  96. }
  97. /****************************************************************************/
  98. /*                     Decode (expand) the encoded string.                  */
  99. /*    Routine checks for a sentinel byte, 0xBB, and if found, takes the     */
  100. /*    following word as the number of identical bytes to add. The actual    */
  101. /*    byte to add is located following the length-word.                     */
  102. /*                                                                          */
  103. /****************************************************************************/
  104. unsigned short decode(len, in_buffer, out_buffer)
  105. unsigned short len;                             /* Length to input string   */
  106. register unsigned char *in_buffer;              /* Pointer to input buffer  */
  107. register unsigned char *out_buffer;             /* Pointer to output buffer */
  108. {
  109.     unsigned short i=0;
  110.     unsigned short j=0;
  111.     unsigned char c;
  112.  
  113.     while (len)
  114.     {
  115.         if (*in_buffer == 0xBB )                /* If the sentinel byte     */
  116.         {
  117.              in_buffer ++;                      /* Next character           */
  118.              i = (unsigned short) *in_buffer++; /* Get low byte, incr       */
  119.              i |= (unsigned short)
  120.                  *in_buffer++ << 8;             /* Get high byte, incr      */
  121.              c = *in_buffer++;                  /* Get byte, incr           */
  122.              while (i--)                        /* Expand the byte          */
  123.              {
  124.                  *out_buffer++ = c;             /* Expand byte              */
  125.                  j++;                           /* Output character count   */
  126.              }
  127.         len -=4;                                /* Adjust input count       */
  128.         }
  129.         else                                    /* Else, just copy          */
  130.         {
  131.             *out_buffer++ = *in_buffer++;
  132.             j++;                                /* Output character count   */
  133.             len--;                              /* Input character count    */
  134.        }
  135.     }
  136.     return j;                                   /* New string length        */
  137. }
  138. /****************************************************************************/
  139. /*                  Calculate the simple JMODEM CRC                         */
  140. /*    Routine obtains a pointer to the buffer of characters to be checked.  */
  141. /*    The first passed parameter is the length of the buffer. The CRC is    */
  142. /*    returned.                                                             */
  143. /*                                                                          */
  144. /****************************************************************************/
  145. unsigned short calc_crc(command, length, buffer)
  146. unsigned short command;                     /* Set or Check CRC             */
  147. unsigned short length;                      /* Buffer length                */
  148. register unsigned char *buffer;             /* Pointer to the buffer        */
  149. {
  150.     unsigned short crc=0;                   /* Start at zero                */
  151.     unsigned short i;                       /* Byte count                   */
  152.  
  153.     if (length <3)                          /* Check for a valid string     */
  154.         return JM_MAX;                      /* Nothing to CRC               */
  155.  
  156.     length -=2;                             /* Don't CRC the CRC            */
  157.     do
  158.     {
  159.     crc += (unsigned short) *buffer++;      /* Sum first                    */
  160.     i = length & 0x07;                      /* 7 bits max to rotate         */
  161.     crc  = _rotl(crc,i);                    /* Rotate i bits left           */
  162.     } while (--length);
  163.  
  164.     switch (command)
  165.     {
  166.         case GET_CRC:
  167.         {
  168.             i =  (unsigned short) *buffer++;
  169.             i |= (unsigned short) (*buffer << 8 );
  170.             return (crc - i);               /* Return AX = 0 if CRC okay    */
  171.         }
  172.         case SET_CRC:
  173.         {
  174.             *buffer++ = (unsigned char) crc;
  175.             *buffer   = (unsigned char) (crc >> 8);
  176.             return crc;                     /* Return CRC though ignored    */
  177.         }
  178.         default:
  179.             return JM_MAX;                  /* Bad data, buffer overflow    */
  180.     }
  181. }
  182. /****************************************************************************/
  183. /************************ E N D  O F   M O D U L E **************************/
  184.