there is an order of areas defined in crt0.s:
;; Ordering of segments for the linker
;; Code that really needs to be in bank 0
.area _HOME
;; Similar to _HOME
.area _BASE
;; Code
.area _CODE
;; Constant data
.area _LIT
;; Constant data used to init _DATA
.area _GSINIT
.area _GSINITTAIL
.area _GSFINAL
;; Initialised in ram data
.area _DATA
;; Uninitialised ram data
.area _BSS
;; For malloc
.area _HEAP
.area _BSS
if you don't pass base address of _CODE into the linker - that result into broken rom, because it's base address assigned to 0 and header gets overwritten.
but when you set base address of _CODE with linker commandline to 0x0200, that produces valid ROM, but results in inserting _CODE section before _HOME and _BASE. that is wrong, because _HOME contains ISRs, trampolines for banked calls, etc, and, depending on the size of the _CODE, that might result into pushing critical code out of bank 0. base address of _CODE should be calculated the same way as _BASE and _HOME. (actually, assigning _CODE base address in the linker should be simply removed).
ps: SDCC itself, when calling the linker also passes base address for _CODE in SDCCmain.c:
and in z80/main.c:
it should not do that.
Last edit: Tony Pavlov 2020-09-10