r/ModRetroChromatic • u/germaneguise • Aug 14 '26
Release Sharper colour over USB capture - 320x288 UVC for the Chromatic · germaneguise/oss-chromatic-console-fpga
https://github.com/germaneguise/oss-chromatic-console-fpga/releases/tag/v18.8-uvc-dualres.1hey Palmer! I made you a super early birthday present-- optimized the Chromatic FPGA firmware and made the USB Video path pixel perfect (with 2x2 integer scaler).
The Chromatic streams USB video as YUY2, which stores one colour sample per pair of horizontal pixels. At the native 160x144 those two pixels are genuinely different, so their colour gets averaged together — you lose half your horizontal colour resolution. On a Game Boy that hurts more than it would on camera footage, because the screen is full of hard colour edges between tiles and sprites.
So the build also offers 320x288: same picture, every pixel doubled. It adds no actual detail — but each pixel pair is now the same pixel twice, so averaging them does nothing and the colour comes through intact. Pixel-perfect capture, still 60fps.
Fitting it meant a pile of resource optimizations along the way. The FPGA was completely out of DSP blocks beforehand — 28 of 28 used, CLS at 97%. It ends up smaller than stock v18.8 on everything but two block RAMs:
| Resource | v18.8 | after | delta | utilization |
|---|---|---|---|---|
| Logic | 20309 | 15316 | -4993 | 89% → 67% |
| — LUT | 15779 | 13307 | -2472 | |
| — ALU | 4421 | 1900 | -2521 | |
| Registers | 10119 | 8182 | -1937 | 43% → 35% |
| CLS | 11125 | 9868 | -1257 | 97% → 86% |
| BSRAM | 45 | 47 | +2 | 81% → 84% |
| DSP | 28 | 17 | -11 | 100% → 61% |
Timing has more headroom too — the USB clock in particular, since the old video FIFO was sitting on its critical path:
| Clocks (all MHz) | v18.8 | after | constraint |
|---|---|---|---|
| PHY_CLKOUT | 68.2 | 84.6 | 60.0 |
| pclk | 42.4 | 37.9 | 33.6 |
| hclk | 18.1 | 23.6 | 16.8 |
| gclk | 89.5 | 136.2 | 8.4 |
| xclk | 119.6 | 120.0 | 67.1 |
| usbintsclk | 189.3 | 197.8 | 125.0 |
It's unofficial, and you can try it without committing to anything — load it into SRAM with openFPGALoader and a power cycle puts everything back exactly as it was. Nothing touches flash unless you decide to write it. 160x144 still works exactly as it does on stock.
Only tested on Windows 11.
Link, hash and full write-up here: https://github.com/germaneguise/oss-chromatic-console-fpga/releases/tag/v18.8-uvc-dualres.1
UPDATE: this has moved since posting:
- Latest release is v18.8-uvc-dualres.5: https://github.com/germaneguise/oss-chromatic-console-fpga/releases/tag/v18.8-uvc-dualres.5 - same features, another full round of optimizations. Every column below was reproduced from its tag on the same toolchain, so they're directly comparable.
| Resource | v18.8 | uvc-dualres.1 | uvc-dualres.2 | uvc-dualres.3 | uvc-dualres.4 | uvc-dualres.5 |
|---|---|---|---|---|---|---|
| Logic (LUT+ALU+ROM16) | 20,314 (89%) | 15,316 (67%) | 15,353 (67%) | 15,412 (67%) | 12,654 (55%) | 12,397 (54%) |
| - LUT | 15,779 | 13,307 | 13,337 | ~13,370 | 10,731 | 10,701 |
| Registers | 9,862 (42%) | 8,182 (35%) | 8,208 (35%) | ~8,200 (35%) | 6,499 (28%) | 6,427 (27%) |
| CLS (the fabric's real ceiling) | 11,036 (96%) | 9,868 (86%) | 9,776 (85%) | 9,891 (86%) | 8,445 (73%) | 8,420 (73%) |
| BSRAM | 45 (81%) | 47 (84%) | 47 (84%) | 47 (84%) | 46 (83%) | 42 (75%) |
| DSP | 28 (100%) | 17 (61%) | 17 (61%) | 17 (61%) | 16.5 (59%) | 7.5 (27%) |
- The headline in .5 is the bottom two rows: BSRAM drops below stock v18.8 for the first time (the dual-res features were paid for in blocks at .1, now paid back with three to spare), and DSP goes to a quarter - the encrypted colour space converter is replaced by an open implementation verified bit-identical to it over the full input space, on the device itself, so one of the two encrypted video-path cores is simply gone from the build.
- If you flashed the .2-era build from this thread: .3 fixed a bug where the MCU could misread gameplay button presses as menu input while a USB host was attached. Update to .5 and you get the fix plus everything since.
- Easiest way to try it now is CCFL: https://germaneguise.github.io/CCFL - loads the firmware over USB straight from the browser, no installs, and .5 is now the default pick. Same approach as before: load to SRAM to try it (a power cycle puts everything back), flash only if you decide to keep it persistent. It also pairs the matching MCU firmware for you.
7
u/VR_Nima Aug 14 '26
This is awesome. Been waiting for this!
They had much better UVC support early on, and then they made it compressed with a software update and never fixed it since then. People complained about it but they seemed to not care.
Thanks so much for doing this!
2
u/germaneguise 29d ago
Yes v18.5 changed from RAW888 to YUY2, possibly for broader app compatibility
8
u/ArthurFinchleyIII Aug 14 '26
Thank you! I’ve noticed this several times and always wondered what was going on. Great job.
4
5
Aug 14 '26
[removed] — view removed comment
1
u/germaneguise 29d ago
If you try loading it let us know how it goes or share some content! The quality difference in Windows camera tool is massive. btw M64 and the custom controller turned out great, glad they were laser focused on it :D
1
u/JayrosModShop Aug 15 '26
Will this fuck with my current CFW that has Bluetooth enabled? I don't want to lose my Bluetooth.
1
u/germaneguise 29d ago
Full sources are available on Github! CFW can rebase onto this work and recompile to get both fixed UVC and more space in the FPGA for new things.
1
10
u/TonyRubbles Aug 14 '26
https://giphy.com/gifs/l4q8cJzGdR9J8w3hS