IBM Graphics on a Monochrome Monitor (COMPUTE! November 1985 by T. G. Hanlin III) IBM PCs can generate stunning graphics, but advanced BASIC graphics features are available only on PCs with a color/graphics adapter. However, with the right programming methods, your monochrome system can produce graphics, too. They are fairly low resolution, and no amount of programming skill can make your monochrome monitor display more than one color, but they are graphics nonetheless. You may find them handy for utilitarian purposes or you may enjoy making simple graphic screens, animated figures, or games. Once you master the basic technique, more and more applications will come to mind. When a PC boots up, it checks to see if the system contains a color/graphics adapter and configures itself accordingly. If a color/ graphics adapter is present, you may use advanced BASIC graphics commands like PUT and GET. If not, those commands cause an error. However, even a monochrome system has the ability to display a large set of special characters. IBM graphics characters have ASCII values of 128 to 255 and include a number of different shapes useful in creating boxes, borders and so on. The characters we're interested in are those which consist of a solid block. All computer graphics are produced by turning pixels on or off to light up different parts of the screen. The smaller the size of the pixel dots, the more detailed the image. Although the IBM character set doesn't include any pixel-sized characters -- each character is composed of several pixels -- it does include some we can use like giant pixels. For example, CHR$(219) is a solid block character, the inverse of CHR$(32), the blank space. Using these two characters together provides a graphics screen with 80 x 25 resolution. To turn a "dot" within this coarse screen, print the solid block at the desired spot. To turn off a dot, print a space. The BASIC function SCREEN(Y,X) tells you whether a given location contains a dot or an empty space. Though you're limited to simple, quite blocky shapes, this system is fast and simple to use. However, it's possible to do much better. Besides the block and space characters which light up or blank out an entire screen location, there aer some which light up only part of a screen position. For instance, CHR$(220) is solid on the bottom half and blank on the top. The reverse is true of CHR$(223). By using these characters, we can double our resolution to 80 x 50 pixels. This complicates matters a bit, since we want to use only half a screen position, and BASIC lets you print only to an entire screen position. Here's a point-plotting routine that handles the tricky details: 10000 GR.Y=Y\2+1:GR.SC=SCREEN(GR.Y,X+1):GR.OFFSET=(Y MOD 2)*3:IF Z=0 THEN 10020 ELSE IF GR.SC=32 THEN GR.SC=223-GR.OFFSET ELSE IF GR.SC+GR.OFFSET<>223 THEN GR.SC=219 10010 LOCATE GR.Y,X+1:PRINT CHR$(GR.SC);:RETURN 10020 IF GR.SC+GR.OFFSET=223 THEN GR.SC=32 ELSE IF GR.SC<>32 THEN GR.SC=220+GR.OFFSET 10030 GOTO 10010 10040 GR.Y=Y\2+1:S9=SCREEN(GR.Y,X+1):Z=(GR.SC=219 OR GR.SC+(Y MOD 2) *3=223):RETURN To plot a point with this routine, set the variable X to the desired horizontal coordinate (0-79) and the variable Y to the vertical coordinate (0-49). Now you've set the screen location for the giant pixel. To turn it on, set the variable Z to 1. Set Z to 0 to turn the pixel off. Then call the subroutine with GOSUB 10000. Line 10040 is a separate routine that tells you whether a given location is lit up or blank. To test any point on the screen, set the variables X and Y to the appropriate coordinates; then GOSUB 10040. The variable Z equals -1 if that point is lit or 0 it it's blank. Though this system emulates a simple graphics screen, keep in mind that you are still printing characters. Thus, there are four screen locations that cause everything to scroll upward if you plot a point there: locations (79,46), (79,47), (79,48), and (79,49). To avoid scrolling your display, either do not use these particular locations or restrict your screen to 79 x 50 pixels (use horizontal locations 0-78). Note that you can mix text and graphics freely, but putting graphics on top of text cause some surprising results. The following program demonstrates how to animate a simple figure. Add these lines to the point-plotting routine and save the program. Make sure the numeric keypad is in numeric mode before you run it. 10 KEY OFF:CLS:DEFING A-Z:Y=0:Z=1:FOR X=0 TO 24:SNAKE$=SNAKE$+CHR$(X) +CHR$(Y):GOSUB 10000:NEXT:DX=1:DY=0:X=X-1 20 I$=INKEY$:IF I$<>"" THEN DX=SGN(INSTR("369",I$)-INSTR("147",I$)): DY=SGN(INSTR("123",I$)-INSTR("789",I$)):IF I$=" " THEN CLS:END 30 X=ASC(RIGHT$(SNAKE$,2))+DX:Y=ASC(RIGHT$(SNAKE$,1))+DY:IF X>78 THEN X=0 ELSE IF X<0 THEN X=78 40 IF Y>49 THEN Y=0 ELSE IF Y<0 THEN Y=49 50 Z=1:GOSUB 10000:SNAKE$=SNAKE$+CHR$(X)+CHR$(Y):X=ASC(LEFT$(SNAKE$, 1)):Y=ASC(MID$(SNAKE$,2,1)):Z=0:GOSUB 10000:SNAKE$=MID$(SNAKE$,3): GOTO 20 Control the direction of the wandering animated snake by using the numeric keypad. Press the space bar to end the program. To improve its speed the point-plotting routine is as short as possible. However, if you don't require fast drawing, you might want to add other features. Perhpas you'd like to color or shade the points to introduce different degrees of brightness (of course, since each two-pixel pair corresponds to a single character, there's a limit to this technique). You might add range checking to check for valid coordinates before you plot a point. And you could also modify the routine to place graphics on top of text correctly.