gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Beginners > Emulator compatibility

#176450 - GLaDOS - Fri Jul 29, 2011 5:45 am

According to Dwedit, my game fails to run on NO$GBA but works on VBA. What are the differences between emulators that cause a game to fail on one particular version? How can I fix it?

#176454 - Dwedit - Fri Jul 29, 2011 6:58 am

In the copy I have, some offending code at 080031A4 reads some pointer (03007B70), which is an address within the stack, then clobbers a return address with a zero value. Then it later tries to return from a function, and returns to address 0, crashing the game.

What's really weird is that this is all in the Division code generated by the compiler, screwing up the stack and returning to a null address.

Code:


080030ec <__aeabi_ldivmod>:
 80030ec:   e3530000    cmp   r3, #0
 80030f0:   03520000    cmpeq   r2, #0
 80030f4:   1a000006    bne   8003114 <__aeabi_ldivmod+0x28>
 80030f8:   e3510000    cmp   r1, #0
 80030fc:   03500000    cmpeq   r0, #0
 8003100:   b3a01102    movlt   r1, #-2147483648   ; 0x80000000
 8003104:   b3a00000    movlt   r0, #0
 8003108:   c3e01102    mvngt   r1, #-2147483648   ; 0x80000000
 800310c:   c3e00000    mvngt   r0, #0
 8003110:   ea001463    b   80082a4 <____aeabi_ldiv0_from_arm>
 8003114:   e24dd008    sub   sp, sp, #8
 8003118:   e92d6000    push   {sp, lr}   @This is strange, why does it save the stack pointer?
 800311c:   eb001473    bl   80082f0 <____gnu_ldivmod_helper_from_arm>
 8003120:   e59de004    ldr   lr, [sp, #4]
 8003124:   e28dd008    add   sp, sp, #8
 8003128:   e8bd000c    pop   {r2, r3}
 800312c:   e12fff1e    bx   lr   @dies here after it returns to an invalid address.

...

0800317c <__gnu_ldivmod_helper>:
 800317c:   b5f0         push   {r4, r5, r6, r7, lr}
 800317e:   b083         sub   sp, #12
 8003180:   1c1d         adds   r5, r3, #0
 8003182:   1c14         adds   r4, r2, #0
 8003184:   9000         str   r0, [sp, #0]
 8003186:   9101         str   r1, [sp, #4]
 8003188:   f001 f832    bl   80041f0 <__divdi3>
 800318c:   1c06         adds   r6, r0, #0
 800318e:   1c0f         adds   r7, r1, #0
 8003190:   1c32         adds   r2, r6, #0
 8003192:   1c3b         adds   r3, r7, #0
 8003194:   1c29         adds   r1, r5, #0
 8003196:   1c20         adds   r0, r4, #0
 8003198:   f7ff ffca    bl   8003130 <__aeabi_lmul>
 800319c:   9a00         ldr   r2, [sp, #0]
 800319e:   9b01         ldr   r3, [sp, #4]
 80031a0:   1a12         subs   r2, r2, r0
 80031a2:   418b         sbcs   r3, r1
 80031a4:   9908         ldr   r1, [sp, #32]  @reads the previous stack pointer
 80031a6:   600a         str   r2, [r1, #0]
 80031a8:   604b         str   r3, [r1, #4]   @clobbers the return address and replaces it with 00000000
 80031aa:   b003         add   sp, #12
 80031ac:   1c30         adds   r0, r6, #0
 80031ae:   1c39         adds   r1, r7, #0
 80031b0:   bcf0         pop   {r4, r5, r6, r7}
 80031b2:   bc04         pop   {r2}
 80031b4:   4710         bx   r2
 80031b6:   46c0         nop         ; (mov r8, r8)


It appears that NO$GBA and VBA emulate the Push SP instruction differently.

VisualBoyAdvance pushes the value 03007B78 onto the stack, and NO$GBA pushes the value 03007B70 onto the stack. So it clobbers the return address in NO$GBA, but not in VisualBoyAdvance.

As for why code would push the stack pointer onto the stack, that's up for debate. Is this a bug in GCC?
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#176456 - GLaDOS - Fri Jul 29, 2011 7:19 am

What about Windows vs Linux version of VBA-M?

When I try to run it in my Ubuntu VM, it doesn't crash, but there's tons of graphical glitches and random stuff so it's not actually playable. Someone told me that the Linux version is more accurate than the Windows version.

#177458 - Grieverz - Mon Jun 11, 2012 3:19 pm

I have similar issue, so I won't create new topic.
http://pastie.org/4057436 - sourcecode
So, this small piece of code does not work on vba 1.7.2, 1.7.1, though it runs ok on no$gba or vba-m (both linux and win). This is compiled with standard recommended TONC makefile and I've tried to change all compilation keys, it uses. I've also tried to change DKP toolchain (versions and base platform win/linux).
This is a part of my small project http://griever.magicteam.net/files/CrackMe_byGriever.gba - it just adds a few other source and data files, which are (as you can see) not a problem. Guess, the problem is in init code.
How can it be fixed?

#177468 - sgeos - Sat Jun 16, 2012 1:29 pm

GLaDOS wrote:
According to Dwedit, my game fails to run on NO$GBA but works on VBA. What are the differences between emulators that cause a game to fail on one particular version?

Different emulators have different accuracy levels and bugs.

GLaDOS wrote:
How can I fix it?

All final testing should be done on hardware. If your game works on hardware but not on a given emulator then you should double check your code. It may have a horrible bug that is magically working for you on hardware.

If you are 99.9% sure your code is good, your favorite emulator may have a bug so you may wish to use a different emulator when you do not want to test on hardware. If it works on any particular emulator but not on hardware, your code is simply broken and needs to be fixed.

#177469 - Dwedit - Sat Jun 16, 2012 7:49 pm

Someone bumped this thread, so I might as well post this:

This is a workaround for NO$GBA's stack bug, when using 64-bit division in your program. Doesn't fix anything else, just 64-bit division.
Copy this to a .s file, and include it in your project.

Code:

 .text
 .align
 .pool
 
 .global __aeabi_ldivmod
 .global __aeabi_uldivmod


__aeabi_ldivmod:
   cmp   r3, #0
   cmpeq   r2, #0
   bne   0f
   cmp   r1, #0
   cmpeq   r0, #0
   movlt   r1, #-2147483648   @ 0x80000000
   movlt   r0, #0
   mvngt   r1, #-2147483648   @ 0x80000000
   mvngt   r0, #0
   b   __aeabi_ldiv0
0:
   sub   sp, sp, #8
   mov r12,sp
   push   {r12, lr}
   bl   __gnu_ldivmod_helper
   ldr   lr, [sp, #4]
   add   sp, sp, #8
   pop   {r2, r3}
   bx   lr

__aeabi_uldivmod:
   cmp   r3, #0
   cmpeq   r2, #0
   bne   0f
   cmp   r1, #0
   cmpeq   r0, #0
   mvnne   r1, #0
   mvnne   r0, #0
   b   __aeabi_ldiv0
0:
   sub   sp, sp, #8
   mov r12,sp
   push   {r12, lr}
   bl   __gnu_uldivmod_helper
   ldr   lr, [sp, #4]
   add   sp, sp, #8
   pop   {r2, r3}
   bx   lr

_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."