Skip to content

Commit

Permalink
kc85: initial cmdline arg parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Aug 6, 2024
1 parent 857f715 commit 729aa12
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 1 deletion.
113 changes: 113 additions & 0 deletions emus/kc85/kc85.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
const build_options = @import("build_options");
const std = @import("std");
const print = std.debug.print;
const fs = std.fs;
const GeneralPurposeAllocator = std.heap.GeneralPurposeAllocator;
const sokol = @import("sokol");
const sapp = sokol.app;
const slog = sokol.log;
Expand All @@ -19,7 +22,21 @@ const name = switch (model) {
};
const KC85 = kc85.Type(model);

// command line args
const Args = struct {
const Module = struct {
mod_type: KC85.ModuleType = .NONE,
rom_dump: ?[]const u8 = null,
};
// optional file to load (.KCC or .TAP format)
file: ?[]const u8 = null,
// modules to insert into slot 08 and 0C
slot8: Module = .{},
slotc: Module = .{},
};

var sys: KC85 = undefined;
var gpa = GeneralPurposeAllocator(.{}){};

export fn init() void {
host.audio.init(.{});
Expand Down Expand Up @@ -47,6 +64,10 @@ export fn init() void {
},
});
host.gfx.init(.{ .display = sys.displayInfo() });
const args = parseArgs(gpa.allocator()) catch {
std.process.exit(10);
};
print("args: {}\n", .{args});
}

export fn frame() void {
Expand All @@ -70,6 +91,9 @@ export fn cleanup() void {
host.gfx.shutdown();
host.prof.shutdown();
host.audio.shutdown();
if (gpa.deinit() != .ok) {
@panic("Memory leaks detected");
}
}

export fn input(ev: ?*const sapp.Event) void {
Expand Down Expand Up @@ -154,3 +178,92 @@ pub fn main() void {
.logger = .{ .func = slog.func },
});
}

fn isArg(arg: []const u8, comptime strings: []const []const u8) bool {
for (strings) |str| {
if (std.mem.eql(u8, arg, str)) {
return true;
}
}
return false;
}

fn parseArgs(alloc: std.mem.Allocator) !Args {
var args = Args{};
var arg_iter = try std.process.argsWithAllocator(alloc);
defer arg_iter.deinit();
_ = arg_iter.skip();
while (arg_iter.next()) |arg| {
if (isArg(arg, &.{ "-h", "-help", "--help" })) {
const help = .{
" -file path -- load .KCC or .TAP file",
" -slot8 name [rom dump path] -- load module into slot 08",
" -slotc name [rom dump path] -- load module into slot 0C",
"",
" Valid module names are:",
" m006 - KC85/2 BASIC ROM",
" m011 - 64 KByte RAM",
" m022 - 16 KByte RAM",
" m012 - TEXOR text processor",
" m026 - FORTH development",
" m027 - assembly development",
};
inline for (help) |s| {
print(s ++ "\n", .{});
}
} else if (isArg(arg, &.{"-file"})) {
const next = arg_iter.next() orelse {
print("Expected path to .KCC or .TAP file after '{s}'\n", .{arg});
return error.InvalidArgs;
};
args.file = try alloc.dupe(u8, next);
} else if (isArg(arg, &.{"-slot8"})) {
args.slot8 = try parseModuleArgs(alloc, arg, &arg_iter);
} else if (isArg(arg, &.{"-slotc"})) {
args.slotc = try parseModuleArgs(alloc, arg, &arg_iter);
} else {
print("Unknown argument: {s} (run '-help' to show valid args)\n", .{arg});
return error.InvalidArgs;
}
}
return args;
}

fn parseModuleArgs(alloc: std.mem.Allocator, arg: []const u8, arg_iter: *std.process.ArgIterator) !Args.Module {
var mod = Args.Module{};
const mod_name = arg_iter.next() orelse {
print("Expected module name after '{s}'\n", .{arg});
return error.InvalidArgs;
};
const mod_table = .{
.{ .name = "m006", .mod_type = .M006_BASIC, .rom = true },
.{ .name = "m011", .mod_type = .M011_64KBYTE, .rom = false },
.{ .name = "m012", .mod_type = .M012_TEXOR, .rom = true },
.{ .name = "m022", .mod_type = .M022_16KBYTE, .rom = false },
.{ .name = "m026", .mod_type = .M026_FORTH, .rom = true },
.{ .name = "m026", .mod_type = .M027_DEV, .rom = true },
};
var is_rom_module = false;
inline for (mod_table) |item| {
if (std.mem.eql(u8, mod_name, item.name)) {
mod.mod_type = item.mod_type;
is_rom_module = item.rom;
break;
}
}
if (mod.mod_type == .NONE) {
print("Invalid module name '{s} (see -help for list of valid module names)\n", .{mod_name});
return error.InvalidArgs;
}
if (is_rom_module) {
const rom_dump_path = arg_iter.next() orelse {
print("Expect ROM dump file path after '{s} {s}\n", .{ arg, mod_name });
return error.InvalidArgs;
};
mod.rom_dump = fs.cwd().readFileAlloc(alloc, rom_dump_path, 64 * 1024) catch |err| {
print("Failed to load module rom dump file '{s}'\n", .{rom_dump_path});
return err;
};
}
return mod;
}
2 changes: 1 addition & 1 deletion zig_notes.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
- Low debug performance may become a problem => investigate!
=> release=safe is fast
=> release=safe is fast => PS: not for the KC85 though!
=> inline functions are also inlined in debug mode, but still
push/pop parameters on stack

Expand Down

0 comments on commit 729aa12

Please sign in to comment.