Re: A83: Pixel/Line/Rectangle Routines. =)


[Prev][Next][Index][Thread]

Re: A83: Pixel/Line/Rectangle Routines. =)




Hey, these are some really nice routines (SOS lib to be perhaps?).
I took a look at "PIXEL" and saw some places I thought could be
optimized.  Take a look (my changes have >- at the start):

;-----------------------------------------------------------------------;
; Pixel Plotting Routine - By Jason Kovacs, with ZLIB's GetPix Routine.	
;
;-----------------------------------------------------------------------;
; Input:  D = X, E = Y, C = Pixel Color (0-Clear, 1-Plot, 2-XOR Pixel).	
;
; Output: Pixel is Plotted to Graph Buffer according to Command in 'C'.	
;
;-----------------------------------------------------------------------;

PIXEL:				; or/dec/dec = 3 bytes, 12 clocks
				; cp/cp/cp =   6 bytes, 21 clocks
	push bc			; Save Loop Value and Color
	push de			; Save the Coordinates
	ld a, c			; Load this to check which Color
>-	or a			; optimized "cp 0"
	call z, PIXEL_WHITE	; Execute PIXEL_WHITE if C=0
>-	dec a			; optimized "cp 1"
	call z, PIXEL_BLACK	; Execute PIXEL_BLACK if C=1
>-	dec a			; optimized "cp 2"
	call z, PIXEL_XORIT	; Execute PIXEL_XORIT if C=2
	pop de			; Retrieve the Coords for Other Routines
	pop bc			; Retrieve the Loop Value and Color
	ret		

PIXEL_WHITE:			; ld =  2 bytes, 7 clocks
				; xor = 1 byte, 4 clocks
	ld a, d			; 'a' now has X Coordinate
	call GETPIX		; Call the Pixel Routine from ZLIB
	CPL			; Compliment 'a' for the correct Bit Mask
	AND (hl)		; 'AND' to Clear the Pixel
	ld (hl), a		; Write the new byte to Graph Buffer
>-	xor a			; optimized "ld a, 0"
	ret
PIXEL_BLACK:			; ld = 
				; xor =
	ld a, d			; 'a' now has X Coordinate
	call GETPIX		; Call the Pixel Routine from ZLIB
     	OR (hl)			; 'OR' to Plot the Pixel
	ld (hl), a		; Write the new byte to Graph Buffer
>-	xor a			; optimized "ld a,1"			
	ret	
PIXEL_XORIT:
	ld a, d			; 'a' now has X Coordinate
	call GETPIX		; Call the Pixel Routine from ZLIB
	XOR (hl)		; 'XOR' to Toggle the Pixel
	ld (hl), a		; Write the new byte to Graph Buffer
	ret			; No need to reload A, done with CPs.


Everything looks good, but you would have to check and test it.  Here's 
some explanations:

1. "or a" will set the zero flag if a==0.  It's small and fast.
2. "dec a" will perform "a-=1" and will set the zero flag if "a==0"
     to begin with
3. "dec a" again; this will work to replace "cp 2" because a has
     already been decremented once!
4. "xor a" is just smaller and faster than "ld a,0".  One side effect
     is that it will affect the flags register (but that doesn't
     matter here).
5. This is necessary if the other optimizaions are used! Using
     "ld a,1" here if the other optimizations are used will cause
     PIXEL_XORIT to be called.

Oh, here's something else I thought of later:

;-----------------------------------------------------------------------;
; Pixel Plotting Routine - By Jason Kovacs, with ZLIB's GetPix Routine.	
;
;-----------------------------------------------------------------------;
; Input:  D = X, E = Y, C = Pixel Color (0-Clear, 1-Plot, 2-XOR Pixel).	
;
; Output: Pixel is Plotted to Graph Buffer according to Command in 'C'.	
;
;-----------------------------------------------------------------------;

PIXEL:				; or/dec/dec = 3 bytes, 12 clocks
				; cp/cp/cp =   6 bytes, 21 clocks
	push bc			; Save Loop Value and Color
	push de			; Save the Coordinates
	ld a, c			; Load this to check which Color
>-	or a			; optimized "cp 0"
>-	jr z, PIXEL_WHITE	; Execute PIXEL_WHITE if C=0
>-	dec a			; optimized "cp 1"
>-	jr z, PIXEL_BLACK	; Execute PIXEL_BLACK if C=1
>-	dec a			; optimized "cp 2"
>-	jr nz, PIXEL_END	; Execute PIXEL_XORIT if C=2

	;Inline XOR routine
>-	ld a, d			; 'a' now has X Coordinate (>-Moved this inline)
	call GETPIX		; Call the Pixel Routine from ZLIB
	XOR (hl)		; 'XOR' to Toggle the Pixel

PIXEL_END:
>-	ld (hl), a		; Write the new byte to Graph Buffer (>-I moved it)
	pop de			; Retrieve the Coords for Other Routines
	pop bc			; Retrieve the Loop Value and Color
	ret		

PIXEL_WHITE:
	ld a, d			; 'a' now has X Coordinate
	call GETPIX		; Call the Pixel Routine from ZLIB
	CPL			; Compliment 'a' for the correct Bit Mask
	AND (hl)		; 'AND' to Clear the Pixel
>-	jr PIXEL_END

PIXEL_BLACK:
	ld a, d			; 'a' now has X Coordinate
	call GETPIX		; Call the Pixel Routine from ZLIB
     	OR (hl)			; 'OR' to Plot the Pixel
>-	jr PIXEL_END	

This uses relative jumps instead of calls and returns.  What do you 
think?

Ok, that's my 2 cents.  I could really use this kind of code, so I hope 
to see it in a lib. :)

______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com


Follow-Ups: