feat(cli): add assemble/disassemble commands and TUI debugger

This commit is contained in:
dualfroz committed 2026-08-27 15:55:37 +02:00
1 parent 996bcedd0b
commit e02d60002f
3 files changed
+179

No files matched your search

+68
View File
@@ -0,0 +1,68 @@
using System;
using System.IO;
using Chip8.Core;
using Chip8.Core.Assembly;
namespace Chip8.Cli;
static class AsmCommand
{
public static int run(string[] args)
{
if (args.Length < 1)
{
Console.Error.WriteLine("usage: chip8 asm <source.asm> [-o out.ch8] [--listing]");
return 1;
}
string sourcePath = args[0];
string? outputPath = null;
bool showListing = false;
for (int index = 1; index < args.Length; index++)
{
switch (args[index])
{
case "-o":
case "--out":
outputPath = args[++index];
break;
case "--listing":
showListing = true;
break;
default:
Console.Error.WriteLine($"error: unknown asm option {args[index]}");
return 1;
}
}
if (!File.Exists(sourcePath))
{
Console.Error.WriteLine($"error: source not found: {sourcePath}");
return 1;
}
string source = File.ReadAllText(sourcePath);
AssemblyResult result;
try
{
result = new Assembler().assemble(source);
}
catch (AsmException error)
{
Console.Error.WriteLine($"error: {error.Message}");
return 1;
}
outputPath ??= Path.ChangeExtension(sourcePath, ".ch8");
File.WriteAllBytes(outputPath, result.rom);
Console.WriteLine($"assembled {result.rom.Length} bytes -> {outputPath}");
if (showListing)
{
Console.Write(result.listing);
}
return 0;
}
}
+46
View File
@@ -0,0 +1,46 @@
using System;
using System.Globalization;
using System.IO;
using Chip8.Core;
namespace Chip8.Cli;
static class DisasmCommand
{
public static int run(string[] args)
{
if (args.Length < 1)
{
Console.Error.WriteLine("usage: chip8 disasm <rom.ch8> [--base 0x200]");
return 1;
}
string romPath = args[0];
ushort baseAddress = Machine.programStart;
for (int index = 1; index < args.Length; index++)
{
if (args[index] == "--base")
{
string value = args[++index];
string digits = value.StartsWith("0x", StringComparison.OrdinalIgnoreCase) ? value.Substring(2) : value;
baseAddress = ushort.Parse(digits, NumberStyles.HexNumber, CultureInfo.InvariantCulture);
}
else
{
Console.Error.WriteLine($"error: unknown disasm option {args[index]}");
return 1;
}
}
if (!File.Exists(romPath))
{
Console.Error.WriteLine($"error: ROM not found: {romPath}");
return 1;
}
byte[] rom = File.ReadAllBytes(romPath);
Console.Write(Disassembler.render(rom, baseAddress));
return 0;
}
}
+65
View File
@@ -0,0 +1,65 @@
using System;
using System.IO;
using Chip8.Core;
namespace Chip8.Cli;
static class TuiDebugger
{
public static int run(string[] args)
{
if (args.Length < 1)
{
Console.Error.WriteLine("usage: chip8 debug <rom.ch8> [--platform NAME]");
return 1;
}
var forwarded = new string[args.Length];
forwarded[0] = args[0];
Array.Copy(args, 1, forwarded, 1, args.Length - 1);
Options options;
try
{
options = Options.parse(forwarded);
}
catch (ArgumentException error)
{
Console.Error.WriteLine($"error: {error.Message}");
return 1;
}
if (!File.Exists(options.romPath))
{
Console.Error.WriteLine($"error: ROM not found: {options.romPath}");
return 1;
}
var machine = new Machine(options.buildQuirks(), options.seed, options.buildPlatform());
machine.loadRom(File.ReadAllBytes(options.romPath));
var console = new DebuggerConsole(new Debugger(machine));
Console.WriteLine($"chip8-sharp debugger - {Path.GetFileName(options.romPath)} ({options.buildPlatform()})");
Console.WriteLine("type 'help' for commands");
Console.Write(console.execute("dis 5"));
Console.WriteLine();
while (!console.quitRequested)
{
Console.Write("(chip8) ");
string? line = Console.ReadLine();
if (line is null)
{
break;
}
string output = console.execute(line);
if (output.Length > 0)
{
Console.WriteLine(output);
}
}
return 0;
}
}