;************************************************************************
;* TITLE	: PACK.S						*
;* Function	: CD+G processing routines				*
;*									*
;* Project #	: JAGUAR CD+G						*
;* Programmer	: Pradip K Fatehpuria	06/29/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	"PROCESS CD+G PACKETS"

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

	.include "jaguar.inc"
	.include "blitter.inc"
	.include "pack.inc"

;*======================================================================*
;* EXTERNAL ROUTINES							*
;*======================================================================*

	.extern	clrtvgrf

	.extern	setlngrf
	.extern	settvgrf

	.extern	blitidle

	.extern	bltfnt16
	.extern	cp2lndsp
	.extern	updtvgrf

	.extern	bltfnt08
	.extern	cp2tvdsp
	.extern	updlngrf

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

	.extern	bldobflg

	.extern	fontdata

	.extern	CDGword

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

	.globl	initproc
	.globl	procsub

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

	.globl	CDGType

	.globl	TvChnlNo

	.globl	XORFlag

	.globl	lnPH
	.globl	lnPV
	.globl	lnCOPH
	.globl	lnCOPV

	.globl	tvPH
	.globl	tvPV
	.globl	tvCOPH
	.globl	tvCOPV

	.globl	ScrlType
	.globl	ScrlColr

	.globl	BrdColNo

;************************************************************************
;* SUBROUTINES AREA							*
;************************************************************************

	.text

;*======================================================================*
;* initialise CD+G processing parameters				*
;* INPUT	: d0.w = TV Channel number to be viewed			*
;*======================================================================*

initproc:
	move.w	d0,TvChnlNo		; TV GRAPHICS channel number

	move.l	#0,d0			; use register to clear parameters

	move.l	d0,symblcnt		; initialise symbol count
	move.l	d0,PakCount		; total no of packets processed

	move.w	d0,lnPH			; scroll factors for line graphics
	move.w	d0,lnPV
	move.w	d0,lnCOPH
	move.w	d0,lnCOPV

	move.w	d0,tvPH			; scroll factors for TV graphics
	move.w	d0,tvPV
	move.w	d0,tvCOPH
	move.w	d0,tvCOPV

	move.w	d0,BrdColNo		; border colour number

	move.w	d0,TvDspFlg		; initialise TV graphics display flag
	move.w	d0,LnDspFlg		; initialise LINE graphics display flag

	bsr	inicolor		; initialise color tables
	rts

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

;*======================================================================*
;* process the four packets collected from the CD			*
;*======================================================================*

procsub:
	movem.l	d0-d7/a0-a6,-(sp)

.pack1:	add.l	#1,PakCount
	move.l	#CDGword+$00,a6
	bsr.s	procpack

.pack2:	add.l	#1,PakCount
	move.l	#CDGword+$18,a6
	bsr.s	procpack

.pack3:	add.l	#1,PakCount
	move.l	#CDGword+$30,a6
	bsr.s	procpack

.pack4:	add.l	#1,PakCount
	move.l	#CDGword+$48,a6
	bsr.s	procpack

.updcl:	tst.w	TvColFlg
	beq.s	.ovrcl
	bsr	setcolor
	move.w	#FALSE,TvColFlg
.ovrcl:

.updtv:	tst.w	TvDspFlg
	beq.s	.ovrtv
	bsr	cp2tvdsp
	move.w	#FALSE,TvDspFlg
.ovrtv:

.updln:	tst.w	LnDspFlg
	beq.s	.ovrln
	bsr	cp2lndsp
	move.w	#FALSE,LnDspFlg
.ovrln:

.ret:	movem.l	(sp)+,d0-d7/a0-a6
	rts

;*======================================================================*
;* process the given pack						*
;*======================================================================*

procpack:

.if 0
	CDDATLEN	equ	1454400

	move.l	#$200000-CDDATLEN,a1
	add.l	symblcnt,a1
	move.l	(a6)+,(a1)+
	move.l	(a6)+,(a1)+
	move.l	(a6)+,(a1)+
	move.l	(a6)+,(a1)+
	move.l	(a6)+,(a1)+
	move.l	(a6)+,(a1)+
	add.l	#24,symblcnt
	cmp.l	#CDDATLEN,symblcnt
	bne.s	.ret
	illegal
.endif

	move.b	SYMB00(a6),d0		; d0 = type of pack
	and.l	#$3F,d0
	mulu	#4,d0			; d0 = byte offset in proc table

	move.l	#proctabl,a0		; a0 = pointer to proc table
	add.l	d0,a0			; add offset in proc table
	move.l	(a0),d1			; d1 = pointer to jump table
	beq.s	.ret			; quit, if NULL pointer

	move.l	#0,d0			; clear d0
	move.b	SYMB01(a6),d0		; d0 = instruction type
	and.l	#$3F,d0
	mulu	#4,d0			; d0 = byte offset in jump table
	add.l	d1,d0			; d0 = relevent position in jump table

	move.l	d0,a0			; a0 = d0
	move.l	(a0),d0			; pointer to the required function
	beq.s	.ret			; quit, if function is NULL

	move.l	d0,a0			; jump to the required function
	jsr	(a0)			; which processes the given pack
.ret:	rts

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

;*======================================================================*
;* inicolor	: initialise primary memory color/secondary memory	*
;*		  color/transparency factor				*
;*======================================================================*

inicolor:
	move.l	#TvPmColR,a0		; primary memory - red component
	move.l	#TvPmColG,a1		; primary memory - green component
	move.l	#TvPmColB,a2		; primary memory - blue component

	move.l	#TransFac,a3		; transparency factor

	move.l	#TvScColR,a4		; secondary memory - red component
	move.l	#TvScColG,a5		; secondary memory - green component
	move.l	#TvScColB,a6		; secondary memory - blue component

	move.l	#$0,d0			; clear d0

	move.w	#63,d1			; total of 256 colors

.loop:	move.l	d0,(a0)+		; primary - red component
	move.l	d0,(a1)+		; primary - green component
	move.l	d0,(a2)+		; primary - blue component

	move.l	d0,(a3)+		; transparency factor

	move.l	d0,(a4)+		; secondary - red component
	move.l	d0,(a5)+		; secondary - green component
	move.l	d0,(a6)+		; secondary - blue component

	dbra	d1,.loop

.ret:	move.w	d0,TvColFlg		; clear tv colour table flag
	rts

;*======================================================================*
;* setpclut	: set primary memory clut to be loaded			*
;* input	: d0.l - the starting position in colour table		*
;*======================================================================*

setpclut:
	move.l	#TvPmColR,a3		; a3 = table for RED component
	move.l	#TvPmColG,a4		; a4 = table for GREEN component
	move.l	#TvPmColB,a5		; a5 = table for BLUE component

	add.l	d0,a3			; a3 = starting position in RED table
	add.l	d0,a4			; a4 = starting position in GREEN table
	add.l	d0,a5			; a5 = the starting position in BLUE table
	rts

;*======================================================================*
;* setsclut	: set secondary memory clut to be loaded		*
;* input	: d0.l - the starting position in colour table		*
;*======================================================================*

setsclut:
	move.l	#TvScColR,a3		; a3 = table for RED component
	move.l	#TvScColG,a4		; a4 = table for GREEN component
	move.l	#TvScColB,a5		; a5 = table for BLUE component

	add.l	d0,a3			; a3 = starting position in RED table
	add.l	d0,a4			; a4 = starting position in GREEN table
	add.l	d0,a5			; a5 = the starting position in BLUE table
	rts

;*======================================================================*
;* settrans	: set transparency factor table to be loaded		*
;* input	: d0.l - the starting position in table			*
;*======================================================================*

settrans:
	move.l	#TransFac,a3		; transparency factor
	add.l	d0,a3			; a3 = starting position in table
	rts

;*======================================================================*
;* Load the CLUT given the starting position in table and the pack	*
;*									*
;* This routine loads a 12 bit colour composition as used in TV-grapics	*
;* or extended TV-graphics mode (when load clut is called)		*
;*									*
;*	RED table	- 000rrrr0					*
;*	GREEn table	- 00gggg00					*
;*	BLUE table	- 000bbbb0					*
;*									*
;* input:	a3 - starting pointer in RED table			*
;*		a4 - starting pointer in GREEN table			*
;*		a5 - starting pointer in BLUE table			*
;*									*
;*======================================================================*

ldclut1:
	move.l	#offstabl,a0		; a0 = offset table for descrabling pack data
	move.l	#0,d0			; clear d0
	move.w	#7,d7			; load 8 colours from pack

.loop:	move.b	(a0)+,d0		; d0 = offset in pack data
	move.b	(a6,d0),d1		; d1 = current symbol
	move.b	d1,d2			; d2 = d1

	lsr.b	#$01,d1			; red = ((color >> 1) & 0x1E)
	andi.b	#$1E,d1			; d1 = 000r rrr0
	lsl.b	#$04,d2			; grn = ((color << 4) & 0x30)
	andi.b	#$30,d2			; d2 = 00gg 0000

	move.b	(a0)+,d0		; d0 = offset in pack data
	move.b	(a6,d0),d0		; d0 = current symbol
	move.b	d0,d3			; d3 = d0

	lsr.b	#$02,d0			; grn = ((color >> 2) & 0x0C)
	andi.b	#$0C,d0			; d0 = 0000 gg00
	or.b	d0,d2			; d2 = 00gg gg00
	lsl.b	#$01,d3			; blu = ((color << 1) & 0x1E)
	andi.b	#$1E,d3			; d3 = 000b bbb0

	move.b	d1,(a3)+		; save RED   (000r rrr0)
	move.b	d2,(a4)+		; save GREEN (00gg gg00)
	move.b	d3,(a5)+		; save BLUE  (000b bbb0)

	dbra	d7,.loop		; continue for next symbols
.ret:	move.w	#TRUE,TvColFlg		; update the colour table
	rts

;*======================================================================*
;* Load the additional 2 bits of each colour given the starting		*
;* position in table and the current pack.				*
;*									*
;* This routine adds aditional low order bits to the colour table as	*
;* prepared above.							*
;*									*
;*	RED table	- 000rrrrr					*
;*	GREEn table	- 00gggggg					*
;*	BLUE table	- 000bbbbb					*
;*									*
;* input:	a3 - starting pointer in RED table			*
;*		a4 - starting pointer in GREEN table			*
;*		a5 - starting pointer in BLUE table			*
;*									*
;*======================================================================*

ldclut2:
	move.l	#offstabl,a0		; a0 = offset table for descrabling pack data
	move.l	#0,d0			; clear d0
	move.w	#15,d7			; load 15 additional colour bits from pack

.loop:	move.b	(a0)+,d0		; d0 = offset in pack data
	move.b	(a6,d0),d1		; d1 = current symbol
	move.b	d1,d2			; d2 = d1
	move.b	d1,d3			; d3 = d1

	lsr.b	#$05,d1			; d1 = red = 0000 000r
	andi.b	#$01,d1			; d1 = red = 0000 000r
	lsr.b	#$02,d2			; d2 = grn = 0000 xxgg
	andi.b	#$03,d2			; d2 = grn = 0000 00gg
	lsr.b	#$01,d3			; d3 = blu = 000x xxxb
	andi.b	#$01,d3			; d3 = blu = 0000 000b

	or.b	d1,(a3)+		; red = 000r rrrr
	or.b	d2,(a4)+		; grn = 00gg gggg
	or.b	d3,(a5)+		; blu = 000b bbbb

	dbra	d7,.loop		; continue for next symbols
.ret:	move.w	#TRUE,TvColFlg		; update the colour table
	rts

;*======================================================================*
;* Load the transparency factor for different color components and	*
;* update the colour table						*
;*									*
;* input:	a3 - starting pointer in table				*
;*======================================================================*

ldtrans:
	move.l	#offstabl,a0		; a0 = offset table for descrabling pack data
	move.l	#0,d0			; clear d0
	move.w	#15,d7			; load 15 additional colour bits from pack

.loop:	move.b	(a0)+,d0		; d1 = offset in current pack
	move.b	(a6,d0),d0		; d0 = TRANSn factor
	and.b	#$3F,d0			; d0 = 6 bits of Transparency factor
	move.b	d0,(a3)+		; save transparency factor

	dbra	d7,.loop		; continue for next symbols
.ret:	move.w	#TRUE,TvColFlg		; update the colour table
	rts

;*======================================================================*
;* setcolor	: set color table from primary/secondary color table	*
;*		  depending upon the memory coltrol instruction, if in	*
;*		  extended TV-graphics mode, of from primary memory	*
;*		  if it is TV-graphics mode.				*
;*									*
;*		  Also, apply the transparency factor, if in		*
;*		  TV-graphics mode					*
;*======================================================================*

setcolor:
	move.l	#CLUT,a1		; a1 = pointer to system CLUT

	move.l	#TransFac,a2		; a2 = table for transparency factor
	move.l	#TvPmColR,a3		; a3 = table for RED component
	move.l	#TvPmColG,a4		; a4 = table for GREEN component
	move.l	#TvPmColB,a5		; a5 = table for BLUE component

	move.w	#$FF,d7			; load system colour table

.loop:	move.l	#$3F,d0			; d0 = 63
	move.l	#$00,d1			; d1 = calculate RED component
	move.l	#$00,d2			; d2 = calculate GREEN component
	move.l	#$00,d3			; d3 = calculate BLUE component

	sub.b	(a2)+,d0		; d0 = 63-TRANSn
	move.b	(a3)+,d1		; d1 = RED component
	move.b	(a4)+,d2		; d2 = GREEN component
	move.b	(a5)+,d3		; d3 = BLUE component

	cmp.b	#$3F,d0			; is TRANSn == 63
	beq.s	.savecol		; yes, go save color table

	mulu	d0,d1			; d1 = (63-TRANSn)*r
	mulu	d0,d2			; d2 = (63-TRANSn)*g
	mulu	d0,d3			; d3 = (63-TRANSn)*b

	divu	#$3F,d1			; d1 = ((63-TRANSn)*r)/63
	divu	#$3F,d2			; d2 = ((63-TRANSn)*g)/63
	divu	#$3F,d3			; d3 = ((63-TRANSn)*b)/63

.savecol:
	lsl.w	#$8,d1			; d1 = 000r rrrr 0000 0000
	lsl.w	#$3,d1			; d1 = rrrr r000 0000 0000
	lsl.w	#$6,d3			; d3 = 0000 0bbb bb00 0000
	or.w	d1,d2			; d2 = rrrr rbbb bb00 0000
	or.w	d3,d2			; d2 = rrrr rbbb bbgg gggg

	move.w	d2,(a1)+		; save colour in CLUT
	dbra	d7,.loop		; continue for next symbols
.ret:	move.w	#FALSE,TvColFlg		; update the colour table
	rts

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

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

opnlngrf:
	move.w	CDGType,d0		; check if already in
	and.w	#LN_GRAPH,d0		;   line graphics mode
	bne.s	.ret			; yes, so quit

	move.w	#TRUE,-(sp)		; set the line graphics object
	bsr	setlngrf		;   to be displayed
	add.l	#2,sp

	move.w	#TRUE,bldobflg		; re-build the object list
	or.w	#LN_GRAPH,CDGType	; set to line graphics mode
.ret:	rts

;*======================================================================*
;* The LINE-GRAPHICS mode WRITE-FONT instruction (4)			*
;*======================================================================*

linefont:
	bsr	opnlngrf		; start line graphics

	move.l	#LnColTbl,a0		; a0 = pointer to line color table
.bgcol:	move.b	SYMB04(a6),d0		; d0 = symbol 4
	andi.w	#$0007,d0		; d0 = 0000 0bbb = bg color number
	move.w	(a0,d0),d1		; d1 = background color
.fgcol:	move.b	SYMB05(a6),d0		; d0 = symbol 5
	andi.w	#$0007,d0		; d0 = 0000 0fff = fg color number
	move.w	(a0,d0),d2		; d2 = foreground color

.xpos:	move.b	SYMB07(a6),d3		; d3 = symbol 7
	andi.w	#$003F,d3		; d3 = 00xx xxxx = column position
	cmp.w	#49,d3			; maximum value of x
	bgt	.ret			; if (x > 49) then quit

.ypos:	move.b	SYMB06(a6),d4		; d4 = symbol 6
	andi.w	#$0003,d4		; d5 = 0000 00yy = row position

.prep:	move.l	#fontdata,a0		; a0 = pointer to font data
	move.l	#offstabl,a1		; a1 = offset table in pack data
	add.l	#$04,a1			; a1 = offset to 8th symbol
	move.w	#$0b,d7			; d7 = 11 (total of 12 symbols)

.loop:	move.l	#0,d6			; clear d6
	move.b	(a1)+,d6		; d6 = offset in pack
	move.b	(a6,d6),d0		; d0 = next symbol

.chk5:	btst.l	#5,d0			; check for bit 5
	beq.s	.bg5
.fg5:	move.w	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over5
.bg5:	move.w	d1,(a0)+		; 0 -> set to background color
.over5:					; bit 5 done

.chk4:	btst.l	#4,d0			; check for bit 4
	beq.s	.bg4
.fg4:	move.w	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over4
.bg4:	move.w	d1,(a0)+		; 0 -> set to background color
.over4:					; bit 4 done

.chk3:	btst.l	#3,d0			; check for bot 3
	beq.s	.bg3
.fg3:	move.w	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over3
.bg3:	move.w	d1,(a0)+		; 0 -> set to background color
.over3:					; bit 3 done

.chk2:	btst.l	#2,d0			; check for bit 2
	beq.s	.bg2
.fg2:	move.w	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over2
.bg2:	move.w	d1,(a0)+		; 0 -> set to background color
.over2:					; bit 2 done

.chk1:	btst.l	#1,d0			; check for bit 1
	beq.s	.bg1
.fg1:	move.w	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over1
.bg1:	move.w	d1,(a0)+		; 0 -> set to background color
.over1:					; bit 1 done

.chk0:	btst.l	#0,d0			; check for bit 0
	beq.s	.bg0
.fg0:	move.w	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over0
.bg0:	move.w	d1,(a0)+		; 0 -> set to background color
.over0:					; bit 0 done

.next:	dbra	d7,.loop		; check next symbol

.blit:	bsr	bltfnt16		; display the font

.disp:	move.w	#TRUE,LnDspFlg		; update LINE-graphics display
.ret:	rts

;*======================================================================*
;* The LINE-GRAPHICS mode WRITE-SCROLL instruction (12)			*
;*======================================================================*

linescrl:
	bsr	opnlngrf		; set line graphics mode

.colr:	move.l	#LnColTbl,a0		; a0 = pointer to line color table
	move.b	SYMB04(a6),d0		; d0 = symbol 4 = 0000 0ccc
	andi.w	#$07,d0			; d0 = offset in line color table
	lsl.w	#1,d0			; d0 = offset in bytes
	move.w	(a0,d0),d1		; d1 = required color
	move.w	d1,ScrlColr		; save color

.rest:	move.b	SYMB05(a6),d1		; d1 = symbol #5
	move.b	SYMB06(a6),d2		; d2 = symbol #6

.lnph:	move.b	d1,d0			; d0 = symbol 5
	andi.w	#$0007,d0		; d0 = 0000 0hhh
	cmp.w	#5,d0			; if (lnPH > 5)
	bgt	.ret			; yes, quit
	move.w	d0,lnPH			; save lnPH

.lnpv:	move.b	d2,d0			; d0 = symbol 6
	andi.w	#$000F,d0		; d0 = 0000 vvvv
	cmp.w	#11,d0			; if (lnPV > 11)
	bgt	.ret			; yes, quit
	move.w	d0,lnPV			; save lnPV

.chkrt:	btst.l	#4,d1			; copy right ?
	beq.s	.chklt			; no, check further
.cpyrt:	move.w	#6,lnCOPH		; yes, copy right
	bra.s	.ocoph
.chklt:	btst.l	#5,d1			; copy left ?
	beq.s	.cpyh0			; no, check further
.cpylt:	move.w	#-6,lnCOPH		; yes, copy left
	bra.s	.ocoph
.cpyh0:	move.w	#0,lnCOPH		; no horizontal copy
.ocoph:

.chkdn:	btst.l	#4,d2			; copy down ?
	beq.s	.chkup			; no, check further
.cpydn:	move.w	#12,lnCOPV		; yes, copy down
	bra.s	.ocopv
.chkup:	btst.l	#5,d2			; copy up ?
	beq.s	.cpyv0			; no, check further
.cpyup:	move.w	#-12,lnCOPV		; yes, copy up
	bra.s	.ocopv
.cpyv0:	move.w	#0,lnCOPV		; no vertical copy
.ocopv:

.scrol:	bsr	updlngrf		; update LINE-graphics memory
	move.w	#0,lnCOPH		; clear lnCOPH
	move.w	#0,lnCOPV		; clear lnCOPV

.disp:	move.w	#TRUE,LnDspFlg		; update LINE-graphics display
.ret:	rts

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

;*======================================================================*
;* Initialise TV-GRAPHICS screen and display it				*
;*======================================================================*

opntvgrf:
	move.w	CDGType,d0		; check if alread in
	and.w	#TV_GRAPH,d0		;   TV graphics mode
	bne.s	.ret			; no, quit

	move.w	#TRUE,-(sp)		; set TV graphics object
	bsr	settvgrf		;   to be displayed
	add.l	#2,sp

	move.w	#TRUE,bldobflg		; re-build the object list
	or.w	#TV_GRAPH,CDGType	; set to TV graphics mode
.ret:	rts

;*======================================================================*
;* The TV-GRAPHICS mode PRESET-MEMORY instruction (1)			*
;*======================================================================*

tvsetmem:
	bsr	opntvgrf		; initialise TV graphics mode

	move.l	#0,d1			; clear d1
	move.w	d1,tvPH			; initialise tvPH
	move.w	d1,tvPV			; initialise tvPV

	move.b	SYMB04(a6),d1		; d1 = symbol 4
	andi.w	#$000F,d1		; d1 = 0000 0000 0000 cccc
	move.w	d1,d0			; d0 = d1
	lsl.w	#8,d0			; d0 = 0000 cccc 0000 0000
	or.w	d0,d1			; d1 = 0000 cccc 0000 cccc
	move.w	d1,-(sp)		; clear the 
	bsr	clrtvgrf		;   and TV graphics work memory
	add.l	#2,sp			;   to background color

.disp:	move.w	#TRUE,TvDspFlg		; update TV-graphics display
.ret:	rts

;*======================================================================*
;* The TV-GRAPHICS mode PRESET-BORDER instruction (2)			*
;*======================================================================*

tvsetbrd:
	move.b	SYMB04(a6),d0		; d0 = symbol 4
	andi.l	#$F,d0			; d0 = 0000 0000 0000 0000 0000 0000 0000 cccc
	move.w	d0,BrdColNo		; border color number = pack[4]

	move.l	#0,d1			; d1 = calculate RED component
	move.l	#TvPmColR,a3		; a3 = table for RED component
	move.b	(a3,d0),d1		; d1 = RED component

	move.l	#0,d2			; d2 = calculate GREEN component
	move.l	#TvPmColG,a4		; a4 = table for GREEN component
	move.b	(a4,d0),d2		; d2 = GREEN component

	move.l	#0,d3			; d3 = calculate BLUE component
	move.l	#TvPmColB,a5		; a5 = table for BLUE component
	move.b	(a5,d0),d3		; d3 = BLUE component

	move.l	#27,d0
	lsl.l	d0,d1			; d1 = rrrr 0000 0000 0000 0000 0000 0000 0000
	move.l	#18,d0
	lsl.l	d0,d2			; d2 = 0000 0000 gggg 0000 0000 0000 0000 0000
	move.l	#3,d0
	lsl.l	d0,d3			; d3 = 0000 0000 0000 0000 0000 0000 bbbb 0000

	or.w	d1,d3			; d3 = rrrr 0000 0000 0000 0000 0000 bbbb 0000
	or.w	d2,d3			; d3 = rrrr 0000 gggg 0000 0000 0000 bbbb 0000

	move.l	d3,BORD1		; set the border color
.ret:	rts

;*======================================================================*
;* The TV-GRAPHICS mode WRITE-FONT FOREGROUND/BACKGROUND instruction (6)*
;*======================================================================*

tvfntfbg:
	bsr	opntvgrf		; start TV graphics

.prep:	bsr	tvprpfnt		; prepare font to blit
	tst.w	d0			; is it successful
	beq.s	.ret			; no, quit

.blit:	move.w	#FALSE,XORFlag		; clear XOR flag
	bsr	bltfnt08		; blit font on offscreen buffer

.disp:	move.w	#TRUE,TvDspFlg		; update TV-graphics display
.ret:	rts

;*======================================================================*
;* The TV-GRAPHICS mode EXCLUSIVE-OR FONT instruction (38)		*
;*======================================================================*

tvxorfnt:
	bsr	opntvgrf		; start TV graphics

.prep:	bsr	tvprpfnt		; prepare font to blit
	tst.w	d0			; is it successful
	beq.s	.ret			; no, quit

.blit:	move.w	#TRUE,XORFlag		; set XOR flag
	bsr	bltfnt08		; blit font on offscreen buffer

.disp:	move.w	#TRUE,TvDspFlg		; update TV-graphics display
.ret:	rts

;*======================================================================*
;* Prepares FONT data to be blitted in REPLACE/XOR format		*
;*======================================================================*

tvprpfnt:
.ch0:	move.b	SYMB04(a6),d0		; d0 = symbol 4
	lsr.b	#$02,d0			; d0 = (d0 >> 2)
	andi.w	#$000C,d0		; d0 = (d0 & 0x000C)
.ch1:	move.b	SYMB05(a6),d1		; d1 = symbol 5
	lsr.b	#$04,d1			; d1 = (d1 >> 4)
	andi.w	#$0003,d1		; d1 = (d1 & 0x0003)
.chno:	or.w	d1,d0			; d0 = channel number

.chkch:	cmpi.w	#1,d0			; (chno > 1) ?
	bgt.s	.usrch			; yes, check for the user channel
	bra.s	.chok			; no, go blit the font
.usrch:	cmp.w	TvChnlNo,d0		; is font from the user channel ?
	bne	.retf			; no, quit
.chok:

.xpos:	move.b	SYMB07(a6),d3		; d3 = symbol 7
	andi.w	#$003F,d3		; d3 = 00xx xxxx = column position
	cmpi.w	#49,d3			; if (x > 49)
	bgt	.retf			; yes, quit

.ypos:	move.b	SYMB06(a6),d4		; d4 = symbol 6
	andi.w	#$001F,d4		; d4 = 000y yyyy = row position
	cmpi.w	#17,d4			; if (y > 17)
	bgt	.retf			; yes, quit

.if 0

.bgcol:	move.b	SYMB04(a6),d1		; d1 = symbol 4 = background color
	andi.w	#$000F,d1
.fgcol:	move.b	SYMB05(a6),d2		; d2 = symbol 5 = foreground color
	andi.w	#$000F,d2

.prep:	move.l	#fontdata,a0		; a0 = pointer to font data
	move.l	#offstabl,a1		; a1 = offset table in pack data
	add.l	#$04,a1			; a1 = offset to 8th symbol
	move.w	#$0b,d7			; d7 = 11 (total of 12 symbols)

.loop:	move.l	#0,d6			; clear d6
	move.b	(a1)+,d6		; d6 = offset in pack
	move.b	(a6,d6),d0		; d0 = next symbol

.chk5:	btst.l	#5,d0			; check for bit 5
	beq.s	.bg5
.fg5:	move.b	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over5
.bg5:	move.b	d1,(a0)+		; 0 -> set to background color
.over5:					; bit 5 done

.chk4:	btst.l	#4,d0			; check for bit 4
	beq.s	.bg4
.fg4:	move.b	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over4
.bg4:	move.b	d1,(a0)+		; 0 -> set to background color
.over4:					; bit 4 done

.chk3:	btst.l	#3,d0			; check for bit 3
	beq.s	.bg3
.fg3:	move.b	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over3
.bg3:	move.b	d1,(a0)+		; 0 -> set to background color
.over3:					; bit 3 done

.chk2:	btst.l	#2,d0			; check for bit 2
	beq.s	.bg2
.fg2:	move.b	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over2
.bg2:	move.b	d1,(a0)+		; 0 -> set to background color
.over2:					; bit 2 done

.chk1:	btst.l	#1,d0			; check for bit 1
	beq.s	.bg1
.fg1:	move.b	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over1
.bg1:	move.b	d1,(a0)+		; 0 -> set to background color
.over1:					; bit 1 done

.chk0:	btst.l	#0,d0			; check for bit 0
	beq.s	.bg0
.fg0:	move.b	d2,(a0)+		; 1 -> set to foreground color
	bra.s	.over0
.bg0:	move.b	d1,(a0)+		; 0 -> set to background color
.over0:					; bit 0 done

	add.l	#2,a0			; skip two bytes
.next:	dbra	d7,.loop		; check next symbol

.else

.prep:	move.l	#fontblit,a0		; a0 = pointer to font data
	move.l	#offstabl,a1		; a1 = offset table in pack data
	add.l	#$04,a1			; a1 = offset to 8th symbol
	move.w	#$02,d7			; d7 = 2 (total of 12 symbols)

.loop:	move.w	#0,d6			; clear d6

	move.b	(a1)+,d6		; d6 = offset in pack
	move.b	(a6,d6),d0		; d0 = 1st symbol
	lsl.b	#$02,d0			; 1st byte
	lsl.l	#$08,d0			; d0 = xxxx11xx

	move.b	(a1)+,d6		; d6 = offset in pack
	move.b	(a6,d6),d0		; d0 = 2nd symbol
	lsl.b	#$02,d0			; 2nd byte
	lsl.l	#$08,d0			; d0 = xx1122xx

	move.b	(a1)+,d6		; d6 = offset in pack
	move.b	(a6,d6),d0		; d0 = 3rd symbol
	lsl.b	#$02,d0			; 3rd byte
	lsl.l	#$08,d0			; d0 = 112233xx

	move.b	(a1)+,d6		; d6 = offset in pack
	move.b	(a6,d6),d0		; d0 = 4th symbol
	lsl.b	#$02,d0			; 4th byte
	move.l	d0,(a0)+		; d0 = 11223344 -> save 4 bytes

.next:	dbra	d7,.loop		; check next symbol

.bit2pix:
	bsr	blitidle

.bgcol:	move.b	SYMB04(a6),d1		; d1 = symbol 4 = xxxxxx0B = background color
	andi.w	#$000F,d1
	move.b	d1,d0			; d0 = xxxxxx0B
	lsl.w	#8,d0			; d0 = xxxx0B00
	or.b	d1,d0			; d0 = xxxx0B0B
	move.w	d0,d1			; d1 = xxxx0B0B
	swap	d1			; d1 = 0B0Bxxxx
	move.w	d0,d1			; d1 = 0B0B0B0B
	move.l	d1,B_DSTD		; initialise destination data
	move.l	d1,B_DSTD+4		; register with background color

.fgcol:	move.b	SYMB05(a6),d2		; d2 = symbol 5 = xxxxxx0B = foreground color
	andi.w	#$000F,d2
	move.b	d2,d0			; d0 = xxxxxx0B
	lsl.w	#8,d0			; d0 = xxxx0B00
	or.b	d2,d0			; d0 = xxxx0B0B
	move.w	d0,d2			; d2 = xxxx0B0B
	swap	d2			; d2 = 0B0Bxxxx
	move.w	d0,d2			; d2 = 0B0B0B0B
	move.l	d2,B_PATD		; initialise pattern data
	move.l	d2,B_PATD+4		; register with foreground color

.blit:	move.l	#0,A1_PIXEL
	move.l	#0,A2_PIXEL

	move.l	#$0001FFF8,A1_STEP
	move.l	#$0001FFF8,A2_STEP

	move.l	#((12<<16)|(8)),B_COUNT

	move.l	#fontdata,A1_BASE
	move.l	#fontblit,A2_BASE

	move.l	#(PITCH1|PIXEL8|WID8|XADDPIX),A1_FLAGS
	move.l	#(PITCH1|PIXEL1|WID8|XADDPIX),A2_FLAGS

	move.l	#(SRCEN|UPDA1|UPDA2|PATDSEL|BCOMPEN|BKGWREN|BUSHI),B_CMD
.endif

.rets:	move.w	#1,d0			; successful
	rts
.retf:	move.w	#0,d0			; failure
	rts

;*======================================================================*
;* The TV-GRAPHICS mode SCROLL SCREEN WITH PRESET instruction (20)	*
;*======================================================================*

tvscrlst:
	bsr	opntvgrf		; set TV graphics mode

.color:	move.b	SYMB04(a6),d0		; d0 = symbol 4
	andi.w	#$000F,d0		; d0 = 0000 0000 0000 cccc
	move.w	d0,d1			; d1 = d0
	lsl.w	#8,d1			; d1 = 0000 cccc 0000 0000
	or.w	d1,d0			; d0 = 0000 cccc 0000 cccc
	move.w	d0,ScrlColr		; save scroll with preset color

.scrol:	move.w	#0,ScrlType		; reset to scroll with preset
	bsr	tvscroll		; scroll screen

.ret:	rts

;*======================================================================*
;* The TV-GRAPHICS mode SCROLL SCREEN WITH COPY instruction (24)	*
;*======================================================================*

tvscrlcp:
	bsr	opntvgrf		; set TV graphics mode

.scrol:	move.w	#1,ScrlType		; scroll with copy
	bsr	tvscroll		; scroll screen

.ret:	rts

;*======================================================================*
;* scroll the TV-GRAPHICS screen					* 
;*======================================================================*

tvscroll:
	move.b	SYMB05(a6),d1		; d1 = symbol 5
	move.b	SYMB06(a6),d2		; d2 = symbol 6

.tvph:	move.b	d1,d0			; d0 = symbol 5
	andi.w	#$0007,d0		; d0 = tvPH
	cmpi.w	#5,d0			; if (tvPH > 5)
	bgt	.ret			; yes, quit
	move.w	d0,tvPH			; save tvPH

.tvpv:	move.b	d2,d0			; d0 = symbol 6
	andi.w	#$000F,d0		; d0 = tvPV
	cmpi.w	#11,d0			; if (tvPV > 11)
	bgt	.ret			; yes, quit
	move.w	d0,tvPV			; save tvPV

.chkrt:	btst.l	#4,d1			; copy right ?
	beq.s	.chklt			; no, check further
.cpyrt:	move.w	#6,tvCOPH		; yes, copy right
	bra.s	.ocoph
.chklt:	btst.l	#5,d1			; copy left ?
	beq.s	.cpyh0			; no, check further
.cpylt:	move.w	#-6,tvCOPH		; yes, copy left
	bra.s	.ocoph
.cpyh0:	move.w	#0,tvCOPH		; no horizontal copy
.ocoph:

.chkdn:	btst.l	#4,d2			; copy down ?
	beq.s	.chkup			; no, check further
.cpydn:	move.w	#12,tvCOPV		; yes, copy down
	bra.s	.ocopv
.chkup:	btst.l	#5,d2			; copy up ?
	beq.s	.cpyv0			; no, check further
.cpyup:	move.w	#-12,tvCOPV		; yes, copy up
	bra.s	.ocopv
.cpyv0:	move.w	#0,tvCOPV		; no vertical copy
.ocopv:

.scrol:	bsr	updtvgrf		; update TV graphics memory
	move.w	#0,tvCOPH		; clear tvCOPH
	move.w	#0,tvCOPV		; clear tvCOPV

.disp:	move.w	#TRUE,TvDspFlg		; update TV-graphics display
.ret:	rts

;*======================================================================*
;* The TV-GRAPHICS mode	LOAD CLUT Colour-0..7 instruction (30)		*
;*			LOAD CLUT Colour-8..15 instruction (31)		*
;*======================================================================*

tvldclt0:
	move.l	#0,d0
	bsr	setpclut
	bsr	ldclut1
	rts

tvldclt1:
	move.l	#8,d0
	bsr	setpclut
	bsr	ldclut1
	rts

;*======================================================================*
;* The TV-GRAPHICS mode DEFINE COLOUR TRANSPARENCY instruction (28)	*
;*======================================================================*

tvcoltrn:
	move.l	#0,d0
	bsr	settrans
	bsr	ldtrans
	rts

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

;*======================================================================*
;* The EXTENDED TV-GRAPHICS mode MEMORY-CONTROL instruction (3)		*
;*======================================================================*

exmemctl:
	rts

;*======================================================================*
;* The EXTENDED TV-GRAPHICS mode XOR ADDITIONAL FONT WITH 2 COLORS	*
;* instruction (14)							*
;*======================================================================*

exadnfnt:
	rts

;*======================================================================*
;* The EXTENDED TV-GRAPHICS mode XOR ADDITIONAL FONT WITH 2 COLORS	*
;* instruction (14)							*
;*======================================================================*

exxradfn:
	rts

;*======================================================================*
;* The EXTENDED TV-GRAPHICS mode LOAD CLUT Colour (0..7) to (248..255)	*
;* instruction (16-47)							*
;*======================================================================*

exldcl00:
	move.l	#$00,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl01:
	move.l	#$08,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl02:
	move.l	#$10,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl03:
	move.l	#$18,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl04:
	move.l	#$20,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl05:
	move.l	#$28,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl06:
	move.l	#$30,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl07:
	move.l	#$38,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl08:
	move.l	#$40,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl09:
	move.l	#$48,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl10:
	move.l	#$50,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl11:
	move.l	#$58,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl12:
	move.l	#$60,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl13:
	move.l	#$68,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl14:
	move.l	#$70,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl15:
	move.l	#$78,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl16:
	move.l	#$80,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl17:
	move.l	#$88,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl18:
	move.l	#$90,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl19:
	move.l	#$98,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl20:
	move.l	#$A0,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl21:
	move.l	#$A8,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl22:
	move.l	#$B0,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl23:
	move.l	#$B8,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl24:
	move.l	#$C0,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl25:
	move.l	#$C8,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl26:
	move.l	#$D0,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl27:
	move.l	#$D8,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl28:
	move.l	#$E0,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl29:
	move.l	#$E8,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl30:
	move.l	#$F0,d0
	bsr	setsclut
	bsr	ldclut1
	rts

exldcl31:
	move.l	#$F8,d0
	bsr	setsclut
	bsr	ldclut1
	rts

;*======================================================================*
;* The EXTENDED TV-GRAPHICS mode LOAD CLUT ADDITIONAL COLOUR (0..15)	*
;* to (240-255) instruction (48-63)					*
;*======================================================================*

exldcl50:
	move.l	#$00,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl51:
	move.l	#$10,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl52:
	move.l	#$20,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl53:
	move.l	#$30,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl54:
	move.l	#$40,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl55:
	move.l	#$50,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl56:
	move.l	#$60,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl57:
	move.l	#$70,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl58:
	move.l	#$80,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl59:
	move.l	#$90,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl60:
	move.l	#$A0,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl61:
	move.l	#$B0,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl62:
	move.l	#$C0,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl63:
	move.l	#$D0,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl64:
	move.l	#$E0,d0
	bsr	setsclut
	bsr	ldclut2
	rts

exldcl65:
	move.l	#$F0,d0
	bsr	setsclut
	bsr	ldclut2
	rts

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

	.data

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

;*
;* DIFFERENT JUMP TABLES
;*
		.phrase
.include	'packtabl.inc'

;*
;* OFFSET INTO PACK DATA FOR DE-SCRAMBLING
;*
		.phrase
offstabl:	.dc.b	SYMB04		; symbol #4
		.dc.b	SYMB05		; symbol #5
		.dc.b	SYMB06		; symbol #6
		.dc.b	SYMB07		; symbol #7
		.dc.b	SYMB08		; symbol #8
		.dc.b	SYMB09		; symbol #9
		.dc.b	SYMB10		; symbol #10
		.dc.b	SYMB11		; symbol #11
		.dc.b	SYMB12		; symbol #12
		.dc.b	SYMB13		; symbol #13
		.dc.b	SYMB14		; symbol #14
		.dc.b	SYMB15		; symbol #15
		.dc.b	SYMB16		; symbol #16
		.dc.b	SYMB17		; symbol #17
		.dc.b	SYMB18		; symbol #18
		.dc.b	SYMB19		; symbol #19
;*
;* Line Graphics Colour Table
;*
		.phrase
LnColTbl:	.dc.w	LNCOL_BLACK
		.dc.w	LNCOL_BLUE
		.dc.w	LNCOL_GREEN
		.dc.w	LNCOL_CYAN
		.dc.w	LNCOL_RED
		.dc.w	LNCOL_MAGENTA
		.dc.w	LNCOL_YELLOW
		.dc.w	LNCOL_WHITE

		.phrase

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

	.bss

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

		.phrase
;*
;* current CHANNEL number as set by the user
;*

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

;*
;* type of graphics being displayed
;*

CDGType:	.ds.w	1		; type of graphcs being displayed

;*
;* whether font blit in RELACE/XOR mode
;*

XORFlag:	.ds.w	1		; whether WRITE FONT (FALSE) or XOR FONT (TRUE)

;*
;* scroll variable from LINE and TV graphics modes
;*

lnPH:		.ds.w	1		; Horizontal Screen Pointer for LINE-Graphics
lnPV:		.ds.w	1		; Vertical Screen Pointer for LINE-Graphics

lnCOPH:		.ds.w	1		; Horizontal shift (left or right) in LINE-Graphics
lnCOPV:		.ds.w	1		; Vertical shift (up or down) in LINE-Graphics

tvPH:		.ds.w	1		; Horizontal Screen Pointer for TV-Graphics
tvPV:		.ds.w	1		; Vertical Screen Pointer for TV-Graphics

tvCOPH:		.ds.w	1		; Horizontal shift (left or right) in TV-Graphics
tvCOPV:		.ds.w	1		; Vertical shift (up or down) in TV-Graphics

;*
;* scroll type and preset color for scroll with Preset
;*

ScrlType:	.ds.w	1		; scroll with copy (TRUE) or preset (FALSE)
ScrlColr:	.ds.w	1		; background colour while scrolling with preset

BrdColNo:	.ds.w	1		; preset border colour

PakCount:	.ds.l	1		; number of packets processed
symblcnt:	.ds.l	1		; number of symbols in buffer

TvDspFlg:	.ds.w	1		; should the TV-graphics display be updated
LnDspFlg:	.ds.w	1		; should the LINE-graphics display be updated

TvColFlg:	.ds.w	1		; should the colour table be updated

		.phrase

TvPmColR:	.ds.b	256		; red component
TvPmColG:	.ds.b	256		; green component
TvPmColB:	.ds.b	256		; blue component

TransFac:	.ds.b	256		; transparency factor

TvScColR:	.ds.b	256		; red component
TvScColG:	.ds.b	256		; green component
TvScColB:	.ds.b	256		; blue component

dummy:		.ds.b	256		; dummy array

		.phrase

fontblit:	.ds.b	12		; pixel data for fonts used in
					; bit to pixel expansion
		.phrase

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

	.end

