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