@@ -49,8 +49,7 @@ pub fn build(b: *std.Build) void {
4949 break :blk buf ;
5050 };
5151
52- const optimize = b .option (std .builtin .OptimizeMode , "optimize" , "Optimize mode for target platform executables (default: ReleaseFast)" ) orelse .ReleaseFast ;
53-
52+ const optimize = b .standardOptimizeOption (.{});
5453 // ---- SDK build from source (llvm-mos-sdk git) ----
5554 const sdk_step = b .step ("sdk-build" , "Build llvm-mos-sdk platform libraries from source" );
5655
@@ -476,6 +475,21 @@ pub fn build(b: *std.Build) void {
476475 addNesLabels (b , elf2mlb , gen_labels , exe , "gg-demo" );
477476 }
478477
478+ // ---- NES full-game ----
479+ {
480+ const step = b .step ("nes-full-game" , "Build NES full game (CH26 port: scrolling platformer, coins, enemies, 3 levels)" );
481+ const exe = addNesExe (b , sdk_dep , sdk_src , sdk_libs , optimize , "full-game" , "nes/nesdoug/full-game/full_game.zig" , .{ .chr_src = "nes/nesdoug/full-game/full_game.chr" , .with_nesdoug = true , .with_famitone2 = true });
482+ exe .root_module .addImport ("neslib" , neslib_mod );
483+ exe .root_module .addImport ("nesdoug" , nesdoug_mod );
484+ exe .root_module .addIncludePath (b .path ("nes/nesdoug/mmc3" ));
485+ exe .root_module .addAssemblyFile (b .path ("nes/nesdoug/full-game/music.s" ));
486+ const install = b .addInstallArtifact (exe , .{ .dest_sub_path = "full-game.nes" });
487+ step .dependOn (& install .step );
488+ b .getInstallStep ().dependOn (& install .step );
489+ run_bininfo .addFileArg (exe .getEmittedBin ());
490+ addNesLabels (b , elf2mlb , gen_labels , exe , "full-game" );
491+ }
492+
479493 // ---- C64 hello ----
480494 {
481495 const step = b .step ("c64-hello" , "Build C64 hello example" );
@@ -842,6 +856,41 @@ pub fn build(b: *std.Build) void {
842856 run_bininfo .addFileArg (exe .getEmittedBin ());
843857 }
844858
859+ // ---- NES MMC3 nesdoug demo (banked_call, IRQ splits, FamiTone2, WRAM) ----
860+ {
861+ const step = b .step ("nes-nesdoug-mmc3" , "Build NES MMC3 nesdoug demo (banked_call, IRQ splits, FamiTone2 music, WRAM)" );
862+ const exe = addNesExe (b , sdk_dep , sdk_src , sdk_libs , optimize , "nesdoug-mmc3" , "nes/nesdoug/mmc3/mmc3.zig" , .{
863+ .mapper = .mmc3 ,
864+ .with_nesdoug = true ,
865+ .with_famitone2 = true ,
866+ .chr_rom_kb = 16 , // Alpha.chr (8KB) + Gears.chr (8KB)
867+ });
868+ // CHR ROM: both .chr files in a single .chr_rom section.
869+ const chr_wf = b .addWriteFiles ();
870+ const root_fwd_mmc3 : []const u8 = blk : {
871+ const p = b .build_root .path orelse "." ;
872+ const buf = b .allocator .dupe (u8 , p ) catch @panic ("OOM" );
873+ std .mem .replaceScalar (u8 , buf , '\\ ' , '/' );
874+ break :blk buf ;
875+ };
876+ const chr_asm = chr_wf .add ("chr-rom-mmc3.s" , b .fmt (
877+ \\.section .chr_rom,"a",@progbits
878+ \\.incbin "{s}/nes/nesdoug/mmc3/Alpha.chr"
879+ \\.incbin "{s}/nes/nesdoug/mmc3/Gears.chr"
880+ , .{ root_fwd_mmc3 , root_fwd_mmc3 }));
881+ exe .root_module .addAssemblyFile (chr_asm );
882+ // Music and sound-effect data in PRG ROM bank 12.
883+ exe .root_module .addIncludePath (b .path ("nes/nesdoug/mmc3" ));
884+ exe .root_module .addAssemblyFile (b .path ("nes/nesdoug/mmc3/music.s" ));
885+ exe .root_module .addImport ("neslib" , neslib_mod );
886+ exe .root_module .addImport ("nesdoug" , nesdoug_mod );
887+ exe .root_module .addImport ("mapper" , nes_mmc3_mapper_mod );
888+ const install = b .addInstallArtifact (exe , .{ .dest_sub_path = "nesdoug-mmc3.nes" });
889+ step .dependOn (& install .step );
890+ b .getInstallStep ().dependOn (& install .step );
891+ run_bininfo .addFileArg (exe .getEmittedBin ());
892+ }
893+
845894 // ---- NES GTROM colour-cycle with LED ----
846895 {
847896 const step = b .step ("nes-gtrom-color-cycle" , "Build NES GTROM mapper colour-cycle with LED example" );
@@ -1190,7 +1239,9 @@ fn addNesExe(
11901239 mapper : NesMapper = .nrom ,
11911240 chr_src : ? []const u8 = null ,
11921241 chr_srcs : ? []const []const u8 = null ,
1242+ chr_rom_kb : usize = 0 ,
11931243 with_nesdoug : bool = false ,
1244+ with_famitone2 : bool = false ,
11941245 },
11951246) * std.Build.Step.Compile {
11961247 const target = b .resolveTargetQuery (.{ .cpu_arch = .mos , .os_tag = .nes });
@@ -1299,17 +1350,21 @@ fn addNesExe(
12991350 \\__chr_ram_size = 8;
13001351 \\INCLUDE "{s}/mos-platform/nes-mmc1/link.ld"
13011352 , .{ reset_dir , sdk_src , sdk_src , sdk_src , sdk_src , sdk_src })),
1302- .mmc3 = > wf .add (ld_name , b .fmt (
1303- \\SEARCH_DIR("{s}");
1304- \\SEARCH_DIR("{s}/mos-platform/nes-mmc3");
1305- \\SEARCH_DIR("{s}/mos-platform/nes");
1306- \\SEARCH_DIR("{s}/mos-platform/nes/rompoke");
1307- \\SEARCH_DIR("{s}/mos-platform/common/ldscripts");
1308- \\/* MMC3 hello uses CHR RAM; override the 256 KiB CHR ROM weak default. */
1309- \\__chr_rom_size = 0;
1310- \\__chr_ram_size = 8;
1311- \\INCLUDE "{s}/mos-platform/nes-mmc3/link.ld"
1312- , .{ reset_dir , sdk_src , sdk_src , sdk_src , sdk_src , sdk_src })),
1353+ .mmc3 = > blk : {
1354+ const chr_cfg = if (cfg .chr_rom_kb > 0 )
1355+ b .fmt ("__chr_rom_size = {d};\n __chr_ram_size = 0;" , .{cfg .chr_rom_kb })
1356+ else
1357+ "/* MMC3 uses CHR RAM; override the 256 KiB CHR ROM weak default. */\n __chr_rom_size = 0;\n __chr_ram_size = 8;" ;
1358+ break :blk wf .add (ld_name , b .fmt (
1359+ \\SEARCH_DIR("{s}");
1360+ \\SEARCH_DIR("{s}/mos-platform/nes-mmc3");
1361+ \\SEARCH_DIR("{s}/mos-platform/nes");
1362+ \\SEARCH_DIR("{s}/mos-platform/nes/rompoke");
1363+ \\SEARCH_DIR("{s}/mos-platform/common/ldscripts");
1364+ \\{s}
1365+ \\INCLUDE "{s}/mos-platform/nes-mmc3/link.ld"
1366+ , .{ reset_dir , sdk_src , sdk_src , sdk_src , sdk_src , chr_cfg , sdk_src }));
1367+ },
13131368 .gtrom = > wf .add (ld_name , b .fmt (
13141369 \\SEARCH_DIR("{s}");
13151370 \\SEARCH_DIR("{s}/mos-platform/nes-gtrom");
@@ -1387,6 +1442,7 @@ fn addNesExe(
13871442 exe .root_module .linkLibrary (libs .c );
13881443 if (libs .neslib ) | neslib | exe .root_module .linkLibrary (neslib );
13891444 if (cfg .with_nesdoug ) if (libs .nesdoug ) | nd | exe .root_module .linkLibrary (nd );
1445+ if (cfg .with_famitone2 ) if (libs .famitone2 ) | ft2 | exe .root_module .linkLibrary (ft2 );
13901446 if (libs .nes_c ) | nc | exe .root_module .linkLibrary (nc );
13911447 if (libs .nes_c_startup ) | ncs | exe .root_module .linkLibrary (ncs );
13921448 exe .setLinkerScript (wrapper_ld );
@@ -2283,6 +2339,7 @@ fn addEaterExe(
22832339 exe .root_module .linkLibrary (libs .crt0 );
22842340 exe .root_module .linkLibrary (libs .c );
22852341 if (libs .crt0_obj ) | obj | exe .root_module .addObject (obj );
2342+ if (libs .mem ) | mem_obj | exe .root_module .addObject (mem_obj );
22862343 exe .forceUndefinedSymbol ("__zig_call_main_section" );
22872344 exe .forceUndefinedSymbol ("main" );
22882345 exe .setLinkerScript (wrapper_ld );
0 commit comments