CHiPs44
Posts: 8
Joined: Thu Apr 08, 2021 1:25 pm

Re: Understanding Pico VGA Code and CMakelists?

Tue Apr 27, 2021 11:37 am

Hello,

My progress so far is available at https://github.com/CHiPs44/hagl_pico_vgaboard.

I tried to keep separate files for MIT licensed parts and BSD 3 clause parts, as I don't know they mix very well, even if they are very permissive licenses.

I didn't even try to compile the project for now, as my knowledge of CmakeFiles & al. is rather low...

As a professional developer, I'm more on the Web side, using PHP, JS, HTML, CSS & SQL databases, so that kind of things still looks like black magic to me.

Feel free to fork and make PRs!

CHiPs.

CHiPs44
Posts: 8
Joined: Thu Apr 08, 2021 1:25 pm

Re: Understanding Pico VGA Code and CMakelists?

Thu Apr 29, 2021 8:55 pm

Hello,

I managed to display something!

That's only black & white, other colors don't show.

The frame has blinking parts (timing issues).

More polished example soon!

Image

CHiPs.

CHiPs44
Posts: 8
Joined: Thu Apr 08, 2021 1:25 pm

Re: Understanding Pico VGA Code and CMakelists?

Wed May 12, 2021 3:56 pm

Hello,

I made some progress, displaying 16 colors and al.

I'm trying to make my example program and the HAGL HAL itself cleaner, but I encounter a linking issue with HAGL...

Please see https://github.com/CHiPs44/hagl_pico_vg ... -839873054 and help me if you can!

CHiPs44
Posts: 8
Joined: Thu Apr 08, 2021 1:25 pm

Re: Understanding Pico VGA Code and CMakelists?

Wed May 12, 2021 3:59 pm

Other question, did someone managed to make VGA output work at 1024x768, 512x384 or 256x192?

With witch timings?

There's an 1024x768@63Hz definition in pico-playground, but it's intended for the 48Mhz FPGA.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Thu May 13, 2021 2:18 pm

const scanvideo_timing_t vga_timing_1024x768_60_default =
{
.clock_freq = 65000000,

.h_active = 1024,
.v_active = 768,

.h_front_porch = 24,
.h_pulse = 136,
.h_total = 1344,
.h_sync_polarity = 0,

.v_front_porch = 3,
.v_pulse = 6,
.v_total = 806,
.v_sync_polarity = 1,

.enable_clock = 0,
.clock_polarity = 0,

.enable_den = 0
};


is a standard VESA XGA mode (although I never know which way the polarity is supposed to be - works on the 3 monitors I have plugged in all the time), but requires 130Mz system clock (i.e. set_clock_khz(130000, true); )

CHiPs44
Posts: 8
Joined: Thu Apr 08, 2021 1:25 pm

Re: Understanding Pico VGA Code and CMakelists?

Fri May 14, 2021 8:55 am

Thanks!

I managed to display full 512x384 and 256x192 screens.

I used an 260MHz system clock and corrected

Code: Select all

v_sync_polarity
to

Code: Select all

0
as stated at http://tinyvga.com/vga-timing/1024x768@60Hz.

With 1024x768, something in my code does truncate to seemingly 640x480, with unfinished lines and garbage displayed at the bottom...

Image

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Fri May 14, 2021 11:01 am

possibly `PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS is too small - the default is only 180

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 3:06 pm

How do I send blank scanlines correctly?

Code: Select all

uint16_t *pix = (uint16_t *) buffer->data;
*pix = COMPOSABLE_EOL_ALIGN;
pix += 2;
pix = (uint16_t *) buffer->data;
pix[0] = COMPOSABLE_RAW_RUN;
pix[1] = pix[2];
pix[2] = 2;
buffer->data_used = 0;
This seems to work right up until I add colour back into my driver and I get some glitches

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 5:02 pm

DarkElvenAngel wrote:
Sat May 15, 2021 3:06 pm
How do I send blank scanlines correctly?


This seems to work right up until I add colour back into my driver and I get some glitches
The code makes no sense at all:

Code: Select all

uint16_t *pix = (uint16_t *) buffer->data;
*pix = COMPOSABLE_EOL_ALIGN;
pix += 2;
so now pix[] = { COMPOSABLE_EOL_ALIGN };

Code: Select all

pix = (uint16_t *) buffer->data;
pix[0] = COMPOSABLE_RAW_RUN;
pix[1] = pix[2];
pix[2] = 2;
you overwrite pix[0] again, and set pix[2] to whatever pix[2] was before?

so now pix[] = { COMPOSABLE_RAW_RUN, ??, 2 }

Code: Select all

buffer->data_used = 0;
Well that's not correct; you've used 1 1/2 words (which you can't, you have to use an even number) and there is no black pixel at the end of the line - check the README in scanvideo again. There is a (very old) function here which draws a single color scanline https://github.com/raspberrypi/pico-pla ... pans.c#L77

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 5:29 pm

Sorry I thought a snippet would be enough this is the full render loop

Code: Select all

const scanvideo_mode_t vga_mode_640x240_60 =
{
    .default_timing = &vga_timing_640x480_60_default,
    .pio_program = &video_24mhz_composable,
    .width = 640,
    .height = 240,
    .xscale = 1,
    .yscale = 2,
};

void __time_critical_func(render_loop) (void)
{
    while (true)
    {
        struct scanvideo_scanline_buffer *buffer = scanvideo_begin_scanline_generation (true);
        uint16_t *pix = (uint16_t *) buffer->data;
        int iScan = scanvideo_scanline_number (buffer->scanline_id);
        int iRow = iScan / GLYPH_HEIGHT;
        iScan -= GLYPH_HEIGHT * iRow;
        iRow -= 3 ;
        pix += 1;
        if (iRow  < 0 || iRow > MAX_LINE)  // blank scan lines
        {
            ++pix;
            *pix = 0;
            ++pix;
            *pix = COMPOSABLE_EOL_ALIGN;
            pix = (uint16_t *) buffer->data;
            pix[0] = COMPOSABLE_RAW_RUN;
            pix[1] = pix[2];
            pix[2] = 2; //COMPOSABLE_EOL_SKIP_ALIGN; ??
            buffer->data_used = 0;
        } else {
        for ( int iCol = 0; iCol < MAX_COL; ++iCol ) 
        {
            uint8_t character = 0;
            if (iRow < MAX_LINE) character = char_buffer[iRow][iCol];
            uint16_t fg = character > 0xff ? 0x7FFF : 0x2BF;  //PICO_SCANVIDEO_PIXEL_FROM_RGB8(  0xFF, 0xAE, 0x00 );0x2BF
            uint16_t bg = 0;        //PICO_SCANVIDEO_PIXEL_FROM_RGB8( 0x00, 0x00, 0x00 );

            uint8_t bits = fontdata[8 * character + iScan];//[GLYPH_HEIGHT * (character + iScan)];
            if (Cursor.Line == iRow && Cursor.Column == iCol && iScan == 7 && led_state) bits = 0xff;
            ++pix;
            if ( bits & 0x80 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x40 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x20 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x10 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x08 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x04 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x02 ) *pix = fg;
            else *pix = bg;
            ++pix;
            if ( bits & 0x01 ) *pix = fg;
            else *pix = bg;
        }
        ++pix;
        *pix = 0;
        ++pix;
        *pix = COMPOSABLE_EOL_ALIGN;
        pix = (uint16_t *) buffer->data;
        pix[0] = COMPOSABLE_RAW_RUN;
        pix[1] = pix[2];
        pix[2] = MAX_COL * GLYPH_WIDTH - 2;
        buffer->data_used = ( MAX_COL * GLYPH_WIDTH + 4 ); // divide by 2 to remove scanlines
        }
        scanvideo_end_scanline_generation (buffer);
    }
}
That function you show to draw a scanline I should have these values?

Code: Select all

    pix[0] = COMPOSABLE_COLOR_RUN | 0;
    pix[1] = (MIN_COLOR_RUN) | (COMPOSABLE_RAW_1P << 16);
    pix[2] = 0 | (COMPOSABLE_EOL_ALIGN << 16);
And replace

Code: Select all

 if (iRow  < 0 || iRow > MAX_LINE)  // blank scan lines
        {
            ++pix;
            *pix = 0;
            ++pix;
            *pix = COMPOSABLE_EOL_ALIGN;
            pix = (uint16_t *) buffer->data;
            pix[0] = COMPOSABLE_RAW_RUN;
            pix[1] = pix[2];
            pix[2] = 2; //COMPOSABLE_EOL_SKIP_ALIGN; ??
            buffer->data_used = 0;
        } 

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 6:17 pm

no the sample used uint32_t *buf i.e. 32 bit values... there were 3 32 bit values, so data->used should be 3. you are using pix which is a 16 bi t pointer.

Ignoring all the pix++ spaghetti, the simplest way to do a single color scanline is just to do

Code: Select all

scanline_buffer->data[0] = COMPOSABLE_COLOR_RUN | (color16 << 16);
sacnline_buffer->data[1] = (width - 3) | (COMPOSABLE_RAW_1P << 16);
scanline_buffer->data[2] = 0 | (COMPOSABLE_EOL_ALIGN << 16);
scanline_buffer->data_used = 3;
or if it s black anyway:

Code: Select all

scanline_buffer->data[0] = COMPOSABLE_RAW1P;
scanline_buffer->data[[1] = COMPOSABLE_EOL_SKIP_ALIGN;
scanline_buffer->data_used = 2;

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 6:39 pm

Okay that hasn't sorted out the issue
P_20210515_143156_1_1.jpg
P_20210515_143156_1_1.jpg (18.98 KiB) Viewed 867 times
The text buffer is empty and these blocks appear outside under the last line of the buffer in the black scan line code.
Any thoughts? If I take the colour code out these go away

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 7:50 pm

i mean you could post your code again... ideally somewhere on github so it is easier to read...

I recommend using https://github.com/raspberrypi/pico-host-sdl/ which will let you debug your video code on the host if using Mac/Linux (or possibly WSL)

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 9:12 pm

I've uploaded the code to gitlab https://gitlab.com/DarkElvenAngel/pt

I'm using a VGA Demo Board The code has bugs in colour mode.

Thanks for having a look

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 9:47 pm


DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sat May 15, 2021 10:14 pm

Indeed that was it a simple mistake!

Thank you very much for your time.

CHiPs44
Posts: 8
Joined: Thu Apr 08, 2021 1:25 pm

Re: Understanding Pico VGA Code and CMakelists?

Mon May 17, 2021 9:44 am

Hello,

PICO_SCANVIDEO_MAX_SCANLINE_BUFFER_WORDS was already at 322, and putting 644 or 514 doesn't change anything.

In fact, I didn't realize that 1024x768/2 is 393216 which is more than the RAM available in the Pico...

I tested with a 1024x192 mode that did not work, so I abandoned this idea : the only interesting resolution would be 256x192 which would use 24576 bytes in 16 colors. 512x384 works but it's 98304 bytes, allowing no double or triple framebuffer to avoid flickering.

Thanks for help!

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Mon May 17, 2021 11:50 am

Yeah, for higher resolutions you absolutely need to draw the scanlines ahead off the beam, which is how scanvideo works (though you can certainly use it for framebuffers too)... that way you don't need double buffers at all (though you do need to be able to draw very fast!)

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sun May 23, 2021 3:37 pm

Just a quick question is it possible while VGA is running in core 1 to stop that core and reset the VGA to a different mode.
I need to change the x and y scaling of the current running mode if possible. This would allow switching from Text to Graphic mode.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Sun May 23, 2021 3:49 pm

It isn't supported in the API at the moment, but can potentially be achieved in a hacky fashion; which parameters do you want to change?

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sun May 23, 2021 3:56 pm

Just the scaling xscale and yscale, The default_timing, pio_program, width , height All would remain the same for simplicity.

The I think I need to switch my render_loop function too

EDIT : Sorry I had a glitch there and my post posted too quickly.

Memotech Bill
Posts: 104
Joined: Sun Nov 18, 2018 9:23 am

Re: Understanding Pico VGA Code and CMakelists?

Sun May 23, 2021 4:46 pm

At some point I tried switching video modes in my Memotech Emulator, and found it didn't work.

The work around I used was to have a fixed video mode of 640x240 (xscale=1, yscale=2), and just switch render loops.

For the graphics mode I do pixel doubling within the render_loop. For these modes my palette lookup returns a 32-bit value with the same colour in low and high words, so filling the scanline buffer with doubled pixels is just as quick as single pixels.

DarkElvenAngel
Posts: 1699
Joined: Tue Mar 20, 2018 9:53 pm

Re: Understanding Pico VGA Code and CMakelists?

Sun May 23, 2021 5:39 pm

Memotech Bill wrote:
Sun May 23, 2021 4:46 pm
At some point I tried switching video modes in my Memotech Emulator, and found it didn't work.

The work around I used was to have a fixed video mode of 640x240 (xscale=1, yscale=2), and just switch render loops.

For the graphics mode I do pixel doubling within the render_loop. For these modes my palette lookup returns a 32-bit value with the same colour in low and high words, so filling the scanline buffer with doubled pixels is just as quick as single pixels.
Well I have managed to break in and get access to yscale but changing the xscale has no effect. So half way there. This did involve a tiny change to scanvideo.c

Edit : this method only works if you are scaling down for example 4 to 1 not the other way around.

kilograham
Raspberry Pi Engineer & Forum Moderator
Raspberry Pi Engineer & Forum Moderator
Posts: 640
Joined: Fri Apr 12, 2019 11:00 am
Location: austin tx

Re: Understanding Pico VGA Code and CMakelists?

Mon May 24, 2021 12:59 am

my beeb emulator does something hacky to allow you to switch hscale to correct aspect ratio on widescreen monitors:

https://github.com/kilograham/b-em/blob ... ay.c#L2713

Return to “SDK”