Shop OBEX P1 Docs P2 Docs Learn Events
Is there a vga 640x480 driver available for P2 please? — Parallax Forums

Is there a vga 640x480 driver available for P2 please?

Hi
I am looking for a vga 640 X 480, 16 colour library to use with flexbasic. There are a lot of display libraries- rogloh's is so comprehensive I suspect it has a kitchen sink function! All I need is a single purpose library for the one bitmapped display. I don't need mouse and graphic routines, just the essentials so I can write to a Hub display buffer in 4 bit colours.
I am sure it would be possible for rogloh's driver to be configuered to do this, but even if I was able to do it I would still have all the code to support all the other variations it supports to find room for.

Ray has a driver but has modified it to do 320 X 240 and I am trying to figure out how to un-modify it...

It would be nice if it also had a palette so the 16 colours can be selected from a much larger selection.
I would like to be able to understand the code- not just use it.

Fred777 recently posted a query on this subject and eventually got it working- but not without making a lot of alterations to Chip Graceys driver which does not work as is on the latest P2 https://forums.parallax.com/discussion/173307/help-with-vga-bitmap-output

I am struggling to get my head around the use of events, smart-pins, streamers etc and how to access them from flexbasic.
Using flexbasic I have managed to get smart-pin A/D, D/A, serial async and spi, pwm triangle and sawtooth, nco etc., working, but the video just defeats me.

Thanks
Dave

Comments

  • How much free HUB space do you have? For the DAT section my COG PASM driver code itself should use under 4kB and only needs a two scan line buffer and frame buffer on top of this. Also if you only spawn it once the scan line buffer could probably share the COG code space too. Are you concerned about bringing in more SPIN code than is required? I think Flexspin will remove the uncalled functions so the total code size won't be large, although I don't use Flexbasic and that could differ.

  • RaymanRayman Posts: 14,640
    edited 2021-06-15 15:36

    One way would be to use the SimpleVGA example I posted (or use Propeller Code Generator to create it) and then modify the assembly for 4bpp.

    I have an ancient 4bpp driver but who knows if it works today, it was probably done on FPGA version of P2...

  • RaymanRayman Posts: 14,640
    edited 2021-06-15 15:56

    I just took my VGA_Simple1a driver and made it 4bpp by changing just one line:
    m_rf:=$7F070000 + basepin<<17 + 640 'visible rfbyte 4bpp LUT->DAC

    Changing $7F08 to $7F07 makes it 4bpp.

    But, the images is off because the embedded image is 8bpp.
    So, you might want to find a 4bpp image. Also, you'd probably need to adjust offset to image...

    Update: Actually it's $7F07 not $7F06 in order to get pixels in correct order...

  • RaymanRayman Posts: 14,640

    Here's a working example, image is not the best, but I'm out of time...

  • Hi
    Gosh that was quick- thanks both.
    Rogloh- I only barely understand your answer :/
    I see lots of conditional if this then that else.. and so on and all the skipped 'thens' will surely stay in.
    Ray- thanks a lot- I will give it a good study- sounds like just what I want- not bothered about the bitmap.
    Dave

  • My point was if you only call a few of the available functions at startup to initialize the video driver such as initDisplay and initRegion etc, then all the other functions present in the API won't get called and should (hopefully) get removed from the executable code generated by flexspin. I just don't know if it removes them in flexbasic as well, but I'm guessing it would too. The final code shouldn't be especially large. The largest hub RAM consumer will still be the frame buffer (by far).

  • FWIW, in FlexBASIC, with optimization set to either “Default” or “Full”, any unused routines will be removed by the compiler.

  • Hi again

    @rayman I have a good solid colour bird displayed on my monitor. :)
    Thanks so much.
    I'm amazed at what can be done with 16 colours!
    All I changed was the VGA_BASE to 32.
    There is a black bar at the bottom of the screen- but maybe that's just the monitor not a 4:3 will see when I start to write to the screen.
    Now I need to decode all those mystical instructions like xcont, xzero (streamer), investigate the palette and writing to the pixel buffer etc.

    Dave

  • aaaaaaaarghaaaaaaaargh Posts: 82
    edited 2021-06-16 13:41

    Here is a simple flexbasic program using rogloh's driver (0.91b)
    has easy access to the Screen memory as its a flexbasic array:
    Program size is 328k bytes including the 300K video buffer but thats at 8bits per pixel

    OPTION EXPLICIT
    const HEAPSIZE=32768
    
    dim VID as class using "p2videodrv.spin2"
    
    
    const   VGA_BASE_PIN    = 40
    const   VGA_VSYNC_PIN   = 44
    const       LINEBUFSIZE     = 640*4
    const       SCREENSIZE      = 640*480
    
    dim as ulong region(12)
    dim as ulong display(14)
    dim as ulong vgapalette(256)
    dim as ulong linebuffer1(LINEBUFSIZE)
    dim shared as ubyte screenbuf(479,639)
    
    dim aaa as ulong
    dim c as ubyte
    dim x,y,mx,my as ulong
    
    vgapalette(0) =    $00_00_00_00   ' 0 = black          
    vgapalette(1) =    $00_00_AA_00   ' 1 = dark blue
    vgapalette(2) =    $00_AA_00_00   ' 2 = dark green
    vgapalette(3) =    $00_AA_AA_00   ' 3 = dark cyan
    vgapalette(4) =    $AA_00_00_00   ' 4 = dark red
    vgapalette(5) =    $AA_00_AA_00   ' 5 = dark magenta
    vgapalette(6) =    $AA_55_00_00   ' 6 = brown
    vgapalette(7) =    $AA_AA_AA_00   ' 7 = light grey
    vgapalette(8) =    $55_55_55_00   ' 8 = dark grey
    vgapalette(9) =    $55_55_FF_00   ' 9 = light blue
    vgapalette(10) =   $55_FF_55_00   '10 = light green
    vgapalette(11) =   $55_FF_FF_00   '11 = light cyan
    vgapalette(12) =   $FF_55_55_00   '12 = light red
    vgapalette(13) =   $FF_55_FF_00   '13 = light magenta
    vgapalette(14) =   $FF_FF_55_00   '14 = yellow
    vgapalette(15) =   $FF_FF_FF_00   '15 = white
    
    var timing = VID.getTiming(VID.RES_640x480) 
    
    vid.initDisplay(@display, VID.VGA, VGA_BASE_PIN, VGA_VSYNC_PIN, VID.RGBHV, @lineBuffer1, LINEBUFSIZE, timing)
    vid.initRegion(@region,  VID.LUT8,  0, VID.FLASH_TEXT, @vgapalette, 0, 16, @screenbuf, @display)
    vid.setTextContext(@display, @region, 0x1F) 
    
    
    
    
    While 1
        for x = 0 to 639
            for y = 0 to 479
                ScreenBuf(y,x) = int(rnd(1)*15) + 1 
            next
        next
    Wend
    
  • Hi

    @aaaaaaaargh
    Thanks for that example program- its all working beautifully, and indeed the program is 328k including the video buffer.
    Ray's program is only 155k including buffer- the difference is mainly the 4 bits per pixel of course. It seems the unused routines in rogloh's program are removed.
    So now I have two solutions. :)
    Because your program is in basic with a random pixel colour screen being drawn continuously, it was obvious how to draw to the pixel buffer and I was soon drawing graphical boxes etc.
    However how you figured this out...

    var timing = VID.getTiming(VID.RES_640x480) 
    
    vid.initDisplay(@display, VID.VGA, VGA_BASE_PIN, VGA_VSYNC_PIN, VID.RGBHV, @lineBuffer1, LINEBUFSIZE, timing)
    vid.initRegion(@region,  VID.LUT8,  0, VID.FLASH_TEXT, @vgapalette, 0, 16, @screenbuf, @display)
    vid.setTextContext(@display, @region, 0x1F) 
    

    I don't know.

    Dave

  • aaaaaaaarghaaaaaaaargh Posts: 82
    edited 2021-06-17 12:05

    @tritonium said:

    var timing = VID.getTiming(VID.RES_640x480) 
    
    vid.initDisplay(@display, VID.VGA, VGA_BASE_PIN, VGA_VSYNC_PIN, VID.RGBHV, @lineBuffer1, LINEBUFSIZE, timing)
    vid.initRegion(@region,  VID.LUT8,  0, VID.FLASH_TEXT, @vgapalette, 0, 16, @screenbuf, @display)
    vid.setTextContext(@display, @region, 0x1F) 
    

    I don't know.

    The cool thing about flexbasic is that you can use (flex) spin and c objects directly from basic, so by taking a look at "complexdemo.spin2" and "p2videodrv.spin2" one can see what subroutines and parameters are available
    The "demo" subroutine is where to look, then call those subroutines with similar parms from flexbasic

    • Set display timing parms
    • Initialize a Display Control Block
    • Initialize a Region Control Block
      (and perhaps create and link more Regions and to cursor and mouse stuff)

    You can have more that one region in your display, perhaps one with graphics and one with text mode - that can save memory.
    Also rogloh is working on supporting external video memory...
    btw. I should be possible to get 16 Colors and save 150K of memory by using VID.LUT4 instead of VID.LUT8. Of course the Screenbuffer acess will be different then, 2 pixels per byte I guess. Haven't tried this though.

  • @aaaaaaaargh said:
    Also rogloh is working on supporting external video memory...

    Actually external memory has been working for a quite a while (it's actually working in that last text wrapper driver for HyperRAM I think), but just not advertised/documented/fully released showing you how to use it. I need to get it documented and fully out with the recent PSRAM+SRAM support too along with a simple graphics demo but I get sidetracked with other things most of the time.

    These memory+video driver combinations are powerful, but just not yet in the perfect state for easily learning how to use them. For me that last bit takes the most time to perfect/explain. I also find the SPIN2 language is fine for coding simple things but can be hard to put together comprehensive layered OO type code without real inheritance, include files, preprocessor etc. Plus the most annoying part when creating library code is that dead code elimination is only part of flex spin not Chip's SPIN2, which can cause bloat or duplicated versions of very similar looking files unnecessarily IMO.

    Thanks for explaining things to the original poster too. :smile:

  • aaaaaaaarghaaaaaaaargh Posts: 82
    edited 2021-06-17 13:22

    @rogloh said:
    I need to get it documented and fully out with the recent PSRAM+SRAM support too along with a simple graphics demo but I get sidetracked with other things most of the time.

    I suffer from a documentation allergy, so I avoid making docs at any cost and understand that docs may be late or non-existent... so it would be better to get the sram example out there asap ;-)

  • tritoniumtritonium Posts: 543
    edited 2021-07-06 22:09

    Hi

    Well the 640 by 480 at 4 bits per pixel works a treat :)
    So I though it would be nicer at 800 by 600- still only 240k.
    but I had a problem- if in the pallette the 'red' most significant nibble was 'odd' in value it messed up the vertical sync!!! it almost looks as if it combines the vert and horiz syncs together...
    some code to demonstrate.

    OPTION EXPLICIT
    
    const HEAPSIZE=20_000   '128768
    
    dim VID as class using "p2videodrv.spin2"
    
    
    const   VGA_BASE_PIN    = 32
    const   VGA_VSYNC_PIN   = 36
    const       LINEBUFSIZE  = 400 '(800 * 0.5) ie 2 pixels per byte
    const       SCREENSIZE   = 800*600  
    
    dim as ulong region(12)
    dim as ulong display(14)
    dim as ulong vgapalette(16) 
    dim as ulong linebuffer1(LINEBUFSIZE)
    dim shared as ubyte screenbuf(599,399)   ' Y,X  ????
    
    '######  In 800 x 600 mode the pallette is sensitive to certain bit patterns- seems to work if the MSNibble of a
    ' colour (r or g or b- ESPECIALLY RED CODE) is an even value ie 0x,2x,4x,6x,8x,etc but fails if odd 
    
    
    
    'it seems the rgb are not the same as ray's prog
    'in 800x600 mode   the red set to F*,D*,B*,9*does not work
    
    '                   b  g  r
    vgapalette(0) =    $00_00_00_00   ' 0 = black          
    vgapalette(1) =    $A0_00_00_00     ' 1 = dark blue
    vgapalette(2) =    $00_A0_00_00   ' 2 = dark green
    vgapalette(3) =    $80_80_00_00   ' 3 = dark cyan
    vgapalette(4) =    $00_00_A0_00     ' 4 = dark red
    vgapalette(5) =    $A0_00_A0_00     ' 5 = dark magenta
    vgapalette(6) =    $60_80_A0_00     ' 6 = brown
    vgapalette(7) =    $AA_AA_AA_00     ' 7 = light grey
    vgapalette(8) =    $80_80_80_00   ' 8 = dark grey
    vgapalette(9) =    $FF_00_00_00     ' 9 = light blue  (this FF works)
    vgapalette(10) =   $00_EE_00_00     '10 = light green
    vgapalette(11) =   $E0_E0_10_00     '11 = light cyan    *** THIS ONE FAILS. RED SET TO $10. MSNIBLE IS ODD!
    vgapalette(12) =   $00_00_E8_00   '12 = light red
    vgapalette(13) =   $E8_00_E8_00   '13 = light magenta
    vgapalette(14) =   $00_EF_EF_00   '14 = yellow
    vgapalette(15) =   $EF_EF_EF_00     '15 = white  (all FF's wont work)
    
    
    var timing = VID.getTiming(VID.RES_800x600) 
    vid.initDisplay(@display, VID.VGA, VGA_BASE_PIN, VGA_VSYNC_PIN, VID.RGBHV, @lineBuffer1, LINEBUFSIZE, timing)
    vid.initRegion(@region,  VID.LUT4,  0, VID.FLASH_TEXT, @vgapalette, 0, 16, @screenbuf, @display)'lut8 to lut4
    vid.setTextContext(@display, @region, 0x1F) 
    
    '+++++++++++++++++++++++++++++++  my stuff  +++++++++++++++++++++++++++
    dim c as ubyte
    
    block(0,0,799,599,0)    'clear screen to black
    
    do
        for c=1 to 15
            block(100,100,600,400,c)
            pausems 500
        next
    loop
    do
    loop
    
    sub block(xs,ys,xf,yf,bcol)
    dim as ushort x,y
    for y=ys to yf
        for x=xs/2 to xf/2
            screenbuf(y,x)=bcol<<4 or bcol
        next
    next
    end
    
    

    Notice that palette 11 (light cyan) is $E0_E0_10_00
    the 10 is the red and it is affecting the vertical sync. Any odd value here does the same

    I would appreciate it if you could cast your eye over this and perhaps suggest a cure?
    Thanks

    Dave

  • Ok, yes that seems weird. I'll take a look at this later tonight when I get a chance on my P2. It might be related to the colour converter restrictions in the P2 but in general it's typically the LSByte bits that can affect sync not the MSB to my knowledge. There was a older driver bug with the parallel output I recently fixed when it wrapped around the pins and sync could get affected. It could be that too. Will check later.

  • Also @tritonium are you saying this issue happens in 800x600 but the exact same colour palette at 640x480 works okay? If so, that's really weird as the same palette output format is shared and it should be independent of resolution.

  • roglohrogloh Posts: 5,786
    edited 2021-07-07 13:43

    Okay @tritonium , I think I was able to reproduce this in my driver using my own 4bpp test code with flexspin not flex basic. I believe it relates to the use of port B with VGA which is a bug I fixed recently. If I run 800x600 using port A with an earlier driver it does not happen but it will with 800x600 on port B, yet 640x480 on port B is okay. Once I used my newer driver the problem went away. Why it is somehow also resolution dependent and 640x480 still works on port B I really don't know but will investigate more to be confident my fix was sufficient.

    Your fix will be (in the short term) to either use port A for VGA or use these six updated constants below to replace their corresponding lines in the p2videodrv.spin file (which could potentially break other non-VGA outputs, I didn't test that).

    m_bs        long    $7f310000 + H_FP                        'front porch before sync
    m_sn        long    $7f310000 + H_SYNC                      'sync
    m_bv        long    $7f310000 + H_BP                        'back porch before visible
    m_vi        long    $7f310000 + H_VISIBLE + H_FP            'visible
    m_rf        long    $7f360000 + H_VISIBLE                   'visible 8x4b for LUT lookup
    m_brdr      long    $7f310000
    

    My latest (still unreleased) version has the port B fix fully included. The problem there was that for VGA, the streamer commands had the "e" bit set when it should be cleared for VGA and this enabled parallel RGB data output on some higher port B pins which can clobber the sync if those pins were situated there. That odd colour bit you needed to set in the palette for this to occur must have aligned with a sync pin.

    By the way, a couple of points related to your test code. You want to define your 32 bit VGA palette entries in R:G:B:0 byte order for the colours to be correctly displayed with my driver (not B:G:R:0), and also you need to have a two scan line buffer. Your test BASIC program code only defined one scan line buffer (400 bytes) so some HUB RAM could get clobbered because the driver does ping pong writing into two scan line buffers.

  • Hi

    @rogloh said:
    Also @tritonium are you saying this issue happens in 800x600 but the exact same colour palette at 640x480 works okay? If so, that's really weird as the same palette output format is shared and it should be independent of resolution.

    That palette works fine on the 640 by 480 :o

    Dave

  • @tritonium said:
    Hi
    That palette works fine on the 640 by 480 :o

    Dave

    Yeah I saw the same thing, and it is rather weird. I think it must relate to how long the sync pulse is corrupted for relative to the scan line period or something.

  • Hi

    Thanks so much- this works fine. :)
    I wrote my previous post several hours before actually posting it so our messages crossed...
    Where would this message board (and Parallax) be without people like you prepared to not only share their knowledge by contributing to the software resources but also quickly respond to members questions.

    Dave

Sign In or Register to comment.