home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 255_01 / gpcir.asm < prev    next >
Encoding:
Assembly Source File  |  1988-03-30  |  17.0 KB  |  473 lines

  1.           page   80,132
  2.           page
  3. ;
  4. ;       EGA Graphic Primitive for Turbo Pascal 3.01A, Version 01FEB86.
  5. ;       (C) 1986 by Kent Cedola, 2015 Meadow Lake Ct., Norfolk, VA, 23518
  6. ;
  7. ;       The algorithm for drawing a circle (below) was from an article in
  8. ;       Dr. Dobb's Journal, December 1983, pp. 19 by Michael T. Enright.
  9. ;
  10. ;       I converting the BASIC sample to Turbo Pascal and then to assembler
  11. ;       for top speed.  This routine will plot a solid color or pattern and
  12. ;       automatically clip for the current viewport.
  13. ;
  14. ;       procedure GPCIR(Radius: Integer);
  15. ;
  16.  
  17. radius    equ    4
  18.  
  19. xcoor1    equ    -2                    ; Location of X graphic bit in AL:SI
  20. xcoor2    equ    -6                    ;   ... format (AH not used).
  21. ycoor1    equ    -10                   ; Location of Y graphic row, contains
  22. ycoor2    equ    -12                   ;   ... row byte offset.
  23.  
  24. xd        equ    -14                   ; Long integer (32 bits)
  25. yd        equ    -18                   ; Long integer (32 bits)
  26. zx        equ    -22                   ; Long integer (32 bits)
  27. zy        equ    -26                   ; Long integer (32 bits)
  28. tx        equ    -30                   ; Long integer (32 bits)
  29. ty        equ    -34                   ; Long integer (32 bits)
  30. tb        equ    -38                   ; Long integer (32 bits)
  31. er        equ    -42                   ; Long integer (32 bits)
  32. atx       equ    -46                   ; Long integer (32 bits)
  33. aty       equ    -50                   ; Long integer (32 bits)
  34. atb       equ    -54                   ; Long integer (32 bits)
  35.  
  36. xf1       equ    -58
  37. xf2       equ    -60
  38. yf1       equ    -62
  39. yf2       equ    -64
  40.  
  41. needed    equ    66                    ; Amount of temporary space needed
  42.  
  43. dgroup    group  _data
  44.  
  45. _data     segment word public 'data'
  46.           assume ds:dgroup
  47.  
  48.           extrn  _gdtype:byte
  49.           extrn  _gdmaxcol:word,_gdmaxrow:word
  50.           extrn  _gdcolor:byte,_gdmerge:byte,_gdaspc1:word,_gdaspc2:word
  51.           extrn  _gdcur_x:word,_gdcur_y:word
  52.           extrn  _gdwd_x1:word,_gdwd_x2:word,_gdwd_x3:word
  53.           extrn  _gdwd_y1:word,_gdwd_y2:word,_gdwd_y3:word
  54.           extrn  _gdvw_x1:word,_gdvw_x2:word,_gdvw_x3:word
  55.           extrn  _gdvw_y1:word,_gdvw_y2:word,_gdvw_y3:word
  56.           extrn  _gdc_flg:byte,_gds_flg:byte,_gdw_flg:byte
  57.  
  58. _data     ends
  59.  
  60. _text     segment byte public 'code'
  61.  
  62.           assume cs:_text,ds:dgroup
  63.           public _gpcir
  64. _gpcir    proc   near
  65.  
  66.           push   bp
  67.           mov    bp,sp
  68.           sub    sp,needed             ; Reserve space for temp. variables
  69.  
  70.           push   si
  71.           push   di
  72.  
  73.           mov    _GDC_FLG,2            ; Set clipping flag
  74.  
  75. ;    Compute AE = R (save in BX for later)
  76.  
  77.           mov    ax,[bp+radius]        ; Load user specified radius
  78.           or     ax,ax                 ; If radius is zero, make it 1
  79.           jnz    notzero
  80.           inc    ax
  81. notzero:
  82.           mov    bx,ax                 ; Copy to BX (AX used later)
  83.           mov    ax,[_GDCUR_X]
  84.           sub    ax,bx
  85.           cmp    ax,_gdvw_x2
  86.           jbe    next1
  87.           jmp    theend
  88. next1:
  89.           add    ax,bx
  90.           add    ax,bx
  91.           cmp    ax,_gdvw_x1
  92.           jae    next2
  93.           jmp    theend
  94. next2:
  95.  
  96. ;    Compute BE = (R * _GDASPC1 / _GDASPC2) (save in DX for later)
  97.  
  98.           mov    ax,bx                 ; Start with R (AE above)
  99.           mul    _GDASPC1              ; Compute the real Y radius from the
  100.           div    _GDASPC2              ;   the defined screen aspects
  101.           mov    dx,ax                 ; Copy to DX (temp save area)
  102.  
  103. ;    Compute the Y coordinate graphic row offset.
  104.  
  105.           mov    cx,_GDCUR_Y           ; Compute the upper and lower row for
  106.           sub    cx,ax                 ;   line clipping logic
  107.           cmp    cx,_gdvw_y2           ;
  108.           jbe    next3
  109.           jmp    theend
  110. next3:
  111.           mov    [bp+yf1],cx           ;   ...
  112.           add    cx,ax                 ;   ...
  113.           add    cx,ax                 ;   ...
  114.           cmp    cx,_gdvw_y1
  115.           jae    next4
  116.           jmp    theend
  117. next4:
  118.           mov    [bp+yf2],cx           ;   ...
  119.  
  120.           mov    _GDC_FLG,0            ; Clear clipping flag
  121.  
  122.           shl    ax,1                  ; Compute the graphic segment offset
  123.           shl    ax,1                  ;   for the Y radius length
  124.           add    ax,dx                 ;   ...
  125.           mov    si,ax                 ; Copy to SI (temp save area)
  126.  
  127.           mov    ax,_GDCUR_Y           ; Compute the graphic segment offset
  128.           shl    ax,1                  ;   for the current row
  129.           shl    ax,1                  ;   ... = A000 + (80 * Y) / 16;
  130.           add    ax,_GDCUR_Y           ;   ...
  131.           add    ax,0A000h             ;   ...
  132.           sub    ax,si                 ; Init the top and bottow y coordinates
  133.           mov    [bp+ycoor1],ax        ;   ...
  134.           add    ax,si                 ;   ...
  135.           add    ax,si                 ;   ...
  136.           mov    [bp+ycoor2],ax        ;   ...
  137.  
  138. ;    Compute the X coordinate graphic bit offset.
  139.  
  140.           mov    si,_GDCUR_X           ; Compute the column byte offset
  141.           mov    [bp+xf1],si           ; Save the left and right column numbers
  142.           mov    [bp+xf2],si           ;   for clipping logic
  143.           mov    cx,si                 ;   ... (Save for later)
  144.           shr    si,1                  ;   DI = X / 8;
  145.           shr    si,1                  ;   ...
  146.           shr    si,1                  ;   ...
  147.           mov    al,80h                ; Compute mask byte to change one bit
  148.           and    cl,7                  ;   ...  (It has to be done this way to
  149.           ror    al,cl                 ;   ...   use merge value in write)
  150.           mov    [bp+xcoor1],al        ; Init the left and right x coordinates
  151.           mov    [bp+xcoor1-2],si      ;   ...  byte 0   = bit mask value
  152.           mov    [bp+xcoor2],al        ;   ...  byte 1   = not used
  153.           mov    [bp+xcoor2-2],si      ;   ...  byte 2-3 = byte column offset
  154.  
  155. ;    Compute XD = BE * BE
  156.  
  157.           mov    cx,dx                 ; Save BE for later (in CX)
  158.           mov    ax,dx                 ; Must use AX for multiply
  159.           mul    dx                    ; BE * BE (AX * DX)
  160.           mov    [bp+xd],ax            ; Save XD
  161.           mov    [bp+xd-2],dx          ;   ...
  162.  
  163. ;    Compute DX = 2 * BE * BE (or XD * 2)
  164.  
  165.           shl    ax,1                  ; Long shift left for multiply
  166.           rcl    dx,1                  ;   ...
  167.           mov    [bp+zx],ax            ; Save DX
  168.           mov    [bp+zx-2],dx          ;   ...
  169.  
  170. ;    Compute DY = 2 * AE * AE
  171.  
  172.           mov    ax,bx                 ; Move current AE to AX
  173.           mul    bx                    ;   ... (AE * AE)
  174.           push   dx                    ; Save the value (AE * AE) for later
  175.           push   ax                    ;   ...
  176.           shl    ax,1                  ; Compute AE * AE * 2 (shift left)
  177.           rcl    dx,1                  ;   ...
  178.           mov    [bp+zy],ax            ; Save DY
  179.           mov    [bp+zy-2],dx          ;   ...
  180.  
  181. ;    Compute YD = (2 * BE - 1) * AE * AE
  182.  
  183.           pop    ax
  184.           shl    cx,1                  ; Compute BE * 2
  185.           dec    cx                    ; Compute BE * 2 - 1
  186.           mul    cx                    ; Compute (BE * 2 - 1) * AE
  187.           mov    [bp+yd],ax            ; Save what we have so far
  188.           mov    [bp+yd-2],dx          ;   ...
  189.           pop    ax                    ; Compute (BE * 2 - 1) * AE * AE
  190.           mul    cx                    ;   ...
  191.           add    [bp+yd-2],ax          ;   ...
  192.  
  193. ;    Compute ER = 0
  194.  
  195.           xor    ax,ax                 ; Clear AX to clear ER
  196.           mov    [bp+er],ax            ;   ...
  197.           mov    [bp+er-2],ax          ;   ...
  198.  
  199. ;    Setup the EGA to perform graphics
  200.  
  201.           mov    dx,03CEh              ; Load EGA graphic controller port addr.
  202.           mov    ah,_GDMERGE           ; Load current merge setting
  203.           mov    al,3                  ; Merge register is number three
  204.           out    dx,ax                 ; Set the EGA's merge register
  205.           mov    ax,0205h              ; Load write mode number two
  206.           out    dx,ax                 ; Set the EGA's mode register
  207.           mov    al,8                  ; Load the mask register number
  208.           out    dx,al                 ; Just postion EGA's controller to it
  209.  
  210.           call   plotpnts              ; Plot the first set of points
  211.  
  212. next_x:
  213.           mov    cx,-1
  214.  
  215.           mov    ax,[bp+er]            ; Compute TX = ER + XD
  216.           mov    dx,[bp+er-2]          ;   ...
  217.           add    ax,[bp+xd]            ;   ...
  218.           adc    dx,[bp+xd-2]          ;   ...
  219.           mov    [bp+tx],ax            ;   ...
  220.           mov    [bp+tx-2],dx          ;   ...
  221.           jns    abs_tx                ; Compute ATX = abs(TX), if needed
  222.           xor    ax,cx
  223.           xor    dx,cx
  224.           inc    ax
  225.           jnc    abs_tx
  226.           inc    dx
  227. abs_tx:
  228.           mov    [bp+atx],ax           ;   ...
  229.           mov    [bp+atx-2],dx         ;   ...
  230.  
  231.           mov    ax,[bp+er]            ; Compute TY = ER - YD
  232.           mov    dx,[bp+er-2]          ;   ...
  233.           sub    ax,[bp+yd]            ;   ...
  234.           sbb    dx,[bp+yd-2]          ;   ...
  235.           mov    [bp+ty],ax            ;   ...
  236.           mov    [bp+ty-2],dx          ;   ...
  237.           jns    abs_ty                ; Compute ATY = abs(TY), if needed
  238.           xor    ax,cx                 ;   ...
  239.           xor    dx,cx                 ;   ...
  240.           inc    ax                    ;   ...
  241.           jnc    abs_ty                ;   ...
  242.           inc    dx                    ;   ...
  243. abs_ty:
  244.           mov    [bp+aty],ax           ;   ...
  245.           mov    [bp+aty-2],dx         ;   ...
  246.  
  247.           mov    ax,[bp+tx]            ; Compute TB = ER + XD - YD
  248.           mov    dx,[bp+tx-2]          ;   ... (or TB = TX - YD)
  249.           sub    ax,[bp+yd]            ;   ...
  250.           sbb    dx,[bp+yd-2]          ;   ...
  251.           mov    [bp+tb],ax            ;   ...
  252.           mov    [bp+tb-2],dx          ;   ...
  253.           jns    abs_tb                ; Compute ATB = abs(TB), if needed
  254.           xor    ax,cx                 ;   ...
  255.           xor    dx,cx                 ;   ...
  256.           inc    ax                    ;   ...
  257.           jnc    abs_tb                ;   ...
  258.           inc    dx                    ;   ...
  259. abs_tb:
  260.           mov    [bp+atb],ax           ;   ...
  261.           mov    [bp+atb-2],dx         ;   ...
  262.  
  263. cond1:
  264.           mov    ax,[bp+atx]           ; Load absolute value of TX
  265.           mov    dx,[bp+atx-2]         ;   ...
  266.           cmp    dx,[bp+aty-2]         ; if (abs(TX) < abs(TY)
  267.           ja     cond2                 ;   ...
  268.           jb     cond1a                ;   ...
  269.           cmp    ax,[bp+aty]           ;   ...
  270.           jae    cond2                 ;   ...
  271. cond1a:
  272.           cmp    dx,[bp+atb-2]         ; and (abs(TX) < abs(TB))
  273.           ja     cond2                 ;   ...
  274.           jb     cond1b                ;   ...
  275.           cmp    ax,[bp+atb]           ;   ...
  276.           jae    cond2                 ;   ...
  277. cond1b:
  278.  
  279. ;    Compute XF1 = XF1 - 1
  280.  
  281.           rol    byte ptr [bp+xcoor1],1
  282.           sbb    word ptr [bp+xcoor1-2],0
  283.           dec    word ptr [bp+xf1]
  284.  
  285. ;    Compute XF2 = XF2 + 1
  286.  
  287.           ror    byte ptr [bp+xcoor2],1
  288.           adc    word ptr [bp+xcoor2-2],0
  289.           inc    word ptr [bp+xf2]
  290.  
  291.           mov    ax,[bp+tx]            ; ER = TX
  292.           mov    dx,[bp+tx-2]          ;   ...
  293.           mov    [bp+er],ax            ;   ...
  294.           mov    [bp+er-2],dx          ;   ...
  295.           mov    ax,[bp+zx]            ; XD = XD + DX
  296.           mov    dx,[bp+zx-2]          ;   ...
  297.           add    [bp+xd],ax            ;   ...
  298.           adc    [bp+xd-2],dx          ;   ...
  299.  
  300.           jmp    until
  301.  
  302. cond2:
  303.           mov    ax,[bp+aty]           ; Load absolute value of TY
  304.           mov    dx,[bp+aty-2]         ;   ...
  305.           cmp    dx,[bp+atx-2]         ; if (abs(TY) < abs(TX)
  306.           ja     cond3                 ;   ...
  307.           jb     cond2a                ;   ...
  308.           cmp    ax,[bp+atx]           ;   ...
  309.           jae    cond3                 ;   ...
  310. cond2a:
  311.           cmp    dx,[bp+atb-2]         ; and (abs(TY) < abs(TB))
  312.           ja     cond3                 ;   ...
  313.           jb     cond2b                ;   ...
  314.           cmp    ax,[bp+atb]           ;   ...
  315.           jae    cond3                 ;   ...
  316. cond2b:
  317.  
  318. ;    Compute YF1 = YF1 - 1
  319.  
  320.           add    word ptr [bp+ycoor1],5
  321.           inc    word ptr [bp+yf1]
  322.  
  323. ;    Compute YF2 = YF2 + 1
  324.  
  325.           sub    word ptr [bp+ycoor2],5
  326.           dec    word ptr [bp+yf2]
  327.  
  328.           mov    ax,[bp+ty]            ; ER = TY
  329.           mov    dx,[bp+ty-2]          ;   ...
  330.           mov    [bp+er],ax            ;   ...
  331.           mov    [bp+er-2],dx          ;   ...
  332.  
  333.           mov    ax,[bp+zy]            ; YD = YD - DY
  334.           mov    dx,[bp+zy-2]          ;   ...
  335.           sub    [bp+yd],ax            ;   ...
  336.           sbb    [bp+yd-2],dx          ;   ...
  337.  
  338.           jmp    until
  339.  
  340. cond3:
  341.  
  342. ;    Compute XF1 = XF1 - 1
  343.  
  344.           rol    byte ptr [bp+xcoor1],1
  345.           sbb    word ptr [bp+xcoor1-2],0
  346.           dec    word ptr [bp+xf1]
  347.  
  348. ;    Compute XF2 = XF2 + 1
  349.  
  350.           ror    byte ptr [bp+xcoor2],1
  351.           adc    word ptr [bp+xcoor2-2],0
  352.           inc    word ptr [bp+xf2]
  353.  
  354. ;    Compute YF1 = YF1 + 1
  355.  
  356.           add    word ptr [bp+ycoor1],5
  357.           inc    word ptr [bp+yf1]
  358.  
  359. ;    Compute YF2 = YF2 - 1
  360.  
  361.           sub    word ptr [bp+ycoor2],5
  362.           dec    word ptr [bp+yf2]
  363.  
  364.           mov    ax,[bp+tb]            ; ER = TB
  365.           mov    dx,[bp+tb-2]          ;   ...
  366.           mov    [bp+er],ax            ;   ...
  367.           mov    [bp+er-2],dx          ;   ...
  368.  
  369.           mov    ax,[bp+zx]            ; XD = XD + DX
  370.           mov    dx,[bp+zx-2]          ;   ...
  371.           add    [bp+xd],ax            ;   ...
  372.           adc    [bp+xd-2],dx          ;   ...
  373.  
  374.           mov    ax,[bp+zy]            ; YD = YD - DY
  375.           mov    dx,[bp+zy-2]          ;   ...
  376.           sub    [bp+yd],ax            ;   ...
  377.           sbb    [bp+yd-2],dx          ;   ...
  378.  
  379. until:
  380.           call   plotpnts              ; Plot the next set of points
  381.  
  382.           mov    ax,[bp+ycoor1]        ; When the two y coordinates are equal
  383.           cmp    ax,[bp+ycoor2]        ;   ... we are done.
  384.           je     done                  ;   ... (all done condition)
  385.           jmp    next_x                ;   ... (do the next row condition)
  386. done:
  387.           mov    al,0FFh               ; Reset EGA back to standard mode
  388.           out    dx,al                 ;   ...
  389.           dec    dx                    ;   ...
  390.           mov    ax,00005h             ;   ...
  391.           out    dx,ax                 ;   ...
  392.           mov    ax,00003h             ;   ...
  393.           out    dx,ax                 ;   ...
  394.  
  395.           jmp    theend                ; Restore the callers parameter frame
  396.  
  397. plotpnts:
  398.           mov    ah,_GDCOLOR
  399.           mov    dx,03CFh
  400.  
  401.           mov    bx,[bp+xf1]
  402.           cmp    bx,_GDVW_X1           ; X1
  403.           jae    next5
  404.           mov    _GDC_FLG,1
  405.           jmp    short plot2
  406. next5:
  407.           mov    al,[bp+xcoor1]
  408.           out    dx,al
  409.           mov    si,[bp+xcoor1-2]
  410.           mov    bx,[bp+yf1]
  411.           cmp    bx,_GDVW_Y1           ; Y1
  412.           jae    next6
  413.           mov    _GDC_FLG,1
  414.           jmp    short plot1
  415. next6:
  416.           mov    es,[bp+ycoor1]
  417.           mov    al,es:[si]
  418.           mov    es:[si],ah
  419. plot1:
  420.           mov    bx,[bp+yf2]
  421.           cmp    bx,_GDVW_Y2           ; Y2
  422.           jbe    next7
  423.           mov    _GDC_FLG,1
  424.           jmp    short plot2
  425. next7:
  426.           mov    es,[bp+ycoor2]
  427.           mov    al,es:[si]
  428.           mov    es:[si],ah
  429. plot2:
  430.           mov    bx,[bp+xf2]
  431.           cmp    bx,_GDVW_X2           ; X2
  432.           jbe    next8
  433.           mov    _GDC_FLG,1
  434.           jmp    short plot4
  435. next8:
  436.           mov    al,[bp+xcoor2]
  437.           out    dx,al
  438.           mov    si,[bp+xcoor2-2]
  439.           mov    bx,[bp+yf1]
  440.           cmp    bx,_GDVW_Y1           ; Y1
  441.           jae    next9
  442.           mov    _GDC_FLG,1
  443.           jmp    short plot3
  444. next9:
  445.           mov    es,[bp+ycoor1]
  446.           mov    al,es:[si]
  447.           mov    es:[si],ah
  448. plot3:
  449.           mov    bx,[bp+yf2]
  450.           cmp    bx,_GDVW_Y2           ; Y2
  451.           jbe    next0
  452.           mov    _GDC_FLG,1
  453.           jmp    short plot4
  454. next0:
  455.           mov    es,[bp+ycoor2]
  456.           mov    al,es:[si]
  457.           mov    es:[si],ah
  458. plot4:
  459.           ret
  460.  
  461. theend:
  462.           pop    di
  463.           pop    si
  464.  
  465.           mov    sp,bp                 ; Restore the stack
  466.           pop    bp
  467.           ret
  468.  
  469. _gpcir    endp
  470.  
  471. _text     ends
  472.           end
  473.