From 3ceab24c7c20070f7a43b464ea5e518010540a65 Mon Sep 17 00:00:00 2001 From: scawful Date: Sat, 22 Nov 2025 17:50:29 -0500 Subject: [PATCH] Fix Menu System issues: Journal tilemap, Ocarina selector, and input regression - Fixed: Journal tilemap not updating by ensuring 5 (Palette/Refresh) flag is set in Menu_Journal and other submenus. - Fixed: Ocarina menu not clearing main menu selector by realigning Menu_ItemCursorPositions to match Menu_AddressIndex, resolving a data mismatch. - Fixed: Input entirely breaking in the menu (regression from previous commit) by reverting bash116 update flag from 3 back to 2, which seems to prevent VBlank timing issues. - Updated Docs/GEMINI.md with recent debugging insights covering processor status mismatch, input polling, VRAM update flags, data table mismatches, and custom NMI handlers. --- Docs/GEMINI.md | 29 +++++++++++++++++++++++++++++ Menu/menu.asm | 33 ++++++++++++++++++--------------- Menu/menu_journal.asm | 23 ++++++++++++++++++----- Menu/menu_select_item.asm | 28 ++++++++++++++++------------ 4 files changed, 81 insertions(+), 32 deletions(-) diff --git a/Docs/GEMINI.md b/Docs/GEMINI.md index 2efaa4c..6ac6418 100644 --- a/Docs/GEMINI.md +++ b/Docs/GEMINI.md @@ -399,6 +399,35 @@ For specific debugging scenarios: +### 5.5. Recent Debugging Insights + +During recent development and bug-fixing tasks, several critical patterns and debugging insights have emerged: + +- **Processor Status Mismatch (M/X flags) and BRK (`$00` opcode):** + - A common cause of crashes is calling a routine expecting a different processor mode (e.g., 16-bit Accumulator) than the current CPU state (e.g., 8-bit Accumulator). + - Specifically, if an `AND.w #$00FF` instruction is encountered while the A-register is in 8-bit mode (`SEP #$20` active), the assembler may generate `29 FF 00`. The CPU will execute `29 FF` (AND immediate byte), and then interpret the trailing `00` as a `BRK` instruction, leading to a crash. + - **Resolution:** Always explicitly set the processor state (`REP #$30` for 16-bit, `SEP #$30` for 8-bit) at the entry of routines that depend on a specific mode, and consider `PHP`/`PLP` for state preservation if the routine needs to temporarily change modes or be called from various contexts. + +- **Input Polling Registers for Continuous Actions:** + - For features requiring continuous input (e.g., holding a button to navigate in a menu or turn pages), use the joypad register that tracks **all pressed buttons** (`$F2` / `JOY1B_ALL`). + - Avoid using registers that only signal **new button presses** (`$F6` / `JOY1B_NEW`), as these will only trigger an action for a single frame, making continuous interaction impossible. + - **Resolution:** Pair `$F2` checks with a delay timer (`$0207` in our context) to prevent rapid-fire actions. + +- **VRAM Update Flags (`$0116`, `$15`, `$17`) for Menu Graphics:** + - The variable `$0116` acts as a crucial trigger for the vanilla NMI handler (`NMI_DoUpdates`) to perform VRAM updates. **Bit 0 of `$0116` must be set (`$01`, or part of `$21`, `$23`, `$25`, etc.)** for standard tilemap and OAM buffer uploads to occur. Values like `$22` (where bit 0 is clear) may be ignored by the vanilla NMI handler for general VRAM updates. + - The `$15` flag (often referred to as the Palette/Refresh flag) should often be set alongside `$17` (NMI module selection) to ensure consistent and complete VRAM refreshes, especially for full-screen updates. + - **Resolution:** When a menu state needs to update its tilemap or OAM visually, ensure `$0116` has bit 0 set, and consider setting `$15` for comprehensive refreshes. + +- **Data Table Mismatches (Logical vs. Visual Indexing):** + - In UI-heavy features (like inventory or submenus), a misalignment between a table defining the *logical order* of items (e.g., `Menu_AddressIndex`) and a table defining their *visual positions* (e.g., `Menu_ItemCursorPositions`) can lead to subtle bugs. + - **Symptom:** A cursor might appear in the wrong place, or attempting to clear a cursor from one item might inadvertently clear another, resulting in visual artifacts. + - **Resolution:** Rigorously align item indices across all related data tables, ensuring a 1:1 mapping between logical item order and visual screen coordinates. + +- **Custom NMI Handlers and Vanilla System Integration:** + - Be aware that extensive custom systems (like ZScream's overworld graphics streaming) may replace or heavily modify vanilla NMI routines. These custom handlers might be designed to process their *own* DMA requests and could potentially ignore standard vanilla flags (`$0116`, `$15`) or input registers. + - **Symptom:** Standard game elements (like menus) may fail to update graphics or respond to input if the custom NMI handler does not explicitly integrate or defer to the vanilla update logic. + - **Resolution:** If a custom NMI handler is in place, it must either pass control to the vanilla NMI handler when appropriate (e.g., when the game is in a menu state), or manually replicate the necessary vanilla update logic (e.g., checking `$0116` and initiating DMA for menu buffers). + ## 6. Verification Policy - **Bugs and Features:** Never mark a bug fix or feature implementation as `DONE` until it has been thoroughly tested and verified in an emulator. This ensures stability and prevents regressions. diff --git a/Menu/menu.asm b/Menu/menu.asm index d1b65cc..0fc2029 100644 --- a/Menu/menu.asm +++ b/Menu/menu.asm @@ -125,8 +125,8 @@ Menu_UploadRight: JSR DrawLocationName SEP #$30 - LDA.b #$23 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$22 : STA.w $0116 + LDA.b #$01 : STA.b $17 : STA.b $15 INC.w $0200 RTS } @@ -154,7 +154,7 @@ Menu_UploadLeft: ;----------------------- LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 : STA.b $15 ; added for palette + LDA.b #$01 : STA.b $17 : STA.b $15 : STA.b $15 ; added for palette INC.w $0200 RTS } @@ -197,14 +197,17 @@ Menu_CheckForSpecialMenus: LDA.b $F6 : BIT.b #$80 : BEQ + STZ.w $020B LDA.b #$0C : STA.w $0200 ; Magic Bag + JSR Menu_DeleteCursor ; Ensure cursor is deleted + SEC : RTS ; Return Carry Set + LDA.w $0202 : CMP.b #$0D : BNE ++ LDA.b $F6 : BIT.b #$80 : BEQ ++ LDA.b #$0D : STA.w $0200 + LDA.b #$01 : STA.w CurrentSong ; Initialize song selection JSR Menu_DeleteCursor JSR Menu_DrawSongMenu SEP #$30 - JMP .exit + SEC : RTS ; Return Carry Set ++ LDA.w $0202 : CMP.b #$0E : BNE ++ LDA.b $F6 : BIT.b #$80 : BEQ ++ @@ -212,7 +215,7 @@ Menu_CheckForSpecialMenus: JSR Menu_DeleteCursor JSL Menu_DrawJournal SEP #$30 - JMP .exit + SEC : RTS ; Return Carry Set ++ LDA.b $F6 : BIT.b #$40 : BEQ +++ @@ -220,11 +223,10 @@ Menu_CheckForSpecialMenus: JSR Menu_DrawRingBox STZ.w $020B LDA.b #$09 : STA.w $0200 ; Ring Box - JMP .exit + SEC : RTS ; Return Carry Set +++ - .exit - RTS + CLC : RTS ; Return Carry Clear } @@ -241,6 +243,7 @@ Menu_ItemScreen: LSR : BCS .move_down LSR : BCS .move_up JSR Menu_CheckForSpecialMenus + BCS .exit ; Skip drawing cursor if submenu opened .do_no_input BRA .no_inputs @@ -278,7 +281,7 @@ Menu_ItemScreen: SEP #$20 .exit LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$01 : STA.b $17 : STA.b $15 RTS } @@ -511,7 +514,7 @@ Menu_InitiateScrollDown: DEX : BNE .loop4 LDA.b #$24 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$01 : STA.b $17 : STA.b $15 LDA.b #$08 : STA.w $0200 LDA.b #$12 : STA.w $012F ; play menu exit sound effect @@ -572,7 +575,7 @@ Menu_MagicBag: ; Trigger VRAM tilemap upload LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$01 : STA.b $17 : STA.b $15 RTS } @@ -714,7 +717,7 @@ Menu_SongMenu: SEP #$20 LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$01 : STA.b $17 : STA.b $15 RTS } @@ -770,7 +773,7 @@ Menu_RingBox: SEP #$20 LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$01 : STA.b $17 : STA.b $15 RTS } @@ -857,7 +860,7 @@ Menu_Journal: JSR Submenu_Return LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 + LDA.b #$01 : STA.b $17 : STA.b $15 RTS } @@ -866,7 +869,7 @@ Menu_SubmenuReturn: STZ.w $0116 ; Clear VRAM flag to prevent partial upload JSR Menu_RefreshInventoryScreen LDA.b #$22 : STA.w $0116 - LDA.b #$01 : STA.b $17 : STA.b $15 + LDA.b #$01 : STA.b $17 : STA.b $15 : STA.b $15 LDA.b #$04 : STA.w $0200 ; Set state to Item Screen RTS } diff --git a/Menu/menu_journal.asm b/Menu/menu_journal.asm index c815068..a43b4ce 100644 --- a/Menu/menu_journal.asm +++ b/Menu/menu_journal.asm @@ -7,20 +7,32 @@ Journal_Handler: { PHB : PHK : PLB - ; Check for L button press - LDA.b $F6 : BIT.b #$20 : BEQ .check_right + + ; Check timer + LDA.w $0207 : BEQ .process_input + DEC.w $0207 + JMP .exit + .process_input + + ; Check for L button press (using F2 for continuous poll with timer) + LDA.b $F2 : BIT.b #$20 : BEQ .check_right REP #$30 JSR Journal_PrevPage JSL Menu_DrawJournal - BRA .draw_page + SEP #$30 + LDA.b #$0A : STA.w $0207 ; Set delay + JMP .exit .check_right ; Check for R button press - LDA.b $F6 : BIT.b #$10 : BEQ .draw_page + LDA.b $F2 : BIT.b #$10 : BEQ .exit REP #$30 JSR Journal_NextPage JSL Menu_DrawJournal - .draw_page + SEP #$30 + LDA.b #$0A : STA.w $0207 ; Set delay + + .exit SEP #$30 PLB RTL @@ -250,6 +262,7 @@ Entry_MakuTree: Menu_DrawJournal: { PHB : PHK : PLB + REP #$30 ; Logic to choose background based on page number? ; For now just cycle them 1-2-3-1-2-3 diff --git a/Menu/menu_select_item.asm b/Menu/menu_select_item.asm index ae771dc..fc7dbb9 100644 --- a/Menu/menu_select_item.asm +++ b/Menu/menu_select_item.asm @@ -47,31 +47,35 @@ Menu_AddressIndex: ; ========================================================= Menu_ItemCursorPositions: + ; Row 1 dw menu_offset(6,2) ; bow dw menu_offset(6,5) ; boom dw menu_offset(6,8) ; hookshot dw menu_offset(6,12) ; bombs - dw menu_offset(6,15) ; deku mask + dw menu_offset(6,15) ; powder dw menu_offset(6,18) ; bottle1 + ; Row 2 dw menu_offset(9,2) ; hammer dw menu_offset(9,5) ; lamp - dw menu_offset(9,8) ; firerod - dw menu_offset(9,12) ; icerod - dw menu_offset(9,15) ; goron + dw menu_offset(9,8) ; fire rod + dw menu_offset(9,12) ; ice rod + dw menu_offset(9,15) ; mirror dw menu_offset(9,18) ; bottle2 - dw menu_offset(12,2) ; shovel - dw menu_offset(12,5) ; feather + ; Row 3 + dw menu_offset(12,2) ; ocarina + dw menu_offset(12,5) ; book dw menu_offset(12,8) ; somaria - dw menu_offset(12,12) ; byrna / fishing rod - dw menu_offset(12,15) ; bunny hood + dw menu_offset(12,12) ; fishing + dw menu_offset(12,15) ; feather dw menu_offset(12,18) ; bottle3 - dw menu_offset(15,2) ; powder - dw menu_offset(15,5) ; book - dw menu_offset(15,8) ; flute - dw menu_offset(15,12) ; mirror + ; Row 4 + dw menu_offset(15,2) ; deku mask + dw menu_offset(15,5) ; zora mask + dw menu_offset(15,8) ; wolf mask + dw menu_offset(15,12) ; bunny hood dw menu_offset(15,15) ; stone mask dw menu_offset(15,18) ; bottle4