Skip to content

experimental display porch adjustment - #124

Draft
stevesims wants to merge 1 commit into
mainfrom
adjust-porch
Draft

experimental display porch adjustment#124
stevesims wants to merge 1 commit into
mainfrom
adjust-porch

Conversation

@stevesims

@stevesims stevesims commented Dec 24, 2023

Copy link
Copy Markdown
Contributor

exposes underlying shrinkScreen and moveScreen functions via VDU API calls shrink screen accessed using VDU 23,0,&C5,x,y
move screen via VDU 23,0,&C6,x,y

making use of "move screen" can potentially allow for low-cost smooth scrolling.

in reality, this is currently problematic and does not work well, so is unlikely to get merged in the near future.

current issues are:

  • calling a "shrink" operation causes the screen contents to be cleared (to black)
    • this changes the actual drawing area, not just the display output, which has some consequences...
    • everything is still attempted to be drawn - there is no "hidden" area per-se
  • canvas drawing operations don't seem to work quite right on a shrunken screen
    • this is visible via "delete" not visibly working on keyboard entry
  • using "move" on a shrunken screen moves the entire visible area
    • this movement is smooth, which is a plus
    • as noted above, there is no "hidden" area
  • when using "shrink" with negative Y values it is easy to create a screen mode that is invalid

using this you can potentially shrink with negative values and thus allow drawing in the "overscan" area. some screens will reject the video signal if you go too far into this area. things drawn into this overscan area are still output to the screen.

as it stands, right now this isn't what we want/need for smooth scrolling.

what we really need instead is a programable border that potentially overlaps with the display. this is likely to be related to the existing functionality present within vdp-gl, but is not what is exposed by the shrinkScreen call

@stevesims

Copy link
Copy Markdown
Contributor Author

an initial analysis of the underlying video system seems to show that it is interrupt driven using DMA to pump out data stored in memory to an array of 8 output pins at a rate that will, given appropriate resistor ladders, get transformed into a VGA signal. pixels in the screen buffer at appropriate positions seem to literally have bits set to drive the HSYNC and VSYNC pins

this therefore doesn't seem to give us an opportunity to have definable borders, where pixels in the screen buffer can in some way be invisible

it may still be possible, but without understanding much better how this output system works it's hard to imagine how 😁

@julianregel

Copy link
Copy Markdown

I know that there isn't a standard for allocating VDU commands (and I've not released recently - but it's getting close to being releasable!), but all the stuff I've been doing is working with VDU 23,0,193-196. It's not the end of the world if I need to reallocate some of them, but they are sort of logically related, so keeping them together would be good if possible.

exposes underlying `shrinkScreen` and `moveScreen` functions via VDU API calls
shrink screen accessed using `VDU 23,0,&C5,x,y`
move screen via `VDU 23,0,&C6,x,y`
@stevesims

Copy link
Copy Markdown
Contributor Author

hey @julianregel - no worries - I can easily move these. I had a vague recollection that you were planning on another call in this range, but hadn't realised you had plans for 196 as well as 194 (the current "gap"). I went with this numbering as these functions also felt related to your earlier additions

I've bumped these numbers up, so my two commands are now sitting at &C5 and &C6 (197-198). at this point however I'm doubtful these will get merged in anyway - not without some adjusting and changes to vdp-gl

@julianregel

Copy link
Copy Markdown

Thanks Steve. I know I've been very quiet, but I've been doing a lot behind the scenes :-)

Wishing you a very Happy Christmas!

@TurboVega

Copy link
Copy Markdown
Contributor

I don't think that using the horizontal synchronization bits to do scrolling is practical, for several reasons. First, we may need to use those bits simply to align the visible area of the screen with the edges of the monitor. Second, as mentioned in other comments, it can do wonky things to the monitor to have too many pixels in the scan line. Third, with good drawing code, scrolling can be accomplished just by drawing within the visible area.

I'm not against the idea of an invisible drawing area in the outer margins of the screen. I just think that if such is done, there should be code to transfer the desired image at any given frame to the DMA buffers for display.

All my opinions, of course.

@TurboVega

Copy link
Copy Markdown
Contributor

Another thought just occurred to me. It is true that the physical bytes in the DMA buffer contain VS and HS bits; however, there is no limitation on the number of links in the DMA buffer chain, or on how the bytes are broken into links. This implies that a single scan line can be in pieces, with the visible pixel bytes residing in a separate DMA buffer than the invisible pixel bytes. It is already true that active scan lines are separate from inactive (vertical blanking) scan lines. OTF shares a single copy of the blanking area pixel bytes for all 600 active scan lines, saving memory. It also shares blank lines outside the visible area, by referring to them in multiple chain links.

Vertical hardware scrolling is trivial. It just means changing links to active scan lines, and implies having extra scan line buffers for top and/or bottom margin areas. So, we will discuss the more difficult task of horizontal scrolling.

If we break the visible portion of each active scan line into 4 pieces link-wise (2 pieces buffer-wise), we can alter DMA data pointers and data sizes to cause hardware scrolling. The 4 pieces are left margin, visible area, right margin, and blanking area.

Here's how it would work.

The blanking bytes (horizontal and vertical) are initialized as usual, and never change. The visible bytes of active scan lines are where the interesting stuff happens.

If the application (game) only scrolls left, then the visible portion of each active scan line has a visible area and a right margin.

If the application only scrolls right, then the visible portion of each active scan line has a right margin and a visible area.

If the application scrolls left and right, then we need a right margin, visible area, and left margin.

In any case, as frames progress over time, to scroll horizontally, we adjust the pointers to the pixel buffers, and the data sizes, to cause parts of the margins and visible area to show or to hide. In preparation for scrolling, we update only the pixels in the margin(s).

The margins and visible area shrink or grow in width as the scroll position changes. This does require serious thought about moving objects like sprites, but at least we don't need to copy the entire screen buffer to scroll.

@TurboVega

Copy link
Copy Markdown
Contributor

On my way to feed equine this morning, the thought came to me that, if we can do scrolling in hardware, maybe we can do sprites as well. I think it's worth a side trip to test the theory.

@TurboVega

TurboVega commented Jan 19, 2024

Copy link
Copy Markdown
Contributor

Reviewing the DMA descriptor information shows that the DMA buffer pointer must be word-aligned. This could be a problem with scrolling and with sprites, unless we only want to support horizontally scrolling 4 pixels at a time. It does not affect vertical movement, though. I will have to give it more thought.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants