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 > Running Code from VRAM?

#167391 - hacker013 - Tue Mar 10, 2009 7:24 pm

Hey everybody,

Is it possible to run code from vram? If yes, how will that work? Just copy the code to vram and execute it?

gr,

newbie013
_________________
Website / Blog

Let the nds be with you.

#167398 - Dwedit - Tue Mar 10, 2009 8:19 pm

Might have to modify the cache settings to get it to perform decently, I don't think it caches VRAM by default.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#167416 - hacker013 - Wed Mar 11, 2009 8:07 am

How do you mean?
_________________
Website / Blog

Let the nds be with you.

#167419 - Dwedit - Wed Mar 11, 2009 9:04 am

The memory protection unit is configured so that the IO registers and VRAM both share cacheability settings. When you jump to VRAM, by default, it is not cached. This would slow down code running from there.

Assuming you are using the standard devkitpro crt0.s file, to turn on the instruction cache for the "VRAM + IO PORTS + PALETTE + OAM" region, use this:
Code:

    ldr    r0,=0b01000011
    mcr    p15, 0, r0, c2, c0, 1


If you don't use the cache, fetching instructions is 10 times slower.


If you are trying to run code from the ARM7, there is no cache for that processor, and the CPU can fetch instructions efficiently. Only thing about VRAM is that it is 16-bit instead of 32-bit, so fetching an instruction takes 2 cycles instead of 1. THUMB code takes 1 cycle to fetch the instruction.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#167425 - hacker013 - Wed Mar 11, 2009 6:14 pm

@Dwedit
I can't find where I must add those 2 lines. Can I just use fread to read it directly to vram or must I use an another way?
_________________
Website / Blog

Let the nds be with you.

#167426 - elhobbs - Wed Mar 11, 2009 6:31 pm

hacker013 wrote:
Can I just use fread to read it directly to vram or must I use an another way?
fread what to vram?

#167427 - hacker013 - Wed Mar 11, 2009 6:44 pm

The kernel made by Mighty Max and updated now by me oO. I'm trying to get it run from vram because it can't fit in siwram because the kernel is now compiled 128kb (damn libfat) and siwram is only 32kb.
_________________
Website / Blog

Let the nds be with you.

#167428 - DiscoStew - Wed Mar 11, 2009 6:45 pm

I believe hacker013 wants to copy compiled code from a file (with fread) into VRAM so it can be executed there, yet it just isn't that simple, is it? I'm pretty sure there is much more work to pull that off.

Also hacker013, the code Dwedit posted only makes those areas cacheable, so should you have code executed from one of those spots with it set as such, it will run faster.
_________________
DS - It's all about DiscoStew

#167429 - hacker013 - Wed Mar 11, 2009 6:50 pm

I don't know where to put thos 2 lines in the crt0.s file?

And also I have this code (modified loader from the original to get it run :) only it doesn't work.) :
Code:
/* ndslib includes */
#include <nds.h>
#include <fat.h>
#include <stdio.h>

#include "service.h"


/* loader just loads .knl into siwram (0x03000000) */

int main(int argc,char **argv) {
   REG_EXMEMCNT = 0xE800 ;
   
   /* set power to all devices, make mainscreen the lower */
   powerOn(POWER_ALL_2D) ;
   powerOff(POWER_SWAP_LCDS) ;
    //vramSetMainBanks(   VRAM_A_MAIN_BG_0x06000000,       
    //                    VRAM_B_MAIN_BG_0x06020000,     
    //                    VRAM_C_LCD, 
    //                    VRAM_D_MAIN_BG_0x06040000   
    //                    );   
                  
   //set the video mode
    //videoSetMode(  MODE_0_2D | DISPLAY_BG0_ACTIVE );
   // black backdrop
   //BG_PALETTE[0]=RGB15(0,0,0);
   //BG0_CR = BG_MAP_BASE(31);
   //BG_PALETTE[255] = RGB15(31,31,31);
   // set up debug output
   //consoleInitDefault((u16*)SCREEN_BASE_BLOCK(31), (u16*)CHAR_BASE_BLOCK(0), 16);
   consoleDemoInit();
   iprintf("Loading kernel ...\n") ;

   /* fat filesystem */
   //bool fat = FAT_InitFiles() ;   
   bool fat = fatInitDefault();
   if (fat) {
      iprintf("  filesystem init\n") ;
   } else {
      iprintf("  filesystem failed\n") ;
   } ;
   

   iprintf("  protection base\n") ;

      MPU_WriteProtectionBase0(0x0000003F) ;               /* highest priority, access for the system mode to all addresses */
      MPU_WriteDataPermissions(0x33333333) ;
      MPU_WriteCodePermissions(0x33333333) ;

   //*(volatile unsigned char *)0x04000247 = 0 ;      // 32kB to arm9, 0kB to arm7
   //iprintf("  siwram set\n") ;
   
   //*(volatile unsigned char *)0x03000000 = 0x12   ;   // access test
   //if (*(volatile unsigned char *)0x03000000 != 0x12) {
   //   iprintf("  siwram not accessible\n") ;
   //   while(1) ;
   //} ;
   //iprintf("  siwram test\n") ;
   
   iprintf("  prepaire vram\n");
   vramSetBankA(VRAM_A_LCD);
   vramSetBankB(VRAM_B_LCD);
   
   size_t knlSize = 0;
   FILE *knl = fopen("NDSOS.knl","rb") ;
   if (!knl) {
      iprintf("  kernel missing\n") ;
      while(1) ;
   } ;
   // Read File Size
   fseek (knl, 0, SEEK_END);
   knlSize = ftell(knl);
   if(knlSize==0)
   {
      fclose(knl);
      iprintf("   kernel size=0! - Halted\n");
      while(1);
   }
   //Malloc a tempory buffer
   void *buffer = malloc(knlSize);
   //Read the kernel from fat
   fseek (knl, 0, SEEK_SET);
   //unsigned long cnt = fread((void *)0x03000000,1,32*1024,knl) ;
   unsigned long cnt = fread(buffer,1,knlSize,knl) ;
   
   if (cnt==0) {
      fclose(knl);
      iprintf("  kernel size=0! - Halted\n") ;
      while(1) ;
   } ;
   //Copy kernel to vram
   dmaCopyAsynch(buffer,(void *)0x06000000,knlSize);
   
   fclose(knl) ;
   
   iprintf("  loaded %ld bytes\n",cnt) ;
   
   typedef void (*siwram_type)(void) ;
   /* main() */
   /* jumping just before crt0 would jump */
   //siwram_type siwram = (siwram_type)0x03000138 ;
   siwram_type siwram = (siwram_type)0x06000138;
   iprintf("  executing\n") ;
   //Run kernel
   siwram() ;
   iprintf("  hmm?\n") ;

   return 0 ;
} ;


Can you see what i'm doing wrong?
_________________
Website / Blog

Let the nds be with you.

#167430 - elhobbs - Wed Mar 11, 2009 8:50 pm

DiscoStew wrote:
I believe hacker013 wants to copy compiled code from a file (with fread) into VRAM so it can be executed there, yet it just isn't that simple, is it? I'm pretty sure there is much more work to pull that off.

Also hacker013, the code Dwedit posted only makes those areas cacheable, so should you have code executed from one of those spots with it set as such, it will run faster.
I was being intentionally obtuse in order to match the vague request.

yes, there is probably more that needs to be done. the knl file is probably compiled to run at a fixed address which will need to be changed. also, any 8bit writes to the data section of the kernel will fail when it is in vram (there may not be any though).

Is this purely an academic exercise? I do not really see any use for this - dslinux has this segment taken care of quite well.

#167449 - hacker013 - Thu Mar 12, 2009 2:21 pm

I'm building this because the game i'm making needs some structure to run on. Because I don't want to include in the game things like multithreading and Virtual Memory. This way also other people can use it. If I got it finished. I'm not doing this for school. I'm doing this for my hobby.
_________________
Website / Blog

Let the nds be with you.

#167451 - Lazy1 - Thu Mar 12, 2009 3:27 pm

I'm not sure why any game would want to execute code from vram.

If I were making a game, what I would do is write it on the PC first using a good library like SDL and port it over later.
That way you don't need to worry about such things until you are ready to port your code.

Quake runs fine with the limited DS hardware, if your game requires code to be squeezed into vram then something isn't right.
Games do not need their own kernel (at least not usually I would think).

Although I admit writing a mini OS sounds fun it's not something I personally would jump into without doing a ton of reading first.

#167453 - hacker013 - Thu Mar 12, 2009 4:26 pm

I'm want to use vram to run the kernel from because i'm using the basic kernel from mighty max and that one runs from siwram and uses the total main ram for virtual memory. But if I compile it is now with the current devkitARM + libs 128 kb :( (damn libfat).
_________________
Website / Blog

Let the nds be with you.

#167454 - Lazy1 - Thu Mar 12, 2009 4:30 pm

I have to ask though, why do you need virtual memory?

#167455 - Mighty Max - Thu Mar 12, 2009 4:46 pm

I would advise to NOT use it other then as the PoC it is.

It was never intended as a working base but to show that it's possible.
_________________
GBAMP Multiboot

#167476 - hacker013 - Fri Mar 13, 2009 11:50 am

Lazy1 wrote:
I have to ask though, why do you need virtual memory?


My game needs much of ram and I haven't a slot2 expansionpack :(
_________________
Website / Blog

Let the nds be with you.

#167478 - Dwedit - Fri Mar 13, 2009 3:48 pm

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

#167479 - Miked0801 - Fri Mar 13, 2009 4:08 pm

:)

typedef bool int;
static bool stateArray[1024*256];

#167480 - Lazy1 - Fri Mar 13, 2009 4:32 pm

Like I said, Quake fits in the DS's limited memory.
If a homebrew project is overrunning those limits it's time to rethink a few things.

Worry about designing your project first and the porting details later.

#167486 - hacker013 - Fri Mar 13, 2009 7:13 pm

I wanna make it nds only -_-
_________________
Website / Blog

Let the nds be with you.

#167488 - Lazy1 - Fri Mar 13, 2009 7:44 pm

No one said you couldn't make it nds only, the idea is that on the PC you have access to debuggers, profilers and a much faster development/testing cycle.
For starting a NEW game from scratch it would be so much easier to start on the PC and port it over when it's ready.

A cheap example would be my port of wolf3d, I did 99% of the screen conversion (320x200->256x192) on the PC using the SDL code that it originally came with.
Since all the menus/ect were hard coded it would have taken AGES to test since I'd have to rebuild and put it on hardware to test whereas ./wolf3d was so much easier and faster.
Plus the debugger was there when I needed it, unlike on hardware where there are no debuggers*.

*Not 100% sure if this is still true

#167489 - DiscoStew - Fri Mar 13, 2009 10:28 pm

With Quake 1, it was optimized to work with just the 4MB on the DS, and the original required at least 16MB of RAM on the PC, I think. Besides, virtual memory is freaking slow.

What exactly is requiring more than 4MB of main RAM?

Miked0801 wrote:
:)

typedef bool int;
static bool stateArray[1024*256];


And yet, for every byte used for a boolean value, it can have 8 separated values. So, an array of 1024 ints can actually carry 32768 separate boolean values. It's a good way to condense memory usage if large bool arrays are being used. It just requires a little more processing to input/retrieve.
_________________
DS - It's all about DiscoStew

#167493 - Miked0801 - Sat Mar 14, 2009 4:31 am

You missed the point Disco. The array of u32 bools was a response to the OP not having enough RAM for his game. PC Development has code like that all the time. Wasting 97% of your memory without knowing it is all too common.

#167495 - DiscoStew - Sat Mar 14, 2009 9:45 am

Miked0801 wrote:
You missed the point Disco. The array of u32 bools was a response to the OP not having enough RAM for his game. PC Development has code like that all the time. Wasting 97% of your memory without knowing it is all too common.


So THAT'S why Windows keeps crashing! :P

But seriously, that never crossed my mind that memory could be wasted in such a fashion, and that often too. Maybe people should go back to working with 286s and older computer models, and learn to deal with limited resources.
_________________
DS - It's all about DiscoStew

#167497 - hacker013 - Sat Mar 14, 2009 7:07 pm

Let's say I write it first for the pc. It is a 3d game so I will use then a decent 3d engine like orge3D. When I finish that I will port it over to the nds. Then comes a question like how in gods name would I port the total orge3D to the nds. Or let' say I use a dll, then I have to write a dll system because the nds hasn't one :( So what you guys telling me is a little to much work, don't you think?
_________________
Website / Blog

Let the nds be with you.

#167498 - bean_xp - Sat Mar 14, 2009 7:44 pm

hacker013 wrote:
Let's say I write it first for the pc. It is a 3d game so I will use then a decent 3d engine like orge3D. When I finish that I will port it over to the nds. Then comes a question like how in gods name would I port the total orge3D to the nds. Or let' say I use a dll, then I have to write a dll system because the nds hasn't one :( So what you guys telling me is a little to much work, don't you think?


No this wouldn't work at all, you couldn't get a .dll system working on the DS for these purposes. The .dll is compiled for intel processors, so you would recompile the library to run on DS. Also the graphics capabilities of the DS are not even similar to PC graphics cards. You would be far better off using some simple openGL commands for your 3D on PC, most of which are available and offer similar functionality in libnds.

I also don't see exactly what you need the extra memory for on DS, what exactly are you planning to use it for?

#167499 - DiscoStew - Sat Mar 14, 2009 8:24 pm

hacker013 wrote:
Let's say I write it first for the pc. It is a 3d game so I will use then a decent 3d engine like orge3D.


Stop. Just stop. You are the programmer for your NDS projects. If you can't port something over to the NDS, then don't use it in your PC version. One of the exceptions to use is OpenGL, because much of the functionality that the NDS is capable of has been wrapped up into similar functions in libnds. But with that, you don't port over OpenGL. You just make sure that the functions you use are ones that are available in libnds.
_________________
DS - It's all about DiscoStew

#167500 - Kath - Sat Mar 14, 2009 8:35 pm

hacker013 wrote:
Let's say I write it first for the pc. It is a 3d game so I will use then a decent 3d engine like orge3D. When I finish that I will port it over to the nds. Then comes a question like how in gods name would I port the total orge3D to the nds. Or let' say I use a dll, then I have to write a dll system because the nds hasn't one :( So what you guys telling me is a little to much work, don't you think?


Just write it for PC using intermediate mode OpenGL (glVertex(...) etc.), it is simple enough to port and you can have a running "fake DS" on Windows in under a day. My game code is exactly the same between the PC and DS versions. Even my world/scene classes are the same. The only things rewritten are the renderer, startup, touch (mouse) and the resource loading/unloading code.

How are you running out of memory anyway? I have an RTS game in ortho 3d and even with a complex scene stuffed inside STL containers I'm never using more than 120k. You'll need to more specific about what you want to achieve.

#167501 - DiscoStew - Sat Mar 14, 2009 8:49 pm

Kath wrote:
Just write it for PC using intermediate mode OpenGL (glVertex(...) etc.), it is simple enough to port and you can have a running "fake DS" on Windows in under a day.


This.

If you are planning to have this be for just the NDS, then set up a PC application with only the basics needed (no fancy stuff) so that it would act like you were running your program under an emulator. The difference would be that it is an actual PC application, which you can test and debug much faster and easier imo. Once it is far enough along, you port it over to the NDS, and make corrections from there.
_________________
DS - It's all about DiscoStew

#167502 - hacker013 - Sat Mar 14, 2009 9:14 pm

But aren't there nds debuggers out?
_________________
Website / Blog

Let the nds be with you.

#167503 - Miked0801 - Sun Mar 15, 2009 12:20 am

Sure, I use one every day. Of course I work for a professional game development company that supplies me with the 20k dev system:)

#167541 - hacker013 - Tue Mar 17, 2009 8:23 pm

Are there also free debuggers?
_________________
Website / Blog

Let the nds be with you.

#167542 - elhobbs - Tue Mar 17, 2009 8:57 pm

desmume and insight/gdb work quite well for me. desmume needs to be re-compiled with the gdb stub turned on though - the downloadable binaries do not have this functionality enabled.

#167547 - albinofrenchy - Wed Mar 18, 2009 1:47 am

Old binaries do exist.

They work well enough. The only problem is is that that version will gleefully write protected memory and not core dump when the real thing would.

#167558 - hacker013 - Wed Mar 18, 2009 3:01 pm

thx :) I was more thinking to buy no$gba debugger :) but I will try first desmume.

@mighty max, is it possible to use that part of virtual memory (mem.c + mem.h + mem.swp) as a library in my game oO ? Or have I to modified it first?
_________________
Website / Blog

Let the nds be with you.

#167559 - elhobbs - Wed Mar 18, 2009 4:14 pm

hacker013 wrote:
thx :) I was more thinking to buy no$gba debugger :) but I will try first desmume.
no$gba is no longer for sale.

hacker013 wrote:
@mighty max, is it possible to use that part of virtual memory (mem.c + mem.h + mem.swp) as a library in my game oO ? Or have I to modified it first?
even though it makes zero sense to use it in a game? and the person who wrote it advises you not to use it? Just out of curiousity: why do you think you need something like this for your game? you would be better served by implementing a cache manager that fits in the memory available to the ds.

#167560 - hacker013 - Wed Mar 18, 2009 4:38 pm

Because i'm building a zelda OoT clone. And it needs more then 4mb memory and I haven't a slot2 ram expansion. So I don't wanna use that.
_________________
Website / Blog

Let the nds be with you.

#167561 - DiscoStew - Wed Mar 18, 2009 5:17 pm

If I'm not mistaken, the N64 only had 4MB of RAM (excluding the upgrade that came with DK64), and I'm sure OoT didn't use all that memory.
_________________
DS - It's all about DiscoStew

#167562 - hacker013 - Wed Mar 18, 2009 6:14 pm

I don't know that for sure but I know de n64 had support for memory extensions like used with zelda MM.
_________________
Website / Blog

Let the nds be with you.

#167563 - Mighty Max - Wed Mar 18, 2009 6:16 pm

hacker013 wrote:
Because i'm building a zelda OoT clone. And it needs more then 4mb memory and I haven't a slot2 ram expansion. So I don't wanna use that.


You should not get near to that limit.
Seperate the data from your program (DLDI/EFS it). The data and code needed at any random point in the game should fit with ease.
Only if you'd load every data into RAM all the time you should run into problems.

It's not that the levels or gamestate are very complex ... (iir that game correctly)

This will not only save you a lot of trouble with a instable code (which that PoC is) but also forces you to make the code and data much more modular which in return extremely fastens the development (reuse of techniques, straight design, easier to read/trace) once the basics are done.
_________________
GBAMP Multiboot

#167566 - elhobbs - Wed Mar 18, 2009 6:24 pm

I am not sure if you know this but all of the assets for the entire game do not need to be loaded into the 4MB on the DS at the same time. you could have 200MB or more of total assets for the game. You only need to load stuff into memory as it is needed.

a swap file will not only drain your battery faster it will also destroy your storage card (sd , micro sd, cflash, etc.) pretty fast too.

#167567 - Miked0801 - Wed Mar 18, 2009 6:29 pm

How much of your clone is currently build hacker?

#167571 - Dwedit - Wed Mar 18, 2009 7:11 pm

In Ocarina of time, it only loads the visuals for rooms that are currently visible. If you manage to leave the bounds of a room, you can still visit other rooms, but they won't draw, so you will walk against invisible walls.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#167574 - hacker013 - Wed Mar 18, 2009 7:46 pm

Miked0801 wrote:
How much of your clone is currently build hacker?


I'm still setting up de basic engine for the menu -_- because nitro engine has many wierd bugs (not showing images and other stuff like that). Maybe you guys can recommend me a other 3d engine with 2d drawing support. I was first thinking that engine used to much ram (so that is the reason I started this topic). But now with the newest libnds the engine doesn't work correctly anymore (Screen screwed up) :'(
_________________
Website / Blog

Let the nds be with you.

#167578 - Emmanuel - Wed Mar 18, 2009 9:18 pm

hacker013 wrote:
Maybe you guys can recommend me a other 3d engine with 2d drawing support.

Maybe make your own... or try to contribute to improve an existing one...

#167587 - Echo49 - Thu Mar 19, 2009 7:36 am

If you're looking into something as (complicated) as running code from VRAM and page files and what not, why not just make your own engine?

Seriously, it's not that hard to create a wrapper around the 3D functions and make it display 2D. It only took me a few days to make one geared specifically for my game.

#167588 - elwing - Thu Mar 19, 2009 8:13 am

hacker013 wrote:
I don't know that for sure but I know de n64 had support for memory extensions like used with zelda MM.


yes, the N64 support a 4Mb memory extension, however it is not needed for OoT, majora's mask need it trough... so the original OoT was also running on only 4Mb...