Z88dk: sccz80: possible bug in linux binaries (not windows)

Created on 26 Aug 2018  ·  40Comments  ·  Source: z88dk/z88dk

Maybe someone can try a test compile of these programs. I cannot reproduce problems with windows binaries.

For ash.c:
zcc +zxn -clib=new -v -startup=30 ash.c -o ASH -subtype=dot-n -Cz"--clean" -create-app

The report says the output asm contains this:
ld hl,%eval( 8 2 -) ;const

Compiling to asm file you can see the line:
zcc +zxn -clib=new -v -startup=30 ash.c -a

Secondly, commenting out the definitions of TRUE and FALSE cause crashes.

For ansitest.c, this uses the new esxdos api in classic:
zcc +zx ansitest.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64

//ansitest.c will compile with this line despite the -o issue, amd the a.tap runs.
//zcc +zx ansitest.c -create-app -lndos -pragma-need=ansiterminal -Cl-v -pragma-define:ansicolumns=64
//Unknown option -o
//Predefined constant: __SCCZ80 = $0001

Adding "-o foo" causes unknown option

I haven't tested this one yet because I need to update the classic binaries.

For devt.c:
zcc +zx devt.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64 -o devt

Trying to compile with the new esxdos api in classic again. I tested without the esxdos bits which worked error free.

This line was reported in the asm:
ld hl,%eval( 7 2 -) ;const

Looking at these problems it kind of looks like the compile is not using the regex submodule which the new expression evaluator is based on?

question

Most helpful comment

I did the named initialise first as you may remember - my C is either 1990 or 2017 nothing in between.

All 40 comments

The expression stuff is local to copt code so there’s no regex dependency there.

Are you sure that the right copt binary is running? - the fact that the %expr is coming out in the final assembler at first glance indicates that it’s an old version.

Have you got a link to the original issue?

No the issue is in conversation and quoted above. I think there's also old source code involved but he's been doing a git pull and ./build.sh to make everything. A which copt should see if the bin is being pulled from the right place.

And actually I think that might be it - I have seen other distributions using the same names zcc and copt from 1989 code so maybe he's installed something that is earlier in the path.

If Tim has time to stop by maybe he can compare which sccz80 and which copt

From macos, on the first compile, using last night freshly extracted nightlies I got:
z80asm --cpu=z80-zxn -b -d -o"ASH" -m -s -L. -L"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/lib/sccz80" -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -I"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" -izxn "/tmp/tmpyE2OBqvy.o" "/tmp/tmpWhfNxF2w.o" Error: library file '/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/lib/sccz80/zxn.lib' version 12, expected version 11

Not sure if that's something I did wrong or not, I wanted to keep my old version of the the compiler so I just moved it aside and dropped last nights nightly in its place. Did I do something stupid, as usual?

-Dx

(even though I downloaded the prebuild I'll try debuilding it)

make clean && ./build.sh

from last night nightlies also fails on MacOS ending at the following:
cc -MMD -I. -Ilib -It -g -Wall -ftabstop=4 -std=gnu11 -O3 -I../common -I../../ext/optparse -I../../ext/regex -I../../ext/uthash/src -g -O2 -o z80asm codearea.o directives.o error_func.o errors.o expr.o hist.o libfile.o listfile.o macros.o main.o model.o modlink.o module.o opcodes.o options.o parse.o scan.o sym.o symtab.o z80asm.o z80pass.o zobjfile.o lib/alloc.o lib/array.o lib/class.o lib/dbg.o lib/list.o lib/minunit.o lib/srcfile.o lib/str.o lib/strhash.o ../common/die.o ../common/fileutil.o ../common/objfile.o ../common/optparse.o ../common/strutil.o ../../ext/regex/regcomp.o ../../ext/regex/regerror.o ../../ext/regex/regexec.o ../../ext/regex/regfree.o make -C dev/z80asm_lib ../../z80asm -xz80asm-z80-.lib --cpu=z80 @z80asm_lib.lst Error at file 'z80asm_lib.lst' line 8: library file '/usr/local/share/z88dk/lib/z80asm-z80-.lib' version 11, expected version 12 1 errors occurred during assembly make[2]: *** [z80asm-z80-.lib] Error 1 make[1]: *** [z80asm_lib] Error 2 make: *** [z80asm] Error 2

If it helps, here's some local system details:

`darran@kimberlyᐉ ZX/Next/ttest % xcode-select -p
/Applications/Xcode8.app/Contents/Developer

darran@kimberlyᐉ ZX/Next/ttest % uname -a
Darwin kimberly.xalior.com 16.7.0 Darwin Kernel Version 16.7.0: Thu Jun 21 20:07:39 PDT 2018; root:xnu-3789.73.14~1/RELEASE_X86_64 x86_64

darran@kimberlyᐉ ZX/Next/ttest % cc -v
Apple LLVM version 8.1.0 (clang-802.0.42)
Target: x86_64-apple-darwin16.7.0
Thread model: posix
InstalledDir: /Applications/Xcode8.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin`

Error: library file '/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/lib/sccz80/zxn.lib' version 12, expected version 11

The object format used by z80asm had to be bumped from version 11 to 12 to solve #885. The error message just means the assembler cannot understand the old format and you need to rebuild the library zxn.lib.

I indeed seemed to have an old version snaffled away in /usr/local/lib/, and that was stopping me rebuild the nightlies... - sorry about that!

-Dx

Error at file 'z80asm_lib.lst' line 8: library file '/usr/local/share/z88dk/lib/z80asm-z80-.lib' version 11, expected version 12

Those z80 compatibility lib files should be built when z80asm built. If z80asm finds another version someplace else, it will be using an older library version of those files.

Did it start working with the old version removed?

After killing that (which I think BREW left behind, ewwww! now have rm -rf /usr/local/lib/z88dk/ to be sure!) I could rebuild the nightly, but still cannot build ash.
This:
zcc +zxn -clib=new -v -startup=30 ash.c -o ASH -subtype=dot-n -Cz"--clean" -create-app

gets:
PROCESSING ash.c ucpp -iquote"." -D__Z88DK -D__ZXNEXT -D__Z80 -DZ80 -D__Z80_ZXN -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -D__SCCZ80 -isystem"/u/ZX/z88dk/lib/config/../..//include/_DEVELOPMENT/sccz80" -DSCCZ80 -DSMALL_C -D__SCCZ80 "ash.c" "/tmp/tmp9WhI2hDw.i2" zpragma -sccz80 < "/tmp/tmp9WhI2hDw.i2" > "/tmp/tmp9WhI2hDw.i" sccz80 -ext=opt -mz80 -standard-escape-chars "/tmp/tmp9WhI2hDw.i" -o "/tmp/tmp9WhI2hDw.opt" copt "/u/ZX/z88dk/lib/config/../..//lib/z80rules.9" < "/tmp/tmp9WhI2hDw.opt" > "/tmp/tmp9WhI2hDw.op1" copt "/u/ZX/z88dk/lib/config/../..//lib/z80rules.2" < "/tmp/tmp9WhI2hDw.op1" > "/tmp/tmp9WhI2hDw.opt" copt "/u/ZX/z88dk/lib/config/../..//lib/z80rules.1" < "/tmp/tmp9WhI2hDw.opt" > "/tmp/tmp9WhI2hDw.op1" copt /u/ZX/z88dk/lib/config/../..//lib/zxn_rules.2 < "/tmp/tmp9WhI2hDw.op1" > "/tmp/tmp9WhI2hDw.asm" cat "/tmp/tmp9WhI2hDw.asm" >> "/tmp/tmp9WhI2hDw.tmp" cat "/tmp/tmp9WhI2hDw.tmp" >> "/tmp/tmp9WhI2hDw.asm" z80asm -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -I"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" -s --cpu=z80-zxn -I"/u/ZX/z88dk/lib/config/../..//lib" "/tmp/tmp9WhI2hDw.asm" Error: library file '/u/ZX/z88dk/lib/config/../z80asm-z80_zxn-.lib' version 12, expected version 11
And, like you @aralbrec in https://github.com/z88dk/z88dk/issues/892 I had missing headers in the nightly which forced me to rebuild it to get them too...

-Dx

(sorry, I feel I'm making things more confusing, not helping you!)

Error: library file '/u/ZX/z88dk/lib/config/../z80asm-z80_zxn-.lib' version 12, expected version 11

This means you are running and old z80asm as it's expecting an older library version number.
Maybe check if which z80asm is coming from the right place. Or enter z80asm on its own to get version info and compare to z88dk/bin/z80asm with ./z80asm in that dir?

Yes the missing headers is an error, just have to wait for @suborb to have time to fix.

Here are the results on Ubuntu, after a fresh clone, ./build.sh

zcc +zxn -clib=new -v -startup=30 ash.c -o ASH -subtype=dot-n -Cz"--clean" -create-app: fails:
Error at file 'ash.c' line 160: symbol '_strcpy' not defined
Error at file 'ash.c' line 314: symbol '_ftell' not defined
Error at file 'ash.c' line 482: symbol '_strncpy' not defined
Error at file 'ash.c' line 682: symbol '_tolower' not defined
Error at file 'ash.c' line 764: symbol '_atoi' not defined
Error at file 'ash.c' line 890: symbol '_strcat' not defined
Error at file 'fcntl/z80/asm_vopen.asm' line 60: symbol 'asm_target_open_p1' not defined
Error at file 'fcntl/z80/asm_vopen.asm' line 127: symbol 'asm_target_open_p2' not defined

is this because of the missing headers?

zcc +zx ansitest.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64
$ zcc +zx ansitest.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64
Error at file 'ansitest.c' line 247: symbol 'esx_m_drvapi' not defined
1 errors occurred during assembly

Yes (I think I commented out the headers as those weren't present in the problem compile). But the reported problem is producing other errors which I can't reproduce and it looks like you're not reproducing either. I think the problem is mixed z88dk versions.

I think a system install was done a long time ago and that puts various bits in different places. I think a system install is best avoided now (at least for the newlib as that encourages local customization of the libs so some stuff must be in user dirs).

$ zcc +zx ansitest.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64
Error at file 'ansitest.c' line 247: symbol 'esx_m_drvapi' not defined
1 errors occurred during assembly

Log out, and log back in again, and it seems to have now found the right compiler...

`darran@kimberlyᐉ ZX/Next/ttest % v8.9.3
zcc +zxn -clib=new -v -startup=30 ash.c -o ASH -subtype=dot-n -Cz"--clean" -create-app

PROCESSING ash.c
ucpp -iquote"." -D__Z88DK -D__ZXNEXT -D__Z80 -DZ80 -D__Z80_ZXN -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -D__SCCZ80 -isystem"/u/ZX/z88dk/lib/config/../..//include/_DEVELOPMENT/sccz80" -DSCCZ80 -DSMALL_C -D__SCCZ80 "ash.c" "/tmp/tmp5r1y3XXr.i2"
zpragma -sccz80 < "/tmp/tmp5r1y3XXr.i2" > "/tmp/tmp5r1y3XXr.i"
sccz80 -ext=opt -mz80 -standard-escape-chars "/tmp/tmp5r1y3XXr.i" -o "/tmp/tmp5r1y3XXr.opt"
copt "/u/ZX/z88dk/lib/config/../..//lib/z80rules.9" < "/tmp/tmp5r1y3XXr.opt" > "/tmp/tmp5r1y3XXr.op1"
copt "/u/ZX/z88dk/lib/config/../..//lib/z80rules.2" < "/tmp/tmp5r1y3XXr.op1" > "/tmp/tmp5r1y3XXr.opt"
copt "/u/ZX/z88dk/lib/config/../..//lib/z80rules.1" < "/tmp/tmp5r1y3XXr.opt" > "/tmp/tmp5r1y3XXr.op1"
copt /u/ZX/z88dk/lib/config/../..//lib/zxn_rules.2 < "/tmp/tmp5r1y3XXr.op1" > "/tmp/tmp5r1y3XXr.asm"
cat "/tmp/tmp5r1y3XXr.asm" >> "/tmp/tmp5r1y3XXr.tmp"
cat "/tmp/tmp5r1y3XXr.tmp" >> "/tmp/tmp5r1y3XXr.asm"
z80asm -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -I"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" -s --cpu=z80-zxn -I"/u/ZX/z88dk/lib/config/../..//lib" "/tmp/tmp5r1y3XXr.asm"

PROCESSING /u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn/zxn_crt.asm.m4
m4 -I "/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" -I "/u/ZX/z88dk/lib/config/../..//src/m4" --define=__STARTUP=30 --define=__STARTUP_OFFSET=256 < "/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn/zxn_crt.asm.m4" > "/tmp/tmpyx8AE1YP"
cat "/tmp/tmpyx8AE1YP" >> "/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn/zxn_crt.asm"
cat "/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn/zxn_crt.asm" >> "/tmp/tmpyx8AE1YP.asm"
cat "/tmp/tmpyx8AE1YP.asm" >> "/tmp/tmpyx8AE1YP.tmp"
cat "/tmp/tmpyx8AE1YP.tmp" >> "/tmp/tmpyx8AE1YP.asm"
WILL ACT AS CRT

GENERATING OUTPUT

PROCESSING CRT
z80asm -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -I"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" -s --cpu=z80-zxn -I"/u/ZX/z88dk/lib/config/../..//lib" -I"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" "/tmp/tmpyx8AE1YP.asm"

z80asm --cpu=z80-zxn -b -d -o"ASH" -m -s -L. -L"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/lib/sccz80" -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -I"/u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn" -izxn "/tmp/tmpyx8AE1YP.o" "/tmp/tmp5r1y3XXr.o"
Error at file 'ash.c' line 160: symbol '_strcpy' not defined
Error at file 'ash.c' line 193: symbol '_strcpy' not defined
Error at file 'ash.c' line 204: symbol '_strcpy' not defined
Error at file 'ash.c' line 211: symbol '_strcpy' not defined
Error at file 'ash.c' line 218: symbol '_strcpy' not defined
Error at file 'ash.c' line 314: symbol '_ftell' not defined
Error at file 'ash.c' line 482: symbol '_strncpy' not defined
Error at file 'ash.c' line 682: symbol '_tolower' not defined
Error at file 'ash.c' line 764: symbol '_atoi' not defined
Error at file 'ash.c' line 861: symbol '_strcpy' not defined
Error at file 'ash.c' line 881: symbol '_strcpy' not defined
Error at file 'ash.c' line 890: symbol '_strcat' not defined
Error at file 'ash.c' line 897: symbol '_strcat' not defined
Error at file 'ash.c' line 917: symbol '_strcat' not defined
Error at file 'fcntl/z80/asm_vopen.asm' line 60: symbol 'asm_target_open_p1' not defined
Error at file 'fcntl/z80/asm_vopen.asm' line 127: symbol 'asm_target_open_p2' not defined
16 errors occurred during assembly
Errors in source file /u/ZX/z88dk/lib/config/../..//libsrc/_DEVELOPMENT/target/zxn/zxn_crt.asm:
Error at file 'ash.c' line 160: symbol '_strcpy' not defined
^ ---- p3head.bhead.len = length;
Error at file 'ash.c' line 193: symbol '_strcpy' not defined
^ ---- break;
Error at file 'ash.c' line 204: symbol '_strcpy' not defined
^ ---- strcat(wfn,(ext[0]=='\0')?dfe:ext);
Error at file 'ash.c' line 211: symbol '_strcpy' not defined
^ ---- }
Error at file 'ash.c' line 218: symbol '_strcpy' not defined
^ ---- char pp,sp,*lp;
Error at file 'ash.c' line 314: symbol '_ftell' not defined
^ ---- (null)Error at file 'ash.c' line 482: symbol '_strncpy' not defined
^ ---- (null)Error at file 'ash.c' line 682: symbol '_tolower' not defined
^ ---- (null)Error at file 'ash.c' line 764: symbol '_atoi' not defined
^ ---- (null)Error at file 'ash.c' line 861: symbol '_strcpy' not defined
^ ---- (null)Error at file 'ash.c' line 881: symbol '_strcpy' not defined
^ ---- (null)Error at file 'ash.c' line 890: symbol '_strcat' not defined
^ ---- (null)Error at file 'ash.c' line 897: symbol '_strcat' not defined
^ ---- (null)Error at file 'ash.c' line 917: symbol '_strcat' not defined
^ ---- (null)Error at file 'fcntl/z80/asm_vopen.asm' line 60: symbol 'asm_target_open_p1' not defined
Error at file 'fcntl/z80/asm_vopen.asm' line 127: symbol 'asm_target_open_p2' not defined`

aha there it is :) That's what I see.

Sorry ;-)

And, for completelness sake:

zcc +zx devt.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64 -o devt

Gets:

Error at file 'devt.c' line 247: symbol 'esx_m_drvapi' not defined 1 errors occurred during assembly Errors in source file /u/ZX/z88dk/lib/config/../..//lib/target/zx/classic/spec_crt0.asm: Error at file 'devt.c' line 247: symbol 'esx_m_drvapi' not defined ^ ---- (null)%

Ha np tim. It's important to find out where these probs are. Problem 1: old system installs are hard to get out of the way.

This other error just has to wait for the classic to get the esxdos.h header committed. I don't think it's a straight copy of newlib's as the classic merges the header for use by both sccz80 and sdcc whereas newlib keeps headers separate for each compiler.

If you uncomment the #include of stdio, ctype, stdlib you'll be left with:

Error at file 'fcntl/z80/asm_vopen.asm' line 60: symbol 'asm_target_open_p1' not defined
Error at file 'fcntl/z80/asm_vopen.asm' line 127: symbol 'asm_target_open_p2' not defined

I'm not sure how to solve that one, but it's further than the original error report.

And, for completelness sake:

zcc +zx devt.c -create-app -lndos -pragma-need=ansiterminal -pragma-define:ansicolumns=64 -o devt

Gets:

Error at file 'devt.c' line 247: symbol 'esx_m_drvapi' not defined 1 errors occurred during assembly Errors in source file /u/ZX/z88dk/lib/config/../..//lib/target/zx/classic/spec_crt0.asm: Error at file 'devt.c' line 247: symbol 'esx_m_drvapi' not defined ^ ---- (null)%

Yeah, you need -lesxdos rather than -lndos

Yes that is a shortcoming in newlib. It has not integrated disk io into its stdio yet so FILE* level disk io is unavailable. This error is coming from use of fopen() which is missing some backend code to open files.

In newlib, all disk io has to go through the low level esxdos api.

This other error just has to wait for the classic to get the esxdos.h header committed. I don't think it's a straight copy of newlib's as the classic merges the header for use by both sccz80 and sdcc whereas newlib keeps headers separate for each compiler.

I'd like it to be a direct copy, but there's a few too many unsigned char parameters in there for it work with sdcc - I'll have a think about how to sort that out.

You could probably clobber it in there.

The header could include the newlib sccz80 header if sccz80 is compiler and the newlib sdcc_iy header if zsdcc is compiler. I think both sccz80 and sdcc_iy c interface functions can coexist in the same library since zsdcc lib functions have leading underscore whereas sccz80 does not. But use of sdcc_iy functions means the zsdcc compile line must include --reserve-regs-iy.

Maybe not ideal.

I can feel a typedef coming along to handle this case - on sccz80 it's an unsigned char and for sdcc it's an unsigned int. A bit of an ugly kludge, but probably fairly quick to do and means that we can share headers.

Given that the calling convention is __smallc this really is a bug in sdcc - it's not actually doing __smallc calling conventions correctly.

Good call on the copy of "copt" - I had a copy in the /usr/local/bin - are there any other binaries I need to delete?

Restoring the original devt.c now with:

zcc +zxn -v -startup=30 -clib=new devt.c -o devt -subtype=dot-n -Cz"--clean" -create-app

PROCESSING devt.c
ucpp -iquote"." -D__Z88DK -D__ZXNEXT -D__Z80 -DZ80 -D__Z80_ZXN -D__ESXDOS_DOT_COMMAND -D__NEXTOS_DOT_COMMAND -D__SCCZ80 -isystem"/home/tim/git/z88dk/lib/config/../..//include/_DEVELOPMENT/sccz80" -DSCCZ80 -DSMALL_C -D__SCCZ80 "devt.c" "/tmp/tmpXXYZUR4v.i2"
zpragma -sccz80 < "/tmp/tmpXXYZUR4v.i2" > "/tmp/tmpXXYZUR4v.i"
sccz80 -ext=opt -mz80 -standard-escape-chars "/tmp/tmpXXYZUR4v.i" -o "/tmp/tmpXXYZUR4v.opt"
sccz80:"devt.c" L:11 Error:Missing token, expecting { got 0
Segmentation fault (core dumped)

static struct esx_drvapi rtc = { 0,{0,0},0 };

Removing the = { 0,{0,0},0 } prevents the seg fault. and DEVT compiles to a DOT using clib=new! So there is an issue with the compiler with initialising the static structure with a union inside.

The ansitest.c with the stuff from the above devt fixed and put back in still gives the same result as Xalior on the missing esx_m_drvapi - this is really what I want to get working to mix the ansi terminal with esxdos api facilities! I will go back to ASH.C now and try that rewriting to get rid of the IO stuff - oh wait I cant as I need the ESXDOS file handling to swap out into and that will give the same missing esx_m_drvapi error... I do appreciate all the help from everyone here though if that hurdle can be overcome I will be in heaven!

Have you tried replacing -lndos with -lesxdos?

Well am I a numpty or what - that works for a mix of DEVT and ANSITEST! Obviously I get A.TAP but I get the system time printed in ANSI colour!

So all I need to do now is work out what to do about the missing fopen etc in newlib... so that my old software can build as DOT's and use all the new facilities or go back to taps on classic for that as well as they make a lot of use of file management - and as a bonus I get ANSI colour...

You can probably #define fopen etc to your own set of functions:

define fopen esx_fopen

I think this would have to be done after stdio.h is included.

Then write esx_fopen to use handles instead of FILE. You may have to cast the handle as an integer or return the handle as HL in an asm implementation of esx_fopen so that FILE (16-bit pointer) is actually holding a 16-bit handle where the MSB is ignored. I guess there's still an issue with FILE* returned as NULL (0) if an error occurs. 0 is a valid file handle and I think the esx api actually returns -1 for failure. So maybe a pass through the code to replace NULL with ESX_NULL which is -1? And maybe you replace use of FILE* with ESX_FILE* too.

That's the first idea I had.

I'm working on that initialisation problem...however:

struct esx_drvapi
{
   union
   {
      uint16_t bc;
      struct
      {
         uint8_t driver;
         uint8_t function;
      }
      call;
   };

   uint16_t de;
   uint16_t hl;
};

With an initialisation of:

static struct esx_drvapi rtc = { 0,{0,0},0 };

Doesn't make a massive amount of sense to my mind.

I am happy to do it any way but {0,0,0} does the same seg. fault . Other instantiations may set driver to different things as they load dynamically so should really be { {'M',1} ,0,0 } for Mouse for example. But it is easy to explicitly set them in Main as I do anyway to work around the lack of initialisation. I was just surprised by the segfault expecting { got 0. So I never even noticed the incorrect brackets.

Yeah. I’m fixing the segfault. It looks like I never tried initialising nested structs.

Sccz80 doesn’t do named initialisation (yet?) so you’ll only ever be able to initialise the first member of a union. Which in this case is uint16

Yes that's correct C89 behaviour. It looks like sdcc is broken here too.

I'm amazed but it looks like zsdcc does named initilaization:

#include <stdint.h>

struct esx_drvapi
{
   union
   {
      uint16_t bc;
      struct
      {
         uint8_t driver;
         uint8_t function;
      }
      call;
   };

   uint16_t de;
   uint16_t hl;
};

//struct esx_drvapi rtc = { {0}, 0, 0 };
struct esx_drvapi ruc = { .call.driver = 1, .call.function = 2, .de = 3, .hl = 4 };

zcc +zxn -a -clib=sdcc_iy zzz.c

but it's getting the union wrong and doing both members of the union in the data structure:

_ruc:
    DEFW +0x0000
    DEFB +0x01
    DEFB +0x02
    DEFW +0x0003
    DEFW +0x0004

So .bc and the .call struct are not sharing space. That's why the weird initilaizer was working - the struct layout is broken.

So I think the only way to do it right for both compilers is to define the struct in asm.

In c make the compiler aware of it:

extern struct esx_drvapi ruc;

In a separate asm file define ruc's contents. Notice a data section is used because this will be non-zero initialized.

asm

SECTION data_user

PUBLIC _ruc

_ruc:

   defb 0   ; .call.driver
   defb 0   ; .call.function
   defw 0   ; .de
   defw 0   ; .hl

Then add that asm file to the compile line.

I did the named initialise first as you may remember - my C is either 1990 or 2017 nothing in between.

Thankfully it looks like the code generator gets it right so it's just the initialization broken in sdcc:

#include <stdint.h>

struct esx_drvapi
{
   union
   {
      uint16_t bc;
      struct
      {
         uint8_t driver;
         uint8_t function;
      }
      call;
   };

   uint16_t de;
   uint16_t hl;
};

//struct esx_drvapi rtc = { {0}, 0, 0 };
struct esx_drvapi ruc = { .call.driver = 1, .call.function = 2, .de = 3, .hl = 4 };

void main(void)
{
    ruc.bc = 10;
    ruc.de = 12;
    ruc.hl = 15;
    ruc.call.driver = 1;
    ruc.call.function = 2;
}
_main:
    ld  hl,0x000a
    ld  (_ruc), hl
    ld  l,0x0c
    ld  ((_ruc + 0x0002)), hl
    ld  l,0x0f
    ld  ((_ruc + 0x0004)), hl
    ld  hl,_ruc
    ld  (hl),0x01
    ld  hl, +(_ruc + 0x0001)
    ld  (hl),0x02
    ret

I've just merged #897 to resolve the initialisation fault.

Was this page helpful?
0 / 5 - 0 ratings