home *** CD-ROM | disk | FTP | other *** search
/ gondwana.ecr.mu.oz.au/pub/ / Graphics.tar / Graphics / VOGLE.ZIP / VOGLE / DRIVERS / IBMPC / CGALINE.ASM < prev    next >
Assembly Source File  |  2000-02-11  |  5KB  |  353 lines

  1.     TITLE    CGALINE - Fast line drawing routine.
  2.     NAME    CGALINE
  3.     PAGE    55,132
  4.  
  5.     COMMENT    $
  6.  
  7.     Name:        CGALINE
  8.  
  9.     Function:    Draw a line in 640x200 2-color mode
  10.  
  11.     Caller:        Microsoft C:
  12.  
  13.             void     cgaline(x1, y1, x2, y2, n);
  14.  
  15.             int    x1, y1, x2, y2;        /* pixel co-ords */
  16.             int    n;            /* pixel value */
  17.  
  18.  
  19.         $
  20.  
  21.  
  22. ; Stack frame addressing - LARGE CODE MODEL
  23.  
  24. ARGx1        EQU    word ptr [bp+6]
  25. ARGy1        EQU    word ptr [bp+8]
  26. ARGx2        EQU    word ptr [bp+10]
  27. ARGy2        EQU    word ptr [bp+12]
  28. ARGn        EQU    byte ptr [bp+14]
  29.  
  30. VARleafincr    EQU    word ptr [bp-6]
  31. VARincr1    EQU    word ptr [bp-8]
  32. VARincr2    EQU    word ptr [bp-10]
  33. VARroutine    EQU    word ptr [bp-12]
  34.  
  35. ByteOffsetShift    EQU    3    ; Used to convert pixels to byte offset
  36.  
  37. DGROUP        GROUP    CGAA_DATA
  38.  
  39.         EXTRN    cgapaddr:far
  40.  
  41. CGAA_TEXT    SEGMENT    byte public 'CODE'
  42.         ASSUME    cs:CGAA_TEXT,ds:DGROUP
  43.  
  44.         PUBLIC    _cgaline
  45.  
  46. _cgaline    PROC    far
  47.  
  48.         push    bp    ; Set up stack frame
  49.         mov    bp,sp
  50.         sub    sp,12    ; Stack space for local variables
  51.         push    si
  52.         push    di
  53.  
  54.         mov    si,2000h    ; Increment for video buffer interleave
  55.         mov    di,80-2000h    ; Increment for last to first interleave
  56. ; check for vertical line
  57.  
  58.         mov    cx,ARGx2
  59.         sub    cx,ARGx1
  60.         jz    VertLine
  61.  
  62. ; force x1 < x2
  63.  
  64.         jns    L01    ; jump if x2 > x1
  65.  
  66.         neg    cx    ; CX = x1 - x2
  67.  
  68.         mov    bx,ARGx2; exchange x1 and x2
  69.         xchg    bx,ARGx1
  70.         mov    ARGx2,bx
  71.  
  72.         mov    bx,ARGy2; exchange y1 and y2
  73.         xchg    bx,ARGy1
  74.         mov    ARGy2,bx
  75.  
  76. ; calc dy = abs(y2 - y1)
  77.  
  78. L01:
  79.         mov    bx,ARGy2
  80.         sub    bx,ARGy1; BX = y2 - y1
  81.         jnz    L02
  82.         jmp    HorizLine
  83. L02:
  84.         jns    L03
  85.  
  86.         neg    bx    ; BX = y1 - y2
  87.         neg    si    ; negate increment for buffer interleave
  88.         neg    di
  89.         xchg    si,di
  90.  
  91. ; select appropriate routine for slope of line
  92.  
  93. L03:
  94.         mov    VARleafincr,di; save increment for buffer interleave
  95.         mov    VARroutine,offset LoSlopeLine
  96.         cmp    bx,cx
  97.         jle    L04    ; jump if dy <= dx (slopr <= 1)
  98.         mov    VARroutine,offset HiSlopeLine
  99.         xchg    bx,cx    ; exchange dy and dx
  100.  
  101. ; calc initial decision variable and increments
  102.  
  103. L04:
  104.         shl    bx,1        ; BX = 2 * dy
  105.         mov    VARincr1,bx    ; incr1 = 2 * dy
  106.         sub    bx,cx
  107.         mov    di,bx        ; DI = d = 2*dy - dx
  108.         sub    bx,cx
  109.         mov    VARincr2,bx    ; incr2 = 2*(dy - dx)
  110.  
  111. ; calc first pixel address
  112.  
  113.         push    cx            ; preserve the register
  114.         mov    ax,ARGy1    ; ax = y
  115.         mov    bx,ARGx1    ; bx = x
  116.         call    cgapaddr    ; ah = bit mask
  117.                     ; es:bx -> buffer
  118.                     ; CL = # bits to shift left
  119.         mov    al,ARGn        ; AL = unshifted pixel value
  120.         shl    ax,cl        ; AH = bitmask in proper position
  121.                     ; AL = pixel value in proper position
  122.         mov    dx,ax        ; DH = bitmask
  123.                     ; DL = pixel value
  124.  
  125.         not    dh        ; DH = inverse bitmask
  126.         pop    cx
  127.         inc    cx
  128.         test    bx,2000h    ; set zero flag if BX in 1st interleave
  129.         jz    L05
  130.         xchg    si,VARleafincr    ; exchange increament 
  131.                     ; values if 1st pixel lies in 1st interleave
  132.         
  133. L05:        jmp    VARroutine    ; Jump to the appropiate routine for slope
  134.  
  135. ; routine for verticle lines
  136.  
  137. VertLine:
  138.         mov    ax,ARGy1
  139.         mov    bx,ARGy2
  140.         mov    cx,bx
  141.         sub    cx,ax
  142.         jge    L31
  143.         neg    cx
  144.         mov    ax,bx
  145.  
  146. L31:
  147.         inc    cx
  148.         mov    bx,ARGx1
  149.         push    cx
  150.         call    cgapaddr
  151.  
  152.         mov    al,ARGn
  153.         shl    ax,cl
  154.         not    ah
  155.         pop    cx
  156.  
  157.         test    bx,si
  158.         jz    L32
  159.  
  160.         xchg    si,di
  161.  
  162. L32:
  163.         test    al,al
  164.         jz    L34
  165. L33:
  166.         or    es:[bx],al
  167.         add    bx,si
  168.         xchg    si,di
  169.         loop    L33
  170.         jmp    short    L35
  171. L34:
  172.         and    es:[bx],ah
  173.         add    bx,si
  174.         xchg    si,di
  175.         loop    L34
  176.  
  177. L35:
  178.         jmp    Lexit
  179.  
  180. ; routine for horizontal line
  181.  
  182. HorizLine:
  183.         mov    ax,ARGy1
  184.         mov    bx,ARGx1
  185.         call    cgapaddr
  186.         mov    di,bx
  187.         mov    dh,ah
  188.         not    dh
  189.         mov    dl,0FFh
  190.  
  191.         shl    dh,cl
  192.         not    dh
  193.  
  194.         mov    cx,ARGx2
  195.         and    cl,7
  196.         xor    cl,7
  197.         shl    dl,cl
  198.  
  199. ; determine byte offset of first and last pixel in line
  200.  
  201.         mov    ax,ARGx2
  202.         mov    bx,ARGx1
  203.         mov    cl,ByteOffsetShift
  204.  
  205.         shr    ax,cl
  206.         shr    bx,cl
  207.         mov    cx,ax
  208.         sub    cx,bx
  209.  
  210. ; propagate pixel value throughout one byte
  211.  
  212.         mov    bx,offset DGROUP:PropagatedPixel
  213.         mov    al,ARGn
  214.         xlat
  215.  
  216. ; set pixels in leftmost byte of line
  217.  
  218.         or    dh,dh
  219.         js    L43
  220.         or    cx,cx
  221.         jnz    L42
  222.         and    dl,dh
  223.         jmp    short L44
  224.  
  225. L42:
  226.         mov    ah,al
  227.         and    ah,dh
  228.         not    dh
  229.         and    es:[di],dh
  230.         or    es:[di],ah
  231.         inc    di
  232.         dec    cx
  233.  
  234. ; draw remainder of the line
  235.  
  236. L43:
  237.         rep    stosb
  238.  
  239. ; set pixels in rightmost byte of line
  240.  
  241. L44:
  242.         and    al,dl
  243.         not    dl
  244.         and    es:[di],dl
  245.         or    es:[di],al
  246.         jmp    Lexit
  247.  
  248.  
  249.  
  250. ; routine for dy >= dx (slope <= 1)
  251.  
  252. LoSlopeLine:
  253.  
  254. L10:
  255.         mov    ah,es:[bx]
  256.  
  257. L11:
  258.         and    ah,dh
  259.         or    ah,dl
  260.         ror    dl,1
  261.         ror    dh,1
  262.         jnc    L14
  263.  
  264. ; bit mask not shifted out
  265.  
  266.         or    di,di
  267.         jns    L12
  268.         add    di,VARincr1
  269.         loop    L11
  270.  
  271.         mov    es:[bx],ah
  272.         jmp    short Lexit
  273.  
  274. L12:
  275.         add    di,VARincr2
  276.         mov    es:[bx],ah
  277.         add    bx,si
  278.         xchg    si,VARleafincr
  279.         loop    L10
  280.         jmp    short Lexit
  281.  
  282. ; bit mask shifted out
  283.  
  284. L14:
  285.         mov    es:[bx],ah
  286.         inc    bx
  287.  
  288.         or    di,di
  289.         jns    L15
  290.         add    di,VARincr1
  291.         loop    L10
  292.         jmp    short Lexit
  293.  
  294. L15:
  295.         add    di,VARincr2
  296.         add    bx,si
  297.         xchg    si,VARleafincr
  298.         
  299.         loop    L10
  300.         jmp    short Lexit
  301.  
  302.  
  303.  
  304. ; routine for dy > dx (slope > 1)
  305.  
  306. HiSlopeLine:
  307.  
  308. L21:
  309.         and    es:[bx],dh
  310.         or    es:[bx],dl
  311.  
  312.         add    bx,si
  313.         xchg    si,VARleafincr
  314.  
  315. L22:
  316.         or    di,di
  317.         jns    L23
  318.  
  319.         add    di,VARincr1
  320.         loop    L21
  321.  
  322.         jmp    short Lexit
  323.  
  324. L23:
  325.         add    di,VARincr2
  326.         ror    dl,1
  327.         ror    dh,1
  328.         cmc
  329.  
  330.         adc    bx,0
  331.  
  332.         loop    L21
  333.  
  334.  
  335. Lexit:
  336.         pop    di
  337.         pop    si
  338.         mov    sp,bp
  339.         pop    bp
  340.         ret
  341.  
  342. _cgaline    ENDP
  343.  
  344. CGAA_TEXT    ENDS
  345.  
  346.  
  347. CGAA_DATA            SEGMENT    word public 'DATA'
  348. PropagatedPixel    DB    00000000b    ;0
  349.         DB    11111111b    ;1
  350. CGAA_DATA            ENDS
  351.  
  352.         END
  353.