		mc68020
		multipass

		xdef	@R_DrawColumn
		xdef	@R_DrawSpan

		xref	_dc_yl
		xref	_dc_yh
		xref	_dc_x
		xref	_columnofs
		xref	_ylookup
		xref	_dc_iscale
		xref	_centery
		xref	_dc_texturemid
		xref	_dc_source
		xref	_dc_colormap
		xref	_ds_xfrac
		xref	_ds_yfrac
		xref	_ds_x1
		xref	_ds_y
		xref	_ds_x2
		xref	_ds_xstep
		xref	_ds_ystep
		xref	_ds_source
		xref	_ds_colormap

SCREENWIDTH	equ	320
FRACBITS	equ	16

;***********************************************************************
@R_DrawColumn	movem.l	d3-d7/a2-a5,-(sp)
		move.l	(_dc_yl),d0
		move.l	(_dc_yh),d7
		sub.l	d0,d7
		bmi.b	1$
		move.l	(_dc_x),d1
		lea	(_columnofs),a5
		lea	(a5,d1.l*4),a1
		lea	(_ylookup),a5
		movea.l	(a5,d0.l*4),a2
		adda.l	(a1),a2
		move.l	(_dc_iscale),d6
		sub.l	(_centery),d0
		muls.l	d6,d0
		move.l	(_dc_texturemid),d5
		add.l	d0,d5
		movea.l	(_dc_source),a3
		movea.l	(_dc_colormap),a4
		moveq	#127,d4
		move.l	#SCREENWIDTH,d3
		moveq	#0,d1		; ensure high bits of d1 are clear

;2$		move.l	d5,d0		; frac
;		swap	d0
;		and.w	d4,d0		; (frac>>16)&127
;		move.b	(a3,d0.w),d1	; dc_source[(frac>>FRACBITS)&127]
;		move.b	(a4,d1.w),(a2)	; *dest = dc_colormap[d1]
;		adda.l	d3,a2		; dest += SCREENWIDTH
;		add.l	d6,d5		; frac += fracstep
;		dbra	d7,2$
;1$		movem.l	(sp)+,d3-d7/a2-a5
;		rts

; faster routine from j.selck@flensburg.netsurf.de:

		add.w	d6,d5		; frac += fracstep (also sets X flag)
		swap	d5		; swap(frac)
		swap	d6		; swap(fracstep)
		and.w	d4,d5		; (frac>>16)&127
2$		move.b	(a3,d5.w),d1	; dc_source[(frac>>FRACBITS)&127]
		move.b	(a4,d1.w),(a2)	; *dest = dc_colormap[d1]
		addx.l	d6,d5		; swap(frac += fracstep), use & set X
		adda.l	d3,a2		; dest += SCREENWIDTH
		and.w	d4,d5		; (frac>>16)&127
		dbra	d7,2$		; !! dbra slow on 68060 !!
1$		movem.l	(sp)+,d3-d7/a2-a5
		rts


; This version of R_DrawColumn from Aki M Laukkanen <amlaukka@cc.helsinki.fi>
; Looks great but graphics don't look right.
;
;		cnop	0,4
;
;@R_DrawColumn
;		movem.l	d2-d3/d5-d7/a2/a3,-(sp)
;
;		move.l	(_dc_yh),d7	; count = _dc_yh - _dc_yl
;		move.l	(_dc_yl),d0
;		sub.l	d0,d7
;		bmi	Lend
;
;		move.l	(_dc_x),d1	; dest = ylookup[_dc_yl] + columnofs[_dc_x]
;		lea	(_ylookup),a0
;		move.l	(a0,d0.l*4),a0
;		lea	(_columnofs),a1
;		add.l	(a1,d1.l*4),a0
;
;		move.l	(_dc_colormap),a2
;		move.l	(_dc_source),a1
;
;		move.l	(_dc_iscale),d1	; frac = _dc_texturemid + (_dc_yl-centery)*fracstep
;		sub.l	(_centery),d0
;		muls.w	d1,d0
;		add.l	_dc_texturemid,d0
;
;		moveq	#$7f,d3
;		move.l	#SCREENWIDTH,a3
;		move.l	d7,d6		; Do the leftover iterations in
;		and.w	#3,d6		; this loop.
;		beq	Lskip
;Lskip_loop
;		move.l	d0,d5
;		swap	d5
;		and.l	d3,d5
;		move.b	(a1,d5.w),d5
;		move.b	(a2,d5.w),(a0)
;		add.l	d1,d0
;		add.l	a3,a0
;		subq.l	#1,d6
;		bne	Lskip_loop
;
;; d7: cnt >> 2
;; a0: chunky
;; a1: texture
;; a2: light_table
;; d0: frac  (uuuu uuuu uuuu uuuu 0000 0000 0UUU UUUU)
;; d1: dfrac*2   (.......................................)
;; d2: frac+dfrac(.......................................)
;
;Lskip
;		add.l	a3,a3
;		lsr.l	#2,d7		; setup registers
;		move.l	d0,d2
;		add.l	a3,a3
;		add.l	d1,d2
;		add.l	d1,d1
;
;		eor.w	d0,d2		; swap the fraction part for addx
;		eor.w	d2,d0		; assuming 16.16 fixed point
;		eor.w	d0,d2
;
;		swap	d0		; swap decimals and fraction
;		swap	d1
;		swap	d2
;	
;		moveq	#0,d5
;		and.w	d3,d2
;		and.w	d3,d0
;
;		sub.w	d1,d0
;		add.l	d1,d0		; setup the X flag
;
;		move.b	(a1,d2.w),d5
;Lloop
;		; This should be reasonably scheduled for
;		; m68060. It should perform well on other processors
;		; too. That AGU stall still bothers me though.
;
;		move.b	(a1,d0.w),d6	; stall + pOEP but allows sOEP
;		addx.l	d1,d2		; pOEP
;		move.b	(a2,d5.l),d5	; pOEP but allows sOEP
;		and.w	d3,d2		; sOEP
;		move.b	d5,(SCREENWIDTH,a0) ; pOEP
;		move.b	(a1,d2.w),d5	; stall + pOEP but allows sOEP
;		addx.l	d1,d0		; pOEP
;		move.b	(a2,d6.l),d6	; pOEP but allows sOEP
;		and.w	d3,d0		; sOEP
;		move.b	d6,(a0)		; pOEP
;					; = ~4.5 cycles/pixel
;					; + cache misses
;
;		; The vertical writes are the true timehog of the loop
;		; because of the characteristics of the copyback cache
;		; operation.
;
;		; Better mark the chunky buffer as write through
;		; with the MMU and have all the horizontal writes
;		; be longs aligned to longword boundary.
;
;		move.b	(a1,d0.w),d6
;		addx.l	d1,d2
;		move.b	(a2,d5.l),d5
;		and.w	d3,d2
;		move.b	d5,(SCREENWIDTH*3,a0)
;		move.b	(a1,d2.w),d5
;		addx.l	d1,d0
;		move.b	(a2,d6.l),d6
;		and.w	d3,d0
;		move.b	d6,(SCREENWIDTH*2,a0)
;
;		add.l	a3,a0
;Lloop_end
;		dbf	d7,Lloop
;Lend
;		movem.l	(sp)+,d2-d3/d5-d7/a2/a3
;		rts


;void R_DrawColumn (void)
;{
;  int count;
;  byte* dest;
;  fixed_t frac;
;  fixed_t fracstep;
;
;  count = dc_yh - dc_yl;
;  if (count < 0)
;    return;
;  dest = ylookup[dc_yl] + columnofs[dc_x];
;  fracstep = dc_iscale;
;  frac = dc_texturemid + (dc_yl-centery)*fracstep;
;  do {
;    *dest = dc_colormap[dc_source[(frac>>FRACBITS)&127]];
;    dest += SCREENWIDTH;
;    frac += fracstep;
;  } while (count--);
;}

;***********************************************************************
@R_DrawSpan	movem.l	d2-d7/a2-a5,-(a7)
		move.l	(_ds_x1),d0
		lea	(_columnofs),a5
		lea	(a5,d0.l*4),a1
		move.l	(_ds_y),d1
		lea	(_ylookup),a5
		movea.l	(a5,d1.l*4),a2
		adda.l	(a1),a2
		move.l	(_ds_x2),d5
		sub.l	d0,d5		; count
		movea.l	(_ds_source),a3
		movea.l	(_ds_colormap),a4
		move.l	(_ds_xstep),d3
		move.l	(_ds_ystep),d4
;-
		moveq	#10,d2
		moveq	#63,d6
		move.l	#63*64,d7
		movea.l	(_ds_xfrac),a0	; xfrac
		movea.l	(_ds_yfrac),a1	; yfrac
1$		move.l	a0,d0		; xfrac
		swap	d0
		and.l	d6,d0		; (xfrac>>16)&63
		move.l	a1,d1		; yfrac
		asr.l	d2,d1
		and.l	d7,d1		; (yfrac>>10)&(63*64)
		add.l	d0,d1		; spot
		moveq	#0,d0
		move.b	(a3,d1.l),d0	; ds_source[spot]
		move.b	(a4,d0.w),(a2)+	; *dest++ = ds_colormap[...]
		adda.l	d3,a0		; xfrac += ds_xstep
		adda.l	d4,a1		; yfrac += ds_ystep
		dbra	d5,1$
		movem.l	(a7)+,d2-d7/a2-a5
		rts

;; faster routine from j.selck@flensburg.netsurf.de (doesn't seem to work):
;
;		move.l	(_ds_xfrac),d0	; xfrac
;		move.l	(_ds_yfrac),d1	; yfrac
;		move.w	d0,d2		; exg.w d0,d1
;		move.w	d1,d0		; d0 = (yh,xl)
;		move.w	d2,d1		; d1 = (xh,yl)
;		move.w	d3,d2		; exg.w d3,d4
;		move.w	d4,d3		; d3 = (xfh,yfl)
;		move.w	d2,d4		; d4 = (yfh,xfl)
;		moveq	#63,d6		; mask
;		moveq	#0,d2		; keep upper bits clear
;		add.w	d3,d1		; yl += yfl, set X for addx
;		swap	d0		; (xl,yh)
;		swap	d1		; (yl,xh)
;		swap	d3		; (yfl,xfh)
;		swap	d4		; (xfl,yfh)
;1$		and.w	d6,d0		; xh &= $63
;		and.w	d6,d1		; yh &= $63
;		move.w	d1,d7
;		rol.w	#6,d7		; (yh & 63) * 64 (don't touch X flag!)
;		or.w	d0,d7		; spot = (yh & 63) * 64 + (xh & 63)
;		move.b	(a3,d7.w),d2	; ds_source[spot]
;		move.b	(a4,d2.w),(a2)+	; *dest++ = ds_colormap[...]
;		addx.l	d4,d0		; (xl,yh) += (xfl,yfh), use and set X
;		addx.l	d3,d1		; (yl,xh) += (yfl,xfh), use and set X
;		dbra	d5,1$		; !! dbra slow on 68060 !!
;		movem.l	(a7)+,d2-d7/a2-a5
;		rts

;void R_DrawSpan (void)
;{
;  fixed_t xfrac, yfrac;
;  byte* dest;
;  int count, spot;
;
;  xfrac = ds_xfrac;
;  yfrac = ds_yfrac;
;  dest = ylookup[ds_y] + columnofs[ds_x1];
;  count = ds_x2 - ds_x1;
;  do {
;    spot = ((yfrac>>(16-6))&(63*64)) + ((xfrac>>16)&63);
;    *dest++ = ds_colormap[ds_source[spot]];
;    xfrac += ds_xstep;
;    yfrac += ds_ystep;
;  } while (count--);
;}

;***********************************************************************

		end
