Questions about the VGA video hardware



  • Wuerfel_21Wuerfel_21 Posts: 805
    edited 2020-07-19 - 00:28:17
    These tilted lines actually look more like "visible area (or scanline as a whole) too narrow / hsync freq too high" (if they tilted the other way, that'd mean it's too wide)

    Have you verified that the driver that is supplying the sync is running the same mode as you? (your monitor should tell you)
  • While I can never be 100% sure, I have checked it and it looks good. It is a 640x240 driver that signals as 640x480. My monitor does pick it up properly, but it doesn't think it's a 640 x 480. It's a simple mod of the standard bitmap driver. I have checked the settings (constant presets), but I could be wrong. The only two differences it has to mine is the pixel clock (30 mhz instead of 25) and distribution of porches. I'm using the tinyvga timings. I'll try finding another driver and see if it helps. Also, is 25 mhz pixel clock too slow for 640 x 480?
  • Wuerfel_21Wuerfel_21 Posts: 805
    edited 2020-07-19 - 01:10:38
    Well yeah, if the pixel clock is different all the timings change around! The nominal pixel clock for 640x480@60Hz is 25.175 MHz - if you use 30 MHz without changing the metrics, you get 640x480@71Hz (most monitors will have no problem with this). Try running with the normal sync pins (and without the other driver "scaffold") again and see what happens.
  • I realise this. However, the other driver I was using didn't add or subtract from the timings. It just shuffled the mix of sync time and porch time. I think I'll switch drivers instead. Also, I've been trying without the scaffold for every change I make. I think this seclnd driver is just dodgy.
  • I use the VGA_Text.spin one that comes with PropTool (which internally uses VGA.spin). Low memory usage, blank screen and IIRC standard timing by default.
  • Did not realise vga_text was just black by default. Huge thanks for the tip and all the generous help you have given me so far. I'll try it out tomorrow, it's pretty late over here.
  • Wuerfel_21Wuerfel_21 Posts: 805
    edited 2020-07-19 - 02:51:58
    Ahh wait I remember, actually, it's NOT black by default, but you can set it to emit sync only by gving it your VGA basepin +1 (instead of +7). i.e. for basepin 16 you'd start it with
  • Uhh, it looks like VGA_Text produces a 512x480 signal, if I look at the settings it has.
  • Wuerfel_21Wuerfel_21 Posts: 805
    edited 2020-07-19 - 11:29:23
    Is it? Ahh, never realized that. (Although the horizontal resolution it does really doesn't matter for this purpose, as long as the timing is vaguely right)
  • Peter JakackiPeter Jakacki Posts: 9,340
    edited 2020-07-19 - 12:46:04
    That link you provided back to the MicroVGA looks like it is based upon an ARM7 design I did back in 2005 where I bit-bashed VGA under interrupts. The original chip was an LPC2106 with 64k RAM but the one I entered into the design contest was based on the newer LPC2138 at the time. Once they realized that fast I/O matters, they produced the LPC2148 and I was able to have much less jitter in the video. I had to do preinterrupts to let things settle before the actual line interrupt itself. I still managed to do wave audio from files and run a foreground program plus serial coms etc. Then I discovered the Propeller and VGA was so much better and easier.

    So, where are you at with your driver. Can you post the latest version as I can check it.

    This is the very original though:
    Funny thing is that I have found that there were a lot of people claiming the design as their own or taking the credit for it, many years after I had designed and published the details. I used IAR workbench since the ARM assembler was totally unlimited and free back then.

    640 x 407 - 193K
  • Here is the latest code. The sections altered to accommodate debugging have been marked with a "normal" + commented-out version, and the debug lines have "debug" above them. VGA_Text_640 is just VGA_Text. I just copied it into my project directory to test what would happen if I altered the horizontal ticks to be 640. It just broke the text driver, so I reverted it.
  • Small update, I swapped the driver for a bitmap driver with confirmed good timings. The display no longer complains about a non-standard resolution.
  • Adding instructions between waitvids is unlikely to help you.

    Waitvids, once started, run continuously and in the background.

    This is done so you have time to set the next one up while the current one is streaming the signal.

    It is helpful to think of them like you do the signal, which is one unbroken chain of levels.

    To affect when things happen, set the number of pixels in a waitvid frame, the pixel clock, and the PLLA value.

    Should a waitvid end without another one being setup, the streamer keeps going with whatever data happens to be on the D and S busses at the time. Unless one is doing tricks, that data is never what you want.

    What you want to do is kick off a waitvid, then get the next one setup and the waitvid instruction for the next one executed so it can continue the signal without it being interrupted.

    The tilt you are seeing is signal timing off due to the chain of waitvids being broken, or the timing values being set incorrectly.

    In most drivers, timing values for non active signals are different from the active regions.

    One important value to get a handle on is total PLLA per line. That has to remain constant, unless the driver does interlaced video, and in that case, one line will be half as many PLLA.

    Figure out what the total PLLA per line is for a working driver, and make sure whatever you do adds up to that, and the waitvids all execute before the ones coming before them.

  • I know that I want to be ready for when the waitvid strikes. I was just adding and removing instructions to see what effect on the display it had. I knew it wouldn't fix anything, but I tried it to see if it'd give me any indication of what's going wrong
  • Okay, so swapping the pixel rate calculation for a more precise precalculated value (read: ripped from a driver that calculates it in-place), I've approximately flattened the lines.
  • Well, you made me do it - I got out my VGA monitor and debugged it here.

    Lots of changes, so I've just attached the fixed code and will give you diff here:
    --- main_broken.spin	2020-07-20 04:44:59.613969400 +0200
    +++ main_fixed.spin	2020-07-20 04:47:48.638637100 +0200
    @@ -18,6 +18,10 @@
       vertical_synch = 2
       vertical_back_porch = 33
    +  hsynch_gp = 1
    +  vsynch_gp = 0
    +  pingroup = 2
       ' These are the inactive states of the synch lines, meaning the state they're in during visible drawing on the screen
       ' They must be set to either 0 or 1 depending on the video mode
    @@ -30,7 +34,7 @@
       'normalstate = (hsynch_inactive << 1 + vsynch_inactive) * $0101
    -  normalstate = ((hsynch_inactive << 1 + vsynch_inactive) << 2) * $0101
    +  normalstate = (hsynch_inactive << hsynch_gp + vsynch_inactive <<vsynch_gp) * $0101
     scrbuf       long      $00000000[5100]
    @@ -39,7 +43,7 @@
       bmp: "VGA64_BMPEngine"
     PUB start
    -  bmp.BMPEngineStart(2, 1, horizontal_resolution, vertical_resolution, @scrbuf)
    +  'bmp.BMPEngineStart(0, 1, horizontal_resolution, vertical_resolution, @scrbuf)
       cognew(@asm_entry, 0) 'launch assembly program in COG 1  
     org 0
    @@ -70,6 +74,7 @@
                   call      #hsynch
                   djnz      line, #hline                                            'Are we still doing visible lines?
    +              'jmp #hline
                   mov       synch_lines, #vertical_front_porch                      'do vertical front porch lines
                   call      #vblank                                                 
    @@ -89,11 +94,11 @@
     vblank        mov       vscl, hres
                   waitvid   synch_active, #0
    -hsynch        mov       vscl, horizontal_front_porch    'Set FrameClocks to the front porch pixel value
    +hsynch        mov       vscl, #horizontal_front_porch   'Set FrameClocks to the front porch pixel value
                   waitvid   synch_active, #0                'Do the front porch pixels (no pixels, no hsynch)
    -              mov       vscl, horizontal_synch          'Set FrameClocks to the sync pulse pixel value
    +              mov       vscl, #horizontal_synch         'Set FrameClocks to the sync pulse pixel value
                   waitvid   synch_active, #1                'Do the horizontal synch pulse (no pixels, hsynch on)
    -              mov       vscl, horizontal_back_porch     'Set FrameClocks to the back porch pixel value
    +              mov       vscl, #horizontal_back_porch    'Set FrameClocks to the back porch pixel value
                   waitvid   synch_active, #0                'Do the horizontal back porch pixels (no pixels, no hsynch)
                   djnz      synch_lines, #vblank            'Do another line of synch?
    @@ -102,38 +107,38 @@
     hsynch_ret    ret                                       
    -vconfig       long      $300004ff
    -reg_dir       long      $ff0000
    +vconfig       long      $300000ff + pingroup<<9
    +reg_dir       long      $ff << (pingroup*8)
     vscl_pixel    long      1 << 12 + 16
    -pix_clk       long      $14242aee     
    +pix_clk       long      $14242aee
     hres          long      horizontal_resolution
    -vres          long      vertical_resolution / 2
    +vres          long      vertical_resolution 
     'pixel_data    long      $0055aaff
    -colour        long      $FF00FFFF
    -'colour_mask   long      $fcfcfcfc
    +colour        long      $FFAA5500
    +colour_mask    long      $fcfcfcfc
    -pixel_data    long      0                       
    +pixel_data    long      %%333322211110000       
     'colour        long      0 
    -colour_mask   long      $f0f0f0f0 
    +'colour_mask  long      $f0f0f0f0 
    -synch_normal  long      normalstate
    +synch_normal  long      normalstate*$01010101
     ' This is a special colour, wherein colour 0 is normal state, while colour 1 is hsynch active (but vsynch inactive)
     ' When in vsync, vsynch is active on both colours
    -'synch_active  long      normalstate ^ $200
    +synch_active   long      normalstate ^ ((|<hsynch_gp)<<8)
    -synch_active  long      normalstate ^ $800
    +'synch_active long      normalstate ^ $800
    -'vsynch_bflip  long      $101
    +vsynch_bflip   long      (|<vsynch_gp)*$101
    -vsynch_bflip  long      $404 
    +'vsynch_bflip long      $404 
     line          res       1
    @@ -141,4 +146,4 @@
     synch_lines   res       1
     h_groups      res       1
    -synch         res       1
    \ No newline at end of file
    +synch         res       1
  • Thank you so, so, so, so, so much. While your code didn't want to compile on my end, for some reason, doing a diff between the two helped me find the fix. It was really stupid mistake, forgetting the immediate on the synch vscl durations. I cannot express how thankful I am for your help, or how sorry I am for making you put up with my stupidity. Really, a thousand cheers to you.
  • Oh that is a subtle one! Sure glad you found it.
Sign In or Register to comment.