home *** CD-ROM | disk | FTP | other *** search
/ ftp.wwiv.com / ftp.wwiv.com.zip / ftp.wwiv.com / pub / PROTOCOL / JMOD311.ZIP / JMODEM_C.DOC < prev    next >
Text File  |  1992-02-02  |  48KB  |  1,241 lines

  1.  
  2.                                   J M O D E M
  3.                          *  The Microsoft C Version  *
  4.                                November 28, 1991
  5.                                Richard B. Johnson
  6.                               405 Broughton Drive
  7.                           Beverly Massachusetts 01915
  8.                                BBS (508) 922-3166
  9.  
  10.           Introduction.
  11.  
  12.           JMODEM was first introduced about two years ago. It has en-
  13.           joyed a steady increase in popularity around the world. It
  14.           has even been explained in some detail in John Dvorak's book
  15.           on PC communications; Dvorak's Guide to PC Telecommunica-
  16.           tions, 1990, Osborne-McGraw-Hill, 2600 Tenth Street,
  17.           Berkeley, CA.
  18.  
  19.           JMODEM was first written in assembly language. Since this
  20.           language is hard to read and use, it has been difficult for
  21.           communications program developers to incorporate it into
  22.           their programs directly. Instead it must be executed as an
  23.           external protocol. Now JMODEM has been written in the C
  24.           Language. C has become the de-facto standard for portable
  25.           code development even though there isn't presently any code
  26.           that is truly portable across many different machines. The
  27.           writing of JMODEM in C will make it easier for software de-
  28.           velopers throughout the world to use this very useful pro-
  29.           tocol.
  30.  
  31.           You can use this new version of JMODEM just as the older
  32.           versions written in assembly. It has a new color sign-on
  33.           screen and status-block windows that overlap. Although the
  34.           new JMODEM.EXE code is larger than the assembly-language
  35.           version, JMODEM.COM, the program still executes very fast
  36.           because much effort has been taken to streamline the C code.
  37.           JMODEM.COM required 64 k of RAM (one segment) to execute
  38.           properly. JMODEM.EXE requires 79 k to allow the screens to
  39.           be written properly, and 66 k of free RAM to execute without
  40.           aborting although the previous screen content will be lost.
  41.           Like all versions of JMODEM, this version is 100% compatible
  42.           with all previous version including Beta version 1.00. From
  43.           it's inception, the essential structure of JMODEM has never
  44.           been changed.
  45.  
  46.           How to install JMODEM.
  47.  
  48.           JMODEM executes best from a batch file as an external pro-
  49.           tocol for any of the communications programs that have ex-
  50.           ternal-protocol capability. A typical communications program
  51.           is TELIX.
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.                                      - 1 -
  60.                                                JMODEM, the C Version
  61.  
  62.  
  63.  
  64.           Here is a batch file used with TELIX for uploads:
  65.  
  66.           @ECHO OFF
  67.           Rem * JMODEM TELIX Upload batch file.
  68.           C:\TELIX\JMODEM S1 %3
  69.           Rem           | ||  |_________ file name (passed by TELIX)
  70.           Rem           | ||____________ COM port (1 - 4)
  71.           Rem           | |_____________ Send
  72.           Rem           |_______________ Path and name of JMODEM
  73.  
  74.  
  75.           This is a batch file used with TELIX for downloads:
  76.  
  77.           @ECHO OFF
  78.           Rem * JMODEM TELIX Download batch file.
  79.           C:\TELIX\JMODEM R1 %3
  80.           Rem           | ||  |_________ file name (passed by TELIX)
  81.           Rem           | ||____________ COM port (1 - 4)
  82.           Rem           | |_____________ Receive
  83.           Rem           |_______________ Path and name of JMODEM
  84.  
  85.  
  86.           This is a batch file used for PCPLUS (PROCOMM) uploads:
  87.  
  88.           @ECHO OFF
  89.           Rem * JMODEM PCPLUS Upload batch file.
  90.           C:\TELIX\JMODEM S1 %1
  91.           Rem           | ||  |_________ file name (passed by PCPLUS)
  92.           Rem           | ||____________ COM port (1 - 4)
  93.           Rem           | |_____________ Send
  94.           Rem           |_______________ Path and name of JMODEM
  95.  
  96.  
  97.           This is a batch file for PCPLUS (PROCOMM) ownloads:
  98.  
  99.           @ECHO OFF
  100.           Rem * JMODEM PCPLUS Download batch file.
  101.           C:\TELIX\JMODEM R1 %1
  102.           Rem           | ||  |_________ file name (passed by PCPLUS)
  103.           Rem           | ||____________ COM port (1 - 4)
  104.           Rem           | |_____________ Receive
  105.           Rem           |_______________ Path and name of JMODEM
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.  
  116.  
  117.  
  118.                                      - 2 -
  119.                                                JMODEM, the C Version
  120.  
  121.  
  122.           If I wished to receive in the "batch" mode, I could make a
  123.           file like this. Notice that some communications programs do
  124.           not allow multiple file names. Note that the comments "!"
  125.           are NOT ALLOWED in a DOS batch file.
  126.  
  127.                         :DO_LOOP                   ! Return here
  128.                         IF "%3" == "" GOTO DONE    ! More parameters?
  129.                         C:\TELIX\JMODEM R1 %3      ! Execute JMODEM
  130.                         IF ERRORLEVEL 1 GOTO DONE  ! Abort on error
  131.                         SHIFT                      ! %4 becomes %3
  132.                         GOTO DO_LOOP               ! Continue
  133.                         :DONE                      ! Exit batch file
  134.  
  135.           If you do not know what "%" parameters are used to pass the
  136.           file name, all you have to do is make a "dummy" batch file
  137.           that contains the following:
  138.  
  139.                         @ECHO OFF
  140.                         ECHO %1
  141.                         ECHO %2
  142.                         ECHO %3
  143.                         ECHO %4
  144.                         ECHO %5
  145.                         PAUSE
  146.  
  147.           When this is executed, you will see something like this:
  148.  
  149.                 1200
  150.                 1
  151.                 FILENAME.TYP
  152.                 ECHO is off
  153.                 ECHO is off
  154.                 Strike a key when ready . . .
  155.  
  156.           The first line contains "1200" which is the baud rate. This
  157.           means that the %1 parameter contains the baud rate.
  158.  
  159.           The second line contains "1" which is the communications
  160.           adapter port being used. This means that the port is being
  161.           passed as the %2 parameter.
  162.  
  163.           The third line contains "FILENAME.TYP" which is the file
  164.           name. This means that the file name is being passed as the
  165.           %3 parameter.
  166.  
  167.           The fourth and fifth lines contain nothing to echo so DOS
  168.           replies the current state of the echo function which is
  169.           "off".
  170.  
  171.           PCPLUS handles the file name passing a little bit different.
  172.           If I execute the same "dummy" batch file from the PCPLUS
  173.           directory, the response is:
  174.  
  175.  
  176.  
  177.                                      - 3 -
  178.                                                JMODEM, the C Version
  179.  
  180.  
  181.  
  182.                 FILENAME.TYP
  183.                 ECHO is off
  184.                 ECHO is off
  185.                 ECHO is off
  186.                 ECHO is off
  187.                 Strike a key when ready . . .
  188.  
  189.           This shows us that PCPLUS passes the file name as the first
  190.           parameter and there are no other parameters. However, If I
  191.           put more parameters on the command line within PCPLUS, they
  192.           will get sent to the batch file. The response is:
  193.  
  194.                 FILENAME.001
  195.                 FILENAME.002
  196.                 FILENAME.003
  197.                 FILENAME.
  198.                 ECHO is off
  199.                 Strike a key when ready . . .
  200.  
  201.           Therefore PCPLUS allows up to four file names to be passed
  202.           providing there's room on the command line.
  203.  
  204.           Notice that these two communications programs check the
  205.           default directory for the external protocol batch file
  206.           FIRST! Therefore you must make certain that there are no
  207.           other similarly-named batch files in the current directory
  208.           or within the current path. Failure to do so will cause the
  209.           improper execution of the wrong batch file. Lets say that
  210.           the path was "C:\DOS;C:\TOOLS;C:\PCPLUS;C:\TELIX;C:\QMODEM".
  211.           If you named all your JMODEM external protocol batch files
  212.           with the same name, and you were attempting to use an ex-
  213.           ternal file transfer protocol from QMODEM, the batch file
  214.           designed to operate with PCPLUS would be the first one
  215.           "found" and executed since the search-path will search the
  216.           \PCPLUS directory before the \QMODEM directory. You prevent
  217.           the execution of the incorrect batch file by calling them
  218.           slightly different names.
  219.  
  220.           When setting up external protocols, remember to configure
  221.           the communications program so that it prompts you for the
  222.           file names. Unlike some protocols, JMODEM does not transfer
  223.           the file name. You can use any file name that you wish. You
  224.           must pass the file name to JMODEM since it must know the
  225.           name of the file being transmitted or received. There are no
  226.           defaults.
  227.  
  228.           Version V3.09 adds support for absolute port addresses and
  229.           IRQ numbers. This allows one to use multiple boards that use
  230.           strange ports and interrupt levels. This also allows one to
  231.           thoroughly screw up his system by writing to the wrong ports
  232.  
  233.  
  234.  
  235.  
  236.                                      - 4 -
  237.                                                JMODEM, the C Version
  238.  
  239.  
  240.           by accident. JMODEM now accepts:
  241.  
  242.                 JMODEM R(3F8:4) filename.typ
  243.  
  244.                 ... for an input string as well as the generic port
  245.           number. In this case, "3F8" is the hexadecimal port address
  246.           and "4" is the IRQ number. The delimiters are required. Be
  247.           very careful when using this new feature. Writes to incor-
  248.           rect port addresses can destroy the contents of hard disks,
  249.           etc. JMODEM has no way of "knowing" if you give it the wrong
  250.           address to use. The complete input specification for the new
  251.           feature is:
  252.  
  253.                 JMODEM R(2F8:3) filename.typ
  254.                        |   | |  |____________ filename
  255.                        |   | |_______________ IRQ to use
  256.                        |   |_________________ hex port address
  257.                        |_____________________ Receive.
  258.  
  259.                 JMODEM S(2F8:3) filename.typ
  260.                        |   | |  |____________ filename
  261.                        |   | |_______________ IRQ to use
  262.                        |   |_________________ hex port address
  263.                        |_____________________ Send.
  264.  
  265.           There must be no spaces between the "X(YYY:Z)" syntax. This
  266.           means that if your batch file gets its parameters from an
  267.           environment variable, it must be parsed like this:
  268.  
  269.                 JMODEM S(%PORT%:%IRQ%) %3
  270.  
  271.           In this case, the two environment variables would have been
  272.           declared using the DOS "SET" command like:
  273.  
  274.           C:\> SET PORT=3F8
  275.           C:\> SET IRQ=4
  276.  
  277.           There must be no spaces between the "=" and the varable.
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.                                      - 5 -
  296.                                                JMODEM, the C Version
  297.  
  298.  
  299.                             Setting up a BBS System
  300.                         External File-Transfer Protocol.
  301.  
  302.  
  303.           If you are running a WILDCAT! bulletin board, the external
  304.           protocol files can be set up like this:
  305.  
  306.                         (JUP.BAT)
  307.                         CD D:\WILDCAT\PROTOCOL
  308.                         IF EXIST TRANSFER.BAD DEL TRANSFER.BAD
  309.                         JMODEM R1 %3
  310.                         IF ERRORLEVEL 1 GOTO END
  311.                         COPY %3 %4
  312.                         :END
  313.                         DEL %3
  314.  
  315.                         (JDOWN.BAT)
  316.                         CD D:\WILDCAT\PROTOCOL
  317.                         IF EXIST TRANSFER.BAD DEL TRANSFER.BAD
  318.                         JMODEM S1 %3
  319.                         IF ERRORLEVEL 1 GOTO BAD
  320.                         GOTO END
  321.                         :BAD
  322.                         COPY ALL.OK TRANSFER.BAD
  323.                         :END
  324.  
  325.           There are many variations available. Since WILDCAT! supports
  326.           batch-mode downloading, you could set up the batch file like
  327.           this:
  328.  
  329.                         (JDOWN.BAT)
  330.                         CD D:\WILDCAT\PROTOCOL
  331.                         IF EXIST TRANSFER.BAD DEL TRANSFER.BAD
  332.                         :DO_LOOP
  333.                         IF "%3" == "" GOTO END
  334.                         JMODEM S1 %3
  335.                         IF ERRORLEVEL 1 GOTO BAD
  336.                         SHIFT
  337.                         GOTO DO_LOOP
  338.                         :BAD
  339.                         COPY ALL.OK TRANSFER.BAD
  340.                         :END
  341.  
  342.           WILDCAT! checks the \PROTOCOL directory to see if the file
  343.           TRANSFER.BAD has been created. If it exists, it announces
  344.           that the file transfer has failed. It also announces "Error
  345.           with external protocol .. ". It does this when, in fact,
  346.           WILDCAT!  has made an error itself. In many cases WILDCAT!
  347.           will "find" the file TRANSFER.BAD when it DOES NOT EXIST! In
  348.           spite of this bug, WILDCAT! is one of the most reliable BBS
  349.           systems supporting external protocols.
  350.  
  351.  
  352.  
  353.  
  354.                                      - 6 -
  355.                                                JMODEM, the C Version
  356.  
  357.  
  358.  
  359.           When setting up batch files remember that there is also a
  360.           bug in all DOS versions. The "IF ERRORLEVEL " statement does
  361.           NOT test the actual value of ERRORLEVEL! Instead it checks
  362.           to see if the returned value is EQUAL or GREATER than the
  363.           tested value. If you were to put the statement:
  364.  
  365.                         IF ERRORLEVEL 0 GOTO GOOD
  366.  
  367.           .... in a batch file, the execution would ALWAYS branch to
  368.           label "GOOD" regardless of the actual ERRORLEVEL returned!
  369.  
  370.           JMODEM does not require any information about handshaking.
  371.           It will look at the modem port and figure out for itself
  372.           what to do.
  373.  
  374.           In the event that the modem carrier is lost, JMODEM will
  375.           abort. Since JMODEM only checks the modem port occasionally,
  376.           it may take several seconds to abort when the carrier is
  377.           lost. It is impossible for a user to get at the DOS level
  378.           through JMODEM. Do NOT use the CTTY command in the external
  379.           protocol batch files. JMODEM returns ERRORLEVEL 1 if there
  380.           was any error in transmission or reception. It returns
  381.           ERRORLEVEL 0 (no error) otherwise. It does not delete files
  382.           that have been partially received although it properly clos-
  383.           es them. The system operator can arrange the batch files to
  384.           delete them if required.
  385.  
  386.           When JMODEM attempts to create a file that already exists it
  387.           can't ask the user if the old one should be deleted since
  388.           the user is probably not in a terminal program at the time.
  389.           Therefore, JMODEM renames the other file to <filename.OLD>
  390.           and creates the new file. In the event that <filaname.OLD>
  391.           exists, it is deleted before the rename operation occurs.
  392.  
  393.           If you don't know what parameters are being sent to external
  394.           protocols, you can make a dummy batch file to check them
  395.           using the DOS's echo command just as explained in the user
  396.           interface previous to this "BBS" section. You can't see the
  397.           parameters being echoed from a remote terminal. You must be
  398.           present at the BBS board terminal to test those parameters
  399.           unless you modify the dummy command file like this:
  400.  
  401.                         @ECHO OFF
  402.                         ECHO %1>COM1
  403.                         ECHO %2>COM1
  404.                         ECHO %3>COM1
  405.                         ECHO %4>COM1
  406.                         ECHO %5>COM1
  407.  
  408.           If you find that your system passes the file name as %3,
  409.           your "upload" (receive) batch file would contain this:
  410.  
  411.  
  412.  
  413.                                      - 7 -
  414.                                                JMODEM, the C Version
  415.  
  416.  
  417.  
  418.                         JMODEM R1 %3
  419.  
  420.           Your "download" (send) batch file would contain this:
  421.  
  422.                         JMODEM S1 %3
  423.  
  424.           In these examples, it is assumed that you are using
  425.           communications adapter port "1".
  426.  
  427.           You can chop this text out with an editor and create your
  428.           batch files quickly and correctly. PCPLUS passes the file-
  429.           name as the %1 parameter and TELIX uses the %3 parameter.
  430.           JMODEM does not need to know anything else about your system
  431.           to operate. It does not even need to know the baud-rate or
  432.           other communications parameters. All it needs to know about
  433.           is the file name and the communications adapter port to use.
  434.  
  435.           JMODEM doesn't care if you are using a 19,200 baud modem
  436.           with the DTE locked at high-speed or a 300 baud modem on a
  437.           lamp-cord. It is very smart about communications and handles
  438.           lost carriers (hangup) and flow-control in a very simple way
  439.           which will be explained in detail later.
  440.  
  441.           If you only want to try JMODEM without having to install it,
  442.           you need only to activate the JMODEM protocol on a BBS sys-
  443.           tem, then "shell to DOS" and execute it manually from the
  444.           DOS prompt. You will be pleasantly surprised at how rapidly
  445.           it can transfer a file and how well it executes over net-
  446.           works.
  447.  
  448.           How JMODEM works.
  449.  
  450.           JMODEM uses variable-length records called blocks. These
  451.           blocks start with 512 data-bytes and increase in length to a
  452.           maximum of 8192 bytes per block. There is a 6-byte overhead
  453.           associated with each block so the percentage of overhead
  454.           starts at a fairly high 0.1 percent and decreases to a very
  455.           low 0.07 percent as the transmission progresses. The block
  456.           length will increase in 512-byte increments as long as there
  457.           are no errors requiring retransmission. Should an error
  458.           occur, the block-size is cut in half. This continues until
  459.           the block-size is as short as 64 bytes.
  460.  
  461.           The blocks may actually be of any length but never exceed
  462.           the maximum allowed. An attempt is made to reduce the amount
  463.           of data that needs to be transmitted by compressing each
  464.           block before transmission. Since much data is already com-
  465.           pressed, being from ".ZIP" files and such, it is possible
  466.           that "compression" may actually cause an increase in block-
  467.           length. JMODEM will send a compressed block only if it is
  468.           shorter than the non-compressed block.
  469.  
  470.  
  471.  
  472.                                      - 8 -
  473.                                                JMODEM, the C Version
  474.  
  475.  
  476.  
  477.           Since it takes time to compress and expand data, only the
  478.           simplest and quickest compression method is used. It is very
  479.           effective with ".EXE" files that contain large blocks of
  480.           binary nulls and most text files but it is not very effec-
  481.           tive with highly compressed archive files. The compression
  482.           method is called "run-length-limited" or more explicitly
  483.           "how many of what kind". Basically, the block is searched
  484.           for groups if similar characters. If many similar characters
  485.           are found, compression consists of sending a sentinel byte
  486.           of hexadecimal BB, followed by a two-byte amount, and this
  487.           followed by the byte to be repeated.
  488.  
  489.           In the following example we have a string of spaces (20
  490.           hex).
  491.  
  492.           Before compression:
  493.                                ( 18 bytes )
  494.             20 20 20 20 20 20 20 20 20 20 20 34 37 87 EF FF 3A 23
  495.  
  496.  
  497.           After compression:
  498.                                ( 11 bytes )
  499.             BB 0B 00 20 34 37 87 EF FF 3A 23
  500.  
  501.           The blocks could actually get longer because the sentinel
  502.           byte could be present in the data:
  503.  
  504.           Before compression:
  505.                                ( 9 bytes )
  506.             BB 00 BB AF EF BB 00 AE EF
  507.  
  508.  
  509.           After compression:
  510.                                ( 16 bytes )
  511.             BB 01 00 BB 00 BB 01 00 BB AF BB 01 00 BB AE EF
  512.  
  513.           As soon as the encoded length exceeds the data block length,
  514.           compression is abandoned and the non-compressed block is
  515.           sent. JMODEM sends a byte that tells the receiver if the
  516.           data is compressed or not. This same byte tells the receiver
  517.           when the end-of-file has occurred so JMODEM is able to
  518.           preserve exact file-length.
  519.  
  520.                                The JMODEM block.
  521.  
  522.  
  523.  
  524.  
  525.  
  526.  
  527.  
  528.  
  529.  
  530.  
  531.                                      - 9 -
  532.                                                JMODEM, the C Version
  533.  
  534.  
  535.  
  536.           The JMODEM block looks like this:
  537.  
  538.            |< --------- First byte sent / received
  539.           20 00 01 01 .. .. .. .. .. AE 01
  540.            |  |  |  |        |        |  |___ CRC (high byte)
  541.            |  |  |  |        |        |______ CRC (low byte)
  542.            |  |  |  |        |_______________ data bytes
  543.            |  |  |  |________________________ type of block
  544.            |  |  |___________________________ block number
  545.            |  |______________________________ block length (high byte)
  546.            |_________________________________ block length (low byte)
  547.  
  548.  
  549.           The Block length:
  550.  
  551.           The block length is a WORD (16 bits). This allows the blocks
  552.           to be 65,535 bytes long although in practice the length is
  553.           not allowed to exceed 8192 bytes (plus overhead). The block-
  554.           length is the length of the entire JMODEM block, not just
  555.           the data-bytes.
  556.  
  557.           The Block number:
  558.  
  559.           The block number is a BYTE. It starts at 1 and becomes zero
  560.           again after block 255. It is used to make certain that all
  561.           receiption errors are detected.
  562.  
  563.           The Block type:
  564.  
  565.           This BYTE is bit-mapped to tell the receiver what kind of
  566.           block has been sent. Presently there are three kinds of
  567.           blocks:
  568.  
  569.                 00000000B       Hex 00  ( Normal data )
  570.                 00000001B       Hex 01  ( Compressed data )
  571.                 00000010B       Hex 02  ( End of file )
  572.  
  573.           The CRC:
  574.  
  575.           The CRC is a WORD (16 bits). It is not a "standard" type of
  576.           CRC because, unless done with hardware, a standard 16-bit
  577.           polynomial would take several seconds to calculate for a
  578.           long block. Instead it uses a rapid rotate and sum algorithm
  579.           that is probably just as effective as the more "standard"
  580.           polynomials.
  581.  
  582.           The CRC is generated using this polynomial:
  583.  
  584.           X =  X + X^(2(n-mod 7)).......  Where n = t(n-1)
  585.                                          And t = string length
  586.  
  587.  
  588.  
  589.  
  590.                                      - 10 -
  591.                                                JMODEM, the C Version
  592.  
  593.  
  594.  
  595.           It has the advantage of simplicity in assembly-language
  596.           programming and will detect errors with a probability of
  597.           about  one undetected error in 2^132 (which is a very large
  598.           number). It does not correct errors so its not important to
  599.           use some "standard" function to generate the CRC.
  600.  
  601.           The C code shows how easy it is to create and check this
  602.           kind of CRC.
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642.  
  643.  
  644.  
  645.  
  646.  
  647.  
  648.  
  649.                                      - 11 -
  650.                                                JMODEM, the C Version
  651.  
  652.  
  653.                            The JMODEM Communications
  654.                                 Hardware Control
  655.  
  656.           When JMODEM is first loaded for execution it checks the
  657.           state of the modem-control leads. If there is no modem
  658.           carrier detected, it assumes that you have connected two PCs
  659.           together without a modem and will not bother to check for a
  660.           dropped carrier during execution.
  661.  
  662.           Since JMODEM must exercise flow-control so it can be used
  663.           with high-speed modems with fixed baud rates, it also as-
  664.           sumes that at the time at which it is first executed, the
  665.           modem will be requesting data because there will have been
  666.           very little I/O over the previous few seconds. JMODEM stores
  667.           the state of RTS/CTS and DTR/DSR and uses this as a refer-
  668.           ence. When transmitting data, should JMODEM find that the
  669.           state of these modem-control leads has changed, it waits
  670.           until the modem-control leads have reverted back to the
  671.           initial state before sending any more data. This allows ANY
  672.           modem to exercise flow-control with JMODEM, even those that
  673.           use "pin 4" instead of "pin 20". When JMODEM is waiting, it
  674.           checks to verify that the modem carrier has not been drop-
  675.           ped. If the carrier is dropped, or if the user aborts,
  676.           JMODEM will exit, setting a DOS ERRORLEVEL code.
  677.  
  678.           You can abort JMODEM at any time by hitting Ctrl-Break or
  679.           Ctrl-C. It will take several seconds for JMODEM to abort
  680.           because it does not continually check these keys. Unlike
  681.           previous versions, JMODEM erases the files from aborted
  682.           downloads. Also, JMODEM will abort if it is unable to rename
  683.           a file in the following example.
  684.  
  685.           Suppose you wish to download a file called VIRUS.EXE. Sup-
  686.           pose also that VIRUS.EXE already exists. Instead of over-
  687.           writing your previous version of VIRUS.EXE, JMODEM has al-
  688.           ways been nice and renamed it to VIRUS.OLD before creating a
  689.           new file. With previous versions of JMODEM, if VIRUS.OLD
  690.           already existed, JMODEM would have deleted it before renam-
  691.           ing the present file to ".OLD". This no longer is done.
  692.           JMODEM never deletes ANYTHING anymore except it's own abort-
  693.           ed download. This should reduce the number of threats I have
  694.           received!
  695.  
  696.  
  697.  
  698.  
  699.  
  700.  
  701.  
  702.  
  703.  
  704.  
  705.  
  706.  
  707.  
  708.                                      - 12 -
  709.                                                JMODEM, the C Version
  710.  
  711.  
  712.                                The C programmer's
  713.                                 Guide to JMODEM
  714.  
  715.           Included within this package should be the following files:
  716.           JMODEM         This is a Microsoft MAKE file for JMODEM.EXE.
  717.           JMODEMTC       Borland's Turbo C MAKE file for JMODEM.EXE.
  718.           JMODEM    EXE  The executable file
  719.           JMODEMTC  RSP  Link response file for Borland's Turbo C
  720.           JMODEM_A  C    Contains the _main() routine entry point.
  721.           JMODEM_B  C    Parses input strings.
  722.           JMODEM_C  C    All of the file I/O is in this file.
  723.           JMODEM_D  C    Data compression/expansion, CRC calculation
  724.           JMODEM_E  C    Communications I/O interrupt service, etc.
  725.           JMODEM_F  C    Screen I/O (windows, etc)
  726.           JMODEM_G  ASM  Interrupt service routines (after V2.00)
  727.           JMODEM    H    Contains JMODEM globals and data structures.
  728.           SCREEN    H    Screen definitions, prototypes, structures
  729.           UART      H    Definitions for the 8250 UART
  730.           TEST      C    This tests compression /expansion, disk I/O.
  731.           TEST           This is the Microsoft MAKE file for TEST.EXE
  732.           TESTTC         Borland's Turbo C MAKE file for TEST.EXE
  733.           SHOW      C    Source for verifying execution in a DOS shell
  734.           SHOW           Microsoft MAKE file for SHOW.EXE
  735.           SHOWTC         Borland's Turbo C MAKE file for SHOW.EXE
  736.           SHOW      EXE  Executes JMODEM from a DOS shell.
  737.           TEST      C    Tests JMODEM data-compression and file I/O.
  738.           TEST           Microsoft MAKE file for TEST.EXE
  739.           TESTTC         Borland's Turbo C MAKE file for TEST.EXE
  740.           TEST      EXE  Executable to test file I/O and compression
  741.  
  742.           If you have MicroSoft 'C' version 5.0 or later, and if your
  743.           environment and paths are properly set up, you should be
  744.           able to type:
  745.  
  746.                 MAKE JMODEM
  747.                 ... and a brand new version of JMODEM will be created.
  748.  
  749.           If you use Borland's Turbo C, you can use the "TC" make
  750.           files to do the same.
  751.  
  752.           Brad Smith from Jacksonville North Carolina created the MAKE
  753.           files for Turbo C and modified the source-code to accommo-
  754.           date the different libraries used in Turbo C. His revisions
  755.           will be present in all subsequent versions of JMODEM to
  756.           assure compatibility with Borland's Turbo C.
  757.  
  758.           Brad is a Turbo C guru and runs a BBS system in
  759.           Jacksonville.
  760.  
  761.                 Brad Smith
  762.                 141 Riggs Street
  763.                 Jacksonville, North Carolina 28540
  764.                 BBS (919) 455-5972 12/24/9600+ 24 hrs
  765.  
  766.  
  767.                                      - 13 -
  768.                                                JMODEM, the C Version
  769.  
  770.  
  771.  
  772.           With this release, there seems to be a Null-Pointer
  773.           assignment error when using Borland's Small Model in TCC
  774.           Version 1.5. This is a compiler bug, or more specifically a
  775.           bug in the C0.ASM code provided with the compiler that you
  776.           can fix.
  777.  
  778.           If you are a Turbo C programmer, don't use the small model
  779.           when creating JMODEM.EXE unless you repair the C0.ASM file
  780.           and create a new C0S.OBJ file using the MAKE-C0.BAT file
  781.           that is provided with the compiler.
  782.  
  783.           To fix the null-pointer problem in Turbo-C find the
  784.           following code-fragment in \LIB\C0.ASM provided with your
  785.           compiler:
  786.  
  787.           IFNDEF        __HUGE__
  788.  
  789.           ;     Reset un-initialized datas
  790.  
  791.                         xor     ax, ax
  792.                         mov     es, cs:DGROUP@@
  793.                         mov     di, offset DGROUP: bdata@
  794.                         mov     cx, offset DGROUP: edata@
  795.                         sub     cx, di
  796.                 rep     stosb
  797.           ENDIF
  798.  
  799.           Add the following code:
  800.  
  801.                 push    ds
  802.                 mov     ax,DGROUP
  803.                 mov     ds,ax
  804.                 mov     word ptr ds:[0],0
  805.                 pop     ds
  806.  
  807.  
  808.           Now find this next code-fragment:
  809.  
  810.                         xor     ax, ax
  811.                         mov     si, ax
  812.                         mov     cx, lgth_CopyRight
  813.                         cld
  814.           ComputeChecksum label near
  815.                         add     al, [si]
  816.                         adc     ah, 0
  817.                         inc     si
  818.                         loop    ComputeChecksum
  819.                         sub     ax, CheckSum
  820.                         jz      ExitToDOS
  821.                         mov     cx, lgth_NullCheck
  822.  
  823.  
  824.  
  825.  
  826.                                      - 14 -
  827.                                                JMODEM, the C Version
  828.  
  829.  
  830.                         mov     dx, offset DGROUP: NullCheck
  831.                         call    ErrorDisplay
  832.  
  833.           Modify the code so it looks like this:
  834.  
  835.           ;             xor     ax, ax
  836.           ;             mov     si, ax
  837.           ;             mov     cx, lgth_CopyRight
  838.           ;             cld
  839.           ;ComputeChecksum label        near
  840.           ;             add     al, [si]
  841.           ;             adc     ah, 0
  842.           ;             inc     si
  843.           ;             loop    ComputeChecksum
  844.           ;             sub     ax, CheckSum
  845.  
  846.                 push    ds
  847.                 mov     ax,DGROUP
  848.                 mov     ds,ax
  849.                 cmp     word ptr ds:[0],0
  850.                 pop     ds
  851.  
  852.                         jz      ExitToDOS
  853.                         mov     cx, lgth_NullCheck
  854.                         mov     dx, offset DGROUP: NullCheck
  855.                         call    ErrorDisplay
  856.  
  857.  
  858.           After to have done this, execute MAKE-C0.BAT for the small
  859.           model library from the DOS prompt:
  860.  
  861.           F:\TURBOC\LIB> MAKE-C0 SMALL
  862.  
  863.           This will create a new small-model startup object file.
  864.  
  865.           Just as in the MASM language files, the source code is
  866.           strongly-typed. All function prototypes are declared and no
  867.           defaults are used. You can compile at warning-level 4, the
  868.           most stringent level available with Microsoft compilers, and
  869.           you will get no warning errors at all. The default warning
  870.           level with Borland's compiler is even more stringent. You
  871.           will get a single warning error when compiling TEST.C as the
  872.           compiler discovers that dummy parameter "one" in the dummy
  873.           screen routine isn't used at all. It has been my experience
  874.           that if you get any warnings (in real code), they MUST be
  875.           fixed or they will bite you later on.
  876.  
  877.           Example:
  878.                         *memory++ = foo;
  879.                 ... will bump the memory pointer after you put foo
  880.                 into memory. Suppose you get to the end of the block
  881.  
  882.  
  883.  
  884.  
  885.                                      - 15 -
  886.                                                JMODEM, the C Version
  887.  
  888.  
  889.                 and wish to index backwards.
  890.  
  891.                 Do you use ...
  892.                         --*memory = foo;
  893.                 ...?
  894.  
  895.                 You do NOT!! You must use:
  896.  
  897.                         *(--memory) = foo;
  898.  
  899.           Little things like this (this is a BIG, BIG bug), could
  900.           cause code to work <sometimes> and keep you awake nights.
  901.           JMODEM has been carefully written to prevent bugs like this.
  902.           It is impossible to be sure that there are no bugs in even
  903.           simple code so be careful if you modify the source.
  904.  
  905.           You may modify JMODEM for your own use, but  P L E A S E  do
  906.           NOT distribute the modified version on BBS systems because I
  907.           do not wish to support 222,500 versions of JMODEM! If you
  908.           find a bug, or wish to improve or add something that will
  909.           increase the value of JMODEM without making it incompatible
  910.           with previous versions, please upload your improvements to
  911.           my BBS system and I may include the revisions (with your
  912.           name attached) in an upcoming version. Note that there are 6
  913.           "type" bits available in the JMODEM control-byte that could
  914.           be used to tell the receiver that another file is coming,
  915.           etc., (for batch). Things like this could be added without
  916.           destroying compatibility with previous versions.
  917.  
  918.           MicroSoft C seems to have several bugs one of which affects
  919.           files that are very long (over 256k). My first attempts to
  920.           use C files under MicroSoft for JMODEM used the stream-I/O
  921.           (FILE *) type of files. This resulted in corruption of long
  922.           files. Therefore I implemented the UNIX/DOS type of file-I/O
  923.           that uses handles rather than file-control blocks. These
  924.           work rather well.
  925.  
  926.           Starting with Version V3.06, The JMODEM distribution file
  927.           will no longer contain the old JMODEM.ASM source. This is to
  928.           reduce the download time. The C version is now mature enough
  929.           so that there is little or no difference between the per-
  930.           formance of JMODEM.COM, the assembly version, and
  931.           JMODEM.EXE, the C version. The original C version was about
  932.           25 k in length. It is now only about 14.
  933.  
  934.           Floating point:
  935.  
  936.           Originally no floating-point libraries were used. The de-
  937.           fault is still not to use any because they result in doubl-
  938.           ing the size of the code. Some persons have complained that
  939.           the speed (cps) indication is not very accurate. This is
  940.  
  941.  
  942.  
  943.  
  944.                                      - 16 -
  945.                                                JMODEM, the C Version
  946.  
  947.  
  948.           true because of the granularity of the time returned from
  949.           DOS (one second). If you add /DFTIME to the command-line
  950.           used to compile JMODEM_A.C in the "MAKE" file, the compiler
  951.           will use floating-point routines for the speed calculation.
  952.           The resulting JMODEM.EXE will be about 35k in length,
  953.           though, so this is a trade-off. If you wish accurate timing,
  954.           you pay for it in much-increased code-size.
  955.  
  956.           Modems:
  957.  
  958.           When JMODEM gets control, it turns ON CTS and DSR just in
  959.           case the BBS program has turned them off (WILDCAT does).
  960.           Some modems "hiccup" when this occurs, and the RTS line will
  961.           bounce. This caused JMODEM to "wait forever" for a RTS that
  962.           never occurs. Therefore I added a 1/2 second delay between
  963.           the time that I first set these bits and the time I start
  964.           checking for RTS and RLSD for flow-control and a possible
  965.           abort. This fixed this problem. The flow-control problem is
  966.           complex because user's might wish to transfer files between
  967.           two computers using only three wires. In such a case, there
  968.           is no flow-control and there is no modem carrier. To accom-
  969.           modate a universal solution to various hookups, JMODEM
  970.           checks for the state of DSR/CTS and RLSD when it first gets
  971.           control. If there is no carrier at this time, JMODEM will
  972.           not check for an aborted carrier during transmission or
  973.           reception. If JMODEM detects a CHANGE in either DSR or CTS,
  974.           it assumes this is flow-control and waits for these bits to
  975.           change back to whatever they were when JMODEM first obtained
  976.           control. This protocol has been used successfully since the
  977.           very first version of JMODEM. There is, however, a pos-
  978.           sibility of JMODEM wrongly interpreting what it finds if
  979.           there is "bounce" when it first gets control. That's the
  980.           reason for the delay. In any event, the normal "timeout"
  981.           trap will prevent a hung system.
  982.  
  983.           BBS systems:
  984.  
  985.           JMODEM still gets blamed for crashing some BBS systems even
  986.           though it is not JMODEM's fault. A common problem occurs
  987.           with systems that use compiled BASIC. Some BBS system pro-
  988.           grams assume certain characteristics about external proto-
  989.           cols and will blow up when the assumption is wrong. If you
  990.           use BASIC code that works like this:
  991.  
  992.                 PROTOSEND$ = "JMODEM S1 "
  993.                 COMSTRING$ = PROTOSEND$+FILENAME$
  994.  
  995.                 SHELL COMSTRING$
  996.  
  997.                 ... Then JMODEM (and other protocols) will work okay.
  998.  
  999.  
  1000.  
  1001.  
  1002.  
  1003.                                      - 17 -
  1004.                                                JMODEM, the C Version
  1005.  
  1006.  
  1007.           However, If you attempt to BLOAD, CALL, or CHAIN to it, the
  1008.           results will be indeterminate. This is because JMODEM
  1009.           allocates memory from C runtime routines that get their
  1010.           memory from DOS (not BASIC). BASIC will not "know" that its
  1011.           memory has been used by the external protocol. If you exe-
  1012.           cute the "SHELL" command, then you force BASIC to give up
  1013.           all the memory that it can afford to spare. This free memory
  1014.           is recorded by DOS and can be used for the external proto-
  1015.           col.
  1016.  
  1017.           BBS systems written is C should execute external protocols
  1018.           something like this:
  1019.  
  1020.                 strcpy(command_line,"JMODEM S1 FILENAME");
  1021.                 system (command_line);
  1022.  
  1023.           The C "system" command executes DOS commands from within C
  1024.           programs by freeing memory and then executing COMMAND.COM.
  1025.           Some C compilers don't have to load an aditional copy of
  1026.           COMMAND.COM. They use an undocumented "back-door" to the
  1027.           existing command interpreter! This saves memory.
  1028.  
  1029.           This is a sneak preview of the undocumented procedure:
  1030.  
  1031.           MOV   WORD PTR [SP_SAV],SP    ; Put the SP in a safe place
  1032.           MOV   WORD PTR [SS_SAV],SS    ; Save segment registers.
  1033.           MOV   WORD PTR [DS_SAV],DS
  1034.           MOV   WORD PTR [ES_SAV],ES
  1035.           MOV   AX,4A00H                ; Free memory
  1036.           MOV   BX,OFFSET TOP           ; Point to the top of code
  1037.           MOV   CL,4                    ; Bits to shift
  1038.           SHR   BX,CL                   ; Div / 16
  1039.           INC   BX                      ; Round up
  1040.           INT   21H                     ; Free some memory
  1041.           ;
  1042.           MOV   SI,OFFSET COMMAND       ; Point to the command
  1043.           INT   2EH                     ; Make the undocumented call
  1044.           CLI                           ; No interrupts, cleaning up
  1045.           MOV   DS,WORD PTR CS:[DS_SAV] ; Restore all segments
  1046.           MOV   ES,WORD PTR [DS_SAV]
  1047.           MOV   SS,WORD PTR [SS_SAV]
  1048.           MOV   SP,WORD PTR [SP_SAV]    ; Restore stack pointer
  1049.           STI                           ; Allow interrupts
  1050.  
  1051.           If JMODEM and other external protocols are executed from BBS
  1052.           software in this manner, then you will have no problems.
  1053.           JMODEM preserves the BBS system communications environment
  1054.           so BBS systems don't have to reinitialize anything when they
  1055.           get control. JMODEM does not even touch the baud rate! Its
  1056.           not necessary to alter any communications parameters so it
  1057.           doesn't.
  1058.  
  1059.  
  1060.  
  1061.  
  1062.                                      - 18 -
  1063.                                                JMODEM, the C Version
  1064.  
  1065.  
  1066.  
  1067.           A small program, SHOW.C is provided with this distribution.
  1068.           It is a C program that allocates a lot of memory, writes to
  1069.           the memory, then executes JMODEM.EXE using the "system"
  1070.           command. After JMODEM returns from the shell, SHOW then
  1071.           continues to write to memory before exiting. Since this
  1072.           procedure is properly written, no system crash will occur.
  1073.           You can load multiple copies of COMMAND.COM to "eat" memory.
  1074.           Eventually there will be too little memory available for
  1075.           JMODEM to execute. The system will still not crash.
  1076.  
  1077.           Help:
  1078.  
  1079.           JMODEM is now over three years old. I first wrote it in
  1080.           assembly and slowly it caught on. I spent last Christmas
  1081.           writing it in C. Since the C release, I have received over
  1082.           500 comments from persons telling me how to make it better.
  1083.           Most of these comments were from so-called professional
  1084.           programmers who complained about various things. Others
  1085.           complained about the comments I made about them in this
  1086.           document <grin>.
  1087.  
  1088.           Please remember that an enhancement is not a "preference".
  1089.           If you prefer to do something one way or another then feel
  1090.           free to modify the code for your own use. If you find a
  1091.           better way to do something then please let me know.
  1092.  
  1093.  
  1094.  
  1095.  
  1096.  
  1097.  
  1098.  
  1099.  
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110.  
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.  
  1118.  
  1119.  
  1120.  
  1121.                                      - 19 -
  1122.                                                JMODEM, the C Version
  1123.  
  1124.  
  1125.                             JMODEM revision history
  1126.  
  1127.           The revision history has been moved to JMODEM_A.C and to
  1128.           JMODEM.H (identical copies). This makes it easier to keep
  1129.           the documentation current.
  1130.  
  1131.           Version V3.09 adds support for absolute port addresses and
  1132.           IRQ numbers. This allows one to use multiple boards that use
  1133.           strange ports and interrupt levels. This also allows one to
  1134.           thoroughly screw up his system by writing to the wrong ports
  1135.           by accident. JMODEM now accepts:
  1136.  
  1137.                 JMODEM R(3F8:4) filename.typ
  1138.  
  1139.                 ... for an input string as well as the generic port
  1140.           number. In this case, "3F8" is the hexadecimal port address
  1141.           and "4" is the IRQ number. The delimiters are required.
  1142.  
  1143.           Version V3.08 does not do anything except make the code
  1144.           comply with Microsoft's interpretation of the ANSI standard
  1145.           so it will compile at their new "warning-level /W4" without
  1146.           any warning errors. Jeff Jevnisek warned me about the new
  1147.           C600 compiler and I had to go out and buy it. He also mod-
  1148.           ified the code to be "Microsoft compliant" so, as usual,
  1149.           there are no warning errors when compiling.
  1150.  
  1151.           Microsoft, supplying over 80 percent of the 'C' compilers in
  1152.           use for the PC environment, is a force that must be accom-
  1153.           modated even though they are < W R O N G >, damned wrong!
  1154.           Here's an example of what they now REQUIRE to pass their
  1155.           "warning-level 4" test:
  1156.  
  1157.           Given this CORRECT code....
  1158.  
  1159.           short function (param)
  1160.           short param;
  1161.           {
  1162.               return param;
  1163.           }
  1164.  
  1165.           ... we now need this:
  1166.  
  1167.           short function (short param)
  1168.           {
  1169.               return param;
  1170.           }
  1171.  
  1172.           ANSI allowed (read ALLOWED) the inclusion of the object size
  1173.           (type) within the parameter list to facilitate making the
  1174.           parser for the compiler. With the "old-style" method, the
  1175.           size of the object was not known until the next line was
  1176.  
  1177.  
  1178.  
  1179.  
  1180.                                      - 20 -
  1181.                                                JMODEM, the C Version
  1182.  
  1183.  
  1184.           read so the compiler had to store the previous variable
  1185.           names (such a pity) until it got to the line that represent-
  1186.           ed the size and type of the object. Microsoft was one of the
  1187.           ANSI committee representatives that insisted upon the allow-
  1188.           ance for including this information within the parameter
  1189.           list. It was ALLOWED by the committee. Now anything not in
  1190.           conformance with Microsoft's WISH is flagged as an error!
  1191.  
  1192.           The second problem is that the NULL object (not anything
  1193.           having to do with ANSI) was previously a generic VALUE of
  1194.           zero that could be assigned to any size object including
  1195.           pointers of all types, ASCII string terminators, etc. This
  1196.           is no longer the case. One must cast it to the appropriate
  1197.           type before use!! I got rid of all references to NULL
  1198.           because it no longer has the required special character-
  1199.           istics.
  1200.  
  1201.           - finis -
  1202.  
  1203.  
  1204.  
  1205.  
  1206.  
  1207.  
  1208.  
  1209.  
  1210.  
  1211.  
  1212.  
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.  
  1221.  
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  
  1227.  
  1228.  
  1229.  
  1230.  
  1231.  
  1232.  
  1233.  
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.                                      - 21 -
  1240.  
  1241.