;*======================================================================*
;*                TITLE:    VIDEO.S                                     *
;*                Function: Video and Object Processor Routines         *
;*                                                                      *
;*                Project #:              JAGUAR                        *
;*                                                                      *
;*                Programmer:             Leonard Tramiel               *
;*                                        Andrew J Burgess              *
;*                                        Rob Zdybel                    *
;*                                                                      *
;*              COPYRIGHT 1992,1993 Atari U.S. Corporation              *
;*          UNATHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION,         *
;*          PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR          *
;*        THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED.       *
;*                            ALL RIGHTS RESERVED.                      *
;*                                                                      *
;*======================================================================*

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

	.include	"jaguar.inc"

;
;	PUBLIC SYMBOLS
;
	.globl	make_olist
	.globl	vblank
	.globl	vidinit
	.globl	waitsync

	.globl	framecnt


;
;	EXTERNAL SYMBOLS
;
	.extern	disp_ptr
	.extern	DISPBUF1


;
;	LOCAL EQUATES
;
PHRASE		EQU	8
SCRNADDR	EQU	PHRASE
OBJSIZE		EQU	5*2

;
;	VIDEO DEFINES
;
vclk		EQU	834
ivclk		EQU	(vclk*3)/2

horiz_per	EQU	317778
sync_per	EQU	46050
eq_per		EQU	23500
front_porch	EQU	17450
line_blank	EQU	109500
disp_width	EQU	320	;this is in pixels
disp_height	EQU	200	;this is in lines

; Horizontal computations

n_hp		EQU	horiz_per/ivclk
n_hbb		EQU	((horiz_per-sync_per-front_porch)/ivclk)+$400
n_hbe		EQU	(line_blank-sync_per-front_porch)/ivclk
n_hs		EQU	((horiz_per-sync_per)/ivclk)+$400
n_hvs		EQU	(horiz_per-(2*sync_per))/ivclk
n_heq		EQU	(horiz_per-eq_per)/ivclk
n_hde		EQU	((disp_width/2)-1)+$400
n_hdb1		EQU	((n_hp)-(disp_width/2))
n_hdb2		EQU	n_hdb1

n_vmode		EQU	$c1

; Vertical

n_vp		EQU	523
n_vee		EQU	6
n_vbe		EQU	40
n_vdb		EQU	n_vbe+26
n_vde		EQU	n_vdb+(disp_height*2)
n_vbb		EQU	n_vde+40
n_vs		EQU	n_vp-10
n_veb		EQU	n_vs-n_vee

;
;	SUBROUTINE AREA
;

;
;	VIDINIT   Initialize Video to 320x200 NTSC
;
;	Given:
;		Control
;
;	Returns:
;		Video Disabled, but ready for 320x200 NTSC
;
;	Register Usage:
;		None
;
;	Externals:
;		None
;
vidinit:
	move.w	#0,VMODE	; Stop the Video (I want to get off)

	move.w	#n_hp,HP
	move.w	#n_hbb,HBB
	move.w	#n_hbe,HBE
	move.w	#n_hs,HS
	move.w	#n_hvs,HVS
	move.w	#n_heq,HEQ
	move.w	#n_hde,HDE
	move.w	#n_hdb1,HDB1
	move.w	#n_hdb2,HDB2

	move.w	#n_vp,VP
	move.w	#n_vee,VEE
	move.w	#n_vbe,VBE
	move.w	#n_vdb,VDB
	move.w	#n_vde,VDE
	move.w	#n_vbb,VBB
	move.w	#n_veb,VEB
	move.w	#n_vs,VS

	move.w	#0,ODP		; Clear any garbage address bits

	move.w	#$0,BG		; Also set up some default colors 
	move.l	#$0,BORD1

	rts


;
;	VBLANK   Vertical Sync Interrupt Handler
;
;	Given:
;		Control
;
;	Returns:
;		Object List restored for next frame
;
;	Register Usage:
;		All Registers Preserved
;
;	Externals:
;		framecnt, disp_ptr, olist_ptr
;
vblank:
	movem.l	d0-d1/a0-a1,-(sp)

	move.l	olist_ptr,a0
	move.l	#OBJSIZE-1,d1
	lea	olist,a1
.cpylp:	move.l	(a1)+,(a0)+	; Copy Object list to display space
	dbra	d1,.cpylp
				
	move.l	disp_ptr,d0	; D0 = Current display buffer
	lsr.l	#3,d0		; long align
	lsl.l	#6,d0
	lsl.l	#6,d0		; pack into upper five nybbles
	move.l	olist_ptr,a0
	move.l	SCRNADDR(a0),d1
	and.l	#$0000003F,d1	; d1 = Upper 3 nybbles of Link Field
	or.l	d1,d0
	move.l	d0,SCRNADDR(a0)	; Point Object Processor at the display buffer

	addq.l	#1,framecnt	; Count a video frame

	move.w	#$101,INT1
	move.w	#0,INT2

	movem.l	(sp)+,d0-d1/a0-a1
	rte


;
;	MAKE_OLIST   Build Object-List for 320x200 bitmap object
;
;	Given:
;		Control
;
;	Returns:
;		OLIST = Master Object List
;		OLIST_PTR = Ptr to a displayable Object List
;
;	Register Usage:
;		All Registers Preserved
;
;	Externals:
;		None
;
make_olist:
	movem.l	d0-d2/a0-a1,-(sp)
;
; At this point I will set up an object list containing
; a Branch object, a Scaled Bit map object and a Stop object.
;
	move	#OBJSIZE-1,d1
	lea	olist_data,a1
	lea	olist,a0
.ocopy:	move.l	(a1)+,(a0)+	; Copy Raw Object list to Master Olist
	dbra	d1,.ocopy
;
; The address of ObjectList should be (a multiple of 32) - 8
; so the first scaled bit mapped object starts at a multiple of 32
;
	move.l	#olist_ram,d0
	add.l	#40,d0
	and.l	#$ffffffe0,d0
	subq.l	#8,d0		; Adjust ptr to 4*Phrase - Phrase Boundary
	move.l	d0,olist_ptr	; OLIST_PTR = Ptr to Displayable Object List
	add.l	#32,d0		; d0 = Ptr to Stop Object
	lsr.l	#3,d0
	move.l	d0,d1
	ror.l	#8,d0
	and.l	#$ff000000,d0
	lsr.l	#8,d1
	and.l	#$0fff,d1	; Split for Hardware
	lea	olist,a0	; point to olist once again
	move.l	4(a0),d2
	or.l	d0,d2
	move.l	d2,4(a0)
	move.l	d1,(a0)		; Patch-Up Branch Object
	or.l	d0,12(a0)
	move.l	#DISPBUF1,d0
	lsr.l	#3,d0
	lsl.l	#6,d0
	lsl.l	#6,d0
	or.l	d0,d1
 	move.l	d1,8(a0)	; Patch-Up Bitmap Object

	move	#OBJSIZE-1,d1
	move.l	olist_ptr,a0
	lea	olist,a1
.cpylp:	move.l	(a1)+,(a0)+	; Copy Object list to display space
	dbra	d1,.cpylp

	move.l	olist_ptr,d0
	swap	d0
	move.l	d0,OLP		; Point to finished Object List

	movem.l	(sp)+,d0-d2/a0-a1
	rts


;
;	WAITSYNC   Wait for VSYNC Interrupt
;
;	Given:
;		Control
;
;	Returns:
;		Nothing
;
;	Register Usage:
;		All Registers Preserved
;
;	Externals:
;		None
;
waitsync:
	move.l	d0,-(sp)

	move.l	framecnt,d0
.wait:	cmp.l	framecnt,d0
	beq	.wait

	move.l	(sp)+,d0
	rts


;
;	VARIABLE RAM
;
	.bss
	.even

framecnt:			; Count of Video Frames
	ds.l	1

olist_ptr:			; Ptr to Active Mungable ObjList
	.ds.l	1

olist_ram:			; Storage for Mungable ObjList
	.ds.l	OBJSIZE+10	; Extra room for alignment

olist:				; Storage for Master ObjList
	.ds.l	OBJSIZE


;
;	CONSTANT DATA
;
	.data
	.even

olist_data:			; Prepackaged Object List
	.dc.l	$00000000 	; Branch Object		d63-d32
	.dc.l	$00008E73	; 			d31-d00

	.dc.l	$00000000	; Scaled BitMap Object	d63-d32
	.dc.l	$00320211	;			d31-d00
	.dc.l	$00000005	;	phrase 2	d63-d32
	.dc.l	$0140c000	;			d31-d00
	.dc.l	$00000000	;	phrase 3	d63-d32
	.dc.l	$00002020	;			d31-d00

	.dc.l	$00000000	; Stop Object		d63-d32
	.dc.l	$00000004	;			d31-d00


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