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.

DS development > DSEMU 0.4.8 (Modulus - SWI 9) Bios call problem.

#61945 - winneymj - Fri Nov 25, 2005 5:17 pm

Hi,
I am fairly new to DS development but have been a C/ASM/JAVA program for some 15 years.
I am using DevKitPro/DevKitArm r17, DsEMU 0.4.8 and ndslib 20051018.
I have been having persistent problems with the Modulus (%) and divide (/) not returning back correct results.
Example (1 % 10) keeps returning 0, and as we all know it should return 1.
I traced/debugged the assember code to the SWI 9, bios call and here is what I am seeing.

R00 - loaded with numerator (example = 1)
R01 - loaded with divisor (example = 10)
Call made to SWI 9
R00 - now has 10
R01 - now has 0

According to documentation I found on the BIOS at ndslib, the SWI 9 call is supposed to return the remainder in R01 (see below), and should contain value 1, not zero. I am not sure the R00 register is correct either.

//////////////////////////////////////////////////////////////////////
//
// swi 0x09: Divide (returns result in r0, remainder in r1)
//
// int Divide(int numerator, int divisor);
// returns numerator / divisor
//
// int Remainder(int numerator, int divisor);
// returns numerator % divisor
//
// void DivMod(int numerator, int divisor, int * result, int * remainder);
// sets *result = numerator / divisor and remainder = numerator % divisor
//
//////////////////////////////////////////////////////////////////////

I saw from the DSEMU posts that 0.4.8, was to correct a SWI divide bug. What was the bug?

Thanks for anyhelp. This has been frustrating me for the last couple of weeks.

#61947 - Ethos - Fri Nov 25, 2005 6:02 pm

Hmmm...Java was released in 1994....max 11 years :P

11 years ago I was programming Mac II's with Pascal...lol
_________________
Ethos' Homepage (Demos/NDS 3D Tutorial)

#61961 - winneymj - Fri Nov 25, 2005 10:12 pm

Started with Pascal, ASM/ Followed by C, C++ and now Java.

#61984 - LOst? - Sat Nov 26, 2005 5:24 am

winneymj wrote:
Started with Pascal, ASM/ Followed by C, C++ and now Java.

I started with basic, then C, then C++, and now HTML.
My life is complete!
_________________
Exceptions are fun

#61990 - doublec - Sat Nov 26, 2005 7:38 am

winneymj wrote:

R00 - loaded with numerator (example = 1)
R01 - loaded with divisor (example = 10)
Call made to SWI 9
R00 - now has 10
R01 - now has 0

According to documentation I found on the BIOS at ndslib, the SWI 9 call is supposed to return the remainder in R01 (see below), and should contain value 1, not zero. I am not sure the R00 register is correct either.


Looking at the code in DSEmu it seems to be putting the data in R00 and R01 as expected. The x86 idiv instruction stores the remainder in EDX and the result in EAX (from http://nasm.sourceforge.net/doc/html/nasmdocb.html#section-B.4.117). The DSEmu code does:

Code:

                mov [arm9reg+0*4],eax
                mov [arm9reg+1*4],edx

This puts the remainder in R1 and the result in R0. This is correct I think. What is probably going wrong is that the intial register data is incorrect. DSEmu is expecting r1 to be divided by r0. Should it be the other way around? I don't have libnds handy to check how it sets it up for the call. I'll check later. The documentation you listed doesn't unfortunately list what registers should be setup for the call.

#62029 - wintermute - Sat Nov 26, 2005 5:55 pm

doublec wrote:

This puts the remainder in R1 and the result in R0. This is correct I think. What is probably going wrong is that the intial register data is incorrect. DSEmu is expecting r1 to be divided by r0. Should it be the other way around? I don't have libnds handy to check how it sets it up for the call. I'll check later. The documentation you listed doesn't unfortunately list what registers should be setup for the call.


Yes, it's the other way round.

http://nocash.emubase.de/gbatek.htm#biosarithmeticfunctions

#62041 - winneymj - Sat Nov 26, 2005 7:25 pm

After more playing I found that if I swap the operands of the modulus and Div it works, ok.
EXAMPLE:

1 % 10 gives wrong result
10 % 1 gives right result for 1 % 10

This seems to indicate the the registers used in the Modulus and Div are around the wrong way.
Looking the the responses above seems to also indicate this.
The only question I have now is, is it the compiler, or DSEMU?

Thanks

#62052 - wintermute - Sat Nov 26, 2005 10:42 pm

winneymj wrote:

The only question I have now is, is it the compiler, or DSEMU?

Thanks


See the previous two messages

#62065 - doublec - Sun Nov 27, 2005 2:48 am

Quote:
The only question I have now is, is it the compiler, or DSEMU?


Definitely DSEmu. I've fixed it and am pushing a patch through to the darcs repository now. If you are able to build from source this will fix it. If not let me know and I'll do a quick bug fix build.

Darcs repository details here:

http://www.double.co.nz/nintendo_ds/dsemu.html#source

Chris.

#62125 - winneymj - Sun Nov 27, 2005 5:36 pm

Quote:
Definitely DSEmu. I've fixed it and am pushing a patch through to the darcs repository now. If you are able to build from source this will fix it. If not let me know and I'll do a quick bug fix build.

Thanks for the help with the modulus problem. The response is great.
I have not been building from the source, so would appreciate a quick bug fix build. I do not want you to do this if it takes too much work, as I have a simple work around, swapping the operands, until you do a more formal release. I leave it up to you. If you think it warants a release go ahead.
And thanks once again for the quick response.