標準TTLだけ(!)でCPUをつくろう!(組立てキットです!)
(ホントは74HC、CMOSなんだけど…)
[第188回]

●波形の写真から、送信されたデータを解読する

今回はいよいよ、解決篇です。
カギは前回お見せした、232C信号の波形の写真にありました。
写真の波形から、送信されたデータを解読してみると、以外な事実が明らかになります。

232Cは8ビットのデータをシリアルに変換して送信します。
1と0だけの羅列になりますから、最初から順に見ていくなら、送信データを読み取ることはできますが、前回の写真のように、その途中の一部だけを見ても、どこが8ビットデータの始めで、どこが終わりなのか、わからないのではないか、と言われるかもしれませんね。
ところが、読めるのです。
まるで、暗号の解読のようですけれど…。

暗号の解読といえば、はるかな昔、子供のころに、エドガー・アラン・ポーの小説「黄金虫」を読んだことを思い出しました。
もちろん、少年向きに書かれた翻訳本でしたけれど。
その中に、財宝のありかを示す、謎の暗号文が出てきます。
記号ばかりが並んだ暗号文です。
この暗号の解読がすごいのですね。子供だった私は、「この主人公はなんて頭がいいのだろう」と、感心してしまいました。
これは、英語のアルファベットをそのまま記号に置き換えたものだ、というんですね。
そして、英語でもっとも多く使われている、アルファベットは何か?またもっとも多く出てくる単語は何か?というような推理によって、見事、その暗号を解読してしまいます。
ま、もっとも、大人になった今、考えてみると、本当に、そんな推理だけで、暗号が解読できてしまうものかどうかはちょっと疑問なのですけれどね。

でも、今回の波形からの解読は、そんなにむつかしいものではありません。
しかも、ちょうど、まあ、なんとも都合のよいところをぴたりととらえた写真だったのです。

もう一度、前回の写真をお見せします。



下側(CH2)のパルス波形をよく見てみると、非常に特徴的な同じ波形の繰り返しに気がつきます。
左の方から3回、約2msecのLの部分があります。
Lは”0”のビットです。
ボーレートは2400ボーです。
2400ビット/秒と考えることができますから、1ビットの長さは1/2400秒、約0.4msecです。
すると、2msec続く”0”とは、”00000”のように”0”のビットが5個連続していることであることがわかります。

ところで、今回送信したデータはどのようなデータであったのか、思い出してみてください。
そうです。16進数をASCIIコードに置き換えたデータを送信したものでした。
その説明は[第181回]にあります。

下はそのときに説明した、16進数1桁をASCIIコードに置き換える表です。
なお()はASCIIコードの16進数表記です。
0 00110000 (30)
1 00110001 (31)
2 00110010 (32)
3 00110011 (33)
4 00110100 (34)
5 00110101 (35)
6 00110110 (36)
7 00110111 (37)
8 00111000 (38)
9 00111001 (39)
A 01000001 (41)
B 01000010 (42)
C 01000011 (43)
D 01000100 (44)
E 01000101 (45)
F 01000110 (46)

今回の送信データには、上の表で示された、30〜39、41〜46以外のコードは含まれていないのです。
さて、このなかで、0が5つ連続しているコードは、と捜してみると、文字Aのコード41(01000001)が目にとまります。
しかし、残念ながら、上の写真の”0”が5つ連続しているデータは、文字Aのコードではありません。

上の表のビット表現は、左端がbit7で、右端がbit0のように並んでいます。
しかしRS232Cで送信するときには、この逆で、bit0から始まってbit7が最後になるように送ります(下図)。

これが、文字AのASCIIコード(41)を232Cで送信するときの波形です。

そこで、もう一度、さきほどの写真の波形を見てみることにしましょう。
0が5つ並んでいるところは一致していますが、その次の1のパルスは、図の波形ではbit6の1ビットだけなのに、写真ではそれよりも長く、おそらく2ビット長であるように見えます。

ええー?それじゃあ、該当者なし?
そうなりますね。文字AのASCIIコード41以外に、0が5個続くコードは存在しません。

ところが、実は、あるのです。
もう一度、上の文字AのASCIIコードを232Cで送信するときの波形の図をよく見てください。
おわかりになりましたでしょうか?

そうです。スタートビットの”0”です。
文字AのASCIIコード41以外に、0が5つ連続するコードは存在しませんが、しかし、データの最初に必ず付け加えられるスタートビットの”0”に続けて0が4つ送られる文字コードなら、ほら、ひとつあるじゃありませんか。

文字0のASCIIコード30です。00110000です。

もう一度、さきほどの写真の波形と比べてみましょう。
おお。今度こそ、ビンゴ、です。

これで、データの流れの中で、1つのデータのスタートビットとストップビットの位置がわかりました。
ここまでわかればあとは簡単です。
写真の波形は下図のように解読できました。

前から順に、30、30、B0、32と読めます。
B0?変ですね?こんなコードは、16進数をASCIIに置き換えた文字コードの中にはありません。何でしょう?
この”B0”のストップビットのところで、受信エラーがONになっています(上側のCH1の波形)。

送信したプログラムリストを見てみましょう。
前回に行った確認で、HLレジスタは、メモリアドレス010Eを表示してエラーで停止しました。
プログラムのその部分です(プログラムリストは前回[第187回]にあります)。

010C 210002

010Cに21が入り、010Dに00が入ります。
その次の010Eに02が入るところでエラーが発生しているようです。
16進数の00は、ASCIIコードでは30・30になります。次の02は同じくASCIIコードでは30.32になります。
だとすると?

上の波形から解読した、30・30・B0・32は、実は30・30・30・32というデータでなければならないところだったのでは?

あ。あ。あ。
ここまで考えてきて、やっと思い出しました、のです。
そうでした。
PICでデータを受信して、2バイトのASCIIコードデータを、1バイトの16進データに変換する、というプログラム部分で、文字0〜9、A〜Fから16進数に変換するために、30〜39と41〜46を分離しています。
その過程で必然的に、コードが30未満、3A〜40、47以上のものを排除することになります。
そのようなコードは、16進数には存在しないコードですから、受信されるはずはないのですけれど、プログラムの流れとして、もしも、そのようなコードがみつかったら、エラー表示をして停止するように作ったことを、すっかり忘れてしまっていたのです。

まさかコードエラーなど、起きるはずがない、という先入観があったため、フレーミングエラーにちがいない、と思い込んでしまったところに、今回のトラブルの原因がなかなかわからなかった、最も大きな要因がありました。

●やっぱり、目撃証言は間違っていた…

しかし、最初に当社のBASICボードで受信してみたときには、エラーは発生しなかったのは、なぜ?
もう一度、BASICボードにつないで、確認をしてみました。
そうしたら…。



BASICボード「ZB11V3」のデータ受信画面です。
あれま。気がつきませんでした。文字化けしています。
中ほどよりうしろのあたりで、210002になるべきところが、2100−2になっています。

うーん。
間が悪かった、というか、これが別の文字コードだったら、文字化けに気がついたのかもしれませんが…。
もともと、ハイパーターミナルでうまく232C送信ができるかどうか試してみることだけが目的だったために、らしい文字列が無事表示された段階で、結果をちらりと見て、オーケー、オーケー、受信すべて、オーケー、と思ってしまったのですよね。

そこへもってきて、たまたま文字化けして表示されたのが「−」だったものですから、また先入観が働いて、見落としてしまいました。
[第182回]で、ファイルの中身をMSDOSのDEBUGコマンドで表示している画面をお見せしました。
これです。



真中に「−」があります。
DEBUGコマンドで、ファイルやメモリの中身を16進数で表示するとき、図のように1行に16バイトのデータを表示します。少し長いので、アドレス位置がわかりやすいようにというためでしょうか、行の真中を示す記号として「−」が使われます。
なまじ、こういう表示に慣れていたものですから、真中付近に「−」があっても、別に異常ともなんとも思わなかったのです。

BASICのボードは、以前から232Cの受信テストに使っていたプログラムをそのまま実行しただけで、「16進数をASCIIコードに変換したデータ」を受信することを目的にしたプログラムではありませんでした。
ですから、受信したコードに相当する文字を表示するだけで、受信した文字コードそのものは、エラーではありませんから、特に異常を示す表示も何も行われなかったために、そこで発生していた「異常」にまったく気がつかなかったのです。

おお。また、思い出してしまいました。
以前にもちょいとお話をしたことがあります、エラリー・クイーンの「Xの悲劇」も、日常見慣れているものは、それを実際には目にしていても、異常とは感じないで、見たという記憶が残らない、という目撃証言に潜む落とし穴を利用したトリックがカギになっていましたね。

それはそうと、上でお見せしたBASICボードの表示画面、えらく年代物の感じですね。
それもそのはず。
もうかれこれ15年間、故障もせずに動いているのですよ。なかなかのものでしょう。

左側に重ねている基板は、カラーグラフィックインタフェースです。N88BASICのカラーグラフィック機能とほぼ同じ機能を実現したボードです。3.5インチのフロッピーディスクインタフェースも実装しています。
右にのびるフラットケーブルは3.5インチのフロッピーディスクドライブにつながっています。
右上にあるDSUBコネクタがRS232Cです。
これは15年前に作った、当社のオリジナルボード「ZB11V3」です。
15年間のほこりにまみれてかなりよごれていますけれど、まだ現役です。こわれません(これはちょいと自慢できますでしょう)。

●なんと、ハイパーターミナルにはバグがありました!

はい。これが今回あきらかになった「衝撃の事実」です。
まあ、予想もしなかった、とんでもないことに、ハイパーターミナルには、バグがあったのです!

どなたもお気づきにはならなかったのでしょうか?
Webで検索してみたところ、これは?というページをみつけました。
http://tss.ram.ne.jp/product/hyperterminal.htmlです。

上のリンク先ページで紹介されているバグは、まさに今回私自身が体験したバグとぴったり一致しました。
私はバグが発生する条件まではつきとめられなかったのですが、この方はしっかりとバグが発生する条件もつかんでみえました。
その条件とは、
1)新しい接続でハイパーターミナルを起動する
2)その起動直後に、同じ文字を3文字以上連続して送信する
というものです。

その例として、”AAAAABBBBBCCCCC”を送信すると、受信側では”AAチAチBBツBツCCテCテ”のように文字化けしてしまう、と紹介されています。
さらに、このバグは、切断後に通信条件を変更して再接続するか、変更しなくても現在の設定を保存して、次回その設定アイコンからハイパーターミナルを起動すると、出現しなくなる、と書かれています。
おお。まさにぴったり。その通りではありませんか。

同じ文字を連続3回送信、というところもぴったりです。
”210002”と送ったところ、”2100−2”になったのですから。

どうもこのバグには規則性があるようです。
下は一般に使われている8ビット半角英数カナの文字コード表です。



今回のエラーは、コード30がコードB0に化けたものでした。その結果”0”が”−”に化けて表示されてしまいました。
この表を見ますと、文字”A”(コードは41)が化けた文字”チ”のコードはC1で、文字”B”(コードは42)が化けた”ツ”のコードはC2、そして文字”C”(コードは43)が化けた”テ”のコードはC3、であることがわかります。
いずれも、送信する、もとのコードのビット7の0が1に変化してしまっている、という明らかな規則性がみられます。

私が今回テストに使用したのは、Windows98です(今だに、です。何しろ動作が軽いものですから、XPなど使う気にならないのですよ)。
なんたって10年前のOSだものですから、今更文句を言ったって、そりゃあ、とっくの昔に、時効成立です。

しかし、しかしです。
さきほどご紹介のあのページをお書きの方は、まあなんと、

WindowsXP SP3に付属のハイパーターミナルVer5.1

で、ご確認なさった、とのことなのですよねぇ。
ふたたび、驚愕、というか、愕然。もう、お口あんぐり、です。

おやまあ、そうですか。
WindowsXP SP3ですか…。ハイパーターミナルVer5.1でねぇ…。
マイクロソフトさんは、いったいどこをバージョンアップなさっていらしたのでしょうか、ねぇ。
2009.3.20upload

前へ
次へ
ホームページトップへ戻る