/libsdcc-z80

Bare metal SDCC library for Z80.

Primary LanguageC

status.badge language.badge standard.badge license.badge

The SDCC Z80 bare metal library

What is SDCC bare metal programming?

It's when you use the SDCC C compiler without default startup code, header files, and libraries (using switches --nostdlib, --nostdinc, and --no-std-crt0). An example of this would be targeting a non-supported Z80 architecture or building an operating system.

libsdcc-z80 is the glue betweeen the SDCC C compiler and the Z80 processor. Z80 lacks instructions for integer and floating point arithmetics.

To mitigate it, the SDCC C compiler replaces these non-existing instructions with calls to special functions (such as: __mulint). Invisible to you, the linker then links these special functions with your code.

This works in the SDCC realm, but if you prevent the compiler to link default SDCC libraries then you need to provide these special functions, and the libsdcc-z80 does that.

How do I compile the libsdcc-z80?

Use make command in the root directory to compile libsdcc-z80. This will build the library inside the build directory and copy the binary libsdcc-z80.lib into the bin directory.

Can I skip the compilation?

Yes you can. Latest version of precompiled library is always available in the bin directory.

Can I use custom build and bin folders?

Yes. To compile this project from your project, pass absolute directories as variables BUILD_DIR and BIN_DIR.

make BUILD_DIR=~/myproj/build BIN_DIR=~/myproj/bin

Is there a sample available?

Check the sample directory! It contains a complete bare metal Z80 program and startup code for ZX Spectrum 48K that compiles to the 0x8000 address (data segment to 0x8100) and uses basic long, long long, and float operations.

A Makefile in this directory was deliberately stripped of all complexity so you can learn how the compilation works by reading it.

How do I create a bare metal program?

First you need a startup code. This is a code that is executed before your C program main() function is called. By convention you should call it crt0.s (the C runtime). This code must prepare the layout for your C program: configure the areas, initialize static variables, set the stack pointer, and jump to your main() function. You can find an example of crt0.s in the sample folder. Then you need to write your C program. When you have both, you compile and link them with libsdcc-z80.lib.

When linking you must pass crt0.rel as the first linker file!

Here is the compilation process that produces test.bin from test.c.

# Assemble crt0.s
sdasz80 -xlos -g crt0.s

# Compile test.c
sdcc -o test.rel \
     -c --std-c11 -mz80 --debug \
     --nostdinc --no-std-crt0 --nostdlib \
     test.c
    
# Link both
sdcc -o test.ihx \
     -mz80 -Wl -y \
     --code-loc 0x8000 --data-loc 0x8600 \
     --std-c11 -mz80 --debug\
     --no-std-crt0 --nostdinc --nostdlib \
     -L../bin -llibsdcc-z80 \
     crt0.rel test.rel

# Finally, convert ihx to binary
sdobjcopy -I ihex -O binary test.ihx test.bin

And, voila, your test.bin is ready.

How do I leave feedback?

Use the GitHub Issues on top of this page.