@@ -133,6 +133,10 @@ pub fn build(b: *std.Build) void {
133133 const atari8_target = b .resolveTargetQuery (.{ .cpu_arch = .mos , .os_tag = .atari8 });
134134 const atari8_gtia_mod = atari8GtiaHeaderMod (b , sdk_dep , atari8_target , optimize );
135135
136+ // Translated PCE headers for PC Engine.
137+ const pce_target = b .resolveTargetQuery (.{ .cpu_arch = .mos , .os_tag = .pce });
138+ const pce_mod = pceHeaderMod (b , sdk_dep , pce_target , optimize );
139+
136140 // Host tool: converts MOS ELF symbol tables to Mesen label files (.mlb).
137141 const elf2mlb = b .addExecutable (.{
138142 .name = "elf2mlb" ,
@@ -564,6 +568,7 @@ pub fn build(b: *std.Build) void {
564568 {
565569 const step = b .step ("pce-color-cycle" , "Build PC Engine color-cycle example" );
566570 const exe = addPceExe (b , sdk_dep , sdk_src , sdk_libs .pce orelse @panic ("pce libs not built" ), optimize , "pce-color-cycle" , "pce/color-cycle/color-cycle.zig" );
571+ exe .root_module .addImport ("pce" , pce_mod );
567572 const install = b .addInstallArtifact (exe , .{ .dest_sub_path = "pce-color-cycle.pce" });
568573 step .dependOn (& install .step );
569574 b .getInstallStep ().dependOn (& install .step );
@@ -574,6 +579,7 @@ pub fn build(b: *std.Build) void {
574579 {
575580 const step = b .step ("pce-color-cycle-banked" , "Build PC Engine banked color-cycle example" );
576581 const exe = addPceExe (b , sdk_dep , sdk_src , sdk_libs .pce orelse @panic ("pce libs not built" ), optimize , "pce-color-cycle-banked" , "pce/color-cycle-banked/color-cycle-banked.zig" );
582+ exe .root_module .addImport ("pce" , pce_mod );
577583 const install = b .addInstallArtifact (exe , .{ .dest_sub_path = "pce-color-cycle-banked.pce" });
578584 step .dependOn (& install .step );
579585 b .getInstallStep ().dependOn (& install .step );
@@ -836,6 +842,24 @@ pub fn build(b: *std.Build) void {
836842 }
837843}
838844
845+ fn pceHeaderMod (
846+ b : * std.Build ,
847+ sdk_dep : * std.Build.Dependency ,
848+ target : std.Build.ResolvedTarget ,
849+ opt : std.builtin.OptimizeMode ,
850+ ) * std.Build.Module {
851+ const tc = b .addTranslateC (.{
852+ .root_source_file = b .path ("pce/pce.h" ),
853+ .target = target ,
854+ .optimize = opt ,
855+ .link_libc = false ,
856+ });
857+ tc .addIncludePath (sdk_dep .path ("mos-platform/pce-common/libpce/include" ));
858+ tc .addIncludePath (sdk_dep .path ("mos-platform/pce-common" ));
859+ tc .addIncludePath (sdk_dep .path ("mos-platform/common/include" ));
860+ return tc .createModule ();
861+ }
862+
839863fn atari2600HeaderMod (
840864 b : * std.Build ,
841865 sdk_dep : * std.Build.Dependency ,
@@ -1643,6 +1667,11 @@ fn addPceExe(
16431667 });
16441668 exe .bundle_compiler_rt = false ;
16451669 exe .lto = .full ;
1670+ // LTO DCE eliminates mosCallMainSection (in .call_main) because the
1671+ // linker KEEP() reference runs after LTO. Force both symbols to keep
1672+ // the .call_main JSR and the main() function itself.
1673+ exe .forceUndefinedSymbol ("__zig_call_main_section" );
1674+ exe .forceUndefinedSymbol ("main" );
16461675 exe .root_module .addCSourceFile (.{
16471676 .file = sdk_dep .path ("mos-platform/pce/crt0/crt0.S" ),
16481677 });
@@ -1653,6 +1682,7 @@ fn addPceExe(
16531682 exe .root_module .linkLibrary (libs .crt );
16541683 exe .root_module .linkLibrary (libs .crt0 );
16551684 exe .root_module .linkLibrary (libs .c );
1685+ if (libs .crt0_obj ) | obj | exe .root_module .addObject (obj );
16561686 exe .setLinkerScript (wrapper_ld );
16571687 exe .root_module .addImport ("mos_panic" , b .createModule (.{
16581688 .root_source_file = b .path ("sdk/panic.zig" ),
0 commit comments