This is a compilation of all the documented Prizm memory regions so far, along with an explanation of what they are and how the OS uses them.
Addresses listed are the cacheable ones where possible (switch the 0x8 for 0xA for non-cacheable addresses).
This will go into the wiki once I am more sure of the correctness of this information.
(Sources: Simon Lothar's documents, WikiPrizm and my own investigation)

0x80000000 to 0x81FFFFFF (32 Mbytes) - Flash, where the OS is and where the 16 MB storage memory is (uses the Fugue FAT filesystem)
0x88000000 to 0x881FFFFF (2 Mbytes - 2097151 bytes) - RAM

    Inside the RAM:
    0x88000000 to 0x880287FF (165888 bytes) - VRAM
    (somewhere in here, or perhaps taking the full range between VRAM and SaveVRAM, go the buffers where pieces of VRAM are saved when MsgBoxPush is called)
    0x880A2AD5 to 0x880CB2D5 (165888 bytes) - SaveVRAM/LoadVRAM
    (somewhere in here, go buffers related to file - either Fugue FAT functions, or things related to file sorting for display (after lookup), or to file lookup)
    0x880D35D0 to 0x880E3000 (64048 byes) - Main Memory
    0x880F0000 to 0x8815FFFF (458752 bytes) - System stack
    0x88160000 to 0x881DFFFF (524288 bytes) - Add-in RAM (static and stack)
    0x881E0000 to 0x881FFFFF (131072 bytes) - heap (use with malloc and free syscalls)
    Sum of known areas in RAM: 1509936 bytes (72% of the total RAM area)


0xAB800000 to 0xABD0FFFF (64048 byes) - Main Memory backup area (this is strange because it doesn't seem to be in flash, nor in RAM...)
0x80B60000 to 0x80B74461 - Section of flash where the language add-ins get copied when selected. The end address might vary depending on the file size?

0xFD800000 to 0xFD803FF8 (16376 bytes) - RS memory. This area is changed by the OS, but not on app change. Survives power-off and reboots. Stores some OS settings (link cable type, Fkey label color, frame color, and possibly things like battery type, brightness and poweroff timeout too) so not the whole of it is available for use in the add-ins, even though all of it is writable (writing some settings leads to OS weirdness/crash). Looks like none of the RS memory is safe for use because the flash access code goes there on poweroff. If that code is corrupted or accessed improperly, serious problems may occur!

0xE5200000 to 0xE5200FFF (4096 bytes) - IL memory. Writable and doesn't seem to be used by the OS. I don't know about reboot and power off survival. Simon's docs say this is 16 KB but I could only write to the first 4 KB.

0xE5007000 to 0xE5008FFF (8192 bytes) - first "additional On-Chip-RAM-area". Writable. I don't know about power off and reboot but this apparently isn't used by the OS.

0xE5017000 to 0xE5018FFF (8192 bytes) - second "additional On-Chip-RAM-area". Like above.

0xA413FEC0 - RTC

On Simon's docs, the page "fx-MPUs" has more addresses of modules on the SH microprocessors used in Casio calculators. These shouldn't be of much use for those just looking for persistent RAM areas or just a few more bytes to use as a buffer.

Sum of so-far-known memory regions usable as buffers by add-ins (excluding VRAM): 679936 bytes. The biggest continuous region is still the add-in stack.

Please let me know if there is any wrong data so I can fix it. Also, please report if you think you know about another memory region (or about other uses for the already documented regions). There are still many areas in RAM which are yet to be properly documented.
Nice write-up, thanks. This should make my job (if I even get around to it) adding support for some performance-boosting techniques to libfxcg much easier.

Cross-referencing with the SH7724 manual: RS memory on that chip is only 2k (so 4k here seems reasonable), and it states that RS memory is retained during R-standby. It appears that U-standby is a lower-power state than R-standby, so I'd assume this won't be retained across power cycles (either the calculator goes into U-standby when "off", or the OS uses RS memory).

IL memory probably isn't retained across power-off either. The IL region is basically a user-controlled cache (similar to the L1 on Blackfin processors that I've used), so it should be used for hot code or data.

Both on-chip memories (RS and IL) are retained in sleep, software standby, and module standby modes; only RS is retained in R-standby, and nothing is retained in U-standby.
And when the Prizm goes off, it goes into which standby mode?

Note that my tests were made on the emulator which doesn't poweroff with the PowerOff syscall. It does, however, reboot; also, when closing the emulator and then bringing it back, I think it has a effect similar to a power off. And the "b" chars I used to check whether RS memory was retained and what sections of it were changed, are still there even after a lot of reboots and emulator shutdowns.

The thing is: if the RS memory really is the 0xFD800000 region, then things like fkey color and cable type are stored in it; since these survive power off and reboots, there are three possibilities:
- RS memory never gets cleared during power off and reboots
- The OS saves the whole of the RS memory to flash and restores it on power up (I don't think the OS saves anything to flash on reboot, but...)
- The OS saves and restores only certain bytes (reasonable, but wouldn't explain why my test buffers are still on the emulator...)

One of these days I'll get around to experimenting with memory regions on a real calculator.

Also I think you made a mistake in your post, or I am misunderstanding: the Prizm doesn't seem to have 4 KB of RS memory, but 16 KB.

My ultimate goal with understanding memory regions is optimizing small parts of code that must run very fast (e.g. the decoder loop on my JPEG viewer), and finding a memory region that survives power off (not necessarily reboots) and that never gets touched, from where one can execute code. That way one could point a system timer to that region, and have for example a clock showing anywhere in the OS, effectively temporarily modding the OS.
(at the same time, this collides with the fact that Bfile doesn't like running timers... sigh)
gbl08ma wrote:
Also I think you made a mistake in your post, or I am misunderstanding: the Prizm doesn't seem to have 4 KB of RS memory, but 16 KB.
Simon says 16k, but your experiment indicates 4k, so I'm assuming 4k is the actual number since it was determined by experiment. Smile
My experiment doesn't indicate 4k. The only thing 4k in my post is the IL memory.

One of the unused RS regions I suggested is 4k, but that's on a bigger 16k region. At the beginning of the RS memory, there are things used by the OS, that's why I gave that buffer as an example of a region that's safe to use (AFAIK).
I suppose that with proper care at least 8 KB of the RS memory can be used.

Quote:
0xFD800000 to 0xFD803FF8 (16376 bytes) - RS memory
Hi Cemetech !

I'm just wondering if it is possible to safely write some data (and then read that) in the SaveVRAM/LoadVRAM buffer. I ask this because I've tried on the emulator and, when I exit the Add-In with the Menu key after writing some data in that buffer (without exceeding its capacity), the calculator reboot of itself and some keys aren't responding normally. I didn't dare putting this on my calculator because I've already bricked one (not by experimenting this, but a long time ago by doing I don't remember exactly what ^^ ) but I don't understand very well why this is happening (I've read that "seems to be used while process-switching with the MENU-key." (in Simon's doc I think), but I don't know exactly what happens when using Menu key...).

I know that for example, on the Monochrome casio Fx's, when using GrayScale, you have to reboot the calculator at the end of the Add-in execution and this isn't risky for the calculator, perheaps the same kind of solution will work on Prizm, but, again, I don't know exactly how to interpret the problem...

Note that I've tried (on the emulator again) to call the SaveVram1() syscall before leaving the Add-In, but this bug is present anyway :/

I've read somewhere that M.Poupe used this buffer in his programs, so I imagine the safe use of this buffer is possible, but I'd like to have some extra-information about it if somedy is aware of this . Smile

Once again, sorry for my probably bad english, I do my best to make reading of this text not too unpleasant Smile
I too am experiencing this problem that Nemhardy is experiencing when I use that buffer my program will not exit.
Well, I guess the OS wants the buffer to be used by nothing other than the VRAM saving syscalls, and messing with these buffers makes the OS "confused".
Has someone tried to write in this buffer in a real calculator ? If yes, is the bug we talked about present after a reboot of the calculator ? I'm trying to understand how MPoupe use it in CGDoom, but that's not the simplest code ever :p .

EDIT : I've found a way (not the cleanest ever) which is making this buffer usuable : I make a copy of all the Saved-VRAM buffer in a file in the ROM storage at the start of the program, and, before leaving it, i restore the saved-VRAM buffer from the file I created before. This is actually working in the emulator, I'll have to do some tests with a real calc. Smile
Don't do that you will wear out the flash memory if your program is ran many times. I think we may have the wrong address or are overwritting a few bytes somewhere that we should not. If the bytes happen to fall in the middle and you want contiguous access simply copy the data elsewhere in ram but don't wear out flash memory.
After some more observation and thinking, I formulated a new hypothesis, which is:
There is no fixed SaveVRAM/LoadVRAM area. The full (or most of the) area after the actual VRAM and before the MCS, is used as a "graphical heap" by the system. This heap has the special function of holding VRAM backup pieces, such as the parts that go behind message boxes when MsgBoxPush and MsgBoxPop is used, and possibly it is involved in the graphing software too. This explains why you have to Push and Pop message boxes (otherwise, the corresponding memory in the "graphical heap" won't be freed).
Under this hypothesis, SaveVRAM and LoadVRAM actually involve a call to a malloc and free specific to this heap, and thus the VRAM gets saved to a new address each time SaveVRAM is called, even if the way that heap is implemented means that it will always be near the same area. Of course no heap likes being written directly, on areas where there is no allocation and where other allocations exist... this hypothesis would explain why the menu would no longer open: as it called SaveVRAM when beginning to open, malloc on the now-broken heap would return a null pointer because it found a strange heap state on the broken heap, and to avoid more damage the menu loading function aborts and you stay where you were (you may get some reboots and system errors, too).

It would be good if Simon could comment on this. I'd like to know how he got to the SaveVRAM address he put on his docs, and with which OS version.

One way to test what I said is to try to use MsgBoxPush and MsgBoxPop when the OS is in that situation when the menu won't open. If MsgBoxPush doesn't work or doesn't save the VRAM behind the MsgBox, then what I said probably has some truth to it.

EDIT: on the emulator of OS 1.02, at 0x880A44AC (well into what is supposed to be the SaveVRAM area) there is what seems to be a pointer table, with addresses corresponding to flash and to RAM. But there are other pointers near this area, see for example 0x880A30C4. One thing we can be sure, is that this is not where the VRAM is saved, at least not in this OS version. I think it's best for everyone if you don't overwrite this area.
I'm not familiar with the API, so maybe they're misnomers, but aren't push and pop typically associated with a stack, rather than a heap?
Not if you use push and pop with linked lists (looking at Java collections). Note: the size of the saved buffer varies on the dimensions, so a heap allocation makes more sense.
It is probably a stack, yes, because you usually push message boxes on top of one another. That would also explain how MsgBoxPop (which takes no arguments) knows what VRAM dimension and position to restore - it always pops the last stack item (which probably has the dimension and position stored in it, in addition to the VRAM data) and goes back with the stack pointer.
Anyway, the situation is more or less the same: because you carelessly overwrite the stack (and/or that other table I pointed out), the OS enters a strange state.

I only said it was a heap because I think there may be alternative heaps for use e.g. by the g3a compression and decompression system (I don't think the zlib they included can work with only the 128 KB of "official" heap...).
Hi ! It's me (again ^^').
I've another question about something I see in SimLo doc : he say, talking about the stack addin zone : "When an add-in is loaded, the complete add-in RAM is virtualized in 8x64kB-chunks (0x88160000->0x08100000..0x881D0000->0x08170000)".
I don't understand exactly what this means concretly : what are this chunks or what happens in the initial RAM zone (0x88160000 to 0x881DFFFF) during program execution ? Are both addresses (0x88160000 and 0x08100000 for exemple) pointing to the same physically identical zone in the Flash ?
That's perheaps a strange question but I just want to understand this notion of virtualization, and I hope it's in the right place/topic.

If someone is aware of this process, I'd greatly appreciate some explanations Smile.
Once again thank you for reading ! Smile
I wrote a quick test that allowed me to quickly find the correct vram address Using the emulator with OS 2.00 I found the address to be 0x880A3F51 however on a real prizm running os 1.04 I got 0x880A2B1D
If you want to run the test yourself run this code

Code:

#include <fxcg/display.h>
#include <fxcg/keyboard.h>
#include <fxcg/misc.h>
#include <stdint.h>
#include <string.h>
static int uintToHex(unsigned int num,char * buf){
   //Divide up into 8 nybless
   unsigned x=8;
   buf+=8;
   *buf--=0;
   while(x--){
      unsigned n=num&15;
      if(n<=9)
         *buf--=n+'0';
      else
         *buf--=n+'A'-10;
      num>>=4;
   }
}
static unsigned short* memset16(unsigned short * d,unsigned short val,unsigned n){
   while(n--)
      *d++=val;
   return d;
}
int main(void){
   int key;
   char buf[32];
   buf[2]='0';
   buf[3]='x';
   unsigned char * addr=0x880A3F51;
   Bdisp_EnableColor(1);
   unsigned x,y;
   unsigned short*p=0xA8000000;
   p=memset16(p,0x31,384);
   p=memset16(p,0xFFFF,384);
   for(y=2;y<216;++y){
      for(x=0;x<384;++x){
         *p++=x*y;
      }
   }
   Bdisp_PutDisp_DD();
   SaveVRAM_1();
   while(1){
      memcpy((unsigned short*)0xA8000000,addr,384*216*2);
      uintToHex(addr,buf+4);
      PrintXY(1,1,buf,32,TEXT_COLOR_WHITE);
      GetKey(&key);//Wait for keypress in case a change needs to be noted
      switch(key){
         case KEY_CTRL_LEFT:
            --addr;
         break;
         case KEY_CTRL_RIGHT:
            ++addr;
         break;
         case KEY_CTRL_UP:
            addr-=384*216*2;
         break;
         case KEY_CTRL_DOWN:
            addr+=384*216*2;
         break;
         case KEY_CTRL_OPTN:
            addr-=384*2;
         break;
         case KEY_CTRL_VARS:
            addr+=384*2;
         break;
      }
      if(key==KEY_CTRL_EXIT)
         break;
   }
   LoadVRAM_1();
}
Is the address the same if there are MsgBox pushed?
According to the test I wrote below, no. The program I wrote below presents a much better solution to find the SaveVRAM address. The way it works is you put a unique string (which is not present elsewhere in ram) into VRAM and call SaveVRAM then search for the string skipping over the normal VRAM. One interesting thing is if I restart the emulator and run the program first thing I get a different address. If I exit and run another program and re-run this program I get the same consistent value 0x880A3F51. I guess if you want to use the address in a program you will need to use search for it.

Code:

#include <fxcg/display.h>
#include <fxcg/keyboard.h>
#include <fxcg/misc.h>
#include <stdint.h>
#include <string.h>
static int uintToHex(unsigned int num,char * buf){
   //Divide up into 8 nybless
   unsigned x=8;
   buf+=8;
   *buf--=0;
   while(x--){
      unsigned n=num&15;
      if(n<=9)
         *buf--=n+'0';
      else
         *buf--=n+'A'-10;
      num>>=4;
   }
}
static const char * SearchFor="Save/Load VRAM address here";
static void * findIn(char *haystack,const char*needle,unsigned max){
   char c=*needle;
   while(max--){
      if(*haystack==c){
         if(strcmp(haystack,needle)==0)
            return haystack;
      }
      haystack++;
   }
   return 0;//Not found
}
static unsigned* memset32(unsigned * d,unsigned val,unsigned n){
   while(n--)
      *d++=val;
   return d;
}
int main(void){
   int key;
   char buf[32];
   unsigned char * addr;
   buf[2]='0';
   buf[3]='x';
   Bdisp_EnableColor(1);
   memset32(0x88000000,0,(384*216)/2);
   strcpy((char*)0x88000000,SearchFor);
   Bdisp_PutDisp_DD();
   SaveVRAM_1();
   addr=(unsigned char*)findIn((char*)0x88000000+(384*216*2),SearchFor,(2*1024*1024)-(2*384*216));
   uintToHex(addr,buf+4);
   PrintXY(1,1,buf,32,TEXT_COLOR_WHITE);
   GetKey(&key);//Wait then pop message
   MsgBoxPush(6);
   strcpy((char*)0x88000000,SearchFor);
   Bdisp_PutDisp_DD();
   SaveVRAM_1();
   addr=(unsigned char*)findIn((char*)0x88000000+(384*216*2),SearchFor,(2*1024*1024)-(2*384*216));
   uintToHex(addr,buf+4);
   PrintXY(1,1,buf,32,TEXT_COLOR_WHITE);
   GetKey(&key);//Wait so that changes (if any) can be noted
   MsgBoxPop();
   LoadVRAM_1();
}

So the address changes, very interesting. I think we can confirm my "There is no fixed SaveVRAM/LoadVRAM area" theory.
Now, is it a stack or a heap? The syscall names ("push"/"pop") indicate that's a stack, but these names are given at the reverse-engineer's discretion (mostly Simon) and may be poorly or carefully thought.
I hope we find a malloc/alloca for that memory area so that we can use it safely without breaking the OS.

(and searching for the area still isn't a proper solution. You never know when the OS decides to move things around in that area, for example inside GetKey, other keyboard reading routine, or through a system timer)
Well if we just search for the address and use only the 165888 bytes allocated we should be fine. I agree that this does confirm your theory that the address is not fixed.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement