예제 #1
0
        public override void AtVsyncNMI()
        {
            if (Patch_Vectors)
            {
                NES.cpu.NMI = true;
            }

            //strobe pad
            NES.WriteMemory(0x4016, 1);
            NES.WriteMemory(0x4016, 0);

            //read pad and create rising edge button signals so we dont trigger events as quickly as we hold the button down
            int currButtons = 0;

            for (int i = 0; i < 8; i++)
            {
                currButtons <<= 1;
                currButtons  |= (NES.ReadMemory(0x4016) & 1);
            }
            int justDown = (~ButtonState) & currButtons;
            Bit a        = (justDown >> 7) & 1;
            Bit b        = (justDown >> 6) & 1;
            Bit sel      = (justDown >> 5) & 1;
            Bit start    = (justDown >> 4) & 1;
            Bit up       = (justDown >> 3) & 1;
            Bit down     = (justDown >> 2) & 1;
            Bit left     = (justDown >> 1) & 1;
            Bit right    = (justDown >> 0) & 1;

            ButtonState = currButtons;

            //RIGHT: next song
            //LEFT: prev song
            //A: restart song

            bool reset = false;

            if (right)
            {
                CurrentSong++;
                reset = true;
            }
            if (left)
            {
                CurrentSong--;
                reset = true;
            }

            if (a)
            {
                reset = true;
            }

            if (reset)
            {
                ReplayInit();
            }
        }
예제 #2
0
        public override byte ReadReg2xxx(int addr)
        {
            if (addr < 0x3800)
            {
                return(base.ReadReg2xxx(addr));
            }
            else if (addr >= 0x3FF0)
            {
                switch (addr)
                {
                case 0x3FF0:
                {
                    byte ret = 0;
                    if (InitPending)
                    {
                        ret = 1;
                    }
                    InitPending = false;
                    return(ret);
                }

                case 0x3FF1:
                {
                    //kevtris's reset process seems not to work. dunno what all is going on in there

                    //our own innovation, should work OK..
                    NES.apu.NESSoftReset();

                    //mostly fceux's guidance
                    NES.WriteMemory(0x4015, 0);
                    for (int i = 0; i < 14; i++)
                    {
                        NES.WriteMemory((ushort)(0x4000 + i), 0);
                    }
                    NES.WriteMemory(0x4015, 0x0F);

                    //clearing APU misc stuff, maybe not needed with soft reset above
                    //NES.WriteMemory(0x4017, 0xC0);
                    //NES.WriteMemory(0x4017, 0xC0);
                    //NES.WriteMemory(0x4017, 0x40);

                    //important to NSF standard for ram to be cleared, otherwise replayers are confused on account of not initializing memory themselves
                    var ram       = NES.ram;
                    var wram      = this.WRAM;
                    int wram_size = wram.Length;
                    for (int i = 0; i < 0x800; i++)
                    {
                        ram[i] = 0;
                    }
                    for (int i = 0; i < wram_size; i++)
                    {
                        wram[i] = 0;
                    }

                    //store specified initial bank state
                    if (BankSwitched)
                    {
                        for (int i = 0; i < 8; i++)
                        {
                            WriteEXP(0x5FF8 + i - 0x4000, InitBankSwitches[i]);
                        }
                    }

                    return((byte)(CurrentSong - 1));
                }

                case 0x3FF2:
                    return(0);                            //always return NTSC for now

                case 0x3FF3:
                    Patch_Vectors = false;
                    return(0);

                case 0x3FF4:
                    Patch_Vectors = true;
                    return(0);

                default:
                    return(base.ReadReg2xxx(addr));
                }
            }
            else if (addr - 0x3800 < NSFROM.Length)
            {
                return(NSFROM[addr - 0x3800]);
            }
            else
            {
                return(base.ReadReg2xxx(addr));
            }
        }
예제 #3
0
        public override void AtVsyncNmi()
        {
            if (Patch_Vectors)
            {
                NES.cpu.NMI = true;
            }

            //strobe pad
            NES.WriteMemory(0x4016, 1);
            NES.WriteMemory(0x4016, 0);

            //read pad and create rising edge button signals so we don't trigger events as quickly as we hold the button down
            int currButtons = 0;

            for (int i = 0; i < 8; i++)
            {
                currButtons <<= 1;
                currButtons  |= (NES.ReadMemory(0x4016) & 1);
            }
            int justDown = (~ButtonState) & currButtons;
            Bit a        = (justDown >> 7) & 1;
            Bit b        = (justDown >> 6) & 1;
            Bit sel      = (justDown >> 5) & 1;
            Bit start    = (justDown >> 4) & 1;
            Bit up       = (justDown >> 3) & 1;
            Bit down     = (justDown >> 2) & 1;
            Bit left     = (justDown >> 1) & 1;
            Bit right    = (justDown >> 0) & 1;

            ButtonState = currButtons;

            //RIGHT: next song
            //LEFT: prev song
            //A: restart song

            //RTC_Hijack :: control NSF from System Bus 0x00CE
            ushort songChangeAdress = 0x00CE;                           //RTC_Hijack
            byte   songValue        = NES.ReadMemory(songChangeAdress); //RTC_Hijack
            bool   reset            = false;

            if (right || (songValue == 0xFB))             //RTC_Hijack
            {
                NES.WriteMemory(songChangeAdress, 0xFF);  //RTC_Hijack
                if (CurrentSong < nsf.TotalSongs - 1)
                {
                    CurrentSong++;
                    reset = true;
                }
            }
            if (left || (songValue == 0xFA))             //RTC_Hijack
            {
                NES.WriteMemory(songChangeAdress, 0xFF); //RTC_Hijack
                if (CurrentSong > 0)
                {
                    CurrentSong--;
                    reset = true;
                }
            }

            if (a)
            {
                reset = true;
            }

            if (reset)
            {
                ReplayInit();
            }
        }
예제 #4
0
 public void WriteMemory(ushort address, byte value) => _nes.WriteMemory(address, value);