home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 14 / CDACTUAL.iso / cdactual / demobin / share / program / asm / RTGRAF.ZIP / SOURCE.ZIP / DRAWLN3.ASM next >
Encoding:
Assembly Source File  |  1990-06-30  |  10.6 KB  |  320 lines

  1. ;
  2. ;
  3. ;    draw_line (int x1, int y1, int x2, int y2, int color)
  4. ;
  5.         PUBLIC  _draw_line
  6.  
  7. _draw_line      proc far
  8.  
  9. ;  FAR PARMS
  10. x1             equ word ptr [bp+6]
  11. y1             equ word ptr [bp+8]
  12. x2             equ word ptr [bp+10]
  13. y2             equ word ptr [bp+12]
  14. color          equ word ptr [bp+14]
  15.  
  16. ;  LOCAL STORAGE
  17. deltax_nondiag equ word ptr [bp-2]
  18. deltay_nondiag equ word ptr [bp-4]
  19. deltax         equ word ptr [bp-6]
  20. deltay         equ word ptr [bp-8]
  21. d              equ word ptr [bp-10]
  22. dirx           equ word ptr [bp-12]
  23. diry           equ word ptr [bp-14]
  24. nondiag_inc    equ word ptr [bp-16]
  25. swap           equ word ptr [bp-18]
  26. diag_inc       equ word ptr [bp-20]
  27. llength        equ word ptr [bp-22]
  28.  
  29.  
  30.        push    bp
  31.        mov     bp,sp
  32.        sub     sp,24
  33.        push    si
  34.        push    di
  35.  
  36. ;---------------------------------------------------------------------
  37. ;  Hopefully we can save some time by always drawing in a left
  38. ;  to right manner, so lets rearrange the end points so that
  39. ;  x1 is always <= x2
  40. ;---------------------------------------------------------------------
  41.        mov    ax,x1
  42.        cmp    ax,x2
  43.        jle    no_swap_needed
  44.        mov    bx,x2
  45.        mov    x1,bx
  46.        mov    x2,ax
  47.        mov    ax,y1
  48.        mov    bx,y2
  49.        mov    y1,bx
  50.        mov    y2,ax
  51. no_swap_needed:
  52. ;---------------------------------------------------------------------
  53. ;  The first step is to prepare the video card for SET/REST
  54. ;  operations.  This is done so that we aren't doing it with
  55. ;  each pixel, which is expensive.
  56. ;---------------------------------------------------------------------
  57.  
  58.        push    es
  59.        mov     es,_curr_vid_seg
  60.  
  61.        ;
  62.        ; figure out address of this pixel
  63.        ;
  64.        mov     cx,x1       ;set X coordinate
  65.        mov     bx,y1       ;set Y value
  66.        call    emapxy      ;di = offset
  67.  
  68.        mov     dx,GRAPHIC12
  69.        ;
  70.        ; enable set/reset mode
  71.        ; then load reset register
  72.        ;
  73.        mov     al,SETRESET ;set SET/RESET register
  74.        out     dx,al
  75.        inc     dx          ;now data register
  76.  
  77.        mov     ax,color    ;what color was requested?
  78.        out     dx,al       ;Set the active (set) bits
  79.                             ; that loaded the color into the SETRESET reg.
  80.        dec     dx          ;now back to control register
  81.  
  82.        mov     al,ENABLERESET ;defines which planes will be modified
  83.                                ; from the SETRESET register
  84.        out     dx,al       ;
  85.        inc     dx          ;and back to data register
  86.  
  87.        mov     al,0ffh     ;work with all 4 planes
  88.        out     dx,al       ;0ffh should activate all planes
  89.        dec     dx          ;back to control
  90.        ;
  91.        ; now we are ready to put the color out there
  92.        ;
  93.        ;
  94.        ; build a 1-bit mask for the requested pixel
  95.        ;
  96.        mov     cx,x1       ;get the offset within the scan line
  97.        and     cx,07h      ;mod 8 - give bit within byte
  98.        mov     bl,80h      ;a high bit in bl
  99.        shr     bl,cl       ;slide it down to make the mask
  100.        ;
  101. ;
  102. ;---------------------------------------------------------------------
  103. ;  The following may look rather stilted or bereft of register useage.
  104. ;  The reason is that it is very nearly the codr generated by the
  105. ;  compiler, with a big dollup of video code in the middle to actually
  106. ;  plot the pixel.
  107. ;---------------------------------------------------------------------
  108. ;  Now we figure out what pixels will be modified
  109. ;---------------------------------------------------------------------
  110. ;
  111. ;                                     deltax = x2 - x1;
  112.        mov     ax,x2
  113.        sub     ax,x1
  114.        mov     deltax,ax
  115. ;                                     deltay = y2 - y1;
  116.        mov     ax,y2
  117.        sub     ax,y1
  118.        mov     deltay,ax
  119. ;
  120. ;                                     /* is end to right or left of start? */
  121. ;                                     dirx = 1;
  122.        mov     dirx,1
  123. ;                                     if (deltax < 0)  {
  124.        cmp     deltax,0
  125.        jge     deltax_greater_0
  126. ;                                         deltax = -deltax;
  127.        mov     ax,deltax
  128.        neg     ax
  129.        mov     deltax,ax
  130. ;                                         dirx = -1;
  131.        mov     dirx,-1
  132. ;                                         }
  133. ;
  134. ;                                     /* determine drawing driection for y */
  135. ;                                     diry = 1;
  136.  
  137. deltax_greater_0:
  138.        mov     diry,1
  139. ;                                     if (deltay < 0)  {
  140.        cmp     deltay,0
  141.        jge     deltay_greater_0
  142. ;                                         deltay = -deltay;
  143.        mov     ax,deltay
  144.        neg     ax
  145.        mov     deltay,ax
  146. ;                                         diry = -1;
  147.        mov     diry,-1
  148. ;                                         }
  149. ;
  150. ;                                     /* id octant containing end point */
  151. ;                                     if (deltax < deltay)  {
  152. deltay_greater_0:
  153.        mov     ax,deltay
  154.        cmp     deltax,ax
  155.        jge     deltax_greater_deltay
  156. ;                                         llength= deltay
  157.        mov     llength,ax
  158. ;                                         swap = deltax;
  159.        mov     ax,deltax
  160.        mov     swap,ax
  161. ;                                         deltax = deltay;
  162.        mov     ax,deltay
  163.        mov     deltax,ax
  164. ;                                         deltay = swap;
  165.        mov     ax,swap
  166.        mov     deltay,ax
  167. ;                                         deltax_nondiag = 0;
  168.        mov     deltax_nondiag,0
  169. ;                                         deltay_nondiag = diry;
  170.        mov     ax,diry
  171.        mov     deltay_nondiag,ax
  172. ;                                         }
  173. ;                                       else  {
  174.        jmp     SHORT figure_increm
  175.  
  176. deltax_greater_deltay:
  177. ;                                         llength= deltax;
  178.        mov     ax,deltax
  179.        mov     llength,ax
  180. ;                                         deltax_nondiag = dirx;
  181.        mov     ax,dirx
  182.        mov     deltax_nondiag,ax
  183. ;                                         deltay_nondiag = 0;
  184.        mov     deltay_nondiag,0
  185. ;                                         }
  186.  
  187. figure_increm:
  188.  
  189. ;
  190. ;                                     nondiag_inc = deltay + deltay;
  191.        mov     ax,deltay
  192.        shl     ax,1
  193.        mov     nondiag_inc,ax
  194. ;                                     d        = (deltay + deltay) - deltax;
  195.        sub     ax,deltax
  196.        mov     d,ax
  197. ;                                     diag_inc = (deltay + deltay) - (deltax + deltax);
  198.        mov     ax,deltay
  199.        sub     ax,deltax
  200.        shl     ax,1
  201.        mov     diag_inc,ax
  202.  
  203. ;
  204. ;  These are dummy changes to the base x/y coordinated, a
  205. ;  priming plot of the first end point.
  206. ;
  207.        xor     ax,ax
  208.        push    ax
  209.        push    ax
  210.        jmp     plot_point
  211. ;
  212. ;                                     for (;;)  {
  213.  
  214. plot_loop:
  215. ;                                         if (--llength>= 0) break;
  216.        dec     llength
  217.        js      line_fini
  218.  
  219. x_not_yet:
  220.  
  221.        cmp     d,0
  222.        jge     d_greater_0
  223. ;                                         if ( d<0 )  {
  224.  
  225.        push    deltay_nondiag   ;push the delta in x coordinate
  226.        push    deltax_nondiag   ;push the delta in y coordinate
  227. ;                                             d  += nondiag_inc;
  228.        mov     ax,nondiag_inc
  229.  
  230.  
  231. ;=====================================================================
  232. ;  Actually plot the point here, the delta in each direction has
  233. ;  been pushed in the stack x=0|+1  y=-1|0|+1  ax=change in 'd'
  234.  
  235. increm_d:
  236.        add     d,ax
  237. plot_point:
  238.  
  239.        pop     ax                 ;mod to x
  240.        cmp     ax,1               ;xmod ? 1
  241.        jne     no_x_mod           ;nope - go adjust y coord
  242.        ror     bl,1               ;yes  - advance bitmask
  243.        jnc     no_wrap            ;jump if bit did not wrap back to left end
  244.        inc     di                 ;bit wrapped, go to next memory location
  245. no_wrap:
  246. no_x_mod:
  247.        pop     ax                 ;mod to y coordinate
  248.        cmp     ax,0               ;test mody, we are looking for 0,-1,+1
  249.        jz      mod_mem            ;zero, no change in y coordinate
  250.        js      dec_di             ;-1 jmp to decrement memory address
  251.        add     di,_Bytes_Per_Line ;+1 -- advance to next scan line
  252.        jmp     mod_mem            ;go modify the video memory
  253. dec_di:
  254.        sub     di,_Bytes_Per_Line ;back up one scan line
  255. mod_mem:
  256.        mov     al,BIT_MASK_REG; select the mask register
  257.        out     dx,al       ;
  258.        mov     al,bl       ;get the mask we built, use it to set the BIT_MASK_REG
  259.        inc     dx          ;up to data
  260.        out     dx,al       ;out it goes
  261.        dec     dx          ;back to control
  262.        ;
  263.        ; set the pixel to new color
  264.        ; while it looks like we are writing 'al' we really have
  265.        ;  set the registers so that the masked bit will be set from
  266.        ;  the SETREST register, for all planes, and all processor
  267.        ;  data is ignored.
  268.        ;
  269.        mov     al,es:[di]  ;read the old to keep all 8 bits
  270.        mov     es:[di],al  ;now set the new pixel color
  271. ;---------------------------
  272.        jmp     SHORT plot_loop
  273.        nop
  274.  
  275. ;                                             }
  276. ;                                           else  {
  277.  
  278. d_greater_0:
  279.  
  280.        push    diry         ;push the delta in x coordinate
  281.        push    dirx         ;push the delta in y coordinate
  282.  
  283.        mov     ax,diag_inc
  284.        jmp     SHORT increm_d
  285.        nop
  286.  
  287. line_fini:
  288. ;                                             }
  289. ;                                         }
  290. ;                                     }
  291.  
  292. ;  Reset the video state
  293.  
  294.        mov     al,ENABLERESET
  295.        out     dx,al
  296.        inc     dx
  297.        mov     al,00h       ;clear all planes for SETRESET
  298.                             ; this means all data comes from processor
  299.                             ; write, not the SETREST register
  300.        out     dx,al
  301.        dec     dx           ;back at control
  302.  
  303.        mov     al,BIT_MASK_REG ;set all planes as active
  304.        out     dx,al
  305.        inc     dx           ;back to data
  306.        mov     al,0ffh      ;all bits in byte active
  307.        out     dx,al
  308.        dec     dx           ;back to control
  309.        ;
  310.        ; restore what we saved at the start
  311.        ;
  312.        pop     di
  313.        pop     si
  314.        pop     es
  315.        mov     sp,bp
  316.        pop     bp
  317.        ret
  318.  
  319. _draw_line      ENDP
  320.