Compile and link vs. whatever zcc does

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
derekfountain
Member
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

Compile and link vs. whatever zcc does

Post by derekfountain »

I have a piece of test code which I've distilled to this:

Code: Select all

#pragma output REGISTER_SP = 0xD000

#include <arch/zx.h>
#include <arch/zx/sp1.h>

int main()
{
  sp1_Initialize( SP1_IFLAG_MAKE_ROTTBL | SP1_IFLAG_OVERWRITE_TILES | SP1_IFLAG_OVERWRITE_DFILE,
                  INK_BLACK | PAPER_WHITE,
                ' ' );
  
  while(1) {
    zx_border(INK_BLACK);
    zx_border(INK_WHITE);
  }
}
I can build a TAP with this:

Code: Select all

zcc +zx -vn -startup=31 -clib=sdcc_iy sp1_test.c -o sp1_test -create-app
which works fine. The sp1 call does practically nothing and the border goes fuzzy.

If I build it with these two lines:

Code: Select all

zcc +zx -compiler sdcc -c sp1_test.c -o sp1_test.o -I$ZCCCFG/../../include/_DEVELOPMENT/sdcc
zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -create-app
then I'm not sure what happens. The machine locks up (expected since there's an infinite loop) but the border doesn't go fuzzy so I'm presuming the sp1 call is actually doing locking.

I've tried various simple permutations of files and library calls, but they all seem OK. It's the use of the SP1 library which seems sensitive to whatever I'm doing wrong. Looking carefully at the compile lines (with -v output) I can see subtle differences between the two approaches. The nuances are rather beyond me though.

What's the correct compiler command line for building individual C sources for linking?
User avatar
dom
Well known member
Posts: 1320
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

In your split build you're creating the .o file with classic and then linking the final library with newlib.

So, you need to add -clib=sdcc_iy to the line that creates the .o
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

derekfountain wrote:If I build it with these two lines:

Code: Select all

zcc +zx -compiler=sdcc -c sp1_test.c -o sp1_test.o -I$ZCCCFG/../../include/_DEVELOPMENT/sdcc
zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -create-app
then I'm not sure what happens. The machine locks up (expected since there's an infinite loop) but the border doesn't go fuzzy so I'm presuming the sp1 call is actually doing locking.
This one is mixing up the classic library and the newlib.

zcc +zx -compiler=sdcc -c sp1_test.c -o sp1_test.o -I$ZCCCFG/../../include/_DEVELOPMENT/sdcc

is doing a classic compile (no clib=...). I think your include path is overriding the classic library's so that it is finding the right prototypes and formatting the calls properly. But this classic compile is an sdcc_ix compile so I'm not certain exactly what happens.
What's the correct compiler command line for building individual C sources for linking?
Start with the correct compile line:

Code: Select all

zcc +zx -vn -startup=31 -clib=sdcc_iy sp1_test.c -o sp1_test -create-app
And then tell zcc to stop at object file by adding "-c":

Code: Select all

zcc +zx -vn -c -startup=31 -clib=sdcc_iy sp1_test.c -o sp1_test -create-app
This will work but the output object file will be "sp1_test" because zcc is being told to rename it by "-o". The create-app step is never taken because a binary is not being produced so that option can be removed. And since no binary is being made, the startup to select a crt is unncessary too. The compilation is stopped before the binary building step.

So the correct invoke is:

Code: Select all

zcc +zx -vn -c -clib=sdcc_iy sp1_test.c
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

It looks like I doddle a lot more tan dom :)
derekfountain
Member
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

Post by derekfountain »

So that would give me these lines:

Code: Select all

zcc +zx -compiler sdcc -clib=sdcc_iy -c sp1_test.c -o sp1_test.o -I$ZCCCFG/../../include/_DEVELOPMENT/sdcc
zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -create-app
There's no (apparent) difference in the behaviour of the final program.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

try this:

Code: Select all

zcc +zx -v -c -clib=sdcc_iy sp1_test.c
zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -create-app
Make sure the old objects are gone just in case an error is occurring and it's picking up an old .o
derekfountain
Member
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

Post by derekfountain »

OK, catching up with overlapping posts, I tried Alvin's lines:

Code: Select all

zcc +zx -vn -c -clib=sdcc_iy sp1_test.c
zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -create-app
Still broken. But if I comment out the sp1 init call those build a working app.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

You're right. Something odd there - I'm looking into it now. The object linked one is sitting on a halt with ints disabled.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

The pragma is not active in the object file compile version so that the stack is not initialized at address 0xd000.

Code: Select all

zcc +zx -vn -c -clib=sdcc_iy sp1_test.c
This sees the pragma and creates the file "zcc_opt.def" to store the initial stack location. Pragmas are communicated to the crt when the binary is built. BUT:

Code: Select all

zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -create-app
Starts a new compile and erases the "zcc_opt.def" file. So the stack pragma is lost.

There is a way to tell zcc to preserve the zcc_opt.def file so that pragmas seen in separate compilation are accumulated (see the -preserve option for zcc) but it is much cleaner and simpler to store your pragmas in a separate pragma file:

zpragma.inc

Code: Select all

#pragma output REGISTER_SP = 0xD000
Then the compile line forming the binary reads the pragma file:

Code: Select all

zcc +zx -vn -c -clib=sdcc_iy sp1_test.c
zcc +zx -v -startup=31 -clib=sdcc_iy sp1_test.o -o sp1_test -pragma-include:zpragma.inc -create-app
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I guess the best way to see what pragmas were active in a compile is to take a look at the zcc_opt.def file after the binary is built. In this case you would have noticed the REGISTER_SP pragma was missing from the file.
derekfountain
Member
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

Post by derekfountain »

OK, my makefile is now working with the external pragma file. Thanks!
Post Reply