jsmolka / eggvance

A Game Boy Advance emulator.
https://smolka.dev/tags/eggvance
GNU General Public License v3.0
65 stars 1 forks source link

Pokemon Ruby / Sapphire: Black lines at top during new game sequence #7

Closed jsmolka closed 3 years ago

jsmolka commented 3 years ago

Does not happen all the time.

bug

The lines are part of BG1. The bug is caused by inconsistent values in BG1VOFS. Explicitly setting BG1VOFS before the sequence fixes this issue (link):

 static void Task_NewGameSpeech1(u8 taskId)
 {
     Text_LoadWindowTemplate(&gWindowTemplate_81E6C3C);
     InitMenuWindow((struct WindowTemplate *)&gMenuTextWindowTemplate);
     // Other regsiters
+    REG_BG1VOFS = 0;
     // Other functions
     ScanlineEffect_Stop();
     // Remaining functions
 }

Another potential fix is disabling the 'scanline effect' which is stopped in the previous function (link):

 void ScanlineEffect_InitHBlankDmaTransfer(void)
 {
+     return;
      // Not called
 }

The most probably cause is a bad write to BG1VOFS between initializing the main menu and the new game sequence.

The scanline effect is initialized during the title screen (here). This results in an hblank DMA that continuously writes to BF1VOFS.

0  03004EF4 -> 04000016 (1)
0  03004EF6 -> 04000016 (1)
0  03004EF8 -> 04000016 (1)
0  03004EFA -> 04000016 (1)
0  03004EFC -> 04000016 (1)
0  03004EFE -> 04000016 (1)
0  03004F00 -> 04000016 (1)
0  03004F02 -> 04000016 (1)
0  03004F04 -> 04000016 (1)
0  03004F06 -> 04000016 (1)
0  03004F08 -> 04000016 (1)
0  03004F0A -> 04000016 (1)
0  03004F0C -> 04000016 (1)
0  03004F0E -> 04000016 (1)
0  03004F10 -> 04000016 (1)
0  03004F12 -> 04000016 (1)
0  03004F14 -> 04000016 (1)
0  03004F16 -> 04000016 (1)
0  03004F18 -> 04000016 (1)
0  03004F1A -> 04000016 (1)
0  03004F1C -> 04000016 (1)
0  03004F1E -> 04000016 (1)
0  03004F20 -> 04000016 (1)
0  03005562 -> 04000014 (1)
0  03005564 -> 04000016 (1)
0  03005566 -> 04000016 (1)
0  03005568 -> 04000016 (1)
0  0300556A -> 04000016 (1)
0  0300556C -> 04000016 (1)

Copied somewhere from PC = 0x080896ba.

 src/scanline_effect.o(.text)
 .text          0x0000000008089578      0x4e4 src/scanline_effect.o
                0x0000000008089578                ScanlineEffect_Stop
                0x00000000080895b8                ScanlineEffect_Clear
                0x00000000080895f8                ScanlineEffect_SetParams
                0x0000000008089668                ScanlineEffect_InitHBlankDmaTransfer
                0x0000000008089930                ScanlineEffect_InitWave

This means that the write which causes the immediate DMA is in this function:

void ScanlineEffect_InitHBlankDmaTransfer(void)
{
    if (gScanlineEffect.state == 0)
    {
        return;
    }
    else if (gScanlineEffect.state == 3)
    {
        gScanlineEffect.state = 0;
        DmaStop(0);
        sShouldStopWaveTask = TRUE;
    }
    else
    {
        DmaStop(0);
        DmaSet(0, gScanlineEffect.dmaSrcBuffers[gScanlineEffect.srcBuffer], gScanlineEffect.dmaDest, gScanlineEffect.dmaControl);
        gScanlineEffect.setFirstScanlineReg();
        gScanlineEffect.srcBuffer ^= 1;
    }
}

The wave get initialized here

        if (!UpdatePaletteFade())
        {
            StartPokemonLogoShine(FALSE);
            ScanlineEffect_InitWave(0, DISPLAY_HEIGHT, 4, 4, 0, SCANLINE_EFFECT_REG_BG1HOFS, TRUE);
            SetMainCallback2(MainCB2);
        }
        break;

and writes zeros to the BG offset register. The last one happens to be non-zero sometimes.

The disassembly of ScanlineEffect_InitWave.

08089944  0000B5F0  push      {r4,r5,r6,r7,lr}
08089946  00004657  mov       r7,r10
08089948  0000464E  mov       r6,r9
0808994A  00004645  mov       r5,r8
0808994C  0000B4E0  push      {r5,r6,r7}
0808994E  0000B088  add       sp,-0x20
08089950  00001C05  mov       r5,r0
08089952  00009104  str       r1,[sp,0x10]
08089954  00009810  ldr       r0,[sp,0x40]
08089956  00004680  mov       r8,r0
08089958  00009911  ldr       r1,[sp,0x44]
0808995A  00004689  mov       r9,r1
0808995C  00009812  ldr       r0,[sp,0x48]
0808995E  00004682  mov       r10,r0
08089960  0000062D  lsl       r5,r5,0x18
08089962  00000E2D  lsr       r5,r5,0x18
08089964  00009904  ldr       r1,[sp,0x10]
08089966  00000609  lsl       r1,r1,0x18
08089968  00009105  str       r1,[sp,0x14]
0808996A  00000E08  lsr       r0,r1,0x18
0808996C  00009003  str       r0,[sp,0xC]
0808996E  00000611  lsl       r1,r2,0x18
08089970  00000E09  lsr       r1,r1,0x18
08089972  00009106  str       r1,[sp,0x18]
08089974  0000061A  lsl       r2,r3,0x18
08089976  00000E12  lsr       r2,r2,0x18
08089978  00009207  str       r2,[sp,0x1C]
0808997A  00004641  mov       r1,r8
0808997C  00000609  lsl       r1,r1,0x18
0808997E  00000E09  lsr       r1,r1,0x18
08089980  00004688  mov       r8,r1
08089982  0000464B  mov       r3,r9
08089984  0000061B  lsl       r3,r3,0x18
08089986  00000E1B  lsr       r3,r3,0x18
08089988  00004699  mov       r9,r3
0808998A  00004650  mov       r0,r10
0808998C  00000600  lsl       r0,r0,0x18
0808998E  00000E00  lsr       r0,r0,0x18
08089990  00004682  mov       r10,r0
08089992  0000F7FF  bl        <setup>
08089994  0000FE11  bl        0x80895B8
08089996  0000482E  ldr       r0,[0x8089A50]
08089998  00004448  add       r0,r9
0808999A  00009000  str       r0,[sp,0x0]
0808999C  0000482D  ldr       r0,[0x8089A54]
0808999E  00009001  str       r0,[sp,0x4]
080899A0  00004669  mov       r1,sp
080899A2  00002001  mov       r0,0x1
080899A4  00007208  strb      r0,[r1,0x8]
080899A6  00004668  mov       r0,sp
080899A8  00002100  mov       r1,0x0
080899AA  00007241  strb      r1,[r0,0x9]
080899AC  00009800  ldr       r0,[sp,0x0]
080899AE  00009901  ldr       r1,[sp,0x4]
080899B0  00009A02  ldr       r2,[sp,0x8]
080899B2  0000F7FF  bl        <setup>
080899B4  0000FE21  bl        0x80895F8
080899B6  00004828  ldr       r0,[0x8089A58]
080899B8  00002100  mov       r1,0x0
080899BA  0000F7F1  bl        <setup>
080899BC  0000F867  bl        0x807AA8C
080899BE  00000600  lsl       r0,r0,0x18
080899C0  00000E07  lsr       r7,r0,0x18
080899C2  00004826  ldr       r0,[0x8089A5C]
080899C4  000000BC  lsl       r4,r7,0x2
080899C6  000019E4  add       r4,r4,r7
080899C8  000000E4  lsl       r4,r4,0x3
080899CA  00001824  add       r4,r4,r0
080899CC  00008125  strh      r5,[r4,0x8]
080899CE  0000466B  mov       r3,sp
080899D0  0000899B  ldrh      r3,[r3,0xC]
080899D2  00008163  strh      r3,[r4,0xA]
080899D4  00002080  mov       r0,0x80
080899D6  00000040  lsl       r0,r0,0x1
080899D8  00009906  ldr       r1,[sp,0x18]
080899DA  0000F156  bl        <setup>
080899DC  0000FF0D  bl        0x81E07F8
080899DE  000081A0  strh      r0,[r4,0xC]
080899E0  00002000  mov       r0,0x0
080899E2  000081E0  strh      r0,[r4,0xE]
080899E4  00004641  mov       r1,r8
080899E6  00008221  strh      r1,[r4,0x10]
080899E8  00008261  strh      r1,[r4,0x12]
080899EA  0000464B  mov       r3,r9
080899EC  000082A3  strh      r3,[r4,0x14]
080899EE  00004650  mov       r0,r10
080899F0  000082E0  strh      r0,[r4,0x16]
080899F2  0000481B  ldr       r0,[0x8089A60]
080899F4  00007607  strb      r7,[r0,0x18]
080899F6  0000481B  ldr       r0,[0x8089A64]
080899F8  00002100  mov       r1,0x0
080899FA  00007001  strb      r1,[r0,0x0]
080899FC  00004C1A  ldr       r4,[0x8089A68]
080899FE  00009B03  ldr       r3,[sp,0xC]
08089A00  00001B5E  sub       r6,r3,r5
08089A02  00000633  lsl       r3,r6,0x18
08089A04  00000E1B  lsr       r3,r3,0x18
08089A06  00001C20  mov       r0,r4
08089A08  00009906  ldr       r1,[sp,0x18]
08089A0A  00009A07  ldr       r2,[sp,0x1C]
08089A0C  0000F7FF  bl        <setup>
08089A0E  0000FF76  bl        0x80898FC
08089A10  00009803  ldr       r0,[sp,0xC]
08089A12  00004285  cmp       r5,r0
08089A14  0000DA13  bge       0x8089A3E
08089A16  00004915  ldr       r1,[0x8089A6C]
08089A18  00001862  add       r2,r4,r1
08089A1A  00000069  lsl       r1,r5,0x1
08089A1C  000023F0  mov       r3,0xF0
08089A1E  000000DB  lsl       r3,r3,0x3
08089A20  000018C8  add       r0,r1,r3
08089A22  00001883  add       r3,r0,r2
08089A24  00001889  add       r1,r1,r2
08089A26  00001C22  mov       r2,r4
08089A28  00001C35  mov       r5,r6
08089A2A  00008810  ldrh      r0,[r2,0x0]
08089A2C  00008008  strh      r0,[r1,0x0]
08089A2E  00008810  ldrh      r0,[r2,0x0]
08089A30  00008018  strh      r0,[r3,0x0]
08089A32  00003202  add       r2,0x2
08089A34  00003302  add       r3,0x2
08089A36  00003102  add       r1,0x2
08089A38  00003D01  sub       r5,0x1
08089A3A  00002D00  cmp       r5,0x0
08089A3C  0000D1F5  bne       0x8089A2A
08089A3E  00001C38  mov       r0,r7
08089A40  0000B008  add       sp,0x20
08089A42  0000BC38  pop       {r3,r4,r5}
08089A44  00004698  mov       r8,r3
08089A46  000046A1  mov       r9,r4
08089A48  000046AA  mov       r10,r5
08089A4A  0000BCF0  pop       {r4,r5,r6,r7}
08089A4C  0000BC02  pop       {r1}
08089A4E  00004708  bx        r1
08089A50  00000010  lsl       r0,r2,0x0
08089A52  00000400  lsl       r0,r0,0x10
08089A54  00000001  lsl       r1,r0,0x0
08089A56  0000A260  add       r2,=0x8089BD8
08089A58  00009735  str       r7,[sp,0xD4]
08089A5A  00000808  lsr       r0,r1,0x0
08089A5C  00004B20  ldr       r3,[0x8089AE0]
08089A5E  00000300  lsl       r0,r0,0xC
08089A60  00004DC0  ldr       r5,[0x8089D64]
08089A62  00000300  lsl       r0,r0,0xC
08089A64  0000FFA4  bl        0x838A9AE
08089A66  00000202  lsl       r2,r0,0x8
08089A68  00005060  str       r0,[r4,r1]
08089A6A  00000300  lsl       r0,r0,0xC
08089A6C  0000FD80  bl        0x838A56E
08089A6E  0000FFFF  bl        0x7E0AA6E
08089A70  0000B500  push      {lr}