What's new

Porting Mupen64Plus to Android

OP
paulscode

paulscode

New member
Ari64, thanks again for the help! I am currently on vacation for a couple of weeks, so I don't have access to my pc at the moment, but I've been digging around in your sourcecode from my phone to find the components you mentioned.

For the constant propagation issue, which file(s)/function(s) do I need to be looking in for that? I found the functions "get_const" and "load_all_consts" in new_dynarec.c, but not sure if these are the places you were referring to, as the code is a bit over my head at the moment. I'll take a closer look at them to try and figure out how they work, if these are the right sections.

For the unsigned offset bug in assem_arm.c's verify_dirty and get_bounds functions, I assume the following minor change would correct that problem:
Code:
  int offset=*ptr&0xfff;  // CHANGED FROM: u_int offset=*ptr&0xfff;
  u_int *l_ptr=(void *)ptr+offset+8;
  u_int source=l_ptr[0];
  u_int copy=l_ptr[1];
  u_int len=l_ptr[2];
Or is it a bit more complicated than that? Also, does this bug only affect ARMv5? It seems from the ARMv7 code that the offset is added to other values before the result is cast to an unsigned int, so I think it should work as is (I'll have to verify that when I get home, though):
Code:
  u_int source=(ptr[0]&0xFFF)+((ptr[0]>>4)&0xF000)+((ptr[2]<<16)&0xFFF0000)+((ptr[2]<<12)&0xF0000000);
 

Ari64

New member
Ari64, thanks again for the help! I am currently on vacation for a couple of weeks, so I don't have access to my pc at the moment, but I've been digging around in your sourcecode from my phone to find the components you mentioned.

Notaz ported the dynarec to PCSX (Playstation emulator) and found a couple of issues. One was that branch offsets are signed but in two cases I made them unsigned (oops). This should fix it:
Code:
--- a/libpcsxcore/new_dynarec/assem_arm.c
+++ b/libpcsxcore/new_dynarec/assem_arm.c
@@ -205,7 +205,7 @@ int verify_dirty(int addr)
   #endif
   if((*ptr&0xFF000000)!=0xeb000000) ptr++;
   assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
-  u_int verifier=(int)ptr+((*ptr<<8)>>6)+8; // get target of bl
+  u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl
   if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
     unsigned int page=source>>12;
     unsigned int map_value=memory_map[page];
@@ -258,7 +258,7 @@ void get_bounds(int addr,u_int *start,u_int *end)
   #endif
   if((*ptr&0xFF000000)!=0xeb000000) ptr++;
   assert((*ptr&0xFF000000)==0xeb000000); // bl instruction
-  u_int verifier=(int)ptr+((*ptr<<8)>>6)+8; // get target of bl
+  u_int verifier=(int)ptr+((signed int)(*ptr<<8)>>6)+8; // get target of bl
   if(verifier==(u_int)verify_code_vm||verifier==(u_int)verify_code_ds) {
     if(memory_map[source>>12]>=0x80000000) source = 0;
     else source = source+(memory_map[source>>12]<<2);

For the constant propagation issue, which file(s)/function(s) do I need to be looking in for that?
For loads that go to fixed memory addresses between 80000000 and 807FFFFF, the normal pagetables are bypassed and it loads from the precalculated memory address. If the RAM is somewhere other than 0x80000000, then you'll need to adjust this address. This happens in get_final_value() and address_generation(), but it's probably easier to understand what's happening if you turn on the debugging output and look at the code that it generates.

I won't have a lot of time to work on mupen64plus until after the holidays, but I wanted to mention that in case it was causing problems for you.
 
OP
paulscode

paulscode

New member
Awesome, I'll look at those sections when I get home (and the debug output as well). I appreciate the help!
 

HD2MAX

New member
Hi, I wanted to thank you for working on this project for android, is an emulator we need in this system that is in continuous evolution and growth, are also working on nullDC which already shows some games and it looks very promising

also now beginning to leave the new smartphones with Nvidia Tegra2 dual core, we will have a great capacity for emulation.

I just wanted to thank everyone, and a lot of spirit.

Happy New Year
 

Cpasjuste

New member
Well, i did try everything i can think off without success. The rdram memory (0x800xx) seems to be well allocated and same for dynarec (0x700xx). The problem like you said seems to be the xlinker init flag not working ...

Maybe i could take a look at what you'v done so far and vice-versa, here's my mail if needed : cpasjuste AT gmail.com
 

maxohkc

New member
Sure, I'll send you my project in its current form when I get home in a couple days.

just found this thread and am super excited. Development was dropped by zodttd I'm pretty sure, so i think you are our last hope. Look forward to purchasing this! is there any news!!!!
 
OP
paulscode

paulscode

New member
Hey, sorry for the late response. I recently found out I will be going on a deployment in March, so with all the paperwork and stuff I haven't had much time for programming since I got back from leave. Thankfully I will be able to take my netbook and phone with me on this one, so I can continue development whenever I have free time (a bit more ghetto than using a real computer, but I've got all the software set up on there that I'll need).

I've uploaded the Eclipse project in its current form, since I've had three people so far ask me for it. Sorry I haven't had a chance to clean the code up, so it is a bit messy and uncommented at the moment:
Mupen64Plus-Android.rar
Let me know if there are any problems (I had to use .rar format because of some recursive symbolic links which wouldn't compress into .zip). Note that it does require Eclipse plus the Android SDK, Android NDK, and Sequoyah plug-ins to work. Also note that some of the code is licensed by the GPL (including Mupen64Plus), and others by the LGPL (including Pelya's SDL port), so if you are thinking about redistributing any part of it, please read the included license documents.
 

zodttd

New member
Hi,

I actually have n64droid working. I just found this thread while searching for a different bug though!

We seemed to have figured things out just the same!

It'll be out very shortly. I'm sorry I haven't been more public with my work on this. I didn't realize others were working on it.
 

Ari64

New member
Thankfully I will be able to take my netbook and phone with me on this one, so I can continue development whenever I have free time (a bit more ghetto than using a real computer, but I've got all the software set up on there that I'll need).

A Celeron or Atom CPU is fast enough to run Mupen64Plus, this will work fine.

I'm sorry I haven't been more public with my work on this. I didn't realize others were working on it.

This isn't the first time this issue has come up. Is it really too much to ask that you keep github.com/zodttd up to date?
 

maxohkc

New member
Hey, sorry for the late response. I recently found out I will be going on a deployment in March, so with all the paperwork and stuff I haven't had much time for programming since I got back from leave. Thankfully I will be able to take my netbook and phone with me on this one, so I can continue development whenever I have free time (a bit more ghetto than using a real computer, but I've got all the software set up on there that I'll need).

I've uploaded the Eclipse project in its current form, since I've had three people so far ask me for it. Sorry I haven't had a chance to clean the code up, so it is a bit messy and uncommented at the moment:
Mupen64Plus-Android.rar
Let me know if there are any problems (I had to use .rar format because of some recursive symbolic links which wouldn't compress into .zip). Note that it does require Eclipse plus the Android SDK, Android NDK, and Sequoyah plug-ins to work. Also note that some of the code is licensed by the GPL (including Mupen64Plus), and others by the LGPL (including Pelya's SDL port), so if you are thinking about redistributing any part of it, please read the included license documents.

HAHAHA really I'm going to Infantry OSUT at Benning in May. Well good luck and hope to hear some more news.
 
Last edited:

zodttd

New member
Ari64: My github is up to date for your project on the iPhone, though in terrible need of an update on that platform. I haven't posted the source to n64droid yet on my github as I was working on it privately in my free time. I will post the source to my port before it goes public for sure. I just need a bit to clean things up.
 
OP
paulscode

paulscode

New member
I actually have n64droid working. I just found this thread while searching for a different bug though!

We seemed to have figured things out just the same!

It'll be out very shortly.
Glad to hear you are having success. It will be nice to look at the source once you get it up and running. I'll still continue my project anyway, since I'm mainly doing this for the educational experience. I'll probably also start looking at writing a nice front-end to link with your emulator's libraries, once it hits the Android market (selling some nice themed front-ends was my other ulterior motive for working on this project originally).

A Celeron or Atom CPU is fast enough to run Mupen64Plus, this will work fine.
It is an Asus Eee PC, with a 1.5 GHz Atom N550 dual-core processor. This will just be the development platform for coding, building, running the debug server, etc -- the emulator wouldn't ever need to run on the netbook itself anyway (although I have verified that plain vanilla Mupen64Plus runs quite well on this netbook for my own gaming purposes). I've already tested to make sure it is able run Eclipse and the necessary plug-ins, and able to deploy the compiled .apk to my phone where it is actually executed.
 

Forlan

New member
Hi,

I actually have n64droid working. I just found this thread while searching for a different bug though!

We seemed to have figured things out just the same!

It'll be out very shortly. I'm sorry I haven't been more public with my work on this. I didn't realize others were working on it.

Will you be teaming up and using Yong Zhang's menus and settings layout like you did with psx4droid? Or will you create your own UI?

And by shortly, do you mean a market release or simply a development breakthrough? Last time I asked you on twitter, you said there were issues with the emu not displaying any graphics.

Also, how's the performance on the once-top-of-the-range phones (1GHZ snapdragon- EVO, Dinc, Nexus, Desire etc) Does the weaker Adreno GPU make much of a difference in n64? I swear I saw you mention once that n64droid will utilize the GPU more than psx, and that you have a few performance tricks up your sleeve.

Which phones have you tested on, and have you found any performance issues yet?

Very sorry for all the questions! It's just nice to hear an update on software which is very exciting!
By soon you mean sometime this month right? ;)
Just kidding.
 
OP
paulscode

paulscode

New member
Ok, I've been reading through the debug messages to try and figure out the problem. There does seem to be some memory translation issue. The debug output is extremely long, but here are what I believe are the relevant parts:
Code:
01-19 20:08:45.553: INFO/libSDL(2564): Calling SDL_main("mupen64plus roms/mario.n64")
01-19 20:08:45.553: INFO/libSDL(2564): param 0 = "mupen64plus"
01-19 20:08:45.553: INFO/libSDL(2564): param 1 = "roms/mario.n64"
01-19 20:08:45.553: VERBOSE/front-end(2564):  __  __                         __   _  _   ____  _             
01-19 20:08:45.553: VERBOSE/front-end(2564): |  \/  |_   _ _ __   ___ _ __  / /_ | || | |  _ \| |_   _ ___ 
01-19 20:08:45.553: VERBOSE/front-end(2564): | |\/| | | | | '_ \ / _ \ '_ \| '_ \| || |_| |_) | | | | / __|  
01-19 20:08:45.553: VERBOSE/front-end(2564): | |  | | |_| | |_) |  __/ | | | (_) |__   _|  __/| | |_| \__ \  
01-19 20:08:45.553: VERBOSE/front-end(2564): |_|  |_|\__,_| .__/ \___|_| |_|\___/   |_| |_|   |_|\__,_|___/  
01-19 20:08:45.553: VERBOSE/front-end(2564):              |_|         http://code.google.com/p/mupen64plus/  
01-19 20:08:45.553: VERBOSE/front-end(2564): Mupen64Plus Console User-Interface Version 1.99.4
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Goodname: Super Mario 64 (U) [!]
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Name: SUPER MARIO 64
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: MD5: 20B854B239203BAF6C961B850A4A51A2
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: CRC: 635a2bff 8b022326
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Imagetype: .v64 (byteswapped)
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Rom size: 8388608 bytes (or 8 Mb or 64 Megabits)
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Version: 1444
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Manufacturer: Nintendo
01-19 20:08:47.483: VERBOSE/front-end(2564): Core: Country: USA
01-19 20:08:47.491: VERBOSE/front-end(2564): UI-console: using Video plugin: <dummy>
01-19 20:08:47.491: VERBOSE/front-end(2564): UI-console: using Audio plugin: 'Mupen64Plus SDL Audio Plugin' v1.99.4
01-19 20:08:47.491: VERBOSE/front-end(2564): UI-console: using Input plugin: <dummy>
01-19 20:08:47.491: VERBOSE/front-end(2564): UI-console: using RSP plugin: 'Hacktarux/Azimer High-Level Emulation RSP Plugin' v1.99.4
01-19 20:08:47.491: VERBOSE/core(2564): Running plugin_check()
01-19 20:08:47.491: VERBOSE/front-end(2564): Core Warning: No video plugin attached.  There will be no video output.
01-19 20:08:47.491: VERBOSE/front-end(2564): Core Warning: No input plugin attached.  You won't be able to control the game.
01-19 20:08:47.491: VERBOSE/core(2564): Running main_run()
01-19 20:08:47.491: VERBOSE/core(2564): inside main_run
01-19 20:08:47.491: VERBOSE/core(2564): inside init_memory
01-19 20:08:47.717: VERBOSE/front-end(2564): Audio: Initializing SDL audio subsystem...
01-19 20:08:47.717: INFO/libSDL(2564): ANDROIDAUD_OpenAudio(): app requested audio bytespersample 2 freq 44100 channels 2 samples 2048
01-19 20:08:47.752: DEBUG/AudioHardwareMot(1159): Output bufSize from kernel = 8192
01-19 20:08:47.756: DEBUG/AudioHardwareMot(1159): Output bufSize from kernel = 8192
01-19 20:08:47.764: INFO/libSDL(2564): ANDROIDAUD_OpenAudio(): app opened audio bytespersample 2 freq 44100 channels 2 bufsize 8192
01-19 20:08:47.764: VERBOSE/core(2564): Calling r4300 CPU core and running the game
01-19 20:08:47.803: DEBUG/AudioHardwareMot(1159): AudioStreamOut::wake: disabling SRC
01-19 20:08:47.811: DEBUG/AudioHardwareMot(1159): Output 0x123e0 exiting standby
01-19 20:08:47.959: VERBOSE/core(2564): RUNNING r4300_execute!!!
01-19 20:08:47.959: VERBOSE/front-end(2564): Core: Starting R4300 emulator: Dynamic Recompiler
01-19 20:08:48.178: VERBOSE/new_dynarec(2564): Init new dynarec.  BASE_ADDR: 0x843bb000, dyna_linker: 0x84098a90
01-19 20:08:48.467: DEBUG/assem_debug(2564): NOTCOMPILED: addr = a4000040 -> 843bb000
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): U:
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  r8
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  r9
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  UU:
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  32:
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  r0
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): pre: r0=-1 r1=-1 r2=-1 r3=-1 r4=-1 r5=-1 r6=-1 r7=-1 r8=-1 r9=-1 r10=36 r12=-1
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): needs: 
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): r:
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): entry: r0=-1 r1=-1 r2=-1 r3=-1 r4=-1 r5=-1 r6=-1 r7=-1 r8=-1 r9=-1 r10=36 r12=-1
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): dirty: 
01-19 20:08:48.475: VERBOSE/new_dynarec(2564): r10 
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  
01-19 20:08:48.475: VERBOSE/new_dynarec(2564):  a4000040: MTC0 r0,cpr0[13]
...lots of more assembly debug information...
Code:
01-19 20:08:48.600: DEBUG/assem_debug(2564): jump_in: a4000220
01-19 20:08:48.600: DEBUG/assem_debug(2564): do_dirty_stub a4000220
01-19 20:08:48.600: DEBUG/assem_debug(2564): movw r1,#51992 (0xcb18)
01-19 20:08:48.600: DEBUG/assem_debug(2564): movw r2,#13584 (0x3510)
01-19 20:08:48.600: DEBUG/assem_debug(2564): movt r1,#-2053963776 (0x85930000)
01-19 20:08:48.600: DEBUG/assem_debug(2564): movt r2,#-2027225088 (0x872b0000)
01-19 20:08:48.600: DEBUG/assem_debug(2564): movw r3,#500 (0x1f4)
01-19 20:08:48.600: DEBUG/assem_debug(2564): movw r0,#544 (0x220)
01-19 20:08:48.600: DEBUG/assem_debug(2564): movt r0,#-1543503872 (0xa4000000)
01-19 20:08:48.600: DEBUG/assem_debug(2564): bl 84098e78 (843bc50c+ffcdc964)
01-19 20:08:48.600: DEBUG/assem_debug(2564): ldr r7,fp+248
01-19 20:08:48.600: DEBUG/assem_debug(2564): b 843bb838 (843bc514+fffff31c)
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16384
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16385
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16386
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16387
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16388
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16389
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16390
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16391
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16392
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16393
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16394
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16395
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16396
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16397
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16398
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16399
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16400
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16401
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16402
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16403
01-19 20:08:48.600: DEBUG/inv_debug(2564): EXP: Phase 16404
01-19 20:08:48.616: INFO/DEBUG(1152): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
01-19 20:08:48.616: INFO/DEBUG(1152): Build fingerprint: 'verizon/shadow_vzw
    /cdma_shadow/shadow:2.2.1/VZW/23.340:user/ota-rel-keys,release-keys'
01-19 20:08:48.616: INFO/DEBUG(1152): pid: 2564, tid: 2573  >>> paulscode.android.mupen64plus <<<
01-19 20:08:48.616: INFO/DEBUG(1152): signal 11 (SIGSEGV), fault addr a4001fd4

EDIT: For reference, I've posted a more complete logcat output HERE.

This is a bit over my head, as far as associating it with the source code itself, but it appears that it is supposed to translate memory addresses after "addr" (0xa4000040) into addresses after "BASE_ADDR" (0x843bb000). It crashes with a fault address of 0xa4001fd4, so I assume wherever this was generated it didn't get translated into 0x843bcf94.

Ari64, I assume this problem originated in one of those two methods you mentioned (get_final_value and address_generation), correct? I'm going to look at those more closely to try and figure out how they work and what I should change.
 
Last edited:

Ari64

New member
My project doesn't currently need it, but glad to hear that the >32MB trampolines work.

It slows things down, so avoid it if you can.

Code:
01-19 21:50:52.810: VERBOSE/new_dynarec(3585):  a4000040: MTC0 r0,cpr0[13]
01-19 21:50:52.818: VERBOSE/new_dynarec(3585):  a4000044: MTC0 r0,cpr0[9]
01-19 21:50:52.818: VERBOSE/new_dynarec(3585):  a4000048: MTC0 r0,cpr0[11]
01-19 21:50:52.825: VERBOSE/new_dynarec(3585):  a400004c: LUI r8,a4700000
01-19 21:50:52.825: VERBOSE/new_dynarec(3585):  a4000050: ADDIU r8,r8,0
01-19 21:50:52.825: VERBOSE/new_dynarec(3585):  a4000054: LW r9,r8+c
01-19 21:50:52.825: VERBOSE/new_dynarec(3585):  a4000058: BNE r9,r0,a4000410
...
01-19 21:50:52.825: VERBOSE/new_dynarec(3585):  a4000078: LUI r8,a4700000
...
01-19 21:50:52.833: VERBOSE/new_dynarec(3585):  a400008c: ADDIU r12,r12,0

There seems to be some instructions missing from your log file, such as everything between a4000058 and a4000078, and everything between a4000078 and a400008c. In fact, there's quite a lot missing from the log file.

The program counter indicates that the crash occurs at 0x843bb150, which would likely be in the code generated for the instruction at a4000064. However, that's one of the areas that is missing from the log.

Ari64, I assume this problem originated in one of those two methods you mentioned (get_final_value and address_generation), correct? I'm going to look at those more closely to try and figure out how they work and what I should change.
Besides those two functions, there's also some cases in loadlr_assemble_arm, plus you'll need to patch write_rdram_new and related functions.
 

Top