In this month's column we will complete our look at line drawing in the 64's bitmapped graphics mode. We will deal with both hi-res and multicolor bitmapped graphics. Fortunately, the same general principles apply to both. Last month we saw how a routine to draw lines might look in BASIC. Actually executing the routine would show that BASIC is much too slow to be of much use for this task. At the end of last month's article we took the first step in putting together a set of machine language routines. This month we will complete the set.
First, here is a summary of the features of these drawing routines. The range of coordinates supported is 0 to 319 for X, and 0 to 199 for Y, when in hi-res mode. For multicolor mode, the range is 0 to 159 for X, and 0 to 199 again for Y. It is up to the user to insure that coordinates are within these ranges. Using coordinates which are too far out of range could cause the 64 to crash. In both hi-res and multicolor mode, the location of 0,0 is found at the lower left corner of the display.
Saving Memory For BASIC
The bitmap memory is placed at 57344 ($E000), underneath the operating system ROM. This avoids taking memory away from BASIC. Since this makes the bitmap data difficult to PEEK directly from BASIC, a routine is provided to perform this function. The screen memory is placed at 51200 ($C800), just below where the DOS Wedge loads. Use of these graphics routines should not conflict with the DOS Wedge, but may conflict with other BASIC enhancement software.
Last month we began by writing four of the required routines. This month we are going to upgrade two of those to accept arguments, and add six more. As was mentioned last time, we will execute these routines via a jump table at the beginning of the machine code. This will provide us fixed locations to SYS to, even if modifications or additions are made later. The following is a list of the routines found in the jump table:
Loc. Description JT + 0 Save screen parameters JT + 3 Restore saved screen parameters JT + 6 Enable graphics screen JT + 9 Clear graphics screen JT + 12 Move graphics cursor to X, Y JT + 15 Plot pixel at X, Y JT + 18 Draw line to X, Y JT + 21 Set drawing mode JT + 24 Set drawing color (multicolor) JT + 27 Read bitmap byte (a function)
The jump vector location of these routines is shown as the variable JT plus an offset. To obtain the actual address, JT should be set to the base of the jump table, which is 49152 or $C000. The following table gives the syntax for using each of the routines in the jump table.
SYS JV :REM SAVE SCREEN SYS JV + 3 :REM RESTORE SCREEN SYS JV + 6, MODE :REM ENABLE GRAPHICS MODE: 0 = HI-RES, 1 = MULTICOLOR SYS JV + 9, C0, C1 :REM CLEAR SCREEN C0 = "OFF" COLOR, C1 = "ON" COLOR USE IF HI-RES BITMAP MODE SYS JV + 9, C0, C1, C2, C3 :REM CLEAR SCREEN C0 = BACKGROUND, C1 = FOREGROUND 1 C2 = FOREGROUND 2, C3 = FOREGROUND 3 USE IF MULTICOLOR MODE SYS JV + 12, X, Y :REM MOVE SYS JV + 15, X, Y :REM PLOT SYS JV + 18, X, Y :REM DRAW SYS JV + 21, DM :REM SET DRAWING MODE DM : 0 = FLIP, 1 = DRAW, 2 = ERASE SYS JV + 24, C: REM SELECT COLOR WORKS ONLY FOR MULTICOLOR MODE
The last routine in the jump table (offset = 27) is handled differently because it should be called by the USR function. To set it up as the USR function, execute the statement:
POKE 785, PEEK(JV + 28) : POKE 786, PEEK(JV + 29)
Once this is done, you may read bytes from the bitmap memory with the statement
BYTE = USR(OFFSET)
where OFFSET is the offset from the base address of the byte you wish to fetch.
A Graphics Cursor
The philosophy behind this is that these graphics commands differ slightly for other graphics enhancements to BASIC. Typically, enhancements will add a line-drawing command which always requires both end points. In the routines above, an internal graphics cursor is maintained. Lines are drawn from this graphics cursor to a specified end point. Whenever a line is drawn, the new end point becomes the graphics cursor location. Thus, successive executions of the DRAW routine will create a series of connected lines.
Also, you have a choice of three drawing modes, flip, draw, and erase. The draw mode causes points along the lines to be set to the on state, or to the selected color if in multicolor graphics. Erasing causes dots to be set to the off state or background color. The flip mode involves switching the pixels to their opposite state In the case of multicolor mode, pixels of the selected color are flipped to the background color, and vice versa. Pixels not of the selected color are flipped to the other nonselected color.
To provide a simple example of how to put these routines to use in a program, the following program draws an interesting circular pattern in hi-res mode. Once the pattern is drawn, the program will wait for you to press a key
10 JT = 49152 : SYS JT : REM SAVE SCREEN 20 SYS JT + 6, 0 : SYS JT + 9, 1, 2 : REM INIT SCREEN 30 SYS JT + 21, 0 : REM FLIP MODE 40 FOR I = 0 TO 6.24 STEP .035 50 X = 50*COS(I) : Y = 50*SIN(I) 60 SYS JT + 12, 160 + X, 100 + Y : REM MOVE 70 SYS JT + 18, 160-X, 100-Y : REM DRAW 80 NEXT 90 GET Z$ : IF Z$ = "" THEN 90 100 SYS JT + 3 : REM RESTORE TEXT SCREEN
To put the required machine code into memory, run the BASIC program shown below.
Next month we'll explore some of the more interesting aspects of the machine language source code listing.