HGC cards on IBM PCs used to be able to run CGA software by using a CGA emulator. How exactly did those programs work? What were the limitations?


How exactly did those programs work?

They were based on the ability of the Hercules card use the CGA's memory space.

The original MDPA (*1) had (only) 4 KiB of memory mapped at B0000h, while the CGA had 16 KiB of Memory at B8000h. The Hercules card in contrast had 64 KiB of memory (*2), starting at B0000h. To avoid conflicts with a CGA in the same system the upper 32 KiB were by default disabled. By default the Hercules was 100% compatible. In fact, so compatible that the PCs BIOS did recognize and use it as MDA (with 4 KiB Memory). Unlike the MDA, the Hercules card did offer a full graphics mode of 720x348 (*3,4), which occupied 32 KiB Memory, thus offering up to two pages.

CGA emulations used the fact that the second 32 KiB were not only free (when only the first graphics page was used) but also that memory could be located where the CGA's 16 KiB are, at B8000h..BBFFFh. Programs assuming a CGA (and direct screen access) would go ahead and paint their output into this memory instead. A timer controlled interrupt would now read the virtual CGA buffer at B8000h and transform its content into the real Hercules buffer at B0000h. On fast machines that could happen for every frame.

This was also supported by the fact that while many programs did direct screen updates, configuration was mostly done via BIOS calls, which could also be intercepted by the emulation and handled accordingly. For games with direct control of the CGA's registers, patches were sometimes available.

In fact, some games even skipped programming a Hercules mode by using a built-in (third party) CGA emulation. Accolade's well known Test Drive for example.

What were the limitations?

Most are related to the fact that the conversion of colour and resolution was done in software. To make it happen, the emulator had to steal the cycles to do so from the game. While not an issue with later PCs, it was a deal breaker early on.

  • Most notable Speed - Games got slowed down. While not much of an issue for round based or adventure games, it was real hurdle for real time/action games.

  • As well as Lag - One way to reduce the impact on the game performance was to skip frames. Doing the conversion only every second, third or fourth frame, reducing the effective frame rate. Again sometimes to an unplayable low when it came to (re)action games.

  • Weird Screen Format - Again due to the complexity of conversion, some emulators offered modes where less complex calculations were used by restricting the display area and colour resolution. As a result, only a part of the screen was used (or parts of the picture cropped) and colour information was dropped.

The other big drawbacks were ugly pictures due to the fact that converting a colour picture to monochrome always loses information. Unlike on a TV, there was no grayscale. Depending on the software this was compensated by replacing the colours by fixed patterns. This worked fine on pictures with sharp contrasts (i.e. always black lines in between) but usually only gave a rough impression of different coloured areas. With graphics based on colours (like with 160x200 mode) and fine details the result was awful. Keep in mind, these were just replacement patterns and nothing like real dithering.

And last, programs that manipulated the CGA's (6845) registers directly did not work at all. There weren't many and some emulators even had patches for common ones, still another hurdle to take.

*1 - Monochrome Display and Printer Adapter as the original IBM MDPA also offered a parallel interface. Obviously IBM assumed that an office user would need a printer interface anyway, thus creating the eventual first Multi-Function-Card :))

*2 - The large memory was meant to support loadable character sets and full graphics, as its developer wanted to use Thai characters.

*3 - Descriptions often mention 350 lines, but the last two weren't visible.

*4 - 720x350 at 50 Hz is, BTW, what can be done with a standard CRT when tweaking within the (European) boundaries.

  • Did Test Drive use the second-page trick on the Hercules to avoid having to copy data around? (Admittedly, it could change its base framebuffer address to 0xB000...) – Stephen Kitt Jul 6 '18 at 13:45
  • Don't ask me anymore. It's been ages ago. In fact I wonder I even remember it did. I think I was researching their handleing of vectors. – Raffzahn Jul 6 '18 at 13:52
  • 1
    “720x350 at 50 Hz is, BTW, PAL resolution.” — No, it isn't. First, vertical resolution of PAL is 576 lines (interlaced). That's way more than 350. Second, PAL has no pixels; the horizontal resolution is determined by the input signal and the frequency the display can handle. The 720 pixels were standardized much later in the DV format, which as digital format had to decide on a pixel size. – celtschk Jul 6 '18 at 21:43
  • Well, @celtschk, if your nitpicking you should be correct. official digital resolution for European TV (vulgo PAL) is 702x574. But that's, as you said, a later definition. Analogue picture is defined as up to 390 lines - thats vertical seperable lines within a scan line. Digital that would equal 780 pixel. 720 therefore can easy be displayed without any change of CRT or electronics. Similar it's 625 lines per picture or 312 per half. 350 scan lines per full is as well within the analogue capabilities. That's why 720x350@50Hz has been choosen for Hercules. – Raffzahn Jul 6 '18 at 22:10
  • @celtschk, note that PAL visible resolution of 576 scanlines is at the 25 Hz frame rate. But Hercules has a 50 Hz refresh rate, so it would be more accurate to compare to the PAL field rate of 50 Hz with 288 visible scanlines out of 312. So it is Hercules with the higher vertical resolution, not PAL. I'm not aware of converting Hercules (or CGA) output to PAL/NTSC for display on a TV being a normal thing. I suspect Raffzhan means a PAL TV tube had the specs to be made into a computer display, not an actual PAL TV could be used. – TrentP Jul 7 '18 at 22:56

The basic idea is to exploit the fact that both CGA and Hercules use the 6845.

I have the source code of an emulator at hand, so I can say what it does:

  • it handles the mode-setting function of interrupt 0x10; for all non-Hercules modes, it includes tables of register settings to use to program the Hercules for the appropriate resolution and framebuffer layout;
  • it piggy-backs on the timer interrupt to copy the framebuffers when an emulated mode is active (from 0xB800, which is where programs would write when using CGA, to 0xB000, the monochrome buffer).

There are quite a number of different emulators with different levels of success with various programs, so there are no doubt different ways of implementing the emulation.

The limitations are mostly related to hardware handling. Any program writing to the CGA registers won’t work, and any program relying on the Hercules vertical blank interval won’t behave quite right (CGA refreshes at 60Hz, Hercules at 50Hz). The status registers are different too, so polling CGA-style won’t work on Hercules at all. As mentioned by tofro, copying the framebuffers took a noticeable amount of time too (especially on CGA/Hercules-era systems), which would affect the system’s performance.

  • Great explanation, I guess I should more often wait for you to save me work :)) – Raffzahn Jul 6 '18 at 12:20
  • 1
    Obviously, moving the framebuffer contents around is not exactly speeding up screen output, especially in graphics modes ... – tofro Jul 6 '18 at 12:20
  • If I correctly remember how the Hercules works, I would think that it should be possible to program the Hercules graphics card to use a "character row" height of 3 rather than 4, and output 80 bytes per line rather than 90. If one did that, set the screen base address to 0xB8000, and erased memory from 0xBC000 to 0xBDFFF, that would yield a 640x300 display mode in which the first two lines of each triplet would match a pair of lines from CGA. The biggest thing I'm unsure about is whether stuff would show up in the right order. – supercat Jul 7 '18 at 17:41
  • 1
    @supercat I wrote a CGA emulator for Hercules at the time, and I used something like this (my memory is hazy) - plus a special TSR that copied the third line, so you could have either (fast) mode where every 3rd line was blank, or a (slower) mode where the 3rd line has been copied from the 2nd one, but this lead to some graphical tearing in moving objects. Still, I was using the TSR even for fast paced games. – Radovan Garabík Jul 9 '18 at 11:32
  • @RadovanGarabík: I wonder how much it would have cost to change the hardware so that the third scan line in each group could use the same address as the second? I think it could be done with three NAND gates and an mode-select bit, or perhaps with even less hardware. – supercat Jul 9 '18 at 17:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.