It is currently Wed Oct 23, 2019 2:58 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Some hardware questions
PostPosted: Mon Jul 15, 2019 1:37 am 
Offline

Joined: Mon Jul 15, 2019 1:11 am
Posts: 5
Hello there. I've been crawling through google and some of the wiki but I'm either blind or some info is just not there :). (It's not exactly the most common asked questions so yeah..).

I will, hopefully, at some point in the future create my own small NES game and a corresponding cartridge. In the spirit of nintendo cartridges I obviously want to augment it with additional features so here are some questions:

Anyway:
1) What is the common thought about the maximum power draw on a cartridge? I would like to add some additional components and don't want to fry any systems in the process...

2) When writing to/reading from PRG RAM, how fast has the RAM to be in order for a successful read? (Or is the NES waiting for some latch to process further?).

3) On a component level, when writing to PRG RAM how can I intercept/read it on the physical cartridge? What pins does it correspond to? (or is it as easy as just the usual address lines?)

4) Would a mapper complicate this process? I could I just intercept my PRG RAM calls before any mapper is involved?

I will create a board completely from scratch, flash my own flash chips, flash and solder an AVRCIC and add my additional components.

In case anyone is interested in the actual project: I'm trying to implement an NRF52832 (bluetooth chip) on the board and have it act as PRG RAM. So if for example I progress in the game (take metroid for example) I can read the states on the bluetooth chip and sync it with an android app over BLE. That's just an easy example but I guess much more is possible.

Thanks in advance, feel free to ask any questions.


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 10:41 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8626
Location: Seattle
Schinken wrote:
1) What is the common thought about the maximum power draw on a cartridge?
My best guess is that you've got somewhere around 500mA for the cartridge. There's a 1A regulator, and the NES seems to consume roughly 400mA.

Quote:
2) When writing to/reading from PRG RAM, how fast has the RAM to be in order for a successful read? (Or is the NES waiting for some latch to process further?).
M2 is true (high) for about 350ns. /ROMSEL is true (low) for the same, but delayed roughly 30ns, so cartridge hardware has about 320ns to both 1- detect that the CPU accessed memory regions at $7FFF and below and 2- get a response out, if appropriate.

Writes may not have the correct value on the data bus until after M2 has risen. Reads just have to be in by the time M2 falls.

Quote:
3) On a component level, when writing to PRG RAM how can I intercept/read it on the physical cartridge? What pins does it correspond to? (or is it as easy as just the usual address lines?)
By "PRG RAM" do you mean "extra RAM on the cartridge for the CPU's use"? Just the usual address lines, except that you don't have access to A15 directly.

Same's more-or-less true for the 2K of RAM that's in the console for the CPU's use, only the NES itself takes care of knowing when to activate it.

Quote:
4) Would a mapper complicate this process? I could I just intercept my PRG RAM calls before any mapper is involved?
This isn't like USB or PCIe; there's no concept of a physically isolated bus for different components. There's something physically responsible for telling other components to respond to reads and writes at specific addresses.

Quote:
In case anyone is interested in the actual project: I'm trying to implement an NRF52832 (bluetooth chip) on the board and have it act as PRG RAM. So if for example I progress in the game (take metroid for example) I can read the states on the bluetooth chip and sync it with an android app over BLE. That's just an easy example but I guess much more is possible.
Implementing a ROM or RAM emulator in a CPU will seriously tax your CPU. The most famous example of success is the Atari 2600's Harmony Cart, which emulates a 32KB ROM (and a few special functions) used by a 1.2MHz 6502 with a 70MHz ARM.

Faster CPUs often have to worry about cache misses and the cost of a context switch (e.g. IRQ). 320ns might sound like forever, but each cache stall could easily eat 100ns by itself.


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 11:27 am 
Offline

Joined: Mon Jul 15, 2019 1:11 am
Posts: 5
Thanks for the elaborate answer! Really appreciated. 500mA is plenty. I guess i'll be around the 30-40mA range (for the IC alone) so theres plenty of padding.

Quote:
By "PRG RAM" do you mean "extra RAM on the cartridge for the CPU's use"? Just the usual address lines, except that you don't have access to A15 directly.

Same's more-or-less true for the 2K of RAM that's in the console for the CPU's use, only the NES itself takes care of knowing when to activate it.

Yes I'm talking about additional RAM on the cartridge (as in battery backed RAM for savegames?). I've read that A15 is not passed through to the cartridge connector, how would one go about accessing this? Or do I not even need that address line? Sorry for my very noobish questions here, I know I'm trying to dive way too fast into this complex topic.


Quote:
This isn't like USB or PCIe; there's no concept of a physically isolated bus for different components. There's something physically responsible for telling other components to respond to reads and writes at specific addresses.

I see, so in laymans words: I have to filter some adresses to generate a corresponding trigger for my specific address range? Doesn't sound too hard.

What about having an actual RAM chip sitting there and having my IC read/write to that while M2&/ROMSEL are in their off-states (NES CPU not doing anything on that?). I guess I could prepare the data and then have an interrupt routine run when the CPU is not accessing. As I only need to access the RAM once in a while (read/write) and that is probably initiated by the app that would leave the BLE chip in a more relaxed state.


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 11:45 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8626
Location: Seattle
Schinken wrote:
I've read that A15 is not passed through to the cartridge connector, how would one go about accessing this? Or do I not even need that address line?
Depends. You can just only use the memory region where A15 is high (addresses $8000-$FFFF), and then not worry about it.

If you really want to use the "conventional" region for RAM – $6000-$7FFF – you'll have to use M2 and /ROMSEL and some analog delays to piece out what A15 would have been.

Quote:
What about having an actual RAM chip sitting there and having my IC read/write to that while M2&/ROMSEL are in their off-states (NES CPU not doing anything on that?).
The NES CPU is always driving the address bus. There's no moment – save when the NES CPU is held in reset by the CIC – where another part could drive the address bus and control lines.

You're basically talking about a "dual ported RAM". There's many ways to make this: they can be simply purchased but they're quite expensive. There are lots of ways to fake one, including using an FPGA or expliclt multiplexer parts.

Previous wireless things that people have built have mostly interfaced with the NES's controller ports, which looks like SPI. It's a lot lower bandwidth, but that's not necessarily a problem.


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 11:49 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21644
Location: NE Indiana, USA (NTSC)
You have a signal on the Game Pak edge connector called /ROMSEL. This is A15 NAND M2: when A15 and M2 (the CPU clock) are both high, this signal goes low about 30 nanoseconds (ns) after the rising edge of M2. Ordinary ROMs use /ROMSEL as a chip enable for PRG ROM.

When M2 is high and /ROMSEL is high, this must mean A15 is low. So if M2, /ROMSEL, A14, and A13 are all high, then A15-A13 must be 011, representing an address in $6000-$7FFF. The circuit described in that article feeds these four signals (M2, /ROMSEL, A14, and A13) to a 4-input NAND gate to create an enable signal at $6000-$7FFF. This is fine for many purposes.

Now here's where the "analog delays" come in: Because /ROMSEL is delayed by about 30 ns, the enable signal from the 4-input NAND will have a 30ns wide low pulse when $E000-$FFFF is accessed, momentarily enabling the memory. For ROM reads, this doesn't hurt. But for mapper writes, it could cause a problem. MMC3, for example, puts the IRQ enable and disable in this region, and some PowerPak mappers have had bugs where IRQ-related writes to $E000 or $E001 end up scribbling over $6000-$6001 as a side effect. So a reliable PRG RAM decoder circuit would need to either A. not put any mapper registers in $E000-$FFFF or B. add a bit of hysteresis to rising edges of M2 so that /ROMSEL is correct by the time M2 rises.

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 12:14 pm 
Offline

Joined: Mon Jul 15, 2019 1:11 am
Posts: 5
Thanks for both your answers! Looks like I got some homework to do. I'll try to concentrate on the RAM problem for now. FPGA is an option though I've done very little with these...

Just one more clarification question: Isn't the PRG RAM (battery backed RAM) only accessed when I do a read/write in the game? I don't need a lot of writes one use case would be for example to refresh my life counter or something (think tingle tuner from the wind waker) so I'd just set a flag in RAM that corresponds to "lifes refreshed" and then check that every few frames and if it is that just go into a routine, handle the life counter refreshing and set the flag to off?

I might be totally wrong here but that would leave me with only occasional access on the RAM and the microcontroller can just wait until there is no read/write?

Thanks anyway so far, I'm currently reading up on the PRG RAM circuits.


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 12:28 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8626
Location: Seattle
Schinken wrote:
Just one more clarification question: Isn't the PRG RAM (battery backed RAM) only accessed when I do a read/write in the game?
Yes, but lots of existing commercial games used the cartridge RAM to augment the 2KB that was in the console. Some commercial games that were originally released on the Famicom Disk System execute code out of cart RAM.

Quote:
I might be totally wrong here but that would leave me with only occasional access on the RAM and the microcontroller can just wait until there is no read/write?
The problem isn't really "can the coprocessor wait" - although bluetooth may or may not let you stall like that - but rather "will other physical things conspire such that the CPU can't respond to a read or write in time".


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 12:38 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11418
Location: Rio de Janeiro - Brazil
Schinken wrote:
Isn't the PRG RAM (battery backed RAM) only accessed when I do a read/write in the game?

While the main motivation for including battery backed RAM to a cartridge may have been the ability to save the player's progress, we're talking about an extra 8KB of RAM on a system with only 2KB of built-in RAM, so it'd be kinda silly to not use all that extra RAM for more than just saving. Lots of games used it for level maps and other large data structures, but also as general purpose RAM.


Top
 Profile  
 
PostPosted: Mon Jul 15, 2019 12:55 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 9:28 pm
Posts: 4210
Location: A world gone mad
I had a feeling the context regarding why the OP wanted to do this would come up. Taken from Discord:

Quote:
[1:04 AM] Schinken: I'm not really into nes development right now (only read a few tidbits here and there). Basically what I'm currently imagining is something like this: Have a regular cartridge (PRG ROM, CHR ROM, maybe a mapper though I don't think my programming skills would make a game complex enough to use one) and then have a microcontroller (right now thinking of a nrf52832 Bluetooth chip) that I can control and exchange data with it. The nrf52832 also has the ability to act as NVRAM. I could then use that in conjunction with an android app to probably to some cool stuff (like have a map on my phone that gradually gets explored as the game progresses). But there are so many variables, for example I don't know how fast the microcontroller would need to be to be an SRAM replacement etc


Top
 Profile  
 
PostPosted: Tue Jul 16, 2019 12:16 am 
Offline

Joined: Tue Oct 06, 2015 10:16 am
Posts: 975
Ah, making an anachronistic WiiU :D


Top
 Profile  
 
PostPosted: Wed Jul 17, 2019 1:29 am 
Offline

Joined: Mon Jul 15, 2019 1:11 am
Posts: 5
Basically ;).

Anyway I think I came up with a feasible (but not universal) solution.

Basic setup: PRG ROM, PRG RAM, CHR RAM, BLE IC, some transistors.

The transistors are put on the RAM Datalines, the IC can turn them on/off. In my NES code I will query an reservered adress in RAM, if that address returns 0 I know that the IC is busy with the ram and to try again later. If I get a preset value (255 for example) I know the RAM is free to access from the NES side.
On the IC side I can check the CPU R/W (or ROMSEL) to see if the CPU is accessing RAM and wait until its free.

Basically: IC is polling some datalines to determine RAM availability
CPU is polling some RAM address to determine RAM availability

With my current understanding there should be no conflicts anymore. It's not fast and not elegant but it should work I guess?

(Edit: Of course this only works somewhat reliable when specifically programmed for it ;)).

Edit2: After some more thoughts I noticed that I would need dual transistors for the data lines (to enable write I guess). As far as I found out there are special bus switch ICs that do just that.

Edit3: Or I could just pull the lines low with transistors and resistors... KISS

Edit4: Yes I'm realising i'm talking to myself :>. I attached my idea of that "RAM Check Circuit" if anyone is interested


Attachments:
Schematic_NES-CARTRIDGE-NRF52_Sheet-1_20190717122142.png
Schematic_NES-CARTRIDGE-NRF52_Sheet-1_20190717122142.png [ 78.9 KiB | Viewed 1762 times ]
Top
 Profile  
 
PostPosted: Wed Jul 17, 2019 10:38 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8626
Location: Seattle
Hold on a sec. There're no spare data lines that can be reserved for your peripheral. There's only one data bus¹, and it goes to every part that the CPU can access, and you have to keep your parts from driving it high or low most of the time in order for anything else to work at all.

You'll have to add hardware to detect a specific otherwise unused address (or range of addresses) and only drive the data bus at the right time. It's very unlikely that /ROMSEL is enough to determine this; R/W is definitely not enough.

There are specific 74xx parts that are made for this decoding process; you might use a 74hc138 or a 74hc133; there are other options. To let the NES's CPU read a value from your coprocessor, you might use a 74hc244.

¹pedantically, there are four data buses: the CPU's - eight bits wide, the PPU's - also eight bits wide, and one for each controller - both five bits wide. The first two both have the constraint that multiple different devices are present and for correct functioning and all peripherals need to agree about when things happen. The last two would work fine for this except that you can only access three of the bits on each controller jack in front, and the remaining two bits are only accessible via the expansion port on the bottom of the front-loading NES.


Top
 Profile  
 
PostPosted: Thu Jul 18, 2019 1:11 am 
Offline

Joined: Mon Jul 15, 2019 1:11 am
Posts: 5
Oh.... OOOOH. And so it dawned upon me.
I guess....

So mappers aren't just fancy ways to mirror your memory but also to extend it. And the PRG RAM addresses are basically just "convention" and I could put my stuff anywhere?


Top
 Profile  
 
PostPosted: Thu Jul 18, 2019 4:51 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 21644
Location: NE Indiana, USA (NTSC)
You can put your stuff anywhere with two caveats:

  1. You can't make anything readable at address space already reserved by the system, which is $0000-$3FFF and $4015-$4017.
  2. Immediately after power is applied, you have to make something readable at $FFFC-$FFFD, which is the reset vector, and at the addresses where the reset vector points.

_________________
Pin Eight | Twitter | GitHub | Patreon


Top
 Profile  
 
PostPosted: Thu Jul 18, 2019 3:25 pm 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 161
lidnariq wrote:
Implementing a ROM or RAM emulator in a CPU will seriously tax your CPU. The most famous example of success is the Atari 2600's Harmony Cart, which emulates a 32KB ROM (and a few special functions) used by a 1.2MHz 6502 with a 70MHz ARM.


If one wasn't interested in using the 6502 for game logic beyond what could fit in 2K of internal RAM, nor in running game logic except during vertical blank, one might be able to get by with a relatively modest ARM having ten I/O pins, along with a couple of 74HC373 or similar chip to isolate it from the CPU and PPU data buses except during reads (the other two I/O wires would go to the address LSB of both buses). Having more I/O than that would make things more convenient, but if the ARM output $01 for every even address and $80 for every odd address that is preceded by an even address, and $4C for every odd address that's preceded by another odd address, the reset vector would go to $8001, after which execution would repeatedly process JMP $8001 with addresses going odd-even-odd-odd-even-odd etc. Once the ARM saw that a few times, it would know the CPU was running code and could start feeding it individual instructions for LDA #xx / STA $0000 / LDA #$xx / STA $0001 / etc. to load up the 2K of internal RAM, and then start executing code in RAM and poll $8000 for a magic value. After that, the ARM could start outputting $00 while it watches the LSB of the PPU address to figure out when each frame starts, wait for the end of that frame, and start outputting some other value to notify the main CPU that it wants to talk to the main CPU. Once that's all done, the ARM could take turns talking to the main CPU during vblank while feeding PPU data during the active part of each frame.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 9 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group