home *** CD-ROM | disk | FTP | other *** search
/ The Fred Fish Collection 1.5 / ffcollection-1-5-1992-11.iso / ff_disks / 300-399 / ff316.lzh / Vectors / V1.1 / src / polydraw.a < prev    next >
Text File  |  1990-02-06  |  8KB  |  190 lines

  1.     ; from CBM Draw.asm
  2.     ; modified for speed by Jean-Michel Forgeas, June 89
  3.     ;       from 2000 to 2430 vectors/second
  4.     ;       in a 704x280, 1 bit-plane BitMap
  5.  
  6.         CODE    text
  7.  
  8.         INCLUDE "exec/types.i"
  9.         INCLUDE "graphics/rastport.i"
  10.         INCLUDE "custom.i"
  11.  
  12.         XDEF    _XPolyLines,_XClear     ; assembler interface
  13.  
  14.  
  15. ;============================================================================
  16. ; NAME
  17. ;
  18. ;    XPolyLines ( rp, startad, vectors )      startad: X1, Y1, X2, Y2, CL
  19. ;                 a0    a4       d7.w                  d0  d1  d2  d3  d4
  20. ;
  21. ; The blitter must be owned before calling this routine to draw lines.
  22. ;============================================================================
  23.  
  24. _XPolyLines
  25.         movem.l d0-d7/a2-a4,-(sp)
  26.         movea.l rp_BitMap(a0),a1        point to the bitmap struct
  27.         movea.l #_custom,a3             point to custom chips
  28.  
  29.         lea.l   bm_Planes(a1),a5        point to array of plane ptrs
  30.         movea.l (a5),a5                 get bitplane address
  31.  
  32.         bra     EndNextVector
  33.  
  34. NextVector:
  35.         movem.w (a4),d0-d4
  36.         adda.l  #10,a4
  37. ;        move.w  (a4)+,d0                  X1 value
  38. ;        move.w  (a4)+,d1                  Y1 value
  39. ;        move.w  (a4)+,d2                  X2 value
  40. ;        move.w  (a4)+,d3                  Y2 value
  41. ;        move.w  (a4)+,d4                  color value  (not used but let increment)
  42.  
  43.         moveq.l #$0f,d4                 compute ASH3-ASH0
  44.         and.w   d0,d4                   for preshifting bltadat
  45.         sub.w   d0,d2                   convert X2 to deltaX
  46.         sub.w   d1,d3                   convert Y2 to deltaY
  47.         mulu.w  bm_BytesPerRow(a1),d1   offset to correct bitmap row
  48.         lsr.w   #3,d0                   convert X1 to a byte offset
  49.         add.w   d0,d1                   now d1=offset into bitplanes
  50.  
  51. ; compute the correct octant code for this line ( SUD,SUL,AUL ) and get the
  52. ; absolute value of max(deltaX, deltaY) into D2 for use as the line length.
  53.         tst.w   d2
  54.         bmi.s   40$                     deltaX is negative
  55.  
  56. ; when deltaX is positive, use the following octant generation decisions
  57.         tst.w   d3                      if deltaY is positive
  58.         bmi.s   20$
  59.         cmp.w   d3,d2                   ...then if deltaX > deltaY...
  60.         blt.s   10$
  61.         moveq.l #OCT4,d5                ...octant=4
  62.         bra.s   GotOctant
  63. 10$     moveq.l #OCT0,d5                ...else octant=0...
  64.         exg d2,d3                       ...and switch the delta values
  65.         bra.s   GotOctant
  66.  
  67. 20$     neg.w   d3                      else deltaY = -deltaY...
  68.         cmp.w   d3,d2                   ...if deltaX > deltaY...
  69.         blt.s   30$
  70.         moveq.l #OCT6,d5                ...octant=6
  71.         bra.s   GotOctant
  72. 30$     moveq.l #OCT1,d5                ...else octant=1...
  73.         exg d2,d3                       ...and switch the delta values
  74.         bra.s   GotOctant
  75.  
  76. ; but when deltaX is negative, use these octant generation decisions instead
  77. 40$     neg.w   d2                      deltaX = -deltaX
  78.         tst.w   d3                      if deltaY is positive...
  79.         bmi.s   60$
  80.         cmp.w   d3,d2                   ...then if deltaX > deltaY
  81.         blt.s   50$
  82.         moveq.l #OCT5,d5                ...octant=5
  83.         bra.s   GotOctant
  84. 50$     moveq.l #OCT2,d5                ...else octant=2...
  85.         exg d2,d3                       ...and switch the delta values
  86.         bra.s   GotOctant
  87.  
  88. 60$     neg.w   d3                      else deltaY = -deltaY
  89.         cmp.w   d3,d2                   if deltaX > deltaY...
  90.         blt.s   70$
  91.         moveq.l #OCT7,d5                ...octant=7
  92.         bra.s   GotOctant
  93. 70$     moveq.l #OCT3,d5                ...else octant = 6...
  94.         exg d2,d3                       ...and switch the delta values
  95.  
  96. ; gets to here with the octant code in D5 and ABS(MAX(deltaX,deltaY)) in D2
  97. GotOctant
  98.         addq.w  #1,d2                   *** is this right ? ***
  99. 5$      add.w   d3,d3                   D3 = 2Y
  100.         move.w  d3,d0                   calculate initial error term
  101.         sub.w   d2,d0                   D0=2Y-X
  102.         bpl.s   10$                     no need to set SIGN
  103.         ori.w   #SIGN,d5                initial term is negative so...
  104. ;                                       we start one line further up
  105.  
  106. ; this is a bit tricky, we need the start code in the top 4 bits of d5 and d4
  107. ; but they are currently in the low 4 bits of d4.  Instead of shifting them
  108. ; all the way up to position, we just rotate them around and or them in.
  109. 10$     ror.w   #4,d4                   move start code to top bits
  110.         or.w    d4,d5                   need shift in both halves...
  111. ;                                       to shift line pattern too
  112.         ori.w   #USEA!USEC!USED,d4      move in codes for DMA channels
  113.  
  114. ; OK, let's start stuffing registers that won't change between successive blits
  115. ; so we can speed up the innner loop that draws a line in each bit plane. Make
  116. ; sure that the blitter is not busy from a previous line draw routine before
  117. ; we start storing to the registers.
  118.         move.w  #BBUSY,d6
  119. 20$     and.w   dmaconr(a3),d6          wait for the blitter to finish
  120.         bne.s   20$                     still busy
  121.  
  122.         move.w  #SETBIT!BLTPRI,dmacon(a3)  give blit high priority
  123.  
  124.         move.w  d3,bltbmod(a3)          bltbmod=2Y
  125.         move.w  d0,d3
  126.         sub.w   d2,d3                   compute 2Y-2X
  127.         move.w  d3,bltamod(a3)          bltamod=2Y-2X
  128.         move.w  bm_BytesPerRow(a1),bltcmod(a3)
  129.         move.w  bm_BytesPerRow(a1),bltdmod(a3)
  130.         asl.w   #6,d2                   convert line length to bltsize
  131.         addq.w  #2,d2                   width=2 for all line drawing
  132.         move.w  d5,bltcon1(a3)          set up bltcon1
  133.  
  134.         movea.l a5,a2                   get bitplane address
  135.         adda.w  d1,a2                   start address of line
  136.  
  137.         move.b  #$ca,d4                 NAC+AB we are drawing the line
  138.         moveq.l #-1,d3                  first and last masks = $FFFF
  139.         move.l  d3,bltafwm(a3)          this stores to both
  140.         move.w  d3,bltbdat(a3)          set up line pattern = $FFFF
  141.         move.w  #$8000,bltadat(a3)      put in the line bit
  142.         move.l  a2,bltcpth(a3)          fill in line start address...
  143.         move.l  a2,bltdpth(a3)          ...of this line
  144.         move.w  d0,bltaptl(a3)          2Y-X, needs reloading each use
  145.         move.w  d4,bltcon0(a3)          store the minterm and stuff
  146.         move.w  d2,bltsize(a3)          ZOOOOM! start the line draw
  147.  
  148. EndNextVector:
  149.         dbra    d7,NextVector           next vector now.
  150.  
  151.         movem.l (sp)+,d0-d7/a2-a4       restore regs
  152.         rts                             all done
  153.  
  154. ;============================================================================
  155. ; XClear( rp )
  156. ;    a0
  157. ;
  158. ; Clears ALL bitmap memory in the given rastport.  Must call OwnBlitter()
  159. ; before calling this routine (or nasty things will happen fer sure).
  160. ; This routine assumes all bitplanes are contiguous in memory!!!!!!!!!!!!
  161. ;============================================================================
  162.  
  163. _XClear
  164.         movea.l #_custom,a1             point to custom chips
  165.         movea.l rp_BitMap(a0),a0        get the bitmap ptr
  166.         moveq.l #0,d0
  167.         moveq.l #0,d1
  168.         move.w  bm_Rows(a0),d0          calculate blitsize
  169.         move.b  bm_Depth(a0),d1
  170.         mulu.w  d1,d0                   d0 = #lines to clear
  171.         lsl.l   #6,d0                   move to correct bits
  172.         move.w  bm_BytesPerRow(a0),d1   get width in words
  173.         lsr.w   #1,d1
  174.         or.w    d1,d0                   d0 = bltsize reg
  175.  
  176.         move.w  #BBUSY,d1
  177. 10$     and.w   dmaconr(a1),d1          wait for blitter to finish
  178.         bne.s   10$                     the last operation
  179.  
  180.         move.w  #SETBIT!BLTPRI,dmacon(a1)       blitter nasty
  181.         clr.l   bltamod(a1)             bltamod & bltbmod = 0
  182.         clr.l   bltcmod(a1)             bltcmod & bltdmod = 0
  183.         clr.w   bltcon1(a1)             no shift or anything special
  184.         move.w  #$01f0,bltcon0(a1)      only using destination
  185.         move.l  bm_Planes(a0),bltdpth(a1)       where we are storing to
  186.         clr.w   bltadat(a1)             what we are storing (0's)
  187.         move.w  d0,bltsize(a1)          start the blit
  188.         rts             done
  189.  
  190.         END