2014年07月の日記です

目次

01日 「我々が考えるように」発表(1945)
01日 NOP 命令が作られた日(1960)
02日 ダグラス・エンゲルバートの命日(2013)
06日 【訂正】NOP命令が作られた日
17日 続・世界初のMML
20日 BCD (二進化十進)とは
23日 高柳健次郎の命日(1990)
27日 NTSC PAL SECAM
28日 6502 は遅かったのか?


「我々が考えるように」発表(1945)  2014-07-01 10:40:56  コンピュータ 今日は何の日

▲目次へ ⇒この記事のURL

今日は MEMEX の構想が発表された日(1945)。


さて、昨日(ヴァネバー・ブッシュの命日)の話の続きです。

「今日は何の日」で、まさかの2日連続の話題。


ブッシュは、1945年の今日発売の The Atlantic Monthly 誌に、「As We May Think」(我々が考えるように)という論文を発表しました。

この論文は、仮想機械 MEMEX の効用を説いたものです。


今は良い時代で、この全文を読むことができます。



論文の前半は、過去の技術の進化と現在の最先端が…各種分野ごとにわかりやすく列記されます。


露光に何時間もかかった写真が進化し、乾板写真となり、現在ではテレビで生中継が可能なこと。

鉛筆やタイプライターで紙に記録してきたのが、現在ではパンチカードに記録することで自動集計が可能になったこと。

そろばんで計算していたのが、機械式計算機が生まれ、複雑な方程式も解ける微分解析機となったこと。

情報を適切に並べるのに、紙の束を何らかの順で並べてファイルしていたのが、パンチカードによってソートが可能になり、何万件ものデータを扱えるようになったこと…




それらの紹介の後、MEMEX のアイディアが披露されます。


技術は進み、たくさんの情報を記録し、ソートしておけるようになりました。

しかし、たとえ「膨大な本をタイトル順に並べた」としても、それで必要な情報が探しやすくなったのでしょうか?


情報を整理するのには、機械的な方法ではダメで、「我々が考えるように」しなくてはならないのです。


ここで、とある情報に、関連性がありそうな別の情報を接続し、後でいつでも引き出せるようにする、という MEMEX の、基本的なアイディアが紹介されます。


膨大な情報は、マイクロフィルムで記録されます。

新しい本や新聞をマイクロフィルムで購入することもできます。

新たな手書きノートも、メモも写真も、撮影して瞬時にマイクロフィルム化できます。


そして、関連する事柄を接続しておくことができます。

…ブッシュは、この「接続された情報」のことを、トレイル(足跡)と呼びました。



たとえば、百科事典では、項目の末尾に関連項目が示されます。

MEMEX のフィルムとして購入できる百科事典は、項目ごとにトレイルが設定されているものになるでしょう。




そして、MEMEX の白眉は、これら「トレイル」の扱いにあります。


トレイルのデータもまた、MEMEX のマイクロフィルムとして記録されます。

パンチカードの穴の有無が光によって検査されているのだから、マイクロフィルム上のインクで同じように情報を記録できる、という技術的裏付けも示唆されています。


そして、マイクロフィルムは複製することも簡単です。

あなたのトレイルデータを複製し、友人に渡すこともできるのです。


例えば、あなたが趣味で「ヨーロッパにおける弓の歴史」を調べたとします。


あなたの書いた論文と、根拠を示す関連書籍を結び付けたトレイルデータを、あなたの友人に渡せば、友人は根拠となる事実が正しいことを確認しつつ、あなたの論文を評価できるのです。


(関連書籍は買う必要があるかもしれませんが、それは「本」が情報の中心だった当時としては当たり前のことです)



弁護士は自分の関与した事件の関連書類をまとめておいて、クライアントに対して、自分が過去にどのような事件を専門として仕事をしてきたか、すぐに示せるでしょう。


医者は珍しい症例のデータを共有し、患者の診断に役立てられるかもしれません。



MEMEX は、単に個人的な記憶の手段としてだけでなく、人々の暮らしを変える「情報の交差点」となるのです。




昨日、ブッシュの命日の記事で書いた通り、ブッシュは自分以外の人の考えを認めないところがありました。


彼はデジタル計算機の限界を超えるために、微分解析機というアナログコンピューターを発明しています。

そのため、デジタル計算機は信用しておらず、新たに生まれつつあったデジタルコンピューターも信用していませんでした。


彼にとっては、マイクロフィルムが最先端技術であり、MEMEX はマイクロフィルムによって発明されるだろう技術でした。


実は、マイクロフィルムを使った連想記録は、この頃すでに発明されていたそうです。

しかし、その発明のことは知らず、技術を発展させるのではなく、夢想するだけに終わっています。


これもまた、「自分のような天才以外に、このようなことを思いつくはずがない」という過信からだったようです。



しかし、この論文のタイトルが「MEMEX」ではなく、「我々が考えるように」だということに注意してください。


ブッシュは、仮想機械として MEMEX を示しましたが、この機械が重要だと言っているわけではありませんでした。



MEMEX を重視するのであれば、ただ MEMEXの夢を語ればよいのです。

しかし、論文の前半は「各分野ごとの工学発展史」でした。


彼は、それまで「技術」が先行し、バラバラに発展していた各種工学分野の成果を、「そろそろ、人間が使いやすいことを重視して、まとめなおすべきではないか」と提言したのです。


いうなれば、20世紀の機械技術の人間復興ルネッサンス


現代的に振り返えれば、ユーザーインターフェースに革命を促したのです。




MEMEX は魅力的な機械でしたが、夢想が壮大すぎてすぐに実現できそうにはありませんでした。


しかし、後の世に確実に種をまきました。この論文を読み、感銘を受け、後に MEMEX を自分なりに作り出そうとした人たちがいるのです。


…というところで、今日の話は終わりにしておきます。

続きはまた明日。(ナヌッ!?)



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

今日は何の日

関連ページ

ヴァネバー・ブッシュ 誕生日(1890)【日記 15/03/11】

訂正・NOP命令の誕生

ダグラス・エンゲルバート 誕生日(1925)【日記 16/01/30】

ダグラス・エンゲルバートの命日(2013)【日記 14/07/02】

【訂正】NOP命令が作られた日【日記 14/07/06】

別年同日の日記

05年 再引越し

08年 溶連菌感染症

11年 節電

13年 凝集度の高いプログラム

15年 A Dark Room , Candy box! , Cookie Clicker.

16年 PHSサービスが始まった日(1995)

18年 氷川丸


申し訳ありませんが、現在意見投稿をできない状態にしています

NOP 命令が作られた日(1960)  2014-07-01 12:16:50  コンピュータ 今日は何の日

▲目次へ ⇒この記事のURL

今日は NOP 命令が初めて公式文章に記された日(1960)。


…本当かどうかわかりませんが。

僕の調べではこれより古い NOP 命令の記述はありません。


2014.7.6 追記

もっと前の記述がある、という情報が寄せられました。情報提供ありがとうございます。

この記事の内容全てが誤りではありませんが、少なくとも「初めて公式文書に記された日」は誤りでした。


最初に NOP が登場したのは IBM 701。しかし、考え出したのは先に開発を始め、後で発売された IBM 702のようです。

IBM 702 では、明確な目的を持って NOP が作られています。

詳細は別記事にまとめてあります。


えーと、1年近く前に書いた記事、「NOP命令の誕生」は、自分では結構面白い内容だと思うのですが、面白さが伝わる人はかなり限られたようです。


うん。妻にすら、なんだかわからないと言われたよ。

まず、普通は NOP 命令が何かわからないよね。それで当然。


もっと多くの方に読んでもらえるように、前知識を解説しちゃいますよ!

面白いと思ったら本文も読んでいってね。




現代のコンピューター機器は、大抵 CPU を搭載しています。

会社によっては MPU って呼んだりするけど、つまりはコンピューターの本体部分。


コンピューターは電流を使って計算をしているわけですが、これは、計算できる回路をたくさん用意して、切り替えているのです。


足し算をしたいなら足し算回路を、引き算をしたいなら引き算回路を、掛け算をしたいなら掛け算回路を、割り算をしたいなら割り算回路を呼び出すだけ。

計算以外では、メモリにデータを記録しておく、とか、逆にデータを読み込む、とか。全部回路で用意されている。


そんな、小さな命令の寄せ集めでコンピューターは動いています。


ちなみに、画面に文字を書いたり、キーボードからの入力を読み込むのは、「記録」の一種です。

特定の場所に書いたデータは画面に表示されて、特定の場所のデータは、キーボードの内容によって勝手に書き変わる。


コンピューターって、本当に、驚くほど簡単な事しかできません。




さて、そんなコンピューターの「命令」も、データとしてメモリに記録されています。

コンピューターは数字しか扱えませんから、10 だったら足し算、11だったら引き算…みたいに、命令は数字と対応している。


しかし、数字だとプログラムしにくいので、一対一対応で、英語を省略したような名前が付いているのが普通です。


足し算なら add 、引き算なら sub 、掛け算なら mul 、割り算なら div 、という具合。

データの読み込みは CPU によって mov (ムーブ、移動、の意味)だったり、ld (ロード、読み込む、の意味)だったり、store (ストア、保存する、の意味)だったり。


余程単純な英語でない限り、CPU メーカーによって命令の呼び名も、その動作詳細も異なるのが普通です。



ところが、メーカーに寄らずほとんど同じ名前、動作も同じ命令があります。

それが NOP 命令。


No OPeration (なにもしない)の略なのですが、略であれば NOOP になりそうなものが、なぜか NOP 。

(NOOP にしているメーカーもあります)




…と、これが「NOP命令」が特別な理由なのですが、理解できる人が非常に少ないんですよね。


多分、プログラム能力がある人って、非常に簡単なものを作る能力でも 100人に1人いない。

ましてや、機械が理解できる言葉(機械語)で直接プログラムしようなんて人は、プログラムできる人のうち 100人に1人いない。


そして、機械語プログラムができる人でも、NOP 命令に興味を持つ人なんて、100人に一人いない。


…となると、今日が「NOP が初めて公式文書に記述された日」と書いて関心を持つ人は、日本全国で 100人程度しかいないことになる。


#今まで NOP に興味を持ってなかった人の2人に1人が、このページを読んで興味を持ってくれれば、5千人程度には増える計算(笑)



僕がコンピューターを使い始めた時には NOP はあって当たり前の命令でした。

だから僕も、正直なところ NOP の存在を特に疑問に思ったことはありませんでした。


これがちっとも「常識」ではないと知ったのは、がたろうさんのページに、「NOPと都市伝説」というコーナーを見つけたから。


そして、上記ページを見つけた時、すでに僕は がたろうさん が求めている答えを知っていました。




がたろうさんは、ある程度有名なマシンを調べて PDP-1 が NOP を最初に搭載したマシンである、と結論付けていました。

そして、その理由はおそらく技術的に自然発生しただけだろう、と。

NOP の名前の由来も、同じように自然発生と考えています。


しかし、PDP-1 の前には TX-0 があり、TX-0 には NOP が存在しなくてはならない、強い理由があるのです。

実際、PDP-1 よりも前に TX-0 の技術文章に NOP が登場していました。



TX-0 は、非常に複雑な命令系を持っています。


先に、CPU の命令を「足し算」「引き算」などの簡単なものしかない、と書きましたが、TX-0 にはそれすらもないのです。


「半加算」と呼ばれる、繰り上がりの無い足し算は出来ました。

また、「繰り上がり処理」も出来ました。

だから、組み合わせれば足し算ができます。でも、それを組み合わせるのはプログラマの責任でした。


全ての命令が、いくつか組み合わせたら何かできそうな機能どまりなのです。

そして、これらの命令は「同時に」実行することが可能でした。


命令の特定のビット(2進数の1桁)を 1 にすると実行され、0 にすると何もしないのです。

いくつかの命令は、2進数1桁ではなく、5桁で表現されました。


この命令体系は TX-0 独特のもので、僕は他のマシンでこのような方法を見たことは無いです。




5桁で示される命令は…2進数5桁では、32種類の組み合わせを作り出せます。

しかし、当初は全ての数字に命令が割り振られていたわけではありません。


命令表で「何も入っていないところは将来の拡張予定」とされました。


しかし、ここで問題が起こります。


1桁で示される命令は「0」を指定すると、その命令は実行しない、と決められています

5桁の場合、すべての桁が 0 の場合は、何もしないことになっていました。


しかし、「何もしない」がゆえに、命令表には何も書かれていませんでした。


何も書かれていないのですから、これは、将来の拡張予定なのでしょうか?

もし拡張されたら、5桁の2進数で示される部分は、「何もしない」ことができなくなり、他の命令に悪影響を与えるのでは?



そして、懸念していた事態…すべてが 0 の「将来の拡張予定」部分に、命令が拡張される時が来ます。


追加された命令は「NOP」。意味はもちろん「No OPeration」でした。

「命令が入ってない場所は将来の拡張予定」でしたが、すべてが 0 の時は何もしないことを保証したかったため、「何もしない」命令が作られたのです。


この追加命令が公式文章に登場したのが、1960年の7月1日。つまり54年前の今日でした。



ちなみに、TX-0 は、6bit を 1byte とする、18bit コンピューターでした。

当時はアスキーコード選定前。1文字は 6bit で、3文字を同時に扱える、ということになります。


このため、TX-0 の機械語命令は、3文字で1命令とするのが普通でした。

NOOP ではなく NOP となっているのはそのためです。



…と、概要は以上の通り。

詳細は「NOP命令の誕生」を読んでね。





ちなみに僕が書いたページ、がたろうさんのページでは触れられていませんが、書いてすぐに連絡済みです。

いろいろお忙しい方なので、ページ更新の暇が無いようです。


お忙しい方の手を煩わせたくないので、「こんな記事があるよ」というような無駄な追加連絡はしないように。

(こっちも趣味、あっちも趣味だから、主張が違ったって構いませんし)



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

今日は何の日

関連ページ

ヴァネバー・ブッシュ 誕生日(1890)【日記 15/03/11】

訂正・NOP命令の誕生

ダグラス・エンゲルバート 誕生日(1925)【日記 16/01/30】

ダグラス・エンゲルバートの命日(2013)【日記 14/07/02】

【訂正】NOP命令が作られた日【日記 14/07/06】

別年同日の日記

05年 再引越し

08年 溶連菌感染症

11年 節電

13年 凝集度の高いプログラム

15年 A Dark Room , Candy box! , Cookie Clicker.

16年 PHSサービスが始まった日(1995)

18年 氷川丸


申し訳ありませんが、現在意見投稿をできない状態にしています

ダグラス・エンゲルバートの命日(2013)  2014-07-02 19:24:15  コンピュータ 今日は何の日

▲目次へ ⇒この記事のURL

今日はダグラス・エンゲルバートの命日(2013)。


一周忌です。

昨年追悼文かいたので、そちらも参照のこと。


50年代の画面技術も彼に関係の深い話です。




さて、一昨日はブッシュの命日

昨日は、ブッシュが「MEMEX」の構想を発表した日でした。


そして今日命日のダグラス・エンゲルバートは、MEMEX を実現しようとした、最初の一人。

「今日は何の日」で3日連続で話ができるとは思いませんでした。



ブッシュは、情報を記録する最先端メディアであったマイクロフィルムと、情報を整理する最先端メディアであったパンチカードを組み合わせたようなもの、として MEMEX を構想しました。


ブッシュ自身は、若いころに「デジタル計算機」の限界を感じ、機械式アナログコンピューターを作った人です。

その経験から、デジタルコンピューターなんて信じていませんでした。


でも、エンゲルバートは海軍のレーダー技師で、SAGE を使った経験から「コンピューターを使えば、情報の記憶と整理の両方が可能である」ことに気が付きます。

これを使えば MEMEX が実現できるでしょう。


そして彼は NLS を作りました。

世界初の、コンピューターで文章を執筆し、推敲し、共有できる環境です。


このために、彼は(正確には彼と仲間たちは)世界初をたくさん考案しています。

一番有名なのは「マウスの発明者」ですが、ディスプレイ、ワープロ、GUI、メール、チャット…などなど。


MEMEX の「トレイル」…現在では「ハイパーリンク」と呼ばれているものに相当するものはありません。

でも、MEMEX では「マイクロフィルムによって友人と情報を共有できる」としていた情報を、オンラインで共有しながら会議ができるようになりました。




エンゲルバートは NLS を大々的に発表します。

この「伝説のデモ」の聴衆の中に、アラン・ケイもいました。

直接見たわけではないようですが、テッド・ネルソンにも影響を与えました。



エンゲルバートの NLS は、使いやすくしようと頑張っていたのですが、実はまだまだ非常に使い方の難しい、技術偏重のシステムでした。


アラン・ケイは、NLS に触発されながらも MEMEX の目指した「我々の考えるように」使えるシステムをめざして研究を開始します。

テッドネルソンは、NLS に足りないもの…情報を繋げる「トレイル」を、コンピューター上に取り入れる方法を考え、マイクロフィルムではとても実現できなかった「ハイパーテキスト」に辿りつきます。


現在の WEB は、アランケイの目指した「使いやすいシステム」と、テッドネルソンの目指した「ハイパーテキスト」の上に作られた…今すぐ実現しそうな機能だけで作られた、小さな箱庭。



…違うもので比較ができません、というのであればよいのですが、残念ながら WEB は、先行する研究者の考えたもののサブセットに過ぎません。


サブセットでも十分便利ではあるけど、問題がいろいろあるのもまた事実。

いつか、新しい技術で解決されると思いますが、その方向性を見極めるためにも、先人たちの研究には敬意を払っておくべきでしょう。



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

今日は何の日

関連ページ

ダグラス・エンゲルバート 誕生日(1925)【日記 16/01/30】

NLS伝説のデモの日(1968)【日記 14/12/08】

別年同日の日記

03年 なかなか忙しくて

09年 夏風邪

17年 バーベキュー


申し訳ありませんが、現在意見投稿をできない状態にしています

【訂正】NOP命令が作られた日  2014-07-06 10:34:33  コンピュータ 今日は何の日

▲目次へ ⇒この記事のURL

先日、「NOP命令が作られた日」という内容を掲載しました。


そちらの記事にも書いてありますが、1年ほど前に書いた記事にゆかりの日に、概要をまとめて再掲載したもの。


しかし、ありがたいことに多くの方に読んでもらいました。

面白がってくれた人が Twitter でリツイートしてくれて、1日で100RTくらい行ったの。


その結果、元記事を書いて1年たっても情報提供がなかったのに、「IBM 704 に NOP あるよ」という有用情報が寄せられました。


調査したら本当で、もっと深いことがいろいろ見えてきました。




というわけで、訂正記事を書きました。


704 よりもっと前にさかのぼり、それでもちゃんと NOP は意味のある命令でした。

(動作は「何もしない」だけど、作られた理由が明確)


今回の話では、「自己書き換えプログラム」「10進法(BCD)コンピューター」「パンチカード集計機」「無条件分岐命令」あたりがカギでした。


いや、ほとんど古代の遺物のような技術で、これらが結びついたら NOP が出来上がった、というのが目からウロコ。




前回記事を読んで面白いと思ってくれた人なら、今度の記事もお楽しみいただけるかと思います。

一方、前回記事が面白くなかった人は、今度の記事もつまらないかと (^^;;


前回記事もそうだったのですが、少ない手がかりを元に真実を探り当てる、歴史推理小説のようなつもり…で書いてます。

ある程度の前提知識が必要ですが、余りにも一般的でない知識についてはその都度解説しています。


NOP 命令の話なので、少なくとも「プログラムすること」を理解しているのは前提。

出来れば機械語の知識もほしい。


かなりマニアなプログラマーでないと読めない推理小説ですね (^^;



#でも、プログラマーは推理小説好きだと思う。




…と、気を持たせるだけ持たせておいて、詳細は訂正記事に譲ります。


この後は、多くの方が読んでくれたので、反響に返事をします。

(別に僕宛てに送ってなくても、ツイートしてたの見つけたのを含む)


いちいち許可取るの面倒だから、文面はコピーせずに概要だけね。



「読みやすくて面白い」


ありがとうございます。最高の褒め言葉です。

また記事書こうと励みになります。



「読みにくい」


申し訳ありません。精進いたします。

しかし、たぶん文章が読みにくいのではなく、内容が理解しづらいのだと思います。


技術系の話題なので、理解にはそれなりの前提知識を必要とします。



「アセンブラわかる人ってそんなに少ないもんかな?」


僕は非常に少ないと思っています。経験則上。


20年前はゲーム会社にいたので、アセンブラ出来ないとロクなもの作れないだろう…とおもうのですが、実際アセンブラわからないプログラマが半分くらいはいましたよ。


ちなみに、普段の仕事はすでに C で十分でした。アセンブラ必須ではない。

でも、ゲームで繊細な動きを作れる人は、やはりアセンブラレベルまで理解できている人でした。


ゲーム会社でそれなのだから、普通に考えたらもう絶望的。



「μコードに似てる」


いや、全くその通りです。呑み込みが早い。

TX-0 のベースとなった Whirlwind I は、μコードを最初に考案したマシンで、TX-0 は簡略化のために、μコードを直接使ってプログラムするような形式でした。



「0の発見に通じるものがある」


こちらも呑み込みが早い。

先日書いた日記には書いてませんが、元記事のまとめにはそういう表現を使いました。


僕がそう感じていたので、記事全体がそういうことを匂わす流れになっているとは思います。



「妻に理解を求めるのが一番ハードル高い」


あー、妻すら理解してくれない、と書いたからね。

世間一般的には、夫の趣味を理解しない妻(もしくはその逆)という構図は多いのですが、うちは幸いその点は大丈夫。


趣味に理解はあります。

妻もプログラムできるし(PHP / Javascript を少し、という程度)、古いコンピューターも理解してる。

(妻が PC 始めたのは MacOS 7 / Windows 3.1 以降だけど、8bit 時代の雰囲気くらいは理解してる)


ただ、アセンブラレベルになると理解が難しいし、ましてやμコードを直接駆動するような TX-0 の話は理解できない。


直接対話で説明できる妻であっても理解させることは難しいのに、ましてや文章でどれだけの人に伝わるか…

という意味合いでした。



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

今日は何の日

別年同日の日記

17年 セレンディピティ


申し訳ありませんが、現在意見投稿をできない状態にしています

続・世界初のMML  2014-07-17 11:06:27  コンピュータ

▲目次へ ⇒この記事のURL

もう1か月半ほど前に「世界初のMML」という日記を書いたのだけど、書いてから気になって調査を続けていました。


TX-0 が世界初の MML 、というのはまぁいいでしょう。

MORIYA Ma. 氏の調査で、現代 MML の先祖がベーシックマスターらしいことも判っている。


じゃぁ、この間はどのようにつながっているの?

…このミッシングリンクが気になっていました。


TX-0 と現代 MML の間は「つながっている」のか、「偶然の一致」なのか、と言い換えることもできます。




いろいろ調査したら、出るわ出るわ…

思った以上に音楽演奏プログラムは多い。500行くらいにまとめたかったのだけど、最終的には 1500行くらいかな? 多すぎて読むのが疲れるので、全体を3部構成にしています。


それでも、途中で見つけて、興味深いから調べて、かなり長い文章書いて、結局枝葉に過ぎなかったので全部消した、というシステム多数。これは、「調査済み」ということを示すために最後に概要だけまとめてある。



コンピューターの黎明期から音楽演奏はあったし、コンピューターが新たなフェイズに入ると、必ず歴史が繰り返されて、音楽演奏の方法が「再発見」される。


世界初のコンピュター演奏で、データはバイナリだった。でも、数年たって TX-0 が MML っぽい記述で演奏を可能にする。

このまま技術がどんどん洗練されていくのかな…とおもったら、PDP-8 でコンピューターが驚くほど安くなり、新たなユーザー層が開拓され、またバイナリ演奏の方法が「発明」される。

そのシステムはすぐに言語を獲得し、洗練されていく。洗練の速度は黎明期より速い。


でも、やっぱり Altair が発売されて新たなユーザーが増えると、またバイナリ演奏からはじまることになる。そして、あっという間に言語が洗練される。


でも、TK-80 が日本で発売されると、またバイナリ演奏に戻る。


…いつまでも続く無限廻廊のよう。でも、ユーザーが増えてつながりも出来ているから、発展の速度はどんどん上がり、システムは洗練されていく。




Altair は非常に普及したので、いくつもの音楽演奏プログラムが作られ、発表されている。

そのうち、特によく出来た2つ…SCORTOS と MUSIC の記述方法を組み合わせ、さらに改良したものがベーシックマスターの BASIC に組み込まれる。


さらに、MZ-80K の技術者は「2つを混ぜた」ことに気付いたようで、再度2つの配合の仕方を変えて再改良する。

またさらに、マイクロソフトがベーシックマスターと MZ-80K と SCORTOS と MUSIC と MUSYS(SCORTOS や MUSIC の元になったシステム)を再発見し、よく研究して根本から作り直す。


いろんな人の手で、何度もスクラップ&ビルドが繰り返され、生み出されたのが現代 MML の始祖。

だから、「どれが最初」と簡単に言えるようなものではないのだけど、あえて言うなら SCORTOS が直系の始祖。

(TX-0 が偶然とはいえ類似文法でより古い、というのは事実で、世界初を否定するものではない)


と、概要はこんな感じ。


細かな文法や、システムの発表時期などを調査して、おそらくこうだろう、と類推しただけで、実際の開発者たちに話を聞いたわけではありません。


ただ、細かなデータなど、証拠はたくさんある。あてずっぽうに言っているわけではない。


興味を持ち、詳しく知りたい人は、詳細記事へ。



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

別年同日の日記

02年 冷蔵庫に乾杯

15年 NECの創業日(1899)

15年 エジホン探偵事務所


申し訳ありませんが、現在意見投稿をできない状態にしています

BCD (二進化十進)とは  2014-07-20 13:02:46  コンピュータ

▲目次へ ⇒この記事のURL

NOP 命令の話を書いたときに、IBM 702 が出てきました。

「BCDを使った10進計算機だった」と書いたところ、ツイッターで思わぬ反響がありました。


電卓なんかは内部で 10進の計算をしている、と書いてある書籍があったが、デジタル回路でどうやって10進計算をしているのか不思議だった、とのこと。


あーなるほど。ここら辺微妙な技術ですね。

2進数がわかる、というのはそれなりにコンピューターに詳しい人だと思いますが、その2進数で10進の計算をする、という話題は、さらにプログラムができる人でないとわからない。


古いコンピューターでは BCD はよく使われた技術なのですが、今ではあまりお目にかかることはありません。

2進数を10進数に変換するのが「当たり前」の技術になったためでもありますが、昔はこの変換も大変で、10進数で結果が欲しいのであれば、最初から 10進数で計算する、というのは悪くないアイディアでした。



2進数を10進数に変換する、というのが当時どれほど大変だったことか、僕が良く挙げる本ですが「ハッカーズ」に書かれています。(第1部 真のハッカーたち 第2章 ハッカー倫理 「芸術や美をコンピューターで作り出すことは可能である」より)


ある時、TX-0 で二進数を十進数に直して表示するルーチンを作る競争が始まります。競争は自然に始まったものですが、誰もが使う基本的なルーチンを少しでも短くできるように、多くの人が知恵を競い合うようになります。

最初は百命令もあったルーチンは、参加者の努力で50命令ちょっとまで削られます。しかし、その後はなかなか進みません。

50命令の壁…誰もがそう感じ、これ以上は1命令たりとも削れないのではないか、という雰囲気が、皆の間に広まります。

その後、寡黙なハッカー、ジェンソンのチャレンジが始まります。彼は誰にも相談せずにアルゴリズムを根本から考え直し、絶妙なテクニックを駆使し、それまでの誰もが思いもつかなかった方法でプログラムを短くするのです。


以下引用。


その内容がようやくハッカー仲間に明らかになったのは、ジェンソンのプログラムが掲示板に張り出されたときだった。十進法プリント・ルーチンを限界まで切り詰めたことをみんなに知らせる彼らしいやり方と言える。


「命令数46」


コードを見つめるみんなの口があんぐりと開いた。マージ・ソーンダースは、その後幾日か、ハッカーたちがいつになく無口だったことを覚えている。

「みんな、これが決定版だってわかったんだよ」と、ボブ・ソーンダースは後に語った。「ついに解脱というわけさ」


今なら2進数を10進数に変換するのは当然の基幹技術で、高級言語では意識することもありませんし、アセンブラでも簡単にできるように命令が揃えられています。


しかし、それ以前は、こんな苦労をして2進数を10進数に変換するか、最初から BCD で計算するかのどちらかだったのです。




さて、BCD の話。


1bit は、 0 か 1 かの2つの状態を表せます。

ここでの足し算は、4種類しかありません。


0+0 = 0

0+1 = 1

1+0 = 1

1+1 = 10


最後だけ、ちょっと特別。繰り上がりが入っているからです。

もし結果も 1bit なら、上の桁は無くなって答えは 0 です。(XOR:排他的論理和、と呼ばれる状態)


繰り上がりは上の桁に足される、と考えれば、何桁に増えようとも、この4つのパターンの組み合わせだけで計算ができます。

これが、2進法計算の原理。


2進法が 2bit なら 2*2 で4種類の状態を表現できます。(00 01 10 11 の4つ)

3bit なら 8 種類、4bit なら 16 種類の状態となります。

10進数一桁(0~9の10種類の状態)を表すのに、3bit では足りないが 4bit なら十分であるとわかります。


そこで、4bit を単位として 10進数を表現することを、BCD と呼びます。

BCD は、Binary Coded Decimalの略。2進数に変換された10進数、という意味合いで、日本語訳は2進化10進。


0000 は 0 。0001 は 1 、0010 は 2 。ここら辺は普通に2進法と10進法が一致します。

1000 は 8 で 1001 は 9 。


この次が重要で、普通に2進数で数えていれば、 1010 になります。(16進数では A と記述される)

でも、2進化10進では繰り上がりが生じて、1 0000 になります。9の次は 10 、という表現です。


足し算も、1bit 単位では2進数と変わりません。でも、計算後に 4bit 単位で結果を見直し、9を超えたら繰り上がって、1の位だけ残すようにします。


#実際にはいろいろややこしいが、特定条件になった時に6を足せばよい。この6は、10進と16進の差分。



そういう回路が組んである場合もあるし、計算後に補正する、なんて面倒を無くすために、最初から足し算を九九みたいな表で持っている機械もありました。


ここまでできれば後は応用。引き算は足し算の逆だし、掛け算は九九の表を持っておけば足し算に変換できます。

(割り算が厄介なのは2進数と同じ)

これで、2進数を使ったデジタル回路で、10進数の計算ができます。


ざっくり言えば、これが BCD の原理です。




昔の BASIC だと、32768 を超えるとエラーになりました。これ、16bit では -32768~32767 しか表せなかったためです。


科学計算では非常に大きな値を扱う可能性がある一方、観測精度の問題も付きまとうため、「おおよその値」がわかれば十分なことが多いです。


だから、たとえば 16bit の範囲の値に「10 倍」とか「10000倍」とか、倍率を付けて(下駄をはかせて)計算しても構いません。

このように下駄をはかせる場合、下駄のことを「指数」と呼びます。


指数があると非常に大きな数も扱えるようになるけど、正確な計算ができるのは、やっぱり最初の 16bit の範囲だけ。これを有効桁数と言います。


現代的には、たとえば Javascript では常に倍精度実数計算をしています。倍精度実数、というのは、有効桁数が 53bit で、指数が 11bit 、符号が 1bit ということ。合計すると 65bit なのですが、ちょっとした数学マジックでごにょごにょ…っとすると、64bit 丁度に収まります。(1bit 得してる)


だから Twitter のステータス(つぶやきにつけられるID)が 53bit を超えてしまったときに騒ぎになったのは記憶に新しいです。



さて、話を戻して、この「有効桁数を持った数値を、指数で大きくして計算」は、コンピューター以前から科学分野では当たり前でした。

IBM の最初のコンピューターである 701 は科学分野向けに作られていたため、当然この方法で計算します。


しかし、これは科学分野では当たり前でも、事務会計分野ではとんでもない話です。

事務会計では、最後の1セントまでキッチリ計算できないと話にならない。桁が大きくなって有効桁数を超えました、なんていって誤差が生じるようでは困るのです。


結果として、科学計算用ほどの速度を求めない代わりに、どんなに桁数が多くても最後の1桁までキッチリ計算する正確さが求められました。

これに応じるように作られていたのが IBM 702 で、BCD を採用しています。


(言語設計上の FORTRAN と COBOL の違いでもあります。FORTRAN は科学技術用で高速性重視、COBOL は事務用で正確さ重視でした。実際、COBOL は内部表現に BCD を使用します。)


BCD の数値はメモリ上に用意され、「終端記号」が現れるまで何桁でも増やすことができました。

もちろん、計算もメモリ・メモリ間で非常に長い桁数同士で行えます。


2進数であっても、レジスタよりも長い有効桁数の計算を行う際に、メモリ上に値を持つことがあります。

このようなものを「多倍長整数演算」と呼びます。多倍長演算すると、ただでさえ厄介な「2進数から10進数への変換」が、さらに厄介になります。

その点、BCD を使った多倍長整数演算なら、10進数への変換は簡単です。IBM 702 は、そのような用途に特化してあったのです。




話は急に変わって、世界初の 1chip CPU である Intel 4004 も IBM の BCD コンピューターの流れを汲む設計でした。


もともと、Intel に「計算機用 LSIの開発」を依頼したビジコン社では、計算する内容をすべてレジスタに入れる形式を考えていたそうです。10進10桁を想定していて、36bit 必要だった、とのこと。(内部演算は2進だったのかな)


想定されていた LSI は、40pin パッケージが必要でした。

しかし、当時の Intel はメモリを作っている会社で、18pin が生産できる LSI の限界でした。


ビジコンから交渉に出向いていた嶋正利はこの技術的限界に気付かずに作りたいチップの仕様を挙げますが、どうも話がかみ合わないまま2か月が過ぎます。


ある日 Intel のテッド・ホフが「電卓なら、4bit で BCD 計算すれば十分では?」とアイディアを思いつきます。

これが、4bit CPU 誕生に結びつきます。出来上がった LSI は 16pin パッケージに収まりました。


テッドは、BCD コンピューターの IBM 1620 を使ったことがありました。

(先に書いた、「足し算も表をひいて行う」コンピューターです)

また、PDP-8 も使ったことがあり、4004 の命令などは PDP-8 の影響が強いです。


訂正 2017.8.28

当初 40pin を想定、と書いてしまいましたが、勘違いでした。


当初は 24pin で8個ほどに分割した LSI を想定。これは大規模すぎて Intel では作れない、とテッド・ホフが 4bit 計算のアイディアを持ってきます。


ところが、ホフのアイディアでは内部回路は単純化されるが、外部は 40pin にかえって大きくなってしまったそうです。

でも、アイディアが良かったので外部 pin 数を減らす工夫を考え、4004 が完成したという話。


また、「2進から10進に変換するためには高価なチップを使えない」ので、4004にはBCD命令を持たせた、という記述がありました。(計算機屋かく戦えり)


どうも、当初は内部2進数演算を想定していた、ということで間違いなさそうです。




時代が飛び回りますが、IBM 702 より古い話。

ENIAC の設計者が後に作った、世界初の「商用マシン」である UNIVAC I では、 XS-3 と呼ばれる特殊な BCD で計算を行います。


先に書いた通り、4bit では 16 の状態があり、BCD ではこのうち10個を使います。

残る状態は 6 個。これを半分にして、BCD の「上下」に3個づつ割り振る、という方法です。


簡単に言えば、2進数の 0000 を 10進数の -3 に割り当てます。

2進数の 0011 が 10進数の 0 。1100 が 9 にあたり、 1111 は 12 です。


1桁づつ計算を行うとき、「繰り上がり」や「繰り下がり」が発生します。

数値範囲には上下に幅がありますから、一旦「2進数として」上の桁を +1 -1 しても問題ありません。

(0000 を 0 とする BCD で -1 すると、 1111 になってしまいおかしくなる)


他にもメリットがあります。0111 が 4 で、1000 が 5 ですから、「最上位ビットが立っているかどうか」を見るだけで、四捨五入ができるようになります。


さらに、ビット反転するだけで「補数」が求められます。

補数とは、簡単に言えば符号が逆の数なのですが、BCD 1桁には 0~9 しかないため、「符号を逆にしたのと同じ意味になる」数を意味します。

もっと言えば、10 進数の場合「10から元の数を引いたもの」が補数です。


たとえば、0100 は 2 ですが、ビット反転して 1011 にすると 8 。

5-2 = 3 となりますが、補数を足すと 5+8 = 13。

1桁で考えると、両者とも結果が「3」となり、同じです。


ビット反転が補数になる、というのは XS-3 の利点です。


…などなど、BCD をちょっと改良しただけなのですが、メリットが沢山。

うまいこと考えたなぁ、と思います。


(実は、UNIVAC I はそれほど詳しくなくて、XS-3 は存在を知っているだけ。

 そのうち詳細を調べたいマシンの1つです)




話は戻って IBM 702。

BCD は1桁を 4bit で示す、と書きましたが、702 では 6bit で表しました。

残る 2bit を使って、数字だけでなく文字も表せます。計算専用ではなく、事務書類の作成も含めて「事務処理用」だったわけです。


この文字コード、先頭 2bit が 00 の時は、下 4bit が 0000 ~ 1001 で 0~9 を示します。BCD 数値と文字コードの 0~9 が一致しているのです。

だから、計算結果をそのまま表示することが可能でした。

(本当は少し違うけど、大まかに言えばそういうこと)



最後の桁には、「終わり」を意味するため、先頭の 2bit を特別扱いします。

符号などもここで扱いました。



現代の 8bit コードでも、下 4bit を BCD にして、上 4bit を 0011 にすると、0~9 の文字が出せます。(ASCII の場合)

この形式を「ゾーン BCD」と呼びます。頭 4bit で BCD の範囲(ゾーン)を示すから、ゾーン BCD というわけです。

最後の桁でフラグを持たせる、というのは IBM 702 の時からの伝統…とも言えなくて、処理するシステムによってマチマチ。決まっているのは頭が 0011 だということだけ。


僕が以前に Javascript で作った「開平法計算機」では、Javascript の扱える値の範囲を超えて計算をするために、多倍長演算を行っています。

…といっても、実際は数値を文字列にして、8桁づつ範囲を区切って数値化して計算しているだけ。


文字列として数値を保持して計算しているのですから、ゾーン BCD だと言えます。


先に書いた、Twitter が 53bit を超えてしまったときの対処も、「ID 数値を文字列として表現」でした。これもゾーン BCD です。




ゾーン BCD は、8bit で10進数1桁しか表せません。

8bit に 4bit の数値2桁を一緒に入れれば、もっとメモリを節約できます。

こちらは、2桁を詰め込む(packed)ため、パックド BCD と呼ばれます。


先に書いた、BCD を前提として 4bit に設計された CPU 4004 の後継機種に、8bit の 8080 があります。


8080 には、加算結果を BCD に直してくれる10進補正命令(DAA)がありました。

加算してから BCD 補正、を桁ごとに繰り返す形になりますが、CPU が最初から BCD を扱えるように設計されているのです。


8080 では加算専用だったのですが、Z80 では減算にも対応しました。

GB CPU は 8080 ベースですが、この部分は Z80 互換になってます。


6502 にも BCD 命令があります。というか、BCD 「モード」にすると、ADC と SBC (キャリー付可算と、ボロー付減算)計算命令の動作が変化して、パックド BCD を対象とするようになります。

こちらのやり方では、8080 と違っていちいち補正命令を使う必要はありません。

(実は、Z80 では6個、GB CPU では4個のフラグのうち、2個は BCD 補正命令のためだけについています。6502 にはこの無駄がありません)


ただ、僕はファミコンで 6502 を覚えたので、実際にこのモードを使ったことはありません。

ファミコンでは、回路規模削減のためにこのモードは削除されていたんですよね。


68000 にも BCD 命令があって、加算命令の名前が ABCD です。Add BCD の略、というだけなのだけど、名前に美しさを感じました。

(ABCD に意味を持たせるなんて、他には ABCD包囲陣くらいしか知らない)


その理由だけでこの命令を使いたくて、大学時代に自作したシューティングゲームでは得点を BCD で扱っています。

でも、これは失敗だった。BCD 命令は加減算と符号反転(補数を得る)しかなくて、特別な方法で敵を倒すと得点が何倍、とかの計算すら困る状態でした。


良く理解しない技術に手を出すな、という教訓ですね (^^;





▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

関連ページ

クリストファー・レイサム・ショールズ 命日(1890)【日記 15/02/17】

IBM - SSEC

訂正・NOP命令の誕生

続・6502は遅かったのか?【日記 14/09/06】

Programming Tips

別年同日の日記

02年 衝動買い

15年 高校部活の同窓会


申し訳ありませんが、現在意見投稿をできない状態にしています

高柳健次郎の命日(1990)  2014-07-23 11:51:27  コンピュータ 歯車 今日は何の日

▲目次へ ⇒この記事のURL

今日はテレビの父、高柳健次郎の命日(1990)。


1926年に「イ」の文字の送受信に成功した、というのが有名な話。

最大視聴率だった、というネタ、好きだわ。



80年代の画面技術で、走査線について書きました。

ブラウン管に電子銃でビームを当て、電磁石によって横に向かってビームを動かします。

さらに、縦方向にも少しづつ動かしていきます。すると、ビームが平面を覆い尽くします。


あとは、ビームを強弱させれば光の強さが変わります。白黒テレビの出来上がり。


…受像機側はこれでいいんですよ。

問題は、撮影側。

ビームが動くのと同期するように、対象物を「左上から横方向に」「少しづつ下方向に」撮影しないといけない。


じつは、この原理は1884年には発明されていて、開発者の名前を取って「ニプコー円盤」と呼ばれています。

受光素子の前を、大きな円盤で覆います。円盤の縁の近くギリギリでおおわれるようにし、縁に多数の穴を開けます。


円盤を回すと、受光素子の前を、穴が多数通り過ぎていきます。

この時、穴は左から右に通り過ぎ、1個が過ぎるとすぐ次の穴が左から現れるようにします。

そして、穴の位置はだんだん下に下がっていきます。


…これで、撮影側の走査線を作ることができます。


じつはこれは、受信機側にも同じ装置を使うことができて、ブラウン管がなくてもライトの光を使って、スクリーンに光を映し出せます。

こうやって、送信側も受信側も「機械式」でテレビを作った例は、高柳健次郎の前にもありました。


しかし、送信側はともかく、受信側に大きくて可動部分が多い方式を使うのは現実的ではない。

家庭に普及させるには、小型化と、可動部分を少なくすることが必須でした。


そこで、受信側はブラウン管を使い、見事に映像を送ったのが 1926年のこと。

「イ」と書いた雲母板(透明な板)の後ろから光を当てて撮影していました。

送信先は、すぐ隣にある受像機で、電線で接続されています。


でも、これがテレビ放送の第一歩。




その後、1933年にアメリカのツヴォルキンが、撮影側も電子化する方法を発明。

これをすぐに高柳も取り入れることで、走査線の数と、1秒間のコマ数を飛躍的に増やします。


ちなみに、走査線が増えれば画像は綺麗になるし、コマ数が増えれば動きが綺麗になります。

1937年には走査線 441本、毎秒30枚の方式を完成。これをほぼそのまま使用する形で、1939年には実験放送が始まっています。

しかし同年、後に第2次世界大戦と呼ばれる戦争が起こり、1941年に日本も参戦。

このため研究は中止され、電波技術に詳しかった高柳もレーダーの研究などを行います。



一方、アメリカでは1941年にはテレビ放送が実用化されます。

高柳は1946年に弟子と共にビクターに入社、テレビの研究が再開します。


1948年、再度実験放送の開始。

1953年にやっと本放送が始まりますが、この年にアメリカではカラー放送の規格が成立しています。

日本のカラー放送は 1960年開始です。


1959年、高柳は世界初のビデオ・テープレコーダーを開発しています。

当初はもちろん放送機材としての利用でしたが、後に高柳のいたビクターで家庭用に改良され、VHS規格となります。


また、静岡県の浜松で生まれ、東京で勉強したのちは浜松に戻って教員をしていた高柳の教え子には、浜松ホトニクス(カミオカンデでニュートリノが発するわずかな光を捉えた受光管を作った会社)の創業者などがいます。




最後に、「テレビ」の話ではありますが、それはそのまま「パソコンモニタ」に流用されています。

だから、これはパソコンの歴史の話でもある。


世界初のラスタースキャンディスプレイを備えたシステムは、安価に入手できる市販のテレビを利用しました。

Apple II もテレビ用の NTSC 信号を前提としたカラー回路を備えています。後にパソコンは専用のディスプレイを使うようになっていきますが、最初はテレビなのです。



▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

歯車

今日は何の日

関連ページ

高柳健次郎の誕生日(1899)【日記 15/01/20】

別年同日の日記

02年 免許更新

09年 ゲーム解禁

13年 ○○、Fonera やめるってよ。

15年 夏風邪

18年 LED 電球


申し訳ありませんが、現在意見投稿をできない状態にしています

NTSC PAL SECAM  2014-07-27 12:18:23  コンピュータ

▲目次へ ⇒この記事のURL

サターンのCPU、という記事の中で、CPU の動作クロックが、NTSC のビデオ信号から決められた、と書きました。


NTSC は、日本のアナログテレビで使われていた方式。

簡単に書けば、1秒間に60枚の絵で動きを表現し、1枚の絵は 720x480 ドット程度で表現されます。

この信号を作るための基本的な周波数(搬送波と言います)が、3.58MHz (正確には 3.579545MHz) です。


テレビに出力するにはこの周波数を作り出す回路は必要。

CPU もこの周波数で動くようにすれば、回路を減らしてコストを下げられます。


だから、MSX は 4MHz で動けるはずの Z80 を、わざわざ 3.58MHz に速度を落として駆動します。

スーパーファミコンも同じ 3.58MHz で、ファミコンは半分の 1.79MHz。

記事に書いたサターンでは、8倍の 28.6MHz でした。


ちょうど半分、とか、8倍、というのはデジタル回路で計算しやすいので、CPU を、 NTSC 搬送波の単純な比率で作れるクロックで駆動できれば、クロックを作り出す発振回路や、別々のクロックの部分をつなぐための回路を節約できます。




…という話を書いたら、「PAL では影響を受けるの?」という質問が来ました。

なるほど。僕も詳しく調べたことはありませんでした。


PAL はヨーロッパで普及したアナログカラーテレビの規格です。

NTSC よりも画素が細かく、1枚の絵が 720x576ドット程度で表現されます。

その代り、1秒間の枚数は 50枚に減ります。

(ややこしくなるので詳細は書きませんが、PAL には NTSC とほぼ同じ解像度・秒間枚数の方式もあります。

 以下は、上記に書いたものを PALとして話を進めます)


計算するとわかるけど、1秒間に表示されるドット数は同じです。

これは、電波で伝送できる情報の量が、当時の技術的限界から決まってしまっていたから。


動きを綺麗に見せようとしたのが NTSC で、画像を綺麗に見せようとしたのが PAL 、というわけです。

(もっとも、それを意図したのかどうかは不明。画面枚数は単に交流周波数の影響を受けた気がする)


そして、PAL の周波数は 4.43MHz (正確には 4.433619MHz) 。


…あれ、僕が思ってたのと違う (^^; NTSC と結構違いますね。

PAL版でもCPU速度はたいして変わらない、と聞いたことがあったので、NTSCと周波数変わらないのかと思ってた。


ちなみに、SECAM は、PAL をさらに改良した方式で、色が綺麗に出るようです。

信号の作り方は違うけど、解像度や秒間枚数、搬送波の周波数は同じ。




さて、「CPU 速度はほぼ同じ」と聞いていたのはどういうことだろう。

気になって調べてみました。


NTSCPAL
ファミコン1.791.66
Master System3.583.55
スーパーファミコン3.583.55
メガドライブ7.677.61
コモドール641.020.985
AMIGA7.167.09
MSX3.583.58
サターン28.628.6

単位は MHz。有効数字3桁に丸めています。


ファミコンは、NTSC は搬送波の周波数の半分、PAL は 3/8。

Master System ・スーパーファミコンは、NTSC はそのままで、PAL は 4/5。


周波数を整数で割って遅くするのは、「分周回路」と呼ばれ、よく使われるテクニックです。

もっとも、僕はハード工作は詳しくないので、具体的な回路は良く知らない。


3/8 にするなら、あらかじめクロックを3倍速にしておいて、8で割ればいいんじゃないかな。

8で割るのは2進カウンタで、3bit 目を取り出せばよいだけ。


この場合、ビデオ回路側には3で割ったクロックを供給する必要があるけど、3で割るのはちょっと厄介。

もっとも、2進カウンタは基本なので、8 で割る回路と一部共用できると思う。


4/5 も同じ考え方で、4倍速クロックを、4と5で割る必要がある。こちらの場合も、4は簡単で5は少し厄介。

搬送波か、CPUクロックかの、どちらかは簡単になる分数を選んでいるのが、なかなか巧妙。



しかし、メガドライブは、謎です。

68000 は NTSC の 15/7 、 PAL は…91/53? で駆動されているけど、Z80 部分は Master System 互換。

改造して 68000 だけクロックアップ、っていうのが流行したようなので、68000 のクロックはビデオ信号とは無関係なのかな?

(しかし、それだとなぜ NTSC と PAL で速度が違うのかわからない。ビデオ信号回路とのタイミング合わせが必要で微調整されている?)




ところで、「PAL のゲーム」といえば AMIGA です。いや、個人的にそう思っているだけで、おそらく一般性は無いのですが。

AMIGA はアメリカで作られたマシンですが、ヨーロッパで非常に良く売れました。

そのため、PAL で作られたソフトが多く、NTSC で表示すると縦方向解像度の違いから、画面の下の方が表示されなかったりしたそうなのですね。

最初から「テレビに接続する」ことを前提に考えられたマシンで、日本ではウゴウゴルーガの製作に使われていた、という話が有名です。


AMIGA はコモドール社のパソコンなので、8bit 時代の大ヒット機、コモドール 64 も調べたら、やっぱ PAL 版がありました。


コモドール 64 のクロックは、NTSC の 2/7 と PAL の 2/9 なのだけど、なんでこんな厄介そうな数字で割っているだろう。

AMIGA は、 NTSC は 2倍、 PAL は 8/5 になっています。まぁ、こちらは素直な感じ。



MSX とサターンは謎。NTSC 信号を基準にした速度ですが、PAL 版でも同じだったことになってます。


MSX はパソコンだったので、値段が高くなっても速度を重視したのかもしれません。

(それくらいなら、Z80 を 4MHz で駆動すればよかったのに…)


セガサターンは、もしかしたら、本当は PAL で変わっているのだけど、ヨーロッパではあまり売れなかったので資料がないだけかも。




さて、総じて PAL の方が速度が遅かった、という結果になるのですが、実はこんなものは誤差範囲。

ゲームを作るうえでは、CPU の速度が多少変わったことよりも、1秒間の画面枚数が違うことや、解像度が違うことの方が重要でした。


ファミコンでは、PAL 版で画面上の縦の解像度が 240ラインになっています。

NTSC だと、240ラインを出力するのですが、上下は画面外に隠れてしまい、だいたい224ラインしか見えませんでした。

これが全部見える、という意味です。


また、1秒間の画面枚数が 60枚から 50枚に落ちます。

ゲームは画面書き換えを基準に動いていますから、全体にスローモーションになります。

(逆に言えば、全体がスローモーションになるからこそ、CPU 速度が多少落ちても問題はありません)


MSX や SG-1000 で使われたビデオチップ、TMS9918 は、縦方向解像度が 192 ラインでした。

これは、VRAM の構造上変えられない数字。

MSX は、PAL 版でも縦 192 だったようです。


しかし、Master System では、9918上位互換の独自チップを使っているため、縦方向に NTSC では 224、PAL では 240まで出せたようです。つまり、ファミコンと同等能力を持っています。

(MSX2 は VRAM 構造が変わり、212 まで出るようになった。これは NTSC / PAL とも同じだったようだ)



大抵、ゲーム機はリージョン管理というものがされていて、別の国のゲームは動きません。

だから、PAL 版を NTSC 本体で遊んだり、その逆はできない。


でも、先に書いた AMIGA はパソコンで、特にリージョン管理もありませんでした。

だから、NTSC 本体で PAL のソフトを遊ぶと一部が画面外で見えなかったり、PAL 本体で NTSC ゲームを遊ぶと画面外にゴミが出たりしました。


もっとも、その程度の問題は些細な事、と、画面の速度管理が高度に発達したのも AMIGA の頃から。

画面描き変え枚数に関係なくゲームが楽しめるように、内部的に細かな計算を駆使して、ゲーム速度が変わらない工夫などがあったようです。

(現在の PC でも、CPUやビデオカードの性能に関係なく遊べるように時間管理するのは基本テクニックになっています。)




さて、僕はその昔 ST-V (セガサターン)のゲームを作る会社でゲームを作っていたことがあります。

僕は経験していないのですが、別のラインで作ったゲームが好評で、サターン版を作ることになりました。


普通だと、プログラム一式を家庭用が得意な外注に出して、作ってもらいます。

でも、その時は外注が忙しく、自分たちでやることになった。


移植と言っても基本的に同じハードですから、すぐに対応できました。

でも、「ヨーロッパでも売るから PAL 版お願い」という話になって、おかしなことになった。


元々 PAL 版なんて考えてなかったんです。

業務用だと筐体ごと売っているので、ヨーロッパでも NTSC 周波数のモニタ込みで販売していて、言語などだけ変えればそのまま出せるのです。


画面解像度が高く、その分縦に圧縮して表示されてしまうのは…サターンには拡大・縮小機能があったので、適当な倍率をかけて表示することで対応しました。

224 ドットを 240ドットに引き延ばすので…15:14 ですね。14ラインごとに、同じラインを重複して描くことになる。

画面は非常に汚いのだけど「手間を考えるとやむなし」との判断。



それより大変なのは、ゲーム速度が変わってしまうことでした。


全体にスローモーションがかかったような感じ。NTSC の速度で「気持ちよく感じる」ように調整した動きは、全部間延びして気持ちよくありません。


作成したチームは、なんとか簡単に対応できないかと、こちらもグラフィックのように「数フレームごとに表示を飛ばす」とか試していたのだけど、結局あきらめて「スローモーション」のまま完成としました。


ただし、ゲーム上表示されていた「タイマー」だけは、1秒が1秒でなくなると気持ち悪いので、調整されて1秒ごとにカウントダウンします。

残り時間も調整したようですが、表示が2桁しかなかったため、面によっては上限の 99 で…


動きがスローモーションなのに制限時間は短かったりして、非常に厳しいゲームになったようです。

(もっとも、海外では日本よりも厳しいゲーム設定が好まれるため、「そのまま出してしまえ」と判断)


AMIGA のゲームのように最初から PAL 対応を考えていれば良いのですが、NTSC 用に調整したゲームを急に PAL 対応、というのは難しいのです。


#ヨーロッパの人は一般家庭へのテレビゲームの普及が遅かったのだが、これも原因の一つだったかもしれない。


▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

関連ページ

Z80 vs 6502

サターンのCPU

高柳健次郎の誕生日(1899)【日記 15/01/20】

ドットリ君【日記 15/03/16】

6502 は遅かったのか?【日記 14/07/28】

別年同日の日記

02年 誕生日!

11年 節電その後

12年 続・理系と工学系


申し訳ありませんが、現在意見投稿をできない状態にしています

【チューリップ】 SECAMはPALよりも画質が悪いです。SECAM映像を出力するゲーム機は殆どありません (2018-01-08 16:29:49)

あきよし】 情報ありがとうございます。…が、どの機種のことでしょう? 垂直帰線割り込みの意味であれば記事に書いた通りですが… (2014-08-08 05:24:41)

【とおり】 PALとNTSCについては単純に割り込み周期の違いで速度差がでてしまうのです.同期をとってないなら速度は同じですね. (2014-08-07 23:46:11)

6502 は遅かったのか?  2014-07-28 17:34:00  コンピュータ

▲目次へ ⇒この記事のURL

昨日書きましたが、MSX もファミコンも、NTSC 信号を元にしたクロックで動作しました。

MSX はそのまま、ファミコンは半分にしていますので、クロックだけで比べるとファミコンは半分の速度です。


このことを調べていたとき、周波数を根拠として「ファミコンは MSX と比較して遅かった」と記述されたページを多数見ました。

もちろん、CPU が違うので周波数で判断できない、と書いてあるページも多数あるのだけど。


僕はファミリーベーシックで 6502 のアセンブラを覚え、MSX でも Z80 のアセンブラを使いました。

でも、MSX はあまりに「遅い」ので驚いた記憶があります。


その時は Z80 の特性を知らず、Z80 で特に遅い命令を多用してしまったからだったのだけど、自分の中では今でもファミコンは MSX に速度で負けてない、という気持ちがあります。




多分、知らない人が勘違いする大きな理由の一つが、機械語命令には、命令ごとに違う「実行に必要なクロック数」がある、ということ。

最近の CPU では、みんな1クロックで実行するのが普通なので、周波数がそのまま速度に直結します。

もっとも、それでも1クロックで「何ができるか」が違うので、CPU の速度を周波数だけで表すことはできないのだけどね。


6502 や Z80 の時代はもっと激しいです。

命令ごとに、2クロックで終わるようなものから、1000クロック以上かかる命令まであるのですから。


これを考慮しなくては速度比較にはなりません。




プログラム中に非常に良く出てくる操作として、「レジスタとメモリ内容の足し算」があります。

例として、この命令の速度を比較してみましょう。


Z80 では、直接アドレスを指定したメモリと足し算する命令はありません。

そのため、2命令を組み合わせます。


LD HL,nn ; 10 (11)

ADD A,(HL) ; 7 (8)


nn は、2バイトの数値を意味しています。


; 以降に、実行に必要なクロック数を書きました。( ) の中は MSX の場合です。

MSX がなぜ遅いのか…という説明は後で書きます。


ここでは、MSX を比較対象として ( ) の中の数値を合計すると、19クロックで完了します。


6502 の足し算命令では、必ずキャリー(桁上がり)を足してしまうため、足し算の前にキャリーを消す必要がありました

また、計算用レジスタは1つしかないため、相手のメモリアドレスだけを指定します。


CLC ; 2

ADC nn ; 4


こちらは合計 6クロック…なのですが、もっと速くできます


6502 の場合、上に書いたように、計算用レジスタが1つしかありません。

そこで、メモリの先頭、8bit でアドレスを表現できる範囲までに限り、高速にアクセスできる方法が用意されていて、256byte をレジスタ代わりに使えるようになっていました。

(6502 では、256 byte ごとに「ページ」と呼んだため、ゼロページアドレッシング、と呼びます)


CLC ; 2

ADC n ; 3


n は1バイトの数値を意味しています。

こちらでは、1クロック減って合計 5クロックです。


ファミコンは半分の周波数で動いている、と考えても、MSX よりもファミコンの方が倍近く速いです。




上の例ではメモリと足し算しましたが、Z80 はメモリアクセスが遅かったため、できるだけメモリアクセスしないテクニックが重要でした。


では、 B レジスタから A レジスタにデータを渡してみましょう。


LD A,B ; 4 (5)



6502 では、レジスタが A X Y の3つしかないため、あまりレジスタ渡しは使いませんでした。

しかし、X から A に渡すのであれば


TXA ; 2


この場合、半分の周波数と考慮しても、ファミコンは MSX より速いです。


現実には 6502 では、ゼロページをレジスタのように使いました。

メモリ相手なので少し遅いのですが、256 本もレジスタがある、と考えるとプログラムの幅が広がります。


LDA n ; 3


メモリを使うにも関わらず、Z80 よりも少ないクロックで動作します。

とはいえ、周波数を考慮すると、この方法ではファミコンよりも MSX の方が速い。


メモリアクセスは遅いのです。




もっと単純に「A に 1 を入れる」を考えてみます。


Z80 では


LD A,#1 ; 7 (8)


6502 では、


LDA #1 ; 2


こちらは、ファミコンの方が圧倒的に速い。


Z80 では、先に挙げた LD A,B は 1バイトの命令でした。そのため、メモリアクセスは1回で済みます。

しかし、LD A,#1 は、 LD A という命令部分と、1 という数値部分の 2バイトに別れていて、2回のメモリアクセスが必要になります。

6502 の LDA #1 でも同様に2バイト命令なのですが、Z80 はメモリアクセスが非常に遅く、6502 と大きく差がつく原因になっています。




さらに、「A に 0 を入れる」。

同じじゃないの? と思われそうですが、Z80 では


SUB A ; 4 (5)


A から A を引いて A に入れる、です。結果は必ず 0 。

一見無意味な命令ですが、メモリアクセスがないので LD A,#0 より速いです。

(同様の意味で XOR A というのも良く使われました。速度は同じ)


6502 では、素直に


LDA #0 ; 2


MSX の方がほんのわずかに遅いのですが、ほぼ同等。




6502 には、インデックスレジスタが X と Y の2つありました。

Z80 にも、IX と IY の二つがあります。


ここで、「インデックスレジスタと数値を足したアドレスの内容を A に読み込む」をしてみましょう。

(インデックスレジスタ相対アドレッシング)


Z80 は、IX と IY は 16 bit で、そこに 8bit の固定値 o (8bitの符号付数値)を足せます。

6502 では、nn は 16bit アドレスで、そこに 8bit の X や Y を足せます。


Z80 では


LD A,(IX + o) ; 19 (21)


6502 では、


LDA nn,X ; 4


ただし、6502 ではページ境界(256byte 単位の区切り)を超えると、 5クロックになります。

(nn + X の結果、上位8bit が nn と違う値になると、追加の1クロックが発生)


こちらは、ファミコンの方が倍以上速い。

インデックスレジスタ相対アドレッシングは、Z80 で特に遅い命令の一つです。

(実は、この命令は 3byte もあり、メモリアクセスが多いのです。)


最初に書いた、僕が「Z80 が遅くて驚いた」理由は、はじめて作った機械語プログラムで、知らずにインデックスレジスタを多用してしまったため。

6502 では特に遅くないので、配列アクセスのための基本テクニックなのですよ。

(というか、インデックスレジスタとはそのためにあるものです)


配列アクセスは多数の敵を動かすゲームで使いたい機能なのだけど、Z80 でゲーム作るときには、絶対使っちゃダメな命令。




さて、機械語が並べられた説明ばかり続いて、そろそろ飽きられそうです。

ちょっと話を変えましょう。


CPU が命令を実行する際は、内部的には次の3つの動作が行われます。


1) メモリにアドレスを送る

2) メモリからデータを読み込む

3) 命令を実行する


これは、順番に行わなくてはなりません。

つまり、一般的に CPU が命令実行に必要な最低クロック数は 3。


ところが、Z80 では、命令を実行するための最低クロック数は 4(MSX の場合は 5)、6502 では 2 です。


<<以下、この節のみ、2014.7.31 に内容変更。

  書き換え前の物は HTML コメントとして残っています>>


元はこの節で、Z80 が遅く、6502 が速い理由について内部構造を解説した…のですが、僕は回路知識が乏しいため、間違っていたようです。


書き換え前は、主に、


・Z80 は 4004 由来で内部バスが4bit である。

・Z80 には命令実行時に1クロック待つことができたが、MSX では回路の都合からこの機能を使っている。


・6502 は、命令実行中に次の命令を読み込んでいた

・6502 は、1クロックで2つの動作ができた


ことを説明し、Z80 はこれが理由で通常より1クロック遅れ、MSX ではさらにもう1クロック遅れるとしました。

一方、6502 では通常より1クロック速くなり、命令によっては追加のメモリアクセスがあるにも関わらず2クロック動作だった、と書いていました。



これに対し、Z80 の内部バス 4bit は ALU (演算回路) 4bit の間違いではないか、と指摘があり、再度調べたところその通りでした。


元の文章を書いた際の参考文献は、R800 (Z80 互換の 16bit CPU) の設計者のインタビュー記事(MSX マガジン永久保存版2収録)。

ここに、「Z80 は / 内部のバスなんかは 4bit だった / だから簡単な命令でも、4クロックで2回に分けて転送したりする」という証言があります。

これを見て、内部バスが 4bit なので余計なクロックが必要となっている、と理解しましたが、これが勘違いでした。


指摘後、詳細情報を調べるために手持ち資料を漁ったところ、Z80 設計者の嶋正利さんの自伝「マイクロコンピュータの誕生 わが青春の 4004」に詳細がありました。

信憑性は、もちろん後者の方がずっと上です。




嶋さんは世界初の CPU 、4004 の設計者でした。これは、日本の会社に在籍しながらインテルと協力して設計したものです。

嶋さんは 4004 完成後に日本に帰国、インテルは 8bit 化した 8008 を作りますが、4004 よりも遅く、周辺回路設計が難しく、ソフトウェアも作りにくい CPU でした。


この後、インテルはリコーに在籍していた嶋さんを「インテルに入社する」ように説得。

最終的にはリコーの人事部にまでインテルから直接交渉が入ります。

リコーの人事部は引き抜きに対して怒りながらも、4年間の休職が認められます。

(これは、4年以内ならいつでも戻ってこい、ということでもあります。神対応!)


ここで、嶋さんは 8080 を設計します。

設計の際には、周辺回路の作りやすさが重視されました。



自伝では、この部分で「遅さ」の理由が明らかにされています。


8080 でも、内部的には1クロックで2つの動作を行っていますが、「外部に対しては」わかりやすく、1クロックで1つの動作しか行わないようにしています。

また、外部にアクセスする際には、CPU の内部状態をデータバスに送出するようにしています。これにより、周辺 LSI はCPU が外部アクセスする「理由」を知ることができ、柔軟な回路設計が可能となるのです。


このため、メモリへのアクセスは「アドレス送信」「CPUステータス送信」「データへのアクセス」という3クロックが必要となります。




Z80 は、嶋さんが仲間と共にインテルをスピンオフし、設立されたザイログ社で作られた CPU です。

別会社なので、回路は完全に新規に作り直していますが、8080 の上位互換になるように設計されています。


この時に、内部回路の高速化によって、ALU は 4bit で十分になっています。

(4bit なのは 4004 由来ではありませんでした)


さらに回路設計をしやすくする工夫が加えられます。Z80 には、DRAM を使用する際に必ず必要な「リフレッシュ回路」が内蔵されているのです。


リフレッシュ回路は、命令実行時に動作します。

これは、命令実行時は CPU 内部で演算が行われていて、メモリは暇なためです。


一方、8080 には存在していなかった「CPU 動作とは関係のないメモリアクセス」が行われるため、命令の読み込みは通常のメモリアクセスよりも早めに切り上げる必要がありました。


また、MSX では、メモリは Z80 には直接接続されていません。

スロット、と呼ばれる仕組みを使い、64Kbyte しかない Z80 のメモリ空間を、1Mbyte に拡張しているのです。


その代償として、スロットへのクロックは、Z80 に供給されるものと比較して、最大で 80ns 遅延しました。


・Z80 では命令実行時のみリフレッシュ回路が働くため、メモリアクセスを通常より速く行わなくてはならない

・MSX ではメモリを直接接続していないため、拡張性と引き換えにアクセスが低速になっている


この2つのことから、MSX では「命令の読み込みが間に合わない」場合が生じます。

その対応として、命令読み込み時のみ、メモリアクセス時に CPU を 1クロックだけ停止させ、メモリのアクセス時間を稼いでいました。


これが、MSX の命令が Z80 標準よりさらに1クロック遅い理由です。

(なお、一部命令では命令部分がプリフィックス付の 2byte です。この場合、「命令」の読み込みを2回繰り返すため、2クロック遅くなります)


以上、Z80 が遅い理由は、

・周辺回路の設計しやすさを考慮し、高速性よりもわかりやすさを優先している。このため、メモリアクセスだけで3クロック。

・MSX では、メモリ空間が増大した代償としてメモリアクセスが遅れるため、命令読み込み時のみ1クロックの待ち時間が追加される。

でした。




6502 は、Z80 とは違い、メモリアクセスを最短時間で行います。

1クロックの間に、アドレスの送信とメモリアクセスを行うため、データの取得自体は1クロックです。


命令実行時は、Z80 はリフレッシュ回路を動かしていました。

しかし、6502 は「命令の次のアドレス内容」をすぐに読み込んでしまいます。


次の内容は、命令に使われるデータかもしれませんし、次の命令かもしれません。

これにより、 LDA #1 のような命令でも、たったの2クロックで終わらせることができます。

(実際には、命令読み込み、命令解釈&データ取得、命令実行の3クロックかかっているが、命令実行中には次の命令を読み込んでいるため、見た目上1クロック短くなる)


命令解釈と命令実行はわかれているようで、データが不要な CLC (クリアキャリー)のような命令でも、2クロックになります。

この際、命令解釈時点で得た「次のメモリ内容」は、そのまま捨てられ、再度同じアドレスを命令実行時に取得するようです。


このため、最低実行時間は2クロックです。


参考:hpcl6502

FPGAで実装された 6502 と、アクセスタイミングなどの説明。

互換品に過ぎないわけですが、6502 は回路構成が単純で作りやすいようで、同等の試みが世界中で行われています。

製作者も良く検討して作っているようなので、互換品とはいえ信頼できると思って参考にしています。






さて、先ほどは単純な機能でクロックを比較しましたが、これだと 6502 に有利な命令ばかり選んでいるのではないか、という気もします。

もう少し、Z80に有利な条件で見てみましょう。


Z80 はレジスタが多いですし、一部のレジスタでは 16bit 計算もできます。

また、ループ専用の命令もあります。

これらは 6502 にはないものです。


また、Z80 はメモリアクセスが遅いので、レジスタの多さを活かしてメモリアクセスがない題材を考えましょう。


そこで、1~100 の数字を全て足すプログラムを作ってみましょう。

答えは 5050 です。8bit には収まらないので、16bit 計算が必要です。


Z80だと次のようになります。


LD HL,#0 ; 10 (11)

LD DE,#1 ; 10 (11)

LD B,#100 ; 7 (8)

LOOP:

ADD HL,DE ; 11 (12)

INC DE ; 6 (7)

DJNZ LOOP ; 13 / 8 (14 / 9)


結果は HL に入ります。


ループごとに1つづつ値が変わる変数、として DE と B の2つがあり、無駄っぽく見えます。

でも、16bit 演算は 16bit のレジスタ同士でないとできないため、DE は必要で、16bit レジスタの INC / DEC ではフラグ変化がないため、B も必要です。


そして、DJNZ は B を暗黙に使用し、減算結果が 0 でない場合はジャンプします。

クロック数を2つ書いてあるのは、ジャンプするときは 14クロック、しない時は 9 クロックになるため。

LOOP: はラベル。アドレスを示す目印で命令ではありません。


LOOP 以前の部分の合計は MSX で 30 クロック。LOOP 以下は 33 クロックですが、100 回繰り返されるので、3300クロック。

ただし、最後の1回は 5 クロック短いので、3295クロック。

総計は 3325 クロックです。


6502 だと次のようになります。


LDA #0 ; 2

STA >0 ; 3

STA >1 ; 3

LDA #100 ; 2

STA >2 ; 3

LOOP:

CLC ; 2

LDA >0 ; 3

ADC >2 ; 3

STA >0 ; 3

LDA >1 ; 2

ADC #0 ; 2

STA >1 ; 3

DEC >2 ; 5

BNE LOOP ; 3 / 2



6502長げーよ。


レジスタが1個しかないため、ゼロページアドレッシングを使っています。 >0 は、ゼロページの 0 番地の意味。

最終結果は 16bit なので >0 と >1 に置き、ループ変数は「足す数」と同じで >2 に置きます。


6502 の加算命令は、常にキャリーを一緒に足すため、CLC でキャリークリアしてから開始。

足す数は 8bit しかないので、上位 8bit には #0 で 0 を指定しています。


LOOP 以前の部分が 13クロック。LOOP 後は 26クロックで、100回繰り返されるので 2600クロック。

ただし、最後の1回は1クロック短いので、2599クロック。


総計で、2625 クロックです。



ファミコンと MSX でいえば、ファミコンが5割ほど遅いです。

しかし、Z80 に一方的に有利な条件で考えた題材にしては、ファミコンは健闘しています。



実際にはファミコンと MSX は CPU としては同程度の速度だったように思います。

Dhrystone とか、BASIC で同じプログラムを走らせてみるとか、ベンチマーク比較はいろいろ見たのですが、CPU の性能と言うより「言語処理系の性能」が色濃く反映されてしまい、均一な速度指標が得られません。


ただ、リストによって 6502 の方が速かったり、Z80 の方が速かったりするのも事実。

(6502 を Z80 の半分の周波数にする形で比較した場合)


つまり、言語による差はあれど、CPU としてはだいたい同じだったのではないかと。



ウォズが 6502 を Apple I に使ったのは、欲しかった 6800 とよく似ているのにずっと安かったから。

ファミコンが 6502 を採用したのは、あまり使われてなくて解析されにくかったから…という理由もあるけど、「Z80 よりも小さな回路サイズなので、Z80 と同じサイズなら、別の機能も入れられる」ためだったらしい。


いずれにせよ、性能が他の CPU とほぼ同等なのに、6502 はコスト面で有利な CPU だったのでしょう。



ファミコンと MSX でいえば、CPU 性能よりも画面周り回路の違いが大きかったように思います。

どっちが良い、ではなくて、違いがはっきりしていて、一長一短あった。


当時は僕は両方持っていたので、同じゲームが両機種にあれば、より上手に作られている方を楽しんでいました。

グラディウスとか、ファミコンより MSX の方が、遥かに良移植だった。


もちろん、スクロールはファミコンの方が滑らかでしたけどね。


2014.8.3 追記

僕の書いたプログラムは、「同程度の性能であることの比較」ができれば十分、という意図だったのですが、もっと速く出来るというご意見を多数いただきました。

非常に面白かったため、解説も含めて別記事にしました。更なる改良もお待ちしております。




▲目次へ ⇒この記事のURL

同じテーマの日記(最近の一覧)

コンピュータ

関連ページ

ランダムアクセス

Z80 vs 6502

「ああ播磨灘」ゲームボーイ版【日記 15/02/16】

ファミコン・SG-1000の発売日(1983)【日記 15/07/15】

続・6502は遅かったのか?【日記 14/09/06】

別年同日の日記

06年 誕生日

07年 誕生日

08年 海の日

08年 誕生日

09年 水族館

15年 マイコプラズマ肺炎:治癒報告

16年 セガサターンモデム


申し訳ありませんが、現在意見投稿をできない状態にしています

【オールドプログラマ】 Z80と比べて遅いって…当時現役で仕事で使っていた人間なら全員鼻で笑いますね… (2016-06-04 12:47:36)

あきよし】 情報ありがとうございます。ファミコンで実際使われていた、という証言は重いです。この方法をありにして、別ページの方を書き変えました。ただ、ループ展開は制限させてもらっています(展開競争は虚しいので)。 (2014-08-04 10:16:58)

【名無し】 巨大テーブルはレジスタ間演算を高速にやりたい他のルーチンからも共用できるので、ある程度以上の大きさのプログラムでは非現実的なものではない筈です。ファミコンのプログラムで見掛けたこともありますし、http://wiki.nesdev.com/w/index.php/6502_assembly_optimisations なんかでもテクニックのひとつとして紹介されてますね。 (2014-08-03 17:01:28)

あきよし】 巨大テーブル化。速度は速いですが、コスト・効率比が悪すぎて現実的に使われることは無いテクニックだと思います。そのため、比較としては NG。ただ、この発想は僕はすごく好きです。 (2014-08-03 16:45:27)

あきよし】 みなさん、改良案ありがとうございます。別記事を書きましたので、今後はそちらに投稿していただけるとありがたいです。 (2014-08-03 16:42:43)

【名無し】 以上のコードでおよそ1120クロック程度です。 (2014-08-02 12:41:20)

【名無し】 記事のタイトルが「6502 は遅かったのか?」であり、コードサイズはかんけいないので ORG $C000;LDY #100;LDA #0;TAX;JMP SKIP;INCH:;INX;DEY;BEQ EXIT;SKIP:;CLC;LOOP:;ADC TABLE,Y;BCS INCH;DEY;BEQ EXIT;ADC TABLE,Y;BCS INCH;DEY;BEQ EXIT;ADC TABLE,Y;BCS INCH;DEY;BEQ EXIT;ADC TABLE,Y;BCS INCH;DEY;BEQ EXIT;ADC TABLE,Y;BCS INCH;DEY;BNE LOOP;EXIT:;STA >0;STX >1;;ORG $C100;TABLE:;DB $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0A,$0B,$0C,$0D,$0E,$0F;DB $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1A,$1B,$1C,$1D,$1E,$1F;DB $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2A,$2B,$2C,$2D,$2E,$2F;DB $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3A,$3B,$3C,$3D,$3E,$3F;DB $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4A,$4B,$4C,$4D,$4E,$4F;DB $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5A,$5B,$5C,$5D,$5E,$5F;DB $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6A,$6B,$6C,$6D,$6E,$6F;DB $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7A,$7B,$7C,$7D,$7E,$7F;DB $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8A,$8B,$8C,$8D,$8E,$8F;DB $90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9A,$9B,$9C,$9D,$9E,$9F;DB $A0,$A1,$A2,$A3,$A4,$A5,$A6,$A7,$A8,$A9,$AA,$AB,$AC,$AD,$AE,$AF;DB $B0,$B1,$B2,$B3,$B4,$B5,$B6,$B7,$B8,$B9,$BA,$BB,$BC,$BD,$BE,$BF;DB $C0,$C1,$C2,$C3,$C4,$C5,$C6,$C7,$C8,$C9,$CA,$CB,$CC,$CD,$CE,$CF;DB $D0,$D1,$D2,$D3,$D4,$D5,$D6,$D7,$D8,$D9,$DA,$DB,$DC,$DD,$DE,$DF;DB $E0,$E1,$E2,$E3,$E4,$E5,$E6,$E7,$E8,$E9,$EA,$EB,$EC,$ED,$EE,$EF;DB $F0,$F1,$F2,$F3,$F4,$F5,$F6,$F7,$F8,$F9,$FA,$FB,$FC,$FD,$FE,$FF (2014-08-02 12:40:15)

【名無し】 6502の高速版のコードサイズが28バイトなので、Z80で同程度のコードサイズが許されるならば若干のループ展開が可能になります。LD HL,0;LD BC,100;LOOP:;ADD HL,BC;DEC C;JR Z,EXIT;ADD HL,BC;DEC C;JR Z,EXIT;ADD HL,BC;DEC C;JR Z,EXIT;ADD HL,BC;DEC C;JR Z,EXIT;ADD HL,BC;DEC C;JP NZ,LOOP;EXIT: で27バイト、2582クロックなので、ファミコンには勝ったことになると思います。 (2014-08-01 18:25:49)

【名無し】 訂正: ジャンプに1wait足すのを忘れてました。11+11+100*(12+5+11)=2822クロックで、ファミコンには僅かに負けます。 (2014-07-31 21:44:23)

【名無し】 jr nz,loop を jp nz,loop にすると更に速くなります。11+11+100*(12+5+10)=2722クロックで、半分のクロック速度のファミコンの1395クロックよりは速いことになりますね。 (2014-07-31 21:39:19)

【m】 ループ内が短すぎてほとんどどうにもなりませんが、ld hl,0; ld bc,100; loop: add hl,bc; dec c; jr nz,loop のほうが少し速い(100から1まで足す,になりますが)。単純に総和を取るんじゃなくて公式 n*(n+1)/2 のほうで比べるとかすれば z80 のほうが速いかも (2014-07-31 21:19:15)

【名無し】 6502の高速版プログラムですが2+3+2+2+3+2+19*(3+3+2+5+2+2)+81*(3+2+5+3)-1+3+3=1395クロックが正しいようです。先の「1357クロック」は、おそらくはキャリーが発生した際のCLCを計算に入れなかったミスっぽい。 (2014-07-31 21:00:06)

【名無し】 Z80に花を持たせるにはメモリのブロック転送などが有効だと思います。Z80ではLDIRで済む程度の処理が6502では案外面倒なことになります。 (2014-07-31 16:59:55)

【名無し】 ご対応ありがとうございます。「Z80 版は、計算したところ残念ながら却って遅くなっていました」とのことですが、XOR A;LD H,A;LD B,100;LOOP:ADD A,B;JP NC,SKIP;INC H;SKIP:DJNZ LOOP;LD L,Aで3113クロックとなり、遅くなってはいないと思います。ちなみに6502版にロジックを合わせてXOR A;LD H,A;LD B,100;JP LOOP;INCH:INC H;DEC B;JR Z,EXIT;LOOP:ADD A,B;JR C,INCH;DJNZ LOOP;EXIT:LD L,Aとすると2900クロックで更に高速化できます。 (2014-07-31 16:51:25)

あきよし】 ご意見ありがとうございます。参考に修正しました。 (2014-07-31 12:59:53)

【名無し】 LDA #100;STA >2;LDA #0;TAX;JMP SKIP;INCH:INX;DEC >2;BEQ EXIT;SKIP:CLC;LOOP:ADC >2;BCS INCH;DEC >2;BNE LOOP;EXIT:STA >0;STX >1 で1357クロックなので、クロック速度倍のZ80と比べてもいくらか速いと思います。 (2014-07-29 20:00:49)

【名無し】 6502、LDA #100;STA >2;LDA #0;TAX;CLC;LOOP:ADC >2;BCC SKIP;INX;CLC;SKIP:DEC >2;BNE LOOP;STA >0;STX >1 で1800くらいかな。 (2014-07-29 04:53:58)

あきよし】 早期に書き変えたいと思いますが、次の週末かな…申し訳ない。 (2014-07-29 04:52:34)

あきよし】 ご意見多数ありがとうございます。感謝いたします。特に、より高速なプログラムを示してくれたのは非常にありがたいです。(もう何十年も使ってなかったので勘が鈍ってます) (2014-07-29 04:51:32)

【名無し】 「1~100 の数字を全て足すプログラム」 Z80でも16bitレジスタを使わずに XOR A;LD H,A;LD B,100;LOOP:ADD A,B;JP NC,SKIP;INC H;SKIP:DJNZ LOOP;LD L,A 等としたほうが高速です。6502版は更に無駄が多すぎ。 (2014-07-29 01:38:48)

【名無し】 「0.5 クロック単位で作業ができるため、0.5クロック目で「アドレス送信」を行い、1クロック目で「データ読み込み」を行うことで、1クロックで読み込みが完了するのです。」タイミングチャート見てもそういうことにはなってないですね。http://www.mdawson.net/vic20chrome/cpu/mos_6500_mpu_preliminary_may_1976.pdf (2014-07-29 01:25:18)

【名無し】 「命令実行前に1クロック待つ」のは外部回路によるもので、Z80の機能ではないし同等のことは他のプロセッサでも可能です。 (2014-07-29 01:20:26)

【名無し】 Z80について「内部バスが 4bit しかない」というのはALUの間違いでは? Z80が「命令を実行するための最低クロック数は 4」である主な原因はM1サイクルの前半と後半でそれぞれ2クロック掛けて外部バスをアクセスしているためだと思います(それだけではないだろうが)。 (2014-07-29 01:17:49)

【名無し】 6502でLDA (nn,X)のアドレッシングはIndexed Indirectになるので「インデックスレジスタと数値を足したアドレスの内容を A に読み込む」とは動作が異なります。 (2014-07-29 01:13:01)

【名無し】 「A に 1 を入れる」のは、6502ではA9 01、Z80では3E 01で大して変わりありません。「ファミコンの方が圧倒的に速い。 1という数字が、命令の一部とはいえ、メモリに入っているためです」という説明は意味不明。 (2014-07-29 01:11:09)


戻る
トップページへ

-- share --

0000

-- follow --




- Reverse Link -