Achso. Da dein code ab main() die Initialisierung überschrieben hat, wird er natürlich direkt ausgeführt. Steht delay() davor, läuft die CPU beim Start direkt da rein, macht eine kurze Pause und dann ein ret. Und das führt mangels irgendeiner Adresse auf dem Stack ins Nirwana.
Ich hätte eigentlich erwartet, dass ein gescheiter Linker wenigstens eine Warnung ausgibt, wenn sich Code-Segmente überlappen. Mein z88dk macht das auch, obwohl es sdcc "unter der Haube" hat.