From: micro@imada.ou.dk (Klaus Pedersen)
Subject: Re: Amiga Blitter 40% slower than Atari Blitter (???)
Organization: Dept. of Math. & Computer Science, Odense University, Denmark
Date: Fri, 16 Oct 1992 04:45:28 GMT

chrisg@cbmvax.commodore.com (Chris Green) writes:

>In article <1992Oct11.192443.23288@imada.ou.dk> micro@imada.ou.dk (Klaus Pedersen) writes:
>>OK, why not try to see who can do the fastest horiz line routine? 
>>Let's try to see who can write the fastest 4 plane Hline-fill with dither.


>No claims to be the fastest, but this routine is at least adequate.
>It is passed a list of y/leftx/rightx triplets. The macro is used to
>generate code specifically for each color. It handles 16, 32, or 64
>colors.

How fast is it? 




HZ-LINE ROUTINE USING THE ST-BLiTTER.

I have written a routine that uses the BLiTTER. I am quite pleased with the
time that the BLiTTER uses to do the BLiT, But se later! 

I draw 97*100 independent HLINES and set up the dither table each 100 hlines.
Each line is 100 pixels. 

Tests on 8MHz ST.

1)
97*[dither_calc + 100 independent 100 pixel hlines]
Execute with the BLiTTER:      0.60 Sec.
Without starting the BLiTTER : 0.38 Sec (this is pure overhead)

As you can see I use more time setting up the BLiTTER than letting the BLiTTER
work!


2)
To see what preformance that could be expected of a polygon fill, I tried
to measure the time used by restarting the BLiTTER to draw a hline below the
previous with only little differnce (none here ;-)

97*[dither_calc + 100 equal 100 pixel hlines]
Execute with the BLiTTER:      0.30 Sec.
Without starting the BLiTTER : 0.08 Sec (this is pure overhead)


Details : only 1 BLiT, source isn't used, destination is only read in the
ends of the line.
Uses the halftone RAM to hold a 4 plane 4 line dithered image.
This routine uses 3 colour-sets of 4 shades, that it mixes to get 32 shades of
each primary colour. (by extending the the Mixtable you can get all possible
13*13*9 colours on the screen at the same time with more dither patterns
you can get even more colours, there isn't any reason that the remaining
3 colours can't be used). 


I am working on 2 other routines (none use the BLiTTER) the first one use
the Falcon true-colour mode (1 word/pixel).
Basically:
	move.w length,D0
	move.w colour,D1
.loop:  move.w D1,(A0)+
        dbra   D0,.loop	

That is all! (not very fast though - 2Mpixels/sec, which means that the about
test should execute in 2 secs).

The other is one that I finish for a freind of mine, it is promising!


-Klaus

PS) The source code have been trimmed, to get the original code contact
    me here. (micro@imada.ou.dk)

------------ C test program -----------------------------------------------
void Polyfill(short col, short xs, short xe, void *screen_line);


long do_hline(void)
{short i;

	time = *_hz_200;

	for (i = 0; i< 97; i++)
		Polyfill(i, i*2, 15+i*2, screen + 160*i);

	printf("TEST 1A: %5ld\n", (*_hz_200-time)/2);

	return 0L;
}



-------- Assembly ----------------------------------------------------

Polyfill:       movem.l D3-D6/A6,-(SP)

* save parameters before calling other fuction
		move.w  D1,D6
		move.w  D2,D4
		movea.l A0,A6

* Using the colour in D0 - set up colour vector
		bsr     SetDither

v_order_ok:     move.w  #99,D5


.loop:		movea.l A6,A0
		move.w  D6,D0
		move.w  D4,D1

		bsr     PF_horz_line

		adda.w  #LN_WIDTH,A6
		dbra    D5,.loop

		movem.l (SP)+,D3-D6/A6
		rts



lf_endmask:     DC.W $FFFF,$7FFF,$3FFF,$1FFF,$0FFF,$07FF,$03FF,$01FF
		DC.W $FF,$7F,$3F,$1F,$0F,$07,$03,$01

rt_endmask:     DC.W !$7FFF,!$3FFF,!$1FFF,!$0FFF,!$07FF,!$03FF,!$01FF
 		DC.W !$FF,!$7F,!$3F,!$1F,!$0F,!$07,!$03,!$01,!$00


*******************************************************************************
* Draw a Horz-Line with the blitter with the dither already in the
* Halftone ram...
* We assume that : BLiTTER->EndMask2 = 0xffff,
* IN:
*   D0: Left edge of line
*   D1: Right edge of line
*   A0: Points on the line start address
* SMASH:
*   D0-D2/A0
PF_horz_line:   move.w  #PLANES,Y_Count+BLiTTER.w ; set number of planes

* Endmasks are derived from source Xmin mod 16 and source Xmax mod 16
		moveq   #$0F,D2         ; d3<- mod 16 mask
		and.w   D1,D2           ; d3<- DST_XMAX mod 16
		add.w   D2,D2           ; d3<- offset into right end mask tbl
		move.w  rt_endmask(PC,D2.w),Endmask3+BLiTTER.w

		moveq   #$0F,D2         ; d2<- mod 16 mask
		and.w   D0,D2           ; d2<- DST_XMIN mod 16
		add.w   D2,D2           ; d2<- offset into left end mask tbl
		move.w  lf_endmask(PC,D2.w),D2 ; d2<- left endmask

* check for multiple word Destination span or single word Destination span
		lsr.w   #4,D0           ; d0<- word offset to dst Xmin
		lsr.w   #4,D1           ; d1<- word offset to dst Xmax
		sub.w   D0,D1           ; d1<- Dst span - 1
		bne.s   .HZL_set_masks  ; 2nd discriminator is one word dst

* When destination spans a single word, both end masks are merged
* into Endmask1.  The other end masks will be ignored by the BLiTTER
		and.w   Endmask3+BLiTTER.w,D2 ; d2<- single word end mask
		move.w  D2,Endmask1+BLiTTER.w ; left end mask
		clr.w   Endmask3+BLiTTER.w
                
* Calculate Destination starting address (X)
		lsl.w   #3,D0           ; d0<- 8 * (DST_XMIN/16)
		adda.w  D0,A0
		move.l  A0,Dst_Addr+BLiTTER.w ; set addr of 1. word
* please note this : we are normally decrementing the destination
* address at the end of the line, which means that we are using the
* Halftone-Ram backwards!
* force the same direction here with a negative Dst_Yinc...
		move.w  #4,Dst_Xinc+BLiTTER.w 
		move.w  #2,X_Count+BLiTTER.w
		move.w  #-2,Dst_Yinc+BLiTTER.w 
* start the blitter in HOG mode - we don't wait!
		or.b  #mLineHog|mLineBusy,Line_Num+BLiTTER.w
		rts

.HZL_set_masks: move.w  D2,Endmask1+BLiTTER.w ; left end mask
		move.w  #PLANES*2,Dst_Xinc+BLiTTER.w 

* Calculate Destination starting address (X)
		lsl.w   #3,D0
		adda.w  D0,A0
		move.l  A0,Dst_Addr+BLiTTER.w ; set addr of 1. word

		addq.w  #1,D1           ; d1<- number of words in dst line
		move.w  D1,X_Count+BLiTTER.w 

* Calculate Destination Yinc
		lsl.w   #3,D1           ; d1<- width of horz. line
		neg.w   D1
		add.w   #2+PLANES*2,D1  ; d1<- value added to dst ptr at
		move.w  D1,Dst_Yinc+BLiTTER.w ;  end of line to reach next plane

* start the blitter in HOG mode - we don't wait!
		or.b  #mLineHog|mLineBusy,Line_Num+BLiTTER.w
		rts




; Set 4-line 4-plane colour dither.
; - Writes the pattern into the Blitter halftone registers.
; - and sets up all the registers in the BLiTTER that don't change during
; the polygon fill.
; IN    : D0 - Colour (index into DitherColor table)
; SMASH : D0-D2/A0-A1
SetDither:      movem.l D3-D6,-(SP)     ; save registers.
            ...
		rts

* Colour masks, this tab specifies the plane masks for each colour.
* (size = 128)
ColorMask:      DC.W $00,$00,$00,$00
            ... 
                DC.W $FFFF,$FFFF,$FFFF,$FFFF


* each line rep. 1 dither pattern each consisting of 4 lines.
* the plane data is replicated into a long rather than word.
* (size = 144 bytes)
DitherMask:     DC.L $00,$00,$00,$00    ; 0/16
            ...    
                DC.L $BBBBBBBB,$FFFFFFFF,$EEEEEEEE,$FFFFFFFF ; 14/16
                DC.L $FFFFFFFF,$FFFFFFFF,$FFFFFFFF,$FFFFFFFF ; 16/16


* The Palette is organized as follows:
*    0   -> BLACK!
*   1-3  -> Free for the application
*   4-7  -> RED (or first base colour) from 4 (dark) to 7 (bright)
*  8-11  -> YELLOW (or second base colour) from 8 (dark) to 11 (bright)
* 12-15  -> BLUE (or thrid base colour) from 12 (dark) to 15 (bright)

* each line rep. 1 colour, with the 2 base-colours and a dither pattern,
* that specify the mixing of the colours!
* This table don't do inter-colour (it only mix red w. red and blue
* with blue, there are many more combinations...)
* FORMAT: zero-colour.w  one-colour.w  dither-index.w  void.w
DitherColor:    DC.W 0*8,4*8,0*16,0          ; RED
                
            ...
                END