Пример #1
0
        public void Run(int instructionCount)
        {
            for (int i = 0; i < instructionCount; i++)
            {
                TestContext.Out.WriteLine($"#{i} {DebugUtils.Trace(_machine)}");

                Cpu.ExecuteNextInstruction(_machine);
            }
        }
Пример #2
0
        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();
            }
        }
Пример #3
0
        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;
            }
        }
Пример #4
0
 private void Next()
 {
     Cpu.ExecuteNextInstruction();
 }