コード例 #1
0
ファイル: NES.Core.cs プロジェクト: KuSunda/BizHawk
        public byte DB;                 //old data bus values from previous reads

        internal void RunCpuOne()
        {
            ///////////////////////////
            // OAM DMA start
            ///////////////////////////

            if (oam_dma_exec && apu.dmc_dma_countdown != 1 && !dmc_realign)
            {
                if (cpu_deadcounter == 0)
                {
                    if (oam_dma_index % 2 == 0)
                    {
                        oam_dma_byte = ReadMemory(oam_dma_addr);
                        oam_dma_addr++;
                    }
                    else
                    {
                        WriteMemory(0x2004, oam_dma_byte);
                    }
                    oam_dma_index++;
                    if (oam_dma_index == 512)
                    {
                        oam_dma_exec = false;
                    }
                }
                else
                {
                    cpu_deadcounter--;
                }
            }

            dmc_realign = false;

            /////////////////////////////
            // OAM DMA end
            /////////////////////////////


            /////////////////////////////
            // dmc dma start
            /////////////////////////////

            if (apu.dmc_dma_countdown > 0)
            {
                if (apu.dmc_dma_countdown == 1)
                {
                    dmc_realign = true;
                }

                cpu.RDY      = false;
                dmc_dma_exec = true;
                apu.dmc_dma_countdown--;
                if (apu.dmc_dma_countdown == 0)
                {
                    apu.RunDMCFetch();
                    dmc_dma_exec          = false;
                    apu.dmc_dma_countdown = -1;
                    do_the_reread         = true;
                }
            }

            /////////////////////////////
            // dmc dma end
            /////////////////////////////
            apu.RunOneFirst();

            if (cpu.RDY && !IRQ_delay)
            {
                cpu.IRQ = _irq_apu || Board.IrqSignal;
            }
            else if (special_case_delay || apu.dmc_dma_countdown == 3)
            {
                cpu.IRQ            = _irq_apu || Board.IrqSignal;
                special_case_delay = false;
            }

            cpu.ExecuteOne();
            Board.ClockCpu();

            int s = apu.EmitSample();

            if (s != old_s)
            {
                blip.AddDelta(apu.sampleclock, s - old_s);
                old_s = s;
            }
            apu.sampleclock++;

            apu.RunOneLast();

            if (do_the_reread && cpu.RDY)
            {
                do_the_reread = false;
            }

            IRQ_delay = false;

            if (!dmc_dma_exec && !oam_dma_exec && !cpu.RDY)
            {
                cpu.RDY   = true;
                IRQ_delay = true;
            }
        }
コード例 #2
0
        public byte DB;                 //old data bus values from previous reads

        internal void RunCpuOne()
        {
            ///////////////////////////
            // OAM DMA start
            ///////////////////////////

            if (oam_dma_exec && apu.dmc_dma_countdown != 1 && !dmc_realign)
            {
                if (cpu_deadcounter == 0)
                {
                    if (oam_dma_index % 2 == 0)
                    {
                        oam_dma_byte = ReadMemory(oam_dma_addr);
                        oam_dma_addr++;
                    }
                    else
                    {
                        WriteMemory(0x2004, oam_dma_byte);
                    }
                    oam_dma_index++;
                    if (oam_dma_index == 512)
                    {
                        oam_dma_exec = false;
                    }
                }
                else
                {
                    cpu_deadcounter--;
                }
            }

            dmc_realign = false;

            /////////////////////////////
            // OAM DMA end
            /////////////////////////////


            /////////////////////////////
            // dmc dma start
            /////////////////////////////

            if (apu.dmc_dma_countdown > 0)
            {
                if (apu.dmc_dma_countdown == 1)
                {
                    dmc_realign = true;
                }

                // By this point the cpu should be frozen, if it is not, then we are in a multi-write opcode, add another cycle delay
                if (!cpu.RDY && !cpu.rdy_freeze && (apu.dmc_dma_countdown == apu.DMC_RDY_check))
                {
                    //Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + apu.call_from_write + " " + cpu.opcode + " " + oam_dma_exec);
                    apu.dmc_dma_countdown += 2;
                    apu.DMC_RDY_check      = -1;
                }

                cpu.RDY      = false;
                dmc_dma_exec = true;
                apu.dmc_dma_countdown--;
                if (apu.dmc_dma_countdown == 0)
                {
                    apu.RunDMCFetch();
                    dmc_dma_exec          = false;
                    apu.dmc_dma_countdown = -1;
                    do_the_reread         = true;
                }

                //Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + apu.call_from_write + " " + cpu.opcode);
            }

            /////////////////////////////
            // dmc dma end
            /////////////////////////////
            apu.RunOneFirst();

            if (cpu.RDY && !IRQ_delay)
            {
                cpu.IRQ = _irq_apu || Board.IrqSignal;
            }
            else if (special_case_delay || apu.dmc_dma_countdown == 3)
            {
                cpu.IRQ            = _irq_apu || Board.IrqSignal;
                special_case_delay = false;
            }

            cpu.ExecuteOne();
            Board.ClockCpu();

            int s = apu.EmitSample();

            if (s != old_s)
            {
                blip.AddDelta(apu.sampleclock, s - old_s);
                old_s = s;
            }
            apu.sampleclock++;

            apu.RunOneLast();

            if (do_the_reread && cpu.RDY)
            {
                do_the_reread = false;
            }

            IRQ_delay = false;

            if (!dmc_dma_exec && !oam_dma_exec && !cpu.RDY)
            {
                cpu.RDY   = true;
                IRQ_delay = true;
            }
        }
コード例 #3
0
ファイル: NES.Core.cs プロジェクト: chronoschal/BizHawk
        public byte DB;         //old data bus values from previous reads

        internal void RunCpuOne()
        {
            ///////////////////////////
            // OAM DMA start
            ///////////////////////////

            if (oam_dma_exec && apu.dmc_dma_countdown != 1 && !dmc_realign)
            {
                if (cpu_deadcounter == 0)
                {
                    if (oam_dma_index % 2 == 0)
                    {
                        oam_dma_byte = ReadMemory(oam_dma_addr);
                        oam_dma_addr++;
                    }
                    else
                    {
                        WriteMemory(0x2004, oam_dma_byte);
                    }
                    oam_dma_index++;
                    if (oam_dma_index == 512)
                    {
                        oam_dma_exec = false;
                    }
                }
                else
                {
                    cpu_deadcounter--;
                }
            }

            dmc_realign = false;

            /////////////////////////////
            // OAM DMA end
            /////////////////////////////


            /////////////////////////////
            // dmc dma start
            /////////////////////////////

            if (apu.dmc_dma_countdown > 0)
            {
                if (apu.dmc_dma_countdown == 1 && !apu.dmc.fill_glitch)
                {
                    dmc_realign = true;
                }

                // By this point the cpu should be frozen, if it is not, then we are in a multi-write opcode, add another cycle delay
                if (!cpu.RDY && !cpu.rdy_freeze && (apu.dmc_dma_countdown == apu.DMC_RDY_check))
                {
                    //Console.WriteLine("dmc double " + cpu.TotalExecutedCycles + " " + cpu.opcode + " " + cpu.mi);
                    apu.dmc_dma_countdown += 2;
                    apu.DMC_RDY_check      = -1;
                }

                cpu.RDY      = false;
                dmc_dma_exec = true;
                apu.dmc_dma_countdown--;
                if (apu.dmc_dma_countdown == 0)
                {
                    if (!apu.dmc.fill_glitch)
                    {
                        reread_trigger = true;
                        // if the DMA address has the same bits set as the re-read address, they don't occur
                        if ((apu.dmc.sample_address & 0x2007) != 0x2002)
                        {
                            do_the_reread_2002++;
                        }

                        if ((apu.dmc.sample_address & 0x2007) != 0x2007)
                        {
                            do_the_reread_2007++;
                        }

                        if ((apu.dmc.sample_address & 0x401F) != 0x4016)
                        {
                            do_the_reread_cont_1++;
                        }

                        if ((apu.dmc.sample_address & 0x401F) != 0x4017)
                        {
                            do_the_reread_cont_2++;
                        }

                        apu.RunDMCFetch();
                    }

                    dmc_dma_exec          = false;
                    apu.dmc_dma_countdown = -1;
                    apu.dmc.fill_glitch   = false;

                    /*
                     * //if (apu.dmc.timer == (apu.dmc.timer_reload-0) && apu.dmc.out_bits_remaining == 7)
                     * //if (apu.dmc.timer == 2 && apu.dmc.out_bits_remaining == 0)
                     * {
                     *      Console.WriteLine("close " + cpu.TotalExecutedCycles + " " + apu.dmc.timer + " " + apu.dmc.sample_length);
                     *      apu.dmc.fill_glitch = true;
                     *      apu.dmc.delay = 3;
                     * }
                     */
                    //Console.WriteLine("dmc RDY false " + cpu.TotalExecutedCycles + " " + cpu.opcode + " " + cpu.mi + " " + apu.dmc.timer);
                }
            }

            /////////////////////////////
            // dmc dma end
            /////////////////////////////
            apu.RunOneFirst();

            if (cpu.RDY && !IRQ_delay)
            {
                cpu.IRQ = _irq_apu || Board.IrqSignal;
            }
            else if (special_case_delay || apu.dmc_dma_countdown == 3)
            {
                cpu.IRQ = _irq_apu || Board.IrqSignal;
                //if (cpu.IRQ) { Console.WriteLine("something IRQ"); }
                special_case_delay = false;
            }

            cpu.ExecuteOne();
            Board.ClockCpu();

            int s = apu.EmitSample();

            if (s != old_s)
            {
                blip.AddDelta(apu.sampleclock, s - old_s);
                old_s = s;
            }
            apu.sampleclock++;

            apu.RunOneLast();

            if (reread_trigger && cpu.RDY)
            {
                do_the_reread_2002   = 0;
                do_the_reread_2007   = 0;
                do_the_reread_cont_1 = 0;
                do_the_reread_cont_2 = 0;
                reread_trigger       = false;
            }


            IRQ_delay = false;

            if (!dmc_dma_exec && !oam_dma_exec && !cpu.RDY)
            {
                cpu.RDY   = true;
                IRQ_delay = true;
            }
        }