               gbdk-3.1 - https://github.com/Zal0/gbdk-2020/releases
               ----------------------------------------
            (C) 2001 Michael Hope <michaelh@juju.net.nz>

Short story:
------------
win32:
* Unzip using WinZip or similar (which you've probably already done :)
    e.g use WinZip to extract to d:\gbstuff\gbdk
* Add the 'bin' directory to your path if required.
    e.g Add 'PATH=%PATH%;d:\gbstuff\gbdk\bin' to autoexec.bat, or
  through the System control panel on Windows NT or 2000.
* Restart if needed.
* GBDK is ready to go - there is no need to compile the libraries or
  to set environment variables.  You may want to remove the
  GBDKDIR line from autoexec.bat that an older version of gbdk may
  have put there.
  See the ChangeLog for more information.
* You can compile the examples by running 'make.bat' in examples\gb
    e.g d:, cd \gbstuff\gbdk\examples\gb, make

Linux:
* Very similar to win32
* Extract the archive somewhere (normally /opt/gbdk)
* Set GBDKDIR to where you installed with a trailing /
    e.g. export GBDKDIR=/home/michaelh/gbdk/
* Try compiling the examples as above

Special note:
-------------
I've reverted the WORD to 16 bit unsigned change that required
-DGBDK_2_COMPAT=1.  You can use BYTE_IS_UNSIGNED if you, like me,
really want WORD to be unsigned :)

Reporting problems and feature requests
---------------------------------------
1.  Make sure that you have read this README fully.
2.  Have a read of the gbdk homepage
    http://gbdk.sourceforge.net/
3.  Read the latest copy of this README
    http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/~checkout~/gbdk-support/README?cvsroot=gbdk
4.  Make sure you have the latest version
    http://sourceforge.net/project/?group_id=1249
5.  Check if anyone else has reported the problem
    http://sourceforge.net/bugs/?group_id=1249

To download the latest source, get the tarball on sourceforge,
extract, and type:

make -f update.mak update

The Linux binary is normally installed in /opt/gbdk.  If you
install somewhere else, set GBDKDIR to the appropriate path.
eg.
        export GBDKDIR=/opt/gbdk/

Note the trailing slash.

Documentation
-------------
Latest version of this README:
    http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/~checkout~/gbdk-support/README?cvsroot=gbdk

Library documentation:
        http://gbdk.sourceforge.net/doc/html/index.html
This was generated from include/*.h by doxygen

General Gameboy information:
        http://www.devrs.com/gb/

GeeBee FAQ:
        http://www.devrs.com/gb/files/faqs.html

GBSpec aka Pan doc
        http://www.devrs.com/gb/files/gbspec.txt

Banked function support
-----------------------
2.95 and above supports banked functions.  The rules are:

* Any function with the attribute 'nonbanked' ie

    int puts(const char *sz) nonbanked;

  will be put into HOME.

* Any function with the 'banked' attribute can be called from any bank
  A banked call has four extra bytes of stack overhead and adds 56
  m-cycles to each call.  If anyone can suggest a faster method, I'd
  love to hear it.

* Any static function will be treated as 'near' and not have the
  overhead of a banked call.

* If you specify 'banked' with either static or nonbanked, the function
  will be non-banked.

* The model used sets whether 'normal' functions (without the banked,
  nonbanked, or static modifiers) are banked or not.  The currently supported
  options are:
        --model-medium  Functions are by default banked
        --model-small   Functions are by default nonbanked
  The default is model is small.  The compiler defines SDCC_MODEL_SMALL
  or SDCC_MODEL_MEDIUM depending on the current model.  Libraries for both
  models are provided in lib/small and lib/medium

* types.h defines BANKED and NONBANKED to 'banked' and 'nonbanked'
  respectively.  I recommend using these for future compatibility and
  for portability.

Some notes:
  * Currently only works with rgbds and isas.  asxxxx doesn't support
    resolving the bank of a function at link time

  * Pointers _will not_ pass correctly across banked functions.  For
    speeds sake pointers are still 16 bit, so if you call a banked
    function with a pointer that is in your bank, the pointer will
    become invalid when your bank disappears.  Be warned.  Note that
    calls within the same bank will still work.  Some ways of getting
    around this problem are:

      o Put heavily used functions or functions that take pointers
        in HOME.  Then the pointer will remain valid.
      o Calls within the same module (ie file) should be in the same
        bank.  Id like to say will, which is true in asxxxx, but I
        haven't confirmed it.

  * A banked call adds an extra 4 bytes to the stack and quite a few
    extra cycles to the call.  Don't use it for heavily used functions
    and avoid it where possible by grouping dependent functions into
    one bank to make them 'near'

  * Assembly functions and functions that don't take parameters (ie
    functions that don't care if a few extra bytes are added to their
    call stack) can be treated as both 'banked' and non-banked.  This
    is due to how the return address of the calling function is
    mangled.

  * Only non-banked (this includes static) functions may be used as
    parameters or have their address taken.  If you don't know what
    this means then you should be OK :)

I have made some of the library functions banked.  More will follow.
Using the banked attribute under asxxxx will cause no harm, but you
are limited to being in the first two banks (32k)

#pragma bank=[xx] has been extended.  Using [xx] = a number (1, 2..)
is assembler independent.  The special banks HOME and BASE are also
assembler independent.  Note that the last #pragma bank= will be the
one that applies for the whole file.

One more thing.  As banked and non-banked functions may be mixed the
compiler commits any constant data at the end of each function.  One
side affect is that code like this:

const int array[] = { 1, 2, 3, 4 };

void foo(void) nonbanked { ... };

will associate array[] with foo() and as foo is in HOME so will be
array.  This only occurs when a constant inialised array is declared
immediately before a nonbanked function.

rgbds support
-------------
2.95 added decent rgbds support.  Basically:
  o Use "sdcc -mgbz80 --asm=rgbds file.c" for each file.c
  o Use "sdcc -mgbz80 --asm=rgbds crt0.o gbz80.lib gb.lib file1.o file2.o..."
crt0.o, gbz80.lib, and gb.lib are in lib/rgbds.  The missing parts are
currently:
  * lcc does not work with rgbds.  You have to call sdcc directly, setting
    up the include path and making the libraries local as appropriate.

  * sdcc does not support the concept of an output file name when
    linking.  This means that your cart will be called 'a.gb', the
    .sym file 'a.sym' etc.

  * The libraries are generated directly from gbdk-lib by 
    tools/astorgb.pl.  The converter may have bugs which passed on 
    through to the libs.  Be cautious of any assembler library functions.

  * I don't know why, but xlink seems to load all of the libraries
    instead of just the ones that are required, adding a significant
    overhead.  this is being investigated.

  * Static initialised data like:

        int data[] = { 1, 2, 3, 4 };
    currently isn't supported.  sdcc pulls some tricks with the way that
    sections are allocated to support the initialisation code which rgbds
    doesn't support.  In any case, static inited data is normally a bug -
    most people normally mean:
        const int data[] = { ... };
    This is especially the case with tile data etc on the gb.

Some of the examples don't yet work.  For now you need a make utility like
GNU make (see below) to compile them.

Differences between this and gbdk-2.1.5
---------------------------------------
* It now uses sdcc <http://sdcc.sourceforge.net/> as the C compiler
  which should lead to better code but unfortunately will generate
  a whole new set of bugs :)  Most of the differences below are due
  to this change-over.

* sdcc _does not_ automatically promote variables to int's.  This is 
  a 'good thing' as normally the promotion is unwanted on an eight
  bit system, but in some places you may get the wrong result.  If
  so, try promoting the variable manually i.e. (int)foo*20;

* If funny things happen when you access registers, try declaring them
  as volatile.  See <hardware.h> for an example.  sdcc normally caches
  variables for speed, but this causes trouble when accessing registers.

* The basic types have changed.  The sizes are now:
        char            8 bits
        int             16 bits
        long            32 bits
        long long       Doesn't exist

* Float support is there but unconnected.

* gbdk has an alternitave set of typedefs for those who like me like
  their WORDs to be unsigned.  Define BYTE_IS_UNSIGNED=1 to use the new
  typedefs.
        Before          With            Or              Size
        BYTE            INT8                            8 signed
        UBYTE           BYTE            UINT8           8 unsigned
        WORD            INT16                           16 signed
        UWORD           WORD            UINT16          16 unsigned
        DWORD           INT32                           32 signed
        UDWORD          DWORD           UINT32          32 unsigned

* There is now real initialised static data support.  You can now use
  BYTE abModifyMeLater[] = { 5, 6, 7, 8 };

  void foo(void) 
  {
    abModifyMeLater[2] = 12;
  }
  and it will work.  Currently this is very inefficient but it will
  be improved.  See const in the next section

* Constant global structs (ie tile data, sprites) SHOULD be declared
  as 'const'  If they are not declared const, not only do they get copied
  into ram at startup but they take up about 6x the rom space.

References
----------
Jeff's gbdev page
http://www.devrs.com/

rgbds
http://www.otakunozoku.com/

GNU make
ftp://agnes.dida.physik.uni-essen.de/home/janjaap/mingw32/newnew/

-- Michael Hope
   <michaelh@juju.net.nz> <nz_michaelh@yahoo.com>
