Improved composite mode support for DOSBox

I recently contributed to a DOSBox patch to make composite output work in all CGA graphics modes. Most CGA composite games use BIOS mode 6 (port 0x3d8 value 0x1a, aka 640x200 1bpp mode) which gives a nice range of colours. However, there are a rare few games which use a 2bpp mode but have 3.57MHz vertical lines which are quite obviously designed to yield a different palette on the composite output. DOSBox currently shows the output of such games as they would appear on a digital (aka TTL or RGBI) monitor, which isn't always what the game author intended - the example that started the thread was Fooblitsky.

I had already written code to simulate composite CGA in 2bpp mode (and indeed all modes) but there is a complication - DOSBox is based around a 256 colour palette and my code assumes 24-bit colour. The first 16 colours are also reserved for the digital CGA colours so that the palette entries don't have to be reloaded when switching between composite and digital, so only 240 colours can be used for composite CGA. The current DOSBox CGA composite implementation uses 80 palette entries - 16 colours (one for each bit pattern) times 5 brightness levels (0, 1, 2, 3 or 4 pixels lit). I realized that actually only 16 of these palette entries are really needed, since the same information is being used to dereference both the "bit pattern" table and the "brightness" table. Also, DOSBox's current implementation isn't quite right since some of the colour fringes are desaturated - look at the top tapper screenshot (the one from DOSBox) here and compare it to the more correct version below - look in particular at the middle of the "SODA" sign in the window, the right edge of the D and the left edge of the O, which is grey in DOSBox (missing its fringing entirely). Since DOSBox uses a (1, 1, 1, 1) kernel for its NTSC filter, there are only actually 16 possible colour combinations (though they are permutated depending on the colour carrier phase).

I realized that a similar technique might be possible for the 2bpp modes. Each output composite pixel depends on the colours of four consecutive pixels of hdot width. These pixels cover at most 3 consecutive ldots, so any given pixel position depends on at most 6 bits of video data. It also depends on 2 bits of x position, so we need 8 bits of palette entries, or 256 colours - just slightly too many. There's an easy way to reduce the amount of palette entries though - half of the output hdots depend on only 2 consecutive ldots (since the sampled hdots exactly cover 2 ldots). So even hdots have 16 possible colours and odd hdots have 64, for a total of 16+64+16+64 = 160 colours - plenty to spare. What's more, the "render" part of the new algorithm is even faster than it used to be (although the mode setting part is probably much slower - however it's run sufficiently rarely that there's no need to optimize it).

9 Responses to “Improved composite mode support for DOSBox”

  1. r.j. says:

    where is the patch?

    • Andrew says:

      Here: http://www.vogons.org/viewtopic.php?f=41&t=12319&start=320#p265379

      There are some tweaks and bug fixes later on in that thread, so that's not quite the final patch that got committed (look at the SVN history to find that).

      I have another CGA simulation algorithm in the works with even more accurate colours (determined from capturing calibration images) but it'll probably be a few more months before I get around to porting it to DOSBox.

      • Awesome stuff!

        I would love to see if this composite video simulation could be combined with non-DOS emulators, such as Genesis and SNES emulators, or even emulators for handheld devices that would have never been output to a composite display in the first place (for curiosity's sake if nothing else).

        Oh, if DOSBox does not already have CRT simulation (fake scanlines don't count), then be sure to look into this: http://ascii.textfiles.com/archives/378
        Completely transforms the experience, I say.

        • Andrew says:

          The version of the composite CGA patch described in this patch is a bit out of date now, as it didn't work for text modes. I've since made a patch which does, and which gives even more accurate colours as well. I think mainline DOSBox does not have CRT simulation yet, but there are some forks which do. I've also written my own CRT simulation code which I may put into a form which can be used by DOSBox at some point. Btw, the textfiles.com link in your comment is giving a 404 for me - could you double-check it?

          • Oh crap. Yeah, blame my phone for that one...
            http://ascii.textfiles.com/archives/3786
            "What a wonder is a terrible monitor"

            And I guess I should probably share this one as well:
            http://www.sega-16.com/forum/showthread.php?30787-Tweaked-Bilateral-Shader&highlight=modified+bilateral+shader

            Just out of curiosity, how well do composite artifact colors deal with interlaced output? Would a form of dithering be possible that way?

            • Andrew says:

              Yeah, those are some lovely pictures.

              Composite artifacting and interlacing are completely orthogonal - you can have either without the other or both together. I'm not sure if there were any micros or consoles which did both by default, though. It's actually been on my todo list for a while to try to coax the CGA into generating interlaced output. There is hardware on the CGA card that stops it from generating an interlaced image if you just do the obvious thing, but I think there is a tricky way to subvert it. Of course, then there is the problem that there is not enough VRAM for a 640x400x2 or a 320x400x4 image, but at least text modes should work. Dithering with interlacing is possible, but there is a danger of 30Hz flicker causing headaches - it's important to avoid having dark even fields and light odd fields or vice-versa. And of course this technique would break every emulator out there.

              • Khopa says:

                Yeah, I do suppose I have a rather unhealthy obsession for interlacing.

                Well, when you have an Artifact Color shader working, I would love to see it. I have plans to exploit NTSC Artifact Colors in Mega Drive-related development, since it also has a scan width of 320 pixels. Unfortunately, there aren't any tiles that could produce only a 90 degree hue shift on the color wheel, due to the lack of a 640-wide pixel mode on the Mega Drive's VDP, but 180 degrees is not a problem when up to 61 colors can fit within a single scanline, or 8 colors in a single tile (technically 16, but the tiles are only 8 pixels wide).

                A 256-pixel-wide mode is also present, so it would be interesting to see how much of a shift that would produce.

                • Andrew says:

                  My current NTSC decoder and CRT simulator (such as they are) can be found in CGAArt at http://www.reenigne.org/misc/cgaart.zip . No bloom or tube-geometry effects but it does have multiple scanline profiles and conservation of light energy (in linear colour space) so you can have beautiful scanlines without making the overall image darker (which as far as I know hasn't been done before). It's not a GPU shader at the moment, though, so it's a bit slow (although not as slow as it could be - it does take advantage of SSE2). I really need to take the time to figure out how to do this stuff on the GPU.

                  It looks like the (320-wide) pixel clock on the NTSC Megadrive is 7.670455MHz, which I'm guessing is 15/7 of the NTSC color carrier frequency (7 oscillator cycles per pixel, 15 oscillator cycles per color carrier cycle). That means that to get an artefact colour you'd need a pattern that repeats every 15 pixels and goes bright and dark 7 times over that period. You'd also need to check that the pixel clock is synchronized with the color burst, which might not be the case (though if both are generated from the same oscillator there should be some temporal sequence of patterns which should work). I suspect a 256-pixel-wide mode wouldn't work since the pixel clock would be less than the Nyquist frequency (twice the color carrier) needed to synthesize the carrier.

                  This kind of "non-integer" artefact colour can work reasonably well (I've done it on a VGA card with a pixel rate of 360/91 of the colour burst). It does make it more difficult to draw images programmatically though.

Leave a Reply