Notes for using SDCC to create z80 code (also applies to z180, r2k, r3ka and gbz80).
crt0.o and --code-loc and --data-loc
The option argument to --code-loc specifies the location where sdcc will place your code. However the place where the startup code from crt0.o is placed is specified in it's source file crt0.s. The default crt0.s places the startup code at address 0. Thus specifying --code-loc 0 will cause problems since sdcc will try to place both your code and the startup code at address 0.
Example for the !ColecoVision with custom crt0.o and already compiled object files in the directory:
sdcc -mz80 --no-std-crt0 --code-loc 0x8080 --data-loc 0x7000 "../colecovision lib/bin/libcvu.lib" "../colecovision lib/bin/libcv.lib" "../colecovision lib/bin/crt0.o" *.o
The example uses two libraries. The program is to be placed into ROM, which is located at 0x8000, while RAM is located at 0x7000. Note that the argument to --code-loc is 0x8080, which leaves 0x80 bytes at 0x8000 for the startup code from crt0.o.
Writing efficient code
memcpy() [Does not apply to gbz80, which doesn't have ldir or equivalent]
Code generation for memcpy() is very efficient. Don't hesitate to use it. E.g. copying a structure (with at least two member variables) will be much more efficient using memcpy() than by assigning the members.
The port has complete support for the _Bool/bool data type when compiling in c99 or sdcc99 mode. Use bool for condition variables, since sdcc will generate more efficient code than e.g. when using unsigned char.
signed vs. unsigned
The Z80 lacks an efficient signed comparison. Using unsigned variables will result in slightly smaller and faster code. On the GBZ80 the situation is even worse, resulting in a more substancial difference in code size and speed.
Make called functions save bc.
Use the provided name for the code segment.
Use the provided name for the const segment.
Set the port mode for I/O to z80 or z180.
Generate code for the selected assembler (rgbds, sdasz80, isas or z80asm). This option can reduce the efficiency of peephole optimization.
Do not link the default crt0.rel. Use this when using a custom crt0.rel instead.
--reserve-regs-iy [Does not apply to gbz80, which doesn't have iy]
This option tells the compiler that it is not allowed to use register pair iy. The option can be useful for systems where iy is reserved for the OS.
Dump the control flow graph, variable conflict graph and tree-decomposition of the control-flow graph in .dot format.
Set the maximum number of register assignments considered at each node of the tree decomposition. Higher values make sdcc slower, but tend to result in better code being generated. The default value is 3000.
--oldralloc [Does not apply to gbz80, where the old register allocator was very broken]
Use the old register allocator. Typically the new allocator is slower, but generates better code (unless --max-allocs-per-node is set to very low values).