How to read/write Sonic 3 FeRAM

Discussion in 'Sega Discussion' started by cage, Oct 30, 2011.

  1. cage

    cage Member

    Joined:
    Oct 28, 2011
    Messages:
    10
    Likes Received:
    0
    I just finished building a genesis cart reader and it seems to be dumping my carts perfectly. I'm not sure how to handle the save data issue in general.

    How do you read and eventually write to the save data portion of the cart, specifically Sonic 3?
     
  2. Chilly Willy

    Chilly Willy Robust Member

    Joined:
    Mar 15, 2011
    Messages:
    242
    Likes Received:
    0
    The sram is at 0x200000 on odd bytes (0x200001, 0x200003, 0x200005, etc). You should be able to just read it normally, but technically, you should "move.b #1,0xA130F1" first, which enables the sram. Sonic 3 does that in the init part of the code when it starts. Setting 0xA130F1 to 0 disables the sram.

    From what I've heard on SpritesMind, the save ram in Sonic 3 is always on and setting it to 1 isn't needed, but they put it in there in case the game is attached to a S&K cart, in which case it IS needed.

    As long as a game is 2MBytes or less, the save ram doesn't need to be disabled. If a game is larger than 2MBytes, you have to enable and disable the save ram, which then disables and enabled (respectively) reading the rom at 0x200000 instead of the save ram.

    The FRAM in Sonic 3 is the same as battery backed up SRAM, but doesn't need the battery.
     
  3. cage

    cage Member

    Joined:
    Oct 28, 2011
    Messages:
    10
    Likes Received:
    0
    Thanks for the information.

    I tried reading 0x00200001 - 002003ff directly but this was giving me back all 0 (dec). Right now I'm just trying to dump all even/odd sram with no luck.

    I'm currently using an Arduino similar chip and I mocked up the reader quickly in their own "language". I've attached a sample of what I'm using and it does work as intended for reading data between 0x0 - 0x001fffff. Maybe I'm missing something simple here?
     

    Attached Files:

  4. Eke

    Eke Spirited Member

    Joined:
    Apr 6, 2010
    Messages:
    117
    Likes Received:
    2

    This won't work since you are not using the Mega Drive, the cartridge itself does not decode write to this address, it only enables RAM between $200000-$3FFFFF when !TIME (B31 on cartridge port) is asserted and D0 is HIGH, which is what console hardware does when software writes $01 to $A130F1.

    So basically, if your arduino board let you do that, you must set B31 LOW (or high, not sure if it's really active low) while D0 is HIGH to enable RAM, then read it from odd bytes between $200001-$23FFFF.


    Out of topic, I found this to dump SRAM/FRAM (but EEPROM as well) for cartridges, using a flashcart and some hardware mods:

    http://68000.web.fc2.com/sram.html

    This guy seems to use it with an USB connector but I can't read japanese:
    http://ponrevival.blogspot.com/2011_10_01_archive.html
     
    Last edited: Nov 2, 2011
  5. cage

    cage Member

    Joined:
    Oct 28, 2011
    Messages:
    10
    Likes Received:
    0
    Hmm...

    I tried different variations of setting the TIME signal high or low but when its called I receive seemingly random data. I'm comparing sections of what I read from the cart to what gens/kega fusion produce as a .srm file.

    The actual save data on the physical cart should have some similar sections in my .srm file. For example I should be the ascii characters L,D,Z somewhere but I mostly get variations of 01,255 (DEC).

    This one has me stumped :(

    digitalWrite(dataline[0], HIGH);
    digitalWrite(TIME, HIGH); // tried HIGH/LOW and putting in different order
    shiftoutAddress(0xA130F1/2);
     
  6. Jorge Nuno

    Jorge Nuno Active Member

    Joined:
    Aug 10, 2011
    Messages:
    28
    Likes Received:
    0
    Ok I did a MD dumper sometime ago, Ill try to help.

    First thing you need to do is initialize all critical control bits to inactive state (1)
    In case of S3, IIRC it uses /Time, /LWR, /VRes, /CAS0, /CE0 {B31, B28, B27, B17, B16}

    After init, you set up the oncart reg to access the Fe-RAM:
    Set /VRes to 0,
    Set /VRes to 1, (reset on-cart flipflop)
    Map pin d0 to output and set it to 1,
    Set /Time to 0, (enable Fe-RAM flipflop)
    Set /Time to 1,
    Map pin d0 to input.


    Do a loop running through the addresses of interest, and assert the control signals appropriately:

    -:
    Set /CAS0 and /CE0 to 0, (cart enabled)
    Get data from dBus,
    Set /CAS0, /CE0 to 1, (cart disabled)
    Increment address,
    Loop -

    If you want do dump rom afterwards:
    Reset address
    Map pin d0 to output and set it to 0,
    Set /Time to 0, (disable Fe-RAM flipflop)
    Set /Time to 1,
    Map pin d0 to input.

    do the loop as before.


    Make sure the wait time between each instruction is 200ns or more (MCU/PLD running at 5MHz maximum clock)
     
    Last edited: Nov 2, 2011
  7. l_oliveira

    l_oliveira Officer at Arms

    Joined:
    Nov 24, 2007
    Messages:
    3,895
    Likes Received:
    252
    I don't know the specifics for the RAMTRON FERAM chip used on the SONIC3 cartridge but on some FERAM chip designs the act of reading the memory causes destruction of the contained data so it has to be written back after being read... :shrug:
     
  8. Jorge Nuno

    Jorge Nuno Active Member

    Joined:
    Aug 10, 2011
    Messages:
    28
    Likes Received:
    0
    In that case, after reading the dBus Set /LWR to 0, and then to '1'.

    Should take care of content destruction

    One thing I forgot, you dont need to output the 0xA13000 address, just assert /Time accordingly.
     
    Last edited: Nov 2, 2011
  9. Eke

    Eke Spirited Member

    Joined:
    Apr 6, 2010
    Messages:
    117
    Likes Received:
    2
    Hum yes, I forgot about this signal.

    For reference, here is the cartridge schematic, from HardwareMan:

    [​IMG]
     
    Last edited: Nov 2, 2011
  10. cage

    cage Member

    Joined:
    Oct 28, 2011
    Messages:
    10
    Likes Received:
    0
    I got the reading of the feram portion seemingly working thanks to the detailed info provided by Jorge Nuno.

    My simple dumper was pulling /CAS0, /CEO low using a 10k resistor and pulling /RESET high using another 10k resistor. Pulling /RESET high was only needed for Sonic 3 and was actually left disconnected when I was first building the circuit. Even without /RESET pulled high I was able to correctly read all my carts except for Sonic 3.

    I didn't know I needed /LWR when reading the feram. I wasn't aware that I had to manipulate all those extras lines considering my pin count on my board is reaching its limit very fast.

    I can also confirm what l_oliveira mentioned about the reading of the feram being a destructive process. Now it makes sense that the data was continually changing on me. Jorge Nuno's second post about setting /LWR low then high fixed that issue.

    The whole odd/even sram reading and the 0xA130F1 address doesn't apply in my case. Actually reading only the odd addresses produces only half of the intended data. I needed to read all address between 0x00200001 and 0x002003ff. I figure that information is pertinent if you're actually running code on the physical sega genesis.

    The only issue that I noticed is in the comparison of my dumped data vs the srm file produced by gens/kega fusion. I needed to delete the first character of my file and then both emulators would correctly load the sram. I'm not sure what's going on here. Kega Fusion's sram also seems to replace 0x00 with 0xFF for some reason.

    Thanks to everybody who chimed in here. There's a ton of great information here.
     
  11. l_oliveira

    l_oliveira Officer at Arms

    Joined:
    Nov 24, 2007
    Messages:
    3,895
    Likes Received:
    252
    Just a final comment of mine, reading the FERAM chip is a destructive process on the literal meaning of the word ...:lol:

    It also destroys the chip.

    So every time you turn on your Mega Drive to play SONIC 3 your backup memory dies a little bit out ... :lol:
     
  12. Chilly Willy

    Chilly Willy Robust Member

    Joined:
    Mar 15, 2011
    Messages:
    242
    Likes Received:
    0
    You need to look at the bus section of the 68000 manual. Remember that you need to be simulating 68000 bus cycles. That's important for reading/writing. As an example, you wrote

    Ignoring whether the lines are being set the to proper active state, you are not simulating the bus operation correctly. You are setting the address AFTER setting TIME. Address lines must be stable BEFORE any strobes are asserted; ditto for writing data. Try to match the bus waveforms in the 68000 manual at least as far as minimum setup times and order of assertion.
     
  13. Eke

    Eke Spirited Member

    Joined:
    Apr 6, 2010
    Messages:
    117
    Likes Received:
    2
    From cartridge port, you can only manipulate VA1-VA23 (VA0 is internal to 68k) and the cartridge does not make differences between 8-bit or 16-bit reads, so you are actually reading words at $200000,$200002, ... and so on up to $2003FE, with only the low byte holding valid data. This makes a total of 512 bytes of data (FeRAM chip has are 9 address lines, connected to VA1-VA9).

    Not sure why you had to delete the first byte (maybe something with the way you write those bytes back or issue with endianness) but about this:

    you are missing the last byte, it should probably be

    Also, something you need to know is that emulators always handle SRAM as 16-bit, even if most SRAM chips are only 8-bit. The reason they do this is that 16-bit SRAM chips are also used in a few games.

    Now, Kega initializes SRAM with $FF (again, it's required by some games to work properly) so unused bytes (even ones) will remain this way.
     
    Last edited: Nov 4, 2011
  14. TmEE

    TmEE Peppy Member

    Joined:
    Aug 13, 2008
    Messages:
    362
    Likes Received:
    1
    luckily Sonic3 uses only small part of the FeRAM chip so you can tie one of the unused upper lines to some other state and get another working page ^^
     
  15. Chilly Willy

    Chilly Willy Robust Member

    Joined:
    Mar 15, 2011
    Messages:
    242
    Likes Received:
    0
    Which ones? I'm not aware of any. That's why no flash card out uses 16 bit sram - they all use 8 bit sram on odd addresses.
     
  16. Eke

    Eke Spirited Member

    Joined:
    Apr 6, 2010
    Messages:
    117
    Likes Received:
    2
    NFL95 and NFL98 do, probably a few other EA sport games.
    I think they don't work with flashcart for this particular reason.
     
  17. Chilly Willy

    Chilly Willy Robust Member

    Joined:
    Mar 15, 2011
    Messages:
    242
    Likes Received:
    0
    Thanks! I'll have to look into that.
     
  18. cage

    cage Member

    Joined:
    Oct 28, 2011
    Messages:
    10
    Likes Received:
    0
    I'm just looking over the ssf2 technical docs and it mentions the following as an example:

    If 0x08 is written to register 0xA130F9, the first 512KB of the normally invisible upper 1MB of ROM is now visible at 0x200000-0x27FFFF.

    So how would I implement this?

    Considering that writing $01 to $A130F1 is setting d0 to 1 and flipping /time on/off.
    What's the equivalent to writing to the
    0xA130F9 address?
     
  19. Eke

    Eke Spirited Member

    Joined:
    Apr 6, 2010
    Messages:
    117
    Likes Received:
    2
    When !TIME and !RW are asserted, SSF2 cartridge hardware decodes:

    . VA1-VA3 to know which 512k region (out of eight available in 4MB area) is being remapped.
    . VD0-VD3 (maybe more, depends of max addressable ROM size) to determine which 512k ROM bank (out of ten for a 5MB game) is being mapped to the given memory region.

    So obviously you need to drive those signals as well.
     
    Last edited: Nov 14, 2011
  20. cage

    cage Member

    Joined:
    Oct 28, 2011
    Messages:
    10
    Likes Received:
    0

Share This Page