Synopsis to "Graphics Programming using Assembly" by Ron Thomas
This book will provide you with all the information you need to write super-fast graphics programes in assembly. Techniques for graphics programming are developed methodically from first principles and a comprehensive set of reusable subroutines is developed as we work our way though the book. With these subroutines you will be able to:-
Over 70 tested graphics subroutines are provided, together with numerous demonstration programs and also a working library for you to use with your own programs. All assembly source code is included.
This book is aimed at readers who have some knowledge of assembly language programming and who now wish to extend their skills into the exciting and stimulating field of computer graphics. The requisite programming techniques for graphics programming are developed methodically from first principles and a comprehensive set of subroutines is descibed in the book. These can moreover be easily incorporated into users programs, for the many specific applications which require the added impact and presentation, which can only be provided by interactive computer graphics.
The book commences with a brief introduction explaining the purpose of the book and then launches into a description of the available video modes, ranging from the humble Colour Graphics Adaptor mode, to all the new modes provided by the Vesa Bios Extensions to the SVGA standard. Then starting with the most basic graphics function - the writing of a pixel onto the display screen, subroutines are described for use in all the commonly avaiable graphics modes and also for the much more versatile SVGA VBE modes.
These fundamental pixel plotting subroutines are then used to construct basic graphic primitives, such as the line, the box, the circle and the ellipse. They are all contructed in wire-frame form, in the manner of the commercial DRAW programs (this is an efficient and intuitive method for the display and manipulation of objects). Methods are also described for filling these objects with colour.
The use of the mouse in the construction of user friendly and intuitive programs is discussed with respect to the limitations of the standard mouse driver in graphics modes. Normally the mouse cannot be used at a higher resolution than 640*480, due to a limitation of the mouse driver, which is particularly frustrating, as entry level PC's are currently being provided with SVGA screens !. A solution to the problem is therefore provided in the form of a special mouse handler, which creates a special mouse cursor which is visible in all the available video modes (even the SVGA/VBE modes). This handler is then used by all the mouse dependent programs described in the book.
We then move on and develop subroutines for performing various image transforms on graphics objects, such as image rotation, image inversion and the construction of mirror images. These operations are essential to CAD programming and should therefore be of particular interest to programmers wishing to work in this area.
Techniques for constructing rectangles, squares and circles interactively using the mouse, are also covered, as are techniques for filling them with colour, i.e forming solid objects from the wire-form outline. Also we don't forget the polygon. Its interactive construction is also described, even for re-entrant shapes and a method is also provided for filling it with colour.
The construction of curves of various mathematical descriptions is also described, including the useful Bezier curve. All this shows what can be achieved in computer graphics; it also demonstrates how a maths coprocessor can be employed to speed up many calculations. (Examples of the programming of the maths coprocessor are not always included in assembly language text books). Other programs demonstrate the construction of Fractal objects such as the famous "Mandelbrot Set" and the generation of the Strange Attractors from the world of Chaos.
A topic of interest to data analysts and statisticians is provided in the form of a program for drawing of the the "Best Straight Line" through a set of experimental data points. I haven't seen this covered in any other assembly language book, so this is one other feature that makes this book that little bit different from the currently available assembly books !
Towards the end of the book, screen image processing is described and covers image inversion and the making of an in-place mirror image. A subroutine for the transfer of a displayed graphics image to a compatible laser printer is also provided, as there must be many occasions when the programmer wishes to capture his/her creations permanently onto paper !
In the last chapter there are examples of the interfacing of assembly subroutines to the high level languages Basic, "C" and Fortran. Programmers with expertise in these languages are therefore provided with the means to beef-up their slow high level applications.
The reader, is therefore provided with a broad base of many aspects of computer graphics, which will enable him, or her to make immediate use of the wide range of subroutines which are described in this book. A guide on these and a description of their calling conventions is included in Appendex B.
This summary has necessarily skipped over a lot of detail and I refer you to the Annontated Table of Contents for a full description of the books content. In addition, Chapter 5 (on line drawing), is provided for your perusal and is a sample of the graphics programming contained in the complete book.
Annotated Table of Contents Contents:- Chapter 1 Introduction and Overview of the book contents. 1 Introduction. 2 What's in the book. Chapter 2 Screen Display and Video modes. Chapter 3 Pixel Addressing. Chapter 4 Pixels. Reading and Writing them. 4.1 Pixel Writing. 4.2 Pixel Reading. Chapter 5 Drawing a Straight Line. 5.1 The Bresenham straight line algorithm. 5.2 The Michalski straight line algorithm. Chapter 6 Line Clipping. The Cohen-Sutherland algorithm. Chapter 7 A special cursor for use in all graphics modes. 7.1 Making the special mouse cursor. 7.2 Drawing a "rubber_band" line with the aid of the mouse. 7.3 Hiding or revealing the special cursor. Chapter 8 Drawing Rectangular Objects. 8.1 Draw a rectangle using the mouse. 8.2 Draw a rectangle filled with colour. 8.3 Draw a true square interactively using the mouse. Chapter 9 Pertaining to Circles. 9.1 The Michener-Bresenham algorithm. 9.2 The Paterson-Kientzle algorithm. 9.3 Filling the circle with colour. 9.4 The drawing of orthogonal circles. Chapter 10 Drawing Ellipses 10.1 A simple geometric algorithm. 10.11 Drawing an Ellipse using the Keintzle algorithm. 10.2 Filling an Ellipse with colour. Chapter 11 Geometrical Transforms. 11.1 Translation. 11.2 Scaling. 11.3 Rotation. 11.4 General Transform using translation, scaling and rotation of coordinates. Chapter 12 Drawing Polygons. 12.1 Drawing a wireframe polygon interactively using the mouse. 12.2 Drawing a solid polygon using determined vertex coordinates. 12.3 Drawing a symmetrical wireframe polygon using the mouse. Chapter 13 Menu Construction. 13.1 Selection from a horizontal menu using the mouse. 13.2 Selection from a two dimensional menu using the mouse. Chapter 14 Fractals and Chaos 14.1 Fractals. 14.11 Sierpinski. 14.12 Cantor Circles. 14.13 The Mandelbrot Set. 14.2 Strange Attractors. 14.21 The Lorenz attractor. 14.22 The Ikeda attractor. Chapter 15 Drawing Curves. 15.1 Drawing a Bezier curve interactively using the mouse. 15.2 Other mathematical curves. 15.21 The Lissajous Curve. 15.22 The Butterfly curve. Chapter 16 The construction of the "Best Straight Line" through a set of observed data points. Chapter 17 Screen Operations. 17.1 Inversion of a defined area of the screen. 17.2 Make a mirror-image in a defined screen area. 17.3 Transfer the screen image to a laser printer. Chapter 18 High Level Language Interfaces. 18.1 The BASIC - Assembly Interface. 18.2 The "C" - Assembly Interface. 18.3 The Fortran - Assembly Interface. Acknowledgements References Glossary Appendices Appendix A Use of the MASM Utilities. A.1 MASM (Assemble the program) A.2 CREF (Create a cross reference listing) A.3 LINK (Form a executable program) A.4 Codeview (Debugging the program) A.5 LIB (Library management) Appendix B A list of all the Subroutine Calls. B.1 A list of all the subroutines contained in the library GLIB.LIB B.2 Details of the subroutines calling requirements. Appendix C Listings of useful ancillary subroutines. Appendix D A list of all the source files described in the book. D.1 List of the source files. D.2 List of the executable files. D.3 List of the other files. Appendix E The Vesa Bios Extension Modes. E1 The Vesa Bios Extension Subfunctions E2 A useful graphics card interrogation program SVGAINFO for the SVGA VBE modes.
But how is it actually done ? Manually we can place a rule on a piece of paper and draw a straight line along its edge. But this is only a replication operation and obviously we can't use the same technique to draw a line of pixels onto the computer screen. A mathematical solution is used instead, in which we represent the straight line by a set of pixels which are located as near as possible to the line defined by its end point coordinates (X1,Y1) and (X2,Y2). It is in fact, a visual approximation of the mathematical line, and the higher the screen resolution, the nearer the line will approach the ideal line. Fig 5.1 shows a magnified section of a typical line, in which the black dots represent the position of the plotted pixels and the ideal line (unseen on the monitor) is represented by the continuous line.
The simplest method of predicting the position of the pixels is to calculate the slope of the line, which is given by (Y2-Y1)/(X2-X1). We can then find any position Y, corresponding to the independent variable X, using the standard equation Y = a + b*X , where a is the intercept with the Y axis and b is the slope. This is very easy to program, but because it uses floating point instructions, is inherently slow. Graphics programmers have therefore devised various ingenuous algorithms, which will calculate the straight line using integer arithmetic only. Although these algorithms are a little more complex, they are nether the less much faster than the floating point version and are used today in most fast graphics programs. One of the early pioneers of these fast algorithms was J.E.Bresenham (Ref 24) and many of the subsequent algorithms are variations of his method, so we will look first at this useful and classic algorithm.
dx = abs(X2 - X1) dy = abs(Y2 - Y1) incr1 = 2 * dy incr2 = 2 * (dy - dx)A third variable DECISION is used as the decision variable and this is initialised as follows:-
decision = 2*dy - dxThe code is then split into two parts, which deal the cases where the slope is greater than or less than one. If its greater than one, then incrementing the dependent variable X will result in an increment in Y greater than one. So for this case we reverse the role of X and Y. In both cases there is a small inner loop in which the algorithm loops through the integral values of X, (or Y for the case where slope > 1) and the decision variable is compared with zero and the appropriate pixel is plotted. For a detailed explanation of the algorithm refer to the original paper, or to Foley and Van Dam's book on "The Fundamentals of Interactive Computer Graphics" (Ref 8). This algorithm is very fast and adequate for most purposes, but it is in fact possible to speed it up further, by applying the incremental changes in the pixel position directly to the addresses in the video memory. To do this properly however, you must always check which memory bank the pixel resides in and switch to it before issuing the instruction to replace, or XOR the pixel at its location in video memory.
.MODEL small ; Listing 5.1 ; Source file is LINE.ASM .DATA X1 EQU [si] ; Coordinates of the line Y1 EQU [si+2] ; contained in the calling X2 EQU [si+4] ; pgm's parameter block Y2 EQU [si+6] colour EQU [si+8] plotadot EQU [si+14] ; Address of dot plotting routine ;-------------------------------; End of parameter block decision sword ? ; The decision variable delta_x dw ? delta_y EQU delta_x incr1 dw ? ; Increment 1 incr2 dw ? ; Increment 2 xend sword ? ; Line end point yend EQU xend xinc dw ? ; X increment yinc EQU xinc .CODE PUBLIC line ;-------------------------------------------------------; ; Draws a straight line using Bresenham's algorithm ; ; Valid for all slopes. ; ; ; ; Entry: si points at parameter block ; ;-------------------------------------------------------; line proc USES ax bx cx dx di bp mov al,colour ; Get the colour attribute mov bx,X1 sub bx,X2 ; Get absolute difference jns short got_dx ; for X2 - X1 neg bx got_dx: mov delta_x,bx ; Save delta_x mov cx,Y1 sub cx,Y2 ; Get absolute difference jns short got_dy ; for Y2 - Y1 neg cx got_dy: mov delta_y,cx ; Save delta_Y cmp cx,bx ; Test the slope. ; Is delta_Y greater jae slope_more_1 ; than delta_X ; i.e the slope is GE 1 ; This section handles lines with slopes less than 1 shl cx,1 ; 2 * delta_Y mov incr1,cx ; increment1 for case d < 0 sub cx,bx ; 2 * delta_Y - delta_X mov decision,cx ; initial decision variable sub cx,bx ; 2 * (delta_Y - delta_X) mov incr2,cx ; increment2 for case d >= 0 mov di,X1 ; Take copy of 1st points coords mov bp,X2 .IF di GT bp ; If X1 larger X2 mov bx,Y1 mov cx,X2 mov dx,Y2 mov xend,di ; Set end of line, xend = X1 .IF delta_y == 0 mov yinc,0 .ELSE .IF dx GT bx ; Is Y2 larger Y1 ? mov yinc,-1 .ELSE mov yinc,1 .ENDIF .ENDIF .ELSE mov bx,Y2 mov cx,X1 mov dx,Y1 mov xend,bp ; Set xend = X2 .IF delta_y == 0 mov yinc,0 .ELSE .IF bx GT dx ; Is Y2 larger Y1 ? mov yinc,1 .ELSE mov yinc,-1 .ENDIF .ENDIF .ENDIF ; The plotting routine is entered with coordinates ; X & Y in cx & dx; & colour attribute in al. Note ; that the bx register is altered by the routine. call plotadot ; Plot the first point mov bp,incr1 ; Set regs with the 2 increments mov di,incr2 .WHILE cx LT xend ; While X less xend inc cx ; Increment X .IF decision LT 0 add decision,bp ; Choose Si,no change in Y .ELSE ; else choose Ti, Y incremented add dx,yinc ; Increment Y add decision,di .ENDIF call plotadot ; Plot all other points .ENDW ret ; Return to DOS ; Here we handle lines with slopes GE 1 slope_more_1: shl bx,1 ; 2 * delta_X mov incr1,bx ; increment1 for case d < 0 sub bx,cx ; 2 * delta_X - delta_Y mov decision,bx ; initial decision variable sub bx,cx ; 2 * (delta_X - delta_Y) mov incr2,bx ; increment2 for case d GE 0 mov di,Y1 mov bp,Y2 .IF di GT bp ; If Y1 larger Y2 mov bx,X1 mov cx,X2 mov dx,Y2 mov yend,di ; Set end of line, yend = Y1 .IF delta_x == 0 mov xinc,0 .ELSE .IF cx GT bx ; Is X2 greater X1 ? mov xinc,-1 .ELSE mov xinc,1 .ENDIF .ENDIF .ELSE mov bx,X2 mov cx,X1 mov dx,Y1 mov yend,bp ; yend = Y2 .IF delta_x == 0 mov xinc,0 .ELSE .IF bx GT cx ; Is X2 larger X1 ? mov xinc,1 .ELSE mov xinc,-1 .ENDIF .ENDIF .ENDIF call plotadot ; Plot the first point (cx,dx) mov bp,incr1 ; Set regs with the 2 increments mov di,incr2 .WHILE dx LT yend ; While Y less Yend inc dx ; Increment Y .IF decision LT 0 add decision,bp ; Choose Si, no change in X .ELSE ; else choose Ti, X incremented add cx,xinc ; Increment X add decision,di .ENDIF call plotadot ; Plot all other points (Xn,Yn) .ENDW ret ; Return to DOS line endp end Listing 5.1 Straight line code using the Bresenham algorithm
To test the line drawing subroutine LINE at various screen resolutions we use the program shown in Listing 5.2. On starting you are prompted for a standard video mode. Please enter your choice in decimal form, but if you prefer you can give a null entry and the default video mode 6 with resolution 640*200 will be used. The same line drawing subroutine can also be used with the much more useful SVGA VBE video modes. You just use the SET_VBE_MODE routine instead of the standard SET_V_MODE routine.
.model small ; Listing 5.2 ; Source file is TESTLINE.ASM .stack EXTRN write_string:proc,read_string:proc EXTRN line:proc,asci2bin:proc,set_v_mode:proc .386 .data CR EQU 0Dh LF EQU 0Ah mode db 0 ; Video mode video_memory dw ? parmblock dw 4 ; Starting column dw 2 ; Starting row dw 638 ; End column dw 198 ; End row db 1 ; Colour. 0,1 for 640*200 ; 0-3 for 400*200 db 0FFh ; Plotting pattern for full line dw 0 ; Not used dw 0 ; Not used routine_address dw ? pixels_per_line dw ? bytes_per_line dw ? number_of_lines dw ? dw 0 ; 0 = replace, 2 = XOR dd ? dw ? dw ? ; End of the parameter block Illegal_no db CR,LF,'Illegal Number$' Illegal_mode db CR,LF,'Illegal Mode$' prompt1 db CR,LF,'Starting column:$' prompt2 db CR,LF,'Starting row:$' prompt3 db CR,LF,'End column:$' prompt4 db CR,LF,'End row:$' prompt5 db CR,LF,'Colour:$' prompt dw prompt1 dw prompt2 dw prompt3 dw prompt4 dw prompt5 kb_buffer db 64,0 ; Keyboard buffer db 64 DUP (?) mode_prompt db CR,LF,'Video Mode in decimal:$' video_mode db 6 ; Default is 640*200 2 colour .CODE start: MOV AX,DGROUP ; Make Data Segment addressable, MOV DS,AX ; set DS to point to data mov ah,0Fh ; Get video state int 10h mov mode,al ; Save mode xor bx,bx mov cx,5 ; Set to loop 5 times again: mov dx,[prompt+bx] call write_string ; Prompt for variable lea dx,kb_buffer ; Point at keyboard buffer call read_string ; Get input from keyboard cmp [kb_buffer+1],0 ; Check we got some data je skip ; Skip to next param if nul call asci2bin ; Convert ASCII chars to binary no jnc ok lea dx,illegal_no call write_string jmp fin ok: mov parmblock[bx],ax; Set the variable skip: add bx,2 loop again lea dx,mode_prompt ; Now prompt & setup the required call write_string ; video mode lea dx,kb_buffer call read_string cmp [kb_buffer+1],0 ; If nul je skip2 ; use default video mode 6 call asci2bin jnc ok2 lea dx,illegal_no call write_string jmp fin ok2: mov video_mode,al skip2: mov ah,0 mov al,video_mode ; Set up the video mode call set_v_mode ; Set plotting routine jnc ok3 ; and the video memory lea dx,illegal_mode call write_string jmp fin ok3: mov number_of_lines,ax mov pixels_per_line,cx mov routine_address,dx mov video_memory,es mov bx,cx ; Convert pixels/line > bytes/line shr bx,3 mov bytes_per_line,bx lea si,parmblock ; Point at the parameter block call line ; Draw the line mov ah,1 int 21h ; Wait for a keypress mov al,mode mov ah,0 int 10h ; Restore original mode FIN: MOV AH,4Ch INT 21H ; Return to DOS END start Listing 5.2 Draws a straight line using Breshenhams algorithm
5.2 The Michalski Straight Line Algorithm
Whilst Bresenham's algorithm is perhaps the most widely used, there are other useful line
drawing algorithms and the algorithm by Michalski, (Refs 25,26) is certainly on par with
Bresenham, at least in the tests I did. I came across a worked example of his algorithm
on a bulletin board and noticed that it had a little extra coding which permits the easy
drawing of non continuous, or dotted lines. There is also provision to draw a subset of the
line, or to skip a defined part of the line, which could be useful in some applications.
The authors name was not contained in the downloaded file, so I acknowledge his original
coding which I have modified and expanded to fit in better with my suite of pixel plotting
subroutines. On inspection you will see that part of the code section is self modifying,
that is, some instructions are changed by previous code. I don't pretend to understand
exactly whats going on here, but suspect its the key to the codes speed. I present it for
what it is, a useful alternative algorithm.
Incidentally the part of the code that draws the interrupted line, could if required, be incorporated in the Bresenham algorithm as the graphics parameter block we use is general and will allow the necessary data to be set there for use by the handling subroutine. My preference however is to keep Bresenham's algorithm as fast as possible and to use the DRAWLINE algorithm when I have need for its other facilities. Documentation on the calling convention, is contained in GLIB.HTML, as it is for all the routines in this book.
.MODEL small ; Listing 5.3 ; Source file is DRAWLINE.ASM ; Self-modifying program implements fast-vector algorithm ; described by Michalski, Doctor Dobb's Journal #74, 12/82 ; see also: FAST-LINE DRAWING TECHNIQUE, BYTE, Aug 81 .DATA skip_count dw ? ; Copy held here ; Equates to variables in calling pgm's parameter block x1 equ word ptr [si] ; Line coordinates y1 equ word ptr [si+2] ; " x2 equ word ptr [si+4] ; " y2 equ word ptr [si+6] ; " colour equ byte ptr [si+8] ; Colour attribute pattern equ byte ptr [si+9] ; Repetition pattern for ; drawing the line len equ word ptr [si+10] ; Line length skip equ word ptr [si+12] ; Skip length plotadot equ word ptr [si+14] ; Address of the fast dot ; plotting routine ; These are values that will be overlayed in the code inc_x EQU 41h dec_X EQU 49h inc_Y EQU 42h dec_Y EQU 4Ah ; These are the addresses where new code is overlayed adj_long_axis EQU BYTE PTR CS:[DI] adj_master EQU WORD PTR CS:[DI+3] test_master EQU WORD PTR CS:[DI+7] alt_adj_master EQU WORD PTR CS:[DI+13] adj_shrt_axis EQU BYTE PTR CS:[DI+15] .CODE PUBLIC DRAWLINE ;---------------------------------------------------------------; ; Routine draws a line between coordinates X1,Y1 & X2,Y2 ; ; ; ; ENTRY: ; ; DS:SI Points at the parameter block, where ; ; ; ; si+0 = x1 starting horizontal pixel position ; ; si+2 = y1 starting vertical pixel position ; ; si+4 = x2 ending HPP ; ; si+6 = y2 ending VPP ; ; si+8 = colour attribute ; ; si+9 = line plotting bit pattern. ; ; 033h=00110011b, a dotted line .. .. .. ; ; 055h=01010101b, a dotted line . . . . . ; ; 077h=01110111b, a dashed line - - - - - ; ; 0Fh =00001111b, a long_dash line --- --- ; ; 0FFh=11111111b, a continuous line --------- ; ; ; ; si+10 = length ; ; 0 = draw entire line ; ; else = draw sub- or super-set of this vector ; ; si+12 = skip length ; ; number of pels to go before starting to draw ; ; 0 = draw entire line ; ; si+14 = address of the dot plotting routine ; ; ; ; ES Points to start of video memory ; ;---------------------------------------------------------------; DRAWLINE PROC USES ax bx cx dx di bp mov bl,inc_x ; assume xstep = +1 mov ax,x2 sub ax,x1 jge short dl1 ; if x1 LE x2 then no change mov bl,dec_x ; xstep = -1 neg ax ; Xdist = ABS(Xdist) dl1: mov cx,ax ; save Xdist mov bh,inc_y ; assume ystep = +1 mov ax,y2 sub ax,y1 jge short dl2 ; if y1 LE y2 then no change mov bh,dec_y ; ystep = -1 neg ax ; Ydist = ABS(Ydist) dl2: mov dx,ax ; save ydist mov di,offset CS:modify_base ; point to the code ; to modify cmp dx,cx ; determine longest axis jge short dl3 ; Y is longer, so skip xchg cx,dx ; swap xdist, ydist xchg bl,bh ; swap inc/dec X/Y values ; MODIFY: dl3: mov adj_long_axis,bh ; the 1st inc/dec code mov adj_master,cx ; Main duty master adjustment shr cx,1 ; Set up cycle tester mov test_master,cx ; Test for cycling mov alt_adj_master,dx ; Alternate adjustment mov adj_shrt_axis,bl ; Alternate inc/dec code mov di,dx ; di is counter: Long axis length cmp len,0 ; if length greater than 0 je short dl4 mov di,len ; Then use it as counter dl4: mov cx,skip ; Get skip count mov skip_count,cx ; Store a copy mov cx,X1 ; Get other arguments mov dx,Y1 mov al,colour xor bx,bx ; Duty master starts = 0 mov bp,bx ; Change to BP as BX is used by ; the fast dot plotting routines ; to return the display offset; ; not used here,but may be used by ; other routines mov ah,pattern ; Get pattern into reg for fast access ;------ Top of the Vector plotting loop ------- dl5: cmp skip_count,0 ; Test skip count je short ok_plot dec skip_count jmp short no_plot ok_plot:test ah,1 ; Is bit 0 set jz short skip_a_dot ; Don't plot if not call plotadot ; plot a dot using appropriate subroutine skip_a_dot: cmp pattern,0FFh ; Is the line continuous ? je short no_plot ror ah,1 ; Rotate the pattern 1 bit to the ; right ready for next dot plot. ; In this way the pattern ; automatically repeats ; Most of the following code is modified by the previous sequence. ; The 1111h's are dummy values that are always overlaid. modify_base label byte no_plot:inc cx ; inc/dec cx/dx: Adjust long axis ptr add bp,1111h ; xdist or ydist: Adjust duty master cmp bp,1111h ; ydist or xdist: Check cycle position jle short dl6 ; skip if short axis is still OK sub bp,1111h ; xdist or ydist: Adjust duty master inc dx ; inc/dec dx/cx: Adjust short axis ptr dl6: dec di ; di is used as a counter jge short dl5 ; do next dot if not finished ret DRAWLINE ENDP end Listing 5.3 Straight line code using the Michalski algorithm
The short test program TESTL_TO, shown in Listing 5.5, is a simple test of the subroutine which draws lines around the boundaries of the screen, using the preset 06h graphics mode. Note also that the lines drawn are not continuous, but are written with a repetitive pattern determined by the value 33h (or 01010101b). That is, we only plot every other pixel in the line; other patterns can also be used set simply by setting the appropriate bits in this mask. After the lines have been drawn, the DOS function 021h/01h, is used to pause the program until any key is pressed; this allows the image to be inspected.
.MODEL small ; Listing 5.4 ; Source file is LINE_TO.ASM x1 EQU [si] ; Equates to data in calling pgm y1 EQU [si+2] x2 EQU [si+4] y2 EQU [si+6] colour EQU byte ptr [si+8] ; BYTE. The pixel colour EXTRN drawline:proc .CODE PUBLIC line_to ;-----------------------------------------------; ; Draws a line from X1,Y1 (last location) to ; ; X2,Y2 and then copies X2,Y2 to X1,Y1 in the ; ; parameter block ready for next call. ; ; ; ; Entry: SI points at parameter block ; ; in the calling program ; ;-----------------------------------------------; line_to PROC uses ax call drawline ; Draw line to the required location mov ax,X2 ; Reset X1,Y1 ready for next call of mov X1,ax ; the routine. mov ax,Y2 mov Y1,ax ret line_to ENDP end Listing 5.4 Draws a line from the last to the current end position
.MODEL small ;Listing 5.5 ; Source file is TESTL_TO.ASM .STACK .386 ;**** For testing LINE_TO routine **** EXTRN line_to:proc,set_v_mode:proc,write_string:proc .DATA CR EQU 0Dh LF EQU 0Ah parmblock EQU THIS word X1 dw 0 Y1 dw 0 X2 dw 600 Y2 dw 0 colour db 1 pattern db 033h ; 0FFh is a continuous line dw 0 dw 0 routine_address dw ? pixels_per_line dw ? bytes_per_line dw ? number_of_lines dw ? dw 0 ; Replace action dd 0 dw ? dw ? ; End of the parameter block mode db ? illegal_mode db CR,LF,'Illegal Mode$' .CODE begin: mov ax,DGROUP ; Set up data segment mov ds,ax mov ah,0Fh int 10h ; Get current video mode mov mode,al ; Save it xor ah,ah mov al,6 ; Select mode 6 call set_v_mode jnc ok lea dx,illegal_mode call write_string jmp fin ok: mov number_of_lines,ax mov pixels_per_line,cx mov routine_address,dx mov bx,cx ; Convert pixels/line to bytes/line shr bx,3 mov bytes_per_line,bx lea si,parmblock call line_to ; Draw 1st line mov y2,198 call line_to mov x2,0 call line_to mov y2,0 call line_to mov ah,1 int 21h ; Wait for keypress mov al,mode mov ah,0 int 10h ; restore orig mode fin: mov ah,4Ch int 21h ; Return to DOS end begin Listing 5.5 Tests out the LINE_TO subroutine
Filename Ext Length Description of the file ANGLE ASM 872 Get angle, given delta y & delta x ASC2BDS ASM 1075 ASCII to binary. Command line use ASCI2BIN ASM 1774 Convert ASCII to binary ASMSUB ASM 511 For the BASIC/ASM inteface test BESTLINE ASM 6137 Best Straight line program BEZIER ASM 5999 Bezier curve subroutine BLINE ASM 4922 Best straight line for 100 points BLINE3 DAT 107 Data for the best straight line pgm BUTERFLY ASM 4243 A program to draw a butterfly curve CHEESE ASM 2382 Makes a Cantor cheese fractal CHKEQUIP ASM 1586 Checks the equipment hardware CHKLINE ASM 1295 Checks if a fill lines been done already CHORDS ASM 2599 Symmetric chords for circle fill CIRCLE ASM 1205 The Michener Breshenham algorithm CIRCLE2 ASM 898 The Paterson Kientzle alogorithm CKVESA ASM 1199 For use in C - MASM interface test CLIP ASM 4730 Clip a straight line DELAY ASM 756 Produce a short delay DISP_DEC ASM 952 Displays a decimal number DRAWLINE ASM 5126 The Michalski line algorithm DRAW_BOX ASM 1001 Draw a rectangular box ELLIPSE ASM 2898 Ellipse using Keintzle algorithm ELLIPSE1 ASM 2618 Ellipse using floating point code FDELAY ASM 773 Time delay using a FORTRAN call FILLBOX ASM 1365 Draws a box filled with colour FILLCIRC ASM 1432 Fill a circle routine FILLELPS ASM 3202 Draws a solid ellipse FILLPOLY ASM 8075 Draws a solid polygon FERN ASM 2892 Draws a Fractal Fern FRAME ASM 1064 Draw frame around the screen FSOUND ASM 1450 For FORTRAN interface test GETCOORD ASM 702 Get mouse coordinates GET_NORM ASM 1969 Get the screen normalisation factor GET_P16 ASM 2675 Get pixel in 16 colour VBE modes GET_P256 ASM 1561 Get pixel in 256 colour VBE modes HOREFILL ASM 2555 Used in filling an ellipse INVERT_S ASM 2298 Inverts selected area of the screen IKEDA ASM 4779 The Ikeda attractor LINE ASM 4066 The Breshenham algorithm LINE_TO ASM 697 Draws a line between two points LISSJ ASM 4521 Draws a Lissajous curve LORENZ ASM 4642 The Lorenz attractor MAKECIRC ASM 3177 Make a circle using the mouse MANDEL ASM 4581 The Mandelbrot fractal MEAN ASM 795 Calculates the mean of a F.P array MENU ASM 6580 Menu selection menu using the mouse MENU2 ASM 13141 Select from 2D menu using the mouse MHANDLER ASM 6483 The mouse handler subroutine MIRROR_S ASM 2296 Make mirror image of selected window NORMWRIT ASM 534 Slow BIOS pixel write ORTHOG_C ASM 8851 Draw orthogonal circles. VBE mode PADRCGA2 ASM 1350 Get pixel address. CGA2 pixel plot PADRMCGA ASM 647 Get pixel address. MCGA pixel plot PADR_256 ASM 1364 Get pixel addr. 256 colour VGA plot PADR_VGA ASM 1388 Get pixel addr. 16 colour VGA plot PARMBLOK ASM 910 Data block for graphics subroutines PLOT4 ASM 1741 For use in consructing an ellipse PLOTCGA2 ASM 1503 Plot pixel in CGA 2 colour mode PLOTMCGA ASM 1167 Plot pixel on MCGA 256 colour mode PLOT_256 ASM 1072 Plot pixel. Std VGA 256 colour mode PLOT_VGA ASM 2132 Plot pixel. Std VGA 16 colour mode POLYGON ASM 2454 Subroutine to draw a polygon PRINTSCR ASM 4457 Send screen image to laser printer PUT_P16 ASM 2938 Plot pixel. VBE 16 colour modes PUT_P16M ASM 2023 Plot pixel. VBE 16.7m colour modes PUT_P256 ASM 2066 Plot pixel. VBE 256 colour modes PUT_P32K ASM 2049 Plot pixel. VBE 32/64k colour modes RESTORE ASM 904 Restores the graphics controller ROTATE ASM 2380 Rotate a cartesian coordinate RUBBER_B ASM 3669 Used in POLYGON construction SCANLINE ASM 737 Scan cmd line & advance to next char SETBANK ASM 630 Get the video memory bank SETVBEM ASM 7271 Set the Vesa Bios Extension mode SETVMODE ASM 2927 Set a standard video mode SHRINK ASM 1075 Reduce DOS memory use to a minimum SIERP ASM 4678 Make a Sierpinski fractal SQUARE ASM 3960 Draws a square SMILEY ASM 2743 Transfers a "smiley" image to LPT2 STDMODE ASM 2832 Demo of setting a standard mode SVGAINFO ASM 14137 Displays information on VBE modes SYMPOLY ASM 4253 Make symmetric polygon with mouse SYM_PLOT ASM 2313 For use by circle subroutine TEMPBEZ ASM 795 Draws a temporary Bezier curve TEMPBOX ASM 1881 Draws a temporary box TEMPCIRC ASM 858 Creates a temporary circle TEMPLINE ASM 2177 Creates a line in rubber band style TEST16 ASM 2675 Tests the 16 colour vbe modes TEST256 ASM 2572 Tests the 256 colour vbe modes TESTB ASM 1953 Test the making of a Bezier curve TESTB2 ASM 2493 Tests the Bezier curve. VBE version TESTB3 ASM 5472 Bezier construction using the mouse TESTBOX1 ASM 4685 Test drawing of a rectangular box TESTBOX2 ASM 4817 Drawing & filling box using a mouse TESTBOX3 ASM 4682 Test the drawing of a square TESTC2 ASM 4811 Draws a circle interactively TESTCIRC ASM 3950 Draws concentric circles & deletes TESTCLIP ASM 3045 Test clipping of a straight line TESTCURS ASM 3604 Test the special cursor TESTDPMS ASM 529 Tests Power management of VGA card TESTELPS ASM 4143 Test the drawing of an an ellipse TESTFEPS ASM 4329 Test filling of ellipses TESTFILL ASM 3935 Tests circle filling TESTFPOL ASM 5196 Tests filling a Polygon TESTLINE ASM 2566 Tests Breshenhans line algorithm TESTL_TO ASM 1208 Tests the Line_To function TESTMLIN ASM 2874 Tests Michalski line alogorithm TESTP32K ASM 2363 Tests the 32k/64k colour VBE modes TESTP16M ASM 2392 Tests the 16m colour VBE modes TESTPOLY ASM 4901 Test out poygon construction TESTROT ASM 4869 Test rotate point routine TESTSETV ASM 1740 Tests setting of specified VBE mode TESTSPOL ASM 4943 Test drawing of a symetric polygon TESTSPR ASM 4683 Tests screen image transfer to LPT2 TESTTRAN ASM 5145 Tests the transform of coordinates TEST_TL ASM 4640 Test drawing of a rubber band line TOGGLE ASM 891 Toggle the special cursor on/off TRANSFM ASM 2240 Transform coordinates by scaling, rotation and translation VBEMODE ASM 2808 Demo of setting a VBE routine VESA INC 1176 Useful include file for VBE use WRITCHAR ASM 314 Write a character to the screen WRITEDEC ASM 949 Write 16 bit unsigned no in decimal WRITEHEX ASM 877 Writes a byte as 2 hex digits WRITHEXD ASM 897 Converts nibble & write to screen
Filename Ext Length Description of the file BESTLINE EXE 2528 Best Straight Line Calculation BUTERFLY EXE 2040 The Butterfly curve CHEESE EXE 1366 The Cantor cheese fractal FERN EXE 1948 The Fractal Fern IKEDA EXE 1426 The Ikeda attractor LISSJ EXE 1546 A Lissajous diagram LORENZ EXE 1412 The Lorenz attractor MANDEL EXE 2324 The Mandelbrot fractal MENU EXE 2752 Select from a horizontal menu MENU2 EXE 2974 Select from a 2 dimension menu MOUSE EXE 93316 MS Driver 9.00 ORTHOG_C EXE 2772 Draw an orthogonal circle SIERP EXE 1460 The Sierpinski fractal STDMODE EXE 815 Sets a standard video mode SVGAINFO EXE 3594 Gets SVGA info on the available modes TEST16 EXE 1562 Test 16 colour VBE modes TEST256 EXE 1488 Test 256 colour VBE modes TESTB EXE 1714 The Bezier Curve TESTB2 EXE 2304 Draw the Bezier curve using VBE modes TESTB3 EXE 3010 Interactive Bezier curve construction TESTBASM EXE 6692 Tests the BASIC - ASM interface TESTBOX1 EXE 2454 Test drawing a rectangular box TESTBOX2 EXE 2608 Draw & fill a box using the mouse TESTBOX3 EXE 2744 Draw a square using the mouse TESTC2 EXE 2872 Draws circle interactively with mouse TESTCIRC EXE 2162 Draws circles in VBE mode & del by XOR TESTCLIP EXE 1718 Tests the clipping of a straight line TESTCURS EXE 2036 Test the special cursor TESTCV EXE 3530 Tests the C - ASM interface TESTDPMS EXE 552 Test power management on a graphics card. TESTELP1 EXE 1700 Test draws Ellipse1. A bit ragged TESTELPS EXE 1896 Test draws the Kientzle ellipse TESTFEPS EXE 2142 Test filling of ellipses TESTFILL EXE 2330 Tests circle filling TESTFPOL EXE 5438 Tests drawing a solid polygon TESTINVS EXE 2218 Test the inversion of screen images TESTLINE EXE 1864 Tests Breshenhams algorithm TESTL_TO EXE 1300 Tests LINE-TO subroutine; dotted frame TESTMIRS EXE 2228 Tests the making of a mirror image TESTMLIN EXE 1660 Tests Michalski's algorithm TESTP32K EXE 1442 Tests the 32k/64k colour VBE modes TESTP16M EXE 1456 Tests 16M colour VBE modes TESTPOLY EXE 3282 Test the construction of polygons TESTROT EXE 2100 Tests the rotate point function TESTSETV EXE 1872 Tests setting & plotting of VBE modes TESTSPOL EXE 2936 Tests drawing symmetric polygons TESTSPR EXE 2776 Test transfer of screen image to LPT2 TESTTONE EXE 19482 Test the FORTRAN - ASM interface TESTTRAN EXE 2668 Tests the coordinate transform subroutine TEST_TL EXE 2500 Test drawing a temporary line UNIVBE EXE 74412 Universal Vesa Driver VBEMODE EXE 817 Sets a VBE mode
Filename Ext Length Description FORTLIB LIB 2085 A skeleton FORTRAN library FORTLIB LST 464 List file for the FORTRAN library GLIB LIB 25625 Library containing graphics routines GLIB LST 8159 List file for the graphics library GLIB DOC 31825 Documentation file for graphics lib. TESTBASM BAS 357 For testing the BASIC-ASM interface TESTCV C 273 For testing the "C" - ASM interface TESTTONE FOR 462 For testing the FORTRAN-ASM interface