From 246e5c982689452ffc2e757dfa2ece3e5f31a978 Mon Sep 17 00:00:00 2001 From: zhangsan1890 <286174533+zhangsan1890@users.noreply.github.com> Date: Wed, 20 May 2026 14:41:54 +0800 Subject: [PATCH] Use VBlank interrupt in unbricked examples --- unbricked/audio/main.asm | 36 ++++++++++++++++++++++++++------- unbricked/bcd/main.asm | 35 +++++++++++++++++++++++++------- unbricked/bricks/main.asm | 36 ++++++++++++++++++++++++++------- unbricked/collision/main.asm | 35 +++++++++++++++++++++++++------- unbricked/functions/main.asm | 36 ++++++++++++++++++++++++++------- unbricked/input/main.asm | 35 +++++++++++++++++++++++++------- unbricked/objects/main.asm | 36 ++++++++++++++++++++++++++------- unbricked/serial-link/demo.asm | 33 ++++++++++++++++++++++-------- unbricked/serial-link/main.asm | 36 +++++++++++++++++++++++---------- unbricked/title-screen/main.asm | 34 +++++++++++++++++++++++++++---- 10 files changed, 280 insertions(+), 72 deletions(-) diff --git a/unbricked/audio/main.asm b/unbricked/audio/main.asm index 6e2ed4be..dd625acb 100644 --- a/unbricked/audio/main.asm +++ b/unbricked/audio/main.asm @@ -6,6 +6,14 @@ DEF BRICK_RIGHT EQU $06 DEF BLANK_TILE EQU $08 ; ANCHOR_END: constants +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -93,14 +101,14 @@ ClearOam: ld a, 0 ld [wFrameCounter], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei + Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ; Add the ball's momentum to its position in OAM. ld a, [wBallMomentumX] @@ -361,6 +369,17 @@ MemCopy: jp nz, MemCopy ret +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + ; ANCHOR: bounce-sound PlayBounceSound: ld a, $85 @@ -645,6 +664,9 @@ BallEnd: SECTION "Counter", WRAM0 wFrameCounter: db +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db + SECTION "Input Variables", WRAM0 wCurKeys: db wNewKeys: db diff --git a/unbricked/bcd/main.asm b/unbricked/bcd/main.asm index 87e17d96..bcaf6f48 100644 --- a/unbricked/bcd/main.asm +++ b/unbricked/bcd/main.asm @@ -10,6 +10,14 @@ DEF SCORE_TENS EQU $9870 DEF SCORE_ONES EQU $9871 ; ANCHOR_END: score-tile-location +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -100,16 +108,15 @@ ClearOam: ld [wCurKeys], a ld [wNewKeys], a ld [wScore], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei ; ANCHOR_END: init-variables Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ; Add the ball's momentum to its position in OAM. ld a, [wBallMomentumX] @@ -392,6 +399,17 @@ MemCopy: jp nz, MemCopy ret +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + Tiles: dw `33333333 dw `33333333 @@ -742,6 +760,9 @@ BallEnd: SECTION "Counter", WRAM0 wFrameCounter: db +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db + SECTION "Input Variables", WRAM0 wCurKeys: db wNewKeys: db diff --git a/unbricked/bricks/main.asm b/unbricked/bricks/main.asm index 38668e4f..565d61f2 100644 --- a/unbricked/bricks/main.asm +++ b/unbricked/bricks/main.asm @@ -6,6 +6,14 @@ DEF BRICK_RIGHT EQU $06 DEF BLANK_TILE EQU $08 ; ANCHOR_END: constants +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -96,14 +104,14 @@ ClearOam: ld [wCurKeys], a ld [wNewKeys], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei + Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ; Add the ball's momentum to its position in OAM. ld a, [wBallMomentumX] @@ -357,6 +365,17 @@ MemCopy: jp nz, MemCopy ret +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + Tiles: dw `33333333 dw `33333333 @@ -615,6 +634,9 @@ BallEnd: SECTION "Counter", WRAM0 wFrameCounter: db +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db + SECTION "Input Variables", WRAM0 wCurKeys: db wNewKeys: db diff --git a/unbricked/collision/main.asm b/unbricked/collision/main.asm index 70ae528e..cddcb4aa 100644 --- a/unbricked/collision/main.asm +++ b/unbricked/collision/main.asm @@ -1,5 +1,13 @@ INCLUDE "hardware.inc" +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -95,16 +103,15 @@ ClearOam: ld [wFrameCounter], a ld [wCurKeys], a ld [wNewKeys], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei ; ANCHOR: momentum Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ; Add the ball's momentum to its position in OAM. ld a, [wBallMomentumX] @@ -344,6 +351,17 @@ MemCopy: jp nz, MemCopy ret +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + Tiles: dw `33333333 dw `33333333 @@ -605,6 +623,9 @@ BallEnd: SECTION "Counter", WRAM0 wFrameCounter: db +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db + SECTION "Input Variables", WRAM0 wCurKeys: db wNewKeys: db diff --git a/unbricked/functions/main.asm b/unbricked/functions/main.asm index 17e700ec..ae2a82dd 100644 --- a/unbricked/functions/main.asm +++ b/unbricked/functions/main.asm @@ -1,5 +1,13 @@ INCLUDE "hardware.inc" +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -72,15 +80,15 @@ ClearOam: ld a, 0 ld [wFrameCounter], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei + ; ANCHOR: main Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ld a, [wFrameCounter] inc a @@ -99,6 +107,17 @@ WaitVBlank2: jp Main ; ANCHOR_END: main +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + ; ANCHOR: memcpy ; Copy bytes from one area to another. ; @param de: Source @@ -362,6 +381,9 @@ PaddleEnd: SECTION "Counter", WRAM0 wFrameCounter: db +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db + SECTION "Input Variables", WRAM0 wCurKeys: db wNewKeys: db diff --git a/unbricked/input/main.asm b/unbricked/input/main.asm index 89e756ca..b678e1ce 100644 --- a/unbricked/input/main.asm +++ b/unbricked/input/main.asm @@ -1,5 +1,13 @@ INCLUDE "hardware.inc" +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -74,17 +82,16 @@ ClearOam: ld [wFrameCounter], a ld [wCurKeys], a ld [wNewKeys], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei ; ANCHOR_END: initialize-vars ; ANCHOR: main Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ; Check the current keys every frame and move left or right. call UpdateKeys @@ -158,6 +165,17 @@ UpdateKeys: ret ; ANCHOR_END: input-routine +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + ; ANCHOR: memcpy ; Copy bytes from one area to another. ; @param de: Source @@ -421,6 +439,9 @@ PaddleEnd: SECTION "Counter", WRAM0 wFrameCounter: db +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db + ; ANCHOR: vars SECTION "Input Variables", WRAM0 wCurKeys: db diff --git a/unbricked/objects/main.asm b/unbricked/objects/main.asm index eeeec818..3aba76fb 100644 --- a/unbricked/objects/main.asm +++ b/unbricked/objects/main.asm @@ -2,6 +2,14 @@ ; ANCHOR_END: dummy Note that lines matching /^; ANCHOR/ are stripped from the online version INCLUDE "hardware.inc" +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + SECTION "Header", ROM0[$100] jp EntryPoint @@ -98,14 +106,14 @@ ClearOam: ld a, 0 ld [wFrameCounter], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei + Main: - ld a, [rLY] - cp 144 - jp nc, Main -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ld a, [wFrameCounter] inc a @@ -124,6 +132,17 @@ WaitVBlank2: jp Main ; ANCHOR_END: main-loop +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + Tiles: dw `33333333 dw `33333333 @@ -373,4 +392,7 @@ PaddleEnd: ; ANCHOR: variables SECTION "Counter", WRAM0 wFrameCounter: db + +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db ; ANCHOR_END: variables diff --git a/unbricked/serial-link/demo.asm b/unbricked/serial-link/demo.asm index d694b2c0..13e5cadc 100644 --- a/unbricked/serial-link/demo.asm +++ b/unbricked/serial-link/demo.asm @@ -64,6 +64,15 @@ DEF HANDSHAKE_FAILED EQU $F0 ; ANCHOR_END: handshake-codes +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + + ; ANCHOR: serial-interrupt-vector SECTION "Serial Interrupt", ROM0[$58] SerialInterrupt: @@ -151,18 +160,12 @@ WaitVBlank: Main: ; ANCHOR_END: serial-demo-init-callsite - ld a, [rLY] - cp 144 - jp nc, Main + call WaitForVBlank ; ANCHOR: serial-demo-update-callsite call Input call MainUpdate ; ANCHOR_END: serial-demo-update-callsite -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 call LinkDisplay ld a, [wFrameCounter] @@ -207,8 +210,10 @@ LinkInit: ; enable the serial interrupt ldh a, [rIE] - or a, IEF_SERIAL + or a, IEF_SERIAL | IEF_VBLANK ldh [rIE], a + xor a + ldh [rIF], a ; enable interrupt processing globally ei @@ -450,6 +455,17 @@ Memfill: jr nz, Memfill ret +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + LinkDisplay: ld hl, DISPLAY_CLOCK_SRC @@ -802,6 +818,7 @@ TilesEnd: SECTION "Counter", WRAM0 wFrameCounter: db +wVBlankDone: db SECTION "Input Variables", WRAM0 wCurKeys: db diff --git a/unbricked/serial-link/main.asm b/unbricked/serial-link/main.asm index e791fc68..7bdb3ae5 100644 --- a/unbricked/serial-link/main.asm +++ b/unbricked/serial-link/main.asm @@ -29,6 +29,15 @@ DEF MSG_GAME EQU $81 ; ANCHOR_END: link-defs +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + + ; ANCHOR: serial-interrupt-vector SECTION "Serial Interrupt", ROM0[$58] SerialInterrupt: @@ -54,8 +63,10 @@ LinkInit: ld [wLink], a call SioInit ldh a, [rIE] - or a, IEF_SERIAL + or a, IEF_SERIAL | IEF_VBLANK ldh [rIE], a + xor a + ldh [rIF], a ret ; ANCHOR_END: link-impl-init @@ -346,15 +357,7 @@ Main: ei ; enable interrupts to process transfers call LinkUpdate -.wait_vblank_end - ldh a, [rLY] - cp 144 - jr nc, .wait_vblank_end - -.wait_vblank_start - ldh a, [rLY] - cp 144 - jr c, .wait_vblank_start + call WaitForVBlank di ; disable interrupts for OAM/VRAM access @@ -517,6 +520,17 @@ Right: ld [_OAMRAM + 1], a jp Main +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + ; Convert a pixel position to a tilemap address ; hl = $9800 + X + Y * 32 ; @param b: X @@ -1101,6 +1115,7 @@ BallEnd: SECTION "Counter", WRAM0 wFrameCounter: db +wVBlankDone: db SECTION "Input Variables", WRAM0 wCurKeys: db @@ -1120,4 +1135,3 @@ wLinkPacketCount: db wShakeFailed: db wRemoteScore: db ; ANCHOR_END: link-state - diff --git a/unbricked/title-screen/main.asm b/unbricked/title-screen/main.asm index 634d4a62..55ce4454 100644 --- a/unbricked/title-screen/main.asm +++ b/unbricked/title-screen/main.asm @@ -4,6 +4,14 @@ INCLUDE "hardware.inc" ; ANCHOR_END: includes +SECTION "VBlank Interrupt", ROM0[$40] +VBlankInterrupt: + push af + ld a, 1 + ld [wVBlankDone], a + pop af + reti + ; ANCHOR: header SECTION "Header", ROM0[$100] @@ -45,17 +53,21 @@ TitleScreen: ld a, %11100100 ld [rBGP], a + ld a, IE_VBLANK + ldh [rIE], a + xor a + ldh [rIF], a + ei + TitleScreenLoop: + call WaitForVBlank call UpdateKeys ld a, [wCurKeys] and PAD_START jr z, TitleScreenLoop ; ANCHOR_END: title_screen -WaitVBlank2: - ld a, [rLY] - cp 144 - jp c, WaitVBlank2 + call WaitForVBlank ; Turn the LCD off ld a, 0 @@ -99,6 +111,17 @@ Done: jp Done ; ANCHOR_END: end +WaitForVBlank: + xor a + ld [wVBlankDone], a +.wait + halt + nop + ld a, [wVBlankDone] + and a + jr z, .wait + ret + ; ANCHOR: memcpy ; Copy bytes from one area to another. ; @param de: Source @@ -337,3 +360,6 @@ Unbricked_Title_Screen_Map_Begin: DB $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, 0,0,0,0,0,0,0,0,0,0,0,0 DB $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, 0,0,0,0,0,0,0,0,0,0,0,0 Unbricked_Title_Screen_Map_End: + +SECTION "VBlank Variables", WRAM0 +wVBlankDone: db