;************************************************************************
;* TITLE	: CDG.S							*
;* Function	: Initialize CD-G playerand other routines		*
;*									*
;* Project #	: JAGUAR CD+G						*
;* Modified	: Pradip K Fatehpuria	07/07/94			*
;*									*
;* COPYRIGHT(c) 1992,1993 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.							*
;************************************************************************

	.title	"CDG.S - CD+G related routines"

;*======================================================================*
;* HEADER FILES								*
;*======================================================================*

	.include 'jaguar.inc'
	.include 'blitter.inc'
	.include 'objlist.inc'
	.include 'defs.inc'
	.include 'pack.inc'

;*======================================================================*
;* EXTERNAL ROUTINE							*
;*======================================================================*

	.extern	blitidle

	.extern	initproc

;*======================================================================*
;* EXTERNAL DATA							*
;*======================================================================*

	.extern	objData
	.extern	bldobflg

	.extern	tvPH
	.extern	tvPV
	.extern	tvCOPH
	.extern	tvCOPV

	.extern	lnPH
	.extern	lnPV
	.extern	lnCOPH
	.extern	lnCOPV

	.extern	ScrlType
	.extern	ScrlColr

;*======================================================================*
;* PUBLIC ROUTINES							*
;*======================================================================*

	.globl	initapp

	.globl	settvgrf
	.globl	setlngrf

	.globl	clrtvgrf
	.globl	clrlngrf

	.globl	bltfnt08
	.globl	cp2tvdsp
	.globl	updtvgrf

	.globl	bltfnt16
	.globl	cp2lndsp
	.globl	updlngrf

;*======================================================================*
;* PUBLIC DATA								*
;*======================================================================*

	.globl	tvdspmem

	.globl	lndspmem

	.globl	fontdata

	.globl	TvChnlNo

;************************************************************************
;* SUBROUTINE AREA							*
;************************************************************************

	.text

;*======================================================================*
;* INITAPP	: initialise application parameters			*
;*======================================================================*

initapp:
	move.w	#0,TvChnlNo		; channel number zero to be displayed
	bsr	initCDG			; initialise the CDG player
.ret:	rts

;*======================================================================*
;* INITCDG	: initialise a CDG track player				*
;* INPUT	: d0.w = TV Channel number to be viewed			*
;*======================================================================*

initCDG:
	bsr	initproc		; initialise CD+G processing parameters

.iniclut:
	move.l	#CLUT,a0		; CLUT address
	move.l	#255,d0			; total of 256 entries
	move.w	#$07C0,d1		; make them all BLUE
.iniloop:
	move.w	d1,(a0)+		; initialise color
	dbra	d0,.iniloop		; loop back for all 256 entries

.iniptrs:
	move.l	#tvgrfmm1,tvgrfmem	; init ptr to TV graphics memory
	move.l	#tvgrfmm2,tvotherm	; init ptr to alternate TV graphics memory

	move.l	#lngrfmm1,lngrfmem	; init ptr to LINE graphics memory
	move.l	#lngrfmm2,lnotherm	; init ptr to alternate LINE graphics memory

.clrscrs:
	move.w	#$0101,d1		; set the color to BLUE
	bsr	clrtvdsp		; clear TV-Graphics Display memory
	bsr	clrtvgrf		; clear TV-Graphics memory

	move.w	#$07C0,d1		; set the color to BLUE
	bsr	clrlndsp		; clear LINE-Graphics Display memory
	bsr	clrlngrf		; clear LINE-Graphics memory

.setobjs:
	move.w	#FALSE,d0		; delete objects from objects list
	bsr	settvgrf		;   the TV graphics object
	bsr	setlngrf		;   the LINE graphics object
	move.w	#TRUE,bldobflg		; re-build the object list

.ret:	rts

;************************************************************************
;* ROUTNES TO MANIPULATE OBJECT LISTS					*
;************************************************************************

;*======================================================================*
;* SETTVGRF	: enable/disable TV-graphics				*
;*======================================================================*

settvgrf:
	lea.l	objData+OBJSIZE*1,a0	; pointer to SCREEN Object
	tst.w	d0			; test parameter
	beq.s	.noobj
.stobj:	andi.b	#(~DELETE_OBJ),O_TYPE(a0)
	rts
.noobj:	ori.b	#(DELETE_OBJ),O_TYPE(a0)
	rts

;*======================================================================*
;* SETLNGRF	: enable/disable line graphics				*
;*======================================================================*

setlngrf:
	lea.l	objData+OBJSIZE*2,a0	; pointer to SCREEN Object
	tst.w	d0			; test parameter
	beq.s	.noobj
.stobj:	andi.b	#(~DELETE_OBJ),O_TYPE(a0)
	rts
.noobj:	ori.b	#(DELETE_OBJ),O_TYPE(a0)
	rts

;************************************************************************
;* DIFFERENT OBJECT SCREEN CLEARING ROUTINES				*
;************************************************************************

;*======================================================================*
;* CLRTVDSP	: clear the display memory for TV Graphics		*
;* INPUT	: d1.w = color to be displayed (0c0c)			*
;*======================================================================*

clrtvdsp:
	bsr	blitidle		; wait for blitter idle

	move.w	d1,B_PATD		; select the color
	move.w	d1,B_PATD+2
	move.w	d1,B_PATD+4
	move.w	d1,B_PATD+6

	move.l	#tvdspmem,A1_BASE	; point to the buffer
	move.l	#0,A1_PIXEL		; pointer to (0,0)
	move.l	#$0001FEC0,A1_STEP	; step y = 1, x = -320
	move.l	#((192<<16)|(320)),B_COUNT ; do h = 192, w = 320
	move.l	#(PITCH1|PIXEL8|WID320|XADDPHR),A1_FLAGS ; flags

	move.l	#(PATDSEL|UPDA1),B_CMD	; start the BLTTER
.ret:	rts

;*======================================================================*
;* CLRTVGRF	: clear the graphic memory for TV-Graphics		*
;* INPUT	: d1.w = color to be displayed (0c0c)			*
;*======================================================================*

clrtvgrf:
	bsr	blitidle		; wait for blitter idle

	move.w	d1,B_PATD		; select the color
	move.w	d1,B_PATD+2
	move.w	d1,B_PATD+4
	move.w	d1,B_PATD+6

	move.l	tvgrfmem,A1_BASE	; point to the buffer
	move.l	#0,A1_PIXEL		; pointer to (0,0)
	move.l	#$0001FEC0,A1_STEP	; step y = 1, x = -320
	move.l	#((240<<16)|(320)),B_COUNT ; do h = 240, w = 320
	move.l	#(PITCH1|PIXEL8|XADDPHR|WID320),A1_FLAGS ; flags

	move.l	#(PATDSEL|UPDA1),B_CMD	; start the BLTTER
.ret:	rts

;*======================================================================*
;* CLRLNDSP	: clear the display memory for LINE-Graphics		*
;* INPUT	: d1.w = color to be displayed (cccc)			*
;*======================================================================*

clrlndsp:
	bsr	blitidle		; wait for blitter idle

	move.w	d1,B_PATD		; select the color
	move.w	d1,B_PATD+2
	move.w	d1,B_PATD+4
	move.w	d1,B_PATD+6

	move.l	#lndspmem,A1_BASE	; point to the buffer
	move.l	#0,A1_PIXEL		; pointer to (0,0)
	move.l	#$0001FEC0,A1_STEP	; step y = 1, x = -320
	move.l	#((24<<16)|(320)),B_COUNT ; do h = 240, w = 320
	move.l	#(PITCH1|PIXEL16|XADDPHR|WID320),A1_FLAGS ; flags

	move.l	#(PATDSEL|UPDA1),B_CMD	; start the BLTTER
.ret:	rts

;*======================================================================*
;* CLRLNGRF	: clear the graphic memory for LINE-Graphics		*
;* INPUT	: d1.w = color to be displayed (cccc)			*
;*======================================================================*

clrlngrf:
	bsr	blitidle		; wait for blitter idle

	move.w	d1,B_PATD		; select the color
	move.w	d1,B_PATD+2
	move.w	d1,B_PATD+4
	move.w	d1,B_PATD+6

	move.l	lngrfmem,A1_BASE	; point to the buffer
	move.l	#0,A1_PIXEL		; pointer to (0,0)
	move.l	#$0001FEC0,A1_STEP	; step y = 1, x = -320
	move.l	#((72<<16)|(320)),B_COUNT ; do h = 240, w = 320
	move.l	#(PITCH1|PIXEL16|XADDPHR|WID320),A1_FLAGS ; flags

	move.l	#(PATDSEL|UPDA1),B_CMD	; start the BLTTER
.ret:	rts

;************************************************************************
;* ROUTINES FOR BLITTING TV-GRAPHICS					*
;************************************************************************

;*======================================================================*
;* bltfnt08(x, y)							*
;* INPUT :	d2.l = replace/xor/or					*
;*		d3.w = x position					*
;*		d4.w = y position					*
;*									*
;* Blit a font with 8 bits per pixel to TV-Graf Memory at (x,y)		*
;*======================================================================*

;************************
.if 0
;************************

bltfnt08:
	bsr	blitidle		; wait for blitter idle

	mulu	#$6,d3			; calculate x position in pixel
	addi.w	#$6,d3			; add extra 6 bit offset on left to keep scope for scrolling with copy

	mulu	#$C,d4			; calculate y position in pixel
	addi.w	#$C,d4			; add extra 12 bit offset on top to keep scope for scrolling with copy

	move.w	d4,d0			; y position
	swap	d0			; set the destination pixel pointer 
	move.w	d3,d0			; must be y|x (save x position in d3)
	move.l	d0,A1_PIXEL		; offset into draw buffer
	move.l	#$0001FFFA,A1_STEP	; step increment y = 1, x = -6

	move.l	#0,A2_PIXEL		; source is always from 0,0
	move.l	#$0001FFFA,A2_STEP	; step increment y = 1, x = -6

	move.l	#((12<<16)|(6)),B_COUNT	; outer/inner loop counters, h = 12, w = 6

	move.l	#(PITCH1|PIXEL8|WID320|XADDPIX),A1_FLAGS ; setup the source and
	move.l	#(PITCH1|PIXEL8|WID8|XADDPIX),A2_FLAGS	 ; destination flags

	move.l	tvgrfmem,A1_BASE	; pointer to destination buffer
	move.l	#fontdata,A2_BASE	; pointer to character data

.bcmd:	or.l	#(SRCEN|UPDA1|UPDA2|DSTEN|BUSHI),d2
	move.l	d2,B_CMD		; set up the blitter commands
	rts

;************************
.else
;************************

bltfnt08:
	bsr	blitidle		; wait for blitter idle

	mulu	#$6,d3			; calculate x position in pixel
	addi.w	#$6,d3			; add extra 6 bit offset on left to keep scope for scrolling with copy

	mulu	#$C,d4			; calculate y position in pixel
	addi.w	#$C,d4			; add extra 12 bit offset on top to keep scope for scrolling with copy

.a1pix:
	move.w	d4,d0			; y position
	swap	d0			; set the destination pixel pointer 
	move.w	d3,d0			; must be y|x (save x position in d3)
	move.l	d0,A1_PIXEL		; offset into draw buffer

	move.l	#((1<<16)|(6)),d1	; step increment y = 1, x = (-6 + delta)
	add.w	d1,d0			; d0 = end pixel in blit
	andi.w	#$7,d0			; check if end pixel on phrase boundary
	beq.s	.a1step			; yes, set step increment
	addi.w	#8,d1			; now add an offset of (8-d0) to the end pixel,
	sub.w	d0,d1			;   so that it reaches the phrase boundary
.a1step:
	neg.w	d1
	move.l	d1,A1_STEP		; step increment y = 1, x = -6+delta

.a2pix:
	move.l	#0,A2_PIXEL		; source is always from 0,0
	cmp.w	#2,d0
	beq.s	.a2step2
	cmp.w	#4,d0
	beq.s	.a2step2
.a2step1:
	move.l	#$0001FFF8,A2_STEP	; step increment y = 1, x = -6+delta(-2) = -8
	bra.s	.bcount
.a2step2:
	move.l	#$0001FFF0,A2_STEP	; step increment y = 1, x = -6+delta(-10) = -16

.bcount:
	move.l	#((12<<16)|(6)),B_COUNT	; inner/outer loop counters

.aflags:
	move.l	#(PITCH1|PIXEL8|WID320|XADDPHR),A1_FLAGS ; source flags
	move.l	#(PITCH1|PIXEL8|WID8|XADDPHR),A2_FLAGS	 ; destination flags

.abases:
	move.l	tvgrfmem,A1_BASE	; pointer to destination buffer
	move.l	#fontdata,A2_BASE	; pointer to character data

.bcmd:	or.l	#(SRCEN|UPDA1|UPDA2|DSTEN|BUSHI),d2
	move.l	d2,B_CMD		; set up the blitter commands
	rts

;************************
.endif
;************************

;*======================================================================*
;* cp2tvdsp	: Copies the graphics memory to display memory when a	*
;*		  update of graphics memory occurs			*
;*======================================================================*

cp2tvdsp:

;****************************************
;* UPDATE DISPLAY FROM GRAPHICS MEMORY -
;*
;* copy the graphic memory to the display
;* memory depending upon (tvPH, tvPV) and
;* (tvCOPH, TVCOPV) starting from FONT
;* at position (1,1)
;*
;* Also, there is an extra one-font 
;* border around TV-graphics memory, 
;* which is used for Scrolling with COPY
;*
;****************************************

	bsr	blitidle		; wait for blitter idle

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),d2
.a1pix:
	move.l	#0,A1_PIXEL		; initialise the destination pixel pointer
.a1step:
	move.l	#$0001FEE0,A1_STEP	; step increment : y = 1, x = -288

.a2pix:
	move.w	#24,d0			; initialise the source pixel pointer
	add.w	tvPV,d0
	sub.w	tvCOPV,d0
	swap	d0
	move.w	#12,d0
	add.w	tvPH,d0
	sub.w	tvCOPH,d0
	move.l	d0,A2_PIXEL
	move.w	d0,d3			; d3 = save source starting x

	move.l	#((1<<16)|(288)),d1	; y = 1, x = -(288 + delta)
	add.w	d1,d0			; d0 = end pixel in blit
	andi.w	#$7,d0			; check if end pixel on phrase boundary
	beq.s	.a2flag			; yes, set step increment
	addi.w	#8,d1			; now add an offset of (8-d0) to the end pixel,
	sub.w	d0,d1			;   so that it reaches the phrase boundary
.a2flag:
	and.w	#$7,d3			; check if starts from a phrase boundary
	beq.s	.a2step			; yes, then no need for two source reads
	or.l	#SRCENX,d2		; the command flags for phrase boundary
.a2step:
	neg.w	d1			; x step value
	move.l	d1,A2_STEP		; step for A2 1 = +1 y|-288 x

.bcount:
	move.l	#((192<<16)|(288)),B_COUNT ; height|width of playfield

.aflags:
	move.l	#(PITCH1|PIXEL8|WID320|XADDPHR),A1_FLAGS ; source flags
	move.l	#(PITCH1|PIXEL8|WID320|XADDPHR),A2_FLAGS ; destination flags

.abases:
	move.l	#tvdspmem,A1_BASE	; base address of destination buffer
	move.l	tvgrfmem,A2_BASE	; base address of character data

.bcmd:	move.l	d2,B_CMD		; set up the blitter commands

.ret:	rts

;*======================================================================*
;* updtvgrf	: updates the graphics memory for commands like, screen	*
;*		  update with preset/copy				*
;*======================================================================*

updtvgrf:

;****************************************
;* SCROLL GRAPHICS MEMORY, IF NECESSARY
;*
;* in this case copy the bit-blit from
;* TV-graphics memory left/right and
;* up/down according to scroll with
;* preset or copy instruction
;*
;* arrange source/destination pixel
;* pointers as well as the blitter
;* flags so that the overlapping
;* memory area problem is taken
;* care of
;****************************************

	move.w	tvCOPH,d0		; check if either of COPH or COPV is set
	or.w	tvCOPV,d0
	beq	.ret			; quit

	bsr	blitidle		; wait for blitter idle

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),d2
.a1pix:
	move.w	#12,d0
	add.w	tvCOPV,d0		; destination y
	swap	d0
	move.w	#6,d0
	add.w	tvCOPH,d0		; destination x
	move.l	d0,A1_PIXEL		; prepare the destination pixel pointer
	move.w	d0,d3			; d3 = save x position

	move.l	#((1<<16)|(300)),d1	; step y = 1, x = -(300 + delta)
	add.w	d1,d0			; end pixel in blit
	andi.w	#$7,d0			; check if end pixel on phrase boundary
	beq.s	.a1step			; yes, set step increment
	addi.w	#8,d1			; now add an offset of (8-d0) to the end pixel,
	sub.w	d0,d1			;   so that it reaches the phrase boundary
.a1step:
	neg.w	d1
	move.l	d1,A1_STEP		; setup the destination step increment

.a2pix:
	move.l	#((12<<16)|(6)),A2_PIXEL ; source y = 12, x = 6
	cmp.w	#$6,d3			; are the starting x position same
	beq.s	.a2step			; no, then no need to make two source reads
	or.l	#SRCENX,d2		; the command flags for phrase boundary
.a2step:
	move.l	#$0001FECE,A2_STEP	; step increment : y = 1, x = -306

.bcount:
	move.l	#((216<<16)|(300)),B_COUNT ; inner/outer loop counters

.aflags:
	move.l	#(PITCH1|PIXEL8|WID320|XADDPHR),A1_FLAGS ; setup the source flags
	move.l	#(PITCH1|PIXEL8|WID320|XADDPHR),A2_FLAGS ; setup the destination flags

.abases:
	move.l	tvotherm,A1_BASE	; base adress of destination buffer
	move.l	tvgrfmem,A2_BASE	; base of address of source buffer

.bcmd:	move.l	d2,B_CMD		; let blitter go

;****************************************
;* SWAP TV graphics memory with it's
;* alternater memory buffer
;****************************************

.swaptvg:
	move.l	tvgrfmem,d0
	move.l	tvotherm,d1

	move.l	d0,tvotherm
	move.l	d1,tvgrfmem

;****************************************
;* PRESET/COPY the border according to
;* scroll instruction
;****************************************

.hz:	move.w	tvCOPH,d0
	beq.s	.vt
	bmi.s	.hzneg
.hzpos:	move.l	#((0<<16)|(6)),d1	; destination (y|x)
	move.l	#((0<<16)|(306)),d2	; source (y|x)
	bra.s	.chblt
.hzneg:	move.l	#((0<<16)|(300)),d1	; destination (y|x)
	move.l	#((0<<16)|(0)),d2	; source (y|x)
.chblt:	move.l	#((240<<16)|(6)),d3	; (height|width)
	bsr	blttvgrf

.vt:	move.w	tvCOPV,d0
	beq.s	.ret
	bmi.s	.vtneg
.vtpos:	move.l	#((12<<16)|(0)),d1	; destination (y|x)
	move.l	#((228<<16)|(0)),d2	; source y
	bra.s	.cvblt
.vtneg:	move.l	#((216<<16)|(0)),d1	; destination y
	move.l	#((0<<16)|(0)),d2	; source y
.cvblt:	move.l	#((12<<16)|(312)),d3	; height
	bsr	blttvgrf

.ret:	rts

;*======================================================================*
;* BLTTVGRF	: blit one portion of tv graphics memory to another	*
;*									*
;* INPUT :								*
;*	D1.l : Destination Y|X						*
;*	D2.l : Source Y|X						*
;*	D3.l : Height|Width						*
;*======================================================================*

blttvgrf:
	bsr	blitidle		; wait for blitter idle

	move.w	ScrlType,d0		; check if copy with preset or copy
	beq.s	scrlset
scrlcpy:				; SCROLL WITH COPY

; COPY SOURCE BLOCK TO DESTINATION BLOCK

	move.l	d1,A1_PIXEL		; destination pixel pointer (y|x)
	move.l	d2,A2_PIXEL		; source pixel pointer (y|x)

	move.l	#$00010000,d0
	move.w	d3,d0
	neg.w	d0
	move.l	d0,A1_STEP		; source step increment
	move.l	d0,A2_STEP		; destination step increment

	move.l	d3,B_COUNT		; set the inner\outer loop counters

	move.l	tvgrfmem,A1_BASE	; pointer to destination buffer
	move.l	tvgrfmem,A2_BASE	; pointer to source buffer

	move.l	#(PITCH1|PIXEL8|WID320|XADDPIX),A1_FLAGS ; source flags
	move.l	#(PITCH1|PIXEL8|WID320|XADDPIX),A2_FLAGS ; destination flags

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),B_CMD ; let it go
.ret:	rts

scrlset:				; SCROLL WITH PRESET

; CLEAR THE DESTINATION BLOCK

	bsr	blitidle		; wait for blitter idle

	move.w	ScrlColr,d0		; set the fill pattern and color
	move.w	d0,B_PATD		; select the color
	move.w	d0,B_PATD+2
	move.w	d0,B_PATD+4
	move.w	d0,B_PATD+6

	move.l	d1,A1_PIXEL		; source pixel pointer (y|x)

	move.l	#$00010000,d0
	move.w	d3,d0
	neg.w	d0
	move.l	d0,A1_STEP		; step -width x, +1 y each line

	move.l	d3,B_COUNT		; set the inner/outer loop counters

	move.l	tvgrfmem,A1_BASE	; point to the buffer

	move.l	#(PITCH1|PIXEL8|WID320|XADDPIX),A1_FLAGS ; set the flags

	move.l	#(PATDSEL|UPDA1),B_CMD	; start the BLTTER
.ret:	rts

;************************************************************************
;* ROUTINES FOR BLITTING LINE-GRAPHICS					*
;************************************************************************

;*======================================================================*
;* bltfnt16(x, y)							*
;* INPUT :	d3.w = x position					*
;*		d4.w = y position					*
;*									*
;* Blit a font with 16 bits per pixel to TV-Graf Memory at (x,y)	*
;*======================================================================*

bltfnt16:
	bsr	blitidle		; wait for blitter idle

	mulu	#$6,d3			; calculate x position in pixel
	addi.w	#$6,d3			; add extra 6 bit offset on left to keep scope for scrolling with copy

	mulu	#$C,d4			; calculate y position in pixel
	addi.w	#$C,d4			; add extra 12 bit offset on top to keep scope for scrolling with copy

	move.w	d4,d0			; y position
	swap	d0			; set the destination pixel pointer 
	move.w	d3,d0			; must be y|x
	move.l	d0,A1_PIXEL		; offset into draw buffer
	move.l	#$0001FFFA,A1_STEP	; step increment y = 1, x = -6

	move.l	#0,A2_PIXEL		; source is always from 0,0
	move.l	#$0001FFFA,A2_STEP	; step increment y = 1, x = -6

	move.l	#((12<<16)|(6)),B_COUNT	; outer/inner loop counters, h = 12, w = 6

	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),A1_FLAGS ; set the source and
	move.l	#(PITCH1|PIXEL16|WID6|XADDPIX),A2_FLAGS   ; destination flags

	move.l	lngrfmem,A1_BASE	; base address of destination buffer
	move.l	#fontdata,A2_BASE	; base address of character data

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),B_CMD ; let it go
.ret:	rts

;*======================================================================*
;* cp2lndsp	: Copies the graphics memory to display memory when a	*
;*		  update of graphics memory occurs			*
;*======================================================================*

cp2lndsp:

;****************************************
;* copy the LINE-graphic memory to the
;* LINE-display memory depending upon
;* (lnPH,lnPV) and (lnCOPH,lnCOPV)
;* starting from FONT (1,1)
;****************************************

	bsr	blitidle		; wait for blitter idle

	move.l	#0,A1_PIXEL		; initialise the destination pixel pointer
	move.l	#$0001FEE0,A1_STEP	; step increment = +1 y|-288 x

	move.w	#24,d0			; initialise the source pixel pointer
	add.w	lnPV,d0
	sub.w	lnCOPV,d0
	swap	d0
	move.w	#12,d0
	add.w	lnPH,d0
	sub.w	lnCOPH,d0
	move.l	d0,A2_PIXEL
	move.l	#$0001FEE0,A2_STEP	; step increment = +1 y|-288 x

	move.l	#((24<<16)|(288)),B_COUNT ; set the inner/outer loop counters

	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),A1_FLAGS ; source flags
	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),A2_FLAGS ; destination flags

	move.l	#lndspmem,A1_BASE	; base address of destination buffer
	move.l	lngrfmem,A2_BASE	; base address of source buffer

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),B_CMD ; let it go
.ret:	rts

;*======================================================================*
;* updlngrf	: updates the graphics memory for screen copy commands	*
;*======================================================================*

updlngrf:

;****************************************
;* SCROLL GRAPHICS MEMORY, IF NECESSARY
;*
;* in that case copy the blit in
;* graphics memory left/right and
;* up/down according to scroll with
;* preset or scroll with copy
;****************************************

	move.w	lnCOPH,d0		; check if either of COPH
	or.w	lnCOPV,d0		; or COPV is set
	beq	.ret			; quit

	bsr	blitidle		; wait for blitter idle

	move.w	#12,d0
	add.w	lnCOPV,d0		; destination y
	swap	d0
	move.w	#6,d0
	add.w	lnCOPH,d0		; destination x
	move.l	d0,A1_PIXEL		; set the destination pixel pointer
	move.l	#$0001FED4,A1_STEP	; destination step (y = 1, x = -300)

	move.l	#((12<<16)|(6)),A2_PIXEL ; source starting position
	move.l	#$0001FED4,A2_STEP	; source step (y = 1, x = -300)

	move.l	#((48<<16)|(300)),B_COUNT ; inner/outer loop counters

	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),A1_FLAGS ; source flags
	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),A2_FLAGS ; destination flags

	move.l	lnotherm,A1_BASE	; base of destination buffer
	move.l	lngrfmem,A2_BASE	; base of source buffer

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),B_CMD ; let it go

;****************************************
;* SWAP LINE graphics memory with it's
;* alternater memory buffer
;****************************************

.swaplng:
	move.l	lngrfmem,d0
	move.l	lnotherm,d1

	move.l	d0,lnotherm
	move.l	d1,lngrfmem

;****************************************
;* PRESET the border according to the
;* scroll instruction
;****************************************

.hz:	move.w	lnCOPH,d0
	beq.s	.vt
	bmi.s	.hzneg
.hzpos:	move.l	#((0<<16)|(6)),d1	; destination (y|x)
	move.l	#((0<<16)|(306)),d2	; source (y|x)
	bra.s	.chblt
.hzneg:	move.l	#((0<<16)|(300)),d1	; destination (y|x)
	move.l	#((0<<16)|(0)),d2	; source (y|x)
.chblt:	move.l	#((72<<16)|(6)),d3	; (height|width)
	bsr	bltlngrf

.vt:	move.w	lnCOPV,d0
	beq.s	.ret
	bmi.s	.vtneg
.vtpos:	move.l	#((12<<16)|(0)),d1	; destination (y|x)
	move.l	#((60<<16)|(0)),d2	; source (y|x)
	bra.s	.cvblt
.vtneg:	move.l	#((48<<16)|(0)),d1	; destination (y|x)
	move.l	#((0<<16)|(0)),d2	; source (y|x)
.cvblt:	move.l	#((12<<16)|(312)),d3	; (height|width)
	bsr	bltlngrf

.ret:	rts

;*======================================================================*
;* BLTLNGRF	: blit one portion of line graphics memory to another	*
;*									*
;* INPUT :								*
;*	D1.l : Destination Y|X						*
;*	D2.l : Source Y|X						*
;*	D3.l : Height|Width						*
;*======================================================================*

bltlngrf:

; CLEAR THE DESTINATION BLOCK

	bsr	blitidle		; wait for blitter idle

	move.w	ScrlColr,d0		; set the fill pattern and color
	move.w	d0,B_PATD		; select the color
	move.w	d0,B_PATD+2
	move.w	d0,B_PATD+4		; select Fill Pattern
	move.w	d0,B_PATD+6

	move.l	d1,A1_PIXEL		; set the source pixel pointer (y|x)

	move.l	#$00010000,d0		; set the source step value
	move.w	d3,d0
	neg.w	d0
	move.l	d0,A1_STEP

	move.l	d3,B_COUNT		; set the inner/outer loop counters

	move.l	lngrfmem,A1_BASE	; point to the buffer

	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),A1_FLAGS ; set flags

	move.l	#(PATDSEL|UPDA1),B_CMD	; let it go
.ret:	rts

;************************************************************************
;* VARIABLE DATA AREA							*
;************************************************************************

	.bss

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

		.phrase

tvdspmem:	.ds.w	(320*192)/2	; graphics memory for TV-Graphics
tvgrfmm1:	.ds.w	(320*240)/2	; graphics memory for TV-Graphics
tvgrfmm2:	.ds.w	(320*240)/2	; graphics memory for TV-Graphics

lndspmem:	.ds.w	(320*24)	; graphics memory for LINE-Graphics
lngrfmm1:	.ds.w	(320*72)	; graphics memory for LINE-Graphics
lngrfmm2:	.ds.w	(320*72)	; graphics memory for LINE-Graphics

dummy1:		.ds.w	256		; just some dummy memory area

		.phrase

fontdata:	.ds.w	72		; memory for font data

dummy2:		.ds.w	256		; just some dummy memory area

		.phrase

tvgrfmem:	.ds.l	1		; pointer to Primary TV graphics memory
tvotherm:	.ds.l	1		; pointer to alternate TV graphics memory

lngrfmem:	.ds.l	1		; pointer to LINE graphics memory
lnotherm:	.ds.l	1		; pointer to alternate LINE graphics memory

		.phrase

TvChnlNo:	.ds.w	1		; the channel number the user wants to view 

		.phrase

;************************************************************************
;* END OF FILE								*
;************************************************************************

	.end
