public static void Walk(Emu6502 cpu, ushort addr) { bool conditional; byte bytes; ushort addr2; HashSet <ushort> branches = new HashSet <ushort>(); while (true) { if (seen.Contains(addr)) { while (true) { if (branches.Count == 0) { return; // done with walk } else { addr = branches.First(); // walk a saved address branches.Remove(addr); if (!seen.Contains(addr)) { break; } } } } string line; string dis = cpu.Disassemble(addr, out conditional, out bytes, out addr2, out line); Console.WriteLine(line); if (dis != "???") { seen.Add(addr); } switch (dis) { case "BRK": case "RTI": case "RTS": case "???": if (branches.Count == 0) { return; // done with walk } else { addr = branches.First(); // walk a saved address branches.Remove(addr); break; } default: if (!conditional && addr2 != 0) { if (dis.StartsWith("JSR")) { Walk(cpu, addr2); // walk call recursively, then continue next address addr += bytes; } else { addr = addr2; } } else { addr += bytes; if (conditional && !seen.Contains(addr2) && !branches.Contains(addr2)) { branches.Add(addr2); // save branch address for later } } break; } } }
static void Main(string[] args) { // recommend get basic, kernal, etc. ROM files from a emulator such as https://vice-emu.sourceforge.io/index.html#download Emu6502 cbm = null; bool error = false; int ram_size = 0; Console.Error.WriteLine("6502 Emulator for Windows Console"); Console.Error.WriteLine("C64, VIC-20, PET, TED, ..."); Console.Error.WriteLine(""); Console.Error.WriteLine("simple-emu-c64 version 1.7"); Console.Error.WriteLine("Copyright (c) 2020 David R. Van Wagner"); Console.Error.WriteLine("davevw.com"); Console.Error.WriteLine("Open Source, MIT License"); Console.Error.WriteLine("github.com/davervw/simple-emu-c64"); Console.Error.WriteLine(""); try { if (args.Length > 2 && args[1].ToLower() == "ram") { ram_size = int.Parse(args[2]) * 1024; } if (args.Length == 0 || args[0].ToLower() == "c64") { if (ram_size == 0) { ram_size = 64 * 1024; } if (File.Exists("basic") && File.Exists("kernal") && (!File.Exists("c64\\basic") || !File.Exists("c64\\kernal"))) { cbm = new EmuC64(ram_size: ram_size, basic_file: "basic", chargen_file: "c64\\chargen", kernal_file: "kernal"); } else { cbm = new EmuC64(ram_size: ram_size, basic_file: "c64\\basic", chargen_file: "c64\\chargen", kernal_file: "c64\\kernal"); } if ((args.Length == 2 || args.Length == 4) && (File.Exists(args[args.Length - 1]) || File.Exists(args[args.Length - 1] + ".prg"))) { ((EmuC64)cbm).StartupPRG = args[args.Length - 1]; } } else if (args.Length > 0 && args[0].ToLower() == "vic20") { cbm = new EmuVIC20(ram_size: ram_size, char_file: "vic20\\chargen", basic_file: "vic20\\basic", kernal_file: "vic20\\kernal"); } else if (args.Length > 0 && args[0].ToLower() == "c16") { if (ram_size == 0) { ram_size = 16 * 1024; } cbm = new EmuTED(ram_size: ram_size, basic_file: "ted\\basic", kernal_file: "ted\\kernal"); } else if (args.Length > 0 && args[0].ToLower() == "plus4" || args[0].ToLower() == "ted") { if (ram_size == 0) { ram_size = 64 * 1024; } cbm = new EmuTED(ram_size: ram_size, basic_file: "ted\\basic", kernal_file: "ted\\kernal"); } else if (args.Length > 0 && args[0].ToLower() == "pet") { if (ram_size == 0) { ram_size = 8 * 1024; } cbm = new EmuPET(ram_size: ram_size, basic_file: "pet\\basic1", edit_file: "pet\\edit1g", kernal_file: "pet\\kernal1"); } else { error = true; } } catch (Exception ex) { Console.Error.WriteLine(ex.ToString()); error = true; } if (error) { return; } else if (args.Length == 0) // if no arguments present, then show usage as well { Console.Error.WriteLine(""); Console.Error.WriteLine("Usage:"); Console.Error.WriteLine(" simple-emu-c64 (no arguments pauses, then starts c64)"); Console.Error.WriteLine(" simple-emu-c64 help (shows usage)"); Console.Error.WriteLine(" simple-emu-c64 [system] {ram #} (system=[c64|vic20|pet|c16|plus4|ted])"); Console.Error.WriteLine(" simple-emu-c64 [system] walk [addr 1 ...]"); Console.Error.WriteLine(""); Console.WriteLine(); } if (args.Length >= 2 && args[1].ToLower() == "walk") { if (args.Length == 2) { cbm.Walk(); } else { Walk6502.Reset(); for (int i = 2; i < args.Length; ++i) { Walk6502.Walk(cbm, ParseAddr(args[i])); } } } else { cbm.ResetRun(); } }