home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / video / 7 / 7_4.asm < prev    next >
Encoding:
Assembly Source File  |  1988-08-11  |  8.5 KB  |  403 lines

  1.         TITLE    'Listing 7-4'
  2.         NAME    Ellipse10
  3.         PAGE    55,132
  4.  
  5. ;
  6. ; Name:        Ellipse10
  7. ;
  8. ; Function:    Draw an ellipse in native EGA/VGA graphics modes.
  9. ;
  10. ; Caller:    Microsoft C:
  11. ;
  12. ;            void Ellipse10(xc,yc,a,b,n);
  13. ;
  14. ;            int xc,yc;        /* center of ellipse */
  15. ;
  16. ;            int a,b;        /* major and minor axes */
  17. ;
  18. ;            int n;            /* pixel value */
  19. ;
  20.  
  21. ARGxc        EQU    word ptr [bp+4]    ; stack frame addressing
  22. ARGyc        EQU    word ptr [bp+6]
  23. ARGa        EQU    word ptr [bp+8]
  24. ARGb        EQU    word ptr [bp+10]
  25. ARGn        EQU    byte ptr [bp+12]
  26.  
  27. ULAddr        EQU    word ptr [bp-2]
  28. URAddr        EQU    word ptr [bp-4]
  29. LLAddr        EQU    word ptr [bp-6]
  30. LRAddr        EQU    word ptr [bp-8]
  31. LMask        EQU    byte ptr [bp-10]
  32. RMask        EQU    byte ptr [bp-12]
  33.  
  34. VARd        EQU    word ptr [bp-16]
  35. VARdx        EQU    word ptr [bp-20]
  36. VARdy        EQU    word ptr [bp-24]
  37. Asquared    EQU    word ptr [bp-28]
  38. Bsquared    EQU    word ptr [bp-32]
  39. TwoAsquared    EQU    word ptr [bp-36]
  40. TwoBsquared    EQU    word ptr [bp-40]
  41.  
  42. RMWbits        EQU    0        ; read-modify-write bits
  43. BytesPerLine    EQU    80
  44.  
  45.  
  46. _TEXT        SEGMENT    byte public 'CODE'
  47.         ASSUME    cs:_TEXT
  48.  
  49.         EXTRN    PixelAddr10:near
  50.  
  51.         PUBLIC    _Ellipse10
  52. _Ellipse10    PROC    near
  53.  
  54.         push    bp        ; preserve caller registers
  55.         mov    bp,sp
  56.         sub    sp,40        ; establish stack frame
  57.         push    si
  58.         push    di
  59.  
  60. ; set Graphics Controller Mode register
  61.  
  62.         mov    dx,3CEh        ; DX := Graphics Controller I/O port
  63.         mov    ax,0005h    ; AL := Mode register number
  64.                     ; AH := Write Mode 0 (bits 0,1)
  65.         out    dx,ax        ;    Read Mode 0 (bit 4)
  66.  
  67. ; set Data Rotate/Function Select register
  68.  
  69.         mov    ah,RMWbits    ; AH := Read-Modify-Write bits
  70.         mov    al,3        ; AL := Data Rotate/Function Select reg
  71.         out    dx,ax
  72.  
  73. ; set Set/Reset and Enable Set/Reset registers
  74.  
  75.         mov    ah,ARGn        ; AH := pixel value
  76.         mov    al,0        ; AL := Set/Reset reg number
  77.         out    dx,ax
  78.  
  79.         mov    ax,0F01h    ; AH := value for Enable Set/Reset (all
  80.                     ;  bit planes enabled)
  81.         out    dx,ax        ; AL := Enable Set/Reset reg number
  82.  
  83. ; initial constants
  84.  
  85.         mov    ax,ARGa
  86.         mul    ax
  87.         mov    Asquared,ax
  88.         mov    Asquared+2,dx    ; a^2
  89.         shl    ax,1
  90.         rcl    dx,1
  91.         mov    TwoAsquared,ax
  92.         mov    TwoAsquared+2,dx ; 2*a^2
  93.  
  94.         mov    ax,ARGb
  95.         mul    ax
  96.         mov    Bsquared,ax
  97.         mov    Bsquared+2,dx    ; b^2
  98.         shl    ax,1
  99.         rcl    dx,1
  100.         mov    TwoBsquared,ax
  101.         mov    TwoBsquared+2,dx ; 2*b^2
  102. ;
  103. ; plot pixels from (0,b) until dy/dx = -1
  104. ;
  105.  
  106. ; initial buffer address and bit mask
  107.  
  108.         mov    ax,BytesPerLine    ; AX := video buffer line length
  109.         mul    ARGb        ; AX := relative byte offset of b
  110.         mov    si,ax
  111.         mov    di,ax
  112.  
  113.         mov    ax,ARGyc    ; AX := yc
  114.         mov    bx,ARGxc    ; BX := xc
  115.         call    PixelAddr10    ; AH := bit mask
  116.                     ; ES:BX -> buffer
  117.                     ; CL := # bits to shift left
  118.         mov    ah,1
  119.         shl    ah,cl        ; AH := bit mask for first pixel
  120.         mov    LMask,ah
  121.         mov    RMask,ah
  122.  
  123.         add    si,bx        ; SI := offset of (0,b)
  124.         mov    ULAddr,si
  125.         mov    URAddr,si
  126.         sub    bx,di        ; AX := offset of (0,-b)
  127.         mov    LLAddr,bx
  128.         mov    LRAddr,bx
  129.  
  130. ; initial decision variables
  131.  
  132.         xor    ax,ax
  133.         mov    VARdx,ax
  134.         mov    VARdx+2,ax    ; dx = 0
  135.  
  136.         mov    ax,TwoAsquared
  137.         mov    dx,TwoAsquared+2
  138.         mov    cx,ARGb
  139.         call    LongMultiply    ; perform 32-bit by 16-bit mulitply
  140.         mov    VARdy,ax
  141.         mov    VARdy+2,dx    ; dy = TwoAsquared * b
  142.  
  143.         mov    ax,Asquared
  144.         mov    dx,Asquared+2    ; DX:AX = Asquared
  145.         sar    dx,1
  146.         rcr    ax,1
  147.         sar    dx,1
  148.         rcr    ax,1        ; DX:AX = Asquared/4
  149.  
  150.         add    ax,Bsquared
  151.         adc    dx,Bsquared+2    ; DX:AX = Bsquared + Asquared/4
  152.         mov    VARd,ax
  153.         mov    VARd+2,dx
  154.  
  155.         mov    ax,Asquared
  156.         mov    dx,Asquared+2
  157.         mov    cx,ARGb
  158.         call    LongMultiply    ; DX:AX = Asquared*b
  159.         sub    VARd,ax
  160.         sbb    VARd+2,dx    ; d = Bsquared - Asquared*b + Asquared/4
  161.  
  162. ; loop until dy/dx >= -1
  163.  
  164.         mov    bx,ARGb        ; BX := initial y-coordinate
  165.  
  166.         xor    cx,cx        ; CH := 0 (initial y-increment)
  167.                     ; CL := 0 (initial x-increment)
  168. L10:        mov    ax,VARdx
  169.         mov    dx,VARdx+2
  170.         sub    ax,VARdy
  171.         sbb    dx,VARdy+2
  172.         jns    L20        ; jump if dx>=dy
  173.  
  174.         call    Set4Pixels
  175.  
  176.         mov    cx,1        ; CH := 0 (y-increment)
  177.                     ; CL := 1 (x-increment)
  178.         cmp    VARd+2,0
  179.         js    L11        ; jump if d < 0
  180.  
  181.         mov    ch,1        ; increment in y direction
  182.         dec    bx        ; decrement current y-coordinate
  183.  
  184.         mov    ax,VARdy
  185.         mov    dx,VARdy+2
  186.         sub    ax,TwoAsquared
  187.         sbb    dx,TwoAsquared+2 ; DX:AX := dy - TwoAsquared
  188.         mov    VARdy,ax
  189.         mov    VARdy+2,dx    ; dy -= TwoAsquared
  190.  
  191.         sub    VARd,ax
  192.         sbb    VARd+2,dx    ; d -= dy
  193.  
  194. L11:        mov    ax,VARdx
  195.         mov    dx,VARdx+2
  196.         add    ax,TwoBsquared
  197.         adc    dx,TwoBsquared+2 ; DX:AX := dx + TwoBsquared
  198.         mov    VARdx,ax
  199.         mov    VARdx+2,dx    ; dx += TwoBsquared
  200.  
  201.         add    ax,Bsquared
  202.         adc    dx,Bsquared+2    ; DX:AX := dx + Bsquared
  203.         add    VARd,ax
  204.         adc    VARd+2,dx    ; d += dx + Bsquared
  205.  
  206.         jmp    L10
  207. ;
  208. ; plot pixels from current (x,y) until y < 0
  209. ;
  210.  
  211. ; initial buffer address and bit mask
  212.  
  213. L20:        push    bx        ; preserve current y-coordinate
  214.         push    cx        ; preserve x- and y-increments
  215.  
  216.         mov    ax,Asquared
  217.         mov    dx,Asquared+2
  218.         sub    ax,Bsquared
  219.         sbb    dx,Bsquared+2    ; DX:AX := Asquared-Bsquared
  220.  
  221.         mov    bx,ax
  222.         mov    cx,dx        ; CX:BX := (Asquared-Bsquared)
  223.  
  224.         sar    dx,1
  225.         rcr    ax,1        ; DX:AX := (Asquared-Bsquared)/2
  226.         add    ax,bx
  227.         adc    dx,cx        ; DX:AX := 3*(Asquared-Bsquared)/2
  228.  
  229.         sub    ax,VARdx
  230.         sbb    dx,VARdx+2
  231.         sub    ax,VARdy
  232.         sbb    dx,VARdy+2    ; DX:AX := 3*(Asquared-Bsquared)/2 - (dx+dy)
  233.  
  234.         sar    dx,1
  235.         rcr    ax,1        ; DX:AX :=
  236.                     ;  ( 3*(Asquared-Bsquared)/2 - (dx+dy) )/2
  237.         add    VARd,ax
  238.         adc    VARd+2,dx    ; update d
  239.  
  240. ; loop until y < 0
  241.  
  242.         pop    cx        ; CH,CL := y- and x-increments
  243.         pop    bx        ; BX := y
  244.  
  245. L21:        call    Set4Pixels
  246.  
  247.         mov    cx,100h        ; CH := 1 (y-increment)
  248.                     ; CL := 0 (x-increment)
  249.  
  250.         cmp    VARd+2,0
  251.         jns    L22        ; jump if d >= 0
  252.  
  253.         mov    cl,1        ; increment in x direction
  254.  
  255.         mov    ax,VARdx
  256.         mov    dx,VARdx+2
  257.         add    ax,TwoBsquared
  258.         adc    dx,TwoBsquared+2 ; DX:AX := dx + TwoBsquared
  259.         mov    VARdx,ax
  260.         mov    VARdx+2,dx    ; dx += TwoBsquared
  261.  
  262.         add    VARd,ax
  263.         adc    VARd+2,dx    ; d += dx
  264.  
  265. L22:        mov    ax,VARdy
  266.         mov    dx,VARdy+2
  267.         sub    ax,TwoAsquared
  268.         sbb    dx,TwoAsquared+2 ; DX:AX := dy - TwoAsquared
  269.         mov    VARdy,ax
  270.         mov    VARdy+2,dx    ; dy -= TwoAsquared
  271.  
  272.         sub    ax,Asquared
  273.         sbb    dx,Asquared+2    ; DX:AX := dy - Asquared
  274.         sub    VARd,ax
  275.         sbb    VARd+2,dx    ; d += Asquared - dy
  276.  
  277.         dec    bx        ; decrement y
  278.         jns    L21        ; loop if y >= 0
  279.  
  280.  
  281. ; restore default Graphics Controller registers
  282.  
  283. Lexit:        mov    ax,0FF08h    ; default Bit Mask
  284.         mov    dx,3CEh
  285.         out    dx,ax
  286.  
  287.         mov    ax,0003        ; default Function Select
  288.         out    dx,ax
  289.  
  290.         mov    ax,0001        ; default Enable Set/Reset
  291.         out    dx,ax
  292.  
  293.         pop    di        ; restore registers and return
  294.         pop    si
  295.         mov    sp,bp
  296.         pop    bp
  297.         ret
  298.  
  299. _Ellipse10    ENDP
  300.  
  301.  
  302. Set4Pixels    PROC    near        ; Call with:  CH := y-increment (0, -1)
  303.                     ;          CL := x-increment (0, 1)
  304.  
  305.         push    ax        ; preserve these regs
  306.         push    bx
  307.         push    dx
  308.  
  309.         mov    dx,3CEh        ; DX := Graphics Controller port
  310.  
  311.         xor    bx,bx        ; BX := 0
  312.         test    ch,ch
  313.         jz    L30        ; jump if y-increment = 0
  314.  
  315.         mov    bx,BytesPerLine    ; BX := positive increment
  316.         neg    bx        ; BX := negative increment
  317.  
  318. L30:        mov    al,8        ; AL := Bit Mask reg number
  319.  
  320. ; pixels at (xc-x,yc+y) and (xc-x,yc-y)
  321.  
  322.         xor    si,si        ; SI := 0
  323.         mov    ah,LMask
  324.  
  325.         rol    ah,cl        ; AH := bit mask rotated horizontally
  326.         rcl    si,1        ; SI := 1 if bit mask rotated around
  327.         neg    si        ; SI := 0 or -1
  328.  
  329.         mov    di,si        ; SI,DI := left horizontal increment
  330.  
  331.         add    si,ULAddr    ; SI := upper left addr + horiz incr
  332.         add    si,bx        ; SI := new upper left addr
  333.         add    di,LLAddr
  334.         sub    di,bx        ; DI := new lower left addr
  335.  
  336.         mov    LMask,ah    ; update these variables
  337.         mov    ULAddr,si
  338.         mov    LLAddr,di
  339.  
  340.         out    dx,ax        ; update Bit Mask register
  341.  
  342.         mov    ch,es:[si]    ; update upper left pixel
  343.         mov    es:[si],ch
  344.         mov    ch,es:[di]    ; update lower left pixel
  345.         mov    es:[di],ch
  346.  
  347.  
  348. ; pixels at (xc+x,yc+y) and (xc+x,yc-y)
  349.  
  350.         xor    si,si        ; SI := 0
  351.         mov    ah,RMask
  352.  
  353.         ror    ah,cl        ; AH := bit mask rotated horizontally
  354.         rcl    si,1        ; SI := 1 if bit mask rotated around
  355.  
  356.         mov    di,si        ; SI,DI := right horizontal increment
  357.  
  358.         add    si,URAddr    ; SI := upper right addr + horiz incr
  359.         add    si,bx        ; SI := new upper right addr
  360.         add    di,LRAddr
  361.         sub    di,bx        ; DI := new lower right addr
  362.  
  363.         mov    RMask,ah    ; update these variables
  364.         mov    URAddr,si
  365.         mov    LRAddr,di
  366.  
  367.         out    dx,ax        ; update Bit Mask register
  368.  
  369.         mov    ch,es:[si]    ; update upper right pixel
  370.         mov    es:[si],ch
  371.         mov    ch,es:[di]    ; update lower right pixel
  372.         mov    es:[di],ch
  373.  
  374.         pop    dx        ; restore these regs
  375.         pop    bx
  376.         pop    ax
  377.         ret
  378.  
  379. Set4Pixels    ENDP
  380.  
  381.  
  382. LongMultiply    PROC    near        ; Caller:    DX = u1 (hi-order word
  383.                     ;         of 32-bit number)
  384.                     ;        AX = u2 (lo-order word)
  385.                     ;        CX = v1 (16-bit number)
  386.                     ; Returns:    DX:AX = 32-bit result)
  387.  
  388.         push    ax        ; preserve u2
  389.         mov    ax,dx        ; AX := 
  390.         mul    cx        ; AX := high-order word of result
  391.         xchg    ax,cx        ; AX := v1, CX := high-order word
  392.         pop    dx        ; DX := u2
  393.         mul    dx        ; AX := low-order word of result
  394.                     ; DX := carry
  395.         add    dx,cx        ; CX := high-order word of result
  396.         ret
  397.  
  398. LongMultiply    ENDP
  399.  
  400. _TEXT        ENDS
  401.  
  402.         END
  403.