原文: http://lsewww.epfl.ch/~felber/GBDK/
翻訳: bero@geocities.co.jp

GameBoy開発キット

バージョン2.0b12(DOS)と2.0b6(Unix)

最終更新:1998年4月16日

注意

私は、新しいGBDK配布をリリースする時間がほとんどない。 私は今ちょうど博士論文を書くことで非常に忙しい。 コンパイラについてのよい知識を持った誰かがGBDKの一層の開発を助けてくれたら、私はうれしい。

浮動小数点とlong longサポートにいくつかバグがあります。 修正の前にこれらの型を使用しないでください。

このページは完全には完成していない。 ここで 古い(時代遅れの)ドキュメントにまだアクセスできる。



ハイライト

GameBoy開発キット(GBDK)は、任天堂GameBoyシステムのための、Cとアセンブラの両方でプログラムを開発することができる一組のツールである。 GBDKは、最も一般的な必要条件のための一組のライブラリを含んでおり、実際のGameBoyや VGB のようなエミュレータで使用するためのイメージファイルを生成する。

GBDKはUNIXとDOSで利用できる。 GBDKのUNIXバージョンはSolaris 2.5.1上でテストされた。 DOSバージョンはDOSにプロテクトモードインタフェース(DPMI)と共に、386DXプロセッサ(以上)を要求する。

GBDKは、現在いくつかのプロジェクトで使用されている。 GBDKを使用した最初の商用プロジェクトは Pro Action Replay II である。

GBDKの特徴:

GBsed (Javaで書かれた相棒スプライトエディタ)は、GameBoyプログラムに含まれるイメージとスプライトを作成することができる。 代わりに、 Ian James によるBMPファイルをCコードに変換するWin 95/NT BMP2GB プログラムか、GBDKのためのスプライトを作成するWin 95/NT GameBoyタイルデザイナー プログラムを使用することができる。


ステータス

GBDKは商用でない開発のためのフリーウェアである。 使用する場合、あなたの活動を私に通知しておくために、私に電子メールを送るだけでよい。 GBDK本当に偉大だと感じれば、私にあなたの国の代表的なものを送ってください...

GBDKを商用プログラムを開発するために使用する場合、プログラムがGBDKを使用して作られたと(クレジット中で)言及し、私に完成品のコピーを送ることを求める。 寛大に感じれば、会社がGameBoyのために制作した他の製品のコピーも送ってください...


変更

最新のGBDKバージョンは、lcc 4.1のプレリリースバージョンを使用するので、DOSバイナリのみで利用できる。 lcc 4.1が公式にリリースされればすぐにUnixバージョンを利用できるだろう。 最新のUnixバージョンを得たければ、私と直接連絡をとること。

GBDK 2.0b12(DOSバイナリのみ)の変更 - 98年4月16日

GBDK 2.0b11(DOSバイナリのみ)の変更 -97年11月24日

GBDK 2.0b10(DOSバイナリのみ)の変更 -97年11月6日

GBDK 2.0b9(DOSバイナリのみ)の変更

GBDK 2.0b8(DOSバイナリのみ)の変更

GBDK 2.0b7(DOSバイナリのみ)の変更

GBDK 2.0b6の変更

GBDK 2.0b5の変更

GBDK 2.0b4の変更

GBDK 2.0b3の変更

GBDK 2.0b2の変更

GBDK 2.0b1の変更

GBDK 1.1の変更


ダウンロードとインストール

GBDKのインストールは次のステップを要求する:

UNIX上で

GBDKを構築するために、gcc、gnu makeと/bin/cshがなければならない。

DOS上で

少なくとも386DXプロセッサとDOSプロテクトモードインターフェイス(DPMI)がなければならない。 例えば、Windows95はDPMIを提供する。 さらに ここから 1つを入手することができる。


コンパイラ

コンパイラは、ANSI/ISO Cのためのフリーなターゲット非依存コンパイラである lcc に基づく。GBDKは、GameBoyカスタムZ80のためのコードを生成するlccのためのコードジェネレータを含んでいる。 完全な説明については、lcc配布に含まれる マニュアルページ を読む。

コンパイラは、基本的な型のための次のサイズを定義する:

サイズ 最小値 最大値
char 1 バイト -128 127
unsigned char 1 バイト 0 255
int 1 バイト -128 127
unsigned int 1 バイト 0 255
long 2 バイト -32768 32767
unsigned long 2 バイト 0 65535
ポインタ 2 バイト 0 65535

CPUが8ビットのプロセッサであるので、int値で動作することはlong値で動作するより非常に効率的である。 しかし、オーバフローに注意する必要がある。

GameBoyイメージを生成する時、リンカは、lib/gb.libテキストファイル中にリストされたオブジェクトファイルの各々の中で不確定シンボルを捜す。 これらのオブジェクトファイルのうちの1つがシンボルを含んでいる場合、メインプログラムとリンクされる。 これらのオブジェクトファイルのどれもシンボルを含んでいない場合、リンカはエラーを生成する。 したがって、明示的に標準ライブラリとメインプログラムをリンクする必要はない。

ここに、lcc使用法のいくつかの例がある:

    lcc -o image.gb source.c
    lcc -o image.gb source.s
    lcc -c -o object.o source.c
    lcc -c -o object.o source.s
    lcc -o image.gb object1.o object2.o
    lcc -o image.gb source.s source.c object.o

次のフラグは、オプションをプリプロセッサ、コンパイラ、アセンブラ、リンカへ渡すことができる:

    -Wp
    -Wf
    -Wa
    -Wl

これらのフラグの典型的な使用法は、リストとマップファイルを生成するためである:

リストとマップファイルを常に生成することは一般によい習慣である。


アセンブラ

アセンブラは ASxxxxクロスアセンブラ に基づく。

命令のいくつかは無く、いくつかは追加されているが、GameBoyプロセッサはZ80に非常に似ている。 さらに、裏レジスタ(BC', DE', HL', AF')とインデックスレジスタ(IX, IY)は無く、したがってDDとFDのオペコードテーブルはない。 最後に、I/Oポートは無くなっており、したがってすべてのIN/OUTオペコードはない。 変更された命令の説明のために、 GameBoy FAQ を読む。

GB特有のオペコードのいくつかの名前を変更した:

    LD (HLI),A      -> LD (HL+),A
    LD (HLD),A      -> LD (HL-),A
    LD A,(HLI)      -> LD A,(HL+)
    LD A,(HLD)      -> LD A,(HL-)
    ADD SP,offset   -> LDA SP,offset(SP)
    LDHL SP,offset  -> LDA HL,offset(SP)

LDAオペコードは68x00アセンブラのような「ロードアドレス」を意味する。 両方が直交なので(異なる2つのレジスタで同じことを行う)、これらの命令をこのように名づけた。

アセンブラは次のフラグを受け付ける:

ASxxxx Assembler V01.75  (GameBoy Z80-like CPU)
 
Usage: [-dqxgalopsf] outfile file1 [file2 file3 ...]
  d    decimal listing
  q    octal   listing
  x    hex     listing (default)
  g    undefined symbols made global
  a    all user symbols made global
  l    create list   output outfile[LST]
  o    create object output outfile[o]
  s    create symbol output outfile[SYM]
  p    disable listing pagination
  f    flag relocatable references by  `   in listing file
 ff    flag relocatable references by mode in listing file

完全な説明については、docディレクトリ中のasmlnk.docファイルまたは このhtmlドキュメント を読む。


リンカ

リンカは ASxxxxクロスアセンブラ に基づく。 それはGameBoyイメージの生成をサポートするために特有の拡張をされた。

リンカは次のフラグを受け付ける:

ASxxxx Linker V01.75
 
Startup:
  --   [Commands]              Non-interactive command line input
  -c                           Command line input
  -f   file[LNK]               File input
  -p   Prompt and echo of file[LNK] to stdout (default)
  -n   No echo of file[LNK] to stdout
Usage: [-Options] outfile file [file ...]
Librarys:
  -k    Library path specification, one per -k
  -l    Library file specification, one per -l
Relocation:
  -b   area base address = expression
  -g   global symbol = expression
  -yo  Number of rom banks (default: 2)
  -ya  Number of ram banks (default: 0)
  -yt  MBC type (default: no MBC)
  -yn  Name of program (default: name of output file)
Map format:
  -m   Map output generated as file[MAP]
  -x   Hexidecimal (default)
  -d   Decimal
  -q   Octal
Output:
  -i   Intel Hex as file[IHX]
  -s   Motorola S19 as file[S19]
  -z   Gameboy image as file[GB]
List:
  -u    Update listing file(s) with link data as file(s)[.RST]
End:
  -e   or null line terminates input

完全な説明については、docディレクトリ中のasmlnk.docファイルまたは このhtmlドキュメント を読む。


インクルードファイルとライブラリ

いくつかのインクルードファイルは、GBDKの一部である。 そのいくつかは有用なマクロを単に定義し(関連するコードはない)、一方他のものは個別のオブジェクトモジュールで実装された関数を定義する。 ライブラリは、最終のイメージファイルのサイズを縮小するために、いくつかの小さなオブジェクトファイルに分割される(必須のモジュールだけが、メインプログラムとリンクされる)。 インクルードファイルとライブラリは次のグループに分けられる:

ランタイムサポート

crt0.oオブジェクトモジュールは、GameBoy初期化ルーチン、Cサポートと他の本質的なものと共に、基礎的なCランタイムライブラリを含んでいる。 このライブラリは必須で、すべてのプログラムと自動的にリンクされる。

gb.hインクルードファイルは、GameBoyに関連する基礎的なマクロと関数を定義する。 さらに、それは、GameBoyハードウェアレジスタを定義するhardware.hファイルをインクルードしている。

標準Cライブラリ

ctype.h、stdarg.h、stdlib.h、string.hとtypes.hインクルードファイルは、標準Cライブラリのいくつかの関数を定義する。

コンソール入出力

基礎的なコンソールI/Oはconsole.hとstdio.hインクルードファイルに定義された一組の関数によって提供される。 コンソールI/OがGameBoyのほとんどのタイルとスプライトを使用しているため、グラフィックスプログラムと容易に混合できないことに注意する。

シンプルなグラフィックライブラリ

スクリーン上に点とイメージを描画するためのシンプルなグラフィック関数は、drawing.hインクルードファイルで定義される。 グラフィックライブラリがGameBoyのほとんどのタイルとスプライトを使用することに注意する。


例プログラム

GBDKはCとアセンブラの両方にいくつかの例プログラムを含んでいる。 それらはexamplesディレクトリとそのサブディレクトリに位置する。 それらは対応するディレクトリでmakeをタイプすることにより構築できる。

space.s

space.s例はスプライト、ウィンドウ、背景、固定小数点表現の値、その他の使用を実証するアセンブラプログラムである。 次のキーが使用されている:

    Arrow keys     : Change the speed (and direction) of the sprite
    Arrow keys + A : Change the speed (and direction) of the window
    Arrow keys + B : Change the speed (and direction) of the background
    START          : Open/close the door
    SELECT         : Basic fading effect

galaxy.c

galaxy.c例はspace.sアセンブラプログラムのC変換である。

sound.c

sound.c例は、GameBoyのサウンドジェネレータの実験を意図する(実際のGameBoy上で使用すること)。 GameBoyの4つの異なるサウンドモードを利用できる。 さらに、それは、Cの中のビットフィールドの使用を実証する(それは迅速なハックであるので、コードにあまり期待しない)。 次のキーが使用されている:

    UP/DOWN      : Move the cursor
    RIGHT/LEFT   : Increment/decrement the value
    RIGHT/LEFT+A : Increment/decrement the value by 10
    RIGHT/LEFT+B : Set the value to maximum/minimum
    START        : Play the current mode's sound (or all modes if in control screen)
    START+A      : Play a little music with the current mode's sound
    SELECT       : Change the sound mode (1, 2, 3, 4 and control)
    SELECT+A     : Dump the sound registers to the screen

rpn.c

rpn.c例は基礎的なRPN電卓である。 12 134*のような式を入力すると、1789+になる。

gb-dtmf/gb-dtmf.c

gb-dtmf/gb-dtmf.cプログラムは、 大橋修 によって書かれており、Dual Tone Multi-Frequency(DTMF)ジェネレータである。

banks.c

banks.c例は、複数バンクプログラムの方法を例証する。

ram_fn.c

ram_fn.c例は、RAMやHIRAMに関数をコピーする方法と、Cからそれらを呼ぶ方法を例証する。

irq.c

irq.c例は、IRQハンドラを取り付ける方法を例証する。

comm.c

comm.c例は、コミュニケーションルーチンを使用する方法を例証する。

dscan/dscan.c

Deep Scan(dscan/dscan.c)は大橋修の友人によって書かれたゲームである。 目的は、ボートから潜水艦を破壊し、潜水艦の出す弾を避けることである。 ゲームは自明に違いない。 次のキーが使用されている:

    RIGHT/LEFT   : Move your boat
    A/B          : Send a bomb from one side of your boat
    START        : Start game or pause game
    When game is paused:
    SELECT       : Invert A and B buttons
    RIGHT/LEFT   : Change speed
    UP/DOWN      : Change level

GBDKプログラミングガイドライン


GBDK 1.1からGBDK 2.0へのコードの移植


Cとアセンブラの混合

Cとアセンブラを混合するために、1つの言語につき1つのファイルを使用し(アセンブラをCコードにを埋め込むことができない)、両方のファイルをともにリンクする必要がある。 ここに、知っておくべきものがある:

ここに、Cとアセンブラを混合する方法の例がある:

main.c

   main()
    {
      int i;
      int add(int, int);
      i = add(1, 3);
    }

add.s

   .globl _add
    _add:         ; int add(int a, int b)
                  ; There is no register to save:
                  ;  BC is not used
                  ;  DE is the return register
                  ;  HL needs never to be saved
    LDA  HL,2(SP)
    LD   E,(HL)   ; Get a in DE
    INC  HL
    LD   D,(HL)
    INC  HL
    LD   A,(HL)   ; Get b in HL
    INC  HL
    LD   H,(HL)
    LD   L,A
    ADD  HL,DE    ; Add DE to HL
    LD   D,H
    LD   E,L
                  ; There is no register to restore
    RET           ; Return result in DE

複数バンクイメージ

GBDKはMBC1とMBC2のデータコントローラのために複数バンクイメージ(複数ROMとRAMバンクの両方で)を生成できる。 複数RAMバンクはMBC 1だけでサポートされる。

複数ROMバンクでは、アドレス0x0000から0x3FFFは固定ROMバンクのために予約され、一方アドレス04000から0x7FFは切り替えできる、つまり、任意のバンクのために使用できる。 切り替え可能なROMバンクは_CODE_1,_CODE_2,...と呼ばれ、 固定ROMバンクは_CODEと呼ばれる(_CODE_0がないことに注目する)。 ROMバンクの最大の数は32である。

アドレス0xC000から0xDFFFは、常に内部RAMのために予約される。 アドレス0xA000から0xBFFFは、(切り替え可能)外部RAMのために予約される。 外部RAMバンクは_BSS_0, _BSS_1, _BSS_2...と呼ばれ、 内部RAMは_BSSと呼ばれる。 外部RAMバンクの最大の数は4である。

RAMバンクの割り当て方法を決定する時、ローカル変数が常にスタックに割り付けられ、初期化されたグローバル変数がROMに位置するることを思い出す。 初期化されていないグローバル変数か静的変数だけがRAMへ割り付けられる。

複数バンクイメージを生成するために、次のようにする必要がある:

バンク切り替えはプログラムにおいて自動的ではない。 switch_rom_bank()とswitch_ram_bank()関数を明示的に呼ばなければならない。 完全な例に関しては、banks.cを参照する。


RAMとHIRAMへの関数のコピー

(memcpy()とhiramcpy()関数を使用して)RAMとHIRAMに関数をコピーし、Cからそれらを実行することができる。 コンパイラは、start_Xとend_X(Xは関数名である)という名前の各関数の開始と終了の2つのシンボルを自動的に生成する。 これは、関数をRAMにコピーする時に関数の長さを計算することができる。 RAMやHIRAMに関数をコピーするための十分な空きスペースがあることを確認する。

RAM、HIRAMまたはROMに位置した関数を呼ぶために、基本的に2つの方法がある:

第2のアプローチはわずかにより効率的である。 両方のアプローチはram_fn.c例において例証される。


IRQハンドラ

GameBoyハードウェアは5つのタイプの割り込みを生成できる:

  VBL : V-blank
  LCD : LCDC status
  TIM : Timer overflow
  SIO : Serial I/O transfer end
  JOY : Transition from high to low of joypad

これらの割り込みのどれでも独自のIRQハンドラ(Cまたはアセンブラの)を取り付けることができる:

完全な例に関しては、irq.cを参照する。


初期化ルーチン

main()関数が呼ばれる前でちょうど割り込みが有効になる前に実行されるルーチンを取り付けることができる。 例えば、割り込みフラグを変更し、main()が実行される前にVBL IRQが扱われるのを避けるために初期化ルーチンを使用できる。 初期化ルーチンを取り付けるために、次のようにする必要がある:


重要なアドレスの変更

-WlgXXX=YYYフラグ(XXXはデータ名、YYYは新しいアドレス)を使用して、リンク時にある重要なデータのアドレスを変更することができる。 変更できるアドレスは:

  .STACK   : Initial stack address
  .OAM     : Location of sprite ram (requires 0xA0 bytes)
  .init    : Initialization routine
  .irq_VBL : VBL IRQ routine
  .irq_LCD : LCD IRQ routine
  .irq_TIM : TIM IRQ routine
  .irq_SIO : SIO IRQ routine
  .irq_JOY : JOY IRQ routine

トラブル対策

アセンブラエラー

メッセージのタイプ:

    u 0226
    a 0329
    u 0333

は、アセンブラのエラーメッセージである。 これらのエラーがどこで起きたか確かめるために、lccの-Wa-lフラグを使用してアセンブリリストを生成し、このファイルを見るべきである。 そのようなエラーがコンパイラの生成したファイルで起きる場合、リストと一緒に私にCソースを送る。

リンクエラー

メッセージのタイプ:

    ?ASlink-W-Undefined Global     .count referenced by module Demo

は、リンカのエラーメッセージである。 イメージファイルは生成されるが、悪くなっているはずである。 エラーに関する詳細な情報はマップファイル(lccの-Wlmフラグを使用して生成される)で見つけることができる。

DOSシェルエラー

DOSシェルは、128文字へコマンドラインを切り詰める。 コンパイラへ渡すフラグの数により、より長いコマンドラインを使用する必要があれば、bash(Unix Bourne-Again SHellのDOS移植)を入手するように強く勧める。 それはDOSシェルより非常に強力であり、コマンドラインを切り詰めない。 よりよい代案は、make(Unix makeユーティリィティのDOS移植)を入手し、DOSバッチファイルの代わりにmakefileを使用することである。 もちろん、両方を入手することができる。 それらは DJGPP (GNU CのDOS移植)の一部として利用できる。


既知の問題

GBDK 2.0の既知の問題

バージョン1.1中の既知の問題


リンク

GBDK移植

GameBoyについての技術的な情報

戻る


最終更新 98年4月16日 Pascal Felber 1