@@ -23,6 +23,7 @@ const SdkLibs = struct {
2323 a2600_3e : ? sdk_mod.Libs = null ,
2424 a8cart : ? sdk_mod.Libs = null ,
2525 snes : ? sdk_mod.Libs = null ,
26+ geos_cbm : ? sdk_mod.Libs = null ,
2627};
2728
2829pub fn build (b : * std.Build ) void {
@@ -64,6 +65,7 @@ pub fn build(b: *std.Build) void {
6465 .{ .name = "atari2600-3e" , .query = .{ .cpu_arch = .mos , .os_tag = .atari2600 } },
6566 .{ .name = "atari8-cart-std" , .query = .{ .cpu_arch = .mos , .os_tag = .atari8 } },
6667 .{ .name = "snes" , .query = .{ .cpu_arch = .mos , .os_tag = .snes } },
68+ .{ .name = "geos-cbm" , .query = .{ .cpu_arch = .mos , .os_tag = .geos_cbm } },
6769 }) | pd | {
6870 const libs = sdk_mod .buildPlatform (b , sdk_src_raw , pd , optimize );
6971 const dest = b .fmt ("mos-platform/{s}/lib" , .{pd .name });
@@ -93,6 +95,7 @@ pub fn build(b: *std.Build) void {
9395 if (std .mem .eql (u8 , pd .name , "atari2600-3e" )) sdk_libs .a2600_3e = libs ;
9496 if (std .mem .eql (u8 , pd .name , "atari8-cart-std" )) sdk_libs .a8cart = libs ;
9597 if (std .mem .eql (u8 , pd .name , "snes" )) sdk_libs .snes = libs ;
98+ if (std .mem .eql (u8 , pd .name , "geos-cbm" )) sdk_libs .geos_cbm = libs ;
9699 }
97100
98101 // Translate neslib.h and nesdoug.h from the MOS SDK into Zig modules.
@@ -434,6 +437,16 @@ pub fn build(b: *std.Build) void {
434437 run_bininfo .addFileArg (exe .getEmittedBin ());
435438 }
436439
440+ // ---- GEOS CBM hello ----
441+ {
442+ const step = b .step ("geos-hello" , "Build GEOS CBM hello example" );
443+ const exe = addGeosExe (b , sdk_src , sdk_dep , sdk_libs .geos_cbm orelse @panic ("geos-cbm libs not built" ), optimize , "geos-hello" , "geos/hello/hello.zig" );
444+ const install = b .addInstallArtifact (exe , .{ .dest_sub_path = "geos-hello.cvt" });
445+ step .dependOn (& install .step );
446+ b .getInstallStep ().dependOn (& install .step );
447+ run_bininfo .addFileArg (exe .getEmittedBin ());
448+ }
449+
437450 // ---- MEGA65 (mega65-libc fetched automatically via build.zig.zon) ----
438451 if (b .lazyDependency ("mega65-libc" , .{})) | m65_dep | {
439452 {
@@ -2039,6 +2052,84 @@ fn simIoHeaderMod(
20392052 return tc .createModule ();
20402053}
20412054
2055+ fn geosHeaderMod (
2056+ b : * std.Build ,
2057+ sdk_dep : * std.Build.Dependency ,
2058+ target : std.Build.ResolvedTarget ,
2059+ opt : std.builtin.OptimizeMode ,
2060+ ) * std.Build.Module {
2061+ const tc = b .addTranslateC (.{
2062+ // geos_zig.h suppresses _Static_assert (struct-size checks fail during translation)
2063+ .root_source_file = b .path ("geos/geos_zig.h" ),
2064+ .target = target ,
2065+ .optimize = opt ,
2066+ .link_libc = false ,
2067+ });
2068+ tc .addIncludePath (sdk_dep .path ("mos-platform/geos-cbm" ));
2069+ tc .addIncludePath (sdk_dep .path ("mos-platform/common/include" ));
2070+ return tc .createModule ();
2071+ }
2072+
2073+ fn addGeosExe (
2074+ b : * std.Build ,
2075+ sdk_src : []const u8 ,
2076+ sdk_dep : * std.Build.Dependency ,
2077+ libs : sdk_mod.Libs ,
2078+ opt : std.builtin.OptimizeMode ,
2079+ name : []const u8 ,
2080+ root_src : []const u8 ,
2081+ ) * std.Build.Step.Compile {
2082+ const target = b .resolveTargetQuery (.{ .cpu_arch = .mos , .os_tag = .geos_cbm });
2083+
2084+ const wf = b .addWriteFiles ();
2085+ const libc_txt = wf .add ("libc.txt" , b .fmt (
2086+ "include_dir={s}/mos-platform/geos-cbm\n " ++
2087+ "sys_include_dir={s}/mos-platform/common/include\n " ++
2088+ "crt_dir={s}/mos-platform/geos-cbm\n " ++
2089+ "msvc_lib_dir=\n kernel32_lib_dir=\n gcc_dir=\n " ,
2090+ .{ sdk_src , sdk_src , sdk_src },
2091+ ));
2092+ // vlir.ld is the GEOS VLIR linker script (produces .cvt binary via OUTPUT_FORMAT FULL blocks).
2093+ // It includes c.ld (common sections) and geos.ld (GEOS symbol table) via INCLUDE directives,
2094+ // both resolved through the SEARCH_DIRs below.
2095+ const wrapper_ld = wf .add ("geos-cbm-wrapper.ld" , b .fmt (
2096+ \\SEARCH_DIR("{s}/mos-platform/geos-cbm");
2097+ \\SEARCH_DIR("{s}/mos-platform/common/ldscripts");
2098+ \\INCLUDE "vlir.ld"
2099+ , .{ sdk_src , sdk_src }));
2100+
2101+ const exe = b .addExecutable (.{
2102+ .name = name ,
2103+ .root_module = b .createModule (.{
2104+ .root_source_file = b .path (root_src ),
2105+ .target = target ,
2106+ .optimize = opt ,
2107+ .sanitize_c = .off ,
2108+ }),
2109+ });
2110+ exe .bundle_compiler_rt = false ;
2111+ exe .lto = .full ;
2112+ exe .forceUndefinedSymbol ("__zig_call_main_section" );
2113+ exe .forceUndefinedSymbol ("main" );
2114+ if (libs .crt0_obj ) | obj | exe .root_module .addObject (obj );
2115+ exe .root_module .linkLibrary (libs .crt );
2116+ exe .root_module .linkLibrary (libs .crt0 );
2117+ exe .root_module .linkLibrary (libs .c );
2118+ if (libs .mem ) | mem_obj | exe .root_module .addObject (mem_obj );
2119+ exe .setLibCFile (libc_txt );
2120+ exe .root_module .link_libc = true ;
2121+ exe .setLinkerScript (wrapper_ld );
2122+ exe .root_module .addImport ("mos_panic" , b .createModule (.{
2123+ .root_source_file = b .path ("sdk/panic.zig" ),
2124+ .target = target ,
2125+ .optimize = opt ,
2126+ .sanitize_c = .off ,
2127+ }));
2128+ exe .root_module .addImport ("geos" , geosHeaderMod (b , sdk_dep , target , opt ));
2129+
2130+ return exe ;
2131+ }
2132+
20422133fn addApple2Exe (
20432134 b : * std.Build ,
20442135 sdk_src : []const u8 ,
0 commit comments