========================= CHIP8 CHIP-8/SCHIP エミュレータ Version 2.2.0 David WINTER (HPMANIAC) ========================= 目次 1 - CHIP8とは 1.1 - 歴史 1.1.1 - 最初のCHIP-8 1.1.2 - その後のCHIP-8 1.1.3 - CHIP-8エミュレータ 1.2 - プログラムとメモリ 1.3 - レジスタセット 1.4 - グラフィック 1.5 - 命令セット 1.6 - キーボード 1.7 - CHIP-8/SCHIP用のゲームやプログラム 2 - CHIP-8エミュレータ 2.1 - CHIP8の設定 2.2 - CHIP8の使い方 2.3 - FIX_CHIPユーティリティ 2.4 - UNCHIPディスアセンブラ 2.5 - BINHEXとHEXBINユーティリティ 2.6 - CHIPPERアセンブラ 3 - お問合せ先 4 - POSTWARE ----------------------------------------------------------------------------- 1 - CHIP-8とは ============== 1.1 - 歴史 ========== 1.1.1 - 最初のCHIP-8 ==================== CHIP-8とは、インタプリタ型プログラム言語の一種です。 「TELMAC 1800」「COSMAC VIP」「ETI 660」「DREAM 6800」といった、70年代後半〜80年代初期の小型コンピュータ上で利用されました。 CHIP-8を使うと、ビデオゲームを手軽に開発できます。 「TELMAC 1800」と「COSMAC VIP」は、RCA社製プロセッサ「CDP-1802(通称COSMAC)」を搭載したコンピュータです。 1977年にこれらの製品が発売されたとき、CHIP-8を使って作られた12本以上のゲームプログラムが付いてきました。 COSMACとTELMACのマニュアルには、これらのゲームプログラムに加えて、BIOS ROMやCHIP-8インタプリタの完全なソースコードが掲載されています。 CHIP-8インタプリタ言語は、40種類弱の命令しか持っていません。(算術演算、フロー制御、グラフィック、サウンド等) CHIP-8を実行する小型コンピュータたちは、わずかなメモリしか搭載していなかったからです。 例えばCOSMAC VIPの標準メモリ容量は2キロバイト、TELMAC 1800の場合は4キロバイトでした。 そんなわけで、CHIP-8インタプリタ本体のプログラムは、たったの512バイトで作成されました。 CHIP-8は、とても単純な初期のプログラム言語の一種でもあります。 CHIP-8を使って、「Pong」「Brix」「Invaders」「Tank」といった、古典的なビデオゲーム作品が移植されました。 腕のいいプログラマは、たった256バイトのプログラムでこれらのゲームを移植することができました。 DREAM 6800上のCHIP-8に関して、こんな話があります。 “「オーストラリアエレクトロニクスマガジン」誌のコンピュータ自作企画で、DREAM 6800とETI 660が発表されました。 どちらも安い材料費で作れます。(約100ドル) 16進キーボードを備えていて、64×32ピクセルのグラフィックをTV出力できます。 搭載メモリは1キロバイト。 仮想高級言語CHIP-8が実行できます。(これって、RCA社がCOSMACのために作ったものだと思うけど...) ... うちの兄さんがDREAM 6800を組み立てました。 なんて素晴らしいコンピュータだ! DREAM 6800の組み立て記事には、たくさんのゲームリストも掲載されていました。 多くのゲームは200バイト前後、それ以外のゲームも充分に小さくて、プログラムリスト打ち込みが苦になりません。 しかもこれらのゲーム、良く動いてとても面白いです。 CHIP-8インタプリタ言語は、古典的なTVゲームを作成するための言語として、非常に優れた設計のようです。” Paul HAYTER (Amiga用CHIP-8インタプリタの作者) 1.1.2 - その後のCHIP-8 ====================== CHIP-8は、70年代後半〜80年代初期にだけ使われていたわけではありません。 90年代初期には、「HP48」計算機上でも利用されました。 当時の「HP48」にはまだ、手軽にゲームを開発するための開発環境がなかったからです。 オリジナルのCHIP-8用に開発されたゲームの大半は、そのままCHIP48(HP48用のCHIP-8インタプリタ)上で実行できました。 それに加えて、いくつかの新しいゲームがCHIP48用として開発されました。 詳しくは、1.7章を参照してください。 その後、CHIP-8の高機能版が登場しました。 「SUPER-CHIP」です。(SCHIPと簡略表記されることもあります) SUPER-CHIPインタプリタは、CHIP-8の完全上位互換に加えて、いくつかの機能強化がなされました。 機能強化点の一つとして、画面解像度が128×64ピクセルになったことが挙げられます。 私は、HP48G上のCHIP-8/SCHIP用にライブラリを作成し、これを利用したゲームが40本以上作られました。 FIX_CHIPユーティリティを使うと、HP48用のCHIP-8ゲームを、PCで扱える形式に変換できます。 詳しくは、2.2章を参照してください。 1.1.3 - CHIP-8エミュレータ ========================== エミュレータ人気の理由の一つとして、昔遊んだ懐かしいゲームをもういちど遊べることが挙げられます。 驚くべきことに、それらのゲームを手作業で移植する必要はなく、現代のコンピュータ上でそのまま実行できるのです。 昔のゲームをまた遊びたい、私がCHIP-8エミュレータを開発したいちばん大きな理由です。 CHIP-8用に開発されたPongやその派生ゲームの数々は、他のエミュレータやコンピュータ用のゲームには見られないタイプのものです。 CHIP-8エミュレータもまた、旧型ホームコンピュータエミュレータの一つであります。 1.2 - プログラムとメモリ ======================= CHIP-8用のアプリケーションプログラムは、アドレス200h番地から実行開始します。 (ETI 660用のCHIP-8プログラムだけは、例外的に600h番地から実行開始します。) CHIP-8インタプリタプログラム自身のために、アドレス000h〜1FFhの領域が利用されます。(TELMAC 1800とCOSMAC VIPの場合) アプリケーションプログラムは、全てのメモリにアクセスできます。 CHIP-8の命令は16ビット長固定なので、メモリアクセスも16ビット単位の偶数アドレスに対して行われることが多いです。 プログラムの中に8ビットデータがあったりした場合は、それ以降の命令並びは奇数アドレスに配置されることになります。 偶数アドレスにしかアクセスできないというわけではありません。 SCHIP用のアプリケーションプログラムもまた、CHIP-8用のアプリケーションプログラムと同様に実行されます。 唯一の違いは、SCHIPで追加された新しい命令セットが利用可能、ということです。 新命令のうちいくつかは、SCHIPインタプリタのCHIP-8互換モードでも利用可能です。 それ以外の新命令は、SCHIPインタプリタのSCHIP拡張モードだけで利用可能です。 1.3 - レジスタセット ==================== データレジスタ: 16個の8ビットレジスタがあります。 それぞれ、V0,V1,V2,V3,V4,V5,V6,V7,V8,V9,VA,VB,VC,VD,VE,VFと名付けられています。 VFレジスタは、算術演算命令実行時のキャリーフラグとしても利用されます。 VFレジスタはまた、スプライト描画命令実行時の衝突判定フラグとしても利用されます。 SCHIP拡張モード命令セットに関する説明の、衝突判定に関する部分を参照してください。 (訳注:と書いてありますが、既存のエミュレータのソースを見ると、CHIP-8モードの描画命令でも衝突判定してるみたいです。) アドレスレジスタ: 唯一のアドレスレジスタとして、Iレジスタがあります。 Iレジスタは16ビットレジスタで、4キロバイトのメモリ全体をアドレッシング可能です。 CHIP-8インタプリタは、Iレジスタの下位12ビットだけを参照します。(2^12=4096) 上位4ビットは、LOAD FONT命令を使って8110h番地に置かれたフォントを使うために利用できます。 (訳注:よくわからないです。8000h〜にROMが配置されているのでしょうか?) タイマ: 2つの8ビットタイマがあります。 一つはディレイタイマ、もう一つはサウンドタイマと呼ばれます。 0以外の値を設定すると、毎秒60回の速度で自動的にカウントダウンされ、0になったら停止します。 サウンドタイマが0以外の値になっている間、ビープ音を発生します。 (訳注:つまり、サウンドタイマに60を設定すると、1秒間ビープ音が鳴るわけです。) ディレイタイマは汎用で、速度調整用ループ等に利用されます。 スタック: 16レベルのスタックがあります。 よって、サブルーチン呼び出しは16階層まで入れ子にできます。 (訳注:スタックはメインメモリ上にありません。 プロセッサ内に12ビット×16レベルの呼び出し履歴メモリを内蔵しているようなイメージです。) 本物のCHIP-8のドキュメントには、スタックに関する説明は記載されていませんでした。 1.4 - グラフィック ================== 最初のCHIP-8は、64×32ピクセルのグラフィック機能を持っていました。 いくつかの改造マシンでは、64×48や64×64ピクセルのグラフィック機能が利用可能でした。 純正TELMACでも、CHIP-8バージョン2(CHIP-82と呼ばれます)を使うと、64×64ピクセルのグラフィック機能が利用可能になりました。 しかしながら、CHIP-82の64×64グラフィックを利用したプログラムはぜんぜん作られなかったみたいです。 CHIP-8のグラフィック機能は64×32ピクセル、と考えて良さそうです。 CHIP-8のグラフィック機能は、8×1ピクセル〜8×15ピクセルのスプライト描画命令として実現されています。 (スプライトパターンは、1バイト〜15バイトで定義されます。) 画面座標の原点は左上隅で、左から右へX=0〜63、上から下へY=0〜31となります。 X座標に63を超える値を指定すると、64で割った余りが実効X座標として使用されます。 (訳注:例えばX=94(=64+30)を指定した場合、それはX=30を指定したのと同じことです。) Y座標も同様で、31を超える値を指定した場合は、32で割った余りが使用されます。 スプライト描画は、画面上のピクセルを反転することで行われます。 スプライト描画によっていくつかの画面上のピクセルが消されると、VFレジスタに01hがセットされます。 さもなくば、VFレジスタには00hがセットされます。 CHIP8は、4×5ピクセルの16進数フォントパターンを内蔵しています。 すなわち、0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,Fのフォントパターンです。 SCHIP拡張モードでは、128×64ピクセルの高解像グラフィックが利用可能です。 SCHIP拡張モードに切り替えると画面座標の有効範囲も変化し、Xが00h〜7Fh(0〜127)、Yが00h〜3Fh(0〜63)となります。 X座標に127を超える値を指定した場合は、128で割った余りが使用されます。 Y座標に63を超える値を指定した場合は、64で割った余りが使用されます。 SCHIP拡張モードはCHIP-8モードに較べて縦横二倍のピクセル数ですので、ひとつひとつのピクセルはCHIP-8モードに較べて縦横半分の大きさとなります。 SCHIP拡張モードでは、8×10ピクセルの10進数フォントと、16×16ピクセルのスプライト描画が利用可能です。 描画機能そのものは、CHIP-8モードと同様です。 4×5フォントと8×10フォントはどちらも、64×32および128×64の画面解像度両方で利用可能です。 画面解像度に応じて、実際に描画されたフォントの見た目の大きさも変わります。 (なぜなら前述のように、画面解像度が変わるとひとつひとつのピクセルの大きさも変わるからです) 1.5 - 命令セット ================ NNNはアドレスを示します。 KKは8ビット定数を示します。 XとYは4ビット定数を示します。 (訳注:VXレジスタとは、X番目のデータレジスタを意味します。例えばX=3の場合、VXレジスタとはV3のことです。) (訳注:VXレジスタに関しても同様です。) 0NNN NNN番地に配置された、CDP-1802機械語サブルーチンを呼び出します。(エミュレータでは未実装です) (訳注:以下で説明する00xxの命令は、実機では機械語サブルーチン呼び出しとして実装されていたのでしょう。 そう言えば、00xxの命令は高水準な命令が多いような気がします。 CHIP-8サブルーチン呼び出し(2NNN)はインタプリタ命令として実装されているのに、 CHIP-8サブルーチンリターン(00EE)が機械語サブルーチン呼び出しとして実装されているのが不思議ですが...) 00CN Nライン下スクロールします。(***) 00FB 4ピクセル右スクロールします。(***) (訳注:CHIP-8互換モードで利用した場合は、2ピクセル右スクロールとなります。) 00FC 4ピクセル左スクロールします。(***) (訳注:CHIP-8互換モードで利用した場合は、2ピクセル左スクロールとなります。) 00FD エミュレーションを終了します。(***) 00FE CHIP-8互換グラフィックモードに切り替えます。 00FF SCHIP拡張グラフィックモードに切り替えます。 00E0 全画面をクリアします。 00EE CHIP-8サブルーチンからリターンします。 1NNN アドレスNNNへ分岐します。 2NNN アドレスNNNに配置されたCHIP-8サブルーチンを呼び出します。 サブルーチン呼び出しは、16階層まで入れ子にできます。 3XKK VXレジスタの値が即値KKに等しければ、直後の命令の実行をスキップします。 4XKK VXレジスタの値が即値KKに等しくなければ、直後の命令の実行をスキップします。 5XY0 VXレジスタとVYレジスタの値が等しければ、直後の命令の実行をスキップします。 6XKK VXレジスタに即値KKを代入します。 7XKK VXレジスタに即値KKを加算します。 (訳注:キャリー検出なしです。VFレジスタは変化しません。) 8XY0 VXレジスタにVYレジスタの値を代入します。 8XY1 VXレジスタとVYレジスタの論理和を求め、VXレジスタに格納します。 8XY2 VXレジスタとVYレジスタの論理積を求め、VXレジスタに格納します。 8XY3 VXレジスタとVYレジスタの排他論理和を求め、VXレジスタに格納します。(*) ・ ・ ・