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.