;*======================================================================*
;*                TITLE:                  MAIN.S                        *
;*                Function:               68000 main routine            *
;*                                                                      *
;*                Project #:              JAGUAR                        *
;*                Programmer:             Andrew J Burgess              *
;*                                                                      *
;*              COPYRIGHT 1992 Atari Computer Corporation               *
;*          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
;*          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
;*        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
;*                            ALL RIGHTS RESERVED.                      *
;*                                                                      *
;*======================================================================*
;*
;* NOTES:
;*
;*======================================================================*

BASE		EQU	$00D00000	;* 68000 register base address
BAR_ON		EQU	1

MAXMODEL	EQU	3

	include "jaguar.inc"
	include "blit.inc"
	include "defs.inc"
	include "joydefs.inc"

;*======================================================================*
	.extern	cube		; polygon parameter block (3D Studio)
	.extern	cone		; polygon parameter block (3D Studio)
	.extern	cylinder	; polygon parameter block (3D Studio)

	.extern	param_ptr	; Pointer to shared parameter buffer
	.extern	argbuffer	; shared parameter buffer
	.extern	matbuffer	; shared parameter buffer
	.extern	imatbuffer	; shared parameter buffer
	.extern	vmatbuffer	; shared parameter buffer
	.extern	clipbuffer	; clipper information buffer
	.extern	iMatrix		; final    transform matrix
	.extern	vMatrix		; final    transform matrix
	.extern	key_level
	.extern	fire_level
	.extern	fire_edge
	.extern	joy_level

	.extern	disp_ptr	; Pointer to Display buffer
	.extern	draw_ptr	; Pointer to Build buffer

	.extern	Initialize	; system intialization routine
	.extern	WaitForSync	; Vblank Sync
	.extern	ChangeDisplay	; swap display and build pointers
	.extern	ClrDispBuf	; clear Display buffer
	.extern	ClrBuildBuf	; clear Build buffer
	.extern	GetInput	; update joystick inputs
	.extern	updPosition	; update X, Y, and Z values
	.extern	updAngles	; update roll, pitch, and yaw values
	.extern	gpuload		; load a GPU program into GPU RAM
	.extern	gpurun		; start execution of a GPU program

	.extern	xform		; GPU xform routine

;*======================================================================*
;*	USEFUL DEFINES
;*======================================================================*

LONGDATA	EQU	4		; 32 bits = 4 bytes = 1 Long
PTRSIZE		EQU	LONGDATA	; all pointers are 32 bits
COUNTSIZE	EQU	LONGDATA
VERTSIZE	EQU	(2*LONGDATA)	; 4 components X|Y|Z|I 16 bits each
BUFFERSIZE	EQU	(320*200*2)	; screen 320 X 200 in 16.16 color mode

DISPBUF1	EQU	ENDRAM-BUFFERSIZE
DISPBUF2	EQU	DISPBUF1-BUFFERSIZE

OFF68K		EQU	$900000
RAMSIZE		EQU	$1000		; 4K bytes
SEMSIZE		EQU	LONGDATA	; 1 LONG
COLRSIZE	EQU	LONGDATA	; 1 LONG 
PARAMSIZE	EQU	PTRSIZE+(2*VERTSIZE)+COLRSIZE

GPUPROG		EQU	G_RAM-OFF68K	; from the GPU's eye
INPUT6		EQU	G_ENDRAM-$4	; pointer to parameter 6 for GPU
INPUT5		EQU	INPUT6-$4	; pointer to parameter 5 for GPU
INPUT4		EQU	INPUT5-$4	; pointer to parameter 4 for GPU
INPUT3		EQU	INPUT4-$4	; pointer to parameter 3 for GPU
INPUT2		EQU	INPUT3-$4	; pointer to parameter 2 for GPU
INPUT1		EQU	INPUT2-$4	; pointer to parameter 1 for GPU

.macro	LONGALIGN	addr
	addq.l	#3,\addr		; make sure the address will remain
					; within the buffer area
	andi.l	#$FFFFFFFC,\addr
.endm

;*======================================================================*
;*	PROGRAM SEGMENT
;*======================================================================*

	.text

;*======================================================================*
;* main()	- main loop program
;*
;*======================================================================*

main:
	clr.b	doneFlag	;* Terminate = FALSE
	clr.b	modelFlag	;* Model     = DEFAULT (CUBE)
	jsr	Initialize	; initialize the system

;	jsr	WaitForSync	;* wait for video sync

	;*==============================================================*
	;* read the joystick input and adjust the appropriate angle values
	;*==============================================================*

loop:
	TIMEBAR	RGB_CYAN

	jsr	WaitForSync	;* wait for video sync

	TIMEBAR	RGB_BLUE

	move.l	draw_ptr,a0
	jsr	ClrBuildBuf	;* clear the build buffer

	TBCOLR	RGB_VIOLET
	TIMEBAR	RGB_VIOLET

	jsr	GetInput	;* read joystick inputs
	jsr	ProcessInput	;* set appropriate data

	TBCOLR	RGB_RED
 	TIMEBAR	RGB_RED

	jsr	Render		;* render polygon data

	TIMEBAR	RGB_BLACK

 	jsr	ChangeDisplay	;* swap build and display pointers

	tst.b	doneFlag
	bne	stop

	jmp	loop

;*======================================================================*

stop:
	TIMEBAR	RGB_BLACK

	illegal
	nop

;*======================================================================*
;* ProcessInput()	- process the user input and setup approiate
;*				variables
;*
;*	input:
;*
;*	preserved:
;*		none
;*======================================================================*

ProcessInput:

	lea	key_level,a0
	move.w	(a0),d0		;* get keypad of CONTROL #1

	btst	#KEY_0,d0
	beq	.ck_viewer
	move.b	#1,doneFlag

.ck_viewer:
	clr.l	d1
	lea	fire_edge,a0
	move.b	(a0),d1		;* get firebuttons edge of CONTROL #1

	btst	#FIRE_C,d1
	beq	.model
	add.b	#1,modelFlag
	cmpi.b	#MAXMODEL,modelFlag
	bne 	.model
	clr.b	modelFlag

.model:
	clr.l	d1
	lea	fire_level,a0
	move.b	(a0),d1		;* get firebuttons of CONTROL #1

	clr.l	d2
	lea	joy_level,a0
	move.b	(a0),d2		;* get joypad of CONTROL #1

	jsr	updPosition	;* adjust position
	jsr	updAngles	;* adjust roll,pitch,yaw

	rts

;*======================================================================*
;* Render()	- process the user input and setup approiate
;*				variables
;*
;*	input:
;*
;*	preserved:
;*		none
;*======================================================================*

Render:

	;*==============================================================*
	;* Copy the MODEL to an INSTANCE for POLYDRAW
	;*==============================================================*

	move.l	#argbuffer,param_ptr
	LONGALIGN param_ptr

.model0:			; JAG Model Format
				;	Zmin  | #Verts
				;	#Segs | #Faces
				;	Segment Ptr
				;	Vertex Ptr
				;	FACE Data ...
				;	SEGMENT Data ...
				;	VERTEX Data ...
	cmpi.b	#0,modelFlag
	bne	.model1

	move.l	#cube,a0	; A0 = Ptr to UNAligned contiguous MODEL data  (3DS)
	bra	modelparam

.model1:
	cmpi.b	#1,modelFlag
	bne	.model2

	move.l	#cone,a0	; A0 = Ptr to UNAligned contiguous MODEL data  (3DS)
	bra	modelparam

.model2:
	cmpi.b	#2,modelFlag
	bne	.model3

	move.l	#cylinder,a0	; A0 = Ptr to UNAligned contiguous MODEL data  (3DS)
	bra	modelparam

.model3:

modelparam:
	move.l	param_ptr,a1	; A1 = Ptr to Aligned data
	move.l	(a0)+,d2
	move.l	d2,(a1)+
	and.l	#$0ffff,d2	; D2 = Number of Vertices
	move.l	(a0)+,(a1)+
	move.l	a1,a2		; A2 = Ptr to Ptr area
	addq.l	#8,a1
	move.l	(a0)+,d0	; D0 = Ptr to UNAligned Segments
	move.l	(a0)+,d1	; D1 = Ptr to UNAligned Vertices
.faclp:
	move.w	(a0)+,(a1)+	; Copy FACEs to Aligned RAM
	cmp.l	a0,d0
	bne	.faclp

	move.l	a1,(a2)+	; Save Segment ptr
.seglp:
	move.l	(a0)+,(a1)+	; Copy SEGMENTs to Aligned RAM
	cmp.l	a0,d1
	bne	.seglp

	move.l	a1,(a2)+	; Save Vertex ptr
	move	d2,d0
	asl	#1,d2
	add	d0,d2		; 3 longs/vertex. So triple the count.
	subq	#1,d2		; WARNING: This will break on really large numbers of verts (>12K)
				; I'm not concerned since our vertex limit is at most 8000.
.vrtlp:	move.l	(a0)+,(a1)+
	dbra	d2,.vrtlp	; Copy the Vertex data to an aligned RAM area

	;*==============================================================*

	move.l	param_ptr,d0
	swap	d0		; GPU and 68000 read addresses swapped
	move.l	d0,INPUT1	; tell GPU where to find parameters

	;*==============================================================*
	;* Copy the transform MATRICES
	;*==============================================================*

		;*======================================================*
		;* VIEWER transform matrix
		;*======================================================*

	move.l	#vmatbuffer,param_ptr	;* VIEWER transform matrix
	LONGALIGN param_ptr
	move.l	#vMatrix,a0		;* A0 = unaligned transform matrix

	move.l	param_ptr,a1
	moveq	#11,d0
.matlp:
	move.l	(a0)+,d1
	move.w	d1,(a1)+		; **KLUDGE** Convert to WORD Format
	dbra	d0,.matlp

	move.l	param_ptr,d0
	swap	d0		; GPU and 68000 read addresses swapped
	move.l	d0,INPUT2	; tell GPU where to find parameters

		;*======================================================*
		;* INSTANCE transform matrix
		;*======================================================*

	move.l	#imatbuffer,param_ptr
	LONGALIGN param_ptr

	move.l	#iMatrix,a0		;* A0 = unaligned transform matrix

	move.l	param_ptr,a1
	moveq	#11,d0
.matlp1:
	move.l	(a0)+,d1
	move.w	d1,(a1)+		; **KLUDGE** Convert to WORD Format
	dbra	d0,.matlp1

	move.l	param_ptr,d0
	swap	d0		; GPU and 68000 read addresses swapped
	move.l	d0,INPUT6	; tell GPU where to find parameters

	;*==============================================================*
	;* Copy the LITEMODEL
	;*==============================================================*

	move.l	#liteModel,d0
	swap	d0
	move.l	d0,INPUT3

	;*==============================================================*
	;* Copy the CLIPBUFFER
	;*==============================================================*

	move.l	#clipbuffer,d0	; BYTE Aligned data
	swap	d0		; GPU and 68000 read addresses swapped
	move.l	d0,INPUT4	; tell GPU where to find parameters

	;*==============================================================*
	;* Copy the DRAWBUFFER
	;*==============================================================*

	move.l	draw_ptr,d0
	swap	d0		; GPU and 68000 read addresses swapped
	move.l	d0,INPUT5	; tell GPU where to find parameters

	lea	xform,a0	; get base address of GPU code
 	lea	G_RAM,a1	; get GPU program base addr

	jsr	gpuload		; load the GPU program
	jsr	gpurun		; run the GPU program

	;*==============================================================*

wait1_gpu:			; wait for GPU to finish
	move.l	#SEMAPHORE,a0
	move.l	(a0),d0
	beq	wait1_gpu
	;*==============================================================*

rdone:

	rts

;*======================================================================*
;*	END OF PROGRAM SEGMENT
;*======================================================================*

	.bss

	.even

doneFlag:
	ds.b	1		; termination flag

modelFlag:
	ds.b	1		;* Which model to display
				;*	0 = DEFAULT (CUBE)
				;*	1 = COMPLEX

;*======================================================================*

	.data

	.even

liteModel:
	.dc.w	$40		;* Ambient:	Intensity
	.dc.w	$80FF		;* InScene:	Intensity
	.dc.w	$e000		;*		Vector	X component
	.dc.w	$0000		;*			Y
	.dc.w	$0000		;*			Z
	.dc.w	$FF		;* Sunlight:	Intensity
	.dc.w	$0000		;*		Vector	X component
	.dc.w	$4000		;*			Y
	.dc.w	$0000		;*			Z
	.dc.w	$0000		;* InScene:	(0000 = End of list)

;*======================================================================*

	END

;*======================================================================*
;*                                 EOF                                  *
;*;*=====================================================================*
;
