home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / source / dcassem.lha / No.19 < prev    next >
Text File  |  1988-05-14  |  8KB  |  216 lines

  1.          CODE
  2.         NOLIST
  3.         INCLUDE    "exec/types.i"
  4.         INCLUDE    "graphics/rastport.i"
  5.         INCLUDE    "custom.i"
  6.         INCLUDE    "globals.i"
  7.         LIST
  8.  
  9.         XREF    _LVOOwnBlitter,_LVODisownBlitter
  10.  
  11.         XDEF    Draw,Line,Clear
  12.  
  13.  
  14. ;============================================================================
  15. ; Draw( rp,x2,y2 )
  16. ;       a0 d0 d1
  17. ;
  18. ; Same as line but calls OwnBlitter before calling the line drawing routine.
  19. ;============================================================================
  20. Draw        move.l    a6,-(sp)
  21.         movea.l    GfxLib(a5),a6        need to own the blitter
  22.         movem.l    d0/d1/a0,-(sp)        save line arguments
  23.         jsr    _LVOOwnBlitter(a6)    get the blitter
  24.         movem.l    (sp)+,d0/d1/a0        restore line args
  25.         bsr.s    Line            draw the line
  26.         jsr    _LVODisownBlitter(a6)    give blitter back to system
  27.         movea.l    (sp)+,a6
  28.         rts
  29.         
  30. ;============================================================================
  31. ; NAME
  32. ;    Line ( rp,x2,y2 )
  33. ;        a0 d0 d1
  34. ;
  35. ; Draws a line from the current position to x2,y2 in the given RastPort.
  36. ; Current color, linepat, mask and flags are observed from the rastport info.
  37. ; The blitter must be owned before calling this routine to draw lines.
  38. ;============================================================================
  39. Line        movem.l    d2-d6/a2-a3,-(sp)
  40.         movea.l    rp_BitMap(a0),a1    point to the bitmap struct
  41.         movea.l    #_custom,a3        point to custom chips
  42.         move.w    d0,d2            get start and end points
  43.         move.w    d1,d3
  44.         movem.w    rp_cp_x(a0),d0/d1    start positions
  45.         movem.w    d2/d3,rp_cp_x(a0)    save new start position
  46.  
  47.         moveq.l    #$0f,d4            compute ASH3-ASH0
  48.         and.w    d0,d4            for preshifting bltadat
  49.         sub.w    d0,d2            convert X2 to deltaX
  50.         sub.w    d1,d3            convert Y2 to deltaY
  51.         mulu.w    bm_BytesPerRow(a1),d1    offset to correct bitmap row
  52.         lsr.w    #3,d0            convert X1 to a byte offset
  53.         add.w    d0,d1            now d1=offset into bitplanes
  54.  
  55. ; compute the correct octant code for this line ( SUD,SUL,AUL ) and get the
  56. ; absolute value of max(deltaX, deltaY) into D2 for use as the line length.
  57.         tst.w    d2
  58.         bmi.s    40$            deltaX is negative
  59.  
  60. ; when deltaX is positive, use the following octant generation decisions
  61.         tst.w    d3        if deltaY is positive
  62.         bmi.s    20$
  63.         cmp.w    d3,d2            ...then if deltaX > deltaY...
  64.         blt.s    10$
  65.         moveq.l    #OCT4,d5        ...octant=4
  66.         bra.s    GotOctant
  67. 10$        moveq.l    #OCT0,d5        ...else octant=0...
  68.         exg    d2,d3            ...and switch the delta values
  69.         bra.s    GotOctant
  70.  
  71. 20$        neg.w    d3        else deltaY = -deltaY...
  72.         cmp.w    d3,d2            ...if deltaX > deltaY...
  73.         blt.s    30$
  74.         moveq.l    #OCT6,d5        ...octant=6
  75.         bra.s    GotOctant
  76. 30$        moveq.l    #OCT1,d5        ...else octant=1...
  77.         exg    d2,d3            ...and switch the delta values
  78.         bra.s    GotOctant
  79.  
  80. ; but when deltaX is negative, use these octant generation decisions instead
  81. 40$        neg.w    d2        deltaX = -deltaX
  82.         tst.w    d3        if deltaY is positive...
  83.         bmi.s    60$
  84.         cmp.w    d3,d2            ...then if deltaX > deltaY
  85.         blt.s    50$
  86.         moveq.l    #OCT5,d5        ...octant=5
  87.         bra.s    GotOctant
  88. 50$        moveq.l    #OCT2,d5        ...else octant=2...
  89.         exg    d2,d3            ...and switch the delta values
  90.         bra.s    GotOctant
  91.  
  92. 60$        neg.w    d3        else deltaY = -deltaY
  93.         cmp.w    d3,d2            if deltaX > deltaY...
  94.         blt.s    70$
  95.         moveq.l    #OCT7,d5        ...octant=7
  96.         bra.s    GotOctant
  97. 70$        moveq.l    #OCT3,d5        ...else octant = 6...
  98.         exg    d2,d3            ...and switch the delta values
  99.  
  100. ; gets to here with the octant code in D5 and ABS(MAX(deltaX,deltaY)) in D2
  101. GotOctant    addq.w    #1,d2            *** is this right ? ***
  102. 5$        add.w    d3,d3            D3 = 2Y
  103.         move.w    d3,d0            calculate initial error term
  104.         sub.w    d2,d0            D0=2Y-X
  105.         bpl.s    10$            no need to set SIGN
  106.         ori.w    #SIGN,d5        initial term is negative so...
  107. ;                        we start one line further up
  108.  
  109. ; this is a bit tricky, we need the start code in the top 4 bits of d5 and d4
  110. ; but they are currently in the low 4 bits of d4.  Instead of shifting them
  111. ; all the way up to position, we just rotate them around and or them in.
  112. 10$        ror.w    #4,d4            move start code to top bits
  113.         or.w    d4,d5            need shift in both halves...
  114. ;                        to shift line pattern too
  115.         ori.w    #USEA!USEC!USED,d4    move in codes for DMA channels
  116.  
  117. ; OK, let's start stuffing registers that won't change between successive blits
  118. ; so we can speed up the innner loop that draws a line in each bit plane. Make
  119. ; sure that the blitter is not busy from a previous line draw routine before
  120. ; we start storing to the registers.
  121.         move.w    #BBUSY,d6
  122. 20$        and.w    dmaconr(a3),d6        wait for the blitter to finish
  123.         bne.s    20$            still busy
  124.  
  125.         move.w    #SETBIT!BLTPRI,dmacon(a3)  give blit high priority
  126.         move.w    d3,bltbmod(a3)        bltbmod=2Y
  127.         move.w    d0,d3
  128.         sub.w    d2,d3            compute 2Y-2X
  129.         move.w    d3,bltamod(a3)        bltamod=2Y-2X
  130.         move.w    bm_BytesPerRow(a1),bltcmod(a3)
  131.         move.w    bm_BytesPerRow(a1),bltdmod(a3)
  132.         moveq.l    #-1,d3            first and last masks = $FFFF
  133.         move.l    d3,bltafwm(a3)        this stores to both
  134.         move.w    rp_LinePtrn(a0),bltbdat(a3) set up line pattern
  135.         asl.w    #6,d2            convert line length to bltsize
  136.         addq.w    #2,d2            width=2 for all line drawing
  137.         move.w    d5,bltcon1(a3)        set up bltcon1
  138.  
  139. ; stash things that need frequent reference during the plane drawing loop
  140.         move.b    rp_FgPen(a0),d5        get pen color
  141.         and.b    rp_Mask(a0),d5        and observe mask
  142.         clr.w    d3
  143.         move.b    bm_Depth(a1),d3        get a plane counter
  144.         lea.l    bm_Planes(a1),a1    point to array of plane ptrs
  145.         bra.s    LoopEntry
  146.  
  147. ; this is the loop that draws lines in each of the required bitplanes.
  148. ; Registers are set up as follows:-
  149. ;    D0 = 2Y-X
  150. ;    D1 = Offset in bitplane to first word of the line
  151. ;    D2 = BlitSize to start the blitter with
  152. ;    D3 = plane counter
  153. ;    D4 = bltcon0
  154. ;    D5 = pencolor
  155. ;    A1 = pointer to bitplane pointers
  156. ;    A3 = pointer to custom chips
  157. ; Notice that during the loop, the blitter can be busy drawing the last line
  158. ; segment while the CPU is setting up for the next load of stores.
  159. PlaneLoop    movea.l    (a1)+,a2        get next bitplane address
  160.         adda.w    d1,a2            start address of line
  161.         move.b    #$0a,d4            assume erasing (minterm = NAC)
  162.         lsr.w    #1,d5            shift next bit into carry
  163.         bcc.s    5$            it's 0 so erase this bit
  164.         move.b    #$ca,d4            NAC+AB we are drawing the line
  165.  
  166. 5$        move.w    #BBUSY,d6
  167. 10$        and.w    dmaconr(a3),d6        wait for the blitter to finish
  168.         bne.s    10$            still busy
  169.  
  170.         move.w    #$8000,bltadat(a3)    put in the line bit
  171.         move.l    a2,bltcpth(a3)        fill in line start address...
  172.         move.l    a2,bltdpth(a3)        ...of this line
  173.         move.w    d0,bltaptl(a3)        2Y-X, needs reloading each use
  174.         move.w    d4,bltcon0(a3)        store the minterm and stuff
  175.         move.w    d2,bltsize(a3)        ZOOOOM! start the line draw
  176. LoopEntry    dbra    d3,PlaneLoop        and do the next plane
  177.  
  178.         movem.l    (sp)+,d2-d6/a2-a3    restore regs
  179.         rts                all done
  180.  
  181. ;============================================================================
  182. ; Clear( rp )
  183. ;        a0
  184. ;
  185. ; Clears ALL bitmap memory in the given rastport.  Must call OwnBlitter()
  186. ; before calling this routine (or nasty things will happen fer sure).
  187. ; This routine assumes all bitplanes are contiguous in memory!!!!!!!!!!!!
  188. ;============================================================================
  189. Clear        movea.l    #_custom,a1        point to custom chips
  190.         movea.l    rp_BitMap(a0),a0    get the bitmap ptr
  191.         moveq.l    #0,d0
  192.         moveq.l    #0,d1
  193.         move.w    bm_Rows(a0),d0        calculate blitsize
  194.         move.b    bm_Depth(a0),d1
  195.         mulu.w    d1,d0            d0 = #lines to clear
  196.         lsl.l    #6,d0            move to correct bits
  197.         move.w    bm_BytesPerRow(a0),d1    get width in words
  198.         lsr.w    #1,d1
  199.         or.w    d1,d0            d0 = bltsize reg
  200.  
  201.         move.w    #BBUSY,d1
  202. 10$        and.w    dmaconr(a1),d1        wait for blitter to finish
  203.         bne.s    10$            the last operation
  204.  
  205.         move.w    #SETBIT!BLTPRI,dmacon(a1)    blitter nasty
  206.         clr.l    bltamod(a1)        bltamod & bltbmod = 0
  207.         clr.l    bltcmod(a1)        bltcmod & bltdmod = 0
  208.         clr.w    bltcon1(a1)        no shift or anything special
  209.         move.w    #$01f0,bltcon0(a1)    only using destination
  210.         move.l    bm_Planes(a0),bltdpth(a1)    where we are storing to
  211.         clr.w    bltadat(a1)        what we are storing (0's)
  212.         move.w    d0,bltsize(a1)        start the blit
  213.         rts                done
  214.  
  215.         END
  216.