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); } }
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); } }