c0pperdragon / C64-Video-Enhancement

Component video modification for the C64 8-bit computer
MIT License
250 stars 36 forks source link

Any plans to improve accuracy? #8

Closed Hojo-Norem closed 5 years ago

Hojo-Norem commented 5 years ago

Colour pallet considerations aside, are there any plans on reproducing VIC-II quirks that rely on its video output circutry such as PAL colour blending and NMOS state transition times?

The first is a quirk that allows for the creation of more colours than the VIC-II can natively produce and is a by-product of the PAL signal generation. More C64 pixelers are starting to take advantage of this. Minor example: palblend (I haven't build your board. The original image was borrowed from a poster over on the Lemon64 forums) The white circle represents colour mixing that will happen with a 'old luma' VIC-II while the yellow circles are for both the new and old luma VIC-IIs. This article (https://kodiak64.com/blog/luma-driven-graphics-on-c64) on the matter is well worth the read.

The second isn't as well known but is seen any time black is used on screen. The NMOS process that the VIC-II is built on has a quirk that a gate will transition quickly from high to low and slowly from low to high. The effect this has on VIC-II gfx is that singluar black pixels on a coloured (or white) surface will appear slightly bigger than other coloured pixels. Conversely, singular coloured/white pixels will be noticeably smaller on a black background. Pixelers over the decades will have at least been subconsciously accounting for this effect in their work.

If you can pull off the colour blending then you'll potentially be bringing something to the NTSC users that PAL users have enjoyed since forever.

c0pperdragon commented 5 years ago

I am not completely sure how this color blending actually works on old PAL TVs, but I guess it somehow mixes the color from two lines to even out transmission errors. This effectively halves the vertical resolution of the color signal, but as humans tend to see variations in luminance better than variations in colors, this was some viable compromise. But this whole scheme is completely restricted to the PAL system (meaning the color transmission mechanism that was used there). And exploiting this to create additional colors can obviously be done, but again makes sense only in the context of PAL. As this modification does not try to generate a PAL signal at all I did not bother emulating this color merge effect. For the most times having a clear and pixel-perfect color output is better than emulating this strange color quirk.

Nevertheless, as all the computation is done in an FPGA and can be reprogrammed without too much difficulty (you need an USB-Blaster for that, but that can be obtained quite cheaply), I could think about implementing this. I am already working on a software-interface to fine-tune the color palette anyway, implementing such an optional color-blend feature would not be too difficult, I guess.

About the other idea with shorter pixels depending on color: Again this could be some image-filtering option. But I can not change the size of the output pixels, because they are generated in a strict pixel clock. Instead I could modify the luminance to make such white pixels look weaker. Again this would be some option, the user needs to turn on specifically.

Obiwantje commented 5 years ago

@c0pperdragon - What a really nice in-depth technical answer and openness to look into perhaps catering to this great question. Kudos to both you and @Hojo-Norem on trying to make this cool solution EVEN better.

Hojo-Norem commented 5 years ago

I've been thinking about this over the last couple of days. Putting the black transition pixel size thing to the side I think that a decent simulation of PAL colour blending can be done if the FPGA has the resources to do it. If it has the space to store the last raw scanline from the VIC-II side then all you would do is compare the current pixel being drawn with the one directly above and output based on the comparison.

I guess that you have some kind of look-up table to determine what colour to output for each pixel, right? I'm also guessing that it's only 16 entries large, one for each of the VIC-II's native palette. I'm no FPGA designer, but if I were doing this in pure software and wanted to do it the lazy way, I would just have a 16x16 table (or 14x14 if you skip black and white) representing every possible combination of colours. If I'm interpreting your schematic properly, then the output colour resolution is 16bpp. Working with a 16x16 table, that would mean that the lookup table would be 512 bytes. If I'm looking at the correct information about the FPGA you are using then there may be embedded user FLASH memory that could be used for this. But again I don't really know FPGAs... I could be barking up the wrong tree.

EDIT: Quick idea. If the FLASH look-up table is possible, then perhaps some way of adjusting the table during runtime could be possible. Maybe snoop some of the VIC-II registers for a magic sequence then after that use those registers to enable the CPU to read/write the colour look-up table. Actually, there's a side benefit to this. As hardly any two Commodore setups are the same in terms of colour output (VIC model, TV, saturation setting, PAL, NTSC, etc), aware software could temporarily program in a colour table that best approximates the colours on the artist's setup.

c0pperdragon commented 5 years ago

The FPGA has enough RAM to store several lines of output data. I am using this for the line-doubling already. So for every pixel I can easily access the pixel in the previous line. Internally everything is computed in YPbPr values - there is just one mapping from the 16 C64 colors to these YPbPr coordinates. This color space is convenient to compute the scanline darkening effect.

More or less the same thing can be done to combine colors without touching luma in this case. The resolution of each color channel is 5 bit, giving a total of 1024 possible color values. A lookup table would not be convenient here, but computation is no big deal in an FPGA, especially if the operation clocks at a mere 16MHz. I guess by just averaging the Pb and Pr values we get the desired results already.

General issue on palette reprogramming: I will try to provide an API via writes into unused VIC registers. The downside of this is that it will be too powerful and could disqualify such machines from demo competitions. I imagine blanking the whole screen for 1 second or so after the palette was modified, so the feature can not be abused to magic more colors to the screen as were possible on the original machine.

c0pperdragon commented 5 years ago

After quite some tinkering with the firemware, I could actually free up some space in the logic fabric to start adding more functionality. As I found, I have some on-chip RAM to spare and finally figured out how to utilize the on-chip flash to store configuration data (not finished yet). My plans now go more or less exactly into the direction of your proposal: To support a 16x16 large matrix of palette entries. Each entry will hold a 15 bit value for the Y-Pb-Pr signal. that can be individually modified by some writes into the VICs register space. As you said, this can be used to set up any palette you like with or without color blending effect. Also setting up RGB colors is possible, as the Y Pb Pr outputs can be adjusted totally independently. RGsB is easy then, but RGBS would also be possible by disabling the sync signal on the G line altogether, and using the existing luma from the A/V connector instead.

Hojo-Norem commented 5 years ago

Wow, that sounds super! The more I've been thinking about it, the more I've been wanting to build one. The FPGA's ground pad might be a challenge for me though... That said, I have noticed one or two PCBs over on OSH Park get around this by putting a largish plated hole connected to GND directly underneath the IC's ground pad so it could be soldered from the bottom. Not ideal if there isn't the room to route traces around it. (I haven't looked at the PCB layout, so I'm not certain if that is an issue or not.) It it is possible then it would reduce the DIY barrier down too just needing a decent soldering iron and a steady hand.

On the subject of possible palette reprogramming 'abuse', I'm not entirely sure that its too big of an issue. As big scene gatherings I would assume that there would be a dedicated compo machine set up for showing productions. I can think of a couple of ways that things could be kept 'honest' so to speak, but as your project is open source, there's nothing stopping somebody building a version of the firmware with such a thing disabled, that is if there's room in the FPGA to implement it at all.

If you're wondering what they are, both methods would have the palette registers locked on reset until either one: A unlock sequence is written, causing the interface to override the screen for a few seconds with a pre programmed bitmap that'll give the game away or perhaps display a small watermark in one of the corners until the next reset...

Or two (possibly simpler to implement): Have a CRC generator on the FPGA that generates a CRC value from the screen registers and pixel data, perhaps only count a few dozen scanlines in the center of the screen to allow a bit of freedom on the screen. Take a regular C64 bitmap image showing whatever message and generate a CRC from it, use that as the register unlock key. Now, to unlock the registers the programmer would have to display the bitmap to allow the CRC generator in the FPGA to generate the unlock key. The upshot of this method is that the memory requirements are shifted over to the software and that the unlock image could be anything /you/ want...

Both are a little involved and probably not work the trouble to implement as like I said somebody with the right skills could easily cook up a fully unlocked firmware to use on their demo machine. Then again, I'm not too sure that it would be that effective to cheat by reprogramming the palette on the fly. Completely new colours would be spotted a mile away and called out and I think that reprogramming the palette on the fly in time critical situations would be difficult, seeing that each palette entry is 3 writes long and probably the register access is going to be register, palette addr and then data then that's another 3 writes.

c0pperdragon commented 5 years ago

My design actually has exactly such a hole under the IC, so I can hand-solder it. This works perfectly every time: After the pins are finished, turn up the iron a bit and feed solder into the hole. Even with a hotter iron it takes some time until the solder melts after the initial heat was sucked into the ground plane. Heat it up until you can stir the solder in the hole like soup in a pot.

For unlocking the setup mode, I imagine to write some magic number into a register and then toggle the mode switch at the back of the computer. As the switch is quite small and hard to reach, this should not go unnoticed.

Hojo-Norem commented 5 years ago

That's great on both points. I'm definitely going to have to build one now...

c0pperdragon commented 5 years ago

Following our discussion, I have created a new firmware version (2.0) that allows modification of the palette. You can have a look at the project main page to see how it is done. Maybe you will indeed build a board for yourself...

Hojo-Norem commented 5 years ago

I'm just about to start getting the parts together. One quick question though, I'm pretty sure that the files I need to send off to the PCB producer (I'll most likely use OSH Park) are the 'Gerber.zip' found in the rfreplacement folder in this project for the main board and for the VIC-II adapter the gerbers are in the zipfile found in "A-VideoBoard/c64mod/c64board/"?

c0pperdragon commented 5 years ago

Yes, you are right with both assumptions. Do not forget to order the VIC-II adapter with only 0.8 mm thickness.

bodgit commented 5 years ago

If it helps anyone else, I've shared the OSH Park projects for the two boards so it's easier for anyone else to order.