*****************************************************************************
* MegaJitter		written by L. Vanhelsuwé	(C) Aug 1992-94
* ----------		------------------------	---------------
*
* This file contains optimized assembler routines to be called from C.
*
* HISTORY
* -------
* 20-APR-1994:	Added register args versions of routines
* 12-MAY-1994:	Further optimized code by using INTERLEAVED bitplanes.
*
* NOTES:	- screen coordinates are assumed to be clipped by caller.
*			  No clipping is performed here!
*
*			- Number of bitplanes is fixed at 4.
*
*			- Resolution is fixed at 512 * 512
*
*			- Bitplanes are INTERLEAVED for extra performance.
*
*****************************************************************************

		XREF	_plane0			;ptr to bitplane 0

		xdef	_asm_plot_pixel
		xdef	_asm_read_pixel
		xdef	_asm_is_food
		xdef	_asm_is_empty
		xdef	_asm_fastwipe_pixel

SCREEN_MAXX	equ	512			; all code below hardwired for this
SCREEN_MAXY	equ	512

NUM_COLORS	equ	16			; 4 bitplanes **!!


;-----------------------------------------------------------------------------
; Here follow the versions with stack-based arguments.
;-----------------------------------------------------------------------------

**!! I'm being x-tremely naughty here. I'm messing around with registers
**!! in the d2-d7/a2-a6 group which I don't save. Lattice C doesn't seem to mind...

;-----------------------------------------------------------------------------
; FastPlot ( FastPixel*, x, y, color)
;
; D0/D1/D2 = X/Y  color 0..15		USES D0,D1,D2,D3	A0,A1
;-----------------------------------------------------------------------------

IPIXEL		MACRO

		b\4	d3,(a0)		;bitplane 0
		b\3	d3,064(a0)	;bitplane 1 (64 bytes further down)
		b\2	d3,128(a0)	;bitplane 2
		b\1	d3,192(a0)	;bitplane 3
		rts

		ENDM


		cnop	0,8

_asm_plot_pixel	move.l	4(sp),a1		;get FastPix*
		movem.l	8(sp),d0/d1/d2		;get x,y,color

		move.w	d0,d3			;copy of x (no need to AND)
		not.b	d3			;0->7  7->0

		lsl.l	#8,d1			;*256 for 512 pixel wide interleaved screen
		lsr.w	#3,d0			;pixel offset -> byte offset
		add.l	d1,d0			; calc byte offset

		move.l	d0,(a1)+		;store offset for wipe_pixel !
		move.l	d3,(a1)+		;store bitno  for wipe_pixel !

		move.l	_plane0,a0
		add.l	d0,a0			;-> byte in bitplane 0

		and.w	#NUM_COLORS-1,d2
		add.w	d2,d2
		jmp	piX0(PC,D2*8)		;execute 1 of 16 custom plotters

piX0		IPIXEL	clr,clr,clr,clr
		IPIXEL	clr,clr,clr,set
		IPIXEL	clr,clr,set,clr
		IPIXEL	clr,clr,set,set
		IPIXEL	clr,set,clr,clr
		IPIXEL	clr,set,clr,set
		IPIXEL	clr,set,set,clr
		IPIXEL	clr,set,set,set
		IPIXEL	set,clr,clr,clr
		IPIXEL	set,clr,clr,set
		IPIXEL	set,clr,set,clr
		IPIXEL	set,clr,set,set
		IPIXEL	set,set,clr,clr
		IPIXEL	set,set,clr,set
		IPIXEL	set,set,set,clr
		IPIXEL	set,set,set,set

;-----------------------------------------------------------------------------
; BOOL = is_food  (x, y)
; BOOL = is_empty (x, y)
;-----------------------------------------------------------------------------
_asm_is_food	movem.l	4(sp),d0-d1		;x, y

		move.w	d0,d2			;copy of x
		not.b	d2			;0->7  7->0

		lsr.w	#3,d0			;pixel offset -> byte offset
		lsl.l	#8,d1			;Y*256 (256 = bytesPerRow)
		add.l	d0,d1			;= byte offset

		moveq	#0,d0			;assume FALSE

		move.l	_plane0,a0
		add.l	d1,a0			;-> byte in bitplane 0

		btst	d2,(a0)			;test bit (no need for AND#7)
		beq.s	no_food2		;if any bit is 0 -> FALSE

		  btst	d2,064(a0)
		  beq.s	no_food2		;%11xx

		    btst   d2,128(a0)
		    beq.s  no_food2			;%111x

		      btst	d2,192(a0)
		      beq.s	no_food2			;%1111

		moveq	#-1,d0			;return TRUE

no_food2	rts

;-----------------------------------------------------------------------------
_asm_is_empty	movem.l	4(sp),d0-d1		;x, y

		move.w	d0,d2			;copy of x
		not.b	d2			;0->7  7->0

		lsr.w	#3,d0			;pixel offset -> byte offset
		lsl.l	#8,d1			;Y*256
		add.l	d0,d1			;= byte offset

		moveq	#0,d0			;assume FALSE

		move.l	_plane0,a0
		add.l	d1,a0

		btst	d2,(a0)			;test bit (no need for AND#7)
		bne.s	no_food2		;if any bit is 1 -> FALSE

		  btst	d2,064(a0)
		  bne.s	no_food2

		    btst    d2,128(a0)
		    bne.s   no_food2

		      btst	d2,192(a0)
		      bne.s	no_food2

		moveq	#-1,d0			;return TRUE

		rts

;-----------------------------------------------------------------------------
; FastWipe (FastPixel*)
;
;-----------------------------------------------------------------------------
		cnop	0,2

_asm_fastwipe_pixel
		move.l	4(sp),a1		;grab arg

		move.l	_plane0,a0		;grab bitplane base ptr

		add.l	(a1)+,a0		;-> byte containing pixel
		move.l	(a1)+,d0		;fetch pre-computed pixel

		bclr	d0,(a0)			;erase pixel	in plane 0
		bclr	d0,064(a0)		;		in plane 1
		bclr	d0,128(a0)		;		in plane 2
		bclr	d0,192(a0)		;		in plane 3
		rts

;-----------------------------------------------------------------------------
; color = ReadPixel (x, y)
;
; D0/D1 = X/Y  
;-----------------------------------------------------------------------------
_asm_read_pixel	movem.l	4(sp),d0-d1		;x, y

		move.w	d0,d2			;isolate bit #
		not.b	d2			;0->7  7->0

		lsr.w	#3,d0			;pixel offset -> byte offset
		lsl.l	#8,d1			;* bm_BytesPerRow
		add.l	d0,d1			;= byte offset

		moveq	#0,d0			;assume color 0

		move.l	_plane0,a1		;plane 0 ptr
		add.l	d1,a1			;-> byte in plane 0 to be tested

		btst	d2,(a1)			;test bit
		beq.s	next_fplane02
		moveq	#1,d0			;if set, add bit in color

next_fplane02	btst	d2,064(a1)
		beq.s	next_fplane12
		addq.b	#2,d0

next_fplane12	btst	d2,128(a1)
		beq.s	next_fplane22
		addq.b	#4,d0

next_fplane22	btst	d2,192(a1)
		beq.s	next_fplane32
		addq.b	#8,d0

next_fplane32	rts

