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 >
Wrap
Text File
|
1990-02-06
|
8KB
|
190 lines
; from CBM Draw.asm
; modified for speed by Jean-Michel Forgeas, June 89
; from 2000 to 2430 vectors/second
; in a 704x280, 1 bit-plane BitMap
CODE text
INCLUDE "exec/types.i"
INCLUDE "graphics/rastport.i"
INCLUDE "custom.i"
XDEF _XPolyLines,_XClear ; assembler interface
;============================================================================
; NAME
;
; XPolyLines ( rp, startad, vectors ) startad: X1, Y1, X2, Y2, CL
; a0 a4 d7.w d0 d1 d2 d3 d4
;
; The blitter must be owned before calling this routine to draw lines.
;============================================================================
_XPolyLines
movem.l d0-d7/a2-a4,-(sp)
movea.l rp_BitMap(a0),a1 point to the bitmap struct
movea.l #_custom,a3 point to custom chips
lea.l bm_Planes(a1),a5 point to array of plane ptrs
movea.l (a5),a5 get bitplane address
bra EndNextVector
NextVector:
movem.w (a4),d0-d4
adda.l #10,a4
; move.w (a4)+,d0 X1 value
; move.w (a4)+,d1 Y1 value
; move.w (a4)+,d2 X2 value
; move.w (a4)+,d3 Y2 value
; move.w (a4)+,d4 color value (not used but let increment)
moveq.l #$0f,d4 compute ASH3-ASH0
and.w d0,d4 for preshifting bltadat
sub.w d0,d2 convert X2 to deltaX
sub.w d1,d3 convert Y2 to deltaY
mulu.w bm_BytesPerRow(a1),d1 offset to correct bitmap row
lsr.w #3,d0 convert X1 to a byte offset
add.w d0,d1 now d1=offset into bitplanes
; compute the correct octant code for this line ( SUD,SUL,AUL ) and get the
; absolute value of max(deltaX, deltaY) into D2 for use as the line length.
tst.w d2
bmi.s 40$ deltaX is negative
; when deltaX is positive, use the following octant generation decisions
tst.w d3 if deltaY is positive
bmi.s 20$
cmp.w d3,d2 ...then if deltaX > deltaY...
blt.s 10$
moveq.l #OCT4,d5 ...octant=4
bra.s GotOctant
10$ moveq.l #OCT0,d5 ...else octant=0...
exg d2,d3 ...and switch the delta values
bra.s GotOctant
20$ neg.w d3 else deltaY = -deltaY...
cmp.w d3,d2 ...if deltaX > deltaY...
blt.s 30$
moveq.l #OCT6,d5 ...octant=6
bra.s GotOctant
30$ moveq.l #OCT1,d5 ...else octant=1...
exg d2,d3 ...and switch the delta values
bra.s GotOctant
; but when deltaX is negative, use these octant generation decisions instead
40$ neg.w d2 deltaX = -deltaX
tst.w d3 if deltaY is positive...
bmi.s 60$
cmp.w d3,d2 ...then if deltaX > deltaY
blt.s 50$
moveq.l #OCT5,d5 ...octant=5
bra.s GotOctant
50$ moveq.l #OCT2,d5 ...else octant=2...
exg d2,d3 ...and switch the delta values
bra.s GotOctant
60$ neg.w d3 else deltaY = -deltaY
cmp.w d3,d2 if deltaX > deltaY...
blt.s 70$
moveq.l #OCT7,d5 ...octant=7
bra.s GotOctant
70$ moveq.l #OCT3,d5 ...else octant = 6...
exg d2,d3 ...and switch the delta values
; gets to here with the octant code in D5 and ABS(MAX(deltaX,deltaY)) in D2
GotOctant
addq.w #1,d2 *** is this right ? ***
5$ add.w d3,d3 D3 = 2Y
move.w d3,d0 calculate initial error term
sub.w d2,d0 D0=2Y-X
bpl.s 10$ no need to set SIGN
ori.w #SIGN,d5 initial term is negative so...
; we start one line further up
; this is a bit tricky, we need the start code in the top 4 bits of d5 and d4
; but they are currently in the low 4 bits of d4. Instead of shifting them
; all the way up to position, we just rotate them around and or them in.
10$ ror.w #4,d4 move start code to top bits
or.w d4,d5 need shift in both halves...
; to shift line pattern too
ori.w #USEA!USEC!USED,d4 move in codes for DMA channels
; OK, let's start stuffing registers that won't change between successive blits
; so we can speed up the innner loop that draws a line in each bit plane. Make
; sure that the blitter is not busy from a previous line draw routine before
; we start storing to the registers.
move.w #BBUSY,d6
20$ and.w dmaconr(a3),d6 wait for the blitter to finish
bne.s 20$ still busy
move.w #SETBIT!BLTPRI,dmacon(a3) give blit high priority
move.w d3,bltbmod(a3) bltbmod=2Y
move.w d0,d3
sub.w d2,d3 compute 2Y-2X
move.w d3,bltamod(a3) bltamod=2Y-2X
move.w bm_BytesPerRow(a1),bltcmod(a3)
move.w bm_BytesPerRow(a1),bltdmod(a3)
asl.w #6,d2 convert line length to bltsize
addq.w #2,d2 width=2 for all line drawing
move.w d5,bltcon1(a3) set up bltcon1
movea.l a5,a2 get bitplane address
adda.w d1,a2 start address of line
move.b #$ca,d4 NAC+AB we are drawing the line
moveq.l #-1,d3 first and last masks = $FFFF
move.l d3,bltafwm(a3) this stores to both
move.w d3,bltbdat(a3) set up line pattern = $FFFF
move.w #$8000,bltadat(a3) put in the line bit
move.l a2,bltcpth(a3) fill in line start address...
move.l a2,bltdpth(a3) ...of this line
move.w d0,bltaptl(a3) 2Y-X, needs reloading each use
move.w d4,bltcon0(a3) store the minterm and stuff
move.w d2,bltsize(a3) ZOOOOM! start the line draw
EndNextVector:
dbra d7,NextVector next vector now.
movem.l (sp)+,d0-d7/a2-a4 restore regs
rts all done
;============================================================================
; XClear( rp )
; a0
;
; Clears ALL bitmap memory in the given rastport. Must call OwnBlitter()
; before calling this routine (or nasty things will happen fer sure).
; This routine assumes all bitplanes are contiguous in memory!!!!!!!!!!!!
;============================================================================
_XClear
movea.l #_custom,a1 point to custom chips
movea.l rp_BitMap(a0),a0 get the bitmap ptr
moveq.l #0,d0
moveq.l #0,d1
move.w bm_Rows(a0),d0 calculate blitsize
move.b bm_Depth(a0),d1
mulu.w d1,d0 d0 = #lines to clear
lsl.l #6,d0 move to correct bits
move.w bm_BytesPerRow(a0),d1 get width in words
lsr.w #1,d1
or.w d1,d0 d0 = bltsize reg
move.w #BBUSY,d1
10$ and.w dmaconr(a1),d1 wait for blitter to finish
bne.s 10$ the last operation
move.w #SETBIT!BLTPRI,dmacon(a1) blitter nasty
clr.l bltamod(a1) bltamod & bltbmod = 0
clr.l bltcmod(a1) bltcmod & bltdmod = 0
clr.w bltcon1(a1) no shift or anything special
move.w #$01f0,bltcon0(a1) only using destination
move.l bm_Planes(a0),bltdpth(a1) where we are storing to
clr.w bltadat(a1) what we are storing (0's)
move.w d0,bltsize(a1) start the blit
rts done
END