EEPROM mapping for homebrew

For anything related to cart (SRAM, SF2 mapper, audio, CD mode 1, ...)

Moderator: BigEvilCorporation

Post Reply
Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

EEPROM mapping for homebrew

Post by Sik » Mon Apr 01, 2019 10:47 pm

It's generally agreed upon that using EEPROM for saved games is a better idea than SRAM+battery both for cost reasons and because batteries are troublesome (you lose everything when they deplete and/or change them and there's risk of leaks if you leave them for too long). But I don't think we ever agreed on some scheme for EEPROM on homebrew games? This is particularly troublesome since every publisher seems to have done whatever they felt like it and ROM header doesn't provide enough information, so emulators resort to databases and it's a pain to develop homebrew using EEPROM.

One suggestion was to use a setup like follows:
  • Bit 0 as SDA
  • Bit 1 as SCL
  • Map EEPROM somewhere in $A130xx (gotta pick an address)
The first two is how Sega opted to wire EEPROM, while the last one is because, erm, mapping it to $200000 means more decoding needed by the cartridge itself (while $A130xx already gets /TIME for that) and especially if the ROM is over 2MB. Since there already wasn't any agreement before, we may as well make our own mapping.

The other issue is that we need to settle on an EEPROM size, since different sizes have different ways to select the address (the smallest ones only have one address byte, larger ones have two address bytes, even larger ones have three). I suppose 32KB or 64KB would work but would be nice to settle on one.

And finally, include this in the ROM header (probably where the SRAM information would usually go, that gives us 12 bytes). Ideally, it should include the EEPROM size, just in case we insist on having room to go for different ones. This way emulators can be updated to detect this setup without resorting to databases (and have homebrew built against this spec).


Anyway, discuss, I want to have people settle on something so I can document EEPROM on Plutiedev :v

EDIT: assembled a list of $A130xx address ranges that I know are used up
https://www.plutiedev.com/a130xx-usage
Sik is pronounced as "seek", not as "sick".

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Re: EEPROM mapping for homebrew

Post by Chilly Willy » Tue Apr 02, 2019 1:43 pm

Having a custom EEPROM spec for homebrew is probably a good idea. Most existing EEPROM games use a single byte at $200001, and it's reflected in the header. Emulators, and the NeoMyth menu, generally look for a save ram space of one byte to auto-select EEPROM mode as no actual battery backed up ram will actually be only one byte. The header for custom EEPROM could be like the save ram spec from sega, but give an address space in $a130xx. That would certainly be easy for emulators and flash carts to detect.

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: EEPROM mapping for homebrew

Post by Sik » Tue Apr 02, 2019 9:36 pm

…yeah good point, if we use the $A130xx range which nobody else used, emulators may as well use that to autodetect the mapping instead of making up a new type.

Incidentally, Genesis Software Development Manual [Version 2.0] [1991-07-09].pdf has more detailed information on the ROM header than GenesisSoftwareManual.pdf:

Image

As you can see, EEPROM was always meant to be marked in a special way! And the fourth byte actually has a meaning, it wasn't an ASCII space (unless that was retrofitted after the fact?). Bits 4-0 there are still unused (as in offcially reserved), maybe we could use them to indicate the EEPROM size? (EDIT: disregarding the following sentence, may go with a different shift factor) Maybe 1<<(n+7) bytes, and then use that to figure out the protocol, the largest size would be 256 GB which I think is probably large enough.

So now we have to settle on an address. $A130E8 seems tempting (it's the gap between Mega Everdrive and the MARS signature), but I just sent an e-mail asking krikkz if he intends to use up that space too. If he does then we may need to look at a different address.

$A13000-$A1300F is used by Pier Solar for its custom stuff, maybe I'll claim that range is reserved for private use since that stuff isn't "standard".
Sik is pronounced as "seek", not as "sick".

Chilly Willy
Very interested
Posts: 2984
Joined: Fri Aug 17, 2007 9:33 pm

Re: EEPROM mapping for homebrew

Post by Chilly Willy » Wed Apr 03, 2019 1:01 am

That's nice. Always wondered what some of those bits were for. Yeah, I'd say using the reserved bits for something like a shift value would probably be the way to go.

Mask of Destiny
Very interested
Posts: 615
Joined: Thu Nov 30, 2006 6:30 am

Re: EEPROM mapping for homebrew

Post by Mask of Destiny » Wed Apr 03, 2019 6:44 pm

My 2 cents: standardizing the mapping (i.e. which address and which I2C bits are connected where) is good, but I think allowing the size to be specified in the header is desirable. It might make sense to pick a single "mode" (i.e. how the address is sent), but from my perspective supporting any of the modes that are already used by existing games is no big deal. For the devices used in commercial games, there's a 1:1 mapping between size and mode, but that's not universally true. If you wanted to simplify the header you could require that devices that follow that relationship be used though.

The other parameter that needs to be specified is the page size. This mostly correlates to size, but Eke's EEPROM doc (which I recommend reading if you haven't already) has some exceptions. In practice, this isn't that important (I haven't gotten around to emulating the page behavior yet in BlastEm and it doesn't seem to have caused any problems), but it is needed if you want to completely specify the EEPROM's behavior.

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Re: EEPROM mapping for homebrew

Post by TmEE co.(TM) » Wed Apr 03, 2019 10:14 pm

I would use an SPI or µWire EEPROM instead rather than I2C types, they're much easier to talk to (thus less hardware). Here's something I devised a while ago :
Image
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

HardWareMan
Very interested
Posts: 745
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Re: EEPROM mapping for homebrew

Post by HardWareMan » Fri Apr 05, 2019 7:10 pm

I'd would change it like this:
Image

TmEE co.(TM)
Very interested
Posts: 2440
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Re: EEPROM mapping for homebrew

Post by TmEE co.(TM) » Fri Apr 05, 2019 7:28 pm

Yeah, that would work better, no bus fights possibility at all ~
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: EEPROM mapping for homebrew

Post by Sik » Fri Apr 05, 2019 8:30 pm

Back from laptop maintenance. I was going with the I2C ones because they were more well known I guessed? (and emulators already support some of them, which makes it easier to test) Also for reference, this is what Sega did (X24C01, SDA at bit 0, SCL at bit 1, $200001):

Image

That looks messier than it is, the board has five chips (ROM, EEPROM, 7432, 7474, 74125), so really only one more compared to the SPI ones mentioned here. This does include the decoding of $000000-$1FFFFF vs $200000-$3FFFFF tho, I didn't check to see how much would be simplified by going with $A130xx (where separating ROM vs EEPROM comes for free thanks to /TIME).

As for size: well yeah, bits 4-0 of the fourth byte. My idea was to pick one common EEPROM chip and assign it to each size (the ones already used in existing games would be assigned to their respective sizes, I don't think there were any incompatible ones with the same size?).

If we insist on also including SPI, I propose we assign it a new type (bits 7-5 of fourth byte). 001 is SRAM, 010 is I2C EEPROM, I suppose 011 could be SPI EEPROM? (I mean, Sega only assigned the first two, so we can do whatever we want with the rest).


EDIT: in fact looking at it some more it does seem that the 7432 is there mainly because of the address decoding (which is the very thing we're trying to simplify by going to $A130xx). So yeah, maybe it's possible to do away with it (meaning I2C is just as hard as SPI in this sense), though I haven't bothered to check how it'd work with /TIME so not confirming anything. Something to look into, anyway.
Sik is pronounced as "seek", not as "sick".

Sik
Very interested
Posts: 939
Joined: Thu Apr 10, 2008 3:03 pm
Contact:

Re: EEPROM mapping for homebrew

Post by Sik » Sun Apr 07, 2019 3:44 pm

Double post but it just hit me: I'm being dumb. Whether it's dealing with two or three support chips (SPI vs EEPROM) is not a big issue, the bigger issue was dealing with ROMs over 2MB. If left in $200001 then one would need to resort to implementing $A130F1 and that'd make things a lot more complex, but by moving EEPROM to /TIME that situation can be avoided (as ROM and EEPROM don't overlap). Kind of important since most homebrewers aim for 4MB.

OK so:
  • We need to pick some common EEPROM chips we're willing to support
  • We need to assign them values for the 4th byte
  • We need to pick an address
  • We need to determine bit assignments for I2C
  • We need to determine bit assignments for SPI
For the 4th byte format, %010xxxxx would belong to I2C EEPROM, %011xxxxx would belong to SPI EEPROM (will anybody use Microwire EEPROM?). Would need to define how to specify xxxxx, was thinking about it indicating size as 1<<n bytes (where n = xxxxx), and each particular size maps to one of the agreed upon chips.

For the address, been thinking about putting it officially at $A130E9 (of course, this only matters if the cartridge has more than one thing in /TIME, but it'd be nice to settle on one address). Any objections?

As for bit assignments: for I2C I wanted SDA in bit 0 and SCL in bit 1 (which is how Sega did it). So how should it work for SPI? (looking at those schematics, it looks like bit 0 for data in, bit 1 for data out, bit 2 for clock and bit 3 for… enable? am I reading right?)
Sik is pronounced as "seek", not as "sick".

Post Reply