;************************************************************************
;* TITLE	: CDG.S							*
;* Function	: Initialize CD-G playerand other routines		*
;*									*
;* Project #	: JAGUAR CD+G						*
;* Modified	: Pradip K Fatehpuria	06/16/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"

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

	.extern	objData
	.extern	screnmem

	.extern	_CDGType

	.extern	_XORFlag

	.extern	_tvPH
	.extern	_tvPV
	.extern	_tvCOPH
	.extern	_tvCOPV

	.extern	_ScrlType
	.extern	_ScrlColr

	.extern	_lnPH
	.extern	_lnPV
	.extern	_lnCOPH
	.extern	_lnCOPV

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

	.globl	initapp

	.globl	_initCDG
	.globl	_initcol

	.globl	_clrscren
	.globl	_clrtvdsp
	.globl	_clrtvgrf
	.globl	_clrlndsp
	.globl	_clrlngrf

	.globl	_clrbuffr

	.globl	_defcolor
	.globl	_setscren
	.globl	_settvgrf
	.globl	_setlngrf

	.globl	_stopblit

	.globl	_bltfnt08
	.globl	_cp2tvdsp

	.globl	_bltfnt16
	.globl	_cp2lndsp

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

	.globl	tvdspmem
	.globl	lndspmem

	.globl	_TvColTbl

	.globl	_fntdata

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

	.text

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

initapp:
	move.w	#$07C0,BG		; set the background colour (BLUE)
	move.l	#$000000FF,BORD1	; set the border colour (BLUE)

	move.w	#$07C0,-(sp)		; set the colour to BLUE
	jsr	_clrscren		; use blitter to clear screen
	add.l	#2,sp

	move.l	#CLUT,_TvColTbl		; set the pointer to CLUT

	move.w	#$0000,_CDGType		; CD-G type variable (none/line/tv)

	jsr	_blitinit		; initialise font blit parameters

	jsr	_initCDG		; initialise the CDG player
	rts

;*======================================================================*
;* INITCDG	: initialise a CDG track player				*
;*======================================================================*

_initCDG:
	jsr	_initcol		; initialise colour table

	move.w	#$0101,-(sp)		; set the colour to BLUE
	jsr	_clrtvdsp		; clear TV-Graphics Display memory
	jsr	_clrtvgrf		; clear TV-Graphics memory
	add.l	#2,sp

	move.w	#$07C0,-(sp)		; set the colour to BLUE
	jsr	_clrlndsp		; clear LINE-Graphics Display memory
	jsr	_clrlngrf		; clear LINE-Graphics memory
	add.l	#2,sp
	rts

;*======================================================================*
;* INITCOL	: initialise colour table				*
;*======================================================================*

_initcol:
	movem.l	a0/d0-d1,-(sp)

	move.l	#CLUT,a0
	move.l	#255,d0
	move.w	#$07C0,d1		; make them all BLUE
.cpyloop:
	move.w	d1,(a0)+
	dbra	d0,.cpyloop

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

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

;*======================================================================*
;* DEFCOLOR	: initialise colour table				*
;*======================================================================*

_defcolor:
	movem.l	a0-a1/d0,-(sp)

	move.l	#CLUT,a1
	move.l	#31,d0			; copy rom colour table 32 times
.cpyloop:
	lea.l	romcolor,a0
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	move.w	(a0)+,(a1)+
	dbra	d0,.cpyloop

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

;*======================================================================*
;* SETSCREN	: enable/disable SCREEN object				*
;* SETTVGRF	: enable/disable TV-graphics				*
;* SETLNGRF	: enable/disable line graphics				*
;*======================================================================*

_setscren:
	movem.l	d0/a0,-(sp)

	lea.l	objData+OBJSIZE*0,a0	; pointer to SCREEN Object
	move.w	$C(sp),d0		; load flag in d0
	beq.s	noobj
	bra.s	stobj

_settvgrf:
	movem.l	d0/a0,-(sp)

	lea.l	objData+OBJSIZE*1,a0	; pointer to SCREEN Object
	move.w	$C(sp),d0		; load flag in d0
	beq.s	noobj
	bra.s	stobj

_setlngrf:
	movem.l	d0/a0,-(sp)

	lea.l	objData+OBJSIZE*2,a0	; pointer to SCREEN Object
	move.w	$C(sp),d0		; load flag in d0
	beq.s	noobj

stobj:	andi.b	#(~DELETE_OBJ),O_TYPE(a0)
	movem.l	(sp)+,a0/d0
	rts

noobj:	ori.b	#DELETE_OBJ,O_TYPE(a0)
	movem.l	(sp)+,a0/d0
	rts

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

;*======================================================================*
;* CLRSCREN	: clears jaguar video screen using the blitter		*
;*======================================================================*

_clrscren:
	movem.l	d0-d3/a0,-(sp)

	move.w	$18(sp),d0		; get the colour in d0
	move.w	#384,d1
	move.w	#200,d2
	move.l	#(PIXEL16|WID384),d3
	move.l	#screnmem,a0
	jsr	_clrbuffr

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

;*======================================================================*
;* CLRTVDSP	: clear the display memory for TV Graphics		*
;*======================================================================*

_clrtvdsp:
	movem.l	d0-d3/a0,-(sp)

	move.w	$18(sp),d0		; get the colour in d0
	move.w	#320,d1
	move.w	#192,d2
	move.l	#(PIXEL8|WID320),d3
	move.l	#tvdspmem,a0
	jsr	_clrbuffr

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

;*======================================================================*
;* CLRTVGRF	: clear the graphic memory for TV-Graphics		*
;*======================================================================*

_clrtvgrf:
	movem.l	d0-d3/a0,-(sp)

	move.w	$18(sp),d0		; get the colour in d0
	move.w	#320,d1
	move.w	#240,d2
	move.l	#(PIXEL8|WID320),d3
	move.l	#tvgrfmem,a0
	jsr	_clrbuffr

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

;*======================================================================*
;* CLRLNDSP	: clear the display memory for LINE-Graphics		*
;*======================================================================*

_clrlndsp:
	movem.l	d0-d3/a0,-(sp)

	move.w	$18(sp),d0		; get the colour in d0
	move.w	#320,d1
	move.w	#24,d2
	move.l	#(PIXEL16|WID320),d3
	move.l	#lndspmem,a0
	jsr	_clrbuffr

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

;*======================================================================*
;* CLRLNGRF	: clear the graphic memory for LINE-Graphics		*
;*======================================================================*

_clrlngrf:
	movem.l	d0-d3/a0,-(sp)

	move.w	$18(sp),d0		; get the colour in d0
	move.w	#320,d1
	move.w	#72,d2
	move.l	#(PIXEL16|WID320),d3
	move.l	#lngrfmem,a0
	jsr	_clrbuffr

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

;*======================================================================*
;* CLRBUFFR	: BLTTER zero fill a given buffer			*
;*									*
;* Input:								*
;*	D0.w = Data Pattern to fill with				*
;*	D1.w = Width of the window in pixel				*
;*	D2.w = Height of the window in pixel				*
;*	D3.l = Number of bits per pixel					*
;*	A0 = Ptr to Buffer to Clear					*
;*======================================================================*

_clrbuffr:
	movem.l	d0-d3/a0,-(sp)

	jsr	_blitidle		; wait for blitter idle

	ori.l	#(PITCH1|XADDPHR),d3
	move.l	d3,A1_FLAGS

	move.l	a0,A1_BASE		; point to the buffer

	move.w	d0,B_PATD		; select the colour
	move.w	d0,B_PATD+2
	move.w	d0,B_PATD+4		; select Fill Pattern
	move.w	d0,B_PATD+6

	clr.l	d0
	move.l	d0,A1_PIXEL		; pointer to (0,0)
	move.l	d0,A1_FPIXEL		; fractional pointer to (0,0)

	move.w	#1,d0
	swap	d0
	move.w	d1,d0
	neg.w	d0
	move.l	d0,A1_STEP		; step -width x, +1 y each line

	move.w	d2,d0
	swap	d0
	move.w	d1,d0
	move.l	d0,B_COUNT		; Do (height..width)

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

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

;*======================================================================*
;* BLITIDLE	: waits for the BLITTER IDLE				*
;*======================================================================*

_blitidle:
	move.l	d0,-(sp)

.waitblt:
	move.l	B_CMD,d0
	lsr.w	#1,d0
	bcc	.waitblt

	move.l	(sp)+,d0
	rts

;************************************************************************
;************************************************************************
;************************************************************************
;************************************************************************

;*======================================================================*
;* blitinit	: initialise font pointer to be blitted on the screen	*
;*======================================================================*

_blitinit:
	move.l	#txtcdata,_fntdata
	rts

;*======================================================================*
;* stopblit	: stops the current blitter operations			*
;*======================================================================*

_stopblit:
	move.w	#2,B_CMD
	rts

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

;*======================================================================*
;* _bltfnt08(x, y, char)						*
;*	short	x, y							*
;*	short	char (ascii)						*
;*									*
;* Blit a font with 8 bits per pixel to TV-Graf Memory at (x,y)		*
;*======================================================================*

_bltfnt08:
	movem.l	d0-d1,-(sp)
	jsr	_blitidle		; wait for blitter idle

	move.w	$C(sp),d0		; get x positin in graphics memory
	mulu	#6,d0			; calculate x in pixel
	addi.w	#6,d0			; add extra 6 bit offset on left to keep scope for scrolling with copy

	move.w	$E(sp),d1		; get y position in graphics memory
	mulu	#12,d1			; calculate  y in pixel
	addi.w	#12,d1			; add extra 12 bit offset on top to keep scope for scrolling with copy

	swap	d1			; set the destination pixel pointer 
	move.w	d0,d1			; must be y|x
	move.l	d1,A1_PIXEL		; offset into draw buffer
	move.l	#0,A2_PIXEL		; source is always from 0,0

	move.w	#12,d0			; set the inner/outer loop counters for blitter
	swap	d0
	move.w	#6,d0
	move.l	d0,B_COUNT		; height|width of playfield

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

	move.w	#1,d0			; now setup the step increments 
	swap	d0			; for blitting
	move.w	#(-6),d0
	move.l	d0,A1_STEP		; step1 = +1 y|-6 x
	move.l	d0,A2_STEP		; step2 = +1 y|-6 x

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

	move.w	_XORFlag,d0		; set up the blitter commands
	beq.s	.rplc

.xor:	move.l	#(SRCEN|UPDA1|UPDA2|DSTEN|LFU_NA|LFU_AN),B_CMD
	movem.l	(sp)+,d0-d1
	rts

.rplc:	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),B_CMD
	movem.l	(sp)+,d0-d1
	rts

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

_cp2tvdsp:
	movem.l	d0-d6,-(sp)

;****************************************
;* 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
;*
;****************************************

	jsr	_blitidle		; wait for blitter idle

	move.l	#0,A1_PIXEL		; initialise the destination pixel pointer

	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,d6			; get the offset of first pixel from the base address
	move.w	#1,d0			; now setup the step increments for blitting
	swap	d0
.a1step:
	move.w	#(-288),d0
	move.l	d0,A1_STEP		; step for A1 = +1 y|-288 x

	move.w	#288,d0			; x step value
	andi.l	#$7,d6			; offset of first pixel from phrase boundary
	beq.s	.a2step
	addi.w	#8,d0
	sub.w	d6,d0
	move.l	#SRCENX,d6		; the command flags for phrase boundary
.a2step:
	neg.w	d0			; x step value
	move.l	d0,A2_STEP		; step for A2 1 = +1 y|-288 x

	move.w	#192,d0			; initialise the inner/outer loop counters
	swap	d0
	move.w	#288,d0
	move.l	d0,B_COUNT		; height|width of playfield

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

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

	or.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),d6
	move.l	d6,B_CMD		; set up the blitter commands

;****************************************
;* 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
	move.w	_tvCOPV,d1
	or.w	d1,d0
	beq	.ret			; quit

	jsr	_blitidle		; wait for blitter idle

	move.w	#6,d1			; source x
	move.w	#12,d2			; source y
	move.w	#-300,d3		; step x
	move.w	#1,d4			; step y

	move.l	#(PITCH1|PIXEL8|WID320|XADDPIX),d5

.ph:	move.w	_tvCOPH,d0
	ble.s	.pv
.phpos:	move.w	#305,d1			; source x
	neg.w	d3			; step x
	or.l	#XSIGNSUB,d5		; flag

.pv:	move.w	_tvCOPV,d0
	ble	.cpyblit
.pvpos:	move.w	#227,d2			; source y
	neg.w	d4			; step y
	or.l	#YSIGNSUB,d5		; flag

.cpyblit:
	move.w	d2,d0			; source y
	swap	d0
	move.w	d1,d0			; source x
	move.l	d0,A2_PIXEL		; prepare the source pixel pointer

	move.w	d2,d0
	add.w	_tvCOPV,d0		; destination y
	swap	d0
	move.w	d1,d0
	add.w	_tvCOPH,d0		; destination x
	move.l	d0,A1_PIXEL		; prepare the destination pixel pointer

	move.w	#216,d0
	swap	d0
	move.w	#300,d0
	move.l	d0,B_COUNT		; setup the inner/outer loop counters

	move.l	d5,A1_FLAGS		; setup the source flags
	move.l	d5,A2_FLAGS		; setup the destination flags

	move.w	d4,d0			; step y
	swap	d0
	move.w	d3,d0			; step x
	move.l	d0,A1_STEP		; setup the source step increment
	move.l	d0,A2_STEP		; setup the destination step increment

	move.l	#tvgrfmem,d0
	move.l	d0,A1_BASE		; base adress of destination buffer
	move.l	d0,A2_BASE		; base of address of source buffer

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

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

.hz:	move.w	_tvCOPH,d0
	beq.s	.vt

	move.w	#0,d1			; destination y
	swap	d1
	move.w	#0,d2			; source y
	swap	d2
	move.w	#240,d3			; height
	swap	d3

	move.w	_tvCOPH,d0
	bmi.s	.hzneg
.hzpos:	move.w	#6,d1			; destination x
	move.w	#306,d2			; source x
	bra.s	.chblt
.hzneg:	move.w	#300,d1			; destination x
	move.w	#0,d2			; source x

.chblt:	move.w	#6,d3			; width
	jsr	blttvgrf

.vt:	move.w	_tvCOPV,d0
	beq.s	.ret

	move.w	_tvCOPV,d0
	bmi.s	.vtneg
.vtpos:	move.w	#12,d1			; destination y
	move.w	#228,d2			; source y
	bra.s	.cvblt
.vtneg:	move.w	#216,d1			; destination y
	move.w	#0,d2			; source y

.cvblt:	move.w	#12,d3			; height

	swap	d1
	move.w	#0,d1			; destination x
	swap	d2
	move.w	#0,d2			; source x
	swap	d3
	move.w	#312,d3			; width
	jsr	blttvgrf

.ret:	movem.l	(sp)+,d0-d6
	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:
	jsr	_blitidle		; wait for blitter idle

	move.w	_ScrlType,d0		; check if copy with preset or copy
	beq.s	scrlset
scrlcpy:				; SCROLL WITH COPY
	move.l	d1,A1_PIXEL		; destination pixel pointer (y|x)
	move.l	d2,A2_PIXEL		; source pixel pointer (y|x)
	move.l	d3,B_COUNT		; set the inner\outer loop counters

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

	move.w	#1,d0
	swap	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	#tvgrfmem,d0
	move.l	d0,A1_BASE		; pointer to destination buffer
	move.l	d0,A2_BASE		; pointer to source buffer

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

scrlset:				; SCROLL WITH PRESET

; CLEAR THE SOURCE BLOCK

	move.l	d2,A1_PIXEL		; source pixel pointer (y|x)
	move.l	#0,A1_FPIXEL		; source fractional pixel pointer
	move.l	d3,B_COUNT		; set the inner/outer loop counters

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

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

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

	move.l	#tvgrfmem,A1_BASE	; point to the buffer

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

	jsr	_blitidle		; wait for blitter idle

; CLEAR THE DESTINATION BLOCK

	move.l	d1,A1_PIXEL		; source pixel pointer (y|x)
	move.l	#0,A1_FPIXEL		; source fractional pixel pointer
	move.l	d3,B_COUNT		; set the inner/outer loop counters

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

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

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

	move.l	#tvgrfmem,A1_BASE	; point to the buffer

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

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

;*======================================================================*
;* _bltfnt16(x, y, char)						*
;*	short	x, y							*
;*	short	char (ascii)						*
;*									*
;* Blit a font with 16 bits per pixel to TV-Graf Memory at (x,y)	*
;*======================================================================*

_bltfnt16:
	movem.l	d0-d1,-(sp)
	jsr	_blitidle		; wait for blitter idle

	move.w	$C(sp),d0		; get x positin in graphics memory
	mulu	#6,d0			; calculate x in pixel
	addi.w	#6,d0			; add extra 6 bit offset on left to keep scope for scrolling with copy

	move.w	$E(sp),d1		; get y position in graphics memory
	mulu	#12,d1			; calculate  y in pixel
	addi.w	#12,d1			; add extra 12 bit offset on top to keep scope for scrolling with copy

	swap	d1			; set the destination pixel pointer 
	move.w	d0,d1			; must be y|x
	move.l	d1,A1_PIXEL		; offset into draw buffer
	move.l	#0,A2_PIXEL		; source is always from 0,0

	move.w	#12,d0			; set the inner/outer loop counters for blitter
	swap	d0
	move.w	#6,d0
	move.l	d0,B_COUNT		; height|width of playfield

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

	move.w	#1,d0			; now setup the step increments 
	swap	d0			; for blitting
	move.w	#(-6),d0
	move.l	d0,A1_STEP		; step1 = +1 y|-6 x
	move.l	d0,A2_STEP		; step2 = +1 y|-6 x

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

	move.l	#(SRCEN|UPDA1|UPDA2|LFU_A|LFU_AN),B_CMD ; let it go
	movem.l	(sp)+,d0-d1
	rts

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

_cp2lndsp:
	movem.l	d0-d5,-(sp)

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

	jsr	_blitidle		; wait for blitter idle

	move.l	#0,A1_PIXEL		; initialise the destination pixel pointer

	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.w	#24,d0			; set the inner/outer loop counters
	swap	d0
	move.w	#288,d0
	move.l	d0,B_COUNT

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

	move.w	#1,d0			; setup the source/destination
	swap	d0			; step increments
	move.w	#(-288),d0
	move.l	d0,A1_STEP		; step1 = +1 y|-288 x
	move.l	d0,A2_STEP		; step2 = +1 y|-288 x

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

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

;****************************************
;* 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 COPV is set
	move.w	_lnCOPV,d1
	or.w	d1,d0
	beq	.ret			; quit

	jsr	_blitidle		; wait for blitter idle

	move.w	#6,d1			; source x
	move.w	#12,d2			; source y
	move.w	#-300,d3		; step x
	move.w	#1,d4			; step y
	move.l	#(PITCH1|PIXEL16|WID320|XADDPIX),d5

.ph:	move.w	_lnCOPH,d0
	ble.s	.pv
.phpos:	move.w	#305,d1			; source x
	neg.w	d3			; step x
	or.l	#XSIGNSUB,d5		; flag

.pv:	move.w	_lnCOPV,d0
	ble.s	.cpyblit
.pvpos:	move.w	#59,d2			; source y
	neg.w	d4			; step y
	or.l	#YSIGNSUB,d5		; flag

.cpyblit:
	move.w	d2,d0			; source y
	swap	d0
	move.w	d1,d0			; source x
	move.l	d0,A2_PIXEL		; set the source pixel pointer

	move.w	d2,d0
	add.w	_lnCOPV,d0		; destination y
	swap	d0
	move.w	d1,d0
	add.w	_lnCOPH,d0		; destination x
	move.l	d0,A1_PIXEL		; set the destination pixel pointer

	move.w	#48,d0			; set the inner/outer loop counters
	swap	d0
	move.w	#300,d0
	move.l	d0,B_COUNT

	move.l	d5,A1_FLAGS		; set the source flags
	move.l	d5,A2_FLAGS		; set the destination flags


	move.w	d4,d0			; step y
	swap	d0
	move.w	d3,d0			; step x
	move.l	d0,A1_STEP		; set the destination step increments
	move.l	d0,A2_STEP		; set the source step increments

	move.l	#lngrfmem,d0
	move.l	d0,A1_BASE		; pointer to destination buffer
	move.l	d0,A2_BASE		; pointer to character data

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

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

.hz:	move.w	_lnCOPH,d0
	beq.s	.vt

	move.w	#0,d1			; destination y
	swap	d1
	move.w	#0,d2			; source y
	swap	d2
	move.w	#72,d3			; height
	swap	d3

	move.w	_lnCOPH,d0
	bmi.s	.hzneg
.hzpos:	move.w	#6,d1			; destination x
	move.w	#306,d2			; source x
	bra.s	.chblt
.hzneg:	move.w	#300,d1			; destination x
	move.w	#0,d2			; source x

.chblt:	move.w	#6,d3			; width
	jsr	bltlngrf

.vt:	move.w	_lnCOPV,d0
	beq.s	.ret

	move.w	_lnCOPV,d0
	bmi.s	.vtneg
.vtpos:	move.w	#12,d1			; destination y
	move.w	#60,d2			; source y
	bra.s	.cvblt
.vtneg:	move.w	#48,d1			; destination y
	move.w	#0,d2			; source y

.cvblt:	move.w	#12,d3			; height

	swap	d1
	move.w	#0,d1			; destination x
	swap	d2
	move.w	#0,d2			; source x
	swap	d3
	move.w	#312,d3			; width
	jsr	bltlngrf

.ret:	movem.l	(sp)+,d0-d5
	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 SOURCE BLOCK

	jsr	_blitidle		; wait for blitter idle

	move.l	d2,A1_PIXEL		; set the source pixel pointer (y|x)
	move.l	#0,A1_FPIXEL		; set the source fractional pixel pointer
	move.l	d3,B_COUNT		; set the inner/outer loop counters

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

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

	move.l	#lngrfmem,A1_BASE	; point to the buffer

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

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

; CLEAR THE DESTINATION BLOCK

	jsr	_blitidle		; wait for blitter idle

	move.l	d1,A1_PIXEL		; set the source pixel pointer (y|x)
	move.l	#0,A1_FPIXEL		; set the source fractional pixel pointer
	move.l	d3,B_COUNT		; set the inner/outer loop counters

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

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

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

	move.l	#lngrfmem,A1_BASE	; point to the buffer

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

;************************************************************************
;* CONSTANT DATA AREA							*
;************************************************************************

	.data

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

		.phrase

romcolor:	.dc.w	$0000		; Black
		.dc.w	$07C0		; Blue
		.dc.w	$003F		; Green
		.dc.w	$07FF		; Cyan
		.dc.w	$F800		; Red
		.dc.w	$FFC0		; Magenta
		.dc.w	$F83F		; Yellow
		.dc.w	$FFFF		; White

		.phrase

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

	.bss

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

		.phrase

tvdspmem:	.ds.w	(320*192)/2	; graphics memory for TV-Graphics
lndspmem:	.ds.w	(320*24)	; graphics memory for LINE-Graphics

tvgrfmem:	.ds.w	(320*240)/2	; graphics memory for TV-Graphics
lngrfmem:	.ds.w	(320*72)	; graphics memory for LINE-Graphics

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

_TvColTbl:	.ds.l	1		; pointer to colour table
_fntdata:	.ds.l	1		; pointer to font data

		.phrase

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

		.phrase

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

	.end
