YMODEMは、モデムを介して接続されたマイクロコンピュータ間でファイル転送を行うためのプロトコルです。主に電子掲示板システムとの間でファイルを転送するために使用されていました。YMODEMは、 XMODEMの拡張版としてチャック・フォースバーグによって開発され、彼のCP/M用YAMプログラムに初めて実装されました。当初はYAMとしても知られていましたが、1985年にオリジナルのXMODEMの作者であるワード・クリステンセンによって正式に「YMODEM」という名前が付けられました。
YMODEMは、他の拡張XMODEM規格に見られる機能を組み合わせ、XMODEMを3つの点で拡張しました。XMODEM-CRCと同様に、YMODEMは8ビットのチェックサムを16ビットの巡回冗長検査(CRC)に置き換えましたが、これをオプションではなくデフォルトの訂正方法としました。TeLinkから、ファイル名とサイズを送信する「ブロック0」ヘッダーを追加し、バッチ転送(1回のセッションで複数のファイルを転送)を可能にし、ファイルの末尾にパディングを追加する必要性をなくしました。最後に、YMODEMは、 XMODEM-1kと同様に、ブロックサイズを元の128バイトから1024バイトに増やすことが可能になり、高速モデムでのスループットが大幅に向上しました。
フォルスバーグは、これらの機能をすべてランタイムオプションとして標準規格を構築し、単一のプロトコルドライバが非YAMシステムに接続する際にXMODEM-CRCまたはXMODEMにフォールバックできるようにしました。彼は、プログラマが可能な限り多くの機能を任意のプラットフォームで実装したいと考えるだろうと考えていました。しかし、実装の大部分が実際にはCRC-16で1KBブロックサイズしか提供しておらず、「ブロック0」を実装せずにYMODEMという名前を使い続けていることに彼は落胆しました。その結果、互換性のないYMODEM実装が多数リリースされ、完全な標準規格をサポートするバージョンを明確に示すためにYMODEM Batchという名前が使われることになりました。
オリジナルのXMODEMは非常にシンプルなプロトコルであり、それが成功の理由でした。当時のほぼすべてのマシン、たとえプロセッサやストレージが非常に限られたマシンでも実装できたのです。XMODEMは、送信するデータを128バイトのパケットに分割し、3バイトのヘッダーと1バイトのチェックサムフッターを追加して、結果として得られる132バイトのパケットを順番に送信するという仕組みでした。受信側のコンピュータは、128バイトのデータからチェックサムを再計算し、フッターで送信されたチェックサムと一致する場合はACKを、一致しない場合はNAKを返信しました。送信側はACKを受信すると次のパケットを送信し、NAKを受信すると前のパケットを再送信しました。
このプロトコルにはいくつかの問題点があった。単純なチェックサムを使用していたため、一般的なエラーが見過ごされる可能性があった。パケットサイズが小さく、ACKまたはNAKを待つ必要があったため、高速回線や遅延の大きい回線ではパフォーマンスが低下した。さらに、転送データにファイルの詳細情報が含まれていなかったため、すべてのファイルを手動で開始する必要があり、多数の小さなファイルを転送する場合、これは面倒な作業となる可能性があった。
これらの問題に対する解決策は1980年代初頭に開発されました。XMODEM-CRCはチェックサムを16ビットの巡回冗長検査(CRC)に置き換え、一般的なエラーに対する耐性を大幅に向上させました。XMODEM-1kはパケットサイズを128バイトから1024バイトに拡張し、高速接続でのパフォーマンスを向上させました。一方、WXMODEMやSEAlinkなどは、パフォーマンスと遅延の両方に対処するためにスライディングウィンドウシステムを導入しましたが、その代償として多少の複雑さを伴いました。また、TeLinkやMODEM7などはファイル情報を追加し、1回の転送で複数のファイルを含めることができるようにすることで、1つのコマンドで複数のファイルをまとめて送信できるようにしました。
CP/M用プログラム「Yet Another Modem」(YAM)の作者であるチャック・フォースバーグは、XMODEM に比べて多くの機能をサポートする単一のプロトコルドライバを作成することを決定し、それを YMODEM と名付けました。ユーザーは転送を開始する際に、コマンドラインで必要なオプションを指定でき、例えば CRC を使用したいと指定することができました。このプロトコルは、そのような指定を試みつつ、リモートソフトウェアが実装する機能に合わせて適切にフォールバックするように設計されていました。
オリジナルのXMODEMの問題点の1つは、一度転送が開始されると、それを中止する明確な方法がなかったことです。通常の解決策は、ユーザーからの要求があった場合に、後続のすべてのパケットに対してNAKを送信することでした。XMODEMプロトコルでは、送信を中止するためのNAK送信回数の上限が10回と定められており、各パケットの送信には1秒かかる場合があったため、送信側が無視されるデータを継続的に送信し続けることで、10秒間の遅延が発生していました。
一部の実装では、受信パケットの最後にACKまたはNAKの代わりにCANを送信して中止を示す機能が追加されていました。しかし、回線ノイズによってCANが生成され、中止がトリガーされる可能性がありました。そこでYAMはこれを若干修正し、2つのCANが連続して送信されることを要求することで、送信側で即座に「正常な中止」を実行するようにしました。
XMODEM-CRCではCRCサポートが導入されました。これは元のプロトコルに対する非常にシンプルな変更で、要求された場合、受信側はNAKの代わりに最初のCを送信することで転送を開始しようとします。リモート送信側がCRCオプションをサポートしている場合、通常どおりパケットの送信を開始しますが、フッターには1バイトのチェックサムではなく16ビットのCRCが含まれます。YAMはこのオプションを何の変更もなくサポートしました。
1024 バイトのパケットは XMODEM-1k で導入されました。[ 1 ]このバージョンでは受信側からのトリガー文字は変更されなかったため、送信側は受信側がより大きなパケットをサポートしているかどうかを知る方法がありませんでした。代わりに、XMODEM-1k は接続の両端で別のプロトコルとして提示されました。このような接続が開始されると、送信側はパケットに 1024 バイトまたは 128 バイトのどちらかを送信することを選択できます。大きい方を示すには、通常のSOHではなくヘッダーにSTX文字を使用します。通常、パディングを大量に送信しないように、最後の数個のパケットのみが小さいパケットを使用します。1k では、すべての接続で CRC が想定されていました。YAM は変更なしで 1k をサポートしました。
FidoNetメールの自動転送をサポートするため、MODEM7では最初のデータブロックを送信する前にファイル名をプレーンテキストとして送信する機能が導入されました。しかし、この方法は信頼性に欠けていたため、TeLinkはファイル名、そして必要に応じて作成日やファイルサイズなどの他のデータを128バイトのパケットにまとめて送信することで、この問題を解決しました。XMODEMはパケット番号1から転送を開始するため、TeLinkはこのパケットを番号0として送信しました。この「ゼロパケット」または「ブロックゼロ」は、SEAlinkなどの他のFidoNetシステムでも一般的に使用されるようになりました。
YAMはゼロパケット形式をサポートしていましたが、多くのサードパーティ製YMODEM実装では無視されていました。ある実装が、ゼロパケット形式に対応していないバージョンにゼロパケットを送信しようとすると、受信側は当然ながらパケットゼロは不正であるためNAKを返します。送信側はNAKを送信エラーと認識し、パケットの再送信を試み、失敗するまで10回試行します。
理由は完全には明らかではないが、多くのYMODEM実装ではこの機能が実装されていなかった。実装者はこの機能を知らなかったため、NAKを送信し、一連の再送信試行をトリガーした後、最終的に失敗した。つまり、ユーザーが準拠したYMODEMを非準拠バージョンで使用することを選択した場合、転送は失敗するということだった。にもかかわらず、このような非準拠バージョンは広く普及していた。
その結果、YMODEMとYMODEM Batchが別々のプロトコルとして記載されているのをよく見かけるようになった。さらに、XMODEM-1kとこれらの規格に準拠していないYMODEMは類似性が高く、しばしば誤って同一製品として記載されるほどだったため、混乱がさらに深まった。
YMODEM-Gは、エラーのない接続に使用されるストリーミング方式です。次のパケットを送信する前にACKの受信を待たず、フロー制御にはXON/XOFFが使用されます。パケット間に遅延が発生しないため、YMODEMよりも高速ですが、エラーを訂正する機能はありません。基盤となる接続がエラーフリーであることに依存しており、[ 1 ]これはたとえばMNPをサポートするモデムの場合に当てはまります。
通常、YMODEM転送は、受信側がCRC付き128バイト形式を使用することを示すC 、または元のチェックサムシステムを使用することを示すNAKを送信することによって開始されます。gプロトコルが必要な場合は、代わりにGを送信することによって転送が開始されます。送信側がgプロトコルをサポートしていない場合、これをエラーとみなして無視しますが、gをサポートしている場合は、パケットを連続的に送信し始めます。最後のパケットを受信した後、データにEOT文字が存在することで示される単一のACKのみを期待します。YMODEM-gは、1kパケットが利用可能であることを前提としています。
しかし、このプロトコルはZMODEMよりも高速である可能性があったにもかかわらず、ほとんど使用されませんでした。これは、他の機能が不足していたことも一因でしたが、より深刻な問題もありました。16550 UARTが登場する以前は、シリアルポートでバッファオーバーランが発生するリスクが非常に高かったのです。YMODEM-gではバッファオーバーランを検出できましたが、ブロック再送信ができないため修正できませんでした。受信側は送信をキャンセルし、最初からやり直す必要がありました。一方、ZMODEMには転送再開機能があり、より魅力的なプロトコルでした。