Raspberry pi in a NES cart

A place where you can keep others updated about your NES-related projects through screenshots, videos or information in general.

Moderator: Moderators

rasteri
Posts: 15
Joined: Sat Dec 09, 2017 6:30 pm

Raspberry pi in a NES cart

Post by rasteri » Sat Dec 09, 2017 8:11 pm

Hello, I'm very much a newcomer to this board, and to NES development in general, so excuse any stupid questions or faux pas. I imagine all this stuff is basic to you guys but I haven't been able to find anyone doing a project like this so I would appreciate some input.

I was disappointed when this project - https://howchoo.com/g/mti0oge5nzk/pi-ca ... -cartridge - turned out to just be another Raspberry Pi case mod. It got me thinking - could you actually put a Pi in a cart and have it output video through the NES? Running any game that the Pi can on an unmodified NES seemed like a fun idea. I was hoping the NES had a simple composite passthrough or something, but that would be too easy!

I suppose the "proper" way to do it would be to have the Pi fill some RAM attached to the PPU's memory bus, but that limits us to 256 different tiles and 16x16 attribute areas. I guess you could do some kind of pattern-matching thing that squashed similar patterns together, or map the pattern and attribute tables to a larger virtual address space using scanline-synced binary counters or something, but I'm lazy and stupid and it just made my head hurt.

So I thought - since we know the exact sequence the PPU will fetch data, why not ignore the address bus entirely and just feed it bytes in the correct order? Since we can feed it different pattern and attribute bytes for each 8x1 pixel area, that gives us 8x1 attributes and a unique pattern for each tile.

Anyway, long story short, I've (mostly) got it working :

https://www.youtube.com/watch?v=CxBBYujFDYM

Right now I'm squirting pre-generated 40970 byte (170 bytes per scanline * 241 scanlines) packets to the PPU using a high-speed USB-to-parallel-FIFO chip (FT232H). There's a small PRG rom that sets up the palette and turns on rendering, as well as sending frame-sync commands back to the Pi. Unfortunately the first-generation Pi I'm using isn't quite fast enough to generate the palette-matched and Floyd-Steinberg dithered frames on-the-fly, but I expect the Pi 3 would have enough power to do it.

I guess my questions are :

1. Has anyone done any work on converting images into NES-friendly formats? I've tried using various homebrew per-frame palette generating algorithms, but nothing seems to work as well as manually hand-picking a palette.

2. What would be the best way of getting controller input back to the Pi? I was thinking a binary comparator on the PRG address lines feeding the chip enable pin of an 8-bit latch, but I'm not really a hardware guy so I'm sure there's a simpler way than that. Keep in mind the process latency on a Pi is far too high to be able to sit directly on a traditional CPU bus.

3. I don't want to reinvent the wheel, so has anyone done any work in this sort of area before? Again I'm a total newcomer to the NES scene (in fact I'd never even played a NES before starting this project, they weren't very common in the UK, haha).

I will of course share source code if anyone's interested.

lidnariq
Posts: 8780
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Raspberry pi in a NES cart

Post by lidnariq » Sat Dec 09, 2017 8:37 pm

Oh man, we've been talking about this for years! It's really cool to see someone actually did it.
rasteri wrote:attribute bytes for each 8x1 pixel area
How do you pick which palette to use?
palette-matched and Floyd-Steinberg dithered frames on-the-fly
Temporal dithering will dramatically improve the video quality, too. ( http://www.pouet.net/prod.php?which=60939 )
1. Has anyone done any work on converting images into NES-friendly formats? I've tried using various homebrew per-frame palette generating algorithms, but nothing seems to work as well as manually hand-picking a palette.
Unfortunately, the only work I've seen was thefox's converter.
2. What would be the best way of getting controller input back to the Pi? I was thinking a binary comparator on the PRG address lines feeding the chip enable pin of an 8-bit latch, but I'm not really a hardware guy so I'm sure there's a simpler way than that. Keep in mind the process latency on a Pi is far too high to be able to sit directly on a traditional CPU bus.
The NES controllers are basically SPI slaves; the NES CPU manually runs the bus.

A pair of latches, a decoder, and having the code on the 2A03 read and relay the values is probably the simplest option, as you guessed.

rasteri
Posts: 15
Joined: Sat Dec 09, 2017 6:30 pm

Re: Raspberry pi in a NES cart

Post by rasteri » Sat Dec 09, 2017 9:17 pm

lidnariq wrote: How do you pick which palette to use?
For each pixel in the slice it finds the palette that has the closest color match, then whichever palette has the most matches "wins" that slice. I'm sure there must be better/more efficient algorithms.
Temporal dithering will dramatically improve the video quality, too. ( http://www.pouet.net/prod.php?which=60939 )
Awesome, I hadn't heard of that but I see some commercial LCD panels do it too. As I understand it, instead of shifting the error onto nearby pixels a la Floyd-Steinberg, you shift it onto the following frame?

lidnariq
Posts: 8780
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Raspberry pi in a NES cart

Post by lidnariq » Sat Dec 09, 2017 9:53 pm

Exactly.


One time I was playing around with temporal dithering, I just used a plain white noise source (LFSR of prime period) and added it to my intended signal. Then I truncated the result to the available output depth. Since the noise source is stationary, I don't need to explicitly propagate error either spatially or temporally. But I also treated RGB independently, which means that the error signals are 1-dimensional, and the random walk is guaranteed to return average 0.

This was in preparation for trying to use Cypress's EZ-USB parts to bit-bang a VGA subset (24MHz R2G2B2) but never managed to figure out how to write the host support.

calima
Posts: 1016
Joined: Tue Oct 06, 2015 10:16 am

Re: Raspberry pi in a NES cart

Post by calima » Sun Dec 10, 2017 2:05 am

While Pi 1 does not have Neon, it does have some simpler SIMD instructions. Using those to optimize your code might make it fast enough.

User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2032
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Raspberry pi in a NES cart

Post by FrankenGraphics » Sun Dec 10, 2017 7:28 am

Headsup that the link to fox's converter in that thread is dead.

Here's the correct one:
https://kkfos.aspekt.fi/downloads/nes-i ... -2-v01.zip

It achieves a higher colour fidelity by flicking palettes and tables each line and frame, which many HDTV:s won't reproduce. This effect could be achieved (with the right screen) though there will be some some side effects from the strobe-as-interpolation when the whole screen is changing a lot (like camera movement in a 3d game). It may come across as either smudgy motion blur (perfectly ok, actually it could be flattering to the image), or jitter/stutter if the change is extreme enough, probably eye straining or worse in the long run, depending on how much the scene changes from frame to frame.
http://www.frankengraphics.com - personal NES blog

rasteri
Posts: 15
Joined: Sat Dec 09, 2017 6:30 pm

Re: Raspberry pi in a NES cart

Post by rasteri » Sun Dec 10, 2017 7:34 am

I've implemented temporal dithering in my image encoder, and it seems really flickery on my emulated output, but hopefully it'll look better on the NES. I may have to buy a PVM (good luck finding a consumer NTSC CRT in the UK), since I'm guessing that the crappy 240p deinterlacing my TV does will totally mangle it.

Applying a motion blur effect in virtualdub makes it look great, so I guess my algorithm must be OK.

User avatar
Bregalad
Posts: 7766
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Re: Raspberry pi in a NES cart

Post by Bregalad » Sun Dec 10, 2017 1:49 pm

lidnariq wrote:Temporal dithering will dramatically improve the video quality, too. ( http://www.pouet.net/prod.php?which=60939 )
Please, no ! Flickering looks awful on a real NES + real CRT screen.

Other than that, I'm happy to see FINALLY someone trying to push the NES 2A03 to it's "limits", it's about time !

lidnariq
Posts: 8780
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Raspberry pi in a NES cart

Post by lidnariq » Sun Dec 10, 2017 2:18 pm

Have you actually watched Out-oh-mat?

Or the 3840 color VGA tweak mode? (e.g. http://swag.outpostbbs.net/GRAPHICS/0191.PAS.html )

User avatar
Macbee
Posts: 113
Joined: Sat Nov 26, 2011 8:31 am
Location: Brazil
Contact:

Re: Raspberry pi in a NES cart

Post by Macbee » Sun Dec 10, 2017 5:16 pm

I don't know if it's possible to use this on your project, but I like tepples' RGB121:
https://forums.nesdev.com/viewtopic.php ... 4&start=15
https://forums.nesdev.com/viewtopic.php ... 2&start=15

calima
Posts: 1016
Joined: Tue Oct 06, 2015 10:16 am

Re: Raspberry pi in a NES cart

Post by calima » Mon Dec 11, 2017 2:05 am

I've tried some of the flicker ROMs made by the penguin game guy, and they looked awful. I couldn't stand that flicker for long.

User avatar
thefox
Posts: 3141
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: Raspberry pi in a NES cart

Post by thefox » Mon Dec 11, 2017 3:12 am

Cool to see somebody experimenting with this stuff. I have been meaning to do something similar for a long time.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi

M_Tee
Posts: 405
Joined: Sat Mar 30, 2013 12:24 am
Contact:

Re: Raspberry pi in a NES cart

Post by M_Tee » Mon Dec 11, 2017 6:33 am

calima wrote:I've tried some of the flicker ROMs made by the penguin game guy, and they looked awful. I couldn't stand that flicker for long.
By "the penguin game guy" I think you mean Macbee, the member that posted immediately prior to you. :)

I really like the effect in Lucky Penguin and on my particular television and hardware, is pretty seamless. But it is an optional setting for a reason (different hardware and user visual sensitivity, etc.)

User avatar
nesrocks
Posts: 434
Joined: Thu Aug 13, 2015 4:40 pm
Location: Rio de Janeiro - Brazil
Contact:

Re: Raspberry pi in a NES cart

Post by nesrocks » Mon Dec 11, 2017 9:55 am

Flickering on a CRT and real NES is practically unoticeable. It is the way to go if you want to simulate more colors. Just use horizontal flicker, never vertical. When running on an emulator with inconsistent frame rate it can look bad though.

Anyway, this project is amazing. I didn't understand if the input issue has been answered, and I hope it can work.
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!

User avatar
FrankenGraphics
Formerly WheelInventor
Posts: 2032
Joined: Thu Apr 14, 2016 2:55 am
Location: Gothenburg, Sweden
Contact:

Re: Raspberry pi in a NES cart

Post by FrankenGraphics » Mon Dec 11, 2017 10:20 am

I agree that flicker ought to be an option, but it'd be great looking for those who'd be able to view it correctly.


Anyway, i think one last thing one could try to reach higher fidelity is streaming sprite chr and map them to different places where they can improve colour detail or smooth out overly harsh attribute borders. It would be less complex to write code for it if all sprites in effect were treated as one single pixel (basically a particle) or perhaps an 8x1 sliver (ie 1-dimensional), although that would cap some of its potential. And it would need to be optimized so it doesn't waste sprites on exceeded sprites per scanline limits with priorites set wrong.

Unfortunately, OAM is internal so i don't think that could be streamed into. the CPU would be full-time responsible for updating between frames, moving around a select number of sprites... possibly updating one half of the selection one frame and the other half the next.

...

It's a fantastic project, congrats!
http://www.frankengraphics.com - personal NES blog

Post Reply