*=======================================================*
*	AddWall: latest update 27/11/95			*
*=======================================================*
*	Build wall & floor runs for 3D environment.	*
*=======================================================*
*     >	New 68030 replacement by Douglas Little.	*
*     >	Atari C conversion by Johan Klockars.		*
*     >	Original C++ code for the PC by Jake Hill	*
*=======================================================*
*	Some improvements made to 68030 version:	*
*=======================================================*
*     >	Algorithm cleaned up to reduce overprinting.	*
*     >	Fewer calculations performed on 'invisibles'.	*
*     >	Upper & lower walls now update occlusion list.	*
*     >	Walls can be placed on sub-pixel boundaries.	*
*     >	Bugs in floors & ceilings removed.		*
*     >	Algorithm uses ~ 90% register based logic.	*
*     >	Local variables accessed from structure.	*
*     >	Optimised (non-stackable) program-flow.		*
*     >	Missing-column bug greatly suppressed.		*
*     >	Higher accuracy arithmetic used on walls.	*
*     >	Improved column clipping logic (drawing bugs).	*
*=======================================================*

;customflow	; enable for optimised non-stackable subroutines.
		; this produces bigger code, but no stack access.
		; it would benefit more from better cacheing and
		; isn't really worth enabling yet.

*-------------------------------------------------------*
*	These register equates are for clarity		*
*-------------------------------------------------------*

column_lasttop		equr	a2
column_lastmaxy		equr	a3
column_lastbot		equr	a4
column_lastminy		equr	a5

column_thistop		equr	d2
column_thisminy		equr	d3
column_thismaxy		equr	d4
column_thisbot		equr	d5

floor_tex		equr	d0
floor_y1		equr	d1
floor_y2		equr	d6

*-------------------------------------------------------*
*	Custom program-flow macros			*
*-------------------------------------------------------*

jsu	macro		; call subunit & return to current location (non stackable)
	ifd		customflow
	lea		.r\@(pc),a1
	bra		\1
	elseif
	bsr		\1
	endc
.r\@:
	endm

jsur	macro		; call subunit & return to distant location (non stackable)
	ifd		customflow
	lea		(\2)(pc),a1
	bra		\1
	elseif
	bsr		\1
	bra.s		\2
	endc
.r\@:
	endm
	
rtu	macro		; return from subunit
	ifd		customflow
	jmp		(a1)
	elseif
	rts
	endc
	endm

advance	macro
	moveq		#0,d6
	move.w		addwall_ysize(a6),d6
	move.w		addwall_y1a(a6),column_thistop
	move.l		addwall_y1i(a6),d0
	ext.l		column_thistop
	bpl.s		.tc1
	moveq		#0,column_thistop
.tc1:	add.l		d0,addwall_y1a(a6)
	move.w		addwall_y2a(a6),column_thisbot
	move.l		addwall_y2i(a6),d0
	ext.l		column_thisbot
	cmp.l		column_thisminy,column_thisbot
	bpl.s		.bc1
	move.l		column_thisminy,column_thisbot
.bc1:	add.l		d0,addwall_y2a(a6)
	cmp.l		column_thismaxy,column_thistop
	bmi.s		.tc2
	move.l		column_thismaxy,column_thistop
.tc2:	cmp.l		d6,column_thisbot
	bmi.s		.bc2
	move.l		d6,column_thisbot
.bc2:
	endm

*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
*	Generate a new wall, floor & ceiling chunk	*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
AddWall:pea		(a3)
	pea		(a4)
*-------------------------------------------------------*
	move.w		wallruncount,addwall_runs(a6)
	move.w		columns,addwall_columns(a6)
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
*	Vertical (y) perspective projection		*
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*
*	y' = y * ( (w/2) / z ) + (h/2)			*
*-------------------------------------------------------*
	moveq		#0,d6
	move.w		addwall_ysize(a6),d6
	moveq		#0,d0
	move.w		addwall_xsize(a6),d0
	lsr.w		d0			; (w/2)
	lsr.w		d6			; (h/2)
	move.l		addwall_y1(a6),d1
	swap		d0
	swap		d6
	move.l		d0,d2
	muls.l		d1,d7:d2
	divs.l		addwall_z1(a6),d7:d2
	add.l		d6,d2
	move.l		d0,d5
	muls.l		d1,d7:d5
	divs.l		addwall_z2(a6),d7:d5
	move.l		addwall_y2(a6),d1
	add.l		d6,d5
	move.l		d0,d3
	muls.l		d1,d7:d3
	divs.l		addwall_z1(a6),d7:d3
	add.l		d6,d3
	move.l		d0,d4
	muls.l		d1,d7:d4
	divs.l		addwall_z2(a6),d7:d4
	add.l		d6,d4
*-------------------------------------------------------*
*	Calculate dy1 & dy2 gradients			*	
*-------------------------------------------------------*
.flip:	move.l		addwall_i2(a6),d0
	sub.l		addwall_i1(a6),d0
	sub.l		d2,d5
	swap		d5
	move.w		d5,d6
	ext.l		d6
	move.w		addwall_i1(a6),d7
	clr.w		d5
	divs.l		d0,d6:d5	; dy1 = (ry1-ly1) / (x2-x1)
	move.l		d4,d1
	sub.l		d3,d1
	swap		d1
	move.w		d1,d6
	ext.l		d6
	clr.w		d1
	divs.l		d0,d6:d1	; dy2 = (ry2-ly2) / (x2-x1)
*-------------------------------------------------------*
*	Clip wall against left edge			*	
*-------------------------------------------------------*
	ext.l		d7
	bpl.s		.nolc
	move.l		d7,d6
	muls.l		d5,d6
	sub.l		d6,d2		; y1 = y1 - (x1*dy1)
	move.l		d7,d6
	muls.l		d1,d6
	sub.l		d6,d3		; y2 = y2 - (x1*dy2)
	moveq		#0,d7
*-------------------------------------------------------*
*	Load results into local loop registers		*	
*-------------------------------------------------------*
.nolc:	move.l		d2,addwall_y1a(a6)
	move.l		d3,addwall_y2a(a6)
	move.l		d5,addwall_y1i(a6)
	move.l		d1,addwall_y2i(a6)
*-------------------------------------------------------*
*	Clip wall against right edge			*
*-------------------------------------------------------*
	move.w		addwall_i2(a6),d6
	move.w		addwall_xsize(a6),d0
	cmp.w		d0,d6
	bmi.s		.x2in
	move.w		d0,d6
.x2in:	move.w		d6,addwall_ci2(a6)
*-------------------------------------------------------*
*	Prefetch column history registers		*
*-------------------------------------------------------*
	lea		miny,a0
	move.w		(a0,d7.l*2),column_lastminy
	moveq		#0,column_thisminy
	lea		maxy,a0
	move.w		(a0,d7.l*2),column_lastmaxy
	moveq		#0,column_thismaxy
	move.l		column_lastminy,column_lasttop
	move.l		column_lastmaxy,column_lastbot
*-------------------------------------------------------*
*	Determine logic group for edge generation	*
*-------------------------------------------------------*
	cmp.b		#UPPER_TYPE,addwall_type(a6)
	beq		AddUpperWall
	cmp.b		#LOWER_TYPE,addwall_type(a6)
	beq		AddLowerWall

*-------------------------------------------------------*
AddMidWall:
*-------------------------------------------------------*
midwall_loop:
*-------------------------------------------------------*
*	Fetch vertical clipping bounds			*
*-------------------------------------------------------*
	lea		miny,a0
	move.w		(a0,d7.l*2),column_thisminy
	lea		maxy,a0
	move.w		(a0,d7.l*2),column_thismaxy
*-------------------------------------------------------*
*	Advance edge accumulators			*
*-------------------------------------------------------*
	advance
*-------------------------------------------------------*
*	Generate floor buckets				*
*-------------------------------------------------------*
	cmp.l		column_thismaxy,column_thisbot
	bpl.s		.clip_lower
*-------------------------------------------------------*
	cmp.l		column_lastbot,column_thisbot
	bpl.s		.nf1
	move.l		column_thisbot,floor_y1
	move.l		column_lastbot,floor_y2
	jsu		flat_leftedge
.nf1:	cmp.l		column_thismaxy,column_lastmaxy
	bpl.s		.nf2
	move.l		column_lastmaxy,floor_y1
	move.l		column_thismaxy,floor_y2
	jsu		flat_leftedge
.nf2:	cmp.l		column_lastbot,column_thisbot
	ble.s		.nf3
	move.l		column_lastbot,floor_y1
	move.l		column_thisbot,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsu		flat_rightedge
.nf3:	cmp.l		column_thismaxy,column_lastmaxy
	ble.s		.floor_done
	move.l		column_thismaxy,floor_y1
	move.l		column_lastmaxy,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsur		flat_rightedge,.floor_done
*-------------------------------------------------------*
.clip_lower:
*-------------------------------------------------------*
	cmp.l		column_lastbot,column_lastmaxy
	ble.s		.floor_done
	move.l		column_lastbot,floor_y1
	move.l		column_lastmaxy,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsu		flat_rightedge
*-------------------------------------------------------*
.floor_done:
*-------------------------------------------------------*
*	Generate ceiling buckets			*
*-------------------------------------------------------*
	cmp.l		column_thisminy,column_thistop
	ble.s		.clip_upper
*-------------------------------------------------------*
	cmp.l		column_lasttop,column_thistop
	ble.s		.nc1
	move.l		column_lasttop,floor_y1
	move.l		column_thistop,floor_y2
	jsu		flat_leftedge
.nc1:	cmp.l		column_thisminy,column_lastminy
	ble.s		.nc2
	move.l		column_thisminy,floor_y1
	move.l		column_lastminy,floor_y2
	jsu		flat_leftedge
.nc2:	cmp.l		column_lasttop,column_thistop
	bpl.s		.nc3
	move.l		column_thistop,floor_y1
	move.l		column_lasttop,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsu		flat_rightedge
.nc3:	cmp.l		column_thisminy,column_lastminy
	bpl.s		.ceiling_done
	move.l		column_lastminy,floor_y1
	move.l		column_thisminy,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsur		flat_rightedge,.ceiling_done
*-------------------------------------------------------*
.clip_upper:
*-------------------------------------------------------*
	cmp.l		column_lasttop,column_lastminy
	bpl.s		.ceiling_done
	move.l		column_lastminy,floor_y1
	move.l		column_lasttop,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsu		flat_rightedge
*-------------------------------------------------------*
.ceiling_done:
*-------------------------------------------------------*
*	Rotate column history registers			*
*-------------------------------------------------------*
	move.l		column_thistop,column_lasttop 
	move.l		column_thisbot,column_lastbot 
	move.l		column_thisminy,column_lastminy 
	move.l		column_thismaxy,column_lastmaxy 
*-------------------------------------------------------*
*	Check - column is already sealed off		*
*-------------------------------------------------------*
	cmp.l		column_thisminy,column_thismaxy 
	ble		.skip
*-------------------------------------------------------*
*	Check - column below [maxy] - blocked by roof	*
*-------------------------------------------------------*
	cmp.l		column_thistop,column_thismaxy 
	ble.s		.update_window
*-------------------------------------------------------*
*	Check - column above [miny] - blocked by floor	*
*-------------------------------------------------------*
	cmp.l		column_thisbot,column_thisminy 
	bpl.s		.update_window
*-------------------------------------------------------*
*	Clip - top of column cropped by [miny]		*
*-------------------------------------------------------*
	cmp.l		column_thistop,column_thisminy 
	ble.s		.ncl1
	move.l		column_thisminy,column_thistop 
*-------------------------------------------------------*
*	Clip - bottom of column cropped by [maxy]	*
*-------------------------------------------------------*
.ncl1:	cmp.l		column_thisbot,column_thismaxy 
	bpl.s		.ncl2
	move.l		column_thismaxy,column_thisbot 
*-------------------------------------------------------*
*	Check - column cropped to zero length		*
*-------------------------------------------------------*
.ncl2:	cmp.l		column_thistop,column_thisbot 
	ble.s		.update_window
*-------------------------------------------------------*
*	Column bucket generator				*
*-------------------------------------------------------*
	moveq		#0,d6
	move.w		addwall_runs(a6),d6
	lea		wallruns,a0
	move.l		d6,d0
	lsl.l		#3,d0
	add.l		d0,a0
	move.w		d7,d0
	tst.b		addwall_opaque(a6)
	beq.s		.solid
	not.w		d0
.solid:	move.w		addwall_tex(a6),wall_id(a0)
	move.w		d0,wall_x(a0)
	move.w		column_thistop,wall_y1(a0)
	move.w		column_thisbot,wall_y2(a0)
	addq		#1,d6
	move.w		d6,addwall_runs(a6)
*-------------------------------------------------------*
*	Update vertical clipping bar			*
*-------------------------------------------------------*
.update_window:
*-------------------------------------------------------*
	tst.b		addwall_opaque(a6)
	bne.s		.trans
	moveq		#0,column_thisbot
	move.w		addwall_ysize(a6),column_thistop
.trans:	cmp.l		column_thistop,column_thisbot
	bgt.s		.upd
	lea		occlusion_list,a0
	move.b		#0,(a0,d7.l)
	subq.w		#1,addwall_columns(a6)
	beq.s		.stop
.upd:	lea		miny,a0
	move.w		column_thistop,(a0,d7.l*2)
	lea		maxy,a0
	move.w		column_thisbot,(a0,d7.l*2)
*-------------------------------------------------------*
*	Advance to next column				*
*-------------------------------------------------------*
.skip:	addq.l		#1,d7
	cmp.w		addwall_ci2(a6),d7
	bmi		midwall_loop
	bra.s		.done
*-------------------------------------------------------*
*	Premature termination				*
*-------------------------------------------------------*
.stop	addq.l		#1,d7
*-------------------------------------------------------*
*	Fill gaps left in floor & ceiling by edges	*
*-------------------------------------------------------*
.done:	cmp.l		column_lastbot,column_lastmaxy
	ble.s		.nfl
	move.l		column_lastbot,floor_y1
	move.l		column_lastmaxy,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsu		flat_rightedge
.nfl:	cmp.l		column_lasttop,column_lastminy
	bpl.s		.ncl
	move.l		column_lastminy,floor_y1
	move.l		column_lasttop,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsu		flat_rightedge
*-------------------------------------------------------*
.ncl:	move.w		addwall_runs(a6),wallruncount
	move.w		addwall_columns(a6),columns
	pop.l		a4
	pop.l		a3
	rts

*-------------------------------------------------------*
AddUpperWall:
*-------------------------------------------------------*
upperwall_loop:
*-------------------------------------------------------*
*	Fetch vertical clipping bounds			*
*-------------------------------------------------------*
	lea		miny,a0
	move.w		(a0,d7.l*2),column_thisminy
	lea		maxy,a0
	move.w		(a0,d7.l*2),column_thismaxy
*-------------------------------------------------------*
*	Advance edge accumulators			*
*-------------------------------------------------------*
	advance
*-------------------------------------------------------*
*	Generate ceiling buckets			*
*-------------------------------------------------------*
	cmp.l		column_thisminy,column_thistop
	ble.s		.clip_upper
*-------------------------------------------------------*
	cmp.l		column_lasttop,column_thistop
	ble.s		.nc1
	move.l		column_lasttop,floor_y1
	move.l		column_thistop,floor_y2
	jsu		flat_leftedge
.nc1:	cmp.l		column_thisminy,column_lastminy
	ble.s		.nc2
	move.l		column_thisminy,floor_y1
	move.l		column_lastminy,floor_y2
	jsu		flat_leftedge
.nc2:	cmp.l		column_lasttop,column_thistop
	bpl.s		.nc3
	move.l		column_thistop,floor_y1
	move.l		column_lasttop,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsu		flat_rightedge
.nc3:	cmp.l		column_thisminy,column_lastminy
	bpl.s		.ceiling_done
	move.l		column_lastminy,floor_y1
	move.l		column_thisminy,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsur		flat_rightedge,.ceiling_done
*-------------------------------------------------------*
.clip_upper:
*-------------------------------------------------------*
	cmp.l		column_lasttop,column_lastminy
	bpl.s		.ceiling_done
	move.l		column_lastminy,floor_y1
	move.l		column_lasttop,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsu		flat_rightedge
*-------------------------------------------------------*
.ceiling_done:
*-------------------------------------------------------*
*	Rotate column history registers			*
*-------------------------------------------------------*
	move.l		column_thistop,column_lasttop 
	move.l		column_thisbot,column_lastbot 
	move.l		column_thisminy,column_lastminy 
	move.l		column_thismaxy,column_lastmaxy 
*-------------------------------------------------------*
*	Check - column is already sealed off		*
*-------------------------------------------------------*
	cmp.l		column_thisminy,column_thismaxy 
	ble.s		.skip
*-------------------------------------------------------*
*	Check - column above [miny] - ignore it		*
*-------------------------------------------------------*
	cmp.l		column_thisbot,column_thisminy 
	bpl.s		.skip
*-------------------------------------------------------*
*	Check - column below [maxy] - blocked by roof	*
*-------------------------------------------------------*
	cmp.l		column_thistop,column_thismaxy 
	ble.s		.update_window
*-------------------------------------------------------*
*	Clip - top of column cropped by [miny]		*
*-------------------------------------------------------*
	cmp.l		column_thistop,column_thisminy 
	ble.s		.ncl1
	move.l		column_thisminy,column_thistop 
*-------------------------------------------------------*
*	Clip - bottom of column cropped by [maxy]	*
*-------------------------------------------------------*
.ncl1:	cmp.l		column_thisbot,column_thismaxy 
	bpl.s		.ncl2
	move.l		column_thismaxy,column_thisbot 
*-------------------------------------------------------*
*	Check - column cropped to zero length		*
*-------------------------------------------------------*
.ncl2:	cmp.l		column_thistop,column_thisbot 
	ble.s		.update_window
*-------------------------------------------------------*
*	Column bucket generator				*
*-------------------------------------------------------*
	moveq		#0,d6
	move.w		addwall_runs(a6),d6
	lea		wallruns,a0
	move.l		d6,d0
	lsl.l		#3,d0
	add.l		d0,a0
	move.w		addwall_tex(a6),wall_id(a0)
	move.w		d7,wall_x(a0)
	move.w		column_thistop,wall_y1(a0)
	move.w		column_thisbot,wall_y2(a0)
	addq		#1,d6
	move.w		d6,addwall_runs(a6)
*-------------------------------------------------------*
*	Update vertical clipping bar			*
*-------------------------------------------------------*
.update_window:
*-------------------------------------------------------*
	move.l		column_thisbot,d1
	cmp.l		column_thismaxy,d1
	blt.s		.upd
	lea		occlusion_list,a0
	move.b		#0,(a0,d7.l)
	subq.w		#1,addwall_columns(a6)
	beq.s		.stop
	lea		maxy,a0
	move.w		#0,(a0,d7.l*2)
	move.w		addwall_ysize(a6),d1
.upd:	lea		miny,a0
	move.w		d1,(a0,d7.l*2)
*-------------------------------------------------------*
*	Advance to next column				*
*-------------------------------------------------------*
.skip:	addq.l		#1,d7
	cmp.w		addwall_ci2(a6),d7
	bmi		upperwall_loop
	bra.s		.done
*-------------------------------------------------------*
*	Premature termination				*
*-------------------------------------------------------*
.stop	addq.l		#1,d7
*-------------------------------------------------------*
*	Fill gaps left in floor & ceiling by edges	*
*-------------------------------------------------------*
.done:	cmp.l		column_lasttop,column_lastminy
	bpl.s		.ncl
	move.l		column_lastminy,floor_y1
	move.l		column_lasttop,floor_y2
	move.w		addwall_cc(a6),floor_tex
	jsu		flat_rightedge
*-------------------------------------------------------*
.ncl:	move.w		addwall_runs(a6),wallruncount
	move.w		addwall_columns(a6),columns
	pop.l		a4
	pop.l		a3
	rts

*-------------------------------------------------------*
AddLowerWall:
*-------------------------------------------------------*
lowerwall_loop:
*-------------------------------------------------------*
*	Fetch vertical clipping bounds			*
*-------------------------------------------------------*
	lea		miny,a0
	move.w		(a0,d7.l*2),column_thisminy
	lea		maxy,a0
	move.w		(a0,d7.l*2),column_thismaxy
*-------------------------------------------------------*
*	Advance edge accumulators			*
*-------------------------------------------------------*
	advance
*-------------------------------------------------------*
*	Generate floor buckets				*
*-------------------------------------------------------*
	cmp.l		column_thismaxy,column_thisbot
	bpl.s		.clip_lower
*-------------------------------------------------------*
	cmp.l		column_lastbot,column_thisbot
	bpl.s		.nf1
	move.l		column_thisbot,floor_y1
	move.l		column_lastbot,floor_y2
	jsu		flat_leftedge
.nf1:	cmp.l		column_thismaxy,column_lastmaxy
	bpl.s		.nf2
	move.l		column_lastmaxy,floor_y1
	move.l		column_thismaxy,floor_y2
	jsu		flat_leftedge
.nf2:	cmp.l		column_lastbot,column_thisbot
	ble.s		.nf3
	move.l		column_lastbot,floor_y1
	move.l		column_thisbot,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsu		flat_rightedge
.nf3:	cmp.l		column_thismaxy,column_lastmaxy
	ble.s		.floor_done
	move.l		column_thismaxy,floor_y1
	move.l		column_lastmaxy,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsur		flat_rightedge,.floor_done
*-------------------------------------------------------*
.clip_lower:
*-------------------------------------------------------*
	cmp.l		column_lastbot,column_lastmaxy
	ble.s		.floor_done
	move.l		column_lastbot,floor_y1
	move.l		column_lastmaxy,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsu		flat_rightedge	
*-------------------------------------------------------*
.floor_done:
*-------------------------------------------------------*
*	Rotate column history registers			*
*-------------------------------------------------------*
	move.l		column_thistop,column_lasttop 
	move.l		column_thisbot,column_lastbot 
	move.l		column_thisminy,column_lastminy 
	move.l		column_thismaxy,column_lastmaxy 
*-------------------------------------------------------*
*	Check - column is already sealed off		*
*-------------------------------------------------------*
	cmp.l		column_thisminy,column_thismaxy 
	ble.s		.skip
*-------------------------------------------------------*
*	Check - column below [maxy] - ingore it		*
*-------------------------------------------------------*
	cmp.l		column_thistop,column_thismaxy 
	ble.s		.skip
*-------------------------------------------------------*
*	Check - column above [miny] - blocked by floor	*
*-------------------------------------------------------*
	cmp.l		column_thisbot,column_thisminy 
	bpl.s		.update_window
*-------------------------------------------------------*
*	Clip - top of column cropped by [miny]		*
*-------------------------------------------------------*
	cmp.l		column_thistop,column_thisminy 
	ble.s		.ncl1
	move.l		column_thisminy,column_thistop 
*-------------------------------------------------------*
*	Clip - bottom of column cropped by [maxy]	*
*-------------------------------------------------------*
.ncl1:	cmp.l		column_thisbot,column_thismaxy 
	bpl.s		.ncl2
	move.l		column_thismaxy,column_thisbot 
*-------------------------------------------------------*
*	Check - column cropped to zero length		*
*-------------------------------------------------------*
.ncl2:	cmp.l		column_thistop,column_thisbot 
	ble.s		.update_window
*-------------------------------------------------------*
*	Column bucket generator				*
*-------------------------------------------------------*
	moveq		#0,d6
	move.w		addwall_runs(a6),d6
	lea		wallruns,a0
	move.l		d6,d0
	lsl.l		#3,d0
	add.l		d0,a0
	move.w		addwall_tex(a6),wall_id(a0)
	move.w		d7,wall_x(a0)
	move.w		column_thistop,wall_y1(a0)
	move.w		column_thisbot,wall_y2(a0)
	addq		#1,d6
	move.w		d6,addwall_runs(a6)
*-------------------------------------------------------*
*	Update vertical clipping bar			*
*-------------------------------------------------------*
.update_window:
*-------------------------------------------------------*
	move.l		column_thistop,d6
	cmp.l		column_thisminy,d6
	bgt.s		.upd
	lea		occlusion_list,a0
	move.b		#0,(a0,d7.l)
	subq.w		#1,addwall_columns(a6)
	beq.s		.stop
	lea		miny,a0
	move.w		addwall_ysize(a6),(a0,d7.l*2)
	moveq		#0,d6
.upd:	lea		maxy,a0
	move.w		d6,(a0,d7.l*2)
*-------------------------------------------------------*
*	Advance to next column				*
*-------------------------------------------------------*
.skip:	addq.l		#1,d7
	cmp.w		addwall_ci2(a6),d7
	bmi		lowerwall_loop
	bra.s		.done
*-------------------------------------------------------*
*	Premature termination				*
*-------------------------------------------------------*
.stop	addq.l		#1,d7
*-------------------------------------------------------*
*	Fill gaps left in floor & ceiling by edges	*
*-------------------------------------------------------*
.done:	cmp.l		column_lastbot,column_lastmaxy
	ble.s		.nfl
	move.l		column_lastbot,floor_y1
	move.l		column_lastmaxy,floor_y2
	move.w		addwall_fc(a6),floor_tex
	jsu		flat_rightedge
*-------------------------------------------------------*
.nfl:	move.w		addwall_runs(a6),wallruncount
	move.w		addwall_columns(a6),columns
	pop.l		a4
	pop.l		a3
	rts

*-------------------------------------------------------*
*	Generate left edges of [dy] 'flats'.		*
*-------------------------------------------------------*
flat_leftedge:
*-------------------------------------------------------*
	rept		1
	sub.l		d1,d6
	subq.l		#1,d6				; number of flat runs needed
	lea		flatruncounts,a0
	add.l		d1,a0
	add.l		d1,a0
	moveq		#0,d0
	move.w		#(flat_len*max_xint),d0
	lsl.l		#8,d1
	add.l		d1,d1				; 8+1 = 6+3 = 64*8 = flat_len*max_xint
*	mulu.w		d0,d1
	sub.l		d0,d1
	lea		flatruns,a6
	add.l		d1,a6				; flatruns+(runsize*(runs-1))
	moveq		#0,d1
.vert:	move.w		(a0)+,d1			; fetch bucket count for this row.
	add.l		d0,a6				; advance to next row in bucket buffer.
	move.w		d7,flat_x1(a6,d1.l*flat_len)	; store X1 @ (row+(count*size)).
	dbra		d6,.vert
.exit:	lea		addwall_struct,a6		; we must restore a6 after trashing it
	endr
	rtu
	
*-------------------------------------------------------*
*	Generate right edges of [dy] 'flats'.		*
*-------------------------------------------------------*
flat_rightedge:
*-------------------------------------------------------*
	rept		1
	sub.l		d1,d6
	push.l		d4
	subq.l		#1,d6				; number of flat runs needed
	lea		flatruncounts,a0 
	add.l		d1,a0
	add.l		d1,a0
	moveq		#0,d4
	move.w		#(flat_len*max_xint),d4
	lsl.l		#8,d1
	add.l		d1,d1				; 8+1 = 6+3 = 64*8 = flat_len*max_xint
*	mulu.w		d4,d1
	lea		flatruns,a6
	add.l		d1,a6
	sub.l		d4,a6				; flatruns + (runsize*(runs-1))
	swap		d0
	move.w		d7,d0				; merge X2 & texture-ID
	moveq		#0,d1
.vert:	move.w		(a0),d1				; fetch bucket count for this row.
	add.l		d4,a6				; advance to next row in bucket buffer.
	addq.w		#1,(a0)+			; increment bucket count and move on.
	move.l		d0,(a6,d1.l*flat_len)		; store texture-ID & X2 @ (row+(count*size)).
	dbra		d6,.vert
.exit:	pop.l		d4
	lea		addwall_struct,a6		; we must restore a6 after trashing it
	endr
	rtu

*-------------------------------------------------------*
			bss
*-------------------------------------------------------*

addwall_struct:		ds.b	addwall_len		; local variables for AddWall.

columns:		ds.w	1			; counter for columns done.

occlusion_list:		ds.b	320			; byte-per-column occlusion list.

maxy:			ds.w	320			; upper clipping buffer.
miny:			ds.w	320			; lower clipping buffer.

wallruncount:		ds.w	1			; counter for total wall runs.
flatruncounts:		ds.w	200			; word-per-row counters for flat runs.

flatruns:		ds.b	(200*max_xint*flat_len)	; floor buckets (rows*buckets*bucketsize).
wallruns:		ds.b	(maxwallruns*wall_len)	; wall buckets (maxwallruns*bucketsize).

*-------------------------------------------------------*
			text
*-------------------------------------------------------*

