PCjs Machines

Home of the original IBM PC emulator for browsers.

Logo

PCjs Blog

Flicker Fakery

One of my long-standing pet peeves about PC emulators has been their obsession with raw speed, and how hard they try to squeeze every last drop of performance out of their instruction execution loop, on the assumption that everyone wants an 8088 that runs at, say, 500Mhz, as opposed to the stately 4.77Mhz of the original IBM PC.

And sure, it might be nice if that Lotus 1-2-3 spreadsheet recalculated instantly, instead of the several seconds that it originally took. But most of the time, such a dramatic difference in speed is more aggravating than helpful. In 1981, you could type DIR at a DOS prompt and skim the directory listing as it was being printed. Do the same thing in a modern emulator, and the directory listing will display so fast that you’ll have no idea what just scrolled off the top of the screen. And many games become unplayable, because they were designed to run on machines of the day, not machines of the future running hundreds of times faster.

Emulators like DOSBox, which has since been ported to EM-DOSBox for the Internet Archive’s MS-DOS Collection, do offer some crude controls to “throttle” the emulated CPU’s speed, but they provide no feedback: you don’t know what the current speed is or what the target speed should be. Even professional emulators like Oracle’s VirtualBox offer only very limited speed controls, such as a processor “Execution Cap”, which is defined as a percentage of the emulator’s maximum speed (whatever that may be), and which is too granular to recreate any specific CPU speed.

Visual Authenticity

Beyond speed accuracy, the next commonly short-changed feature is visual authenticity. Most emulators do a good job faithfully emulating video hardware features, sometimes even obscure features that were used by only a handful of apps. But many emulators don’t bother with:

And last, and maybe also least, FLICKERING.

Yes, the beloved flicker of the original IBM Color Graphics Adapter (CGA). And I’m not talking about the barely perceptible flicker produced by the CGA monitor’s 60Hz refresh rate. That flicker was tolerable. In fact, many people who didn’t need either color or graphics would opt for IBM’s Monochrome Display Adapter (MDA), because the green phosphor of IBM’s monochrome monitor had such high persistence that the 60Hz refresh rate was virtually imperceptible.

No, the capital-letter FLICKER that I’m talking about was a side-effect of what IBM’s ROM BIOS did every time the CGA’s screen had to be scrolled: completely turn off the video signal OFF, rearrange the contents of video memory, and then turn the video signal back ON. IBM adopted this approach because otherwise you would see an even worse effect: random video interference or “snow”.

This all came about because the CGA’s memory wasn’t “dual-ported”: if the CPU accessed the CGA’s memory at the same that the display hardware was accessing it (to refresh the screen 60 times per second), the CPU would win and the display hardware would lose, resulting in garbage appearing on the screen for a brief instant.

PC software could avoid that conflict by waiting until the CGA hardware was in a retrace period: either the brief horizontal retrace period that occurs as the CRT repositions the electron beam from the right side of the screen back to the left side, or the slightly longer vertical retrace period that involves moving the beam from the bottom to the top.

However, IBM decided that, since neither of those retrace periods were long enough to perform a full-screen scroll, the easiest solution was to simply turn the screen off for the duration. The result, which many of us suffered with for years, was FLICKER.

I can hear the counter-arguments, starting with “Why in the world would anyone want to recreate or experience such an annoying feature?” In part, it’s a quest for authenticity. It’s the difference between going to an art museum and seeing original paintings and sculptures, as opposed to just looking at photographs or reading descriptions on the internet. The photographs and descriptions can never faithfully reproduce the real objects, but the more accurate they are, the better.

It’s also important for understanding the world in which PC users and programmers operated in the early 1980’s, the challenges that programmers faced, and some of the interesting solutions they came up with.

One of those interesting solutions was a program from 1986 called FlickerFree, the purpose and value of which would be almost completely lost on someone today if they had never seen or used an original IBM PC with a CGA.

In fact, FlickerFree proved to be a useful PCjs test case, because it relied on a quirk of CGA hardware that I hadn’t originally implemented: frame buffer wrap-around. FlickerFree resolved the flickering-scroll problem by treating the CGA’s 16Kb of video memory as a giant ring buffer: instead of moving the contents of video memory “upward”, like IBM’s ROM BIOS did, FlickerFree would simply shift the video memory start address “downward”. After all, one 25x80 screen of character data required only 4000 bytes, and the CGA had 16,384 bytes of memory.

At first glance, that approach would seem to merely delay the inevitable, because when the start address nears the end of the buffer, the entire buffer still has to be scrolled. But, as it turned out, the CGA’s CRT controller starts reading from the top of video memory after it reaches the bottom. So all software has to do is write new lines at the top of the video memory again. If IBM had thought of that trick 5 years earlier, back in 1981, think of all the years of shared flicker-grief that could have been avoided!

Today, in honor of all that flickering, I’m pleased to announce that PCx86, one of the PCjs emulators I’m always trying to improve, now offers FLICKERING on all IBM PC Color Graphics configurations. If you feel the need to override it, you can add flicker=0 to the URL of your favorite machine; e.g.:

www.pcjs.org/software/pcx86/util/flickerfree/1.0/?flicker=0

In fact, you can set the flicker property to any value from 0 to 1; the default is 0.5. This value is applied to the opacity property of the PCx86 <canvas> element, allowing you to mimic whatever degree of “phosphorescent persistence” you prefer.

You can thank me later.

Jeff Parsons
Jul 15, 2017