Yeah I thought the same. Good way to get audio too without all that extra work.
If I go past that shop again soon I might pickup a second one to cut apart with the Dremel to see what chip is used inside. The case appears to be sealed.
@rogloh Is there a more recent release of your video driver than the V 0.8b version at the top of this thread? I’m about to start playing with video again and I want to make sure I am using your current driver.
@rogloh Is there a more recent release of your video driver than the V 0.8b version at the top of this thread? I’m about to start playing with video again and I want to make sure I am using your current driver.
There was one minor bug fix which I applied to the version of Roger's driver in FlexGUI (samples/Multi-Language/video). So that's very slightly more recent than v0.8b.
Yeah @JRoark there was a bug in the original code, discovered and fixed later after release. The later versions of Eric's tools will now catch it as a warning so it's easy to spot and he's also now fixed in his in samples. It was just missing a # in a $1ff constant during setup and meant video was slightly affected depending on Port B input state (was nasty to track down that one at the time IIRC).
I do plan a newer release soon with the HyperRAM thing. It will support a few extra things and use my new HyperRAM interface for external frame buffers in RAM/Flash, as well as dropping down to two colour text if the P2 pixel clock frequency multiple is too low for 16 colour text yet the P2 can still do full colour graphics, instead of preventing it from outputting anything whenever a colour text region is enabled as it does today. It also improves PAL timing and colour which I'd worked on too.
@rogloh I gotta tell ya: this is some neat code. I’m learning a lot just “looking over your shoulder” as it were. My needs are mostly big text (for small screen HMI), but I’m starting to think about sticking real graphics under the hood after playing with your driver and Eric’s Mandelbrot demo. This is cool!
Thanks JRoark. Yeah once people get to experiment with the full extent of all its features I sort of imagined they'd probably start to like it. Sprites and external frame buffers should only add further to its utility. After the HyperRAM thing I'll probably see if I can add a sprite layer on top with separate COG(s).
HyperRAM is all working with my updated video driver by the way, I'm just tidying up and getting the flash sorted. I did jut find a HyperFlash write burst boundary wrap bug in there I now need to fix and then that should finally be the end of it, at last.
A graphics drawing layer that writes into HyperRAM from other COG(s) would to be very useful too. I can hopefully put together something very simple to demo that little, but a lot of powerful drawing code could be added on top of this for decent GUI/2d gfx by anyone else. The external frame buffer certainly opens up lots more possibilities for a P2 display in high resolution, e.g. 1080p 8bpp which is probably the (overclocked) HyperRAM limit.
I've also designed the HyperRAM driver with graphics in mind from the start, so it can blit images between HUB and HyperRAM, or HyperRAM to HyperRAM or HyperFlash to HyperRAM. It can also accelerate graphics fills and generate horizontal/vertical lines, which is useful for some GUI elements like box outlines scroll bars, window edges, etc, plus it can now do read-modify-write of arbitrary bits in bytes/word/longs for less than 8bpp pixel drawing. In the future I hope it may get some arbitrary angle line drawing acceleration too if I can free a little more space or extend those portions to hub exec.
Was able to finally get the DVI/VGA driver working under PNut v34s today to make it compatible with both toolchains. There were a handful of things I needed to sort out to port it from Fastspin to official SPIN2...
-replace cognew with coginit
-add return result variables to called functions that return values
-add () around functions
-eliminate namespace scope problems with locals and PASM labels (Fastspin is more lenient there)
-there was some printing bug in the driver I found that showed up more in PNut SPIN2 but not using Fastspin. I know I'd had problems there before but never fully tracked it down, and using PNut seemed to make it appear immediately. Sorted now.
Demos also needed some similar work to get them running.
The P2 PLL setup with CLKSET is different too with how SPIN2 does it vs Fastspin and I still need to work on that a bit more to make the driver work nicer.
I plan to release an updated version that works with PNut SPIN2 soon.
I've ported the video driver to PNut with the auto PLL setting and it appears to be functioning in some cases but I am seeing differences in behaviour at higher resolutions that stress the P2. For some weird reason the 1024x768 and 1280x1024 images will sync ok using Fastspin, but won't when loaded from PNut. The 1280x1024 displays vertical lines instead of text/pixels in 1280x1024 with PNut and the 1024x768 resolution with mono text won't display anything at all, it's like the CPU might be running a tad slow as there is jitter on the HSYNC signal with PNut but not with FastSpin. Both measured 63.69kHz on my scope. Maybe some PLL jitter differences..?
This is weird because my driver is a common PASM object and should be assembling then operating identically. I'm trying to hunt for binary differences but I'll probably need to extract my driver's PASM binary part within the OBJ generated by PNut and compare with Fastspin data to be 100% sure both tools generate the same code.
The only other thing could be bootup timing differences if my driver code has some particular dependence there that works only with Fastspin and not PNut, but I can't see what that would be.
Yeah looks like both toolchains compile my PASM driver differently and there are 5 opcodes that are different throughout my driver using both tools, now deciphering where and what they are.
The only other thing could be bootup timing differences if my driver code has some particular dependence there that works only with Fastspin and not PNut, but I can't see what that would be.
Also check for RAM initialization problems - these catch me out quite often. Often your code "expects" all RAM to be initialized (e.g. to zero). Usually, you can spot these by manually having your program initialize unused RAM before it starts - if this changes the program behaviour, you have an initialization problem!
Yeah thanks RossH good idea. I don't think I make assumptions there but I will have to check that.
For now I have found they are all jmp # instructions that are different. I need to see if these make sense. Might be relative/absolute defaults but that is weird too because there are other jumps in the code that are the same with both tools.
Aha, some of this code gets patched to new addresses! The relative vs absolute jumps would then be different when mono text is enabled. That will explain the differences only at high resolutions.
I remember noting PNut using relative encoding in a circumstance where Fastspin uses absolute encoding. I saw it when testing that long-standing Pnut pasm bug that miscalculated hubRAM symbols when not referenced from cogRAM.
At the time Pnut was also trying to use relative branching between hubRAM and lutRAM, I think. That's a bit of a no-no. I didn't bother bringing it up because PNut 's jumps/calls weren't trustworthy then anyway. I haven't looked at it again.
Yeah PNut was using relative jumps when this code is initially stored in LUT and is doing jumps into COGRAM but then later gets patched and moved so it runs from COGRAM. Fastspin was using absolute jumps here so this patching method worked out okay. I didn't catch this when it was first coded and tested because Fastspin behaved differently to PNut and I was only using Fastspin then.
I've now patched these locations to use absolute jumps. Video seems to work now again for both Fastspin and PNut in the prior failing situation.
Certainly looking forward to a new and better VGA driver for SPIN2. As I mentioned previously I like the original P1 Font option, But having non-printable characters available in a Character Chart/Map copy & paste pull-down menu would be great. I don't know how hard that would be ( willing to help create one if need be ). Hopefully different screen tile sizes will be an option also - 80x40, 50x24, 40x15
Yeah this driver can internally support 8 pixel or double wide (fat pixel) fonts at any height up to 256 scanlines IIRC. Text resolutions would then support 40/80, 50/100, 64/128, 80/160, 120/240 character columns in 640, 800, 1024, 1280, 1920 pixel wide screens (standard resolutions), using either double or single wide pixels. Other custom resolutions can be achieved too. If you are prepared to sacrifice half the 256 character font, you can achieve higher resolution 16 pixel wide fonts when you manage your own screen buffer formatting as character pairs. Line doubling can also occur so a 640x480 screen could yield 40x15 characters using a 8x16 font.
If other non 8 pixel character sizes are required with more characters or colour options, additional COG(s) could be used to render into a line buffer which my video driver outputs, it was designed to allow for that though there is not an example available for this yet. I do want to work on an add-on sprite driver for this video driver after it is released.
WOW!!!
Congratulations. The complexdemo is fantastic!!!
Now to see how to drive this in VGA 1920x1080 with various sections.
I see you have included 4 font sets as binaries. How did you make the binary?
I have an 8x8 font that I derived from hippy's font for the P1 that I thought I might try out. But time for some playing first.
Thanks Cluso. This thing has been around for quite a while as a beta and I've not touched it a lot lately until quite recently but it was originally just for Fastspin only (we didn't really have official SPIN2 back then) - I've been getting it ready for a new release that supports external HyperRAM frame buffer requests (the best part) plus allowing mono text output for lower P2:pixel clock ratios as well getting it running under PNut with better PLL control. It should be out soon (I know I keep saying that), just needs a doc update and some better demos to show a larger extent of what is possible. It does support 1920x1080 with VGA and you can also tweak the timing if you find you have issues there.
Fonts are just in a simple binary format. The format got briefly documented (copied below). I can't recall what tool I used to convert the raw data for the demos, it was probably something temporary I hacked up on an old PC I used back then, but it should be simple to code something to convert your font into the right data format.
' Font data format:
'
' Fonts are required to be formatted as 256 byte blocks for each scanline in
' the font (requiring 8 pixel wide data per character). These 256 byte
' blocks are then repeated by the height of the font in pixels.
'
' The least significant bits of the font data are displayed first.
'
' Bits set in the font data represent foreground coloured pixels for each
' character while cleared bits are used for background coloured pixels.
The original complexdemo would have issues at that resolution because of its colour text requirements of at least 5x pixel clock which will exceed the P2 rating signficantly. My new version now allows monochrome text that does not have that same burden and can work that high. I think it only needs a 2x or 3x clock. For generating full colour text at 1080p over VGA it will require another COG one day to render into a scanline buffer that this driver will then output. There are limits.
If you try 74.25MHz with 1080i, it may just work with a 5x clock but the P2 would need to hit ~375MHz! (or you could try a 4x clock at 300MHz, sometimes it just works out if the horizontal blanking timing is sufficient, and fractional clocks are supported too, if you want to experiment between 300-375MHz to find the working limit).
Note, in graphics mode, you'll mostly only need a 2x clock (or even 1x in transparent mode) but text takes quite a lot more overhead.
When I did VGA 1920x1080 8x8 font some 18 months ago, IIRC I used 1pp with a single foreground colour and a background colour. I was able to switch the colours on each line. IIRC I used 148.5MHz.
I am trying to just get 1920x1080 to display. Colours don’t matter. Is your driver able to do this?
Just wondering and experimenting what it can do, even if I need to convert chars to font bitmap using another cog.
Yep it can do 1920x1080 with graphics regions only at 297MHz. To do a text mode in full HD you'll need to wait for my next release to support the mono text with 1920x1080 at the lower P2 clock rates.
In my original driver you can try creating a single region with these settings in the complex demo (the zeroth 3rd argument for the size will cause the first region to take up the entire screen, and so any other text regions causing problems won't be shown) e.g.:
Tried it and works
Not rock steady. In particular, the border seemed a little eratic. Didn't waste any time on it tho as I'll wait for your next release
I've added some improved text region handling in the driver code (it was incomplete before in the beta) and now each COG can have its own text context where it maintains which display & region will receive printed text, along with tracking the region's current write position and the foreground and background text colour nibbles. An optional HW cursor for each region can also be linked to the write position to keep them synced automatically if desired. Every text region can actually display its own HW text cursor at the same time though I've found while doing that it can confuse things a bit for the user when more than one cursor is displayed, so probably good to hide the last region's cursor when switching text output to a different region. I have added an option to have that done for you as well.
After being initialized, COGs can swap their current text output context to other saved contexts to allow them to draw into other configured text regions when more than one exists on the display(s). The text region can optionally be cleared with blanks when it is created, and/or later with a clear method.
Beyond ordinary printable characters, the code will handle TAB/BS/CR/LF chars and will automatically scroll as the data is printed to a text region when it reaches end of line and end of region. It will also handle optional skew for a viewport into wider windows. I do have another independent get/set API to control both the current soft+HW cursor positions for each region and its fg/bg colours and of course people can also still fully manage their screen buffer contents independently if they'd like.
In addition to single characters, hex, dec and binary data can be printed along with zero terminated strings, though ideally this belongs outside the driver in the future with some type of common formatting API.
For now I'm trying to keep it simple/small but if anyone has a request for other useful text output capabilities within the SPIN2 driver this is a good time for me to try to add it. There is no real standard for doing this for the P2 though one might start to evolve a bit like P1.
I also did some benchmark testing by experimenting with text regions and different P2 clock speeds and my new mono text mode at lower P2:pixel clock ratios seems to be working out well. Mono mode gets selected at startup based on the P2:pixel clock ratio. You do need to operate at least at a 2x pixel clock or higher for any text regions to work (eg. above ~50MHz for VGA). When the ratio falls within the range from [2,3) you just get plain mono text (1bpp), with no attributes. When it falls within the range from [3,5) you get mono text and two text attributes in the upper bits of the 16 bit word in the screen buffer. Bit8 is inverse, Bit15 is flashing and flashing is still controlled globally in the region by the region flags. You need to use ratios 5 and over to enable colour text. Colour text already includes the optional flashing attribute. Note that in mono text mode you can still have colour graphics regions as well, the text regions perform independently.
This is what I found can be achieved for these common resolutions:
Pixel clocks used were these:
VGA=25 Mpixels/s
SVGA=40 Mpixels/s
XGA=65 Mpixels/s
SXGA=108 Mpixels/s
UXGA=162 Mpixels/s
FullHD=148.5 Mpixels/s
I guess I should also disable text regions outright if the P2:pixel clock is something below 2, even though you can probably still use that ratio in the transparent graphics mode. Right now it will still fail to display if that is attempted (code won't hang, but it will be too slow for syncs to remain stable).
Update: Just fixed this. Now for cases with less than 2 P2 clocks per pixel, any defined text regions will not slow the sync any more as they will just show each scan line in the region's background palette colour. So the driver can still continue to operate with graphics regions. I was just able to get a stable VGA graphics region in 8bpp or less colour depths (but not 256 LUT which is memory intensive) running at 25MHz with no pixel doubling of course. This will still be useful for ultra low clocked P2s to gain some VGA graphics output capabilities. Maybe RC fast might work. EDIT: just tried it, I get a display output but the hsyncs are rather jittery on the scope and there are some scan line glitches on screen. The RC oscillator is not a good clock for video.
Update 2: I found you can get a mouse sprite working with 1bpp so in theory you could put together a 640x480 mono GUI on a 25MHz P2 with this. Get the old school Macintosh look. Mouse sprite also appears to work at 2bpp too but no higher.
As an experiment I just took the P1 16x32 font and mapped the leftmost 8 pixels of the lower 128 characters of the font and rightmost pixels into the upper 128 characters of the font and then display characters with bit7 alternating between 0/1 in the screen buffer to draw both halves of the wider character. I can now display 120x33 characters in 1080p and it looks quite readable (in mono) for simple text only applications albeit without lots of extra drawing symbols etc. It also works with pixel doubling and line doubling independently so you can go down to 60x16 or 60x33 etc.
Here's a pic of this method driving out mono text at the slightly higher 1920x1200 on my Dell monitor which looks really clean in person:
I also finally located this underlying bug that would draw into the wrong address and corrupt hub memory if you define the text region with a zero scan line height (which means the region just goes to end of the display). I now have to solve that issue, but at least I found what it was that would crash this text code.
This code works in both PNut and Fastspin now too which is good.
Comments
If I go past that shop again soon I might pickup a second one to cut apart with the Dremel to see what chip is used inside. The case appears to be sealed.
There was one minor bug fix which I applied to the version of Roger's driver in FlexGUI (samples/Multi-Language/video). So that's very slightly more recent than v0.8b.
I do plan a newer release soon with the HyperRAM thing. It will support a few extra things and use my new HyperRAM interface for external frame buffers in RAM/Flash, as well as dropping down to two colour text if the P2 pixel clock frequency multiple is too low for 16 colour text yet the P2 can still do full colour graphics, instead of preventing it from outputting anything whenever a colour text region is enabled as it does today. It also improves PAL timing and colour which I'd worked on too.
HyperRAM is all working with my updated video driver by the way, I'm just tidying up and getting the flash sorted. I did jut find a HyperFlash write burst boundary wrap bug in there I now need to fix and then that should finally be the end of it, at last.
A graphics drawing layer that writes into HyperRAM from other COG(s) would to be very useful too. I can hopefully put together something very simple to demo that little, but a lot of powerful drawing code could be added on top of this for decent GUI/2d gfx by anyone else. The external frame buffer certainly opens up lots more possibilities for a P2 display in high resolution, e.g. 1080p 8bpp which is probably the (overclocked) HyperRAM limit.
I've also designed the HyperRAM driver with graphics in mind from the start, so it can blit images between HUB and HyperRAM, or HyperRAM to HyperRAM or HyperFlash to HyperRAM. It can also accelerate graphics fills and generate horizontal/vertical lines, which is useful for some GUI elements like box outlines scroll bars, window edges, etc, plus it can now do read-modify-write of arbitrary bits in bytes/word/longs for less than 8bpp pixel drawing. In the future I hope it may get some arbitrary angle line drawing acceleration too if I can free a little more space or extend those portions to hub exec.
-replace cognew with coginit
-add return result variables to called functions that return values
-add () around functions
-eliminate namespace scope problems with locals and PASM labels (Fastspin is more lenient there)
-there was some printing bug in the driver I found that showed up more in PNut SPIN2 but not using Fastspin. I know I'd had problems there before but never fully tracked it down, and using PNut seemed to make it appear immediately. Sorted now.
Demos also needed some similar work to get them running.
The P2 PLL setup with CLKSET is different too with how SPIN2 does it vs Fastspin and I still need to work on that a bit more to make the driver work nicer.
I plan to release an updated version that works with PNut SPIN2 soon.
This is weird because my driver is a common PASM object and should be assembling then operating identically. I'm trying to hunt for binary differences but I'll probably need to extract my driver's PASM binary part within the OBJ generated by PNut and compare with Fastspin data to be 100% sure both tools generate the same code.
The only other thing could be bootup timing differences if my driver code has some particular dependence there that works only with Fastspin and not PNut, but I can't see what that would be.
Also check for RAM initialization problems - these catch me out quite often. Often your code "expects" all RAM to be initialized (e.g. to zero). Usually, you can spot these by manually having your program initialize unused RAM before it starts - if this changes the program behaviour, you have an initialization problem!
For now I have found they are all jmp # instructions that are different. I need to see if these make sense. Might be relative/absolute defaults but that is weird too because there are other jumps in the code that are the same with both tools.
I think that will be it
At the time Pnut was also trying to use relative branching between hubRAM and lutRAM, I think. That's a bit of a no-no. I didn't bother bringing it up because PNut 's jumps/calls weren't trustworthy then anyway. I haven't looked at it again.
I've now patched these locations to use absolute jumps. Video seems to work now again for both Fastspin and PNut in the prior failing situation.
Happy days.
If other non 8 pixel character sizes are required with more characters or colour options, additional COG(s) could be used to render into a line buffer which my video driver outputs, it was designed to allow for that though there is not an example available for this yet. I do want to work on an add-on sprite driver for this video driver after it is released.
WOW!!!
Congratulations. The complexdemo is fantastic!!!
Now to see how to drive this in VGA 1920x1080 with various sections.
I see you have included 4 font sets as binaries. How did you make the binary?
I have an 8x8 font that I derived from hippy's font for the P1 that I thought I might try out. But time for some playing first.
Fonts are just in a simple binary format. The format got briefly documented (copied below). I can't recall what tool I used to convert the raw data for the demos, it was probably something temporary I hacked up on an old PC I used back then, but it should be simple to code something to convert your font into the right data format.
' Font data format:
'
' Fonts are required to be formatted as 256 byte blocks for each scanline in
' the font (requiring 8 pixel wide data per character). These 256 byte
' blocks are then repeated by the height of the font in pixels.
'
' The least significant bits of the font data are displayed first.
'
' Bits set in the font data represent foreground coloured pixels for each
' character while cleared bits are used for background coloured pixels.
I have modified for 1024x768 with 128x48 characters and all ok
However, I am missing something in getting 1920x1080 working. Using the font16 so 240x62 (should be 62.5 or else 135 if 8x8 font).
Here is an extract
If you try 74.25MHz with 1080i, it may just work with a 5x clock but the P2 would need to hit ~375MHz! (or you could try a 4x clock at 300MHz, sometimes it just works out if the horizontal blanking timing is sufficient, and fractional clocks are supported too, if you want to experiment between 300-375MHz to find the working limit).
Note, in graphics mode, you'll mostly only need a 2x clock (or even 1x in transparent mode) but text takes quite a lot more overhead.
I am trying to just get 1920x1080 to display. Colours don’t matter. Is your driver able to do this?
Just wondering and experimenting what it can do, even if I need to convert chars to font bitmap using another cog.
In my original driver you can try creating a single region with these settings in the complex demo (the zeroth 3rd argument for the size will cause the first region to take up the entire screen, and so any other text regions causing problems won't be shown) e.g.:
Not rock steady. In particular, the border seemed a little eratic. Didn't waste any time on it tho as I'll wait for your next release
EDIT: It might be the mouse being enabled too. I think I put in a fix for that in 1080p in my latest revision which maxes out the timing limit.
After being initialized, COGs can swap their current text output context to other saved contexts to allow them to draw into other configured text regions when more than one exists on the display(s). The text region can optionally be cleared with blanks when it is created, and/or later with a clear method.
Beyond ordinary printable characters, the code will handle TAB/BS/CR/LF chars and will automatically scroll as the data is printed to a text region when it reaches end of line and end of region. It will also handle optional skew for a viewport into wider windows. I do have another independent get/set API to control both the current soft+HW cursor positions for each region and its fg/bg colours and of course people can also still fully manage their screen buffer contents independently if they'd like.
In addition to single characters, hex, dec and binary data can be printed along with zero terminated strings, though ideally this belongs outside the driver in the future with some type of common formatting API.
For now I'm trying to keep it simple/small but if anyone has a request for other useful text output capabilities within the SPIN2 driver this is a good time for me to try to add it. There is no real standard for doing this for the P2 though one might start to evolve a bit like P1.
I also did some benchmark testing by experimenting with text regions and different P2 clock speeds and my new mono text mode at lower P2:pixel clock ratios seems to be working out well. Mono mode gets selected at startup based on the P2:pixel clock ratio. You do need to operate at least at a 2x pixel clock or higher for any text regions to work (eg. above ~50MHz for VGA). When the ratio falls within the range from [2,3) you just get plain mono text (1bpp), with no attributes. When it falls within the range from [3,5) you get mono text and two text attributes in the upper bits of the 16 bit word in the screen buffer. Bit8 is inverse, Bit15 is flashing and flashing is still controlled globally in the region by the region flags. You need to use ratios 5 and over to enable colour text. Colour text already includes the optional flashing attribute. Note that in mono text mode you can still have colour graphics regions as well, the text regions perform independently.
This is what I found can be achieved for these common resolutions:
Pixel clocks used were these:
VGA=25 Mpixels/s
SVGA=40 Mpixels/s
XGA=65 Mpixels/s
SXGA=108 Mpixels/s
UXGA=162 Mpixels/s
FullHD=148.5 Mpixels/s
I guess I should also disable text regions outright if the P2:pixel clock is something below 2, even though you can probably still use that ratio in the transparent graphics mode. Right now it will still fail to display if that is attempted (code won't hang, but it will be too slow for syncs to remain stable).
Update: Just fixed this. Now for cases with less than 2 P2 clocks per pixel, any defined text regions will not slow the sync any more as they will just show each scan line in the region's background palette colour. So the driver can still continue to operate with graphics regions. I was just able to get a stable VGA graphics region in 8bpp or less colour depths (but not 256 LUT which is memory intensive) running at 25MHz with no pixel doubling of course. This will still be useful for ultra low clocked P2s to gain some VGA graphics output capabilities. Maybe RC fast might work. EDIT: just tried it, I get a display output but the hsyncs are rather jittery on the scope and there are some scan line glitches on screen. The RC oscillator is not a good clock for video.
Update 2: I found you can get a mouse sprite working with 1bpp so in theory you could put together a 640x480 mono GUI on a 25MHz P2 with this. Get the old school Macintosh look. Mouse sprite also appears to work at 2bpp too but no higher.
Here's a pic of this method driving out mono text at the slightly higher 1920x1200 on my Dell monitor which looks really clean in person:
In terms of using the full Parallax font with all its 256 characters I know some work was done to compress the P1 font down to 8 pixel widths some time back, so I should try to find something that works there too.
https://forums.parallax.com/discussion/101194/fascinating-two-secret-internal-rom-fonts
I also finally located this underlying bug that would draw into the wrong address and corrupt hub memory if you define the text region with a zero scan line height (which means the region just goes to end of the display). I now have to solve that issue, but at least I found what it was that would crash this text code.
This code works in both PNut and Fastspin now too which is good.