
                  SIXTEEN COLOR DOT GRAPHICS FOR THE PC

    The  PC junior is the only member of the IBM PC family  that  can 
    produce  the 16 color all points addressable 320 by 200  graphics 
    without  the  recently  announced but  scarce  enhanced  graphics 
    boards.   It seems at best that the PC will produce only a choice 
    of two sets of 4 colors in an all points addressable mode.  I was 
    working on a program that required graphics and wanted it to work 
    on  all IBM PC machines and found a compromise that I would  like 
    to share with you in this short note. 

    I  found  that the Junior has a mode that displays all 16  colors 
    in  160  by 200 resolution.  It requires 16000 bytes  of  display 
    memory  since each byte contains two 4 bit nibbles of color  data 
    to  display two such elongated dots.   In order to make  anything 
    look  well  with  that mode however,  the dots must  actually  be 
    displayed  two at a time  to produce square pixels thus  reducing 
    to  a  160  by 100 display mode of  16  colors.   With  a  little 
    experimenting  I was able to do this on the PC as well and in  so 
    doing,  utilized the same code on both without using the ROM BIOS 
    support provided on the Junior.

    It  seems  that  the only way to get 16  colors  with  the  color 
    display adapter is to be in one of the color text modes.  This is 
    the  only clue you need to proceed.   Notice that there are  some 
    special  non ASCII characters displayed with codes from 80 to  FF 
    hex.   One  of  those  codes is DE hex or 222  decimal  and  will 
    display  an  80 column character with the left half that  of  the 
    foreground  color  and  the  right  half  the  background  color.  
    Fortunately both colors are defined in the attribute byte so that 
    the  left and right halves can be  controlled  separately.   This 
    produces  a  160  by 25 display that is dot addressable  with  16 
    colors.   Notice  that we have used two bytes for  each  adjacent 
    pair so that only one fourth of the display memory is used.

    Now for the tricky part.  By getting into debug and experimenting 
    with  the 6845 video controller registers I was able to get  some 
    rather interesting effects.   I have been told that you can cause 
    damage to the video system by doing the wrong thing here so I was 
    cautious.   What I wanted was a squish in the vertical  direction 
    by a factor of four.  Therefore, after setting up for the 80 X 25 
    color graphics text mode,  I knew that something might be done to 
    the  6845 registers that controlled the vertical  characteristics 
    of  the  display  if it were to be possible at  all.   These  are 
    R4,R5,R6, and R7.  Then too there is R9 which has something to do 
    with the scan line count per character.  In the 80 character mode 
    register  4  contains 31 meaning that there is provision  for  31 
    rows  not the 25 that we might expect.   This means  simply  that 
    there  are  6  rows  to provide for the  vertical  retrace  time.  
    Register  6 contains the expected 25 and register 7  contains  28 
    which  is the vertical sync position.   This set up allows for  3 
    undisplayed rows,  25 display rows and finally 3 undisplayed rows 
    at  the bottom.   Meanwhile register 9 contains 7 which  actually 
    allocates  scans  zero to 7 for a total of 8 scan lines per  row.  
    The  total count on the scan lines is 248 with only 200  of  them 
    actually displayed.




                                    1






    Thus assign 124 to register 4, 100 to register 6, 112 to register 
    7,  and 1 to register 9.   There will be 124 rows with 12 at  the 
    top  and bottom.   Each row has two scan lines for a total of 248 
    scan  lines with only 200 of them actually displayed.   While  in 
    debug I tried this and found that all of my 80 column text showed 
    only  the top two scan lines but that I could display about  four 
    times as many of them.   So that is the  solution.   Actually,  I 
    coded  it in assembly language but to communicate  here,  I  will 
    include a short segment of basic which does the same thing.   The 
    assembly  language program is much much faster than this routine.  

    10 WIDTH "SCRN:" 80                 ' 80 COLUMN MODE
    20 SCREEN 0,1,0,0                   ' COLOR MODE
    30 OUT &H3D8,9                      ' DISABLES BLINK BIT
    40 DEF SEG = &HB800                 ' COLOR DISPLAY AREA
    50 FOR I = 0 TO 80*100*2 STEP 2     ' FILL "SCREEN"
    60 POKE I,222                       ' HALF AND HALF CHAR
    70 POKE I + 1,0                     ' BLACK ON BLACK
    80 NEXT I
    90 OUT &H3D4,4                      ' R4  SELECTED
    100 OUT &H3D5,124                   ' R4  VERTICAL TOTAL
    110 OUT &H3D4,6                     ' R6  SELECTED
    120 OUT &H3D5,100                   ' R6  VERTICAL DISPLAYED
    130 OUT &H3D4,7                     ' R7  SELECTED
    140 OUT &H3D5,112                   ' R7  VERTICAL SYNC
    150 OUT &H3D4,9                     ' R9  SELECTED
    160 OUT &H3D5,1                     ' R9  SCAN LINES (2)


    Statement  number 40 is necessary to disable the blink else color 
    codes larger than 7 produce a blinking display.  Now you have all 
    of  the screen filled with black foreground and black  background 
    "dots".   To  draw  a line of yellow dots in  column  25  without 
    changing the other dot color in column 24, write:

    1000 FOR I = 0 TO 100
    1010 A = I * 160 + (25\2) * 2 + 1    ' LOCATION OF ATTRIBUTE
    1020 N = PEEK(A)                     ' GET ATTRIBUTE BYTE
    1030 POKE A,(N AND &HF0) OR &H0E     ' CHANGE DOT TO YELLOW
    1040 NEXT I

    When  you  exit  this program you will not be able  to  read  the 
    display  messages because of being in this strange graphics mode.  
    Just set the width to 40 to see what you are doing.















                                2
