^C|0
^C|0|E~0Bits 'N PC's ^0|0
^C|0|F~0      by     ^0|0 
^C|0|F~0Daniel Tobias^0|0
^C|0 

^C|5
^C|5~3|0VIDEOSYNCRACIES^0|5
^C|5

   If you've been following Joel Ellis Rea's Video Tutorial series in ~3|9Big Blue
~3|9Disk^0, you know that there are many different kinds of video adapters for the 
IBM PC, many of which are not very compatible with one another.  This has many 
ramifications which programmers must consider when designing programs to look 
good on a variety of monitors. 

   For instance, any text that is blue on a Color Graphics Adapter (CGA) will 
come out underlined on a Monochrome Display Adapter (MDA).  Text that is black 
on white on a CGA will come out this way (inverse video) on a MDA, but all 
other combinations (including those with a white background and some color 
other than black as foreground) will appear as normal white (or green or 
amber, depending on your monitor) text on a black background.  (The exception 
is black text on black background, which is invisible on either adapter.) 
 
   All of this (which is explained in the BASIC manual under the COLOR 
command) can make it extremely difficult to set up screens in your programs.  
Add to this the fact that CGA cards support a 40-column text mode but the MDA 
does not; the Extended Graphics Adapter (EGA) supports most but not all of the 
CGA features; and, of course, the fact that MDA cards cannot display graphics 
at all, and you reach a situation which can give programmers headaches.

   However, there are ways of getting a handle on all this.  There are some 
ways in which programs can determine what sort of graphic adapter the user has, 
so you can set screen colors differently, suppress graphics images for non-CGA 
users, handle things differently for EGA users, etc.  Here are some of these 
ways. 

   To determine whether a user has color graphics capabilities, do a PEEK at
the mode flag location at segment 0, byte $0410 (hex).  "AND" this byte with 
hex byte $30 to extract the particular bits you want. 

   In BASIC, do this with ^1DEF SEG 0: S = PEEK(&H0410) AND &H30^0; in Turbo 
Pascal, use ^1s := mem[$0000:$0410] AND $30^0. 

   If the resulting number is $30, then the user has a MDA or compatible card 
(including Hercules cards, whose graphics are incompatible with CGA graphics).  
Otherwise, the user can be assumed to have some form of color graphics.  The 
other possible values are $10 for most CGA cards when they are in 80-column 
mode; $20 for a CGA card (or PCjr) in 40-column mode; and $00 on some peculiar
non-standard cards, including some EGA-compatibles, and others too strange to 
mention.

   This takes care of the Monochrome vs. Color Graphics distinction.  However, 
there are also several varieties of color graphics boards which are not 
distinguished by this flag; one of these is the EGA.  EGA cards support some 
additional graphics modes not present in a CGA, but do not correctly support 
some of the special PORTs and calls of the CGA.  For instance, the routine in 
our operating system that bounces the screen when you hit the top or bottom of 
a file does not work on an EGA.  Hence, it is useful for programs to determine 
if the user has an EGA, and take appropriate actions as a result. 

   This is more complicated, since it is necessary to do an interrupt call to 
the PC's BIOS.  This is a relatively advanced feature, not recommended for 
novices.  You can do lots of useful things through these calls, but you can 
also screw up your system if you don't know what you're doing.  (It is actually 
possible to destroy the video adapter board and/or monitor by causing the PC to 
send inappropriate output to it, so be extremely sure you know what you're 
doing before you experiment with PORTs, CALLs and interrupts regarding video 
display.  Don't say we didn't warn you!) 

  The example below is in Turbo Pascal, which supports interrupts through a 
built-in function.  (It is much more difficult to do the same thing in BASIC.)

  First, set up a record containing the registers to be passed on the 
interrupt call.  Use these declarations: 

^1type iAPX = RECORD
^1                  CASE Byte OF
^1                    1:  (ax, bx, cx, dx, bp, si, di, ds, es, flags: integer);
^1                    2:  (al, ah, bl, bh, ch, dl, dh: byte)
^1                  END;
^1
^1var registers: iAPX;
^1    EGA: boolean;

Now, do the following, in order to select function $12 of interrupt $10:

^1with registers do
^1     begin
^1          ah := $12;   { Select function $12 }
^1          bl := $10;   { Select sub-function $10 }
^1          intr($10, registers);   { Call interrupt $10 }
^1          if (flags and 1) = 1 then EGA := true  { Check flag }
^1             else EGA := false
^1     end;

   If the value of the "flags" entry has its least-significant bit set, then 
the user has an EGA; otherwise, a different adapter (such as the CGA) is being 
used. 

   Finally, the PCjr video output is generally compatible with a CGA.  However, 
there are certain PORTs which cause color effects on a CGA, which are not 
supported by the PCjr.  If you don't know what PORTs are, then you probably 
don't use them, and thus needn't worry; normal high-level-language commands 
will work identically on a CGA and a PCjr.  But, if you use features that are 
not compatible, then there is a simple PEEK to determine whether a user has a 
PCjr or not. 

   Look at segment $FFFF, location $E.  If it contains the value $FD then the 
computer is a PCjr; any other value indicates some other kind of machine. 

  In BASIC, you do it with ^1DEF SEG &HFFFF: IF PEEK(&HE) = &HFD THEN^0 do 
whatever is appropriate for a PCjr.  In Turbo Pascal use ^1if mem[$FFFF:$E] = $FD^0.

  The above tricks should let you distinguish between most of the varieties of 
display adapters that are out there.  There are a few exceptions, though.  For 
instance, the AT&T monochrome card is actually CGA-compatible.  It shades the 
colors to separate them and produces output in which blue-on-white or red-on-
black text (unfortunately, two of the best and most commonly-used combinations)
are totally unreadable (the letters are completely invisible).  We have not yet
discovered a way of testing for such a system configuration, so just try to 
avoid these color combinations altogether. 
