Categories: Arcade, Display Tech, Game Consoles, Hardware
NeoVGA is a scaling solution to facilitate enjoyment of the Neo Geo on modern high-resolution displays without scaling artifacts or processing lag. Here’s an image of it working well to draw you in:
I’ve been messing with FPGAs and VHDL recently, and did a project I’ve wanted to do for a while – kind of.
I have a lot of old systems that output a ~240-line RGB signal, with a 15KHz horizontal sync and 60Hz vertical sync. Newer displays are seldom compatible with it – even my old 90s CRT TV took some modification to get RGB happening on there.
CRTs are very interesting technology and they are still my favorite type of display. However, it’s not good to be locked into them only, as they are obviously worse for watching movies or doing anything made after the 90s. Interlacing looks awful but it’s the only reasonable way to watch movies or do anything modern on it, which is no good.
Feeding an analogue signal directly to a newer TV means it typically has to capture a frame, render it to a buffer, do scaling / interpolation / other image processing, and then output it to the display. This adds latency, and can also severely degrade the image as those algorithms are usually intended for live action scenes and will make anything with high contrast lines and edges look like a mess. It gets worse when you consider how lossy composite video already is, and that almost every modern TV interprets the signal as an interlaced one. Getting an analogue signal, let alone RGB onto a new display is either expensive or mediocre. The best solution would seem to be a good line doubler like the XRGB-3 in B0 mode, which shouldn’t add any lag to the output. An XRGB-3 costs a lot of money though, as do comparable solutions.
So, here comes the DIY solution! The goal here is to make a 2:1 line doubler that simply doubles the horizontal scan rate to 30Khz by doubling each line. This generates a VGA-compatible signal, and further encoding to DVI or HDMI shouldn’t be too difficult as timings are compatible. Now, the “easy” way of doing this might involve capturing a frame into a buffer, scaling that up to the output resolution’s dimensions, then outputting that. In the best case, this involves a frame of latency, and might necessitate interpolation or blocky uneven pixels. Neither is desirable.
The other solution is the classical “line doubling”. Here, the horizontal scan rate is set to be exactly double that of the source signal. Two line buffers are used here. As the RGB source signal renders one line, it is captured into one of the buffers. During this time, the VGA signal is drawing the other buffer twice. Then, the buffers swap, and it runs again, forever. So long as everything is kept in lockstep, this will be a very efficient, no-lag low-memory form of line doubling.
The trouble with this technique is that a doubled scan rate must be obtained. I’m pretty new to VHDL, and while I know I need a phase-locked loop to get my new frequency, I don’t know a thing about how to actually implement such a thing, so I’m stuck there. That’s why the Neo Geo is a system of interest. It has a discrete RGB DAC, with a 6MHz pixel clock that is exposed to me – I don’t have to pull information from the sync signal at all. More importantly, that 6MHz pixel clock is just 1/4 the 24MHz master clock. I decided to take advantage of the 12MHz CPU clock (master / 2) and use it as my doubled clock for line doubling.
Here’s the Neo Geo MV-1C DAC pinned out:
I got this concept first working using just a single bit, and cycle counting:
Here’s my ghetto setup running on an Altera DE2:
I had some stability issues relating partially to poor wiring and GPIO pin choices, making it go crazy sometimes:
I re-did the wiring, making a breakout section on the Neo Geo:
Now it works great:
Scanlines are optional, too. Here it is working on my desktop LCD monitor:
I moved it over to my Xilinx Virtex 2 Pro Dev kit, as I actually own it (unlike the rented Altera board…)
I’m still dealing with a few stability issues since I’ve moved it over, so I have to check over wiring and maybe make a few timing changes. The last thing I want to do is also use the composite sync coming from the JAMMA egde as a sort of reality check to be sure timings have not drifted, as on some bright scenes the screen will start to scroll left or right. I think there is interference making it miss a clock / register an extra one, so I’ll see what can be done with that.
Here’s a video of it in action:
Update: I’ve moved it over fully to the XUP V2P development kit I have, and it has become pretty reliable. I fixed a few color accuracy mistakes as well, and fixed up the sync signal. I am still working on compatibility as a few monitors still don’t want to sync to it properly. The picture above is it working on a GDM series SONY CRT monitor. Check out these close-up shots of KoF ’99 Kasumi Todoh with and without scanlines: