예제 #1
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
        /// <summary>
        /// メモリを1回右ローテート
        /// N: 結果の最上位ビット
        /// Z: 結果が0であるか
        /// C: はみ出たビット
        /// </summary>
        void ROR(ref byte value)
        {
            byte tmp = Nes.FetchBit(value, 0);

            value = (byte)((value >> 1) + Convert.ToInt32(cFlag) * 0x80);
            cFlag = tmp != 0;
            FlagNandZ(value);
        }
예제 #2
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
        /// <summary>
        /// メモリを1回左ローテート
        /// N: 結果の最上位ビット
        /// Z: 結果が0であるか
        /// C: はみ出たビット
        /// </summary>
        void ROL(ref byte value)
        {
            byte tmp = Nes.FetchBit(value, 7);

            value = (byte)((value << 1) + Convert.ToInt32(cFlag));
            cFlag = tmp != 0;
            FlagNandZ(value);
        }
예제 #3
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
        /// <summary>
        /// bitテストを行う
        /// N: メモリのbit7
        /// V: メモリのbit6
        /// Z: 結果が0であるか
        /// </summary>
        /// <param name="address">実効アドレス</param>
        void BIT(ushort address)
        {
            byte value = ReadMemory(address);

            nFlag = Nes.FetchBit(value, 7) != 0;
            vFlag = Nes.FetchBit(value, 6) != 0;
            zFlag = (registerA & value) == 0;
        }
예제 #4
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
 /// <summary>
 /// Pのセッター各bitをフラグに格納
 /// </summary>
 /// <param name="value">P</param>
 void SetRegisterP(byte value)
 {
     nFlag = Nes.FetchBit(value, 7) != 0;
     vFlag = Nes.FetchBit(value, 6) != 0;
     bFlag = Nes.FetchBit(value, 4) != 0;
     iFlag = Nes.FetchBit(value, 2) != 0;
     zFlag = Nes.FetchBit(value, 1) != 0;
     cFlag = Nes.FetchBit(value, 0) != 0;
 }
예제 #5
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
 public Cpu(Nes nes, int programRomSize) : base(nes)
 {
     unitName   = GetType().Name;
     cpuAddress = new byte[0x10000];
     INITIAL_PROGRAM_COUNTER = (ushort)(0x10000 - programRomSize);
     programCounter          = 0x8000;    //PC初期化
     //フラグ初期化
     nFlag     = false;
     vFlag     = false;
     bFlag     = false;
     iFlag     = false;
     zFlag     = false;
     cFlag     = false;
     registerS = 0xff;
     this.nes  = nes;
 }
예제 #6
0
        public Ppu(Nes nes, MirrorType mirrorType) : base(nes)
        {
            unitName   = GetType().Name;
            ppuAddress = new byte[0x4000];
            this.nes   = nes;


            nmiInterrupt = false;

            oamDataWriteCount = 0;
            ppuWriteCount     = 0;
            tempOamData       = new byte[4];
            ppuAddressInc     = 0x01;

            RenderLine = 0;
            vBlank     = false;

            renderer        = new Renderer(mirrorType);
            renderer.Sprite = new byte[nes.CharacterRimSize / 16, 8, 8];
        }
예제 #7
0
        /// <summary>
        /// PPUレジスタの書き込み
        /// </summary>
        /// <param name="address">Address.</param>
        /// <param name="value">Value.</param>
        public void WritePpuRegister(ushort address, byte value)
        {
            switch (address)
            {
            /*
             * 0x2000 PPUCTRL W コントロールレジスタ1 割り込みなどPPUの設定
             * bit 76543210
             *     VPHBSINN
             *
             * V : VBLANK 開始時に NMI 割り込みを発生 (0:off, 1:on)
             * P : P: PPU マスター/スレーブ
             * H : スプライトサイズ (0:8*8, 1:8*16)
             * B : BG パターンテーブル (0:$0000, 1:$1000)
             * S : スプライトパターンテーブル (0:$0000, 1:$1000)
             * I : PPU アドレスインクリメント (0:+1, 1:+32) - VRAM 上で +1 は横方向、+32 は縦方向
             * N : ネームテーブル (0:$2000, 1:$2400, 2:$2800, 3:$2C00)
             */
            case 0x2000:
                nmiInterrupt                = Nes.FetchBit(value, 7) == 1;
                ppuAddressInc               = (byte)(Nes.FetchBit(value, 2) * 31 + 1);
                renderer.SpriteSize         = Nes.FetchBit(value, 5) * 8 + 8;
                renderer.BgPatternTable     = 256 * Nes.FetchBit(value, 4);
                renderer.SpritePatternTable = 256 * Nes.FetchBit(value, 3);
                renderer.DisplayTable       = Nes.FetchBit(value, 1) * 2 + Nes.FetchBit(value, 0);
                break;

            /* 0x2001 PPUMASK W コントロールレジスタ2 背景イネーブルなどPPUの設定
             * bit 76543210
             *     BGRsbMmG
             *
             * B : 色強調(青)
             * G : 色強調(緑)
             * R : 色強調(赤)
             * s : スプライト描画(0:off, 1:on)
             * b : BG 描画 (0:off, 1:on)
             * M : 画面左端 8px でスプライトクリッピング (0:有効, 1:無効)
             * m : 画面左端 8px で BG クリッピング (0:有効, 1:無効)
             * G : 0:カラー, 1:モノクロ
             */
            case 0x2001:
                renderer.IsSpriteVisible = Nes.FetchBit(value, 4) == 1;
                renderer.IsBGVisible     = Nes.FetchBit(value, 3) == 1;
                break;

            //読み書きするOAMアドレスを指定
            case 0x2003:
                oamAddr = value;
                break;

            //0x2003で指定したOAMアドレスにy, tile, attr, xの順に書き込む
            case 0x2004:
                oamDataWriteCount++;
                tempOamData[oamDataWriteCount - 1] = value;
                if (oamDataWriteCount == 4)
                {
                    renderer.WriteOamTable(oamAddr, tempOamData[3], tempOamData[0], tempOamData[1], tempOamData[2]);
                    oamDataWriteCount = 0;
                }
                break;

            //1回目の書き込みでx, 2回目の書き込みでyのスクロールオフセットを指定
            case 0x2005:
                switch (ppuWriteCount)
                {
                case 0:
                    //scrollOffsetX = value;
                    renderer.ScrollOffsetX = value;
                    ppuWriteCount++;
                    break;

                case 1:
                    //scrollOffsetY = value;
                    renderer.ScrollOffsetY = value;
                    ppuWriteCount          = 0;
                    break;
                }
                break;

            //1回目の書き込みで上位バイト, 2回目の書き込みで下位バイトを設定
            case 0x2006:
                switch (ppuWriteCount)
                {
                case 0:
                    ppuAddr = (ushort)(value * 0x100);
                    ppuWriteCount++;
                    break;

                case 1:
                    ppuAddr      += value;
                    ppuWriteCount = 0;
                    break;
                }
                break;

            //ppuAddrのアドレスに書き込み
            case 0x2007:
                ppuData = value;
                WriteMemory(ppuAddr, value);
                ppuAddr += ppuAddressInc;
                break;

            //OMAへDMA転送
            case 0x4014:
                for (int i = 0, j = value * 0x100; i < 0x40; i++, j += 4)
                {
                    renderer.WriteOamTable(i, nes.ReadCpuMemory((ushort)(j + 3)), nes.ReadCpuMemory((ushort)j), nes.ReadCpuMemory((ushort)(j + 1)), nes.ReadCpuMemory((ushort)(j + 2)));
                }
                PpuCycle = 514;
                break;
            }
        }
예제 #8
0
파일: Unit.cs 프로젝트: t29wuQ/NES_Emulator
 protected Unit(Nes nes)
 {
     this.nes = nes;
 }
예제 #9
0
        /// <summary>
        /// oamメモリへの書き込み
        /// </summary>
        /// <param name="offset">Offset.</param>
        /// <param name="x">The x coordinate.</param>
        /// <param name="y">The y coordinate.</param>
        /// <param name="tile">Tile.</param>
        /// <param name="attr">Attr.</param>
        public void WriteOamTable(int offset, int x, int y, int tile, int attr)
        {
            if (spritePosition[offset] != null)
            {
                foreach (int position in spritePosition[offset])
                {
                    spriteRenderPosition.Remove(position);
                }
                spritePosition[offset] = null;
            }

            bool spriteHit = false;

            if (offset == 0)
            {
                spriteHit = true;
            }

            int tileID             = tile;
            int patternTableNumber = SpritePatternTable;

            if (SpriteSize > 8)
            {
                patternTableNumber = Nes.FetchBit(tileID, 0) * 256;
                tileID             = 2 * (tileID >> 1);
            }
            bool verticalReverse   = Nes.FetchBit(attr, 7) == 1;
            bool horizontalReverse = Nes.FetchBit(attr, 6) == 1;
            bool priority          = Nes.FetchBit(attr, 5) == 0;
            int  palette           = Nes.FetchBit(attr, 1) * 2 + Nes.FetchBit(attr, 0);

            oamTable[offset] = new Oam
            {
                X                 = x,
                Y                 = y + 1,
                TileID            = tileID,
                PatternTable      = patternTableNumber,
                HorizontalReverse = horizontalReverse,
                VerticalReverse   = verticalReverse,
                Priority          = priority,
                Palette           = palette,
                SpriteHit         = spriteHit
            };

            spritePosition[offset] = new List <int>();
            for (int i = x + y * 256, k = 0; i < SpriteSize * 256 + y * 256 + x; i += 256, k++)
            {
                for (int j = 0; j < 8; j++)
                {
                    if (!spriteRenderPosition.ContainsKey(i + j))
                    {
                        spriteRenderPosition.Add(i + j, oamTable[offset]);
                    }
                    else
                    {
                        spriteRenderPosition[i + j] = oamTable[offset];
                    }

                    spritePosition[offset].Add(i + j);
                }

                if (k == 7)
                {
                    oamTable[offset] = new Oam
                    {
                        X                 = x,
                        Y                 = y + 9,
                        TileID            = tileID + 1,
                        PatternTable      = patternTableNumber,
                        HorizontalReverse = horizontalReverse,
                        VerticalReverse   = verticalReverse,
                        Priority          = priority,
                        Palette           = palette
                    };
                }
            }
        }
예제 #10
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
 /// <summary>
 /// フラグN, Zを決める
 /// N: 結果の最上位ビット
 /// Z: 結果が0であるか
 /// </summary>
 /// <param name="value">結果</param>
 void FlagNandZ(int value)
 {
     zFlag = value == 0;
     nFlag = Nes.FetchBit(value, 7) != 0;
 }
예제 #11
0
파일: Cpu.cs 프로젝트: t29wuQ/NES_Emulator
 /// <summary>
 /// メモリを1回右シフト
 /// N: 結果の最上位ビット
 /// Z: 結果が0であるか
 /// C: はみ出たビット
 /// </summary>
 void LSR(ref byte value)
 {
     cFlag   = Nes.FetchBit(value, 0) != 0;
     value >>= 1;
     FlagNandZ(value);
 }