;------------------------------------------------------------------------------------------------------------------
;	Scroller for VBXE FX core v 1.09 and above
;	This is very simple scroller example for VBXE written by Candl'O'Sin with help of AtariArea users, and Biki/Union
;	I'm not an 6502 coder, so if this is inefficent for you, please provide better one
;
;	Candle'O'Sin
;-------------------------------------------------------------------------------------------------------------------

;--------------------------------------------------------
; some system/memory address space definitions
; antic
VCOUNT	equ	$D40B
NMIEN	equ	$D40E
NMIST	equ	$D40E
; gtia
COLBAK	equ	$D01A
CONSOL	equ	$D01F
; pokey
SKSTAT	equ	$D20F

; os
POKMSK		equ	$10
CRITIC		equ	$42
COLCRS		equ	$55
SAVMSC		equ	$58


; page 0 user data
.zpvar		Screen	.word
.zpvar		TextAdr	.word
.zpvar		Temp	.byte
.zpvar		BufPtr	.word

; OS Vectors
VSERIN		equ	$20A

.def	__VBXE_AUTO__
.def	VBXE_WINDOW	=	0x3000

;--------------------------------------------------------
; main
	org $2000

	icl	'fileio.lib'
	icl	'vbxe.lib'

main
	lda	#<Welcome_Txt		; introduce ourselves :)
	sta	TextPtr
	lda	#>Welcome_Txt
	sta	TextPtr+1
	jsr	PutLine

	jsr	VBXE_Detect		; VBXE core 1.07 and above detection,
	bcc	Main_VBXE_Found
	mwa	#VBXE_NPresent TextPtr
	jsr	PutLine			; well.. no VBXE no show
	rts				; exit to dos
	;---------------------------------------------------------------------
Main_VBXE_Found
	cpx	#0xd6
	beq	Main_VBXE_at_d6
	inc	VBXE_Address+1		; not at d6, but still found - d7 then!
Main_VBXE_at_d6
	mwa	#VBXE_Present TextPtr	; this is neat feature of mads - it replaces previous lda/sta pairs with single mnemonic
	jsr	Putline
	
	lda	#0x38			; set the base address of MEMA window to 0x3000 (and not collide with SpartaDosX), size to 4k and accesible only by CPU
	vbsta	VBXE_MA_CTL
	lda	#0x80			; copy some data into VBXE address space (XDL, Blitter control blocks (BCB))
	vbsta	VBXE_MA_BSEL
	ldx	#XDL_Lenght
	ldy	#0
Main_l1	lda	XDL,y
	sta	VBXE_WINDOW+0x400,y
	iny
	dex
	bne	Main_l1

	ldx	#BLT_Lenght
	ldy	#0
Main_l2	lda	BLT_CLR,y
	sta	VBXE_WINDOW+0x500,y
	iny
	dex
	bne	Main_l2

	lda	#0			; setup VBXE for displaying picture data
	vbsta	VBXE_XDL_ADR0		; but don't show the overlay just yet!
	vbsta	VBXE_XDL_ADR2
	lda	#0x04
	vbsta	VBXE_XDL_ADR1


	mwa	#VBXE_Loading TextPtr	; inform the user that big file is loading
	jsr	PutLine
	
	lda	#0x80
	vbsta	VBXE_MA_BSEL
	mwa	#Graphics FileNamePtr
	lda	#0x10
	sta	BankIndex		; load font data under 0x010000
	jsr	LoadData

	mwa	#VBXE_Key TextPtr	; inform the user how to quit our example
	jsr	PutLine
	
	sei
	lda	NMIST
	sta	NMI_Status
	lda	#0
	sta	NMIEN

	lda	#0x80
	vbsta	VBXE_MA_BSEL
	mwa	#Palette Pal_ptr	; set the pointer to palette address
	lda	#0			; start with color #0
	ldx	#1			; and set the overlay (#1) palette
	jsr	VBXE_SetPalette

	lda	#%00000001		; XDL enabled, and transparent color index 0, otherwise you would see
	vbsta	VBXE_VIDEO_CONTROL	; just some letters flying over black screen

Main_Loop


	ldy	#text_lenght-1
Main_Loop_l1
	tya
	pha
	lda	#5
	jsr	Prepare_Next
	jsr	Draw_Font
	pla
	tay
	dey
	bpl	Main_Loop_l1

	jsr	Increase_Index
	jsr	Flip_Screen
	jsr	Clear_Screen

	jsr	Wait_For_Sync

	lda	SKSTAT
	and	#4
	bne	Main_Loop


	lda	NMI_Status		; restore NMI status
	sta	NMIEN
	cli				; and IRQ

	lda	#0
	vbsta	VBXE_VIDEO_CONTROL	; disable XDL
	lda	#0
	sta	VBXE_MA_BSEL		; restore main memory (and disable VBXE memory window at VBXE_WINDOW)
	
	jmp	(0x000a)		; good bye ;)

;--------------------------------------------------------
Increase_Index
	lda	Index_X
	add	#1
	sta	Index_X
	sta	Temp_X

	lda	Index_X+1
	adc	#0
	and	#0x03
	sta	Index_X+1
	sta	Temp_X+1

	lda	Index_Y
	add	#1
	sta	Index_Y
	sta	Temp_Y

	lda	Index_Y+1
	adc	#0
	and	#0x03
	sta	Index_Y+1
	sta	Temp_Y+1

	rts
;--------------------------------------------------------
Flip_Screen
	lda	#0x80
	vbsta	VBXE_MA_BSEL
	lda	VBXE_WINDOW+0x405
	sta	VBXE_WINDOW+0x500+BLT_FNTCP-BLT_CLR+8
	sta	VBXE_WINDOW+0x500+BLT_SCRCLR-BLT_CLR+8
	eor	#1
	sta	VBXE_WINDOW+0x405
	rts
;--------------------------------------------------------

;--------------------------------------------------------
; Prepare_next - get next position for next letter
; a - spacing between letters
Prepare_next
	pha
	lda	<sin_table
	sta	Prepare_sm1
	lda	<cos_table
	sta	Prepare_sm2
	lda	>sin_table
	sta	Prepare_sm1+1
	lda	>cos_table
	sta	Prepare_sm2+1

	pla
	pha
	add	Temp_X
	sta	Temp_X
	lda	Temp_X+1
	adc	#0
	and	#0x03
	sta	Temp_X+1

	lda	Temp_X
	add	Prepare_sm1
	sta	Prepare_sm1
	lda	Temp_X+1
	adc	Prepare_sm1+1
	sta	Prepare_sm1+1

	pla
	add	Temp_Y
	sta	Temp_Y
	lda	Temp_Y+1
	adc	#0
	and	#0x03
	sta	Temp_Y+1

	lda	Temp_Y
	add	Prepare_sm2
	sta	Prepare_sm2
	lda	Temp_Y+1
	adc	Prepare_sm2+1
	sta	Prepare_sm2+1

	lda	0x55AA
Prepare_sm1	equ *-2
	sta	font_x

	lda	0x55AA
Prepare_sm2	equ *-2
	sta	font_y

	lda	text,y
	rts
;--------------------------------------------------------
; Draw_Font - accumulator - font number
; font_x - font x pos
; font_y - font y pos
Draw_Font
	cmp	#0
	beq	Draw_Font_end
	sec
	sbc	#1
	asl	@
	asl	@
	pha
	lda	#0x80
	vbsta	VBXE_MA_BSEL
	pla
	sta	VBXE_WINDOW+0x500+BLT_FNTCP-BLT_CLR+1
	lda	font_x
	sta	VBXE_WINDOW+0x500+BLT_FNTCP-BLT_CLR+6	; font x pos
	lda	font_y
	sta	VBXE_WINDOW+0x500+BLT_FNTCP-BLT_CLR+7	; font y pos
	lda	#BLT_FNTCP-BLT_CLR
	vbsta	VBXE_BL_ADR0		; setup the blitter for memory fill operation
	lda	#0
	vbsta	VBXE_BL_ADR2		; see the description of BCB at the end of this
	lda	#0x05			; source
	vbsta	VBXE_BL_ADR1
	lda	#0
Draw_Font_l1
	vblda	VBXE_BLITTER_BUSY
	cmp	#0
	bne	Draw_Font_l1		; wait for blitter to finish
	lda	#1
	vbsta	VBXE_BLITTER_START	; start the blit
Draw_Font_end
	rts
;--------------------------------------------------------
Wait_For_Sync
	lda	$d40b
	rne		 		;repeat last instruction if not equal
	lda	$d40b
	req				;repeat last instruction if equal
	rts
;--------------------------------------------------------
; Clear_Screen - clears screen
Clear_Screen
	lda	#BLT_SCRCLR-BLT_CLR
	vbsta	VBXE_BL_ADR0		; setup the blitter for memory fill operation
	lda	#0
	vbsta	VBXE_BL_ADR2		; see the description of BCB at the end of this
	lda	#0x05			; source
	vbsta	VBXE_BL_ADR1
	lda	#0
Clear_Screen_l1
	vblda	VBXE_BLITTER_BUSY
	cmp	#0
	bne	Clear_Screen_l1	; wait for blitter to finish
	lda	#1
	vbsta	VBXE_BLITTER_START	; start the blit
	rts
;--------------------------------------------------------
; data declaration
Welcome_Txt
	.byte	'VBXE Blitter scroller example',0x9b,0
	
VBXE_Present
	.byte 	'VBXE found at '
VBXE_Address
	.byte	'D640',0x9b,0
VBXE_NPresent
	.byte	'VBXE NOT found!',0x9b,0
VBXE_Loading
	.byte	'Loading FONTS.RAW, please wait...',0x9b,0
VBXE_Key
	.byte	'Press any key to quit (well... almost any key ;))',0x9b,0
Buffer
	dta 0
Graphics
	dta c'D:DATA>FONTS.RAW'
filenamelength	equ *-Graphics

XDL
	dta %01110010,%00001000,0xef,0x00,0x00,0x02,0x00,0x01,%00010000,0xff	  ; graphics mode,SD resolution, 240 lines, start at 0x20000, 256 bytes/line
	dta %00000000,%10000000							   ; end of XDL, wait for VSYNC
XDL_Lenght	equ *-XDL
BLT_CLR	BLTBLK (0x000000,0x00FF,0x01,0x000000,0x00FF,0x01,0x00FF,0x05,0x00,0x00,0x00,0x00,0x00,0x00)

BLT_PALCP
	dta 0x00,0x00,0x00	; source address
	dta 0xFF,0x00		; source step y
	dta 0x01		; source step x
	dta 0x00,0x03,0x00	; destination address
	dta 0xFF,0x00		; destination step y
	dta 0x01		; destination step x
	dta 0xFF,0x00		; width
	dta 0x02		; height
	dta 0xFF		; and mask
	dta 0x00		; xor mask
	dta 0x00		; collision and mask
	dta 0x00		; zoom
	dta 0x00		; patter feature
	dta 0x00		; control

BLT_FNTCP
	dta 0x00,0x00,0x01	; source address
	dta 0x20,0x00		; source step y
	dta 0x01		; source step x
	dta 0x00,0x00,0x02	; destination address
	dta 0x00,0x01		; destination step y
	dta 0x01		; destination step x
	dta 0x1f,0x00		; width
	dta 0x1f		; height
	dta 0xff		; and mask
	dta 0x00		; xor mask
	dta 0x00		; collision and mask
	dta 0x00		; zoom
	dta 0x00		; patter feature
	dta 0x01		; control
BLT_FNTCLR
	dta 0x00,0x00,0x01	; source address
	dta 0x20,0x00		; source step y
	dta 0x01		; source step x
	dta 0x00,0x00,0x02	; destination address
	dta 0x00,0x01		; destination step y
	dta 0x01		; destination step x
	dta 0x1f,0x00		; width
	dta 0x1f		; height
	dta 0x00		; and mask
	dta 0x00		; xor mask
	dta 0x00		; collision and mask
	dta 0x00		; zoom
	dta 0x00		; patter feature
	dta 0x00		; control
BLT_SCRCLR
	dta 0x00,0x00,0x00	; source address
	dta 0x00,0x00		; source step y
	dta 0x00		; source step x
	dta 0x00,0x00,0x02	; destination address
	dta 0x00,0x01		; destination step y
	dta 0x01		; destination step x
	dta 0xff,0x00		; width
	dta 0240		; height
	dta 0x00		; and mask (and mask equal to 0, memory will be filled with xor mask)
	dta 0x00		; xor mask
	dta 0x00		; collision and mask
	dta 0x00		; zoom
	dta 0x00		; patter feature
	dta 0x00		; control
BLT_Lenght	equ	*-BLT_CLR

.var	frame		.byte
.var	scroll		.byte
.var	font_x		.byte
.var	font_y		.byte

.var	Index_X 	.word
.var	Index_Y 	.word
.var	Temp_Y		.word
.var	Temp_X		.word
.var	NMI_Status	.byte

	dta	"Z"
text	dta  d"--: ATARI VBXE BLITTER EXAMPLE :--"
text_lenght	equ *-text
	dta	"Q"

sin_table
	dta b(sin(112,111,128,0,1023))

cos_table
	dta b(sin(100,100,256,64,256+64))
	dta b(sin(160,40,128,32,256+32))
	dta b(sin(120,80,256,64,256+64))
	dta b(sin(100,100,256,64,256+64))

offset_x	dta	0
offset_y	dta	0

Palette
	ins	'fonts.pal'

; ---
	run main
