Solid Shape Drawing on the Commodore 64
by Richard Rylander omputer graphics is one of the easy-to-use graphics capabilities to fastest growing areas of com the masses. The “ masses,” however, Cputer software and hardware may still find the Macintosh pricey, development. The old saying that especially if they just want to play “ one picture is worth a thousand around a bit with MacPaint. Low- words” couldn’t be truer when you cost computers, such as the Commo consider the effectiveness of a pie dore 64, while lacking the slick chart or bar graph versus columns of graphic interaction of the Mac, are numbers. Even the simplest of home selling for such ridiculously low computers is capable of at least this prices ($150 at the time o f writing basic form of computer graphics. But this article) that they are hard to pass the term computer graphics usually up. They have the potential for some brings to mind more exciting images fairly sophisticated graphics, but so than just mundane business far most of the commercially avail applications. able software has done little more Special visual effects for motion than add the usual “ point plotting” pictures and some television adver and “ line drawing” commands. tisements are now being done with This article describes a software computers to create scenes o f “ en package that will allow you to create hanced reality.” W e see spacecraft your own computer-generated making impossible manuevers or scenes, such as “ Coffee and Donuts” shimmering corporate logos “ flying in Figure 1 (page 55) and “ Goblets”
Pumping pixels requires tight, efficient code. Here are halftone shading, backlighting and other visual effects in a tight little package.
by” in ways that would be difficult to in Figure 2 (page 55). You can con simulate with conventional photo struct images from combinations of graphic techniques. The enormous elementary shapes (spheres, cylin amount of data and processing neces ders, and toroids in various orienta sary to produce such images has tions) or by the “ polygon mesh” tech made the use of “ super computers” nique typically used to render more essential. Even with the largest com complex objects. You can produce puters working full time on the task, drawings with realistic shading ef only a few feet of film are produced fects and in a variety o f styles to per day. For home computer owners make some surprisingly detailed pic who want to create their own com tures with a minimum of effort. The puter-generated masterpiece, howev package includes demonstration pro er, the task is not hopeless. grams to illustrate how you use each The Apple Macintosh represents a graphic function and style option. major step in bringing powerful, In keeping with the “ running light without overbyte” theme of DDJ, the Richard Rylander, 179 TV. McKnight entire graphics package fits in 3K of Rd. Apt. 203, St. Paul, M N 55119. RAM. The program sits in an area of
Dr. Dobb’s Journal, May 1985 50 Q C 7 RAM that is inaccessible to BASIC (a arithmetic routines. Because we will in the code. The multiplication rou 4K block following the BASIC ROM) draw our shaded shapes on a high- tine also contains a special case to so that you don’t lose any useful pro resolution display of 320 x 200 treat a single-precision number as a gram space. Commodore supplies a points, we need only single-precision signed integer, which is then squared. “ DOS Wedge” program that occu arguments for most functions and The integer-square-root routine pies the last 1K of this block, and one double-precision results for some in deserves some special comment. o f my objectives in the design of the termediate values. Have you ever tried the BASIC graphics package was to maintain The first two routines, multiplying square-root function? If you have, compatibility with this useful utility. two single-precision numbers to yield you know it takes about 52 millisec The compactness of the code re a double-precision product and divid onds. A t this rate, plotting the 64,000 quired me to leave out some “ bells ing a double-precision dividend by a pixels o f a 320 x 200 screen would and whistles,” but I ’ve made no sacri double-precision divisor to yield a take about 3,328 seconds, or nearly fices to execution speed or user-inter- double-precision quotient, are fairly an hour, if we need a square root per face ease. The main omission is error standard routines that should need no point! O f course, we don’t need a trapping— the software performs no description other than the comments square root for each point, but it is an checking to ensure that you use only “ legal” point coordinates and so on. This may make program develop ment a little more difficult, but once you have written and debugged a pro gram properly, error checking be comes extraneous and only slows pro gram execution. W e must address several general tasks in developing a shape-drawing program. The first is, o f course, how to calculate the apparent brightness for all points on visible surfaces o f ob jects. Next, how do we display these different brightness levels on a high- resolution display that is basically on or off? Finally, a “ general” task, but detailed in nature, is creating the spe cific software tools that will let us do the required calculations and bit-map manipulations. The program itself is written in machine language, because even with our simplifying restrictions, the plot ting of each pixel still involves consid erable computation. The program uses integer arithmetic throughout, and we utilize all the symmetry avail able to eliminate redundant calcula tions. The main program actually consists of five separate subprograms to break the process into manageable pieces and to provide a library o f sep arate utilities that you may find use ful in other programs. Before getting into the problem of shade calculation, I’ll present the first subprogram, which is a collection of integer arith metic utilities that all the later sub programs need.
Integer Arithmetic Utilities Listing One (page 61) provides the source code for a set o f four integer
51 Dr. Dobb's Journal, May 1985 essential part o f many shade calcula Kaner and John R. Vokey in the June and Y screen coordinates (w e take X tions. Obviously, anything we can do 1984 issue o f MICRO). A gain , modulo 8 and Y modulo 8) with the to speed up this particular function though, because we are interested Y bits shifted to become the upper will have a great effect on the overall only in generating random bytes, we three bits. This effectively repeats the program speed. can use a much faster routine. threshold pattern over the entire bit The BASIC square-root routine is The method we use is to store two map area. For each point within an slow because BASIC is written to save previous random bytes, exclusive OR object to be drawn, we calculate a space, not time. Virtually all small them bit by bit, and rotate the result shade value normalized to the range BASICs find a square root by first to the right by one bit to generate a 0-63 and then compare it to the taking the log o f the argument, divid new random byte. Because it needs threshold value at that screen point to ing that result by 2, and then expon no multiply or divide operations, pro decide whether to plot or unplot. entiating. Because LOG and EXP vides a fairly uniform distribution of If we have, for example, a large functions are already available, why random bytes, and has a long period, area where the shade value is con use any more space than necessary to this process is fast. Note that even stant at 31 (a 50 percent gray), then derive SQR? though we are only generating ran within each 8 X 8-pixel character One way to speed up this function dom bytes (0-255), the pattern or se cell block, half of the threshold values is to use Newton’s method, an itera quence o f successive bytes doesn’t re will be greater than or equal to the tive procedure that can give full float peat until after 35,805 calls to the shade value, turning on half the pix ing-point precision in less time. Be random-number-generator routine els. The order in which the values 0 to cause we are interested only in (fo r the initial parameters used in the 63 are arranged in the threshold table integer results, we can do much bet program). The long period is neces determines how these on pixels are ter yet, though. sary to ensure that we won’t produce distributed. A common pattern for The method we actually use is es any unwanted secondary patterns in these so called ordered-dither matri sentially as fast as doing a single-di what should be “ randomly” shaded ces is a recursive arrangement such vide operation. We construct the root, images— the human eye is adept at as that shown in Table 1 (page 53). If bit by bit, in a manner similar to the picking out such correlations. that matrix is subdivided into quar way we would take a decimal square Now that some low-level number ters, sixteenths, and so on, each sub root by hand using pencil and paper crunching is out of the way, we can matrix has the same general pattern, (does anyone remember how to do concentrate on the graphics aspects with offsets between submatrices. that in this age of electronic calcula of the main program. The matrix in Table 1 (classic Bay tors?). The process is even easier for a er ordered dither) keeps the on and binary root because the guesses are, of Graphics Utilities o ff pixels spread as far apart as possi course, only 1 or 0. The procedure is Listing Two (page 62) provides the ble for any shade. This keeps the spa almost identical to that for division: source code for the elementary tial frequencies in the shade “ tex we guess a partial root bit (as we graphics functions of displaying and ture” as high as possible for a would guess the next quotient bit) clearing the bit-map, filling the color particular shade. A disadvantage, and, in effect, compare the square of map (determining dot/background though, is that texture changes then the partial quotient to the argument to colors), and plotting (and unplotting) accompany shade changes, making see if we keep the 1 guessed or change individual points both directly and shade quantization more apparent. it to a 0 and restore the argument. For with the plot or unplot decision Another disadvantage is that many more details about this procedure, I weighted by a shade value and a par color monitors have a hard time cop recommend section 17.3, “ Binary ticular shade style function. The ing with the very high frequency on- Square Roots— Restoring Method,” PLOT (and U NPLO T), CLEAR, COL off-on sequence o f pixels, distorting of the book The Logic of Computer OR, GRFON (display graphics shade values when isolated pixels get Arithmetic by Ivan Flores (Engle screen), and GROFF (return to text lost. wood Cliffs, NJ: Prentice-Hall). screen) routines are specific to the As an aside, a convenient algorithm The last integer arithmetic routine Commodore 64. To adapt this pro to generate the ordered-dither matrix is a fast procedure for generating gram for other 6502-based comput in Table 1 (or such a matrix of any pseudo-random bytes. An old and ers, you need to rewrite these rou size) is found in Figure 7 (page 59). popular method for generating pseu tines, but the rest of the graphics The threshold matrix we actually do-random numbers is the so called package (save the final user interface use in the program is shown in Table congruential method, in which you to BASIC) is machine independent. 2 (page 53). Here we follow a recur derive each successive random num The SHADE routine is simple and sive scheme as we start turning on ber from the previous random num straightforward. We set up an 8 x 8 pixels until eight nuclei have been es ber by multiplying by a suitably cho threshold matrix as a linear array of tablished. As shades increase, new sen constant and taking the product values 0 to 63. The six bits we need to pixels are added around the edges of modulo P, where P is a large prime address an element o f this threshold these nuclei, simulating the dot- (see, for example, “ A Better Random array are determined by masking off growth behavior seen in normal Number Generator,” by H. Cem the lower three bits of the absolute X printing halftones. Except in the ex
Dr. Dobb's Journal, May 1985 52 369 treme highlight and shadow regions, plicity more than makes up for plot SYS to PLTSHD. This seems like a lot the shade texture remains fairly con ting 20 percent more points. Scaling is of work to plot a single point, but we stant. Also, the clustering of on or o ff left as an option because some printers really won’t be plotting shade-weight pixels is much less demanding on the (such as the Commodore 1525) have ed points by hand— the later shape- display bandwidth. But take your 1:1 dot densities. By not scaling, the drawing routines take care of this. pick— try filling the threshold matrix screen display is distorted but a hard with your own patterns. copy printout will have the proper ge Line and Facet Drawing The RSHADE routine shades by ometry. On the other hand, you can Listing Three (page 64) completes comparing the shade value to a pseu set up printers, such as the Epson R X - the elementary graphics functions by do-random byte shifted right twice to 80, with the appropriate horizontal adding line-drawing and shaded-fac- match the 0-63 range. This scheme and vertical dot densities to produce a et-drawing routines. We draw lines also tends to average out the tone er 4:3 aspect ratio screen dump. Scaling using a modified form of Bresen- rors generated as each pixel is turned here corrects both the screen and the ham’s algorithm, a DDA (Digital Dif only on or off (though we want an hard-copy output. ferential Analyzer) technique that intermediate shade of gray) by dith The routine PLTSHD is a higher lev keeps the actual plotted points within ering the threshold value randomly at el routine that simply checks a couple one half-screen unit o f the true line. each pixel. Both shading schemes of flags to see what kind of shading we Regardless o f the order in which we produce sharp edges because each want and whether to scale or not. It specify the line’s endpoints, the pro pixel is plotted independently. then calls the appropriate shading rou gram sorts them so that lines are al Abrupt shade changes are then fol tine. To plot a shade-weighted pixel ways drawn from left to right (the X lowed faithfully. from BASIC, POKE a shade value (0 position is incremented or unchanged The SCALE routine provides an 63) into VALUE; POKE the absolute X at each step). We then need only de opportunity to mention a general rule and (optionally scaled) Y values into termine which is greater, the change you should follow when you try to XPLOT, X PLO T+1, and YPLOT; set in X or the change in Y, and whether write fast programs: I f at all possible, up the flags HTORRN (H A LFTO N E the Y coordinate difference is posi avoid division; and if you must divide, or RANDOM) and NOSCAL; then tive or negative. The program checks try to make it by a power o f 2 (so that you can use right shifts). The SCALE routine helps correct some o f the geo metric distortion that otherwise re 0 32 8 40 2 34 10 42 sults from plotting objects on the 48 16 56 24 50 18 58 26 Commodore 64’s rectangular bit 12 44 4 36 14 46 6 38 map. While the monitor display has 60 28 52 20 62 30 54 22 an aspect ratio of approximately 4:3, 3 35 11 43 1 33 9 41 the bit-map aspect ratio is 320:200 or 51 19 59 27 49 17 57 25 8:5. A simple way to keep sphere out 15 47 7 39 13 45 5 37 lines circular (instead o f the usual 63 31 55 23 61 29 53 21 egglike appearance) is to work in pseudoscreen coordinates o f 320 X 240, giving the bitmap the same 4:3 Table 1 aspect ratio as the screen display. Recursive Arrangement of Ordered-Dither Matrix The SCALE routine then converts 0 239 YPLOT values to a 0-199 range. An obvious way to do this is to first multiply by 5 and then divide by 6. Or you might save a multiplication by first dividing a copy o f YP LO T by 6 0 8 53 61 2 10 55 63 and subtracting that from the original 16 24 37 45 18 26 39 47 YPLOT. A much faster way is to mul 49 57 4 12 51 59 6 14 tiply the single-precision YP LO T by 33 41 20 28 35 43 22 30 213 and then take just the upper byte 3 11 54 62 1 9 52 60 of the double-precision product (e f 19 27 38 46 17 25 36 44 fectively dividing by 256) as the 50 58 7 15 48 56 5 13 scaled YPLO T value. This gives us the 34 42 23 31 32 40 21 29 proper range o f absolute screen Y val ues and “ rounds” the scaling as well. This method o f scaling means that Table 2 you effectively replot every sixth Y Threshold Matrix line of pixels, but the routine’s sim
53 Dr. Dobb’s Journal, May 1985 ^70 the scale flag to see if the endpoints sections, and, if a larger triangle is ly with how different surfaces reflect, should be adjusted (in their Y coordi essential, you can break it into small refract, scatter, or absorb light. In nates) before plotting commences. er triangles that meet this condition. creasingly complex models for the vi This keeps a common coordinate sys The occasional inconvenience this sual appearance o f various surface tem for drawing shaded shapes might cause is worth the increase in textures have led to ever more realis (spheres and so on) and lines in the speed and shortened program. tic images, but increasing computa same image. A flag MODE deter W e leave the shade value used in tional overhead accompanies these mines whether the line is drawn by drawing facets as a parameter that models. W e’ll employ the simplest setting or clearing pixels ( “ black” or the calling program specifies. A l shading scheme to start with and “ white” lines). though adding “ surface normal” cal then suggest how you might modify it The program’s last elementary culation and shade value computa to add “ realism,” while still keeping function is to draw shaded triangular tion based on some illumination the computations manageable. facets. A powerful and flexible tech model (and requiring the Z coordi If we restrict ourselves to simple, nique for rendering objects is by nates then to be specified for the ver symmetrical objects, we can greatly means of a polygon mesh. Natural tices) is not difficult, the same shade simplify the problem of calculating polyhedral objects (for example, value is used for all points of the fac surface brightness. This is not a se cubes and pyramids) are obvious can et, making shade determination by a vere restriction in itself, as you can didates for this method, but you can BASIC program practical. Also, leav break most “ complex” objects down also approximate curved surfaces by ing shade calculations up to BASIC into combinations of simple elemen a connected mesh o f planar polygonal adds the flexibility that we can use tal shapes. We will have to limit our sections. As in piecewise-linear ap any shading model. The curved sur selves to •‘normal” (that is, head-on) proximations o f curves, the finer the face-drawing routines I describe later views of the objects, because once we segmentation, the better the approxi do include shade determination, but allow objects to be rotated, they lose mation— although at the price of here each point can potentially have a most of their symmetry. Also, calcu greater computational overhead. The different shade value, putting it in the lation time (particularly that for hid coordinates of the polygon vertices innermost loop. For this reason, the den surface removal) increases then constitute a data base that you curved surfaces must have a fixed enormously. can manipulate easily for rotational shading model. We use the Lambertian (diffuse transformations, perspective trans An interesting use for the BASIC- reflector) model to determine the formations, and so on. Triangular specified shade values is drawing surface brightness. W e assume that sections are the simplest to handle “ white” facets by setting the shade to light comes from a single, specific di and the most general because you can 64. This doesn’t seem particularly rection and then find the cosine o f the break any higher-order polygon down useful, but when you draw “ wire angle between this reference vector into triangular sections. / frame” polyhedra, it makes a simple, and a surface normal vector. This As in the line-drawing routine, the hidden-line removal scheme possible. gives us shade values from 1, where program sorts the endpoints of the fac If the facets of an object are sorted so the surface faces the light source, to 0 ets into a left-to-right order and checks that they are drawn from those fur at the terminator, where light just the scale flag to maintain a consistent thest to those nearest the observer, grazes the surface; and negative val coordinate system. A t each X position with “ black” lines added around the ues where the surface is turned away across the facet, a top and bottom Y edges of each facet, then foreground from the light. Here is our first op coordinate pair is determined by a sim facets that partially obscure back tion: We can clip the brightness val ple proportionality between the X dif ground facets erase the lines in their ues at 0 so that areas facing away ference and Y difference for the partic interior. We can set a flag EDGES so from the light have zero brightness, ular triangular sides. Although this that, after the program has drawn a as an object lit by a single source (in involves both multiplication and divi shaded facet, it can add lines auto deep space) would appear. Or, we can sion operations, it is not the innermost matically to outline and emphasize use the absolute value o f the cosine so loop here (drawing the shaded line seg the edges. The MODE flag again de that the object appears to be lit by ment between Y pairs is). It also does termines how the lines are drawn (set two identical sources on opposite not give more than one Y value per X or cleared). sides. Either way is simple, so we al position, as would a DDA method (for Now that we have a toolbox of low for both cases by using a flag to lines with slope greater than 1 in arithmetic and primitive-graphics determine what kind o f illumination magnitude). routines, we can concentrate on the scheme we want to use for a whole The maximum X difference is re main subprogram for drawing shad scene or any individual shape making stricted to less than 256 (single preci ed, curved surfaces rapidly. up the scene. sion), though the absolute X coordi Although this simple model is valid nates for the triangle vertices can be Determining Shade Values for for diffusely reflecting surfaces, it anywhere on the screen. This is not Curved Surfaces does not account for any contribu too severe a constraint because most Many recent advances in computer tions from specular surface reflec polygon meshes are made up of small image synthesis have dealt specifical tions, secondary light sources (other
Dr. Dobb’s Journal, May 1985 5 4 371 SPHERE H-CVLHDR U-CYLNDR TOROID
SAMPLE SHAPES
U-TOROID H-TOROID H-SPOOL U-SPOOL
Figure 3 Figure 4
Figure 5 Figure 6
55 Dr. Dobb’s Journal, May 1985 than the “ opposite face” light) or am ing in the “ portrait” (as opposed to pseudo-random bytes (used in the bient (nondirectional) light. These “ landscape” — unrotated) mode then RSHADE routine) to the same range additional subtleties are not difficult comes from over the left shoulder. simply by shifting them right twice. to implement, but for the level of de So, for a surface point (X , Y, Z ) on a tail and dynamic range (number of Drawing a Shaded Sphere sphere of radius R, the appropriate gray levels) in our halftone display, Spheres are particularly easy objects SHADE integer (0-63) is: they really aren’t worth the effort. to deal with because a radial vector from the center to a point on the sur SHADE = 26*(X + Y + 2*Z)/R Object Geometry face is in the same direction as a sur Calculating the surface normal vec face normal from that point. The The factor 26 properly accounts for tors for points on an arbitrary surface only real problem we must deal with the SQR (6) in the denominator o f the can be difficult, but this is why we is one of normalization. We will al previous equation. have restricted ourselves to objects ways deal with coordinates relative to As stated earlier, all the primitive that can be made up of combinations the “ local center of curvature” of ob shapes considered here have at least o f the eight simple shapes shown in jects. For spheres, this is just their fourfold symmetry. We need com Figure 3 (page 55). A ll the basic geometric center. pute the Z component only once for shapes have at least fourfold symme Consider a point on the surface each + X and ± Y quartet o f points try; that is, once we have found the that extends out o f the screen from (relative to the geometric center of surface normal for a point (X, Y ) in relative coordinates (X ,Y ). We find the object). The sphere and top-view one quadrant o f the object, we can the corresponding Z value using the toroid actually have n-fold symme easily find the surface normals for the equation for a sphere: try, which the Cartesian grid of other three quadrants by comple screen pixels reduces to eightfold menting appropriate components. Z = SQR(R*R - X*X - Y*Y) symmetry. That is, in addition to Also, by restricting ourselves to changing signs o f X and Y, we can shapes with relatively simple surfaces, This calculated Z then forms the exchange the X and Y coordinates to we can determine the required surface third member of the surface normal find another surface point with the normal vectors without resorting to vector. To calculate the cosine of the same Z value. trigonometric functions, using instead angle between this vector and the il some simple geometric consider - lumination reference vector, we must Shape-Drawing Routines ations. first normalize both to have unit Listing Four (page 68) is a set of rou Another time-saver is to choose an length. The normal we have just tines for drawing the eight simple illumination reference vector to best found has, of course, a length o f R, so shapes shown in Figure 5. The routines take advantage o f symmetries in the we need only divide each component resemble some form of compiled BA objects. Unfortunately, the “ best” by the radius o f the sphere. The illu SIC in that they use no special bit ma choice for computational purposes— mination vector (1,1,2) has a length nipulations or unusual addressing a light source directly behind the o f SQR(6), s o we normalize this vec methods, but just have appropriately viewer— gives a rather flat-looking tor to unit length by dividing each ordered calls to the lower-level routines image. Much more pleasing shading component by SQR(6). set up earlier. Comment statements results from illumination coming Now that we have two vectors of precede each shape-drawing routine, from “ over the shoulder.” The slight unit length but different directions, giving an equivalent BASIC routine. assymmetry that results gives a we find the cosine o f the angle be This seems to be the easiest way to ex stronger sense o f depth to the objects. tween them by taking their inner plain each routine because most read The coordinate system describing product, which is nothing more than ers are familiar with BASIC program objects on the screen has its X axis summing the products of the X, Y, methods. I thus give special comment increasing horizontally to the right, and Z coordinate pairs— like so: to only a few of the routines here. the Y axis increasing vertically up GETVAL is a shade-normalization ward, and the Z axis increasing out of COSINE = (1*X + 1 * Y + 2*Z) routine that also checks for normal or the screen toward the viewer (a con / (R*SQR(6)) backlit illumination via the flag BAK- ventional right-handed coordinate LIT. The byte pair at TO NE contains system). The illumination reference To use integer arithmetic through the inner (dot) product o f the illumina vector used here has X , Y, and Z out, we don’t really want brightness tion vector with the local surface nor components of (1,1,2), representing expressed as a fraction between 0 and mal vector. GETVAL then effectively light coming from over the right 1, but rather scaled to a range of inte does the division by SQ R(6)*R and shoulder. The symmetry in X and Y gers from 0 to 63. We choose a maxi multiplication by 63 to put VALUE makes for easier shade calculations mum shade value of 63 to match the into the proper range, clipping at zero and gives a similar looking scene if 64 gray levels that can be approxi or taking the absolute value, as you rotate a hard-copy output 90 de mated by an 8X8 threshold matrix necessary. grees to fit objects that are taller than (described earlier in the “ Graphics PTPLOT does all the dirty work they are wide into the display. Light Utilities” section). We scale the needed to plot shaded points for four
Dr. Dobb's Journal, May 1985 56 373 fold symmetrical objects. Provision is explain with the help of the diagram tines are specific to the Commodore also made here for clipping the object in Figure 5 (appropriate for a top- 64 in that they use some of the rou at independent levels up, down, left, view toroid) (page 55). tines in the BASIC ROM to interpret and right of the object’s center. The Consider a point P at coordinates statements in a BASIC program or en clipping feature is needed to blend (XREL, YREL) relative to the center tered in the direct command mode. various primitive objects into more o f the object. W e can take the local Graphics commands are given in complex ones with smooth transitions center of curvature o f the toroid to be the form: at the seams. Clipping also allows us at the point C, which lies on the inter to create some intricate “ weaving” section of the line passing through SYS(FNCTN),PARAM 1 ,PARAM2, effects by redrawing portions of over the center of the toroid and a point [OPTIONAL PARAMETERS] lapping shapes as in F igu re 4, beneath P (where Z = 0) with a circle “ Linked Toroids,” (page 55). o f radius RC (the “ average” radius of where FN C TN is the address of the The flag NOROT determines the toroid is RC = (RO + R I) / 2). We graphic function you desire (or a whether the X and Y coordinates will determine the surface normal by the variable that has been assigned the be exchanged. This is useful both for relative X , Y, and Z displacements address value) and PAR AMI and drawing the eightfold symmetrical ob from the point C. PARAM2 are parameters (such as the jects (top-view toroid and sphere) and The byte R0 is used for temporary center coordinates of an object) that for rotating the fourfold symmetrical storage of the radial distance from the function requires, followed by objects 90 degrees so that a single the toroid center to the point beneath any optional parameters. drawing routine can produce two ori P (where Z = 0): The parameters can be either liter entations of an object. The calculations al numerics or expressions that are are basically those for the sphere, but R0 = SQR( XREL* XREL evaluated for the desired values. We we’ll see later that we can put other + YREL*YREL) do not have to put the function ad objects, such as toroids, into forms that dress in parentheses, but it helps to look like spheres (at least locally). We can determine the relative X and make the program more readable. GETZ calculates the effective Z co Y displacements, XSHD and YSHD, Separating parameters by commas is ordinate for a spherelike surface, giv respectively, o f P from C easily by us required. If you desire an optional pa en the X and Y coordinates relative ing similar triangles: rameter (such as specifying a new ra to the local center of curvature. Note dius for sphere drawing), you add it that this routine needs the SQRT XSHD = XREL*( 1 - RC/RO) by following the last required param function, and because it is in general YSHD = YREL*( 1 - RC/RO) eter by a comma and then the option called for each quartet of points plot al value or expression. ted, our fast SQRT makes a big dif We find the Z coordinate via the P y The use of optional parameters is ference in execution speed. thagorean theorem, using the radius more easily explained with the se SPHERE follows the previously o f the “ ring” portion, RT, as the hy quence o f BASIC statements found in outlined algorithm and takes full ad potenuse. RT is then also the length Figure 8 (page 59): vantage of the available symmetry. o f the normal vector and is the value For all the shape-drawing func The radius is POKEd into RADIUS, POKEd into RADIUS for normaliza tions, you must specify the X and Y and clipping distances relative to the tion in the shade calculations. center coordinates, but shape sizes sphere center are POKEd into CLIPL The routine TOROID follows this are optional parameters. The last val (left), CLIPR (right), CLIPU (up), algorithm, taking advantage of the ues specified become the new default and CLIPD (down). eightfold symmetry in the object. sizes, allowing you to draw copies of CYLNDR draws a cylinder with EDGTOR and SPOOL use similar similar objects (such as a bunch of sizes POKEd into RADIUS and center of curvature coordinates to grapes) just by setting the new center HLEN (half-length). The flag draw other orientations of a toroid. I coordinates. All shapes but the NOROT determines whether the cyl have given the BASIC equivalents but sphere take two size parameters, and inder will be drawn with a horizontal leave it to readers to draw the appro you must specify both when you de or a vertical axis. The routine is sim priate geometric constructions if they sire a change (even when only one pa ple, using PTPLOT for the main desire more details. rameter takes on a new value). A ll shade-calculation tasks. Actually, we size parameters (radii and cylinder could write a much faster routine to Using the Shape-Drawing Rou half-lengths) must be less than 256, take advantage of the fact that we tines— Interface to BASIC not a severe limitation considering can use the same shade value for all The last module, completing our the screen is only 200 pixels high points along lines parallel to the cyl graphics package, is a convenient in (“ 240” with scaling). inder axis. This would require consid terface to BASIC. Listing Five (page The commands to clear the bit map erably more space, however. 76) is a collection o f routines to pass and initialize the color map each take The peculiar manipulations of rel parameters easily to the graphics rou a single optional parameter, but the ative coordinates for plotting toroids tines from the BASIC programs that default values remain unchanged. Un in various orientations are easier to control image generation. These rou less you specify alternate bytes, the bit
58 Dr. Dobb's Journal, May 1985 map is filled with Os (cleared) and the color map is filled with Is (for black dots on a white background). The 10 REM ORDERED DITHER ARRAY— RECURSIVE FILL most useful alternate byte with which 20 l = 0:J = 0:K=1:N = 0:P = 3 30 REM P' IS ORDER OF ARRAY, SIZE IS (2 * P) x (2 ' P) to fill the bit map is 255, setting the 40 P = 2 ' P:DIM A(P - 1 ,P - 1) entire background. Because the shad 50 GOSUB100 ing process clears, as well as sets, ap 60 END propriate points, objects still appear 100 IF K = P THEN A(I,J) = N:N = N + 1 :K = K/2:RETURN normal but against a black back 110 K = 2*K:GOSUB 100 120 l = l + K:J = J + K:K = 2'K:GOSUB 100 ground (particularly effective when 130 l = l -K:K = 2XK:G0SUB 100 you use the “ back light” style). 140 1=1 + K:J = J - K:K = 2'K:GOSUB 100 The byte used to fill the color map 150 l = l-K :K = K/2:RETURN is made up o f background and fore Figure 7 ground nibbles. To initialize the color map for a different color combination than black on white, use:
SYS(52001),16*DC + BC . . . (SET UP GRAPHICS, STYLES. ETC) 200 SP = 52119:REM ADDRESS OF SPHERE FUNCTION where DC is the dot-color number 210 SYS(SP),80,75,30:REM DRAW A SPHERE OF RADIUS 30 AT X = 80 Y = 75 220 SYS(SP),300,50 REM DRAW ANOTHER SPHERE AT X - 300, y = 50 and BC is the background-color num 230 REM SINCE NO RADIUS IS. SPECIFIED, LAST VALUE IS USED AS DEFAULT ber (as given in any reference to pro 240 SYS(SP),200,150,40:REM NEW SPHERE RADIUS (40) BECOMES DEFAULT gramming the Commodore 64). The addresses for all the graphic Figure 8 functions and the parameters they take, along with locations to be POKEd with clipping values and flags for various drawing styles, are sum marized in Table 3 (page 60). The best way to see how these shape- drawing routines are used is to exam ine the demonstration programs in Listing Six (page 78), “SHAPES DEMO,” and Listing Seven (page 80), “ STE LLATIO N.” A ll the differ ent style options are exercized there. It is useful to save an abbreviated ver sion o f SHAPES DEMO, consisting of just the lines up to 340 and the sub routines following line 1620. This skeleton program can then form a base, providing all the POKE and SYS locations you need and to which you can add your own image-generation control program.
Auxiliary Programs SHAPES DEMO and STELLATION make use of two auxiliary programs that, while not strictly needed to pro duce graphic images, provide utilities to both enhance the image itself and speed the drawing process. Listing Eight (page 80) is a routine for sort ing an integer array indirectly through a key array (to determine drawing order for facets in a polygon mesh quickly). Listing Nine (page 82) allows you to add text to graphic
Dr. Dobb’s Journal, May 1985 59 r\-ltr images in a variety o f styles. the graphics package in one piece. imum element index of the arrays The code for these routines is short The KEYSORT routine works with into location 140, the address of the enough to be tucked in behind Com two 1-dimensional integer arrays of first (0th) element of the key array modore’s DOS Wedge program so the same size. One is filled with some into locations 251 (low byte) and 252 that, again, you don’t lose any BASIC “ priority” parameter (such as the (high byte), and the base address of program space but maintain full “ average Z ” coordinates for the fac the priority array into 253 and 254. compatibility with the wedge. If you ets in a polygon mesh), and the other You can find these array base ad are willing to give up the convenience becomes a “ key” array whose ele dresses easily because the Commo of the wedge, however, you can easily ments index those in the “ priority” dore 64 places the address of the relocate these routines to the end of array in increasing order. “ current BASIC variable” into loca the “ interface” subprogram to keep To use the routine, POKE the max tions 71 and 72. Setting the 0th ele-
BIT-MAP SCREEN : 40960-48959 ($AOOO-$BF3F)
COLOR M A P : 33792-34791 <$8400-$87E7)
CLIPPING BOUNDS (relative to object center):
893 ($037D) LEFT BOUND 894 ($037E) RIGHT BOUND 895 ($037F) UPPER BOUND 896 ($0380) LOWER BOUND
53280 ($D020) BORDER COLOR [0-15], POKE with 1 to match white screen
STYLE FLAGS 838 ($0346) SHADE STYLE [0 = random, 1 = halftone] 839 ($0347) SCALE FLAG [0 = normal (1:1). 1 = scaled (3:4)] 868 ($0364) EDGES FLAG [0=normal, 1 =add lines to facet edges] 871 ($0367) EDGE/LINE MODE [0 = draw, 1 =erase] 898 ($0382) LIGHTING STYLE [0 = normal single source, 1 = backlit]
FUNCTION LOCATIONS—CALL WITH "SYS(FNCTN), PARAMETERS." OPTIONAL PARAMETERS IN SQUARE BRACK ETS, DEFAULT VALUES ARE USED IF NOT SPECIFIED
49378 ($C0E2) SWITCH TO GRAPHICS MODE 49411 ($C103) RETURN TO TEXT SCREEN
51979 ($CB0B) CLEAR[,CLEAR BYTE] FILL BIT MAP WITH CLEAR BYTE [DEFAULT = 0] 52001 ($CB21) C0L0R[,COLOR BYTE] FILL COLOR MAP WITH COLOR BYTE
52023 ($CB37) PL0T,X,Y SET POINT AT (X,Y) 52026 ($CB3A) UNPLOT,X,Y CLEAR POINT AT (X,Y)
52049 ($CB51) LINE.X1 ,Y1 ,X2,Y2 DRAW A LINE BETWEEN (X1 ,Y1) AND (X2,Y2)
52052 ($CB54) FACET,X 1,Y 1 ,X2,Y2,X3,Y3,VA DRAW A SHADED TRIANGULAR FACET BETWEEN COORDINATE PAIRS (X1 ,Y1), (X2,Y2) AND (X3,Y3) USING "VA" SHADE VALUE (0:BLACK TO 64:WHITE)
CURVED SURI 52119 ($CB97) SPHERE,X,Y[,R] DRAW A SPHERE CENTERED AT (X,Y) WITH RADIUS R 52141 ($CBAD) TOROID,X,Y[,RI,RO] DRAW A TOP-VIEW TOROID WITH INNER RADIUS Rl AND OUTER RADIUS RO 52150 ($CBB6) VCYL,X,Y[,R,HL] DRAW A CYLINDER WITH AXIS VERTICAL, RADIUS R AND HALF-LENGTH HL 52153 ($CBB9) HCYL,X,Y[,R,HL] DRAW A CYLINDER WITH AXIS HORIZONTAL 52186 ($CBDA) VTOR,X,Y[,RI,RO] DRAW AN EDGE-VIEW TOROID WITH AXIS VERTICAL 52189 ($CBDD) HTOR,X,Y[,RI,RO] DRAW AN EDGE-VEIW TOROID WITH AXIS HORIZONTAL 52203 ($CBEB) VSPOOL,X,Y[,RI,RO] DRAW AN INSIDE-VIEW TOROID ("SPOOL") WITH AXIS VERTICAL 52206 ($CBEE) HSPOOL,X,Y[,RI,RO] DRAW AN INSIDE-VIEW TOROID ("SPOOL") WITH AXIS HORIZONTAL
Table 3 Graphics Addresses
60 Dr. Dobb’s Journal, May 1985 ment of an array equal to itself mere et completely overwrites the ue execution). ly establishes it as the current background (clearing, as well as set The subroutine following line 1780 variable. Then you can transfer the ting, points) so that drawing facets in SHAPES DEMO illustrates how to contents o f 71 and 72 to the proper from back to front gives a proper ren print text in a variety o f styles on the pointer at 251/252 or 253/254. Be dering of the object. bit-map image. Although the pro careful to use literal numerics for The stellated dodecahedron of Fig gram actually uses only one style, the “ 251” and so on, because you don’t ure 6 usually has only 30 visible or subroutine allows for five possibili want to change the current variable. partially visible facets. Sorting with ties. Normal ( “ black” on “ white” ) A fter setting up the pointers, SYS to BASIC would be satisfactory here, but characters and reverse characters can the start of the KEYSORT routine. more complex polygon mesh objects overwrite the background, black Another caution to observe if you use can easily contain hundreds of visible characters can be ORed with the KEYSORT for other applications is and partially visible facets. You can background, white characters AND- not to create any new variables be really appreciate KEYSORT in those ed with the background, or black tween finding the array base address cases. Although it uses the simple and characters exclusive ORed with the es and invoking KEYSORT, because inefficient bubble-sort algorithm, be background. The last possibility gives arrays will be pushed up in memory ing implemented in machine code lets characters that “ change phase” to keep them at the end of BASIC’s KEYSORT run circles around any BA across black/white edges in the variable storage. SIC sorting alternative. image. KEYSORT is set up to handle arrays The final routine, in Listing Nine, with up to 256 elements each. If need W RITE, allows you to add text to the Conclusion ed, you can sort larger arrays by break graphic display. The primary reason The graphics package described here ing them into smaller arrays, sorting for implementing this as a machine we hope presents some new ap with KEYSORT, and then collating the code routine is that the bit map for proaches to computer-generated im results. Merging a few already sorted the graphic image is located in the ages on small systems. A t the same arrays is a fairly simple operation that shadow RAM beneath the BASIC time, I’m sure I ’ve missed some obvi you can do in a single pass, extending ROM (again saving useful BASIC ous tricks that would speed up the the usefulness o f this routine. program memory space). We can programs or reduce their size. I will S T E L L A T IO N uses K E YS O R T transfer bit images from the charac be interested to see responses to this (lines 840-880) to determine the ter ROM to the bit map just by PO- article and shortcuts or enhance drawing order for the facets of a KEing values to the bit map, but we ments that might be added. Although small stellated dodecahedron (Figure gain more flexibility if we first read the price/performance ratio of small 6, page 55). This is a polyhedron that the bit-map bytes to exclusive OR graphics system continues to improve is not strictly convex (some internal them, AND them, and so on with (especially with the development of dihedral angles are greater than 180 character image. Reading the shad custom LSI graphics chips), there are degrees), causing some foreground ow RAM requires that the BASIC yet many unexplored software ap
facets to partially obscure those in ROM be switched out (through the proaches to the problem. d d ) the background. The Painter’s algo bank switching used in the Commo rithm is used to handle hidden sur dore 64), something a BASIC pro face removal. Each newly drawn fac gram cannot do (and hope to contin
Drawing on the C-64 (Text begins on page 50) Listing One
INTCI3CR ARITHMETIC ROUTINES 00032 C004 0 0 00 2 00073 C0O4 00003 0000 ft I CHARD L. KYI AND! ft 0/1 2/: 00034 C004 MULTIPLY SINGLE PRECISIUN Mill T I Pl. I LAND 00004 0000 00035 COO 4 UY SINGI E PRECISION MULTIPLIER UIVING OO0O 000 36 r.004 DOUBLE PRECISION PRODUCT (LNHK Al "MULT" 000 3 7 COO 4 00038 C004 00OO 000 39 CO04 0 OOO 00040 C004 0000 » USE PAGE ZCftO LOCATIONS WHERE POSSIBLE FUR 00041 C004 I ENTRY TO SQUARE 0 0 0 1 1 00OO 5 ITERATIVE PROCEDURE WORl SPACE 00042 C00e> 10 07 1 USE ABSOLUTE VALUE 0 0 0 1 2 0000 00043 C00U 58 SEC ; NEb.\ IE IF NEEDED 0OO1 3 0 00 0 ML PC ND '‘ t AC ; MULT 1ILICAND 00044 C007 A9 00 LDA N 100 00014 Ml PI ER =*AD ! MULTIPLIER 00045 coot. E5 AC SBC MLPCND 00015 PROD =4AE ; PRODUCT 00046 C0OD 85 AC STA ML I Cl 10 00016 00047 C00F 85 AD P03ITV STA MLFLER 000 I 7 0O0O DVDND =»»T) ; D IVI DEND/QUOT1CN1 c a n A9 00 MULT LDA m o o ; ENTRY TO MULTIPLY 0 0 0 1 a 0000 DVSOP ‘iTD ; DIVISOR 00049 C013 LDX NT 08 00019 0000 RMNDR “ID4 ; REMAINDER 00050 CO 15 MLOOF LSR Ml PLER 0 00 20 0000 00051 CO 17 BCC NOADD 00021 OOO0 00052 CO 19 CLC 0 0 0 2 2 0000 00053 C01A ADC MLPCND 00023 0OO0 00054 C01C NOADD ROR 00024 0000 00055 CO ID ROR 00025 0000 00056 CO IF DEX 00026 0000 j SET UP SEED VALUES FOR PSEUDO RANDOM NUMBERS 00057 C020 BNE 00027 0000 •-4COO0 0005(3 C022 STA cooo RNIjM .UYTE JFF,*5r-; 00059 C024 RTS 000 28 COO I C025 00029 C002 RTCMP .BYTE 100,100 61 C025 C003 C004 C004 (Continued on next page)
Dr. Dobb’s Journal, May 1985 61 377 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing One
00062 C023 00063 C023 ; DIVIDE DOUBLE PRECISION DIVIDEND Listing Two 00064 C023 , BY DOUBLE PRECISION DIVISOR GIVING 00063 C023 ; DOUBLE PRECISION QUOTIENT 0 0 0 6 6cars ; } GRAPHICS UTILITIES 00067 C023 I DIVIDEND IS REPLACED BY QUOTIENT 00002 0000 t C023 I IN THE PROCESS 00003 0000 ; RICHARD L. RYLANDER 11/4/04 C023 00070 C025 ; QUOTIENT IS ROUNDED TO NEAREST INTEGER ; LOAD ARITHMETIC UTILITIES FIRST 00071 C023 ; 00072 C023 A9 00 DIVIDE LDA #*00 RAM=*033E 00073 C027 85 B4 STA RMNDR ORIGIN=**C0E2 00074 C029 85 B5 STA RMNDR♦1 I 00073 C02B A2 10 LDX • 1 1 0 Ml.PCND3-! AC } MULTIPLICAND 00076 C02D 26 FD DLOOP ROL DVDND 0001 1 Ml PLER=*AD I MULTIPLIER 0007 7 C02F 26 FE ROL DVDND*1 0 0 0 12 FROD«*AE ; PRODUCT
62 Dr. Dobb's Journal, May 1985 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Two
00123 Cl 66 TXA 00214 C212 00 t 24 C 1 67 29 07 AMD #*07 00213 C214 00123 Cl 69 18 CLC 00216 C214 5 SCALE Y FROM 0-239 PSEUDO-COORDINATES 00126 C16A 63 FB ADC *FB 00217 C214 | TO 0-199 TRUC SCREEN COORDINATES BY 00127 C16C 83 FB STA #FB 00218 C214 j Y ■ (Y*l)>213/236 00 128 C16E AD 3F 03 LDA XPl. T 00219 C214 I 00129 C 171 29 F8 AND #*F0 002 20 C214 AC 41 03 SCALE LDY YPLT 00130 C 173 63 FB ADC *FB 00221 C217 C8 I NY 00131 C 173 83 FB STA *F0 00222 C210 84 AD STY MLPLER 00132 CI 77 AD 40 03 LDA XF-l.ri l 00223 C21A A9 D5 LDA #*D5 | 21T. 00133 C17A 63 FC ADC *FC 00224 C21C 85 AC STA MLPCND 001 34 C17C 83 FC sta trc 00223 C21E 20 11 CO JSR MULT j RETURN WITH HIGH BYTE 001 33 C17E A9 AO LDA ft*AO 00226 C221 8 D 41 03 STA YPLT I IN ACCUMULATOR 00136 C 180 63 FC ADC *FC 00227 C224 AD 46 03 NORM LDA HTORRN 00137 C182 83 FC STA *FC 00228 C227 F0 03 BEQ RPLT 00138 C 184 AD 3F 03 LDA XPLT 00229 C229 4C DD Cl JMP SHADE 00139 C 187 29 07 AND *107 00230 C22C 4C FF Cl RPLT JMP RSHADE 00140 Cl 89 49 07 EOR #107 00231 C22F 5 00141 C1B6 AA TAX 00232 C22F 00142 C18C A9 01 I DA #101 00233 C22F 00143 C1UE FLOTLP DLX 00234 C22F THRESH .BYTE *00,*08,*33,*3D 00144 C18F BMI PLOT2 00234 C230 00143 C 19 I ASL A 00234 C231 00146 C192 DO FA BNE PLOT LP 00234 C232 00147 C 194 AO 00 PL0T2 LDY #0 00233 C233 .BYTE *02,*0A,*37,*3F 00148 C 196 2C 3E 03 BIT PLTFLG 00233 C234 00149 Cl 99 10 03 6 PL NOPl.QT 00233 C235 00130 C 1 96 49 FF EOR #*FF 00233 C236 00131 C19D 31 F6 AND < JFB) i V 00236 C237 .BYTE * 10,* 18,*23,* 2D 00132 C19F 2C .BYTE *2C 00236 C238 00133 C1A0 11 FB NOPLOT ORA (4FB>,Y 00236 C239 00134 CIA2 91 FB STA <4FB>,Y 00236 C23A 00133 C1A4 LDA 401 ; 6 ASIC ROM RESTORED 00237 C23B .BYTE * 12,* 1A,*27,*2F 00136 C1A6 ORA #*01 00237 C23C 00137 C1A8 STA *01 00237 C23D 00138 CIAA RTS 00237 C23E 00139 Cl AB 00238 C23F .BYTE *31,*39,*04,*0C 00160 C1A6 TABIE1 .BYTE *00,440,480,*C0 00238 C240 00160 Cl AC 00238 C241 00160 Cl AO 00238 C242 00160 Cl AE 00239 C243 .BYTE * 33,*36,*06,*0E 00161 CIAF . bv it 0,*40,*00,4CO 00239 C244 00161 Cl BO 00239 C245 00161 C161 00239 C246 00161 C1B2 00240 C247 .6 YTE 421,*29,*14,*1C 00162 C1B3 .f t YTE 400, *40, *00, ICO 00240 C248 00162 C1B4 00240 C249 00162 CID3 00240 C24A 00241 00162 C 1 B6 C24B .BYTE *23,*2B,*16,*1E 00163 C1B7 .BYTE *00,*40,*80,ICO 00241 C24C 00163 C1B8 00241 C24D 00163 Cl 69 00241 C24E 00163 C16A 00242 C24F .BYTE 4 03,*O B ,4 36,* 3E 00164 C 166 .BYTE *00,*40,*00,*C0 00242 C250 00164 C1BC 00242 C251 00164 C1BD 00242 C2S2 00164 C16E 00243 C253 .BYTE *01,*09,*34,*3C 00163 C16F .BYTE *00,*40,*80,(C0,* 00243 C254 00163 CICO 00243 C255 00163 C1C1 00243 C256 00163 C1C2 00244 C257 .BYTE *13,* 16,*26,*2E 00163 C 1C3 00244 C258 00166 C1C4 00244 C259 00167 C1C4 TABLE2 .6 YTE *00,*01,*02,*03 00244 C25A 00167 C1C3 00243 C2SB .BYTE *11,*19,*24,*2C 00167 C1C6 00243 C25C 00167 C 1C 7 00243 C25D 00168 ClCB .6 YTE 405,*06,*07,*00 00245 C25E 00168 C1C9 00246 C25F .BYTE *32,*3A,*07,*0F 00168 C1CA 00246 C260 00168 ClCB 00246 C261 00169 circ .BYTE *0A,*06,*0C,*0D 00246 C262 00169 C1CD 00247 C263 .BYTE *30,*38,*05,*0D 00169 C1CE 00247 C264 00169 C1CF 0024 7 C265 Oei 70 Cl DO .6 YTE *0F,*10,411,*12 00247 C266 00170 C1D1 00248 C267 .BYTE *22,*2A,*17,*IF 00170 C 1 D2 00248 C268 00170 C1D3 00248 C269 00171 C1D4 .BYTE *14,*13,*16,*17 00248 C26A 00171 Cl 03 00249 C268 .BYTE *20,*28,* IS,* ID 00171 C 1 D6 00249 C26C 00171 C1D7 00249 C26D 00172 C1D8 .BYTE *19,*1A,*IB,*1C,*1E 00249 C26E 00172 C1D9 00250 C26F 00172 Cl DA 00172 C 1 DB 00172 Cl DC 00173 C1DD 00174 C1DD 001 73 Cl DD SYMBOL TABLE 00176 C1DD ; SHADING BY HYBRID DITHER/DOT-GROWTH 00177 C 1 DD I SYMBOL VALUE 00178 C 1 DD AD 3F 03 SHADE LDA XPLT ; USE BITS ----- *** CLEAR C12C CLRLP Cl 38 COL I Cl 1C COLOR Cl 10 00179 C 1 E0 29 07 AND #*07 | OF X ’ SCREEN COORD GREATR C1FC GRFOFF C 103 GRFON COE 2 HTORRN 0346 00180 C 1E2 8 D 48 03 STA TEMP MLPCND 00AC MLPLER 00AD MORE C20C Mill T C0 I 1 00181 C1E3 AD 4 1 03 LDA YPLT | AND B I T S ----- NOPLOT Cl AO NORM C224 NOSCAL 0347 ORIGIN C0E2 00182 CIE8 29 07 AND #*07 1 OF 'Y’ SCREEN COORD PLOT C143 PL0T2 Cl 94 PLOTLP C18E PLTFLG 033E C20F 00AE C0C8 00183 C1EA 0A ASL A | SHIFTED INTO — --- PLTSHD PROD RAM 033E RANDOM C1EB ASL A I POSITION TO DETERMINE RNDM C00O RPLT C22C RSHADE C1FF SCALE C214 00184 0348 00183 C1EC ASL A ; 6 -BIT OFFSET IN SHADE C 1 DD TABLE 1 C1AB TABLE2 C1C4 TEMP 0D 48 03 ORA TEMP » THRESHOLD TABLE THRESH C22F UNFLOT C. 1 46 VALUE 0344 VIC1 0342 00186 C 1 ED 0341 00187 C 1 F0 TAX VIC2 0343 XPLT 033F YPLT 00188 CIF1 BD 2F C2 LDA THRESH,X J SCREEN-POSITI ON-WEIGHTED 00189 C1F4 CD 44 03 CMP VALUE ; THRESHOl D VAl UE END OF ASSEMBLY End Listing Two 00190 C1F7 10 03 BFL GREATR 00191 C1F9 4C 46 Cl JMP UNF'l OT 00192 C1FC 4C 43 Cl GREATR JMP PLOT 00193 C1FF ( 00194 C1FF 00193 C1FF Listing Three 00196 C1FF SHADING BY RANDOM HALFTONE 00197 C1FF 00001 j FACET - DRAW SHADED TRIANGULAR FACETS 00198 C IFF RSHADE JSR RANDOM 0 00 02 I AND STRAIGHT LINES. 00199 C202 4A LSR A I RCDUCE RANDOM BYTE 00003 00200 C 20 5 4A LSR A ; TO 6 BITS FOR SHADE 00004 ; RICHARD L. RYLANDER 11/4/84 00201 C204 CD 44 03 CMP VALUE ; VALUE COMPARISON 00005 00202 C207 10 03 BPL MORE I LOAD "ARITH.HEX" AND "GRAPH.HEX" 00203 C209 4C 46 Cl JMP UNPLOT 00007 0000 I BEFORE USING 00204 C20C 4C 43 Cl MORE JMP PLOT 00203 C20F I 00206 C20F 0 0 0 1 0 00 00 00207 C20F I 0 0 0 1 1 0000 I 00208 C20F ; PLOT A POINT WEIGHTED BY SHADING SCHEME 0 0 0 1 2 0000 XPLT - *033F 00209 C20F j AND SHADE VALUE 00013 0000 YPLT - *0341 0 0210 C20F ; CHECK NOSCAL’ FLAG FOR SCALING OF Y COORD 00014 0000 NORM - *C224 0021 1 C20F ; CHECK 'HTORRN' FLAG FOR TYPE OF SHADING 00015 00 00 NOSCAL - *0347 C20F 00016 0000 C20F PLTSHD I DA NOSCAL 00017 0000 (Continued on page 66)
Dr. Dobb’s Journal, May 1985 64 379 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Three
0001 a 00147 C2EB 20 6 F C4 JSR FINDXY ENTRY POINT TO 00019 MLF'CND - «AC 00148 C2EE AO 4A 03 LDA XMIN OUTLINE FACETS 000 20 MLPLER - #AD 00149 C2F1 BD 3F 03 STA XPLT 00021 PROD -
66 Dr. Dobb’s Journal, May 1985 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Three
00273 C424 AD 53 03 DRAW LDA YTOP 00401 C533 AO 61 03 LDA FLAG3 00274 C427 BD 41 03 STA YPLT 00402 C536 BD 63 03 STA FLAG 00275 C42A 20 24 C2 JSR NORM i PLOT A SHADE-WEIGHTED 00403 C539 20 3C C4 JSR ENDPTS 00276 C42D AD 53 03 LDA YTOP { PIXEL CHECKING ONLY 00404 C53C BD 54 03 STA YBOT 00277 C430 CD 54 03 CMF YBOT | FOR SHADE STYLE 00403 C53F 20 BD C4 JSR VLINE 00278 C433 F 06 BEQ DONE 00406 C542 AD 40 03 LDA XPLTM 00279 C435 CE 53 03 DEC YTOP 00407 C345 CD 4E 03 CMP XMID*1 00280 C43B 4C 24 C4 JMP DRAW 00408 C548 00 BB BNE NEXTX1 00281 C43B 60 DONE RTS 00409 C54A AD 3F 03 LDA XPLT 00282 C43C * 00410 C54D CD 4D 03 CMP XMID 00284 C4 3C s 00412 C352 EE 3F 03 NEXTX1 INC XPLT 00285 C43C ; FIND ENDPOINTS FOR VERTICAL LINES 00413 CSSS D0 03 BNE SI.IP3 00286 C43C } BETWEEN FACET EDGES 00414 C557 EE 40 03 INC XPLT * 1 00287 C43C ; 004 15 C55A 4C FB C4 SKIP3 JMP FCETLP 00288 C43C AO 5F 03 ENDPTS LDA XDIFF 00416 C55D 38 CONT SEC 00289 C43F 85 AC STA MLPCND 00417 C53E AD 3F 03 LDA XPLT 00290 C441 AD 5E 03 LDA DELTAY 00418 CS61 ED 4A 03 SBC XMIN 00291 C444 AD STA MLPLER 00419 C564 BD 5F 03 STA XDIFF 00292 C446 20 1 1 C0 JSR MULT 00420 C567 AD 59 03 LDA DLTAX3 00293 C449 85 FE STA DVDND*1 00421 C56A F0 63 BEQ FINI 00294 C44B AS AE LDA PROD 00422 C56C QD SA 03 STA DELTAX 00295 C44D 83 FO STA DVDND 00423 CS6 F AD SD 03 I DA DLTAY3 00296 C44F A9 00 LDA «0 00424 C572 BO 5E 03 STA DELTAY 00297 C451 85 FC STA DVSOR*1 00425 C575 AD 62 03 LDA FLAG3 00298 C453 AD 5A 03 LDA DELTAX 00426 C578 BD 63 03 STA FLAG 00299 C456 85 FB STA DVSOR 00427 C57B AD 4C 03 LDA YMIN 00300 C458 20 25 C0 JSR DIVIDE 00428 C57E 80 55 03 STA YBASE 00301 C45B AD 63 03 LDA FLAG 00429 CS81 20 3C C4 JSR ENDPTS 00302 C45E D0 08 BNE NEGSLP 00430 C584 OD 54 03 ;;rA YBOT 00303 C460 18 CLC 00431 C387 38 SEC 00304 C461 AD 55 03 LDA YBASE 00432 CS88 AD 3F 03 LDA XPLT 00305 C464 65 FD ADC QUOT 00433 C38B ED 4D 03 BBC XMID 00306 C466 90 06 BCC SKIP2 00434 CS8 E 8 D SF 03 STA XDIFF 00307 C468 3B NEGSLP SEC 00435 C591 AD 38 03 LDA DLTAX2 00308 C469 AD 55 03 LDA YBASE 00436 C394 F0 39 BEQ FINI 00309 C46C E5 FD SBC QUOT 00437 C596 8 D 3A 03 STA DELTAX 00310 C46E 60 SKIP2 RTS 00438 C599 AD SC 03 LDA DLTAY2 0031 1 C46F 1 00439 C59C 8 D 5E 03 STA DELTAY 00312 C46F 00440 C39F AD 61 03 LDA FLAG2 00313 C46F 1 00441 C5A2 80 63 03 STA FLAG 00314 C46F 1 FIND COORDINATE DIFFERENCES 00442 C3A3 AD 4F 03 LDA YMID 00315 C46F 1 00443 CSAB 80 53 03 STA YBASE 00316 C46F ; ALL "DELTA X" VALUES POSITIVE, 00444 C5AB 20 3C C4 JSR ENDPTS 00317 C46F l SINGLE PRECISION 00394 C51F 20 3C C4 JSR ENDPTS 1300 1 2 MLPLER-fAD 00393 ; MULTIPLIER (S) C522 BD 53 03 STA YTOP 00013 PRQD=iAE } PPODUCT (0) 00396 C525 AD 59 03 LDA DLTAX3 MULT=*C011 00397 C528 F0 33 BEQ CONT j CALL FOR MULTIPLY 00398 C52A BD SA 03 STA DEL TAX DVDND-JFD 00399 C52D AD 50 03 LDA DLTAY3 I DIVIDEND
Dr. Dobb's Journal. M ay 1985 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Four
0 0 0 17 000a DVS0R-4FB I DIVISOR (D> 00146 C628 ZWX-*2«Z- XSHD QU0T-4FD I QUOTIENT (D) 001 4 7 C628 XPI T-XCENT-XREl s REM I EFT HEMISPHERE 00019 DIVIDE-4C025 i CALL FOR DIVIDE 00148 C628 IF YREl . CLIF'LI THEN GOTO DHFNI 00020 » 00149 C628 TONE=ZWX*YSHD 00021 ARG-4AC I ARGUMENT 00150 C628 GOSUB GETVAL s REM NORMAI 17E SHADE VAI. 0 0 0 2 2 SQR-4AE I SQUARE OF ARQ 00153 C628 TONE -»Z WX - YSHD 00027 SQRT-4C064 I CALL FOR SQRT 00136 C628 GOSUB GETVAL 00029 00157 C628 YPLT-YCENT-YREL 00029 RNDM-4C000 | RANDOM NUMBER 00158 C628 GOSUB PLTSHD' 00030 RANDOM=»C0C8 t CALL FOR RANDOM 00159 C628 IF HEM1-0 THEN RETURN 00031 ; NOTE - A CALL TO RANDOM' LEAVES A RANDOM BYTE 00160 C628 HEMI-0 00032 I IN THE ACCUMULATOR 00161 C628 IF XREL --CL I PR THEN RETURN 00033 I 0 0 16 2 C628 ZWX Z♦XSHD 00034 XPLT--4033F 00163 C628 XPLT*-XCENT* XREL 00035 YPLT-*034 I 00164 C628 GOSUB 'CHCLUP' 00036 NORM-4C224 00165 C628 RL TURN 00037 PLTSHD-4C20F 00166 C628 VALUE-40344 5 FINAL NORMALIZED SHADE VALUE 00167 C628 PTPLOT BIT HVFLAG 00039 0000 HTORRN= 40346 ; SHADE FLAG, t-HALFTONE 00168 C62B BPL NOROT NOSCAL“40347 ; SCALE FLAG, 1-NO SCALE 00169 C62D AD 6 C a LDA XREL 00041 1 001 70 C630 PHA 00042 -RAM 00171 C631 PHA 00043 036A XCENT » CENTER COORD 00172 C632 AD 70 03 LDA YREL 00044 036C XREL S RELATIVE (TO CENTER) 00173 C635 8 D 6 C 03 STA XREL 00043 0360 XSHO I USED IN SHADE CALC 00174 C638 PLA 00046 036F YCENT j CENTER CfJORD 00173 C639 STA 0004 7 0370 YREL I RELATIVE (TO CENTER) 001 76 C63C LDA 0004B 0371 YSHD I USED IN SHADE CALC 00177 C63F PHA 00049 0373 ZREL t RELATIVE (TO CENTER) 00178 C640 PHA 00050 0375 ZWX I Z WITH X (* OR -> 00179 C641 LDA 00031 0377 I 00180 C644 STA 00032 0377 { LOCAL RADIUS OF SURFACE 00181 C647 PLA 00053 0379 j USED IN SHADE CALC 00182 C648 STA 037B TNTMP • I USED IN SHADE CALC 00183 C64B LDA 0370 I 00184 C64E PHA 0370 CL I PL ; LEFT CLIPPING BOUND 00183 C64F PHA 037E CL I PR } RIGHT Cl T PPI Nil HOUND 00186 C650 LDA 037F CLIPU I UP LIIPP1NG BOUND 00187 C653 STA 0 380 Cl-IPD j DOWN Cl IPFING BOUND 00188 C656 68 PLA 0381 00189 C657 BD 72 03 STA YSHD*1 00061 0381 HEM I 5 PLOTTING HEMISPHERE 00190 C65A 20 45 C7 NOROT JSR GETZ 00062 0382 00191 C65D A9 01 PTPLT2 LDA #401 00063 0382 UAH IT ; BACKLIT f I AG 00192 C65F 8 D 81 03 STA HEM I 00064 0383 HV'Kl AG ; HUR17ONTAl./VER TIG Al. FLAG 00193 C662 38 SEC 00065 0384 1LMP ; TEMPORARY STORAGE , 00194 C663 AD 7D 03 LDA CL I PL I CHECK I EFT HEMISPHERE 00066 0386 C.NTX j I OOP COUNTER 00193 C666 CD 6 C 03 CMP XREL 0387 CNI Y S I OOP COUNTER 00196 C669 90 7D BCC RHEMI 0388 MAX 5 I OOP 1. IMI 1 00197 C6 6 B 38 SEC 0389 00198 C6 6 C AD 3C 03 LDA ROOT 000 70 0389 HI.FN 5 HAi F I ENG IH OF CYLINDERS 00199 C66 F ED 6 D 03 SBC XSHD 0007 1 038A ; SQUARE 0» TOROID RADIUS 0 02 00 C672 8 D 75 03 STA ZWX 00072 03BC ; TOROID (RING) RADIUS 00201 C673 AD 3D 03 LDA ROOT * 1 00073 0 sun 5 Cl MU R RAD I UR Ol TOROID 0 02 02 C678 ED 6 E 03 SBC XSHD*1 000 74 0 38E S UUIt-.R RADIUS OT 1 OROl D 00203 C67B BD 76 03 STA ZWX* 1 000 75 03UF ; INNtR RADIUS OF TOROID 00204 C67E 38 SEC 00076 0390 00203 C67F AD 6 A 03 LDA XCENT 00077 0392 00206 C682 ED 6 C 03 SBC XREL 0393 00207 C683 8 D 3F 03 STA XPLT 00079 0393 C688 AD 6 B 03 LDA XCENT*1 0393 00209 C6 BB E9 00 SBC #400 00061 0393 0 0 2 10 C6 8 D 8 D 40 03 STA XPLT+1 00082 C5EA 0021 I C690 ( 00083 C5EA 0 0 2 12 C690 38 CHCLUP SEC 00084 C5EA j DIVIDE WITH SINGLE PRECISION DIVISOR 00213 C691 AD 7F 03 LDA CLIPU ; CHECK FOR UP CLIPPING 00085 C5EA ! (USED OFTEN IN SHAPE RUUTINFS) 00214 C694 CD 70 03 CMP YREl. C3F.A 00213 C697 90 23 BCC DHEMI 00087 C5CA LDA N0 00216 C699 18 CLC 00088 C5EC 85 FC STA DVSOR*1 00217 C69A AD 75 03 LDA ZWX 00089 C5LE 4C 25 C0 JMP DIVIDE 00218 C69D 6 D 71 03 ADC YSHD C5F1 00219 C6A0 8 D 79 03 STA TONE 00091 C3F1 0 02 20 C6A3 AD 76 03 LDA ZWX* 1 00092 C5F1 00221 C6A6 6 D 72 03 ADC YSHD*1 00093 C5F1 i CALCULATE SHADE VALUE <0 63) BY 0 02 22 C6A9 8 D 7A 03 STA TONCU C5F1 5 MULTIPLYING TONE' BV 26 THEN 00223 C6 AC 20 FI C5 JSR GE TVAL 00095 C3F1 ; DIVIDE RESULT BY RADIUS OK SURFACE 00224 C6 AF 18 CLC 00096 C5F1 I 00225 C6B0 AD 6 F 03 LDA YCENT 00097 C5F1 2C 7A 03 GETVAL BIT TONEH 00226 C6B3 6 D 70 03 ADC YREL C5F4 10 12 BF'L CNTNU ; IF TONE' 0, THEN 00227 C6 B6 8 D 41 03 STA YPLT C5F6 AD 82 03 LDA BAI L IT ; MAI E VALUE 0 OR ABS(TONE) 00228 C6B9 20 0F C2 JSR PLTSHD 00100 C5F9 D0 04 BNE NEGATE I DEPENDINO ON BAH 1T FLAG 00229 C6 BC I 00101 C5FB BD 44 03 STA VALUE 00230 C6 BC 38 DHEMI SEC 00102 C5FE 60 RTS 00231 C6 BD AD 80 03 LDA CL I F D j CHECK FOR DOWN CLIPPING 00103 C5FF 30 NEGATE SEC 00232 C6C0 CD 70 03 CMP YREL 00104 C600 A9 00 LDA #4 00 00233 C6C3 90 23 BCC RHEMI 00105 C602 ED 79 03 SBC TONE 00234 C6C5 38 SEC 00106 C603 8 D 79 03 STA TONE 00233 C6 C6 AD 75 03 LDA ZWX 00107 C608 AD 79 03 CNTNU LDA TONE 00236 C6C9 ED 71 03 SBC YSHD 00108 C60B 85 AC STA MLPCND 00237 C6 CC 8 D 79 03 STA TONE 00109 C60O A9 1A LDA #-41A 00238 C6 CF AD 76 03 I DA ZWX*l 001 10 C60F 85 AD STA MLF'LER 00239 C6D2 ED 72 03 SBC YSHD*1 001 1 1 C611 20 11 C0 JSR MULT 00240 C6D5 8 D 7A 03 STA TONE*1 0 0 1 12 C614 85 FE STA DVDND*1 00241 C6 D8 20 FI C5 JSR GETVAL 001 13 C616 A5 AE LDA PROD 00242 C6 DB 38 SEC 001 14 C618 85 FD STA DVDND 00243 C6 DC AD 6 F 03 LD« YCENT 001 13 C61A AD 77 03 LDA RADIUS 0024 4 C6 DF ED 70 03 SBC YREL 0 0 1 16 C61D 85 FB STA DVSOR 00245 C6E2 8 D 41 0 3 STA YPLT 001 17 C61F 20 EA C5 JSR SDIV 00246 C6E5 20 0F C2 JSR PLTSHD 001 IB C622 A5 FD LDA QUOT 00247 C6 E8 < 001 19 C624 BD 44 03 STA VALUE 00248 C6 E8 AD 81 03 RHEMI LDA lirMI 0 0 12 0 C627 60 RTS 00249 C6 EB F0 34 BEQ PLDONE 0 0 1 2 1 C628 I 00250 C6 ED CE 81 03 DEC HEM I 00122 C628 00231 C6F0 38 SEC 00123 C628 00232 C6 F I AD 7E 03 I DA CL I PR j CHECK FOR RIGHT CLIPPING 00124 C628 00233 C6F4 CD 6 C 03 CMP XREL 00125 C628 00234 C6F7 90 28 BCC PLDONE 00126 C62B 00253 C6F9 18 CLC 00127 C628 DEPENDING ON STATUS OF "HVFLAG', EXCHANGE 00236 C6 FA AD 3C 03 LDA ROOT 00128 C628 X AND Y COORDINATES TO ROTATE OBJECTS 90 DEG 00257 C6 FD 6 D 6 D 03 ADC XSHD 00129 C62B SINGLE SHAPE F
70 Dr. Dobb's Journal, May 1985 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Four
00272 C726 AD 6 E 03 LDA XSHD*1 ; RESTORE COORDS 00401 C80D 80 6 C 03 STA XREL 00273 C729 8 D 7203 STA YSHD*1 00402 C810 OD 6 D 03 STA XSHD 00274 C72C 68 FLA 9 00403 C813 20 04 C0 JSR SQUARE 00273 C72D OD 6 E 03 STA XSHD*1 00404 C816 38 SEC 00276 C730 AD 6 D 03 LDA XSHD 00405 C817 AD 84 03 LDA TEMP 00277 C733 BD 71 03 STA YSHD 00406 C81A E5 AE SBC SQR 00278 C736 68 PLA 00407 C81C 85 AC STA RADCND 00279 C737 BD 6 D 03 STA XSHD 00408 CB1E AD 85 03 LDA TEMP*1 00280 C73A AD 6 C 03 LDA XREL 00409 CB21 E5 AF SBC SQR* 1 00281 C73D OD 70 03 STA YREL 004 10 C823 85 AD STA RADCND*1 00282 C740 6 9 FLA 00411 C825 20 64 C0 JSR SQRT 00283 C741 BD 6 C 03 STA XREL 00412 C828 AD 3C 03 LDA ROOT 00284 C744 60 NORSTR RTS 00413 C82B BD 88 03 STA MAX 00283 C745 1 00414 C82E AD 87 03 LOOPY LDA CNTY 00286 C745 00415 C831 8 D 70 03 STA YREL 00287 C745 t 00416 CB34 8 D 71 03 STA YSHD 00288 C745 I CALCULATE Z FROM LOCAL X.Y BY 00417 C837 A9 00 LDA H0 00289 C745 1 PYTHAGOREAN SUM 004 18 C839 BD 83 03 STA HVFLAG 00290 C745 I 00419 C83C 20 28 C6 JSR PTPLOT 00291 C745 AD 77 03 GETZ LDA RADIUS 00420 C83F A9 80 LDA (U80 00292 C748 85 AC STA ARG 00421 C841 8 D 83 03 STA HVFLAG 00293 C74A 20 0 4 C0 JSR SQUARE 00422 C844 20 28 C6 JSR PTPLOT 00294 C74D BO 7C 03 STA TNTMP*1 00423 C847 AD 87 03 LDA CNTY 00295 C750 A5 AE LDA SQR 00424 C84A CD 88 03 CMP MAX 00296 C752 BD 7B 0 7. STA TNTMP 00425 C84D F0 06 BEQ DONEY 00297 C755 AD 6 D 03 LDA XSHD 00426 C84F EE 87 03 INC CNTY 00298 C758 BS AC STA ARG 00427 C852 4C 2E C8 JMP LOOPY 00299 C75A 20 04 C0 JSR SQUARE 00428 C855 AD 86 03 DONEY LDA CNTX 00300 C75D 30 SEC 00429 C85B CD 92 03 CMP XMAX 00301 C75E AD 7B 03 LDA TNTMP 00430 CB5B F 0 06 BEQ DONE 00302 C761 E5 AE SBC SQR 00431 C85D EE B6 03 INC CNTX 00303 C763 8 D 7B 03 STA TNTMP 00432 C860 4C 05 CB JMP LOOPX 00304 C766 AD 7C 03 LDA TNTMP*1 00433 C863 68 DONE RTS 00305 C769 E5 AF SBC SQR* 1 00434 CB64 1 TNTMP*1 00307 C76E AD 71 03 LDA YSHD 00436 C864 00308 C771 85 AC STA ARG 00437 C864 ; DRAW SHADED CYLINDERS 00309 C773 20 04 C0 JSR SQUARE 00438 C864 00310 C776 38 SEC 00439 C864 ; 'BASIC SUBROUTINE' EQUIVALENT 003 1 1 C777 AD 7B 03 LDA TNTMP 00440 CB64 00312 C77A E5 AE SBC SQR 00441 C864 1 CYLNDR' XSHD-0 00313 C77C 85 AC STA RADCND 00442 CB64 1 FOR YREL-RADIUS TO 0 00314 C77E AD 7C 03 LDA TNTMP*1 00443 C864 YSHD-YREL 00315 C781 ES AF SHC SQR* 1 00444 C864 I FOR XREL-HLEN TO 0 00316 C783 85 AO STA RADCND*1 00445 CB64 ; GOSUB PTPLOT' 00317 C785 30 0A BMI ZEROOT 00446 C864 » NEXT XREL 00318 C787 20 64 C0 JSR SQRT 00447 C864 ; NEXT YREL 00319 C78A 0E 3C 03 ASL ROOI 00448 C864 i RETURN 00320 C78D 2E 3D 03 ROL ROOT *1 00449 C864 00321 C790 60 RTS 00450 CS64 A9 00 CYLNDR LDA N0 00322 C791 A9 00 ZEROOT LDA N*00 00451 C866 BD 6 D 03 STA XSHD 00323 C793 8 D 3C 03 STA ROOT 00452 CB69 8 D 6 E 03 STA XSHD*1 00324 C796 BD 3D 03 STA ROOT*1 00453 C8 6 C BD 72 03 STA YSHD*1 00325 C799 60 RTS 00454 C86 F AD 77 03 LDA RADIUS 00326 C79A 1 00455 CB72 BD 70 03 STA YREL 00327 C79A 00456 C875 AD 89 03 CYLOOP LDA HLEN 00328 C79A ; 00457 CB78 8 D 6 C 03 STA XREL 00329 C79A ; SET UP PARAMETERS FOR TOROIDS 00458 CB7B AD 70 03 LDA YREL 00330 C79A i 00459 C87E BD 71 03 STA YSHD 00331 C79A s RT-(RO-RI)/2 RS*RT«RT RC-=RT*R1 00460 C881 28 28 C6 CXLOOP JSR PTPLOT 00332 C79A I 00461 C884 CE 6 C 03 DEC XREL 00333 C79A AD BE 03 TPARM LDA RO 00462 C887 10 F8 BPL CXLOOP 00334 C79D 38 SEC 00463 C889 CE 70 03 DEC YREL 00335 C79E ED 8 F 03 SBC RI 00464 C8 8C 10 E7 BPL CYLOOP 00336 C7A1 4A LSR A 00465 C8 8 E 60 RTS 00337 C7A2 BD 8 C 03 STA RT 00466 C8 8F I 00338 C7A5 BD 77 03 STA RADIUS 00467 C88 F 00339 C7A8 18 CLC 00468 C88F ( 00340 C7A9 6 D BF 03 ADC RI 00469 C8 BF • DRAW EDGE-VIEW TOROIDS 00341 C7AC 8 D BD 03 STA RC 00470 C8 8F 00342 C7AF AD BC 03 LDA RT 00471 C8 8 F 1 BASIC SUBROUTINE' EQUIVALENT 00343 C7B2 85 AC STA ARG 004 72 C8 8F 00344 C7B4 20 04 C0 JSR SQUARE 00473 C88 F j EDGTOR' GOSUB 'TPARM'I REM SET UP RADII 00345 C7B7 A5 AE LDA SQR 00474 C8 8F » FOR CNT X=0 TO RT 00346 C7B9 BD BA 03 STA RS 00475 CB8 F ; XREL-CNTX:XSHD-CNTX 00347 C7pC A5 AF LDA SQR* 1 00476 C8 8F R0-SQR(RT*RT-CNTX«CNTX) 00348 C7BE 8 D 8 B 03 STA RS* 1 00477 C8 BF » FOR CNTY-0 TO RO+RC 00349 C7C1 A9 00 LDA M0 00478 C8 BF YREL-CNTY 00350 C7C3 III; 86 03 STA CNTX 00479 C8 8 F YSHD-(R0*CNTY)/
Dr. Dobb's Journal, May 1985 72 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Four
00329 C9FD 4C CC CB JMP LOOPY4 00657 C9F8 AD 89 03 LDA 00529 C900 AD 86 03 DONE4 LDA CNTX 00658 C9FB 85 FB STA 00330 C903 CD BC 03 CMP RT 00659 C9FD 20 EA C5 JSR 00331 C906 F0 06 BEQ DONEHT 00660 CA00 38 SEC 00332 C909 EE B6 03 INC CNTX 00661 CA01 AD 87 03 LDA CNTY 00333 C90B 4C 9A CB JMP LOOPX4 00662 CA04 ES FD SBC QUOT 00334 C90E DONEHT RTS 00663 CA06 8 D 71 03 STA YSHD 00535 C90F 00664 CA09 A9 00 LDA #*0 0 00336 C90F 00665 CAOB 8 D 83 03 STA HVFLAG 00337 C90F 00666 CA0E ES FE SBC 0U0T*1 00539 C90F DRAW A SHADED, TOP-VIEW TOROID 00667 CA10 8 D 72 03 STA YSHD*1 00339 C90F 00668 CA13 20 28 C6 JSR PTPLOT 00540 C90F BASIC SUBROUTINE' EQUIVALENT 00669 CA16 A9 80 LDA *480 0034 1 C90F 00670 CA18 BD 83 03 STA HVFLAG 00542 C90F TOROID' GOSUB 'TPARM' 00671 CA1B 20 28 C6 JSR PTPLOT 00543 C90F FOR CNTX-0 TO R0/S0R(2) 00672 CA1E AD 87 03 LDA CNTY 00544 C90F REM 8 -FOLD SYMMETRY USED 00673 CA21 CD 88 03 CMP MAX 00545 C90F XREL-CNTX 00674 CA24 F0 06 BEQ DDNY 1 00546 C90F MAX«SQR(RO»RO-CNTX»CNTX> 00675 CA26 EE 87 03 INC CNTY 0054 7 C90F IF CNTX >RI THEN GOTO GRTR* 00676 CA29 4C 9A C9 JMP LLPYI 00549 C90F CNTY«SQR(RI*RI-CNTY«CNTY> 00677 CA2C AD 86 03 DDNY1 LDA CNTX 00549 C90F GOTO 'LLPY1' 00679 CA2F CD 92 03 CMP XMAX 00550 C90F GRTR' CNTY-CNTX 00679 CA32 F0 06 BEQ DUNTOR 00551 C90F 'LLPYI' YREL-CNTY 00680 CA34 EE 86 03 INC CNTX 00332 C90F R0-SQR
74 Dr. Dobb's Journal, May 1985 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Four
NORSTR C744 0347 ORIGIN CSEA PLDONE C721 PLTSHD C20F 00AE PTPLOT C628 PTPLT2 C65D QUOT 0 0 FD 0389 RADCND 00AC RADIUS 0377 I SET CENTER COORDINATES RAM 036A C0C8 RC 038D RHEMI C6 E8 » RI 038F COO0 RO 038E ROOT 033C 0 01 15 CAFB 20 C8 CA CENTER JSR GETNUM RS 038A RT 03BC SD1V CSEA SPHERE C7C7 0 01 16 CAFE 8 C 6 A 03 STY XCENT SPOOL CA3B SQR 00AE SQRT C064 SQUARE C004 00117 CB01 8 D 6 B 03 STA XCENT*1 TEMP 0384 TNTMP 037B TONE 0379 TOROID C90F 201 18 CB04 20 C8 CA JSR GETNUM TPARM C79A VALUE 0344 XCENT 036A XMAX 039: 0 01 19 CB07 8 C 6 F 03 STY YCENT XPLT 033F XREL 036C XSHD 036D XSQR 0390 0 01 20 CBOA 60 RTS YCENT 036F YPLT 0341 YREL 0370 YSHD 0371 00121CB0B ZEROOT C791 ZREL 0373 ZWX 0375 00122CB0B 0 0 1 2 3 CBOB END OF ASSEMBLY 001 24 CBOB CLEAR THE BITMAP, FILLING WITH (OPTIONAL) 00125 CBOB FILL VALUE SPECIFIED OR WITH (DEFAULT) "0" 001 26 CBOB 0 01 27 CBOB 20 D2 CA CLEAR2 JSR PCHECK O012B CBOE 24 FB BIT DEFLAG Listing Five 0 01 29 CB10 30 07 BMI DEFCLR 001 30 CB12 20 9E AD JSR EVAEXP INTERFACE - EASY PARAMETER SETTING FOR SHAPE 5 00131 CB15 20 AA B1 { DRAWING ROUTINES FROM BASIC. JSR FLTFIX 00132 CB18 2C 00003 0000 .BYTE *2C 0 0 1 3 3 C&19 AO 00 00004 0000 j RICHARD L. RYLANDER 11/23/B4 DEFCLR LDY #0 00134 CB1B 00003 0000 BC 35 Cl STY CLRBYT 00135 CB1E 4C 2C Cl JMP CLEARR 00136 CB21 > 00137 CB21 00138 CB21 I 00010 PARAMETER LOCATIONS FOR VARIOUS SHAPES 00139 CB21 I FILL COLOR MAP WITH (OPTIONAL) COLOR BYTE 0001 1 001 40 CB21 ; SPEC IF IF.D OR WITH (DEFAULT) "*01" 00012 XCENT -*036A 00141 CB21 ; (BLACK DOTS ON WHITE BACKGROUND) 00013 YCENT -*036F 001 42 CB21 I 00014 XPLOT “J033F 00143 CB21 20 D2 CA C0L0R2 JSR PCHECK 001 44 CB24 00013 YPLOT -*0341 24 FB BIT DEFLAG 00016 XMIN -*034A 0 0 1 4 5 CB26 30 07 BMI DEFCOL 00017 YMIN -»034C 0 0 1 4 6 CB2B 20 9E AD JSR EVAEXP 00018 XMID -*034D 0 01 47 CB2B 20 AA B1 JSR FLTFIX 001 48 CB2E 2C 000 19 YMID «*034F .BYTE *2C 0 01 49 CB2F A0 01 000 20 XMAX -*0350 DEFCOL l.DY #*01 YMAX “*0352 001 50 CB31 8 C 19 Cl STY COLBYT 00021 00151 CB34 4C 18 Cl JMP COLORR 00022 RADIUS -10377 CB37 00023 HLEN “*0389 001 52 00024 RI -*038F 0 01 53 CB37 00154 CB37 00023 RU -*038E 00026 0 01 55 CB37 PLOT OR UNPLOT POINTS 00027 HVFLAG -*0383 00156 CB37 00028 VALUE -*0344 00157 CB37 -0T2 LDA #0 00029 PLTFLG =*033E 001 58 CB39 .BYTE *2C 00159 CB3A A9 80 JPLT2 LDA #*80 CB3C 00031 DEFLAG -SFB 001 60 BD 3E 03 STA PLTFLG 00032 00161 CB3F 20 C8 CA JSR GETNUM 00033 001 62 CB42 BC 3F 03 STY XPLOT 00163 CB45 8 D 40 03 STA XPLOT*1 00034 00164 CB48 ; FUNCTION LOCATIONS 20 C8 CA JSR GETNUM 00035 00165 CB4B BC 41 03 00036 STY YPLOT 00166 CB4E 4C 4B Cl JMP PLOTR 00037 I SWITCH TO GRAPHICS MODE 00167 ; RETURN TO TEXT DISPLAY CB51 00168 CB51 00039 0000 00169 CBS 1 CLEARR-*C12C | CLEAR BITMAP 00170 CBSl ; DRAW LINES BETWEEN (X1,Y1) AND (X2,Y2> 0004 1 CLRBYT-*C135 I CLEAR
Dr. Dobb's Journal, May 1985 76 sak Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Five
00238 CBCB 20 AA 61 JSR FLTFIX 330 POKE 198,0:WAIT 198,1«P0KE 198,0 00239 CBCE 8C 77 03 STY RADIUS 540 REM WAIT FOR A KEY TO BE PRESSED 00240 CBD1 20 C8 CA JSR GETNUM 550 I 00241 CBD4 8C 89 03 STY HLEN 560 REM DRAW TWO "GOBLETS" ONE WITH HALFTONE, THE OTHER RANDOM SHADING. 00242 CBD7 4C 64 C8 SKIP2 JMP CYLNDR 570 i 00243 CBDA 5B0 SYS(CL)«SYS(CO),16*11+1 00244 CBOA 582 RW-14j CM-15:A*-"COMPARI SON":GOSUB 1900:RW*15:CM-19iA*-"OF":GOSUB 1900 00243 CBDA 584 RW-16s CM-14:A*-"SHADE STYLES"»GOSUB 1900:RW-18:CM-14:A»-"<— HALFTONE” 00246 CBDA DRAW EDGE-VIEW TOROIDS WITH AXES HORIZONTAL 586 GOSUB 1900:RW-20:CM-15:A#-"RANDOM — >":GOSUB 1900 00247 CBDA OR VERTICAL 590 POKE LB,255:POKE RB,255:POKE UB,49:P0KE DB.255: REM CLIP AT SCREEN TOP 00248 CBDA INNNER AND OUTER RADII ARC OPTIONAL 600 SYS(SP),80,190,e0 00249 CBDA 610 POKE UB,51iPOKE DB,51: REM CLIP AT JUNCTION WITH SPHERE FOR SMOOTH SEAM 00230 CBDA A9 80 rOR2 LDA H*B0 620 SYS(VS),80,69,10,130 00231 CBDC 2C .BYTE < 2C 630 POKE DB,9« POKE UB ,8 002S2 CBDD A9 00 rOR2 LDA *0 640 SYS(VT),80,9,25,45 00233 CBDF 8 D 83 03 STA HVFLAG 650 POKE SH,0 sREM SWITCH TO RANDOM SHADING 00234 CBE2 20 FB CA JSR CENTER 660 POKE LB,255:POKE RB,253:POKE UB,49:POKE DB,253 00235 CBE3 20 E4 CA JSR GETTWO 670 SYS(SP),240,190,80 00256 CBE8 4C 8 F C8 JMP EDGTOR 6B0 POKE UB ,51: F'OI E DD,51 00257 CBEB 690 SYS(VS),240,69,10,130 00258 CBEB 700 POKE DB,9:P0KE UB,8 00259 CBEB 710 SYS(VT),240,9,25,45 00260 CBEB I DRAW INS1DE-VIEW TOROIDS, “SPOOLS", 720 POKE 198,0:WAIT 198,1:P0KE 198,0 00261 CBEB i WITH AXES HORIZONTAL OR VERTICAL 740 : 0262 CBEB 5 INNER AND OUTER RADII ARE OPTIONAL 750 REM DRAW "WINE" SCENE 00263 CBEB i 760 POKE LT,1 :REM BACKLIT ILLUMINATION 00264 CBEB A9 80 VSPL2 LDA »*80 770 POKE SH,1 :REM HALFTONE SHADING FOR MOST (RANDOM "LABEL" ON BOTTLE) 00265 CBED 2C .bYTE 12C SYS(CO):SYS(CL),255: REM FILL BITMAP WITH I S ("SET" BACKGROUND) 00266 CBEE A9 00 HSPL2 LDA *0 790 POKE 60,0 : REM BLACK BORDER TO MATCH BACKGROUND 00267 CBF0 8 D 83 03 STA HVFLAG 792 RW-0!CM=0:MD-2:A*-"DRAWING WITH":GOSUB 1900:RW-1:CM-2:A*="BACKLIGHT" 00268 CBF3 20 FB CA JSR CENTER 794 GOSUB 1900 s RW-2:CM-0:A#="AGAINST A SET":GOSUB 1900 00269 CBF6 20 E4 CA JSR GETTWO 796 RW«3« CM-2:A*-"BACK GROUND":GOSUB 1900 00270 CBF9 4C 3B CA JMP SPOOLR 798 RW-1iCM-26:A*="COLORS ADDED":GOSUB 1900 00271 CBFC RW-2«CM-25:A*-"T0 SELECT AREAS":GOSUB 1900 REM DRAW DOTTLE POKE UB,0iPOKE DB,255:POKE LB,255:POKE RB,255 830 SYS(VT),150,10,30,50 840 POKE UB,255:SYS(VC),150,70,50,60 SYMBOL TABLE 850 POKE DB,0:SYS(VT),150,130,6,50 G60 POKE DB,55:POKE UB,0«SYS(VS),150,204,13,181 SYMBOL VALUE 870 POKE UB,255:SYS(VC),150,221,16,17 CENTER CAFB CHI COM AEFD CLEAR2 CB0B CLEARR C12C CLRBYT Cl 33 COLBYT Cl 19 COLOR2 CB21 COLORR Cl 18 I REM DRAW WINE GLASS CYLNDR C864 DEFCLR CD19 DEFCOL CB2F DEFLAG 00FB POKE UB,20:SYS(SP),B0,120,60 DFAULT CAFA EDGTOR C8 8 F EVAEXP AD9E FACET2 CB54 i POKE UB,33iPOKE DB,34:SYS(VS),80,34,1( , 1 1 0 FACETR C4E1 PLTFIX B1 AA GETNUM CACB GETTWO CAE4 GRFOFF C103 GRFON C0E2 HCYL2 CBB9 HLEN 0389 REM DRAW SOME GRAPES HSFL2 CBEE HT0R2 CBDD HVFLAG 0383 LDRAW CB94 SYS(SF),8 ,8 ,8 : REM OTHER "GRAPES" WILL BE SAME RADIUS - JUST GIVE POSITIONS LINE2 CB51 LINER C2DB LINFAC 0393 NOMORE CADF 950 SYS(SP),20,8:SYS(SP) ,40,8: SYS(SP),12,20:SYS(SP),30,20:SYS(SF ),25,16 ORIGIN CAC8 PCHECK CAD2 FL0T2 CB37 PLOTR C14B 960 i PLTFLG 033E RAD I US 0377 RAM 0393 RI 038F 970 REM DRAW AN APPLE BY A PAIR OF EDGE-VIEW TOROIDS AND A SPHERE SECTION RO 03DE SKIP1 CBAA SKIF2 CBD7 SFHER2 CB97 POKE UB,233:POKE DB,255:POKE LB,255:POKE RB,59 SPHERR C7C7 SF'OOLR CA3B TORUS2 CBAD TORUSR C90F SYS(VT),260,29,0,50:SYS(VT),260,79 UNPLT2 CB3A VALUE 0344 VCYL2 CBB6 VSPL2 CBEB POKE UB,43:POKE DB,43:SYS(SP),260,54,60 VTOR2 CBDA XCENT 036A XMAX 0350 XMID 034D REM PUT STEM ON APPLE XMIN 034A XPLOT 033F YCENT 036F YMAX 0352 POKE RB,0:POKE DB,0:SYS(TR),272,104,10,15 YMID 034F YMIN 034C YF'LOT 0341 REM ADD A LEAF BY A SPHERE SECTION POKE DB,235iPOKE RB,0:SYS(SP),256,119,15 END OF ASSEMBLY REM ADD A RANDOM SHADED "LABEL" TO THE BOTTLE End Listing Five POKE UB, 255: POKE RB,2551 POKE LB, 6 1070 POKE,SH,0:SYS(VC),150,72,30,40 1080 i 1090 REM ADD COLORS TO "WINE" SCENE Listing Six 1 100 SYS(CO),12:REM REPLACE WHITE "HOLES" (BACKGROUND) WITH MEDIUM GRAY 1102 Xl-01Yl-200:X2-100:Y2-239:DC-0:BC=0:GOSUB 1700:REM HIDE TEXT IN CORNERS 10 REM SHAPES DEMO 1 104 X1-180:Y1-200:X2=319:Y2-239:DC-0:BC-0:GOSUB 1700 20 : 1110 X1-200:YI-I:X2-315:Y2S100:DC=0:BC-2:GOSUB 1700 30 REM RICHARD L. RYLANDER 11/23/84
78 Dr. Dobb’s Journal, May 1985 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Six
1760 POKE 34752*IX-40*IY,CC 900 REM DRAW FACETS lACCORDING TO Z DEPTH SINCE NOT CONVEX) 1770 NEXTiNEXTjRETURN 910 SYS 10 REM "STELLATION' DRAW A SMALL STELLATED DODECAHEDRON If VARIOUS ORIENTATIONS 20 REM AND STYLES RICHARD L. RYLANDER 12/5/84 Listing Eight 30 40 GR=49378 :REM GRAPHICS MODE 0 1 ; KEYSORT - RELOCATABLE BUBBLE SORT USING KEY ARRAY 50 TX =494 1 1 :REM TEXT MODE ; POINTING TO INTEGER ARRAY 60 BO-53280 :REM BORDER COLOR 00003 0000 70 : 00004 0000 RICHARD L. RYLANDER 1/12/85 80 REM INITIALIZE A FEW STYLE PARAMETERS 00005 0000 90 POKE 839,1 :REM SCALE <3:4) FOR UNDISTORTED SCREEN DISPLAY 00006 0000 OR IGIN=4'CF59 ; 53081. (FOLLOWING DOS 5.1) 100 POKE 871,0 :REM FACET EDGE/LINE MODE (0=DRAW, 1“ERASE > 00007 0000 110 SH“87.8 : REM SHADE STYLE (0-RANDUM, 1-HALFTONE) KB ' *FB ; 251. POINTER TO KEY ARRAY 120 EG= 868 :REM EDGES FLAG (0=NORMAL, 1=ADD LINES TO FACET EDGES) ZB > * FD 1 253. POINTER TO DATA ARRAY 130 : MAX ' tec ; 140. POKE WITH MAX ARRAY INDEX 140 REM FUNCTION LOCATIONS TOP ■ 4 AC 150 CL-51979 :REM CLEAR BITMAP TOPDIS > *AD 160 CO=52001 :REM FILL COLOR MAP FLAG ■ 4AE 170 FC“52052 :REM DRAW A SHADED FACET NXTFLG > 461 180 KS=53081 :REM DO )EYED SORT CRRNT ■ *62 190 » 16 REPEAT = 464 200 XC=160:YC“ 12C :REM (SCALED) SCREEN CENTER COORDINATES 17 2 1 0 s ■OR IGI 220 PRINT"(SC> ***»#***#********#*»****#**•*««#" 00019 CF59 230 PRINT" * SMALL STELLATED DODECAHEDRON «" 0 0020 CF59 INIT LDY } INITIALIZE KEY ARRAY 240 PRINT" 00021 CF5B INLOOP INY 250 PRINT"CCD)CCD) SELECT SHADING STYLE:" 0 00 22 CF5C TYA 260 PRINT" R^RANDOM, H=HALFTONE" 00023 CF5D STA (KB),Y 270 INPUT"CCD) YOUR CHOICE H CCL)CCL)CCL)" ; AS 00024 CF5F CMP MAX 280 POKE SH,0:IF A»="H" THEN POKE SH,1 CF61 BNE INLOOP 290 PRINT"CCD)CCD) SELECT STYLE FOR DRAWING:" CF63 300 PRINT"CCD) N - NORMAL":PRINT"CCD) E - EDGES EMPHASIZED" 00027 CF63 83 AD SORT STA TOPDIS J 'A' HOLDS 'MAX’ 310 PRINT"CCD) W - WIRE FRAME (HIDDEN LINES REMOVED)" CF65 A5 AD L00P1 LDA TOPDIS 320 INPUT"CCD> YOUR CHOICE NCCL)CCL)CCL)";A# 00029 CF67 85 AC STA TOP 330 POKE EG , 0: WIs0: IF AI*-"N" THEN 360 00030 CF69 A2 00 LDX N0 340 POKE EG,1:IF A4="W" THEN WI=-1 00031 CF6 B 86 61 STX NXTFLG 350 : 00032 CF6 D 86 AE ST X FLAG 360 PRINT"CCD) READING VERTEX DATA" 00033 CF6 F 86 64 L00P2 STX REPEAT 370 VN=32: DIM PX (VN-1 ,2) : REM VN = NUMBER OF VERTICES 00034 CF71 380 FOR N=0 TO VN-1: READ PX(N,0),PX Dr. Dobb's Journal, May 1985 80 ^ A 7 Drawing on the C-64 (Listing Continued, text begins on page 50) Listing Eight 00085 CFB3 E6 AE INC FLAG 00086 CFB3 E4 AC NOSWAP CPX TOP Listing Nine 00087 CFB7 D0 B6 BNE L00P2 00088 CFB9 A3 AE LDA FLAG 00089 CFBB D0 A8 BNE LOOP1 00001 “WRITE" RICHARD L. RYLANDER 00090 CFBD 1 0009 J CFBD « UNPACK THE BYTE 000 02 12/30/84 00092 CFBD J INTO BASIC'S NOF 00003 REVISED 1/19/83 - ORIGIN MOVED TO *CFE3 (53221.) 00004 00093 CFBD 1 00094 CFBD A6 BC UNPACK LDX MAX 00005 PUT TEXT CHARACTERS ON GRAPHIC SCREEN 00095 CFBF EQ I NX 00006 (UNDER BASIC ROM) IN VARIOUS STYLES 00096 CFC0 CA PKLOOP DEX 00097 CFC1 8 A TXA 00098 CFC2 A8 TAY CFE3 A5 01 LDA *01 00099 CFC3 B1 FB LDA (KB) ,Y CFE7 29 FE AND #*FE CFC5 48 PHA 0001 1 CFE9 85 0 1 STA *01 0 0 10 0 CFEB A0 07 LDY #7 0 0 10 1 CFC6 BA TXA 00012 0A A I MOVE TO 2* I-M 00013 CFED B1 FD LDA ( *FD),Y I READ CHARACTER BYTE 0 0 10 2 CFC7 ASL 00014 CFEF j MODIFY W/SCREEN BYTE 09 ORA - 31 FB AND (*FB),Y 00103 CFC8 0 1 # 1 00013 CFF1 91 FB STA (*FB),Y I STORE IN SCREEN 00104 CFCA 90 04 BCC STORE 00016 CFF3 00103 CFCC E6 61 INC NXTFLG 00017 CFF3 t POKE NEW LOGICAL OPERATOR TO REPLACE 00106 CFCE E6 FC INC KB* 1 00018 CFF3 | AND- (53231.) FOR DIFFERENT STYLES 00107 CFD0 A8 STORE TAY 00019 CFF3 ; ORA-17. BIT (NOP>-36. AND-49. EOR-81. 68 PLA 00108 CFD1 00020 CFF3 00109 CFD2 91 FB STA (KB),Y 00021 CFF3 DEY 0 0 1 10 CFD4 A9 00 LDA «0 00022 CFF4 10 F7 BPL LOOP 0 0 1 1 1 CFD6 88 DEY 00023 CFF6 AS 01 LDA *01 I RESTORE BASIC ROM 0 0 1 12 CFD7 91 FB STA (KB),Y 00024 CFFB 09 01 ORA Ml 00113 CFD9 AS 61 LDA NXTFLG 00023 CFFA 8 3 01 STA *01 001 14 CFDB F0 04 BEO OK. CFFC 60 DEC NXTFLG 20026 RTS 0 0 1 13 CFDD C6 61 00027 CFFD 00116 CFDF C6 FC DEC KB* 1 001 17 CFE1 BA OK TXA 0 0 1 IB CFE2 D0 DC BNE PKLOOP 001 19 CFE4 60 DONE RTS 0 0 12 0 CFE5 .END SYMBOL TABLE ERRORS - 00000 SYMBOL TABLE END OF ASSEMBLY SYMBOL VALUE CRRNT 0062 DONE CFE4 00AE GETINT CF71 INI T CF39 INLOOP CF5B 00FB LOAD CF7C LOOP 1 CF65 L00P2 CF6 F 008C NODEC CFGB NOSWAP CFB5 NXTFLG 0061 CFE1 ORDER CF97 ORIGIN CF59 PKLOOP CFC0 REPEAT 0064 SORT CF63 STORE CFD0 SWAP CFA2 TEST CFA0 TOP 00AC TOPDIS 00AD UNPACK CFBD 00FD END OF ASSEMBLY End l isting Eight End Listings 82 Dr. Dobb’s Journal, May 1985