building a snes flash cart from scratch

Place to talk about all that new hardware and decaying software you have.

Moderator: General Mods

Post Reply
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

building a snes flash cart from scratch

Post by scottjg »

Hi.

I'm trying to build my own flash cart (mostly) from scratch (without an existing snes cart pcb) using modern parts. My goal is to eventually use an fpga to try and recreate some special chip functionality (perhaps using emulator source as a reference). Ideally, the only non-modern special chip required would be the CIC. This is more of an academic endeavor, so I'm very much more interested in learning how all the hardware works.

For my first crack at the design, I'm trying to just get the basic hirom/lorom and maybe save support working. After reading various docs, and looking at cart pcbs, I understand that the cart itself has mapping hardware to dedicate some address space for the save games. Given that a cart could technically map this anywhere, is there an easy way to handle this? How does zsnes know what addresses are dedicated to sram given just a rom?

Also, from the perspective of a cart, what's the difference between HiRom/LoRom? It seems like HiRom just gets more address lines (and presumably faster read speeds). Is there anything special that the cart needs to do to be a LoRom cart vs a HiRom cart aside from the actual rom data?

-sjg
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Re: building a snes flash cart from scratch

Post by grinvader »

scottjg wrote:Given that a cart could technically map this anywhere, is there an easy way to handle this?
No.
How does zsnes know what addresses are dedicated to sram given just a rom?
Heuristics.
(and presumably faster read speeds)
Nope (that's Fast/Slowrom stuff).
Is there anything special that the cart needs to do to be a LoRom cart vs a HiRom cart aside from the actual rom data?
Hi/Lorom is as you mentionned all about mapping, nothing about data. They are supposed to be mapping 'standard's, but a couple "lorom" games have sram in a different place, although the bulk do respect the 'normal' mapping they follow.
It all boils down to PCB traces and that little mapping chip, in the end.

We were just lucky to get only a handful of mappings instead of what the NES got, for instance.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

thanks for the advice.

the easiest heuristic i can imagine is maybe scanning the rom before execution and looking for writes that would normally be mapped to rom. What are some other good heuristics to use?

edit: I just looked at the source. It seems for non-special chip games, they always use banks 07-77 for sram. That shouldn't be too hard to implement...
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

None really... Early on the standard mappings were used, and eventually bug reports pointed out the ones that do not fit.

Like Ys 3, iirc.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

scottjg wrote: edit: I just looked at the source. It seems for non-special chip games, they always use banks 07-77 for sram. That shouldn't be too hard to implement...
Don't trust stuff you see at first in ZSNES source, some of it isn't organized well, and logic could be in other places. Most people miss what's going on in the ZSNES source. So unless you're willing to sit down and trace the code execution through various mapping routines, you're better off just asking for help.

If you're willing to embed logic in your device to scan various locations in the ROM image for certain values, then you can make a cart which maps just as well as our emulators do.

One of the biggest issues you have to deal with is mirroring, which depends on the size of the ROM and RAM. After that, where SRAM appears would depend on the type of features the game makes use of.

The type of features we're referring to:
Large ROM support
Large RAM support
Special chip support
Expansion slot support
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

thanks for the warning, Nach. i just took a cursory glance with grep, so i'm sure i missed plenty.

i think i understand the most obvious mirroring. it seems like lorom carts are traditionally wired so that the a15 line coming from the snes is skipped. so within a bank (which, as i understand is the top byte of the address), the addresses $0000-$7FFF would correspond to identical data at $8000-$FFFF. in hirom, this doesn't happen since that address line is wired through.

given that i'm only trying to understand basic hirom/lorom and saving right now, is there anything else i need to know about mirroring? how does the size of the rom affect how it is mirrored? when you say large ram, is that in reference to sram on the carts? (if not, then what?)

i am planning to have some hardware to scan the roms. for my first spin, i think i'm going to have a microcontroller on the board that controls some buffers that go between the address lines and the flash (this way i can easily remap the address lines to switch between hi/lorom mapping). i can hang a usb port off the controller so it can double as a mechanism to program the flash. later on, this will probably need to be an fpga.

if i understand you correctly, given that the game doesn't use any special snes chips or extended features (no large ram/rom, etc), there is some mapping rom/ram size to sram address. is there a table of this mapping somewhere? is there a formula?
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

scottjg wrote: i think i understand the most obvious mirroring. it seems like lorom carts are traditionally wired so that the a15 line coming from the snes is skipped. so within a bank (which, as i understand is the top byte of the address), the addresses $0000-$7FFF would correspond to identical data at $8000-$FFFF. in hirom, this doesn't happen since that address line is wired through.

given that i'm only trying to understand basic hirom/lorom and saving right now, is there anything else i need to know about mirroring? how does the size of the rom affect how it is mirrored?
The idea with mirroring is that the size of the ROM always appears to the SNES to be more or less the same.

Anything which isn't a size which is a power of 2 has each segment mirrored up until it reaches the size of the preceding segment, until the entire ROM image is a power of 2. The ROM is then repeated through the SNES address space.

To figure out the size of each segment, convert the size to binary, and check for all the 1 bits. The size of a segment is the value of that bit on in binary.

Example 1: 16 - 10000
Power of 2, 1 segment, no extra mirroring.

Example 2: 21 - 10101
3 segments of 16, 4, and 1.
The 3rd segment of size 1 is mirrored twice to equal the preceding segment size which is 4 (1*2*2 == 4). The 2nd and 3rd segment are now merged into one segment which is of size 8 (4+4). Since 8 is half the size of the preceding segment which is 16, it has to be mirrored once (8*2 == 16). Now there are 2 segments of 16 and 16, which together are 32, which is a power of 2, so we're done.

Once you have the mirrored size, leaving out other variables as to special hardware, how to map just the ROM falls into 3 cases.

Case 1: <=2MB.
Case 2: 4MB (there is nothing between 2MB and 4MB since anything in between would be mirrored to 4MB).
Case 3: 8MB

In any of these cases, any access that would say ask for larger than the size of the ROM, for example, in case 2, it asks for byte 2MB + 57 would map to byte 57 byte, since it's repeated through the range (easy math, just modulo by the mirrored size, or and it with the size-1).
scottjg wrote: when you say large ram, is that in reference to sram on the carts? (if not, then what?)
Yes. IIRC, <=256 kilobits was one case, and >=512 kilobits was the other. Technically, if you have an in between size, the same mirroring algo applies here too.

You now basically end up with a total of 18 cases for normal ROM images.
2*3*3. Hi/Lo, size cases, RAM cases, (3rd RAM case is no RAM at all).

However while 18 cases sounds daunting, many of them don't actually exist.
Off the top of my head what I can recall exists (which may be wrong):
Lo, small, none
Lo, small, small
Lo, small, large
Lo, medium, none
Lo, medium, small
Hi, small, none
Hi, small, small
Hi, medium, none
Hi, medium, small
Hi, large, small

Some of these despite being a different case may also map exactly the same way. I don't quite recall exactly.
scottjg wrote: if i understand you correctly, given that the game doesn't use any special snes chips or extended features (no large ram/rom, etc), there is some mapping rom/ram size to sram address. is there a table of this mapping somewhere? is there a formula?
To get the exact mapping table for these cases, I recommend checking both ZSNES and bsnes source, and seeing what you can pull out of it. Hopefully checking both of them, you'll be able to get it.

If you have further questions, just ask.

______
Edit:
Oh, and despite everything I said above, you could design a game to map any which way. Any special hardware cases also have different mapping cases than above.

Some people say the above is either impossible to understand and just seems like black magic, or even though the heuristics work rather well for all known games and makes sense if you contemplate them, you should never use them because a game could violate these rules if whoever wired it / mapped it saw fit to.

So just a disclaimer, beware of a flame war regarding this.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

Hi again. I've been working on this and I have made a lot of progress.

My setup right now is an FPGA that is connected on the SNES cartridge bus. I load the ROM from an SD card into SRAM, and then the FPGA maps the memory so that the SNES can play the game from SRAM.

One of the features that I am still trying to prototype is how to initiate reset from your controller.

As in, you might pick a game from the menu, then start playing the game. Suddenly, you want a new game, so you press some button combo (say, L+R+Start+Select) and it resets back to the menu.

The method I have attempted was to monitor the cart bus on the FPGA, and wait for $4219 (the joypad register) to show up, then read the data to see the state of the buttons, finally the FPGA could decide to initiate a hardware reset if it saw a certain button combo. Unfortunately, the data bus always reads a static $42 while the $4219 address appears on the addr bus (in any bank). Even when I mash buttons, it never seems to change. I don't think it's specific to the game, as it happens in super mario world, and a homebrew demo that shows the joypad status. I'm watching the snes data bus with a logic analyzer, so I'm reasonably sure that it's not just a bug in my code.

I'm wondering if there's anyone familiar with the hardware (neviksti, et all) who might have a hint at what's wrong here (perhaps that register just isn't mapped on the same bus as the cartridge?).

Also, I was wondering if anyone might have an alternative method to trigger reset. I was thinking of trying to patch the rom on-the-fly or something, but i'm not sure how it might work. anyone have any ideas?
gllt
NO VOWELS >:[
Posts: 753
Joined: Sun Aug 31, 2008 12:59 pm
Location: ALABAMA
Contact:

Post by gllt »

I can't help really
but I'm super proud of you, at least of what progress you've mentioned

good job man, congrats
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

According to Anomie's Memory Map document:
Note 1: The address for internal CPU registers may go out Address Bus A,
however the CPU ignores the data bus. It is unknown whether the data bus
is ignored for the whole memory region, or just for those addresses which
are actually registers. It is also unknown whether CPU writes show up on
the data bus or not. Current theory is that addresses and writes will show
up, but reads may or may not, and the data bus is only ignored for those
bits of those registers actually mapped (e.g., data bus is ignored for only
bit 7 of $4211).
If I'm understanding correctly, it seems there's no guarantee internal CPU register data will show up on the cart bus and you may not be able to do what you're trying to do.

However, copiers are able to see controller combos like that and take action. So, there should be some way to do this. I never really looked into copier BIOS nor how they work on the level you need, so I couldn't tell you specifically what they do. :(
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

thanks for the tip, nightcrawler. So I guess my findings reflect anomie's docs.

I've been talking to some people and i guess the solution is to trigger an interrupt from that cartridge pin periodically. During the triggered interrupt, i can feed the snes some code that will check the joypad and write back to the fpga. pretty nasty solution, but i suppose it will do.
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

Hmm.. yeah, that doesn't sound ideal. Keep us updated on how it goes. I'm interested to hear more on the subject.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

err, i didn't want to spam, but since you asked, I am keeping a blog about my project at http://sneshack.blogspot.com/

There has been some progress since my last blog post. It's too bad that I have been short on time, and haven't done a proper write-up yet. Perhaps tomorrow.

At the very least there are some cool pictures on my blog: One of my prototype using a fpga development kit, and another of the custom board that i designed.
Nightcrawler
Romhacking God
Posts: 922
Joined: Wed Jul 28, 2004 11:27 pm
Contact:

Post by Nightcrawler »

That made for some interesting reading. :) How much did it cost you for the PCB run you had made? Who was your vendor? I have the resources to design PCBs myself and have thought about doing some projects, but the cost seemed high when I last looked into it. It's expensive when we have prototype boards made here at work.

I noticed you mentioned you might have problems generating the 5V you will need from your 3V parts. If you need any help with that, let me know. There are several small IC solutions available to up convert if you need to. This can be done a variety of other ways as well such as using a charge pump capacitor setup or a small inductor.

It's much more simple just to power your board with a higher voltage and just use regulators, voltage dividers etc.. to step down to any lower values you may need. For example, using 5V as your main power and come up with something to step it down to 3V is much simpler than using 3V and stepping that up to 5V.
[url=http://transcorp.romhacking.net]TransCorp[/url] - Home of the Dual Orb 2, Cho Mahou Tairyku Wozz, and Emerald Dragon SFC/SNES translations.
[url=http://www.romhacking.net]ROMhacking.net[/url] - The central hub of the ROM hacking community.
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

i ordered these boards from myropcb. it was a bit expensive (~120$ or so). The big issue is that the snes cart connector is thinner than the normal FR4, so a lot of the nice deals on the internet don't apply.

As for 5v io, my current board is powered from the snes bus (5v) and uses a 3.3v regulator and 1.2v regulator to generate the supply for the fpga. I have buffer ics between the fpga and the snes io to step down/up the voltage. Really, the step-up isn't necessary since 3.3v is enough for the snes to recognize the io as a logic 1 (my de2 prototype doesn't do any step-up).

Right now these boards aren't looking too good. There's lots of problems with the design, and my one board that seems to be working ok in my tests won't boot in the snes. very depressing. I'm thinking of taking a less ambitious second-try where I make some boards that mate with the sparkfun xilinx fpga breakout. Hopefully, I can get /something/ to work with these boards, though...
PHoNyMiKe
Retrosexual
Posts: 1011
Joined: Wed Jul 28, 2004 2:09 am
Location: Rapture

Post by PHoNyMiKe »

yo send me a board and I'll solder the stuff on and test it. I have plenty of experience with small soldering and low level hardware. I have an extra 32mbit SF cart (nintendo programmable catridge). I ruined the first one trying to probe it with a µc. the circuitry on it could do both hirom and lorom, no idea how the chip works though.
[url=http://www.alexchiu.com/affiliates/clickthru.cgi?id=phonymike]ultimate immortality[/url]
[url=http://www.sloganizer.net/en/][img]http://www.sloganizer.net/en/image,zsnes,white,purple.png[/img][/url]
scottjg
New Member
Posts: 8
Joined: Sun Sep 14, 2008 9:40 am

Post by scottjg »

thanks for the offer. Unfortuantely, I don't have any boards or parts left at this point. I have enough practice where I can solder the stuff by hand now, so that's not a big issue for me anymore.

I am almost done designing a daughter-board for the sparkfun xilinx eval board, so that I can test my design more incrementally. I think there is a pretty good chance that it'll work. When it does, I will design the whole pcb again. I'm hoping that it'll fit in an original snes cart.
Post Reply