;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Jaguar Example Source Code
; Jaguar Workshop Series #1
; Copyright (c)1994 Atari Corp.
; ALL RIGHTS RESERVED
;
; Program: hv.cof      - Minimum time object list update
;  Module: hv_list.s   - Object List Refresh and Initialization
;
		.include        "jaguar.inc"
		.include        "hv4.inc"

		.globl		InitLister
		.globl		UpdateList

		.extern		InitMoveVars

		.extern		bra1
		.extern		bra2
		.extern		bm1
		.extern		gpu1
		.extern		stop1
		.extern		stop2
		.extern		bmp_highl
		.extern		bmp_lowl
		.extern		reflect
		.extern		count_x
		.extern		count_y
		.extern		x_motion
		.extern		y_motion
		.extern		x_pos
		.extern		y_pos
		.extern		x_min
		.extern		x_max
		.extern		y_min
		.extern		y_max
		.extern		upd_freqx
		.extern		upd_freqy
		.extern		a_hdb
		.extern		a_hde
		.extern		a_vdb
		.extern		a_vde
		.extern		width
		.extern		height

		.extern		JAGPIC
		.extern		chopper
		.extern		stillife
		.extern		image1
		.extern		image2
		.extern		image3

		.text

CopyPicture:
        movem.l d0/a0-a1, -(sp)

				lea.l JAGPIC, a0
        lea.l image1, a1
        move.w #(BMP_PHRASES*2*BMP_HEIGHT-1), d0
.loop1:
				move.l (a0)+, (a1)+
        dbra d0, .loop1

				lea.l stillife, a0
        lea.l image2, a1
        move.w #(BMP_PHRASES*2*BMP_HEIGHT-1), d0
.loop2:
				move.l (a0)+, (a1)+
        dbra d0, .loop2

				lea.l chopper, a0
        lea.l image3, a1
        move.w #(BMP_PHRASES*2*BMP_HEIGHT-1), d0
.loop3:
				move.l (a0)+, (a1)+
        dbra d0, .loop3

        movem.l (sp)+, d0/a0-a1
        rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InitLister: Initialize Object List Processor List
;
; Returns: Pre-word-swapped address of object list in d0.l
;
InitLister:
		movem.l d1-d7/a0-a6,-(sp)

		jsr CopyPicture

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Write first BRANCH object (branch if YPOS > a_vde )

		move.l	#bra1,a0
		move.l	#BRANCHOBJ,d0
		move.l	#stop1,d2
		move.w	a_vde,bra_ypo
		move.l	#O_BRLT,bra_con
		jsr			build_obj			; Build a branch object at main_obj_list

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Write second BRANCH object (branch if YPOS < a_vdb)   

		move.l	#bra2,a0
		move.l	#BRANCHOBJ,d0
		move.l	#stop1,d2
		move.w	a_vdb,bra_ypo
		move.l	#O_BRGT,bra_con
		jsr			build_obj			; Build a branch object at bra2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Write BITMAP objects (COUNT_BM times)

		move.w	#COUNT_BM-1,d1

		move.l	#bm1,a0
		move.l	#bmp_highl,a1
		move.l	#bmp_lowl,a2

loop1:
		move.l	#O_TRANS,bmp_bit
		move.l	#BMP_PHRASES,bmp_phr
		move.l	#BITOBJ,d0
		move.l	a0,d2
		add.l		#16,d2
		move.w	d1,d3
		lsl.w		#2,d3
		add.w		#200,d3
		move.w	d1,d4
		lsl.w		#2,d4
		add.w		#200,d4
		move.l	#BMP_HEIGHT,d5
		move.l	#image1,d6
		move.l	#O_DEPTH16|O_NOGAP,d7
		jsr			build_obj

		adda.l	#16,a0
		adda.l	#4,a1
		adda.l	#4,a2
		dbra		d1,loop1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Write a GPU Interrupt Object

		move.l	#gpu1,a0
		move.l	#GPUOBJ,d0
		jsr			build_obj			; Build a gpu object at gpu1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Write a STOP object at end of list

		move.l	#stop1,a0
		move.l	#STOPOBJ,d0
		jsr			build_obj			; Build a stop object at stop1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Now return swapped list pointer in D0                      

		move.l	#bra1,d0  
		swap		d0

		movem.l	(sp)+,d1-d7/a0-a6
		rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; UpdateList: Update list fields destroyed by the object processor.
;
UpdateList:
		movem.l	d0-d2/a0-a4,-(sp)

		move.w	#COUNT_BM-1,d2
		move.l	#bm1,a0
		move.l	#bmp_highl,a1
		move.l	#bmp_lowl,a2
		move.l	#x_pos,a3
		move.l	#y_pos,a4

loop2:
		move.l	(a1),(a0)				; Store low longword of phrase
;		move.l	(a2),4(a0)			; Store low longword of phrase

		move.l	(a2),d0					; Grab low longword of phrase
		andi.l	#$FFFFC007,d0		; Strip old YPOS
		clr.l		d1
		move.w	(a4),d1					; Update YPOS from internal var
		lsl.w		#3,d1						; Shift into bits 13-3
		or.w		d1,d0
		move.l	d0,4(a0)				; Store low longword of phrase 1

		move.l	12(a0),d0				; Low Phrase 2 -> d0.l
		andi.l	#$FFFFF000,d0		; Extract XPOS
		move.w	(a3),d1			    ; Grab new XPOS
		or.w		d1,d0						; store XPOS
		move.l	d0,12(a0)		    ; d0.l -> Low Phrase 2

		adda.l	#16,a0
		adda.l	#4,a1
		adda.l	#4,a2
		adda.l	#2,a3
		adda.l	#2,a4
		dbra		d2,loop2

		move.w	#$101,INT1			; Signal we're done
		move.w	#$0,INT2

		movem.l	(sp)+,d0-d2/a0-a4
		rte

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
build_obj:
		movem.l	d0-d7/a0-a3,-(sp)

;		a0=Adress of object to process
;		a1=Adress of high long of (s)bmpobj phrase 1 for later update
;		a2=Adress of low long of (s)bmpobj phrase 1 for later update
;		a3=Adress of low long of scaleobj phrase 3 for later update
;		d0=Object type (0-4) and low long of phrase 1
;		d1=High long of phrase 1
;		d2=Link adress to next object
;		d3=X-Position of bitmap (.w)
;		d4=Y-Position of bitmap (.w)
;		d5=Bitmap height in pixel
;		d6=Adress of bitmap
;		d7=Bitmap depth, pitch (O_TRANS, O_NOGAP)

		move.l	d0,obj_typ

		cmp.l		#0,d0					; Bitmap object
		beq.w		.build_bitmap
		cmp.l		#1,d0					; Scaled bitmap  object (begins like bitmap)
		beq.w		.build_bitmap
		cmp.l		#2,d0					; GPU object
		beq.w		.build_gpu
		cmp.l		#3,d0					; Branch object
		beq.w		.build_branch
		cmp.l		#4,d0					; Stop object
		beq.w		.build_stop

		jmp			.all_done

.build_bitmap:
		clr.l   d1

		jsr			format_link		; Stuff in LINK address in d0 and d1

		and.w		#$FFFE,d4			; Y-Position must be even

		lsl.w		#3,d4
		or.w		d4,d0

		lsl.l		#8,d5					; Bitmap height
		lsl.l		#6,d5
		or.l		d5,d0

		lsl.l		#8,d6					; Adress of picture
		or.l		d6,d1

		move.l	d1,(a0)+
		move.l	d1,(a1)
		move.l	d0,(a0)+
		move.l	d0,(a2)

		clr.l		d0						; Now Phrase

		or.w		d3,d0					; X-Position
		or.l		d7,d0					; Depth...

		move.l	bmp_bit,d1		; Goon with phrase 2

		move.l	bmp_phr,d4		; DWIDTH
		move.l	d4,d3

		lsl.l		#8,d4
		lsl.l		#8,d4
		lsl.l		#2,d4
		or.l		d4,d0

		lsl.l		#8,d4					; IWIDTH Bits 28-31
		lsl.l		#2,d4
		or.l		d4,d0

		lsr.l		#4,d3					; IWIDTH Bits 37-32
		or.l		d3,d1

		move.l  d1,(a0)+
		move.l  d0,(a0)+

		move.l	obj_typ,d0

		cmp.l		#1,d0					; Scaled bitmap  object
		beq.w		.build_scale

		jmp			.all_done

.build_scale:
		clr.l		(a0)+					; High long
		clr.l		d0

		move.w	scl_vsc,d0		; Vscale
		lsl.w	#8,d0
		or.w	scl_hsc,d0			; Hscale

		move.l	d0,(a0)				; Low long
		move.l	d0,(a3)

		jmp			.all_done

.build_gpu:
		clr.l		d1

		move.l	d1,(a0)+
		move.l	d0,(a0)

		jmp			.all_done

.build_branch:
		clr.l		d1

		or.l		bra_con,d0		; Branch condition

		jsr			format_link		; Stuff in LINK address in d0 and d1

		move.w	bra_ypo,d3		; YPOS of branch object
		lsl.w		#3,d3					; Make it bits 13-3
		or.w		d3,d0

		move.l	d1,(a0)+
		move.l	d0,(a0)

		jmp			.all_done

.build_stop:
		clr.l		d1

		or.l		#O_STOPINTS,d0

		move.l	d1,(a0)+
		move.l	d0,(a0)

.all_done:
		movem.l	(sp)+,d0-d7/a0-a3
		rts


format_link:
		movem.l	d2-d3,-(sp)

		andi.l	#$3FFFF8,d2		; Ensure alignment/valid address
		move.l	d2,d3

		swap		d2						; Put bits 10-3 in bits 31-24
		clr.w		d2
		lsl.l		#5,d2
		or.l		d2,d0

		lsr.l		#8,d3					; Put bits 21-11 in bits 42-32
		lsr.l		#3,d3
		or.l		d3,d1

		movem.l	(sp)+,d2-d3
		rts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Some variables
;
		.bss
		.phrase

obj_typ:		ds.l	1
bra_ypo:		ds.w	1
bra_con:		ds.l	1
bmp_bit:		ds.l	1
bmp_phr:		ds.l	1
scl_vsc:		ds.w	1
scl_hsc:		ds.w	1

		.end