📄 jmodem_c.doc
字号:
JMODEM.EXE, the C version. The original C version was about
25 k in length. It is now only about 14.
Floating point:
Originally no floating-point libraries were used. The de-
fault is still not to use any because they result in doubl-
ing the size of the code. Some persons have complained that
the speed (cps) indication is not very accurate. This is
- 16 -
JMODEM, the C Version
true because of the granularity of the time returned from
DOS (one second). If you add /DFTIME to the command-line
used to compile JMODEM_A.C in the "MAKE" file, the compiler
will use floating-point routines for the speed calculation.
The resulting JMODEM.EXE will be about 35k in length,
though, so this is a trade-off. If you wish accurate timing,
you pay for it in much-increased code-size.
Modems:
When JMODEM gets control, it turns ON CTS and DSR just in
case the BBS program has turned them off (WILDCAT does).
Some modems "hiccup" when this occurs, and the RTS line will
bounce. This caused JMODEM to "wait forever" for a RTS that
never occurs. Therefore I added a 1/2 second delay between
the time that I first set these bits and the time I start
checking for RTS and RLSD for flow-control and a possible
abort. This fixed this problem. The flow-control problem is
complex because user's might wish to transfer files between
two computers using only three wires. In such a case, there
is no flow-control and there is no modem carrier. To accom-
modate a universal solution to various hookups, JMODEM
checks for the state of DSR/CTS and RLSD when it first gets
control. If there is no carrier at this time, JMODEM will
not check for an aborted carrier during transmission or
reception. If JMODEM detects a CHANGE in either DSR or CTS,
it assumes this is flow-control and waits for these bits to
change back to whatever they were when JMODEM first obtained
control. This protocol has been used successfully since the
very first version of JMODEM. There is, however, a pos-
sibility of JMODEM wrongly interpreting what it finds if
there is "bounce" when it first gets control. That's the
reason for the delay. In any event, the normal "timeout"
trap will prevent a hung system.
BBS systems:
JMODEM still gets blamed for crashing some BBS systems even
though it is not JMODEM's fault. A common problem occurs
with systems that use compiled BASIC. Some BBS system pro-
grams assume certain characteristics about external proto-
cols and will blow up when the assumption is wrong. If you
use BASIC code that works like this:
PROTOSEND$ = "JMODEM S1 "
COMSTRING$ = PROTOSEND$+FILENAME$
SHELL COMSTRING$
... Then JMODEM (and other protocols) will work okay.
- 17 -
JMODEM, the C Version
However, If you attempt to BLOAD, CALL, or CHAIN to it, the
results will be indeterminate. This is because JMODEM
allocates memory from C runtime routines that get their
memory from DOS (not BASIC). BASIC will not "know" that its
memory has been used by the external protocol. If you exe-
cute the "SHELL" command, then you force BASIC to give up
all the memory that it can afford to spare. This free memory
is recorded by DOS and can be used for the external proto-
col.
BBS systems written is C should execute external protocols
something like this:
strcpy(command_line,"JMODEM S1 FILENAME");
system (command_line);
The C "system" command executes DOS commands from within C
programs by freeing memory and then executing COMMAND.COM.
Some C compilers don't have to load an aditional copy of
COMMAND.COM. They use an undocumented "back-door" to the
existing command interpreter! This saves memory.
This is a sneak preview of the undocumented procedure:
MOV WORD PTR [SP_SAV],SP ; Put the SP in a safe place
MOV WORD PTR [SS_SAV],SS ; Save segment registers.
MOV WORD PTR [DS_SAV],DS
MOV WORD PTR [ES_SAV],ES
MOV AX,4A00H ; Free memory
MOV BX,OFFSET TOP ; Point to the top of code
MOV CL,4 ; Bits to shift
SHR BX,CL ; Div / 16
INC BX ; Round up
INT 21H ; Free some memory
;
MOV SI,OFFSET COMMAND ; Point to the command
INT 2EH ; Make the undocumented call
CLI ; No interrupts, cleaning up
MOV DS,WORD PTR CS:[DS_SAV] ; Restore all segments
MOV ES,WORD PTR [DS_SAV]
MOV SS,WORD PTR [SS_SAV]
MOV SP,WORD PTR [SP_SAV] ; Restore stack pointer
STI ; Allow interrupts
If JMODEM and other external protocols are executed from BBS
software in this manner, then you will have no problems.
JMODEM preserves the BBS system communications environment
so BBS systems don't have to reinitialize anything when they
get control. JMODEM does not even touch the baud rate! Its
not necessary to alter any communications parameters so it
doesn't.
- 18 -
JMODEM, the C Version
A small program, SHOW.C is provided with this distribution.
It is a C program that allocates a lot of memory, writes to
the memory, then executes JMODEM.EXE using the "system"
command. After JMODEM returns from the shell, SHOW then
continues to write to memory before exiting. Since this
procedure is properly written, no system crash will occur.
You can load multiple copies of COMMAND.COM to "eat" memory.
Eventually there will be too little memory available for
JMODEM to execute. The system will still not crash.
Help:
JMODEM is now over three years old. I first wrote it in
assembly and slowly it caught on. I spent last Christmas
writing it in C. Since the C release, I have received over
500 comments from persons telling me how to make it better.
Most of these comments were from so-called professional
programmers who complained about various things. Others
complained about the comments I made about them in this
document <grin>.
Please remember that an enhancement is not a "preference".
If you prefer to do something one way or another then feel
free to modify the code for your own use. If you find a
better way to do something then please let me know.
- 19 -
JMODEM, the C Version
JMODEM revision history
The revision history has been moved to JMODEM_A.C and to
JMODEM.H (identical copies). This makes it easier to keep
the documentation current.
Version V3.09 adds support for absolute port addresses and
IRQ numbers. This allows one to use multiple boards that use
strange ports and interrupt levels. This also allows one to
thoroughly screw up his system by writing to the wrong ports
by accident. JMODEM now accepts:
JMODEM R(3F8:4) filename.typ
... for an input string as well as the generic port
number. In this case, "3F8" is the hexadecimal port address
and "4" is the IRQ number. The delimiters are required.
Version V3.08 does not do anything except make the code
comply with Microsoft's interpretation of the ANSI standard
so it will compile at their new "warning-level /W4" without
any warning errors. Jeff Jevnisek warned me about the new
C600 compiler and I had to go out and buy it. He also mod-
ified the code to be "Microsoft compliant" so, as usual,
there are no warning errors when compiling.
Microsoft, supplying over 80 percent of the 'C' compilers in
use for the PC environment, is a force that must be accom-
modated even though they are < W R O N G >, damned wrong!
Here's an example of what they now REQUIRE to pass their
"warning-level 4" test:
Given this CORRECT code....
short function (param)
short param;
{
return param;
}
... we now need this:
short function (short param)
{
return param;
}
ANSI allowed (read ALLOWED) the inclusion of the object size
(type) within the parameter list to facilitate making the
parser for the compiler. With the "old-style" method, the
size of the object was not known until the next line was
- 20 -
JMODEM, the C Version
read so the compiler had to store the previous variable
names (such a pity) until it got to the line that represent-
ed the size and type of the object. Microsoft was one of the
ANSI committee representatives that insisted upon the allow-
ance for including this information within the parameter
list. It was ALLOWED by the committee. Now anything not in
conformance with Microsoft's WISH is flagged as an error!
The second problem is that the NULL object (not anything
having to do with ANSI) was previously a generic VALUE of
zero that could be assigned to any size object including
pointers of all types, ASCII string terminators, etc. This
is no longer the case. One must cast it to the appropriate
type before use!! I got rid of all references to NULL
because it no longer has the required special character-
istics.
- finis -
- 21 -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -