VOGONS

Common searches


First post, by videogamer555

User metadata
Rank Member
Rank
Member

I know in 16-color modes, such as EGA (320x200 and 640x200) and VGA (640x350), you have normally have to put the bits in one bitplane at a time (using a control register on the graphics card via the OUT x86 instruction, to set the plane that you are about to copy the image data to). However I also, know that some more exotic modes can be achieved by actually playing with some of the other features of these graphics card control registers, doing things like chaining and unchaining the shift registers in the graphics card via the use of graphics card control registers. Is it possible to do some of this hacky graphics register programming to achieve a bit-packed (not bit-planar) 16 color mode in EGA or VGA graphics? If so, it would make a lot of the rest of the graphics programing a lot simpler (programming for bit-packed graphics is a lot simpler than programming for bit-planar graphics).
Furthermore, even if this is possible on real x86 PCs, I'm not sure if it's possible in DosBox, due to it only implementing the bare minimum number of x86 features needed for getting games to run. Can anybody here tell me if it's possible to do switch to a bit-packed 16 color mode in DosBox?

Reply 1 of 14, by ViTi95

User metadata
Rank Member
Rank
Member

With EGA cards you can write pixels to VRAM in a chunky way using Write Mode 2, BUT it's much slower than writing plane by plane (it requires a read and a write operation from the video card for each pixel). I guess the only way to do bit-packed 16 color graphics is using the text modes (VGA supports 80x200 resolution this way, using half characters you can get up to 160x200 or 80x400). And yes, DosBox implements nearly 99% of the functionality of EGA and VGA cards, so you can test those modes without problems.

https://www.youtube.com/@viti95

Reply 2 of 14, by videogamer555

User metadata
Rank Member
Rank
Member
ViTi95 wrote on 2022-01-31, 09:22:

With EGA cards you can write pixels to VRAM in a chunky way using Write Mode 2, BUT it's much slower than writing plane by plane (it requires a read and a write operation from the video card for each pixel). I guess the only way to do bit-packed 16 color graphics is using the text modes (VGA supports 80x200 resolution this way, using half characters you can get up to 160x200 or 80x400). And yes, DosBox implements nearly 99% of the functionality of EGA and VGA cards, so you can test those modes without problems.

Thanks for that info. How do you access "write mode 2"? Which graphics card registers (as accessed with the IN and OUT instructions) would you use?
Also, how do you get 80x200 (or 80x400) in a text mode? Even with half-height graphics characters, that implies characters with a total height of 4 (or 2) pixels. Which graphics card registers would I need to access to chanhe the font height?

Reply 3 of 14, by ViTi95

User metadata
Rank Member
Rank
Member

Using EGA/VGA Write Mode 2 it's a little bit complicated, you should read this book, it explains it very well with some examples http://vtda.org/books/Computing/Programming/E … DyckKliewer.pdf

The VGA 80x200 mode is set by changing the number of scanlines to draw per character in 80x25 text mode. In this "mode", only the first row is drawn per character (it's similar to the CGA 160x100 16 color hack). You can checkout how it's done in this repo: https://github.com/drwonky/cgax16demo

Also FastDoom supports this mode, the code it's a little bit messy but shows fine how to draw in this mode https://github.com/viti95/FastDoom/blob/maste … ASTDOOM/i_ibm.c, methods VGA16_DrawBackbuffer and I_InitGraphics.

https://www.youtube.com/@viti95

Reply 4 of 14, by videogamer555

User metadata
Rank Member
Rank
Member
ViTi95 wrote on 2022-01-31, 17:36:

Using EGA/VGA Write Mode 2 it's a little bit complicated, you should read this book, it explains it very well with some examples http://vtda.org/books/Computing/Programming/E … DyckKliewer.pdf

The VGA 80x200 mode is set by changing the number of scanlines to draw per character in 80x25 text mode. In this "mode", only the first row is drawn per character (it's similar to the CGA 160x100 16 color hack). You can checkout how it's done in this repo: https://github.com/drwonky/cgax16demo

Also FastDoom supports this mode, the code it's a little bit messy but shows fine how to draw in this mode https://github.com/viti95/FastDoom/blob/maste … ASTDOOM/i_ibm.c, methods VGA16_DrawBackbuffer and I_InitGraphics.

Thanks. I'll have to check that out.
I also discovered something. If I set the chaining bit in graphics card sequencer register 4. It does something quite interesting (at least in DosBox, not sure about real hardware). It changes it from the normal EGA image-planar mode (where you have to select each plane you want to write to with sequencer register 2), to a byte-planar mode (where no plane selecting via register is required, as each consecutive byte writes to the next plane for that set of 8 pixels, and increments to the next set of 8 pixels after going through 4 bytes). This is a good compromise between packed pixel, where each byte contains RGBI data for 2 pixels, and fully planar mode where you can only write to one color channel at a time (switching color channels with a separate editing of sequencer register 4). Once this byte-planar mode is active, you don't need to do any more editing of the graphics card's registers. This means many fewer lines of code, as you don't need to keep switching color planes, and you also don't need to worry about the complexities of using Write Mode 2 (which from what I have read, operates in a very counterintuitive way, requiring you to read VRAM, not just write to it, in order to display an image).

In the following examples, each letter represents a single bit:
Normal EGA mode works like this (screen pixel dimensions are 16x4 in this example, and byte width is 2)
Four planes, one for each color channel
Plane B
BBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBB
Plane G
GGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGG
GGGGGGGGGGGGGGGG
Plane R
RRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRR
RRRRRRRRRRRRRRRR
Plane I
IIIIIIIIIIIIIIII
IIIIIIIIIIIIIIII
IIIIIIIIIIIIIIII
IIIIIIIIIIIIIIII

Byte planar EGA mode works like this (screen pixel dimensions are 2x4 in this example, and byte width is 8 )
One plane with four color channels
RRRRRRRRGGGGGGGGBBBBBBBBIIIIIIIIRRRRRRRRGGGGGGGGBBBBBBBBIIIIIIII
RRRRRRRRGGGGGGGGBBBBBBBBIIIIIIIIRRRRRRRRGGGGGGGGBBBBBBBBIIIIIIII
RRRRRRRRGGGGGGGGBBBBBBBBIIIIIIIIRRRRRRRRGGGGGGGGBBBBBBBBIIIIIIII
RRRRRRRRGGGGGGGGBBBBBBBBIIIIIIIIRRRRRRRRGGGGGGGGBBBBBBBBIIIIIIII

Reply 5 of 14, by mkarcher

User metadata
Rank l33t
Rank
l33t
videogamer555 wrote on 2022-01-31, 21:46:

Thanks. I'll have to check that out.
I also discovered something. If I set the chaining bit in graphics card sequencer register 4. It does something quite interesting (at least in DosBox, not sure about real hardware). It changes it from the normal EGA image-planar mode (where you have to select each plane you want to write to with sequencer register 2), to a byte-planar mode (where no plane selecting via register is required, as each consecutive byte writes to the next plane for that set of 8 pixels, and increments to the next set of 8 pixels after going through 4 bytes).

The idea you describe (enabling chain-4 mode on 16-color modes) doesn't work on EGA cards, because that mode hasn't been implemented until VGA. But it should work perfectly on any VGA compatible card. The drawback of that approach is that you limit the video memory available from 256KB to 64KB, so you are limited to 640 * 200 pixels and a single page.

The opposite of your idea is well-known: The default 256-color mode limits memory to 64KB, which is just enough for 320 * 200 pixels at 256 colors. If you disable chain-4, you get access to the full 256KB of VGA memory, which allows hardware-scrolling, page flipping and/or higher resoultions up to 360*480. This is called "Mode X". Because Mode X works everywhere, your "chained 16-color mode" should also work everywhere.

Reply 6 of 14, by videogamer555

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2022-01-31, 22:34:

The idea you describe (enabling chain-4 mode on 16-color modes) doesn't work on EGA cards, because that mode hasn't been implemented until VGA. But it should work perfectly on any VGA compatible card. The drawback of that approach is that you limit the video memory available from 256KB to 64KB, so you are limited to 640 * 200 pixels and a single page.

The opposite of your idea is well-known: The default 256-color mode limits memory to 64KB, which is just enough for 320 * 200 pixels at 256 colors. If you disable chain-4, you get access to the full 256KB of VGA memory, which allows hardware-scrolling, page flipping and/or higher resoultions up to 360*480. This is called "Mode X". Because Mode X works everywhere, your "chained 16-color mode" should also work everywhere.

I see. I wasn't aware of the limitations of EGA here. I had been getting my graphics card registers info from http://www.osdever.net/FreeVGA/vga/vga.htm which is all about VGA. It has very thorough documentation on the VGA registers, some of which I assume also go back to EGA or even CGA. But I have never seen a good documentation on EGA or CGA cards specifically, so I don't know exactly what features their registers have that are limited compared to VGA. A website similar to the one I linked to but with documentation on the EGA card would be great. Same with CGA cards. If you know of such websites, a link would ne much appreciated.

Reply 7 of 14, by ViTi95

User metadata
Rank Member
Rank
Member

The original IBM EGA manual describes it's registers, maybe it could be useful http://minuszerodegrees.net/oa/OA%20-%20IBM%2 … s%20Adapter.pdf

Also I can try those experiments with real hardware (nearly any kind of known video card), I'm very interested to test if it's possible to have bit-packed EGA modes.

https://www.youtube.com/@viti95

Reply 8 of 14, by videogamer555

User metadata
Rank Member
Rank
Member
ViTi95 wrote on 2022-02-01, 00:26:

The original IBM EGA manual describes it's registers, maybe it could be useful http://minuszerodegrees.net/oa/OA%20-%20IBM%2 … s%20Adapter.pdf

Also I can try those experiments with real hardware (nearly any kind of known video card), I'm very interested to test if it's possible to have bit-packed EGA modes.

Thanks. Do you also know where I could get a CGA manual?

Reply 9 of 14, by videogamer555

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2022-01-31, 22:34:
videogamer555 wrote on 2022-01-31, 21:46:

Thanks. I'll have to check that out.
I also discovered something. If I set the chaining bit in graphics card sequencer register 4. It does something quite interesting (at least in DosBox, not sure about real hardware). It changes it from the normal EGA image-planar mode (where you have to select each plane you want to write to with sequencer register 2), to a byte-planar mode (where no plane selecting via register is required, as each consecutive byte writes to the next plane for that set of 8 pixels, and increments to the next set of 8 pixels after going through 4 bytes).

The idea you describe (enabling chain-4 mode on 16-color modes) doesn't work on EGA cards, because that mode hasn't been implemented until VGA. But it should work perfectly on any VGA compatible card. The drawback of that approach is that you limit the video memory available from 256KB to 64KB, so you are limited to 640 * 200 pixels and a single page.

The opposite of your idea is well-known: The default 256-color mode limits memory to 64KB, which is just enough for 320 * 200 pixels at 256 colors. If you disable chain-4, you get access to the full 256KB of VGA memory, which allows hardware-scrolling, page flipping and/or higher resoultions up to 360*480. This is called "Mode X". Because Mode X works everywhere, your "chained 16-color mode" should also work everywhere.

I know Q Basic (not sure about GW Basic) is capable of some kind of 16 color mode, where the color of each pixel is specified by single PSet statement. I'm not sure how it does that. When PSet is used in 16 color mode, Does it switch beteween all 4 color planes and set the color of the pixel? If so, that is a huge time waster for setting a single pixel. There would be MANY steps needed to set a single pixel using that method. Or does it use some kind kind of exotic mode that actually allows a single byte to specify the color of a single pixel? If so, that's even more exotic than bit-packed mode if it is, because in packed mode, you have 2 nibbles in one byte, to specify the color of a pair of pixels. However, in Q Basic's PSet statement, the upper nibble is ignored, while the lower nibble of the byte is used to set the color, and the x and y coordinates in the PSet statement are used to select the specific pixel. The PSet statement looks like this:
PSet(x,y),PaletteIndex
x is the x coordinate of the pixel to set
y is the y coordinate of the pixel to set
PaletteIndex is the index of the desired color in the 16-color EGA palette.

Reply 10 of 14, by ViTi95

User metadata
Rank Member
Rank
Member
videogamer555 wrote on 2022-02-01, 01:52:
ViTi95 wrote on 2022-02-01, 00:26:

The original IBM EGA manual describes it's registers, maybe it could be useful http://minuszerodegrees.net/oa/OA%20-%20IBM%2 … s%20Adapter.pdf

Also I can try those experiments with real hardware (nearly any kind of known video card), I'm very interested to test if it's possible to have bit-packed EGA modes.

Thanks. Do you also know where I could get a CGA manual?

http://minuszerodegrees.net/oa/OA%20-%2 ... 0(CGA).pdf ^^

https://www.youtube.com/@viti95

Reply 11 of 14, by Ringding

User metadata
Rank Member
Rank
Member
videogamer555 wrote on 2022-02-01, 02:15:

I know Q Basic (not sure about GW Basic) is capable of some kind of 16 color mode, where the color of each pixel is specified by single PSet statement. I'm not sure how it does that. When PSet is used in 16 color mode, Does it switch beteween all 4 color planes and set the color of the pixel? If so, that is a huge time waster for setting a single pixel. There would be MANY steps needed to set a single pixel using that method.

Yes, that’s what it does, and it is indeed very slow.

Reply 12 of 14, by mkarcher

User metadata
Rank l33t
Rank
l33t
Ringding wrote on 2022-02-01, 08:24:
videogamer555 wrote on 2022-02-01, 02:15:

I know Q Basic (not sure about GW Basic) is capable of some kind of 16 color mode, where the color of each pixel is specified by single PSet statement. I'm not sure how it does that. When PSet is used in 16 color mode, Does it switch beteween all 4 color planes and set the color of the pixel? If so, that is a huge time waster for setting a single pixel. There would be MANY steps needed to set a single pixel using that method.

Yes, that’s what it does, and it is indeed very slow.

Are you sure it doesn't use the set/reset mechanism instead of accessing all planes? The recommended way to set a single pixel (assuming write mode 0 / no data rotation / no other frills are enabled) is:

  • Set the enable set/reset register to 0Fh
  • Set the required color in the set/reset register
  • Set the bit mask register to the pixel you want to set
  • cause a read/write on that address in EGA memory space (e.g. using INC)

The value written in the last step doesn't matter because the enable set/reset register causes the value from the set/reset register to replace the CPU data for all four planes. If you know you are setting several pixels in a row, you don't have to repeat the first step for each pixel. If you want to set multiple pixels of the same color in a row, you can omit the first two steps. Of course, a general purpose PSET function will most likely do all four steps, because on an XT just doing it is likely faster than (or as fast as) keeping track whether you can avoid the first or the first two steps.

Reply 13 of 14, by pan069

User metadata
Rank Oldbie
Rank
Oldbie

Just for an interesting demonstration of what you can achieve in 16 color VGA, check out DoWhackaDo by Renaissance (White Shadow). This demo uses the bit planes as individual planes (i.e. the background, scrollers and foreground logo) all exist each in their own plane (single color of course). The illusion of multiple colors (e.g. the blue gradient in the scroller) is achieved by changing the palette each scanline (like you'd do for traditional copper bars). It's a real work of art. Best viewed on real hardware of course (it even runs on my 286 16Mhz.) 😀

https://www.youtube.com/watch?v=iSVAFEbB_j8

https://www.pouet.net/prod.php?which=3544

Edit: PS. I did some digging on this demo a few years back, was trying to figure out how to logo moves in front and behind the scroller: Re: Programming the VGA chip in C/C++ for 16 bit DOS - help writing my own routines

Last edited by pan069 on 2022-02-01, 09:49. Edited 1 time in total.

Reply 14 of 14, by Ringding

User metadata
Rank Member
Rank
Member
mkarcher wrote on 2022-02-01, 09:18:
Are you sure it doesn't use the set/reset mechanism instead of accessing all planes? The recommended way to set a single pixel ( […]
Show full quote

Are you sure it doesn't use the set/reset mechanism instead of accessing all planes? The recommended way to set a single pixel (assuming write mode 0 / no data rotation / no other frills are enabled) is:

  • Set the enable set/reset register to 0Fh
  • Set the required color in the set/reset register
  • Set the bit mask register to the pixel you want to set
  • cause a read/write on that address in EGA memory space (e.g. using INC)

Ok, you’re right. It will probably use this method. It still needs to do a bunch of OUT instructions. What I wanted to say is that it has to do more work than writing a byte to a memory address somewhere.