Giter Site home page Giter Site logo

jsmolka / eggvance Goto Github PK

View Code? Open in Web Editor NEW
64.0 4.0 1.0 3 MB

A Game Boy Advance emulator.

Home Page: https://smolka.dev/tags/eggvance

License: GNU General Public License v3.0

C++ 99.48% CMake 0.52%
cpp eggvance gba emulator game-boy-advance

eggvance's People

Contributors

jsmolka avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

matanlurey

eggvance's Issues

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

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}

Mother 3: Softlock when sleeping

The game softlocks when trying to sleep (cannot exit anymore).

mother3

Same thing happens with mGBA. Pressing L + R + A resumes the game. The time until unpaused is much longer compared to mGBA. Not sure if that is an emulator bug.

Export the assembly code

After lurking a bit with the source code I saw the disassembler and that if I decomment disasm() in arm.cpp I get the assembly code on sheel so I can generate a file.

The problem is that is generating the one in that moment, I was looking to get the full code of a rom.

Do you think that is possible to add a parameter that export the code with the memory address?

Celeste: audio cracking on the right ear

There is a periodic on the right side. Happened somewhere between master commit 997 and 1014.

Similar noise happens in Top Gun - Combat Zones on the left side.

Regression since this commit: 82709d9

It happens consistently every ~2 seconds.

Was caused by effectively running late twice in the timer event.

Golden Sun layering issue

Golden.Sun.USA.Europe (1).zip
image
the carpet is occluding the character sprites, which obviously shouldn't happen.
Golden Sun makes clever usage of OBJ rendering behavior, that isn't properly documented in GBATEK.
It uses transparent OBJs to hijack the priority of the character OBJs.

This works because:

  1. OBJs are rendered in forward order
  2. higher priority OBJ pixels always update the OBJ buffer priority, even if the pixel transparent.
  3. lower priority OBJ pixels always write the OBJ buffer if it's currently transparent.

save file is courtesy of benderscuffy.

Gunstar Super Heroes (U) sprite priority issues

image
this game is notorious for rendering incorrectly in many emulators.
the solution is simple: account for the per-scanline maximum cycle count for OBJs (as mentioned in GBATEK) and skip remaining OBJs / pixels if the limit is hit.

EDIT: if you don't do that yet, you also need to render OBJs in forward order.

Castlevania - Aria of Sorrow: Garbage values when entering the menu

They show for a small amount of time before proceeding into the menu.

castle menu

DMAs shortly after hitting start in the first room:

Click
3  0  02011DDC -> 020121DC 256
3  0  0201261C -> 02012A1C 256
3  0  03002C60 -> 04000008 20
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768
3  0  03002C60 -> 02000070 2
3  0  03002C98 -> 02000078 4
3  0  03001458 -> 02011088 320
3  0  0200FEC4 -> 02010008 80
3  0  02011070 -> 02011078 2
3  0  02025468 -> 02010154 7
3  0  020115C8 -> 020115D0 4
3  0  020115D8 -> 020119D8 512
3  0  03007EA4 -> 020115C8 4
3  0  020123E4 -> 02012500 142
3  0  03007E9C -> 020123E4 142
3  0  02012C24 -> 02012D40 142
3  0  03007E9C -> 02012C24 142
3  0  02011DDC -> 02011FDC 256
3  0  0201261C -> 0201281C 256
3  0  02012E60 -> 02012F20 96
3  0  03007E9C -> 02012E60 96
3  0  02011DDC -> 020121DC 256
3  0  0201261C -> 02012A1C 256
3  0  03002C60 -> 04000008 20
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768
3  0  080E5C38 -> 0201261C 256
3  0  020153F8 -> 06000000 4096

DMAs shortly after hitting start in the second room:

Click
0  2  02007876 -> 04000010 1
3  0  0811A7D8 -> 020126DC 16
0  2  02007878 -> 04000010 1
0  2  0200787A -> 04000010 1
0  2  0200787C -> 04000010 1
0  2  0200787E -> 04000010 1
0  2  02007880 -> 04000010 1
0  2  02007882 -> 04000010 1
0  2  02007884 -> 04000010 1
0  2  02007886 -> 04000010 1
0  2  02007888 -> 04000010 1
0  2  0200788A -> 04000010 1
0  2  0200788C -> 04000010 1
0  2  0200788E -> 04000010 1
0  2  02007890 -> 04000010 1
3  0  03007E1C -> 020016F0 33
0  2  02007892 -> 04000010 1
0  2  02007894 -> 04000010 1
3  0  03007E20 -> 020034D8 33
0  2  02007896 -> 04000010 1
0  2  02007898 -> 04000010 1
0  2  0200789A -> 04000010 1
0  2  0200789C -> 04000010 1
0  2  0200789E -> 04000010 1
0  2  020078A0 -> 04000010 1
0  2  020078A2 -> 04000010 1
0  2  020078A4 -> 04000010 1
0  2  020078A6 -> 04000010 1
0  2  020078A8 -> 04000010 1
0  2  020078AA -> 04000010 1
0  2  020078AC -> 04000010 1
0  2  020078AE -> 04000010 1
0  2  020078B0 -> 04000010 1
0  2  020078B2 -> 04000010 1
0  2  020078B4 -> 04000010 1
0  2  020078B6 -> 04000010 1
0  2  020078B8 -> 04000010 1
0  2  020078BA -> 04000010 1
0  2  020078BC -> 04000010 1
0  2  020078BE -> 04000010 1
0  2  020078C0 -> 04000010 1
0  2  020078C2 -> 04000010 1
0  2  020078C4 -> 04000010 1
0  2  020078C6 -> 04000010 1
0  2  020078C8 -> 04000010 1
0  2  020078CA -> 04000010 1
0  2  020078CC -> 04000010 1
0  2  020078CE -> 04000010 1
0  2  020078D0 -> 04000010 1
0  2  020078D2 -> 04000010 1
0  2  020078D4 -> 04000010 1
0  2  020078D6 -> 04000010 1
0  2  020078D8 -> 04000010 1
0  2  020078DA -> 04000010 1
0  2  020078DC -> 04000010 1
0  2  020078DE -> 04000010 1
0  2  020078E0 -> 04000010 1
0  2  020078E2 -> 04000010 1
0  2  020078E4 -> 04000010 1
0  2  020078E6 -> 04000010 1
0  2  020078E8 -> 04000010 1
0  2  020078EA -> 04000010 1
0  2  020078EC -> 04000010 1
0  2  020078EE -> 04000010 1
0  2  020078F0 -> 04000010 1
0  2  020078F2 -> 04000010 1
0  2  020078F4 -> 04000010 1
0  2  020078F6 -> 04000010 1
0  2  020078F8 -> 04000010 1
0  2  020078FA -> 04000010 1
0  2  020078FC -> 04000010 1
0  2  020078FE -> 04000010 1
0  2  02007900 -> 04000010 1
0  2  02007902 -> 04000010 1
0  2  02007904 -> 04000010 1
0  2  02007906 -> 04000010 1
0  2  02007908 -> 04000010 1
3  0  02011DDC -> 020121DC 256
0  2  0200790A -> 04000010 1
3  0  0201261C -> 02012A1C 256
0  2  0200790C -> 04000010 1
0  2  0200790E -> 04000010 1
0  2  02007910 -> 04000010 1
0  2  02007912 -> 04000010 1
0  2  02007914 -> 04000010 1
0  2  02007916 -> 04000010 1
0  2  02007918 -> 04000010 1
0  2  0200791A -> 04000010 1
0  2  0200791C -> 04000010 1
0  2  0200791E -> 04000010 1
0  2  02007920 -> 04000010 1
0  2  02007922 -> 04000010 1
0  2  02007924 -> 04000010 1
0  2  02007926 -> 04000010 1
0  2  02007928 -> 04000010 1
0  2  0200792A -> 04000010 1
0  2  0200792C -> 04000010 1
0  2  0200792E -> 04000010 1
0  2  02007930 -> 04000010 1
0  2  02007932 -> 04000010 1
0  2  02007934 -> 04000010 1
0  2  02007936 -> 04000010 1
0  2  02007938 -> 04000010 1
0  2  0200793A -> 04000010 1
0  2  0200793C -> 04000010 1
0  2  0200793E -> 04000010 1
0  2  02007940 -> 04000010 1
0  2  02007942 -> 04000010 1
0  2  02007944 -> 04000010 1
0  2  02007946 -> 04000010 1
0  2  02007948 -> 04000010 1
0  2  0200794A -> 04000010 1
0  2  0200794C -> 04000010 1
0  2  0200794E -> 04000010 1
0  2  02007950 -> 04000010 1
0  2  02007952 -> 04000010 1
0  2  02007954 -> 04000010 1
0  2  02007956 -> 04000010 1
0  2  02007958 -> 04000010 1
0  2  0200795A -> 04000010 1
0  2  0200795C -> 04000010 1
0  2  0200795E -> 04000010 1
0  2  02007960 -> 04000010 1
0  2  02007962 -> 04000010 1
0  2  02007964 -> 04000010 1
0  2  02007966 -> 04000010 1
0  2  02007968 -> 04000010 1
0  2  0200796A -> 04000010 1
0  2  0200796C -> 04000010 1
0  2  0200796E -> 04000010 1
0  2  02007970 -> 04000010 1
0  2  02007972 -> 04000010 1
0  2  02007974 -> 04000010 1
0  2  02007976 -> 04000010 1
0  2  02007978 -> 04000010 1
0  2  0200797A -> 04000010 1
0  2  0200797C -> 04000010 1
0  2  0200797E -> 04000010 1
0  2  02007980 -> 04000010 1
0  2  02007982 -> 04000010 1
0  2  02007984 -> 04000010 1
0  2  02007986 -> 04000010 1
0  2  02007988 -> 04000010 1
0  2  0200798A -> 04000010 1
0  2  0200798C -> 04000010 1
0  2  0200798E -> 04000010 1
0  2  02007990 -> 04000010 1
0  2  02007992 -> 04000010 1
0  2  02007994 -> 04000010 1
0  2  02007996 -> 04000010 1
0  2  02007998 -> 04000010 1
0  2  0200799A -> 04000010 1
0  2  0200799C -> 04000010 1
0  2  0200799E -> 04000010 1
0  2  020079A0 -> 04000010 1
0  2  020079A2 -> 04000010 1
0  2  020079A4 -> 04000010 1
0  2  020079A6 -> 04000010 1
0  2  020079A8 -> 04000010 1
0  2  020079AA -> 04000010 1
0  2  020079AC -> 04000010 1
3  0  03002C60 -> 04000008 20
3  0  0200786C -> 04000010 1
3  0  02012A1C -> 05000000 256
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768

NanoBoy in the first room:

Click
3  0  03002C60 -> 04000008 20
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768
3  0  03002C60 -> 02000070 2
3  0  03002C98 -> 02000078 4
3  0  03001458 -> 02011088 320
3  0  0200FEC4 -> 02010008 80
3  0  02011070 -> 02011078 2
3  0  02025468 -> 02010154 7
3  0  020115C8 -> 020115D0 4
3  0  020115D8 -> 020119D8 512
3  0  03007EA4 -> 020115C8 4
3  0  020123E4 -> 02012500 142
3  0  03007E9C -> 020123E4 142
3  0  02012C24 -> 02012D40 142
3  0  03007E9C -> 02012C24 142
3  0  02011DDC -> 02011FDC 256
3  0  0201261C -> 0201281C 256
3  0  020127CE -> 020129CE 39
3  0  02012E60 -> 02012F20 96
3  0  03007E9C -> 02012E60 96
3  0  02011DDC -> 020121DC 256
3  0  0201261C -> 02012A1C 256
3  0  03002C60 -> 04000008 20
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768
3  0  080E5C38 -> 0201261C 256
3  0  020153F8 -> 06000000 4096
3  0  02016B82 -> 0600178A 1083
3  0  020153F8 -> 0600A000 4096
3  0  02016662 -> 0600B26A 1739
3  0  020153F8 -> 06010200 256
3  0  020155F8 -> 06010600 256
3  0  020157F8 -> 06010A00 256
3  0  020159F8 -> 06010E00 256
3  0  02015BF8 -> 06011200 256
3  0  02015DF8 -> 06011600 256
3  0  02015FF8 -> 06011A00 256
3  0  020161F8 -> 06011E00 256
3  0  020163F8 -> 06012200 256
3  0  020165F8 -> 06012600 256
3  0  020167F8 -> 06012A00 256
3  0  020169F8 -> 06012E00 256
3  0  02016BF8 -> 06013200 256
3  0  02016DF8 -> 06013600 256
3  0  02016FF8 -> 06013A00 256
3  0  020171F8 -> 06013E00 256
3  0  0820C318 -> 02011F1C 16
3  0  0820C338 -> 02011F3C 16
3  0  0820C358 -> 02011F5C 16
3  0  0820C2F8 -> 02011F7C 16
3  0  0820C2D8 -> 02011F9C 16

NanoBoy in the second room:

Click
3  0  03002C60 -> 04000008 20
3  0  0200786C -> 04000010 1
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768
0  2  0200786E -> 04000010 1
0  2  02007870 -> 04000010 1
0  2  02007872 -> 04000010 1
0  2  02007874 -> 04000010 1
0  2  02007876 -> 04000010 1
0  2  02007878 -> 04000010 1
0  2  0200787A -> 04000010 1
3  0  03002C60 -> 02000070 2
3  0  03002C98 -> 02000078 4
0  2  0200787C -> 04000010 1
3  0  03001458 -> 02011088 320
0  2  0200787E -> 04000010 1
3  0  030016BC -> 020112EC 167
0  2  02007880 -> 04000010 1
3  0  0200FEC4 -> 02010008 80
3  0  02011070 -> 02011078 2
3  0  02025468 -> 02010154 7
0  2  02007882 -> 04000010 1
3  0  02025478 -> 02010164 3
0  2  02007884 -> 04000010 1
3  0  020115C8 -> 020115D0 4
0  2  02007886 -> 04000010 1
3  0  020115D8 -> 020119D8 512
0  2  02007888 -> 04000010 1
3  0  0201176A -> 02011B6A 311
0  2  0200788A -> 04000010 1
3  0  02011904 -> 02011D04 106
3  0  03007EA4 -> 020115C8 4
3  0  020123E4 -> 02012500 142
0  2  0200788C -> 04000010 1
3  0  0201246C -> 02012588 74
3  0  03007E9C -> 020123E4 142
3  0  02012C24 -> 02012D40 142
0  2  0200788E -> 04000010 1
3  0  02012C42 -> 02012D5E 127
3  0  03007E9C -> 02012C24 142
0  2  02007890 -> 04000010 1
3  0  03007E9C -> 02012D02 31
3  0  02011DDC -> 02011FDC 256
0  2  02007892 -> 04000010 1
3  0  02011F2E -> 0201212E 87
3  0  0201261C -> 0201281C 256
0  2  02007894 -> 04000010 1
3  0  020126E4 -> 020128E4 156
3  0  02012E60 -> 02012F20 96
0  2  02007896 -> 04000010 1
3  0  02012EA0 -> 02012F60 64
3  0  03007E9C -> 02012E60 96
0  2  02007898 -> 04000010 1
0  2  0200789A -> 04000010 1
0  2  0200789C -> 04000010 1
0  2  0200789E -> 04000010 1
0  2  020078A0 -> 04000010 1
0  2  020078A2 -> 04000010 1
0  2  020078A4 -> 04000010 1
0  2  020078A6 -> 04000010 1
0  2  020078A8 -> 04000010 1
0  2  020078AA -> 04000010 1
3  0  02011DDC -> 020121DC 256
0  2  020078AC -> 04000010 1
3  0  02011EFC -> 020122FC 112
3  0  0201261C -> 02012A1C 256
0  2  020078AE -> 04000010 1
3  0  020126B0 -> 02012AB0 182
0  2  020078B0 -> 04000010 1
3  0  03002C60 -> 04000008 20
3  0  03000C58 -> 07000000 256
3  0  03007EDC -> 03000C58 512
3  0  03007EDC -> 03000058 768
3  0  080E5C38 -> 0201261C 256
3  0  020153F8 -> 06000000 4096
3  0  020153F8 -> 0600A000 4096
3  0  0201662E -> 0600B236 1765
3  0  020153F8 -> 06010200 256
3  0  020155F8 -> 06010600 256
3  0  020157F8 -> 06010A00 256
3  0  020159F8 -> 06010E00 256
3  0  02015BF8 -> 06011200 256
3  0  02015DF8 -> 06011600 256
3  0  02015FF8 -> 06011A00 256
3  0  020161F8 -> 06011E00 256
3  0  020163F8 -> 06012200 256
3  0  020165F8 -> 06012600 256
3  0  020167F8 -> 06012A00 256
3  0  020169F8 -> 06012E00 256
3  0  02016BF8 -> 06013200 256
3  0  02016DF8 -> 06013600 256
3  0  02016FF8 -> 06013A00 256
3  0  020171F8 -> 06013E00 256
3  0  0820C318 -> 02011F1C 16
3  0  0820C338 -> 02011F3C 16
3  0  0820C358 -> 02011F5C 16
3  0  0820C2F8 -> 02011F7C 16
3  0  0820C2D8 -> 02011F9C 16

Golden Sun: Intro sound is worse compared to sequel

The Nintendo intro bleep (channel 1) is way worse compared to Golden Sun - The Lost Age.

Game A writes to channel 1:

800008000000
878244800008
87C294800008
87C224800008
80C208800008

Game B writes to channel 1:

800008000000
878254800008
87C294800008
87C224800008
80C208800008

The frequence is slightly different but the bad sound persists even when forcing the value to 0x54.


The written data results in the following sequence:

Game A:

Sq1: form 0 | frequency 0
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0
Sq1: form 2 | frequency 1922
Env: volume 4 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 3
Sq1: form 2 | frequency 1986
Env: volume 9 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 8
Env: volume 7
Env: volume 6
Env: volume 5
Env: volume 4
Env: volume 3
Env: volume 2
Sq1: form 2 | frequency 1986
Env: volume 2 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 1
Env: volume 0
Sq1: form 2 | frequency 194
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0

Game B:

Sq1: form 0 | frequency 0
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0
Sq1: form 2 | frequency 1922
Env: volume 5 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 4
Sq1: form 2 | frequency 1986
Env: volume 9 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 8
Env: volume 7
Env: volume 6
Env: volume 5
Env: volume 4
Env: volume 3
Env: volume 2
Sq1: form 2 | frequency 1986
Env: volume 2 | timer 4 | increase 0
Len: timer 64 | expire 0
Env: volume 1
Env: volume 0
Sq1: form 2 | frequency 194
Env: volume 0 | timer 0 | increase 1
Len: timer 64 | expire 0

The output should be almost identical so I suspect this to be a resampling problem.


Both games still have different sound output when removing external things like BIAS and even hardcoding the frequency.


It appears that halting causes the problem. A uses halting while B doesn't. Removing the halt state in A fixes the audio problems. Halting the CPU results in single runs of 960 cycles which cause the sample function in the APU to run twice sometimes. Although this shouldn't be a problem, it is. Splitting the run function into single parts fixes the issue.

uint visible = 160;
while (visible--)
{
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run(100);
    arm.run( 60);
    ppu.scanline();
    ppu.hblank();
    arm.run(100);
    arm.run(100);
    arm.run( 72);
    ppu.next();
}

Running 960 at once also ticks the sequencer 960 times. The square channel calculated it's values and this value is now samples twice with the intermediate step missing.

Final Fantasy VI Advance: Continuous typing sound during intro

There is a continuous typing sound during the intro even when there shouldn't be any sound at all.

The sound is produced by square 1.

Writes to the channel:

3  0000'0000'0800'0000
5  0000'8000'0800'0000
0  0000'8000'0800'0008
2  0000'8000'0800'0008
4  0000'80E4'0800'0008
5  0000'04E4'0800'0008
3  0000'04E4'0800'0008
5  0000'84E4'0800'0008
3  0000'84E4'0800'0008
5  0000'80E4'0800'0008
0  0000'80E4'0800'0008
2  0000'80E4'0800'0008
4  0000'80E4'0800'0008
-------------------------- should end around here
5  0000'04E4'0800'0008
3  0000'04E4'0800'0008
5  0000'84E4'0800'0008
3  0000'84E4'0800'0008
5  0000'80E4'0800'0008
0  0000'80E4'0800'001F
1  0000'80E4'0800'001F
2  0000'80E4'083F'001F
3  0000'80E4'2F3F'001F
4  0000'8000'2F3F'001F
5  0000'0000'2F3F'001F

Mega Man Zero: No sound

It uses FIFO_A for sound and reads from 0x0202F0F0 with DMA1. The timer properly triggers but the FIFO gets filled with zeros all the time.

ANDS instruction has no effect on C flag

mov r1, #0x80000000
mov r4, #0x1
ands r0, r1, r1, lsl r4

I think the state of cpsr after execute arm code above is : [N:0, Z: 1, C: 1, V:0] --> 0x6
But I found that eggvance give me: [N:0, Z: 1, C: 0, V:0] --> 0x4

After some code tracing, There is a piece of code make me confuse:

src/arm/instr_arm.cpp, line 75 :

constexpr bool kLogical = 
           kOpcode == kOpcodeAdd // ?
        || kOpcode == kOpcodeEor
        || kOpcode == kOpcodeOrr
        || kOpcode == kOpcodeMov
        || kOpcode == kOpcodeBic
        || kOpcode == kOpcodeMvn
        || kOpcode == kOpcodeTst
        || kOpcode == kOpcodeTeq;

Do you mean KOpcodeAnd?

Attribute NanoboyAdvance

It always seemed to me that eggvance has taken strong inspiration from NanoboyAdvance from the get go.
The latest case, the RTC implementation, is a clear case to me. The code is pretty much the exact same except for some minor naming and style differences and fewer comments. It follows the exact same structure and logic.

NanoboyAdvance:
https://github.com/fleroviux/NanoboyAdvance/blob/master/source/emulator/cartridge/gpio/rtc.cpp

eggvance:
https://github.com/jsmolka/eggvance/blob/d925e80d3cc11ca043fbdc896524fba787a3226b/eggvance/src/gamepak/rtc.cpp

In the past I've looked over this because a) NanoboyAdvance was credited to some extent in the README (while now any credit is gone) and b) it was less clear cut that some code is a direct copy of mine instead of merely being inspired.

Therefore I kindly ask to add proper attribution.

BIOS intro: bad sound

The last bleep in the BIOS intro sounds distorted / metallic. This can be fixed by splitting the long arm.run(960) into smaller 100 cycle chunks (see #14). The sound is provided by the FIFO so it's most likely a timer issue.


The bug is caused by the current layout of the tick function.

void Arm::tick(int cycles)
{
    this->cycles -= cycles;

    if (state & kStateTimer)
        timer.run(cycles);

    if (irq.delaying)
    {
        irq.delay -= cycles;

        if (irq.delay < 0)
            irq.delay = 0;
    }

    apu.run(cycles);
}

Running the timer first with large values skipped some samples and caused the metallic sound. Running 100 cycles max each step reduced that probability and mitigated the bug. Another way to do this is switching the timer.run and apu.run positions. I will solve this bug with the upcoming scheduler.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.