mfeberhard
Member
For all you users of my CP/M Xmodem program, I’ve just released a new version, version 2.10. This version corrects a long-standing bug. Here’s a wordy description of the bug:
Xmodem versions prior to 2.10 would fail in some cases during reception with checksums, with a "Can't Sync" error, if XMODEM was started before the sender (e.g. TeraTerm) was started. Xmodem will send a NAK every few seconds to tell the sender to start sending, and to use checksums (rather than CRCs). Xmodem will do this until it receives any byte from the sender. Before sending the file, TeraTerm attempts to flush its serial port to get rid of any stray NAKs by repeatedly reading from its serial port until the serial port indicates that it has no data available. This will normally flush out any accumulated NAKs that Xmodem sent while trying to establish connection for file reception using checksums. However, this fails if the PC hardware or OS does not immediately report that a new character is waiting after TeraTerm's flush loop reads a NAK. The result will be an extra NAK in its serial port buffer, causing TeraTerm to resend the first block. This will cause an Xmodem synchronization error later on, the first time that Xmodem holds off ACKing a block (e.g. to write to disk) because there will be an extra ACK in the queue. The solution (in Xmodem version 2.10) is to wait to see if the serial port is idle for a half second after the very first block. If not, then Xmodem will receive the resent block 1 without having sent an ACK for the first one. From there on, synchronization is correct.
While I was at it, I corrected a typo in that “Can’t Sync” error message, and I replaced my PDEC16 subroutine (which prints a 16-bit value in decimal) with a really slick and extremely compact recursive subroutine that was written by Bill Gates back when he was still writing code. For you assembly language nerds, take a look at that subroutine an see if you can understand how it works
I love it!
Note that the file that's called Xmodem.cpm needs to be renamed Xmodem.com once it's on your CP/M machine.
Please try it out, tell me if I broke anything!!!
-Martin
Xmodem versions prior to 2.10 would fail in some cases during reception with checksums, with a "Can't Sync" error, if XMODEM was started before the sender (e.g. TeraTerm) was started. Xmodem will send a NAK every few seconds to tell the sender to start sending, and to use checksums (rather than CRCs). Xmodem will do this until it receives any byte from the sender. Before sending the file, TeraTerm attempts to flush its serial port to get rid of any stray NAKs by repeatedly reading from its serial port until the serial port indicates that it has no data available. This will normally flush out any accumulated NAKs that Xmodem sent while trying to establish connection for file reception using checksums. However, this fails if the PC hardware or OS does not immediately report that a new character is waiting after TeraTerm's flush loop reads a NAK. The result will be an extra NAK in its serial port buffer, causing TeraTerm to resend the first block. This will cause an Xmodem synchronization error later on, the first time that Xmodem holds off ACKing a block (e.g. to write to disk) because there will be an extra ACK in the queue. The solution (in Xmodem version 2.10) is to wait to see if the serial port is idle for a half second after the very first block. If not, then Xmodem will receive the resent block 1 without having sent an ACK for the first one. From there on, synchronization is correct.
While I was at it, I corrected a typo in that “Can’t Sync” error message, and I replaced my PDEC16 subroutine (which prints a 16-bit value in decimal) with a really slick and extremely compact recursive subroutine that was written by Bill Gates back when he was still writing code. For you assembly language nerds, take a look at that subroutine an see if you can understand how it works
Note that the file that's called Xmodem.cpm needs to be renamed Xmodem.com once it's on your CP/M machine.
Please try it out, tell me if I broke anything!!!
-Martin