GameBoy Developer's Kit

Version 2.1.0 (DOS and Unix)

Last updated: 21-Apr-1999

Pascal Felber and Michael Hope


News

The new versions of GBDK use a new directory structure. The GBDK can target pure Z80 systems (and not only the Z80 variant found in the GameBoy). The new directory structure is: /SDK/XX-XX/Y.Y.Y (Y-Y-Y on DOS), where XX-XX is the target and Y.Y.Y is the version number. An additional benefit is that it is possible to install new GBDK versions without removing the older ones.

A preliminary version of the libraries documentation is available online. For technical informations about the GameBoy hardware, see there.

New: Have a look at the GBDoK documentation page maintained by Jason.


A japanese translation of this page is available here.


Highlights

The GameBoy Developer's Kit (GBDK), is a set of tools that enable to develop programs for the Nintendo GameBoy system, either in C or in assembly. GBDK includes a set of libraries for the most common requirements and generates image files for use with a real GameBoy or with an emulator like VGB or no$gmb.

GBDK is available for UNIX and DOS. The UNIX version of GBDK has been tested on Solaris 2.6. The DOS version requires a 386 DX processor (or higher), with a DOS Protected Mode Interface (DPMI).

GBDK is currently being used in several projects. The first commercial project that used GBDK is Pro Action Replay II. GBDK also got used for a japanese RPG game (Monster Race from KOEI Co., Ltd.).

GBDK features:

GBsed, a companion sprite editor written in Java, enables to create images and sprites to be included in GameBoy programs. Alternatively, you can use the Win 95/NT BMP2GB program by Ian James that convert BMP files to C code, or the Win 95/NT GameBoy Tile Designer and Map Builder programs that lets you create images and maps for GBDK.


Status

GBDK is freeware for non-commercial developments. If you use it, just send me an e-mail to keep me informed of your work. If you really find it great, you can send me something typical from your country...

If GBDK is used for developing a commercial program, I ask you to mention that the program has been made using GBDK (in the credits), and to send me a copy of the finished product. If you feel generous, you can also send me a copy of any other products that your company has produced for the GameBoy...


Changes

Changes in GBDK 2.1.0 (DOS, Linux, and Unix) - 21 Apr 99

Changes in GBDK 2.0.18 (DOS, Linux, and Unix) - 26 Mar 99

Changes in GBDK 2.0.17 (DOS and Unix) - 26 Nov 98

Changes in GBDK 2.0.16 (DOS and Unix) - 30 Oct 98

Changes in GBDK 2.0.15 (DOS and Unix) - 5 Oct 98

Changes in GBDK 2.0.14 (DOS binary only) - 28 Sep 98

Changes in GBDK 2.0b13 (DOS and Linux binaries) - 17 Aug 98

Changes in GBDK 2.0b12 (DOS binary only) - 16 Apr 98

Changes in GBDK 2.0b11 (DOS binary only) - 24 Nov 97

Changes in GBDK 2.0b10 (DOS binary only) - 6 Nov 97

Changes in GBDK 2.0b9 (DOS binary only)

Changes in GBDK 2.0b8 (DOS binary only)

Changes in GBDK 2.0b7 (DOS binary only)

Changes in GBDK 2.0b6 (DOS and Unix)

Changes in GBDK 2.0b5

Changes in GBDK 2.0b4

Changes in GBDK 2.0b3

Changes in GBDK 2.0b2

Changes in GBDK 2.0b1

Changes in GBDK 1.1


Downloading and Installing

Installing GBDK requires the following steps:

On UNIX

You must have gcc, gnu make and /bin/csh for building GBDK.

On DOS

You must have at least a 386 DX processor, and a DOS Protected Mode Interface (DPMI). For instance, Windows 95 provides a DPMI. You can also get one from here.

The GBDK distribution includes a batch file (gbdk.bat, by Mark Rawer) that automates many of the steps below, and that enables to install the GBDK distribution in any directory. You'll have to edit and modify the first lines of this batch file before executing it.


The Compiler

The compiler is based on lcc, a free of charge retargetable compiler for ANSI/ISO C. GBDK includes a code generator for lcc that generates code for the GameBoy custom Z80. For an ehaustive description, read the man page included with the lcc distribution.

The compiler defines the following sizes for basic types:

type size min max
char 1 byte -128 127
unsigned char 1 byte 0 255
int 1 byte -128 127
unsigned int 1 byte 0 255
long 2 byte -32768 32767
unsigned long 2 byte 0 65535
long long 4 byte -2147483648 2147483647
unsigned long long 4 byte 0 4294967296
float 4 byte n/a n/a
double 4 byte n/a n/a
pointer 2 byte n/a n/a

Since the CPU is an 8-bit processor, working with int values is much more efficient than working with long values. But you have to be careful with overflows.

When generating a GameBoy image, the linker will look for undefined symbols in each of the object files listed in the lib/gb.lib text file. If one of these object files contains the symbol, it will be linked with the main program. If none of these object files contain the symbol, the linker will generate an error. Therefore, there is no need to explicitely link the main program with the standard libraries.

Here are some examples of lcc usage:

    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

The following flags allow to pass options to the preprocessor, the compiler, the assembler, and the linker:

    -Wp
    -Wf
    -Wa
    -Wl

A typical useage of these flags is for generating listing and map files:

It is generally a good habit to generate listing and map files.


The Assembler

The assembler is based on ASxxxx Cross Assemblers.

The GameBoy processor is very similar to the Z80, although some of the instructions are missing and some ther have been added. Also, she second set of registers (BC', DE', HL', AF') and the index registers (IX, IY) are missing and, consequently, there are no DD and FD opcode tables. Finally, I/O ports are gone and so are all IN/OUT opcodes. For a descriptions of the changed instructions, read the GameBoy FAQ.

I have modified the name of some of the GB-specific opcodes:

    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)

The LDA opcode means "load address", like in 68x00 assembly. I've called these instructions like this because both are orthogonal (they do the same thing on two different registers).

The assembler accepts the following flags:

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

For an ehaustive description, read the asmlnk.doc file in the doc directory, or this html-ized document.


The Linker

The linker is based on ASxxxx Cross Assemblers. It has been extended in particular to support generation of GameBoy images.

The linker accepts the following flags:

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 ...]
Libraries:
  -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)
  -yp# Patch one byte in the output GB file (# is: addr=byte)
Map format:
  -m   Map output generated as file[MAP]
  -j   no$gmb symbol file generated as file[SYM]
  -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

For an ehaustive description, read the asmlnk.doc file in the doc directory, or this html-ized document.


The Include Files and Libraries

Several include files are part of GBDK. Some of them only define useful macros (with no code associated), while others define functions implemented in separate object modules. The libraries are split in several small object files in order to reduce the size of the final image file (only the required modules are linked with the main program). The include files and libraries are divided in the following groups:

Runtime support

The crt0.o object module contains the basic C runtime library, with GameBoy initialization routines, C support and other essential things. This library is required and automatically linked with every program.

The gb.h include file defines basic GameBoy-related macros and functions. It also includes the hardware.h file that defines GameBoy hardware registers.

Standard C libraries

The ctype.h, stdarg.h, stdlib.h, string.h, and types.h include files define some functions found in the standard C libraries.

Console Input/Output

Basic console I/O is provided through a set of functions defined in the console.h and stdio.h include files. Note that console I/O uses most of the tiles and sprites of the GameBoy, and thus is not easily mixable with graphics programs.

Simple Graphic Library

Simple graphic functions for drawing points and images on the screen are defined in the drawing.h include file. Note that the graphic library uses most of the tiles and sprites of the GameBoy.

Misc Libraries

The rand.h include file defines functions for using the GBDK random generator.


The Example Programs

GBDK includes several example programs both in C and in assembly. They are located in the examples directory, and in its subdirectories. They can be build by typing make in the correnponding directory.

space.s

[galaxy/space]

The space.s example is an assembly program that demonstrates the use of sprites, window, background, fixed-point values and more. The following keys are used:

    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

The galaxy.c example is a C translation of the space.s assembly program.

paint.c

[paint]

The paint.c example is a painting program. It supports different painting tools, drawing modes, and colors. At the moment, it only paints individual pixels. This program illustrates the use of the full-screen drawing library. It also illustrates the use of generic structures and big sprites. It is definitely worth having a look at its source. The following keys are used:

    Arrow keys : Move the cursor
    SELECT     : Display/hide the tools palette
    A          : Select tool

sound.c

[sound]

The sound.c example is meant for experimenting with the soung generator of the GameBoy (to use on a real GameBoy). The four different sound modes of the GameBoy are available. It also demonstrates the use of bit fields in C (it's a quick hack, so don't expect too much from the code). The following keys are used:

    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]

The rpn.c example is a basic RPN calculator. Try entering expressions like 12 134* and then 1789+.

banks.c

[banks]

The banks.c example illustrates how to make multiple-banks programs.

ram_fn.c

[ram_fn]

The ram_fn.c example illustrates how to copy functions to RAM or HIRAM, and how to call them from C.

irq.c

[irq]

The irq.c example illustrates how to install interrupt handlers.

comm.c

[comm]

The comm.c example illustrates how to use communication routines.

gb-dtmf/gb-dtmf.c

[gb-dtmf]

The gb-dtmf/gb-dtmf.c program, written by Osamu Ohashi, is a Dual Tone Multi-Frequency (DTMF) generator.

colorbar/colorbar.c

[colorbar]

The colorbar/colorbar.c program, written by Mr. N.U. of TeamKNOx, illustrates the use of colors on a Color GameBoy.

dscan/dscan.c

[dscan]

Deep Scan (dscan/dscan.c) is a game written by Mr. N.U. of TeamKNOx that supports the Color GameBoy. Your aim is to destroy the submarines from your boat, and to avoid the projectiles that they send to you. The game should be self-explanatory. The following keys are used:

    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

rand.c

[rand]

The rand.c program, written by Luc Van den Borre, illustrates the use of the GBDK random generator.


GBDK Programming Guidelines


Porting Code from GBDK 1.1 to GBDK 2.0


Mixing C and Assembly

For mixing C and assembly, you must use one file per language (you cannot embed C code with assembly) and link both files together. Here are the things to know:

Here is an example of how to mix assembly with C:

main.c

    main()
    {
      WORD i;
      WORD add(WORD, WORD);

      i = add(1, 3);
    }

add.s

    .globl _add
    _add:         ; WORD add(WORD a, WORD 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

Multiple Bank Images

GBDK can generate multiple bank images (with both multible ROM and RAM banks) for MBC1 and MBC2 memory bank controllers. Multiple RAM banks are only supported by MBC 1.

With multiple ROM banks, addresses 0x0000 to 0x3FFF are reserved for the fixed ROM bank, while addresses 0x4000 to 0x7FFF are switchable, i.e. can be used for any bank. Switchable ROM banks are called _CODE_1, _CODE_2,... and the fixed ROM bank is called _CODE (note that there is no _CODE_0). The maximum number of ROM banks is 32.

Addresses 0xC000 to 0xDFFF are always reserved for the internal RAM. Addresses 0xA000 to 0xBFFF are reserved for (switchable) external RAM. External RAM banks are called _BSS_0, _BSS_1, _BSS_2,... and internal RAM is called _BSS. The maximum number of external RAM banks is 4.

When deciding how to populate your RAM banks, remember that local variables are always allocated on the stack, and initialized global variables are located in ROM. Only uninitialized global or static variables are allocated into RAM.

For generating multiple bank images, you have to:

Bank switching is not automatic in programs. You have to explicitely call the switch_rom_bank() and switch_ram_bank() functions. See banks.c for a complete example.


Copying Functions to RAM and HIRAM

It is possible to copy functions to RAM and HIRAM (using the memcpy() and hiramcpy() functions), and execute them from C. The compiler automatically generates two symbol for the start and the end of each function, named start_X and end_X (where X is the name of the function). This enables to calculate the length of a function when copying it to RAM. Ensure you have enough free space in RAM or HIRAM for copying a function.

There are basically two ways for calling a function located in RAM, HIRAM, or ROM:

The second approach is slightly more efficient. Both approaches are illustrated in the ram_fn.c example.


Interrupt Handlers

The GameBoy hardware can generate 5 types of interrupts:

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

It is possible to install your own interrupt handlers (in C or in assembly) for any of these interrupts. Up to 7 interrupt handlers can be installed for each interrupt. Interrupt handlers are called in sequence. To install a new interrupt handler, do the following:

See irq.c for a complete example.


Initialization Routine

You can install a routine that will be executed before the main() function is called, and just before the interrupts are enabled. For instance, you can use an initialization routine to modify the interrupt flags and avoid that a VBL IRQ is handled before main() is executed. For installing an initialization routine, you have to:


Changing Important Addresses

It is possible to change the addresses of some important data at link time using the -Wl-gXXX=YYY flag (where XXX is the name of the data, and YYY is the new address). The addresses that can be changed are:

  .OAM         : Location of sprite ram (requires 0xA0 bytes)
  .STACK       : Initial stack address
  .refresh_OAM : Address to which the routine for refreshing OAM will be copied (must be in HIRAM)
  .init        : Initialization routine

Troubleshooting

Assembly Errors

Messages of the type:

    u 0226
    a 0329
    u 0333

are error messages from the assembler. To see where these errors occur, you should produce an assembly listing using the -Wa-l flag of lcc and have a look at this file. If such an error occurs with a file generated by the compiler, send me the C source along with the listing.

Link Errors

Messages of the type:

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

are error messages from the linker. An image file is generated, but sould be corrupted. Detailed information about errors can be found in map files (generated using the -Wl-m flag of lcc).

DOS Shell Errors

The DOS shell truncates commmand lines to something like 128 characters. If you have to use a longer line due to the number of flags you pass to the compiler, I strongly encourage you to get bash, a DOS port of Unix Bourne-Again SHell. It is much more powerful than DOS shell, and does not truncate command lines. A better alternative is to get make, a DOS port of the Unix make utility, and use makefiles instead of DOS batch files. Of course, you can get both. They are available as part of DJGPP (DOS port of GNU C).


Known Problems

Known problems in GBDK 2.0


Links

GBDK Documentation and Support Files

GBDK Ports

Technical informations on the GameBoy

Back


Last Updated 21-Apr-99, Pascal Felber