Shop OBEX P1 Docs P2 Docs Learn Events
VGA 640x480, 800x600, 1024x768, 1280x960 full color ANSI text driver — Parallax Forums

VGA 640x480, 800x600, 1024x768, 1280x960 full color ANSI text driver

ersmithersmith Posts: 6,053
edited 2020-08-15 16:40 in Propeller 2
(2020-08-15): Version 1.0: Ported to PNut, added 16x32 font support, added 1280x960 mode

(2019-10-02: Version 0.6: 8bpp color support, new silicon support, and converted C driver for Catalina and riscvp2)

(3/01/2019: Version 0.5: Re-arranged to make using multiple monitors possible. Added simple C and BASIC demos.)

(2/19/2019: Version 0.4. Fixed a nasty bug in the vsync polarity. Please update!)

(2/19/2019: Updated again with a newer driver that supports 1024x768 and has better sync at 640x480)

(2/18/2019: Updated with a screenshot and newer driver.)

This is still a work in progress, but it seems to sync OK on my monitor. It uses a 1bpp bitmap with 256 characters. The font provided is 8x16, so we get 80x30 characters at 640x480 and 100x40 characters at 800x600 (we only use 15 rows of the font in the latter case). Each character can have arbitrary background and foreground colors, so each character takes up 8 bytes of memory; thus the 800x600 case uses 100*40*8 = 32000 bytes of memory for the screen. The way it works generates 8 pixels at a time, so practically speaking the font has to be 8 pixels wide, but can be any height.

Internally it loads one row of the font into COG RAM during horizontal blanking, and uses getbyte to look up the pixel data for each character from that font row, while placing the fg and bg colors into the LUT for display. Doing this for higher resolutions is probably going to be difficult, although I'm sure there are ways to shave some cycles off the inner loop.

The demo only works properly in the most recent fastspin (3.9.20) because it uses setpiv to blend pixel colors, and earlier fastspins had a bug in that instruction. The actual driver should be OK with older fastspin and should easily port to PNut (there's just the usual Start/Stop Spin methods, most of the driver code is in PASM).


screen.jpg;
3264 x 2448 - 3M

Comments

  • Cool :) This looks nice...800x600 demo worked out of the box. I only had to reduce the pixel clock in the 640x480 demo - without it my cheapo little 4" monitor wouldn't accept the signal. Scoping it showed 76Hz vsync and I think 38 or 39kHz hsync. 30MHz pixclk was about the max that worked, but looked pretty jittery...25.175MHz looks solid, and yields a normal 59.94 vsync
  • I've updated the .zip file in the first image with a newer version of the code. There's not much different in the driver itself, but the vga640x480 demo now includes a terminal driver that understands ANSI escape sequences (I forgot to update the 800x600 demo, but you can easily see how to copy the routines over from the 640x480 one -- the text processing functions are all in separate .spinh files).
  • RaymanRayman Posts: 14,646
    the 640x480 works for me, but is very jittery...
    XDIV needs to be a low value (like 1 or 2) for the current silicon.

    800x600 doesn't work for me.
  • RaymanRayman Posts: 14,646
    I've modified the 640x480 example to work with my monitor.
    Also, changed basepin...
  • RaymanRayman Posts: 14,646
    edited 2019-02-18 19:34
    I just tried adding a bitmap driver to this so can switch between text and bitmap.

    Adding the bitmap file into the DAT section seems to crash Fastspin…

    Doesn't seem to like a giant file being dropped in... Works if change to a small file...
    DAT
    '
    '
    ' Bitmap  'bitmap buffer starts at $1000
    '
    orgh    '$1000 - $436    'justify pixels at $1000, pallete at $1000-$400
    bitmap  
            file    "bitmap2.bmp"'combined1.bmp" 
            'bitmap2.bmp   '640 x 480, 8pbb-lut
    
    buffer  'tile buffer
        long 0[COLS*ROWS*2]
    '
    ' font buffer
    '
        long
    fontdata
        file "unscii-16.bin"
    '   file "unscii-8-fantasy.bin"
    
    '=================================================================================================================
    ' BELOW HERE IS THE DEMO CODE
    '=================================================================================================================
    democolors
        long $FF000000, $FFFF0000, $00FF0000, $00FFFF00
        long $0000FF00, $FF00FF00, $FFFFFF00, $00000000
        long $7F000000, $007F7F00, $007F0000
    
  • jmgjmg Posts: 15,173
    Rayman wrote: »
    the 640x480 works for me, but is very jittery...
    XDIV needs to be a low value (like 1 or 2) for the current silicon.

    800x600 doesn't work for me.

    Can you post images of the jitter vs PFD MHz for your P2/Monitor combination ?
    Does it suddenly get worse, or just gradually ?
    ie is /3 usable (6.66'MHz), or is 10MHz PFD needed ?

    Trying to get a feel for the 'minimum MHz' that P2 PFD can run at, for various VGA pairings.

    How tolerant is your monitor to Line Scan and Pixel clocks ?

    eg 26MHz, which is a cheap GPS TCXO value, can yield
    PFD = 26M/3 = 8.666'MHz
    Err = 1-29*(26M/3)/(25.175M*10) = 0.165%


  • Thanks for everyone's suggestions. My monitor seems to be pretty tolerant, but I'll try to keep the XDIV value low. I've updated the first post with some revised code. The frequency calculations in the 800x600 code is now properly parameterized, and I've tweaked the 640x480 code again to something that I hope will work for more monitors. For some reason @Rayman 's settings do not work on my monitor, even though it looks like they exactly follow the spec :(. Which is weird because as I mentioned my monitor is usually pretty tolerant, but maybe that's the problem -- it's picking the signal up as 720x400 instead of 640x480.

    I've optimized the pixel loop and can now display 1024x768. To do that I'm overclocking the P2 Eval board to 200 MHz, but my board at least doesn't feel too warm when I do this -- but your mileage may vary, so you may or may not want to actually try it yourself. (It sounds like many people have gone above 200 MHz so it's probably not too crazy.)

    I think that's the limit for full color foreground and background, changing on every character (hah! someone will prove me wrong :)) but for monochrome or with colors changing less often getting to 1600x1200 or 1920x1060 should be pretty easy
  • jmgjmg Posts: 15,173
    ersmith wrote: »
    ... To do that I'm overclocking the P2 Eval board to 200 MHz, but my board at least doesn't feel too warm when I do this -- but your mileage may vary, so you may or may not want to actually try it yourself. (It sounds like many people have gone above 200 MHz so it's probably not too crazy.)
    ..
    Measurements are being reported at 350MHz, so 200MHz looks more mainstream.
    IIRC Chip was hoping to target 250MHz as a more formal spec (HDMI min) , in the P2+ at OnSemi now - maybe with lower Max Tj, and tighter supply specs.
    Of course, that depends on just how the P&R goes at OnSemi, and there is more logic in 2+... time will tell.

  • RaymanRayman Posts: 14,646
    Just FYI, most current LCD monitors appear to want ~60 Hz vertical..

    Although I think some gaming ones do 120 Hz...
  • Aha! I think I found why my monitor won't sync properly at 640x480 -- it's looking for negative polarity on hsync, whereas if I'm reading the code correctly we're providing positive. I've changed the driver to make the polarity a parameter. I *think* this should work OK, but I'm a software guy, not hardware, so it's entirely possible that I've messed something up with the signals. Please don't plug this in to an analog monitor until it's been thoroughly vetted, and in general be careful with it.

    The new version of the 640x480 demo runs at 60Hz (like the 800x600 and 1024x768 ones) and syncs fine on my monitor.
  • A lot of older LCD monitors are 59.97 (or there abouts) Hz, rather than exactly 60Hz.
    Gaming monitors come in 120Hz and 144Hz flavors.

    Also, I doubt you would damage an analog monitor with bad signal data (like pos vs neg hsync, or off timings), unless it was a really crappy monitor in the first place.
  • The newer modes all worked for me without changes. The HSync polarity does indeed change (monitor accepts it without any fuss), but altering the VSync polarity doesn't seem to have an effect - it always looks positive on the scope.
  • ersmithersmith Posts: 6,053
    edited 2019-02-20 00:20
    @avsa242: Oh boy, there was a nasty typo on line 87 of vga_tile_driver.spin2; it should read
      drvc #vsync
    
    (I forget the "#", so it's driving some random pin :(). I'm posting an update now.

    Thanks for checking this on the scope! I wouldn't have noticed that the polarity was wrong, my monitor was only looking at horizontal polarity.
  • evanhevanh Posts: 15,916
    I'll repost this in here since it is using Eric's tile driver:

    Given HDMI needs 10x the data rate of the pixel rate, 640x480's 250MHz data rate would normally be considered the only viable resolution for the Prop2. In an attempt to go higher I've been playing with display timing of the vgatile driver. My LCD TV seems extremely forgiving of timings for any particular known resolution ... but it doesn't accept an unknown resolution. I suspect modern 16:9 monitors/TVs will generally have similar "reduced blanking" capabilities. After all, they have no need of retrace times.

    What I've been able to do is start from the spec'd 34MHz pixel rate of 848x480@60Hz mode and chop down the timings until I've even got 848x480 at 25MHz working.

    Question is, does this work for anyone else at all?
    https://forums.parallax.com/discussion/download/125779/vga848x480.spin2
  • Works for me - 26.26kHz, 54.25Hz
    One thing I'm not sure others are seeing though...I've seen it with all of these - is that the left and/or right is chopped off...haven't tried it with this mode yet, but have been able to adjust the timings set in the driver to get it to fit onscreen. This is a cheapo little 4-something inch LCD though. I suspect it's mostly to blame, as I remember running into the same with a lot of the P1-based drivers, as well...got to get my hands on a better VGA monitor, heh.
  • jmgjmg Posts: 15,173
    Many larger monitors auto-fit, and in doing that, they expect an image border to work to.
    That means the image offered needs to have a definite edge - black backgrounds do not work as well, & any errant pixels outside display window can confuse it.
    Not sure how that squeezed flyback will interact with the auto-fit ?
  • ersmith wrote: »
    @avsa242: Oh boy, there was a nasty typo on line 87 of vga_tile_driver.spin2; it should read
      drvc #vsync
    
    (I forget the "#", so it's driving some random pin :(). I'm posting an update now.

    Thanks for checking this on the scope! I wouldn't have noticed that the polarity was wrong, my monitor was only looking at horizontal polarity.

    Yup! Neg and Pos both now reflect correctly here

  • evanhevanh Posts: 15,916
    edited 2019-02-22 15:11
    Oh, I forgot about the 26kHz horizontal. That's really low for PC monitors. And I suspect is what is wrong when I try to plug an older LCD monitor in. I've had to up the requirements somewhat to 28 MHz to get this Dell monitor to take.

    This one should be more universal but will run hotter when targetting HDMI.
    EDIT: Updated comments in source
    EDIT2: Revised for 60 Hz vsync because it fit
  • evanhevanh Posts: 15,916
    avsa242 wrote: »
    ... is that the left and/or right is chopped off...haven't tried it with this mode yet, but have been able to adjust the timings set in the driver to get it to fit onscreen. This is a cheapo little 4-something inch LCD though...
    Yep, seen plenty of that on my TV too. VGA inputs on TV's seem to be somewhat different to monitors.
  • evanhevanh Posts: 15,916
    edited 2019-02-22 14:38
    Just done the same treatment to 800x600 and got the TV down to 30 MHz, and 28 MHz on the monitor. So 800x600 looks viable over HDMI. Albeit probably at 300MHz! :D

    Will be interesting to see how closely HDMI timings track these VGA timings and also if monitors and TVs differ from each other on HDMI.

    EDIT: +1 to vsync
    EDIT2: Added lots of experiments as options to the timings
  • evanh wrote: »
    Will be interesting to see how closely HDMI timings track these VGA timings and also if monitors and TVs differ from each other on HDMI.

    Yes it will be. I know my 24 inch Dell LCD (over DVI) took all sorts of weird timing and resolutions I threw at it using an HDMI signal from my custom FPGA implementation. I suspect HDTV's may be somewhat less forgiving but it would probably vary and is worth playing around with.
  • RaymanRayman Posts: 14,646
    I think most monitors will be forgiving as long as refresh is 60 Hz +/- 10% or so.
  • evanhevanh Posts: 15,916
    edited 2019-02-21 01:58
    49 Hz seems to be the bottom limit for vsync. And 29 kHz for hsync. Although the TV clearly went lower on the horizontal.

    Keeping above those two figures, the biggest problem mostly was that the TV or monitor would detect wrong resolution and make an ugly picture.

    PS: I'm hoping HDMI devices have higher chance of making use of the integral clock and be much better with resolution detection.
  • I've updated the driver so that the VGA pin is now a parameter to the start() method rather than a constant. This should allow for multiple monitors to be easily connected; you'll need one Spin object (and COG) per monitor. The terminal driver code is now more cleanly separated from the tile driver and demo code.

    I've also added some very simple examples of how to use this from C (fastspin only for now, sorry) and BASIC.
  • Wow, I see I haven't updated this for a while, so here's a new version. For those coming to this for the first time: this is a VGA driver for P2 supporting text displayed at 640x480, 800x600, or 1024x768. Most ANSI escape codes are correctly interpreted (enough at least for the pye micropython editor to work correctly) including things like blinking and underlined text.

    There are a bunch of improvements over the last version:

    (1) The new silicon is supported. The hardware is checked at run time so both old and new silicon are supported by the same binary (only the streamer parameters have to change).

    (2) Memory used is more configurable: you can have either 8 bytes per character (allowing for full 24bpp on each of the foreground and background colors for each character) or 4 bytes per character (allowing 8bpp ANSI palette for foreground and background colors). Other than the color we also have 2 bytes per character for the character itself and for special effects.

    (3) A C version of the driver is provided. This is converted automatically from the Spin driver via spin2cpp. I've tested it with riscvp2 and Catalina. p2gcc doesn't have the propeller2.h support that's needed, but perhaps eventually the new PropGCC will. FlexC (aka fastspin) doesn't work with this converted C driver yet, but it can use the Spin code directly so that's not a big problem.

    The documentation is still a little sparse, but I hope the demos (demo.spin2, basdemo.bas, and ccode/cdemo.c) will show basic usage at least. For C only the 800x600 driver is provided, but you can change ccode/Makefile to use one of the other sizes if you'd like. For BASIC or Spin (or FlexC), pick a driver and instantiate it like:
    obj
       vga: "vgatext_640x480.spin2"
    ...
    vga.start(BASEPIN)
    vga.str(string("Hello, world!"))
    
    The parameter to the start function is the base pin of the VGA hardware. For the P2-Eval board this is usually a multiple of 8; I've defaulted to 48, but use whatever pin group your hardware is plugged in to. After initialization, you can write characters to the object using the usual methods .tx, .str, .dec, and so on. ANSI escape sequences may be used to change colors or provide special effects for the text.

    Source code is on my github at:

    https://github.com/totalspectrum/p2_vga_text
  • The pixels should be pretty solid with the new hardware. With the original P2 silicon it'd be wise to make the system clock speed some multiple of the VGA pixel clock, otherwise there will be jitter. For 800x600 I found 160MHz and 200Mhz (multiples of 40MHz) worked well.
  • evanhevanh Posts: 15,916
    On top of Eric's advise I'll add that in the revA silicon, of the first 16 divide values of XDIV, only /5 and /7 produce a lot of jitter. Above /16 though, things do get rougher.

    I should try HDMI out again myself ...
  • Wow, I didn't realize it had been so long since I updated this thread. I've posted the most recent version of my VGA text driver in the first post. Features:

    - Support for a variety of resolutions from 640x480 to 1280x960
    - Support for a variety of color depths, from monochrome with no effects (1 byte per character) to full color with underline, strikethrough, blinking, and similar effects (8 bytes per character)
    - Included 8x8, 8x16, and 16x32 fonts (the latter is the Parallax P1 font)
    - Interprets most ANSI escape sequences for cursor positioning, text modification, color changes, and effects changes, so standard terminal control codes may be used
    - Runs with fastspin and PNut
  • This is a very nice text driver that “just works” out of the box. The BASIC demo is minimalist but shows clearly all the basics. This is my new goto for VGA output. Thanks for the redux!
  • Thanks for finally bringing the VGA driver up-to-date (2020-08-15): Version 1.0: Ported to PNut. I just now tried it out and it works great for what I need. A simple, easy to use, and modify - with selectible screen resolutions, type fonts, tile sizes, full 24-bit colors.

    Some of my applications need the 640 x480 resolution screen but with 15 x40 tile sizes, the original 16x32 P1 font is a plus. I also like that is works with FastSpin and PNut, and supports the "View Character Chart" pick & place P1 full character set. ( Is it possible to add a DAT file of custom/user P1 graphics/text characters? - I will see if I can modify the VGA driver to do this )

    First look and test of Version 1.0 VGA driver looks very promising for what I need. I will be integrating it into my P2 WorkBench program in the next day or so. Stay tuned for some application programs...
Sign In or Register to comment.