A bit of background first.
Some years ago(turns out it was years ago, damn time flies) I seen that Google's April Fools video: https://www.youtube.com/watch?v=rznYifPHxDg and it got my mind racing. Back then I was too young and knew almost nothing about electronics and very few about coding. Since that I became proficient with coding and started getting in to electronics as well. So to learn more about electronics, making your own circuits, etc, I started coming up with project ideas. This is my preferred way to learn new things: start a project on topic I know almost nothing about and learn through research along the way. Before I was doing it with coding projects and I was able to say if project is possible before taking on it. Now I need your expertise to do same for my crazy NES/Famicom related project.
To be clear, I am not looking for a extensive guide on how to do what I want, I just looking for an confirmation that it is possible in a way I see it, and maybe some pointers on where to start.
Now about the idea. I gave it away a bit already by that Google's video, but I'll clarify further: I'd like to make device that would contain inside something like Pi Pico W or something similar, and would make NES think that it is a cartridge, but would have internal processing to allow features like internet OR contain very complex games that would normally fit in to cartridge memory OR implement rom selector OR everything above with some kind of simple OS on top of it.
After doing a bit of reading about cartridges, I see it as kind of mapper, but instead of switching banks with data, it would switch content inside virtual "bank" with simple program that would make NES continuously read same area of memory, but data at those addresses would change. And button presses would make NES to read from some special addresses prompting controller to update information in addresses NES constantly reads.
By the "reading addresses" I mean that my controller would read address lines and push out data from internal buffer on bus lines, and not an actual ROM chips.
First few things that made me think that it might be impossible to do(at least in form that I was going to) are:
- CIC chip - is it hard to replicate or is it possible to just buy one, add to my circuit and forget about it?
- Microcontroller boot time - I read that Pi Pico takes about 100ms to boot and start executing user code. Can NES wait for the controller to start spewing out data? Or can I feed it NOOP codes from some simple microcontroller with no boot time, while main one boots? Or I would have a proper rom chip with some simple rom loaded to keep NES busy meanwhile?
- 60 or 72 pins. That is a lot. Pi Pico has only 40 pins and only around 30 of those are GPIO pins I can use to communicate with NES. But I would assume that I can skip some of those pins and NES would still load the "game". So what is an absolute minimum of pins I should connect and control? I would assume I need address bits, but if I limit myself to smaller address space, I can skip some address pins, right? But what about rest of the pins? Do I need those extension and audio pins? What can I leave hanging, what should have a pull-up/down-resistor on it?
- Voltage. As far as I can see, NES is 5V based system, but what is threshold for a high signal? Can I feed it 3.3V signals from Pi Pico or should I use 3.3->5 signal converters/use controller based on 5V signals?
One last note: I own Subor's clone of Famicom, so I targeting 60 pin cartridge and PAL, but if everything would work out - I can expand it to support NES and NTSC if there would be an interest.
Crazy project by newbie, what can go wrong?
Moderator: Moderators
Re: Crazy project by newbie, what can go wrong?
I recently saw a tweet from some Famicom developer who is doing basically exactly this, although he called out theRasteri's NES DOOM as the most immediate inspiration:
https://twitter.com/HD64180/status/1600367593931800577
If you have spare pins on the RP2040 (big if), you should be able to use the second CPU inside the RP2040 to emulate the CIC on those pins. But no-one's already done that, so you'd have to port the algorithm yourself (not hard) and get the cycle-exact timing (ugh)
If you stuffed the data bus with constant "$40", the 2A03 would see that as "JMP $4040" and as long as it kept fetching $4040 the address bus is pinned at $4040, $4041, $4042. Similarly, you could stuff the data bus with constant "$4C", which would be seen as "JMP ($4C4C), contents of ($4C4C) are themselves $4C4C", and the address bus would count $4C4C $4C4D $4C4E $4C4C $4C4D.(edit: oops, braino) The bytes are $4C (JMP $4C4C) and $6C (JMP ($6C6C)), and the address bus sequences would be $4C4C $4C4D $4C4E repeat; $6C6C $6C6D $6C6E $6C6C $6C6D repeat.
However, in both of these cases, you would have to make a point of only switching out at the moment that the jump is happening, not in the middle of an instruction.
Don't even bother trying until you've managed this with separate Picos for PRG and CHR.
https://twitter.com/HD64180/status/1600367593931800577
Search for "avrciczz".
If you have spare pins on the RP2040 (big if), you should be able to use the second CPU inside the RP2040 to emulate the CIC on those pins. But no-one's already done that, so you'd have to port the algorithm yourself (not hard) and get the cycle-exact timing (ugh)
Nope, NES waits for no man. The amount of time you have before the CIC releases the 2A03 is about 100ms, which is uncomfortably similar.- Microcontroller boot time - I read that Pi Pico takes about 100ms to boot and start executing user code. Can NES wait for the controller to start spewing out data?
There's exactly two instructions that you could stuff the data bus with to keep the CPU busy until you can override it. They are both jumps.Or can I feed it NOOP codes from some simple microcontroller with no boot time, while main one boots?
However, in both of these cases, you would have to make a point of only switching out at the moment that the jump is happening, not in the middle of an instruction.
This is by far the simplest: use the 2A03 because it is a CPU, even if a slow one, and elicit its cooperation.Or I would have a proper rom chip with some simple rom loaded to keep NES busy meanwhile?
It will basically not doable in just one Pico to handle both CPU and PPU. RP2040 has way too few pins to do that, and trying to multiplex things will be an order of magnitude harder.- 60 or 72 pins. That is a lot. Pi Pico has only 40 pins and only around 30 of those are GPIO pins I can use to communicate with NES. But I would assume that I can skip some of those pins and NES would still load the "game". So what is an absolute minimum of pins I should connect and control? I would assume I need address bits, but if I limit myself to smaller address space, I can skip some address pins, right? But what about rest of the pins? Do I need those extension and audio pins? What can I leave hanging, what should have a pull-up/down-resistor on it?
Don't even bother trying until you've managed this with separate Picos for PRG and CHR.
You must use voltage protection to keep from damaging the NES or the RP2040. However, you're correct that the voltage thresholds used by the NES are "TTL" and not "CMOS", so 3.3V will be received by the CPU as logic high. This means that "voltage clamp" chips like the GTL2000 can be used as opposed to full "translation" chips like the 74AVC16245.- Voltage. As far as I can see, NES is 5V based system, but what is threshold for a high signal? Can I feed it 3.3V signals from Pi Pico or should I use 3.3->5 signal converters/use controller based on 5V signals?
Re: Crazy project by newbie, what can go wrong?
Minor nitpick: JMP $XXXX is opcode $4C and JMP ($XXXX) is opcode $6C - opcode $40 is RTI.lidnariq wrote: ↑Wed Dec 14, 2022 8:52 pm There's exactly two instructions that you could stuff the data bus with to keep the CPU busy until you can override it. They are both jumps. If you stuffed the data bus with constant "$40", the 2A03 would see that as "JMP $4040" and as long as it kept fetching $4040 the address bus is pinned at $4040, $4041, $4042. Similarly, you could stuff the data bus with constant "$4C", which would be seen as "JMP ($4C4C), contents of ($4C4C) are themselves $4C4C", and the address bus would count $4C4C $4C4D $4C4E $4C4C $4C4D.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
- rainwarrior
- Posts: 8732
- Joined: Sun Jan 22, 2012 12:03 pm
- Location: Canada
- Contact:
Re: Crazy project by newbie, what can go wrong?
Two examples which might be useful to look at:
1. PartytimeHXLNT made the "ConnectedNES" which was an open source project that could connect to Twitter via the controller port.
https://www.nobadmemories.com/connectednes/
2. Broke Studio was working on a "Rainbow' Wifi cart as well, which I think has some working prototype applications at this point, and some available emulated simulation:
viewtopic.php?t=17408
1. PartytimeHXLNT made the "ConnectedNES" which was an open source project that could connect to Twitter via the controller port.
https://www.nobadmemories.com/connectednes/
2. Broke Studio was working on a "Rainbow' Wifi cart as well, which I think has some working prototype applications at this point, and some available emulated simulation:
viewtopic.php?t=17408
Re: Crazy project by newbie, what can go wrong?
Wow, answers so fast and so detailed. You guys are awesome community ![Very Happy :D](./images/smilies/icon_biggrin.gif)
You got me some thing to think about, so thank you very much! I will let you know how I go![Smile :)](./images/smilies/icon_smile.gif)
![Very Happy :D](./images/smilies/icon_biggrin.gif)
You got me some thing to think about, so thank you very much! I will let you know how I go
![Smile :)](./images/smilies/icon_smile.gif)