#106816 - Lazy1 - Mon Oct 23, 2006 7:11 pm
I have been thinking about this for a while, having a seperate version of libnds which would allow a nds program to be compiled as native PC code.
I think direct hardware access would raise an error which could be captured, decoded and handled within the library - but I'm not too sure about that.
There are a few issues remaining with the idea, but it would really speed up development if you could just compile and run on the same PC as your developing on rather than having to copy it to your DS every time.
Any thoughts?
It would be like an emulator, but instead only emulates the DS hardware while running native code.
#106818 - silent_code - Mon Oct 23, 2006 7:21 pm
i once wrote a look and feel nds simulator for a project. it still needed some changes in the code to compile for nds, but you got the idea of how it would look and play like on the nds. it was sort of a prototype running on a pc. ;)
i'm currently developping a toolset that'll make it easier to move these prototypes to nds. no release yet, as this is part of another project, but it will definitely be released asap.
#106870 - melw - Tue Oct 24, 2006 8:55 am
You may want to use an opposite approach - make a simple SDL application (something that runs on Win32, OSX, Linux, GP2X, you name it) and make a conversion from there to libnds where needed. Doing the minimum, i.e. input system for buttons and mouse (i.e. touchscreen) and framebuffer for showing the graphics is something like one weekend at max. and it's easy to expand from there. You can even just define different targets in your makefile and compile to whatever platform you like.
I've been using this kind of system for nearly a year and haven't touched an emulator since then... Making cross-platform 3d graphics implementation is also possible since the libnds is close enough to OpenGL, even if lacking here and there.
#106889 - Lazy1 - Tue Oct 24, 2006 2:52 pm
That is almost exactly what I had in mind, except I need to be able to trap and handle accesses to non existant DS hardware.
For example, say the app wants to write to POWER_CR.
The application would segfault, I could decode the instruction and update the local POWER_CR variable which would affect the application.
#106899 - GPFerror - Tue Oct 24, 2006 4:13 pm
melw wrote: |
You may want to use an opposite approach - make a simple SDL application (something that runs on Win32, OSX, Linux, GP2X, you name it) and make a conversion from there to libnds where needed. Doing the minimum, i.e. input system for buttons and mouse (i.e. touchscreen) and framebuffer for showing the graphics is something like one weekend at max. and it's easy to expand from there. You can even just define different targets in your makefile and compile to whatever platform you like.
I've been using this kind of system for nearly a year and haven't touched an emulator since then... Making cross-platform 3d graphics implementation is also possible since the libnds is close enough to OpenGL, even if lacking here and there. |
Well it is possible to use my libSDL port for the ds as well, and if more people used it it would have better features, right now touchscreen is only used for debug output. Sound is still in its infancy and filesupport is hardcoded to either use romfs or fatlib.
It uses a mode6 1024X512 8bit background or 512X512 16bit background which uses scaling to match your setscreen size, I have used it for porting stuff from the pc etc to the ds.
The latest SDL version can be downloaded from http://gpf.dcemu.co.uk/ndsSDL.shtml
But I think TheLazy1 approach sound very interesting and I have seen similiar approaches on other consoles and its very usefull. Untill there is better emulator support with gdb debugging this sounds like a good solutution.
Troy(GPF)
http://gpf.dcemu.co.uk
#106976 - masscat - Wed Oct 25, 2006 12:13 pm
I looked at this approach a while back. Here is some linux code for catching segmentation faults:
Code: |
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <ucontext.h>
int a_global_var = 10;
static void
seg_fault_catcher( int signum, siginfo_t *info, void *data) {
ucontext_t *context = (ucontext_t *)data;
printf("Segmentation fault\n");
printf("context uc_flags 0x%lx\n", context->uc_flags);
fflush( stdout);
a_global_var = 15;
abort();
}
int main() {
struct sigaction new_action = {
.sa_handler = NULL,
.sa_sigaction = seg_fault_catcher,
.sa_flags = SA_SIGINFO,
.sa_restorer = NULL
};
int small_array[10];
int i;
sigemptyset ( &new_action.sa_mask);
sigaction( SIGSEGV, &new_action, NULL);
printf("Hello world\n");
printf("%p\n", &a_global_var);
printf("%p\n", seg_fault_catcher);
while ( a_global_var == 10) {
*(int *)0x4000000 = 10;
}
printf("Good bye\n");
return (0);
} |
And that is about as far as I took it. My advice would be to look at GDB (GNU debugger) code for examples of how to run a process under control, catching its errors and changing its state as the two problems are very similar.
I like this approach as you get a 'free' PC version of your NDS game as well as the ability to use better debug tools.
On another note, I am putting a GDB stub into the desume emulator at the moment. This should allow sophisticated debugging techniques such as break on read and write of memory addresses.
#106978 - sgeos - Wed Oct 25, 2006 12:21 pm
Lazy1 wrote: |
That is almost exactly what I had in mind, except I need to be able to trap and handle accesses to non existant DS hardware.
|
I think you'd be better off building an API that can be used with both the PC and the DS.
-Brendan
#107017 - Lazy1 - Wed Oct 25, 2006 6:37 pm
sgeos wrote: |
Lazy1 wrote: | That is almost exactly what I had in mind, except I need to be able to trap and handle accesses to non existant DS hardware.
|
I think you'd be better off building an API that can be used with both the PC and the DS.
-Brendan |
Problem is that for some reason DS coders are reluctant to use such libraries and the dev community seems to look down on those who do.
Just look at PA-LIB.
#107041 - silent_code - Wed Oct 25, 2006 10:36 pm
don't care about other people if it helps you. you don't have to make it public or something. even if you do, everyone can decide for himself what to use, e.g. MegaETK is a kick ass game and it was done with PAlib. [i personally don't use PAlib and i also don't plan to use it.] you can't tell me that someone says bad things about ETK, plus he won that goddamn contest ;)
#107046 - Lazy1 - Wed Oct 25, 2006 11:05 pm
What I mean is, don't ask for PALIB help on IRC...
They'll flame the crap out of you, then suggest libnds.
Besides, there isn't much direct HW access done anyway.
It's mainly setting BG scrolling registers during vblank or whatever, maybe writes to vram but that would be slow as hell using this method and you shouldn't be writing to vram like that anyway (unless it's a special case).
The goal wouldn't be a 100% accurate emulator, just something to do rapid development on.
Masscat: I tried something like that, but was never able to skip over the instruction or figure out how to decode it.
My guess would be to have platform specific code decompile the instruction and update the local register copy itself.
I guess I have alot more reading to do on signals. :)
#107053 - tepples - Thu Oct 26, 2006 12:11 am
First of all, create a single framework that can be used to develop on the GBA and PC. The GBA is a simpler system, and it should be easier to get it up and running quickly. This will give you ideas about how to do the DS source compatibility layer right.
Hint 1: Make the C or C++ equivalent of a bean. For instance, don't expose a global variable DISPCNT; instead make functions such as getDISPCNT() and setDISPCNT() for all hardware registers, so that your PC based PPU emulator can more easily intercept them. Then in the GBA side, just make the get() and set() into inline functions.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#107056 - Lazy1 - Thu Oct 26, 2006 1:09 am
You raise a good point there, I wouldn't need to have the register addresses the same as nds.
So, I wouldn't need to trap/decode memory accesses at all or atleast not in the way I first thought.
There are still a few issues, but they aren't that big of a deal:
- No assembly source
- No direct writes to vram
- No way to force 66mhz operation, you'd have to sync to vblank for accuracy
I have no idea about arm7 code, maybe have a seperate PC library for that and have it run as another process and use IPC to communicate with the main application.
#107079 - PypeBros - Thu Oct 26, 2006 9:18 am
i have to admit that i'm a bit perplexed by your approach. Okay, it's a common things in emulators to write out native code to speed up emulation (like in those N64 emulators), or simply to let the current processor do the job when hosting and emulated processors are the same (that's what QEMU does, for instance).
But here, the processors are very differents and the one you want to emulate runs orders of magnitude slower than the host, and emulating the CPU is hardly the most complicated thing to do ...
At the end, you'd be running something that's not the program you'd like to see running on the DS (e.g. it may have a very different memory footprints and suffer different weird bugs), and you'd still have to wait for a full SIGSEGV delivery everytime you do something special (like reprogramming any register that needs to behave in a 'special' way). Not mentionning the ugly case where your system doesn't let you map memory at VRAM and where you'd have to catch a SIGSEGV for every pixel you change :-/
So if you want to have a "compatibility" library to run new software X both on the DS and on anything else, i'd suggest you focus on a library with a higher level of abstraction (such as PA_Lib?) -- that is, your C program should never do some direct I/O to the registers -- so that the library can completely hide what's going on below.
Or alternatively, you just write a portable game engine like Sarrien, ScummVM or the one behind Another World and Flash back ...
_________________
SEDS: Sprite Edition on DS :: modplayer
#107110 - Lazy1 - Thu Oct 26, 2006 7:06 pm
I see your point, but this wouldn't be designed for accuracy as it would only emulate a few system registers and the display system.
It's more for rapid development if you get an idea and you want to work on it quickly without having to do musical CF cards every time you want to test it.
I know the architecture is extremely different, but I don't see that as a big issue. You could always use dualis, but this would mean you just compile and run your DS app from the command line just like any other PC application.
The issue of writing to hardware registers has been resolved, the register definitions will be pointing to global variables instead.
The only issue remaining is direct writes to vram which I don't think is done that often, if you have gfx or a map to copy DMA would be a better option and it could be easily simulated with no performance penalty.