I am trying to programatically detect the CGA card on old IBM 5150-ish PCs.

The Paku Paku game source code doesn't directly detect it. The strategy is to detect VGA, EGA, Tandy, PCJr, etc etc, then if none of those "hit", assume it is CGA. Similar code is found here: https://forum.vcfed.org/index.php?threads/is-there-a-way-to-detect-a-plantronics-colorplus-card-by-software.79115/ and here: https://www.brutman.com/forums/viewtopic.php?t=119

However I'm wondering if there is some way to directly detect the CGA card's presence?

I realize the IBM BIOS source code may have references to this but I'm not sure of exactly how it's doing it so I kind of gave up looking at that. I know that it's detecting between no video, MDA, and CGA, but I'm not sure if that is compatible with technology that did not exist when the BIOS was written. (Edit - please see Raffzahn's answer below, BIOS is not doing what i thought!!!)

The guide at http://www.tinyvga.com/6845 regarding the Motorola shows that most of the registers in the CGA's Motorola 6845 chip are write only, however the cursor addresses at registers 14 and 15 are both read/write.

I am wondering if I output data to register 14 at the 6845 I/O-portaddress, and read it back, using x86 OUT and IN instructions, would that be good evidence the machine had a CGA card?

What happens if you write to an I/O-port that doesn't exist in the hardware? Does it crash?

  • 2
    Other graphics card all emulated CGA to some degree. You'd have to find something that was NOT emulated by other graphic cards which is unique to CGA to make sure that it's a CGA and not some other card. And yes, you can check for the presence of 6845 registers to verify that the PC has a graphics card at all (but this is not a useful check, nobody was going to run a game on a PC without any graphics...)
    – dirkt
    Commented May 4, 2023 at 3:41
  • 2
    @Raffzahn There were plenty of applications which completely ignored the BIOS, so compatibility is handled on the hardware level. You can find this even on post-VGA cards, that all simulate earlier cards, complete with the slow access via IN/OUT (while also providing PCI memory mapped registers), and sprinkling the extension bits across various CRTC indices. However, you may be able to detect a CGA ROM, though I don't know how many versions the ROM went through.
    – dirkt
    Commented May 4, 2023 at 6:08
  • 2
    @dirkt What CGA ROM would you detect, and how?
    – Justme
    Commented May 4, 2023 at 6:22
  • 2
    @dirkt CGA (and MDA) does not have a ROM. Also the fact, that some later cards may be (in part) compatible doesn't change that. I just went thru the process of supporting the creation of a new compatible XT BIOS over the last year or so.
    – Raffzahn
    Commented May 4, 2023 at 6:52
  • 2
    @TimLocke It is. But it only ever contains stuff written there by CPU. In text mode it contains character codes and attributes. In graphics mode it contains pixels. So the pixels, if they represent pixels of font, is written by CPU via BIOS or user code. You can read the RAM, you can't access the text mode font ROM, because that's the hardware that converts character codes to pixels of a character.
    – Justme
    Commented May 4, 2023 at 20:43

4 Answers 4


You can, in fact, relatively reliably and safe, detect a 6845 in your system by trying to write to a 6845 register and see whether you can read back the same value. I have successfully done that with the "Cursor End" register - an action that is easily reversible and relatively non-destructive. Use the address register at 0x3D4 to write the register number, then the data register (one up) to write your value - wait a short time, then try to read back from the data register using the same method. If you can read the same value, you're relatively safe to assume you have a 6845 in the system. After that, restore the old "Cursor End" value you hopefully saved before.

(You can use the same method to detect MDA and Hercules cards at 0x3b4. It is, however, a bit more tricky to distinguish between these two)

Note, however, that for a dual-card setup (MDA+CGA), the pure existence of a 6845 at the CGA port address doesn't necessarily mean that this display adapter is in fact the active one currently - You'd still use the BIOS (or "DIP switch") settings to detect which one is the currently active adapter.

Also, you might want to do the VGA and EGA tests before (I use the video BIOS to do that), otherwise you might mis-treat one of those in CGA mode as a "real" CGA adapter.

  • 1
    Note that currently available adapter doesn't mean the other doesn't work. Long ago I wrote code that simultaneously used the CGA for text and the VGA(?) for graphics. Over time fewer cards would play nice with coexistence and it finally became necessary to simply copy out the initialization code and then do everything directly. Commented May 7, 2023 at 4:02
  • @LorenPechtel Of course. When the adapter is detectable, it will most probably work - But your program needs to have a strategy what it wants to do with more than one available character and cannot simply assume a monitor is connected and the whole chain is operable. I Have, however, yet to find a situation where there is MDA and CGA in a system and not interoperable.
    – tofro
    Commented May 7, 2023 at 7:04
  • In my case I was free to simply fail if the required hardware wasn't present--this was in-house software, the two-monitor mode used by roughly a dozen people. Commented May 8, 2023 at 2:42
  • Apparently this was hard back then too, so many games just asked what the user would like. Civilization 1: i.sstatic.net/liPOw.png Commented May 9, 2023 at 5:11
  • @ThorbjørnRavnAndersen It wasn't any harder back then than it is today, but sometimes people tend to be lazy. The example screen shows a selection between VGA, EGA and MCGA - These have always been easy to detect using the video BIOS, Tandies and PCjr a bit harder. The point is rather how software was delivered to the end customer: New "standards" were coming up any week, and it was a lot easier to have your phone support tell people to use this or that selection in a menu than to re-copy thousands of floppies with a new detection routine and distribute via mail.
    – tofro
    Commented May 9, 2023 at 7:59

The Paku Paku game source code doesn't directly detect it. The strategy is to detect VGA, EGA, Tandy, PCJr, etc etc, then if none of those "hit", assume it is CGA.

Does it, or would MDA also be supported?

In any case it's the way conforming to the PC's design.

I realize the IBM BIOS source code may have references to this but I'm not sure of exactly how it's doing it so I kind of gave up looking at that.

(Genuine) PC/XT BIOS does not do such at all. It's from the good old times of reliable configuration values stored in manual switches. All those complicated probings are later inventions. BIOS simply looks for all hardware configuration at the motherboard configuration switches, in this case Switch Block 1 (SW1).

While those no longer physically exist, all later PC compatible hardware emulates them from some BIOS setting.

I know that it's detecting between no video, MDA, and CGA, but I'm not sure if that is compatible with technology that did not exist when the BIOS was written.

In this case it's switch 5 & 6 of SW1 as MinusZeroDegree tells:

Video card type.
5=OFF, 6=OFF:    MDA (monochrome)
5=OFF, 6=ON :    CGA, at 40 column by 25 line mode
5=ON , 6=OFF:    CGA, at 80 column by 25 line mode
5=ON , 6=ON :    Cards with a BIOS expansion ROM (e.g.  EGA / VGA)

BIOS assumes that only that selected card is fitted and ignores everything else. Also ON/ON setting is not usable for PC's with BIOS prior to 10/27/82, as it was that version that first scanned for extension ROMs.

Basically the BIOS itself uses INT 10h (Video output) for all output but only installs INT 10h handlers for CGA or MDA. Everything else relies on BIOS expansion ROM being present and installing their own video output handlers.

Plug and Play as it was intended.

What happens if you write to an I/O-port that doesn't exist in the hardware? Does it crash?

Usually not (*1). A read will return random values, mostly defined by bus load/capacity. A write will simply do nothing - or a least it should :))


*1 - Some non-IBM PC hardware may execute a bus fault.

  • 1
    wow thats awesome, thank you for posting that. i had completely forgotten about dip switches on motherboards, probably been 20 years since i touched one.. .
    – don bright
    Commented May 5, 2023 at 2:00

If all the other adapters have already been detected to be absent from the system, the possible options are that there are no MDA or CGA adapter at all, there is either MDA or CGA adapter installed, or there are both MDA and CGA adapters are installed. In this case the BIOS simply uses which is selected by the user.

The CGA and MDA adapters live in different IO and memory addresses that don't overlap, so while they both can be present in the system, only one can be the default which the BIOS uses for output.

I recall that one BIOS seemed to blindly initialize both cards without checking their presence, and then used the one that's set to default. That's because it is preferable to initialize the video output properly, as if some user program has programmed the output incorrectly, pressing ctrl-alt-del does not cause a hardware reset to reset the MC6845 CRTC to stop video output.

The idea of using the cursor address register of MC6845 should be a valid option to probe the presence of a CGA adapter, from the CGA port address 3D4h/3D5h.

Another way is to poll the CGA status register 3DAh for proper looking signals. The bit 0 contains an active low Display Enable signal, and bit 3 has the Vertical Sync. Bit 2 should be high on an original CGA adapter when light pen trigger is not pushed. Bit 1 being high means light pen event has been triggered and if it is set, the bit can be cleared by writing to port 3DBh. The VSYNC should go high briefly at 59.9 Hz rate, and the DE should go low during each of the 200 active lines per frame at rate of 15.7 kHz and be high otherwise between lines and frames.

  • 1
    Disabling interrupts and measuring horizontal and vertical sync rates would make it possible to distinguish a variety of CGA clones, especially if one were to modify the values of some CRTC registers and observe the effects thereof.
    – supercat
    Commented May 4, 2023 at 14:52
  • 1
    @supercat On a classic PC, you have a minimum granularity of 18.2ms to measure time - That's by far not enough to measure sync times. You could base your measurement on the CPU clock, but then, well, it's based on the CPU clock. YOu could re-program the PIT, but then again, that would only work on relatively compatible machines. All in all, way too much hassle.
    – tofro
    Commented May 8, 2023 at 7:58
  • 1
    @tofro On a classic PC the PIT is just programmed to slowest possible divisor of 65536 (0) to get interrupts at 18.2 Hz rate. The PIT still runs at count rate of 1193181.8 MHz and it can be reprogrammed with any divisor you like, or the counter register can be read for timestamps at the count rate.
    – Justme
    Commented May 8, 2023 at 8:57
  • 1
    @tofro: Even without reprogramming the PIT, waiting for a PIT count, and then counting the number of horizontal blanks until the next sync along with the minimum and maximum numbers of horizontal blanks within vertical high and low intervals should make it possible to distinguish among the common video sync rates even if there might be a few missed horizontal blanks.
    – supercat
    Commented May 8, 2023 at 14:50

To answer the specific question:

What happens if you write to an I/O-port that doesn't exist in the hardware? Does it crash?

That doesn't happen with any Intel or Zilog microprocessor I'm aware of. When you write to a port, the address, data and control lines are set appropriately and it's up to the hardware to notice that its address is selected and route the data into the peripheral. If we write to a port where no hardware is listening, then the data bus is not routed anywhere, and the write has no effect.

A similar principle applies to memory operations - a write to an address not backed by real memory will have no effect, and a read will give the result of interpreting an unasserted data bus (often all ones or all zeros, but possibly just random data, depending on the logic family).

On the other hand, writing to a port that does have corresponding hardware, but isn't the hardware you expected, may have almost any outcome, up to and including physical damage. So be careful!

  • 2
    You only need to consider the Motorola M68000 CPU for that. It has a DTACK pin which is required to terminate a bus cycle. If there is no memory or device to acknowledge the bus cycle, it will wait forever. Although your motherboard could have a system to terminate the cycle with an error if it does not happen within a sensible time. Also on certain SoundBlaster cards that don't have sockets for the CMS/GameBlaster chips but they are not present, writing to the chips will cause logic on the sound card to add wait states until the chip signals it's ready, and that never happens.
    – Justme
    Commented May 10, 2023 at 12:51
  • 1
    Thanks @Justme. I've only done software on a M86k, so I've edited to reflect the limits of my knowledge. Commented May 10, 2023 at 13:12

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .