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