home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / MODEM / JMOD309.ZIP / JMODEM_C.DOC < prev    next >
Encoding:
Text File  |  1991-07-06  |  46.3 KB  |  1,240 lines

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