GideonZ / 1541ultimate

Official GIT archive of 1541 ultimate II sources
GNU General Public License v3.0
173 stars 45 forks source link

U64 Elite Feature Request: scaled up hdmi internally #297

Closed ferkulat closed 1 year ago

ferkulat commented 1 year ago

Hi I have this idea, that I would like to spend some more time in front of the UE64 and do non gaming related stuff with it.

The screens, I have, do a pretty poor job at scaling up the HDMI output to fit the screen. The output is not sharp. (scan lines disabled) And my eyes try to fix that all the time.

Would it be possible to output native screen resolutions and scale the C64 output internally? Maybe as a configuration option with factors 1, 2 and 3? And everything that is not C64 output, because of factor and aspect ratio, will be filled (black?).

One could argue: "That's what is was like back then." But since it can run on 48MHz, I have the idea to do more serious stuff with it.

GideonZ commented 1 year ago

Unfortunately this is not possible, due to the limited I/O speeds of the FPGA. These are limited to 640 Mbps. Currently, the U64 uses 270 Mbps, so there is some room for higher resolutions. However, you would need to understand that the U64 does not have a frame buffer, so any resolution that it could make should be in sync with the VIC and limited to a pixel rate of 64 MHz. This limits the possibilities greatly. It may be able to do 800 x 600, but not sure if that's going to help you. Oh yes, and of course, 800 x 600 @ 50 Hz... not sure if that's very standard either.

1080p => 148.5 MHz pixel rate > 64 MHz: cannot do 1080i => 74.25 MHz pixel rate > 64 MHz, cannot do 720p => 74.25 MHz pixel rate > 64 MHz, cannot do ... 800 x 600 @ 60 Hz => 40 MHz pixel rate > can do, but may not solve your screen scaling problem.

It MAY be technically possible to do 1080i @ 50 MHz, with reduced blanking, yielding approximately 64 MHz pixel rate... But it will surely be highly non-standard and questionable if your screen will support it. Most European screens would, tho.

So, then the scaling. You are asking for integer factors... Let's take PAL:

The VIC produces 288p..... So the scaling factor to get 1080 would be 3.75 in the vertical direction. This is not 3, and also not 4... When you choose 4, you can only draw 270 lines, which means that you'll need to cut off some vertical border, which is very okay, giving an overscan impression. When taking the VIC timing as a reference, which is 312 lines, the total number of lines to scan in order to keep in sync is (312 / 270) 1080 = 1248, or for 1080i: 1248 / 2 = 624. This is quite a bit more than the standard 1125 (/2 =562.5) lines normally found in 1080p(i). The line rate is then 50.12 Hz 624 = 31275 Hz, which is very close to 2 times the 15625 Hz of PAL (although the VIC has a line rate of 15639 Hz). At a maximum pixel clock of 64 MHz, the maximum number of pixel clocks per line is hence: 64M / 31275 = 2046. A normal line length in 50 Hz 1080p/1080i is 2640 (a LOTT of blanking). 2046 is marginally larger than 1920, so there is not much time for hsync. Just enough to encode 48 kHz audio... it MIGHT work. So much for the vertical timing. For the horizontal timing let's consider the number of visible pixels that the VIC produces, which is 400, although VICE runs at 384. 1920 / 384 = 5; so an integer multiplication of 5 should do the trick, after cutting off 8 pixels on both sides. This gives a horrible aspect ratio of course. Another option is to use a multiplication of 4 there as well, giving a maximum of 1600 pixels, so filling up the remaining 320 pixels with black would do the trick. (Heh, would the menu show in the remaining 320 pixels? hmmm..)

So with a custom screen timing for 1080i @ 50 Hz, it might be feasible: Pixel rate: 64 MHz (target) Line rate: 31277.7 Hz (target, to be as close as possible to VIC to limit buffering to almost nothing) Clocks per line: 2046 => 2040 rounded: 8 front porch, 40 sync, 72 back porch, 1920 active, of with 1600 used Lines: 270 VIC lines, to 540 lines per field, 1080 lines per frame. Total lines: 1248, meaning: 168 lines of blanking, e.g. 3 lines front porch, 5 lines sync, and 160 lines front porch. The timing can be improved when some lines of video data buffer are added. Then some lines in the blanking can be exchanged for more blanking horizontally, probably giving better compatibility.

For NTSC it looks more dim, because the VIC produces only 240 visible lines (at 60 Hz). This requires an upscale of 4.5 which is nasty. Chosing 4 would mean 960 active lines, with 120 lines of black. But as you can see, this requires a buffer of at least half of these lines. Choosing a factor 5, the screen could show only 1080 / 5 = 216 lines, which yield almost no border at all at the top and bottom. Maybe this is acceptable, but this means that also some lines need to be buffered as well. So let's assume a bit of buffering can be added, then to keep in sync with the VIC, one field should take up the same amount of time still. For a standard timing of 1125 lines (/2 for interlaced), the maximum number of clocks per line in 60 Hz mode is 64 MHz / (60 Hz * 1125 lines) = 1896 clocks per line. Aaaah.. unfortunatly that breaks, because the number of pixels to show is already 1920... Even for the minimum sync possible (which is given by the encoding of audio) of 72 or 80 clocks, you need 2000 clocks per line minimum. This limites the line rate to 64 MHz / 2000 clocks = 32 kHz exactly. So at 60 Hz you only have 533 lines max, which is not sufficient for the 540 that is required to 'draw' 1080i.

So, in short, it might be feasible for PAL (-> 1080i), but it is impossible for NTSC.

ferkulat commented 1 year ago

Thank you very much for this elaborate answer. I had no idea how complicated this is.