Showing posts with label make. Show all posts
Showing posts with label make. Show all posts

In this -third- part of our tutorial we are going to compile the GNU Debugger. It was ported to the Zilog Z80 architecture by Leonardo Etcheverry and is available from his git repository. The code is old and you need to apply some hacks for it to compile.

First install some additional tools. These are not part of the standard Ubuntu installation:

sudo apt-get install ncurses-dev flex bison
GNU Debugger also requires the texinfo package. But shall avoid compiling documentation because it is outdated and recent versions of texinfo are too strict for the job.
Now fetch gdb-z80 source code by first cd-ing to your ~/dev folder and executing:
git clone https://github.com/legumbre/gdb-z80.git 
cd gdb-z80
You are now ready to compile. Configure the package for cross debugging. Here is the command to do it:
./configure --enable-werror=no --target=z80-unknown-coff
The target of cross compilation is z80. The --enable-werror=no switch turns off error on warning behaviour on newer versions of gcc. The code is too old to pass without warnings and we don't want them to break the compilation.

Before running make we need means to avoid compiling documentation. The tool that we strive to avoid is makeinfo which is part of texinfo package. As you can remember we did not install it. So we are going to make the make think we have it by redirecting it to another tool which will do ... absolutely nothing ... and return success. It just so happens that unix has such a tool. It's called Wine. No, wait. It is called /usr/bin/true.

So here is how we call our make file
make MAKEINFO=true
We apply the same trick to install gdb-z80 to destination folder
sudo make MAKEINFO=true install

If everything went according to our grand plan there are two new files in your /usr/local/bin folder.
ls /usr/local/bin 
z80-unknown-coff-gdb  z80-unknown-coff-gdbtui
Grand! Now install your favourite GDB GUI. I recommend the Data Display debugger. It is absolutely archaic piece of technology and brings you back to the early days of unix when Motif roamed the earth. Just the right tool for ZX Spectrum development.

Install the DDD
sudo apt-get install ddd
And test our system by passing gdb-z80 to the Data Display Debugger using the --debugger option.
ddd --debugger z80-unknown-coff-gdb &
 

Yaay. You have a debugger for Z80 on your system. Next time we are going to dwelve into remote debugging and step through a program on your ZX Spectrum emulator.

Till then ... be patient.

Let us compile'n'run stuff.

In part I. of this turorial you "gitted" yx repository to your local disk. If you followed the tutorial then your target folder was ~/dev/yx.

Open the terminal and set this as your current working folder. Go to tools subfolder (e.g. execute cd ~/dev/yx/tools). There are a bunch of useful tools inside but right now we are only interested in makezxbin. This is an upgraded makebin tool that enables us to use SDCC C compiler for ZX Spectrum development.

You are free to choose z88dk instead. But SDCC is -in my opinion- a more mature environment. It supports C99; has as advanced code optimizer; and produces gdb-z80 compatible symbolic information. z88dk on the other side has superior libraries and ZX Spectrum support.
You can compile and deploy makezxbin like this:
cd makezxbin
gcc makezxbin.c -o makezxbin
sudo mv makezxbin /usr/bin/makezxbin
Congratulations! You now have a complete suite of compiler tools needed to develop for ZX Spectrum.

Now go to the ~/dev/yx/apps/template folder and run make. This will create a template application which writes a value of 255 to the first byte of video memory. When it is run the result will be 8 pixel line in the first row of the screen:

The make file will also run the emulator and load your app.
You can use this template application as a quick starter for most of your development projects. Let's analyse it.

First there is a pretty straightforward Makefile. Its main target is app.bin. The Makefile assumes that all *.c files ald all *.s files are part of our project. Thus if you add new source files - it will automatically consume them as part of our project.

For easier understanding here are the unconventional tricks of this Makefile:
  • it uses your standard gcc (and not SDCC!) compiler to generate .depend file out of *.c and *.h source files for easier compilation,
  • it puts crt0.s to 0x8000 and your program to 0x8032, so if you change crt0.s (increasing its length above 0x32 bytes) make sure you update your programs' start address,
  • it uses our makezxbin tool to generate correct binary (makebin has a bug and can't be used for this purpose), and
  • it uses SDCC all the way but at the end executes appmake +zx --binfile ./app.bin --org 32768 to generate ZX Spectrum tape. appmake is part of z88dk and this is one reason installing both development environments in part I. of this tutorial.
The other two files in the folder are crt0.s and app.c  crt0.s is a standard name for a startup file t.i. a file that gets executed first when your program is stasrted.  This one prepares everything to run your program from BASIC and return control to it. It:
  • stores current stack pointer and contents of all registers,
  • jumps to start of GSINIT assembler section where the SDCC compiler places all global variables initialization code,
  • establishes stack (1KB) and heap global symbols for our program,
  • jumps to _main C function, and
  • when the main concludes restores registers and stack and returns control to BASIC.
crt0.s is compiled to address 32768 (0x8000) and is 0x32 bytes long. app.c code is compiled to the address 0x8032. It contains the main function.  This function simply writes 255 to the first video memory byte:
void main() {
    unsigned char * vmem = 16384;
    (*vmem)=255;
}
You can examine the locations of your symbols (variables, functions) by opening crt0.map file after compilation.
That's it for yoday. Enjoy your experimenting. Our next tutorial will be about debugging.

GNU Make is a decent tool. But due to the fact that I commonly create only a handful of Makefiles per project and that its syntax is easy to forget (or -perhaps- hard to remember) - it often takes me an hour before I create a new generic Makefile for a project.

More often then not I end up analysing and recycling an existing one from one of my previous projects. Thus I wrote a generic Windows starter that will work on any folder that contains .c and .h files as long as you have The GNU C Compiler Suite and Make installed on your machine.

Simply add this Makefile to your folder and change the target (the default is "buddy.exe") to the name of your desired exe output file. Make sure that one .c file contains the main function and the rest will be done by the build system.

The main tricks being used are:

1. Obtaining list of all *.c files in folder...

SRCS    =   $(wildcard *.c)
2. ...using it to generate all object files.
OBJS    =   $(patsubst %.c,%.o,$(SRCS))
3. Creating dependency file named .depend by using -MM switch on gcc (i.e. fake compilation step).
$(CC) $(CFLAGS) $(SRCS) -MM >> .depend
4. Including dependency file into makefile using -include (minus means it will not complain if the file is not there i.e. on the first run).
-include .depend
5. And last but not least: redirection of stderr to NUL to prevent DEL command from complaining when there are no matching files.
del *.o 2>NUL
Here is the entire Makefile.


CC = gcc CFLAGS = -I. SRCS = $(wildcard *.c) OBJS = $(patsubst %.c,%.o,$(SRCS)) .PHONY: all clean all: depend buddy.exe depend: $(SRCS) del .depend 2>NUL $(CC) $(CFLAGS) $(SRCS) -MM >> .depend -include .depend %.o: %.c $(CC) -c -o $@ $< $(CFLAGS) buddy.exe: $(OBJS) $(CC) -o $@ $^ clean: del *.o 2>NUL del *.exe 2>NUL del .depend 2>NUL

Older Posts Home

Blogger Syntax Highliter