home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / video / 6 / 6_9.asm < prev   
Encoding:
Assembly Source File  |  1988-08-11  |  4.4 KB  |  221 lines

  1.         TITLE    'Listing 6-9'
  2.         NAME    Line13
  3.         PAGE    55,132
  4.  
  5. ;
  6. ; Name:        Line13
  7. ;
  8. ; Function:    Draw a line in MCGA/VGA 320x200 256-color mode
  9. ;
  10. ; Caller:    Microsoft C:
  11. ;
  12. ;            void Line13(x1,y1,x2,y2,n);
  13. ;
  14. ;            int x1,y1,x2,y2;    /* pixel coordinates */
  15. ;
  16. ;            int n;            /* pixel value */
  17. ;
  18.  
  19. ARGx1        EQU    word ptr [bp+4]    ; stack frame addressing
  20. ARGy1        EQU    word ptr [bp+6]
  21. ARGx2        EQU    word ptr [bp+8]
  22. ARGy2        EQU    word ptr [bp+10]
  23. ARGn        EQU    byte ptr [bp+12]
  24. VARincr1    EQU    word ptr [bp-2]
  25. VARincr2    EQU    word ptr [bp-4]
  26. VARroutine    EQU    word ptr [bp-6]
  27.  
  28. BytesPerLine    EQU    320
  29.  
  30.  
  31. _TEXT        SEGMENT    byte public 'CODE'
  32.         ASSUME    cs:_TEXT
  33.  
  34.         EXTRN    PixelAddr13:near
  35.  
  36.         PUBLIC    _Line13
  37. _Line13        PROC    near
  38.  
  39.         push    bp        ; preserve caller registers
  40.         mov    bp,sp
  41.         sub    sp,6        ; stack space for local variables
  42.         push    si
  43.         push    di
  44.  
  45. ; check for vertical line
  46.  
  47.         mov    si,BytesPerLine    ; initial y-increment
  48.  
  49.         mov    cx,ARGx2
  50.         sub    cx,ARGx1    ; CX := x2 - x1
  51.         jz    VertLine13    ; jump if vertical line
  52.  
  53. ; force x1 < x2
  54.  
  55.         jns    L01        ; jump if x2 > x1
  56.  
  57.         neg    cx        ; CX := x1 - x2
  58.         
  59.         mov    bx,ARGx2    ; exchange x1 and x2
  60.         xchg    bx,ARGx1
  61.         mov    ARGx2,bx
  62.  
  63.         mov    bx,ARGy2    ; exchange y1 and y2
  64.         xchg    bx,ARGy1
  65.         mov    ARGy2,bx
  66.  
  67. ; calculate dy = ABS(y2-y1)
  68.  
  69. L01:        mov    bx,ARGy2
  70.         sub    bx,ARGy1    ; BX := y2 - y1
  71.         jz    HorizLine13    ; jump if horizontal line
  72.  
  73.         jns    L03        ; jump if slope is positive
  74.  
  75.         neg    bx        ; BX := y1 - y2
  76.         neg    si        ; negate y-increment
  77.  
  78. ; select appropriate routine for slope of line
  79.  
  80. L03:        push    si        ; preserve y-increment
  81.  
  82.         mov    VARroutine,offset LoSlopeLine13
  83.         cmp    bx,cx
  84.         jle    L04        ; jump if dy <= dx (slope <= 1)
  85.         mov    VARroutine,offset HiSlopeLine13
  86.         xchg    bx,cx        ; exchange dy and dx
  87.  
  88. ; calculate initial decision variable and increments
  89.  
  90. L04:        shl    bx,1        ; BX := 2 * dy
  91.         mov    VARincr1,bx    ; incr1 := 2 * dy
  92.         sub    bx,cx
  93.         mov    si,bx        ; SI := d = 2 * dy - dx
  94.         sub    bx,cx
  95.         mov    VARincr2,bx    ; incr2 := 2 * (dy - dx)
  96.  
  97. ; calculate first pixel address
  98.  
  99.         push    cx        ; preserve this register
  100.         mov    ax,ARGy1    ; AX := y
  101.         mov    bx,ARGx1    ; BX := x
  102.                 call    PixelAddr13     ; ES:BX -> buffer
  103.  
  104.         mov    di,bx        ; ES:DI -> buffer
  105.  
  106.         pop    cx        ; restore this register
  107.         inc    cx        ; CX := # of pixels to draw
  108.  
  109.         pop    bx        ; BX := y-increment
  110.         jmp    VARroutine    ; jump to appropriate routine for slope
  111.  
  112.  
  113. ; routine for vertical lines
  114.  
  115. VertLine13:    mov    ax,ARGy1    ; AX := y1
  116.         mov    bx,ARGy2    ; BX := y2
  117.         mov    cx,bx
  118.         sub    cx,ax        ; CX := dy
  119.         jge    L31        ; jump if dy >= 0
  120.  
  121.         neg    cx        ; force dy >= 0
  122.         mov    ax,bx        ; AX := y2
  123.  
  124. L31:        inc    cx        ; CX := # of pixels to draw
  125.         mov    bx,ARGx1    ; BX := x
  126.         push    cx        ; preserve this register
  127.                 call    PixelAddr13     ; ES:BX -> video buffer
  128.                 pop     cx
  129.  
  130.         mov    di,bx        ; ES:DI -> video buffer
  131.         dec    si        ; SI := bytes/line - 1
  132.  
  133.         mov    al,ARGn        ; AL := pixel value
  134.  
  135. L32:        stosb            ; set pixel value in buffer
  136.         add    di,si        ; increment to next line
  137.         loop    L32
  138.  
  139.         jmp    Lexit
  140.  
  141.  
  142.  
  143. ; routine for horizontal lines (slope = 0)
  144.  
  145. HorizLine13:
  146.         push    cx        ; preserve CX
  147.         mov    ax,ARGy1
  148.         mov    bx,ARGx1
  149.                 call    PixelAddr13     ; ES:BX -> video buffer
  150.         mov    di,bx        ; ES:DI -> buffer
  151.  
  152.         pop    cx
  153.         inc    cx        ; CX := number of pixels to draw
  154.  
  155.         mov    al,ARGn        ; AL := pixel value
  156.  
  157.         rep    stosb        ; update the video buffer
  158.  
  159.         jmp    short Lexit
  160.  
  161.  
  162. ; routine for dy <= dx (slope <= 1)    ; ES:DI -> video buffer
  163.                     ; BX = y-increment
  164.                     ; CX = #pixels to draw
  165.                     ; SI = decision variable
  166. LoSlopeLine13:
  167.  
  168.         mov    al,ARGn        ; AL := pixel value
  169.  
  170. L11:        stosb            ; store pixel, increment x
  171.  
  172.         or    si,si        ; test sign of d
  173.         jns    L12        ; jump if d >= 0
  174.  
  175.         add    si,VARincr1    ; d := d + incr1
  176.         loop    L11
  177.         jmp    short Lexit
  178.  
  179. L12:        add    si,VARincr2    ; d := d + incr2
  180.         add    di,bx        ; increment y
  181.         loop    L11
  182.         jmp    short Lexit
  183.  
  184.  
  185. ; routine for dy > dx (slope > 1)    ; ES:DI -> video buffer
  186.                     ; BX = y-increment
  187.                     ; CX = #pixels to draw
  188.                     ; SI = decision variable
  189. HiSlopeLine13:
  190.         mov    al,ARGn        ; AL := pixel value
  191.  
  192. L21:        stosb            ; update next pixel, increment x
  193.  
  194.         add    di,bx        ; increment y
  195.  
  196. L22:        or    si,si        ; test sign of d
  197.         jns    L23        ; jump if d >= 0
  198.  
  199.         add    si,VARincr1    ; d := d + incr1
  200.         dec    di        ; decrement x (already incremented
  201.                     ;  by stosb)
  202.         loop    L21
  203.         jmp    short Lexit
  204.  
  205.  
  206. L23:        add    si,VARincr2    ; d := d + incr2
  207.         loop    L21
  208.  
  209.  
  210. Lexit:        pop    di        ; restore registers and return
  211.         pop    si
  212.         mov    sp,bp
  213.         pop    bp
  214.         ret
  215.  
  216. _Line13        ENDP
  217.  
  218. _TEXT        ENDS
  219.  
  220.         END
  221.