Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Accessing to the save/load game data
#21
Well, I'm trying this save/load functionalities and at the momment doesn't work.

I'm reading the code (the Thor code is the same code that the libraty.c on ngpc framework, so I think that simply, Thor copy and paste the same code without modifications). I'm resize the rom file to 2Mb with the resize script of Loïc too.

I need help to check and understood this code block.

1. So, as we are talking about, first of all, I need only the offset and de block. By default, the original code put the offset value to 0x1e0000 and block number to 30. Ok..for the momment I leave it with this values. So, the save method has this:


Code:
__ASM("SAVEOFFSET    EQU    0x1e0000");
__ASM("BLOCK_NB        EQU    30");

//__ASM("SAVEOFFSET    EQU    0x1FA000");
//__ASM("BLOCK_NB        EQU    0x21");
    
__ASM("VECT_FLASHWRITE    EQU    6");
__ASM("VECT_FLASHERS    EQU    8");
__ASM("rWDCR        EQU    0x6f");
__ASM("WD_CLR        EQU    0x4e");

// Erase block first (mandatory) : 64kb for only 256 bytes
__ASM("    ld    ra3,0");
__ASM("    ld    rb3,BLOCK_NB");
__ASM("    ld    rw3,VECT_FLASHERS");
__ASM("    ld    (rWDCR),WD_CLR");
__ASM("    swi    1");

// Then write data
__ASM("    ld    ra3,0");
__ASM("    ld    rbc3,1");    // 256 bytes
__ASM("    ld    xhl,(xsp+4)");
__ASM("    ld    xhl3,xhl");
__ASM("    ld    xde3,SAVEOFFSET");
__ASM("    ld    rw3,VECT_FLASHWRITE");
__ASM("    ld    (rWDCR),WD_CLR");
__ASM("    swi    1");

__ASM("    ld    (rWDCR),WD_CLR");



My first doubt in this method is that, the data parameter is passed to the function, but not is used with her own name in any place of this assembly code. Where is used the data parameter on this method?


2. The second method, GetSavedData() do various things:
  • a. It Create a u32 pointer called ptr, with 0x200000+0x1e0000 value. For me, the problem here is that I don't know what is the real valie of 0x200000+0x1e0000.
  • b. It Create a u32 pointer called ptrData, of the data array (I supose that, if I change the value of some index of this data array previously, the  ptrData has the value too)
  • c. First great doubt, the if statement check if the value of ptr it's equal like 0xcafebabe (MAGIC_NB definition). For what reason the pointer ptr (0x200000+0x1e0000) sould be equals at 0xcafebabe literal? In case of this was equals, fill the array with the data.
  • d. In case of the previous point was false, It puts in the first index of array the value of MAGIC_NB and erase all array values with 0.
Someone can explain me what are doing this? If I understand right, if the data was saved, when I call the GetSavedData method goes to the if and retrive all data, but this never happen.


Code:
void GetSavedData()
{
    u32 *ptr = (u32*)(0x200000+0x1e0000);
    u32 *ptrData = (u32*)data;
    u8 i;

    if (*ptr == MAGIC_NB) // Data saved
    {
        for (i=0;i<64;i++)
            ptrData[i] = ptr[i];
    }
    else // No data
    {
        ptrData[0] = MAGIC_NB;
        for (i=1;i<64;i++)
            ptrData[i] = 0;
    }
}

Well, someone can help me? I'm so lost here.
Reply
#22
1. Where is used the data parameter on this method :
 
Code:
__ASM(" ld xhl,(xsp+4)");

As I said in one of my previous post, C uses the stack to share parameters between main code and function. Thus xhl (32bit register) is filled with the address of your data.



2.a : It Create a u32 pointer called ptr, with 0x200000+0x1e0000 value. For me, the problem here is that I don't know what is the real value of 0x200000+0x1e0000.

On a NGPC, the cartridge begins at 0x200000. so we initialize the pointer at 0x200000 (start of the cartridge address range) + 0x1e0000 (the offset of your saved data on the cartridge).
This address thus indicate the exact position of your data on the cartridge.
I think that those save/read function in the C framework should be rewritten so they can become bloc related instead of a single address/bloc.


2.b : this pointer should be to the RAM structure that will recieve the data.

2.c : There's no absolute need for this control. None of the official games are doing this. This is only to check if your loaded data are correct (you write this control data, and check if htey are correct when reading your data).

2.d : Same as 2.c. Not really needed, but you can use this to know if you have already used the save function. if the result pointer is null, it means that you don't have data saved on your cartridge.

Loïc
Reply
#23
Hi all,

First of all, Loïc thanks for your last explanation.
After a week of work, I'm done. I'm able to save a load data from memory flash (yeah!!)

Only one thing, I had to use the offset 0x1FA000 and nb_block 0x21 as Loïc say to me, doesn't work if I use another ( I don't know why ).

This works on a rom of 2Mb or bigger with emulator and in a 32Mb bung flash cart, so, in a 32mb flash cart use the same offset than 16Mb??

Regards,
Reply
#24
(11-23-2018, 09:17 AM)KeiDash Wrote: Hi all,

First of all, Loïc thanks for your last explanation.
After a week of work, I'm done. I'm able to save a load data from memory flash (yeah!!)

Only one thing, I had to use the offset 0x1FA000 and nb_block 0x21 as Loïc say to me, doesn't work if I use another ( I don't know why ).

This works on a rom of 2Mb or bigger with emulator and in a 32Mb bung flash cart, so, in a 32mb flash cart use the same offset than 16Mb??

Regards,

A 32mb cart structure is the same as 2x16mb.
Save can work at the same offset, meaning that you have to take care of your rom structure so you won't have code or data on this part of your rom. It could also be placed on the second 16Mb chip, at bloc 0x44 if I'm not wrong.
Reply
#25
(11-23-2018, 07:03 PM)Loïc Wrote: A 32mb cart structure is the same as 2x16mb.
Save can work at the same offset, meaning that you have to take care of your rom structure so you won't have code or data on this part of your rom. It could also be placed on the second 16Mb chip, at bloc 0x44 if I'm not wrong.

Very interesting. The offset will be the same in the second chip (0x1FA000)? I mean:

From this:
Code:
__ASM("SAVEOFFSET    EQU    0x1FA000");
__ASM("BLOCK_NB        EQU    0x21");

To this:
Code:
__ASM("SAVEOFFSET    EQU    0x1FA000");
__ASM("BLOCK_NB        EQU    0x44");
Reply
#26
no, you should add 0x200000 to your offset, according to https://forum.freeplaytech.com/showthrea...88#pid5388
Reply
#27
(11-23-2018, 08:42 PM)Loïc Wrote: no, you should add 0x200000 to your offset, according to https://forum.freeplaytech.com/showthrea...88#pid5388

Thanks Loïc.

It's possible that my poor knowledge on this make me confuse. In the post that you link here, I see that you say that the 32Mb cartridge has 2 chips in different possitions and a explanation for save and load game on Biomotor Unitron (a game of 8Mb), but I can't see any reference to the 0x200000 offset for the second chip in 32Mb cartridge.

I think "ok, Loïc know more about this than me, let my try it", so I'm wrote the next line on my code to Save the game:

Code:
    __ASM("SAVEOFFSET    EQU    0x200000");
    __ASM("BLOCK_NB        EQU    0x44");

And then, when I'm going to edit the Load method, I saw the line where the code get the specific memory position to read the data allocated there:
Code:
u32 *ptr = (u32*)(0x200000+0x1FA000);

So, I think...Whait, this reading (for 16Mb cart) got the position of 0x200000+0x1FA000...so, in 32Mb cartridge, it's the same positions too (from+to)?

The truth is that I am very grateful with your help, I never study some thinks like this read memory positions with this kind of values (0x20000, 0x1FA000, 0x44, etc), this is brand new for me.

Regads,
Reply
#28
here's a little description of the neogeo pocket ram/rom structure


+-------------------+--------------------------------+-----------------------------------+
|  internal stuff   |  1st flash rom                 |   2nd flash rom                   |
+-------------------+--------------------------------+-----------------------------------+


- internal stuff is the range from 0x000000 to 0x1FFFFF. it's divided in parts like main RAM, z80 ram, tile memory, scroll planes, palettes and other technical stuff. everything here is most likely handled by the c framework.
- 1st flash rom : from the handheld point of view, the flash start at 0x200000. if your cartridge is 4 to 16mbit, only one flash rom is present on the cartridge.
- 2nd flash rom : only for bung/flashmasta/retrohq or 32mbits games.

the data linked above are from the cartridge point of view, thus starting at 0x000000.
When refering to the data, you must think with base address of 0x200000 + offfset (ex : 0x1FA000)

if I refer to those data, 0x1FA000 is only present for 16mbit or above, and it's part of the 33rd bloc.

you can save your data here on 16/32mbit cartridges.
If you do that on a 32mbit cartridge, then your card structure will be like (only flash structure :

+------------------------+--------------------------+-----------------------------------+
|  code and data         |  savegame bloc 33 (0x21) |   remaining data (or code)        |
+------------------------+--------------------------+-----------------------------------+
                         ^                          ^
                         |                          |
       offset 0x1FA000 --+                          +-- offset [font=Courier]0x1FC000[/font]

In this case, you clear bloc 0x21, write at offset 0x1FA000, but you read at direct address 0x3FA000 (0x200000 + 0x1FA000)

It may be easier, mainly in C, to move the save bloc near the end of the cartridge (the last bloc is reserved for technical purpose).
Moving your data according to this diagram (32mbit cartridge) :

+--------------------------------------------+--------------------------+
|  code and data                             |  savegame bloc 68 (0x44) |
+--------------------------------------------+--------------------------+
                                             ^                          ^
                                             |                          |
                           offset 0x3FA000 --+                          +-- offset [font=Courier]0x3FC000, end of code+data+savegame[/font]

Here, you clear bloc 0x44, write at offset 0x3FA000, but you read at direct address 0x5FA000 (0x200000 + 0x3FA000)


I hope that's clear enough now ?
Reply
#29
Well, I think so.

I understand that you explain to me. Some issues I can not understand because of total ignorance, such as understanding the structure of a chip or how to get to know what positions are used for what, but in this case I understood what you have explained to me. In my case, I never had worked in low level code.

For example, one thing that I don't understand is, how to get to understand that the 2nd chip begins at a position and end in others position different of the first chip positions. In any case, I understand this issue.

I'm just tried to save data on a bung flash cart with offset 0x200000+0x3FA000 [font=Arial]and nb_block to 0x44 [font=Trebuchet MS]and this method doens't work[/font][/font]


Many thanks for your patient Loïc
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)