feat(cli): add assemble/disassemble commands and TUI debugger
This commit is contained in:
1 parent
996bcedd0b
commit
e02d60002f
3 files changed
+179
No files matched your search
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user