Questions about the VGA video hardware

Okay, so I've been poring over the P1 manual, datasheet and counter addendum, in addition to reading and annotating 2 assembly language VGA drivers, and this is what I've found out.

1. The video generator (in VGA mode) is basically just a CTRA-driven thing that takes exactly what you give in a waitvid and writes it to outa (with the number of clocks needed to change
data set by vscl). This means that the generator can write potentially anything at any rate supported by the PLLA (it has to operate in a PLL mode).

2. Selecting the correct pixel clock and timing the sync lines falls to me, the programmer.

3. The counters are set by selecting the correct mode, FRQx and (optionally) PHSx. To operate as a normal oscillator (like a 555 or something), it must be set to either the PLL or the NCO
modes. To get the formula for the NCO mode, dig through the application note on the counters (for reference, the equation is: frequency in hertz = system frequency in hertz * FRQx /
2^32)

Now, I know all that is old news to most of you (like, the absolute basics.), but as a newcomer to the Propeller, I had to spend time finding this info, and I just want it here for posterity for the next poor sod googling this.

After reading some documentation on VGA (timing tables) and the assembly drivers (the bitmap one included with the prop tool, which uses the video hardware, and a barebones one doing everything manually), I'm left with a few questions.

1. Are there predefined "modes" for VGA, or can I just pump pixels at my chosen resolution?

2. How do I pick a good pixel clock?

3. How do I know how much back/front porch and hblank and vblank to have? Do I need to translate the timings to cycles of the CTRA clock?

4. Which timings are important to get tight, and which can be more loose?

5. How do I set VSCL properly when doing h/vblank and porches? Looking through Chip's code, he does some fancy things with the VSCL register, and I'm very confused.

My goal is to be able to kind of make a driver for each of my projects' needs and resources. I know the premade ones are way better, but I still want to have the option in case I need to squeeze things. I'd appreciate any help on these topics, I've kind of hit a dead end on my understanding, and any pointers would be very welcome.
«1

Comments

  • whickerwhicker Posts: 635
    edited 2020-07-08 - 04:13:07
    yes there are defined VGA modes. 640x480, 800x600, 1024x768, etc.
    with some rather tightly defined timing.
    you know when you get it wrong, as the monitor cannot sync and parts of the picture are cutoff.

    This seems to be somebody else playing around with VGA timing:
    http://martin.hinner.info/vga/timing.html

    http://tinyvga.com/vga-timing
  • evanhevanh Posts: 9,702
    edited 2020-07-08 - 05:04:27
    The old CRT's didn't care about the digital resolution of the picture. All they needed was syncs that fit between the upper and lower limits. It's a different story with LCD monitors and LCD TVs because they need to know the incoming resolution of the picture to perform the scan conversion correctly.

    Modern LCD's use the H and V sync rates to determine what the resolution is. You can adjust the dot clock outside of typical quite a ways. Vertical sync can sometimes be moved a long way off but some modes are more touchy than others.

    Best to use porch (blanking) lengths that suit the target frequencies rather than the other way round.

    Rule of thumb is place the sync pulses in the first half of the blanking times. Some are very early while others are more central. It doesn't seem to be that important in practice. Nor does the length of the sync pulse have much importance.

  • In my experience any multisync monitor, CRT or LCD, will take any reasonable timing just fine. Some LCDs have trouble with non-standard pixel clocks, but that only results in some blurriness and uneven sampling. And generally, if the mode is nonstandard, one needs to use the monitor controls to adjust it a bit to look good.
  • evanhevanh Posts: 9,702
    edited 2020-07-08 - 07:50:58
    Wuerfel_21 wrote: »
    In my experience any multisync monitor, CRT or LCD, will take any reasonable timing just fine. Some LCDs have trouble with non-standard pixel clocks, but that only results in some blurriness and uneven sampling. And generally, if the mode is nonstandard, one needs to use the monitor controls to adjust it a bit to look good.

    The scan converter issue is not a rescaling issue but an incoming pixel sampling issue at the monitor/TV (display).

    The display will have info to say what its guess is. If it's an LCD and it hasn't guessed the resolution correctly then the pixel sampling will be out and you'll get uneven pixel sizes in the display's scan buffer - Which produces regular corrugations in the displayed image on the LCD.

    It can't be made to look good while the resolution is guessed wrongly.

    PS: DVI/HDMI/Displayport probably have an advantage over VGA on this point. I haven't done enough testing to know for sure, but I did notice a difference with the limited prop2 testing I've already done with the HDMI accessory board.
  • Thank you for your insight, especially about the mode situation. Most of the documentation that I could find (and understand) was for old analog CRTs, so the bit about modern LCDs really helps.

    I'm still a bit confused though. When looking through Chip's 512x384 bitmap driver, I notice he does a fair bit of VSCL trickery around the blanking periods. Is this necessary? Or can I just tack on extra blank lines and run them with the same VSCL settings?
  • Thank you for your insight, especially about the mode situation. Most of the documentation that I could find (and understand) was for old analog CRTs, so the bit about modern LCDs really helps.

    I'm still a bit confused though. When looking through Chip's 512x384 bitmap driver, I notice he does a fair bit of VSCL trickery around the blanking periods. Is this necessary? Or can I just tack on extra blank lines and run them with the same VSCL settings?

    Theoretically yes, but in practice you will want to do some housekeeping during blanking to prepare the next line/frame, which would be difficult to do while feeding enough pixels to the video generator
  • Wuerfel_21 wrote: »
    Thank you for your insight, especially about the mode situation. Most of the documentation that I could find (and understand) was for old analog CRTs, so the bit about modern LCDs really helps.

    I'm still a bit confused though. When looking through Chip's 512x384 bitmap driver, I notice he does a fair bit of VSCL trickery around the blanking periods. Is this necessary? Or can I just tack on extra blank lines and run them with the same VSCL settings?

    Theoretically yes, but in practice you will want to do some housekeeping during blanking to prepare the next line/frame, which would be difficult to do while feeding enough pixels to the video generator

    So it's used kind of a "you just do this while I go do some chores" command? Sorry if my questions seem kind of dumb, but it's hard to understand the context around assembly code and why things are done a certain way.
  • Wuerfel_21 wrote: »
    Thank you for your insight, especially about the mode situation. Most of the documentation that I could find (and understand) was for old analog CRTs, so the bit about modern LCDs really helps.

    I'm still a bit confused though. When looking through Chip's 512x384 bitmap driver, I notice he does a fair bit of VSCL trickery around the blanking periods. Is this necessary? Or can I just tack on extra blank lines and run them with the same VSCL settings?

    Theoretically yes, but in practice you will want to do some housekeeping during blanking to prepare the next line/frame, which would be difficult to do while feeding enough pixels to the video generator

    So it's used kind of a "you just do this while I go do some chores" command? Sorry if my questions seem kind of dumb, but it's hard to understand the context around assembly code and why things are done a certain way.

    yes
  • Sorry, but I have a new question. In the VSCL register, what happens if the FrameClocks value is less than the PixelClocks value would indicate (i.e. that FrameClocks is less than 16x (for 4 colour mode) or 32x (for 2 colour mode) PixelClocks? Does it just immediately go to get new info from a waitvid?
  • Sorry, but I have a new question. In the VSCL register, what happens if the FrameClocks value is less than the PixelClocks value would indicate (i.e. that FrameClocks is less than 16x (for 4 colour mode) or 32x (for 2 colour mode) PixelClocks? Does it just immediately go to get new info from a waitvid?

    Yes, that's how it works
  • Okay, so I think I understand, although my "driver" is still not behaving as it should. My monitor's not getting a lock on the signal. Could someone please have a look at this code? I'm just trying to display a repeating set of pixels, just to get it to display anything. I'm going by the numbers at http://tinyvga.com/vga-timing/640x480@60Hz
  • Handy trick for debugging VGA drivers: modify the driver to be debugged to move the sync signals onto two of the color signals. Then, start up a known-good VGA driver at the same resolution, showing a black screen. Now you will be able to see the sync signals on your monitor.

    Alternatively, if you have an oscilloscope, use that to look at the sync signals.
  • canadajonescanadajones Posts: 25
    edited 2020-07-16 - 14:15:16
    I do have an oscilloscope (20 MHz sampling rate), it shows that both the synch signals stay at 6-7 KHz, while the colour lines hover at around 13 KHz. Now this might be somewhat logical, as I'm merely repeating the same pixel pattern (on the colour pins), but the synch thing came out of left field. I'll try that debugging trick, thank you!
  • canadajonescanadajones Posts: 25
    edited 2020-07-16 - 22:57:51
    Okay, so this is the result I'm getting. I had to do a few modifications to pull it off. I disabled the visible line waitvid to avoid interference with the good driver synch signals. I also added a vsynch check, to make sure it only wrote to the line during visible line time. I then moved the sync signal up 2 pins, going to the blue group (assuming a P16-P23 Vsynch-Hsynch-B-G-R arrangement). However, for some reason, it's displaying green. I'm not quite sure how to interpret the signal coming in, but the blue should be vsynch, the green hsynch.IMG_20200717_003007.jpg?width=877&height=658
    IMG_20200717_003040.jpg?width=877&height=658
  • you can't just comment out/remove waitvids! That'll mess up the timing!
  • Oh wait, I'm just dumb and didn't notice the
                  mov       vscl, hres
                  waitvid   synch_active, #0
    
  • Oh wait no, there is a problem, you're never doing waitvid for the visible portion
  • canadajonescanadajones Posts: 25
    edited 2020-07-17 - 11:21:13
    I know, I was having trouble getting it to register, so I disabled the visible lines in the hopes of fixing it, in case that waitvid was interfering with the real synch signals. (the real problem was elsewhere, I was just dumb) I re-enabled the waitvid, this is the result. A green line flashes on-screen once in a while. I'm guessing that is from desynch between the two drivers. Apart from re-enabling the IMG_20200717_131716.jpg?width=877&height=658
  • Hsync should be one stationary vertical bar and Vsync should be one stationary horizontal bar.If they scroll around a little bit that's fine, too.

    I don't that should be an immediate:
    xor       synch_active, #vsynch_bflip
    

  • Also:
    vscl_pixel    long      1 << 12 + 32
    
    should be
    vscl_pixel    long      1 << 12 + 16
    

    And the value you put in FRQA
    (pixel_clock / 5) << 3
    
    evaluates to 48, which is waaay too low - Counter NCO frequency in HZ is actually ((FRQA/2³²)*CLKFREQ). For more info, read the counter appnote
  • Yea, I must've changed that vscl_pixel too when fumbling around with the settings. It was 16 before I changed it over to display the synch signals Sorry about that :neutral:. About the frqa, if you look at the associated instruction, it's a movi, not a mov.
  • Ahhh. Well, does it work now? I can't see anything else wrong. I don't have a VGA monitor set up right now, so I can't tell.
  • Uhh, let me check. I haven't actually done anything to the driver apart from shift the synch signals, so if it didn't work before, I don't see why it'd work now
  • canadajonescanadajones Posts: 25
    edited 2020-07-17 - 21:28:39
    Nope, it's still not working. I'll do some oscilloscope probing, but I'm at a complete loss as to why this won't work. I'm attaching the code, in case of any passing angels who'd be so kind as to have a quick look at it. (The driver it asks for is just a bitmap driver, I just used it when testing with sync signals on the colour lines to provide good sync signals.)
  • Okay, so I didn't notice your immediacy comment earlier. It's now been rectified, and now it all shows up as blue, as expected. Thank you for that. So, it appears that while there is only one horizontal bar (blinking in and out), there are many vertical bars. I can see a repeating series of thin blue line-black space-thick blue line-black space. By the numbers I've inputted into the constant definitions, that sequence corresponds to horizontal front porch, then synch, then back porch. The last black space would have to be the visible screen, To double check this, I change the bit pattern my driver attempts to display to that of pure white. This confirmed my suspicions, as the screen then started rapidly scrolling with a lot of yellow colour and the blue lines now turned white. This is expected, as I'm hogging the blue for sync, only red and green can come through, which makes yellow. The scrolling I assume is due to desynch between the two drivers' vblank. IMG_20200718_232353.jpg Sadly, due to poor construction of my VGA adapter, there is quite a lot of colour bleed. Even with this though, I can tell that that the visible screen is reduced to just a small space. I'll experiment further and double check my visible horizontal line code.
  •  mov       vscl, vscl_pixel
    
    has to be moved below hline, otherwise it'll use the sync VSCL for the visible portion
  • ah, there's the issue. I was looking at it, but I misjudged the jump
    It's slightly misaligned, but that's just the drivers talking, I think

  • Okay, so after trying it, it appears there is an issue with what I think is vertical synch firing off too frequently. IMG_20200719_010223.jpg
    The yellow is the visible lines. It appears like it's only doing one line of visible lines before immediately not doing something for a while. Is this normal? It's still connected with the 2 drivers.
  • canadajonescanadajones Posts: 25
    edited 2020-07-18 - 23:42:55
    Adding nops (or any instruction really) between the vsynch calling portion and the end of the visible lines causes the line gaps to tilt significantly
    IMG_20200719_014001.jpg
    In other news, it's not caused by vsynch. I added a plain jmp instead of the djnz after the hsynch, and the effect persists (though, the nop effect doesn't, for obvious reasons).
  • Okay, so I managed to get it to stop scrolling, by very careful manipulation of the hsynch section. It's still broken, but it can get a vertical hold on the signal. The blue bar is scrolling across the screen, and is what I assume to be the vsynch.
    IMG_20200719_014812.jpg?width=877&height=658
Sign In or Register to comment.