Compiler versions tried are 3.0.0 and latest snapshot.
When I use the --no-std-crt0 option in a -mz80 build and supply my own crt0.rel file linking does not appear to be working correctly even when the crt0.rel file is a copy of the original z80 crt0.rel. The problem I see is the call to initialise the data array points to the C9 return code after the array initialisation code. In the attachment I have provided some simple test code and the good and bad binary images of the code produced.
To work around the problem I have to remove the --no-std-crt0 option and copy my customised crt0.rel file to the /usr/local/share/sdcc/lib/z80/ directory.
Problem build:
sdcc -mz80 --no-std-crt0 --data-loc 0 testcrt0.rel crt0.rel
Build that works
sdcc -mz80 --data-loc 0 testcrt0.rel
I'm new to sdcc so apologies if I'm doing something incorrect.
source and binary image
The workaround probably just changes the order, in which the linker sees the files.
Try setting --data-loc and --code-loc to more sensible values. In particular, do not tell the linker to place the any of those sections at the same place as the crt0.
Your example tells the linker to place both the data and part of crt0 at address zero (the crt0 has an .org 0 and .org 0x100). The safe way is probaly to try rather high --data-loc and --code-loc first, and then reduce it to calim back unused space between crt0 and them.
Please report back if this fixes your problem.
Philipp
I've tried all sorts of settings with code and data locations, here is one with some settings that seem sensible to me but still produces the same problem:
sdcc -mz80 --no-std-crt0 --code-loc 0x0800 --data-loc 0x1000 testcrt0.rel crt0.rel
The code goes into 0x0800 fine but the data initialisation still wants to call the 0xC9 return instruction at 0x1024. It should actually be calling 0x100d instead.
00000100 31 FF FF CD 24 10 CD 00 08 C3 0D 08
00001000 FF FF FF FF FF FF FF FF 21 00 10 36 12 21 01 10 36 12 23 36 12 23 36 12 23 36 12 23 36 12 23 36
00001020 12 23 36 12 C9
It would appear that the --no-std-crt0 option insists that you have to init the data yourself but this is not what the manual states, I just want to tell the compiler to use my own crt0.rel file and it should not be bypassing the initialisation of the data.
I've tried all sorts of settings with code and data locations, here is one with some settings that seem sensible to me but still produces the same problem:
sdcc -mz80 --no-std-crt0 --code-loc 0x0800 --data-loc 0x1000 testcrt0.rel crt0.rel
The code goes into 0x0800 fine but the data initialisation still wants to call the 0xC9 return instruction at 0x1024. It should actually be calling 0x100d instead.
00000100 31 FF FF CD 24 10 CD 00 08 C3 0D 08
00001000 FF FF FF FF FF FF FF FF 21 00 10 36 12 21 01 10 36 12 23 36 12 23 36 12 23 36 12 23 36 12 23 36
00001020 12 23 36 12 C9
It would appear that the --no-std-crt0 option insists that you have to init the data yourself but this is not what the manual states, I just want to tell the compiler to use my own crt0.rel file and it should not be bypassing the initialisation of the data.
Could you try
1) Swapping the order of testcrt0.rel and crt0.rel in your command line
2) Using a higher value for --code-loc than for --data-loc
3) Both of the above
And provide the .map files?
Currently this looks like a bug in the default crt0 to me:
.area _GSINIT
gsinit::
.area _GSFINAL
ret
will only work if the linker sees the crt0 first, placing the gsinit:: at the start of the gsinit section, and the initialization from the other files after that, before the ret. If the linker sees the other filees first, it will first place the initialization ocde, effectively jumping to the ret at the end of the initialization.
Philipp
Apologies for the double post before...
Also I meant to say:
"The code goes into 0x0800 fine but the data initialisation still wants to
call the 0xC9 return instruction at 0x1008."
As can be seen the code and data locations don't change even when swapping the addresses...
Swapped rel ordering:
sdcc -mz80 --no-std-crt0 --code-loc 0x0800 --data-loc 0x1000 crt0.rel testcrt0.rel
00000100 31 FF FF CD 24 08 CD 00 10 C3 0D 10
00000800 FF FF FF FF FF FF FF FF 21 00 08 36 12 21 01 08 36 12 23 36 12 23 36 12 23 36 12 23 36 12 23 36
00000820 12 23 36 12 C9
00001000 3E 30 F5 33 CD 13 10 33 C9 3E 02 CF C9 3E 00 CF 76 18 FD 21 02 00 39 6E 3E 01 CF C9 6B 3E 01 CF
00001020 C9
Swapped rel ordering address locations:
sdcc -mz80 --no-std-crt0 --code-loc 0x1000 --data-loc 0x0800 crt0.rel testcrt0.rel
00000100 31 FF FF CD 24 08 CD 00 10 C3 0D 10
00000800 FF FF FF FF FF FF FF FF 21 00 08 36 12 21 01 08 36 12 23 36 12 23 36 12 23 36 12 23 36 12 23 36
00000820 12 23 36 12 C9
00001000 3E 30 F5 33 CD 13 10 33 C9 3E 02 CF C9 3E 00 CF 76 18 FD 21 02 00 39 6E 3E 01 CF C9 6B 3E 01 CF
00001020 C9
Normal rel ordering and swapped address locations:
sdcc -mz80 --no-std-crt0 --code-loc 0x1000 --data-loc 0x0800 testcrt0.rel crt0.rel
00000100 31 FF FF CD 24 08 CD 00 10 C3 0D 10
00000800 FF FF FF FF FF FF FF FF 21 00 08 36 12 21 01 08 36 12 23 36 12 23 36 12 23 36 12 23 36 12 23 36
00000820 12 23 36 12 C9
00001000 3E 30 F5 33 CD 13 10 33 C9 3E 02 CF C9 3E 00 CF 76 18 FD 21 02 00 39 6E 3E 01 CF C9 6B 3E 01 CF
00001020 C9
map file
The attached map file was produced with this command line:
sdcc -mz80 --no-std-crt0 --code-loc 0x1000 --data-loc 0x0800 testcrt0.rel crt0.rel
I can reproduce the problem when using
sdcc -mz80 --no-std-crt0 --data-loc 0 testcrt0.rel crt0.rel
I cannot reproduce the problem when using
sdcc -mz80 --no-std-crt0 --data-loc 0 crt0.rel testcrt0.rel
Beware that for the latter command the output files, including .ihx and .map are named differently.
Philipp
This is probably related to or the same as bug 1540.
https://sourceforge.net/p/sdcc/bugs/1540/
Duplicate of #1540.
Philipp