|Dͻ
|D |5The Happy Hacker |D
|Dͼ

^C^1A Video Primer -- Part 5
^Cby Joel Ellis Rea

   Once upon a time, a company named Motorola built a remarkable chip.  This 
chip provided most of the circuitry needed to make the video portion of a 
terminal.  As input, it needed an area in memory to hold a video image, and as 
output it produced a video signal and two SYNC signals (one each for horizontal 
and vertical SYNC).  This chip was used in many terminals of the day, and still 
is.  It became the basis of most 80-column video expander boards for the old 
Apple ][ and Apple ][ plus computers.  It is still alive and well as the "heart"
of both the IBM Monochrome Display Adapter (MDA) and the IBM Color Graphics Ad-
apter (CGA), as well as most boards that are completely compatible with either, 
such as the Hercules Monochrome Graphics Board and the Plantronics ColorPLUS 
board.  It is NOT used in the Enhanced Graphics Adapter, but many of its func-
tions are simulated.  This chip is called the Motorola 6845 Cathode Ray Tube 
Controller (CRTC) chip.  We will refer to it simply as the CRTC for the remain-
der of this article. 

   From past issues, you may recall that all IBM Video Boards (to date, anyway) 
scan from the upper left corner of the screen, straight across a "scan line", 
then come back and just a little bit lower, then repeat this process until 
reaching the bottom right corner of the screen, at which point the beam goes 
back up to the top left corner to start another screen scan.  This is called 
"Raster Scanning", and is what the CRTC was designed to control.  You may also 
recall that the MDA and CGA standards have different numbers of scan lines per 
character line as well as for the entire screen, different horizontal and verti-
cal scanning frequencies, etc.  The same CRTC handles them both, as well as 
many of the 400-scan-line cards, etc.  This should give you some idea of just 
how flexible this chip is. 

   If the beam remained "on" during the complete scanning process, you would be 
able to see the "retraces" from the end of each line to the beginning of the 
next, as well as from the bottom right corner of the screen to the upper left 
corner.  This would be distracting, to say the least.  So the beam is shut off, 
or "blanked", during those retrace times.  At the end of each scan line, the 
Horizontal SYNC signal becomes active to signal the monitor to blank the beam 
and move it to the beginning of the next line.  It remains active long enough 
for this to be completed.  At the end of a screen frame, the Vertical SYNC sig-
nal becomes active to signal the monitor to blank the beam and retrace it back 
to the upper left corner of the screen.  It remains active long enough for this 
process to be completed -- several times longer than the Horizontal Sync, of 
course. 

   So, among other things, the CRTC controls the position and width of the Hori-
zontal SYNC active portion within each scan line, and the position of the Verti-
cal SYNC within each frame scanned.  It also controls how many characters to
show on each line, how many character rows to display, and how many scan lines 
per character row.  The CRTC also generates the Hardware Cursor, and can control
on what scan lines it starts and ends, relative to the start of the character 
row it is on.  It also keeps track of where the cursor is.  In addition, it 
controls where (according to its own memory map) the video image it is display-
ing exists in memory.  Since it knows where the beam is at all times, it can
"listen" to a Light Pen signal, and translate its pulse into the coordinates of
the screen it is pointing to, based on when it "sees" the pulse. 

   All this is handled by 18 8-bit (1-byte) registers.  The first 14 registers 
are Write-Only, which means data can be written to them to tell the CRTC the 
basic parameters of the desired display.  The next two, which hold the position 
of the cursor, are Read/Write, which means that they can be either written to 
(to move the cursor) or read from (to see where the cursor currently is).  The 
final two are Read-Only, and can only be read (to see where a Light Pen, if any,
is pointing). 

   Register 0 (^1R0^0) is called the "Horizontal Total" register.  It holds the num-
ber of characters there would be on each character row, if the row went all the 
way across the screen, and there were no Horizontal Sync.  In other words, it 
defines the physical width of the screen.  ^1R1^0, called "Horizontal Displayed", 
holds the actual number of characters displayed per character row.  On both the 
MDA and on the CGA in 80-column mode, it holds the value 80.  On the CGA in 
40-column or in graphics modes, it holds the value 40.  ^1R2^0 ("Horizontal SYNC 
Position"), tells where on the physical line the Horizontal SYNC signal begins 
to become active, and ^1R3^0 ("Horizontal SYNC Width") tells how long it remains 
active.

   ^1R4^0 ("Vertical Total") holds the total number of character rows there would be
if all possible rows were used, from top to bottom, including the Vertical SYNC 
period.  ^1R5^0 ("Vertical Total Adjust") holds a number from 0 to 15 which is the 
number of additional scan lines to add to the total from the character rows in 
R4 to bring it to the real total, since it is not always a whole number of char-
acter rows.  ^1R6^0 ("Vertical Displayed") is the number of character rows that are 
actually used, or displayed.  This is equal to 25 in the MDA and in both text 
modes of the CGA.  It is equal to 100 in the CGA graphics mode, for reasons I 
will explain at a later time.  ^1R7^0 is "Vertical SYNC Position", and it holds the 
character row on which the Vertical SYNC begins.  There is no "Vertical SYNC 
Width" register. 

   ^1R8^0 ("Interlace Mode") is a special register.  Only the lowest two bits mean 
anything.  The lowest, with a value of 1 (if set), is the "Interlace SYNC" 
bit.  The second lowest, with a value of 2 (if set), is the "Interlace Video" 
bit.  It only takes effect if the "Interlace SYNC" bit is set, so the only 
meaningful values for R8 are 0 (no Interlace -- normal mode), 1 (Interlace SYNC)
and "3" (Interlace Video and SYNC).  Interlacing means to cause every other 
video field (a single vertical scan from top to bottom) to be shifted down one-
half scan line, so that the scan lines of one field fit "between" the scan 
lines of the immediately preceeding field.  These two fields form one "frame", 
a completely-scanned image.  Without Interlace, "field" and "frame" are 
synonymous for all practical purposes.  Anyway, the result of turning on 
Interlace SYNC is to double each scan line.  Since this happens every OTHER 
field, there is a slight flicker involved.  It is less apparent on the 
Monochrome Display because of its long-persistant green phosphors.  Adding 
"Interlace Video" to "Interlace SYNC" causes the "inserted" scan lines to hold 
new data, rather than duplicates of the same scan lines from the previous 
frame.  Were there enough memory on the MDA, and were the boards designed a 
little differently, you could use this feature to get 50 lines of text on your 
screen.  It would be nice on monitors with long persistance, like the 
Monochrome Display. 

   ^1R9^0 ("Maximum Scan Line Address") tells how many scan lines there are in each 
character row -- i.e. how "tall" the character rows are.  Actually, the number 
in R9 is the number of scan lines MINUS ONE.  In other words, R9 counts 
starting at 0 rather than at 1.  It holds 7 for the CGA in text modes, 1 
for CGA in graphics modes, and 13 for the MDA.  That means that each character 
row is 8 scan lines tall for CGA text, 2 for CGA graphics, and 14 for MDA text.
This register can hold a number from 0 to 15, meaning the CRTC could handle 
characters up to 16 scan lines tall.  Note that the value here, plus one, times 
the value in R6 ("Vertical Displayed"), equals the total displayed scan lines.  
For the CGA, it is either "(7+1) * 25 = 200" (text) or "(1+1) * 100 = 200" 
(graphics).  For the MDA, it is "(13+1) * 25 = 350".  Thus, the CGA has 200 
scan lines in all modes, and the MDA has 350. 

   ^1R10^0 ("Cursor Start") and ^1R11^0 ("Cursor End") define the height and position 
of the cursor, relative to the total character height given in R9.  Both range 
from 0 to 15 and both start counting at 0.  The CGA sets R10 to 6 and R11 to 
7, making the cursor occupy the bottom two lines of each character.  The MDA 
sets R10 to 11 and R11 to 12, just below the descenders of the characters, 
but just above the bottom physical scan lines of the character rows.  In both 
cases, the default cursor is two scan lines tall.  By setting R10 to 0, you 
can make the cursor a full block, by having it start at the top of the character
row.  By setting R10 to 15, you can make the cursor disappear, by making it 
start below the visible character row.  If you wish to make the cursor disap-
pear, it is better to use the BIOS to do so than to "tweak" R10 directly. 

   ^1R12^0 ("Start Address High") and ^1R13^0 ("Start Address Low") point to the memory 
location containing the first character to be displayed.  Together, they can 
hold a number from 0 to 65,535 (64K), so the CRTC can access up to 64K of memory
for its video images.  On both the MDA and the CGA, these usually are set to 0.
On the CGA they can be set to multiples of 2,000 for 40-column text screens or 
multiples of 4,000 for 80-column text screens, to implement displaying any one 
of up to 4 (80 column) or 8 (40-column) text screen buffers.  Actually, you can 
set them to any value, but it should be low enough so that there is enough 
memory after the specified Start Address to hold an entire screen.  The CGA has 
16,384 bytes (16K), so reasonable values range up to 14,336 (14K) for 40-column 
text screens, or 12,248 (12K) for 80-column text screens.  By advancing the 
Start Address by the total number of bytes required for a line on the CGA, you 
can use the physical screen as a 25-row window into a screen 4 or 8 times as 
large (100 or 200 row for 80 and 40 column text screens, respectively), and 
scroll quickly within this large "virtual screen" without having to actually do 
the time-consuming block moves normally associated with scrolling.
   
   ^1R14^0 ("Cursor Address High") and ^1R15^0 ("Cursor Address Low") point to the mem-
ory location containing the character cell where the cursor is currently dis-
played.  The cursor can be pointing to an area outside the displayed screen, in 
which case the cursor is "off the screen".  These two are the only registers in 
the CRTC that can be both written to or read from -- i.e., they are the only 
two Read/Write registers.  Writing to them moves the cursor to the location 
written.  Reading them shows where in memory the character "under" the cursor 
is. 
   
   ^1R16^0 ("Light Pen High") and ^1R17^0 ("Light Pen Low") point to the memory 
location where the Light Pen, if attached and actually pointing to the screen, 
is currently pointing.  Since the Light Pen can detect the beam as it actually 
passes under it (as a sudden increase in the brightness of the phosphors under 
it), it can send a pulse each screen field.  By timing just when that pulse 
appears during the field, the CRTC can determine where the Pen was pointing.  
It automatically uses the other registers (Start Address, Vertical Displayed, 
Horizontal Displayed and Maximum Scan Line Address) to determine where IN 
MEMORY the character "under" the Light Pen is.  This address is held in these 
Light Pen registers.  Since only the operator can move the Light Pen, it 
makes no sense to try to WRITE to these registers, thus they are the only Read 
Only registers on the CRTC.  Because the long-persistance phosphors of the IBM 
Monochrome Display stay bright too long for the Light Pen to be able to easily 
and accurately sense the beam, the Light Pen is usually implemented only with 
the CGA. 
   
   That covers all 18 registers of the CRTC.  But how does the computer get to 
them?  That depends on the installation.  Both the MDA and the CGA allocate two 
CPU ports to the CRTC.  On the MDA, they are at port locations 03B4h (hexadeci-
mal) and 03B5h.  On the CGA, they are ports 03D4h and 03D5h.  CPU port 03x4h 
(where "x" is "B" for the MDA or "D" for the CGA) holds which CRTC register is 
present at port 03x5h.  So, to turn on Interlace SYNC, you would place a "1" in 
CRTC Register R8.  To do THAT, you would do an OUT of the value "8" to CPU port 
03x4h to make R8 available at 03x5h.  Then, since R8 is Write Only (and you want
to write to it anyway), you would then do an OUT of the value "1" to CPU port 
03x5h.  On the MDA in BASIC, this would be: 
^1   OUT &h03B4, 8:  OUT &h03B5, 1:  REM Turn on Interlace SYNC. 
   
In Turbo Pascal (also using the MDA), this would be:
^1   Port [$03B4] := 8;  Port [$03B5] := 1;  { Turn on Interlace SYNC } 
   
or, for more readable code, you could use this Turbo Pascal sequence: 
^1   CONST
^1     MDA_CRTC_register   := $03B4; 
^1     MDA_CRTC_data       := $03B5; 
^1     CRTC_Interlace      := 8; 
^1     CRTC_Interlace_SYNC := 1; 
        . 
        .
        . 
^1   BEGIN
        .
        .
        .
^1     Port [MDA_CRTC_Register] := CRTC_Interlace; 
^1     Port [MDA_CRTC_Data    ] := CRTC_Interlace_SYNC; 
   
   Next lesson will discuss more of the specific registers implemented in the 
non-CRTC hardware on the MDA and CGA.  The $03x4 and $03x5 registers which ac- 
cess the CRTC register index and data respectively are examples of these, but 
there are more.  We will show how to use them in combination with the CRTC to 
provide a 160x100 lo-res graphics mode on the CGA, with each pixel able to be 
any of the 16 colors, plus a border (like on the text screens) which can also 
be any of the 16 colors.
