You've already forked pac-man-emulator
mirror of
https://github.com/izzy2lost/pac-man-emulator.git
synced 2026-03-10 12:38:25 -07:00
• Add emulator.cli project targeting netcoreapp3.1 • Switch emulator to be a library • Target netstandard2.0 for emulator, cli, disassembler projects (2.1 is too high for UAP 10.0.18362.0) • Fix netcoreapp3.1 -> netstandard2.0 compilation errors
130 lines
5.7 KiB
C#
130 lines
5.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using Microsoft.Extensions.CommandLineUtils;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace JustinCredible.PacEmu.CLI
|
|
{
|
|
/**
|
|
* The main entry point into the desktop version of the emulator which handles
|
|
* parsing CLI arguments and passing them to the emulator library.
|
|
*/
|
|
public class Program
|
|
{
|
|
private static CommandLineApplication _app;
|
|
|
|
private static string AppVersion
|
|
{
|
|
get
|
|
{
|
|
return Assembly.GetEntryAssembly().GetCustomAttribute<AssemblyInformationalVersionAttribute>().InformationalVersion;
|
|
}
|
|
}
|
|
|
|
public static void Main(string[] args)
|
|
{
|
|
var version = Program.AppVersion;
|
|
|
|
_app = new CommandLineApplication();
|
|
_app.Name = "pacemu";
|
|
_app.Description = "Pac-Man Arcade Hardware Emulator";
|
|
_app.HelpOption("-?|-h|--help");
|
|
|
|
_app.VersionOption("-v|--version",
|
|
|
|
// Used for HelpOption() header
|
|
$"{_app.Name} {version}",
|
|
|
|
// Used for output of --version option.
|
|
version
|
|
);
|
|
|
|
// When launched without any commands or options.
|
|
_app.OnExecute(() =>
|
|
{
|
|
_app.ShowHelp();
|
|
return 0;
|
|
});
|
|
|
|
_app.Command("run", Run);
|
|
|
|
_app.Execute(args);
|
|
}
|
|
|
|
private static void Run(CommandLineApplication command)
|
|
{
|
|
command.Description = "Runs the emulator using the given ROM files.";
|
|
command.HelpOption("-?|-h|--help");
|
|
|
|
var romPathArg = command.Argument("[ROM path]", "The path to a directory containing the ROM set to load.");
|
|
|
|
var romsetOption = command.Option("-rs|--rom-set", "The name of an alternative ROM set and/or PCB configuration to use; pacman or mspacman; defaults to pacman", CommandOptionType.SingleValue);
|
|
var dipSwitchesOption = command.Option("-dw|--dip-switches", "The path to a JSON file containing DIP switch settings; defaults to dip-switches.json in CWD.", CommandOptionType.SingleValue);
|
|
var loadStateOption = command.Option("-l|--load-state", "Loads an emulator save state from the given path.", CommandOptionType.SingleValue);
|
|
var skipChecksumsOption = command.Option("-sc|--skip-checksums", "Allow running a ROM with invalid checksums.", CommandOptionType.NoValue);
|
|
var writableRomOption = command.Option("-wr|--writable-rom", "Allow memory writes to the ROM address space.", CommandOptionType.NoValue);
|
|
var debugOption = command.Option("-d|--debug", "Run in debug mode; enables internal statistics and logs useful when debugging.", CommandOptionType.NoValue);
|
|
var breakOption = command.Option("-b|--break", "Used with debug, will break at the given address and allow single stepping opcode execution (e.g. --break 0x0248)", CommandOptionType.MultipleValue);
|
|
var reverseStepOption = command.Option("-rvs|--reverse-step", "Used with debug, allows for single stepping in reverse to rewind opcode execution.", CommandOptionType.NoValue);
|
|
var annotationsPathOption = command.Option("-a|--annotations", "Used with debug, a path to a text file containing memory address annotations for interactive debugging (line format: 0x1234 .... ; Annotation)", CommandOptionType.SingleValue);
|
|
|
|
command.OnExecute(() =>
|
|
{
|
|
var config = new EmulatorConfig();
|
|
|
|
if (String.IsNullOrWhiteSpace(romPathArg.Value))
|
|
throw new Exception("A directory containing Pac-Man arcade hardware compatible ROM files is required.");
|
|
|
|
if (!Directory.Exists(romPathArg.Value))
|
|
throw new Exception($"Could not locate a directory at path {romPathArg.Value}");
|
|
|
|
config.RomPath = romPathArg.Value;
|
|
config.RomSet = ROMSet.PacMan;
|
|
|
|
if (romsetOption.HasValue())
|
|
{
|
|
if (romsetOption.Value() == "pacman")
|
|
config.RomSet = ROMSet.PacMan;
|
|
else if (romsetOption.Value() == "mspacman")
|
|
config.RomSet = ROMSet.MsPacMan;
|
|
else
|
|
throw new ArgumentException($"Unexpected ROM set: {romsetOption.Value()}");
|
|
}
|
|
|
|
config.DipSwitchesConfigPath = dipSwitchesOption.HasValue() ? dipSwitchesOption.Value() : null;
|
|
config.LoadStateFilePath = loadStateOption.HasValue() ? loadStateOption.Value() : null;
|
|
config.SkipChecksums = skipChecksumsOption.HasValue();
|
|
config.WritableRom = writableRomOption.HasValue();
|
|
config.Debug = debugOption.HasValue();
|
|
|
|
if (config.Debug)
|
|
{
|
|
if (breakOption.HasValue())
|
|
{
|
|
var addresses = new List<UInt16>();
|
|
|
|
foreach (var addressString in breakOption.Values)
|
|
{
|
|
UInt16 address = Convert.ToUInt16(addressString, 16);
|
|
addresses.Add(address);
|
|
}
|
|
|
|
config.Breakpoints = addresses;
|
|
}
|
|
|
|
config.ReverseStep = reverseStepOption.HasValue();
|
|
config.AnnotationsFilePath = annotationsPathOption.HasValue() ? annotationsPathOption.Value() : null;
|
|
}
|
|
|
|
Emulator.Start(config);
|
|
|
|
return 0;
|
|
});
|
|
}
|
|
}
|
|
}
|