2012年01月23日の日記です


ゲームボーイの CPU  2012-01-23 17:22:01  コンピュータ

うかつな事に、1年近く前に「ゲームボーイシリーズが CPU に 8080 を採用」と書いてしまった


その後、WEB 上の各種ソースをあたるも、みな「Z80」と書いてある。

おかしいなぁ、自分の記憶では、大学時代にバイトしていた会社で閲覧した任天堂公式資料に「8080カスタム」とあった気がするのだが。

(もっとも、社外秘の資料なので当然現在持っていないし、古い記憶なので思い違いかもしれない)


しかし、探せばあるもので、ゲームボーイ(以下 GB と書く)の CPU を詳しく解説した資料があった。


家には Z80 の資料はある。これで比較できる…

と思ったけど、それじゃ片手落ち。8080 も調べなくては。


で、調べたら、8080 と Z80 の機械語コードを、対比させて網羅しているページがあった。


これで比較ができる。




えーと、比較しながら、8080 / Z80 / GB CPU の動作詳細をまとめた資料を作ったのだけど、公開はしないでおきます。

長いばかりでつまらないから。知りたい人は、上のリンクを読んで自分で調べてね。


概要だけまとめます。

まず、GB CPU Manual は良い資料なのだけど、冒頭のほうにある CPU 機能のオーバービューは結構間違えているので注意するように。

後ろの CPU 命令の詳細資料は、ほぼ正しいと思われるけど、CB prefix 系の、BIT SET RES 命令のオペコードなどは間違えているようだ。

(疑問があったのでほかのソースも当たって判断)



で、8080 と Z80 と GB CPU の違いを、GB 主体で書くと次のような感じだ。



・Z80 で追加されたレジスタは、GB CPU には存在しない。


・当然、上記レジスタに関連する Z80 の追加命令は GB CPU には存在しない。


・Z80 で追加された命令のうち「ED prefix」系の命令は GB CPU には存在しない。

 ED prifix 命令には、I/O命令、16bitメモリロード命令、16bit キャリー付加減算命令、割込み制御命令、Aレジスタの符号反転、メモリ 4bit ローテート命令、ブロック転送命令、ブロックサーチ命令が含まれる。


以上は、「Z80 で追加されたものは、GB CPU にはない」と言う話だ。つまり、単に 8080 互換。



・8080 から存在し、Z80 で拡張された「レジスタ交換命令」は、GB CPU には存在しない。


・8080 から存在し、Z80 で拡張された「I/O命令」は、GB CPU には存在しない。


・8080 から存在し、Z80 で拡張された、6個の「フラグ」を整理統合。

 8080 由来3個(Z C H)、Z80由来1個(N)の4つになった。

 整理されたフラグを使用した「条件ジャンプ命令」(8080に存在)は GB CPU には存在しない。


以上は、「8080 に存在したものが存在しない」と言う話だ。8080 のサブセットになった。


Z80由来のフラグ(N)が増えたが、実はこのフラグを使用する命令は、Z80 では増えていない。

そのため、GB CPU でもフラグが増加したにもかかわらず、命令は増えていない。

じゃぁ、なんのためにこのフラグが用意されたのか、という理由は次で述べる。



・Z80 で拡張された「CB prifix」系の命令(ビット操作命令)は、GB CPU にすべて存在する。

 ビットテスト、ビットセット、ビットリセット、シフト、ローテートが含まれる。

 (8080 には、A レジスタのローテートのみ存在した)


・Z80 で拡張された「相対ジャンプ命令」は GB CPU にほとんど存在する。

 ただし、相対ジャンプと同時にカウントを行う「ループ命令」は存在しない。


・8080 では BCD 演算補助命令が加算時しか使用できなかった。

 Z80 では、同命令の動作が変更され、加算だけでなく減算でも使用できるようになった。

 GB CPU では、Z80 と同様の機能が存在する。

 (先に説明した、Z80 でフラグが増加したのに命令が増えていないのは、この命令の動作変更のため)


以上が、「Z80 で拡張されたものが存在する」と言う話だ。

Z80 での拡張を含むので、GB CPU は Z80 のサブセット、と言えなくもない。


しかし、Z80 と比較した場合、「存在しない命令」がはるかに多く、8080 と比較した場合「追加・削除された命令」がわずかにある程度だ。

これで Z80 相当、と呼ぶのはつらい気がする。




GB CPU には、独自の拡張命令もある。


まずは、スタックポインタ(SP レジスタ)の演算命令。

8080/Z80 とも、スタックは「特別なもの」扱いなので、直接演算命令を用意していない。

1つづつの加算・減算程度はできるが、それ以上に複雑なことをするには、別のレジスタの仲介が必要で面倒だった。


GB CPU ではこれが改められ、スタックポインタも普通のレジスタの一種にしている。

直接読み出しができるし、直接加算ができる。


そして、「SP からの相対位置で」示されるアドレスからの読出しができる。SPレジスタ相対アドレッシングだ。


2017.3.27 追記

この部分、勘違いしてた。コメント欄で教えてくださっていた方がいたのに、気づくのが遅れました。


追加命令 LD HL,SP+n を勘違いしたのだけど、これは「SP に n を足した数値を HL に入れる」だった。

つまり、SP 相対アドレスを HL に取り出す、アドレス計算命令に過ぎない。(68000 や x86 の lea に類似)


元はこの後「ローカルスコープが作れるようになる」と書いていたが、上記のように勘違いなのでできない。


とはいえ、HL にアドレスを取り出したら、次は LD A,(HL) のようにしてメモリ内容にアクセスしたくなる。

すぐ下に書くが、HL によるアクセスは強力に拡張されているので、やはりローカルスコープを作り出す目的かもしれない。


メモリと A レジスタ間での読み書き命令も拡張された。

8080 の A レジスタと、アドレス直値で指定されたメモリとの読み書き命令は、「HL で示したアドレスに読み書きした後、HL を増減」という命令に変更された。

ポストインクリメント/デクリメント・アドレスレジスタ間接アドレッシングだ。8080 相当の CPU に付加するには、かなり強力な機能。

元の命令は、なぜか違う命令コードになったが、ちゃんと残っているのでご安心を。


また、アドレス FF00 に 1byte 数字、もしくは C レジスタの内容を足したアドレスに読み書きする命令も作られた。

これは、ファミコンで慣れた 6502 の0ページアドレッシングがほしかったのだろう。便利だからね、あれ

と同時に、Z80 に存在する I/O 命令相当のこともこなしている(だから、Cレジスタでアドレス指定なのだろう)。一石二鳥の拡張命令だ。

(GB では、FF00 からの領域に、I/O と CPU 内部 RAM が配置されている)


レジスタの上位 4bit と下位 4bit を交換する、と言う命令もある。Z80 の 4bit ローテート命令とも動作が違う。

普通のローテート4回と同じだが、ゲームなので高速性が求められるだろうし、4bit 単位と言うのは、実際よく使うのだ。



携帯ゲーム機用らしく、省電力のための拡張命令も2つある。

ひとつは、8080 から存在する「CPU 停止命令」だ。本来の命令は、プログラムの実行が停止するだけで、CPU の機能自体はすべて動き続ける。


GB CPU では、CPU と ROM へのクロック供給を停止し、本当に CPU を止めてしまう。


ゲームは画面書き換えの 1/60 秒(以下、1インタと表現)を単位として動いている。

だから、すべての処理は1インタ以内に終わらせないといけない。

処理が「一番重いとき」でこの時間に間に合わせるのだから、通常は 0.8インタとかで終わらせていて、残りの時間は1インタのタイミングが来るのを待っている。


普通なら、「待っている」ためのプログラムを作る。何もしないでタイミングを待ち続けるループ。

これ、何もしていないけど、CPU としては動いているので電力を消費する。


ところが、GB CPU では、先に書いた CPU 停止命令がある。「何もしない」時に停止させてしまう。

停止した CPU を起こす機能もちゃんとあって、これが「画面書き換えのタイミング」に設定されている。


「画面書き換え待ち」という、本来やりたいことはちゃんと実現されているうえ、CPU を停止させることで電力消費を抑え、バッテリーを長持ちさせる。

(先に書いたように、処理が 0.8インタで終わるのであれば、CPU はゲーム時間の2割も停止し、その分省電力にできる)


この機能を CPU に追加させる、というのは、携帯ゲーム用に開発された CPU としては素晴らしい着眼点だ。



もうひとつは、「システム停止命令」だ。これは新設された命令。

GB の画面表示回路への通電を切った上、上に書いた CPU 停止状態に入る。いわゆる、サスペンドモードだ。


CPU 停止状態は割り込みがかかると終了するのだが、通常一番使われるのが、上に書いた通り画面書き換えタイミングの割り込みだ。

ところが、システム停止中は画面表示が停止しているため、これらの割り込みもかからない。

サスペンドモードは、ボタンを押すことで終了する。実は、GB では、ボタンはI/Oポートにつなげられているが、押すことで割り込みを発生することもできる設計なのだ。



割り込みの話ついでに、「割込みルーチンからの復帰」命令。


8080では、割り込みからの復帰は「サブルーチンからの復帰」命令で行う。割り込みというのは、強制的なサブルーチン呼び出しのことだからね。

Z80 では、割込み復帰命令と言う専用の命令が作られた。しかし実は、この命令の動作は「サブルーチンからの復帰」とまったく同じなのだ。実際、多くのシステムで、割り込みからの復帰にサブルーチンからの復帰命令を使って構わない。

じゃぁ、割り込みからの復帰命令っていうのは何なのか、って説明はややこしいので省略


GB CPU では、割り込みが起こったときの CPU の動作が 8080 や Z80 とは違う。だから、サブルーチンからの復帰命令で戻ると、その後の動作がおかしくなる。そのために専用命令が準備された。動作が Z80 と異なるだけでなく、命令コードも違う。


GB CPU Manual では、この命令は「Z80 の命令コードを変えて残された命令」という扱いになっているが、これは GB CPU 独自の拡張命令と見たほうがよいだろう。

(アセンブラのニーモニックは RETI で同じだけど、これは RETurn Interrupt の意味にすぎない。Z80 と同じ命令だとする根拠としては弱すぎる。)




で、散々比較して思った。

元ゲームプログラマとしては、この CPU がゲーム向きに巧妙にカスタマイズされているのが、よくわかる。

特に、消費電力を抑える仕組みとか、割込み処理の変更とか、地味だけどよくできている。


GB CPU を作ったのはシャープ(LR35902という型番がついている)。

ザイログと仲がよく、Z80 のセカンドソース品も作っていたし、Z80 を使用した PC もたくさん出していた。


シャープは任天堂とも仲がよかった。

ファミコンは 6502 だったが、次のゲーム機ではぜひ Z80 を、と薦めたのではなかろうか。


でも、Z80 でアセンブラをやったことがある人ならわかると思うが、Z80 の拡張命令には、遅いものが多い。

便利でいいのだけど、速度が重視されるゲームではあまり使えない。


だから、ゲームを作るときは、ほとんど 8080 相当の命令しか使わないのだ。

Z80 の拡張部分は、CPU の回路を複雑にしているだけで、ゲームを作る場合にはほとんどが無駄。

その一方、ゲームにほしい割込み処理とかは貧弱で、まともな処理をしたければ周辺 IC を追加しないといけない。


回路規模が小さくなれば、CPUサイズも小さくなり、コストは下がる。周辺 IC が不要になれば、コストも下がるし機械も小さくできる。

「おもちゃメーカー」である任天堂が、携帯機を設計しているのだ。コストやサイズは気になるところだ。

だから、シャープの思惑通り Z80 を採用する交換条件として、大幅に機能を削り、CPU 単体で割込み処理などを行えるようにするカスタマイズを依頼したのではないだろうか。



この場合、任天堂の目指したのは「8080 カスタム」だろう。公式資料にそう書いていたとしても、おかしくはない。

むしろ、Z80 と書いてしまうと、機能を削除した部分が貧弱になったと批判されかねず、「8080 に機能追加した」としたほうが、いろいろな意味で穏当であっただろう。


一方、実際の回路は、シャープがザイログからライセンスを受けた Z80 の回路から、大幅に削除、追加して作られたはずだ。

というか、シャープはおそらくインテルのライセンスは受けていないので、政治的な理由で「8080互換」は謳えない。

だから、シャープの立場で言えば「Z80 カスタム」と言うのが正しい。



つまり、技術面では 8080 カスタムと呼ぶべきで、政治面では Z80 カスタムと呼ぶべき。

どちらで呼ぶかは、個人の感性(信条の)問題だ。




ところで、最初に「WEB 上の各種ソースをあたるも、みな「Z80」と」と書いた。

wikipedia にも、そう書いてある。(ゲームボーイだけでなく、シリーズ機種すべて、Z80 扱い)


ふと思ったが、wikipedia は、「印刷資料」を基に記事を書かないと、独自研究扱いなのではないの?

Z80 って書いてある印刷資料、どこかにあったのかな?



でも、日本の wikipedia は間違いだらけだから、と思って、英語版記事を見た。

そうしたら、Z80 とは書いていなかった。


「8080 に酷似した、SHARP の 8bit カスタム LR35902」とした上で、「Z80 の追加命令のいくつか、特にビット操作命令が存在する」と説明している。


事実をそのまま書いた冷静な記事。



主に日本語版の wikipedia に疑念を抱いて、Z80 なのか 8080 なのか躍起になって調べたのだが、日本語版の wikipedia の内容が「根拠なく書かれていた」と言うだけの話でした。



翌々日追記

海外でも、ゲームボーイの CPU は「GBZ80」と呼ばれることが多いようです。

で、技術系の解説サイトを見るたびに、「GBZ80 と呼ばれてるけど、8080 のほうが近いから」と断っていることが多いです。


上に書いた wikipedia での CPU 解説も、一部分のみ翻訳したけど、「Z80 じゃないから」と念を押すような文面でした。


こちらのサイトでは、「アセンブラはZ80構文を使うことが多いけど、同じじゃないから」という表記も見られます。


…つまり、「アセンブラがザイログ表記で書かれることが多いから、Z80だ」と考える人が多いのですね。

言語と CPU アーキテクチャは無関係なのに。



そういえば、自分のページに情報くれた方も、「ニモニックがZ80」だったから、Z80だと思っていた、と書いていました。


ザイログニーモニックは Z80 の全命令を網羅したものですが、その中には 8080 の命令セットも含まれるので、ザイログニーモニックで 8080 のプログラムを書くことも可能です。


「CPU メーカーがニーモニックを決定する」のであれば、ザイログのライセンスしか受けていないシャープとしては、ザイログニーモニック互換にするのが最も順当な方法となります。


さらに、ゲームボーイ発売時は Z80 プログラマが多数いましたので、8080 相当の機能しかないとしても、そのアセンブラに「普及言語」としてザイログニーモニックを選ぶのは、自然な流れであったのだろう、と思います。



しかし、ザイログニーモニックだから Z80 だろう、という類推をする人が多いのは、心情としても理解できます。

これで、なぜ Z80 と勘違いされるのか、という疑問が解けた感じ。



もうひとつ、Z80 は知っているけど 8080 は知らない人も多いようです。

この人たちに、「むしろ 8080 に近い」という言葉はまったくの無意味。

Z80 のほうが有名だから、と言う理由で「Z80 カスタム」と信じ込んでいます。


こちらの書き方をしているページは、技術を知らないのにスペックを書きたがる人に多いみたい。

正確さを必要とする wikipedia などでは、この書き方はどうかと思いますが…



いずれにしても、自分としては「Z80 カスタム」と思われている傾向について、調査を通じて納得ができました。


ゲームボーイの CPU は Z80 と言い切っていたりリコーが Z80 をカスタムしたものと言っている人を見ても、寛容な気持ちでいられそうです。



2013.9.10追記


CPU 停止命令の説明がわかりにくかったことに気づき説明追記。(日記なのに後で書き変えてます)

補足説明なので元の記事と内容はかわりません。


最後に書いた、リコーがZ80をカスタムした…と書かれていたページは、修正されていました。

この日記を参考にしたことが明記してあり、お礼までされてしまった。

晒しネタに使って申し訳ありませんでした。



2014.11.8追記


コメント欄で誤りの指摘があり、修正しました。

僕の勘違いが2つ、意図が伝わっていないのが2つ。意図が伝わりにくい部分は加筆しています。



Twitter で「呼び方としては Z80 の機能削減と呼んでも良いのではないか」と僕に訊ねてきた方がいらっしゃいました。


僕がこのページを書いた意図は、書いた当時「Z80」だと言い切る方が多かったため、そうではないと伝えるためでした。

内容が正しく理解されていれば、それをどのように呼ぶかは個人の自由かと思います。



現状、Wikipedia で「Z80」となっていた部分も、「Z80カスタム」などに改められ、どう変わっているか明記されたようです。

CPU に関しては Wikipedia の英語版の表記が正確なので、日本語版でも英語翻訳するのが望ましいようにも思いますが、「カスタム」であることが伝われば嘘ではないでしょう。


このページを書いた当初の目的は果たせたかな、と思っています。




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

コンピュータ

関連ページ

MC68000とは何か

ゲームボーイの発売日【日記 14/04/21】

横井軍平の誕生日(1941)【日記 13/09/10】

スーパーファミコンの発売日(1990)【日記 13/11/21】

BCD (二進化十進)とは【日記 14/07/20】

別年同日の日記

15年 アプリケーションサーバとしてのQNAP

15年 宮永好道 命日(1993)

16年 iOSでtextのコピー・ペーストができないバグの回避

18年 サターンポリゴンのゆがみ

21年 100倍規模


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

【名無し】 追記に「「ローカルスコープが作れるようになる」と書いていたが、上記のように勘違いなのでできない。」とありますが、GBZ80はSPへ -128~+127 の直値を加算する命令があり、ローカルスコープを作ることが目的のそれと思われます。 (2017-05-05 18:51:46)

あきよし】 気付くの遅れました。指摘ありがとうございます。全くその通りで、勘違いしたようです。本文修正しました。 (2017-03-27 15:32:30)

【雷更新世】 SP相対の読み出しはできないようです。「LD HL,SP+disp8」(表記は多種あるが機械語F8)がHLにSP相対の「アドレスを」ロードする命令なのを誤ってSP相対読み出しのように書かれている記述を見かけましたが、それではないでしょうか。 (2017-02-11 21:21:45)

【nasi】 wikipediaは「印刷」資料を基に記事を書かないといけないということはないのではないかと思います。ウィキペディアに執筆してよいかどうかの基準は「真実であるかどうか」ではなく「検証可能かどうか」です。つまり、私たちがウィキペディアで提供するのは、信頼できるソース(情報源)を参照することにより「検証できる」内容だけだということです。 (2016-07-20 16:29:46)

【名無し】 ご対応ありがとうございました。ローカルスコープを作りやすくする改良についてですが、ゲームボーイのCPUでは肝心のローカルスコープへのアクセスを行う命令(Z80でのインデクスレジスタ相対を扱うような命令)が強化されなかったので実際さほど便利にはなってないところが残念なところではありますね。 (2014-11-08 22:50:49)

あきよし】 ご指摘いただいた内容を元に、内容修正しました。SPの扱い変更は少し詳細に踏み込み、ED系は「符号反転」に修正、フラグの扱いも少し踏み込んで書きました。(技術詳細を書きたいわけではなく、わかりやすい解説としたいため、踏み込み不足はご容赦を…) (2014-11-08 06:41:07)

あきよし】 ご指摘ありがとうございます。実はZ80にはそれほど詳しくなく、SPを読み出す命令が無い、は誤りと後に知りました。が、ここでの主眼は「SP相対アドレッシングなど、ローカルスコープを作りやすくする改良が入っている」ことでした。
ED系に関しては指摘の通りの勘違いです。
フラグは、GBCPUに残されたNフラグのことを書いたのですが、意図が伝わりにくかったようです。
 (2014-11-08 06:06:30)

【名無し】 「8080/Z80 とも、スタックは「特別なもの」扱いなので、演算命令を用意していない。」とのことですが、SPへの演算命令は8080のDAD SPやINX SP/DCX SPが存在します。HLにオフセットを代入したのちDAD SPを行えばGBのCPUに新設された「SPに直値を加えた結果をHLに代入する」命令と同等のことができるので、記事中で書かれていた「ローカルスコープ変数」は8080の頃から実現は可能です。 (2014-11-07 18:29:54)

【名無し】 「Z80由来のフラグが増えたが、実はこのフラグを使用する命令は、Z80 では増えていない。」とのことですが、ブロックサーチ命令等、P/Vフラグへの結果を見なければいけない命令は8080からいくつか追加されています。 (2014-11-07 18:24:00)

【名無し】 「ED prifix 命令には~Aレジスタビット反転命令~が含まれる。」とありますが、Aレジスタのビット反転命令は8080の頃から1バイト命令で存在します。Z80で新設された「Aレジスタの2の補数を求める命令」と勘違いされてるのでは? (2014-11-07 18:21:32)


戻る
トップページへ

-- share --

20300150

-- follow --




- Reverse Link -