zcc manual available ?

Discussion about other targets
Post Reply
PokeMon
New member
Posts: 4
Joined: Tue Mar 04, 2014 12:00 am

zcc manual available ?

Post by PokeMon »

As I am working now with z88dk and try to integrate c related stuff in assembly context - I wonder if there is a manual or detailed description about zcc (zccp) with options to use. A bit more detailed than just the list getting with "-help". ;)

Of course I can try myself but would be more easy to have help. Even the wiki is not very detailed in that point.

I now found an option to have access to the assembly files which maybe sufficient for my purpose.
I want to have plain Z80 code - target independant or at least no overhead.
As I can assemble the code myself I could manage to grab the temporary asm files.

Or are there better solutions ?
Use library option ?

I now used this options during first tries - any other proposals ?

Code: Select all

zcc +zx81 -a -no-cleanup -O3 -v hello.c -o hello.bin
or using

Code: Select all

zcc -a -no-cleanup -O3 -v hello.c -o hello.bin
The code is the same, just more defines for available libs (zx81 related I think).

The source is:

Code: Select all

# include <stdio.h>
int main (void)
{
printf("Hello world \n");
printf("Hello world 2");
return 0;
}
Last edited by PokeMon on Tue Mar 04, 2014 11:37 pm, edited 1 time in total.
User avatar
dom
Well known member
Posts: 2091
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

Compiling an executable needs 3 things. Your code, the crt0 and some library functions.

The crt0 is basically the startup for the target and is the bit that jumps to main.

The library is composed of at least two parts: the generic z80 support library - this contains functions such as multiply, get long from stack etc and a machine specific part that interfaces to the hardware - in your example it would contain the entire printf function.

So, you can quite legitimately use the -a option to get hold of the assembly file. Pull that into your project and the.n link outside. You'll have to link with at least the z80 support library. If you use any of the standard library ie ctype, strings you can just use the platform library from any target. If you want output then you'll need to build a custom library. There's a retarget.txt file that tells you what you need to do.

The most bare metal target is embedded so take a look at that.

The other thing to bear in mind is that with z88dk you can mix and match assembly files with c files so you might find it easier to have zcc manage everything and create a new target for whatever you want to do.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

PokeMon wrote:I want to have plain Z80 code - target independant or at least no overhead.
As I can assemble the code myself I could manage to grab the temporary asm files.

Or are there better solutions ?
Use library option ?

I now used this options during first tries - any other proposals ?

Code: Select all

zcc +zx81 -a -no-cleanup -O3 -v hello.c -o hello.bin
or using

Code: Select all

zcc -a -no-cleanup -O3 -v hello.c -o hello.bin
The code is the same, just more defines for available libs (zx81 related I think).

The source is:

Code: Select all

# include <stdio.h>
int main (void)
{
printf("Hello world \n");
printf("Hello world 2");
return 0;
}
Just to expand on what dom said:

"zcc -a" is going to show you what the C compiler did to translate main.c to asm. It's the asm that solely implements the main.c file, without any additions.

"zcc +zx81" is going to select the zx81 target for you. You're going to get the translated main.c as above, but you will also get a zx81 crt0, which is the small program that sets up the C environment prior to jumping to main. What you'll find in there are things like setting up the heap, the exit stack (C requires an exit stack of 32 entries I think), movement of the stack pointer (maybe), creation of STDIN/STDOUT/STDERR file blocks, space made for floating point registers, etc. In addition, the zx81 crt0 can be configured (with an appropriate -startup on the zcc line) to implement hi-res graphics and if this is done space is set aside for a display file and a display routine is incorporated that replaces the zx81 rom routine. All told, its purpose is to supply the most general implementation for the zx81 which is quite often what you want. However, you might consider this overhead as you may not want all these things and these things do come at a cost in memory footprint. The zx81 is also a little bit special as its memory areas (with ram expansion) are not created equal -- some of it cannot contain executable code. So another reason you may not want to use the zx81 crt0 is to take tighter control over the memory map. All this depends on what your project is; stef has done a lot for the zx81 target and you may find an appropriate startup for you but if not you'll probably want to write your own.

The other thing "+zx81" does is select the libraries to use for the zx81 target. As dom mentioned, the libraries can be split into three parts :- a generic part used for any z80 machine (things like strcpy, isspace, etc), a generic part supplying primitives the compiler needs (things like add two longs, multiply two numbers, even minute things such as read a long from memory), and an architecture specific part to interface with the hardware somehow (drawing graphics, the stdio backend where input is gathered and written to screen, etc).

So, the linker will put together a binary with the crt0 first, followed by your C program + asm files if you have any + library function code + space for variables. The crt0 contains the only ORG and that's what you RAND USR. The crt0 does its thing and then jumps to main.

Where you find related files:

z88dk/lib/clibs/zx81_clib.lib
This is the almost complete library used for the zx81.
Using "+zx81" will supply "-lzx81_clib" to z80asm so linking occurs against this library

z88dk/libsrc/zx81.lst
Lists all functions that are placed in that library when the libraries are made
The '@' symbol is like an include for another list. For example, "@z80.lst" is pulling in the generic z80 library and you can find that in that directory too.

z88dk/lib/zx81_crt0.asm
This is the zx81 crt0. As you can see it can be quite complicated with lots of different options.


Now you don't have to use the built-in stuff to target the zx81. Dom mentioned you can modify the embedded target ("embedded_crt0.asm") which is probably the most bare target there but you don't have to start from that. You can start very simple (XREF _main; org xxxx; jp _main) and add things as you need them. You can compile your own list of library functions (see the zx81.lst above) and make a library out of that. Then when you compile, link against that library but there may be no significant advantage to doing that than using the existing zx81 clib -- keep in mind z80asm is a real linker so it will only attach code that you use, but seeing that list you can maybe be more familiar with where the library source is located and you can investigate the source yourself to decide it that's what you want to use.


About mixing C and asm :- you can do that as much as you want. That main.c program could have been written in asm if you had chosen to (bypass the zcc -a step), calling the library functions directly. To do that, you need to look at the library source and see how registers have to be set up prior to calling.

You can specify multiple files on the zcc compile line too.

zcc +zx -vn frankt.c frankt.asm -o frankt -lndos -create-app
http://www.worldofspectrum.org/forums/s ... stcount=35

There frank.c prototypes a function that takes no parameters. The same name (with leading _) appears as asm entrypoint in frankt.asm. This way the C program calls the asm subroutine directly. When parameters are passed, you implement a linking method at the start of the asm function to gather parameters from the stack into registers.

Anyway I'll stop there and you can ask more questions if you like. I'll just point out there is a lot of new (and probably buggy) code in z88dk/libsrc/_DEVELOPMENT that is being frequently updated; this will be a new clib option and you are welcome to help test it :) The new approach being taken is to completely separate the asm implementation from the C prologue (the bit where the parameters passed on the stack by the c compiler are gathered into registers) so that, one option, asm programmers can use library functions without any C overhead at all.
PokeMon
New member
Posts: 4
Joined: Tue Mar 04, 2014 12:00 am

Post by PokeMon »

Well, dom & anvil,
thanks for your fast and very detailed answers.
I think this will be enough information for a good startup and as soon as I have more questions I will come back to this thread. :)
Post Reply