public virtual void Walk() { Walk6502.Reset(); ushort addr = (ushort)((memory[0xFFFC] | (memory[0xFFFD] << 8))); // RESET vector Walk6502.Walk(this, addr); }
// Commodore 64 - walk Kernal Reset vector, MAIN, CRUNCH, GONE (EXECUTE), Statements, Functions, and Operators BASIC ROM code public override void Walk() { // in case cpu has not been reset, manually initialize low memory that will be called by BASIC and KERNAL ROM for (int i = 0; i < 0x18; ++i) { memory[(ushort)(0x73 + i)] = memory[(ushort)(0xE3A2 + i)]; // CHARGET } memory[0x300] = LO(0xE38B); // ERROR memory[0x301] = HI(0xE38B); memory[0x302] = LO(0xA483); // MAIN memory[0x303] = HI(0xA483); memory[0x304] = LO(0xA57C); // CRUNCH memory[0x305] = HI(0xA57C); memory[0x306] = LO(0xA71A); // QPLOP memory[0x307] = HI(0xA71A); memory[0x308] = LO(0xA7E4); // GONE memory[0x309] = HI(0xA7E4); memory[0x30A] = LO(0xAE86); // EVAL memory[0x30B] = HI(0xAE86); memory[0x31A] = LO(0xF34A); // OPEN memory[0x31B] = HI(0xF34A); memory[0x31C] = LO(0xF291); // CLOSE memory[0x31D] = HI(0xF291); memory[0x31E] = LO(0xF20E); // CHKIN memory[0x31F] = HI(0xF20E); memory[0x320] = LO(0xF250); // CKOUT memory[0x321] = HI(0xF250); memory[0x322] = LO(0xF333); // CHECK STOP memory[0x323] = HI(0xF333); memory[0x324] = LO(0xF157); // CHRIN memory[0x325] = HI(0xF157); memory[0x326] = LO(0xF1CA); // CHROUT memory[0x327] = HI(0xF1CA); memory[0x328] = LO(0xF6ED); // STOP memory[0x329] = HI(0xF6ED); memory[0x32A] = LO(0xF13E); // GETIN memory[0x32B] = HI(0xF13E); memory[0x32C] = LO(0xF32F); // CLALL memory[0x32D] = HI(0xF32F); memory[0x330] = LO(0xF4A5); // LOAD memory[0x331] = HI(0xF4A5); memory[0x332] = LO(0xF5ED); // SAVE memory[0x333] = HI(0xF5ED); base.Walk(); // reset seen, and walk the RESET vector ushort addr; addr = (ushort)(memory[0xFFFE] | (memory[0xFFFF] << 8)); // IRQ Walk6502.Walk(this, addr); addr = (ushort)(memory[0xFFFA] | (memory[0xFFFB] << 8)); // NMI Walk6502.Walk(this, addr); // Portion of MAIN, CRUNCH and GONE(Execute) or MAIN1(Store line) Walk6502.Walk(this, 0xA494); for (ushort table = 0xA00C; table < 0xA051; table += 2) // BASIC Statements { addr = (ushort)((memory[table] | (memory[(ushort)(table + 1)] << 8)) + 1); // put on stack for RTS, so must add one Walk6502.Walk(this, addr); } for (ushort table = 0xA052; table < 0xA07F; table += 2) // Function Dispatch { addr = (ushort)((memory[table] | (memory[(ushort)(table + 1)] << 8))); Walk6502.Walk(this, addr); } for (ushort table = 0xA080; table < 0xA09D; table += 3) // Operator Dispatch { addr = (ushort)((memory[(ushort)(table + 1)] | (memory[(ushort)(table + 2)] << 8)) + 1); // put on stack for RTS, so must add one Walk6502.Walk(this, addr); } }
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(); } }