NESRAM - a dual-port RAM NROM-128/256 cartridge!

Discuss hardware-related topics, such as development cartridges, CopyNES, PowerPak, EPROMs, or whatever.

Moderator: Moderators

Post Reply
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

So, I had a crazy idea and decided to follow it through... I have created a shield for the Arduino Mega 2560 that substitutes two 16K dual-port RAM chips in place of the PRG & CHR ROMs, and a breakout board to connect the necessary signals to the NES cartridge port.
IMG_20171108_1454412.jpg
IMG_20171108_15030231.jpg
The Arduino accesses the CHR-RAM chip via its built-in XMEM (eXternal MEMory) interface, which means it is just like writing to internal RAM from the Arduino's perspective.

Why? Because this gives you read / write access to both pattern tables (8K), and all four name tables (4K, no mirroring), from outside of the NES. You could then use the Arduino to dynamically update tile data / attributes on-the-fly for example, while the NES does its reads / writes from the other side of the dual-port RAM!

The PRG data is stored in the Arduino's flash memory and uploaded to the dual-port PRG-RAM on start-up. There is only one XMEM interface on the Arduino though, so PRG-RAM is written sequentially all in one go, using two SN74HC590A 8-bit binary counters to increment through the addresses being written, ascending in order. So it is possible to update PRG data on-the-fly as well, but only using 'sequential access' - not 'random access'. PRG doesn't have to be dual-port RAM though, it could just be an EEPROM. But, this certainly made testing simpler! I am using a 16K chip at the moment (NROM-128), but it could be swapped out for a 32K chip (NROM-256) easily - the extra signals are already connected.

As a demonstration / proof-of-concept I decided to try using the pattern tables as a 256x128 screen buffer. I took some games written for the Arduino-based 'Arduboy' console, and re-wrote the display routines to output the screen buffer as NES tiles, continually updated directly into CHR-RAM - all the NES has to do is read and display the same set of tiles over and over (I also needed to add in a sprite-zero hit half way down to switch pattern tables, so I could get all 512 tiles on screen at once).

The sound is just a square wave from a single Arduino pin, going through a 270K resistor into EXP6 on the cartridge port, and then through the usual 47K resistor from EXP6 to 'Audio-In' underneath on the NES expansion port.

There is definitely more information to be explained here, and I am happy to answer questions, but for now I am just really excited to actually have a proof-of-concept that I can share!

https://www.youtube.com/watch?v=OAwb10NGNno
https://www.youtube.com/watch?v=FkIiFlbovt0
Last edited by uXe on Tue Nov 07, 2017 11:43 pm, edited 1 time in total.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by lidnariq »

uXe wrote:There is only one XMEM interface on the Arduino though, so PRG-RAM is written sequentially all in one go, using two SN74HC590A 8-bit binary counters to increment through the addresses being written, ascending in order. So it is possible to update PRG data on-the-fly as well, but only using 'sequential access' - not 'random access'.
I think you could use A15 (and an inverter) to select between the two RAMs' chip enables. ... or if you want a really cheap option, A14 and A15. (After all, the internal RAM keeps you from accessing most of the region where A15 and A14 are both low, and you wouldn't want to address both RAMs at the same time anyway... at least not usually)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by tokumaru »

Pretty cool!
uXe wrote:As a demonstration / proof-of-concept I decided to try using the pattern tables as a 256x128 screen buffer. I took some games written for the Arduino-based 'Arduboy' console
Since you're using 1bpp graphics, you could actually have 1024 unique tiles using a little palette trickery... You can display the individual planes of an NES tile by using the following palettes:

Black, white, black, white: plane 0 will show;
Black, black, white, white: plane 1 will show;

This is an easy way to create full screen 1bpp images on the NES. You can still use the sprite 0 hit for switching pattern tables mid screen if you arrange the name tables like this:

8 rows: tiles 0-255 of PT0 using palette 0;
8 rows: tiles 0-255 of PT0 using palette 1;
(sprite 0 hit here)
8 rows: tiles 0-255 of PT1 using palette 0;
6 rows: tiles 0-192 of PT1 using palette 1;

Or you could use timed code instead of sprite 0 hits.
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

lidnariq wrote:I think you could use A15 (and an inverter) to select between the two RAMs' chip enables. ... or if you want a really cheap option, A14 and A15. (After all, the internal RAM keeps you from accessing most of the region where A15 and A14 are both low, and you wouldn't want to address both RAMs at the same time anyway... at least not usually)
Good idea! At the moment A14 & A15 of the XMEM interface are unconnected, and I am addressing CHR-RAM as if it were a 16K block from 0x4000 to 0x8000 because of the way the Arduino eats up the first 8,704 bytes of address space.

I am still weighing up how beneficial it is to have PRG as dual-port... but can definitely see the potential for playing with CHR using the dual-port RAM.
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

tokumaru wrote:Pretty cool!

Since you're using 1bpp graphics, you could actually have 1024 unique tiles using a little palette trickery... You can display the individual planes of an NES tile by using the following palettes:

Black, white, black, white: plane 0 will show;
Black, black, white, white: plane 1 will show;
Nice! Hadn't explored that far yet, the Arduboy games are only 128x64 and I'm already doubling that up to be 256x128.

At the moment I am using a "Black, white, black, white" palette because there are a couple of individual pixels that are always on-screen for the sprite-zero hit, and I'm using the black to 'hide' them. :P
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by rainwarrior »

This looks neat.

I'm reminded of a similar project by Batsly Adams from a while back:
http://www.batslyadams.com/2014/05/nes- ... rface.html
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

rainwarrior wrote:This looks neat.

I'm reminded of a similar project by Batsly Adams from a while back
Yes! I remember reading this one too (PS. the spammers have really gone nuts in the comments on Batsly's blog... :cry: )

Dual-port RAM is heaps of fun to play with! I used a dual-port FIFO in another project controlling the GameBoy's LCD (again, to play Arduboy games on!):

https://hackaday.com/2015/08/18/arduboy ... oy-screen/
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by tokumaru »

It would be cool if the whole PPU memory was dual-ported, name tables included. It'd actually be nice to have more than 12KB of it too, that the NES could access through bank switching.
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

tokumaru wrote:It would be cool if the whole PPU memory was dual-ported, name tables included. It'd actually be nice to have more than 12KB of it too, that the NES could access through bank switching.
Name tables are included. I have 'CIRAM /CE' ('VRAM /CS') held high on my cartridge breakout board, which disables the NES' internal 2K of VRAM. And PA0-PA13 are all wired to the dual-port RAM, so the name tables are stored there - no mirroring. All four name tables could be used if you wanted to.

EDIT: You would also be able access space at $3000-$3EFF (that is usually just a mirror of $2000-$2EFF).
Last edited by uXe on Sat Nov 11, 2017 8:47 pm, edited 1 time in total.
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

Only the Palette RAM at 0x3F00 to 0x3FFF is not accessible - "writing to the internal palette range (3F00-3FFF) will not assert /WR" (from https://wiki.nesdev.com/w/index.php/PPU ... escription)
User avatar
uXe
Posts: 27
Joined: Sun Nov 25, 2012 5:28 am
Location: Adelaide, Australia

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by uXe »

Had a bit of fun experimenting some more with the dual-port CHR-RAM tonight - overwriting the nametable palette attributes in Galaxian with rotating values... disco aliens!! :mrgreen:

https://www.youtube.com/watch?v=VhZj0wh9AVE
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: NESRAM - a dual-port RAM NROM-128/256 cartridge!

Post by lidnariq »

uXe wrote:I am still weighing up how beneficial it is to have PRG as dual-port...
One answer that immediate pops out to to me is streaming DPCM samples, since the Atmega has more than enough power to mix and convert.

Of course, you only really need one byte of dual-ported RAM for that...
Post Reply