DOS VGA Tricks

Discussion of development of software for any "obsolete" computer or video game system.
lidnariq
Posts: 10707
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DOS VGA Tricks

Post by lidnariq »

Just to explain everything – you could definitely do this yourself but I'm amused by doing this:

3C2h : 63 vs E3 - change sync flags from marking 400-scanline mode to marking 480-scanline mode. Doesn't necessarily do anything; fixed-frequency VGA monitors used this to adjust the vertical size
3D4h,01 : 4F vs 3F - 80 or 64 4-pixel units (horizontal size)
3D4h,02 : 50 vs 40 - preserve just one 4-pixel unit of overscan (256c mode doesn't really use colored overscan anyway)
3D4h,04 : 54 vs 4A - move hsync later within the scanline, so that the 256 drawn pixels are centered, more or less
3D4h,05 : 80 vs 9A - adjust hsync length from 12 to 16 4-pixel units (((4A & ~1F) | (9A & 1F)) = 5A)
3D4h,06 : BF vs 0B - vertical height was 0x1BF+2 scanlines, is now 0x20B+2 scanlines
3D4h,07 : 1F vs 3E - vertical height was 0x1BF is now 0x20B
3D4h,10 : 9C vs DA - vsync started at 0x19C, now starts at 0x1DA
3D4h,11 : 8E vs 9C - compensates for change in index 10
3D4h,12 : 8F vs BF - active area increased from 0x18F+1 scanlines to 0x1BF+1 scanlines
3D4h,13 : 28 vs 20 - logical screen width was 40 8-pixel units, is now 32 8-pixel units
3D4h,15 : 96 vs C7 - lower overscan increased from 6 scanlines to 8 scanlines (subtract index 12)
3D4h,16 : B9 vs 04 - upper overscan increased from 6 scanlines to 7 scanlines (subtract from index 6)
User avatar
Nikku4211
Posts: 427
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: DOS VGA Tricks

Post by Nikku4211 »

lidnariq wrote: Mon Nov 30, 2020 6:20 pm Just to explain everything – you could definitely do this yourself but I'm amused by doing this:

3C2h : 63 vs E3 - change sync flags from marking 400-scanline mode to marking 480-scanline mode. Doesn't necessarily do anything; fixed-frequency VGA monitors used this to adjust the vertical size
3D4h,01 : 4F vs 3F - 80 or 64 4-pixel units (horizontal size)
3D4h,02 : 50 vs 40 - preserve just one 4-pixel unit of overscan (256c mode doesn't really use colored overscan anyway)
3D4h,04 : 54 vs 4A - move hsync later within the scanline, so that the 256 drawn pixels are centered, more or less
3D4h,05 : 80 vs 9A - adjust hsync length from 12 to 16 4-pixel units (((4A & ~1F) | (9A & 1F)) = 5A)
3D4h,06 : BF vs 0B - vertical height was 0x1BF+2 scanlines, is now 0x20B+2 scanlines
3D4h,07 : 1F vs 3E - vertical height was 0x1BF is now 0x20B
3D4h,10 : 9C vs DA - vsync started at 0x19C, now starts at 0x1DA
3D4h,11 : 8E vs 9C - compensates for change in index 10
3D4h,12 : 8F vs BF - active area increased from 0x18F+1 scanlines to 0x1BF+1 scanlines
3D4h,13 : 28 vs 20 - logical screen width was 40 8-pixel units, is now 32 8-pixel units
3D4h,15 : 96 vs C7 - lower overscan increased from 6 scanlines to 8 scanlines (subtract index 12)
3D4h,16 : B9 vs 04 - upper overscan increased from 6 scanlines to 7 scanlines (subtract from index 6)
Thanks for explaining. I was really clueless on some of these.
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.
lidnariq
Posts: 10707
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DOS VGA Tricks

Post by lidnariq »

lidnariq wrote: Tue Nov 24, 2020 6:32 pm I should clearly go make a custom build of dosbox that logs VGA register access.
So I did. Very little beyond what I already surmised, except:

- The "plasma" at the beginning is not a raster effect at all; it's just double-buffered.
- the hardware Y zoom is a raster effect using 3d4 index 13 to repeat scanlines, not 3d4 index 9. In hindsight, this makes sense, because it lets him achieve fractional scaling
- The various "water" effects sometimes uses 3d4/13 to skip rows of data altogether
- the various "wobble" effects only update 3d4/4, so each time it steps left or right, the scanline is too short or too long by 4 pixels. Ideally, he would have written to indices 1-5 to keep hsync timing perfectly constant, but that might have been too slow. (But ... who knows? there's enough time for 4 writes for a palette update, and 10 writes is more but not waaaaay more)

The X zooming is actually more clever than it has any right to be. I hadn't noticed – probably should have – each scanline is only a single color. Indeed, the entire image is packed with each scanline of image data in its own bitplane, and it uses 3c0/0, 3c0/10, and 3c0/14 to only draw specific linear combinations of bitplanes on each scanline. (It also uses 3d4/c&d plus 3d4/13 to only draw one scanline's worth of data). I can't quite figure out how to unbake the source bitplanes:
Xzoomer.png
Xzoomer.png (232 Bytes) Viewed 8231 times
into "SURPRISE! PRODUCTIONS" but it's at least reminiscent.
User avatar
Nikku4211
Posts: 427
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: DOS VGA Tricks

Post by Nikku4211 »

lidnariq wrote: Tue Dec 01, 2020 2:07 am
lidnariq wrote: Tue Nov 24, 2020 6:32 pm I should clearly go make a custom build of dosbox that logs VGA register access.
So I did.
Wow. That was fast.
lidnariq wrote: Tue Dec 01, 2020 2:07 am - The various "water" effects sometimes uses 3d4/13 to skip rows of data altogether
So it changes virtual screen width too?
lidnariq wrote: Tue Dec 01, 2020 2:07 am - the various "wobble" effects only update 3d4/4, so each time it steps left or right, the scanline is too short or too long by 4 pixels. Ideally, he would have written to indices 1-5 to keep hsync timing perfectly constant, but that might have been too slow. (But ... who knows? there's enough time for 4 writes for a palette update, and 10 writes is more but not waaaaay more)
Bruh moment.
lidnariq wrote: Tue Dec 01, 2020 2:07 am The X zooming is actually more clever than it has any right to be. I hadn't noticed – probably should have – each scanline is only a single color. Indeed, the entire image is packed with each scanline of image data in its own bitplane, and it uses 3c0/0, 3c0/10, and 3c0/14 to only draw specific linear combinations of bitplanes on each scanline. (It also uses 3d4/c&d plus 3d4/13 to only draw one scanline's worth of data). I can't quite figure out how to unbake the source bitplanes:Xzoomer.png into "SURPRISE! PRODUCTIONS" but it's at least reminiscent.
So now you have got to crack the bitplane source. Does it use an actual planar colour mode, or is the colour linear?
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.
lidnariq
Posts: 10707
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DOS VGA Tricks

Post by lidnariq »

Nikku4211 wrote: Tue Dec 01, 2020 9:42 am
lidnariq wrote: Tue Dec 01, 2020 2:07 am - The various "water" effects sometimes uses 3d4/13 to skip rows of data altogether
So it changes virtual screen width too?
Yeah, on a scanline-to-scanline basis. Think of 3d4/13 as holding "what number to add to the current redraw pointer to get the next redraw pointer".

So when it's unchanging, it just the virtual screen width.

In the relevant effect here, he's using any of 0, 40, 80, 120 to either repeat a scanline, advance one scanline, or skip one or two scanlines.

In a raster effect, it's the closest thing that the VGA has to being able to set X/Y scrolling. It lets you adjust the coarse scrolling position ... as long as the next one is not earlier, and no more than 1020/2040/4080 pixels later in framebuffer memory.
lidnariq wrote: Tue Dec 01, 2020 2:07 am the entire image is packed with each scanline of image data in its own bitplane
So now you have got to crack the bitplane source. Does it use an actual planar colour mode, or is the colour linear?
Actually, a night's sleep told me where I'd gone astray. It's not planar; instead each color is marking its own segment. (In the limit, this would become planar, but it only uses 15 segments, not a full 31 that 5 scanlines might require)

Where the demo writes to 3c0/14, it's actually selecting one of six different 16-color palettes to apply for that scanline. (3c0/14 isn't supposed to work in 256color mode but this demo relies on it a lot. The "linefading" effect also uses it)

So the "SU" in "SURPRISE!" are saved as the bytes [1 2 2 3 0 4 5 5 4]
░███░█░░█ and the palette for the first displayed line lights up 2, 3, and 4
█░░░░█░░█ and the next displayed line lights up 1 and 4
░██░░█░░█ 2 and 4
░░░█░█░░█ 3 and 4
███░░░██░ 1, 2, and 5
User avatar
Nikku4211
Posts: 427
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: DOS VGA Tricks

Post by Nikku4211 »

lidnariq wrote: Tue Dec 01, 2020 11:50 am
Nikku4211 wrote: Tue Dec 01, 2020 9:42 am
lidnariq wrote: Tue Dec 01, 2020 2:07 am - The various "water" effects sometimes uses 3d4/13 to skip rows of data altogether
So it changes virtual screen width too?
Yeah, on a scanline-to-scanline basis. Think of 3d4/13 as holding "what number to add to the current redraw pointer to get the next redraw pointer".

So when it's unchanging, it just the virtual screen width.

In the relevant effect here, he's using any of 0, 40, 80, 120 to either repeat a scanline, advance one scanline, or skip one or two scanlines.

In a raster effect, it's the closest thing that the VGA has to being able to set X/Y scrolling. It lets you adjust the coarse scrolling position ... as long as the next one is not earlier, and no more than 1020/2040/4080 pixels later in framebuffer memory.
Interesting... So you can't set the source display address within a scanline's worth of time?
lidnariq wrote: Tue Dec 01, 2020 11:50 am Actually, a night's sleep told me where I'd gone astray. It's not planar; instead each color is marking its own segment. (In the limit, this would become planar, but it only uses 15 segments, not a full 31 that 5 scanlines might require)

Where the demo writes to 3c0/14, it's actually selecting one of six different 16-color palettes to apply for that scanline. (3c0/14 isn't supposed to work in 256color mode but this demo relies on it a lot. The "linefading" effect also uses it)

So the "SU" in "SURPRISE!" are saved as the bytes [1 2 2 3 0 4 5 5 4]
░███░█░░█ and the palette for the first displayed line lights up 2, 3, and 4
█░░░░█░░█ and the next displayed line lights up 1 and 4
░██░░█░░█ 2 and 4
░░░█░█░░█ 3 and 4
███░░░██░ 1, 2, and 5
Oh, that's really awesome. This is just like what Traveller's Tales did with Sonic 3D Blast's full-screen 60fps animations, except applied separately on a scanline-by-scanline basis.

What VGA variable is it setting for the X-zooming, though?
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.
lidnariq
Posts: 10707
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DOS VGA Tricks

Post by lidnariq »

Nikku4211 wrote: Tue Dec 01, 2020 6:08 pm So you can't set the source display address within a scanline's worth of time?
You can't set it at all. It's copied from 3D4h indices 0Ch+0Dh at the top of the field and then any other changes have no effect until the next field. The only way to affect the current pointer is to use 3D4h index 18h, which specifies a scanline at which to zero it. (You can update 3d4/18 multiple times per field, if you can find something useful to do with it. Maybe in combination with 3D4h index 13h?)

It's kinda like how the Master System has no ability to change Y scrolling during redraw.
What VGA variable is it setting for the X-zooming, though?
The X zoom is set by changing which single source line of pixels it's using to draw the entire screen. 3D4h indices 0Ch+0Dh again.

Here's the raw contents of video memory during that effect:
Attachments
Xzoomer-all-scanlines.png
Xzoomer-all-scanlines.png (2.98 KiB) Viewed 8152 times
User avatar
Nikku4211
Posts: 427
Joined: Sun Dec 15, 2019 1:28 pm
Location: Bronx, New York
Contact:

Re: DOS VGA Tricks

Post by Nikku4211 »

lidnariq wrote: Tue Dec 01, 2020 6:22 pm
Nikku4211 wrote: Tue Dec 01, 2020 6:08 pm So you can't set the source display address within a scanline's worth of time?
You can't set it at all. It's copied from 3D4h indices 0Ch+0Dh at the top of the field and then any other changes have no effect until the next field. The only way to affect the current pointer is to use 3D4h index 18h, which specifies a scanline at which to zero it. (You can update 3d4/18 multiple times per field, if you can find something useful to do with it. Maybe in combination with 3D4h index 13h?)

It's kinda like how the Master System has no ability to change Y scrolling during redraw.
What VGA variable is it setting for the X-zooming, though?
The X zoom is set by changing which single source line of pixels it's using to draw the entire screen. 3D4h indices 0Ch+0Dh again.

Here's the raw contents of video memory during that effect:
Oh, now I get it. Reminds me of a similar effect I did in an SMW hack.
I have an ASD, so empathy is not natural for me. If I hurt you, I apologise.
Mills
Posts: 43
Joined: Tue Jul 01, 2014 3:30 am

Re: DOS VGA Tricks

Post by Mills »

Sorry for posting on an old thread, but I just loved it.

I created that little engine someone talked about, and I'm still working on it. The information you provided about copper demo is awesome, and it game me ideas for a scan line raster effect.

On that copper demo, they use a rare VGA card which lets you change start address every scan line, but very few VGA cards and monitors will cope with that. So I focused on the 3D4h index 13h register, and I realized you can create a wavy effect with that (very very limited).

3D4h index 13h can only get values from 0 (repeat scan line) to 256. If you use the popular 320 width mode, you can only jump a few scan lines ahead (around 6). So you can interlace 6 images in VRAM (every image being a bit to the right or left) and change between them using this register.
lidnariq
Posts: 10707
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DOS VGA Tricks

Post by lidnariq »

Mills wrote: Tue Jan 11, 2022 6:43 am On that copper demo, they use a rare VGA card which lets you change start address every scan line, but very few VGA cards and monitors will cope with that.
Copper by Surprise! doesn't do that - VGA registers don't provide any interface to that.

At best, it might be possible to update the fine X scroll register (3C0h/13h) each scanline, but I don't have the hardware to check against.

The horizontal wobbles are all based around moving the sync pulse around... but:
3D4h index 13h can only get values from 0 (repeat scan line) to 256. If you use the popular 320 width mode, you can only jump a few scan lines ahead (around 6). So you can interlace 6 images in VRAM (every image being a bit to the right or left) and change between them using this register.
The hsync pulses can be moved around with 4px precision (3d4h index 4), while index 13h is 8px precision... but at least index 13h will work at all on a flat panel, or in a VM.
Mills
Posts: 43
Joined: Tue Jul 01, 2014 3:30 am

Re: DOS VGA Tricks

Post by Mills »

lidnariq wrote: At best, it might be possible to update the fine X scroll register (3C0h/13h) each scanline, but I don't have the hardware to check against.
I have a real VGA to test, I might try later. EDIT: This is not going to work, documentation says it is used to calculate the start address at the top left of the screen, and it adds this to the start address register. start address registers are only updated once per frame :(.
lidnariq wrote: The hsync pulses can be moved around with 4px precision (3d4h index 4), while index 13h is 8px precision... but at least index 13h will work at all on a flat panel, or in a VM.
I got a wave effect changing this every scanline, you have to store the image 4 times, (interlacing image lines and shifting them 2, 4, 6 pixels to the left or right). Then you have to create a weird array containing how many bytes you want to offset the next scanline, and it worked!
Screenshot from 2022-01-12 13-42-53.png
It is working on pcem (8088 4.77), I had to create a dynamic function, to modify the amount of time it takes, so that I got a stable image.
Images can't be very wide, (around 200 pixels) so that you don't see copies of the image at the right and left sides of the screen.

You can only displace lines in 2 pixels increments, and the array needed to create the waves, is so weird you can't just animate it by changing the offset.
lidnariq
Posts: 10707
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: DOS VGA Tricks

Post by lidnariq »

Mills wrote: Wed Jan 12, 2022 6:08 am I have a real VGA to test, I might try later. EDIT: This is not going to work, documentation says it is used to calculate the start address at the top left of the screen, and it adds this to the start address register. start address registers are only updated once per frame :(.
That feels weird to me - at least, in comparison to other machines that I know more about. On all the other machines I know about, the fine X scrolling amount is implemented by adjusting the amount of the shift register FIFO delays words coming in to when they're displayed. So it's weird to me that 3C0h/13h wouldn't be implemented the same way.

I could rationalize why it might not work in 256-color modes, or not in the unchained 256-color mode, but I don't see a way it could not work in 16-color or text modes...
Mills
Posts: 43
Joined: Tue Jul 01, 2014 3:30 am

Re: DOS VGA Tricks

Post by Mills »

I can't remember if I tested on a real VGA. If that works, the regular address register will also work, and emulators lack this feature.

I'm going to try it...
Joe
Posts: 475
Joined: Mon Apr 01, 2013 11:17 pm

Re: DOS VGA Tricks

Post by Joe »

Mills wrote: Wed Jan 12, 2022 6:08 amThis is not going to work, documentation says it is used to calculate the start address at the top left of the screen, and it adds this to the start address register.
What documentation are you reading? This very reliable source says the value you write applies at the start of the next line. (Scroll down a bit; it's mentioned right before the next section.)
Mills
Posts: 43
Joined: Tue Jul 01, 2014 3:30 am

Re: DOS VGA Tricks

Post by Mills »

Joe wrote: Wed Jan 12, 2022 11:42 am
Mills wrote: Wed Jan 12, 2022 6:08 amThis is not going to work, documentation says it is used to calculate the start address at the top left of the screen, and it adds this to the start address register.
What documentation are you reading? This very reliable source says the value you write applies at the start of the next line. (Scroll down a bit; it's mentioned right before the next section.)
Changing start address did not work on real VGA. Now I'm trying pixel panning and it is doing "something" in dosbox :). I have to check what i'm doing and then test on real VGA. Anyway we have only 4 pixel wave effect, but this can be used on top of 3d4h index 4 (+ 4 copies of the image) to move scanlines to the right or left any number of pixels :).

Or maybe in "EGA" mode this pixel panning can move 8 pixels to the left or right, if the 3d4h index 4 can also move 8 pixels in ega mode... (i don't know).

EDIT:Forget about EGA...
Post Reply