Example #1
0
        public void update(MMU mmu)
        {
            byte JOYP = mmu.JOYP;

            if (!isBit(4, JOYP))
            {
                mmu.JOYP = (byte)((JOYP & 0xF0) | pad);
                if (pad != 0xF)
                {
                    mmu.requestInterrupt(JOYPAD_INTERRUPT);
                }
            }
            if (!isBit(5, JOYP))
            {
                mmu.JOYP = (byte)((JOYP & 0xF0) | buttons);
                if (buttons != 0xF)
                {
                    mmu.requestInterrupt(JOYPAD_INTERRUPT);
                }
            }
            if ((JOYP & 0b00110000) == 0b00110000)
            {
                mmu.JOYP = 0xFF;
            }
        }
        private void changeSTATMode(int mode, MMU mmu)
        {
            byte STAT = (byte)(mmu.STAT & ~0x3);

            mmu.STAT = (byte)(STAT | mode);
            //Accessing OAM - Mode 2 (80 cycles)
            if (mode == 2 && isBit(5, STAT))
            { // Bit 5 - Mode 2 OAM Interrupt         (1=Enable) (Read/Write)
                mmu.requestInterrupt(LCD_INTERRUPT);
            }

            //case 3: //Accessing VRAM - Mode 3 (172 cycles) Total M2+M3 = 252 Cycles

            //HBLANK - Mode 0 (204 cycles) Total M2+M3+M0 = 456 Cycles
            else if (mode == 0 && isBit(3, STAT))
            { // Bit 3 - Mode 0 H-Blank Interrupt     (1=Enable) (Read/Write)
                mmu.requestInterrupt(LCD_INTERRUPT);
            }

            //VBLANK - Mode 1 (4560 cycles - 10 lines)
            else if (mode == 1 && isBit(4, STAT))
            { // Bit 4 - Mode 1 V-Blank Interrupt     (1=Enable) (Read/Write)
                mmu.requestInterrupt(LCD_INTERRUPT);
            }
        }
Example #3
0
 private void handleTimer(int cycles, MMU mmu)
 {
     if (mmu.TAC_ENABLED)
     {
         timerCounter += cycles;
         while (timerCounter >= TAC_FREQ[mmu.TAC_FREQ])
         {
             mmu.TIMA++;
             timerCounter -= TAC_FREQ[mmu.TAC_FREQ];
         }
         if (mmu.TIMA == 0xFF)
         {
             mmu.requestInterrupt(TIMER_INTERRUPT);
             mmu.TIMA = mmu.TMA;
         }
     }
 }
        public void update(int cycles, MMU mmu)
        {
            scanlineCounter += cycles;
            byte currentMode = (byte)(mmu.STAT & 0x3); //Current Mode Mask

            if (isLCDEnabled(mmu.LCDC))
            {
                switch (currentMode)
                {
                case 2:     //Accessing OAM - Mode 2 (80 cycles)
                    if (scanlineCounter >= OAM_CYCLES)
                    {
                        changeSTATMode(3, mmu);
                        scanlineCounter -= OAM_CYCLES;
                    }
                    break;

                case 3:     //Accessing VRAM - Mode 3 (172 cycles) Total M2+M3 = 252 Cycles
                    if (scanlineCounter >= VRAM_CYCLES)
                    {
                        changeSTATMode(0, mmu);
                        drawScanLine(mmu);
                        scanlineCounter -= VRAM_CYCLES;
                    }
                    break;

                case 0:     //HBLANK - Mode 0 (204 cycles) Total M2+M3+M0 = 456 Cycles
                    if (scanlineCounter >= HBLANK_CYCLES)
                    {
                        mmu.LY++;
                        scanlineCounter -= HBLANK_CYCLES;

                        if (mmu.LY == SCREEN_HEIGHT)
                        {     //check if we arrived Vblank
                            changeSTATMode(1, mmu);
                            mmu.requestInterrupt(VBLANK_INTERRUPT);
                            RenderFrame();
                        }
                        else
                        {     //not arrived yet so return to 2
                            changeSTATMode(2, mmu);
                        }
                    }
                    break;

                case 1:     //VBLANK - Mode 1 (4560 cycles - 10 lines)
                    if (scanlineCounter >= SCANLINE_CYCLES)
                    {
                        mmu.LY++;
                        scanlineCounter -= SCANLINE_CYCLES;

                        if (mmu.LY > SCREEN_VBLANK_HEIGHT)
                        {     //check end of VBLANK
                            changeSTATMode(2, mmu);
                            mmu.LY = 0;
                        }
                    }
                    break;
                }

                if (mmu.LY == mmu.LYC)
                { //handle coincidence Flag
                    mmu.STAT = bitSet(2, mmu.STAT);
                    if (isBit(6, mmu.STAT))
                    {
                        mmu.requestInterrupt(LCD_INTERRUPT);
                    }
                }
                else
                {
                    mmu.STAT = bitClear(2, mmu.STAT);
                }
            }
            else
            { //LCD Disabled
                scanlineCounter = 0;
                mmu.LY          = 0;
                mmu.STAT        = (byte)(mmu.STAT & ~0x3);
            }
        }