Exemple #1
0
        private void ExecuteSystem()
        {
            Via0.Ca1 = ViaReadAtn();
            Via0.ExecutePhase();
            Via1.ExecutePhase();

            // SO pin pipeline
            if ((_overflowFlagDelaySr & 0x01) != 0)
            {
                _cpu.SetOverflow();
            }

            _overflowFlagDelaySr >>= 1;

            _cpu.IRQ = !(Via0.Irq && Via1.Irq);             // active low IRQ line
            _cpu.ExecuteOne();

            if (_ledEnabled)
            {
                _driveLightOffTime = 25000;
            }
            else if (_driveLightOffTime > 0)
            {
                _driveLightOffTime--;
            }
        }
Exemple #2
0
        private void RunCpuOne()
        {
            cpu_stepcounter++;
            if (cpu_stepcounter == cpu_sequence[cpu_step])
            {
                cpu_step++;
                cpu_step       &= 31;
                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
                        cpu_deadcounter += 514;
                    }
                }

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

                apu.RunOne();
                board.ClockCPU();
                ppu.PostCpuInstructionOne();
            }
        }
Exemple #3
0
        private void ExecutePhaseInternal()
        {
            Via0.Ca1 = ViaReadAtn();

            // clock output from 325572-01 drives CPU clock (phi0)
            ExecuteMotor();
            ExecuteFlux();
            Via0.ExecutePhase();
            Via1.ExecutePhase();

            // SO pin pipeline
            if ((_overflowFlagDelaySr & 0x01) != 0)
            {
                _cpu.SetOverflow();
            }
            _overflowFlagDelaySr >>= 1;

            _cpu.IRQ = !(Via0.Irq && Via1.Irq); // active low IRQ line
            _cpu.ExecuteOne();

            _via0PortBtemp = Via0.EffectivePrB;
            _ledEnabled    = (_via0PortBtemp & 0x08) != 0;

            if (_ledEnabled)
            {
                _driveLightOffTime = 1000000;
            }
            else if (_driveLightOffTime > 0)
            {
                _driveLightOffTime--;
            }
        }
Exemple #4
0
 public void Clock()
 {
     if (delayCycles > 0)
     {
         delayCycles--;
         if (delayCycles == 1)
         {
             resetPC = ReadMemory(0xFFFC);
         }
         else if (delayCycles == 0)
         {
             resetPC     |= ReadMemory(0xFFFD) << 8;
             processor.PC = (ushort)resetPC;
         }
     }
     else
     {
         if (InputAEC())
         {
             processor.IRQ = !InputIRQ();                     //6502 core expects inverted input
             nmiBuffer     = InputNMI();
             if (!nmiBuffer && cachedNMI)
             {
                 processor.NMI = true;                         //6502 core expects inverted input
             }
             cachedNMI     = nmiBuffer;
             processor.RDY = InputRDY();
             processor.ExecuteOne();
         }
     }
 }
Exemple #5
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();
            }
        }
Exemple #6
0
        public void Execute()
        {
            via0.ExecutePhase1();
            via1.ExecutePhase1();

            cpu.IRQ = !(via0.IRQ && via1.IRQ);
            cpu.ExecuteOne();
            via0.ExecutePhase2();
            via1.ExecutePhase2();
        }
Exemple #7
0
 public void ExecutePhase()
 {
     _irqDelay >>= 1;
     _nmiDelay >>= 1;
     _irqDelay  |= ReadIrq() ? 0x0 : 0x2;
     _nmiDelay  |= ReadNmi() ? 0x0 : 0x2;
     _cpu.RDY    = ReadRdy();
     _cpu.IRQ    = (_irqDelay & 1) != 0;
     _cpu.NMI   |= (_nmiDelay & 3) == 2;
     _cpu.ExecuteOne();
 }
        // ------------------------------------

        public void ExecutePhase()
        {
            _cpu.RDY = ReadRdy();

            if (ReadAec())
            {
                _cpu.IRQ    = !ReadIrq();
                _pinNmiLast = _thisNmi;
                _thisNmi    = ReadNmi();
                _cpu.NMI   |= _pinNmiLast && !_thisNmi;
                _cpu.ExecuteOne();
            }
            else
            {
                LagCycles++;
            }
        }
Exemple #9
0
        public void ExecutePhase2()
        {
            cpu.RDY = ReadRDY();

            // the 6502 core expects active high
            // so we reverse the polarity here
            thisNMI = ReadNMI();
            if (!thisNMI && pinNMILast)
            {
                cpu.NMI = true;
            }

            if (ReadAEC())
            {
                cpu.ExecuteOne();
                pinNMILast = thisNMI;
            }
            else
            {
                lagCycles++;
            }
        }
Exemple #10
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();
            }
        }
Exemple #11
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;
            }
        }
Exemple #12
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;
            }
        }
Exemple #13
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;
            }
        }