Original Post

Hi everyone,

is there any trick when accessing the SAVERAM using the Flashboy Plus? I tried storing some values and everything works fine in RealityBoy. However, when I use the Flashboy I get strange results from data not being stored to randomly changing data.

Does anyone know how to fix this?

25 Replies

Ok… it seems to work now. Can anyone tell me how many bytes of SRAM are avalibiable?

Hi. This tripped me up too. It turns out only the even byte addresses in SRAM are accessible. The Flashboy has 8K of SRAM.

Just like the SRAM on a regular cartridge, it’s only an 8-bit wide chip on the 16-bit wide bus… so you have to access it through even addresses only.

DogP

I just noticed that SRAM access is till glitchy in GameHero. Obviously I am doing something wrong, even though I am only writing an accessing the even bytes.

Could you post some example code how to write 10 bytes to the SAVERAM and then access it again?

Thanks for the clarifications, guys. I’d also love to see some working example code as I am also still having problems. Thanks! 🙂

I guess no one got this working so far.

OK, this seems to work for me:

void saveToRam(u8 value, u8 pos)
{
	SAVERAM[(pos*2)+1] = value;
}

u8 getFromRam(u8 pos)
{
	u8 value = SAVERAM[(pos*2)+1];
	
	return (u8)value;
}

void clearRam(u8 offset, u8 range)
{
	u8 i = 0;
	
	for(i=offset; i

Cheers,

thunder

Thanks thunder, I was able to fix the save function of VUE Snake using your functions. 🙂 An u8 is not sufficient to address the whole SRAM, though. Here’s the corrected functions:

void saveToRam(u8 value, u16 pos)
{
	SAVERAM[(pos*2)+1] = value;
}

u8 getFromRam(u16 pos)
{
	u8 value = SAVERAM[(pos*2)+1];
	
	return (u8)value;
}

void clearRam(u16 offset, u16 range)
{
	u16 i = 0;
	
	for(i=offset; i

Does being able to write only even addresses mean that we can only use 4kb? Or is it actually a 16kb SRAM of which we can use 8kb?

That wouldn’t make sense. Maybe we just have to read/write 16 bits at a time and use masking to access odd-numbered bytes. Like this (untested):

void PokeSRAM (u16 Index, u8 Value)
{
  if(Index & 1)
  {
    Index >>= 1;
    ((u16*)SAVERAM)[Index] = (((u16*)SAVERAM)[Index] & 0xFF00) | Value;
  }
  else
    SAVERAM[Index] = Value;
}

u8 PeekSRAM (u16 Index)
{
  if(Index & 1)
    return ((u16*)SAVERAM)[Index >> 1] & 0x00FF;
  else
    return SAVERAM[Index];
}

Ok, as there are still some people having problems writing to the SRAM I programmed a little test program. It simply writes a changing value to the SRAM and reads it again. If the value that has been read isn’t the one that has been written the test fails. The program tests this for the complete 4k. I tested this using RealityBoy and on Hardware using my FlashBoy Plus. It worked perfectly on both systems.

This is how I write/read the SRAM:

static u16* const	SAVERAMX =	(u16*)0x06000000;

void mem_setToSRAM(u16 pos, u8 value)
{
	SAVERAMX[(pos*2)] = value;
}

u8 mem_getFromSRAM(u16 pos)
{
	u8 value = SAVERAMX[(pos*2)];
	
	return (u8)value;
}

void mem_clearSRAM(u16 offset, u16 range)
{
	u8 i = 0;
	
	for(i=offset; i<(offset+range); i++)
	{
		mem_setToSRAM(i, 0);
	}
}

I know it is not proper c formated code with fancy shifting and all of that stuff but it works for me. I hacked the test program together pretty fast... so there might be something wrong there.

I hope this helps!

Attachments:

Ahhh, there are 8k of RAM…. I will keep on testing!

Ok, here is the update. The program now test 8k. It still works on both systems. Also Kr155e pointed out a bug in the clearRam function so here is the fixed one:

static u16* const	SAVERAMX =	(u16*)0x06000000;

void mem_setToSRAM(u16 pos, u8 value)
{
	SAVERAMX[(pos*2)] = value;
}

u8 mem_getFromSRAM(u16 pos)
{
	u8 value = SAVERAMX[(pos*2)];
	
	return (u8)value;
}

void mem_clearSRAM(u16 offset, u16 range)
{
	u16 i = 0;
	
	for(i=offset; i<(offset+range); i++)
	{
		mem_setToSRAM(i, 0);
	}
}
Attachments:

So all 8K can be used, but the position has to be multiplied by two?

EDIT:
But you are declaring SAVERAMX as a pointer to u16, but your functions only read and write bytes, so does the actual position have to be multiplied by four? So is the actual address 0x06000000 + (position << 2)? EDIT 2: But the VB is big endian, so the actual address that the byte gets written to/read from is 0x06000003 + (position << 2)? I am very confused by this.

  • This reply was modified 12 years ago by HorvatM.

The SRAM is a 8-bit wide chip on a 16-bit wide bus, so you have to access it through even addresses only.

Well, I looked at the SRAM file of your test program produced by Reality Boy with a hex editor and only every other byte was nonzero. But eg. Galactic Pinball can use every byte. Since the FlashBoy Plus is compatible with all commercial games, how does it do that?

HorvatM wrote:
Well, I looked at the SRAM file of your test program produced by Reality Boy with a hex editor and only every other byte was nonzero. But eg. Galactic Pinball can use every byte. Since the FlashBoy Plus is compatible with all commercial games, how does it do that?

That’s interesting… I have no freaking clue. I guess this needs further investigations. If I try to write into the uneven bytes it always fails. Writing 8k isn’t a problem when I only accessed the even bytes. That’s also how I understood DogP and Dasi.

KR155E is going to test the SRAM access the way I did it in Blox 2. Let’s see what happens there.

KR155E is going to test the SRAM access the way I did it in Blox 2. Let’s see what happens there.

My initial recode of the save functions in Blox 2 did not work, so I have to debug it. This is not much fun, so I have no idea when I’ll be in the mood. So… better don’t wait for me. 😉

@thunderstruck: Thanks for sharing your code and running the tests.

HorvatM wrote:
But the VB is big endian …

Actually, the VB is little-endian.

As thunderstruck states, the save RAM is an 8-bit device, but the VB has a 16-bit bus. In other words, there is no “0th” address line. No matter what address you access, it becomes “even” at the cart connector (i.e. the address is, in effect, boolean ANDed with 0xFFFF_FFFE). Since the SRAM’s A0 is connected to the VB’s A1 (and so on) each byte in the chip is read/written as a 16-bit word on the VB (thus, incrementing the address by one results in every address being used twice).

The only explanation I can see for what you observed with GP is that the (pragmatic) author(s) didn’t see the need to waste time clearing the upper (unwritten) byte before writing a word to SRAM, but the emulator author decided (correctly, IMO) that such writes should be preserved (although it may have been pragmatism in this case, too ;-)). This effect could be used by a VB program to detect whether it is running in an emulator or on hardware, but the emulator could just as easily be patched to prevent said detection…

I understand that the lowest bit is always zero, but if you look at GP’s SRAM, you will see that, for example, the player names are stored as consecutive ASCII characters, and it uses all 8K of the SRAM. So how does it access the odd bytes? Does the SRAM support 16-bit I/O or what?

  • This reply was modified 12 years ago by HorvatM.

Seems a bit odd to me.

Isn’t the SRAM hooked to the same bus as the rom but only half of the data lines hooked up?

Is it the data lines that are used every second one and not just the upper or lower half?

So is the SRAM using D1, D3, D5, D7, D9, D11, D13, D15 instead of just D0-D7 or D8-D15?

Guess I could open a cart and have a look…

 

Write a reply

You must be logged in to reply to this topic.