diff --git a/constants/hardware_constants.asm b/constants/hardware_constants.asm index 9da516403..1580747b0 100644 --- a/constants/hardware_constants.asm +++ b/constants/hardware_constants.asm @@ -36,7 +36,8 @@ DEF LCD_STAT EQU 1 DEF TIMER EQU 2 DEF SERIAL EQU 3 DEF JOYPAD EQU 4 -DEF IE_DEFAULT EQU (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) +DEF IE_DEFAULT EQU (1 << SERIAL) | (1 << LCD_STAT) | (1 << VBLANK) +DEF IE_DEFAULT_WO_LCD_STAT EQU (1 << SERIAL) | (1 << VBLANK) ; OAM attribute flags DEF OAM_TILE_BANK EQU 3 diff --git a/engine/link/link.asm b/engine/link/link.asm index c015fcaf9..7f35e3a2f 100644 --- a/engine/link/link.asm +++ b/engine/link/link.asm @@ -104,7 +104,7 @@ endc xor a ldh [rIF], a - ld a, (1 << JOYPAD) | (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK) + ld a, (1 << JOYPAD) | (1 << SERIAL) | (1 << VBLANK) ldh [rIE], a call Link_CopyRandomNumbers @@ -280,7 +280,7 @@ endc xor a ldh [rIF], a - ld a, (1 << JOYPAD) | (1 << SERIAL) | (1 << TIMER) | (1 << VBLANK) + ld a, (1 << JOYPAD) | (1 << SERIAL) | (1 << VBLANK) ldh [rIE], a ld de, MUSIC_NONE call PlayMusic diff --git a/engine/menus/cleared_level_screen.asm b/engine/menus/cleared_level_screen.asm index 18cb5db8a..d7a4054b0 100755 --- a/engine/menus/cleared_level_screen.asm +++ b/engine/menus/cleared_level_screen.asm @@ -1,6 +1,7 @@ ClearedLevelScreen: xor a ldh [hMapAnims], a + ldh [hLCDStatIntRequired], a ldh [hSCY], a ld a, -$4 ldh [hSCX], a diff --git a/engine/menus/game_menu.asm b/engine/menus/game_menu.asm index 923a6d5d1..101fea716 100755 --- a/engine/menus/game_menu.asm +++ b/engine/menus/game_menu.asm @@ -14,6 +14,7 @@ GameMenu: GameMenu_KeepMusic: xor a ldh [hMapAnims], a + ldh [hLCDStatIntRequired], a call ClearTilemap call LoadFrame call LoadStandardFont diff --git a/engine/menus/level_selection_menu.asm b/engine/menus/level_selection_menu.asm index 2b901e2c8..f7320f894 100755 --- a/engine/menus/level_selection_menu.asm +++ b/engine/menus/level_selection_menu.asm @@ -4,6 +4,7 @@ LevelSelectionMenu:: ldh [hMapAnims], a ldh [hSCY], a ldh [hSCX], a + ldh [hLCDStatIntRequired], a ld a, 1 << DONT_CLEAR_SHADOW_OAM_IN_SPRITE_ANIMS_F ld [wStateFlags], a diff --git a/engine/menus/main_menu.asm b/engine/menus/main_menu.asm index 45985c802..597d00d06 100644 --- a/engine/menus/main_menu.asm +++ b/engine/menus/main_menu.asm @@ -14,6 +14,7 @@ MainMenu: .loop xor a ldh [hMapAnims], a + ldh [hLCDStatIntRequired], a call ClearTilemap call LoadFrame call LoadStandardFont diff --git a/engine/menus/titlescreen.asm b/engine/menus/titlescreen.asm index f2bc8a017..aa7fad1df 100755 --- a/engine/menus/titlescreen.asm +++ b/engine/menus/titlescreen.asm @@ -13,6 +13,8 @@ IntroSequence: ; fallthrough StartTitleScreen: + ld a, TRUE + ldh [hLCDStatIntRequired], a ldh a, [rSVBK] push af ld a, BANK(wLYOverrides) diff --git a/engine/movie/credits.asm b/engine/movie/credits.asm index 9cf3a8ab6..7429568ca 100644 --- a/engine/movie/credits.asm +++ b/engine/movie/credits.asm @@ -8,6 +8,9 @@ Credits:: .okay ld [wJumptableIndex], a + ld a, TRUE + ldh [hLCDStatIntRequired], a + ldh a, [rSVBK] push af ld a, BANK(wGBCPalettes) diff --git a/engine/movie/intro.asm b/engine/movie/intro.asm index 534beb958..5f4fad8c0 100644 --- a/engine/movie/intro.asm +++ b/engine/movie/intro.asm @@ -1,4 +1,6 @@ CrystalIntro: + ld a, TRUE + ldh [hLCDStatIntRequired], a ldh a, [rSVBK] push af ld a, BANK(wGBCPalettes) diff --git a/engine/overworld/events.asm b/engine/overworld/events.asm index d3f7f139a..97d6ad21a 100644 --- a/engine/overworld/events.asm +++ b/engine/overworld/events.asm @@ -3,6 +3,8 @@ SECTION "Events", ROMX OverworldLoop:: xor a ; MAPSTATUS_START ld [wMapStatus], a + ld a, TRUE + ld [hLCDStatIntRequired], a .loop ld a, [wMapStatus] ld hl, .Jumptable diff --git a/home/init.asm b/home/init.asm index 80a462ff4..357fd482b 100644 --- a/home/init.asm +++ b/home/init.asm @@ -151,7 +151,8 @@ Init:: xor a ldh [rIF], a - ld a, IE_DEFAULT + ldh [hLCDStatIntRequired], a + ld a, IE_DEFAULT_WO_LCD_STAT ldh [rIE], a ei diff --git a/home/serial.asm b/home/serial.asm index b4070fc3c..ecc1a6138 100644 --- a/home/serial.asm +++ b/home/serial.asm @@ -156,7 +156,7 @@ Serial_ExchangeByte:: .not_player_1_or_timed_out ldh a, [rIE] - and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) + and IE_DEFAULT cp 1 << SERIAL jr nz, .loop ld a, [wLinkByteTimeout] @@ -180,7 +180,7 @@ Serial_ExchangeByte:: xor a ldh [hSerialReceivedNewData], a ldh a, [rIE] - and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) + and IE_DEFAULT sub 1 << SERIAL jr nz, .non_serial_interrupts_enabled @@ -212,7 +212,7 @@ Serial_ExchangeByte:: .timed_out ldh a, [rIE] - and (1 << SERIAL) | (1 << TIMER) | (1 << LCD_STAT) | (1 << VBLANK) + and IE_DEFAULT cp 1 << SERIAL ld a, SERIAL_NO_DATA_BYTE ret z diff --git a/home/vblank.asm b/home/vblank.asm index deac90453..a149231df 100644 --- a/home/vblank.asm +++ b/home/vblank.asm @@ -35,12 +35,12 @@ VBlank:: reti .VBlanks: - dw VBlank0 - dw VBlank1 - dw VBlank2 - dw VBlank3 - dw VBlank4 - dw VBlank5 + dw VBlank0 ; normal operation + dw VBlank1 ; battle transition, battle anims (double speed mode) + dw VBlank2 ; link + dw VBlank3 ; battle anims (regular speed mode) + dw VBlank4 ; printer + dw VBlank5 ; credits dw VBlank6 dw VBlank0 ; just in case @@ -118,6 +118,7 @@ VBlank0:: ldh [hVBlankOccurred], a ; if hWindowHUDLY is active, enable interrupts so the LCD interrupt can trigger + ; while non-vblank-sensitive operations are executed. ldh a, [hWindowHUDLY] and a jr z, .next2 @@ -163,10 +164,9 @@ VBlank0:: ldh a, [hROMBankBackup] rst Bankswitch - ; if hWindowHUDLY is not active, we're done ldh a, [hWindowHUDLY] and a - ret z + jr z, .no_window_hud ; interrupts must be enabled in the cycle that rLY becomes [hWindowHUDLY] to prevent flickering ; wait until [hWindowHUDLY] - [rLY] is NOT between 0 and 2 before disabling interrupts @@ -178,9 +178,17 @@ VBlank0:: cp 2 + 1 jr c, .wait_loop - ; restore normal interrupts: enable ints besides joypad and let vblank finish +.no_window_hud + ; if hWindowHUDLY is active, only LCD_STAT is enabled. + ; if hLCDStatIntRequired changeed during last frame, interrupts to request have changed. + ; so, restore normal interrupts: enable ints besides joypad (and maybe lcd stat) and let vblank finish. di + ld a, [hLCDStatIntRequired] + and a ld a, IE_DEFAULT + jr nz, .enable_ints + ld a, IE_DEFAULT_WO_LCD_STAT +.enable_ints ldh [rIE], a ret diff --git a/ram/hram.asm b/ram/hram.asm index bdd29c677..c5f98e747 100644 --- a/ram/hram.asm +++ b/ram/hram.asm @@ -13,6 +13,8 @@ hVBlankOccurred:: db hROMBank:: db hVBlank:: db +hLCDStatIntRequired:: db + hMapEntryMethod:: db hJoypadReleased:: db