Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
New Game Block Dude (Port)
#16
So, I had a look at your project and couldn't really figure out where you wanted to insert your load/save - so, what I've done in DDMR etc is to abstract the save code into it's own functions


Code:
void GetDDMRData(u16 *Palette, u8 *Difficulty, SCORE *scoretable)
{
    u32 data[256];
    u8 iScoreLoop;

    GetFlash(&data);

    // Set defaults
    *Palette=RGB(0,15,15);
    *Difficulty=1;

    switch(data[0])
    {
        case MAGIC_NB:
            {
                // Restore from
                SetRandomCounterSeed((u16)data[1]);
                *Palette=(u16)data[2];
                *Difficulty=(u8)data[3];
                for(iScoreLoop=0;iScoreLoop<(HST_SIZE*3);iScoreLoop++)
                {
                    scoretable[iScoreLoop].Initial1=(data[4+(iScoreLoop<<1)]&0xff000000)>>24;
                    scoretable[iScoreLoop].Initial2=(data[4+(iScoreLoop<<1)]&0x00ff0000)>>16;
                    scoretable[iScoreLoop].Initial3=(data[4+(iScoreLoop<<1)]&0x0000ff00)>>8;
                    scoretable[iScoreLoop].Score=(u16)(data[5+(iScoreLoop<<1)]&0x0000ffff);
                }
            }
            break;
        case MAGIC_NB+1:
            {
                // Set defaults
                InitialiseQRandom();
                for(iScoreLoop=0;iScoreLoop<(HST_SIZE*3);iScoreLoop++)
                {
                    scoretable[iScoreLoop].Initial1=65;
                    scoretable[iScoreLoop].Initial2=65;
                    scoretable[iScoreLoop].Initial3=65;
                    scoretable[iScoreLoop].Score=0;
                }
            }
            break;
        default:
            // Shouldn't be anything else
            break;
    }
}

/**********************************
*     Saves data into flash memory:
*  - QRandom() seed
*  - Mr Robot's palette
*  - High score table
*
* First byte will be the MAGIC_NB
* and subsequent bytes will be the stored data
* data[1] == Random Seed
* data[2] == Mr Robot Palette
* data[3]-data[3+(HST_SIZE*2)] == HighScore Table
* High Score entry
* byte0=INITIALS
* byte1=SCORE
**********************************/
void SaveDDMR(u16 MrRobotPalette, u8 Difficulty, SCORE HighScoreTable[])
{

    u32 data[256];
    u8 iScoreLoop;

    GetFlash(&data);
    data[0]=MAGIC_NB;
    data[1]=GetRandomCounterSeed();
    data[2]=MrRobotPalette;
    data[3]=Difficulty;
    for(iScoreLoop=0;iScoreLoop<(HST_SIZE*3);iScoreLoop++)
    {
        data[4+(iScoreLoop<<1)]=((u32)HighScoreTable[iScoreLoop].Initial1<<24)+((u32)HighScoreTable[iScoreLoop].Initial2<<16)+((u32)HighScoreTable[iScoreLoop].Initial3<<8);
        data[5+(iScoreLoop<<1)]=((u32)HighScoreTable[iScoreLoop].Score);
    }
    SetFlash(data);

}

And then changed (a little bit by trial and error) the original library.c functions like so:

Code:
void SetFlash(void *data) {
    
    // The "data" array needs to have the magic number (MAGIC_NB)
    // in position zero

    // Calling function needs to set this as follows:
    // data[0]=MAGIC_NB
    // What you do with the remaining elements is up to you

    // Set the save offset and block number
    // These need to be equal to the ptr number in GetFlash()
    // SAVEOFFSET 0x1FA000
    // +
    // BLOCK_NB 0x21
    // = 0x3FA000
    // No, I don't quite get it either, but these are the numbers that
    // seem to work...

    __ASM("SAVEOFFSET    EQU    0x1FA000");
    __ASM("BLOCK_NB        EQU    0x21");

    // Other variables are fixed and refer to the various system calls required by the flash write
    __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
    // Set low/high data size (0 low + 2 high=512 bytes, I think?)
    __ASM("    ld    ra3,0"); 
    __ASM("    ld    rbc3,2");    // 512 bytes
    // Call the Flash write routine
    __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");
}

void GetFlash(void *data) {
    
    // Set the pointers up to the flash memory address
    // Needs to be the same as address used in SetFlash()

    u32 *ptr = (u32*)(0x3FA000);
    u32 *ptrData = (u32*)data;
    u8 i;
    // Check the read data for the "magic" number
    // Basically, an arbitary number that we have in data[0]
    // If this isn't set then the data hasn't been initialised

    if (*ptr == MAGIC_NB) // Data saved
    {
        for (i=0;i<128;i++)
            ptrData[i] = ptr[i];
    }
    else // No data
    {
        // If the magic number is not set, then set MAGIC_NB+1 to the first element of the array
        // and then set everything else to zero
        // The calling routine can then set the array up as you see fit (default values etc)
        // and then set data[0]=MAGIC_NB to enable writing
        ptrData[0] = MAGIC_NB+1;
        for (i=1;i<128;i++)
            ptrData[i] = 0x00;
    }
}

The magic number can be anything you like, it's literally just a sequence of bytes that you wouldn't expect to see normally. Thor's original one was to use 0xcafebabe and I didn't see the need to change that

The last piece of the puzzle, at least when you flash to flashmasta/retrohq is to pad the ROM file to 2mb - winteriscoming used a .py script for that, but I used the following windows command script to do the same thing (so I don't have to have python installed) - certutil and fsutil should be available on any standard Win10/11 installation

Code:
ECHO Padding:
echo ff ff ff ff ff ff ff ff>ff.txt
certutil -decodehex ff.txt ff.pad
FOR /L %%f IN (1,1,18) DO (
    ECHO PASS %%f
    COPY /b ff.pad+ff.pad ff.pad2 >NUL
    DEL ff.pad
    REN ff.pad2 ff.pad
)
copy /b MRROBOT.ngp+ff.pad TEMP.ngp
del MRROBOT.ngp
del ff.txt
del ff.pad
ren TEMP.ngp MRROBOT.ngp
fsutil file setEOF MRROBOT.ngp 2097152
Reply


Messages In This Thread
New Game Block Dude (Port) - by scomico - 02-06-2022, 01:53 PM
RE: New Game Block Dude (Port) - by Flavor - 02-08-2022, 05:18 AM
RE: New Game Block Dude (Port) - by KeiDash - 02-08-2022, 08:20 PM
RE: New Game Block Dude (Port) - by Ahchay - 02-09-2022, 01:17 AM
RE: New Game Block Dude (Port) - by Flavor - 02-09-2022, 09:04 AM
RE: New Game Block Dude (Port) - by Ahchay - 02-09-2022, 06:51 PM
RE: New Game Block Dude (Port) - by sodthor - 02-09-2022, 07:59 PM
RE: New Game Block Dude (Port) - by sodthor - 02-10-2022, 04:01 AM
RE: New Game Block Dude (Port) - by scomico - 01-19-2026, 01:38 PM
RE: New Game Block Dude (Port) - by sodthor - 01-22-2026, 09:33 PM
RE: New Game Block Dude (Port) - by Ahchay - 01-23-2026, 09:39 PM
RE: New Game Block Dude (Port) - by Ahchay - 02-04-2026, 02:58 AM
RE: New Game Block Dude (Port) - by Ahchay - 02-04-2026, 02:59 AM

Forum Jump:


Users browsing this thread: 1 Guest(s)