;******************************************************************************
;            (C) Copyright 1992-1995, Radius, Inc. and Atari Corp.
; Secret and confidential                                   All rights reserved
;******************************************************************************
; This source code and any compilation or derivative thereof is the joint
; property of Radius, Inc. and Atari Corp.  This code is provided pursuant
; to a Software License Agreement and/or Software Development Contract.  This
; code is the proprietary information of Radius, Inc. and Atari Corp. and is
; confidential in nature.  Its use and dissemination by any party other than
; Atari Corp. are strictly limited by the confidential information provisions
; of the Agreement or Contract referenced above.
;******************************************************************************
; Program: player.cof	- Cinepak Player Demo
;  Module: gpustart.s	- GPU Startup Stub/Interrupts
;
; Revision History:
; 12/09/94 - Created (SDS)
; 03/30/95 - Modified for PLAYER.COF (SDS)
;******************************************************************************
; 100 31 Mar 95 SDS     Initial revision.
; 101 08 Nov 95 JPE     Official legal banner added (no other changes).
;******************************************************************************

		.include "jaguar.inc"
		.include "memory.inc"
		.include "player.inc"
		 
		.globl	gpustartup
		.globl	gpustartupx
		.globl	GSTUBSTART
		.globl	GPUOLP

		.extern	GPU_CPUINT
		.extern	GPU_OPINT

		.extern	bmpupdate
		.extern	scrbuf
		.extern runframes

		.extern	time
		.extern timeIncr

ISRSTACK	.equ	G_RAM+4096

		.68000
		.text
gpustartup:
		.gpu
		.org	G_RAM

;;;;;;;;;;;;;;;;;
;;; CPU Interrupt
;;;;;;;;;;;;;;;;;
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; DSP Interrupt (reserved for CD-BIOS)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop

;;;;;;;;;;;;;;;;;
;;; PIT Interrupt
;;;;;;;;;;;;;;;;;
		movei	#GPU_PITINT,r0
		jump	(r0)
		nop
		nop
		nop
		nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Object Processor Interrupt
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		movei	#GPU_OPINT,r0
		jump	(r0)
		nop
		nop

GPUOLP:		.dc.l	0

;;;;;;;;;;;;;;;;;;;;;
;;; Blitter Interrupt
;;;;;;;;;;;;;;;;;;;;;
		nop
		nop
		nop
		nop
		nop
		nop
		nop
		nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Procedure: GPU Startup Stub
;;;	       Set the ISR, enable interrupts, set register bank #1,
;;;            enter Cinepak code.
		
GSTUBSTART:
		movei	#ISRSTACK,r31		; Initialize interrupt stack

		movei	#G_FLAGS,r0
		movei	#G_PITENA|G_DSPENA|G_OPENA|REGPAGE,r2

		store	r2,(r0)			; Clobber G_FLAGS

		nop				; Allow time to take effect
		nop

		movei	#runframes,r0
		moveq	#0,r1
		store	r1,(r0)

		movei	#GPUOLP,r0		; Address of OLP parameter
		load	(r0),r1			; Load it

		move	r1,r2			; Swap 'em
		shrq	#16,r1
		shlq	#16,r2
		or	r2,r1

		movei	#OLP,r0
		store	r1,(r0)			; Store in OLP

		movei	#PIT0,r0		; Setup PIT to ~600 Hz
		moveq	#1,r1
		storew	r1,(r0)

		addq	#2,r0
		movei	#$568E,r1
		storew	r1,(r0)
			
		movei	#G_RAM+GPU_OFFSET,r0	; Jump to Cinepak Code
		jump	(r0)
		nop

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Interrupt: GPU Object Processor
;;;	       Increment runframes, update object list.
		
GPU_OPINT:
		movei	#G_FLAGS,r30		; Interrupt START 
		load	(r30),r29

		movei	#OBF,r0			; Store any value here
		storew	r1,(r0)			; to restart OP

		movei	#runframes,r2		; Increment Frame Counter
		load	(r2),r0
		addq	#1,r0
		store	r0,(r2)

		movei	#$7FF,r3
		movei	#GPUOLP,r4		; Address of object list pointer
		movei	#bmpupdate,r5

		movei	#(3*8),r0
		load	(r4),r8			; Object List Pointer
		add	r0,r8			; Add Bitmap Offset

		load	(r5),r2			; Get first saved bitmap long
		addq	#4,r5

		and	r3,r2			; Remove old bitmap address

		movei	#scrbuf,r0		; New screen address
		load	(r0),r1			; Get it

		shlq	#8,r1			; Make it DATA
		or	r1,r2			; Or onto old longword

		store	r2,(r8)			; Store first longword
		addq	#4,r8			; Advance to next

		load	(r5),r2			; Second longword
		store	r2,(r8)			; Restore it
		
		bclr	#3,r29			; Standard Interrupt Exit
		bset	#12,r29
		load	(r31),r28
		addq	#2,r28
		addq	#4,r31
		jump	(r28)		
		store	r29,(r30)
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Interrupt: GPU Programmable Interrupt Timer
;;;	       Add timeIncr to time.

GPU_PITINT:
		movei	#G_FLAGS,r30		; Interrupt START 
		load	(r30),r29

		movei	#time+2,r4		; This means time+2 must
		movei	#timeIncr,r5		; be long aligned.

		load	(r4),r0			; Load time+2
		load	(r5),r1			; Load timeIncr

		add	r1,r0			; Add the two
		store	r0,(r4)			; Store the result

		jr	CC,nocarry		; If no carry, exit
		nop

		subq	#2,r4			; Step back to time

		loadw	(r4),r0			; Load high 16 bits
		addq	#1,r0			; Add carry
		storew	r0,(r4)			; Store
nocarry:
		bclr	#3,r29			; Standard Interrupt Exit
		bset	#11,r29
		load	(r31),r28
		addq	#2,r28
		addq	#4,r31
		jump	(r28)		
		store	r29,(r30)
		
		.68000
gpustartupx:
		.end

		
