Try this, modified from a posting of mine earlier this year.
COMPILE ,_dimmedvarsOnly
DIM gRowBytes,gBaseAddr&,gScrnRect.8
END GLOBALS
_useASM=_false ' _zTrue
LOCAL FN SetCPixel(x,y,pixelVal&)
'fast replacement for SETCPIXEL; works in 256 colours only
COMPILE LONG IF _useASM 'very fast
REGISTER(a1)=gBaseAddr&
REGISTER(d0)=gRowBytes
` add.w ^x,a1
` muls ^y,d0
` move.l ^pixelVal&,d1
` move.b d1,(a1,d0.l)
COMPILE XELSE ' safer; clip to gScrnRect
LONG IF (x>=0) AND (x< GSCRNRECT.RIGHT)
IF (y > =0) AND (y < GSCRNRECT.BOTTOM) POKE y*gRowBytes+gBaseAddr&+x,pixelVal&
END IF
COMPILE END IF
END FN
LOCAL FN GetScreenGWParameters
DIM currPort&,currDevice&,pmHand&
CALL GETGWORLD(currPort&,currDevice&)
pmHand&=FN GETGWORLDPIXMAP(currPort&)
gScrnRect;8=@pmHand&..pmBounds%
gRowBytes=pmHand&..pmRowBytes% AND &3FFF
gBaseAddr&=FN GETPIXBASEADDR(pmHand&)
END FN
LOCAL FN SetRandomRGB(rgbPtr&)
rgbPtr&.red%=RND(32767)*2
rgbPtr&.green%=RND(32767)*2
rgbPtr&.blue%=RND(32767)*2
END FN
DIM j,k,rgb.6,pixelVal&,tk1&,tk2&
DIM windRect.8, aPoint.0, yOffset,xOffset
WINDOW 1,"Compare",(50,70)-(500,400),_docNoGrow
windRect;8=WINDOW(_wndPointer)+_portRect
FN GetScreenGWParameters
CALL SETPT(aPoint,0,0)
CALL LOCALTOGLOBAL(aPoint)
DO
tk1&=FN TICKCOUNT
FOR j=0 TO windRect.right-1 'Paint the window...
FN SetRandomRGB(@rgb) '...in coloured stripes...
FOR k=0 TO windRect.bottom-1 '...a pixel at a time...
CALL SETCPIXEL(j,k,rgb) '...by a slow method.
NEXT : NEXT
tk1&=FN TICKCOUNT-tk1&
tk2&=FN TICKCOUNT
FOR j=0 TO windRect.bottom-1
FN SetRandomRGB(@rgb)
pixelVal&=FN COLOR2INDEX(rgb) ' convert rgb to pixel value
FOR k=0 TO windRect.right-1 'Paint the window...
FN SetCPixel(k+xOffset,j+yOffset,pixelVal&) '...by a faster method.
NEXT : NEXT
tk2&=FN TICKCOUNT-tk2&
CALL TEXTMODE(_srcCopy)
PRINT%(210,20) tk1& "CALL SETCPIXEL" ' show times
PRINT%(210,40) tk2& "FN SetCPixel"
UNTIL FN BUTTON OR (INKEY$<>"")