Beispiel #1
0
        internal void RunCpuOne()
        {
            cpu_stepcounter++;
            if (cpu_stepcounter == cpu_sequence[cpu_step])
            {
                cpu_step++;
                if (cpu_step == 5)
                {
                    cpu_step = 0;
                }
                cpu_stepcounter = 0;

                if (sprdma_countdown > 0)
                {
                    sprdma_countdown--;
                    if (sprdma_countdown == 0)
                    {
                        //its weird that this is 514.. normally itd be 512 (and people would say its wrong) or 513 (and people would say its right)
                        //but 514 passes test 4-irq_and_dma
                        // according to nesdev wiki, http://wiki.nesdev.com/w/index.php/PPU_OAM this is 513 on even cycles and 514 on odd cycles
                        // TODO: Implement that
                        cpu_deadcounter += 514;
                    }
                }

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

                    if (apu.dmc_dma_countdown == 0)
                    {
                        apu.dmc_dma_countdown = -1;
                    }
                }

                if (cpu_deadcounter > 0)
                {
                    cpu_deadcounter--;
                }
                else
                {
                    cpu.IRQ = _irq_apu || Board.IRQSignal;
                    cpu.ExecuteOne();
                }

                ppu.ppu_open_bus_decay(0);
                apu.RunOne();
                Board.ClockCPU();
                ppu.PostCpuInstructionOne();
            }
        }
Beispiel #2
0
        internal void RunCpuOne()
        {
            cpu_stepcounter++;
            if (cpu_stepcounter == cpu_sequence[cpu_step])
            {
                cpu_step++;
                if (cpu_step == 5)
                {
                    cpu_step = 0;
                }
                cpu_stepcounter = 0;

                ///////////////////////////
                // OAM DMA start
                ///////////////////////////

                if (sprdma_countdown > 0)
                {
                    sprdma_countdown--;
                    if (sprdma_countdown == 0)
                    {
                        if (cpu.TotalExecutedCycles % 2 == 0)
                        {
                            cpu_deadcounter = 2;
                        }
                        else
                        {
                            cpu_deadcounter = 1;
                        }
                        oam_dma_exec       = true;
                        cpu.RDY            = false;
                        oam_dma_index      = 0;
                        special_case_delay = true;
                    }
                }

                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--;
                    }
                }
                else if (apu.dmc_dma_countdown == 1)
                {
                    dmc_realign = true;
                }
                else if (dmc_realign)
                {
                    dmc_realign = false;
                }
                /////////////////////////////
                // OAM DMA end
                /////////////////////////////


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

                if (apu.dmc_dma_countdown > 0)
                {
                    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.RunOne(true);

                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();
                apu.RunOne(false);

                if (ppu.double_2007_read > 0)
                {
                    ppu.double_2007_read--;
                }

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

                if (IRQ_delay)
                {
                    IRQ_delay = false;
                }

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

                ppu.ppu_open_bus_decay(0);

                Board.ClockCPU();
                ppu.PostCpuInstructionOne();
            }
        }
Beispiel #3
0
        public byte DB;                 //old data bus values from previous reads

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

            if (sprdma_countdown > 0)
            {
                sprdma_countdown--;
                if (sprdma_countdown == 0)
                {
                    if (cpu.TotalExecutedCycles % 2 == 0)
                    {
                        cpu_deadcounter = 2;
                    }
                    else
                    {
                        cpu_deadcounter = 1;
                    }
                    oam_dma_exec       = true;
                    cpu.RDY            = false;
                    oam_dma_index      = 0;
                    special_case_delay = true;
                }
            }

            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--;
                }
            }
            else if (apu.dmc_dma_countdown == 1)
            {
                dmc_realign = true;
            }
            else if (dmc_realign)
            {
                dmc_realign = false;
            }
            /////////////////////////////
            // OAM DMA end
            /////////////////////////////


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

            if (apu.dmc_dma_countdown > 0)
            {
                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 (ppu.double_2007_read > 0)
            {
                ppu.double_2007_read--;
            }

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

            if (IRQ_delay)
            {
                IRQ_delay = false;
            }

            if (!dmc_dma_exec && !oam_dma_exec && !cpu.RDY)
            {
                cpu.RDY   = true;
                IRQ_delay = true;
            }
        }
Beispiel #4
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;
            }
        }
Beispiel #5
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 && !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;
            }
        }