public void Run(int instructionCount) { for (int i = 0; i < instructionCount; i++) { TestContext.Out.WriteLine($"#{i} {DebugUtils.Trace(_machine)}"); Cpu.ExecuteNextInstruction(_machine); } }
public void TestPrintProgram() { var cart = new Cartridge(); cart.LoadFromFile("../../../test_programs/print_test.rom"); var ram = new Ram(); var memoryController = new MemoryController(ram, cart); var cpu = new Cpu(memoryController); cpu.Init(); // Need to figure out halt... bool done = false; int iterations = 0; while (!done && iterations++ < 10000) { cpu.ExecuteNextInstruction(); } }
public void Step() { //if (State.Memory[0xFF50].GetBit(0)) // Bootrom disabled //{ // //var nextInstr = Disassembler.DisassembleInstruction(InstructionLookahead.Passive(State)); // //_log[State.Registers.PC.Value] = nextInstr; // //if (!_logHits.ContainsKey(State.Registers.PC.Value)) _logHits[State.Registers.PC.Value] = 0; // //_logHits[State.Registers.PC.Value]++; // _trace.WriteLine(DebugUtils.Trace(State)); // if (State.Registers.PC.Value == 0x00F0) // { // _trace.Flush(); // Environment.Exit(0); // } //} if (State.Stopped) { // STOP mode is exited when a button is pressed. // IF bit 4 is set when a button is pressed, so we can use that. if (State.Memory[0xFF0F].GetBit(4)) { State.Stopped = false; } else { return; } } if (State.Halted) { _lcdController.Tick(); _timerController.Tick(); ElapsedCycles += 1; } else { var cycles = Cpu.ExecuteNextInstruction(State); ElapsedCycles += cycles; for (var i = 0; i < cycles; i++) { _lcdController.Tick(); _timerController.Tick(); } } // Handle interrupts var firedInterrupts = (byte)(State.Memory[0xFF0F] & State.Memory[0xFFFF]); if (State.InterruptMasterEnable && firedInterrupts != 0) { // Save PC // TODO: push 16 bit values onto the stack in one call var pc = State.Registers.PC.Value; State.Stack.Push(pc.GetHigh()); State.Stack.Push(pc.GetLow()); State.InterruptMasterEnable = false; //_logger.WriteLine($"Servicing interrupt ... {State.Memory[0xFF0F].ToBinaryString()} {State.Memory[0xFFFF].ToBinaryString()} {firedInterrupts.ToBinaryString()} {ElapsedCycles - _c}"); _c = ElapsedCycles; if (firedInterrupts.GetBit(0)) // VBlank { State.Registers.PC.Value = 0x0040; State.Memory[0xFF0F] = State.Memory[0xFF0F].SetBit(0, false); } else if (firedInterrupts.GetBit(1)) // LCD status { State.Registers.PC.Value = 0x0048; State.Memory[0xFF0F] = State.Memory[0xFF0F].SetBit(1, false); } else if (firedInterrupts.GetBit(2)) // Timer { State.Registers.PC.Value = 0x0050; State.Memory[0xFF0F] = State.Memory[0xFF0F].SetBit(2, false); } else if (firedInterrupts.GetBit(3)) // Serial link { State.Registers.PC.Value = 0x0058; State.Memory[0xFF0F] = State.Memory[0xFF0F].SetBit(3, false); } else if (firedInterrupts.GetBit(4)) // Keypad press { State.Registers.PC.Value = 0x0060; State.Memory[0xFF0F] = State.Memory[0xFF0F].SetBit(4, false); } } // HALT mode is always exited regardless of the state of the IME if (firedInterrupts != 0) { State.Halted = false; } }
private void Next() { Cpu.ExecuteNextInstruction(); }