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 C031 26 B4 ROL RMNDR 00013 MliLT-*C011 j CALL FOR MULTIPLY 00079 C033 26 B5 ROL RMNDR*1 00014 » C033 30 SEC 00015 RNDM=*C000 5 RANDOM NUMBER 00001 C036 AS B4 LDA RMNDR 00016 RANDOM-*C0C8 ; CALL FOR RANDOM 00082 C038 E5 FB SBC DVSOR 00017 j NOTE - A CALL TO RANDOM" LEAVES A RANDOM BYTE 000B3 C03A A8 TAY 00018 ; IN THE ACCUMULATOR 00084 C03B A5 B5 LDA RMNDR-* 1 I 00083 C03D ES FC SBC DVSOR*1 0 00 20 =RAM C03F 90 04 BCC DECCNT 00021 033E PLTFLG 5 PLOT/UNPLOT FLAG 00087 C041 84 B4 STY RMNDR 00022 033F XPLT i ABSOLUTE PLOT COORD C04 3 85 B5 STA RMNDR*1 00023 0341 Yf'LT ; ABSOLUTE PLOT COORD C043 CA DECCNT DEX 00024 0342 VIC1 ; REGISTER STORAGE 00090 C046 DO E5 BNE DLOOP 0343 V1C2 ; REGISTER STORAGE 00091 C048 26 FD ROL DVDND I CHECK IF REMAINDER 0344 VAl.UE ; FINAL NORMALIZED SHADE VALUE 00092 C04A 26 FE ROL DVDND*1 ; IS >« 1/2 OF DIVIDEND 00027 0346 HTORRN ; SHADE FLAG, 1“HALFTONE 00093 C04C 06 B4 ASL RMNDR I FOR ROUNDING 00028 0347 MOSCAL ! SCALE FLAG, 1-NO SCALE C04E 26 B5 ROL RMNDR*1 00029 0348 TEMP } TEMPORARY STORAGE C050 BO 0B ROUND 00030 034A C032 38 SEC 00031 034A C033 A5 FB LDA DVSOR 00032 C0E2 C03S E5 B4 SBC RMNDR 00033 COE 2 00099 C037 A5 FC LDA DVSOR*1 00034 COE 2 0 0 10 0 C059 E5 B5 SBC RMNDR * 1 00035 C0E2 i TURN ON BIT MAP GRAPHICS MODE, 00101 COSO BO 06 BCS NOCHNG • 00036 C0E2 ; SAVING REGISTER VALUES FOR 00102 C03D E6 FD ROUND INC DVDND 00037 COE 2 ; RETURN TO TEXT MODE LATER. 00103 C05F D0 02 BNE NOCIING 00038 C0E2 00104 C061 E6 FE INC DVDND*1 00039 C0E2 AD 11 DO GRFON LDA *D011 00103 C063 60 NOCHNG RTS 00040 COES 09 20 ORA #*20 00106 C064 00041 COE 7 0D 11 DO STA *D011 00107 C064 00042 COEA AD 00 DD LDA *DD00 00108 C0A4 0D 42 03 STA VIC1 00109 C064 TAKE INTEGER SQUARE ROOT OF A 29 FC AND #*FC 001 10 C064 DOUBLE PRECISION RADICAND GIVING 00043 C0F2 09 01 ORA #*01 001 1 1 C064 SINGLE PRECISION ROOT < REAL ROOT ) C0F4 8 D 00 DD STA * DD00 001 12 C064 00047 C0F7 AD 10 D0 LDA *D010 00113 C064 SQRT LDX #*00 00048 C0FA 0D 43 03 STA VIC2 001 14 C066 A9 00 LDA #*00 00049 C0FD A9 19 LDA #119 001 IS C068 8 D 3C 03 STA ROOT 00050 C0FF 0D 10 DO STA <0010 00116 C06B 8 D 3D 03 STA ROOT * 1 00051 C 102 60 RTS 001 17 C06E 85 FB SI A TEMP 00052 C103 0 0 1 18 C070 85 FC STA TEMP*I 00053 C 103 00119 C072 0E 3C 03 SQRT1 ASL ROOT 00054 Cl 03 0 0 12 0 C075 2E 3D 0 3 ROL ROOT * 1 00053 C103 j RETURN TO TEXT SCREEN 00121 C078 EE 3C 03 INC ROOT { ASSUME CURRENT LSB OF 00122 C07B DO 03 BNE NEXT1 ; ROOT WILL BE I 00036 C103 < 00123 C07D EE 3D 03 INC ROOT * 1 C 103 AD 11 DO GRFOFF LDA *0011 AND ftCDF 00124 C080 NEXT1 ASL RADCND j SHIFT RADICAND LEFT C0050 C 106 29 DF 06 AC 00039 C 108 0D 11 D0 STA *D011 00125 C002 26 AD MOL RADCND*1 ; TWICE INIO TEMP C10B AD 42 03 LOA VIC1 C084 26 1 13 ROL TEMP 00126 00061 C10E 0D 00 DD 00127 C086 26 FC ROL TEMF' * 1 STA *0000 LDA VIC2 C088 06 AC ASL RADCND 00062 Cl 11 AD 43 03 00128 00063 Cl 14 0D 10 DO STA *D010 00129 C00A 26 AD ROL RADCND*1 00064 Cl 17 RTS 00130 C0QC 26 FB ROL TEMP 00063 Cl 10 0131 CODE 26 FC ROL TEMF *1 00066 cue C090 I SUBTRACT ROOT ESTIMATE 001 32 38 SEC 00067 Cl 10 ; FROM TEMP 1 00133 C091 LDA TEMP 00068 C 110 j FILL COLOR MAP FOR BLACK DOTS ON WHITE 00134 C093 SBC ROOT 00069 Cl 10 00133 C096 A TAY 8 00070 Cl 10 A9 01 LDA #*01 I POKE NEW COLORS HERE 30136 C097 A5 FC LDA TEMP*! 00071 Cl 1A A2 00 LDX «0 00137 C099 ED 3D 03 SBC ROOT * 1 00072 Cl 1C 90 00 84 STA * 8 100,X 90 12 BCC RESTOR 00073 Cl IF 9D 00 85 STA *8500,X 85 FC STA TEMP * 1 SUBTRACTION 01. 00074 Cl 22 9D 00 86 STA *0600,X 00140 C0A0 84 FB STY TEMP 00073 Cl 25 90 00 87 STA *0700,X 00141 EE 3C 03 C0A2 INC ROOT 00076 Cl 20 CA DEX 00142 C0A5 BNE NEXT2 00077 Cl 29 00 FI BNE COL 1 C0A7 INC ROOT•1 00143 00078 C 1 2 B RTS 00144 C0AA NEXT2 DEX 000/9 C I 2C 00145 C0AB BNE SQRT1 C12C 00146 C0AD JMP FINI 01 C12C 00147 C0B0 RESTOR SEC j IGNORE SUB T RAC TION C12C CLEAR HI-RES GRAPHICS SCREEN 00148 COB 1 AD 3C 03 LDA ROOT j AND RESET LSB uF ROOT 00083 C12C 00149 C0B4 E9 01 SBC Mi01 00084 C12C A9 AO LDA ft*A0 00150 C0B6 8 D 3C 03 STA ROOT 00085 C12E 85 FC STA *FC 00151 C0K9 B0 03 BCS NEXT3 00086 Cl 30 AO 00 LDY NO 00152 CObB CE 3D 0 5 DEC ROOT * 1 C132 04 FB STY *FB 00153 C0bE CA NE X T3 DEX Cl 34 A9 00 LDA *0 j CLEAR BYTE 00154 COBr DO B1 BNE SQRT1 Cl 36 A2 20 LDX #*20 00155 C0C1 6 E 3D 03 FINI ROR ROOT * 1 FINAl /2 TO NORMALIZE Cl 30 91 FB STA (*FB>,Y 00156 C0C4 6 E ZC 03 ROR ROOT C13A C0 INY 00157 C0C7 60 RTS 00092 C13B DO FB BNE CLRLP 00158 coc:a 00093 Cl 3D E6 FC INC *FC 00139 C0C8 00094 C13F DEX 00160 C0C8 00095 C 1 40 BNE CLRLP 00161 C0C8 » GENERATE PSEUDO-RANDOM BYTES 00096 C 142 RTS 00162 cons ; EXIT WITH P-R BYTE IN ACCUM. 00097 C 143 00163 C0C8 C 1 43 00164 C0C8 AD 00 CO RANDOM LDA RNDM 00099 C 1 43 00163 C0CB 8 D 02 CO STA RTEMP 00100 C 1 43 I PLOT AND UNPLOT POINTS ON HI-RES GRAPHICS 00166 C0CE 4D 01 CO EOR RNDM*1 0 0 10 1 C143 1 SCREEN. ABSOLUTE X AND Y SCREEN COORDINATES 00167 COD 1 2E 03 CO ROL RTEMP*1 I RTEMP*1 PRESERVES 00102 Cl 43 ; ARE POKED INTO XPLT, XPLT*1, AND YF’LT CARRY BIT FOR CYCLING 00160 C0D4 6 A ROR A 5 00103 C143 I 00169 CODS 6 E 03 CO ROR RTEMP*1 I RANDOM NUMBERS 00104 C 1 43 PLOT LDA N0 00170 C0DB 8 D 00 CO STA RNDM 00103 C M S .BYTE *2C 00171 C0OB AD 02 C0 LDA RTEMP 00106 C 146 UNPLOT LDA ft*00 00172 CODE 80 01 CO STA RNDM*I 00107 C 140 STA PLTFLO 00173 COE 1 RTS 00108 C14B AS 01 LDA *01 | BASIC ROM OUT 00174 C0E2 • END 00109 C14D 29 FE AND Ilf FE ERRORS - 00000 001 10 C14F 03 01 STA *01 ERRORS - 00000 001 1 1 C1S1 SEC INVERT Y COORDINATE TO 001 12 Cl 32 LDA ft*C7 PUT ORIGIN IN LOWER LEFT SYMBOL TABLE 001 1 3 C 154 SBC YPLT CORNER OF SCREEN 001 14 C 137 TAX (199.-YPLT > SYMBOL VALUE 0 0 1 13 Cl SB LSR A DECCNT C045 CO 25 CB2 D 0 0 1 16 C 159 LSR A DVSOR 00FB FINI C0C1 ML OOP CO 15 ML.PCND 00AC 001 17 C1SA 4A LSR A HLPLER MULT C011 NEXT1 coao NEXT2 COAA 0 0 1 18 Cl SB TAY NEXT3 C0BE NOADD C01C NOCHNG C063 POSI TV C00F 001 19 CISC B9 AB Cl LDA TABLE1,Y PROD 0OAE RADCND O0AC RANDOM C0C8 RESTOR C0B0 0 0 12 0 C13F 03 FB S1A *FB RMNDR 00B4 RNDM C0O0 ROOT 033C ROUND C05D C1 6 I B9 C4 Cl I DA TABLE2,Y RTEMP C002 SQRT C064 SQRT 1 C072 SQUARE C004 Cl 64 03 FC STA *FC TEMP 00KB END OF ASSEMBLY End Listing One (Continued on page 64)

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 - DY 00026 OUOT - tFD 00155 C303 D0 70 BNE STEPX 00027 DIVIDE - 4C025 00156 C305 38 SEC 00028 0000 f 00157 C306 AO 56 03 LDA DLTAXl 00029 0000 • -RAM 00158 C309 ED 5B 03 SBC DLTAY1 00030 034A I 00159 C30C B0 74 BCS STEPX 00031 034A XMIN 00160 C30E AO 5B 03 LDA DLTAY1 * - * ♦ 1 00032 034C YMIN 00161 C311 8 D 65 03 STA ERROR 00033 034D XMID * - • ♦ 2 00162 C314 80 68 03 STA COUNT 00034 034F VMID * - * ♦ 1 00163 C317 4E 65 03 LSR ERROR *»« 00035 0330 XMAX *2 00164 C31A 38 SEC 00036 0332 YMAX 00165 C31B AD 56 03 LDA DLTAXl 00037 0333 YTOP 00038 0334 YBOT • - * ♦ 1 00166 C31E ED 65 03 SBC ERROR 00039 0333 YBASE • ■** 1 00167 C321 80 65 03 STA ERROR 00040 0336 DLTAX1 00168 C324 AD 57 03 LDA DLTAX1*1 00041 0338 DLTAX2 * - * ♦ 1 00169 C327 E9 00 SBC N0 00042 0359 DLTAX3 00170 C329 8 D 66 03 STA ERROR*1 00043 033A DELTAX *■«*! 00171 C32C EE 6 8 03 INC COUNT 00044 035B DLTAY1 • - * ♦ 1 00172 C32F AO 67 03 LDA MODE I 0 - DRAW, 1 - ERASE 00043 033C DLTAY2 00173 C332 D0 06 BNE ERASE1 00046 0330 DLTAY3 • -•♦l 00174 C334 20 43 Cl JSR PLOT 0004 7 035E DELTAY • -•♦I 00175 C337 4C 30 C3 JMP SKI 00048 033F XDIFF 00176 C33A 20 46 Cl I JSR UNPLOT 00049 0360 FLAG1 * ■ * ♦ 1 00177 C33D AD 60 03 LDA FLAG1 0 - POSITIVE SLOPE 00030 0361 FLAG2 • ■ • ♦ 1 00170 C340 0 0 05 BNE NSLOPE 00031 0362 FLAG3 *«■* 1 00179 C342 EE 41 03 INC YPLT 00032 0363 FLAG 00180 C345 D0 03 BNE SK2 ALWAYS BRANCH 00033 0364 EDGES • -■.♦I 00181 C347 CE 41 03 E DEC YPLT 00034 0363 ERROR • - • ♦ 2 00182 C34A 2C 66 03 BIT ERROR*1 00033 0367 MODE * - • ♦ 1 00183 C34D 30 1A BMI SK3 00036 0368 COUNT * - * ♦ 2 00184 C34F EE 3F 83 INC XPLT 036A I 00185 C352 00 03 BNE NOINCI 036A 00186 C354 EE 40 03 INC XPLT * 1 00039 036A 00187 C357 38 1 SEC C26F 00188 C358 AD 65 03 LDA ERROR 00061 C26F 00189 C35B ED SB 03 SBC DLTAY1 00062 C26F I 00190 C35E 80 65 03 STA ERROR 00063 C26F I SCALE ALL Y COORDINATES FROM 0..239 00191 C361 AO 66 03 LDA ERROR*1 00064 C26F | PSUEDO-COORDINATE RANGE TO 0..199 00192 C364 E9 00 SBC «0 00063 C26F I TRUE SCREEN COORDINATE RANGE 00193 C366 8 D 66 03 STA ERROR*1 00066 C26F I 00194 C369 18 CLC C26F A0 06 SCALE LDY 06 00195 C36A AD 65 83 LDA ERROR C271 A9 03 LDA ft«D5 00196 C36D 60 56 83 ADC DLTAXl 00069 C273 83 AC STA MLPCND 00197 C370 8 D 65 03 STA ERROR 00070 C273 B9 4C 03 LDA YMIN,Y 00198 C373 AD 66 03 LDA ERROR*1 00071 C278 83 AO STA MLPLER 00199 C376 60 37 03 ADC DLTAX1*1 00072 C27A 20 11 C0 JSR MULT 0 02 00 C379 80 66 03 STA ERROR*1 00073 C27D 99 4C 03 STA YMIN.Y 00201 C37C CE 6 8 03 DEC COUNT 00074 C280 88 DEY 0 02 02 C37F D0 AE BNE LNLP1 00073 C281 88 DEY 00203 C381 60 RTS 00076 C282 DEY 00204 C382 00077 C283 10 F0 BPL SCLP 00205 C382 AD 56 03 LDA DLTAXl 00078 C283 RTS 00206 C385 80 65 03 STA ERROR 00079 C286 00207 C38B 8 D 6 8 03 STA COUNT C286 00208 C38B AD 57 03 LDA DLTAX1*1 00081 C286 I••••••••••«•*•«••••••••••••••••»•••»•• 00209 C38E BD 66 03 STA ERROR*1 00082 C286 I 00210 C391 8 D 69 03 STA COUNT*1 00083 C286 I EXCHANGE 'MIN ' AND ’MID' COORDINATES 0021 1 C394 4E 66 03 LSR ERROR*1 00084 C286 I 0 0 2 1 2 C397 6 E 65 03 ROR ERROR C286 A0 02 SWAP 12 LDY »2 00213 C39A 38 SEC C288 B9 4A 03 LOOP1 LDA XMIN,Y 00214 C39B AD 5B 03 LDA DLTAY1 C28B PHA 00215 C39E ED 65 03 SBC ERROR C28C D*r 41) 03 LDA XMID,Y 00216 C3A1 8 D 65 03 STA ERROR C28F 99 4A 03 STA XMIN,Y 00217 C3A4 A9 00 LDA «0 000V0 C292 68 PLA 00218 C3A6 ED 66 03 SbC ERROR*1 00091 C293 99 4D 03 STA XMID,Y 00219 C3A9 80 66 03 STA ERROR*I 00092 C296 88 DEY 0 02 20 C3AC AO 67 03 LDA MODE 00093 C297 10 EF BPL LOOPI 00221 C3AF D0 06 BNE ERASE2 00094 C299 60 RTS 0 02 22 C3B1 20 43 Cl JSR PLOT 00093 C29A I 00223 C3B4 4C BA C3 JMP SKP1 00096 C29A 00224 C3B7 20 46 Cl ! JSR UNPLOT 00097 C29A 00225 C3BA EE 3F 03 INC XPLT C29A I EXCHANGE MID- AND MAX’ COORDINATES 00226 C3BD D0 03 BNE N0INC2 00099 C29A I 00227 C3BF EE 40 03 INC XPLT * 1 00100 C29A A0 02 SWAP23 LDY #2 00228 C3C2 2C 66 03 BIT ERROR*1 00101 C29C B9 4D 03 L00P2 LDA XMID,Y 00229 C3C5 30 20 BMI SKP3 00102 C29F 48 PHA 00230 C3C7 AO 60 03 LDA FLAG 1 00103 C2A0 B9 30 03 LDA XMAX , Y- 00231 C3CA D0 05 BNE NGSLP 00104 C2A3 99 4D 03 STA XMI0,Y 00232 C3CC EE 41 03 INC YPLT 00103 C2A6 68 PLA 00233 C3CF D0 03 BNE SKP2 I ALWAYS BRANCH 00106 C2A7 99 30 03 STA XMAX,Y 00234 C3D1 CE 41 03 DEC YPLT 00107 C2AA DEY 00235 C3D4 38 SEC 00108 C2AB 10 EF BPL LOOP2 00236 C3D5 AD 65 03 LDA ERROR 00109 C2A0 RTS 00237 C3DB ED 56 03 SBC DLTAXl 00110 C2AE I 00238 C3DB UD 65 03 STA ERROR 001 I I C2AE 00239 C3DE AD 66 03 LDA ERROR*1 0 0112 C2AE 00240 C3E1 ED 57 03 SBC DLTAX1*1 001 13 C2AE I SORT COORDINATES ACCORDING TO X COMPONENTS 0024 1 C3E4 80 66 03 STA ERROR*1 001 14 C2AE » 00242 C3E7 18 CLC 00113 C2AE A2 02 SORTX LDX #2 00243 C3E8 AD 65 03 LDA ERROR 0 0 1 16 C2B0 38 SORTLP SEC 00244 C3EB 60 5B 03 ADC Dl.TAYl 00117 C2B1 AD 40 03 LDA XMID 00245 C3EE BD 65 03 STA ERROR 0 0 1 18 C2B4 ED 4A 03 SBC XMIN 00246 C3F1 AD 66 03 LDA ERROR*1 00119 C2b7 AD 4E 03 LDA XMID*1 00247 C3F4 69 00 ADC N0 00120 C2BA ED 4B 03 SBC XMIN*1 00248 C3F6 8 D 66 03 STA ERROR*1 00121 C2BD B0 03 BCS NOSWP1 00249 C3F9 38 SEC 00122 C28F 20 86 C2 JSR SWAP12 00250 C3FA AD 68 03 LDA COUNT 00123 C2C2 CA NOSWP1 DEX 00251 C3FD E9 01 SBC ttl 00124 C2C3 F0 15 BEO SORTED 00252 C3FF 8 D 6 8 03 STA COUNT 00123 C2C3 38 SEC 00253 C402 B0 03 BCS TEST 00126 C2C6 AO 30 03 LDA XMAX 00254 C404 CE 69 03 DEC COUNT*1 00127 C2C9 ED 4D 03 SBC XMID 00255 C407 2C 69 03 BIT COUNT*1 00128 C2CC AD 51 03 LDA XMAX *1 00256 C40A 10 A0 BPL LNLP2 00129 C2CF ED 4E 03 SBC XMID+1 00257 C40C 60 RTS 00130 C2D2 B0 DC BCS SORTLP 00258 C40D 00131 C2D4 20 9A C2 JSR SWAP23 00259 C40O 00132 C 207 4C B0 C2 JMP SORTLP 00260 C40D ; DRAW 1 LINE AT 00133 C20A 60 SORTED RTS 00261 C40O 5 XPLT I 00134 C2DB I 00262 C40D 00133 C2DB I ...... 00263 C40O 38 SEC MAKE SURE YTOP >YBOT 00136 C20B I 00264 C40E AO 53 03 LDA YTOP 00137 C2DB I DRAW A LINE BETWEEN XMIN,YMIN AND XMID.YMID 00265 C411 ED 54 03 SBC YBOT 00138 C2DB I USING FAST DDA (DIGITAL DIFFERENTIAL ANALYZER) 00266 C414 B0 0E BCS DRAW 00139 C2DB I TECHNIQUE 00267 C416 AD 53 03 LDA YTOP 00140 C20B 00268 C419 48 PHA 00141 C2DB A9 02 LDA «2 » ENSURE XMAX IS 00269 C41A AD 34 03 LDA YBOT 00142 C2DD 8 D 51 03 STA XMAX-* 1 | LARGEST BEFORE 00270 C41D BD 53 03 STA YTOP 00143 C2E0 20 AE C2 JSR SORTX I ORDERING 'MIN' AND MID' 00271 C420 PLA 00144 C2E3 AD 47 03 LDA NOSCAL 00272 C421 3D 34 03 STA YBOT 00143 C2E6 F0 03 BEO OIJTLN 00146 C2E8 20 6 F C2 JSR SCALE (Continued on page 68)

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 VALUES, 00463 C3E0 20 9A C2 JSR SWAP23 00336 C496 1 FLAGS INDICATE SLOPE OF LIMIT LINES 00464 C3E3 20 86 C2 JSR SWAP12 00337 C496 1 00465 CSE6 20 EB C2 JSR OUTLN 00338 C496 A9 00 LDA N«00 00466 C5E9 60 FINISH RTS 00339 C498 8 D 60 03 STA FLAG1 00467 CSEA .END 00340 C49B STA FLAG2 00341 C49E STA FLAG3 00342 C4A1 38 SEC ERRORS - 00000 00343 C4A2 AD 4F 03 LDA YMID 00344 C4A3 ED 4C 03 SBC YMIN 00343 C4A8 B0 09 BCS STORE 1 SYMBOL TABLE 00346 C4AA EE 60 03 INC FLAG1 00347 C4A0 AD 4C 03 LDA YMIN SYMBOL VALUE 00348 C4B0 ED 4F 03 SBC YMID CONT C55D COUNT 0368 DELTAX 035A DELTAY 035E 00349 C4B3 8 D SB 03 STORE1 STA DLTAY1 DIVIDE C025 DLTAX1 0356 DLTAX2 0358 DLTAX3 0359 00330 C4B6 38 SEC DLTAY1 035B DLTAY2 035C DLTAY3 035D DONE C43B 00331 C4B7 AD 52 03 LDA YMAX DRAM C424 DVDND 00FD DVSOR 0 0 F B EDGES 0364 00332 C4BA ED 4F 03 SBC YMID ENDPTS C43C ERASE I C33A ERASE2 C3B7 ERROR 0365 00333 C4BD B0 09 BCS STORE2 FACET C4E1 FCETLP C4FB FINDXY C46F FINI C5CF 00334 C4BF EE 61 03 INC FLAG2 FINISH C5E9 FLAG 0363 FLAG1 0360 FLAG2 0361 00333 C4C2 AD 4F 03 LDA YMID FLAG3 0362 LINE C2DB LNLP1 C32F LNt P2 C3AC 00356 C4C5 ED 52 0 3 SBC YMAX LOOP 1 C2B8 LOOP2 C29C MLfCND 00AC MLPLER 00AO 00357 C4C8 8 D SC 03 STORE2 STA DLTAY2 MODE 0367 MULT C011 NEGSLP C468 NEXT XI C552 00338 C4CB 38 SEC NEXTX2 CSC 4 NGSLP C3D1 N0INC1 C357 N0INC2 C3C2 00359 C4CC AD 52 03 LDA YMAX NORM C224 NOSCAL 0347 NOSWP1 C2C2 NSLOPE C347 00360 C4CF ED 4C 03 SBC YMIN ORIGIN C26F OUTLN C2EB PLOT C 143 PROD 00AE 00361 C402 B0 09 BCS STORE3 QUOT 00FD RAM 034A SCALE C26F SCLP C275 00362 C4D4 EE 62 03 INC FLAG3 SKI C33D SK2 C34A SK3 C369 SKIP2 C46E 00363 C4D7 AD 4C 03 LDA YMIN SKIP3 C55A St IP4 C5CC SKP1 C3BA SKP2 C3D4 00364 C4DA ED 52 03 SBC YMAX SKP3 C3E7 SORTED C2DA SORTLP C2B0 SORTX C2AE 00365 C4DD 8 D SD 03 ST0RE3 STA DLTAY3 STEPX C382 STEPY C30E STORE 1 C4B3 ST0RE2 C4C8 00366 C4E0 60 RTS ST0RE3 C4DD SWAPI2 C2B6 SWAP23 C29A TEST C407 00367 C4E1 00368 C4E1 SYMBOL TABLE 00369 C4E1 00370 C4E1 DRAW A SHADED TRIANGULAR FACET SYMBOL VALUE 00371 C4E1 UNPLOT Cl46 VLINE C40D XDIFF 035F XMAX 0350 00372 C4E1 20 AE C2 FACET JSR SORTX XMID 034D XMIN 034A XPLT 033F YBASE 0353 00373 C4E4 AD 47 03 LDA NOSCAL YBOT 0334 YMAX 0332 YMID 034F YMIN 034C 00374 C4E7 F0 03 BEQ YSOK YPLT 0341 YSOK C4EC YTOP 0353 00375 C4E9 20 6 F C2 JSR SCALE 00376 C4EC 20 6 F C4 YSOK JSR FINDXY END OF ASSEMBLY 00377 C4EF AD 4A 03 LDA XMIN 00378 C4F2 BD 3F 03 STA XPLT End Listing Three 00379 C4F3 AD 4B 03 LDA XMIN*1 C4F8 8 D 40 03 STA xpl r*i 00381 C4FB 38 FCETLP SEC Listing Four 00382 C4FC AD 3F 03 LDA XPLT 00383 C4FF ED 4A 03 SBC XMIN 00384 C302 8 D 3F 03 STA XDIFF j PRIMITIVE SOLID SHAPE DRAWING 00385 C503 AD 36 03 LDA DLTAX1 I 00386 F0 33 BEQ CONT I RICHARD L. RYLANDER 11/7/84 S 00387 80 SA 03 STA DFLTAX 00003 0000 00388 C50D AD SB 03 LDA DLTAY1 s LOAD ARITHMETIC AND GRAPHIC UTILITIES FIRST 00389 C510 8 D 3E 03 STA DELTAY 00390 C513 AD 60 03 LDA FLAG1 00391 C516 80 63 03 STA FLAG 00392 C519 AD 4C 03 LDA YMIN 00393 C51C 80 55 03 STA YBASE MLPCND-*AC | MULTIPLICAND 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 00400 C530 80 5E 03 STA DELTAY (Continued on page 70)

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 00151 C628 YPL T=YCENT • YFtEL 00023 SQUARE9*C004 j CALL FOR SQUARE 00152 C628 GOSUB PLTSHD':REM PLOT OR ONI I UT 00024 t 00153 C628 REM POINTS WEIGHTED BY SHADE VAI UE 00025 RADCND-4AC | RADICAND (D) 00154 C628 IF YREL >CLIPD THEN GOTO RHEMI 00026 ROOT-4033C t SQUARE ROOT 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-XSHDj XSHD-YSHD;YSHD-(STACI ) 00270 C721 2C 83 03 Pl.DONE BIT HVFLAG 00142 C62Q 'NOROT' GOSUB GETZ' 00271 C724 10 IE BPL NORSTR 00143 C628 REM CALCULATE 2*Z FROM X,Y AMD RADIUS 00144 C628 HEMI - 1 00145 C628 IF XREL>CLIPL THEN GOTO RHEMI (Continued on page 72)

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)/ 00351 C7C6 60 RTS 00480 C8 8F t GOSUB PTPLOT' 00352 C7C7 1 00481 CB8 F i NEXT CNTY 00353 C7C7 00482 C8 BF ; NEXT CNTX 00354 C7C7 1 00483 C8 8 F i RETURN 00355 C7C7 ; DRAW A SHADED SPHERE 00484 CBBF ; 00356 C7C7 1 00485 C8 BF 20 9A C7 EDGTOR JSR TPARM 00357 C7C7 5 BASIC SUBROUTINE- EQUIVALENT 00486 CB92 A'? 00 LDA # 10 0 00 358 C7C7 1 00487 CB94 BD 6 E 03 STA XSHD*1 00359 C7C7 j 'SPHERE- FOR CNTX-0 TO RADIUS/SQR(2> 00488 C897 80 72 03 STA YSHD*1 00360 C7C7 1 XREL =CNTXiXSHD-CNTX 00489 C89A AD 86 03 LOOPX4 LDA CNTX 00361 C7C7 FOR CNTY-CNTX TO SQR HVFLAG-0 00492 CBA3 0‘ AC STA ARG 00364 C7C7 1 GOSUB PTPLOT 00493 CBA5 20 04 C0 JSR SQUARE 00365 C7C7 1 REM EXCHANGE X «. Y TO USE 8 -FOLD SYM 00494 C8A8 30 SEC 00366 C7C7 I HVFLAG=-128 00495 C8A9 AD 8A 03 LDA RS 00367 C7C7 1 00496 CBAC E5 AE SBC SQR 00368 C7C7 I GOSUB PTPLOT 00497 C8AE 85 AC STA RADCND 00369 C7C7 I NEXT CNTY 00498 C8B0 AD 8 B 03 LDA RS* 1 00370 C7C7 NEXT CNTX 00499 C8B3 E5 AF SBC SQR* 1 00371 C7C7 ( RETURN 00500 C8B5 85 AD STA RADCND*1 00372 C7C7 1 00501 CBB7 20 64 C0 JSR SQRT 00373 C7C7 I 00502 C8 BA AD 3C 03 LDA ROOT 00374 C7C7 AD 77 03 SPHERE LDA RADIUS 00503 C8 BD 8 D 89 03 STA R0 00375 C7CA B5 AC STA ARG 00504 CBC0 IB CLC 00376 C7CC 20 04 C0 JSR SQUARE 00505 C8C1 6 D 8 D 03 ADC RC 00377 C7CF 06 AE ASL SQR 00506 C8C4 BD BB 03 STA MAX 00378 C7D1 26 AF ROL SQR* 1 00507 C8C7 A9 00 LDA Nf 00 00379 C7D3 A5 AE LDA SQR 00508 C8C9 BD 87 03 STA CNTY 00380 C7D5 05 AC STA RADCND 00509 CBCC AD 87 03 L00PY4 LDA CNTY 00381 C7D7 A5 AF LDA SQR* 1 00510 C8CF 8 D 70 03 STA YREL 00382 C709 85 AD STA RADCND*1 0051 1 C8D2 85 AD STA MLPLER 00383 C7DB 20 64 C0 JSR SQRT 00512 C8D4 AD 89 03 LDA R0 00384 C7DE 4E 3D 03 LSR ROOT +1 00513 CBD7 85 AC STA MLPCND 00385 C7E1 6 E 3C 03 ROR ROOT 00514 C8D9 20 1 1 C0 JSR MULT 00386 C7E4 AD 3C 03 LDA ROOT 00515 CBDC 85 FE STA DVDND*1 00387 C7E7 BD 92 03 STA XMAX 00516 C8 DE A5 AE LDA PROD 00388 C7EA A9 00 LDA #4 00 00517 C8E0 85 FD STA DVDND 00389 C7EC BD 86 03 STA CNTX 00518 C8E2 AD 88 03 LDA MAX 00390 C7EF 8 D 6 E 03 STA XSHD*1 00519 C8E5 05 FB STA DVSOR 00391 C7F2 BD 72 03 STA YSHD*1 00520 C8E7 20 EA C5 JSR SD IV 00392 C7F5 AD 77 03 LDA RADIUS 00521 C8EA A5 FD LDA QUOT 00393 C7F8 85 AC STA ARG 00522 C8 EC 8 D 71 03 STA YSHD 00394 C7FA 20 04 C0 JSR SQUARE 00523 CBEF 20 28 C6 JSR PTPLOT 00395 C7FD 8 D 85 03 STA TEMP*I 00524 C8F2 AD 87 03 LDA CNTY 00396 C800 AS AE LDA SQR 00525 C8F5 CD BB 03 CMP MAX 00397 C802 BD 84 03 STA TEMP 00526 CBF8 F0 06 BEQ DONE4 00398 C805 AD 86 03 LOOPX LDA CNTX 00527 C8FA EE 87 03 INC CNTY 00399 C808 BD 87 03 STA CNTY 00400 C80B 85 AC STA ARG (Continued on

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 00681 CA37 4C 33 C9 JMP LLPX1 00533 C90F XSHD-CNTX-(CNTX«RC)/R0 00682 CA3A 60 DUNTOR RTS 00534 C90F YSHD-CNTY-/R0 00685 CA5B 00355 C90F HVFLAG-01GOSUB PTPLOT' 00684 CA3B 00556 C90F HVFLAG— 1281 GOSUB PTPLOT' 00685 CA3B 00557 C90F IF CNTY-MAX THEN GOTO 'DDNY1’ 00686 CA3B DRAW "INSIDE VIEW” TOROIDS 00558 C90F CNTY-CNTYfi 00687 CA3B 00559 C90F GOTO 'LLPYI' CA3B BASIC SUBROUTINE' EQUIVALENT 00560 C90F 00689 CA3B 00561 C90F 00690 CA3B 'SPOOL' GOSUB 'TPARM' 00562 C90F 00691 CA3B FOR CNTX-0 TO RT 00563 C90F 20 9A C7 TOROID JSR TPARM 00692 CA3B XREL-CNTX» XSHD-CNTX 00564 C912 AD 8 E 03 LDA RO 00693 CA3B MAX-RC-SQR(RS-CNTX*CN rx) 00565 C913 BS AC STA ARG 00694 CA3B FOR CNTY-0 TO MAX 00566 C917 20 04 C0 JSR SQUARE 00695 CA3B YREL-CNTY 00567 C91A 06 AE ASL SQR 00696 CA3B YSHD-(RC*CNTY/MAX)-CNTY 00569 C91C 26 AF ROL SQR*1 00697 CA3B GOSUB PTPLOT' 00569 C91E A5 AE LDA SQR 00698 CA3B NEXT CNTY 00570 C920 85 AC STA RADCND CA5B NEXT CNTX 0057 V C922 A5 AF LDA SQR*1 CA3B RETURN 00572 C924 85 AD STA RADCND*1 00701 CA3B 00573 C926 20 64 C0 JSR SORT 00702 CA3B 20 9A C7 SPOOL JSR TPARM 00574 C929 4E 3D 03 LSR ROOT♦1 00703 CA3E AD 86 03 LLPX2 LDA CNTX 00575 C92C 6 E 3C 03 ROR ROOT 00704 CA41 8 D 6 C 05 STA XREL 00576 C92F AD 3C 03 LDA ROOT 00705 CA44 85 AC STA ARG 00577 C932 BD 92 03 STA XMAX 00706 CA46 38 SEC 00579 C935 AD 03 LLPX1 LDA CNTX 00707 CA47 A9 00 LDA #4 00 86 CA49 00579 C938 8 D 6 C 03 STA XREL ED 86 03 SBC CNTX 00590 C93B 85 AC STA ARG 00709 CA4C BD 6 D 03 STA XSHD 00591 C93D 20 04 CO JSR SQUARE 00710 CA4F A9 00 LDA #f00 00592 C940 BD 91 0 5 STA XSQR*I 00711 CAS1 E9 00 SBC #100 00393 C943 AS AE LDA SQR 00712 CA53 STA XSHD*1 00594 C945 8 D 90 03 STA XSQR 00713 CAS6 JSR SQUARE 00595 C948 AD 8E 03 LDA RO 00714 CA59 SEC 00396 C94B B5 AC STA ARG 30715 CASA AD BA 05 LDA RS 00597 C94D 20 04 CO JSR SQUARE 00716 CA5D ES AE SBC SQR 00*99 C950 38 SEC 00717 CA5F 85 AC STA RADCND 00599 C951 A5 AE LDA SQR 00718 CA61 AD 8 B 03 LDA RS* 1 00590 C953 ED 90 03 SBC XSQR 00719 CA64 ES AF SBC SQR* 1 00591 C956 85 AC STA RADCND 00720 CA66 85 AD STA RADCND*1 00592 C958 A5 AF LDA SQR*1 00721 CA68 20 64 CO JSR SQRT 00593 C95A ED 91 03 SBC XSQR * 1 00722 CA6 B 38 SEC 00594 C95D 85 AD STA RADCND*1 00723 CA6 C AD BD 03 LDA RC 00595 C95F 20 64 CO JSR SORT 00724 CA6 F ED 3C 05 SBC ROOT 00596 C962 AD 3C 03 LDA ROOT 00725 CA72 BD 88 03 STA MAX 00597 C965 BD 88 05 STA MAX 00726 CA75 A9 00 LDA #*00 00599 C968 38 SEC 00727 CA77 8 D 87 03 STA CNTY 00599 C969 AD BF 05 LDA RI 00728 CA7A AD 87 05 LLPY2 LDA CNTY 00600 C96C ED 86 03 SBC 00729 CA7D 8 D 70 05 STA YREL 00601 C96F 90 23 BCC 00730 CA80 85 AD STA MLPLER 00602 C971 AD BF 03 LDA 00731 CA82 AD 8 D 03 LDA RC 00603 C974 85 AC STA 00732 CABS 85 AC STA ML PCND 00604 C976 20 04 C0 J8 R 00733 CAB7 20 11 CO JSR MULT 00603 C979 38 SEC 00734 CA8A 85 FE STA DVDND*1 00606 C97A A5 AE LDA 00735 CA8 C A5 AE LDA PROD 00607 C97C ED 90 03 SBC XSQR 00736 CA8E 85 FD STA DVDND 00609 C97F 85 AC STA RADCND 00737 CA90 AD 88 03 LDA MAX 00609 C981 A5 AF LDA S0R*1 00738 CA93 85 FB STA DVSOR 00610 C983 ED 91 03 SBC XSQR*1 00739 CA95 20 EA C5 JSR SDIV 00611 C986 85 AD STA RADCND*1 00740 CA98 A5 FD LDA QUOT 00612 C9B8 20 64 CO JSR SQRT 00741 CA9A 38 SEC 00613 C9BB AD 3C 05 LDA ROOT 00742 CA9B ED 87 03 SBC CNTY 00614 C98E BD 87 03 STA CNTY 00743 CA9E 8 D 71 05 STA YSHD 00615 C991 4C 9A C9 JMP LLPYI 00744 CAA1 A5 FE LDA QUOT * 1 00616 C994 AD 86 03 GRTR LDA CNTX 00745 CAA3 E9 00 SBC # *0 0 00617 C997 BD 87 03 STA CNTY 00746 CAA5 8 D 72 03 STA YSHD*1 00619 C99A AD 87 03 LLPYI LDA CNTY 00747 CAA8 20 28 C6 JSR PTPLOT 00619 C99D 8 D 70 03 STA YREL 00 748 CAAB AD 87 03 LDA CNTY 00620 C9A0 85 AC STA ARG 00749 CAAE CD 88 03 CMP MAX 00621 C9A2 20 04 CO JSR SQUARE 00750 CAB1 F 0 06 BEQ DDNY2 00622 C9A5 18 CLC 00751 CAB3 EE B7 03 INC CNTY 00623 C9A6 AS AE LDA SQR 00752 CAB6 4C 7A CA JMP LLPY2 00624 C9AB 6 D 90 05 ADC XSQR 00753 CAB9 AD 86 03 DDNY2 LDA CNTX 00625 C9AB BS AC STA RADCND 00754 CABC CD 8 C 03 CMP RT 00626 C9AD AS AF LDA SQR * 1 00753 CABF F0 06 BEQ DUNHSP 00627 C9AF 6 D 91 03 ADC XSQR*1 00756 CACt EE 86 03 INC CNTX 00629 C9B2 85 AD STA RADCND*1 00757 CAC4 4C 3E CA JMP LLPX2 00629 C9B4 20 64 CO JSR SQRT 00758 CAC7 60 DUNHSP RTS 00630 C9B7 AD 3C 05 LDA ROOT 00759 CAC8 .END 00631 C9BA BD 89 05 STA RO 00632 C9BD 85 FB STA DVSOR ERRORS 00633 C9BF AD 86 03 LDA CNTX 00634 C9C2 85 AD STA MLPLER SYMBOL TABLE 00635 C9C4 AD 8 D 03 LDA RC 00636 C9C7 83 AC STA MLPCND SYMBOL VALUE 00637 C9C9 20 11 C0 JSR MULT ARG 00AC 00639 C9CC 85 FE STA DVDND*1 CLIPL 037D 00639 C9CE A5 AE LDA PROD SYMBOL TABLE 00640 C9D0 85 FD STA DVDND 00641 C9D2 20 EA C3 JSR SDIV SYMBOL VALUE 00642 C9D5 38 SEC CNTX 0386 CNTY 0387 CXLOOP C8B1 CYLNDR C864 00643 C9D6 AD 86 03 LDA CNTX CYLOOP C87S DDNY1 CA2C DDNY2 CAB9 DHEMI 00644 C9D9 C6 BC ES FD SBC. QUOT DIVIDE C025 DONE C863 DONE 4 C900 DONEHT C90E 00643 C9DB 8 D 6 D 05 STA XSHD DONEY CSSS DUNHSP CAC7 DUNTOR CA3A DVDND 00FD 00646 C9DE A9 00 LDA # *0 0 DVSOR 00KB EDGTOR C F CSFl 00647 C9E0 8 8 GETVAL GETZ C745 ES FE SBC OUOT * 1 GRTR C994 HEM I 0381 HLEN 0389 HTORRN 0346 00648 C9E2 8 D 6 E 05 STA XSHD*1 HVFLAG 0383 LLPX1 00649 C935 LLPX2 CA3E LLPYI C99A C9E5 AD 87 03 LDA CNTY LLPY2 CA7A LOOPX C805 LOOPX4 CB9A LOOPY C82E 00630 C9E8 85 AD STA MLPLER LOOPY4 C8CC MAX 0388 MLPCND 00AC MLPLER 0BAD 00651 C9EA AD 8 D 03 LDA RC MULT C01 1 NEGATE C5FF NORM C224 NOROT C65A 00632 C9ED 85 AC STA MLPCND 00653 C9EF 20 11 CO JSR MULT 00654 C9F2 85 FE STA DVDND*1 End Listing Four 00655 C9F4 AS AE LDA PROD 00656 C9F6 85 FD STA DVDND (Listing Five begins on page 76)

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 00043 C0LBYT-*C119 j COLOR BYTE 00173 CBSl 00044 I 00174 CBSl A9 00 00045 PLOTR =*C14B { POINT PLOT ROUTINE L1NE2 LDA #0 00175 CB53 2C .BYTE *2C 00046 LINER -IC2DB 5 DRAW A LINE 00176 CB54 A9 80 00047 FACETR -IC4E1 I DRAW A SHADED FACET FACET2 LDA #*B0 00177 CBS6 8 D 93 03 STA LINFAC 00178 CB59 20 C8 CA JSR GETNUM 00179 CB5C BC 4A 03 STY XMIN 00050 CB5F 00051 i SHADED SHAPE DRAWING ROUTINES 8 D 4B 03 STA XMIN*1 00181 CB62 20 C CA 00052 I 8 JSR GETNUM 00053 SPHERR=*C7C7 j SPHERE 00182 CB6 S BC 4C 03 STY YMIN 00054 CYLNDR=*C864 j CYLINDER 00183 CB68 20 C8 CA JSR GETNUM 00184 00055 T0RUSR-*C90F 1 TOP-VIEW TOROID CB6 B 8C 4D 03 STY XMID 00056 EDGT0R-*C88F I EDGE-VIEW TOROID 00185 CB6 E 80 4E 03 STA XMID+1 00057 SP00LR-*CA3B I INSIDE-VIEW TOROID CB71 20 C8 CA JSR GETNUM 00058 00187 CB74 BC 4F 03 STY YMID 00059 00188 CB77 2C 93 03 BIT LINFAC 00060 00189 CB7A 10 18 BPL LDRAW 00061 { BASIC ROM ROUTINES 00190 CB7C 20 C8 CA JSR GETNUM 00191 CB7F 00062 I 8C 50 03 STY XMAX 00063 CHKCOM-*AEFD | CHECK FOR COMMA 00192 CB82 BD 51 03 STA XMAX♦1 00064 EVAEXP-*AD9E j EVALUATE EXPRESSION 00193 CBBS 20 C8 CA JSR GCTNUM 00065 FLTFIX“*B1AA | CONVERT TO FIXED 00194 CB88 8C 52 03 STY YMAX 00066 00195 CB8 B 20 C8 CA JSR GETNUM 00067 00196 CB8E 8 C 44 03 STY VALUE 0393 I LINE OR FACET FLAG 00197 CB91 4C El C4 JMP FACETR 0394 00198 CB94 4C DB C2 LDRAW JMP LINER 0394 00199 CB97 I CACB 00200 CB97 00072 CAC8 00201 CB97 00073 CAC8 f 00202 CB97 5 DRAW A SPHERE CENTERED AT (XCENT,YCENT) 00074 CAC8 I GET PARAMETERS FROM BASIC CALLING STATEMENT 00203 CB97 ; DEFAULT RADIUS IS LAST VALUE USED 000 75 CACB j OF THE FORM: 00204 CB97 00076 CAC8 j SYS(FNCTN),PARAM1,PARAM2,PARAM3C0PT3 00205 CB97 20 FB CA SPHER2 JSR CENTER 00077 CACB i WHERE THE THIRD PARAMETER (FOR EXAMPLE) CB9A 20 D2 CA JSR PCHECK 00070 CACB j MAY BE OPTIONAL (A DEFAULT VALUE IS USED CB9D 24 FB BIT DEFLAG 00079 CAC8 ; IF THE PARAMETER IS NOT SPECIFIED) CB9F 30 09 BMI SKIPI CAC8 I 00209 CBA1 20 9E AD JSR EVAEXP CAC8 20 FD AE GETNUM JSR CHKCOM I LOOK FOR COMMA 00210 CBA4 20 AA B1 JSR FLTFIX CACB 20 9E AD JSR EVAEXP j EVALUATE EXPRESSION 0 0 2 1 1 CBA7 8 C 77 03 STY RADIUS CACE 20 AA B1 JSR FLTFIX 5 CHANGE TO INTEGER WITH 00212 CBAA 4C C7 C7 SKIP1 JMP SPHERR CADI { HIGH BYTE IN “A" AND LOW BYTE IN "Y" 00213 CBAO CADI RTS 00214 CBAD CAD2 t 00215 CBAD CAD2 j CHECK FOR ADDITIONAL (OPTIONAL) PARAMETERS 00216 CBAD DRAW A TOP-VIEW TOROID AT (XCENT,YCENT> CAD2 00217 CBAD DEFAULT INNER AND OUTER RADII ARE LAST USED CAD2 A9 2C PCHECK LDA #*2C 00218 CBAD CAD4 LDY #0 00219 CBAD 20 FB CA T0RUS2 JSR CENTER 00091 CAD6 84 FB STY DEFLAG 20 E4 CA JSR GETTWO 00092 CADB D1 7 A CMP (*7A),Y 4C OF C9 JMP TORUSR 00093 CADA DO 03 BNE NOMORE USE DEFAULT 00222 CBB6 CADC 4C 73 I JMP *0073 00223 CBB6 00095 CADF AO 80 NOMORE LDY #*80 00224 CBB6 00096 CAE 1 84 FB STY DEFLAG 00225 CBB6 I DRAW CYLINDERS WITH AXES HORIZONTAL OR 00097 CAE3 60 RTS 00226 CBB6 I VERTICAL. DEFAULT RADIUS AND "HALF-LENGTH" 00098 CAE 4 I 00227 CBB6 ( ARE LAST VALUES USED. CAE 4 GET TWO ADDITIONAL PARAMETERS FOR TOROIDS 00228 CBB6 1 00100 CAE 4 < 00229 CBB6 A9 80 VCYL2 LDA #*80 00101 CAE4 20 D2 CA GETTWO JSR PCHECK 2C •BYTE *2C 0 0 10 2 CAE 7 24 FB BIT DEFLAG A9 00 HCYL2 LDA #0 00103 CAE9 30 OF BMI DFAULT BD 83 03 STA HVFLAG 00104 CAEB 20 9E AD JSR EVAEXP 20 FB CA JSR CENTER 00105 CAEE 20 AA & 1 JSR FLTFIX 00234 CBC1 20 D2 CA JSR PCHECK 00106 CAF1 BC 8 F 03 STY RI 00235 CBC4 24 FB BIT DEFLAG 00107 CAF4 20 C8 CA JSR GETNUM 00236 CBC6 30 OF BMI SKIP2 00108 CAF 7 BC 8E 03 STY RO 00237 CBC8 20 9E AD JSR EVAEXP 00109 CAFA 60 DFAULT RTS 001 10 CAFB t (Continued on page 78)

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 :POKE B0,14:RCM RETURN TO TEXT MODE 453 RW-9:CM-2:MD-1 :A*~"SPHERE":GOSUB1900 1610 END 460 SYS(HC),120,199,38,38 1620 465 CM-11:A*-"H-CYLNDR":GOSUB1900 1630 REM SUBROUTINE FOR ADDING COLOR TO DIFFERENT SCREEN AREAS 470 SYS(VC),200,199 :REM NO SIZE PARAMETERS GIVEN, DEFAULT (PREVIOUS) ARE USED 1640 REM REMEMBER THAT COLOR BOUNDARIES MUST CORRESPOND TO CHARACTER BOUNDARIES 475 CM-211 A*i«"V-CYLNDR": GOSUB) 900 1650 REM DEFINE A RECTANGULAR AREA BY LOWER-LEFT AND UPPER-RIGHT COORDINATES 480 SYS(TR),280,199,15,38 1660 REM (XI,Y1)-LOWER-LEFT POINT, (X2,Y2)“UPPER-RIGHT POINT 485 CM-32:A*-"TOROID":GOSUD1900 1670 REM THE CORNER POINTS CAN BE ARBITRARY BUT COLOR CHANGE WILL BE IN THE 490 SYS(VT),40,64 1680 REM SMALLEST CHARACTER-CELL BOUNDED RECTANGLE THAT INCLUDES THOSE POINTS 495 RW-23j CM=1: At-"V-TOROID":GOSUD1900 1690 REM Y-COORDINATES MUST BE "UNSCALED" IF SCALE FLAG IS SET: 500 SYS(HT),120,64 1700 IF PEEK (SC) THEN Y 1 - (Y1-+1) *213/256i Y2- ( Y2+1) *213/256 503 CM—11:A*-"H-TOROID"lGOSUB1900 1710 REM COLOR TO BE POKED IN IS GIVEN BY VARIABLE CC-"COMPOS ITE COLOR" 310 SYS(HS),200,64,3,100 1720 REM WHERE CC-16*DC + BC CDC-DOT COLOR, BC-BACKGROUND COLOR NUMBERS 1 3 13 CM-22iA»«"H-SPOOL"iGOSUB1900 1730 CC-16*DC+BC 320 SYS(VS),280,64 1740 FOR IX-INTIX1/8) TO INT(X2/B) 325 CM-32» A*-"V-SPOOL":GOSUB1900 1730 FOR IY-INT(Y1/B> TO INT(Y2/8> (Continued on page 80)

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 ,0):Y2-PX

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*SIN(Y) *COS(Z) 00041 CF73 LDA (KB),Y 450 X2"-C0S < X > *S IN (Y) : YG-^-COS ( X ) *SIN (Z > : Yl=COS (X) *COS (A) : Y2=SIN(X) 00042 CF75 ASL A 460 Z0“SIN(Y )* COS(Z)*SIN PX * (P7. -PX(FX 00058 CF91 , ) 68 PLA 620 Z-Z- ,0) -PX,1)-PX-PX(FX(VF,1) ,2))* “ 'NEXT’ THEN SWAP KEY 680 NC«SQR(X*X+Y*Y*Z«Z):REM LENGTH OF NORMAL VECTOR 00065 CF97 ; ELEMENTS, ELSE CONTINUE 690 SH(VF)“26*(2*Z + X + Y)/NC 00066 CF97 700 SH(VF)“ *64)*)>Y THEN Y-ABS(PX+YC:PX(N,0)-S*PX(N,0)+XC:NEXT 00073 CFA4 STX TOPDIS 790 i 00076 CFA6 LDA (KB),Y 800 REM FIND AVERAGE Z FOR EACH FACET 00077 CFA8 PHA 810 FOR N-0 TO VF CFA9 DEY 820 ZX,2)*PX:POKE 232,PEEK(72) CFB0 DEY 870 ZX(0)-ZX(0):FOKE 253,PEEK(71)I POKE 254,PEEK(72> CFB1 STA 880 SYS(KS) 890 i (Continued on page 82)

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